Platformio supports Arduino Portenta H7

Hi,
Does anyone know an instruction on how to add a new board: Arduino Portenta H7?
I was following this but got an error:
“Error: Could not load broken JSON: ~/.platformio/boards/h7.json”

Is there a place to request adding new board to PlatformIO?
Thanks!

Then the JSON is not syntactically valid. Run it through https://jsonformatter.curiousconcept.com/.

Also, it involves more than adding a board defintion for the Portenta H7. You would need to add the Arduino core packages as well, with the appropriate builder script for it.

If I’m correct then GitHub - arduino/ArduinoCore-mbed is the core for the board? If yes, that’s the same core as for the nano33ble, so a lot may be re-used here :slight_smile:

What’s the current state of your h7.json file?

1 Like

Wow, thanks for the direction! Yes the H7 uses the same mbed core with nano33ble. The ArduinoCore-mbed already supports the H7. Appreciate any direction on how to adapt the platform.py. :slight_smile:

Below is my current h7.json. Looks like you’re pointing to exactly where I need to change platform.py.

KeyError: “Invalid board option ‘build.variant’”:

{
  "build": {
    "cpu": "cortex-m7",
    "extra_flags": "-DSTM32H7xx -DSTM32H747xx",
    "f_cpu": "480000000L",
    "mcu": "STM32H747XIH6",
    "product_line": "STM32H747xx"
  },
  "connectivity": [
    "wifi",
    "bluetooth"
  ],
  "debug": {
    "default_tools": [
      "jlink"
    ],
    "jlink_device": "STM32H747XI",
    "openocd_board": "st_nucleo_h743zi",
    "openocd_target": "stm32h7x",
    "svd_path": "STM32H7x7.svd"
  },
  "frameworks": [
    "arduino",
    "stm32cube",
    "libopencm3",
    "mbed"
  ],
  "name": "H7Portenta",
  "upload": {
    "maximum_ram_size": 1024288,
    "maximum_size": 2097152,
    "protocol": "sam-ba",
    "protocols": [
      "jlink",
      "cmsis-dap",
      "stlink",
      "blackmagic",
      "mbed"
    ]
  },
  "url": "https://www.arduino.cc/pro/hardware/product/portenta-h7",
  "vendor": "Arduino"
}

I got it working. Yay!! Beautiful PlatformIO! :heart_eyes:

{
  "build": {
    "arduino":{
      "ldscript": "linker_script.ld"
    },
    "core": "arduino",
    "cpu": "cortex-m7",
    "f_cpu": "480000000L",
    "mcu": "STM32H747xiH6",
    "variant": "PORTENTA_H7_M7",
    "product_line": "STM32H747xx",
    "hwids": [
      [
        "0x2341",
        "0x025b"
      ],
      [
        "0x2341",
        "0x035b"
      ],
      [
        "0x2341",
        "0x045b"
      ]
    ]
  },
  "connectivity": [
    "bluetooth"
  ],
  "debug": {
    "default_tools": [
      "jlink"
    ],
    "jlink_device": "STM32H747XI",
    "openocd_board": "st_nucleo_h743zi",
    "openocd_target": "stm32h7x",
    "svd_path": "STM32H7x7.svd"
  },
  "frameworks": [
    "arduino",
    "cmsis",
    "stm32cube",
    "libopencm3",
    "mbed"
  ],
  "name": "H7Portenta",
  "upload": {
    "maximum_ram_size": 523624,
    "maximum_size": 786432,
    "protocol": "dfu",
    "protocols": [
      "jlink",
      "cmsis-dap",
      "stlink",
      "blackmagic",
      "mbed"
    ]
  },
  "url": "https://www.arduino.cc/pro/hardware/product/portenta-h7",
  "vendor": "Arduino"
}

Oh that’s great, I was just about to say that I’ll take some time and see if the platform-ststm32 code can be hacked to quickly support this board.

What is your final platformio.ini and the modifications you had to do to the Python script(s)?

This would also be very intersting to submit as PR to GitHub - platformio/platform-ststm32: ST STM32: development platform for PlatformIO to support the board (one ‘board’ for the M7 part, one for the M4 part)

My platformio.ini is pretty simple (see below). Yes I had to add some python code to the platform-ststm32. Basically copy & paste from the nano33ble. (Thanks to your suggestion! Saved me a lot of time :slight_smile: )
Yeah I love it to be upstreamed support. One problem before submitting: uploading fails. Portenta H7 uses dfu-utils but dfu-util doesn’t know how to DFU the H7. Do you know where should I add a few commands before dfu-utils is called?

[env: portenta_h7m4]
platform = ststm32
board = portenta_h7m4
framework = arduino

[env: portenta_h7m7]
platform = ststm32
board = portenta_h7m7
framework = arduino

Hm first of all you should try reproducing what the Arduino IDE does on the commandline.

So if you have a compiled firmware for the portenta_h7m7 environment (PS: The space after env: is kinda weird and might end up in the pathname), the Arduino IDE would do something like

dfu-util --device 0x2341:0x035b -D ".pio\build\portenta_h7m7\firmware.bin" -a0 --dfuse-address=0x08040000:leave

Try and open a PlatformIO CLI, pio run -e portenta_h7m7 to compile the firmware and then the command above but prefixed with the path to the dfu-util, which should be C:\Users\<user>\.platformio\packages\tool-dfuutil\bin. The board has to be put the board into DFU bootloader mode of course, so you should see something like

grafik

in the device manager.

What does dfu-util output then?

If the dfu-util version is too old, it can still be replaced with platform_packages = tool-dfuutil@somenewsource.zip.

1 Like

Yeah, you’re right. Here’s the commands sequence that work for me:

pio run -d coreM7
stty -f /dev/cu.usbmodem1424201 1200
sleep 1
dfu-util —-device 0x2341:0x035b -D coreM7/.pio/build/h7m7/firmware.bin -a0 --dfuse-address=0x08040000:leave

stty -f /dev/cu.usbmodem1424201 1200 is to bring the Arduino to DFU mode. Looks like we also need to get the serial port string from platformIO. Then we had to wait a bit before calling dfu-util. I don’t like sleep in the code though. How do you think? Maybe polling for USB enumeration?

Here’s the output of dfu-util with: pio run -t upload -d coreM7
Looks like dfu-util doesn’t bring the chip to DFU mode, so we need to add commands to do make sure the board is in DFU mode before calling dfu-util.

Configuring upload protocol...
AVAILABLE: blackmagic, cmsis-dap, dfu, jlink, mbed, stlink
CURRENT: upload_protocol = dfu
Uploading .pio/build/portenta_h7m7/firmware.bin
dfu-util 0.9

Copyright 2005-2009 Weston Schmidt, Harald Welte and OpenMoko Inc.
Copyright 2010-2020 Tormod Volden and Stefan Schmidt
This program is Free Software and has ABSOLUTELY NO WARRANTY
Please report bugs to http://sourceforge.net/p/dfu-util/tickets/

dfu-util: Invalid DFU suffix signature
dfu-util: A valid DFU suffix will be required in a future dfu-util release!!!
dfu-util: No DFU capable USB device available
*** [upload] Error 74

PS: let me know if you’d like me to push the change somewhere. Not sure if you had the board to try.

I don’t have the hardware in the first place :sweat_smile:.

Ah indeed, that’s a nifty trick by the booloader / firmware – it detects that the USB-CDC serial is opened at 1200 baud and can do special logic then, aka rebooting into DFU mode. PlatformIO can do this too, and also has logic to wait for a new upload port then. But usually a COM port, not a new USB device I think.

The Atmel-SAM boards typically use this since the bootloader BOSSAC also behaves the same way with a ‘magic touch’.

So maybe adding those would help, too. (Or temporarily stty -f /dev/cu.usbmodem1424201 1200 before upload via PlatformIO)

Hm let’s dig into this then. First of all, with pio run -e portenta_h7m7 -t upload -v (or just “Advanced → Verbose Upload” in the VSCode project tasks), you’ll see the full invocation line that PlatformIO does for uploading. Can you post that?

Then it can be compared on what parts aren’t like the command that does work.

Is the code responsible for taking the information of the board’s JSON file and turning it into the command that’ll be executed for the DFU upload, btw.

An apparent problem is e.g. that it already hardcodes -a0 which would make upload to the M4 core that sits on interface number 1 impossible, without a code change in the code above plus a new field in the board’s JSON file to get that information from, per-board.

1 Like

Oh and on a side-node, these

two attributes should be set too in the board’s JSON file I think, but with offset_address adapted to 0x08040000 for the M7 and 0x08100000 for the M4. Maybe the native_usb even does the trick so that it waits for a new USB device of a certain VID/PID instead of a new serial port.

1 Like

Wowow it works beautifully. Thank you so much for your suggestion! :star_struck:
Will submit a PR soon.

Thanks a lot for your help, @maxgerhardt. Here’s the PR: Support Arduino Portenta H7: https://www.arduino.cc/pro/hardware/prod… by long-pham · Pull Request #494 · platformio/platform-ststm32 · GitHub

1 Like