cancel
Showing results for 
Search instead for 
Did you mean: 

SPI: changing CPOL between transmissions

connoisseur_de_mimi
Associate II

I have 2 devices on my SPI bus that need different CPOL settings. both use CPHA = 0 and the SPI peripheral is configured to use Motorola frame format.

Communication works with both devices if their respective CPOL setting is set in CubeMX (and thus fixed at compile time), but I need to switch CPOL at runtime, so I tried to set and clear the CPOL bit in SPI CR1 before the transmission:

 

SET_BIT(hspi_->Instance->CR1, SPI_CR1_CPOL);

HAL_GPIO_WritePin(DAC_CS_GPIO_Port, DAC_CS_Pin, GPIO_PIN_RESET);
HAL_StatusTypeDef status = HAL_SPI_Transmit(hspi_, buf, sizeof(buf) / sizeof(buf[0]), 1000);  //single byte
if (status == HAL_OK)
	status = HAL_SPI_Transmit(hspi_, parameters, length, 1000);  //multiple bytes
CLEAR_BIT(hspi_->Instance->CR1, SPI_CR1_CPOL);

HAL_GPIO_WritePin(LCD_CS_GPIO_Port, LCD_CS_Pin, GPIO_PIN_RESET);
//...

 

 this works to change CPOL to what the devices need, but whenever CPOL changes, the first byte transmitted is 0x00 and only 7 clock pulses are generated:

connoisseur_de_mimi_1-1715784526043.png

(the lines mark the first clock edges of bytes 2, 3 and 4, respectively. the 7 clocks before that are where I would expect byte 1. manually decoding these bytes show that the are indeed what I wanted to send)

subsequent transfers work just fine:

connoisseur_de_mimi_2-1715784647618.png

(the second transmission sends different, but correct data)

RM0434 35.6.1 states that

connoisseur_de_mimi_3-1715784945416.png

no transmission is ongoing when I change the bit, I'd expect the above to work as intended.

 

I have tried enabling and disabling the SPI peripheral just before or after changing CPOL, but this has not changed the result.

 

while ((hspi_->Instance->SR & SPI_SR_FTLVL) && (hspi_->Instance->SR & SPI_SR_BSY))
	;

CLEAR_BIT(hspi_->Instance->CR1, SPI_CR1_SPE);    //disable SPI

while (hspi_->Instance->SR & SPI_SR_FRLVL)
	;

SET_BIT(hspi_->Instance->CR1, SPI_CR1_SPE);    //enable SPI

 

 

Am I doing something obviously wrong here?

1 ACCEPTED SOLUTION

Accepted Solutions
connoisseur_de_mimi
Associate II

found this thread with a fix that works for me: https://community.st.com/t5/stm32-mcus-products/stm32f4-spi-clock-polarity-how-to-change-it-dynamically/td-p/529573

it seems SPI must be disabled before CPOL is changed and enabled afterwards.

View solution in original post

1 REPLY 1
connoisseur_de_mimi
Associate II

found this thread with a fix that works for me: https://community.st.com/t5/stm32-mcus-products/stm32f4-spi-clock-polarity-how-to-change-it-dynamically/td-p/529573

it seems SPI must be disabled before CPOL is changed and enabled afterwards.