Skip to main content
Associate
January 2, 2025
Question

trying to get NMEA sentences from EVB-VIC3DA using NUCLEO-C031C6

  • January 2, 2025
  • 5 replies
  • 2903 views

Happy New Year everyone !

I am currently trying to get the nmea sentences from the above gnss module (vic3da) i have connected the uart rx/tx and ground (gnd) and am able to ping the gps unit but unable to read any data from it has anyone ever written code that i might have a look at to know if I'm doing some thing wrong as I am completely new to MCUs or can anyone guide me to complete my project successfully ? 

 

with regards

swayam :)

5 replies

Technical Moderator
January 2, 2025

Hi,

VIC3DA has 2 UARTs, UART1 and UART2. By default, NMEA is coming out of UART2. 

Can you please tell me which UART (UART1 or UART2) you are tapping into?

Where you are connecting the UART lines?

Have you put a scope or logic analyzer on the UART TX pin to see if there is data coming out on the point where you are tapping into?

If you are looking into developing application development with an MCU, it is better to use UART1 as there is J401 and J403 with UART pins exposed. You can connect STM32 MCU UART lines here.

To change internal routing for VIC3DA from UART2 to UART1, you should send the following commands.

 

 

$PSTMSETPAR,1101,1 //changes from UART2 to UART1
$PSTMSAVEPAR // save into flash
$PSTMSRR // software rest for settings to take effect

//any time you make a change to CDB (register settings), you have to send $PSTMSAVEPAR followed by $PSTMSRR for settings to take effect.

 

 

Please note that once you change communication from UART2 to UART1, you will no longer see data on the USB port. 

Also there is board called X-NUCLEO-GNSS2A1 board which plugs directly into the ST morpho connector. This might be the best hardware fit your development needs. https://www.st.com/en/ecosystems/x-nucleo-gnss2a1.html

Regarding firmware, you can refer to X-NUCLEO-GNSS1 software package. Please refer to getting started guide on how to start a project and you can include one of the example projects as part of your application during GNSS middleware configuration.

 

​In order 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.
Associate
January 18, 2025

pin layout ioc filepin layout ioc filetx/d1 rx/d0 on the boardtx/d1 rx/d0 on the boardtx/rx on the gnss moduletx/rx on the gnss modulegndgndgndgndall wire connections between the boardsall wire connections between the boards

Associate
January 18, 2025
/* USER CODE BEGIN Header */
/**
 ******************************************************************************
 * @file : main.c
 * @brief : Main program body
 ******************************************************************************
 * @attention
 *
 * Copyright (c) 2024 STMicroelectronics.
 * All rights reserved.
 *
 * This software is licensed under terms that can be found in the LICENSE file
 * in the root directory of this software component.
 * If no LICENSE file comes with this software, it is provided AS-IS.
 *
 ******************************************************************************
 */
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include <string.h>
#include <stdio.h>
#include <stdbool.h>
/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */

/* USER CODE END PTD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */

/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */

/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/
UART_HandleTypeDef huart2;

/* USER CODE BEGIN PV */
#define BUFFER_SIZE 1024
uint8_t rxBuffer[BUFFER_SIZE];
char uartBuffer[100];
volatile uint8_t rxByte;
volatile uint16_t rxHead = 0;
volatile uint16_t rxTail = 0;
bool gnss_connected = false;
/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_USART2_UART_Init(void);
/* USER CODE BEGIN PFP */
static void ProcessNMEAData(void);
/* USER CODE END PFP */

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
 if(huart->Instance == USART2)
 {
 rxBuffer[rxHead] = rxByte;
 rxHead = (rxHead + 1) % BUFFER_SIZE;
 HAL_UART_Receive_IT(&huart2, &rxByte, 1);
 }
}

