15
15
#include < inttypes.h>
16
16
#include < string.h>
17
17
18
- #include < Arduino.h>
18
+ #include " Print.h"
19
+ #include " Printable.h"
20
+ #include " Common.h"
19
21
20
22
/* *************************************************************************************
21
23
* NAMESPACE
@@ -31,14 +33,19 @@ namespace arduino
31
33
class CanMsg : public Printable
32
34
{
33
35
public:
34
- static size_t constexpr MAX_DATA_LENGTH = 8 ;
36
+ static uint8_t constexpr MAX_DATA_LENGTH = 8 ;
37
+
38
+ static uint32_t constexpr CAN_EFF_FLAG = 0x80000000U ;
39
+ static uint32_t constexpr CAN_SFF_MASK = 0x000007FFU ; /* standard frame format (SFF) */
40
+ static uint32_t constexpr CAN_EFF_MASK = 0x1FFFFFFFU ; /* extended frame format (EFF) */
41
+
35
42
36
43
CanMsg (uint32_t const can_id, uint8_t const can_data_len, uint8_t const * can_data_ptr)
37
44
: id{can_id}
38
- , data_length{can_data_len}
45
+ , data_length{min ( can_data_len, MAX_DATA_LENGTH) }
39
46
, data{0 }
40
47
{
41
- memcpy (data, can_data_ptr, min (can_data_len, MAX_DATA_LENGTH) );
48
+ memcpy (data, can_data_ptr, data_length );
42
49
}
43
50
44
51
CanMsg () : CanMsg(0 , 0 , nullptr ) { }
@@ -52,14 +59,15 @@ class CanMsg : public Printable
52
59
53
60
virtual ~CanMsg () { }
54
61
55
- void operator = (CanMsg const & other)
62
+ CanMsg & operator = (CanMsg const & other)
56
63
{
57
- if (this == &other)
58
- return ;
59
-
60
- this ->id = other.id ;
61
- this ->data_length = other.data_length ;
62
- memcpy (this ->data , other.data , this ->data_length );
64
+ if (this != &other)
65
+ {
66
+ this ->id = other.id ;
67
+ this ->data_length = other.data_length ;
68
+ memcpy (this ->data , other.data , this ->data_length );
69
+ }
70
+ return (*this );
63
71
}
64
72
65
73
virtual size_t printTo (Print & p) const override
@@ -68,7 +76,10 @@ class CanMsg : public Printable
68
76
size_t len = 0 ;
69
77
70
78
/* Print the header. */
71
- len = snprintf (buf, sizeof (buf), " [%08" PRIX32 " ] (%d) : " , id, data_length);
79
+ if (isStandardId ())
80
+ len = snprintf (buf, sizeof (buf), " [%03" PRIX32 " ] (%d) : " , getStandardId (), data_length);
81
+ else
82
+ len = snprintf (buf, sizeof (buf), " [%08" PRIX32 " ] (%d) : " , getExtendedId (), data_length);
72
83
size_t n = p.write (buf, len);
73
84
74
85
/* Print the data. */
@@ -82,11 +93,45 @@ class CanMsg : public Printable
82
93
return n;
83
94
}
84
95
96
+
97
+ uint32_t getStandardId () const {
98
+ return (id & CAN_SFF_MASK);
99
+ }
100
+ uint32_t getExtendedId () const {
101
+ return (id & CAN_EFF_MASK);
102
+ }
103
+ bool isStandardId () const {
104
+ return ((id & CAN_EFF_FLAG) == 0 );
105
+ }
106
+ bool isExtendedId () const {
107
+ return ((id & CAN_EFF_FLAG) == CAN_EFF_FLAG);
108
+ }
109
+
110
+
111
+ /*
112
+ * CAN ID semantics (mirroring definition by linux/can.h):
113
+ * |- Bit 31 : frame format flag (0 = standard 11 bit, 1 = extended 29 bit)
114
+ * |- Bit 30 : reserved (future remote transmission request flag)
115
+ * |- Bit 29 : reserved (future error frame flag)
116
+ * |- Bit 0-28 : CAN identifier (11/29 bit)
117
+ */
85
118
uint32_t id;
86
119
uint8_t data_length;
87
120
uint8_t data[MAX_DATA_LENGTH];
88
121
};
89
122
123
+ /* *************************************************************************************
124
+ * FREE FUNCTIONS
125
+ **************************************************************************************/
126
+
127
+ inline uint32_t CanStandardId (uint32_t const id) {
128
+ return (id & CanMsg::CAN_SFF_MASK);
129
+ }
130
+
131
+ inline uint32_t CanExtendedId (uint32_t const id) {
132
+ return (CanMsg::CAN_EFF_FLAG | (id & CanMsg::CAN_EFF_MASK));
133
+ }
134
+
90
135
/* *************************************************************************************
91
136
* NAMESPACE
92
137
**************************************************************************************/
0 commit comments