cancel
Showing results for 
Search instead for 
Did you mean: 

Trouble using STM32F4's CRC on 8 bit array

infoinfo991
Associate III
Posted on January 12, 2014 at 01:29

I am using a STM32F4's internal CRC peripheral

My test sample data works against the code available at http://www.opensource.apple.com/source/xnu/xnu-1456.1.26/bsd/libkern/crc32.c

Sample data is { 0xA1, 0x11, 0xC0, 0x00, 0x83, 0x81, 0x7E, 0x7E, 0x08, 0x00, 0x3C, 0x00, 0x00, 0x83, 0xA2, 0x07, 0xF1, 0xFF, 0xF9, 0xFF, 0x04, 0x00, 0x21, 0x03, 0x17, 0x1F, 0x29, 0xF9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00 } Length is 75

When I pass it into the function at http://www.opensource.apple.com/source/xnu/xnu-1456.1.26/bsd/libkern/crc32.c with an initial CRC of 0, it produces 0x0B5D0A7D, which is correct because it matches what my target black box device produces.

The STM32F4's CRC does not produce the same result at all, I have tried several techniques

First problem, the CRC initial value is 0xFFFFFFFF and I can't change it according to appnote 4187.

Second problem, the DR register is 32 bits, but my data length is 75.

For the first problem, I tried to set the DR to 0 by feeding it 0xFFFFFFFF first, it does make DR 0 but my CRC performed on my sample afterwards still does not match

For the second problem, I have tried several things:

I tried passing in 8 bit values. I tried both little and big endian.

I even tried use the hardware CRC for the first 18 uints and then passing the last 3 bytes into a the C code I mentioned above

None of these techniques worked.

How can I solve these two problems in a way that I can generate a CRC with my sample that matches my target?
4 REPLIES 4
Posted on January 12, 2014 at 01:36

Yes, the hw CRC is designed for 4-byte lengths, and backward for the little endian.

See thread on

https://my.st.com/public/STe2ecommunities/mcu/Lists/cortex_mx_stm32/flat.aspx?RootFolder=/public/STe2ecommunities/mcu/Lists/cortex_mx_stm32/CRC%20computation&FolderCTID=0x01200200770978C69A1141439FE559EB459D7580009C4E14902C3CDE46A77F0FFD06506F5B&currentviews=1617

computation, and the answer I provided for your prior thread.

[DEAD LINK /public/STe2ecommunities/mcu/Lists/cortex_mx_stm32/Flat.aspx?RootFolder=/public/STe2ecommunities/mcu/Lists/cortex_mx_stm32/need%20to%20change%20CRC%20peripheral%27s%20polynomial&FolderCTID=0x01200200770978C69A1141439FE559EB459D7580009C4E14902C3CDE46A77F0FFD06506F5B&TopicsView=https://my.st.com/public/STe2ecommunities/mcu/Lists/cortex_mx_stm32/AllItems.aspx?Paged%3DTRUE%26p_StickyPost%3D%26p_DiscussionLastUpdated%3D20140109%252011%253a07%253a30%26p_ID%3D36686%26View%3D%257bF47A9ED8%252dE726%252d42BE%252dACED%252d732F13B66581%257d%26FolderCTID%3D0x012001%26PageFirstRow%3D41&currentviews=61]https://my.st.com/public/STe2ecommunities/mcu/Lists/cortex_mx_stm32/Flat.aspx?RootFolder=%2fpublic%2fSTe2ecommunities%2fmcu%2fLists%2fcortex%5fmx%5fstm32%2fneed%20to%20change%20CRC%20peripheral%27s%20polynomial&FolderCTID=0x01200200770978C69A1141439FE559EB459D7580009C4E14902C3CDE46A77F0FFD06506F5B&TopicsView=https%3A%2F%2Fmy%2Est%2Ecom%2Fpublic%2FSTe2ecommunities%2Fmcu%2FLists%2Fcortex%5Fmx%5Fstm32%2FAllItems%2Easpx%3FPaged%3DTRUE%26p%5FStickyPost%3D%26p%5FDiscussionLastUpdated%3D20140109%252011%253a07%253a30%26p%5FID%3D36686%26View%3D%257bF47A9ED8%252dE726%252d42BE%252dACED%252d732F13B66581%257d%26FolderCTID%3D0x012001%26PageFirstRow%3D41¤tviews=61

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Posted on January 12, 2014 at 01:45

The reset value you want is 0xFFFFFFFF, your main issues are you need to bit reverse the data you apply to the DR, as the CRC byte/bit order is BACKWARD compared to the sense you need. You have to manually handle the 0-3 remainder bytes as the hardware only does 32-bit (4 Byte), and finally you need to INVERT the CRC to match this interpretation of the CRC32 algorithm. Many use cases don't, it only really serves to address an all ZERO data issue, which can be avoided with headers/preamble bytes which often exist in physical protocols.

If you wanted to reset the CRC->DR to ZERO, the quickest way is to feed it back on itself. ie CRC->DR = CRC->DR; // Clear CRC
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
infoinfo991
Associate III
Posted on January 12, 2014 at 03:07

sweet thanks I got it working when I saw your rbit example

the fix was to do the first 72 bytes using hardware, but pass them into rbit before feeding them into DR

then after the 72 bytes, take DR, rbit it, and then invert it all, then pass it into the soft function, and the result finally matched

my own implementation shown at 

https://github.com/frank26080115/UsbXlater/blob/master/UsbXlater_FW/crc.c

Posted on January 12, 2014 at 03:20

Honestly I think the NOPs are extraneous, they where left over from a conversion from a posters example where I changed only the code that was giving them trouble. The code sought to demonstrate the mechanics involved, I've done this all in assembler.

The 1KB CRC table is a bit expensive for my taste, the 4-bit nibble mode approach is pretty efficient.

Not sure I understand the XOR ZERO stuff in your code.
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..