cancel
Showing results for 
Search instead for 
Did you mean: 

STM32 F0 SPI slave proper setup

Hello there,

So far I was designing only SPI masters in the STM32 MCU's- now I am doing a slave application and I am having problems.

First of, I was surprised that the STM32CubeF0-master repository doesn't consist of a single SPI slave example (please correct me if I am wrong).

I am trying to accomplish a simple functionality, that can be described as this:

  1. Use software nCS line,
  2. As soon as nCS goes low, turn on TxRx DMA transfer via HAL_SPI_TransmitReceive_DMA,
  3. Obtain and transfer at the same time the amount of bytes specified in the 4th parameter,
  4. On complete TxRx callback use the same function to enable DMA as in point 2,
  5. On nCS going high do HAL_SPI_DMAStop.

For some reason, my config only works without using HAL_SPI_DMAStop. I am not sure how is using it breaking the program flow. Here is my function for slave SPI DMA management:

rc_t spis_manage(spis_t* const spis, const bool on)
{
	UTIL_ASSERT(spis, e_rcPar);
	rc_t stat;
 
	if (HAL_SPI_STATE_READY != HAL_SPI_GetState(spis->hSpi))
	{
		if (e_rcOk != (stat = util_status(HAL_SPI_DMAStop(spis->hSpi))))
			return stat;
	}
 
	if (on)
	{
		stat = util_status(HAL_SPI_TransmitReceive_DMA(spis->hSpi,
				(uint8_t*)spis->bufTx, (uint8_t*)spis->bufRx, spis->size));
	}
 
	return stat;
}

It is used as follows;

  1. nCS goes low: spis_manage(x, TRUE);
  2. data transfer/ receive completed: spis_manage(x, TRUE),
  3. nCS goes high: spis_manage(x, false);

The incorrect behavior I am observing is that only the 1rst transfer is correct, i.e.

  1. nCS goes low,
  2. specified amount of bytes are transfered,
  3. nCS goes high.

After I repeat the operation, it takes 3 bytes more pushed from the SPI master to trigger the transfer/ receive complete callback, and I dont know why.

Is my program flow correct? I would appreciate all help.

11 REPLIES 11

Yes, this seems right... I find this very problematic. Lets say the master asserts the NSS line and the slave gets ready to receive/ transmit X data. Master the transfers less bytes than X and deasserts NSS. Slave is stuck with old data in TX FIFO buffer and cannot do anything about it.

This is why I always send a dummy byte first, to flush that residue... This is a very dirty workaround.

hi! on the M0 + core, it worked for me only like this:

HAL_SPI_DMAStop(&hspi1);
__HAL_RCC_SPI1_FORCE_RESET();
__HAL_RCC_SPI1_RELEASE_RESET();
MX_SPI1_Init();