Accessing USB for a siple, slow-minded, BASIC programmer
Andrew Conroy (370) 740 posts |
I was wanting to play around with poking USB and simply seeing if I could understand some small portion of how things work. To this end, I thought I would try and produce a simple list of USB devices currently connected (no practical use, already done before, but maybe educational for me). However, USB documentation seems fragmentary, highly obscure and opaque, and exceptionally well hidden (or I’m just hopeless at searching for it!). Is it possible for a simple BASIC programmer (with no experience or understanding of C) to get their head around this and achieve a plain list of, say, product & vendor IDs plus textual description of the device (similar to the output of *USBDevices and *USBDevInfo [Edit: Yes, so simple I can’t even spell the subject correctly, I see that now!] |
Dave Higton (1515) 3526 posts |
Well, I thought I had left a few examples lying around :-) The biggest challenge in driving a USB device is in finding out what to send, and what the device will send back. I’ve been in something of a privileged position in that I have access to a hardware USB analyser and I have years of experience in reverse engieering protocols. Other than that, you have to look at the USB Implementers Forum and work your way through class specifications. I would recommend anybody to have a go. It usually is hard, but to me this means I have to try hard. Structured trial and error. Lots of trial; very nearly as much error. It’s time we got some more Human Interface Devices into RISC OS; that’s relatively simple in terms of the protocol, the difficult bits being to understand the descriptors, and to get transfers happening in the background. The devices I have in mind are graphics tablets and joysticks. When you’ve got those going, how about Bluetooth?
Everbody has to begin somewhere. I did. I persevered. And you are far from being a beginner in programming. |
Trevor Johnson (329) 1645 posts |
Any connections to Paul Siple? |
Andrew Conroy (370) 740 posts |
I looked at your software, but I couldn’t see anywhere where they tried to get a list of connected USB devices with their VID, PID & textual description. Is trying to get this not as straight forward as it might, at first, sound, and hence best not done? To give a hypothetical example, say I have two USB keyboards (or pens, or mice, doesn’t matter), which both have the same VID & PID but which have different textual descriptions (seen this many times on the Iyonix etc. using !USBInfo). Is it possible to query this list from somewhere to see which of the two devices is currently connected? As far as I can see, just looking at the system variables won’t do this. (I know I could pipe the output of *USBDevices and process that, but that feels like a bodge, or perhaps that’s the only way?). I’m not even thinking of trying to write drivers, if you find it hard, then it’s a waste of time me even going anywhere near it. |
Dave Higton (1515) 3526 posts |
What do you want, Andrew? Do you want a recipe to do something specific, or do you want to learn in more general terms how to communicate with USB devices?
That’s correct. In most cases it isn’t very helpful. There’s one case where it is, but unfortunately for you I wrote it in C and I haven’t yet published the code. The examples I have published give you ways to access devices using control, bulk and interrupt transfers. If you read the examples in conjunction with the relevant parts of the USB specs, you should be able to find how to get the information you want. Yes, there is a fairly steep learning curve, dealing with the myriad pieces of information that can be transferred via control transfers. You have to sift out the parameters that will transfer what you want. If you’re coming to SAUG on Tuesday, we can talk about it some more and look at the USB documents. Btw I also consider myself a slow BASIC programmer. When I can’t do something, I keep working at it, much like a dog worries a bone, until either I’ve worked out how to do it, or I give up – fortunately, usually the former. If I do give up, I usually go back to it weeks or months later; I hate to be beaten. |
Andrew Conroy (370) 740 posts |
I didn’t have any specific long-term end goal/device in mind beyond looking at what was connected, which maybe was a mistake. I naively thought that there would be a nice simple “USB_EnumerateDevices” type SWI which would return a list of devices and useful information about them. Clearly this isn’t the case. My initial post was borne out of frustration after lots of searching of ROOL and elsewhere and not finding much information about how to talk to USB. The best I could find was a PDF Colin linked to in a thread on the forum. I did see mention elsewhere on the forum of some USBDriver_ SWIs but then failed to find any mention of them in the Wiki/online PRM either. There was some information on the iyonix.com website too, but I didn’t know how up-to-date that was. I’ve subsequently found some BASIC code which appears to be getting PID, VID & description info directly from connected USB devices in Ian Hamiltons Epson Scanning software !MFPxEpson, and it looks decidedly more complicated that I’d initially envisioned! Never mind, the journey was educational in itself. |
Steffen Huber (91) 1953 posts |
Hi Andrew, the current problem with USB on RISC OS is that the API basically exposes all the complexity of USB to the developer. You need to know a lot about USB to use the API correctly. It took me a long time to do something simple like controlling a mass storage device via DeviceFS – this only involves enumerating devices and commumicating via bulk transfers. It would be nice if we had a more abstract way to control USB devices. We already have it for mass-storage devices (the SCSI API) and are on the way for Audio (thanks to Dave Higton). On the other hand, abstracting away USB complexity often means that you basically no longer control a USB device, but a storage device or an audio device. Maybe there would be room for an intermediate layer which encapsulates USB stuff by USB device class. |
Andrew Conroy (370) 740 posts |
Thanks to Dave Higton sending me example code, holding my hand and giving encouragement, I managed to understand how the code worked, and find the relevant few pages in the 650page USB 2.0 Spec, so that I now have some (hacky) code which effectively returns the same information as you already get by issuing *USBDevInfo It’s a shame there doesn’t seem to be any way (for a BASIC program) of detecting that a new USB device has been plugged in (or one unplugged) other than repeatedly looking at the auto-generated USB$Device system variables. A Wimp_Message to say “Device connected” or “Device unplugged” might be handy for people, I’d guess. Only useful when in the Desktop though, I appreciate that. |