Refactoring of startup code, mainly dealing with detection of unexpec… (#4275)

* Refactoring of startup code, mainly dealing with detection of unexpected restart/shutdown

* Added g_FATFS_Obj initialization [Horus]

* Fix normal startup

* Use g_eeGeneral.unexpectedShutdown only on radios that have PWRMANAGE defined
Fixes for radios that don't have power control.
Other fixes

* CLI test for new()

* [Horus] Reboot protection reworked to also handle non-WDT events

(cherry picked from commit fe9a52779d062e3f24639479273c906abe6e440b)

Conflicts:
	radio/src/targets/horus/board.h

* Reverting most of the changes

* Cleanup

* Added comment that explains apparent non usage of the wdt_disable() function

* More cleanup

* Missing include

* Compilation fix
This commit is contained in:
Damjan Adamic
2017-01-24 07:52:33 +01:00
committed by Bertrand Songis
parent bf15410bf1
commit b3f4870da7
9 changed files with 651 additions and 525 deletions
+59 -1
View File
@@ -22,6 +22,7 @@
#include "diskio.h"
#include <ctype.h>
#include <malloc.h>
#include <new>
#define CLI_COMMAND_MAX_ARGS 8
#define CLI_COMMAND_MAX_LEN 256
@@ -302,6 +303,62 @@ int cliTestSD(const char ** argv)
return 0;
}
int cliTestNew()
{
char * tmp = 0;
serialPrint("Allocating 1kB with new()");
CoTickDelay(100);
tmp = new char[1024];
if (tmp) {
serialPrint("\tsuccess");
delete[] tmp;
tmp = 0;
}
else {
serialPrint("\tFAILURE");
}
serialPrint("Allocating 10MB with (std::nothrow) new()");
CoTickDelay(100);
tmp = new (std::nothrow) char[1024*1024*10];
if (tmp) {
serialPrint("\tFAILURE, tmp = %p", tmp);
delete[] tmp;
tmp = 0;
}
else {
serialPrint("\tsuccess, allocaton failed, tmp = 0");
}
serialPrint("Allocating 10MB with new()");
CoTickDelay(100);
tmp = new char[1024*1024*10];
if (tmp) {
serialPrint("\tFAILURE, tmp = %p", tmp);
delete[] tmp;
tmp = 0;
}
else {
serialPrint("\tsuccess, allocaton failed, tmp = 0");
}
serialPrint("Test finished");
return 0;
}
int cliTest(const char ** argv)
{
if (!strcmp(argv[1], "new")) {
return cliTestNew();
}
else if (!strcmp(argv[1], "std::exception")) {
serialPrint("Not implemented");
}
else {
serialPrint("%s: Invalid argument \"%s\"", argv[0], argv[1]);
}
return 0;
}
int cliTrace(const char ** argv)
{
if (!strcmp(argv[1], "on")) {
@@ -509,7 +566,7 @@ void printTaskSwitchLog()
uint32_t * tsl = new uint32_t[DEBUG_TASKS_LOG_SIZE];
if (!tsl) {
serialPrint("Not enough memory");
return 0;
return;
}
memcpy(tsl, taskSwitchLog, sizeof(taskSwitchLog));
uint32_t * p = tsl + taskSwitchLogPos;
@@ -892,6 +949,7 @@ const CliCommand cliCommands[] = {
{ "set", cliSet, "<what> <value>" },
{ "stackinfo", cliStackInfo, "" },
{ "meminfo", cliMemoryInfo, "" },
{ "test", cliTest, "new | std::exception" },
{ "trace", cliTrace, "on | off" },
#if defined(PCBFLAMENCO)
{ "read_bq24195", cliReadBQ24195, "<register>" },
+6
View File
@@ -41,6 +41,12 @@
#define __SDRAM __DMA
#endif
#if defined(PCBHORUS) && !defined(SIMU)
#define __NOINIT __attribute__((section(".noinit")))
#else
#define __NOINIT
#endif
#if defined(SIMU) || defined(CPUARM) || GCC_VERSION < 472
typedef int32_t int24_t;
#else
+29 -10
View File
@@ -2438,29 +2438,47 @@ void opentxInit(OPENTX_INIT_ARGS)
#if defined(RTCLOCK) && !defined(COPROCESSOR)
rtcInit(); // RTC must be initialized before rambackupRestore() is called
#endif
#if defined(EEPROM)
storageReadAll();
#endif
// Radios handle UNEXPECTED_SHUTDOWN() differently:
// * radios with WDT and EEPROM and CPU controlled power use Reset status register
// and eeGeneral.unexpectedShutdown
// * radios with SDCARD model storage use Reset status register and special
// variables in RAM. They can not use eeGeneral.unexpectedShutdown
// * radios without CPU controlled power can only use Reset status register (if available)
if (UNEXPECTED_SHUTDOWN()) {
TRACE("Unexpected Shutdown detected");
unexpectedShutdown = 1;
}
else {
#if defined(SDCARD) && !defined(PCBMEGA2560)
// SDCARD related stuff, only done if not unexpectedShutdown
if (!unexpectedShutdown) {
sdInit();
logsInit();
}
#endif
}
#if defined(PCBHORUS)
topbar = new Topbar(&g_model.topbarData);
LUA_INIT_THEMES_AND_WIDGETS();
if (!unexpectedShutdown) {
// g_model.topbarData is still zero here (because it was not yet read from SDCARD),
// but we only remember the pointer to in in constructor.
// The storageReadAll() needs topbar object, so it must be created here
topbar = new Topbar(&g_model.topbarData);
// lua widget state must also be prepared before the call to storageReadAll()
LUA_INIT_THEMES_AND_WIDGETS();
}
#endif
// handling of storage for radios that have no EEPROM
#if !defined(EEPROM)
#if defined(RAMBACKUP)
if (UNEXPECTED_SHUTDOWN()) {
if (unexpectedShutdown) {
// SDCARD not available, try to restore last model from RAM
TRACE("rambackupRestore");
rambackupRestore();
}
else {
@@ -2469,7 +2487,7 @@ void opentxInit(OPENTX_INIT_ARGS)
#else
storageReadAll();
#endif
#endif
#endif // #if !defined(EEPROM)
#if defined(SERIAL2)
serial2Init(g_eeGeneral.serial2Mode, MODEL_TELEMETRY_PROTOCOL());
@@ -2515,11 +2533,12 @@ void opentxInit(OPENTX_INIT_ARGS)
if (g_eeGeneral.backlightMode != e_backlight_mode_off) backlightOn(); // on Tx start turn the light on
if (!UNEXPECTED_SHUTDOWN()) {
if (!unexpectedShutdown) {
opentxStart();
}
#if defined(CPUARM) || defined(CPUM2560)
// TODO Horus does not need this
if (!g_eeGeneral.unexpectedShutdown) {
g_eeGeneral.unexpectedShutdown = 1;
storageDirty(EE_GENERAL);
@@ -2667,7 +2686,7 @@ int main()
drawSleepBitmap();
opentxClose();
boardOff(); // Only turn power off if necessary
wdt_disable();
wdt_disable(); // this function is provided by AVR Libc
while(1); // never return from main() - there is no code to return back, if any delays occurs in physical power it does dead loop.
#endif
+30 -45
View File
@@ -2,7 +2,7 @@
* Copyright (C) OpenTX
*
* Based on code named
* th9x - http://code.google.com/p/th9x
* th9x - http://code.google.com/p/th9x
* er9x - http://code.google.com/p/er9x
* gruvin9x - http://code.google.com/p/gruvin9x
*
@@ -37,7 +37,7 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include "debug.h"
/*----------------------------------------------------------------------------
* Exported variables
*----------------------------------------------------------------------------*/
@@ -50,11 +50,12 @@ extern int _heap_end;
/*----------------------------------------------------------------------------
* Exported functions
*----------------------------------------------------------------------------*/
extern void _exit( int status ) ;
extern void _kill( int pid, int sig ) ;
extern int _getpid ( void ) ;
// extern void _exit( int status ) ;
// extern void _kill( int pid, int sig ) ;
// extern int _getpid ( void ) ;
unsigned char * heap = (unsigned char *)&_end;
extern caddr_t _sbrk(int nbytes)
{
if (heap + nbytes < (unsigned char *)&_heap_end) {
@@ -70,84 +71,68 @@ extern caddr_t _sbrk(int nbytes)
extern int _gettimeofday(void *p1, void *p2)
{
return 0 ;
return 0;
}
extern int _link( char *old, char *nw )
extern int _link(char *old, char *nw)
{
return -1 ;
return -1;
}
extern int _unlink (const char *path)
extern int _unlink(const char *path)
{
return -1 ;
return -1;
}
extern int _open(const char *name, int flags, int mode)
{
return -1 ;
return -1;
}
extern int _close( int file )
extern int _close(int file)
{
return -1 ;
return -1;
}
extern int _fstat( int file, struct stat *st )
extern int _fstat(int file, struct stat * st)
{
st->st_mode = S_IFCHR ;
return 0 ;
st->st_mode = S_IFCHR ;
return 0;
}
extern int _isatty( int file )
extern int _isatty(int file)
{
return 1 ;
return 1;
}
extern int _lseek( int file, int ptr, int dir )
extern int _lseek(int file, int ptr, int dir)
{
return 0 ;
return 0;
}
extern int _read(int file, char *ptr, int len)
{
return 0 ;
return 0;
}
extern int _write( int file, char *ptr, int len )
extern int _write(int file, char *ptr, int len)
{
int iIndex ;
// for ( ; *ptr != 0 ; ptr++ )
for ( iIndex=0 ; iIndex < len ; iIndex++, ptr++ )
{
// TODO UART_PutChar( *ptr ) ;
}
return iIndex ;
return 0;
}
extern void _exit( int status )
extern void _exit(int status)
{
#if defined(SIMU)
printf( "Exiting with status %d.\n", status ) ;
#endif
for ( ; ; ) ;
TRACE("_exit(%d)", status);
for (;;);
}
extern void _kill( int pid, int sig )
extern void _kill(int pid, int sig)
{
return ;
return ;
}
extern int _getpid ( void )
extern int _getpid()
{
return -1 ;
}
//void _init (void)
//{
//}
+5
View File
@@ -156,6 +156,11 @@ void boardInit()
__enable_irq();
TRACE("\nHorus board started :)");
TRACE("RCC->CSR = %08x", RCC->CSR);
// we need to initialize g_FATFS_Obj here, because it is in .ram section (because of DMA access)
// and this section is un-initialized
memset(&g_FATFS_Obj, 0, sizeof(g_FATFS_Obj));
keysInit();
adcInit();
+481 -462
View File
@@ -1,462 +1,481 @@
/*
* 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 _BOARD_HORUS_H_
#define _BOARD_HORUS_H_
#include "stddef.h"
#if defined(__cplusplus) && !defined(SIMU)
extern "C" {
#endif
#if __clang__
// clang is very picky about the use of "register"
// Tell clang to ignore the warnings for the following files
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-register"
#endif
#include "STM32F4xx_DSP_StdPeriph_Lib_V1.4.0/Libraries/CMSIS/Device/ST/STM32F4xx/Include/stm32f4xx.h"
#include "STM32F4xx_DSP_StdPeriph_Lib_V1.4.0/Libraries/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_rcc.h"
#include "STM32F4xx_DSP_StdPeriph_Lib_V1.4.0/Libraries/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_gpio.h"
#include "STM32F4xx_DSP_StdPeriph_Lib_V1.4.0/Libraries/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_spi.h"
#include "STM32F4xx_DSP_StdPeriph_Lib_V1.4.0/Libraries/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_i2c.h"
#include "STM32F4xx_DSP_StdPeriph_Lib_V1.4.0/Libraries/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_rtc.h"
#include "STM32F4xx_DSP_StdPeriph_Lib_V1.4.0/Libraries/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_pwr.h"
#include "STM32F4xx_DSP_StdPeriph_Lib_V1.4.0/Libraries/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_dma.h"
#include "STM32F4xx_DSP_StdPeriph_Lib_V1.4.0/Libraries/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_usart.h"
#include "STM32F4xx_DSP_StdPeriph_Lib_V1.4.0/Libraries/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_flash.h"
#include "STM32F4xx_DSP_StdPeriph_Lib_V1.4.0/Libraries/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_sdio.h"
#include "STM32F4xx_DSP_StdPeriph_Lib_V1.4.0/Libraries/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_dbgmcu.h"
#include "STM32F4xx_DSP_StdPeriph_Lib_V1.4.0/Libraries/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_ltdc.h"
#include "STM32F4xx_DSP_StdPeriph_Lib_V1.4.0/Libraries/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_fmc.h"
#include "STM32F4xx_DSP_StdPeriph_Lib_V1.4.0/Libraries/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_tim.h"
#include "STM32F4xx_DSP_StdPeriph_Lib_V1.4.0/Libraries/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_dma2d.h"
#include "STM32F4xx_DSP_StdPeriph_Lib_V1.4.0/Libraries/STM32F4xx_StdPeriph_Driver/inc/misc.h"
#if __clang__
// Restore warnings about registers
#pragma clang diagnostic pop
#endif
#if !defined(SIMU)
#include "usbd_cdc_core.h"
#include "usbd_msc_core.h"
#include "usbd_hid_core.h"
#include "usbd_usr.h"
#include "usbd_desc.h"
#include "usb_conf.h"
#include "usbd_conf.h"
#endif
#include "hal.h"
#if defined(__cplusplus) && !defined(SIMU)
}
#endif
#define FLASHSIZE 0x80000
#define BOOTLOADER_SIZE 0x8000
#define FIRMWARE_ADDRESS 0x08000000
// HSI is at 168Mhz (over-drive is not enabled!)
#define PERI1_FREQUENCY 42000000
#define PERI2_FREQUENCY 84000000
#define TIMER_MULT_APB1 2
#define TIMER_MULT_APB2 2
#define strcpy_P strcpy
#define strcat_P strcat
extern uint16_t sessionTimer;
#define SLAVE_MODE() (g_model.trainerMode == TRAINER_MODE_SLAVE)
#define TRAINER_CONNECTED() (GPIO_ReadInputDataBit(TRAINER_DETECT_GPIO, TRAINER_DETECT_GPIO_PIN) == Bit_RESET)
// Board driver
void boardInit(void);
void boardOff(void);
// Delays driver
#ifdef __cplusplus
extern "C" {
#endif
void delaysInit(void);
void delay_01us(uint16_t nb);
void delay_us(uint16_t nb);
void delay_ms(uint32_t ms);
#ifdef __cplusplus
}
#endif
// PCBREV driver
#define IS_HORUS_PROD() GPIO_ReadInputDataBit(PCBREV_GPIO, PCBREV_GPIO_PIN)
#if defined(SIMU)
#define IS_FIRMWARE_COMPATIBLE_WITH_BOARD() true
#elif PCBREV >= 13
#define IS_FIRMWARE_COMPATIBLE_WITH_BOARD() IS_HORUS_PROD()
#else
#define IS_FIRMWARE_COMPATIBLE_WITH_BOARD() (!IS_HORUS_PROD())
#endif
// CPU Unique ID
#define LEN_CPU_UID (3*8+2)
void getCPUUniqueID(char * s);
// SD driver
#define BLOCK_SIZE 512 /* Block Size in Bytes */
#if !defined(SIMU) || defined(SIMU_DISKIO)
uint32_t sdIsHC(void);
uint32_t sdGetSpeed(void);
#define SD_IS_HC() (sdIsHC())
#define SD_GET_SPEED() (sdGetSpeed())
#define SD_GET_FREE_BLOCKNR() (sdGetFreeSectors())
#define SD_CARD_PRESENT() (~SD_PRESENT_GPIO->IDR & SD_PRESENT_GPIO_PIN)
void sdInit(void);
void sdMount(void);
void sdDone(void);
#define sdPoll10ms()
uint32_t sdMounted(void);
#else
#define SD_IS_HC() (0)
#define SD_GET_SPEED() (0)
#define sdInit()
#define sdMount()
#define sdDone()
#define SD_CARD_PRESENT() true
#endif
#if defined(DISK_CACHE)
#include "diskio.h"
DRESULT __disk_read(BYTE drv, BYTE * buff, DWORD sector, UINT count);
DRESULT __disk_write(BYTE drv, const BYTE * buff, DWORD sector, UINT count);
#else
#define __disk_read disk_read
#define __disk_write disk_write
#endif
// Flash Write driver
#define FLASH_PAGESIZE 256
void unlockFlash(void);
void lockFlash(void);
void flashWrite(uint32_t * address, uint32_t * buffer);
uint32_t isFirmwareStart(const uint8_t * buffer);
uint32_t isBootloaderStart(const uint8_t * buffer);
// SDRAM driver
void SDRAM_Init(void);
// Pulses driver
#define INTERNAL_MODULE_ON() GPIO_SetBits(INTMODULE_PWR_GPIO, INTMODULE_PWR_GPIO_PIN)
#define INTERNAL_MODULE_OFF() GPIO_ResetBits(INTMODULE_PWR_GPIO, INTMODULE_PWR_GPIO_PIN)
#define EXTERNAL_MODULE_ON() GPIO_SetBits(EXTMODULE_PWR_GPIO, EXTMODULE_PWR_GPIO_PIN)
#define EXTERNAL_MODULE_OFF() GPIO_ResetBits(EXTMODULE_PWR_GPIO, EXTMODULE_PWR_GPIO_PIN)
#define IS_INTERNAL_MODULE_ON() (GPIO_ReadInputDataBit(INTMODULE_PWR_GPIO, INTMODULE_PWR_GPIO_PIN) == Bit_SET)
#define IS_EXTERNAL_MODULE_ON() (GPIO_ReadInputDataBit(EXTMODULE_PWR_GPIO, EXTMODULE_PWR_GPIO_PIN) == Bit_SET)
#define IS_UART_MODULE(port) (port == INTERNAL_MODULE)
void init_no_pulses(uint32_t port);
void disable_no_pulses(uint32_t port);
void init_ppm(uint32_t module_index);
void disable_ppm(uint32_t module_index);
void init_pxx(uint32_t module_index);
void disable_pxx(uint32_t module_index);
void init_dsm2(uint32_t module_index);
void disable_dsm2(uint32_t module_index);
void init_crossfire(uint32_t module_index);
void disable_crossfire(uint32_t module_index);
// Trainer driver
void init_trainer_ppm(void);
void stop_trainer_ppm(void);
void init_trainer_capture(void);
void stop_trainer_capture(void);
// Keys driver
enum EnumKeys
{
KEY_PGUP,
KEY_PGDN,
KEY_ENTER,
KEY_MODEL,
KEY_UP = KEY_MODEL,
KEY_EXIT,
KEY_DOWN = KEY_EXIT,
KEY_TELEM,
KEY_RIGHT = KEY_TELEM,
KEY_RADIO,
KEY_LEFT = KEY_RADIO,
TRM_BASE,
TRM_LH_DWN = TRM_BASE,
TRM_LH_UP,
TRM_LV_DWN,
TRM_LV_UP,
TRM_RV_DWN,
TRM_RV_UP,
TRM_RH_DWN,
TRM_RH_UP,
TRM_LS_DWN,
TRM_LS_UP,
TRM_RS_DWN,
TRM_RS_UP,
TRM_LAST = TRM_RS_UP,
NUM_KEYS
};
enum EnumSwitches
{
SW_SA,
SW_SB,
SW_SC,
SW_SD,
SW_SE,
SW_SF,
SW_SG,
SW_SH,
NUM_SWITCHES
};
#define IS_3POS(x) ((x) != SW_SF && (x) != SW_SH)
enum EnumSwitchesPositions
{
SW_SA0,
SW_SA1,
SW_SA2,
SW_SB0,
SW_SB1,
SW_SB2,
SW_SC0,
SW_SC1,
SW_SC2,
SW_SD0,
SW_SD1,
SW_SD2,
SW_SE0,
SW_SE1,
SW_SE2,
SW_SF0,
SW_SF1,
SW_SF2,
SW_SG0,
SW_SG1,
SW_SG2,
SW_SH0,
SW_SH1,
SW_SH2,
};
void keysInit(void);
uint8_t keyState(uint8_t index);
uint32_t switchState(uint8_t index);
uint32_t readKeys(void);
uint32_t readTrims(void);
#define TRIMS_PRESSED() (readTrims())
#define KEYS_PRESSED() (readKeys())
#define DBLKEYS_PRESSED_RGT_LFT(in) ((in & ((1<<KEY_RIGHT) + (1<<KEY_LEFT))) == ((1<<KEY_RIGHT) + (1<<KEY_LEFT)))
#define DBLKEYS_PRESSED_UP_DWN(in) ((in & ((1<<KEY_UP) + (1<<KEY_DOWN))) == ((1<<KEY_UP) + (1<<KEY_DOWN)))
#define DBLKEYS_PRESSED_RGT_UP(in) ((in & ((1<<KEY_RIGHT) + (1<<KEY_UP))) == ((1<<KEY_RIGHT) + (1<<KEY_UP)))
#define DBLKEYS_PRESSED_LFT_DWN(in) ((in & ((1<<KEY_LEFT) + (1<<KEY_DOWN))) == ((1<<KEY_LEFT) + (1<<KEY_DOWN)))
// Rotary encoder driver
#define ROTARY_ENCODER_NAVIGATION
void checkRotaryEncoder(void);
// WDT driver
#define WDTO_500MS 500
#define wdt_disable()
void watchdogInit(unsigned int duration);
#if defined(WATCHDOG_DISABLED) || defined(SIMU)
#define wdt_enable(x)
#define wdt_reset()
#else
#define wdt_enable(x) watchdogInit(x)
#define wdt_reset() IWDG->KR = 0xAAAA
#endif
#define WAS_RESET_BY_WATCHDOG() (RCC->CSR & (RCC_CSR_WDGRSTF | RCC_CSR_WWDGRSTF))
#define WAS_RESET_BY_SOFTWARE() (RCC->CSR & RCC_CSR_SFTRSTF)
#define WAS_RESET_BY_WATCHDOG_OR_SOFTWARE() (RCC->CSR & (RCC_CSR_WDGRSTF | RCC_CSR_WWDGRSTF | RCC_CSR_SFTRSTF))
// ADC driver
#define NUM_POTS 3
#define NUM_SLIDERS 4
#define NUM_XPOTS 3
enum Analogs {
STICK1,
STICK2,
STICK3,
STICK4,
POT_FIRST,
POT1 = POT_FIRST,
POT2,
POT3,
POT_LAST = POT3,
SLIDER1,
SLIDER2,
SLIDER3,
SLIDER4,
TX_VOLTAGE,
MOUSE1,
MOUSE2,
NUMBER_ANALOG
};
#define IS_POT(x) ((x)>=POT_FIRST && (x)<=POT_LAST)
#define IS_SLIDER(x) ((x)>=SLIDER1 && (x)<=SLIDER4)
extern uint16_t adcValues[NUMBER_ANALOG];
void adcInit(void);
void adcRead(void);
uint16_t getAnalogValue(uint8_t index);
uint16_t getBatteryVoltage(); // returns current battery voltage in 10mV steps
#if defined(__cplusplus) && !defined(SIMU)
extern "C" {
#endif
// Power driver
void pwrInit(void);
uint32_t pwrCheck(void);
void pwrOn(void);
void pwrOff(void);
void pwrResetHandler(void);
uint32_t pwrPressed(void);
uint32_t pwrPressedDuration(void);
#define pwroffPressed() pwrPressed()
#define UNEXPECTED_SHUTDOWN() (WAS_RESET_BY_WATCHDOG() || g_eeGeneral.unexpectedShutdown)
// Led driver
void ledOff(void);
void ledRed(void);
void ledBlue(void);
// LCD driver
#define LCD_W 480
#define LCD_H 272
#define LCD_DEPTH 16
void lcdInit(void);
void lcdRefresh(void);
void DMAFillRect(uint16_t * dest, uint16_t destw, uint16_t x, uint16_t y, uint16_t w, uint16_t h, uint16_t color);
void DMACopyBitmap(uint16_t * dest, uint16_t destw, uint16_t x, uint16_t y, const uint16_t * src, uint16_t srcw, uint16_t srcx, uint16_t srcy, uint16_t w, uint16_t h);
void DMACopyAlphaBitmap(uint16_t * dest, uint16_t destw, uint16_t x, uint16_t y, const uint16_t * src, uint16_t srcw, uint16_t srcx, uint16_t srcy, uint16_t w, uint16_t h);
void DMABitmapConvert(uint16_t * dest, const uint8_t * src, uint16_t w, uint16_t h, uint32_t format);
void lcdStoreBackupBuffer(void);
int lcdRestoreBackupBuffer(void);
void lcdSetContrast();
#define lcdOff(...)
#define lcdSetRefVolt(...)
#define lcdRefreshWait(...)
// Backlight driver
void backlightInit(void);
#if defined(SIMU)
#define backlightEnable(...)
#else
void backlightEnable(uint8_t dutyCycle);
#endif
#define BACKLIGHT_ENABLE() backlightEnable(unexpectedShutdown ? 100 : 100-g_eeGeneral.backlightBright)
#define BACKLIGHT_DISABLE() backlightEnable(unexpectedShutdown ? 100 : g_eeGeneral.blOffBright)
#define isBacklightEnabled() true
// USB driver
int usbPlugged(void);
void usbInit(void);
void usbStart(void);
void usbStop(void);
void usbSerialPutc(uint8_t c);
#define USB_NAME "FrSky Horus"
#define USB_MANUFACTURER 'F', 'r', 'S', 'k', 'y', ' ', ' ', ' ' /* 8 bytes */
#define USB_PRODUCT 'H', 'o', 'r', 'u', 's', ' ', ' ', ' ' /* 8 Bytes */
#if defined(__cplusplus) && !defined(SIMU)
}
#endif
// Audio driver
void audioInit(void);
void audioConsumeCurrentBuffer(void);
#define audioDisableIrq() // interrupts must stay enabled on Horus
#define audioEnableIrq() // interrupts must stay enabled on Horus
#define setSampleRate(freq)
void setScaledVolume(uint8_t volume);
void setVolume(uint8_t volume);
int32_t getVolume(void);
#define VOLUME_LEVEL_MAX 23
#define VOLUME_LEVEL_DEF 12
// Telemetry driver
#define TELEMETRY_FIFO_SIZE 512
void telemetryPortInit(uint32_t baudrate, uint8_t mode);
void telemetryPortSetDirectionOutput(void);
void sportSendBuffer(uint8_t * buffer, uint32_t count);
uint8_t telemetryGetByte(uint8_t * byte);
// Haptic driver
void hapticInit(void);
void hapticDone(void);
void hapticOff(void);
#define HAPTIC_OFF() hapticOff()
void hapticOn(uint32_t pwmPercent);
// GPS driver
void gpsInit(uint32_t baudrate);
uint8_t gpsGetByte(uint8_t * byte);
#if defined(DEBUG)
extern uint8_t gpsTraceEnabled;
#endif
void gpsSendByte(uint8_t byte);
// Second serial port driver
#define SERIAL2
#define DEBUG_BAUDRATE 115200
extern uint8_t serial2Mode;
void serial2Init(unsigned int mode, unsigned int protocol);
void serial2Putc(char c);
#define serial2TelemetryInit(protocol) serial2Init(UART_MODE_TELEMETRY, protocol)
void serial2SbusInit(void);
void serial2Stop(void);
#define USART_FLAG_ERRORS (USART_FLAG_ORE | USART_FLAG_NE | USART_FLAG_FE | USART_FLAG_PE)
int sbusGetByte(uint8_t * byte);
// BT driver
#define BLUETOOTH_DEFAULT_BAUDRATE 115200
#define BLUETOOTH_FACTORY_BAUDRATE 9600
uint8_t bluetoothReady(void);
void bluetoothInit(uint32_t baudrate);
void bluetoothWrite(const void * buffer, int len);
void bluetoothWriteString(const char * str);
int bluetoothRead(void * buffer, int len);
void bluetoothWakeup(void);
void bluetoothDone(void);
#if defined(USB_JOYSTICK) && !defined(SIMU)
void usbJoystickUpdate(void);
#endif
extern uint8_t currentTrainerMode;
void checkTrainerSettings(void);
#if defined(__cplusplus)
#include "fifo.h"
#include "dmafifo.h"
extern DMAFifo<512> telemetryFifo;
extern DMAFifo<32> serial2RxFifo;
#endif
#endif // _BOARD_HORUS_H_
/*
* 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 _BOARD_HORUS_H_
#define _BOARD_HORUS_H_
#include "stddef.h"
#if defined(__cplusplus) && !defined(SIMU)
extern "C" {
#endif
#if __clang__
// clang is very picky about the use of "register"
// Tell clang to ignore the warnings for the following files
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-register"
#endif
#include "STM32F4xx_DSP_StdPeriph_Lib_V1.4.0/Libraries/CMSIS/Device/ST/STM32F4xx/Include/stm32f4xx.h"
#include "STM32F4xx_DSP_StdPeriph_Lib_V1.4.0/Libraries/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_rcc.h"
#include "STM32F4xx_DSP_StdPeriph_Lib_V1.4.0/Libraries/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_gpio.h"
#include "STM32F4xx_DSP_StdPeriph_Lib_V1.4.0/Libraries/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_spi.h"
#include "STM32F4xx_DSP_StdPeriph_Lib_V1.4.0/Libraries/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_i2c.h"
#include "STM32F4xx_DSP_StdPeriph_Lib_V1.4.0/Libraries/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_rtc.h"
#include "STM32F4xx_DSP_StdPeriph_Lib_V1.4.0/Libraries/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_pwr.h"
#include "STM32F4xx_DSP_StdPeriph_Lib_V1.4.0/Libraries/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_dma.h"
#include "STM32F4xx_DSP_StdPeriph_Lib_V1.4.0/Libraries/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_usart.h"
#include "STM32F4xx_DSP_StdPeriph_Lib_V1.4.0/Libraries/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_flash.h"
#include "STM32F4xx_DSP_StdPeriph_Lib_V1.4.0/Libraries/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_sdio.h"
#include "STM32F4xx_DSP_StdPeriph_Lib_V1.4.0/Libraries/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_dbgmcu.h"
#include "STM32F4xx_DSP_StdPeriph_Lib_V1.4.0/Libraries/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_ltdc.h"
#include "STM32F4xx_DSP_StdPeriph_Lib_V1.4.0/Libraries/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_fmc.h"
#include "STM32F4xx_DSP_StdPeriph_Lib_V1.4.0/Libraries/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_tim.h"
#include "STM32F4xx_DSP_StdPeriph_Lib_V1.4.0/Libraries/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_dma2d.h"
#include "STM32F4xx_DSP_StdPeriph_Lib_V1.4.0/Libraries/STM32F4xx_StdPeriph_Driver/inc/misc.h"
#if __clang__
// Restore warnings about registers
#pragma clang diagnostic pop
#endif
#if !defined(SIMU)
#include "usbd_cdc_core.h"
#include "usbd_msc_core.h"
#include "usbd_hid_core.h"
#include "usbd_usr.h"
#include "usbd_desc.h"
#include "usb_conf.h"
#include "usbd_conf.h"
#endif
#include "hal.h"
#if defined(__cplusplus) && !defined(SIMU)
}
#endif
#define FLASHSIZE 0x80000
#define BOOTLOADER_SIZE 0x8000
#define FIRMWARE_ADDRESS 0x08000000
// HSI is at 168Mhz (over-drive is not enabled!)
#define PERI1_FREQUENCY 42000000
#define PERI2_FREQUENCY 84000000
#define TIMER_MULT_APB1 2
#define TIMER_MULT_APB2 2
#define strcpy_P strcpy
#define strcat_P strcat
extern uint16_t sessionTimer;
#define SLAVE_MODE() (g_model.trainerMode == TRAINER_MODE_SLAVE)
#define TRAINER_CONNECTED() (GPIO_ReadInputDataBit(TRAINER_DETECT_GPIO, TRAINER_DETECT_GPIO_PIN) == Bit_RESET)
// Board driver
void boardInit(void);
void boardOff(void);
// Delays driver
#ifdef __cplusplus
extern "C" {
#endif
void delaysInit(void);
void delay_01us(uint16_t nb);
void delay_us(uint16_t nb);
void delay_ms(uint32_t ms);
#ifdef __cplusplus
}
#endif
// PCBREV driver
#define IS_HORUS_PROD() GPIO_ReadInputDataBit(PCBREV_GPIO, PCBREV_GPIO_PIN)
#if defined(SIMU)
#define IS_FIRMWARE_COMPATIBLE_WITH_BOARD() true
#elif PCBREV >= 13
#define IS_FIRMWARE_COMPATIBLE_WITH_BOARD() IS_HORUS_PROD()
#else
#define IS_FIRMWARE_COMPATIBLE_WITH_BOARD() (!IS_HORUS_PROD())
#endif
// CPU Unique ID
#define LEN_CPU_UID (3*8+2)
void getCPUUniqueID(char * s);
// SD driver
#define BLOCK_SIZE 512 /* Block Size in Bytes */
#if !defined(SIMU) || defined(SIMU_DISKIO)
uint32_t sdIsHC(void);
uint32_t sdGetSpeed(void);
#define SD_IS_HC() (sdIsHC())
#define SD_GET_SPEED() (sdGetSpeed())
#define SD_GET_FREE_BLOCKNR() (sdGetFreeSectors())
#define SD_CARD_PRESENT() (~SD_PRESENT_GPIO->IDR & SD_PRESENT_GPIO_PIN)
void sdInit(void);
void sdMount(void);
void sdDone(void);
#define sdPoll10ms()
uint32_t sdMounted(void);
#else
#define SD_IS_HC() (0)
#define SD_GET_SPEED() (0)
#define sdInit()
#define sdMount()
#define sdDone()
#define SD_CARD_PRESENT() true
#endif
#if defined(DISK_CACHE)
#include "diskio.h"
DRESULT __disk_read(BYTE drv, BYTE * buff, DWORD sector, UINT count);
DRESULT __disk_write(BYTE drv, const BYTE * buff, DWORD sector, UINT count);
#else
#define __disk_read disk_read
#define __disk_write disk_write
#endif
// Flash Write driver
#define FLASH_PAGESIZE 256
void unlockFlash(void);
void lockFlash(void);
void flashWrite(uint32_t * address, uint32_t * buffer);
uint32_t isFirmwareStart(const uint8_t * buffer);
uint32_t isBootloaderStart(const uint8_t * buffer);
// SDRAM driver
void SDRAM_Init(void);
// Pulses driver
#define INTERNAL_MODULE_ON() GPIO_SetBits(INTMODULE_PWR_GPIO, INTMODULE_PWR_GPIO_PIN)
#define INTERNAL_MODULE_OFF() GPIO_ResetBits(INTMODULE_PWR_GPIO, INTMODULE_PWR_GPIO_PIN)
#define EXTERNAL_MODULE_ON() GPIO_SetBits(EXTMODULE_PWR_GPIO, EXTMODULE_PWR_GPIO_PIN)
#define EXTERNAL_MODULE_OFF() GPIO_ResetBits(EXTMODULE_PWR_GPIO, EXTMODULE_PWR_GPIO_PIN)
#define IS_INTERNAL_MODULE_ON() (GPIO_ReadInputDataBit(INTMODULE_PWR_GPIO, INTMODULE_PWR_GPIO_PIN) == Bit_SET)
#define IS_EXTERNAL_MODULE_ON() (GPIO_ReadInputDataBit(EXTMODULE_PWR_GPIO, EXTMODULE_PWR_GPIO_PIN) == Bit_SET)
#define IS_UART_MODULE(port) (port == INTERNAL_MODULE)
void init_no_pulses(uint32_t port);
void disable_no_pulses(uint32_t port);
void init_ppm(uint32_t module_index);
void disable_ppm(uint32_t module_index);
void init_pxx(uint32_t module_index);
void disable_pxx(uint32_t module_index);
void init_dsm2(uint32_t module_index);
void disable_dsm2(uint32_t module_index);
void init_crossfire(uint32_t module_index);
void disable_crossfire(uint32_t module_index);
// Trainer driver
void init_trainer_ppm(void);
void stop_trainer_ppm(void);
void init_trainer_capture(void);
void stop_trainer_capture(void);
// Keys driver
enum EnumKeys
{
KEY_PGUP,
KEY_PGDN,
KEY_ENTER,
KEY_MODEL,
KEY_UP = KEY_MODEL,
KEY_EXIT,
KEY_DOWN = KEY_EXIT,
KEY_TELEM,
KEY_RIGHT = KEY_TELEM,
KEY_RADIO,
KEY_LEFT = KEY_RADIO,
TRM_BASE,
TRM_LH_DWN = TRM_BASE,
TRM_LH_UP,
TRM_LV_DWN,
TRM_LV_UP,
TRM_RV_DWN,
TRM_RV_UP,
TRM_RH_DWN,
TRM_RH_UP,
TRM_LS_DWN,
TRM_LS_UP,
TRM_RS_DWN,
TRM_RS_UP,
TRM_LAST = TRM_RS_UP,
NUM_KEYS
};
enum EnumSwitches
{
SW_SA,
SW_SB,
SW_SC,
SW_SD,
SW_SE,
SW_SF,
SW_SG,
SW_SH,
NUM_SWITCHES
};
#define IS_3POS(x) ((x) != SW_SF && (x) != SW_SH)
enum EnumSwitchesPositions
{
SW_SA0,
SW_SA1,
SW_SA2,
SW_SB0,
SW_SB1,
SW_SB2,
SW_SC0,
SW_SC1,
SW_SC2,
SW_SD0,
SW_SD1,
SW_SD2,
SW_SE0,
SW_SE1,
SW_SE2,
SW_SF0,
SW_SF1,
SW_SF2,
SW_SG0,
SW_SG1,
SW_SG2,
SW_SH0,
SW_SH1,
SW_SH2,
};
void keysInit(void);
uint8_t keyState(uint8_t index);
uint32_t switchState(uint8_t index);
uint32_t readKeys(void);
uint32_t readTrims(void);
#define TRIMS_PRESSED() (readTrims())
#define KEYS_PRESSED() (readKeys())
#define DBLKEYS_PRESSED_RGT_LFT(in) ((in & ((1<<KEY_RIGHT) + (1<<KEY_LEFT))) == ((1<<KEY_RIGHT) + (1<<KEY_LEFT)))
#define DBLKEYS_PRESSED_UP_DWN(in) ((in & ((1<<KEY_UP) + (1<<KEY_DOWN))) == ((1<<KEY_UP) + (1<<KEY_DOWN)))
#define DBLKEYS_PRESSED_RGT_UP(in) ((in & ((1<<KEY_RIGHT) + (1<<KEY_UP))) == ((1<<KEY_RIGHT) + (1<<KEY_UP)))
#define DBLKEYS_PRESSED_LFT_DWN(in) ((in & ((1<<KEY_LEFT) + (1<<KEY_DOWN))) == ((1<<KEY_LEFT) + (1<<KEY_DOWN)))
// Rotary encoder driver
#define ROTARY_ENCODER_NAVIGATION
void checkRotaryEncoder(void);
// 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 wdt_disable()
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()
#else
#if defined(WATCHDOG_DISABLED)
#define wdt_enable(x)
#define wdt_reset()
#else
#define wdt_enable(x) watchdogInit(x)
#define wdt_reset() IWDG->KR = 0xAAAA
#endif
#define WAS_RESET_BY_WATCHDOG() (RCC->CSR & (RCC_CSR_WDGRSTF | RCC_CSR_WWDGRSTF))
#define WAS_RESET_BY_SOFTWARE() (RCC->CSR & RCC_CSR_SFTRSTF)
#define WAS_RESET_BY_WATCHDOG_OR_SOFTWARE() (RCC->CSR & (RCC_CSR_WDGRSTF | RCC_CSR_WWDGRSTF | RCC_CSR_SFTRSTF))
#endif
// ADC driver
#define NUM_POTS 3
#define NUM_SLIDERS 4
#define NUM_XPOTS 3
enum Analogs {
STICK1,
STICK2,
STICK3,
STICK4,
POT_FIRST,
POT1 = POT_FIRST,
POT2,
POT3,
POT_LAST = POT3,
SLIDER1,
SLIDER2,
SLIDER3,
SLIDER4,
TX_VOLTAGE,
MOUSE1,
MOUSE2,
NUMBER_ANALOG
};
#define IS_POT(x) ((x)>=POT_FIRST && (x)<=POT_LAST)
#define IS_SLIDER(x) ((x)>=SLIDER1 && (x)<=SLIDER4)
extern uint16_t adcValues[NUMBER_ANALOG];
void adcInit(void);
void adcRead(void);
uint16_t getAnalogValue(uint8_t index);
uint16_t getBatteryVoltage(); // returns current battery voltage in 10mV steps
#if defined(__cplusplus) && !defined(SIMU)
extern "C" {
#endif
// Power driver
void pwrInit(void);
uint32_t pwrCheck(void);
void pwrOn(void);
void pwrOff(void);
void pwrResetHandler(void);
uint32_t pwrPressed(void);
uint32_t pwrPressedDuration(void);
#define pwroffPressed() pwrPressed()
#if defined(SIMU)
#define UNEXPECTED_SHUTDOWN() (false)
#else
#define UNEXPECTED_SHUTDOWN() (powerupReason == DIRTY_SHUTDOWN)
#endif
// Led driver
void ledOff(void);
void ledRed(void);
void ledBlue(void);
// LCD driver
#define LCD_W 480
#define LCD_H 272
#define LCD_DEPTH 16
void lcdInit(void);
void lcdRefresh(void);
void DMAFillRect(uint16_t * dest, uint16_t destw, uint16_t x, uint16_t y, uint16_t w, uint16_t h, uint16_t color);
void DMACopyBitmap(uint16_t * dest, uint16_t destw, uint16_t x, uint16_t y, const uint16_t * src, uint16_t srcw, uint16_t srcx, uint16_t srcy, uint16_t w, uint16_t h);
void DMACopyAlphaBitmap(uint16_t * dest, uint16_t destw, uint16_t x, uint16_t y, const uint16_t * src, uint16_t srcw, uint16_t srcx, uint16_t srcy, uint16_t w, uint16_t h);
void DMABitmapConvert(uint16_t * dest, const uint8_t * src, uint16_t w, uint16_t h, uint32_t format);
void lcdStoreBackupBuffer(void);
int lcdRestoreBackupBuffer(void);
void lcdSetContrast();
#define lcdOff(...)
#define lcdSetRefVolt(...)
#define lcdRefreshWait(...)
// Backlight driver
void backlightInit(void);
#if defined(SIMU)
#define backlightEnable(...)
#else
void backlightEnable(uint8_t dutyCycle);
#endif
#define BACKLIGHT_ENABLE() backlightEnable(unexpectedShutdown ? 100 : 100-g_eeGeneral.backlightBright)
#define BACKLIGHT_DISABLE() backlightEnable(unexpectedShutdown ? 100 : g_eeGeneral.blOffBright)
#define isBacklightEnabled() true
// USB driver
int usbPlugged(void);
void usbInit(void);
void usbStart(void);
void usbStop(void);
void usbSerialPutc(uint8_t c);
#define USB_NAME "FrSky Horus"
#define USB_MANUFACTURER 'F', 'r', 'S', 'k', 'y', ' ', ' ', ' ' /* 8 bytes */
#define USB_PRODUCT 'H', 'o', 'r', 'u', 's', ' ', ' ', ' ' /* 8 Bytes */
#if defined(__cplusplus) && !defined(SIMU)
}
#endif
// Audio driver
void audioInit(void);
void audioConsumeCurrentBuffer(void);
#define audioDisableIrq() // interrupts must stay enabled on Horus
#define audioEnableIrq() // interrupts must stay enabled on Horus
#define setSampleRate(freq)
void setScaledVolume(uint8_t volume);
void setVolume(uint8_t volume);
int32_t getVolume(void);
#define VOLUME_LEVEL_MAX 23
#define VOLUME_LEVEL_DEF 12
// Telemetry driver
#define TELEMETRY_FIFO_SIZE 512
void telemetryPortInit(uint32_t baudrate, uint8_t mode);
void telemetryPortSetDirectionOutput(void);
void sportSendBuffer(uint8_t * buffer, uint32_t count);
uint8_t telemetryGetByte(uint8_t * byte);
// Haptic driver
void hapticInit(void);
void hapticDone(void);
void hapticOff(void);
#define HAPTIC_OFF() hapticOff()
void hapticOn(uint32_t pwmPercent);
// GPS driver
void gpsInit(uint32_t baudrate);
uint8_t gpsGetByte(uint8_t * byte);
#if defined(DEBUG)
extern uint8_t gpsTraceEnabled;
#endif
void gpsSendByte(uint8_t byte);
// Second serial port driver
#define SERIAL2
#define DEBUG_BAUDRATE 115200
extern uint8_t serial2Mode;
void serial2Init(unsigned int mode, unsigned int protocol);
void serial2Putc(char c);
#define serial2TelemetryInit(protocol) serial2Init(UART_MODE_TELEMETRY, protocol)
void serial2SbusInit(void);
void serial2Stop(void);
#define USART_FLAG_ERRORS (USART_FLAG_ORE | USART_FLAG_NE | USART_FLAG_FE | USART_FLAG_PE)
int sbusGetByte(uint8_t * byte);
// BT driver
#define BLUETOOTH_DEFAULT_BAUDRATE 115200
#define BLUETOOTH_FACTORY_BAUDRATE 9600
uint8_t bluetoothReady(void);
void bluetoothInit(uint32_t baudrate);
void bluetoothWrite(const void * buffer, int len);
void bluetoothWriteString(const char * str);
int bluetoothRead(void * buffer, int len);
void bluetoothWakeup(void);
void bluetoothDone(void);
#if defined(USB_JOYSTICK) && !defined(SIMU)
void usbJoystickUpdate(void);
#endif
extern uint8_t currentTrainerMode;
void checkTrainerSettings(void);
#if defined(__cplusplus)
#include "fifo.h"
#include "dmafifo.h"
extern DMAFifo<512> telemetryFifo;
extern DMAFifo<32> serial2RxFifo;
#endif
#endif // _BOARD_HORUS_H_
+1 -1
View File
@@ -308,7 +308,7 @@ DRESULT disk_ioctl (
// TODO everything here should not be in the driver layer ...
FATFS g_FATFS_Obj __DMA;
FATFS g_FATFS_Obj __DMA; // initialized in boardInit()
#if defined(LOG_TELEMETRY)
FIL g_telemetryFile = {};
#endif
+33 -6
View File
@@ -21,6 +21,10 @@
#include "pwr.h"
#include "board.h"
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
void pwrInit()
{
GPIO_InitTypeDef GPIO_InitStructure;
@@ -70,6 +74,8 @@ void pwrInit()
void pwrOn()
{
GPIO_SetBits(PWR_GPIO, PWR_ON_GPIO_PIN);
shutdownRequest = NO_SHUTDOWN_REQUEST;
shutdownReason = DIRTY_SHUTDOWN;
}
void pwrOff()
@@ -87,6 +93,8 @@ void pwrOff()
// Shutdown the Haptic
hapticDone();
shutdownRequest = SHUTDOWN_REQUEST;
shutdownReason = NORMAL_POWER_OFF;
GPIO_ResetBits(PWR_GPIO, PWR_ON_GPIO_PIN);
}
@@ -104,13 +112,28 @@ void pwrResetHandler()
__ASM volatile ("nop");
__ASM volatile ("nop");
// Turn soft power ON now, but only if we got started because of the watchdog
// or software reset. If the radio was started by user pressing the power button
// then that button is providing power and we don't need to enable it here.
// 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.
//
// If we were to turn it on here indiscriminately, then the radio can go into the
// power on/off loop after being powered off by the user. (issue #2790)
if (WAS_RESET_BY_WATCHDOG_OR_SOFTWARE()) {
// 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.
if (shutdownRequest != SHUTDOWN_REQUEST) {
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = PWR_ON_GPIO_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
@@ -119,6 +142,10 @@ void pwrResetHandler()
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init(PWR_GPIO, &GPIO_InitStructure);
if (shutdownReason == DIRTY_SHUTDOWN) {
powerupReason = DIRTY_SHUTDOWN;
}
pwrOn();
}
}
+7
View File
@@ -127,6 +127,13 @@ SECTIONS
_ebss = .; /* define a global symbol at bss end */
} >CCM
/* Non-zeroed data section */
. = ALIGN(4);
.noinit (NOLOAD) :
{
*(.noinit)
} >CCM
/* collect all uninitialized .ccm sections */
.ram (NOLOAD) :
{