static void ProcessNMEAData(void)
{
 static char line[256];
 static int lineIndex = 0;

 while (rxHead != rxTail)
 {
 char c = rxBuffer[rxTail];
 rxTail = (rxTail + 1) % BUFFER_SIZE;

 if (c == '\n')
 {
 line[lineIndex] = '\0';
 // Echo the complete NMEA sentence
 HAL_UART_Transmit(&huart2, (uint8_t*)line, lineIndex, 100);
 HAL_UART_Transmit(&huart2, (uint8_t*)"\r\n", 2, 100);
 lineIndex = 0;
 }
 else if (c == '\r')
 {
 // Ignore carriage returns
 continue;
 }
 else if (lineIndex < 255)
 {
 line[lineIndex++] = c;
 }
 }
}
/* USER CODE END 0 */

/**
 * @brief The application entry point.
 * @retval int
 */
int main(void)
{
 /* USER CODE BEGIN 1 */

 /* USER CODE END 1 */

 /* MCU Configuration--------------------------------------------------------*/
 /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
 HAL_Init();

 /* USER CODE BEGIN Init */

 /* USER CODE END Init */

 /* Configure the system clock */
 SystemClock_Config();

 /* USER CODE BEGIN SysInit */

 /* USER CODE END SysInit */

 /* Initialize all configured peripherals */
 MX_GPIO_Init();
 MX_USART2_UART_Init();

 /* USER CODE BEGIN 2 */
 // Start UART reception in interrupt mode
 HAL_UART_Receive_IT(&huart2, &rxByte, 1);

 // VIC3DA Configuration Commands
 uint8_t get_version[] = "$PSTMGETSWVER,0*3C\r\n";
 uint8_t rate_cmd[] = "$PSTMSETPAR,1000,100*54\r\n"; // Set 10Hz rate
 uint8_t gga_msg[] = "$PSTMSETPAR,1001,1*76\r\n"; // Enable GGA
 uint8_t gsa_msg[] = "$PSTMSETPAR,1002,1*75\r\n"; // Enable GSA
 uint8_t gsv_msg[] = "$PSTMSETPAR,1003,1*74\r\n"; // Enable GSV
 uint8_t rmc_msg[] = "$PSTMSETPAR,1005,1*72\r\n"; // Enable RMC
 uint8_t save_cmd[] = "$PSTMSAVEPAR*58\r\n";
 uint8_t reset_cmd[] = "$PSTMSRR*3F\r\n";

 // Send initial configuration
 HAL_UART_Transmit(&huart2, get_version, strlen((char*)get_version), 100);
 HAL_Delay(1000); // Wait for version response

 HAL_UART_Transmit(&huart2, rate_cmd, strlen((char*)rate_cmd), 100);
 HAL_Delay(100);
 HAL_UART_Transmit(&huart2, gga_msg, strlen((char*)gga_msg), 100);
 HAL_Delay(100);
 HAL_UART_Transmit(&huart2, gsa_msg, strlen((char*)gsa_msg), 100);
 HAL_Delay(100);
 HAL_UART_Transmit(&huart2, gsv_msg, strlen((char*)gsv_msg), 100);
 HAL_Delay(100);
 HAL_UART_Transmit(&huart2, rmc_msg, strlen((char*)rmc_msg), 100);
 HAL_Delay(100);

 // Save settings and reset
 HAL_UART_Transmit(&huart2, save_cmd, strlen((char*)save_cmd), 100);
 HAL_Delay(1000);
 HAL_UART_Transmit(&huart2, reset_cmd, strlen((char*)reset_cmd), 100);
 HAL_Delay(2000); // Wait for reset to complete
 /* USER CODE END 2 */

 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 uint32_t lastBlinkTime = 0;
 uint8_t blinkState = 0; // Used to track the blink pattern state

 while (1)
 {
 ProcessNMEAData();

 // LED blinking pattern: two quick blinks followed by one long blink
 uint32_t currentTime = HAL_GetTick();
 if(currentTime - lastBlinkTime >= 200) // Check every 200ms
 {
 switch(blinkState) {
 case 0: // First quick blink ON
 HAL_GPIO_WritePin(Led_GPIO_Port, Led_Pin, GPIO_PIN_RESET);
 lastBlinkTime = currentTime;
 blinkState = 1;
 break;

 case 1: // First quick blink OFF
 HAL_GPIO_WritePin(Led_GPIO_Port, Led_Pin, GPIO_PIN_SET);
 lastBlinkTime = currentTime;
 blinkState = 2;
 break;

 case 2: // Second quick blink ON
 HAL_GPIO_WritePin(Led_GPIO_Port, Led_Pin, GPIO_PIN_RESET);
 lastBlinkTime = currentTime;
 blinkState = 3;
 break;

 case 3: // Second quick blink OFF
 HAL_GPIO_WritePin(Led_GPIO_Port, Led_Pin, GPIO_PIN_SET);
 lastBlinkTime = currentTime;
 blinkState = 4;
 break;

 case 4: // Long blink ON
 HAL_GPIO_WritePin(Led_GPIO_Port, Led_Pin, GPIO_PIN_RESET);
 lastBlinkTime = currentTime;
 blinkState = 5;
 break;

 case 5: // Long blink OFF (with longer delay)
 HAL_GPIO_WritePin(Led_GPIO_Port, Led_Pin, GPIO_PIN_SET);
 lastBlinkTime = currentTime;
 blinkState = 0;
 HAL_Delay(500); // Longer pause before repeating pattern
 break;
 }
 }

 HAL_Delay(10); // Small delay to prevent busy-waiting
 /* USER CODE END WHILE */

 /* USER CODE BEGIN 3 */
 }
 /* USER CODE END 3 */
}

