Author Topic: ADB to USB keyboard converter  (Read 321568 times)

PierceSutton and 3 Guests are viewing this topic.

Offline tufty

  • Posts: 347
  • Location: French Alps
Re: ADB to USB keyboard converter
« Reply #200 on: Mon, 04 November 2013, 12:12:13 »
Okay, took the time to do it.

I'm still getting dropped keys, particularly with "double" letters. Ironically enough, it just dropped one of the "t"s in "letters" and I had to edit. It's a *lot* better than before, but it's still an issue, at least for my M0116.

To give you an idea of the difference, I just had a shot at ztype using it.  I usually hit 45-50 wpm and 98%+ accuracy using the same keyboard hooked to an iMate, with the teensy I couldn't do any better than 27wpm and 91% accuracy.

Back to the iMate for me at the moment.

Offline blargg

  • Posts: 45
    • My github
Re: ADB to USB keyboard converter
« Reply #201 on: Mon, 04 November 2013, 12:37:42 »
I wonder whether the iMate is polling faster and thus able to handle a higher typing speed. That is, there is a sweet spot of polling rate where it's not too low for fast typists, and not too high that the keyboard drops keys. hasu, you have meta-commands, correct? You could add one to adjust the polling rate in half-msec or so increments (and print it to hid). That would solve the polling rate issue if that's the cause.

