GPS Device
Loading...
Searching...
No Matches
main.c File Reference

Application entry point for the GPS tracking device. More...

#include <stdbool.h>
#include <stdint.h>
#include <string.h>
#include "arm_cortex_m4_systick.h"
#include "button.h"
#include "common.h"
#include "err.h"
#include "io.h"
#include "neo6.h"
#include "menu.h"
#include "stm32f401re.h"
#include "stm32f401re_gpio.h"
#include "console.h"
#include "ssd1309.h"
#include "datalog.h"
Include dependency graph for main.c:

Go to the source code of this file.

Functions

static void init_all (void)
 Initializes all subsystems and hardware peripherals.
static void run_all (void)
 Runs all subsystems for one iteration of the main loop.
static ERR_te acquire_neo6_location (uint8_t index, char **value_o)
 Data-view callback for the location menu.
static ERR_te acquire_datetime (uint8_t index, char **value_o)
 Data-view callback for the date/time menu.
static ERR_te acquire_movement (uint8_t index, char **value_o)
 Data-view callback for the movement menu.
static ERR_te acquire_accuracy (uint8_t index, char **value_o)
 Data-view callback for the accuracy menu.
static ERR_te acquire_satellites (uint8_t index, char **value_o)
 Data-view callback for the satellites menu.
int main (void)

Variables

SSD1309_HANDLE_tsssd1309_handle
BUTTON_HANDLE_tslbtn
BUTTON_HANDLE_tsmbtn
BUTTON_HANDLE_tsrbtn
MENU_HANDLE_tscurrent_menu
MENU_HANDLE_tsmain_menu
MENU_HANDLE_tslocation_menu
MENU_HANDLE_tsdatetime_menu
MENU_HANDLE_tsmovement_menu
MENU_HANDLE_tsaccuracy_menu
MENU_HANDLE_tssatellites_menu
NEO6_HANDLE_tsneo6_handle
DATALOG_HANDLE_tsdatalog_handle
bool lbtn_pushed = false
bool mbtn_pushed = false
bool rbtn_pushed = false
bool can_toggle_lbtn = true
bool can_toggle_mbtn = true
bool can_toggle_rbtn = true
bool mbtn_held = false
bool can_hold_mbtn = true
bool refresh = true
char selected_option [SSD1309_MAX_CHARS_IN_LINE]
uint32_t refreshed_ms

Detailed Description

Application entry point for the GPS tracking device.

Author
github.com/Baksi675

This file contains the top-level application logic for a GPS tracking device built on the STM32F401RE microcontroller. It ties together all subsystems and drives the main loop.

The device provides:

  • Real-time GPS data display on an SSD1309 OLED via a scrollable menu system
  • Three-button navigation (left scroll, middle select/back-hold, right scroll)
  • Periodic GPS data logging to SD card via the datalog module
  • A USART console for runtime command dispatch and log level control

Subsystem initialization order in init_all:

  1. IO (test LED)
  2. Console (USART1, log dependency initialized internally)
  3. SSD1309 OLED display
  4. Buttons (left, middle, right)
  5. NEO-6 GPS module
  6. Menu system (main, location, date/time, movement, accuracy, satellites)
  7. Datalog (SD card, 10-second interval)
Attention
On the prototype hardware, the FatFs diskio.c CS pin must be configured as GPIOB pin 6.
Version
0.1
Date
2026-01-01

Definition in file main.c.

Function Documentation

◆ init_all()

void init_all ( void )
static

Initializes all subsystems and hardware peripherals.

Called once at startup. Configures every subsystem in dependency order and sets current_menu to the top-level main menu. See the main.c file description for the full initialization sequence.

Definition at line 117 of file main.c.

