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

@@ -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)));
};

+ 14
- 4
k66_usbhost.ino View File

@@ -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();
}


+ 90
- 4
keyboard.cpp View File

@@ -23,6 +23,7 @@

#include <Arduino.h>
#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::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);
// 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);
}

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