(typed on an M0116 without problem, so apparently I'm not a very fast typist)
« Last Edit: Mon, 04 November 2013, 12:40:20 by blargg »

Offline tufty

  • Posts: 347
  • Location: French Alps
Re: ADB to USB keyboard converter
« Reply #202 on: Mon, 04 November 2013, 13:04:34 »
I wonder whether the iMate is polling faster and thus able to handle a higher typing speed. That is, there is a sweet spot of polling rate where it's not too low for fast typists, and not too high that the keyboard drops keys. hasu, you have meta-commands, correct? You could add one to adjust the polling rate in half-msec or so increments (and print it to hid). That would solve the polling rate issue if that's the cause.

(typed on an M0116 without problem, so apparently I'm not a very fast typist)
I think it's more likely to be driving the adb protocol handler via interrupts.  IIRC the processor used on the iMate is significantly less capable than the teensy.

The teensy *is* capable of handling full-whack ADB without dropping events (check out https://code.google.com/p/waxbee/ which handles adb tablets, these drive the ADB connection harder than it should be capable of going), but it absolutely has to be doing the ADB low level protocol via interrupts to do it.  If you miss an edge, you lose a packet, simple as that. 

Offline thegagne

  • Posts: 69
  • Location: United States
Re: ADB to USB keyboard converter
« Reply #203 on: Mon, 04 November 2013, 17:35:00 »
Hasu's converter is certainly mature enough to use, but may* still drop keys on certain models (sorry hasu, been too busy to repatch my m0116 mappings into your code, I'll try and get round to testing again soon, I promise). 

If you don't have an iMate lying about, drop the cash on a teensy and give it a go.  Worst case, you can rip out all the ADB circuitry, get handy with the soldering iron, and use either hasu's or soarer's "raw matrix" drivers for the teensy.

So... how's the performance on teensy with "raw matrix" drivers? I don't think I can handle drops...

Offline blargg

  • Posts: 45
    • My github
Re: ADB to USB keyboard converter
« Reply #204 on: Mon, 04 November 2013, 21:59:11 »
It's a *lot* better than before, but it's still an issue, at least for my M0116.
Can you come up with an easy-to-do test that shows the dropped keys that a non-touch-typist could reproduce? I want to make this happen on my M0116, so I can solve this problem. If I have to rewrite the ADB code to be interrupt-based and use input capture, so be it.

If you're willing, my plan is to have you try a version I've done of the ADB keyboard driver that uses PJRC's USB driver and my own glue code to adb.c, then if that doesn't work, a version with adjustable polling rate, then if that doesn't work, a rewrite using interrupts and input capture.
« Last Edit: Mon, 04 November 2013, 22:10:41 by blargg »

Offline tufty

  • Posts: 347
  • Location: French Alps
Re: ADB to USB keyboard converter
« Reply #205 on: Tue, 05 November 2013, 00:56:19 »
It's a *lot* better than before, but it's still an issue, at least for my M0116.
Can you come up with an easy-to-do test that shows the dropped keys that a non-touch-typist could reproduce? I want to make this happen on my M0116, so I can solve this problem. If I have to rewrite the ADB code to be interrupt-based and use input capture, so be it.
Not really.

I would conservatively estimate my sustained rate outside "sprint typing" games at around 35wpm - better than a "hunt and peck" typist but not full touch-typing speed as a secretary would use it.  This is mainly because my technique is awful...

I see most drops on repeated letters, a case where there is significantly less finger movement between keystrokes.  Hammer action if you will, maybe 50 wpm+  My guess is that the code that processes a "finalised" keystroke is delaying things enough to make the difference.

So I suppose a qualitative test would be to go for "double keypresses", as fast as you can.

Quote
If you're willing, my plan is to have you try a version I've done of the ADB keyboard driver that uses PJRC's USB driver and my own glue code to adb.c, then if that doesn't work, a version with adjustable polling rate, then if that doesn't work, a rewrite using interrupts and input capture.
Sure thing.  My teensy is set up as follows under hasu's code:
Code: [Select]
/* ADB port setting */
#define ADB_PORT        PORTC
#define ADB_PIN         PINC
#define ADB_DDR         DDRC
#define ADB_DATA_BIT    7

So... how's the performance on teensy with "raw matrix" drivers? I don't think I can handle drops...
Not heard any complaints with either hasu's or soarer's code.  hasu's code has been used on the ergodox, which should be capable of some really fast action.


Offline CarVac

  • Posts: 22
Re: ADB to USB keyboard converter
« Reply #206 on: Tue, 05 November 2013, 06:49:47 »
So... how's the performance on teensy with "raw matrix" drivers? I don't think I can handle drops...

I type ~100-105 wpm and the teensy 2.0++ is not a problem on my reborn Thinkpad keyboard.

The only time I drop letters is when a wire pulls out of the breadboard, but that'll be cured once I finalize the analog electronics and lay it out all on a PCB.

Offline blargg

  • Posts: 45
    • My github
Re: ADB to USB keyboard converter
« Reply #207 on: Tue, 05 November 2013, 14:07:09 »
I had an idea for testing high-speed typing: wire another microcontroller up to the keyboard and have it generate automated keypresses of adjustable frequency, and adjustable synchronization to ADB polling (in case that affects dropping, so it can trigger worst-case behavior). Then find what a Mac can handle, what the Belkin adapter can handle, and what our code can handle (I don't have an iMate unfortunately and don't know how well the Belkin compares).

tufty, what OS are you using (in case that affects USB polling rate or something)? If it's Windows, I think all I've got is some version of XP on a laptop.

Offline tufty

  • Posts: 347
  • Location: French Alps
Re: ADB to USB keyboard converter
« Reply #208 on: Tue, 05 November 2013, 14:08:48 »
Yeah, thrashing adb down the line at it would work, I'd guess.  Of course, you'd have to have a reliable adb protocol *generator* for that ...

I'm on OSX, BTW.

Offline blargg

  • Posts: 45
    • My github
Re: ADB to USB keyboard converter
« Reply #209 on: Tue, 05 November 2013, 14:32:33 »
Oh, I meant having the tester directly connected to the keyswitches on the M0116 keyboard itself, simulating human presses as closely as possible to the real thing. Though yours is an interesting idea as well. I kind of have done this with the simulator, feeding the ADB driver data of varying timing and verifying that it handles everything within spec. But this doesn't have the USB stuff running which is might be the culprit.

OS X, good, I have a PPC iMac running 10.5.x I could fire up for this.
« Last Edit: Tue, 05 November 2013, 14:34:42 by blargg »

Offline Soarer

  • * Moderator
  • Posts: 1918
  • Location: UK
Re: ADB to USB keyboard converter
« Reply #210 on: Tue, 05 November 2013, 15:09:02 »
A little project to press keys etc. would have other uses as well, like generally analyzing a keyboard's scan rate, debounce time and method, etc.

Being able to 'press' four keys ought to be enough, using something like a 74HC4066 quad analogue switch. Could always use more than one of them. A teensy could drive it with a variety of patterns at different speeds. I'm thinking you'd send a command to the Teensy to start each sequence, so it could also be used to measure total lag (like namenlos did).
« Last Edit: Tue, 05 November 2013, 15:12:30 by Soarer »

Offline hasu

  • Thread Starter
  • Posts: 2768
  • Location: Tokyo, Japan
  • @tmk
    • tmk keyboard firmware project
Re: ADB to USB keyboard converter
« Reply #211 on: Thu, 07 November 2013, 15:52:10 »
tufty, thanks for testing.
I don't have any missing keystroke on my ADB boards since blargg's fix was merged. And I tried your github repositry and had no drop key during short run.

I doubt it misses signal so often, ADB is totally host driven polling protocol and device doesn't send data asynchronously. Host sends talk command and waits for response from keyboard, we can know when keyboard send data and use busy-wait. I think it doesn't necessarily need interrupt based code. It is the case in particular unless busy-wait is disturbed by other interrupts.


MINOR CODE CHANGE:
I added cli() in adb.c to prevent interrupts from breaking timing of busy-wait. This would be stupidly long block like several milli seconds, but the converter has no other critical task fortunately.
https://github.com/tmk/tmk_keyboard/commit/94823030f00e9293ffc7ae4bec9611c8224d3532

Without this cli() block I don't have any minssing keys but during typing I occasionally see errors at:
https://github.com/tmk/tmk_keyboard/blob/c18c52f551545b46a28902c69730eefbdb75577d/protocol/adb.c#L142
This error seems to be no harm, though, use of cli() can suppress it.
« Last Edit: Thu, 07 November 2013, 15:56:07 by hasu »
TMK products:HHKB Alt  ⌨ConvertersAlps64FC660C AltFC980C Alt

Offline blargg

  • Posts: 45
    • My github
Re: ADB to USB keyboard converter
« Reply #212 on: Fri, 08 November 2013, 00:24:20 »
The extra USBASP arrived and I've got V-USB and the ADB code running it somewhat decently (typing this using it). I was able to use the jumper posts to get the signals for ADB. +5V from the voltage selection, and an I/O pin and GND from the clock select jumper posts, so no physical modifications to the USBASP board (other than installing the jumper posts for J2 and J3, as they don't come installed). The breadboard just has the 1K pull-up resistor. It was easier to just bring the jumper posts over there rather than try to connect my ADB socket's wires to the board directly.





EDIT: nice, I got the ADB polling synchronized with the V-USB interrupts so that I can disable interrupts for the entire ADB code (send command to keyboard, receive response) and not disrupt USB. So this is allows a $3 ADB-USB converter ($6 if you need to buy a second USBASP to reprogram the first).

EDIT2: I made the key tester, though it's on the Teensy so I can't test the Teensy versions until some new atmega chips arrive to move the tester program over to. Testing the Belkin USB-ADB adapter, the maximum key press rate without dropped keys on an M0116 is 14.3 per second. With my V-USB version on a reprogrammed USBASP (atmega8 at 12 MHz), the maximum key press rate is 13.9 Hz (just a hair lower than the Belkin). Each test closes the contacts of the switch on the M0116 keyboard to cause 80 presses of the same key at the maximum rate and I check for any dropped or wrong.
« Last Edit: Fri, 08 November 2013, 22:54:43 by blargg »

Offline blargg

  • Posts: 45
    • My github
Re: ADB to USB keyboard converter
« Reply #213 on: Sat, 09 November 2013, 12:52:36 »
More maximum key press rates (e.g. on M3501 with USBASP-based converter, you can press the same key 31 times per second without any being lost):
Code: [Select]
31.3Hz M3501 USBASP with reduced ADB time
29.4Hz M3501 Belkin

15.2Hz M0116 USBASP with reduced ADB time
13.9Hz M0116 USBASP
14.3Hz M0116 Belkin

10.4Hz M0487 USBASP with reduced ADB time
10.2Hz M0487 Belkin

I reduced the ADB command sending time by 25% (still within spec by 5%), which upped its maximum rate slightly.

Offline hasu

  • Thread Starter
  • Posts: 2768
  • Location: Tokyo, Japan
  • @tmk
    • tmk keyboard firmware project
Re: ADB to USB keyboard converter
« Reply #214 on: Sat, 09 November 2013, 14:16:48 »
Great job again! blargg,

How did you sync with V-USB? IIRC V-USB consumes about 50us with its interrupt rouine of USB and that breaks ADB communication.
Can we get to access your code some later? Ingriguing.
TMK products:HHKB Alt  ⌨ConvertersAlps64FC660C AltFC980C Alt

Offline tufty

  • Posts: 347
  • Location: French Alps
Re: ADB to USB keyboard converter
« Reply #215 on: Sat, 09 November 2013, 14:27:14 »
That's sounding extremely positive.  If you have test code, I'd be happy to give it a go.

Offline blargg

  • Posts: 45
    • My github
Re: ADB to USB keyboard converter
« Reply #216 on: Sat, 09 November 2013, 18:09:24 »
Moved my key tester to another AVR and tested TMK LUFA version on the Teensy. Timings came out slightly differently for others, so I retested everything. Unfortunately I'm not finding any problem with the TMK version as compared to the Belkin and VUSB ones, so this hasn't isolated the dropped key issue.

Code: [Select]
Maximum key press rate for various keyboards and USB-ADB adapters:
29.4Hz M3501 Belkin
27.8Hz M3501 USBASP
26.3Hz M3501 TMK LUFA

15.2Hz M0116 TMK LUFA
15.2Hz M0116 USBASP
14.7Hz M0116 Belkin

14.3Hz M0487 TMK LUFA
13.5Hz M0487 Belkin
10.9Hz M0487 USBASP

Now to ready this USBASP version for posting here.
« Last Edit: Sat, 09 November 2013, 18:18:14 by blargg »

Offline blargg

  • Posts: 45
    • My github
Re: ADB to USB keyboard converter
« Reply #217 on: Sun, 10 November 2013, 01:44:31 »
OK, here's the source code and some documentation for this USBASP version of the ADB code:

adb-usb-usbasp-1.zip

The simplest wiring just involves cutting the extra ISP ribbon cable you'll have from the USBASP and splicing the ADB cable to it (here I'm using a header that plugs into the breadboard, since I'm not going to build a permanent cable):



The other approach is to connect to the jumper pins on the USBASP board. This allows keeping the ADB keyboard connected to the USBASP, the USBASP plugged into USB and into the ISP cable to the reprogrammer, and the reprogrammer also plugged into USB, all at the same time. This way you can reprogram the USBASP as you debug this code, and not have to unplug anything each edit-debug cycle:



EDIT: hmmm, I just realized that the 1K series resistor on the TX pin of the USBASP board could be used as the pull-up for ADB; just tie TX and RX together and have the code keep TX high. So no extra components needed, just wires to wires when using the ISP cable cut in half.

EDIT2: It wasn't surviving a host suspend+resume. Fix: insert an adb_keyboard_poll() call in input.c line 211:

Code: [Select]
        if ( diff > (byte) min_tclocks )
        {
            prev_time = time;
            break;
        }
       
        usb_keyboard_poll(); // inserted
    }

