diff --git a/src/communication.rs b/src/communication.rs index ce0b8a3..129409a 100644 --- a/src/communication.rs +++ b/src/communication.rs @@ -17,7 +17,7 @@ use postcard_rpc::{ }, }; -use bioz_icd_rs::{PingEndpoint, GetUniqueIdEndpoint, ENDPOINT_LIST, TOPICS_IN_LIST, TOPICS_OUT_LIST}; +use bioz_icd_rs::{PingEndpoint, GetUniqueIdEndpoint, SetGreenLedEndpoint, ENDPOINT_LIST, TOPICS_IN_LIST, TOPICS_OUT_LIST}; pub struct Context { pub unique_id: [u8; 12], @@ -48,6 +48,7 @@ define_dispatch! { | ---------- | ---- | ------- | | PingEndpoint | blocking | ping_handler | | GetUniqueIdEndpoint | blocking | get_unique_id_handler | + | SetGreenLedEndpoint | async | set_green_led_handler | }; topics_in: { list: TOPICS_IN_LIST; @@ -124,4 +125,15 @@ fn ping_handler(_context: &mut Context, _header: VarHeader, rqst: u32) -> u32 { fn get_unique_id_handler(context: &mut Context, _header: VarHeader, _rqst: ()) -> [u8; 12] { info!("get_unique_id"); context.unique_id +} + +use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex; +use embassy_sync::signal::Signal; + +pub static LED_FREQUENCY_SIGNAL: Signal = Signal::new(); + +async fn set_green_led_handler(_context: &mut Context, _header: VarHeader, rqst: f32) { + info!("Set green led frequency to {:?} Hz", rqst); + + LED_FREQUENCY_SIGNAL.signal(rqst); } \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index be28dd6..9f4dc74 100644 --- a/src/main.rs +++ b/src/main.rs @@ -3,10 +3,12 @@ use defmt::info; use embassy_executor::Spawner; +use embassy_time::{Timer, Duration}; +use embassy_futures::{select::select, select::Either}; use embassy_stm32::gpio::{Level, Output, Speed}; use embassy_stm32::{i2c, spi, Config}; use embassy_stm32::time::Hertz; -use embassy_time::Timer; + use crate::ad5940_registers::{AFECON, AFEGENINTSTA}; use {defmt_rtt as _, panic_probe as _}; @@ -26,7 +28,7 @@ use embassy_stm32::usb::Driver; use embassy_stm32::{bind_interrupts, peripherals, usb}; mod communication; -use communication::init_communication; +use communication::{init_communication, LED_FREQUENCY_SIGNAL}; bind_interrupts!(struct Irqs { USB_DRD_FS => usb::InterruptHandler; @@ -122,6 +124,9 @@ async fn main(spawner: Spawner) { let driver = Driver::new(p.USB, Irqs, p.PA12, p.PA11); init_communication(driver, spawner); + // Green led task + spawner.must_spawn(green_led(led)); + loop { // Read chip id // let chip_id = ad5940.get_chipid().await.unwrap(); @@ -135,16 +140,38 @@ async fn main(spawner: Spawner) { // info!("Electrodes states: {:?}", result); // info!("high"); - led.set_high(); + - Timer::after_millis(1000).await; - led.set_low(); - Timer::after_millis(1000).await; - info!("Toggle!"); + info!("Mainloop still running!"); + + Timer::after_millis(5000).await; // ad5940.sequencer_trigger().await; } +} + +#[embassy_executor::task] +async fn green_led(mut led: Output<'static>) { + let mut delay = Duration::from_millis(500); + + loop { + // Wait for either a frequency change or a timer timeout + match select(LED_FREQUENCY_SIGNAL.wait(), Timer::after(delay)).await { + Either::First(frequency) => { + if frequency > 0.0 { + // Avoid divide-by-zero or negative delay + let millis = (1000.0 / frequency) as u64 / 2; + delay = Duration::from_millis(millis.max(1)); // enforce minimum delay of 1ms + } + } + Either::Second(_) => { + // Timer expired, proceed to toggle + } + } + + led.toggle(); + } } \ No newline at end of file