pamoja_can/id.rs
1//! The CAN identifier: a standard 11-bit or extended 29-bit arbitration ID.
2
3/// A CAN arbitration identifier.
4///
5/// CAN comes in two identifier widths: the original standard 11-bit form and the extended
6/// 29-bit form that higher-layer protocols such as J1939 use to pack a priority, a
7/// parameter group, and addresses into the ID itself. This type holds either, always
8/// masked to its width.
9///
10/// # Examples
11///
12/// ```
13/// use pamoja_can::CanId;
14///
15/// let std = CanId::standard(0x123);
16/// assert!(!std.is_extended());
17/// assert_eq!(std.raw(), 0x123);
18///
19/// // Values wider than the identifier are masked to fit.
20/// assert_eq!(CanId::standard(0xFFFF).raw(), 0x7FF);
21/// ```
22#[derive(Clone, Copy, Debug, PartialEq, Eq)]
23pub struct CanId {
24 bits: u32,
25 extended: bool,
26}
27
28impl CanId {
29 /// The mask of a standard 11-bit identifier.
30 pub const STANDARD_MASK: u32 = 0x7FF;
31
32 /// The mask of an extended 29-bit identifier.
33 pub const EXTENDED_MASK: u32 = 0x1FFF_FFFF;
34
35 /// Creates a standard 11-bit identifier, masking the value to fit.
36 ///
37 /// # Arguments
38 ///
39 /// * `raw` - the identifier value; bits above the low 11 are dropped.
40 ///
41 /// # Returns
42 ///
43 /// The identifier.
44 pub fn standard(raw: u16) -> CanId {
45 CanId {
46 bits: u32::from(raw) & Self::STANDARD_MASK,
47 extended: false,
48 }
49 }
50
51 /// Creates an extended 29-bit identifier, masking the value to fit.
52 ///
53 /// # Arguments
54 ///
55 /// * `raw` - the identifier value; bits above the low 29 are dropped.
56 ///
57 /// # Returns
58 ///
59 /// The identifier.
60 pub fn extended(raw: u32) -> CanId {
61 CanId {
62 bits: raw & Self::EXTENDED_MASK,
63 extended: true,
64 }
65 }
66
67 /// Returns the identifier value.
68 ///
69 /// # Returns
70 ///
71 /// The raw bits, already masked to the identifier's width.
72 pub fn raw(&self) -> u32 {
73 self.bits
74 }
75
76 /// Reports whether this is an extended 29-bit identifier.
77 ///
78 /// # Returns
79 ///
80 /// `true` for an extended identifier, `false` for a standard one.
81 pub fn is_extended(&self) -> bool {
82 self.extended
83 }
84}