From 2c18b3cb544cfe3741b8751610648c599fafa2bf Mon Sep 17 00:00:00 2001 From: Jeremy Soller Date: Fri, 8 Nov 2019 10:29:29 -0700 Subject: [PATCH] Send keypresses over ps2 --- .../system76/galp3-c/include/board/kbscan.h | 4 + .../system76/galp3-c/include/board/keymap.h | 7 ++ src/board/system76/galp3-c/kbc.c | 4 +- src/board/system76/galp3-c/kbscan.c | 94 +++++++++++-------- src/board/system76/galp3-c/keymap.c | 7 -- src/ec/it8587e/kbc.c | 4 + 6 files changed, 75 insertions(+), 45 deletions(-) diff --git a/src/board/system76/galp3-c/include/board/kbscan.h b/src/board/system76/galp3-c/include/board/kbscan.h index 2a0a26d..f9327ad 100644 --- a/src/board/system76/galp3-c/include/board/kbscan.h +++ b/src/board/system76/galp3-c/include/board/kbscan.h @@ -1,8 +1,12 @@ #ifndef _BOARD_KBSCAN_H #define _BOARD_KBSCAN_H +#include + #include +extern bool kbscan_enabled; + void kbscan_init(void); void kbscan_event(void); diff --git a/src/board/system76/galp3-c/include/board/keymap.h b/src/board/system76/galp3-c/include/board/keymap.h index 7a390e8..0f92dc2 100644 --- a/src/board/system76/galp3-c/include/board/keymap.h +++ b/src/board/system76/galp3-c/include/board/keymap.h @@ -3,6 +3,13 @@ #include +// Keymap output pins +#define KM_OUT 16 +// Keymap input pins +#define KM_IN 8 +// Keymap layers (normal, Fn) +#define KM_LAY 2 + uint16_t keymap(int output, int input, int layer); // See http://www.techtoys.com.hk/Downloads/Download/Microchip/PS2_driver/ScanCode.pdf diff --git a/src/board/system76/galp3-c/kbc.c b/src/board/system76/galp3-c/kbc.c index bec0647..b42da58 100644 --- a/src/board/system76/galp3-c/kbc.c +++ b/src/board/system76/galp3-c/kbc.c @@ -1,6 +1,7 @@ #include #include +#include void kbc_init(void) { *(KBC.irq) = 0; @@ -77,16 +78,17 @@ void kbc_event(struct Kbc * kbc) { break; case 0xF4: printf(" enable scanning\n"); + kbscan_enabled = true; kbc_keyboard(kbc, 0xFA); break; case 0xF5: printf(" disable scanning\n"); + kbscan_enabled = false; kbc_keyboard(kbc, 0xFA); break; case 0xFF: printf(" self test\n"); kbc_keyboard(kbc, 0xFA); - while (kbc_status(kbc) & KBC_STS_OBF) {} // Yep, everything is still good, I promise kbc_keyboard(kbc, 0xAA); break; diff --git a/src/board/system76/galp3-c/kbscan.c b/src/board/system76/galp3-c/kbscan.c index db5d620..5ad1fb3 100644 --- a/src/board/system76/galp3-c/kbscan.c +++ b/src/board/system76/galp3-c/kbscan.c @@ -1,59 +1,79 @@ #include #include +#include #include #include +bool kbscan_enabled = false; +uint8_t kbscan_layer = 0; +uint8_t __pdata kbscan_last[KM_OUT] = { 0 }; + void kbscan_init(void) { KSOCTRL = 0x05; KSICTRLR = 0x04; // Set all outputs to GPIO mode and low - KSOH2 = 0; - KSOH1 = 0; KSOL = 0; - KSOHGCTRL = 0xFF; - KSOHGOEN = 0xFF; + KSOH1 = 0; + KSOH2 = 0; KSOLGCTRL = 0xFF; KSOLGOEN = 0xFF; + KSOHGCTRL = 0xFF; + KSOHGOEN = 0xFF; } void kbscan_event(void) { - static int layer = 0; - - static uint8_t last = 0xFF; - uint8_t new = KSI; - if (new != last) { - printf("KSI %02X\n", new); - - int i; - for (i = 0; i <= 15; i++) { - if (i < 8) { - KSOL = ~(1 << i); - KSOH1 = 0xFF; - } else { - KSOL = 0xFF; - KSOH1 = ~(1 << (i - 8)); - } - - // TODO: figure out optimal delay - delay_ms(1); - - uint8_t ksi = KSI; - - int j; - for (j = 0; j < 8; j++) { - if (!(ksi & (1 << j))) { - uint16_t key = keymap(i, j, layer); - printf(" %d, %d, %d = 0x%04X\n", i, j, layer, key); - } - } + int i; + for (i = 0; i < KM_OUT; i++) { + KSOL = 0xFF; + KSOH1 = 0xFF; + KSOH2 = 0xFF; + if (i < 8) { + KSOL = ~(1 << i); + } else if (i < 16) { + KSOH1 = ~(1 << (i - 8)); + } else if (i < 24) { + KSOH2 = ~(1 << (i - 16)); } - KSOL = 0; - KSOH1 = 0; + // TODO: figure out optimal delay + delay_ticks(1); - delay_ms(1); + uint8_t new = ~KSI; + uint8_t last = kbscan_last[i]; + if (new != last) { + int j; + for (j = 0; j < 8; j++) { + bool new_b = new & (1 << j); + bool last_b = last & (1 << j); + if (new_b != last_b) { + uint16_t key = keymap(i, j, kbscan_layer); + printf(" %d, %d, %d = 0x%04X, %d\n", i, j, kbscan_layer, key, new_b); + if (kbscan_enabled && key) { + switch (key & 0xFF00) { + case K_E0: + kbc_keyboard(&KBC, 0xE0); + // Fall through + case 0x00: + if (!new_b) { + kbc_keyboard(&KBC, 0xF0); + } + kbc_keyboard(&KBC, (uint8_t)key); + break; + } + } + } + } + + kbscan_last[i] = new; + } } - last = new; + + KSOL = 0; + KSOH1 = 0; + KSOH2 = 0; + + // TODO: figure out optimal delay + delay_ticks(1); } diff --git a/src/board/system76/galp3-c/keymap.c b/src/board/system76/galp3-c/keymap.c index 7e28dba..2163905 100644 --- a/src/board/system76/galp3-c/keymap.c +++ b/src/board/system76/galp3-c/keymap.c @@ -1,12 +1,5 @@ #include -// Keymap output pins -#define KM_OUT 16 -// Keymap input pins -#define KM_IN 8 -// Keymap layers (normal, Fn) -#define KM_LAY 2 - uint16_t __code KEYMAP[KM_OUT][KM_IN][KM_LAY] = { { // 0 {0, 0}, // 0 diff --git a/src/ec/it8587e/kbc.c b/src/ec/it8587e/kbc.c index a8c73bb..7d2de75 100644 --- a/src/ec/it8587e/kbc.c +++ b/src/ec/it8587e/kbc.c @@ -18,9 +18,13 @@ uint8_t kbc_read(struct Kbc * kbc) { } void kbc_keyboard(struct Kbc * kbc, uint8_t data) { + //TODO: use timeout + while (kbc_status(kbc) & KBC_STS_OBF) {} *(kbc->keyboard_out) = data; } void kbc_mouse(struct Kbc * kbc, uint8_t data) { + //TODO: use timeout + while (kbc_status(kbc) & KBC_STS_OBF) {} *(kbc->mouse_out) = data; }