/**
 * @brief System Clock Configuration
 * @retval None
 */
void SystemClock_Config(void)
{
 RCC_OscInitTypeDef RCC_OscInitStruct = {0};
 RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

 /** Initializes the RCC Oscillators according to the specified parameters
 * in the RCC_OscInitTypeDef structure.
 */
 RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
 RCC_OscInitStruct.HSEState = RCC_HSE_ON;
 if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
 {
 Error_Handler();
 }

 /** Initializes the CPU, AHB and APB buses clocks
 */
 RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
 |RCC_CLOCKTYPE_PCLK1;
 RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSE;
 RCC_ClkInitStruct.SYSCLKDivider = RCC_SYSCLK_DIV1;
 RCC_ClkInitStruct.AHBCLKDivider = RCC_HCLK_DIV1;
 RCC_ClkInitStruct.APB1CLKDivider = RCC_APB1_DIV1;

 if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1) != HAL_OK)
 {
 Error_Handler();
 }
}

/**
 * @brief USART2 Initialization Function
 * @PAram None
 * @retval None
 */
static void MX_USART2_UART_Init(void)
{
 /* USER CODE BEGIN USART2_Init 0 */

 /* USER CODE END USART2_Init 0 */

 /* USER CODE BEGIN USART2_Init 1 */

 /* USER CODE END USART2_Init 1 */
 huart2.Instance = USART2;
 huart2.Init.BaudRate = 115200;
 huart2.Init.WordLength = UART_WORDLENGTH_8B;
 huart2.Init.StopBits = UART_STOPBITS_1;
 huart2.Init.Parity = UART_PARITY_NONE;
 huart2.Init.Mode = UART_MODE_TX_RX;
 huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;
 huart2.Init.OverSampling = UART_OVERSAMPLING_16;
 huart2.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
 huart2.Init.ClockPrescaler = UART_PRESCALER_DIV1;
 huart2.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
 if (HAL_UART_Init(&huart2) != HAL_OK)
 {
 Error_Handler();
 }
 /* USER CODE BEGIN USART2_Init 2 */

 /* USER CODE END USART2_Init 2 */
}

/**
 * @brief GPIO Initialization Function
 * @PAram None
 * @retval None
 */
static void MX_GPIO_Init(void)
{
 GPIO_InitTypeDef GPIO_InitStruct = {0};
 /* USER CODE BEGIN MX_GPIO_Init_1 */
 /* USER CODE END MX_GPIO_Init_1 */

 /* GPIO Ports Clock Enable */
 __HAL_RCC_GPIOC_CLK_ENABLE();
 __HAL_RCC_GPIOF_CLK_ENABLE();
 __HAL_RCC_GPIOA_CLK_ENABLE();

 /*Configure GPIO pin Output Level */
 HAL_GPIO_WritePin(Led_GPIO_Port, Led_Pin, GPIO_PIN_SET);

 /*Configure GPIO pin : User_Button_Pin */
 GPIO_InitStruct.Pin = User_Button_Pin;
 GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING;
 GPIO_InitStruct.Pull = GPIO_NOPULL;
 HAL_GPIO_Init(User_Button_GPIO_Port, &GPIO_InitStruct);

 /*Configure GPIO pin : Led_Pin */
 GPIO_InitStruct.Pin = Led_Pin;
 GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
 GPIO_InitStruct.Pull = GPIO_NOPULL;
 GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
 HAL_GPIO_Init(Led_GPIO_Port, &GPIO_InitStruct);

 /* EXTI interrupt init*/
 HAL_NVIC_SetPriority(EXTI4_15_IRQn, 0, 0);
 HAL_NVIC_EnableIRQ(EXTI4_15_IRQn);

 /* USER CODE BEGIN MX_GPIO_Init_2 */
 /* USER CODE END MX_GPIO_Init_2 */
}

/* USER CODE BEGIN 4 */

/* USER CODE END 4 */

/**
 * @brief This function is executed in case of error occurrence.
 * @retval None
 */
void Error_Handler(void)
{
 /* USER CODE BEGIN Error_Handler_Debug */
 /* User can add his own implementation to report the HAL error return state */
 __disable_irq();
 while (1)
 {
 }
 /* USER CODE END Error_Handler_Debug */
}

#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 */
Tesla DeLorean
Guru
January 18, 2025

Isn't there a pin level conflict on the NUCLEO-64 with Arduino rail D0/D1 and ST-LINK VCP?

Why echoing NMEA back to receiver?

Tips, Buy me a coffee, or three.. PayPal VenmoUp vote any posts that you find helpful, it shows what's working..
Associate
January 18, 2025

Hi ! 

I'm completely new to this so .. Did you mean to use two different UARTs?

UART2 for the VCP (USB) and UART1 for the communication between the gnss module and the mcu ?

Tesla DeLorean
Guru
January 18, 2025

Looking at the Schematic  https://www.st.com/resource/en/schematic_pack/mb1717-c031c6-b02_schematic.pdf#page=3

 

PA2/PA3 (USART2) is for the ST-LINK VCP, can connect to rail via SB (Solder Bridges)

PB6/PB7 (USART1) is for the Arduino rail

Pins for MCU via Data Sheet tables

https://www.st.com/resource/en/datasheet/stm32c031c4.pdf#page=36

 

So interact with the VIC3DA via the STM32C031's USART1, and echo/diagnose through USART2 to the ST-LINK and the terminal connected to that COM/VCP

Tips, Buy me a coffee, or three.. PayPal VenmoUp vote any posts that you find helpful, it shows what's working..
Associate
January 21, 2025

Hi

I have tried connecting directly using USB to PC and the values are coming in serial monitor. But not in MCU.

Andrew Neil
Super User
January 21, 2025

So now connect MCU to a PC serial terminal via USB-to-UART:

  • Verify that stuff sent by the MCU is received on the terminal
  • Verify that stuff sent from the terminal is received by the MCU

 

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.
Associate
January 21, 2025

Hi
I have verified the stuff sent by the MCU (Just printed Helloworld).
I have verified both the stuff.

Associate
January 22, 2025

Hi

I have conducted the tests either way. 

There is some progress I can say. Initially I was trying to power up the GNSS module using the USB Type A to USB MIcro ( Laptop to the module). Now I tried with powering it up with the 3.3V from the MCU itself and while i do that I do get some interrupts. Initially I did doubt the reliability of jumper wires but now it is also cleared since I ensured continuity among wires. Since I dont have a scope or logic analyzer( i have ordered it - it might take some time), I cannot monitor the signals.

 

 

About the Interrupt that I received, the code parses the first character and then checks for the symbol '$". It didnt work.

So I increased the no. of characters to 10 then i received this output

swayamsidhmohanty_0-1737583485295.jpeg

 

Hello world is just to check the UART between the MCU and my computer. Please dont mind it.

 

The no that i get is 536871948. I find it strange that ASCII code for $ is 36 and G is 71. And in UART serial monitor I am getting NMEA sentences starting with '$G....' and the output we got somehow has these codes. 5-36-8-71-.... There is a character in between.

Is this meaningful data. If yes should we parse it this way.

 

What are your suggestions to read data using DMA over this character by character approach?

Tesla DeLorean
Guru
January 22, 2025

536871948 = 0x2000040C  the address of rxChar array in memory.

Your handler is now expecting 10 characters, you make no attempt to process them in that form

I'd recommend mastering C coding before trying DMA. Perhaps work with colleagues or supervisors to guide you.

/* USER CODE BEGIN Header */
/**
 ******************************************************************************
 * @file : main.c
 * @brief : Main program body
 ******************************************************************************
 * @attention
 *
 * Copyright (c) 2025 STMicroelectronics.
 * All rights reserved.
 *
 * This software is licensed under terms that can be found in the LICENSE file
 * in the root directory of this software component.
 * If no LICENSE file comes with this software, it is provided AS-IS.
 *
 ******************************************************************************
 */
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */

/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */

/* USER CODE END PTD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */

/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */

/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/

UART_HandleTypeDef huart1;
UART_HandleTypeDef huart2;
DMA_HandleTypeDef hdma_usart1_rx;

/* USER CODE BEGIN PV */

/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_DMA_Init(void);
static void MX_USART1_UART_Init(void);
static void MX_USART2_UART_Init(void);
/* USER CODE BEGIN PFP */

/* USER CODE END PFP */

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
#define NMEA_BUFFER_SIZE 512
 uint8_t nmeaBuffer[NMEA_BUFFER_SIZE];

 uint8_t rxChar[10], rcvd_msg;

 volatile uint16_t nmeaIndex = 0;
 volatile uint8_t nmeaComplete = 0;
 volatile char nmeaSentence[NMEA_BUFFER_SIZE];

 /* GNSS configuration commands */
 GPIO_PinState Test_Jumper;

 const char* GNSS_SET_RATE_1HZ = "$PMSTK220,1000*1F\r\n"; // Set update rate to 1Hz
 uint8_t GNSS_SET_BAUD_9600[] = "$PSTMSETPAR,115200*17\r\n"; // Set baud rate to 9600
 const char* GNSS_SET_NMEA_OUTPUT = "$PMSTK314,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0*28\r\n"; // Enable GGA and RMC sentences

