embassy-rs / embassy

Modern embedded framework, using Rust and async.
https://embassy.dev
Apache License 2.0
5.33k stars 735 forks source link

Unable to create Timer interrupt for stm32f4 #2612

Open learncodingforweb opened 7 months ago

learncodingforweb commented 7 months ago

Hi, I do not know how to create timer, which will gives me time in ms elapsed. so that i can use timer value to get usart data received through DMA idle interrupt. if there is gap for a time more than 20ms between data received on serial port. then it will gives me interrupt to report pick up data? I tried to find example code provided the embassy examples, but there is no example code. can you tell me. how can i use timer interrupt in embassy?

bind_interrupts!(struct UIrg{
    USART3 => usart::InterruptHandler<peripherals::USART3>;
});

#[embassy_executor::task]
async fn rf_recieve(mut rx: UartRx<'static, USART3, DMA1_CH1>) {
    let mut buf: [u8; 8];
    defmt::info!("idle mode selected");
    loop {
        buf = [0; 8];
        let r = rx.read_until_idle(&mut buf).await;
        if r.is_ok() {
            let sz = r.unwrap();
            if sz == 8 {
                let fd = bsp::rf_filter(&buf);
                defmt::info!("{} => {:?}", sz, fd);
            } else {
                defmt::info!("partial data {} => {:?}", sz, buf);
            }
        } else {
            defmt::info!("serial data read error");
        }
    }
}
lulf commented 6 months ago

I'm not entirely sure what you're asking or if my answer is relevant to you, but the way to create a timer is this:

use embassy_time::{Timer, Duration};

Timer::after(Duration::from_millis(20)).await

You can then combine the timer with other things such as the read:

use embassy_futures::select::{select, Either};

match select(Timer::after(Duration::from_millis(20)), rx.read_until_idle(&mut buf)).await {
    Either::First(_) => {} // Timer fired!
    Either::Second(_) => {} // Data was read
}

It's not entirely clear to me why you'd want to do this, because read_until_idle kinda does what you describe internally, waiting until the RX is idle before returning.