Asynchronous USB transfers using libusb-win32

Posted in Uncategorized on July 28, 2009 by ee07m060

The official documentation for the libusb-win32 library makes no mention of the asynchronous API that the library provides.  Evidence of these functions is to be found in the prototypes defined in the header file usb.h that forms part of the source code for the win32 port of this important library.

Those async functions are defined as follows:

int usb_submit_async(void *context, char *bytes, int size);
int usb_reap_async(void *context, int timeout);
int usb_reap_async_nocancel(void *context, int timeout);
int usb_cancel_async(void *context);
int usb_free_async(void **context);

What still remains absent in the async API is any documentation on how to use it!

The clearest example of working async code that I have found was written by Kevin Kofler. Kevin developed it as part of the USB codebase for the Texas Instrument calculator project.  Here is a small excerpt of Kevin’s code.  It should get you going with async USB transfers in Windows using libusb-win32:

[..]
/* variables for slv_check and slv_bulk_read2 */

static int         io_pending = 0;
uint8_t            rBuf[64];
uint8_t*           rBufPtr;

[..]
static int slv_check(CableHandle *h, int *status) {

	int ret;
	if (!io_pending) {
		ret = usb_bulk_setup_async(uHdl, &context, TIGL_BULK_IN);
		if (ret < 0)
			return ERR_READ_ERROR;
		ret = usb_submit_async(context, (char*)rBuf, max_ps);

		if (ret < 0) {
			usb_free_async(&context);
			return ERR_READ_ERROR;
		}
		io_pending = TRUE;
	}
	ret = usb_reap_async_nocancel(context, 0);

	if (ret < 0 && ret != -ETIMEDOUT) { 		// Error, unlink URB and return failure.
                usb_cancel_async(context);
		usb_free_async(&context);
		io_pending = FALSE;
		if (ret > 0) {
			nBytesRead = ret;
			rBufPtr = rBuf;
			*status = STATUS_RX; // data available
		}
	}
	return 0;
}

New Sourceforge project for Linux driver for Owon scopes

Posted in Uncategorized on June 29, 2009 by ee07m060

I just set up a new project at Sourceforge to hold the Linux driver code for the Owon digital storage oscilloscopes.

http://sourceforge.net/projects/owondriver

The first release of the driver is now uploaded. It should work okay. No warranties, but I can tentatively vouch that it does what it says on the tin!

Nevertheless, there are plenty of TODOs outstanding.   For example, it would be nice to find out exactly what data is stored in the remaining 32-bit integers in the channel vectorgram headers. 

There are five or six integers in the vectorgram headers which are still of an unknown purpose.  At a guess they might hold Peak-to-Peak and frequency measurements for the channel.

All comments welcomed!

Edit:

While I remember, I used the following resources to determine the Owon’s USB transaction protocol, and to write the code to drive the device:

Reverse engineering Windows USB device drivers (Steven Toth, linuxtv.org)

SniffUsb 2.0 USB Sniffer for Windows (Benoit Papillault, PCAUSA)

usbmon.txt (Linux kernel documentation)

The usbmon: USB monitoring framework (Pete Zaitcev, Red Hat Inc)

Snooping the USB Data Stream (Greg Kroah-Hartman, Linux Journal)

Writing a Simple USB Driver (Greg Kroah-Hartman, Linux Journal)

Writing a Real Driver – In User Space (Greg Kroah-Hartman, Linux Journal)

libusb Developers Guide (Johannes Erdfelt)

USB in a Nutshell – Making sense of the USB standard (Beyond Logic)

USB Made Simple: Part 4 – Protocol (MQP Electronics Ltd)

Reverse engineering a USB peripheral driver for the Owon scope

Posted in usb with tags , , , , , , on June 23, 2009 by ee07m060

As part of this router project, I need to understand USB at a low-level – for driving a MAX3421 controller.   And for some months now, I have been meaning to look at a digital storage oscilloscope made by Owon.  It is the PDS5022s model which can be connected to a PC over a USB link.

Unfortunately, the Owon software although written in Java is wrapped up in a Windows-only executable.   I want to use the scope in Linux, and the binary won’t even run in Wine, nor can I unwrap it to get to the Java classes.

So, there lies the dilemma. I needed to understand USB, and I wanted to reverse engineering the USB peripheral driver for the digital scope.  Here we see two birds and one stone!

