sxkbd

Firmware for RP2040-based corne split keyboard
git clone https://git.sinitax.com/sinitax/sxkbd
Log | Files | Refs | Submodules | README | LICENSE | sfeed.txt

commit d19f5ce8b56e1199eb9e20ba83b38f8e3e915437
parent b50765e6377eda0b6b4aa292379f8b01e48ae5c0
Author: Louis Burda <quent.burda@gmail.com>
Date:   Sun,  5 Feb 2023 17:10:07 +0100

Make led blip asynchronous and add sync mechanism to split comms

Diffstat:
Msrc/led.c | 61+++++++++++++++++++++++++++++++++++++++++++++++++------------
Msrc/led.h | 7++++++-
Msrc/main.c | 6+++---
Msrc/split.c | 63+++++++++++++++++++++++++++++++++++++++++++++------------------
Msrc/util.c | 2+-
5 files changed, 104 insertions(+), 35 deletions(-)

diff --git a/src/led.c b/src/led.c @@ -4,7 +4,6 @@ #include "bsp/board.h" -#define BLINK_DELAY 500 #define ONBOARD_LED_PIN 25 static struct ws2812 onboard_led; @@ -14,12 +13,19 @@ bool led_reset; uint32_t led_blink_ms; uint32_t led_rgb; +bool led_blip_reset; +bool led_blip; +uint32_t led_blip_ms; +uint32_t led_blip_rgb; + void led_init(void) { led_reset = true; led_mode = LED_ON; led_rgb = SOFT_WHITE; + led_blip = false; + led_blip_rgb = HARD_WHITE; ws2812_init(&onboard_led, pio0, ONBOARD_LED_PIN); } @@ -29,18 +35,44 @@ led_task(void) static uint32_t start_ms = 0; static bool state = false; + if (led_blip_reset) { + start_ms = board_millis(); + led_blip = true; + ws2812_put(&onboard_led, led_blip_rgb); + state = true; + led_blip_reset = false; + } + + if (led_blip) { + if (state && board_millis() - start_ms > led_blip_ms) { + ws2812_put(&onboard_led, led_rgb); + state = false; + } else if (board_millis() - start_ms > 2 * led_blip_ms) { + led_blip = false; + led_reset = true; + } + } + + if (led_blip) return; + switch (led_mode) { case LED_OFF: - if (led_reset) - ws2812_put(&onboard_led, 0); + if (led_reset) { + led_rgb = 0; + ws2812_put(&onboard_led, led_rgb); + } break; case LED_ON: - if (led_reset) + if (led_reset) { ws2812_put(&onboard_led, led_rgb); + } break; case LED_BLINK: - if (led_reset) + if (led_reset) { start_ms = board_millis(); + state = true; + ws2812_put(&onboard_led, led_rgb); + } if (board_millis() - start_ms < led_blink_ms) return; @@ -55,13 +87,18 @@ led_task(void) } void -led_blip(uint32_t rgb) +led_set_mode(int mode, uint32_t rgb, uint32_t ms) { - uint32_t start; + led_mode = mode; + led_rgb = rgb; + led_blink_ms = ms; +} - ws2812_put(&onboard_led, rgb); - start = board_millis(); - while (board_millis() < start + BLINK_DELAY) - tud_task(); - led_task(); +void +led_start_blip(uint32_t rgb, uint32_t ms) +{ + if (led_blip) return; + led_blip_rgb = rgb; + led_blip_ms = ms; + led_blip_reset = true; } diff --git a/src/led.h b/src/led.h @@ -21,6 +21,11 @@ extern bool led_reset; extern uint32_t led_blink_ms; extern uint32_t led_rgb; +extern bool led_blip; +extern bool led_blip_reset; +extern uint32_t led_blip_ms; +extern uint32_t led_blip_rgb; + void led_init(void); void led_task(void); -void led_blip(uint32_t rgb); +void led_start_blip(uint32_t rgb, uint32_t ms); diff --git a/src/main.c b/src/main.c @@ -37,7 +37,7 @@ main(void) split_init(); hid_init(); - led_blip(HARD_WHITE); + led_start_blip(HARD_WHITE, 500); start = board_millis(); while (true) { @@ -69,12 +69,12 @@ tud_mount_cb(void) void tud_umount_cb(void) { - led_blip(HARD_WHITE); - led_blink_ms = 500; led_rgb = SOFT_WHITE; led_mode = LED_BLINK; led_reset = true; + + led_start_blip(HARD_WHITE, 500); } void diff --git a/src/split.c b/src/split.c @@ -22,7 +22,7 @@ #include <stdint.h> -#define UART_TIMEOUT 20 +#define UART_TIMEOUT 5 #define UART_BAUD 115200 #if SPLIT_SIDE == LEFT @@ -34,7 +34,7 @@ #endif enum { - CMD_SCAN_KEYMAT_REQ = 0xA0, + CMD_SCAN_KEYMAT_REQ = 0x80, CMD_SCAN_KEYMAT_RESP, CMD_STDIO_PUTS }; @@ -53,6 +53,7 @@ static uint uart_recv(uint8_t *data, uint len); static uint uart_send(const uint8_t *data, uint len); static void handle_cmd(uint8_t cmd); +static bool send_cmd(uint8_t cmd); static void irq_rx(void); static uint uart_tx_sm; @@ -214,9 +215,18 @@ uart_send(const uint8_t *data, uint len) } void -handle_cmd(uint8_t cmd) +handle_cmd(uint8_t start) { uint8_t buf[128]; + uint8_t cmd; + + if (start != 0xaa) + return; + + if (!uart_recv(&cmd, 1)) { + WARN("Got start byte without command"); + return; + } switch (cmd) { case CMD_SCAN_KEYMAT_REQ: @@ -225,7 +235,7 @@ handle_cmd(uint8_t cmd) break; } scan_pending = true; - return; + break; case CMD_SCAN_KEYMAT_RESP: if (split_role != MASTER) { WARN("Got SCAN_KEYMAT_RESP as slave"); @@ -234,7 +244,7 @@ handle_cmd(uint8_t cmd) if (uart_recv((uint8_t *) &halfmat, 4) != 4) WARN("Incomplete matrix received"); scan_pending = false; - return; + break; case CMD_STDIO_PUTS: if (split_role != MASTER) { WARN("Got STDIO_PUTS as slave"); @@ -243,10 +253,22 @@ handle_cmd(uint8_t cmd) memset(buf, 0, sizeof(buf)); uart_recv(buf, sizeof(buf)-1); printf("SLAVE: %s\n", buf); - return; + break; + default: + WARN("Unknown uart cmd: %i", cmd); + break; } +} + +bool +send_cmd(uint8_t cmd) +{ + uint8_t buf[2]; + + buf[0] = 0xaa; + buf[1] = cmd; - WARN("Unexpected uart cmd: %i", cmd); + return uart_send(buf, 2) == 2; } void @@ -273,41 +295,46 @@ void split_task(void) { uint32_t start_ms; - uint8_t cmd; if (split_role == MASTER) { scan_pending = true; - cmd = CMD_SCAN_KEYMAT_REQ; - ASSERT(uart_send(&cmd, 1) == 1); + if (!send_cmd(CMD_SCAN_KEYMAT_REQ)) { + WARN("UART send SCAN_KEYMAT_REQ failed"); + return; + } keymat_next(); keymat_scan(); /* scan our side in parallel */ start_ms = board_millis(); - while (scan_pending && board_millis() < start_ms + 20) { + while (scan_pending && board_millis() < start_ms + 3) { if (!pio_sm_is_rx_fifo_empty(pio0, uart_rx_sm)) handle_cmd(uart_rx_byte()); tud_task(); } if (scan_pending) { - WARN("Slave matrix scan timeout"); + WARN("Slave matrix scan timeout (%u)", + board_millis() - start_ms); } else { - DEBUG("Slave matrix scan success"); + DEBUG("Slave matrix scan success (%u)", + board_millis() - start_ms); keymat_decode_half(SPLIT_OPP(SPLIT_SIDE), halfmat); } scan_pending = false; } else { start_ms = board_millis(); - while (!scan_pending && board_millis() < start_ms + 20) { + while (!scan_pending && board_millis() < start_ms + 3) { if (!pio_sm_is_rx_fifo_empty(pio0, uart_rx_sm)) handle_cmd(uart_rx_byte()); tud_task(); } if (scan_pending) { keymat_scan(); - cmd = CMD_SCAN_KEYMAT_RESP; - DEBUG("Sending SCAN_KEYMAT_RESP %i", cmd); - ASSERT(uart_send(&cmd, 1) == 1); + DEBUG("Sending SCAN_KEYMAT_RESP"); + if (!send_cmd(CMD_SCAN_KEYMAT_RESP)) { + WARN("UART send SCAN_KEYMAT_RESP failed"); + return; + } halfmat = keymat_encode_half(SPLIT_SIDE); - ASSERT(uart_send((uint8_t *) &halfmat, 4) == 4); + uart_send((uint8_t *) &halfmat, 4); scan_pending = false; } } diff --git a/src/util.c b/src/util.c @@ -44,7 +44,7 @@ stdio_log(int level, const char *fmtstr, ...) va_list ap, cpy; if (level == LOG_WARN) { - led_blip(HARD_RED); + led_start_blip(HARD_RED, 100); va_copy(cpy, ap); va_start(cpy, fmtstr); vsnprintf(warnlog, sizeof(warnlog), fmtstr, cpy);