Browse Source

Add public API for Keyboard driver

main
PaulStoffregen 7 years ago
parent
commit
f3d503259c
3 changed files with 122 additions and 18 deletions
  1. +18
    -10
      USBHost_t36.h
  2. +14
    -4
      k66_usbhost.ino
  3. +90
    -4
      keyboard.cpp

+ 18
- 10
USBHost_t36.h View File

// your best effort to read chapter 4 before asking USB questions! // your best effort to read chapter 4 before asking USB questions!




#define USBHOST_PRINT_DEBUG
// #define USBHOST_PRINT_DEBUG


/************************************************/ /************************************************/
/* Data Types */ /* Data Types */
public: public:
KeyboardController(USBHost &host) { init(); } KeyboardController(USBHost &host) { init(); }
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: protected:
virtual bool claim(Device_t *device, int type, const uint8_t *descriptors, uint32_t len); virtual bool claim(Device_t *device, int type, const uint8_t *descriptors, uint32_t len);
virtual void control(const Transfer_t *transfer); virtual void control(const Transfer_t *transfer);
void new_data(const Transfer_t *transfer); void new_data(const Transfer_t *transfer);
void init(); void init();
private: 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; Pipe_t *datapipe;
setup_t setup; setup_t setup;
uint8_t report[8]; 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))); Pipe_t mypipes[2] __attribute__ ((aligned(32)));
Transfer_t mytransfers[4] __attribute__ ((aligned(32))); Transfer_t mytransfers[4] __attribute__ ((aligned(32)));
}; };

+ 14
- 4
k66_usbhost.ino View File

USBHS_USBCMD |= USBHS_USBCMD_IAA; USBHS_USBCMD |= USBHS_USBCMD_IAA;
if (rootdev) print(rootdev->control_pipe); if (rootdev) print(rootdev->control_pipe);
#endif #endif

keyboard1.attachPress(press);
keyboard2.attachPress(press);
midi1.setHandleNoteOff(OnNoteOff); midi1.setHandleNoteOff(OnNoteOff);
midi1.setHandleNoteOn(OnNoteOn); midi1.setHandleNoteOn(OnNoteOn);
midi1.setHandleControlChange(OnControlChange); midi1.setHandleControlChange(OnControlChange);
digitalWriteFast(30, LOW); 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) void OnNoteOn(byte channel, byte note, byte velocity)
{ {
Serial.print(channel); Serial.print(channel);
Serial.print(", note="); Serial.print(", note=");
Serial.print(note); Serial.print(note);
Serial.print(", velocity=");
Serial.print(velocity);
//Serial.print(", velocity=");
//Serial.print(velocity);
Serial.println(); Serial.println();
} }



+ 90
- 4
keyboard.cpp View File



#include <Arduino.h> #include <Arduino.h>
#include "USBHost_t36.h" // Read this header first for key info #include "USBHost_t36.h" // Read this header first for key info
#include "keylayouts.h" // from Teensyduino core library




void KeyboardController::init() void KeyboardController::init()


void KeyboardController::callback(const Transfer_t *transfer) void KeyboardController::callback(const Transfer_t *transfer)
{ {
println("KeyboardController Callback (static)");
//println("KeyboardController Callback (static)");
if (transfer->driver) { if (transfer->driver) {
((KeyboardController *)(transfer->driver))->new_data(transfer); ((KeyboardController *)(transfer->driver))->new_data(transfer);
} }
} }


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) void KeyboardController::new_data(const Transfer_t *transfer)
{ {
println("KeyboardController Callback (member)"); println("KeyboardController Callback (member)");
print(" KB Data: "); print(" KB Data: ");
print_hexbytes(transfer->buffer, 8); print_hexbytes(transfer->buffer, 8);
// TODO: parse the new data
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); queue_Data_Transfer(datapipe, report, 8, this);
} }


void KeyboardController::disconnect()
void KeyboardController::key_press(uint32_t mod, uint32_t key)
{ {
// TODO: free resources
// 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;
}















Loading…
Cancel
Save