~ Archive for USB ~

Asynchronous threads, or “runloops” to monitor a “source”

3

Once I had the synchronous read, it was just a matter of continuing with the example and setting up an asynchronous read (which does not loose data the way the synchronous read does).

I will take out the declarations and error checks which are in the USB simple example code

To start with, I declared gbuffer to be of size 320000 instead of 8 (to capture 5 mn of data) and set that declaration at the head of the program (so it is global)

In the synchronous case, all the instructions execute one after the other. Nothing can be done while the data is read. In the asynchronous case, the data is read from the input pipe at the same time as the main program is executing its tasks (on a single processor, the two codes alternate)

One way to set up two pieces of code to execute simultaneously is to start a “thread”.

But if the thread needs to remain running so that it can process requests at a future time, one uses a thread’s run loop. The run loop monitors input sources attached to the thread and dispatches the events it receives to the thread’s installed handler functions. After the handlers finish processing the event, the run loop returns the thread to its idle state and waits for more events.

Event-driven applications receive their events in a run loop. A run loop monitors sources of input to the application and dispatches control when sources become ready for processing. When processing is complete, control passes back to the run loop which then waits for the next event.

with the command, CFrunlooprun control is passed to the run loop until CFRunLoopStop

And this is more or less what happens in the transferdata function: create a source, CreateInterfaceAsyncEventSource, add the source to the runloop, CFRunLoopAddSource, request the input of data for a certain number of bytes, ReadPipeAsync, and start the runloop so it can monitor the source and read the data as it becomes available.

next I need to read about the notion of a callbackfunction

void
MyCallBackFunction(void *dummy, IOReturn result, void *arg0)
{
printf(“MyCallbackfunction: %d, %d, %d\n”, (int)dummy, (int)result, (int)arg0);

CFRunLoopStop(CFRunLoopGetCurrent());
}

void transferData(IOUSBInterfaceInterface **intf, UInt8 inPipeRef)
{

numBytesRead = sizeof(gBuffer);

err = (*intf)->CreateInterfaceAsyncEventSource(intf, &cfSource);

CFRunLoopAddSource(CFRunLoopGetCurrent(), cfSource, kCFRunLoopDefaultMode);

err = (*intf)->ReadPipeAsync(intf, inPipeRef, gBuffer, numBytesRead, (IOAsyncCallback1)MyCallBackFunction, (void*)(UInt32)inPipeRef);

CFRunLoopRun();

//when the program reaches this line of code
// the reading of the transmission of the data is over, and one can read
// the data in gbuffer


}

Reading data from an USB input interrupt pipe (endpoint)

2

Taking the kext file out, the Device was treated as an HID device. I have found two xcode projects which work, HID explorer and HID examples, but I am stuck right now, because these HID projects talk about elements, and USB prober talks about endpoint. I have not yet found what the link is between endpoints and elements.
Putting the kext file back in, I found several xcode projects for the USB, USBPrivateDAtaSample and SimpleUserClient (which still give me error messages) and USBSimple Example which I got to work: I put the vendor and product id, looked for interrupt pipes instead of bulk pipes, and added a synchronous readpipe command.

char gBuffer[8];

UInt32 numBytesRead;

numBytesRead = sizeof(gBuffer);

err = (*intf)->ReadPipe(intf, inPipeRef, gBuffer, &numBytesRead);

if (err) printf(“Unable to perform interrupt read %2x %4x %4x\n”,err_get_system(err),err_get_sub(err),err_get_code(err));

for (i = 1; i USElessthanSYMBOLHERE numBytesRead; i++) printf(“Read %x (%ld bytes) from interrupt endpoint\n”, gBuffer[i],gBuffer[0]);

(the first byte of data is a number, 7 usually, the rest are characters)

The key to success was being able to interpret the error message! I read how to print and interprete the error code ox38 ox00 ox2e8

 http://developer.apple.com/qa/qa2001/qa1…

looking up in IOreturn.h, 0x028 is data overrun!

#define kIOReturnOverrun iokit_common_err(0x2e8) //

The other key to success was the apple USB forum site who helped with the error code

 http://lists.apple.com/archives/Usb

where I was told that I should try reading at least maxPacketSize bytes, where maxPacketSize bytes is a USB prober info on the enpoint pipe. So I tried with a buffer size of 8, instead of 64 or 2, and bingo, the error message went away, and I was reading data!

Of course it helps that I have the PC opensource code to figure out what to do with the data!!!!

So a bright day, I talked to my device. Now I have to learn how to access it asynchronously.

Mac OSX: using a unix command to look for a kext file

ø

Apple’s tech help on the usb discussion list helped me out:

I have a kernel extension matching to the IOUSBInterface
of my device and preventing the IOUSBHIDDriver from matching to the
device.

To search for it

find /System/Library/Extensions -name “Info.plist” -exec grep -H
1155 “{}” \;

This searches all the Info.plist files for one that contains
“1155”, the idVendor of the device. Judging from the IOProbeScore
of 100000 and the values in the ioregistry, the kext in question is
doing a vendor specific match by specifying idVendor/idProduct/
bcdDevice/bConfigurationValue/bInterfaceNumber.

The result of the search is
/System/Library/Extensions/STMicroTestDriver.kext/Contents/Info.plist:
1155