With the help of a USB sniffer that runs on Windows, the libusb C library, gcc, khexedit, usbmon and some sticky-backed plastic, I finally got there..   a working userspace Linux driver for the Owon.  At a guess, the code should also work for other scopes in the Owon range.  Once I’ve debugged it a bit, I will post up the source.

[michael@epox Debug]$ ./owondump test5.bin

..Initialising libUSB
..Finding USB buses
..Searching buses for Owon
..Found an Owon device 5345:1234 on bus 001
..Attempting USB lock on device  5345:1234
..Trying to claim interface 0 of 5345:1234
..Successfully claimed interface 0 to 5345:1234
..Attempting to get the Device Descriptor
..Successfully obtained device descriptor!
..Attempting to bulk write start command to device...
..Successful bulk write of 0005h bytes!
..Attempting to bulk read 000ch bytes from device...
..Successful bulk read of 000ch bytes! :
        00000000: e1 d7 00 00 8d d4 2d 21 00 00 00 00
..Attempting to malloc read buffer space of 0000d7e1h bytes
..Successful malloc!
..Owon ready to bulk transfer 0000d7e1h bytes
..Attempting to bulk read 0000d7e1h bytes from device...
..Successful bulk read of 0000d7e1h bytes! :
..Hexdump of CH1 header :
        00000000: 53 50 42 56 30 31 e1 d7 00 00 43 48 31 04 31 00
        00000001: 00 6a 18 00 00 6a 18 00 00 00 00 00 00 11 00 00
        00000002: 00 fe ff ff ff 02 00 00 00 00 00 00 00 00 00 80
        00000003: 40 cb 17 48 42 6c 2d 9c 46 cd cc cc 3e 2a 00 29
..Channel Settings :
 channel name: CH1
 vertical sens: 10mV
 timebase: 0.0025s

 channel name: CH2
 vertical sens: 20mV
 timebase: 0.0025s

 channel name: CHA
 vertical sens: 10mV
 timebase: 0.01s

 channel name: CHB
 vertical sens: 10mV
 timebase: 0.005s

 channel name: CHC
 vertical sens: 20mV
 timebase: 0.01s
..Successfully opened file 'test5.bin'!
..Successfully written 55265 bytes to file test5.bin
..Attempting to release interface 0
..Successful release of interface 0!
[michael@epox Debug]$

owon bitmap using linux driver
Waveform bitmap downloaded using Linux driver for Owon

Dodgy dongles

Posted in Uncategorized on June 20, 2009 by ee07m060

I seem to be buying up all the dodgy Bluetooth dongles on ebay.

The first batch have a chipset from Integrated System Solutions Corp, but share the same ‘unique’  48-bit Bluetooth hardware address of 00:00:00:00:00:00 !   They also take far too long to respond to USB descriptor requests which causes timeout errors.

The second batch of dongles have a CSR chipset and an external antenna for “enhanced data range”.   So far, so good. But then I noticed that one of the antennas had worked a bit loose and so I prised the dongle open to re-attach it firmly.

Imagine my dismay at finding that the antenna for “enhanced data range” actually serves no purpose since it is 100% plastic and not even connected to the board!   On the plus side, at least these dongles work properly.

Two more batches of dongle should be arriving soon.  So third or maybe fourth time lucky!


/sbin/lsusb -v returns the following information…

Bus 004 Device 009: ID 1131:1001 Integrated System Solution Corp. KY-BT100 Bluetooth Adapter
Device Descriptor:
bLength                18
bDescriptorType         1
bcdUSB               1.10
bDeviceClass          224 Wireless
bDeviceSubClass         1 Radio Frequency
bDeviceProtocol         1 Bluetooth
bMaxPacketSize0        16
idVendor           0×1131 Integrated System Solution Corp.
idProduct          0×1001 KY-BT100 Bluetooth Adapter
bcdDevice            3.73
iManufacturer           1
iProduct                2
iSerial                 0
bNumConfigurations      1
Configuration Descriptor:
bLength                 9
bDescriptorType         2
wTotalLength          186
bNumInterfaces          3
bConfigurationValue     1
iConfiguration          0
bmAttributes         0xc0
Self Powered
MaxPower                0mA
Interface Descriptor:
bLength                 9
bDescriptorType         4
bInterfaceNumber        0
bAlternateSetting       0
bNumEndpoints           3
bInterfaceClass       224 Wireless
bInterfaceSubClass      1 Radio Frequency
bInterfaceProtocol      1 Bluetooth
iInterface              0
Endpoint Descriptor:
bLength                 7
bDescriptorType         5
bEndpointAddress     0×81  EP 1 IN
bmAttributes            3
Transfer Type            Interrupt
Synch Type               None
Usage Type               Data
wMaxPacketSize     0×0010  1x 16 bytes
bInterval               1
Endpoint Descriptor:
bLength                 7
bDescriptorType         5
bEndpointAddress     0×02  EP 2 OUT
bmAttributes            2
Transfer Type            Bulk
Synch Type               None
Usage Type               Data
wMaxPacketSize     0×0040  1x 64 bytes
bInterval               1
Endpoint Descriptor:
bLength                 7
bDescriptorType         5
bEndpointAddress     0×82  EP 2 IN
bmAttributes            2
Transfer Type            Bulk
Synch Type               None
Usage Type               Data
wMaxPacketSize     0×0040  1x 64 bytes
bInterval               1
Interface Descriptor:
bLength                 9
bDescriptorType         4
bInterfaceNumber        1
bAlternateSetting       0
bNumEndpoints           2
bInterfaceClass       224 Wireless
bInterfaceSubClass      1 Radio Frequency
bInterfaceProtocol      1 Bluetooth
iInterface              0
Endpoint Descriptor:
bLength                 7
bDescriptorType         5
bEndpointAddress     0×03  EP 3 OUT
bmAttributes            1
Transfer Type            Isochronous
Synch Type               None
Usage Type               Data
wMaxPacketSize     0×0000  1x 0 bytes
bInterval               1
Endpoint Descriptor:
bLength                 7
bDescriptorType         5
bEndpointAddress     0×83  EP 3 IN
bmAttributes            1
Transfer Type            Isochronous
Synch Type               None
Usage Type               Data
wMaxPacketSize     0×0000  1x 0 bytes
bInterval               1
Interface Descriptor:
bLength                 9
bDescriptorType         4
bInterfaceNumber        1
bAlternateSetting       1
bNumEndpoints           2
bInterfaceClass       224 Wireless
bInterfaceSubClass      1 Radio Frequency
bInterfaceProtocol      1 Bluetooth
iInterface              0
Endpoint Descriptor:
bLength                 7
bDescriptorType         5
bEndpointAddress     0×03  EP 3 OUT
bmAttributes            1
Transfer Type            Isochronous
Synch Type               None
Usage Type               Data
wMaxPacketSize     0×0009  1x 9 bytes
bInterval               1
Endpoint Descriptor:
bLength                 7
bDescriptorType         5
bEndpointAddress     0×83  EP 3 IN
bmAttributes            1
Transfer Type            Isochronous
Synch Type               None
Usage Type               Data
wMaxPacketSize     0×0009  1x 9 bytes
bInterval               1
Interface Descriptor:
bLength                 9
bDescriptorType         4
bInterfaceNumber        1
bAlternateSetting       2
bNumEndpoints           2
bInterfaceClass       224 Wireless
bInterfaceSubClass      1 Radio Frequency
bInterfaceProtocol      1 Bluetooth
iInterface              0
Endpoint Descriptor:
bLength                 7
bDescriptorType         5
bEndpointAddress     0×03  EP 3 OUT
bmAttributes            1
Transfer Type            Isochronous
Synch Type               None
Usage Type               Data
wMaxPacketSize     0×0011  1x 17 bytes
bInterval               1
Endpoint Descriptor:
bLength                 7
bDescriptorType         5
bEndpointAddress     0×83  EP 3 IN
bmAttributes            1
Transfer Type            Isochronous
Synch Type               None
Usage Type               Data
wMaxPacketSize     0×0011  1x 17 bytes
bInterval               1
Interface Descriptor:
bLength                 9
bDescriptorType         4
bInterfaceNumber        1
bAlternateSetting       3
bNumEndpoints           2
bInterfaceClass       224 Wireless
bInterfaceSubClass      1 Radio Frequency
bInterfaceProtocol      1 Bluetooth
iInterface              0
Endpoint Descriptor:
bLength                 7
bDescriptorType         5
bEndpointAddress     0×03  EP 3 OUT
bmAttributes            1
Transfer Type            Isochronous
Synch Type               None
Usage Type               Data
wMaxPacketSize     0×0019  1x 25 bytes
bInterval               1
Endpoint Descriptor:
bLength                 7
bDescriptorType         5
bEndpointAddress     0×83  EP 3 IN
bmAttributes            1
Transfer Type            Isochronous
Synch Type               None
Usage Type               Data
wMaxPacketSize     0×0019  1x 25 bytes
bInterval               1
Interface Descriptor:
bLength                 9
bDescriptorType         4
bInterfaceNumber        1
bAlternateSetting       4
bNumEndpoints           2
bInterfaceClass       224 Wireless
bInterfaceSubClass      1 Radio Frequency
bInterfaceProtocol      1 Bluetooth
iInterface              0
Endpoint Descriptor:
bLength                 7
bDescriptorType         5
bEndpointAddress     0×03  EP 3 OUT
bmAttributes            1
Transfer Type            Isochronous
Synch Type               None
Usage Type               Data
wMaxPacketSize     0×0021  1x 33 bytes
bInterval               1
Endpoint Descriptor:
bLength                 7
bDescriptorType         5
bEndpointAddress     0×83  EP 3 IN
bmAttributes            1
Transfer Type            Isochronous
Synch Type               None
Usage Type               Data
wMaxPacketSize     0×0021  1x 33 bytes
bInterval               1
Interface Descriptor:
bLength                 9
bDescriptorType         4
bInterfaceNumber        1
bAlternateSetting       5
bNumEndpoints           2
bInterfaceClass       224 Wireless
bInterfaceSubClass      1 Radio Frequency
bInterfaceProtocol      1 Bluetooth
iInterface              0
Endpoint Descriptor:
bLength                 7
bDescriptorType         5
bEndpointAddress     0×03  EP 3 OUT
bmAttributes            1
Transfer Type            Isochronous
Synch Type               None
Usage Type               Data
wMaxPacketSize     0×0031  1x 49 bytes
bInterval               1
Endpoint Descriptor:
bLength                 7
bDescriptorType         5
bEndpointAddress     0×83  EP 3 IN
bmAttributes            1
Transfer Type            Isochronous
Synch Type               None
Usage Type               Data
wMaxPacketSize     0×0031  1x 49 bytes
bInterval               1
Interface Descriptor:
bLength                 9
bDescriptorType         4
bInterfaceNumber        2
bAlternateSetting       0
bNumEndpoints           0
bInterfaceClass       254 Application Specific Interface
bInterfaceSubClass      1 Device Firmware Update
bInterfaceProtocol      0
iInterface              0

