GPS Device
Loading...
Searching...
No Matches
Data Log Public APIs

Functions

ERR_te datalog_init_subsys (void)
 Initializes the data log subsystem.
ERR_te datalog_deinit_subsys (void)
 Deinitializes the data log subsystem.
ERR_te datalog_start_subsys (void)
 Starts the data log subsystem.
ERR_te datalog_stop_subsys (void)
 Stops the data log subsystem.
ERR_te datalog_init_handle (DATALOG_CFG_ts const *datalog_cfg, DATALOG_HANDLE_ts **datalog_handle_o)
 Initializes and registers a data log handle.
ERR_te datalog_deinit_handle (DATALOG_HANDLE_ts const *datalog_handle)
 Deinitializes a data log handle.
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.

Detailed Description

Function Documentation

◆ datalog_init_subsys()

ERR_te datalog_init_subsys ( void )

Initializes the data log subsystem.

See also
datalog_init_subsys

Definition at line 137 of file datalog.c.

137 {
138 ERR_te err;
139
140 if(internal_state.initialized) {
142 }
143
144 internal_state = (struct internal_state_s){ 0 };
145
146 internal_state.log_level = LOG_LEVEL_INFO;
148 internal_state.initialized = true;
149 internal_state.started = false;
150
151 init_log();
152 init_systick();
153 init_neo6();
154
156 if(err != ERR_OK) {
157 LOG_ERROR(
158 internal_state.subsys,
159 internal_state.log_level,
160 "datalog_init_subsys: cmd_register error"
161 );
162 return err;
163 }
164 LOG_INFO(
165 internal_state.subsys,
166 internal_state.log_level,
167 "datalog_init_subsys: subsys initialized"
168 );
169
170 return ERR_OK;
171}
static struct internal_state_s internal_state
Singleton instance of the SysTick driver internal state.
CMD_CLIENT_INFO_ts datalog_cmd_client_info
Registration descriptor passed to the command subsystem.
Definition datalog.c:124
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
ERR_te init_neo6(void)
Initializes the NEO-6 GPS module.
Definition init.c:52
ERR_te init_systick(void)
Initializes the SysTick timer.
Definition init.c:40
#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_DATALOG
Definition modules.h:50
Internal state of the SysTick driver.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ datalog_deinit_subsys()

ERR_te datalog_deinit_subsys ( void )

Deinitializes the data log subsystem.

See also
datalog_deinit_subsys

Definition at line 174 of file datalog.c.

174 {
175 if(internal_state.initialized) {
176 internal_state = (struct internal_state_s){ 0 };
177
179 }
180 else {
181 LOG_ERROR(
182 internal_state.subsys,
183 internal_state.log_level,
184 "datalog_deinit_subsys: subsys is not initialized"
185 );
186
188 }
189 LOG_INFO(
190 internal_state.subsys,
191 internal_state.log_level,
192 "datalog_deinit_subsys: subsys deinitialized"
193 );
194
195 return ERR_OK;
196}
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:

◆ datalog_start_subsys()

ERR_te datalog_start_subsys ( void )

Starts the data log subsystem.

See also
datalog_start_subsys

Definition at line 199 of file datalog.c.

199 {
200 if(internal_state.initialized && !internal_state.started) {
201 internal_state.started = true;
202
203 LOG_INFO(
204 internal_state.subsys,
205 internal_state.log_level,
206 "datalog_start_subsys: subsys started"
207 );
208 }
209 else {
210 LOG_ERROR(
211 internal_state.subsys,
212 internal_state.log_level,
213 "datalog_start_subsys: subsys not initialized or already started"
214 );
215
216 return ERR_UNKNOWN;
217 }
218
219 return ERR_OK;
220}
@ ERR_UNKNOWN
Definition err.h:37
Here is the caller graph for this function:

◆ datalog_stop_subsys()

ERR_te datalog_stop_subsys ( void )

Stops the data log subsystem.

See also
datalog_stop_subsys

Definition at line 223 of file datalog.c.

223 {
224 if(internal_state.initialized && internal_state.started) {
225 internal_state.started = false;
226
227 LOG_INFO(
228 internal_state.subsys,
229 internal_state.log_level,
230 "datalog_stop_subsys: subsys stopped"
231 );
232 }
233 else {
234 LOG_ERROR(
235 internal_state.subsys,
236 internal_state.log_level,
237 "datalog_stop_subsys: subsys not initialized or already already stopped"
238 );
239
240 return ERR_UNKNOWN;
241 }
242
243 return ERR_OK;
244}

◆ datalog_init_handle()

ERR_te datalog_init_handle ( DATALOG_CFG_ts const * datalog_cfg,
DATALOG_HANDLE_ts ** datalog_handle_o )

Initializes and registers a data log handle.

See also
datalog_init_handle

Definition at line 247 of file datalog.c.

247 {
248 uint8_t free_index;
249
250 if(!internal_state.initialized) {
251 LOG_ERROR(
252 internal_state.subsys,
253 internal_state.log_level,
254 "datalog_init_handle: subsys not initialized"
255 );
256
258 }
259
260 if(internal_state.datalog_num == CONFIG_DATALOG_MAX_OBJECTS) {
262 internal_state.subsys,
263 internal_state.log_level,
264 "datalog_init_handle: subsystem out of memory space"
265 );
266
268 }
269
270 if(!datalog_cfg) {
271 LOG_ERROR(
272 internal_state.subsys,
273 internal_state.log_level,
274 "datalog_init_handle: invalid argument"
275 );
277 }
278
279 bool found = false;
280
281 for(uint32_t i = 0; i < CONFIG_DATALOG_MAX_OBJECTS; i++) {
282 if(!internal_state.datalogs[i].in_use) {
283 free_index = i;
284 found = true;
285 break;
286 }
287 }
288
289 if(!found)
291
292 // Mount filesystem
293 internal_state.datalogs[free_index].fr = f_mount(&internal_state.datalogs[free_index].fs, "0:", 1);
294 if (internal_state.datalogs[free_index].fr != FR_OK) {
296 }
297
298 // Create / open file
299 internal_state.datalogs[free_index].fr = f_open(&internal_state.datalogs[free_index].fil, "0:datalog.txt", FA_CREATE_ALWAYS | FA_WRITE);
300 if (internal_state.datalogs[free_index].fr != FR_OK) {
302 }
303
304 f_close(&internal_state.datalogs[free_index].fil);
305
306 str_cpy(
307 internal_state.datalogs[free_index].name,
308 datalog_cfg->name,
309 get_str_len(datalog_cfg->name) + 1
310 );
311 internal_state.datalogs[free_index].datalog_time = datalog_cfg->datalog_time;
312 internal_state.datalogs[free_index].in_use = true;
313
314 internal_state.datalog_num++;
315
316 *datalog_handle_o = &internal_state.datalogs[free_index];
317
318 LOG_INFO(
319 internal_state.subsys,
320 internal_state.log_level,
321 "datalog_init_handle: handle %s initialized",
322 internal_state.datalogs[free_index].name
323 );
324
325 return ERR_OK;
326}
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
@ ERR_NOT_ENOUGH_SPACE
Definition err.h:49
@ ERR_INITIALIZATION_FAILURE
Definition err.h:43
@ ERR_INVALID_ARGUMENT
Definition err.h:38
#define LOG_CRITICAL(subsys, lvl, fmt,...)
Definition log.h:259
Here is the call graph for this function:
Here is the caller graph for this function:

◆ datalog_deinit_handle()

ERR_te datalog_deinit_handle ( DATALOG_HANDLE_ts const * datalog_handle)

Deinitializes a data log handle.

See also
datalog_deinit_handle

Definition at line 329 of file datalog.c.

