Implement scancode buffer
This commit is contained in:
committed by
Jeremy Soller
parent
e86e18d4b1
commit
146f2d2b4a
@ -10,7 +10,7 @@
|
||||
extern uint8_t kbc_leds;
|
||||
|
||||
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);
|
||||
|
||||
#endif // _BOARD_KBC_H
|
||||
|
@ -72,16 +72,46 @@ static const uint16_t kbc_typematic_period[32] = {
|
||||
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_translate) {
|
||||
key = keymap_translate(key);
|
||||
}
|
||||
if (!key) return true;
|
||||
|
||||
uint8_t scancodes[3] = {0, 0, 0};
|
||||
uint8_t scancodes_len = 0;
|
||||
switch (key & 0xFF00) {
|
||||
case KF_E0:
|
||||
TRACE(" E0\n");
|
||||
if (!kbc_keyboard(kbc, 0xE0, KBC_TIMEOUT)) return false;
|
||||
scancodes[scancodes_len++] = 0xE0;
|
||||
key &= 0xFF;
|
||||
// Fall through
|
||||
case 0x00:
|
||||
@ -89,15 +119,14 @@ bool kbc_scancode(struct Kbc * kbc, uint16_t key, bool pressed) {
|
||||
if (kbc_translate) {
|
||||
key |= 0x80;
|
||||
} else {
|
||||
TRACE(" F0\n");
|
||||
if (!kbc_keyboard(kbc, 0xF0, KBC_TIMEOUT)) return false;
|
||||
scancodes[scancodes_len++] = 0xF0;
|
||||
}
|
||||
}
|
||||
TRACE(" %02X\n", key);
|
||||
if (!kbc_keyboard(kbc, (uint8_t)key, KBC_TIMEOUT)) return false;
|
||||
scancodes[scancodes_len++] = (uint8_t)key;
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
|
||||
return kbc_buffer_push(scancodes, scancodes_len);
|
||||
}
|
||||
|
||||
enum KbcState {
|
||||
@ -416,6 +445,11 @@ static void kbc_on_output_empty(struct Kbc * kbc) {
|
||||
void kbc_event(struct Kbc * kbc) {
|
||||
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
|
||||
if (kbc_second) {
|
||||
if (kbc_second_wait > 0) {
|
||||
|
@ -203,7 +203,7 @@ bool kbscan_press(uint16_t key, bool pressed, uint8_t * layer) {
|
||||
switch (key & KT_MASK) {
|
||||
case (KT_NORMAL):
|
||||
if (kbscan_enabled) {
|
||||
kbc_scancode(&KBC, key, pressed);
|
||||
kbc_scancode(key, pressed);
|
||||
}
|
||||
break;
|
||||
case (KT_FN):
|
||||
@ -220,22 +220,22 @@ bool kbscan_press(uint16_t key, bool pressed, uint8_t * layer) {
|
||||
case COMBO_DISPLAY_MODE:
|
||||
if (kbscan_enabled) {
|
||||
if (pressed) {
|
||||
kbc_scancode(&KBC, K_LEFT_SUPER, true);
|
||||
kbc_scancode(&KBC, K_P, true);
|
||||
kbc_scancode(&KBC, K_P, false);
|
||||
kbc_scancode(K_LEFT_SUPER, true);
|
||||
kbc_scancode(K_P, true);
|
||||
kbc_scancode(K_P, false);
|
||||
} else {
|
||||
kbc_scancode(&KBC, K_LEFT_SUPER, false);
|
||||
kbc_scancode(K_LEFT_SUPER, false);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case COMBO_PRINT_SCREEN:
|
||||
if (kbscan_enabled) {
|
||||
if (pressed) {
|
||||
kbc_scancode(&KBC, KF_E0 | 0x12, true);
|
||||
kbc_scancode(&KBC, KF_E0 | 0x7C, true);
|
||||
kbc_scancode(KF_E0 | 0x12, true);
|
||||
kbc_scancode(KF_E0 | 0x7C, true);
|
||||
} else {
|
||||
kbc_scancode(&KBC, KF_E0 | 0x7C, false);
|
||||
kbc_scancode(&KBC, KF_E0 | 0x12, false);
|
||||
kbc_scancode(KF_E0 | 0x7C, false);
|
||||
kbc_scancode(KF_E0 | 0x12, false);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
Reference in New Issue
Block a user