1212 * INCLUDE
1313 **************************************************************************************/
1414
15- #include < stdint .h>
15+ #include < inttypes .h>
1616#include < string.h>
1717
18- #include < Arduino.h>
18+ #include " Print.h"
19+ #include " Printable.h"
20+ #include " Common.h"
1921
2022/* *************************************************************************************
2123 * NAMESPACE
@@ -31,14 +33,19 @@ namespace arduino
3133class CanMsg :public Printable
3234{
3335public:
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+
3542
3643CanMsg (uint32_t const can_id,uint8_t const can_data_len,uint8_t const * can_data_ptr)
3744 : id{can_id}
38- , data_length{can_data_len}
45+ , data_length{min ( can_data_len, MAX_DATA_LENGTH) }
3946 , data{0 }
4047 {
41- memcpy (data, can_data_ptr,min (can_data_len, MAX_DATA_LENGTH) );
48+ memcpy (data, can_data_ptr,data_length );
4249 }
4350
4451CanMsg () : CanMsg(0 ,0 ,nullptr ) { }
@@ -52,14 +59,15 @@ class CanMsg : public Printable
5259
5360virtual ~CanMsg () { }
5461
55- void operator = (CanMsgconst & other)
62+ CanMsg & operator = (CanMsgconst & other)
5663 {
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 );
6371 }
6472
6573virtual size_t printTo (Print & p)const override
@@ -68,7 +76,10 @@ class CanMsg : public Printable
6876size_t len =0 ;
6977
7078/* Print the header.*/
71- len =snprintf (buf,sizeof (buf)," [%08X] (%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);
7283size_t n = p.write (buf, len);
7384
7485/* Print the data.*/
@@ -82,11 +93,45 @@ class CanMsg : public Printable
8293return n;
8394 }
8495
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+ */
85118uint32_t id;
86119uint8_t data_length;
87120uint8_t data[MAX_DATA_LENGTH];
88121};
89122
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+
90135/* *************************************************************************************
91136 * NAMESPACE
92137 **************************************************************************************/