mirror of
https://github.com/opentx/opentx.git
synced 2025-07-23 16:25:16 +03:00
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 fe9a52779d
)
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:
parent
bf15410bf1
commit
b3f4870da7
9 changed files with 651 additions and 525 deletions
|
@ -22,6 +22,7 @@
|
||||||
#include "diskio.h"
|
#include "diskio.h"
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <malloc.h>
|
#include <malloc.h>
|
||||||
|
#include <new>
|
||||||
|
|
||||||
#define CLI_COMMAND_MAX_ARGS 8
|
#define CLI_COMMAND_MAX_ARGS 8
|
||||||
#define CLI_COMMAND_MAX_LEN 256
|
#define CLI_COMMAND_MAX_LEN 256
|
||||||
|
@ -302,6 +303,62 @@ int cliTestSD(const char ** argv)
|
||||||
return 0;
|
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)
|
int cliTrace(const char ** argv)
|
||||||
{
|
{
|
||||||
if (!strcmp(argv[1], "on")) {
|
if (!strcmp(argv[1], "on")) {
|
||||||
|
@ -509,7 +566,7 @@ void printTaskSwitchLog()
|
||||||
uint32_t * tsl = new uint32_t[DEBUG_TASKS_LOG_SIZE];
|
uint32_t * tsl = new uint32_t[DEBUG_TASKS_LOG_SIZE];
|
||||||
if (!tsl) {
|
if (!tsl) {
|
||||||
serialPrint("Not enough memory");
|
serialPrint("Not enough memory");
|
||||||
return 0;
|
return;
|
||||||
}
|
}
|
||||||
memcpy(tsl, taskSwitchLog, sizeof(taskSwitchLog));
|
memcpy(tsl, taskSwitchLog, sizeof(taskSwitchLog));
|
||||||
uint32_t * p = tsl + taskSwitchLogPos;
|
uint32_t * p = tsl + taskSwitchLogPos;
|
||||||
|
@ -892,6 +949,7 @@ const CliCommand cliCommands[] = {
|
||||||
{ "set", cliSet, "<what> <value>" },
|
{ "set", cliSet, "<what> <value>" },
|
||||||
{ "stackinfo", cliStackInfo, "" },
|
{ "stackinfo", cliStackInfo, "" },
|
||||||
{ "meminfo", cliMemoryInfo, "" },
|
{ "meminfo", cliMemoryInfo, "" },
|
||||||
|
{ "test", cliTest, "new | std::exception" },
|
||||||
{ "trace", cliTrace, "on | off" },
|
{ "trace", cliTrace, "on | off" },
|
||||||
#if defined(PCBFLAMENCO)
|
#if defined(PCBFLAMENCO)
|
||||||
{ "read_bq24195", cliReadBQ24195, "<register>" },
|
{ "read_bq24195", cliReadBQ24195, "<register>" },
|
||||||
|
|
|
@ -41,6 +41,12 @@
|
||||||
#define __SDRAM __DMA
|
#define __SDRAM __DMA
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(PCBHORUS) && !defined(SIMU)
|
||||||
|
#define __NOINIT __attribute__((section(".noinit")))
|
||||||
|
#else
|
||||||
|
#define __NOINIT
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(SIMU) || defined(CPUARM) || GCC_VERSION < 472
|
#if defined(SIMU) || defined(CPUARM) || GCC_VERSION < 472
|
||||||
typedef int32_t int24_t;
|
typedef int32_t int24_t;
|
||||||
#else
|
#else
|
||||||
|
|
|
@ -2438,29 +2438,47 @@ void opentxInit(OPENTX_INIT_ARGS)
|
||||||
#if defined(RTCLOCK) && !defined(COPROCESSOR)
|
#if defined(RTCLOCK) && !defined(COPROCESSOR)
|
||||||
rtcInit(); // RTC must be initialized before rambackupRestore() is called
|
rtcInit(); // RTC must be initialized before rambackupRestore() is called
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(EEPROM)
|
#if defined(EEPROM)
|
||||||
storageReadAll();
|
storageReadAll();
|
||||||
#endif
|
#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()) {
|
if (UNEXPECTED_SHUTDOWN()) {
|
||||||
|
TRACE("Unexpected Shutdown detected");
|
||||||
unexpectedShutdown = 1;
|
unexpectedShutdown = 1;
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
#if defined(SDCARD) && !defined(PCBMEGA2560)
|
#if defined(SDCARD) && !defined(PCBMEGA2560)
|
||||||
|
// SDCARD related stuff, only done if not unexpectedShutdown
|
||||||
|
if (!unexpectedShutdown) {
|
||||||
sdInit();
|
sdInit();
|
||||||
logsInit();
|
logsInit();
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
|
||||||
|
|
||||||
#if defined(PCBHORUS)
|
#if defined(PCBHORUS)
|
||||||
topbar = new Topbar(&g_model.topbarData);
|
if (!unexpectedShutdown) {
|
||||||
LUA_INIT_THEMES_AND_WIDGETS();
|
// 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
|
#endif
|
||||||
|
|
||||||
|
// handling of storage for radios that have no EEPROM
|
||||||
#if !defined(EEPROM)
|
#if !defined(EEPROM)
|
||||||
#if defined(RAMBACKUP)
|
#if defined(RAMBACKUP)
|
||||||
if (UNEXPECTED_SHUTDOWN()) {
|
if (unexpectedShutdown) {
|
||||||
|
// SDCARD not available, try to restore last model from RAM
|
||||||
|
TRACE("rambackupRestore");
|
||||||
rambackupRestore();
|
rambackupRestore();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -2469,7 +2487,7 @@ void opentxInit(OPENTX_INIT_ARGS)
|
||||||
#else
|
#else
|
||||||
storageReadAll();
|
storageReadAll();
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif // #if !defined(EEPROM)
|
||||||
|
|
||||||
#if defined(SERIAL2)
|
#if defined(SERIAL2)
|
||||||
serial2Init(g_eeGeneral.serial2Mode, MODEL_TELEMETRY_PROTOCOL());
|
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 (g_eeGeneral.backlightMode != e_backlight_mode_off) backlightOn(); // on Tx start turn the light on
|
||||||
|
|
||||||
if (!UNEXPECTED_SHUTDOWN()) {
|
if (!unexpectedShutdown) {
|
||||||
opentxStart();
|
opentxStart();
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(CPUARM) || defined(CPUM2560)
|
#if defined(CPUARM) || defined(CPUM2560)
|
||||||
|
// TODO Horus does not need this
|
||||||
if (!g_eeGeneral.unexpectedShutdown) {
|
if (!g_eeGeneral.unexpectedShutdown) {
|
||||||
g_eeGeneral.unexpectedShutdown = 1;
|
g_eeGeneral.unexpectedShutdown = 1;
|
||||||
storageDirty(EE_GENERAL);
|
storageDirty(EE_GENERAL);
|
||||||
|
@ -2667,7 +2686,7 @@ int main()
|
||||||
drawSleepBitmap();
|
drawSleepBitmap();
|
||||||
opentxClose();
|
opentxClose();
|
||||||
boardOff(); // Only turn power off if necessary
|
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.
|
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
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
* Copyright (C) OpenTX
|
* Copyright (C) OpenTX
|
||||||
*
|
*
|
||||||
* Based on code named
|
* 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
|
* er9x - http://code.google.com/p/er9x
|
||||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||||
*
|
*
|
||||||
|
@ -37,7 +37,7 @@
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include "debug.h"
|
||||||
/*----------------------------------------------------------------------------
|
/*----------------------------------------------------------------------------
|
||||||
* Exported variables
|
* Exported variables
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
|
@ -50,11 +50,12 @@ extern int _heap_end;
|
||||||
/*----------------------------------------------------------------------------
|
/*----------------------------------------------------------------------------
|
||||||
* Exported functions
|
* Exported functions
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
extern void _exit( int status ) ;
|
// extern void _exit( int status ) ;
|
||||||
extern void _kill( int pid, int sig ) ;
|
// extern void _kill( int pid, int sig ) ;
|
||||||
extern int _getpid ( void ) ;
|
// extern int _getpid ( void ) ;
|
||||||
|
|
||||||
unsigned char * heap = (unsigned char *)&_end;
|
unsigned char * heap = (unsigned char *)&_end;
|
||||||
|
|
||||||
extern caddr_t _sbrk(int nbytes)
|
extern caddr_t _sbrk(int nbytes)
|
||||||
{
|
{
|
||||||
if (heap + nbytes < (unsigned char *)&_heap_end) {
|
if (heap + nbytes < (unsigned char *)&_heap_end) {
|
||||||
|
@ -70,84 +71,68 @@ extern caddr_t _sbrk(int nbytes)
|
||||||
|
|
||||||
extern int _gettimeofday(void *p1, void *p2)
|
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)
|
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 ;
|
st->st_mode = S_IFCHR ;
|
||||||
|
return 0;
|
||||||
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)
|
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 ;
|
return 0;
|
||||||
|
|
||||||
|
|
||||||
// for ( ; *ptr != 0 ; ptr++ )
|
|
||||||
for ( iIndex=0 ; iIndex < len ; iIndex++, ptr++ )
|
|
||||||
{
|
|
||||||
// TODO UART_PutChar( *ptr ) ;
|
|
||||||
}
|
|
||||||
|
|
||||||
return iIndex ;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
extern void _exit( int status )
|
extern void _exit(int status)
|
||||||
{
|
{
|
||||||
#if defined(SIMU)
|
TRACE("_exit(%d)", status);
|
||||||
printf( "Exiting with status %d.\n", status ) ;
|
for (;;);
|
||||||
#endif
|
|
||||||
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 ;
|
return -1 ;
|
||||||
}
|
}
|
||||||
|
|
||||||
//void _init (void)
|
|
||||||
//{
|
|
||||||
|
|
||||||
//}
|
|
||||||
|
|
|
@ -156,6 +156,11 @@ void boardInit()
|
||||||
__enable_irq();
|
__enable_irq();
|
||||||
|
|
||||||
TRACE("\nHorus board started :)");
|
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();
|
keysInit();
|
||||||
adcInit();
|
adcInit();
|
||||||
|
|
|
@ -1,462 +1,481 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) OpenTX
|
* Copyright (C) OpenTX
|
||||||
*
|
*
|
||||||
* Based on code named
|
* 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
|
* er9x - http://code.google.com/p/er9x
|
||||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||||
*
|
*
|
||||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License version 2 as
|
||||||
* published by the Free Software Foundation.
|
* published by the Free Software Foundation.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _BOARD_HORUS_H_
|
#ifndef _BOARD_HORUS_H_
|
||||||
#define _BOARD_HORUS_H_
|
#define _BOARD_HORUS_H_
|
||||||
|
|
||||||
#include "stddef.h"
|
#include "stddef.h"
|
||||||
|
|
||||||
#if defined(__cplusplus) && !defined(SIMU)
|
#if defined(__cplusplus) && !defined(SIMU)
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if __clang__
|
#if __clang__
|
||||||
// clang is very picky about the use of "register"
|
// clang is very picky about the use of "register"
|
||||||
// Tell clang to ignore the warnings for the following files
|
// Tell clang to ignore the warnings for the following files
|
||||||
#pragma clang diagnostic push
|
#pragma clang diagnostic push
|
||||||
#pragma clang diagnostic ignored "-Wdeprecated-register"
|
#pragma clang diagnostic ignored "-Wdeprecated-register"
|
||||||
#endif
|
#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/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_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_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_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_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_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_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_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_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_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_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_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_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_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_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/stm32f4xx_dma2d.h"
|
||||||
#include "STM32F4xx_DSP_StdPeriph_Lib_V1.4.0/Libraries/STM32F4xx_StdPeriph_Driver/inc/misc.h"
|
#include "STM32F4xx_DSP_StdPeriph_Lib_V1.4.0/Libraries/STM32F4xx_StdPeriph_Driver/inc/misc.h"
|
||||||
#if __clang__
|
#if __clang__
|
||||||
// Restore warnings about registers
|
// Restore warnings about registers
|
||||||
#pragma clang diagnostic pop
|
#pragma clang diagnostic pop
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#if !defined(SIMU)
|
#if !defined(SIMU)
|
||||||
#include "usbd_cdc_core.h"
|
#include "usbd_cdc_core.h"
|
||||||
#include "usbd_msc_core.h"
|
#include "usbd_msc_core.h"
|
||||||
#include "usbd_hid_core.h"
|
#include "usbd_hid_core.h"
|
||||||
#include "usbd_usr.h"
|
#include "usbd_usr.h"
|
||||||
#include "usbd_desc.h"
|
#include "usbd_desc.h"
|
||||||
#include "usb_conf.h"
|
#include "usb_conf.h"
|
||||||
#include "usbd_conf.h"
|
#include "usbd_conf.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "hal.h"
|
#include "hal.h"
|
||||||
|
|
||||||
#if defined(__cplusplus) && !defined(SIMU)
|
#if defined(__cplusplus) && !defined(SIMU)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define FLASHSIZE 0x80000
|
#define FLASHSIZE 0x80000
|
||||||
#define BOOTLOADER_SIZE 0x8000
|
#define BOOTLOADER_SIZE 0x8000
|
||||||
#define FIRMWARE_ADDRESS 0x08000000
|
#define FIRMWARE_ADDRESS 0x08000000
|
||||||
|
|
||||||
// HSI is at 168Mhz (over-drive is not enabled!)
|
// HSI is at 168Mhz (over-drive is not enabled!)
|
||||||
#define PERI1_FREQUENCY 42000000
|
#define PERI1_FREQUENCY 42000000
|
||||||
#define PERI2_FREQUENCY 84000000
|
#define PERI2_FREQUENCY 84000000
|
||||||
#define TIMER_MULT_APB1 2
|
#define TIMER_MULT_APB1 2
|
||||||
#define TIMER_MULT_APB2 2
|
#define TIMER_MULT_APB2 2
|
||||||
|
|
||||||
#define strcpy_P strcpy
|
#define strcpy_P strcpy
|
||||||
#define strcat_P strcat
|
#define strcat_P strcat
|
||||||
|
|
||||||
extern uint16_t sessionTimer;
|
extern uint16_t sessionTimer;
|
||||||
|
|
||||||
#define SLAVE_MODE() (g_model.trainerMode == TRAINER_MODE_SLAVE)
|
#define SLAVE_MODE() (g_model.trainerMode == TRAINER_MODE_SLAVE)
|
||||||
#define TRAINER_CONNECTED() (GPIO_ReadInputDataBit(TRAINER_DETECT_GPIO, TRAINER_DETECT_GPIO_PIN) == Bit_RESET)
|
#define TRAINER_CONNECTED() (GPIO_ReadInputDataBit(TRAINER_DETECT_GPIO, TRAINER_DETECT_GPIO_PIN) == Bit_RESET)
|
||||||
|
|
||||||
// Board driver
|
// Board driver
|
||||||
void boardInit(void);
|
void boardInit(void);
|
||||||
void boardOff(void);
|
void boardOff(void);
|
||||||
|
|
||||||
// Delays driver
|
// Delays driver
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
void delaysInit(void);
|
void delaysInit(void);
|
||||||
void delay_01us(uint16_t nb);
|
void delay_01us(uint16_t nb);
|
||||||
void delay_us(uint16_t nb);
|
void delay_us(uint16_t nb);
|
||||||
void delay_ms(uint32_t ms);
|
void delay_ms(uint32_t ms);
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// PCBREV driver
|
// PCBREV driver
|
||||||
#define IS_HORUS_PROD() GPIO_ReadInputDataBit(PCBREV_GPIO, PCBREV_GPIO_PIN)
|
#define IS_HORUS_PROD() GPIO_ReadInputDataBit(PCBREV_GPIO, PCBREV_GPIO_PIN)
|
||||||
#if defined(SIMU)
|
#if defined(SIMU)
|
||||||
#define IS_FIRMWARE_COMPATIBLE_WITH_BOARD() true
|
#define IS_FIRMWARE_COMPATIBLE_WITH_BOARD() true
|
||||||
#elif PCBREV >= 13
|
#elif PCBREV >= 13
|
||||||
#define IS_FIRMWARE_COMPATIBLE_WITH_BOARD() IS_HORUS_PROD()
|
#define IS_FIRMWARE_COMPATIBLE_WITH_BOARD() IS_HORUS_PROD()
|
||||||
#else
|
#else
|
||||||
#define IS_FIRMWARE_COMPATIBLE_WITH_BOARD() (!IS_HORUS_PROD())
|
#define IS_FIRMWARE_COMPATIBLE_WITH_BOARD() (!IS_HORUS_PROD())
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// CPU Unique ID
|
// CPU Unique ID
|
||||||
#define LEN_CPU_UID (3*8+2)
|
#define LEN_CPU_UID (3*8+2)
|
||||||
void getCPUUniqueID(char * s);
|
void getCPUUniqueID(char * s);
|
||||||
|
|
||||||
// SD driver
|
// SD driver
|
||||||
#define BLOCK_SIZE 512 /* Block Size in Bytes */
|
#define BLOCK_SIZE 512 /* Block Size in Bytes */
|
||||||
#if !defined(SIMU) || defined(SIMU_DISKIO)
|
#if !defined(SIMU) || defined(SIMU_DISKIO)
|
||||||
uint32_t sdIsHC(void);
|
uint32_t sdIsHC(void);
|
||||||
uint32_t sdGetSpeed(void);
|
uint32_t sdGetSpeed(void);
|
||||||
#define SD_IS_HC() (sdIsHC())
|
#define SD_IS_HC() (sdIsHC())
|
||||||
#define SD_GET_SPEED() (sdGetSpeed())
|
#define SD_GET_SPEED() (sdGetSpeed())
|
||||||
#define SD_GET_FREE_BLOCKNR() (sdGetFreeSectors())
|
#define SD_GET_FREE_BLOCKNR() (sdGetFreeSectors())
|
||||||
#define SD_CARD_PRESENT() (~SD_PRESENT_GPIO->IDR & SD_PRESENT_GPIO_PIN)
|
#define SD_CARD_PRESENT() (~SD_PRESENT_GPIO->IDR & SD_PRESENT_GPIO_PIN)
|
||||||
void sdInit(void);
|
void sdInit(void);
|
||||||
void sdMount(void);
|
void sdMount(void);
|
||||||
void sdDone(void);
|
void sdDone(void);
|
||||||
#define sdPoll10ms()
|
#define sdPoll10ms()
|
||||||
uint32_t sdMounted(void);
|
uint32_t sdMounted(void);
|
||||||
#else
|
#else
|
||||||
#define SD_IS_HC() (0)
|
#define SD_IS_HC() (0)
|
||||||
#define SD_GET_SPEED() (0)
|
#define SD_GET_SPEED() (0)
|
||||||
#define sdInit()
|
#define sdInit()
|
||||||
#define sdMount()
|
#define sdMount()
|
||||||
#define sdDone()
|
#define sdDone()
|
||||||
#define SD_CARD_PRESENT() true
|
#define SD_CARD_PRESENT() true
|
||||||
#endif
|
#endif
|
||||||
#if defined(DISK_CACHE)
|
#if defined(DISK_CACHE)
|
||||||
#include "diskio.h"
|
#include "diskio.h"
|
||||||
DRESULT __disk_read(BYTE drv, BYTE * buff, DWORD sector, UINT count);
|
DRESULT __disk_read(BYTE drv, BYTE * buff, DWORD sector, UINT count);
|
||||||
DRESULT __disk_write(BYTE drv, const BYTE * buff, DWORD sector, UINT count);
|
DRESULT __disk_write(BYTE drv, const BYTE * buff, DWORD sector, UINT count);
|
||||||
#else
|
#else
|
||||||
#define __disk_read disk_read
|
#define __disk_read disk_read
|
||||||
#define __disk_write disk_write
|
#define __disk_write disk_write
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Flash Write driver
|
// Flash Write driver
|
||||||
#define FLASH_PAGESIZE 256
|
#define FLASH_PAGESIZE 256
|
||||||
void unlockFlash(void);
|
void unlockFlash(void);
|
||||||
void lockFlash(void);
|
void lockFlash(void);
|
||||||
void flashWrite(uint32_t * address, uint32_t * buffer);
|
void flashWrite(uint32_t * address, uint32_t * buffer);
|
||||||
uint32_t isFirmwareStart(const uint8_t * buffer);
|
uint32_t isFirmwareStart(const uint8_t * buffer);
|
||||||
uint32_t isBootloaderStart(const uint8_t * buffer);
|
uint32_t isBootloaderStart(const uint8_t * buffer);
|
||||||
|
|
||||||
// SDRAM driver
|
// SDRAM driver
|
||||||
void SDRAM_Init(void);
|
void SDRAM_Init(void);
|
||||||
|
|
||||||
// Pulses driver
|
// Pulses driver
|
||||||
#define INTERNAL_MODULE_ON() GPIO_SetBits(INTMODULE_PWR_GPIO, INTMODULE_PWR_GPIO_PIN)
|
#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 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_ON() GPIO_SetBits(EXTMODULE_PWR_GPIO, EXTMODULE_PWR_GPIO_PIN)
|
||||||
#define EXTERNAL_MODULE_OFF() GPIO_ResetBits(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_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_EXTERNAL_MODULE_ON() (GPIO_ReadInputDataBit(EXTMODULE_PWR_GPIO, EXTMODULE_PWR_GPIO_PIN) == Bit_SET)
|
||||||
#define IS_UART_MODULE(port) (port == INTERNAL_MODULE)
|
#define IS_UART_MODULE(port) (port == INTERNAL_MODULE)
|
||||||
|
|
||||||
void init_no_pulses(uint32_t port);
|
void init_no_pulses(uint32_t port);
|
||||||
void disable_no_pulses(uint32_t port);
|
void disable_no_pulses(uint32_t port);
|
||||||
void init_ppm(uint32_t module_index);
|
void init_ppm(uint32_t module_index);
|
||||||
void disable_ppm(uint32_t module_index);
|
void disable_ppm(uint32_t module_index);
|
||||||
void init_pxx(uint32_t module_index);
|
void init_pxx(uint32_t module_index);
|
||||||
void disable_pxx(uint32_t module_index);
|
void disable_pxx(uint32_t module_index);
|
||||||
void init_dsm2(uint32_t module_index);
|
void init_dsm2(uint32_t module_index);
|
||||||
void disable_dsm2(uint32_t module_index);
|
void disable_dsm2(uint32_t module_index);
|
||||||
void init_crossfire(uint32_t module_index);
|
void init_crossfire(uint32_t module_index);
|
||||||
void disable_crossfire(uint32_t module_index);
|
void disable_crossfire(uint32_t module_index);
|
||||||
|
|
||||||
// Trainer driver
|
// Trainer driver
|
||||||
void init_trainer_ppm(void);
|
void init_trainer_ppm(void);
|
||||||
void stop_trainer_ppm(void);
|
void stop_trainer_ppm(void);
|
||||||
void init_trainer_capture(void);
|
void init_trainer_capture(void);
|
||||||
void stop_trainer_capture(void);
|
void stop_trainer_capture(void);
|
||||||
|
|
||||||
// Keys driver
|
// Keys driver
|
||||||
enum EnumKeys
|
enum EnumKeys
|
||||||
{
|
{
|
||||||
KEY_PGUP,
|
KEY_PGUP,
|
||||||
KEY_PGDN,
|
KEY_PGDN,
|
||||||
KEY_ENTER,
|
KEY_ENTER,
|
||||||
KEY_MODEL,
|
KEY_MODEL,
|
||||||
KEY_UP = KEY_MODEL,
|
KEY_UP = KEY_MODEL,
|
||||||
KEY_EXIT,
|
KEY_EXIT,
|
||||||
KEY_DOWN = KEY_EXIT,
|
KEY_DOWN = KEY_EXIT,
|
||||||
KEY_TELEM,
|
KEY_TELEM,
|
||||||
KEY_RIGHT = KEY_TELEM,
|
KEY_RIGHT = KEY_TELEM,
|
||||||
KEY_RADIO,
|
KEY_RADIO,
|
||||||
KEY_LEFT = KEY_RADIO,
|
KEY_LEFT = KEY_RADIO,
|
||||||
|
|
||||||
TRM_BASE,
|
TRM_BASE,
|
||||||
TRM_LH_DWN = TRM_BASE,
|
TRM_LH_DWN = TRM_BASE,
|
||||||
TRM_LH_UP,
|
TRM_LH_UP,
|
||||||
TRM_LV_DWN,
|
TRM_LV_DWN,
|
||||||
TRM_LV_UP,
|
TRM_LV_UP,
|
||||||
TRM_RV_DWN,
|
TRM_RV_DWN,
|
||||||
TRM_RV_UP,
|
TRM_RV_UP,
|
||||||
TRM_RH_DWN,
|
TRM_RH_DWN,
|
||||||
TRM_RH_UP,
|
TRM_RH_UP,
|
||||||
TRM_LS_DWN,
|
TRM_LS_DWN,
|
||||||
TRM_LS_UP,
|
TRM_LS_UP,
|
||||||
TRM_RS_DWN,
|
TRM_RS_DWN,
|
||||||
TRM_RS_UP,
|
TRM_RS_UP,
|
||||||
TRM_LAST = TRM_RS_UP,
|
TRM_LAST = TRM_RS_UP,
|
||||||
|
|
||||||
NUM_KEYS
|
NUM_KEYS
|
||||||
};
|
};
|
||||||
|
|
||||||
enum EnumSwitches
|
enum EnumSwitches
|
||||||
{
|
{
|
||||||
SW_SA,
|
SW_SA,
|
||||||
SW_SB,
|
SW_SB,
|
||||||
SW_SC,
|
SW_SC,
|
||||||
SW_SD,
|
SW_SD,
|
||||||
SW_SE,
|
SW_SE,
|
||||||
SW_SF,
|
SW_SF,
|
||||||
SW_SG,
|
SW_SG,
|
||||||
SW_SH,
|
SW_SH,
|
||||||
NUM_SWITCHES
|
NUM_SWITCHES
|
||||||
};
|
};
|
||||||
#define IS_3POS(x) ((x) != SW_SF && (x) != SW_SH)
|
#define IS_3POS(x) ((x) != SW_SF && (x) != SW_SH)
|
||||||
|
|
||||||
enum EnumSwitchesPositions
|
enum EnumSwitchesPositions
|
||||||
{
|
{
|
||||||
SW_SA0,
|
SW_SA0,
|
||||||
SW_SA1,
|
SW_SA1,
|
||||||
SW_SA2,
|
SW_SA2,
|
||||||
SW_SB0,
|
SW_SB0,
|
||||||
SW_SB1,
|
SW_SB1,
|
||||||
SW_SB2,
|
SW_SB2,
|
||||||
SW_SC0,
|
SW_SC0,
|
||||||
SW_SC1,
|
SW_SC1,
|
||||||
SW_SC2,
|
SW_SC2,
|
||||||
SW_SD0,
|
SW_SD0,
|
||||||
SW_SD1,
|
SW_SD1,
|
||||||
SW_SD2,
|
SW_SD2,
|
||||||
SW_SE0,
|
SW_SE0,
|
||||||
SW_SE1,
|
SW_SE1,
|
||||||
SW_SE2,
|
SW_SE2,
|
||||||
SW_SF0,
|
SW_SF0,
|
||||||
SW_SF1,
|
SW_SF1,
|
||||||
SW_SF2,
|
SW_SF2,
|
||||||
SW_SG0,
|
SW_SG0,
|
||||||
SW_SG1,
|
SW_SG1,
|
||||||
SW_SG2,
|
SW_SG2,
|
||||||
SW_SH0,
|
SW_SH0,
|
||||||
SW_SH1,
|
SW_SH1,
|
||||||
SW_SH2,
|
SW_SH2,
|
||||||
};
|
};
|
||||||
void keysInit(void);
|
void keysInit(void);
|
||||||
uint8_t keyState(uint8_t index);
|
uint8_t keyState(uint8_t index);
|
||||||
uint32_t switchState(uint8_t index);
|
uint32_t switchState(uint8_t index);
|
||||||
uint32_t readKeys(void);
|
uint32_t readKeys(void);
|
||||||
uint32_t readTrims(void);
|
uint32_t readTrims(void);
|
||||||
#define TRIMS_PRESSED() (readTrims())
|
#define TRIMS_PRESSED() (readTrims())
|
||||||
#define KEYS_PRESSED() (readKeys())
|
#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_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_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_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)))
|
#define DBLKEYS_PRESSED_LFT_DWN(in) ((in & ((1<<KEY_LEFT) + (1<<KEY_DOWN))) == ((1<<KEY_LEFT) + (1<<KEY_DOWN)))
|
||||||
|
|
||||||
// Rotary encoder driver
|
// Rotary encoder driver
|
||||||
#define ROTARY_ENCODER_NAVIGATION
|
#define ROTARY_ENCODER_NAVIGATION
|
||||||
void checkRotaryEncoder(void);
|
void checkRotaryEncoder(void);
|
||||||
|
|
||||||
// WDT driver
|
// WDT driver
|
||||||
#define WDTO_500MS 500
|
#define WDTO_500MS 500
|
||||||
#define wdt_disable()
|
extern uint32_t powerupReason;
|
||||||
void watchdogInit(unsigned int duration);
|
|
||||||
#if defined(WATCHDOG_DISABLED) || defined(SIMU)
|
#define SHUTDOWN_REQUEST 0xDEADBEEF
|
||||||
#define wdt_enable(x)
|
#define NO_SHUTDOWN_REQUEST ~SHUTDOWN_REQUEST
|
||||||
#define wdt_reset()
|
#define DIRTY_SHUTDOWN 0xCAFEDEAD
|
||||||
#else
|
#define NORMAL_POWER_OFF ~DIRTY_SHUTDOWN
|
||||||
#define wdt_enable(x) watchdogInit(x)
|
|
||||||
#define wdt_reset() IWDG->KR = 0xAAAA
|
#define wdt_disable()
|
||||||
#endif
|
void watchdogInit(unsigned int duration);
|
||||||
#define WAS_RESET_BY_WATCHDOG() (RCC->CSR & (RCC_CSR_WDGRSTF | RCC_CSR_WWDGRSTF))
|
#if defined(SIMU)
|
||||||
#define WAS_RESET_BY_SOFTWARE() (RCC->CSR & RCC_CSR_SFTRSTF)
|
#define WAS_RESET_BY_WATCHDOG() (false)
|
||||||
#define WAS_RESET_BY_WATCHDOG_OR_SOFTWARE() (RCC->CSR & (RCC_CSR_WDGRSTF | RCC_CSR_WWDGRSTF | RCC_CSR_SFTRSTF))
|
#define WAS_RESET_BY_SOFTWARE() (false)
|
||||||
|
#define WAS_RESET_BY_WATCHDOG_OR_SOFTWARE() (false)
|
||||||
// ADC driver
|
#define wdt_enable(x)
|
||||||
#define NUM_POTS 3
|
#define wdt_reset()
|
||||||
#define NUM_SLIDERS 4
|
#else
|
||||||
#define NUM_XPOTS 3
|
#if defined(WATCHDOG_DISABLED)
|
||||||
enum Analogs {
|
#define wdt_enable(x)
|
||||||
STICK1,
|
#define wdt_reset()
|
||||||
STICK2,
|
#else
|
||||||
STICK3,
|
#define wdt_enable(x) watchdogInit(x)
|
||||||
STICK4,
|
#define wdt_reset() IWDG->KR = 0xAAAA
|
||||||
POT_FIRST,
|
#endif
|
||||||
POT1 = POT_FIRST,
|
#define WAS_RESET_BY_WATCHDOG() (RCC->CSR & (RCC_CSR_WDGRSTF | RCC_CSR_WWDGRSTF))
|
||||||
POT2,
|
#define WAS_RESET_BY_SOFTWARE() (RCC->CSR & RCC_CSR_SFTRSTF)
|
||||||
POT3,
|
#define WAS_RESET_BY_WATCHDOG_OR_SOFTWARE() (RCC->CSR & (RCC_CSR_WDGRSTF | RCC_CSR_WWDGRSTF | RCC_CSR_SFTRSTF))
|
||||||
POT_LAST = POT3,
|
#endif
|
||||||
SLIDER1,
|
|
||||||
SLIDER2,
|
// ADC driver
|
||||||
SLIDER3,
|
#define NUM_POTS 3
|
||||||
SLIDER4,
|
#define NUM_SLIDERS 4
|
||||||
TX_VOLTAGE,
|
#define NUM_XPOTS 3
|
||||||
MOUSE1,
|
enum Analogs {
|
||||||
MOUSE2,
|
STICK1,
|
||||||
NUMBER_ANALOG
|
STICK2,
|
||||||
};
|
STICK3,
|
||||||
#define IS_POT(x) ((x)>=POT_FIRST && (x)<=POT_LAST)
|
STICK4,
|
||||||
#define IS_SLIDER(x) ((x)>=SLIDER1 && (x)<=SLIDER4)
|
POT_FIRST,
|
||||||
extern uint16_t adcValues[NUMBER_ANALOG];
|
POT1 = POT_FIRST,
|
||||||
void adcInit(void);
|
POT2,
|
||||||
void adcRead(void);
|
POT3,
|
||||||
uint16_t getAnalogValue(uint8_t index);
|
POT_LAST = POT3,
|
||||||
uint16_t getBatteryVoltage(); // returns current battery voltage in 10mV steps
|
SLIDER1,
|
||||||
|
SLIDER2,
|
||||||
#if defined(__cplusplus) && !defined(SIMU)
|
SLIDER3,
|
||||||
extern "C" {
|
SLIDER4,
|
||||||
#endif
|
TX_VOLTAGE,
|
||||||
|
MOUSE1,
|
||||||
// Power driver
|
MOUSE2,
|
||||||
void pwrInit(void);
|
NUMBER_ANALOG
|
||||||
uint32_t pwrCheck(void);
|
};
|
||||||
void pwrOn(void);
|
#define IS_POT(x) ((x)>=POT_FIRST && (x)<=POT_LAST)
|
||||||
void pwrOff(void);
|
#define IS_SLIDER(x) ((x)>=SLIDER1 && (x)<=SLIDER4)
|
||||||
void pwrResetHandler(void);
|
extern uint16_t adcValues[NUMBER_ANALOG];
|
||||||
uint32_t pwrPressed(void);
|
void adcInit(void);
|
||||||
uint32_t pwrPressedDuration(void);
|
void adcRead(void);
|
||||||
#define pwroffPressed() pwrPressed()
|
uint16_t getAnalogValue(uint8_t index);
|
||||||
#define UNEXPECTED_SHUTDOWN() (WAS_RESET_BY_WATCHDOG() || g_eeGeneral.unexpectedShutdown)
|
uint16_t getBatteryVoltage(); // returns current battery voltage in 10mV steps
|
||||||
|
|
||||||
// Led driver
|
#if defined(__cplusplus) && !defined(SIMU)
|
||||||
void ledOff(void);
|
extern "C" {
|
||||||
void ledRed(void);
|
#endif
|
||||||
void ledBlue(void);
|
|
||||||
|
// Power driver
|
||||||
// LCD driver
|
void pwrInit(void);
|
||||||
#define LCD_W 480
|
uint32_t pwrCheck(void);
|
||||||
#define LCD_H 272
|
void pwrOn(void);
|
||||||
#define LCD_DEPTH 16
|
void pwrOff(void);
|
||||||
void lcdInit(void);
|
void pwrResetHandler(void);
|
||||||
void lcdRefresh(void);
|
uint32_t pwrPressed(void);
|
||||||
void DMAFillRect(uint16_t * dest, uint16_t destw, uint16_t x, uint16_t y, uint16_t w, uint16_t h, uint16_t color);
|
uint32_t pwrPressedDuration(void);
|
||||||
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);
|
#define pwroffPressed() pwrPressed()
|
||||||
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);
|
#if defined(SIMU)
|
||||||
void DMABitmapConvert(uint16_t * dest, const uint8_t * src, uint16_t w, uint16_t h, uint32_t format);
|
#define UNEXPECTED_SHUTDOWN() (false)
|
||||||
void lcdStoreBackupBuffer(void);
|
#else
|
||||||
int lcdRestoreBackupBuffer(void);
|
#define UNEXPECTED_SHUTDOWN() (powerupReason == DIRTY_SHUTDOWN)
|
||||||
void lcdSetContrast();
|
#endif
|
||||||
#define lcdOff(...)
|
|
||||||
#define lcdSetRefVolt(...)
|
// Led driver
|
||||||
#define lcdRefreshWait(...)
|
void ledOff(void);
|
||||||
|
void ledRed(void);
|
||||||
// Backlight driver
|
void ledBlue(void);
|
||||||
void backlightInit(void);
|
|
||||||
#if defined(SIMU)
|
// LCD driver
|
||||||
#define backlightEnable(...)
|
#define LCD_W 480
|
||||||
#else
|
#define LCD_H 272
|
||||||
void backlightEnable(uint8_t dutyCycle);
|
#define LCD_DEPTH 16
|
||||||
#endif
|
void lcdInit(void);
|
||||||
#define BACKLIGHT_ENABLE() backlightEnable(unexpectedShutdown ? 100 : 100-g_eeGeneral.backlightBright)
|
void lcdRefresh(void);
|
||||||
#define BACKLIGHT_DISABLE() backlightEnable(unexpectedShutdown ? 100 : g_eeGeneral.blOffBright)
|
void DMAFillRect(uint16_t * dest, uint16_t destw, uint16_t x, uint16_t y, uint16_t w, uint16_t h, uint16_t color);
|
||||||
#define isBacklightEnabled() true
|
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);
|
||||||
// USB driver
|
void DMABitmapConvert(uint16_t * dest, const uint8_t * src, uint16_t w, uint16_t h, uint32_t format);
|
||||||
int usbPlugged(void);
|
void lcdStoreBackupBuffer(void);
|
||||||
void usbInit(void);
|
int lcdRestoreBackupBuffer(void);
|
||||||
void usbStart(void);
|
void lcdSetContrast();
|
||||||
void usbStop(void);
|
#define lcdOff(...)
|
||||||
void usbSerialPutc(uint8_t c);
|
#define lcdSetRefVolt(...)
|
||||||
#define USB_NAME "FrSky Horus"
|
#define lcdRefreshWait(...)
|
||||||
#define USB_MANUFACTURER 'F', 'r', 'S', 'k', 'y', ' ', ' ', ' ' /* 8 bytes */
|
|
||||||
#define USB_PRODUCT 'H', 'o', 'r', 'u', 's', ' ', ' ', ' ' /* 8 Bytes */
|
// Backlight driver
|
||||||
|
void backlightInit(void);
|
||||||
#if defined(__cplusplus) && !defined(SIMU)
|
#if defined(SIMU)
|
||||||
}
|
#define backlightEnable(...)
|
||||||
#endif
|
#else
|
||||||
|
void backlightEnable(uint8_t dutyCycle);
|
||||||
// Audio driver
|
#endif
|
||||||
void audioInit(void);
|
#define BACKLIGHT_ENABLE() backlightEnable(unexpectedShutdown ? 100 : 100-g_eeGeneral.backlightBright)
|
||||||
void audioConsumeCurrentBuffer(void);
|
#define BACKLIGHT_DISABLE() backlightEnable(unexpectedShutdown ? 100 : g_eeGeneral.blOffBright)
|
||||||
#define audioDisableIrq() // interrupts must stay enabled on Horus
|
#define isBacklightEnabled() true
|
||||||
#define audioEnableIrq() // interrupts must stay enabled on Horus
|
|
||||||
#define setSampleRate(freq)
|
// USB driver
|
||||||
void setScaledVolume(uint8_t volume);
|
int usbPlugged(void);
|
||||||
void setVolume(uint8_t volume);
|
void usbInit(void);
|
||||||
int32_t getVolume(void);
|
void usbStart(void);
|
||||||
#define VOLUME_LEVEL_MAX 23
|
void usbStop(void);
|
||||||
#define VOLUME_LEVEL_DEF 12
|
void usbSerialPutc(uint8_t c);
|
||||||
|
#define USB_NAME "FrSky Horus"
|
||||||
// Telemetry driver
|
#define USB_MANUFACTURER 'F', 'r', 'S', 'k', 'y', ' ', ' ', ' ' /* 8 bytes */
|
||||||
#define TELEMETRY_FIFO_SIZE 512
|
#define USB_PRODUCT 'H', 'o', 'r', 'u', 's', ' ', ' ', ' ' /* 8 Bytes */
|
||||||
void telemetryPortInit(uint32_t baudrate, uint8_t mode);
|
|
||||||
void telemetryPortSetDirectionOutput(void);
|
#if defined(__cplusplus) && !defined(SIMU)
|
||||||
void sportSendBuffer(uint8_t * buffer, uint32_t count);
|
}
|
||||||
uint8_t telemetryGetByte(uint8_t * byte);
|
#endif
|
||||||
|
|
||||||
// Haptic driver
|
// Audio driver
|
||||||
void hapticInit(void);
|
void audioInit(void);
|
||||||
void hapticDone(void);
|
void audioConsumeCurrentBuffer(void);
|
||||||
void hapticOff(void);
|
#define audioDisableIrq() // interrupts must stay enabled on Horus
|
||||||
#define HAPTIC_OFF() hapticOff()
|
#define audioEnableIrq() // interrupts must stay enabled on Horus
|
||||||
void hapticOn(uint32_t pwmPercent);
|
#define setSampleRate(freq)
|
||||||
|
void setScaledVolume(uint8_t volume);
|
||||||
// GPS driver
|
void setVolume(uint8_t volume);
|
||||||
void gpsInit(uint32_t baudrate);
|
int32_t getVolume(void);
|
||||||
uint8_t gpsGetByte(uint8_t * byte);
|
#define VOLUME_LEVEL_MAX 23
|
||||||
#if defined(DEBUG)
|
#define VOLUME_LEVEL_DEF 12
|
||||||
extern uint8_t gpsTraceEnabled;
|
|
||||||
#endif
|
// Telemetry driver
|
||||||
void gpsSendByte(uint8_t byte);
|
#define TELEMETRY_FIFO_SIZE 512
|
||||||
|
void telemetryPortInit(uint32_t baudrate, uint8_t mode);
|
||||||
// Second serial port driver
|
void telemetryPortSetDirectionOutput(void);
|
||||||
#define SERIAL2
|
void sportSendBuffer(uint8_t * buffer, uint32_t count);
|
||||||
#define DEBUG_BAUDRATE 115200
|
uint8_t telemetryGetByte(uint8_t * byte);
|
||||||
extern uint8_t serial2Mode;
|
|
||||||
void serial2Init(unsigned int mode, unsigned int protocol);
|
// Haptic driver
|
||||||
void serial2Putc(char c);
|
void hapticInit(void);
|
||||||
#define serial2TelemetryInit(protocol) serial2Init(UART_MODE_TELEMETRY, protocol)
|
void hapticDone(void);
|
||||||
void serial2SbusInit(void);
|
void hapticOff(void);
|
||||||
void serial2Stop(void);
|
#define HAPTIC_OFF() hapticOff()
|
||||||
#define USART_FLAG_ERRORS (USART_FLAG_ORE | USART_FLAG_NE | USART_FLAG_FE | USART_FLAG_PE)
|
void hapticOn(uint32_t pwmPercent);
|
||||||
int sbusGetByte(uint8_t * byte);
|
|
||||||
|
// GPS driver
|
||||||
// BT driver
|
void gpsInit(uint32_t baudrate);
|
||||||
#define BLUETOOTH_DEFAULT_BAUDRATE 115200
|
uint8_t gpsGetByte(uint8_t * byte);
|
||||||
#define BLUETOOTH_FACTORY_BAUDRATE 9600
|
#if defined(DEBUG)
|
||||||
uint8_t bluetoothReady(void);
|
extern uint8_t gpsTraceEnabled;
|
||||||
void bluetoothInit(uint32_t baudrate);
|
#endif
|
||||||
void bluetoothWrite(const void * buffer, int len);
|
void gpsSendByte(uint8_t byte);
|
||||||
void bluetoothWriteString(const char * str);
|
|
||||||
int bluetoothRead(void * buffer, int len);
|
// Second serial port driver
|
||||||
void bluetoothWakeup(void);
|
#define SERIAL2
|
||||||
void bluetoothDone(void);
|
#define DEBUG_BAUDRATE 115200
|
||||||
|
extern uint8_t serial2Mode;
|
||||||
#if defined(USB_JOYSTICK) && !defined(SIMU)
|
void serial2Init(unsigned int mode, unsigned int protocol);
|
||||||
void usbJoystickUpdate(void);
|
void serial2Putc(char c);
|
||||||
#endif
|
#define serial2TelemetryInit(protocol) serial2Init(UART_MODE_TELEMETRY, protocol)
|
||||||
|
void serial2SbusInit(void);
|
||||||
extern uint8_t currentTrainerMode;
|
void serial2Stop(void);
|
||||||
void checkTrainerSettings(void);
|
#define USART_FLAG_ERRORS (USART_FLAG_ORE | USART_FLAG_NE | USART_FLAG_FE | USART_FLAG_PE)
|
||||||
|
int sbusGetByte(uint8_t * byte);
|
||||||
#if defined(__cplusplus)
|
|
||||||
#include "fifo.h"
|
// BT driver
|
||||||
#include "dmafifo.h"
|
#define BLUETOOTH_DEFAULT_BAUDRATE 115200
|
||||||
extern DMAFifo<512> telemetryFifo;
|
#define BLUETOOTH_FACTORY_BAUDRATE 9600
|
||||||
extern DMAFifo<32> serial2RxFifo;
|
uint8_t bluetoothReady(void);
|
||||||
#endif
|
void bluetoothInit(uint32_t baudrate);
|
||||||
|
void bluetoothWrite(const void * buffer, int len);
|
||||||
|
void bluetoothWriteString(const char * str);
|
||||||
#endif // _BOARD_HORUS_H_
|
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_
|
||||||
|
|
|
@ -308,7 +308,7 @@ DRESULT disk_ioctl (
|
||||||
|
|
||||||
// TODO everything here should not be in the driver layer ...
|
// 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)
|
#if defined(LOG_TELEMETRY)
|
||||||
FIL g_telemetryFile = {};
|
FIL g_telemetryFile = {};
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -21,6 +21,10 @@
|
||||||
#include "pwr.h"
|
#include "pwr.h"
|
||||||
#include "board.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()
|
void pwrInit()
|
||||||
{
|
{
|
||||||
GPIO_InitTypeDef GPIO_InitStructure;
|
GPIO_InitTypeDef GPIO_InitStructure;
|
||||||
|
@ -70,6 +74,8 @@ void pwrInit()
|
||||||
void pwrOn()
|
void pwrOn()
|
||||||
{
|
{
|
||||||
GPIO_SetBits(PWR_GPIO, PWR_ON_GPIO_PIN);
|
GPIO_SetBits(PWR_GPIO, PWR_ON_GPIO_PIN);
|
||||||
|
shutdownRequest = NO_SHUTDOWN_REQUEST;
|
||||||
|
shutdownReason = DIRTY_SHUTDOWN;
|
||||||
}
|
}
|
||||||
|
|
||||||
void pwrOff()
|
void pwrOff()
|
||||||
|
@ -87,6 +93,8 @@ void pwrOff()
|
||||||
// Shutdown the Haptic
|
// Shutdown the Haptic
|
||||||
hapticDone();
|
hapticDone();
|
||||||
|
|
||||||
|
shutdownRequest = SHUTDOWN_REQUEST;
|
||||||
|
shutdownReason = NORMAL_POWER_OFF;
|
||||||
GPIO_ResetBits(PWR_GPIO, PWR_ON_GPIO_PIN);
|
GPIO_ResetBits(PWR_GPIO, PWR_ON_GPIO_PIN);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -104,13 +112,28 @@ void pwrResetHandler()
|
||||||
__ASM volatile ("nop");
|
__ASM volatile ("nop");
|
||||||
__ASM volatile ("nop");
|
__ASM volatile ("nop");
|
||||||
|
|
||||||
// Turn soft power ON now, but only if we got started because of the watchdog
|
// We get here whether we are powering up normally, we had an unexpected reboot or we have just powered down normally.
|
||||||
// or software reset. If the radio was started by user pressing the power button
|
// We want:
|
||||||
// then that button is providing power and we don't need to enable it here.
|
// - 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
|
// shutdownRequest is used to handle the 3rd case. If we really powered down on purpose this will still be set to SHUTDOWN_REQUEST
|
||||||
// power on/off loop after being powered off by the user. (issue #2790)
|
// 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().
|
||||||
if (WAS_RESET_BY_WATCHDOG_OR_SOFTWARE()) {
|
// 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_InitTypeDef GPIO_InitStructure;
|
||||||
GPIO_InitStructure.GPIO_Pin = PWR_ON_GPIO_PIN;
|
GPIO_InitStructure.GPIO_Pin = PWR_ON_GPIO_PIN;
|
||||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
|
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
|
||||||
|
@ -119,6 +142,10 @@ void pwrResetHandler()
|
||||||
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
|
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
|
||||||
GPIO_Init(PWR_GPIO, &GPIO_InitStructure);
|
GPIO_Init(PWR_GPIO, &GPIO_InitStructure);
|
||||||
|
|
||||||
|
if (shutdownReason == DIRTY_SHUTDOWN) {
|
||||||
|
powerupReason = DIRTY_SHUTDOWN;
|
||||||
|
}
|
||||||
|
|
||||||
pwrOn();
|
pwrOn();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -127,6 +127,13 @@ SECTIONS
|
||||||
_ebss = .; /* define a global symbol at bss end */
|
_ebss = .; /* define a global symbol at bss end */
|
||||||
} >CCM
|
} >CCM
|
||||||
|
|
||||||
|
/* Non-zeroed data section */
|
||||||
|
. = ALIGN(4);
|
||||||
|
.noinit (NOLOAD) :
|
||||||
|
{
|
||||||
|
*(.noinit)
|
||||||
|
} >CCM
|
||||||
|
|
||||||
/* collect all uninitialized .ccm sections */
|
/* collect all uninitialized .ccm sections */
|
||||||
.ram (NOLOAD) :
|
.ram (NOLOAD) :
|
||||||
{
|
{
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue