185 lines
4.5 KiB
C
185 lines
4.5 KiB
C
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <stdint.h>
|
|
#include <stdlib.h>
|
|
|
|
// PC speichert mit LITTLE ENDIAN
|
|
|
|
// Berechnen einer 8 Bit CRC-Pruefsumme
|
|
uint8_t calcCRC8(uint8_t* data, size_t size);
|
|
|
|
// Berechnen einer 16 Bit CRC-Pruefsumme
|
|
uint16_t calcCRC16(uint8_t* inBytes, size_t size);
|
|
|
|
// Berechnen einer 32 Bit CRC-Pruefsumme mit allen Parametern
|
|
uint32_t calcCRC32(
|
|
uint8_t* inBytes,
|
|
size_t size,
|
|
uint32_t polynomial,
|
|
uint32_t initialValue,
|
|
uint32_t finalXOR,
|
|
uint8_t inputReflected,
|
|
uint8_t outputReflected
|
|
);
|
|
|
|
// Berechnung der Pruefsummen fuer Testbench
|
|
void calc_axis_crc_tb();
|
|
|
|
int main()
|
|
{
|
|
// Testweise Pruefsumme berechnen und ausgeben
|
|
char msg[] = "Hello World!";
|
|
uint32_t crc = calcCRC32((uint8_t*) msg, strlen(msg), 0x814141ab, 0, 0, 0, 0);
|
|
printf("CRC32 of '%s': 0x%08x\n\n", msg, crc);
|
|
|
|
char msg2[] = "ABCDEFGHIJKL";
|
|
crc = calcCRC32((uint8_t*) msg2, strlen(msg2), 0x814141ab, 0, 0, 0, 0);
|
|
printf("CRC32 of '%s': 0x%08x\n\n", msg2, crc);
|
|
|
|
uint8_t data[128];
|
|
for (int i = 0; i < 128; i++) data[i] = 0;
|
|
for (uint32_t i = 0; i < 32; i++) {
|
|
data[4*i] = (uint8_t) i;
|
|
}
|
|
crc = calcCRC32((uint8_t*) data, 64, 0xF4ACFB13, 0xFFFFFFFF, 0xFFFFFFFF, 1, 1);
|
|
printf("CRC32: 0x%08x\n\n", crc);
|
|
crc = calcCRC32((uint8_t*) (data+64), 64, 0xF4ACFB13, 0xFFFFFFFF, 0xFFFFFFFF, 1, 1);
|
|
printf("CRC32: 0x%08x\n\n", crc);
|
|
|
|
calc_axis_crc_tb();
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
uint8_t calcCRC8(uint8_t* inBytes, size_t size)
|
|
{
|
|
const uint8_t polynomial = 0xD5;
|
|
uint8_t crc = 0x0; // initial value
|
|
|
|
for (size_t i = 0; i < size; i++) {
|
|
crc ^= inBytes[i];
|
|
|
|
for (int bit = 0; bit < 8; bit++) {
|
|
if ((crc & 0x80) != 0) {
|
|
crc = (uint8_t) ((crc << 1) ^ polynomial);
|
|
}
|
|
else {
|
|
crc = (uint8_t)(crc << 1);
|
|
|
|
}
|
|
}
|
|
}
|
|
return crc;
|
|
}
|
|
|
|
|
|
uint16_t calcCRC16(uint8_t* inBytes, size_t size)
|
|
{
|
|
const uint16_t polynomial = 0x1021;
|
|
uint16_t crc = 0;
|
|
|
|
for (size_t b = 0; b < size; b++) {
|
|
crc ^= (uint16_t) (inBytes[b] << 8);
|
|
|
|
for (int i = 0; i < 8; i++) {
|
|
if ((crc & 0x8000) != 0) {
|
|
crc = (uint16_t) (crc << 1) ^ polynomial;
|
|
} else {
|
|
crc = (uint16_t)(crc << 1);
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
return crc;
|
|
}
|
|
|
|
|
|
uint32_t calcCRC32(
|
|
uint8_t* inBytes,
|
|
size_t size,
|
|
uint32_t polynomial,
|
|
uint32_t initialValue,
|
|
uint32_t finalXOR,
|
|
uint8_t inputReflected,
|
|
uint8_t outputReflected
|
|
) {
|
|
uint32_t crc = initialValue;
|
|
uint8_t byte;
|
|
|
|
for (size_t i = 0; i < size; i++) {
|
|
byte = inBytes[i];
|
|
|
|
if (inputReflected != 0) {
|
|
uint8_t reflected = 0;
|
|
|
|
for (int b = 0; b < 8; b++) {
|
|
if ((byte & (1<<b)) != 0) {
|
|
reflected |= (uint8_t) (1<<(7-b));
|
|
}
|
|
}
|
|
byte = reflected;
|
|
}
|
|
|
|
crc ^= (uint32_t) (byte << 24);
|
|
|
|
for (int bit = 0; bit < 8; bit++) {
|
|
if ((crc & (uint32_t)(1<<31)) != 0) {
|
|
crc = (uint32_t) (crc << 1) ^ polynomial;
|
|
} else {
|
|
crc <<= 1;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (outputReflected != 0) {
|
|
uint32_t reflected = 0;
|
|
|
|
for (int i = 0; i < 32; i++) {
|
|
if ((crc & (uint32_t) (1<<i)) != 0) {
|
|
reflected |= (uint32_t) (1<<(31-i));
|
|
}
|
|
}
|
|
crc = reflected;
|
|
}
|
|
|
|
return crc ^ finalXOR;
|
|
}
|
|
|
|
|
|
void calc_axis_crc_tb()
|
|
{
|
|
char test_data[] = "Hello World!";
|
|
|
|
uint32_t testPolynomials[3] = {
|
|
0x4C11DB7,
|
|
0x814141AB,
|
|
0xF4ACFB13,
|
|
};
|
|
|
|
uint32_t initalValues[2] = {
|
|
0x0,
|
|
0xFFFFFFFF,
|
|
};
|
|
|
|
uint32_t finalXORs[2] = {
|
|
0x0,
|
|
0xFFFFFFFF,
|
|
};
|
|
|
|
for (int p = 0; p < 3; p++) {
|
|
for (int iV = 0; iV < 2; iV++) {
|
|
for (int f = 0; f < 2; f++) {
|
|
for (uint8_t r = 0; r < 2; r++) {
|
|
uint32_t checksum;
|
|
checksum = calcCRC32((uint8_t*) test_data, 12, testPolynomials[p], initalValues[iV], finalXORs[f], r, r);
|
|
//printf("Polynom %d, iV %d: x\"%08x\"\n", p, iV, checksum);
|
|
printf("x\"%08x\", ", checksum);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
printf("\n");
|
|
}
|