cancel
Showing results for 
Search instead for 
Did you mean: 

How can I calculate the CRC in java ?

michaelmccartyeng
Associate II
Posted on July 04, 2013 at 04:30

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 !
5 REPLIES 5
Posted on July 04, 2013 at 14:05

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&currentviews=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&currentviews=3665]
Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
michaelmccartyeng
Associate II
Posted on July 06, 2013 at 03:18

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&currentviews=3665]

Posted on July 06, 2013 at 14:23

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();
}
}

Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
michaelmccartyeng
Associate II
Posted on July 23, 2013 at 03:02

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;
}

Posted on June 21, 2017 at 19:48

Fix for DEAD LINK

https://community.st.com/0D50X00009XkbNMSAZ

Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..