Now that I know what happens during suspend, I should make the power key on the ADB keyboard wake the host.

EDIT3: I got host wakeup working using the ADB power key. Haven't updated code archive yet.
« Last Edit: Sun, 10 November 2013, 13:25:37 by blargg »

Offline blargg

  • Posts: 45
    • My github
Re: ADB to USB keyboard converter
« Reply #218 on: Sun, 10 November 2013, 16:54:25 »
Oh wow, I just figured out a way to make it miss a key easily: press the key down for only a split-second. This generates the key down and key up events together in the same 16-bit word returned, and at least my handler nullifies it (adds to keys held, then removes, before sending off to USB). So we need to check for this condition, and if it holds, defer the key up until after sending off the key held status to USB.

BTW, I was causing this to occur on the M3501, by far the fastest-responding of all the keyboards above. So since it occurs there, it'll be easier to make occur on others.

Seeing if I can reproduce this on the TMK LUFA version, and then come up with a fairly clean fix to that and mine.

EDIT: With this fix to the USBASP version, it can handle up to 41.7Hz key press rate without loss on an M3501. It should be able to handle 60Hz, so there's some room for improvement :)

EDIT2: Argh, this doesn't help the M0116 at all. I guess it is unable to deliver the press and release events in the same exchange.
« Last Edit: Sun, 10 November 2013, 17:43:19 by blargg »

