USB: Use updated PeripheralMutex
This commit is contained in:
		
							parent
							
								
									a39dea4d98
								
							
						
					
					
						commit
						615bb33dcb
					
				| @ -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() { | ||||
|  | ||||
| @ -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))] | ||||
|  | ||||
| @ -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}; | ||||
|  | ||||
| @ -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}; | ||||
|  | ||||
| @ -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" | ||||
|  | ||||
| @ -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; | ||||
| 
 | ||||
|  | ||||
| @ -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<S: IntoClassSet<B, T>>( | ||||
|         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<B>, | ||||
| { | ||||
|     type Interrupt = interrupt::OTG_FSInterrupt; | ||||
|     type Interrupt = interrupt::OTG_FS; | ||||
|     fn on_interrupt(&mut self) { | ||||
|         self.classes.poll_all(&mut self.device); | ||||
|     } | ||||
|  | ||||
| @ -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 | ||||
|  | ||||
| @ -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(); | ||||
| } | ||||
| @ -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<S: PeripheralState> { | ||||
|     inner: Option<(UnsafeCell<S>, S::Interrupt)>, | ||||
|     _not_send: PhantomData<*mut ()>, | ||||
|     _pinned: PhantomPinned, | ||||
| } | ||||
| 
 | ||||
| impl<S: PeripheralState> PeripheralMutex<S> { | ||||
|     pub fn new(state: S, irq: S::Interrupt) -> Self { | ||||
|         Self { | ||||
|             inner: Some((UnsafeCell::new(state), irq)), | ||||
|             _not_send: PhantomData, | ||||
|             _pinned: PhantomPinned, | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     pub fn with<R>(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<S: PeripheralState> Drop for PeripheralMutex<S> { | ||||
|     fn drop(&mut self) { | ||||
|         if let Some((_state, irq)) = &mut self.inner { | ||||
|             irq.disable(); | ||||
|             irq.remove_handler(); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @ -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 | ||||
|         } | ||||
|     } | ||||
| } | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user