void GNSS_Init()
{
 /* Send configuration commands to GNSS module */

// UART_Start_Receive_DMA(&huart1, nmeaBuffer, NMEA_BUFFER_SIZE);

// HAL_UART_Transmit(&huart1, (uint8_t*)GNSS_SET_BAUD_9600, 25, HAL_MAX_DELAY);
// HAL_Delay(100);
// HAL_UART_Transmit(&huart1, (uint8_t*)GNSS_SET_RATE_1HZ, strlen(GNSS_SET_RATE_1HZ), HAL_MAX_DELAY);
// HAL_Delay(100);
// HAL_UART_Transmit(&huart1, (uint8_t*)GNSS_SET_NMEA_OUTPUT, strlen(GNSS_SET_NMEA_OUTPUT), HAL_MAX_DELAY);
// HAL_Delay(100);

 /* Start receiving data in interrupt mode */
 HAL_UART_Receive_IT(&huart1, &rxChar[0], sizeof(rxChar));
}

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
 if (huart->Instance == USART1)
 {
 int i;
 for(i=0; i<sizeof(rxChar); i++) // For each character requested
 {
 if (rxChar[i] == '$') // Start of NMEA sentence
 {
 nmeaIndex = 0;
 }
 if (nmeaIndex < NMEA_BUFFER_SIZE - 1)
 {
 nmeaBuffer[nmeaIndex++] = rxChar[i];

 if (rxChar[i] == '\n') // End of NMEA sentence
 {
 nmeaBuffer[nmeaIndex] = '\0';
 if (nmeaComplete != 1)
 {
 strcpy(nmeaSentence, (char *)nmeaBuffer); // copy to an inactive buffer
 nmeaComplete = 1;
 }
 }
 }
 else
 {
 nmeaIndex = 0; // Buffer overflow protection
 }

 /* Restart interrupt reception */
 HAL_UART_Receive_IT(&huart1, &rxChar[0], sizeof(rxChar));
 }
}

void USART2OutString(char *str)
{
 HAL_UART_Transmit(&huart2, (uint8_t *)str, strlen(str), HAL_MAX_DELAY);
}


void ProcessNMEASentence(char* sentence)
{
 /* Forward NMEA sentence to debug UART */
 USART2OutString(sentence);

 /* Add your NMEA parsing code here */

// strstr() seems like a poor choice the sentence starts at the first character

 /* Example: Check for specific NMEA sentences

 if (strstr(sentence, "$GPRMC") != NULL)
 {
 // Parse RMC sentence
 }
 else if(strstr((char*)sentence, "$GPGGA") != NULL)
 {
 // Parse GGA sentence
 }

 */
}

/* USER CODE END 0 */

/**
 * @brief The application entry point.
 * @retval int
 */
int main(void)
{
 /* USER CODE BEGIN 1 */

 /* USER CODE END 1 */

 /* MCU Configuration--------------------------------------------------------*/

 /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
 HAL_Init();

 /* USER CODE BEGIN Init */

 /* USER CODE END Init */

 /* Configure the system clock */
 SystemClock_Config();

 /* USER CODE BEGIN SysInit */

 /* USER CODE END SysInit */

 /* Initialize all configured peripherals */
 MX_GPIO_Init();
 MX_DMA_Init();
 MX_USART1_UART_Init();
 MX_USART2_UART_Init();
 /* USER CODE BEGIN 2 */

 /* USER CODE END 2 */

 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 GNSS_Init();
 uint8_t data[] = "Hello world\n\r";
 char msg[100];

 USART2OutString(data);

 while (1)
 {
 Test_Jumper = HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_6);
 if (Test_Jumper)
 HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_RESET);
 else
 HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_SET);

 if (nmeaComplete)
 {
 ProcessNMEASentence(nmeaSentence);
 nmeaComplete = 0;
 }
 }
}

/**
 * @brief System Clock Configuration
 * @retval None
 */
void SystemClock_Config(void)
{
 RCC_OscInitTypeDef RCC_OscInitStruct = {0};
 RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

 /** Initializes the RCC Oscillators according to the specified parameters
 * in the RCC_OscInitTypeDef structure.
 */
 RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
 RCC_OscInitStruct.HSIState = RCC_HSI_ON;
 RCC_OscInitStruct.HSIDiv = RCC_HSI_DIV4;
 RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
 if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
 {
 Error_Handler();
 }

 /** Initializes the CPU, AHB and APB buses clocks
 */
 RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
 |RCC_CLOCKTYPE_PCLK1;
 RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI;
 RCC_ClkInitStruct.SYSCLKDivider = RCC_SYSCLK_DIV1;
 RCC_ClkInitStruct.AHBCLKDivider = RCC_HCLK_DIV1;
 RCC_ClkInitStruct.APB1CLKDivider = RCC_APB1_DIV1;

 if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK)
 {
 Error_Handler();
 }
}

