|
|
View previous topic :: View next topic |
Author |
Message |
demedeiros
Joined: 27 Dec 2013 Posts: 71
|
Help with CRC |
Posted: Tue Jan 30, 2024 7:33 pm |
|
|
Hi All,
I am trying to use the CCS supplied crc.c file for calculation of a 32bit CRC. I am not sure if I am doing something wrong as the CRC result does not match anything that is calculated when I plug the data into https://crccalc.com/
Code: |
void crcTest()
{
char testData[200] = "#,A,23,09,03,4000.400000,N,7000.000000,W,0.0,-95.52,0.000,0.000,01,02,00,00001,";
uint32_t myCRC = generate_32bit_crc(testData,strlen(testData),CRC_32);
fprintf(RF, "CRC: 0x%lx\r\n\n", myCRC);
}
|
I have tried the length with strlen() and with sizeof() to (from my undertanding) include and not include the terminating character.
Its fairly straightforward, so I am at a loss for what I am doing wrong. This example shown here returns 0x42e9a8ef. If I plug the same data into crccalc, I do not get this value with any of the algorithms.
Link to CRCCalc https://crccalc.com/?crc=#,A,23,09,03,4000.400000,N,7000.000000,W,0.0,-95.52,0.000,0.000,01,02,00,00001,&method=crc32&datatype=ascii&outtype=0
Any thoughts? |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19538
|
|
Posted: Wed Jan 31, 2024 3:47 am |
|
|
OK.
I think I've met this before. The CCS supplied CRC32 algorithm only works
correctly for sources that are a multiple of four bytes long.
I went online, and found a simpler algorithm, that actually saves quite a
lot of data movement, by reversing the bit order the code works through
the words. You therefore have to use a bit reversed 'key' for this (so
0xEDB88320, instead of 0x04C11DB7), but it results in faster calculation,
and as I wrote it, works directly on a 'string' (terminating on the null
terminator), so does not need a 'length'.
Attaching your code and this:
Code: |
#define REVCRC_32 0xEDB88320 //bit reversed CRC32
unsigned int32 crc32str(unsigned int8 *message) {
int16 i=0; //support up to 65535 chars
int8 j;
unsigned int32 crc=0xFFFFFFFF, bmask; //initial value set
unsigned int8 b; //individual bytes
while (message[i] != 0)
{ //for an ASCII string - stop at terminator
b = message[i]; // Read next byte.
crc = crc ^ b; //XOR in the byte
for (j = 0; j < 8; j++) { // Repeat eight times.
bmask = -(crc & 1);
crc = (crc >> 1) ^ (REVCRC_32 & bmask);
}
i = i + 1;
}
return ~crc;
}
void crcTest()
{
char testData[] = "#,A,23,09,03,4000.400000,N,7000.000000,W,0.0,-95.52,0.000,0.000,01,02,00,00001,";
unsigned int32 myCRC = crc32str(testData);
printf( "CRC: 0x%lx\r\n\n", myCRC);
}
|
Hopefully this will work for you. |
|
|
demedeiros
Joined: 27 Dec 2013 Posts: 71
|
|
Posted: Wed Jan 31, 2024 5:42 am |
|
|
Ttelmah,
Thank you, once again you save the day!
Things like this make me doubt myself... "It should just work!!! What kind of idiotic mistake am I making! |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19538
|
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|