24#include "configuration.h"
27#define VTG_TMG_T_DEGREE_POS 1
28#define VTG_TMG_T_POS 2
29#define VTG_TMG_M_DEGREE_POS 3
30#define VTG_TMG_M_POS 4
31#define VTG_SPEED_KNOTS_POS 5
32#define VTG_SPEED_N_POS 6
33#define VTG_SPEED_OVER_GROUND_POS 7
34#define VTG_SPEED_OVER_GROUND_K_POS 8
35#define VTG_MODE_INDICATOR_POS 9
40#define GGA_LAT_DIR_POS 3
42#define GGA_LON_DIR_POS 5
43#define GGA_QUALITY_FIX_POS 6
44#define GGA_NUM_SATS_POS 7
46#define GGA_ORTH_HEIGHT_POS 9
47#define GGA_ORTH_HEIGHT_UNIT_POS 10
48#define GGA_GEOID_SEP_POS 11
49#define GGA_GEOID_SEP_UNIT_POS 12
50#define GGA_DATA_REC_AGE_POS 13
51#define GGA_REF_STAT_ID_POS 14
55#define GSA_FIX_TYPE_POS 2
56#define GSA_PRN_NUM_POS 3
57#define GSA_PDOP_POS 15
58#define GSA_HDOP_POS 16
59#define GSA_VDOP_POS 17
62#define GSV_NUM_OF_MESSAGES_POS 1
63#define GSV_NUM_OF_THIS_MESSAGE_POS 2
64#define GSV_NUM_SATS_VISIBLE_POS 3
65#define GSV_SV_PRN_NUM_POS 4
66#define GSV_ELEVATION_POS 5
67#define GSV_AZIMUTH_POS 6
180 .help =
"Dumps raw NMEA messages, usage: neo6 dumpnmea <true|false>",
230 "neo6_init_subsys: cmd_register error"
239 "neo6_init_subsys: subsys initialized"
259 "neo6_deinit_subsys: subsys is not initialized or stopped"
268 "neo6_deinit_subsys: subsystem deinitialized"
281 "neo6_start_subsys: subsys started"
288 "neo6_start_subsys: subsys not initialized or already started"
305 "neo6_stop_subsys: subsys stopped"
312 "neo6_stop_subsys: subsys not initialized or already already stopped"
327 "neo6_init_handle: handle already initialized"
337 "neo6_init_handle: No USART peripheral given"
346 "neo6_init_handle: No GPIO peripheral given"
388 uint8_t data_len = 0;
392 uint8_t data[data_len];
398 for(uint32_t i = 0; i < data_len; i++) {
399 if(data[i] ==
'\n') {
400 uint8_t nmea_len = 0;
403 uint8_t nmea_msg[nmea_len];
406 nmea_msg[nmea_len - 2] =
'\0';
407 nmea_msg[nmea_len - 1] =
'\0';
460 uint32_t char_count = 0;
462 while(*msg !=
'*' && char_count < msg_len) {
473 if(char_count == msg_len) {
477 *checksum_o = xor_val;
506 uint8_t checksum_calc = 0;
512 char *tokens[CONFIG_NEO6_MAX_TOKENS];
513 uint16_t num_tokens = 0;
515 if(checksum_recv == checksum_calc) {
516 str_tokenize((
char*)msg,
",", CONFIG_NEO6_MAX_TOKENS, tokens, &num_tokens);
518 if(
str_cmp(
"$GPRMC", tokens[0]) ==
true) {
521 else if(
str_cmp(
"$GPVTG", tokens[0]) ==
true) {
524 else if(
str_cmp(
"$GPGGA", tokens[0]) ==
true) {
527 else if(
str_cmp(
"$GPGSA", tokens[0]) ==
true) {
530 else if(
str_cmp(
"$GPGSV", tokens[0]) ==
true) {
557 if(
str_cmp(tokens[2],
"A") ==
false) {
574 uint8_t time_len = 6;
575 int8_t real_counter = 0;
576 for(uint8_t j = 0; j < time_len; j++) {
579 if((real_counter + 1) % 3 == 0 && real_counter <= 5) {
591 for(uint8_t j = 0; j < lat_txt_len; j++) {
599 for(uint8_t j = 0; j < lon_txt_len; j++) {
637 if(track_made_good_len == 0) {
643 track_made_good_len + 1);
681 if(fix_status_len == 0) {
686 char msg[] =
"No valid fix";
690 char msg[] =
"GPS fix";
694 char msg[] =
"DGPS fix";
704 if(num_sats_used_len == 0) {
715 if(ort_height_len == 0) {
729 if(geoid_sep_len == 0) {
759 if(msg_part_len == 0) {
779 if(msg_part_len == 0) {
789 if(msg_part_len == 0) {
800 if(msg_part_len == 0) {
828 if(msg_part_len == 0) {
869 "neo6_dumpnmea_handler: invalid arguments"
875 if(
str_cmp(argv[2],
"true") ==
true) {
878 else if(
str_cmp(argv[2],
"false") ==
true) {
885 "neo6_dumpnmea_handler: invalid arguments"
static struct internal_state_s internal_state
Singleton instance of the SysTick driver internal state.
Circular buffer module public API.
Command subsystem public API.
Common utility module public API.
System-wide error code definitions.
ERR_te cbuf_read(CBUF_HANDLE_ts *cbuf_handle, uint8_t *output_buf_o)
Reads all available data from the circular buffer into an output buffer.
ERR_te cbuf_len(CBUF_HANDLE_ts const *cbuf_handle, uint8_t *len_o)
Returns the number of bytes currently stored in the circular buffer.
ERR_te cbuf_write(CBUF_HANDLE_ts *cbuf_handle, uint8_t *input_buf, uint32_t input_len)
Writes data from an input buffer into the circular buffer.
ERR_te cmd_deregister(CMD_CLIENT_INFO_ts const *cmd_client_info)
Deregisters a client from the command subsystem.
ERR_te cmd_register(CMD_CLIENT_INFO_ts *cmd_client_info)
Registers a client with the command subsystem.
bool str_cmp(const char *str1, const char *str2)
Compares two null-terminated strings for equality.
int str_cpy(char *str_to, const char *str_from, uint32_t len)
Copies a null-terminated string into a destination buffer.
uint8_t ascii_hex_to_byte(char high, char low)
Converts two ASCII hex characters into a single byte value.
uint32_t get_str_len(char const *str)
Returns the length of a string, excluding the null terminator.
int str_tokenize(char *str, const char *separator, uint16_t max_tokens, char **tokens, uint16_t *num_tokens)
Splits a string into tokens separated by a given delimiter.
ERR_te
Standard return type used by all public API functions.
@ ERR_DEINITIALIZATION_FAILURE
@ ERR_MODULE_ALREADY_INITIALIZED
@ ERR_INITIALIZATION_FAILURE
@ ERR_DATA_ACQUISITION_FAILURE
ERR_te init_log(void)
Initializes the logging subsystem.
#define LOG_ERROR(subsys, lvl, fmt,...)
#define LOG_INFO(subsys, lvl, fmt,...)
LOG_LEVEL_te
Log severity levels, in ascending order of severity.
MODULES_te
Identifies a subsystem for use in logging and CLI output.
static ERR_te neo6_dumpnmea_handler(uint32_t argc, char **argv)
CLI handler for the "dumpnmea" command. Enables or disables raw NMEA logging.
static ERR_te neo6_process_gga(char **tokens)
Parses a GGA sentence and updates fix status, satellites used, orthometric height,...
static ERR_te neo6_process_rmc(char **tokens)
Parses an RMC sentence and updates time, date, latitude, and longitude.
static ERR_te neo6_process_gsa(char **tokens)
Parses a GSA sentence and updates fix type, PDOP, HDOP, and VDOP.
static ERR_te neo6_calc_checksum(char *msg, uint32_t msg_len, uint8_t *checksum_o)
Computes the NMEA checksum of a sentence by XORing all bytes between '$' and '*'.
static ERR_te neo6_process_vtg(char **tokens)
Parses a VTG sentence and updates movement direction and speed.
static ERR_te neo6_process_gsv(char **tokens)
Parses a GSV sentence and updates the total satellite count.
static ERR_te neo6_process_msg(uint8_t *msg, uint32_t msg_len)
Verifies the checksum of a received NMEA sentence and dispatches it to the appropriate parser.
ERR_te neo6_deinit_subsys(void)
Deinitializes the NEO-6 subsystem.
ERR_te neo6_run(void)
Processes received NMEA data.
ERR_te neo6_start_subsys(void)
Starts the NEO-6 subsystem.
ERR_te neo6_init_handle(NEO6_CFG_ts *neo6_cfg, NEO6_HANDLE_ts **neo6_handle_o)
Initializes the NEO-6 hardware handle.
ERR_te neo6_stop_subsys(void)
Stops the NEO-6 subsystem.
ERR_te neo6_init_subsys(void)
Initializes the NEO-6 subsystem.
ERR_te neo6_get_info(NEO6_INFO_ts **neo6_info_o)
Returns a pointer to the internal GPS data structure.
struct neo6_handle_s NEO6_HANDLE_ts
Opaque handle representing the NEO-6 hardware instance.
void gpio_init(GPIO_CFG_ts *gpio_cfg)
Initializes a GPIO pin according to the given configuration.
GPIO_PIN_te
GPIO pin number within a port (0–15).
GPIO_ALTERNATE_FUNCTION_te
GPIO alternate function mapping (AF0–AF15).
@ GPIO_MODE_ALTERNATE_FUNCTION
void usart6_irq_data_recv_callback(uint8_t data)
USART RXNE interrupt callback. Writes the received byte into the USART receive buffer.
void usart_init(USART_CFG_ts *usart_cfg)
Initializes the USART peripheral with the given configuration.
void usart_set_reception(USART_REGDEF_ts *usart_instance, EN_STATUS_te en_status)
Enables or disables the USART receiver (RE bit).
USART_BAUD_RATE_te
USART baud rate in bits per second.
@ USART_INTERRUPT_EN_TRUE
Common initialization public API.
Log subsystem public API.
System module identifier definitions.
#define GGA_GEOID_SEP_POS
#define GGA_GEOID_SEP_UNIT_POS
static CMD_CLIENT_INFO_ts neo6_cmd_client_info
Registration descriptor passed to the command subsystem.
#define GGA_ORTH_HEIGHT_UNIT_POS
#define VTG_SPEED_OVER_GROUND_POS
#define VTG_TMG_T_DEGREE_POS
static uint8_t nmea_cbuf_mem[128]
Backing memory for the NMEA sentence accumulation buffer.
#define GSV_NUM_SATS_VISIBLE_POS
#define GGA_ORTH_HEIGHT_POS
#define GGA_QUALITY_FIX_POS
static uint8_t usart_data_recv_cbuf_mem[128]
Backing memory for the USART receive circular buffer.
static CMD_INFO_ts neo6_cmds[]
Table of CLI commands registered by the NEO-6 subsystem.
NEO-6M GPS module public API.
STM32F401RE GPIO driver public API.
STM32F401RE USART driver public API.
Handle representing a circular buffer instance.
Describes a subsystem client registering with the command module.
Describes a single command exposed by a client.
Configuration structure for initializing a GPIO pin.
GPIO_ALTERNATE_FUNCTION_te alternate_function
GPIO peripheral register map.
Configuration structure for initializing a NEO-6 handle.
USART_REGDEF_ts * usart_instance
GPIO_REGDEF_ts * rx_gpio_port
GPIO_REGDEF_ts * tx_gpio_port
USART_BAUD_RATE_te usart_baud_rate
GPIO_ALTERNATE_FUNCTION_te gpio_alternate_function
Holds all GPS data fields parsed from incoming NMEA sentences.
Configuration structure for initializing a USART peripheral.
USART_BAUD_RATE_te baud_rate
USART_REGDEF_ts * instance
USART_INTERRUPT_EN_te interrupt_en
USART peripheral register map.
Internal state of the SysTick driver.
NEO6_HANDLE_ts neo6_handle
CBUF_HANDLE_ts usart_data_recv_cbuf
Internal structure representing the NEO-6 hardware instance.
USART_REGDEF_ts * usart_instance
USART_BAUD_RATE_te usart_baud_rate
GPIO_ALTERNATE_FUNCTION_te gpio_alternate_function
GPIO_REGDEF_ts * rx_gpio_port
GPIO_REGDEF_ts * tx_gpio_port