feat: H7 support (#5738)
Co-authored-by: Richard Li <richard.li@ces.hk> Co-authored-by: philmoz <phil.a.mitchell@gmail.com> Co-authored-by: raphaelcoeffic <1050031+raphaelcoeffic@users.noreply.github.com>
This commit is contained in:
co-authored by
Richard Li
philmoz
raphaelcoeffic
parent
5a15ffb017
commit
3d25c2a0f8
@@ -15,3 +15,7 @@
|
||||
path = radio/src/thirdparty/lvgl
|
||||
url = https://github.com/EdgeTX/lvgl.git
|
||||
branch = release/v8.2
|
||||
[submodule "radio/src/thirdparty/uf2"]
|
||||
path = radio/src/thirdparty/uf2
|
||||
url = https://github.com/microsoft/uf2.git
|
||||
shallow = true
|
||||
|
||||
@@ -57,7 +57,11 @@ option(BOOTLOADER "Include Bootloader" ON)
|
||||
option(FWDRIVE "Attach also firmware drive with USB" OFF)
|
||||
option(DISABLE_MCUCHECK "Disable MCU check at start" OFF)
|
||||
option(LUA_MIXER "Enable LUA mixer/model scripts support" ON)
|
||||
option(USBJ_EX "Enable USB Joystick Extension" ON)
|
||||
if(PCB STREQUAL X9D+ AND PCBREV STREQUAL 2019)
|
||||
option(USBJ_EX "Enable USB Joystick Extension" OFF)
|
||||
else()
|
||||
option(USBJ_EX "Enable USB Joystick Extension" ON)
|
||||
endif()
|
||||
|
||||
# since we reset all default CMAKE compiler flags for firmware builds, provide an alternate way for user to specify additional flags.
|
||||
set(FIRMWARE_C_FLAGS "" CACHE STRING "Additional flags for firmware target c compiler (note: all CMAKE_C_FLAGS[_*] are ignored for firmware/bootloader).")
|
||||
@@ -79,6 +83,8 @@ elseif(PCB STREQUAL NV14)
|
||||
include(targets/nv14/CMakeLists.txt)
|
||||
elseif(PCB STREQUAL PL18)
|
||||
include(targets/pl18/CMakeLists.txt)
|
||||
elseif(PCB STREQUAL STM32H7S78_DK)
|
||||
include(targets/stm32h7s78-dk/CMakeLists.txt)
|
||||
elseif(PCB STREQUAL X9E OR PCB STREQUAL X9D+ OR PCB STREQUAL X9D OR PCB STREQUAL X7 OR PCB STREQUAL X9LITE OR PCB STREQUAL X9LITES OR PCB STREQUAL XLITE OR PCB STREQUAL XLITES)
|
||||
include(targets/taranis/CMakeLists.txt)
|
||||
else()
|
||||
@@ -96,7 +102,7 @@ include(hal/CMakeLists.txt)
|
||||
add_subdirectory(bitmaps)
|
||||
add_subdirectory(fonts)
|
||||
|
||||
if(CPU_TYPE STREQUAL STM32H7)
|
||||
if(CPU_TYPE STREQUAL STM32H7 OR CPU_TYPE STREQUAL STM32H7RS)
|
||||
include(targets/common/arm/stm32/h7/CMakeLists.txt)
|
||||
endif()
|
||||
|
||||
@@ -119,6 +125,10 @@ endif()
|
||||
|
||||
include_directories(targets/${TARGET_DIR} ${THIRDPARTY_DIR})
|
||||
|
||||
if(NATIVE_BUILD)
|
||||
include_directories(targets/simu)
|
||||
endif()
|
||||
|
||||
foreach(LANGUAGE ${RADIO_LANGUAGES})
|
||||
if(TRANSLATIONS STREQUAL ${LANGUAGE})
|
||||
add_definitions(-DTRANSLATIONS_${LANGUAGE} -DTRANSLATIONS="${LANGUAGE}")
|
||||
@@ -544,8 +554,10 @@ if(DEBUG)
|
||||
target_compile_definitions(stm32_drivers_w_dbg_fw PRIVATE -DDEBUG)
|
||||
endif()
|
||||
|
||||
set(LINKER_SCRIPT firmware.ld)
|
||||
|
||||
target_link_options(firmware PRIVATE
|
||||
-lm -T${LINKER_DIR}/firmware.ld
|
||||
-lm -T${LINKER_DIR}/${LINKER_SCRIPT}
|
||||
-Wl,-Map=firmware.map,--cref,--no-warn-mismatch,--gc-sections
|
||||
--specs=nano.specs
|
||||
)
|
||||
@@ -592,11 +604,24 @@ else()
|
||||
message("-- Bootloader contained in firmware binary")
|
||||
endif()
|
||||
|
||||
if(FIRMWARE_FORMAT_UF2)
|
||||
add_custom_command(
|
||||
TARGET firmware POST_BUILD
|
||||
COMMAND ${PYTHON_EXECUTABLE} ${RADIO_DIRECTORY}/util/elf2uf2.py
|
||||
--reboot auto --device "${FLAVOUR}"
|
||||
--version "edgetx-${VERSION}-${VERSION_SUFFIX} (${GIT_STR})"
|
||||
-i firmware.elf firmware.uf2
|
||||
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
|
||||
VERBATIM
|
||||
)
|
||||
endif()
|
||||
|
||||
add_custom_command(
|
||||
TARGET firmware POST_BUILD
|
||||
COMMAND ${CMAKE_OBJCOPY} -O binary ${OBJCOPY_ARGS} firmware.elf firmware.bin
|
||||
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
|
||||
)
|
||||
|
||||
|
||||
find_program(GAWK gawk
|
||||
HINTS "c:/cygwin/bin/" "c:/msys/bin/"
|
||||
|
||||
@@ -62,9 +62,9 @@
|
||||
|
||||
#define STR_MULTI_DEFAULT QT_TRANSLATE_NOOP("Multiprotocols", "DEFAULT")
|
||||
STRLIST(NO_SUBTYPE, {STR_MULTI_DEFAULT})
|
||||
#else
|
||||
#elif defined(MULTIMODULE)
|
||||
#define STRLIST(x, ...) const char* const x[] = __VA_ARGS__;
|
||||
#define PROTODEF const mm_protocol_definition multi_protocols[]
|
||||
#define PROTODEF(...) const mm_protocol_definition multi_protocols[] = __VA_ARGS__
|
||||
|
||||
const char* const mm_options_strings::options[] = {
|
||||
nullptr,
|
||||
@@ -81,6 +81,9 @@
|
||||
};
|
||||
|
||||
#define NO_SUBTYPE nullptr
|
||||
#else
|
||||
#define STRLIST(x, ...)
|
||||
#define PROTODEF(...)
|
||||
#endif
|
||||
|
||||
//
|
||||
@@ -161,7 +164,7 @@ STRLIST(STR_SUBTYPE_NN, { SPARE_SUBTYPE_NAMES })
|
||||
// failsafe support yes/no, channel map disabled yes/no, reference to the suptype options strings above
|
||||
// and further protocol options, e.g. RF tune, video frequency.
|
||||
//
|
||||
PROTODEF {
|
||||
PROTODEF ({
|
||||
{MODULE_SUBTYPE_MULTI_FLYSKY, 4, false, true, STR_SUBTYPE_FLYSKY, nullptr},
|
||||
{MODULE_SUBTYPE_MULTI_HUBSAN, 2, false, false, STR_SUBTYPE_HUBSAN, STR_MULTI_VIDFREQ},
|
||||
{MODULE_SUBTYPE_MULTI_FRSKY, 1, false, false, STR_SUBTYPE_FRSKYD, STR_MULTI_RFTUNE},
|
||||
@@ -273,6 +276,6 @@ PROTODEF {
|
||||
|
||||
// Sentinel and default for protocols not listed above (MM_RF_CUSTOM is 0xff)
|
||||
{MODULE_SUBTYPE_MULTI_SENTINEL, 0, false, false, NO_SUBTYPE, nullptr},
|
||||
};
|
||||
});
|
||||
|
||||
#endif // MULTIMODULE
|
||||
|
||||
+12
-12
@@ -92,19 +92,19 @@ class BinAllocator
|
||||
};
|
||||
|
||||
#if defined(SIMU)
|
||||
typedef BinAllocator<40,300> BinAllocator_slots1;
|
||||
typedef BinAllocator<80,100> BinAllocator_slots2;
|
||||
#elif defined(CCMRAM)
|
||||
#if defined(DEBUG)
|
||||
typedef BinAllocator<28,400> BinAllocator_slots1;
|
||||
typedef BinAllocator<92,90> BinAllocator_slots2;
|
||||
typedef BinAllocator<40,300> BinAllocator_slots1;
|
||||
typedef BinAllocator<80,100> BinAllocator_slots2;
|
||||
#elif defined(STM32F4)
|
||||
#if defined(DEBUG)
|
||||
typedef BinAllocator<28,395> BinAllocator_slots1;
|
||||
typedef BinAllocator<92,85> BinAllocator_slots2;
|
||||
#else
|
||||
typedef BinAllocator<28,415> BinAllocator_slots1;
|
||||
typedef BinAllocator<92,98> BinAllocator_slots2;
|
||||
#endif
|
||||
#else
|
||||
typedef BinAllocator<28,415> BinAllocator_slots1;
|
||||
typedef BinAllocator<92,98> BinAllocator_slots2;
|
||||
#endif
|
||||
#else
|
||||
typedef BinAllocator<28,200> BinAllocator_slots1;
|
||||
typedef BinAllocator<92,50> BinAllocator_slots2;
|
||||
typedef BinAllocator<28,200> BinAllocator_slots1;
|
||||
typedef BinAllocator<92,50> BinAllocator_slots2;
|
||||
#endif
|
||||
|
||||
BinAllocator_slots1 slots1;
|
||||
|
||||
@@ -8,6 +8,8 @@ elseif(PCB STREQUAL PL18)
|
||||
set(BITMAP_TARGET_PREFIX pl18)
|
||||
elseif(PCB STREQUAL X12S)
|
||||
set(BITMAP_TARGET_PREFIX x12s)
|
||||
elseif(PCB STREQUAL STM32H7S78_DK)
|
||||
set(BITMAP_TARGET_PREFIX h7rs)
|
||||
else()
|
||||
set(BITMAP_TARGET_PREFIX x10)
|
||||
endif()
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright (C) EdgeTX
|
||||
*
|
||||
* Based on code named
|
||||
* opentx - https://github.com/opentx/opentx
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
struct VersionTag
|
||||
{
|
||||
char flavour[12];
|
||||
char full_version[44];
|
||||
const char* version;
|
||||
const char* fork;
|
||||
};
|
||||
|
||||
// Ensure flavour can hold FLAVOUR defined in target cmakefile
|
||||
static_assert(sizeof(((VersionTag){}).flavour) >= sizeof(FLAVOUR),
|
||||
"VersionTag flavour size too small");
|
||||
@@ -7,13 +7,25 @@ INCLUDE definitions.ld
|
||||
/* Define output sections */
|
||||
SECTIONS
|
||||
{
|
||||
/* The startup code goes first into FLASH */
|
||||
/* ISR vector to be loaded */
|
||||
.isr_vector :
|
||||
{
|
||||
_sisr_vector = .;
|
||||
KEEP(*(.isr_vector))
|
||||
|
||||
. = ALIGN(4);
|
||||
_eisr_vector = .;
|
||||
} > REGION_ISR_VECT AT> REGION_TEXT_STORAGE
|
||||
|
||||
_isr_load = LOADADDR(.isr_vector);
|
||||
|
||||
/* The program code and other data goes into FLASH */
|
||||
.text :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
KEEP(*(.isr_vector)) /* Startup code */
|
||||
FILL(0xFFFF)
|
||||
CREATE_OBJECT_SYMBOLS
|
||||
|
||||
_stext = .;
|
||||
KEEP(*(.version))
|
||||
KEEP(*(.bootversiondata))
|
||||
|
||||
@@ -21,7 +33,9 @@ SECTIONS
|
||||
|
||||
. = ALIGN(4);
|
||||
_etext = .; /* define a global symbols at end of code */
|
||||
} >FLASH
|
||||
} > REGION_TEXT AT> REGION_TEXT_STORAGE
|
||||
|
||||
_text_load = LOADADDR(.text);
|
||||
|
||||
INCLUDE common_sections.ld
|
||||
}
|
||||
|
||||
@@ -12,11 +12,11 @@
|
||||
PROVIDE(__exidx_end = .);
|
||||
} > REGION_TEXT AT> REGION_TEXT_STORAGE
|
||||
|
||||
.reboot_buffer(NOLOAD) :
|
||||
/* Bootstrap code to load ISR vector and code sections */
|
||||
.bootstrap :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
*(.reboot*)
|
||||
} > REGION_DATA
|
||||
*(.bootstrap)
|
||||
} > REGION_TEXT_STORAGE
|
||||
|
||||
/* Initialized data sections goes into RAM, load LMA copy after code */
|
||||
.data :
|
||||
@@ -32,7 +32,7 @@
|
||||
_sidata = LOADADDR(.data);
|
||||
|
||||
/* Uninitialized data section */
|
||||
.bss(NOLOAD) :
|
||||
.bss(NOLOAD) : AT (ADDR(.bss))
|
||||
{
|
||||
. = ALIGN(4);
|
||||
/* This is used by the startup in order to initialize the .bss secion */
|
||||
@@ -43,8 +43,8 @@ _sidata = LOADADDR(.data);
|
||||
_ebss = .; /* define a global symbol at bss end */
|
||||
} > REGION_BSS
|
||||
|
||||
/* collect all uninitialized .ram sections (force DMA accessible) */
|
||||
.ram (NOLOAD) :
|
||||
/* collect all uninitialized .ram sections */
|
||||
.ram (NOLOAD) : AT (ADDR(.ram))
|
||||
{
|
||||
. = ALIGN(4);
|
||||
_sram = .;
|
||||
@@ -55,6 +55,12 @@ _sidata = LOADADDR(.data);
|
||||
|
||||
INCLUDE extra_sections.ld
|
||||
|
||||
/* Seems to be the safest place for all targets (see AN2606) */
|
||||
.reboot_buffer (ORIGIN(REGION_DATA) + LENGTH(REGION_DATA) - 4) (NOLOAD) : AT (ADDR(.reboot_buffer))
|
||||
{
|
||||
KEEP(*(.reboot*))
|
||||
} > REGION_DATA
|
||||
|
||||
/* Remove information from the standard libraries */
|
||||
/DISCARD/ :
|
||||
{
|
||||
|
||||
@@ -9,13 +9,21 @@ SECTIONS
|
||||
{
|
||||
.bootloader :
|
||||
{
|
||||
FILL(0xFFFF)
|
||||
KEEP(*(.bootloader))
|
||||
. = BOOTLOADER_SIZE;
|
||||
} > REGION_BOOTLOADER
|
||||
|
||||
/* Used only with H7 */
|
||||
.firmware_header :
|
||||
{
|
||||
KEEP(*(.fwdescription))
|
||||
} > REGION_TEXT AT> REGION_TEXT_STORAGE
|
||||
|
||||
/* ISR vector to be loaded */
|
||||
.isr_vector :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
_sisr_vector = .;
|
||||
KEEP(*(.isr_vector))
|
||||
|
||||
@@ -42,11 +50,9 @@ SECTIONS
|
||||
|
||||
_text_load = LOADADDR(.text);
|
||||
|
||||
/* Firmware bootstrap code to load ISR vector and code sections */
|
||||
.bootstrap :
|
||||
{
|
||||
*(.bootstrap)
|
||||
} > REGION_TEXT_STORAGE
|
||||
|
||||
INCLUDE common_sections.ld
|
||||
|
||||
.text_end_section : {} > REGION_TEXT AT > REGION_TEXT_STORAGE
|
||||
_firmware_length = LOADADDR(.text_end_section) - LOADADDR(.firmware_header);
|
||||
_firmware_version = _text_load;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
/* SDRAM definitions */
|
||||
SDRAM_START = DEFINED(__SDRAM_START__) ? __SDRAM_START__ : 0xC0000000;
|
||||
SDRAM_SIZE = DEFINED(__SDRAM_SIZE__) ? __SDRAM_SIZE__ : 8192K;
|
||||
|
||||
/* Highest heap address */
|
||||
HEAP_ADDRESS = SDRAM_START + SDRAM_SIZE;
|
||||
|
||||
/* Highest address of the user mode stack */
|
||||
STACK_ADDRESS = ORIGIN(DTCMRAM) + LENGTH(DTCMRAM) - 16; /* end of RAM */
|
||||
|
||||
/* Maximum bootloader code size */
|
||||
BOOTLOADER_SIZE = 0x20000;
|
||||
|
||||
/* Required amount of stack for interrupt stack (Main stack) */
|
||||
MAIN_STACK_SIZE = 8192;
|
||||
|
||||
/* Generate a link error if heap and stack don't fit into RAM */
|
||||
MIN_HEAP_SIZE = 4096k; /* required amount of heap */
|
||||
|
||||
/* Specify the memory areas */
|
||||
MEMORY
|
||||
{
|
||||
FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 128K
|
||||
ITCMRAM (xrw) : ORIGIN = 0x00000000, LENGTH = 64K
|
||||
DTCMRAM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K
|
||||
RAM_D1 (xrw) : ORIGIN = 0x24000000, LENGTH = 512K
|
||||
RAM_D2 (xrw) : ORIGIN = 0x30000000, LENGTH = 288K
|
||||
RAM_D3 (xrw) : ORIGIN = 0x38000000, LENGTH = 64K
|
||||
SDRAM (rwx) : ORIGIN = SDRAM_START, LENGTH = SDRAM_SIZE
|
||||
}
|
||||
|
||||
REGION_ALIAS("REGION_TEXT_STORAGE", FLASH);
|
||||
REGION_ALIAS("REGION_TEXT", FLASH);
|
||||
REGION_ALIAS("REGION_DATA", DTCMRAM);
|
||||
REGION_ALIAS("REGION_BSS", RAM_D1);
|
||||
REGION_ALIAS("REGION_RAM", RAM_D1);
|
||||
@@ -0,0 +1,58 @@
|
||||
|
||||
/* Task stacks */
|
||||
.ccm (NOLOAD) :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
_sccm = .;
|
||||
*(.ccm)
|
||||
. = ALIGN(4);
|
||||
_eccm = .;
|
||||
} > DTCMRAM
|
||||
|
||||
/* Reserve stack space */
|
||||
.stack (NOLOAD) :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
. = . + MAIN_STACK_SIZE;
|
||||
. = ALIGN(4);
|
||||
} > DTCMRAM
|
||||
|
||||
/* Fast code */
|
||||
.iram (NOLOAD) :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
_siram = .;
|
||||
*(.iram)
|
||||
. = ALIGN(4);
|
||||
_eiram = .;
|
||||
} > ITCMRAM AT> REGION_TEXT_STORAGE
|
||||
|
||||
_stext_iram = LOADADDR(.iram);
|
||||
|
||||
/* Extra DMA section */
|
||||
.dram (NOLOAD) :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
_s_dram = .;
|
||||
*(.dram)
|
||||
. = ALIGN(4);
|
||||
_e_dram = .;
|
||||
} > RAM_D2
|
||||
|
||||
.sdram (NOLOAD) :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
*(.sdram)
|
||||
*(.sdram*)
|
||||
*(.sdram_rodata)
|
||||
*(.sdram_rodata*)
|
||||
|
||||
. = ALIGN(4);
|
||||
_esdram = .;
|
||||
|
||||
/* Reserve heap space in RAM */
|
||||
. = . + MIN_HEAP_SIZE;
|
||||
. = ALIGN(4);
|
||||
} > SDRAM
|
||||
|
||||
PROVIDE(_heap_start = _esdram);
|
||||
@@ -0,0 +1,40 @@
|
||||
/* SDRAM definitions */
|
||||
SDRAM_START = DEFINED(__SDRAM_START__) ? __SDRAM_START__ : 0xC0000000;
|
||||
SDRAM_SIZE = DEFINED(__SDRAM_SIZE__) ? __SDRAM_SIZE__ : 8192K;
|
||||
|
||||
/* Highest heap address */
|
||||
HEAP_ADDRESS = SDRAM_START + SDRAM_SIZE;
|
||||
|
||||
/* Highest address of the user mode stack */
|
||||
STACK_ADDRESS = ORIGIN(DTCMRAM) + LENGTH(DTCMRAM); /* end of RAM */
|
||||
|
||||
/* Maximum bootloader code size */
|
||||
BOOTLOADER_SIZE = 0x20000;
|
||||
|
||||
/* Required amount of stack for interrupt stack (Main stack) */
|
||||
MAIN_STACK_SIZE = 8192;
|
||||
|
||||
/* Generate a link error if heap and stack don't fit into RAM */
|
||||
MIN_HEAP_SIZE = 4096k; /* required amount of heap */
|
||||
/*_Min_Stack_Size = 0x400; /* required amount of stack */
|
||||
|
||||
/* Specify the memory areas */
|
||||
MEMORY
|
||||
{
|
||||
FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 128K
|
||||
ITCMRAM (xrw) : ORIGIN = 0x00000000, LENGTH = 64K
|
||||
DTCMRAM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K
|
||||
RAM_D1 (xrw) : ORIGIN = 0x24000000, LENGTH = 512K
|
||||
RAM_D2 (xrw) : ORIGIN = 0x30000000, LENGTH = 288K
|
||||
RAM_D3 (xrw) : ORIGIN = 0x38000000, LENGTH = 64K
|
||||
SDRAM (rwx) : ORIGIN = SDRAM_START, LENGTH = SDRAM_SIZE
|
||||
QSPIFLASH (rx) : ORIGIN = 0x90000000, LENGTH = 8M
|
||||
}
|
||||
|
||||
REGION_ALIAS("REGION_BOOTLOADER", FLASH);
|
||||
REGION_ALIAS("REGION_ISR_VECT", DTCMRAM);
|
||||
REGION_ALIAS("REGION_TEXT_STORAGE", QSPIFLASH);
|
||||
REGION_ALIAS("REGION_TEXT", SDRAM);
|
||||
REGION_ALIAS("REGION_DATA", DTCMRAM);
|
||||
REGION_ALIAS("REGION_BSS", RAM_D1);
|
||||
REGION_ALIAS("REGION_RAM", RAM_D1);
|
||||
@@ -0,0 +1,39 @@
|
||||
/* PSRAM definitions */
|
||||
PSRAM_START = DEFINED(__PSRAM_START__) ? __PSRAM_START__ : 0x90000000;
|
||||
PSRAM_SIZE = DEFINED(__PSRAM_SIZE__) ? __PSRAM_SIZE__ : 32678K;
|
||||
|
||||
NORFLASH_START = 0x70000000;
|
||||
NORFLASH_SIZE = 128M;
|
||||
|
||||
/* Highest heap address */
|
||||
HEAP_ADDRESS = PSRAM_START + PSRAM_SIZE;
|
||||
|
||||
/* Highest address of the user mode stack */
|
||||
STACK_ADDRESS = ORIGIN(DTCMRAM) + LENGTH(DTCMRAM) - 16; /* end of RAM */
|
||||
|
||||
/* Maximum bootloader code size */
|
||||
BOOTLOADER_SIZE = 0x10000;
|
||||
|
||||
/* Required amount of stack for interrupt stack (Main stack) */
|
||||
MAIN_STACK_SIZE = 8192;
|
||||
|
||||
/* Generate a link error if heap and stack don't fit into RAM */
|
||||
MIN_HEAP_SIZE = 4096k; /* required amount of heap */
|
||||
|
||||
/* Specify the memory areas */
|
||||
MEMORY
|
||||
{
|
||||
FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 64K
|
||||
ITCMRAM (xrw) : ORIGIN = 0x00000000, LENGTH = 64K
|
||||
DTCMRAM (xrw) : ORIGIN = 0x20000000, LENGTH = 64K
|
||||
RAM (xrw) : ORIGIN = 0x24000000, LENGTH = 384K
|
||||
DMA (xrw) : ORIGIN = 0x24060000, LENGTH = 72K
|
||||
PSRAM (rwx) : ORIGIN = PSRAM_START, LENGTH = PSRAM_SIZE
|
||||
}
|
||||
|
||||
REGION_ALIAS("REGION_TEXT_STORAGE", FLASH);
|
||||
REGION_ALIAS("REGION_TEXT", ITCMRAM);
|
||||
REGION_ALIAS("REGION_ISR_VECT", DTCMRAM);
|
||||
REGION_ALIAS("REGION_DATA", RAM);
|
||||
REGION_ALIAS("REGION_BSS", RAM);
|
||||
REGION_ALIAS("REGION_RAM", RAM);
|
||||
@@ -0,0 +1,59 @@
|
||||
|
||||
/* Task stacks */
|
||||
.ccm (NOLOAD) :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
_sccm = .;
|
||||
*(.ccm)
|
||||
. = ALIGN(4);
|
||||
_eccm = .;
|
||||
} > DTCMRAM
|
||||
|
||||
/* Reserve stack space */
|
||||
.stack(NOLOAD) :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
. = . + MAIN_STACK_SIZE;
|
||||
. = ALIGN(4);
|
||||
} > DTCMRAM
|
||||
|
||||
/* Fast code */
|
||||
.iram (NOLOAD) :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
_siram = .;
|
||||
*(.iram)
|
||||
. = ALIGN(4);
|
||||
_eiram = .;
|
||||
} > ITCMRAM AT> REGION_TEXT_STORAGE
|
||||
|
||||
_stext_iram = LOADADDR(.iram);
|
||||
|
||||
/* Extra DMA section */
|
||||
.dram (NOLOAD) :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
_s_dram = .;
|
||||
*(.dram)
|
||||
_e_dram = .;
|
||||
} > DMA
|
||||
|
||||
_dram_addr = ADDR(.dram);
|
||||
|
||||
.sdram (NOLOAD) :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
*(.sdram)
|
||||
*(.sdram*)
|
||||
*(.sdram_rodata)
|
||||
*(.sdram_rodata*)
|
||||
|
||||
. = ALIGN(4);
|
||||
_esdram = .;
|
||||
|
||||
/* Reserve heap space in RAM */
|
||||
. = . + MIN_HEAP_SIZE;
|
||||
. = ALIGN(4);
|
||||
} > PSRAM
|
||||
|
||||
PROVIDE(_heap_start = _esdram);
|
||||
@@ -0,0 +1,41 @@
|
||||
/* PSRAM definitions */
|
||||
PSRAM_START = DEFINED(__PSRAM_START__) ? __PSRAM_START__ : 0x90000000;
|
||||
PSRAM_SIZE = DEFINED(__PSRAM_SIZE__) ? __PSRAM_SIZE__ : 32678K;
|
||||
|
||||
NORFLASH_START = 0x70000000;
|
||||
NORFLASH_SIZE = 128M;
|
||||
|
||||
/* Highest heap address */
|
||||
HEAP_ADDRESS = PSRAM_START + PSRAM_SIZE;
|
||||
|
||||
/* Highest address of the user mode stack */
|
||||
STACK_ADDRESS = ORIGIN(DTCMRAM) + LENGTH(DTCMRAM);
|
||||
|
||||
/* Maximum bootloader code size */
|
||||
BOOTLOADER_SIZE = 0x10000;
|
||||
|
||||
/* Required amount of stack for interrupt stack (Main stack) */
|
||||
MAIN_STACK_SIZE = 8192;
|
||||
|
||||
/* Generate a link error if heap and stack don't fit into RAM */
|
||||
MIN_HEAP_SIZE = 4096k; /* required amount of heap */
|
||||
|
||||
/* Specify the memory areas */
|
||||
MEMORY
|
||||
{
|
||||
FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 64K
|
||||
ITCMRAM (xrw) : ORIGIN = 0x00000000, LENGTH = 64K /* SRAM1 = 128K */
|
||||
DTCMRAM (xrw) : ORIGIN = 0x20000000, LENGTH = 64K /* SRAM3 = 128K */
|
||||
RAM (xrw) : ORIGIN = 0x24000000, LENGTH = 384K /* SRAM1 + SRAM2 + SRAM3 */
|
||||
DMA (xrw) : ORIGIN = 0x24060000, LENGTH = 72K /* SRAM4 */
|
||||
PSRAM (rwx) : ORIGIN = PSRAM_START, LENGTH = PSRAM_SIZE
|
||||
NORFLASH (rwx) : ORIGIN = 0x70000000, LENGTH = 128M
|
||||
}
|
||||
|
||||
REGION_ALIAS("REGION_BOOTLOADER", FLASH);
|
||||
REGION_ALIAS("REGION_TEXT_STORAGE", NORFLASH);
|
||||
REGION_ALIAS("REGION_TEXT", PSRAM);
|
||||
REGION_ALIAS("REGION_ISR_VECT", DTCMRAM);
|
||||
REGION_ALIAS("REGION_DATA", RAM);
|
||||
REGION_ALIAS("REGION_BSS", RAM);
|
||||
REGION_ALIAS("REGION_RAM", RAM);
|
||||
@@ -124,30 +124,6 @@ DEFINE_STM32_SOFTSERIAL_PORT(InternalModule, intmoduleTimer);
|
||||
|
||||
#define EXTMODULE_USART_IRQ_PRIORITY 6
|
||||
|
||||
#if defined(EXTMODULE_TX_INVERT_GPIO) && defined(EXTMODULE_RX_INVERT_GPIO)
|
||||
|
||||
#define HAS_EXTMODULE_INVERTERS
|
||||
|
||||
static void _extmod_set_inverted(uint8_t enable)
|
||||
{
|
||||
// In EdgeTX the external module is normally always
|
||||
// inverted, so invert the logic here
|
||||
gpio_write(EXTMODULE_TX_INVERT_GPIO, !enable);
|
||||
gpio_write(EXTMODULE_RX_INVERT_GPIO, !enable);
|
||||
}
|
||||
|
||||
static void _extmod_init_inverter()
|
||||
{
|
||||
gpio_init(EXTMODULE_TX_INVERT_GPIO, GPIO_OUT, GPIO_PIN_SPEED_LOW);
|
||||
gpio_init(EXTMODULE_RX_INVERT_GPIO, GPIO_OUT, GPIO_PIN_SPEED_LOW);
|
||||
|
||||
// this sets the output to idle-low as is
|
||||
// the default in EdgeTX on external module
|
||||
// (historically, most radios work this way)
|
||||
_extmod_set_inverted(false);
|
||||
}
|
||||
#endif
|
||||
|
||||
static const stm32_usart_t extmoduleUSART = {
|
||||
.USARTx = EXTMODULE_USART,
|
||||
.txGPIO = EXTMODULE_TX_GPIO,
|
||||
@@ -167,6 +143,44 @@ static const stm32_usart_t extmoduleUSART = {
|
||||
|
||||
DEFINE_STM32_SERIAL_PORT(ExternalModule, extmoduleUSART, INTMODULE_FIFO_SIZE, 0);
|
||||
|
||||
|
||||
#if (defined(EXTMODULE_TX_INVERT_GPIO) && defined(EXTMODULE_RX_INVERT_GPIO)) \
|
||||
|| defined(STM32H7) || defined(STM32H7RS)
|
||||
|
||||
#define HAS_EXTMODULE_INVERTERS
|
||||
|
||||
static void _extmod_set_inverted(uint8_t enable)
|
||||
{
|
||||
#if defined(STM32H7) || defined(STM32H7RS)
|
||||
#ifdef EXTMODULE_USART
|
||||
stm32_usart_rx_inversion(&extmoduleUSART, !enable);
|
||||
stm32_usart_tx_inversion(&extmoduleUSART, !enable);
|
||||
#else
|
||||
#error no UART to invert
|
||||
#endif
|
||||
#else
|
||||
// In EdgeTX the external module is normally always
|
||||
// inverted, so invert the logic here
|
||||
gpio_write(EXTMODULE_TX_INVERT_GPIO, !enable);
|
||||
gpio_write(EXTMODULE_RX_INVERT_GPIO, !enable);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
static void _extmod_init_inverter()
|
||||
{
|
||||
#if defined(EXTMODULE_TX_INVERT_GPIO) && defined(EXTMODULE_RX_INVERT_GPIO)
|
||||
gpio_init(EXTMODULE_TX_INVERT_GPIO, GPIO_OUT, GPIO_PIN_SPEED_LOW);
|
||||
gpio_init(EXTMODULE_RX_INVERT_GPIO, GPIO_OUT, GPIO_PIN_SPEED_LOW);
|
||||
#endif
|
||||
|
||||
// this sets the output to idle-low as is
|
||||
// the default in EdgeTX on external module
|
||||
// (historically, most radios work this way)
|
||||
_extmod_set_inverted(false);
|
||||
}
|
||||
#endif
|
||||
|
||||
#elif defined(TRAINER_MODULE_SBUS_USART)
|
||||
|
||||
static const stm32_usart_t sbus_trainer_USART = {
|
||||
@@ -269,24 +283,6 @@ static void _set_sport_input(uint8_t enable)
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(TELEMETRY_TX_REV_GPIO) && defined(TELEMETRY_RX_REV_GPIO)
|
||||
|
||||
#define HAS_SPORT_INVERTER
|
||||
|
||||
static void _sport_set_inverted(uint8_t enable)
|
||||
{
|
||||
gpio_write(TELEMETRY_TX_REV_GPIO, !enable);
|
||||
gpio_write(TELEMETRY_RX_REV_GPIO, !enable);
|
||||
}
|
||||
|
||||
static void _sport_init_inverter()
|
||||
{
|
||||
gpio_init(TELEMETRY_TX_REV_GPIO, GPIO_OUT, GPIO_PIN_SPEED_LOW);
|
||||
gpio_init(TELEMETRY_RX_REV_GPIO, GPIO_OUT, GPIO_PIN_SPEED_LOW);
|
||||
_sport_set_inverted(false);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(TELEMETRY_USART)
|
||||
static const stm32_usart_t sportUSART = {
|
||||
.USARTx = TELEMETRY_USART,
|
||||
@@ -300,7 +296,11 @@ static const stm32_usart_t sportUSART = {
|
||||
.rxDMA = nullptr,
|
||||
.rxDMA_Stream = 0,
|
||||
.rxDMA_Channel = 0,
|
||||
#if defined(STM32H7) || (STM32H7RS)
|
||||
.set_input = nullptr,
|
||||
#else
|
||||
.set_input = _set_sport_input,
|
||||
#endif
|
||||
.txDMA_IRQn = TELEMETRY_DMA_TX_Stream_IRQ,
|
||||
.txDMA_IRQ_Prio = TELEMETRY_DMA_IRQ_PRIORITY,
|
||||
};
|
||||
@@ -320,6 +320,34 @@ static void _sport_direction_init()
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
#if (defined(TELEMETRY_TX_REV_GPIO) && defined(TELEMETRY_RX_REV_GPIO)) || defined(STM32H7) || defined(STM32H7RS)
|
||||
|
||||
#define HAS_SPORT_INVERTER
|
||||
|
||||
static void _sport_set_inverted(uint8_t enable)
|
||||
{
|
||||
#if defined(STM32H7) || defined(STM32H7RS)
|
||||
#if defined(TELEMETRY_USART)
|
||||
stm32_usart_rx_inversion(&sportUSART, !enable);
|
||||
stm32_usart_tx_inversion(&sportUSART, !enable);
|
||||
#endif
|
||||
#else
|
||||
gpio_write(TELEMETRY_TX_REV_GPIO, !enable);
|
||||
gpio_write(TELEMETRY_RX_REV_GPIO, !enable);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void _sport_init_inverter()
|
||||
{
|
||||
#if defined(TELEMETRY_TX_REV_GPIO) && defined(TELEMETRY_RX_REV_GPIO)
|
||||
gpio_init(TELEMETRY_TX_REV_GPIO, GPIO_OUT, GPIO_PIN_SPEED_LOW);
|
||||
gpio_init(TELEMETRY_RX_REV_GPIO, GPIO_OUT, GPIO_PIN_SPEED_LOW);
|
||||
#endif
|
||||
_sport_set_inverted(false);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(TELEMETRY_TIMER)
|
||||
static const stm32_softserial_rx_port sportSoftRX = {
|
||||
.GPIO = TELEMETRY_RX_GPIO,
|
||||
|
||||
@@ -55,6 +55,7 @@ uint32_t rgbGetLedColor(uint8_t led)
|
||||
return ws2812_get_color(led);
|
||||
}
|
||||
|
||||
|
||||
bool rgbGetState(uint8_t led)
|
||||
{
|
||||
return ws2812_get_state(led);
|
||||
@@ -79,7 +80,7 @@ void rgbLedStart()
|
||||
xTimerCreateStatic("rgbLed", LED_STRIP_REFRESH_PERIOD / RTOS_MS_PER_TICK, pdTRUE, (void*)0,
|
||||
rgbLedTimerCb, &rgbLedTimerBuffer);
|
||||
}
|
||||
|
||||
|
||||
if (rgbLedTimer) {
|
||||
if( xTimerStart( rgbLedTimer, 0 ) != pdPASS ) {
|
||||
/* The timer could not be set into the Active state. */
|
||||
@@ -127,4 +128,4 @@ extern "C" void LED_STRIP_TIMER_DMA_IRQHandler()
|
||||
ws2812_dma_isr(&_led_timer);
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) EdgeTx
|
||||
* Copyright (C) EdgeTx
|
||||
*
|
||||
* Based on code named
|
||||
* opentx - https://github.com/opentx/opentx
|
||||
@@ -26,4 +26,4 @@ void rgbLedStop();
|
||||
void rgbSetLedColor(unsigned char, unsigned char, unsigned char, unsigned char);
|
||||
uint32_t rgbGetLedColor(uint8_t led);
|
||||
bool rgbGetState(unsigned char);
|
||||
void rgbLedColorApply();
|
||||
void rgbLedColorApply();
|
||||
@@ -0,0 +1,753 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file startup_stm32h750xx.s
|
||||
* @author MCD Application Team
|
||||
* @brief STM32H750xx Devices vector table for GCC based toolchain.
|
||||
* This module performs:
|
||||
* - Set the initial SP
|
||||
* - Set the initial PC == Reset_Handler,
|
||||
* - Set the vector table entries with the exceptions ISR address
|
||||
* - Branches to main in the C library (which eventually
|
||||
* calls main()).
|
||||
* After Reset the Cortex-M processor is in Thread mode,
|
||||
* priority is Privileged, and the Stack is set to Main.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2018 STMicroelectronics.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is licensed under terms that can be found in the LICENSE file
|
||||
* in the root directory of this software component.
|
||||
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
.syntax unified
|
||||
.cpu cortex-m7
|
||||
.fpu softvfp
|
||||
.thumb
|
||||
|
||||
.global g_pfnVectors
|
||||
.global Default_Handler
|
||||
|
||||
/* start address for the initialization values of the .data section.
|
||||
defined in linker script */
|
||||
.word _sidata
|
||||
/* start address for the .data section. defined in linker script */
|
||||
.word _sdata
|
||||
/* end address for the .data section. defined in linker script */
|
||||
.word _edata
|
||||
/* start address for the .bss section. defined in linker script */
|
||||
.word _sbss
|
||||
/* end address for the .bss section. defined in linker script */
|
||||
.word _ebss
|
||||
/* stack used for SystemInit_ExtMemCtl; always internal RAM used */
|
||||
|
||||
/**
|
||||
* @brief This is the code that gets called when the processor first
|
||||
* starts execution following a reset event. Only the absolutely
|
||||
* necessary set is performed, after which the application
|
||||
* supplied main() routine is called.
|
||||
* @param None
|
||||
* @retval : None
|
||||
*/
|
||||
|
||||
.section .text.Reset_Handler
|
||||
.weak Reset_Handler
|
||||
.type Reset_Handler, %function
|
||||
Reset_Handler:
|
||||
ldr sp, =_estack /* set stack pointer */
|
||||
|
||||
/* Call the clock system initialization function.*/
|
||||
bl SystemInit
|
||||
|
||||
/* Copy the data segment initializers from flash to SRAM */
|
||||
ldr r0, =_sdata
|
||||
ldr r1, =_edata
|
||||
ldr r2, =_sidata
|
||||
movs r3, #0
|
||||
b LoopCopyDataInit
|
||||
|
||||
CopyDataInit:
|
||||
ldr r4, [r2, r3]
|
||||
str r4, [r0, r3]
|
||||
adds r3, r3, #4
|
||||
|
||||
LoopCopyDataInit:
|
||||
adds r4, r0, r3
|
||||
cmp r4, r1
|
||||
bcc CopyDataInit
|
||||
/* Zero fill the bss segment. */
|
||||
ldr r2, =_sbss
|
||||
ldr r4, =_ebss
|
||||
movs r3, #0
|
||||
b LoopFillZerobss
|
||||
|
||||
FillZerobss:
|
||||
str r3, [r2]
|
||||
adds r2, r2, #4
|
||||
|
||||
LoopFillZerobss:
|
||||
cmp r2, r4
|
||||
bcc FillZerobss
|
||||
|
||||
/* Call static constructors */
|
||||
bl __libc_init_array
|
||||
/* Call the application's entry point.*/
|
||||
bl main
|
||||
bx lr
|
||||
.size Reset_Handler, .-Reset_Handler
|
||||
|
||||
/**
|
||||
* @brief This is the code that gets called when the processor receives an
|
||||
* unexpected interrupt. This simply enters an infinite loop, preserving
|
||||
* the system state for examination by a debugger.
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
.section .text.Default_Handler,"ax",%progbits
|
||||
Default_Handler:
|
||||
Infinite_Loop:
|
||||
b Infinite_Loop
|
||||
.size Default_Handler, .-Default_Handler
|
||||
/******************************************************************************
|
||||
*
|
||||
* The minimal vector table for a Cortex M. Note that the proper constructs
|
||||
* must be placed on this to ensure that it ends up at physical address
|
||||
* 0x0000.0000.
|
||||
*
|
||||
*******************************************************************************/
|
||||
.section .isr_vector,"a",%progbits
|
||||
.type g_pfnVectors, %object
|
||||
|
||||
|
||||
g_pfnVectors:
|
||||
.word _estack
|
||||
.word Reset_Handler
|
||||
|
||||
.word NMI_Handler
|
||||
.word HardFault_Handler
|
||||
.word MemManage_Handler
|
||||
.word BusFault_Handler
|
||||
.word UsageFault_Handler
|
||||
.word 0
|
||||
.word 0
|
||||
.word 0
|
||||
.word 0
|
||||
.word SVC_Handler
|
||||
.word DebugMon_Handler
|
||||
.word 0
|
||||
.word PendSV_Handler
|
||||
.word SysTick_Handler
|
||||
|
||||
.size g_pfnVectors, .-g_pfnVectors
|
||||
|
||||
/* External Interrupts */
|
||||
.word WWDG_IRQHandler /* Window WatchDog */
|
||||
.word PVD_AVD_IRQHandler /* PVD/AVD through EXTI Line detection */
|
||||
.word TAMP_STAMP_IRQHandler /* Tamper and TimeStamps through the EXTI line */
|
||||
.word RTC_WKUP_IRQHandler /* RTC Wakeup through the EXTI line */
|
||||
.word FLASH_IRQHandler /* FLASH */
|
||||
.word RCC_IRQHandler /* RCC */
|
||||
.word EXTI0_IRQHandler /* EXTI Line0 */
|
||||
.word EXTI1_IRQHandler /* EXTI Line1 */
|
||||
.word EXTI2_IRQHandler /* EXTI Line2 */
|
||||
.word EXTI3_IRQHandler /* EXTI Line3 */
|
||||
.word EXTI4_IRQHandler /* EXTI Line4 */
|
||||
.word DMA1_Stream0_IRQHandler /* DMA1 Stream 0 */
|
||||
.word DMA1_Stream1_IRQHandler /* DMA1 Stream 1 */
|
||||
.word DMA1_Stream2_IRQHandler /* DMA1 Stream 2 */
|
||||
.word DMA1_Stream3_IRQHandler /* DMA1 Stream 3 */
|
||||
.word DMA1_Stream4_IRQHandler /* DMA1 Stream 4 */
|
||||
.word DMA1_Stream5_IRQHandler /* DMA1 Stream 5 */
|
||||
.word DMA1_Stream6_IRQHandler /* DMA1 Stream 6 */
|
||||
.word ADC_IRQHandler /* ADC1, ADC2 and ADC3s */
|
||||
.word FDCAN1_IT0_IRQHandler /* FDCAN1 interrupt line 0 */
|
||||
.word FDCAN2_IT0_IRQHandler /* FDCAN2 interrupt line 0 */
|
||||
.word FDCAN1_IT1_IRQHandler /* FDCAN1 interrupt line 1 */
|
||||
.word FDCAN2_IT1_IRQHandler /* FDCAN2 interrupt line 1 */
|
||||
.word EXTI9_5_IRQHandler /* External Line[9:5]s */
|
||||
.word TIM1_BRK_IRQHandler /* TIM1 Break interrupt */
|
||||
.word TIM1_UP_IRQHandler /* TIM1 Update interrupt */
|
||||
.word TIM1_TRG_COM_IRQHandler /* TIM1 Trigger and Commutation interrupt */
|
||||
.word TIM1_CC_IRQHandler /* TIM1 Capture Compare */
|
||||
.word TIM2_IRQHandler /* TIM2 */
|
||||
.word TIM3_IRQHandler /* TIM3 */
|
||||
.word TIM4_IRQHandler /* TIM4 */
|
||||
.word I2C1_EV_IRQHandler /* I2C1 Event */
|
||||
.word I2C1_ER_IRQHandler /* I2C1 Error */
|
||||
.word I2C2_EV_IRQHandler /* I2C2 Event */
|
||||
.word I2C2_ER_IRQHandler /* I2C2 Error */
|
||||
.word SPI1_IRQHandler /* SPI1 */
|
||||
.word SPI2_IRQHandler /* SPI2 */
|
||||
.word USART1_IRQHandler /* USART1 */
|
||||
.word USART2_IRQHandler /* USART2 */
|
||||
.word USART3_IRQHandler /* USART3 */
|
||||
.word EXTI15_10_IRQHandler /* External Line[15:10]s */
|
||||
.word RTC_Alarm_IRQHandler /* RTC Alarm (A and B) through EXTI Line */
|
||||
.word 0 /* Reserved */
|
||||
.word TIM8_BRK_TIM12_IRQHandler /* TIM8 Break and TIM12 */
|
||||
.word TIM8_UP_TIM13_IRQHandler /* TIM8 Update and TIM13 */
|
||||
.word TIM8_TRG_COM_TIM14_IRQHandler /* TIM8 Trigger and Commutation and TIM14 */
|
||||
.word TIM8_CC_IRQHandler /* TIM8 Capture Compare */
|
||||
.word DMA1_Stream7_IRQHandler /* DMA1 Stream7 */
|
||||
.word FMC_IRQHandler /* FMC */
|
||||
.word SDMMC1_IRQHandler /* SDMMC1 */
|
||||
.word TIM5_IRQHandler /* TIM5 */
|
||||
.word SPI3_IRQHandler /* SPI3 */
|
||||
.word UART4_IRQHandler /* UART4 */
|
||||
.word UART5_IRQHandler /* UART5 */
|
||||
.word TIM6_DAC_IRQHandler /* TIM6 and DAC1&2 underrun errors */
|
||||
.word TIM7_IRQHandler /* TIM7 */
|
||||
.word DMA2_Stream0_IRQHandler /* DMA2 Stream 0 */
|
||||
.word DMA2_Stream1_IRQHandler /* DMA2 Stream 1 */
|
||||
.word DMA2_Stream2_IRQHandler /* DMA2 Stream 2 */
|
||||
.word DMA2_Stream3_IRQHandler /* DMA2 Stream 3 */
|
||||
.word DMA2_Stream4_IRQHandler /* DMA2 Stream 4 */
|
||||
.word ETH_IRQHandler /* Ethernet */
|
||||
.word ETH_WKUP_IRQHandler /* Ethernet Wakeup through EXTI line */
|
||||
.word FDCAN_CAL_IRQHandler /* FDCAN calibration unit interrupt*/
|
||||
.word 0 /* Reserved */
|
||||
.word 0 /* Reserved */
|
||||
.word 0 /* Reserved */
|
||||
.word 0 /* Reserved */
|
||||
.word DMA2_Stream5_IRQHandler /* DMA2 Stream 5 */
|
||||
.word DMA2_Stream6_IRQHandler /* DMA2 Stream 6 */
|
||||
.word DMA2_Stream7_IRQHandler /* DMA2 Stream 7 */
|
||||
.word USART6_IRQHandler /* USART6 */
|
||||
.word I2C3_EV_IRQHandler /* I2C3 event */
|
||||
.word I2C3_ER_IRQHandler /* I2C3 error */
|
||||
.word OTG_HS_EP1_OUT_IRQHandler /* USB OTG HS End Point 1 Out */
|
||||
.word OTG_HS_EP1_IN_IRQHandler /* USB OTG HS End Point 1 In */
|
||||
.word OTG_HS_WKUP_IRQHandler /* USB OTG HS Wakeup through EXTI */
|
||||
.word OTG_HS_IRQHandler /* USB OTG HS */
|
||||
.word DCMI_IRQHandler /* DCMI */
|
||||
.word CRYP_IRQHandler /* Crypto */
|
||||
.word HASH_RNG_IRQHandler /* Hash and Rng */
|
||||
.word FPU_IRQHandler /* FPU */
|
||||
.word UART7_IRQHandler /* UART7 */
|
||||
.word UART8_IRQHandler /* UART8 */
|
||||
.word SPI4_IRQHandler /* SPI4 */
|
||||
.word SPI5_IRQHandler /* SPI5 */
|
||||
.word SPI6_IRQHandler /* SPI6 */
|
||||
.word SAI1_IRQHandler /* SAI1 */
|
||||
.word LTDC_IRQHandler /* LTDC */
|
||||
.word LTDC_ER_IRQHandler /* LTDC error */
|
||||
.word DMA2D_IRQHandler /* DMA2D */
|
||||
.word SAI2_IRQHandler /* SAI2 */
|
||||
.word QUADSPI_IRQHandler /* QUADSPI */
|
||||
.word LPTIM1_IRQHandler /* LPTIM1 */
|
||||
.word CEC_IRQHandler /* HDMI_CEC */
|
||||
.word I2C4_EV_IRQHandler /* I2C4 Event */
|
||||
.word I2C4_ER_IRQHandler /* I2C4 Error */
|
||||
.word SPDIF_RX_IRQHandler /* SPDIF_RX */
|
||||
.word OTG_FS_EP1_OUT_IRQHandler /* USB OTG FS End Point 1 Out */
|
||||
.word OTG_FS_EP1_IN_IRQHandler /* USB OTG FS End Point 1 In */
|
||||
.word OTG_FS_WKUP_IRQHandler /* USB OTG FS Wakeup through EXTI */
|
||||
.word OTG_FS_IRQHandler /* USB OTG FS */
|
||||
.word DMAMUX1_OVR_IRQHandler /* DMAMUX1 Overrun interrupt */
|
||||
.word HRTIM1_Master_IRQHandler /* HRTIM Master Timer global Interrupt */
|
||||
.word HRTIM1_TIMA_IRQHandler /* HRTIM Timer A global Interrupt */
|
||||
.word HRTIM1_TIMB_IRQHandler /* HRTIM Timer B global Interrupt */
|
||||
.word HRTIM1_TIMC_IRQHandler /* HRTIM Timer C global Interrupt */
|
||||
.word HRTIM1_TIMD_IRQHandler /* HRTIM Timer D global Interrupt */
|
||||
.word HRTIM1_TIME_IRQHandler /* HRTIM Timer E global Interrupt */
|
||||
.word HRTIM1_FLT_IRQHandler /* HRTIM Fault global Interrupt */
|
||||
.word DFSDM1_FLT0_IRQHandler /* DFSDM Filter0 Interrupt */
|
||||
.word DFSDM1_FLT1_IRQHandler /* DFSDM Filter1 Interrupt */
|
||||
.word DFSDM1_FLT2_IRQHandler /* DFSDM Filter2 Interrupt */
|
||||
.word DFSDM1_FLT3_IRQHandler /* DFSDM Filter3 Interrupt */
|
||||
.word SAI3_IRQHandler /* SAI3 global Interrupt */
|
||||
.word SWPMI1_IRQHandler /* Serial Wire Interface 1 global interrupt */
|
||||
.word TIM15_IRQHandler /* TIM15 global Interrupt */
|
||||
.word TIM16_IRQHandler /* TIM16 global Interrupt */
|
||||
.word TIM17_IRQHandler /* TIM17 global Interrupt */
|
||||
.word MDIOS_WKUP_IRQHandler /* MDIOS Wakeup Interrupt */
|
||||
.word MDIOS_IRQHandler /* MDIOS global Interrupt */
|
||||
.word JPEG_IRQHandler /* JPEG global Interrupt */
|
||||
.word MDMA_IRQHandler /* MDMA global Interrupt */
|
||||
.word 0 /* Reserved */
|
||||
.word SDMMC2_IRQHandler /* SDMMC2 global Interrupt */
|
||||
.word HSEM1_IRQHandler /* HSEM1 global Interrupt */
|
||||
.word 0 /* Reserved */
|
||||
.word ADC3_IRQHandler /* ADC3 global Interrupt */
|
||||
.word DMAMUX2_OVR_IRQHandler /* DMAMUX Overrun interrupt */
|
||||
.word BDMA_Channel0_IRQHandler /* BDMA Channel 0 global Interrupt */
|
||||
.word BDMA_Channel1_IRQHandler /* BDMA Channel 1 global Interrupt */
|
||||
.word BDMA_Channel2_IRQHandler /* BDMA Channel 2 global Interrupt */
|
||||
.word BDMA_Channel3_IRQHandler /* BDMA Channel 3 global Interrupt */
|
||||
.word BDMA_Channel4_IRQHandler /* BDMA Channel 4 global Interrupt */
|
||||
.word BDMA_Channel5_IRQHandler /* BDMA Channel 5 global Interrupt */
|
||||
.word BDMA_Channel6_IRQHandler /* BDMA Channel 6 global Interrupt */
|
||||
.word BDMA_Channel7_IRQHandler /* BDMA Channel 7 global Interrupt */
|
||||
.word COMP1_IRQHandler /* COMP1 global Interrupt */
|
||||
.word LPTIM2_IRQHandler /* LP TIM2 global interrupt */
|
||||
.word LPTIM3_IRQHandler /* LP TIM3 global interrupt */
|
||||
.word LPTIM4_IRQHandler /* LP TIM4 global interrupt */
|
||||
.word LPTIM5_IRQHandler /* LP TIM5 global interrupt */
|
||||
.word LPUART1_IRQHandler /* LP UART1 interrupt */
|
||||
.word 0 /* Reserved */
|
||||
.word CRS_IRQHandler /* Clock Recovery Global Interrupt */
|
||||
.word ECC_IRQHandler /* ECC diagnostic Global Interrupt */
|
||||
.word SAI4_IRQHandler /* SAI4 global interrupt */
|
||||
.word 0 /* Reserved */
|
||||
.word 0 /* Reserved */
|
||||
.word WAKEUP_PIN_IRQHandler /* Interrupt for all 6 wake-up pins */
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Provide weak aliases for each Exception handler to the Default_Handler.
|
||||
* As they are weak aliases, any function with the same name will override
|
||||
* this definition.
|
||||
*
|
||||
*******************************************************************************/
|
||||
.weak NMI_Handler
|
||||
.thumb_set NMI_Handler,Default_Handler
|
||||
|
||||
.weak HardFault_Handler
|
||||
.thumb_set HardFault_Handler,Default_Handler
|
||||
|
||||
.weak MemManage_Handler
|
||||
.thumb_set MemManage_Handler,Default_Handler
|
||||
|
||||
.weak BusFault_Handler
|
||||
.thumb_set BusFault_Handler,Default_Handler
|
||||
|
||||
.weak UsageFault_Handler
|
||||
.thumb_set UsageFault_Handler,Default_Handler
|
||||
|
||||
.weak SVC_Handler
|
||||
.thumb_set SVC_Handler,Default_Handler
|
||||
|
||||
.weak DebugMon_Handler
|
||||
.thumb_set DebugMon_Handler,Default_Handler
|
||||
|
||||
.weak PendSV_Handler
|
||||
.thumb_set PendSV_Handler,Default_Handler
|
||||
|
||||
.weak SysTick_Handler
|
||||
.thumb_set SysTick_Handler,Default_Handler
|
||||
|
||||
.weak WWDG_IRQHandler
|
||||
.thumb_set WWDG_IRQHandler,Default_Handler
|
||||
|
||||
.weak PVD_AVD_IRQHandler
|
||||
.thumb_set PVD_AVD_IRQHandler,Default_Handler
|
||||
|
||||
.weak TAMP_STAMP_IRQHandler
|
||||
.thumb_set TAMP_STAMP_IRQHandler,Default_Handler
|
||||
|
||||
.weak RTC_WKUP_IRQHandler
|
||||
.thumb_set RTC_WKUP_IRQHandler,Default_Handler
|
||||
|
||||
.weak FLASH_IRQHandler
|
||||
.thumb_set FLASH_IRQHandler,Default_Handler
|
||||
|
||||
.weak RCC_IRQHandler
|
||||
.thumb_set RCC_IRQHandler,Default_Handler
|
||||
|
||||
.weak EXTI0_IRQHandler
|
||||
.thumb_set EXTI0_IRQHandler,Default_Handler
|
||||
|
||||
.weak EXTI1_IRQHandler
|
||||
.thumb_set EXTI1_IRQHandler,Default_Handler
|
||||
|
||||
.weak EXTI2_IRQHandler
|
||||
.thumb_set EXTI2_IRQHandler,Default_Handler
|
||||
|
||||
.weak EXTI3_IRQHandler
|
||||
.thumb_set EXTI3_IRQHandler,Default_Handler
|
||||
|
||||
.weak EXTI4_IRQHandler
|
||||
.thumb_set EXTI4_IRQHandler,Default_Handler
|
||||
|
||||
.weak DMA1_Stream0_IRQHandler
|
||||
.thumb_set DMA1_Stream0_IRQHandler,Default_Handler
|
||||
|
||||
.weak DMA1_Stream1_IRQHandler
|
||||
.thumb_set DMA1_Stream1_IRQHandler,Default_Handler
|
||||
|
||||
.weak DMA1_Stream2_IRQHandler
|
||||
.thumb_set DMA1_Stream2_IRQHandler,Default_Handler
|
||||
|
||||
.weak DMA1_Stream3_IRQHandler
|
||||
.thumb_set DMA1_Stream3_IRQHandler,Default_Handler
|
||||
|
||||
.weak DMA1_Stream4_IRQHandler
|
||||
.thumb_set DMA1_Stream4_IRQHandler,Default_Handler
|
||||
|
||||
.weak DMA1_Stream5_IRQHandler
|
||||
.thumb_set DMA1_Stream5_IRQHandler,Default_Handler
|
||||
|
||||
.weak DMA1_Stream6_IRQHandler
|
||||
.thumb_set DMA1_Stream6_IRQHandler,Default_Handler
|
||||
|
||||
.weak ADC_IRQHandler
|
||||
.thumb_set ADC_IRQHandler,Default_Handler
|
||||
|
||||
.weak FDCAN1_IT0_IRQHandler
|
||||
.thumb_set FDCAN1_IT0_IRQHandler,Default_Handler
|
||||
|
||||
.weak FDCAN2_IT0_IRQHandler
|
||||
.thumb_set FDCAN2_IT0_IRQHandler,Default_Handler
|
||||
|
||||
.weak FDCAN1_IT1_IRQHandler
|
||||
.thumb_set FDCAN1_IT1_IRQHandler,Default_Handler
|
||||
|
||||
.weak FDCAN2_IT1_IRQHandler
|
||||
.thumb_set FDCAN2_IT1_IRQHandler,Default_Handler
|
||||
|
||||
.weak EXTI9_5_IRQHandler
|
||||
.thumb_set EXTI9_5_IRQHandler,Default_Handler
|
||||
|
||||
.weak TIM1_BRK_IRQHandler
|
||||
.thumb_set TIM1_BRK_IRQHandler,Default_Handler
|
||||
|
||||
.weak TIM1_UP_IRQHandler
|
||||
.thumb_set TIM1_UP_IRQHandler,Default_Handler
|
||||
|
||||
.weak TIM1_TRG_COM_IRQHandler
|
||||
.thumb_set TIM1_TRG_COM_IRQHandler,Default_Handler
|
||||
|
||||
.weak TIM1_CC_IRQHandler
|
||||
.thumb_set TIM1_CC_IRQHandler,Default_Handler
|
||||
|
||||
.weak TIM2_IRQHandler
|
||||
.thumb_set TIM2_IRQHandler,Default_Handler
|
||||
|
||||
.weak TIM3_IRQHandler
|
||||
.thumb_set TIM3_IRQHandler,Default_Handler
|
||||
|
||||
.weak TIM4_IRQHandler
|
||||
.thumb_set TIM4_IRQHandler,Default_Handler
|
||||
|
||||
.weak I2C1_EV_IRQHandler
|
||||
.thumb_set I2C1_EV_IRQHandler,Default_Handler
|
||||
|
||||
.weak I2C1_ER_IRQHandler
|
||||
.thumb_set I2C1_ER_IRQHandler,Default_Handler
|
||||
|
||||
.weak I2C2_EV_IRQHandler
|
||||
.thumb_set I2C2_EV_IRQHandler,Default_Handler
|
||||
|
||||
.weak I2C2_ER_IRQHandler
|
||||
.thumb_set I2C2_ER_IRQHandler,Default_Handler
|
||||
|
||||
.weak SPI1_IRQHandler
|
||||
.thumb_set SPI1_IRQHandler,Default_Handler
|
||||
|
||||
.weak SPI2_IRQHandler
|
||||
.thumb_set SPI2_IRQHandler,Default_Handler
|
||||
|
||||
.weak USART1_IRQHandler
|
||||
.thumb_set USART1_IRQHandler,Default_Handler
|
||||
|
||||
.weak USART2_IRQHandler
|
||||
.thumb_set USART2_IRQHandler,Default_Handler
|
||||
|
||||
.weak USART3_IRQHandler
|
||||
.thumb_set USART3_IRQHandler,Default_Handler
|
||||
|
||||
.weak EXTI15_10_IRQHandler
|
||||
.thumb_set EXTI15_10_IRQHandler,Default_Handler
|
||||
|
||||
.weak RTC_Alarm_IRQHandler
|
||||
.thumb_set RTC_Alarm_IRQHandler,Default_Handler
|
||||
|
||||
.weak TIM8_BRK_TIM12_IRQHandler
|
||||
.thumb_set TIM8_BRK_TIM12_IRQHandler,Default_Handler
|
||||
|
||||
.weak TIM8_UP_TIM13_IRQHandler
|
||||
.thumb_set TIM8_UP_TIM13_IRQHandler,Default_Handler
|
||||
|
||||
.weak TIM8_TRG_COM_TIM14_IRQHandler
|
||||
.thumb_set TIM8_TRG_COM_TIM14_IRQHandler,Default_Handler
|
||||
|
||||
.weak TIM8_CC_IRQHandler
|
||||
.thumb_set TIM8_CC_IRQHandler,Default_Handler
|
||||
|
||||
.weak DMA1_Stream7_IRQHandler
|
||||
.thumb_set DMA1_Stream7_IRQHandler,Default_Handler
|
||||
|
||||
.weak FMC_IRQHandler
|
||||
.thumb_set FMC_IRQHandler,Default_Handler
|
||||
|
||||
.weak SDMMC1_IRQHandler
|
||||
.thumb_set SDMMC1_IRQHandler,Default_Handler
|
||||
|
||||
.weak TIM5_IRQHandler
|
||||
.thumb_set TIM5_IRQHandler,Default_Handler
|
||||
|
||||
.weak SPI3_IRQHandler
|
||||
.thumb_set SPI3_IRQHandler,Default_Handler
|
||||
|
||||
.weak UART4_IRQHandler
|
||||
.thumb_set UART4_IRQHandler,Default_Handler
|
||||
|
||||
.weak UART5_IRQHandler
|
||||
.thumb_set UART5_IRQHandler,Default_Handler
|
||||
|
||||
.weak TIM6_DAC_IRQHandler
|
||||
.thumb_set TIM6_DAC_IRQHandler,Default_Handler
|
||||
|
||||
.weak TIM7_IRQHandler
|
||||
.thumb_set TIM7_IRQHandler,Default_Handler
|
||||
|
||||
.weak DMA2_Stream0_IRQHandler
|
||||
.thumb_set DMA2_Stream0_IRQHandler,Default_Handler
|
||||
|
||||
.weak DMA2_Stream1_IRQHandler
|
||||
.thumb_set DMA2_Stream1_IRQHandler,Default_Handler
|
||||
|
||||
.weak DMA2_Stream2_IRQHandler
|
||||
.thumb_set DMA2_Stream2_IRQHandler,Default_Handler
|
||||
|
||||
.weak DMA2_Stream3_IRQHandler
|
||||
.thumb_set DMA2_Stream3_IRQHandler,Default_Handler
|
||||
|
||||
.weak DMA2_Stream4_IRQHandler
|
||||
.thumb_set DMA2_Stream4_IRQHandler,Default_Handler
|
||||
|
||||
.weak ETH_IRQHandler
|
||||
.thumb_set ETH_IRQHandler,Default_Handler
|
||||
|
||||
.weak ETH_WKUP_IRQHandler
|
||||
.thumb_set ETH_WKUP_IRQHandler,Default_Handler
|
||||
|
||||
.weak FDCAN_CAL_IRQHandler
|
||||
.thumb_set FDCAN_CAL_IRQHandler,Default_Handler
|
||||
|
||||
.weak DMA2_Stream5_IRQHandler
|
||||
.thumb_set DMA2_Stream5_IRQHandler,Default_Handler
|
||||
|
||||
.weak DMA2_Stream6_IRQHandler
|
||||
.thumb_set DMA2_Stream6_IRQHandler,Default_Handler
|
||||
|
||||
.weak DMA2_Stream7_IRQHandler
|
||||
.thumb_set DMA2_Stream7_IRQHandler,Default_Handler
|
||||
|
||||
.weak USART6_IRQHandler
|
||||
.thumb_set USART6_IRQHandler,Default_Handler
|
||||
|
||||
.weak I2C3_EV_IRQHandler
|
||||
.thumb_set I2C3_EV_IRQHandler,Default_Handler
|
||||
|
||||
.weak I2C3_ER_IRQHandler
|
||||
.thumb_set I2C3_ER_IRQHandler,Default_Handler
|
||||
|
||||
.weak OTG_HS_EP1_OUT_IRQHandler
|
||||
.thumb_set OTG_HS_EP1_OUT_IRQHandler,Default_Handler
|
||||
|
||||
.weak OTG_HS_EP1_IN_IRQHandler
|
||||
.thumb_set OTG_HS_EP1_IN_IRQHandler,Default_Handler
|
||||
|
||||
.weak OTG_HS_WKUP_IRQHandler
|
||||
.thumb_set OTG_HS_WKUP_IRQHandler,Default_Handler
|
||||
|
||||
.weak OTG_HS_IRQHandler
|
||||
.thumb_set OTG_HS_IRQHandler,Default_Handler
|
||||
|
||||
.weak DCMI_IRQHandler
|
||||
.thumb_set DCMI_IRQHandler,Default_Handler
|
||||
|
||||
.weak CRYP_IRQHandler
|
||||
.thumb_set CRYP_IRQHandler,Default_Handler
|
||||
|
||||
.weak HASH_RNG_IRQHandler
|
||||
.thumb_set HASH_RNG_IRQHandler,Default_Handler
|
||||
|
||||
.weak FPU_IRQHandler
|
||||
.thumb_set FPU_IRQHandler,Default_Handler
|
||||
|
||||
.weak UART7_IRQHandler
|
||||
.thumb_set UART7_IRQHandler,Default_Handler
|
||||
|
||||
.weak UART8_IRQHandler
|
||||
.thumb_set UART8_IRQHandler,Default_Handler
|
||||
|
||||
.weak SPI4_IRQHandler
|
||||
.thumb_set SPI4_IRQHandler,Default_Handler
|
||||
|
||||
.weak SPI5_IRQHandler
|
||||
.thumb_set SPI5_IRQHandler,Default_Handler
|
||||
|
||||
.weak SPI6_IRQHandler
|
||||
.thumb_set SPI6_IRQHandler,Default_Handler
|
||||
|
||||
.weak SAI1_IRQHandler
|
||||
.thumb_set SAI1_IRQHandler,Default_Handler
|
||||
|
||||
.weak LTDC_IRQHandler
|
||||
.thumb_set LTDC_IRQHandler,Default_Handler
|
||||
|
||||
.weak LTDC_ER_IRQHandler
|
||||
.thumb_set LTDC_ER_IRQHandler,Default_Handler
|
||||
|
||||
.weak DMA2D_IRQHandler
|
||||
.thumb_set DMA2D_IRQHandler,Default_Handler
|
||||
|
||||
.weak SAI2_IRQHandler
|
||||
.thumb_set SAI2_IRQHandler,Default_Handler
|
||||
|
||||
.weak QUADSPI_IRQHandler
|
||||
.thumb_set QUADSPI_IRQHandler,Default_Handler
|
||||
|
||||
.weak LPTIM1_IRQHandler
|
||||
.thumb_set LPTIM1_IRQHandler,Default_Handler
|
||||
|
||||
.weak CEC_IRQHandler
|
||||
.thumb_set CEC_IRQHandler,Default_Handler
|
||||
|
||||
.weak I2C4_EV_IRQHandler
|
||||
.thumb_set I2C4_EV_IRQHandler,Default_Handler
|
||||
|
||||
.weak I2C4_ER_IRQHandler
|
||||
.thumb_set I2C4_ER_IRQHandler,Default_Handler
|
||||
|
||||
.weak SPDIF_RX_IRQHandler
|
||||
.thumb_set SPDIF_RX_IRQHandler,Default_Handler
|
||||
|
||||
.weak OTG_FS_EP1_OUT_IRQHandler
|
||||
.thumb_set OTG_FS_EP1_OUT_IRQHandler,Default_Handler
|
||||
|
||||
.weak OTG_FS_EP1_IN_IRQHandler
|
||||
.thumb_set OTG_FS_EP1_IN_IRQHandler,Default_Handler
|
||||
|
||||
.weak OTG_FS_WKUP_IRQHandler
|
||||
.thumb_set OTG_FS_WKUP_IRQHandler,Default_Handler
|
||||
|
||||
.weak OTG_FS_IRQHandler
|
||||
.thumb_set OTG_FS_IRQHandler,Default_Handler
|
||||
|
||||
.weak DMAMUX1_OVR_IRQHandler
|
||||
.thumb_set DMAMUX1_OVR_IRQHandler,Default_Handler
|
||||
|
||||
.weak HRTIM1_Master_IRQHandler
|
||||
.thumb_set HRTIM1_Master_IRQHandler,Default_Handler
|
||||
|
||||
.weak HRTIM1_TIMA_IRQHandler
|
||||
.thumb_set HRTIM1_TIMA_IRQHandler,Default_Handler
|
||||
|
||||
.weak HRTIM1_TIMB_IRQHandler
|
||||
.thumb_set HRTIM1_TIMB_IRQHandler,Default_Handler
|
||||
|
||||
.weak HRTIM1_TIMC_IRQHandler
|
||||
.thumb_set HRTIM1_TIMC_IRQHandler,Default_Handler
|
||||
|
||||
.weak HRTIM1_TIMD_IRQHandler
|
||||
.thumb_set HRTIM1_TIMD_IRQHandler,Default_Handler
|
||||
|
||||
.weak HRTIM1_TIME_IRQHandler
|
||||
.thumb_set HRTIM1_TIME_IRQHandler,Default_Handler
|
||||
|
||||
.weak HRTIM1_FLT_IRQHandler
|
||||
.thumb_set HRTIM1_FLT_IRQHandler,Default_Handler
|
||||
|
||||
.weak DFSDM1_FLT0_IRQHandler
|
||||
.thumb_set DFSDM1_FLT0_IRQHandler,Default_Handler
|
||||
|
||||
.weak DFSDM1_FLT1_IRQHandler
|
||||
.thumb_set DFSDM1_FLT1_IRQHandler,Default_Handler
|
||||
|
||||
.weak DFSDM1_FLT2_IRQHandler
|
||||
.thumb_set DFSDM1_FLT2_IRQHandler,Default_Handler
|
||||
|
||||
.weak DFSDM1_FLT3_IRQHandler
|
||||
.thumb_set DFSDM1_FLT3_IRQHandler,Default_Handler
|
||||
|
||||
.weak SAI3_IRQHandler
|
||||
.thumb_set SAI3_IRQHandler,Default_Handler
|
||||
|
||||
.weak SWPMI1_IRQHandler
|
||||
.thumb_set SWPMI1_IRQHandler,Default_Handler
|
||||
|
||||
.weak TIM15_IRQHandler
|
||||
.thumb_set TIM15_IRQHandler,Default_Handler
|
||||
|
||||
.weak TIM16_IRQHandler
|
||||
.thumb_set TIM16_IRQHandler,Default_Handler
|
||||
|
||||
.weak TIM17_IRQHandler
|
||||
.thumb_set TIM17_IRQHandler,Default_Handler
|
||||
|
||||
.weak MDIOS_WKUP_IRQHandler
|
||||
.thumb_set MDIOS_WKUP_IRQHandler,Default_Handler
|
||||
|
||||
.weak MDIOS_IRQHandler
|
||||
.thumb_set MDIOS_IRQHandler,Default_Handler
|
||||
|
||||
.weak JPEG_IRQHandler
|
||||
.thumb_set JPEG_IRQHandler,Default_Handler
|
||||
|
||||
.weak MDMA_IRQHandler
|
||||
.thumb_set MDMA_IRQHandler,Default_Handler
|
||||
|
||||
.weak SDMMC2_IRQHandler
|
||||
.thumb_set SDMMC2_IRQHandler,Default_Handler
|
||||
|
||||
.weak HSEM1_IRQHandler
|
||||
.thumb_set HSEM1_IRQHandler,Default_Handler
|
||||
|
||||
.weak ADC3_IRQHandler
|
||||
.thumb_set ADC3_IRQHandler,Default_Handler
|
||||
|
||||
.weak DMAMUX2_OVR_IRQHandler
|
||||
.thumb_set DMAMUX2_OVR_IRQHandler,Default_Handler
|
||||
|
||||
.weak BDMA_Channel0_IRQHandler
|
||||
.thumb_set BDMA_Channel0_IRQHandler,Default_Handler
|
||||
|
||||
.weak BDMA_Channel1_IRQHandler
|
||||
.thumb_set BDMA_Channel1_IRQHandler,Default_Handler
|
||||
|
||||
.weak BDMA_Channel2_IRQHandler
|
||||
.thumb_set BDMA_Channel2_IRQHandler,Default_Handler
|
||||
|
||||
.weak BDMA_Channel3_IRQHandler
|
||||
.thumb_set BDMA_Channel3_IRQHandler,Default_Handler
|
||||
|
||||
.weak BDMA_Channel4_IRQHandler
|
||||
.thumb_set BDMA_Channel4_IRQHandler,Default_Handler
|
||||
|
||||
.weak BDMA_Channel5_IRQHandler
|
||||
.thumb_set BDMA_Channel5_IRQHandler,Default_Handler
|
||||
|
||||
.weak BDMA_Channel6_IRQHandler
|
||||
.thumb_set BDMA_Channel6_IRQHandler,Default_Handler
|
||||
|
||||
.weak BDMA_Channel7_IRQHandler
|
||||
.thumb_set BDMA_Channel7_IRQHandler,Default_Handler
|
||||
|
||||
.weak COMP1_IRQHandler
|
||||
.thumb_set COMP1_IRQHandler,Default_Handler
|
||||
|
||||
.weak LPTIM2_IRQHandler
|
||||
.thumb_set LPTIM2_IRQHandler,Default_Handler
|
||||
|
||||
.weak LPTIM3_IRQHandler
|
||||
.thumb_set LPTIM3_IRQHandler,Default_Handler
|
||||
|
||||
.weak LPTIM4_IRQHandler
|
||||
.thumb_set LPTIM4_IRQHandler,Default_Handler
|
||||
|
||||
.weak LPTIM5_IRQHandler
|
||||
.thumb_set LPTIM5_IRQHandler,Default_Handler
|
||||
|
||||
.weak LPUART1_IRQHandler
|
||||
.thumb_set LPUART1_IRQHandler,Default_Handler
|
||||
|
||||
.weak CRS_IRQHandler
|
||||
.thumb_set CRS_IRQHandler,Default_Handler
|
||||
|
||||
.weak ECC_IRQHandler
|
||||
.thumb_set ECC_IRQHandler,Default_Handler
|
||||
|
||||
.weak SAI4_IRQHandler
|
||||
.thumb_set SAI4_IRQHandler,Default_Handler
|
||||
|
||||
.weak WAKEUP_PIN_IRQHandler
|
||||
.thumb_set WAKEUP_PIN_IRQHandler,Default_Handler
|
||||
|
||||
|
||||
@@ -0,0 +1,780 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file startup_stm32h7s7xx.s
|
||||
* @author MCD Application Team
|
||||
* @brief STM32H7S7xx Devices vector table for GCC toolchain.
|
||||
* This module performs:
|
||||
* - Set the initial SP
|
||||
* - Set the initial PC == Reset_Handler,
|
||||
* - Set the vector table entries with the exceptions ISR address
|
||||
* - Branches to main in the C library (which eventually
|
||||
* calls main()).
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2023 STMicroelectronics.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is licensed under terms that can be found in the LICENSE file
|
||||
* in the root directory of this software component.
|
||||
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
.syntax unified
|
||||
.cpu cortex-m7
|
||||
.fpu softvfp
|
||||
.thumb
|
||||
|
||||
.global g_pfnVectors
|
||||
.global Default_Handler
|
||||
|
||||
/* start address for the initialization values of the .data section.
|
||||
defined in linker script */
|
||||
.word _sidata
|
||||
/* start address for the .data section. defined in linker script */
|
||||
.word _sdata
|
||||
/* end address for the .data section. defined in linker script */
|
||||
.word _edata
|
||||
/* start address for the .bss section. defined in linker script */
|
||||
.word _sbss
|
||||
/* end address for the .bss section. defined in linker script */
|
||||
.word _ebss
|
||||
|
||||
/**
|
||||
* @brief This is the code that gets called when the processor first
|
||||
* starts execution following a reset event. Only the absolutely
|
||||
* necessary set is performed, after which the application
|
||||
* supplied main() routine is called.
|
||||
* @param None
|
||||
* @retval : None
|
||||
*/
|
||||
|
||||
.section .text.Reset_Handler
|
||||
.weak Reset_Handler
|
||||
.type Reset_Handler, %function
|
||||
Reset_Handler:
|
||||
ldr r0, =_estack
|
||||
mov sp, r0 /* set stack pointer */
|
||||
/* Call the clock system initialization function.*/
|
||||
bl SystemInit
|
||||
|
||||
/* Copy the data segment initializers from flash to SRAM */
|
||||
ldr r0, =_sdata
|
||||
ldr r1, =_edata
|
||||
ldr r2, =_sidata
|
||||
movs r3, #0
|
||||
b LoopCopyDataInit
|
||||
|
||||
CopyDataInit:
|
||||
ldr r4, [r2, r3]
|
||||
str r4, [r0, r3]
|
||||
adds r3, r3, #4
|
||||
|
||||
LoopCopyDataInit:
|
||||
adds r4, r0, r3
|
||||
cmp r4, r1
|
||||
bcc CopyDataInit
|
||||
|
||||
/* Zero fill the bss segment. */
|
||||
ldr r2, =_sbss
|
||||
ldr r4, =_ebss
|
||||
movs r3, #0
|
||||
b LoopFillZerobss
|
||||
|
||||
FillZerobss:
|
||||
str r3, [r2]
|
||||
adds r2, r2, #4
|
||||
|
||||
LoopFillZerobss:
|
||||
cmp r2, r4
|
||||
bcc FillZerobss
|
||||
|
||||
/* Call static constructors */
|
||||
bl __libc_init_array
|
||||
/* Call the application's entry point.*/
|
||||
bl main
|
||||
|
||||
LoopForever:
|
||||
b LoopForever
|
||||
|
||||
.size Reset_Handler, .-Reset_Handler
|
||||
|
||||
/**
|
||||
* @brief This is the code that gets called when the processor receives an
|
||||
* unexpected interrupt. This simply enters an infinite loop, preserving
|
||||
* the system state for examination by a debugger.
|
||||
*
|
||||
* @param None
|
||||
* @retval : None
|
||||
*/
|
||||
.section .text.Default_Handler,"ax",%progbits
|
||||
Default_Handler:
|
||||
Infinite_Loop:
|
||||
b Infinite_Loop
|
||||
.size Default_Handler, .-Default_Handler
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* The STM32H7S7xx vector table. Note that the proper constructs
|
||||
* must be placed on this to ensure that it ends up at physical address
|
||||
* 0x0000.0000.
|
||||
*
|
||||
******************************************************************************/
|
||||
.section .isr_vector,"a",%progbits
|
||||
.type g_pfnVectors, %object
|
||||
.size g_pfnVectors, .-g_pfnVectors
|
||||
|
||||
g_pfnVectors:
|
||||
.word _estack
|
||||
.word Reset_Handler
|
||||
.word NMI_Handler
|
||||
.word HardFault_Handler
|
||||
.word MemManage_Handler
|
||||
.word BusFault_Handler
|
||||
.word UsageFault_Handler
|
||||
.word 0
|
||||
.word 0
|
||||
.word 0
|
||||
.word 0
|
||||
.word SVC_Handler
|
||||
.word DebugMon_Handler
|
||||
.word 0
|
||||
.word PendSV_Handler
|
||||
.word SysTick_Handler
|
||||
/* External Interrupts */
|
||||
.word PVD_PVM_IRQHandler /* PVD/PVM through EXTI Line detection */
|
||||
.word 0 /* Reserved */
|
||||
.word DTS_IRQHandler /* Digital Temperature Sensor */
|
||||
.word IWDG_IRQHandler /* Internal Watchdog */
|
||||
.word WWDG_IRQHandler /* Window Watchdog */
|
||||
.word RCC_IRQHandler /* RCC global interrupts through EXTI Line detection */
|
||||
.word 0 /* Reserved */
|
||||
.word 0 /* Reserved */
|
||||
.word FLASH_IRQHandler /* FLASH interrupts */
|
||||
.word RAMECC_IRQHandler /* RAMECC interrupts */
|
||||
.word FPU_IRQHandler /* FPU */
|
||||
.word 0 /* Reserved */
|
||||
.word 0 /* Reserved */
|
||||
.word TAMP_IRQHandler /* Tamper and TimeStamp interrupts */
|
||||
.word 0 /* Reserved */
|
||||
.word 0 /* Reserved */
|
||||
.word EXTI0_IRQHandler /* EXTI Line0 */
|
||||
.word EXTI1_IRQHandler /* EXTI Line1 */
|
||||
.word EXTI2_IRQHandler /* EXTI Line2 */
|
||||
.word EXTI3_IRQHandler /* EXTI Line3 */
|
||||
.word EXTI4_IRQHandler /* EXTI Line4 */
|
||||
.word EXTI5_IRQHandler /* EXTI Line5 */
|
||||
.word EXTI6_IRQHandler /* EXTI Line6 */
|
||||
.word EXTI7_IRQHandler /* EXTI Line7 */
|
||||
.word EXTI8_IRQHandler /* EXTI Line8 */
|
||||
.word EXTI9_IRQHandler /* EXTI Line9 */
|
||||
.word EXTI10_IRQHandler /* EXTI Line10 */
|
||||
.word EXTI11_IRQHandler /* EXTI Line11 */
|
||||
.word EXTI12_IRQHandler /* EXTI Line12 */
|
||||
.word EXTI13_IRQHandler /* EXTI Line13 */
|
||||
.word EXTI14_IRQHandler /* EXTI Line14 */
|
||||
.word EXTI15_IRQHandler /* EXTI Line15 */
|
||||
.word RTC_IRQHandler /* RTC wakeup and alarm interrupts */
|
||||
.word SAES_IRQHandler /* SAES */
|
||||
.word CRYP_IRQHandler /* CRYP */
|
||||
.word PKA_IRQHandler /* PKA */
|
||||
.word HASH_IRQHandler /* HASH */
|
||||
.word RNG_IRQHandler /* RNG */
|
||||
.word ADC1_2_IRQHandler /* ADC1 & ADC2 */
|
||||
.word GPDMA1_Channel0_IRQHandler /* GPDMA1 Channel 0 */
|
||||
.word GPDMA1_Channel1_IRQHandler /* GPDMA1 Channel 1 */
|
||||
.word GPDMA1_Channel2_IRQHandler /* GPDMA1 Channel 2 */
|
||||
.word GPDMA1_Channel3_IRQHandler /* GPDMA1 Channel 3 */
|
||||
.word GPDMA1_Channel4_IRQHandler /* GPDMA1 Channel 4 */
|
||||
.word GPDMA1_Channel5_IRQHandler /* GPDMA1 Channel 5 */
|
||||
.word GPDMA1_Channel6_IRQHandler /* GPDMA1 Channel 6 */
|
||||
.word GPDMA1_Channel7_IRQHandler /* GPDMA1 Channel 7 */
|
||||
.word TIM1_BRK_IRQHandler /* TIM1 Break */
|
||||
.word TIM1_UP_IRQHandler /* TIM1 Update */
|
||||
.word TIM1_TRG_COM_IRQHandler /* TIM1 Trigger and Commutation */
|
||||
.word TIM1_CC_IRQHandler /* TIM1 Capture Compare */
|
||||
.word TIM2_IRQHandler /* TIM2 */
|
||||
.word TIM3_IRQHandler /* TIM3 */
|
||||
.word TIM4_IRQHandler /* TIM4 */
|
||||
.word TIM5_IRQHandler /* TIM5 */
|
||||
.word TIM6_IRQHandler /* TIM6 */
|
||||
.word TIM7_IRQHandler /* TIM7 */
|
||||
.word TIM9_IRQHandler /* TIM9 */
|
||||
.word SPI1_IRQHandler /* SPI1 */
|
||||
.word SPI2_IRQHandler /* SPI2 */
|
||||
.word SPI3_IRQHandler /* SPI3 */
|
||||
.word SPI4_IRQHandler /* SPI4 */
|
||||
.word SPI5_IRQHandler /* SPI5 */
|
||||
.word SPI6_IRQHandler /* SPI6 */
|
||||
.word HPDMA1_Channel0_IRQHandler /* HPDMA1 Channel 0 */
|
||||
.word HPDMA1_Channel1_IRQHandler /* HPDMA1 Channel 1 */
|
||||
.word HPDMA1_Channel2_IRQHandler /* HPDMA1 Channel 2 */
|
||||
.word HPDMA1_Channel3_IRQHandler /* HPDMA1 Channel 3 */
|
||||
.word HPDMA1_Channel4_IRQHandler /* HPDMA1 Channel 4 */
|
||||
.word HPDMA1_Channel5_IRQHandler /* HPDMA1 Channel 5 */
|
||||
.word HPDMA1_Channel6_IRQHandler /* HPDMA1 Channel 6 */
|
||||
.word HPDMA1_Channel7_IRQHandler /* HPDMA1 Channel 7 */
|
||||
.word SAI1_A_IRQHandler /* Serial Audio Interface 1 block A */
|
||||
.word SAI1_B_IRQHandler /* Serial Audio Interface 1 block B */
|
||||
.word SAI2_A_IRQHandler /* Serial Audio Interface 2 block A */
|
||||
.word SAI2_B_IRQHandler /* Serial Audio Interface 2 block B */
|
||||
.word I2C1_EV_IRQHandler /* I2C1 Event */
|
||||
.word I2C1_ER_IRQHandler /* I2C1 Error */
|
||||
.word I2C2_EV_IRQHandler /* I2C2 Event */
|
||||
.word I2C2_ER_IRQHandler /* I2C2 Error */
|
||||
.word I2C3_EV_IRQHandler /* I2C3 Event */
|
||||
.word I2C3_ER_IRQHandler /* I2C3 Error */
|
||||
.word USART1_IRQHandler /* USART1 */
|
||||
.word USART2_IRQHandler /* USART2 */
|
||||
.word USART3_IRQHandler /* USART3 */
|
||||
.word UART4_IRQHandler /* UART4 */
|
||||
.word UART5_IRQHandler /* UART5 */
|
||||
.word UART7_IRQHandler /* UART7 */
|
||||
.word UART8_IRQHandler /* UART8 */
|
||||
.word I3C1_EV_IRQHandler /* I3C1 Event */
|
||||
.word I3C1_ER_IRQHandler /* I3C1 Error */
|
||||
.word OTG_HS_IRQHandler /* USB OTG HS */
|
||||
.word ETH_IRQHandler /* Ethernet */
|
||||
.word CORDIC_IRQHandler /* CORDIC */
|
||||
.word GFXTIM_IRQHandler /* GFXTIM */
|
||||
.word DCMIPP_IRQHandler /* DCMIPP */
|
||||
.word LTDC_IRQHandler /* LTDC */
|
||||
.word LTDC_ER_IRQHandler /* LTDC error */
|
||||
.word DMA2D_IRQHandler /* DMA2D */
|
||||
.word JPEG_IRQHandler /* JPEG */
|
||||
.word GFXMMU_IRQHandler /* GFXMMU */
|
||||
.word I3C1_WKUP_IRQHandler /* I3C1 wakeup */
|
||||
.word MCE1_IRQHandler /* MCE1 */
|
||||
.word MCE2_IRQHandler /* MCE2 */
|
||||
.word MCE3_IRQHandler /* MCE3 */
|
||||
.word XSPI1_IRQHandler /* XSPI1 */
|
||||
.word XSPI2_IRQHandler /* XSPI2 */
|
||||
.word FMC_IRQHandler /* FMC */
|
||||
.word SDMMC1_IRQHandler /* SDMMC1 */
|
||||
.word SDMMC2_IRQHandler /* SDMMC2 */
|
||||
.word 0 /* Reserved */
|
||||
.word 0 /* Reserved */
|
||||
.word OTG_FS_IRQHandler /* USB OTG FS */
|
||||
.word TIM12_IRQHandler /* TIM12 */
|
||||
.word TIM13_IRQHandler /* TIM13 */
|
||||
.word TIM14_IRQHandler /* TIM14 */
|
||||
.word TIM15_IRQHandler /* TIM15 */
|
||||
.word TIM16_IRQHandler /* TIM16 */
|
||||
.word TIM17_IRQHandler /* TIM17 */
|
||||
.word LPTIM1_IRQHandler /* LP TIM1 */
|
||||
.word LPTIM2_IRQHandler /* LP TIM2 */
|
||||
.word LPTIM3_IRQHandler /* LP TIM3 */
|
||||
.word LPTIM4_IRQHandler /* LP TIM4 */
|
||||
.word LPTIM5_IRQHandler /* LP TIM5 */
|
||||
.word SPDIF_RX_IRQHandler /* SPDIF_RX */
|
||||
.word MDIOS_IRQHandler /* MDIOS */
|
||||
.word ADF1_FLT0_IRQHandler /* ADF1 Filter 0 */
|
||||
.word CRS_IRQHandler /* CRS */
|
||||
.word UCPD1_IRQHandler /* UCPD1 */
|
||||
.word CEC_IRQHandler /* HDMI_CEC */
|
||||
.word PSSI_IRQHandler /* PSSI */
|
||||
.word LPUART1_IRQHandler /* LP UART1 */
|
||||
.word WAKEUP_PIN_IRQHandler /* Wake-up pins interrupt */
|
||||
.word GPDMA1_Channel8_IRQHandler /* GPDMA1 Channel 8 */
|
||||
.word GPDMA1_Channel9_IRQHandler /* GPDMA1 Channel 9 */
|
||||
.word GPDMA1_Channel10_IRQHandler /* GPDMA1 Channel 10 */
|
||||
.word GPDMA1_Channel11_IRQHandler /* GPDMA1 Channel 11 */
|
||||
.word GPDMA1_Channel12_IRQHandler /* GPDMA1 Channel 12 */
|
||||
.word GPDMA1_Channel13_IRQHandler /* GPDMA1 Channel 13 */
|
||||
.word GPDMA1_Channel14_IRQHandler /* GPDMA1 Channel 14 */
|
||||
.word GPDMA1_Channel15_IRQHandler /* GPDMA1 Channel 15 */
|
||||
.word HPDMA1_Channel8_IRQHandler /* HPDMA1 Channel 8 */
|
||||
.word HPDMA1_Channel9_IRQHandler /* HPDMA1 Channel 9 */
|
||||
.word HPDMA1_Channel10_IRQHandler /* HPDMA1 Channel 10 */
|
||||
.word HPDMA1_Channel11_IRQHandler /* HPDMA1 Channel 11 */
|
||||
.word HPDMA1_Channel12_IRQHandler /* HPDMA1 Channel 12 */
|
||||
.word HPDMA1_Channel13_IRQHandler /* HPDMA1 Channel 13 */
|
||||
.word HPDMA1_Channel14_IRQHandler /* HPDMA1 Channel 14 */
|
||||
.word HPDMA1_Channel15_IRQHandler /* HPDMA1 Channel 15 */
|
||||
.word GPU2D_IRQHandler /* GPU2D */
|
||||
.word GPU2D_ER_IRQHandler /* GPU2D error */
|
||||
.word ICACHE_IRQHandler /* ICACHE */
|
||||
.word FDCAN1_IT0_IRQHandler /* FDCAN1 Interrupt 0 */
|
||||
.word FDCAN1_IT1_IRQHandler /* FDCAN1 Interrupt 1 */
|
||||
.word FDCAN2_IT0_IRQHandler /* FDCAN2 Interrupt 0 */
|
||||
.word FDCAN2_IT1_IRQHandler /* FDCAN2 Interrupt 1 */
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Provide weak aliases for each Exception handler to the Default_Handler.
|
||||
* As they are weak aliases, any function with the same name will override
|
||||
* this definition.
|
||||
*
|
||||
*******************************************************************************/
|
||||
|
||||
.weak NMI_Handler
|
||||
.thumb_set NMI_Handler,Default_Handler
|
||||
|
||||
.weak HardFault_Handler
|
||||
.thumb_set HardFault_Handler,Default_Handler
|
||||
|
||||
.weak MemManage_Handler
|
||||
.thumb_set MemManage_Handler,Default_Handler
|
||||
|
||||
.weak BusFault_Handler
|
||||
.thumb_set BusFault_Handler,Default_Handler
|
||||
|
||||
.weak UsageFault_Handler
|
||||
.thumb_set UsageFault_Handler,Default_Handler
|
||||
|
||||
.weak SVC_Handler
|
||||
.thumb_set SVC_Handler,Default_Handler
|
||||
|
||||
.weak DebugMon_Handler
|
||||
.thumb_set DebugMon_Handler,Default_Handler
|
||||
|
||||
.weak PendSV_Handler
|
||||
.thumb_set PendSV_Handler,Default_Handler
|
||||
|
||||
.weak SysTick_Handler
|
||||
.thumb_set SysTick_Handler,Default_Handler
|
||||
|
||||
.weak PVD_PVM_IRQHandler
|
||||
.thumb_set PVD_PVM_IRQHandler,Default_Handler
|
||||
|
||||
.weak DTS_IRQHandler
|
||||
.thumb_set DTS_IRQHandler,Default_Handler
|
||||
|
||||
.weak IWDG_IRQHandler
|
||||
.thumb_set IWDG_IRQHandler,Default_Handler
|
||||
|
||||
.weak WWDG_IRQHandler
|
||||
.thumb_set WWDG_IRQHandler,Default_Handler
|
||||
|
||||
.weak RCC_IRQHandler
|
||||
.thumb_set RCC_IRQHandler,Default_Handler
|
||||
|
||||
.weak FLASH_IRQHandler
|
||||
.thumb_set FLASH_IRQHandler,Default_Handler
|
||||
|
||||
.weak RAMECC_IRQHandler
|
||||
.thumb_set RAMECC_IRQHandler,Default_Handler
|
||||
|
||||
.weak FPU_IRQHandler
|
||||
.thumb_set FPU_IRQHandler,Default_Handler
|
||||
|
||||
.weak TAMP_IRQHandler
|
||||
.thumb_set TAMP_IRQHandler,Default_Handler
|
||||
|
||||
.weak EXTI0_IRQHandler
|
||||
.thumb_set EXTI0_IRQHandler,Default_Handler
|
||||
|
||||
.weak EXTI1_IRQHandler
|
||||
.thumb_set EXTI1_IRQHandler,Default_Handler
|
||||
|
||||
.weak EXTI2_IRQHandler
|
||||
.thumb_set EXTI2_IRQHandler,Default_Handler
|
||||
|
||||
.weak EXTI3_IRQHandler
|
||||
.thumb_set EXTI3_IRQHandler,Default_Handler
|
||||
|
||||
.weak EXTI4_IRQHandler
|
||||
.thumb_set EXTI4_IRQHandler,Default_Handler
|
||||
|
||||
.weak EXTI5_IRQHandler
|
||||
.thumb_set EXTI5_IRQHandler,Default_Handler
|
||||
|
||||
.weak EXTI6_IRQHandler
|
||||
.thumb_set EXTI6_IRQHandler,Default_Handler
|
||||
|
||||
.weak EXTI7_IRQHandler
|
||||
.thumb_set EXTI7_IRQHandler,Default_Handler
|
||||
|
||||
.weak EXTI8_IRQHandler
|
||||
.thumb_set EXTI8_IRQHandler,Default_Handler
|
||||
|
||||
.weak EXTI9_IRQHandler
|
||||
.thumb_set EXTI9_IRQHandler,Default_Handler
|
||||
|
||||
.weak EXTI10_IRQHandler
|
||||
.thumb_set EXTI10_IRQHandler,Default_Handler
|
||||
|
||||
.weak EXTI11_IRQHandler
|
||||
.thumb_set EXTI11_IRQHandler,Default_Handler
|
||||
|
||||
.weak EXTI12_IRQHandler
|
||||
.thumb_set EXTI12_IRQHandler,Default_Handler
|
||||
|
||||
.weak EXTI13_IRQHandler
|
||||
.thumb_set EXTI13_IRQHandler,Default_Handler
|
||||
|
||||
.weak EXTI14_IRQHandler
|
||||
.thumb_set EXTI14_IRQHandler,Default_Handler
|
||||
|
||||
.weak EXTI15_IRQHandler
|
||||
.thumb_set EXTI15_IRQHandler,Default_Handler
|
||||
|
||||
.weak RTC_IRQHandler
|
||||
.thumb_set RTC_IRQHandler,Default_Handler
|
||||
|
||||
.weak SAES_IRQHandler
|
||||
.thumb_set SAES_IRQHandler,Default_Handler
|
||||
|
||||
.weak CRYP_IRQHandler
|
||||
.thumb_set CRYP_IRQHandler,Default_Handler
|
||||
|
||||
.weak PKA_IRQHandler
|
||||
.thumb_set PKA_IRQHandler,Default_Handler
|
||||
|
||||
.weak HASH_IRQHandler
|
||||
.thumb_set HASH_IRQHandler,Default_Handler
|
||||
|
||||
.weak RNG_IRQHandler
|
||||
.thumb_set RNG_IRQHandler,Default_Handler
|
||||
|
||||
.weak ADC1_2_IRQHandler
|
||||
.thumb_set ADC1_2_IRQHandler,Default_Handler
|
||||
|
||||
.weak GPDMA1_Channel0_IRQHandler
|
||||
.thumb_set GPDMA1_Channel0_IRQHandler,Default_Handler
|
||||
|
||||
.weak GPDMA1_Channel1_IRQHandler
|
||||
.thumb_set GPDMA1_Channel1_IRQHandler,Default_Handler
|
||||
|
||||
.weak GPDMA1_Channel2_IRQHandler
|
||||
.thumb_set GPDMA1_Channel2_IRQHandler,Default_Handler
|
||||
|
||||
.weak GPDMA1_Channel3_IRQHandler
|
||||
.thumb_set GPDMA1_Channel3_IRQHandler,Default_Handler
|
||||
|
||||
.weak GPDMA1_Channel4_IRQHandler
|
||||
.thumb_set GPDMA1_Channel4_IRQHandler,Default_Handler
|
||||
|
||||
.weak GPDMA1_Channel5_IRQHandler
|
||||
.thumb_set GPDMA1_Channel5_IRQHandler,Default_Handler
|
||||
|
||||
.weak GPDMA1_Channel6_IRQHandler
|
||||
.thumb_set GPDMA1_Channel6_IRQHandler,Default_Handler
|
||||
|
||||
.weak GPDMA1_Channel7_IRQHandler
|
||||
.thumb_set GPDMA1_Channel7_IRQHandler,Default_Handler
|
||||
|
||||
.weak TIM1_BRK_IRQHandler
|
||||
.thumb_set TIM1_BRK_IRQHandler,Default_Handler
|
||||
|
||||
.weak TIM1_UP_IRQHandler
|
||||
.thumb_set TIM1_UP_IRQHandler,Default_Handler
|
||||
|
||||
.weak TIM1_TRG_COM_IRQHandler
|
||||
.thumb_set TIM1_TRG_COM_IRQHandler,Default_Handler
|
||||
|
||||
.weak TIM1_CC_IRQHandler
|
||||
.thumb_set TIM1_CC_IRQHandler,Default_Handler
|
||||
|
||||
.weak TIM2_IRQHandler
|
||||
.thumb_set TIM2_IRQHandler,Default_Handler
|
||||
|
||||
.weak TIM3_IRQHandler
|
||||
.thumb_set TIM3_IRQHandler,Default_Handler
|
||||
|
||||
.weak TIM4_IRQHandler
|
||||
.thumb_set TIM4_IRQHandler,Default_Handler
|
||||
|
||||
.weak TIM5_IRQHandler
|
||||
.thumb_set TIM5_IRQHandler,Default_Handler
|
||||
|
||||
.weak TIM6_IRQHandler
|
||||
.thumb_set TIM6_IRQHandler,Default_Handler
|
||||
|
||||
.weak TIM7_IRQHandler
|
||||
.thumb_set TIM7_IRQHandler,Default_Handler
|
||||
|
||||
.weak TIM9_IRQHandler
|
||||
.thumb_set TIM9_IRQHandler,Default_Handler
|
||||
|
||||
.weak SPI1_IRQHandler
|
||||
.thumb_set SPI1_IRQHandler,Default_Handler
|
||||
|
||||
.weak SPI2_IRQHandler
|
||||
.thumb_set SPI2_IRQHandler,Default_Handler
|
||||
|
||||
.weak SPI3_IRQHandler
|
||||
.thumb_set SPI3_IRQHandler,Default_Handler
|
||||
|
||||
.weak SPI4_IRQHandler
|
||||
.thumb_set SPI4_IRQHandler,Default_Handler
|
||||
|
||||
.weak SPI5_IRQHandler
|
||||
.thumb_set SPI5_IRQHandler,Default_Handler
|
||||
|
||||
.weak SPI6_IRQHandler
|
||||
.thumb_set SPI6_IRQHandler,Default_Handler
|
||||
|
||||
.weak HPDMA1_Channel0_IRQHandler
|
||||
.thumb_set HPDMA1_Channel0_IRQHandler,Default_Handler
|
||||
|
||||
.weak HPDMA1_Channel1_IRQHandler
|
||||
.thumb_set HPDMA1_Channel1_IRQHandler,Default_Handler
|
||||
|
||||
.weak HPDMA1_Channel2_IRQHandler
|
||||
.thumb_set HPDMA1_Channel2_IRQHandler,Default_Handler
|
||||
|
||||
.weak HPDMA1_Channel3_IRQHandler
|
||||
.thumb_set HPDMA1_Channel3_IRQHandler,Default_Handler
|
||||
|
||||
.weak HPDMA1_Channel4_IRQHandler
|
||||
.thumb_set HPDMA1_Channel4_IRQHandler,Default_Handler
|
||||
|
||||
.weak HPDMA1_Channel5_IRQHandler
|
||||
.thumb_set HPDMA1_Channel5_IRQHandler,Default_Handler
|
||||
|
||||
.weak HPDMA1_Channel6_IRQHandler
|
||||
.thumb_set HPDMA1_Channel6_IRQHandler,Default_Handler
|
||||
|
||||
.weak HPDMA1_Channel7_IRQHandler
|
||||
.thumb_set HPDMA1_Channel7_IRQHandler,Default_Handler
|
||||
|
||||
.weak SAI1_A_IRQHandler
|
||||
.thumb_set SAI1_A_IRQHandler,Default_Handler
|
||||
|
||||
.weak SAI1_B_IRQHandler
|
||||
.thumb_set SAI1_B_IRQHandler,Default_Handler
|
||||
|
||||
.weak SAI2_A_IRQHandler
|
||||
.thumb_set SAI2_A_IRQHandler,Default_Handler
|
||||
|
||||
.weak SAI2_B_IRQHandler
|
||||
.thumb_set SAI2_B_IRQHandler,Default_Handler
|
||||
|
||||
.weak I2C1_EV_IRQHandler
|
||||
.thumb_set I2C1_EV_IRQHandler,Default_Handler
|
||||
|
||||
.weak I2C1_ER_IRQHandler
|
||||
.thumb_set I2C1_ER_IRQHandler,Default_Handler
|
||||
|
||||
.weak I2C2_EV_IRQHandler
|
||||
.thumb_set I2C2_EV_IRQHandler,Default_Handler
|
||||
|
||||
.weak I2C2_ER_IRQHandler
|
||||
.thumb_set I2C2_ER_IRQHandler,Default_Handler
|
||||
|
||||
.weak I2C3_EV_IRQHandler
|
||||
.thumb_set I2C3_EV_IRQHandler,Default_Handler
|
||||
|
||||
.weak I2C3_ER_IRQHandler
|
||||
.thumb_set I2C3_ER_IRQHandler,Default_Handler
|
||||
|
||||
.weak USART1_IRQHandler
|
||||
.thumb_set USART1_IRQHandler,Default_Handler
|
||||
|
||||
.weak USART2_IRQHandler
|
||||
.thumb_set USART2_IRQHandler,Default_Handler
|
||||
|
||||
.weak USART3_IRQHandler
|
||||
.thumb_set USART3_IRQHandler,Default_Handler
|
||||
|
||||
.weak UART4_IRQHandler
|
||||
.thumb_set UART4_IRQHandler,Default_Handler
|
||||
|
||||
.weak UART5_IRQHandler
|
||||
.thumb_set UART5_IRQHandler,Default_Handler
|
||||
|
||||
.weak UART7_IRQHandler
|
||||
.thumb_set UART7_IRQHandler,Default_Handler
|
||||
|
||||
.weak UART8_IRQHandler
|
||||
.thumb_set UART8_IRQHandler,Default_Handler
|
||||
|
||||
.weak I3C1_EV_IRQHandler
|
||||
.thumb_set I3C1_EV_IRQHandler,Default_Handler
|
||||
|
||||
.weak I3C1_ER_IRQHandler
|
||||
.thumb_set I3C1_ER_IRQHandler,Default_Handler
|
||||
|
||||
.weak OTG_HS_IRQHandler
|
||||
.thumb_set OTG_HS_IRQHandler,Default_Handler
|
||||
|
||||
.weak ETH_IRQHandler
|
||||
.thumb_set ETH_IRQHandler,Default_Handler
|
||||
|
||||
.weak CORDIC_IRQHandler
|
||||
.thumb_set CORDIC_IRQHandler,Default_Handler
|
||||
|
||||
.weak GFXTIM_IRQHandler
|
||||
.thumb_set GFXTIM_IRQHandler,Default_Handler
|
||||
|
||||
.weak DCMIPP_IRQHandler
|
||||
.thumb_set DCMIPP_IRQHandler,Default_Handler
|
||||
|
||||
.weak LTDC_IRQHandler
|
||||
.thumb_set LTDC_IRQHandler,Default_Handler
|
||||
|
||||
.weak LTDC_ER_IRQHandler
|
||||
.thumb_set LTDC_ER_IRQHandler,Default_Handler
|
||||
|
||||
.weak DMA2D_IRQHandler
|
||||
.thumb_set DMA2D_IRQHandler,Default_Handler
|
||||
|
||||
.weak JPEG_IRQHandler
|
||||
.thumb_set JPEG_IRQHandler,Default_Handler
|
||||
|
||||
.weak GFXMMU_IRQHandler
|
||||
.thumb_set GFXMMU_IRQHandler,Default_Handler
|
||||
|
||||
.weak I3C1_WKUP_IRQHandler
|
||||
.thumb_set I3C1_WKUP_IRQHandler,Default_Handler
|
||||
|
||||
.weak MCE1_IRQHandler
|
||||
.thumb_set MCE1_IRQHandler,Default_Handler
|
||||
|
||||
.weak MCE2_IRQHandler
|
||||
.thumb_set MCE2_IRQHandler,Default_Handler
|
||||
|
||||
.weak MCE3_IRQHandler
|
||||
.thumb_set MCE3_IRQHandler,Default_Handler
|
||||
|
||||
.weak XSPI1_IRQHandler
|
||||
.thumb_set XSPI1_IRQHandler,Default_Handler
|
||||
|
||||
.weak XSPI2_IRQHandler
|
||||
.thumb_set XSPI2_IRQHandler,Default_Handler
|
||||
|
||||
.weak FMC_IRQHandler
|
||||
.thumb_set FMC_IRQHandler,Default_Handler
|
||||
|
||||
.weak SDMMC1_IRQHandler
|
||||
.thumb_set SDMMC1_IRQHandler,Default_Handler
|
||||
|
||||
.weak SDMMC2_IRQHandler
|
||||
.thumb_set SDMMC2_IRQHandler,Default_Handler
|
||||
|
||||
.weak OTG_FS_IRQHandler
|
||||
.thumb_set OTG_FS_IRQHandler,Default_Handler
|
||||
|
||||
.weak TIM12_IRQHandler
|
||||
.thumb_set TIM12_IRQHandler,Default_Handler
|
||||
|
||||
.weak TIM13_IRQHandler
|
||||
.thumb_set TIM13_IRQHandler,Default_Handler
|
||||
|
||||
.weak TIM14_IRQHandler
|
||||
.thumb_set TIM14_IRQHandler,Default_Handler
|
||||
|
||||
.weak TIM15_IRQHandler
|
||||
.thumb_set TIM15_IRQHandler,Default_Handler
|
||||
|
||||
.weak TIM16_IRQHandler
|
||||
.thumb_set TIM16_IRQHandler,Default_Handler
|
||||
|
||||
.weak TIM17_IRQHandler
|
||||
.thumb_set TIM17_IRQHandler,Default_Handler
|
||||
|
||||
.weak LPTIM1_IRQHandler
|
||||
.thumb_set LPTIM1_IRQHandler,Default_Handler
|
||||
|
||||
.weak LPTIM2_IRQHandler
|
||||
.thumb_set LPTIM2_IRQHandler,Default_Handler
|
||||
|
||||
.weak LPTIM3_IRQHandler
|
||||
.thumb_set LPTIM3_IRQHandler,Default_Handler
|
||||
|
||||
.weak LPTIM4_IRQHandler
|
||||
.thumb_set LPTIM4_IRQHandler,Default_Handler
|
||||
|
||||
.weak LPTIM5_IRQHandler
|
||||
.thumb_set LPTIM5_IRQHandler,Default_Handler
|
||||
|
||||
.weak SPDIF_RX_IRQHandler
|
||||
.thumb_set SPDIF_RX_IRQHandler,Default_Handler
|
||||
|
||||
.weak MDIOS_IRQHandler
|
||||
.thumb_set MDIOS_IRQHandler,Default_Handler
|
||||
|
||||
.weak ADF1_FLT0_IRQHandler
|
||||
.thumb_set ADF1_FLT0_IRQHandler,Default_Handler
|
||||
|
||||
.weak CRS_IRQHandler
|
||||
.thumb_set CRS_IRQHandler,Default_Handler
|
||||
|
||||
.weak UCPD1_IRQHandler
|
||||
.thumb_set UCPD1_IRQHandler,Default_Handler
|
||||
|
||||
.weak CEC_IRQHandler
|
||||
.thumb_set CEC_IRQHandler,Default_Handler
|
||||
|
||||
.weak PSSI_IRQHandler
|
||||
.thumb_set PSSI_IRQHandler,Default_Handler
|
||||
|
||||
.weak LPUART1_IRQHandler
|
||||
.thumb_set LPUART1_IRQHandler,Default_Handler
|
||||
|
||||
.weak WAKEUP_PIN_IRQHandler
|
||||
.thumb_set WAKEUP_PIN_IRQHandler,Default_Handler
|
||||
|
||||
.weak GPDMA1_Channel8_IRQHandler
|
||||
.thumb_set GPDMA1_Channel8_IRQHandler,Default_Handler
|
||||
|
||||
.weak GPDMA1_Channel9_IRQHandler
|
||||
.thumb_set GPDMA1_Channel9_IRQHandler,Default_Handler
|
||||
|
||||
.weak GPDMA1_Channel10_IRQHandler
|
||||
.thumb_set GPDMA1_Channel10_IRQHandler,Default_Handler
|
||||
|
||||
.weak GPDMA1_Channel11_IRQHandler
|
||||
.thumb_set GPDMA1_Channel11_IRQHandler,Default_Handler
|
||||
|
||||
.weak GPDMA1_Channel12_IRQHandler
|
||||
.thumb_set GPDMA1_Channel12_IRQHandler,Default_Handler
|
||||
|
||||
.weak GPDMA1_Channel13_IRQHandler
|
||||
.thumb_set GPDMA1_Channel13_IRQHandler,Default_Handler
|
||||
|
||||
.weak GPDMA1_Channel14_IRQHandler
|
||||
.thumb_set GPDMA1_Channel14_IRQHandler,Default_Handler
|
||||
|
||||
.weak GPDMA1_Channel15_IRQHandler
|
||||
.thumb_set GPDMA1_Channel15_IRQHandler,Default_Handler
|
||||
|
||||
.weak HPDMA1_Channel8_IRQHandler
|
||||
.thumb_set HPDMA1_Channel8_IRQHandler,Default_Handler
|
||||
|
||||
.weak HPDMA1_Channel9_IRQHandler
|
||||
.thumb_set HPDMA1_Channel9_IRQHandler,Default_Handler
|
||||
|
||||
.weak HPDMA1_Channel10_IRQHandler
|
||||
.thumb_set HPDMA1_Channel10_IRQHandler,Default_Handler
|
||||
|
||||
.weak HPDMA1_Channel11_IRQHandler
|
||||
.thumb_set HPDMA1_Channel11_IRQHandler,Default_Handler
|
||||
|
||||
.weak HPDMA1_Channel12_IRQHandler
|
||||
.thumb_set HPDMA1_Channel12_IRQHandler,Default_Handler
|
||||
|
||||
.weak HPDMA1_Channel13_IRQHandler
|
||||
.thumb_set HPDMA1_Channel13_IRQHandler,Default_Handler
|
||||
|
||||
.weak HPDMA1_Channel14_IRQHandler
|
||||
.thumb_set HPDMA1_Channel14_IRQHandler,Default_Handler
|
||||
|
||||
.weak HPDMA1_Channel15_IRQHandler
|
||||
.thumb_set HPDMA1_Channel15_IRQHandler,Default_Handler
|
||||
|
||||
.weak GPU2D_IRQHandler
|
||||
.thumb_set GPU2D_IRQHandler,Default_Handler
|
||||
|
||||
.weak GPU2D_ER_IRQHandler
|
||||
.thumb_set GPU2D_ER_IRQHandler,Default_Handler
|
||||
|
||||
.weak ICACHE_IRQHandler
|
||||
.thumb_set ICACHE_IRQHandler,Default_Handler
|
||||
|
||||
.weak FDCAN1_IT0_IRQHandler
|
||||
.thumb_set FDCAN1_IT0_IRQHandler,Default_Handler
|
||||
|
||||
.weak FDCAN1_IT1_IRQHandler
|
||||
.thumb_set FDCAN1_IT1_IRQHandler,Default_Handler
|
||||
|
||||
.weak FDCAN2_IT0_IRQHandler
|
||||
.thumb_set FDCAN2_IT0_IRQHandler,Default_Handler
|
||||
|
||||
.weak FDCAN2_IT1_IRQHandler
|
||||
.thumb_set FDCAN2_IT1_IRQHandler,Default_Handler
|
||||
|
||||
.weak SystemInit
|
||||
@@ -20,6 +20,7 @@
|
||||
*/
|
||||
|
||||
#include "hal/switch_driver.h"
|
||||
#include "bsp_io.h"
|
||||
#include "stm32_switch_driver.h"
|
||||
#include "stm32_gpio_driver.h"
|
||||
|
||||
@@ -36,17 +37,21 @@ __weak void boardInitSwitches()
|
||||
_init_switches();
|
||||
}
|
||||
|
||||
__weak SwitchHwPos boardSwitchGetPosition(uint8_t cat, uint8_t idx)
|
||||
__weak SwitchHwPos boardSwitchGetPosition(SwitchCategory cat, uint8_t idx)
|
||||
{
|
||||
return stm32_switch_get_position(&_switch_offsets[cat][idx]);
|
||||
const stm32_switch_t* sw = &_switch_offsets[cat][idx];
|
||||
if(sw->type != SWITCH_HW_ADC && sw->GPIOx_high == nullptr)
|
||||
return bsp_get_switch_position(sw, cat, idx);
|
||||
|
||||
return stm32_switch_get_position(sw);
|
||||
}
|
||||
|
||||
const char* boardSwitchGetName(uint8_t cat, uint8_t idx)
|
||||
const char* boardSwitchGetName(SwitchCategory cat, uint8_t idx)
|
||||
{
|
||||
return _switch_offsets[cat][idx].name;
|
||||
}
|
||||
|
||||
SwitchHwType boardSwitchGetType(uint8_t cat, uint8_t idx)
|
||||
SwitchHwType boardSwitchGetType(SwitchCategory cat, uint8_t idx)
|
||||
{
|
||||
return _switch_offsets[cat][idx].type;
|
||||
}
|
||||
|
||||
@@ -1388,9 +1388,11 @@ int cliDisplay(const char ** argv)
|
||||
case 2:
|
||||
tim = TIM2;
|
||||
break;
|
||||
#if defined(TIM8)
|
||||
case 8:
|
||||
tim = TIM8;
|
||||
break;
|
||||
#endif
|
||||
case 13:
|
||||
tim = TIM13;
|
||||
break;
|
||||
@@ -1417,10 +1419,12 @@ int cliDisplay(const char ** argv)
|
||||
cliSerialPrint(" CCR4 0x%x", tim->CCR4);
|
||||
}
|
||||
}
|
||||
#if defined(DMA1_Stream7)
|
||||
else if (!strcmp(argv[1], "dma")) {
|
||||
cliSerialPrint("DMA1_Stream7");
|
||||
cliSerialPrint(" CR 0x%x", DMA1_Stream7->CR);
|
||||
}
|
||||
#endif
|
||||
#if defined(DEBUG_INTERRUPTS)
|
||||
else if (!strcmp(argv[1], "int")) {
|
||||
printInterrupts();
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
#define LABELS_LENGTH 100 // Maximum length of the label string
|
||||
#define LABEL_LENGTH 16
|
||||
|
||||
#if defined(COLORLCD) || defined(STM32H747xx)
|
||||
#if defined(COLORLCD)
|
||||
#define MAX_MODELS 60
|
||||
#define MAX_OUTPUT_CHANNELS 32 // number of real output channels CH1-CH32
|
||||
#define MAX_FLIGHT_MODES 9
|
||||
|
||||
@@ -628,19 +628,19 @@ PACK(struct CustomScreenData {
|
||||
#endif
|
||||
|
||||
struct RGBLedColor {
|
||||
uint8_t r;
|
||||
uint8_t g;
|
||||
uint8_t b;
|
||||
uint8_t r;
|
||||
uint8_t g;
|
||||
uint8_t b;
|
||||
|
||||
uint32_t getColor() {
|
||||
return ((r << 16) + (g << 8) + b);
|
||||
}
|
||||
uint32_t getColor() {
|
||||
return ((r << 16) + (g << 8) + b);
|
||||
}
|
||||
|
||||
void setColor(uint32_t color) {
|
||||
r = color >> 16;
|
||||
g = color >> 8;
|
||||
b = color;
|
||||
}
|
||||
void setColor(uint32_t color) {
|
||||
r = color >> 16;
|
||||
g = color >> 8;
|
||||
b = color;
|
||||
}
|
||||
};
|
||||
|
||||
#if defined(FUNCTION_SWITCHES_RGB_LEDS)
|
||||
@@ -655,7 +655,7 @@ struct RGBLedColor {
|
||||
uint16_t functionSwitchConfig; \
|
||||
uint16_t functionSwitchGroup; \
|
||||
uint16_t functionSwitchStartConfig; \
|
||||
uint8_t functionSwitchLogicalState; \
|
||||
uint8_t functionSwitchLogicalState; \
|
||||
char switchNames[NUM_FUNCTIONS_SWITCHES][LEN_SWITCH_NAME]; \
|
||||
FUNCTION_SWITCHS_RGB_LEDS_FIELDS
|
||||
#else
|
||||
@@ -973,12 +973,8 @@ PACK(struct RadioData {
|
||||
|
||||
char ownerRegistrationID[PXX2_LEN_REGISTRATION_ID];
|
||||
|
||||
#if defined(ROTARY_ENCODER_NAVIGATION) && !defined(USE_HATS_AS_KEYS)
|
||||
CUST_ATTR(rotEncDirection, r_rotEncDirection, nullptr);
|
||||
NOBACKUP(uint8_t rotEncMode:3);
|
||||
#else
|
||||
NOBACKUP(uint8_t rotEncModeSpare:3 SKIP);
|
||||
#endif
|
||||
|
||||
NOBACKUP(int8_t uartSampleMode:2); // See UartSampleModes
|
||||
|
||||
|
||||
+2
-24
@@ -25,6 +25,8 @@
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#include "memory_sections.h"
|
||||
|
||||
#if !defined(M_PI)
|
||||
#define M_PI 3.14159265358979323846 // pi
|
||||
#define M_PI_2 1.57079632679489661923 // pi/2
|
||||
@@ -55,30 +57,6 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(SIMU)
|
||||
#define __DMA
|
||||
#else
|
||||
#define __DMA __attribute__((section(".ram"), aligned(4)))
|
||||
#endif
|
||||
|
||||
#if defined(CCMRAM) && !defined(SIMU)
|
||||
#define __CCMRAM __attribute__((section(".ccm"), aligned(4)))
|
||||
#else
|
||||
#define __CCMRAM
|
||||
#endif
|
||||
|
||||
#if defined(SDRAM) && !defined(SIMU)
|
||||
#define __SDRAM __attribute__((section(".sdram"), aligned(4)))
|
||||
#if defined(COLORLCD)
|
||||
#define __SDRAMFONTS __attribute__((section(".sdram_fonts"), aligned(4)))
|
||||
#endif
|
||||
#else
|
||||
#define __SDRAM __DMA
|
||||
#if defined(COLORLCD)
|
||||
#define __SDRAMFONTS __DMA
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if __GNUC__
|
||||
#define PACK(__Declaration__) __Declaration__ __attribute__((__packed__))
|
||||
#else
|
||||
|
||||
@@ -0,0 +1,489 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Adafruit Industries
|
||||
*
|
||||
* MIT License
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "uf2_ghostfat.h"
|
||||
#include "board.h"
|
||||
|
||||
#include "uf2/uf2.h"
|
||||
#include "io/uf2.h"
|
||||
|
||||
#include "hal/flash_driver.h"
|
||||
#include "fw_desc.h"
|
||||
|
||||
#include "debug.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
typedef struct {
|
||||
uint8_t JumpInstruction[3];
|
||||
uint8_t OEMInfo[8];
|
||||
uint16_t SectorSize;
|
||||
uint8_t SectorsPerCluster;
|
||||
uint16_t ReservedSectors;
|
||||
uint8_t FATCopies;
|
||||
uint16_t RootDirectoryEntries;
|
||||
uint16_t TotalSectors16;
|
||||
uint8_t MediaDescriptor;
|
||||
uint16_t SectorsPerFAT;
|
||||
uint16_t SectorsPerTrack;
|
||||
uint16_t Heads;
|
||||
uint32_t HiddenSectors;
|
||||
uint32_t TotalSectors32;
|
||||
uint8_t PhysicalDriveNum;
|
||||
uint8_t Reserved;
|
||||
uint8_t ExtendedBootSig;
|
||||
uint32_t VolumeSerialNumber;
|
||||
uint8_t VolumeLabel[11];
|
||||
uint8_t FilesystemIdentifier[8];
|
||||
} __attribute__((packed)) FAT_BootBlock;
|
||||
|
||||
typedef struct {
|
||||
char name[8];
|
||||
char ext[3];
|
||||
uint8_t attrs;
|
||||
uint8_t reserved;
|
||||
uint8_t createTimeFine;
|
||||
uint16_t createTime;
|
||||
uint16_t createDate;
|
||||
uint16_t lastAccessDate;
|
||||
uint16_t highStartCluster;
|
||||
uint16_t updateTime;
|
||||
uint16_t updateDate;
|
||||
uint16_t startCluster;
|
||||
uint32_t size;
|
||||
} __attribute__((packed)) DirEntry;
|
||||
static_assert(sizeof(DirEntry) == 32);
|
||||
|
||||
struct TextFile {
|
||||
char const name[11];
|
||||
char const *content;
|
||||
};
|
||||
|
||||
#define NUM_FAT_BLOCKS UF2_NUM_BLOCKS
|
||||
#define UF2_VOLUME_LABEL {'E', 'D', 'G', 'E', 'T', 'X', '_', 'U', 'F', '2', ' ' }
|
||||
#define UF2_INDEX_URL "https://edgetx.org"
|
||||
|
||||
#define STR0(x) #x
|
||||
#define STR(x) STR0(x)
|
||||
|
||||
#ifndef ARRAY_SIZE
|
||||
#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
|
||||
#endif
|
||||
|
||||
#define __YEAR_INT__ ((( \
|
||||
(__DATE__ [ 7u] - '0') * 10u + \
|
||||
(__DATE__ [ 8u] - '0')) * 10u + \
|
||||
(__DATE__ [ 9u] - '0')) * 10u + \
|
||||
(__DATE__ [10u] - '0'))
|
||||
|
||||
#define __MONTH_INT__ ( \
|
||||
(__DATE__ [2u] == 'n' && __DATE__ [1u] == 'a') ? 1u /*Jan*/ \
|
||||
: (__DATE__ [2u] == 'b' ) ? 2u /*Feb*/ \
|
||||
: (__DATE__ [2u] == 'r' && __DATE__ [1u] == 'a') ? 3u /*Mar*/ \
|
||||
: (__DATE__ [2u] == 'r' ) ? 4u /*Apr*/ \
|
||||
: (__DATE__ [2u] == 'y' ) ? 5u /*May*/ \
|
||||
: (__DATE__ [2u] == 'n' ) ? 6u /*Jun*/ \
|
||||
: (__DATE__ [2u] == 'l' ) ? 7u /*Jul*/ \
|
||||
: (__DATE__ [2u] == 'g' ) ? 8u /*Aug*/ \
|
||||
: (__DATE__ [2u] == 'p' ) ? 9u /*Sep*/ \
|
||||
: (__DATE__ [2u] == 't' ) ? 10u /*Oct*/ \
|
||||
: (__DATE__ [2u] == 'v' ) ? 11u /*Nov*/ \
|
||||
: 12u /*Dec*/ )
|
||||
|
||||
#define __DAY_INT__ ( \
|
||||
(__DATE__ [4u] == ' ' ? 0u : __DATE__ [4u] - '0') * 10u \
|
||||
+ (__DATE__ [5u] - '0') )
|
||||
|
||||
// __TIME__ expands to an eight-character string constant
|
||||
// "23:59:01", or (if cannot determine time) "??:??:??"
|
||||
#define __HOUR_INT__ ( \
|
||||
(__TIME__ [0u] == '?' ? 0u : __TIME__ [0u] - '0') * 10u \
|
||||
+ (__TIME__ [1u] == '?' ? 0u : __TIME__ [1u] - '0') )
|
||||
|
||||
#define __MINUTE_INT__ ( \
|
||||
(__TIME__ [3u] == '?' ? 0u : __TIME__ [3u] - '0') * 10u \
|
||||
+ (__TIME__ [4u] == '?' ? 0u : __TIME__ [4u] - '0') )
|
||||
|
||||
#define __SECONDS_INT__ ( \
|
||||
(__TIME__ [6u] == '?' ? 0u : __TIME__ [6u] - '0') * 10u \
|
||||
+ (__TIME__ [7u] == '?' ? 0u : __TIME__ [7u] - '0') )
|
||||
|
||||
|
||||
#define __DOSDATE__ ( \
|
||||
((__YEAR_INT__ - 1980u) << 9u) | \
|
||||
( __MONTH_INT__ << 5u) | \
|
||||
( __DAY_INT__ << 0u) )
|
||||
|
||||
#define __DOSTIME__ ( \
|
||||
( __HOUR_INT__ << 11u) | \
|
||||
( __MINUTE_INT__ << 5u) | \
|
||||
( __SECONDS_INT__ << 0u) )
|
||||
|
||||
#include "stamp.h"
|
||||
|
||||
const char infoUf2File[] =
|
||||
"UF2 Bootloader " VERSION "\r\n"
|
||||
"Board-ID: " FLAVOUR "\r\n"
|
||||
"Date: " DATE "\r\n";
|
||||
|
||||
const char indexFile[] = //
|
||||
"<!doctype html>\n"
|
||||
"<html>"
|
||||
"<body>"
|
||||
"<script>\n"
|
||||
"location.replace(\"" UF2_INDEX_URL "\");\n"
|
||||
"</script>"
|
||||
"</body>"
|
||||
"</html>\n";
|
||||
|
||||
// WARNING -- code presumes only one NULL .content for .UF2 file
|
||||
// and requires it be the last element of the array
|
||||
static struct TextFile const info[] = {
|
||||
{.name = {'I','N','F','O','_','U','F','2','T','X','T'}, .content = infoUf2File},
|
||||
{.name = {'I','N','D','E','X',' ',' ',' ','H','T','M'}, .content = indexFile},
|
||||
{.name = {'C','U','R','R','E','N','T',' ','U','F','2'}, .content = nullptr},
|
||||
};
|
||||
|
||||
// WARNING -- code presumes each non-UF2 file content fits in single sector
|
||||
// Cannot programmatically statically assert .content length
|
||||
// for each element above.
|
||||
static_assert(ARRAY_SIZE(indexFile) < 512);
|
||||
|
||||
|
||||
#define NUM_FILES (ARRAY_SIZE(info))
|
||||
#define NUM_DIRENTRIES (NUM_FILES + 1) // Code adds volume label as first root directory entry
|
||||
|
||||
|
||||
#define UF2_SIZE (current_flash_size() * 2 + 512)
|
||||
#define UF2_SECTORS (UF2_SIZE / 512)
|
||||
#define UF2_FIRST_SECTOR (NUM_FILES + 1) // WARNING -- code presumes each non-UF2 file content fits in single sector
|
||||
#define UF2_LAST_SECTOR (UF2_FIRST_SECTOR + UF2_SECTORS - 1)
|
||||
|
||||
#define RESERVED_SECTORS 1
|
||||
#define ROOT_DIR_SECTORS 4
|
||||
#define SECTORS_PER_FAT ((NUM_FAT_BLOCKS * 2 + 511) / 512)
|
||||
|
||||
#define START_FAT0 RESERVED_SECTORS
|
||||
#define START_FAT1 (START_FAT0 + SECTORS_PER_FAT)
|
||||
#define START_ROOTDIR (START_FAT1 + SECTORS_PER_FAT)
|
||||
#define START_CLUSTERS (START_ROOTDIR + ROOT_DIR_SECTORS)
|
||||
|
||||
// all directory entries must fit in a single sector
|
||||
// because otherwise current code overflows buffer
|
||||
#define DIRENTRIES_PER_SECTOR (512/sizeof(DirEntry))
|
||||
|
||||
static_assert(NUM_DIRENTRIES < DIRENTRIES_PER_SECTOR * ROOT_DIR_SECTORS);
|
||||
|
||||
|
||||
static FAT_BootBlock const BootBlock = {
|
||||
.JumpInstruction = {0xeb, 0x3c, 0x90},
|
||||
.OEMInfo = {'M','S','W','I','N','4','.','1'},
|
||||
.SectorSize = 512,
|
||||
.SectorsPerCluster = 1,
|
||||
.ReservedSectors = RESERVED_SECTORS,
|
||||
.FATCopies = 2,
|
||||
.RootDirectoryEntries = (ROOT_DIR_SECTORS * DIRENTRIES_PER_SECTOR),
|
||||
.TotalSectors16 = NUM_FAT_BLOCKS - 2,
|
||||
.MediaDescriptor = 0xF8,
|
||||
.SectorsPerFAT = SECTORS_PER_FAT,
|
||||
.SectorsPerTrack = 1,
|
||||
.Heads = 1,
|
||||
.PhysicalDriveNum = 0x80, // to match MediaDescriptor of 0xF8
|
||||
.ExtendedBootSig = 0x29,
|
||||
.VolumeSerialNumber = 0x00000000,
|
||||
.VolumeLabel = UF2_VOLUME_LABEL,
|
||||
.FilesystemIdentifier = {'F','A','T','1','6',' ',' ',' '},
|
||||
};
|
||||
|
||||
static uf2_fat_write_state_t _uf2_write_state;
|
||||
|
||||
void uf2_fat_reset_state()
|
||||
{
|
||||
memset(&_uf2_write_state, 0, sizeof(_uf2_write_state));
|
||||
}
|
||||
|
||||
const uf2_fat_write_state_t* uf2_fat_get_state()
|
||||
{
|
||||
return &_uf2_write_state;
|
||||
}
|
||||
|
||||
static inline bool is_firmware_length_valid(uint32_t len)
|
||||
{
|
||||
return len && len <= UF2_MAX_FW_SIZE;
|
||||
}
|
||||
|
||||
static inline bool is_address_in_firmware(uintptr_t addr)
|
||||
{
|
||||
return (addr & FIRMWARE_ADDRESS) == FIRMWARE_ADDRESS;
|
||||
}
|
||||
|
||||
static inline bool is_firmware_valid(firmware_description_t const* fw_desc)
|
||||
{
|
||||
return fw_desc && is_firmware_length_valid(fw_desc->length) &&
|
||||
is_address_in_firmware(fw_desc->version_ptr) &&
|
||||
is_address_in_firmware((uintptr_t)fw_desc->reset_handler);
|
||||
}
|
||||
|
||||
// get current.uf2 flash size in bytes, round up to 256 bytes
|
||||
static uint32_t current_flash_size(void)
|
||||
{
|
||||
static uint32_t flash_sz = 0;
|
||||
uint32_t result = flash_sz; // presumes atomic 32-bit read/write and static result
|
||||
|
||||
// only need to compute once
|
||||
if ( result == 0 ) {
|
||||
firmware_description_t const *fw_desc =
|
||||
(firmware_description_t const *)FIRMWARE_ADDRESS;
|
||||
|
||||
if (is_firmware_valid(fw_desc)) {
|
||||
// round up to 256 bytes
|
||||
result = (fw_desc->length + BOOTLOADER_SIZE + 255U) & (~255U);
|
||||
} else {
|
||||
result = UF2_MAX_FW_SIZE;
|
||||
}
|
||||
flash_sz = result; // presumes atomic 32-bit read/write and static result
|
||||
}
|
||||
|
||||
return flash_sz;
|
||||
}
|
||||
|
||||
static void padded_memcpy (char *dst, char const *src, int len)
|
||||
{
|
||||
for (int i = 0; i < len; ++i) {
|
||||
if (*src)
|
||||
*dst = *src++;
|
||||
else
|
||||
*dst = ' ';
|
||||
dst++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------*/
|
||||
/* Read
|
||||
*------------------------------------------------------------------*/
|
||||
void uf2_fat_read_block(uint32_t block_no, uint8_t *data)
|
||||
{
|
||||
memset(data, 0, 512);
|
||||
uint32_t sectionIdx = block_no;
|
||||
|
||||
if (block_no == 0) { // Requested boot block
|
||||
memcpy(data, &BootBlock, sizeof(BootBlock));
|
||||
data[510] = 0x55;
|
||||
data[511] = 0xaa;
|
||||
// logval("data[0]", data[0]);
|
||||
} else if (block_no < START_ROOTDIR) { // Requested FAT table sector
|
||||
sectionIdx -= START_FAT0;
|
||||
// logval("sidx", sectionIdx);
|
||||
if (sectionIdx >= SECTORS_PER_FAT)
|
||||
sectionIdx -= SECTORS_PER_FAT; // second FAT is same as the first...
|
||||
if (sectionIdx == 0) {
|
||||
data[0] = 0xf8; // first FAT entry must match BPB MediaDescriptor
|
||||
// WARNING -- code presumes only one NULL .content for .UF2 file
|
||||
// and all non-NULL .content fit in one sector
|
||||
// and requires it be the last element of the array
|
||||
for (unsigned i = 1; i < NUM_FILES * 2 + 4; ++i) {
|
||||
data[i] = 0xff;
|
||||
}
|
||||
}
|
||||
for (unsigned i = 0; i < 256; ++i) { // Generate the FAT chain for the firmware "file"
|
||||
uint32_t v = sectionIdx * 256 + i;
|
||||
if (UF2_FIRST_SECTOR <= v && v <= UF2_LAST_SECTOR)
|
||||
((uint16_t *)(void *)data)[i] = v == UF2_LAST_SECTOR ? 0xffff : v + 1;
|
||||
}
|
||||
} else if (block_no < START_CLUSTERS) { // Requested root directory sector
|
||||
|
||||
sectionIdx -= START_ROOTDIR;
|
||||
|
||||
DirEntry *d = (DirEntry *)data;
|
||||
int remainingEntries = DIRENTRIES_PER_SECTOR;
|
||||
if (sectionIdx == 0) { // volume label first
|
||||
// volume label is first directory entry
|
||||
padded_memcpy(d->name, (char const *) BootBlock.VolumeLabel, 11);
|
||||
d->attrs = 0x28;
|
||||
d++;
|
||||
remainingEntries--;
|
||||
}
|
||||
|
||||
for (unsigned i = DIRENTRIES_PER_SECTOR * sectionIdx;
|
||||
remainingEntries > 0 && i < NUM_FILES;
|
||||
i++, d++) {
|
||||
|
||||
// WARNING -- code presumes all but last file take exactly one sector
|
||||
uint16_t startCluster = i + 2;
|
||||
|
||||
struct TextFile const * inf = &info[i];
|
||||
padded_memcpy(d->name, inf->name, 11);
|
||||
d->createTimeFine = __SECONDS_INT__ % 2 * 100;
|
||||
d->createTime = __DOSTIME__;
|
||||
d->createDate = __DOSDATE__;
|
||||
d->lastAccessDate = __DOSDATE__;
|
||||
d->highStartCluster = startCluster >> 8;
|
||||
// DIR_WrtTime and DIR_WrtDate must be supported
|
||||
d->updateTime = __DOSTIME__;
|
||||
d->updateDate = __DOSDATE__;
|
||||
d->startCluster = startCluster & 0xFF;
|
||||
// WARNING -- code presumes only one NULL .content for .UF2 file
|
||||
// and requires it be the last element of the array
|
||||
d->size = inf->content ? strlen(inf->content) : UF2_SIZE;
|
||||
}
|
||||
|
||||
} else {
|
||||
sectionIdx -= START_CLUSTERS;
|
||||
if (sectionIdx < NUM_FILES - 1) {
|
||||
memcpy(data, info[sectionIdx].content, strlen(info[sectionIdx].content));
|
||||
} else { // generate the UF2 file data on-the-fly
|
||||
sectionIdx -= NUM_FILES - 1;
|
||||
|
||||
uint32_t addr = 0;
|
||||
if (sectionIdx >= UF2_MAX_FW_SIZE / 256) return;
|
||||
|
||||
UF2_Block *bl = (UF2_Block *)data;
|
||||
bl->magicStart0 = UF2_MAGIC_START0;
|
||||
bl->magicStart1 = UF2_MAGIC_START1;
|
||||
bl->magicEnd = UF2_MAGIC_END;
|
||||
bl->blockNo = sectionIdx;
|
||||
bl->numBlocks = current_flash_size() / 256 + 1;
|
||||
bl->flags = 0;
|
||||
bl->reserved = 0;
|
||||
|
||||
if (sectionIdx == BOOTLOADER_SIZE / 256) {
|
||||
writeUF2RebootBlock(bl);
|
||||
writeUF2FirmwareVersion(bl);
|
||||
} else {
|
||||
if (sectionIdx < BOOTLOADER_SIZE / 256) {
|
||||
addr = 0x08000000 + sectionIdx * 256;
|
||||
} else {
|
||||
sectionIdx -= BOOTLOADER_SIZE / 256 + 1;
|
||||
addr = FIRMWARE_ADDRESS + sectionIdx * 256;
|
||||
}
|
||||
|
||||
bl->targetAddr = addr;
|
||||
bl->payloadSize = 256;
|
||||
memcpy(bl->data, (void *)addr, bl->payloadSize);
|
||||
writeUF2FirmwareVersion(bl);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------*/
|
||||
/* Write UF2
|
||||
*------------------------------------------------------------------*/
|
||||
|
||||
/** Write an block
|
||||
*
|
||||
* @return number of bytes processed, only the following values
|
||||
* -1 : if not an uf2 block
|
||||
* 512 : write is successful
|
||||
*/
|
||||
int uf2_fat_write_block(uint32_t block_no, uint8_t *data)
|
||||
{
|
||||
uf2_fat_write_state_t *wr_st = &_uf2_write_state;
|
||||
UF2_Block *bl = (UF2_Block *)data;
|
||||
// TRACE("Write magic: %x", bl->magicStart0);
|
||||
|
||||
if (!isUF2Block((const uint8_t*)bl, 512)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// only accept block with same family id
|
||||
if (UF2_FAMILY_ID && !((bl->flags & UF2_FLAG_FAMILY_ID) &&
|
||||
(bl->reserved == UF2_FAMILY_ID))) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((bl->flags & UF2_FLAG_NOFLASH) || bl->payloadSize > 256 ||
|
||||
(bl->targetAddr & 0xff) || bl->targetAddr < BOOTLOADER_ADDRESS ||
|
||||
bl->targetAddr + bl->payloadSize >
|
||||
(FIRMWARE_ADDRESS + UF2_MAX_FW_SIZE)) {
|
||||
// block doesn't seem valid; we still want to count these blocks
|
||||
// to reset properly
|
||||
} else {
|
||||
uint32_t wr_block = bl->blockNo;
|
||||
if (wr_block >= BOOTLOADER_SIZE / 256) wr_block--;
|
||||
|
||||
uint32_t erase_sector = wr_block / (UF2_ERASE_BLOCK_SIZE / 256);
|
||||
uint32_t mask = 1 << (erase_sector & 0x1F);
|
||||
uint32_t pos = erase_sector >> 5;
|
||||
|
||||
uint32_t addr = bl->targetAddr;
|
||||
if (wr_st && !(wr_st->erased_mask[pos] & mask)) {
|
||||
TRACE_DEBUG("[UF2] erase 0x%08x\n", bl->targetAddr);
|
||||
|
||||
auto drv = flashFindDriver(addr);
|
||||
if (drv) {
|
||||
if (drv->erase_sector(addr) < 0) return -1;
|
||||
|
||||
// mark additional erased sectors
|
||||
uint32_t sector = drv->get_sector(addr);
|
||||
uint32_t sect_len = drv->get_sector_size(sector);
|
||||
uint32_t media_len = flashGetSize(addr);
|
||||
if (media_len < sect_len) sect_len = media_len;
|
||||
uint32_t erased_sectors = sect_len / UF2_ERASE_BLOCK_SIZE;
|
||||
|
||||
while (erased_sectors-- != 0) {
|
||||
pos = erase_sector >> 5;
|
||||
mask = 1 << (erase_sector & 0x1F);
|
||||
wr_st->erased_mask[pos] |= mask;
|
||||
erase_sector++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TRACE_DEBUG("[UF2] write 0x%08x\n", bl->targetAddr);
|
||||
|
||||
auto drv = flashFindDriver(addr);
|
||||
if (drv) {
|
||||
uint32_t len = bl->payloadSize;
|
||||
uint8_t* data = (uint8_t*)bl->data;
|
||||
if (drv->program(addr, data, len) < 0) return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (wr_st && bl->numBlocks) {
|
||||
if (wr_st->num_blocks != bl->numBlocks) {
|
||||
if (bl->numBlocks >= UF2_MAX_BLOCKS || wr_st->num_blocks) {
|
||||
wr_st->num_blocks = UF2_INVALID_NUM_BLOCKS;
|
||||
} else {
|
||||
wr_st->num_blocks = bl->numBlocks;
|
||||
}
|
||||
}
|
||||
if (bl->blockNo < UF2_MAX_BLOCKS) {
|
||||
uint32_t mask = 1 << (bl->blockNo & 0x1F);
|
||||
uint32_t pos = bl->blockNo >> 5;
|
||||
if (!(wr_st->written_mask[pos] & mask)) {
|
||||
wr_st->written_mask[pos] |= mask;
|
||||
wr_st->num_written++;
|
||||
TRACE_DEBUG("[UF2] wr #%d (%d / %d)\n", bl->blockNo,
|
||||
state->num_written, bl->numBlocks);
|
||||
}
|
||||
if (wr_st->num_written >= wr_st->num_blocks) {
|
||||
TRACE_DEBUG("[UF2] done: reboot\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 512;
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright (C) EdgeTX
|
||||
*
|
||||
* Based on code named
|
||||
* opentx - https://github.com/opentx/opentx
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#define UF2_NUM_BLOCKS 32768 // at least 16MB
|
||||
#define UF2_INVALID_NUM_BLOCKS 0xFFFFFFFF
|
||||
|
||||
#if !defined(UF2_MAX_FW_SIZE)
|
||||
#define UF2_MAX_FW_SIZE (2 * 1024 * 1024)
|
||||
#endif
|
||||
|
||||
#define UF2_MAX_BLOCKS (UF2_MAX_FW_SIZE / 256)
|
||||
|
||||
#define UF2_ERASE_BLOCK_SIZE (4 * 1024)
|
||||
#define UF2_ERASE_BLOCKS (UF2_MAX_FW_SIZE / UF2_ERASE_BLOCK_SIZE)
|
||||
|
||||
typedef struct {
|
||||
uint32_t num_blocks;
|
||||
uint32_t num_written;
|
||||
uint32_t written_mask[UF2_MAX_BLOCKS / 32];
|
||||
uint32_t erased_mask[UF2_ERASE_BLOCKS / 32];
|
||||
} uf2_fat_write_state_t;
|
||||
|
||||
void uf2_fat_reset_state();
|
||||
const uf2_fat_write_state_t* uf2_fat_get_state();
|
||||
|
||||
void uf2_fat_read_block(uint32_t block_no, uint8_t *data);
|
||||
int uf2_fat_write_block(uint32_t block_no, uint8_t *data);
|
||||
@@ -94,7 +94,6 @@ uint8_t heartbeat;
|
||||
safetych_t safetyCh[MAX_OUTPUT_CHANNELS];
|
||||
#endif
|
||||
|
||||
// __DMA for the MSC_BOT_Data member
|
||||
union ReusableBuffer reusableBuffer __DMA;
|
||||
|
||||
#if defined(DEBUG_LATENCY)
|
||||
@@ -143,6 +142,8 @@ void checkValidMCU(void)
|
||||
#define TARGET_IDCODE 0x463
|
||||
#elif defined(STM32H750xx) || defined(STM32H747xx)
|
||||
#define TARGET_IDCODE 0x450
|
||||
#elif defined(STM32H7RS)
|
||||
#define TARGET_IDCODE 0x485
|
||||
#else
|
||||
// Ensure new radio get registered :)
|
||||
#warning "Target MCU code undefined"
|
||||
@@ -208,7 +209,7 @@ void timer_10ms()
|
||||
evalFunctionSwitches();
|
||||
#endif
|
||||
|
||||
#if defined(ROTARY_ENCODER_NAVIGATION) && !defined(LIBOPENUI)
|
||||
#if defined(ROTARY_ENCODER_NAVIGATION) && !defined(COLORLCD)
|
||||
if (rotaryEncoderPollingCycle()) {
|
||||
inactivityTimerReset(ActivitySource::Keys);
|
||||
}
|
||||
@@ -1123,7 +1124,7 @@ void edgeTxResume()
|
||||
{
|
||||
TRACE("edgeTxResume");
|
||||
|
||||
sdMount();
|
||||
if (!sdMounted()) sdInit();
|
||||
#if defined(COLORLCD) && defined(LUA)
|
||||
// reload widgets
|
||||
luaInitThemesAndWidgets();
|
||||
@@ -1596,7 +1597,7 @@ int main()
|
||||
checkValidMCU();
|
||||
#endif
|
||||
|
||||
#if defined(PCBHORUS)
|
||||
#if defined(IS_FIRMWARE_COMPATIBLE_WITH_BOARD)
|
||||
if (!IS_FIRMWARE_COMPATIBLE_WITH_BOARD()) {
|
||||
runFatalErrorScreen(STR_WRONG_PCBREV);
|
||||
}
|
||||
|
||||
@@ -451,12 +451,8 @@ enum FunctionsActive {
|
||||
FUNCTION_BACKGND_MUSIC_PAUSE,
|
||||
FUNCTION_BACKLIGHT,
|
||||
FUNCTION_RACING_MODE,
|
||||
#if defined(HARDWARE_TOUCH)
|
||||
FUNCTION_DISABLE_TOUCH,
|
||||
#endif
|
||||
#if defined(AUDIO_MUTE_GPIO)
|
||||
FUNCTION_DISABLE_AUDIO_AMP,
|
||||
#endif
|
||||
};
|
||||
|
||||
#define VARIO_FREQUENCY_ZERO 700/*Hz*/
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright (C) EdgeTX
|
||||
*
|
||||
* Based on code named
|
||||
* opentx - https://github.com/opentx/opentx
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include "fw_desc.h"
|
||||
|
||||
// Symbols from linker script
|
||||
extern uint32_t _estack;
|
||||
extern uint32_t _firmware_length;
|
||||
extern uint32_t _firmware_version;
|
||||
|
||||
extern void Reset_Handler();
|
||||
|
||||
__attribute__((section(".fwdescription"), used))
|
||||
firmware_description_t _fw_desc = {
|
||||
.stack_address = &_estack,
|
||||
.reset_handler = (void*)Reset_Handler,
|
||||
.length = (uint32_t)&_firmware_length,
|
||||
.version_ptr = (uintptr_t)&_firmware_version,
|
||||
};
|
||||
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright (C) EdgeTX
|
||||
*
|
||||
* Based on code named
|
||||
* opentx - https://github.com/opentx/opentx
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
typedef struct {
|
||||
// Allows the bootloader to load
|
||||
// the firmware as if this would
|
||||
// be the vector table.
|
||||
void* stack_address;
|
||||
void* reset_handler;
|
||||
|
||||
// TODO: insert some magic tag here
|
||||
uint32_t length;
|
||||
uint32_t version_ptr;
|
||||
// .. and here ?
|
||||
} firmware_description_t;
|
||||
|
||||
@@ -37,5 +37,5 @@ extern const char vers_stamp[];
|
||||
* (the one not running) or the buffer
|
||||
* @param buffer If non-null find the firmware version in the buffer instead
|
||||
*/
|
||||
const char * getFirmwareVersion(const char * buffer = nullptr);
|
||||
const char * getFirmwareVersion(const uint8_t* buffer = nullptr);
|
||||
#endif
|
||||
|
||||
@@ -64,12 +64,12 @@ uint16_t lcdColorTable[] = {
|
||||
|
||||
uint32_t HSVtoRGB(float H, float S, float V)
|
||||
{
|
||||
if (H > 360 || H < 0 || S > 100 || S < 0 || V > 100 || V < 0) {
|
||||
if (H > 360 || H < 0 || S > MAX_SATURATION || S < 0 || V > MAX_BRIGHTNESS || V < 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
float s = S / 100;
|
||||
float v = V / 100;
|
||||
float s = S / MAX_SATURATION;
|
||||
float v = V / MAX_BRIGHTNESS;
|
||||
float C = s * v;
|
||||
float X = C * (1 - abs(fmod(H / 60.0, 2) - 1));
|
||||
float m = v - C;
|
||||
@@ -95,6 +95,39 @@ uint32_t HSVtoRGB(float H, float S, float V)
|
||||
return RGB(R, G, B);
|
||||
}
|
||||
|
||||
uint32_t HSVtoRGB32(float H, float S, float V)
|
||||
{
|
||||
if (H > 360 || H < 0 || S > MAX_SATURATION || S < 0 || V > MAX_BRIGHTNESS || V < 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
float s = S / MAX_SATURATION;
|
||||
float v = V / MAX_BRIGHTNESS;
|
||||
float C = s * v;
|
||||
float X = C * (1 - abs(fmod(H / 60.0, 2) - 1));
|
||||
float m = v - C;
|
||||
float r, g, b;
|
||||
|
||||
if (H >= 0 && H < 60) {
|
||||
r = C, g = X, b = 0;
|
||||
} else if (H >= 60 && H < 120) {
|
||||
r = X, g = C, b = 0;
|
||||
} else if (H >= 120 && H < 180) {
|
||||
r = 0, g = C, b = X;
|
||||
} else if (H >= 180 && H < 240) {
|
||||
r = 0, g = X, b = C;
|
||||
} else if (H >= 240 && H < 300) {
|
||||
r = X, g = 0, b = C;
|
||||
} else {
|
||||
r = C, g = 0, b = X;
|
||||
}
|
||||
int R = (r + m) * 255;
|
||||
int G = (g + m) * 255;
|
||||
int B = (b + m) * 255;
|
||||
|
||||
return RGB32(R, G, B);
|
||||
}
|
||||
|
||||
void RGBtoHSV(uint8_t R, uint8_t G, uint8_t B, float &fH, float &fS, float &fV)
|
||||
{
|
||||
float fR = (float)R / 255;
|
||||
@@ -152,6 +185,19 @@ LcdFlags colorToRGB(LcdFlags colorFlags)
|
||||
return (colorFlags & 0xFFFF) | COLOR(COLOR_VAL(colorFlags)) | RGB_FLAG;
|
||||
}
|
||||
|
||||
uint32_t color32ToRGB(uint32_t color)
|
||||
{
|
||||
// RGB or indexed color?
|
||||
if (color & RGB888_FLAG)
|
||||
return color;
|
||||
|
||||
color = COLOR_VAL(COLOR(color));
|
||||
auto r = GET_RED(color);
|
||||
auto g = GET_GREEN(color);
|
||||
auto b = GET_BLUE(color);
|
||||
return RGB32(r, g, b) | RGB888_FLAG;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to translate a colorFlags value to a lv_color_t suitable
|
||||
* for passing to an lv_obj function
|
||||
|
||||
@@ -132,9 +132,25 @@ constexpr int MAX_HUE = 360;
|
||||
constexpr int MAX_BRIGHTNESS = 100;
|
||||
|
||||
extern uint32_t HSVtoRGB(float H, float S, float V);
|
||||
extern uint32_t HSVtoRGB32(float H, float S, float V);
|
||||
extern void RGBtoHSV(uint8_t R, uint8_t G, uint8_t B, float& fH, float& fS,
|
||||
float& fV);
|
||||
|
||||
LcdFlags colorToRGB(LcdFlags colorFlags);
|
||||
uint32_t color32ToRGB(uint32_t color);
|
||||
|
||||
lv_color_t makeLvColor(uint32_t colorFlags);
|
||||
|
||||
constexpr uint32_t RGB888_FLAG = 0x1000000;
|
||||
|
||||
enum COLOR_EDITOR_FMT {
|
||||
RGB565 = 0,
|
||||
RGB888
|
||||
};
|
||||
|
||||
#define RGB32(r, g, b) \
|
||||
(uint32_t)((((r) & 0xFF) << 16) + (((g) & 0xFF) << 8) + ((b) & 0xFF))
|
||||
|
||||
#define GET_RED32(color) (((color) & 0xFF0000) >> 16)
|
||||
#define GET_GREEN32(color) (((color) & 0x00FF00) >> 8)
|
||||
#define GET_BLUE32(color) ((color) & 0x0000FF)
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include "color_editor.h"
|
||||
|
||||
#include "button.h"
|
||||
@@ -162,7 +163,7 @@ class ColorBar : public FormField
|
||||
p2.x = area->x2 - 1;
|
||||
}
|
||||
auto c = bar->getRGB(bar->screenToValue(i));
|
||||
line_dsc.color = lv_color_make(GET_RED(c), GET_GREEN(c), GET_BLUE(c));
|
||||
line_dsc.color = lv_color_make(GET_RED32(c), GET_GREEN32(c), GET_BLUE32(c));
|
||||
lv_draw_line(dsc->draw_ctx, &line_dsc, &p1, &p2);
|
||||
}
|
||||
|
||||
@@ -289,42 +290,42 @@ class HSVColorType : public BarColorType
|
||||
public:
|
||||
HSVColorType(Window* parent, uint32_t color) : BarColorType(parent)
|
||||
{
|
||||
auto rgb = COLOR_VAL(colorToRGB(color));
|
||||
auto rgb = color32ToRGB(color);
|
||||
|
||||
auto r = GET_RED(rgb), g = GET_GREEN(rgb), b = GET_BLUE(rgb);
|
||||
auto r = GET_RED32(rgb), g = GET_GREEN32(rgb), b = GET_BLUE32(rgb);
|
||||
float values[MAX_BARS];
|
||||
RGBtoHSV(r, g, b, values[0], values[1], values[2]);
|
||||
values[1] *= MAX_SATURATION; // convert the proper base
|
||||
values[2] *= MAX_BRIGHTNESS;
|
||||
|
||||
for (auto i = 0; i < MAX_BARS; i++) {
|
||||
bars[i]->maxValue = i == 0 ? MAX_HUE : MAX_BRIGHTNESS;
|
||||
bars[i]->maxValue = (i == 0) ? MAX_HUE : (i == 1) ? MAX_SATURATION : MAX_BRIGHTNESS;
|
||||
bars[i]->invert = i != 0;
|
||||
bars[i]->value = values[i];
|
||||
}
|
||||
|
||||
// hue
|
||||
bars[0]->getRGB = [=](int pos) {
|
||||
auto rgb = HSVtoRGB(pos, bars[1]->value, bars[2]->value);
|
||||
auto rgb = HSVtoRGB32(pos, bars[1]->value, bars[2]->value);
|
||||
return rgb;
|
||||
};
|
||||
|
||||
// saturation
|
||||
bars[1]->getRGB = [=](int pos) {
|
||||
auto rgb = HSVtoRGB(bars[0]->value, pos, bars[2]->value);
|
||||
auto rgb = HSVtoRGB32(bars[0]->value, pos, bars[2]->value);
|
||||
return rgb;
|
||||
};
|
||||
|
||||
// brightness
|
||||
bars[2]->getRGB = [=](int pos) {
|
||||
auto rgb = HSVtoRGB(bars[0]->value, bars[1]->value, pos);
|
||||
auto rgb = HSVtoRGB32(bars[0]->value, bars[1]->value, pos);
|
||||
return rgb;
|
||||
};
|
||||
}
|
||||
|
||||
uint32_t getRGB() override
|
||||
{
|
||||
return COLOR2FLAGS(HSVtoRGB(bars[0]->value, bars[1]->value, bars[2]->value)) | RGB_FLAG;
|
||||
return HSVtoRGB32(bars[0]->value, bars[1]->value, bars[2]->value) | RGB888_FLAG;
|
||||
}
|
||||
|
||||
protected:
|
||||
@@ -337,9 +338,9 @@ class RGBColorType : public BarColorType
|
||||
public:
|
||||
RGBColorType(Window* parent, uint32_t color) : BarColorType(parent)
|
||||
{
|
||||
auto rgb = COLOR_VAL(colorToRGB(color));
|
||||
auto rgb = color32ToRGB(color);
|
||||
|
||||
auto r = GET_RED(rgb), g = GET_GREEN(rgb), b = GET_BLUE(rgb);
|
||||
auto r = GET_RED32(rgb), g = GET_GREEN32(rgb), b = GET_BLUE32(rgb);
|
||||
float values[MAX_BARS];
|
||||
values[0] = r;
|
||||
values[1] = g;
|
||||
@@ -351,14 +352,14 @@ class RGBColorType : public BarColorType
|
||||
bars[i]->invert = true;
|
||||
}
|
||||
|
||||
bars[0]->getRGB = [=](int pos) { return RGB(pos, 0, 0); };
|
||||
bars[1]->getRGB = [=](int pos) { return RGB(0, pos, 0); };
|
||||
bars[2]->getRGB = [=](int pos) { return RGB(0, 0, pos); };
|
||||
bars[0]->getRGB = [=](int pos) { return RGB32(pos, 0, 0); };
|
||||
bars[1]->getRGB = [=](int pos) { return RGB32(0, pos, 0); };
|
||||
bars[2]->getRGB = [=](int pos) { return RGB32(0, 0, pos); };
|
||||
}
|
||||
|
||||
uint32_t getRGB() override
|
||||
{
|
||||
return RGB2FLAGS(bars[0]->value, bars[1]->value, bars[2]->value);
|
||||
return RGB32(bars[0]->value, bars[1]->value, bars[2]->value) | RGB888_FLAG;
|
||||
}
|
||||
|
||||
protected:
|
||||
@@ -396,7 +397,7 @@ class ThemeColorType : public ColorType
|
||||
auto btn = new TextButton(parent, rect_t{}, " ");
|
||||
etx_bg_color(btn->getLvObj(), (LcdColorIndex)color);
|
||||
btn->setPressHandler([=]() {
|
||||
m_color = COLOR2FLAGS(color);
|
||||
m_color = color;
|
||||
lv_event_send(parent->getParent()->getParent()->getLvObj(),
|
||||
LV_EVENT_VALUE_CHANGED, nullptr);
|
||||
return 0;
|
||||
@@ -421,14 +422,31 @@ class ThemeColorType : public ColorType
|
||||
////// ColorEditor Base class
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
ColorEditor::ColorEditor(Window* parent, const rect_t& rect, uint32_t color,
|
||||
std::function<void(uint32_t rgb)> setValue) :
|
||||
Window(parent, rect), _setValue(std::move(setValue)), _color(color)
|
||||
std::function<void(uint32_t rgb)> setValue,
|
||||
std::function<void(uint32_t rgb)> preview,
|
||||
COLOR_EDITOR_FMT fmt) :
|
||||
Window(parent, rect), _setValue(std::move(setValue)), _preview(std::move(preview)),
|
||||
format(fmt)
|
||||
{
|
||||
_colorType = new HSVColorType(this, color);
|
||||
if (format == RGB565) {
|
||||
if (color & RGB_FLAG) {
|
||||
color = COLOR_VAL(color);
|
||||
auto r = GET_RED(color);
|
||||
auto g = GET_GREEN(color);
|
||||
auto b = GET_BLUE(color);
|
||||
color = RGB32(r, g, b) | RGB888_FLAG;
|
||||
} else {
|
||||
color = COLOR_VAL(color);
|
||||
}
|
||||
}
|
||||
_color = color;
|
||||
_colorType = new HSVColorType(this, _color);
|
||||
_colorType->setText();
|
||||
|
||||
lv_obj_add_event_cb(lvobj, ColorEditor::value_changed, LV_EVENT_VALUE_CHANGED,
|
||||
nullptr);
|
||||
|
||||
if (_preview) _preview(_color);
|
||||
}
|
||||
|
||||
void ColorEditor::setColorEditorType(COLOR_EDITOR_TYPE colorType)
|
||||
@@ -439,10 +457,10 @@ void ColorEditor::setColorEditorType(COLOR_EDITOR_TYPE colorType)
|
||||
}
|
||||
if (colorType == RGB_COLOR_EDITOR) {
|
||||
_colorType = new RGBColorType(this, _color);
|
||||
setRGB();
|
||||
setText();
|
||||
} else if (colorType == HSV_COLOR_EDITOR) {
|
||||
_colorType = new HSVColorType(this, _color);
|
||||
setHSV();
|
||||
setText();
|
||||
} else {
|
||||
_colorType = new ThemeColorType(this, _color);
|
||||
setText();
|
||||
@@ -454,7 +472,20 @@ void ColorEditor::setColorEditorType(COLOR_EDITOR_TYPE colorType)
|
||||
void ColorEditor::setText()
|
||||
{
|
||||
_colorType->setText();
|
||||
if (_setValue != nullptr) _setValue(_color);
|
||||
if (_setValue != nullptr) {
|
||||
uint32_t c = _color;
|
||||
if (format == RGB565) {
|
||||
if (c & RGB888_FLAG) {
|
||||
auto r = GET_RED32(c);
|
||||
auto g = GET_GREEN32(c);
|
||||
auto b = GET_BLUE32(c);
|
||||
c = RGB2FLAGS(r, g, b);
|
||||
} else {
|
||||
c = COLOR2FLAGS(c);
|
||||
}
|
||||
}
|
||||
_setValue(c);
|
||||
}
|
||||
}
|
||||
|
||||
void ColorEditor::setRGB()
|
||||
@@ -462,12 +493,7 @@ void ColorEditor::setRGB()
|
||||
_color = _colorType->getRGB();
|
||||
// update bars & labels
|
||||
setText();
|
||||
}
|
||||
|
||||
void ColorEditor::setHSV()
|
||||
{
|
||||
// update bars & labels
|
||||
setText();
|
||||
if (_preview) _preview(_color);
|
||||
}
|
||||
|
||||
void ColorEditor::value_changed(lv_event_t* e)
|
||||
|
||||
@@ -37,7 +37,9 @@ class ColorEditor : public Window
|
||||
{
|
||||
public:
|
||||
ColorEditor(Window* parent, const rect_t& rect, uint32_t color,
|
||||
std::function<void(uint32_t rgb)> setValue = nullptr);
|
||||
std::function<void(uint32_t rgb)> setValue = nullptr,
|
||||
std::function<void(uint32_t rgb)> preview = nullptr,
|
||||
COLOR_EDITOR_FMT fmt = RGB565);
|
||||
|
||||
#if defined(DEBUG_WINDOWS)
|
||||
std::string getName() const override { return "ColorEditor"; }
|
||||
@@ -57,10 +59,11 @@ class ColorEditor : public Window
|
||||
protected:
|
||||
ColorType* _colorType = nullptr;
|
||||
std::function<void(uint32_t)> _setValue;
|
||||
std::function<void(uint32_t)> _preview;
|
||||
uint32_t _color;
|
||||
COLOR_EDITOR_FMT format;
|
||||
|
||||
void setText();
|
||||
void setHSV();
|
||||
void setRGB();
|
||||
static void value_changed(lv_event_t* e);
|
||||
};
|
||||
|
||||
@@ -21,7 +21,6 @@
|
||||
|
||||
#include "color_picker.h"
|
||||
|
||||
#include "color_editor.h"
|
||||
#include "color_list.h"
|
||||
#include "etx_lv_theme.h"
|
||||
|
||||
@@ -44,14 +43,23 @@ class ColorEditorPopup : public BaseDialog
|
||||
ColorSwatch* colorPad = nullptr;
|
||||
StaticText* hexStr = nullptr;
|
||||
uint32_t m_color;
|
||||
uint32_t origColor;
|
||||
std::function<void(uint32_t)> setValue;
|
||||
COLOR_EDITOR_FMT format;
|
||||
|
||||
void updateColor(uint32_t c)
|
||||
{
|
||||
m_color = c;
|
||||
|
||||
auto rgb = COLOR_VAL(colorToRGB(m_color));
|
||||
uint8_t r, g, b;
|
||||
|
||||
uint8_t r = GET_RED(rgb), g = GET_GREEN(rgb), b = GET_BLUE(rgb);
|
||||
if (format == RGB565) {
|
||||
auto rgb = COLOR_VAL(colorToRGB(m_color));
|
||||
r = GET_RED(rgb); g = GET_GREEN(rgb); b = GET_BLUE(rgb);
|
||||
} else {
|
||||
auto rgb = color32ToRGB(m_color);
|
||||
r = GET_RED32(rgb); g = GET_GREEN32(rgb); b = GET_BLUE32(rgb);
|
||||
}
|
||||
|
||||
colorPad->setColor(r, g, b);
|
||||
|
||||
@@ -60,18 +68,27 @@ class ColorEditorPopup : public BaseDialog
|
||||
hexStr->setText(s);
|
||||
}
|
||||
|
||||
void onCancel() override
|
||||
{
|
||||
if (setValue) setValue(origColor);
|
||||
this->deleteLater();
|
||||
}
|
||||
|
||||
public:
|
||||
ColorEditorPopup(uint32_t color,
|
||||
std::function<void(uint32_t)> _setValue) :
|
||||
std::function<void(uint32_t)> _setValue,
|
||||
std::function<void(uint32_t)> _preview,
|
||||
COLOR_EDITOR_FMT fmt) :
|
||||
BaseDialog(STR_COLOR_PICKER, false, COLOR_EDIT_WIDTH,
|
||||
LV_SIZE_CONTENT)
|
||||
LV_SIZE_CONTENT),
|
||||
origColor(color), setValue(std::move(_setValue)), format(fmt)
|
||||
{
|
||||
FlexGridLayout grid(col_dsc, row_dsc);
|
||||
auto line = form->newLine(grid);
|
||||
|
||||
rect_t r{0, 0, CE_SZ, CE_SZ};
|
||||
auto cedit =
|
||||
new ColorEditor(line, r, color, [=](uint32_t c) { updateColor(c); });
|
||||
new ColorEditor(line, r, color, [=](uint32_t c) { updateColor(c); }, _preview, format);
|
||||
lv_obj_set_style_grid_cell_x_align(cedit->getLvObj(), LV_GRID_ALIGN_CENTER,
|
||||
0);
|
||||
|
||||
@@ -138,12 +155,12 @@ class ColorEditorPopup : public BaseDialog
|
||||
lv_obj_set_flex_grow(hbox->getLvObj(), 1);
|
||||
|
||||
new TextButton(hbox, rect_t{0, 0, BTN_W, 0}, STR_CANCEL, [=]() -> int8_t {
|
||||
this->deleteLater();
|
||||
onCancel();
|
||||
return 0;
|
||||
});
|
||||
|
||||
new TextButton(hbox, rect_t{0, 0, BTN_W, 0}, STR_SAVE, [=]() -> int8_t {
|
||||
if (_setValue) _setValue(m_color);
|
||||
if (setValue) setValue(m_color);
|
||||
this->deleteLater();
|
||||
return 0;
|
||||
});
|
||||
@@ -161,16 +178,18 @@ class ColorEditorPopup : public BaseDialog
|
||||
|
||||
ColorPicker::ColorPicker(Window* parent, const rect_t& rect,
|
||||
std::function<uint32_t()> getValue,
|
||||
std::function<void(uint32_t)> setValue) :
|
||||
Button(parent, {rect.x, rect.y, ColorEditorPopup::COLOR_PAD_WIDTH, ColorEditorPopup::COLOR_PAD_HEIGHT}),
|
||||
setValue(std::move(setValue))
|
||||
std::function<void(uint32_t)> setValue,
|
||||
std::function<void(uint32_t)> preview,
|
||||
COLOR_EDITOR_FMT fmt) :
|
||||
Button(parent, {rect.x, rect.y, rect.w == 0 ? ColorEditorPopup::COLOR_PAD_WIDTH : rect.w, ColorEditorPopup::COLOR_PAD_HEIGHT}),
|
||||
setValue(std::move(setValue)), preview(std::move(preview)), format(fmt)
|
||||
{
|
||||
updateColor(getValue());
|
||||
}
|
||||
|
||||
void ColorPicker::onClicked()
|
||||
{
|
||||
new ColorEditorPopup(getColor(), [=](uint32_t c) { setColor(c); });
|
||||
new ColorEditorPopup(getColor(), [=](uint32_t c) { setColor(c); }, preview, format);
|
||||
}
|
||||
|
||||
void ColorPicker::setColor(uint32_t c)
|
||||
@@ -183,8 +202,16 @@ void ColorPicker::updateColor(uint32_t c)
|
||||
{
|
||||
color = c;
|
||||
|
||||
auto rgb = COLOR_VAL(colorToRGB(color));
|
||||
auto lvcolor =
|
||||
lv_color_make(GET_RED(rgb), GET_GREEN(rgb), GET_BLUE(rgb));
|
||||
uint8_t r, g, b;
|
||||
|
||||
if (format == RGB565) {
|
||||
auto rgb = COLOR_VAL(colorToRGB(color));
|
||||
r = GET_RED(rgb); g = GET_GREEN(rgb); b = GET_BLUE(rgb);
|
||||
} else {
|
||||
auto rgb = color32ToRGB(color);
|
||||
r = GET_RED32(rgb); g = GET_GREEN32(rgb); b = GET_BLUE32(rgb);
|
||||
}
|
||||
|
||||
auto lvcolor = lv_color_make(r, g, b);
|
||||
lv_obj_set_style_bg_color(lvobj, lvcolor, LV_PART_MAIN);
|
||||
}
|
||||
|
||||
@@ -22,18 +22,23 @@
|
||||
#pragma once
|
||||
|
||||
#include "button.h"
|
||||
#include "color_editor.h"
|
||||
|
||||
class ColorPicker : public Button
|
||||
{
|
||||
uint32_t color;
|
||||
std::function<void(uint32_t)> setValue;
|
||||
std::function<void(uint32_t)> preview;
|
||||
COLOR_EDITOR_FMT format;
|
||||
|
||||
void updateColor(uint32_t c);
|
||||
|
||||
public:
|
||||
ColorPicker(Window* parent, const rect_t& rect,
|
||||
std::function<uint32_t()> getValue,
|
||||
std::function<void(uint32_t)> setValue = nullptr);
|
||||
std::function<void(uint32_t)> setValue = nullptr,
|
||||
std::function<void(uint32_t)> preview = nullptr,
|
||||
COLOR_EDITOR_FMT fmt = RGB565);
|
||||
|
||||
void setColor(uint32_t c);
|
||||
uint32_t getColor() const { return color; }
|
||||
|
||||
@@ -56,7 +56,10 @@ class NumberArea : public FormField
|
||||
#if defined(DEBUG_WINDOWS)
|
||||
std::string getName() const override
|
||||
{
|
||||
return "NumberArea(" + std::to_string(getValue()) + ")";
|
||||
if(numEdit)
|
||||
return "NumberArea(" + numEdit->getName() + ")";
|
||||
else
|
||||
return "NumberArea(unknown)";
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@ class TextEdit : public TextButton
|
||||
std::function<void(void)> updateHandler = nullptr);
|
||||
|
||||
#if defined(DEBUG_WINDOWS)
|
||||
std::string getName() const override { return "TextEdit \"" + text + "\""; }
|
||||
std::string getName() const override { return std::string("TextEdit \"") + text + "\""; }
|
||||
#endif
|
||||
|
||||
void preview(bool edited, char* text, uint8_t length);
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
/* clang-format off */
|
||||
|
||||
#include <stdint.h>
|
||||
#include "definitions.h"
|
||||
|
||||
/*====================
|
||||
COLOR SETTINGS
|
||||
@@ -185,8 +186,10 @@
|
||||
#if LV_USE_GPU_STM32_DMA2D
|
||||
/*Must be defined to include path of CMSIS header of target processor
|
||||
e.g. "stm32f769xx.h" or "stm32f429xx.h"*/
|
||||
#ifdef STM32H7
|
||||
#if defined(STM32H7)
|
||||
#define LV_GPU_DMA2D_CMSIS_INCLUDE "stm32h7xx.h"
|
||||
#elif defined(STM32H7RS)
|
||||
#define LV_GPU_DMA2D_CMSIS_INCLUDE "stm32h7rsxx.h"
|
||||
#else
|
||||
#define LV_GPU_DMA2D_CMSIS_INCLUDE "stm32f4xx.h"
|
||||
#endif
|
||||
@@ -353,10 +356,10 @@
|
||||
#define LV_ATTRIBUTE_LARGE_RAM_ARRAY
|
||||
|
||||
/*Place performance critical functions into a faster memory (e.g RAM)*/
|
||||
#define LV_ATTRIBUTE_FAST_MEM
|
||||
#define LV_ATTRIBUTE_FAST_MEM __IRAM
|
||||
|
||||
/*Prefix variables that are used in GPU accelerated operations, often these need to be placed in RAM sections that are DMA accessible*/
|
||||
#define LV_ATTRIBUTE_DMA
|
||||
#define LV_ATTRIBUTE_DMA __DMA
|
||||
|
||||
/*Export integer constant to binding. This macro is used with constants in the form of LV_<CONST> that
|
||||
*should also appear on LVGL binding API such as Micropython.*/
|
||||
|
||||
@@ -28,20 +28,21 @@
|
||||
#include "switches.h"
|
||||
#include "color_picker.h"
|
||||
|
||||
#if defined(FUNCTION_SWITCHES_RGB_LEDS)
|
||||
static constexpr coord_t LH = 72;
|
||||
#else
|
||||
static constexpr coord_t LH = 36;
|
||||
#endif
|
||||
|
||||
#define SET_DIRTY() storageDirty(EE_MODEL)
|
||||
|
||||
static const lv_coord_t line_col_dsc1[] = {LV_GRID_CONTENT,
|
||||
LV_GRID_TEMPLATE_LAST};
|
||||
|
||||
#if defined(FUNCTION_SWITCHES_RGB_LEDS)
|
||||
static const lv_coord_t line_col_dsc2[] = {
|
||||
LV_GRID_FR(13), LV_GRID_FR(11), LV_GRID_FR(11),
|
||||
LV_GRID_FR(12), LV_GRID_FR(10), LV_GRID_FR(7), LV_GRID_FR(7),
|
||||
LV_GRID_TEMPLATE_LAST};
|
||||
#else
|
||||
static const lv_coord_t line_col_dsc2[] = {
|
||||
LV_GRID_FR(10), LV_GRID_FR(10), LV_GRID_FR(10),
|
||||
LV_GRID_FR(12), LV_GRID_FR(8), LV_GRID_TEMPLATE_LAST};
|
||||
#endif
|
||||
|
||||
static const lv_coord_t line_row_dsc[] = {LV_GRID_CONTENT,
|
||||
LV_GRID_TEMPLATE_LAST};
|
||||
@@ -124,60 +125,110 @@ class FunctionSwitch : public Window
|
||||
});
|
||||
|
||||
#if defined(FUNCTION_SWITCHES_RGB_LEDS)
|
||||
new StaticText(this, {8 , 6 + 36, SW_W, EdgeTxStyles::PAGE_LINE_HEIGHT}, STR_FS_OFF_COLOR, COLOR_THEME_PRIMARY1);
|
||||
offValue = g_model.functionSwitchLedOFFColor[switchIndex];
|
||||
onValue = g_model.functionSwitchLedONColor[switchIndex];
|
||||
|
||||
auto offcolor = new ColorPicker(
|
||||
this, rect_t{},
|
||||
offColor = new ColorPicker(
|
||||
this, {C1_X, 0, C1_W, 0},
|
||||
[=]() -> int { // getValue
|
||||
return g_model.functionSwitchLedOFFColor[switchIndex];
|
||||
return g_model.functionSwitchLedOFFColor[switchIndex].getColor();
|
||||
},
|
||||
[=](int newValue) { // setValue
|
||||
g_model.functionSwitchLedOFFColor[switchIndex] =
|
||||
(uint32_t)newValue;
|
||||
TRACE("Color: %x", g_model.functionSwitchLedOFFColor[switchIndex]);
|
||||
g_model.functionSwitchLedOFFColor[switchIndex] = offValue;
|
||||
g_model.functionSwitchLedONColor[switchIndex] = onValue;
|
||||
|
||||
// Convert color index to RGB
|
||||
newValue = color32ToRGB(newValue);
|
||||
g_model.functionSwitchLedOFFColor[switchIndex].setColor(newValue);
|
||||
|
||||
offValue = g_model.functionSwitchLedOFFColor[switchIndex];
|
||||
SET_DIRTY();
|
||||
});
|
||||
offcolor->setPos(NM_X, 36);
|
||||
},
|
||||
[=](int newValue) { previewColor(newValue); }, RGB888);
|
||||
|
||||
new StaticText(this, {TP_X, 6 + 36, SW_W, EdgeTxStyles::PAGE_LINE_HEIGHT}, STR_FS_ON_COLOR, COLOR_THEME_PRIMARY1);
|
||||
|
||||
auto oncolor = new ColorPicker(
|
||||
this, rect_t{},
|
||||
onColor = new ColorPicker(
|
||||
this, {C2_X, 0, C2_W, 0},
|
||||
[=]() -> int { // getValue
|
||||
return g_model.functionSwitchLedONColor[switchIndex];
|
||||
return g_model.functionSwitchLedONColor[switchIndex].getColor();
|
||||
},
|
||||
[=](int newValue) { // setValue
|
||||
g_model.functionSwitchLedONColor[switchIndex] =
|
||||
(uint32_t)newValue;
|
||||
g_model.functionSwitchLedOFFColor[switchIndex] = offValue;
|
||||
g_model.functionSwitchLedONColor[switchIndex] = onValue;
|
||||
|
||||
// Convert color index to RGB
|
||||
newValue = color32ToRGB(newValue);
|
||||
g_model.functionSwitchLedONColor[switchIndex].setColor(newValue);
|
||||
|
||||
onValue = g_model.functionSwitchLedONColor[switchIndex];
|
||||
SET_DIRTY();
|
||||
});
|
||||
oncolor->setPos(GR_X, 36);
|
||||
},
|
||||
[=](int newValue) { previewColor(newValue); }, RGB888);
|
||||
#endif //FUNCTION_SWITCHES_RGB_LEDS
|
||||
|
||||
setState();
|
||||
}
|
||||
|
||||
static constexpr coord_t SW_W = (LCD_W - 4 * 2 - 2 * 4) / 5;
|
||||
static constexpr coord_t NM_X = SW_W + 2;
|
||||
#if defined(FUNCTION_SWITCHES_RGB_LEDS)
|
||||
static constexpr coord_t SW_X = PAD_SMALL;
|
||||
static constexpr coord_t SW_W = 70;
|
||||
static constexpr coord_t NM_X = SW_X + SW_W;
|
||||
static constexpr coord_t NM_W = 60;
|
||||
static constexpr coord_t TP_X = NM_X + NM_W + PAD_SMALL;
|
||||
static constexpr coord_t TP_W = 78;
|
||||
static constexpr coord_t GR_X = TP_X + TP_W + PAD_SMALL;
|
||||
static constexpr coord_t GR_W = 84;
|
||||
static constexpr coord_t ST_X = GR_X + GR_W + PAD_SMALL;
|
||||
static constexpr coord_t ST_W = 60;
|
||||
static constexpr coord_t C1_X = ST_X + ST_W + PAD_SMALL;
|
||||
static constexpr coord_t C1_W = 40;
|
||||
static constexpr coord_t C2_X = C1_X + C1_W + PAD_SMALL;
|
||||
static constexpr coord_t C2_W = 40;
|
||||
#else
|
||||
static constexpr coord_t SW_W = (LCD_W - PAD_SMALL * 2 - PAD_TINY_GAP * 4) / 5;
|
||||
static constexpr coord_t NM_X = SW_W + PAD_TINY_GAP;
|
||||
static constexpr coord_t NM_W = 80;
|
||||
static constexpr coord_t TP_X = NM_X + SW_W + 2;
|
||||
static constexpr coord_t TP_X = NM_X + SW_W + PAD_TINY_GAP;
|
||||
static constexpr coord_t TP_W = 86;
|
||||
static constexpr coord_t GR_X = TP_X + SW_W + 2;
|
||||
static constexpr coord_t GR_X = TP_X + SW_W + PAD_TINY_GAP;
|
||||
static constexpr coord_t GR_W = 94;
|
||||
static constexpr coord_t ST_X = GR_X + SW_W + 20;
|
||||
static constexpr coord_t ST_W = 70;
|
||||
#endif
|
||||
|
||||
protected:
|
||||
uint8_t switchIndex;
|
||||
Choice* typeChoice = nullptr;
|
||||
Choice* groupChoice = nullptr;
|
||||
Choice* startChoice = nullptr;
|
||||
#if defined(FUNCTION_SWITCHES_RGB_LEDS)
|
||||
ColorPicker* offColor = nullptr;
|
||||
ColorPicker* onColor = nullptr;
|
||||
RGBLedColor offValue;
|
||||
RGBLedColor onValue;
|
||||
#endif
|
||||
int lastType = -1;
|
||||
|
||||
#if defined(FUNCTION_SWITCHES_RGB_LEDS)
|
||||
void previewColor(int newValue)
|
||||
{
|
||||
// Convert color index to RGB
|
||||
newValue = color32ToRGB(newValue);
|
||||
if (getFSLogicalState(switchIndex)) {
|
||||
g_model.functionSwitchLedONColor[switchIndex].setColor(newValue);
|
||||
} else {
|
||||
g_model.functionSwitchLedOFFColor[switchIndex].setColor(newValue);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void setState()
|
||||
{
|
||||
startChoice->show(FSWITCH_CONFIG(switchIndex) == SWITCH_2POS && FSWITCH_GROUP(switchIndex) == 0);
|
||||
groupChoice->show(FSWITCH_CONFIG(switchIndex) != SWITCH_NONE);
|
||||
#if defined(FUNCTION_SWITCHES_RGB_LEDS)
|
||||
offColor->show(FSWITCH_CONFIG(switchIndex) != SWITCH_NONE);
|
||||
onColor->show(FSWITCH_CONFIG(switchIndex) != SWITCH_NONE);
|
||||
#endif
|
||||
}
|
||||
|
||||
void checkEvents() override
|
||||
@@ -276,6 +327,10 @@ ModelFunctionSwitches::ModelFunctionSwitches() : Page(ICON_MODEL_SETUP)
|
||||
new StaticText(line, rect_t{}, STR_GROUP, COLOR_THEME_PRIMARY1_INDEX, FONT(XS));
|
||||
startupHeader = new StaticText(line, rect_t{}, STR_SWITCH_STARTUP,
|
||||
COLOR_THEME_PRIMARY1_INDEX, FONT(XS));
|
||||
#if defined(FUNCTION_SWITCHES_RGB_LEDS)
|
||||
new StaticText(line, rect_t{}, STR_OFF, COLOR_THEME_PRIMARY1_INDEX, FONT(XS));
|
||||
new StaticText(line, rect_t{}, STR_ON_ONE_SWITCHES[0], COLOR_THEME_PRIMARY1_INDEX, FONT(XS));
|
||||
#endif
|
||||
|
||||
for (uint8_t i = 0; i < NUM_FUNCTIONS_SWITCHES; i += 1) {
|
||||
new FunctionSwitch(body, i);
|
||||
|
||||
@@ -603,6 +603,7 @@ class ModuleSubTypeChoice : public Choice
|
||||
g_model.moduleData[moduleIdx].subType = newValue;
|
||||
SET_DIRTY();
|
||||
} else {
|
||||
#if defined(MULTIMODULE)
|
||||
g_model.moduleData[moduleIdx].multi.rfProtocol = newValue;
|
||||
g_model.moduleData[moduleIdx].subType = 0;
|
||||
resetMultiProtocolsOptions(moduleIdx);
|
||||
@@ -614,6 +615,7 @@ class ModuleSubTypeChoice : public Choice
|
||||
while (!status.isValid() && (RTOS_GET_MS() - startUpdate < 250))
|
||||
;
|
||||
SET_DIRTY();
|
||||
#endif
|
||||
}
|
||||
|
||||
if (moduleWindow)
|
||||
|
||||
@@ -88,4 +88,4 @@ RadioCustSwitchesDiagsPage::RadioCustSwitchesDiagsPage() :
|
||||
buildBody(body);
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
@@ -26,6 +26,7 @@
|
||||
#include "io/frsky_firmware_update.h"
|
||||
#include "io/multi_firmware_update.h"
|
||||
#include "io/bootloader_flash.h"
|
||||
#include "io/uf2_flash.h"
|
||||
#include "standalone_lua.h"
|
||||
#include "sdcard.h"
|
||||
#include "view_text.h"
|
||||
@@ -354,6 +355,7 @@ void RadioSdManagerPage::fileAction(const char* path, const char* name,
|
||||
menu->addLine(STR_FLASH_EXTERNAL_ELRS, [=]() {
|
||||
MultiFirmwareUpdate(fullpath, EXTERNAL_MODULE, MULTI_TYPE_ELRS);
|
||||
});
|
||||
#endif
|
||||
} else if (!strcasecmp(BITMAPS_PATH, path) &&
|
||||
isExtensionMatching(ext, BITMAPS_EXT) &&
|
||||
strlen(name) <= LEN_BITMAP_NAME) {
|
||||
@@ -382,10 +384,18 @@ void RadioSdManagerPage::fileAction(const char* path, const char* name,
|
||||
});
|
||||
}
|
||||
if (!strcasecmp(ext, FIRMWARE_EXT)) {
|
||||
#if defined(FIRMWARE_FORMAT_UF2)
|
||||
if (isUF2FirmwareFile(fullpath)) {
|
||||
menu->addLine(STR_FLASH_BOOTLOADER,
|
||||
[=]() { FirmwareUpdate(fullpath); });
|
||||
}
|
||||
#else
|
||||
if (isBootloader(fullpath)) {
|
||||
menu->addLine(STR_FLASH_BOOTLOADER,
|
||||
[=]() { BootloaderUpdate(fullpath); });
|
||||
}
|
||||
#endif
|
||||
#if defined(HARDWARE_INTERNAL_MODULE) || defined(HARDWARE_EXTERNAL_MODULE)
|
||||
} else if (!strcasecmp(ext, SPORT_FIRMWARE_EXT)) {
|
||||
|
||||
auto mod_desc = modulePortGetModuleDescription(SPORT_MODULE);
|
||||
@@ -535,6 +545,15 @@ void RadioSdManagerPage::fileAction(const char* path, const char* name,
|
||||
});
|
||||
}
|
||||
|
||||
#if defined(FIRMWARE_FORMAT_UF2)
|
||||
void RadioSdManagerPage::FirmwareUpdate(const char* fn)
|
||||
{
|
||||
UF2FirmwareUpdate firmwareUpdate;
|
||||
auto dialog =
|
||||
new FlashDialog<UF2FirmwareUpdate>(firmwareUpdate);
|
||||
dialog->flash(fn);
|
||||
}
|
||||
#else
|
||||
void RadioSdManagerPage::BootloaderUpdate(const char* fn)
|
||||
{
|
||||
BootloaderFirmwareUpdate bootloaderFirmwareUpdate;
|
||||
@@ -542,6 +561,7 @@ void RadioSdManagerPage::BootloaderUpdate(const char* fn)
|
||||
new FlashDialog<BootloaderFirmwareUpdate>(bootloaderFirmwareUpdate);
|
||||
dialog->flash(fn);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(BLUETOOTH)
|
||||
void RadioSdManagerPage::BluetoothFirmwareUpdate(const char* fn)
|
||||
@@ -551,6 +571,7 @@ void RadioSdManagerPage::BluetoothFirmwareUpdate(const char* fn)
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(HARDWARE_INTERNAL_MODULE) || defined(HARDWARE_EXTERNAL_MODULE)
|
||||
void RadioSdManagerPage::FrSkyFirmwareUpdate(const char* fn,
|
||||
ModuleIndex module)
|
||||
{
|
||||
@@ -569,3 +590,4 @@ void RadioSdManagerPage::MultiFirmwareUpdate(const char* fn,
|
||||
new FlashDialog<MultiDeviceFirmwareUpdate>(deviceFirmwareUpdate);
|
||||
dialog->flash(fn);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -48,14 +48,20 @@ class RadioSdManagerPage : public PageTab
|
||||
|
||||
void fileAction(const char* path, const char* name, const char* fullpath);
|
||||
void dirAction(const char* path, const char* name, const char* fullpath);
|
||||
|
||||
|
||||
#if defined(FIRMWARE_FORMAT_UF2)
|
||||
void FirmwareUpdate(const char* fn);
|
||||
#else
|
||||
void BootloaderUpdate(const char* fn);
|
||||
#endif
|
||||
#if defined(BLUETOOTH)
|
||||
void BluetoothFirmwareUpdate(const char* fn);
|
||||
#endif
|
||||
#if defined(HARDWARE_INTERNAL_MODULE) || defined(HARDWARE_EXTERNAL_MODULE)
|
||||
void FrSkyFirmwareUpdate(const char* fn, ModuleIndex module);
|
||||
void MultiFirmwareUpdate(const char* fn, ModuleIndex module,
|
||||
MultiModuleType type);
|
||||
#endif
|
||||
|
||||
void checkEvents() override;
|
||||
};
|
||||
|
||||
@@ -30,16 +30,25 @@ set(BOOTLOADER_SRC ${BOOTLOADER_SRC}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/hal/key_driver.cpp
|
||||
)
|
||||
|
||||
|
||||
if(FUNCTION_SWITCHES_WITH_RGB)
|
||||
set(SRC ${SRC}
|
||||
hal/rgbleds.cpp
|
||||
)
|
||||
endif()
|
||||
|
||||
if (NOT NATIVE_BUILD)
|
||||
set(SRC ${SRC}
|
||||
hal/storage.cpp
|
||||
hal/fatfs_diskio.cpp
|
||||
hal/flash_driver.cpp
|
||||
${FATFS_DIR}/ff.c
|
||||
${FATFS_DIR}/ffunicode.c
|
||||
)
|
||||
set(BOOTLOADER_SRC ${BOOTLOADER_SRC}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/hal/storage.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/hal/fatfs_diskio.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/hal/flash_driver.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/${FATFS_DIR}/ff.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/${FATFS_DIR}/ffunicode.c
|
||||
)
|
||||
|
||||
@@ -41,6 +41,12 @@ void abnormalRebootDisableDetection();
|
||||
// (see AbnormalRebootCause)
|
||||
uint32_t abnormalRebootGetCause();
|
||||
|
||||
// Retrieve last reboot command
|
||||
uint32_t abnormalRebootGetCmd();
|
||||
|
||||
// Reset reboot command
|
||||
void abnormalRebootResetCmd();
|
||||
|
||||
#define UNEXPECTED_SHUTDOWN() \
|
||||
(abnormalRebootGetCause() == ARC_Watchdog)
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
const etx_hal_adc_driver_t* _hal_adc_driver = nullptr;
|
||||
const etx_hal_adc_inputs_t* _hal_adc_inputs = nullptr;
|
||||
|
||||
static uint16_t adcValues[MAX_ANALOG_INPUTS] __DMA;
|
||||
static uint16_t adcValues[MAX_ANALOG_INPUTS] __DMA_NO_CACHE;
|
||||
|
||||
#if defined(CSD203_SENSOR)
|
||||
extern uint16_t getCSD203BatteryVoltage(void);
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
#include "hal/flash_driver.h"
|
||||
|
||||
typedef struct {
|
||||
const etx_flash_driver_t* drv;
|
||||
uint32_t start_addr;
|
||||
uint32_t end_addr;
|
||||
} flash_media_t;
|
||||
|
||||
static flash_media_t _flash_media[2] = {{nullptr, 0, 0}};
|
||||
|
||||
void flashRegisterDriver(uint32_t start_addr, uint32_t length,
|
||||
const etx_flash_driver_t* drv)
|
||||
{
|
||||
for (int i = 0; i < 2; i++) {
|
||||
flash_media_t& fm = _flash_media[i];
|
||||
if (fm.drv) continue;
|
||||
fm = {
|
||||
.drv = drv,
|
||||
.start_addr = start_addr,
|
||||
.end_addr = start_addr + length - 1,
|
||||
};
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
const etx_flash_driver_t* flashFindDriver(uint32_t addr)
|
||||
{
|
||||
for (int i = 0; i < 2; i++) {
|
||||
const flash_media_t& fm = _flash_media[i];
|
||||
if (!fm.drv) continue;
|
||||
if (fm.start_addr <= addr && fm.end_addr >= addr)
|
||||
return fm.drv;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
uint32_t flashGetSize(uint32_t addr)
|
||||
{
|
||||
for (int i = 0; i < 2; i++) {
|
||||
const flash_media_t& fm = _flash_media[i];
|
||||
if (!fm.drv) continue;
|
||||
if (fm.start_addr <= addr && fm.end_addr >= addr)
|
||||
return fm.end_addr - fm.start_addr + 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright (C) EdgeTX
|
||||
*
|
||||
* Based on code named
|
||||
* opentx - https://github.com/opentx/opentx
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
typedef struct {
|
||||
uint32_t (*get_size_kb)();
|
||||
uint32_t (*get_sector)(uint32_t address);
|
||||
uint32_t (*get_sector_size)(uint32_t sector);
|
||||
|
||||
int (*erase_sector)(uint32_t address);
|
||||
int (*program)(uint32_t address, void* data, uint32_t len);
|
||||
int (*read)(uint32_t address, void* data, uint32_t len);
|
||||
} etx_flash_driver_t;
|
||||
|
||||
void flashRegisterDriver(uint32_t start_addr, uint32_t length,
|
||||
const etx_flash_driver_t* drv);
|
||||
|
||||
const etx_flash_driver_t* flashFindDriver(uint32_t addr);
|
||||
uint32_t flashGetSize(uint32_t addr);
|
||||
@@ -1,5 +1,4 @@
|
||||
/*
|
||||
* Copyright (C) EdgeTX
|
||||
*
|
||||
* Based on code named
|
||||
* opentx - https://github.com/opentx/opentx
|
||||
@@ -49,4 +48,4 @@ void setFSLedON(uint8_t index) {
|
||||
bool getFSLedState(uint8_t index) {
|
||||
return fsLedState(index);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
@@ -1,5 +1,4 @@
|
||||
/*
|
||||
* Copyright (C) EdgeTX
|
||||
*
|
||||
* Based on code named
|
||||
* opentx - https://github.com/opentx/opentx
|
||||
@@ -30,4 +29,4 @@ constexpr uint32_t colorTabl2[] = {0x000000, 0xF8F8F8, 0xF80000, 0x00F800, 0xF8F
|
||||
|
||||
void setFSLedOFF(uint8_t index);
|
||||
void setFSLedON(uint8_t index);
|
||||
bool getFSLedState(uint8_t index);
|
||||
bool getFSLedState(uint8_t index);
|
||||
@@ -31,10 +31,10 @@
|
||||
// Board API
|
||||
void boardInitSwitches();
|
||||
|
||||
SwitchHwPos boardSwitchGetPosition(uint8_t cat, uint8_t idx);
|
||||
SwitchHwPos boardSwitchGetPosition(SwitchCategory cat, uint8_t idx);
|
||||
|
||||
const char* boardSwitchGetName(uint8_t cat, uint8_t idx);
|
||||
SwitchHwType boardSwitchGetType(uint8_t cat, uint8_t idx);
|
||||
const char* boardSwitchGetName(SwitchCategory cat, uint8_t idx);
|
||||
SwitchHwType boardSwitchGetType(SwitchCategory cat, uint8_t idx);
|
||||
|
||||
uint8_t boardGetMaxSwitches();
|
||||
uint8_t boardGetMaxFctSwitches();
|
||||
|
||||
@@ -33,10 +33,11 @@ enum usbMode {
|
||||
USB_JOYSTICK_MODE,
|
||||
USB_MASS_STORAGE_MODE,
|
||||
USB_SERIAL_MODE,
|
||||
USB_DFU_MODE,
|
||||
#if defined(USB_SERIAL)
|
||||
USB_MAX_MODE=USB_SERIAL_MODE
|
||||
USB_MAX_MODE=USB_SERIAL_MODE,
|
||||
#else
|
||||
USB_MAX_MODE=USB_MASS_STORAGE_MODE
|
||||
USB_MAX_MODE=USB_MASS_STORAGE_MODE,
|
||||
#endif
|
||||
};
|
||||
|
||||
@@ -53,11 +54,15 @@ bool usbStarted();
|
||||
EXTERN_C(int getSelectedUsbMode());
|
||||
void setSelectedUsbMode(int mode);
|
||||
|
||||
// USB CDC
|
||||
uint32_t usbSerialFreeSpace();
|
||||
extern const etx_serial_port_t UsbSerialPort;
|
||||
|
||||
// USB HID
|
||||
#if defined(USBJ_EX)
|
||||
void usbJoystickRestart();
|
||||
#endif
|
||||
void usbJoystickUpdate();
|
||||
|
||||
extern const etx_serial_port_t UsbSerialPort;
|
||||
// USB DFU
|
||||
int usbRegisterDFUMedia(const void* dfu_media);
|
||||
|
||||
@@ -34,6 +34,10 @@
|
||||
#include "lib_file.h"
|
||||
#endif
|
||||
|
||||
#ifndef BOOTLOADER_ADDRESS
|
||||
#define BOOTLOADER_ADDRESS FIRMWARE_ADDRESS
|
||||
#endif
|
||||
|
||||
bool isBootloader(const char * filename)
|
||||
{
|
||||
FIL file;
|
||||
@@ -66,12 +70,6 @@ void BootloaderFirmwareUpdate::flashFirmware(const char * filename, ProgressHand
|
||||
|
||||
f_open(&file, filename, FA_READ);
|
||||
|
||||
static uint8_t unlocked = 0;
|
||||
if (!unlocked) {
|
||||
unlocked = 1;
|
||||
unlockFlash();
|
||||
}
|
||||
|
||||
UINT flash_size = file.obj.objsize;
|
||||
if (flash_size > BOOTLOADER_SIZE) {
|
||||
flash_size = BOOTLOADER_SIZE;
|
||||
@@ -97,7 +95,7 @@ void BootloaderFirmwareUpdate::flashFirmware(const char * filename, ProgressHand
|
||||
}
|
||||
for (UINT j = 0; j < count; j += FLASH_PAGESIZE) {
|
||||
WDG_ENABLE(3000);
|
||||
flashWrite(CONVERT_UINT_PTR(FIRMWARE_ADDRESS + i + j), CONVERT_UINT_PTR(buffer + j));
|
||||
flashWrite(CONVERT_UINT_PTR(BOOTLOADER_ADDRESS + i + j), CONVERT_UINT_PTR(buffer + j));
|
||||
WDG_ENABLE(WDG_DURATION);
|
||||
}
|
||||
progressHandler("Bootloader", STR_WRITING, i, flash_size);
|
||||
@@ -117,12 +115,6 @@ void BootloaderFirmwareUpdate::flashFirmware(const char * filename, ProgressHand
|
||||
watchdogSuspend(0);
|
||||
WDG_RESET();
|
||||
|
||||
if (unlocked) {
|
||||
lockFlash();
|
||||
unlocked = 0;
|
||||
}
|
||||
|
||||
f_close(&file);
|
||||
|
||||
pulsesStart();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,211 @@
|
||||
/*
|
||||
* Copyright (C) EdgeTX
|
||||
*
|
||||
* Based on code named
|
||||
* opentx - https://github.com/opentx/opentx
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include "uf2.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <algorithm>
|
||||
|
||||
#include "board.h"
|
||||
#include "fw_version.h"
|
||||
|
||||
#include "thirdparty/FatFs/ff.h"
|
||||
#include "thirdparty/uf2/uf2.h"
|
||||
|
||||
#define UF2_BLOCK_SIZE 512
|
||||
|
||||
bool isUF2Block(const void* block, uint32_t len)
|
||||
{
|
||||
const UF2_Block* uf2 = (UF2_Block*)block;
|
||||
return len >= UF2_BLOCK_SIZE
|
||||
&& uf2->magicStart0 == UF2_MAGIC_START0
|
||||
&& uf2->magicStart1 == UF2_MAGIC_START1
|
||||
&& uf2->magicEnd == UF2_MAGIC_END;
|
||||
}
|
||||
|
||||
static size_t getUF2Extension(const UF2_Block* block, uint32_t extension,
|
||||
const char** data)
|
||||
{
|
||||
if ((block->flags & UF2_FLAG_EXTENSION_TAGS) == 0) return 0;
|
||||
|
||||
uint32_t* ptr = (uint32_t*)(block->data + block->payloadSize);
|
||||
if (*ptr == 0) return 0;
|
||||
|
||||
while ((size_t)((uint8_t*)ptr - (uint8_t*)block) < sizeof(UF2_Block)) {
|
||||
uint32_t tag = ((*ptr) & 0xFFFFFF00) >> 8;
|
||||
uint32_t len = (*ptr) & 0x000000FF;
|
||||
if (*ptr == 0) break;
|
||||
if (tag != extension) {
|
||||
ptr += (len + 3) / 4;
|
||||
continue;
|
||||
}
|
||||
*data = (char*)++ptr;
|
||||
return len > 4 ? len - 4 : 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool extractUF2FirmwareVersion(const void* block, VersionTag* tag)
|
||||
{
|
||||
|
||||
memset(tag, 0, sizeof(VersionTag));
|
||||
|
||||
const char* extension;
|
||||
size_t len = getUF2Extension((UF2_Block*)block, UF2_DEVICE_TAG, &extension);
|
||||
if (len == 0) return false;
|
||||
memcpy(tag->flavour, extension, std::min(len, sizeof(tag->flavour) - 1));
|
||||
|
||||
len = getUF2Extension((UF2_Block*)block, UF2_VERSION_TAG, &extension);
|
||||
if (len == 0) return false;
|
||||
memcpy(tag->full_version, extension, std::min(len, sizeof(tag->full_version) - 1));
|
||||
|
||||
tag->fork = tag->full_version;
|
||||
tag->full_version[sizeof("edgetx") - 1] = '\0';
|
||||
tag->version = tag->fork + sizeof("edgetx");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool isUF2FirmwareImage(const void* buffer, uint32_t length)
|
||||
{
|
||||
const uint8_t* bptr = (const uint8_t*)buffer;
|
||||
const uint8_t* end_ptr = bptr + length;
|
||||
|
||||
while(bptr < end_ptr) {
|
||||
if (!isUF2Block(bptr, end_ptr - bptr)) return false;
|
||||
bptr += UF2_BLOCK_SIZE;
|
||||
}
|
||||
|
||||
// check compat: should this really be part of checking
|
||||
// the file type?
|
||||
// VersionTag tag;
|
||||
// if(!extractFirmwareVersion(buffer, &tag))
|
||||
// return false;
|
||||
|
||||
// if(strnlen(tag.flavour, sizeof(tag.flavour)) != strlen(FLAVOUR))
|
||||
// return false;
|
||||
|
||||
// if(strncmp(tag.flavour, FLAVOUR, sizeof(FLAVOUR)) != 0)
|
||||
// return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool isUF2FirmwareFile(const char * filename)
|
||||
{
|
||||
FIL file;
|
||||
uint8_t buffer[2048];
|
||||
UINT count;
|
||||
|
||||
if(f_open(&file, filename, FA_READ) != FR_OK)
|
||||
return false;
|
||||
|
||||
if (f_read(&file, buffer, sizeof(buffer), &count) != FR_OK || count != sizeof(buffer)) {
|
||||
f_close(&file);
|
||||
return false;
|
||||
}
|
||||
|
||||
f_close(&file);
|
||||
|
||||
bool ret = isUF2FirmwareImage(buffer, sizeof(buffer));
|
||||
return ret;
|
||||
}
|
||||
|
||||
static uint8_t* skipUF2Extensions(uint8_t* data) {
|
||||
|
||||
uint32_t* ptr = (uint32_t*)data;
|
||||
while(true) {
|
||||
uint32_t tag = ((*ptr) & 0xFFFFFF00) >> 8;
|
||||
uint32_t len = (*ptr) & 0x000000FF;
|
||||
if (*ptr == 0) break;
|
||||
if (tag) {
|
||||
ptr += (len + 3) / 4;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
return (uint8_t*)ptr;
|
||||
}
|
||||
|
||||
void writeUF2FirmwareVersion(void* block)
|
||||
{
|
||||
UF2_Block* uf2 = (UF2_Block*)block;
|
||||
uint8_t* end_data = skipUF2Extensions(uf2->data + uf2->payloadSize);
|
||||
|
||||
const char* version = getFirmwareVersion((const uint8_t*)FIRMWARE_ADDRESS);
|
||||
if (version) {
|
||||
uf2->flags |= UF2_FLAG_EXTENSION_TAGS;
|
||||
|
||||
size_t version_len = strlen(version);
|
||||
const char* flavour_start = version + sizeof("edgetx-") - 1;
|
||||
const char* flavour_end = strchr(flavour_start, '-');
|
||||
|
||||
uint32_t ext_tag = UF2_DEVICE_TAG << 8;
|
||||
if (flavour_end < version + version_len) {
|
||||
size_t flavour_len = flavour_end - flavour_start;
|
||||
ext_tag |= (flavour_len + 4) & 0xFF;
|
||||
memcpy(end_data, &ext_tag, sizeof(ext_tag));
|
||||
end_data += 4;
|
||||
memcpy(end_data, flavour_start, flavour_len);
|
||||
end_data += ((flavour_len) + 3) & (~3);
|
||||
version_len -= flavour_len + 1;
|
||||
} else {
|
||||
flavour_end = nullptr;
|
||||
}
|
||||
|
||||
ext_tag = UF2_VERSION_TAG << 8;
|
||||
ext_tag |= (version_len + 4) & 0xFF;
|
||||
|
||||
memcpy(end_data, &ext_tag, sizeof(ext_tag));
|
||||
end_data +=4;
|
||||
|
||||
if (flavour_end) {
|
||||
memcpy(end_data, version, sizeof("edgetx-") - 1);
|
||||
end_data += sizeof("edgetx-") - 1;
|
||||
version_len -= sizeof("edgetx-") - 1;
|
||||
memcpy(end_data, flavour_end + 1, version_len);
|
||||
} else {
|
||||
memcpy(end_data, version, version_len);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void writeUF2RebootBlock(void* block)
|
||||
{
|
||||
extern uint32_t _reboot_cmd;
|
||||
|
||||
UF2_Block* uf2 = (UF2_Block*)block;
|
||||
|
||||
uf2->targetAddr = (uintptr_t)&_reboot_cmd;
|
||||
uf2->flags |= UF2_FLAG_EXTENSION_TAGS | UF2_FLAG_NOFLASH;
|
||||
uf2->payloadSize = 4;
|
||||
memcpy(uf2->data, "BDFU", 4);
|
||||
|
||||
uint8_t* end_data = skipUF2Extensions(uf2->data + uf2->payloadSize);
|
||||
uint32_t ext_tag = (UF2_REBOOT_TAG << 8) | 8;
|
||||
memcpy(end_data, &ext_tag, sizeof(ext_tag));
|
||||
end_data += 4;
|
||||
|
||||
uint32_t reboot_addr = BOOTLOADER_ADDRESS;
|
||||
memcpy(end_data, &reboot_addr, sizeof(reboot_addr));
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright (C) EdgeTX
|
||||
*
|
||||
* Based on code named
|
||||
* opentx - https://github.com/opentx/opentx
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include "boards/FirmwareVersionTag.h"
|
||||
|
||||
#define UF2_VERSION_TAG 0x9FC7BC
|
||||
#define UF2_DEVICE_TAG 0x650D9D
|
||||
#define UF2_REBOOT_TAG 0xE60835
|
||||
|
||||
// ignore family ID if not defined
|
||||
#if !defined(UF2_FAMILY_ID)
|
||||
#define UF2_FAMILY_ID 0
|
||||
#endif
|
||||
|
||||
bool isUF2Block(const void* block, uint32_t len);
|
||||
bool isUF2FirmwareImage(const void* buffer, uint32_t length);
|
||||
bool isUF2FirmwareFile(const char * filename);
|
||||
|
||||
bool extractUF2FirmwareVersion(const void* block, VersionTag* tag);
|
||||
|
||||
void writeUF2FirmwareVersion(void* block);
|
||||
void writeUF2RebootBlock(void* block);
|
||||
|
||||
@@ -0,0 +1,120 @@
|
||||
/*
|
||||
* Copyright (C) EdgeTX
|
||||
*
|
||||
* Based on code named
|
||||
* opentx - https://github.com/opentx/opentx
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include "uf2_flash.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <algorithm>
|
||||
|
||||
#include "thirdparty/FatFs/ff.h"
|
||||
#include "thirdparty/uf2/uf2.h"
|
||||
|
||||
#include "hal/watchdog_driver.h"
|
||||
#include "hal/flash_driver.h"
|
||||
|
||||
#include "pulses/pulses.h"
|
||||
|
||||
#define UF2_BLOCK_SIZE 512
|
||||
|
||||
void UF2FirmwareUpdate::flashFirmware(const char* filename,
|
||||
ProgressHandler progressHandler)
|
||||
{
|
||||
#if !defined(SIMU)
|
||||
FIL file;
|
||||
UF2_Block block;
|
||||
bool success = false;
|
||||
|
||||
pulsesStop();
|
||||
if (f_open(&file, filename, FA_READ) != FR_OK) {
|
||||
progressHandler("Firmware", STR_FIRMWARE_UPDATE_ERROR, 1, 1);
|
||||
pulsesStart();
|
||||
return;
|
||||
}
|
||||
|
||||
size_t total_len = f_size(&file);
|
||||
size_t erased_len = 0;
|
||||
uint32_t last_erased = 0;
|
||||
|
||||
UINT bytes_read;
|
||||
while (f_read(&file, &block, sizeof(block), &bytes_read) == FR_OK &&
|
||||
bytes_read > 0) {
|
||||
|
||||
uint32_t addr = block.targetAddr;
|
||||
if ((block.flags & UF2_FLAG_NOFLASH) == 0 && addr > last_erased) {
|
||||
auto drv = flashFindDriver(addr);
|
||||
if (drv) {
|
||||
uint32_t sector = drv->get_sector(addr);
|
||||
uint32_t sect_len = drv->get_sector_size(sector);
|
||||
if (drv->erase_sector(addr) < 0) break;
|
||||
last_erased = block.targetAddr + sect_len - 1;
|
||||
}
|
||||
}
|
||||
|
||||
erased_len += bytes_read;
|
||||
progressHandler("Firmware", "Erasing...", erased_len, total_len);
|
||||
|
||||
if (erased_len >= total_len) {
|
||||
success = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (success) {
|
||||
success = false;
|
||||
size_t written_len = 0;
|
||||
f_rewind(&file);
|
||||
|
||||
while (f_read(&file, &block, sizeof(block), &bytes_read) == FR_OK &&
|
||||
bytes_read > 0) {
|
||||
|
||||
if ((block.flags & UF2_FLAG_NOFLASH) == 0) {
|
||||
uint32_t addr = block.targetAddr;
|
||||
auto drv = flashFindDriver(addr);
|
||||
if (drv) {
|
||||
uint32_t len = block.payloadSize;
|
||||
uint8_t* data = (uint8_t*)block.data;
|
||||
drv->program(addr, data, len);
|
||||
}
|
||||
}
|
||||
|
||||
written_len += bytes_read;
|
||||
progressHandler("Firmware", "Writing...", written_len, total_len);
|
||||
|
||||
if (written_len >= total_len) {
|
||||
success = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(success)
|
||||
POPUP_INFORMATION(STR_FIRMWARE_UPDATE_SUCCESS);
|
||||
else
|
||||
POPUP_INFORMATION(STR_FIRMWARE_UPDATE_ERROR);
|
||||
|
||||
watchdogSuspend(0);
|
||||
WDG_RESET();
|
||||
|
||||
f_close(&file);
|
||||
pulsesStart();
|
||||
#endif
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright (C) EdgeTX
|
||||
*
|
||||
* Based on code named
|
||||
* opentx - https://github.com/opentx/opentx
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "io/uf2.h"
|
||||
#include "edgetx.h"
|
||||
|
||||
class UF2FirmwareUpdate
|
||||
{
|
||||
public:
|
||||
void flashFirmware(const char* filename, ProgressHandler progressHandler);
|
||||
};
|
||||
@@ -548,9 +548,4 @@ bool rotaryEncoderPollingCycle()
|
||||
return false;
|
||||
}
|
||||
|
||||
#elif !defined(COLORLCD)
|
||||
|
||||
int8_t rotaryEncoderGetAccel() { return ROTENC_LOWSPEED; }
|
||||
void rotaryEncoderResetAccel() {}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -122,6 +122,13 @@ void applyDefaultTemplate()
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(FUNCTION_SWITCHES_RGB_LEDS)
|
||||
for (uint8_t i = 0; i < NUM_FUNCTIONS_SWITCHES; i++) {
|
||||
g_model.functionSwitchLedOFFColor[i].setColor(0);
|
||||
g_model.functionSwitchLedONColor[i].setColor(0xFFFFFF);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(COLORLCD)
|
||||
|
||||
LayoutFactory::loadDefaultLayout();
|
||||
|
||||
@@ -346,10 +346,10 @@ static void _crsf_extmodule_frame_received()
|
||||
// FreeRTOS methods from ISR with prio 0
|
||||
static void _soft_irq_trigger(void*)
|
||||
{
|
||||
#ifndef STM32H7
|
||||
EXTI->SWIER = TELEMETRY_RX_FRAME_EXTI_LINE;
|
||||
#if defined(TELEMETRY_USE_CUSTOM_EXTI)
|
||||
stm32_exti_custom_trigger_swi(TELEMETRY_RX_FRAME_EXTI_LINE);
|
||||
#else
|
||||
EXTI->SWIER1 = TELEMETRY_RX_FRAME_EXTI_LINE;
|
||||
stm32_exti_trigger_swi(TELEMETRY_RX_FRAME_EXTI_LINE);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
@@ -397,8 +397,14 @@ static void* crossfireInit(uint8_t module)
|
||||
#if !defined(SIMU)
|
||||
if (drv && ctx && drv->setIdleCb) {
|
||||
drv->setIdleCb(ctx, _soft_irq_trigger, nullptr);
|
||||
#if defined(TELEMETRY_USE_CUSTOM_EXTI)
|
||||
stm32_exti_custom_enable(TELEMETRY_RX_FRAME_EXTI_LINE, 3,
|
||||
_crsf_extmodule_frame_received);
|
||||
#else
|
||||
stm32_exti_enable(TELEMETRY_RX_FRAME_EXTI_LINE, 0,
|
||||
_crsf_extmodule_frame_received);
|
||||
#endif
|
||||
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -426,7 +432,11 @@ static void crossfireDeInit(void* ctx)
|
||||
auto drv = modulePortGetSerialDrv(mod_st->rx);
|
||||
auto ctx = modulePortGetCtx(mod_st->rx);
|
||||
if (drv && ctx && drv->setIdleCb) {
|
||||
stm32_exti_disable(TELEMETRY_RX_FRAME_EXTI_LINE);
|
||||
#if defined(TELEMETRY_USE_CUSTOM_EXTI)
|
||||
stm32_exti_custom_disable(TELEMETRY_RX_FRAME_EXTI_LINE);
|
||||
#else
|
||||
stm32_exti_disable(TELEMETRY_RX_FRAME_EXTI_LINE);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -65,7 +65,7 @@
|
||||
#endif
|
||||
|
||||
static module_pulse_driver _module_drivers[MAX_MODULES];
|
||||
static module_pulse_buffer _module_buffers[MAX_MODULES] __DMA;
|
||||
static module_pulse_buffer _module_buffers[MAX_MODULES] __DMA_NO_CACHE;
|
||||
|
||||
void pulsesInit()
|
||||
{
|
||||
@@ -83,7 +83,7 @@ uint8_t* pulsesGetModuleBuffer(uint8_t module)
|
||||
}
|
||||
|
||||
ModuleState moduleState[NUM_MODULES];
|
||||
TrainerPulsesData trainerPulsesData __DMA;
|
||||
TrainerPulsesData trainerPulsesData __DMA_NO_CACHE;
|
||||
|
||||
void pulsesStart()
|
||||
{
|
||||
|
||||
@@ -85,7 +85,11 @@ const char YAMLFILE_CHECKSUM_TAG_NAME[] = "checksum";
|
||||
#define SCRIPT_EXT ".lua"
|
||||
#define SCRIPT_BIN_EXT ".luac"
|
||||
#define TEXT_EXT ".txt"
|
||||
#if defined(FIRMWARE_FORMAT_UF2)
|
||||
#define FIRMWARE_EXT ".uf2"
|
||||
#else
|
||||
#define FIRMWARE_EXT ".bin"
|
||||
#endif
|
||||
#define SPORT_FIRMWARE_EXT ".frk"
|
||||
#define FRSKY_FIRMWARE_EXT ".frsk"
|
||||
#define MULTI_FIRMWARE_EXT ".bin"
|
||||
|
||||
+7
-13
@@ -96,28 +96,22 @@ __SECTION_USED(".bootversiondata") const char boot_version[] = "edgetx-" FLA
|
||||
* Tries to find EdgeTX or OpenTX version in the first 1024 byte of either firmware/bootloader (the one not running) or the buffer
|
||||
* @param buffer If non-null find the firmware version in the buffer instead
|
||||
*/
|
||||
const char * getFirmwareVersion(const char * buffer)
|
||||
const char * getFirmwareVersion(const uint8_t* buffer)
|
||||
{
|
||||
if (buffer == nullptr) {
|
||||
#if defined(BOOT)
|
||||
buffer = (const char *)(FIRMWARE_ADDRESS + BOOTLOADER_SIZE);
|
||||
if(buffer == nullptr) {
|
||||
#if defined(BOOT) && !defined(FIRMWARE_QSPI)
|
||||
buffer = (const uint8_t *)(FIRMWARE_ADDRESS + BOOTLOADER_SIZE);
|
||||
#else
|
||||
buffer = (const char *)FIRMWARE_ADDRESS;
|
||||
buffer = (const uint8_t *)FIRMWARE_ADDRESS;
|
||||
#endif
|
||||
}
|
||||
|
||||
for (int i = 0; i < 1024; i++) {
|
||||
for (int i = 0; i < 2024; i++) {
|
||||
if ((memcmp(buffer + i, "edgetx-", 7) == 0)
|
||||
|| memcmp(buffer + i, "opentx-", 7) == 0) {
|
||||
return buffer + i;
|
||||
return (const char*)buffer + i;
|
||||
}
|
||||
}
|
||||
|
||||
return "no version found";
|
||||
}
|
||||
#else
|
||||
const char * getFirmwareVersion(const char * buffer)
|
||||
{
|
||||
return "edgetx-" FLAVOUR "-" VERSION DISPLAY_VERSION " (" GIT_STR ")";
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -14,7 +14,7 @@ endif()
|
||||
# Warning: this file must be kept in sync with 'yaml_datastructs.cpp'
|
||||
# in the same directory.
|
||||
|
||||
if((PCB STREQUAL X10) OR (PCB STREQUAL X12S))
|
||||
if((PCB STREQUAL X10) OR (PCB STREQUAL X12S) OR (PCB STREQUAL STM32H7S78_DK))
|
||||
if(PCBREV STREQUAL T15)
|
||||
set(YAML_GEN_OUTPUT storage/yaml/yaml_datastructs_t15.cpp)
|
||||
elseif(PCBREV STREQUAL F16)
|
||||
|
||||
@@ -2258,14 +2258,12 @@ static void r_carryTrim(void* user, uint8_t* data, uint32_t bitoffs,
|
||||
yaml_put_bits(data, i, bitoffs, 6);
|
||||
}
|
||||
|
||||
#if defined(ROTARY_ENCODER_NAVIGATION) && !defined(USE_HATS_AS_KEYS)
|
||||
static void r_rotEncDirection(void* user, uint8_t* data, uint32_t bitoffs,
|
||||
const char* val, uint8_t val_len)
|
||||
{
|
||||
uint32_t i = yaml_str2uint(val, val_len);
|
||||
yaml_put_bits(data, i, bitoffs, 2);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void r_telemetryBaudrate(void* user, uint8_t* data, uint32_t bitoffs,
|
||||
const char* val, uint8_t val_len)
|
||||
|
||||
@@ -363,7 +363,8 @@ static const struct YamlNode struct_RadioData[] = {
|
||||
YAML_UNSIGNED( "blOffBright", 7 ),
|
||||
YAML_STRING("bluetoothName", 10),
|
||||
YAML_STRING("ownerRegistrationID", 8),
|
||||
YAML_PADDING( 3 ),
|
||||
YAML_CUSTOM("rotEncDirection",r_rotEncDirection,nullptr),
|
||||
YAML_UNSIGNED( "rotEncMode", 3 ),
|
||||
YAML_SIGNED( "uartSampleMode", 2 ),
|
||||
YAML_UNSIGNED( "stickDeadZone", 3 ),
|
||||
YAML_STRING("selectedTheme", 26),
|
||||
|
||||
@@ -363,7 +363,8 @@ static const struct YamlNode struct_RadioData[] = {
|
||||
YAML_UNSIGNED( "blOffBright", 7 ),
|
||||
YAML_STRING("bluetoothName", 10),
|
||||
YAML_STRING("ownerRegistrationID", 8),
|
||||
YAML_PADDING( 3 ),
|
||||
YAML_CUSTOM("rotEncDirection",r_rotEncDirection,nullptr),
|
||||
YAML_UNSIGNED( "rotEncMode", 3 ),
|
||||
YAML_SIGNED( "uartSampleMode", 2 ),
|
||||
YAML_UNSIGNED( "stickDeadZone", 3 ),
|
||||
YAML_STRING("selectedTheme", 26),
|
||||
|
||||
@@ -344,7 +344,8 @@ static const struct YamlNode struct_RadioData[] = {
|
||||
YAML_UNSIGNED( "backlightColor", 8 ),
|
||||
YAML_STRING("bluetoothName", 10),
|
||||
YAML_STRING("ownerRegistrationID", 8),
|
||||
YAML_PADDING( 3 ),
|
||||
YAML_CUSTOM("rotEncDirection",r_rotEncDirection,nullptr),
|
||||
YAML_UNSIGNED( "rotEncMode", 3 ),
|
||||
YAML_SIGNED( "uartSampleMode", 2 ),
|
||||
YAML_PADDING( 3 ),
|
||||
YAML_UNSIGNED( "radioGFDisabled", 1 ),
|
||||
|
||||
@@ -344,7 +344,8 @@ static const struct YamlNode struct_RadioData[] = {
|
||||
YAML_UNSIGNED( "backlightColor", 8 ),
|
||||
YAML_STRING("bluetoothName", 10),
|
||||
YAML_STRING("ownerRegistrationID", 8),
|
||||
YAML_PADDING( 3 ),
|
||||
YAML_CUSTOM("rotEncDirection",r_rotEncDirection,nullptr),
|
||||
YAML_UNSIGNED( "rotEncMode", 3 ),
|
||||
YAML_SIGNED( "uartSampleMode", 2 ),
|
||||
YAML_PADDING( 3 ),
|
||||
YAML_UNSIGNED( "radioGFDisabled", 1 ),
|
||||
|
||||
@@ -346,7 +346,8 @@ static const struct YamlNode struct_RadioData[] = {
|
||||
YAML_UNSIGNED( "backlightColor", 8 ),
|
||||
YAML_STRING("bluetoothName", 10),
|
||||
YAML_STRING("ownerRegistrationID", 8),
|
||||
YAML_PADDING( 3 ),
|
||||
YAML_CUSTOM("rotEncDirection",r_rotEncDirection,nullptr),
|
||||
YAML_UNSIGNED( "rotEncMode", 3 ),
|
||||
YAML_SIGNED( "uartSampleMode", 2 ),
|
||||
YAML_PADDING( 3 ),
|
||||
YAML_SIGNED( "imuMax", 8 ),
|
||||
|
||||
@@ -170,6 +170,7 @@ void evalFunctionSwitches()
|
||||
for (uint8_t i = 0; i < fct_switches; i++) {
|
||||
if (FSWITCH_CONFIG(i) == SWITCH_NONE) {
|
||||
setFSLedOFF(i);
|
||||
//fsLedRGB(i, 0);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
@@ -25,6 +25,7 @@ if(NOT NATIVE_BUILD)
|
||||
${STM32USB_DIR}/Core/Src/usbd_ctlreq.c
|
||||
${STM32USB_DIR}/Core/Src/usbd_ioreq.c
|
||||
${STM32USB_DIR}/Class/CDC/Src/usbd_cdc.c
|
||||
${STM32USB_DIR}/Class/DFU/Src/usbd_dfu.c
|
||||
${STM32USB_DIR}/Class/MSC/Src/usbd_msc_data.c
|
||||
${STM32USB_DIR}/Class/MSC/Src/usbd_msc_scsi.c
|
||||
${STM32USB_DIR}/Class/MSC/Src/usbd_msc_bot.c
|
||||
@@ -34,9 +35,14 @@ if(NOT NATIVE_BUILD)
|
||||
target_include_directories(stm32usb PRIVATE
|
||||
${STM32USB_DIR}/Core/Inc
|
||||
${STM32USB_DIR}/Class/CDC/Inc
|
||||
${STM32USB_DIR}/Class/DFU/Inc
|
||||
${STM32USB_DIR}/Class/HID/Inc
|
||||
${STM32USB_DIR}/Class/MSC/Inc)
|
||||
|
||||
target_include_directories(board_bl PRIVATE
|
||||
${STM32USB_DIR}/Core/Inc
|
||||
${STM32USB_DIR}/Class/DFU/Inc)
|
||||
|
||||
set(FIRMWARE_SRC ${FIRMWARE_SRC} $<TARGET_OBJECTS:stm32usb>)
|
||||
set(BOOTLOADER_SRC ${BOOTLOADER_SRC} $<TARGET_OBJECTS:stm32usb>)
|
||||
|
||||
@@ -44,14 +50,15 @@ if(NOT NATIVE_BUILD)
|
||||
add_library(stm32usb_device_bl OBJECT EXCLUDE_FROM_ALL
|
||||
${STM32_DRIVER_DIR}/usbd_conf.c
|
||||
${STM32_DRIVER_DIR}/usbd_desc.c
|
||||
${STM32_DRIVER_DIR}/usb_driver.cpp
|
||||
${STM32_DRIVER_DIR}/usbd_storage_msd.cpp
|
||||
${STM32_DRIVER_DIR}/usb_driver.cpp
|
||||
)
|
||||
|
||||
target_compile_options(stm32usb_device_bl PRIVATE -DBOOT)
|
||||
target_include_directories(stm32usb_device_bl PRIVATE
|
||||
${STM32USB_DIR}/Core/Inc
|
||||
${STM32USB_DIR}/Class/CDC/Inc
|
||||
${STM32USB_DIR}/Class/DFU/Inc
|
||||
${STM32USB_DIR}/Class/HID/Inc
|
||||
${STM32USB_DIR}/Class/MSC/Inc)
|
||||
|
||||
@@ -74,6 +81,7 @@ if(NOT NATIVE_BUILD)
|
||||
target_include_directories(stm32usb_device_fw PRIVATE
|
||||
${STM32USB_DIR}/Core/Inc
|
||||
${STM32USB_DIR}/Class/CDC/Inc
|
||||
${STM32USB_DIR}/Class/DFU/Inc
|
||||
${STM32USB_DIR}/Class/HID/Inc
|
||||
${STM32USB_DIR}/Class/MSC/Inc)
|
||||
|
||||
@@ -146,3 +154,11 @@ set(FIRMWARE_SRC ${FIRMWARE_SRC} syscalls.c)
|
||||
|
||||
set(TARGET_SRC ${TARGET_SRC} ../common/arm/stm32/cpu_id.cpp)
|
||||
set(SRC ${SRC} io/bootloader_flash.cpp)
|
||||
|
||||
if(FIRMWARE_FORMAT_UF2)
|
||||
add_definitions(-DFIRMWARE_FORMAT_UF2)
|
||||
set(SRC ${SRC}
|
||||
io/uf2.cpp
|
||||
io/uf2_flash.cpp
|
||||
)
|
||||
endif()
|
||||
|
||||
@@ -83,3 +83,13 @@ uint32_t abnormalRebootGetCause()
|
||||
_init_reboot_cause();
|
||||
return _reboot_cause;
|
||||
}
|
||||
|
||||
uint32_t abnormalRebootGetCmd()
|
||||
{
|
||||
return _reboot_cmd;
|
||||
}
|
||||
|
||||
void abnormalRebootResetCmd()
|
||||
{
|
||||
_reboot_cmd = 0;
|
||||
}
|
||||
|
||||
@@ -24,9 +24,11 @@
|
||||
#include <inttypes.h>
|
||||
#include "cpu_id.h"
|
||||
|
||||
#if !defined(SIMU) && !defined(BACKUP)
|
||||
#if !defined(SIMU) && !defined(BACKUP) && !defined(YAML_GENERATOR)
|
||||
#if defined(STM32H7)
|
||||
#include "stm32h7xx.h"
|
||||
#elif defined(STM32H7RS)
|
||||
#include "stm32h7rsxx.h"
|
||||
#elif defined(STM32F4)
|
||||
#include "stm32f4xx.h"
|
||||
#elif defined(STM32F2)
|
||||
|
||||
@@ -12,9 +12,22 @@ set(BOOTLOADER_SRC ${BOOTLOADER_SRC}
|
||||
${RADIO_SRC_DIR}/syscalls.c
|
||||
${RADIO_SRC_DIR}/crc.cpp
|
||||
boot.cpp
|
||||
bin_files.cpp
|
||||
)
|
||||
|
||||
if(FIRMWARE_FORMAT_UF2)
|
||||
set(BOOTLOADER_SRC ${BOOTLOADER_SRC}
|
||||
boot_uf2.cpp
|
||||
boot_dfu.cpp
|
||||
${RADIO_SRC_DIR}/io/uf2.cpp
|
||||
${RADIO_SRC_DIR}/drivers/uf2_ghostfat.cpp
|
||||
)
|
||||
else()
|
||||
set(BOOTLOADER_SRC ${BOOTLOADER_SRC}
|
||||
boot_menu.cpp
|
||||
bin_fw_files.cpp
|
||||
)
|
||||
endif()
|
||||
|
||||
if(DEBUG_SEGGER_RTT)
|
||||
set(BOOTLOADER_SRC ${BOOTLOADER_SRC}
|
||||
${RADIO_SRC_DIR}/thirdparty/Segger_RTT/RTT/SEGGER_RTT.c
|
||||
|
||||
+121
-30
@@ -25,19 +25,52 @@
|
||||
#include "boot.h"
|
||||
#include "board.h"
|
||||
#include "sdcard.h"
|
||||
#include "bin_files.h"
|
||||
#include "firmware_files.h"
|
||||
#include "fw_version.h"
|
||||
#include "strhelpers.h"
|
||||
#include "hal/storage.h"
|
||||
#include "flash_driver.h"
|
||||
|
||||
// Size of the block read when checking / writing BIN files
|
||||
#define BLOCK_LEN 4096
|
||||
|
||||
// 'private'
|
||||
static DIR dir;
|
||||
static FIL FlashFile;
|
||||
|
||||
static uint32_t firmwareSize;
|
||||
static uint32_t firmwareAddress = FIRMWARE_ADDRESS;
|
||||
static uint32_t firmwareWritten = 0;
|
||||
uint32_t unlocked = 0;
|
||||
|
||||
struct FWFileInfo {
|
||||
TCHAR name[FF_MAX_LFN + 1];
|
||||
unsigned int size;
|
||||
};
|
||||
|
||||
// 'public' variables
|
||||
BinFileInfo binFiles[MAX_BIN_FILES];
|
||||
uint8_t Block_buffer[BLOCK_LEN];
|
||||
UINT BlockCount;
|
||||
static FWFileInfo fwFiles[MAX_FW_FILES];
|
||||
static uint8_t Block_buffer[BLOCK_LEN];
|
||||
static UINT BlockCount;
|
||||
|
||||
static void flashWriteBlock()
|
||||
{
|
||||
// TODO: use some board provided driver instead
|
||||
uint32_t blockOffset = 0;
|
||||
#if !defined(SIMU)
|
||||
while (BlockCount) {
|
||||
flashWrite((uint32_t *)firmwareAddress, (uint32_t *)&Block_buffer[blockOffset]);
|
||||
blockOffset += FLASH_PAGESIZE;
|
||||
firmwareAddress += FLASH_PAGESIZE;
|
||||
if (BlockCount > FLASH_PAGESIZE) {
|
||||
BlockCount -= FLASH_PAGESIZE;
|
||||
}
|
||||
else {
|
||||
BlockCount = 0;
|
||||
}
|
||||
}
|
||||
#endif // SIMU
|
||||
}
|
||||
|
||||
void sdInit(void)
|
||||
{
|
||||
@@ -56,14 +89,41 @@ void sdDone()
|
||||
storageDeInit();
|
||||
}
|
||||
|
||||
FRESULT openBinDir(MemoryType mt)
|
||||
FRESULT openFirmwareDir()
|
||||
{
|
||||
FRESULT fr = f_chdir(getBinaryPath(mt));
|
||||
FRESULT fr = f_chdir(getFirmwarePath());
|
||||
if (fr != FR_OK) return fr;
|
||||
|
||||
|
||||
return f_opendir(&dir, ".");
|
||||
}
|
||||
|
||||
static uint32_t isValidBufferStart(const uint8_t * buffer)
|
||||
{
|
||||
#if !defined(SIMU)
|
||||
return isFirmwareStart(buffer);
|
||||
#else
|
||||
return 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
FlashCheckRes checkFirmwareFile(unsigned int index, FlashCheckRes res)
|
||||
{
|
||||
if (res != FC_UNCHECKED)
|
||||
return res;
|
||||
|
||||
if (openFirmwareFile(index) != FR_OK)
|
||||
return FC_ERROR;
|
||||
|
||||
if (closeFirmwareFile() != FR_OK)
|
||||
return FC_ERROR;
|
||||
|
||||
if (!isValidBufferStart(Block_buffer))
|
||||
return FC_ERROR;
|
||||
|
||||
return FC_OK;
|
||||
}
|
||||
|
||||
|
||||
static FRESULT findNextBinFile(FILINFO* fno)
|
||||
{
|
||||
FRESULT fr;
|
||||
@@ -102,7 +162,7 @@ static FRESULT findNextBinFile(FILINFO* fno)
|
||||
return fr;
|
||||
}
|
||||
|
||||
unsigned int fetchBinFiles(unsigned int index)
|
||||
unsigned int fetchFirmwareFiles(unsigned int index)
|
||||
{
|
||||
FILINFO file_info;
|
||||
|
||||
@@ -117,8 +177,8 @@ unsigned int fetchBinFiles(unsigned int index)
|
||||
return 0;
|
||||
}
|
||||
|
||||
strAppend(binFiles[0].name, file_info.fname);
|
||||
binFiles[0].size = file_info.fsize;
|
||||
strAppend(fwFiles[0].name, file_info.fname);
|
||||
fwFiles[0].size = file_info.fsize;
|
||||
|
||||
unsigned int i = 1;
|
||||
for (; i < MAX_NAMES_ON_SCREEN+1; i++) {
|
||||
@@ -126,49 +186,57 @@ unsigned int fetchBinFiles(unsigned int index)
|
||||
if (findNextBinFile(&file_info) != FR_OK || file_info.fname[0] == 0)
|
||||
return i;
|
||||
|
||||
strAppend(binFiles[i].name, file_info.fname);
|
||||
binFiles[i].size = file_info.fsize;
|
||||
strAppend(fwFiles[i].name, file_info.fname);
|
||||
fwFiles[i].size = file_info.fsize;
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
FRESULT openBinFile(MemoryType mt, unsigned int index)
|
||||
const char* getFirmwareFileNameByIndex(unsigned int index)
|
||||
{
|
||||
if(index >= MAX_FW_FILES)
|
||||
return "";
|
||||
|
||||
return fwFiles[index].name;
|
||||
}
|
||||
|
||||
FRESULT openFirmwareFile(unsigned int index)
|
||||
{
|
||||
TCHAR full_path[FF_MAX_LFN+1];
|
||||
FRESULT fr;
|
||||
FRESULT res;
|
||||
|
||||
// build full_path: [bin path]/[filename]
|
||||
char* s = strAppend(full_path, getBinaryPath(mt));
|
||||
char* s = strAppend(full_path, getFirmwarePath());
|
||||
s = strAppend(s, "/");
|
||||
strAppend(s, binFiles[index].name);
|
||||
strAppend(s, fwFiles[index].name);
|
||||
|
||||
BlockCount = 0;
|
||||
|
||||
|
||||
// open the file
|
||||
if ((fr = f_open(&FlashFile, full_path, FA_READ)) != FR_OK)
|
||||
return fr;
|
||||
res = f_open(&FlashFile, full_path, FA_READ);
|
||||
if (res != FR_OK) return res;
|
||||
|
||||
// skip bootloader in firmware
|
||||
if (mt == MEM_FLASH &&
|
||||
((fr = f_lseek(&FlashFile, BOOTLOADER_SIZE)) != FR_OK))
|
||||
return fr;
|
||||
res = f_lseek(&FlashFile, BOOTLOADER_SIZE);
|
||||
if (res != FR_OK) return res;
|
||||
|
||||
// ... and fetch BLOCK_LEN bytes
|
||||
fr = f_read(&FlashFile, Block_buffer, BLOCK_LEN, &BlockCount);
|
||||
|
||||
if (BlockCount == BLOCK_LEN)
|
||||
return fr;
|
||||
res = f_read(&FlashFile, Block_buffer, BLOCK_LEN, &BlockCount);
|
||||
if (BlockCount == BLOCK_LEN && isValidBufferStart(Block_buffer)) return res;
|
||||
|
||||
f_close(&FlashFile);
|
||||
return FR_INVALID_OBJECT;
|
||||
}
|
||||
|
||||
void extractFirmwareVersion(VersionTag* tag)
|
||||
void getFileFirmwareVersion(VersionTag* tag)
|
||||
{
|
||||
const char * vers = getFirmwareVersion((const char *)Block_buffer);
|
||||
memset(tag->flavour, 0, sizeof(tag->flavour));
|
||||
const char * vers = getFirmwareVersion((const uint8_t *)Block_buffer);
|
||||
if (!vers || (vers[0] == 'n' && vers[1] == 'o')) { // "no version found"
|
||||
memcpy(tag->flavour, "unknown", sizeof("unknown"));
|
||||
tag->version = "unknown";
|
||||
tag->flavour[sizeof(tag->flavour)-1] = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -180,18 +248,41 @@ void extractFirmwareVersion(VersionTag* tag)
|
||||
char* fl = tag->flavour;
|
||||
while(*vers != '-')
|
||||
*(fl++) = *(vers++);
|
||||
tag->flavour[sizeof(tag->flavour)-1] = 0;
|
||||
|
||||
// skip '-'
|
||||
tag->version = ++vers;
|
||||
}
|
||||
|
||||
FRESULT readBinFile()
|
||||
FRESULT readFirmwareFile()
|
||||
{
|
||||
BlockCount = 0;
|
||||
return f_read(&FlashFile, Block_buffer, sizeof(Block_buffer), &BlockCount);
|
||||
}
|
||||
|
||||
FRESULT closeBinFile()
|
||||
FRESULT closeFirmwareFile()
|
||||
{
|
||||
return f_close(&FlashFile);
|
||||
}
|
||||
|
||||
void firmwareInitWrite(uint32_t index)
|
||||
{
|
||||
firmwareSize = fwFiles[index].size - BOOTLOADER_SIZE;
|
||||
firmwareAddress = FIRMWARE_ADDRESS + BOOTLOADER_SIZE;
|
||||
firmwareWritten = 0;
|
||||
}
|
||||
|
||||
bool firmwareWriteBlock(uint32_t* progress)
|
||||
{
|
||||
flashWriteBlock();
|
||||
firmwareWritten += sizeof(Block_buffer);
|
||||
*progress = (100 * firmwareWritten) / firmwareSize;
|
||||
|
||||
readFirmwareFile();
|
||||
if (BlockCount == 0 || firmwareWritten >= FLASHSIZE - BOOTLOADER_SIZE) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -19,45 +19,27 @@
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
// #if !defined(SIMU)
|
||||
// #include "stm32_hal_ll.h"
|
||||
// #include "stm32_hal.h"
|
||||
// #include "stm32_timer.h"
|
||||
// #endif
|
||||
#include "boot.h"
|
||||
|
||||
#include "hal/usb_driver.h"
|
||||
#include "hal/abnormal_reboot.h"
|
||||
#include "hal/rotary_encoder.h"
|
||||
|
||||
#include "board.h"
|
||||
#include "debug.h"
|
||||
|
||||
#include "timers_driver.h"
|
||||
|
||||
#if defined(BLUETOOTH)
|
||||
#include "bluetooth_driver.h"
|
||||
#include "stm32_serial_driver.h"
|
||||
#endif
|
||||
|
||||
#include "board.h"
|
||||
#include "boot.h"
|
||||
#include "bin_files.h"
|
||||
#include "lcd.h"
|
||||
#include "debug.h"
|
||||
|
||||
#include "timers_driver.h"
|
||||
#include "flash_driver.h"
|
||||
|
||||
#include "hal/abnormal_reboot.h"
|
||||
#include "hal/rotary_encoder.h"
|
||||
|
||||
#if defined(DEBUG_SEGGER_RTT)
|
||||
#include "thirdparty/Segger_RTT/RTT/SEGGER_RTT.h"
|
||||
#endif
|
||||
|
||||
#if defined(SPI_FLASH)
|
||||
#define MAIN_MENU_LEN 3
|
||||
#else
|
||||
#define MAIN_MENU_LEN 2
|
||||
#endif
|
||||
|
||||
#if defined(SPI_FLASH)
|
||||
#include "diskio_spi_flash.h"
|
||||
#define SEL_CLEAR_FLASH_STORAGE_MENU_LEN 2
|
||||
#endif
|
||||
#define REBOOT_CMD_DFU 0x55464442
|
||||
|
||||
#if !defined(SIMU)
|
||||
// Bootloader marker:
|
||||
@@ -72,104 +54,6 @@ const uint8_t bootloaderVersion[] __attribute__ ((section(".version"), used)) =
|
||||
#define __weak __attribute__((weak))
|
||||
#endif
|
||||
|
||||
volatile tmr10ms_t g_tmr10ms;
|
||||
volatile uint8_t tenms = 1;
|
||||
|
||||
uint32_t firmwareSize;
|
||||
uint32_t firmwareAddress = FIRMWARE_ADDRESS;
|
||||
uint32_t firmwareWritten = 0;
|
||||
|
||||
FlashCheckRes valid;
|
||||
MemoryType memoryType;
|
||||
uint32_t unlocked = 0;
|
||||
|
||||
void per5ms() {} // make linker happy
|
||||
|
||||
void per10ms()
|
||||
{
|
||||
tenms |= 1u; // 10 mS has passed
|
||||
g_tmr10ms++;
|
||||
|
||||
keysPollingCycle();
|
||||
|
||||
#if defined(ROTARY_ENCODER_NAVIGATION) && !defined(USE_HATS_AS_KEYS)
|
||||
static rotenc_t rePreviousValue;
|
||||
|
||||
rotenc_t reNewValue = rotaryEncoderGetValue();
|
||||
int8_t scrollRE = reNewValue - rePreviousValue;
|
||||
if (scrollRE) {
|
||||
rePreviousValue = reNewValue;
|
||||
pushEvent(scrollRE < 0 ? EVT_ROTARY_LEFT : EVT_ROTARY_RIGHT);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
uint32_t isValidBufferStart(const uint8_t * buffer)
|
||||
{
|
||||
#if !defined(SIMU)
|
||||
return isFirmwareStart(buffer);
|
||||
#else
|
||||
return 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
FlashCheckRes checkFlashFile(unsigned int index, FlashCheckRes res)
|
||||
{
|
||||
if (res != FC_UNCHECKED)
|
||||
return res;
|
||||
|
||||
if (openBinFile(memoryType, index) != FR_OK)
|
||||
return FC_ERROR;
|
||||
|
||||
if (closeBinFile() != FR_OK)
|
||||
return FC_ERROR;
|
||||
|
||||
if (!isValidBufferStart(Block_buffer))
|
||||
return FC_ERROR;
|
||||
|
||||
return FC_OK;
|
||||
}
|
||||
|
||||
int menuFlashFile(uint32_t index, event_t event)
|
||||
{
|
||||
valid = checkFlashFile(index, valid);
|
||||
|
||||
if (valid == FC_ERROR) {
|
||||
if (event == EVT_KEY_BREAK(KEY_EXIT) || event == EVT_KEY_BREAK(KEY_ENTER))
|
||||
return 0;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (event == EVT_KEY_LONG(KEY_ENTER)) {
|
||||
|
||||
return (openBinFile(memoryType, index) == FR_OK) && isValidBufferStart(Block_buffer);
|
||||
}
|
||||
else if (event == EVT_KEY_BREAK(KEY_EXIT))
|
||||
return 0;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
void flashWriteBlock()
|
||||
{
|
||||
// TODO: use some board provided driver instead
|
||||
uint32_t blockOffset = 0;
|
||||
#if !defined(SIMU)
|
||||
while (BlockCount) {
|
||||
flashWrite((uint32_t *)firmwareAddress, (uint32_t *)&Block_buffer[blockOffset]);
|
||||
blockOffset += FLASH_PAGESIZE;
|
||||
firmwareAddress += FLASH_PAGESIZE;
|
||||
if (BlockCount > FLASH_PAGESIZE) {
|
||||
BlockCount -= FLASH_PAGESIZE;
|
||||
}
|
||||
else {
|
||||
BlockCount = 0;
|
||||
}
|
||||
}
|
||||
#endif // SIMU
|
||||
}
|
||||
|
||||
#if !defined(SIMU)
|
||||
|
||||
typedef void (*fctptr_t)(void);
|
||||
@@ -184,13 +68,14 @@ static __attribute__((noreturn)) void jumpTo(uint32_t addr)
|
||||
}
|
||||
|
||||
// Optional board hook
|
||||
__weak void boardBLInit() {}
|
||||
__weak void boardBLEarlyInit() {}
|
||||
__weak bool boardBLStartCondition() { return false; }
|
||||
__weak void boardBLPreJump() {}
|
||||
__weak void boardBLInit() {}
|
||||
|
||||
void bootloaderInitApp()
|
||||
{
|
||||
boardBLInit();
|
||||
boardBLEarlyInit();
|
||||
|
||||
#if defined(DEBUG_SEGGER_RTT)
|
||||
SEGGER_RTT_ConfigUpBuffer(0, NULL, NULL, 0, SEGGER_RTT_MODE_NO_BLOCK_SKIP);
|
||||
@@ -198,18 +83,28 @@ void bootloaderInitApp()
|
||||
|
||||
pwrInit();
|
||||
keysInit();
|
||||
delaysInit();
|
||||
|
||||
// wait a bit for the inputs to stabilize...
|
||||
if (!WAS_RESET_BY_WATCHDOG_OR_SOFTWARE()) {
|
||||
for (uint32_t i = 0; i < 150000; i++) {
|
||||
__ASM volatile("nop");
|
||||
bool boot_dfu = abnormalRebootGetCmd() == REBOOT_CMD_DFU;
|
||||
if (!boot_dfu) {
|
||||
bool start_firmware = true;
|
||||
|
||||
// wait a bit for the inputs to stabilize...
|
||||
if (!WAS_RESET_BY_WATCHDOG_OR_SOFTWARE()) {
|
||||
delay_us(200);
|
||||
}
|
||||
}
|
||||
|
||||
if (!boardBLStartCondition()) {
|
||||
// Start main application
|
||||
boardBLPreJump();
|
||||
jumpTo(APP_START_ADDRESS);
|
||||
start_firmware = !boardBLStartCondition();
|
||||
if (start_firmware) {
|
||||
// Start main application
|
||||
boardBLPreJump();
|
||||
jumpTo(APP_START_ADDRESS);
|
||||
}
|
||||
} else {
|
||||
#if defined(FIRMWARE_QSPI)
|
||||
abnormalRebootResetCmd();
|
||||
setSelectedUsbMode(USB_DFU_MODE);
|
||||
#endif
|
||||
}
|
||||
|
||||
// TODO: move all this into board specifics
|
||||
@@ -219,8 +114,6 @@ void bootloaderInitApp()
|
||||
rotaryEncoderInit();
|
||||
#endif
|
||||
|
||||
delaysInit(); // needed for lcdInit()
|
||||
|
||||
#if defined(DEBUG)
|
||||
initSerialPorts();
|
||||
#endif
|
||||
@@ -238,9 +131,8 @@ void bootloaderInitApp()
|
||||
|
||||
timersInit();
|
||||
|
||||
// SD card detect pin
|
||||
sdInit();
|
||||
usbInit();
|
||||
boardBLInit();
|
||||
}
|
||||
|
||||
int main()
|
||||
@@ -249,286 +141,28 @@ void bootloaderInitApp() {}
|
||||
int bootloaderMain()
|
||||
#endif
|
||||
{
|
||||
BootloaderState state = ST_START;
|
||||
uint32_t vpos = 0;
|
||||
uint32_t radioMenuItem = 0;
|
||||
uint8_t index = 0;
|
||||
FRESULT fr;
|
||||
uint32_t nameCount = 0;
|
||||
|
||||
// init hardware (may jump to app)
|
||||
bootloaderInitApp();
|
||||
|
||||
// init screen
|
||||
bootloaderInitScreen();
|
||||
|
||||
#if defined(FIRMWARE_FORMAT_UF2)
|
||||
if (getSelectedUsbMode() == USB_DFU_MODE) {
|
||||
bootloaderDFU();
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(PWR_BUTTON_PRESS)
|
||||
// wait until power button is released
|
||||
while (pwrPressed()) {}
|
||||
#endif
|
||||
|
||||
for (;;) {
|
||||
|
||||
if (tenms) {
|
||||
tenms = 0;
|
||||
|
||||
if (state != ST_USB && state != ST_FLASHING
|
||||
&& state != ST_FLASH_DONE && state != ST_RADIO_MENU) {
|
||||
if (usbPlugged()) {
|
||||
state = ST_USB;
|
||||
if (!unlocked) {
|
||||
unlocked = 1;
|
||||
unlockFlash();
|
||||
}
|
||||
#if !defined(SIMU)
|
||||
usbStart();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
if (state == ST_USB) {
|
||||
if (usbPlugged() == 0) {
|
||||
vpos = 0;
|
||||
#if !defined(SIMU)
|
||||
usbStop();
|
||||
#endif
|
||||
if (unlocked) {
|
||||
lockFlash();
|
||||
unlocked = 0;
|
||||
}
|
||||
state = ST_START;
|
||||
}
|
||||
bootloaderDrawScreen(state, 0);
|
||||
}
|
||||
|
||||
lcdRefreshWait();
|
||||
event_t event = getEvent();
|
||||
|
||||
if (state == ST_START) {
|
||||
|
||||
bootloaderDrawScreen(state, vpos);
|
||||
|
||||
if (IS_NEXT_EVENT(event)) {
|
||||
if (vpos < bootloaderGetMenuItemCount(MAIN_MENU_LEN) - 1) { vpos++; }
|
||||
continue;
|
||||
}
|
||||
else if (IS_PREVIOUS_EVENT(event)) {
|
||||
if (vpos > 0) { vpos--; }
|
||||
continue;
|
||||
}
|
||||
else if (event == EVT_KEY_BREAK(KEY_ENTER)) {
|
||||
switch (vpos) {
|
||||
case 0:
|
||||
memoryType = MEM_FLASH;
|
||||
state = ST_DIR_CHECK;
|
||||
break;
|
||||
#if defined(SPI_FLASH)
|
||||
case 1:
|
||||
state = ST_CLEAR_FLASH_CHECK;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
if(vpos < bootloaderGetMenuItemCount(MAIN_MENU_LEN-1))
|
||||
{
|
||||
state = ST_RADIO_MENU;
|
||||
radioMenuItem = vpos - MAIN_MENU_LEN - 1;
|
||||
} else {
|
||||
state = ST_REBOOT;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// next loop
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else if (state == ST_DIR_CHECK) {
|
||||
fr = openBinDir(memoryType);
|
||||
|
||||
if (fr == FR_OK) {
|
||||
index = vpos = 0;
|
||||
state = ST_FILE_LIST;
|
||||
nameCount = fetchBinFiles(index);
|
||||
continue;
|
||||
}
|
||||
else {
|
||||
bootloaderDrawScreen(state, fr);
|
||||
|
||||
if (event == EVT_KEY_BREAK(KEY_EXIT) || event == EVT_KEY_BREAK(KEY_ENTER)) {
|
||||
vpos = 0;
|
||||
state = ST_START;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (state == ST_FILE_LIST) {
|
||||
uint32_t limit = MAX_NAMES_ON_SCREEN;
|
||||
if (nameCount < limit) {
|
||||
limit = nameCount;
|
||||
}
|
||||
|
||||
if (IS_NEXT_EVENT(event)) {
|
||||
if (vpos < limit - 1) {
|
||||
vpos += 1;
|
||||
}
|
||||
else {
|
||||
if (nameCount > limit) {
|
||||
index += 1;
|
||||
nameCount = fetchBinFiles(index);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (IS_PREVIOUS_EVENT(event)) {
|
||||
if (vpos > 0) {
|
||||
vpos -= 1;
|
||||
}
|
||||
else {
|
||||
if (index) {
|
||||
index -= 1;
|
||||
nameCount = fetchBinFiles(index);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bootloaderDrawScreen(state, 0);
|
||||
|
||||
for (uint32_t i = 0; i < limit; i++) {
|
||||
bootloaderDrawFilename(binFiles[i].name, i, (vpos == i));
|
||||
}
|
||||
|
||||
if (event == EVT_KEY_BREAK(KEY_ENTER)) {
|
||||
// Select file to flash
|
||||
state = ST_FLASH_CHECK;
|
||||
valid = FC_UNCHECKED;
|
||||
continue;
|
||||
}
|
||||
else if (event == EVT_KEY_BREAK(KEY_EXIT)) {
|
||||
state = ST_START;
|
||||
vpos = 0;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else if (state == ST_FLASH_CHECK) {
|
||||
bootloaderDrawScreen(state, valid, binFiles[vpos].name);
|
||||
|
||||
int result = menuFlashFile(vpos, event);
|
||||
if (result == 0) {
|
||||
// canceled
|
||||
state = ST_FILE_LIST;
|
||||
}
|
||||
else if (result == 1) {
|
||||
// confirmed
|
||||
|
||||
if (memoryType == MEM_FLASH) {
|
||||
firmwareSize = FIRMWARE_LEN(binFiles[vpos].size);
|
||||
firmwareAddress = APP_START_ADDRESS;
|
||||
firmwareWritten = 0;
|
||||
}
|
||||
state = ST_FLASHING;
|
||||
}
|
||||
}
|
||||
else if (state == ST_FLASHING) {
|
||||
// commit to flashing
|
||||
if (!unlocked && (memoryType == MEM_FLASH)) {
|
||||
unlocked = 1;
|
||||
unlockFlash();
|
||||
}
|
||||
|
||||
int progress = 0;
|
||||
if (memoryType == MEM_FLASH) {
|
||||
flashWriteBlock();
|
||||
firmwareWritten += sizeof(Block_buffer);
|
||||
progress = (100 * firmwareWritten) / firmwareSize;
|
||||
}
|
||||
|
||||
bootloaderDrawScreen(state, progress);
|
||||
|
||||
fr = readBinFile();
|
||||
if (BlockCount == 0) {
|
||||
state = ST_FLASH_DONE; // EOF
|
||||
}
|
||||
else if (memoryType == MEM_FLASH && firmwareWritten >= FIRMWARE_MAX_LEN) {
|
||||
state = ST_FLASH_DONE; // Backstop
|
||||
}
|
||||
#if defined(SPI_FLASH)
|
||||
} else if (state == ST_CLEAR_FLASH_CHECK) {
|
||||
bootloaderDrawScreen(state, vpos);
|
||||
if (IS_NEXT_EVENT(event)) {
|
||||
if (vpos < SEL_CLEAR_FLASH_STORAGE_MENU_LEN - 1) { vpos++; }
|
||||
continue;
|
||||
}
|
||||
if (IS_PREVIOUS_EVENT(event)) {
|
||||
if (vpos > 0) { vpos--; }
|
||||
continue;
|
||||
}
|
||||
if (event == EVT_KEY_LONG(KEY_ENTER) && vpos == 0)
|
||||
{
|
||||
state = ST_CLEAR_FLASH;
|
||||
} else if (event == EVT_KEY_BREAK(KEY_EXIT) ||
|
||||
(event == EVT_KEY_BREAK(KEY_ENTER) && vpos == 1) ) {
|
||||
vpos = 0;
|
||||
state = ST_START;
|
||||
continue;
|
||||
}
|
||||
} else if (state == ST_CLEAR_FLASH) {
|
||||
bootloaderDrawScreen(state, 0);
|
||||
lcdRefresh();
|
||||
sdDone();
|
||||
spiFlashDiskEraseAll();
|
||||
sdInit();
|
||||
vpos = 0;
|
||||
state = ST_START;
|
||||
#endif
|
||||
} else if (state == ST_RADIO_MENU) {
|
||||
if(bootloaderRadioMenu(radioMenuItem, event))
|
||||
{
|
||||
state = ST_START;
|
||||
vpos = 0;
|
||||
bootloaderDrawScreen(state, vpos);
|
||||
}
|
||||
}
|
||||
|
||||
if (state == ST_FLASH_DONE) {
|
||||
if (unlocked) {
|
||||
lockFlash();
|
||||
unlocked = 0;
|
||||
}
|
||||
|
||||
if (event == EVT_KEY_BREAK(KEY_EXIT) || event == EVT_KEY_BREAK(KEY_ENTER)) {
|
||||
state = ST_START;
|
||||
vpos = 0;
|
||||
}
|
||||
|
||||
bootloaderDrawScreen(state, 100);
|
||||
}
|
||||
|
||||
if (event == EVT_KEY_LONG(KEY_EXIT)) {
|
||||
// Start the main application
|
||||
state = ST_REBOOT;
|
||||
}
|
||||
|
||||
lcdRefresh();
|
||||
|
||||
}
|
||||
|
||||
if (state != ST_FLASHING && state != ST_USB) {
|
||||
if (pwrOffPressed()) {
|
||||
sdDone();
|
||||
boardOff();
|
||||
}
|
||||
}
|
||||
|
||||
if (state == ST_REBOOT) {
|
||||
sdDone();
|
||||
#if !defined(SIMU)
|
||||
blExit();
|
||||
NVIC_SystemReset();
|
||||
#if !defined(FIRMWARE_FORMAT_UF2)
|
||||
bootloaderMenu();
|
||||
#else
|
||||
exit(1);
|
||||
bootloaderUF2();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -25,6 +25,8 @@
|
||||
#include "stamp.h"
|
||||
#include "keys.h"
|
||||
|
||||
#include "hal/flash_driver.h"
|
||||
|
||||
#if LCD_W < 212
|
||||
#if defined(VERSION_TAG)
|
||||
#define BOOTLOADER_TITLE " Bootloader - " VERSION_TAG
|
||||
@@ -61,11 +63,14 @@ enum BootloaderState {
|
||||
ST_REBOOT,
|
||||
};
|
||||
|
||||
enum FlashCheckRes {
|
||||
FC_UNCHECKED=0,
|
||||
FC_OK,
|
||||
FC_ERROR
|
||||
};
|
||||
// interactive bootloader
|
||||
void bootloaderMenu();
|
||||
|
||||
// non-interactive UF2 bootloader
|
||||
void bootloaderUF2();
|
||||
|
||||
// non-interactive DFU bootloader
|
||||
void bootloaderDFU();
|
||||
|
||||
// Declarations of functions that need to be implemented
|
||||
// for each target with a bootloader
|
||||
@@ -87,4 +92,7 @@ uint32_t bootloaderGetMenuItemCount(int baseCount);
|
||||
// returns true on submenu exit
|
||||
bool bootloaderRadioMenu(uint32_t menuItem, event_t event);
|
||||
|
||||
void bootloaderDrawDFUScreen();
|
||||
|
||||
void sdInit();
|
||||
void blExit();
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
#include "stm32_hal.h"
|
||||
|
||||
#include "boot.h"
|
||||
#include "hal/usb_driver.h"
|
||||
#include "lcd.h"
|
||||
|
||||
extern volatile uint8_t tenms;
|
||||
|
||||
void bootloaderDFU()
|
||||
{
|
||||
usbPlugged();
|
||||
usbStart();
|
||||
|
||||
bootloaderDrawDFUScreen();
|
||||
|
||||
for (;;) {
|
||||
if (tenms) {
|
||||
if (!usbPlugged()) break;
|
||||
bootloaderDrawDFUScreen();
|
||||
lcdRefresh();
|
||||
}
|
||||
}
|
||||
|
||||
blExit();
|
||||
NVIC_SystemReset();
|
||||
}
|
||||
@@ -0,0 +1,297 @@
|
||||
#include "boot.h"
|
||||
#include "firmware_files.h"
|
||||
|
||||
#include "hal/usb_driver.h"
|
||||
#include "hal/rotary_encoder.h"
|
||||
|
||||
#include "lcd.h"
|
||||
|
||||
#if defined(SPI_FLASH)
|
||||
#define MAIN_MENU_LEN 3
|
||||
#else
|
||||
#define MAIN_MENU_LEN 2
|
||||
#endif
|
||||
|
||||
#if defined(SPI_FLASH)
|
||||
#include "diskio_spi_flash.h"
|
||||
#define SEL_CLEAR_FLASH_STORAGE_MENU_LEN 2
|
||||
#endif
|
||||
|
||||
volatile tmr10ms_t g_tmr10ms;
|
||||
volatile uint8_t tenms = 1;
|
||||
|
||||
void per5ms() {} // make linker happy
|
||||
|
||||
void per10ms()
|
||||
{
|
||||
tenms |= 1u; // 10 mS has passed
|
||||
g_tmr10ms++;
|
||||
|
||||
keysPollingCycle();
|
||||
|
||||
// TODO: use rotaryEncoderPollingCycle() instead
|
||||
#if defined(ROTARY_ENCODER_NAVIGATION) && !defined(USE_HATS_AS_KEYS)
|
||||
static rotenc_t rePreviousValue;
|
||||
|
||||
rotenc_t reNewValue = rotaryEncoderGetValue();
|
||||
int8_t scrollRE = reNewValue - rePreviousValue;
|
||||
if (scrollRE) {
|
||||
rePreviousValue = reNewValue;
|
||||
pushEvent(scrollRE < 0 ? EVT_ROTARY_LEFT : EVT_ROTARY_RIGHT);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
FlashCheckRes valid;
|
||||
|
||||
int menuFlashFile(uint32_t index, event_t event)
|
||||
{
|
||||
valid = checkFirmwareFile(index, valid);
|
||||
|
||||
if (valid == FC_ERROR) {
|
||||
if (event == EVT_KEY_BREAK(KEY_EXIT) || event == EVT_KEY_BREAK(KEY_ENTER))
|
||||
return 0;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (event == EVT_KEY_LONG(KEY_ENTER)) {
|
||||
return openFirmwareFile(index) == FR_OK ? 1 : -1;
|
||||
} else if (event == EVT_KEY_BREAK(KEY_EXIT))
|
||||
return 0;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
void bootloaderMenu()
|
||||
{
|
||||
BootloaderState state = ST_START;
|
||||
uint32_t vpos = 0;
|
||||
uint32_t radioMenuItem = 0;
|
||||
uint8_t index = 0;
|
||||
FRESULT fr;
|
||||
uint32_t nameCount = 0;
|
||||
|
||||
sdInit();
|
||||
|
||||
for (;;) {
|
||||
|
||||
if (tenms) {
|
||||
tenms = 0;
|
||||
|
||||
if (state != ST_USB && state != ST_FLASHING
|
||||
&& state != ST_FLASH_DONE && state != ST_RADIO_MENU) {
|
||||
if (usbPlugged()) {
|
||||
state = ST_USB;
|
||||
#if !defined(SIMU)
|
||||
usbStart();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
if (state == ST_USB) {
|
||||
if (usbPlugged() == 0) {
|
||||
vpos = 0;
|
||||
#if !defined(SIMU)
|
||||
usbStop();
|
||||
#endif
|
||||
state = ST_START;
|
||||
}
|
||||
bootloaderDrawScreen(state, 0);
|
||||
}
|
||||
|
||||
lcdRefreshWait();
|
||||
event_t event = getEvent();
|
||||
|
||||
if (state == ST_START) {
|
||||
|
||||
bootloaderDrawScreen(state, vpos);
|
||||
|
||||
if (IS_NEXT_EVENT(event)) {
|
||||
if (vpos < bootloaderGetMenuItemCount(MAIN_MENU_LEN) - 1) { vpos++; }
|
||||
continue;
|
||||
}
|
||||
else if (IS_PREVIOUS_EVENT(event)) {
|
||||
if (vpos > 0) { vpos--; }
|
||||
continue;
|
||||
}
|
||||
else if (event == EVT_KEY_BREAK(KEY_ENTER)) {
|
||||
switch (vpos) {
|
||||
case 0:
|
||||
state = ST_DIR_CHECK;
|
||||
break;
|
||||
#if defined(SPI_FLASH)
|
||||
case 1:
|
||||
state = ST_CLEAR_FLASH_CHECK;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
if(vpos < bootloaderGetMenuItemCount(MAIN_MENU_LEN-1))
|
||||
{
|
||||
state = ST_RADIO_MENU;
|
||||
radioMenuItem = vpos - MAIN_MENU_LEN - 1;
|
||||
} else {
|
||||
state = ST_REBOOT;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// next loop
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else if (state == ST_DIR_CHECK) {
|
||||
fr = openFirmwareDir();
|
||||
|
||||
if (fr == FR_OK) {
|
||||
index = vpos = 0;
|
||||
state = ST_FILE_LIST;
|
||||
nameCount = fetchFirmwareFiles(index);
|
||||
continue;
|
||||
}
|
||||
else {
|
||||
bootloaderDrawScreen(state, fr);
|
||||
|
||||
if (event == EVT_KEY_BREAK(KEY_EXIT) || event == EVT_KEY_BREAK(KEY_ENTER)) {
|
||||
vpos = 0;
|
||||
state = ST_START;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (state == ST_FILE_LIST) {
|
||||
uint32_t limit = MAX_NAMES_ON_SCREEN;
|
||||
if (nameCount < limit) {
|
||||
limit = nameCount;
|
||||
}
|
||||
|
||||
if (IS_NEXT_EVENT(event)) {
|
||||
if (vpos < limit - 1) {
|
||||
vpos += 1;
|
||||
} else {
|
||||
if (nameCount > limit) {
|
||||
index += 1;
|
||||
nameCount = fetchFirmwareFiles(index);
|
||||
}
|
||||
}
|
||||
} else if (IS_PREVIOUS_EVENT(event)) {
|
||||
if (vpos > 0) {
|
||||
vpos -= 1;
|
||||
}
|
||||
else {
|
||||
if (index) {
|
||||
index -= 1;
|
||||
nameCount = fetchFirmwareFiles(index);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bootloaderDrawScreen(state, 0);
|
||||
|
||||
for (uint32_t i = 0; i < limit; i++) {
|
||||
bootloaderDrawFilename(getFirmwareFileNameByIndex(i), i, (vpos == i));
|
||||
}
|
||||
|
||||
if (event == EVT_KEY_BREAK(KEY_ENTER)) {
|
||||
// Select file to flash
|
||||
state = ST_FLASH_CHECK;
|
||||
valid = FC_UNCHECKED;
|
||||
continue;
|
||||
} else if (event == EVT_KEY_BREAK(KEY_EXIT)) {
|
||||
state = ST_START;
|
||||
vpos = 0;
|
||||
continue;
|
||||
}
|
||||
} else if (state == ST_FLASH_CHECK) {
|
||||
bootloaderDrawScreen(state, valid, getFirmwareFileNameByIndex(vpos));
|
||||
|
||||
int result = menuFlashFile(vpos, event);
|
||||
if (result == 0) {
|
||||
// canceled
|
||||
state = ST_FILE_LIST;
|
||||
} else if (result == 1) {
|
||||
// confirmed
|
||||
firmwareInitWrite(vpos);
|
||||
state = ST_FLASHING;
|
||||
}
|
||||
} else if (state == ST_FLASHING) {
|
||||
uint32_t progress = 0;
|
||||
bool done = firmwareWriteBlock(&progress);
|
||||
bootloaderDrawScreen(state, progress);
|
||||
if(done) {
|
||||
state = ST_FLASH_DONE;
|
||||
}
|
||||
#if defined(SPI_FLASH)
|
||||
} else if (state == ST_CLEAR_FLASH_CHECK) {
|
||||
bootloaderDrawScreen(state, vpos);
|
||||
if (IS_NEXT_EVENT(event)) {
|
||||
if (vpos < SEL_CLEAR_FLASH_STORAGE_MENU_LEN - 1) { vpos++; }
|
||||
continue;
|
||||
}
|
||||
if (IS_PREVIOUS_EVENT(event)) {
|
||||
if (vpos > 0) { vpos--; }
|
||||
continue;
|
||||
}
|
||||
if (event == EVT_KEY_LONG(KEY_ENTER) && vpos == 0)
|
||||
{
|
||||
state = ST_CLEAR_FLASH;
|
||||
} else if (event == EVT_KEY_BREAK(KEY_EXIT) ||
|
||||
(event == EVT_KEY_BREAK(KEY_ENTER) && vpos == 1) ) {
|
||||
vpos = 0;
|
||||
state = ST_START;
|
||||
continue;
|
||||
}
|
||||
} else if (state == ST_CLEAR_FLASH) {
|
||||
bootloaderDrawScreen(state, 0);
|
||||
lcdRefresh();
|
||||
sdDone();
|
||||
spiFlashDiskEraseAll();
|
||||
sdInit();
|
||||
vpos = 0;
|
||||
state = ST_START;
|
||||
#endif
|
||||
} else if (state == ST_RADIO_MENU) {
|
||||
if(bootloaderRadioMenu(radioMenuItem, event))
|
||||
{
|
||||
state = ST_START;
|
||||
vpos = 0;
|
||||
bootloaderDrawScreen(state, vpos);
|
||||
}
|
||||
}
|
||||
|
||||
if (state == ST_FLASH_DONE) {
|
||||
if (event == EVT_KEY_BREAK(KEY_EXIT) || event == EVT_KEY_BREAK(KEY_ENTER)) {
|
||||
state = ST_START;
|
||||
vpos = 0;
|
||||
}
|
||||
|
||||
bootloaderDrawScreen(state, 100);
|
||||
}
|
||||
|
||||
if (event == EVT_KEY_LONG(KEY_EXIT)) {
|
||||
// Start the main application
|
||||
state = ST_REBOOT;
|
||||
}
|
||||
|
||||
lcdRefresh();
|
||||
}
|
||||
|
||||
if (state != ST_FLASHING && state != ST_USB) {
|
||||
if (pwrOffPressed()) {
|
||||
sdDone();
|
||||
boardOff();
|
||||
}
|
||||
}
|
||||
|
||||
if (state == ST_REBOOT) {
|
||||
sdDone();
|
||||
#if !defined(SIMU)
|
||||
blExit();
|
||||
NVIC_SystemReset();
|
||||
#else
|
||||
exit(1);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
#include "boot.h"
|
||||
|
||||
#include "hal/usb_driver.h"
|
||||
#include "hal/storage.h"
|
||||
#include "hal/fatfs_diskio.h"
|
||||
|
||||
#include "thirdparty/FatFs/diskio.h"
|
||||
#include "drivers/uf2_ghostfat.h"
|
||||
|
||||
#include "board.h"
|
||||
#include "lcd.h"
|
||||
|
||||
extern uf2_fat_write_state_t _uf2_write_state;
|
||||
|
||||
volatile tmr10ms_t g_tmr10ms;
|
||||
volatile uint8_t tenms = 1;
|
||||
|
||||
void per5ms() {} // make linker happy
|
||||
|
||||
void per10ms()
|
||||
{
|
||||
tenms |= 1u; // 10 mS has passed
|
||||
g_tmr10ms++;
|
||||
}
|
||||
|
||||
void bootloaderUF2()
|
||||
{
|
||||
BootloaderState state = ST_START;
|
||||
|
||||
// register SD storage
|
||||
storageInit();
|
||||
disk_initialize(0);
|
||||
|
||||
for (;;) {
|
||||
|
||||
if (tenms) {
|
||||
tenms = 0;
|
||||
|
||||
if (state != ST_USB && state != ST_FLASHING && state != ST_FLASH_DONE) {
|
||||
if (usbPlugged()) {
|
||||
state = ST_USB;
|
||||
#if !defined(SIMU)
|
||||
usbStart();
|
||||
#endif
|
||||
} else if (pwrOffPressed()) {
|
||||
storageDeInit();
|
||||
boardOff();
|
||||
}
|
||||
}
|
||||
|
||||
if (state == ST_USB || state == ST_FLASH_DONE) {
|
||||
if (usbPlugged() == 0) {
|
||||
#if !defined(SIMU)
|
||||
usbStop();
|
||||
#endif
|
||||
state = (state == ST_FLASH_DONE) ? ST_REBOOT : ST_START;
|
||||
} else {
|
||||
auto wr_st = uf2_fat_get_state();
|
||||
if (wr_st->num_blocks != 0 && wr_st->num_blocks <= UF2_MAX_BLOCKS) {
|
||||
state = ST_FLASHING;
|
||||
}
|
||||
}
|
||||
bootloaderDrawScreen(state, 0);
|
||||
}
|
||||
|
||||
if (state == ST_START) {
|
||||
bootloaderDrawScreen(state, 0);
|
||||
} else if (state == ST_FLASHING) {
|
||||
auto wr_st = uf2_fat_get_state();
|
||||
if (wr_st->num_blocks == 0 || wr_st->num_blocks > UF2_MAX_BLOCKS) {
|
||||
state = ST_USB;
|
||||
} else {
|
||||
uint32_t progress = (wr_st->num_written * 100) / wr_st->num_blocks;
|
||||
if (wr_st->num_written == wr_st->num_blocks) {
|
||||
state = ST_FLASH_DONE;
|
||||
uf2_fat_reset_state();
|
||||
}
|
||||
bootloaderDrawScreen(state, progress);
|
||||
}
|
||||
} else if (state == ST_FLASH_DONE) {
|
||||
bootloaderDrawScreen(state, 100);
|
||||
}
|
||||
|
||||
lcdRefresh();
|
||||
}
|
||||
|
||||
if (state == ST_REBOOT) {
|
||||
storageDeInit();
|
||||
#if !defined(SIMU)
|
||||
blExit();
|
||||
NVIC_SystemReset();
|
||||
#else
|
||||
exit(1);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
+23
-39
@@ -26,13 +26,9 @@
|
||||
#if defined(COLORLCD)
|
||||
#include "bitmaps.h"
|
||||
#endif
|
||||
#include "boards/FirmwareVersionTag.h"
|
||||
|
||||
enum MemoryType {
|
||||
MEM_FLASH,
|
||||
MEM_EEPROM
|
||||
};
|
||||
|
||||
#define getBinaryPath(mt) (FIRMWARES_PATH)
|
||||
#define getFirmwarePath() (FIRMWARES_PATH)
|
||||
|
||||
#if LCD_H == 480
|
||||
#define MAX_NAMES_ON_SCREEN 13
|
||||
@@ -40,56 +36,44 @@ enum MemoryType {
|
||||
#define MAX_NAMES_ON_SCREEN 6
|
||||
#endif
|
||||
|
||||
#define MAX_BIN_FILES (MAX_NAMES_ON_SCREEN+1)
|
||||
#define MAX_FW_FILES (MAX_NAMES_ON_SCREEN+1)
|
||||
|
||||
// Size of the block read when checking / writing BIN files
|
||||
#define BLOCK_LEN 4096
|
||||
|
||||
// File info struct while browsing files on SD card
|
||||
struct BinFileInfo {
|
||||
TCHAR name[FF_MAX_LFN + 1];
|
||||
unsigned int size;
|
||||
};
|
||||
|
||||
// File info storage while browsing files on SD card
|
||||
extern BinFileInfo binFiles[MAX_BIN_FILES];
|
||||
|
||||
// Block buffer used when checking / writing BIN files
|
||||
extern uint8_t Block_buffer[BLOCK_LEN];
|
||||
|
||||
// Bytes read into the Block_buffer
|
||||
extern UINT BlockCount;
|
||||
|
||||
// Open directory for EEPROM / firmware files
|
||||
FRESULT openBinDir(MemoryType mt);
|
||||
// Open directory for firmware files
|
||||
FRESULT openFirmwareDir();
|
||||
|
||||
// Fetch file names and sizes into binFiles,
|
||||
// starting at the provided index.
|
||||
// Only files ending with ".bin" (case-insensitive)
|
||||
// will be considered.
|
||||
unsigned int fetchBinFiles(unsigned int index);
|
||||
unsigned int fetchFirmwareFiles(unsigned int index);
|
||||
const char* getFirmwareFileNameByIndex(unsigned int index);
|
||||
|
||||
// Open file indexed in binFiles and read the first BLOCK_LEN bytes
|
||||
// Bootloader is skipped in firmware files
|
||||
FRESULT openBinFile(MemoryType mt, unsigned int index);
|
||||
FRESULT openFirmwareFile(unsigned int index);
|
||||
|
||||
struct VersionTag
|
||||
{
|
||||
char flavour[11];
|
||||
const char* version;
|
||||
const char* fork;
|
||||
};
|
||||
// Ensure flavour can hold FLAVOUR defined in target cmakefile
|
||||
static_assert(sizeof(((VersionTag){}).flavour) >= sizeof(FLAVOUR), "VersionTag flavour size too small");
|
||||
|
||||
|
||||
// Can be called right after openBinFile() to extract the version information
|
||||
// from a firmware file
|
||||
void extractFirmwareVersion(VersionTag* tag);
|
||||
void getFileFirmwareVersion(VersionTag* tag);
|
||||
|
||||
// Read the next BLOCK_LEN bytes into 'Block_buffer'
|
||||
// Check 'BlockCount' for # of bytes read
|
||||
FRESULT readBinFile();
|
||||
FRESULT readFirmwareFile();
|
||||
|
||||
// Close the previously opened file
|
||||
FRESULT closeBinFile();
|
||||
FRESULT closeFirmwareFile();
|
||||
|
||||
enum FlashCheckRes {
|
||||
FC_UNCHECKED=0,
|
||||
FC_OK,
|
||||
FC_ERROR
|
||||
};
|
||||
FlashCheckRes checkFirmwareFile(unsigned int index, FlashCheckRes res);
|
||||
|
||||
void firmwareInitWrite(uint32_t index);
|
||||
bool firmwareEraseBlock(uint32_t* progress);
|
||||
bool firmwareWriteBlock(uint32_t* progress);
|
||||
|
||||
@@ -125,17 +125,28 @@
|
||||
#define BLOCK_SIZE FF_MAX_SS
|
||||
#define SD_TIMEOUT 300 /* 300ms */
|
||||
|
||||
#if defined(STM32H7) || defined(STM32H7RS) || defined(STM32F4)
|
||||
#if defined(STM32F4)
|
||||
extern uint32_t _sram;
|
||||
extern uint32_t _heap_start;
|
||||
#if defined(SDRAM)
|
||||
#define _IS_DMA_BUFFER(addr) \
|
||||
#define _IS_DMA_BUFFER(addr) \
|
||||
(((((intptr_t)(addr)) & 0xFF000000) == (((intptr_t)&_sram) & 0xFF000000)) || \
|
||||
((((intptr_t)(addr)) & 0xFC000000) == (((intptr_t)&_heap_start) & 0xFC000000)))
|
||||
((((intptr_t)(addr)) & 0xFC000000) == \
|
||||
(((intptr_t)&_heap_start) & 0xFC000000)))
|
||||
#else
|
||||
#define _IS_DMA_BUFFER(addr) \
|
||||
((((intptr_t)(addr)) & 0xFF000000) == (((intptr_t)&_sram) & 0xFF000000))
|
||||
#endif
|
||||
#elif defined(STM32H7) || defined(STM32H7RS)
|
||||
extern uint32_t _sram;
|
||||
extern uint32_t _s_dram;
|
||||
extern uint32_t _heap_start;
|
||||
#define _IS_DMA_BUFFER(addr) \
|
||||
(((((intptr_t)(addr)) & 0xFF000000) == (((intptr_t)&_sram) & 0xFF000000)) || \
|
||||
((((intptr_t)(addr)) & 0xFFF60000) == \
|
||||
(((intptr_t)&_s_dram) & 0xFFF60000)) || \
|
||||
((((intptr_t)(addr)) & 0xFC000000) == \
|
||||
(((intptr_t)&_heap_start) & 0xFC000000)))
|
||||
#else
|
||||
#define _IS_DMA_BUFFER(addr) (true)
|
||||
#endif
|
||||
@@ -343,14 +354,14 @@ static DRESULT _read_dma(BYTE* buff, DWORD sector, UINT count)
|
||||
return RES_ERROR;
|
||||
}
|
||||
|
||||
#if __CORTEX_M >= 0x07
|
||||
SCB_CleanInvalidateDCache();
|
||||
#endif
|
||||
|
||||
// Wait for the reading process to complete or a timeout to occur
|
||||
uint32_t timeout = HAL_GetTick();
|
||||
while((ReadStatus == 0) && ((HAL_GetTick() - timeout) < SD_TIMEOUT));
|
||||
|
||||
#if __CORTEX_M >= 0x07
|
||||
SCB_CleanInvalidateDCache();
|
||||
#endif
|
||||
|
||||
if (ReadStatus == 0) {
|
||||
TRACE("SD read timeout (s:%u c:%u)", sector, (uint32_t)count);
|
||||
return RES_ERROR;
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
#include "hal/gpio.h"
|
||||
#include "sdcard_spi.h"
|
||||
|
||||
|
||||
#include "hal.h"
|
||||
|
||||
#if defined(SD_SPI)
|
||||
@@ -39,10 +40,10 @@
|
||||
|
||||
static const stm32_spi_t _sd_spi_hw = {
|
||||
.SPIx = SD_SPI,
|
||||
.SPI_GPIOx = SD_GPIO,
|
||||
.SPI_Pins = SD_GPIO_PIN_SCK | SD_GPIO_PIN_MISO | SD_GPIO_PIN_MOSI,
|
||||
.CS_GPIOx = SD_GPIO,
|
||||
.CS_Pin = SD_GPIO_PIN_CS,
|
||||
.SCK = SD_GPIO_PIN_SCK,
|
||||
.MISO = SD_GPIO_PIN_MISO,
|
||||
.MOSI = SD_GPIO_PIN_MOSI,
|
||||
.CS = SD_GPIO_PIN_CS,
|
||||
.DMA = SD_SPI_DMA,
|
||||
.DMA_Channel = SD_SPI_DMA_CHANNEL,
|
||||
.txDMA_Stream = SD_SPI_DMA_TX_STREAM,
|
||||
|
||||
@@ -62,6 +62,8 @@ set(FIRMWARE_SRC ${FIRMWARE_SRC} $<TARGET_OBJECTS:stm32_stdperiph>)
|
||||
set(BOOTLOADER_SRC ${BOOTLOADER_SRC} $<TARGET_OBJECTS:stm32_stdperiph>)
|
||||
|
||||
if(NOT NATIVE_BUILD)
|
||||
include_directories(targets/common/arm/stm32/f2)
|
||||
|
||||
#
|
||||
# FreeRTOS port specific include
|
||||
#
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright (C) EdgeTX
|
||||
*
|
||||
* Based on code named
|
||||
* opentx - https://github.com/opentx/opentx
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#define __CCMRAM
|
||||
#define __DMA
|
||||
#define __DMA_NO_CACHE
|
||||
#define __IRAM
|
||||
#define __SDRAM
|
||||
#define __SDRAMFONTS
|
||||
|
||||
@@ -97,6 +97,8 @@ set(FIRMWARE_SRC ${FIRMWARE_SRC} $<TARGET_OBJECTS:stm32_stdperiph>)
|
||||
set(BOOTLOADER_SRC ${BOOTLOADER_SRC} $<TARGET_OBJECTS:stm32_stdperiph>)
|
||||
|
||||
if(NOT NATIVE_BUILD)
|
||||
include_directories(targets/common/arm/stm32/f4)
|
||||
|
||||
#
|
||||
# FreeRTOS port specific include
|
||||
#
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright (C) EdgeTX
|
||||
*
|
||||
* Based on code named
|
||||
* opentx - https://github.com/opentx/opentx
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#define __CCMRAM __attribute__((section(".ccm"), aligned(4)))
|
||||
#define __DMA __attribute__((section(".ram"), aligned(4)))
|
||||
#define __DMA_NO_CACHE __DMA
|
||||
#define __IRAM
|
||||
|
||||
#if defined(SDRAM)
|
||||
#define __SDRAM __attribute__((section(".sdram"), aligned(4)))
|
||||
#define __SDRAMFONTS __attribute__((section(".sdram_fonts"), aligned(4)))
|
||||
#else
|
||||
#define __SDRAM
|
||||
#define __SDRAMFONTS
|
||||
#endif
|
||||
|
||||
@@ -19,10 +19,14 @@
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include "flash_driver.h"
|
||||
|
||||
#include "stm32_cmsis.h"
|
||||
#include "stm32_hal.h"
|
||||
|
||||
uint32_t stm32_flash_get_size_kb()
|
||||
#include <string.h>
|
||||
|
||||
static uint32_t stm32_flash_get_size_kb()
|
||||
{
|
||||
uint32_t flash_size_kb = *(const uint32_t*)FLASHSIZE_BASE;
|
||||
return flash_size_kb;
|
||||
@@ -30,7 +34,7 @@ uint32_t stm32_flash_get_size_kb()
|
||||
|
||||
#if defined(STM32F2) || defined(STM32F4)
|
||||
|
||||
uint32_t stm32_flash_get_sector(uint32_t address)
|
||||
static uint32_t stm32_flash_get_sector(uint32_t address)
|
||||
{
|
||||
uint32_t sector;
|
||||
uint32_t sector_addr = address & 0xFFFFF;
|
||||
@@ -68,12 +72,12 @@ static uint32_t _flash_sector_address(uint32_t sector, uint32_t bank)
|
||||
return addr;
|
||||
}
|
||||
|
||||
uint32_t stm32_flash_get_sector_size(uint32_t sector)
|
||||
static uint32_t stm32_flash_get_sector_size(uint32_t sector)
|
||||
{
|
||||
// bank 2
|
||||
if (sector >= 12) sector -= 12;
|
||||
|
||||
// first 4: 16KB
|
||||
// first 4: 16KB
|
||||
if (sector < 4) return 16 * 1024;
|
||||
// sector 4: 64KB
|
||||
if (sector == 4) return 64 * 1024;
|
||||
@@ -83,7 +87,7 @@ uint32_t stm32_flash_get_sector_size(uint32_t sector)
|
||||
|
||||
#elif defined(STM32H7) || defined(STM32H7RS)
|
||||
|
||||
uint32_t stm32_flash_get_sector(uint32_t address)
|
||||
static uint32_t stm32_flash_get_sector(uint32_t address)
|
||||
{
|
||||
uint32_t sector_addr = address & 0xFFFFF;
|
||||
return sector_addr / FLASH_SECTOR_SIZE;
|
||||
@@ -99,7 +103,7 @@ static uint32_t _flash_sector_address(uint32_t sector, uint32_t bank)
|
||||
return addr;
|
||||
}
|
||||
|
||||
uint32_t stm32_flash_get_sector_size(uint32_t sector)
|
||||
static uint32_t stm32_flash_get_sector_size(uint32_t sector)
|
||||
{
|
||||
(void)sector;
|
||||
return FLASH_SECTOR_SIZE;
|
||||
@@ -107,7 +111,7 @@ uint32_t stm32_flash_get_sector_size(uint32_t sector)
|
||||
|
||||
#endif
|
||||
|
||||
uint32_t stm32_flash_get_bank(uint32_t address)
|
||||
static uint32_t stm32_flash_get_bank(uint32_t address)
|
||||
{
|
||||
#if defined(DUAL_BANK)
|
||||
return ((address & 0x100000) != 0x100000) ? FLASH_BANK_1 : FLASH_BANK_2;
|
||||
@@ -120,10 +124,10 @@ uint32_t stm32_flash_get_bank(uint32_t address)
|
||||
#endif
|
||||
}
|
||||
|
||||
void stm32_flash_unlock() { HAL_FLASH_Unlock(); }
|
||||
void stm32_flash_lock() { HAL_FLASH_Lock(); }
|
||||
static inline void stm32_flash_unlock() { HAL_FLASH_Unlock(); }
|
||||
static inline void stm32_flash_lock() { HAL_FLASH_Lock(); }
|
||||
|
||||
int stm32_flash_erase_sector(uint32_t address)
|
||||
static int stm32_flash_erase_sector(uint32_t address)
|
||||
{
|
||||
FLASH_EraseInitTypeDef eraseInit;
|
||||
eraseInit.TypeErase = FLASH_TYPEERASE_SECTORS;
|
||||
@@ -138,12 +142,16 @@ int stm32_flash_erase_sector(uint32_t address)
|
||||
eraseInit.VoltageRange = FLASH_VOLTAGE_RANGE_3;
|
||||
#endif
|
||||
|
||||
int ret = 0;
|
||||
uint32_t sector_errors = 0;
|
||||
|
||||
stm32_flash_unlock();
|
||||
if (HAL_FLASHEx_Erase(&eraseInit, §or_errors) != HAL_OK) {
|
||||
return -1;
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
stm32_flash_lock();
|
||||
return ret;
|
||||
}
|
||||
|
||||
#if defined(STM32H7)
|
||||
@@ -160,23 +168,42 @@ int stm32_flash_erase_sector(uint32_t address)
|
||||
HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, address, *p_data)
|
||||
#endif
|
||||
|
||||
int stm32_flash_program(uint32_t address, uint8_t* data, uint32_t len)
|
||||
static int stm32_flash_program(uint32_t address, void* data, uint32_t len)
|
||||
{
|
||||
uint32_t* p_data = (uint32_t*)data;
|
||||
uint32_t end_addr = address + len;
|
||||
|
||||
int ret = 0;
|
||||
stm32_flash_unlock();
|
||||
while (address < end_addr) {
|
||||
if (_FLASH_PROGRAM(address, p_data) != HAL_OK) {
|
||||
return -1;
|
||||
ret = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
address += sizeof(uint32_t) * FLASH_PROG_WORDS;
|
||||
p_data += FLASH_PROG_WORDS;
|
||||
}
|
||||
|
||||
stm32_flash_lock();
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int stm32_flash_read(uint32_t address, void* data, uint32_t len)
|
||||
{
|
||||
memcpy(data, (void*)address, len);
|
||||
return 0;
|
||||
}
|
||||
|
||||
const etx_flash_driver_t stm32_flash_driver = {
|
||||
.get_size_kb = stm32_flash_get_size_kb,
|
||||
.get_sector = stm32_flash_get_sector,
|
||||
.get_sector_size = stm32_flash_get_sector_size,
|
||||
.erase_sector = stm32_flash_erase_sector,
|
||||
.program = stm32_flash_program,
|
||||
.read = stm32_flash_read,
|
||||
};
|
||||
|
||||
// Legacy API
|
||||
|
||||
#define FLASH_PAGESIZE 256
|
||||
@@ -215,6 +242,21 @@ uint32_t isFirmwareStart(const uint8_t * buffer)
|
||||
if ((block[2] & 0xFFC00000) != 0x08000000) {
|
||||
return 0;
|
||||
}
|
||||
#elif defined(STM32H7)
|
||||
// // Stack pointer in D1 RAM
|
||||
// if ((block[0] & 0xFFFC0000) != 0x24080000) {
|
||||
// Stack pointer in DTCM RAM
|
||||
if ((block[0] & 0xFFFF0000) != 0x20020000) {
|
||||
return 0;
|
||||
}
|
||||
// First ISR pointer in FLASH
|
||||
if ((block[1] & 0xF0000000) != 0x90000000) {
|
||||
return 0;
|
||||
}
|
||||
// Second ISR pointer in FLASH
|
||||
if ((block[2] & 0xF0000000) != 0xC0000000) {
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
// Stack pointer in RAM
|
||||
if ((block[0] & 0xFFFC0000) != 0x20000000) {
|
||||
|
||||
@@ -23,24 +23,26 @@
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
uint32_t stm32_flash_get_size_kb();
|
||||
uint32_t stm32_flash_get_sector(uint32_t address);
|
||||
uint32_t stm32_flash_get_sector_size(uint32_t sector);
|
||||
uint32_t stm32_flash_get_bank(uint32_t address);
|
||||
#include "hal/flash_driver.h"
|
||||
|
||||
void stm32_flash_unlock();
|
||||
void stm32_flash_lock();
|
||||
// uint32_t stm32_flash_get_size_kb();
|
||||
// uint32_t stm32_flash_get_sector(uint32_t address);
|
||||
// uint32_t stm32_flash_get_sector_size(uint32_t sector);
|
||||
// uint32_t stm32_flash_get_bank(uint32_t address);
|
||||
|
||||
int stm32_flash_erase_sector(uint32_t address);
|
||||
int stm32_flash_program(uint32_t address, uint8_t* data, uint32_t len);
|
||||
// void stm32_flash_unlock();
|
||||
// void stm32_flash_lock();
|
||||
|
||||
// int stm32_flash_erase_sector(uint32_t address);
|
||||
// int stm32_flash_program(uint32_t address, uint8_t* data, uint32_t len);
|
||||
|
||||
extern const etx_flash_driver_t stm32_flash_driver;
|
||||
extern const void* stm32_flash_dfu_media;
|
||||
|
||||
// Legacy API
|
||||
|
||||
uint32_t isFirmwareStart(const uint8_t * buffer);
|
||||
uint32_t isBootloaderStart(const uint8_t * buffer);
|
||||
|
||||
void unlockFlash();
|
||||
void lockFlash();
|
||||
|
||||
void flashWrite(uint32_t* address, const uint32_t* buffer);
|
||||
|
||||
|
||||
@@ -85,7 +85,9 @@ static void _fs_parse(STRUCT_HALL *hallBuffer, unsigned char ch)
|
||||
hallBuffer->length = ch;
|
||||
hallBuffer->dataIndex = 0;
|
||||
hallBuffer->status = GET_DATA;
|
||||
if (0 == hallBuffer->length) {
|
||||
if(hallBuffer->length > HALLSTICK_BUFF_SIZE - 5) { // buffer size - header size (1 byte header + 1 byte ID + 1 byte length + 2 bytes CRC = 5 bytes)
|
||||
hallBuffer->status = GET_START;
|
||||
} else if (0 == hallBuffer->length) {
|
||||
hallBuffer->status = GET_CHECKSUM;
|
||||
hallBuffer->checkSum = 0;
|
||||
}
|
||||
@@ -142,6 +144,7 @@ static void flysky_gimbal_loop(void*)
|
||||
|
||||
switch (HallProtocol.hallID.hall_Id.receiverID) {
|
||||
case TRANSFER_DIR_TXMCU:
|
||||
case TRANSFER_DIR_RFMODULE:
|
||||
if (HallProtocol.hallID.hall_Id.packetID ==
|
||||
FLYSKY_HALL_RESP_TYPE_VALUES) {
|
||||
int16_t* p_values = (int16_t*)HallProtocol.data;
|
||||
|
||||
@@ -22,8 +22,10 @@
|
||||
#pragma once
|
||||
|
||||
#include "hal/serial_port.h"
|
||||
|
||||
#define HALLSTICK_BUFF_SIZE ( 512 )
|
||||
|
||||
// Max packet size = 1 byte header + 1 byte ID + 1 byte length + 25 bytes payload + 2 bytes CRC = 30 bytes
|
||||
// using 32 bytes is more than enough
|
||||
#define HALLSTICK_BUFF_SIZE ( 32 )
|
||||
#define FLYSKY_HALL_BAUDRATE ( 921600 )
|
||||
#define FLYSKY_HALL_CHANNEL_COUNT ( 4 )
|
||||
|
||||
|
||||
@@ -2,89 +2,149 @@ set(CPU_FAMILY STM32)
|
||||
set(MCU cortex-m7)
|
||||
set(FPU_FLAGS "-mfloat-abi=hard -mfpu=fpv4-sp-d16")
|
||||
|
||||
if(NOT NATIVE_BUILD)
|
||||
# STM32 HAL/LL library
|
||||
set(STM32CUBE_DIR ${THIRDPARTY_DIR}/STM32H7xx_HAL_Driver)
|
||||
include_directories(${STM32CUBE_DIR}/Inc)
|
||||
|
||||
add_library(stm32cube_ll OBJECT EXCLUDE_FROM_ALL
|
||||
# LL drivers
|
||||
${STM32CUBE_DIR}/Src/stm32h7xx_ll_gpio.c
|
||||
${STM32CUBE_DIR}/Src/stm32h7xx_ll_fmc.c
|
||||
${STM32CUBE_DIR}/Src/stm32h7xx_ll_tim.c
|
||||
${STM32CUBE_DIR}/Src/stm32h7xx_ll_dma.c
|
||||
${STM32CUBE_DIR}/Src/stm32h7xx_ll_usart.c
|
||||
${STM32CUBE_DIR}/Src/stm32h7xx_ll_rcc.c
|
||||
${STM32CUBE_DIR}/Src/stm32h7xx_ll_exti.c
|
||||
${STM32CUBE_DIR}/Src/stm32h7xx_ll_sdmmc.c
|
||||
${STM32CUBE_DIR}/Src/stm32h7xx_ll_adc.c
|
||||
${STM32CUBE_DIR}/Src/stm32h7xx_ll_spi.c
|
||||
${STM32CUBE_DIR}/Src/stm32h7xx_ll_usb.c
|
||||
${STM32CUBE_DIR}/Src/stm32h7xx_ll_dma2d.c
|
||||
# HAL drivers
|
||||
${STM32CUBE_DIR}/Src/stm32h7xx_hal.c
|
||||
${STM32CUBE_DIR}/Src/stm32h7xx_hal_pwr.c
|
||||
${STM32CUBE_DIR}/Src/stm32h7xx_hal_pwr_ex.c
|
||||
${STM32CUBE_DIR}/Src/stm32h7xx_hal_rcc.c
|
||||
${STM32CUBE_DIR}/Src/stm32h7xx_hal_rcc_ex.c
|
||||
${STM32CUBE_DIR}/Src/stm32h7xx_hal_rtc.c
|
||||
${STM32CUBE_DIR}/Src/stm32h7xx_hal_i2c.c
|
||||
${STM32CUBE_DIR}/Src/stm32h7xx_hal_i2c_ex.c
|
||||
${STM32CUBE_DIR}/Src/stm32h7xx_hal_sd.c
|
||||
${STM32CUBE_DIR}/Src/stm32h7xx_hal_dma.c
|
||||
${STM32CUBE_DIR}/Src/stm32h7xx_hal_mdma.c
|
||||
${STM32CUBE_DIR}/Src/stm32h7xx_hal_pcd.c
|
||||
${STM32CUBE_DIR}/Src/stm32h7xx_hal_pcd_ex.c
|
||||
${STM32CUBE_DIR}/Src/stm32h7xx_hal_qspi.c
|
||||
${STM32CUBE_DIR}/Src/stm32h7xx_hal_flash.c
|
||||
${STM32CUBE_DIR}/Src/stm32h7xx_hal_flash_ex.c
|
||||
${STM32CUBE_DIR}/Src/stm32h7xx_hal_cortex.c
|
||||
${STM32CUBE_DIR}/Src/stm32h7xx_hal_sdram.c
|
||||
${STM32CUBE_DIR}/Src/stm32h7xx_hal_gpio.c
|
||||
${STM32CUBE_DIR}/Src/stm32h7xx_hal_dsi.c
|
||||
${STM32CUBE_DIR}/Src/stm32h7xx_hal_ltdc.c
|
||||
)
|
||||
# CMSIS library
|
||||
set(CMSIS_DIR ${THIRDPARTY_DIR}/CMSIS)
|
||||
include_directories(${CMSIS_DIR}/Include)
|
||||
|
||||
if(CPU_TYPE STREQUAL STM32H7RS)
|
||||
include_directories(${CMSIS_DIR}/Device/ST/STM32H7RS/Include)
|
||||
set(CMSIS_SRC
|
||||
targets/common/arm/stm32/h7/system_stm32h7rsxx.c
|
||||
)
|
||||
else()
|
||||
include_directories(${CMSIS_DIR}/Device/ST/STM32H7xx/Include)
|
||||
set(CMSIS_SRC
|
||||
targets/common/arm/stm32/h7/system_stm32h7xx.c
|
||||
)
|
||||
endif()
|
||||
|
||||
|
||||
if(NOT NATIVE_BUILD)
|
||||
if(CPU_TYPE STREQUAL STM32H7RS)
|
||||
set(STM32CUBE_PREFIX stm32h7rsxx)
|
||||
set(STM32CUBE_DIR ${THIRDPARTY_DIR}/STM32H7RS_HAL_Driver)
|
||||
set(STM32CUBE_SRC_PREFIX ${STM32CUBE_DIR}/Src/${STM32CUBE_PREFIX})
|
||||
set(STM32CUBE_SRC
|
||||
# LL drivers
|
||||
${STM32CUBE_SRC_PREFIX}_ll_gpio.c
|
||||
${STM32CUBE_SRC_PREFIX}_ll_fmc.c
|
||||
${STM32CUBE_SRC_PREFIX}_ll_tim.c
|
||||
${STM32CUBE_SRC_PREFIX}_ll_dma.c
|
||||
${STM32CUBE_SRC_PREFIX}_ll_usart.c
|
||||
${STM32CUBE_SRC_PREFIX}_ll_rcc.c
|
||||
${STM32CUBE_SRC_PREFIX}_ll_exti.c
|
||||
${STM32CUBE_SRC_PREFIX}_ll_sdmmc.c
|
||||
${STM32CUBE_SRC_PREFIX}_ll_adc.c
|
||||
${STM32CUBE_SRC_PREFIX}_ll_spi.c
|
||||
${STM32CUBE_SRC_PREFIX}_ll_usb.c
|
||||
${STM32CUBE_SRC_PREFIX}_ll_dma2d.c
|
||||
# HAL drivers
|
||||
${STM32CUBE_SRC_PREFIX}_hal.c
|
||||
${STM32CUBE_SRC_PREFIX}_hal_pwr.c
|
||||
${STM32CUBE_SRC_PREFIX}_hal_pwr_ex.c
|
||||
${STM32CUBE_SRC_PREFIX}_hal_rcc.c
|
||||
${STM32CUBE_SRC_PREFIX}_hal_rcc_ex.c
|
||||
${STM32CUBE_SRC_PREFIX}_hal_rtc.c
|
||||
${STM32CUBE_SRC_PREFIX}_hal_i2c.c
|
||||
${STM32CUBE_SRC_PREFIX}_hal_i2c_ex.c
|
||||
${STM32CUBE_SRC_PREFIX}_hal_sd.c
|
||||
${STM32CUBE_SRC_PREFIX}_hal_dma.c
|
||||
${STM32CUBE_SRC_PREFIX}_hal_pcd.c
|
||||
${STM32CUBE_SRC_PREFIX}_hal_pcd_ex.c
|
||||
${STM32CUBE_SRC_PREFIX}_hal_xspi.c
|
||||
${STM32CUBE_SRC_PREFIX}_hal_flash.c
|
||||
${STM32CUBE_SRC_PREFIX}_hal_flash_ex.c
|
||||
${STM32CUBE_SRC_PREFIX}_hal_cortex.c
|
||||
${STM32CUBE_SRC_PREFIX}_hal_sdram.c
|
||||
${STM32CUBE_SRC_PREFIX}_hal_gpio.c
|
||||
${STM32CUBE_SRC_PREFIX}_hal_ltdc.c
|
||||
${STM32CUBE_SRC_PREFIX}_hal_lptim.c
|
||||
)
|
||||
else()
|
||||
set(STM32CUBE_PREFIX stm32h7xx)
|
||||
set(STM32CUBE_DIR ${THIRDPARTY_DIR}/STM32H7xx_HAL_Driver)
|
||||
set(STM32CUBE_SRC_PREFIX ${STM32CUBE_DIR}/Src/${STM32CUBE_PREFIX})
|
||||
set(STM32CUBE_SRC
|
||||
# LL drivers
|
||||
${STM32CUBE_SRC_PREFIX}_ll_gpio.c
|
||||
${STM32CUBE_SRC_PREFIX}_ll_fmc.c
|
||||
${STM32CUBE_SRC_PREFIX}_ll_tim.c
|
||||
${STM32CUBE_SRC_PREFIX}_ll_dma.c
|
||||
${STM32CUBE_SRC_PREFIX}_ll_usart.c
|
||||
${STM32CUBE_SRC_PREFIX}_ll_rcc.c
|
||||
${STM32CUBE_SRC_PREFIX}_ll_exti.c
|
||||
${STM32CUBE_SRC_PREFIX}_ll_sdmmc.c
|
||||
${STM32CUBE_SRC_PREFIX}_ll_adc.c
|
||||
${STM32CUBE_SRC_PREFIX}_ll_spi.c
|
||||
${STM32CUBE_SRC_PREFIX}_ll_usb.c
|
||||
${STM32CUBE_SRC_PREFIX}_ll_dma2d.c
|
||||
# HAL drivers
|
||||
${STM32CUBE_SRC_PREFIX}_hal.c
|
||||
${STM32CUBE_SRC_PREFIX}_hal_pwr.c
|
||||
${STM32CUBE_SRC_PREFIX}_hal_pwr_ex.c
|
||||
${STM32CUBE_SRC_PREFIX}_hal_rcc.c
|
||||
${STM32CUBE_SRC_PREFIX}_hal_rcc_ex.c
|
||||
${STM32CUBE_SRC_PREFIX}_hal_rtc.c
|
||||
${STM32CUBE_SRC_PREFIX}_hal_i2c.c
|
||||
${STM32CUBE_SRC_PREFIX}_hal_i2c_ex.c
|
||||
${STM32CUBE_SRC_PREFIX}_hal_sd.c
|
||||
${STM32CUBE_SRC_PREFIX}_hal_dma.c
|
||||
${STM32CUBE_SRC_PREFIX}_hal_mdma.c
|
||||
${STM32CUBE_SRC_PREFIX}_hal_pcd.c
|
||||
${STM32CUBE_SRC_PREFIX}_hal_pcd_ex.c
|
||||
${STM32CUBE_SRC_PREFIX}_hal_qspi.c
|
||||
${STM32CUBE_SRC_PREFIX}_hal_flash.c
|
||||
${STM32CUBE_SRC_PREFIX}_hal_flash_ex.c
|
||||
${STM32CUBE_SRC_PREFIX}_hal_cortex.c
|
||||
${STM32CUBE_SRC_PREFIX}_hal_sdram.c
|
||||
${STM32CUBE_SRC_PREFIX}_hal_gpio.c
|
||||
${STM32CUBE_SRC_PREFIX}_hal_dsi.c
|
||||
${STM32CUBE_SRC_PREFIX}_hal_ltdc.c
|
||||
)
|
||||
endif()
|
||||
|
||||
# STM32 HAL/LL library
|
||||
include_directories(${STM32CUBE_DIR}/Inc)
|
||||
|
||||
add_library(stm32cube_ll OBJECT EXCLUDE_FROM_ALL ${STM32CUBE_SRC})
|
||||
target_compile_definitions(stm32cube_ll PRIVATE USE_FULL_LL_DRIVER)
|
||||
target_include_directories(stm32cube_ll PRIVATE
|
||||
${THIRDPARTY_DIR}/CMSIS/Device/ST/STM32H7xx/Include
|
||||
${THIRDPARTY_DIR}/CMSIS/Include)
|
||||
|
||||
set(FIRMWARE_SRC ${FIRMWARE_SRC} $<TARGET_OBJECTS:stm32cube_ll>)
|
||||
set(BOOTLOADER_SRC ${BOOTLOADER_SRC} $<TARGET_OBJECTS:stm32cube_ll>)
|
||||
endif()
|
||||
|
||||
# StdPeriph library
|
||||
set(STM32LIB_DIR ${THIRDPARTY_DIR})
|
||||
include_directories(${STM32LIB_DIR}/CMSIS/Device/ST/STM32H7xx/Include)
|
||||
include_directories(${STM32LIB_DIR}/CMSIS/Include)
|
||||
|
||||
add_definitions(-DSTM32H7)
|
||||
|
||||
set(STM32_STDPERIPH_SRC
|
||||
targets/common/arm/stm32/h7/system_stm32h7xx.c
|
||||
)
|
||||
if(CPU_TYPE STREQUAL STM32H7RS)
|
||||
add_definitions(-DSTM32H7RS)
|
||||
else()
|
||||
add_definitions(-DSTM32H7)
|
||||
endif()
|
||||
|
||||
if(CPU_TYPE_FULL STREQUAL STM32H750Ix)
|
||||
set(STM32_STDPERIPH_SRC ${STM32_STDPERIPH_SRC}
|
||||
set(CMSIS_SRC ${CMSIS_SRC}
|
||||
boards/generic_stm32/startup/startup_stm32h750xx.s
|
||||
)
|
||||
)
|
||||
elseif(CPU_TYPE_FULL STREQUAL STM32H747Ix)
|
||||
set(STM32_STDPERIPH_SRC ${STM32_STDPERIPH_SRC}
|
||||
set(CMSIS_SRC ${CMSIS_SRC}
|
||||
boards/generic_stm32/startup/startup_stm32h747xx.s
|
||||
)
|
||||
elseif(CPU_TYPE_FULL STREQUAL STM32H7S7xx)
|
||||
set(CMSIS_SRC ${CMSIS_SRC}
|
||||
boards/generic_stm32/startup/startup_stm32h7s7xx.s
|
||||
)
|
||||
else()
|
||||
message("### ERROR ####: ${CPU_TYPE_FULL}")
|
||||
endif()
|
||||
|
||||
add_library(stm32_stdperiph OBJECT EXCLUDE_FROM_ALL
|
||||
${STM32_STDPERIPH_SRC}
|
||||
add_library(cmsis OBJECT EXCLUDE_FROM_ALL
|
||||
${CMSIS_SRC}
|
||||
)
|
||||
|
||||
set(FIRMWARE_SRC ${FIRMWARE_SRC} $<TARGET_OBJECTS:stm32_stdperiph>)
|
||||
set(BOOTLOADER_SRC ${BOOTLOADER_SRC} $<TARGET_OBJECTS:stm32_stdperiph>)
|
||||
set(FIRMWARE_SRC ${FIRMWARE_SRC} $<TARGET_OBJECTS:cmsis>)
|
||||
set(BOOTLOADER_SRC ${BOOTLOADER_SRC} $<TARGET_OBJECTS:cmsis>)
|
||||
|
||||
if(NOT NATIVE_BUILD)
|
||||
include_directories(targets/common/arm/stm32/h7)
|
||||
|
||||
#
|
||||
# FreeRTOS port specific include
|
||||
#
|
||||
@@ -112,4 +172,9 @@ if(NOT NATIVE_BUILD)
|
||||
# System and FreeRTOS port files
|
||||
#
|
||||
set(FIRMWARE_SRC ${FIRMWARE_SRC} $<TARGET_OBJECTS:freertos>)
|
||||
|
||||
#
|
||||
# Firmware description
|
||||
#
|
||||
set(FIRMWARE_SRC ${FIRMWARE_SRC} fw_desc.c)
|
||||
endif()
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright (C) EdgeTX
|
||||
*
|
||||
* Based on code named
|
||||
* opentx - https://github.com/opentx/opentx
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#define __CCMRAM __attribute__((section(".ccm"), aligned(4)))
|
||||
#define __DMA __attribute__((section(".ram"), aligned(4)))
|
||||
#define __DMA_NO_CACHE __attribute__((section(".dram"), aligned(4)))
|
||||
#define __IRAM __attribute__((section(".iram")))
|
||||
#define __SDRAM __attribute__((section(".sdram"), aligned(4)))
|
||||
#define __SDRAMFONTS __attribute__((section(".sdram_fonts"), aligned(4)))
|
||||
|
||||
|
||||
@@ -0,0 +1,285 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file system_stm32h7rsxx.c
|
||||
* @author MCD Application Team
|
||||
* @brief CMSIS Cortex-M7 Device Peripheral Access Layer System Source File
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2022 STMicroelectronics.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is licensed under terms that can be found in the LICENSE file
|
||||
* in the root directory of this software component.
|
||||
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||
*
|
||||
******************************************************************************
|
||||
*
|
||||
* This file provides two functions and one global variable to be called from
|
||||
* user application:
|
||||
* - SystemInit(): This function is called at startup just after reset and
|
||||
* before branch to main program. This call is made inside
|
||||
* the "startup_stm32h7rsxx.s" file.
|
||||
*
|
||||
* - SystemCoreClock variable: Contains the core clock (sys_cpu_ck), it can
|
||||
* be used by the user application to setup the
|
||||
* SysTick timer or configure other parameters.
|
||||
*
|
||||
* - SystemCoreClockUpdate(): Updates the variable SystemCoreClock and must
|
||||
* be called whenever the core clock is changed
|
||||
* during program execution.
|
||||
*
|
||||
* After each device reset the HSI (64 MHz) is used as system clock source.
|
||||
* Then SystemInit() function is called, in "startup_stm32h7rsxx.s" file, to
|
||||
* optionally configure the system clock before to branch to main program.
|
||||
*
|
||||
*=============================================================================
|
||||
*/
|
||||
|
||||
/** @addtogroup CMSIS
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup STM32H7RSxx_System
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup STM32H7RSxx_System_Private_Includes
|
||||
* @{
|
||||
*/
|
||||
|
||||
#include "stm32h7rsxx.h"
|
||||
#include <math.h>
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup STM32H7RSxx_System_Private_TypesDefinitions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup STM32H7RSxx_System_Private_Defines
|
||||
* @{
|
||||
*/
|
||||
#if !defined (HSE_VALUE)
|
||||
#define HSE_VALUE 24000000UL /*!< Value of the High-Speed External oscillator in Hz */
|
||||
#endif /* HSE_VALUE */
|
||||
|
||||
#if !defined (HSI_VALUE)
|
||||
#define HSI_VALUE 64000000UL /*!< Value of the High-Speed Internal oscillator in Hz */
|
||||
#endif /* HSI_VALUE */
|
||||
|
||||
#if !defined (CSI_VALUE)
|
||||
#define CSI_VALUE 4000000UL /*!< Value of the Low-power Internal oscillator in Hz */
|
||||
#endif /* CSI_VALUE */
|
||||
|
||||
/*!< The VTOR location information is based on information from the linker with a dependency
|
||||
on the IDE, the cortex register is updated using the INTVECT_START.
|
||||
*/
|
||||
#if defined(__ICCARM__)
|
||||
extern uint32_t __vector_table;
|
||||
#define INTVECT_START ((uint32_t)& __vector_table)
|
||||
#elif defined(__CC_ARM) || defined(__ARMCC_VERSION)
|
||||
extern void * __Vectors;
|
||||
#define INTVECT_START ((uint32_t) & __Vectors)
|
||||
#elif defined(__GNUC__)
|
||||
extern void * g_pfnVectors;
|
||||
#define INTVECT_START ((uint32_t)& g_pfnVectors)
|
||||
#endif /* __ICCARM__*/
|
||||
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup STM32H7RSxx_System_Private_Macros
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup STM32H7RSxx_System_Private_Variables
|
||||
* @{
|
||||
*/
|
||||
/* The SystemCoreClock variable is updated in two ways:
|
||||
1) by calling CMSIS function SystemCoreClockUpdate()
|
||||
2) each time HAL_RCC_ClockConfig() is called to configure the system clock frequency
|
||||
Note: If you use this function to configure the system clock; then there
|
||||
is no need to call the first function listed above, since SystemCoreClock
|
||||
variable is updated automatically.
|
||||
*/
|
||||
uint32_t SystemCoreClock = HSI_VALUE;
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup STM32H7RSxx_System_Private_FunctionPrototypes
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup STM32H7RSxx_System_Private_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Setup the microcontroller system.
|
||||
* @retval None
|
||||
*/
|
||||
|
||||
void SystemInit(void)
|
||||
{
|
||||
/* Configure the Vector Table location -------------------------------------*/
|
||||
SCB->VTOR = INTVECT_START;
|
||||
|
||||
/* FPU settings ------------------------------------------------------------*/
|
||||
#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
|
||||
SCB->CPACR |= ((3UL << 20U)|(3UL << 22U)); /* set CP10 and CP11 Full Access */
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Update SystemCoreClock variable according to RCC registers values.
|
||||
* The SystemCoreClock variable contains the core clock (sys_cpu_ck), it can
|
||||
* be used by the user application to setup the SysTick timer or configure
|
||||
* other parameters.
|
||||
*
|
||||
* @note Each time the core clock changes, this function must be called
|
||||
* to update SystemCoreClock variable value. Otherwise, any configuration
|
||||
* based on this variable will be incorrect.
|
||||
*
|
||||
* @note - The system frequency computed by this function is not the real
|
||||
* frequency in the chip. It is calculated based on the predefined
|
||||
* constant and the selected clock source:
|
||||
*
|
||||
* - If SYSCLK source is HSI, SystemCoreClock will contain the HSI_VALUE(*)
|
||||
*
|
||||
* - If SYSCLK source is CSI, SystemCoreClock will contain the CSI_VALUE(**)
|
||||
*
|
||||
* - If SYSCLK source is HSE, SystemCoreClock will contain the HSE_VALUE(***)
|
||||
*
|
||||
* - If SYSCLK source is PLL, SystemCoreClock will contain the HSI_VALUE(*)
|
||||
* or CSI_VALUE(**) or HSE_VALUE(***) multiplied/divided by the PLL factors.
|
||||
*
|
||||
* (*) HSI_VALUE is a constant defined in stm32h7rsxx_hal.h file (default value
|
||||
* 64 MHz) but the real value may vary depending on the variations
|
||||
* in voltage and temperature.
|
||||
*
|
||||
* (**) CSI_VALUE is a constant defined in stm32h7rsxx_hal.h file (default value
|
||||
* 4 MHz) but the real value may vary depending on the variations
|
||||
* in voltage and temperature.
|
||||
*
|
||||
* (***) HSE_VALUE is a constant defined in stm32h7rsxx_hal.h file (default value
|
||||
* 24 MHz), user has to ensure that HSE_VALUE is same as the real
|
||||
* frequency of the crystal used. Otherwise, this function may
|
||||
* have wrong result.
|
||||
*
|
||||
* - The result of this function could be not correct when using fractional
|
||||
* value for HSE crystal.
|
||||
*
|
||||
* @retval None
|
||||
*/
|
||||
void SystemCoreClockUpdate(void)
|
||||
{
|
||||
uint32_t sysclk, hsivalue, pllsource, pllm, pllp, core_presc;
|
||||
float_t pllfracn, pllvco;
|
||||
|
||||
/* Get SYSCLK source -------------------------------------------------------*/
|
||||
switch (RCC->CFGR & RCC_CFGR_SWS)
|
||||
{
|
||||
case 0x00: /* HSI used as system clock source (default after reset) */
|
||||
sysclk = (HSI_VALUE >> ((RCC->CR & RCC_CR_HSIDIV) >> RCC_CR_HSIDIV_Pos));
|
||||
break;
|
||||
|
||||
case 0x08: /* CSI used as system clock source */
|
||||
sysclk = CSI_VALUE;
|
||||
break;
|
||||
|
||||
case 0x10: /* HSE used as system clock source */
|
||||
sysclk = HSE_VALUE;
|
||||
break;
|
||||
|
||||
case 0x18: /* PLL1 used as system clock source */
|
||||
/* PLL1_VCO = (HSE_VALUE or HSI_VALUE or CSI_VALUE/ PLLM) * PLLN
|
||||
SYSCLK = PLL1_VCO / PLL1R
|
||||
*/
|
||||
pllsource = (RCC->PLLCKSELR & RCC_PLLCKSELR_PLLSRC);
|
||||
pllm = ((RCC->PLLCKSELR & RCC_PLLCKSELR_DIVM1) >> RCC_PLLCKSELR_DIVM1_Pos) ;
|
||||
if ((RCC->PLLCFGR & RCC_PLLCFGR_PLL1FRACEN) != 0U)
|
||||
{
|
||||
pllfracn = (float_t)(uint32_t)(((RCC->PLL1FRACR & RCC_PLL1FRACR_FRACN)>> RCC_PLL1FRACR_FRACN_Pos));
|
||||
}
|
||||
else
|
||||
{
|
||||
pllfracn = (float_t)0U;
|
||||
}
|
||||
|
||||
if (pllm != 0U)
|
||||
{
|
||||
switch (pllsource)
|
||||
{
|
||||
case 0x02: /* HSE used as PLL1 clock source */
|
||||
pllvco = ((float_t)HSE_VALUE / (float_t)pllm) * ((float_t)(uint32_t)(RCC->PLL1DIVR1 & RCC_PLL1DIVR1_DIVN) + (pllfracn/(float_t)0x2000) +(float_t)1 );
|
||||
break;
|
||||
|
||||
case 0x01: /* CSI used as PLL1 clock source */
|
||||
pllvco = ((float_t)CSI_VALUE / (float_t)pllm) * ((float_t)(uint32_t)(RCC->PLL1DIVR1 & RCC_PLL1DIVR1_DIVN) + (pllfracn/(float_t)0x2000) +(float_t)1 );
|
||||
break;
|
||||
|
||||
case 0x00: /* HSI used as PLL1 clock source */
|
||||
default:
|
||||
hsivalue = (HSI_VALUE >> ((RCC->CR & RCC_CR_HSIDIV) >> RCC_CR_HSIDIV_Pos));
|
||||
pllvco = ( (float_t)hsivalue / (float_t)pllm) * ((float_t)(uint32_t)(RCC->PLL1DIVR1 & RCC_PLL1DIVR1_DIVN) + (pllfracn/(float_t)0x2000) +(float_t)1 );
|
||||
break;
|
||||
}
|
||||
pllp = (((RCC->PLL1DIVR1 & RCC_PLL1DIVR1_DIVP) >> RCC_PLL1DIVR1_DIVP_Pos) + 1U ) ;
|
||||
sysclk = (uint32_t)(float_t)(pllvco/(float_t)pllp);
|
||||
}
|
||||
else
|
||||
{
|
||||
sysclk = 0U;
|
||||
}
|
||||
break;
|
||||
|
||||
default: /* Unexpected, default to HSI used as system clock source (default after reset) */
|
||||
sysclk = (HSI_VALUE >> ((RCC->CR & RCC_CR_HSIDIV) >> RCC_CR_HSIDIV_Pos));
|
||||
break;
|
||||
}
|
||||
|
||||
/* system clock frequency : CM7 CPU frequency */
|
||||
core_presc = (RCC->CDCFGR & RCC_CDCFGR_CPRE);
|
||||
if (core_presc >= 8U)
|
||||
{
|
||||
SystemCoreClock = (sysclk >> (core_presc - RCC_CDCFGR_CPRE_3 + 1U));
|
||||
}
|
||||
else
|
||||
{
|
||||
SystemCoreClock = sysclk;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
@@ -178,7 +178,10 @@
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
void SystemInit (void)
|
||||
|
||||
#define BOOTSTRAP __attribute__((section(".bootstrap")))
|
||||
|
||||
BOOTSTRAP void SystemInit (void)
|
||||
{
|
||||
#if defined (DATA_IN_D2_SRAM)
|
||||
__IO uint32_t tmpreg;
|
||||
@@ -481,21 +484,21 @@ void I2C2_EV_IRQHandler(void){asm("BKPT");}
|
||||
void I2C2_ER_IRQHandler(void){asm("BKPT");}
|
||||
void SPI1_IRQHandler(void){asm("BKPT");}
|
||||
void SPI2_IRQHandler(void){asm("BKPT");}
|
||||
void EXTI15_10_IRQHandler(void){asm("BKPT");}
|
||||
//void EXTI15_10_IRQHandler(void){asm("BKPT");}
|
||||
void RTC_Alarm_IRQHandler(void){asm("BKPT");}
|
||||
void TIM8_CC_IRQHandler(void){asm("BKPT");}
|
||||
void DMA1_Stream7_IRQHandler(void){asm("BKPT");}
|
||||
//void DMA1_Stream7_IRQHandler(void){asm("BKPT");}
|
||||
void FMC_IRQHandler(void){asm("BKPT");}
|
||||
void TIM5_IRQHandler(void){asm("BKPT");}
|
||||
void SPI3_IRQHandler(void){asm("BKPT");}
|
||||
void UART5_IRQHandler(void){asm("BKPT");}
|
||||
//void UART5_IRQHandler(void){asm("BKPT");}
|
||||
void TIM7_IRQHandler(void){asm("BKPT");}
|
||||
//void DMA2_Stream0_IRQHandler(void){asm("BKPT");}
|
||||
void DMA2_Stream2_IRQHandler(void){asm("BKPT");}
|
||||
void DMA2_Stream3_IRQHandler(void){asm("BKPT");}
|
||||
//void DMA2_Stream4_IRQHandler(void){asm("BKPT");}
|
||||
void ETH_IRQHandler(void){asm("BKPT");}
|
||||
void ETH_WKUP_IRQHandler(void){asm("BKPT");}
|
||||
//void ETH_WKUP_IRQHandler(void){asm("BKPT");}
|
||||
void FDCAN_CAL_IRQHandler(void){asm("BKPT");}
|
||||
void DMA2_Stream5_IRQHandler(void){asm("BKPT");}
|
||||
void DMA2_Stream6_IRQHandler(void){asm("BKPT");}
|
||||
@@ -510,7 +513,7 @@ void DCMI_IRQHandler(void){asm("BKPT");}
|
||||
void CRYP_IRQHandler(void){asm("BKPT");}
|
||||
void HASH_RNG_IRQHandler(void){asm("BKPT");}
|
||||
void FPU_IRQHandler(void){asm("BKPT");}
|
||||
void UART8_IRQHandler(void){asm("BKPT");}
|
||||
//void UART8_IRQHandler(void){asm("BKPT");}
|
||||
void SPI4_IRQHandler(void){asm("BKPT");}
|
||||
void SPI5_IRQHandler(void){asm("BKPT");}
|
||||
void SPI6_IRQHandler(void){asm("BKPT");}
|
||||
@@ -541,7 +544,6 @@ void DFSDM1_FLT2_IRQHandler(void){asm("BKPT");}
|
||||
void DFSDM1_FLT3_IRQHandler(void){asm("BKPT");}
|
||||
void SAI3_IRQHandler(void){asm("BKPT");}
|
||||
void SWPMI1_IRQHandler(void){asm("BKPT");}
|
||||
void TIM15_IRQHandler(void){asm("BKPT");}
|
||||
void TIM16_IRQHandler(void){asm("BKPT");}
|
||||
void MDIOS_WKUP_IRQHandler(void){asm("BKPT");}
|
||||
void MDIOS_IRQHandler(void){asm("BKPT");}
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
|
||||
void pwrInit()
|
||||
{
|
||||
|
||||
#if defined(SD_PRESENT_GPIO)
|
||||
gpio_init(SD_PRESENT_GPIO, GPIO_IN_PU, GPIO_PIN_SPEED_LOW);
|
||||
#endif
|
||||
@@ -37,13 +38,13 @@ void pwrInit()
|
||||
#endif
|
||||
|
||||
// Internal module power
|
||||
#if defined(HARDWARE_INTERNAL_MODULE)
|
||||
#if defined(HARDWARE_INTERNAL_MODULE) && defined(INTMODULE_PWR_GPIO)
|
||||
gpio_init(INTMODULE_PWR_GPIO, GPIO_OUT, GPIO_PIN_SPEED_LOW);
|
||||
INTERNAL_MODULE_OFF();
|
||||
#endif
|
||||
|
||||
// External module power
|
||||
#if defined(HARDWARE_EXTERNAL_MODULE)
|
||||
#if defined(HARDWARE_EXTERNAL_MODULE) && defined(EXTMODULE_PWR_GPIO)
|
||||
gpio_init(EXTMODULE_PWR_GPIO, GPIO_OUT, GPIO_PIN_SPEED_LOW);
|
||||
EXTERNAL_MODULE_PWR_OFF();
|
||||
#endif
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user