Skip to content
Snippets Groups Projects
Commit c89faa42 authored by Benjamin Koch's avatar Benjamin Koch
Browse files

merge UART RX task with autobaud task

parent 2f379bf1
No related branches found
No related tags found
No related merge requests found
......@@ -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;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment