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

usb_usb converter and Apple Magic keyboard #606

Closed
lzhang10 opened this issue Mar 25, 2019 · 28 comments
Closed

usb_usb converter and Apple Magic keyboard #606

lzhang10 opened this issue Mar 25, 2019 · 28 comments

Comments

@lzhang10
Copy link

I am trying to get the usb to usb converter to work with my Apple Magic keyboard in USB mode:

Hardware & Software

What works

  • Most keys on keyboard work out of box

What does not work

  • None of the modifier keys works
  • Eject key (top right next to F12) does not work
  • fn key (bottom left key) does not work

Investigation

Using hid_listen, I can see that:

  1. the keyboard report is 10 bytes instead of the usual 8:
input 1: 01 00 00 00 00 00 00 00 00 00
  1. the first byte is not mods and is always 0x01. mods state is instead in the the second byte.
  2. the last byte serves as an additional fn state:
input 1: 01 00 00 00 00 00 00 00 00 02
  • 0x01: eject key pressed
  • 0x02: fn key pressed
  • 0x03: eject and fn key pressed at the same time

Discussion

I modified the code to use the second byte in the report as mods state. Now all keys work except fn and eject.

I'm looking for ideas to get fn key to work. Right now I put the fn state in the reserved byte. But I don't know what the next step will be. It is unclear to me how to add an additional Fn key state bit.

@tmk
Copy link
Owner

tmk commented Mar 25, 2019

Thanks for the detailed report and PR! It is very helpful info for development.

It seems that the converter fails to request the keyboard to work in standard-boot keyboard mode for some reason and it still sends keys in apple-specific mode. I hope I can improve the converter so that it works with the keyboard in its expected way.

The PR #607 is good workaround for the Apple keyboard but it is not how the converter should works from its design aspect and I won't merge it at this time. I'll keep the PR(and this issue) open for people who want to use the keyboard to discuss it.

@tmk
Copy link
Owner

tmk commented Mar 25, 2019

For reference, this is USB descriptor of the Apple keyboard that lzhang10 sent me.

https://gist.github.com/tmk/0626b78f73575d5c1efa86470c4cdb18

From the descriptor, first byte is request ID(1) and bit0 and bit1 of 10th byte are eject and Fn as lzhang10 described.

I think you can remap those keys in your keymap file using this ad-hoc code.
https://github.com/tmk/tmk_keyboard/pull/607/files#r268881925

@lzhang10
Copy link
Author

I am able to get fn key to work by mapping it to F24 in #607. I'm happy with what I achieved with the usb to usb converter so far:

  1. fn key works in an FN layer, i.e. fn+up => PGUP
  2. I can set up dual keys using Caps(CTRL_L/ESC) and Enter(CTRL_R/Enter). This works better than xcape tool I have been using so far since it's not OS dependent.
  3. SpaceFN layer works.
  4. SHIFT+TAB output ~ using this tip: https://github.com/tmk/tmk_keyboard/wiki/FAQ-Keymap#esc-and--on-a-key

I will close this issue and #607 as search engine can still reach them.

@rsthaeni
Copy link

hi, I'm interested in trying to get my apple magic to work with this (I'm using a japanese one idk if that changes things but the two keys to the left and right of the spacebar worked fine when I edited them with the tmk editor, but all the other modifiers pretty much broke). I'm a total noob and I don't really understand how to change the things you talk about here. Specifically how you "modified the code to use the second byte in the report as mods state". would that modification take place in the keymap.hex file? sorry in advance if my questions are dumb I really don't know what I'm doing here lol

@tmk
Copy link
Owner

tmk commented Mar 27, 2020

You will have to build firmware yourself after apply pull request #607 changes.

You can download hex file here. You can change its keymap by selecting the downloaded hex in 'Base Firmware File:' on Keymap Editor.

66c1154

Change:
7915990

@rsthaeni
Copy link

thanks~~ it works really well, but for some reason I'm getting what I think is ghosting, like when I try to type some things fast it'll make more than one of a part of it, for example when typing 'fik' I get fifik' if I hold f then add on holding i and then press k. sorry if that isn't really clear but it creates typos super frequently when typing a little faster and I can't reproduce it when the keyboard is plugged straight into the computer.

@tmk
Copy link
Owner

tmk commented Mar 27, 2020

If you can read source code and have tools to build firmware, try debuging these lines.

https://github.com/tmk/tmk_keyboard/blob/usb_usb_apple_fix/tmk_core/protocol/usb_hid/parser.cpp#L15-L40

And it would be helpful to debug if you can share outputs from hid_listen.

@rsthaeni
Copy link

rsthaeni commented Mar 27, 2020

Thanks again :DD , I will try at it

@tmk
Copy link
Owner

tmk commented Mar 27, 2020

I just updated code a bit. Not sure this fixes the problem but can you download this again and try?

https://github.com/tmk/tmk_keyboard/tree/usb_usb_apple_fix/converter/usb_usb/binary

@rsthaeni
Copy link

Thanks omg it works so well, thank you so much!!! 😄

@tmk
Copy link
Owner

tmk commented Mar 28, 2020

Great to hear.
Can you share your keyboard model number if it is not A1644?

@rsthaeni
Copy link

It is A1644 Japanese layout

@Findecanor
Copy link

Hmm. The code that sends the "Set Protocol" request looks weird. I'm not sure it sends the request unless the keyboard interface is the first interface (number 0).
In the lsusb output, the keyboard interface is interface number 1.

Therefore, the Magic Keyboard may not receive the request and change to the boot protocol.

You might want to take a look at that.

@rsthaeni
Copy link

I'm not sure what you mean by this cause I'm a total noob, but I've been using the code that hasu linked above since he posted it and I haven't run into any issues with it.

@tmk
Copy link
Owner

tmk commented May 11, 2020

@Findecanor
I think you are right. USB Host library doesn't expect device whose keyboard function located in interface 1. The Apple Magic Keyboard is only the case so far as far as I know. There is small collection of keyboard descriptors in wiki.
https://github.com/tmk/tmk_keyboard/wiki/USB-Descriptor#descriptor-example

This adhoc patch may work with the keyboard.

