Skip to content

Commit 9f12547

Browse files
authored
Add initial support for Arduino Portenta H7 (#494)
1 parent a69cf22 commit 9f12547

File tree

6 files changed

+301
-20
lines changed

6 files changed

+301
-20
lines changed

boards/portenta_h7_m4.json

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
{
2+
"build": {
3+
"arduino":{
4+
"ldscript": "linker_script.ld"
5+
},
6+
"extra_flags": "-DARDUINO_PORTENTA_H7_M4",
7+
"core": "arduino",
8+
"cpu": "cortex-m4",
9+
"f_cpu": "480000000L",
10+
"mcu": "stm32h747xih6",
11+
"variant": "PORTENTA_H7_M4",
12+
"product_line": "STM32H747xx",
13+
"hwids": [
14+
[
15+
"0x2341",
16+
"0x035b"
17+
],
18+
[
19+
"0x2341",
20+
"0x025b"
21+
],
22+
[
23+
"0x2341",
24+
"0x045b"
25+
]
26+
]
27+
},
28+
"connectivity": [
29+
"bluetooth",
30+
"wifi"
31+
],
32+
"debug": {
33+
"jlink_device": "STM32H747XI_M4",
34+
"openocd_target": "stm32h7x_dual_bank"
35+
},
36+
"frameworks": [
37+
"arduino"
38+
],
39+
"name": "Arduino Portenta H7 (M4 core)",
40+
"upload": {
41+
"maximum_ram_size": 294248,
42+
"maximum_size": 1048576,
43+
"protocol": "dfu",
44+
"protocols": [
45+
"cmsis-dap",
46+
"dfu",
47+
"jlink",
48+
"stlink",
49+
"mbed"
50+
],
51+
"require_upload_port": true,
52+
"use_1200bps_touch": true,
53+
"wait_for_upload_port": true,
54+
"offset_address": "0x08100000"
55+
},
56+
"url": "https://www.arduino.cc/pro/hardware/product/portenta-h7",
57+
"vendor": "Arduino"
58+
}

boards/portenta_h7_m7.json

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
{
2+
"build": {
3+
"arduino":{
4+
"ldscript": "linker_script.ld"
5+
},
6+
"extra_flags": "-DARDUINO_PORTENTA_H7_M7",
7+
"core": "arduino",
8+
"cpu": "cortex-m7",
9+
"f_cpu": "480000000L",
10+
"mcu": "stm32h747xih6",
11+
"variant": "PORTENTA_H7_M7",
12+
"product_line": "STM32H747xx",
13+
"hwids": [
14+
[
15+
"0x2341",
16+
"0x035b"
17+
],
18+
[
19+
"0x2341",
20+
"0x025b"
21+
],
22+
[
23+
"0x2341",
24+
"0x045b"
25+
]
26+
]
27+
},
28+
"connectivity": [
29+
"bluetooth",
30+
"wifi"
31+
],
32+
"debug": {
33+
"jlink_device": "STM32H747XI_M7",
34+
"openocd_target": "stm32h7x_dual_bank"
35+
},
36+
"frameworks": [
37+
"arduino"
38+
],
39+
"name": "Arduino Portenta H7 (M7 core)",
40+
"upload": {
41+
"maximum_ram_size": 523624,
42+
"maximum_size": 786432,
43+
"protocol": "dfu",
44+
"protocols": [
45+
"cmsis-dap",
46+
"dfu",
47+
"jlink",
48+
"stlink",
49+
"mbed"
50+
],
51+
"require_upload_port": true,
52+
"use_1200bps_touch": true,
53+
"wait_for_upload_port": true,
54+
"offset_address": "0x08040000"
55+
},
56+
"url": "https://www.arduino.cc/pro/hardware/product/portenta-h7",
57+
"vendor": "Arduino"
58+
}
Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
# Copyright 2019-present PlatformIO <[email protected]>
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
"""
15+
Arduino
16+
17+
Arduino Wiring-based Framework allows writing cross-platform software to
18+
control devices attached to a wide range of Arduino boards to create all
19+
kinds of creative coding, interactive objects, spaces or physical experiences.
20+
"""
21+
22+
from os.path import isdir, isfile, join
23+
24+
from SCons.Script import DefaultEnvironment
25+
26+
env = DefaultEnvironment()
27+
platform = env.PioPlatform()
28+
board = env.BoardConfig()
29+
30+
FRAMEWORK_DIR = platform.get_package_dir("framework-arduino-nrf52-mbedos")
31+
assert isdir(FRAMEWORK_DIR)
32+
33+
34+
def load_flags(filename):
35+
if not filename:
36+
return []
37+
38+
file_path = join(FRAMEWORK_DIR, "variants", board.get(
39+
"build.variant"), "%s.txt" % filename)
40+
if not isfile(file_path):
41+
print("Warning: Couldn't find file '%s'" % file_path)
42+
return []
43+
44+
with open(file_path, "r") as fp:
45+
return [f.strip() for f in fp.readlines() if f.strip()]
46+
47+
48+
cflags = set(load_flags("cflags"))
49+
cxxflags = set(load_flags("cxxflags"))
50+
ccflags = cflags.intersection(cxxflags)
51+
52+
env.Append(
53+
ASFLAGS=["-x", "assembler-with-cpp"],
54+
55+
CFLAGS=sorted(list(cflags - ccflags)),
56+
57+
CCFLAGS=sorted(list(ccflags)),
58+
59+
CPPDEFINES=[d.replace("-D", "") for d in load_flags("defines")],
60+
61+
CXXFLAGS=sorted(list(cxxflags - ccflags)),
62+
63+
LIBPATH=[
64+
join(FRAMEWORK_DIR, "variants", board.get("build.variant")),
65+
join(FRAMEWORK_DIR, "variants", board.get("build.variant"), "libs")
66+
],
67+
68+
LINKFLAGS=load_flags("ldflags"),
69+
70+
LIBSOURCE_DIRS=[join(FRAMEWORK_DIR, "libraries")],
71+
72+
LIBS=["mbed"]
73+
)
74+
75+
env.Append(
76+
ASFLAGS=env.get("CCFLAGS", [])[:],
77+
78+
# Due to long path names "-iprefix" hook is required to avoid toolchain crashes
79+
CCFLAGS=[
80+
"-iprefix" + join(FRAMEWORK_DIR, "cores", board.get("build.core")),
81+
"@%s" % join(FRAMEWORK_DIR, "variants", board.get(
82+
"build.variant"), "includes.txt"),
83+
"-nostdlib"
84+
],
85+
86+
CPPDEFINES=[
87+
("ARDUINO", 10810),
88+
"ARDUINO_ARCH_MBED"
89+
],
90+
91+
CPPPATH=[
92+
join(FRAMEWORK_DIR, "cores", board.get("build.core")),
93+
join(FRAMEWORK_DIR, "cores", board.get("build.core"), "api", "deprecated")
94+
],
95+
96+
LINKFLAGS=[
97+
"--specs=nano.specs",
98+
"--specs=nosys.specs",
99+
"-Wl,--as-needed"
100+
]
101+
)
102+
103+
# Framework requires all symbols from mbed libraries
104+
env.Prepend(_LIBFLAGS="-Wl,--whole-archive ")
105+
env.Append(_LIBFLAGS=" -Wl,--no-whole-archive -lstdc++ -lsupc++ -lm -lc -lgcc -lnosys")
106+
107+
if not board.get("build.ldscript", ""):
108+
env.Replace(LDSCRIPT_PATH=board.get("build.arduino.ldscript", ""))
109+
110+
libs = []
111+
112+
if "build.variant" in board:
113+
env.Append(CPPPATH=[
114+
join(FRAMEWORK_DIR, "variants", board.get("build.variant"))
115+
])
116+
117+
libs.append(
118+
env.BuildLibrary(
119+
join("$BUILD_DIR", "FrameworkArduinoVariant"),
120+
join(FRAMEWORK_DIR, "variants",
121+
board.get("build.variant"))))
122+
123+
libs.append(
124+
env.BuildLibrary(
125+
join("$BUILD_DIR", "FrameworkArduino"),
126+
join(FRAMEWORK_DIR, "cores", board.get("build.core"))))
127+
128+
env.Prepend(LIBS=libs)

builder/main.py

Lines changed: 47 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,27 @@
2020
from SCons.Script import (ARGUMENTS, COMMAND_LINE_TARGETS, AlwaysBuild,
2121
Builder, Default, DefaultEnvironment)
2222

23+
from platformio.util import get_serial_ports
24+
25+
26+
def BeforeUpload(target, source, env): # pylint: disable=W0613,W0621
27+
env.AutodetectUploadPort()
28+
29+
upload_options = {}
30+
if "BOARD" in env:
31+
upload_options = env.BoardConfig().get("upload", {})
32+
33+
if not bool(upload_options.get("disable_flushing", False)):
34+
env.FlushSerialBuffer("$UPLOAD_PORT")
35+
36+
before_ports = get_serial_ports()
37+
38+
if bool(upload_options.get("use_1200bps_touch", False)):
39+
env.TouchSerialPort("$UPLOAD_PORT", 1200)
40+
41+
if bool(upload_options.get("wait_for_upload_port", False)):
42+
env.Replace(UPLOAD_PORT=env.WaitForNewSerialPort(before_ports))
43+
2344

2445
env = DefaultEnvironment()
2546
env.SConscript("compat.py", exports="env")
@@ -198,25 +219,32 @@ def _jlink_cmd_script(env, source):
198219

199220
upload_actions = [env.VerboseAction("$UPLOADCMD", "Uploading $SOURCE")]
200221

201-
if board.get("build.mcu").startswith("stm32f103") and "arduino" in env.get(
202-
"PIOFRAMEWORK"):
203-
# F103 series doesn't have embedded DFU over USB
204-
# stm32duino bootloader (v1, v2) is used instead
205-
def __configure_upload_port(env):
206-
return basename(env.subst("$UPLOAD_PORT"))
207-
208-
_upload_tool = "maple_upload"
209-
_upload_flags = [
210-
"${__configure_upload_port(__env__)}",
211-
board.get("upload.boot_version", 2),
212-
"%s:%s" % (vid[2:], pid[2:])
213-
]
214-
215-
env.Replace(__configure_upload_port=__configure_upload_port)
216-
217-
upload_actions.insert(
218-
0, env.VerboseAction(env.AutodetectUploadPort,
219-
"Looking for upload port..."))
222+
if "arduino" in env.get("PIOFRAMEWORK"):
223+
if env.subst("$BOARD").startswith("portenta"):
224+
upload_actions.insert(
225+
0,
226+
env.VerboseAction(
227+
env.AutodetectUploadPort, "Looking for upload port..."
228+
),
229+
)
230+
elif board.get("build.mcu").startswith("stm32f103"):
231+
# F103 series doesn't have embedded DFU over USB
232+
# stm32duino bootloader (v1, v2) is used instead
233+
def __configure_upload_port(env):
234+
return basename(env.subst("$UPLOAD_PORT"))
235+
236+
_upload_tool = "maple_upload"
237+
_upload_flags = [
238+
"${__configure_upload_port(__env__)}",
239+
board.get("upload.boot_version", 2),
240+
"%s:%s" % (vid[2:], pid[2:])
241+
]
242+
243+
env.Replace(__configure_upload_port=__configure_upload_port)
244+
245+
upload_actions.insert(
246+
0, env.VerboseAction(env.AutodetectUploadPort,
247+
"Looking for upload port..."))
220248

221249
if "dfu-util" in _upload_tool:
222250
# Add special DFU header to the binary image

platform.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,12 @@
209209
"owner": "platformio",
210210
"version": "~2.10.0"
211211
},
212+
"framework-arduino-mbed": {
213+
"type": "framework",
214+
"optional": true,
215+
"owner": "platformio",
216+
"version": "~1.3.2"
217+
},
212218
"framework-stm32cubef0": {
213219
"type": "framework",
214220
"optional": true,

platform.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,10 @@ def configure_default_packages(self, variables, targets):
3232

3333
frameworks = variables.get("pioframework", [])
3434
if "arduino" in frameworks:
35-
if build_core == "maple":
35+
if board.startswith("portenta_h7"):
36+
self.frameworks["arduino"]["package"] = "framework-arduino-mbed"
37+
self.frameworks["arduino"]["script"] = "builder/frameworks/arduino/arduino_h7_mbedos.py"
38+
elif build_core == "maple":
3639
self.frameworks["arduino"]["package"] = "framework-arduinoststm32-maple"
3740
self.packages["framework-arduinoststm32-maple"]["optional"] = False
3841
self.packages["framework-arduinoststm32"]["optional"] = True

0 commit comments

Comments
 (0)