#if defined(ARDUINO)
#include <Arduino.h>
#endif
#if defined(KINETISK)
#include "mk20dx128.h"
#include "FastCRC.h"
typedef struct {
union {
uint32_t CRC; 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; uint32_t CTRL; } CRC_T;
static volatile CRC_T * const rCRC = (CRC_T *)0x40032000;
#define CRC_CTRL_WAS 25
#define CRC_CTRL_TCRC 24
#define CRC_CTRL_TOTR1 29
FastCRC7::FastCRC7(){
SIM_SCGC6 |= SIM_SCGC6_CRC;
}
uint8_t FastCRC7::crc7(const uint8_t *data, const size_t datalen)
{
return (generic(0x09, 0, CRC_FLAG_NOREFLECT, data, datalen));
}
uint8_t FastCRC7::update(const uint8_t *data, const size_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++; }
while (src <= target-4) {
rCRC->CRC = *( uint32_t *)src; src += 4;
}
while (src < target) {
rCRC->CRC8_3 = *src++; }
return rCRC->CRC8_3 >> 1;
}
uint8_t FastCRC7::generic(const uint8_t polynom, const uint8_t seed, const uint32_t flags, const uint8_t *data,const size_t datalen)
{
rCRC->CTRL = flags | (1<<CRC_CTRL_TCRC) | (1<<CRC_CTRL_WAS); rCRC->GPOLY = ((uint32_t)polynom)<<(24 + 1); rCRC->CRC = ((uint32_t)seed<<(24 + 1)); rCRC->CTRL = flags | (1<<CRC_CTRL_TCRC);
return update(data, datalen);
}
uint8_t FastCRC7::crc7_upd(const uint8_t *data, size_t datalen){return update(data, datalen);}
FastCRC8::FastCRC8(){
SIM_SCGC6 |= SIM_SCGC6_CRC;
}
uint8_t FastCRC8::smbus(const uint8_t *data, const size_t datalen)
{
return generic(0x07, 0, CRC_FLAG_NOREFLECT, data, datalen);
}
uint8_t FastCRC8::maxim(const uint8_t *data, const size_t datalen)
{
return generic(0x31, 0, CRC_FLAG_REFLECT, data, datalen);
}
uint8_t FastCRC8::update(const uint8_t *data, const size_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++; }
while (src <= target-4) {
rCRC->CRC = *( uint32_t *)src; src += 4;
}
while (src < target) {
rCRC->CRC8_3 = *src++; }
if (rCRC->CTRL & (1<<CRC_CTRL_TOTR1))
return rCRC->CRC8;
else
return rCRC->CRC8_3;
}
uint8_t FastCRC8::generic(const uint8_t polynom, const uint8_t seed, const uint32_t flags, const uint8_t *data,const size_t datalen)
{
rCRC->CTRL = flags | (1<<CRC_CTRL_TCRC) | (1<<CRC_CTRL_WAS); rCRC->GPOLY = ((uint32_t)polynom)<<24; rCRC->CRC = ((uint32_t)seed<<24); rCRC->CTRL = flags | (1<<CRC_CTRL_TCRC);
return update(data, datalen);
}
uint8_t FastCRC8::smbus_upd(const uint8_t *data, size_t datalen){return update(data, datalen);}
uint8_t FastCRC8::maxim_upd(const uint8_t *data, size_t datalen){return update(data, datalen);}
FastCRC14::FastCRC14(){
SIM_SCGC6 |= SIM_SCGC6_CRC;
}
uint16_t FastCRC14::darc(const uint8_t *data,const size_t datalen)
{
return generic(0x0805, 0x0000, CRC_FLAG_REFLECT, data, datalen);
}
uint16_t FastCRC14::gsm(const uint8_t *data,const size_t datalen)
{
return generic(0x202d, 0x0000, CRC_FLAG_NOREFLECT | CRC_FLAG_XOR, data, datalen);
}
uint16_t FastCRC14::eloran(const uint8_t *data,const size_t datalen)
{
return generic(0x60b1, 0x0, CRC_FLAG_NOREFLECT , data, datalen);
}
uint16_t FastCRC14::update(const uint8_t *data, const size_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++; }
while (src <= target-4) {
rCRC->CRC = *( uint32_t *)src; src += 4;
}
while (src < target) {
rCRC->CRC8_3 = *src++; }
if (rCRC->CTRL & (1<<CRC_CTRL_TOTR1))
return rCRC->CRC16;
else
return rCRC->CRC >> (32 - 14);
}
uint16_t FastCRC14::generic(const uint16_t polynom, const uint16_t seed, const uint32_t flags, const uint8_t *data, const size_t datalen)
{
rCRC->CTRL = flags | (1<<CRC_CTRL_TCRC) | (1<<CRC_CTRL_WAS); rCRC->GPOLY = ((uint32_t)polynom) << (32 - 14); rCRC->CRC = ((uint32_t)seed << (32 - 14) ); rCRC->CTRL = flags | (1<<CRC_CTRL_TCRC);
return update(data, datalen);
}
uint16_t FastCRC14::darc_upd(const uint8_t *data, size_t len) {return update(data, len);}
uint16_t FastCRC14::gsm_upd(const uint8_t *data, size_t len) {return update(data, len);}
uint16_t FastCRC14::eloran_upd(const uint8_t *data, size_t len) {return update(data, len);}
FastCRC16::FastCRC16(){
SIM_SCGC6 |= SIM_SCGC6_CRC;
}
uint16_t FastCRC16::ccitt(const uint8_t *data,const size_t datalen)
{
return generic(0x1021, 0XFFFF, CRC_FLAG_NOREFLECT, data, datalen);
}
uint16_t FastCRC16::mcrf4xx(const uint8_t *data,const size_t datalen)
{
return generic(0x1021, 0XFFFF, CRC_FLAG_REFLECT , data, datalen);
}
uint16_t FastCRC16::modbus(const uint8_t *data, const size_t datalen)
{
return generic(0x8005, 0XFFFF, CRC_FLAG_REFLECT, data, datalen);
}
uint16_t FastCRC16::kermit(const uint8_t *data, const size_t datalen)
{
return generic(0x1021, 0x00, CRC_FLAG_REFLECT, data, datalen);
}
uint16_t FastCRC16::xmodem(const uint8_t *data, const size_t datalen)
{
return generic(0x1021, 0, CRC_FLAG_NOREFLECT, data, datalen);
}
uint16_t FastCRC16::x25(const uint8_t *data, const size_t datalen)
{
return generic(0x1021, 0XFFFF, CRC_FLAG_REFLECT | CRC_FLAG_XOR, data, datalen);
}
uint16_t FastCRC16::update(const uint8_t *data, const size_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++; }
while (src <= target-4) {
rCRC->CRC = *( uint32_t *)src; src += 4;
}
while (src < target) {
rCRC->CRC8_3 = *src++; }
if (rCRC->CTRL & (1<<CRC_CTRL_TOTR1))
return rCRC->CRC16;
else
return rCRC->CRC16_1;
}
uint16_t FastCRC16::generic(const uint16_t polynom, const uint16_t seed, const uint32_t flags, const uint8_t *data, const size_t datalen)
{
rCRC->CTRL = flags | (1<<CRC_CTRL_TCRC) | (1<<CRC_CTRL_WAS); rCRC->GPOLY = ((uint32_t)polynom)<<16; rCRC->CRC = ((uint32_t)seed<<16); rCRC->CTRL = flags | (1<<CRC_CTRL_TCRC);
return update(data, datalen);
}
uint16_t FastCRC16::ccitt_upd(const uint8_t *data, size_t len) {return update(data, len);}
uint16_t FastCRC16::mcrf4xx_upd(const uint8_t *data, size_t len){return update(data, len);}
uint16_t FastCRC16::kermit_upd(const uint8_t *data, size_t len) {return update(data, len);}
uint16_t FastCRC16::modbus_upd(const uint8_t *data, size_t len) {return update(data, len);}
uint16_t FastCRC16::xmodem_upd(const uint8_t *data, size_t len) {return update(data, len);}
uint16_t FastCRC16::x25_upd(const uint8_t *data, size_t len) {return update(data, len);}
FastCRC32::FastCRC32(){
SIM_SCGC6 |= SIM_SCGC6_CRC;
}
uint32_t FastCRC32::crc32(const uint8_t *data, const size_t datalen)
{
return generic(0x04C11DB7L, 0XFFFFFFFFL, CRC_FLAG_REFLECT | CRC_FLAG_XOR, data, datalen);
}
uint32_t FastCRC32::cksum(const uint8_t *data, const size_t datalen)
{
return generic(0x04C11DB7L, 0, CRC_FLAG_NOREFLECT | CRC_FLAG_XOR, data, datalen);
}
uint32_t FastCRC32::update(const uint8_t *data, const size_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++; }
while (src <= target-4) {
rCRC->CRC = *( uint32_t *)src; src += 4;
}
while (src < target) {
rCRC->CRC8_3 = *src++; }
return rCRC->CRC;
}
uint32_t FastCRC32::generic(const uint32_t polynom, const uint32_t seed, const uint32_t flags, const uint8_t *data, const size_t datalen)
{
rCRC->CTRL = flags | (1<<CRC_CTRL_TCRC) | (1<<CRC_CTRL_WAS); rCRC->GPOLY = polynom; rCRC->CRC = seed; rCRC->CTRL = flags | (1<<CRC_CTRL_TCRC);
return update(data, datalen);
}
uint32_t FastCRC32::crc32_upd(const uint8_t *data, size_t len){return update(data, len);}
uint32_t FastCRC32::cksum_upd(const uint8_t *data, size_t len){return update(data, len);}
#endif