rewire teensy keyboard so USB works in the BIOS

This commit is contained in:
Jorj Bauer 2021-01-19 20:14:49 -05:00
parent 97059a0a5b
commit f57478f85d
3 changed files with 77 additions and 56 deletions

View File

@ -1,7 +1,6 @@
#include <Arduino.h> #include <Arduino.h>
#include "teensy-keyboard.h" #include "teensy-keyboard.h"
#include <Keypad.h> #include <Keypad.h>
#include "LRingBuffer.h"
#include "teensy-println.h" #include "teensy-println.h"
#include "globals.h" #include "globals.h"
@ -21,7 +20,41 @@ char keys[ROWS][COLS] = {
uint8_t rowsPins[ROWS] = { 33, 34, 35, 36, 37 }; uint8_t rowsPins[ROWS] = { 33, 34, 35, 36, 37 };
uint8_t colsPins[COLS] = { 41, 40, 3, 4, 24, 25, 39, 23, 28, 29, 30, 31, 32 }; // 0, 1, 26, 27 are moving to ... 41, 40, 39, 23? uint8_t colsPins[COLS] = { 41, 40, 3, 4, 24, 25, 39, 23, 28, 29, 30, 31, 32 }; // 0, 1, 26, 27 are moving to ... 41, 40, 39, 23?
Keypad keypad(makeKeymap(keys), rowsPins, colsPins, ROWS, COLS); Keypad keypad(makeKeymap(keys), rowsPins, colsPins, ROWS, COLS);
LRingBuffer buffer(10); // 10 keys should be plenty, right?
struct _tkb_event {
uint8_t keycode;
bool pressedIfTrue;
struct _tkb_event *next;
};
#define MAXKBEVENTS 10
struct _tkb_event keyboardEvents[MAXKBEVENTS];
uint8_t kbEventCount = 0;
uint8_t kbEventHead = 0;
uint8_t kbEventPtr = 0;
bool addEvent(uint8_t kc, bool pressed)
{
if (kbEventCount >= MAXKBEVENTS)
return false;
keyboardEvents[kbEventPtr].keycode = kc;
keyboardEvents[kbEventPtr++].pressedIfTrue = pressed;
if (kbEventPtr >= MAXKBEVENTS) kbEventPtr = 0;
kbEventCount++;
}
bool popEvent(uint8_t *kc, bool *pressed)
{
if (kbEventCount) {
*kc = keyboardEvents[kbEventHead].keycode;
*pressed = keyboardEvents[kbEventHead++].pressedIfTrue;
if (kbEventHead >= MAXKBEVENTS) kbEventHead = 0;
kbEventCount--;
return true;
}
return false;
}
static uint8_t shiftedNumber[] = { '<', // , static uint8_t shiftedNumber[] = { '<', // ,
'_', // - '_', // -
@ -79,10 +112,10 @@ void TeensyKeyboard::pressedKey(uint8_t key)
capsLock = !capsLock; capsLock = !capsLock;
break; break;
case PK_LA: case PK_LA:
((TeensyMouse *)g_mouse)->mouseButtonEvent(true); leftApplePressed = 1;
leftApplePressed = 1;
break; break;
case PK_RA: case PK_RA:
((TeensyMouse *)g_mouse)->mouseButtonEvent(true);
rightApplePressed = 1; rightApplePressed = 1;
break; break;
} }
@ -90,31 +123,31 @@ void TeensyKeyboard::pressedKey(uint8_t key)
} }
if (key == ' ' || key == PK_DEL || key == PK_ESC || key == PK_RET || key == PK_TAB) { if (key == ' ' || key == PK_DEL || key == PK_ESC || key == PK_RET || key == PK_TAB) {
buffer.addByte(key); addEvent(key, true);
return; return;
} }
if (key >= 'a' && if (key >= 'a' &&
key <= 'z') { key <= 'z') {
if (ctrlPressed) { if (ctrlPressed) {
buffer.addByte(key - 'a' + 1); addEvent(key - 'a' + 1, true);
return; return;
} }
if (leftShiftPressed || rightShiftPressed || capsLock) { if (leftShiftPressed || rightShiftPressed || capsLock) {
buffer.addByte(key - 'a' + 'A'); addEvent(key - 'a' + 'A', true);
return; return;
} }
buffer.addByte(key); addEvent(key, true);
return; return;
} }
// FIXME: can we control-shift? // FIXME: can we control-shift?
if (key >= ',' && key <= ';') { if (key >= ',' && key <= ';') {
if (leftShiftPressed || rightShiftPressed) { if (leftShiftPressed || rightShiftPressed) {
buffer.addByte(shiftedNumber[key - ',']); addEvent(shiftedNumber[key - ','], true);
return; return;
} }
buffer.addByte(key); addEvent(key, true);
return; return;
} }
@ -141,13 +174,13 @@ void TeensyKeyboard::pressedKey(uint8_t key)
break; break;
} }
if (ret) { if (ret) {
buffer.addByte(ret); addEvent(ret, true);
return; return;
} }
} }
// Everything else falls through. // Everything else falls through.
buffer.addByte(key); addEvent(key, true);
} }
void TeensyKeyboard::releasedKey(uint8_t key) void TeensyKeyboard::releasedKey(uint8_t key)
@ -174,6 +207,7 @@ void TeensyKeyboard::releasedKey(uint8_t key)
break; break;
} }
} }
addEvent(key, false);
} }
bool TeensyKeyboard::kbhit() bool TeensyKeyboard::kbhit()
@ -196,55 +230,42 @@ bool TeensyKeyboard::kbhit()
} }
} }
// For debugging: also allow USB serial to act as a keyboard return kbEventCount;
if (serialavailable()) {
buffer.addByte(serialgetch());
}
return buffer.hasData();
} }
int8_t TeensyKeyboard::read() int8_t TeensyKeyboard::read()
{ {
if (buffer.hasData()) { if (kbEventCount) {
return buffer.consumeByte(); uint8_t kc;
bool pressed;
if (popEvent(&kc, &pressed)) {
if (pressed) {
return kc;
}
}
} }
return 0; return 0;
} }
// This is a non-buffered interface to the physical keyboard, as used // This is the interface to the physical keyboard, as used by the VM.
// by the VM.
void TeensyKeyboard::maintainKeyboard() void TeensyKeyboard::maintainKeyboard()
{ {
if (keypad.getKeys()) { kbhit();
for (int i=0; i<LIST_MAX; i++) {
if ( keypad.key[i].stateChanged ) { if (kbEventCount) {
switch (keypad.key[i].kstate) { uint8_t kc;
case PRESSED: bool pressed;
vmkeyboard->keyDepressed(keypad.key[i].kchar); if (popEvent(&kc, &pressed)) {
if (keypad.key[i].kchar == PK_LSHFT) { if (pressed) {
((TeensyMouse *)g_mouse)->mouseButtonEvent(true); sprintf(debugBuf, "%d press ", kc);
} g_display->debugMsg(debugBuf);
break; vmkeyboard->keyDepressed(kc);
case RELEASED: } else {
vmkeyboard->keyReleased(keypad.key[i].kchar); sprintf(debugBuf, "%d relsd ", kc);
if (keypad.key[i].kchar == PK_LSHFT) { g_display->debugMsg(debugBuf);
((TeensyMouse *)g_mouse)->mouseButtonEvent(false); vmkeyboard->keyReleased(kc);
}
break;
case HOLD:
case IDLE:
break;
}
} }
} }
} }
// For debugging: also allow USB serial to act as a keyboard
if (serialavailable()) {
int c = serialgetch();
vmkeyboard->keyDepressed(c);
vmkeyboard->keyReleased(c);
}
} }

