-
Notifications
You must be signed in to change notification settings - Fork 99
Description
Thank you for your library! I just got a Teensy 4.0, and was able to use the MouseKeyboardForward.ino sketch with a Dell keyboard right out of the box.
My project is to build an HID remapper for my Apple Magic Keyboard A1843, so I can type Command-C and have the office PC receive Ctrl-C (among other features, such as media keys sending UART commands to my iPod).
For the Magic Keyboard, it didn't work when I first plugged it in. I investigated further, and made the following changes to support typing and modifier keys.
C:\Users\burkipe\AppData\Local\Arduino15\packages\teensy\hardware\avr\1.59.0\libraries\USBHost_t36\keyboard.cpp
uint8_t key_modifiers = 0;
uint32_t thisKey = 0;
bool KeyboardController::hid_process_in_data(const Transfer_t *transfer)
{
const uint8_t *buffer = (const uint8_t *)transfer->buffer;
uint16_t len = transfer->length;
const uint8_t *p = buffer;
USBHDBGSerial.printf("HPID(%p, %u):", transfer->driver, len);
if (len > 32) len = 32;
while (len--) USBHDBGSerial.printf(" %02X", *p++);
if (buffer[3] != thisKey) { Keyboard.release(0XF000 | thisKey); thisKey = 0; }
if (buffer[3] != 0x00) { thisKey = buffer[3]; Keyboard.press(0XF000 | thisKey); }
// if (buffer[3] == 0x00) { Keyboard.release(0XF000 | thisKey); thisKey = 0; }
if (buffer[3] == 0x39)
{
// leds_.capsLock = true; updateLEDS();
if (driver_[0] != nullptr) {
USBHDBGSerial.printf("driver_[0]->sendControlPacket");
// Only do it this way if we are a standard USB device
leds_.capsLock = true;
driver_[0]->sendControlPacket(0x21, 9, 0x200, 1, sizeof(leds_.byte), (void*) &leds_.byte);
// sendControlPacket(uint32_t bmRequestType, uint32_t bRequest, uint32_t wValue, uint32_t wIndex, uint32_t wLength, void *buf)
} else {
USBHDBGSerial.printf("driver_[0] is nullptr");
}
}
// Probably need to do some more checking of the data, but
// first pass if length == 8 assume boot format:
// Hoped driver would be something I could check but...
if ((transfer->driver == driver_[0]) && (transfer->length == 8)) {
/*USBHDBGSerial.printf(" (boot)\n"); */
process_boot_keyboard_format(buffer, true);
keyboard_uses_boot_format_ = true;
return true;
}
USBHDBGSerial.printf("\n");
return false;
}
void KeyboardController::hid_input_data(uint32_t usage, int32_t value)
{
// Hack ignore 0xff00 high words as these are user values...
// USBHDBGSerial.printf("KeyboardController: topusage= %x usage=%X, value=%d\n", topusage_, usage, value);
if ((usage & 0xffff0000) == 0xff000000) return;
if ((topusage_ == 0x10000 ) && (usage == 0x700E1) && (value == 1)) { USBHDBGSerial.printf("Left shift down"); int mask = 1 << 1; key_modifiers |= mask; USBHDBGSerial.printf("key_modifiers %x", key_modifiers); Keyboard.set_modifier(key_modifiers); }
if ((topusage_ == 0x10000 ) && (usage == 0x700E1) && (value == 0)) { USBHDBGSerial.printf("Left shift up"); int mask = 1 << 1; key_modifiers &= ~mask; USBHDBGSerial.printf("key_modifiers %x", key_modifiers); Keyboard.set_modifier(key_modifiers); }
if ((topusage_ == 0x10000 ) && (usage == 0x700E3) && (value == 1)) { USBHDBGSerial.printf("Command down"); int mask = 1 << 3; key_modifiers |= mask; USBHDBGSerial.printf("key_modifiers %x", key_modifiers); Keyboard.set_modifier(key_modifiers); }
if ((topusage_ == 0x10000 ) && (usage == 0x700E3) && (value == 0)) { USBHDBGSerial.printf("Command up"); int mask = 1 << 3; key_modifiers &= ~mask; USBHDBGSerial.printf("key_modifiers %x", key_modifiers); Keyboard.set_modifier(key_modifiers); }
if ((topusage_ == 0x10000 ) && (usage == 0x700E0) && (value == 1)) { USBHDBGSerial.printf("Control down"); int mask = 1 << 0; key_modifiers |= mask; USBHDBGSerial.printf("key_modifiers %x", key_modifiers); Keyboard.set_modifier(key_modifiers); }
if ((topusage_ == 0x10000 ) && (usage == 0x700E0) && (value == 0)) { USBHDBGSerial.printf("Control up"); int mask = 1 << 0; key_modifiers &= ~mask; USBHDBGSerial.printf("key_modifiers %x", key_modifiers); Keyboard.set_modifier(key_modifiers); }
if ((topusage_ == 0x10000 ) && (usage == 0x700E2) && (value == 1)) { USBHDBGSerial.printf("Alt down"); int mask = 1 << 2; key_modifiers |= mask; USBHDBGSerial.printf("key_modifiers %x", key_modifiers); Keyboard.set_modifier(key_modifiers); }
if ((topusage_ == 0x10000 ) && (usage == 0x700E2) && (value == 0)) { USBHDBGSerial.printf("Alt up"); int mask = 1 << 2; key_modifiers &= ~mask; USBHDBGSerial.printf("key_modifiers %x", key_modifiers); Keyboard.set_modifier(key_modifiers); }
// If this is the TOPUSAGE_KEYBOARD do in it's own function
if (process_hid_keyboard_data(usage, value))
return;
Now I'm trying to support the CAPS lock LED.
TinyUSB is able to switch on the LED correctly using a Raspberry Pi Pico, by sending the following commands:
On the Teensy,
driver_[0]->sendControlPacket(0x21, 9, 0x200, 1, sizeof(leds_.byte), (void*) &leds_.byte);
is sending correctly, but the second IN transaction is STALLing.
How do I ACK the IN transaction from the keyboard?

