diff --git a/usart_async_buffered_generalized/src/bin/main.rs b/usart_async_buffered_generalized/src/bin/main.rs index 9e73f7b..9e3aaa5 100644 --- a/usart_async_buffered_generalized/src/bin/main.rs +++ b/usart_async_buffered_generalized/src/bin/main.rs @@ -5,15 +5,23 @@ use defmt::*; use embassy_executor::Spawner; use embassy_time::{Duration, Timer}; -use embassy_stm32::usart::{Config, Uart}; use embassy_stm32::bind_interrupts; -use embassy_stm32::usart::{BufferedUart, BufferedInterruptHandler}; -use embassy_stm32::mode::Async; -use embedded_io_async::{Read, Write}; use embassy_stm32::peripherals; +use embassy_stm32::usart::{BufferedInterruptHandler, BufferedUart, Config}; +use embedded_io_async::{Read, Write}; use static_cell::StaticCell; use {defmt_rtt as _, panic_probe as _}; +// Select + channel + heapless Vec +use embassy_futures::select::{select, Either}; +use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex; +use embassy_sync::channel::Channel; +use heapless::Vec; + +const MAX_MSG: usize = 64; +const QSIZE: usize = 4; +static UART_TX: Channel, QSIZE> = Channel::new(); + bind_interrupts!( struct Irqs { USART1 => BufferedInterruptHandler; @@ -21,16 +29,40 @@ bind_interrupts!( ); #[embassy_executor::task] -async fn receive_uart(mut uart: BufferedUart<'static>) { +async fn uart_task(mut uart: BufferedUart<'static>) { let mut buf = [0u8; 1]; + loop { - unwrap!(uart.read(&mut buf).await); - unwrap!(uart.write(&buf).await); - unwrap!(uart.write(b"a\r\n").await); - info!("uart received {}", buf[0]); + let rx_fut = uart.read(&mut buf); + let tx_fut = UART_TX.receive(); + + match select(rx_fut, tx_fut).await { + // Incoming RX byte + Either::First(res) => { + if let Ok(_) = res { + // Echo and log + unwrap!(uart.write(&buf).await); + unwrap!(uart.write(b"a\r\n").await); + info!("uart received {}", buf[0]); + unwrap!(uart.flush().await); + } + } + // Outgoing TX request from main + Either::Second(msg) => { + unwrap!(uart.write(&msg).await); + unwrap!(uart.flush().await); + info!("sent {} bytes", msg.len()); + } + } } } +pub async fn send_uart(data: &[u8]) { + let mut v: Vec = Vec::new(); + let _ = v.extend_from_slice(data); // truncate if too long + UART_TX.send(v).await; +} + #[embassy_executor::main] async fn main(spawner: Spawner) { info!("tititititi"); @@ -44,7 +76,6 @@ async fn main(spawner: Spawner) { let mut cfg = Config::default(); cfg.baudrate = 230_400; - let config = Config::default(); let usart = BufferedUart::new( p.USART1, p.PA10, // RX @@ -53,15 +84,22 @@ async fn main(spawner: Spawner) { rx_buf, Irqs, cfg, - ).unwrap(); + ) + .unwrap(); - info!("starting echo"); - spawner.spawn(receive_uart(usart)).unwrap(); + info!("starting uart task"); + spawner.spawn(uart_task(usart)).unwrap(); - let mut counter: u8 = 230; + let mut counter: u32 = 230; loop { counter = counter.wrapping_add(1); - info!("CPU doing other work: {}", counter); - Timer::after(Duration::from_millis(300)).await; + + if counter % 10000 == 0 { + info!("CPU doing other work: {}", counter); + } + if counter % 100000 == 0 { + // Send whenever you want; the UART task performs the actual write. + send_uart(b"Hello\r\n").await; + } } }