[STM32H750] Working board definitions and some questions

Discussion and questions about boards that can run MicroPython but don't have a dedicated forum.
Target audience: Everyone interested in running MicroPython on other hardware.
jahr
Posts: 11
Joined: Fri Apr 02, 2021 1:20 pm

[STM32H750] Working board definitions and some questions

Post by jahr » Sun Sep 12, 2021 8:42 pm

Hello,

I own some STM32H750 MCU based boards and I've found that there is no working board definition available. So I decided to write one by myself. It was not an easy task but finaly I ended having two working boards ;) They are available here and here.
I'll describe main points for those who may want to use the definitions as a template. Perhaps someone finds it usefull.

1. MCU name

In the mpconfigboard.h I use

Code: Select all

#define MICROPY_HW_MCU_NAME         "STM32H750"
and in the mpconfigboard.mk

Code: Select all

CMSIS_MCU = STM32H750xx
I placed a pull request to allow that but in the meanwhile replace H750 with H743 in those files.

2. SPI and QSPI flash

SPI and QSPI definition sections I've compiled from PYBD_SF2 board definition and from WeActTC/MiniSTM32H7xx repository. It's necessary to have a block device configuration for both devices. File bdev.c with parts of these configurations is required.

3. Board early initialization

Because part of the firmware is placed in the extended QSPI memory, it is necessary to initialize that memory before starting Micropython. The early initialization code is run from board_init.c and an entry point for that is defined in mpconfigboard.h:

Code: Select all

#define MICROPY_BOARD_EARLY_INIT    board_early_init
void board_early_init(void);
4. Linker script

Regions, where the compiled code is placed, are defined in the linker script. At this point, I had the biggest problem. The code placed to the main chip memory must meet two basic conditions. The first is clear - it must fit 128kB area. The other is also clear but it took me two days to find it :D
The code in the main memory must contain at least all the code necessary to initialize the QSPI memory!
After many attempts and failures I managed to divide the code between memories using this terrible lookig section of the linker script (in stm32h750.ld):

Code: Select all

    /* Define the code that goes in QSPI flash */
    .text_ext :
    {
        . = ALIGN(4);
        /**drivers/*(.text* .rodata*)*/ /* necessary */
        *extmod/*(.text* .rodata*)
        *frozen_mpy/*(.text* .rodata*)
        *lib/libm_dbl/*(.text* .rodata*)
        *lib/oofatfs/*(.text* .rodata*)
        /**lib/stm32lib/CMSIS/*(.text* .rodata*)*/ /* necessary */
        *lib/stm32lib/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_a*(.text* .rodata*)
        /**lib/stm32lib/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_c*(.text* .rodata*)*/ /* stm32h7xx_hal_cortex is necessary */
        *lib/stm32lib/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_d*(.text* .rodata*)
        *lib/stm32lib/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_f*(.text* .rodata*)
        *lib/stm32lib/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_g*(.text* .rodata*)
        *lib/stm32lib/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_i*(.text* .rodata*)
        *lib/stm32lib/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_m*(.text* .rodata*)
        /**lib/stm32lib/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_p*(.text* .rodata*)*/ /* necessary */
        /**lib/stm32lib/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_r*(.text* .rodata*)*/ /* necessary */
        *lib/stm32lib/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_s*(.text* .rodata*)
        *lib/stm32lib/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_t*(.text* .rodata*)
        *lib/stm32lib/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_u*(.text* .rodata*)
        *lib/stm32lib/STM32H7xx_HAL_Driver/Src/stm32h7xx_ll_*(.text* .rodata*)
        *py/*(.text* .rodata*)
        *shared/*(.text* .rodata*)
        *usbdev/*(.text* .rodata*)
        . = ALIGN(4);
    } >FLASH_EXT
Uncommented lines specify parts which are placed to the QSPI memory, commented lines marked as "necessary" must be present in the main memory. However, these "necessary" parts usually contain more than one module, so there is still some space for further optimization ;)
Such optimization may be necessary for other firmware configurations. I did not divide the root folder of modules (it's the whole in the main memory), so there is a lot of space for another further optimization :D

And now some questions

1. Can anyone suggest the right value for

Code: Select all

#define MICROPY_HW_QSPI_PRESCALER       2
I've read an article from st.com, studied the MP code and went through some (many) code examples and found nothing clear. All possible values were used at least once somewhere, so I've chosen the value of 2 (looked good to me) but I'm not sure if it is optimal.

2. I really don't like how the above mentioned linker script's section looks like ;) Can someone suggest how it could be written better?

Thank you for your attention :)

jahr
Posts: 11
Joined: Fri Apr 02, 2021 1:20 pm

Re: [STM32H750] Working board definitions and some questions

Post by jahr » Mon Sep 13, 2021 7:17 am

I've forgotten to mention how the firmware is downloaded to the board. First I've tried to use mboot. It compiled, I've flashed it and it ran. But flashing DFU was not possible - there was an error clearing the main memory. So i've abandonned the idea to use mboot (if somebody knows how make it work, please send me an advice ;)).
I used STM32CubeProgrammer to flash it. Firmware0.bin is used in the usual way, for flashing firmware1.bin, it is necessary to use STM32H7xx_W25Q128_WeActStudio.stldr, which is available in the above mentioned repository WeActTC/MiniSTM32H7xx in folder SDK/QSPI_Flasher (instructions are also there).

JohnieBraaf
Posts: 9
Joined: Mon Jan 06, 2020 12:08 am

Re: [STM32H750] Working board definitions and some questions

Post by JohnieBraaf » Mon Sep 13, 2021 7:56 am

1. Can anyone suggest the right value for

Code: Select all

#define MICROPY_HW_QSPI_PRESCALER       2
Is this define even necesarry?

With regards to flashing, programming. If you use STM32Programmer it's easier to just use the hex or dfu file.
Otherwise you weed need to flash both .bin files manually to specific addresses.

jahr
Posts: 11
Joined: Fri Apr 02, 2021 1:20 pm

Re: [STM32H750] Working board definitions and some questions

Post by jahr » Mon Sep 13, 2021 8:24 am

JohnieBraaf wrote:
Mon Sep 13, 2021 7:56 am
Is this define even necesarry?
If I do not use the define, the value of 3 is used (see qspi.c in the stm32 port directory). Do you think that value is better?
JohnieBraaf wrote:
Mon Sep 13, 2021 7:56 am
With regards to flashing, programming. If you use STM32Programmer it's easier to just use the hex or dfu file.
Otherwise you weed need to flash both .bin files manually to specific addresses.
What do you mean with STM32Programmer? I'm using STM32CubeProgrammer and it doesn't support flashing DFU files and using BIN is easier for me than HEX. Does that STM32Programmer support flashing QSPI memory without external loader plugin?

Thank you

JohnieBraaf
Posts: 9
Joined: Mon Jan 06, 2020 12:08 am

Re: [STM32H750] Working board definitions and some questions

Post by JohnieBraaf » Mon Sep 13, 2021 8:50 am

I don't know the answer regarding your SPI question.

Indeed I meant STM32CubeProgrammer. Ok, if that works for you then it should be fine.
You could also create a .bat script for it that calls the STM32_Programmer_CLI.exe

Example:

Code: Select all

STM32_Programmer_CLI.exe -c port=SWD index=%BOARD_ID% reset=HWrst -e all
STM32_Programmer_CLI.exe -c port=SWD index=%BOARD_ID% reset=HWrst -el %STM32_EXT_FLASH_LOADER% -d %HEX_FILE% -v -HardRst

jahr
Posts: 11
Joined: Fri Apr 02, 2021 1:20 pm

Re: [STM32H750] Working board definitions and some questions

Post by jahr » Mon Sep 13, 2021 9:09 am

JohnieBraaf wrote:
Mon Sep 13, 2021 8:50 am
You could also create a .bat script for it that calls the STM32_Programmer_CLI.exe
It looks good, thanks :)

peter009
Posts: 1
Joined: Sat Nov 27, 2021 9:04 am
Contact:

Re: [STM32H750] Working board definitions and some questions

Post by peter009 » Sat Nov 27, 2021 9:07 am

jahr wrote:
Sun Sep 12, 2021 8:42 pm
Hello,

I own some STM32H750 MCU based boards and I've found that there is no working board definition available. So I decided to write one by myself. It was not an easy task but finaly I ended having two working boards ;) They are available here and here.
I'll describe main points for those who may want to use the definitions as a template. Perhaps someone finds it usefull.

1. MCU name

In the mpconfigboard.h I use

Code: Select all

#define MICROPY_HW_MCU_NAME         "STM32H750"
and in the mpconfigboard.mk

Code: Select all

CMSIS_MCU = STM32H750xx
I placed a pull request to allow that but in the meanwhile replace H750 with H743 in those files.

2. SPI and QSPI flash

SPI and QSPI definition sections I've compiled from PYBD_SF2 board definition and from WeActTC/MiniSTM32H7xx repository. It's necessary to have a block device configuration for both devices. File bdev.c with parts of these configurations is required.

3. Board early initialization

Because part of the firmware is placed in the extended QSPI memory, it is necessary to initialize that memory before starting Micropython. The early initialization code is run from board_init.c and an entry point for that is defined in mpconfigboard.h:

Code: Select all

#define MICROPY_BOARD_EARLY_INIT    board_early_init
void board_early_init(void);
4. Linker script GB WhatsApp


Regions, where the compiled code is placed, are defined in the linker script. At this point, I had the biggest problem. The code placed to the main chip memory must meet two basic conditions. The first is clear - it must fit 128kB area. The other is also clear but it took me two days to find it :D
The code in the main memory must contain at least all the code necessary to initialize the QSPI memory!
After many attempts and failures I managed to divide the code between memories using this terrible lookig section of the linker script (in stm32h750.ld):

Code: Select all

    /* Define the code that goes in QSPI flash */
    .text_ext :
    {
        . = ALIGN(4);
        /**drivers/*(.text* .rodata*)*/ /* necessary */
        *extmod/*(.text* .rodata*)
        *frozen_mpy/*(.text* .rodata*)
        *lib/libm_dbl/*(.text* .rodata*)
        *lib/oofatfs/*(.text* .rodata*)
        /**lib/stm32lib/CMSIS/*(.text* .rodata*)*/ /* necessary */
        *lib/stm32lib/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_a*(.text* .rodata*)
        /**lib/stm32lib/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_c*(.text* .rodata*)*/ /* stm32h7xx_hal_cortex is necessary */
        *lib/stm32lib/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_d*(.text* .rodata*)
        *lib/stm32lib/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_f*(.text* .rodata*)
        *lib/stm32lib/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_g*(.text* .rodata*)
        *lib/stm32lib/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_i*(.text* .rodata*)
        *lib/stm32lib/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_m*(.text* .rodata*)
        /**lib/stm32lib/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_p*(.text* .rodata*)*/ /* necessary */
        /**lib/stm32lib/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_r*(.text* .rodata*)*/ /* necessary */
        *lib/stm32lib/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_s*(.text* .rodata*)
        *lib/stm32lib/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_t*(.text* .rodata*)
        *lib/stm32lib/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_u*(.text* .rodata*)
        *lib/stm32lib/STM32H7xx_HAL_Driver/Src/stm32h7xx_ll_*(.text* .rodata*)
        *py/*(.text* .rodata*)
        *shared/*(.text* .rodata*)
        *usbdev/*(.text* .rodata*)
        . = ALIGN(4);
    } >FLASH_EXT
Uncommented lines specify parts which are placed to the QSPI memory, commented lines marked as "necessary" must be present in the main memory. However, these "necessary" parts usually contain more than one module, so there is still some space for further optimization ;)
Such optimization may be necessary for other firmware configurations. I did not divide the root folder of modules (it's the whole in the main memory), so there is a lot of space for another further optimization :D

And now some questions

1. Can anyone suggest the right value for

Code: Select all

#define MICROPY_HW_QSPI_PRESCALER       2
I've read an article from st.com, studied the MP code and went through some (many) code examples and found nothing clear. All possible values were used at least once somewhere, so I've chosen the value of 2 (looked good to me) but I'm not sure if it is optimal.

2. I really don't like how the above mentioned linker script's section looks like ;) Can someone suggest how it could be written better?

Thank you for your attention :)
It looks good..Thanks..

User avatar
SunWukong
Posts: 11
Joined: Thu Jan 16, 2020 2:22 pm
Contact:

Re: [STM32H750] Working board definitions and some questions

Post by SunWukong » Thu Dec 09, 2021 11:44 pm

The build has worked well so far with these board definitions.

Code: Select all

LINK build-WEACT_H750/firmware.elf
   text    data     bss     dec     hex filename
 384144      24   32352  416520   65b08 build-WEACT_H750/firmware.elf
INFO: this build places firmware in external QSPI flash
GEN build-WEACT_H750/firmware0.bin
GEN build-WEACT_H750/firmware1.bin
GEN build-WEACT_H750/firmware.dfu
Unfortunately, I could not successfully flash the firmware afterwards.

Code: Select all

make BOARD=WEACT_H750 deploy
Writing build-WEACT_H750/firmware.dfu to the board
Traceback (most recent call last):
  File "/home/mike/micropython/ports/stm32/../../tools/pydfu.py", line 22, in <module>
    import usb.core
ModuleNotFoundError: No module named 'usb'
make: *** [Makefile:665: deploy] Fehler 1
I then transferred the firmware0.bin and firmware1.bin files to a PC with Windows on which the STM32CubeProgrammer is installed. firmware0.bin could be flashed without any problems. With firmware1.bin I found out that the STM32CubeProgrammer cannot handle the installed external QSPI Flash (W25Q64 ) by default. I then found what I was looking for in the ST Community Forum.
STM32CubeIDE STM32H750VB QSPI External loader Problem
After I had copied this helper programm into a directory that seemed suitable to me, I was able to select the W25Q64 chip and theoretically flash it, but in the end there were unfortunately error messages.

Code: Select all

C:\Program Files\STMicroelectronics\STM32Cube\STM32CubeProgrammer\bin\ExternalLoader

Code: Select all

00:00:44 : STM32CubeProgrammer API v2.1.0
00:00:48 : USB speed : Full Speed (12MBit/s)
00:00:48 : Manuf. ID : STMicroelectronics
00:00:48 : Product ID : DFU in FS Mode
00:00:48 : SN : 200364500000
00:00:48 : FW version : 0x011a
00:00:48 : Device ID : 0x0450
00:00:48 : UPLOADING OPTION BYTES DATA ...
00:00:48 : Bank : 0x00
00:00:48 : Address : 0x5200201c
00:00:48 : Size : 308 Bytes
00:00:48 : UPLOADING ...
00:00:48 : Size : 1024 Bytes
00:00:48 : Address : 0x8000000
00:00:48 : Read progress:
00:00:48 : Data read successfully
00:00:48 : Time elapsed during the read operation is: 00:00:00.007
00:02:09 : Memory Programming ...
00:02:09 : Opening and parsing file: firmware1.bin
00:02:09 : File : firmware1.bin
00:02:09 : Size : 267312 Bytes
00:02:09 : Address : 0x90000000
00:02:09 : Erasing memory corresponding to segment 0:
00:02:09 : Not flash Memory : No erase done
00:02:09 : Download in Progress:
00:02:14 : Error: failed to download Segment[0]
00:02:14 : Error: failed to download the File
00:02:14 : Time elapsed during download operation: 00:00:04.734
00:02:14 : Verifying ...
00:02:14 : Read progress:
00:02:19 : Error: Failed to read memory at address 0x90000000 during verification
00:02:19 : Error: Download verification failed
00:02:19 : RUNNING Program ...
00:02:19 : Address: : 0x90000000
00:02:24 : Error: Start operation failed
Now I am at a loss, but tomorrow, no today, I will search the net and maybe I will find out what I am doing wrong.

User avatar
SunWukong
Posts: 11
Joined: Thu Jan 16, 2020 2:22 pm
Contact:

Re: [STM32H750] Working board definitions and some questions

Post by SunWukong » Fri Dec 10, 2021 12:23 am

I have now tried to flash the firmware.elf, but that also failed.

Code: Select all

01:14:10 : STM32CubeProgrammer API v2.1.0
01:14:34 : USB speed : Full Speed (12MBit/s)
01:14:34 : Manuf. ID : STMicroelectronics
01:14:34 : Product ID : DFU in FS Mode
01:14:34 : SN : 200364500000
01:14:34 : FW version : 0x011a
01:14:34 : Device ID : 0x0450
01:14:34 : UPLOADING OPTION BYTES DATA ...
01:14:34 : Bank : 0x00
01:14:34 : Address : 0x5200201c
01:14:34 : Size : 308 Bytes
01:14:35 : UPLOADING ...
01:14:35 : Size : 1024 Bytes
01:14:35 : Address : 0x8000000
01:14:35 : Read progress:
01:14:35 : Data read successfully
01:14:35 : Time elapsed during the read operation is: 00:00:00.006
01:16:50 : Read File: T:\Entwicklung\STMicroelectronics\MicroPython\Firmware\Mini STM32H750\firmware.elf
01:16:50 : Number of segments: 2
01:16:50 : segment[0]: address= 0x8000000, size= 0x1C878
01:16:50 : segment[1]: address= 0x90000000, size= 0x41430
01:17:22 : Memory Programming ...
01:17:22 : Opening and parsing file: firmware1.bin
01:17:23 : File : firmware1.bin
01:17:23 : Size : 267312 Bytes
01:17:23 : Address : 0x08000000
01:17:23 : Erasing memory corresponding to segment 0:
01:17:23 : Erasing internal memory sectors [0 2]
01:17:25 : Download in Progress:
01:17:27 : File download complete
01:17:28 : Time elapsed during download operation: 00:00:04.996
01:17:28 : Verifying ...
01:17:28 : Read progress:
01:17:29 : Download verified successfully
01:17:29 : RUNNING Program ...
01:17:29 : Address: : 0x08000000
01:17:29 : Error: Start operation failed
01:17:29 : Warning: Connection to device 0x450 is lost

jahr
Posts: 11
Joined: Fri Apr 02, 2021 1:20 pm

Re: [STM32H750] Working board definitions and some questions

Post by jahr » Fri Dec 10, 2021 8:59 am

Hello SunWukong, try to flash firmware1.bin using the instructions on the page https://github.com/WeActTC/MiniSTM32H7x ... PI_Flasher. It worked well for me ;)

Post Reply