cancel
Showing results for 
Search instead for 
Did you mean: 

USART1 Receive Problem with STM32L072CZ

Emanuele Zampieri
Associate II
Posted on November 23, 2017 at 21:34

Hi,

I'm trying to read via USART1 the bytes generated by the GNSS module.

I'm developing on the discovery kit B-L072Z-LRWAN1 board (Discovery kit LoRa), where the TX and RX pins of the GNSS module are connected respectively to PA9 and PA10 of the STM32.

In my code, I read the bytes (one by one) sent by the GNSS module via HAL_UART_Receive function, as shown below. 

The problem occurs when the mcu executes the third call to 

HAL_UART_Receive(). In this case the STM32 remains blocked and does not respect the timeout set as parameter.

The GNSS module works properly, with a UART-USB converter I can correctly read the bytes generated by the module.

This is my code:

#define UART                                   USART1

#define UART_TX_PIN                     GPIO_PIN_9

#define UART_RX_PIN                    

GPIO_PIN_10

#define UART_GPIO_PORT           

GPIOA 

#define UART_AF                             GPIO_AF4_USART1

#define UART_CLK_ENABLE()        __USART1_CLK_ENABLE();

//Uart Handle

static UART_HandleTypeDef uartHandle;

void GNSS_Uart_IoInit(void);

/*!

 * @brief Initializes the UART interface

 * @param None

 * @retval None

 */

UART_HandleTypeDef GNSS_Init(void)

{

   

//Enable clock

   

UART_CLK_ENABLE();

   

__HAL_RCC_USART1_CLK_ENABLE();

   

GNSS_Uart_IoInit();

   

uartHandle.Instance = UART;

   uartHandle.Init.BaudRate = 9600;

   uartHandle.Init.WordLength = UART_WORDLENGTH_8B;

   uartHandle.Init.StopBits = UART_STOPBITS_1;

   uartHandle.Init.Parity = UART_PARITY_NONE;

   uartHandle.Init.Mode = UART_MODE_TX_RX;

   uartHandle.Init.HwFlowCtl = UART_HWCONTROL_NONE;

   if(HAL_UART_Init(&uartHandle) != HAL_OK)

   {

       /* Initialization Error */

       Error_Handler(); 

   }

   

if(HAL_UART_GetState(&uartHandle) != HAL_UART_STATE_READY)

      

Error_Handler();

   

return uartHandle;

}

/*!

 * @brief Initializes the GPIO for UART interface

 * @param None

 * @retval None

 */

void GNSS_Uart_IoInit(void)

{

   

__GPIOA_CLK_ENABLE();

/**UART GPIO Configuration    

    PA9     ------> UART1_TX

    PA10    ------> UART1_RX 

    */

   

GPIO_InitTypeDef GPIO_InitStruct = {0};

   

//Set pin

   

GPIO_InitStruct.Pin = UART_TX_PIN|UART_RX_PIN;

   GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;

   GPIO_InitStruct.Pull = GPIO_PULLUP;

   GPIO_InitStruct.Speed = GPIO_SPEED_LOW;

   GPIO_InitStruct.Alternate = UART_AF;

   HAL_GPIO_Init(UART_GPIO_PORT, &GPIO_InitStruct);

}

void readData(void)

{

   

uint8_t buff[2];

   

if(HAL_UART_GetState(&uartHandle) == HAL_UART_STATE_READY)

   

{

      

HAL_UART_Receive(&uartHandle, buff, 1, 200);

      

PRINTF('R: %c \n\r', buff[0]);

   

}else

      

PRINTF('BUSY');

   }

}

This is the main:

int main( void )

{

  //STM32 HAL library initialization

  HAL_Init();

  

  //Configure the system clock

  SystemClock_Config();

   //Configure the debug mode

  DBG_Init();

  

  //Configure the hardware

  HW_Init();

  GNSS_Init();

  

  //Configure the Lora Stack

  lora_Init(&LoRaMainCallbacks, &LoRaParamInit);

  //Main loop

  while(1)

  {

       //Run the LoRa class A state machine

       lora_fsm();

      

readData();

   }

The PRINTF function allows the communication with the pc through the st-link.

Thanks.

3 REPLIES 3
Posted on November 24, 2017 at 01:25

I do this by servicing the USART IRQ into a FIFO buffer, reading the USART registers directly. Foreground code then parses and demuxes NMEA, UBX and RTCM3 packets from the GPS unit, and higher baud rates are used to reduce latency.

The LoRa/Radio code in the library has a tendency to block for multiple milliseconds, as does the VCOM interrupt handler, these can both result in data loss. Not sure of the time in the state machine loop but if too long the USART will underrun, a status that needs clearing to receive additional characters. Here we rewrote the VCOM driver, fixing the code that blocks, and as much of the HAL nonsense as possible.

Assume at 9600 baud one character per millisecond.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Posted on December 04, 2017 at 21:10

Thank you for your answer.

If I understand correctly you do not use HAL for the UART.

Could you tell me what you have changed in the VCOM driver? 

I think I will remove this driver from my project.

Thanks.

Posted on December 04, 2017 at 22:46

I use HAL to initialize things, but the code in the LRWAN example is badly broken.

The VCOM code called under interrupt blocks. Delays in the radio code also block. Interrupt priorities are poorly chosen.

I modified the buffering code in VCOM so it doesn't block, and the IRQ preempts other sources. VCOM is very helpful with debugging and flow analysis as the CM0+ doesn't support SWV connectivity.

The GPS data is buffered by an IRQ handler, and pulled in the main() while loop.

The VCOM and GPS interrupts enter and leave quickly.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..