Modeling a Linux USB Serial Driver with IOKit
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