diff options
| -rw-r--r-- | embassy-stm32/src/can/fdcan.rs | 246 |
1 files changed, 108 insertions, 138 deletions
diff --git a/embassy-stm32/src/can/fdcan.rs b/embassy-stm32/src/can/fdcan.rs index a7815f79b..4495280c4 100644 --- a/embassy-stm32/src/can/fdcan.rs +++ b/embassy-stm32/src/can/fdcan.rs | |||
| @@ -52,36 +52,39 @@ impl<T: Instance> interrupt::typelevel::Handler<T::IT0Interrupt> for IT0Interrup | |||
| 52 | regs.ir().write(|w| w.set_tefn(true)); | 52 | regs.ir().write(|w| w.set_tefn(true)); |
| 53 | } | 53 | } |
| 54 | 54 | ||
| 55 | match &T::state().tx_mode { | 55 | T::info().state.lock(|s| { |
| 56 | TxMode::NonBuffered(waker) => waker.wake(), | 56 | let state = s.borrow_mut(); |
| 57 | TxMode::ClassicBuffered(buf) => { | 57 | match &state.tx_mode { |
| 58 | if !T::registers().tx_queue_is_full() { | 58 | TxMode::NonBuffered(waker) => waker.wake(), |
| 59 | match buf.tx_receiver.try_receive() { | 59 | TxMode::ClassicBuffered(buf) => { |
| 60 | Ok(frame) => { | 60 | if !T::registers().tx_queue_is_full() { |
| 61 | _ = T::registers().write(&frame); | 61 | match buf.tx_receiver.try_receive() { |
| 62 | Ok(frame) => { | ||
| 63 | _ = T::registers().write(&frame); | ||
| 64 | } | ||
| 65 | Err(_) => {} | ||
| 62 | } | 66 | } |
| 63 | Err(_) => {} | ||
| 64 | } | 67 | } |
| 65 | } | 68 | } |
| 66 | } | 69 | TxMode::FdBuffered(buf) => { |
| 67 | TxMode::FdBuffered(buf) => { | 70 | if !T::registers().tx_queue_is_full() { |
| 68 | if !T::registers().tx_queue_is_full() { | 71 | match buf.tx_receiver.try_receive() { |
| 69 | match buf.tx_receiver.try_receive() { | 72 | Ok(frame) => { |
| 70 | Ok(frame) => { | 73 | _ = T::registers().write(&frame); |
| 71 | _ = T::registers().write(&frame); | 74 | } |
| 75 | Err(_) => {} | ||
| 72 | } | 76 | } |
| 73 | Err(_) => {} | ||
| 74 | } | 77 | } |
| 75 | } | 78 | } |
| 76 | } | 79 | } |
| 77 | } | ||
| 78 | 80 | ||
| 79 | if ir.rfn(0) { | 81 | if ir.rfn(0) { |
| 80 | T::state().rx_mode.on_interrupt::<T>(0); | 82 | state.rx_mode.on_interrupt::<T>(0, state.ns_per_timer_tick); |
| 81 | } | 83 | } |
| 82 | if ir.rfn(1) { | 84 | if ir.rfn(1) { |
| 83 | T::state().rx_mode.on_interrupt::<T>(1); | 85 | state.rx_mode.on_interrupt::<T>(1, state.ns_per_timer_tick); |
| 84 | } | 86 | } |
| 87 | }); | ||
| 85 | 88 | ||
| 86 | if ir.bo() { | 89 | if ir.bo() { |
| 87 | regs.ir().write(|w| w.set_bo(true)); | 90 | regs.ir().write(|w| w.set_bo(true)); |
| @@ -165,7 +168,6 @@ pub struct CanConfigurator<'d> { | |||
| 165 | _phantom: PhantomData<&'d ()>, | 168 | _phantom: PhantomData<&'d ()>, |
| 166 | config: crate::can::fd::config::FdCanConfig, | 169 | config: crate::can::fd::config::FdCanConfig, |
| 167 | info: &'static Info, | 170 | info: &'static Info, |
| 168 | state: &'static State, | ||
| 169 | /// Reference to internals. | 171 | /// Reference to internals. |
| 170 | properties: Properties, | 172 | properties: Properties, |
| 171 | periph_clock: crate::time::Hertz, | 173 | periph_clock: crate::time::Hertz, |
| @@ -188,9 +190,10 @@ impl<'d> CanConfigurator<'d> { | |||
| 188 | rcc::enable_and_reset::<T>(); | 190 | rcc::enable_and_reset::<T>(); |
| 189 | 191 | ||
| 190 | let info = T::info(); | 192 | let info = T::info(); |
| 191 | let state = unsafe { T::mut_state() }; | 193 | T::info().state.lock(|s| { |
| 192 | state.tx_pin_port = Some(tx.pin_port()); | 194 | s.borrow_mut().tx_pin_port = Some(tx.pin_port()); |
| 193 | state.rx_pin_port = Some(rx.pin_port()); | 195 | s.borrow_mut().rx_pin_port = Some(rx.pin_port()); |
| 196 | }); | ||
| 194 | (info.internal_operation)(InternalOperation::NotifySenderCreated); | 197 | (info.internal_operation)(InternalOperation::NotifySenderCreated); |
| 195 | (info.internal_operation)(InternalOperation::NotifyReceiverCreated); | 198 | (info.internal_operation)(InternalOperation::NotifyReceiverCreated); |
| 196 | 199 | ||
| @@ -209,7 +212,6 @@ impl<'d> CanConfigurator<'d> { | |||
| 209 | _phantom: PhantomData, | 212 | _phantom: PhantomData, |
| 210 | config, | 213 | config, |
| 211 | info, | 214 | info, |
| 212 | state, | ||
| 213 | properties: Properties::new(T::info()), | 215 | properties: Properties::new(T::info()), |
| 214 | periph_clock: T::frequency(), | 216 | periph_clock: T::frequency(), |
| 215 | } | 217 | } |
| @@ -261,12 +263,8 @@ impl<'d> CanConfigurator<'d> { | |||
| 261 | /// Start in mode. | 263 | /// Start in mode. |
| 262 | pub fn start(self, mode: OperatingMode) -> Can<'d> { | 264 | pub fn start(self, mode: OperatingMode) -> Can<'d> { |
| 263 | let ns_per_timer_tick = calc_ns_per_timer_tick(self.info, self.periph_clock, self.config.frame_transmit); | 265 | let ns_per_timer_tick = calc_ns_per_timer_tick(self.info, self.periph_clock, self.config.frame_transmit); |
| 264 | critical_section::with(|_| { | 266 | self.info.state.lock(|s| { |
| 265 | let state = self.state as *const State; | 267 | s.borrow_mut().ns_per_timer_tick = ns_per_timer_tick; |
| 266 | unsafe { | ||
| 267 | let mut_state = state as *mut State; | ||
| 268 | (*mut_state).ns_per_timer_tick = ns_per_timer_tick; | ||
| 269 | } | ||
| 270 | }); | 268 | }); |
| 271 | self.info.regs.into_mode(self.config, mode); | 269 | self.info.regs.into_mode(self.config, mode); |
| 272 | (self.info.internal_operation)(InternalOperation::NotifySenderCreated); | 270 | (self.info.internal_operation)(InternalOperation::NotifySenderCreated); |
| @@ -275,7 +273,6 @@ impl<'d> CanConfigurator<'d> { | |||
| 275 | _phantom: PhantomData, | 273 | _phantom: PhantomData, |
| 276 | config: self.config, | 274 | config: self.config, |
| 277 | info: self.info, | 275 | info: self.info, |
| 278 | state: self.state, | ||
| 279 | _mode: mode, | 276 | _mode: mode, |
| 280 | properties: Properties::new(self.info), | 277 | properties: Properties::new(self.info), |
| 281 | } | 278 | } |
| @@ -309,7 +306,6 @@ pub struct Can<'d> { | |||
| 309 | _phantom: PhantomData<&'d ()>, | 306 | _phantom: PhantomData<&'d ()>, |
| 310 | config: crate::can::fd::config::FdCanConfig, | 307 | config: crate::can::fd::config::FdCanConfig, |
| 311 | info: &'static Info, | 308 | info: &'static Info, |
| 312 | state: &'static State, | ||
| 313 | _mode: OperatingMode, | 309 | _mode: OperatingMode, |
| 314 | properties: Properties, | 310 | properties: Properties, |
| 315 | } | 311 | } |
| @@ -323,7 +319,9 @@ impl<'d> Can<'d> { | |||
| 323 | /// Flush one of the TX mailboxes. | 319 | /// Flush one of the TX mailboxes. |
| 324 | pub async fn flush(&self, idx: usize) { | 320 | pub async fn flush(&self, idx: usize) { |
| 325 | poll_fn(|cx| { | 321 | poll_fn(|cx| { |
| 326 | self.state.tx_mode.register(cx.waker()); | 322 | self.info.state.lock(|s| { |
| 323 | s.borrow_mut().tx_mode.register(cx.waker()); | ||
| 324 | }); | ||
| 327 | 325 | ||
| 328 | if idx > 3 { | 326 | if idx > 3 { |
| 329 | panic!("Bad mailbox"); | 327 | panic!("Bad mailbox"); |
| @@ -343,12 +341,12 @@ impl<'d> Can<'d> { | |||
| 343 | /// can be replaced, this call asynchronously waits for a frame to be successfully | 341 | /// can be replaced, this call asynchronously waits for a frame to be successfully |
| 344 | /// transmitted, then tries again. | 342 | /// transmitted, then tries again. |
| 345 | pub async fn write(&mut self, frame: &Frame) -> Option<Frame> { | 343 | pub async fn write(&mut self, frame: &Frame) -> Option<Frame> { |
| 346 | self.state.tx_mode.write(self.info, frame).await | 344 | TxMode::write(self.info, frame).await |
| 347 | } | 345 | } |
| 348 | 346 | ||
| 349 | /// Returns the next received message frame | 347 | /// Returns the next received message frame |
| 350 | pub async fn read(&mut self) -> Result<Envelope, BusError> { | 348 | pub async fn read(&mut self) -> Result<Envelope, BusError> { |
| 351 | self.state.rx_mode.read_classic(self.info, self.state).await | 349 | RxMode::read_classic(self.info).await |
| 352 | } | 350 | } |
| 353 | 351 | ||
| 354 | /// Queues the message to be sent but exerts backpressure. If a lower-priority | 352 | /// Queues the message to be sent but exerts backpressure. If a lower-priority |
| @@ -356,12 +354,12 @@ impl<'d> Can<'d> { | |||
| 356 | /// can be replaced, this call asynchronously waits for a frame to be successfully | 354 | /// can be replaced, this call asynchronously waits for a frame to be successfully |
| 357 | /// transmitted, then tries again. | 355 | /// transmitted, then tries again. |
| 358 | pub async fn write_fd(&mut self, frame: &FdFrame) -> Option<FdFrame> { | 356 | pub async fn write_fd(&mut self, frame: &FdFrame) -> Option<FdFrame> { |
| 359 | self.state.tx_mode.write_fd(self.info, frame).await | 357 | TxMode::write_fd(self.info, frame).await |
| 360 | } | 358 | } |
| 361 | 359 | ||
| 362 | /// Returns the next received message frame | 360 | /// Returns the next received message frame |
| 363 | pub async fn read_fd(&mut self) -> Result<FdEnvelope, BusError> { | 361 | pub async fn read_fd(&mut self) -> Result<FdEnvelope, BusError> { |
| 364 | self.state.rx_mode.read_fd(self.info, self.state).await | 362 | RxMode::read_fd(self.info).await |
| 365 | } | 363 | } |
| 366 | 364 | ||
| 367 | /// Split instance into separate portions: Tx(write), Rx(read), common properties | 365 | /// Split instance into separate portions: Tx(write), Rx(read), common properties |
| @@ -372,14 +370,12 @@ impl<'d> Can<'d> { | |||
| 372 | CanTx { | 370 | CanTx { |
| 373 | _phantom: PhantomData, | 371 | _phantom: PhantomData, |
| 374 | info: self.info, | 372 | info: self.info, |
| 375 | state: self.state, | ||
| 376 | config: self.config, | 373 | config: self.config, |
| 377 | _mode: self._mode, | 374 | _mode: self._mode, |
| 378 | }, | 375 | }, |
| 379 | CanRx { | 376 | CanRx { |
| 380 | _phantom: PhantomData, | 377 | _phantom: PhantomData, |
| 381 | info: self.info, | 378 | info: self.info, |
| 382 | state: self.state, | ||
| 383 | _mode: self._mode, | 379 | _mode: self._mode, |
| 384 | }, | 380 | }, |
| 385 | Properties { | 381 | Properties { |
| @@ -395,7 +391,6 @@ impl<'d> Can<'d> { | |||
| 395 | _phantom: PhantomData, | 391 | _phantom: PhantomData, |
| 396 | config: tx.config, | 392 | config: tx.config, |
| 397 | info: tx.info, | 393 | info: tx.info, |
| 398 | state: tx.state, | ||
| 399 | _mode: rx._mode, | 394 | _mode: rx._mode, |
| 400 | properties: Properties::new(tx.info), | 395 | properties: Properties::new(tx.info), |
| 401 | } | 396 | } |
| @@ -407,7 +402,7 @@ impl<'d> Can<'d> { | |||
| 407 | tx_buf: &'static mut TxBuf<TX_BUF_SIZE>, | 402 | tx_buf: &'static mut TxBuf<TX_BUF_SIZE>, |
| 408 | rxb: &'static mut RxBuf<RX_BUF_SIZE>, | 403 | rxb: &'static mut RxBuf<RX_BUF_SIZE>, |
| 409 | ) -> BufferedCan<'d, TX_BUF_SIZE, RX_BUF_SIZE> { | 404 | ) -> BufferedCan<'d, TX_BUF_SIZE, RX_BUF_SIZE> { |
| 410 | BufferedCan::new(self.info, self.state, self._mode, tx_buf, rxb) | 405 | BufferedCan::new(self.info, self._mode, tx_buf, rxb) |
| 411 | } | 406 | } |
| 412 | 407 | ||
| 413 | /// Return a buffered instance of driver with CAN FD support. User must supply Buffers | 408 | /// Return a buffered instance of driver with CAN FD support. User must supply Buffers |
| @@ -416,7 +411,7 @@ impl<'d> Can<'d> { | |||
| 416 | tx_buf: &'static mut TxFdBuf<TX_BUF_SIZE>, | 411 | tx_buf: &'static mut TxFdBuf<TX_BUF_SIZE>, |
| 417 | rxb: &'static mut RxFdBuf<RX_BUF_SIZE>, | 412 | rxb: &'static mut RxFdBuf<RX_BUF_SIZE>, |
| 418 | ) -> BufferedCanFd<'d, TX_BUF_SIZE, RX_BUF_SIZE> { | 413 | ) -> BufferedCanFd<'d, TX_BUF_SIZE, RX_BUF_SIZE> { |
| 419 | BufferedCanFd::new(self.info, self.state, self._mode, tx_buf, rxb) | 414 | BufferedCanFd::new(self.info, self._mode, tx_buf, rxb) |
| 420 | } | 415 | } |
| 421 | } | 416 | } |
| 422 | 417 | ||
| @@ -437,7 +432,6 @@ pub type TxBuf<const BUF_SIZE: usize> = Channel<CriticalSectionRawMutex, Frame, | |||
| 437 | pub struct BufferedCan<'d, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize> { | 432 | pub struct BufferedCan<'d, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize> { |
| 438 | _phantom: PhantomData<&'d ()>, | 433 | _phantom: PhantomData<&'d ()>, |
| 439 | info: &'static Info, | 434 | info: &'static Info, |
| 440 | state: &'static State, | ||
| 441 | _mode: OperatingMode, | 435 | _mode: OperatingMode, |
| 442 | tx_buf: &'static TxBuf<TX_BUF_SIZE>, | 436 | tx_buf: &'static TxBuf<TX_BUF_SIZE>, |
| 443 | rx_buf: &'static RxBuf<RX_BUF_SIZE>, | 437 | rx_buf: &'static RxBuf<RX_BUF_SIZE>, |
| @@ -447,7 +441,6 @@ pub struct BufferedCan<'d, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize> { | |||
| 447 | impl<'c, 'd, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize> BufferedCan<'d, TX_BUF_SIZE, RX_BUF_SIZE> { | 441 | impl<'c, 'd, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize> BufferedCan<'d, TX_BUF_SIZE, RX_BUF_SIZE> { |
| 448 | fn new( | 442 | fn new( |
| 449 | info: &'static Info, | 443 | info: &'static Info, |
| 450 | state: &'static State, | ||
| 451 | _mode: OperatingMode, | 444 | _mode: OperatingMode, |
| 452 | tx_buf: &'static TxBuf<TX_BUF_SIZE>, | 445 | tx_buf: &'static TxBuf<TX_BUF_SIZE>, |
| 453 | rx_buf: &'static RxBuf<RX_BUF_SIZE>, | 446 | rx_buf: &'static RxBuf<RX_BUF_SIZE>, |
| @@ -457,7 +450,6 @@ impl<'c, 'd, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize> BufferedCan<'d, | |||
| 457 | BufferedCan { | 450 | BufferedCan { |
| 458 | _phantom: PhantomData, | 451 | _phantom: PhantomData, |
| 459 | info, | 452 | info, |
| 460 | state, | ||
| 461 | _mode, | 453 | _mode, |
| 462 | tx_buf, | 454 | tx_buf, |
| 463 | rx_buf, | 455 | rx_buf, |
| @@ -473,19 +465,15 @@ impl<'c, 'd, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize> BufferedCan<'d, | |||
| 473 | 465 | ||
| 474 | fn setup(self) -> Self { | 466 | fn setup(self) -> Self { |
| 475 | // We don't want interrupts being processed while we change modes. | 467 | // We don't want interrupts being processed while we change modes. |
| 476 | critical_section::with(|_| { | 468 | self.info.state.lock(|s| { |
| 477 | let rx_inner = super::common::ClassicBufferedRxInner { | 469 | let rx_inner = super::common::ClassicBufferedRxInner { |
| 478 | rx_sender: self.rx_buf.sender().into(), | 470 | rx_sender: self.rx_buf.sender().into(), |
| 479 | }; | 471 | }; |
| 480 | let tx_inner = super::common::ClassicBufferedTxInner { | 472 | let tx_inner = super::common::ClassicBufferedTxInner { |
| 481 | tx_receiver: self.tx_buf.receiver().into(), | 473 | tx_receiver: self.tx_buf.receiver().into(), |
| 482 | }; | 474 | }; |
| 483 | let state = self.state as *const State; | 475 | s.borrow_mut().rx_mode = RxMode::ClassicBuffered(rx_inner); |
| 484 | unsafe { | 476 | s.borrow_mut().tx_mode = TxMode::ClassicBuffered(tx_inner); |
| 485 | let mut_state = state as *mut State; | ||
| 486 | (*mut_state).rx_mode = RxMode::ClassicBuffered(rx_inner); | ||
| 487 | (*mut_state).tx_mode = TxMode::ClassicBuffered(tx_inner); | ||
| 488 | } | ||
| 489 | }); | 477 | }); |
| 490 | self | 478 | self |
| 491 | } | 479 | } |
| @@ -545,7 +533,6 @@ pub type BufferedFdCanReceiver = super::common::BufferedReceiver<'static, FdEnve | |||
| 545 | pub struct BufferedCanFd<'d, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize> { | 533 | pub struct BufferedCanFd<'d, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize> { |
| 546 | _phantom: PhantomData<&'d ()>, | 534 | _phantom: PhantomData<&'d ()>, |
| 547 | info: &'static Info, | 535 | info: &'static Info, |
| 548 | state: &'static State, | ||
| 549 | _mode: OperatingMode, | 536 | _mode: OperatingMode, |
| 550 | tx_buf: &'static TxFdBuf<TX_BUF_SIZE>, | 537 | tx_buf: &'static TxFdBuf<TX_BUF_SIZE>, |
| 551 | rx_buf: &'static RxFdBuf<RX_BUF_SIZE>, | 538 | rx_buf: &'static RxFdBuf<RX_BUF_SIZE>, |
| @@ -555,7 +542,6 @@ pub struct BufferedCanFd<'d, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize> | |||
| 555 | impl<'c, 'd, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize> BufferedCanFd<'d, TX_BUF_SIZE, RX_BUF_SIZE> { | 542 | impl<'c, 'd, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize> BufferedCanFd<'d, TX_BUF_SIZE, RX_BUF_SIZE> { |
| 556 | fn new( | 543 | fn new( |
| 557 | info: &'static Info, | 544 | info: &'static Info, |
| 558 | state: &'static State, | ||
| 559 | _mode: OperatingMode, | 545 | _mode: OperatingMode, |
| 560 | tx_buf: &'static TxFdBuf<TX_BUF_SIZE>, | 546 | tx_buf: &'static TxFdBuf<TX_BUF_SIZE>, |
| 561 | rx_buf: &'static RxFdBuf<RX_BUF_SIZE>, | 547 | rx_buf: &'static RxFdBuf<RX_BUF_SIZE>, |
| @@ -565,7 +551,6 @@ impl<'c, 'd, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize> BufferedCanFd<' | |||
| 565 | BufferedCanFd { | 551 | BufferedCanFd { |
| 566 | _phantom: PhantomData, | 552 | _phantom: PhantomData, |
| 567 | info, | 553 | info, |
| 568 | state, | ||
| 569 | _mode, | 554 | _mode, |
| 570 | tx_buf, | 555 | tx_buf, |
| 571 | rx_buf, | 556 | rx_buf, |
| @@ -581,19 +566,15 @@ impl<'c, 'd, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize> BufferedCanFd<' | |||
| 581 | 566 | ||
| 582 | fn setup(self) -> Self { | 567 | fn setup(self) -> Self { |
| 583 | // We don't want interrupts being processed while we change modes. | 568 | // We don't want interrupts being processed while we change modes. |
| 584 | critical_section::with(|_| { | 569 | self.info.state.lock(|s| { |
| 585 | let rx_inner = super::common::FdBufferedRxInner { | 570 | let rx_inner = super::common::FdBufferedRxInner { |
| 586 | rx_sender: self.rx_buf.sender().into(), | 571 | rx_sender: self.rx_buf.sender().into(), |
| 587 | }; | 572 | }; |
| 588 | let tx_inner = super::common::FdBufferedTxInner { | 573 | let tx_inner = super::common::FdBufferedTxInner { |
| 589 | tx_receiver: self.tx_buf.receiver().into(), | 574 | tx_receiver: self.tx_buf.receiver().into(), |
| 590 | }; | 575 | }; |
| 591 | let state = self.state as *const State; | 576 | s.borrow_mut().rx_mode = RxMode::FdBuffered(rx_inner); |
| 592 | unsafe { | 577 | s.borrow_mut().tx_mode = TxMode::FdBuffered(tx_inner); |
| 593 | let mut_state = state as *mut State; | ||
| 594 | (*mut_state).rx_mode = RxMode::FdBuffered(rx_inner); | ||
| 595 | (*mut_state).tx_mode = TxMode::FdBuffered(tx_inner); | ||
| 596 | } | ||
| 597 | }); | 578 | }); |
| 598 | self | 579 | self |
| 599 | } | 580 | } |
| @@ -641,19 +622,18 @@ impl<'c, 'd, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize> Drop for Buffer | |||
| 641 | pub struct CanRx<'d> { | 622 | pub struct CanRx<'d> { |
| 642 | _phantom: PhantomData<&'d ()>, | 623 | _phantom: PhantomData<&'d ()>, |
| 643 | info: &'static Info, | 624 | info: &'static Info, |
| 644 | state: &'static State, | ||
| 645 | _mode: OperatingMode, | 625 | _mode: OperatingMode, |
| 646 | } | 626 | } |
| 647 | 627 | ||
| 648 | impl<'d> CanRx<'d> { | 628 | impl<'d> CanRx<'d> { |
| 649 | /// Returns the next received message frame | 629 | /// Returns the next received message frame |
| 650 | pub async fn read(&mut self) -> Result<Envelope, BusError> { | 630 | pub async fn read(&mut self) -> Result<Envelope, BusError> { |
| 651 | self.state.rx_mode.read_classic(&self.info, &self.state).await | 631 | RxMode::read_classic(&self.info).await |
| 652 | } | 632 | } |
| 653 | 633 | ||
| 654 | /// Returns the next received message frame | 634 | /// Returns the next received message frame |
| 655 | pub async fn read_fd(&mut self) -> Result<FdEnvelope, BusError> { | 635 | pub async fn read_fd(&mut self) -> Result<FdEnvelope, BusError> { |
| 656 | self.state.rx_mode.read_fd(&self.info, &self.state).await | 636 | RxMode::read_fd(&self.info).await |
| 657 | } | 637 | } |
| 658 | } | 638 | } |
| 659 | 639 | ||
| @@ -667,7 +647,6 @@ impl<'d> Drop for CanRx<'d> { | |||
| 667 | pub struct CanTx<'d> { | 647 | pub struct CanTx<'d> { |
| 668 | _phantom: PhantomData<&'d ()>, | 648 | _phantom: PhantomData<&'d ()>, |
| 669 | info: &'static Info, | 649 | info: &'static Info, |
| 670 | state: &'static State, | ||
| 671 | config: crate::can::fd::config::FdCanConfig, | 650 | config: crate::can::fd::config::FdCanConfig, |
| 672 | _mode: OperatingMode, | 651 | _mode: OperatingMode, |
| 673 | } | 652 | } |
| @@ -678,7 +657,7 @@ impl<'c, 'd> CanTx<'d> { | |||
| 678 | /// can be replaced, this call asynchronously waits for a frame to be successfully | 657 | /// can be replaced, this call asynchronously waits for a frame to be successfully |
| 679 | /// transmitted, then tries again. | 658 | /// transmitted, then tries again. |
| 680 | pub async fn write(&mut self, frame: &Frame) -> Option<Frame> { | 659 | pub async fn write(&mut self, frame: &Frame) -> Option<Frame> { |
| 681 | self.state.tx_mode.write(self.info, frame).await | 660 | TxMode::write(self.info, frame).await |
| 682 | } | 661 | } |
| 683 | 662 | ||
| 684 | /// Queues the message to be sent but exerts backpressure. If a lower-priority | 663 | /// Queues the message to be sent but exerts backpressure. If a lower-priority |
| @@ -686,7 +665,7 @@ impl<'c, 'd> CanTx<'d> { | |||
| 686 | /// can be replaced, this call asynchronously waits for a frame to be successfully | 665 | /// can be replaced, this call asynchronously waits for a frame to be successfully |
| 687 | /// transmitted, then tries again. | 666 | /// transmitted, then tries again. |
| 688 | pub async fn write_fd(&mut self, frame: &FdFrame) -> Option<FdFrame> { | 667 | pub async fn write_fd(&mut self, frame: &FdFrame) -> Option<FdFrame> { |
| 689 | self.state.tx_mode.write_fd(self.info, frame).await | 668 | TxMode::write_fd(self.info, frame).await |
| 690 | } | 669 | } |
| 691 | } | 670 | } |
| 692 | 671 | ||
| @@ -712,19 +691,19 @@ impl RxMode { | |||
| 712 | } | 691 | } |
| 713 | } | 692 | } |
| 714 | 693 | ||
| 715 | fn on_interrupt<T: Instance>(&self, fifonr: usize) { | 694 | fn on_interrupt<T: Instance>(&self, fifonr: usize, ns_per_timer_tick: u64) { |
| 716 | T::registers().regs.ir().write(|w| w.set_rfn(fifonr, true)); | 695 | T::registers().regs.ir().write(|w| w.set_rfn(fifonr, true)); |
| 717 | match self { | 696 | match self { |
| 718 | RxMode::NonBuffered(waker) => { | 697 | RxMode::NonBuffered(waker) => { |
| 719 | waker.wake(); | 698 | waker.wake(); |
| 720 | } | 699 | } |
| 721 | RxMode::ClassicBuffered(buf) => { | 700 | RxMode::ClassicBuffered(buf) => { |
| 722 | if let Some(result) = self.try_read::<T>() { | 701 | if let Some(result) = self.try_read::<T>(ns_per_timer_tick) { |
| 723 | let _ = buf.rx_sender.try_send(result); | 702 | let _ = buf.rx_sender.try_send(result); |
| 724 | } | 703 | } |
| 725 | } | 704 | } |
| 726 | RxMode::FdBuffered(buf) => { | 705 | RxMode::FdBuffered(buf) => { |
| 727 | if let Some(result) = self.try_read_fd::<T>() { | 706 | if let Some(result) = self.try_read_fd::<T>(ns_per_timer_tick) { |
| 728 | let _ = buf.rx_sender.try_send(result); | 707 | let _ = buf.rx_sender.try_send(result); |
| 729 | } | 708 | } |
| 730 | } | 709 | } |
| @@ -732,12 +711,12 @@ impl RxMode { | |||
| 732 | } | 711 | } |
| 733 | 712 | ||
| 734 | //async fn read_classic<T: Instance>(&self) -> Result<Envelope, BusError> { | 713 | //async fn read_classic<T: Instance>(&self) -> Result<Envelope, BusError> { |
| 735 | fn try_read<T: Instance>(&self) -> Option<Result<Envelope, BusError>> { | 714 | fn try_read<T: Instance>(&self, ns_per_timer_tick: u64) -> Option<Result<Envelope, BusError>> { |
| 736 | if let Some((frame, ts)) = T::registers().read(0) { | 715 | if let Some((frame, ts)) = T::registers().read(0) { |
| 737 | let ts = T::calc_timestamp(T::state().ns_per_timer_tick, ts); | 716 | let ts = T::calc_timestamp(ns_per_timer_tick, ts); |
| 738 | Some(Ok(Envelope { ts, frame })) | 717 | Some(Ok(Envelope { ts, frame })) |
| 739 | } else if let Some((frame, ts)) = T::registers().read(1) { | 718 | } else if let Some((frame, ts)) = T::registers().read(1) { |
| 740 | let ts = T::calc_timestamp(T::state().ns_per_timer_tick, ts); | 719 | let ts = T::calc_timestamp(ns_per_timer_tick, ts); |
| 741 | Some(Ok(Envelope { ts, frame })) | 720 | Some(Ok(Envelope { ts, frame })) |
| 742 | } else if let Some(err) = T::registers().curr_error() { | 721 | } else if let Some(err) = T::registers().curr_error() { |
| 743 | // TODO: this is probably wrong | 722 | // TODO: this is probably wrong |
| @@ -747,12 +726,12 @@ impl RxMode { | |||
| 747 | } | 726 | } |
| 748 | } | 727 | } |
| 749 | 728 | ||
| 750 | fn try_read_fd<T: Instance>(&self) -> Option<Result<FdEnvelope, BusError>> { | 729 | fn try_read_fd<T: Instance>(&self, ns_per_timer_tick: u64) -> Option<Result<FdEnvelope, BusError>> { |
| 751 | if let Some((frame, ts)) = T::registers().read(0) { | 730 | if let Some((frame, ts)) = T::registers().read(0) { |
| 752 | let ts = T::calc_timestamp(T::state().ns_per_timer_tick, ts); | 731 | let ts = T::calc_timestamp(ns_per_timer_tick, ts); |
| 753 | Some(Ok(FdEnvelope { ts, frame })) | 732 | Some(Ok(FdEnvelope { ts, frame })) |
| 754 | } else if let Some((frame, ts)) = T::registers().read(1) { | 733 | } else if let Some((frame, ts)) = T::registers().read(1) { |
| 755 | let ts = T::calc_timestamp(T::state().ns_per_timer_tick, ts); | 734 | let ts = T::calc_timestamp(ns_per_timer_tick, ts); |
| 756 | Some(Ok(FdEnvelope { ts, frame })) | 735 | Some(Ok(FdEnvelope { ts, frame })) |
| 757 | } else if let Some(err) = T::registers().curr_error() { | 736 | } else if let Some(err) = T::registers().curr_error() { |
| 758 | // TODO: this is probably wrong | 737 | // TODO: this is probably wrong |
| @@ -762,16 +741,12 @@ impl RxMode { | |||
| 762 | } | 741 | } |
| 763 | } | 742 | } |
| 764 | 743 | ||
| 765 | fn read<F: CanHeader>( | 744 | fn read<F: CanHeader>(info: &'static Info, ns_per_timer_tick: u64) -> Option<Result<(F, Timestamp), BusError>> { |
| 766 | &self, | ||
| 767 | info: &'static Info, | ||
| 768 | state: &'static State, | ||
| 769 | ) -> Option<Result<(F, Timestamp), BusError>> { | ||
| 770 | if let Some((msg, ts)) = info.regs.read(0) { | 745 | if let Some((msg, ts)) = info.regs.read(0) { |
| 771 | let ts = info.calc_timestamp(state.ns_per_timer_tick, ts); | 746 | let ts = info.calc_timestamp(ns_per_timer_tick, ts); |
| 772 | Some(Ok((msg, ts))) | 747 | Some(Ok((msg, ts))) |
| 773 | } else if let Some((msg, ts)) = info.regs.read(1) { | 748 | } else if let Some((msg, ts)) = info.regs.read(1) { |
| 774 | let ts = info.calc_timestamp(state.ns_per_timer_tick, ts); | 749 | let ts = info.calc_timestamp(ns_per_timer_tick, ts); |
| 775 | Some(Ok((msg, ts))) | 750 | Some(Ok((msg, ts))) |
| 776 | } else if let Some(err) = info.regs.curr_error() { | 751 | } else if let Some(err) = info.regs.curr_error() { |
| 777 | // TODO: this is probably wrong | 752 | // TODO: this is probably wrong |
| @@ -781,16 +756,15 @@ impl RxMode { | |||
| 781 | } | 756 | } |
| 782 | } | 757 | } |
| 783 | 758 | ||
| 784 | async fn read_async<F: CanHeader>( | 759 | async fn read_async<F: CanHeader>(info: &'static Info) -> Result<(F, Timestamp), BusError> { |
| 785 | &self, | ||
| 786 | info: &'static Info, | ||
| 787 | state: &'static State, | ||
| 788 | ) -> Result<(F, Timestamp), BusError> { | ||
| 789 | //let _ = self.read::<F>(info, state); | ||
| 790 | poll_fn(move |cx| { | 760 | poll_fn(move |cx| { |
| 791 | state.err_waker.register(cx.waker()); | 761 | let ns_per_timer_tick = info.state.lock(|s| { |
| 792 | self.register(cx.waker()); | 762 | let state = s.borrow_mut(); |
| 793 | match self.read::<_>(info, state) { | 763 | state.err_waker.register(cx.waker()); |
| 764 | state.rx_mode.register(cx.waker()); | ||
| 765 | state.ns_per_timer_tick | ||
| 766 | }); | ||
| 767 | match RxMode::read::<_>(info, ns_per_timer_tick) { | ||
| 794 | Some(result) => Poll::Ready(result), | 768 | Some(result) => Poll::Ready(result), |
| 795 | None => Poll::Pending, | 769 | None => Poll::Pending, |
| 796 | } | 770 | } |
| @@ -798,15 +772,15 @@ impl RxMode { | |||
| 798 | .await | 772 | .await |
| 799 | } | 773 | } |
| 800 | 774 | ||
| 801 | async fn read_classic(&self, info: &'static Info, state: &'static State) -> Result<Envelope, BusError> { | 775 | async fn read_classic(info: &'static Info) -> Result<Envelope, BusError> { |
| 802 | match self.read_async::<_>(info, state).await { | 776 | match RxMode::read_async::<_>(info).await { |
| 803 | Ok((frame, ts)) => Ok(Envelope { ts, frame }), | 777 | Ok((frame, ts)) => Ok(Envelope { ts, frame }), |
| 804 | Err(e) => Err(e), | 778 | Err(e) => Err(e), |
| 805 | } | 779 | } |
| 806 | } | 780 | } |
| 807 | 781 | ||
| 808 | async fn read_fd(&self, info: &'static Info, state: &'static State) -> Result<FdEnvelope, BusError> { | 782 | async fn read_fd(info: &'static Info) -> Result<FdEnvelope, BusError> { |
| 809 | match self.read_async::<_>(info, state).await { | 783 | match RxMode::read_async::<_>(info).await { |
| 810 | Ok((frame, ts)) => Ok(FdEnvelope { ts, frame }), | 784 | Ok((frame, ts)) => Ok(FdEnvelope { ts, frame }), |
| 811 | Err(e) => Err(e), | 785 | Err(e) => Err(e), |
| 812 | } | 786 | } |
| @@ -835,9 +809,11 @@ impl TxMode { | |||
| 835 | /// frame is dropped from the mailbox, it is returned. If no lower-priority frames | 809 | /// frame is dropped from the mailbox, it is returned. If no lower-priority frames |
| 836 | /// can be replaced, this call asynchronously waits for a frame to be successfully | 810 | /// can be replaced, this call asynchronously waits for a frame to be successfully |
| 837 | /// transmitted, then tries again. | 811 | /// transmitted, then tries again. |
| 838 | async fn write_generic<F: embedded_can::Frame + CanHeader>(&self, info: &'static Info, frame: &F) -> Option<F> { | 812 | async fn write_generic<F: embedded_can::Frame + CanHeader>(info: &'static Info, frame: &F) -> Option<F> { |
| 839 | poll_fn(|cx| { | 813 | poll_fn(|cx| { |
| 840 | self.register(cx.waker()); | 814 | info.state.lock(|s| { |
| 815 | s.borrow_mut().tx_mode.register(cx.waker()); | ||
| 816 | }); | ||
| 841 | 817 | ||
| 842 | if let Ok(dropped) = info.regs.write(frame) { | 818 | if let Ok(dropped) = info.regs.write(frame) { |
| 843 | return Poll::Ready(dropped); | 819 | return Poll::Ready(dropped); |
| @@ -854,16 +830,16 @@ impl TxMode { | |||
| 854 | /// frame is dropped from the mailbox, it is returned. If no lower-priority frames | 830 | /// frame is dropped from the mailbox, it is returned. If no lower-priority frames |
| 855 | /// can be replaced, this call asynchronously waits for a frame to be successfully | 831 | /// can be replaced, this call asynchronously waits for a frame to be successfully |
| 856 | /// transmitted, then tries again. | 832 | /// transmitted, then tries again. |
| 857 | async fn write(&self, info: &'static Info, frame: &Frame) -> Option<Frame> { | 833 | async fn write(info: &'static Info, frame: &Frame) -> Option<Frame> { |
| 858 | self.write_generic::<_>(info, frame).await | 834 | TxMode::write_generic::<_>(info, frame).await |
| 859 | } | 835 | } |
| 860 | 836 | ||
| 861 | /// Queues the message to be sent but exerts backpressure. If a lower-priority | 837 | /// Queues the message to be sent but exerts backpressure. If a lower-priority |
| 862 | /// frame is dropped from the mailbox, it is returned. If no lower-priority frames | 838 | /// frame is dropped from the mailbox, it is returned. If no lower-priority frames |
| 863 | /// can be replaced, this call asynchronously waits for a frame to be successfully | 839 | /// can be replaced, this call asynchronously waits for a frame to be successfully |
| 864 | /// transmitted, then tries again. | 840 | /// transmitted, then tries again. |
| 865 | async fn write_fd(&self, info: &'static Info, frame: &FdFrame) -> Option<FdFrame> { | 841 | async fn write_fd(info: &'static Info, frame: &FdFrame) -> Option<FdFrame> { |
| 866 | self.write_generic::<_>(info, frame).await | 842 | TxMode::write_generic::<_>(info, frame).await |
| 867 | } | 843 | } |
| 868 | } | 844 | } |
| 869 | 845 | ||
| @@ -961,12 +937,14 @@ impl State { | |||
| 961 | } | 937 | } |
| 962 | } | 938 | } |
| 963 | 939 | ||
| 940 | type SharedState = embassy_sync::blocking_mutex::Mutex<CriticalSectionRawMutex, core::cell::RefCell<State>>; | ||
| 964 | struct Info { | 941 | struct Info { |
| 965 | regs: Registers, | 942 | regs: Registers, |
| 966 | interrupt0: crate::interrupt::Interrupt, | 943 | interrupt0: crate::interrupt::Interrupt, |
| 967 | _interrupt1: crate::interrupt::Interrupt, | 944 | _interrupt1: crate::interrupt::Interrupt, |
| 968 | tx_waker: fn(), | 945 | tx_waker: fn(), |
| 969 | internal_operation: fn(InternalOperation), | 946 | internal_operation: fn(InternalOperation), |
| 947 | state: SharedState, | ||
| 970 | } | 948 | } |
| 971 | 949 | ||
| 972 | impl Info { | 950 | impl Info { |
| @@ -993,8 +971,6 @@ trait SealedInstance { | |||
| 993 | 971 | ||
| 994 | fn info() -> &'static Info; | 972 | fn info() -> &'static Info; |
| 995 | fn registers() -> crate::can::fd::peripheral::Registers; | 973 | fn registers() -> crate::can::fd::peripheral::Registers; |
| 996 | fn state() -> &'static State; | ||
| 997 | unsafe fn mut_state() -> &'static mut State; | ||
| 998 | fn internal_operation(val: InternalOperation); | 974 | fn internal_operation(val: InternalOperation); |
| 999 | fn calc_timestamp(ns_per_timer_tick: u64, ts_val: u16) -> Timestamp; | 975 | fn calc_timestamp(ns_per_timer_tick: u64, ts_val: u16) -> Timestamp; |
| 1000 | } | 976 | } |
| @@ -1019,32 +995,30 @@ macro_rules! impl_fdcan { | |||
| 1019 | const MSG_RAM_OFFSET: usize = $msg_ram_offset; | 995 | const MSG_RAM_OFFSET: usize = $msg_ram_offset; |
| 1020 | 996 | ||
| 1021 | fn internal_operation(val: InternalOperation) { | 997 | fn internal_operation(val: InternalOperation) { |
| 1022 | critical_section::with(|_| { | 998 | peripherals::$inst::info().state.lock(|s| { |
| 1023 | //let state = self.state as *const State; | 999 | let mut mut_state = s.borrow_mut(); |
| 1024 | unsafe { | 1000 | match val { |
| 1025 | //let mut_state = state as *mut State; | 1001 | InternalOperation::NotifySenderCreated => { |
| 1026 | let mut_state = peripherals::$inst::mut_state(); | 1002 | mut_state.sender_instance_count += 1; |
| 1027 | match val { | 1003 | } |
| 1028 | InternalOperation::NotifySenderCreated => { | 1004 | InternalOperation::NotifySenderDestroyed => { |
| 1029 | mut_state.sender_instance_count += 1; | 1005 | mut_state.sender_instance_count -= 1; |
| 1030 | } | 1006 | if ( 0 == mut_state.sender_instance_count) { |
| 1031 | InternalOperation::NotifySenderDestroyed => { | 1007 | (*mut_state).tx_mode = TxMode::NonBuffered(embassy_sync::waitqueue::AtomicWaker::new()); |
| 1032 | mut_state.sender_instance_count -= 1; | ||
| 1033 | if ( 0 == mut_state.sender_instance_count) { | ||
| 1034 | (*mut_state).tx_mode = TxMode::NonBuffered(embassy_sync::waitqueue::AtomicWaker::new()); | ||
| 1035 | } | ||
| 1036 | } | ||
| 1037 | InternalOperation::NotifyReceiverCreated => { | ||
| 1038 | mut_state.receiver_instance_count += 1; | ||
| 1039 | } | 1008 | } |
| 1040 | InternalOperation::NotifyReceiverDestroyed => { | 1009 | } |
| 1041 | mut_state.receiver_instance_count -= 1; | 1010 | InternalOperation::NotifyReceiverCreated => { |
| 1042 | if ( 0 == mut_state.receiver_instance_count) { | 1011 | mut_state.receiver_instance_count += 1; |
| 1043 | (*mut_state).rx_mode = RxMode::NonBuffered(embassy_sync::waitqueue::AtomicWaker::new()); | 1012 | } |
| 1044 | } | 1013 | InternalOperation::NotifyReceiverDestroyed => { |
| 1014 | mut_state.receiver_instance_count -= 1; | ||
| 1015 | if ( 0 == mut_state.receiver_instance_count) { | ||
| 1016 | (*mut_state).rx_mode = RxMode::NonBuffered(embassy_sync::waitqueue::AtomicWaker::new()); | ||
| 1045 | } | 1017 | } |
| 1046 | } | 1018 | } |
| 1047 | if mut_state.sender_instance_count == 0 && mut_state.receiver_instance_count == 0 { | 1019 | } |
| 1020 | if mut_state.sender_instance_count == 0 && mut_state.receiver_instance_count == 0 { | ||
| 1021 | unsafe { | ||
| 1048 | let tx_pin = crate::gpio::AnyPin::steal(mut_state.tx_pin_port.unwrap()); | 1022 | let tx_pin = crate::gpio::AnyPin::steal(mut_state.tx_pin_port.unwrap()); |
| 1049 | tx_pin.set_as_disconnected(); | 1023 | tx_pin.set_as_disconnected(); |
| 1050 | let rx_pin = crate::gpio::AnyPin::steal(mut_state.rx_pin_port.unwrap()); | 1024 | let rx_pin = crate::gpio::AnyPin::steal(mut_state.rx_pin_port.unwrap()); |
| @@ -1054,26 +1028,22 @@ macro_rules! impl_fdcan { | |||
| 1054 | } | 1028 | } |
| 1055 | }); | 1029 | }); |
| 1056 | } | 1030 | } |
| 1031 | |||
| 1057 | fn info() -> &'static Info { | 1032 | fn info() -> &'static Info { |
| 1033 | |||
| 1058 | static INFO: Info = Info { | 1034 | static INFO: Info = Info { |
| 1059 | regs: Registers{regs: crate::pac::$inst, msgram: crate::pac::$msg_ram_inst, msg_ram_offset: $msg_ram_offset}, | 1035 | regs: Registers{regs: crate::pac::$inst, msgram: crate::pac::$msg_ram_inst, msg_ram_offset: $msg_ram_offset}, |
| 1060 | interrupt0: crate::_generated::peripheral_interrupts::$inst::IT0::IRQ, | 1036 | interrupt0: crate::_generated::peripheral_interrupts::$inst::IT0::IRQ, |
| 1061 | _interrupt1: crate::_generated::peripheral_interrupts::$inst::IT1::IRQ, | 1037 | _interrupt1: crate::_generated::peripheral_interrupts::$inst::IT1::IRQ, |
| 1062 | tx_waker: crate::_generated::peripheral_interrupts::$inst::IT0::pend, | 1038 | tx_waker: crate::_generated::peripheral_interrupts::$inst::IT0::pend, |
| 1063 | internal_operation: peripherals::$inst::internal_operation, | 1039 | internal_operation: peripherals::$inst::internal_operation, |
| 1040 | state: embassy_sync::blocking_mutex::Mutex::new(core::cell::RefCell::new(State::new())), | ||
| 1064 | }; | 1041 | }; |
| 1065 | &INFO | 1042 | &INFO |
| 1066 | } | 1043 | } |
| 1067 | fn registers() -> Registers { | 1044 | fn registers() -> Registers { |
| 1068 | Registers{regs: crate::pac::$inst, msgram: crate::pac::$msg_ram_inst, msg_ram_offset: Self::MSG_RAM_OFFSET} | 1045 | Registers{regs: crate::pac::$inst, msgram: crate::pac::$msg_ram_inst, msg_ram_offset: Self::MSG_RAM_OFFSET} |
| 1069 | } | 1046 | } |
| 1070 | unsafe fn mut_state() -> &'static mut State { | ||
| 1071 | static mut STATE: State = State::new(); | ||
| 1072 | &mut *core::ptr::addr_of_mut!(STATE) | ||
| 1073 | } | ||
| 1074 | fn state() -> &'static State { | ||
| 1075 | unsafe { peripherals::$inst::mut_state() } | ||
| 1076 | } | ||
| 1077 | 1047 | ||
| 1078 | #[cfg(feature = "time")] | 1048 | #[cfg(feature = "time")] |
| 1079 | fn calc_timestamp(ns_per_timer_tick: u64, ts_val: u16) -> Timestamp { | 1049 | fn calc_timestamp(ns_per_timer_tick: u64, ts_val: u16) -> Timestamp { |
