cancel
Showing results for 
Search instead for 
Did you mean: 

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

shravan
Associate II
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

7 REPLIES 7
Tilen MAJERLE
ST Employee
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

S.Ma
Principal
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.

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.

Posted on August 09, 2017 at 15:42

Hi Tilen,

I have a query. Correct me if I am wrong. In stm32 

CPOL = 0, CPHA = 0(1EDGE) ==> MODE0

CPOL = 0, CPHA = 1(1EDGE) ==> MODE1

CPOL = 1, CPHA = 0(2EDGE) ==> MODE2

CPOL = 1, CPHA = 1(2EDGE) ==> MODE3

I have referred a general document for understanding this MODE's.

Posted on August 10, 2017 at 09:44

Hello

p.Shravan

‌,

Your matching is correct. However, this does not apply only to STM32 but to SPI peripheral in general.

Best regards,

Tilen

Bruno Conceição
Associate II

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

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.