diff --git a/master/master/config.h b/master/master/config.h --- a/master/master/config.h +++ b/master/master/config.h @@ -13,6 +13,8 @@ #ifndef CONFIG_H_ #define CONFIG_H_ +#include + // -------------------------------------------------------------------------- // Module config (master.c) // -------------------------------------------------------------------------- @@ -25,22 +27,26 @@ #define HEATER_THRESHOLD 60 + // -------------------------------------------------------------------------- // Error Codes config (led.c, used throughout code) // -------------------------------------------------------------------------- // SD Card -#define ERROR_SD_INIT 2 -#define ERROR_SD_PARTITION 3 -#define ERROR_SD_FILE 4 +#define ERROR_SLAVETIMEOUT 0 +#define ERROR_SD_INIT 1 +#define ERROR_SD_PARTITION 2 +#define ERROR_SD_FILE 3 + +#define ERROR_XBEETIMEOUT 4 -#define ERROR_XBEETIMEOUT 5 -#define ERROR_NOXBEE 6 + +#define ERROR_FATAL 5 -#define ERROR_CRAP 15 +#define ERROR_ATFAIL 6 +#define ERROR_EXITAT 7 -#define ERROR_ATFAIL 3 -#define ERROR_EXITAT 8 +// !!! Please specify detailed messages for these error codes in logger.c // -------------------------------------------------------------------------- // Slave Sensors config (slavesensors.c) diff --git a/master/master/lib/logger.c b/master/master/lib/logger.c --- a/master/master/lib/logger.c +++ b/master/master/lib/logger.c @@ -26,19 +26,47 @@ #include "serial.h" #include "logger.h" #include "led.h" +#include "looptime.h" + +#define MAX_ERRNO 7 + +// Label lookup table +// Make sure there are never more labels than there are MAX_NUM_SENSORS! +const char err_0[] PROGMEM = "slave timeout"; +const char err_1[] PROGMEM = "initializing SD card failed"; +const char err_2[] PROGMEM = "opening SD partition failed"; +const char err_3[] PROGMEM = "opening SD file failed"; +const char err_4[] PROGMEM = "XBee timeout"; +const char err_5[] PROGMEM = "FATAL UNHANDLED ERROR"; +const char err_6[] PROGMEM = "enter AT mode failed"; +const char err_7[] PROGMEM = "exit AT mode failed"; + +const char *const errorMessageLookup[] PROGMEM = +{ + err_0, + err_1, + err_2, + err_3, + err_4, + err_5, + err_6, + err_7, +}; + + struct partition_struct* partition; struct fat_fs_struct* fs; -struct fat_dir_entry_struct directory; struct fat_dir_struct* dd; -struct fat_file_struct* fd; +struct fat_file_struct* fd_datalog; +struct fat_file_struct* fd_errorlog; void logger_setup() { if(!sd_raw_init()) { - led_errorcode(ERROR_SD_INIT); + error_log(ERROR_SD_INIT); return; } @@ -52,7 +80,7 @@ void logger_setup() if(!partition) { // Error opening partition. MBR might be screwed up. - led_errorcode(ERROR_SD_PARTITION); + error_log(ERROR_SD_PARTITION); return; } @@ -62,78 +90,137 @@ void logger_setup() if(!fs) { // opening filesystem failed - led_errorcode(ERROR_SD_PARTITION); + error_log(ERROR_SD_PARTITION); return; } - // Open directory - fat_get_dir_entry_of_path(fs, "/", &directory); + // Open root directory + struct fat_dir_entry_struct rootDirEntry; + fat_get_dir_entry_of_path(fs, "/", &rootDirEntry); - dd = fat_open_dir(fs, &directory); + dd = fat_open_dir(fs, &rootDirEntry); if(!dd) { // opening root directory failed _delay_ms(10); - led_errorcode(ERROR_SD_FILE); + error_log(ERROR_SD_FILE); return; } - // Create new log file - uint8_t logid = eeprom_read_byte(LOGGER_ID_EEPROM_ADDR); - char filename[16]; + // we pre-increment logid here because it starts at 255, then wraps to 0 + uint8_t logid = eeprom_read_byte(LOGGER_ID_EEPROM_ADDR) + 1; + eeprom_update_byte(LOGGER_ID_EEPROM_ADDR, logid); + + int32_t errorOffset = 0; + char errorFilename[17]; + - // we pre-increment logid here because it starts at 255, then wraps to 0 - snprintf(filename, 16, "data%d.csv",++logid); - - // TODO: Catch errors here - if(fat_create_file(dd, filename, &directory) == 0) + // Form filename + snprintf(errorFilename, 17, "run%derror.csv",logid); + struct fat_dir_entry_struct errorDirEntry; + if(fat_create_file(dd, errorFilename, &errorDirEntry) == 0) + { + serial0_sendString("Error create errorlog\r\n"); + error_log(ERROR_SD_FILE); + } + // Search for file in current directory and open it + fd_errorlog = open_file_in_dir(fs, dd, errorFilename); + if(!fd_errorlog) { - led_errorcode(ERROR_SD_FILE); - } - - eeprom_update_byte(LOGGER_ID_EEPROM_ADDR, logid); - - // Search for file in current directory and open it - fd = open_file_in_dir(fs, dd, filename); - if(!fd) + serial0_sendString("Error open errorlog!\r\n"); + error_log(ERROR_SD_FILE); + return; + } + errorOffset=0; + if(!fat_seek_file(fd_errorlog, &errorOffset, FAT_SEEK_SET)) { - led_errorcode(ERROR_SD_FILE); - _delay_ms(10); + // Error seeking to file + serial0_sendString("Error seek errorlog!\r\n"); + error_log(ERROR_SD_FILE); + fat_close_file(fd_errorlog); return; } - - // Seek to beginning of file - // TODO: Is this needed? - int32_t offset = 0; - if(!fat_seek_file(fd, &offset, FAT_SEEK_SET)) + + + int32_t dataOffset = 0; + char dataFilename[17]; + + // Form filename + snprintf(dataFilename, 17, "run%ddata.csv",logid); + struct fat_dir_entry_struct dataDirEntry; + // Create new data log file + if(fat_create_file(dd, dataFilename, &dataDirEntry) == 0) + { + serial0_sendString("Error create datalog\r\n"); + error_log(ERROR_SD_FILE); + } + // Search for file in current directory and open it + fd_datalog = open_file_in_dir(fs, dd, dataFilename); + if(!fd_datalog) + { + serial0_sendString("Error open datalog!\r\n"); + error_log(ERROR_SD_FILE); + return; + } + dataOffset=0; + if(!fat_seek_file(fd_datalog, &dataOffset, FAT_SEEK_SET)) { // Error seeking to file - led_errorcode(ERROR_SD_FILE); - _delay_ms(10); - fat_close_file(fd); + serial0_sendString("Error seek datalog!\r\n"); + error_log(ERROR_SD_FILE); + fat_close_file(fd_datalog); return; } - + + // Write header information logger_log(LOGGER_HEADERTEXT); logger_log("\n-- BEGIN DATA --\n"); - + + error_log_rawwrite(LOGGER_HEADERTEXT); + error_log_rawwrite("\n-- BEGIN ERROR --\n"); } void logger_log(char *buffer) { uint8_t len = strlen(buffer); - if(fat_write_file(fd, (uint8_t*) buffer, len) != len) + if(fat_write_file(fd_datalog, (uint8_t*) buffer, len) != len) { // Error writing to file return; } } +void error_log(uint8_t errNo) +{ + char labelBuffer[32]; + labelBuffer[0] = 0x00; + + if(errNo <= MAX_ERRNO) + { + strncpy_P(labelBuffer,(char*)pgm_read_word(&(errorMessageLookup[errNo])),32); + } + char errorLine[128]; + snprintf(errorLine, 128, "%lu, %u, %s,\r\n", time_millis(), errNo, labelBuffer); + error_log_rawwrite(errorLine); + led_errorcode(errNo); +} + +void error_log_rawwrite(char *buffer) +{ + uint8_t len = strlen(buffer); + if(fat_write_file(fd_errorlog, (uint8_t*) buffer, len) != len) + { + // Error writing to file + return; + } +} + + void logger_closeLog() { - fat_close_file(fd); + fat_close_file(fd_datalog); fat_close_dir(dd); fat_close(fs); partition_close(partition); diff --git a/master/master/lib/logger.h b/master/master/lib/logger.h --- a/master/master/lib/logger.h +++ b/master/master/lib/logger.h @@ -18,7 +18,8 @@ void logger_setup(); uint8_t logger_writeLine(char* dateLine, uint8_t length); struct fat_file_struct* open_file_in_dir(struct fat_fs_struct* fs, struct fat_dir_struct* dd, const char* name); uint8_t find_file_in_dir(struct fat_fs_struct* fs, struct fat_dir_struct* dd, const char* name, struct fat_dir_entry_struct* dir_entry); - +void error_log(uint8_t errNo); +void error_log_rawwrite(char *buffer); void logger_log(char *buffer); void logger_closeLog(); diff --git a/master/master/lib/sdcard/fat_config.h b/master/master/lib/sdcard/fat_config.h --- a/master/master/lib/sdcard/fat_config.h +++ b/master/master/lib/sdcard/fat_config.h @@ -102,13 +102,13 @@ void get_datetime(uint16_t* year, uint8_ * \ingroup fat_config * Maximum number of file handles. */ -#define FAT_FILE_COUNT 1 +#define FAT_FILE_COUNT 2 /** * \ingroup fat_config * Maximum number of directory handles. */ -#define FAT_DIR_COUNT 2 +#define FAT_DIR_COUNT 3 /** * @} diff --git a/master/master/lib/sensordata.c b/master/master/lib/sensordata.c --- a/master/master/lib/sensordata.c +++ b/master/master/lib/sensordata.c @@ -83,12 +83,9 @@ void sensordata_logvalues() #define CSV_BUFFER_SIZE 64 char csvHeader[CSV_BUFFER_SIZE]; csvHeader[0] = 0x00; - - slavesensors_selectlogger(); // Add master data headers logger_log("Time,BoardTemp,GPSTime,GPSLat,GPSLon,GPSSpeed,GPSHDOP,GPSCourse,GPSSV,"); - serial0_sendString("Time,BoardTemp,GPSTime,GPSLat,GPSLon,GPSSpeed,GPSHDOP,GPSCourse,GPSSV,"); // Add slave data headers for(uint8_t i=0; i timeout) { - led_errorcode(ERROR_XBEETIMEOUT); + error_log(ERROR_XBEETIMEOUT); return true; } if(time_millis() - lastBlink > 50) @@ -361,7 +361,7 @@ int slavesensors_enterAT() int xbeeIsOk() { if(waitTimeout(2000)) { - led_errorcode(ERROR_XBEETIMEOUT); + error_log(ERROR_XBEETIMEOUT); return 1; } char* tmppntr = serial0_readLine(); @@ -371,7 +371,7 @@ int xbeeIsOk() } else { - led_errorcode(ERROR_NOXBEE); + error_log(ERROR_SLAVETIMEOUT); return 1; } } @@ -490,6 +490,7 @@ void slavesensors_process(uint8_t parseR // if we're requesting, we have no data, and we're over the timeout, this is bad! // setParserState(STATE_RESET); - meh, can't do this because it freaking increments the cirbufptr gotoNextSlaveOrSensor(true); + error_log(ERROR_SLAVETIMEOUT); } }