diff --git a/USBHost_t36.h b/USBHost_t36.h index 702fd92..22b7b79 100644 --- a/USBHost_t36.h +++ b/USBHost_t36.h @@ -53,7 +53,7 @@ // your best effort to read chapter 4 before asking USB questions! -#define USBHOST_PRINT_DEBUG +// #define USBHOST_PRINT_DEBUG /************************************************/ /* Data Types */ @@ -474,13 +474,13 @@ class KeyboardController : public USBDriver { public: KeyboardController(USBHost &host) { init(); } KeyboardController(USBHost *host) { init(); } - int available(); - int read(); - uint8_t getKey(); - uint8_t getModifiers(); - uint8_t getOemKey(); - void attachPress(void (*keyPressed)()); - void attachRelease(void (*keyReleased)()); + int available(); + int read(); + uint16_t getKey() { return keyCode; } + uint8_t getModifiers() { return modifiers; } + uint8_t getOemKey() { return keyOEM; } + void attachPress(void (*f)(int unicode)) { keyPressedFunction = f; } + void attachRelease(void (*f)(int unicode)) { keyReleasedFunction = f; } protected: virtual bool claim(Device_t *device, int type, const uint8_t *descriptors, uint32_t len); virtual void control(const Transfer_t *transfer); @@ -489,11 +489,19 @@ protected: void new_data(const Transfer_t *transfer); void init(); private: - void (*keyPressedFunction)(); - void (*keyReleasedFunction)(); + void update(); + uint16_t convert_to_unicode(uint32_t mod, uint32_t key); + void key_press(uint32_t mod, uint32_t key); + void key_release(uint32_t mod, uint32_t key); + void (*keyPressedFunction)(int unicode); + void (*keyReleasedFunction)(int unicode); Pipe_t *datapipe; setup_t setup; uint8_t report[8]; + uint16_t keyCode; + uint8_t modifiers; + uint8_t keyOEM; + uint8_t prev_report[8]; Pipe_t mypipes[2] __attribute__ ((aligned(32))); Transfer_t mytransfers[4] __attribute__ ((aligned(32))); }; diff --git a/k66_usbhost.ino b/k66_usbhost.ino index fc3a60c..dba26ae 100644 --- a/k66_usbhost.ino +++ b/k66_usbhost.ino @@ -55,7 +55,8 @@ void setup() USBHS_USBCMD |= USBHS_USBCMD_IAA; if (rootdev) print(rootdev->control_pipe); #endif - + keyboard1.attachPress(press); + keyboard2.attachPress(press); midi1.setHandleNoteOff(OnNoteOff); midi1.setHandleNoteOn(OnNoteOn); midi1.setHandleControlChange(OnControlChange); @@ -77,7 +78,16 @@ void pulse(int usec) digitalWriteFast(30, LOW); } - +void press(int key) +{ + Serial.print("key "); + Serial.println(key); + //Serial.print("key "); + //Serial.print((char)keyboard1.getKey()); + //Serial.print(" "); + //Serial.print((char)keyboard2.getKey()); + //Serial.println(); +} void OnNoteOn(byte channel, byte note, byte velocity) { @@ -96,8 +106,8 @@ void OnNoteOff(byte channel, byte note, byte velocity) Serial.print(channel); Serial.print(", note="); Serial.print(note); - Serial.print(", velocity="); - Serial.print(velocity); + //Serial.print(", velocity="); + //Serial.print(velocity); Serial.println(); } diff --git a/keyboard.cpp b/keyboard.cpp index 95bbe52..3802301 100644 --- a/keyboard.cpp +++ b/keyboard.cpp @@ -23,6 +23,7 @@ #include #include "USBHost_t36.h" // Read this header first for key info +#include "keylayouts.h" // from Teensyduino core library void KeyboardController::init() @@ -74,25 +75,110 @@ void KeyboardController::control(const Transfer_t *transfer) void KeyboardController::callback(const Transfer_t *transfer) { - println("KeyboardController Callback (static)"); + //println("KeyboardController Callback (static)"); if (transfer->driver) { ((KeyboardController *)(transfer->driver))->new_data(transfer); } } -void KeyboardController::new_data(const Transfer_t *transfer) -{ - println("KeyboardController Callback (member)"); - print(" KB Data: "); - print_hexbytes(transfer->buffer, 8); - // TODO: parse the new data - queue_Data_Transfer(datapipe, report, 8, this); -} - void KeyboardController::disconnect() { // TODO: free resources } +// Arduino defined this static weak symbol callback, and their +// examples use it as the only way to detect new key presses, +// so unfortunate as static weak callbacks are, it probably +// needs to be supported for compatibility +extern "C" { +void __keyboardControllerEmptyCallback() { } +} +void keyPressed() __attribute__ ((weak, alias("__keyboardControllerEmptyCallback"))); +void keyReleased() __attribute__ ((weak, alias("__keyboardControllerEmptyCallback"))); + +static bool contains(uint8_t b, const uint8_t *data) +{ + if (data[2] == b || data[3] == b || data[4] == b) return true; + if (data[5] == b || data[6] == b || data[7] == b) return true; + return false; +} + +void KeyboardController::new_data(const Transfer_t *transfer) +{ + println("KeyboardController Callback (member)"); + print(" KB Data: "); + print_hexbytes(transfer->buffer, 8); + for (int i=2; i < 8; i++) { + uint32_t key = prev_report[i]; + if (key >= 4 && !contains(key, report)) { + key_release(prev_report[0], key); + } + } + for (int i=2; i < 8; i++) { + uint32_t key = report[i]; + if (key >= 4 && !contains(key, prev_report)) { + key_press(report[0], key); + } + } + memcpy(prev_report, report, 8); + queue_Data_Transfer(datapipe, report, 8, this); +} + +void KeyboardController::key_press(uint32_t mod, uint32_t key) +{ + // TODO: queue events, perform callback from Task + println(" press, key=", key); + modifiers = mod; + keyOEM = key; + keyCode = convert_to_unicode(mod, key); + println(" unicode = ", keyCode); + if (keyPressedFunction) { + keyPressedFunction(keyCode); + } else { + keyPressed(); + } +} + +void KeyboardController::key_release(uint32_t mod, uint32_t key) +{ + // TODO: queue events, perform callback from Task + println(" release, key=", key); + modifiers = mod; + keyOEM = key; + keyCode = convert_to_unicode(mod, key); + if (keyReleasedFunction) { + keyReleasedFunction(keyCode); + } else { + keyReleased(); + } +} + +uint16_t KeyboardController::convert_to_unicode(uint32_t mod, uint32_t key) +{ + // TODO: special keys + // TODO: caps lock + // TODO: dead key sequences + if ((mod & 0x02) || (mod & 0x20)) key |= SHIFT_MASK; + for (int i=0; i < 96; i++) { + if (keycodes_ascii[i] == key) return i + 32; + } +#ifdef ISO_8859_1_A0 + for (int i=0; i < 96; i++) { + if (keycodes_iso_8859_1[i] == key) return i + 160; + } +#endif + return 0; +} + + + + + + + + + + +