aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDario Nieuwenhuis <[email protected]>2023-11-21 14:45:10 +0000
committerGitHub <[email protected]>2023-11-21 14:45:10 +0000
commit7f1fd199bb95f150de1b51ed19c5a602e334a1b7 (patch)
tree37bdef45f8e568c090b5265d2a8cf09ac772fd63
parent5ddd2cf9a6f165469a5bf207f73b26936f1d7735 (diff)
parent88f893da4541ba42553fa14ba12845d9f3f2d133 (diff)
Merge pull request #2207 from mickvangelderen/split-can-bus-2
Split can bus 2
-rw-r--r--embassy-stm32/src/can/bxcan.rs74
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 @@
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,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
397pub struct CanTx<'c, 'd, T: Instance> { 392pub 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
401impl<'c, 'd, T: Instance> CanTx<'c, 'd, T> { 396impl<'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)]
472pub struct CanRx<'c, 'd, T: Instance> { 479pub 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
476impl<'c, 'd, T: Instance> CanRx<'c, 'd, T> { 484impl<'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
540impl<'d, T: Instance> Deref for Can<'d, T> { 548impl<'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