2017-11-23 12:34 PM
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.
2017-11-23 04:25 PM
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.
2017-12-04 01:10 PM
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.
2017-12-04 02:46 PM
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.