diff options
| author | Corey Schuhen <[email protected]> | 2025-06-21 11:58:53 +1000 |
|---|---|---|
| committer | Corey Schuhen <[email protected]> | 2025-06-21 11:58:53 +1000 |
| commit | b2dcdad51db528e1242ef7ea6028341339a9d488 (patch) | |
| tree | c04e9d79d2a0d554fd6e280eed3e284c152f1e53 /embassy-stm32 | |
| parent | 206a324cf4d612122356fb350b4a3b56391d6f20 (diff) | |
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.
Diffstat (limited to 'embassy-stm32')
| -rw-r--r-- | embassy-stm32/src/can/bxcan/mod.rs | 240 |
1 files changed, 113 insertions, 127 deletions
diff --git a/embassy-stm32/src/can/bxcan/mod.rs b/embassy-stm32/src/can/bxcan/mod.rs index 305666d5b..e2d1c8182 100644 --- a/embassy-stm32/src/can/bxcan/mod.rs +++ b/embassy-stm32/src/can/bxcan/mod.rs | |||
| @@ -35,7 +35,9 @@ impl<T: Instance> interrupt::typelevel::Handler<T::TXInterrupt> for TxInterruptH | |||
| 35 | v.set_rqcp(1, true); | 35 | v.set_rqcp(1, true); |
| 36 | v.set_rqcp(2, true); | 36 | v.set_rqcp(2, true); |
| 37 | }); | 37 | }); |
| 38 | T::state().tx_mode.on_interrupt::<T>(); | 38 | T::info().state.lock(|state| { |
| 39 | state.borrow().tx_mode.on_interrupt::<T>(); | ||
| 40 | }); | ||
| 39 | } | 41 | } |
| 40 | } | 42 | } |
| 41 | 43 | ||
| @@ -46,7 +48,9 @@ pub struct Rx0InterruptHandler<T: Instance> { | |||
| 46 | 48 | ||
| 47 | impl<T: Instance> interrupt::typelevel::Handler<T::RX0Interrupt> for Rx0InterruptHandler<T> { | 49 | impl<T: Instance> interrupt::typelevel::Handler<T::RX0Interrupt> for Rx0InterruptHandler<T> { |
| 48 | unsafe fn on_interrupt() { | 50 | unsafe fn on_interrupt() { |
| 49 | T::state().rx_mode.on_interrupt::<T>(RxFifo::Fifo0); | 51 | T::info().state.lock(|state| { |
| 52 | state.borrow().rx_mode.on_interrupt::<T>(RxFifo::Fifo0); | ||
| 53 | }); | ||
| 50 | } | 54 | } |
| 51 | } | 55 | } |
| 52 | 56 | ||
| @@ -57,7 +61,9 @@ pub struct Rx1InterruptHandler<T: Instance> { | |||
| 57 | 61 | ||
| 58 | impl<T: Instance> interrupt::typelevel::Handler<T::RX1Interrupt> for Rx1InterruptHandler<T> { | 62 | impl<T: Instance> interrupt::typelevel::Handler<T::RX1Interrupt> for Rx1InterruptHandler<T> { |
| 59 | unsafe fn on_interrupt() { | 63 | unsafe fn on_interrupt() { |
| 60 | T::state().rx_mode.on_interrupt::<T>(RxFifo::Fifo1); | 64 | T::info().state.lock(|state| { |
| 65 | state.borrow().rx_mode.on_interrupt::<T>(RxFifo::Fifo1); | ||
| 66 | }); | ||
| 61 | } | 67 | } |
| 62 | } | 68 | } |
| 63 | 69 | ||
| @@ -73,7 +79,9 @@ impl<T: Instance> interrupt::typelevel::Handler<T::SCEInterrupt> for SceInterrup | |||
| 73 | 79 | ||
| 74 | if msr_val.slaki() { | 80 | if msr_val.slaki() { |
| 75 | msr.modify(|m| m.set_slaki(true)); | 81 | msr.modify(|m| m.set_slaki(true)); |
| 76 | T::state().err_waker.wake(); | 82 | T::info().state.lock(|state| { |
| 83 | state.borrow().err_waker.wake(); | ||
| 84 | }); | ||
| 77 | } else if msr_val.erri() { | 85 | } else if msr_val.erri() { |
| 78 | // Disable the interrupt, but don't acknowledge the error, so that it can be | 86 | // Disable the interrupt, but don't acknowledge the error, so that it can be |
| 79 | // forwarded off the bus message consumer. If we don't provide some way for | 87 | // 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 | |||
| 83 | let ier = T::regs().ier(); | 91 | let ier = T::regs().ier(); |
| 84 | ier.modify(|i| i.set_errie(false)); | 92 | ier.modify(|i| i.set_errie(false)); |
| 85 | 93 | ||
| 86 | T::state().err_waker.wake(); | 94 | T::info().state.lock(|state| { |
| 95 | state.borrow().err_waker.wake(); | ||
| 96 | }); | ||
| 87 | } | 97 | } |
| 88 | } | 98 | } |
| 89 | } | 99 | } |
| @@ -157,7 +167,6 @@ impl Drop for CanConfig<'_> { | |||
| 157 | pub struct Can<'d> { | 167 | pub struct Can<'d> { |
| 158 | phantom: PhantomData<&'d ()>, | 168 | phantom: PhantomData<&'d ()>, |
| 159 | info: &'static Info, | 169 | info: &'static Info, |
| 160 | state: &'static State, | ||
| 161 | periph_clock: crate::time::Hertz, | 170 | periph_clock: crate::time::Hertz, |
| 162 | } | 171 | } |
| 163 | 172 | ||
| @@ -228,7 +237,6 @@ impl<'d> Can<'d> { | |||
| 228 | Self { | 237 | Self { |
| 229 | phantom: PhantomData, | 238 | phantom: PhantomData, |
| 230 | info: T::info(), | 239 | info: T::info(), |
| 231 | state: T::state(), | ||
| 232 | periph_clock: T::frequency(), | 240 | periph_clock: T::frequency(), |
| 233 | } | 241 | } |
| 234 | } | 242 | } |
| @@ -297,7 +305,9 @@ impl<'d> Can<'d> { | |||
| 297 | self.info.regs.0.mcr().modify(|m| m.set_sleep(true)); | 305 | self.info.regs.0.mcr().modify(|m| m.set_sleep(true)); |
| 298 | 306 | ||
| 299 | poll_fn(|cx| { | 307 | poll_fn(|cx| { |
| 300 | self.state.err_waker.register(cx.waker()); | 308 | self.info.state.lock(|state| { |
| 309 | state.borrow().err_waker.register(cx.waker()); | ||
| 310 | }); | ||
| 301 | if self.is_sleeping() { | 311 | if self.is_sleeping() { |
| 302 | Poll::Ready(()) | 312 | Poll::Ready(()) |
| 303 | } else { | 313 | } else { |
| @@ -351,7 +361,6 @@ impl<'d> Can<'d> { | |||
| 351 | CanTx { | 361 | CanTx { |
| 352 | _phantom: PhantomData, | 362 | _phantom: PhantomData, |
| 353 | info: self.info, | 363 | info: self.info, |
| 354 | state: self.state, | ||
| 355 | } | 364 | } |
| 356 | .flush_inner(mb) | 365 | .flush_inner(mb) |
| 357 | .await; | 366 | .await; |
| @@ -367,7 +376,6 @@ impl<'d> Can<'d> { | |||
| 367 | CanTx { | 376 | CanTx { |
| 368 | _phantom: PhantomData, | 377 | _phantom: PhantomData, |
| 369 | info: self.info, | 378 | info: self.info, |
| 370 | state: self.state, | ||
| 371 | } | 379 | } |
| 372 | .flush_any_inner() | 380 | .flush_any_inner() |
| 373 | .await | 381 | .await |
| @@ -378,7 +386,6 @@ impl<'d> Can<'d> { | |||
| 378 | CanTx { | 386 | CanTx { |
| 379 | _phantom: PhantomData, | 387 | _phantom: PhantomData, |
| 380 | info: self.info, | 388 | info: self.info, |
| 381 | state: self.state, | ||
| 382 | } | 389 | } |
| 383 | .flush_all_inner() | 390 | .flush_all_inner() |
| 384 | .await | 391 | .await |
| @@ -406,19 +413,19 @@ impl<'d> Can<'d> { | |||
| 406 | /// | 413 | /// |
| 407 | /// Returns a tuple of the time the message was received and the message frame | 414 | /// Returns a tuple of the time the message was received and the message frame |
| 408 | pub async fn read(&mut self) -> Result<Envelope, BusError> { | 415 | pub async fn read(&mut self) -> Result<Envelope, BusError> { |
| 409 | self.state.rx_mode.read(self.info, self.state).await | 416 | RxMode::read(self.info).await |
| 410 | } | 417 | } |
| 411 | 418 | ||
| 412 | /// Attempts to read a CAN frame without blocking. | 419 | /// Attempts to read a CAN frame without blocking. |
| 413 | /// | 420 | /// |
| 414 | /// Returns [Err(TryReadError::Empty)] if there are no frames in the rx queue. | 421 | /// Returns [Err(TryReadError::Empty)] if there are no frames in the rx queue. |
| 415 | pub fn try_read(&mut self) -> Result<Envelope, TryReadError> { | 422 | pub fn try_read(&mut self) -> Result<Envelope, TryReadError> { |
| 416 | self.state.rx_mode.try_read(self.info) | 423 | RxMode::try_read(self.info) |
| 417 | } | 424 | } |
| 418 | 425 | ||
| 419 | /// Waits while receive queue is empty. | 426 | /// Waits while receive queue is empty. |
| 420 | pub async fn wait_not_empty(&mut self) { | 427 | pub async fn wait_not_empty(&mut self) { |
| 421 | self.state.rx_mode.wait_not_empty(self.info, self.state).await | 428 | RxMode::wait_not_empty(self.info).await |
| 422 | } | 429 | } |
| 423 | 430 | ||
| 424 | /// Split the CAN driver into transmit and receive halves. | 431 | /// Split the CAN driver into transmit and receive halves. |
| @@ -429,12 +436,10 @@ impl<'d> Can<'d> { | |||
| 429 | CanTx { | 436 | CanTx { |
| 430 | _phantom: PhantomData, | 437 | _phantom: PhantomData, |
| 431 | info: self.info, | 438 | info: self.info, |
| 432 | state: self.state, | ||
| 433 | }, | 439 | }, |
| 434 | CanRx { | 440 | CanRx { |
| 435 | _phantom: PhantomData, | 441 | _phantom: PhantomData, |
| 436 | info: self.info, | 442 | info: self.info, |
| 437 | state: self.state, | ||
| 438 | }, | 443 | }, |
| 439 | ) | 444 | ) |
| 440 | } | 445 | } |
| @@ -515,7 +520,6 @@ impl<'d, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize> BufferedCan<'d, TX_ | |||
| 515 | pub struct CanTx<'d> { | 520 | pub struct CanTx<'d> { |
| 516 | _phantom: PhantomData<&'d ()>, | 521 | _phantom: PhantomData<&'d ()>, |
| 517 | info: &'static Info, | 522 | info: &'static Info, |
| 518 | state: &'static State, | ||
| 519 | } | 523 | } |
| 520 | 524 | ||
| 521 | impl<'d> CanTx<'d> { | 525 | impl<'d> CanTx<'d> { |
| @@ -524,7 +528,9 @@ impl<'d> CanTx<'d> { | |||
| 524 | /// If the TX queue is full, this will wait until there is space, therefore exerting backpressure. | 528 | /// If the TX queue is full, this will wait until there is space, therefore exerting backpressure. |
| 525 | pub async fn write(&mut self, frame: &Frame) -> TransmitStatus { | 529 | pub async fn write(&mut self, frame: &Frame) -> TransmitStatus { |
| 526 | poll_fn(|cx| { | 530 | poll_fn(|cx| { |
| 527 | self.state.tx_mode.register(cx.waker()); | 531 | self.info.state.lock(|state| { |
| 532 | state.borrow().tx_mode.register(cx.waker()); | ||
| 533 | }); | ||
| 528 | if let Ok(status) = self.info.regs.transmit(frame) { | 534 | if let Ok(status) = self.info.regs.transmit(frame) { |
| 529 | return Poll::Ready(status); | 535 | return Poll::Ready(status); |
| 530 | } | 536 | } |
| @@ -549,7 +555,9 @@ impl<'d> CanTx<'d> { | |||
| 549 | 555 | ||
| 550 | async fn flush_inner(&self, mb: Mailbox) { | 556 | async fn flush_inner(&self, mb: Mailbox) { |
| 551 | poll_fn(|cx| { | 557 | poll_fn(|cx| { |
| 552 | self.state.tx_mode.register(cx.waker()); | 558 | self.info.state.lock(|state| { |
| 559 | state.borrow().tx_mode.register(cx.waker()); | ||
| 560 | }); | ||
| 553 | if self.info.regs.0.tsr().read().tme(mb.index()) { | 561 | if self.info.regs.0.tsr().read().tme(mb.index()) { |
| 554 | return Poll::Ready(()); | 562 | return Poll::Ready(()); |
| 555 | } | 563 | } |
| @@ -566,7 +574,9 @@ impl<'d> CanTx<'d> { | |||
| 566 | 574 | ||
| 567 | async fn flush_any_inner(&self) { | 575 | async fn flush_any_inner(&self) { |
| 568 | poll_fn(|cx| { | 576 | poll_fn(|cx| { |
| 569 | self.state.tx_mode.register(cx.waker()); | 577 | self.info.state.lock(|state| { |
| 578 | state.borrow().tx_mode.register(cx.waker()); | ||
| 579 | }); | ||
| 570 | 580 | ||
| 571 | let tsr = self.info.regs.0.tsr().read(); | 581 | let tsr = self.info.regs.0.tsr().read(); |
| 572 | if tsr.tme(Mailbox::Mailbox0.index()) | 582 | if tsr.tme(Mailbox::Mailbox0.index()) |
| @@ -593,7 +603,9 @@ impl<'d> CanTx<'d> { | |||
| 593 | 603 | ||
| 594 | async fn flush_all_inner(&self) { | 604 | async fn flush_all_inner(&self) { |
| 595 | poll_fn(|cx| { | 605 | poll_fn(|cx| { |
| 596 | self.state.tx_mode.register(cx.waker()); | 606 | self.info.state.lock(|state| { |
| 607 | state.borrow().tx_mode.register(cx.waker()); | ||
| 608 | }); | ||
| 597 | 609 | ||
| 598 | let tsr = self.info.regs.0.tsr().read(); | 610 | let tsr = self.info.regs.0.tsr().read(); |
| 599 | if tsr.tme(Mailbox::Mailbox0.index()) | 611 | if tsr.tme(Mailbox::Mailbox0.index()) |
| @@ -634,7 +646,7 @@ impl<'d> CanTx<'d> { | |||
| 634 | self, | 646 | self, |
| 635 | txb: &'static mut TxBuf<TX_BUF_SIZE>, | 647 | txb: &'static mut TxBuf<TX_BUF_SIZE>, |
| 636 | ) -> BufferedCanTx<'d, TX_BUF_SIZE> { | 648 | ) -> BufferedCanTx<'d, TX_BUF_SIZE> { |
| 637 | BufferedCanTx::new(self.info, self.state, self, txb) | 649 | BufferedCanTx::new(self.info, self, txb) |
| 638 | } | 650 | } |
| 639 | } | 651 | } |
| 640 | 652 | ||
| @@ -644,33 +656,22 @@ pub type TxBuf<const BUF_SIZE: usize> = Channel<CriticalSectionRawMutex, Frame, | |||
| 644 | /// Buffered CAN driver, transmit half. | 656 | /// Buffered CAN driver, transmit half. |
| 645 | pub struct BufferedCanTx<'d, const TX_BUF_SIZE: usize> { | 657 | pub struct BufferedCanTx<'d, const TX_BUF_SIZE: usize> { |
| 646 | info: &'static Info, | 658 | info: &'static Info, |
| 647 | state: &'static State, | ||
| 648 | _tx: CanTx<'d>, | 659 | _tx: CanTx<'d>, |
| 649 | tx_buf: &'static TxBuf<TX_BUF_SIZE>, | 660 | tx_buf: &'static TxBuf<TX_BUF_SIZE>, |
| 650 | } | 661 | } |
| 651 | 662 | ||
| 652 | impl<'d, const TX_BUF_SIZE: usize> BufferedCanTx<'d, TX_BUF_SIZE> { | 663 | impl<'d, const TX_BUF_SIZE: usize> BufferedCanTx<'d, TX_BUF_SIZE> { |
| 653 | fn new(info: &'static Info, state: &'static State, _tx: CanTx<'d>, tx_buf: &'static TxBuf<TX_BUF_SIZE>) -> Self { | 664 | fn new(info: &'static Info, _tx: CanTx<'d>, tx_buf: &'static TxBuf<TX_BUF_SIZE>) -> Self { |
| 654 | Self { | 665 | Self { info, _tx, tx_buf }.setup() |
| 655 | info, | ||
| 656 | state, | ||
| 657 | _tx, | ||
| 658 | tx_buf, | ||
| 659 | } | ||
| 660 | .setup() | ||
| 661 | } | 666 | } |
| 662 | 667 | ||
| 663 | fn setup(self) -> Self { | 668 | fn setup(self) -> Self { |
| 664 | // We don't want interrupts being processed while we change modes. | 669 | // We don't want interrupts being processed while we change modes. |
| 665 | critical_section::with(|_| { | 670 | let tx_inner = super::common::ClassicBufferedTxInner { |
| 666 | let tx_inner = super::common::ClassicBufferedTxInner { | 671 | tx_receiver: self.tx_buf.receiver().into(), |
| 667 | tx_receiver: self.tx_buf.receiver().into(), | 672 | }; |
| 668 | }; | 673 | self.info.state.lock(|state| { |
| 669 | let state = self.state as *const State; | 674 | state.borrow_mut().tx_mode = TxMode::Buffered(tx_inner); |
| 670 | unsafe { | ||
| 671 | let mut_state = state as *mut State; | ||
| 672 | (*mut_state).tx_mode = TxMode::Buffered(tx_inner); | ||
| 673 | } | ||
| 674 | }); | 675 | }); |
| 675 | self | 676 | self |
| 676 | } | 677 | } |
| @@ -704,7 +705,6 @@ impl<'d, const TX_BUF_SIZE: usize> Drop for BufferedCanTx<'d, TX_BUF_SIZE> { | |||
| 704 | pub struct CanRx<'d> { | 705 | pub struct CanRx<'d> { |
| 705 | _phantom: PhantomData<&'d ()>, | 706 | _phantom: PhantomData<&'d ()>, |
| 706 | info: &'static Info, | 707 | info: &'static Info, |
| 707 | state: &'static State, | ||
| 708 | } | 708 | } |
| 709 | 709 | ||
| 710 | impl<'d> CanRx<'d> { | 710 | impl<'d> CanRx<'d> { |
| @@ -714,19 +714,19 @@ impl<'d> CanRx<'d> { | |||
| 714 | /// | 714 | /// |
| 715 | /// Returns a tuple of the time the message was received and the message frame | 715 | /// Returns a tuple of the time the message was received and the message frame |
| 716 | pub async fn read(&mut self) -> Result<Envelope, BusError> { | 716 | pub async fn read(&mut self) -> Result<Envelope, BusError> { |
| 717 | self.state.rx_mode.read(self.info, self.state).await | 717 | RxMode::read(self.info).await |
| 718 | } | 718 | } |
| 719 | 719 | ||
| 720 | /// Attempts to read a CAN frame without blocking. | 720 | /// Attempts to read a CAN frame without blocking. |
| 721 | /// | 721 | /// |
| 722 | /// Returns [Err(TryReadError::Empty)] if there are no frames in the rx queue. | 722 | /// Returns [Err(TryReadError::Empty)] if there are no frames in the rx queue. |
| 723 | pub fn try_read(&mut self) -> Result<Envelope, TryReadError> { | 723 | pub fn try_read(&mut self) -> Result<Envelope, TryReadError> { |
| 724 | self.state.rx_mode.try_read(self.info) | 724 | RxMode::try_read(self.info) |
| 725 | } | 725 | } |
| 726 | 726 | ||
| 727 | /// Waits while receive queue is empty. | 727 | /// Waits while receive queue is empty. |
| 728 | pub async fn wait_not_empty(&mut self) { | 728 | pub async fn wait_not_empty(&mut self) { |
| 729 | self.state.rx_mode.wait_not_empty(self.info, self.state).await | 729 | RxMode::wait_not_empty(self.info).await |
| 730 | } | 730 | } |
| 731 | 731 | ||
| 732 | /// Return a buffered instance of driver. User must supply Buffers | 732 | /// Return a buffered instance of driver. User must supply Buffers |
| @@ -734,7 +734,7 @@ impl<'d> CanRx<'d> { | |||
| 734 | self, | 734 | self, |
| 735 | rxb: &'static mut RxBuf<RX_BUF_SIZE>, | 735 | rxb: &'static mut RxBuf<RX_BUF_SIZE>, |
| 736 | ) -> BufferedCanRx<'d, RX_BUF_SIZE> { | 736 | ) -> BufferedCanRx<'d, RX_BUF_SIZE> { |
| 737 | BufferedCanRx::new(self.info, self.state, self, rxb) | 737 | BufferedCanRx::new(self.info, self, rxb) |
| 738 | } | 738 | } |
| 739 | 739 | ||
| 740 | /// Accesses the filter banks owned by this CAN peripheral. | 740 | /// Accesses the filter banks owned by this CAN peripheral. |
| @@ -752,33 +752,22 @@ pub type RxBuf<const BUF_SIZE: usize> = Channel<CriticalSectionRawMutex, Result< | |||
| 752 | /// CAN driver, receive half in Buffered mode. | 752 | /// CAN driver, receive half in Buffered mode. |
| 753 | pub struct BufferedCanRx<'d, const RX_BUF_SIZE: usize> { | 753 | pub struct BufferedCanRx<'d, const RX_BUF_SIZE: usize> { |
| 754 | info: &'static Info, | 754 | info: &'static Info, |
| 755 | state: &'static State, | ||
| 756 | rx: CanRx<'d>, | 755 | rx: CanRx<'d>, |
| 757 | rx_buf: &'static RxBuf<RX_BUF_SIZE>, | 756 | rx_buf: &'static RxBuf<RX_BUF_SIZE>, |
| 758 | } | 757 | } |
| 759 | 758 | ||
| 760 | impl<'d, const RX_BUF_SIZE: usize> BufferedCanRx<'d, RX_BUF_SIZE> { | 759 | impl<'d, const RX_BUF_SIZE: usize> BufferedCanRx<'d, RX_BUF_SIZE> { |
| 761 | fn new(info: &'static Info, state: &'static State, rx: CanRx<'d>, rx_buf: &'static RxBuf<RX_BUF_SIZE>) -> Self { | 760 | fn new(info: &'static Info, rx: CanRx<'d>, rx_buf: &'static RxBuf<RX_BUF_SIZE>) -> Self { |
| 762 | BufferedCanRx { | 761 | BufferedCanRx { info, rx, rx_buf }.setup() |
| 763 | info, | ||
| 764 | state, | ||
| 765 | rx, | ||
| 766 | rx_buf, | ||
| 767 | } | ||
| 768 | .setup() | ||
| 769 | } | 762 | } |
| 770 | 763 | ||
| 771 | fn setup(self) -> Self { | 764 | fn setup(self) -> Self { |
| 772 | // We don't want interrupts being processed while we change modes. | 765 | // We don't want interrupts being processed while we change modes. |
| 773 | critical_section::with(|_| { | 766 | let rx_inner = super::common::ClassicBufferedRxInner { |
| 774 | let rx_inner = super::common::ClassicBufferedRxInner { | 767 | rx_sender: self.rx_buf.sender().into(), |
| 775 | rx_sender: self.rx_buf.sender().into(), | 768 | }; |
| 776 | }; | 769 | self.info.state.lock(|state| { |
| 777 | let state = self.state as *const State; | 770 | state.borrow_mut().rx_mode = RxMode::Buffered(rx_inner); |
| 778 | unsafe { | ||
| 779 | let mut_state = state as *mut State; | ||
| 780 | (*mut_state).rx_mode = RxMode::Buffered(rx_inner); | ||
| 781 | } | ||
| 782 | }); | 771 | }); |
| 783 | self | 772 | self |
| 784 | } | 773 | } |
| @@ -792,7 +781,7 @@ impl<'d, const RX_BUF_SIZE: usize> BufferedCanRx<'d, RX_BUF_SIZE> { | |||
| 792 | /// | 781 | /// |
| 793 | /// Returns [Err(TryReadError::Empty)] if there are no frames in the rx queue. | 782 | /// Returns [Err(TryReadError::Empty)] if there are no frames in the rx queue. |
| 794 | pub fn try_read(&mut self) -> Result<Envelope, TryReadError> { | 783 | pub fn try_read(&mut self) -> Result<Envelope, TryReadError> { |
| 795 | match &self.state.rx_mode { | 784 | self.info.state.lock(|s| match &s.borrow().rx_mode { |
| 796 | RxMode::Buffered(_) => { | 785 | RxMode::Buffered(_) => { |
| 797 | if let Ok(result) = self.rx_buf.try_receive() { | 786 | if let Ok(result) = self.rx_buf.try_receive() { |
| 798 | match result { | 787 | match result { |
| @@ -810,7 +799,7 @@ impl<'d, const RX_BUF_SIZE: usize> BufferedCanRx<'d, RX_BUF_SIZE> { | |||
| 810 | _ => { | 799 | _ => { |
| 811 | panic!("Bad Mode") | 800 | panic!("Bad Mode") |
| 812 | } | 801 | } |
| 813 | } | 802 | }) |
| 814 | } | 803 | } |
| 815 | 804 | ||
| 816 | /// Waits while receive queue is empty. | 805 | /// Waits while receive queue is empty. |
| @@ -929,27 +918,30 @@ impl RxMode { | |||
| 929 | } | 918 | } |
| 930 | } | 919 | } |
| 931 | 920 | ||
| 932 | pub(crate) async fn read(&self, info: &Info, state: &State) -> Result<Envelope, BusError> { | 921 | pub(crate) async fn read(info: &Info) -> Result<Envelope, BusError> { |
| 933 | match self { | 922 | poll_fn(|cx| { |
| 934 | Self::NonBuffered(waker) => { | 923 | info.state.lock(|state| { |
| 935 | poll_fn(|cx| { | 924 | let state = state.borrow(); |
| 936 | state.err_waker.register(cx.waker()); | 925 | state.err_waker.register(cx.waker()); |
| 937 | waker.register(cx.waker()); | 926 | match &state.rx_mode { |
| 938 | match self.try_read(info) { | 927 | Self::NonBuffered(waker) => { |
| 939 | Ok(result) => Poll::Ready(Ok(result)), | 928 | waker.register(cx.waker()); |
| 940 | Err(TryReadError::Empty) => Poll::Pending, | ||
| 941 | Err(TryReadError::BusError(be)) => Poll::Ready(Err(be)), | ||
| 942 | } | 929 | } |
| 943 | }) | 930 | _ => { |
| 944 | .await | 931 | panic!("Bad Mode") |
| 945 | } | 932 | } |
| 946 | _ => { | 933 | } |
| 947 | panic!("Bad Mode") | 934 | }); |
| 935 | match RxMode::try_read(info) { | ||
| 936 | Ok(result) => Poll::Ready(Ok(result)), | ||
| 937 | Err(TryReadError::Empty) => Poll::Pending, | ||
| 938 | Err(TryReadError::BusError(be)) => Poll::Ready(Err(be)), | ||
| 948 | } | 939 | } |
| 949 | } | 940 | }) |
| 941 | .await | ||
| 950 | } | 942 | } |
| 951 | pub(crate) fn try_read(&self, info: &Info) -> Result<Envelope, TryReadError> { | 943 | pub(crate) fn try_read(info: &Info) -> Result<Envelope, TryReadError> { |
| 952 | match self { | 944 | info.state.lock(|state| match state.borrow().rx_mode { |
| 953 | Self::NonBuffered(_) => { | 945 | Self::NonBuffered(_) => { |
| 954 | let registers = &info.regs; | 946 | let registers = &info.regs; |
| 955 | if let Some(msg) = registers.receive_fifo(RxFifo::Fifo0) { | 947 | if let Some(msg) = registers.receive_fifo(RxFifo::Fifo0) { |
| @@ -975,25 +967,28 @@ impl RxMode { | |||
| 975 | _ => { | 967 | _ => { |
| 976 | panic!("Bad Mode") | 968 | panic!("Bad Mode") |
| 977 | } | 969 | } |
| 978 | } | 970 | }) |
| 979 | } | 971 | } |
| 980 | pub(crate) async fn wait_not_empty(&self, info: &Info, state: &State) { | 972 | pub(crate) async fn wait_not_empty(info: &Info) { |
| 981 | match &state.rx_mode { | 973 | poll_fn(|cx| { |
| 982 | Self::NonBuffered(waker) => { | 974 | info.state.lock(|s| { |
| 983 | poll_fn(|cx| { | 975 | let state = s.borrow(); |
| 984 | waker.register(cx.waker()); | 976 | match &state.rx_mode { |
| 985 | if info.regs.receive_frame_available() { | 977 | Self::NonBuffered(waker) => { |
| 986 | Poll::Ready(()) | 978 | waker.register(cx.waker()); |
| 987 | } else { | ||
| 988 | Poll::Pending | ||
| 989 | } | 979 | } |
| 990 | }) | 980 | _ => { |
| 991 | .await | 981 | panic!("Bad Mode") |
| 992 | } | 982 | } |
| 993 | _ => { | 983 | } |
| 994 | panic!("Bad Mode") | 984 | }); |
| 985 | if info.regs.receive_frame_available() { | ||
| 986 | Poll::Ready(()) | ||
| 987 | } else { | ||
| 988 | Poll::Pending | ||
| 995 | } | 989 | } |
| 996 | } | 990 | }) |
| 991 | .await | ||
| 997 | } | 992 | } |
| 998 | } | 993 | } |
| 999 | 994 | ||
| @@ -1008,21 +1003,24 @@ impl TxMode { | |||
| 1008 | tsr.tme(Mailbox::Mailbox0.index()) || tsr.tme(Mailbox::Mailbox1.index()) || tsr.tme(Mailbox::Mailbox2.index()) | 1003 | tsr.tme(Mailbox::Mailbox0.index()) || tsr.tme(Mailbox::Mailbox1.index()) || tsr.tme(Mailbox::Mailbox2.index()) |
| 1009 | } | 1004 | } |
| 1010 | pub fn on_interrupt<T: Instance>(&self) { | 1005 | pub fn on_interrupt<T: Instance>(&self) { |
| 1011 | match &T::state().tx_mode { | 1006 | T::info().state.lock(|state| { |
| 1012 | TxMode::NonBuffered(waker) => waker.wake(), | 1007 | let tx_mode = &state.borrow().tx_mode; |
| 1013 | TxMode::Buffered(buf) => { | 1008 | match tx_mode { |
| 1014 | while self.buffer_free::<T>() { | 1009 | TxMode::NonBuffered(waker) => waker.wake(), |
| 1015 | match buf.tx_receiver.try_receive() { | 1010 | TxMode::Buffered(buf) => { |
| 1016 | Ok(frame) => { | 1011 | while self.buffer_free::<T>() { |
| 1017 | _ = Registers(T::regs()).transmit(&frame); | 1012 | match buf.tx_receiver.try_receive() { |
| 1018 | } | 1013 | Ok(frame) => { |
| 1019 | Err(_) => { | 1014 | _ = Registers(T::regs()).transmit(&frame); |
| 1020 | break; | 1015 | } |
| 1016 | Err(_) => { | ||
| 1017 | break; | ||
| 1018 | } | ||
| 1021 | } | 1019 | } |
| 1022 | } | 1020 | } |
| 1023 | } | 1021 | } |
| 1024 | } | 1022 | } |
| 1025 | } | 1023 | }); |
| 1026 | } | 1024 | } |
| 1027 | 1025 | ||
| 1028 | fn register(&self, arg: &core::task::Waker) { | 1026 | fn register(&self, arg: &core::task::Waker) { |
| @@ -1057,6 +1055,7 @@ impl State { | |||
| 1057 | } | 1055 | } |
| 1058 | } | 1056 | } |
| 1059 | 1057 | ||
| 1058 | type SharedState = embassy_sync::blocking_mutex::Mutex<CriticalSectionRawMutex, core::cell::RefCell<State>>; | ||
| 1060 | pub(crate) struct Info { | 1059 | pub(crate) struct Info { |
| 1061 | regs: Registers, | 1060 | regs: Registers, |
| 1062 | tx_interrupt: crate::interrupt::Interrupt, | 1061 | tx_interrupt: crate::interrupt::Interrupt, |
| @@ -1065,6 +1064,7 @@ pub(crate) struct Info { | |||
| 1065 | sce_interrupt: crate::interrupt::Interrupt, | 1064 | sce_interrupt: crate::interrupt::Interrupt, |
| 1066 | tx_waker: fn(), | 1065 | tx_waker: fn(), |
| 1067 | internal_operation: fn(InternalOperation), | 1066 | internal_operation: fn(InternalOperation), |
| 1067 | state: SharedState, | ||
| 1068 | 1068 | ||
| 1069 | /// The total number of filter banks available to the instance. | 1069 | /// The total number of filter banks available to the instance. |
| 1070 | /// | 1070 | /// |
| @@ -1075,8 +1075,6 @@ pub(crate) struct Info { | |||
| 1075 | trait SealedInstance { | 1075 | trait SealedInstance { |
| 1076 | fn info() -> &'static Info; | 1076 | fn info() -> &'static Info; |
| 1077 | fn regs() -> crate::pac::can::Can; | 1077 | fn regs() -> crate::pac::can::Can; |
| 1078 | fn state() -> &'static State; | ||
| 1079 | unsafe fn mut_state() -> &'static mut State; | ||
| 1080 | fn internal_operation(val: InternalOperation); | 1078 | fn internal_operation(val: InternalOperation); |
| 1081 | } | 1079 | } |
| 1082 | 1080 | ||
| @@ -1136,6 +1134,7 @@ foreach_peripheral!( | |||
| 1136 | sce_interrupt: crate::_generated::peripheral_interrupts::$inst::SCE::IRQ, | 1134 | sce_interrupt: crate::_generated::peripheral_interrupts::$inst::SCE::IRQ, |
| 1137 | tx_waker: crate::_generated::peripheral_interrupts::$inst::TX::pend, | 1135 | tx_waker: crate::_generated::peripheral_interrupts::$inst::TX::pend, |
| 1138 | internal_operation: peripherals::$inst::internal_operation, | 1136 | internal_operation: peripherals::$inst::internal_operation, |
| 1137 | state: embassy_sync::blocking_mutex::Mutex::new(core::cell::RefCell::new(State::new())), | ||
| 1139 | num_filter_banks: peripherals::$inst::NUM_FILTER_BANKS, | 1138 | num_filter_banks: peripherals::$inst::NUM_FILTER_BANKS, |
| 1140 | }; | 1139 | }; |
| 1141 | &INFO | 1140 | &INFO |
| @@ -1144,21 +1143,10 @@ foreach_peripheral!( | |||
| 1144 | crate::pac::$inst | 1143 | crate::pac::$inst |
| 1145 | } | 1144 | } |
| 1146 | 1145 | ||
| 1147 | unsafe fn mut_state() -> & 'static mut State { | ||
| 1148 | static mut STATE: State = State::new(); | ||
| 1149 | &mut *core::ptr::addr_of_mut!(STATE) | ||
| 1150 | } | ||
| 1151 | fn state() -> &'static State { | ||
| 1152 | unsafe { peripherals::$inst::mut_state() } | ||
| 1153 | } | ||
| 1154 | |||
| 1155 | |||
| 1156 | fn internal_operation(val: InternalOperation) { | 1146 | fn internal_operation(val: InternalOperation) { |
| 1157 | critical_section::with(|_| { | 1147 | peripherals::$inst::info().state.lock(|s| { |
| 1158 | //let state = self.state as *const State; | 1148 | let mut mut_state = s.borrow_mut(); |
| 1159 | unsafe { | ||
| 1160 | //let mut_state = state as *mut State; | 1149 | //let mut_state = state as *mut State; |
| 1161 | let mut_state = peripherals::$inst::mut_state(); | ||
| 1162 | match val { | 1150 | match val { |
| 1163 | InternalOperation::NotifySenderCreated => { | 1151 | InternalOperation::NotifySenderCreated => { |
| 1164 | mut_state.sender_instance_count += 1; | 1152 | mut_state.sender_instance_count += 1; |
| @@ -1179,11 +1167,9 @@ foreach_peripheral!( | |||
| 1179 | } | 1167 | } |
| 1180 | } | 1168 | } |
| 1181 | } | 1169 | } |
| 1182 | } | ||
| 1183 | }); | 1170 | }); |
| 1184 | } | 1171 | } |
| 1185 | } | 1172 | } |
| 1186 | |||
| 1187 | impl Instance for peripherals::$inst { | 1173 | impl Instance for peripherals::$inst { |
| 1188 | type TXInterrupt = crate::_generated::peripheral_interrupts::$inst::TX; | 1174 | type TXInterrupt = crate::_generated::peripheral_interrupts::$inst::TX; |
| 1189 | type RX0Interrupt = crate::_generated::peripheral_interrupts::$inst::RX0; | 1175 | type RX0Interrupt = crate::_generated::peripheral_interrupts::$inst::RX0; |