diff --git a/hidboot.h b/hidboot.h
index 4aafd98..3cc1d9e 100644
--- a/hidboot.h
+++ b/hidboot.h
@@ -459,10 +459,11 @@ uint8_t HIDBoot<BOOT_PROTOCOL>::Init(uint8_t parent, uint8_t port, bool lowspeed
         USBTRACE2("bNumIface:", bNumIface);
 
         // Yes, mouse wants SetProtocol and SetIdle too!
-        for(uint8_t i = 0; i < epMUL(BOOT_PROTOCOL); i++) {
+        //for(uint8_t i = 0; i < epMUL(BOOT_PROTOCOL); i++) {
+        for(uint8_t i = 0; i < 2; i++) {
                 USBTRACE2("\r\nInterface:", i);
                 rcode = SetProtocol(i, bRptProtoEnable ? HID_RPT_PROTOCOL : USB_HID_BOOT_PROTOCOL);
-                if(rcode) goto FailSetProtocol;
+                //if(rcode) goto FailSetProtocol;
                 USBTRACE2("PROTOCOL SET HID_BOOT rcode:", rcode);
                 rcode = SetIdle(i, 0, 0);
                 USBTRACE2("SET_IDLE rcode:", rcode);

This is prebuilt firmware with the patch. Anyone can test this with the keyboard?
The keyboard works except for Fn and eject key, perhaps.

https://gist.githubusercontent.com/tmk/6c798c478e0605f5a944cdb02829db8d/raw/95d36ec2de3d4bd3e0b93116664dbab65ef73c87/usb_usb_unimap.hex

@tmk tmk reopened this May 11, 2020
@addamasartus
Copy link

@tmk Hi Hasu. I'm also using a Japanese apple magic keyboard with your adapter (with the fix you posted for rsthaeni) - and I've run into an issue that doesn't have much to do with the intended functionality of the adapter itself.

I use "sticky keys" in windows because I prefer to just press shift as if it's another key in the line of characters I'm typing. It has an odd quirk where if you let go of a key (that is, if the OS detects a "keyup" event), it cancels the stored shift. This creates a lot of annoying situations where I need to shift the next word, I just spaced and haven't quite released the space bar, I tap shift, release space, and the stored shift is canceled.

I think this could be circumvented via firmware by tricking the OS into taking a space bar "keyup" instantly whenever I press the space bar down. This would remove the ability to hold space, but I can't think of any times where I'd personally want to do that. Do you know of any way to accomplish this with your keymap editor? And if not, would it be much trouble to add this functionality to the firmware you posted for rsthaeni?

@tmk
Copy link
Owner

tmk commented Jun 18, 2020

This creates a lot of annoying situations where I need to shift the next word, I just spaced and haven't quite released the space bar, I tap shift, release space, and the stored shift is canceled.

This probem is not specific to the fix or Apple Magic keyboard, perhaps. And I guess this happens with other usb keyboard even without the covnerter.

If so and you need further help please create new issue for this topic. This may be useful for other people and future reference.

Short answer to your quesion is no, you can't do that in Keymap Editor. You need write code to implement that feature yourself.

@addamasartus
Copy link

Yeah, it happens with any usb keyboard. I'll start a new issue for this, thanks for the response.

@HubKing
Copy link

HubKing commented Jul 16, 2020

Hello. I am investigating the possibility of enabling fn, eject keys on a non-mac, before starting an actual project. Reading the thread, it seems that if I use your code, I could make the fn key work. But how about the eject key? Have you succeeded in making it work? I would like to map it to something else, like F20.

@tmk
Copy link
Owner

tmk commented Jul 17, 2020

@HubKing I don't have the keyobard but think both keys can be remapped.

Testing like below would be helpful if you start your project.

  1. Try this firmware first. Post hid_listen log to see what happens when pressing those keys.
    usb_usb converter and Apple Magic keyboard #606 (comment)

  2. Try this and post log.
    usb_usb converter and Apple Magic keyboard #606 (comment)

@lzhang10
Copy link
Author

lzhang10 commented Jul 19, 2020

I have been using Apple Magic Keyboard with a USB host shield for a while since I opened this issue. Seeing that there are still some interests in this, here is my modified code of tmk_core/protocol/usb_hid/parser.cpp for the magic keyboard where I map Eject to F23 and Fn to F24:

oid KBDReportParser::Parse(USBHID *hid, bool is_rpt_id, uint8_t len, uint8_t *buf)                                                                                                                                
{
     // Apple USB Magic keyboard (Model A1644) (buf[1] == 0x01) has mods byte in buf[1] while buf[0] is always 0x01:
    // input 1: 01 00 00 00 00 00 00 00 00 01
    // It has 8 key input bytes instead of the usual 6
    // buf[9] on magic keyboard:
    // 0x01: eject key (top right next key to F12) pressed
    // 0x02: fn key (bottom left key) pressed
    // 0x03: fn and eject key pressed at the same time
    // we store buf[9] in buf[1] (reserved byte)
    // and map eject and fn to F23 and F24
    if (buf[0] == 0x01 && len == 10) {
        uint8_t t = buf[0];
        buf[0] = buf[1];
        buf[1] = buf[9];
        if (buf[9] & 0x01) buf[6] = KC_F23; // eject -> F23
        if (buf[9] & 0x02) buf[7] = KC_F24; // Fn -> F24
    }

    // Rollover error
    // Cherry: 0101010101010101
    // https://geekhack.org/index.php?topic=69169.msg2638223#msg2638223
    // Apple:  0000010101010101
    // https://geekhack.org/index.php?topic=69169.msg2760969#msg2760969
    if (buf[2] == 0x01) {
       dprint("Rollover error: ignored\r\n");
       return;
    }

    ::memcpy(&report, buf, sizeof(report_keyboard_t));
    time_stamp = millis();
}

Now, you can make Fn key (F24) into a new layer (in my case layer 5).
As for Eject (F23), here is how to map it to CTRL-ALT-DEL:

tmk_keyboard/converter/usb_usb/keymap.c:

...
    [0] = KEYMAP_ALL(
              F13, F14, F15, F16, F17, F18, F19, F20, F21, F22, FN0, FN1,
    ESC,      F1,  F2,  F3,  F4,  F5,  F6,  F7,  F8,  F9,  F10, F11, F12,           PSCR,SLCK,PAUS,    VOLD,VOLU,MUTE,PWR,     HELP,

...
    /* Fn layer (F24) on the magic keyboard
     */
    [5] = KEYMAP_ALL(
              <this will be your Fn layer>
    ),

...
const action_t PROGMEM fn_actions[] = {
  [0] = ACTION_MODS_KEY(MOD_LALT|MOD_LCTL, KC_DEL),    // Eject (F23) key: CTRL+ALT+DEL
  [1] = ACTION_LAYER_MOMENTARY(5),            // Fn (F24) layer

Hope this helps.

tmk added a commit to tmk/USB_Host_Shield_2.0 that referenced this issue Dec 25, 2022
The keyboard has boot keyboard on interface 1, not 0.
hidboot.h did not support device like that.
tmk/tmk_keyboard#606 (comment)
USB Descriptor: https://gist.github.com/tmk/0626b78f73575d5c1efa86470c4cdb18
@tmk
Copy link
Owner

tmk commented Dec 25, 2022

Not tested but this can fix for Apple Magic keyboard model A1644, perhaps.

tmk/USB_Host_Shield_2.0@381956e

@wgjhstt247
Copy link

@tmk I applied your changes from the apple fix branch in addition to tmk/USB_Host_Shield_2.0@381956e

and I’m using the converter with A1843 keyboard. This is the same generation as the A1644 keyboard, but full size. I’m only using this converter as a fix for a ConnectPro KVM at the moment. The ConnectPro KVM correctly reads the hotkey for changing inputs and settings with this keyboard. Without the converter, it wouldn’t work. Thank you for all your work on this! I noticed the caps lock led light doesn’t light up when caps lock is enabled.

Is there anything in particular you would like me to test? I haven’t tried to use debug features, magic key, boot magic, etc or any changes in key mapping really.

tmk added a commit to tmk/USB_Host_Shield_2.0 that referenced this issue Jan 22, 2023
Apple Magic Keyboard(A1644 A1843) has keyboard at interface 1, not 0.
Application can use this function instead of SetReport().
tmk/tmk_keyboard#606 (comment)
tmk added a commit that referenced this issue Jan 22, 2023
The device has keyboard function at interface 1, not 0. #606
@tmk
Copy link
Owner

tmk commented Jan 22, 2023

Thanks for testing. Good to hear that.

For LED indicators, these two patches fix the problem.

Can you try these patches or just prebuilt firmware below?

https://raw.githubusercontent.com/tmk/tmk_keyboard/usb_usb_setprotocol_fix/converter/usb_usb/binary/usb_usb_unimap.hex

If this fix works for you I'll update default firmware on repository and Keymap Editor later.

@wgjhstt247
Copy link

wgjhstt247 commented Jan 23, 2023

@tmk I compiled the firmware with this patch (I run the converter using a Pro Micro 3.3v/8Mhz; prebuilt firmware in the repository is configured for 16Mhz). This patch didn't work and the converter no longer works. Is iface stored at bootIf[0] or bootIf[1] since the keyboard is at interface 1?

@tmk
Copy link
Owner

tmk commented Jan 24, 2023

You have to add the last two patches to your repos that worked before, perhaps.
I don't think the patches break converter behavior severely like that. bootIf[0] will work, because its content should be interface 1.

This branch applies the patches for Apple Magic Keyboard onto the latest repo. You can build with this, note that you need git submodule to update USB_Host_Shield_2.0-tmk.
https://github.com/tmk/tmk_keyboard/tree/usb_usb_setprotocol_fix

I built for 8MHz for test. Can you try this prebuilt firmware and post debug log using hid_listen?
https://github.com/tmk/tmk_keyboard/blob/6314587982f770c6cef7379b32edab1571d422b2/converter/usb_usb/binary/usb_usb_8mhz_debug.hex

@wgjhstt247
Copy link

@tmk My mistake. Something happened with the SPI communication on my board. I've fixed that and pulled down a fresh copy of master along with all the changes here including the led updates. The caps lock led works now with the A1843 keyboard. Thank you!

@tmk
Copy link
Owner

tmk commented Jan 25, 2023

Thanks for testing.

Just updated repo at 8fd2ba9.
Apple Magic Keyboard(A1644/A1843) is supported by default firmware now.

@tmk tmk closed this as completed Jan 25, 2023
tmk added a commit to tmk/USB_Host_Shield_2.0 that referenced this issue Jan 25, 2023
The keyboard has boot keyboard on interface 1, not 0.
hidboot.h did not support device like that.
tmk/tmk_keyboard#606 (comment)
USB Descriptor: https://gist.github.com/tmk/0626b78f73575d5c1efa86470c4cdb18
tmk added a commit to tmk/USB_Host_Shield_2.0 that referenced this issue Jan 25, 2023
Apple Magic Keyboard(A1644 A1843) has keyboard at interface 1, not 0.
Application can use this function instead of SetReport().
tmk/tmk_keyboard#606 (comment)
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

7 participants