GPS Device
Loading...
Searching...
No Matches
NEO-6 Public API

Public functions to interact with the NEO-6 GPS subsystem. More...

Collaboration diagram for NEO-6 Public API:

Functions

ERR_te neo6_init_subsys (void)
 Initializes the NEO-6 subsystem.
ERR_te neo6_deinit_subsys (void)
 Deinitializes the NEO-6 subsystem.
ERR_te neo6_start_subsys (void)
 Starts the NEO-6 subsystem.
ERR_te neo6_stop_subsys (void)
 Stops 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_run (void)
 Processes received NMEA data. Must be called periodically.
ERR_te neo6_get_info (NEO6_INFO_ts **neo6_info_o)
 Returns a pointer to the internal GPS data structure.

Detailed Description

Public functions to interact with the NEO-6 GPS subsystem.

Function Documentation

◆ neo6_init_subsys()

ERR_te neo6_init_subsys ( void )

Initializes the NEO-6 subsystem.

Resets the internal state, initializes the USART receive circular buffers, initializes the logging dependency, and registers the CLI commands.

Must be called before any other NEO-6 API function.

Returns
  • ERR_OK on success
  • ERR_MODULE_ALREADY_INITIALIZED if the subsystem is already initialized
  • Propagated error from cmd_register on failure
See also
neo6_init_subsys

Definition at line 205 of file neo6.c.

205 {
206 ERR_te err;
207
208 if(internal_state.initialized) {
210 }
211
212 internal_state = (struct internal_state_s){ 0 };
213 internal_state.log_level = LOG_LEVEL_INFO;
215 internal_state.usart_data_recv_cbuf.ptr = usart_data_recv_cbuf_mem;
216 internal_state.usart_data_recv_cbuf.size = sizeof(usart_data_recv_cbuf_mem);
217 internal_state.nmea_cbuf.ptr = nmea_cbuf_mem;
218 internal_state.nmea_cbuf.size = sizeof(nmea_cbuf_mem);
219 internal_state.dump_raw_nmea = false;
220 internal_state.initialized = true;
221 internal_state.started = false;
222
223 init_log();
224
226 if(err != ERR_OK) {
227 LOG_ERROR(
228 internal_state.subsys,
229 internal_state.log_level,
230 "neo6_init_subsys: cmd_register error"
231 );
232
233 return err;
234 }
235
236 LOG_INFO(
237 internal_state.subsys,
238 internal_state.log_level,
239 "neo6_init_subsys: subsys initialized"
240 );
241
242 return ERR_OK;
243}
static struct internal_state_s internal_state
Singleton instance of the SysTick driver internal state.
ERR_te cmd_register(CMD_CLIENT_INFO_ts *cmd_client_info)
Registers a client with the command subsystem.
Definition cmd.c:51
ERR_te
Standard return type used by all public API functions.
Definition err.h:35
@ ERR_OK
Definition err.h:36
@ ERR_MODULE_ALREADY_INITIALIZED
Definition err.h:54
ERR_te init_log(void)
Initializes the logging subsystem.
Definition init.c:25
#define LOG_ERROR(subsys, lvl, fmt,...)
Definition log.h:258
#define LOG_INFO(subsys, lvl, fmt,...)
Definition log.h:255
@ LOG_LEVEL_INFO
Definition log.h:64
@ MODULES_NEO6
Definition modules.h:45
static CMD_CLIENT_INFO_ts neo6_cmd_client_info
Registration descriptor passed to the command subsystem.
Definition neo6.c:192
static uint8_t nmea_cbuf_mem[128]
Backing memory for the NMEA sentence accumulation buffer.
Definition neo6.c:83
static uint8_t usart_data_recv_cbuf_mem[128]
Backing memory for the USART receive circular buffer.
Definition neo6.c:75
Internal state of the SysTick driver.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ neo6_deinit_subsys()

ERR_te neo6_deinit_subsys ( void )

Deinitializes the NEO-6 subsystem.

Resets the internal state to zero and deregisters the CLI commands. The subsystem must be stopped before calling this function.

Returns
  • ERR_OK on success
  • ERR_DEINITIALIZATION_FAILURE if the subsystem is not initialized or still running
  • Propagated error from cmd_deregister on failure
See also
neo6_deinit_subsys

Definition at line 246 of file neo6.c.

