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 a08ae9e31873a094a5e7d47ae8cfd2edfe6a60a4
parent c70a527d0418b4f32437873f682680f451fa4fb8
Author: Louis Burda <quent.burda@gmail.com>
Date:   Sat, 28 Jan 2023 23:35:59 +0100

Add led blips for warnings and on startup

Diffstat:
Msrc/hid.c | 4++--
Msrc/led.c | 18+++++++++++++++---
Msrc/led.h | 8++++++++
Msrc/main.c | 22++++++++++++++++------
Msrc/util.c | 19+++++++++++++------
Msrc/util.h | 4+++-
Msrc/ws2812.h | 6+++---
7 files changed, 60 insertions(+), 21 deletions(-)

diff --git a/src/hid.c b/src/hid.c @@ -515,9 +515,9 @@ void tud_hid_set_protocol_cb(uint8_t instance, uint8_t protocol) { if (protocol == HID_PROTOCOL_BOOT) { - led_rgb = WS2812_U32RGB(100, 100, 0); + led_rgb = SOFT_YELLOW; } else { - led_rgb = WS2812_U32RGB(100, 0, 100); + led_rgb = SOFT_PURPLE; } led_mode = LED_ON; led_reset = true; diff --git a/src/led.c b/src/led.c @@ -4,6 +4,7 @@ #include "bsp/board.h" +#define BLINK_DELAY 500 #define ONBOARD_LED_PIN 25 static struct ws2812 onboard_led; @@ -18,7 +19,7 @@ led_init(void) { led_reset = true; led_mode = LED_ON; - led_rgb = WS2812_U32RGB(100, 100, 100); + led_rgb = SOFT_WHITE; ws2812_init(&onboard_led, pio0, ONBOARD_LED_PIN); } @@ -35,7 +36,7 @@ led_task(void) break; case LED_ON: if (led_reset) - ws2812_put(&onboard_led, led_rgb); + ws2812_put(&onboard_led, WS2812_U32RGB(led_rgb)); break; case LED_BLINK: if (led_reset) @@ -46,10 +47,21 @@ led_task(void) start_ms += led_blink_ms; state = !state; - ws2812_put(&onboard_led, state ? led_rgb : 0); + ws2812_put(&onboard_led, state ? WS2812_U32RGB(led_rgb) : 0); break; } led_reset = false; } +void +led_blip(uint32_t rgb) +{ + uint32_t start; + + ws2812_put(&onboard_led, WS2812_U32RGB(rgb)); + start = board_millis(); + while (board_millis() < start + BLINK_DELAY) + tud_task(); + led_task(); +} diff --git a/src/led.h b/src/led.h @@ -3,6 +3,13 @@ #include <stdint.h> #include <stdbool.h> +#define SOFT_WHITE 0x404040 +#define SOFT_YELLOW 0x404000 +#define SOFT_PURPLE 0x400040 +#define HARD_WHITE 0xFFFFFF +#define HARD_YELLOW 0xFF00FF +#define HARD_RED 0xFF0000 + enum { LED_OFF, LED_ON, @@ -16,3 +23,4 @@ extern uint32_t led_rgb; void led_init(void); void led_task(void); +void led_blip(uint32_t rgb); diff --git a/src/main.c b/src/main.c @@ -37,6 +37,8 @@ main(void) split_init(); hid_init(); + led_blip(HARD_WHITE); + start = board_millis(); while (true) { tud_task(); @@ -59,7 +61,7 @@ tud_mount_cb(void) #ifndef SPLIT_ROLE split_role = MASTER; #endif - led_rgb = WS2812_U32RGB(100, 0, 100); + led_rgb = SOFT_PURPLE; led_mode = LED_ON; led_reset = true; } @@ -67,8 +69,10 @@ tud_mount_cb(void) void tud_umount_cb(void) { + led_blip(HARD_WHITE); + led_blink_ms = 500; - led_rgb = WS2812_U32RGB(100, 100, 100); + led_rgb = SOFT_WHITE; led_mode = LED_BLINK; led_reset = true; } @@ -79,7 +83,7 @@ tud_suspend_cb(bool remote_wakeup_en) #ifndef SPLIT_ROLE split_role = SLAVE; #endif - led_rgb = WS2812_U32RGB(100, 100, 100); + led_rgb = SOFT_WHITE; led_mode = LED_ON; led_reset = true; } @@ -87,7 +91,7 @@ tud_suspend_cb(bool remote_wakeup_en) void tud_resume_cb(void) { - led_rgb = WS2812_U32RGB(100, 0, 100); + led_rgb = SOFT_PURPLE; led_mode = LED_ON; led_reset = true; } @@ -137,10 +141,16 @@ process_cmd(char *cmd) loglevel = LOG_INFO; } else if (!strcmp(arg, "warn")) { loglevel = LOG_WARN; - } else if (!strcmp(arg, "warn")) { + } else if (!strcmp(arg, "err")) { loglevel = LOG_ERR; } else { - printf("Invalid log level: %s\n", arg); + printf("Invalid log level\n"); + } + } else if (!strcmp(cmd, "warn")) { + if (*warnlog) { + printf("Warning: %s\n", warnlog); + } else { + printf("No warnings logged\n"); } } else { printf("Invalid command: %s\n", cmd); diff --git a/src/util.c b/src/util.c @@ -11,6 +11,7 @@ #include <stdio.h> +char warnlog[512]; int loglevel = LOG_INFO; static void @@ -40,12 +41,20 @@ void __attribute__ ((format (printf, 2, 3))) stdio_log(int level, const char *fmtstr, ...) { - va_list ap; + va_list ap, cpy; + + if (level == LOG_WARN) { + led_blip(HARD_RED); + va_copy(cpy, ap); + va_start(cpy, fmtstr); + vsnprintf(warnlog, sizeof(warnlog), fmtstr, cpy); + va_end(cpy); + } - if (!tud_cdc_connected()) + if (level > loglevel) return; - if (level > loglevel) + if (!tud_cdc_connected()) return; va_start(ap, fmtstr); @@ -61,17 +70,15 @@ blink_panic(uint32_t blink_ms, uint32_t rgb, const char *fmtstr, ...) { va_list ap; - va_start(ap, fmtstr); - led_blink_ms = blink_ms; led_rgb = rgb; led_mode = LED_BLINK; + va_start(ap, fmtstr); while (1) { tud_task(); panic_task(fmtstr, ap, 1000); led_task(); } - va_end(ap); } diff --git a/src/util.h b/src/util.h @@ -1,6 +1,7 @@ #pragma once #include "ws2812.h" +#include "led.h" #include <stdbool.h> #include <stdint.h> @@ -13,7 +14,7 @@ #define INFO(...) stdio_log(LOG_INFO, "INFO : " __VA_ARGS__) #define DEBUG(...) stdio_log(LOG_DEBUG, "DEBUG: " __VA_ARGS__) -#define PANIC(...) blink_panic(200, WS2812_U32RGB(255, 0, 0), __VA_ARGS__); +#define PANIC(...) blink_panic(200, HARD_RED, __VA_ARGS__); #define ASSERT(cond) do { \ if (!(cond)) PANIC("Assertion failed: (%s) in %s:%i", \ #cond, __FILE__, __LINE__); \ @@ -36,4 +37,5 @@ void stdio_log(int loglevel, const char *fmtstr, ...); void blink_panic(uint32_t blink_ms, uint32_t rgb, const char *fmtstr, ...); +extern char warnlog[]; extern int loglevel; diff --git a/src/ws2812.h b/src/ws2812.h @@ -5,9 +5,9 @@ #include <stdbool.h> -#define _WS2812_U8(v, s) (((uint32_t) (v) & 0xFF) << s) -#define WS2812_U32RGB(r, g, b) \ - (_WS2812_U8(b, 0) | _WS2812_U8(r, 8) | _WS2812_U8(g, 16)) +#define _WS2812_U8(v, si, so) ((((uint32_t) (v) >> si) & 0xFF) << so) +#define WS2812_U32RGB(rgb) (_WS2812_U8(rgb, 16, 0) \ + | _WS2812_U8(rgb, 0, 8) | _WS2812_U8(rgb, 8, 16)) struct ws2812 { PIO pio;