altos: Reduce stack usage of FAT driver and logger
[fw/altos] / src / drivers / ao_log_fat.c
1 /*
2  * Copyright © 2013 Keith Packard <keithp@keithp.com>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; version 2 of the License.
7  *
8  * This program is distributed in the hope that it will be useful, but
9  * WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11  * General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License along
14  * with this program; if not, write to the Free Software Foundation, Inc.,
15  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
16  */
17
18 #include "ao.h"
19 #include "ao_log.h"
20 #include "ao_fat.h"
21
22 static uint8_t  log_year, log_month, log_day;
23 static uint8_t  log_open;
24 static int8_t   log_fd;
25 static uint8_t  log_mutex;
26
27 static void
28 ao_log_open(void)
29 {
30         static char     name[12];
31         int8_t  status;
32
33         sprintf(name,"%04d%02d%02dLOG", 2000 + log_year, log_month, log_day);
34         status = ao_fat_open(name, AO_FAT_OPEN_WRITE);
35         if (status >= 0) {
36                 log_fd = status;
37                 ao_fat_seek(log_fd, 0, AO_FAT_SEEK_END);
38                 log_open = 1;
39         } else if (status == -AO_FAT_ENOENT) {
40                 status = ao_fat_creat(name);
41                 if (status >= 0) {
42                         log_fd = status;
43                         log_open = 1;
44                 }
45         } 
46 }
47
48 static void
49 ao_log_close(void)
50 {
51         if (log_open) {
52                 log_open = 0;
53                 ao_fat_close(log_fd);
54                 log_fd = -1;
55         }
56 }
57
58 uint8_t
59 ao_log_full(void)
60 {
61         return ao_fat_full();
62 }
63
64 uint8_t
65 ao_log_mega(struct ao_log_mega *log)
66 {
67         uint8_t wrote = 0;
68         ao_mutex_get(&log_mutex);
69         if (log->type == AO_LOG_GPS_TIME) {
70                 if (log_open &&
71                     (log_year != log->u.gps.year ||
72                      log_month != log->u.gps.month ||
73                      log_day != log->u.gps.day)) {
74                         ao_log_close();
75                 }
76                 if (!log_open) {
77                         log_year = log->u.gps.year;
78                         log_month = log->u.gps.month;
79                         log_day = log->u.gps.day;
80                         ao_log_open();
81                 }
82         }
83         if (log_open) {
84                 wrote = ao_fat_write(log_fd, log, sizeof (*log)) == AO_FAT_SUCCESS;
85                 ao_fat_sync();
86         }
87         ao_mutex_put(&log_mutex);
88         return wrote;
89 }
90
91 void
92 ao_log_flush(void)
93 {
94         ao_fat_sync();
95 }