diff options
| author | Thales Fragoso <[email protected]> | 2021-03-01 21:30:03 -0300 |
|---|---|---|
| committer | Thales Fragoso <[email protected]> | 2021-03-19 19:44:30 -0300 |
| commit | 615bb33dcb3c09b1c53ce500fe402610c06427aa (patch) | |
| tree | 51b260338764358b189e61e89929e7645d32afdf | |
| parent | a39dea4d98232c9b27608d183b4cd14f2b05ad53 (diff) | |
USB: Use updated PeripheralMutex
| -rw-r--r-- | embassy-extras/src/ring_buffer.rs | 6 | ||||
| -rw-r--r-- | embassy-stm32/src/interrupt.rs | 2 | ||||
| -rw-r--r-- | embassy-stm32f4-examples/src/bin/usb_serial.rs | 2 | ||||
| -rw-r--r-- | embassy-stm32f4-examples/src/bin/usb_serial2.rs | 2 | ||||
| -rw-r--r-- | embassy-stm32f4/Cargo.toml | 2 | ||||
| -rw-r--r-- | embassy-stm32f4/src/lib.rs | 1 | ||||
| -rw-r--r-- | embassy-stm32f4/src/usb.rs | 8 | ||||
| -rw-r--r-- | embassy-stm32f4/src/usb_serial.rs | 4 | ||||
| -rw-r--r-- | embassy-stm32f4/src/util/mod.rs | 12 | ||||
| -rw-r--r-- | embassy-stm32f4/src/util/peripheral.rs | 78 | ||||
| -rw-r--r-- | embassy-stm32f4/src/util/ring_buffer.rs | 86 |
11 files changed, 17 insertions, 186 deletions
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> { | |||
| 69 | self.empty = self.start == self.end; | 69 | self.empty = self.start == self.end; |
| 70 | } | 70 | } |
| 71 | 71 | ||
| 72 | pub fn clear(&mut self) { | ||
| 73 | self.start = 0; | ||
| 74 | self.end = 0; | ||
| 75 | self.empty = true; | ||
| 76 | } | ||
| 77 | |||
| 72 | fn wrap(&self, n: usize) -> usize { | 78 | fn wrap(&self, n: usize) -> usize { |
| 73 | assert!(n <= self.buf.len()); | 79 | assert!(n <= self.buf.len()); |
| 74 | if n == self.buf.len() { | 80 | 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; | |||
| 9 | 9 | ||
| 10 | // Re-exports | 10 | // Re-exports |
| 11 | pub use cortex_m::interrupt::{CriticalSection, Mutex}; | 11 | pub use cortex_m::interrupt::{CriticalSection, Mutex}; |
| 12 | pub use embassy::interrupt::{declare, take, Interrupt}; | 12 | pub use embassy::interrupt::{declare, take, Interrupt, InterruptExt}; |
| 13 | 13 | ||
| 14 | #[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd)] | 14 | #[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd)] |
| 15 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | 15 | #[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}; | |||
| 12 | use embassy::io::{AsyncBufReadExt, AsyncWriteExt}; | 12 | use embassy::io::{AsyncBufReadExt, AsyncWriteExt}; |
| 13 | use embassy::time::{Duration, Timer}; | 13 | use embassy::time::{Duration, Timer}; |
| 14 | use embassy::util::Forever; | 14 | use embassy::util::Forever; |
| 15 | use embassy_stm32f4::interrupt::OwnedInterrupt; | 15 | use embassy_stm32f4::interrupt::InterruptExt; |
| 16 | use embassy_stm32f4::usb::Usb; | 16 | use embassy_stm32f4::usb::Usb; |
| 17 | use embassy_stm32f4::usb_serial::UsbSerial; | 17 | use embassy_stm32f4::usb_serial::UsbSerial; |
| 18 | use embassy_stm32f4::{interrupt, pac, rtc}; | 18 | 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; | |||
| 11 | use embassy::executor::{task, Executor}; | 11 | use embassy::executor::{task, Executor}; |
| 12 | use embassy::io::{AsyncBufReadExt, AsyncWriteExt}; | 12 | use embassy::io::{AsyncBufReadExt, AsyncWriteExt}; |
| 13 | use embassy::util::Forever; | 13 | use embassy::util::Forever; |
| 14 | use embassy_stm32f4::interrupt::OwnedInterrupt; | 14 | use embassy_stm32f4::interrupt::InterruptExt; |
| 15 | use embassy_stm32f4::usb::Usb; | 15 | use embassy_stm32f4::usb::Usb; |
| 16 | use embassy_stm32f4::usb_serial::UsbSerial; | 16 | use embassy_stm32f4::usb_serial::UsbSerial; |
| 17 | use embassy_stm32f4::{interrupt, pac}; | 17 | 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"] | |||
| 32 | [dependencies] | 32 | [dependencies] |
| 33 | embassy = { version = "0.1.0", path = "../embassy" } | 33 | embassy = { version = "0.1.0", path = "../embassy" } |
| 34 | embassy-stm32 = { version = "0.1.0", path = "../embassy-stm32" } | 34 | embassy-stm32 = { version = "0.1.0", path = "../embassy-stm32" } |
| 35 | embassy-extras = {version = "0.1.0", path = "../embassy-extras" } | ||
| 36 | |||
| 35 | defmt = { version = "0.2.0", optional = true } | 37 | defmt = { version = "0.2.0", optional = true } |
| 36 | log = { version = "0.4.11", optional = true } | 38 | log = { version = "0.4.11", optional = true } |
| 37 | cortex-m-rt = "0.6.13" | 39 | 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; | |||
| 318 | pub mod serial; | 318 | pub mod serial; |
| 319 | pub mod usb; | 319 | pub mod usb; |
| 320 | pub mod usb_serial; | 320 | pub mod usb_serial; |
| 321 | pub mod util; | ||
| 322 | 321 | ||
| 323 | pub(crate) mod cdc_acm; | 322 | pub(crate) mod cdc_acm; |
| 324 | 323 | ||
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; | |||
| 8 | 8 | ||
| 9 | use crate::interrupt; | 9 | use crate::interrupt; |
| 10 | use crate::usb_serial::{ReadInterface, UsbSerial, WriteInterface}; | 10 | use crate::usb_serial::{ReadInterface, UsbSerial, WriteInterface}; |
| 11 | use crate::util::peripheral::{PeripheralMutex, PeripheralState}; | 11 | use embassy_extras::peripheral::{PeripheralMutex, PeripheralState}; |
| 12 | 12 | ||
| 13 | pub struct State<'bus, B, T> | 13 | pub struct State<'bus, B, T> |
| 14 | where | 14 | where |
| @@ -36,7 +36,7 @@ where | |||
| 36 | pub fn new<S: IntoClassSet<B, T>>( | 36 | pub fn new<S: IntoClassSet<B, T>>( |
| 37 | device: UsbDevice<'bus, B>, | 37 | device: UsbDevice<'bus, B>, |
| 38 | class_set: S, | 38 | class_set: S, |
| 39 | irq: interrupt::OTG_FSInterrupt, | 39 | irq: interrupt::OTG_FS, |
| 40 | ) -> Self { | 40 | ) -> Self { |
| 41 | let state = State { | 41 | let state = State { |
| 42 | device, | 42 | device, |
| @@ -54,7 +54,7 @@ where | |||
| 54 | let mutex = unsafe { Pin::new_unchecked(&mut *mutex) }; | 54 | let mutex = unsafe { Pin::new_unchecked(&mut *mutex) }; |
| 55 | 55 | ||
| 56 | // Use inner to register the irq | 56 | // Use inner to register the irq |
| 57 | mutex.with(|_, _| {}); | 57 | mutex.register_interrupt(); |
| 58 | } | 58 | } |
| 59 | } | 59 | } |
| 60 | 60 | ||
| @@ -119,7 +119,7 @@ where | |||
| 119 | B: UsbBus, | 119 | B: UsbBus, |
| 120 | T: ClassSet<B>, | 120 | T: ClassSet<B>, |
| 121 | { | 121 | { |
| 122 | type Interrupt = interrupt::OTG_FSInterrupt; | 122 | type Interrupt = interrupt::OTG_FS; |
| 123 | fn on_interrupt(&mut self) { | 123 | fn on_interrupt(&mut self) { |
| 124 | self.classes.poll_all(&mut self.device); | 124 | self.classes.poll_all(&mut self.device); |
| 125 | } | 125 | } |
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; | |||
| 11 | 11 | ||
| 12 | use crate::cdc_acm::CdcAcmClass; | 12 | use crate::cdc_acm::CdcAcmClass; |
| 13 | use crate::usb::{ClassSet, SerialState, State}; | 13 | use crate::usb::{ClassSet, SerialState, State}; |
| 14 | use crate::util::peripheral::PeripheralMutex; | 14 | use embassy_extras::peripheral::PeripheralMutex; |
| 15 | use crate::util::ring_buffer::RingBuffer; | 15 | use embassy_extras::ring_buffer::RingBuffer; |
| 16 | 16 | ||
| 17 | pub struct ReadInterface<'a, 'bus, 'c, I, B, T> | 17 | pub struct ReadInterface<'a, 'bus, 'c, I, B, T> |
| 18 | where | 18 | 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 @@ | |||
| 1 | pub mod peripheral; | ||
| 2 | pub mod ring_buffer; | ||
| 3 | |||
| 4 | /// Low power blocking wait loop using WFE/SEV. | ||
| 5 | pub fn low_power_wait_until(mut condition: impl FnMut() -> bool) { | ||
| 6 | while !condition() { | ||
| 7 | // WFE might "eat" an event that would have otherwise woken the executor. | ||
| 8 | cortex_m::asm::wfe(); | ||
| 9 | } | ||
| 10 | // Retrigger an event to be transparent to the executor. | ||
| 11 | cortex_m::asm::sev(); | ||
| 12 | } | ||
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 @@ | |||
| 1 | use core::cell::UnsafeCell; | ||
| 2 | use core::marker::{PhantomData, PhantomPinned}; | ||
| 3 | use core::pin::Pin; | ||
| 4 | use core::sync::atomic::{compiler_fence, Ordering}; | ||
| 5 | |||
| 6 | use crate::interrupt::OwnedInterrupt; | ||
| 7 | |||
| 8 | pub trait PeripheralState { | ||
| 9 | type Interrupt: OwnedInterrupt; | ||
| 10 | fn on_interrupt(&mut self); | ||
| 11 | } | ||
| 12 | |||
| 13 | pub struct PeripheralMutex<S: PeripheralState> { | ||
| 14 | inner: Option<(UnsafeCell<S>, S::Interrupt)>, | ||
| 15 | _not_send: PhantomData<*mut ()>, | ||
| 16 | _pinned: PhantomPinned, | ||
| 17 | } | ||
| 18 | |||
| 19 | impl<S: PeripheralState> PeripheralMutex<S> { | ||
| 20 | pub fn new(state: S, irq: S::Interrupt) -> Self { | ||
| 21 | Self { | ||
| 22 | inner: Some((UnsafeCell::new(state), irq)), | ||
| 23 | _not_send: PhantomData, | ||
| 24 | _pinned: PhantomPinned, | ||
| 25 | } | ||
| 26 | } | ||
| 27 | |||
| 28 | pub fn with<R>(self: Pin<&mut Self>, f: impl FnOnce(&mut S, &mut S::Interrupt) -> R) -> R { | ||
| 29 | let this = unsafe { self.get_unchecked_mut() }; | ||
| 30 | let (state, irq) = unwrap!(this.inner.as_mut()); | ||
| 31 | |||
| 32 | irq.disable(); | ||
| 33 | compiler_fence(Ordering::SeqCst); | ||
| 34 | |||
| 35 | irq.set_handler( | ||
| 36 | |p| { | ||
| 37 | // Safety: it's OK to get a &mut to the state, since | ||
| 38 | // - We're in the IRQ, no one else can't preempt us | ||
| 39 | // - We can't have preempted a with() call because the irq is disabled during it. | ||
| 40 | let state = unsafe { &mut *(p as *mut S) }; | ||
| 41 | state.on_interrupt(); | ||
| 42 | }, | ||
| 43 | state.get() as *mut (), | ||
| 44 | ); | ||
| 45 | |||
| 46 | // Safety: it's OK to get a &mut to the state, since the irq is disabled. | ||
| 47 | let state = unsafe { &mut *state.get() }; | ||
| 48 | |||
| 49 | let r = f(state, irq); | ||
| 50 | |||
| 51 | compiler_fence(Ordering::SeqCst); | ||
| 52 | irq.enable(); | ||
| 53 | |||
| 54 | r | ||
| 55 | } | ||
| 56 | |||
| 57 | pub fn try_free(self: Pin<&mut Self>) -> Option<(S, S::Interrupt)> { | ||
| 58 | let this = unsafe { self.get_unchecked_mut() }; | ||
| 59 | this.inner.take().map(|(state, irq)| { | ||
| 60 | irq.disable(); | ||
| 61 | irq.remove_handler(); | ||
| 62 | (state.into_inner(), irq) | ||
| 63 | }) | ||
| 64 | } | ||
| 65 | |||
| 66 | pub fn free(self: Pin<&mut Self>) -> (S, S::Interrupt) { | ||
| 67 | unwrap!(self.try_free()) | ||
| 68 | } | ||
| 69 | } | ||
| 70 | |||
| 71 | impl<S: PeripheralState> Drop for PeripheralMutex<S> { | ||
| 72 | fn drop(&mut self) { | ||
| 73 | if let Some((_state, irq)) = &mut self.inner { | ||
| 74 | irq.disable(); | ||
| 75 | irq.remove_handler(); | ||
| 76 | } | ||
| 77 | } | ||
| 78 | } | ||
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 @@ | |||
| 1 | use crate::fmt::{assert, *}; | ||
| 2 | |||
| 3 | pub struct RingBuffer<'a> { | ||
| 4 | buf: &'a mut [u8], | ||
| 5 | start: usize, | ||
| 6 | end: usize, | ||
| 7 | empty: bool, | ||
| 8 | } | ||
| 9 | |||
| 10 | impl<'a> RingBuffer<'a> { | ||
| 11 | pub fn new(buf: &'a mut [u8]) -> Self { | ||
| 12 | Self { | ||
| 13 | buf, | ||
| 14 | start: 0, | ||
| 15 | end: 0, | ||
| 16 | empty: true, | ||
| 17 | } | ||
| 18 | } | ||
| 19 | |||
| 20 | pub fn push_buf(&mut self) -> &mut [u8] { | ||
| 21 | if self.start == self.end && !self.empty { | ||
| 22 | trace!(" ringbuf: push_buf empty"); | ||
| 23 | return &mut self.buf[..0]; | ||
| 24 | } | ||
| 25 | |||
| 26 | let n = if self.start <= self.end { | ||
| 27 | self.buf.len() - self.end | ||
| 28 | } else { | ||
| 29 | self.start - self.end | ||
| 30 | }; | ||
| 31 | |||
| 32 | trace!(" ringbuf: push_buf {:?}..{:?}", self.end, self.end + n); | ||
| 33 | &mut self.buf[self.end..self.end + n] | ||
| 34 | } | ||
| 35 | |||
| 36 | pub fn push(&mut self, n: usize) { | ||
| 37 | trace!(" ringbuf: push {:?}", n); | ||
| 38 | if n == 0 { | ||
| 39 | return; | ||
| 40 | } | ||
| 41 | |||
| 42 | self.end = self.wrap(self.end + n); | ||
| 43 | self.empty = false; | ||
| 44 | } | ||
| 45 | |||
| 46 | pub fn pop_buf(&mut self) -> &mut [u8] { | ||
| 47 | if self.empty { | ||
| 48 | trace!(" ringbuf: pop_buf empty"); | ||
| 49 | return &mut self.buf[..0]; | ||
| 50 | } | ||
| 51 | |||
| 52 | let n = if self.end <= self.start { | ||
| 53 | self.buf.len() - self.start | ||
| 54 | } else { | ||
| 55 | self.end - self.start | ||
| 56 | }; | ||
| 57 | |||
| 58 | trace!(" ringbuf: pop_buf {:?}..{:?}", self.start, self.start + n); | ||
| 59 | &mut self.buf[self.start..self.start + n] | ||
| 60 | } | ||
| 61 | |||
| 62 | pub fn pop(&mut self, n: usize) { | ||
| 63 | trace!(" ringbuf: pop {:?}", n); | ||
| 64 | if n == 0 { | ||
| 65 | return; | ||
| 66 | } | ||
| 67 | |||
| 68 | self.start = self.wrap(self.start + n); | ||
| 69 | self.empty = self.start == self.end; | ||
| 70 | } | ||
| 71 | |||
| 72 | pub fn clear(&mut self) { | ||
| 73 | self.start = 0; | ||
| 74 | self.end = 0; | ||
| 75 | self.empty = true; | ||
| 76 | } | ||
| 77 | |||
| 78 | fn wrap(&self, n: usize) -> usize { | ||
| 79 | assert!(n <= self.buf.len()); | ||
| 80 | if n == self.buf.len() { | ||
| 81 | 0 | ||
| 82 | } else { | ||
| 83 | n | ||
| 84 | } | ||
| 85 | } | ||
| 86 | } | ||
