1
0
Fork 0
mirror of https://github.com/EdgeTX/edgetx.git synced 2025-07-19 22:35:10 +03:00

Merge remote-tracking branch 'origin/next' into

kilrah/bl_eeprom_save_load

Conflicts:
	radio/src/bootloader/boot.cpp
This commit is contained in:
bsongis 2014-04-09 10:05:42 +02:00
commit ab7218e5cf
46 changed files with 1731 additions and 1284 deletions

View file

@ -53,10 +53,6 @@
#include <stdlib.h>
#include <string.h>
#if defined(PCBTARANIS)
#include "stm32f2xx_flash.h"
#endif
#include "board_taranis.h"
#include "../pwr.h"
#include "../lcd.h"
@ -67,7 +63,7 @@
#include "../translations/en.h"
#if defined(PCBTARANIS)
#define BOOTLOADER_TITLE " OpenTX Boot Loader v1.0"
#define BOOTLOADER_TITLE " Taranis BootLoader - v1.0"
#define BOOT_KEY_UP KEY_PLUS
#define BOOT_KEY_DOWN KEY_MINUS
#define BOOT_KEY_LEFT KEY_MENU
@ -76,16 +72,13 @@
#define BOOT_KEY_EXIT KEY_EXIT
#define DISPLAY_CHAR_WIDTH 35
#elif defined(PCBSKY9X)
#define BOOTLOADER_TITLE "Boot Loader - Sky9x"
#define BOOTLOADER_TITLE "Sky9x Boot Loader - v1.0"
#endif
#define BOOTLOADER_SIZE 0x8000
#if defined(PCBTARANIS)
#define FIRMWARE_ADDRESS 0x08000000
#elif defined(PCBSKY9X)
#define FIRMWARE_ADDRESS 0x00400000
#endif
const uint8_t bootloaderVersion[] __attribute__ ((section(".version"), used)) =
{
'B', 'O', 'O', 'T', '1', '0'
};
// states
enum BootLoaderStates {
@ -131,7 +124,6 @@ uint32_t Valid;
uint32_t FlashSize;
uint32_t FlashBlocked = 1;
uint32_t LockBits;
uint32_t Block_buffer[1024];
@ -186,112 +178,6 @@ void delay2ms()
}
#endif
#if defined(PCBTARANIS)
uint32_t isFirmwareStart(uint32_t *block)
{
if ((block[0] & 0xFFFC0000) != 0x20000000) {
return 0;
}
if ((block[1] & 0xFFF00000) != 0x08000000) {
return 0;
}
if ((block[2] & 0xFFF00000) != 0x08000000) {
return 0;
}
return 1;
}
#elif defined(PCBSKY9X)
uint32_t isFirmwareStart( uint32_t *block )
{
if ((block[0] & 0xFFFE3000) != 0x20000000 ) {
return 0;
}
if ((block[1] & 0xFFF80000) != 0x00400000) {
return 0;
}
if ((block[2] & 0xFFF80000) != 0x00400000) {
return 0;
}
return 1;
}
#endif
#if defined(PCBSKY9X)
uint32_t (*IAP_Function)(uint32_t, uint32_t);
uint32_t program( uint32_t *address, uint32_t *buffer ) // size is 256 bytes
{
uint32_t FlashSectorNum;
uint32_t flash_cmd = 0;
uint32_t i;
// uint32_t flash_status = 0;
// uint32_t EFCIndex = 0; // 0:EEFC0, 1: EEFC1
/* Initialize the function pointer (retrieve function address from NMI vector) */
if ((uint32_t) address == FIRMWARE_START+BOOTLOADER_SIZE) {
if (isFirmwareStart(buffer))
FlashBlocked = 0;
else
FlashBlocked = 1;
}
if (FlashBlocked) {
return 1;
}
// Always initialise this here, setting a default doesn't seem to work
IAP_Function = (uint32_t (*)(uint32_t, uint32_t)) *(( uint32_t *)0x00800008);
FlashSectorNum = (uint32_t) address;
FlashSectorNum >>= 8;// page size is 256 bytes
FlashSectorNum &= 2047;// max page number
/* Send data to the sector here */
for ( i = 0; i < 64; i += 1 )
{
*address++ = *buffer++;
}
/* build the command to send to EEFC */
flash_cmd = (0x5A << 24) | (FlashSectorNum << 8) | 0x03; //AT91C_MC_FCMD_EWP ;
__disable_irq();
/* Call the IAP function with appropriate command */
i = IAP_Function( 0, flash_cmd );
__enable_irq();
return i;
}
uint32_t readLockBits()
{
// Always initialise this here, setting a default doesn't seem to work
IAP_Function = (uint32_t (*)(uint32_t, uint32_t)) *(( uint32_t *)0x00800008);
uint32_t flash_cmd = (0x5A << 24) | 0x0A;//AT91C_MC_FCMD_GLB ;
__disable_irq();
(void) IAP_Function( 0, flash_cmd );
__enable_irq();
return EFC->EEFC_FRR;
}
void clearLockBits()
{
uint32_t i;
uint32_t flash_cmd = 0;
// Always initialise this here, setting a default doesn't seem to work
IAP_Function = (uint32_t (*)(uint32_t, uint32_t)) *(( uint32_t *)0x00800008);
for ( i = 0; i < 16; i += 1 )
{
flash_cmd = (0x5A << 24) | ((128*i) << 8) | 0x09; //AT91C_MC_FCMD_CLB ;
__disable_irq();
/* Call the IAP function with appropriate command */
(void) IAP_Function( 0, flash_cmd );
__enable_irq();
}
}
#endif
void interrupt10ms(void)
{
Tenms |= 1; // 10 mS has passed
@ -385,116 +271,6 @@ void hw_delay(uint16_t time)
// wait
}
}
//After reset, write is not allowed in the Flash control register (FLASH_CR) to protect the
//Flash memory against possible unwanted operations due, for example, to electric
//disturbances. The following sequence is used to unlock this register:
//1. Write KEY1 = 0x45670123 in the Flash key register (FLASH_KEYR)
//2. Write KEY2 = 0xCDEF89AB in the Flash key register (FLASH_KEYR)
//Any wrong sequence will return a bus error and lock up the FLASH_CR register until the
//next reset.
//The FLASH_CR register can be locked again by software by setting the LOCK bit in the
//FLASH_CR register.
void unlockFlash()
{
FLASH->KEYR = 0x45670123;
FLASH->KEYR = 0xCDEF89AB;
}
void waitFlashIdle()
{
while (FLASH->SR & FLASH_FLAG_BSY) {
wdt_reset();
}
}
#define SECTOR_MASK ((uint32_t)0xFFFFFF07)
void eraseSector(uint32_t sector)
{
waitFlashIdle();
FLASH->CR &= CR_PSIZE_MASK;
FLASH->CR |= FLASH_PSIZE_WORD;
FLASH->CR &= SECTOR_MASK;
FLASH->CR |= FLASH_CR_SER | (sector << 3);
FLASH->CR |= FLASH_CR_STRT;
/* Wait for operation to be completed */
waitFlashIdle();
/* if the erase operation is completed, disable the SER Bit */
FLASH->CR &= (~FLASH_CR_SER);
FLASH->CR &= SECTOR_MASK;
}
uint32_t program(uint32_t *address, uint32_t *buffer) // size is 256 bytes
{
uint32_t i;
if ((uint32_t) address == 0x08008000) {
if (isFirmwareStart(buffer)) {
FlashBlocked = 0;
}
else {
FlashBlocked = 1;
}
}
if (FlashBlocked) {
return 1;
}
if ((uint32_t) address == 0x08008000) {
eraseSector(2);
}
if ((uint32_t) address == 0x0800C000) {
eraseSector(3);
}
if ((uint32_t) address == 0x08010000) {
eraseSector(4);
}
if ((uint32_t) address == 0x08020000) {
eraseSector(5);
}
if ((uint32_t) address == 0x08040000) {
eraseSector(6);
}
if ((uint32_t) address == 0x08060000) {
eraseSector(7);
}
// Now program the 256 bytes
for (i = 0; i < 64; i += 1) {
/* Device voltage range supposed to be [2.7V to 3.6V], the operation will
be done by word */
// Wait for last operation to be completed
waitFlashIdle();
FLASH->CR &= CR_PSIZE_MASK;
FLASH->CR |= FLASH_PSIZE_WORD;
FLASH->CR |= FLASH_CR_PG;
*address = *buffer;
/* Wait for operation to be completed */
waitFlashIdle();
FLASH->CR &= (~FLASH_CR_PG);
/* Check the written value */
if (*address != *buffer) {
/* Flash content doesn't match SRAM content */
return 2;
}
/* Increment FLASH destination address */
address += 1;
buffer += 1;
}
return 0;
}
#endif
uint8_t *cpystr(uint8_t *dest, uint8_t *source)
@ -590,7 +366,7 @@ int menuFlashFile(uint32_t index, uint8_t event)
fr = openFirmwareFile(index);
fr = f_close(&FlashFile);
Valid = 1;
if (isFirmwareStart(Block_buffer) == 0) {
if (!isFirmwareStart(Block_buffer)) {
Valid = 2;
}
}
@ -772,14 +548,10 @@ int main()
}
#if defined(PCBSKY9X)
usbMassStorage();
lcd_putc( 0, 6*FH, 'F' );
lcd_putc( 6, 6*FH, '0' + FlashBlocked );
lcd_putc( 0, 7*FH, 'E' );
lcd_putc( 6, 7*FH, '0' + EepromBlocked );
#endif
}
if ((state == ST_FLASH_MENU) || (state == ST_RESTORE_MENU)) {
if (state == ST_FLASH_MENU || state == ST_RESTORE_MENU) {
sdInit();
state == ST_RESTORE_MENU ? memoryType = MEM_EEPROM : memoryType = MEM_FLASH;
state = ST_DIR_CHECK;
@ -817,7 +589,7 @@ int main()
// TODO Get RTC date/time, dump EEPROM to EEPROMS_PATH/EEPROM_yy-mm-dd-hh-mm-ss.BIN
lcd_putsLeft(2*FH, INDENT "Backup successful!");
//lcd_putsLeft(3*FH, filename);
// lcd_putsLeft(3*FH, filename);
if (event == EVT_KEY_BREAK(BOOT_KEY_EXIT) || event == EVT_KEY_BREAK(BOOT_KEY_MENU)) {
vpos = 0;
state = ST_START;
@ -918,18 +690,26 @@ int main()
if (state == ST_FLASHING) {
// Commit to flashing
uint32_t blockOffset = 0;
lcd_putsLeft(4*FH, "\032Loading...");
lcd_putsLeft(4*FH, "\032Writing...");
if (firmwareAddress == FIRMWARE_ADDRESS + BOOTLOADER_SIZE) {
if (!isFirmwareStart(Block_buffer)) {
state = ST_FLASH_DONE;
}
}
while (BlockCount) {
program((uint32_t *) firmwareAddress, &Block_buffer[blockOffset]); // size is 256 bytes
blockOffset += 64; // 32-bit words (256 bytes)
firmwareAddress += 256;
if (BlockCount > 256) {
BlockCount -= 256;
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;
}
}
firmwareWritten += 4; // 4K blocks
lcd_rect( 3, 6*FH+4, 204, 7);
@ -947,7 +727,7 @@ int main()
}
if (state == ST_FLASH_DONE) {
lcd_putsLeft(4*FH, "\024Loading Complete");
lcd_putsLeft(4*FH, "\024Writing Complete");
if (event == EVT_KEY_FIRST(BOOT_KEY_EXIT) || event == EVT_KEY_BREAK(BOOT_KEY_MENU)) {
state = ST_START;
vpos = 0;