diff options
| author | Damien George <damien@micropython.org> | 2024-09-10 00:02:18 +1000 |
|---|---|---|
| committer | Damien George <damien@micropython.org> | 2025-07-08 16:25:14 +1000 |
| commit | acb294f61af3bd214cc95a4881722754624b912d (patch) | |
| tree | 75bf2334674de7b522d90d707ac650a599ec4ad3 | |
| parent | 96b8f3aebcc7abc67f15c912286d0cba64589de1 (diff) | |
stm32/mboot: Add support for STM32N6xx MCUs.
Works in the usual USB DFU mode, and can program external SPI flash. It
will enable XSPI memory-mapped mode before jumping to the application
firmware in the external SPI flash.
Signed-off-by: Damien George <damien@micropython.org>
| -rwxr-xr-x | ports/stm32/mboot/Makefile | 40 | ||||
| -rw-r--r-- | ports/stm32/mboot/adc.c | 2 | ||||
| -rw-r--r-- | ports/stm32/mboot/main.c | 37 | ||||
| -rw-r--r-- | ports/stm32/mboot/mphalport.h | 17 | ||||
| -rw-r--r-- | ports/stm32/mboot/stm32_memory_n6.ld | 18 | ||||
| -rw-r--r-- | ports/stm32/mboot/stm32_sections.ld | 8 |
6 files changed, 112 insertions, 10 deletions
diff --git a/ports/stm32/mboot/Makefile b/ports/stm32/mboot/Makefile index 87bced1ae..7c0bde81f 100755 --- a/ports/stm32/mboot/Makefile +++ b/ports/stm32/mboot/Makefile @@ -34,7 +34,13 @@ include ../../../py/mkenv.mk include $(BOARD_DIR)/mpconfigboard.mk # A board can set MBOOT_TEXT0_ADDR to a custom location where mboot should reside. +ifeq ($(MCU_SERIES),n6) +MBOOT_TEXT0_ADDR ?= 0x34180400 +MBOOT_LD_FILES ?= stm32_memory_n6.ld stm32_sections.ld +else MBOOT_TEXT0_ADDR ?= 0x08000000 +MBOOT_LD_FILES ?= stm32_memory.ld stm32_sections.ld +endif # The string in MBOOT_VERSION (default defined in version.c if not defined by a # board) will be stored in the final MBOOT_VERSION_ALLOCATED_BYTES bytes of mboot flash. @@ -89,7 +95,6 @@ CFLAGS += -DMBOOT_VERSION=\"$(MBOOT_VERSION)\" endif CFLAGS += -DMBOOT_VERSION_ALLOCATED_BYTES=$(MBOOT_VERSION_ALLOCATED_BYTES) -DMBOOT_VERSION_INCLUDE_OPTIONS=$(MBOOT_VERSION_INCLUDE_OPTIONS) -MBOOT_LD_FILES ?= stm32_memory.ld stm32_sections.ld LDFLAGS += -nostdlib -L . $(addprefix -T,$(MBOOT_LD_FILES)) -Map=$(@:.elf=.map) --cref LDFLAGS += --defsym mboot_version_len=$(MBOOT_VERSION_ALLOCATED_BYTES) LIBS += $(shell $(CC) $(CFLAGS) -print-libgcc-file-name) @@ -137,12 +142,11 @@ SRC_C += \ drivers/bus/softqspi.c \ drivers/memory/spiflash.c \ ports/stm32/flash.c \ - ports/stm32/flashbdev.c \ ports/stm32/i2cslave.c \ ports/stm32/powerctrlboot.c \ ports/stm32/qspi.c \ - ports/stm32/spibdev.c \ ports/stm32/usbd_conf.c \ + ports/stm32/xspi.c \ $(wildcard $(BOARD_DIR)/*.c) SRC_O += \ @@ -169,16 +173,22 @@ SRC_HAL += $(addprefix $(STM32LIB_HAL_BASE)/Src/stm32$(MCU_SERIES)xx_,\ hal.c \ hal_cortex.c \ hal_dma.c \ - hal_flash.c \ - hal_flash_ex.c \ hal_pcd.c \ hal_pcd_ex.c \ hal_pwr_ex.c \ hal_rcc.c \ hal_rcc_ex.c \ + ll_rcc.c \ ll_usb.c \ ) +ifneq ($(MCU_SERIES),n6) +SRC_HAL += $(addprefix $(STM32LIB_HAL_BASE)/Src/stm32$(MCU_SERIES)xx_,\ + hal_flash.c \ + hal_flash_ex.c \ + ) +endif + ifeq ($(MCU_SERIES),$(filter $(MCU_SERIES),f4 f7 h7)) SRC_HAL += $(addprefix $(STM32LIB_HAL_BASE)/Src/stm32$(MCU_SERIES)xx_,\ hal_mmc.c \ @@ -187,6 +197,12 @@ SRC_HAL += $(addprefix $(STM32LIB_HAL_BASE)/Src/stm32$(MCU_SERIES)xx_,\ ) endif +ifeq ($(MCU_SERIES),n6) +SRC_HAL += $(addprefix $(STM32LIB_HAL_BASE)/Src/stm32$(MCU_SERIES)xx_,\ + hal_bsec.c \ + ) +endif + SRC_USBDEV += $(addprefix ports/stm32/$(USBDEV_DIR)/,\ core/src/usbd_core.c \ core/src/usbd_ctlreq.c \ @@ -206,7 +222,7 @@ $(TOP)/lib/stm32lib/README.md: $(ECHO) "stm32lib submodule not found, fetching it now..." (cd $(TOP) && git submodule update --init lib/stm32lib) -.PHONY: deploy deploy-stlink +.PHONY: deploy deploy-stlink deploy-trusted deploy: $(BUILD)/firmware.dfu $(ECHO) "Writing $< to the board" @@ -216,9 +232,15 @@ deploy-stlink: $(BUILD)/firmware.dfu $(ECHO) "Writing $< to the board via ST-LINK" $(Q)$(STFLASH) write $(BUILD)/firmware.bin $(MBOOT_TEXT0_ADDR) -$(BUILD)/firmware.dfu: $(BUILD)/firmware.elf +deploy-trusted: $(BUILD)/firmware-trusted.bin + $(STM32_CUBE_PROGRAMMER)/bin/STM32_Programmer.sh -c port=SWD mode=HOTPLUG ap=1 -el $(DKEL) -w $^ 0x70000000 -hardRst + +$(BUILD)/firmware.bin: $(BUILD)/firmware.elf $(ECHO) "Create $@" $(Q)$(OBJCOPY) -O binary -j .isr_vector -j .text -j .data -j .mboot_version_text $^ $(BUILD)/firmware.bin + +$(BUILD)/firmware.dfu: $(BUILD)/firmware.bin + $(ECHO) "Create $@" $(Q)$(PYTHON) $(DFU) -b $(MBOOT_TEXT0_ADDR):$(BUILD)/firmware.bin $@ $(BUILD)/firmware.hex: $(BUILD)/firmware.elf @@ -230,6 +252,10 @@ $(BUILD)/firmware.elf: $(OBJ) $(Q)$(LD) $(LDFLAGS) -o $@ $^ $(LIBS) $(Q)$(SIZE) $@ +$(BUILD)/firmware-trusted.bin: $(BUILD)/firmware.bin + /bin/rm -f $@ + $(STM32_CUBE_PROGRAMMER)/bin/STM32_SigningTool_CLI -bin $^ -nk -of 0x80000000 -t fsbl -o $@ -hv $(STM32_N6_HEADER_VERSION) + ######################################### # Rules to generate header files diff --git a/ports/stm32/mboot/adc.c b/ports/stm32/mboot/adc.c index c7b974924..06db0b59b 100644 --- a/ports/stm32/mboot/adc.c +++ b/ports/stm32/mboot/adc.c @@ -1,3 +1,5 @@ // Include the main ADC driver, so mboot can use adc_config() and adc_config_and_read_u16(). #include "py/obj.h" +#if MICROPY_PY_MACHINE_ADC #include "../machine_adc.c" +#endif diff --git a/ports/stm32/mboot/main.c b/ports/stm32/mboot/main.c index ff44dac63..2be879335 100644 --- a/ports/stm32/mboot/main.c +++ b/ports/stm32/mboot/main.c @@ -41,6 +41,7 @@ #include "sdcard.h" #include "dfu.h" #include "pack.h" +#include "xspi.h" // Whether the bootloader will leave via reset, or direct jump to the application. #ifndef MBOOT_LEAVE_BOOTLOADER_VIA_RESET @@ -373,7 +374,7 @@ void SystemClock_Config(void) { #elif defined(STM32G0) #define AHBxENR IOPENR #define AHBxENR_GPIOAEN_Pos RCC_IOPENR_GPIOAEN_Pos -#elif defined(STM32H7) +#elif defined(STM32H7) || defined(STM32N6) #define AHBxENR AHB4ENR #define AHBxENR_GPIOAEN_Pos RCC_AHB4ENR_GPIOAEN_Pos #elif defined(STM32H5) || defined(STM32WB) @@ -424,6 +425,10 @@ void mp_hal_pin_config_speed(uint32_t port_pin, uint32_t speed) { #define MBOOT_SPIFLASH2_LAYOUT "" #endif +#if defined(STM32N6) +#define FLASH_LAYOUT_STR "@Internal Flash " MBOOT_SPIFLASH_LAYOUT MBOOT_SPIFLASH2_LAYOUT +#else + #if defined(STM32F4) \ || defined(STM32F722xx) \ || defined(STM32F723xx) \ @@ -584,12 +589,18 @@ static int mboot_flash_write(uint32_t addr, const uint8_t *src8, size_t len) { return 0; } +#endif + /******************************************************************************/ // Writable address space interface static int do_mass_erase(void) { + #if defined(STM32N6) + return -1; + #else // TODO spiflash erase ? return mboot_flash_mass_erase(); + #endif } #if defined(MBOOT_SPIFLASH_ADDR) || defined(MBOOT_SPIFLASH2_ADDR) @@ -625,7 +636,12 @@ int hw_page_erase(uint32_t addr, uint32_t *next_addr) { } else #endif { + #if defined(STM32N6) + dfu_context.status = DFU_STATUS_ERROR_ADDRESS; + dfu_context.error = MBOOT_ERROR_STR_INVALID_ADDRESS_IDX; + #else ret = mboot_flash_page_erase(addr, next_addr); + #endif } mboot_state_change(MBOOT_STATE_ERASE_END, ret); @@ -678,9 +694,12 @@ int hw_write(uint32_t addr, const uint8_t *src8, size_t len) { ret = mp_spiflash_write(MBOOT_SPIFLASH2_SPIFLASH, addr - MBOOT_SPIFLASH2_ADDR, len, src8); } else #endif + #if !defined(STM32N6) if (flash_is_valid_addr(addr)) { ret = mboot_flash_write(addr, src8, len); - } else { + } else + #endif + { dfu_context.status = DFU_STATUS_ERROR_ADDRESS; dfu_context.error = MBOOT_ERROR_STR_INVALID_ADDRESS_IDX; } @@ -1509,7 +1528,7 @@ void stm32_main(uint32_t initial_r0) { // Make sure IRQ vector table points to flash where this bootloader lives. SCB->VTOR = MBOOT_VTOR; - #if __CORTEX_M != 33 + #if __CORTEX_M != 33 && __CORTEX_M != 55 // Enable 8-byte stack alignment for IRQ handlers, in accord with EABI SCB->CCR |= SCB_CCR_STKALIGN_Msk; #endif @@ -1539,6 +1558,12 @@ void stm32_main(uint32_t initial_r0) { SCB_EnableDCache(); #endif + #if defined(STM32N6) + LL_PWR_EnableBkUpAccess(); + initial_r0 = TAMP_S->BKP31R; + TAMP_S->BKP31R = 0; + #endif + MBOOT_BOARD_EARLY_INIT(&initial_r0); #ifdef MBOOT_BOOTPIN_PIN @@ -1748,6 +1773,12 @@ void USB_DRD_FS_IRQHandler(void) { HAL_PCD_IRQHandler(&pcd_fs_handle); } +#elif defined(STM32N6) + +void USB1_OTG_HS_IRQHandler(void) { + HAL_PCD_IRQHandler(&pcd_hs_handle); +} + #elif defined(STM32WB) void USB_LP_IRQHandler(void) { diff --git a/ports/stm32/mboot/mphalport.h b/ports/stm32/mboot/mphalport.h index 45bf11d42..9cac0f70c 100644 --- a/ports/stm32/mboot/mphalport.h +++ b/ports/stm32/mboot/mphalport.h @@ -239,3 +239,20 @@ void mp_hal_pin_config_speed(uint32_t port_pin, uint32_t speed); #define pin_J13 (GPIOJ_BASE | 13) #define pin_J14 (GPIOJ_BASE | 14) #define pin_J15 (GPIOJ_BASE | 15) + +#define pin_N0 (GPION_BASE | 0) +#define pin_N1 (GPION_BASE | 1) +#define pin_N2 (GPION_BASE | 2) +#define pin_N3 (GPION_BASE | 3) +#define pin_N4 (GPION_BASE | 4) +#define pin_N5 (GPION_BASE | 5) +#define pin_N6 (GPION_BASE | 6) +#define pin_N7 (GPION_BASE | 7) +#define pin_N8 (GPION_BASE | 8) +#define pin_N9 (GPION_BASE | 9) +#define pin_N10 (GPION_BASE | 10) +#define pin_N11 (GPION_BASE | 11) +#define pin_N12 (GPION_BASE | 12) +#define pin_N13 (GPION_BASE | 13) +#define pin_N14 (GPION_BASE | 14) +#define pin_N15 (GPION_BASE | 15) diff --git a/ports/stm32/mboot/stm32_memory_n6.ld b/ports/stm32/mboot/stm32_memory_n6.ld new file mode 100644 index 000000000..bd2471dbf --- /dev/null +++ b/ports/stm32/mboot/stm32_memory_n6.ld @@ -0,0 +1,18 @@ +/* + Linker script fragment for mboot on an STM32N6xx MCU. + This defines the memory sections for the bootloader to use. + + On N6, the hardware bootloader loads the first 512k of external flash into + the upper part of SRAM2 AXI S, starting at 0x34180000. The first 1024 bytes + is a header. Then comes the actual code, starting with the vector table. +*/ + +MEMORY +{ + FLASH_BL (rx) : ORIGIN = 0x34180400, LENGTH = 31744 /* AXISRAM2_S */ + RAM (xrw) : ORIGIN = 0x341e0000, LENGTH = 128K /* AXISRAM2_S */ +} + +/* Location of protected flash area which must not be modified, because mboot lives there. */ +_mboot_protected_flash_start = ORIGIN(FLASH_BL); +_mboot_protected_flash_end_exclusive = ORIGIN(FLASH_BL) + LENGTH(FLASH_BL); diff --git a/ports/stm32/mboot/stm32_sections.ld b/ports/stm32/mboot/stm32_sections.ld index 43511f083..4a6fd44b2 100644 --- a/ports/stm32/mboot/stm32_sections.ld +++ b/ports/stm32/mboot/stm32_sections.ld @@ -33,6 +33,14 @@ SECTIONS _etext = .; } >FLASH_BL + /* Secure Gateway stubs */ + .gnu.sgstubs : + { + . = ALIGN(4); + *(.gnu.sgstubs*) + . = ALIGN(4); + } >FLASH_BL + /* used by the startup to initialize data */ _sidata = LOADADDR(.data); |
