2013-10-11 03:38 AM
Hi all ,
Currently i am trying to communicate with Vending machine through DEX protocol via STM32.But i could not calculate accurate CRC-16 byte so i receive always an error.There are many online calculator about crc-16 but none of them worked for me.Is there anybody worked with crc-16 in c language and in stm32 syntax? #crc-162013-10-11 06:17 AM
Yes
One has to consider the polynomial, initial state, shift direction of data and CRC. Do you have an example of the data and correct CRC bytes?// Generic CRC-CCITT 16 bit implementation for buffer/stream validation
// This is a minimal code space version, a fast parallel table routine
// could be used if time/throughput is critical
WORD CRC16(WORD Crc, DWORD Size, BYTE *Buffer)
{
while(Size--)
{
int i;
Crc = Crc ^ ((WORD)*Buffer++ << 8);
for(i=0; i<8; i++)
if (Crc & 0x8000)
Crc = (Crc << 1) ^ 0x1021;
else
Crc = (Crc << 1);
}
return(Crc);
}
Use
Crc = CRC16(0xFFFF, sizeof(Buffer), Buffer);
2013-10-11 06:26 AM
Thanks clive,
that is point! i have no correct crc byte for any data stream.But i know i need to use 0xa001 as polynomial.Also what is the magic of the initial value?What is the difference between 0xFFFF and 0x0000?.Ex. my string is ''6150210000RR01L01''. Whenever i try use different algorithm for calculating crc byte, i have different crc values even if polynomial and initial value is same.2013-10-11 08:02 AM
Think of the CRC as the remainder from a complex long division. If you have the math or numbers wrong, the answer will also be wrong.
No, I'm looking for examples of actual bus transactions, either ones captured from a functional system, or provided as complete examples with the appropriate CRC as part of the specification.2013-10-11 09:35 AM
0x10 - DLE
0x01 - SOH
0x36 - 6
0x31 - 1
0x35 - 5
0x30 - 0
0x32 - 2
0x31 - 1
0x30 - 0
0x30 - 0
0x30 - 0
0x30 - 0
0x52 - R
0x52 - R
0x30 - 0
0x31 - 1
0x4C - L
0x30 - 0
0x31 - 1
0x10 - DLE
0x03 - ETX
0x1A - CRC Low
0x6D - CRC High
2013-10-11 01:16 PM
// DEX Protocol CRC Demo - sourcer32@gmail.com
#include <
windows.h
>
#include <
stdio.h
>
#include <
stdlib.h
>
char test[] = ''1234567890RR01L01''; // 0xDE, 0x4D
unsigned short crc16(unsigned short crc, unsigned char data)
{
int i;
crc = crc ^ ((unsigned short)data & 0x00FF);
for(i=0; i<
8
; i++)
if (crc & 1)
crc = (crc >> 1) ^ 0xA001; // Right shifting polynomial
else
crc = (crc >> 1);
return(crc);
}
unsigned short crc16fast(unsigned short crc, unsigned char data)
{
static const unsigned short crctable[] = { // Nibble Table for 0xA001 polynomial - sourcer32@gmail.com
0x0000,0xCC01,0xD801,0x1400,0xF001,0x3C00,0x2800,0xE401,
0xA001,0x6C00,0x7800,0xB401,0x5000,0x9C01,0x8801,0x4400 };
crc = crc ^ ((unsigned short)data & 0x00FF); // Data & CRC shift right, ie LSB first
crc = (crc >> 4) ^ crctable[crc & 0xF]; // Process 8-bits, 2 rounds of 4-bits
crc = (crc >> 4) ^ crctable[crc & 0xF]; // Right shifting polynomial
return(crc);
}
void senddex(char *string)
{
unsigned short crc;
printf(''0x10 - DLE
'');
printf(''0x01 - SOH
'');
crc = 0x0000; // Initial
while(*string) // For string
{
printf(''0x%02X - %c
'', *string, *string);
crc = crc16fast(crc, (unsigned char)*string++); // Add to CRC
}
printf(''0x10 - DLE
'');
printf(''0x03 - ET
X'');
crc = crc16fast(crc, 0x03); // Add ETX to CRC
printf(''0x%02X - CRC Low
'', ((crc >> 0) & 0x00FF));
printf(''0x%02X - CRC High
'', ((crc >> 8) & 0x00FF));
}
int main(int argc, char *argv)
{
senddex(test);
return(1);
}
2013-10-20 11:23 PM
Thanks for your great support clive.This totally will help me.There is not any example for DEX implementation at least i could not find any.
2013-10-21 01:28 PM
Glad it helped, were you able to confirm a successful response from your equipment?
It took me a bit of fishing to find the details I was looking for, basically the CRC being used, and the data over which it was being applied. This should at least show up in a Google/Bing search if someone tries in the future.2013-10-21 11:48 PM
2013-11-12 11:27 AM