From c89faa42abc962f5626369dcee332f9d28f2b259 Mon Sep 17 00:00:00 2001 From: Benjamin Koch <bbbsnowball@gmail.com> Date: Sat, 20 May 2023 16:41:42 +0200 Subject: [PATCH] merge UART RX task with autobaud task --- firmware/rust1/src/bin/heizung.rs | 97 ++++++++++++++++++++++++------- 1 file changed, 76 insertions(+), 21 deletions(-) diff --git a/firmware/rust1/src/bin/heizung.rs b/firmware/rust1/src/bin/heizung.rs index 4248da4..e0d30a4 100644 --- a/firmware/rust1/src/bin/heizung.rs +++ b/firmware/rust1/src/bin/heizung.rs @@ -5,7 +5,7 @@ use defmt::*; use embassy_executor::Spawner; //use embassy_futures::join::join; -use embassy_futures::select::{select, Either, select3, Either3}; +use embassy_futures::select::*; use embassy_rp::gpio; use embassy_time::{Duration, Timer}; use embassy_rp::gpio::{Input, Level, Output, Pull, Flex}; @@ -24,18 +24,6 @@ use heapless::String; use fixed::traits::ToFixed; use fixed_macro::types::U56F8; -#[embassy_executor::task] -async fn reader(mut rx: UartRx<'static, UART0, uart::Async>) { - info!("Reading..."); - loop { - let mut buf = [0; 1]; - match rx.read(&mut buf).await { - Result::Ok(()) => info!("RX {:?}", buf), - Result::Err(e) => info!("RX error {:?}", e), - } - } -} - fn append_hex1<const N : usize>(s : &mut String<N>, num : u8) -> Result<(), ()> { let ch = if num < 10 { ('0' as u8 + num) as char @@ -291,9 +279,63 @@ async fn debug_print_pio_addr(sm: embassy_rp::pac::pio::StateMachine) { } } +mod dont_abort { + use core::future::*; + use core::pin::Pin; + use core::task::*; + + pub struct DontAbort<A> { + a: A, + done: bool + } + + pub struct DontAbortFuture<'a, A> { + inner: &'a mut DontAbort<A> + } + + impl<A> DontAbort<A> { + pub fn new(a: A) -> DontAbort<A> { + DontAbort { a, done: false } + } + + #[allow(dead_code)] + pub fn done(self: &Self) -> bool { + return self.done; + } + + pub fn continue_wait<'a>(self: &'a mut Self) -> DontAbortFuture<'a, A> { + DontAbortFuture { inner: self } + } + } + + impl<A: Unpin> Unpin for DontAbort<A> {} + impl<'a, A: Unpin> Unpin for DontAbortFuture<'a, A> {} + + impl<'a, A> Future for DontAbortFuture<'a, A> + where + A: Future, + { + type Output = A::Output; + + fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> { + let this = unsafe { self.get_unchecked_mut() }; + if this.inner.done { + panic!("Ready future is called again!"); + } + let a = unsafe { Pin::new_unchecked(&mut this.inner.a) }; + if let Poll::Ready(x) = a.poll(cx) { + this.inner.done = true; + return Poll::Ready(x); + } + Poll::Pending + } + } +} + #[embassy_executor::task] -async fn autobaud_task(pio0: embassy_rp::peripherals::PIO0, rx_pin: embassy_rp::peripherals::PIN_17, - dma_channel: embassy_rp::peripherals::DMA_CH0) { +async fn uart_task(pio0: embassy_rp::peripherals::PIO0, rx_pin: embassy_rp::peripherals::PIN_17, + dma_channel: embassy_rp::peripherals::DMA_CH0, + mut rx: UartRx<'static, UART0, uart::Async>) { let Pio { mut common, sm0: mut sm, @@ -417,14 +459,17 @@ async fn autobaud_task(pio0: embassy_rp::peripherals::PIO0, rx_pin: embassy_rp:: let mut dma_in_ref = dma_channel.into_ref(); let mut din = [42u32; 9]; let mut bit_index = 0; + let mut rx_buf = [0; 1]; + let mut rx_future = dont_abort::DontAbort::new(rx.read(&mut rx_buf)); loop { - let x = select3( + let x = select4( irq0.wait(), sm.rx().dma_pull(dma_in_ref.reborrow(), &mut din), debug_print_pio_addr(embassy_rp::pac::PIO0.sm(0)), + rx_future.continue_wait(), ).await; match x { - Either3::First(_) => { + Either4::First(_) => { let mut sum = 0; let mut first = 0; let mut ok = false; @@ -494,7 +539,7 @@ async fn autobaud_task(pio0: embassy_rp::peripherals::PIO0, rx_pin: embassy_rp:: info!("Guessed baud rate: {}", baud); } }, - Either3::Second(_) => { + Either4::Second(_) => { if false { for i in 0..din.len() { if din[i] == 0 { @@ -506,6 +551,18 @@ async fn autobaud_task(pio0: embassy_rp::peripherals::PIO0, rx_pin: embassy_rp:: } } }, + Either4::Fourth(x) => { + drop(rx_future); + match x { + Result::Ok(()) => { + info!("RX {:?}", rx_buf); + }, + Result::Err(e) => { + info!("RX error {:?}", e); + }, + } + rx_future = dont_abort::DontAbort::new(rx.read(&mut rx_buf)); + }, _ => { }, } @@ -568,14 +625,12 @@ async fn main(spawner: Spawner) { p.DMA_CH1, uart_config, ); - unwrap!(spawner.spawn(reader(uart_rx))); + unwrap!(spawner.spawn(uart_task(p.PIO0, rx_for_autobaud, p.DMA_CH0, uart_rx))); if false { unwrap!(spawner.spawn(beeper_task(p.PWM_CH3, led_r))); } - unwrap!(spawner.spawn(autobaud_task(p.PIO0, rx_for_autobaud, p.DMA_CH0))); - loop { led_b.set_high(); Timer::after(Duration::from_secs(1)).await; -- GitLab