Offline hydrospell

  • * Destiny Supporter
  • Posts: 272
  • Location: Singapore
  • some keyboard thing
    • octobrain
Re: ADB to USB keyboard converter
« Reply #219 on: Sun, 10 November 2013, 22:28:48 »
blargg

you're operating at such a high (low in terms of programming?) level that I honestly have no idea what you're doing, except you're doing important work for us who want to use teensy with these obsolete keyboards!

FWIW I've seen no key dropping problem yet on my IIgs board. I'm a 90wpm typist on typeracer if that means anything -- are you optimizing for much higher typing speeds than this? 41.7Hz key press rate is pretty intense. (insert fingering joke)

cheers
⌨ Filco MJ2 MX Blues / M0116 Orange Alps / Homemade 60% MX Reds / M0110

Cherry MX art prints 20/50 still available!

Offline blargg

  • Posts: 45
    • My github
Re: ADB to USB keyboard converter
« Reply #220 on: Sun, 10 November 2013, 23:22:01 »
My main goal is to have as clear an idea of what all is happening and why. This naturally leads to a cleaner design that gets better performance out of ADB.

I've done more research into the fundamental limitations of USB on the AVR MCUs and the ADB keyboards:

* V-USB has an opportunity to update the keyboard every 8ms; you either use that opportunity or wait until the next one 8ms later. No variation. Interrupt also occurs at that rate. This was consistent across Linux and an iBook running Mac OS 9.2.2 and Mac OS 10.4.11.

* Teensy USB (PJRC) can update every 2ms (only tested on Linux). Interrupt activity is minimal. Fine to disable interrupts during ADB.

* ADB keyboard internal polling rates, worst-case (keys constantly being pressed and released, ADB transaction between every poll): M3501 122Hz, M0116 57Hz. Note these are calculated based on looking at the polling signals with a scope. I hope to actually produce these key rates (half that of course) at some point to confirm these calculations.

* Internal polling rates are slightly higher when no keys are being pressed because ADB activity pauses internal polling until the transfer is done. This is why polling too quickly, especially on keyboards with lower internal polling rates, can cause them to become slow to respond, as this lowers the polling rate. In the extreme, you could cause the internal polling rate to go down to 1 Hz.

* Key pressed and released between ADB reads: M3501 generates key down and key up events for same key on next ADB read. M0116 doesn't generate anything apparently.
« Last Edit: Sun, 10 November 2013, 23:25:16 by blargg »

Offline blargg

  • Posts: 45
    • My github
Re: ADB to USB keyboard converter
« Reply #221 on: Mon, 11 November 2013, 20:37:28 »
Update to the USBASP code:

adb-usb-usbasp-2.zip

* Keyboard works after resume from sleep.
* Power key wakes host.
* Changed polling to 12ms (83Hz). Works better with M0116. Can still be adjusted back to 8ms (125Hz) in main.c
* Fixed dropped key when it's pressed and released in same ADB event.
* Reorganized code and made USB synchronization more robust.

I also found that the M0116 can generate simultaneous key down and key up events in one ADB transaction, so maybe this was the problem occurring there too.

I achieved 41.1Hz single key press rate on the M3501 when I set the polling period to 8ms in the USBASP code.

Now on to the Teensy code, which can send USB updates every 2ms.

Offline hasu

  • Thread Starter
  • Posts: 2768
  • Location: Tokyo, Japan
  • @tmk
    • tmk keyboard firmware project
Re: ADB to USB keyboard converter
« Reply #222 on: Thu, 14 November 2013, 15:59:28 »
blargg, Thanks for your testing and further research. Incredibly great skills and jobs!

Ah, this is very likely the cuase of key drop problem. I'll fix this fault of my firmware with how your 'extra_key' does later.

I also found that the M0116 can generate simultaneous key down and key up events in one ADB transaction, so maybe this was the problem occurring there too.
TMK products:HHKB Alt  ⌨ConvertersAlps64FC660C AltFC980C Alt

Offline blargg

  • Posts: 45
    • My github
Re: ADB to USB keyboard converter
« Reply #223 on: Thu, 14 November 2013, 18:03:08 »
I've spent the last few days full-time working on this code. New versions of my USBASP and Teensy ADB converter code (renamed projects for clarity):

blargg-adb-usbasp-3.zip

* Now merges extra ADB events with next where possible, making better use of limited USB update opportunities.
* Eliminated adjustable ADB polling rate, as higher rates only hurt, and improved USB synchronization made adjustable polling impossible.
* Consolidated sources.
* Using 16-bit timer1 for everything.

blargg-adb-teensy-2.zip

* Changed polling to 12ms (83Hz). Works better with M0116. Can still be adjusted back to 8ms (125Hz) in main.c
* Fixed dropped key when it's pressed and released in same ADB event.
* Reorganized code to be in sync with v-usb version.
* Disable interrupts for all ADB transactions.
* Send each ADB event byte as a separate USB report. This ensures things are in order and cleanly handles cases when the same key is pressed then released in a single ADB event.

More research

* The M0116 can generate key down and key up in same event word.

* Just as keyboard can report key down then key up in same event (key down in upper byte), it can report key up then key down in same event (in this case, the key up is in the upper byte).

* The keyboards buffer up key presses done faster than ADB polling. In a test on the M0116, I polled ADB only once every four seconds. Pressing a, waiting until it appeared, then pressing 123456 quickly resulted in 1234 being received over the next 16 seconds. So buffer is 4 keys. And on the M3501, it buffers 16 key presses. It even buffers the relative order of presses and releases of multiple keys, replaying everything as it occurred. So it's likely that the buffers are actually 8 and 32 events, respectively, holding key press and release events until they're read by host. I never realized how involved the driver in a keyboard could be.

* Power key presses are buffered just as others.

* Power key press generates 7F7F, and release FFFF. These special encodings are necessary to differentiate between the FF merely meaning no event (the 7F7F isn't necessary; press could be encoded like any other key).

* A 12ms ADB polling rate is ideal, even for the M3501; 8ms only improves maximum key press rate by a hair, and 4ms just makes it far worse.

Handling key press and release in same event

With the Teensy USB, the host can poll it as quickly as every 2ms, so handling key press and release in same event is trivial: just handle each as a separate USB report. In my Teensy code I always handle the two ADB bytes separately, since this preserves the order of key presses as well.

An easy way to check whether your handling of this is working is to lower your ADB polling rate to say once a second, ensuring that any key presses result in a key down and key up in the same event.

In my V-USB code, where USB polling is only 8ms, I intelligently defer and merge ADB events across polls, to keep the report rate as high as posssible. As the code shows, this is very involved and I wouldn't recommend it on the Teensy at all.

Timings

With my improved Teensy and V-USB code, I get what might be the best possible timings on the M3501 (the M0116 timings are the same as before):

Code: [Select]
41.7Hz M3501 blargg-adb-usbasp-3
38.5Hz M3501 blargg-adb-teensy-2

The M3501 polls around 122Hz, which would suggest a 61Hz maximum key press rate. But, for debouncing purposes, it might require two polls of the key released before it will register another key press. If this is true, then the maximum key press rate would be 40.7Hz.

Disabling interrupts during ADB

For the Teensy code, interrupts should be disabled for all of ADB code, including when sending. The USB hardware means that you don't need interrupts enabled constantly. I mention this hasu because I think your current ADB code only disables interrupts when receiving from the keyboard.

Continuing the search for the dropped keys problem

The latest Teensy code I posted is worthy of continued testing for the dropped keys problem. tufty, if you could give this a try on your M0116, that'd be great. I can then continue my earlier list of things to try if even this doesn't work.
« Last Edit: Thu, 14 November 2013, 18:08:22 by blargg »

Offline tufty

  • Posts: 347
  • Location: French Alps
Re: ADB to USB keyboard converter
« Reply #224 on: Fri, 15 November 2013, 01:49:48 »
Hi Shay

Any chance you could put the teensy code up on github?  Doesn't compile out of the box for me (gcc 4.6.2), I'll clone on my account and see if I can patch up the errors.  Otherwise, the errors are issues with non-const stuff with __attribute__(progmem).

Code: [Select]
error: variable ĎÖí must be const in order to be put into read-only section by means of Ď__attribute__((progmem))íitems in error so far are device_descriptor, keyboard_hid_report_desc, config1_descriptor, string0, string1, string2 and descriptor_list.

There's also a warning on __builtin_avr_delay_cycles being implicitly defined.

Cheers

Simon

Offline blargg

  • Posts: 45
    • My github
Re: ADB to USB keyboard converter
« Reply #225 on: Fri, 15 November 2013, 13:16:31 »
OK, after some bumps I've got a repo up for it (thanks for the push to figure git out):

https://github.com/gblargg/adb-usb

It was probably the -Wall and -Wextra options in the Makefile causing the problems, which I've removed from the Makefile. I'm using avr-gcc 4.5.3 which probably doesn't have as strict warnings.

I also built a .hex file for you using your settings posted earlier (PORTC, bit 7), if you want to just flash this without building the source:

blargg-adb-usb-3.hex.zip

Offline tufty

  • Posts: 347
  • Location: French Alps
Re: ADB to USB keyboard converter
« Reply #226 on: Mon, 18 November 2013, 04:06:00 »
Had a heavy weekend, haven't had time to play.  I'll try and get a test or two done in the next day or so.

Simon

Offline tufty

  • Posts: 347
  • Location: French Alps
Re: ADB to USB keyboard converter
« Reply #227 on: Wed, 20 November 2013, 07:45:14 »
Helluva week going on, but just had a try.

a - binary doesn't work.  My guess is that it's built for teensy2.0++ rather than teensy 2.0
b - code won't compile.  It mentions DDRA, which apparently the teensy 2.0 doesn't have, and tries to use _builtin_avr_delay_cycles, which I don't appear to have either.

Haven't had a chance to dig much more, maybe tonight.

Simon

Offline blargg

  • Posts: 45
    • My github
Re: ADB to USB keyboard converter
« Reply #228 on: Wed, 20 November 2013, 12:50:58 »
OK, rebuild for your teensy 2.0 and pushed fixes for PORTA and __builtin_avr_delay_cycles issues (thanks for trying the code):

blargg-adb-usb-3-teensy-2.0.hex.zip

Hopefully the hex or source now works for you.

Offline tufty

  • Posts: 347
  • Location: French Alps
Re: ADB to USB keyboard converter
« Reply #229 on: Tue, 26 November 2013, 01:42:06 »
So, the week's been hellish, but I just got a chance to play.

Firstly, your hex works fine on my teensy.
Secondly, as my typing without swearage will attest, there's no dropped keys so far.  This is most excellent news.  I just typed out a 400 word article at full clip, and the only issue I've seen was my slightly "sticky" space bar, and that's a mechanical issue.

You are a star.

Just noticed that the teensy's LED is glowing orange, though. Not sure if it's getting a high-freq 50% duty cycle signal across it, or if it's something to do with pin resets.  It's on PD6, IIRC

I'll probably end up hacking my "standard" M0116 layout into a fork of your code (the extended layout you have used swaps option and command on the M0116, and loses my second layer mappings), but it occurs to me that it should be possible to detect the type of keyboard at ADB startup, by looking at the original handler id the keyboard has, and swap layouts dynamically.  Useful for people building external converter boxes that need to handle both "standard" and "extended" keyboards.
« Last Edit: Tue, 26 November 2013, 01:58:35 by tufty »

Offline blargg

  • Posts: 45
    • My github
Re: ADB to USB keyboard converter
« Reply #230 on: Tue, 26 November 2013, 13:50:12 »
Great to hear! This gives us code that works, and tmk which drops keys, and among the differences a few that are the cause.

Quote
Just noticed that the teensy's LED is glowing orange, though. Not sure if it's getting a high-freq 50% duty cycle signal across it, or if it's something to do with pin resets.  It's on PD6, IIRC
Oh yeah, I have my code by default put all pins as inputs with weak pull-ups. This is the safest approach since nothing floats and anything else unexpectedly connected won't play tug-of-war with pins set as outputs. I didn't bother making PD6 an output held low. Will update the repo with that fix.

Quote
I'll probably end up hacking my "standard" M0116 layout into a fork of your code (the extended layout you have used swaps option and command on the M0116, and loses my second layer mappings),
Since you'll be doing more reflashing, I'd like to try implementing the key pressed/released in same event fix in tmk's code for you to try before you port the layouts to mine, so we can hopefully have tmk's working just as well as mine.

tmk github: "Remove tentative files from blargg"  Yay, I hated seeing my stuff clutter up the adb converter there. Simple is good :)

