mirror of
https://github.com/embassy-rs/embassy.git
synced 2025-10-01 22:30:49 +00:00
BXCAN: Put State inside a critical section mutex of RefCell. This removed unsound code that was giving out mut& to State
This change is equiverlent to f5658d6833cb140296a0b6f25b7eb6d16f06c520 that was already done for the FDCAN driver.
This commit is contained in:
parent
206a324cf4
commit
b2dcdad51d
@ -35,7 +35,9 @@ impl<T: Instance> interrupt::typelevel::Handler<T::TXInterrupt> for TxInterruptH
|
|||||||
v.set_rqcp(1, true);
|
v.set_rqcp(1, true);
|
||||||
v.set_rqcp(2, true);
|
v.set_rqcp(2, true);
|
||||||
});
|
});
|
||||||
T::state().tx_mode.on_interrupt::<T>();
|
T::info().state.lock(|state| {
|
||||||
|
state.borrow().tx_mode.on_interrupt::<T>();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -46,7 +48,9 @@ pub struct Rx0InterruptHandler<T: Instance> {
|
|||||||
|
|
||||||
impl<T: Instance> interrupt::typelevel::Handler<T::RX0Interrupt> for Rx0InterruptHandler<T> {
|
impl<T: Instance> interrupt::typelevel::Handler<T::RX0Interrupt> for Rx0InterruptHandler<T> {
|
||||||
unsafe fn on_interrupt() {
|
unsafe fn on_interrupt() {
|
||||||
T::state().rx_mode.on_interrupt::<T>(RxFifo::Fifo0);
|
T::info().state.lock(|state| {
|
||||||
|
state.borrow().rx_mode.on_interrupt::<T>(RxFifo::Fifo0);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -57,7 +61,9 @@ pub struct Rx1InterruptHandler<T: Instance> {
|
|||||||
|
|
||||||
impl<T: Instance> interrupt::typelevel::Handler<T::RX1Interrupt> for Rx1InterruptHandler<T> {
|
impl<T: Instance> interrupt::typelevel::Handler<T::RX1Interrupt> for Rx1InterruptHandler<T> {
|
||||||
unsafe fn on_interrupt() {
|
unsafe fn on_interrupt() {
|
||||||
T::state().rx_mode.on_interrupt::<T>(RxFifo::Fifo1);
|
T::info().state.lock(|state| {
|
||||||
|
state.borrow().rx_mode.on_interrupt::<T>(RxFifo::Fifo1);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -73,7 +79,9 @@ impl<T: Instance> interrupt::typelevel::Handler<T::SCEInterrupt> for SceInterrup
|
|||||||
|
|
||||||
if msr_val.slaki() {
|
if msr_val.slaki() {
|
||||||
msr.modify(|m| m.set_slaki(true));
|
msr.modify(|m| m.set_slaki(true));
|
||||||
T::state().err_waker.wake();
|
T::info().state.lock(|state| {
|
||||||
|
state.borrow().err_waker.wake();
|
||||||
|
});
|
||||||
} else if msr_val.erri() {
|
} else if msr_val.erri() {
|
||||||
// Disable the interrupt, but don't acknowledge the error, so that it can be
|
// Disable the interrupt, but don't acknowledge the error, so that it can be
|
||||||
// forwarded off the bus message consumer. If we don't provide some way for
|
// forwarded off the bus message consumer. If we don't provide some way for
|
||||||
@ -83,7 +91,9 @@ impl<T: Instance> interrupt::typelevel::Handler<T::SCEInterrupt> for SceInterrup
|
|||||||
let ier = T::regs().ier();
|
let ier = T::regs().ier();
|
||||||
ier.modify(|i| i.set_errie(false));
|
ier.modify(|i| i.set_errie(false));
|
||||||
|
|
||||||
T::state().err_waker.wake();
|
T::info().state.lock(|state| {
|
||||||
|
state.borrow().err_waker.wake();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -157,7 +167,6 @@ impl Drop for CanConfig<'_> {
|
|||||||
pub struct Can<'d> {
|
pub struct Can<'d> {
|
||||||
phantom: PhantomData<&'d ()>,
|
phantom: PhantomData<&'d ()>,
|
||||||
info: &'static Info,
|
info: &'static Info,
|
||||||
state: &'static State,
|
|
||||||
periph_clock: crate::time::Hertz,
|
periph_clock: crate::time::Hertz,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -228,7 +237,6 @@ impl<'d> Can<'d> {
|
|||||||
Self {
|
Self {
|
||||||
phantom: PhantomData,
|
phantom: PhantomData,
|
||||||
info: T::info(),
|
info: T::info(),
|
||||||
state: T::state(),
|
|
||||||
periph_clock: T::frequency(),
|
periph_clock: T::frequency(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -297,7 +305,9 @@ impl<'d> Can<'d> {
|
|||||||
self.info.regs.0.mcr().modify(|m| m.set_sleep(true));
|
self.info.regs.0.mcr().modify(|m| m.set_sleep(true));
|
||||||
|
|
||||||
poll_fn(|cx| {
|
poll_fn(|cx| {
|
||||||
self.state.err_waker.register(cx.waker());
|
self.info.state.lock(|state| {
|
||||||
|
state.borrow().err_waker.register(cx.waker());
|
||||||
|
});
|
||||||
if self.is_sleeping() {
|
if self.is_sleeping() {
|
||||||
Poll::Ready(())
|
Poll::Ready(())
|
||||||
} else {
|
} else {
|
||||||
@ -351,7 +361,6 @@ impl<'d> Can<'d> {
|
|||||||
CanTx {
|
CanTx {
|
||||||
_phantom: PhantomData,
|
_phantom: PhantomData,
|
||||||
info: self.info,
|
info: self.info,
|
||||||
state: self.state,
|
|
||||||
}
|
}
|
||||||
.flush_inner(mb)
|
.flush_inner(mb)
|
||||||
.await;
|
.await;
|
||||||
@ -367,7 +376,6 @@ impl<'d> Can<'d> {
|
|||||||
CanTx {
|
CanTx {
|
||||||
_phantom: PhantomData,
|
_phantom: PhantomData,
|
||||||
info: self.info,
|
info: self.info,
|
||||||
state: self.state,
|
|
||||||
}
|
}
|
||||||
.flush_any_inner()
|
.flush_any_inner()
|
||||||
.await
|
.await
|
||||||
@ -378,7 +386,6 @@ impl<'d> Can<'d> {
|
|||||||
CanTx {
|
CanTx {
|
||||||
_phantom: PhantomData,
|
_phantom: PhantomData,
|
||||||
info: self.info,
|
info: self.info,
|
||||||
state: self.state,
|
|
||||||
}
|
}
|
||||||
.flush_all_inner()
|
.flush_all_inner()
|
||||||
.await
|
.await
|
||||||
@ -406,19 +413,19 @@ impl<'d> Can<'d> {
|
|||||||
///
|
///
|
||||||
/// Returns a tuple of the time the message was received and the message frame
|
/// Returns a tuple of the time the message was received and the message frame
|
||||||
pub async fn read(&mut self) -> Result<Envelope, BusError> {
|
pub async fn read(&mut self) -> Result<Envelope, BusError> {
|
||||||
self.state.rx_mode.read(self.info, self.state).await
|
RxMode::read(self.info).await
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Attempts to read a CAN frame without blocking.
|
/// Attempts to read a CAN frame without blocking.
|
||||||
///
|
///
|
||||||
/// Returns [Err(TryReadError::Empty)] if there are no frames in the rx queue.
|
/// Returns [Err(TryReadError::Empty)] if there are no frames in the rx queue.
|
||||||
pub fn try_read(&mut self) -> Result<Envelope, TryReadError> {
|
pub fn try_read(&mut self) -> Result<Envelope, TryReadError> {
|
||||||
self.state.rx_mode.try_read(self.info)
|
RxMode::try_read(self.info)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Waits while receive queue is empty.
|
/// Waits while receive queue is empty.
|
||||||
pub async fn wait_not_empty(&mut self) {
|
pub async fn wait_not_empty(&mut self) {
|
||||||
self.state.rx_mode.wait_not_empty(self.info, self.state).await
|
RxMode::wait_not_empty(self.info).await
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Split the CAN driver into transmit and receive halves.
|
/// Split the CAN driver into transmit and receive halves.
|
||||||
@ -429,12 +436,10 @@ impl<'d> Can<'d> {
|
|||||||
CanTx {
|
CanTx {
|
||||||
_phantom: PhantomData,
|
_phantom: PhantomData,
|
||||||
info: self.info,
|
info: self.info,
|
||||||
state: self.state,
|
|
||||||
},
|
},
|
||||||
CanRx {
|
CanRx {
|
||||||
_phantom: PhantomData,
|
_phantom: PhantomData,
|
||||||
info: self.info,
|
info: self.info,
|
||||||
state: self.state,
|
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -515,7 +520,6 @@ impl<'d, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize> BufferedCan<'d, TX_
|
|||||||
pub struct CanTx<'d> {
|
pub struct CanTx<'d> {
|
||||||
_phantom: PhantomData<&'d ()>,
|
_phantom: PhantomData<&'d ()>,
|
||||||
info: &'static Info,
|
info: &'static Info,
|
||||||
state: &'static State,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'d> CanTx<'d> {
|
impl<'d> CanTx<'d> {
|
||||||
@ -524,7 +528,9 @@ impl<'d> CanTx<'d> {
|
|||||||
/// If the TX queue is full, this will wait until there is space, therefore exerting backpressure.
|
/// If the TX queue is full, this will wait until there is space, therefore exerting backpressure.
|
||||||
pub async fn write(&mut self, frame: &Frame) -> TransmitStatus {
|
pub async fn write(&mut self, frame: &Frame) -> TransmitStatus {
|
||||||
poll_fn(|cx| {
|
poll_fn(|cx| {
|
||||||
self.state.tx_mode.register(cx.waker());
|
self.info.state.lock(|state| {
|
||||||
|
state.borrow().tx_mode.register(cx.waker());
|
||||||
|
});
|
||||||
if let Ok(status) = self.info.regs.transmit(frame) {
|
if let Ok(status) = self.info.regs.transmit(frame) {
|
||||||
return Poll::Ready(status);
|
return Poll::Ready(status);
|
||||||
}
|
}
|
||||||
@ -549,7 +555,9 @@ impl<'d> CanTx<'d> {
|
|||||||
|
|
||||||
async fn flush_inner(&self, mb: Mailbox) {
|
async fn flush_inner(&self, mb: Mailbox) {
|
||||||
poll_fn(|cx| {
|
poll_fn(|cx| {
|
||||||
self.state.tx_mode.register(cx.waker());
|
self.info.state.lock(|state| {
|
||||||
|
state.borrow().tx_mode.register(cx.waker());
|
||||||
|
});
|
||||||
if self.info.regs.0.tsr().read().tme(mb.index()) {
|
if self.info.regs.0.tsr().read().tme(mb.index()) {
|
||||||
return Poll::Ready(());
|
return Poll::Ready(());
|
||||||
}
|
}
|
||||||
@ -566,7 +574,9 @@ impl<'d> CanTx<'d> {
|
|||||||
|
|
||||||
async fn flush_any_inner(&self) {
|
async fn flush_any_inner(&self) {
|
||||||
poll_fn(|cx| {
|
poll_fn(|cx| {
|
||||||
self.state.tx_mode.register(cx.waker());
|
self.info.state.lock(|state| {
|
||||||
|
state.borrow().tx_mode.register(cx.waker());
|
||||||
|
});
|
||||||
|
|
||||||
let tsr = self.info.regs.0.tsr().read();
|
let tsr = self.info.regs.0.tsr().read();
|
||||||
if tsr.tme(Mailbox::Mailbox0.index())
|
if tsr.tme(Mailbox::Mailbox0.index())
|
||||||
@ -593,7 +603,9 @@ impl<'d> CanTx<'d> {
|
|||||||
|
|
||||||
async fn flush_all_inner(&self) {
|
async fn flush_all_inner(&self) {
|
||||||
poll_fn(|cx| {
|
poll_fn(|cx| {
|
||||||
self.state.tx_mode.register(cx.waker());
|
self.info.state.lock(|state| {
|
||||||
|
state.borrow().tx_mode.register(cx.waker());
|
||||||
|
});
|
||||||
|
|
||||||
let tsr = self.info.regs.0.tsr().read();
|
let tsr = self.info.regs.0.tsr().read();
|
||||||
if tsr.tme(Mailbox::Mailbox0.index())
|
if tsr.tme(Mailbox::Mailbox0.index())
|
||||||
@ -634,7 +646,7 @@ impl<'d> CanTx<'d> {
|
|||||||
self,
|
self,
|
||||||
txb: &'static mut TxBuf<TX_BUF_SIZE>,
|
txb: &'static mut TxBuf<TX_BUF_SIZE>,
|
||||||
) -> BufferedCanTx<'d, TX_BUF_SIZE> {
|
) -> BufferedCanTx<'d, TX_BUF_SIZE> {
|
||||||
BufferedCanTx::new(self.info, self.state, self, txb)
|
BufferedCanTx::new(self.info, self, txb)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -644,33 +656,22 @@ pub type TxBuf<const BUF_SIZE: usize> = Channel<CriticalSectionRawMutex, Frame,
|
|||||||
/// Buffered CAN driver, transmit half.
|
/// Buffered CAN driver, transmit half.
|
||||||
pub struct BufferedCanTx<'d, const TX_BUF_SIZE: usize> {
|
pub struct BufferedCanTx<'d, const TX_BUF_SIZE: usize> {
|
||||||
info: &'static Info,
|
info: &'static Info,
|
||||||
state: &'static State,
|
|
||||||
_tx: CanTx<'d>,
|
_tx: CanTx<'d>,
|
||||||
tx_buf: &'static TxBuf<TX_BUF_SIZE>,
|
tx_buf: &'static TxBuf<TX_BUF_SIZE>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'d, const TX_BUF_SIZE: usize> BufferedCanTx<'d, TX_BUF_SIZE> {
|
impl<'d, const TX_BUF_SIZE: usize> BufferedCanTx<'d, TX_BUF_SIZE> {
|
||||||
fn new(info: &'static Info, state: &'static State, _tx: CanTx<'d>, tx_buf: &'static TxBuf<TX_BUF_SIZE>) -> Self {
|
fn new(info: &'static Info, _tx: CanTx<'d>, tx_buf: &'static TxBuf<TX_BUF_SIZE>) -> Self {
|
||||||
Self {
|
Self { info, _tx, tx_buf }.setup()
|
||||||
info,
|
|
||||||
state,
|
|
||||||
_tx,
|
|
||||||
tx_buf,
|
|
||||||
}
|
|
||||||
.setup()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn setup(self) -> Self {
|
fn setup(self) -> Self {
|
||||||
// We don't want interrupts being processed while we change modes.
|
// We don't want interrupts being processed while we change modes.
|
||||||
critical_section::with(|_| {
|
let tx_inner = super::common::ClassicBufferedTxInner {
|
||||||
let tx_inner = super::common::ClassicBufferedTxInner {
|
tx_receiver: self.tx_buf.receiver().into(),
|
||||||
tx_receiver: self.tx_buf.receiver().into(),
|
};
|
||||||
};
|
self.info.state.lock(|state| {
|
||||||
let state = self.state as *const State;
|
state.borrow_mut().tx_mode = TxMode::Buffered(tx_inner);
|
||||||
unsafe {
|
|
||||||
let mut_state = state as *mut State;
|
|
||||||
(*mut_state).tx_mode = TxMode::Buffered(tx_inner);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
@ -704,7 +705,6 @@ impl<'d, const TX_BUF_SIZE: usize> Drop for BufferedCanTx<'d, TX_BUF_SIZE> {
|
|||||||
pub struct CanRx<'d> {
|
pub struct CanRx<'d> {
|
||||||
_phantom: PhantomData<&'d ()>,
|
_phantom: PhantomData<&'d ()>,
|
||||||
info: &'static Info,
|
info: &'static Info,
|
||||||
state: &'static State,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'d> CanRx<'d> {
|
impl<'d> CanRx<'d> {
|
||||||
@ -714,19 +714,19 @@ impl<'d> CanRx<'d> {
|
|||||||
///
|
///
|
||||||
/// Returns a tuple of the time the message was received and the message frame
|
/// Returns a tuple of the time the message was received and the message frame
|
||||||
pub async fn read(&mut self) -> Result<Envelope, BusError> {
|
pub async fn read(&mut self) -> Result<Envelope, BusError> {
|
||||||
self.state.rx_mode.read(self.info, self.state).await
|
RxMode::read(self.info).await
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Attempts to read a CAN frame without blocking.
|
/// Attempts to read a CAN frame without blocking.
|
||||||
///
|
///
|
||||||
/// Returns [Err(TryReadError::Empty)] if there are no frames in the rx queue.
|
/// Returns [Err(TryReadError::Empty)] if there are no frames in the rx queue.
|
||||||
pub fn try_read(&mut self) -> Result<Envelope, TryReadError> {
|
pub fn try_read(&mut self) -> Result<Envelope, TryReadError> {
|
||||||
self.state.rx_mode.try_read(self.info)
|
RxMode::try_read(self.info)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Waits while receive queue is empty.
|
/// Waits while receive queue is empty.
|
||||||
pub async fn wait_not_empty(&mut self) {
|
pub async fn wait_not_empty(&mut self) {
|
||||||
self.state.rx_mode.wait_not_empty(self.info, self.state).await
|
RxMode::wait_not_empty(self.info).await
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return a buffered instance of driver. User must supply Buffers
|
/// Return a buffered instance of driver. User must supply Buffers
|
||||||
@ -734,7 +734,7 @@ impl<'d> CanRx<'d> {
|
|||||||
self,
|
self,
|
||||||
rxb: &'static mut RxBuf<RX_BUF_SIZE>,
|
rxb: &'static mut RxBuf<RX_BUF_SIZE>,
|
||||||
) -> BufferedCanRx<'d, RX_BUF_SIZE> {
|
) -> BufferedCanRx<'d, RX_BUF_SIZE> {
|
||||||
BufferedCanRx::new(self.info, self.state, self, rxb)
|
BufferedCanRx::new(self.info, self, rxb)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Accesses the filter banks owned by this CAN peripheral.
|
/// Accesses the filter banks owned by this CAN peripheral.
|
||||||
@ -752,33 +752,22 @@ pub type RxBuf<const BUF_SIZE: usize> = Channel<CriticalSectionRawMutex, Result<
|
|||||||
/// CAN driver, receive half in Buffered mode.
|
/// CAN driver, receive half in Buffered mode.
|
||||||
pub struct BufferedCanRx<'d, const RX_BUF_SIZE: usize> {
|
pub struct BufferedCanRx<'d, const RX_BUF_SIZE: usize> {
|
||||||
info: &'static Info,
|
info: &'static Info,
|
||||||
state: &'static State,
|
|
||||||
rx: CanRx<'d>,
|
rx: CanRx<'d>,
|
||||||
rx_buf: &'static RxBuf<RX_BUF_SIZE>,
|
rx_buf: &'static RxBuf<RX_BUF_SIZE>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'d, const RX_BUF_SIZE: usize> BufferedCanRx<'d, RX_BUF_SIZE> {
|
impl<'d, const RX_BUF_SIZE: usize> BufferedCanRx<'d, RX_BUF_SIZE> {
|
||||||
fn new(info: &'static Info, state: &'static State, rx: CanRx<'d>, rx_buf: &'static RxBuf<RX_BUF_SIZE>) -> Self {
|
fn new(info: &'static Info, rx: CanRx<'d>, rx_buf: &'static RxBuf<RX_BUF_SIZE>) -> Self {
|
||||||
BufferedCanRx {
|
BufferedCanRx { info, rx, rx_buf }.setup()
|
||||||
info,
|
|
||||||
state,
|
|
||||||
rx,
|
|
||||||
rx_buf,
|
|
||||||
}
|
|
||||||
.setup()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn setup(self) -> Self {
|
fn setup(self) -> Self {
|
||||||
// We don't want interrupts being processed while we change modes.
|
// We don't want interrupts being processed while we change modes.
|
||||||
critical_section::with(|_| {
|
let rx_inner = super::common::ClassicBufferedRxInner {
|
||||||
let rx_inner = super::common::ClassicBufferedRxInner {
|
rx_sender: self.rx_buf.sender().into(),
|
||||||
rx_sender: self.rx_buf.sender().into(),
|
};
|
||||||
};
|
self.info.state.lock(|state| {
|
||||||
let state = self.state as *const State;
|
state.borrow_mut().rx_mode = RxMode::Buffered(rx_inner);
|
||||||
unsafe {
|
|
||||||
let mut_state = state as *mut State;
|
|
||||||
(*mut_state).rx_mode = RxMode::Buffered(rx_inner);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
@ -792,7 +781,7 @@ impl<'d, const RX_BUF_SIZE: usize> BufferedCanRx<'d, RX_BUF_SIZE> {
|
|||||||
///
|
///
|
||||||
/// Returns [Err(TryReadError::Empty)] if there are no frames in the rx queue.
|
/// Returns [Err(TryReadError::Empty)] if there are no frames in the rx queue.
|
||||||
pub fn try_read(&mut self) -> Result<Envelope, TryReadError> {
|
pub fn try_read(&mut self) -> Result<Envelope, TryReadError> {
|
||||||
match &self.state.rx_mode {
|
self.info.state.lock(|s| match &s.borrow().rx_mode {
|
||||||
RxMode::Buffered(_) => {
|
RxMode::Buffered(_) => {
|
||||||
if let Ok(result) = self.rx_buf.try_receive() {
|
if let Ok(result) = self.rx_buf.try_receive() {
|
||||||
match result {
|
match result {
|
||||||
@ -810,7 +799,7 @@ impl<'d, const RX_BUF_SIZE: usize> BufferedCanRx<'d, RX_BUF_SIZE> {
|
|||||||
_ => {
|
_ => {
|
||||||
panic!("Bad Mode")
|
panic!("Bad Mode")
|
||||||
}
|
}
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Waits while receive queue is empty.
|
/// Waits while receive queue is empty.
|
||||||
@ -929,27 +918,30 @@ impl RxMode {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) async fn read(&self, info: &Info, state: &State) -> Result<Envelope, BusError> {
|
pub(crate) async fn read(info: &Info) -> Result<Envelope, BusError> {
|
||||||
match self {
|
poll_fn(|cx| {
|
||||||
Self::NonBuffered(waker) => {
|
info.state.lock(|state| {
|
||||||
poll_fn(|cx| {
|
let state = state.borrow();
|
||||||
state.err_waker.register(cx.waker());
|
state.err_waker.register(cx.waker());
|
||||||
waker.register(cx.waker());
|
match &state.rx_mode {
|
||||||
match self.try_read(info) {
|
Self::NonBuffered(waker) => {
|
||||||
Ok(result) => Poll::Ready(Ok(result)),
|
waker.register(cx.waker());
|
||||||
Err(TryReadError::Empty) => Poll::Pending,
|
|
||||||
Err(TryReadError::BusError(be)) => Poll::Ready(Err(be)),
|
|
||||||
}
|
}
|
||||||
})
|
_ => {
|
||||||
.await
|
panic!("Bad Mode")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
match RxMode::try_read(info) {
|
||||||
|
Ok(result) => Poll::Ready(Ok(result)),
|
||||||
|
Err(TryReadError::Empty) => Poll::Pending,
|
||||||
|
Err(TryReadError::BusError(be)) => Poll::Ready(Err(be)),
|
||||||
}
|
}
|
||||||
_ => {
|
})
|
||||||
panic!("Bad Mode")
|
.await
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
pub(crate) fn try_read(&self, info: &Info) -> Result<Envelope, TryReadError> {
|
pub(crate) fn try_read(info: &Info) -> Result<Envelope, TryReadError> {
|
||||||
match self {
|
info.state.lock(|state| match state.borrow().rx_mode {
|
||||||
Self::NonBuffered(_) => {
|
Self::NonBuffered(_) => {
|
||||||
let registers = &info.regs;
|
let registers = &info.regs;
|
||||||
if let Some(msg) = registers.receive_fifo(RxFifo::Fifo0) {
|
if let Some(msg) = registers.receive_fifo(RxFifo::Fifo0) {
|
||||||
@ -975,25 +967,28 @@ impl RxMode {
|
|||||||
_ => {
|
_ => {
|
||||||
panic!("Bad Mode")
|
panic!("Bad Mode")
|
||||||
}
|
}
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
pub(crate) async fn wait_not_empty(&self, info: &Info, state: &State) {
|
pub(crate) async fn wait_not_empty(info: &Info) {
|
||||||
match &state.rx_mode {
|
poll_fn(|cx| {
|
||||||
Self::NonBuffered(waker) => {
|
info.state.lock(|s| {
|
||||||
poll_fn(|cx| {
|
let state = s.borrow();
|
||||||
waker.register(cx.waker());
|
match &state.rx_mode {
|
||||||
if info.regs.receive_frame_available() {
|
Self::NonBuffered(waker) => {
|
||||||
Poll::Ready(())
|
waker.register(cx.waker());
|
||||||
} else {
|
|
||||||
Poll::Pending
|
|
||||||
}
|
}
|
||||||
})
|
_ => {
|
||||||
.await
|
panic!("Bad Mode")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if info.regs.receive_frame_available() {
|
||||||
|
Poll::Ready(())
|
||||||
|
} else {
|
||||||
|
Poll::Pending
|
||||||
}
|
}
|
||||||
_ => {
|
})
|
||||||
panic!("Bad Mode")
|
.await
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1008,21 +1003,24 @@ impl TxMode {
|
|||||||
tsr.tme(Mailbox::Mailbox0.index()) || tsr.tme(Mailbox::Mailbox1.index()) || tsr.tme(Mailbox::Mailbox2.index())
|
tsr.tme(Mailbox::Mailbox0.index()) || tsr.tme(Mailbox::Mailbox1.index()) || tsr.tme(Mailbox::Mailbox2.index())
|
||||||
}
|
}
|
||||||
pub fn on_interrupt<T: Instance>(&self) {
|
pub fn on_interrupt<T: Instance>(&self) {
|
||||||
match &T::state().tx_mode {
|
T::info().state.lock(|state| {
|
||||||
TxMode::NonBuffered(waker) => waker.wake(),
|
let tx_mode = &state.borrow().tx_mode;
|
||||||
TxMode::Buffered(buf) => {
|
match tx_mode {
|
||||||
while self.buffer_free::<T>() {
|
TxMode::NonBuffered(waker) => waker.wake(),
|
||||||
match buf.tx_receiver.try_receive() {
|
TxMode::Buffered(buf) => {
|
||||||
Ok(frame) => {
|
while self.buffer_free::<T>() {
|
||||||
_ = Registers(T::regs()).transmit(&frame);
|
match buf.tx_receiver.try_receive() {
|
||||||
}
|
Ok(frame) => {
|
||||||
Err(_) => {
|
_ = Registers(T::regs()).transmit(&frame);
|
||||||
break;
|
}
|
||||||
|
Err(_) => {
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn register(&self, arg: &core::task::Waker) {
|
fn register(&self, arg: &core::task::Waker) {
|
||||||
@ -1057,6 +1055,7 @@ impl State {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type SharedState = embassy_sync::blocking_mutex::Mutex<CriticalSectionRawMutex, core::cell::RefCell<State>>;
|
||||||
pub(crate) struct Info {
|
pub(crate) struct Info {
|
||||||
regs: Registers,
|
regs: Registers,
|
||||||
tx_interrupt: crate::interrupt::Interrupt,
|
tx_interrupt: crate::interrupt::Interrupt,
|
||||||
@ -1065,6 +1064,7 @@ pub(crate) struct Info {
|
|||||||
sce_interrupt: crate::interrupt::Interrupt,
|
sce_interrupt: crate::interrupt::Interrupt,
|
||||||
tx_waker: fn(),
|
tx_waker: fn(),
|
||||||
internal_operation: fn(InternalOperation),
|
internal_operation: fn(InternalOperation),
|
||||||
|
state: SharedState,
|
||||||
|
|
||||||
/// The total number of filter banks available to the instance.
|
/// The total number of filter banks available to the instance.
|
||||||
///
|
///
|
||||||
@ -1075,8 +1075,6 @@ pub(crate) struct Info {
|
|||||||
trait SealedInstance {
|
trait SealedInstance {
|
||||||
fn info() -> &'static Info;
|
fn info() -> &'static Info;
|
||||||
fn regs() -> crate::pac::can::Can;
|
fn regs() -> crate::pac::can::Can;
|
||||||
fn state() -> &'static State;
|
|
||||||
unsafe fn mut_state() -> &'static mut State;
|
|
||||||
fn internal_operation(val: InternalOperation);
|
fn internal_operation(val: InternalOperation);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1136,6 +1134,7 @@ foreach_peripheral!(
|
|||||||
sce_interrupt: crate::_generated::peripheral_interrupts::$inst::SCE::IRQ,
|
sce_interrupt: crate::_generated::peripheral_interrupts::$inst::SCE::IRQ,
|
||||||
tx_waker: crate::_generated::peripheral_interrupts::$inst::TX::pend,
|
tx_waker: crate::_generated::peripheral_interrupts::$inst::TX::pend,
|
||||||
internal_operation: peripherals::$inst::internal_operation,
|
internal_operation: peripherals::$inst::internal_operation,
|
||||||
|
state: embassy_sync::blocking_mutex::Mutex::new(core::cell::RefCell::new(State::new())),
|
||||||
num_filter_banks: peripherals::$inst::NUM_FILTER_BANKS,
|
num_filter_banks: peripherals::$inst::NUM_FILTER_BANKS,
|
||||||
};
|
};
|
||||||
&INFO
|
&INFO
|
||||||
@ -1144,21 +1143,10 @@ foreach_peripheral!(
|
|||||||
crate::pac::$inst
|
crate::pac::$inst
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe fn mut_state() -> & 'static mut State {
|
|
||||||
static mut STATE: State = State::new();
|
|
||||||
&mut *core::ptr::addr_of_mut!(STATE)
|
|
||||||
}
|
|
||||||
fn state() -> &'static State {
|
|
||||||
unsafe { peripherals::$inst::mut_state() }
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
fn internal_operation(val: InternalOperation) {
|
fn internal_operation(val: InternalOperation) {
|
||||||
critical_section::with(|_| {
|
peripherals::$inst::info().state.lock(|s| {
|
||||||
//let state = self.state as *const State;
|
let mut mut_state = s.borrow_mut();
|
||||||
unsafe {
|
|
||||||
//let mut_state = state as *mut State;
|
//let mut_state = state as *mut State;
|
||||||
let mut_state = peripherals::$inst::mut_state();
|
|
||||||
match val {
|
match val {
|
||||||
InternalOperation::NotifySenderCreated => {
|
InternalOperation::NotifySenderCreated => {
|
||||||
mut_state.sender_instance_count += 1;
|
mut_state.sender_instance_count += 1;
|
||||||
@ -1179,11 +1167,9 @@ foreach_peripheral!(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Instance for peripherals::$inst {
|
impl Instance for peripherals::$inst {
|
||||||
type TXInterrupt = crate::_generated::peripheral_interrupts::$inst::TX;
|
type TXInterrupt = crate::_generated::peripheral_interrupts::$inst::TX;
|
||||||
type RX0Interrupt = crate::_generated::peripheral_interrupts::$inst::RX0;
|
type RX0Interrupt = crate::_generated::peripheral_interrupts::$inst::RX0;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user