From 59ccc45f280e05a9d2a0ece2bb1e01debadb2f7e Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Wed, 14 Apr 2021 16:01:43 +0200 Subject: Remove pin from Uart --- embassy-nrf/src/buffered_uarte.rs | 8 ++-- embassy-nrf/src/uarte.rs | 86 +++++++++++++++++++-------------------- 2 files changed, 45 insertions(+), 49 deletions(-) (limited to 'embassy-nrf/src') diff --git a/embassy-nrf/src/buffered_uarte.rs b/embassy-nrf/src/buffered_uarte.rs index 702ccde0e..9e67aaef6 100644 --- a/embassy-nrf/src/buffered_uarte.rs +++ b/embassy-nrf/src/buffered_uarte.rs @@ -78,7 +78,7 @@ impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarte<'d, U, T> { ) -> Self { unborrow!(uarte, timer, ppi_ch1, ppi_ch2, irq, rxd, txd, cts, rts); - let r = uarte.regs(); + let r = U::regs(); let rt = timer.regs(); rxd.conf().write(|w| w.input().connect().drive().h0h1()); @@ -178,7 +178,7 @@ impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarte<'d, U, T> { pub fn set_baudrate(self: Pin<&mut Self>, baudrate: Baudrate) { self.inner().with(|state, _irq| { - let r = state.uarte.regs(); + let r = U::regs(); let rt = state.timer.regs(); let timeout = 0x8000_0000 / (baudrate as u32 / 40); @@ -265,7 +265,7 @@ impl<'d, U: UarteInstance, T: TimerInstance> AsyncWrite for BufferedUarte<'d, U, impl<'a, U: UarteInstance, T: TimerInstance> Drop for State<'a, U, T> { fn drop(&mut self) { - let r = self.uarte.regs(); + let r = U::regs(); let rt = self.timer.regs(); // TODO this probably deadlocks. do like Uarte instead. @@ -290,7 +290,7 @@ impl<'a, U: UarteInstance, T: TimerInstance> PeripheralState for State<'a, U, T> type Interrupt = U::Interrupt; fn on_interrupt(&mut self) { trace!("irq: start"); - let r = self.uarte.regs(); + let r = U::regs(); let rt = self.timer.regs(); loop { diff --git a/embassy-nrf/src/uarte.rs b/embassy-nrf/src/uarte.rs index 957fa4c71..9e485907c 100644 --- a/embassy-nrf/src/uarte.rs +++ b/embassy-nrf/src/uarte.rs @@ -2,12 +2,11 @@ use core::future::Future; use core::marker::PhantomData; -use core::pin::Pin; -use core::sync::atomic::{compiler_fence, AtomicBool, Ordering}; +use core::sync::atomic::{compiler_fence, Ordering}; use core::task::Poll; +use embassy::interrupt::InterruptExt; use embassy::traits::uart::{Error, Read, Write}; use embassy::util::{AtomicWaker, OnDrop, PeripheralBorrow}; -use embassy_extras::peripheral_shared::{Peripheral, PeripheralState}; use embassy_extras::unborrow; use futures::future::poll_fn; @@ -38,16 +37,9 @@ impl Default for Config { } } -struct State { - peri: T, - - endrx_waker: AtomicWaker, - endtx_waker: AtomicWaker, -} - /// Interface to the UARTE peripheral pub struct Uarte<'d, T: Instance> { - inner: Peripheral>, + peri: T, phantom: PhantomData<&'d mut T>, } @@ -72,7 +64,7 @@ impl<'d, T: Instance> Uarte<'d, T> { ) -> Self { unborrow!(uarte, irq, rxd, txd, cts, rts); - let r = uarte.regs(); + let r = T::regs(); assert!(r.enable.read().enable().is_disabled()); @@ -115,38 +107,29 @@ impl<'d, T: Instance> Uarte<'d, T> { r.events_rxstarted.reset(); r.events_txstarted.reset(); + irq.set_handler(Self::on_interrupt); + irq.unpend(); + irq.enable(); + // Enable r.enable.write(|w| w.enable().enabled()); Self { - inner: Peripheral::new( - irq, - State { - peri: uarte, - endrx_waker: AtomicWaker::new(), - endtx_waker: AtomicWaker::new(), - }, - ), + peri: uarte, phantom: PhantomData, } } - fn inner(self: Pin<&mut Self>) -> Pin<&mut Peripheral>> { - unsafe { Pin::new_unchecked(&mut self.get_unchecked_mut().inner) } - } -} - -impl PeripheralState for State { - type Interrupt = T::Interrupt; + fn on_interrupt(_: *mut ()) { + let r = T::regs(); + let s = T::state(); - fn on_interrupt(&self) { - let r = self.peri.regs(); if r.events_endrx.read().bits() != 0 { - self.endrx_waker.wake(); + s.endrx_waker.wake(); r.intenclr.write(|w| w.endrx().clear()); } if r.events_endtx.read().bits() != 0 { - self.endtx_waker.wake(); + s.endtx_waker.wake(); r.intenclr.write(|w| w.endtx().clear()); } @@ -163,8 +146,7 @@ impl<'a, T: Instance> Drop for Uarte<'a, T> { fn drop(&mut self) { info!("uarte drop"); - let s = unsafe { Pin::new_unchecked(&mut self.inner) }.state(); - let r = s.peri.regs(); + let r = T::regs(); let did_stoprx = r.events_rxstarted.read().bits() != 0; let did_stoptx = r.events_txstarted.read().bits() != 0; @@ -194,16 +176,14 @@ impl<'d, T: Instance> Read for Uarte<'d, T> { #[rustfmt::skip] type ReadFuture<'a> where Self: 'a = impl Future> + 'a; - fn read<'a>(mut self: Pin<&'a mut Self>, rx_buffer: &'a mut [u8]) -> Self::ReadFuture<'a> { - self.as_mut().inner().register_interrupt(); - + fn read<'a>(&'a mut self, rx_buffer: &'a mut [u8]) -> Self::ReadFuture<'a> { async move { let ptr = rx_buffer.as_ptr(); let len = rx_buffer.len(); assert!(len <= EASY_DMA_SIZE); - let s = self.inner().state(); - let r = s.peri.regs(); + let r = T::regs(); + let s = T::state(); let drop = OnDrop::new(move || { info!("read drop: stopping"); @@ -250,17 +230,15 @@ impl<'d, T: Instance> Write for Uarte<'d, T> { #[rustfmt::skip] type WriteFuture<'a> where Self: 'a = impl Future> + 'a; - fn write<'a>(mut self: Pin<&'a mut Self>, tx_buffer: &'a [u8]) -> Self::WriteFuture<'a> { - self.as_mut().inner().register_interrupt(); - + fn write<'a>(&'a mut self, tx_buffer: &'a [u8]) -> Self::WriteFuture<'a> { async move { let ptr = tx_buffer.as_ptr(); let len = tx_buffer.len(); assert!(len <= EASY_DMA_SIZE); // TODO: panic if buffer is not in SRAM - let s = self.inner().state(); - let r = s.peri.regs(); + let r = T::regs(); + let s = T::state(); let drop = OnDrop::new(move || { info!("write drop: stopping"); @@ -306,8 +284,22 @@ impl<'d, T: Instance> Write for Uarte<'d, T> { mod sealed { use super::*; + pub struct State { + pub endrx_waker: AtomicWaker, + pub endtx_waker: AtomicWaker, + } + impl State { + pub const fn new() -> Self { + Self { + endrx_waker: AtomicWaker::new(), + endtx_waker: AtomicWaker::new(), + } + } + } + pub trait Instance { - fn regs(&self) -> &pac::uarte0::RegisterBlock; + fn regs() -> &'static pac::uarte0::RegisterBlock; + fn state() -> &'static State; } } @@ -318,9 +310,13 @@ pub trait Instance: sealed::Instance + 'static { macro_rules! impl_instance { ($type:ident, $irq:ident) => { impl sealed::Instance for peripherals::$type { - fn regs(&self) -> &pac::uarte0::RegisterBlock { + fn regs() -> &'static pac::uarte0::RegisterBlock { unsafe { &*pac::$type::ptr() } } + fn state() -> &'static sealed::State { + static STATE: sealed::State = sealed::State::new(); + &STATE + } } impl Instance for peripherals::$type { type Interrupt = interrupt::$irq; -- cgit