aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--embassy-stm32/src/can/bxcan/mod.rs296
-rw-r--r--embassy-stm32/src/can/bxcan/registers.rs12
-rw-r--r--tests/stm32/src/bin/can.rs4
3 files changed, 200 insertions, 112 deletions
diff --git a/embassy-stm32/src/can/bxcan/mod.rs b/embassy-stm32/src/can/bxcan/mod.rs
index 0ac4cdab6..4f516c917 100644
--- a/embassy-stm32/src/can/bxcan/mod.rs
+++ b/embassy-stm32/src/can/bxcan/mod.rs
@@ -5,6 +5,7 @@ use core::future::poll_fn;
5use core::marker::PhantomData; 5use core::marker::PhantomData;
6use core::task::Poll; 6use core::task::Poll;
7 7
8use embassy_hal_internal::interrupt::InterruptExt;
8use embassy_hal_internal::{into_ref, PeripheralRef}; 9use embassy_hal_internal::{into_ref, PeripheralRef};
9use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex; 10use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex;
10use embassy_sync::channel::Channel; 11use embassy_sync::channel::Channel;
@@ -154,7 +155,10 @@ impl<T: Instance> Drop for CanConfig<'_, T> {
154 155
155/// CAN driver 156/// CAN driver
156pub struct Can<'d, T: Instance> { 157pub struct Can<'d, T: Instance> {
157 peri: PeripheralRef<'d, T>, 158 _peri: PeripheralRef<'d, T>,
159 instance: &'d crate::pac::can::Can,
160 info: &'static Info,
161 state: &'static State,
158} 162}
159 163
160/// Error returned by `try_write` 164/// Error returned by `try_write`
@@ -179,6 +183,8 @@ impl<'d, T: Instance> Can<'d, T> {
179 + 'd, 183 + 'd,
180 ) -> Self { 184 ) -> Self {
181 into_ref!(peri, rx, tx); 185 into_ref!(peri, rx, tx);
186 let info = T::info();
187 let regs = &T::info().regs;
182 188
183 rx.set_as_af(rx.af_num(), AFType::Input); 189 rx.set_as_af(rx.af_num(), AFType::Input);
184 tx.set_as_af(tx.af_num(), AFType::OutputPushPull); 190 tx.set_as_af(tx.af_num(), AFType::OutputPushPull);
@@ -186,7 +192,7 @@ impl<'d, T: Instance> Can<'d, T> {
186 T::enable_and_reset(); 192 T::enable_and_reset();
187 193
188 { 194 {
189 T::regs().ier().write(|w| { 195 regs.0.ier().write(|w| {
190 w.set_errie(true); 196 w.set_errie(true);
191 w.set_fmpie(0, true); 197 w.set_fmpie(0, true);
192 w.set_fmpie(1, true); 198 w.set_fmpie(1, true);
@@ -197,7 +203,7 @@ impl<'d, T: Instance> Can<'d, T> {
197 w.set_lecie(true); 203 w.set_lecie(true);
198 }); 204 });
199 205
200 T::regs().mcr().write(|w| { 206 regs.0.mcr().write(|w| {
201 // Enable timestamps on rx messages 207 // Enable timestamps on rx messages
202 208
203 w.set_ttcm(true); 209 w.set_ttcm(true);
@@ -205,17 +211,14 @@ impl<'d, T: Instance> Can<'d, T> {
205 } 211 }
206 212
207 unsafe { 213 unsafe {
208 T::TXInterrupt::unpend(); 214 info.tx_interrupt.unpend();
209 T::TXInterrupt::enable(); 215 info.tx_interrupt.enable();
210 216 info.rx0_interrupt.unpend();
211 T::RX0Interrupt::unpend(); 217 info.rx0_interrupt.enable();
212 T::RX0Interrupt::enable(); 218 info.rx1_interrupt.unpend();
213 219 info.rx1_interrupt.enable();
214 T::RX1Interrupt::unpend(); 220 info.sce_interrupt.unpend();
215 T::RX1Interrupt::enable(); 221 info.sce_interrupt.enable();
216
217 T::SCEInterrupt::unpend();
218 T::SCEInterrupt::enable();
219 } 222 }
220 223
221 rx.set_as_af(rx.af_num(), AFType::Input); 224 rx.set_as_af(rx.af_num(), AFType::Input);
@@ -223,7 +226,12 @@ impl<'d, T: Instance> Can<'d, T> {
223 226
224 Registers(T::regs()).leave_init_mode(); 227 Registers(T::regs()).leave_init_mode();
225 228
226 Self { peri } 229 Self {
230 _peri: peri,
231 instance: &T::info().regs.0,
232 info: T::info(),
233 state: T::state(),
234 }
227 } 235 }
228 236
229 /// Set CAN bit rate. 237 /// Set CAN bit rate.
@@ -265,12 +273,12 @@ impl<'d, T: Instance> Can<'d, T> {
265 /// Waking the peripheral manually does not trigger a wake-up interrupt. 273 /// Waking the peripheral manually does not trigger a wake-up interrupt.
266 /// This will wait until the peripheral has acknowledged it has awoken from sleep mode 274 /// This will wait until the peripheral has acknowledged it has awoken from sleep mode
267 pub fn wakeup(&mut self) { 275 pub fn wakeup(&mut self) {
268 Registers(T::regs()).wakeup() 276 self.info.regs.wakeup()
269 } 277 }
270 278
271 /// Check if the peripheral is currently in sleep mode 279 /// Check if the peripheral is currently in sleep mode
272 pub fn is_sleeping(&self) -> bool { 280 pub fn is_sleeping(&self) -> bool {
273 T::regs().msr().read().slak() 281 self.info.regs.0.msr().read().slak()
274 } 282 }
275 283
276 /// Put the peripheral in sleep mode 284 /// Put the peripheral in sleep mode
@@ -282,11 +290,11 @@ impl<'d, T: Instance> Can<'d, T> {
282 /// If the peripheral has automatic wakeup enabled, when a Start-of-Frame is detected 290 /// If the peripheral has automatic wakeup enabled, when a Start-of-Frame is detected
283 /// the peripheral will automatically wake and receive the incoming message. 291 /// the peripheral will automatically wake and receive the incoming message.
284 pub async fn sleep(&mut self) { 292 pub async fn sleep(&mut self) {
285 T::regs().ier().modify(|i| i.set_slkie(true)); 293 self.info.regs.0.ier().modify(|i| i.set_slkie(true));
286 T::regs().mcr().modify(|m| m.set_sleep(true)); 294 self.info.regs.0.mcr().modify(|m| m.set_sleep(true));
287 295
288 poll_fn(|cx| { 296 poll_fn(|cx| {
289 T::state().err_waker.register(cx.waker()); 297 self.state.err_waker.register(cx.waker());
290 if self.is_sleeping() { 298 if self.is_sleeping() {
291 Poll::Ready(()) 299 Poll::Ready(())
292 } else { 300 } else {
@@ -295,7 +303,7 @@ impl<'d, T: Instance> Can<'d, T> {
295 }) 303 })
296 .await; 304 .await;
297 305
298 T::regs().ier().modify(|i| i.set_slkie(false)); 306 self.info.regs.0.ier().modify(|i| i.set_slkie(false));
299 } 307 }
300 308
301 /// Enable FIFO scheduling of outgoing frames. 309 /// Enable FIFO scheduling of outgoing frames.
@@ -337,7 +345,13 @@ impl<'d, T: Instance> Can<'d, T> {
337 345
338 /// Waits for a specific transmit mailbox to become empty 346 /// Waits for a specific transmit mailbox to become empty
339 pub async fn flush(&self, mb: Mailbox) { 347 pub async fn flush(&self, mb: Mailbox) {
340 CanTx::<T>::flush_inner(mb).await 348 CanTx {
349 _instance: &self.instance,
350 info: self.info,
351 state: self.state,
352 }
353 .flush_inner(mb)
354 .await;
341 } 355 }
342 356
343 /// Waits until any of the transmit mailboxes become empty 357 /// Waits until any of the transmit mailboxes become empty
@@ -347,12 +361,24 @@ impl<'d, T: Instance> Can<'d, T> {
347 /// This will happen if FIFO scheduling of outgoing frames is not enabled, 361 /// This will happen if FIFO scheduling of outgoing frames is not enabled,
348 /// and a frame with equal priority is already queued for transmission. 362 /// and a frame with equal priority is already queued for transmission.
349 pub async fn flush_any(&self) { 363 pub async fn flush_any(&self) {
350 CanTx::<T>::flush_any_inner().await 364 CanTx {
365 _instance: &self.instance,
366 info: self.info,
367 state: self.state,
368 }
369 .flush_any_inner()
370 .await
351 } 371 }
352 372
353 /// Waits until all of the transmit mailboxes become empty 373 /// Waits until all of the transmit mailboxes become empty
354 pub async fn flush_all(&self) { 374 pub async fn flush_all(&self) {
355 CanTx::<T>::flush_all_inner().await 375 CanTx {
376 _instance: &self.instance,
377 info: self.info,
378 state: self.state,
379 }
380 .flush_all_inner()
381 .await
356 } 382 }
357 383
358 /// Attempts to abort the sending of a frame that is pending in a mailbox. 384 /// Attempts to abort the sending of a frame that is pending in a mailbox.
@@ -363,12 +389,12 @@ impl<'d, T: Instance> Can<'d, T> {
363 /// If there is a frame in the provided mailbox, and it is canceled successfully, this function 389 /// If there is a frame in the provided mailbox, and it is canceled successfully, this function
364 /// returns `true`. 390 /// returns `true`.
365 pub fn abort(&mut self, mailbox: Mailbox) -> bool { 391 pub fn abort(&mut self, mailbox: Mailbox) -> bool {
366 Registers(T::regs()).abort(mailbox) 392 self.info.regs.abort(mailbox)
367 } 393 }
368 394
369 /// Returns `true` if no frame is pending for transmission. 395 /// Returns `true` if no frame is pending for transmission.
370 pub fn is_transmitter_idle(&self) -> bool { 396 pub fn is_transmitter_idle(&self) -> bool {
371 Registers(T::regs()).is_idle() 397 self.info.regs.is_idle()
372 } 398 }
373 399
374 /// Read a CAN frame. 400 /// Read a CAN frame.
@@ -377,31 +403,35 @@ impl<'d, T: Instance> Can<'d, T> {
377 /// 403 ///
378 /// Returns a tuple of the time the message was received and the message frame 404 /// Returns a tuple of the time the message was received and the message frame
379 pub async fn read(&mut self) -> Result<Envelope, BusError> { 405 pub async fn read(&mut self) -> Result<Envelope, BusError> {
380 T::state().rx_mode.read::<T>().await 406 self.state.rx_mode.read(self.info, self.state).await
381 } 407 }
382 408
383 /// Attempts to read a CAN frame without blocking. 409 /// Attempts to read a CAN frame without blocking.
384 /// 410 ///
385 /// Returns [Err(TryReadError::Empty)] if there are no frames in the rx queue. 411 /// Returns [Err(TryReadError::Empty)] if there are no frames in the rx queue.
386 pub fn try_read(&mut self) -> Result<Envelope, TryReadError> { 412 pub fn try_read(&mut self) -> Result<Envelope, TryReadError> {
387 T::state().rx_mode.try_read::<T>() 413 self.state.rx_mode.try_read(self.info)
388 } 414 }
389 415
390 /// Waits while receive queue is empty. 416 /// Waits while receive queue is empty.
391 pub async fn wait_not_empty(&mut self) { 417 pub async fn wait_not_empty(&mut self) {
392 T::state().rx_mode.wait_not_empty::<T>().await 418 self.state.rx_mode.wait_not_empty(self.info, self.state).await
393 } 419 }
394 420
395 /// Split the CAN driver into transmit and receive halves. 421 /// Split the CAN driver into transmit and receive halves.
396 /// 422 ///
397 /// Useful for doing separate transmit/receive tasks. 423 /// Useful for doing separate transmit/receive tasks.
398 pub fn split<'c>(&'c mut self) -> (CanTx<'d, T>, CanRx<'d, T>) { 424 pub fn split<'c>(&'c mut self) -> (CanTx<'d>, CanRx<'d>) {
399 ( 425 (
400 CanTx { 426 CanTx {
401 _peri: unsafe { self.peri.clone_unchecked() }, 427 _instance: &self.instance,
428 info: self.info,
429 state: self.state,
402 }, 430 },
403 CanRx { 431 CanRx {
404 peri: unsafe { self.peri.clone_unchecked() }, 432 instance: &self.instance,
433 info: self.info,
434 state: self.state,
405 }, 435 },
406 ) 436 )
407 } 437 }
@@ -411,7 +441,7 @@ impl<'d, T: Instance> Can<'d, T> {
411 &'c mut self, 441 &'c mut self,
412 txb: &'static mut TxBuf<TX_BUF_SIZE>, 442 txb: &'static mut TxBuf<TX_BUF_SIZE>,
413 rxb: &'static mut RxBuf<RX_BUF_SIZE>, 443 rxb: &'static mut RxBuf<RX_BUF_SIZE>,
414 ) -> BufferedCan<'d, T, TX_BUF_SIZE, RX_BUF_SIZE> { 444 ) -> BufferedCan<'d, TX_BUF_SIZE, RX_BUF_SIZE> {
415 let (tx, rx) = self.split(); 445 let (tx, rx) = self.split();
416 BufferedCan { 446 BufferedCan {
417 tx: tx.buffered(txb), 447 tx: tx.buffered(txb),
@@ -426,17 +456,17 @@ impl<'d, T: FilterOwner> Can<'d, T> {
426 /// To modify filters of a slave peripheral, `modify_filters` has to be called on the master 456 /// To modify filters of a slave peripheral, `modify_filters` has to be called on the master
427 /// peripheral instead. 457 /// peripheral instead.
428 pub fn modify_filters(&mut self) -> MasterFilters<'_, T> { 458 pub fn modify_filters(&mut self) -> MasterFilters<'_, T> {
429 unsafe { MasterFilters::new(T::regs()) } 459 unsafe { MasterFilters::new(self.info.regs.0) }
430 } 460 }
431} 461}
432 462
433/// Buffered CAN driver. 463/// Buffered CAN driver.
434pub struct BufferedCan<'d, T: Instance, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize> { 464pub struct BufferedCan<'d, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize> {
435 tx: BufferedCanTx<'d, T, TX_BUF_SIZE>, 465 tx: BufferedCanTx<'d, TX_BUF_SIZE>,
436 rx: BufferedCanRx<'d, T, RX_BUF_SIZE>, 466 rx: BufferedCanRx<'d, RX_BUF_SIZE>,
437} 467}
438 468
439impl<'d, T: Instance, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize> BufferedCan<'d, T, TX_BUF_SIZE, RX_BUF_SIZE> { 469impl<'d, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize> BufferedCan<'d, TX_BUF_SIZE, RX_BUF_SIZE> {
440 /// Async write frame to TX buffer. 470 /// Async write frame to TX buffer.
441 pub async fn write(&mut self, frame: &Frame) { 471 pub async fn write(&mut self, frame: &Frame) {
442 self.tx.write(frame).await 472 self.tx.write(frame).await
@@ -471,18 +501,20 @@ impl<'d, T: Instance, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize> Buffer
471} 501}
472 502
473/// CAN driver, transmit half. 503/// CAN driver, transmit half.
474pub struct CanTx<'d, T: Instance> { 504pub struct CanTx<'d> {
475 _peri: PeripheralRef<'d, T>, 505 _instance: &'d crate::pac::can::Can,
506 info: &'static Info,
507 state: &'static State,
476} 508}
477 509
478impl<'d, T: Instance> CanTx<'d, T> { 510impl<'d> CanTx<'d> {
479 /// Queues the message to be sent. 511 /// Queues the message to be sent.
480 /// 512 ///
481 /// If the TX queue is full, this will wait until there is space, therefore exerting backpressure. 513 /// If the TX queue is full, this will wait until there is space, therefore exerting backpressure.
482 pub async fn write(&mut self, frame: &Frame) -> TransmitStatus { 514 pub async fn write(&mut self, frame: &Frame) -> TransmitStatus {
483 poll_fn(|cx| { 515 poll_fn(|cx| {
484 T::state().tx_mode.register(cx.waker()); 516 self.state.tx_mode.register(cx.waker());
485 if let Ok(status) = Registers(T::regs()).transmit(frame) { 517 if let Ok(status) = self.info.regs.transmit(frame) {
486 return Poll::Ready(status); 518 return Poll::Ready(status);
487 } 519 }
488 520
@@ -501,13 +533,13 @@ impl<'d, T: Instance> CanTx<'d, T> {
501 /// This is done to work around a hardware limitation that could lead to out-of-order delivery 533 /// This is done to work around a hardware limitation that could lead to out-of-order delivery
502 /// of frames with the same priority. 534 /// of frames with the same priority.
503 pub fn try_write(&mut self, frame: &Frame) -> Result<TransmitStatus, TryWriteError> { 535 pub fn try_write(&mut self, frame: &Frame) -> Result<TransmitStatus, TryWriteError> {
504 Registers(T::regs()).transmit(frame).map_err(|_| TryWriteError::Full) 536 self.info.regs.transmit(frame).map_err(|_| TryWriteError::Full)
505 } 537 }
506 538
507 async fn flush_inner(mb: Mailbox) { 539 async fn flush_inner(&self, mb: Mailbox) {
508 poll_fn(|cx| { 540 poll_fn(|cx| {
509 T::state().tx_mode.register(cx.waker()); 541 self.state.tx_mode.register(cx.waker());
510 if T::regs().tsr().read().tme(mb.index()) { 542 if self.info.regs.0.tsr().read().tme(mb.index()) {
511 return Poll::Ready(()); 543 return Poll::Ready(());
512 } 544 }
513 545
@@ -518,14 +550,14 @@ impl<'d, T: Instance> CanTx<'d, T> {
518 550
519 /// Waits for a specific transmit mailbox to become empty 551 /// Waits for a specific transmit mailbox to become empty
520 pub async fn flush(&self, mb: Mailbox) { 552 pub async fn flush(&self, mb: Mailbox) {
521 Self::flush_inner(mb).await 553 self.flush_inner(mb).await
522 } 554 }
523 555
524 async fn flush_any_inner() { 556 async fn flush_any_inner(&self) {
525 poll_fn(|cx| { 557 poll_fn(|cx| {
526 T::state().tx_mode.register(cx.waker()); 558 self.state.tx_mode.register(cx.waker());
527 559
528 let tsr = T::regs().tsr().read(); 560 let tsr = self.info.regs.0.tsr().read();
529 if tsr.tme(Mailbox::Mailbox0.index()) 561 if tsr.tme(Mailbox::Mailbox0.index())
530 || tsr.tme(Mailbox::Mailbox1.index()) 562 || tsr.tme(Mailbox::Mailbox1.index())
531 || tsr.tme(Mailbox::Mailbox2.index()) 563 || tsr.tme(Mailbox::Mailbox2.index())
@@ -545,14 +577,14 @@ impl<'d, T: Instance> CanTx<'d, T> {
545 /// This will happen if FIFO scheduling of outgoing frames is not enabled, 577 /// This will happen if FIFO scheduling of outgoing frames is not enabled,
546 /// and a frame with equal priority is already queued for transmission. 578 /// and a frame with equal priority is already queued for transmission.
547 pub async fn flush_any(&self) { 579 pub async fn flush_any(&self) {
548 Self::flush_any_inner().await 580 self.flush_any_inner().await
549 } 581 }
550 582
551 async fn flush_all_inner() { 583 async fn flush_all_inner(&self) {
552 poll_fn(|cx| { 584 poll_fn(|cx| {
553 T::state().tx_mode.register(cx.waker()); 585 self.state.tx_mode.register(cx.waker());
554 586
555 let tsr = T::regs().tsr().read(); 587 let tsr = self.info.regs.0.tsr().read();
556 if tsr.tme(Mailbox::Mailbox0.index()) 588 if tsr.tme(Mailbox::Mailbox0.index())
557 && tsr.tme(Mailbox::Mailbox1.index()) 589 && tsr.tme(Mailbox::Mailbox1.index())
558 && tsr.tme(Mailbox::Mailbox2.index()) 590 && tsr.tme(Mailbox::Mailbox2.index())
@@ -567,7 +599,7 @@ impl<'d, T: Instance> CanTx<'d, T> {
567 599
568 /// Waits until all of the transmit mailboxes become empty 600 /// Waits until all of the transmit mailboxes become empty
569 pub async fn flush_all(&self) { 601 pub async fn flush_all(&self) {
570 Self::flush_all_inner().await 602 self.flush_all_inner().await
571 } 603 }
572 604
573 /// Attempts to abort the sending of a frame that is pending in a mailbox. 605 /// Attempts to abort the sending of a frame that is pending in a mailbox.
@@ -578,20 +610,20 @@ impl<'d, T: Instance> CanTx<'d, T> {
578 /// If there is a frame in the provided mailbox, and it is canceled successfully, this function 610 /// If there is a frame in the provided mailbox, and it is canceled successfully, this function
579 /// returns `true`. 611 /// returns `true`.
580 pub fn abort(&mut self, mailbox: Mailbox) -> bool { 612 pub fn abort(&mut self, mailbox: Mailbox) -> bool {
581 Registers(T::regs()).abort(mailbox) 613 self.info.regs.abort(mailbox)
582 } 614 }
583 615
584 /// Returns `true` if no frame is pending for transmission. 616 /// Returns `true` if no frame is pending for transmission.
585 pub fn is_idle(&self) -> bool { 617 pub fn is_idle(&self) -> bool {
586 Registers(T::regs()).is_idle() 618 self.info.regs.is_idle()
587 } 619 }
588 620
589 /// Return a buffered instance of driver. User must supply Buffers 621 /// Return a buffered instance of driver. User must supply Buffers
590 pub fn buffered<const TX_BUF_SIZE: usize>( 622 pub fn buffered<const TX_BUF_SIZE: usize>(
591 self, 623 self,
592 txb: &'static mut TxBuf<TX_BUF_SIZE>, 624 txb: &'static mut TxBuf<TX_BUF_SIZE>,
593 ) -> BufferedCanTx<'d, T, TX_BUF_SIZE> { 625 ) -> BufferedCanTx<'d, TX_BUF_SIZE> {
594 BufferedCanTx::new(self, txb) 626 BufferedCanTx::new(self.info, self.state, self, txb)
595 } 627 }
596} 628}
597 629
@@ -599,23 +631,35 @@ impl<'d, T: Instance> CanTx<'d, T> {
599pub type TxBuf<const BUF_SIZE: usize> = Channel<CriticalSectionRawMutex, Frame, BUF_SIZE>; 631pub type TxBuf<const BUF_SIZE: usize> = Channel<CriticalSectionRawMutex, Frame, BUF_SIZE>;
600 632
601/// Buffered CAN driver, transmit half. 633/// Buffered CAN driver, transmit half.
602pub struct BufferedCanTx<'d, T: Instance, const TX_BUF_SIZE: usize> { 634pub struct BufferedCanTx<'d, const TX_BUF_SIZE: usize> {
603 _tx: CanTx<'d, T>, 635 info: &'static Info,
636 state: &'static State,
637 _tx: CanTx<'d>,
604 tx_buf: &'static TxBuf<TX_BUF_SIZE>, 638 tx_buf: &'static TxBuf<TX_BUF_SIZE>,
605} 639}
606 640
607impl<'d, T: Instance, const TX_BUF_SIZE: usize> BufferedCanTx<'d, T, TX_BUF_SIZE> { 641impl<'d, const TX_BUF_SIZE: usize> BufferedCanTx<'d, TX_BUF_SIZE> {
608 fn new(_tx: CanTx<'d, T>, tx_buf: &'static TxBuf<TX_BUF_SIZE>) -> Self { 642 fn new(info: &'static Info, state: &'static State, _tx: CanTx<'d>, tx_buf: &'static TxBuf<TX_BUF_SIZE>) -> Self {
609 Self { _tx, tx_buf }.setup() 643 Self {
644 info,
645 state,
646 _tx,
647 tx_buf,
648 }
649 .setup()
610 } 650 }
611 651
612 fn setup(self) -> Self { 652 fn setup(self) -> Self {
613 // We don't want interrupts being processed while we change modes. 653 // We don't want interrupts being processed while we change modes.
614 critical_section::with(|_| unsafe { 654 critical_section::with(|_| {
615 let tx_inner = super::common::ClassicBufferedTxInner { 655 let tx_inner = super::common::ClassicBufferedTxInner {
616 tx_receiver: self.tx_buf.receiver().into(), 656 tx_receiver: self.tx_buf.receiver().into(),
617 }; 657 };
618 T::mut_state().tx_mode = TxMode::Buffered(tx_inner); 658 let state = self.state as *const State;
659 unsafe {
660 let mut_state = state as *mut State;
661 (*mut_state).tx_mode = TxMode::Buffered(tx_inner);
662 }
619 }); 663 });
620 self 664 self
621 } 665 }
@@ -623,60 +667,67 @@ impl<'d, T: Instance, const TX_BUF_SIZE: usize> BufferedCanTx<'d, T, TX_BUF_SIZE
623 /// Async write frame to TX buffer. 667 /// Async write frame to TX buffer.
624 pub async fn write(&mut self, frame: &Frame) { 668 pub async fn write(&mut self, frame: &Frame) {
625 self.tx_buf.send(*frame).await; 669 self.tx_buf.send(*frame).await;
626 T::TXInterrupt::pend(); // Wake for Tx 670 let waker = self.info.tx_waker;
671 waker(); // Wake for Tx
627 } 672 }
628 673
629 /// Returns a sender that can be used for sending CAN frames. 674 /// Returns a sender that can be used for sending CAN frames.
630 pub fn writer(&self) -> BufferedCanSender { 675 pub fn writer(&self) -> BufferedCanSender {
631 BufferedCanSender { 676 BufferedCanSender {
632 tx_buf: self.tx_buf.sender().into(), 677 tx_buf: self.tx_buf.sender().into(),
633 waker: T::TXInterrupt::pend, 678 waker: self.info.tx_waker,
634 } 679 }
635 } 680 }
636} 681}
637 682
638impl<'d, T: Instance, const TX_BUF_SIZE: usize> Drop for BufferedCanTx<'d, T, TX_BUF_SIZE> { 683impl<'d, const TX_BUF_SIZE: usize> Drop for BufferedCanTx<'d, TX_BUF_SIZE> {
639 fn drop(&mut self) { 684 fn drop(&mut self) {
640 critical_section::with(|_| unsafe { 685 critical_section::with(|_| {
641 T::mut_state().tx_mode = TxMode::NonBuffered(embassy_sync::waitqueue::AtomicWaker::new()); 686 let state = self.state as *const State;
687 unsafe {
688 let mut_state = state as *mut State;
689 (*mut_state).tx_mode = TxMode::NonBuffered(embassy_sync::waitqueue::AtomicWaker::new());
690 }
642 }); 691 });
643 } 692 }
644} 693}
645 694
646/// CAN driver, receive half. 695/// CAN driver, receive half.
647#[allow(dead_code)] 696#[allow(dead_code)]
648pub struct CanRx<'d, T: Instance> { 697pub struct CanRx<'d> {
649 peri: PeripheralRef<'d, T>, 698 instance: &'d crate::pac::can::Can,
699 info: &'static Info,
700 state: &'static State,
650} 701}
651 702
652impl<'d, T: Instance> CanRx<'d, T> { 703impl<'d> CanRx<'d> {
653 /// Read a CAN frame. 704 /// Read a CAN frame.
654 /// 705 ///
655 /// If no CAN frame is in the RX buffer, this will wait until there is one. 706 /// If no CAN frame is in the RX buffer, this will wait until there is one.
656 /// 707 ///
657 /// Returns a tuple of the time the message was received and the message frame 708 /// Returns a tuple of the time the message was received and the message frame
658 pub async fn read(&mut self) -> Result<Envelope, BusError> { 709 pub async fn read(&mut self) -> Result<Envelope, BusError> {
659 T::state().rx_mode.read::<T>().await 710 self.state.rx_mode.read(self.info, self.state).await
660 } 711 }
661 712
662 /// Attempts to read a CAN frame without blocking. 713 /// Attempts to read a CAN frame without blocking.
663 /// 714 ///
664 /// Returns [Err(TryReadError::Empty)] if there are no frames in the rx queue. 715 /// Returns [Err(TryReadError::Empty)] if there are no frames in the rx queue.
665 pub fn try_read(&mut self) -> Result<Envelope, TryReadError> { 716 pub fn try_read(&mut self) -> Result<Envelope, TryReadError> {
666 T::state().rx_mode.try_read::<T>() 717 self.state.rx_mode.try_read(self.info)
667 } 718 }
668 719
669 /// Waits while receive queue is empty. 720 /// Waits while receive queue is empty.
670 pub async fn wait_not_empty(&mut self) { 721 pub async fn wait_not_empty(&mut self) {
671 T::state().rx_mode.wait_not_empty::<T>().await 722 self.state.rx_mode.wait_not_empty(self.info, self.state).await
672 } 723 }
673 724
674 /// Return a buffered instance of driver. User must supply Buffers 725 /// Return a buffered instance of driver. User must supply Buffers
675 pub fn buffered<const RX_BUF_SIZE: usize>( 726 pub fn buffered<const RX_BUF_SIZE: usize>(
676 self, 727 self,
677 rxb: &'static mut RxBuf<RX_BUF_SIZE>, 728 rxb: &'static mut RxBuf<RX_BUF_SIZE>,
678 ) -> BufferedCanRx<'d, T, RX_BUF_SIZE> { 729 ) -> BufferedCanRx<'d, RX_BUF_SIZE> {
679 BufferedCanRx::new(self, rxb) 730 BufferedCanRx::new(self.info, self.state, self, rxb)
680 } 731 }
681} 732}
682 733
@@ -684,23 +735,35 @@ impl<'d, T: Instance> CanRx<'d, T> {
684pub type RxBuf<const BUF_SIZE: usize> = Channel<CriticalSectionRawMutex, Result<Envelope, BusError>, BUF_SIZE>; 735pub type RxBuf<const BUF_SIZE: usize> = Channel<CriticalSectionRawMutex, Result<Envelope, BusError>, BUF_SIZE>;
685 736
686/// CAN driver, receive half in Buffered mode. 737/// CAN driver, receive half in Buffered mode.
687pub struct BufferedCanRx<'d, T: Instance, const RX_BUF_SIZE: usize> { 738pub struct BufferedCanRx<'d, const RX_BUF_SIZE: usize> {
688 _rx: CanRx<'d, T>, 739 info: &'static Info,
740 state: &'static State,
741 _rx: CanRx<'d>,
689 rx_buf: &'static RxBuf<RX_BUF_SIZE>, 742 rx_buf: &'static RxBuf<RX_BUF_SIZE>,
690} 743}
691 744
692impl<'d, T: Instance, const RX_BUF_SIZE: usize> BufferedCanRx<'d, T, RX_BUF_SIZE> { 745impl<'d, const RX_BUF_SIZE: usize> BufferedCanRx<'d, RX_BUF_SIZE> {
693 fn new(_rx: CanRx<'d, T>, rx_buf: &'static RxBuf<RX_BUF_SIZE>) -> Self { 746 fn new(info: &'static Info, state: &'static State, _rx: CanRx<'d>, rx_buf: &'static RxBuf<RX_BUF_SIZE>) -> Self {
694 BufferedCanRx { _rx, rx_buf }.setup() 747 BufferedCanRx {
748 info,
749 state,
750 _rx,
751 rx_buf,
752 }
753 .setup()
695 } 754 }
696 755
697 fn setup(self) -> Self { 756 fn setup(self) -> Self {
698 // We don't want interrupts being processed while we change modes. 757 // We don't want interrupts being processed while we change modes.
699 critical_section::with(|_| unsafe { 758 critical_section::with(|_| {
700 let rx_inner = super::common::ClassicBufferedRxInner { 759 let rx_inner = super::common::ClassicBufferedRxInner {
701 rx_sender: self.rx_buf.sender().into(), 760 rx_sender: self.rx_buf.sender().into(),
702 }; 761 };
703 T::mut_state().rx_mode = RxMode::Buffered(rx_inner); 762 let state = self.state as *const State;
763 unsafe {
764 let mut_state = state as *mut State;
765 (*mut_state).rx_mode = RxMode::Buffered(rx_inner);
766 }
704 }); 767 });
705 self 768 self
706 } 769 }
@@ -714,7 +777,7 @@ impl<'d, T: Instance, const RX_BUF_SIZE: usize> BufferedCanRx<'d, T, RX_BUF_SIZE
714 /// 777 ///
715 /// Returns [Err(TryReadError::Empty)] if there are no frames in the rx queue. 778 /// Returns [Err(TryReadError::Empty)] if there are no frames in the rx queue.
716 pub fn try_read(&mut self) -> Result<Envelope, TryReadError> { 779 pub fn try_read(&mut self) -> Result<Envelope, TryReadError> {
717 match &T::state().rx_mode { 780 match &self.state.rx_mode {
718 RxMode::Buffered(_) => { 781 RxMode::Buffered(_) => {
719 if let Ok(result) = self.rx_buf.try_receive() { 782 if let Ok(result) = self.rx_buf.try_receive() {
720 match result { 783 match result {
@@ -722,7 +785,7 @@ impl<'d, T: Instance, const RX_BUF_SIZE: usize> BufferedCanRx<'d, T, RX_BUF_SIZE
722 Err(e) => Err(TryReadError::BusError(e)), 785 Err(e) => Err(TryReadError::BusError(e)),
723 } 786 }
724 } else { 787 } else {
725 if let Some(err) = Registers(T::regs()).curr_error() { 788 if let Some(err) = self.info.regs.curr_error() {
726 return Err(TryReadError::BusError(err)); 789 return Err(TryReadError::BusError(err));
727 } else { 790 } else {
728 Err(TryReadError::Empty) 791 Err(TryReadError::Empty)
@@ -746,10 +809,14 @@ impl<'d, T: Instance, const RX_BUF_SIZE: usize> BufferedCanRx<'d, T, RX_BUF_SIZE
746 } 809 }
747} 810}
748 811
749impl<'d, T: Instance, const RX_BUF_SIZE: usize> Drop for BufferedCanRx<'d, T, RX_BUF_SIZE> { 812impl<'d, const RX_BUF_SIZE: usize> Drop for BufferedCanRx<'d, RX_BUF_SIZE> {
750 fn drop(&mut self) { 813 fn drop(&mut self) {
751 critical_section::with(|_| unsafe { 814 critical_section::with(|_| {
752 T::mut_state().rx_mode = RxMode::NonBuffered(embassy_sync::waitqueue::AtomicWaker::new()); 815 let state = self.state as *const State;
816 unsafe {
817 let mut_state = state as *mut State;
818 (*mut_state).rx_mode = RxMode::NonBuffered(embassy_sync::waitqueue::AtomicWaker::new());
819 }
753 }); 820 });
754 } 821 }
755} 822}
@@ -839,13 +906,13 @@ impl RxMode {
839 } 906 }
840 } 907 }
841 908
842 pub async fn read<T: Instance>(&self) -> Result<Envelope, BusError> { 909 pub(crate) async fn read(&self, info: &Info, state: &State) -> Result<Envelope, BusError> {
843 match self { 910 match self {
844 Self::NonBuffered(waker) => { 911 Self::NonBuffered(waker) => {
845 poll_fn(|cx| { 912 poll_fn(|cx| {
846 T::state().err_waker.register(cx.waker()); 913 state.err_waker.register(cx.waker());
847 waker.register(cx.waker()); 914 waker.register(cx.waker());
848 match self.try_read::<T>() { 915 match self.try_read(info) {
849 Ok(result) => Poll::Ready(Ok(result)), 916 Ok(result) => Poll::Ready(Ok(result)),
850 Err(TryReadError::Empty) => Poll::Pending, 917 Err(TryReadError::Empty) => Poll::Pending,
851 Err(TryReadError::BusError(be)) => Poll::Ready(Err(be)), 918 Err(TryReadError::BusError(be)) => Poll::Ready(Err(be)),
@@ -858,17 +925,17 @@ impl RxMode {
858 } 925 }
859 } 926 }
860 } 927 }
861 pub fn try_read<T: Instance>(&self) -> Result<Envelope, TryReadError> { 928 pub(crate) fn try_read(&self, info: &Info) -> Result<Envelope, TryReadError> {
862 match self { 929 match self {
863 Self::NonBuffered(_) => { 930 Self::NonBuffered(_) => {
864 let registers = Registers(T::regs()); 931 let registers = &info.regs;
865 if let Some(msg) = registers.receive_fifo(RxFifo::Fifo0) { 932 if let Some(msg) = registers.receive_fifo(RxFifo::Fifo0) {
866 T::regs().ier().write(|w| { 933 registers.0.ier().write(|w| {
867 w.set_fmpie(0, true); 934 w.set_fmpie(0, true);
868 }); 935 });
869 Ok(msg) 936 Ok(msg)
870 } else if let Some(msg) = registers.receive_fifo(RxFifo::Fifo1) { 937 } else if let Some(msg) = registers.receive_fifo(RxFifo::Fifo1) {
871 T::regs().ier().write(|w| { 938 registers.0.ier().write(|w| {
872 w.set_fmpie(1, true); 939 w.set_fmpie(1, true);
873 }); 940 });
874 Ok(msg) 941 Ok(msg)
@@ -883,12 +950,12 @@ impl RxMode {
883 } 950 }
884 } 951 }
885 } 952 }
886 pub async fn wait_not_empty<T: Instance>(&self) { 953 pub(crate) async fn wait_not_empty(&self, info: &Info, state: &State) {
887 match &T::state().rx_mode { 954 match &state.rx_mode {
888 Self::NonBuffered(waker) => { 955 Self::NonBuffered(waker) => {
889 poll_fn(|cx| { 956 poll_fn(|cx| {
890 waker.register(cx.waker()); 957 waker.register(cx.waker());
891 if Registers(T::regs()).receive_frame_available() { 958 if info.regs.receive_frame_available() {
892 Poll::Ready(()) 959 Poll::Ready(())
893 } else { 960 } else {
894 Poll::Pending 961 Poll::Pending
@@ -903,7 +970,7 @@ impl RxMode {
903 } 970 }
904} 971}
905 972
906enum TxMode { 973pub(crate) enum TxMode {
907 NonBuffered(AtomicWaker), 974 NonBuffered(AtomicWaker),
908 Buffered(super::common::ClassicBufferedTxInner), 975 Buffered(super::common::ClassicBufferedTxInner),
909} 976}
@@ -943,7 +1010,7 @@ impl TxMode {
943 } 1010 }
944} 1011}
945 1012
946struct State { 1013pub(crate) struct State {
947 pub(crate) rx_mode: RxMode, 1014 pub(crate) rx_mode: RxMode,
948 pub(crate) tx_mode: TxMode, 1015 pub(crate) tx_mode: TxMode,
949 pub err_waker: AtomicWaker, 1016 pub err_waker: AtomicWaker,
@@ -959,7 +1026,17 @@ impl State {
959 } 1026 }
960} 1027}
961 1028
1029pub(crate) struct Info {
1030 regs: Registers,
1031 tx_interrupt: crate::interrupt::Interrupt,
1032 rx0_interrupt: crate::interrupt::Interrupt,
1033 rx1_interrupt: crate::interrupt::Interrupt,
1034 sce_interrupt: crate::interrupt::Interrupt,
1035 tx_waker: fn(),
1036}
1037
962trait SealedInstance { 1038trait SealedInstance {
1039 fn info() -> &'static Info;
963 fn regs() -> crate::pac::can::Can; 1040 fn regs() -> crate::pac::can::Can;
964 fn state() -> &'static State; 1041 fn state() -> &'static State;
965 unsafe fn mut_state() -> &'static mut State; 1042 unsafe fn mut_state() -> &'static mut State;
@@ -1012,6 +1089,17 @@ foreach_peripheral!(
1012 (can, $inst:ident) => { 1089 (can, $inst:ident) => {
1013 impl SealedInstance for peripherals::$inst { 1090 impl SealedInstance for peripherals::$inst {
1014 1091
1092 fn info() -> &'static Info {
1093 static INFO: Info = Info {
1094 regs: Registers(crate::pac::$inst),
1095 tx_interrupt: crate::_generated::peripheral_interrupts::$inst::TX::IRQ,
1096 rx0_interrupt: crate::_generated::peripheral_interrupts::$inst::RX0::IRQ,
1097 rx1_interrupt: crate::_generated::peripheral_interrupts::$inst::RX1::IRQ,
1098 sce_interrupt: crate::_generated::peripheral_interrupts::$inst::SCE::IRQ,
1099 tx_waker: crate::_generated::peripheral_interrupts::$inst::TX::pend,
1100 };
1101 &INFO
1102 }
1015 fn regs() -> crate::pac::can::Can { 1103 fn regs() -> crate::pac::can::Can {
1016 crate::pac::$inst 1104 crate::pac::$inst
1017 } 1105 }
diff --git a/embassy-stm32/src/can/bxcan/registers.rs b/embassy-stm32/src/can/bxcan/registers.rs
index ad27e0744..e7c7525d8 100644
--- a/embassy-stm32/src/can/bxcan/registers.rs
+++ b/embassy-stm32/src/can/bxcan/registers.rs
@@ -131,7 +131,7 @@ impl Registers {
131 /// Note that this will not trigger [`Interrupt::Wakeup`], only reception of an incoming CAN 131 /// Note that this will not trigger [`Interrupt::Wakeup`], only reception of an incoming CAN
132 /// frame will cause that interrupt. 132 /// frame will cause that interrupt.
133 #[allow(dead_code)] 133 #[allow(dead_code)]
134 pub fn wakeup(&mut self) { 134 pub fn wakeup(&self) {
135 self.0.mcr().modify(|reg| { 135 self.0.mcr().modify(|reg| {
136 reg.set_sleep(false); 136 reg.set_sleep(false);
137 reg.set_inrq(false); 137 reg.set_inrq(false);
@@ -216,7 +216,7 @@ impl Registers {
216 /// If FIFO scheduling is enabled, frames are transmitted in the order that they are passed to this function. 216 /// If FIFO scheduling is enabled, frames are transmitted in the order that they are passed to this function.
217 /// 217 ///
218 /// If all transmit mailboxes are full, this function returns [`nb::Error::WouldBlock`]. 218 /// If all transmit mailboxes are full, this function returns [`nb::Error::WouldBlock`].
219 pub fn transmit(&mut self, frame: &Frame) -> nb::Result<TransmitStatus, Infallible> { 219 pub fn transmit(&self, frame: &Frame) -> nb::Result<TransmitStatus, Infallible> {
220 // Check if FIFO scheduling is enabled. 220 // Check if FIFO scheduling is enabled.
221 let fifo_scheduling = self.0.mcr().read().txfp(); 221 let fifo_scheduling = self.0.mcr().read().txfp();
222 222
@@ -292,7 +292,7 @@ impl Registers {
292 Ok(()) 292 Ok(())
293 } 293 }
294 294
295 fn write_mailbox(&mut self, idx: usize, frame: &Frame) { 295 fn write_mailbox(&self, idx: usize, frame: &Frame) {
296 debug_assert!(idx < 3); 296 debug_assert!(idx < 3);
297 297
298 let mb = self.0.tx(idx); 298 let mb = self.0.tx(idx);
@@ -309,7 +309,7 @@ impl Registers {
309 }); 309 });
310 } 310 }
311 311
312 fn read_pending_mailbox(&mut self, idx: usize) -> Option<Frame> { 312 fn read_pending_mailbox(&self, idx: usize) -> Option<Frame> {
313 if self.abort_by_index(idx) { 313 if self.abort_by_index(idx) {
314 debug_assert!(idx < 3); 314 debug_assert!(idx < 3);
315 315
@@ -332,7 +332,7 @@ impl Registers {
332 } 332 }
333 333
334 /// Tries to abort a pending frame. Returns `true` when aborted. 334 /// Tries to abort a pending frame. Returns `true` when aborted.
335 fn abort_by_index(&mut self, idx: usize) -> bool { 335 fn abort_by_index(&self, idx: usize) -> bool {
336 self.0.tsr().write(|reg| reg.set_abrq(idx, true)); 336 self.0.tsr().write(|reg| reg.set_abrq(idx, true));
337 337
338 // Wait for the abort request to be finished. 338 // Wait for the abort request to be finished.
@@ -351,7 +351,7 @@ impl Registers {
351 /// 351 ///
352 /// If there is a frame in the provided mailbox, and it is canceled successfully, this function 352 /// If there is a frame in the provided mailbox, and it is canceled successfully, this function
353 /// returns `true`. 353 /// returns `true`.
354 pub fn abort(&mut self, mailbox: Mailbox) -> bool { 354 pub fn abort(&self, mailbox: Mailbox) -> bool {
355 // If the mailbox is empty, the value of TXOKx depends on what happened with the previous 355 // If the mailbox is empty, the value of TXOKx depends on what happened with the previous
356 // frame in that mailbox. Only call abort_by_index() if the mailbox is not empty. 356 // frame in that mailbox. Only call abort_by_index() if the mailbox is not empty.
357 let tsr = self.0.tsr().read(); 357 let tsr = self.0.tsr().read();
diff --git a/tests/stm32/src/bin/can.rs b/tests/stm32/src/bin/can.rs
index 004b1a729..f63076512 100644
--- a/tests/stm32/src/bin/can.rs
+++ b/tests/stm32/src/bin/can.rs
@@ -19,8 +19,8 @@ mod can_common;
19use can_common::*; 19use can_common::*;
20 20
21type Can<'d> = embassy_stm32::can::Can<'d, embassy_stm32::peripherals::CAN1>; 21type Can<'d> = embassy_stm32::can::Can<'d, embassy_stm32::peripherals::CAN1>;
22type CanTx<'d> = embassy_stm32::can::CanTx<'d, embassy_stm32::peripherals::CAN1>; 22type CanTx<'d> = embassy_stm32::can::CanTx<'d>;
23type CanRx<'d> = embassy_stm32::can::CanRx<'d, embassy_stm32::peripherals::CAN1>; 23type CanRx<'d> = embassy_stm32::can::CanRx<'d>;
24 24
25bind_interrupts!(struct Irqs { 25bind_interrupts!(struct Irqs {
26 CAN1_RX0 => Rx0InterruptHandler<CAN1>; 26 CAN1_RX0 => Rx0InterruptHandler<CAN1>;