diff --git a/companion/src/firmwares/opentx/opentxTaranisSimulator.cpp b/companion/src/firmwares/opentx/opentxTaranisSimulator.cpp index ed934036a..dfe271830 100644 --- a/companion/src/firmwares/opentx/opentxTaranisSimulator.cpp +++ b/companion/src/firmwares/opentx/opentxTaranisSimulator.cpp @@ -93,6 +93,7 @@ inline int geteepromsize() { #include "radio/src/gui/view_text.cpp" #include "radio/src/gui/view_about.cpp" #include "radio/src/lcd.cpp" +#include "radio/src/strhelpers.cpp" #include "radio/src/logs.cpp" #include "radio/src/rtc.cpp" #include "radio/src/targets/taranis/keys_driver.cpp" diff --git a/radio/src/.gitignore b/radio/src/.gitignore index 5bf38bf1f..e2ec3ddcd 100644 --- a/radio/src/.gitignore +++ b/radio/src/.gitignore @@ -20,3 +20,4 @@ /traces /MODELS /FIRMWARES +/EEPROMS diff --git a/radio/src/Makefile b/radio/src/Makefile index 056f04db0..110f03c04 100644 --- a/radio/src/Makefile +++ b/radio/src/Makefile @@ -949,7 +949,7 @@ endif ifeq ($(SDCARD), YES) CPPDEFS += -DSDCARD - CPPSRC += logs.cpp + CPPSRC += logs.cpp strhelpers.cpp endif RUN_FROM_FLASH = 1 diff --git a/radio/src/bootloader/Makefile b/radio/src/bootloader/Makefile index 0e178100f..1e5fa0730 100644 --- a/radio/src/bootloader/Makefile +++ b/radio/src/bootloader/Makefile @@ -169,6 +169,7 @@ CPPSRC = ../targets/taranis/lcd_driver.cpp \ ../lcd.cpp \ ../keys.cpp \ ../fonts.cpp \ + ../strhelpers.cpp \ boot.cpp # List ASM source files here diff --git a/radio/src/bootloader/boot.cpp b/radio/src/bootloader/boot.cpp index bc1280835..f5906bf55 100644 --- a/radio/src/bootloader/boot.cpp +++ b/radio/src/bootloader/boot.cpp @@ -54,6 +54,7 @@ #include #include "board_taranis.h" +#include "../eeprom_rlc.h" #include "../pwr.h" #include "../lcd.h" #include "../keys.h" @@ -90,21 +91,32 @@ enum BootLoaderStates { ST_FLASH_CHECK, ST_FLASHING, ST_FLASH_DONE, + ST_RESTORE_MENU, ST_USB, ST_REBOOT, }; +enum MemoryTypes { + MEM_FLASH, + MEM_EEPROM +}; + /*---------------------------------------------------------------------------- * Local variables *----------------------------------------------------------------------------*/ uint32_t FirmwareSize; +uint32_t firmwareAddress = FIRMWARE_ADDRESS; +uint32_t firmwareWritten = 0; +uint32_t eepromAddress = 0; +uint32_t eepromWritten = 0; + +TCHAR backupFilename[60]; uint32_t Master_frequency; volatile uint8_t Tenms; uint8_t EE_timer; -TCHAR FlashFilename[60]; FIL FlashFile; DIR Dj; FILINFO Finfo; @@ -121,6 +133,8 @@ uint32_t LockBits; uint32_t Block_buffer[1024]; UINT BlockCount; +uint32_t memoryType; + #if defined(PCBSKY9X) extern int32_t EblockAddress; #endif @@ -265,13 +279,6 @@ void hw_delay(uint16_t time) } #endif -uint8_t *cpystr(uint8_t *dest, uint8_t *source) -{ - while ((*dest++ = *source++)) - ; - return dest - 1; -} - FRESULT readBinDir(DIR *dj, FILINFO *fno) { FRESULT fr; @@ -284,7 +291,7 @@ FRESULT readBinDir(DIR *dj, FILINFO *fno) break; } if (*fno->lfname == 0) { - cpystr((uint8_t *) fno->lfname, (uint8_t *) fno->fname); // Copy 8.3 name + strAppend(fno->lfname, fno->fname); // Copy 8.3 name } int32_t len = strlen(fno->lfname) - 4; if (len < 0) { @@ -336,46 +343,63 @@ uint32_t fillNames(uint32_t index) return i; } -FRESULT openFirmwareFile(uint32_t index) +const char *getBinaryPath() { - cpystr(cpystr((uint8_t *)FlashFilename, (uint8_t *)FIRMWARES_PATH "/"), (uint8_t *) Filenames[index]); - f_open(&FlashFile, FlashFilename, FA_READ); - f_lseek(&FlashFile, BOOTLOADER_SIZE); - return f_read(&FlashFile, (BYTE *) Block_buffer, 4096, &BlockCount); + if (memoryType == MEM_FLASH) + return FIRMWARES_PATH; + else + return EEPROMS_PATH; +} + +FRESULT openBinaryFile(uint32_t index) +{ + TCHAR filename[60]; + strAppend(strAppend(strAppend(filename, getBinaryPath()), "/"), Filenames[index]); + f_open(&FlashFile, filename, FA_READ); + if (memoryType == MEM_FLASH) + f_lseek(&FlashFile, BOOTLOADER_SIZE); + return f_read(&FlashFile, (BYTE *)Block_buffer, 4096, &BlockCount); +} + +uint32_t isValidBufferStart(const uint32_t * buffer) +{ + if (memoryType == MEM_FLASH) + return isFirmwareStart(buffer); + else + return isEepromStart(buffer); } int menuFlashFile(uint32_t index, uint8_t event) { FRESULT fr; - lcd_putsLeft(4*FH, "\012Hold [ENT] to start loading" ); + lcd_putsLeft(4*FH, "\012Hold [ENT] to start writing"); if (Valid == 0) { // Validate file here // return 3 if invalid - fr = openFirmwareFile(index); + fr = openBinaryFile(index); fr = f_close(&FlashFile); Valid = 1; - if (!isFirmwareStart(Block_buffer)) { + if (!isValidBufferStart(Block_buffer)) { Valid = 2; } } if (Valid == 2) { - lcd_putsLeft(4*FH, "\011No firmware found in the file!"); - if (event == EVT_KEY_FIRST(BOOT_KEY_EXIT) || event == EVT_KEY_FIRST(BOOT_KEY_MENU)) { + if (memoryType == MEM_FLASH) + lcd_putsLeft(4*FH, "\011Not a valid firmware file! "); + else + lcd_putsLeft(4*FH, "\011Not a valid EEPROM file! "); + if (event == EVT_KEY_BREAK(BOOT_KEY_EXIT) || event == EVT_KEY_BREAK(BOOT_KEY_MENU)) { return 0; } return -1; } if (event == EVT_KEY_LONG(BOOT_KEY_MENU)) { - fr = openFirmwareFile(index); - FirmwareSize = FileSize[index]; - if (fr != FR_OK) { - return 0; // File open error - } - return 1; + fr = openBinaryFile(index); + return (fr == FR_OK && isValidBufferStart(Block_buffer)); } else if (event == EVT_KEY_FIRST(BOOT_KEY_EXIT)) { return 0; @@ -388,20 +412,37 @@ extern Key keys[]; static uint32_t PowerUpDelay; +void writeFlashBlock() +{ + uint32_t blockOffset = 0; + while (BlockCount) { + writeFlash((uint32_t *)firmwareAddress, &Block_buffer[blockOffset]); + blockOffset += FLASH_PAGESIZE/4; // 32-bit words + firmwareAddress += FLASH_PAGESIZE; + if (BlockCount > FLASH_PAGESIZE) { + BlockCount -= FLASH_PAGESIZE; + } + else { + BlockCount = 0; + } + } +} + +void writeEepromBlock() +{ + eeWriteBlockCmp((uint8_t *)Block_buffer, eepromAddress, BlockCount); + eepromAddress += BlockCount; +} + int main() { uint8_t index = 0; -#if defined(PCBTARANIS) - uint8_t TenCount = 2; -#endif uint8_t maxhsize = DISPLAY_CHAR_WIDTH; FRESULT fr; uint32_t state = ST_START; uint32_t nameCount = 0; uint32_t vpos = 0; uint32_t hpos = 0; - uint32_t firmwareAddress = FIRMWARE_ADDRESS; - uint32_t firmwareWritten = 0; #if defined(PCBTARANIS) wdt_reset(); @@ -448,13 +489,6 @@ int main() init_spi(); #endif -#if defined(PCBSKY9X) - uint32_t chip_id = CHIPID->CHIPID_CIDR; - FlashSize = ( (chip_id >> 8 ) & 0x000F ) == 9 ? 256 : 512; -#elif defined(PCBTARANIS) - FlashSize = 512; -#endif - #if defined(PCBSKY9X) LockBits = readLockBits(); if (LockBits) { @@ -474,7 +508,6 @@ int main() wdt_reset(); if (Tenms) { - wdt_reset(); // Retrigger hardware watchdog if (EE_timer) { if (--EE_timer == 0) { @@ -501,17 +534,27 @@ int main() if (state == ST_START) { lcd_putsLeft(2*FH, "\010Write Firmware"); - lcd_putsLeft(3*FH, "\010Exit"); + lcd_putsLeft(3*FH, "\010Restore EEPROM"); + lcd_putsLeft(4*FH, "\010Exit"); lcd_invert_line(2+vpos); - lcd_putsLeft(6*FH, INDENT "Or plug in a USB cable for mass storage"); - if (event == EVT_KEY_FIRST(BOOT_KEY_DOWN) || event == EVT_KEY_FIRST(BOOT_KEY_UP)) { - vpos = (vpos+1) & 0x01; + lcd_putsLeft(7*FH, INDENT "Or plug in a USB cable for mass storage"); + if (event == EVT_KEY_FIRST(BOOT_KEY_DOWN)) { + vpos == 2 ? vpos = 0 : vpos = vpos+1; + } + else if (event == EVT_KEY_FIRST(BOOT_KEY_UP)) { + vpos == 0 ? vpos = 2 : vpos = vpos-1; } else if (event == EVT_KEY_BREAK(BOOT_KEY_MENU)) { - if (vpos == 0) - state = ST_FLASH_MENU; - else - state = ST_REBOOT; + switch (vpos) { + case 0: + state = ST_FLASH_MENU; + break; + case 1: + state = ST_RESTORE_MENU; + break; + default: + state = ST_REBOOT; + } } } @@ -526,19 +569,20 @@ int main() #endif } - if (state == ST_FLASH_MENU) { + if (state == ST_FLASH_MENU || state == ST_RESTORE_MENU) { sdInit(); + memoryType = (state == ST_RESTORE_MENU ? MEM_EEPROM : MEM_FLASH); state = ST_DIR_CHECK; } else if (state == ST_DIR_CHECK) { - fr = f_chdir(FIRMWARES_PATH); + fr = f_chdir(getBinaryPath()); if (fr == FR_OK) { state = ST_OPEN_DIR; } else { - lcd_putsLeft(2*FH, INDENT "No firmware in " FIRMWARES_PATH " directory"); - if (event == EVT_KEY_FIRST(BOOT_KEY_EXIT) || event == EVT_KEY_FIRST(BOOT_KEY_MENU)) { + lcd_putsLeft(2*FH, INDENT "Directory is missing!"); + if (event == EVT_KEY_BREAK(BOOT_KEY_EXIT) || event == EVT_KEY_BREAK(BOOT_KEY_MENU)) { vpos = 0; state = ST_START; } @@ -640,46 +684,42 @@ int main() // confirmed firmwareAddress = FIRMWARE_ADDRESS + BOOTLOADER_SIZE; firmwareWritten = 0; + eepromAddress = 0; + eepromWritten = 0; state = ST_FLASHING; } } - if (state == ST_FLASHING) { - // Commit to flashing - uint32_t blockOffset = 0; + else if (state == ST_FLASHING) { + // commit to flashing lcd_putsLeft(4*FH, "\032Writing..."); - if (firmwareAddress == FIRMWARE_ADDRESS + BOOTLOADER_SIZE) { - if (!isFirmwareStart(Block_buffer)) { - state = ST_FLASH_DONE; - } + int progress; + if (memoryType == MEM_FLASH) { + writeFlashBlock(); + firmwareWritten += sizeof(Block_buffer); + progress = (200*firmwareWritten) / FirmwareSize; } - - while (BlockCount) { - writeFlash((uint32_t *)firmwareAddress, &Block_buffer[blockOffset]); - blockOffset += FLASH_PAGESIZE/4; // 32-bit words - firmwareAddress += FLASH_PAGESIZE; - if (BlockCount > FLASH_PAGESIZE) { - BlockCount -= FLASH_PAGESIZE; - } - else { - BlockCount = 0; - } + else { + writeEepromBlock(); + eepromWritten += sizeof(Block_buffer); + progress = (200*eepromWritten) / EESIZE; } - firmwareWritten += 4; // 4K blocks - lcd_rect( 3, 6*FH+4, 204, 7); - lcd_hline(5, 6*FH+6, (200*firmwareWritten*1024)/FirmwareSize, FORCE); - lcd_hline(5, 6*FH+7, (200*firmwareWritten*1024)/FirmwareSize, FORCE); - lcd_hline(5, 6*FH+8, (200*firmwareWritten*1024)/FirmwareSize, FORCE); + lcd_hline(5, 6*FH+6, progress, FORCE); + lcd_hline(5, 6*FH+7, progress, FORCE); + lcd_hline(5, 6*FH+8, progress, FORCE); fr = f_read(&FlashFile, (BYTE *)Block_buffer, sizeof(Block_buffer), &BlockCount); if (BlockCount == 0) { - state = ST_FLASH_DONE; + state = ST_FLASH_DONE; // EOF } - if (firmwareWritten >= FlashSize - 32) { - state = ST_FLASH_DONE; // Backstop + if (firmwareWritten >= FLASHSIZE - BOOTLOADER_SIZE) { + state = ST_FLASH_DONE; // Backstop + } + if (eepromWritten >= EESIZE) { + state = ST_FLASH_DONE; // Backstop } } @@ -695,10 +735,7 @@ int main() state = ST_REBOOT; } - if (--TenCount == 0) { - TenCount = 2; - lcdRefresh(); - } + lcdRefresh(); if (PowerUpDelay < 20) { // 200 mS PowerUpDelay += 1; diff --git a/radio/src/eeprom_rlc.h b/radio/src/eeprom_rlc.h index 969670e97..b30b4077e 100644 --- a/radio/src/eeprom_rlc.h +++ b/radio/src/eeprom_rlc.h @@ -247,4 +247,13 @@ void loadGeneralSettings(); void loadModel(int index); #endif +// For EEPROM backup/restore +#if defined(CPUARM) +inline bool isEepromStart(const void * buffer) +{ + const EeFs * eeprom = (const EeFs *)buffer; + return (eeprom->version==EEFS_VERS && eeprom->mySize==sizeof(eeFs) && eeprom->bs==BS); +} +#endif + #endif diff --git a/radio/src/gui/menu_general.cpp b/radio/src/gui/menu_general.cpp index 96fbb295a..7341fef8a 100644 --- a/radio/src/gui/menu_general.cpp +++ b/radio/src/gui/menu_general.cpp @@ -685,6 +685,55 @@ inline bool isFilenameLower(bool isfile, const char * fn, const char * line) return (!isfile && line[SD_SCREEN_FILE_LENGTH+1]) || (isfile==(bool)line[SD_SCREEN_FILE_LENGTH+1] && strcasecmp(fn, line) < 0); } +#if defined(PCBTARANIS) +void backupEeprom() +{ + char filename[60]; + uint8_t buffer[1024]; + FIL file; + + lcd_clear(); + lcd_putsLeft(4*FH, STR_WRITING); + lcd_rect(3, 6*FH+4, 204, 7); + lcdRefresh(); + + eeCheck(true); + + // create the directory if needed... + DIR folder; + FRESULT result = f_opendir(&folder, EEPROMS_PATH); + if (result != FR_OK) { + if (result == FR_NO_PATH) + result = f_mkdir(EEPROMS_PATH); + if (result != FR_OK) { + POPUP_WARNING(SDCARD_ERROR(result)); + return; + } + } + + // prepare the filename... + char * tmp = strAppend(filename, EEPROMS_PATH "/eeprom"); + tmp = strAppendDate(tmp, true); + strAppend(tmp, EEPROM_EXT); + + // open the file for writing... + f_open(&file, filename, FA_WRITE | FA_CREATE_ALWAYS); + + for (int i=0; i + +char * strAppend(char * dest, const char * source) +{ + while ((*dest++ = *source++)) + ; + return dest - 1; +} + +#if defined(RTCLOCK) +#include "rtc.h" + +char * strAppendDate(char * str, bool time) +{ + str[0] = '-'; + struct gtm utm; + gettime(&utm); + div_t qr = div(utm.tm_year+1900, 10); + str[4] = '0' + qr.rem; + qr = div(qr.quot, 10); + str[3] = '0' + qr.rem; + qr = div(qr.quot, 10); + str[2] = '0' + qr.rem; + str[1] = '0' + qr.quot; + str[5] = '-'; + qr = div(utm.tm_mon+1, 10); + str[7] = '0' + qr.rem; + str[6] = '0' + qr.quot; + str[8] = '-'; + qr = div(utm.tm_mday, 10); + str[10] = '0' + qr.rem; + str[9] = '0' + qr.quot; + + if (time) { + str[11] = '-'; + div_t qr = div(utm.tm_hour, 10); + str[13] = '0' + qr.rem; + str[12] = '0' + qr.quot; + str[14] = '-'; + qr = div(utm.tm_min, 10); + str[16] = '0' + qr.rem; + str[15] = '0' + qr.quot; + str[17] = '-'; + qr = div(utm.tm_sec, 10); + str[19] = '0' + qr.rem; + str[18] = '0' + qr.quot; + str[20] = '\0'; + return &str[20]; + } + else { + str[11] = '\0'; + return &str[11]; + } +} + +#endif diff --git a/radio/src/targets/taranis/board_taranis.h b/radio/src/targets/taranis/board_taranis.h index 9c97cc5da..06b592c2a 100644 --- a/radio/src/targets/taranis/board_taranis.h +++ b/radio/src/targets/taranis/board_taranis.h @@ -145,8 +145,8 @@ void delay_01us(uint16_t nb); #define FLASH_PAGESIZE 256 void unlockFlash(); void writeFlash(uint32_t * address, uint32_t * buffer); -uint32_t isFirmwareStart(uint32_t *block); -uint32_t isBootloaderStart(uint32_t *block); +uint32_t isFirmwareStart(const uint32_t *block); +uint32_t isBootloaderStart(const uint32_t *block); // Pulses driver void init_no_pulses(uint32_t port); diff --git a/radio/src/targets/taranis/flash_driver.cpp b/radio/src/targets/taranis/flash_driver.cpp index 7e5be65ba..001b8e903 100644 --- a/radio/src/targets/taranis/flash_driver.cpp +++ b/radio/src/targets/taranis/flash_driver.cpp @@ -98,7 +98,7 @@ void writeFlash(uint32_t *address, uint32_t *buffer) // page size is 256 bytes } } -uint32_t isFirmwareStart(uint32_t *block) +uint32_t isFirmwareStart(const uint32_t *block) { if ((block[0] & 0xFFFC0000) != 0x20000000) { return 0; @@ -112,7 +112,7 @@ uint32_t isFirmwareStart(uint32_t *block) return 1; } -uint32_t isBootloaderStart(uint32_t *block) +uint32_t isBootloaderStart(const uint32_t *block) { for (int i=0; i<256; i++) { if (block[i] == 0x544F4F42/*BOOT*/) { diff --git a/radio/src/targets/taranis/usbd_storage_msd.cpp b/radio/src/targets/taranis/usbd_storage_msd.cpp index 73d7b4887..81b073ee0 100644 --- a/radio/src/targets/taranis/usbd_storage_msd.cpp +++ b/radio/src/targets/taranis/usbd_storage_msd.cpp @@ -697,7 +697,7 @@ int32_t fat12Read( uint8_t *buffer, uint16_t sector, uint16_t count ) memcpy(buffer, g_DIRroot, BLOCKSIZE ) ; } else if (sector < 3 + (EESIZE/BLOCKSIZE)) { - eeprom_read_block (buffer, (sector-3)*BLOCKSIZE, BLOCKSIZE); + eeprom_read_block(buffer, (sector-3)*BLOCKSIZE, BLOCKSIZE); } else if (sector < 3 + (EESIZE/BLOCKSIZE) + (FLASHSIZE/BLOCKSIZE)) { uint32_t address; @@ -724,8 +724,7 @@ int32_t fat12Write(const uint8_t *buffer, uint16_t sector, uint32_t count ) } else if (sector < 3 + (EESIZE/BLOCKSIZE)) { while (count) { - const EeFs * test = (const EeFs *)buffer; - if (offset == 0 && test->version==EEFS_VERS && test->mySize==sizeof(eeFs) && test->bs==BS) { + if (offset == 0 && isEepromStart(buffer)) { TRACE("EEPROM start found in sector %d", sector); offset = sector; }