-
-
Notifications
You must be signed in to change notification settings - Fork 8.2k
WIP: stm32: Add support for STM32N6xx MCUs and three N6 boards #17171
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
Code size report:
|
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## master #17171 +/- ##
=======================================
Coverage 98.54% 98.54%
=======================================
Files 169 169
Lines 21898 21898
=======================================
Hits 21579 21579
Misses 319 319 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
// TODO: if (HAL_PWREx_ConfigSupply(PWR_EXTERNAL_SOURCE_SUPPLY ) != HAL_OK) | ||
//xspi_flash_init(); | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
#define OMV_BOOT_MAGIC_ADDR (0x3401FFFCU) | |
#define OMV_BOOT_MAGIC_VALUE (0xB00710ADU) | |
void board_enter_bootloader(void) { | |
*((uint32_t *) OMV_BOOT_MAGIC_ADDR) = OMV_BOOT_MAGIC_VALUE; | |
SCB_CleanDCache(); | |
NVIC_SystemReset(); | |
} |
To enter our bootloader.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you want to have the OPENMV_N6 board definition included in MicroPython's stm32 port (like with the OPENMV_AE3)? If so, it should work with mboot. But probably also a good idea to work with the OpenMV bootloader, which means adding this code.
Related: how did you choose address 0x3401FFFC? That's part way through SRAM1, in the FLEXRAM area. You'd need to make sure that isn't cleared on reset like the rest of SRAM1/2, and also make sure it's not overwritten by the bootloader.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you want to have the OPENMV_N6 board definition included in MicroPython's stm32 port (like with the OPENMV_AE3)? If so, it should work with mboot. But probably also a good idea to work with the OpenMV bootloader, which means adding this code.
Either way is fine with me. If mboot support is kept, I can always use MP_CONFIGFILE
to override and not build mboot when building our firmware.
Related: how did you choose address 0x3401FFFC? That's part way through SRAM1, in the FLEXRAM area. You'd need to make sure that isn't cleared on reset like the rest of SRAM1/2, and also make sure it's not overwritten by the bootloader.
Good point. The bootloader uses the 128K (or 64K) DTCM for its memory (heap, stack etc..), so this address is typically 0x2001FFFCU
(last word of bootloader's memory) and it's the same for almost all boards. However, for some reason, this doesn't work on the N6, so I just used SRAM1. Note that SRAM1 and SRAM2 don't seem to get erased on reset, otherwise this wouldn't work, but it would still be better to use DTCM for this, but it's not working.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh I think I just needed a DSB, seems the write might be buffered. The following works too:
#define OMV_BOOT_MAGIC_ADDR (0x3001FFFCU)
#define OMV_BOOT_MAGIC_VALUE (0xB00710ADU)
void board_enter_bootloader(void) {
*((uint32_t *) OMV_BOOT_MAGIC_ADDR) = OMV_BOOT_MAGIC_VALUE;
__DSB();
NVIC_SystemReset();
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@dpgeorge There seems to be some issue with DTCM, I can't access any address above ~0x1000. This causes a fault on boot when it tries accesses the magic number address (oddly enough, it doesn't always happen). Perhaps it has something to do with security config, flexram, clocks or something else that gets enabled by the main firmware, but even from the main firmware I still can't access this memory from gdb. Anyway let's please keep the original boot address (with cache clean).
562ed7c
to
6cb319e
Compare
MICROPY_PY_NETWORK_CYW43 = 1 | ||
MICROPY_PY_SSL = 1 | ||
MICROPY_SSL_MBEDTLS = 1 | ||
MICROPY_VFS_LFS2 = 1 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I need to be able to disable mboot USE_MBOOT ?= 1
and also we never use LFS2, just fat.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've made all these options use ?=
.
But note that the way it's configured you'll probably want to enable USE_MBOOT
because that puts the firmware in external flash. Otherwise MicroPython runs from RAM.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there any way to build a flash-based image just without mboot? Like an option to do so, that gets forced to one if mboot is enabled, otherwise is user-defined?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think that's just USE_MBOOT=1
. I guess it should be called USE_BOOTLOADER=1
but for consistency it's the mboot option.
That option is anyway local to the board (nothing outside the board uses this config option, except mboot itself). The option controls:
- which ld scripts to use
- location of
.text
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But what if you don't want to build mboot, yet still want a flash-based image? Can USE_MBOOT=1
define something like MICROPY_FLASH_BASED=1
? For example:
USE_MBOOT ?= 1
MICROPY_FLASH_BASED ?= $(USE_MBOOT)
This way I can define USE_MBOOT=0 MICROPY_FLASH_BASED=1
to get a flash-based image without mboot.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Mboot is not built unless you explicitly do make
in the ports/stm32/mboot
directory.
But, I can do what you suggest, it makes sense.
#define MICROPY_HW_ENABLE_RNG (0) | ||
#define MICROPY_HW_ENABLE_RTC (0) | ||
#define MICROPY_HW_ENABLE_RTC (1) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For our bootloader, we need the following:
#define MICROPY_HW_ENTER_BOOTLOADER_VIA_RESET (0)
extern void board_early_init(void);
#define MICROPY_BOARD_EARLY_INIT board_early_init
extern void board_enter_bootloader(void);
#define MICROPY_BOARD_ENTER_BOOTLOADER(nargs, args) board_enter_bootloader()
With the following code in board.c
(which could be gated if mboot is enabled):
#include STM32_HAL_H
#include "py/mphal.h"
#define OMV_BOOT_MAGIC_ADDR (0x3401FFFCU)
#define OMV_BOOT_MAGIC_VALUE (0xB00710ADU)
void board_early_init(void) {
}
void board_enter_bootloader(void) {
*((uint32_t *) OMV_BOOT_MAGIC_ADDR) = OMV_BOOT_MAGIC_VALUE;
SCB_CleanDCache();
NVIC_SystemReset();
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've now made the board work with both the OpenMV bootloader and mboot.
LL_AHB5_GRP1_EnableClockLowPower(LL_AHB5_GRP1_PERIPH_OTGPHY1); | ||
|
||
// Select 24MHz clock. | ||
MODIFY_REG(USB1_HS_PHYC->USBPHYC_CR, USB_USBPHYC_CR_FSEL, 2 << USB_USBPHYC_CR_FSEL_Pos); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's a proper init sequence for this in the examples in the HAL, if you want to take a look. I think it's more or less the same, but there were some delays, more force_reset/release etc...
Also, could you please add this? I use it in HS mode.
diff --git a/ports/stm32/usbdev/class/inc/usbd_cdc_msc_hid.h b/ports/stm32/usbdev/class/inc/usbd_cdc_msc_hid.h
index 3a87896b4..5906f95e0 100644
--- a/ports/stm32/usbdev/class/inc/usbd_cdc_msc_hid.h
+++ b/ports/stm32/usbdev/class/inc/usbd_cdc_msc_hid.h
@@ -11,7 +11,7 @@
// Work out if we should support USB high-speed device mode
#if MICROPY_HW_USB_HS \
- && (!MICROPY_HW_USB_HS_IN_FS || defined(STM32F723xx) || defined(STM32F733xx))
+ && (!MICROPY_HW_USB_HS_IN_FS || defined(STM32F723xx) || defined(STM32F733xx) || defined(STM32N6))
#define USBD_SUPPORT_HS_MODE (1)
#else
#define USBD_SUPPORT_HS_MODE (0)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've added the USBD_SUPPORT_HS_MODE
option as above.
But testing it with #15909 shows that there is data corruption when HS is enabled. That needs investigation.
43eb2ba
to
653f480
Compare
32f5690
to
5fb6eff
Compare
The N6 is missing from the FPU filter list in |
75dc026
to
5522b3b
Compare
OK, now fixed. |
5522b3b
to
dbb5086
Compare
Signed-off-by: Damien George <damien@micropython.org>
That's almost the same as FLT_EVAL_METHOD == 0, but indicates the presence of _Float16_t support. Signed-off-by: Damien George <damien@micropython.org>
Changes in this new library version are: - Add N6 HAL at v1.1.0. Signed-off-by: Damien George <damien@micropython.org>
Signed-off-by: Damien George <damien@micropython.org>
Signed-off-by: Damien George <damien@micropython.org>
See ST Errata ES0620 - Rev 0.2 section 2.1.2. Signed-off-by: iabdalkader <i.abdalkader@gmail.com>
Signed-off-by: Damien George <damien@micropython.org>
Signed-off-by: Damien George <damien@micropython.org>
Signed-off-by: Damien George <damien@micropython.org>
Signed-off-by: Damien George <damien@micropython.org>
Signed-off-by: Damien George <damien@micropython.org>
Signed-off-by: Damien George <damien@micropython.org>
Signed-off-by: Damien George <damien@micropython.org>
dbb5086
to
5c6c893
Compare
I finally got the filesystem working. Needed to make sure all relevant code and data structures to erase/write SPI flash is in RAM, and that interrupts are fully disabled during erase/write (obvious but tricky to do). |
Summary
This PR adds preliminary support for ST's new STM32N6xx MCUs.
Supported features of this MCU so far are:
machine.Pin
machine.UART
Supported boards:
Note that the N6 does not have internal flash, and has some tricky boot sequence, so using a custom bootloader (mboot) is almost a necessity.
The ST CMSIS and HAL files are added verbatim here, but will eventually be moved intoEdit: N6 CMSIS and HAL files are now instm32lib
.stm32lib
.OpenMV have generously sponsored the development of this port.
Testing
This PR has been tested on the three N6 boards that are added here.