hal-common: remove Pin in PeripheralMutex

This commit is contained in:
Dario Nieuwenhuis
2021-07-29 14:08:32 +02:00
parent de207764ae
commit af87031d62
7 changed files with 171 additions and 197 deletions

View File

@ -9,14 +9,31 @@ use usb_device::device::UsbDevice;
mod cdc_acm;
pub mod usb_serial;
use crate::peripheral::{PeripheralMutex, PeripheralState};
use crate::peripheral::{PeripheralMutex, PeripheralState, StateStorage};
use embassy::interrupt::Interrupt;
use usb_serial::{ReadInterface, UsbSerial, WriteInterface};
/// Marker trait to mark an interrupt to be used with the [`Usb`] abstraction.
pub unsafe trait USBInterrupt: Interrupt + Send {}
pub(crate) struct State<'bus, B, T, I>
pub struct State<'bus, B, T, I>(StateStorage<StateInner<'bus, B, T, I>>)
where
B: UsbBus,
T: ClassSet<B>,
I: USBInterrupt;
impl<'bus, B, T, I> State<'bus, B, T, I>
where
B: UsbBus,
T: ClassSet<B>,
I: USBInterrupt,
{
pub fn new() -> Self {
Self(StateStorage::new())
}
}
pub(crate) struct StateInner<'bus, B, T, I>
where
B: UsbBus,
T: ClassSet<B>,
@ -34,7 +51,7 @@ where
I: USBInterrupt,
{
// Don't you dare moving out `PeripheralMutex`
inner: RefCell<PeripheralMutex<State<'bus, B, T, I>>>,
inner: RefCell<PeripheralMutex<'bus, StateInner<'bus, B, T, I>>>,
}
impl<'bus, B, T, I> Usb<'bus, B, T, I>
@ -43,30 +60,22 @@ where
T: ClassSet<B>,
I: USBInterrupt,
{
pub fn new<S: IntoClassSet<B, T>>(device: UsbDevice<'bus, B>, class_set: S, irq: I) -> Self {
let state = State {
pub fn new<S: IntoClassSet<B, T>>(
state: &'bus mut State<'bus, B, T, I>,
device: UsbDevice<'bus, B>,
class_set: S,
irq: I,
) -> Self {
let initial_state = StateInner {
device,
classes: class_set.into_class_set(),
_interrupt: PhantomData,
};
let mutex = PeripheralMutex::new(state, irq);
let mutex = unsafe { PeripheralMutex::new_unchecked(&mut state.0, initial_state, irq) };
Self {
inner: RefCell::new(mutex),
}
}
/// # Safety
/// The `UsbDevice` passed to `Self::new` must not be dropped without calling `Drop` on this `Usb` first.
pub unsafe fn start(self: Pin<&mut Self>) {
let this = self.get_unchecked_mut();
let mut mutex = this.inner.borrow_mut();
let mutex = Pin::new_unchecked(&mut *mutex);
// Use inner to register the irq
// SAFETY: the safety contract of this function makes sure the `UsbDevice` won't be invalidated
// without the `PeripheralMutex` being dropped.
mutex.register_interrupt_unchecked();
}
}
impl<'bus, 'c, B, T, I> Usb<'bus, B, T, I>
@ -129,7 +138,7 @@ where
}
}
impl<'bus, B, T, I> PeripheralState for State<'bus, B, T, I>
impl<'bus, B, T, I> PeripheralState for StateInner<'bus, B, T, I>
where
B: UsbBus,
T: ClassSet<B>,

View File

@ -10,9 +10,10 @@ use usb_device::class_prelude::*;
use usb_device::UsbError;
use super::cdc_acm::CdcAcmClass;
use super::StateInner;
use crate::peripheral::PeripheralMutex;
use crate::ring_buffer::RingBuffer;
use crate::usb::{ClassSet, SerialState, State, USBInterrupt};
use crate::usb::{ClassSet, SerialState, USBInterrupt};
pub struct ReadInterface<'a, 'bus, 'c, I, B, T, INT>
where
@ -22,7 +23,7 @@ where
INT: USBInterrupt,
{
// Don't you dare moving out `PeripheralMutex`
pub(crate) inner: &'a RefCell<PeripheralMutex<State<'bus, B, T, INT>>>,
pub(crate) inner: &'a RefCell<PeripheralMutex<'bus, StateInner<'bus, B, T, INT>>>,
pub(crate) _buf_lifetime: PhantomData<&'c T>,
pub(crate) _index: PhantomData<I>,
}
@ -39,7 +40,7 @@ where
INT: USBInterrupt,
{
// Don't you dare moving out `PeripheralMutex`
pub(crate) inner: &'a RefCell<PeripheralMutex<State<'bus, B, T, INT>>>,
pub(crate) inner: &'a RefCell<PeripheralMutex<'bus, StateInner<'bus, B, T, INT>>>,
pub(crate) _buf_lifetime: PhantomData<&'c T>,
pub(crate) _index: PhantomData<I>,
}
@ -54,7 +55,6 @@ where
fn poll_fill_buf(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<&[u8]>> {
let this = self.get_mut();
let mut mutex = this.inner.borrow_mut();
let mutex = unsafe { Pin::new_unchecked(&mut *mutex) };
mutex.with(|state| {
let serial = state.classes.get_serial();
let serial = Pin::new(serial);
@ -76,7 +76,6 @@ where
fn consume(self: Pin<&mut Self>, amt: usize) {
let this = self.get_mut();
let mut mutex = this.inner.borrow_mut();
let mutex = unsafe { Pin::new_unchecked(&mut *mutex) };
mutex.with(|state| {
let serial = state.classes.get_serial();
let serial = Pin::new(serial);
@ -100,7 +99,6 @@ where
) -> Poll<io::Result<usize>> {
let this = self.get_mut();
let mut mutex = this.inner.borrow_mut();
let mutex = unsafe { Pin::new_unchecked(&mut *mutex) };
mutex.with(|state| {
let serial = state.classes.get_serial();
let serial = Pin::new(serial);