When I remove the file STMicroTestDriver.kext, the wild divine can no longer find the device, but HID explorer lists the lightstone along with everything else.

TheWD software needs access to the device, but without the kext, the HID Driver will open the device and they can’t open it.

If the HID driver doesn’t match to the device, I can’t use the HID mgr to talk to it.

So I need to go two incompatible ways.

1 remove the kext file (disabling WD),so I can use HID explorer and matlab

2. keep the kext file in place, and learn to use IOUSBInterfaceInterface calls to talk to the device (as long as the WD driver/app isn’t running). So I can send/receive USB requests.

HID Explorer

ø

My tech support told me about HID Explorer.
 http://developer.apple.com/samplecode/HI…

It is a complete projet with C code which does something when I run it: It provides information on all HID devices. So 1. I can find out what I have, 2. I can see examples of a program I can run in xcode, debug etc.

Unfortunately, something is off with my device, HID explorer does not see it as an HID device. this was confirmed by running

ioreg -lw 0

2.7 meg of information! the main one being that there is no hid info in there at all for my device.

What next! This is like learning a language. There are folks out there who know it! Human beings have an amazing ability for languages. Helas!!! not all of us!

The mac console and USB drivers

1

Today, I feel pretty optimistic about this project, even though I am not any closer to the goal:
“many devices these days [including this sensor] are made as generic HID (Human Interface Devices) that comply with the USB specifications, so you can enumerate and create a handle to the device (treat it like a file) within c/c++.”

Generic is good. I don’t have to write a driver. C is good, I don’t need to learn about the kernel. Ok, so it can be done, but how?

What I learned about my USB device and its driver

In applications, there is a utility called console which records error message and background processes. Clicking on the log icon shows that there are several logs going on. But only the default one shows any activity when I start the game.

USBSimpleExample: Starting

Found device 0x000091ab

dealWithDevice: found 1 configurations

found interface: 0x000092db

dealWithInterface: found 2 pipes

dealWithPipes: grabbing BULK IN pipe index 1, number 1

dealWithPipes: grabbing BULK OUT pipe index 2, number 2

It seems to me that the game called a generic USB driver called USBSimpleExample which sets up the pipe communications for the device throught the hierarchy described below:

The device is associated to pipes which are connections from the host controller to a logical entity on the device named an endpoint. The pipes are synonymous to byte streams
each pipe is uni-directional, either in or out of the device. endpoint 0 is used to control the device on the bus

To access an endpoint, a hierarchical configuration must be obtained.

1. The device connected to the bus has one (and only one) device descriptor

2. the device descriptor has one or more configuration descriptors. These configurations often correspond to states, e.g. active vs. low power mode.

3. Each configuration descriptor in turn has one or more interface descriptors, which describe certain aspects of the device, so that it may be used for different purposes: for example, a camera may have both audio and video interfaces.

4. Each interface descriptors in turn have one default interface setting and possibly more alternate interface settings

5. Each interface setting has an endpoint descriptor, as outlined above. An endpoint may however be reused among several interfaces and alternate interface settings.

Devices that attach to the bus can be full-custom devices requiring a full-custom device driver to be used, or may belong to a device class. the same device driver may be used for any device that claims to be a member of a certain class. HID is one such device class.
 http://en.wikipedia.org/wiki/Universal_S…

So there is a generic USB driver. Somehow you tell it you want to talk to your particular device, it finds the device, talks to the device, finds out from the device how many pipes to set up, in this case one for in, one for out.

So I can learn how to access a generic USB device, or how to access a HID compliant device. A third possibility is to see if I can access my sensor through matlab and the psychtoolbox. Quite a few ways to go.
 http://psychtoolbox.org/usb.html

Boredom and the wild divine biofeedback light stone

2

I have decided to try to talk to my wild divine hardware. This means diving into the computer world, and getting way over my head. By the look of it, I will never make it. But if I do make it, I better leave a trail behind, for any lost soul out there, who finds the earth is not complex enough as it is, and wants to explore human’s ephemeral technical world.

So the problem is simple enough. I have a biosensor which measures heart beat and electrical conductance, or some such. this sensor talks through a USB port to a software game, the wild divine. How can I write a program that accesses the sensor and plots the data in real time.

The net says an application cannot access a hardware device directly. It needs to talk to a “Device Manager” or “I/O Kit” or else talk to a manager which will talk to this device manager, and the device manager talks to a “device driver” which talks to the “hardware device”.

I have the game installed on my computer. So although I have not idea where, or if this file is readable, there should already be a device driver for the sensor.

Also, I am not starting from scratch. Someone created an open software for PC which is supposed to do what I want to do. http://sourceforge.net/projects/lsm/ It has about a 100 files, which is not really encouraging, but there is a file with USB and lightstone in the name that seems to read information from the sensor, so that file may be the meat of the matter (the driver) for the PC.

Through a couple fas computer help desks, I have located two sources of help. There is a group of employees at Harvard called abcd, which gathers people into email lists concerning various hardware/software interests. There is also a computing society linked through the computer department.

Through ABCD I got a response from BU about a tutorial in linux on how to write a device driver
 http://www.linuxjournal.com/article/7353
This gives no information on what language/compiler etc is used to create, build and load the driver, or to bind it to hardware, so it is not a lets start from scratch tutorial, but at least, it suggests that a device driver can be writen.

Log in