Slightly off topic but does anyone know how to calculate CRC using STM32 hardware when number of bytes is not a multiple of 4?
Make one up and apply it consistently. The way the register feeds is not conducive to byte level operation, or any ''standard'' method. Either pad the 32-bit word with zeros and perform a full 32-bit cycle, or shift your byte(s) to the high order end of the register, or perform a couple of byte wide computations in software.
Tips, Buy me a coffee, or three.. PayPal VenmoUp vote any posts that you find helpful, it shows what's working..
See this forum post (by mcuisp) on how to make STM32 calculate CRC same as x86 PC (by reversing the bits of the 32 bit values fed into the CRC hadrware).
But wouldn't the extra zeros/padding change the CRC thus generating a CRC that is differient to how ''the other end'' will calculate it? I don't want to have a ''non-standard'' CRC imlementation at ''the other end''.
It doesn't feed correctly anyway for byte wise operation, so I'm not sure what ''standard'' you have in mind. The polynomial is one of a number classically used, but you'd need to endian swap the bytes on a little-endian machine, which is not happening here, for it to be generated normally. So my point is if you pick a method, you have defined the ''standard'', and you apply the same computation at each end of the link.
Tips, Buy me a coffee, or three.. PayPal VenmoUp vote any posts that you find helpful, it shows what's working..
Either pad the 32-bit word with zeros and perform a full 32-bit cycle, or shift your byte(s) to the high order end of the register But wouldn't the extra zeros/padding change the CRC thus generating a CRC that is differient to how ''the other end'' will calculate it? I don't want to have a ''non-standard'' CRC imlementation at ''the other end''.or perform a couple of byte wide computations in software.
You'd have to do it in software, because the register only does the math 32-bits at a time, and you need to do 8, 16, or 24 bits
It's really a pity they didn't use a right-shifting model, rather than the left-shifting one. So you'd need to bit-reverse all the 32-bit words, then read the CRC register, bit-reverse that, apply your remaining 0 to 3 bytes using a right-shifting model in software.
Tips, Buy me a coffee, or three.. PayPal VenmoUp vote any posts that you find helpful, it shows what's working..
Only if you have control over the other end of the link. The STM32 hardware can calculate the most popular CRC32 (PKZIP, WINRAR, XVI hex editor etc. etc. ) if you reverse the bits as you feed it and reverse the bits at the end (as per link above). I may have a play with this but I suspect the approach of software CRCing the leftover bytes might be the only way to do this. As only 3 bytes max would need software CRCing this would have little speed impact. will report back my findings.
The bit reverses on the data and the CRC register above relate to making the STM32's CRC perform a computation which matches the polynomial, and inverse conditions of the one used by PKZIP.
The issues are related to endian, and shift direction. In my opinion the choices by ST were particularly bad. The code snippet from the second post to this thread will allow you to validate the 32-bit computation used by the STM32. It will work on small-endian machines, and does validate the numbers you were seeing.
Tips, Buy me a coffee, or three.. PayPal VenmoUp vote any posts that you find helpful, it shows what's working..
Thanks for everybody. Now I need a clarification, the reverse operation before and after computing the CRC, is it related to little endian/big endian ? I am looking for a tool with which I can validate the CRC computation but I can't find one that corresponds to STM32. What I find is using big endian. Do you have one ? Thanks again,MCU Lüfter
Now I could probably reimplement with a table driven varient but this should prove the concept.
u32 revbit(u32 data) { asm(''rbit r0,r0''); return data; }; u32 CalcCRC32(u8 *buffer,u32 size) { u32 i, j; u32 ui32; RCC_AHBPeriphClockCmd(RCC_AHBPeriph_CRC,ENABLE); CRC->CR=1; asm(''NOP'');asm(''NOP'');asm(''NOP'');//delay for hardware ready i = size >> 2; while(i--) { ui32=*((u32 *)buffer); buffer += 4; ui32=revbit(ui32);//reverse the bit order of input data CRC->DR=ui32; } ui32=CRC->DR; ui32=revbit(ui32);//reverse the bit order of output data i = size & 3; while(i--) { ui32 ^= (u32)*buffer++; for(j=0; j<8; j++) if (ui32 & 1) ui32 = (ui32 >> 1) ^ 0xEDB88320; else ui32 >>= 1; } ui32^=0xffffffff;//xor with 0xffffffff return ui32;//now the output is compatible with windows/winzip/winrar };
Tips, Buy me a coffee, or three.. PayPal VenmoUp vote any posts that you find helpful, it shows what's working..