2 * Copyleft 2011 Bernie Innocenti <bernie@codewiz.org>
3 * Serial data logger for RMS
5 * This application records all incoming data from an RS-232 serial port
6 * to a file on a FAT-formatted SD card. It can be used to log kernel
11 #define FILE_NAME "log.txt"
12 #define FILE_NAME_PATTERN "log%04d.txt"
13 #define FILE_OVERWRITE 0
14 #define FILE_PREALLOC_SIZE 102400
17 #include "hw/hw_led.h"
21 #include <cfg/debug.h>
24 #include <cpu/power.h>
26 #include <FAT16/fat.h>
27 #include <FAT16/partition.h>
28 #include <FAT16/sd_raw.h>
31 #include <drv/timer.h>
32 #include <kern/proc.h>
34 #include <stdio.h> // sprintf()
35 #include <string.h> // strcmp()
42 struct fat_fs_struct *fs;
43 struct partition_struct *partition;
44 struct fat_dir_struct *dd;
45 struct fat_dir_entry_struct dir_entry;
46 struct fat_file_struct *fd;
49 static void fat_init(void)
51 partition = partition_open(
55 sd_raw_write_interval,
61 // If the partition did not open, assume the storage device
62 // is a "superfloppy", i.e. has no MBR.
63 partition = partition_open(
67 sd_raw_write_interval,
76 if (!(fs = fat_open(partition)))
81 // Open root directory
82 fat_get_dir_entry_of_path(fs, "/", &dir_entry);
83 if (!(dd = fat_open_dir(fs, &dir_entry)))
89 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)
91 fat_reset_dir(dd); //Make sure to start from the beginning of the directory!
92 while(fat_read_dir(dd, dir_entry))
94 if(strcmp(dir_entry->long_name, name) == 0)
104 static struct fat_file_struct *open_file_in_dir(struct fat_fs_struct* fs, struct fat_dir_struct* dd, const char* name)
106 struct fat_dir_entry_struct file_entry;
107 if(!find_file_in_dir(fs, dd, name, &file_entry))
110 return fat_open_file(fs, &file_entry);
114 static void init(void)
116 /* Initialize debugging module (allow kprintf(), etc.) */
119 /* Initialize system timer */
122 /* Enable all the interrupts */
125 /* Kernel initialization: processes */
128 /* Initialize UART0 */
129 ser_init(&ser, SER_UART0);
131 //FIXME: The 16MHz arduino clock causes 3.5% baudrate error at 115200
132 //ser_setbaudrate(&ser, 115200);
133 ser_setbaudrate(&ser, 57600);
136 // At this baud rate, we're fast enought to write a continuous
137 // input stream to the SD card
138 //ser_setbaudrate(&ser, 19200);
140 // Initialize LED driver
144 * This gives avrdude some time to start reflashing in case
145 * the bug caused the program to do continous serial output
149 DDRB |= BV(PORTB0) | BV(PORTB2) | BV(PORTB3) | BV(PORTB5);
152 ASSERT(0); for(;;) {}
164 bool sync_pending = false;
169 if(!fat_create_file(dd, FILE_NAME, &dir_entry))
171 fat_delete_file(fs, &dir_entry);
172 fat_create_file(dd, FILE_NAME, &dir_entry);
175 fd = open_file_in_dir(fs, dd, FILE_NAME);
177 #else /* Generate a new filename */
180 char filename[8+1+3+1];
182 for (n = 0; /**/; ++n)
184 sprintf(filename, FILE_NAME_PATTERN, n);
185 if (fat_create_file(dd, filename, &dir_entry))
189 fd = open_file_in_dir(fs, dd, filename);
193 #if FILE_PREALLOC_SIZE
196 memset(buf, ' ', sizeof(buf));
197 for (int i = 0; i < (int)(FILE_PREALLOC_SIZE / sizeof(buf)); ++i)
198 fat_write_file(fd, (void *)buf, sizeof(buf));
201 fat_seek_file(fd, &offset, FAT_SEEK_SET);
208 if ((size = ser_read(&ser, buf, sizeof(buf))) != 0)
211 fat_write_file(fd, (void *)buf, size);
217 serstatus_t err = ser_getstatus(&ser);
218 if (err & ~SERRF_RXTIMEOUT)
221 kfile_printf(&ser.fd, "\r\n*** err=%d ***\r\n", err);
223 ser_setstatus(&ser, 0);
230 sync_pending = false;