cancel
Showing results for 
Search instead for 
Did you mean: 

Byte-wise only CRC for STM32L486?

dlane
Associate II
Posted on March 14, 2016 at 18:01

I'm using the CRC unit on the STM32L486. In the reference manual it states that:

''CRC computation is done on the whole 32-bit data

word or byte by byte depending on the format of the data being written.''

However, later in the documentation it states that:

''The data size can be dynamically adjusted to minimize the number of write accesses for a given number of bytes. For instance, a CRC for 5 bytes can be computed with a word write followed by a byte write.''

From my use of the CRC unit, it seems that I can only achieve the latter statement, which does a byte by byte calculation. Even if I write a whole word to the Data Register (DR), it will process the word a byte at a time.

From the first statement, it appears that the CRC should also do word-wise calculations, but I have not been able to accomplish that. 

Can I do word-wise calculations with this CRC or only byte-wise?

Any guidance or clarification on the capabilities of this MCU's CRC peripheral would be greatly appreciated!

#crc #stm32 #stm32l4 #bit-cloudy
13 REPLIES 13
Posted on March 14, 2016 at 18:32

You need to cast the access to the CRC->DR register for the size of the data you are shovelling in. There is a peripheral level configuration for the size and polynomial.ie

*((volatile uint8_t *)&CRC->DR) = byte;

*((volatile uint16_t *)&CRC->DR) = halfword;

*((volatile uint32_t *)&CRC->DR) = word; // normally not casted, here for illustrationA 32-bit write to an 8-bit CRC will cause 4 byte wide iterations

https://community.st.com/0D50X00009XkfPISAZ

 

https://community.st.com/0D50X00009XkfPESAZ

 

Edit: Fixed DEAD LINKs, original post from Mar 14 2016

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
dlane
Associate II
Posted on March 14, 2016 at 19:01

I should be doing the correct casting, especially since I am using the STM32Cube_L4 LL Drivers. Here is an example of what I am getting, perhaps you can point out something I am missing:

Configure the CRC:

Polynomial coeff: 0x04C11DB7

Polynomial size: 0x00 (32 bit)

Input data reverse: 0x00 (none)

Output data reverse: 0x00 (none)

Initial value: 0xFFFFFFFF

I send a single 32-bit word to be calculated:

LL_CRC_FeedData32(&CRC, 0x00001021);

The CRC result is 0x4BB7ED3F

If I use an online CRC calculator with the same settings my result is: 

0xCBA38BD8

Using that same online calculator, if instead of inputting the single 32-bit word (0x00001021) I perform the calculation byte by byte, I get my first result of 0x4BB7ED3F.

Am I missing something here? I was expecting the LL_CRC_FeedData32(x) call, which simply is a an inline for CRC->DR = x, to match what I get from the CRC calculator.

Posted on March 14, 2016 at 20:40

Am I missing something here?

Endian mode vs shift direction?

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
dlane
Associate II
Posted on March 14, 2016 at 21:39

Endian mode vs shift direction?

 

Since I'm using the MCU's hardware peripheral and can't adjust those parameters, I assume you are referring to the online calculator.

That being the case, I don't think either of those are the issue given that I can use the online calculator to come to the result as the MCU's hardware peripheral. However, like I stated earlier, the only way I can get the online calculator to come to the same result as the CRC peripheral is if I add the values byte by byte to the calculator.

So, using the 0x00001021 example I gave earlier, I would set the calculator's:

initial value -> 0xFFFFFFFF

input value -> 0x00

crc result ->

0x4E08BFB4

Then I would update the initial value to the result of the previous calculation:

initial value -> 

0x4E08BFB4

input value -> 0x00

crc result ->

0x00B7647D

initial value -> 

0x00B7647D

input value -> 0x10

crc result ->

0xFB75A670

initial value -> 

0xFB75A670

input value -> 0x21

crc result ->

0x4BB7ED3F

 

 

This last result is the same result I get when I send the 0x00001021 word to the CRC register. So, it does appear that the CRC module is calculating the CRC a byte at a time even though I send a whole word. That also indicates that endianness and shift direction are not likely issues since I eventually got the same result.

Additionally, the shift direction should be correct because if I calculate the CRC with just an 8-bit input, the result is the same for both the hardware CRC peripheral and the online calculator. 

Do you have any idea why that would be happening?

Posted on March 14, 2016 at 22:08

Do you have any idea why that would be happening?

Can you cite the specific calculator you are using, and how it knows if you are passing bytes or words.

Not sure where it is pulling 0xCBA38BD8 from

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
dlane
Associate II
Posted on March 14, 2016 at 22:23

Sure, here it is: http://www.sunshine2k.de/coding/javascript/crc/crc_js.html

The settings I am using are:

CRC Width: CRC-32

CRC Parametrization: custom

CRC Detailed Parameters: input and result reflected both UNchecked

polynomial: 0x04C11DB7

initial value: 0xFFFFFFFF

final xor value: 0x0

CRC Input Data: set to bytes

Then in the input data box I add the input value in hex. I specify a word or a byte by the input value, eg. Word: 0x00001021. Byte: 0x21

Posted on March 14, 2016 at 23:05

I don't think 0x00001021 is ''Bytes'', you'd need to understand how the JavaScript handles that. This is the inherent problem relying on these calculators.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
dlane
Associate II
Posted on March 14, 2016 at 23:11

I'm assuming that 0x00001021 is treated as a word, not bytes. Either way, you are correct about not knowing the underlying mechanics of the online calculators. 

I have yet to find a calculator that I can configure to get the same results as this CRC hardware peripheral with a given input value.

Is there a calculator that you recommend that I can verify against?

Posted on March 15, 2016 at 00:47

I've done it from first principles. The one you cited takes bytes, in the form 0x00 0x00 0x10 0x21, which is big endian first, which is architecturally backward, which breaks most general demos. There is a PC based example half way down this thread.

https://community.st.com/0D50X00009Xkhp1SAB

I couldn't make sense of the number you were getting, regardless of how I ordered the bits or bytes, so I'd basically have to debug the loop as it iterates bytes in the Java Script. Not sure there is a lot of point in doing that, as I know how to generate valid numbers.

DWORD Crc32(DWORD Crc, DWORD Data){int i;Crc = Crc ^ Data;for(i=0; i<32; i++)if (Crc & 0x80000000)Crc = (Crc << 1) ^ 0x04C11DB7; // Polynomial used in STM32elseCrc = (Crc << 1);return(Crc);}DWORD Crc32ByteWise(DWORD Crc, BYTE Data){int i;Crc = Crc ^ ((DWORD)Data << 24);for(i=0; i<8; i++)if (Crc & 0x80000000)Crc = (Crc << 1) ^ 0x04C11DB7; // Polynomial used in STM32elseCrc = (Crc << 1);return(Crc);}

This other thread deals with a lot of common CRC methods

https://community.st.com/0D50X00009XkgXtSAJ

And there are about 10 years of other thread

Edit: Fixed DEAD LINKs, original post from Mar 14 2016

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..