cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F7 SPI Runtime OR Memory access problems

AWent
Associate III

Hi Community,

I have a STM32F769I as a SPI slave.

I want to receive up to 6kByte data in 244 Byte packets (consequently up to 25 SPI packets á 244 Byte).

I am using the HAL_SPI_TxRxCpltCallback function. This function will be called after every 244 Byte packet; and stores the received data in a 6 kByte data buffer. After all data has been received a flag will be set to activate a print function in the main.

For now, the 6 kByte (dummy) data frames will be send every 2 seconds by the SPI master.

However, the STM32 sometimes misses SPI packets and consequently mess up the data.

As soon as I exceed an amount of data (4392 Byte = 18 packets á 244 bytes) the STM misses packets in a transaction and thus the data will only be printed after every second transaction.

Furthermore, memory access problems occure every now and then ending up in the HardFault_handler.

I think, I am facing some timing problems due to interrupts as well as memory access problems.

Any suggestions?

13 REPLIES 13
AWent
Associate III

Sure, I can try that.

I am at 4MHz right now, and I can vary from 125kHz up to 8MHz....

AWent
Associate III

I tested from 125kHz up to 8MHz.

Except from the transfer speed, I could not identify any differences or abnormalities.

I used a Saleae Logic Pro 8 Analyzer which was able to detect and analyze the transfer at every configuation.

However, the problems at the STM32 stayed the same.

At some random point it looses a packet or some bits; which finally messes up the whole upcoming transactions.

A 6kByte transfer still won't work at all.

KnarfB
Principal III

Hmm. The following works reliably for me copy-free at 12 MBit/s on two Nucleo STM32F042K6 boards (transmit master + receive slave) with STM32CubeMX generated code skeleton:

Transmitter:

  while (1)
  {
    /* USER CODE END WHILE */
 
    /* USER CODE BEGIN 3 */
	  HAL_GPIO_WritePin( LD3_GPIO_Port, LD3_Pin, GPIO_PIN_SET );
	  HAL_StatusTypeDef status = HAL_SPI_Transmit_DMA( &hspi1, buffer, len );
	  if( status != HAL_OK ) {
		  Error_Handler();
	  }
	  HAL_GPIO_WritePin( LD3_GPIO_Port, LD3_Pin, GPIO_PIN_RESET );
	  HAL_Delay(100);
  }

Receiver:

char buffer[512*8];
int i=1;
volatile int done = 0;
 
void HAL_SPI_RxCpltCallback(SPI_HandleTypeDef *hspi)
{
	HAL_StatusTypeDef status = HAL_SPI_Receive_DMA( &hspi1, buffer+i*512, 512 );
	i++;
	if(i==8) {
		i=0;
		done = 1;
	}
}

and in main():

HAL_StatusTypeDef status = HAL_SPI_Receive_DMA( &hspi1, buffer, 512 );  // very first DMA
  for(;;) {
	  if(done) {
		  HAL_UART_Transmit( &huart2, buffer, sizeof(buffer), HAL_MAX_DELAY );
		  done=0;
	  }
  }

Frank

Now, from this code I understood how to implement the "pointer-shifting" for DMA ( buffer+i*512 ), thanks.

I updated my code now and got rid of the copying parts. Thus, my received data will be written in the frame_buffer immideately.

That works so far, but still does not solve the main problem that the devices hangs up.

@Frank Bauernoeppel: Is your setup still working if you increase the data amount? Up to e.g. 10, 12 or even 20 packets á 512 Byte?

The code you presented is sending 4096 Byte per transaction. At my setup that works for roughly 50 transaction till the systems hangy up.

As closer as I go towards the 6000 Bytes per transfer, the system hangs up earlier and earlier.