1
0
Fork 0
mirror of https://github.com/betaflight/betaflight.git synced 2025-07-23 08:15:30 +03:00

STM32H730 - Initial ST32H730 support.

The H730 is a value-line CPU, similar to the H723/H725, but with only
128kb RAM.

The FC firmware code is designed to RUN from external flash in MEMORY
MAPPED mode, via OctoSPI.  Use of ITCM/DTCM advised for core loops, like
PID control.

A bootloader is required to enable memory-mapped mode and jump to the
firmware, similar to how EXST bootloader system works.

Config storage is not part of this commit and is a problem when using a
single flash chip in memory mapped mode because the CPU can't run
read/write routines from the flash chip while writing to the flash chip.
Until flash read/write routines are updated the solution requires either
a second flash chip on an SPI interface, or the use of an SD card for
config storage.

Additional commits will support read/write of config to the code/data
storage flash chip to enable cheap and space efficient single-flash-chip
FC solutions.

Squashed commits:
STM32H730 - Workaround issue with 2GB `.elf` files being created.
STM32H730 - Reduce firmware size to 1MB.
STM32H730 - Add USB HS configuration.
STM32H730 - Add ADC internal tag mappings.
STM32H730 - Update all ADC mappings based on the referenced ST
documentation.  Add the VBAT channels.
STM32H730 - Fix DMA continuous requests.
STM32H730 - Fix ADC_INTERNAL confusion.
STM32H730/G4 - Disambiguate use of ADC_CHANNEL_INTERNAL_FIRST_ID.
STM32H730 - Fix documentation reference.
STM32H730 - Add DMA request mapping for ADC3.
STM32H730 - Explicitly set the ADC clock.
STM32H730 - Configure PLL2 speeds correctly.

* Tested with Ultrafast 64GB SanDisk SDXC card.

STM32H730 - Use 50Mhz clock for SDXC cards.

* Tested with SanDisk Ultra 64GB.  100Mhz clock gave CRC errors.

STM32H730 - Ensure USB has a lower NVIC priority than the SDMMC card
reads.

If it's higher, 0, then the SDMMC's DMA IRQ handler doesn't get called
when handing USB MSC storage reads.

STM32H730 - Support CPU name in CLI.

STM32H730 - Rebuild when linker scripts changes.
This commit is contained in:
Dominic Clifton 2021-03-11 22:38:34 +01:00 committed by Dominic Clifton
parent 0b7fcb7df4
commit a325e2386d
24 changed files with 1382 additions and 43 deletions

View file

@ -0,0 +1,174 @@
/* Entry Point */
ENTRY(Reset_Handler)
/* Highest address of the user mode stack */
_estack = ORIGIN(STACKRAM) + LENGTH(STACKRAM); /* end of RAM */
/* Base address where the quad spi. */
__octospi1_start = ORIGIN(OCTOSPI1);
__octospi2_start = ORIGIN(OCTOSPI2);
/* Generate a link error if heap and stack don't fit into RAM */
_Min_Heap_Size = 0; /* required amount of heap */
_Min_Stack_Size = 0x800; /* required amount of stack */
/* Define output sections */
SECTIONS
{
_isr_vector_table_flash_base = LOADADDR(.isr_vector);
PROVIDE (isr_vector_table_flash_base = _isr_vector_table_flash_base);
.isr_vector :
{
. = ALIGN(512);
PROVIDE (isr_vector_table_base = .);
KEEP(*(.isr_vector)) /* Startup code */
. = ALIGN(4);
PROVIDE (isr_vector_table_end = .);
} >VECTAB AT> MAIN
_ram_isr_vector_table_base = LOADADDR(.ram_isr_vector);
PROVIDE (ram_isr_vector_table_base = _ram_isr_vector_table_base);
.ram_isr_vector (NOLOAD) :
{
. = ALIGN(512); /* Vector table offset must be multiple of 0x200 */
PROVIDE (ram_isr_vector_table_base = .);
. += (isr_vector_table_end - isr_vector_table_base);
. = ALIGN(4);
PROVIDE (ram_isr_vector_table_end = .);
} >DTCM_RAM
/* The program code and other data goes into MAIN */
.text :
{
. = ALIGN(4);
*(.text) /* .text sections (code) */
*(.text*) /* .text* sections (code) */
*(.rodata) /* .rodata sections (constants, strings, etc.) */
*(.rodata*) /* .rodata* sections (constants, strings, etc.) */
*(.glue_7) /* glue arm to thumb code */
*(.glue_7t) /* glue thumb to arm code */
*(.eh_frame)
KEEP (*(.init))
KEEP (*(.fini))
. = ALIGN(4);
_etext = .; /* define a global symbols at end of code */
} >MAIN
/* Critical program code goes into ITCM RAM */
/* Copy specific fast-executing code to ITCM RAM */
tcm_code = LOADADDR(.tcm_code);
.tcm_code :
{
. = ALIGN(4);
tcm_code_start = .;
*(.tcm_code)
*(.tcm_code*)
. = ALIGN(4);
tcm_code_end = .;
} >ITCM_RAM AT >MAIN
.ARM.extab :
{
*(.ARM.extab* .gnu.linkonce.armextab.*)
} >MAIN
.ARM :
{
__exidx_start = .;
*(.ARM.exidx*) __exidx_end = .;
} >MAIN
.pg_registry :
{
PROVIDE_HIDDEN (__pg_registry_start = .);
KEEP (*(.pg_registry))
KEEP (*(SORT(.pg_registry.*)))
PROVIDE_HIDDEN (__pg_registry_end = .);
} >MAIN
.pg_resetdata :
{
PROVIDE_HIDDEN (__pg_resetdata_start = .);
KEEP (*(.pg_resetdata))
PROVIDE_HIDDEN (__pg_resetdata_end = .);
} >MAIN
/* used by the startup to initialize data */
_sidata = LOADADDR(.data);
/* Initialized data sections goes into RAM, load LMA copy after code */
.data :
{
. = ALIGN(4);
_sdata = .; /* create a global symbol at data start */
*(.data) /* .data sections */
*(.data*) /* .data* sections */
. = ALIGN(4);
_edata = .; /* define a global symbol at data end */
} >DTCM_RAM AT >MAIN
/* Uninitialized data section */
. = ALIGN(4);
.bss (NOLOAD) :
{
/* This is used by the startup in order to initialize the .bss secion */
_sbss = .; /* define a global symbol at bss start */
__bss_start__ = _sbss;
*(.bss)
*(SORT_BY_ALIGNMENT(.bss*))
*(COMMON)
. = ALIGN(4);
_ebss = .; /* define a global symbol at bss end */
__bss_end__ = _ebss;
} >RAM
/* Uninitialized data section */
. = ALIGN(4);
.sram2 (NOLOAD) :
{
/* This is used by the startup in order to initialize the .sram2 secion */
_ssram2 = .; /* define a global symbol at sram2 start */
__sram2_start__ = _ssram2;
*(.sram2)
*(SORT_BY_ALIGNMENT(.sram2*))
. = ALIGN(4);
_esram2 = .; /* define a global symbol at sram2 end */
__sram2_end__ = _esram2;
} >RAM
/* used during startup to initialized fastram_data */
_sfastram_idata = LOADADDR(.fastram_data);
/* Initialized FAST_DATA section for unsuspecting developers */
.fastram_data :
{
. = ALIGN(4);
_sfastram_data = .; /* create a global symbol at data start */
*(.fastram_data) /* .data sections */
*(.fastram_data*) /* .data* sections */
. = ALIGN(4);
_efastram_data = .; /* define a global symbol at data end */
} >FASTRAM AT >MAIN
. = ALIGN(4);
.fastram_bss (NOLOAD) :
{
_sfastram_bss = .;
__fastram_bss_start__ = _sfastram_bss;
*(.fastram_bss)
*(SORT_BY_ALIGNMENT(.fastram_bss*))
. = ALIGN(4);
_efastram_bss = .;
__fastram_bss_end__ = _efastram_bss;
} >FASTRAM
}

View file

@ -0,0 +1,44 @@
SECTIONS
{
.persistent_data (NOLOAD) :
{
__persistent_data_start__ = .;
*(.persistent_data)
. = ALIGN(4);
__persistent_data_end__ = .;
} >RAM
/* User_heap_stack section, used to check that there is enough RAM left */
_heap_stack_end = ORIGIN(STACKRAM)+LENGTH(STACKRAM) - 8; /* 8 bytes to allow for alignment */
_heap_stack_begin = _heap_stack_end - _Min_Stack_Size - _Min_Heap_Size;
. = _heap_stack_begin;
._user_heap_stack :
{
. = ALIGN(4);
PROVIDE ( end = . );
PROVIDE ( _end = . );
. = . + _Min_Heap_Size;
. = . + _Min_Stack_Size;
. = ALIGN(4);
} >STACKRAM = 0xa5
/* MEMORY_bank1 section, code must be located here explicitly */
/* Example: extern int foo(void) __attribute__ ((section (".mb1text"))); */
.memory_b1_text :
{
*(.mb1text) /* .mb1text sections (code) */
*(.mb1text*) /* .mb1text* sections (code) */
*(.mb1rodata) /* read-only data (constants) */
*(.mb1rodata*)
} >MEMORY_B1
/* Remove information from the standard libraries */
/DISCARD/ :
{
libc.a ( * )
libm.a ( * )
libgcc.a ( * )
}
.ARM.attributes 0 : { *(.ARM.attributes) }
}

View file

@ -0,0 +1,143 @@
/*
*****************************************************************************
**
** File : stm32_flash_h750_exst.ld
**
** Abstract : Linker script for STM32H750xB Device with
** 512K AXI-RAM mapped onto AXI bus on D1 domain
** 128K SRAM1 mapped on D2 domain
** 128K SRAM2 mapped on D2 domain
** 32K SRAM3 mapped on D2 domain
** 64K SRAM4 mapped on D3 domain
** 64K ITCM
** 128K DTCM
**
*****************************************************************************
*/
/* Entry Point */
ENTRY(Reset_Handler)
/*
0x00000000 to 0x0000FFFF 64K ITCM
0x20000000 to 0x2001FFFF 128K DTCM, main RAM
0x24000000 to 0x2404FFFF 320K AXI SRAM, D1 domain
0x30000000 to 0x30003FFF 16K SRAM1, D2 domain
0x30004000 to 0x30007FFF 16K SRAM2, D2 domain
0x38000000 to 0x38003FFF 16K SRAM4, D3 domain, unused
0x38800000 to 0x38800FFF 4K BACKUP SRAM, Backup domain, unused
0x08000000 to 0x0801FFFF 128K isr vector, startup code, firmware, no config! // FLASH_Sector_0
*/
/*
For H7 EXFL (External Flash) targets a binary is built that is placed on an external device.
The bootloader will enable the memory mapped mode on the CPU which allows code to run directly from
the external flash device.
The bootloader then executes code at the CODE_RAM address. The address of CODE_RAM is fixed to 0x90010000
and must not be changed.
The initial CODE_RAM is sized at 1MB.
*/
/* see .exst section below */
_exst_hash_size = 64;
/* Specify the memory areas */
MEMORY
{
ITCM_RAM (rwx) : ORIGIN = 0x00000000, LENGTH = 64K
DTCM_RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 128K
RAM (rwx) : ORIGIN = 0x24000000, LENGTH = 128K + 192K /* 128K AXI SRAM + 192K ITCM & AXI = 320K */
D2_RAM (rwx) : ORIGIN = 0x30000000, LENGTH = 32K /* SRAM1 16K + SRAM2 16K */
D3_RAM (rwx) : ORIGIN = 0x38000000, LENGTH = 16K /* SRAM4 16K */
BACKUP_SRAM (rwx) : ORIGIN = 0x38800000, LENGTH = 4K
MEMORY_B1 (rx) : ORIGIN = 0x60000000, LENGTH = 0K
OCTOSPI2 (rx) : ORIGIN = 0x70000000, LENGTH = 256M
OCTOSPI1 (rx) : ORIGIN = 0x90000000, LENGTH = 256M
OCTOSPI1_CODE (rx): ORIGIN = ORIGIN(OCTOSPI1) + 1M, LENGTH = 1M - _exst_hash_size /* hard coded start address, as required by SPRACINGH7 boot loader, don't change! */
EXST_HASH (rx) : ORIGIN = ORIGIN(OCTOSPI1_CODE) + LENGTH(OCTOSPI1_CODE), LENGTH = _exst_hash_size
}
REGION_ALIAS("STACKRAM", DTCM_RAM)
REGION_ALIAS("FASTRAM", DTCM_RAM)
REGION_ALIAS("MAIN", OCTOSPI1_CODE)
REGION_ALIAS("VECTAB", MAIN)
INCLUDE "stm32_h730_common.ld"
SECTIONS
{
/* used during startup to initialized dmaram_data */
_sdmaram_idata = LOADADDR(.dmaram_data);
. = ALIGN(32);
.dmaram_data :
{
PROVIDE(dmaram_start = .);
_sdmaram = .;
_dmaram_start__ = _sdmaram;
_sdmaram_data = .; /* create a global symbol at data start */
*(.dmaram_data) /* .data sections */
*(.dmaram_data*) /* .data* sections */
. = ALIGN(32);
_edmaram_data = .; /* define a global symbol at data end */
} >RAM AT >MAIN
. = ALIGN(32);
.dmaram_bss (NOLOAD) :
{
_sdmaram_bss = .;
__dmaram_bss_start__ = _sdmaram_bss;
*(.dmaram_bss)
*(SORT_BY_ALIGNMENT(.dmaram_bss*))
. = ALIGN(32);
_edmaram_bss = .;
__dmaram_bss_end__ = _edmaram_bss;
} >RAM
. = ALIGN(32);
.DMA_RAM (NOLOAD) :
{
KEEP(*(.DMA_RAM))
PROVIDE(dmaram_end = .);
_edmaram = .;
_dmaram_end__ = _edmaram;
} >RAM
.DMA_RW_D2 (NOLOAD) :
{
. = ALIGN(32);
PROVIDE(dmarw_start = .);
_sdmarw = .;
_dmarw_start__ = _sdmarw;
KEEP(*(.DMA_RW))
PROVIDE(dmarw_end = .);
_edmarw = .;
_dmarw_end__ = _edmarw;
} >D2_RAM
.DMA_RW_AXI (NOLOAD) :
{
. = ALIGN(32);
PROVIDE(dmarwaxi_start = .);
_sdmarwaxi = .;
_dmarwaxi_start__ = _sdmarwaxi;
KEEP(*(.DMA_RW_AXI))
PROVIDE(dmarwaxi_end = .);
_edmarwaxi = .;
_dmarwaxi_end__ = _edmarwaxi;
} >RAM
}
INCLUDE "stm32_h730_common_post.ld"
INCLUDE "stm32_ram_h730_exst_post.ld"

View file

@ -0,0 +1,29 @@
SECTIONS
{
/* Create space for a hash. Currently an MD5 has is used, which is 16 */
/* bytes long. however the last 64 bytes are RESERVED for hash related */
.exst_hash :
{
/* 64 bytes is the size of an MD5 hashing block size. */
. = ORIGIN(EXST_HASH);
BYTE(0x00); /* block format */
BYTE(0x00); /* Checksum method, 0x00 = MD5 hash */
BYTE(0x00); /* Reserved */
BYTE(0x00); /* Reserved */
/* Fill the last 60 bytes with data, including an empty hash aligned */
/* to the last 16 bytes. */
FILL(0x00000000); /* Reserved */
. = ORIGIN(EXST_HASH) + LENGTH(EXST_HASH) - 16;
__md5_hash_address__ = .;
LONG(0x00000000);
LONG(0x00000000);
LONG(0x00000000);
LONG(0x00000000);
. = ORIGIN(EXST_HASH) + LENGTH(EXST_HASH);
__firmware_end__ = .;
} >EXST_HASH
}