aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--embassy-stm32/src/can/bxcan.rs101
1 files changed, 85 insertions, 16 deletions
diff --git a/embassy-stm32/src/can/bxcan.rs b/embassy-stm32/src/can/bxcan.rs
index 88eef528f..7b664a113 100644
--- a/embassy-stm32/src/can/bxcan.rs
+++ b/embassy-stm32/src/can/bxcan.rs
@@ -2,7 +2,7 @@ use core::future::poll_fn;
2use core::marker::PhantomData; 2use core::marker::PhantomData;
3use core::ops::{Deref, DerefMut}; 3use core::ops::{Deref, DerefMut};
4use core::task::Poll; 4use core::task::Poll;
5 5use core::cell::RefCell;
6pub use bxcan; 6pub use bxcan;
7use bxcan::{Data, ExtendedId, Frame, Id, StandardId}; 7use bxcan::{Data, ExtendedId, Frame, Id, StandardId};
8use embassy_hal_common::{into_ref, PeripheralRef}; 8use embassy_hal_common::{into_ref, PeripheralRef};
@@ -72,7 +72,7 @@ impl<T: Instance> interrupt::typelevel::Handler<T::SCEInterrupt> for SceInterrup
72} 72}
73 73
74pub struct Can<'d, T: Instance> { 74pub struct Can<'d, T: Instance> {
75 can: bxcan::Can<BxcanInstance<'d, T>>, 75 pub can: RefCell<bxcan::Can<BxcanInstance<'d, T>>>,
76} 76}
77 77
78#[derive(Debug)] 78#[derive(Debug)]
@@ -147,19 +147,20 @@ impl<'d, T: Instance> Can<'d, T> {
147 tx.set_as_af(tx.af_num(), AFType::OutputPushPull); 147 tx.set_as_af(tx.af_num(), AFType::OutputPushPull);
148 148
149 let can = bxcan::Can::builder(BxcanInstance(peri)).leave_disabled(); 149 let can = bxcan::Can::builder(BxcanInstance(peri)).leave_disabled();
150 Self { can } 150 let can_ref_cell = RefCell::new(can);
151 Self { can: can_ref_cell }
151 } 152 }
152 153
153 pub fn set_bitrate(&mut self, bitrate: u32) { 154 pub fn set_bitrate(&mut self, bitrate: u32) {
154 let bit_timing = Self::calc_bxcan_timings(T::frequency(), bitrate).unwrap(); 155 let bit_timing = Self::calc_bxcan_timings(T::frequency(), bitrate).unwrap();
155 self.can.modify_config().set_bit_timing(bit_timing).leave_disabled(); 156 self.can.borrow_mut().modify_config().set_bit_timing(bit_timing).leave_disabled();
156 } 157 }
157 158
158 /// Queues the message to be sent but exerts backpressure 159 /// Queues the message to be sent but exerts backpressure
159 pub async fn write(&mut self, frame: &Frame) -> bxcan::TransmitStatus { 160 pub async fn write(&mut self, frame: &Frame) -> bxcan::TransmitStatus {
160 poll_fn(|cx| { 161 poll_fn(|cx| {
161 T::state().tx_waker.register(cx.waker()); 162 T::state().tx_waker.register(cx.waker());
162 if let Ok(status) = self.can.transmit(frame) { 163 if let Ok(status) = self.can.borrow_mut().transmit(frame) {
163 return Poll::Ready(status); 164 return Poll::Ready(status);
164 } 165 }
165 166
@@ -341,6 +342,74 @@ impl<'d, T: Instance> Can<'d, T> {
341 // Pack into BTR register values 342 // Pack into BTR register values
342 Some((sjw - 1) << 24 | (bs1 as u32 - 1) << 16 | (bs2 as u32 - 1) << 20 | (prescaler as u32 - 1)) 343 Some((sjw - 1) << 24 | (bs1 as u32 - 1) << 16 | (bs2 as u32 - 1) << 20 | (prescaler as u32 - 1))
343 } 344 }
345
346 pub fn split<'c>(&'c self) -> (CanTx<'c, 'd, T>, CanRx<'c, 'd, T>) {
347 (CanTx { can: &self.can }, CanRx { can: &self.can })
348 }
349}
350
351pub struct CanTx<'c, 'd, T: Instance> {
352 can: &'c RefCell<bxcan::Can<BxcanInstance<'d, T>>>,
353}
354
355impl<'c, 'd, T: Instance> CanTx<'c, 'd, T> {
356 pub async fn write(&mut self, frame: &Frame) -> bxcan::TransmitStatus {
357 poll_fn(|cx| {
358 T::state().tx_waker.register(cx.waker());
359 if let Ok(status) = self.can.borrow_mut().transmit(frame) {
360 return Poll::Ready(status);
361 }
362
363 Poll::Pending
364 })
365 .await
366 }
367
368 pub async fn flush(&self, mb: bxcan::Mailbox) {
369 poll_fn(|cx| {
370 T::state().tx_waker.register(cx.waker());
371 if T::regs().tsr().read().tme(mb.index()) {
372 return Poll::Ready(());
373 }
374
375 Poll::Pending
376 })
377 .await;
378 }
379}
380
381pub struct CanRx<'c, 'd, T: Instance> {
382 can: &'c RefCell<bxcan::Can<BxcanInstance<'d, T>>>,
383}
384
385impl<'c, 'd, T: Instance> CanRx<'c, 'd, T> {
386 pub async fn read(&mut self) -> Result<(u16, bxcan::Frame), BusError> {
387 poll_fn(|cx| {
388 T::state().err_waker.register(cx.waker());
389 if let Poll::Ready((time, frame)) = T::state().rx_queue.recv().poll_unpin(cx) {
390 return Poll::Ready(Ok((time, frame)));
391 } else if let Some(err) = self.curr_error() {
392 return Poll::Ready(Err(err));
393 }
394
395 Poll::Pending
396 })
397 .await
398 }
399
400 fn curr_error(&self) -> Option<BusError> {
401 let err = { T::regs().esr().read() };
402 if err.boff() {
403 return Some(BusError::BusOff);
404 } else if err.epvf() {
405 return Some(BusError::BusPassive);
406 } else if err.ewgf() {
407 return Some(BusError::BusWarning);
408 } else if let Some(err) = err.lec().into_bus_err() {
409 return Some(err);
410 }
411 None
412 }
344} 413}
345 414
346enum RxFifo { 415enum RxFifo {
@@ -357,19 +426,19 @@ impl<'d, T: Instance> Drop for Can<'d, T> {
357 } 426 }
358} 427}
359 428
360impl<'d, T: Instance> Deref for Can<'d, T> { 429// impl<'d, T: Instance> Deref for Can<'d, T> {
361 type Target = bxcan::Can<BxcanInstance<'d, T>>; 430// type Target = bxcan::Can<BxcanInstance<'d, T>>;
362 431
363 fn deref(&self) -> &Self::Target { 432// fn deref(&self) -> &Self::Target {
364 &self.can 433// self.can.borrow()
365 } 434// }
366} 435// }
367 436
368impl<'d, T: Instance> DerefMut for Can<'d, T> { 437// impl<'d, T: Instance> DerefMut for Can<'d, T> {
369 fn deref_mut(&mut self) -> &mut Self::Target { 438// fn deref_mut(&mut self) -> &mut Self::Target {
370 &mut self.can 439// self.can.borrow_mut()
371 } 440// }
372} 441// }
373 442
374pub(crate) mod sealed { 443pub(crate) mod sealed {
375 use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex; 444 use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex;