2024-05-15 07:57 AM - edited 2024-05-15 08:00 AM
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:
(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:
(the second transmission sends different, but correct data)
RM0434 35.6.1 states that
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?
Solved! Go to Solution.
2024-05-15 08:42 AM
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.
2024-05-15 08:42 AM
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.