diff options
Diffstat (limited to 'usb_keyboard.c')
-rw-r--r-- | usb_keyboard.c | 70 |
1 files changed, 35 insertions, 35 deletions
diff --git a/usb_keyboard.c b/usb_keyboard.c index eed1b88..8212c60 100644 --- a/usb_keyboard.c +++ b/usb_keyboard.c @@ -1,3 +1,9 @@ +/* usb_keyboard.c - Implementation of a USB keyboard device + * + * Copyright (C) 2024 Luke T. Shumaker <lukeshu@lukeshu.com> + * SPDX-Licence-Identifier: AGPL-3.0-or-later + */ + #include "tusb.h" #include "tusb_helpers.h" /* for TUD_ENDPOINT_IN */ @@ -34,46 +40,40 @@ void usb_keyboard_init() { }); } -#define kbd_buf_cap 1024 -static uint32_t kbd_buf[kbd_buf_cap]; -static size_t kbd_buf_beg = 0; -static size_t kbd_buf_len = 0; - static uint8_t ascii2keycode[128][2] = { HID_ASCII_TO_KEYCODE }; -void usb_keyboard_task(void) { - static bool sent_key = false; - if (tud_hid_n_ready(kbd_ifc)) { - uint8_t const report_id = 0; - uint8_t modifier = 0; - uint8_t keycodes[6] = {0}; - - if (kbd_buf_len && !sent_key) { - if (ascii2keycode[kbd_buf[kbd_buf_beg]][0]) - modifier = KEYBOARD_MODIFIER_LEFTSHIFT; - keycodes[0] = ascii2keycode[kbd_buf[kbd_buf_beg]][1]; - - kbd_buf_beg++; - if (kbd_buf_beg == kbd_buf_cap) - kbd_buf_beg = 0; - kbd_buf_len--; - } +void usb_keyboard_cr(void *_stack) { + usb_keyboard_stack_t *stack = _stack; - tud_hid_n_keyboard_report(kbd_ifc, report_id, modifier, keycodes); - sent_key = !sent_key; - } -} + cr_begin(); -bool usb_keyboard_send_char(uint32_t ch) { - if (kbd_buf_len == kbd_buf_cap) /* buffer full */ - return false; - if (ch > 0x7F) /* not ASCII */ - return false; - kbd_buf[(kbd_buf_beg + kbd_buf_len++) % kbd_buf_cap] = ch; -} + for (;;) { + while (!tud_hid_n_ready(kbd_ifc)) + cr_yield(); + + if (cr_chan_have_req(stack->chan)) { + cr_chan_recv_req(stack->chan, &stack->rune); + + stack->modifier = ascii2keycode[stack->rune][0] ? KEYBOARD_MODIFIER_LEFTSHIFT : 0; + stack->keycodes[0] = ascii2keycode[stack->rune][1]; + tud_hid_n_keyboard_report(kbd_ifc, stack->report_id, stack->modifier, stack->keycodes); + + while (!tud_hid_n_ready(kbd_ifc)) + cr_yield(); + + stack->modifier = 0; + stack->keycodes[0] = 0; + tud_hid_n_keyboard_report(kbd_ifc, stack->report_id, stack->modifier, stack->keycodes); + + cr_chan_send_resp(stack->chan, 1); + } else { + stack->modifier = 0; + stack->keycodes[0] = 0; + tud_hid_n_keyboard_report(kbd_ifc, stack->report_id, stack->modifier, stack->keycodes); + } + } -bool usb_keyboard_is_flushed(void) { - return kbd_buf_len == 0; + cr_end() } /** |