2013-07-03 07:30 PM
Hello All,
I have a stm32f4 discovery. I'm sending out messages the first part is my ''header'' the rest is ''data'' then the tail is the crc value from the hw perph. This is the code I use to send the messages.// new data is coming in to this node from another
// broadcast handle it based on where it came from
// and what this node does with raw data
case
CMD_NEWDATA:
// send header
crcVal.UI32 = CRC_CalcBlockCRC((u32*)&Msg, 1);
sendRawData((u32*)&Msg, 1);
// send vardata
// todo if ptr type send that out dma etc
for
(i=0; i<Msg.size; i++)
{
crcVal.UI32 = CRC_CalcBlockCRC((u32*)&Msg.vd[i], 1);
sendRawData((u32*)&Msg.vd[i], 1);
}
// send out crc
sendRawData(&crcVal.UI32, 1);
CRC_ResetDR();
// reset the crc
break
;
this is what I see come out the other end
02 07 02 00 18 8A D0 23 25 2B 09 00 [[98 E2 D7 AC]]
02 07 02 00 7C 8A D0 23 25 2B 09 00 [[EA 63 8C 89]]
02 07 02 00 E0 8A D0 23 25 2B 09 00 [[DF EF D7 66]]
02 07 02 00 44 8B D0 23 25 2B 09 00 [[37 66 FA 53]]
02 07 02 00 A8 8B D0 23 25 2B 09 00 [[FF E6 DC 3A]]
02 07 02 00 0C 8C D0 23 25 2B 09 00 [[07 40 01 55]]
the part in the [[xx]] is the CRC My crc produced by java is nothing close to the crc produced by the stm. So now I'm kinda in a chicken/egg situation.
Question 1: is my crc even correct for the data preceding it ?
Question 2: (if question 1 is yes) how do I calculate the same crc in Java.
This is my Java code btw, just the part where it adds the last bit of crc
is.read(crcBytes, 0, 4);
crc.update(crcBytes);
if
(crc.getValue() == 0)
{
as always thanks for the time !
2013-07-04 05:05 AM
The thing to remember about the CRC unit on the STM32 is it operates on 32-bit data, and backward, it left shifts data whose order would normally flow from the right.
[DEAD LINK /public/STe2ecommunities/mcu/Lists/cortex_mx_stm32/Flat.aspx?RootFolder=/public/STe2ecommunities/mcu/Lists/cortex_mx_stm32/CRC%20computation&FolderCTID=0x01200200770978C69A1141439FE559EB459D7580009C4E14902C3CDE46A77F0FFD06506F5B¤tviews=3665]STM32 CRC#include <
windows.h
>
#include <
stdio.h
>
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 STM32
else
Crc = (Crc << 1);
return(Crc);
}
DWORD Crc32Fast(DWORD Crc, DWORD Data)
{
static const DWORD CrcTable[16] = { // Nibble lookup table for 0x04C11DB7 polynomial
0x00000000,0x04C11DB7,0x09823B6E,0x0D4326D9,0x130476DC,0x17C56B6B,0x1A864DB2,0x1E475005,
0x2608EDB8,0x22C9F00F,0x2F8AD6D6,0x2B4BCB61,0x350C9B64,0x31CD86D3,0x3C8EA00A,0x384FBDBD };
Crc
= Crc ^ Data; // Apply all 32-bits
// Process 32-bits, 4 at a time, or 8 rounds
Crc = (Crc << 4) ^ CrcTable[Crc >> 28]; // Assumes 32-bit reg, masking index to 4-bits
Crc = (Crc <<
4
) ^ CrcTable[Crc >> 28]; // 0x04C11DB7 Polynomial used in STM32
Crc = (Crc <<
4
) ^ CrcTable[Crc >> 28];
Crc = (Crc <<
4
) ^ CrcTable[Crc >> 28];
Crc = (Crc <<
4
) ^ CrcTable[Crc >> 28];
Crc = (Crc <<
4
) ^ CrcTable[Crc >> 28];
Crc = (Crc <<
4
) ^ CrcTable[Crc >> 28];
Crc = (Crc <<
4
) ^ CrcTable[Crc >> 28];
return(Crc);
}
void test(void)
{
BYTE vector[12] = { 0x02,0x07,0x02,0x00,0x18,0x8A,0xD0,0x23,0x25,0x2B,0x09,0x00 };
DWORD Crc;
int i;
for(i=0; i<12; i++)
printf(''%02X '',vector[i]);
putchar('
');
Crc = 0xFFFFFFFF; // Initial state
for(i=0; i<12; i+=4)
{
Crc = Crc32Fast(Crc, *((DWORD *)&vector[i]) ); // 4-bytes at a time
}
printf(''%08X test
'',Crc);
}
int main(int argc, char **argv)
{
printf(''%08
X'',Crc32(0xFFFFFFFF, 0x12345678)); // 0xDF8A8A2B
printf(''%08
X'',Crc32Fast(0xFFFFFFFF, 0x12345678)); // 0xDF8A8A2B
test();
return(1);
}
DF8A8A2B
DF8A8A2B
02 07 02 00 18 8A D0 23 25 2B 09 00
ACD7E298 test
[DEAD LINK /public/STe2ecommunities/mcu/Lists/cortex_mx_stm32/Flat.aspx?RootFolder=/public/STe2ecommunities/mcu/Lists/cortex_mx_stm32/CRC%20computation&FolderCTID=0x01200200770978C69A1141439FE559EB459D7580009C4E14902C3CDE46A77F0FFD06506F5B¤tviews=3665]
2013-07-05 06:18 PM
Thanks Clive,
I tried to adapt your c code into java. Why must I always deal with unsigned ints which java does not support ? This is what I have so far but my crc never returns 0, which is what should happen when I crc the data and the crc right ? Either way the crc never matches. The slow method always has a crc =0. Any ideas whats going on ?package zonerobotics.node.comm;
import java.nio.ByteBuffer;
public class STM32CRC {
int crc = 0xFFFFFFFF;
final int CrcTable[] = {
// Nibble lookup table for 0x04C11DB7 polynomial
0x00000000,0x04C11DB7,0x09823B6E,0x0D4326D9,0x130476DC,0x17C56B6B,0x1A864DB2,0x1E475005,
0x2608EDB8,0x22C9F00F,0x2F8AD6D6,0x2B4BCB61,0x350C9B64,0x31CD86D3,0x3C8EA00A,0x384FBDBD };
void reset()
{
crc = 0xFFFFFFFF;
}
void update(byte[] data)
{
// if its not divisible by 4 we are up a creek without a paddle
if
((data.length % 4) != 0)
{
System.out.println(
''Bad CRC update size: ''
+data.length );
reset();
return
;
}
// do the crc
ByteBuffer bb = ByteBuffer.wrap(data);
while
(bb.hasRemaining())
{
crc = Crc32Fast(crc, bb.getInt());
}
}
long getValue()
{
return
crc;
}
int Crc32Slow(int Crc, int Data)
{
int i;
Crc = Crc ^ Data;
for
(i=0; i<32; i++)
if
((Crc & 0x80000000)>0)
Crc = (Crc << 1) ^ 0x04C11DB7;
// Polynomial used in STM32
else
Crc = (Crc << 1);
return
(Crc);
}
int Crc32Fast(int Crc, int Data)
{
Crc = Crc ^ Data;
// Apply all 32-bits
Crc = (Crc << 4) ^ CrcTable[(Crc >> 28) & 0x0F];
// Assumes 32-bit reg, masking index to 4-bits
Crc = (Crc << 4) ^ CrcTable[(Crc >> 28) & 0x0F];
// 0x04C11DB7 Polynomial used in STM32
Crc = (Crc << 4) ^ CrcTable[(Crc >> 28) & 0x0F];
Crc = (Crc << 4) ^ CrcTable[(Crc >> 28) & 0x0F];
Crc = (Crc << 4) ^ CrcTable[(Crc >> 28) & 0x0F];
Crc = (Crc << 4) ^ CrcTable[(Crc >> 28) & 0x0F];
Crc = (Crc << 4) ^ CrcTable[(Crc >> 28) & 0x0F];
Crc = (Crc << 4) ^ CrcTable[(Crc >> 28) & 0x0F];
return
(Crc);
}
// TODO Auto-generated method stub
}
[DEAD LINK /public/STe2ecommunities/mcu/Lists/cortex_mx_stm32/Flat.aspx?RootFolder=/public/STe2ecommunities/mcu/Lists/cortex_mx_stm32/CRC%20computation&FolderCTID=0x01200200770978C69A1141439FE559EB459D7580009C4E14902C3CDE46A77F0FFD06506F5B¤tviews=3665]
2013-07-06 05:23 AM
I'm not terribly functional in Java, but this translation appears to be workable..
public class STM32CRC {
// Initial rough conversion done with http://www.tangiblesoftwaresolutions.com/Product_Details/CPlusPlus_to_Java_Converter_Details.html
// Polished with http://www.browxy.com
// Clive - sourcer32@gmail.com
private static int Crc32(int Crc, int Data)
{
int i;
Crc = Crc ^ Data;
for (i = 0; i <
32
; i++)
{
if ((Crc & 0x80000000) != 0)
{
Crc = (Crc << 1) ^ 0x04C11DB7; // Polynomial used in STM32
}
else
{
Crc = (Crc << 1);
}
}
return (Crc);
}
private static int Crc32Fast(int Crc, int Data)
{
int[] CrcTable = {0x00000000,0x04C11DB7,0x09823B6E,0x0D4326D9,0x130476DC,0x17C56B6B,0x1A864DB2,0x1E475005, 0x2608EDB8,0x22C9F00F,0x2F8AD6D6,0x2B4BCB61,0x350C9B64,0x31CD86D3,0x3C8EA00A,0x384FBDBD}; // Nibble lookup table for 0x04C11DB7 polynomial
Crc
= Crc ^ Data; // Apply all 32-bits
// Process 32-bits, 4 at a time, or 8 rounds
Crc = (Crc << 4) ^ CrcTable[Crc >>> 28]; // Assumes 32-bit reg, masking index to 4-bits
Crc = (Crc <<
4
) ^ CrcTable[Crc >>> 28]; // 0x04C11DB7 Polynomial used in STM32
Crc = (Crc <<
4
) ^ CrcTable[Crc >>> 28];
Crc = (Crc <<
4
) ^ CrcTable[Crc >>> 28];
Crc = (Crc <<
4
) ^ CrcTable[Crc >>> 28];
Crc = (Crc <<
4
) ^ CrcTable[Crc >>> 28];
Crc = (Crc <<
4
) ^ CrcTable[Crc >>> 28];
Crc = (Crc <<
4
) ^ CrcTable[Crc >>> 28];
return (Crc);
}
private static void test()
{
int[] vector = {0x02,0x07,0x02,0x00,0x18,0x8A,0xD0,0x23,0x25,0x2B,0x09,0x00};
int Crc;
int i;
int Hold;
for (i = 0; i < 12; i++)
{
System.out.printf(''%02X '',vector[i]);
}
System.out.print('
');
Crc = (int)0xFFFFFFFF; // Initial state
for (i = 0; i < 12; i += 4)
{
Hold = vector[i+0] + (vector[i+1] << 8) + (vector[i+2] << 16) + (vector[i+3] << 24);
Crc = Crc32Fast(Crc, Hold); // 4-bytes at a time
}
System.out.printf(''%08X test
'',Crc);
}
public static void main(String[] args)
{
System.out.printf(''%08
X'',Crc32(0xFFFFFFFF, 0x12345678)); // 0xDF8A8A2B
System.out.printf(''%08
X'',Crc32Fast(0xFFFFFFFF, 0x12345678)); // 0xDF8A8A2B
test();
}
}
2013-07-22 06:02 PM
Thanks a bunch Clive, I finally got around to making it all work.
package zonerobotics.node.comm;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
public class STM32CRC {
int crc = 0xFFFFFFFF;
final int CrcTable[] = {
// Nibble lookup table for 0x04C11DB7 polynomial
0x00000000,0x04C11DB7,0x09823B6E,0x0D4326D9,0x130476DC,0x17C56B6B,0x1A864DB2,0x1E475005,
0x2608EDB8,0x22C9F00F,0x2F8AD6D6,0x2B4BCB61,0x350C9B64,0x31CD86D3,0x3C8EA00A,0x384FBDBD };
void reset()
{
crc = 0xFFFFFFFF;
}
void update(ByteBuffer bb)
{
if
(bb.capacity()%4 != 0 )
{
return
;
}
bb.position(0);
bb.order(ByteOrder.LITTLE_ENDIAN);
while
(bb.hasRemaining())
{
crc = Crc32Fast(crc, bb.getInt());
// 4-bytes at a time
}
}
void update(int[] data)
{
// if its not divisible by 4 we are up a creek without a paddle
if
((data.length % 4) != 0)
{
System.out.println(
''Bad CRC update size: ''
+data.length );
reset();
return
;
}
int Crc;
int i;
int Hold;
for
(i = 0; i < data.length; i += 4)
{
Hold = data[i+0] + (data[i+1] << 8) + (data[i+2] << 16) + (data[i+3] << 24);
crc = Crc32Fast(crc, Hold);
// 4-bytes at a time
System.out.printf(
''%08X
''
,Hold);
}
}
int getValue()
{
return
crc;
}
int Crc32Slow(int Crc, int Data)
{
int i;
Crc = Crc ^ Data;
for
(i=0; i<32; i++)
if
((Crc & 0x80000000)>0)
Crc = (Crc << 1) ^ 0x04C11DB7;
// Polynomial used in STM32
else
Crc = (Crc << 1);
return
(Crc);
}
int Crc32Fast(int Crc, int Data)
{
Crc = Crc ^ Data;
// Apply all 32-bits
Crc = (Crc << 4) ^ CrcTable[(Crc >> 28) & 0x0F];
// Assumes 32-bit reg, masking index to 4-bits
Crc = (Crc << 4) ^ CrcTable[(Crc >> 28) & 0x0F];
// 0x04C11DB7 Polynomial used in STM32
Crc = (Crc << 4) ^ CrcTable[(Crc >> 28) & 0x0F];
Crc = (Crc << 4) ^ CrcTable[(Crc >> 28) & 0x0F];
Crc = (Crc << 4) ^ CrcTable[(Crc >> 28) & 0x0F];
Crc = (Crc << 4) ^ CrcTable[(Crc >> 28) & 0x0F];
Crc = (Crc << 4) ^ CrcTable[(Crc >> 28) & 0x0F];
Crc = (Crc << 4) ^ CrcTable[(Crc >> 28) & 0x0F];
return
(Crc);
}
// TODO Auto-generated method stub
}
I use it like this with the bytebuffer
crc.reset();
crc.update(incMsg.data);
if
(crc.getValue() == 0)
{
newRawMessages.add(incMsg);
}
else
{
System.out.printf(
''CRC ERR %08X
''
,crc.getValue());
rxState = eRXState.start;
}
2017-06-21 12:48 PM
Fix for DEAD LINK
https://community.st.com/0D50X00009XkbNMSAZ