diff options
| author | Tommas Bakker <[email protected]> | 2023-10-25 13:56:23 +0200 |
|---|---|---|
| committer | Mick van Gelderen <[email protected]> | 2023-11-21 15:34:34 +0100 |
| commit | 06a83c0f897d0fe39c59e33b14d9b4f0cd705a0b (patch) | |
| tree | 195414d16ab101e55e1d81a21e9182620c9300f0 | |
| parent | 766ec77ec5a9a5a0e4af32651c9eb0b6c8e93fed (diff) | |
Refactor bxcan split.
| -rw-r--r-- | embassy-stm32/src/can/bxcan.rs | 70 |
1 files changed, 43 insertions, 27 deletions
diff --git a/embassy-stm32/src/can/bxcan.rs b/embassy-stm32/src/can/bxcan.rs index 0d4bf692d..85dbe714f 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,14 +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 |
| 185 | .borrow_mut() | ||
| 186 | .modify_config() | 183 | .modify_config() |
| 187 | .set_bit_timing(bit_timing) | 184 | .set_bit_timing(bit_timing) |
| 188 | .leave_disabled(); | 185 | .leave_disabled(); |
| @@ -193,55 +190,56 @@ impl<'d, T: Instance> Can<'d, T> { | |||
| 193 | /// This will wait for 11 consecutive recessive bits (bus idle state). | 190 | /// 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. | 191 | /// Contrary to enable method from bxcan library, this will not freeze the executor while waiting. |
| 195 | pub async fn enable(&mut self) { | 192 | pub async fn enable(&mut self) { |
| 196 | while self.borrow_mut().enable_non_blocking().is_err() { | 193 | while self.enable_non_blocking().is_err() { |
| 197 | // SCE interrupt is only generated for entering sleep mode, but not leaving. | 194 | // 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. | 195 | // Yield to allow other tasks to execute while can bus is initializing. |
| 199 | embassy_futures::yield_now().await; | 196 | embassy_futures::yield_now().await; |
| 200 | } | 197 | } |
| 201 | } | 198 | } |
| 202 | 199 | ||
| 200 | |||
| 203 | /// Queues the message to be sent but exerts backpressure | 201 | /// Queues the message to be sent but exerts backpressure |
| 204 | pub async fn write(&mut self, frame: &Frame) -> bxcan::TransmitStatus { | 202 | pub async fn write(&mut self, frame: &Frame) -> bxcan::TransmitStatus { |
| 205 | CanTx { can: &self.can }.write(frame).await | 203 | self.split().0.write(frame).await |
| 206 | } | 204 | } |
| 207 | 205 | ||
| 208 | /// Attempts to transmit a frame without blocking. | 206 | /// Attempts to transmit a frame without blocking. |
| 209 | /// | 207 | /// |
| 210 | /// Returns [Err(TryWriteError::Full)] if all transmit mailboxes are full. | 208 | /// Returns [Err(TryWriteError::Full)] if all transmit mailboxes are full. |
| 211 | pub fn try_write(&mut self, frame: &Frame) -> Result<bxcan::TransmitStatus, TryWriteError> { | 209 | pub fn try_write(&mut self, frame: &Frame) -> Result<bxcan::TransmitStatus, TryWriteError> { |
| 212 | CanTx { can: &self.can }.try_write(frame) | 210 | self.split().0.try_write(frame) |
| 213 | } | 211 | } |
| 214 | 212 | ||
| 215 | /// Waits for a specific transmit mailbox to become empty | 213 | /// Waits for a specific transmit mailbox to become empty |
| 216 | pub async fn flush(&self, mb: bxcan::Mailbox) { | 214 | pub async fn flush(&self, mb: bxcan::Mailbox) { |
| 217 | CanTx { can: &self.can }.flush(mb).await | 215 | CanTx::<T>::_flush(mb).await |
| 218 | } | 216 | } |
| 219 | 217 | ||
| 220 | /// Waits until any of the transmit mailboxes become empty | 218 | /// Waits until any of the transmit mailboxes become empty |
| 221 | pub async fn flush_any(&self) { | 219 | pub async fn flush_any(&self) { |
| 222 | CanTx { can: &self.can }.flush_any().await | 220 | CanTx::<T>::_flush_any().await |
| 223 | } | 221 | } |
| 224 | 222 | ||
| 225 | /// Waits until all of the transmit mailboxes become empty | 223 | /// Waits until all of the transmit mailboxes become empty |
| 226 | pub async fn flush_all(&self) { | 224 | pub async fn flush_all(&self) { |
| 227 | CanTx { can: &self.can }.flush_all().await | 225 | CanTx::<T>::_flush_all().await |
| 228 | } | 226 | } |
| 229 | 227 | ||
| 230 | /// Returns a tuple of the time the message was received and the message frame | 228 | /// Returns a tuple of the time the message was received and the message frame |
| 231 | pub async fn read(&mut self) -> Result<Envelope, BusError> { | 229 | pub async fn read(&mut self) -> Result<Envelope, BusError> { |
| 232 | CanRx { can: &self.can }.read().await | 230 | self.split().1.read().await |
| 233 | } | 231 | } |
| 234 | 232 | ||
| 235 | /// Attempts to read a can frame without blocking. | 233 | /// Attempts to read a can frame without blocking. |
| 236 | /// | 234 | /// |
| 237 | /// Returns [Err(TryReadError::Empty)] if there are no frames in the rx queue. | 235 | /// Returns [Err(TryReadError::Empty)] if there are no frames in the rx queue. |
| 238 | pub fn try_read(&mut self) -> Result<Envelope, TryReadError> { | 236 | pub fn try_read(&mut self) -> Result<Envelope, TryReadError> { |
| 239 | CanRx { can: &self.can }.try_read() | 237 | self.split().1.try_read() |
| 240 | } | 238 | } |
| 241 | 239 | ||
| 242 | /// Waits while receive queue is empty. | 240 | /// Waits while receive queue is empty. |
| 243 | pub async fn wait_not_empty(&mut self) { | 241 | pub async fn wait_not_empty(&mut self) { |
| 244 | CanRx { can: &self.can }.wait_not_empty().await | 242 | self.split().1.wait_not_empty().await |
| 245 | } | 243 | } |
| 246 | 244 | ||
| 247 | unsafe fn receive_fifo(fifo: RxFifo) { | 245 | unsafe fn receive_fifo(fifo: RxFifo) { |
| @@ -385,24 +383,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)) | 383 | Some((sjw - 1) << 24 | (bs1 as u32 - 1) << 16 | (bs2 as u32 - 1) << 20 | (prescaler - 1)) |
| 386 | } | 384 | } |
| 387 | 385 | ||
| 388 | pub fn split<'c>(&'c self) -> (CanTx<'c, 'd, T>, CanRx<'c, 'd, T>) { | 386 | pub fn split<'c>(&'c mut self) -> (CanTx<'c, 'd, T>, CanRx<'c, 'd, T>) { |
| 389 | (CanTx { can: &self.can }, CanRx { can: &self.can }) | 387 | let (tx, rx0, rx1) = self.can.split_by_ref(); |
| 388 | (CanTx { tx }, CanRx { rx0, rx1 }) | ||
| 390 | } | 389 | } |
| 391 | 390 | ||
| 392 | pub fn as_mut(&self) -> RefMut<'_, bxcan::Can<BxcanInstance<'d, T>>> { | 391 | pub fn as_mut(&mut self) -> &mut bxcan::Can<BxcanInstance<'d, T>> { |
| 393 | self.can.borrow_mut() | 392 | &mut self.can |
| 394 | } | 393 | } |
| 395 | } | 394 | } |
| 396 | 395 | ||
| 397 | pub struct CanTx<'c, 'd, T: Instance> { | 396 | pub struct CanTx<'c, 'd, T: Instance> { |
| 398 | can: &'c RefCell<bxcan::Can<BxcanInstance<'d, T>>>, | 397 | tx: &'c mut bxcan::Tx<BxcanInstance<'d, T>>, |
| 399 | } | 398 | } |
| 400 | 399 | ||
| 401 | impl<'c, 'd, T: Instance> CanTx<'c, 'd, T> { | 400 | impl<'c, 'd, T: Instance> CanTx<'c, 'd, T> { |
| 402 | pub async fn write(&mut self, frame: &Frame) -> bxcan::TransmitStatus { | 401 | pub async fn write(&mut self, frame: &Frame) -> bxcan::TransmitStatus { |
| 403 | poll_fn(|cx| { | 402 | poll_fn(|cx| { |
| 404 | T::state().tx_waker.register(cx.waker()); | 403 | T::state().tx_waker.register(cx.waker()); |
| 405 | if let Ok(status) = self.can.borrow_mut().transmit(frame) { | 404 | if let Ok(status) = self.tx.transmit(frame) { |
| 406 | return Poll::Ready(status); | 405 | return Poll::Ready(status); |
| 407 | } | 406 | } |
| 408 | 407 | ||
| @@ -415,11 +414,10 @@ impl<'c, 'd, T: Instance> CanTx<'c, 'd, T> { | |||
| 415 | /// | 414 | /// |
| 416 | /// Returns [Err(TryWriteError::Full)] if all transmit mailboxes are full. | 415 | /// Returns [Err(TryWriteError::Full)] if all transmit mailboxes are full. |
| 417 | pub fn try_write(&mut self, frame: &Frame) -> Result<bxcan::TransmitStatus, TryWriteError> { | 416 | pub fn try_write(&mut self, frame: &Frame) -> Result<bxcan::TransmitStatus, TryWriteError> { |
| 418 | self.can.borrow_mut().transmit(frame).map_err(|_| TryWriteError::Full) | 417 | self.tx.transmit(frame).map_err(|_| TryWriteError::Full) |
| 419 | } | 418 | } |
| 420 | 419 | ||
| 421 | /// Waits for a specific transmit mailbox to become empty | 420 | pub async fn _flush(mb: bxcan::Mailbox) { |
| 422 | pub async fn flush(&self, mb: bxcan::Mailbox) { | ||
| 423 | poll_fn(|cx| { | 421 | poll_fn(|cx| { |
| 424 | T::state().tx_waker.register(cx.waker()); | 422 | T::state().tx_waker.register(cx.waker()); |
| 425 | if T::regs().tsr().read().tme(mb.index()) { | 423 | if T::regs().tsr().read().tme(mb.index()) { |
| @@ -431,8 +429,13 @@ impl<'c, 'd, T: Instance> CanTx<'c, 'd, T> { | |||
| 431 | .await; | 429 | .await; |
| 432 | } | 430 | } |
| 433 | 431 | ||
| 432 | /// Waits for a specific transmit mailbox to become empty | ||
| 433 | pub async fn flush(&self, mb: bxcan::Mailbox) { | ||
| 434 | Self::_flush(mb).await | ||
| 435 | } | ||
| 436 | |||
| 434 | /// Waits until any of the transmit mailboxes become empty | 437 | /// Waits until any of the transmit mailboxes become empty |
| 435 | pub async fn flush_any(&self) { | 438 | pub async fn _flush_any() { |
| 436 | poll_fn(|cx| { | 439 | poll_fn(|cx| { |
| 437 | T::state().tx_waker.register(cx.waker()); | 440 | T::state().tx_waker.register(cx.waker()); |
| 438 | 441 | ||
| @@ -449,8 +452,13 @@ impl<'c, 'd, T: Instance> CanTx<'c, 'd, T> { | |||
| 449 | .await; | 452 | .await; |
| 450 | } | 453 | } |
| 451 | 454 | ||
| 455 | /// Waits until any of the transmit mailboxes become empty | ||
| 456 | pub async fn flush_any(&self) { | ||
| 457 | Self::_flush_any().await | ||
| 458 | } | ||
| 459 | |||
| 452 | /// Waits until all of the transmit mailboxes become empty | 460 | /// Waits until all of the transmit mailboxes become empty |
| 453 | pub async fn flush_all(&self) { | 461 | pub async fn _flush_all() { |
| 454 | poll_fn(|cx| { | 462 | poll_fn(|cx| { |
| 455 | T::state().tx_waker.register(cx.waker()); | 463 | T::state().tx_waker.register(cx.waker()); |
| 456 | 464 | ||
| @@ -466,11 +474,19 @@ impl<'c, 'd, T: Instance> CanTx<'c, 'd, T> { | |||
| 466 | }) | 474 | }) |
| 467 | .await; | 475 | .await; |
| 468 | } | 476 | } |
| 477 | |||
| 478 | |||
| 479 | |||
| 480 | /// Waits until all of the transmit mailboxes become empty | ||
| 481 | pub async fn flush_all(&self) { | ||
| 482 | Self::_flush_all().await | ||
| 483 | } | ||
| 469 | } | 484 | } |
| 470 | 485 | ||
| 471 | #[allow(dead_code)] | 486 | #[allow(dead_code)] |
| 472 | pub struct CanRx<'c, 'd, T: Instance> { | 487 | pub struct CanRx<'c, 'd, T: Instance> { |
| 473 | can: &'c RefCell<bxcan::Can<BxcanInstance<'d, T>>>, | 488 | rx0: &'c mut bxcan::Rx0<BxcanInstance<'d, T>>, |
| 489 | rx1: &'c mut bxcan::Rx1<BxcanInstance<'d, T>>, | ||
| 474 | } | 490 | } |
| 475 | 491 | ||
| 476 | impl<'c, 'd, T: Instance> CanRx<'c, 'd, T> { | 492 | impl<'c, 'd, T: Instance> CanRx<'c, 'd, T> { |
| @@ -538,7 +554,7 @@ impl<'d, T: Instance> Drop for Can<'d, T> { | |||
| 538 | } | 554 | } |
| 539 | 555 | ||
| 540 | impl<'d, T: Instance> Deref for Can<'d, T> { | 556 | impl<'d, T: Instance> Deref for Can<'d, T> { |
| 541 | type Target = RefCell<bxcan::Can<BxcanInstance<'d, T>>>; | 557 | type Target = bxcan::Can<BxcanInstance<'d, T>>; |
| 542 | 558 | ||
| 543 | fn deref(&self) -> &Self::Target { | 559 | fn deref(&self) -> &Self::Target { |
| 544 | &self.can | 560 | &self.can |
