I have tmc2209 stepper driver. I am planning to use UART for communication. The communication protocol looks pretty simple, but I can't figure out how to calculate this damn CRC. The polynomial is CRC-8 0x07. For the message 0x05 0x00 0x00 the correct CRC is 0x48 and for message 0x05 0x00 0x06 is correct CRC 0x6F. I know this because I have brute forced all possible combinations for these messages and with correct CRC tmc2209 responses. When I calculate CRC manually for these messages it doesn't match. They have some CRC example calculation in datasheet but this code looks broken for me. Here is the datasheet: https://www.trinamic.com/fileadmin/assets/Products/ICs_Documents/TMC2209_Datasheet_V103.pdf UART starts at page 15 and CRC calculation is on page 17.
CRC located in last byte of message
, add return datagram[datagramLength - 1];
on last method, you will get that crc
value. Look at this:
#include <stdio.h>
#include <stdint.h>
uint8_t swuart_calcCRC (uint8_t * datagram, uint8_t datagramLength) {
int i, j;
uint8_t *crc = datagram + (datagramLength - 1); // CRC located in last byte of message
uint8_t currentByte;
*crc = 0;
for (i = 0; i < (datagramLength - 1); i++) { // Execute for all bytes of a message
currentByte = datagram[i]; // Retrieve a byte to be sent from Array
for (j = 0; j < 8; j++) {
if ((*crc >> 7) ^ (currentByte & 0x01)) { // update CRC based result of XOR operation
*crc = (*crc << 1) ^ 0x07;
}
else {
*crc = (*crc << 1);
}
currentByte = currentByte >> 1;
} // for CRC bit
} // for message byte
return datagram[datagramLength - 1];
}
int main () {
uint8_t datagram1[] = { 0x05, 0x00, 0x00, 0x00 };
uint8_t datagram2[] = { 0x05, 0x00, 0x06, 0x00 };
uint8_t length = 4;
uint8_t crc1 = swuart_calcCRC (datagram1, length);
printf ("crc1: %02X\n", crc1);
uint8_t crc2 = swuart_calcCRC (datagram2, length);
printf ("crc2: %02X\n", crc2);
return 0;
}
Result:
crc1: 48
crc2: 6F