aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--embassy-stm32/src/can/bx/mod.rs11
-rw-r--r--embassy-stm32/src/can/bxcan.rs2
-rw-r--r--embassy-stm32/src/can/enums.rs12
-rw-r--r--embassy-stm32/src/can/fd/peripheral.rs5
-rw-r--r--embassy-stm32/src/can/frame.rs140
-rw-r--r--examples/stm32f1/src/bin/can.rs2
-rw-r--r--examples/stm32f4/src/bin/can.rs2
-rw-r--r--examples/stm32f7/src/bin/can.rs2
-rw-r--r--tests/stm32/src/bin/can.rs2
9 files changed, 78 insertions, 100 deletions
diff --git a/embassy-stm32/src/can/bx/mod.rs b/embassy-stm32/src/can/bx/mod.rs
index 650d4414b..ae8bafaa8 100644
--- a/embassy-stm32/src/can/bx/mod.rs
+++ b/embassy-stm32/src/can/bx/mod.rs
@@ -44,7 +44,6 @@ pub type Data = crate::can::frame::ClassicData;
44pub type Frame = crate::can::frame::ClassicFrame; 44pub type Frame = crate::can::frame::ClassicFrame;
45 45
46use crate::can::bx::filter::MasterFilters; 46use crate::can::bx::filter::MasterFilters;
47use crate::can::frame::ClassicData;
48 47
49/// A bxCAN peripheral instance. 48/// A bxCAN peripheral instance.
50/// 49///
@@ -799,10 +798,7 @@ where
799 data[4..8].copy_from_slice(&mb.tdhr().read().0.to_ne_bytes()); 798 data[4..8].copy_from_slice(&mb.tdhr().read().0.to_ne_bytes());
800 let len = mb.tdtr().read().dlc(); 799 let len = mb.tdtr().read().dlc();
801 800
802 Some(Frame::new( 801 Some(Frame::new(Header::new(id, len, false), &data).unwrap())
803 Header::new(id, len, false),
804 ClassicData::new(&data).unwrap(),
805 ))
806 } else { 802 } else {
807 // Abort request failed because the frame was already sent (or being sent) on 803 // Abort request failed because the frame was already sent (or being sent) on
808 // the bus. All mailboxes are now free. This can happen for small prescaler 804 // the bus. All mailboxes are now free. This can happen for small prescaler
@@ -944,10 +940,7 @@ fn receive_fifo(canregs: crate::pac::can::Can, fifo_nr: usize) -> nb::Result<Fra
944 // Release the mailbox. 940 // Release the mailbox.
945 rfr.write(|w| w.set_rfom(true)); 941 rfr.write(|w| w.set_rfom(true));
946 942
947 Ok(Frame::new( 943 Ok(Frame::new(Header::new(id, len, false), &data).unwrap())
948 Header::new(id, len, false),
949 ClassicData::new(&data).unwrap(),
950 ))
951} 944}
952 945
953/// Identifies one of the two receive FIFOs. 946/// Identifies one of the two receive FIFOs.
diff --git a/embassy-stm32/src/can/bxcan.rs b/embassy-stm32/src/can/bxcan.rs
index 4d96df8aa..bb7cc3d7f 100644
--- a/embassy-stm32/src/can/bxcan.rs
+++ b/embassy-stm32/src/can/bxcan.rs
@@ -274,7 +274,7 @@ impl<'d, T: Instance> Can<'d, T> {
274 data[0..4].copy_from_slice(&fifo.rdlr().read().0.to_ne_bytes()); 274 data[0..4].copy_from_slice(&fifo.rdlr().read().0.to_ne_bytes());
275 data[4..8].copy_from_slice(&fifo.rdhr().read().0.to_ne_bytes()); 275 data[4..8].copy_from_slice(&fifo.rdhr().read().0.to_ne_bytes());
276 276
277 let frame = Frame::new(Header::new(id, data_len, false), Data::new(&data).unwrap()); 277 let frame = Frame::new(Header::new(id, data_len, false), &data).unwrap();
278 let envelope = Envelope { 278 let envelope = Envelope {
279 #[cfg(feature = "time")] 279 #[cfg(feature = "time")]
280 ts, 280 ts,
diff --git a/embassy-stm32/src/can/enums.rs b/embassy-stm32/src/can/enums.rs
index 36139a45c..651de9194 100644
--- a/embassy-stm32/src/can/enums.rs
+++ b/embassy-stm32/src/can/enums.rs
@@ -28,3 +28,15 @@ pub enum BusError {
28 /// At least one of error counter has reached the Error_Warning limit of 96. 28 /// At least one of error counter has reached the Error_Warning limit of 96.
29 BusWarning, 29 BusWarning,
30} 30}
31
32/// Frame Create Errors
33#[derive(Debug)]
34#[cfg_attr(feature = "defmt", derive(defmt::Format))]
35pub enum FrameCreateError {
36 /// Data in header does not match supplied.
37 NotEnoughData,
38 /// Invalid data length not 0-8 for Classic packet or valid for FD.
39 InvalidDataLength,
40 /// Invalid ID.
41 InvalidCanId,
42}
diff --git a/embassy-stm32/src/can/fd/peripheral.rs b/embassy-stm32/src/can/fd/peripheral.rs
index cce4e5e8d..e14977d91 100644
--- a/embassy-stm32/src/can/fd/peripheral.rs
+++ b/embassy-stm32/src/can/fd/peripheral.rs
@@ -56,7 +56,10 @@ impl Registers {
56 match maybe_header { 56 match maybe_header {
57 Some((header, ts)) => { 57 Some((header, ts)) => {
58 let data = &buffer[0..header.len() as usize]; 58 let data = &buffer[0..header.len() as usize];
59 Some((F::from_header(header, data)?, ts)) 59 match F::from_header(header, data) {
60 Ok(frame) => Some((frame, ts)),
61 Err(_) => None,
62 }
60 } 63 }
61 None => None, 64 None => None,
62 } 65 }
diff --git a/embassy-stm32/src/can/frame.rs b/embassy-stm32/src/can/frame.rs
index 0dc74d299..14fc32c51 100644
--- a/embassy-stm32/src/can/frame.rs
+++ b/embassy-stm32/src/can/frame.rs
@@ -1,6 +1,8 @@
1//! Definition for CAN Frames 1//! Definition for CAN Frames
2use bit_field::BitField; 2use bit_field::BitField;
3 3
4use crate::can::enums::FrameCreateError;
5
4/// CAN Header, without meta data 6/// CAN Header, without meta data
5#[derive(Debug, Copy, Clone)] 7#[derive(Debug, Copy, Clone)]
6pub struct Header { 8pub struct Header {
@@ -82,7 +84,7 @@ impl Header {
82/// and to retrieve the Header from a frame 84/// and to retrieve the Header from a frame
83pub trait CanHeader: Sized { 85pub trait CanHeader: Sized {
84 /// Construct frame from header and payload 86 /// Construct frame from header and payload
85 fn from_header(header: Header, data: &[u8]) -> Option<Self>; 87 fn from_header(header: Header, data: &[u8]) -> Result<Self, FrameCreateError>;
86 88
87 /// Get this frame's header struct 89 /// Get this frame's header struct
88 fn header(&self) -> &Header; 90 fn header(&self) -> &Header;
@@ -103,15 +105,15 @@ impl ClassicData {
103 /// 105 ///
104 /// Returns `None` if `data` is more than 64 bytes (which is the maximum) or 106 /// Returns `None` if `data` is more than 64 bytes (which is the maximum) or
105 /// cannot be represented with an FDCAN DLC. 107 /// cannot be represented with an FDCAN DLC.
106 pub fn new(data: &[u8]) -> Option<Self> { 108 pub fn new(data: &[u8]) -> Result<Self, FrameCreateError> {
107 if !FdData::is_valid_len(data.len()) { 109 if data.len() > 8 {
108 return None; 110 return Err(FrameCreateError::InvalidDataLength);
109 } 111 }
110 112
111 let mut bytes = [0; 8]; 113 let mut bytes = [0; 8];
112 bytes[..data.len()].copy_from_slice(data); 114 bytes[..data.len()].copy_from_slice(data);
113 115
114 Some(Self { bytes }) 116 Ok(Self { bytes })
115 } 117 }
116 118
117 /// Raw read access to data. 119 /// Raw read access to data.
@@ -134,12 +136,6 @@ impl ClassicData {
134 } 136 }
135} 137}
136 138
137impl From<&[u8]> for ClassicData {
138 fn from(d: &[u8]) -> Self {
139 ClassicData::new(d).unwrap()
140 }
141}
142
143/// Frame with up to 8 bytes of data payload as per Classic CAN 139/// Frame with up to 8 bytes of data payload as per Classic CAN
144#[derive(Debug, Copy, Clone)] 140#[derive(Debug, Copy, Clone)]
145#[cfg_attr(feature = "defmt", derive(defmt::Format))] 141#[cfg_attr(feature = "defmt", derive(defmt::Format))]
@@ -150,59 +146,42 @@ pub struct ClassicFrame {
150 146
151impl ClassicFrame { 147impl ClassicFrame {
152 /// Create a new CAN classic Frame 148 /// Create a new CAN classic Frame
153 pub fn new(can_header: Header, data: impl Into<ClassicData>) -> ClassicFrame { 149 pub fn new(can_header: Header, raw_data: &[u8]) -> Result<Self, FrameCreateError> {
154 ClassicFrame { 150 let data = ClassicData::new(raw_data)?;
155 can_header, 151 Ok(ClassicFrame { can_header, data: data })
156 data: data.into(),
157 }
158 } 152 }
159 153
160 /// Creates a new data frame. 154 /// Creates a new data frame.
161 pub fn new_data(id: impl Into<embedded_can::Id>, data: &[u8]) -> Self { 155 pub fn new_data(id: impl Into<embedded_can::Id>, data: &[u8]) -> Result<Self, FrameCreateError> {
162 let eid: embedded_can::Id = id.into(); 156 let eid: embedded_can::Id = id.into();
163 let header = Header::new(eid, data.len() as u8, false); 157 let header = Header::new(eid, data.len() as u8, false);
164 Self::new(header, data) 158 Self::new(header, data)
165 } 159 }
166 160
167 /// Create new extended frame 161 /// Create new extended frame
168 pub fn new_extended(raw_id: u32, raw_data: &[u8]) -> Option<Self> { 162 pub fn new_extended(raw_id: u32, raw_data: &[u8]) -> Result<Self, FrameCreateError> {
169 if let Some(id) = embedded_can::ExtendedId::new(raw_id) { 163 if let Some(id) = embedded_can::ExtendedId::new(raw_id) {
170 match ClassicData::new(raw_data) { 164 Self::new(Header::new(id.into(), raw_data.len() as u8, false), raw_data)
171 Some(data) => Some(ClassicFrame::new(
172 Header::new(id.into(), raw_data.len() as u8, false),
173 data,
174 )),
175 None => None,
176 }
177 } else { 165 } else {
178 None 166 Err(FrameCreateError::InvalidCanId)
179 } 167 }
180 } 168 }
181 169
182 /// Create new standard frame 170 /// Create new standard frame
183 pub fn new_standard(raw_id: u16, raw_data: &[u8]) -> Option<Self> { 171 pub fn new_standard(raw_id: u16, raw_data: &[u8]) -> Result<Self, FrameCreateError> {
184 if let Some(id) = embedded_can::StandardId::new(raw_id) { 172 if let Some(id) = embedded_can::StandardId::new(raw_id) {
185 match ClassicData::new(raw_data) { 173 Self::new(Header::new(id.into(), raw_data.len() as u8, false), raw_data)
186 Some(data) => Some(ClassicFrame::new(
187 Header::new(id.into(), raw_data.len() as u8, false),
188 data,
189 )),
190 None => None,
191 }
192 } else { 174 } else {
193 None 175 Err(FrameCreateError::InvalidCanId)
194 } 176 }
195 } 177 }
196 178
197 /// Create new remote frame 179 /// Create new remote frame
198 pub fn new_remote(id: impl Into<embedded_can::Id>, len: usize) -> Option<Self> { 180 pub fn new_remote(id: impl Into<embedded_can::Id>, len: usize) -> Result<Self, FrameCreateError> {
199 if len <= 8usize { 181 if len <= 8usize {
200 Some(ClassicFrame::new( 182 Self::new(Header::new(id.into(), len as u8, true), &[0; 8])
201 Header::new(id.into(), len as u8, true),
202 ClassicData::empty(),
203 ))
204 } else { 183 } else {
205 None 184 Err(FrameCreateError::InvalidDataLength)
206 } 185 }
207 } 186 }
208 187
@@ -229,20 +208,19 @@ impl ClassicFrame {
229 208
230impl embedded_can::Frame for ClassicFrame { 209impl embedded_can::Frame for ClassicFrame {
231 fn new(id: impl Into<embedded_can::Id>, raw_data: &[u8]) -> Option<Self> { 210 fn new(id: impl Into<embedded_can::Id>, raw_data: &[u8]) -> Option<Self> {
232 match ClassicData::new(raw_data) { 211 let frameopt = ClassicFrame::new(Header::new(id.into(), raw_data.len() as u8, false), raw_data);
233 Some(data) => Some(ClassicFrame::new( 212 match frameopt {
234 Header::new(id.into(), raw_data.len() as u8, false), 213 Ok(frame) => Some(frame),
235 data, 214 Err(_) => None,
236 )),
237 None => None,
238 } 215 }
239 } 216 }
240 fn new_remote(id: impl Into<embedded_can::Id>, len: usize) -> Option<Self> { 217 fn new_remote(id: impl Into<embedded_can::Id>, len: usize) -> Option<Self> {
241 if len <= 8 { 218 if len <= 8 {
242 Some(ClassicFrame::new( 219 let frameopt = ClassicFrame::new(Header::new(id.into(), len as u8, true), &[0; 8]);
243 Header::new(id.into(), len as u8, true), 220 match frameopt {
244 ClassicData::empty(), 221 Ok(frame) => Some(frame),
245 )) 222 Err(_) => None,
223 }
246 } else { 224 } else {
247 None 225 None
248 } 226 }
@@ -268,8 +246,8 @@ impl embedded_can::Frame for ClassicFrame {
268} 246}
269 247
270impl CanHeader for ClassicFrame { 248impl CanHeader for ClassicFrame {
271 fn from_header(header: Header, data: &[u8]) -> Option<Self> { 249 fn from_header(header: Header, data: &[u8]) -> Result<Self, FrameCreateError> {
272 Some(Self::new(header, ClassicData::new(data)?)) 250 Self::new(header, data)
273 } 251 }
274 252
275 fn header(&self) -> &Header { 253 fn header(&self) -> &Header {
@@ -290,15 +268,15 @@ impl FdData {
290 /// 268 ///
291 /// Returns `None` if `data` is more than 64 bytes (which is the maximum) or 269 /// Returns `None` if `data` is more than 64 bytes (which is the maximum) or
292 /// cannot be represented with an FDCAN DLC. 270 /// cannot be represented with an FDCAN DLC.
293 pub fn new(data: &[u8]) -> Option<Self> { 271 pub fn new(data: &[u8]) -> Result<Self, FrameCreateError> {
294 if !FdData::is_valid_len(data.len()) { 272 if !FdData::is_valid_len(data.len()) {
295 return None; 273 return Err(FrameCreateError::InvalidDataLength);
296 } 274 }
297 275
298 let mut bytes = [0; 64]; 276 let mut bytes = [0; 64];
299 bytes[..data.len()].copy_from_slice(data); 277 bytes[..data.len()].copy_from_slice(data);
300 278
301 Some(Self { bytes }) 279 Ok(Self { bytes })
302 } 280 }
303 281
304 /// Raw read access to data. 282 /// Raw read access to data.
@@ -337,40 +315,35 @@ pub struct FdFrame {
337 315
338impl FdFrame { 316impl FdFrame {
339 /// Create a new CAN classic Frame 317 /// Create a new CAN classic Frame
340 pub fn new(can_header: Header, data: FdData) -> FdFrame { 318 pub fn new(can_header: Header, raw_data: &[u8]) -> Result<Self, FrameCreateError> {
341 FdFrame { can_header, data } 319 let data = FdData::new(raw_data)?;
320 Ok(FdFrame { can_header, data })
342 } 321 }
343 322
344 /// Create new extended frame 323 /// Create new extended frame
345 pub fn new_extended(raw_id: u32, raw_data: &[u8]) -> Option<Self> { 324 pub fn new_extended(raw_id: u32, raw_data: &[u8]) -> Result<Self, FrameCreateError> {
346 if let Some(id) = embedded_can::ExtendedId::new(raw_id) { 325 if let Some(id) = embedded_can::ExtendedId::new(raw_id) {
347 match FdData::new(raw_data) { 326 Self::new(Header::new(id.into(), raw_data.len() as u8, false), raw_data)
348 Some(data) => Some(FdFrame::new(Header::new(id.into(), raw_data.len() as u8, false), data)),
349 None => None,
350 }
351 } else { 327 } else {
352 None 328 Err(FrameCreateError::InvalidCanId)
353 } 329 }
354 } 330 }
355 331
356 /// Create new standard frame 332 /// Create new standard frame
357 pub fn new_standard(raw_id: u16, raw_data: &[u8]) -> Option<Self> { 333 pub fn new_standard(raw_id: u16, raw_data: &[u8]) -> Result<Self, FrameCreateError> {
358 if let Some(id) = embedded_can::StandardId::new(raw_id) { 334 if let Some(id) = embedded_can::StandardId::new(raw_id) {
359 match FdData::new(raw_data) { 335 Self::new(Header::new(id.into(), raw_data.len() as u8, false), raw_data)
360 Some(data) => Some(FdFrame::new(Header::new(id.into(), raw_data.len() as u8, false), data)),
361 None => None,
362 }
363 } else { 336 } else {
364 None 337 Err(FrameCreateError::InvalidCanId)
365 } 338 }
366 } 339 }
367 340
368 /// Create new remote frame 341 /// Create new remote frame
369 pub fn new_remote(id: impl Into<embedded_can::Id>, len: usize) -> Option<Self> { 342 pub fn new_remote(id: impl Into<embedded_can::Id>, len: usize) -> Result<Self, FrameCreateError> {
370 if len <= 8 { 343 if len <= 8 {
371 Some(FdFrame::new(Header::new(id.into(), len as u8, true), FdData::empty())) 344 Self::new(Header::new(id.into(), len as u8, true), &[0; 8])
372 } else { 345 } else {
373 None 346 Err(FrameCreateError::InvalidDataLength)
374 } 347 }
375 } 348 }
376 349
@@ -392,20 +365,17 @@ impl FdFrame {
392 365
393impl embedded_can::Frame for FdFrame { 366impl embedded_can::Frame for FdFrame {
394 fn new(id: impl Into<embedded_can::Id>, raw_data: &[u8]) -> Option<Self> { 367 fn new(id: impl Into<embedded_can::Id>, raw_data: &[u8]) -> Option<Self> {
395 match FdData::new(raw_data) { 368 match FdFrame::new(Header::new_fd(id.into(), raw_data.len() as u8, false, true), raw_data) {
396 Some(data) => Some(FdFrame::new( 369 Ok(frame) => Some(frame),
397 Header::new_fd(id.into(), raw_data.len() as u8, false, true), 370 Err(_) => None,
398 data,
399 )),
400 None => None,
401 } 371 }
402 } 372 }
403 fn new_remote(id: impl Into<embedded_can::Id>, len: usize) -> Option<Self> { 373 fn new_remote(id: impl Into<embedded_can::Id>, len: usize) -> Option<Self> {
404 if len <= 8 { 374 if len <= 8 {
405 Some(FdFrame::new( 375 match FdFrame::new(Header::new_fd(id.into(), len as u8, true, true), &[0; 64]) {
406 Header::new_fd(id.into(), len as u8, true, true), 376 Ok(frame) => Some(frame),
407 FdData::empty(), 377 Err(_) => None,
408 )) 378 }
409 } else { 379 } else {
410 None 380 None
411 } 381 }
@@ -432,8 +402,8 @@ impl embedded_can::Frame for FdFrame {
432} 402}
433 403
434impl CanHeader for FdFrame { 404impl CanHeader for FdFrame {
435 fn from_header(header: Header, data: &[u8]) -> Option<Self> { 405 fn from_header(header: Header, data: &[u8]) -> Result<Self, FrameCreateError> {
436 Some(Self::new(header, FdData::new(data)?)) 406 Self::new(header, data)
437 } 407 }
438 408
439 fn header(&self) -> &Header { 409 fn header(&self) -> &Header {
diff --git a/examples/stm32f1/src/bin/can.rs b/examples/stm32f1/src/bin/can.rs
index a43fb4427..ac337e8a0 100644
--- a/examples/stm32f1/src/bin/can.rs
+++ b/examples/stm32f1/src/bin/can.rs
@@ -46,7 +46,7 @@ async fn main(_spawner: Spawner) {
46 46
47 let mut i: u8 = 0; 47 let mut i: u8 = 0;
48 loop { 48 loop {
49 let tx_frame = Frame::new_data(unwrap!(StandardId::new(i as _)), &[i, 0, 1, 2, 3, 4, 5, 6]); 49 let tx_frame = Frame::new_data(unwrap!(StandardId::new(i as _)), &[i, 0, 1, 2, 3, 4, 5, 6]).unwrap();
50 can.write(&tx_frame).await; 50 can.write(&tx_frame).await;
51 51
52 match can.read().await { 52 match can.read().await {
diff --git a/examples/stm32f4/src/bin/can.rs b/examples/stm32f4/src/bin/can.rs
index 2ed631a46..71b9453eb 100644
--- a/examples/stm32f4/src/bin/can.rs
+++ b/examples/stm32f4/src/bin/can.rs
@@ -51,7 +51,7 @@ async fn main(_spawner: Spawner) {
51 51
52 let mut i: u8 = 0; 52 let mut i: u8 = 0;
53 loop { 53 loop {
54 let tx_frame = Frame::new_data(unwrap!(StandardId::new(i as _)), &[i]); 54 let tx_frame = Frame::new_data(unwrap!(StandardId::new(i as _)), &[i]).unwrap();
55 let tx_ts = Instant::now(); 55 let tx_ts = Instant::now();
56 can.write(&tx_frame).await; 56 can.write(&tx_frame).await;
57 57
diff --git a/examples/stm32f7/src/bin/can.rs b/examples/stm32f7/src/bin/can.rs
index 2701196ed..221ac2a05 100644
--- a/examples/stm32f7/src/bin/can.rs
+++ b/examples/stm32f7/src/bin/can.rs
@@ -26,7 +26,7 @@ bind_interrupts!(struct Irqs {
26#[embassy_executor::task] 26#[embassy_executor::task]
27pub async fn send_can_message(tx: &'static mut CanTx<'static, CAN3>) { 27pub async fn send_can_message(tx: &'static mut CanTx<'static, CAN3>) {
28 loop { 28 loop {
29 let frame = Frame::new_data(unwrap!(StandardId::new(0 as _)), &[0]); 29 let frame = Frame::new_data(unwrap!(StandardId::new(0 as _)), &[0]).unwrap();
30 tx.write(&frame).await; 30 tx.write(&frame).await;
31 embassy_time::Timer::after_secs(1).await; 31 embassy_time::Timer::after_secs(1).await;
32 } 32 }
diff --git a/tests/stm32/src/bin/can.rs b/tests/stm32/src/bin/can.rs
index e36137b38..c08c69a3b 100644
--- a/tests/stm32/src/bin/can.rs
+++ b/tests/stm32/src/bin/can.rs
@@ -60,7 +60,7 @@ async fn main(_spawner: Spawner) {
60 60
61 let mut i: u8 = 0; 61 let mut i: u8 = 0;
62 loop { 62 loop {
63 let tx_frame = Frame::new_data(unwrap!(StandardId::new(i as _)), &[i]); 63 let tx_frame = Frame::new_data(unwrap!(StandardId::new(i as _)), &[i]).unwrap();
64 64
65 info!("Transmitting frame..."); 65 info!("Transmitting frame...");
66 let tx_ts = Instant::now(); 66 let tx_ts = Instant::now();