cancel
Showing results for 
Search instead for 
Did you mean: 

stm32g030 spi switch from HAL to LL not work

Hi :

I want to switch my project from HAL to LL because of flash size.

But SPI doesn't work after switching.

When I using HAL, the code below in main function works fine, uart will print OK.

When I switch to LL, it will print NG.

After switching to LL, I already add LL_SPI_Enable(SPI1); to MX_SPI1_Init function.

Cubemx project and all code is as attachment.

  uint8_t data = 0x80;

  CS_GPIO_Port->BSRR = (uint32_t)CS_Pin << 16u;

#ifdef USE_HAL_DRIVER
  HAL_SPI_Transmit(&hspi1, &data, 1, 100);
  HAL_SPI_Receive(&hspi1, &data, 1, 100);
#else
  while (!LL_SPI_IsActiveFlag_TXE(SPI1));
  LL_SPI_TransmitData8(SPI1, data);

  while (!LL_SPI_IsActiveFlag_TXE(SPI1));
  LL_SPI_TransmitData8(SPI1, 0xff);
  while (!LL_SPI_IsActiveFlag_RXNE(SPI1));
  data = LL_SPI_ReceiveData8(SPI1);
#endif

  CS_GPIO_Port->BSRR = CS_Pin;

  if(data == 0x05)
  {
      while (!LL_USART_IsActiveFlag_TXE(USART2));
      LL_USART_TransmitData8(USART2, 'O');
      while (!LL_USART_IsActiveFlag_TXE(USART2));
      LL_USART_TransmitData8(USART2, 'K');
  }
  else
  {
      while (!LL_USART_IsActiveFlag_TXE(USART2));
      LL_USART_TransmitData8(USART2, 'N');
      while (!LL_USART_IsActiveFlag_TXE(USART2));
      LL_USART_TransmitData8(USART2, 'G');
  }

MX_SPI1_Init:

/**
  * @brief SPI1 Initialization Function
  * @PAram None
  * @retval None
  */
static void MX_SPI1_Init(void)
{

  /* USER CODE BEGIN SPI1_Init 0 */

  /* USER CODE END SPI1_Init 0 */

  LL_SPI_InitTypeDef SPI_InitStruct = {0};

  LL_GPIO_InitTypeDef GPIO_InitStruct = {0};

  /* Peripheral clock enable */
  LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_SPI1);

  LL_IOP_GRP1_EnableClock(LL_IOP_GRP1_PERIPH_GPIOA);
  /**SPI1 GPIO Configuration
  PA5   ------> SPI1_SCK
  PA6   ------> SPI1_MISO
  PA7   ------> SPI1_MOSI
  */
  GPIO_InitStruct.Pin = SCL_Pin;
  GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE;
  GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_LOW;
  GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
  GPIO_InitStruct.Pull = LL_GPIO_PULL_NO;
  GPIO_InitStruct.Alternate = LL_GPIO_AF_0;
  LL_GPIO_Init(SCL_GPIO_Port, &GPIO_InitStruct);

  GPIO_InitStruct.Pin = SDO_Pin;
  GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE;
  GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_LOW;
  GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
  GPIO_InitStruct.Pull = LL_GPIO_PULL_NO;
  GPIO_InitStruct.Alternate = LL_GPIO_AF_0;
  LL_GPIO_Init(SDO_GPIO_Port, &GPIO_InitStruct);

  GPIO_InitStruct.Pin = SDA_Pin;
  GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE;
  GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_LOW;
  GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
  GPIO_InitStruct.Pull = LL_GPIO_PULL_NO;
  GPIO_InitStruct.Alternate = LL_GPIO_AF_0;
  LL_GPIO_Init(SDA_GPIO_Port, &GPIO_InitStruct);

  /* USER CODE BEGIN SPI1_Init 1 */

  /* USER CODE END SPI1_Init 1 */
  /* SPI1 parameter configuration*/
  SPI_InitStruct.TransferDirection = LL_SPI_FULL_DUPLEX;
  SPI_InitStruct.Mode = LL_SPI_MODE_MASTER;
  SPI_InitStruct.DataWidth = LL_SPI_DATAWIDTH_8BIT;
  SPI_InitStruct.ClockPolarity = LL_SPI_POLARITY_LOW;
  SPI_InitStruct.ClockPhase = LL_SPI_PHASE_1EDGE;
  SPI_InitStruct.NSS = LL_SPI_NSS_SOFT;
  SPI_InitStruct.BaudRate = LL_SPI_BAUDRATEPRESCALER_DIV4;
  SPI_InitStruct.BitOrder = LL_SPI_MSB_FIRST;
  SPI_InitStruct.CRCCalculation = LL_SPI_CRCCALCULATION_DISABLE;
  SPI_InitStruct.CRCPoly = 7;
  LL_SPI_Init(SPI1, &SPI_InitStruct);
  LL_SPI_SetStandard(SPI1, LL_SPI_PROTOCOL_MOTOROLA);
  LL_SPI_EnableNSSPulseMgt(SPI1);
  /* USER CODE BEGIN SPI1_Init 2 */
#ifndef USE_HAL_DRIVER
  LL_SPI_Enable(SPI1);
#endif
  /* USER CODE END SPI1_Init 2 */

}

 

1 ACCEPTED SOLUTION

Accepted Solutions

Hi :

To resolve this, every time you send data, you need to read it once.

So the code should be as follow:

#ifdef USE_HAL_DRIVER
  HAL_SPI_Transmit(&hspi1, &data, 1, 100);
  HAL_SPI_Receive(&hspi1, &data, 1, 100);
#else
  while (!LL_SPI_IsActiveFlag_TXE(SPI1));
  LL_SPI_TransmitData8(SPI1, data);
  /*you need read after send */
  while (!LL_SPI_IsActiveFlag_RXNE(SPI1));
  LL_SPI_ReceiveData8(SPI1);

  while (!LL_SPI_IsActiveFlag_TXE(SPI1));
  LL_SPI_TransmitData8(SPI1, 0xff);
  while (!LL_SPI_IsActiveFlag_RXNE(SPI1));
  data = LL_SPI_ReceiveData8(SPI1);
#endif

View solution in original post

4 REPLIES 4

Hi @Imen.D :

Can you help confirm this question?

Saket_Om
ST Employee

Hello @Zhou JianQiang 

What is not working exactly? Is it sending wrong data ? is the SPI clock generated ? 

Could you share the content of SR and CR register after SPI init and before executing LL_SPI_TransmitData8(SPI1, data);

Please refer to the example below as starting point :

STM32CubeG0/Projects/NUCLEO-G070RB/Examples_LL/SPI at master · STMicroelectronics/STM32CubeG0 · GitHub

 

To give better visibility on the answered topics, please click on "Accept as Solution" on the reply which solved your issue or answered your question.
Saket_Om
Andrew Neil
Super User

@Zhou JianQiang wrote:

SPI doesn't work after switching.


That's uninformative.

What testing/investigation/debugging have you done to find what's going on?

Have you looked at the SPI lines with an oscilloscope and/or analyser to see what's happening on the wires?

Have you stepped through the old HAL code, and the new LL code, and compared what's happening?

 

Remember that the STM32 itself neither knows nor cares about HAL or LL - all that matters is that the registers get set to the correct things...

A complex system that works is invariably found to have evolved from a simple system that worked.
A complex system designed from scratch never works and cannot be patched up to make it work.

Hi :

To resolve this, every time you send data, you need to read it once.

So the code should be as follow:

#ifdef USE_HAL_DRIVER
  HAL_SPI_Transmit(&hspi1, &data, 1, 100);
  HAL_SPI_Receive(&hspi1, &data, 1, 100);
#else
  while (!LL_SPI_IsActiveFlag_TXE(SPI1));
  LL_SPI_TransmitData8(SPI1, data);
  /*you need read after send */
  while (!LL_SPI_IsActiveFlag_RXNE(SPI1));
  LL_SPI_ReceiveData8(SPI1);

  while (!LL_SPI_IsActiveFlag_TXE(SPI1));
  LL_SPI_TransmitData8(SPI1, 0xff);
  while (!LL_SPI_IsActiveFlag_RXNE(SPI1));
  data = LL_SPI_ReceiveData8(SPI1);
#endif