Skip to content

Commit

Permalink
Add CRC classes CRC8, CRC16, CRC32, CRC64 (#3)
Browse files Browse the repository at this point in the history
* version 0.1.1
  • Loading branch information
RobTillaart authored Jan 20, 2021
1 parent 2dac155 commit 783d437
Show file tree
Hide file tree
Showing 21 changed files with 1,040 additions and 133 deletions.
19 changes: 8 additions & 11 deletions CRC.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,16 @@
//
// FILE: CRC.h
// AUTHOR: Rob Tillaart
// VERSION: 0.1.0
// VERSION: 0.1.1
// PURPOSE: Arduino library fir CRC8, CRC16, CRC16-CCITT, CRC32
// URL: https://github.com/RobTillaart/CRC
//



#include "Arduino.h"


#define CRC_LIB_VERSION (F("0.1.0"))
#define CRC_LIB_VERSION (F("0.1.1"))


////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -68,7 +67,7 @@ uint64_t reverse64(uint64_t in)
///////////////////////////////////////////////////////////////////////////////////

// CRC POLYNOME = x8 + x5 + x4 + 1 = 1001 1000 = 0x8C
uint8_t CRC8(uint8_t *array, uint8_t length, uint8_t polynome = 0xD5, uint8_t startmask = 0x00, uint8_t endmask = 0x00, bool reverseIn = false, bool reverseOut = false)
uint8_t crc8(uint8_t *array, uint8_t length, uint8_t polynome = 0xD5, uint8_t startmask = 0x00, uint8_t endmask = 0x00, bool reverseIn = false, bool reverseOut = false)
{
uint8_t crc = startmask;
while (length--)
Expand Down Expand Up @@ -96,7 +95,7 @@ uint8_t CRC8(uint8_t *array, uint8_t length, uint8_t polynome = 0xD5, uint8_t st


// CRC POLYNOME = x15 + 1 = 1000 0000 0000 0001 = 0x8001
uint16_t CRC16(uint8_t *array, uint8_t length, uint16_t polynome = 0x8001, uint16_t startmask = 0x0000, uint16_t endmask = 0x0000, bool reverseIn = false, bool reverseOut = false)
uint16_t crc16(uint8_t *array, uint8_t length, uint16_t polynome = 0x8001, uint16_t startmask = 0x0000, uint16_t endmask = 0x0000, bool reverseIn = false, bool reverseOut = false)
{
uint16_t crc = startmask;
while (length--)
Expand Down Expand Up @@ -124,14 +123,14 @@ uint16_t CRC16(uint8_t *array, uint8_t length, uint16_t polynome = 0x8001, uint1


// CRC-CCITT POLYNOME = x13 + X5 + 1 = 0001 0000 0010 0001 = 0x1021
uint16_t CRC16_CCITT(uint8_t *array, uint8_t length)
uint16_t crc16_CCITT(uint8_t *array, uint8_t length)
{
return CRC16(array, length, 0x1021, 0xFFFF);
return crc16(array, length, 0x1021, 0xFFFF);
}


// CRC-32 POLYNOME = x32 + ..... + 1
uint32_t CRC32(uint8_t *array, uint8_t length, uint32_t polynome = 0x04C11DB7, uint32_t startmask = 0, uint32_t endmask = 0, bool reverseIn = false, bool reverseOut = false)
uint32_t crc32(uint8_t *array, uint8_t length, uint32_t polynome = 0x04C11DB7, uint32_t startmask = 0, uint32_t endmask = 0, bool reverseIn = false, bool reverseOut = false)
{
uint32_t crc = startmask;
while (length--)
Expand Down Expand Up @@ -159,7 +158,7 @@ uint32_t CRC32(uint8_t *array, uint8_t length, uint32_t polynome = 0x04C11DB7, u


// CRC-CCITT POLYNOME = x64 + ..... + 1
uint64_t CRC64(uint8_t *array, uint8_t length, uint64_t polynome, uint64_t startmask, uint64_t endmask, bool reverseIn, bool reverseOut)
uint64_t crc64(uint8_t *array, uint8_t length, uint64_t polynome, uint64_t startmask, uint64_t endmask, bool reverseIn, bool reverseOut)
{
uint64_t crc = startmask;
while (length--)
Expand All @@ -185,7 +184,5 @@ uint64_t CRC64(uint8_t *array, uint8_t length, uint64_t polynome, uint64_t start
return crc;
}

///////////////////////////////////////////////////////////////


// -- END OF FILE --
96 changes: 96 additions & 0 deletions CRC16.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
//
// FILE: CRC16.cpp
// AUTHOR: Rob Tillaart
// PURPOSE: Arduino class for CRC16
// URL: https://github.com/RobTillaart/CRC


#include "CRC16.h"


CRC16::CRC16()
{
reset();
}


void CRC16::reset()
{
_polynome = CRC16_DEFAULT_POLYNOME;
_startMask = 0;
_endMask = 0;
_crc = 0;
_reverseIn = false;
_reverseOut = false;
_started = false;
_count = 0;
}


void CRC16::restart()
{
_started = true;
_crc = _startMask;
_count = 0;
}


void CRC16::add(uint8_t value)
{
_count++;
_update(value);
}


void CRC16::add(uint8_t * array, uint32_t length)
{
_count += length;
while (length--)
{
yield();
uint8_t data = *array++;
_update(data);
}
}


uint16_t CRC16::getCRC()
{
uint16_t rv = _crc;
if (_reverseOut) rv = _reverse(rv);
rv ^= _endMask;
return rv;
}


void CRC16::_update(uint8_t value)
{
if (!_started) restart();
if (_reverseIn) value = _reverse(value);
_crc ^= ((uint16_t)value) << 8;;
for (uint8_t i = 8; i; i--)
{
if (_crc & (1UL << 15))
{
_crc <<= 1;
_crc ^= _polynome;
}
else
{
_crc <<= 1;
}
}
}


uint16_t CRC16::_reverse(uint16_t in)
{
uint16_t x = in;
x = (((x & 0XAAAA) >> 1) | ((x & 0X5555) << 1));
x = (((x & 0xCCCC) >> 2) | ((x & 0X3333) << 2));
x = (((x & 0xF0F0) >> 4) | ((x & 0X0F0F) << 4));
x = (( x >> 8) | (x << 8));
return x;
}

// -- END OF FILE --
50 changes: 50 additions & 0 deletions CRC16.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
#pragma once
//
// FILE: CRC16.h
// AUTHOR: Rob Tillaart
// PURPOSE: Arduino class for CRC16
// URL: https://github.com/RobTillaart/CRC


#include "Arduino.h"

#define CRC16_DEFAULT_POLYNOME 0x1021


class CRC16
{
public:
CRC16();

// set parameters to default
void reset(); // set all to constructor defaults
void restart(); // reset crc with same parameters.

// set parameters
void setPolynome(uint16_t polynome) { _polynome = polynome; };
void setStartXOR(uint16_t start) { _startMask = start; };
void setEndXOR(uint16_t end) { _endMask = end; };
void setReverseIn(bool reverseIn) { _reverseIn = reverseIn; };
void setReverseOut(bool reverseOut) { _reverseOut = reverseOut; };

void add(uint8_t value);
void add(uint8_t * array, uint32_t length);

uint16_t getCRC(); // returns CRC
uint32_t count() { return _count; };

private:
uint16_t _reverse(uint16_t value);
void _update(uint8_t value);

uint16_t _polynome;
uint16_t _startMask;
uint16_t _endMask;
uint16_t _crc;
bool _reverseIn;
bool _reverseOut;
bool _started;
uint32_t _count;
};

// -- END OF FILE --
96 changes: 96 additions & 0 deletions CRC32.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
//
// FILE: CRC32.cpp
// AUTHOR: Rob Tillaart
// PURPOSE: Arduino class for CRC32;
// URL: https://github.com/RobTillaart/CRC


#include "CRC32.h"


CRC32::CRC32()
{
reset();
}


void CRC32::reset()
{
_polynome = CRC32_DEFAULT_POLYNOME;
_startMask = 0;
_endMask = 0;
_crc = 0;
_reverseIn = false;
_reverseOut = false;
_started = false;
_count = 0;
}


void CRC32::restart()
{
_started = true;
_crc = _startMask;
_count = 0;
}


void CRC32::add(uint8_t value)
{
_count++;
_update(value);
}


void CRC32::add(uint8_t * array, uint32_t length)
{
_count += length;
while (length--)
{
yield();
_update(*array++);
}
}


uint32_t CRC32::getCRC()
{
uint32_t rv = _crc;
if (_reverseOut) rv = _reverse(rv);
rv ^=_endMask;
return rv;
}


void CRC32::_update(uint8_t value)
{
if (!_started) restart();
if (_reverseIn) value = _reverse(value);
_crc ^= ((uint32_t)value) << 24;;
for (uint8_t i = 8; i; i--)
{
if (_crc & (1UL << 31))
{
_crc <<= 1;
_crc ^= _polynome;
}
else
{
_crc <<= 1;
}
}
}


uint32_t CRC32::_reverse(uint32_t in)
{
uint32_t x = in;
x = (((x & 0xAAAAAAAA) >> 1) | ((x & 0x55555555) << 1));
x = (((x & 0xCCCCCCCC) >> 2) | ((x & 0x33333333) << 2));
x = (((x & 0xF0F0F0F0) >> 4) | ((x & 0x0F0F0F0F) << 4));
x = (((x & 0xFF00FF00) >> 8) | ((x & 0x00FF00FF) << 8));
x = (x >> 16) | (x << 16);
return x;
}

// -- END OF FILE --
50 changes: 50 additions & 0 deletions CRC32.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
#pragma once
//
// FILE: CRC32.h
// AUTHOR: Rob Tillaart
// PURPOSE: Arduino class for CRC32
// URL: https://github.com/RobTillaart/CRC


#include "Arduino.h"

#define CRC32_DEFAULT_POLYNOME 0x04C11DB7


class CRC32
{
public:
CRC32();

// set parameters to default
void reset(); // set all to constructor defaults
void restart(); // reset crc with same parameters.

// set parameters
void setPolynome(uint32_t polynome) { _polynome = polynome; };
void setStartXOR(uint32_t start) { _startMask = start; };
void setEndXOR(uint32_t end) { _endMask = end; };
void setReverseIn(bool reverseIn) { _reverseIn = reverseIn; };
void setReverseOut(bool reverseOut) { _reverseOut = reverseOut; };

void add(uint8_t value);
void add(uint8_t * array, uint32_t length);

uint32_t getCRC(); // returns CRC
uint32_t count() { return _count; };

private:
uint32_t _reverse(uint32_t value);
void _update(uint8_t value);

uint32_t _polynome;
uint32_t _startMask;
uint32_t _endMask;
uint32_t _crc;
bool _reverseIn;
bool _reverseOut;
bool _started;
uint32_t _count;
};

// -- END OF FILE --
Loading

0 comments on commit 783d437

Please sign in to comment.