const pm_char * eeRestoreModel(uint8_t i_fileDst, char *model_name) { char *buf = reusableBuffer.modelsel.mainname; FIL restoreFile; UINT read; eeCheck(true); if (!sdMounted()) { return STR_NO_SDCARD; } strcpy(buf, STR_MODELS_PATH); buf[sizeof(MODELS_PATH)-1] = '/'; strcpy(&buf[sizeof(MODELS_PATH)], model_name); strcpy(&buf[strlen(buf)], STR_MODELS_EXT); FRESULT result = f_open(&restoreFile, buf, FA_OPEN_EXISTING | FA_READ); if (result != FR_OK) { return SDCARD_ERROR(result); } if (f_size(&restoreFile) < 8) { f_close(&restoreFile); return STR_INCOMPATIBLE; } result = f_read(&restoreFile, (uint8_t *)buf, 8, &read); if (result != FR_OK || read != 8) { f_close(&restoreFile); return SDCARD_ERROR(result); } uint8_t version = (uint8_t)buf[4]; if (*(uint32_t*)&buf[0] != O9X_FOURCC || version < FIRST_CONV_EEPROM_VER || version > EEPROM_VER || buf[5] != 'M') { f_close(&restoreFile); return STR_INCOMPATIBLE; } if (eeModelExists(i_fileDst)) { eeDeleteModel(i_fileDst); } uint16_t size = min<uint16_t>(sizeof(g_model), *(uint16_t*)&buf[6]); uint32_t address = eepromHeader.files[i_fileDst+1].zoneIndex * EEPROM_ZONE_SIZE; // erase blocks eepromEraseBlock(address); eepromEraseBlock(address+EEPROM_BLOCK_SIZE); // write header EepromFileHeader * header = (EepromFileHeader *)eepromWriteBuffer; header->fileIndex = i_fileDst+1; header->size = size; int offset = 4; // write model do { uint16_t blockSize = min<uint16_t>(size, EEPROM_BUFFER_SIZE-offset); result = f_read(&restoreFile, eepromWriteBuffer+offset, blockSize, &read); if (result != FR_OK || read != blockSize) { f_close(&g_oLogFile); return SDCARD_ERROR(result); } eepromWrite(address, eepromWriteBuffer, blockSize+offset); size -= blockSize; address += EEPROM_BUFFER_SIZE; offset = 0; } while (size > 0); // write FAT eepromHeader.files[i_fileDst+1].exists = 1; eepromIncFatAddr(); eepromWriteState = EEPROM_WRITE_NEW_FAT; eepromWriteWait(); eeLoadModelHeader(i_fileDst, &modelHeaders[i_fileDst]); #if defined(PCBSKY9X) if (version < EEPROM_VER) { ConvertModel(i_fileDst, version); loadModel(g_eeGeneral.currModel); } #endif return NULL; }
const pm_char *openLogs() { // Determine and set log file filename FRESULT result; DIR folder; char filename[34]; // /LOGS/modelnamexxx-2013-01-01.log if (!sdMounted()) return STR_NO_SDCARD; if (sdGetFreeSectors() == 0) return STR_SDCARD_FULL; // check and create folder here strcpy_P(filename, STR_LOGS_PATH); result = f_opendir(&folder, filename); if (result != FR_OK) { if (result == FR_NO_PATH) result = f_mkdir(filename); if (result != FR_OK) return SDCARD_ERROR(result); } filename[sizeof(LOGS_PATH)-1] = '/'; memcpy(&filename[sizeof(LOGS_PATH)], g_model.header.name, sizeof(g_model.header.name)); filename[sizeof(LOGS_PATH)+sizeof(g_model.header.name)] = '\0'; uint8_t i = sizeof(LOGS_PATH)+sizeof(g_model.header.name)-1; uint8_t len = 0; while (i>sizeof(LOGS_PATH)-1) { if (!len && filename[i]) len = i+1; if (len) { if (filename[i]) filename[i] = idx2char(filename[i]); else filename[i] = '_'; } i--; } if (len == 0) { uint8_t num = g_eeGeneral.currModel + 1; strcpy_P(&filename[sizeof(LOGS_PATH)], STR_MODEL); filename[sizeof(LOGS_PATH) + PSIZE(TR_MODEL)] = (char)((num / 10) + '0'); filename[sizeof(LOGS_PATH) + PSIZE(TR_MODEL) + 1] = (char)((num % 10) + '0'); len = sizeof(LOGS_PATH) + PSIZE(TR_MODEL) + 2; } char * tmp = &filename[len]; #if defined(RTCLOCK) tmp = strAppendDate(&filename[len]); #endif strcpy_P(tmp, STR_LOGS_EXT); result = f_open(&g_oLogFile, filename, FA_OPEN_ALWAYS | FA_WRITE); if (result != FR_OK) { return SDCARD_ERROR(result); } if (f_size(&g_oLogFile) == 0) { writeHeader(); } else { result = f_lseek(&g_oLogFile, f_size(&g_oLogFile)); // append if (result != FR_OK) { return SDCARD_ERROR(result); } } return NULL; }
const pm_char * eeBackupModel(uint8_t i_fileSrc) { char *buf = reusableBuffer.modelsel.mainname; FIL archiveFile; DIR archiveFolder; UINT written; eeCheck(true); if (!sdMounted()) { return STR_NO_SDCARD; } // check and create folder here strcpy(buf, STR_MODELS_PATH); FRESULT result = f_opendir(&archiveFolder, buf); if (result != FR_OK) { if (result == FR_NO_PATH) result = f_mkdir(buf); if (result != FR_OK) return SDCARD_ERROR(result); } else { f_closedir(&archiveFolder); } buf[sizeof(MODELS_PATH)-1] = '/'; strcpy(strcat_modelname(&buf[sizeof(MODELS_PATH)], i_fileSrc), STR_MODELS_EXT); result = f_open(&archiveFile, buf, FA_CREATE_ALWAYS | FA_WRITE); if (result != FR_OK) { return SDCARD_ERROR(result); } #if defined(PCBSKY9X) strcpy(statusLineMsg, PSTR("File ")); strcpy(statusLineMsg+5, &buf[sizeof(MODELS_PATH)]); #endif uint16_t size = eeModelSize(i_fileSrc); *(uint32_t*)&buf[0] = O9X_FOURCC; buf[4] = g_eeGeneral.version; buf[5] = 'M'; *(uint16_t*)&buf[6] = size; result = f_write(&archiveFile, buf, 8, &written); if (result != FR_OK || written != 8) { f_close(&archiveFile); return SDCARD_ERROR(result); } uint32_t address = eepromHeader.files[i_fileSrc+1].zoneIndex * EEPROM_ZONE_SIZE + sizeof(EepromFileHeader); while (size > 0) { uint16_t blockSize = min<uint16_t>(size, EEPROM_BUFFER_SIZE); eepromRead(address, eepromWriteBuffer, blockSize); result = f_write(&archiveFile, eepromWriteBuffer, blockSize, &written); if (result != FR_OK || written != blockSize) { f_close(&archiveFile); return SDCARD_ERROR(result); } size -= blockSize; address += blockSize; } f_close(&archiveFile); #if defined(PCBSKY9X) showStatusLine(); #endif return NULL; }
const pm_char * openLogs() { // Determine and set log file filename FRESULT result; DIR folder; char filename[34]; // /LOGS/modelnamexxx-2013-01-01.log if (!sdMounted()) return STR_NO_SDCARD; strcpy_P(filename, STR_LOGS_PATH); result = f_opendir(&folder, filename); if (result != FR_OK) { if (result == FR_NO_PATH) result = f_mkdir(filename); if (result != FR_OK) return SDCARD_ERROR(result); } filename[sizeof(LOGS_PATH)-1] = '/'; memcpy(&filename[sizeof(LOGS_PATH)], g_model.header.name, sizeof(g_model.header.name)); filename[sizeof(LOGS_PATH)+sizeof(g_model.header.name)] = '\0'; uint8_t i = sizeof(LOGS_PATH)+sizeof(g_model.header.name)-1; uint8_t len = 0; while (i>sizeof(LOGS_PATH)-1) { if (!len && filename[i]) len = i+1; if (len) { if (filename[i]) filename[i] = idx2char(filename[i]); else filename[i] = '_'; } i--; } if (len == 0) { uint8_t num = g_eeGeneral.currModel + 1; strcpy_P(&filename[sizeof(LOGS_PATH)], STR_MODEL); filename[sizeof(LOGS_PATH) + PSIZE(TR_MODEL)] = (char)((num / 10) + '0'); filename[sizeof(LOGS_PATH) + PSIZE(TR_MODEL) + 1] = (char)((num % 10) + '0'); len = sizeof(LOGS_PATH) + PSIZE(TR_MODEL) + 2; } char * tmp = &filename[len]; #if defined(RTCLOCK) tmp = strAppendDate(&filename[len]); #endif strcpy_P(tmp, STR_LOGS_EXT); result = f_open(&g_oLogFile, filename, FA_OPEN_ALWAYS | FA_WRITE); if (result != FR_OK) { return SDCARD_ERROR(result); } if (f_size(&g_oLogFile) == 0) { #if defined(RTCLOCK) f_puts("Date,Time,", &g_oLogFile); #else f_puts("Time,", &g_oLogFile); #endif #if defined(PCBTARANIS) && defined(REVPLUS) f_puts("RSSI,A1,A2,A3,A4,", &g_oLogFile); #elif defined(CPUARM) && defined(FRSKY) f_puts("SWR,RSSI,A1,A2,A3,A4,", &g_oLogFile); #elif defined(FRSKY) f_puts("Buffer,RX,TX,A1,A2,", &g_oLogFile); #endif #if defined(FRSKY_HUB) if (IS_USR_PROTO_FRSKY_HUB()) { f_puts("GPS Date,GPS Time,Long,Lat,Course,GPS Speed(kts),GPS Alt,Baro Alt(", &g_oLogFile); f_puts(TELEMETRY_BARO_ALT_UNIT, &g_oLogFile); f_puts("),Vertical Speed,Air Speed(kts),Temp1,Temp2,RPM,Fuel," TELEMETRY_CELLS_LABEL "Current,Consumption,Vfas,AccelX,AccelY,AccelZ,", &g_oLogFile); } #endif #if defined(WS_HOW_HIGH) if (IS_USR_PROTO_WS_HOW_HIGH()) { f_puts("WSHH Alt,", &g_oLogFile); } #endif #if defined(PCBTARANIS) f_puts("Rud,Ele,Thr,Ail,S1,S2,S3,LS,RS,SA,SB,SC,SD,SE,SF,SG,SH\n", &g_oLogFile); #else f_puts("Rud,Ele,Thr,Ail,P1,P2,P3,THR,RUD,ELE,3POS,AIL,GEA,TRN\n", &g_oLogFile); #endif } else { result = f_lseek(&g_oLogFile, f_size(&g_oLogFile)); // append if (result != FR_OK) { return SDCARD_ERROR(result); } } return NULL; }