rktk/task/main_loop/
slave.rs

1use embassy_futures::join::join3;
2use embassy_time::{Duration, Timer};
3use rktk_log::debug;
4
5use crate::{
6    config::schema::DynamicConfig,
7    drivers::interface::{
8        debounce::DebounceDriver,
9        keyscan::KeyscanDriver,
10        mouse::MouseDriver,
11        split::{MasterToSlave, SlaveToMaster},
12    },
13    hooks::interface::SlaveHooks,
14    task::channels::{
15        rgb::RGB_CHANNEL,
16        split::{M2sRx, S2mTx},
17    },
18};
19
20pub async fn start<KS: KeyscanDriver, M: MouseDriver, DB: DebounceDriver, SH: SlaveHooks>(
21    config: &'static DynamicConfig,
22    s2m_tx: S2mTx<'_>,
23    m2s_rx: M2sRx<'_>,
24    mut keyscan: KS,
25    debounce: &mut Option<DB>,
26    mut mouse: Option<M>,
27    mut slave_hooks: SH,
28) {
29    crate::print!("Slave start");
30
31    slave_hooks
32        .on_slave_init(&mut keyscan, mouse.as_mut())
33        .await;
34
35    join3(
36        async {
37            if let Some(mouse) = &mut mouse {
38                debug!("mouse start");
39                let interval = Duration::from_millis(config.rktk.scan_interval_mouse);
40                loop {
41                    let start = embassy_time::Instant::now();
42
43                    if let Ok(data) = mouse.read().await {
44                        if data != (0, 0) {
45                            let e = SlaveToMaster::Mouse {
46                                // x and y are swapped
47                                x: data.0,
48                                y: data.1,
49                            };
50                            s2m_tx.send(e).await;
51                        }
52                    }
53
54                    let took = start.elapsed();
55                    if took < interval {
56                        Timer::after(interval - took).await;
57                    }
58                }
59            }
60        },
61        async {
62            debug!("keyscan start");
63            let interval = Duration::from_millis(config.rktk.scan_interval_keyboard);
64            loop {
65                Timer::after(interval).await;
66
67                keyscan
68                    .scan(|event| {
69                        debug!("keyscan event: {:?}", event);
70                        if let Some(debounce) = debounce.as_mut() {
71                            if debounce.should_ignore_event(&event, embassy_time::Instant::now()) {
72                                debug!("keyscan event ignored");
73                                return;
74                            }
75                        }
76
77                        let event = if event.pressed {
78                            SlaveToMaster::Pressed(event.row, event.col)
79                        } else {
80                            SlaveToMaster::Released(event.row, event.col)
81                        };
82
83                        let _ = s2m_tx.try_send(event);
84                    })
85                    .await;
86            }
87        },
88        async {
89            debug!("split start");
90            loop {
91                let data = m2s_rx.receive().await;
92                debug!("split data recv: {:?}", data);
93                match data {
94                    MasterToSlave::Rgb(ctrl) => {
95                        let _ = RGB_CHANNEL.try_send(ctrl);
96                    }
97                    MasterToSlave::Message(_) => {}
98                }
99            }
100        },
101    )
102    .await;
103}