2016-03-14 10:01 AM
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 dataword 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-cloudy2016-03-14 10:32 AM
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 iterationshttps://community.st.com/0D50X00009XkfPISAZ
https://community.st.com/0D50X00009XkfPESAZ
Edit: Fixed DEAD LINKs, original post from Mar 14 2016
2016-03-14 11:01 AM
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: 0x04C11DB7Polynomial size: 0x00 (32 bit)Input data reverse: 0x00 (none)Output data reverse: 0x00 (none)Initial value: 0xFFFFFFFFI send a single 32-bit word to be calculated:LL_CRC_FeedData32(&CRC, 0x00001021);The CRC result is 0x4BB7ED3FIf 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.2016-03-14 12:40 PM
Am I missing something here?
Endian mode vs shift direction?2016-03-14 01:39 PM
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 -> 0xFFFFFFFFinput value -> 0x00crc result ->
0x4E08BFB4
Then I would update the initial value to the result of the previous calculation:initial value ->0x4E08BFB4
input value -> 0x00crc result ->0x00B7647D
initial value ->0x00B7647D
input value -> 0x10crc result ->0xFB75A670
initial value ->0xFB75A670
input value -> 0x21crc 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?
2016-03-14 02:08 PM
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 from2016-03-14 02:23 PM
Sure, here it is: http://www.sunshine2k.de/coding/javascript/crc/crc_js.html
The settings I am using are:CRC Width: CRC-32CRC Parametrization: customCRC Detailed Parameters: input and result reflected both UNcheckedpolynomial: 0x04C11DB7initial value: 0xFFFFFFFFfinal xor value: 0x0CRC Input Data: set to bytesThen 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: 0x212016-03-14 03:05 PM
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.
2016-03-14 03:11 PM
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?2016-03-14 04:47 PM
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