aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--embassy-stm32/src/usb/usb.rs66
1 files changed, 33 insertions, 33 deletions
diff --git a/embassy-stm32/src/usb/usb.rs b/embassy-stm32/src/usb/usb.rs
index 460abfe28..cba4915c1 100644
--- a/embassy-stm32/src/usb/usb.rs
+++ b/embassy-stm32/src/usb/usb.rs
@@ -2,10 +2,9 @@
2 2
3use core::future::poll_fn; 3use core::future::poll_fn;
4use core::marker::PhantomData; 4use core::marker::PhantomData;
5use core::sync::atomic::Ordering; 5use core::sync::atomic::{AtomicBool, Ordering};
6use core::task::Poll; 6use core::task::Poll;
7 7
8use atomic_polyfill::{AtomicBool, AtomicU8};
9use embassy_hal_common::into_ref; 8use embassy_hal_common::into_ref;
10use embassy_sync::waitqueue::AtomicWaker; 9use embassy_sync::waitqueue::AtomicWaker;
11use embassy_time::{block_for, Duration}; 10use embassy_time::{block_for, Duration};
@@ -35,10 +34,9 @@ static BUS_WAKER: AtomicWaker = NEW_AW;
35static EP0_SETUP: AtomicBool = AtomicBool::new(false); 34static EP0_SETUP: AtomicBool = AtomicBool::new(false);
36static EP_IN_WAKERS: [AtomicWaker; EP_COUNT] = [NEW_AW; EP_COUNT]; 35static EP_IN_WAKERS: [AtomicWaker; EP_COUNT] = [NEW_AW; EP_COUNT];
37static EP_OUT_WAKERS: [AtomicWaker; EP_COUNT] = [NEW_AW; EP_COUNT]; 36static EP_OUT_WAKERS: [AtomicWaker; EP_COUNT] = [NEW_AW; EP_COUNT];
38static IRQ_FLAGS: AtomicU8 = AtomicU8::new(0); 37static IRQ_RESET: AtomicBool = AtomicBool::new(false);
39const IRQ_FLAG_RESET: u8 = 0x01; 38static IRQ_SUSPEND: AtomicBool = AtomicBool::new(false);
40const IRQ_FLAG_SUSPEND: u8 = 0x02; 39static IRQ_RESUME: AtomicBool = AtomicBool::new(false);
41const IRQ_FLAG_RESUME: u8 = 0x04;
42 40
43fn convert_type(t: EndpointType) -> EpType { 41fn convert_type(t: EndpointType) -> EpType {
44 match t { 42 match t {
@@ -184,47 +182,51 @@ impl<'d, T: Instance> Driver<'d, T> {
184 182
185 let istr = regs.istr().read(); 183 let istr = regs.istr().read();
186 184
187 let mut flags: u8 = 0;
188
189 if istr.susp() { 185 if istr.susp() {
190 //trace!("USB IRQ: susp"); 186 //trace!("USB IRQ: susp");
191 flags |= IRQ_FLAG_SUSPEND; 187 IRQ_SUSPEND.store(true, Ordering::Relaxed);
192 regs.cntr().modify(|w| { 188 regs.cntr().modify(|w| {
193 w.set_fsusp(true); 189 w.set_fsusp(true);
194 w.set_lpmode(true); 190 w.set_lpmode(true);
195 }) 191 });
192
193 // Write 0 to clear.
194 let mut clear = regs::Istr(!0);
195 clear.set_susp(false);
196 regs.istr().write_value(clear);
197
198 // Wake main thread.
199 BUS_WAKER.wake();
196 } 200 }
197 201
198 if istr.wkup() { 202 if istr.wkup() {
199 //trace!("USB IRQ: wkup"); 203 //trace!("USB IRQ: wkup");
200 flags |= IRQ_FLAG_RESUME; 204 IRQ_RESUME.store(true, Ordering::Relaxed);
201 regs.cntr().modify(|w| { 205 regs.cntr().modify(|w| {
202 w.set_fsusp(false); 206 w.set_fsusp(false);
203 w.set_lpmode(false); 207 w.set_lpmode(false);
204 }) 208 });
209
210 // Write 0 to clear.
211 let mut clear = regs::Istr(!0);
212 clear.set_wkup(false);
213 regs.istr().write_value(clear);
214
215 // Wake main thread.
216 BUS_WAKER.wake();
205 } 217 }
206 218
207 if istr.reset() { 219 if istr.reset() {
208 //trace!("USB IRQ: reset"); 220 //trace!("USB IRQ: reset");
209 flags |= IRQ_FLAG_RESET; 221 IRQ_RESET.store(true, Ordering::Relaxed);
210 222
211 // Write 0 to clear. 223 // Write 0 to clear.
212 let mut clear = regs::Istr(!0); 224 let mut clear = regs::Istr(!0);
213 clear.set_reset(false); 225 clear.set_reset(false);
214 regs.istr().write_value(clear); 226 regs.istr().write_value(clear);
215 }
216 227
217 if flags != 0 { 228 // Wake main thread.
218 // Send irqs to main thread.
219 IRQ_FLAGS.fetch_or(flags, Ordering::AcqRel);
220 BUS_WAKER.wake(); 229 BUS_WAKER.wake();
221
222 // Clear them
223 let mut mask = regs::Istr(0);
224 mask.set_wkup(true);
225 mask.set_susp(true);
226 mask.set_reset(true);
227 regs.istr().write_value(regs::Istr(!(istr.0 & mask.0)));
228 } 230 }
229 231
230 if istr.ctr() { 232 if istr.ctr() {
@@ -436,17 +438,15 @@ impl<'d, T: Instance> driver::Bus for Bus<'d, T> {
436 if self.inited { 438 if self.inited {
437 let regs = T::regs(); 439 let regs = T::regs();
438 440
439 let flags = IRQ_FLAGS.load(Ordering::Acquire); 441 if IRQ_RESUME.load(Ordering::Acquire) {
440 442 IRQ_RESUME.store(false, Ordering::Relaxed);
441 if flags & IRQ_FLAG_RESUME != 0 {
442 IRQ_FLAGS.fetch_and(!IRQ_FLAG_RESUME, Ordering::AcqRel);
443 return Poll::Ready(Event::Resume); 443 return Poll::Ready(Event::Resume);
444 } 444 }
445 445
446 if flags & IRQ_FLAG_RESET != 0 { 446 if IRQ_RESET.load(Ordering::Acquire) {
447 IRQ_FLAGS.fetch_and(!IRQ_FLAG_RESET, Ordering::AcqRel); 447 IRQ_RESET.store(false, Ordering::Relaxed);
448 448
449 trace!("RESET REGS WRITINGINGING"); 449 trace!("RESET");
450 regs.daddr().write(|w| { 450 regs.daddr().write(|w| {
451 w.set_ef(true); 451 w.set_ef(true);
452 w.set_add(0); 452 w.set_add(0);
@@ -475,8 +475,8 @@ impl<'d, T: Instance> driver::Bus for Bus<'d, T> {
475 return Poll::Ready(Event::Reset); 475 return Poll::Ready(Event::Reset);
476 } 476 }
477 477
478 if flags & IRQ_FLAG_SUSPEND != 0 { 478 if IRQ_SUSPEND.load(Ordering::Acquire) {
479 IRQ_FLAGS.fetch_and(!IRQ_FLAG_SUSPEND, Ordering::AcqRel); 479 IRQ_SUSPEND.store(false, Ordering::Relaxed);
480 return Poll::Ready(Event::Suspend); 480 return Poll::Ready(Event::Suspend);
481 } 481 }
482 482