Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ADB: Extended Apple Mouse Protocol #274

Closed
tmk opened this issue Dec 5, 2015 · 9 comments
Closed

ADB: Extended Apple Mouse Protocol #274

tmk opened this issue Dec 5, 2015 · 9 comments

Comments

@tmk
Copy link
Owner

tmk commented Dec 5, 2015

I re-dsicovered this documentation about ADB mouse protocol. This helps to add multi-button mouse support to ADB protocol.
https://developer.apple.com/legacy/library/technotes/hw/hw_01.html#Extended

Some people may want to use their mouse or trackball with enabling all buttons. #225

@tmk tmk added the TODO label Dec 7, 2015
@tmk
Copy link
Owner Author

tmk commented Dec 7, 2015

Someone with ADB multi-button mouse/trackball, could you try this fun job?

Or donate it to me :D

@rebpdx
Copy link

rebpdx commented Dec 11, 2016

@tmk I have a Kensington Turbo and am interested in helping. I'm a little confused at the comments in the existing adb_talk function about, stop bit cannot be checked normally due to SRQ possibility. https://github.com/tmk/tmk_keyboard/blob/master/tmk_core/protocol/adb.c#L145-L146

Is it possible to handle stop bit and SRQ to dynamically stop at end of 2-5 byte transmission or is it required ahead of adb_talk call to assume a transmission size? I think transmission size by mouse resolution could be determined but that doesn't seem like the proper adb way of handling it.

@tmk
Copy link
Owner Author

tmk commented Dec 12, 2016

The document doesn't say clearly but I guess you can know/speculate mouse data size from mouse button size or device identifier of register 1.

It may be possible to determine the size by monitoring signal after stop-bit but I don't think it is what ADB protocol requires.

@numist
Copy link

numist commented Dec 6, 2018

Monitoring the signal after the stop bit is the correct way to detect the end of a variable-size ADB payload. You should never be sent more than 8 bytes from a device, so you can use that as an upper bound for any buffers that you use for clocking/decoding data.

In my firmware I detect the end of transmission by setting an edge detection timeout that is the same as the bit cell time (100µs), represented as timeoutMicros below:

/*
** Bit values are each recorded in two timers, the first measuring the LOW
** duration, the second measuring the HIGH duration. ADB differentiates bits
** by LOW duration, based on whether the duration is greater or smaller than
** half of the bit cell; a 0 spends more than half the bit cell LOW, and
** a 1 spends more than half the bit cell HIGH.
**
** The stop bit, being the last traffic of the packet, only sets the first of
** its timers. This makes overflow conditions easily detected and avoided; if
** the last timer in the array is nonzero, the device was still transmitting.
**
** ADB defines the maximum payload size of a packet to 5 bytes, so the max
** number of bits is:
**
**   1 start bit + (5 bytes * 8 bits/byte) + 1 stop bit -> 42 bits
**
** The number of timers needed to record 42 bits from the bus is:
**
**   2 timers/bit * 42 bits -> 84 timers
**
** Unfortunately, register 1 of the Extended Mouse Protocol is 8 bytes...
** DOC: https://developer.apple.com/legacy/library/technotes/hw/hw_01.html#Extended
*/
#define TIMER_COUNT (2 * (1 + 8 * 8 + 1))
unsigned char timers[TIMER_COUNT];
unsigned char nTimers;
unsigned long startTimerMicros = 0;
int iTimer = -1;

do {
  unsigned long currentTimeMicros;
  unsigned char val, prevVal = digitalRead(ADB_PIN);
  // Timeout set to 260µs for first edge after request, 100µs otherwise
  unsigned long timeoutMicros =  micros() + (iTimer >= 0 ? TX_MAX_BIT_CELL_TIME : TX_MAX_STOP_BIT_TO_START_BIT_TIME);

  // Loop until wire changes state or timeout reached
  while(prevVal == (val = digitalRead(ADB_PIN)) && timeoutMicros > micros());

  // Record current time for cell decoding
  currentTimeMicros = micros();

  if (prevVal == val) {
    // Timeout; device is finished transmitting (or never started)
    break;
  }
  
  // Record elapsed time in timers[]
  if (iTimer >= 0) {
    timer[iTimer] = currentTimeMicros - startTimerMicros;
  }
  startTimerMicros = currentTimeMicros;
  iTimer++;
} while (iTimer < TIMER_COUNT);
nTimers = iTimer < 0 ? 0 : iTimer;

// Tons of error condition checking and bit cell timer decoding follows…  

@tmk
Copy link
Owner Author

tmk commented Dec 6, 2018

Thank you for the input!
Can we refer to other part of your firmware codes somewhere?

@numist
Copy link

numist commented Dec 7, 2018

It's in a private GitHub repo (I've granted you access), but it looks like I never pushed extended mouse support so I hope to find it on my old computer. All the signalling code and some other odds and ends are present though.

@lbibass
Copy link

lbibass commented May 8, 2019

@numist did you ever get it working? I would love to be able to use my turbo mouse with some of my other apple hardware. Thanks!

@numist
Copy link

numist commented May 10, 2019

@lbibass: haven't had opportunity to yet, and work is in its busy season so it's unlikely I'll be able to until July at the earliest 😕

tmk added a commit that referenced this issue Jun 23, 2019
Also add Kensington Turbo Mouse 5 specific initialization
@tmk
Copy link
Owner Author

tmk commented Jun 23, 2019

I got Turbo Mouse(#64210) the other day and added code for Extended Mouse Protocol and Turbo Mouse at 814eaa2.

To enable all four buttons on the trackball enigmatic device specific initialization was needed.

If your device is not eabled fully with simple 'Extended Mouse Protocol' you will need to add code for initialization commands probably.

NetBSD and Linux has good info for command sequence required by multi-button mouse/trackballs.
https://elixir.bootlin.com/linux/v4.4/source/drivers/macintosh/adbhid.c#L1176
https://github.com/NetBSD/src/blob/64b8a48e1288eb3902ed73113d157af50b2ec596/sys/arch/macppc/dev/ams.c#L261

tokuhira pushed a commit to tokuhira/tmk_keyboard that referenced this issue Jan 10, 2020
Also add Kensington Turbo Mouse 5 specific initialization
@tmk tmk closed this as completed Feb 4, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants