diff options
| author | Dario Nieuwenhuis <[email protected]> | 2023-11-21 14:45:10 +0000 |
|---|---|---|
| committer | GitHub <[email protected]> | 2023-11-21 14:45:10 +0000 |
| commit | 7f1fd199bb95f150de1b51ed19c5a602e334a1b7 (patch) | |
| tree | 37bdef45f8e568c090b5265d2a8cf09ac772fd63 | |
| parent | 5ddd2cf9a6f165469a5bf207f73b26936f1d7735 (diff) | |
| parent | 88f893da4541ba42553fa14ba12845d9f3f2d133 (diff) | |
Merge pull request #2207 from mickvangelderen/split-can-bus-2
Split can bus 2
| -rw-r--r-- | embassy-stm32/src/can/bxcan.rs | 74 |
1 files changed, 41 insertions, 33 deletions
diff --git a/embassy-stm32/src/can/bxcan.rs b/embassy-stm32/src/can/bxcan.rs index 0d4bf692d..2f7417340 100644 --- a/embassy-stm32/src/can/bxcan.rs +++ b/embassy-stm32/src/can/bxcan.rs | |||
| @@ -1,4 +1,3 @@ | |||
| 1 | use core::cell::{RefCell, RefMut}; | ||
| 2 | use core::future::poll_fn; | 1 | use core::future::poll_fn; |
| 3 | use core::marker::PhantomData; | 2 | use core::marker::PhantomData; |
| 4 | use core::ops::{Deref, DerefMut}; | 3 | use core::ops::{Deref, DerefMut}; |
| @@ -84,7 +83,7 @@ impl<T: Instance> interrupt::typelevel::Handler<T::SCEInterrupt> for SceInterrup | |||
| 84 | } | 83 | } |
| 85 | 84 | ||
| 86 | pub struct Can<'d, T: Instance> { | 85 | pub struct Can<'d, T: Instance> { |
| 87 | pub can: RefCell<bxcan::Can<BxcanInstance<'d, T>>>, | 86 | pub can: bxcan::Can<BxcanInstance<'d, T>>, |
| 88 | } | 87 | } |
| 89 | 88 | ||
| 90 | #[derive(Debug)] | 89 | #[derive(Debug)] |
| @@ -175,17 +174,12 @@ impl<'d, T: Instance> Can<'d, T> { | |||
| 175 | tx.set_as_af(tx.af_num(), AFType::OutputPushPull); | 174 | tx.set_as_af(tx.af_num(), AFType::OutputPushPull); |
| 176 | 175 | ||
| 177 | let can = bxcan::Can::builder(BxcanInstance(peri)).leave_disabled(); | 176 | let can = bxcan::Can::builder(BxcanInstance(peri)).leave_disabled(); |
| 178 | let can_ref_cell = RefCell::new(can); | 177 | Self { can } |
| 179 | Self { can: can_ref_cell } | ||
| 180 | } | 178 | } |
| 181 | 179 | ||
| 182 | pub fn set_bitrate(&mut self, bitrate: u32) { | 180 | pub fn set_bitrate(&mut self, bitrate: u32) { |
| 183 | let bit_timing = Self::calc_bxcan_timings(T::frequency(), bitrate).unwrap(); | 181 | let bit_timing = Self::calc_bxcan_timings(T::frequency(), bitrate).unwrap(); |
| 184 | self.can | 182 | self.can.modify_config().set_bit_timing(bit_timing).leave_disabled(); |
| 185 | .borrow_mut() | ||
| 186 | .modify_config() | ||
| 187 | .set_bit_timing(bit_timing) | ||
| 188 | .leave_disabled(); | ||
| 189 | } | 183 | } |
| 190 | 184 | ||
| 191 | /// Enables the peripheral and synchronizes with the bus. | 185 | /// Enables the peripheral and synchronizes with the bus. |
| @@ -193,7 +187,7 @@ impl<'d, T: Instance> Can<'d, T> { | |||
| 193 | /// This will wait for 11 consecutive recessive bits (bus idle state). | 187 | /// This will wait for 11 consecutive recessive bits (bus idle state). |
| 194 | /// Contrary to enable method from bxcan library, this will not freeze the executor while waiting. | 188 | /// Contrary to enable method from bxcan library, this will not freeze the executor while waiting. |
| 195 | pub async fn enable(&mut self) { | 189 | pub async fn enable(&mut self) { |
| 196 | while self.borrow_mut().enable_non_blocking().is_err() { | 190 | while self.enable_non_blocking().is_err() { |
| 197 | // SCE interrupt is only generated for entering sleep mode, but not leaving. | 191 | // SCE interrupt is only generated for entering sleep mode, but not leaving. |
| 198 | // Yield to allow other tasks to execute while can bus is initializing. | 192 | // Yield to allow other tasks to execute while can bus is initializing. |
| 199 | embassy_futures::yield_now().await; | 193 | embassy_futures::yield_now().await; |
| @@ -202,46 +196,46 @@ impl<'d, T: Instance> Can<'d, T> { | |||
| 202 | 196 | ||
| 203 | /// Queues the message to be sent but exerts backpressure | 197 | /// Queues the message to be sent but exerts backpressure |
| 204 | pub async fn write(&mut self, frame: &Frame) -> bxcan::TransmitStatus { | 198 | pub async fn write(&mut self, frame: &Frame) -> bxcan::TransmitStatus { |
| 205 | CanTx { can: &self.can }.write(frame).await | 199 | self.split().0.write(frame).await |
| 206 | } | 200 | } |
| 207 | 201 | ||
| 208 | /// Attempts to transmit a frame without blocking. | 202 | /// Attempts to transmit a frame without blocking. |
| 209 | /// | 203 | /// |
| 210 | /// Returns [Err(TryWriteError::Full)] if all transmit mailboxes are full. | 204 | /// Returns [Err(TryWriteError::Full)] if all transmit mailboxes are full. |
| 211 | pub fn try_write(&mut self, frame: &Frame) -> Result<bxcan::TransmitStatus, TryWriteError> { | 205 | pub fn try_write(&mut self, frame: &Frame) -> Result<bxcan::TransmitStatus, TryWriteError> { |
| 212 | CanTx { can: &self.can }.try_write(frame) | 206 | self.split().0.try_write(frame) |
| 213 | } | 207 | } |
| 214 | 208 | ||
| 215 | /// Waits for a specific transmit mailbox to become empty | 209 | /// Waits for a specific transmit mailbox to become empty |
| 216 | pub async fn flush(&self, mb: bxcan::Mailbox) { | 210 | pub async fn flush(&self, mb: bxcan::Mailbox) { |
| 217 | CanTx { can: &self.can }.flush(mb).await | 211 | CanTx::<T>::flush_inner(mb).await |
| 218 | } | 212 | } |
| 219 | 213 | ||
| 220 | /// Waits until any of the transmit mailboxes become empty | 214 | /// Waits until any of the transmit mailboxes become empty |
| 221 | pub async fn flush_any(&self) { | 215 | pub async fn flush_any(&self) { |
| 222 | CanTx { can: &self.can }.flush_any().await | 216 | CanTx::<T>::flush_any_inner().await |
| 223 | } | 217 | } |
| 224 | 218 | ||
| 225 | /// Waits until all of the transmit mailboxes become empty | 219 | /// Waits until all of the transmit mailboxes become empty |
| 226 | pub async fn flush_all(&self) { | 220 | pub async fn flush_all(&self) { |
| 227 | CanTx { can: &self.can }.flush_all().await | 221 | CanTx::<T>::flush_all_inner().await |
| 228 | } | 222 | } |
| 229 | 223 | ||
| 230 | /// Returns a tuple of the time the message was received and the message frame | 224 | /// Returns a tuple of the time the message was received and the message frame |
| 231 | pub async fn read(&mut self) -> Result<Envelope, BusError> { | 225 | pub async fn read(&mut self) -> Result<Envelope, BusError> { |
| 232 | CanRx { can: &self.can }.read().await | 226 | self.split().1.read().await |
| 233 | } | 227 | } |
| 234 | 228 | ||
| 235 | /// Attempts to read a can frame without blocking. | 229 | /// Attempts to read a can frame without blocking. |
| 236 | /// | 230 | /// |
| 237 | /// Returns [Err(TryReadError::Empty)] if there are no frames in the rx queue. | 231 | /// Returns [Err(TryReadError::Empty)] if there are no frames in the rx queue. |
| 238 | pub fn try_read(&mut self) -> Result<Envelope, TryReadError> { | 232 | pub fn try_read(&mut self) -> Result<Envelope, TryReadError> { |
| 239 | CanRx { can: &self.can }.try_read() | 233 | self.split().1.try_read() |
| 240 | } | 234 | } |
| 241 | 235 | ||
| 242 | /// Waits while receive queue is empty. | 236 | /// Waits while receive queue is empty. |
| 243 | pub async fn wait_not_empty(&mut self) { | 237 | pub async fn wait_not_empty(&mut self) { |
| 244 | CanRx { can: &self.can }.wait_not_empty().await | 238 | self.split().1.wait_not_empty().await |
| 245 | } | 239 | } |
| 246 | 240 | ||
| 247 | unsafe fn receive_fifo(fifo: RxFifo) { | 241 | unsafe fn receive_fifo(fifo: RxFifo) { |
| @@ -385,24 +379,25 @@ impl<'d, T: Instance> Can<'d, T> { | |||
| 385 | Some((sjw - 1) << 24 | (bs1 as u32 - 1) << 16 | (bs2 as u32 - 1) << 20 | (prescaler - 1)) | 379 | Some((sjw - 1) << 24 | (bs1 as u32 - 1) << 16 | (bs2 as u32 - 1) << 20 | (prescaler - 1)) |
| 386 | } | 380 | } |
| 387 | 381 | ||
| 388 | pub fn split<'c>(&'c self) -> (CanTx<'c, 'd, T>, CanRx<'c, 'd, T>) { | 382 | pub fn split<'c>(&'c mut self) -> (CanTx<'c, 'd, T>, CanRx<'c, 'd, T>) { |
| 389 | (CanTx { can: &self.can }, CanRx { can: &self.can }) | 383 | let (tx, rx0, rx1) = self.can.split_by_ref(); |
| 384 | (CanTx { tx }, CanRx { rx0, rx1 }) | ||
| 390 | } | 385 | } |
| 391 | 386 | ||
| 392 | pub fn as_mut(&self) -> RefMut<'_, bxcan::Can<BxcanInstance<'d, T>>> { | 387 | pub fn as_mut(&mut self) -> &mut bxcan::Can<BxcanInstance<'d, T>> { |
| 393 | self.can.borrow_mut() | 388 | &mut self.can |
| 394 | } | 389 | } |
| 395 | } | 390 | } |
| 396 | 391 | ||
| 397 | pub struct CanTx<'c, 'd, T: Instance> { | 392 | pub struct CanTx<'c, 'd, T: Instance> { |
| 398 | can: &'c RefCell<bxcan::Can<BxcanInstance<'d, T>>>, | 393 | tx: &'c mut bxcan::Tx<BxcanInstance<'d, T>>, |
| 399 | } | 394 | } |
| 400 | 395 | ||
| 401 | impl<'c, 'd, T: Instance> CanTx<'c, 'd, T> { | 396 | impl<'c, 'd, T: Instance> CanTx<'c, 'd, T> { |
| 402 | pub async fn write(&mut self, frame: &Frame) -> bxcan::TransmitStatus { | 397 | pub async fn write(&mut self, frame: &Frame) -> bxcan::TransmitStatus { |
| 403 | poll_fn(|cx| { | 398 | poll_fn(|cx| { |
| 404 | T::state().tx_waker.register(cx.waker()); | 399 | T::state().tx_waker.register(cx.waker()); |
| 405 | if let Ok(status) = self.can.borrow_mut().transmit(frame) { | 400 | if let Ok(status) = self.tx.transmit(frame) { |
| 406 | return Poll::Ready(status); | 401 | return Poll::Ready(status); |
| 407 | } | 402 | } |
| 408 | 403 | ||
| @@ -415,11 +410,10 @@ impl<'c, 'd, T: Instance> CanTx<'c, 'd, T> { | |||
| 415 | /// | 410 | /// |
| 416 | /// Returns [Err(TryWriteError::Full)] if all transmit mailboxes are full. | 411 | /// Returns [Err(TryWriteError::Full)] if all transmit mailboxes are full. |
| 417 | pub fn try_write(&mut self, frame: &Frame) -> Result<bxcan::TransmitStatus, TryWriteError> { | 412 | pub fn try_write(&mut self, frame: &Frame) -> Result<bxcan::TransmitStatus, TryWriteError> { |
| 418 | self.can.borrow_mut().transmit(frame).map_err(|_| TryWriteError::Full) | 413 | self.tx.transmit(frame).map_err(|_| TryWriteError::Full) |
| 419 | } | 414 | } |
| 420 | 415 | ||
| 421 | /// Waits for a specific transmit mailbox to become empty | 416 | async fn flush_inner(mb: bxcan::Mailbox) { |
| 422 | pub async fn flush(&self, mb: bxcan::Mailbox) { | ||
| 423 | poll_fn(|cx| { | 417 | poll_fn(|cx| { |
| 424 | T::state().tx_waker.register(cx.waker()); | 418 | T::state().tx_waker.register(cx.waker()); |
| 425 | if T::regs().tsr().read().tme(mb.index()) { | 419 | if T::regs().tsr().read().tme(mb.index()) { |
| @@ -431,8 +425,12 @@ impl<'c, 'd, T: Instance> CanTx<'c, 'd, T> { | |||
| 431 | .await; | 425 | .await; |
| 432 | } | 426 | } |
| 433 | 427 | ||
| 434 | /// Waits until any of the transmit mailboxes become empty | 428 | /// Waits for a specific transmit mailbox to become empty |
| 435 | pub async fn flush_any(&self) { | 429 | pub async fn flush(&self, mb: bxcan::Mailbox) { |
| 430 | Self::flush_inner(mb).await | ||
| 431 | } | ||
| 432 | |||
| 433 | async fn flush_any_inner() { | ||
| 436 | poll_fn(|cx| { | 434 | poll_fn(|cx| { |
| 437 | T::state().tx_waker.register(cx.waker()); | 435 | T::state().tx_waker.register(cx.waker()); |
| 438 | 436 | ||
| @@ -449,8 +447,12 @@ impl<'c, 'd, T: Instance> CanTx<'c, 'd, T> { | |||
| 449 | .await; | 447 | .await; |
| 450 | } | 448 | } |
| 451 | 449 | ||
| 452 | /// Waits until all of the transmit mailboxes become empty | 450 | /// Waits until any of the transmit mailboxes become empty |
| 453 | pub async fn flush_all(&self) { | 451 | pub async fn flush_any(&self) { |
| 452 | Self::flush_any_inner().await | ||
| 453 | } | ||
| 454 | |||
| 455 | async fn flush_all_inner() { | ||
| 454 | poll_fn(|cx| { | 456 | poll_fn(|cx| { |
| 455 | T::state().tx_waker.register(cx.waker()); | 457 | T::state().tx_waker.register(cx.waker()); |
| 456 | 458 | ||
| @@ -466,11 +468,17 @@ impl<'c, 'd, T: Instance> CanTx<'c, 'd, T> { | |||
| 466 | }) | 468 | }) |
| 467 | .await; | 469 | .await; |
| 468 | } | 470 | } |
| 471 | |||
| 472 | /// Waits until all of the transmit mailboxes become empty | ||
| 473 | pub async fn flush_all(&self) { | ||
| 474 | Self::flush_all_inner().await | ||
| 475 | } | ||
| 469 | } | 476 | } |
| 470 | 477 | ||
| 471 | #[allow(dead_code)] | 478 | #[allow(dead_code)] |
| 472 | pub struct CanRx<'c, 'd, T: Instance> { | 479 | pub struct CanRx<'c, 'd, T: Instance> { |
| 473 | can: &'c RefCell<bxcan::Can<BxcanInstance<'d, T>>>, | 480 | rx0: &'c mut bxcan::Rx0<BxcanInstance<'d, T>>, |
| 481 | rx1: &'c mut bxcan::Rx1<BxcanInstance<'d, T>>, | ||
| 474 | } | 482 | } |
| 475 | 483 | ||
| 476 | impl<'c, 'd, T: Instance> CanRx<'c, 'd, T> { | 484 | impl<'c, 'd, T: Instance> CanRx<'c, 'd, T> { |
| @@ -538,7 +546,7 @@ impl<'d, T: Instance> Drop for Can<'d, T> { | |||
| 538 | } | 546 | } |
| 539 | 547 | ||
| 540 | impl<'d, T: Instance> Deref for Can<'d, T> { | 548 | impl<'d, T: Instance> Deref for Can<'d, T> { |
| 541 | type Target = RefCell<bxcan::Can<BxcanInstance<'d, T>>>; | 549 | type Target = bxcan::Can<BxcanInstance<'d, T>>; |
| 542 | 550 | ||
| 543 | fn deref(&self) -> &Self::Target { | 551 | fn deref(&self) -> &Self::Target { |
| 544 | &self.can | 552 | &self.can |
