Add CRC stack for testing (Currently unused)
This commit is contained in:
parent
bae708a4d6
commit
2004034674
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,155 @@
|
||||||
|
/* FastCRC library code is placed under the MIT license
|
||||||
|
* Copyright (c) 2014,2015 Frank Bösing
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining
|
||||||
|
* a copy of this software and associated documentation files (the
|
||||||
|
* "Software"), to deal in the Software without restriction, including
|
||||||
|
* without limitation the rights to use, copy, modify, merge, publish,
|
||||||
|
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||||
|
* permit persons to whom the Software is furnished to do so, subject to
|
||||||
|
* the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be
|
||||||
|
* included in all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||||
|
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||||
|
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
|
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
// Teensy 3.0, Teensy 3.1:
|
||||||
|
// See K20P64M72SF1RM.pdf (Kinetis), Pages 638 - 641 for documentation of CRC Device
|
||||||
|
// See KINETIS_4N30D.pdf for Errata (Errata ID 2776)
|
||||||
|
//
|
||||||
|
// So, ALL HW-calculations are done as 32 bit.
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Thanks to:
|
||||||
|
// - Catalogue of parametrised CRC algorithms, CRC RevEng
|
||||||
|
// http://reveng.sourceforge.net/crc-catalogue/
|
||||||
|
//
|
||||||
|
// - Danjel McGougan (CRC-Table-Generator)
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
|
// Set this to 0 for smaller 32BIT-CRC-Tables:
|
||||||
|
#define CRC_BIGTABLES 1
|
||||||
|
|
||||||
|
|
||||||
|
#if !defined(FastCRC_h)
|
||||||
|
#define FastCRC_h
|
||||||
|
#include "inttypes.h"
|
||||||
|
|
||||||
|
|
||||||
|
// ================= DEFINES ===================
|
||||||
|
#if defined(KINETISK)
|
||||||
|
#define CRC_SW 0
|
||||||
|
#define CRC_FLAG_NOREFLECT (((1<<31) | (1<<30)) | ((0<<29) | (0<<28))) //refin=false refout=false
|
||||||
|
#define CRC_FLAG_REFLECT (((1<<31) | (0<<30)) | ((1<<29) | (0<<28))) //Reflect in- and outgoing bytes (refin=true refout=true)
|
||||||
|
#define CRC_FLAG_XOR (1<<26) //Perform XOR on result
|
||||||
|
#define CRC_FLAG_NOREFLECT_8 (0) //For 8-Bit CRC
|
||||||
|
#define CRC_FLAG_REFLECT_SWAP (((1<<31) | (0<<30)) | ((0<<29) | (1<<28))) //For 16-Bit CRC (byteswap)
|
||||||
|
#else
|
||||||
|
#define CRC_SW 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// ================= 7-BIT CRC ===================
|
||||||
|
class FastCRC7
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
FastCRC7();
|
||||||
|
uint8_t crc7(const uint8_t *data, const uint16_t datalen); // (MultiMediaCard interface)
|
||||||
|
uint8_t crc7_upd(const uint8_t *data, const uint16_t datalen); // Call for subsequent calculations with previous seed.
|
||||||
|
#if !CRC_SW
|
||||||
|
uint8_t generic(const uint8_t polyom, const uint8_t seed, const uint32_t flags, const uint8_t *data, const uint16_t datalen); //Not available in non-hw-variant (not T3.x)
|
||||||
|
#endif
|
||||||
|
private:
|
||||||
|
#if CRC_SW
|
||||||
|
uint8_t seed;
|
||||||
|
#else
|
||||||
|
uint8_t update(const uint8_t *data, const uint16_t datalen);
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
// ================= 8-BIT CRC ===================
|
||||||
|
|
||||||
|
class FastCRC8
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
FastCRC8();
|
||||||
|
uint8_t smbus(const uint8_t *data, const uint16_t datalen); // Alias CRC-8
|
||||||
|
uint8_t maxim(const uint8_t *data, const uint16_t datalen); // Equivalent to _crc_ibutton_update() in crc16.h from avr_libc
|
||||||
|
|
||||||
|
uint8_t smbus_upd(const uint8_t *data, uint16_t datalen); // Call for subsequent calculations with previous seed.
|
||||||
|
uint8_t maxim_upd(const uint8_t *data, uint16_t datalen); // Call for subsequent calculations with previous seed.
|
||||||
|
#if !CRC_SW
|
||||||
|
uint8_t generic(const uint8_t polyom, const uint8_t seed, const uint32_t flags, const uint8_t *data, const uint16_t datalen); //Not available in non-hw-variant (not T3.x)
|
||||||
|
#endif
|
||||||
|
private:
|
||||||
|
#if CRC_SW
|
||||||
|
uint8_t seed;
|
||||||
|
#else
|
||||||
|
uint8_t update(const uint8_t *data, const uint16_t datalen);
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
// ================= 16-BIT CRC ===================
|
||||||
|
|
||||||
|
class FastCRC16
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
FastCRC16();
|
||||||
|
uint16_t ccitt(const uint8_t *data, const uint16_t datalen); // Alias "false CCITT"
|
||||||
|
uint16_t mcrf4xx(const uint8_t *data,const uint16_t datalen); // Equivalent to _crc_ccitt_update() in crc16.h from avr_libc
|
||||||
|
uint16_t kermit(const uint8_t *data, const uint16_t datalen); // Alias CRC-16/CCITT, CRC-16/CCITT-TRUE, CRC-CCITT
|
||||||
|
uint16_t modbus(const uint8_t *data, const uint16_t datalen); // Equivalent to _crc_16_update() in crc16.h from avr_libc
|
||||||
|
uint16_t xmodem(const uint8_t *data, const uint16_t datalen); // Alias ZMODEM, CRC-16/ACORN
|
||||||
|
uint16_t x25(const uint8_t *data, const uint16_t datalen); // Alias CRC-16/IBM-SDLC, CRC-16/ISO-HDLC, CRC-B
|
||||||
|
|
||||||
|
uint16_t ccitt_upd(const uint8_t *data, uint16_t len); // Call for subsequent calculations with previous seed
|
||||||
|
uint16_t mcrf4xx_upd(const uint8_t *data, uint16_t len); // Call for subsequent calculations with previous seed
|
||||||
|
uint16_t kermit_upd(const uint8_t *data, uint16_t len); // Call for subsequent calculations with previous seed
|
||||||
|
uint16_t modbus_upd(const uint8_t *data, uint16_t len); // Call for subsequent calculations with previous seed
|
||||||
|
uint16_t xmodem_upd(const uint8_t *data, uint16_t len); // Call for subsequent calculations with previous seed
|
||||||
|
uint16_t x25_upd(const uint8_t *data, uint16_t len); // Call for subsequent calculations with previous seed
|
||||||
|
#if !CRC_SW
|
||||||
|
uint16_t generic(const uint16_t polyom, const uint16_t seed, const uint32_t flags, const uint8_t *data, const uint16_t datalen); //Not available in non-hw-variant (not T3.x)
|
||||||
|
#endif
|
||||||
|
private:
|
||||||
|
#if CRC_SW
|
||||||
|
uint16_t seed;
|
||||||
|
#else
|
||||||
|
uint16_t update(const uint8_t *data, const uint16_t datalen);
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
// ================= 32-BIT CRC ===================
|
||||||
|
|
||||||
|
class FastCRC32
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
FastCRC32();
|
||||||
|
uint32_t crc32(const uint8_t *data, const uint16_t datalen); // Alias CRC-32/ADCCP, PKZIP, Ethernet, 802.3
|
||||||
|
uint32_t cksum(const uint8_t *data, const uint16_t datalen); // Alias CRC-32/POSIX
|
||||||
|
|
||||||
|
uint32_t crc32_upd(const uint8_t *data, uint16_t len); // Call for subsequent calculations with previous seed
|
||||||
|
uint32_t cksum_upd(const uint8_t *data, uint16_t len); // Call for subsequent calculations with previous seed
|
||||||
|
#if !CRC_SW
|
||||||
|
uint32_t generic(const uint32_t polyom, const uint32_t seed, const uint32_t flags, const uint8_t *data, const uint16_t datalen); //Not available in non-hw-variant (not T3.x)
|
||||||
|
#endif
|
||||||
|
private:
|
||||||
|
#if CRC_SW
|
||||||
|
uint32_t seed;
|
||||||
|
#else
|
||||||
|
uint32_t update(const uint8_t *data, const uint16_t datalen);
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,71 @@
|
||||||
|
/* FastCRC library code is placed under the MIT license
|
||||||
|
* Copyright (c) 2014,2015,2016 Frank Bösing
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining
|
||||||
|
* a copy of this software and associated documentation files (the
|
||||||
|
* "Software"), to deal in the Software without restriction, including
|
||||||
|
* without limitation the rights to use, copy, modify, merge, publish,
|
||||||
|
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||||
|
* permit persons to whom the Software is furnished to do so, subject to
|
||||||
|
* the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be
|
||||||
|
* included in all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||||
|
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||||
|
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
|
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
// CPU-specific implementations of helper functions
|
||||||
|
|
||||||
|
#if !defined(KINETISK)
|
||||||
|
#if !defined(FastCRC_cpu)
|
||||||
|
#define FastCRC_cpu
|
||||||
|
|
||||||
|
//Reverse byte order (16 bit)
|
||||||
|
#if defined(__thumb__)
|
||||||
|
static inline __attribute__((always_inline))
|
||||||
|
uint32_t REV16( uint32_t value) //ARM-THUMB
|
||||||
|
{
|
||||||
|
asm ("rev16 %0, %1" : "=r" (value) : "r" (value) );
|
||||||
|
return(value);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
static inline __attribute__((always_inline))
|
||||||
|
uint32_t REV16( uint32_t value) //generic
|
||||||
|
{
|
||||||
|
return (value >> 8) | ((value & 0xff) << 8);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//Reverse byte order (32 bit)
|
||||||
|
#if defined(__thumb__)
|
||||||
|
static inline __attribute__((always_inline))
|
||||||
|
uint32_t REV32( uint32_t value) //ARM-THUMB
|
||||||
|
{
|
||||||
|
asm ("rev %0, %1" : "=r" (value) : "r" (value) );
|
||||||
|
return(value);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
static inline __attribute__((always_inline))
|
||||||
|
uint32_t REV32( uint32_t value) //generic
|
||||||
|
{
|
||||||
|
value = (value >> 16) | ((value & 0xffff) << 16);
|
||||||
|
return ((value >> 8) & 0xff00ff) | ((value & 0xff00ff) << 8);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
|
#endif
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,453 @@
|
||||||
|
/* FastCRC library code is placed under the MIT license
|
||||||
|
* Copyright (c) 2014,2015 Frank Bösing
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining
|
||||||
|
* a copy of this software and associated documentation files (the
|
||||||
|
* "Software"), to deal in the Software without restriction, including
|
||||||
|
* without limitation the rights to use, copy, modify, merge, publish,
|
||||||
|
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||||
|
* permit persons to whom the Software is furnished to do so, subject to
|
||||||
|
* the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be
|
||||||
|
* included in all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||||
|
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||||
|
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
|
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
//
|
||||||
|
// HW-calculations are 32BIT
|
||||||
|
//
|
||||||
|
// Thanks to:
|
||||||
|
// - Catalogue of parametrised CRC algorithms, CRC RevEng
|
||||||
|
// http://reveng.sourceforge.net/crc-catalogue/
|
||||||
|
//
|
||||||
|
// - Danjel McGougan (CRC-Table-Generator)
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "Arduino.h"
|
||||||
|
#if defined(KINETISK)
|
||||||
|
|
||||||
|
#include "mk20dx128.h"
|
||||||
|
#include "FastCRC.h"
|
||||||
|
|
||||||
|
// ===============================================
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
union {
|
||||||
|
uint32_t CRC; //CRC Data register
|
||||||
|
struct {
|
||||||
|
uint16_t CRC16;
|
||||||
|
uint16_t CRC16_1;
|
||||||
|
};
|
||||||
|
struct {
|
||||||
|
uint8_t CRC8;
|
||||||
|
uint8_t CRC8_1;
|
||||||
|
uint8_t CRC8_2;
|
||||||
|
uint8_t CRC8_3;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
uint32_t GPOLY; //CRC Polynomial register
|
||||||
|
uint32_t CTRL; //CRC Control register
|
||||||
|
} CRC_T;
|
||||||
|
|
||||||
|
static volatile CRC_T * const rCRC = (CRC_T *)0x40032000;
|
||||||
|
|
||||||
|
#define CRC_CTRL_WAS 25 // Write CRC Data Register As Seed(1) / Data(0)
|
||||||
|
#define CRC_CTRL_TCRC 24 // Width of CRC protocol (0=16 BIT, 1=32 BIT)
|
||||||
|
#define CRC_CTRL_TOTR1 29 // TOTR[1]
|
||||||
|
|
||||||
|
// ================= 7-BIT CRC ===================
|
||||||
|
/** Constructor
|
||||||
|
* Enables CRC-clock
|
||||||
|
*/
|
||||||
|
FastCRC7::FastCRC7(){
|
||||||
|
SIM_SCGC6 |= SIM_SCGC6_CRC;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** CRC 7
|
||||||
|
* MultiMediaCard interface
|
||||||
|
* @param data Pointer to Data
|
||||||
|
* @param datalen Length of Data
|
||||||
|
* @return CRC value
|
||||||
|
*/
|
||||||
|
uint8_t FastCRC7::crc7(const uint8_t *data, const uint16_t datalen)
|
||||||
|
{
|
||||||
|
// poly=0x09 init=0x00 refin=false refout=false xorout=0x00 check=0x75
|
||||||
|
return (generic(0x09, 0, CRC_FLAG_NOREFLECT, data, datalen));
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Update
|
||||||
|
* Call for subsequent calculations with previous seed
|
||||||
|
* @param data Pointer to Data
|
||||||
|
* @param datalen Length of Data
|
||||||
|
* @return CRC value
|
||||||
|
*/
|
||||||
|
uint8_t FastCRC7::update(const uint8_t *data, const uint16_t datalen)
|
||||||
|
{
|
||||||
|
|
||||||
|
const uint8_t *src = data;
|
||||||
|
const uint8_t *target = src + datalen;
|
||||||
|
|
||||||
|
while (((uintptr_t)src & 0x03) != 0 && (src < target)) {
|
||||||
|
rCRC->CRC8_3 = *src++; //Write 8 BIT
|
||||||
|
}
|
||||||
|
|
||||||
|
while (src <= target-4) {
|
||||||
|
rCRC->CRC = *( uint32_t *)src; //Write 32 BIT
|
||||||
|
src += 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (src < target) {
|
||||||
|
rCRC->CRC8_3 = *src++; //Write 8 Bit
|
||||||
|
}
|
||||||
|
|
||||||
|
//TODO: Check handling of CRC_CTRL_TOTR1 for other CRC7s
|
||||||
|
/*
|
||||||
|
if (rCRC->CTRL & (1<<CRC_CTRL_TOTR1))
|
||||||
|
return rCRC->CRC8 >> 1;
|
||||||
|
else
|
||||||
|
*/
|
||||||
|
return rCRC->CRC8_3 >> 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** generic function for all 7-Bit CRCs
|
||||||
|
* @param polynom Polynom
|
||||||
|
* @param seed Seed
|
||||||
|
* @param flags Flags
|
||||||
|
* @param data Pointer to Data
|
||||||
|
* @param datalen Length of Data
|
||||||
|
* @return CRC value
|
||||||
|
*/
|
||||||
|
uint8_t FastCRC7::generic(const uint8_t polynom, const uint8_t seed, const uint32_t flags, const uint8_t *data,const uint16_t datalen)
|
||||||
|
{
|
||||||
|
|
||||||
|
rCRC->CTRL = flags | (1<<CRC_CTRL_TCRC) | (1<<CRC_CTRL_WAS); // 32Bit Mode, Prepare to write seed(25)
|
||||||
|
rCRC->GPOLY = ((uint32_t)polynom)<<(24 + 1); // Set polynom
|
||||||
|
rCRC->CRC = ((uint32_t)seed<<(24 + 1)); // Write seed
|
||||||
|
rCRC->CTRL = flags | (1<<CRC_CTRL_TCRC); // Clear WAS Bit - prepare to write data
|
||||||
|
|
||||||
|
return update(data, datalen);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t FastCRC7::crc7_upd(const uint8_t *data, uint16_t datalen){return update(data, datalen);}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// ================= 8-BIT CRC ===================
|
||||||
|
|
||||||
|
/** Constructor
|
||||||
|
* Enables CRC-clock
|
||||||
|
*/
|
||||||
|
FastCRC8::FastCRC8(){
|
||||||
|
SIM_SCGC6 |= SIM_SCGC6_CRC;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** SMBUS CRC
|
||||||
|
* aka CRC-8
|
||||||
|
* @param data Pointer to Data
|
||||||
|
* @param datalen Length of Data
|
||||||
|
* @return CRC value
|
||||||
|
*/
|
||||||
|
uint8_t FastCRC8::smbus(const uint8_t *data, const uint16_t datalen)
|
||||||
|
{
|
||||||
|
// poly=0x07 init=0x00 refin=false refout=false xorout=0x00 check=0xf4
|
||||||
|
return generic(0x07, 0, CRC_FLAG_NOREFLECT, data, datalen);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** MAXIM 8-Bit CRC
|
||||||
|
* equivalent to _crc_ibutton_update() in crc16.h from avr_libc
|
||||||
|
* @param data Pointer to Data
|
||||||
|
* @param datalen Length of Data
|
||||||
|
* @return CRC value
|
||||||
|
*/
|
||||||
|
uint8_t FastCRC8::maxim(const uint8_t *data, const uint16_t datalen)
|
||||||
|
{
|
||||||
|
// poly=0x31 init=0x00 refin=true refout=true xorout=0x00 check=0xa1
|
||||||
|
return generic(0x31, 0, CRC_FLAG_REFLECT, data, datalen);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Update
|
||||||
|
* Call for subsequent calculations with previous seed
|
||||||
|
* @param data Pointer to Data
|
||||||
|
* @param datalen Length of Data
|
||||||
|
* @return CRC value
|
||||||
|
*/
|
||||||
|
uint8_t FastCRC8::update(const uint8_t *data, const uint16_t datalen)
|
||||||
|
{
|
||||||
|
|
||||||
|
const uint8_t *src = data;
|
||||||
|
const uint8_t *target = src + datalen;
|
||||||
|
|
||||||
|
while (((uintptr_t)src & 0x03) != 0 && (src < target)) {
|
||||||
|
rCRC->CRC8_3 = *src++; //Write 8 BIT
|
||||||
|
}
|
||||||
|
|
||||||
|
while (src <= target-4) {
|
||||||
|
rCRC->CRC = *( uint32_t *)src; //Write 32 BIT
|
||||||
|
src += 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (src < target) {
|
||||||
|
rCRC->CRC8_3 = *src++; //Write 8 Bit
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rCRC->CTRL & (1<<CRC_CTRL_TOTR1))
|
||||||
|
return rCRC->CRC8;
|
||||||
|
else
|
||||||
|
return rCRC->CRC8_3;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** generic function for all 8-Bit CRCs
|
||||||
|
* @param polynom Polynom
|
||||||
|
* @param seed Seed
|
||||||
|
* @param flags Flags
|
||||||
|
* @param data Pointer to Data
|
||||||
|
* @param datalen Length of Data
|
||||||
|
* @return CRC value
|
||||||
|
*/
|
||||||
|
uint8_t FastCRC8::generic(const uint8_t polynom, const uint8_t seed, const uint32_t flags, const uint8_t *data,const uint16_t datalen)
|
||||||
|
{
|
||||||
|
|
||||||
|
rCRC->CTRL = flags | (1<<CRC_CTRL_TCRC) | (1<<CRC_CTRL_WAS); // 32Bit Mode, Prepare to write seed(25)
|
||||||
|
rCRC->GPOLY = ((uint32_t)polynom)<<24; // Set polynom
|
||||||
|
rCRC->CRC = ((uint32_t)seed<<24); // Write seed
|
||||||
|
rCRC->CTRL = flags | (1<<CRC_CTRL_TCRC); // Clear WAS Bit - prepare to write data
|
||||||
|
|
||||||
|
return update(data, datalen);
|
||||||
|
}
|
||||||
|
uint8_t FastCRC8::smbus_upd(const uint8_t *data, uint16_t datalen){return update(data, datalen);}
|
||||||
|
uint8_t FastCRC8::maxim_upd(const uint8_t *data, uint16_t datalen){return update(data, datalen);}
|
||||||
|
|
||||||
|
// ================= 16-BIT CRC ===================
|
||||||
|
|
||||||
|
/** Constructor
|
||||||
|
* Enables CRC-clock
|
||||||
|
*/
|
||||||
|
FastCRC16::FastCRC16(){
|
||||||
|
SIM_SCGC6 |= SIM_SCGC6_CRC;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** CCITT
|
||||||
|
* Alias "false CCITT"
|
||||||
|
* @param data Pointer to Data
|
||||||
|
* @param datalen Length of Data
|
||||||
|
* @return CRC value
|
||||||
|
*/
|
||||||
|
uint16_t FastCRC16::ccitt(const uint8_t *data,const uint16_t datalen)
|
||||||
|
{
|
||||||
|
// poly=0x1021 init=0xffff refin=false refout=false xorout=0x0000 check=0x29b1
|
||||||
|
return generic(0x1021, 0XFFFF, CRC_FLAG_NOREFLECT, data, datalen);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** MCRF4XX
|
||||||
|
* equivalent to _crc_ccitt_update() in crc16.h from avr_libc
|
||||||
|
* @param data Pointer to Data
|
||||||
|
* @param datalen Length of Data
|
||||||
|
* @return CRC value
|
||||||
|
*/
|
||||||
|
uint16_t FastCRC16::mcrf4xx(const uint8_t *data,const uint16_t datalen)
|
||||||
|
{
|
||||||
|
// poly=0x1021 init=0xffff refin=true refout=true xorout=0x0000 check=0x6f91
|
||||||
|
return generic(0x1021, 0XFFFF, CRC_FLAG_REFLECT, data, datalen);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** MODBUS
|
||||||
|
* equivalent to _crc_16_update() in crc16.h from avr_libc
|
||||||
|
* @param data Pointer to Data
|
||||||
|
* @param datalen Length of Data
|
||||||
|
* @return CRC value
|
||||||
|
*/
|
||||||
|
uint16_t FastCRC16::modbus(const uint8_t *data, const uint16_t datalen)
|
||||||
|
{
|
||||||
|
// poly=0x8005 init=0xffff refin=true refout=true xorout=0x0000 check=0x4b37
|
||||||
|
return generic(0x8005, 0XFFFF, CRC_FLAG_REFLECT, data, datalen);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** KERMIT
|
||||||
|
* Alias CRC-16/CCITT, CRC-16/CCITT-TRUE, CRC-CCITT
|
||||||
|
* @param data Pointer to Data
|
||||||
|
* @param datalen Length of Data
|
||||||
|
* @return CRC value
|
||||||
|
*/
|
||||||
|
uint16_t FastCRC16::kermit(const uint8_t *data, const uint16_t datalen)
|
||||||
|
{
|
||||||
|
// poly=0x1021 init=0x0000 refin=true refout=true xorout=0x0000 check=0x2189
|
||||||
|
// sometimes byteswapped presentation of result
|
||||||
|
return generic(0x1021, 0x00, CRC_FLAG_REFLECT, data, datalen);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** XMODEM
|
||||||
|
* Alias ZMODEM, CRC-16/ACORN
|
||||||
|
* @param data Pointer to Data
|
||||||
|
* @param datalen Length of Data
|
||||||
|
* @return CRC value
|
||||||
|
*/
|
||||||
|
uint16_t FastCRC16::xmodem(const uint8_t *data, const uint16_t datalen)
|
||||||
|
{
|
||||||
|
//width=16 poly=0x1021 init=0x0000 refin=false refout=false xorout=0x0000 check=0x31c3
|
||||||
|
return generic(0x1021, 0, CRC_FLAG_NOREFLECT, data, datalen);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** X25
|
||||||
|
* Alias CRC-16/IBM-SDLC, CRC-16/ISO-HDLC, CRC-B
|
||||||
|
* @param data Pointer to Data
|
||||||
|
* @param datalen Length of Data
|
||||||
|
* @return CRC value
|
||||||
|
*/
|
||||||
|
uint16_t FastCRC16::x25(const uint8_t *data, const uint16_t datalen)
|
||||||
|
{
|
||||||
|
// poly=0x1021 init=0xffff refin=true refout=true xorout=0xffff check=0x906e
|
||||||
|
return generic(0x1021, 0XFFFF, CRC_FLAG_REFLECT | CRC_FLAG_XOR, data, datalen);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Update
|
||||||
|
* Call for subsequent calculations with previous seed
|
||||||
|
* @param data Pointer to Data
|
||||||
|
* @param datalen Length of Data
|
||||||
|
* @return CRC value
|
||||||
|
*/
|
||||||
|
uint16_t FastCRC16::update(const uint8_t *data, const uint16_t datalen)
|
||||||
|
{
|
||||||
|
const uint8_t *src = data;
|
||||||
|
const uint8_t *target = src + datalen;
|
||||||
|
|
||||||
|
while (((uintptr_t)src & 0x03) !=0 && (src < target)) {
|
||||||
|
rCRC->CRC8_3 = *src++; //Write 8 BIT
|
||||||
|
}
|
||||||
|
|
||||||
|
while (src <= target-4) {
|
||||||
|
rCRC->CRC = *( uint32_t *)src; //Write 32 BIT
|
||||||
|
src += 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (src < target) {
|
||||||
|
rCRC->CRC8_3 = *src++; //Write 8 Bit
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rCRC->CTRL & (1<<CRC_CTRL_TOTR1))
|
||||||
|
return rCRC->CRC16;
|
||||||
|
else
|
||||||
|
return rCRC->CRC16_1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** generic function for all 16-Bit CRCs
|
||||||
|
* @param polynom Polynom
|
||||||
|
* @param seed Seed
|
||||||
|
* @param flags Flags
|
||||||
|
* @param data Pointer to Data
|
||||||
|
* @param datalen Length of Data
|
||||||
|
* @return CRC value
|
||||||
|
*/
|
||||||
|
uint16_t FastCRC16::generic(const uint16_t polynom, const uint16_t seed, const uint32_t flags, const uint8_t *data, const uint16_t datalen)
|
||||||
|
{
|
||||||
|
|
||||||
|
rCRC->CTRL = flags | (1<<CRC_CTRL_TCRC) | (1<<CRC_CTRL_WAS);// 32-Bit Mode, prepare to write seed(25)
|
||||||
|
rCRC->GPOLY = ((uint32_t)polynom)<<16; // set polynom
|
||||||
|
rCRC->CRC = ((uint32_t)seed<<16); // this is the seed
|
||||||
|
rCRC->CTRL = flags | (1<<CRC_CTRL_TCRC); // Clear WAS Bit - prepare to write data
|
||||||
|
|
||||||
|
return update(data, datalen);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t FastCRC16::ccitt_upd(const uint8_t *data, uint16_t len) {return update(data, len);}
|
||||||
|
uint16_t FastCRC16::mcrf4xx_upd(const uint8_t *data, uint16_t len){return update(data, len);}
|
||||||
|
uint16_t FastCRC16::kermit_upd(const uint8_t *data, uint16_t len) {return update(data, len);}
|
||||||
|
uint16_t FastCRC16::modbus_upd(const uint8_t *data, uint16_t len) {return update(data, len);}
|
||||||
|
uint16_t FastCRC16::xmodem_upd(const uint8_t *data, uint16_t len) {return update(data, len);}
|
||||||
|
uint16_t FastCRC16::x25_upd(const uint8_t *data, uint16_t len) {return update(data, len);}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// ================= 32-BIT CRC ===================
|
||||||
|
|
||||||
|
/** Constructor
|
||||||
|
* Enables CRC-clock
|
||||||
|
*/
|
||||||
|
FastCRC32::FastCRC32(){
|
||||||
|
SIM_SCGC6 |= SIM_SCGC6_CRC;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** CRC32
|
||||||
|
* Alias CRC-32/ADCCP, PKZIP, Ethernet, 802.3
|
||||||
|
* @param data Pointer to Data
|
||||||
|
* @param datalen Length of Data
|
||||||
|
* @return CRC value
|
||||||
|
*/
|
||||||
|
uint32_t FastCRC32::crc32(const uint8_t *data, const uint16_t datalen)
|
||||||
|
{
|
||||||
|
// poly=0x04c11db7 init=0xffffffff refin=true refout=true xorout=0xffffffff check=0xcbf43926
|
||||||
|
return generic(0x04C11DB7L, 0XFFFFFFFFL, CRC_FLAG_REFLECT | CRC_FLAG_XOR, data, datalen);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** CKSUM
|
||||||
|
* Alias CRC-32/POSIX
|
||||||
|
* @param data Pointer to Data
|
||||||
|
* @param datalen Length of Data
|
||||||
|
* @return CRC value
|
||||||
|
*/
|
||||||
|
uint32_t FastCRC32::cksum(const uint8_t *data, const uint16_t datalen)
|
||||||
|
{
|
||||||
|
// width=32 poly=0x04c11db7 init=0x00000000 refin=false refout=false xorout=0xffffffff check=0x765e7680
|
||||||
|
return generic(0x04C11DB7L, 0, CRC_FLAG_NOREFLECT | CRC_FLAG_XOR, data, datalen);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Update
|
||||||
|
* Call for subsequent calculations with previous seed
|
||||||
|
* @param data Pointer to Data
|
||||||
|
* @param datalen Length of Data
|
||||||
|
* @return CRC value
|
||||||
|
*/
|
||||||
|
//#pragma GCC diagnostic ignored "-Wpointer-arith"
|
||||||
|
uint32_t FastCRC32::update(const uint8_t *data, const uint16_t datalen)
|
||||||
|
{
|
||||||
|
|
||||||
|
const uint8_t *src = data;
|
||||||
|
const uint8_t *target = src + datalen;
|
||||||
|
|
||||||
|
while (((uintptr_t)src & 0x03) != 0 && (src < target)) {
|
||||||
|
rCRC->CRC8_3 = *src++; //Write 8 BIT
|
||||||
|
}
|
||||||
|
|
||||||
|
while (src <= target-4) {
|
||||||
|
rCRC->CRC = *( uint32_t *)src; //Write 32 BIT
|
||||||
|
src += 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (src < target) {
|
||||||
|
rCRC->CRC8_3 = *src++; //Write 8 Bit
|
||||||
|
}
|
||||||
|
|
||||||
|
return rCRC->CRC;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** generic function for all 32-Bit CRCs
|
||||||
|
* @param polynom Polynom
|
||||||
|
* @param seed Seed
|
||||||
|
* @param flags Flags
|
||||||
|
* @param data Pointer to Data
|
||||||
|
* @param datalen Length of Data
|
||||||
|
* @return CRC value
|
||||||
|
*/
|
||||||
|
uint32_t FastCRC32::generic(const uint32_t polynom, const uint32_t seed, const uint32_t flags, const uint8_t *data, const uint16_t datalen)
|
||||||
|
{
|
||||||
|
|
||||||
|
rCRC->CTRL = flags | (1<<CRC_CTRL_TCRC) | (1<<CRC_CTRL_WAS); // 32Bit Mode, prepare to write seed(25)
|
||||||
|
rCRC->GPOLY = polynom; // Set polynom
|
||||||
|
rCRC->CRC = seed; // This is the seed
|
||||||
|
rCRC->CTRL = flags | (1<<CRC_CTRL_TCRC); // Clear WAS Bit - prepare to write data
|
||||||
|
|
||||||
|
return update(data, datalen);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t FastCRC32::crc32_upd(const uint8_t *data, uint16_t len){return update(data, len);}
|
||||||
|
uint32_t FastCRC32::cksum_upd(const uint8_t *data, uint16_t len){return update(data, len);}
|
||||||
|
#endif // #if defined(KINETISK)
|
|
@ -0,0 +1,509 @@
|
||||||
|
/* FastCRC library code is placed under the MIT license
|
||||||
|
* Copyright (c) 2014,2015,2016 Frank Bösing
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining
|
||||||
|
* a copy of this software and associated documentation files (the
|
||||||
|
* "Software"), to deal in the Software without restriction, including
|
||||||
|
* without limitation the rights to use, copy, modify, merge, publish,
|
||||||
|
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||||
|
* permit persons to whom the Software is furnished to do so, subject to
|
||||||
|
* the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be
|
||||||
|
* included in all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||||
|
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||||
|
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
|
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
//
|
||||||
|
// Thanks to:
|
||||||
|
// - Catalogue of parametrised CRC algorithms, CRC RevEng
|
||||||
|
// http://reveng.sourceforge.net/crc-catalogue/
|
||||||
|
//
|
||||||
|
// - Danjel McGougan (CRC-Table-Generator)
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "Arduino.h"
|
||||||
|
#if !defined(KINETISK)
|
||||||
|
|
||||||
|
#include "FastCRC.h"
|
||||||
|
#include "FastCRC_cpu.h"
|
||||||
|
#include "FastCRC_tables.h"
|
||||||
|
|
||||||
|
|
||||||
|
// ================= 7-BIT CRC ===================
|
||||||
|
|
||||||
|
/** Constructor
|
||||||
|
*/
|
||||||
|
FastCRC7::FastCRC7(){}
|
||||||
|
|
||||||
|
/** SMBUS CRC
|
||||||
|
* aka CRC-8
|
||||||
|
* @param data Pointer to Data
|
||||||
|
* @param datalen Length of Data
|
||||||
|
* @return CRC value
|
||||||
|
*/
|
||||||
|
uint8_t FastCRC7::crc7_upd(const uint8_t *data, uint16_t datalen)
|
||||||
|
{
|
||||||
|
uint8_t crc = seed;
|
||||||
|
if (datalen) do {
|
||||||
|
crc = pgm_read_byte(&crc_table_crc7[crc ^ *data]);
|
||||||
|
data++;
|
||||||
|
} while (--datalen);
|
||||||
|
seed = crc;
|
||||||
|
return crc >> 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t FastCRC7::crc7(const uint8_t *data, const uint16_t datalen)
|
||||||
|
{
|
||||||
|
// poly=0x09 init=0x00 refin=false refout=false xorout=0x00 check=0x75
|
||||||
|
seed = 0x00;
|
||||||
|
return crc7_upd(data, datalen);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ================= 8-BIT CRC ===================
|
||||||
|
|
||||||
|
/** Constructor
|
||||||
|
*/
|
||||||
|
FastCRC8::FastCRC8(){}
|
||||||
|
|
||||||
|
/** SMBUS CRC
|
||||||
|
* aka CRC-8
|
||||||
|
* @param data Pointer to Data
|
||||||
|
* @param datalen Length of Data
|
||||||
|
* @return CRC value
|
||||||
|
*/
|
||||||
|
uint8_t FastCRC8::smbus_upd(const uint8_t *data, uint16_t datalen)
|
||||||
|
{
|
||||||
|
uint8_t crc = seed;
|
||||||
|
if (datalen) do {
|
||||||
|
crc = pgm_read_byte(&crc_table_smbus[crc ^ *data]);
|
||||||
|
data++;
|
||||||
|
} while (--datalen);
|
||||||
|
seed = crc;
|
||||||
|
return crc;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t FastCRC8::smbus(const uint8_t *data, const uint16_t datalen)
|
||||||
|
{
|
||||||
|
// poly=0x07 init=0x00 refin=false refout=false xorout=0x00 check=0xf4
|
||||||
|
seed = 0x00;
|
||||||
|
return smbus_upd(data, datalen);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** MAXIM 8-Bit CRC
|
||||||
|
* equivalent to _crc_ibutton_update() in crc16.h from avr_libc
|
||||||
|
* @param data Pointer to Data
|
||||||
|
* @param datalen Length of Data
|
||||||
|
* @return CRC value
|
||||||
|
*/
|
||||||
|
uint8_t FastCRC8::maxim_upd(const uint8_t *data, uint16_t datalen)
|
||||||
|
{
|
||||||
|
uint8_t crc = seed;
|
||||||
|
if (datalen) do {
|
||||||
|
crc = pgm_read_byte(&crc_table_maxim[crc ^ *data]);
|
||||||
|
data++;
|
||||||
|
} while (--datalen);
|
||||||
|
seed = crc;
|
||||||
|
return crc;
|
||||||
|
}
|
||||||
|
uint8_t FastCRC8::maxim(const uint8_t *data, const uint16_t datalen)
|
||||||
|
{
|
||||||
|
// poly=0x31 init=0x00 refin=true refout=true xorout=0x00 check=0xa1
|
||||||
|
seed = 0x00;
|
||||||
|
return maxim_upd(data, datalen);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ================= 16-BIT CRC ===================
|
||||||
|
/** Constructor
|
||||||
|
*/
|
||||||
|
FastCRC16::FastCRC16(){}
|
||||||
|
|
||||||
|
#define crc_n4(crc, data, table) crc ^= data; \
|
||||||
|
crc = pgm_read_word(&table[(crc & 0xff) + 0x300]) ^ \
|
||||||
|
pgm_read_word(&table[((crc >> 8) & 0xff) + 0x200]) ^ \
|
||||||
|
pgm_read_word(&table[((data >> 16) & 0xff) + 0x100]) ^ \
|
||||||
|
pgm_read_word(&table[data >> 24]);
|
||||||
|
|
||||||
|
/** CCITT
|
||||||
|
* Alias "false CCITT"
|
||||||
|
* @param data Pointer to Data
|
||||||
|
* @param datalen Length of Data
|
||||||
|
* @return CRC value
|
||||||
|
*/
|
||||||
|
uint16_t FastCRC16::ccitt_upd(const uint8_t *data, uint16_t len)
|
||||||
|
{
|
||||||
|
|
||||||
|
uint16_t crc = seed;
|
||||||
|
while (((uintptr_t)data & 3) && len) {
|
||||||
|
crc = (crc >> 8) ^ pgm_read_word(&crc_table_ccitt[(crc & 0xff) ^ *data++]);
|
||||||
|
len--;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (len >= 16) {
|
||||||
|
len -= 16;
|
||||||
|
crc_n4(crc, ((uint32_t *)data)[0], crc_table_ccitt);
|
||||||
|
crc_n4(crc, ((uint32_t *)data)[1], crc_table_ccitt);
|
||||||
|
crc_n4(crc, ((uint32_t *)data)[2], crc_table_ccitt);
|
||||||
|
crc_n4(crc, ((uint32_t *)data)[3], crc_table_ccitt);
|
||||||
|
data += 16;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (len--) {
|
||||||
|
crc = (crc >> 8) ^ pgm_read_word(&crc_table_ccitt[(crc & 0xff) ^ *data++]);
|
||||||
|
}
|
||||||
|
|
||||||
|
seed = crc;
|
||||||
|
crc = REV16(crc);
|
||||||
|
|
||||||
|
return crc;
|
||||||
|
}
|
||||||
|
uint16_t FastCRC16::ccitt(const uint8_t *data,const uint16_t datalen)
|
||||||
|
{
|
||||||
|
// poly=0x1021 init=0xffff refin=false refout=false xorout=0x0000 check=0x29b1
|
||||||
|
seed = 0xffff;
|
||||||
|
return ccitt_upd(data, datalen);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** MCRF4XX
|
||||||
|
* equivalent to _crc_ccitt_update() in crc16.h from avr_libc
|
||||||
|
* @param data Pointer to Data
|
||||||
|
* @param datalen Length of Data
|
||||||
|
* @return CRC value
|
||||||
|
*/
|
||||||
|
|
||||||
|
uint16_t FastCRC16::mcrf4xx_upd(const uint8_t *data, uint16_t len)
|
||||||
|
{
|
||||||
|
|
||||||
|
uint16_t crc = seed;
|
||||||
|
|
||||||
|
while (((uintptr_t)data & 3) && len) {
|
||||||
|
crc = (crc >> 8) ^ pgm_read_word(&crc_table_mcrf4xx[(crc & 0xff) ^ *data++]);
|
||||||
|
len--;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (len >= 16) {
|
||||||
|
len -= 16;
|
||||||
|
crc_n4(crc, ((uint32_t *)data)[0], crc_table_mcrf4xx);
|
||||||
|
crc_n4(crc, ((uint32_t *)data)[1], crc_table_mcrf4xx);
|
||||||
|
crc_n4(crc, ((uint32_t *)data)[2], crc_table_mcrf4xx);
|
||||||
|
crc_n4(crc, ((uint32_t *)data)[3], crc_table_mcrf4xx);
|
||||||
|
data += 16;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (len--) {
|
||||||
|
crc = (crc >> 8) ^ pgm_read_word(&crc_table_mcrf4xx[(crc & 0xff) ^ *data++]);
|
||||||
|
}
|
||||||
|
|
||||||
|
seed = crc;
|
||||||
|
return crc;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t FastCRC16::mcrf4xx(const uint8_t *data,const uint16_t datalen)
|
||||||
|
{
|
||||||
|
// poly=0x1021 init=0xffff refin=true refout=true xorout=0x0000 check=0x6f91
|
||||||
|
seed = 0xffff;
|
||||||
|
return mcrf4xx_upd(data, datalen);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** MODBUS
|
||||||
|
* equivalent to _crc_16_update() in crc16.h from avr_libc
|
||||||
|
* @param data Pointer to Data
|
||||||
|
* @param datalen Length of Data
|
||||||
|
* @return CRC value
|
||||||
|
*/
|
||||||
|
uint16_t FastCRC16::modbus_upd(const uint8_t *data, uint16_t len)
|
||||||
|
{
|
||||||
|
|
||||||
|
uint16_t crc = seed;
|
||||||
|
|
||||||
|
while (((uintptr_t)data & 3) && len) {
|
||||||
|
crc = (crc >> 8) ^ pgm_read_word(&crc_table_modbus[(crc & 0xff) ^ *data++]);
|
||||||
|
len--;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (len >= 16) {
|
||||||
|
len -= 16;
|
||||||
|
crc_n4(crc, ((uint32_t *)data)[0], crc_table_modbus);
|
||||||
|
crc_n4(crc, ((uint32_t *)data)[1], crc_table_modbus);
|
||||||
|
crc_n4(crc, ((uint32_t *)data)[2], crc_table_modbus);
|
||||||
|
crc_n4(crc, ((uint32_t *)data)[3], crc_table_modbus);
|
||||||
|
data += 16;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (len--) {
|
||||||
|
crc = (crc >> 8) ^ pgm_read_word(&crc_table_modbus[(crc & 0xff) ^ *data++]);
|
||||||
|
}
|
||||||
|
|
||||||
|
seed = crc;
|
||||||
|
return crc;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t FastCRC16::modbus(const uint8_t *data, const uint16_t datalen)
|
||||||
|
{
|
||||||
|
// poly=0x8005 init=0xffff refin=true refout=true xorout=0x0000 check=0x4b37
|
||||||
|
seed = 0xffff;
|
||||||
|
return modbus_upd(data, datalen);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** KERMIT
|
||||||
|
* Alias CRC-16/CCITT, CRC-16/CCITT-TRUE, CRC-CCITT
|
||||||
|
* @param data Pointer to Data
|
||||||
|
* @param datalen Length of Data
|
||||||
|
* @return CRC value
|
||||||
|
*/
|
||||||
|
uint16_t FastCRC16::kermit_upd(const uint8_t *data, uint16_t len)
|
||||||
|
{
|
||||||
|
|
||||||
|
uint16_t crc = seed;
|
||||||
|
|
||||||
|
while (((uintptr_t)data & 3) && len) {
|
||||||
|
crc = (crc >> 8) ^ pgm_read_word(&crc_table_kermit[(crc & 0xff) ^ *data++]);
|
||||||
|
len--;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (len >= 16) {
|
||||||
|
len -= 16;
|
||||||
|
crc_n4(crc, ((uint32_t *)data)[0], crc_table_kermit);
|
||||||
|
crc_n4(crc, ((uint32_t *)data)[1], crc_table_kermit);
|
||||||
|
crc_n4(crc, ((uint32_t *)data)[2], crc_table_kermit);
|
||||||
|
crc_n4(crc, ((uint32_t *)data)[3], crc_table_kermit);
|
||||||
|
data += 16;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (len--) {
|
||||||
|
crc = (crc >> 8) ^ pgm_read_word(&crc_table_kermit[(crc & 0xff) ^ *data++]);
|
||||||
|
}
|
||||||
|
|
||||||
|
seed = crc;
|
||||||
|
return crc;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t FastCRC16::kermit(const uint8_t *data, const uint16_t datalen)
|
||||||
|
{
|
||||||
|
// poly=0x1021 init=0x0000 refin=true refout=true xorout=0x0000 check=0x2189
|
||||||
|
// sometimes byteswapped presentation of result
|
||||||
|
seed = 0x0000;
|
||||||
|
return kermit_upd(data, datalen);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** XMODEM
|
||||||
|
* Alias ZMODEM, CRC-16/ACORN
|
||||||
|
* @param data Pointer to Data
|
||||||
|
* @param datalen Length of Data
|
||||||
|
* @return CRC value
|
||||||
|
*/
|
||||||
|
uint16_t FastCRC16::xmodem_upd(const uint8_t *data, uint16_t len)
|
||||||
|
{
|
||||||
|
|
||||||
|
uint16_t crc = seed;
|
||||||
|
|
||||||
|
while (((uintptr_t)data & 3) && len) {
|
||||||
|
crc = (crc >> 8) ^ pgm_read_word(&crc_table_xmodem[(crc & 0xff) ^ *data++]);
|
||||||
|
len--;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (len >= 16) {
|
||||||
|
len -= 16;
|
||||||
|
crc_n4(crc, ((uint32_t *)data)[0], crc_table_xmodem);
|
||||||
|
crc_n4(crc, ((uint32_t *)data)[1], crc_table_xmodem);
|
||||||
|
crc_n4(crc, ((uint32_t *)data)[2], crc_table_xmodem);
|
||||||
|
crc_n4(crc, ((uint32_t *)data)[3], crc_table_xmodem);
|
||||||
|
data += 16;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (len--) {
|
||||||
|
crc = (crc >> 8) ^ pgm_read_word(&crc_table_xmodem[(crc & 0xff) ^ *data++]);
|
||||||
|
}
|
||||||
|
|
||||||
|
seed = crc;
|
||||||
|
crc = REV16(crc);
|
||||||
|
return crc;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t FastCRC16::xmodem(const uint8_t *data, const uint16_t datalen)
|
||||||
|
{
|
||||||
|
//width=16 poly=0x1021 init=0x0000 refin=false refout=false xorout=0x0000 check=0x31c3
|
||||||
|
seed = 0x0000;
|
||||||
|
return xmodem_upd(data, datalen);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** X25
|
||||||
|
* Alias CRC-16/IBM-SDLC, CRC-16/ISO-HDLC, CRC-B
|
||||||
|
* @param data Pointer to Data
|
||||||
|
* @param datalen Length of Data
|
||||||
|
* @return CRC value
|
||||||
|
*/
|
||||||
|
uint16_t FastCRC16::x25_upd(const uint8_t *data, uint16_t len)
|
||||||
|
{
|
||||||
|
|
||||||
|
uint16_t crc = seed;
|
||||||
|
|
||||||
|
while (((uintptr_t)data & 3) && len) {
|
||||||
|
crc = (crc >> 8) ^ pgm_read_word(&crc_table_x25[(crc & 0xff) ^ *data++]);
|
||||||
|
len--;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (len >= 16) {
|
||||||
|
len -= 16;
|
||||||
|
crc_n4(crc, ((uint32_t *)data)[0], crc_table_x25);
|
||||||
|
crc_n4(crc, ((uint32_t *)data)[1], crc_table_x25);
|
||||||
|
crc_n4(crc, ((uint32_t *)data)[2], crc_table_x25);
|
||||||
|
crc_n4(crc, ((uint32_t *)data)[3], crc_table_x25);
|
||||||
|
data += 16;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (len--) {
|
||||||
|
crc = (crc >> 8) ^ pgm_read_word(&crc_table_x25[(crc & 0xff) ^ *data++]);
|
||||||
|
}
|
||||||
|
|
||||||
|
crc = ~crc;
|
||||||
|
|
||||||
|
seed = crc;
|
||||||
|
return crc;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t FastCRC16::x25(const uint8_t *data, const uint16_t datalen)
|
||||||
|
{
|
||||||
|
// poly=0x1021 init=0xffff refin=true refout=true xorout=0xffff check=0x906e
|
||||||
|
seed = 0xffff;
|
||||||
|
return x25_upd(data, datalen);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// ================= 32-BIT CRC ===================
|
||||||
|
/** Constructor
|
||||||
|
*/
|
||||||
|
FastCRC32::FastCRC32(){}
|
||||||
|
|
||||||
|
#define crc_n4d(crc, data, table) crc ^= data; \
|
||||||
|
crc = pgm_read_dword(&table[(crc & 0xff) + 0x300]) ^ \
|
||||||
|
pgm_read_dword(&table[((crc >> 8) & 0xff) + 0x200]) ^ \
|
||||||
|
pgm_read_dword(&table[((crc >> 16) & 0xff) + 0x100]) ^ \
|
||||||
|
pgm_read_dword(&table[(crc >> 24) & 0xff]);
|
||||||
|
|
||||||
|
#define crcsm_n4d(crc, data, table) crc ^= data; \
|
||||||
|
crc = (crc >> 8) ^ pgm_read_dword(&table[crc & 0xff]); \
|
||||||
|
crc = (crc >> 8) ^ pgm_read_dword(&table[crc & 0xff]); \
|
||||||
|
crc = (crc >> 8) ^ pgm_read_dword(&table[crc & 0xff]); \
|
||||||
|
crc = (crc >> 8) ^ pgm_read_dword(&table[crc & 0xff]);
|
||||||
|
|
||||||
|
/** CRC32
|
||||||
|
* Alias CRC-32/ADCCP, PKZIP, Ethernet, 802.3
|
||||||
|
* @param data Pointer to Data
|
||||||
|
* @param datalen Length of Data
|
||||||
|
* @return CRC value
|
||||||
|
*/
|
||||||
|
#if CRC_BIGTABLES
|
||||||
|
#define CRC_TABLE_CRC32 crc_table_crc32_big
|
||||||
|
#else
|
||||||
|
#define CRC_TABLE_CRC32 crc_table_crc32
|
||||||
|
#endif
|
||||||
|
|
||||||
|
uint32_t FastCRC32::crc32_upd(const uint8_t *data, uint16_t len)
|
||||||
|
{
|
||||||
|
|
||||||
|
uint32_t crc = seed;
|
||||||
|
|
||||||
|
while (((uintptr_t)data & 3) && len) {
|
||||||
|
crc = (crc >> 8) ^ pgm_read_dword(&CRC_TABLE_CRC32[(crc & 0xff) ^ *data++]);
|
||||||
|
len--;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (len >= 16) {
|
||||||
|
len -= 16;
|
||||||
|
#if CRC_BIGTABLES
|
||||||
|
crc_n4d(crc, ((uint32_t *)data)[0], CRC_TABLE_CRC32);
|
||||||
|
crc_n4d(crc, ((uint32_t *)data)[1], CRC_TABLE_CRC32);
|
||||||
|
crc_n4d(crc, ((uint32_t *)data)[2], CRC_TABLE_CRC32);
|
||||||
|
crc_n4d(crc, ((uint32_t *)data)[3], CRC_TABLE_CRC32);
|
||||||
|
#else
|
||||||
|
crcsm_n4d(crc, ((uint32_t *)data)[0], CRC_TABLE_CRC32);
|
||||||
|
crcsm_n4d(crc, ((uint32_t *)data)[1], CRC_TABLE_CRC32);
|
||||||
|
crcsm_n4d(crc, ((uint32_t *)data)[2], CRC_TABLE_CRC32);
|
||||||
|
crcsm_n4d(crc, ((uint32_t *)data)[3], CRC_TABLE_CRC32);
|
||||||
|
#endif
|
||||||
|
data += 16;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (len--) {
|
||||||
|
crc = (crc >> 8) ^ pgm_read_dword(&CRC_TABLE_CRC32[(crc & 0xff) ^ *data++]);
|
||||||
|
}
|
||||||
|
|
||||||
|
crc = ~crc;
|
||||||
|
|
||||||
|
seed = crc;
|
||||||
|
return crc;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t FastCRC32::crc32(const uint8_t *data, const uint16_t datalen)
|
||||||
|
{
|
||||||
|
// poly=0x04c11db7 init=0xffffffff refin=true refout=true xorout=0xffffffff check=0xcbf43926
|
||||||
|
seed = 0xffffffff;
|
||||||
|
return crc32_upd(data, datalen);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** CKSUM
|
||||||
|
* Alias CRC-32/POSIX
|
||||||
|
* @param data Pointer to Data
|
||||||
|
* @param datalen Length of Data
|
||||||
|
* @return CRC value
|
||||||
|
*/
|
||||||
|
#if CRC_BIGTABLES
|
||||||
|
#define CRC_TABLE_CKSUM crc_table_cksum_big
|
||||||
|
#else
|
||||||
|
#define CRC_TABLE_CKSUM crc_table_cksum
|
||||||
|
#endif
|
||||||
|
uint32_t FastCRC32::cksum_upd(const uint8_t *data, uint16_t len)
|
||||||
|
{
|
||||||
|
|
||||||
|
uint32_t crc = seed;
|
||||||
|
|
||||||
|
while (((uintptr_t)data & 3) && len) {
|
||||||
|
crc = (crc >> 8) ^ pgm_read_dword(&CRC_TABLE_CKSUM[(crc & 0xff) ^ *data++]);
|
||||||
|
len--;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (len >= 16) {
|
||||||
|
len -= 16;
|
||||||
|
#if CRC_BIGTABLES
|
||||||
|
crc_n4d(crc, ((uint32_t *)data)[0], CRC_TABLE_CKSUM);
|
||||||
|
crc_n4d(crc, ((uint32_t *)data)[1], CRC_TABLE_CKSUM);
|
||||||
|
crc_n4d(crc, ((uint32_t *)data)[2], CRC_TABLE_CKSUM);
|
||||||
|
crc_n4d(crc, ((uint32_t *)data)[3], CRC_TABLE_CKSUM);
|
||||||
|
#else
|
||||||
|
crcsm_n4d(crc, ((uint32_t *)data)[0], CRC_TABLE_CKSUM);
|
||||||
|
crcsm_n4d(crc, ((uint32_t *)data)[1], CRC_TABLE_CKSUM);
|
||||||
|
crcsm_n4d(crc, ((uint32_t *)data)[2], CRC_TABLE_CKSUM);
|
||||||
|
crcsm_n4d(crc, ((uint32_t *)data)[3], CRC_TABLE_CKSUM);
|
||||||
|
#endif
|
||||||
|
data += 16;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (len--) {
|
||||||
|
crc = (crc >> 8) ^ pgm_read_dword(&CRC_TABLE_CKSUM[(crc & 0xff) ^ *data++]);
|
||||||
|
}
|
||||||
|
|
||||||
|
seed = crc;
|
||||||
|
crc = ~REV32(crc);
|
||||||
|
return crc;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t FastCRC32::cksum(const uint8_t *data, const uint16_t datalen)
|
||||||
|
{
|
||||||
|
// width=32 poly=0x04c11db7 init=0x00000000 refin=false refout=false xorout=0xffffffff check=0x765e7680
|
||||||
|
seed = 0x00;
|
||||||
|
return cksum_upd(data, datalen);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // #if !defined(KINETISK)
|
|
@ -0,0 +1,21 @@
|
||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) 2016 Frank
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
|
@ -0,0 +1,56 @@
|
||||||
|
FastCRC
|
||||||
|
=======
|
||||||
|
|
||||||
|
Fast CRC Arduino library
|
||||||
|
Up to 30 times faster than crc16.h (_avr_libc)
|
||||||
|
|
||||||
|
- uses the on-chip hardware for Teensy 3.0 / 3.1 / 3.2 / 3.5 / 3.6
|
||||||
|
- uses fast table-algorithms for other chips
|
||||||
|
|
||||||
|
List of supported CRC calculations:
|
||||||
|
-
|
||||||
|
7 BIT:
|
||||||
|
|
||||||
|
CRC7
|
||||||
|
(poly=0x09 init=0x00 refin=false refout=false xorout=0x00 check=0x75)
|
||||||
|
MultiMediaCard interface
|
||||||
|
|
||||||
|
|
||||||
|
8 BIT:
|
||||||
|
|
||||||
|
SMBUS
|
||||||
|
(poly=0x07 init=0x00 refin=false refout=false xorout=0x00 check=0xf4)
|
||||||
|
|
||||||
|
MAXIM
|
||||||
|
(poly=0x31 init=0x00 refin=true refout=true xorout=0x00 check=0xa1)
|
||||||
|
|
||||||
|
|
||||||
|
16 BIT:
|
||||||
|
|
||||||
|
KERMIT (Alias CRC-16/CCITT, CRC-16/CCITT-TRUE, CRC-CCITT)
|
||||||
|
(poly=0x1021 init=0x0000 refin=true refout=true xorout=0x0000 check=0x2189
|
||||||
|
Attention: sometimes you'll find byteswapped presentation of result in other implementations)
|
||||||
|
|
||||||
|
CCITT-FALSE
|
||||||
|
(poly=0x1021 init=0xffff refin=false refout=false xorout=0x0000 check=0x29b1)
|
||||||
|
|
||||||
|
MCRF4XX
|
||||||
|
(poly=0x1021 init=0xffff refin=true refout=true xorout=0x0000 check=0x6f91)
|
||||||
|
|
||||||
|
MODBUS
|
||||||
|
(poly=0x8005 init=0xffff refin=true refout=true xorout=0x0000 check=0x4b37)
|
||||||
|
|
||||||
|
XMODEM (Alias ZMODEM, CRC-16/ACORN)
|
||||||
|
(poly=0x1021 init=0x0000 refin=false refout=false xorout=0x0000 check=0x31c3)
|
||||||
|
|
||||||
|
X25 (Alias CRC-16/IBM-SDLC, CRC-16/ISO-HDLC, CRC-B)
|
||||||
|
(poly=0x1021 init=0xffff refin=true refout=true xorout=0xffff check=0x906e)
|
||||||
|
|
||||||
|
|
||||||
|
32 BIT:
|
||||||
|
|
||||||
|
CRC32, CRC-32/ADCCP, PKZIP, ETHERNET, 802.3
|
||||||
|
(poly=0x04c11db7 init=0xffffffff refin=true refout=true xorout=0xffffffff check=0xcbf43926)
|
||||||
|
|
||||||
|
CKSUM, CRC-32/POSIX
|
||||||
|
(poly=0x04c11db7 init=0x00000000 refin=false refout=false xorout=0xffffffff check=0x765e7680)
|
|
@ -0,0 +1,163 @@
|
||||||
|
/*
|
||||||
|
FastCRC
|
||||||
|
Benchmark
|
||||||
|
|
||||||
|
(c) Frank Boesing 2014-2016
|
||||||
|
|
||||||
|
Edit FastCRC.h for smaller Tables (#define CRC_BIGTABLES 1) - not needed for Teensy 3.x
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <util/crc16.h>
|
||||||
|
#include <FastCRC.h>
|
||||||
|
|
||||||
|
|
||||||
|
//#define LOFLASH // <- Uncomment this for devices with small flashmemory
|
||||||
|
|
||||||
|
//Determince the max. possible size for the data:
|
||||||
|
#if defined(__MK20DX256__) || defined(__MK64FX512__) || defined(__MK66FX1M0__)
|
||||||
|
#define BUFSIZE (56 * 1024) // 56KB for Teensy 3.x
|
||||||
|
#elif defined(__MK20DX128__)
|
||||||
|
#define BUFSIZE (12 * 1024) // 12KB for Teensy 3.0
|
||||||
|
#elif defined(__MKL26Z64__)
|
||||||
|
#define BUFSIZE (4 * 1024) // 4KB for Teensy LC
|
||||||
|
#else
|
||||||
|
#define BUFSIZE (1 * 1024) // 1KB for Teensy 2.0 / others...(use max. possible!)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
uint8_t buf[BUFSIZE];
|
||||||
|
|
||||||
|
FastCRC8 CRC8;
|
||||||
|
FastCRC16 CRC16;
|
||||||
|
FastCRC32 CRC32;
|
||||||
|
|
||||||
|
|
||||||
|
// Supporting functions for Software CRC
|
||||||
|
|
||||||
|
inline uint16_t softcrc(uint16_t seed, uint8_t *data, uint16_t datalen) {
|
||||||
|
for (uint16_t i = 0; i < datalen; i++) {
|
||||||
|
seed = _crc16_update(seed, data[i]);
|
||||||
|
}
|
||||||
|
return seed;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline uint16_t softcrcIbutton(uint16_t seed, uint8_t *data, uint16_t datalen) {
|
||||||
|
for (uint16_t i = 0; i < datalen; i++) {
|
||||||
|
seed = _crc_ibutton_update(seed, data[i]);
|
||||||
|
}
|
||||||
|
return seed;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline uint16_t softcrcCCIT(uint16_t seed, uint8_t *data, uint16_t datalen) {
|
||||||
|
for (uint16_t i = 0; i < datalen; i++) {
|
||||||
|
seed = _crc_ccitt_update(seed, data[i]);
|
||||||
|
}
|
||||||
|
return seed;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline uint16_t softcrcXMODEM(uint16_t seed, uint8_t *data, uint16_t datalen) {
|
||||||
|
for (uint16_t i = 0; i < datalen; i++) {
|
||||||
|
seed = _crc_xmodem_update(seed, data[i]);
|
||||||
|
}
|
||||||
|
return seed;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void printVals(const char * name, const uint32_t crc, const uint32_t time) {
|
||||||
|
Serial.print(name);
|
||||||
|
Serial.print("\tValue:0x");
|
||||||
|
Serial.print(crc, HEX);
|
||||||
|
Serial.print(", Time: ");
|
||||||
|
Serial.print(time);
|
||||||
|
Serial.print(" us (");
|
||||||
|
Serial.print((8.*BUFSIZE) / time);
|
||||||
|
Serial.println(" mbs)");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void setup() {
|
||||||
|
int time;
|
||||||
|
uint32_t crc;
|
||||||
|
|
||||||
|
delay(1500);
|
||||||
|
Serial.begin(115200);
|
||||||
|
|
||||||
|
Serial.println("CRC Benchmark");
|
||||||
|
Serial.print("F_CPU: ");
|
||||||
|
Serial.print((int) (F_CPU / 1E6));
|
||||||
|
Serial.print(" MHz, length: ");
|
||||||
|
Serial.print(BUFSIZE);
|
||||||
|
Serial.println(" Bytes.");
|
||||||
|
Serial.println();
|
||||||
|
|
||||||
|
//Fill array with testdata
|
||||||
|
for (uint16_t i = 0; i < BUFSIZE; i++) {
|
||||||
|
buf[i] = (i + 1) & 0xff;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 8 BIT */
|
||||||
|
time = micros();
|
||||||
|
crc = CRC8.maxim(buf, BUFSIZE);
|
||||||
|
time = micros() - time;
|
||||||
|
printVals("Maxim (iButton) FastCRC:", crc, time);
|
||||||
|
|
||||||
|
time = micros();
|
||||||
|
crc = softcrcIbutton(0, buf, BUFSIZE);
|
||||||
|
time = micros() - time;
|
||||||
|
printVals("Maxim (iButton) builtin:", crc, time);
|
||||||
|
|
||||||
|
#if !defined(LOFLASH)
|
||||||
|
time = micros();
|
||||||
|
crc = CRC16.modbus(buf, BUFSIZE);
|
||||||
|
time = micros() - time;
|
||||||
|
printVals("MODBUS FastCRC:", crc, time);
|
||||||
|
|
||||||
|
time = micros();
|
||||||
|
crc = softcrc(0xffff, buf, BUFSIZE);
|
||||||
|
time = micros() - time;
|
||||||
|
printVals("MODBUS builtin: ", crc, time);
|
||||||
|
|
||||||
|
time = micros();
|
||||||
|
crc = CRC16.xmodem(buf, BUFSIZE);
|
||||||
|
time = micros() - time;
|
||||||
|
printVals("XMODEM FastCRC:", crc, time);
|
||||||
|
|
||||||
|
time = micros();
|
||||||
|
crc = softcrcXMODEM(0, buf, BUFSIZE);
|
||||||
|
time = micros() - time;
|
||||||
|
printVals("XMODEM builtin: ", crc, time);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* 16 BIT */
|
||||||
|
time = micros();
|
||||||
|
crc = CRC16.mcrf4xx(buf, BUFSIZE);
|
||||||
|
time = micros() - time;
|
||||||
|
printVals("MCRF4XX FastCRC:", crc, time);
|
||||||
|
|
||||||
|
|
||||||
|
time = micros();
|
||||||
|
crc = softcrcCCIT(0xffff, buf, BUFSIZE);
|
||||||
|
time = micros() - time;
|
||||||
|
printVals("MCRF4XX builtin:", crc, time);
|
||||||
|
|
||||||
|
#if !defined(LOFLASH)
|
||||||
|
time = micros();
|
||||||
|
crc = CRC16.kermit(buf, BUFSIZE);
|
||||||
|
time = micros() - time;
|
||||||
|
printVals("KERMIT FastCRC:", crc, time);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/* 32 BIT */
|
||||||
|
#if !defined(LOFLASH)
|
||||||
|
time = micros();
|
||||||
|
crc = CRC32.crc32(buf, BUFSIZE);
|
||||||
|
time = micros() - time;
|
||||||
|
printVals("Ethernet FastCRC:", crc, time);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop() {
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,36 @@
|
||||||
|
/*
|
||||||
|
FastCRC-Example
|
||||||
|
|
||||||
|
(c) Frank Boesing 2014
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <FastCRC.h>
|
||||||
|
|
||||||
|
FastCRC16 CRC16;
|
||||||
|
|
||||||
|
uint8_t buf[9] = {'1', '2', '3', '4', '5', '6', '7', '8', '9'};
|
||||||
|
|
||||||
|
void setup() {
|
||||||
|
|
||||||
|
delay(1500);
|
||||||
|
Serial.begin(115200);
|
||||||
|
|
||||||
|
Serial.println("CRC Example");
|
||||||
|
Serial.println();
|
||||||
|
|
||||||
|
Serial.print("CCITT-CRC of \"");
|
||||||
|
|
||||||
|
for (unsigned int i = 0; i < sizeof(buf); i++) {
|
||||||
|
Serial.print((char) buf[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
Serial.print("\" is: 0x");
|
||||||
|
Serial.println( CRC16.ccitt(buf, sizeof(buf)), HEX );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void loop() {
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,36 @@
|
||||||
|
/*
|
||||||
|
FastCRC-Example
|
||||||
|
|
||||||
|
(c) Frank Boesing 2014
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <FastCRC.h>
|
||||||
|
|
||||||
|
FastCRC32 CRC32;
|
||||||
|
|
||||||
|
uint8_t buf[9] = {'1', '2', '3', '4', '5', '6', '7', '8', '9'};
|
||||||
|
|
||||||
|
void setup() {
|
||||||
|
|
||||||
|
delay(1500);
|
||||||
|
Serial.begin(115200);
|
||||||
|
|
||||||
|
Serial.println("CRC Example");
|
||||||
|
Serial.println();
|
||||||
|
|
||||||
|
Serial.print("CRC32 of \"");
|
||||||
|
|
||||||
|
for (unsigned int i = 0; i < sizeof(buf); i++) {
|
||||||
|
Serial.print((char) buf[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
Serial.print("\" is: 0x");
|
||||||
|
Serial.println( CRC32.crc32(buf, sizeof(buf)), HEX );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void loop() {
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,36 @@
|
||||||
|
/*
|
||||||
|
FastCRC-Example
|
||||||
|
|
||||||
|
(c) Frank Boesing 2014
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <FastCRC.h>
|
||||||
|
|
||||||
|
FastCRC8 CRC8;
|
||||||
|
|
||||||
|
uint8_t buf[9] = {'1', '2', '3', '4', '5', '6', '7', '8', '9'};
|
||||||
|
|
||||||
|
void setup() {
|
||||||
|
|
||||||
|
delay(1500);
|
||||||
|
Serial.begin(115200);
|
||||||
|
|
||||||
|
Serial.println("CRC Example");
|
||||||
|
Serial.println();
|
||||||
|
|
||||||
|
Serial.print("SMBUS-CRC of \"");
|
||||||
|
|
||||||
|
for (unsigned int i = 0; i < sizeof(buf); i++) {
|
||||||
|
Serial.print((char) buf[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
Serial.print("\" is: 0x");
|
||||||
|
Serial.println( CRC8.smbus(buf, sizeof(buf)), HEX );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void loop() {
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,47 @@
|
||||||
|
/*
|
||||||
|
FastCRC-Example
|
||||||
|
|
||||||
|
(c) Frank Boesing 2014
|
||||||
|
|
||||||
|
This example shows how to use the update functions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <FastCRC.h>
|
||||||
|
|
||||||
|
FastCRC16 CRC16;
|
||||||
|
|
||||||
|
uint8_t buf[9] = {'1', '2', '3', '4', '5', '6', '7', '8', '9'};
|
||||||
|
|
||||||
|
void setup() {
|
||||||
|
uint16_t crc;
|
||||||
|
|
||||||
|
delay(1500);
|
||||||
|
Serial.begin(115200);
|
||||||
|
|
||||||
|
Serial.println("CRC Example");
|
||||||
|
Serial.println();
|
||||||
|
|
||||||
|
Serial.print("CCITT-CRC of \"");
|
||||||
|
|
||||||
|
for (unsigned int i = 0; i < sizeof(buf); i++) {
|
||||||
|
Serial.print((char) buf[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
Serial.print("\" is: 0x");
|
||||||
|
|
||||||
|
|
||||||
|
//Calculate first half of buffer:
|
||||||
|
crc = CRC16.ccitt(&buf[0], 4);
|
||||||
|
|
||||||
|
//Calculate seconde half of buffer:
|
||||||
|
crc = CRC16.ccitt_upd(&buf[4],5);
|
||||||
|
|
||||||
|
Serial.println(crc, HEX );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void loop() {
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,71 @@
|
||||||
|
//FastCRC
|
||||||
|
//Validate computed CRCs
|
||||||
|
//
|
||||||
|
//(c) Frank Boesing 2014
|
||||||
|
|
||||||
|
#include <util/crc16.h>
|
||||||
|
#include <FastCRC.h>
|
||||||
|
|
||||||
|
FastCRC7 CRC7;
|
||||||
|
FastCRC8 CRC8;
|
||||||
|
FastCRC16 CRC16;
|
||||||
|
FastCRC32 CRC32;
|
||||||
|
|
||||||
|
|
||||||
|
uint8_t buf[9] = {'1','2','3','4','5','6','7','8','9'};
|
||||||
|
|
||||||
|
|
||||||
|
void printVals(const char * name, uint32_t check, uint32_t val){
|
||||||
|
Serial.print(name);
|
||||||
|
if (check == val)
|
||||||
|
Serial.print(" is ok");
|
||||||
|
else
|
||||||
|
Serial.print(" is NOT ok");
|
||||||
|
Serial.println();
|
||||||
|
}
|
||||||
|
|
||||||
|
void setup() {
|
||||||
|
uint32_t crc;
|
||||||
|
|
||||||
|
delay(1500);
|
||||||
|
Serial.begin(115200);
|
||||||
|
|
||||||
|
Serial.println("CRC Validation");
|
||||||
|
|
||||||
|
crc = CRC7.crc7(buf, sizeof(buf));
|
||||||
|
printVals("CRC7", 0x75, crc);
|
||||||
|
|
||||||
|
crc = CRC8.smbus(buf, sizeof(buf));
|
||||||
|
printVals("SMBUS", 0xf4, crc);
|
||||||
|
|
||||||
|
crc = CRC8.maxim(buf, sizeof(buf));
|
||||||
|
printVals("Maxim", 0xa1, crc);
|
||||||
|
|
||||||
|
crc = CRC16.ccitt(buf, sizeof(buf));
|
||||||
|
printVals("CCITT", 0x29b1, crc);
|
||||||
|
|
||||||
|
crc = CRC16.mcrf4xx(buf, sizeof(buf));
|
||||||
|
printVals("MCRF4XX", 0x6f91, crc);
|
||||||
|
|
||||||
|
crc = CRC16.modbus(buf, sizeof(buf));
|
||||||
|
printVals("MODBUS", 0x4b37, crc);
|
||||||
|
|
||||||
|
crc = CRC16.kermit(buf, sizeof(buf));
|
||||||
|
printVals("KERMIT", 0x2189, crc);
|
||||||
|
|
||||||
|
crc = CRC16.xmodem(buf, sizeof(buf));
|
||||||
|
printVals("XMODEM", 0x31c3, crc);
|
||||||
|
|
||||||
|
crc = CRC16.x25(buf, sizeof(buf));
|
||||||
|
printVals("X.25", 0x906e, crc);
|
||||||
|
|
||||||
|
crc = CRC32.crc32(buf, sizeof(buf));
|
||||||
|
printVals("CRC32", 0xcbf43926, crc);
|
||||||
|
|
||||||
|
crc = CRC32.cksum(buf, sizeof(buf));
|
||||||
|
printVals("CKSUM", 0x765e7680, crc);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void loop() {
|
||||||
|
}
|
|
@ -0,0 +1,52 @@
|
||||||
|
#######################################
|
||||||
|
# Syntax Coloring Map For FastCRC
|
||||||
|
#######################################
|
||||||
|
|
||||||
|
#######################################
|
||||||
|
# Datatypes (KEYWORD1)
|
||||||
|
#######################################
|
||||||
|
|
||||||
|
FastCRC7 KEYWORD1
|
||||||
|
FastCRC8 KEYWORD1
|
||||||
|
FastCRC16 KEYWORD1
|
||||||
|
FastCRC32 KEYWORD1
|
||||||
|
CRC7 KEYWORD1
|
||||||
|
CRC8 KEYWORD1
|
||||||
|
CRC16 KEYWORD1
|
||||||
|
CRC32 KEYWORD1
|
||||||
|
|
||||||
|
#######################################
|
||||||
|
# Methods and Functions (KEYWORD2)
|
||||||
|
#######################################
|
||||||
|
crc7 KEYWORD2
|
||||||
|
crc7_upd KEYWORD2
|
||||||
|
ccitt KEYWORD2
|
||||||
|
ccitt_upd KEYWORD2
|
||||||
|
kermit KEYWORD2
|
||||||
|
kermit_upd KEYWORD2
|
||||||
|
mcrf4xx KEYWORD2
|
||||||
|
mcrf4xx_upd KEYWORD2
|
||||||
|
modbus KEYWORD2
|
||||||
|
modbus_upd KEYWORD2
|
||||||
|
xmodem KEYWORD2
|
||||||
|
xmodem_upd KEYWORD2
|
||||||
|
x25 KEYWORD2
|
||||||
|
x25_upd KEYWORD2
|
||||||
|
update KEYWORD2
|
||||||
|
update_upd KEYWORD2
|
||||||
|
generic KEYWORD2
|
||||||
|
crc32 KEYWORD2
|
||||||
|
crc32_upd KEYWORD2
|
||||||
|
cksum KEYWORD2
|
||||||
|
cksum_upd KEYWORD2
|
||||||
|
|
||||||
|
#######################################
|
||||||
|
# Constants (LITERAL1)
|
||||||
|
#######################################
|
||||||
|
|
||||||
|
CRC_FLAG_NOREFLECT LITERAL1
|
||||||
|
CRC_FLAG_REFLECT LITERAL1
|
||||||
|
CRC_FLAG_XOR LITERAL1
|
||||||
|
CRC_FLAG_NOREFLECT_8 LITERAL1
|
||||||
|
CRC_FLAG_REFLECT_SWAP LITERAL1
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
name=FastCRC
|
||||||
|
version=1.2
|
||||||
|
author=Frank Bösing
|
||||||
|
maintainer=Frank Boesing<f.boesing@gmx.de>
|
||||||
|
sentence=Fast CRC routines
|
||||||
|
paragraph=
|
||||||
|
category=Data Processing
|
||||||
|
url=https://github.com/FrankBoesing/FastCRC
|
||||||
|
architectures=*
|
Loading…
Reference in New Issue