Skip to main content
Explorer
July 7, 2025
Solved

stm32g030 spi switch from HAL to LL not work

  • July 7, 2025
  • 4 replies
  • 396 views

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

}

 

    This topic has been closed for replies.
    Best answer by Zhou JianQiang

    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

    4 replies

    Explorer
    July 8, 2025

    Hi @Imen.D :

    Can you help confirm this question?

    Technical Moderator
    July 8, 2025

    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

     

    Super User
    July 8, 2025

    @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...

    Zhou JianQiangAuthorAnswer
    Explorer
    July 9, 2025

    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