mirror of
https://github.com/gdsports/USBHost_t36
synced 2024-11-21 08:35:03 -05:00
Add public API for Keyboard driver
This commit is contained in:
parent
650ff7eeec
commit
f3d503259c
@ -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)));
|
||||
};
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
106
keyboard.cpp
106
keyboard.cpp
@ -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::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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user