174 lines
3.7 KiB
C++
174 lines
3.7 KiB
C++
/*
|
|
* Copyright (C) EdgeTX
|
|
*
|
|
* Based on code named
|
|
* opentx - https://github.com/opentx/opentx
|
|
* 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.
|
|
*/
|
|
|
|
#include "boot.h"
|
|
|
|
#include "hal/usb_driver.h"
|
|
#include "hal/abnormal_reboot.h"
|
|
#include "hal/rotary_encoder.h"
|
|
|
|
#include "board.h"
|
|
#include "debug.h"
|
|
|
|
#include "timers_driver.h"
|
|
|
|
#if defined(BLUETOOTH)
|
|
#include "bluetooth_driver.h"
|
|
#include "stm32_serial_driver.h"
|
|
#endif
|
|
|
|
#if defined(DEBUG_SEGGER_RTT)
|
|
#include "thirdparty/Segger_RTT/RTT/SEGGER_RTT.h"
|
|
#endif
|
|
|
|
#define REBOOT_CMD_DFU 0x55464442
|
|
|
|
#if !defined(SIMU)
|
|
// Bootloader marker:
|
|
// -> used to detect valid bootloader files
|
|
const uint8_t bootloaderVersion[] __attribute__ ((section(".version"), used)) =
|
|
{'B', 'O', 'O', 'T', '1', '0'};
|
|
#endif
|
|
|
|
#if defined(SIMU)
|
|
#define __weak
|
|
#elif !defined(__weak)
|
|
#define __weak __attribute__((weak))
|
|
#endif
|
|
|
|
#if !defined(SIMU)
|
|
|
|
typedef void (*fctptr_t)(void);
|
|
|
|
static __attribute__((noreturn)) void jumpTo(uint32_t addr)
|
|
{
|
|
__disable_irq();
|
|
__set_MSP(*(uint32_t*)addr);
|
|
fctptr_t reset_handler = (fctptr_t)*(uint32_t*)(addr + 4);
|
|
reset_handler();
|
|
while(1){}
|
|
}
|
|
|
|
// Optional board hook
|
|
__weak void boardBLEarlyInit() {}
|
|
__weak bool boardBLStartCondition() { return false; }
|
|
__weak void boardBLPreJump() {}
|
|
__weak void boardBLInit() {}
|
|
|
|
void bootloaderInitApp()
|
|
{
|
|
boardBLEarlyInit();
|
|
|
|
#if defined(DEBUG_SEGGER_RTT)
|
|
SEGGER_RTT_ConfigUpBuffer(0, NULL, NULL, 0, SEGGER_RTT_MODE_NO_BLOCK_SKIP);
|
|
#endif
|
|
|
|
pwrInit();
|
|
keysInit();
|
|
delaysInit();
|
|
|
|
bool boot_dfu = abnormalRebootGetCmd() == REBOOT_CMD_DFU;
|
|
if (!boot_dfu) {
|
|
bool start_firmware = true;
|
|
|
|
// wait a bit for the inputs to stabilize...
|
|
if (!WAS_RESET_BY_WATCHDOG_OR_SOFTWARE()) {
|
|
delay_ms(10);
|
|
}
|
|
|
|
start_firmware = !boardBLStartCondition();
|
|
if (start_firmware) {
|
|
// Start main application
|
|
boardBLPreJump();
|
|
jumpTo(APP_START_ADDRESS);
|
|
}
|
|
} else {
|
|
#if defined(FIRMWARE_QSPI)
|
|
abnormalRebootResetCmd();
|
|
setSelectedUsbMode(USB_DFU_MODE);
|
|
#endif
|
|
}
|
|
|
|
// TODO: move all this into board specifics
|
|
pwrOn();
|
|
|
|
#if defined(ROTARY_ENCODER_NAVIGATION) && !defined(USE_HATS_AS_KEYS)
|
|
rotaryEncoderInit();
|
|
#endif
|
|
|
|
#if defined(DEBUG)
|
|
initSerialPorts();
|
|
#endif
|
|
|
|
__enable_irq();
|
|
|
|
TRACE("\nBootloader started :)");
|
|
|
|
// TODO: move BT into board specifics
|
|
#if defined(BLUETOOTH)
|
|
// we shutdown the bluetooth module now to be sure it will be detected on
|
|
// firmware start
|
|
bluetoothInit(BLUETOOTH_DEFAULT_BAUDRATE, false);
|
|
#endif
|
|
|
|
timersInit();
|
|
|
|
usbInit();
|
|
boardBLInit();
|
|
}
|
|
|
|
#if defined(FIRMWARE_FORMAT_UF2)
|
|
// make linker happy
|
|
void per5ms() {}
|
|
#endif
|
|
|
|
int main()
|
|
#else // SIMU
|
|
void bootloaderInitApp() {}
|
|
int bootloaderMain()
|
|
#endif
|
|
{
|
|
// init hardware (may jump to app)
|
|
bootloaderInitApp();
|
|
|
|
// init screen
|
|
bootloaderInitScreen();
|
|
|
|
#if defined(FIRMWARE_FORMAT_UF2)
|
|
if (getSelectedUsbMode() == USB_DFU_MODE) {
|
|
bootloaderDFU();
|
|
}
|
|
#endif
|
|
|
|
#if defined(PWR_BUTTON_PRESS)
|
|
// wait until power button is released
|
|
while (pwrPressed()) {}
|
|
#endif
|
|
|
|
#if !defined(FIRMWARE_FORMAT_UF2)
|
|
bootloaderMenu();
|
|
#else
|
|
bootloaderUF2();
|
|
#endif
|
|
|
|
return 0;
|
|
}
|