aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDario Nieuwenhuis <[email protected]>2023-12-18 18:44:41 +0100
committerDario Nieuwenhuis <[email protected]>2023-12-18 18:44:51 +0100
commit87c8d9df94d222d772013fbb3f8ec60054cde039 (patch)
treeaf19aaa9a61c3198bd5984a190370438fc3ec786
parent21fce1e19501171cfd3a5ddd32556961410bd024 (diff)
stm32/can: docs.
-rw-r--r--embassy-stm32/src/can/bxcan.rs45
1 files changed, 41 insertions, 4 deletions
diff --git a/embassy-stm32/src/can/bxcan.rs b/embassy-stm32/src/can/bxcan.rs
index 788360249..3c663b452 100644
--- a/embassy-stm32/src/can/bxcan.rs
+++ b/embassy-stm32/src/can/bxcan.rs
@@ -21,8 +21,10 @@ use crate::{interrupt, peripherals, Peripheral};
21#[derive(Debug, Clone, PartialEq, Eq)] 21#[derive(Debug, Clone, PartialEq, Eq)]
22#[cfg_attr(feature = "defmt", derive(defmt::Format))] 22#[cfg_attr(feature = "defmt", derive(defmt::Format))]
23pub struct Envelope { 23pub struct Envelope {
24 /// Reception time.
24 #[cfg(feature = "time")] 25 #[cfg(feature = "time")]
25 pub ts: embassy_time::Instant, 26 pub ts: embassy_time::Instant,
27 /// The actual CAN frame.
26 pub frame: bxcan::Frame, 28 pub frame: bxcan::Frame,
27} 29}
28 30
@@ -43,6 +45,7 @@ impl<T: Instance> interrupt::typelevel::Handler<T::TXInterrupt> for TxInterruptH
43 } 45 }
44} 46}
45 47
48/// RX0 interrupt handler.
46pub struct Rx0InterruptHandler<T: Instance> { 49pub struct Rx0InterruptHandler<T: Instance> {
47 _phantom: PhantomData<T>, 50 _phantom: PhantomData<T>,
48} 51}
@@ -54,6 +57,7 @@ impl<T: Instance> interrupt::typelevel::Handler<T::RX0Interrupt> for Rx0Interrup
54 } 57 }
55} 58}
56 59
60/// RX1 interrupt handler.
57pub struct Rx1InterruptHandler<T: Instance> { 61pub struct Rx1InterruptHandler<T: Instance> {
58 _phantom: PhantomData<T>, 62 _phantom: PhantomData<T>,
59} 63}
@@ -65,6 +69,7 @@ impl<T: Instance> interrupt::typelevel::Handler<T::RX1Interrupt> for Rx1Interrup
65 } 69 }
66} 70}
67 71
72/// SCE interrupt handler.
68pub struct SceInterruptHandler<T: Instance> { 73pub struct SceInterruptHandler<T: Instance> {
69 _phantom: PhantomData<T>, 74 _phantom: PhantomData<T>,
70} 75}
@@ -82,10 +87,13 @@ impl<T: Instance> interrupt::typelevel::Handler<T::SCEInterrupt> for SceInterrup
82 } 87 }
83} 88}
84 89
90/// CAN driver
85pub struct Can<'d, T: Instance> { 91pub struct Can<'d, T: Instance> {
86 pub can: bxcan::Can<BxcanInstance<'d, T>>, 92 can: bxcan::Can<BxcanInstance<'d, T>>,
87} 93}
88 94
95/// CAN bus error
96#[allow(missing_docs)]
89#[derive(Debug)] 97#[derive(Debug)]
90#[cfg_attr(feature = "defmt", derive(defmt::Format))] 98#[cfg_attr(feature = "defmt", derive(defmt::Format))]
91pub enum BusError { 99pub enum BusError {
@@ -101,6 +109,7 @@ pub enum BusError {
101 BusWarning, 109 BusWarning,
102} 110}
103 111
112/// Error returned by `try_read`
104#[derive(Debug)] 113#[derive(Debug)]
105#[cfg_attr(feature = "defmt", derive(defmt::Format))] 114#[cfg_attr(feature = "defmt", derive(defmt::Format))]
106pub enum TryReadError { 115pub enum TryReadError {
@@ -110,6 +119,7 @@ pub enum TryReadError {
110 Empty, 119 Empty,
111} 120}
112 121
122/// Error returned by `try_write`
113#[derive(Debug)] 123#[derive(Debug)]
114#[cfg_attr(feature = "defmt", derive(defmt::Format))] 124#[cfg_attr(feature = "defmt", derive(defmt::Format))]
115pub enum TryWriteError { 125pub enum TryWriteError {
@@ -177,6 +187,7 @@ impl<'d, T: Instance> Can<'d, T> {
177 Self { can } 187 Self { can }
178 } 188 }
179 189
190 /// Set CAN bit rate.
180 pub fn set_bitrate(&mut self, bitrate: u32) { 191 pub fn set_bitrate(&mut self, bitrate: u32) {
181 let bit_timing = Self::calc_bxcan_timings(T::frequency(), bitrate).unwrap(); 192 let bit_timing = Self::calc_bxcan_timings(T::frequency(), bitrate).unwrap();
182 self.can.modify_config().set_bit_timing(bit_timing).leave_disabled(); 193 self.can.modify_config().set_bit_timing(bit_timing).leave_disabled();
@@ -194,7 +205,9 @@ impl<'d, T: Instance> Can<'d, T> {
194 } 205 }
195 } 206 }
196 207
197 /// Queues the message to be sent but exerts backpressure 208 /// Queues the message to be sent.
209 ///
210 /// If the TX queue is full, this will wait until there is space, therefore exerting backpressure.
198 pub async fn write(&mut self, frame: &Frame) -> bxcan::TransmitStatus { 211 pub async fn write(&mut self, frame: &Frame) -> bxcan::TransmitStatus {
199 self.split().0.write(frame).await 212 self.split().0.write(frame).await
200 } 213 }
@@ -221,12 +234,16 @@ impl<'d, T: Instance> Can<'d, T> {
221 CanTx::<T>::flush_all_inner().await 234 CanTx::<T>::flush_all_inner().await
222 } 235 }
223 236
237 /// Read a CAN frame.
238 ///
239 /// If no CAN frame is in the RX buffer, this will wait until there is one.
240 ///
224 /// Returns a tuple of the time the message was received and the message frame 241 /// Returns a tuple of the time the message was received and the message frame
225 pub async fn read(&mut self) -> Result<Envelope, BusError> { 242 pub async fn read(&mut self) -> Result<Envelope, BusError> {
226 self.split().1.read().await 243 self.split().1.read().await
227 } 244 }
228 245
229 /// Attempts to read a can frame without blocking. 246 /// Attempts to read a CAN frame without blocking.
230 /// 247 ///
231 /// Returns [Err(TryReadError::Empty)] if there are no frames in the rx queue. 248 /// Returns [Err(TryReadError::Empty)] if there are no frames in the rx queue.
232 pub fn try_read(&mut self) -> Result<Envelope, TryReadError> { 249 pub fn try_read(&mut self) -> Result<Envelope, TryReadError> {
@@ -288,7 +305,7 @@ impl<'d, T: Instance> Can<'d, T> {
288 } 305 }
289 } 306 }
290 307
291 pub const fn calc_bxcan_timings(periph_clock: Hertz, can_bitrate: u32) -> Option<u32> { 308 const fn calc_bxcan_timings(periph_clock: Hertz, can_bitrate: u32) -> Option<u32> {
292 const BS1_MAX: u8 = 16; 309 const BS1_MAX: u8 = 16;
293 const BS2_MAX: u8 = 8; 310 const BS2_MAX: u8 = 8;
294 const MAX_SAMPLE_POINT_PERMILL: u16 = 900; 311 const MAX_SAMPLE_POINT_PERMILL: u16 = 900;
@@ -379,21 +396,29 @@ impl<'d, T: Instance> Can<'d, T> {
379 Some((sjw - 1) << 24 | (bs1 as u32 - 1) << 16 | (bs2 as u32 - 1) << 20 | (prescaler - 1)) 396 Some((sjw - 1) << 24 | (bs1 as u32 - 1) << 16 | (bs2 as u32 - 1) << 20 | (prescaler - 1))
380 } 397 }
381 398
399 /// Split the CAN driver into transmit and receive halves.
400 ///
401 /// Useful for doing separate transmit/receive tasks.
382 pub fn split<'c>(&'c mut self) -> (CanTx<'c, 'd, T>, CanRx<'c, 'd, T>) { 402 pub fn split<'c>(&'c mut self) -> (CanTx<'c, 'd, T>, CanRx<'c, 'd, T>) {
383 let (tx, rx0, rx1) = self.can.split_by_ref(); 403 let (tx, rx0, rx1) = self.can.split_by_ref();
384 (CanTx { tx }, CanRx { rx0, rx1 }) 404 (CanTx { tx }, CanRx { rx0, rx1 })
385 } 405 }
386 406
407 /// Get mutable access to the lower-level driver from the `bxcan` crate.
387 pub fn as_mut(&mut self) -> &mut bxcan::Can<BxcanInstance<'d, T>> { 408 pub fn as_mut(&mut self) -> &mut bxcan::Can<BxcanInstance<'d, T>> {
388 &mut self.can 409 &mut self.can
389 } 410 }
390} 411}
391 412
413/// CAN driver, transmit half.
392pub struct CanTx<'c, 'd, T: Instance> { 414pub struct CanTx<'c, 'd, T: Instance> {
393 tx: &'c mut bxcan::Tx<BxcanInstance<'d, T>>, 415 tx: &'c mut bxcan::Tx<BxcanInstance<'d, T>>,
394} 416}
395 417
396impl<'c, 'd, T: Instance> CanTx<'c, 'd, T> { 418impl<'c, 'd, T: Instance> CanTx<'c, 'd, T> {
419 /// Queues the message to be sent.
420 ///
421 /// If the TX queue is full, this will wait until there is space, therefore exerting backpressure.
397 pub async fn write(&mut self, frame: &Frame) -> bxcan::TransmitStatus { 422 pub async fn write(&mut self, frame: &Frame) -> bxcan::TransmitStatus {
398 poll_fn(|cx| { 423 poll_fn(|cx| {
399 T::state().tx_waker.register(cx.waker()); 424 T::state().tx_waker.register(cx.waker());
@@ -475,6 +500,7 @@ impl<'c, 'd, T: Instance> CanTx<'c, 'd, T> {
475 } 500 }
476} 501}
477 502
503/// CAN driver, receive half.
478#[allow(dead_code)] 504#[allow(dead_code)]
479pub struct CanRx<'c, 'd, T: Instance> { 505pub struct CanRx<'c, 'd, T: Instance> {
480 rx0: &'c mut bxcan::Rx0<BxcanInstance<'d, T>>, 506 rx0: &'c mut bxcan::Rx0<BxcanInstance<'d, T>>,
@@ -482,6 +508,11 @@ pub struct CanRx<'c, 'd, T: Instance> {
482} 508}
483 509
484impl<'c, 'd, T: Instance> CanRx<'c, 'd, T> { 510impl<'c, 'd, T: Instance> CanRx<'c, 'd, T> {
511 /// Read a CAN frame.
512 ///
513 /// If no CAN frame is in the RX buffer, this will wait until there is one.
514 ///
515 /// Returns a tuple of the time the message was received and the message frame
485 pub async fn read(&mut self) -> Result<Envelope, BusError> { 516 pub async fn read(&mut self) -> Result<Envelope, BusError> {
486 poll_fn(|cx| { 517 poll_fn(|cx| {
487 T::state().err_waker.register(cx.waker()); 518 T::state().err_waker.register(cx.waker());
@@ -590,13 +621,19 @@ pub(crate) mod sealed {
590 } 621 }
591} 622}
592 623
624/// CAN instance trait.
593pub trait Instance: sealed::Instance + RccPeripheral + 'static { 625pub trait Instance: sealed::Instance + RccPeripheral + 'static {
626 /// TX interrupt for this instance.
594 type TXInterrupt: crate::interrupt::typelevel::Interrupt; 627 type TXInterrupt: crate::interrupt::typelevel::Interrupt;
628 /// RX0 interrupt for this instance.
595 type RX0Interrupt: crate::interrupt::typelevel::Interrupt; 629 type RX0Interrupt: crate::interrupt::typelevel::Interrupt;
630 /// RX1 interrupt for this instance.
596 type RX1Interrupt: crate::interrupt::typelevel::Interrupt; 631 type RX1Interrupt: crate::interrupt::typelevel::Interrupt;
632 /// SCE interrupt for this instance.
597 type SCEInterrupt: crate::interrupt::typelevel::Interrupt; 633 type SCEInterrupt: crate::interrupt::typelevel::Interrupt;
598} 634}
599 635
636/// BXCAN instance newtype.
600pub struct BxcanInstance<'a, T>(PeripheralRef<'a, T>); 637pub struct BxcanInstance<'a, T>(PeripheralRef<'a, T>);
601 638
602unsafe impl<'d, T: Instance> bxcan::Instance for BxcanInstance<'d, T> { 639unsafe impl<'d, T: Instance> bxcan::Instance for BxcanInstance<'d, T> {