246 {
247 if(internal_state.initialized && !internal_state.started) {
248 internal_state = (struct internal_state_s){ 0 };
249
251 if(err != ERR_OK) {
252 return err;
253 }
254 }
255 else {
256 LOG_ERROR(
257 internal_state.subsys,
258 internal_state.log_level,
259 "neo6_deinit_subsys: subsys is not initialized or stopped"
260 );
261
263 }
264
265 LOG_INFO(
266 internal_state.subsys,
267 internal_state.log_level,
268 "neo6_deinit_subsys: subsystem deinitialized"
269 );
270 return ERR_OK;
271}
ERR_te cmd_deregister(CMD_CLIENT_INFO_ts const *cmd_client_info)
Deregisters a client from the command subsystem.
Definition cmd.c:66
@ ERR_DEINITIALIZATION_FAILURE
Definition err.h:44
Here is the call graph for this function:

◆ neo6_start_subsys()

ERR_te neo6_start_subsys ( void )

Starts the NEO-6 subsystem.

Returns
  • ERR_OK on success
  • ERR_UNKNOWN if the subsystem is not initialized or already started
See also
neo6_start_subsys

Definition at line 274 of file neo6.c.

274 {
275 if(internal_state.initialized && !internal_state.started) {
276 internal_state.started = true;
277
278 LOG_INFO(
279 internal_state.subsys,
280 internal_state.log_level,
281 "neo6_start_subsys: subsys started"
282 );
283 }
284 else {
285 LOG_ERROR(
286 internal_state.subsys,
287 internal_state.log_level,
288 "neo6_start_subsys: subsys not initialized or already started"
289 );
290
291 return ERR_UNKNOWN;
292 }
293
294 return ERR_OK;
295}
@ ERR_UNKNOWN
Definition err.h:37
Here is the caller graph for this function:

◆ neo6_stop_subsys()

ERR_te neo6_stop_subsys ( void )

Stops the NEO-6 subsystem.

Returns
  • ERR_OK on success
  • ERR_UNKNOWN if the subsystem is not initialized or already stopped
See also
neo6_stop_subsys

Definition at line 298 of file neo6.c.

298 {
299 if(internal_state.initialized && internal_state.started) {
300 internal_state.started = false;
301
302 LOG_INFO(
303 internal_state.subsys,
304 internal_state.log_level,
305 "neo6_stop_subsys: subsys stopped"
306 );
307 }
308 else {
309 LOG_ERROR(
310 internal_state.subsys,
311 internal_state.log_level,
312 "neo6_stop_subsys: subsys not initialized or already already stopped"
313 );
314
315 return ERR_UNKNOWN;
316 }
317
318 return ERR_OK;
319}

◆ neo6_init_handle()

ERR_te neo6_init_handle ( NEO6_CFG_ts * neo6_cfg,
NEO6_HANDLE_ts ** neo6_handle_o )

Initializes the NEO-6 hardware handle.

Configures the USART peripheral with interrupt-driven reception and initializes both the RX and TX GPIO pins in alternate function mode.

Note
Only one handle instance is supported. Calling this function a second time without deinitialization returns an error.
Parameters
[in]neo6_cfgPointer to the NEO-6 configuration structure.
[out]neo6_handle_oPointer to a handle pointer that will be set to the initialized instance.
Returns
  • ERR_OK on success
  • ERR_INITIALIZATION_FAILURE if a handle is already initialized, or if the USART or GPIO pointers in neo6_cfg are NULL
See also
neo6_init_handle

Definition at line 322 of file neo6.c.

322 {
323 if(internal_state.neo6_handle.initialized == true) {
324 LOG_ERROR(
325 internal_state.subsys,
326 internal_state.log_level,
327 "neo6_init_handle: handle already initialized"
328 );
329
331 }
332
333 if(neo6_cfg->usart_instance == (void*)0) {
334 LOG_ERROR(
335 internal_state.subsys,
336 internal_state.log_level,
337 "neo6_init_handle: No USART peripheral given"
338 );
339
341 }
342 else if(neo6_cfg->rx_gpio_port == (void*)0 || neo6_cfg->tx_gpio_port == (void*)0) {
343 LOG_ERROR(
344 internal_state.subsys,
345 internal_state.log_level,
346 "neo6_init_handle: No GPIO peripheral given"
347 );
348
350 }
351
352 internal_state.neo6_handle.usart_instance = neo6_cfg->usart_instance;
353 internal_state.neo6_handle.usart_baud_rate = neo6_cfg->usart_baud_rate;
354 internal_state.neo6_handle.rx_gpio_port = neo6_cfg->rx_gpio_port;
355 internal_state.neo6_handle.tx_gpio_port = neo6_cfg->tx_gpio_port;
356 internal_state.neo6_handle.rx_gpio_pin = neo6_cfg->rx_gpio_pin;
357 internal_state.neo6_handle.tx_gpio_pin = neo6_cfg->tx_gpio_pin;
358 internal_state.neo6_handle.gpio_alternate_function = neo6_cfg->gpio_alternate_function;
359
360 USART_CFG_ts neo6_usart = { 0 };
361 neo6_usart.instance = neo6_cfg->usart_instance;
362 neo6_usart.baud_rate = neo6_cfg->usart_baud_rate;
364 usart_init(&neo6_usart);
366
367 GPIO_CFG_ts neo6_rx = { 0 };
368 neo6_rx.port = neo6_cfg->rx_gpio_port;
369 neo6_rx.pin = neo6_cfg->rx_gpio_pin;
372 gpio_init(&neo6_rx);
373
374 GPIO_CFG_ts neo6_tx = { 0 };
375 neo6_tx.port = neo6_cfg->tx_gpio_port;
376 neo6_tx.pin = neo6_cfg->tx_gpio_pin;
379 gpio_init(&neo6_tx);
380
381 internal_state.neo6_handle.initialized = true;
382
383 return ERR_OK;
384}
@ ENABLE
Definition common.h:100
@ ERR_INITIALIZATION_FAILURE
Definition err.h:43
void gpio_init(GPIO_CFG_ts *gpio_cfg)
Initializes a GPIO pin according to the given configuration.
@ GPIO_MODE_ALTERNATE_FUNCTION
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_INTERRUPT_EN_TRUE
Configuration structure for initializing a GPIO pin.
GPIO_REGDEF_ts * port
GPIO_ALTERNATE_FUNCTION_te alternate_function
GPIO_PIN_te pin
GPIO_MODE_te mode
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
Configuration structure for initializing a USART peripheral.
USART_BAUD_RATE_te baud_rate
USART_REGDEF_ts * instance
USART_INTERRUPT_EN_te interrupt_en
Here is the call graph for this function:
Here is the caller graph for this function:

