Upd. See the end of post for working code
I'm already mad with this. How can I make checksum from CRC unit on stm32f103 match with software implementation? Stm has polynom 0x04C11DB7
and reset value 0xFFFFFFFF
. So I've tried to calculate it in python.
Code for stm:
uint32_t crc32_hard_block(uint32_t *buf, uint32_t len)
{
CRC_ResetDR();
uint32_t crc = CRC_CalcBlockCRC(buf, len);
return crc;
}
uint32_t buf[4] = {50, 10, 243, 147};
uint32_t crc_hard_block = crc32_hard_block(buf, 4);
Code for python:
custom_crc_table = {}
def int_to_bytes(i):
return [(i >> 24) & 0xFF, (i >> 16) & 0xFF, (i >> 8) & 0xFF, i & 0xFF]
def reverse_int(i, w):
b = '{:0{width}b}'.format(i, width=w)
return int(b[::-1], 2)
def generate_crc32_table(_poly):
global custom_crc_table
for i in range(256):
c = i << 24
for j in range(8):
c = (c << 1) ^ _poly if (c & 0x80000000) else c << 1
custom_crc_table[i] = c
def custom_crc32(buf, _poly):
global custom_crc_table
crc = 0xFFFFFFFF
for integer in buf:
b = int_to_bytes(integer)
for byte in b:
top = (crc >> 24) & 0xFF
crc = (crc << 8) | byte
crc = crc ^ custom_crc_table[top]
return crc, reverse_int(crc, 32)
poly = 0x04C11DB7
buf = [50, 10, 243, 147]
generate_crc32_table(poly)
custom_crc, rev = custom_crc32(buf, poly)
print("Custom rev src " + hex(rev))
print("Custom crc " + hex(custom_crc))
Testing on array [50, 10, 243, 147] gives me output:
In python:
Custom rev src 0x344a9514f010200020100010100020301000203
Custom crc 0x3010002030100020200020100010203ca2a548b #reversed
It's definetly something wrong with my crc.
In stm:
0x491b3bf3
UPDATE
Here is working code for software crc as on stm32f103 and code for stm32f103.
Python:
def generate_crc32_table(_poly):
global custom_crc_table
for i in range(256):
c = i << 24
for j in range(8):
c = (c << 1) ^ _poly if (c & 0x80000000) else c << 1
custom_crc_table[i] = c & 0xffffffff
def crc32_stm(bytes_arr):
length = len(bytes_arr)
crc = 0xffffffff
k = 0
while length >= 4:
v = ((bytes_arr[k] << 24) & 0xFF000000) | ((bytes_arr[k+1] << 16) & 0xFF0000) | \
((bytes_arr[k+2] << 8) & 0xFF00) | (bytes_arr[k+3] & 0xFF)
crc = ((crc << 8) & 0xffffffff) ^ custom_crc_table[0xFF & ((crc >> 24) ^ v)]
crc = ((crc << 8) & 0xffffffff) ^ custom_crc_table[0xFF & ((crc >> 24) ^ (v >> 8))]
crc = ((crc << 8) & 0xffffffff) ^ custom_crc_table[0xFF & ((crc >> 24) ^ (v >> 16))]
crc = ((crc << 8) & 0xffffffff) ^ custom_crc_table[0xFF & ((crc >> 24) ^ (v >> 24))]
k += 4
length -= 4
if length > 0:
v = 0
for i in range(length):
v |= (bytes_arr[k+i] << 24-i*8)
if length == 1:
v &= 0xFF000000
elif length == 2:
v &= 0xFFFF0000
elif length == 3:
v &= 0xFFFFFF00
crc = (( crc << 8 ) & 0xffffffff) ^ custom_crc_table[0xFF & ( (crc >> 24) ^ (v ) )];
crc = (( crc << 8 ) & 0xffffffff) ^ custom_crc_table[0xFF & ( (crc >> 24) ^ (v >> 8) )];
crc = (( crc << 8 ) & 0xffffffff) ^ custom_crc_table[0xFF & ( (crc >> 24) ^ (v >> 16) )];
crc = (( crc << 8 ) & 0xffffffff) ^ custom_crc_table[0xFF & ( (crc >> 24) ^ (v >> 24) )];
return crc
poly = 0x04C11DB7
buf = [50, 10, 243, 147]
generate_crc32_table(poly)
crc_stm = crc32_stm(bytearray(buf))
Stm32f103:
#include <stm32f10x_crc.h>
uint32_t crc32_native(char *bfr, int len, int clear) {
uint32_t crc;
int l = len / 4;
uint32_t *p = (uint32_t*)bfr;
uint32_t x = p[l];
if(clear)
{
CRC_ResetDR();
}
while(l--)
{
crc = CRC_CalcCRC(*p++);
}
switch(len & 3)
{
case 1: crc = CRC_CalcCRC(x & 0x000000FF); break;
case 2: crc = CRC_CalcCRC(x & 0x0000FFFF); break;
case 3: crc = CRC_CalcCRC(x & 0x00FFFFFF); break;
}
return crc;
}
custom_crc_table = {}
def int_to_bytes(i):
return [(i >> 24) & 0xFF, (i >> 16) & 0xFF, (i >> 8) & 0xFF, i & 0xFF]
def generate_crc32_table(_poly):
global custom_crc_table
for i in range(256):
c = i << 24
for j in range(8):
c = (c << 1) ^ _poly if (c & 0x80000000) else c << 1
custom_crc_table[i] = c & 0xffffffff
def custom_crc32(buf):
global custom_crc_table
crc = 0xffffffff
for integer in buf:
b = int_to_bytes(integer)
for byte in b:
crc = ((crc << 8) & 0xffffffff) ^ custom_crc_table[(crc >> 24) ^ byte]
return crc
poly = 0x04C11DB7
buf = [50, 10, 243, 147]
generate_crc32_table(poly)
custom_crc = custom_crc32(buf)
print("Custom crc " + hex(custom_crc))