BMOW title
Floppy Emu banner

USB to ADB Progress – Good News and Bad News

USB

I’m still chugging away slowly on this USB to ADB input translator concept, using a PIC32 starter kit. First the good news: the ADB end of things is pretty much finished. I’ve designed a demo that creates a phantom mouse on a Mac SE, and when I hold a button on the starter kit, it moves the mouse around in lazy circles. It also coexists happily with other real ADB peripherals, remapping itself if necessary to avoid ADB address conflicts, and asserting the SRQ signal as necessary when it needs attention to report new mouse movement data. So that part is looking good.

Now for the bad news: the USB side is looking to be much more difficult than I expected. I’m struggling to create even a simple demo of reading from a USB mouse, let alone dealing properly with keyboards or USB hubs. Microchip only provides a single USB Host example project for the starter kit, which writes a file to an attached USB storage device. It works, but it doesn’t tell me much about how to handle a mouse or keyboard, and all of the USB specifics are in a separate pre-compiled library.

My search for a simple USB example is made harder by the fact that most PIC example code was designed for older Microchip compilers, and needs modification to get it working with the latest XC32 and MPLAB X. I found this example by Suwa-Koubou, who modified Microchip’s USB library to add support for multiple, cascadable hubs. It includes a simple example program that displays messages when USB devices are attached and detached, as well as examples of dumping input data from a mouse, keyboard, and joystick. Sounds great! But it was designed for the older MPLAB 8 and C32 compiler.

I spent a few hours trying to update and port this example project, but I ran into several problems while trying to update it. Something about the interrupt declaration mechanism has changed (shadow registers?), and it was designed for a different model of PIC32. I updated the code as I thought was needed, but the modified example doesn’t work. It never logs any attach/detach events, and doesn’t really do anything at all, except once when it crashed after I attached a USB keyboard. So more work is needed there.

Assuming I can eventually get the code working for reading from a USB mouse and keyboard, through a hub, I’m still worried about how to multitask the USB and ADB interfaces. My understanding of the USB Host implementation is shaky, but I think some events are handled by interrupts, while other activity requires periodically calling USBTasks() from the main loop, every 1 ms or so. Both of those present potential problems for the ADB interface, which bit-bangs the ADB protocol using a purely software-based implementation. ADB transactions can take about 3 ms, plus a few milliseconds more waiting for an attention or reset signal. If I don’t call USBTasks() during that period, it may starve the USB Host controller and cause errors. But if I insert periodic calls to USBTasks() inside the ADB code, it may cause ADB timing errors depending on how longUSBTasks() takes to return. Similarly, if a USB interrupt fires in the middle of an ADB transaction, and it takes more than a few microseconds to complete, it may cause timing errors for any ADB transaction that was in progress. Hmm…

Read 14 comments and join the conversation 

14 Comments so far

  1. Steve - April 1st, 2016 2:19 pm

    I probably shouldn’t have posted that USB whine. The trouble with the USB hub example was only in the message logging, and not in the USB code itself. It’s working now, and I’m able to read from a USB keyboard and mouse simultaneously, though a hub.

    As far as I can tell, the USB interrupt is only called when a device is attached or detached, which shouldn’t ever happen with normal use since ADB doesn’t support hot-plugged devices anyway. That means no USB interrupts to mess with the ADB timing, which is good. There is also a USB start of frame interrupt (SOF), which I think is supposed to fire once per millisecond, but I put a breakpoint inside and it was never hit.

  2. raijinzrael - April 1st, 2016 2:26 pm

    You’re doing an awesome work. Now, if only someone else could do the same you’re doing, but for PS/2. would be nice to drive all our retro stuff with only an USB keyboard and Mouse.

  3. Steve - April 1st, 2016 4:11 pm

    USB to PS/2 adapter are pretty common, in both directions. This looks like what you need: http://www.walmart.com/ip/PS-2-to-USB-Female-Adapter-Converter-Connector-Black-3Pcs-for-Keyboard-Mouse/47596732

  4. raijinzrael - April 1st, 2016 6:40 pm

    @Steve

    I know that USB > PS/2 exist, them are all active adapters and are pretty common stuff… But the contrary USB > PS/2 (Same case as USB > ADB, that’s why i posted my thought here) is a pretty rare beast and really doesn’t exist outside the internal dual PS/2-USB support that some keyboard/mouse makers crafted inside a small set of models.

    As for the link… I have a bunch of these adapters, every one with different shape & color, but them are just passive adapters for USB keyboards/mouse which have internal support for both USB/PS2 protocols. Them will no work in any modern 2008+ mouse/keyboard set because them don’t come with such support anymore :-(.

    I tell to you sincerely and knowing what i’m saying, there doesn’t exist really any active USB > PS/2 adapter that would allow us to use our modern USB Keyb/Mouse sets with our retro configurations. Ofc i’m not saying that you should do it too… After all you focus more in the retro Apple world. I only say that would be nice if someone else could do the awesome work you’re doing with USB > ADB adapter, but with an USB > PS/2 active adapter.

  5. raijinzrael - April 1st, 2016 6:43 pm

    *Correction*

    Is PS/2 > USB the one that is widely available and pretty common. USB > PS/2 is the problematic configuration for which there aren’t *active* adapters available.

  6. Steve - April 1st, 2016 6:56 pm

    Interesting, I didn’t realize those were passive adapters that required PS/2 support in the keyboard/mouse itself. USB to PS/2 shouldn’t be difficult, as the PS/2 protocol is pretty simple. Maybe I’ll look at doing that in the future.

  7. David Kuder - April 1st, 2016 8:26 pm

    PS/2 is super simple to implement, raijinzrael. Grab almost any of the Teensy range, modify the PS2 keyboard example to send key codes via the USB. http://pjrc.com/teensy/td_libs_PS2Keyboard.html and http://pjrc.com/teensy/td_keyboard.html

  8. David Kuder - April 1st, 2016 8:29 pm

    Sorry, I guess I read that backwards. But some members of the Teensy range also offer USB Host and enough to implement a PS/2 device.

  9. Andrew H - April 2nd, 2016 10:34 pm

    The inability to properly and sanely handle USB host is why I recommended something slightly more powerful like the ATSAMD21 chip you find in the new Arduino Zero along with SparkFun’s SAMD21 breakout board https://www.sparkfun.com/products/13672 – the chip, the ATSAMD21G18, is about $4 in quantities of 100, and much more powerful / has a much larger user base. :3

    But it looks like you already saw that suggestion before 🙂

  10. Andrew H - April 2nd, 2016 10:39 pm

    Tiny bit more help; the ASF USB host stack manual http://www.atmel.com/images/atmel-42336-asf-usb-stack-manual_applicationnote_at09331.pdf shows that the stack has USB hub support as long as you define a config variable – page 173, so you should definitely be able to use a hub with the Atmel stack. it also has DMA and all other kinds of fun stuff.

  11. Steve - April 3rd, 2016 6:37 am

    At this point I think I’m fighting with the PIC tools and software stack more than the PIC32 hardware. Unlike older PICs with their wacky architecture, the PIC32 is based on a fairly modern MIPS M4K core with a seemingly robust USB peripheral. I did research the SAMD21 for information on USB Host with hubs, after you first mentioned it, since it sounded promising. That #define USB_HOST_HUB_SUPPORT in the ASF code is literally the *only* mention of USB hubs with the SAMD series that I could find. I also looked at the Arduino core libraries for SAMD, and their USB library does not support hubs. Does the SAMD ASF support cascaded hubs? How about low speed devices connected through a full speed hub? Example projects? Nothing. Contrast this with the PIC32, where after some digging I was able to find three different working example projects of hosting a mouse and keyboard through a hub, and many other related forum discussions of people doing similar things. Maybe my Google search skills are just weak, but this is what I mean when I keep saying the PIC32 is better documented than most of the various ARM-based MCUs I’ve compared it with.

  12. Andrew H - April 3rd, 2016 8:14 pm

    Well, the SAMD21 is a relatively new chip. I don’t see why the ASF host framework wouldn’t support cascaded hubs, since beyond the first hub the chip shouldn’t see anything different afaik.

    With how little the sparkfun board costs it can’t hurt to give it a try, I’d say.

  13. Geordie Millar - April 4th, 2016 4:20 am

    Could you perhaps use a pair of microcontrollers and go USB -> Serial and Serial -> ADB on the second one… might be a bit easier on the software side, and the serial -> ADB micro wouldn’t need to be a very powerful one I don’t think…

  14. Steve - April 4th, 2016 8:15 am

    Are you suggesting the two microcontroller approach as a solution to the USB and ADB interface multitasking concern? Good thought, and I’d considered that too. There still might be a multitasking concern with the serial interface between the two, but most mcus have DMA for serial transfers.

    Fortunately I think the PIC32 is going to work OK for this. I still haven’t implemented it all yet, but the basic USB transfer work is handled by the USB engine in parallel with the MCU code, and it uses DMA to read/write the USB data payloads. It’s only the higher level logic for starting transfers, parsing results, or changing states that requires MCU code. I think I can handle this in between ADB messages, and it’ll work… to be confirmed.

Leave a reply. For customer support issues, please use the Customer Support link instead of writing comments.