2017-08-09 05:54 AM
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
2017-08-09 06:07 AM
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
2017-08-09 06:08 AM
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.
2017-08-09 08:14 AM
Thanks for the reply. I am making the necessary code changes now. I will test and get back to you.
2017-08-09 08:42 AM
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.
2017-08-10 02:44 AM
Hello
p.Shravan
,Your matching is correct. However, this does not apply only to STM32 but to SPI peripheral in general.
Best regards,
Tilen
2019-02-13 03:29 AM
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
2019-02-13 04:08 AM
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.