aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--embassy-hal-common/src/peripheral.rs18
-rw-r--r--embassy-hal-common/src/usb/mod.rs5
-rw-r--r--embassy-nrf/src/buffered_uarte.rs30
-rw-r--r--embassy-stm32/src/eth/v2/mod.rs4
4 files changed, 28 insertions, 29 deletions
diff --git a/embassy-hal-common/src/peripheral.rs b/embassy-hal-common/src/peripheral.rs
index 46c6ebeee..dcf9d3a27 100644
--- a/embassy-hal-common/src/peripheral.rs
+++ b/embassy-hal-common/src/peripheral.rs
@@ -50,19 +50,23 @@ pub(crate) fn can_be_preempted(irq: &impl Interrupt) -> bool {
50} 50}
51 51
52impl<'a, S: PeripheralState> PeripheralMutex<'a, S> { 52impl<'a, S: PeripheralState> PeripheralMutex<'a, S> {
53 /// Create a new `PeripheralMutex` wrapping `irq`, with the initial state `state`. 53 /// Create a new `PeripheralMutex` wrapping `irq`, with `init` initializing the initial state.
54 /// 54 ///
55 /// self requires `state` to live for `'static`, because if the `PeripheralMutex` is leaked, the 55 /// self requires `S` to live for `'static`, because if the `PeripheralMutex` is leaked, the
56 /// interrupt won't be disabled, which may try accessing the state at any time. To use non-`'static` 56 /// interrupt won't be disabled, which may try accessing the state at any time. To use non-`'static`
57 /// state, see [`Self::new_unchecked`]. 57 /// state, see [`Self::new_unchecked`].
58 /// 58 ///
59 /// Registers `on_interrupt` as the `irq`'s handler, and enables it. 59 /// Registers `on_interrupt` as the `irq`'s handler, and enables it.
60 pub fn new(storage: &'a mut StateStorage<S>, state: S, irq: S::Interrupt) -> Self 60 pub fn new(
61 irq: S::Interrupt,
62 storage: &'a mut StateStorage<S>,
63 init: impl FnOnce() -> S,
64 ) -> Self
61 where 65 where
62 'a: 'static, 66 'a: 'static,
63 { 67 {
64 // safety: safe because state is `'static`. 68 // safety: safe because state is `'static`.
65 unsafe { Self::new_unchecked(storage, state, irq) } 69 unsafe { Self::new_unchecked(irq, storage, init) }
66 } 70 }
67 71
68 /// Create a `PeripheralMutex` without requiring the state is `'static`. 72 /// Create a `PeripheralMutex` without requiring the state is `'static`.
@@ -72,9 +76,9 @@ impl<'a, S: PeripheralState> PeripheralMutex<'a, S> {
72 /// # Safety 76 /// # Safety
73 /// The created instance must not be leaked (its `drop` must run). 77 /// The created instance must not be leaked (its `drop` must run).
74 pub unsafe fn new_unchecked( 78 pub unsafe fn new_unchecked(
75 storage: &'a mut StateStorage<S>,
76 state: S,
77 irq: S::Interrupt, 79 irq: S::Interrupt,
80 storage: &'a mut StateStorage<S>,
81 init: impl FnOnce() -> S,
78 ) -> Self { 82 ) -> Self {
79 if can_be_preempted(&irq) { 83 if can_be_preempted(&irq) {
80 panic!("`PeripheralMutex` cannot be created in an interrupt with higher priority than the interrupt it wraps"); 84 panic!("`PeripheralMutex` cannot be created in an interrupt with higher priority than the interrupt it wraps");
@@ -84,7 +88,7 @@ impl<'a, S: PeripheralState> PeripheralMutex<'a, S> {
84 88
85 // Safety: The pointer is valid and not used by anyone else 89 // Safety: The pointer is valid and not used by anyone else
86 // because we have the `&mut StateStorage`. 90 // because we have the `&mut StateStorage`.
87 state_ptr.write(state); 91 state_ptr.write(init());
88 92
89 irq.disable(); 93 irq.disable();
90 irq.set_handler(|p| { 94 irq.set_handler(|p| {
diff --git a/embassy-hal-common/src/usb/mod.rs b/embassy-hal-common/src/usb/mod.rs
index ae9f26075..70a74bd52 100644
--- a/embassy-hal-common/src/usb/mod.rs
+++ b/embassy-hal-common/src/usb/mod.rs
@@ -67,12 +67,11 @@ where
67 class_set: S, 67 class_set: S,
68 irq: I, 68 irq: I,
69 ) -> Self { 69 ) -> Self {
70 let initial_state = StateInner { 70 let mutex = PeripheralMutex::new_unchecked(irq, &mut state.0, || StateInner {
71 device, 71 device,
72 classes: class_set.into_class_set(), 72 classes: class_set.into_class_set(),
73 _interrupt: PhantomData, 73 _interrupt: PhantomData,
74 }; 74 });
75 let mutex = PeripheralMutex::new_unchecked(&mut state.0, initial_state, irq);
76 Self { 75 Self {
77 inner: RefCell::new(mutex), 76 inner: RefCell::new(mutex),
78 } 77 }
diff --git a/embassy-nrf/src/buffered_uarte.rs b/embassy-nrf/src/buffered_uarte.rs
index 642c30185..048c36d39 100644
--- a/embassy-nrf/src/buffered_uarte.rs
+++ b/embassy-nrf/src/buffered_uarte.rs
@@ -155,23 +155,21 @@ impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarte<'d, U, T> {
155 ppi_ch2.set_task(Task::from_reg(&r.tasks_stoprx)); 155 ppi_ch2.set_task(Task::from_reg(&r.tasks_stoprx));
156 ppi_ch2.enable(); 156 ppi_ch2.enable();
157 157
158 let initial_state = StateInner {
159 phantom: PhantomData,
160 timer,
161 _ppi_ch1: ppi_ch1,
162 _ppi_ch2: ppi_ch2,
163
164 rx: RingBuffer::new(rx_buffer),
165 rx_state: RxState::Idle,
166 rx_waker: WakerRegistration::new(),
167
168 tx: RingBuffer::new(tx_buffer),
169 tx_state: TxState::Idle,
170 tx_waker: WakerRegistration::new(),
171 };
172
173 Self { 158 Self {
174 inner: PeripheralMutex::new_unchecked(&mut state.0, initial_state, irq), 159 inner: PeripheralMutex::new_unchecked(irq, &mut state.0, move || StateInner {
160 phantom: PhantomData,
161 timer,
162 _ppi_ch1: ppi_ch1,
163 _ppi_ch2: ppi_ch2,
164
165 rx: RingBuffer::new(rx_buffer),
166 rx_state: RxState::Idle,
167 rx_waker: WakerRegistration::new(),
168
169 tx: RingBuffer::new(tx_buffer),
170 tx_state: TxState::Idle,
171 tx_waker: WakerRegistration::new(),
172 }),
175 } 173 }
176 } 174 }
177 175
diff --git a/embassy-stm32/src/eth/v2/mod.rs b/embassy-stm32/src/eth/v2/mod.rs
index cfb461ab3..c1956aa16 100644
--- a/embassy-stm32/src/eth/v2/mod.rs
+++ b/embassy-stm32/src/eth/v2/mod.rs
@@ -78,10 +78,8 @@ impl<'d, P: PHY, const TX: usize, const RX: usize> Ethernet<'d, P, TX, RX> {
78 tx_d1.configure(); 78 tx_d1.configure();
79 tx_en.configure(); 79 tx_en.configure();
80 80
81 let inner = Inner::new(peri);
82
83 // NOTE(unsafe) We are ourselves not leak-safe. 81 // NOTE(unsafe) We are ourselves not leak-safe.
84 let state = PeripheralMutex::new_unchecked(&mut state.0, inner, interrupt); 82 let state = PeripheralMutex::new_unchecked(interrupt, &mut state.0, || Inner::new(peri));
85 83
86 // NOTE(unsafe) We have exclusive access to the registers 84 // NOTE(unsafe) We have exclusive access to the registers
87 let dma = ETH.ethernet_dma(); 85 let dma = ETH.ethernet_dma();