Skip to content

Commit

Permalink
Generalized CRC table generation
Browse files Browse the repository at this point in the history
  • Loading branch information
Ultrawipf committed Jan 16, 2023
1 parent 3ab8a79 commit 8289bac
Show file tree
Hide file tree
Showing 6 changed files with 103 additions and 44 deletions.
61 changes: 61 additions & 0 deletions Firmware/FFBoard/Inc/CRC.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
/*
* CRC.h
*
* Created on: 10.01.2023
* Author: Yannick
*/

#ifndef SRC_CRC_H_
#define SRC_CRC_H_
#include "main.h"
#include "array"


template<typename T>
T reverseBits(T value)
{
static_assert(sizeof(T) == 1 || sizeof(T) == 2 || sizeof(T) == 4, "Type must be 1,2 or 4 bytes long");
value = ((value & 0xAAAAAAAA) >> 1) | ((value & 0x55555555) << 1);
value = ((value & 0xCCCCCCCC) >> 2) | ((value & 0x33333333) << 2);

if(sizeof(T)>1)
value = ((value & 0xF0F0F0F0) >> 4) | ((value & 0x0F0F0F0F) << 4);

if(sizeof(T)>3)
value = ((value & 0xFF00FF00) >> 8) | ((value & 0x00FF00FF) << 8);

value = (value >> (4*sizeof(T))) | (value << (4*sizeof(T)));

return value; // & (1 << (sizeof(T)*8)) - 1
}

/**
* Helper function to create a CRC table of different sizes and types
*/
template<typename T,size_t LEN>
void makeCrcTable(std::array<T,LEN> &table, const T crcpoly,const uint8_t bits,const bool refin = false,const bool refout = false)
{
T mask = 1 << (bits-1);
for (uint16_t byte = 0; byte < LEN; ++byte)
{
T crc = (refin ? reverseBits<T>(byte) : byte);
for (uint8_t bit = 0; bit < bits; ++bit)
{
if (crc & mask)
{
crc = (crc << 1) ^ crcpoly;
}
else
{
crc <<= 1;
}
}
table[byte] = (refout ? reverseBits<T>(crc) : crc);
}
}


uint8_t calculateCrc8(std::array<uint8_t,256> &crctable,uint8_t* buf,uint16_t len,uint8_t crc=0);
uint16_t calculateCrc16_8(std::array<uint16_t,256> &crctable,uint8_t* buf,uint16_t len,uint16_t crc=0);

#endif /* SRC_CRC_H_ */
28 changes: 28 additions & 0 deletions Firmware/FFBoard/Src/CRC.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/*
* CRC.cpp
*
* Created on: Jan 10, 2023
* Author: Yannick
*/

#include "CRC.h"

/**
* Calculates a crc8 checksum
*/
uint8_t calculateCrc8(std::array<uint8_t,256> &crctable,uint8_t* buf,uint16_t len,uint8_t crc){
for(uint16_t i = 0;i<len;i++){
crc = crctable[buf[i] ^ crc];
}
return crc;
}

/**
* Calculates a 16b checksum using a crc16 table on a 8b buffer
*/
uint16_t calculateCrc16_8(std::array<uint16_t,256> &crctable,uint8_t* buf,uint16_t len,uint16_t crc){
for(uint16_t i = 0;i<len;i++){
crc = crctable[(((crc >> 8) ^ buf[i]) & 0xFF)] ^ (crc << 8);
}
return crc;
}
3 changes: 2 additions & 1 deletion Firmware/FFBoard/UserExtensions/Inc/EncoderBissC.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include <math.h>
#include "PersistentStorage.h"
#include "semaphore.hpp"
#include "array"

