1use bit_field::BitField;
3
4use crate::can::enums::FrameCreateError;
5
6#[cfg(feature = "time")]
8pub type Timestamp = embassy_time::Instant;
9
10#[cfg(not(feature = "time"))]
12pub type Timestamp = u16;
13
14#[derive(Debug, Copy, Clone)]
16pub struct Header {
17 id: embedded_can::Id,
18 len: u8,
19 flags: u8,
20}
21
22#[cfg(feature = "defmt")]
23impl defmt::Format for Header {
24 fn format(&self, fmt: defmt::Formatter<'_>) {
25 match self.id() {
26 embedded_can::Id::Standard(id) => {
27 defmt::write!(fmt, "Can Standard ID={:x} len={}", id.as_raw(), self.len,)
28 }
29 embedded_can::Id::Extended(id) => {
30 defmt::write!(fmt, "Can Extended ID={:x} len={}", id.as_raw(), self.len,)
31 }
32 }
33 }
34}
35
36impl Header {
37 const FLAG_RTR: usize = 0; const FLAG_FDCAN: usize = 1; const FLAG_BRS: usize = 2; pub fn new(id: embedded_can::Id, len: u8, rtr: bool) -> Header {
43 let mut flags = 0u8;
44 flags.set_bit(Self::FLAG_RTR, rtr);
45 Header { id, len, flags }
46 }
47
48 pub fn new_fd(id: embedded_can::Id, len: u8, rtr: bool, brs: bool) -> Header {
50 let mut flags = 0u8;
51 flags.set_bit(Self::FLAG_RTR, rtr);
52 flags.set_bit(Self::FLAG_FDCAN, true);
53 flags.set_bit(Self::FLAG_BRS, brs);
54 Header { id, len, flags }
55 }
56
57 pub fn id(&self) -> &embedded_can::Id {
59 &self.id
60 }
61
62 pub fn id_mut(&mut self) -> &mut embedded_can::Id {
64 &mut self.id
65 }
66
67 pub fn len(&self) -> u8 {
69 self.len
70 }
71
72 pub fn rtr(&self) -> bool {
74 self.flags.get_bit(Self::FLAG_RTR)
75 }
76
77 pub fn fdcan(&self) -> bool {
79 self.flags.get_bit(Self::FLAG_FDCAN)
80 }
81
82 pub fn bit_rate_switching(&self) -> bool {
84 self.flags.get_bit(Self::FLAG_BRS)
85 }
86
87 pub(crate) fn priority(&self) -> u32 {
89 match self.id() {
90 embedded_can::Id::Standard(id) => (id.as_raw() as u32) << 18,
91 embedded_can::Id::Extended(id) => id.as_raw(),
92 }
93 }
94}
95
96pub trait CanHeader: Sized {
99 fn from_header(header: Header, data: &[u8]) -> Result<Self, FrameCreateError>;
101
102 fn header(&self) -> &Header;
104}
105
106#[derive(Debug, Copy, Clone)]
110#[cfg_attr(feature = "defmt", derive(defmt::Format))]
111pub struct ClassicData {
112 pub(crate) bytes: [u8; 8],
113}
114
115impl ClassicData {
116 pub fn new(data: &[u8]) -> Result<Self, FrameCreateError> {
120 if data.len() > 8 {
121 return Err(FrameCreateError::InvalidDataLength);
122 }
123
124 let mut bytes = [0; 8];
125 bytes[..data.len()].copy_from_slice(data);
126
127 Ok(Self { bytes })
128 }
129
130 pub fn raw(&self) -> &[u8] {
132 &self.bytes
133 }
134
135 pub fn raw_mut(&mut self) -> &mut [u8] {
137 &mut self.bytes
138 }
139
140 pub const fn is_valid_len(len: usize) -> bool {
142 match len {
143 0..=8 => true,
144 _ => false,
145 }
146 }
147
148 #[inline]
150 pub const fn empty() -> Self {
151 Self { bytes: [0; 8] }
152 }
153}
154
155#[derive(Debug, Copy, Clone)]
158#[cfg_attr(feature = "defmt", derive(defmt::Format))]
159pub struct Frame {
160 can_header: Header,
161 data: ClassicData,
162}
163
164impl Frame {
165 pub fn new(can_header: Header, raw_data: &[u8]) -> Result<Self, FrameCreateError> {
167 let data = ClassicData::new(raw_data)?;
168 Ok(Frame { can_header, data: data })
169 }
170
171 pub fn new_data(id: impl Into<embedded_can::Id>, data: &[u8]) -> Result<Self, FrameCreateError> {
173 let eid: embedded_can::Id = id.into();
174 let header = Header::new(eid, data.len() as u8, false);
175 Self::new(header, data)
176 }
177
178 pub fn new_extended(raw_id: u32, raw_data: &[u8]) -> Result<Self, FrameCreateError> {
180 if let Some(id) = embedded_can::ExtendedId::new(raw_id) {
181 Self::new(Header::new(id.into(), raw_data.len() as u8, false), raw_data)
182 } else {
183 Err(FrameCreateError::InvalidCanId)
184 }
185 }
186
187 pub fn new_standard(raw_id: u16, raw_data: &[u8]) -> Result<Self, FrameCreateError> {
189 if let Some(id) = embedded_can::StandardId::new(raw_id) {
190 Self::new(Header::new(id.into(), raw_data.len() as u8, false), raw_data)
191 } else {
192 Err(FrameCreateError::InvalidCanId)
193 }
194 }
195
196 pub fn new_remote(id: impl Into<embedded_can::Id>, len: usize) -> Result<Self, FrameCreateError> {
198 if len <= 8usize {
199 Self::new(Header::new(id.into(), len as u8, true), &[0; 8])
200 } else {
201 Err(FrameCreateError::InvalidDataLength)
202 }
203 }
204
205 pub fn header(&self) -> &Header {
207 &self.can_header
208 }
209
210 pub fn id(&self) -> &embedded_can::Id {
212 &self.can_header.id
213 }
214
215 pub fn id_mut(&mut self) -> &mut embedded_can::Id {
217 &mut self.can_header.id
218 }
219
220 pub fn data(&self) -> &[u8] {
222 &self.data.raw()[..self.can_header.len as usize]
223 }
224
225 pub fn raw_data(&self) -> &[u8] {
227 self.data.raw()
228 }
229
230 pub fn data_mut(&mut self) -> &mut [u8] {
232 &mut self.data.raw_mut()[..self.can_header.len as usize]
233 }
234
235 pub fn priority(&self) -> u32 {
237 self.header().priority()
238 }
239}
240
241impl embedded_can::Frame for Frame {
242 fn new(id: impl Into<embedded_can::Id>, raw_data: &[u8]) -> Option<Self> {
243 let frameopt = Frame::new(Header::new(id.into(), raw_data.len() as u8, false), raw_data);
244 match frameopt {
245 Ok(frame) => Some(frame),
246 Err(_) => None,
247 }
248 }
249 fn new_remote(id: impl Into<embedded_can::Id>, len: usize) -> Option<Self> {
250 if len <= 8 {
251 let frameopt = Frame::new(Header::new(id.into(), len as u8, true), &[0; 8]);
252 match frameopt {
253 Ok(frame) => Some(frame),
254 Err(_) => None,
255 }
256 } else {
257 None
258 }
259 }
260 fn is_extended(&self) -> bool {
261 match self.can_header.id {
262 embedded_can::Id::Extended(_) => true,
263 embedded_can::Id::Standard(_) => false,
264 }
265 }
266 fn is_remote_frame(&self) -> bool {
267 self.can_header.rtr()
268 }
269 fn id(&self) -> embedded_can::Id {
270 self.can_header.id
271 }
272 fn dlc(&self) -> usize {
273 self.can_header.len as usize
274 }
275 fn data(&self) -> &[u8] {
276 &self.data()
277 }
278}
279
280impl CanHeader for Frame {
281 fn from_header(header: Header, data: &[u8]) -> Result<Self, FrameCreateError> {
282 Self::new(header, data)
283 }
284
285 fn header(&self) -> &Header {
286 self.header()
287 }
288}
289
290#[derive(Debug, Clone)]
295#[cfg_attr(feature = "defmt", derive(defmt::Format))]
296pub struct Envelope {
297 pub ts: Timestamp,
299 pub frame: Frame,
301}
302
303impl Envelope {
304 pub fn parts(self) -> (Frame, Timestamp) {
306 (self.frame, self.ts)
307 }
308}
309
310#[derive(Debug, Copy, Clone)]
314#[cfg_attr(feature = "defmt", derive(defmt::Format))]
315pub struct FdData {
316 pub(crate) bytes: [u8; 64],
317}
318
319impl FdData {
320 pub fn new(data: &[u8]) -> Result<Self, FrameCreateError> {
325 if !FdData::is_valid_len(data.len()) {
326 return Err(FrameCreateError::InvalidDataLength);
327 }
328
329 let mut bytes = [0; 64];
330 bytes[..data.len()].copy_from_slice(data);
331
332 Ok(Self { bytes })
333 }
334
335 pub fn raw(&self) -> &[u8] {
337 &self.bytes
338 }
339
340 pub fn raw_mut(&mut self) -> &mut [u8] {
342 &mut self.bytes
343 }
344
345 pub const fn is_valid_len(len: usize) -> bool {
347 match len {
348 0..=8 => true,
349 12 => true,
350 16 => true,
351 20 => true,
352 24 => true,
353 32 => true,
354 48 => true,
355 64 => true,
356 _ => false,
357 }
358 }
359
360 #[inline]
362 pub const fn empty() -> Self {
363 Self { bytes: [0; 64] }
364 }
365}
366
367#[derive(Debug, Copy, Clone)]
369#[cfg_attr(feature = "defmt", derive(defmt::Format))]
370pub struct FdFrame {
371 can_header: Header,
372 data: FdData,
373}
374
375impl FdFrame {
376 pub fn new(can_header: Header, raw_data: &[u8]) -> Result<Self, FrameCreateError> {
378 let data = FdData::new(raw_data)?;
379 Ok(FdFrame { can_header, data })
380 }
381
382 pub fn new_extended(raw_id: u32, raw_data: &[u8]) -> Result<Self, FrameCreateError> {
384 if let Some(id) = embedded_can::ExtendedId::new(raw_id) {
385 Self::new(Header::new(id.into(), raw_data.len() as u8, false), raw_data)
386 } else {
387 Err(FrameCreateError::InvalidCanId)
388 }
389 }
390
391 pub fn new_standard(raw_id: u16, raw_data: &[u8]) -> Result<Self, FrameCreateError> {
393 if let Some(id) = embedded_can::StandardId::new(raw_id) {
394 Self::new(Header::new(id.into(), raw_data.len() as u8, false), raw_data)
395 } else {
396 Err(FrameCreateError::InvalidCanId)
397 }
398 }
399
400 pub fn new_remote(id: impl Into<embedded_can::Id>, len: usize) -> Result<Self, FrameCreateError> {
402 if len <= 8 {
403 Self::new(Header::new(id.into(), len as u8, true), &[0; 8])
404 } else {
405 Err(FrameCreateError::InvalidDataLength)
406 }
407 }
408
409 pub fn header(&self) -> &Header {
411 &self.can_header
412 }
413
414 pub fn id(&self) -> &embedded_can::Id {
416 &self.can_header.id
417 }
418
419 pub fn data(&self) -> &[u8] {
421 &self.data.raw()[..self.can_header.len as usize]
422 }
423
424 pub fn data_mut(&mut self) -> &mut [u8] {
426 &mut self.data.raw_mut()[..self.can_header.len as usize]
427 }
428}
429
430impl embedded_can::Frame for FdFrame {
431 fn new(id: impl Into<embedded_can::Id>, raw_data: &[u8]) -> Option<Self> {
432 match FdFrame::new(Header::new_fd(id.into(), raw_data.len() as u8, false, true), raw_data) {
433 Ok(frame) => Some(frame),
434 Err(_) => None,
435 }
436 }
437 fn new_remote(id: impl Into<embedded_can::Id>, len: usize) -> Option<Self> {
438 if len <= 8 {
439 match FdFrame::new(Header::new_fd(id.into(), len as u8, true, true), &[0; 64]) {
440 Ok(frame) => Some(frame),
441 Err(_) => None,
442 }
443 } else {
444 None
445 }
446 }
447 fn is_extended(&self) -> bool {
448 match self.can_header.id {
449 embedded_can::Id::Extended(_) => true,
450 embedded_can::Id::Standard(_) => false,
451 }
452 }
453 fn is_remote_frame(&self) -> bool {
454 self.can_header.rtr()
455 }
456 fn id(&self) -> embedded_can::Id {
457 self.can_header.id
458 }
459 fn dlc(&self) -> usize {
461 self.can_header.len as usize
462 }
463 fn data(&self) -> &[u8] {
464 &self.data()
465 }
466}
467
468impl CanHeader for FdFrame {
469 fn from_header(header: Header, data: &[u8]) -> Result<Self, FrameCreateError> {
470 Self::new(header, data)
471 }
472
473 fn header(&self) -> &Header {
474 self.header()
475 }
476}
477
478#[derive(Debug, Clone)]
482#[cfg_attr(feature = "defmt", derive(defmt::Format))]
483pub struct FdEnvelope {
484 pub ts: Timestamp,
486
487 pub frame: FdFrame,
489}
490
491impl FdEnvelope {
492 pub fn parts(self) -> (FdFrame, Timestamp) {
494 (self.frame, self.ts)
495 }
496}