rmk_q6_he_ansi/backlight/led_processor.rs
1use BacklightCmd::Indicators;
2use rmk::{
3 channel::{blocking_mutex::raw::CriticalSectionRawMutex, channel::Channel},
4 event::LedIndicatorEvent,
5 macros::processor,
6};
7
8/// Channel used to send backlight indicator commands.
9pub static BACKLIGHT_CH: Channel<CriticalSectionRawMutex, BacklightCmd, 8> = Channel::new();
10
11/// Commands for lock indicator LEDs.
12#[derive(Copy, Clone)]
13pub enum BacklightCmd {
14 /// Mark a single LED as fully calibrated during the full-travel pass.
15 ///
16 /// The backlight task immediately repaints that LED green, providing
17 /// per-key visual confirmation independent of the gradient background.
18 CalibKeyDone(u8),
19 /// Signal a first-boot calibration phase transition via the backlight.
20 CalibPhase(CalibPhase),
21 /// Report full-travel calibration progress as a percentage (0–100).
22 ///
23 /// Drives the whole-keyboard blue→green gradient.
24 CalibProgress(u8),
25 /// Update Caps Lock / Num Lock indicator LED states.
26 Indicators {
27 /// Whether Caps Lock is currently active.
28 caps: bool,
29 /// Whether Num Lock is currently active.
30 num: bool,
31 },
32}
33
34/// Calibration phase signaled to the backlight task during first-boot setup.
35#[derive(Copy, Clone)]
36pub enum CalibPhase {
37 /// All keys accepted; the settle window is running.
38 /// Backlight: three short green flashes - signals the user every key has
39 /// been recorded and all keys may be released.
40 AllAccepted,
41 /// Calibration complete and persisted to EEPROM; keyboard is ready.
42 /// Backlight color: green for 2 s, then restores normal white.
43 Done,
44 /// Full-travel pass in progress; user should press every key to the bottom.
45 /// Backlight color: red→blue gradient (0 % → 100 % of keys accepted);
46 /// individual accepted keys light up green immediately.
47 Full,
48 /// Zero-travel pass in progress; keys should be fully released.
49 /// Backlight color: amber.
50 Zero,
51}
52
53/// Controller that reacts to indicator events for the LED driver.
54#[processor(subscribe = [LedIndicatorEvent])]
55pub struct LedIndicatorProcessor;
56
57impl LedIndicatorProcessor {
58 /// Create a new indicator controller.
59 #[must_use]
60 pub const fn new() -> Self { Self }
61
62 /// Handle incoming lock LED indicator events.
63 async fn on_led_indicator_event(&self, event: LedIndicatorEvent) {
64 let caps = event.caps_lock();
65 let num = event.num_lock();
66
67 BACKLIGHT_CH.sender().send(Indicators { caps, num }).await;
68 }
69}