diff options
| -rw-r--r-- | embassy-stm32/src/can/bxcan/mod.rs | 296 | ||||
| -rw-r--r-- | embassy-stm32/src/can/bxcan/registers.rs | 12 | ||||
| -rw-r--r-- | tests/stm32/src/bin/can.rs | 4 |
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; | |||
| 5 | use core::marker::PhantomData; | 5 | use core::marker::PhantomData; |
| 6 | use core::task::Poll; | 6 | use core::task::Poll; |
| 7 | 7 | ||
| 8 | use embassy_hal_internal::interrupt::InterruptExt; | ||
| 8 | use embassy_hal_internal::{into_ref, PeripheralRef}; | 9 | use embassy_hal_internal::{into_ref, PeripheralRef}; |
| 9 | use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex; | 10 | use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex; |
| 10 | use embassy_sync::channel::Channel; | 11 | use embassy_sync::channel::Channel; |
| @@ -154,7 +155,10 @@ impl<T: Instance> Drop for CanConfig<'_, T> { | |||
| 154 | 155 | ||
| 155 | /// CAN driver | 156 | /// CAN driver |
| 156 | pub struct Can<'d, T: Instance> { | 157 | pub 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. |
| 434 | pub struct BufferedCan<'d, T: Instance, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize> { | 464 | pub 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 | ||
| 439 | impl<'d, T: Instance, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize> BufferedCan<'d, T, TX_BUF_SIZE, RX_BUF_SIZE> { | 469 | impl<'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. |
| 474 | pub struct CanTx<'d, T: Instance> { | 504 | pub 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 | ||
| 478 | impl<'d, T: Instance> CanTx<'d, T> { | 510 | impl<'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> { | |||
| 599 | pub type TxBuf<const BUF_SIZE: usize> = Channel<CriticalSectionRawMutex, Frame, BUF_SIZE>; | 631 | pub 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. |
| 602 | pub struct BufferedCanTx<'d, T: Instance, const TX_BUF_SIZE: usize> { | 634 | pub 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 | ||
| 607 | impl<'d, T: Instance, const TX_BUF_SIZE: usize> BufferedCanTx<'d, T, TX_BUF_SIZE> { | 641 | impl<'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 | ||
| 638 | impl<'d, T: Instance, const TX_BUF_SIZE: usize> Drop for BufferedCanTx<'d, T, TX_BUF_SIZE> { | 683 | impl<'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)] |
| 648 | pub struct CanRx<'d, T: Instance> { | 697 | pub 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 | ||
| 652 | impl<'d, T: Instance> CanRx<'d, T> { | 703 | impl<'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> { | |||
| 684 | pub type RxBuf<const BUF_SIZE: usize> = Channel<CriticalSectionRawMutex, Result<Envelope, BusError>, BUF_SIZE>; | 735 | pub 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. |
| 687 | pub struct BufferedCanRx<'d, T: Instance, const RX_BUF_SIZE: usize> { | 738 | pub 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 | ||
| 692 | impl<'d, T: Instance, const RX_BUF_SIZE: usize> BufferedCanRx<'d, T, RX_BUF_SIZE> { | 745 | impl<'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 | ||
| 749 | impl<'d, T: Instance, const RX_BUF_SIZE: usize> Drop for BufferedCanRx<'d, T, RX_BUF_SIZE> { | 812 | impl<'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 | ||
| 906 | enum TxMode { | 973 | pub(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 | ||
| 946 | struct State { | 1013 | pub(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 | ||
| 1029 | pub(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 | |||
| 962 | trait SealedInstance { | 1038 | trait 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; | |||
| 19 | use can_common::*; | 19 | use can_common::*; |
| 20 | 20 | ||
| 21 | type Can<'d> = embassy_stm32::can::Can<'d, embassy_stm32::peripherals::CAN1>; | 21 | type Can<'d> = embassy_stm32::can::Can<'d, embassy_stm32::peripherals::CAN1>; |
| 22 | type CanTx<'d> = embassy_stm32::can::CanTx<'d, embassy_stm32::peripherals::CAN1>; | 22 | type CanTx<'d> = embassy_stm32::can::CanTx<'d>; |
| 23 | type CanRx<'d> = embassy_stm32::can::CanRx<'d, embassy_stm32::peripherals::CAN1>; | 23 | type CanRx<'d> = embassy_stm32::can::CanRx<'d>; |
| 24 | 24 | ||
| 25 | bind_interrupts!(struct Irqs { | 25 | bind_interrupts!(struct Irqs { |
| 26 | CAN1_RX0 => Rx0InterruptHandler<CAN1>; | 26 | CAN1_RX0 => Rx0InterruptHandler<CAN1>; |