117 {
118 GPIO_CFG_ts test_led = { 0 };
119 test_led.mode = GPIO_MODE_OUTPUT;
120 test_led.pin = GPIO_PIN_15;
121 test_led.port = GPIOB;
122 gpio_init(&test_led);
123 IO_CFG_ts io_test_led_conf = { 0 };
124 IO_HANDLE_ts *io_test_led_handle = { 0 };
125 io_test_led_conf.gpio_handle = &test_led;
126 str_cpy(io_test_led_conf.name, "test_led", get_str_len("test_led") + 1);
128 io_init_handle(&io_test_led_conf, &io_test_led_handle);
130
131 CONSOLE_HANDLE_ts console_handle = { 0 };
132 console_handle.usart_instance = USART1;
133 console_handle.usart_baud_rate = USART_BAUD_RATE_115200;
134 console_handle.gpio_port = GPIOA;
135 console_handle.gpio_pin = GPIO_PIN_10;
137 console_init(&console_handle);
138
139 SSD1309_CFG_ts ssd1309_conf = { 0 };
140 ssd1309_get_def_cfg(&ssd1309_conf);
141 ssd1309_conf.i2c_instance = I2C1;
143 ssd1309_conf.scl_gpio_pin = GPIO_PIN_8;
144 ssd1309_conf.scl_gpio_port = GPIOB;
145 ssd1309_conf.sda_gpio_pin = GPIO_PIN_9;
146 ssd1309_conf.sda_gpio_port = GPIOB;
148 ssd1309_init_handle(&ssd1309_conf, &ssd1309_handle);
150
151 BUTTON_CFG_ts lbtn_cfg = { 0 };
152 lbtn_cfg.gpio_port = GPIOB;
153 lbtn_cfg.gpio_pin = GPIO_PIN_5;
154 lbtn_cfg.debounce_limit_ms = 50;
155 lbtn_cfg.held_limit_ms = 1000;
157 str_cpy(lbtn_cfg.name, "leftbtn", get_str_len("leftbtn") + 1);
158
159 BUTTON_CFG_ts mbtn_cfg = { 0 };
160 mbtn_cfg.gpio_port = GPIOB;
161 mbtn_cfg.gpio_pin = GPIO_PIN_4;
162 mbtn_cfg.debounce_limit_ms = 50;
163 mbtn_cfg.held_limit_ms = 1000;
165 str_cpy(mbtn_cfg.name, "midbtn", get_str_len("midbtn") + 1);
166
167 BUTTON_CFG_ts rbtn_cfg = { 0 };
168 rbtn_cfg.gpio_port = GPIOB;
169 rbtn_cfg.gpio_pin = GPIO_PIN_10;
170 rbtn_cfg.debounce_limit_ms = 50;
171 rbtn_cfg.held_limit_ms = 1000;
173 str_cpy(rbtn_cfg.name, "rightbtn", get_str_len("rightbtn") + 1);
174
176 button_init_handle(&lbtn_cfg, &lbtn);
177 button_init_handle(&mbtn_cfg, &mbtn);
178 button_init_handle(&rbtn_cfg, &rbtn);
180
181 NEO6_CFG_ts neo6_cfg = { 0 };
182 neo6_cfg.usart_instance = USART6;
183 neo6_cfg.usart_baud_rate = 9600;
184 neo6_cfg.rx_gpio_port = GPIOA;
185 neo6_cfg.rx_gpio_pin = GPIO_PIN_12;
186 neo6_cfg.tx_gpio_port = GPIOA;
187 neo6_cfg.tx_gpio_pin = GPIO_PIN_11;
190 neo6_init_handle(&neo6_cfg, &neo6_handle);
192
193 MENU_CFG_ts main_menu_cfg = { 0 };
194 txt_cpy(main_menu_cfg.name, "main", get_str_len("main"));
195 txt_cpy(main_menu_cfg.title, " MENU ", 16);
196 txt_cpy(main_menu_cfg.options[0], "LOCATION", get_str_len("LOCATION"));
197 txt_cpy(main_menu_cfg.options[1], "DATE/TIME", get_str_len("DATE/TIME"));
198 txt_cpy(main_menu_cfg.options[2], "MOVEMENT", get_str_len("MOVEMENT"));
199 txt_cpy(main_menu_cfg.options[3], "ACCURACY", get_str_len("ACCURACY"));
200 txt_cpy(main_menu_cfg.options[4], "SATELLITES", get_str_len("SATELLITES"));
201 main_menu_cfg.type = MENU_TYPE_SELECTABLE;
202
203 MENU_CFG_ts location_menu_cfg = { 0 };
204 txt_cpy(location_menu_cfg.name, "loc", get_str_len("loc"));
205 txt_cpy(location_menu_cfg.title, " LOCATION ", 16);
206 txt_cpy(location_menu_cfg.options[0], "Latitude:", get_str_len("Latitude:"));
207 txt_cpy(location_menu_cfg.options[1], "Longitude:", get_str_len("Longitude:"));
208 txt_cpy(location_menu_cfg.options[2], "Orthometric h.:", get_str_len("Orthometric h.:"));
209 txt_cpy(location_menu_cfg.options[3], "Geoid sep.:", get_str_len("Geoid sep.:"));
210 location_menu_cfg.type = MENU_TYPE_DATA_VIEW;
211 location_menu_cfg.get_value_fn = acquire_neo6_location;
212
213 MENU_CFG_ts datetime_menu_cfg = { 0 };
214 txt_cpy(datetime_menu_cfg.name, "dt", get_str_len("dt"));
215 txt_cpy(datetime_menu_cfg.title, " DATE/TIME ", 16);
216 txt_cpy(datetime_menu_cfg.options[0], "Current date:", get_str_len("Current date:"));
217 txt_cpy(datetime_menu_cfg.options[1], "Current time:", get_str_len("Current time:"));
218 datetime_menu_cfg.type = MENU_TYPE_DATA_VIEW;
219 datetime_menu_cfg.get_value_fn = acquire_datetime;
220
221 MENU_CFG_ts movement_menu_cfg = { 0 };
222 txt_cpy(movement_menu_cfg.name, "mov", get_str_len("mov"));
223 txt_cpy(movement_menu_cfg.title, " MOVEMENT ", 16);
224 txt_cpy(movement_menu_cfg.options[0], "Movement speed:", get_str_len("Movement speed:"));
225 txt_cpy(movement_menu_cfg.options[1], "Movement dir.:", get_str_len("Movement dir.:"));
226 movement_menu_cfg.type = MENU_TYPE_DATA_VIEW;
227 movement_menu_cfg.get_value_fn = acquire_movement;
228
229 MENU_CFG_ts accuracy_menu_cfg = { 0 };
230 txt_cpy(accuracy_menu_cfg.name, "acc", get_str_len("acc"));
231 txt_cpy(accuracy_menu_cfg.title, " ACCURACY ", 16);
232 txt_cpy(accuracy_menu_cfg.options[0], "Fix status:", get_str_len("Fix status:"));
233 txt_cpy(accuracy_menu_cfg.options[1], "Fix type:", get_str_len("Fix type:"));
234 txt_cpy(accuracy_menu_cfg.options[2], "PDOP:", get_str_len("PDOP:"));
235 txt_cpy(accuracy_menu_cfg.options[3], "HDOP:", get_str_len("HDOP:"));
236 txt_cpy(accuracy_menu_cfg.options[4], "VDOP:", get_str_len("VDOP:"));
237 accuracy_menu_cfg.type = MENU_TYPE_DATA_VIEW;
238 accuracy_menu_cfg.get_value_fn = acquire_accuracy;
239
240 MENU_CFG_ts satellites_menu_cfg = { 0 };
241 txt_cpy(satellites_menu_cfg.name, "sats", get_str_len("sats"));
242 txt_cpy(satellites_menu_cfg.title, " SATELLITES ", 16);
243 txt_cpy(satellites_menu_cfg.options[0], "Num sats:", get_str_len("Num sats:"));
244 txt_cpy(satellites_menu_cfg.options[1], "Num sats used:", get_str_len("Num sats used:"));
245 satellites_menu_cfg.type = MENU_TYPE_DATA_VIEW;
246 satellites_menu_cfg.get_value_fn = acquire_satellites;
247
249 menu_init_handle(&main_menu_cfg, &main_menu);
250 menu_init_handle(&location_menu_cfg, &location_menu);
251 menu_init_handle(&datetime_menu_cfg, &datetime_menu);
252 menu_init_handle(&movement_menu_cfg, &movement_menu);
253 menu_init_handle(&accuracy_menu_cfg, &accuracy_menu);
254 menu_init_handle(&satellites_menu_cfg, &satellites_menu);
256
258
259 DATALOG_CFG_ts datalog_cfg = { 0 };
260 str_cpy(datalog_cfg.name, "datalog", get_str_len("datalog") + 1);
261 datalog_cfg.datalog_time = DATALOG_TIME_10S;
263 datalog_init_handle(&datalog_cfg, &datalog_handle);
265}
ERR_te button_init_subsys(void)
Initializes the button subsystem.
Definition button.c:159
ERR_te button_init_handle(BUTTON_CFG_ts *button_cfg, BUTTON_HANDLE_ts **button_handle)
Initializes and registers a button handle.
Definition button.c:269
ERR_te button_start_subsys(void)
Starts the button subsystem.
Definition button.c:221
@ BUTTON_PUSHED_TYPE_HIGH
Definition button.h:64
int str_cpy(char *str_to, const char *str_from, uint32_t len)
Copies a null-terminated string into a destination buffer.
Definition common.c:333
uint32_t get_str_len(char const *str)
Returns the length of a string, excluding the null terminator.
Definition common.c:22
int txt_cpy(char *txt_to, const char *txt_from, uint32_t len)
Copies a fixed-length block of text into a destination buffer.
Definition common.c:350
ERR_te console_init(CONSOLE_HANDLE_ts *console_handle)
Initializes the console subsystem.
Definition console.c:92
ERR_te datalog_init_handle(DATALOG_CFG_ts const *datalog_cfg, DATALOG_HANDLE_ts **datalog_handle_o)
Initializes and registers a data log handle.
Definition datalog.c:247
ERR_te datalog_start_subsys(void)
Starts the data log subsystem.
Definition datalog.c:199
ERR_te datalog_init_subsys(void)
Initializes the data log subsystem.
Definition datalog.c:137
@ DATALOG_TIME_10S
Definition datalog.h:58
ERR_te io_init_handle(IO_CFG_ts *io_cfg, IO_HANDLE_ts **io_handle_o)
Initializes and registers an IO handle.
Definition io.c:229
ERR_te io_start_subsys(void)
Starts the IO subsystem.
Definition io.c:181
ERR_te io_init_subsys(void)
Initializes the IO subsystem.
Definition io.c:120
struct io_handle_s IO_HANDLE_ts
Opaque handle representing an IO instance.
Definition io.h:69
ERR_te menu_init_handle(MENU_CFG_ts *menu_cfg, MENU_HANDLE_ts **menu_handle_o)
Initializes and registers a menu handle.
Definition menu.c:268
ERR_te menu_start_subsys(void)
Starts the menu subsystem.
Definition menu.c:220
ERR_te menu_init_subsys(void)
Initializes the menu subsystem.
Definition menu.c:159
@ MENU_TYPE_DATA_VIEW
Definition menu.h:67
@ MENU_TYPE_SELECTABLE
Definition menu.h:61
ERR_te neo6_start_subsys(void)
Starts the NEO-6 subsystem.
Definition neo6.c:274
ERR_te neo6_init_handle(NEO6_CFG_ts *neo6_cfg, NEO6_HANDLE_ts **neo6_handle_o)
Initializes the NEO-6 hardware handle.
Definition neo6.c:322
ERR_te neo6_init_subsys(void)
Initializes the NEO-6 subsystem.
Definition neo6.c:205
ERR_te ssd1309_init_handle(SSD1309_CFG_ts *ssd1309_cfg, SSD1309_HANDLE_ts **ssd1309_handle_o)
Initializes the SSD1309 display and sends the full configuration sequence over I2C.
Definition ssd1309.c:622
ERR_te ssd1309_init_subsys(void)
Initializes the SSD1309 subsystem.
Definition ssd1309.c:488
ERR_te ssd1309_start_subsys(void)
Starts the SSD1309 subsystem.
Definition ssd1309.c:551
ERR_te ssd1309_get_def_cfg(SSD1309_CFG_ts *ssd1309_cfg_o)
Populates a configuration structure with sensible default values.
Definition ssd1309.c:599
void gpio_init(GPIO_CFG_ts *gpio_cfg)
Initializes a GPIO pin according to the given configuration.
@ GPIO_PIN_5
@ GPIO_PIN_11
@ GPIO_PIN_8
@ GPIO_PIN_12
@ GPIO_PIN_10
@ GPIO_PIN_9
@ GPIO_PIN_15
@ GPIO_PIN_4
@ GPIO_ALTERNATE_FUNCTION_AF7
@ GPIO_ALTERNATE_FUNCTION_AF4
@ GPIO_ALTERNATE_FUNCTION_AF8
@ GPIO_MODE_OUTPUT
#define USART6
#define GPIOB
#define USART1
#define I2C1
#define GPIOA
MENU_HANDLE_ts * datetime_menu
Definition main.c:61
MENU_HANDLE_ts * satellites_menu
Definition main.c:64
static ERR_te acquire_neo6_location(uint8_t index, char **value_o)
Data-view callback for the location menu.
Definition main.c:391
BUTTON_HANDLE_ts * rbtn
Definition main.c:57
MENU_HANDLE_ts * movement_menu
Definition main.c:62
MENU_HANDLE_ts * main_menu
Definition main.c:59
static ERR_te acquire_satellites(uint8_t index, char **value_o)
Data-view callback for the satellites menu.
Definition main.c:472
DATALOG_HANDLE_ts * datalog_handle
Definition main.c:66
static ERR_te acquire_accuracy(uint8_t index, char **value_o)
Data-view callback for the accuracy menu.
Definition main.c:450
BUTTON_HANDLE_ts * mbtn
Definition main.c:56
MENU_HANDLE_ts * accuracy_menu
Definition main.c:63
MENU_HANDLE_ts * location_menu
Definition main.c:60
NEO6_HANDLE_ts * neo6_handle
Definition main.c:65
SSD1309_HANDLE_ts * ssd1309_handle
Definition main.c:54
static ERR_te acquire_movement(uint8_t index, char **value_o)
Data-view callback for the movement menu.
Definition main.c:431
MENU_HANDLE_ts * current_menu
Definition main.c:58
static ERR_te acquire_datetime(uint8_t index, char **value_o)
Data-view callback for the date/time menu.
Definition main.c:412
BUTTON_HANDLE_ts * lbtn
Definition main.c:55
Configuration structure for initializing a button instance.
Definition button.h:75
uint32_t debounce_limit_ms
Definition button.h:94
uint32_t held_limit_ms
Definition button.h:97
char name[CONFIG_BUTTON_MAX_NAME_LEN]
Definition button.h:78
GPIO_PIN_te gpio_pin
Definition button.h:84
GPIO_REGDEF_ts * gpio_port
Definition button.h:81
BUTTON_PUSHED_TYPE_te pushed_type
Definition button.h:91
Configuration handle for initializing the console subsystem.
Definition console.h:57
GPIO_PIN_te gpio_pin
Definition console.h:68
USART_BAUD_RATE_te usart_baud_rate
Definition console.h:62
GPIO_ALTERNATE_FUNCTION_te gpio_alternate_function
Definition console.h:71
GPIO_REGDEF_ts * gpio_port
Definition console.h:65
USART_REGDEF_ts * usart_instance
Definition console.h:59
Configuration structure for initializing a data log handle.
Definition datalog.h:72
char name[CONFIG_SD_MAX_NAME_LEN]
Definition datalog.h:74
DATALOG_TIME_te datalog_time
Definition datalog.h:77
Configuration structure for initializing a GPIO pin.
GPIO_REGDEF_ts * port
GPIO_PIN_te pin
GPIO_MODE_te mode
Configuration structure for initializing an IO handle.
Definition io.h:53
char name[CONFIG_IO_MAX_NAME_LEN]
Definition io.h:58
GPIO_CFG_ts * gpio_handle
Definition io.h:55
Configuration structure for initializing a menu handle.
Definition menu.h:78
MENU_TYPE_ts type
Definition menu.h:91
char title[SSD1309_MAX_CHARS_IN_LINE]
Definition menu.h:80
char options[CONFIG_MENU_MAX_OPTIONS][SSD1309_MAX_CHARS_IN_LINE]
Definition menu.h:88
ERR_te(* get_value_fn)(uint8_t index, char **value_o)
Definition menu.h:101
char name[CONFIG_MENU_MAX_NAME_LEN]
Definition menu.h:104
Configuration structure for initializing a NEO-6 handle.
Definition neo6.h:110
USART_REGDEF_ts * usart_instance
Definition neo6.h:112
GPIO_REGDEF_ts * rx_gpio_port
Definition neo6.h:118
GPIO_REGDEF_ts * tx_gpio_port
Definition neo6.h:124
USART_BAUD_RATE_te usart_baud_rate
Definition neo6.h:115
GPIO_PIN_te rx_gpio_pin
Definition neo6.h:121
GPIO_ALTERNATE_FUNCTION_te gpio_alternate_function
Definition neo6.h:130
GPIO_PIN_te tx_gpio_pin
Definition neo6.h:127
Full configuration structure for initializing an SSD1309 display handle.
Definition ssd1309.h:1046
GPIO_PIN_te scl_gpio_pin
Definition ssd1309.h:1054
GPIO_ALTERNATE_FUNCTION_te gpio_alternate_function
Definition ssd1309.h:1063
I2C_REGDEF_ts * i2c_instance
Definition ssd1309.h:1048
GPIO_REGDEF_ts * scl_gpio_port
Definition ssd1309.h:1051
GPIO_REGDEF_ts * sda_gpio_port
Definition ssd1309.h:1057
GPIO_PIN_te sda_gpio_pin
Definition ssd1309.h:1060
Here is the call graph for this function:

◆ run_all()

void run_all ( void )
static

Runs all subsystems for one iteration of the main loop.

Called on every iteration of the superloop in main. Performs the following steps in order:

  1. Updates the NEO-6 GPS parser.
  2. Processes any pending console input and dispatches commands.
  3. Appends a GPS log entry if the datalog interval has elapsed.
  4. Debounces and samples all three buttons.
  5. Handles button events:
    • Left button: scroll down.
    • Right button: scroll up.
    • Middle button press: navigate into the selected submenu.
    • Middle button hold: navigate back to the previous menu.
  6. Forces a display refresh every 1000 ms regardless of button activity.
  7. Redraws current_menu if refresh is set.
Note
Button events use an edge-detect pattern (can_toggle / can_hold flags) to prevent repeated triggering while a button remains held.

Definition at line 288 of file main.c.

288 {
289 neo6_run();
290
291 console_run();
292
294
296
300
302
305
306 refresh = true;
307 can_toggle_lbtn = false;
308 }
309 else if(!lbtn_pushed && !can_toggle_lbtn) {
310 can_toggle_lbtn = true;
311 }
312
315
316 if(current_menu == main_menu) {
317 if(str_cmp(selected_option, "LOCATION") == true) {
320 refresh = true;
321 }
322 else if(str_cmp(selected_option, "DATE/TIME") == true) {
325 refresh = true;
326 }
327 else if(str_cmp(selected_option, "MOVEMENT") == true) {
330 refresh = true;
331 }
332 else if(str_cmp(selected_option, "ACCURACY") == true) {
335 refresh = true;
336 }
337 else if(str_cmp(selected_option, "SATELLITES") == true) {
340 refresh = true;
341 }
342 }
343
344 can_toggle_mbtn = false;
345 }
346 else if(!mbtn_pushed && !can_toggle_mbtn) {
347 can_toggle_mbtn = true;
348 }
349
350 if(mbtn_held && can_hold_mbtn) {
351 MENU_HANDLE_ts *prev_menu = { 0 };
352
353 menu_get_prev_menu(current_menu, &prev_menu);
354 current_menu = prev_menu;
355 refresh = true;
356
357 can_hold_mbtn = false;
358 }
359 else if(!mbtn_held && !can_hold_mbtn) {
360 can_hold_mbtn = true;
361 }
362
365
366 refresh = true;
367 can_toggle_rbtn = false;
368 }
369 else if(!rbtn_pushed && !can_toggle_rbtn) {
370 can_toggle_rbtn = true;
371 }
372
373 if(systick_get_ms() - refreshed_ms >= 1000) {
374 refresh = true;
375 }
376
377 if(refresh) {
379 refresh = false;
381 }
382}
ERR_te button_run_handle_all(void)
Runs the state machine for all registered buttons.
Definition button.c:502
ERR_te button_get_pushed_state(BUTTON_HANDLE_ts const *button_handle, bool *pushed_state_o)
Retrieves the pushed (pressed) state of a button.
Definition button.c:516
ERR_te button_get_held_state(BUTTON_HANDLE_ts const *button_handle, bool *held_state_o)
Retrieves the held state of a button.
Definition button.c:533
bool str_cmp(const char *str1, const char *str2)
Compares two null-terminated strings for equality.
Definition common.c:248
@ DOWN
Definition common.h:108
@ UP
Definition common.h:111
ERR_te console_run(void)
Runs the console state machine. Must be called periodically.
Definition console.c:120
uint32_t systick_get_ms(void)
Returns the number of milliseconds elapsed since SysTick was initialized.
ERR_te datalog_run_handle(DATALOG_HANDLE_ts *datalog_handle)
Writes a GPS data entry to the log file if the logging interval has elapsed.
Definition datalog.c:384
ERR_te menu_get_prev_menu(MENU_HANDLE_ts *menu_handle, MENU_HANDLE_ts **prev_menu_handle_o)
Pops and returns the previous menu from the navigation history stack.
Definition menu.c:402
ERR_te menu_run_handle(MENU_HANDLE_ts *menu_handle)
Renders a single menu to the display.
Definition menu.c:340
ERR_te menu_scroll(MENU_HANDLE_ts *menu_handle, VERTICAL_DIR_te vertical_dir)
Moves the menu selection cursor by one step in the given direction.
Definition menu.c:387
ERR_te menu_get_selected_option(MENU_HANDLE_ts const *menu_handle, char *selected_option_o)
Retrieves the string of the currently highlighted option.
Definition menu.c:367
ERR_te menu_set_prev_menu(MENU_HANDLE_ts *menu_handle, MENU_HANDLE_ts *prev_menu_handle)
Pushes a menu onto the navigation history stack of another menu.
Definition menu.c:412
struct menu_handle_s MENU_HANDLE_ts
Opaque handle representing a menu instance.
Definition menu.h:115
ERR_te neo6_run(void)
Processes received NMEA data. Must be called periodically.
Definition neo6.c:387
char selected_option[SSD1309_MAX_CHARS_IN_LINE]
Definition main.c:91
bool mbtn_held
Definition main.c:84
bool rbtn_pushed
Definition main.c:80
uint32_t refreshed_ms
Definition main.c:94
bool can_toggle_mbtn
Definition main.c:82
bool can_toggle_lbtn
Definition main.c:81
bool can_toggle_rbtn
Definition main.c:83
bool refresh
Definition main.c:88
bool lbtn_pushed
Definition main.c:78
bool can_hold_mbtn
Definition main.c:85
bool mbtn_pushed
Definition main.c:79
Here is the call graph for this function:

