Impossible to check data for checksums using SPI
Hello,
I’m using two STM32 F4 boards to continuously send and receive data over SPI communication.
The first board is configured as the Master and only transfers data, while the second board is configured as the Slave and only receives data.
I have already manually checked my data using an oscilloscope and debug tools, and I receive exactly the data I transmit.
Now, I use a checksum to verify the integrity of my data. I have two problems:
On Master Side: The sprintf() function alters my data. When I use sprintf() on the Master side, I get different checksum values even if I transfer the same data. I resolved this problem by using memcpy(), but this complicates things when adding several parameter values into the buffer. Do you know a better solution if I want to do something like sprintf((char *)data_tx.msg, "IdFrame%d", IdFrame) where I can easily load the buffer with several parameters without altering it?
On Slave Side: I compute the checksums directly from the data buffer received from SPI without any manipulation, but I get different checksum values even I send the same data from the Master.
This is my code
/*
MASTER BOARD
*/
#define MSG_SIZE 300
struct Struct_Formatted_Data {
uint8_t msg[MSG_SIZE];
uint8_t checksum;
} __attribute__((packed));
struct Struct_Formatted_Data data_tx;
int size_of_struct_formatted_data = sizeof(struct Struct_Formatted_Data);
uint8_t calculate_checksum(uint8_t *data, size_t length) {
uint8_t checksum = 0;
for (size_t i = 0; i < length; i++) {
checksum += data[i];
}
return checksum;
}
int main(){
while(1){
sprintf((char *)data_tx.msg, "{\"DATA:{\"IdFrame\":5,\"AccVert\":5,\"Pression1\":5,\"Pression2\":5}}"); //This does not give the same checksums every iteration
memcpy(data_tx.msg, "{\"DATA:{\"IdFrame\":5,\"AccVert\":5,\"Pression1\":5,\"Pression2\":5}}", size_of_struct_formatted_data); //This does not give the same checksums every iteration
data_tx.checksum = calculate_checksum((uint8_t *)data_tx.msg, size_of_struct_formatted_data);
HAL_SPI_Transmit(&hspi1, (uint8_t *)&data_tx, size_of_struct_formatted_data, HAL_MAX_DELAY);
HAL_Delay(100);
}
}
/*
SLAVE BOARD
*/
volatile int msgFromSPI = 0;
#define MSG_SIZE 300
struct Struct_Formatted_Data {
uint8_t msg[MSG_SIZE];
uint8_t checksum;
} __attribute__((packed));
struct Struct_Formatted_Data data_tx;
int size_of_struct_formatted_data = sizeof(struct Struct_Formatted_Data);
uint8_t calculate_checksum(uint8_t *data, size_t length) {
uint8_t checksum = 0;
for (size_t i = 0; i < length; i++) {
checksum += data[i];
}
return checksum;
}
void HAL_SPI_RxCpltCallback(SPI_HandleTypeDef *hspi) {
if(hspi->Instance == hspi1.Instance && -1 == msgFromSPI) {
msgFromSPI = 1;
}
}
int main(){
while (1){
if (1 == msgFromSPI){ //Process the message
msgFromSPI = 0;
HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_7);
checksum_computed = calculate_checksum((uint8_t *)data_tx.msg, size_of_struct_formatted_data);
} else if (0 == msgFromSPI){
msgFromSPI = -1;
HAL_SPI_Receive_DMA(&hspi1, (uint8_t *)&data_tx, size_of_struct_formatted_data);
}
}
}
Thanks in advance for your help
