BMOW title
Floppy Emu banner

More USB-to-ADB Planning

09973-_03

This must be a record for the number of times I’ve posted about a project, without actually building the project, or even a half-way working prototype. I’m still fleshing out my ideas for a USB-to-ADB keyboard/mouse adapter for vintage Macintosh and Apple IIgs computers. In my last update, I described how USB interrupts would interfere with the software timing loops in my bit-banged ADB implementation, and sketched out a few possible solutions to the problem.

After more thought and research, I’ve decided to try the approach that my last post called “timer hacking”. It isn’t really a hack, but rather a better (but more complex) implementation of ADB for the microcontroller. It means removing all the blocking code and software delay loops from my initial ADB implementation, and replacing them with interrupts driven from timers and pin state change events. The ADB-related interrupts will be given higher priority than USB interrupts, and can even interrupt the USB interrupt handler. Because this new ADB code will be interrupt driven, using hardware timers, simultaneous USB activity shouldn’t cause any timing errors. I’m reasonably confident this should all work, but it’ll take time to implement.

I discovered that the PIC32MX I’m using has an input capture feature with a 4-deep FIFO. That will be much nicer than using a basic pin state change interrupt, because input capture records a timer value at the instant a pin changes state, instead of sometime later when the interrupt handler runs and executes code to query the current timer value. So timing measurements when reading ADB will be more accurate. The FIFO means the ADB interrupt handler will only need to be invoked after every 4 rising/falling edges on the ADB signal, instead of for every edge, which will help make things a little more efficient. For writing ADB, I’ll look at using the microcontroller’s built-in PWM hardware, changing the pulse width for each ADB bit, which should be slightly more efficient than using a simple hardware timer to toggle the ADB pin.

 
Taking a Break

Unfortunately, I can’t actually pursue this plan yet, with the PIC32MX USB Starter Kit II that I’ve been using. This kit has virtually none of the PIC’s pins broken out onto headers, essentially no I/O at all except for the USB ports. Earlier I managed to hack in a single external input by soldering a wire to an unused crystal footprint on the board, which was enough for some simple experiments. But that particular pin isn’t connected to the PIC32MX’s input capture peripheral. Some PIC32MX’s have the ability to dynamically remap the pins, but not this particular one. So in short, I can’t use input capture with this hardware.

Even if that weren’t the case, there are other reasons I want access to more I/O pins. It would be a huge help with debugging if I could connect a serial terminal to the PIC’s UART, and log messages with it. While there’s already a built-in debug-print capability that operates over USB, it seems incredibly slow, on the order of 100 characters per second. And I’d also like additional I/O to experiment with some of this device’s other planned features, like a power-on button connected to ADB’s “on” pin. I’d also like to start testing with the actual model of PIC32MX I plan to use in the final device, instead of the high-end PIC32MX795 in the USB Starter Kit. So it’s time for me to order a bunch of discrete parts, or maybe some much simpler PIC32MX prototyping board, and get working on a real prototype.

The trouble comes when I need to program the PIC32MX on this new board or prototype. Many are designed to be programmed via USB, but I can’t do that if the USB interface is already in use as a USB host. The USB Starter Kit II works around that problem by having two separate PICs, each with their own USB interface, but that’s complex and expensive. The other solution is to use a programmer like a PICkit 3 to program the chip via its ICSP pins, so that’s what I’ll do. Except I don’t own a PICkit 3. I ordered a PICkit 3 clone a while ago from Aliexpress, but it probably won’t arrive for several weeks. Until that happens, I’ll be taking a break from this project, aside from possible further sketching out of ideas on paper.

Read 11 comments and join the conversation 

11 Comments so far

  1. techknight - April 12th, 2016 3:30 pm

    Why cant we use Atmel AVR? I tend to stick with that chip for everything.

  2. Michael Engel - May 23rd, 2016 7:53 am

    Not sure if you have seen this adapter. It’s the wrong way around (ADB devices to USB host), but the author circumvented the problem of handling ADB and USB at the same time using two ATtiny2313 microcontrollers that communicate over the built-in UARTs:

    http://spritesmods.com/?art=macsearm&page=4

  3. cb88 - May 24th, 2016 7:00 am

    Would you consider doing pre adb on the same boards also? So, It’d end up with adb, pre adb and usb connectors? The Mac Plus keyboards seem to be just as flakey as anything else that old…

  4. Alexcat3 - October 10th, 2016 8:36 am

    I don’t know much about microcontrollers but, instead of using to microcontrolers, how about using a microcontroller and a dedicated spi usb interface chip. They seem to cost about $4, and with one of them you wouldn’t need to worry about the USB handling code, it would all be in the usb chip’s rom.

  5. Matthew Sillman - November 17th, 2016 8:47 am

    Try looking at Sprite_TM’s SE/ARM page. He has a schematic listed for ADB to USB conversion using a Teensy Microcontroller.

  6. cb88 - November 20th, 2016 10:48 am

    I\’ve been looking at using pic32mm in some of my projects (which is around a $1.50 per chip) in a 2 MCU solution you could use the cheap PIC32MM as the ADB side… and use the PIC32MX as usb host and programming interface for both.

    Also I have read that you can put your interrupt handler in program memory (sram) which can eliminate flash wait states etc… for a huge speedup. Hitech C for pic32 can apparently do this by default… I wonder if gcc/XC32 is smart enough to do it.

  7. Dave - January 18th, 2017 5:15 am

    Is there any update on this project? I am not savvy enough to provide any technical insight like others, but I would be very keen to purchase one of these when complete.

  8. Steve - January 18th, 2017 4:31 pm

    I have the parts to build a full prototype, but haven’t found the free time or enthusiasm to pursue it further. It’s still on my list, though!

  9. Ed - February 2nd, 2017 10:39 pm

    I was able to make a really terrible USB-to-ADB adapter (mouse-only for now) using an Arduino and a Sparkfun-branded USB Host Shield (which is based on an SPI-controlled USB host chip) https://github.com/ehalferty/arduino-usb-to-adb I was surprised to find that I could ignore LISTEN 3 commands entirely(!)

  10. Steve - February 2nd, 2017 11:01 pm

    Very cool! Why do you say it’s really terrible? I should check out that USB Host shield, maybe something like that is a better solution if it’s well-supported. I think the implementation can get away with ignoring the ADB Listen 3 if you don’t care about handling possible address collisions on the ADB bus.

  11. Ed - February 2nd, 2017 11:24 pm

    Well I’m ignoring listen 3, and not checking for collisions when responding to talk commands, and I’m not sure that this solves the problem of USB interrupts interfering with ADB interrupts, since I don’t know if the USB Host Shield library is using a timer interrupts. But anyway, it worked so I’m not overly concerned lol

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