-/**
- * \file
- *
- * \author Bernie Innocenti <bernie@codewiz.org>
- *
- * \brief Serial data logger for RMS
+/*
+ * Copyleft 2011 Bernie Innocenti <bernie@codewiz.org>
+ * Serial data logger for RMS
*
* This application records all incoming data from an RS-232 serial port
* to a file on a FAT-formatted SD card. It can be used to log kernel
* console messages.
*/
+// Configuration
+#define FILE_NAME "log.txt"
+#define FILE_NAME_PATTERN "log%04d.txt"
+#define FILE_OVERWRITE 0
+#define FILE_PREALLOC_SIZE 102400
+
+
#include "hw/hw_led.h"
#define LOG_LEVEL 3
#include <cpu/irq.h>
#include <cpu/power.h>
-#ifdef BERTOS_FAT
- #include <drv/sd.h>
- #include <fs/fat.h>
-#else
- #include <FAT16/fat.h>
- #include <FAT16/partition.h>
- #include <FAT16/sd_raw.h>
-#endif
+#include <FAT16/fat.h>
+#include <FAT16/partition.h>
+#include <FAT16/sd_raw.h>
#include <drv/ser.h>
#include <drv/timer.h>
#include <kern/proc.h>
-#include <string.h>
+#include <stdio.h> // sprintf()
+#include <string.h> // strcmp()
+// Our serial port
static Serial ser;
-#ifdef BERTOS_FAT
- static Serial spi;
- static FATFS fs;
- static FatFile file;
- static Sd sd;
-#else
- struct fat_fs_struct *fs;
- struct partition_struct *partition;
- struct fat_dir_struct *dd;
- struct fat_dir_entry_struct dir_entry;
- struct fat_file_struct *fd;
-#endif
-
-
-#ifndef BERTOS_FAT
+// FAT global state
+struct fat_fs_struct *fs;
+struct partition_struct *partition;
+struct fat_dir_struct *dd;
+struct fat_dir_entry_struct dir_entry;
+struct fat_file_struct *fd;
+
+
static void fat_init(void)
{
partition = partition_open(
ASSERT(0); for(;;) {}
}
- //Open root directory
+ // Open root directory
fat_get_dir_entry_of_path(fs, "/", &dir_entry);
if (!(dd = fat_open_dir(fs, &dir_entry)))
{
return fat_open_file(fs, &file_entry);
}
-#endif // !BERTOS_FAT
static void init(void)
{
// input stream to the SD card
//ser_setbaudrate(&ser, 19200);
- /* Initialize LED driver */
+ // Initialize LED driver
LED_INIT();
+ /*
+ * This gives avrdude some time to start reflashing in case
+ * the bug caused the program to do continous serial output
+ */
timer_delay(1000);
- kfile_printf(&ser.fd, "Hello, world!\r\n");
-#ifdef BERTOS_FAT
- ser_init(&spi, SER_SPI);
-#else
DDRB |= BV(PORTB0) | BV(PORTB2) | BV(PORTB3) | BV(PORTB5);
if (!sd_raw_init())
{
ASSERT(0); for(;;) {}
}
-#endif
fat_init();
}
{
init();
-#ifdef BERTOS_FAT
+ size_t size;
+ bool sync_pending = false;
+ char buf[256];
- FRESULT fat_err;
- if ((fat_err = f_mount(0, &fs)) != FR_OK)
+ #if FILE_OVERWRITE
{
- LOG_ERR("Error mounting FAT volume: %d\n", fat_err);
- }
-
- fat_err = fatfile_open(&file, "foo.txt", FA_WRITE | FA_CREATE_ALWAYS);
- ASSERT(fat_err == FR_OK);
-
- size_t count = kfile_write(&file.fd, "Hello, world!", strlen("Hello, world!"));
- ASSERT(count == strlen("Hello, world!"));
+ if(!fat_create_file(dd, FILE_NAME, &dir_entry))
+ {
+ fat_delete_file(fs, &dir_entry);
+ fat_create_file(dd, FILE_NAME, &dir_entry);
+ }
-#else
+ fd = open_file_in_dir(fs, dd, FILE_NAME);
+ }
+ #else /* Generate a new filename */
+ {
+ int n;
+ char filename[8+1+3+1];
- fat_create_file(dd, "log.txt", &dir_entry);
- fd = open_file_in_dir(fs, dd, "log.txt");
- int32_t offset = 0;
- fat_seek_file(fd, &offset, FAT_SEEK_END);
+ for (n = 0; /**/; ++n)
+ {
+ sprintf(filename, FILE_NAME_PATTERN, n);
+ if (fat_create_file(dd, filename, &dir_entry))
+ break;
+ }
-#endif
+ fd = open_file_in_dir(fs, dd, filename);
+ }
+ #endif
- while (1)
+ #if FILE_PREALLOC_SIZE
{
- size_t size;
- char buf[128];
- bool sync_pending = false;
+ LED_ON();
+ memset(buf, ' ', sizeof(buf));
+ for (int i = 0; i < (int)(FILE_PREALLOC_SIZE / sizeof(buf)); ++i)
+ fat_write_file(fd, (void *)buf, sizeof(buf));
+
+ int32_t offset = 0;
+ fat_seek_file(fd, &offset, FAT_SEEK_SET);
+ LED_OFF();
+ }
+ #endif
+ for (;;)
+ {
if ((size = ser_read(&ser, buf, sizeof(buf))) != 0)
{
LED_ON();