◆ acquire_neo6_location()

ERR_te acquire_neo6_location ( uint8_t index,
char ** value_o )
static

Data-view callback for the location menu.

Returns GPS location fields from the NEO-6 info structure: index 0 = latitude, 1 = longitude, 2 = orthometric height, 3 = geoid separation.

Definition at line 391 of file main.c.

391 {
392 NEO6_INFO_ts *neo6_info = NULL;
393 neo6_get_info(&neo6_info);
394
395 switch(index) {
396 case 0: *value_o = neo6_info->lat; break;
397 case 1: *value_o = neo6_info->lon; break;
398 case 2: *value_o = neo6_info->ort_height; break;
399 case 3: *value_o = neo6_info->geoid_sep; break;
400 }
401
402 return ERR_OK;
403}
@ ERR_OK
Definition err.h:36
ERR_te neo6_get_info(NEO6_INFO_ts **neo6_info_o)
Returns a pointer to the internal GPS data structure.
Definition neo6.c:430
Holds all GPS data fields parsed from incoming NMEA sentences.
Definition neo6.h:85
char geoid_sep[16]
Definition neo6.h:89
char lon[16]
Definition neo6.h:87
char ort_height[16]
Definition neo6.h:88
char lat[16]
Definition neo6.h:86
Here is the call graph for this function:
Here is the caller graph for this function:

◆ acquire_datetime()

ERR_te acquire_datetime ( uint8_t index,
char ** value_o )
static

Data-view callback for the date/time menu.

Returns GPS date/time fields from the NEO-6 info structure: index 0 = date, 1 = time.

Definition at line 412 of file main.c.

412 {
413 NEO6_INFO_ts *neo6_info = NULL;
414 neo6_get_info(&neo6_info);
415
416 switch(index) {
417 case 0: *value_o = neo6_info->date; break;
418 case 1: *value_o = neo6_info->time; break;
419 }
420
421 return ERR_OK;
422}
char time[16]
Definition neo6.h:90
char date[16]
Definition neo6.h:91
Here is the call graph for this function:
Here is the caller graph for this function:

◆ acquire_movement()

ERR_te acquire_movement ( uint8_t index,
char ** value_o )
static

Data-view callback for the movement menu.

Returns movement fields from the NEO-6 info structure: index 0 = movement speed, 1 = movement direction.

Definition at line 431 of file main.c.

431 {
432 NEO6_INFO_ts *neo6_info = NULL;
433 neo6_get_info(&neo6_info);
434
435 switch(index) {
436 case 0: *value_o = neo6_info->mov_speed; break;
437 case 1: *value_o = neo6_info->mov_dir; break;
438 }
439
440 return ERR_OK;
441}
char mov_dir[16]
Definition neo6.h:92
char mov_speed[16]
Definition neo6.h:93
Here is the call graph for this function:
Here is the caller graph for this function:

◆ acquire_accuracy()

ERR_te acquire_accuracy ( uint8_t index,
char ** value_o )
static

Data-view callback for the accuracy menu.

Returns fix quality fields from the NEO-6 info structure: index 0 = fix status, 1 = fix type, 2 = PDOP, 3 = HDOP, 4 = VDOP.

Definition at line 450 of file main.c.

450 {
451 NEO6_INFO_ts *neo6_info = NULL;
452 neo6_get_info(&neo6_info);
453
454 switch(index) {
455 case 0: *value_o = neo6_info->fix_status; break;
456 case 1: *value_o = neo6_info->fix_type; break;
457 case 2: *value_o = neo6_info->pdop; break;
458 case 3: *value_o = neo6_info->hdop; break;
459 case 4: *value_o = neo6_info->vdop; break;
460 }
461
462 return ERR_OK;
463}
char pdop[16]
Definition neo6.h:97
char fix_type[16]
Definition neo6.h:96
char hdop[16]
Definition neo6.h:98
char vdop[16]
Definition neo6.h:99
char fix_status[16]
Definition neo6.h:100
Here is the call graph for this function:
Here is the caller graph for this function:

◆ acquire_satellites()

ERR_te acquire_satellites ( uint8_t index,
char ** value_o )
static

Data-view callback for the satellites menu.