/**
 * @brief USART1 Initialization Function
 * @PAram None
 * @retval None
 */
static void MX_USART1_UART_Init(void)
{
 /* USER CODE BEGIN USART1_Init 0 */

 /* USER CODE END USART1_Init 0 */

 /* USER CODE BEGIN USART1_Init 1 */

 /* USER CODE END USART1_Init 1 */
 huart1.Instance = USART1;
 huart1.Init.BaudRate = 115200;
 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();
 }
 /* USER CODE BEGIN USART1_Init 2 */

 /* USER CODE END USART1_Init 2 */
}

/**
 * @brief USART2 Initialization Function
 * @PAram None
 * @retval None
 */
static void MX_USART2_UART_Init(void)
{
 /* USER CODE BEGIN USART2_Init 0 */

 /* USER CODE END USART2_Init 0 */

 /* USER CODE BEGIN USART2_Init 1 */

 /* USER CODE END USART2_Init 1 */
 huart2.Instance = USART2;
 huart2.Init.BaudRate = 115200;
 huart2.Init.WordLength = UART_WORDLENGTH_8B;
 huart2.Init.StopBits = UART_STOPBITS_1;
 huart2.Init.Parity = UART_PARITY_NONE;
 huart2.Init.Mode = UART_MODE_TX_RX;
 huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;
 huart2.Init.OverSampling = UART_OVERSAMPLING_16;
 huart2.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
 huart2.Init.ClockPrescaler = UART_PRESCALER_DIV1;
 huart2.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
 if (HAL_UART_Init(&huart2) != HAL_OK)
 {
 Error_Handler();
 }
 /* USER CODE BEGIN USART2_Init 2 */

 /* USER CODE END USART2_Init 2 */

}

/**
 * Enable DMA controller clock
 */
static void MX_DMA_Init(void)
{
 /* DMA controller clock enable */
 __HAL_RCC_DMA1_CLK_ENABLE();

 /* DMA interrupt init */
 /* DMA1_Channel1_IRQn interrupt configuration */
 HAL_NVIC_SetPriority(DMA1_Channel1_IRQn, 0, 0);
 HAL_NVIC_EnableIRQ(DMA1_Channel1_IRQn);
}

/**
 * @brief GPIO Initialization Function
 * @PAram None
 * @retval None
 */
static void MX_GPIO_Init(void)
{
 GPIO_InitTypeDef GPIO_InitStruct = {0};
/* USER CODE BEGIN MX_GPIO_Init_1 */
/* USER CODE END MX_GPIO_Init_1 */

 /* GPIO Ports Clock Enable */
 __HAL_RCC_GPIOA_CLK_ENABLE();
 __HAL_RCC_GPIOB_CLK_ENABLE();

 /*Configure GPIO pin Output Level */
 HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_RESET);

 /*Configure GPIO pin : PA5 */
 GPIO_InitStruct.Pin = GPIO_PIN_5;
 GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
 GPIO_InitStruct.Pull = GPIO_NOPULL;
 GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
 HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

 /*Configure GPIO pin : PA6 */
 GPIO_InitStruct.Pin = GPIO_PIN_6;
 GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
 GPIO_InitStruct.Pull = GPIO_NOPULL;
 HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

/* USER CODE BEGIN MX_GPIO_Init_2 */
/* USER CODE END MX_GPIO_Init_2 */
}

/* USER CODE BEGIN 4 */

/* USER CODE END 4 */

/**
 * @brief This function is executed in case of error occurrence.
 * @retval None
 */
void Error_Handler(void)
{
 /* USER CODE BEGIN Error_Handler_Debug */
 /* User can add his own implementation to report the HAL error return state */
 __disable_irq();
 while (1)
 {
 }
 /* USER CODE END Error_Handler_Debug */
}

#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 */
Tips, Buy me a coffee, or three.. PayPal VenmoUp vote any posts that you find helpful, it shows what's working..