cancel
Showing results for 
Search instead for 
Did you mean: 

Unstable SPI Slave

Nikolaj_TL
Associate III

I have a custom board with a STMWB55 (master) and a STM32F031 (slave). They communicate over SPI using DMA. Unforturenately there are communication problems.

 

In order to identify the problem I have simplified the setup. I have used a ST NUCLEO-F031K6 and a ST NUCLEO-WB55 board to test the communication (SCLK, MISO & MOSI are used, 250kHz clk freq). Both use SPI example provided from ST (from STM32Cube_FW_F0_V1.11.5 and STM32Cube_FW_WB_V1.19.0)
The slave is setup to use interrupt instead of DMA to get the simplest setup. The only modification made from the original example is that the Master sends 8x bytes messages and the slave echoes what it receives - in order to test the slave device. Approximately 200 bits out of 10kB from the slave are errorprone. The communication is monitored using a logic analyser and the data is analysed with python.

 

Is this success/failure rate expected? Is this something that you have come across before? Do you have suggestions for solutions?

 

Here is an example of an error from the test:

Nikolaj_TL_0-1723122821437.png

(the slave actually echoes the message received +1, in order to easily compare the messages)

12 REPLIES 12
Nikolaj_TL
Associate III

I too am conviced that the problem lies in the slave code. There is definitely something about the first byte in the second word that might unveil the cause of the problem.

Below I have shared some of the code, the full project is attached to the post. As mentioned before the project is based on the example project from ST only with minor changes:
STM32Cube_FW_F0_V1.11.5\Projects\STM32F031K6-Nucleo\Examples\SPI\SPI_FullDuplex_ComIT

 

 

int main(void)
{
  HAL_Init();
  SystemClock_Config();   /* Configure the system clock to 48 MHz */

  /* Set the SPI parameters */
  SpiHandle.Instance               = SPIx;
  SpiHandle.Init.Mode              = SPI_MODE_SLAVE;
  SpiHandle.Init.Direction         = SPI_DIRECTION_2LINES;
  SpiHandle.Init.CLKPhase          = SPI_PHASE_1EDGE;
  SpiHandle.Init.CLKPolarity       = SPI_POLARITY_LOW;
  SpiHandle.Init.DataSize          = SPI_DATASIZE_8BIT;
  SpiHandle.Init.FirstBit          = SPI_FIRSTBIT_MSB;
  SpiHandle.Init.TIMode            = SPI_TIMODE_DISABLE;
  SpiHandle.Init.CRCCalculation    = SPI_CRCCALCULATION_DISABLE;
  SpiHandle.Init.CRCPolynomial     = 7;
  SpiHandle.Init.CRCLength         = SPI_CRC_LENGTH_8BIT;
  SpiHandle.Init.NSS               = SPI_NSS_HARD_INPUT;	//SPI_NSS_SOFT
  SpiHandle.Init.NSSPMode          = SPI_NSS_PULSE_DISABLE;

  if(HAL_SPI_Init(&SpiHandle) != HAL_OK)  {
    Error_Handler();     /* Initialization Error */
  }

  if(HAL_SPI_TransmitReceive_IT(&SpiHandle, (uint8_t*)aTxBuffer, (uint8_t *)aRxBuffer, BUFFERSIZE) != HAL_OK)  {
    Error_Handler();     /* Transfer error in transmission process */
  }

  /* Infinite loop */
  while (1)
  {  }
}

 

 

void HAL_SPI_TxRxCpltCallback(SPI_HandleTypeDef *hspi) {
	HAL_GPIO_TogglePin(DEBUG_GPIO_PORT, DEBUG_PIN);	/* Debug Pin */

	/* Clear Buffer */
	memset(aTxBuffer, 0, BUFFERSIZE);

	for(uint8_t i=0; i<BUFFERSIZE; i++) {
		aTxBuffer[i] = i+1;
	}

	HAL_SPI_TransmitReceive_IT(&SpiHandle, (uint8_t*)aTxBuffer, (uint8_t *)aRxBuffer, BUFFERSIZE);
	HAL_GPIO_TogglePin(DEBUG_GPIO_PORT, DEBUG_PIN); 	/* Debug Pin */
}

 

 

 

I took a look. Pretty simple, that should be working.

Only thing I can think of is a signal integrity issue, but your scope plots looks good, and the speed is slow.

Perhaps do something in HAL_SPI_ErrorCallback like toggle a pin so you know if it is detecting errors. Could be silently falling through.

That's all I got. Let us know if you solve it.

If you feel a post has answered your question, please click "Accept as Solution".
Nikolaj_TL
Associate III

I have set HAL_SPI_ErrorCallback to abort the transaction and signal on the Debug Pin. If it is hit no more transaction should be sent on MISO, as no new transfers are setup. 
After testing I can tell that the ErrorCallback is not called.

 

void HAL_SPI_ErrorCallback(SPI_HandleTypeDef *hspi)
{
  HAL_SPI_Abort(&SpiHandle);

  HAL_GPIO_TogglePin(DEBUG_GPIO_PORT, DEBUG_PIN); 	/* Debug Pin */
  HAL_Delay(100);
  HAL_GPIO_TogglePin(DEBUG_GPIO_PORT, DEBUG_PIN); 	/* Debug Pin */
}