◆ neo6_run()

ERR_te neo6_run ( void )

Processes received NMEA data. Must be called periodically.

Drains bytes from the USART receive circular buffer into the NMEA accumulation buffer. Each time a newline character is detected, the complete sentence is extracted, its checksum is verified, and it is dispatched to the appropriate parser (RMC, VTG, GGA, GSA, or GSV).

Parsed values are written directly into the internal NEO6_INFO_ts structure and are accessible via neo6_get_info.

Note
Known limitation: if a received chunk contains the end of one sentence and the start of the next, the second sentence is lost. This does not currently cause observable issues.
Returns
  • ERR_OK on success
  • ERR_DATA_ACQUISITION_FAILURE if a sentence fails its checksum verification
  • ERR_UNKNOWN if a checksum cannot be computed (malformed sentence)

Processes received NMEA data. Must be called periodically.

See also
neo6_run

Definition at line 387 of file neo6.c.

387 {
388 uint8_t data_len = 0;
389 cbuf_len(&internal_state.usart_data_recv_cbuf, &data_len);
390
391 if(data_len) {
392 uint8_t data[data_len];
393
394 cbuf_read(&internal_state.usart_data_recv_cbuf, data);
395
396 cbuf_write(&internal_state.nmea_cbuf, data, data_len);
397
398 for(uint32_t i = 0; i < data_len; i++) {
399 if(data[i] == '\n') {
400 uint8_t nmea_len = 0;
401 cbuf_len(&internal_state.nmea_cbuf, &nmea_len);
402
403 uint8_t nmea_msg[nmea_len];
404 cbuf_read(&internal_state.nmea_cbuf, nmea_msg);
405
406 nmea_msg[nmea_len - 2] = '\0';
407 nmea_msg[nmea_len - 1] = '\0';
408
409 if(internal_state.dump_raw_nmea == true) {
410 LOG_INFO(
411 internal_state.subsys,
412 internal_state.log_level,
413 "%s", nmea_msg
414 );
415 }
416
417 // Process NMEA message
418 ERR_te err = neo6_process_msg(nmea_msg, nmea_len);
419 if(err != ERR_OK) {
420 return err;
421 }
422 }
423 }
424 }
425
426 return ERR_OK;
427}
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.
Definition cbuf.c:22
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.
Definition cbuf.c:61
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.
Definition cbuf.c:41
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.
Definition neo6.c:501
Here is the call graph for this function:
Here is the caller graph for this function:

◆ neo6_get_info()

ERR_te neo6_get_info ( NEO6_INFO_ts ** neo6_info_o)

Returns a pointer to the internal GPS data structure.

The returned pointer is valid for the lifetime of the subsystem. The structure is updated in place on each successful NMEA parse. The caller must not free or modify the returned pointer.

Parameters
[out]neo6_info_oPointer to a pointer that will be set to the internal NEO6_INFO_ts structure.
Returns
  • ERR_OK always
See also
neo6_get_info

Definition at line 430 of file neo6.c.

430 {
431 *neo6_info_o = &internal_state.neo6_info;
432
433 return ERR_OK;
434}
Here is the caller graph for this function: