summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDamien George <damien@micropython.org>2024-09-10 00:02:18 +1000
committerDamien George <damien@micropython.org>2025-07-08 16:25:14 +1000
commitacb294f61af3bd214cc95a4881722754624b912d (patch)
tree75bf2334674de7b522d90d707ac650a599ec4ad3
parent96b8f3aebcc7abc67f15c912286d0cba64589de1 (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-xports/stm32/mboot/Makefile40
-rw-r--r--ports/stm32/mboot/adc.c2
-rw-r--r--ports/stm32/mboot/main.c37
-rw-r--r--ports/stm32/mboot/mphalport.h17
-rw-r--r--ports/stm32/mboot/stm32_memory_n6.ld18
-rw-r--r--ports/stm32/mboot/stm32_sections.ld8
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);