Farynx
Farynx

Reputation: 113

Correct way to deactivate SPI in half-duplex/simplex mode STM32F4

I am trying to change a STM32F4 from slave to master after certain amount of time, send a message as master, and go back to slave. I found out that configuring the SPI as slave_rxonly and enabling the SPI will cause the clock to unexpectedly sent a clock as soon as I configure the device back to master. Without me sending any data. I assume its becasue I am either initializing the peripheral wrong or deinitializing it incorrectly

This is my main loop.

  while (1)
  {
    /* USER CODE END WHILE */
 
    /* USER CODE BEGIN 3 */
      MX_SPI1_Init(); /* This configures master */
      HAL_Delay(10);
 
      sendHelloWorld();
      configSlave(); /* Configures slave mode */
      __HAL_SPI_ENABLE(&hspi1); /* Enabling the device in this mode generates a continous clock during master init */
 
      HAL_Delay(100);
 
      HAL_SPI_DeInit(&hspi1);   /* Disables SPI and de-initializes the peripheral */
  }

My master config:

  hspi1.Instance = SPI1;
  hspi1.Init.Mode = SPI_MODE_MASTER;
  hspi1.Init.Direction = SPI_DIRECTION_2LINES;
  hspi1.Init.DataSize = SPI_DATASIZE_8BIT;
  hspi1.Init.CLKPolarity = SPI_POLARITY_LOW;
  hspi1.Init.CLKPhase = SPI_PHASE_1EDGE;
  hspi1.Init.NSS = SPI_NSS_SOFT;
  hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_256;
  hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;
  hspi1.Init.TIMode = SPI_TIMODE_DISABLE;
  hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
  hspi1.Init.CRCPolynomial = 10;
  if (HAL_SPI_Init(&hspi1) != HAL_OK)
  {
    Error_Handler();
  }

My slave config:

if(HAL_SPI_DeInit(&hspi1) != HAL_ERROR)
{
       /* SPI1 parameter configuration*/
    hspi1.Instance = SPI1;
    hspi1.Init.Mode = SPI_MODE_SLAVE;
    hspi1.Init.Direction = SPI_DIRECTION_2LINES_RXONLY;
    hspi1.Init.DataSize = SPI_DATASIZE_8BIT;
    hspi1.Init.CLKPolarity = SPI_POLARITY_LOW;
    hspi1.Init.CLKPhase = SPI_PHASE_1EDGE;
    hspi1.Init.NSS = SPI_NSS_SOFT;
    hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;
    hspi1.Init.TIMode = SPI_TIMODE_DISABLE;
    hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
    hspi1.Init.CRCPolynomial = 10;
 
    if (HAL_SPI_Init(&hspi1) != HAL_OK)
    {
        Error_Handler();
    }
 
}

and this is the waveform from my logic analyzer. As soon as I run the function MX_SPI1_Init() after enabling the SPI as a Slave the clock is generated. Orange is the clock and as you can see - from the 10ms delay -it gets enabled right after the initialization as master. enter image description here

Any thoughts? I've been fighting with this issue for over a week, and tried many things

Upvotes: 1

Views: 1123

Answers (1)

Tom V
Tom V

Reputation: 5510

Possibly the rubbish HAL function accidentally changes temporarily to master rx-only. Various HAL functions are naive in the order they write to registers and create glitches like this. Try calling HAL_SPI_DeInit before reconfiguring. Alternatively just ditch the HAL altogether.

Master RX-only always has to blindly output the clock. If you want to control when the clock is sent then use master tx and rx mode, and then write the same amount of dummy data that you want to read. If you want MOSI to remain tristate and not send the dummy data then you could change the pin to GPIO mode while you do this.

Upvotes: 3

Related Questions