Open Model Railroad Network (OpenMRN)
Loading...
Searching...
No Matches
Crc.hxx
Go to the documentation of this file.
1
35#ifndef _UTILS_CRC_HXX_
36#define _UTILS_CRC_HXX_
37
38#include <stdint.h>
39#include <stddef.h>
40
41#ifndef CRC8DALLAS_TABLE_SIZE
43#define CRC8DALLAS_TABLE_SIZE 16
44#endif
45#ifndef CRC16CCITT_TABLE_SIZE
47#define CRC16CCITT_TABLE_SIZE 256
48#endif
49
50
59uint16_t crc_16_ibm(const void* data, size_t length_bytes);
60
74void crc3_crc16_ibm(const void* data, size_t length_bytes, uint16_t* checksum);
75
83{
84public:
86 : state_(0)
87 {
88 }
89
91 void init()
92 {
93 state_ = 0;
94 }
95
97 uint8_t get()
98 {
99 return state_;
100 }
101
105 bool check_ok()
106 {
107 return (state_ == 0);
108 }
109
114 bool check_ok(uint8_t checksum_byte)
115 {
116 return (state_ == checksum_byte);
117 }
118
122 void update0(uint8_t message_byte)
123 {
124 uint8_t data = state_ ^ message_byte;
125 uint8_t crc = 0;
126 if (data & 1)
127 {
128 crc ^= 0x5e;
129 }
130 if (data & 2)
131 {
132 crc ^= 0xbc;
133 }
134 if (data & 4)
135 {
136 crc ^= 0x61;
137 }
138 if (data & 8)
139 {
140 crc ^= 0xc2;
141 }
142 if (data & 0x10)
143 {
144 crc ^= 0x9d;
145 }
146 if (data & 0x20)
147 {
148 crc ^= 0x23;
149 }
150 if (data & 0x40)
151 {
152 crc ^= 0x46;
153 }
154 if (data & 0x80)
155 {
156 crc ^= 0x8c;
157 }
158 state_ = crc;
159 }
160
164 void update16(uint8_t message_byte)
165 {
166 uint8_t data = state_ ^ message_byte;
167 state_ = tableLo16[data & 0xf] ^ tableHi16[data >> 4];
168 }
169
173 void update256(uint8_t message_byte)
174 {
175 state_ = table256[state_ ^ message_byte];
176 }
177
180 void update(uint8_t message_byte)
181 {
182#if CRC8DALLAS_TABLE_SIZE == 0
183 update0(message_byte);
184#elif CRC8DALLAS_TABLE_SIZE == 16
185 update16(message_byte);
186#elif CRC8DALLAS_TABLE_SIZE == 256
187 update256(message_byte);
188#else
189#error "Invalid value for CRC8DALLAS_TABLE_SIZE"
190#endif
191 }
192
193private:
194 // Of the static tables here only those will be linked into a binary which
195 // have been used there.
196
198 static const uint8_t table256[256];
199
201 static const uint8_t tableHi16[16];
202
204 static const uint8_t tableLo16[16];
205
207 uint8_t state_;
208}; // Crc8DallasMaxim
209
216{
217public:
218 Crc16CCITT()
219 : state_(0xFFFF)
220 {
221 }
222
224 void init()
226 state_ = 0xFFFF;
227 }
228
230 uint16_t get()
231 {
232 return state_;
233 }
234
238 bool check_ok()
239 {
240 return (state_ == 0);
241 }
242
247 bool check_ok(uint16_t checksum)
248 {
249 return (state_ == checksum);
250 }
251
255 void update16(uint8_t message_byte)
256 {
257 uint8_t data = (state_ >> 8) ^ message_byte;
258 state_ = (state_ << 8) ^
259 tableLo16[data & 0xF] ^ tableHi16[data >> 4];
260 }
261
265 void update256(uint8_t message_byte)
266 {
267 state_ = (state_ << 8) ^ table256[(state_ >> 8) ^ message_byte];
268 }
272 void update(uint8_t message_byte)
273 {
274#if CRC16CCITT_TABLE_SIZE == 16
275 update16(message_byte);
276#elif CRC16CCITT_TABLE_SIZE == 256
277 update256(message_byte);
278#else
279#error "Invalid value for CRC16CCITT_TABLE_SIZE"
280#endif
281 }
282
286 void crc(const void* data, size_t length_bytes)
287 {
288 const uint8_t *payload = static_cast<const uint8_t*>(data);
289 init();
290 for (size_t i = 0; i < length_bytes; ++i)
291 {
292 update(payload[i]);
293 }
294 }
295
296private:
297 // Of the static tables here only those will be linked into a binary which
298 // have been used there.
299
301 static const uint16_t table256[256];
302
304 static const uint16_t tableHi16[16];
305
307 static const uint16_t tableLo16[16];
308
310 uint16_t state_;
311}; // Crc16CCITT
312
325static inline void crc3_crc16_ccitt(
326 const void* data, size_t length_bytes, uint16_t checksum[3])
327{
328 const uint8_t* payload = static_cast<const uint8_t*>(data);
329
330 Crc16CCITT crc_all;
331 Crc16CCITT crc_even;
332 Crc16CCITT crc_odd;
333
334 for (size_t i = 0; i < length_bytes; ++i)
335 {
336 crc_all.update(payload[i]);
337 if (i & 0x1)
338 {
339 // odd index bytes
340 crc_odd.update(payload[i]);
341 }
342 else
343 {
344 // even index byte
345 crc_even.update(payload[i]);
346 }
347 }
348
349 checksum[0] = crc_all.get();
350 checksum[1] = crc_even.get();
351 checksum[2] = crc_odd.get();
352}
353
354#endif // _UTILS_CRC_HXX_
void crc3_crc16_ibm(const void *data, size_t length_bytes, uint16_t *checksum)
Computes the triple-CRC value over a chunk of data.
Definition Crc.cxx:167
uint16_t crc_16_ibm(const void *data, size_t length_bytes)
Computes the 16-bit CRC value over data using the CRC16-ANSI (aka CRC16-IBM) settings.
Definition Crc.cxx:156
static void crc3_crc16_ccitt(const void *data, size_t length_bytes, uint16_t checksum[3])
Computes the triple-CRC value over a chunk of data.
Definition Crc.hxx:325
Helper class for computing CRC-16 according to the CCITT specification (polynomial = 0x1021,...
Definition Crc.hxx:216
uint16_t state_
Current value of the state register for the CRC computation.
Definition Crc.hxx:310
static const uint16_t tableHi16[16]
16-entry lookup table for the update16 function.
Definition Crc.hxx:317
static const uint16_t table256[256]
256-entry lookup table for the update256 function.
Definition Crc.hxx:275
void update16(uint8_t message_byte)
Processes one byte of the incoming message.
Definition Crc.hxx:255
static const uint16_t tableLo16[16]
16-entry lookup table for the update16 function.
Definition Crc.hxx:311
void crc(const void *data, size_t length_bytes)
Computes the 16-bit CRC value over data.
Definition Crc.hxx:286
uint16_t get()
Definition Crc.hxx:230
bool check_ok()
Checks that the message has a correct CRC.
Definition Crc.hxx:238
void update(uint8_t message_byte)
Processes one byte of the incoming message.
Definition Crc.hxx:272
void update256(uint8_t message_byte)
Processes one byte of the incoming message.
Definition Crc.hxx:265
bool check_ok(uint16_t checksum)
Checks that the message has a correct CRC.
Definition Crc.hxx:247
void init()
Re-sets the state machine for checksumming a new message.
Definition Crc.hxx:224
Helper class for computing CRC-8 according to Dallas/Maxim specification for 1-wire protocol.
Definition Crc.hxx:83
static const uint8_t tableLo16[16]
16-entry lookup table for the update16 function.
Definition Crc.hxx:262
static const uint8_t tableHi16[16]
16-entry lookup table for the update16 function.
Definition Crc.hxx:269
void update(uint8_t message_byte)
Processes one byte of the incoming message.
Definition Crc.hxx:180
bool check_ok()
Checks that the message has a correct CRC.
Definition Crc.hxx:105
void update0(uint8_t message_byte)
Processes one byte of the incoming message.
Definition Crc.hxx:122
static const uint8_t table256[256]
256-entry lookup table for the update256 function.
Definition Crc.hxx:225
void update16(uint8_t message_byte)
Processes one byte of the incoming message.
Definition Crc.hxx:164
bool check_ok(uint8_t checksum_byte)
Checks that the message has a correct CRC.
Definition Crc.hxx:114
uint8_t get()
Definition Crc.hxx:97
void update256(uint8_t message_byte)
Processes one byte of the incoming message.
Definition Crc.hxx:173
uint8_t state_
Current value of the state register for the CRC computation.
Definition Crc.hxx:207
void init()
Re-sets the state machine for checksumming a new message.
Definition Crc.hxx:91