Skip to main content
MSavc
Associate
July 25, 2018
Question

STM32F7 SPI send/receive issue

  • July 25, 2018
  • 12 replies
  • 2306 views

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?

    This topic has been closed for replies.

    12 replies

    T J
    Senior III
    August 1, 2018

    how are you reading the receive packets ?

    David Littell
    Senior II
    August 1, 2018

    Reflection or some other signal quality problem on the SPI clock, maybe?

    MSavc
    MSavcAuthor
    Associate
    August 2, 2018

    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;
    	}

    David Littell
    Senior II
    August 2, 2018

    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().

    MSavc
    MSavcAuthor
    Associate
    August 2, 2018

    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.

    David Littell
    Senior II
    August 2, 2018

    OK, are you flushing/invalidating the data cache as needed (or are the buffers in non-cached memory)?

    MSavc
    MSavcAuthor
    Associate
    August 2, 2018

    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.

    David Littell
    Senior II
    August 2, 2018

    OK, next guess! :grinning_face:

    Is BUFF_SIZE evenly divisible by 4? If not, try making it so.

    MSavc
    MSavcAuthor
    Associate
    August 3, 2018
    #define BUFF_SIZE 128

    Yes, it`s divisible by 4.

    David Littell
    Senior II
    August 3, 2018

    What do your SPI_HandleTypeDef and DMA_HandleTypeDef structure initializations look like?