Bus 004 Device 008: ID 0a12:0001 Cambridge Silicon Radio, Ltd Bluetooth Dongle (HCI mode)
Device Descriptor:
bLength                18
bDescriptorType         1
bcdUSB               1.10
bDeviceClass          224 Wireless
bDeviceSubClass         1 Radio Frequency
bDeviceProtocol         1 Bluetooth
bMaxPacketSize0        16
idVendor           0×0a12 Cambridge Silicon Radio, Ltd
idProduct          0×0001 Bluetooth Dongle (HCI mode)
bcdDevice            1.34
iManufacturer           1 Conwise Technology
iProduct                2 CONWISE BT
iSerial                 0
bNumConfigurations      1
Configuration Descriptor:
bLength                 9
bDescriptorType         2
wTotalLength          108
bNumInterfaces          2
bConfigurationValue     1
iConfiguration          0
bmAttributes         0×80
MaxPower              100mA
Interface Descriptor:
bLength                 9
bDescriptorType         4
bInterfaceNumber        0
bAlternateSetting       0
bNumEndpoints           3
bInterfaceClass       224 Wireless
bInterfaceSubClass      1 Radio Frequency
bInterfaceProtocol      1 Bluetooth
iInterface              0
Endpoint Descriptor:
bLength                 7
bDescriptorType         5
bEndpointAddress     0×81  EP 1 IN
bmAttributes            3
Transfer Type            Interrupt
Synch Type               None
Usage Type               Data
wMaxPacketSize     0×0010  1x 16 bytes
bInterval               1
Endpoint Descriptor:
bLength                 7
bDescriptorType         5
bEndpointAddress     0×82  EP 2 IN
bmAttributes            2
Transfer Type            Bulk
Synch Type               None
Usage Type               Data
wMaxPacketSize     0×0040  1x 64 bytes
bInterval               0
Endpoint Descriptor:
bLength                 7
bDescriptorType         5
bEndpointAddress     0×02  EP 2 OUT
bmAttributes            2
Transfer Type            Bulk
Synch Type               None
Usage Type               Data
wMaxPacketSize     0×0040  1x 64 bytes
bInterval               0
Interface Descriptor:
bLength                 9
bDescriptorType         4
bInterfaceNumber        1
bAlternateSetting       0
bNumEndpoints           2
bInterfaceClass       224 Wireless
bInterfaceSubClass      1 Radio Frequency
bInterfaceProtocol      1 Bluetooth
iInterface              0
Endpoint Descriptor:
bLength                 7
bDescriptorType         5
bEndpointAddress     0×83  EP 3 IN
bmAttributes            1
Transfer Type            Isochronous
Synch Type               None
Usage Type               Data
wMaxPacketSize     0×0000  1x 0 bytes
bInterval               1
Endpoint Descriptor:
bLength                 7
bDescriptorType         5
bEndpointAddress     0×03  EP 3 OUT
bmAttributes            1
Transfer Type            Isochronous
Synch Type               None
Usage Type               Data
wMaxPacketSize     0×0000  1x 0 bytes
bInterval               1
Interface Descriptor:
bLength                 9
bDescriptorType         4
bInterfaceNumber        1
bAlternateSetting       1
bNumEndpoints           2
bInterfaceClass       224 Wireless
bInterfaceSubClass      1 Radio Frequency
bInterfaceProtocol      1 Bluetooth
iInterface              0
Endpoint Descriptor:
bLength                 7
bDescriptorType         5
bEndpointAddress     0×83  EP 3 IN
bmAttributes            1
Transfer Type            Isochronous
Synch Type               None
Usage Type               Data
wMaxPacketSize     0×0009  1x 9 bytes
bInterval               1
Endpoint Descriptor:
bLength                 7
bDescriptorType         5
bEndpointAddress     0×03  EP 3 OUT
bmAttributes            1
Transfer Type            Isochronous
Synch Type               None
Usage Type               Data
wMaxPacketSize     0×0009  1x 9 bytes
bInterval               1
Interface Descriptor:
bLength                 9
bDescriptorType         4
bInterfaceNumber        1
bAlternateSetting       2
bNumEndpoints           2
bInterfaceClass       224 Wireless
bInterfaceSubClass      1 Radio Frequency
bInterfaceProtocol      1 Bluetooth
iInterface              0
Endpoint Descriptor:
bLength                 7
bDescriptorType         5
bEndpointAddress     0×83  EP 3 IN
bmAttributes            1
Transfer Type            Isochronous
Synch Type               None
Usage Type               Data
wMaxPacketSize     0×0011  1x 17 bytes
bInterval               1
Endpoint Descriptor:
bLength                 7
bDescriptorType         5
bEndpointAddress     0×03  EP 3 OUT
bmAttributes            1
Transfer Type            Isochronous
Synch Type               None
Usage Type               Data
wMaxPacketSize     0×0011  1x 17 bytes
bInterval               1

