Open Model Railroad Network (OpenMRN)
Loading...
Searching...
No Matches
Crc.cxx
Go to the documentation of this file.
1
35#include <stdint.h>
36
37#include "utils/Crc.hxx"
38#include "utils/macros.h"
39
41static const uint16_t crc_16_ibm_init_value = 0x0000; // TODO: check
43static const uint16_t crc_16_ibm_poly = 0xA001; // TODO: check
44
51uint8_t reverse(uint8_t data)
52{
53 uint8_t out = 0;
54 for (int i = 0; i < 8; i++)
55 {
56 out = (out << 1) | (data & 1);
57 data >>= 1;
58 }
59 return out;
60}
61
62/*
63
64static const uint16_t crc_16_ibm_poly = 0x8005; // WORKING
65
66inline void crc_16_ibm_add(uint16_t& state, uint8_t data)
67{
68 //data = reverse(data);
69 // This does LSB-first.
70 for (int i = 0; i < 8; i++)
71 {
72 bool bit = data & 1;
73 data >>= 1;
74 if (state & 0x8000)
75 {
76 bit = !bit;
77 }
78 if (bit)
79 {
80 state = (state << 1) ^ crc_16_ibm_poly;
81 }
82 else
83 {
84 state = (state << 1);
85 }
86 }
87}
88
89inline uint16_t crc_16_ibm_finish(uint16_t state)
90{
91 return (reverse(state & 0xff) << 8) | reverse(state >> 8);
92 //crc_16_ibm_add(state, 0);
93 //crc_16_ibm_add(state, 0);
94 //return state;
95}*/
96
98static const uint16_t CRC16_IBM_HI[16] =
99{
100 0x0000, 0xcc01, 0xd801, 0x1400, 0xf001, 0x3c00, 0x2800, 0xe401,
101 0xa001, 0x6c00, 0x7800, 0xb401, 0x5000, 0x9c01, 0x8801, 0x4400,
102};
104static const uint16_t CRC16_IBM_LO[16] =
105{
106 0x0000, 0xc0c1, 0xc181, 0x0140, 0xc301, 0x03c0, 0x0280, 0xc241,
107 0xc601, 0x06c0, 0x0780, 0xc741, 0x0500, 0xc5c1, 0xc481, 0x0440,
108};
109
115inline void __attribute__((always_inline))
116crc_16_ibm_add(uint16_t &state, uint8_t data)
117{
118 state ^= data;
119 state = (state >> 8) ^ CRC16_IBM_LO[state & 0xf] ^
120 CRC16_IBM_HI[(state >> 4) & 0xf];
121}
122
124void crc_16_ibm_add_basic(uint16_t &state, uint8_t data)
125{
126 state ^= data;
127 for (int i = 0; i < 8; i++)
128 {
129 if (state & 1)
130 {
131 state = (state >> 1) ^ crc_16_ibm_poly;
132 }
133 else
134 {
135 state = (state >> 1);
136 }
137 }
138}
139
147inline uint16_t crc_16_ibm_finish(uint16_t state)
148{
149 //return (reverse(state & 0xff) << 8) | reverse(state >> 8);
150 //crc_16_ibm_add(state, 0);
151 //crc_16_ibm_add(state, 0);
152 return state;
153}
154
155
156uint16_t crc_16_ibm(const void* data, size_t length)
157{
158 const uint8_t *payload = static_cast<const uint8_t*>(data);
159 uint16_t state = crc_16_ibm_init_value;
160 for (size_t i = 0; i < length; ++i)
161 {
162 crc_16_ibm_add(state, payload[i]);
163 }
164 return crc_16_ibm_finish(state);
165}
166
167void crc3_crc16_ibm(const void* data, size_t length_bytes, uint16_t* checksum)
168{
169 uint16_t state1 = crc_16_ibm_init_value;
170 uint16_t state2 = crc_16_ibm_init_value;
171 uint16_t state3 = crc_16_ibm_init_value;
172
173#ifdef ESP_NONOS
174 // Aligned reads only.
175 const uint32_t* payload = static_cast<const uint32_t*>(data);
176 HASSERT((((uint32_t)payload) & 3) == 0);
177 uint32_t cword = 0;
178 for (size_t i = 1; i <= length_bytes; ++i)
179 {
180 if ((i & 3) == 1)
181 {
182 cword = payload[(i - 1) >> 2];
183 }
184 else
185 {
186 cword >>= 8;
187 }
188 uint8_t cbyte = cword & 0xff;
189 crc_16_ibm_add(state1, cbyte);
190 if (i & 1)
191 {
192 // odd byte
193 crc_16_ibm_add(state2, cbyte);
194 }
195 else
196 {
197 // even byte
198 crc_16_ibm_add(state3, cbyte);
199 }
200 }
201#else
202 const uint8_t *payload = static_cast<const uint8_t*>(data);
203 for (size_t i = 1; i <= length_bytes; ++i)
204 {
205 crc_16_ibm_add(state1, payload[i-1]);
206 if (i & 1)
207 {
208 // odd byte
209 crc_16_ibm_add(state2, payload[i-1]);
210 }
211 else
212 {
213 // even byte
214 crc_16_ibm_add(state3, payload[i-1]);
215 }
216 }
217#endif
218
219 checksum[0] = crc_16_ibm_finish(state1);
220 checksum[1] = crc_16_ibm_finish(state2);
221 checksum[2] = crc_16_ibm_finish(state3);
222}
223
224// static
225const uint8_t Crc8DallasMaxim::table256[256] =
226{
227 0x00, 0x5e, 0xbc, 0xe2, 0x61, 0x3f, 0xdd, 0x83,
228 0xc2, 0x9c, 0x7e, 0x20, 0xa3, 0xfd, 0x1f, 0x41,
229 0x9d, 0xc3, 0x21, 0x7f, 0xfc, 0xa2, 0x40, 0x1e,
230 0x5f, 0x01, 0xe3, 0xbd, 0x3e, 0x60, 0x82, 0xdc,
231 0x23, 0x7d, 0x9f, 0xc1, 0x42, 0x1c, 0xfe, 0xa0,
232 0xe1, 0xbf, 0x5d, 0x03, 0x80, 0xde, 0x3c, 0x62,
233 0xbe, 0xe0, 0x02, 0x5c, 0xdf, 0x81, 0x63, 0x3d,
234 0x7c, 0x22, 0xc0, 0x9e, 0x1d, 0x43, 0xa1, 0xff,
235 0x46, 0x18, 0xfa, 0xa4, 0x27, 0x79, 0x9b, 0xc5,
236 0x84, 0xda, 0x38, 0x66, 0xe5, 0xbb, 0x59, 0x07,
237 0xdb, 0x85, 0x67, 0x39, 0xba, 0xe4, 0x06, 0x58,
238 0x19, 0x47, 0xa5, 0xfb, 0x78, 0x26, 0xc4, 0x9a,
239 0x65, 0x3b, 0xd9, 0x87, 0x04, 0x5a, 0xb8, 0xe6,
240 0xa7, 0xf9, 0x1b, 0x45, 0xc6, 0x98, 0x7a, 0x24,
241 0xf8, 0xa6, 0x44, 0x1a, 0x99, 0xc7, 0x25, 0x7b,
242 0x3a, 0x64, 0x86, 0xd8, 0x5b, 0x05, 0xe7, 0xb9,
243 0x8c, 0xd2, 0x30, 0x6e, 0xed, 0xb3, 0x51, 0x0f,
244 0x4e, 0x10, 0xf2, 0xac, 0x2f, 0x71, 0x93, 0xcd,
245 0x11, 0x4f, 0xad, 0xf3, 0x70, 0x2e, 0xcc, 0x92,
246 0xd3, 0x8d, 0x6f, 0x31, 0xb2, 0xec, 0x0e, 0x50,
247 0xaf, 0xf1, 0x13, 0x4d, 0xce, 0x90, 0x72, 0x2c,
248 0x6d, 0x33, 0xd1, 0x8f, 0x0c, 0x52, 0xb0, 0xee,
249 0x32, 0x6c, 0x8e, 0xd0, 0x53, 0x0d, 0xef, 0xb1,
250 0xf0, 0xae, 0x4c, 0x12, 0x91, 0xcf, 0x2d, 0x73,
251 0xca, 0x94, 0x76, 0x28, 0xab, 0xf5, 0x17, 0x49,
252 0x08, 0x56, 0xb4, 0xea, 0x69, 0x37, 0xd5, 0x8b,
253 0x57, 0x09, 0xeb, 0xb5, 0x36, 0x68, 0x8a, 0xd4,
254 0x95, 0xcb, 0x29, 0x77, 0xf4, 0xaa, 0x48, 0x16,
255 0xe9, 0xb7, 0x55, 0x0b, 0x88, 0xd6, 0x34, 0x6a,
256 0x2b, 0x75, 0x97, 0xc9, 0x4a, 0x14, 0xf6, 0xa8,
257 0x74, 0x2a, 0xc8, 0x96, 0x15, 0x4b, 0xa9, 0xf7,
258 0xb6, 0xe8, 0x0a, 0x54, 0xd7, 0x89, 0x6b, 0x35,
259};
260
261// static
262const uint8_t Crc8DallasMaxim::tableLo16[16] =
263{
264 0x00, 0x5e, 0xbc, 0xe2, 0x61, 0x3f, 0xdd, 0x83,
265 0xc2, 0x9c, 0x7e, 0x20, 0xa3, 0xfd, 0x1f, 0x41,
266};
267
268// static
269const uint8_t Crc8DallasMaxim::tableHi16[16] =
270{
271 0x00, 0x9d, 0x23, 0xbe, 0x46, 0xdb, 0x65, 0xf8,
272 0x8c, 0x11, 0xaf, 0x32, 0xca, 0x57, 0xe9, 0x74
273};
274
275const uint16_t Crc16CCITT::table256[256] =
276{
277 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7,
278 0x8108, 0x9129, 0xA14A, 0xB16B, 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF,
279 0x1231, 0x0210, 0x3273, 0x2252, 0x52B5, 0x4294, 0x72F7, 0x62D6,
280 0x9339, 0x8318, 0xB37B, 0xA35A, 0xD3BD, 0xC39C, 0xF3FF, 0xE3DE,
281 0x2462, 0x3443, 0x0420, 0x1401, 0x64E6, 0x74C7, 0x44A4, 0x5485,
282 0xA56A, 0xB54B, 0x8528, 0x9509, 0xE5EE, 0xF5CF, 0xC5AC, 0xD58D,
283 0x3653, 0x2672, 0x1611, 0x0630, 0x76D7, 0x66F6, 0x5695, 0x46B4,
284 0xB75B, 0xA77A, 0x9719, 0x8738, 0xF7DF, 0xE7FE, 0xD79D, 0xC7BC,
285 0x48C4, 0x58E5, 0x6886, 0x78A7, 0x0840, 0x1861, 0x2802, 0x3823,
286 0xC9CC, 0xD9ED, 0xE98E, 0xF9AF, 0x8948, 0x9969, 0xA90A, 0xB92B,
287 0x5AF5, 0x4AD4, 0x7AB7, 0x6A96, 0x1A71, 0x0A50, 0x3A33, 0x2A12,
288 0xDBFD, 0xCBDC, 0xFBBF, 0xEB9E, 0x9B79, 0x8B58, 0xBB3B, 0xAB1A,
289 0x6CA6, 0x7C87, 0x4CE4, 0x5CC5, 0x2C22, 0x3C03, 0x0C60, 0x1C41,
290 0xEDAE, 0xFD8F, 0xCDEC, 0xDDCD, 0xAD2A, 0xBD0B, 0x8D68, 0x9D49,
291 0x7E97, 0x6EB6, 0x5ED5, 0x4EF4, 0x3E13, 0x2E32, 0x1E51, 0x0E70,
292 0xFF9F, 0xEFBE, 0xDFDD, 0xCFFC, 0xBF1B, 0xAF3A, 0x9F59, 0x8F78,
293 0x9188, 0x81A9, 0xB1CA, 0xA1EB, 0xD10C, 0xC12D, 0xF14E, 0xE16F,
294 0x1080, 0x00A1, 0x30C2, 0x20E3, 0x5004, 0x4025, 0x7046, 0x6067,
295 0x83B9, 0x9398, 0xA3FB, 0xB3DA, 0xC33D, 0xD31C, 0xE37F, 0xF35E,
296 0x02B1, 0x1290, 0x22F3, 0x32D2, 0x4235, 0x5214, 0x6277, 0x7256,
297 0xB5EA, 0xA5CB, 0x95A8, 0x8589, 0xF56E, 0xE54F, 0xD52C, 0xC50D,
298 0x34E2, 0x24C3, 0x14A0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
299 0xA7DB, 0xB7FA, 0x8799, 0x97B8, 0xE75F, 0xF77E, 0xC71D, 0xD73C,
300 0x26D3, 0x36F2, 0x0691, 0x16B0, 0x6657, 0x7676, 0x4615, 0x5634,
301 0xD94C, 0xC96D, 0xF90E, 0xE92F, 0x99C8, 0x89E9, 0xB98A, 0xA9AB,
302 0x5844, 0x4865, 0x7806, 0x6827, 0x18C0, 0x08E1, 0x3882, 0x28A3,
303 0xCB7D, 0xDB5C, 0xEB3F, 0xFB1E, 0x8BF9, 0x9BD8, 0xABBB, 0xBB9A,
304 0x4A75, 0x5A54, 0x6A37, 0x7A16, 0x0AF1, 0x1AD0, 0x2AB3, 0x3A92,
305 0xFD2E, 0xED0F, 0xDD6C, 0xCD4D, 0xBDAA, 0xAD8B, 0x9DE8, 0x8DC9,
306 0x7C26, 0x6C07, 0x5C64, 0x4C45, 0x3CA2, 0x2C83, 0x1CE0, 0x0CC1,
307 0xEF1F, 0xFF3E, 0xCF5D, 0xDF7C, 0xAF9B, 0xBFBA, 0x8FD9, 0x9FF8,
308 0x6E17, 0x7E36, 0x4E55, 0x5E74, 0x2E93, 0x3EB2, 0x0ED1, 0x1EF0
309};
310
311const uint16_t Crc16CCITT::tableLo16[16] =
312{
313 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7,
314 0x8108, 0x9129, 0xA14A, 0xB16B, 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF
315};
316
317const uint16_t Crc16CCITT::tableHi16[16] =
318{
319 0x0000, 0x1231, 0x2462, 0x3653, 0x48C4, 0x5AF5, 0x6CA6, 0x7E97,
320 0x9188, 0x83B9, 0xB5EA, 0xA7DB, 0xD94C, 0xCB7D, 0xFD2E, 0xEF1F
321};
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
static const uint16_t crc_16_ibm_init_value
Initialization value for the CRC-16-IBM calculator.
Definition Crc.cxx:41
static const uint16_t CRC16_IBM_LO[16]
Translation table for crc16-ibm, low nibble.
Definition Crc.cxx:104
uint8_t reverse(uint8_t data)
Reverses the bits of a byte.
Definition Crc.cxx:51
uint16_t crc_16_ibm_finish(uint16_t state)
Finalizes the state machine of a CRC16-IBM calculator.
Definition Crc.cxx:147
static const uint16_t CRC16_IBM_HI[16]
Translation table for crc16-ibm, high nibble.
Definition Crc.cxx:98
void crc_16_ibm_add(uint16_t &state, uint8_t data)
Appends a byte to a CRC16 state machine.
Definition Crc.cxx:116
uint16_t crc_16_ibm(const void *data, size_t length)
Computes the 16-bit CRC value over data using the CRC16-ANSI (aka CRC16-IBM) settings.
Definition Crc.cxx:156
static const uint16_t crc_16_ibm_poly
Polynomial for the CRC-16-IBM calculator.
Definition Crc.cxx:43
void crc_16_ibm_add_basic(uint16_t &state, uint8_t data)
Bitwise implementation of the crc16 ibm add.
Definition Crc.cxx:124
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
static const uint16_t tableLo16[16]
16-entry lookup table for the update16 function.
Definition Crc.hxx:311
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
static const uint8_t table256[256]
256-entry lookup table for the update256 function.
Definition Crc.hxx:225
#define HASSERT(x)
Checks that the value of expression x is true, else terminates the current process.
Definition macros.h:138