Quote
it should be possible to detect the type of keyboard at ADB startup, by looking at the original handler id the keyboard has, and swap layouts dynamically.  Useful for people building external converter boxes that need to handle both "standard" and "extended" keyboards.
Good idea. I'll have to see whether keyboards have some kind of model ID readable, or some low-level difference in how they respond.

Regarding reconfiguration, I've recently discovered bootloaders and the great USBaspLoader (and done a big rewrite of it which I'm releasing soon). These would be great for this kind of thing on the USBASP stick, and I remember seeing hooks for them in tmk's code even. Updating of the layouts without needing a separate progammer.

I also ordered some attiny85's and am going to put the ADB converter on to it. I think I can get it down to the attiny85, three generic small-signal diodes, a small capacitor, and a few resistors (two 1K, two 68 ohm). This will support USB self-reprogramming via avrdude, so layout customizations and bug fixes could be applied without any separate programmer.
« Last Edit: Tue, 26 November 2013, 14:17:04 by blargg »

Offline blargg

  • Posts: 45
    • My github
Re: ADB to USB keyboard converter
« Reply #231 on: Tue, 26 November 2013, 15:35:28 »
I forked tmk_keyboard and added the same-key-down-then-up-in-adb-event fix to it:

https://github.com/gblargg/tmk_keyboard

Also tested it by changing ADB polling rate to 1Hz (and tested that old code indeed lost the keys).

I see that hasu has modified the ADB code to wrap all bus operations in cli()/sei(), so it should be solid now, unless the problem is elsewhere in tmk's matrix handling, keyboard HID driver, or LUFA.

And no thanks to gcc for giving me a nice compiler bug that I spent an hour trying to realize was a compiler bug and not my bug. Confidence shaken in GCC, as it kept occuring until I convoluted my code and added volatile to get around it, though have no idea what conditions cause the compiler bug.

EDIT: I ran a test to see what differences the keyboard have via registers, for differentiating which is connected and automatically selecting the keymap:
Code: [Select]
        Talk   1    2    3
M0487 (IIgs): 0000 xFFF 6x08
M0116 (Kybd): 0000 FF00 6x01
M3501 (Ext2): 0000 FFFF 6x02

I just send a talk command (same as one for checking keys, just a different register number) and print the 16-bit result. The x nibbles were random. Register 3 is most promising. Bit 14 is service request enable, which defaults to 1, and bit 13 is exceptional event, set to 1 if not supported. So seeing a 6 there matches what the docs suggest. Bits 8-11 are the device address, which it apparently chooses at random? I was seeing values all over the place. I wonder whether my test code was somehow triggering a collision and the keyboard were choosing a random address.

The low byte is the one that is perfect for us. Docs show it's the handler ID. So that's it. IIgs crappy keyboard is 0x08, Apple Keyboard is 0x01, and Extended Keyboard II is 0x02.
« Last Edit: Tue, 26 November 2013, 17:23:32 by blargg »

Offline tufty

  • Posts: 347
  • Location: French Alps
Re: ADB to USB keyboard converter
« Reply #232 on: Wed, 27 November 2013, 01:55:21 »
The device address *shouldn't* be random, it should be 2 for a keyboard.  It's wierd that you're seeing odd values.  Are you doing a full bus reset prior to checking addresses (shouldn't need to do address resolution, we only have one device)?

I'd recommend reading (and saving a copy of) Space Aliens Ate My Mouse if you haven't already.

Keyboard type resolution should definitely start with register 3's default handler id, and there may be some register 2 information allowing us to get more specific.

There's things that can be done with register 1 for specific keyboards, apparently - the iBook keyboard can be told to do different things through there, for example.  Chapter and verse is probably best got from the Apple's source, http://opensource.apple.com/source/AppleADBKeyboard/AppleADBKeyboard-232.0.1/AppleADBKeyboard.cpp for example.

Offline hasu

  • Thread Starter
  • Posts: 2768
  • Location: Tokyo, Japan
  • @tmk
    • tmk keyboard firmware project
Re: ADB to USB keyboard converter
« Reply #233 on: Thu, 28 November 2013, 01:39:50 »
blargg,
I merged your fix of extra key. Thank you.
TMK products:HHKB Alt  ⌨ConvertersAlps64FC660C AltFC980C Alt

