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;
|
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
|
||||||
|
@ -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) {
|
||||||
|
@ -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;
|
||||||
|
Reference in New Issue
Block a user