mirror of
https://github.com/opentx/opentx.git
synced 2025-07-17 05:15:18 +03:00
MAGIC value for powerReason should be stored in RTC backup on Horus (#7096)
- Allows the radio main application to start correctly when coming from an app in RAM - Refactoring of the `UNEXPECTED_SHUTDOWN()` process - Saves the RTC battery as BACKUP RAM is not needed on normal shutdown - On PWR OFF on an ALERT, the radio won't show the next alert before shutting down - Bootloader flashable through the SD Manager
This commit is contained in:
parent
103534bdcf
commit
4cdd17f0d7
41 changed files with 235 additions and 190 deletions
|
@ -148,11 +148,11 @@ include_directories(${CMAKE_CURRENT_BINARY_DIR}/bitmaps/${GUI_DIR})
|
|||
add_subdirectory(lua)
|
||||
include(gui/CMakeLists.txt)
|
||||
|
||||
if(RAMBACKUP)
|
||||
add_definitions(-DRAMBACKUP)
|
||||
if(RTC_BACKUP_RAM)
|
||||
add_definitions(-DRTC_BACKUP_RAM)
|
||||
set(SRC ${SRC} storage/rlc.cpp)
|
||||
set(FIRMWARE_SRC ${FIRMWARE_SRC} storage/rambackup.cpp)
|
||||
set(GTEST_SRC ${GTEST_SRC} ${RADIO_SRC_DIRECTORY}/storage/rambackup.cpp)
|
||||
set(FIRMWARE_SRC ${FIRMWARE_SRC} storage/rtc_backup.cpp)
|
||||
set(GTEST_SRC ${GTEST_SRC} ${RADIO_SRC_DIRECTORY}/storage/rtc_backup.cpp)
|
||||
endif()
|
||||
|
||||
if(NOT LUA STREQUAL NO)
|
||||
|
|
|
@ -762,11 +762,11 @@ const char * Bluetooth::flashFirmware(const char * filename)
|
|||
pausePulses();
|
||||
|
||||
bluetoothInit(BLUETOOTH_BOOTLOADER_BAUDRATE, true); // normal mode
|
||||
watchdogSuspend(1000);
|
||||
watchdogSuspend(500 /*5s*/);
|
||||
RTOS_WAIT_MS(1000);
|
||||
|
||||
bluetoothInit(BLUETOOTH_BOOTLOADER_BAUDRATE, false); // bootloader mode
|
||||
watchdogSuspend(1000);
|
||||
watchdogSuspend(500 /*5s*/);
|
||||
RTOS_WAIT_MS(1000);
|
||||
|
||||
const char * result = doFlashFirmware(filename);
|
||||
|
@ -785,7 +785,7 @@ const char * Bluetooth::flashFirmware(const char * filename)
|
|||
drawProgressScreen(getBasename(filename), STR_MODULE_RESET, 0, 0);
|
||||
|
||||
/* wait 1s off */
|
||||
watchdogSuspend(1000);
|
||||
watchdogSuspend(500 /*5s*/);
|
||||
RTOS_WAIT_MS(1000);
|
||||
|
||||
state = BLUETOOTH_STATE_OFF;
|
||||
|
|
|
@ -94,7 +94,7 @@ void readModelNotes()
|
|||
menuTextView(event);
|
||||
event = getEvent();
|
||||
lcdRefresh();
|
||||
wdt_reset();
|
||||
WDG_RESET();
|
||||
}
|
||||
|
||||
LED_ERROR_END();
|
||||
|
|
|
@ -51,7 +51,7 @@ bool menuRadioPowerMeter(event_t event)
|
|||
lcdRefresh();
|
||||
moduleState[g_moduleIdx].readModuleInformation(&reusableBuffer.moduleSetup.pxx2.moduleInformation, PXX2_HW_INFO_TX_ID, PXX2_HW_INFO_TX_ID);
|
||||
/* wait 1s to resume normal operation before leaving */
|
||||
watchdogSuspend(1000);
|
||||
watchdogSuspend(500 /*5s*/);
|
||||
RTOS_WAIT_MS(1000);
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -159,6 +159,10 @@ void onSdManagerMenu(const char * result)
|
|||
getSelectionFullPath(lfn);
|
||||
pushMenuTextView(lfn);
|
||||
}
|
||||
else if (result == STR_FLASH_BOOTLOADER) {
|
||||
getSelectionFullPath(lfn);
|
||||
bootloaderFlash(lfn);
|
||||
}
|
||||
else if (result == STR_FLASH_INTERNAL_MODULE) {
|
||||
getSelectionFullPath(lfn);
|
||||
FrskyDeviceFirmwareUpdate device(INTERNAL_MODULE);
|
||||
|
@ -278,6 +282,13 @@ bool menuRadioSdManager(event_t _event)
|
|||
POPUP_MENU_ADD_ITEM(STR_ASSIGN_SPLASH);
|
||||
}
|
||||
}
|
||||
if (!READ_ONLY() && !strcasecmp(ext, FIRMWARE_EXT)) {
|
||||
TCHAR lfn[_MAX_LFN+1];
|
||||
getSelectionFullPath(lfn);
|
||||
if (isBootloader(lfn)) {
|
||||
POPUP_MENU_ADD_ITEM(STR_FLASH_BOOTLOADER);
|
||||
}
|
||||
}
|
||||
else if (!READ_ONLY() && !strcasecmp(ext, SPORT_FIRMWARE_EXT)) {
|
||||
if (HAS_SPORT_UPDATE_CONNECTOR())
|
||||
POPUP_MENU_ADD_ITEM(STR_FLASH_EXTERNAL_DEVICE);
|
||||
|
|
|
@ -65,7 +65,7 @@ bool menuRadioSpectrumAnalyser(event_t event)
|
|||
moduleState[g_moduleIdx].mode = MODULE_MODE_NORMAL;
|
||||
}
|
||||
/* wait 1s to resume normal operation before leaving */
|
||||
watchdogSuspend(1000);
|
||||
watchdogSuspend(500 /*5s*/);
|
||||
RTOS_WAIT_MS(1000);
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -74,11 +74,11 @@ void drawFatalErrorScreen(const char * message)
|
|||
|
||||
void runFatalErrorScreen(const char * message)
|
||||
{
|
||||
while (1) {
|
||||
while (true) {
|
||||
drawFatalErrorScreen(message);
|
||||
backlightEnable(100);
|
||||
uint8_t refresh = false;
|
||||
while (1) {
|
||||
while (true) {
|
||||
uint32_t pwr_check = pwrCheck();
|
||||
if (pwr_check == e_power_off) {
|
||||
boardOff();
|
||||
|
|
|
@ -50,7 +50,7 @@ void menuRadioPowerMeter(event_t event)
|
|||
lcdRefresh();
|
||||
moduleState[g_moduleIdx].readModuleInformation(&reusableBuffer.moduleSetup.pxx2.moduleInformation, PXX2_HW_INFO_TX_ID, PXX2_HW_INFO_TX_ID);
|
||||
/* wait 1s to resume normal operation before leaving */
|
||||
watchdogSuspend(1000);
|
||||
watchdogSuspend(500 /*5s*/);
|
||||
RTOS_WAIT_MS(1000);
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -44,7 +44,7 @@ void menuRadioSpectrumAnalyser(event_t event)
|
|||
lcdRefresh();
|
||||
moduleState[g_moduleIdx].readModuleInformation(&reusableBuffer.moduleSetup.pxx2.moduleInformation, PXX2_HW_INFO_TX_ID, PXX2_HW_INFO_TX_ID);
|
||||
/* wait 1s to resume normal operation before leaving */
|
||||
watchdogSuspend(1000);
|
||||
watchdogSuspend(500 /*5s*/);
|
||||
RTOS_WAIT_MS(1000);
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -44,7 +44,7 @@ void readModelNotes()
|
|||
menuTextView(event);
|
||||
event = getEvent();
|
||||
lcdRefresh();
|
||||
wdt_reset();
|
||||
WDG_RESET();
|
||||
}
|
||||
|
||||
LED_ERROR_END();
|
||||
|
|
|
@ -27,7 +27,7 @@ bool isBootloader(const char * filename)
|
|||
uint8_t buffer[1024];
|
||||
UINT count;
|
||||
|
||||
if (f_read(&file, buffer, 1024, &count) != FR_OK || count != 1024) {
|
||||
if (f_read(&file, buffer, sizeof(buffer), &count) != FR_OK || count != sizeof(buffer)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -47,18 +47,18 @@ void bootloaderFlash(const char * filename)
|
|||
unlockFlash();
|
||||
}
|
||||
|
||||
for (int i=0; i<BOOTLOADER_SIZE; i+=1024) {
|
||||
watchdogSuspend(100/*1s*/);
|
||||
if (f_read(&file, buffer, 1024, &count) != FR_OK || count != 1024) {
|
||||
for (int i = 0; i < BOOTLOADER_SIZE; i += 1024) {
|
||||
watchdogSuspend(1000/*10s*/);
|
||||
if (f_read(&file, buffer, sizeof(buffer), &count) != FR_OK || count != sizeof(buffer)) {
|
||||
POPUP_WARNING(STR_SDCARD_ERROR);
|
||||
break;
|
||||
}
|
||||
if (i==0 && !isBootloaderStart(buffer)) {
|
||||
if (i == 0 && !isBootloaderStart(buffer)) {
|
||||
POPUP_WARNING(STR_INCOMPATIBLE);
|
||||
break;
|
||||
}
|
||||
for (int j=0; j<1024; j+=FLASH_PAGESIZE) {
|
||||
flashWrite(CONVERT_UINT_PTR(FIRMWARE_ADDRESS+i+j), (uint32_t *)(buffer+j));
|
||||
for (int j = 0; j < 1024; j += FLASH_PAGESIZE) {
|
||||
flashWrite(CONVERT_UINT_PTR(FIRMWARE_ADDRESS + i + j), CONVERT_UINT_PTR(buffer + j));
|
||||
}
|
||||
drawProgressScreen("Bootloader", STR_WRITING, i, BOOTLOADER_SIZE);
|
||||
#if defined(SIMU)
|
||||
|
@ -68,6 +68,8 @@ void bootloaderFlash(const char * filename)
|
|||
#endif
|
||||
}
|
||||
|
||||
watchdogSuspend(0);
|
||||
|
||||
if (unlocked) {
|
||||
lockFlash();
|
||||
unlocked = 0;
|
||||
|
|
|
@ -492,7 +492,7 @@ const char * FrskyDeviceFirmwareUpdate::flashFirmware(const char * filename)
|
|||
drawProgressScreen(getBasename(filename), STR_DEVICE_RESET, 0, 0);
|
||||
|
||||
/* wait 2s off */
|
||||
watchdogSuspend(2000);
|
||||
watchdogSuspend(1000 /*10s*/);
|
||||
RTOS_WAIT_MS(2000);
|
||||
|
||||
const char * result = doFlashFirmware(filename);
|
||||
|
@ -515,7 +515,7 @@ const char * FrskyDeviceFirmwareUpdate::flashFirmware(const char * filename)
|
|||
SPORT_UPDATE_POWER_OFF();
|
||||
|
||||
/* wait 2s off */
|
||||
watchdogSuspend(2000);
|
||||
watchdogSuspend(500 /*5s*/);
|
||||
RTOS_WAIT_MS(2000);
|
||||
telemetryClearFifo();
|
||||
|
||||
|
@ -756,7 +756,7 @@ const char * FrskyChipFirmwareUpdate::flashFirmware(const char * filename, bool
|
|||
|
||||
if (wait) {
|
||||
/* wait 2s off */
|
||||
watchdogSuspend(2000);
|
||||
watchdogSuspend(1000 /*10s*/);
|
||||
RTOS_WAIT_MS(2000);
|
||||
}
|
||||
|
||||
|
@ -776,7 +776,7 @@ const char * FrskyChipFirmwareUpdate::flashFirmware(const char * filename, bool
|
|||
}
|
||||
|
||||
/* wait 2s off */
|
||||
watchdogSuspend(2000);
|
||||
watchdogSuspend(1000 /*10s*/);
|
||||
RTOS_WAIT_MS(2000);
|
||||
|
||||
#if defined(HARDWARE_INTERNAL_MODULE)
|
||||
|
|
|
@ -195,7 +195,7 @@ const char * MultiFirmwareUpdateDriver::waitForInitialSync(bool& inverted) const
|
|||
sendByte(CRC_EOP);
|
||||
|
||||
getRxByte(byte);
|
||||
wdt_reset();
|
||||
WDG_RESET();
|
||||
|
||||
} while((byte != STK_INSYNC) && --retries);
|
||||
|
||||
|
@ -270,7 +270,7 @@ const char * MultiFirmwareUpdateDriver::progPage(uint8_t* buffer, uint16_t size)
|
|||
uint8_t retries = 4;
|
||||
do {
|
||||
getRxByte(byte);
|
||||
wdt_reset();
|
||||
WDG_RESET();
|
||||
} while(!byte && --retries);
|
||||
|
||||
if (!retries || (byte != STK_OK))
|
||||
|
@ -298,7 +298,7 @@ const char * MultiFirmwareUpdateDriver::flashFirmware(FIL* file, const char* lab
|
|||
init(inverted);
|
||||
|
||||
/* wait 500ms for power on */
|
||||
watchdogSuspend(500);
|
||||
watchdogSuspend(500 /*5s*/);
|
||||
RTOS_WAIT_MS(500);
|
||||
|
||||
result = waitForInitialSync(inverted);
|
||||
|
@ -533,7 +533,7 @@ bool multiFlashFirmware(uint8_t moduleIdx, const char * filename)
|
|||
drawProgressScreen(getBasename(filename), STR_DEVICE_RESET, 0, 0);
|
||||
|
||||
/* wait 2s off */
|
||||
watchdogSuspend(2000);
|
||||
watchdogSuspend(500 /*5s*/);
|
||||
RTOS_WAIT_MS(2000);
|
||||
|
||||
const char * result = driver->flashFirmware(&file, getBasename(filename));
|
||||
|
@ -557,7 +557,7 @@ bool multiFlashFirmware(uint8_t moduleIdx, const char * filename)
|
|||
SPORT_UPDATE_POWER_OFF();
|
||||
|
||||
/* wait 2s off */
|
||||
watchdogSuspend(2000);
|
||||
watchdogSuspend(500 /*5s*/);
|
||||
RTOS_WAIT_MS(2000);
|
||||
|
||||
// reset telemetry protocol
|
||||
|
|
|
@ -189,7 +189,7 @@ bool waitKeysReleased()
|
|||
#endif
|
||||
|
||||
while (keyDown()) {
|
||||
wdt_reset();
|
||||
WDG_RESET();
|
||||
|
||||
#if !defined(BOOT)
|
||||
if ((get_tmr10ms() - start) >= 300) { // wait no more than 3 seconds
|
||||
|
|
|
@ -167,8 +167,8 @@ void checkEeprom()
|
|||
#else
|
||||
void checkEeprom()
|
||||
{
|
||||
#if defined(RAMBACKUP) && !defined(SIMU)
|
||||
if (TIME_TO_RAMBACKUP()) {
|
||||
#if defined(RTC_BACKUP_RAM) && !defined(SIMU)
|
||||
if (TIME_TO_BACKUP_RAM()) {
|
||||
rambackupWrite();
|
||||
rambackupDirtyMsk = 0;
|
||||
}
|
||||
|
@ -504,7 +504,7 @@ void perMain()
|
|||
|
||||
event_t evt = getEvent(false);
|
||||
|
||||
#if defined(RAMBACKUP)
|
||||
#if defined(RTC_BACKUP_RAM)
|
||||
if (globalData.unexpectedShutdown) {
|
||||
drawFatalErrorScreen(STR_EMERGENCY_MODE);
|
||||
return;
|
||||
|
|
|
@ -109,7 +109,7 @@ void per10ms()
|
|||
|
||||
if (watchdogTimeout) {
|
||||
watchdogTimeout -= 1;
|
||||
wdt_reset(); // Retrigger hardware watchdog
|
||||
WDG_RESET(); // Retrigger hardware watchdog
|
||||
}
|
||||
|
||||
#if defined(GUI)
|
||||
|
@ -932,7 +932,7 @@ void checkAll()
|
|||
tmr10ms_t tgtime = get_tmr10ms() + 500;
|
||||
while (tgtime != get_tmr10ms()) {
|
||||
RTOS_WAIT_MS(1);
|
||||
wdt_reset();
|
||||
WDG_RESET();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -999,6 +999,8 @@ void checkThrottleStick()
|
|||
#if defined(PWR_BUTTON_PRESS)
|
||||
uint32_t power = pwrCheck();
|
||||
if (power == e_power_off) {
|
||||
drawSleepBitmap();
|
||||
boardOff();
|
||||
break;
|
||||
}
|
||||
else if (power == e_power_press) {
|
||||
|
@ -1016,7 +1018,7 @@ void checkThrottleStick()
|
|||
|
||||
doLoopCommonActions();
|
||||
|
||||
wdt_reset();
|
||||
WDG_RESET();
|
||||
|
||||
RTOS_WAIT_MS(10);
|
||||
}
|
||||
|
@ -1047,7 +1049,7 @@ void alert(const char * title, const char * msg , uint8_t sound)
|
|||
bool refresh = false;
|
||||
#endif
|
||||
|
||||
while (1) {
|
||||
while (true) {
|
||||
RTOS_WAIT_MS(10);
|
||||
|
||||
if (keyDown()) // wait for key release
|
||||
|
@ -1055,7 +1057,7 @@ void alert(const char * title, const char * msg , uint8_t sound)
|
|||
|
||||
doLoopCommonActions();
|
||||
|
||||
wdt_reset();
|
||||
WDG_RESET();
|
||||
|
||||
const uint32_t pwr_check = pwrCheck();
|
||||
if (pwr_check == e_power_off) {
|
||||
|
@ -1858,6 +1860,10 @@ void opentxInit()
|
|||
globalData.unexpectedShutdown = 1;
|
||||
}
|
||||
|
||||
#if defined(RTC_BACKUP_RAM)
|
||||
SET_POWER_REASON(0);
|
||||
#endif
|
||||
|
||||
#if defined(SDCARD)
|
||||
// SDCARD related stuff, only done if not unexpectedShutdown
|
||||
if (!globalData.unexpectedShutdown) {
|
||||
|
@ -1909,7 +1915,7 @@ void opentxInit()
|
|||
|
||||
// handling of storage for radios that have no EEPROM
|
||||
#if !defined(EEPROM)
|
||||
#if defined(RAMBACKUP) && !defined(SIMU)
|
||||
#if defined(RTC_BACKUP_RAM) && !defined(SIMU)
|
||||
if (globalData.unexpectedShutdown) {
|
||||
// SDCARD not available, try to restore last model from RAM
|
||||
TRACE("rambackupRestore");
|
||||
|
@ -1966,20 +1972,22 @@ void opentxInit()
|
|||
opentxStart();
|
||||
}
|
||||
|
||||
// TODO Horus does not need this
|
||||
#if !defined(RTC_BACKUP_RAM)
|
||||
if (!g_eeGeneral.unexpectedShutdown) {
|
||||
g_eeGeneral.unexpectedShutdown = 1;
|
||||
storageDirty(EE_GENERAL);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(GUI)
|
||||
lcdSetContrast();
|
||||
#endif
|
||||
|
||||
backlightOn();
|
||||
|
||||
startPulses();
|
||||
|
||||
wdt_enable(WDTO_500MS);
|
||||
WDG_ENABLE(WDG_DURATION);
|
||||
}
|
||||
|
||||
#if defined(SIMU)
|
||||
|
@ -2001,7 +2009,7 @@ int main()
|
|||
|
||||
// G: The WDT remains active after a WDT reset -- at maximum clock speed. So it's
|
||||
// important to disable it before commencing with system initialisation (or
|
||||
// we could put a bunch more wdt_reset()s in. But I don't like that approach
|
||||
// we could put a bunch more WDG_RESET()s in. But I don't like that approach
|
||||
// during boot up.)
|
||||
#if defined(PCBTARANIS)
|
||||
g_eeGeneral.contrast = LCD_CONTRAST_DEFAULT;
|
||||
|
@ -2018,7 +2026,9 @@ int main()
|
|||
#endif
|
||||
|
||||
#if defined(SPLASH) && !defined(STARTUP_ANIMATION)
|
||||
if (!UNEXPECTED_SHUTDOWN()) {
|
||||
drawSplash();
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(PCBHORUS)
|
||||
|
|
|
@ -443,7 +443,7 @@ bool Pxx2OtaUpdate::waitStep(uint8_t step, uint8_t timeout)
|
|||
OtaUpdateInformation * destination = moduleState[module].otaUpdateInformation;
|
||||
uint8_t elapsed = 0;
|
||||
|
||||
watchdogSuspend(100);
|
||||
watchdogSuspend(100 /*1s*/);
|
||||
|
||||
while (step != destination->step) {
|
||||
if (elapsed++ > timeout) {
|
||||
|
@ -532,7 +532,7 @@ void Pxx2OtaUpdate::flashFirmware(const char * filename)
|
|||
{
|
||||
pausePulses();
|
||||
|
||||
watchdogSuspend(100);
|
||||
watchdogSuspend(100 /*1s*/);
|
||||
RTOS_WAIT_MS(100);
|
||||
|
||||
moduleState[module].mode = MODULE_MODE_OTA_UPDATE;
|
||||
|
|
|
@ -729,7 +729,7 @@ void RlcFile::nextRlcWriteStep()
|
|||
void RlcFile::flush()
|
||||
{
|
||||
while (!eepromIsTransferComplete())
|
||||
wdt_reset();
|
||||
WDG_RESET();
|
||||
|
||||
ENABLE_SYNC_WRITE(true);
|
||||
|
||||
|
|
33
radio/src/storage/rtc_backup.h
Normal file
33
radio/src/storage/rtc_backup.h
Normal file
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
* Copyright (C) OpenTX
|
||||
*
|
||||
* Based on code named
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#ifndef _RAM_BACKUP_H_
|
||||
#define _RAM_BACKUP_H_
|
||||
|
||||
#include "definitions.h"
|
||||
|
||||
PACK(struct RamBackup {
|
||||
uint16_t size;
|
||||
uint8_t data[4094];
|
||||
});
|
||||
|
||||
extern RamBackup * ramBackup;
|
||||
|
||||
#endif // _RAM_BACKUP_H_
|
|
@ -38,11 +38,4 @@ const char * createModel();
|
|||
const char * loadRadioSettings(const char * path);
|
||||
const char * loadRadioSettings();
|
||||
|
||||
PACK(struct RamBackup {
|
||||
uint16_t size;
|
||||
uint8_t data[4094];
|
||||
});
|
||||
|
||||
extern RamBackup * ramBackup;
|
||||
|
||||
#endif // _SDCARD_RAW_H_
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
|
||||
#if defined(SIMU)
|
||||
#define WRITE_DELAY_10MS 100
|
||||
#elif defined(RAMBACKUP)
|
||||
#elif defined(RTC_BACKUP_RAM)
|
||||
#define WRITE_DELAY_10MS 1500 /* 15s */
|
||||
#elif defined(PCBTARANIS)
|
||||
#define WRITE_DELAY_10MS 500
|
||||
|
@ -37,10 +37,11 @@ extern uint8_t storageDirtyMsk;
|
|||
extern tmr10ms_t storageDirtyTime10ms;
|
||||
#define TIME_TO_WRITE() (storageDirtyMsk && (tmr10ms_t)(get_tmr10ms() - storageDirtyTime10ms) >= (tmr10ms_t)WRITE_DELAY_10MS)
|
||||
|
||||
#if defined(RAMBACKUP)
|
||||
#if defined(RTC_BACKUP_RAM)
|
||||
#include "storage/rtc_backup.h"
|
||||
extern uint8_t rambackupDirtyMsk;
|
||||
extern tmr10ms_t rambackupDirtyTime10ms;
|
||||
#define TIME_TO_RAMBACKUP() (rambackupDirtyMsk && (tmr10ms_t)(get_tmr10ms() - rambackupDirtyTime10ms) >= (tmr10ms_t)100)
|
||||
#define TIME_TO_BACKUP_RAM() (rambackupDirtyMsk && (tmr10ms_t)(get_tmr10ms() - rambackupDirtyTime10ms) >= (tmr10ms_t)100)
|
||||
#endif
|
||||
|
||||
void storageEraseAll(bool warn);
|
||||
|
@ -64,7 +65,7 @@ void checkExternalAntenna();
|
|||
#include "sdcard_raw.h"
|
||||
#endif
|
||||
|
||||
#if defined(RAMBACKUP)
|
||||
#if defined(RTC_BACKUP_RAM)
|
||||
void rambackupWrite();
|
||||
bool rambackupRestore();
|
||||
unsigned int compress(uint8_t * dst, unsigned int dstsize, const uint8_t * src, unsigned int len);
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
uint8_t storageDirtyMsk;
|
||||
tmr10ms_t storageDirtyTime10ms;
|
||||
|
||||
#if defined(RAMBACKUP)
|
||||
#if defined(RTC_BACKUP_RAM)
|
||||
uint8_t rambackupDirtyMsk;
|
||||
tmr10ms_t rambackupDirtyTime10ms;
|
||||
#endif
|
||||
|
@ -34,7 +34,7 @@ void storageDirty(uint8_t msk)
|
|||
storageDirtyMsk |= msk;
|
||||
storageDirtyTime10ms = get_tmr10ms();
|
||||
|
||||
#if defined(RAMBACKUP)
|
||||
#if defined(RTC_BACKUP_RAM)
|
||||
rambackupDirtyMsk = storageDirtyMsk;
|
||||
rambackupDirtyTime10ms = storageDirtyTime10ms;
|
||||
#endif
|
||||
|
|
|
@ -561,8 +561,7 @@ void checkSwitches()
|
|||
bool refresh = false;
|
||||
#endif
|
||||
|
||||
while (1) {
|
||||
|
||||
while (true) {
|
||||
#if defined(PCBTARANIS) || defined(PCBHORUS)
|
||||
#define GETADC_COUNT 1
|
||||
#endif
|
||||
|
@ -749,6 +748,8 @@ void checkSwitches()
|
|||
#if defined(PWR_BUTTON_PRESS)
|
||||
uint32_t power = pwrCheck();
|
||||
if (power == e_power_off) {
|
||||
drawSleepBitmap();
|
||||
boardOff();
|
||||
break;
|
||||
}
|
||||
else if (power == e_power_press) {
|
||||
|
@ -767,7 +768,7 @@ void checkSwitches()
|
|||
|
||||
doLoopCommonActions();
|
||||
|
||||
wdt_reset();
|
||||
WDG_RESET();
|
||||
|
||||
RTOS_WAIT_MS(10);
|
||||
}
|
||||
|
|
|
@ -8,6 +8,8 @@ if(CPU_TYPE_FULL STREQUAL STM32F429xI)
|
|||
../f4/system_stm32f4xx.c
|
||||
../../../../../targets/${TARGET_DIR}/startup_stm32f42_43xxx.s
|
||||
../../../../../${STM32LIB_DIR}/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_rcc.c
|
||||
../../../../../${STM32LIB_DIR}/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_rtc.c
|
||||
../../../../../${STM32LIB_DIR}/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_pwr.c
|
||||
../../../../../${STM32LIB_DIR}/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_syscfg.c
|
||||
../../../../../${STM32LIB_DIR}/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_gpio.c
|
||||
../../../../../${STM32LIB_DIR}/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_exti.c
|
||||
|
@ -25,6 +27,8 @@ elseif(CPU_TYPE_FULL STREQUAL STM32F407xE)
|
|||
../f4/system_stm32f4xx.c
|
||||
../../../../../targets/${TARGET_DIR}/startup_stm32f40_41xxx.s
|
||||
../../../../../${STM32LIB_DIR}/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_rcc.c
|
||||
../../../../../${STM32LIB_DIR}/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_rtc.c
|
||||
../../../../../${STM32LIB_DIR}/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_pwr.c
|
||||
../../../../../${STM32LIB_DIR}/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_syscfg.c
|
||||
../../../../../${STM32LIB_DIR}/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_gpio.c
|
||||
../../../../../${STM32LIB_DIR}/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_exti.c
|
||||
|
@ -99,20 +103,16 @@ if(PCB STREQUAL X7 OR PCB STREQUAL XLITE OR PCB STREQUAL XLITES)
|
|||
)
|
||||
endif()
|
||||
|
||||
if(NOT (PCB STREQUAL X10 OR PCB STREQUAL X12S))
|
||||
set(BOOTLOADER_SRC
|
||||
${BOOTLOADER_SRC}
|
||||
../../../../../targets/${TARGET_DIR}/i2c_driver.cpp
|
||||
)
|
||||
remove_definitions(-DDEBUG)
|
||||
else()
|
||||
if(PCB STREQUAL X10 OR PCB STREQUAL X12S)
|
||||
set(BOOTLOADER_SRC
|
||||
${BOOTLOADER_SRC}
|
||||
../../../../../targets/${TARGET_DIR}/sdram_driver.c
|
||||
../../../../../targets/common/arm/stm32/sdio_sd.c
|
||||
../../../../../targets/common/arm/stm32/rtc_driver.cpp
|
||||
../../../../../targets/${TARGET_DIR}/haptic_driver.cpp
|
||||
../../../../../gui/${GUI_DIR}/bitmapbuffer.cpp
|
||||
../../../../../gui/${GUI_DIR}/rle.cpp
|
||||
|
||||
../../../../../syscalls.c
|
||||
)
|
||||
|
||||
|
@ -123,12 +123,20 @@ else()
|
|||
../../../../../serial.cpp
|
||||
)
|
||||
endif()
|
||||
else()
|
||||
set(BOOTLOADER_SRC
|
||||
${BOOTLOADER_SRC}
|
||||
../../../../../targets/${TARGET_DIR}/i2c_driver.cpp
|
||||
)
|
||||
remove_definitions(-DDEBUG)
|
||||
endif()
|
||||
|
||||
remove_definitions(-DDISK_CACHE)
|
||||
remove_definitions(-DLUA)
|
||||
remove_definitions(-DCLI)
|
||||
remove_definitions(-DUSB_SERIAL)
|
||||
remove_definitions(-DWATCHDOG)
|
||||
|
||||
add_definitions(-DBOOT)
|
||||
|
||||
set(CMAKE_EXE_LINKER_FLAGS "-mcpu=${MCU} -mthumb -nostartfiles -lm -T${RADIO_SRC_DIRECTORY}/targets/${TARGET_DIR}/stm32_ramboot.ld -Wl,-Map=bootloader.map,--cref,--no-warn-mismatch,--gc-sections")
|
||||
|
|
|
@ -195,7 +195,7 @@ int main()
|
|||
FRESULT fr;
|
||||
uint32_t nameCount = 0;
|
||||
|
||||
wdt_reset();
|
||||
WDG_RESET();
|
||||
|
||||
RCC_AHB1PeriphClockCmd(PWR_RCC_AHB1Periph | KEYS_RCC_AHB1Periph |
|
||||
LCD_RCC_AHB1Periph | BACKLIGHT_RCC_AHB1Periph |
|
||||
|
@ -215,7 +215,7 @@ int main()
|
|||
#if defined(PCBHORUS)
|
||||
// wait a bit for the inputs to stabilize...
|
||||
for (uint32_t i = 0; i < 50000; i++) {
|
||||
wdt_reset();
|
||||
WDG_RESET();
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -265,12 +265,12 @@ int main()
|
|||
#if defined(PWR_BUTTON_PRESS)
|
||||
// wait until power button is released
|
||||
while (pwrPressed()) {
|
||||
wdt_reset();
|
||||
WDG_RESET();
|
||||
}
|
||||
#endif
|
||||
|
||||
for (;;) {
|
||||
wdt_reset();
|
||||
WDG_RESET();
|
||||
|
||||
if (tenms) {
|
||||
tenms = 0;
|
||||
|
@ -506,16 +506,12 @@ int main()
|
|||
lcdRefresh();
|
||||
lcdRefreshWait();
|
||||
|
||||
#if !defined(EEPROM)
|
||||
// Use jump on radios with emergency mode
|
||||
// to avoid triggering it with a soft reset
|
||||
|
||||
// Jump to proper application address
|
||||
jumpTo(APP_START_ADDRESS);
|
||||
#else
|
||||
// Use software reset everywhere else
|
||||
NVIC_SystemReset();
|
||||
#if defined(RTC_BACKUP_RAM)
|
||||
rtcInit();
|
||||
RTC->BKP0R = SOFTRESET_REQUEST;
|
||||
#endif
|
||||
|
||||
NVIC_SystemReset();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -523,5 +519,5 @@ int main()
|
|||
}
|
||||
|
||||
#if defined(PCBHORUS)
|
||||
void *__dso_handle = 0;
|
||||
void *__dso_handle = nullptr;
|
||||
#endif
|
||||
|
|
|
@ -20,6 +20,13 @@
|
|||
|
||||
#include "opentx.h"
|
||||
|
||||
void waitFlashIdle()
|
||||
{
|
||||
do {
|
||||
WDG_RESET();
|
||||
} while (FLASH->SR & FLASH_FLAG_BSY);
|
||||
}
|
||||
|
||||
//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:
|
||||
|
@ -37,21 +44,16 @@ void unlockFlash()
|
|||
|
||||
void lockFlash()
|
||||
{
|
||||
while (FLASH->SR & FLASH_SR_BSY);
|
||||
waitFlashIdle();
|
||||
FLASH->CR |= FLASH_CR_LOCK;
|
||||
}
|
||||
|
||||
void waitFlashIdle()
|
||||
{
|
||||
while (FLASH->SR & FLASH_FLAG_BSY) {
|
||||
wdt_reset();
|
||||
}
|
||||
}
|
||||
|
||||
#define SECTOR_MASK ((uint32_t)0xFFFFFF07)
|
||||
|
||||
void eraseSector(uint32_t sector)
|
||||
{
|
||||
WDG_ENABLE(3000); // some sectors may take > 1s to erase
|
||||
|
||||
waitFlashIdle();
|
||||
|
||||
FLASH->CR &= CR_PSIZE_MASK;
|
||||
|
@ -66,9 +68,11 @@ void eraseSector(uint32_t sector)
|
|||
/* if the erase operation is completed, disable the SER Bit */
|
||||
FLASH->CR &= (~FLASH_CR_SER);
|
||||
FLASH->CR &= SECTOR_MASK;
|
||||
|
||||
WDG_ENABLE(WDG_DURATION);
|
||||
}
|
||||
|
||||
void flashWrite(uint32_t * address, uint32_t * buffer) // page size is 256 bytes
|
||||
void flashWrite(uint32_t * address, const uint32_t * buffer) // page size is 256 bytes
|
||||
{
|
||||
#define SECTOR_ADDRESS (((uint32_t)address) & 0xFFFFF)
|
||||
|
||||
|
@ -110,7 +114,6 @@ void flashWrite(uint32_t * address, uint32_t * buffer) // page size is 256 bytes
|
|||
eraseSector(4 + FLASH_BANK);
|
||||
}
|
||||
else if ((((uint32_t)address) & 0x3FFF) == 0) {
|
||||
|
||||
// test other 16KB sectors
|
||||
if (SECTOR_ADDRESS == 0x04000) {
|
||||
eraseSector(1 + FLASH_BANK);
|
||||
|
@ -141,7 +144,7 @@ void flashWrite(uint32_t * address, uint32_t * buffer) // page size is 256 bytes
|
|||
|
||||
/* Wait for operation to be completed */
|
||||
waitFlashIdle();
|
||||
FLASH->CR &= (~FLASH_CR_PG);
|
||||
FLASH->CR &= ~FLASH_CR_PG;
|
||||
|
||||
/* Check the written value */
|
||||
if (*address != *buffer) {
|
||||
|
@ -192,7 +195,7 @@ uint32_t isBootloaderStart(const uint8_t * buffer)
|
|||
{
|
||||
const uint32_t * block = (const uint32_t *)buffer;
|
||||
|
||||
for (int i=0; i<256; i++) {
|
||||
for (int i = 0; i < 256; i++) {
|
||||
if (block[i] == 0x544F4F42/*BOOT*/) {
|
||||
return 1;
|
||||
}
|
||||
|
|
|
@ -59,17 +59,14 @@ void rtcGetTime(struct gtm * t)
|
|||
|
||||
void rtcInit()
|
||||
{
|
||||
RTC_InitTypeDef RTC_InitStruct;
|
||||
|
||||
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);
|
||||
PWR_BackupAccessCmd(ENABLE);
|
||||
RCC_LSEConfig(RCC_LSE_ON);
|
||||
|
||||
// Prevent lockup in case of 32kHz oscillator failure
|
||||
uint32_t i = 0;
|
||||
while(RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET)
|
||||
{
|
||||
if ( ++i > 1000000 )
|
||||
while (RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET) {
|
||||
if (++i > 1000000)
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -77,6 +74,9 @@ void rtcInit()
|
|||
RCC_RTCCLKCmd(ENABLE);
|
||||
RTC_WaitForSynchro();
|
||||
|
||||
#if !defined(BOOT)
|
||||
RTC_InitTypeDef RTC_InitStruct;
|
||||
|
||||
// RTC time base = LSE / ((AsynchPrediv+1) * (SynchPrediv+1)) = 1 Hz*/
|
||||
RTC_InitStruct.RTC_HourFormat = RTC_HourFormat_24;
|
||||
RTC_InitStruct.RTC_AsynchPrediv = 127;
|
||||
|
@ -86,8 +86,9 @@ void rtcInit()
|
|||
struct gtm utm;
|
||||
rtcGetTime(&utm);
|
||||
g_rtcTime = gmktime(&utm);
|
||||
#endif
|
||||
|
||||
#if defined(RAMBACKUP)
|
||||
#if defined(RTC_BACKUP_RAM) && !defined(BOOT)
|
||||
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_BKPSRAM, ENABLE);
|
||||
PWR_BackupRegulatorCmd(ENABLE);
|
||||
#endif
|
||||
|
|
|
@ -14,7 +14,7 @@ set(GUI_DIR 480x272)
|
|||
set(NAVIGATION_TYPE horus)
|
||||
set(TARGET_DIR horus)
|
||||
set(LINKER_SCRIPT targets/horus/stm32f4_flash.ld)
|
||||
set(RAMBACKUP YES)
|
||||
set(RTC_BACKUP_RAM YES)
|
||||
set(LUA YES)
|
||||
set(PPM_LIMITS_SYMETRICAL YES)
|
||||
set(USB_SERIAL ON CACHE BOOL "Enable USB serial (CDC)")
|
||||
|
|
|
@ -29,10 +29,6 @@ extern "C" {
|
|||
}
|
||||
#endif
|
||||
|
||||
uint32_t shutdownRequest; // Stores intentional shutdown to avoid reboot loop
|
||||
uint32_t shutdownReason; // Used for detecting unexpected reboots regardless of reason
|
||||
uint32_t powerupReason __NOINIT; // Stores power up reason beyond initialization for emergency mode activation
|
||||
|
||||
HardwareOptions hardwareOptions;
|
||||
|
||||
void watchdogInit(unsigned int duration)
|
||||
|
@ -40,7 +36,7 @@ void watchdogInit(unsigned int duration)
|
|||
IWDG->KR = 0x5555; // Unlock registers
|
||||
IWDG->PR = 3; // Divide by 32 => 1kHz clock
|
||||
IWDG->KR = 0x5555; // Unlock registers
|
||||
IWDG->RLR = duration; // 1.5 seconds nominal
|
||||
IWDG->RLR = duration;
|
||||
IWDG->KR = 0xAAAA; // reload
|
||||
IWDG->KR = 0xCCCC; // start
|
||||
}
|
||||
|
@ -173,6 +169,7 @@ void boardInit()
|
|||
#endif
|
||||
|
||||
ledInit();
|
||||
|
||||
#if defined(PCBX10) && !defined(RADIO_T16)
|
||||
sportUpdateInit();
|
||||
#endif
|
||||
|
@ -189,7 +186,7 @@ void boardOff()
|
|||
backlightEnable(0);
|
||||
|
||||
while (pwrPressed()) {
|
||||
wdt_reset();
|
||||
WDG_RESET();
|
||||
}
|
||||
|
||||
SysTick->CTRL = 0; // turn off systick
|
||||
|
@ -209,8 +206,12 @@ void boardOff()
|
|||
// Shutdown the Haptic
|
||||
hapticDone();
|
||||
|
||||
shutdownRequest = SHUTDOWN_REQUEST;
|
||||
shutdownReason = NORMAL_POWER_OFF;
|
||||
#if defined(RTC_BACKUP_RAM)
|
||||
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_BKPSRAM, DISABLE);
|
||||
PWR_BackupRegulatorCmd(DISABLE);
|
||||
#endif
|
||||
|
||||
RTC->BKP0R = SHUTDOWN_REQUEST;
|
||||
|
||||
pwrOff();
|
||||
}
|
||||
|
|
|
@ -136,7 +136,7 @@ DRESULT __disk_write(BYTE drv, const BYTE * buff, DWORD sector, UINT count);
|
|||
#define FLASH_PAGESIZE 256
|
||||
void unlockFlash();
|
||||
void lockFlash();
|
||||
void flashWrite(uint32_t * address, uint32_t * buffer);
|
||||
void flashWrite(uint32_t * address, const uint32_t * buffer);
|
||||
uint32_t isFirmwareStart(const uint8_t * buffer);
|
||||
uint32_t isBootloaderStart(const uint8_t * buffer);
|
||||
|
||||
|
@ -305,28 +305,22 @@ void rotaryEncoderInit();
|
|||
void rotaryEncoderCheck();
|
||||
|
||||
// WDT driver
|
||||
#define WDTO_500MS 500
|
||||
extern uint32_t powerupReason;
|
||||
|
||||
#define SHUTDOWN_REQUEST 0xDEADBEEF
|
||||
#define NO_SHUTDOWN_REQUEST ~SHUTDOWN_REQUEST
|
||||
#define DIRTY_SHUTDOWN 0xCAFEDEAD
|
||||
#define NORMAL_POWER_OFF ~DIRTY_SHUTDOWN
|
||||
#define WDG_DURATION 500 /*ms*/
|
||||
|
||||
void watchdogInit(unsigned int duration);
|
||||
#if defined(SIMU)
|
||||
#define WAS_RESET_BY_WATCHDOG() (false)
|
||||
#define WAS_RESET_BY_SOFTWARE() (false)
|
||||
#define WAS_RESET_BY_WATCHDOG_OR_SOFTWARE() (false)
|
||||
#define wdt_enable(x)
|
||||
#define wdt_reset()
|
||||
#define WDG_ENABLE(x)
|
||||
#define WDG_RESET()
|
||||
#else
|
||||
#if defined(WATCHDOG)
|
||||
#define wdt_enable(x) watchdogInit(x)
|
||||
#define wdt_reset() IWDG->KR = 0xAAAA
|
||||
#define WDG_ENABLE(x) watchdogInit(x)
|
||||
#define WDG_RESET() IWDG->KR = 0xAAAA
|
||||
#else
|
||||
#define wdt_enable(x)
|
||||
#define wdt_reset()
|
||||
#define WDG_ENABLE(x)
|
||||
#define WDG_RESET()
|
||||
#endif
|
||||
#define WAS_RESET_BY_WATCHDOG() (RCC->CSR & (RCC_CSR_WDGRSTF | RCC_CSR_WWDGRSTF))
|
||||
#define WAS_RESET_BY_SOFTWARE() (RCC->CSR & RCC_CSR_SFTRSTF)
|
||||
|
@ -453,14 +447,41 @@ extern volatile uint32_t pwm_interrupt_count;
|
|||
#define BATTERY_MAX 115 // 11.5V
|
||||
#endif
|
||||
|
||||
#if defined(__cplusplus)
|
||||
enum PowerReason {
|
||||
SHUTDOWN_REQUEST = 0xDEADBEEF,
|
||||
SOFTRESET_REQUEST = 0xCAFEDEAD,
|
||||
};
|
||||
|
||||
constexpr uint32_t POWER_REASON_SIGNATURE = 0x0178746F;
|
||||
|
||||
inline bool UNEXPECTED_SHUTDOWN()
|
||||
{
|
||||
#if defined(SIMU) || defined(NO_UNEXPECTED_SHUTDOWN)
|
||||
return false;
|
||||
#else
|
||||
if (WAS_RESET_BY_WATCHDOG())
|
||||
return true;
|
||||
else if (WAS_RESET_BY_SOFTWARE())
|
||||
return RTC->BKP0R != SOFTRESET_REQUEST;
|
||||
else
|
||||
return RTC->BKP1R == POWER_REASON_SIGNATURE && RTC->BKP0R != SHUTDOWN_REQUEST;
|
||||
#endif
|
||||
}
|
||||
|
||||
inline void SET_POWER_REASON(uint32_t value)
|
||||
{
|
||||
RTC->BKP0R = value;
|
||||
RTC->BKP1R = POWER_REASON_SIGNATURE;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(__cplusplus) && !defined(SIMU)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// Power driver
|
||||
#define SOFT_PWR_CTRL
|
||||
extern uint32_t shutdownRequest; // Stores intentional shutdown to avoid reboot loop
|
||||
extern uint32_t shutdownReason; // Used for detecting unexpected reboots regardless of reason
|
||||
void pwrInit();
|
||||
uint32_t pwrCheck();
|
||||
void pwrOn();
|
||||
|
@ -468,11 +489,6 @@ void pwrOff();
|
|||
void pwrResetHandler();
|
||||
bool pwrPressed();
|
||||
uint32_t pwrPressedDuration();
|
||||
#if defined(SIMU) || defined(NO_UNEXPECTED_SHUTDOWN)
|
||||
#define UNEXPECTED_SHUTDOWN() (false)
|
||||
#else
|
||||
#define UNEXPECTED_SHUTDOWN() ((powerupReason == DIRTY_SHUTDOWN) || WAS_RESET_BY_WATCHDOG_OR_SOFTWARE())
|
||||
#endif
|
||||
|
||||
// Led driver
|
||||
void ledInit();
|
||||
|
|
|
@ -2,8 +2,6 @@
|
|||
#include "../../common/arm/stm32/bootloader/boot.h"
|
||||
#include "../../common/arm/stm32/bootloader/bin_files.h"
|
||||
|
||||
#define SELECTED_COLOR (INVERS | TEXT_COLOR)
|
||||
|
||||
const uint8_t __bmp_plug_usb_rle[] {
|
||||
#include "bmp_plug_usb.lbm"
|
||||
};
|
||||
|
@ -48,7 +46,7 @@ void bootloaderInitScreen()
|
|||
|
||||
backlightEnable(BACKLIGHT_LEVEL_MAX);
|
||||
|
||||
//TODO: load/decompress bitmaps
|
||||
// TODO: load/decompress bitmaps
|
||||
loadFonts();
|
||||
}
|
||||
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
*/
|
||||
|
||||
#include "board.h"
|
||||
#include "storage/rtc_backup.h"
|
||||
|
||||
void pwrInit()
|
||||
{
|
||||
|
@ -81,9 +82,6 @@ void pwrOn()
|
|||
GPIO_Init(PWR_ON_GPIO, &GPIO_InitStructure);
|
||||
|
||||
GPIO_SetBits(PWR_ON_GPIO, PWR_ON_GPIO_PIN);
|
||||
|
||||
shutdownRequest = NO_SHUTDOWN_REQUEST;
|
||||
shutdownReason = DIRTY_SHUTDOWN;
|
||||
}
|
||||
|
||||
void pwrOff()
|
||||
|
@ -105,38 +103,7 @@ void pwrResetHandler()
|
|||
__ASM volatile ("nop");
|
||||
__ASM volatile ("nop");
|
||||
|
||||
// We get here whether we are powering up normally, we had an unexpected reboot or we have just powered down normally.
|
||||
// We want:
|
||||
// - In the 2nd case, to power ON as soon as possible if an unexpected reboot happened
|
||||
// (we get there running on remaining capacitor charge, soft power having been cut by the RESET).
|
||||
// - In the 3rd case, NOT power on as that would prevent from turning the system off.
|
||||
// - The 1st case does not need to be handled here, but will be as a result of the handling for the 3rd case, see below.
|
||||
//
|
||||
// shutdownRequest is used to handle the 3rd case. If we really powered down on purpose this will still be set to SHUTDOWN_REQUEST
|
||||
// as we left it in pwrOff(). If however we had an unexpected reboot, it would be set to NO_SHUTDOWN_REQUEST as we set it in pwrOn().
|
||||
// Any other value (e.g. resulting from data corruption) would also keep power on for safety, so this variable can NOT be used
|
||||
// to detect an unexpected reboot (on a normal power on the contents of the variable are random).
|
||||
//
|
||||
// shutdownReason is used to differentiate between an unexpected reboot and a normal power on. We set it to DIRTY_SHUTDOWN in pwrOn()
|
||||
// in anticipation of a potential reboot. Should there be one the value should be preserved and signal below that we rebooted unexpectedly.
|
||||
// If it is NOT set to DIRTY_SHUTDOWN we likely had a normal boot and its contents are random. Due to the need to initialize it to detect a
|
||||
// potential failure ASAP we cannot use it to determine in the firmware why we got there, it has to be buffered.
|
||||
//
|
||||
// powerupReason is there to cater for that, and is what is used in the firmware to decide whether we have to enter emergency mode.
|
||||
// This variable needs to be in a RAM section that is not initialized or zeroed, since once we exit this pwrResetHandler() function the
|
||||
// C runtime would otherwise overwrite it during program init.
|
||||
// Only for X12, X10 power circuit causes inability to shut down on some samples.
|
||||
|
||||
#if defined(PCBX12S)
|
||||
if (shutdownRequest != SHUTDOWN_REQUEST || WAS_RESET_BY_WATCHDOG_OR_SOFTWARE()) {
|
||||
if (shutdownReason == DIRTY_SHUTDOWN) {
|
||||
powerupReason = DIRTY_SHUTDOWN;
|
||||
}
|
||||
pwrOn();
|
||||
}
|
||||
#else
|
||||
if (WAS_RESET_BY_WATCHDOG_OR_SOFTWARE()) {
|
||||
pwrOn();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -51,6 +51,7 @@ DMA_TypeDef dma2;
|
|||
USART_TypeDef Usart0, Usart1, Usart2, Usart3, Usart4;
|
||||
SysTick_Type systick;
|
||||
ADC_Common_TypeDef adc;
|
||||
RTC_TypeDef rtc;
|
||||
#else
|
||||
Pio Pioa, Piob, Pioc;
|
||||
Pmc pmc;
|
||||
|
@ -672,7 +673,7 @@ void lockFlash()
|
|||
{
|
||||
}
|
||||
|
||||
void flashWrite(uint32_t *address, uint32_t *buffer)
|
||||
void flashWrite(uint32_t *address, const uint32_t *buffer)
|
||||
{
|
||||
simuSleep(100);
|
||||
}
|
||||
|
|
|
@ -86,6 +86,7 @@ extern DMA_Stream_TypeDef dma1_stream0, dma1_stream1, dma1_stream2, dma1_stream3
|
|||
extern DMA_TypeDef dma2;
|
||||
extern SysTick_Type systick;
|
||||
extern ADC_Common_TypeDef adc;
|
||||
extern RTC_TypeDef rtc;
|
||||
#undef SysTick
|
||||
#define SysTick (&systick)
|
||||
#undef GPIOA
|
||||
|
@ -166,6 +167,8 @@ extern ADC_Common_TypeDef adc;
|
|||
#define DMA2 (&dma2)
|
||||
#undef ADC
|
||||
#define ADC (&adc)
|
||||
#undef RTC
|
||||
#define RTC (&rtc)
|
||||
#elif defined(PCBSKY9X)
|
||||
extern Pmc pmc;
|
||||
#undef PMC
|
||||
|
|
|
@ -218,7 +218,7 @@ void stop_trainer_capture();
|
|||
|
||||
// Write Flash driver
|
||||
#define FLASH_PAGESIZE 256
|
||||
void flashWrite(uint32_t * address, uint32_t * buffer);
|
||||
void flashWrite(uint32_t * address, const uint32_t * buffer);
|
||||
|
||||
// Keys driver
|
||||
uint32_t switchState(uint8_t index);
|
||||
|
@ -259,12 +259,12 @@ extern "C" {
|
|||
|
||||
// WDT driver
|
||||
#if !defined(WATCHDOG) || defined(SIMU)
|
||||
#define wdt_enable(x)
|
||||
#define wdt_reset()
|
||||
#define WDG_ENABLE(x)
|
||||
#define WDG_RESET()
|
||||
#define IS_RESET_REASON_WATCHDOG() false
|
||||
#else
|
||||
#define wdt_enable(x) WDT->WDT_MR = 0x3FFF207F
|
||||
#define wdt_reset() WDT->WDT_CR = 0xA5000001
|
||||
#define WDG_ENABLE(x) WDT->WDT_MR = 0x3FFF207F
|
||||
#define WDG_RESET() WDT->WDT_CR = 0xA5000001
|
||||
#define IS_RESET_REASON_WATCHDOG() ((ResetReason & RSTC_SR_RSTTYP) == (2 << 8))
|
||||
#endif
|
||||
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
|
||||
uint32_t (*IAP_Function)(uint32_t, uint32_t);
|
||||
|
||||
void flashWrite(uint32_t *address, uint32_t *buffer) // size is 256 bytes
|
||||
void flashWrite(uint32_t * address, const uint32_t * buffer) // size is 256 bytes
|
||||
{
|
||||
uint32_t FlashSectorNum;
|
||||
uint32_t flash_cmd = 0;
|
||||
|
|
|
@ -120,7 +120,7 @@ void lcdInit()
|
|||
TC0->TC_CHANNEL[0].TC_CCR = 5; // Enable clock and trigger it (may only need trigger)
|
||||
while ( TC0->TC_CHANNEL[0].TC_CV < 36000 ) {
|
||||
// Value depends on MCK/2 (used 18MHz) give 2mS delay
|
||||
wdt_reset(); // Wait
|
||||
WDG_RESET(); // Wait
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -36,7 +36,7 @@ void watchdogInit(unsigned int duration)
|
|||
IWDG->KR = 0x5555; // Unlock registers
|
||||
IWDG->PR = 3; // Divide by 32 => 1kHz clock
|
||||
IWDG->KR = 0x5555; // Unlock registers
|
||||
IWDG->RLR = duration; // 1.5 seconds nominal
|
||||
IWDG->RLR = duration;
|
||||
IWDG->KR = 0xAAAA; // reload
|
||||
IWDG->KR = 0xCCCC; // start
|
||||
}
|
||||
|
@ -222,7 +222,7 @@ void boardOff()
|
|||
|
||||
#if defined(PWR_BUTTON_PRESS)
|
||||
while (pwrPressed()) {
|
||||
wdt_reset();
|
||||
WDG_RESET();
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -234,7 +234,7 @@ void boardOff()
|
|||
__disable_irq();
|
||||
|
||||
while (1) {
|
||||
wdt_reset();
|
||||
WDG_RESET();
|
||||
#if defined(PWR_BUTTON_PRESS)
|
||||
// X9E/X7 needs watchdog reset because CPU is still running while
|
||||
// the power key is held pressed by the user.
|
||||
|
|
|
@ -95,7 +95,7 @@ uint32_t sdMounted();
|
|||
#define FLASH_PAGESIZE 256
|
||||
void unlockFlash();
|
||||
void lockFlash();
|
||||
void flashWrite(uint32_t * address, uint32_t * buffer);
|
||||
void flashWrite(uint32_t * address, const uint32_t * buffer);
|
||||
uint32_t isFirmwareStart(const uint8_t * buffer);
|
||||
uint32_t isBootloaderStart(const uint8_t * buffer);
|
||||
|
||||
|
@ -441,13 +441,13 @@ uint32_t readTrims();
|
|||
#define KEYS_PRESSED() (readKeys())
|
||||
|
||||
// WDT driver
|
||||
#define WDTO_500MS 500
|
||||
#define WDG_DURATION 500 /*ms*/
|
||||
#if !defined(WATCHDOG) || defined(SIMU)
|
||||
#define wdt_enable(x)
|
||||
#define wdt_reset()
|
||||
#define WDG_ENABLE(x)
|
||||
#define WDG_RESET()
|
||||
#else
|
||||
#define wdt_enable(x) watchdogInit(x)
|
||||
#define wdt_reset() IWDG->KR = 0xAAAA
|
||||
#define WDG_ENABLE(x) watchdogInit(x)
|
||||
#define WDG_RESET() IWDG->KR = 0xAAAA
|
||||
#endif
|
||||
void watchdogInit(unsigned int duration);
|
||||
#define WAS_RESET_BY_SOFTWARE() (RCC->CSR & RCC_CSR_SFTRSTF)
|
||||
|
|
|
@ -189,7 +189,7 @@ TASK_FUNCTION(mixerTask)
|
|||
DEBUG_TIMER_STOP(debugTimerTelemetryWakeup);
|
||||
|
||||
if (heartbeat == HEART_WDT_CHECK) {
|
||||
wdt_reset();
|
||||
WDG_RESET();
|
||||
heartbeat = 0;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue