Add FAT16 library
[rmslog.git] / rmslog / main.c
1 /**
2  * \file
3  *
4  * \author Bernie Innocenti <bernie@codewiz.org>
5  *
6  * \brief Serial data logger for RMS
7  *
8  * This application logs data 
9  */
10
11 #include "hw/hw_led.h"
12
13 #define LOG_LEVEL      3
14 #include <cfg/log.h>
15 #include <cfg/debug.h>
16
17 #include <cpu/irq.h>
18 #include <cpu/power.h>
19
20 #ifdef BERTOS_FAT
21         #include <drv/sd.h>
22         #include <fs/fat.h>
23 #else
24         #include <FAT16/fat.h>
25         #include <FAT16/partition.h>
26         #include <FAT16/sd_raw.h>
27 #endif
28
29 #include <drv/ser.h>
30 #include <drv/timer.h>
31 #include <kern/proc.h>
32
33 #include <string.h>
34
35
36 static Serial ser;
37
38 #ifdef BERTOS_FAT
39         static Serial spi;
40         static FATFS fs;
41         static FatFile file;
42         static Sd sd;
43 #else
44         struct fat_fs_struct        *fs;
45         struct partition_struct     *partition;
46         struct fat_dir_struct       *dd;
47         struct fat_dir_entry_struct dir_entry;
48         struct fat_file_struct      *fd;
49 #endif
50
51
52 #ifndef BERTOS_FAT
53 static void fat_init(void)
54 {
55         partition = partition_open(
56                 sd_raw_read,
57                 sd_raw_read_interval,
58                 sd_raw_write,
59                 sd_raw_write_interval,
60                 0
61         );
62
63         if (!partition)
64         {
65                 // If the partition did not open, assume the storage device
66                 // is a "superfloppy", i.e. has no MBR.
67                 partition = partition_open(
68                         sd_raw_read,
69                         sd_raw_read_interval,
70                         sd_raw_write,
71                         sd_raw_write_interval,
72                         0
73                 );
74         }
75         if (!partition)
76         {
77                 ASSERT(0); for(;;) {}
78         }
79
80         if (!(fs = fat_open(partition)))
81         {
82                 ASSERT(0); for(;;) {}
83         }
84
85     //Open root directory
86     fat_get_dir_entry_of_path(fs, "/", &dir_entry);
87     if (!(dd = fat_open_dir(fs, &dir_entry)))
88         {
89                 ASSERT(0); for(;;) {}
90         }
91 }
92
93 static uint8_t find_file_in_dir(UNUSED_ARG(struct fat_fs_struct *, fs), struct fat_dir_struct* dd, const char* name, struct fat_dir_entry_struct* dir_entry)
94 {
95         fat_reset_dir(dd);      //Make sure to start from the beginning of the directory!
96     while(fat_read_dir(dd, dir_entry))
97     {
98         if(strcmp(dir_entry->long_name, name) == 0)
99         {
100             //fat_reset_dir(dd);
101             return 1;
102         }
103     }
104
105     return 0;
106 }
107
108 static struct fat_file_struct *open_file_in_dir(struct fat_fs_struct* fs, struct fat_dir_struct* dd, const char* name)
109 {
110     struct fat_dir_entry_struct file_entry;
111     if(!find_file_in_dir(fs, dd, name, &file_entry))
112         return 0;
113
114     return fat_open_file(fs, &file_entry);
115 }
116
117 #endif // !BERTOS_FAT
118
119 static void init(void)
120 {
121         /* Initialize debugging module (allow kprintf(), etc.) */
122         kdbg_init();
123
124         /* Initialize system timer */
125         timer_init();
126
127         /* Enable all the interrupts */
128         IRQ_ENABLE;
129
130         /* Kernel initialization: processes */
131         proc_init();
132
133         /* Initialize UART0 */
134         ser_init(&ser, SER_UART0);
135         //FIXME
136         //ser_setbaudrate(&ser, 115200);
137         //ser_setbaudrate(&ser, 57600);
138         //UCSR0A = BV(U2X0);
139         ser_setbaudrate(&ser, 19200);
140
141         /* Initialize LED driver */
142         LED_INIT();
143
144         timer_delay(1000);
145         kfile_printf(&ser.fd, "Hello, world!\r\n");
146
147 #ifdef BERTOS_FAT
148         ser_init(&spi, SER_SPI);
149 #else
150         DDRB |= BV(PORTB0) | BV(PORTB2) | BV(PORTB3) | BV(PORTB5);
151         if (!sd_raw_init())
152         {
153                 ASSERT(0); for(;;) {}
154         }
155 #endif
156
157         fat_init();
158 }
159
160
161 int main(void)
162 {
163         init();
164
165 #ifdef BERTOS_FAT
166
167         FRESULT fat_err;
168         if ((fat_err = f_mount(0, &fs)) != FR_OK)
169         {
170                 LOG_ERR("Error mounting FAT volume: %d\n", fat_err);
171         }
172
173         fat_err = fatfile_open(&file, "foo.txt", FA_WRITE | FA_CREATE_ALWAYS);
174         ASSERT(fat_err == FR_OK);
175
176         size_t count = kfile_write(&file.fd, "Hello, world!", strlen("Hello, world!"));
177         ASSERT(count == strlen("Hello, world!"));
178
179 #else
180
181         fat_create_file(dd, "log.txt", &dir_entry);
182         fd = open_file_in_dir(fs, dd, "log.txt");
183         int32_t offset = 0;
184         fat_seek_file(fd, &offset, FAT_SEEK_END);
185
186 #endif
187
188         while (1)
189         {
190                 size_t size;
191                 char buf[128];
192                 bool sync_pending = false;
193
194                 if ((size = ser_read(&ser, buf, sizeof(buf))) != 0)
195                 {
196                         LED_ON();
197                         fat_write_file(fd, (void *)buf, size);
198                         sync_pending = true;
199                         sprintf(buf, "%d\r\n", size);
200                         ser_write(&ser, buf, strlen(buf));
201                         LED_OFF();
202                 }
203                 else
204                 {
205                         serstatus_t err = ser_getstatus(&ser);
206                         if (err & ~SERRF_RXTIMEOUT)
207                         {
208                                 LED_ON();
209                                 kfile_printf(&ser.fd, "\r\n*** err=%d ***\r\n", err);
210                         }
211                         ser_setstatus(&ser, 0);
212
213                         if (sync_pending)
214                         {
215                                 LED_ON();
216                                 sd_raw_sync();
217                                 LED_OFF();
218                                 sync_pending = false;
219                         }
220                 }
221         }
222         fat_close_file(fd);
223 }