PICKit2 vs ICD2

Posted in pic with tags , , , , on June 20, 2009 by ee07m060

There are two types of programmer for the PIC series of 16 bit microcontroller.

The original programmer is called the PICKIT2.  To encourage early adoption of the PIC architecture, Microchip placed the schematics, board artwork, and software of the PICKIT2 programmer into the public domain.  Anybody is free to sell clones of the PICKIT2 programmer. Clones are available for around $20 on ebay.

Later, however, Microchip developed a more sophisticated programmer known as the ICD2.   ICD stands for In-Circuit Debugging.  Through the use of the debugger which is built-in to the MPLAB IDE, the internal state of the microcontroller can be examined with the ICD2.  Program execution can stepped through one instruction at a time and breakpoints can be set.   However, unlike the PICKIT2, the design of the ICD2 remains proprietary.

The relative merits of these two programmers are discussed regularly on Microchip Technical forums.   Xiofan Chen has constructed a helpful FAQ on the subject:

Support for the PICKIT2 programmer in the MPLAB IDE has greatly improved in recent releases.  And now, like the ICD2, the PICKIT2 can also be used as a debugger. Some developers are reporting that there is now little to choose between the two models.

Wouter van Ooijen has written a FAQ on the PICKit2 and Au Group Electronics provide some background to understanding the hardware of the PICKit2 and guidance on calibrating the programmer.  There is also a dedicated Google group for the “discussion of open-source development for Microchip’s PICKit series of programmers”

Hello world!

Posted in Uncategorized on June 17, 2009 by ee07m060

Welcome to WordPress.com. This is your first post. Edit or delete it and start blogging!