Port of teensy 3 FastCRC library, uses hardware CRC

Dependents:   fastCRCperf

Port of teensy 3 FastCRC library, uses hardware CRC on K64F. About 30 times faster than Arduino CRC (crc16.h).

https://github.com/FrankBoesing/FastCRC

teensy forum discussions on FastCRC https://forum.pjrc.com/threads/25699-Fast-CRC-library-(uses-the-built-in-crc-module-in-Teensy3)

Committer:
manitou
Date:
Fri Apr 22 17:07:33 2016 +0000
Revision:
1:1ce0f4ee7357
Parent:
0:7343f324d853
table-drive bug fix

Who changed what in which revision?

UserRevisionLine numberNew contents of line
manitou 0:7343f324d853 1 /* FastCRC library code is placed under the MIT license
manitou 0:7343f324d853 2 * Copyright (c) 2014,2015 Frank Bösing
manitou 0:7343f324d853 3 *
manitou 0:7343f324d853 4 * Permission is hereby granted, free of charge, to any person obtaining
manitou 0:7343f324d853 5 * a copy of this software and associated documentation files (the
manitou 0:7343f324d853 6 * "Software"), to deal in the Software without restriction, including
manitou 0:7343f324d853 7 * without limitation the rights to use, copy, modify, merge, publish,
manitou 0:7343f324d853 8 * distribute, sublicense, and/or sell copies of the Software, and to
manitou 0:7343f324d853 9 * permit persons to whom the Software is furnished to do so, subject to
manitou 0:7343f324d853 10 * the following conditions:
manitou 0:7343f324d853 11 *
manitou 0:7343f324d853 12 * The above copyright notice and this permission notice shall be
manitou 0:7343f324d853 13 * included in all copies or substantial portions of the Software.
manitou 0:7343f324d853 14 *
manitou 0:7343f324d853 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
manitou 0:7343f324d853 16 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
manitou 0:7343f324d853 17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
manitou 0:7343f324d853 18 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
manitou 0:7343f324d853 19 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
manitou 0:7343f324d853 20 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
manitou 0:7343f324d853 21 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
manitou 0:7343f324d853 22 * SOFTWARE.
manitou 0:7343f324d853 23 */
manitou 0:7343f324d853 24
manitou 0:7343f324d853 25 //
manitou 0:7343f324d853 26 // Thanks to:
manitou 0:7343f324d853 27 // - Catalogue of parametrised CRC algorithms, CRC RevEng
manitou 0:7343f324d853 28 // http://reveng.sourceforge.net/crc-catalogue/
manitou 0:7343f324d853 29 //
manitou 0:7343f324d853 30 // - Danjel McGougan (CRC-Table-Generator)
manitou 0:7343f324d853 31 //
manitou 0:7343f324d853 32
manitou 0:7343f324d853 33
manitou 0:7343f324d853 34 #if !defined(__CORTEX_M4)
manitou 0:7343f324d853 35
manitou 0:7343f324d853 36 #include "FastCRC.h"
manitou 0:7343f324d853 37 #include "FastCRC_cpu.h"
manitou 0:7343f324d853 38 #include "FastCRC_tables.h"
manitou 0:7343f324d853 39
manitou 0:7343f324d853 40
manitou 0:7343f324d853 41 // ================= 8-BIT CRC ===================
manitou 0:7343f324d853 42
manitou 0:7343f324d853 43 /** Constructor
manitou 0:7343f324d853 44 */
manitou 0:7343f324d853 45 FastCRC8::FastCRC8(){}
manitou 0:7343f324d853 46
manitou 0:7343f324d853 47 /** SMBUS CRC
manitou 0:7343f324d853 48 * aka CRC-8
manitou 0:7343f324d853 49 * @param data Pointer to Data
manitou 0:7343f324d853 50 * @param datalen Length of Data
manitou 0:7343f324d853 51 * @return CRC value
manitou 0:7343f324d853 52 */
manitou 0:7343f324d853 53 uint8_t FastCRC8::smbus_upd(const uint8_t *data, uint16_t datalen)
manitou 0:7343f324d853 54 {
manitou 0:7343f324d853 55 uint8_t crc = seed;
manitou 0:7343f324d853 56 if (datalen) do {
manitou 0:7343f324d853 57 crc = crc_table_smbus[crc ^ *data];
manitou 0:7343f324d853 58 data++;
manitou 0:7343f324d853 59 } while (--datalen);
manitou 0:7343f324d853 60 seed = crc;
manitou 0:7343f324d853 61 return crc;
manitou 0:7343f324d853 62 }
manitou 0:7343f324d853 63
manitou 0:7343f324d853 64 uint8_t FastCRC8::smbus(const uint8_t *data, const uint16_t datalen)
manitou 0:7343f324d853 65 {
manitou 0:7343f324d853 66 // poly=0x07 init=0x00 refin=false refout=false xorout=0x00 check=0xf4
manitou 0:7343f324d853 67 seed = 0x00;
manitou 0:7343f324d853 68 return smbus_upd(data, datalen);
manitou 0:7343f324d853 69 }
manitou 0:7343f324d853 70
manitou 0:7343f324d853 71 /** MAXIM 8-Bit CRC
manitou 0:7343f324d853 72 * equivalent to _crc_ibutton_update() in crc16.h from avr_libc
manitou 0:7343f324d853 73 * @param data Pointer to Data
manitou 0:7343f324d853 74 * @param datalen Length of Data
manitou 0:7343f324d853 75 * @return CRC value
manitou 0:7343f324d853 76 */
manitou 0:7343f324d853 77 uint8_t FastCRC8::maxim_upd(const uint8_t *data, uint16_t datalen)
manitou 0:7343f324d853 78 {
manitou 0:7343f324d853 79 uint8_t crc = seed;
manitou 0:7343f324d853 80 if (datalen) do {
manitou 0:7343f324d853 81 crc = crc_table_maxim[crc ^ *data];
manitou 0:7343f324d853 82 data++;
manitou 0:7343f324d853 83 } while (--datalen);
manitou 0:7343f324d853 84 seed = crc;
manitou 0:7343f324d853 85 return crc;
manitou 0:7343f324d853 86 }
manitou 0:7343f324d853 87 uint8_t FastCRC8::maxim(const uint8_t *data, const uint16_t datalen)
manitou 0:7343f324d853 88 {
manitou 0:7343f324d853 89 // poly=0x31 init=0x00 refin=true refout=true xorout=0x00 check=0xa1
manitou 0:7343f324d853 90 seed = 0x00;
manitou 0:7343f324d853 91 return maxim_upd(data, datalen);
manitou 0:7343f324d853 92 }
manitou 0:7343f324d853 93
manitou 0:7343f324d853 94 // ================= 16-BIT CRC ===================
manitou 0:7343f324d853 95 /** Constructor
manitou 0:7343f324d853 96 */
manitou 0:7343f324d853 97 FastCRC16::FastCRC16(){}
manitou 0:7343f324d853 98
manitou 0:7343f324d853 99 #define crc_n4(crc, data, table) crc ^= data; \
manitou 0:7343f324d853 100 crc = table[(crc & 0xff) + 0x300] ^ \
manitou 0:7343f324d853 101 table[((crc >> 8) & 0xff) + 0x200] ^ \
manitou 0:7343f324d853 102 table[((data >> 16) & 0xff) + 0x100] ^ \
manitou 0:7343f324d853 103 table[data >> 24];
manitou 0:7343f324d853 104
manitou 0:7343f324d853 105 /** CCITT
manitou 0:7343f324d853 106 * Alias "false CCITT"
manitou 0:7343f324d853 107 * @param data Pointer to Data
manitou 0:7343f324d853 108 * @param datalen Length of Data
manitou 0:7343f324d853 109 * @return CRC value
manitou 0:7343f324d853 110 */
manitou 0:7343f324d853 111 uint16_t FastCRC16::ccitt_upd(const uint8_t *data, uint16_t len)
manitou 0:7343f324d853 112 {
manitou 0:7343f324d853 113
manitou 0:7343f324d853 114 uint16_t crc = seed;
manitou 0:7343f324d853 115
manitou 0:7343f324d853 116 while (((uintptr_t)data & 3) && len) {
manitou 0:7343f324d853 117 crc = (crc >> 8) ^ crc_table_ccitt[(crc & 0xff) ^ *data++];
manitou 0:7343f324d853 118 len--;
manitou 0:7343f324d853 119 }
manitou 0:7343f324d853 120
manitou 0:7343f324d853 121 while (len >= 16) {
manitou 0:7343f324d853 122 len -= 16;
manitou 0:7343f324d853 123 crc_n4(crc, ((uint32_t *)data)[0], crc_table_ccitt);
manitou 0:7343f324d853 124 crc_n4(crc, ((uint32_t *)data)[1], crc_table_ccitt);
manitou 0:7343f324d853 125 crc_n4(crc, ((uint32_t *)data)[2], crc_table_ccitt);
manitou 0:7343f324d853 126 crc_n4(crc, ((uint32_t *)data)[3], crc_table_ccitt);
manitou 0:7343f324d853 127 data += 16;
manitou 0:7343f324d853 128 }
manitou 0:7343f324d853 129
manitou 0:7343f324d853 130 while (len--) {
manitou 0:7343f324d853 131 crc = (crc >> 8) ^ crc_table_ccitt[(crc & 0xff) ^ *data++];
manitou 0:7343f324d853 132 }
manitou 0:7343f324d853 133
manitou 0:7343f324d853 134 crc = REV16(crc);
manitou 0:7343f324d853 135
manitou 0:7343f324d853 136 seed = crc;
manitou 0:7343f324d853 137 return crc;
manitou 0:7343f324d853 138 }
manitou 0:7343f324d853 139 uint16_t FastCRC16::ccitt(const uint8_t *data,const uint16_t datalen)
manitou 0:7343f324d853 140 {
manitou 0:7343f324d853 141 // poly=0x1021 init=0xffff refin=false refout=false xorout=0x0000 check=0x29b1
manitou 0:7343f324d853 142 seed = 0xffff;
manitou 0:7343f324d853 143 return ccitt_upd(data, datalen);
manitou 0:7343f324d853 144 }
manitou 0:7343f324d853 145
manitou 0:7343f324d853 146 /** MCRF4XX
manitou 0:7343f324d853 147 * equivalent to _crc_ccitt_update() in crc16.h from avr_libc
manitou 0:7343f324d853 148 * @param data Pointer to Data
manitou 0:7343f324d853 149 * @param datalen Length of Data
manitou 0:7343f324d853 150 * @return CRC value
manitou 0:7343f324d853 151 */
manitou 0:7343f324d853 152
manitou 0:7343f324d853 153 uint16_t FastCRC16::mcrf4xx_upd(const uint8_t *data, uint16_t len)
manitou 0:7343f324d853 154 {
manitou 0:7343f324d853 155
manitou 0:7343f324d853 156 uint16_t crc = seed;
manitou 0:7343f324d853 157
manitou 0:7343f324d853 158 while (((uintptr_t)data & 3) && len) {
manitou 0:7343f324d853 159 crc = (crc >> 8) ^ crc_table_mcrf4xx[(crc & 0xff) ^ *data++];
manitou 0:7343f324d853 160 len--;
manitou 0:7343f324d853 161 }
manitou 0:7343f324d853 162
manitou 0:7343f324d853 163 while (len >= 16) {
manitou 0:7343f324d853 164 len -= 16;
manitou 0:7343f324d853 165 crc_n4(crc, ((uint32_t *)data)[0], crc_table_mcrf4xx);
manitou 0:7343f324d853 166 crc_n4(crc, ((uint32_t *)data)[1], crc_table_mcrf4xx);
manitou 0:7343f324d853 167 crc_n4(crc, ((uint32_t *)data)[2], crc_table_mcrf4xx);
manitou 0:7343f324d853 168 crc_n4(crc, ((uint32_t *)data)[3], crc_table_mcrf4xx);
manitou 0:7343f324d853 169 data += 16;
manitou 0:7343f324d853 170 }
manitou 0:7343f324d853 171
manitou 0:7343f324d853 172 while (len--) {
manitou 0:7343f324d853 173 crc = (crc >> 8) ^ crc_table_mcrf4xx[(crc & 0xff) ^ *data++];
manitou 0:7343f324d853 174 }
manitou 0:7343f324d853 175
manitou 0:7343f324d853 176 seed = crc;
manitou 0:7343f324d853 177 return crc;
manitou 0:7343f324d853 178 }
manitou 0:7343f324d853 179
manitou 0:7343f324d853 180 uint16_t FastCRC16::mcrf4xx(const uint8_t *data,const uint16_t datalen)
manitou 0:7343f324d853 181 {
manitou 0:7343f324d853 182 // poly=0x1021 init=0xffff refin=true refout=true xorout=0x0000 check=0x6f91
manitou 0:7343f324d853 183 seed = 0xffff;
manitou 0:7343f324d853 184 return mcrf4xx_upd(data, datalen);
manitou 0:7343f324d853 185 }
manitou 0:7343f324d853 186
manitou 0:7343f324d853 187 /** MODBUS
manitou 0:7343f324d853 188 * equivalent to _crc_16_update() in crc16.h from avr_libc
manitou 0:7343f324d853 189 * @param data Pointer to Data
manitou 0:7343f324d853 190 * @param datalen Length of Data
manitou 0:7343f324d853 191 * @return CRC value
manitou 0:7343f324d853 192 */
manitou 0:7343f324d853 193 uint16_t FastCRC16::modbus_upd(const uint8_t *data, uint16_t len)
manitou 0:7343f324d853 194 {
manitou 0:7343f324d853 195
manitou 0:7343f324d853 196 uint16_t crc = seed;
manitou 0:7343f324d853 197
manitou 0:7343f324d853 198 while (((uintptr_t)data & 3) && len) {
manitou 0:7343f324d853 199 crc = (crc >> 8) ^ crc_table_modbus[(crc & 0xff) ^ *data++];
manitou 0:7343f324d853 200 len--;
manitou 0:7343f324d853 201 }
manitou 0:7343f324d853 202
manitou 0:7343f324d853 203 while (len >= 16) {
manitou 0:7343f324d853 204 len -= 16;
manitou 0:7343f324d853 205 crc_n4(crc, ((uint32_t *)data)[0], crc_table_modbus);
manitou 0:7343f324d853 206 crc_n4(crc, ((uint32_t *)data)[1], crc_table_modbus);
manitou 0:7343f324d853 207 crc_n4(crc, ((uint32_t *)data)[2], crc_table_modbus);
manitou 0:7343f324d853 208 crc_n4(crc, ((uint32_t *)data)[3], crc_table_modbus);
manitou 0:7343f324d853 209 data += 16;
manitou 0:7343f324d853 210 }
manitou 0:7343f324d853 211
manitou 0:7343f324d853 212 while (len--) {
manitou 0:7343f324d853 213 crc = (crc >> 8) ^ crc_table_modbus[(crc & 0xff) ^ *data++];
manitou 0:7343f324d853 214 }
manitou 0:7343f324d853 215
manitou 0:7343f324d853 216 seed = crc;
manitou 0:7343f324d853 217 return crc;
manitou 0:7343f324d853 218 }
manitou 0:7343f324d853 219
manitou 0:7343f324d853 220 uint16_t FastCRC16::modbus(const uint8_t *data, const uint16_t datalen)
manitou 0:7343f324d853 221 {
manitou 0:7343f324d853 222 // poly=0x8005 init=0xffff refin=true refout=true xorout=0x0000 check=0x4b37
manitou 0:7343f324d853 223 seed = 0xffff;
manitou 0:7343f324d853 224 return modbus_upd(data, datalen);
manitou 0:7343f324d853 225 }
manitou 0:7343f324d853 226
manitou 0:7343f324d853 227 /** KERMIT
manitou 0:7343f324d853 228 * Alias CRC-16/CCITT, CRC-16/CCITT-TRUE, CRC-CCITT
manitou 0:7343f324d853 229 * @param data Pointer to Data
manitou 0:7343f324d853 230 * @param datalen Length of Data
manitou 0:7343f324d853 231 * @return CRC value
manitou 0:7343f324d853 232 */
manitou 0:7343f324d853 233 uint16_t FastCRC16::kermit_upd(const uint8_t *data, uint16_t len)
manitou 0:7343f324d853 234 {
manitou 0:7343f324d853 235
manitou 0:7343f324d853 236 uint16_t crc = seed;
manitou 0:7343f324d853 237
manitou 0:7343f324d853 238 while (((uintptr_t)data & 3) && len) {
manitou 0:7343f324d853 239 crc = (crc >> 8) ^ crc_table_kermit[(crc & 0xff) ^ *data++];
manitou 0:7343f324d853 240 len--;
manitou 0:7343f324d853 241 }
manitou 0:7343f324d853 242
manitou 0:7343f324d853 243 while (len >= 16) {
manitou 0:7343f324d853 244 len -= 16;
manitou 0:7343f324d853 245 crc_n4(crc, ((uint32_t *)data)[0], crc_table_kermit);
manitou 0:7343f324d853 246 crc_n4(crc, ((uint32_t *)data)[1], crc_table_kermit);
manitou 0:7343f324d853 247 crc_n4(crc, ((uint32_t *)data)[2], crc_table_kermit);
manitou 0:7343f324d853 248 crc_n4(crc, ((uint32_t *)data)[3], crc_table_kermit);
manitou 0:7343f324d853 249 data += 16;
manitou 0:7343f324d853 250 }
manitou 0:7343f324d853 251
manitou 0:7343f324d853 252 while (len--) {
manitou 0:7343f324d853 253 crc = (crc >> 8) ^ crc_table_kermit[(crc & 0xff) ^ *data++];
manitou 0:7343f324d853 254 }
manitou 0:7343f324d853 255
manitou 0:7343f324d853 256 seed = crc;
manitou 0:7343f324d853 257 return crc;
manitou 0:7343f324d853 258 }
manitou 0:7343f324d853 259
manitou 0:7343f324d853 260 uint16_t FastCRC16::kermit(const uint8_t *data, const uint16_t datalen)
manitou 0:7343f324d853 261 {
manitou 0:7343f324d853 262 // poly=0x1021 init=0x0000 refin=true refout=true xorout=0x0000 check=0x2189
manitou 0:7343f324d853 263 // sometimes byteswapped presentation of result
manitou 0:7343f324d853 264 seed = 0x0000;
manitou 0:7343f324d853 265 return kermit_upd(data, datalen);
manitou 0:7343f324d853 266 }
manitou 0:7343f324d853 267
manitou 0:7343f324d853 268 /** XMODEM
manitou 0:7343f324d853 269 * Alias ZMODEM, CRC-16/ACORN
manitou 0:7343f324d853 270 * @param data Pointer to Data
manitou 0:7343f324d853 271 * @param datalen Length of Data
manitou 0:7343f324d853 272 * @return CRC value
manitou 0:7343f324d853 273 */
manitou 0:7343f324d853 274 uint16_t FastCRC16::xmodem_upd(const uint8_t *data, uint16_t len)
manitou 0:7343f324d853 275 {
manitou 0:7343f324d853 276
manitou 0:7343f324d853 277 uint16_t crc = seed;
manitou 0:7343f324d853 278
manitou 0:7343f324d853 279 while (((uintptr_t)data & 3) && len) {
manitou 0:7343f324d853 280 crc = (crc >> 8) ^ crc_table_xmodem[(crc & 0xff) ^ *data++];
manitou 0:7343f324d853 281 len--;
manitou 0:7343f324d853 282 }
manitou 0:7343f324d853 283
manitou 0:7343f324d853 284 while (len >= 16) {
manitou 0:7343f324d853 285 len -= 16;
manitou 0:7343f324d853 286 crc_n4(crc, ((uint32_t *)data)[0], crc_table_xmodem);
manitou 0:7343f324d853 287 crc_n4(crc, ((uint32_t *)data)[1], crc_table_xmodem);
manitou 0:7343f324d853 288 crc_n4(crc, ((uint32_t *)data)[2], crc_table_xmodem);
manitou 0:7343f324d853 289 crc_n4(crc, ((uint32_t *)data)[3], crc_table_xmodem);
manitou 0:7343f324d853 290 data += 16;
manitou 0:7343f324d853 291 }
manitou 0:7343f324d853 292
manitou 0:7343f324d853 293 while (len--) {
manitou 0:7343f324d853 294 crc = (crc >> 8) ^ crc_table_xmodem[(crc & 0xff) ^ *data++];
manitou 0:7343f324d853 295 }
manitou 0:7343f324d853 296
manitou 0:7343f324d853 297 crc = REV16(crc);
manitou 0:7343f324d853 298
manitou 0:7343f324d853 299 seed = crc;
manitou 0:7343f324d853 300 return crc;
manitou 0:7343f324d853 301 }
manitou 0:7343f324d853 302
manitou 0:7343f324d853 303 uint16_t FastCRC16::xmodem(const uint8_t *data, const uint16_t datalen)
manitou 0:7343f324d853 304 {
manitou 0:7343f324d853 305 //width=16 poly=0x1021 init=0x0000 refin=false refout=false xorout=0x0000 check=0x31c3
manitou 0:7343f324d853 306 seed = 0x0000;
manitou 0:7343f324d853 307 return xmodem_upd(data, datalen);
manitou 0:7343f324d853 308 }
manitou 0:7343f324d853 309
manitou 0:7343f324d853 310 /** X25
manitou 0:7343f324d853 311 * Alias CRC-16/IBM-SDLC, CRC-16/ISO-HDLC, CRC-B
manitou 0:7343f324d853 312 * @param data Pointer to Data
manitou 0:7343f324d853 313 * @param datalen Length of Data
manitou 0:7343f324d853 314 * @return CRC value
manitou 0:7343f324d853 315 */
manitou 0:7343f324d853 316 uint16_t FastCRC16::x25_upd(const uint8_t *data, uint16_t len)
manitou 0:7343f324d853 317 {
manitou 0:7343f324d853 318
manitou 0:7343f324d853 319 uint16_t crc = seed;
manitou 0:7343f324d853 320
manitou 0:7343f324d853 321 while (((uintptr_t)data & 3) && len) {
manitou 0:7343f324d853 322 crc = (crc >> 8) ^ crc_table_x25[(crc & 0xff) ^ *data++];
manitou 0:7343f324d853 323 len--;
manitou 0:7343f324d853 324 }
manitou 0:7343f324d853 325
manitou 0:7343f324d853 326 while (len >= 16) {
manitou 0:7343f324d853 327 len -= 16;
manitou 0:7343f324d853 328 crc_n4(crc, ((uint32_t *)data)[0], crc_table_x25);
manitou 0:7343f324d853 329 crc_n4(crc, ((uint32_t *)data)[1], crc_table_x25);
manitou 0:7343f324d853 330 crc_n4(crc, ((uint32_t *)data)[2], crc_table_x25);
manitou 0:7343f324d853 331 crc_n4(crc, ((uint32_t *)data)[3], crc_table_x25);
manitou 0:7343f324d853 332 data += 16;
manitou 0:7343f324d853 333 }
manitou 0:7343f324d853 334
manitou 0:7343f324d853 335 while (len--) {
manitou 0:7343f324d853 336 crc = (crc >> 8) ^ crc_table_x25[(crc & 0xff) ^ *data++];
manitou 0:7343f324d853 337 }
manitou 0:7343f324d853 338
manitou 0:7343f324d853 339 crc = ~crc;
manitou 0:7343f324d853 340
manitou 0:7343f324d853 341 seed = crc;
manitou 0:7343f324d853 342 return crc;
manitou 0:7343f324d853 343 }
manitou 0:7343f324d853 344
manitou 0:7343f324d853 345 uint16_t FastCRC16::x25(const uint8_t *data, const uint16_t datalen)
manitou 0:7343f324d853 346 {
manitou 0:7343f324d853 347 // poly=0x1021 init=0xffff refin=true refout=true xorout=0xffff check=0x906e
manitou 0:7343f324d853 348 seed = 0xffff;
manitou 0:7343f324d853 349 return x25_upd(data, datalen);
manitou 0:7343f324d853 350 }
manitou 0:7343f324d853 351
manitou 0:7343f324d853 352
manitou 0:7343f324d853 353
manitou 0:7343f324d853 354
manitou 0:7343f324d853 355
manitou 0:7343f324d853 356 // ================= 32-BIT CRC ===================
manitou 0:7343f324d853 357 /** Constructor
manitou 0:7343f324d853 358 */
manitou 0:7343f324d853 359 FastCRC32::FastCRC32(){}
manitou 0:7343f324d853 360
manitou 0:7343f324d853 361 #define crc_n4d(crc, data, table) crc ^= data; \
manitou 0:7343f324d853 362 crc = table[(crc & 0xff) + 0x300] ^ \
manitou 0:7343f324d853 363 table[((crc >> 8) & 0xff) + 0x200] ^ \
manitou 1:1ce0f4ee7357 364 table[((crc >> 16) & 0xff) + 0x100] ^ \
manitou 1:1ce0f4ee7357 365 table[(crc >> 24) & 0xff];
manitou 0:7343f324d853 366
manitou 0:7343f324d853 367 #define crcsm_n4d(crc, data, table) crc ^= data; \
manitou 0:7343f324d853 368 crc = (crc >> 8) ^ table[crc & 0xff]; \
manitou 0:7343f324d853 369 crc = (crc >> 8) ^ table[crc & 0xff]; \
manitou 0:7343f324d853 370 crc = (crc >> 8) ^ table[crc & 0xff]; \
manitou 0:7343f324d853 371 crc = (crc >> 8) ^ table[crc & 0xff];
manitou 0:7343f324d853 372
manitou 0:7343f324d853 373 /** CRC32
manitou 0:7343f324d853 374 * Alias CRC-32/ADCCP, PKZIP, Ethernet, 802.3
manitou 0:7343f324d853 375 * @param data Pointer to Data
manitou 0:7343f324d853 376 * @param datalen Length of Data
manitou 0:7343f324d853 377 * @return CRC value
manitou 0:7343f324d853 378 */
manitou 0:7343f324d853 379
manitou 1:1ce0f4ee7357 380 #if CRC_BIGTABLES
manitou 1:1ce0f4ee7357 381 #define CRC_TABLE_CRC32 crc_table_crc32_big
manitou 1:1ce0f4ee7357 382 #else
manitou 0:7343f324d853 383 #define CRC_TABLE_CRC32 crc_table_crc32
manitou 1:1ce0f4ee7357 384 #endif
manitou 0:7343f324d853 385
manitou 0:7343f324d853 386 uint32_t FastCRC32::crc32_upd(const uint8_t *data, uint16_t len)
manitou 0:7343f324d853 387 {
manitou 0:7343f324d853 388
manitou 0:7343f324d853 389 uint32_t crc = seed;
manitou 0:7343f324d853 390
manitou 0:7343f324d853 391 while (((uintptr_t)data & 3) && len) {
manitou 1:1ce0f4ee7357 392 crc = (crc >> 8) ^ CRC_TABLE_CRC32[(crc & 0xff) ^ *data++];
manitou 0:7343f324d853 393 len--;
manitou 0:7343f324d853 394 }
manitou 0:7343f324d853 395
manitou 0:7343f324d853 396 while (len >= 16) {
manitou 0:7343f324d853 397 len -= 16;
manitou 0:7343f324d853 398 #if CRC_BIGTABLES
manitou 1:1ce0f4ee7357 399 crc_n4d(crc, ((uint32_t *)data)[0], CRC_TABLE_CRC32);
manitou 1:1ce0f4ee7357 400 crc_n4d(crc, ((uint32_t *)data)[1], CRC_TABLE_CRC32);
manitou 1:1ce0f4ee7357 401 crc_n4d(crc, ((uint32_t *)data)[2], CRC_TABLE_CRC32);
manitou 1:1ce0f4ee7357 402 crc_n4d(crc, ((uint32_t *)data)[3], CRC_TABLE_CRC32);
manitou 0:7343f324d853 403 #else
manitou 1:1ce0f4ee7357 404 crcsm_n4d(crc, ((uint32_t *)data)[0], CRC_TABLE_CRC32);
manitou 1:1ce0f4ee7357 405 crcsm_n4d(crc, ((uint32_t *)data)[1], CRC_TABLE_CRC32);
manitou 1:1ce0f4ee7357 406 crcsm_n4d(crc, ((uint32_t *)data)[2], CRC_TABLE_CRC32);
manitou 1:1ce0f4ee7357 407 crcsm_n4d(crc, ((uint32_t *)data)[3], CRC_TABLE_CRC32);
manitou 0:7343f324d853 408 #endif
manitou 0:7343f324d853 409 data += 16;
manitou 0:7343f324d853 410 }
manitou 0:7343f324d853 411
manitou 0:7343f324d853 412 while (len--) {
manitou 1:1ce0f4ee7357 413 crc = (crc >> 8) ^ CRC_TABLE_CRC32[(crc & 0xff) ^ *data++];
manitou 0:7343f324d853 414 }
manitou 0:7343f324d853 415
manitou 0:7343f324d853 416 crc = ~crc;
manitou 0:7343f324d853 417
manitou 0:7343f324d853 418 seed = crc;
manitou 0:7343f324d853 419 return crc;
manitou 0:7343f324d853 420 }
manitou 0:7343f324d853 421
manitou 0:7343f324d853 422 uint32_t FastCRC32::crc32(const uint8_t *data, const uint16_t datalen)
manitou 0:7343f324d853 423 {
manitou 0:7343f324d853 424 // poly=0x04c11db7 init=0xffffffff refin=true refout=true xorout=0xffffffff check=0xcbf43926
manitou 0:7343f324d853 425 seed = 0xffffffff;
manitou 0:7343f324d853 426 return crc32_upd(data, datalen);
manitou 0:7343f324d853 427 }
manitou 0:7343f324d853 428
manitou 0:7343f324d853 429 /** CKSUM
manitou 0:7343f324d853 430 * Alias CRC-32/POSIX
manitou 0:7343f324d853 431 * @param data Pointer to Data
manitou 0:7343f324d853 432 * @param datalen Length of Data
manitou 0:7343f324d853 433 * @return CRC value
manitou 0:7343f324d853 434 */
manitou 1:1ce0f4ee7357 435 #if CRC_BIGTABLES
manitou 1:1ce0f4ee7357 436 #define CRC_TABLE_CKSUM crc_table_cksum_big
manitou 1:1ce0f4ee7357 437 #else
manitou 1:1ce0f4ee7357 438 #define CRC_TABLE_CKSUM crc_table_cksum
manitou 1:1ce0f4ee7357 439 #endif
manitou 0:7343f324d853 440 uint32_t FastCRC32::cksum_upd(const uint8_t *data, uint16_t len)
manitou 0:7343f324d853 441 {
manitou 0:7343f324d853 442
manitou 0:7343f324d853 443 uint32_t crc = seed;
manitou 0:7343f324d853 444
manitou 0:7343f324d853 445 while (((uintptr_t)data & 3) && len) {
manitou 1:1ce0f4ee7357 446 crc = (crc >> 8) ^ CRC_TABLE_CKSUM[(crc & 0xff) ^ *data++];
manitou 0:7343f324d853 447 len--;
manitou 0:7343f324d853 448 }
manitou 0:7343f324d853 449
manitou 0:7343f324d853 450 while (len >= 16) {
manitou 0:7343f324d853 451 len -= 16;
manitou 0:7343f324d853 452 #if CRC_BIGTABLES
manitou 1:1ce0f4ee7357 453 crc_n4d(crc, ((uint32_t *)data)[0], CRC_TABLE_CKSUM);
manitou 1:1ce0f4ee7357 454 crc_n4d(crc, ((uint32_t *)data)[1], CRC_TABLE_CKSUM);
manitou 1:1ce0f4ee7357 455 crc_n4d(crc, ((uint32_t *)data)[2], CRC_TABLE_CKSUM);
manitou 1:1ce0f4ee7357 456 crc_n4d(crc, ((uint32_t *)data)[3], CRC_TABLE_CKSUM);
manitou 0:7343f324d853 457 #else
manitou 1:1ce0f4ee7357 458 crcsm_n4d(crc, ((uint32_t *)data)[0], CRC_TABLE_CKSUM);
manitou 1:1ce0f4ee7357 459 crcsm_n4d(crc, ((uint32_t *)data)[1], CRC_TABLE_CKSUM);
manitou 1:1ce0f4ee7357 460 crcsm_n4d(crc, ((uint32_t *)data)[2], CRC_TABLE_CKSUM);
manitou 1:1ce0f4ee7357 461 crcsm_n4d(crc, ((uint32_t *)data)[3], CRC_TABLE_CKSUM);
manitou 0:7343f324d853 462 #endif
manitou 0:7343f324d853 463 data += 16;
manitou 0:7343f324d853 464 }
manitou 0:7343f324d853 465
manitou 0:7343f324d853 466 while (len--) {
manitou 1:1ce0f4ee7357 467 crc = (crc >> 8) ^ CRC_TABLE_CKSUM[(crc & 0xff) ^ *data++];
manitou 0:7343f324d853 468 }
manitou 0:7343f324d853 469
manitou 0:7343f324d853 470 crc = ~REV32(crc);
manitou 0:7343f324d853 471
manitou 0:7343f324d853 472 seed = crc;
manitou 0:7343f324d853 473 return crc;
manitou 0:7343f324d853 474 }
manitou 0:7343f324d853 475
manitou 0:7343f324d853 476 uint32_t FastCRC32::cksum(const uint8_t *data, const uint16_t datalen)
manitou 0:7343f324d853 477 {
manitou 0:7343f324d853 478 // width=32 poly=0x04c11db7 init=0x00000000 refin=false refout=false xorout=0xffffffff check=0x765e7680
manitou 0:7343f324d853 479 seed = 0x00;
manitou 0:7343f324d853 480 return cksum_upd(data, datalen);
manitou 0:7343f324d853 481 }
manitou 0:7343f324d853 482
manitou 0:7343f324d853 483 #endif // __MK20DX128__ || __MK20DX256__