Page 1 of 2
which algorithm to check STM32F4 CRC32
Posted: Sun Oct 27, 2013 12:03 pm
by jarekl
It seems I can't find the right algorithm to check the CRC-32 I get from the STM32F4xx.
The use of the CRC register seems simple enough but I can't reproduce the result on my linux computer sending the data.
I'm sending 1280 bytes over USB to the STM32F4xx-Discover and if I do a simple sum-checksum I get the correct result (the board sends it back to the PC over USB)
so there is reason to believe the data is correct at least for debugging.
Re: which algorithm to check STM32F4 CRC32
Posted: Sun Oct 27, 2013 2:11 pm
by Giovanni
Are the initial CRC value and polynomial the same?
Giovanni
Re: which algorithm to check STM32F4 CRC32
Posted: Sun Oct 27, 2013 4:20 pm
by efuentes
I've run into this issue before... It turns out they calculate the CRC a little differently than you would expect.
In order to get correct crc, you have to:
- reverse the bits before you write them to the data register
- reverse the bits and XOR them with 0xFFFFFFFF after you read from the data register to get the correct checksum.
http://www.st.com/st-web-ui/static/active/en/resource/technical/document/application_note/DM00068118.pdfI don't think some of the register fields mentioned in the app not exist, but it does explain what you need to do in order to get the right checksum.
Re: which algorithm to check STM32F4 CRC32
Posted: Sun Oct 27, 2013 7:28 pm
by jarekl
Giovanni wrote:Are the initial CRC value and polynomial the same?
Giovanni
I start by enabling the clock and setting the CR-register bit and then writing to the (DR) register as the do in the STM32F4xx-library examples (or was it the code it self).
There seems to be some endianess issue with the polynomial (or something) so there are two takes on the same poly. Tried both but only the (Other)
polynomial (not the one given in the STM32F4xx docs beginning with 0x4...) gives reasonable results. Sorry for being this fuzzy.
Re: which algorithm to check STM32F4 CRC32
Posted: Sun Oct 27, 2013 8:18 pm
by jarekl
efuentes wrote:I've run into this issue before... It turns out they calculate the CRC a little differently than you would expect.
In order to get correct crc, you have to:
- reverse the bits before you write them to the data register
- reverse the bits and XOR them with 0xFFFFFFFF after you read from the data register to get the correct checksum.
http://www.st.com/st-web-ui/static/active/en/resource/technical/document/application_note/DM00068118.pdfI don't think some of the register fields mentioned in the app not exist, but it does explain what you need to do in order to get the right checksum.
I follow exactly the steps on page 8 of that document (except steps 2,3,4 which don't apply to F4).
I did try your suggestion. Didn't work for me (yet

. More trial on horror to follow. Thanks anyway. I hate not to have anything to try.
Re: which algorithm to check STM32F4 CRC32
Posted: Sun Oct 27, 2013 10:28 pm
by efuentes
Can you post some code of what you've tried?
Re: which algorithm to check STM32F4 CRC32
Posted: Sun Oct 27, 2013 11:40 pm
by jarekl
efuentes wrote:Can you post some code of what you've tried?
Sure. Here goes,
Code: Select all
/*
* STM32 header files
*/
#include <stm32_rcc.h>
#include <stm32f4xx.h>
uint32_t
crc32(uint32_t *p, int len)
{
int i;
CRC_TypeDef *CReg;
CReg = (CRC_TypeDef *)CRC_BASE;
CReg->CR = (uint8_t)1;
for ( i = 0; i < len; i++)
CReg->DR = *(p+i);
return (CReg->DR);
}
Not longer sure which of the header contains the typedefs and #defines.
I've tried variations with
Code: Select all
for ( i = 0; i < len; i++)
CReg->DR = ~(*(p+i));
and
and also
The crc32 that is use on the host returns the same result as the crc32(1) command, but to be honest, I'm not sure that it uses the same poly which is why I ask. But I'm getting the impression that the poly implemented by the stm32f4xx is very common.
Re: which algorithm to check STM32F4 CRC32
Posted: Mon Oct 28, 2013 12:25 am
by efuentes
I'm sorry, I wasn't very clear. When I meant reverse the bits, I meant swap the bits such that the least significant bit is now the most significant bit, the lsb + 1 is now msb - 1 etc...
I've defined these macro in my crc header file
Code: Select all
#define crcReset() (CRC->DR = 1)
#define crcRead() (__REV(CRC->DR) ^ 0xFFFFFFFF)
#define crcWrite(x) {CRC->DR = __REV(x)}
__REV is a macro defined in the CMSIS (core_cminstr.h I think...). It is a wrapper around the rbit instruction.
Whenever you would write the the CRC->DR, call crcWrite. If you want to get the current CRC, call crc read.
Hopefully this works out for you.
Erick
Re: which algorithm to check STM32F4 CRC32
Posted: Mon Oct 28, 2013 6:58 am
by efuentes
I've defined these macro in my crc header file
Code: Select all
#define crcReset() (CRC->DR = 1)
#define crcRead() (__REV(CRC->DR) ^ 0xFFFFFFFF)
#define crcWrite(x) {CRC->DR = __REV(x)}
__REV is a macro defined in the CMSIS (core_cminstr.h I think...). It is a wrapper around the rbit instruction.
it makes no sense for the __REV to be a wrapper around rbit... It should be __RBIT(x)
Re: which algorithm to check STM32F4 CRC32
Posted: Mon Oct 28, 2013 11:31 am
by jarekl
efuentes wrote:I've defined these macro in my crc header file
Code: Select all
#define crcReset() (CRC->DR = 1)
#define crcRead() (__REV(CRC->DR) ^ 0xFFFFFFFF)
#define crcWrite(x) {CRC->DR = __REV(x)}
__REV is a macro defined in the CMSIS (core_cminstr.h I think...). It is a wrapper around the rbit instruction.
it makes no sense for the __REV to be a wrapper around rbit... It should be __RBIT(x)
Here's what the code looks like right now,
Code: Select all
#define crcReset() (CRC->CR = 1)
#define crcRead() (__REV(CRC->DR) ^ 0xFFFFFFFF)
#define crcWrite(x) (CRC->DR = __REV(x))
uint32_t
crc32(uint32_t *p, int len)
{
int i;
crcReset();
for ( i = 0; i < len; i++)
crcWrite(p[i]);
return crcRead();
}
I had to change in crcReset(), CRC->DR to CRC->CR (typo i presume).
Code: Select all
#define crcWrite(x) {CRC->DR = __REV(x)}
Does not compile. Either I had to add ";" after REV(x) or remove the curly braces (same result).
Using __RBIT(x) i get
and __REV(x) gives,
The second number is the expected result. I'm computing the crc32 for an array of "1", 1280 elements long. This is the number that (also) comes out of the linux command crc32(1).
Maybe this is somehow related to my build environment. This is the result of "make clean; make"
Code: Select all
$ make
Compiler Options
arm-none-eabi-gcc -c -mcpu=cortex-m4 -O2 -ggdb -fomit-frame-pointer -falign-functions=16 -mfloat-abi=softfp -mfpu=fpv4-sp-d16 -fsingle-precision-constant -ffunction-sections -fdata-sections -fno-common -Wall -Wextra -Wstrict-prototypes -Wa,-alms=build/lst/ -DCORTEX_USE_FPU=TRUE -DTHUMB_PRESENT -mno-thumb-interwork -DTHUMB_NO_INTERWORKING -MD -MP -MF .dep/build.d -I. -I../../hsarm/ChibiOS-RT/os/ports/common/ARMCMx/CMSIS/include -I../../hsarm/ChibiOS-RT/os/ports/common/ARMCMx -I../../hsarm/ChibiOS-RT/os/ports/GCC/ARMCMx -I../../hsarm/ChibiOS-RT/os/ports/GCC/ARMCMx/STM32F4xx -I../../hsarm/ChibiOS-RT/os/kernel/include -I../../hsarm/ChibiOS-RT/os/hal/include -I../../hsarm/ChibiOS-RT/os/hal/platforms/STM32F4xx -I../../hsarm/ChibiOS-RT/os/hal/platforms/STM32 -I../../hsarm/ChibiOS-RT/os/hal/platforms/STM32/GPIOv2 -I../../hsarm/ChibiOS-RT/os/hal/platforms/STM32/I2Cv1 -I../../hsarm/ChibiOS-RT/os/hal/platforms/STM32/OTGv1 -I../../hsarm/ChibiOS-RT/os/hal/platforms/STM32/RTCv2 -I../../hsarm/ChibiOS-RT/os/hal/platforms/STM32/SPIv1 -I../../hsarm/ChibiOS-RT/os/hal/platforms/STM32/TIMv1 -I../../hsarm/ChibiOS-RT/os/hal/platforms/STM32/USARTv1 -I../../hsarm/ChibiOS-RT/boards/ST_STM32F4_DISCOVERY -I../../hsarm/ChibiOS-RT/os/various main.c -o main.o
Anyhow, thank's for all your help. It is really appreciated. I'm total newbie with ChibiOS and ARM (but it's quite a rewarding learning experience).