aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThales Fragoso <[email protected]>2021-03-01 21:30:03 -0300
committerThales Fragoso <[email protected]>2021-03-19 19:44:30 -0300
commit615bb33dcb3c09b1c53ce500fe402610c06427aa (patch)
tree51b260338764358b189e61e89929e7645d32afdf
parenta39dea4d98232c9b27608d183b4cd14f2b05ad53 (diff)
USB: Use updated PeripheralMutex
-rw-r--r--embassy-extras/src/ring_buffer.rs6
-rw-r--r--embassy-stm32/src/interrupt.rs2
-rw-r--r--embassy-stm32f4-examples/src/bin/usb_serial.rs2
-rw-r--r--embassy-stm32f4-examples/src/bin/usb_serial2.rs2
-rw-r--r--embassy-stm32f4/Cargo.toml2
-rw-r--r--embassy-stm32f4/src/lib.rs1
-rw-r--r--embassy-stm32f4/src/usb.rs8
-rw-r--r--embassy-stm32f4/src/usb_serial.rs4
-rw-r--r--embassy-stm32f4/src/util/mod.rs12
-rw-r--r--embassy-stm32f4/src/util/peripheral.rs78
-rw-r--r--embassy-stm32f4/src/util/ring_buffer.rs86
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
11pub use cortex_m::interrupt::{CriticalSection, Mutex}; 11pub use cortex_m::interrupt::{CriticalSection, Mutex};
12pub use embassy::interrupt::{declare, take, Interrupt}; 12pub 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};
12use embassy::io::{AsyncBufReadExt, AsyncWriteExt}; 12use embassy::io::{AsyncBufReadExt, AsyncWriteExt};
13use embassy::time::{Duration, Timer}; 13use embassy::time::{Duration, Timer};
14use embassy::util::Forever; 14use embassy::util::Forever;
15use embassy_stm32f4::interrupt::OwnedInterrupt; 15use embassy_stm32f4::interrupt::InterruptExt;
16use embassy_stm32f4::usb::Usb; 16use embassy_stm32f4::usb::Usb;
17use embassy_stm32f4::usb_serial::UsbSerial; 17use embassy_stm32f4::usb_serial::UsbSerial;
18use embassy_stm32f4::{interrupt, pac, rtc}; 18use 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;
11use embassy::executor::{task, Executor}; 11use embassy::executor::{task, Executor};
12use embassy::io::{AsyncBufReadExt, AsyncWriteExt}; 12use embassy::io::{AsyncBufReadExt, AsyncWriteExt};
13use embassy::util::Forever; 13use embassy::util::Forever;
14use embassy_stm32f4::interrupt::OwnedInterrupt; 14use embassy_stm32f4::interrupt::InterruptExt;
15use embassy_stm32f4::usb::Usb; 15use embassy_stm32f4::usb::Usb;
16use embassy_stm32f4::usb_serial::UsbSerial; 16use embassy_stm32f4::usb_serial::UsbSerial;
17use embassy_stm32f4::{interrupt, pac}; 17use 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]
33embassy = { version = "0.1.0", path = "../embassy" } 33embassy = { version = "0.1.0", path = "../embassy" }
34embassy-stm32 = { version = "0.1.0", path = "../embassy-stm32" } 34embassy-stm32 = { version = "0.1.0", path = "../embassy-stm32" }
35embassy-extras = {version = "0.1.0", path = "../embassy-extras" }
36
35defmt = { version = "0.2.0", optional = true } 37defmt = { version = "0.2.0", optional = true }
36log = { version = "0.4.11", optional = true } 38log = { version = "0.4.11", optional = true }
37cortex-m-rt = "0.6.13" 39cortex-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;
318pub mod serial; 318pub mod serial;
319pub mod usb; 319pub mod usb;
320pub mod usb_serial; 320pub mod usb_serial;
321pub mod util;
322 321
323pub(crate) mod cdc_acm; 322pub(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
9use crate::interrupt; 9use crate::interrupt;
10use crate::usb_serial::{ReadInterface, UsbSerial, WriteInterface}; 10use crate::usb_serial::{ReadInterface, UsbSerial, WriteInterface};
11use crate::util::peripheral::{PeripheralMutex, PeripheralState}; 11use embassy_extras::peripheral::{PeripheralMutex, PeripheralState};
12 12
13pub struct State<'bus, B, T> 13pub struct State<'bus, B, T>
14where 14where
@@ -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
12use crate::cdc_acm::CdcAcmClass; 12use crate::cdc_acm::CdcAcmClass;
13use crate::usb::{ClassSet, SerialState, State}; 13use crate::usb::{ClassSet, SerialState, State};
14use crate::util::peripheral::PeripheralMutex; 14use embassy_extras::peripheral::PeripheralMutex;
15use crate::util::ring_buffer::RingBuffer; 15use embassy_extras::ring_buffer::RingBuffer;
16 16
17pub struct ReadInterface<'a, 'bus, 'c, I, B, T> 17pub struct ReadInterface<'a, 'bus, 'c, I, B, T>
18where 18where
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 @@
1pub mod peripheral;
2pub mod ring_buffer;
3
4/// Low power blocking wait loop using WFE/SEV.
5pub 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 @@
1use core::cell::UnsafeCell;
2use core::marker::{PhantomData, PhantomPinned};
3use core::pin::Pin;
4use core::sync::atomic::{compiler_fence, Ordering};
5
6use crate::interrupt::OwnedInterrupt;
7
8pub trait PeripheralState {
9 type Interrupt: OwnedInterrupt;
10 fn on_interrupt(&mut self);
11}
12
13pub struct PeripheralMutex<S: PeripheralState> {
14 inner: Option<(UnsafeCell<S>, S::Interrupt)>,
15 _not_send: PhantomData<*mut ()>,
16 _pinned: PhantomPinned,
17}
18
19impl<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
71impl<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 @@
1use crate::fmt::{assert, *};
2
3pub struct RingBuffer<'a> {
4 buf: &'a mut [u8],
5 start: usize,
6 end: usize,
7 empty: bool,
8}
9
10impl<'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}