aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTommas Bakker <[email protected]>2023-10-25 13:56:23 +0200
committerMick van Gelderen <[email protected]>2023-11-21 15:34:34 +0100
commit06a83c0f897d0fe39c59e33b14d9b4f0cd705a0b (patch)
tree195414d16ab101e55e1d81a21e9182620c9300f0
parent766ec77ec5a9a5a0e4af32651c9eb0b6c8e93fed (diff)
Refactor bxcan split.
-rw-r--r--embassy-stm32/src/can/bxcan.rs70
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 @@
1use core::cell::{RefCell, RefMut};
2use core::future::poll_fn; 1use core::future::poll_fn;
3use core::marker::PhantomData; 2use core::marker::PhantomData;
4use core::ops::{Deref, DerefMut}; 3use core::ops::{Deref, DerefMut};
@@ -84,7 +83,7 @@ impl<T: Instance> interrupt::typelevel::Handler<T::SCEInterrupt> for SceInterrup
84} 83}
85 84
86pub struct Can<'d, T: Instance> { 85pub 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
397pub struct CanTx<'c, 'd, T: Instance> { 396pub 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
401impl<'c, 'd, T: Instance> CanTx<'c, 'd, T> { 400impl<'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)]
472pub struct CanRx<'c, 'd, T: Instance> { 487pub 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
476impl<'c, 'd, T: Instance> CanRx<'c, 'd, T> { 492impl<'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
540impl<'d, T: Instance> Deref for Can<'d, T> { 556impl<'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