Offline blargg

  • Posts: 45
    • My github
Re: ADB to USB keyboard converter
« Reply #234 on: Thu, 28 November 2013, 01:47:39 »
Are you doing a full bus reset prior to checking addresses (shouldn't need to do address resolution, we only have one device)?
Currently the ADB code doesn't do any kind of reset. It'd be nice if it did an explicit reset in the beginning. It must be triggering a collision and causing this. I should get this resolved even though it's posed no problem.

Quote
I'd recommend reading (and saving a copy of) Space Aliens Ate My Mouse if you haven't already.

Keyboard type resolution should definitely start with register 3's default handler id, and there may be some register 2 information allowing us to get more specific.
Yeah, I scanned that and the other ADB docs (the IM chapter, IIgs ADB guide, and Microchip's app note) but I couldn't find any list of keyboard handler IDs like I found empirically.

Quote
Chapter and verse is probably best got from the Apple's source, http://opensource.apple.com/source/AppleADBKeyboard/AppleADBKeyboard-232.0.1/AppleADBKeyboard.cpp for example.
Interesting that it still has ADB vestiges that are preserved in the Darwin driver code.

Offline tufty

  • Posts: 347
  • Location: French Alps
Re: ADB to USB keyboard converter
« Reply #235 on: Thu, 28 November 2013, 09:10:27 »
This might help - it's "classic" side, but there has to be a way of discovering - http://www.fenestrated.net/~macman/mirrors/Apple%20Technotes%20(As%20of%202002)/tb/tb_12.html

The adb stuff in Darwin is because, at least up to 10.4, supported machines still used it.  Keyboards and trackpads on (I think) the G4 iBook were ADB, for example.  I know my powerbook G4 is.

Offline blargg

  • Posts: 45
    • My github
Re: ADB to USB keyboard converter
« Reply #236 on: Fri, 13 December 2013, 22:33:45 »
I got some attiny85 chips and while the ADB converter works (including without an external crystal), it's not going to be any cheaper/easier than reprogramming a USBASP or some USB-equipped AVR board. USBASP is the way to go. Already-assembled with a USB connector, status LEDs, a place for a jumper, good bootloader support for self-updating, and an ISP connector and included ribbon cable to cut in half and connect the ADB cable to. This is ideal.

When I have some motivation I'll add keyboard type detection and support for different layouts for each type.

Offline multiholle

  • Posts: 1
Re: ADB to USB keyboard converter
« Reply #237 on: Sat, 14 December 2013, 10:25:41 »
I tried your Code with my Apple Extended Keyboard II and a Teensy 2.0. It worked a couple of times, but not always. Right now it's not working at all. When I enable the debug output I get the following:

Code: [Select]
Waiting for device:....
Listening:
debug enabled.
Keyboard start.

After that all three green LEDs of the keyboard are on and nothing happens if I press a key. Any ideas?

Offline hasu

  • Thread Starter
  • Posts: 2768
  • Location: Tokyo, Japan
  • @tmk
    • tmk keyboard firmware project
Re: ADB to USB keyboard converter
« Reply #238 on: Sat, 14 December 2013, 18:27:45 »
blargg, nice. Can I have usbasploader and your converter with attiny85? 8KB is enough to do that?

multiholle, do you have pull-up resistor? Pic of your converter may help.
TMK products:HHKB Alt  ⌨ConvertersAlps64FC660C AltFC980C Alt

Offline blargg

  • Posts: 45
    • My github
Re: ADB to USB keyboard converter
« Reply #239 on: Sun, 15 December 2013, 18:59:36 »
hasu, oh, do you mean can USBaspLoader fit on an attiny85 with the USB-ADB converter? They should combine fine, as the ADB-USB code is only about 3000 bytes, and the bootloader under 2000. The attiny85 is so limited that the bootloaders have to jump through extra hoops. The USBasp reprogrammed is preferable. It has more I/O pins even just on the end connector than the attiny, and a crystal. I'm curious as to what advantages an attiny85 has over it.
« Last Edit: Sun, 15 December 2013, 19:04:00 by blargg »

Offline hasu

  • Thread Starter
  • Posts: 2768
  • Location: Tokyo, Japan
  • @tmk
    • tmk keyboard firmware project
Re: ADB to USB keyboard converter
« Reply #240 on: Sun, 15 December 2013, 19:35:59 »
Thanks, 3KB code size is great.
Yes. I was thinking about tiny85 with USBaspLoader+ADB converter because I prefered dedicated small DIY conveter than tentative setup with cheap USBasp hardware. But I found I don't have it in my parts box and I can get mega328p at almost same cost of tiny85 at local store :) I'll go with mega328p if I make my own DIY converter. But still 8pin DIP is attractive size for DIY converter.

I see, getting USBasp hardware from ebay is the best in terms of cost effective. I'll also get some.
TMK products:HHKB Alt  ⌨ConvertersAlps64FC660C AltFC980C Alt

Offline blargg

  • Posts: 45
    • My github
Re: ADB to USB keyboard converter
« Reply #241 on: Sun, 15 December 2013, 20:33:48 »
Be sure you get the one that claims 5V/3.3V, otherwise you might get a cheaper one that doesn't expose the TX/RX pins. They might show a picture of the LC Soft one but still send the cheaper one, which is why to look for 3.3V with jumper selection claim, then it's the LC soft board. I should be receiving one from another seller and I'll report back which two so far sent me the right one.

Like you said, more capable atmega chips are about the same price as an attiny. Also the attiny series has fewer features, e.g. frozen while reflashing itself, which makes USB harder to handle without errors, no USART, only 8-bit counters. On the other hand, the tiny has a 16MHz internal RC, 20MHz maximum frequency, pin change interrupt, that only newer atmega chips seem to have.

Offline jacobolus

  • Posts: 3634
  • Location: San Francisco, CA
Re: ADB to USB keyboard converter
« Reply #242 on: Sun, 22 December 2013, 05:51:48 »
Thank you guys so much for all the hard work. I just used the code from the master branch of tmk/tmk_keyboard, with a teensy 2.0 installed inside an M0116, and it works perfectly! (Though the default layout seems to have command and option keys switched; but thatís easy enough to reverse myself.)

Now I just need to figure out how to turn the caps lock key [I replaced the switch w/ a non-toggle version] into an Fn key, so I can use the regular number row for F keys, etc. Thatís the project for tomorrow or the next day, now that the hardware part works.

Anyway, again thanks.

Offline tufty

  • Posts: 347
  • Location: French Alps
Re: ADB to USB keyboard converter
« Reply #243 on: Sun, 22 December 2013, 10:50:23 »
Thank you guys so much for all the hard work. I just used the code from the master branch of tmk/tmk_keyboard, with a teensy 2.0 installed inside an M0116, and it works perfectly! (Though the default layout seems to have command and option keys switched; but thatís easy enough to reverse myself.)

Now I just need to figure out how to turn the caps lock key [I replaced the switch w/ a non-toggle version] into an Fn key, so I can use the regular number row for F keys, etc. Thatís the project for tomorrow or the next day, now that the hardware part works.

Anyway, again thanks.
My fork of the tmk repository has a capslock-triggered function layer.  It's a bit behind hasu's repository, though. You should be able to do some mergery to get something that works.

Offline arfink

  • Posts: 66
Re: ADB to USB keyboard converter
« Reply #244 on: Wed, 15 January 2014, 20:18:19 »
Funny running into you again here Shay. It's been a long time. :)

Offline 128keaton

  • Posts: 15
    • Homepage
Re: ADB to USB keyboard converter
« Reply #245 on: Mon, 24 March 2014, 10:41:29 »
Hello folks. I might be reviving a dead project, but I've been having trouble getting my Apple Keyboard II (m0487) to work. I am using an Arduino Micro, it should work. I've put the 1K resistor on the DATA Line. I am using the coiled cable, but it shouldn't matter as I have the 1k resistor. Currently, I've tried it on two Macs, but it doesn't want to work. USB Prober detects it. Everything appears to be in place, I just cannot get the keyboard to type! Any suggestions?

EDIT: I tested the keyboard on my macintosh classic, it works fine there. (ADB) so the keyboard is working.
Here is the setup:


EDIT 2: Found the error:
Code: [Select]
adb_host_kbd_recv: ERROR(-17)
adb_host_kbd_recv: ERROR(-17)
adb_host_kbd_recv: ERROR(-17)
adb_host_kbd_recv: ERROR(-17)



I just have no idea what it means :P.
« Last Edit: Mon, 24 March 2014, 16:07:11 by 128keaton »
Ducky Shine - Gray alum (stock)
AEKIII - Gray (stock) with Arduino Micro

Offline robertarrington

  • Posts: 1
Re: ADB to USB keyboard converter
« Reply #246 on: Mon, 24 March 2014, 15:26:57 »
Hi.

I just purchased an AEKII on eBay and am interested in using this tool to convert its ADB signal to USB.

However, I accidentally purchased a Teensy 3.1 (MK20DX256). Is there any way to use this firmware with a 3.1?

Thanks

Offline jacobolus

  • Posts: 3634
  • Location: San Francisco, CA
Re: ADB to USB keyboard converter
« Reply #247 on: Mon, 24 March 2014, 18:03:57 »
However, I accidentally purchased a Teensy 3.1 (MK20DX256). Is there any way to use this firmware with a 3.1?
No. If youíre willing to write a whole bunch of code, then some of Hasuís code could probably be re-used. But thatís probably a multi-week effort for a competent programmer.

Just go buy a Teensy 2.0, or some similar little microcontroller (there are some tiny Arduino clones on ebay for $5/each).

Offline hasu

  • Thread Starter
  • Posts: 2768
  • Location: Tokyo, Japan
  • @tmk
    • tmk keyboard firmware project
Re: ADB to USB keyboard converter
« Reply #248 on: Mon, 24 March 2014, 18:49:27 »
128keaton,
Pull up resistor should be connected in parallel between Data line and 5V. Your resistor is located in series. I assume green line is Data line, the line should be connected to a port PD0  directly and the resister between 5V and PD0.


For later reference,

PULL UP RESISTOR:
Code: [Select]
Keyboard       Conveter
               ,------.
5V------+------|VCC   |
        |      |      |
        R      |      |
        |      |      |
Data----+------|PD0   |
               |      |
GND------------|GND   |
               `------'
R: 1K Ohm resistor

WRONG:
Code: [Select]
Keyboard       Conveter
               ,------.
5V-------------|VCC   |                                                                                                             
               |      |
               |      |
               |      |
Data----R------|PD0   |
               |      |
GND------------|GND   |
               `------'
« Last Edit: Mon, 24 March 2014, 18:57:46 by hasu »
TMK products:HHKB Alt  ⌨ConvertersAlps64FC660C AltFC980C Alt

Offline jacobolus

  • Posts: 3634
  • Location: San Francisco, CA
Re: ADB to USB keyboard converter
« Reply #249 on: Mon, 24 March 2014, 19:09:37 »
128keaton, yeah, as Hasu says, you want to plug the resistor into your breadboard to directly connect the 'data' and +5V pins. (You donít need to attach it to the wires coming from your ADB plug.)
« Last Edit: Mon, 24 March 2014, 19:12:45 by jacobolus »