imuboard/mk: add program_noerase target
[fpv.git] / imuboard / sd_log.c
1 #include <string.h>
2 #include <stdlib.h>
3 #include <stdio.h>
4 #include <aversive/pgmspace.h>
5
6 #include "fat.h"
7 #include "fat_config.h"
8 #include "partition.h"
9 #include "sd_raw.h"
10 #include "sd_raw_config.h"
11 #include "sd_log.h"
12 #include "main.h"
13
14 static struct fat_file_struct *log_fd = NULL;
15
16 static uint8_t find_file_in_dir(struct fat_fs_struct* fs,
17         struct fat_dir_struct* dd, const char* name,
18         struct fat_dir_entry_struct* dir_entry)
19 {
20         (void)fs;
21
22         while(fat_read_dir(dd, dir_entry)) {
23                 if(strcmp(dir_entry->long_name, name) == 0) {
24                         fat_reset_dir(dd);
25                         return 1;
26                 }
27         }
28
29         return 0;
30 }
31
32 static struct fat_file_struct *open_file_in_dir(struct fat_fs_struct* fs,
33         struct fat_dir_struct* dd, const char* name)
34 {
35         struct fat_dir_entry_struct file_entry;
36
37         if(!find_file_in_dir(fs, dd, name, &file_entry))
38                 return 0;
39
40         return fat_open_file(fs, &file_entry);
41 }
42
43 /* open the log file on the SD card */
44 int8_t sd_log_open(void)
45 {
46         struct fat_file_struct *fd;
47         struct fat_fs_struct *fs;
48         struct partition_struct *partition ;
49         struct fat_dir_struct *dd;
50         struct fat_dir_entry_struct directory;
51         struct fat_dir_entry_struct file_entry;
52         int16_t i = 0;
53         char name[16];
54
55         /* setup sd card slot */
56         if (!sd_raw_init()) {
57 #if SD_DEBUG
58                 printf_P(PSTR("MMC/SD initialization failed\n"));
59 #endif
60                 return -1;
61         }
62
63         /* open first partition */
64         partition = partition_open(sd_raw_read,
65                 sd_raw_read_interval,
66 #if SD_RAW_WRITE_SUPPORT
67                 sd_raw_write, sd_raw_write_interval,
68 #else
69                 0, 0,
70 #endif
71                 0);
72
73         if (!partition) {
74                 /* If the partition did not open, assume the storage device
75                  * is a "superfloppy", i.e. has no MBR.
76                  */
77                 partition = partition_open(sd_raw_read,
78                         sd_raw_read_interval,
79 #if SD_RAW_WRITE_SUPPORT
80                         sd_raw_write,
81                         sd_raw_write_interval,
82 #else
83                         0,
84                         0,
85 #endif
86                         -1);
87                 if (!partition) {
88 #if SD_DEBUG
89                         printf_P(PSTR("opening partition failed\n"));
90 #endif
91                         return -1;
92                 }
93         }
94
95         /* open file system */
96         fs = fat_open(partition);
97         if (!fs) {
98 #if SD_DEBUG
99                 printf_P(PSTR("opening filesystem failed\n"));
100 #endif
101                 return -1;
102         }
103
104         /* open root directory */
105         fat_get_dir_entry_of_path(fs, "/", &directory);
106         dd = fat_open_dir(fs, &directory);
107         if (!dd) {
108 #if SD_DEBUG
109                 printf_P(PSTR("opening root directory failed\n"));
110 #endif
111                 return -1;
112         }
113
114         printf_P(PSTR("choose log file name\n"));
115         while (1) {
116                 snprintf(name, sizeof(name), "log%.4d", i++);
117                 if (!find_file_in_dir(fs, dd, name, &file_entry))
118                         break;
119         }
120
121         printf_P(PSTR("create log file %s\n"), name);
122         if (!fat_create_file(dd, name, &file_entry)) {
123                 printf_P(PSTR("error creating file: "));
124         }
125
126         fd = open_file_in_dir(fs, dd, name);
127         if (!fd) {
128                 printf_P(PSTR("error opening "));
129                 return -1;
130         }
131         log_fd = fd;
132
133         imuboard.flags |= IMUBOARD_F_SDCARD_OK;
134         return 0;
135 }
136
137 /* log output */
138 intptr_t sd_log_write(const void *buffer, uintptr_t buffer_len)
139 {
140         if (log_fd == NULL)
141                 return -1;
142
143         return fat_write_file(log_fd, buffer, buffer_len);
144 }
145
146 uint8_t sd_log_enabled(void)
147 {
148         return log_fd != NULL;
149 }