Recently I started working on the GNSS with STM32, I am very new to STM32 eco-system. I have a IRNSS click from MikroE which has L89H and I am trying to integrate L89H with STM32WL55JC1 controller.
I have implemented the UART receive NMEA messages from the L89H. I have connected TX, RX, 3,3v, GND pins to STM32's RX, TX, 3.3v, and ground. But when I execute the code no NMEA messages are displayed on the serial monitor. I don't know where I am going wring and I would appreciate to have help for me in this situation.
When i plugged the device, I can see the PPS LED is blinking which means I device is receiving the satellite signal.
From the documentation it is mentioned that the default baud rate is 9600. So I am using the default baud rate.
I connect the same IRNSS click to the Clicker 2 STM32 controller, and when I uploaded the example GNSS FW I can see the NMEA messages received by the controller. But the same board is not working when I connected to STM32WL55JC1.
I am using the following code to read and print the NMEA messages in the CUBE IDE:
#include "main.h"
#include "malloc.h"
#include "string.h"
UART_HandleTypeDef huart1;
uint8_t* RX_BUFFER = NULL;
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_USART1_UART_Init(void);
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_USART1_UART_Init();
while (1)
{
RX_BUFFER = (uint8_t*)malloc(400 * sizeof(uint8_t));
HAL_UART_Receive(&huart1,(uint8_t *)RX_BUFFER,350,500);
HAL_Delay(1000);
int size = sizeof(RX_BUFFER);
HAL_UART_Transmit(&huart1,(uint8_t *)RX_BUFFER,size,500);
HAL_Delay(1000);
}
}
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
HAL_PWR_EnableBkUpAccess();
__HAL_RCC_LSEDRIVE_CONFIG(RCC_LSEDRIVE_LOW);
/** Configure the main internal regulator output voltage
*/
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
/** Initializes the CPU, AHB and APB buses clocks
*/
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSE|RCC_OSCILLATORTYPE_MSI;
RCC_OscInitStruct.LSEState = RCC_LSE_ON;
RCC_OscInitStruct.MSIState = RCC_MSI_ON;
RCC_OscInitStruct.MSICalibrationValue = RCC_MSICALIBRATION_DEFAULT;
RCC_OscInitStruct.MSIClockRange = RCC_MSIRANGE_6;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_MSI;
RCC_OscInitStruct.PLL.PLLM = RCC_PLLM_DIV1;
RCC_OscInitStruct.PLL.PLLN = 24;
RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV2;
RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV2;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler();
}
/** Configure the SYSCLKSource, HCLK, PCLK1 and PCLK2 clocks dividers
*/
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK3|RCC_CLOCKTYPE_HCLK
|RCC_CLOCKTYPE_SYSCLK|RCC_CLOCKTYPE_PCLK1
|RCC_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
RCC_ClkInitStruct.AHBCLK3Divider = RCC_SYSCLK_DIV1;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
{
Error_Handler();
}
}
/**
* @brief USART1 Initialization Function
* @param None
* @retval None
*/
static void MX_USART1_UART_Init(void)
{
huart1.Instance = USART1;
huart1.Init.BaudRate = 9600;
huart1.Init.WordLength = UART_WORDLENGTH_8B;
huart1.Init.StopBits = UART_STOPBITS_1;
huart1.Init.Parity = UART_PARITY_NONE;
huart1.Init.Mode = UART_MODE_TX_RX;
huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart1.Init.OverSampling = UART_OVERSAMPLING_16;
huart1.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
huart1.Init.ClockPrescaler = UART_PRESCALER_DIV1;
huart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
if (HAL_UART_Init(&huart1) != HAL_OK)
{
Error_Handler();
}
if (HAL_UARTEx_SetTxFifoThreshold(&huart1, UART_TXFIFO_THRESHOLD_1_8) != HAL_OK)
{
Error_Handler();
}
if (HAL_UARTEx_SetRxFifoThreshold(&huart1, UART_RXFIFO_THRESHOLD_1_8) != HAL_OK)
{
Error_Handler();
}
if (HAL_UARTEx_DisableFifoMode(&huart1) != HAL_OK)
{
Error_Handler();
}
}
static void MX_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOC_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
HAL_GPIO_WritePin(Wake_up_GPIO_Port, Wake_up_Pin, GPIO_PIN_RESET);
/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(Reset_GPIO_Port, Reset_Pin, GPIO_PIN_RESET);
/*Configure GPIO pin : Wake_up_Pin */
GPIO_InitStruct.Pin = Wake_up_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(Wake_up_GPIO_Port, &GPIO_InitStruct);
/*Configure GPIO pin : Reset_Pin */
GPIO_InitStruct.Pin = Reset_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(Reset_GPIO_Port, &GPIO_InitStruct);
}
void Error_Handler(void)
{
__disable_irq();
while (1)
{
}
}
#ifdef USE_FULL_ASSERT
/**
* @brief Reports the name of the source file and the source line number
* where the assert_param error has occurred.
* @param file: pointer to the source file name
* @param line: assert_param error line source number
* @retval None
*/
void assert_failed(uint8_t *file, uint32_t line)
{
/* USER CODE BEGIN 6 */
/* User can add his own implementation to report the file name and line number,
ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
/* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */
Please let me know if you need any additional information.
Best regards, Pavan Ravuru
Caveat: I'm not too familiar with the STM32 HAL
Some issues ...
mallocon each loop iteration. You are leaking memory. Move themallocabove thewhilesizeof(RXBUFFER)is incorrect. It is the size of a pointer and not the length of what that pointer points to. So, this is 4 or 8 bytes and not the 400 that you expect.HAL_Delayat all?uint8_t *casts.Most guides I've looked at recommend using interrupts or DMA (e.g.
HAL_UART_Receive_ITorHAL_UART_Receive_DMA.I found the source code for
HAL_UART_Receive: https://www.disca.upv.es/aperles/arm_cortex_m3/llibre/st/STM32F439xx_User_Manual/stm32f4xx__hal__uart_8c_source.htmlFrom it, if you get a timeout, [I think] you can use
huart->RxXferCountto determine the actual amount of data transferred.This is [a bit of a hack] in lieu of using the interrupt or DMA versions.
You may want to implement ring buffers or "sliding" indexes into separate RX and TX buffers.
Again ... Why are you sending the GPS data back to the device? This makes no sense to me. Do you need/have another UART or other device? Is this just sample code and you want to process the GPS data instead?
Here is some refactored code. It is just a guess.