329 {
330 if(!datalog_handle->initialized) {
331 LOG_ERROR(
332 internal_state.subsys,
333 internal_state.log_level,
334 "datalog_deinit_handle: handle not initialized"
335 );
336 return ERR_ILLEGAL_ACTION;
337 }
338
339 if(internal_state.datalog_num == 0) {
340 LOG_ERROR(
341 internal_state.subsys,
342 internal_state.log_level,
343 "datalog_deinit_handle: no such handle to deinitialize"
344 );
345
347 }
348
349 for(uint32_t i = 0; i < CONFIG_DATALOG_MAX_OBJECTS; i++) {
350 if(&internal_state.datalogs[i] == datalog_handle) {
351 uint8_t name_len = get_str_len(internal_state.datalogs[i].name) + 1;
352 char name[name_len];
353 str_cpy(name, internal_state.datalogs[i].name, name_len);
354
355 internal_state.datalogs[i] = (DATALOG_HANDLE_ts){ 0 };
356
357 internal_state.datalog_num--;
358
359 LOG_INFO(
360 internal_state.subsys,
361 internal_state.log_level,
362 "datalog_deinit_handle: handle %s deinitialized",
363 name
364 );
365
366 break;
367 }
368
369 if(i == CONFIG_DATALOG_MAX_OBJECTS - 1) {
370 LOG_ERROR(
371 internal_state.subsys,
372 internal_state.log_level,
373 "datalog_deinit_handle: no such handle to deinitialize"
374 );
375
377 }
378 }
379
380 return ERR_OK;
381}
struct datalog_handle_s DATALOG_HANDLE_ts
Opaque handle representing a data log instance.
Definition datalog.h:88
@ ERR_UNINITIALZIED_OBJECT
Definition err.h:42
@ ERR_ILLEGAL_ACTION
Definition err.h:50
DATALOG_HANDLE_ts * datalog_handle
Definition main.c:66
Here is the call graph for this function:

◆ datalog_run_handle()

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.

See also
datalog_run_handle

Definition at line 384 of file datalog.c.

