2019-08-21 10:26 PM
Hello
Since the STM32f42xx series has no intial value for the CRC I'm wondering if there is a way to stop a crc calculation (store the DR value) and resume it by writing the DR register with the stored value and some calculation??
Something like this:
crcvalue1 = HAL_CRC_Calculate(&CRCType, &byte_array_hex[0], 37000);
__HAL_CRC_DR_RESET(&CRCType);
CRCType.Instance->DR = crcvalue1;
crcvalue2 = HAL_CRC_Accumulate(&CRCType, &byte_array_hex[37000], 13000);
The goal is to interrupt a ongoing CRC calculaton with a higher prioritized calculation and afterwards resume to the lower priority again.
Kind regards
Mathias
2019-08-26 01:27 AM
Once again an awesome solution. Thank you very much!
Now I have to figure out how to use this solution with DMA.
Do you maybe have an idea how I could do that?
Is it possible to change the dma data before every transfer?
2019-08-26 01:43 AM
DMA can't do bit manipulation. HW CRC unit not that well thought out. Newer parts offer additional options.
2019-08-27 02:18 AM
+1 to what Clive said, no option to do this with DMA.
The other side appears to have more flexibility; I'd expect you can pull this out with a bit of experimentation.\
JW
2019-08-27 02:43 AM
Yes, there is no way to do that with DMA.
But what do you mean with "the other side appears to have more flexibility"?
2019-08-28 10:32 PM
@Community member Do you have some sort of mathematic derivation how the reverse crc calculaton works?
2019-08-28 11:08 PM
I have a more mechanical understanding of the method/process. The other threads show the bit level reversal method, and the table driven versions are pulled from that. You can move the polynomial backward and forward in time.
These CRC/LFSR implementations have historically been used for error detection/correction. Fire codes were an early use of these. When the checksum fails you wind it backward, applying the bits in the reverse order, and shifting in the opposite direction, and you can determine where a couple of bits are wrong, and fix them. Basically approaching a discontinuity from both directions. In the context here, I'm using those techniques to compute a value that will undo itself when applied to a specific starting value.
Neal Glover Fire Codes http://www.bitsavers.org/components/cirrusLogic/Practical_Error-Correction_Design_For_Engineers_2ed_1991.pdf
2019-08-28 11:29 PM
DWORD Crc32(DWORD Crc, DWORD Data)
{
int i;
Crc = Crc ^ Data; // Data applied first, cheaper to apply XOR here than 1-bit at a time
for(i=0; i<32; i++)
if (Crc & 0x80000000)
Crc = (Crc << 1) ^ 0x04C11DB7; // Polynomial used in STM32
else
Crc = (Crc << 1); // Shifts left in forward direction
return(Crc);
}
DWORD Crc32Rev(DWORD CurrentCrc, DWORD DesiredCrc)
{
DWORD Data;
int i;
for(i=0; i<32; i++)
if (DesiredCrc & 0x00000001)
#if 1
DesiredCrc = ((DesiredCrc ^ 0x04C11DB7) >> 1) | 0x80000000; // Long form
#else // or
DesiredCrc = (DesiredCrc >> 1) ^ 0x82608EDB; // Back feeding polynomial
#endif
else
DesiredCrc = (DesiredCrc >> 1); // Shifts right in the reverse direction
Data = DesiredCrc ^ CurrentCrc; // Data removed last
return(Data); // Data Pattern to get Desired CRC from Current CRC
}
The polynomial is 33-bits long in reality, in the form x**32 + .. + 1
We play games here with left/right alignment so it fits within the 32-bits
afforded by the machine.
0x04C11DB7 -> 1 0000 0100 1100 0001 0001 1101 1011 0111
0x82608EDB -> 1000 0010 0110 0000 1000 1110 1101 1011 1
@Community member the forum is screwy, you have to click "Previous Answers" due to the node you replied too
2019-08-29 03:00 AM
> But what do you mean with "the other side appears to have more flexibility"?
I was under the impression you need to communicate between STM32 and FM3 (then the latter would be the "other side"), but upon second reading I now see you need backwards compatibility rather. Sorry for the confusion.
JW