1
0
Fork 0
mirror of https://github.com/opentx/opentx.git synced 2025-07-23 16:25:16 +03:00

Merge pull request #961 from opentx/kilrah/bl_eeprom_save_load

Kilrah/bl eeprom save load
This commit is contained in:
Andre Bernet 2014-04-09 20:36:03 +02:00
commit af4f8e7f36
15 changed files with 261 additions and 109 deletions

View file

@ -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"

View file

@ -20,3 +20,4 @@
/traces
/MODELS
/FIRMWARES
/EEPROMS

View file

@ -949,7 +949,7 @@ endif
ifeq ($(SDCARD), YES)
CPPDEFS += -DSDCARD
CPPSRC += logs.cpp
CPPSRC += logs.cpp strhelpers.cpp
endif
RUN_FROM_FLASH = 1

View file

@ -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

View file

@ -54,6 +54,7 @@
#include <string.h>
#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;

View file

@ -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

View file

@ -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<EESIZE; i+=1024) {
UINT count;
eeprom_read_block(buffer, i, 1024);
f_write(&file, buffer, 1024, &count);
lcd_hline(5, 6*FH+6, (200*i)/EESIZE, FORCE);
lcd_hline(5, 6*FH+7, (200*i)/EESIZE, FORCE);
lcd_hline(5, 6*FH+8, (200*i)/EESIZE, FORCE);
lcdRefresh();
SIMU_SLEEP(100/*ms*/);
}
f_close(&file);
}
#endif
#if defined(PCBTARANIS)
void flashBootloader(const char * filename)
{
@ -696,6 +745,7 @@ void flashBootloader(const char * filename)
lcd_clear();
lcd_putsLeft(4*FH, STR_WRITING);
lcd_rect(3, 6*FH+4, 204, 7);
lcdRefresh();
static uint8_t unlocked = 0;
if (!unlocked) {
@ -719,8 +769,10 @@ void flashBootloader(const char * filename)
lcd_hline(5, 6*FH+7, (200*i)/BOOTLOADER_SIZE, FORCE);
lcd_hline(5, 6*FH+8, (200*i)/BOOTLOADER_SIZE, FORCE);
lcdRefresh();
SIMU_SLEEP(30/*ms*/);
}
}
f_close(&file);
}
#endif
@ -1131,6 +1183,13 @@ void menuGeneralVersion(uint8_t event)
lcd_putsLeft(6*FH, PSTR("CoPr: ---"));
}
#endif
#if defined(PCBTARANIS)
lcd_putsLeft(7*FH, "\004[ENTER Long] to backup the EEPROM");
if (event == EVT_KEY_LONG(KEY_ENTER)) {
backupEeprom();
}
#endif
}
void displayKeyState(uint8_t x, uint8_t y, EnumKeys key)

View file

@ -295,5 +295,7 @@ void lcdRefresh();
#define LCD_BYTE_FILTER(p, keep, add) LCD_BYTE_FILTER_PLAN(p, keep, add)
#endif
char * strAppend(char * dest, const char * source);
char * strAppendDate(char * str, bool time=false);
#endif
/*eof*/

View file

@ -95,28 +95,13 @@ const pm_char * openLogs()
len = sizeof(LOGS_PATH) + PSIZE(TR_MODEL) + 2;
}
char * tmp = &filename[len];
#if defined(RTCLOCK)
filename[len] = '-';
struct gtm utm;
gettime(&utm);
div_t qr = div(utm.tm_year+1900, 10);
filename[len+4] = '0' + qr.rem;
qr = div(qr.quot, 10);
filename[len+3] = '0' + qr.rem;
qr = div(qr.quot, 10);
filename[len+2] = '0' + qr.rem;
filename[len+1] = '0' + qr.quot;
filename[len+5] = '-';
qr = div(utm.tm_mon+1, 10);
filename[len+7] = '0' + qr.rem;
filename[len+6] = '0' + qr.quot;
filename[len+8] = '-';
qr = div(utm.tm_mday, 10);
filename[len+10] = '0' + qr.rem;
filename[len+9] = '0' + qr.quot;
tmp = strAppendDate(&filename[len]);
#endif
strcpy_P(&filename[len+11], STR_LOGS_EXT);
strcpy_P(tmp, STR_LOGS_EXT);
result = f_open(&g_oLogFile, filename, FA_OPEN_ALWAYS | FA_WRITE);
if (result != FR_OK) {

View file

@ -48,6 +48,7 @@
#define BITMAPS_PATH ROOT_PATH "BMP"
#define SCRIPTS_PATH ROOT_PATH "SCRIPTS"
#define FIRMWARES_PATH ROOT_PATH "FIRMWARES"
#define EEPROMS_PATH ROOT_PATH "EEPROMS"
#define MODELS_EXT ".bin"
#define LOGS_EXT ".csv"
@ -56,6 +57,7 @@
#define SCRIPTS_EXT ".lua"
#define TEXT_EXT ".txt"
#define FIRMWARE_EXT ".bin"
#define EEPROM_EXT ".bin"
extern FATFS g_FATFS_Obj;

View file

@ -674,6 +674,6 @@ FlagStatus RCC_GetFlagStatus(uint8_t RCC_FLAG) { return RESET; }
ErrorStatus RTC_WaitForSynchro(void) { return SUCCESS; }
void unlockFlash() { }
void writeFlash(uint32_t *address, uint32_t *buffer) { SIMU_SLEEP(100); }
uint32_t isBootloaderStart(uint32_t *block) { return 1; }
uint32_t isBootloaderStart(const uint32_t *block) { return 1; }
#endif

56
radio/src/strhelpers.cpp Executable file
View file

@ -0,0 +1,56 @@
#include <stdlib.h>
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

View file

@ -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);

View file

@ -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*/) {

View file

@ -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;
}