mirror of
https://github.com/micropython/micropython.git
synced 2025-07-21 13:01:10 +02:00
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>
This commit is contained in:
@@ -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
|
||||
|
||||
|
@@ -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
|
||||
|
@@ -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) {
|
||||
|
@@ -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)
|
||||
|
18
ports/stm32/mboot/stm32_memory_n6.ld
Normal file
18
ports/stm32/mboot/stm32_memory_n6.ld
Normal file
@@ -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);
|
@@ -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);
|
||||
|
||||
|
Reference in New Issue
Block a user