Skip to content

Commit

Permalink
refactor(core): extract all keyboard tasks to fn
Browse files Browse the repository at this point in the history
Signed-off-by: Haobo Gu <[email protected]>
  • Loading branch information
HaoboGu committed Feb 20, 2024
1 parent fff98bb commit 6fbf11d
Show file tree
Hide file tree
Showing 2 changed files with 84 additions and 51 deletions.
131 changes: 82 additions & 49 deletions rmk/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,13 @@

use config::{RmkConfig, VialConfig};
use core::{cell::RefCell, convert::Infallible};
use defmt::{error, info};
use defmt::{debug, error};
use embassy_futures::join::join;
use embassy_time::Timer;
use embassy_usb::driver::Driver;
use embassy_usb::{
class::hid::{HidReader, HidReaderWriter, HidWriter},
driver::Driver,
};
use embedded_hal::digital::{InputPin, OutputPin, PinState};
use embedded_storage::nor_flash::NorFlash;
use keyboard::Keyboard;
Expand Down Expand Up @@ -61,61 +64,26 @@ pub async fn initialize_keyboard_with_config_and_run<
keymap: &'static RefCell<KeyMap<F, EEPROM_SIZE, ROW, COL, NUM_LAYER>>,
keyboard_config: RmkConfig<'static>,
) -> ! {
let (mut keyboard, mut usb_device, vial_service) = (
// TODO: Config struct for keyboard services
// Create keyboard services and devices
let (mut keyboard, mut usb_device, mut vial_service) = (
Keyboard::new(input_pins, output_pins, keymap),
KeyboardUsbDevice::new(driver, keyboard_config.usb_config),
VialService::new(keymap, keyboard_config.vial_config),
);

// TODO: Config struct for keyboard light service
let mut light_service: LightService<Out> = LightService::new(None, None, None, PinState::Low);

// Create 4 tasks: usb, keyboard, led, vial
let usb_fut = usb_device.device.run();
let keyboard_fut = async {
loop {
let _ = keyboard.keyboard_task().await;
keyboard
.send_report(&mut usb_device.keyboard_hid_writer)
.await;
keyboard.send_other_report(&mut usb_device.other_hid).await;
}
};

// Keyboard state defined in protocol, aka capslock/numslock/scrolllock
let led_reader_fut = async {
let mut led_indicator_data: [u8; 1] = [0; 1];
loop {
match usb_device
.keyboard_hid_reader
.read(&mut led_indicator_data)
.await
{
Ok(_) => {
let indicator = match LedIndicator::unpack_from_slice(&led_indicator_data) {
Ok(p) => p,
Err(_) => {
info!("packing error: {:b}", led_indicator_data[0]);
LedIndicator::default()
}
};
info!("Read keyboard state: {:?}", indicator);
// Ignore the result, which is `Infallible` in most cases
light_service.set_leds(indicator).ok();
}
Err(e) => error!("Read keyboard state error: {}", e),
};
Timer::after_millis(10).await;
}
};
let keyboard_fut = keyboard_task(
&mut keyboard,
&mut usb_device.keyboard_hid_writer,
&mut usb_device.other_hid_writer,
);
let led_reader_fut = led_task(&mut usb_device.keyboard_hid_reader, &mut light_service);
let via_fut = vial_task(&mut usb_device.via_hid, &mut vial_service);

let via_fut = async {
loop {
vial_service
.process_via_report(&mut usb_device.via_hid)
.await;
Timer::after_millis(1).await;
}
};
// Run all tasks
join(usb_fut, join(join(keyboard_fut, led_reader_fut), via_fut)).await;

panic!("Keyboard service is died")
Expand Down Expand Up @@ -159,3 +127,68 @@ pub async fn initialize_keyboard_and_run<
)
.await
}

async fn keyboard_task<
'a,
D: Driver<'a>,
In: InputPin<Error = Infallible>,
Out: OutputPin<Error = Infallible>,
F: NorFlash,
const EEPROM_SIZE: usize,
const ROW: usize,
const COL: usize,
const NUM_LAYER: usize,
>(
keyboard: &mut Keyboard<'a, In, Out, F, EEPROM_SIZE, ROW, COL, NUM_LAYER>,
keyboard_hid_writer: &mut HidWriter<'a, D, 8>,
other_hid_writer: &mut HidWriter<'a, D, 9>,
) -> ! {
loop {
let _ = keyboard.keyboard_task().await;
keyboard.send_report(keyboard_hid_writer).await;
keyboard.send_other_report(other_hid_writer).await;
}
}

async fn led_task<'a, D: Driver<'a>, Out: OutputPin>(
keyboard_hid_reader: &mut HidReader<'a, D, 1>,
light_service: &mut LightService<Out>,
) -> ! {
let mut led_indicator_data: [u8; 1] = [0; 1];
loop {
match keyboard_hid_reader.read(&mut led_indicator_data).await {
Ok(_) => {
match LedIndicator::unpack_from_slice(&led_indicator_data) {
Ok(indicator) => {
debug!("Read keyboard state: {:?}", indicator);
// Ignore the result, which is `Infallible` in most cases
light_service.set_leds(indicator).ok();
}
Err(_) => {
error!("packing error: {:b}", led_indicator_data[0]);
}
};
}
Err(e) => error!("Read keyboard state error: {}", e),
};
Timer::after_millis(10).await;
}
}

async fn vial_task<
'a,
D: Driver<'a>,
F: NorFlash,
const EEPROM_SIZE: usize,
const ROW: usize,
const COL: usize,
const NUM_LAYER: usize,
>(
via_hid: &mut HidReaderWriter<'a, D, 32, 32>,
vial_service: &mut VialService<'a, F, EEPROM_SIZE, ROW, COL, NUM_LAYER>,
) -> ! {
loop {
vial_service.process_via_report(via_hid).await;
Timer::after_millis(1).await;
}
}
4 changes: 2 additions & 2 deletions rmk/src/usb.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ pub(crate) struct KeyboardUsbDevice<'d, D: Driver<'d>> {
pub(crate) device: UsbDevice<'d, D>,
pub(crate) keyboard_hid_writer: HidWriter<'d, D, 8>,
pub(crate) keyboard_hid_reader: HidReader<'d, D, 1>,
pub(crate) other_hid: HidWriter<'d, D, 9>,
pub(crate) other_hid_writer: HidWriter<'d, D, 9>,
pub(crate) via_hid: HidReaderWriter<'d, D, 32, 32>,
}

Expand Down Expand Up @@ -115,7 +115,7 @@ impl<D: Driver<'static>> KeyboardUsbDevice<'static, D> {
device: usb,
keyboard_hid_reader: reader,
keyboard_hid_writer: writer,
other_hid,
other_hid_writer: other_hid,
via_hid,
};
}
Expand Down

0 comments on commit 6fbf11d

Please sign in to comment.