class EncoderBissC: public Encoder, public SPIDevice , public CommandHandler,cpp_freertos::Thread,public PersistentStorage {
public:
Expand Down Expand Up @@ -70,7 +71,7 @@ class EncoderBissC: public Encoder, public SPIDevice , public CommandHandler,cpp


const uint8_t POLY = 0x43;
static uint8_t tableCRC6n[64];
static std::array<uint8_t,64> tableCRC6n;
int32_t numErrors = 0;
static bool inUse;
cpp_freertos::BinarySemaphore requestNewDataSem = cpp_freertos::BinarySemaphore(false);
Expand Down
3 changes: 1 addition & 2 deletions Firmware/FFBoard/UserExtensions/Inc/VescCAN.h
Original file line number Diff line number Diff line change
Expand Up @@ -160,9 +160,8 @@ class VescCAN: public MotorDriver,
int16_t buffer_get_int16(const uint8_t *buffer, int32_t *index);
float buffer_get_float16(const uint8_t *buffer, float scale, int32_t *index);
float buffer_get_float32(const uint8_t *buffer, float scale, int32_t *index);
unsigned short crc16(unsigned char *buf, unsigned int len);

static uint16_t crc16_tab[256];
static std::array<uint16_t,256> crc16_tab;
static const uint16_t crcpoly = 0x1021;
static bool crcTableInitialized;

Expand Down
20 changes: 6 additions & 14 deletions Firmware/FFBoard/UserExtensions/Src/EncoderBissC.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@
*/

#include "EncoderBissC.h"
#include "CRC.h"
#include "array"

bool EncoderBissC::inUse = false;
ClassIdentifier EncoderBissC::info = {
.name = "BISS-C" ,
Expand All @@ -18,7 +21,7 @@ const ClassIdentifier EncoderBissC::getInfo(){
return info;
}

uint8_t EncoderBissC::tableCRC6n[64] __attribute__((section (".ccmram")));
std::array<uint8_t,64> EncoderBissC::tableCRC6n __attribute__((section (".ccmram")));

EncoderBissC::EncoderBissC() :
SPIDevice(ENCODER_SPI_PORT, ENCODER_SPI_PORT.getCsPins()[0]),
Expand All @@ -27,20 +30,9 @@ EncoderBissC::EncoderBissC() :
EncoderBissC::inUse = true;


//Init CRC table
for(int i = 0; i < 64; i++){
int crc = i;
//Init CRC-6 table
makeCrcTable(tableCRC6n,POLY,6);

for (int j = 0; j < 6; j++){
if (crc & 0x20){
crc <<= 1;
crc ^= POLY;
} else {
crc <<= 1;
}
}
tableCRC6n[i] = crc;
}
restoreFlash();
this->spiPort.takeExclusive(true);
configSPI();
Expand Down
32 changes: 5 additions & 27 deletions Firmware/FFBoard/UserExtensions/Src/VescCAN.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,10 @@
#ifdef VESC
#include <VescCAN.h>
#include "ClassIDs.h"
#include "CRC.h"

bool VescCAN::crcTableInitialized = false;
uint16_t VescCAN::crc16_tab[256] __attribute__((section (".ccmram"))); // Generate in ram to save some flash (512B)
std::array<uint16_t,256> VescCAN::crc16_tab __attribute__((section (".ccmram"))); // Generate in ram to save some flash (512B)

// ***** static initializer for the VESC_1 instance (extend VESC_CAN) *****

Expand Down Expand Up @@ -53,22 +54,7 @@ VescCAN::VescCAN(uint8_t address) :
VESC_THREAD_PRIO) {

if(!crcTableInitialized){ // Generate a CRC16 table the first time a vesc instance is created
for (uint16_t byte = 0; byte < 256; byte++)
{
uint16_t crc = byte;
for (uint8_t bit = 0; bit < 16; bit++)
{
if (crc & 0x8000)
{
crc = (crc << 1) ^ crcpoly;
}
else
{
crc <<= 1;
}
}
crc16_tab[byte] = crc;
}
makeCrcTable(crc16_tab, crcpoly,16);
crcTableInitialized = true;
}

Expand Down Expand Up @@ -643,7 +629,8 @@ void VescCAN::canRxPendCallback(CAN_HandleTypeDef *hcan, uint8_t *rxBuf,
uint8_t crc_high = rxBuf[index++];
uint8_t crc_low = rxBuf[index++];

if (crc16(buffer_rx, rxbuf_length)
if(calculateCrc16_8(crc16_tab,buffer_rx,rxbuf_length)
//if (crc16(buffer_rx, rxbuf_length)
== ((uint8_t) crc_high << 8 | (uint8_t) crc_low)) {

this->decode_buffer(buffer_rx, rxbuf_length);
Expand Down Expand Up @@ -733,13 +720,4 @@ float VescCAN::buffer_get_float16(const uint8_t *buffer, float scale,
return (float) buffer_get_int16(buffer, index) / scale;
}

unsigned short VescCAN::crc16(unsigned char *buf, unsigned int len) {
unsigned int i;
unsigned short cksum = 0;
for (i = 0; i < len; i++) {
cksum = crc16_tab[(((cksum >> 8) ^ *buf++) & 0xFF)] ^ (cksum << 8);
}
return cksum;
}

#endif

0 comments on commit 8289bac

Please sign in to comment.