Skip to content

Commit acb294f

Browse files
committed
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 <[email protected]>
1 parent 96b8f3a commit acb294f

File tree

6 files changed

+112
-10
lines changed

6 files changed

+112
-10
lines changed

ports/stm32/mboot/Makefile

Lines changed: 33 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,13 @@ include ../../../py/mkenv.mk
3434
include $(BOARD_DIR)/mpconfigboard.mk
3535

3636
# A board can set MBOOT_TEXT0_ADDR to a custom location where mboot should reside.
37+
ifeq ($(MCU_SERIES),n6)
38+
MBOOT_TEXT0_ADDR ?= 0x34180400
39+
MBOOT_LD_FILES ?= stm32_memory_n6.ld stm32_sections.ld
40+
else
3741
MBOOT_TEXT0_ADDR ?= 0x08000000
42+
MBOOT_LD_FILES ?= stm32_memory.ld stm32_sections.ld
43+
endif
3844

3945
# The string in MBOOT_VERSION (default defined in version.c if not defined by a
4046
# board) will be stored in the final MBOOT_VERSION_ALLOCATED_BYTES bytes of mboot flash.
@@ -89,7 +95,6 @@ CFLAGS += -DMBOOT_VERSION=\"$(MBOOT_VERSION)\"
8995
endif
9096
CFLAGS += -DMBOOT_VERSION_ALLOCATED_BYTES=$(MBOOT_VERSION_ALLOCATED_BYTES) -DMBOOT_VERSION_INCLUDE_OPTIONS=$(MBOOT_VERSION_INCLUDE_OPTIONS)
9197

92-
MBOOT_LD_FILES ?= stm32_memory.ld stm32_sections.ld
9398
LDFLAGS += -nostdlib -L . $(addprefix -T,$(MBOOT_LD_FILES)) -Map=$(@:.elf=.map) --cref
9499
LDFLAGS += --defsym mboot_version_len=$(MBOOT_VERSION_ALLOCATED_BYTES)
95100
LIBS += $(shell $(CC) $(CFLAGS) -print-libgcc-file-name)
@@ -137,12 +142,11 @@ SRC_C += \
137142
drivers/bus/softqspi.c \
138143
drivers/memory/spiflash.c \
139144
ports/stm32/flash.c \
140-
ports/stm32/flashbdev.c \
141145
ports/stm32/i2cslave.c \
142146
ports/stm32/powerctrlboot.c \
143147
ports/stm32/qspi.c \
144-
ports/stm32/spibdev.c \
145148
ports/stm32/usbd_conf.c \
149+
ports/stm32/xspi.c \
146150
$(wildcard $(BOARD_DIR)/*.c)
147151

148152
SRC_O += \
@@ -169,16 +173,22 @@ SRC_HAL += $(addprefix $(STM32LIB_HAL_BASE)/Src/stm32$(MCU_SERIES)xx_,\
169173
hal.c \
170174
hal_cortex.c \
171175
hal_dma.c \
172-
hal_flash.c \
173-
hal_flash_ex.c \
174176
hal_pcd.c \
175177
hal_pcd_ex.c \
176178
hal_pwr_ex.c \
177179
hal_rcc.c \
178180
hal_rcc_ex.c \
181+
ll_rcc.c \
179182
ll_usb.c \
180183
)
181184

185+
ifneq ($(MCU_SERIES),n6)
186+
SRC_HAL += $(addprefix $(STM32LIB_HAL_BASE)/Src/stm32$(MCU_SERIES)xx_,\
187+
hal_flash.c \
188+
hal_flash_ex.c \
189+
)
190+
endif
191+
182192
ifeq ($(MCU_SERIES),$(filter $(MCU_SERIES),f4 f7 h7))
183193
SRC_HAL += $(addprefix $(STM32LIB_HAL_BASE)/Src/stm32$(MCU_SERIES)xx_,\
184194
hal_mmc.c \
@@ -187,6 +197,12 @@ SRC_HAL += $(addprefix $(STM32LIB_HAL_BASE)/Src/stm32$(MCU_SERIES)xx_,\
187197
)
188198
endif
189199

200+
ifeq ($(MCU_SERIES),n6)
201+
SRC_HAL += $(addprefix $(STM32LIB_HAL_BASE)/Src/stm32$(MCU_SERIES)xx_,\
202+
hal_bsec.c \
203+
)
204+
endif
205+
190206
SRC_USBDEV += $(addprefix ports/stm32/$(USBDEV_DIR)/,\
191207
core/src/usbd_core.c \
192208
core/src/usbd_ctlreq.c \
@@ -206,7 +222,7 @@ $(TOP)/lib/stm32lib/README.md:
206222
$(ECHO) "stm32lib submodule not found, fetching it now..."
207223
(cd $(TOP) && git submodule update --init lib/stm32lib)
208224

209-
.PHONY: deploy deploy-stlink
225+
.PHONY: deploy deploy-stlink deploy-trusted
210226

211227
deploy: $(BUILD)/firmware.dfu
212228
$(ECHO) "Writing $< to the board"
@@ -216,9 +232,15 @@ deploy-stlink: $(BUILD)/firmware.dfu
216232
$(ECHO) "Writing $< to the board via ST-LINK"
217233
$(Q)$(STFLASH) write $(BUILD)/firmware.bin $(MBOOT_TEXT0_ADDR)
218234

219-
$(BUILD)/firmware.dfu: $(BUILD)/firmware.elf
235+
deploy-trusted: $(BUILD)/firmware-trusted.bin
236+
$(STM32_CUBE_PROGRAMMER)/bin/STM32_Programmer.sh -c port=SWD mode=HOTPLUG ap=1 -el $(DKEL) -w $^ 0x70000000 -hardRst
237+
238+
$(BUILD)/firmware.bin: $(BUILD)/firmware.elf
220239
$(ECHO) "Create $@"
221240
$(Q)$(OBJCOPY) -O binary -j .isr_vector -j .text -j .data -j .mboot_version_text $^ $(BUILD)/firmware.bin
241+
242+
$(BUILD)/firmware.dfu: $(BUILD)/firmware.bin
243+
$(ECHO) "Create $@"
222244
$(Q)$(PYTHON) $(DFU) -b $(MBOOT_TEXT0_ADDR):$(BUILD)/firmware.bin $@
223245

224246
$(BUILD)/firmware.hex: $(BUILD)/firmware.elf
@@ -230,6 +252,10 @@ $(BUILD)/firmware.elf: $(OBJ)
230252
$(Q)$(LD) $(LDFLAGS) -o $@ $^ $(LIBS)
231253
$(Q)$(SIZE) $@
232254

255+
$(BUILD)/firmware-trusted.bin: $(BUILD)/firmware.bin
256+
/bin/rm -f $@
257+
$(STM32_CUBE_PROGRAMMER)/bin/STM32_SigningTool_CLI -bin $^ -nk -of 0x80000000 -t fsbl -o $@ -hv $(STM32_N6_HEADER_VERSION)
258+
233259
#########################################
234260
# Rules to generate header files
235261

ports/stm32/mboot/adc.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
11
// Include the main ADC driver, so mboot can use adc_config() and adc_config_and_read_u16().
22
#include "py/obj.h"
3+
#if MICROPY_PY_MACHINE_ADC
34
#include "../machine_adc.c"
5+
#endif

ports/stm32/mboot/main.c

Lines changed: 34 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
#include "sdcard.h"
4242
#include "dfu.h"
4343
#include "pack.h"
44+
#include "xspi.h"
4445

4546
// Whether the bootloader will leave via reset, or direct jump to the application.
4647
#ifndef MBOOT_LEAVE_BOOTLOADER_VIA_RESET
@@ -373,7 +374,7 @@ void SystemClock_Config(void) {
373374
#elif defined(STM32G0)
374375
#define AHBxENR IOPENR
375376
#define AHBxENR_GPIOAEN_Pos RCC_IOPENR_GPIOAEN_Pos
376-
#elif defined(STM32H7)
377+
#elif defined(STM32H7) || defined(STM32N6)
377378
#define AHBxENR AHB4ENR
378379
#define AHBxENR_GPIOAEN_Pos RCC_AHB4ENR_GPIOAEN_Pos
379380
#elif defined(STM32H5) || defined(STM32WB)
@@ -424,6 +425,10 @@ void mp_hal_pin_config_speed(uint32_t port_pin, uint32_t speed) {
424425
#define MBOOT_SPIFLASH2_LAYOUT ""
425426
#endif
426427

428+
#if defined(STM32N6)
429+
#define FLASH_LAYOUT_STR "@Internal Flash " MBOOT_SPIFLASH_LAYOUT MBOOT_SPIFLASH2_LAYOUT
430+
#else
431+
427432
#if defined(STM32F4) \
428433
|| defined(STM32F722xx) \
429434
|| defined(STM32F723xx) \
@@ -584,12 +589,18 @@ static int mboot_flash_write(uint32_t addr, const uint8_t *src8, size_t len) {
584589
return 0;
585590
}
586591

592+
#endif
593+
587594
/******************************************************************************/
588595
// Writable address space interface
589596

590597
static int do_mass_erase(void) {
598+
#if defined(STM32N6)
599+
return -1;
600+
#else
591601
// TODO spiflash erase ?
592602
return mboot_flash_mass_erase();
603+
#endif
593604
}
594605

595606
#if defined(MBOOT_SPIFLASH_ADDR) || defined(MBOOT_SPIFLASH2_ADDR)
@@ -625,7 +636,12 @@ int hw_page_erase(uint32_t addr, uint32_t *next_addr) {
625636
} else
626637
#endif
627638
{
639+
#if defined(STM32N6)
640+
dfu_context.status = DFU_STATUS_ERROR_ADDRESS;
641+
dfu_context.error = MBOOT_ERROR_STR_INVALID_ADDRESS_IDX;
642+
#else
628643
ret = mboot_flash_page_erase(addr, next_addr);
644+
#endif
629645
}
630646

631647
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) {
678694
ret = mp_spiflash_write(MBOOT_SPIFLASH2_SPIFLASH, addr - MBOOT_SPIFLASH2_ADDR, len, src8);
679695
} else
680696
#endif
697+
#if !defined(STM32N6)
681698
if (flash_is_valid_addr(addr)) {
682699
ret = mboot_flash_write(addr, src8, len);
683-
} else {
700+
} else
701+
#endif
702+
{
684703
dfu_context.status = DFU_STATUS_ERROR_ADDRESS;
685704
dfu_context.error = MBOOT_ERROR_STR_INVALID_ADDRESS_IDX;
686705
}
@@ -1509,7 +1528,7 @@ void stm32_main(uint32_t initial_r0) {
15091528
// Make sure IRQ vector table points to flash where this bootloader lives.
15101529
SCB->VTOR = MBOOT_VTOR;
15111530

1512-
#if __CORTEX_M != 33
1531+
#if __CORTEX_M != 33 && __CORTEX_M != 55
15131532
// Enable 8-byte stack alignment for IRQ handlers, in accord with EABI
15141533
SCB->CCR |= SCB_CCR_STKALIGN_Msk;
15151534
#endif
@@ -1539,6 +1558,12 @@ void stm32_main(uint32_t initial_r0) {
15391558
SCB_EnableDCache();
15401559
#endif
15411560

1561+
#if defined(STM32N6)
1562+
LL_PWR_EnableBkUpAccess();
1563+
initial_r0 = TAMP_S->BKP31R;
1564+
TAMP_S->BKP31R = 0;
1565+
#endif
1566+
15421567
MBOOT_BOARD_EARLY_INIT(&initial_r0);
15431568

15441569
#ifdef MBOOT_BOOTPIN_PIN
@@ -1748,6 +1773,12 @@ void USB_DRD_FS_IRQHandler(void) {
17481773
HAL_PCD_IRQHandler(&pcd_fs_handle);
17491774
}
17501775

1776+
#elif defined(STM32N6)
1777+
1778+
void USB1_OTG_HS_IRQHandler(void) {
1779+
HAL_PCD_IRQHandler(&pcd_hs_handle);
1780+
}
1781+
17511782
#elif defined(STM32WB)
17521783

17531784
void USB_LP_IRQHandler(void) {

ports/stm32/mboot/mphalport.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -239,3 +239,20 @@ void mp_hal_pin_config_speed(uint32_t port_pin, uint32_t speed);
239239
#define pin_J13 (GPIOJ_BASE | 13)
240240
#define pin_J14 (GPIOJ_BASE | 14)
241241
#define pin_J15 (GPIOJ_BASE | 15)
242+
243+
#define pin_N0 (GPION_BASE | 0)
244+
#define pin_N1 (GPION_BASE | 1)
245+
#define pin_N2 (GPION_BASE | 2)
246+
#define pin_N3 (GPION_BASE | 3)
247+
#define pin_N4 (GPION_BASE | 4)
248+
#define pin_N5 (GPION_BASE | 5)
249+
#define pin_N6 (GPION_BASE | 6)
250+
#define pin_N7 (GPION_BASE | 7)
251+
#define pin_N8 (GPION_BASE | 8)
252+
#define pin_N9 (GPION_BASE | 9)
253+
#define pin_N10 (GPION_BASE | 10)
254+
#define pin_N11 (GPION_BASE | 11)
255+
#define pin_N12 (GPION_BASE | 12)
256+
#define pin_N13 (GPION_BASE | 13)
257+
#define pin_N14 (GPION_BASE | 14)
258+
#define pin_N15 (GPION_BASE | 15)

ports/stm32/mboot/stm32_memory_n6.ld

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
/*
2+
Linker script fragment for mboot on an STM32N6xx MCU.
3+
This defines the memory sections for the bootloader to use.
4+
5+
On N6, the hardware bootloader loads the first 512k of external flash into
6+
the upper part of SRAM2 AXI S, starting at 0x34180000. The first 1024 bytes
7+
is a header. Then comes the actual code, starting with the vector table.
8+
*/
9+
10+
MEMORY
11+
{
12+
FLASH_BL (rx) : ORIGIN = 0x34180400, LENGTH = 31744 /* AXISRAM2_S */
13+
RAM (xrw) : ORIGIN = 0x341e0000, LENGTH = 128K /* AXISRAM2_S */
14+
}
15+
16+
/* Location of protected flash area which must not be modified, because mboot lives there. */
17+
_mboot_protected_flash_start = ORIGIN(FLASH_BL);
18+
_mboot_protected_flash_end_exclusive = ORIGIN(FLASH_BL) + LENGTH(FLASH_BL);

ports/stm32/mboot/stm32_sections.ld

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,14 @@ SECTIONS
3333
_etext = .;
3434
} >FLASH_BL
3535

36+
/* Secure Gateway stubs */
37+
.gnu.sgstubs :
38+
{
39+
. = ALIGN(4);
40+
*(.gnu.sgstubs*)
41+
. = ALIGN(4);
42+
} >FLASH_BL
43+
3644
/* used by the startup to initialize data */
3745
_sidata = LOADADDR(.data);
3846

0 commit comments

Comments
 (0)