cancel
Showing results for 
Search instead for 
Did you mean: 

What does the SPI SPE bit do?

RrW1
Associate III

I am new to the STM32 microcontrollers and I am experimenting with the SPI peripheral (interrupt mode, non DMA, slave) of the STM32F410. I noticed that the reference manual mentions the SPE bit (bit 6 of the SPIx CR1 register) but does not provide much explanation to it.

I was wondering what disabling the SPE bit does after each SPI transaction. Does disabling the SPI SPE bit (at each SPI CS rising interrupt) clears the Rx buffer and the Tx buffer? Is the code snippet below for operating the SPI at the GPIO interrupt side correct?

void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
   if(GPIO_Pin == SPI2_CS_Pin)
   {
      if(HAL_GPIO_ReadPin(SPI2_CS_GPIO_Port, SPI2_CS_Pin) == GPIO_PIN_RESET)
      {
         /* SPI CS Falling Edge Interrupt Handler */
 
         /* Enable SPI2 SPE bit to listen to master device for SPI byte */
         SPI2->CR1 |= (0x1 << 6);
 
         /* Exchange byte with master device and do further processing in HAL_SPI_TxRxCpltCallback and main loop */
         HAL_SPI_TransmitReceive_IT(&hspi2, (uint8_t*)dummybyte, (uint8_t*)pSpi2RxBuff, cSpi2RxLen);
 
         /* Disable SPI2 SPE bit inside main while loop */
      }
      else
      {
         /* SPI CS Rising Edge Interrupt Handler */
 
         /* Force disable SPI2 peripheral by disabling SPE bit */
         SPI2->CR1 &= ~(0x1 << 6);
 
	/* Clear Rx buffer if not empty by reading SPI2 Data Register and Status Register */
	if(SPI2->SR & SPI_FLAG_OVR || SPI2->SR & SPI_FLAG_RXNE)
	{
	    uint8_t temp = 0;
	    while(SPI2->SR & SPI_FLAG_RXNE)
	    {
	       temp = SPI2->DR;
	    }
	    temp = SPI2->SR;
         }
      }
   }
}

Thank you!

1 ACCEPTED SOLUTION

Accepted Solutions
TDK
Guru

The reference manual discusses it in the actual SPI section, but not so much in the register description.

In master mode, SPE enables the clock. In slave mode, it starts the peripheral listening to the lines.

Clearing SPE will abort any half-completed bytes, so you could use it to resync to the start of a transaction.

Your HAL code will likely not work great. HAL is built so you call HAL_SPI_* functions as opposed to direct register manipulation. For example, the SPI bit is set from within HAL_SPI_TransmitReceive_IT so there is no need to do it beforehand.

To abort a transfer, HAL_SPI_Abort_IT should be used which clears the SPE bit.

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

View solution in original post

4 REPLIES 4
TDK
Guru

The reference manual discusses it in the actual SPI section, but not so much in the register description.

In master mode, SPE enables the clock. In slave mode, it starts the peripheral listening to the lines.

Clearing SPE will abort any half-completed bytes, so you could use it to resync to the start of a transaction.

Your HAL code will likely not work great. HAL is built so you call HAL_SPI_* functions as opposed to direct register manipulation. For example, the SPI bit is set from within HAL_SPI_TransmitReceive_IT so there is no need to do it beforehand.

To abort a transfer, HAL_SPI_Abort_IT should be used which clears the SPE bit.

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

Thank you for the response! Thanks for the suggestion on HAL_SPI_Abort_IT too, it fixed an issue I was trying to solve!

Could you explain what you mean by aborting any half-completed bytes? Does that mean that both Tx and Rx communication is immediately cut off and both buffers are cleared on the slave device?

I also noticed from the logic analyzer waveforms that the MISO line looks different when comparing manually toggling the SPE bit and using HAL_SPI_Abort_IT. Currently, the configuration is CPOL = 0 and CPHA = 0. I noticed that if I manually disable the SPE bit using direct register manipulation, after each (correct multiple byte) SPI transaction, the MISO line goes to zero afterwards when manually clearing the SPE bit. When also manually setting the SPE bit high upon the CS falling edge interrupt, the MISO line goes high exactly before the SPI transaction occurs. When using the HAL_SPI_Abort_IT, the MISO line does not go to zero afterwards when HAL_SPI_Abort_IT was used. What could be the cause of this?

A half completed byte is when only 1-7 bits get sent so far, so they byte is not yet complete. This doesnt typically occur during transmission.
The MOSI line can be high or low depending on previously sent data. Unless there is a clock edge at an incorrect state, I wouldn't worry about it. There was a post which investigated this further, but it’s a non issue in my opinion.
If you feel a post has answered your question, please click "Accept as Solution".
RrW1
Associate III

Thanks for the explanation!