Implement scancode buffer

This commit is contained in:
Jeremy Soller
2021-07-19 12:22:57 -06:00
committed by Jeremy Soller
parent e86e18d4b1
commit 146f2d2b4a
3 changed files with 52 additions and 18 deletions

View File

@ -10,7 +10,7 @@
extern uint8_t kbc_leds; extern uint8_t kbc_leds;
void kbc_init(void); void kbc_init(void);
bool kbc_scancode(struct Kbc * kbc, uint16_t key, bool pressed); bool kbc_scancode(uint16_t key, bool pressed);
void kbc_event(struct Kbc * kbc); void kbc_event(struct Kbc * kbc);
#endif // _BOARD_KBC_H #endif // _BOARD_KBC_H

View File

@ -72,16 +72,46 @@ static const uint16_t kbc_typematic_period[32] = {
500, // 2.0 cps = 500ms 500, // 2.0 cps = 500ms
}; };
bool kbc_scancode(struct Kbc * kbc, uint16_t key, bool pressed) { static uint8_t kbc_buffer[16] = { 0 };
static uint8_t kbc_buffer_head = 0;
static uint8_t kbc_buffer_tail = 0;
static bool kbc_buffer_pop(uint8_t * scancode) {
if (kbc_buffer_head == kbc_buffer_tail) {
return false;
}
*scancode = kbc_buffer[kbc_buffer_head];
kbc_buffer_head = (kbc_buffer_head + 1U) % ARRAY_SIZE(kbc_buffer);
return true;
}
static bool kbc_buffer_push(uint8_t * scancodes, uint8_t len) {
//TODO: make this test more efficient
for (uint8_t i = 0; i < len; i++) {
if ((kbc_buffer_tail + i + 1U) % ARRAY_SIZE(kbc_buffer) == kbc_buffer_head) {
return false;
}
}
for (uint8_t i = 0; i < len; i++) {
kbc_buffer[kbc_buffer_tail] = scancodes[i];
kbc_buffer_tail = (kbc_buffer_tail + 1U) % ARRAY_SIZE(kbc_buffer);
}
return true;
}
bool kbc_scancode(uint16_t key, bool pressed) {
if (!kbc_first) return true; if (!kbc_first) return true;
if (kbc_translate) { if (kbc_translate) {
key = keymap_translate(key); key = keymap_translate(key);
} }
if (!key) return true; if (!key) return true;
uint8_t scancodes[3] = {0, 0, 0};
uint8_t scancodes_len = 0;
switch (key & 0xFF00) { switch (key & 0xFF00) {
case KF_E0: case KF_E0:
TRACE(" E0\n"); scancodes[scancodes_len++] = 0xE0;
if (!kbc_keyboard(kbc, 0xE0, KBC_TIMEOUT)) return false;
key &= 0xFF; key &= 0xFF;
// Fall through // Fall through
case 0x00: case 0x00:
@ -89,15 +119,14 @@ bool kbc_scancode(struct Kbc * kbc, uint16_t key, bool pressed) {
if (kbc_translate) { if (kbc_translate) {
key |= 0x80; key |= 0x80;
} else { } else {
TRACE(" F0\n"); scancodes[scancodes_len++] = 0xF0;
if (!kbc_keyboard(kbc, 0xF0, KBC_TIMEOUT)) return false;
} }
} }
TRACE(" %02X\n", key); scancodes[scancodes_len++] = (uint8_t)key;
if (!kbc_keyboard(kbc, (uint8_t)key, KBC_TIMEOUT)) return false;
break; break;
} }
return true;
return kbc_buffer_push(scancodes, scancodes_len);
} }
enum KbcState { enum KbcState {
@ -416,6 +445,11 @@ static void kbc_on_output_empty(struct Kbc * kbc) {
void kbc_event(struct Kbc * kbc) { void kbc_event(struct Kbc * kbc) {
uint8_t sts; uint8_t sts;
// Read from scancode buffer when possible
if (state == KBC_STATE_NORMAL && kbc_buffer_pop(&state_data)) {
state = KBC_STATE_KEYBOARD;
}
// Read from touchpad when possible // Read from touchpad when possible
if (kbc_second) { if (kbc_second) {
if (kbc_second_wait > 0) { if (kbc_second_wait > 0) {

View File

@ -203,7 +203,7 @@ bool kbscan_press(uint16_t key, bool pressed, uint8_t * layer) {
switch (key & KT_MASK) { switch (key & KT_MASK) {
case (KT_NORMAL): case (KT_NORMAL):
if (kbscan_enabled) { if (kbscan_enabled) {
kbc_scancode(&KBC, key, pressed); kbc_scancode(key, pressed);
} }
break; break;
case (KT_FN): case (KT_FN):
@ -220,22 +220,22 @@ bool kbscan_press(uint16_t key, bool pressed, uint8_t * layer) {
case COMBO_DISPLAY_MODE: case COMBO_DISPLAY_MODE:
if (kbscan_enabled) { if (kbscan_enabled) {
if (pressed) { if (pressed) {
kbc_scancode(&KBC, K_LEFT_SUPER, true); kbc_scancode(K_LEFT_SUPER, true);
kbc_scancode(&KBC, K_P, true); kbc_scancode(K_P, true);
kbc_scancode(&KBC, K_P, false); kbc_scancode(K_P, false);
} else { } else {
kbc_scancode(&KBC, K_LEFT_SUPER, false); kbc_scancode(K_LEFT_SUPER, false);
} }
} }
break; break;
case COMBO_PRINT_SCREEN: case COMBO_PRINT_SCREEN:
if (kbscan_enabled) { if (kbscan_enabled) {
if (pressed) { if (pressed) {
kbc_scancode(&KBC, KF_E0 | 0x12, true); kbc_scancode(KF_E0 | 0x12, true);
kbc_scancode(&KBC, KF_E0 | 0x7C, true); kbc_scancode(KF_E0 | 0x7C, true);
} else { } else {
kbc_scancode(&KBC, KF_E0 | 0x7C, false); kbc_scancode(KF_E0 | 0x7C, false);
kbc_scancode(&KBC, KF_E0 | 0x12, false); kbc_scancode(KF_E0 | 0x12, false);
} }
} }
break; break;