Just to want to let you all know, that we made many attempts to calculate the same CRC in a software that STM32L CRC HW unit does, but all in vain, especially if you want the same results e.g. on Intel.
After all we tried, the only code that is working, we got from ST support upon our request there.
CRC's by their nature are sensitive to bit and sequence errors, if you screw up the math you're going to get the wrong numbers.
The polynomial, endian-ness, and 32-bit data width of the STM32 are difficult for some people to get their heads around, especially if they rely on web sources for their testing and knowledge.
Thanks for your kindly help. According to you and Clive1's suggestion, we try to find the discussion from web and we try some examples for both STM and PC side. We found one matching calculation. Because the calculation on ST is not the standard way for CRC32, it needs to modify to match the standard calculation. Below is the example for reference, hope it can help others. By the way, thanks Adam and Clive1.//====== PC side====================//--------CRC32.c---------------------------------------ULONG Table[256];ULONG CRC;ULONG Reflect(ULONG ref, char ch){ ULONG value = 0; // Swap bit 0 for bit 7 // bit 1 for bit 6, etc. for(int i = 1; i < (ch + 1); i++) { if (ref & 1) value |= 1 << (ch - i); ref >>= 1; } return value;}void CRC_32(){ // This is the official polynomial used by CRC-32 // in PKZip, WinZip and Ethernet. ULONG ulPolynomial = 0x04C11DB7; // 256 values representing ASCII character codes. for (int i = 0; i <= 0xFF; i++) { Table[i] = Reflect(i, 8) << 24; for (int j = 0; j < 8; j++) Table[i] = (Table[i] << 1) ^ (Table[i] & (1 << 31) ? ulPolynomial : 0); Table[i] = Reflect(Table[i], 32); }}void CRC32_Calculate(const LPBYTE buffer, UINT size, ULONG &CRC){ // calculate the CRC LPBYTE pbyte = buffer; while (size--) CRC = (CRC >> 8) ^ Table[(CRC & 0xFF) ^ *pbyte++];}//--------main.c-------------------------------------------- CRC_32(); CRC = 0xFFFFFFFF; CRC32_Calculate((LPBYTE)Buffer, sz, CRC); CRC ^= 0xFFFFFFFF;//========== STM32F side===========/**********************reverse bits of DWORDInput: u32 data -- the inputOutput: u32 data -- the output**********************/uint32_t revbit(uint32_t data){ asm(''rbit r0,r0''); return data;};/**********************Calculate CRC32 of DWORD data array.Input: u32 *dworddata -- the array point u32 dwordcount -- the data len in DWORDOutput: u32 CRC32 -- the result**********************/uint32_t CalcCRC32(uint32_t *dworddata,uint32_t dwordcount){ uint32_t ui32; for(;dwordcount>0;dwordcount--) { ui32=*dworddata; dworddata++; ui32=revbit(ui32); CRC->DR=ui32; } ui32=CRC->DR; ui32=revbit(ui32); ui32^=0xffffffff; return ui32;};//========================================
Hi Ivan,No the F1 implementation has a fixed polynomial and bit width, with software bit reversal it can do the equivalent to the 'PKZIP' style computation.MODBUS requires different hardware support. See my thread related to the F3 doing MODBUS in hardware.
thanks for Ur conclusion and summarizing...the function is working well if buffer length will more than 4-byte but it does not work correct if buffer length will less than 4-byte.I believe that it is because of initial value of variable in function.if U or any one could fix it, I'll appreciate.Best Regards
So you pick the guy who's post count to the forum is ONE, and hasn't posted in TWO years?
Yes, it doesn't look like he sets crc_reg in that case, probably want a crc_reg = CRC->DR Seem to think I posted a working example earlier in the thread, where it does the last byte in software. But the purpose of writing crc_reg back into the register is that it causes the math to zero it out. Please don't use the U and Ur abbreviations, you're not texting
Tips, Buy me a coffee, or three.. PayPal VenmoUp vote any posts that you find helpful, it shows what's working..