View File

@ -16,7 +16,8 @@ class TeensyKeyboard : public PhysicalKeyboard {
virtual int8_t read(); virtual int8_t read();
private: public:
// These are only public b/c teensy.ino (not a class) needs them.
void pressedKey(uint8_t key); void pressedKey(uint8_t key);
void releasedKey(uint8_t key); void releasedKey(uint8_t key);

View File

@ -16,8 +16,6 @@
#include "teensy-println.h" #include "teensy-println.h"
#include "smalloc.h" #include "smalloc.h"
#include "iocompat.h"
//#define DEBUG_TIMING //#define DEBUG_TIMING
#if F_CPU < 240000000 #if F_CPU < 240000000
@ -129,17 +127,18 @@ static uint8_t usb_scanmap[256] = {
void onKeypress(uint8_t keycode) void onKeypress(uint8_t keycode)
{ {
if (keycode == 67) { if (keycode == 67 || keycode == 70) {
// F10 is our interrupt button; FIXME this probably needs to be adjustable // F10 or PrtSc/SysRq are interrupt buttons. Probably needs to be
// configurable somehow...
g_biosInterrupt = true; g_biosInterrupt = true;
} else { } else {
((AppleVM *)g_vm)->getKeyboard()->keyDepressed(usb_scanmap[keycode]); ((TeensyKeyboard *)g_keyboard)->pressedKey(usb_scanmap[keycode]);
} }
} }
void onKeyrelease(uint8_t keycode) void onKeyrelease(uint8_t keycode)
{ {
((AppleVM *)g_vm)->getKeyboard()->keyReleased(usb_scanmap[keycode]); ((TeensyKeyboard *)g_keyboard)->releasedKey(usb_scanmap[keycode]);
} }
void setup() void setup()