Port of teensy 3 FastCRC library, uses hardware CRC
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)
FastCRCsw.cpp@1:1ce0f4ee7357, 2016-04-22 (annotated)
- 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?
User | Revision | Line number | New 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__ |