Returns satellite count fields from the NEO-6 info structure: index 0 = total satellites in view, 1 = satellites used in fix.

Definition at line 472 of file main.c.

472 {
473 NEO6_INFO_ts *neo6_info = NULL;
474 neo6_get_info(&neo6_info);
475
476 switch(index) {
477 case 0: *value_o = neo6_info->num_sats_all; break;
478 case 1: *value_o = neo6_info->num_sats_used; break;
479 }
480
481 return ERR_OK;
482}
char num_sats_all[4]
Definition neo6.h:95
char num_sats_used[4]
Definition neo6.h:94
Here is the call graph for this function:
Here is the caller graph for this function:

◆ main()

int main ( void )

Definition at line 96 of file main.c.

96 {
97 init_all();
98
99 // Delay here is needed to not crash the system
100 DELAY(50);
101
102 while(1) {
103 run_all();
104 }
105
106 return 0;
107}
#define DELAY(ms)
Blocking delay using the system tick counter.
Definition common.h:65
static void run_all(void)
Runs all subsystems for one iteration of the main loop.
Definition main.c:288
static void init_all(void)
Initializes all subsystems and hardware peripherals.
Definition main.c:117

Variable Documentation

◆ ssd1309_handle

SSD1309_HANDLE_ts* ssd1309_handle

