Skip to main content
amarburg
Associate
January 21, 2020
Question

Resetting SCLK polarity after changing SPI mode through HAL (STM32F7xx)

  • January 21, 2020
  • 4 replies
  • 2462 views

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)

This topic has been closed for replies.

4 replies

Visitor II
November 5, 2020

Try to insert HAL_SPI_DeInit(&SpiHandle) before SpiHandle.Init.CLKPolarity = SPI_POLARITY_LOW;

Visitor II
November 11, 2020

Discard this advice. See the really working code in my separate comment.

Wdong.2
Associate
November 9, 2020

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

Visitor II
November 11, 2020

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 */

}