2020-01-21 09:30 AM
We're developing for the STM32F767, primarily using the HAL. We have devices on the SPI bus which require different timing clock polarities. Re-configuring the SPI hardware through repeated calls to HAL_SPI_Init works, however, the actual hardware state of the SCLK line does not seem to change during HAL_SPI_Init .... we are only able to get it to reset by clocking out a byte. What's the "right" way to force the SCLK line to the correct polarity?
In pseudo-code, this works, but is obviously ugly:
SpiHandle.Init.CLKPolarity = SPI_POLARITY_HIGH;
HAL_SPI_Init(&SpiHandle);
// Expect SCLK to be high
// (successfully communicate with devices expecting SCLK to idle high)
SpiHandle.Init.CLKPolarity = SPI_POLARITY_LOW;
HAL_SPI_Init(&SpiHandle);
// !! Expect SCLK to be low, it is actually still high
// Sending a "null" transmission resets clock
char txBuffer[1] = '\0';
HAL_SPI_Transmit(&SpiHandle, txBuffer, 1, SPITimeout );
// !!! SCLK is now low
// (successful communication with devices expecting SCLK to idle low)
2020-11-05 02:21 AM
Try to insert HAL_SPI_DeInit(&SpiHandle) before SpiHandle.Init.CLKPolarity = SPI_POLARITY_LOW;
2020-11-09 07:33 AM
1�?you can change spi sck pull mode with the cpol ,pull up with cpol=1,pull down with cpol=0
2�?another solution,you can set the master_keep_io_state bit
2020-11-11 12:16 AM
The following endless cycle content is proven with STM32F405ZGT6:
// Start of cyclical code
SPI_ChangeParameters(&hspi3, SPI_DATASIZE_8BIT, SPI_POLARITY_HIGH, SPI_PHASE_2EDGE, 8);
// Insert here some tiny magic delay! HAL_Delay(2) is even overkill
// Insert here your activate CS
// Insert here your chip activity: HAL_SPI_TransmitReceive_IT() or another function
// Wait until HAL_SPI_GetState(&hspi3) == HAL_SPI_STATE_READY
// Insert here your deactivate CS
SPI_ChangeParameters(&hspi3, SPI_DATASIZE_16BIT, SPI_POLARITY_HIGH, SPI_PHASE_2EDGE, 4);
// Insert here some tiny magic delay! HAL_Delay(2) is even overkill
// Insert here your activate CS
// Insert here your chip activity: HAL_SPI_TransmitReceive_IT() or another function
// Wait until HAL_SPI_GetState(&hspi3) == HAL_SPI_STATE_READY
// Insert here your deactivate CS
SPI_ChangeParameters(&hspi3, SPI_DATASIZE_16BIT, SPI_POLARITY_LOW, SPI_PHASE_2EDGE, 4);
// Insert here some tiny magic delay! HAL_Delay(2) is even overkill
// Insert here your activate CS
// Insert here your chip activity: HAL_SPI_TransmitReceive_IT() or another function
// Wait until HAL_SPI_GetState(&hspi3) == HAL_SPI_STATE_READY
// Insert here your deactivate CS
// End of cyclical code
//---------------
int SPI_ChangeParameters(SPI_HandleTypeDef* hspi, uint32_t dataSize, uint32_t clkPolarity, uint32_t clkPhase, uint32_t baudRatePrescaler)
{
__HAL_SPI_DISABLE(hspi);
hspi->Init.DataSize = dataSize;
hspi->Init.CLKPolarity = clkPolarity;
hspi->Init.CLKPhase = clkPhase;
hspi->Init.BaudRatePrescaler = baudRatePrescaler;
if (HAL_SPI_Init(hspi) != HAL_OK)
{
return FALSE;
}
/* Enable SPI peripheral so SPI phase and polarity are changed before SPI peripheral in selected (otherwise trouble!!!) */
__HAL_SPI_ENABLE(hspi);
return TRUE;
}
//--------------- STM32CubeMX: Initialization of Spi3 controller with my addition
static void MX_SPI3_Init(void)
{
/* USER CODE BEGIN SPI3_Init 0 */
/* USER CODE END SPI3_Init 0 */
/* USER CODE BEGIN SPI3_Init 1 */
/* USER CODE END SPI3_Init 1 */
/* SPI3 parameter configuration*/
hspi3.Instance = SPI3;
hspi3.Init.Mode = SPI_MODE_MASTER;
hspi3.Init.Direction = SPI_DIRECTION_2LINES;
hspi3.Init.DataSize = SPI_DATASIZE_8BIT;
hspi3.Init.CLKPolarity = SPI_POLARITY_HIGH;
hspi3.Init.CLKPhase = SPI_PHASE_2EDGE;
hspi3.Init.NSS = SPI_NSS_SOFT;
hspi3.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_8;
hspi3.Init.FirstBit = SPI_FIRSTBIT_MSB;
hspi3.Init.TIMode = SPI_TIMODE_DISABLE;
hspi3.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
hspi3.Init.CRCPolynomial = 10;
if (HAL_SPI_Init(&hspi3) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN SPI3_Init 2 */
// Enable SPI peripheral so SPI phase and polarity are changed before SPI peripheral in selected (otherwise trouble!!!)
__HAL_SPI_ENABLE(&hspi3);
/* USER CODE END SPI3_Init 2 */
}
2020-11-11 12:18 AM
Discard this advice. See the really working code in my separate comment.