florisla / stm32loader

Flash firmware to STM32 microcontrollers using Python.
GNU General Public License v3.0
109 stars 53 forks source link

How to program an STM32H750? #67

Closed zapta closed 12 months ago

zapta commented 1 year ago

TL;DR, what -f (family) value to use with STM32H750 ?

When I program an STM32H750 I am getting a message that -f family is missing and that chip id 0x450 is unknown. When I add -f H7 I am getting an error. What -f value should I use?

Programming without the -f flag

$ stm32loader -p COM7 -e -w -v ../../controller/platformio/release/firmware.bin
Bootloader activation timeout -- retrying
Bootloader version: 0x31
Chip id: 0x450 (Unknown)           // < ----
Supply -f [family] to see flash size and device UID, e.g: -f F1     // <-----
Write 291 chunks at address 0x8000000...
Read 291 chunks at address 0x8000000...
Activating bootloader (select UART)
Extended erase (0x44)

Programming with the -f H7 flag:

$ stm32loader -p COM7 -f H7 -e -w -v ../../controller/platformio/release/firmware.bin
Bootloader activation timeout -- retrying
Bootloader version: 0x31
Chip id: 0x450 (Unknown)
Traceback (most recent call last):
  File "<frozen runpy>", line 198, in _run_module_as_main
  File "<frozen runpy>", line 88, in _run_code
  File "C:\Users\user\AppData\Local\Programs\Python\Python312\Scripts\stm32loader.exe\__main__.py", line 7, in <module>
  File "C:\Users\user\AppData\Local\Programs\Python\Python312\Lib\site-packages\stm32loader\__main__.py", line 37, in main
    stm32loader_main(*sys.argv[1:])
  File "C:\Users\user\AppData\Local\Programs\Python\Python312\Lib\site-packages\stm32loader\main.py", line 348, in main
    loader.read_device_uid()
  File "C:\Users\user\AppData\Local\Programs\Python\Python312\Lib\site-packages\stm32loader\main.py", line 272, in read_device_uid
    flash_size = self.stm32.get_flash_size(family)
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\user\AppData\Local\Programs\Python\Python312\Lib\site-packages\stm32loader\bootloader.py", line 388, in get_flash_size
    flash_size_address = self.FLASH_SIZE_ADDRESS[device_family]
                         ~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^
KeyError: 'H7'
Activating bootloader (select UART)
florisla commented 1 year ago

-f H7 should be right; known families are F0, F1, F3, F4, F7, H7, L4, L0, G0.

Chip ID 0x450 should be known, since the code contains this: 0x450: "STM32H76xxx/77xxx".

The problem is, the default release of stm32loader on PyPI is too old. It is 0.5.1 while you need 0.6.x .

I can add 0.6.0 if you're prepared to test it out?

florisla commented 1 year ago

Hi, version 0.6.0 is released. Can you give it a try?

florisla commented 1 year ago

You're also welcome to test out the test version of 0.7.0 from here: https://test.pypi.org/project/stm32loader/0.7.0.dev0/#files

zapta commented 1 year ago

Thanks @florisla.

I upgraded to

stm32loader 0.6.0
Python 3.12.0

Programming without -f does. The chip id is now known and the missing -f warning is printed (good).

$ stm32loader -p COM7  -e -w -v ../../controller/platformio/.pio/build/my_env/firmware.bin
Bootloader activation timeout -- retrying
Bootloader version: 0x31
Chip id: 0x450 (STM32H76xxx/77xxx)
Supply -f [family] to see flash size and device UID, e.g: -f F1
Write 291 chunks at address 0x8000000...
Read 291 chunks at address 0x8000000...
Activating bootloader (select UART)
Extended erase (0x44), this can take ten seconds or more
Verification OK

Adding -f H7 crashes the program

c$  stm32loader -p COM7  -f H7 -e -w -v ../../controller/platformio/.pio/build/my_env/firmware.bin
Bootloader activation timeout -- retrying
Bootloader version: 0x31
Chip id: 0x450 (STM32H76xxx/77xxx)
Traceback (most recent call last):
  File "<frozen runpy>", line 198, in _run_module_as_main
  File "<frozen runpy>", line 88, in _run_code
  File "C:\Users\user\AppData\Local\Programs\Python\Python312\Scripts\stm32loader.exe\__main__.py", line 7, in <module>
  File "C:\Users\user\AppData\Local\Programs\Python\Python312\Lib\site-packages\stm32loader\__main__.py", line 37, in main
    stm32loader_main(*sys.argv[1:])
  File "C:\Users\user\AppData\Local\Programs\Python\Python312\Lib\site-packages\stm32loader\main.py", line 426, in main
    loader.read_device_uid()
  File "C:\Users\user\AppData\Local\Programs\Python\Python312\Lib\site-packages\stm32loader\main.py", line 390, in read_device_uid
    flash_size = self.stm32.get_flash_size()
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\user\AppData\Local\Programs\Python\Python312\Lib\site-packages\stm32loader\bootloader.py", line 464, in get_flash_size
    flash_size_bytes = self.read_memory(flash_size_address, 2)
                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\user\AppData\Local\Programs\Python\Python312\Lib\site-packages\stm32loader\bootloader.py", line 540, in read_memory
    if length > self.data_transfer_size:
       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
TypeError: '>' not supported between instances of 'int' and 'NoneType'
Activating bootloader (select UART)

I will try 0.7.0 dev and will report here.

zapta commented 1 year ago

And this is what I got with 0.7.0.dev0

$ pip freeze | grep stm32loader
stm32loader==0.7.0.dev0

Without the -f H7 it crashes:

$  stm32loader -p COM7   -e -w -v ../../controller/platformio/.pio/build/my_env/firmware.bin
Bootloader activation timeout -- retrying
Bootloader version: 0x31
Chip id: 0x450 (STM32H76xxx/77xxx)
Supply -f [family] to see flash size and device UID, e.g: -f F1
Traceback (most recent call last):
  File "<frozen runpy>", line 198, in _run_module_as_main
  File "<frozen runpy>", line 88, in _run_code
  File "C:\Users\user\AppData\Local\Programs\Python\Python312\Scripts\stm32loader.exe\__main__.py", line 7, in <module>
  File "C:\Users\user\AppData\Local\Programs\Python\Python312\Lib\site-packages\stm32loader\__main__.py", line 37, in main
    stm32loader_main(*sys.argv[1:])
  File "C:\Users\user\AppData\Local\Programs\Python\Python312\Lib\site-packages\stm32loader\main.py", line 245, in main
    loader.perform_commands()
  File "C:\Users\user\AppData\Local\Programs\Python\Python312\Lib\site-packages\stm32loader\main.py", line 144, in perform_commands
    end_address = self.configuration.address + self.configuration.length
                  ~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~
TypeError: unsupported operand type(s) for +: 'int' and 'NoneType'
Activating bootloader (select UART)

And it crashes with the -f H7

$  stm32loader -p COM7 -f H7  -e -w -v ../../controller/platformio/.pio/build/my_env/firmware.bin
Bootloader activation timeout -- retrying
Bootloader version: 0x31
Chip id: 0x450 (STM32H76xxx/77xxx)
Traceback (most recent call last):
  File "<frozen runpy>", line 198, in _run_module_as_main
  File "<frozen runpy>", line 88, in _run_code
  File "C:\Users\user\AppData\Local\Programs\Python\Python312\Scripts\stm32loader.exe\__main__.py", line 7, in <module>
  File "C:\Users\user\AppData\Local\Programs\Python\Python312\Lib\site-packages\stm32loader\__main__.py", line 37, in main
    stm32loader_main(*sys.argv[1:])
  File "C:\Users\user\AppData\Local\Programs\Python\Python312\Lib\site-packages\stm32loader\main.py", line 244, in main
    loader.read_device_uid()
  File "C:\Users\user\AppData\Local\Programs\Python\Python312\Lib\site-packages\stm32loader\main.py", line 208, in read_device_uid
    flash_size = self.stm32.get_flash_size()
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\user\AppData\Local\Programs\Python\Python312\Lib\site-packages\stm32loader\bootloader.py", line 479, in get_flash_size
    flash_size_bytes = self.read_memory(flash_size_address, 2)
                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\user\AppData\Local\Programs\Python\Python312\Lib\site-packages\stm32loader\bootloader.py", line 555, in read_memory
    if length > self.data_transfer_size:
       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
TypeError: '>' not supported between instances of 'int' and 'NoneType'
Activating bootloader (select UART)
florisla commented 1 year ago

You exposed not one but two bugs... Sorry about the inconvenience. Could you test v0.7.0-dev2 ?

https://test.pypi.org/project/stm32loader/0.7.0.dev1/#files

zapta commented 1 year ago

Hi @florisla, I tried dev 1 and it doesn't program at all, exiting with a message regarding a missing length.

$ pip freeze | grep stm32loader
stm32loader==0.7.0.dev1
$ stm32loader -p COM7 -e -w -v ../../controller/platformio/.pio/build/my_env/firmware.bin
Bootloader activation timeout -- retrying
Bootloader version: 0x31
Chip id: 0x450 (STM32H76xxx/77xxx)
Supply -f [family] to see flash size and device UID, e.g: -f F1
Can not erase from specific address without specified length.
Consider using the --length argument.
Activating bootloader (select UART)
$ stm32loader -p COM7 -f H7 -e -w -v ../../controller/platformio/.pio/build/my_env/firmware.bin
Bootloader activation timeout -- retrying
Bootloader version: 0x31
Chip id: 0x450 (STM32H76xxx/77xxx)
Device UID: 003D-0037-33325115-34353635
Flash size: 128 KiB
Can not erase from specific address without specified length.
Consider using the --length argument.
Activating bootloader (select UART)
florisla commented 1 year ago

Sorry about that! dev2 is available... no guarantees unfortunately ;-)

https://test.pypi.org/project/stm32loader/0.7.0.dev2/#files

zapta commented 1 year ago

@florisla, thank you for taking the time. It looks good now. If you have additional tests in mind, please let me know.

$ pip freeze | grep stm32loader
stm32loader==0.7.0.dev2

$ stm32loader -p COM7 -e -w -v ../../controller/platformio/.pio/build/my_env/firmware.bin
Bootloader version: 0x31
Chip id: 0x450 (STM32H76xxx/77xxx)
Supply -f [family] to see flash size and device UID, e.g: -f F1
Write 291 chunks at address 0x8000000...
Read 291 chunks at address 0x8000000...
Activating bootloader (select UART)
Extended erase (0x44), this can take ten seconds or more
Verification OK

$ stm32loader -p COM7 -f H7 -e -w -v ../../controller/platformio/.pio/build/my_env/firmware.bin
Bootloader version: 0x31
Chip id: 0x450 (STM32H76xxx/77xxx)
Device UID: 003D-0037-33325115-34353635
Flash size: 128 KiB
Write 291 chunks at address 0x8000000...
Read 291 chunks at address 0x8000000...
Activating bootloader (select UART)
Extended erase (0x44), this can take ten seconds or more
Verification OK
zapta commented 1 year ago

One more thing, the chip is STM32H750 but is identified as STM32H76xxx/77xxx. Anything that can be done?

Chip id: 0x450 (STM32H76xxx/77xxx)
florisla commented 1 year ago

Funny, the H76xxx and H77xxx series don't even exist :-)

I think it's a copy-paste error because AN2606 does in fact mention 0x451 for STM32F76xxx/77xxx .

Will be fixed in the final v0.7.0.

I'm confused that the write action seems to occur before the erase, and verification succeeds after erase... Did you truncate some of the output?

Would be great if you could test erasing a single sector of the flash memory:

stm32loader --erase --address 0x08000000 --length 0x20000
zapta commented 1 year ago

No, didn't truncate the output, it includes everything.

This is what I get when I try the erase command:

$ pip freeze | grep stm32loader
stm32loader==0.7.0.dev2

$ stm32loader --erase --address 0x08000000 --length 0x20000  -p COM7 -f H7
Bootloader activation timeout -- retrying
Bootloader version: 0x31
Chip id: 0x450 (STM32H76xxx/77xxx)
Device UID: 003D-0037-33325115-34353635
Flash size: 128 KiB
Traceback (most recent call last):
  File "<frozen runpy>", line 198, in _run_module_as_main
  File "<frozen runpy>", line 88, in _run_code
  File "C:\Users\user\AppData\Local\Programs\Python\Python312\Scripts\stm32loader.exe\__main__.py", line 7, in <module>
  File "C:\Users\user\AppData\Local\Programs\Python\Python312\Lib\site-packages\stm32loader\__main__.py", line 37, in main
    stm32loader_main(*sys.argv[1:])
  File "C:\Users\user\AppData\Local\Programs\Python\Python312\Lib\site-packages\stm32loader\main.py", line 247, in main
    loader.perform_commands()
  File "C:\Users\user\AppData\Local\Programs\Python\Python312\Lib\site-packages\stm32loader\main.py", line 147, in perform_commands
    self.stm32.erase_memory(from_to=(start_address, end_address))
  File "C:\Users\user\AppData\Local\Programs\Python\Python312\Lib\site-packages\stm32loader\bootloader.py", line 610, in erase_memory
    pages = list(range(first_page, last_page))
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
TypeError: 'float' object cannot be interpreted as an integer
Activating bootloader (select UART)
florisla commented 1 year ago

This one should work better:

https://test.pypi.org/project/stm32loader/0.7.1.dev0/#files

zapta commented 1 year ago

@florisla, here is the log of the three commands. It looks good. The erasure message is still at the end. Also, would be nice to say exactly in the log what was erased, it's not clear if its just the write area or the entire flash. (as a layman I don't know that 'Extended erase (0x44)' means).

Thanks for your help, If you want me to run additional tests please let me know. This utility is a god send. It allows me to provide a single reflashing utility (I build an app specific binary using pyinstaller such that they don't need to install python) instead of instructing the users to register to ST and download their programming app.

$ pip freeze | grep stm32loader
stm32loader==0.7.1.dev0

$ stm32loader --erase --address 0x08000000 --length 0x20000  -p COM7 -f H7
Bootloader activation timeout -- retrying
Bootloader version: 0x31
Chip id: 0x450 (STM32H74xxx/75xxx)
Device UID: 003D-0037-33325115-34353635
Flash size: 128 KiB
Activating bootloader (select UART)
Extended erase (0x44), this can take ten seconds or more

$ stm32loader -p COM7 -e -w -v ../../controller/platformio/.pio/build/my_env/firmware.bin
Bootloader activation timeout -- retrying
Bootloader version: 0x31
Chip id: 0x450 (STM32H74xxx/75xxx)
Supply --family to see flash size and device UID, e.g: -f F1
Write 291 chunks at address 0x8000000...
Read 291 chunks at address 0x8000000...
Activating bootloader (select UART)
Extended erase (0x44), this can take ten seconds or more
Verification OK

$ stm32loader -p COM7 -f H7 -e -w -v ../../controller/platformio/.pio/build/my_env/firmware.bin
Bootloader activation timeout -- retrying
Bootloader version: 0x31
Chip id: 0x450 (STM32H74xxx/75xxx)
Device UID: 003D-0037-33325115-34353635
Flash size: 128 KiB
Write 291 chunks at address 0x8000000...
Read 291 chunks at address 0x8000000...
Activating bootloader (select UART)
Extended erase (0x44), this can take ten seconds or more
Verification OK
florisla commented 1 year ago

Hi, if you want to distribute a binary, it may be worthwhile to try out stm32flash. It's available in Ubuntu, fast, and has excellent device support.

zapta commented 1 year ago

It looks like a very capable tool indeed.

I am using stm32loader because it allows me to add a thin layer application specific logic, and is highly portable since it's based on Python.

https://github.com/zapta/daq/blob/main/host/src/flasher.py#L52

My system has other python based binaries so I don't mine generating one more for the flasher.

https://github.com/zapta/daq/blob/main/host/pyinstaller/windows/build_flasher.bat#L18

florisla commented 12 months ago

All these fixes are now release as v0.7.1.