2018-07-25 04:54 AM
Hi!
I have an issue with SPI communication on STM32F746 MCU.
I have two MCU connected via SPI on my board in 16 bit mode, both MCU`s are STM32F746. At start point it seems normal, but after some time it starts to drop packeges cause CRC32 check(CRC32 computes on CRC module by hardware) not solved.
When i debugging dropped packets, i`ve see a repetition of pervious byte in next cell of receive buffer(for debugging, all cellc in buffer are initialize with unique value).
It not deterministically, so most part of packets are normal, but i wanna solve this "bug".
Can somebody help me?
2018-08-01 03:00 AM
how are you reading the receive packets ?
2018-08-01 06:28 AM
Reflection or some other signal quality problem on the SPI clock, maybe?
2018-08-02 01:26 AM
Both MCU`s placed on one PCB, trace between them is very short, so, i think it`s not a clock. Same problem i have with another projects with f746 MCU, where i`m using another PCB`s.
I`m send and receive packets with HAL_SPI_TransmitReceive_DMA function, here is the code:
//transmit buff by timer irq
void TIM8_TRG_COM_TIM14_IRQHandler(void)
{
/* USER CODE BEGIN TIM8_TRG_COM_TIM14_IRQn 0 */
/* USER CODE END TIM8_TRG_COM_TIM14_IRQn 0 */
HAL_TIM_IRQHandler(&htim14);
/* USER CODE BEGIN TIM8_TRG_COM_TIM14_IRQn 1 */
extern uint16_t recv_data_buff[BUFF_SIZE], transmit_data_buff[BUFF_SIZE];
extern uint16_t pack_cnt;
extern CRC_HandleTypeDef hcrc;
extern SPI_HandleTypeDef hspi5;
extern uint8_t received;
if(received)
{
received = 0;
//uint32_t
HAL_GPIO_WritePin(CPU_SPI_RXTXLEVEL_GPIO_Port, CPU_SPI_RXTXLEVEL_Pin, SET);
HAL_GPIO_WritePin(CPU_SPI_RXTXLEVEL_GPIO_Port, CPU_SPI_RXTXLEVEL_Pin, RESET);
for(uint8_t i = 0; i < 100; i++)
{
if(HAL_GPIO_ReadPin(CPU_RXTXCONTROL_GPIO_Port, CPU_RXTXCONTROL_Pin) == RESET)
{
transmit_data_buff[start_marker] = START_MARKER_VALUE;
transmit_data_buff[packet_cnt] = pack_cnt++;
transmit_data_buff[service_word] = SERVICE_WORD_VALUE;
uint16_t p = 0x0000;
for(uint16_t i = data; i < checksum; i++)
transmit_data_buff[i] = p++;
uint16_t * pbuff = &transmit_data_buff[1];
uint32_t chksum_buff[30];
for(uint8_t i = 0; i < 30; i++)
{
chksum_buff[i] = 0;
for(uint8_t j = 0; j < 2; j ++)
{
chksum_buff[i] |= (uint32_t) (*pbuff << (16U *(1 - j)));
pbuff++;
}
}
uint32_t crc32 = HAL_CRC_Calculate(&hcrc, (uint32_t *)chksum_buff, 30);
transmit_data_buff[checksum] = (uint16_t)(crc32 >> 16U);
transmit_data_buff[checksum + 1] = (uint16_t) crc32;
transmit_data_buff[finish_marker] = FINISH_MARKER_VALUE;
for(uint8_t i = 0; i < 64; i++)
transmit_data_buff[i + 64] = transmit_data_buff[i];
//HAL_SPI_Transmit_DMA(&hspi5, (uint8_t *) transmit_data_buff, BUFF_SIZE);
HAL_GPIO_WritePin(CPU_SPI_CS_GPIO_Port, CPU_SPI_CS_Pin, RESET);
HAL_SPI_TransmitReceive_DMA(&hspi5, (uint8_t *) transmit_data_buff, (uint8_t *) recv_data_buff, BUFF_SIZE);
//HAL_SPI_TransmitReceive_IT(&hspi5, (uint8_t *) transmit_data_buff, (uint8_t *) recv_data_buff, BUFF_SIZE);
break;
}
}
}
/* USER CODE END TIM8_TRG_COM_TIM14_IRQn 1 */
}
//check crc and markers on DMA callback
void HAL_SPI_TxRxCpltCallback(SPI_HandleTypeDef *hspi)
{
/* Prevent unused argument(s) compilation warning */
//UNUSED(hspi);
if (hspi->Instance == SPIx){
uint32_t chksum_buff[30];
uint16_t * pbuff = &recv_data_buff[1];
//if(recv_data_buff[0] != (uint16_t)0x6801)
//start_bit_check++;
packs_summary++;
if((recv_data_buff[64] != (uint16_t)0x6801) && (recv_data_buff[0] != (uint16_t)0x6801))
start_bit_check++;
for(uint8_t i = 0; i < 30; i++)
{
chksum_buff[i] = 0;
for(uint8_t j = 0; j < 2; j ++)
{
chksum_buff[i] |= (uint32_t) (*pbuff << (16U *(1 - j)));
pbuff++;
}
}
uint32_t chksum;
chksum = ((uint32_t)recv_data_buff[checksum] << 16U) | (uint32_t)recv_data_buff[checksum + 1];
uint32_t crc32;
crc32 = HAL_CRC_Calculate(&hcrc, (uint32_t *)chksum_buff, 30);
if (chksum == crc32)
received_packet_cnt++;
else
{
pbuff = &recv_data_buff[65];
//packs_summary++;
for(uint8_t i = 0; i < 30; i++)
{
chksum_buff[i] = 0;
for(uint8_t j = 0; j < 2; j ++)
{
chksum_buff[i] |= (uint32_t) (*pbuff << (16U *(1 - j)));
pbuff++;
}
}
uint32_t chksum = ((uint32_t)recv_data_buff[checksum + 64] << 16U) | (uint32_t) recv_data_buff[checksum + 65];
uint32_t crc32 = HAL_CRC_Calculate(&hcrc, (uint32_t *)chksum_buff, 30);
if (chksum == crc32)
received_packet_cnt++;
else
packs_dropped++;
}
HAL_GPIO_WritePin(CPU_SPI_CS_GPIO_Port, CPU_SPI_CS_Pin, SET);
HAL_GPIO_WritePin(CPU_SPI_RXTXLEVEL_GPIO_Port, CPU_SPI_RXTXLEVEL_Pin, SET);
//HAL_GPIO_TogglePin(CPU_LED1_GPIO_Port, CPU_LED1_Pin);
//HAL_SPI_DeInit(&hspi5);
//HAL_SPI_Init(&hspi5);
//HAL_Delay(1);
received = 1;
}
2018-08-02 05:41 AM
Hopefully this will help: When the CRC module is configured to produce a 32-bit CRC it expects to run over an integral number of 32-bit words. So I had to ensure the byte count passed to HAL_CRC_Calculate() was increased to an evenly divisible-by-4 boundary and the memory in the buffer beyond the "real" data was cleared.
One other thing I did was use __HAL_CRC_INITIALCRCVALUE_CONFIG() before calling HAL_CRC_Calculate().
2018-08-02 05:55 AM
Problem not with CRC: when i debugging corrupted received packet, i see corrupted data in buffer before HAL_CRC_Calculate(), CRC working fine for me. It`s trouble with SPI module or with DMA.
2018-08-02 05:58 AM
OK, are you flushing/invalidating the data cache as needed (or are the buffers in non-cached memory)?
2018-08-02 07:50 AM
I`m not flushing or invalidating data in buffers, but every packet have same data (i`m use it for debugging), so they are doesn`t needed to flush or invalidate because data is the same in each packet.
2018-08-02 09:30 AM
OK, next guess! :grinning_face:
Is BUFF_SIZE evenly divisible by 4? If not, try making it so.
2018-08-03 12:20 AM
#define BUFF_SIZE 128
Yes, it`s divisible by 4.