• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Modeling a Linux USB Serial Driver with IOKit
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Modeling a Linux USB Serial Driver with IOKit


  • Subject: Modeling a Linux USB Serial Driver with IOKit
  • From: Caylan Larson <email@hidden>
  • Date: Wed, 17 Apr 2013 19:54:17 -0500

Ahoy,

I've been working hard on a basic implementation of a userspace driver for the WCH341.  Would you mind offering some advice for where I may have gone astray?

I've got the device/interface endpoints setup correctly.  That is, _usbDevice and _usbInterface have been initialized properly.  I can't configure the device to get write/read to work.  My application is very simple, send one "W\n" and receive a basic string response from the serial device (9600 baud).

I'm modeling this after http://tomoyo.sourceforge.jp/cgi-bin/lxr/source/drivers/usb/serial/ch341.c

Here is my home grown way to set control.

-(void)sendControlRequest:(int)requestValue
              inDirection:(int)direction
                withValue:(int)bufferValue
                  atIndex:(int)index
               bufferSize:(int)size
{
    NSLog(@"-START--------");

    IOReturn    kr;

    int writeBuffer[size];
    writeBuffer[0] = bufferValue; // Status Request

    USBDeviceAddress deviceAddress;
    IOUSBDevRequest     request;

    kr = (*_usbDevice)->GetDeviceAddress(_usbDevice, &deviceAddress);

    request.bmRequestType = USBmakebmRequestType(direction, kUSBVendor, kUSBDevice);
    request.bRequest = requestValue;
    request.wValue = deviceAddress;
    request.wIndex = index;
    request.wLength = size;
    request.pData = &writeBuffer;

    kr = (*_usbDevice)->DeviceRequest(_usbDevice, &request);

    if (kr == kIOReturnSuccess)
    {
        NSLog(@"Success - Bytes are %x and %x", writeBuffer[0], writeBuffer[1]);
    }else if ( kr == kIOReturnOverrun)
    {
        NSLog(@"Device request failed: overrun");
    }else
    {
        NSLog(@"WriteToDevice reset returned err 0x%x\n", kr);

    }
    NSLog(@"-END--------");

}

… Then later, I set up the register/values from http://tomoyo.sourceforge.jp/cgi-bin/lxr/source/drivers/usb/serial/ch341.c…


    //     ch341_control_in(dev, 0x5f, 0, 0, buffer, size);
    [self sendControlRequest:0x5f inDirection:kUSBIn withValue:0 atIndex:0 bufferSize:2];

    //     ch341_control_out(dev, 0xa1, 0, 0);
    [self sendControlRequest:0xa1 inDirection:kUSBOut withValue:0 atIndex:0 bufferSize:2];

    // ch341_control_out(dev, 0x9a, 0x1312, a);
    [self sendControlRequest:0x9a
                 inDirection:kUSBOut
                   withValue:0x1312
                     atIndex:[self calculateBaudrate]
                  bufferSize:2];


    //     ch341_control_in(dev, 0x95, 0x2518, 0, buffer, size);
    [self sendControlRequest:0x5f inDirection:kUSBIn withValue:0 atIndex:0 bufferSize:2];

    //    ch341_control_out(dev, 0x9a, 0x2518, 0x0050);
    [self sendControlRequest:0x9a inDirection:kUSBOut withValue:0x2518 atIndex:0x0050 bufferSize:2];

    // STATUS - EXPECT 0xff 0xee
    [self sendControlRequest:0x95 inDirection:kUSBIn withValue:0x0706 atIndex:0 bufferSize:2];

    //    ch341_control_out(dev, 0xa1, 0x501f, 0xd90a);
    [self sendControlRequest:0xa1 inDirection:kUSBOut withValue:0x501f atIndex:0xd90a bufferSize:2];

    // ch341_control_out(dev, 0x9a, 0x1312, a);
    [self sendControlRequest:0x9a
                 inDirection:kUSBOut
                   withValue:0x1312
                     atIndex:[self calculateBaudrate]
                  bufferSize:2];

    //  ch341_control_out(dev, 0xa4, ~(CH341_BIT_RTS | CH341_BIT_DTR), 0);
    [self sendControlRequest:0xa4
                 inDirection:kUSBOut
                   withValue:~(CH341_BIT_RTS | CH341_BIT_DTR)
                     atIndex:0
                  bufferSize:2];

Then I write to pipe 2 using...

    kr = (*_usbInterface)->WritePipe(_usbInterface,
                                     2,
                                     (void *) [stringToPrint UTF8String],
                                     (UInt32) strlen([stringToPrint UTF8String])
                                     );

2013-04-17 18:18:39.578 Balance[526:303] Attached Modem Device: USB2.0-Ser!
2013-04-17 18:18:39.580 Balance[526:303] Warning Nil - Vendor: (null) Product: USB2.0-Ser!
2013-04-17 18:18:39.585 Balance[526:303] device pointer before: 0
2013-04-17 18:18:39.586 Balance[526:303] device pointer after: 71304080
2013-04-17 18:18:39.586 Balance[526:303] Found device (vendor = 6790, product = 29987)
2013-04-17 18:18:39.586 Balance[526:303] Iterating a USB interface
2013-04-17 18:18:39.587 Balance[526:303]   Interface class 255, subclass 1
2013-04-17 18:18:39.588 Balance[526:303]   Interface has 3 endpoints
2013-04-17 18:18:39.588 Balance[526:303]     PipeRef 1:
2013-04-17 18:18:39.588 Balance[526:303]       direction in,
2013-04-17 18:18:39.588 Balance[526:303]       transfer type bulk, maxPacketSize 32
2013-04-17 18:18:39.589 Balance[526:303]     PipeRef 2:
2013-04-17 18:18:39.589 Balance[526:303]       direction out,
2013-04-17 18:18:39.589 Balance[526:303]       transfer type bulk, maxPacketSize 32
2013-04-17 18:18:39.590 Balance[526:303]     PipeRef 3:
2013-04-17 18:18:39.590 Balance[526:303]       direction in,
2013-04-17 18:18:39.590 Balance[526:303]       transfer type interrupt, maxPacketSize 8


2013-04-17 18:18:49.082 Balance[526:303] Wrote "W
" (2 bytes) to bulk endpoint


And try to read from pipe 1 using…

       result = (*_usbInterface)->ReadPipeAsyncTO(_usbInterface,
                                               1,
                                               readBuffer,
                                               numBytesRead,
                                               500,
                                               1000,
                                               USBDeviceReadCompletionCallback,
                                               (__bridge void *)(self));

But that yields...

2013-04-17 18:18:49.082 Balance[526:303] started async read
2013-04-17 18:18:50.526 Balance[526:303] usb read timeout

Thoughts?

Caylan

_______________________________________________

Cocoa-dev mailing list (email@hidden)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:

This email sent to email@hidden


  • Prev by Date: ANN: new open-source window manager for OS X
  • Next by Date: Re: ANN: new open-source window manager for OS X
  • Previous by thread: Re: ANN: new open-source window manager for OS X
  • Next by thread: NSCAssert in OS X and iOS
  • Index(es):
    • Date
    • Thread