I've got to transmit 8 bytes of data through UART and the last byte itself is the CRC.
Calculating the CRC I understand, but what I'm not sure of it whether to calculate it based off of the original data I have before the transmission (where every byte is written LSB) or based off of the data being transmitted over UART (which is MSB).
I currently have data divided up into 1 byte blocks with a packed struct so that it's a bit easier for me to fiddle with the bytes.
typedef struct __attribute__((packed)){
uint8_t sync;
uint8_t slave_address;
uint8_t register_address;
uint8_t pwmA;
uint8_t dirA;
uint8_t pwmB;
uint8_t dirB;
uint8_t crc;
} packet_t;
packet_t new_sig = {
.sync = 0b10100000,
.slave_address = 0b10000000,
.register_address = 0b01000101,
.pwmA = 0b0,
.dirA = 0b0,
.pwmB = 0b0,
.dirB = 0b0,
.crc = 0b0,
};
All of these are written in LSB format. Sync, Slave and Register are constants in this example and most of the fiddling happens in the remaining spots. Pwm A and B can be from 0-255 and dir A and B are either a 0 or a 1.
Once I'm done fiddling with the data and I want to calculate the CRC. I use this function for it:
void CalcCRC(unsigned char* datagram, unsigned char datagramLength) {
int i,j;
unsigned char* crc = datagram + (datagramLength-1); // CRC located in last byte of message
unsigned char 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
new_sig.crc = *crc;
}
I got the function from the motor driver's datasheet (https://www.mouser.ee/datasheet/2/609/TMC7300_datasheet_rev1_08-3364772.pdf).
There might be more things wrong with my solution, but I assume my problem is with calculating the CRC. I've tried to switch the data from LSB to MSB for calculations, but it hasn't worked. Any advice?

Some details first:
Endian usually refers to the byte order.
Example: With BIG endian and with 2-byte
int16_t, the most significant byte is stored in the lowest address, followed by the the least significant byte in the next, higher address. LITTLE endian is the other way around. OP's code does not have multiple byte data, so this issue does not apply.With serial data transmission, there also is a byte order, or endian too. With BIG endian, the most significant byte is transmitted first, followed by the least. OP's code does not have multiple byte data, so this issue does not directly apply.
Within serial transmission, there is also bit endian, which bit is sent first, the most significant bit or least? Often this order is not seen by the programmer. UARTs send the least significant bit first.
OP's
CalcCRC()uses the bytes of the structure from the lowest addressed to the highest addressed byte. Within the algorithm, the bytes are used from least significant bit to most significant bit.If the serial transmission sends the lowest addressed bytes first, then the OP's
CalcCRC()matches that. If the serial transmission sends the highest addressed bytes first, then the OP'sCalcCRC()should change to calculated the CRC in that order.Why should CRC calculation match transmission order?
OP's
CalcCRC()calculates CRC after all the bytes are present in the data pointed to bydatagram. Higher performance code may calculate the CRC after each and every byte is sent/received. Thus the orders must match.At a hardware level, some CRC calculations are done 1-bit at a time, so the transmission must not only match the byte order, but also the bit order. This usually does not apply to UART serial transmissions.
Given OP's
CalcCRC()and sending by UART, I expect the proper calculation order is lowest addressed byte to most. This does not imply BIG or LITTLE endian multi-byte types, as that is a separate issue.Of course the important thing is that the transmitted and receiver agree.