Corrupted data via SPI_HAL_Receive in STM32F407
- June 16, 2021
- 2 replies
- 1333 views
Dear friends, I need your help with the issue of data corruption when reading the data on SPI bus in STM32F407. I'm using 24 channels of temperature measurement (slaves) with one master STM32F407. 12 channels are connected to SPI1, other 12 channels - to SPI2.
Configuration of SPIs was done by CubeMX:
hspi2.Instance = SPI2;
hspi2.Init.Mode = SPI_MODE_MASTER;
hspi2.Init.Direction = SPI_DIRECTION_2LINES;
hspi2.Init.DataSize = SPI_DATASIZE_8BIT;
hspi2.Init.CLKPolarity = SPI_POLARITY_LOW;
hspi2.Init.CLKPhase = SPI_PHASE_1EDGE;
hspi2.Init.NSS = SPI_NSS_SOFT;
hspi2.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_16;
hspi2.Init.FirstBit = SPI_FIRSTBIT_MSB;
hspi2.Init.TIMode = SPI_TIMODE_DISABLE;
hspi2.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
hspi2.Init.CRCPolynomial = 10;
hspi3.Instance = SPI3;
hspi3.Init.Mode = SPI_MODE_MASTER;
hspi3.Init.Direction = SPI_DIRECTION_2LINES;
hspi3.Init.DataSize = SPI_DATASIZE_8BIT;
hspi3.Init.CLKPolarity = SPI_POLARITY_LOW;
hspi3.Init.CLKPhase = SPI_PHASE_2EDGE;
hspi3.Init.NSS = SPI_NSS_SOFT;
hspi3.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_16;
hspi3.Init.FirstBit = SPI_FIRSTBIT_MSB;
hspi3.Init.TIMode = SPI_TIMODE_DISABLE;
hspi3.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
hspi3.Init.CRCPolynomial = 10;SPI CLK frequency is around 2.7 MHz. MAX31856 has maximum SPI clock at 5 MHz, so it is ok.
Code for reading the temperature:
uint8_t byte_addr = 0x0C;
uint8_t byte_rec_1[3] = {0};
uint8_t byte_rec_2[3] = {0};
for(temp_sens_t i = TEMP_SENS_1; i <= TEMP_SENS_12; i++)
{
chip_sel_temp_sens(11-i, ON);
HAL_SPI_Transmit(&hspi1, &byte_addr, 1, 0xFFFF);
HAL_SPI_Receive(&hspi1, byte_rec_1, 3, 0xFFFF);
chip_sel_temp_sens(11-i, OFF);
Temp_arr[11-i] = (int32_t)byte_rec_1[0] << 16;
Temp_arr[11-i] |= (uint32_t)byte_rec_1[1] << 8;
Temp_arr[11-i] |= (uint32_t)byte_rec_1[2];
chip_sel_temp_sens(11-i, ON);
HAL_SPI_Transmit(&hspi3, &byte_addr, 1, 0xFFFF);
HAL_SPI_Receive(&hspi3, byte_rec_2, 3, 0xFFFF);
chip_sel_temp_sens(11-i, OFF);
Temp_arr[11-i+12] = (int32_t)byte_rec_2[0] << 16;
Temp_arr[11-i+12] |= (uint32_t)byte_rec_2[1] << 8;
Temp_arr[11-i+12] |= (uint32_t)byte_rec_2[2];
}
}Everything works fine for all channels, I can measure and control the temperature for all channels. But... Ocidentially, on some channels the data become incorrect. The analysis of the incorrect measured data and real data is in the attached file. I have connected two channels in parallel with one thermocouple, so it was possible to measure the same values for two separated MAX31856 ICs. So, as you can see, the first byte is read ok, but the second byte is incorrect for values lower than 128. Look like some higer bits are read as "1" instead of "0" - for the range 255...128 everything is correct, for the range 127...64 the eighth bit is wrong (1 instead of 0), for the range 63...32 - 8th and 7th bits are wrong, for the range 31...16 - 8th, 7th and 6th bits are wrong, etc.
I have analyzed the raw data on SPI bus by means of Logical Analyzer - the data is ok. In the Atollic I have set breakpoint on chip_sel_temp_sens(11-i, ON); line, where the data was just read by HAL function and that data is wrong...
As I said, such error is not regular - everything is ok in most cases, but, yesterday the 6th channel had such problem, today - 2nd channel (whereas 6th is ok).
Could you be so kind to help me with this issue?