OLED display handle.

Definition at line 54 of file main.c.

◆ lbtn

Left button handle.

Definition at line 55 of file main.c.

◆ mbtn

Middle button handle (select / back-hold).

Definition at line 56 of file main.c.

◆ rbtn

Right button handle.

Definition at line 57 of file main.c.

◆ current_menu

MENU_HANDLE_ts* current_menu

Pointer to the menu currently displayed.

Definition at line 58 of file main.c.

◆ main_menu

MENU_HANDLE_ts* main_menu

Top-level selectable menu.

Definition at line 59 of file main.c.

◆ location_menu

MENU_HANDLE_ts* location_menu

Data-view menu: latitude, longitude, height, geoid.

Definition at line 60 of file main.c.

◆ datetime_menu

MENU_HANDLE_ts* datetime_menu

Data-view menu: GPS date and time.

Definition at line 61 of file main.c.

◆ movement_menu

MENU_HANDLE_ts* movement_menu

Data-view menu: speed and direction.

Definition at line 62 of file main.c.

◆ accuracy_menu

MENU_HANDLE_ts* accuracy_menu

Data-view menu: fix status, fix type, DOP values.

Definition at line 63 of file main.c.

◆ satellites_menu

MENU_HANDLE_ts* satellites_menu

Data-view menu: satellite counts.

Definition at line 64 of file main.c.

◆ neo6_handle

NEO6_HANDLE_ts* neo6_handle

NEO-6 GPS module handle.

Definition at line 65 of file main.c.

◆ datalog_handle

DATALOG_HANDLE_ts* datalog_handle

SD card data log handle.

Definition at line 66 of file main.c.

◆ lbtn_pushed

bool lbtn_pushed = false

True while the left button is held down.

Definition at line 78 of file main.c.

◆ mbtn_pushed

bool mbtn_pushed = false

True while the middle button is held down.

Definition at line 79 of file main.c.

◆ rbtn_pushed

bool rbtn_pushed = false

True while the right button is held down.

Definition at line 80 of file main.c.

◆ can_toggle_lbtn

bool can_toggle_lbtn = true

Edge-detect guard for the left button.

Definition at line 81 of file main.c.

◆ can_toggle_mbtn

bool can_toggle_mbtn = true

Edge-detect guard for the middle button.

Definition at line 82 of file main.c.

◆ can_toggle_rbtn

bool can_toggle_rbtn = true

Edge-detect guard for the right button.

Definition at line 83 of file main.c.

◆ mbtn_held

bool mbtn_held = false

True when the middle button has been held long enough.

Definition at line 84 of file main.c.

◆ can_hold_mbtn

bool can_hold_mbtn = true

Edge-detect guard for the middle button hold.

Definition at line 85 of file main.c.

◆ refresh

bool refresh = true

True when the display should be redrawn on the next iteration.

Definition at line 88 of file main.c.

◆ selected_option

char selected_option[SSD1309_MAX_CHARS_IN_LINE]

Buffer for the option string returned by menu_get_selected_option.

Definition at line 91 of file main.c.

◆ refreshed_ms

uint32_t refreshed_ms

Systick timestamp (ms) of the most recent display refresh.

Definition at line 94 of file main.c.