384 {
385 uint32_t time = systick_get_ms();
386
387 // Time interval has not been reached yet, return
388 if(time - datalog_handle->last_upd_time < datalog_handle->datalog_time * 1000) {
389 return ERR_OK;
390 }
391
392 // Open file
393 datalog_handle->fr = f_open(&datalog_handle->fil, "0:datalog.txt", FA_OPEN_APPEND | FA_WRITE);
394 if (datalog_handle->fr != FR_OK) {
395 return ERR_UNKNOWN;
396 }
397
398 NEO6_INFO_ts *neo6_info = (void*)0;
399 neo6_get_info(&neo6_info);
400
401 // Set up time string
402 uint32_t time_len = get_str_len(neo6_info->time) + 2;
403 char time_str[time_len];
404 str_cpy(time_str, neo6_info->time, time_len - 2);
405 time_str[time_len - 2] = '\r';
406 time_str[time_len - 1] = '\n';
407
408 // Write time string to file
409 datalog_handle->fr = f_write(&datalog_handle->fil, time_str, time_len, &datalog_handle->bw);
410 if (datalog_handle->fr != FR_OK || datalog_handle->bw != time_len) {
411 f_close(&datalog_handle->fil);
412 return ERR_UNKNOWN;
413 }
414
415 // Set up latitude string
416 uint32_t lat_len = get_str_len(neo6_info->lat) + 2;
417 char lat_str[lat_len];
418 str_cpy(lat_str, neo6_info->lat, lat_len - 2);
419 lat_str[lat_len - 2] = '\r';
420 lat_str[lat_len - 1] = '\n';
421
422 // Write latitude string to file
423 datalog_handle->fr = f_write(&datalog_handle->fil, lat_str, lat_len, &datalog_handle->bw);
424 if (datalog_handle->fr != FR_OK || datalog_handle->bw != lat_len) {
425 f_close(&datalog_handle->fil);
426 return ERR_UNKNOWN;
427 }
428
429 // Set up longitude string
430 uint32_t lon_len = get_str_len(neo6_info->lon) + 2;
431 char lon_str[lon_len];
432 str_cpy(lon_str, neo6_info->lon, lon_len - 2);
433 lon_str[lon_len - 2] = '\r';
434 lon_str[lon_len - 1] = '\n';
435
436 // Write longitude string to file
437 datalog_handle->fr = f_write(&datalog_handle->fil, lon_str, lon_len, &datalog_handle->bw);
438 if (datalog_handle->fr != FR_OK || datalog_handle->bw != lon_len) {
439 f_close(&datalog_handle->fil);
440 return ERR_UNKNOWN;
441 }
442
443 // Set up orthometric height string
444 uint32_t ort_height_len = get_str_len(neo6_info->ort_height) + 2;
445 char ort_height_str[ort_height_len];
446 str_cpy(ort_height_str, neo6_info->ort_height, ort_height_len - 2);
447 ort_height_str[ort_height_len - 2] = '\r';
448 ort_height_str[ort_height_len - 1] = '\n';
449
450 // Write orthometric height string to file
451 datalog_handle->fr = f_write(&datalog_handle->fil, ort_height_str, ort_height_len, &datalog_handle->bw);
452 if (datalog_handle->fr != FR_OK || datalog_handle->bw != ort_height_len) {
453 f_close(&datalog_handle->fil);
454 return ERR_UNKNOWN;
455 }
456
457 // Set up movement speed string
458 uint32_t mov_speed_len = get_str_len(neo6_info->mov_speed) + 2;
459 char mov_speed_str[mov_speed_len];
460 str_cpy(mov_speed_str, neo6_info->mov_speed, mov_speed_len - 2);
461 mov_speed_str[mov_speed_len - 2] = '\r';
462 mov_speed_str[mov_speed_len - 1] = '\n';
463
464 // Write movement speed string to file
465 datalog_handle->fr = f_write(&datalog_handle->fil, mov_speed_str, mov_speed_len, &datalog_handle->bw);
466 if (datalog_handle->fr != FR_OK || datalog_handle->bw != mov_speed_len) {
467 f_close(&datalog_handle->fil);
468 return ERR_UNKNOWN;
469 }
470
471 // Set up movement direction string
472 uint32_t mov_dir_len = get_str_len(neo6_info->mov_dir) + 2;
473 char mov_dir_str[mov_dir_len];
474 str_cpy(mov_dir_str, neo6_info->mov_dir, mov_dir_len - 2);
475 mov_dir_str[mov_dir_len - 2] = '\r';
476 mov_dir_str[mov_dir_len - 1] = '\n';
477
478 // Write movement direction string to file
479 datalog_handle->fr = f_write(&datalog_handle->fil, mov_dir_str, mov_dir_len, &datalog_handle->bw);
480 if (datalog_handle->fr != FR_OK || datalog_handle->bw != mov_dir_len) {
481 f_close(&datalog_handle->fil);
482 return ERR_UNKNOWN;
483 }
484
485 datalog_handle->fr = f_write(&datalog_handle->fil, "\r\n", 2, &datalog_handle->bw);
486
487 f_close(&datalog_handle->fil);
488
489 datalog_handle->last_upd_time = systick_get_ms();
490
491 return ERR_OK;
492}
uint32_t systick_get_ms(void)
Returns the number of milliseconds elapsed since SysTick was initialized.
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 mov_dir[16]
Definition neo6.h:92
char lon[16]
Definition neo6.h:87
char ort_height[16]
Definition neo6.h:88
char time[16]
Definition neo6.h:90
char mov_speed[16]
Definition neo6.h:93
char lat[16]
Definition neo6.h:86
Here is the call graph for this function:
Here is the caller graph for this function: