Skip to main content
shravan
Associate II
August 9, 2017
Question

Can SPI clk polarity and clk phase be changed on the fly?

  • August 9, 2017
  • 4 replies
  • 3676 views
Posted on August 09, 2017 at 14:54

Hi,

I am using STM32F429 controller for one of my custom application. I need to perform SPI write in one of the four modes, specifically I have set CPOL = 0, CPHA =0. But during SPI read I need to changed the CPHA =1. My question is will that be possible to do on the fly? If yes, how? Any suggestions would help me a lot.

Regards,

Shravan

    This topic has been closed for replies.

    4 replies

    Tilen MAJERLE
    ST Employee
    August 9, 2017
    Posted on August 09, 2017 at 15:07

    Hello

    p.Shravan

    ‌,

    while SPI is enabled, you cannot change CPOL and CPHA values. To do your task, you should clock your SPI bytes, disable SPI, change CPOL and CPHA, enable SPI and again continue with SPI transfer.

    Quote from reference manual for STM32F4xx, RM0090:

    Prior to changing the CPOL/CPHA bits the SPI must be disabled by resetting the SPE bit

    Best regards,

    Tilen

    shravan
    shravanAuthor
    Associate II
    August 9, 2017
    Posted on August 09, 2017 at 15:14

    Thanks for the reply. I am making the necessary code changes now. I will test and get back to you.

    S.Ma
    Principal
    August 9, 2017
    Posted on August 09, 2017 at 15:08

    Besides the rule requirering to disable/enable the SPI, most of the SPI settings can be changed as long as SPI is resting (pause between bytes), which can be done by checking the BUSY bit (and DMA stopped if enabled). This is for example used when trying to generate SWD signals as the write and read bits are done in different clock edge to max out the setup time, hence max bit rate. Give it a try.

    Bruno Conceição
    Associate II
    February 13, 2019

    Hi Tilen,

    big fan here :D I've been following your work for some time and you're probably the reason for me to have chosen ST ecosystem. Regarding this situation, would this be a valid approach?

    HAL_StatusTypeDef Max31855SetSpiMode(SPI_HandleTypeDef *spiHandle)
    {
    	/*check for SPI Mode 1 (CPOL = 0, CPHA = 1)*/
    	if(spiHandle->Init.CLKPolarity != SPI_POLARITY_LOW || spiHandle->Init.CLKPhase != SPI_PHASE_2EDGE){
     
    		/*Prior to changing the CPOL/CPHA bits the SPI must be disabled by resetting the SPE bit*/
    		if(HAL_SPI_DeInit(spiHandle) != HAL_OK){
    			return(HAL_ERROR);
    		}
     
    		/*load configurations for SPI MODE 1 and re-enable SPI instance*/
    		spiHandle->Instance = SPI2;
    		spiHandle->Init.Mode = SPI_MODE_MASTER;
    		spiHandle->Init.Direction = SPI_DIRECTION_2LINES;
    		spiHandle->Init.DataSize = SPI_DATASIZE_8BIT;
    		spiHandle->Init.CLKPolarity = SPI_POLARITY_LOW;
    		spiHandle->Init.CLKPhase = SPI_PHASE_2EDGE;
    		spiHandle->Init.NSS = SPI_NSS_SOFT;
    		spiHandle->Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_4;
    		spiHandle->Init.FirstBit = SPI_FIRSTBIT_MSB;
    		spiHandle->Init.TIMode = SPI_TIMODE_DISABLE;
    		spiHandle->Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
    		spiHandle->Init.CRCPolynomial = 10;
    		if (HAL_SPI_Init(spiHandle) != HAL_OK)
    		{
    		 _Error_Handler(__FILE__, __LINE__);
    		}
    	}
     
    	return(HAL_OK);
    }

    or is there a more safe way for doing things?

    Thanks

    S.Ma
    Principal
    February 13, 2019

    As long as the SPI is idle (BUSY bit), most of the settings can be dynamically changed.

    This is a practical test, not guaranteed by the documentation. Used it to emulate SWD with SPI, clock phase change when SWDIO turns TX to RX during the turnaround bit.