diff --git a/embassy-extras/src/ring_buffer.rs b/embassy-extras/src/ring_buffer.rs index f2b9f7359..0ef66f00a 100644 --- a/embassy-extras/src/ring_buffer.rs +++ b/embassy-extras/src/ring_buffer.rs @@ -69,6 +69,12 @@ impl<'a> RingBuffer<'a> { self.empty = self.start == self.end; } + pub fn clear(&mut self) { + self.start = 0; + self.end = 0; + self.empty = true; + } + fn wrap(&self, n: usize) -> usize { assert!(n <= self.buf.len()); if n == self.buf.len() { diff --git a/embassy-stm32/src/interrupt.rs b/embassy-stm32/src/interrupt.rs index 5ad7ef8ef..7def7be58 100644 --- a/embassy-stm32/src/interrupt.rs +++ b/embassy-stm32/src/interrupt.rs @@ -9,7 +9,7 @@ use crate::pac::NVIC_PRIO_BITS; // Re-exports pub use cortex_m::interrupt::{CriticalSection, Mutex}; -pub use embassy::interrupt::{declare, take, Interrupt}; +pub use embassy::interrupt::{declare, take, Interrupt, InterruptExt}; #[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] diff --git a/embassy-stm32f4-examples/src/bin/usb_serial.rs b/embassy-stm32f4-examples/src/bin/usb_serial.rs index 90139c5ac..bf8ca4252 100644 --- a/embassy-stm32f4-examples/src/bin/usb_serial.rs +++ b/embassy-stm32f4-examples/src/bin/usb_serial.rs @@ -12,7 +12,7 @@ use embassy::executor::{task, Executor}; use embassy::io::{AsyncBufReadExt, AsyncWriteExt}; use embassy::time::{Duration, Timer}; use embassy::util::Forever; -use embassy_stm32f4::interrupt::OwnedInterrupt; +use embassy_stm32f4::interrupt::InterruptExt; use embassy_stm32f4::usb::Usb; use embassy_stm32f4::usb_serial::UsbSerial; use embassy_stm32f4::{interrupt, pac, rtc}; diff --git a/embassy-stm32f4-examples/src/bin/usb_serial2.rs b/embassy-stm32f4-examples/src/bin/usb_serial2.rs index 79e323ca6..dd2618759 100644 --- a/embassy-stm32f4-examples/src/bin/usb_serial2.rs +++ b/embassy-stm32f4-examples/src/bin/usb_serial2.rs @@ -11,7 +11,7 @@ use defmt::panic; use embassy::executor::{task, Executor}; use embassy::io::{AsyncBufReadExt, AsyncWriteExt}; use embassy::util::Forever; -use embassy_stm32f4::interrupt::OwnedInterrupt; +use embassy_stm32f4::interrupt::InterruptExt; use embassy_stm32f4::usb::Usb; use embassy_stm32f4::usb_serial::UsbSerial; use embassy_stm32f4::{interrupt, pac}; diff --git a/embassy-stm32f4/Cargo.toml b/embassy-stm32f4/Cargo.toml index b39a141b4..55e6b84dd 100644 --- a/embassy-stm32f4/Cargo.toml +++ b/embassy-stm32f4/Cargo.toml @@ -32,6 +32,8 @@ stm32f479 = ["stm32f4xx-hal/stm32f469", "embassy-stm32/stm32f479"] [dependencies] embassy = { version = "0.1.0", path = "../embassy" } embassy-stm32 = { version = "0.1.0", path = "../embassy-stm32" } +embassy-extras = {version = "0.1.0", path = "../embassy-extras" } + defmt = { version = "0.2.0", optional = true } log = { version = "0.4.11", optional = true } cortex-m-rt = "0.6.13" diff --git a/embassy-stm32f4/src/lib.rs b/embassy-stm32f4/src/lib.rs index 1788f5e77..1d44e379f 100644 --- a/embassy-stm32f4/src/lib.rs +++ b/embassy-stm32f4/src/lib.rs @@ -318,7 +318,6 @@ pub mod rtc; pub mod serial; pub mod usb; pub mod usb_serial; -pub mod util; pub(crate) mod cdc_acm; diff --git a/embassy-stm32f4/src/usb.rs b/embassy-stm32f4/src/usb.rs index 9e7411562..1d43c4f51 100644 --- a/embassy-stm32f4/src/usb.rs +++ b/embassy-stm32f4/src/usb.rs @@ -8,7 +8,7 @@ use usb_device::device::UsbDevice; use crate::interrupt; use crate::usb_serial::{ReadInterface, UsbSerial, WriteInterface}; -use crate::util::peripheral::{PeripheralMutex, PeripheralState}; +use embassy_extras::peripheral::{PeripheralMutex, PeripheralState}; pub struct State<'bus, B, T> where @@ -36,7 +36,7 @@ where pub fn new>( device: UsbDevice<'bus, B>, class_set: S, - irq: interrupt::OTG_FSInterrupt, + irq: interrupt::OTG_FS, ) -> Self { let state = State { device, @@ -54,7 +54,7 @@ where let mutex = unsafe { Pin::new_unchecked(&mut *mutex) }; // Use inner to register the irq - mutex.with(|_, _| {}); + mutex.register_interrupt(); } } @@ -119,7 +119,7 @@ where B: UsbBus, T: ClassSet, { - type Interrupt = interrupt::OTG_FSInterrupt; + type Interrupt = interrupt::OTG_FS; fn on_interrupt(&mut self) { self.classes.poll_all(&mut self.device); } diff --git a/embassy-stm32f4/src/usb_serial.rs b/embassy-stm32f4/src/usb_serial.rs index bacc886d8..00d92c9c5 100644 --- a/embassy-stm32f4/src/usb_serial.rs +++ b/embassy-stm32f4/src/usb_serial.rs @@ -11,8 +11,8 @@ use usb_device::UsbError; use crate::cdc_acm::CdcAcmClass; use crate::usb::{ClassSet, SerialState, State}; -use crate::util::peripheral::PeripheralMutex; -use crate::util::ring_buffer::RingBuffer; +use embassy_extras::peripheral::PeripheralMutex; +use embassy_extras::ring_buffer::RingBuffer; pub struct ReadInterface<'a, 'bus, 'c, I, B, T> where diff --git a/embassy-stm32f4/src/util/mod.rs b/embassy-stm32f4/src/util/mod.rs deleted file mode 100644 index cf3306545..000000000 --- a/embassy-stm32f4/src/util/mod.rs +++ /dev/null @@ -1,12 +0,0 @@ -pub mod peripheral; -pub mod ring_buffer; - -/// Low power blocking wait loop using WFE/SEV. -pub fn low_power_wait_until(mut condition: impl FnMut() -> bool) { - while !condition() { - // WFE might "eat" an event that would have otherwise woken the executor. - cortex_m::asm::wfe(); - } - // Retrigger an event to be transparent to the executor. - cortex_m::asm::sev(); -} diff --git a/embassy-stm32f4/src/util/peripheral.rs b/embassy-stm32f4/src/util/peripheral.rs deleted file mode 100644 index f2c7912ff..000000000 --- a/embassy-stm32f4/src/util/peripheral.rs +++ /dev/null @@ -1,78 +0,0 @@ -use core::cell::UnsafeCell; -use core::marker::{PhantomData, PhantomPinned}; -use core::pin::Pin; -use core::sync::atomic::{compiler_fence, Ordering}; - -use crate::interrupt::OwnedInterrupt; - -pub trait PeripheralState { - type Interrupt: OwnedInterrupt; - fn on_interrupt(&mut self); -} - -pub struct PeripheralMutex { - inner: Option<(UnsafeCell, S::Interrupt)>, - _not_send: PhantomData<*mut ()>, - _pinned: PhantomPinned, -} - -impl PeripheralMutex { - pub fn new(state: S, irq: S::Interrupt) -> Self { - Self { - inner: Some((UnsafeCell::new(state), irq)), - _not_send: PhantomData, - _pinned: PhantomPinned, - } - } - - pub fn with(self: Pin<&mut Self>, f: impl FnOnce(&mut S, &mut S::Interrupt) -> R) -> R { - let this = unsafe { self.get_unchecked_mut() }; - let (state, irq) = unwrap!(this.inner.as_mut()); - - irq.disable(); - compiler_fence(Ordering::SeqCst); - - irq.set_handler( - |p| { - // Safety: it's OK to get a &mut to the state, since - // - We're in the IRQ, no one else can't preempt us - // - We can't have preempted a with() call because the irq is disabled during it. - let state = unsafe { &mut *(p as *mut S) }; - state.on_interrupt(); - }, - state.get() as *mut (), - ); - - // Safety: it's OK to get a &mut to the state, since the irq is disabled. - let state = unsafe { &mut *state.get() }; - - let r = f(state, irq); - - compiler_fence(Ordering::SeqCst); - irq.enable(); - - r - } - - pub fn try_free(self: Pin<&mut Self>) -> Option<(S, S::Interrupt)> { - let this = unsafe { self.get_unchecked_mut() }; - this.inner.take().map(|(state, irq)| { - irq.disable(); - irq.remove_handler(); - (state.into_inner(), irq) - }) - } - - pub fn free(self: Pin<&mut Self>) -> (S, S::Interrupt) { - unwrap!(self.try_free()) - } -} - -impl Drop for PeripheralMutex { - fn drop(&mut self) { - if let Some((_state, irq)) = &mut self.inner { - irq.disable(); - irq.remove_handler(); - } - } -} diff --git a/embassy-stm32f4/src/util/ring_buffer.rs b/embassy-stm32f4/src/util/ring_buffer.rs deleted file mode 100644 index 0ef66f00a..000000000 --- a/embassy-stm32f4/src/util/ring_buffer.rs +++ /dev/null @@ -1,86 +0,0 @@ -use crate::fmt::{assert, *}; - -pub struct RingBuffer<'a> { - buf: &'a mut [u8], - start: usize, - end: usize, - empty: bool, -} - -impl<'a> RingBuffer<'a> { - pub fn new(buf: &'a mut [u8]) -> Self { - Self { - buf, - start: 0, - end: 0, - empty: true, - } - } - - pub fn push_buf(&mut self) -> &mut [u8] { - if self.start == self.end && !self.empty { - trace!(" ringbuf: push_buf empty"); - return &mut self.buf[..0]; - } - - let n = if self.start <= self.end { - self.buf.len() - self.end - } else { - self.start - self.end - }; - - trace!(" ringbuf: push_buf {:?}..{:?}", self.end, self.end + n); - &mut self.buf[self.end..self.end + n] - } - - pub fn push(&mut self, n: usize) { - trace!(" ringbuf: push {:?}", n); - if n == 0 { - return; - } - - self.end = self.wrap(self.end + n); - self.empty = false; - } - - pub fn pop_buf(&mut self) -> &mut [u8] { - if self.empty { - trace!(" ringbuf: pop_buf empty"); - return &mut self.buf[..0]; - } - - let n = if self.end <= self.start { - self.buf.len() - self.start - } else { - self.end - self.start - }; - - trace!(" ringbuf: pop_buf {:?}..{:?}", self.start, self.start + n); - &mut self.buf[self.start..self.start + n] - } - - pub fn pop(&mut self, n: usize) { - trace!(" ringbuf: pop {:?}", n); - if n == 0 { - return; - } - - self.start = self.wrap(self.start + n); - self.empty = self.start == self.end; - } - - pub fn clear(&mut self) { - self.start = 0; - self.end = 0; - self.empty = true; - } - - fn wrap(&self, n: usize) -> usize { - assert!(n <= self.buf.len()); - if n == self.buf.len() { - 0 - } else { - n - } - } -}