diff --git a/README.md b/README.md
index c57acccc64..3bac206b5d 100644
--- a/README.md
+++ b/README.md
@@ -71,7 +71,7 @@ git clone --recurse-submodules https://github.com/modm-io/modm.git
## Targets
modm can generate code for 506
-AVR, 163 SAM and 2010
+AVR, 163 SAM and 2110
STM32 devices, however, there are different levels of support and testing.
diff --git a/docs/src/how-modm-works.md b/docs/src/how-modm-works.md
index dfbcf841fb..13461d72c7 100644
--- a/docs/src/how-modm-works.md
+++ b/docs/src/how-modm-works.md
@@ -56,7 +56,7 @@ def prepare(module, options):
def build(env):
device = env[":target"]
- env.substitutions = device.properties
+ env.substitutions = device.get_driver("uart")
env.outbasepath = "src/modm/platform/uart"
for instance in device.get_driver("uart:stm32*")["instance"]:
env.template("uart.hpp.in", "uart_{}.hpp".format(instance))
diff --git a/examples/nucleo_f767zi/ethernet/main.cpp b/examples/nucleo_f767zi/ethernet/main.cpp
index 628bd2d34e..0ae88c3b2d 100755
--- a/examples/nucleo_f767zi/ethernet/main.cpp
+++ b/examples/nucleo_f767zi/ethernet/main.cpp
@@ -188,11 +188,12 @@ main()
Leds::setOutput();
MODM_LOG_INFO << "\n\nReboot: Ethernet Example" << modm::endl;
- Ethernet::Port::connect();
usb_hs::Device::connect<
- usb_hs::Ck::Ulpick, usb_hs::Stp::Ulpistp,
- usb_hs::Dir::Ulpidir, usb_hs::Nxt::Ulpinxt,
- usb_hs::D0::Ulpid0, usb_hs::D1::Ulpid1,
- usb_hs::D2::Ulpid2, usb_hs::D3::Ulpid3,
- usb_hs::D4::Ulpid4, usb_hs::D5::Ulpid5,
- usb_hs::D6::Ulpid6, usb_hs::D7::Ulpid7>();
+ usb_hs::Ck::UlpiCk, usb_hs::Stp::UlpiStp,
+ usb_hs::Dir::UlpiDir, usb_hs::Nxt::UlpiNxt,
+ usb_hs::D0::UlpiD0, usb_hs::D1::UlpiD1,
+ usb_hs::D2::UlpiD2, usb_hs::D3::UlpiD3,
+ usb_hs::D4::UlpiD4, usb_hs::D5::UlpiD5,
+ usb_hs::D6::UlpiD6, usb_hs::D7::UlpiD7>();
usb_hs::Overcurrent::setInput();
// Deactivate VBUS Sensing B
diff --git a/src/modm/driver/gpio/gpio_sampler.lb b/src/modm/driver/gpio/gpio_sampler.lb
index 6710e3e785..23a106fc34 100644
--- a/src/modm/driver/gpio/gpio_sampler.lb
+++ b/src/modm/driver/gpio/gpio_sampler.lb
@@ -19,36 +19,22 @@ def prepare(module, options):
if options[":target"].identifier["platform"] != "stm32":
return False
- core = options[":target"].get_driver("core:cortex-m*")
+ core = options[":target"].driver("core").type
# Cortex-M0 doesn't have the DWT->CYCCNT and Cortex-M7 support is broken
- if not core or "m0" in core["type"] or "m7" in core["type"]:
+ if "m0" in core or "m7" in core:
return False
module.depends(
":platform:gpio",
":platform:core",
":architecture:interrupt")
+
return True
def build(env):
- exti_vectors = [v["name"] for v in env[":target"].get_driver("core")["vector"] if "EXTI" in v["name"]]
- # These are all exti possible vectors: 0, 0_1, 1, 15_10, 2, 2_3, 2_TSC, 3, 4, 4_15, 9_5
- extimap = {
- "0": [0], "1": [1], "2": [2], "3": [3], "4": [4],
- "0_1": [0,1],
- "2_TSC": [2],
- "2_3": [2,3],
- "4_15": [4,5,6,7,8,9,10,11,12,13,14,15],
- "9_5": [5,6,7,8,9],
- "15_10": [10,11,12,13,14,15],
- }
- extis = OrderedDict()
- for v in sorted(exti_vectors):
- extis[v] = extimap[v[4:]]
-
env.substitutions = {
- "extis": extis,
+ "extis": env[":target"].core.shared_irqs("EXTI"),
"vectors_location": env.get(":platform:core:vector_table_location", "rom")
}
env.outbasepath = "modm/src/modm/driver"
diff --git a/src/modm/platform/adc/stm32/module.lb b/src/modm/platform/adc/stm32/module.lb
index 6600dfeea0..d18ece929a 100644
--- a/src/modm/platform/adc/stm32/module.lb
+++ b/src/modm/platform/adc/stm32/module.lb
@@ -68,27 +68,6 @@ def prepare(module, options):
device = options[":target"]
if not device.has_driver("adc:stm32"):
return False
- global props
- props = {}
- driver = device.get_driver("adc")
- props["target"] = target = device.identifier
- props["driver"] = driver
- props["instances"] = []
-
- if target["family"] in ["f2", "f4", "f7"]:
- props["shared_irqs"] = {"ADC": listify(device.get_driver("adc")["instance"])}
- props["shared_irq_ids"] = props["shared_irqs"]["ADC"]
- else:
- shared_irqs = [v["name"] for v in device.get_driver("core")["vector"]]
- shared_irqs = [v for v in shared_irqs if v.startswith("ADC") and "_" in v]
- props["shared_irqs"] = {}
- props["shared_irq_ids"] = []
- for irq in shared_irqs:
- parts = irq[3:].split("_")
- shared_irqs_ids = (int(parts[0]), int(parts[1]) )
- props["shared_irqs"][irq] = shared_irqs_ids
- props["shared_irq_ids"].extend(shared_irqs_ids)
-
module.depends(
":architecture:adc",
@@ -99,21 +78,35 @@ def prepare(module, options):
":math:algorithm",
":utils")
- for instance in listify(device.get_driver("adc").get("instance", [])):
- module.add_submodule(Instance(int(instance)))
+ for instance in device.driver("adc").instances():
+ module.add_submodule(Instance(instance.number))
return True
-def build(env):
+def validate(env):
device = env[":target"]
- driver = device.get_driver("adc")
-
global props
+ props = {}
+ props["target"] = target = device.identifier
+ props["instances"] = []
+
+ shared_irqs = device.core.shared_irqs("ADC")
+ if shared_irqs.values():
+ props["shared_irqs"] = shared_irqs
+ props["shared_irq_ids"] = list(shared_irqs.values())[0]
+ else:
+ irq_name = next(device.core.vectors(lambda v: v.startswith("ADC")), "ADC")
+ instances = [i.number for i in device.driver("adc").instances()]
+ props["shared_irqs"] = {irq_name: instances}
+ props["shared_irq_ids"] = instances
+def build(env):
+ device = env[":target"]
+ global props
env.substitutions = props
env.outbasepath = "modm/src/modm/platform/adc"
- if device.get_driver("adc").get("instance", None) is None:
+ if not device.driver("adc").instances():
Instance(None).build(env)
if any(i in props["shared_irq_ids"] for i in props["instances"]):
diff --git a/src/modm/platform/adc/stm32f0/module.lb b/src/modm/platform/adc/stm32f0/module.lb
index dc763098df..ef32994b98 100644
--- a/src/modm/platform/adc/stm32f0/module.lb
+++ b/src/modm/platform/adc/stm32f0/module.lb
@@ -18,8 +18,7 @@ def init(module):
def prepare(module, options):
device = options[":target"]
- if not (device.has_driver("adc:stm32-f0") or
- device.has_driver("adc:stm32-g0")):
+ if not device.has_driver("adc:stm32-[fg]0"):
return False
module.depends(
":architecture:delay",
@@ -33,11 +32,10 @@ def prepare(module, options):
def build(env):
device = env[":target"]
- driver = device.get_driver("adc")
properties = {}
properties["target"] = target = device.identifier
- properties["id"] = driver.get("instance", [""])[0]
+ properties["id"] = device.driver("adc").instances([""])[0]
channels = {i:"In{}".format(i) for i in reversed(range(0,19))}
if target.family in ["g0"]:
@@ -52,10 +50,7 @@ def build(env):
else:
channels[18] = "Battery"
properties["channels"] = channels
-
- irq = next(v["name"] for v in device.get_driver("core")["vector"]
- if v["name"].startswith("ADC1"))
- properties["irq"] = irq
+ properties["irq"] = next(device.core.vectors(lambda v: v.startswith("ADC1")))
env.substitutions = properties
env.outbasepath = "modm/src/modm/platform/adc"
diff --git a/src/modm/platform/adc/stm32f3/module.lb b/src/modm/platform/adc/stm32f3/module.lb
index c2843e47fa..0c47c3ce06 100644
--- a/src/modm/platform/adc/stm32f3/module.lb
+++ b/src/modm/platform/adc/stm32f3/module.lb
@@ -27,7 +27,7 @@ class Instance(Module):
device = env[":target"]
driver = device.get_driver("adc")
- properties = device.properties
+ properties = {}
properties["target"] = target = device.identifier
instance_id = int(self.instance)
properties["id"] = instance_id
@@ -145,18 +145,10 @@ def prepare(module, options):
":platform:gpio",
":platform:rcc")
- for instance in listify(device.get_driver("adc")["instance"]):
- module.add_submodule(Instance(int(instance)))
+ for instance in device.driver("adc").instances():
+ module.add_submodule(Instance(instance.number))
return True
def build(env):
- device = env[":target"]
- driver = device.get_driver("adc")
-
- properties = device.properties
- properties["target"] = device.identifier
- properties["driver"] = driver
-
- env.substitutions = properties
- env.outbasepath = "modm/src/modm/platform/adc"
+ pass
diff --git a/src/modm/platform/can/lpc/module.lb b/src/modm/platform/can/lpc/module.lb
index c2e52dad64..d9cd9f00b1 100644
--- a/src/modm/platform/can/lpc/module.lb
+++ b/src/modm/platform/can/lpc/module.lb
@@ -38,13 +38,10 @@ def prepare(module, options):
def build(env):
device = env[":target"]
- driver = device.get_driver("can")
-
- properties = device.properties
- properties["target"] = target = device.identifier
- properties["driver"] = driver
-
- env.substitutions = properties
+ env.substitutions = {
+ "target": device.identifier,
+ "driver": device.get_driver("can"),
+ }
env.outbasepath = "modm/src/modm/platform/can"
env.template("c_can.cpp.in")
diff --git a/src/modm/platform/can/stm32/module.lb b/src/modm/platform/can/stm32/module.lb
index 6c07ffdcf8..4f50069f08 100644
--- a/src/modm/platform/can/stm32/module.lb
+++ b/src/modm/platform/can/stm32/module.lb
@@ -76,16 +76,20 @@ can_map = {
},
}
-def get_substitutions(instance, device, env):
+def get_substitutions(env, instance):
+ device = env[":target"]
target = device.identifier
+
driver = device.get_driver("can")
- instances = map(lambda i: int(i), driver["instance"]) if "instance" in driver else (0,)
+ instances = (i.number for i in device.driver("can").instances())
+ instances = instances if instances else [0]
- cm = can_map[target["family"]]
+ cm = can_map[target.family]
is_single = (cm[instance].type == CanType.Single) or (cm[instance].associated_instance not in instances)
other = cm[instance].associated_instance
subs = {
+ "target": target,
"id": "" if instance == 0 else str(instance),
"own_instance": cm[instance].register,
"other_instance": cm[other].register if other in cm else None,
@@ -109,15 +113,7 @@ class Instance(Module):
return True
def build(self, env):
- device = env[":target"]
- driver = device.get_driver("can")
-
- properties = device.properties
- properties["target"] = target = device.identifier
- properties["driver"] = driver
- properties.update(get_substitutions(self.instance, device, env))
-
- env.substitutions = properties
+ env.substitutions = get_substitutions(env, self.instance)
env.outbasepath = "modm/src/modm/platform/can"
env.template("can.hpp.in", "can_{}.hpp".format(self.instance))
@@ -147,34 +143,25 @@ def prepare(module, options):
":platform:rcc",
":utils")
- driver = device.get_driver("can")
+ instances = device.driver("can").instances()
# If there is only one instance of the peripheral it is not numbered and
# merged into the generic can module.
- if "instance" in driver:
- for instance in listify(driver["instance"]):
- module.add_submodule(Instance(int(instance)))
+ if instances:
+ for instance in instances:
+ module.add_submodule(Instance(instance.number))
else:
load_options(module)
return True
def build(env):
- device = env[":target"]
- driver = device.get_driver("can")
-
- properties = device.properties
- properties["target"] = device.identifier
- properties["driver"] = driver
-
- if "instance" not in driver:
- properties.update(get_substitutions(0, device, env))
-
- env.substitutions = properties
+ env.substitutions = {"target": env[":target"].identifier}
env.outbasepath = "modm/src/modm/platform/can"
env.template("can_filter.hpp.in")
env.template("can_filter.cpp.in")
- if "instance" not in driver:
+ if not env[":target"].driver("can").instances():
+ env.substitutions = get_substitutions(env, 0)
env.template("can.hpp.in")
env.template("can.cpp.in")
diff --git a/src/modm/platform/clock/lpc/module.lb b/src/modm/platform/clock/lpc/module.lb
index c8000f9d13..c40df2f4de 100644
--- a/src/modm/platform/clock/lpc/module.lb
+++ b/src/modm/platform/clock/lpc/module.lb
@@ -25,7 +25,7 @@ def build(env):
device = env[":target"]
driver = device.get_driver("clock")
- properties = device.properties
+ properties = {}
properties["target"] = target = device.identifier
properties["driver"] = driver
diff --git a/src/modm/platform/clock/stm32/module.lb b/src/modm/platform/clock/stm32/module.lb
index cf0de906f6..25fb892437 100644
--- a/src/modm/platform/clock/stm32/module.lb
+++ b/src/modm/platform/clock/stm32/module.lb
@@ -21,9 +21,7 @@ def prepare(module, options):
if not options[":target"].has_driver("rcc:stm32*"):
return False
- module.depends(":cmsis:device", ":utils", ":platform:clock")
- # FIXME: Move Peripherals enum somewhere better
- module.depends(":platform:gpio")
+ module.depends(":cmsis:device", ":utils", ":platform:clock", ":platform:core")
return True
def build(env):
@@ -67,31 +65,18 @@ def build(env):
properties["pllsai_p_usb"] = (target["family"] == "f7") or \
((target["family"] == "f4") and target["name"] in ["46", "69", "79"])
- flash_latencies = {}
- for vcore in device.get_driver("flash")["latency"]:
- flash_latencies[int(vcore["vcore-min"])] = sorted([int(f["hclk-max"]) for f in vcore["wait-state"]])
-
- properties["table"] = flash_latencies
+ properties["table"] = device.flash.wait_states
env.substitutions = properties
env.outbasepath = "modm/src/modm/platform/clock"
env.template("rcc.cpp.in")
env.template("rcc.hpp.in")
- all_peripherals = set()
- all_drivers = [d for d in device._properties["driver"] if d["name"] not in ["gpio", "core"]]
- translate = lambda s: s.replace("_", "").capitalize()
- for d in all_drivers:
- dname = translate(d["name"])
- if "instance" in d:
- all_peripherals.update(dname + translate(i) for i in d["instance"])
- else:
- all_peripherals.add(dname)
- all_peripherals = sorted(list(all_peripherals))
-
rcc_map = env.query(":cmsis:device:rcc-map")
rcc_enable = {}
rcc_reset = {}
+ all_peripherals = uniquify(map(env.filter("modm.fmt.driver"), env[":target"].peripherals))
+ all_peripherals_lut = {p.lower():p for p in all_peripherals}
for per, mode in rcc_map.items():
nper = per
@@ -110,14 +95,14 @@ def build(env):
if "Eth" in all_peripherals and per == "ETHMAC":
per = "Eth"
# Fix USBOTG OTG
- if "Usbotgfs" in all_peripherals and per.startswith("OTG"):
+ if "UsbOtgFs" in all_peripherals and per.startswith("OTG"):
if per == "OTGH": per = "OTGHS";
per = "USB"+per
# print(per, mode)
- if per.capitalize() not in all_peripherals:
+ if per.lower() not in all_peripherals_lut:
continue
if "EN" in mode:
- rcc_enable[per.capitalize()] = (nper, mode["EN"])
+ rcc_enable[all_peripherals_lut[per.lower()]] = (nper, mode["EN"])
if "RST" in mode:
rcc_reset[nper] = mode["RST"]
diff --git a/src/modm/platform/comp/stm32/base.hpp.in b/src/modm/platform/comp/stm32/base.hpp.in
index 46443a8940..383cd99ac8 100644
--- a/src/modm/platform/comp/stm32/base.hpp.in
+++ b/src/modm/platform/comp/stm32/base.hpp.in
@@ -19,17 +19,17 @@ namespace modm::platform
/// @ingroup modm_platform_comp
class CompBase
{
- {% if driver.type not in ["stm32-tsmc90_g4_rockfish_cube"] -%}
+ {% if type not in ["stm32-tsmc90_g4_rockfish_cube"] -%}
public:
enum class
Mode
{
- {% if driver.type in ["stm32-v1.3"] -%}
+ {% if type in ["stm32-v1.3"] -%}
UltraLowPower = 0b00 << 2,
LowPower = 0b01 << 2,
MediumSpeed = 0b10 << 2,
HighSpeed = 0b11 << 2,
- {% elif driver.type in ["stm32-tsmc90_cube"] -%}
+ {% elif type in ["stm32-tsmc90_cube"] -%}
HighSpeed = 0b00 << 2,
MediumSpeed = 0b01 << 2,
//MediumSpeed2 = 0b10 << 2,
@@ -50,7 +50,7 @@ namespace modm::platform
protected:
static constexpr uint32_t PolarityMask = 0b1 << 15;
- {% if driver.type in ["stm32-v1.3", "stm32-tsmc90_cube"] -%}
+ {% if type in ["stm32-v1.3", "stm32-tsmc90_cube"] -%}
public:
enum class
Hysteresis
@@ -62,7 +62,7 @@ namespace modm::platform
};
protected:
static constexpr uint32_t HysteresisMask = 0b11 << 16;
- {% elif "g4" in driver.type -%}
+ {% elif "g4" in type -%}
public:
enum class
Hysteresis
diff --git a/src/modm/platform/comp/stm32/comp.hpp.in b/src/modm/platform/comp/stm32/comp.hpp.in
index 638f838bf1..b1bde6055e 100644
--- a/src/modm/platform/comp/stm32/comp.hpp.in
+++ b/src/modm/platform/comp/stm32/comp.hpp.in
@@ -234,7 +234,7 @@ namespace modm::platform
Output out = Output::NoSelection,
{% endif -%}
Hysteresis hyst = Hysteresis::NoHysteresis,
- {% if driver.type not in ["stm32-tsmc90_g4_rockfish_cube"] -%}
+ {% if type not in ["stm32-tsmc90_g4_rockfish_cube"] -%}
Mode mode = Mode::HighSpeed,
{% endif -%}
Polarity pol = Polarity::NonInverted,
@@ -248,7 +248,7 @@ namespace modm::platform
setOutputSelection(out);
{% endif -%}
setHysteresis(hyst);
- {% if driver.type not in ["stm32-tsmc90_g4_rockfish_cube"] -%}
+ {% if type not in ["stm32-tsmc90_g4_rockfish_cube"] -%}
setMode(mode);
{% endif -%}
setPolarity(pol);
@@ -308,7 +308,7 @@ namespace modm::platform
}
{% endif -%}
- {% if driver.type not in ["stm32-tsmc90_g4_rockfish_cube"] -%}
+ {% if type not in ["stm32-tsmc90_g4_rockfish_cube"] -%}
/**
* \brief Sets the mode that determins speed/power consumption.
*
diff --git a/src/modm/platform/comp/stm32/module.lb b/src/modm/platform/comp/stm32/module.lb
index 87aee6f45d..15d0d587c4 100644
--- a/src/modm/platform/comp/stm32/module.lb
+++ b/src/modm/platform/comp/stm32/module.lb
@@ -24,13 +24,12 @@ class Instance(Module):
def build(self, env):
device = env[":target"]
- driver = device.get_driver("comp")
- properties = device.properties
+ properties = {}
properties["target"] = device.identifier
instance_id = int(self.instance)
properties["id"] = instance_id
- properties["driver"] = driver
+ properties["type"] = device.driver("comp").type
properties["csr"] = "COMP_CSR_" if device.identifier["family"] in ["l4", "g4"] else "COMP_CSR_COMPx"
properties["blanking_source"] = dict()
if device.identifier["family"] in ["g4"]:
@@ -50,8 +49,6 @@ class Instance(Module):
properties["blanking_source"]["b010"] = "Tim2Oc3"
properties["blanking_source"]["b011"] = "Tim3Oc3"
-
-
env.substitutions = properties
env.outbasepath = "modm/src/modm/platform/comp"
@@ -83,7 +80,7 @@ def prepare(module, options):
"stm32-v3.4"
"stm32-v3.6"
"""
- if not device.get_driver("comp")["type"] in ["stm32-v1.3", "stm32-tsmc90_cube", "stm32-tsmc90_g4_rockfish_cube"]:
+ if not device.driver("comp").type in ["stm32-v1.3", "stm32-tsmc90_cube", "stm32-tsmc90_g4_rockfish_cube"]:
return False
# Only some STM32F3 and STM32L4
@@ -100,18 +97,17 @@ def prepare(module, options):
module.depends(":cmsis:device")
- for instance in listify(device.get_driver("comp")["instance"]):
- module.add_submodule(Instance(int(instance)))
+ for instance in device.driver("comp").instances():
+ module.add_submodule(Instance(instance.number))
return True
def build(env):
device = env[":target"]
- driver = device.get_driver("comp")
- properties = device.properties
+ properties = {}
properties["target"] = device.identifier
- properties["driver"] = driver
+ properties["type"] = device.driver("comp").type
properties["csr"] = "COMP_CSR_" if device.identifier["family"] in ["l4", "g4"] else "COMP_CSR_COMPx"
env.substitutions = properties
diff --git a/src/modm/platform/core/cortex/module.lb b/src/modm/platform/core/cortex/module.lb
index 8139b55583..c19474814f 100644
--- a/src/modm/platform/core/cortex/module.lb
+++ b/src/modm/platform/core/cortex/module.lb
@@ -11,6 +11,8 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
# -----------------------------------------------------------------------------
+import copy
+
def common_vector_table_location(env):
return env.get(":platform:cortex-m:vector_table_location", "rom")
@@ -72,7 +74,7 @@ def common_memories(env):
:returns: dictionary of memory properties
"""
device = env[":target"]
- memories = listify(device.get_driver("core")["memory"])
+ memories = copy.deepcopy(listify(device.get_driver("core")["memory"]))
# Convert from string to int and add offsets
flash_offset = env.get(":platform:cortex-m:linkerscript.flash_offset", 0)
diff --git a/src/modm/platform/core/stm32/module.lb b/src/modm/platform/core/stm32/module.lb
index 125234452e..679ac609bf 100644
--- a/src/modm/platform/core/stm32/module.lb
+++ b/src/modm/platform/core/stm32/module.lb
@@ -32,10 +32,14 @@ def build(env):
# startup helper code
env.template("startup_platform.c.in")
+ # Generate a list of all on-device peripherals
+ peripherals = uniquify(map(env.filter("modm.fmt.driver"), env[":target"].peripherals))
+ env.substitutions = {"peripherals": peripherals}
+ env.template("peripherals.hpp.in")
+
def post_build(env):
properties = env.query("::cortex-m:linkerscript")
- target = env[":target"].identifier
properties["with_crashcatcher"] = env.has_module(":crashcatcher")
if "backup" in properties["regions"]:
diff --git a/src/modm/platform/gpio/stm32/peripherals.hpp.in b/src/modm/platform/core/stm32/peripherals.hpp.in
similarity index 71%
rename from src/modm/platform/gpio/stm32/peripherals.hpp.in
rename to src/modm/platform/core/stm32/peripherals.hpp.in
index df8a0a20f8..54c487ad30 100644
--- a/src/modm/platform/gpio/stm32/peripherals.hpp.in
+++ b/src/modm/platform/core/stm32/peripherals.hpp.in
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2019, Niklas Hauser
+ * Copyright (c) 2019-2020, Niklas Hauser
*
* This file is part of the modm project.
*
@@ -9,22 +9,20 @@
*/
// ----------------------------------------------------------------------------
-#ifndef MODM_STM32_PERIPHERALS_HPP
-#define MODM_STM32_PERIPHERALS_HPP
+#pragma once
namespace modm::platform
{
+/// @ingroup modm_platform_core
enum class
Peripheral
{
BitBang,
-%% for per in all_peripherals
+%% for per in peripherals
{{ per }},
%% endfor
Syscfg = Sys,
};
}
-
-#endif // MODM_STM32_PERIPHERALS_HPP
diff --git a/src/modm/platform/dma/stm32/module.lb b/src/modm/platform/dma/stm32/module.lb
index 20d50a2d39..655d37d6c6 100644
--- a/src/modm/platform/dma/stm32/module.lb
+++ b/src/modm/platform/dma/stm32/module.lb
@@ -34,7 +34,7 @@ def prepare(module, options):
def build(env):
device = env[":target"]
- properties = device.properties
+ properties = {}
properties["target"] = device.identifier
dma = device.get_driver("dma")
properties["dma"] = dma
@@ -60,7 +60,6 @@ def build(env):
env.substitutions = properties
env.outbasepath = "modm/src/modm/platform/dma"
-
env.template("dma_base.hpp.in")
env.template("dma_hal.hpp.in")
env.template("dma_hal_impl.hpp.in")
diff --git a/src/modm/platform/gpio/at90_tiny_mega/base.hpp.in b/src/modm/platform/gpio/at90_tiny_mega/base.hpp.in
index 48541ade10..9932af2345 100644
--- a/src/modm/platform/gpio/at90_tiny_mega/base.hpp.in
+++ b/src/modm/platform/gpio/at90_tiny_mega/base.hpp.in
@@ -15,10 +15,7 @@
#include "define.h"
#include
-namespace modm
-{
-
-namespace platform
+namespace modm::platform
{
/// @ingroup modm_platform_gpio
@@ -95,7 +92,7 @@ protected:
template< class Pin >
class GpioOpenDrain : public Pin
{
- static Gpio::InputType inputType;
+ static inline Gpio::InputType inputType{Gpio::InputType::Floating};
static_assert(Pin::direction == modm::Gpio::Direction::InOut, "Pin must inherit from modm::GpioIO");
public:
using Output = GpioOpenDrain;
@@ -143,12 +140,6 @@ public:
}
};
-} // namespace platform
-
} // namespace modm
-template< class Pin >
-modm::platform::Gpio::InputType
-modm::platform::GpioOpenDrain::inputType(modm::platform::Gpio::InputType::Floating);
-
#endif // MODM_AVR_GPIO_BASE_HPP
diff --git a/src/modm/platform/gpio/at90_tiny_mega/module.lb b/src/modm/platform/gpio/at90_tiny_mega/module.lb
index 3eae2a69e9..d8dbba9ca1 100644
--- a/src/modm/platform/gpio/at90_tiny_mega/module.lb
+++ b/src/modm/platform/gpio/at90_tiny_mega/module.lb
@@ -101,7 +101,7 @@ def validate(env):
for d in all_drivers:
dname = d["name"].capitalize()
if "instance" in d:
- all_peripherals.extend([dname + i.capitalize() for i in d["instance"]])
+ all_peripherals.extend([dname + i["name"].capitalize() for i in d["instance"]])
else:
all_peripherals.append(dname)
bprops["all_peripherals"] = sorted(list(set(all_peripherals)))
diff --git a/src/modm/platform/gpio/lpc/module.lb b/src/modm/platform/gpio/lpc/module.lb
index 6fae601442..ec11d66a1b 100644
--- a/src/modm/platform/gpio/lpc/module.lb
+++ b/src/modm/platform/gpio/lpc/module.lb
@@ -25,7 +25,7 @@ def build(env):
device = env[":target"]
driver = device.get_driver("gpio")
- properties = device.properties
+ properties = {}
properties["target"] = target = device.identifier
properties["driver"] = driver
diff --git a/src/modm/platform/gpio/sam/module.lb b/src/modm/platform/gpio/sam/module.lb
index 35d5650f0f..089e031773 100644
--- a/src/modm/platform/gpio/sam/module.lb
+++ b/src/modm/platform/gpio/sam/module.lb
@@ -38,9 +38,10 @@ def build(env):
bprops = env.substitutions
device = env[":target"]
driver = device.get_driver("gpio")
+ gpios = copy.deepcopy(driver["gpio"])
peripherals = OrderedDict()
- for gpio in driver["gpio"]:
+ for gpio in gpios:
signals = []
for signal in gpio["signal"]:
signal.update({
@@ -70,14 +71,14 @@ def build(env):
gpio["signal"] = signals
bprops["peripherals"] = OrderedDict(sorted(peripherals.items()))
- bprops["functions"] = sorted(list(set(s["function"] for gpio in driver["gpio"] for s in gpio["signal"])))
+ bprops["functions"] = sorted(list(set(s["function"] for gpio in gpios for s in gpio["signal"])))
bprops["target"] = device.identifier
env.substitutions = bprops
env.outbasepath = "modm/src/modm/platform/gpio"
- bprops["gpios"] = driver["gpio"]
+ bprops["gpios"] = gpios
env.template("config.hpp.in")
env.copy("connector.hpp")
env.copy("pin.hpp")
diff --git a/src/modm/platform/gpio/stm32/base.hpp.in b/src/modm/platform/gpio/stm32/base.hpp.in
index 86208b73e0..81b26420fd 100644
--- a/src/modm/platform/gpio/stm32/base.hpp.in
+++ b/src/modm/platform/gpio/stm32/base.hpp.in
@@ -26,7 +26,7 @@ struct Gpio
enum class
InputType
{
-%% if target["family"] in ["f1"]
+%% if target.family in ["f1"]
Floating = 0x4, ///< floating on input
PullUp = 0x9, ///< pull-up on input
PullDown = 0x8, ///< pull-down on input
@@ -41,7 +41,7 @@ struct Gpio
OutputType
{
PushPull = 0x0, ///< push-pull on output
-%% if target["family"] in ["f1"]
+%% if target.family in ["f1"]
OpenDrain = 0x4, ///< open-drain on output
%% else
OpenDrain = 0x1, ///< open-drain on output
@@ -51,14 +51,14 @@ struct Gpio
enum class
OutputSpeed
{
-%% if target["family"] in ["f1"]
+%% if target.family in ["f1"]
Low = 0x2,
Medium = 0x1,
High = 0x3,
MHz2 = Low,
MHz10 = Medium,
MHz50 = High,
-%% elif target["family"] in ["f0", "f3"]
+%% elif target.family in ["f0", "f3"]
Low = 0,
Medium = 0x1,
High = 0x3,
@@ -99,15 +99,15 @@ struct Gpio
Signal
{
BitBang,
-%% for signal in all_signals
- {{ signal }},
+%% for signal in signal_names
+ {{ signal | modm.fmt }},
%% endfor
};
/// @endcond
protected:
/// @cond
-%% if target["family"] not in ["f1"]
+%% if target.family not in ["f1"]
/// I/O Direction Mode values for this specific pin.
enum class
Mode
diff --git a/src/modm/platform/gpio/stm32/connector_specialized.hpp.in b/src/modm/platform/gpio/stm32/connector_specialized.hpp.in
index 72f2e9295a..845f5ef907 100644
--- a/src/modm/platform/gpio/stm32/connector_specialized.hpp.in
+++ b/src/modm/platform/gpio/stm32/connector_specialized.hpp.in
@@ -34,9 +34,9 @@ static constexpr uint8_t lmb(uint32_t value)
} // namespace detail
// specializations
-%% for remap in driver.remap
+%% for remap in signal_remap
%% set reg = "MAPR" if (remap["position"] | int) < 32 else "MAPR2"
- %% set per = remap | formatPeripheral
+ %% set per = remap | modm.fmt.driver
template< template class... Signals >
struct GpioConnector
{
@@ -51,14 +51,14 @@ struct GpioConnector
{
using namespace detail_gpio_connector;
static constexpr uint32_t id = detail::GpioSignalConnect::id;
- static_assert((id == uint32_t(-1)) || {% for group in remap.group %}(lmb(id) == {{group.id}}UL){% if not loop.last %} || {% else %},{% endif %}{% endfor %}
+ static_assert((id == uint32_t(-1)) || {% for group in remap.group %}(lmb(id) == {{group.id}}ul){% if not loop.last %} || {% else %},{% endif %}{% endfor %}
"This pin set contains conflicting remap groups!\nAvailable groups for {{per}} are:\n"
%% for line in group_map | printSignalMap(per)
"{{line}}\n"
%% endfor
);
if (id != uint32_t(-1)) {
- AFIO->{{reg}} = (AFIO->{{reg}} & ~({{ remap["mask"] }}UL << {{ (remap["position"] | int) % 32 }})) | (lmb(id) << {{ (remap["position"] | int) % 32 }});
+ AFIO->{{reg}} = (AFIO->{{reg}} & ~({{ remap.mask }}ul << {{ (remap.position | int) % 32 }})) | (lmb(id) << {{ (remap.position | int) % 32 }});
}
detail::GpioSignalConnect::connect();
}
diff --git a/src/modm/platform/gpio/stm32/module.lb b/src/modm/platform/gpio/stm32/module.lb
index 2e4814dcbe..2235c00b5d 100644
--- a/src/modm/platform/gpio/stm32/module.lb
+++ b/src/modm/platform/gpio/stm32/module.lb
@@ -12,57 +12,102 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
# -----------------------------------------------------------------------------
-import copy
-from collections import defaultdict, OrderedDict
+def init(module):
+ module.name = ":platform:gpio"
+ module.description = "General Purpose I/O (GPIO)"
+
+def prepare(module, options):
+ device = options[":target"]
+ if not device.has_driver("gpio:stm32*"):
+ return False
+
+ ports = list(map(str.upper, device.gpio.ports))
+ module.add_set_option(
+ EnumerationOption(
+ name="enable_ports",
+ description="Enable clock for these GPIO ports during startup",
+ enumeration=ports),
+ default=ports)
-def port_ranges(gpios):
- ports = {p: (32, 0) for p in set(p["port"] for p in gpios)}
- for gpio in gpios:
- pin = int(gpio["pin"])
- pmin, pmax = ports[gpio["port"]]
- ports[gpio["port"]] = (min(pin, pmin), max(pin, pmax))
+ module.depends(
+ ":architecture:gpio",
+ ":cmsis:device",
+ ":math:utils",
+ ":platform:rcc")
+ return True
+
+def build(env):
+ device = env[":target"]
+ env.substitutions = {
+ "target": device.identifier,
+ "signal_remap": device.gpio.signals_remap,
+ "ranges": device.gpio.ranges,
+ "ports": list(map(str.upper, device.gpio.ports)),
+ "signal_names": uniquify(s["name"] for s in device.gpio.signals_all),
+ "pf": "1" if device.identifier.family in ["l4", "g0", "g4"] else "",
+ }
+ env.outbasepath = "modm/src/modm/platform/gpio"
+
+ for (port, pin) in device.gpio.pins:
+ has_remap = (port+str(pin)) in device.gpio.package_remap
+ subs = {
+ "port": port.upper(), "pin": pin,
+ "exti_irqn": device.core.instance_irq_map("EXTI")[pin][0],
+ "signals": device.gpio.signals_by_name(port, pin),
+ "has_remap": has_remap,
+ }
+ if has_remap:
+ reg, mask = get_remap_command(device.identifier.family, port+str(pin))
+ subs.update({
+ "remap_reg": reg,
+ "remap_mask": mask,
+ "remap_value": device.gpio.package_remap[port+str(pin)]
+ })
+ header_name = "gpio_{}{}.hpp".format(port.upper(), pin)
+ env.template("pin.hpp.in", header_name, substitutions=subs, filters={
+ "to_adc_channel": lambda name: "".join(filter(str.isdigit, name))})
- ports = [{"name": k.upper(), "start": v[0], "width": v[1] - v[0] + 1} for k,v in ports.items()]
- ports.sort(key=lambda p: p["name"])
- return ports
+ env.template("port.hpp.in")
+ env.template("software_port.hpp.in")
+ env.template("set.hpp.in")
+ if "f1" in device.gpio.type:
+ env.template("connector_specialized.hpp.in",
+ substitutions={"group_map": device.gpio.signals_group},
+ filters={"printSignalMap": print_remap_group_table})
+ env.template("base.hpp.in")
+ env.template("unused.hpp.in")
+ if len(env["enable_ports"]):
+ env.template("enable.cpp.in")
-def translate(s):
- return s.replace("_", "").capitalize()
+ env.copy("../common/inverted.hpp", "inverted.hpp")
+ env.copy("../common/connector.hpp", "connector.hpp")
+ env.template("../common/connector_detail.hpp.in", "connector_detail.hpp")
-def get_driver(s):
- name = "None"
- if "driver" in s: name = translate(s["driver"]);
- if "instance" in s: name += translate(s["instance"]);
- return name
-def get_name(s):
- return translate(s["name"])
+# -----------------------------------------------------------------------------
+def format_str(s):
+ return "".join(p.capitalize() for p in str(s).split("_"))
-def extract_signals(signals):
- afs = {}
- for s in signals:
- driver = get_driver(s)
- name = get_name(s)
- key = driver + name
- afs[key] = {"driver": driver, "name": name, "af": s["af"]}
- return afs
+def format_driver(s):
+ return format_str(s.get("driver", "")) + format_str(s.get("instance", ""))
def print_remap_group_table(signal_map, peripheral):
+ from collections import defaultdict
per_signal_map = defaultdict(lambda : defaultdict(list))
afs = []
for key, signals in signal_map.items():
for signal in signals:
- if get_driver(signal) == peripheral:
- for af in signal["af"]:
- per_signal_map[key][af].append(get_name(signal))
- afs.extend(signal["af"])
- afs = sorted(list(set(afs)))
+ if format_driver(signal) == peripheral:
+ for af in signal["group"]:
+ per_signal_map[key][str(af)].append(format_str(signal["name"]))
+ afs.extend(map(str, signal["group"]))
+ afs = uniquify(afs)
array = [[peripheral] + afs]
lengths = [len(s) for s in array[0]]
- for gpio in sorted(per_signal_map, key=lambda p: (p[0], int(p[1:]))):
- blub = [gpio.upper()] + [[] for _ in afs]
- for af, names in per_signal_map[gpio].items():
+ for (port, pin) in sorted(per_signal_map):
+ blub = [port.upper()+str(pin)] + [[] for _ in afs]
+ for af, names in per_signal_map[(port, pin)].items():
for name in names:
blub[array[0].index(af)].append(name)
blub = [",".join(b) if isinstance(b, list) else b for b in blub]
@@ -80,47 +125,6 @@ def print_remap_group_table(signal_map, peripheral):
return lines
-
-def validate_alternate_functions(driver, env):
- """
- For the STM32F1/L1 series
- -------------------------
- These chips can only remap functions in groups, some of them with overlapping
- pins. A unique map must exist for (Signal.driver + Signal.instance + ordered_set(Pins)) -> Remap
- So the combination of Signal driver plus instance and an ordered set of Pins must not map to
- different Remap Groups, otherwise our HAL assumptions are broken.
- """
- success = True
-
- if "f1" in driver["type"]:
- for remap in driver["remap"]:
- af_map = defaultdict(list)
- for group in remap["group"]:
- for signal in group["signal"]:
- af_map[signal["port"] + signal["pin"]].append((group["id"], signal["name"]))
- for pin, afs in af_map.items():
- per = remap["driver"]
- if "instance" in remap: per += remap["instance"];
- gafs = sorted(list(set([a[0] for a in afs])))
- nafs = sorted(list(set([a[1] for a in afs])))
- if len(afs) > 1:
- env.log.debug("P%s: Duplicate groups %s for signal '%s': %s" % (pin.upper(), gafs, per, nafs))
- success = False
- else:
- for gpio in driver["gpio"]:
- if "signal" not in gpio: continue;
- af_map = defaultdict(list)
- for signal in gpio["signal"]:
- if "af" not in signal: continue;
- af_map[get_driver(signal)].append((signal["af"], signal["name"]))
- for per, afs in af_map.items():
- nafs = sorted(list(set([a[0] for a in afs])))
- if len(nafs) > 1:
- env.log.debug("P%s: Duplicate AFs %s for signal '%s': %s" % (gpio["port"].upper() + gpio["pin"], nafs, per, [a[1] for a in afs if a[0] in nafs]))
- success = False
- if not success:
- env.log.debug("Gpio signal validation failed!")
-
def get_remap_command(family, key):
reg = 'SYSCFG->CFGR1'
mask = {
@@ -136,178 +140,3 @@ def get_remap_command(family, key):
if mask is None:
raise ValidateException("Unknown Remap for GPIO: 'P{}'".format(key.upper()))
return (reg, mask)
-
-bprops = {}
-
-# -----------------------------------------------------------------------------
-def init(module):
- module.name = ":platform:gpio"
- module.description = "General Purpose I/O (GPIO)"
-
-def prepare(module, options):
- device = options[":target"]
- if not device.has_driver("gpio:stm32*"):
- return False
-
- bprops["ranges"] = port_ranges(device.get_driver("gpio")["gpio"])
- bprops["ports"] = OrderedDict([(k, i) for i, k in enumerate([p["name"] for p in bprops["ranges"]])])
-
- module.add_set_option(
- EnumerationOption(
- name="enable_ports",
- description="Enable clock for these GPIO ports during startup",
- enumeration=list(bprops["ports"].keys())),
- default=list(bprops["ports"].keys()))
-
- module.depends(
- ":architecture:gpio",
- ":cmsis:device",
- ":math:utils",
- ":platform:rcc")
- return True
-
-def validate(env):
- device = env[":target"]
- driver = device.get_driver("gpio")
- # Not an issue anymore, but kept here for future issues
- # validate_alternate_functions(driver, env)
-
- signal_map = defaultdict(list)
- if "f1" in driver["type"]:
- # map all remaps onto pins
- for remap in driver["remap"]:
- # smap = defaultdict(list)
- for group in remap["group"]:
- for signal in group["signal"]:
- key = signal["port"] + signal["pin"]
- for sig in signal_map[key]:
- if (get_driver(sig) == get_driver(remap) and
- get_name(sig) == get_name(signal)):
- sig["af"].append(group["id"])
- break
- else:
- sig = copy.deepcopy(signal)
- sig["driver"] = remap["driver"]
- sig["af"] = [group["id"]]
- if "instance" in remap:
- sig["instance"] = remap["instance"]
- signal_map[key].append(sig)
- bprops["group_map"] = signal_map
-
- # These are all exti possible vectors: 0, 0_1, 1, 15_10, 2, 2_3, 2_TSC, 3, 4, 4_15, 9_5
- all_exti = {
- "0": [0], "1": [1], "2": [2], "3": [3], "4": [4],
- "0_1": [0,1],
- "2_TSC": [2],
- "2_3": [2,3],
- "4_15": [4,5,6,7,8,9,10,11,12,13,14,15],
- "9_5": [5,6,7,8,9],
- "15_10": [10,11,12,13,14,15],
- }
- extimap = {}
- for vec in [v["name"][4:] for v in device.get_driver("core")["vector"] if "EXTI" in v["name"]]:
- if vec not in all_exti:
- raise ValidateException("Unknown EXTI vector: '{}'".format(vec))
- for num in all_exti[vec]:
- if str(num) in extimap:
- raise ValidateException("Pin '{}' already in EXTI map!".format(str(num)))
- extimap[str(num)] = vec
-
- # Compute the set of remapped pins
- remapped_gpios = {}
- for p in driver["package"][0]["pin"]:
- variant = p.get("variant", "")
- if "remap" in variant: # also matches "remap-default"
- name = p["name"][1:4].strip().lower()
- if len(name) > 2 and not name[2].isdigit():
- name = name[:2]
- remapped_gpios[name] = (variant == "remap") # "remap-default" -> False
-
- all_signals = {}
- for gpio in driver["gpio"]:
- key = gpio["port"] + gpio["pin"]
- raw_signals = gpio["signal"] if "signal" in gpio else []
- for signal in raw_signals:
- if "af" in signal:
- signal["af"] = [signal["af"]]
- else:
- signal["af"] = []
- if key in signal_map:
- raw_signals.extend(signal_map[key])
- gpio["signal"] = raw_signals
- extracted_signals = extract_signals(raw_signals)
- all_signals.update(extracted_signals)
- signal_names = sorted(list(set(s["name"] for s in extracted_signals.values())))
- extracted_signals = OrderedDict([(name, sorted([s for s in extracted_signals.values() if s["name"] == name], key=lambda si:si["name"])) for name in signal_names])
- has_remap = key in remapped_gpios
- bprops[key] = {
- "gpio": gpio,
- "exti_irqn": extimap[gpio["pin"]],
- "signals": extracted_signals,
- "has_remap": has_remap,
- }
- if has_remap:
- reg, mask = get_remap_command(device.identifier.family, key)
- bprops[key].update({
- "remap_reg": reg,
- "remap_mask": mask,
- "remap_value": remapped_gpios[key]
- })
-
- all_peripherals = [s["driver"] for s in all_signals.values()]
- # Signals are not enough, since there are peripherals that don't have signals.
- # Example: STM32F401RE < 64pins: SPI4 cannot be connected to any pins.
- # FIXME: Allow accessing device file more freely
- all_drivers = [d for d in device._properties["driver"] if d["name"] not in ["gpio", "core"]]
- for d in all_drivers:
- dname = translate(d["name"])
- if "instance" in d:
- all_peripherals.extend([dname + translate(i) for i in d["instance"]])
- else:
- all_peripherals.append(dname)
- if "remap" in driver:
- all_peripherals.extend([get_driver(r) for r in driver["remap"]])
- bprops["all_peripherals"] = sorted(list(set(all_peripherals)))
- bprops["all_signals"] = sorted(list(set(s["name"] for s in all_signals.values())))
- bprops["pf"] = "1" if device.identifier["family"] in ["l4", "g0", "g4"] else ""
-
- # Check the max number of ADC instances
- max_adc_instance = max(map(int, device.get_driver("adc").get("instance", [1])))
- if (max_adc_instance > (3 if device.identifier["family"] == "f1" else 5 if device.identifier["family"] == "g4" else 4)):
- raise ValidateException("Too many ADC instances: '{}'".format(max_adc_instance))
-
-def build(env):
- device = env[":target"]
- driver = device.get_driver("gpio")
- properties = device.properties
- properties["target"] = device.identifier
- properties["driver"] = driver
- properties.update(bprops)
-
- env.substitutions = properties
- env.outbasepath = "modm/src/modm/platform/gpio"
- gpio_source = "pin_f1.hpp.in" if "f1" in driver["type"] else "pin.hpp.in"
-
- for gpio in driver["gpio"]:
- po, pi = gpio["port"], gpio["pin"]
- properties.update(bprops[po + pi])
- header_name = "gpio_{}{}.hpp".format(po.upper(), pi)
- env.template(gpio_source, header_name, filters={ "to_adc_channel" : lambda name : "".join(filter(str.isdigit, name)) })
-
- env.template("port.hpp.in")
- env.template("software_port.hpp.in")
- env.template("set.hpp.in")
- if "f1" in driver["type"]:
- env.template("connector_specialized.hpp.in", filters={"formatPeripheral": get_driver, "printSignalMap": print_remap_group_table})
- env.template("base.hpp.in")
- env.template("unused.hpp.in")
- if len(env["enable_ports"]):
- env.template("enable.cpp.in")
-
- env.copy("../common/inverted.hpp", "inverted.hpp")
- env.copy("../common/connector.hpp", "connector.hpp")
- env.template("../common/connector_detail.hpp.in", "connector_detail.hpp")
-
- # FIXME: Move to modm:platform:core!
- env.outbasepath = "modm/src/modm/platform/core"
- env.template("peripherals.hpp.in")
diff --git a/src/modm/platform/gpio/stm32/pin.hpp.in b/src/modm/platform/gpio/stm32/pin.hpp.in
index 68335efc6d..f174d44246 100644
--- a/src/modm/platform/gpio/stm32/pin.hpp.in
+++ b/src/modm/platform/gpio/stm32/pin.hpp.in
@@ -9,9 +9,8 @@
*/
// ----------------------------------------------------------------------------
-%% set port = gpio["port"] | upper
%% set reg = "GPIO" ~ port
-%% set pin = gpio["pin"]
+%% set cr = "CRL" if pin < 8 else "CRH"
#ifndef MODM_STM32_GPIO_PIN_{{ port ~ pin }}_HPP
#define MODM_STM32_GPIO_PIN_{{ port ~ pin }}_HPP
@@ -47,29 +46,36 @@ public:
static constexpr bool isInverted = false;
static constexpr Port port = Port::{{port}}; ///< Port name
static constexpr uint8_t pin = {{pin}}; ///< Pin number
- static constexpr IRQn_Type ExternalInterruptIRQ = EXTI{{ exti_irqn }}_IRQn;
+ static constexpr IRQn_Type ExternalInterruptIRQ = {{ exti_irqn }}_IRQn;
protected:
+ /// Port Number.
+ static constexpr uint8_t port_nr = uint8_t(port);
/// Bitmask for registers that contain a 1bit value for every pin.
static constexpr uint16_t mask = 0x1 << pin;
+%% if target.family in ["f1"]
+ static constexpr uint8_t cr_pin = pin % 8;
+ /// Bitmask for the configuration register with a 4bit mask.
+ static constexpr uint32_t mask4 = 0xf << (cr_pin * 4);
+%% else
/// Bitmask for registers that contain a 2bit value for every pin.
static constexpr uint32_t mask2 = 0x3 << (pin * 2);
- /// Port Number.
- static constexpr uint8_t port_nr = uint8_t(port);
/// Alternate Function register id. 0 for pin 0-7. 1 for pin 8-15.
static constexpr uint8_t af_id = pin / 8;
/// Alternate Function offset.
static constexpr uint8_t af_offset = (pin * 4) % 32;
/// Alternate Function register mask.
static constexpr uint32_t af_mask = 0xf << af_offset;
+%% endif
public:
/// @cond
+%% if target.family not in ["f1"]
inline static void setAlternateFunction(uint8_t af) {
{{reg}}->AFR[af_id] = ({{reg}}->AFR[af_id] & ~af_mask) | ((af & 0xf) << af_offset);
{{reg}}->MODER = ({{reg}}->MODER & ~mask2) | (i(Mode::AlternateFunction) << (pin * 2));
}
-
+%% endif
/// Enable Analog Mode which is needed to use this pin as an ADC input.
inline static void setAnalogInput() { PinSet::setAnalogInput(); }
/// @endcond
@@ -124,7 +130,9 @@ public:
constexpr uint8_t bit_pos = (pin & 0b0011) << 2;
constexpr uint16_t syscfg_mask = (0b1111) << bit_pos;
constexpr uint16_t syscfg_value = (port_nr & (0b1111)) << bit_pos;
-%% if target.family in ["g0"]
+%% if target.family in ["f1"]
+ AFIO->EXTICR[index] = (AFIO->EXTICR[index] & ~syscfg_mask) | syscfg_value;
+%% elif target.family in ["g0"]
EXTI->EXTICR[index] = (EXTI->EXTICR[index] & ~syscfg_mask) | syscfg_value;
%% else
SYSCFG->EXTICR[index] = (SYSCFG->EXTICR[index] & ~syscfg_mask) | syscfg_value;
@@ -168,6 +176,14 @@ public:
// GpioIO
// start documentation inherited
inline static Direction getDirection() {
+%% if target.family in ["f1"]
+ uint32_t mode = ({{reg}}->{{cr}} & mask4);
+ if ((mode == 0) or (mode > (uint32_t(0b1001) << (cr_pin * 4))))
+ return Direction::Special;
+ if (mode > 0)
+ return Direction::Out;
+ return Direction::In;
+%% else
uint32_t mode = ({{reg}}->MODER & mask2);
if (mode == (i(Mode::Input) << pin * 2)) {
return Direction::In;
@@ -176,16 +192,18 @@ public:
return Direction::Out;
}
return Direction::Special;
+%% endif
}
// end documentation inherited
inline static void lock() { PinSet::lock(); }
inline static void disconnect() {
setInput(InputType::Floating);
+%% if target.family not in ["f1"]
{{reg}}->AFR[af_id] &= ~af_mask;
- %% if target["family"] in ["l4"] and target["name"] in ["71", "75", "76", "85", "86"]
+ %% if target.family in ["l4"] and target.name in ["71", "75", "76", "85", "86"]
{{reg}}->ASCR &= ~mask;
%% endif
-
+%% endif
}
public:
@@ -193,9 +211,9 @@ public:
/// @{
/// Connect to any software peripheral
using BitBang = GpioSignal;
- %% for name, group in signals.items()
- /// Connect to {% for sig in group %}{{ sig.driver }}{{ "" if loop.last else " or "}}{% endfor %}
- using {{ name }} = GpioSignal;
+ %% for sname, sgroup in signals.items() | sort
+ /// Connect to {% for sig in sgroup %}{{ sig | modm.fmt.driver }}{{ "" if loop.last else " or "}}{% endfor %}
+ using {{ sname | modm.fmt }} = GpioSignal;
%% endfor
/// @}
#endif
@@ -206,14 +224,14 @@ public:
(peripheral == Peripheral::BitBang),
"Gpio{{ port ~ pin }}::BitBang only connects to software drivers!");
};
- %% for signal_name, signal_group in signals.items()
+ %% for sname, sgroup in signals.items() | sort
template< Peripheral peripheral >
- struct {{ signal_name }} { static void connect();
+ struct {{ sname | modm.fmt }} { static void connect();
static_assert(
- %% for signal in signal_group
- (peripheral == Peripheral::{{ signal.driver }}){% if loop.last %},{% else %} ||{% endif %}
+ %% for signal in sgroup
+ (peripheral == Peripheral::{{ signal | modm.fmt.driver }}){% if loop.last %},{% else %} or{% endif %}
%% endfor
- "Gpio{{ port ~ pin }}::{{ signal_name }} only connects to {% for signal in signal_group %}{{signal.driver}}{% if not loop.last %} or {% endif %}{% endfor %}!");
+ "Gpio{{ port ~ pin }}::{{ sname | modm.fmt }} only connects to {% for signal in sgroup %}{{signal | modm.fmt.driver}}{% if not loop.last %} or {% endif %}{% endfor %}!");
};
%% endfor
/// @endcond
@@ -233,30 +251,45 @@ struct Gpio{{ port ~ pin }}::BitBang
static constexpr int af = -1;
inline static void connect() {}
};
-%% for signal_group in signals.values()
- %% for signal in signal_group
+%% for sname, sgroup in signals.items() | sort
+ %% for signal in sgroup
template<>
-struct Gpio{{ port ~ pin }}::{{ signal.name }}
+struct Gpio{{ port ~ pin }}::{{ sname | modm.fmt }}
{
using Gpio = Gpio{{ port ~ pin }};
- static constexpr Gpio::Signal Signal = Gpio::Signal::{{ signal.name }};
- static constexpr int af = {{ signal.af[0] if signal.af | length else -1 }};
+ static constexpr Gpio::Signal Signal = Gpio::Signal::{{ sname | modm.fmt }};
+ %% if "group" in signal
+ static constexpr uint32_t Groups = {% for gid in signal.group %}(1ul << {{ gid }}){% if not loop.last %} | {% endif %}{% endfor %};
+ %% else
+ static constexpr uint32_t Groups{-1ul};
+ %% endif
+ static constexpr int af = {{ signal.af if "af" in signal else -1 }};
inline static void
connect()
{
- %% if signal.af | length
- setAlternateFunction({{ signal.af[0] }});
- %% elif ( signal.driver.startswith("Adc") or signal.driver.startswith("Dac")
- or signal.driver.startswith("Comp") )
+ %% if target.family in ["f1"]
+ %% if signal.is_analog
+ setAnalogInput();
+ %% else
+ uint32_t cr = {{reg}}->{{cr}};
+ if (cr & (0b0011UL << (cr_pin * 4))) {
+ {{reg}}->{{cr}} = cr | (0b1000UL << (cr_pin * 4));
+ }
+ %% endif
+ %% else
+ %% if "af" in signal
+ setAlternateFunction({{ signal.af }});
+ %% elif signal.is_analog
disconnect();
setAnalogInput();
+ %% endif
%% endif
}
};
- %% if signal.driver.startswith("Adc") and signal.name.startswith("In")
+ %% if "analog_channel" in signal
template<>
constexpr int8_t
-Gpio{{ port ~ pin }}::AdcChannel = {{ signal.name | to_adc_channel }};
+Gpio{{ port ~ pin }}::AdcChannel = {{ signal.analog_channel }};
%% endif
%% if signal.driver.startswith("Dac") and signal.name.startswith("Out")
diff --git a/src/modm/platform/gpio/stm32/pin_f1.hpp.in b/src/modm/platform/gpio/stm32/pin_f1.hpp.in
deleted file mode 100644
index 469e5d7661..0000000000
--- a/src/modm/platform/gpio/stm32/pin_f1.hpp.in
+++ /dev/null
@@ -1,235 +0,0 @@
-/*
- * Copyright (c) 2017-2018, Niklas Hauser
- *
- * This file is part of the modm project.
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/.
- */
-// ----------------------------------------------------------------------------
-
-%% set port = gpio["port"] | upper
-%% set reg = "GPIO" ~ port
-%% set pin = gpio["pin"] | int
-%% set cr = "CRL" if pin < 8 else "CRH"
-
-#ifndef MODM_STM32_GPIO_PIN_{{ port ~ pin }}_HPP
-#define MODM_STM32_GPIO_PIN_{{ port ~ pin }}_HPP
-
-#include "../device.hpp"
-#include "base.hpp"
-#include "set.hpp"
-
-
-namespace modm
-{
-
-namespace platform
-{
-
-/// @cond
-class Gpio{{ port ~ pin }};
-using GpioOutput{{ port ~ pin }} = Gpio{{ port ~ pin }};
-using GpioInput{{ port ~ pin }} = Gpio{{ port ~ pin }};
-/// @endcond
-
-/// IO class for Pin {{port ~ pin}}
-/// @ingroup modm_platform_gpio
-struct Gpio{{ port ~ pin }} : public Gpio, ::modm::GpioIO
-{
- template
- friend class GpioSet;
- using PinSet = GpioSet;
- friend class Adc1; friend class Adc2; friend class Adc3;
-public:
- using Output = Gpio{{ port ~ pin }};
- using Input = Gpio{{ port ~ pin }};
- using IO = Gpio{{ port ~ pin }};
- using Type = Gpio{{ port ~ pin }};
- static constexpr bool isInverted = false;
- static constexpr Port port = Port::{{port}}; ///< Port name
- static constexpr uint8_t pin = {{pin}}; ///< Pin Number
- static constexpr IRQn_Type ExternalInterruptIRQ = EXTI{{ exti_irqn }}_IRQn;
-
-protected:
- /// Bitmask for registers that contain a 1bit value for every pin.
- static constexpr uint16_t mask = 0x1 << pin;
- static constexpr uint8_t cr_pin = {{ pin }} % 8;
- /// Bitmask for the configuration register with a 4bit mask.
- static constexpr uint32_t mask4 = 0xf << (cr_pin * 4);
- /// Port Number.
- static constexpr uint8_t port_nr = static_cast(port);
-
-public:
- /// @cond
- /// Enable Analog Mode which is needed to use this pin as an ADC input.
- inline static void setAnalogInput() { PinSet::setAnalogInput(); }
- /// @endcond
-
-public:
- // GpioOutput
- // start documentation inherited
- inline static void setOutput() { PinSet::setOutput(); }
- inline static void setOutput(bool status) { PinSet::setOutput(status); }
- inline static void set() { PinSet::set(); }
- inline static void set(bool status) { PinSet::set(status); }
- inline static void reset() { PinSet::reset(); }
- inline static void toggle() {
- if (isSet()) reset();
- else set();
- }
- inline static bool isSet() { return ({{reg}}->ODR & mask); }
- // stop documentation inherited
- inline static void configure(OutputType type, OutputSpeed speed = OutputSpeed::MHz50) { PinSet::configure(type, speed); }
- inline static void setOutput(OutputType type, OutputSpeed speed = OutputSpeed::MHz50) { PinSet::setOutput(type, speed); }
- // GpioInput
- // start documentation inherited
- inline static void setInput() { PinSet::setInput(); }
- inline static bool read() { return ({{reg}}->IDR & mask); }
- // end documentation inherited
- inline static void configure(InputType type) { PinSet::configure(type); }
- inline static void setInput(InputType type) { PinSet::setInput(type); }
- // External Interrupts
- // Warning: This will disable any previously enabled interrupt which is
- // routed to the same interupt line, e.g. PA3 will disable PB3.
- // This is a hardware limitation by the STM32 EXTI.
- inline static void enableExternalInterrupt()
- {
- // PA[x], x = 0 .. 3 maps to EXTICR[0]
- // PA[x], x = 4 .. 7 maps to EXTICR[1]
- // PA[x], x = 8 .. 11 maps to EXTICR[2]
- // PA[x], x = 12 .. 15 maps to EXTICR[3]
- // => bit3 and bit2 (mask 0b1100) specify the register
- // => bit1 and bit0 (mask 0b0011) specify the bit position
- constexpr uint8_t index = (pin & 0b1100) >> 2;
- constexpr uint8_t bit_pos = (pin & 0b0011) << 2;
- constexpr uint16_t syscfg_mask = (0b1111) << bit_pos;
- constexpr uint16_t syscfg_value = (port_nr & (0b1111)) << bit_pos;
- AFIO->EXTICR[index] = (AFIO->EXTICR[index] & ~syscfg_mask) | syscfg_value;
- EXTI->IMR |= mask;
- }
- inline static void disableExternalInterrupt() { EXTI->IMR &= ~mask; }
- inline static void enableExternalInterruptVector(const uint32_t priority)
- {
- NVIC_SetPriority(ExternalInterruptIRQ, priority);
- NVIC_EnableIRQ(ExternalInterruptIRQ);
- }
- inline static void disableExternalInterruptVector() { NVIC_DisableIRQ(ExternalInterruptIRQ); }
- inline static void
- setInputTrigger(const InputTrigger trigger)
- {
- switch (trigger)
- {
- case InputTrigger::RisingEdge:
- EXTI->RTSR |= mask;
- EXTI->FTSR &= ~mask;
- break;
- case InputTrigger::FallingEdge:
- EXTI->RTSR &= ~mask;
- EXTI->FTSR |= mask;
- break;
- case InputTrigger::BothEdges:
- EXTI->RTSR |= mask;
- EXTI->FTSR |= mask;
- break;
- }
- }
- inline static bool getExternalInterruptFlag() { return (EXTI->PR & mask); }
- inline static void acknowledgeExternalInterruptFlag() { EXTI->PR = mask; }
- // GpioIO
- // start documentation inherited
- inline static Direction getDirection() {
- uint32_t mode = ({{reg}}->{{cr}} & mask4);
- if ((mode == 0) or (mode > (uint32_t(0b1001) << (cr_pin * 4))))
- return Direction::Special;
- if (mode > 0)
- return Direction::Out;
- return Direction::In;
- }
- // end documentation inherited
- inline static void lock() { PinSet::lock(); }
- inline static void disconnect() { setInput(); };
-
-public:
-#ifdef __DOXYGEN__
- /// @{
- /// Connect to any software peripheral
- using BitBang = GpioSignal;
- %% for name, group in signals.items()
- /// Connect to {% for sig in group %}{{ sig.driver }}{{ "" if loop.last else " or "}}{% endfor %}
- using {{ name }} = GpioSignal;
- %% endfor
- /// @}
-#endif
- /// @cond
- template< Peripheral peripheral >
- struct BitBang { static void connect();
- static_assert(
- (peripheral == Peripheral::BitBang),
- "Gpio{{ port ~ pin }}::BitBang only connects to software drivers!");
- };
- %% for signal_name, signal_group in signals.items()
- template< Peripheral peripheral >
- struct {{ signal_name }} { static void connect();
- static_assert(
- %% for signal in signal_group
- (peripheral == Peripheral::{{ signal.driver }}){% if loop.last %},{% else %} ||{% endif %}
- %% endfor
- "Gpio{{ port ~ pin }}::{{ signal_name }} only connects to {% for signal in signal_group %}{{signal.driver}}{% if not loop.last %} or {% endif %}{% endfor %}!");
- };
- %% endfor
- /// @endcond
-private:
- template< Peripheral peripheral >
- static constexpr int8_t AdcChannel = -1;
-};
-
-/// @cond
-template<>
-struct Gpio{{ port ~ pin }}::BitBang
-{
- using Gpio = Gpio{{ port ~ pin }};
- static constexpr Gpio::Signal Signal = Gpio::Signal::BitBang;
- inline static void connect() {}
-};
-%% for _, signal_group in signals.items()
- %% for signal in signal_group
-template<>
-struct Gpio{{ port ~ pin }}::{{ signal.name }}
-{
- %% if signal.af | length
- static constexpr uint32_t Groups = {% for af in signal.af %}(1UL << {{ af }}){% if not loop.last %} | {% endif %}{% endfor %};
- %% else
- static constexpr uint32_t Groups = uint32_t(-1);
- %% endif
- using Gpio = Gpio{{ port ~ pin }};
- static constexpr Gpio::Signal Signal = Gpio::Signal::{{ signal.name }};
- inline static void
- connect()
- {
- %% if signal.driver.startswith("Adc")
- setAnalogInput();
- %% else
- uint32_t cr = {{reg}}->{{cr}};
- if (cr & (0b0011UL << (cr_pin * 4))) {
- {{reg}}->{{cr}} = cr | (0b1000UL << (cr_pin * 4));
- }
- %% endif
- }
-};
- %% if signal.driver.startswith("Adc") and signal.name.startswith("In")
-template<>
-constexpr int8_t
-Gpio{{ port ~ pin }}::AdcChannel = {{ signal.name | to_adc_channel }};
- %% endif
- %% endfor
-
-%% endfor
-/// @endcond
-
-} // namespace platform
-
-} // namespace modm
-
-#endif // MODM_STM32_GPIO_{{ port ~ pin }}_HPP
diff --git a/src/modm/platform/gpio/stm32/port.hpp.in b/src/modm/platform/gpio/stm32/port.hpp.in
index 5254494334..848db241b8 100644
--- a/src/modm/platform/gpio/stm32/port.hpp.in
+++ b/src/modm/platform/gpio/stm32/port.hpp.in
@@ -17,10 +17,7 @@
#include
#include
-namespace modm
-{
-
-namespace platform
+namespace modm::platform
{
/// @cond
@@ -57,8 +54,8 @@ public:
static PortType isSet()
{
uint16_t r{0};
-%% for port, id in ports.items()
- if constexpr (mask({{id}})) r = (GPIO{{port}}->ODR & mask({{id}})) ^ inverted({{id}});
+%% for port in ports
+ if constexpr (mask({{loop.index0}})) r = (GPIO{{port}}->ODR & mask({{loop.index0}})) ^ inverted({{loop.index0}});
%% endfor
if constexpr (getDataOrder() == modm::GpioPort::DataOrder::Reversed)
return bitReverse(r) >> StartPinReversed;
@@ -68,8 +65,8 @@ public:
static PortType read()
{
uint16_t r{0};
-%% for port, id in ports.items()
- if constexpr (mask({{id}})) r = (GPIO{{port}}->IDR & mask({{id}})) ^ inverted({{id}});
+%% for port in ports
+ if constexpr (mask({{loop.index0}})) r = (GPIO{{port}}->IDR & mask({{loop.index0}})) ^ inverted({{loop.index0}});
%% endfor
if constexpr (getDataOrder() == modm::GpioPort::DataOrder::Reversed)
return bitReverse(r) >> StartPinReversed;
@@ -82,9 +79,9 @@ public:
if constexpr (getDataOrder() == modm::GpioPort::DataOrder::Reversed)
p = bitReverse(uint16_t(uint16_t(data) << StartPinReversed));
else p = uint16_t(data) << StartPin;
-%% for port, id in ports.items()
- if constexpr (mask({{id}})) { p ^= inverted({{id}});
- GPIO{{port}}->BSRR = ((~p & mask({{id}})) << 16) | (p & mask({{id}}));
+%% for port in ports
+ if constexpr (mask({{loop.index0}})) { p ^= inverted({{loop.index0}});
+ GPIO{{port}}->BSRR = ((~p & mask({{loop.index0}})) << 16) | (p & mask({{loop.index0}}));
}
%% endfor
}
@@ -94,10 +91,10 @@ public:
// ------ Port Width Information ------
%% for port in ranges
template<>
-struct GpioPortInfo
+struct GpioPortInfo
{
- static constexpr int8_t Width = {{port["width"]}};
- static constexpr int8_t StartPin = {{port["start"]}};
+ static constexpr int8_t Width = {{port.width}};
+ static constexpr int8_t StartPin = {{port.start}};
static constexpr int8_t EndPin = StartPin + Width;
template< uint8_t QueryStartPin, int8_t QueryWidth >
@@ -107,12 +104,12 @@ struct GpioPortInfo
static constexpr bool isReversed = QueryWidth < 0;
static constexpr int8_t width = isNormal ? QueryWidth : -QueryWidth;
static_assert(isReversed or width <= Width,
- "GpioPort Width out of bounds! Maximum is {{port["width"]}}.");
+ "GpioPort Width out of bounds! Maximum is {{port.width}}.");
static_assert(isReversed or (QueryStartPin + QueryWidth <= EndPin),
- "GpioPort StartPin + Width out of bounds! Maximum is {{port["start"] + port["width"] - 1}}.");
+ "GpioPort StartPin + Width out of bounds! Maximum is {{port.start + port.width - 1}}.");
static_assert(isNormal or (StartPin <= QueryStartPin + QueryWidth + 1),
- "GpioPort StartPin - Width out of bounds! Minimum is {{port["start"]}}.");
+ "GpioPort StartPin - Width out of bounds! Minimum is {{port.start}}.");
};
};
%% endfor
@@ -143,8 +140,6 @@ struct GpioSetShim : public GpioSet<
%% endfor
/// @endcond
-} // namespace platform
-
-} // namespace modm
+} // namespace modm::platform
#endif // MODM_STM32_GPIO_PORT_HPP
diff --git a/src/modm/platform/gpio/stm32/set.hpp.in b/src/modm/platform/gpio/stm32/set.hpp.in
index 9b643af7ee..21d81d535e 100644
--- a/src/modm/platform/gpio/stm32/set.hpp.in
+++ b/src/modm/platform/gpio/stm32/set.hpp.in
@@ -45,7 +45,7 @@ protected:
if (masks[id] & (1 << ii)) r |= (uint32_t(value) << (ii * 2));
return r;
}
-%% if target["family"] in ["f1"]
+%% if target.family in ["f1"]
static constexpr uint64_t mask4(uint8_t id, uint8_t value = 0b1111) {
uint64_t r{0};
for (int ii=0; ii<16; ii++)
@@ -70,11 +70,11 @@ public:
public:
static void setOutput()
{
-%% if target["family"] in ["f1"]
+%% if target.family in ["f1"]
configure(OutputType::PushPull);
%% else
- %% for port, id in ports.items()
- if constexpr (mask({{id}})) GPIO{{port}}->MODER = (GPIO{{port}}->MODER & ~mask2({{id}})) | mask2({{id}}, i(Mode::Output));
+ %% for port in ports
+ if constexpr (mask({{loop.index0}})) GPIO{{port}}->MODER = (GPIO{{port}}->MODER & ~mask2({{loop.index0}})) | mask2({{loop.index0}}, i(Mode::Output));
%% endfor
%% endif
}
@@ -88,23 +88,23 @@ public:
static void setOutput(OutputType type, OutputSpeed speed = OutputSpeed::MHz50)
{
configure(type, speed);
-%% if target["family"] not in ["f1"]
+%% if target.family not in ["f1"]
setOutput();
%% endif
}
static void configure(OutputType type, OutputSpeed speed = OutputSpeed::MHz50)
{
-%% if target["family"] in ["f1"]
- %% for port, id in ports.items()
- if constexpr (crl({{id}})) GPIO{{port}}->CRL = (GPIO{{port}}->CRL & ~crl({{id}})) | ((i(type) | i(speed)) * crl({{id}}, 0b0001));
- if constexpr (crh({{id}})) GPIO{{port}}->CRH = (GPIO{{port}}->CRH & ~crh({{id}})) | ((i(type) | i(speed)) * crh({{id}}, 0b0001));
+%% if target.family in ["f1"]
+ %% for port in ports
+ if constexpr (crl({{loop.index0}})) GPIO{{port}}->CRL = (GPIO{{port}}->CRL & ~crl({{loop.index0}})) | ((i(type) | i(speed)) * crl({{loop.index0}}, 0b0001));
+ if constexpr (crh({{loop.index0}})) GPIO{{port}}->CRH = (GPIO{{port}}->CRH & ~crh({{loop.index0}})) | ((i(type) | i(speed)) * crh({{loop.index0}}, 0b0001));
%% endfor
%% else
- %% for port, id in ports.items()
- if constexpr (mask({{id}})) {
- GPIO{{port}}->OSPEEDR = (GPIO{{port}}->OSPEEDR & ~mask2({{id}})) | (i(speed) * mask2({{id}}, 0b01));
- GPIO{{port}}->OTYPER = (GPIO{{port}}->OTYPER & ~mask({{id}})) | (i(type) ? mask({{id}}) : 0);
+ %% for port in ports
+ if constexpr (mask({{loop.index0}})) {
+ GPIO{{port}}->OSPEEDR = (GPIO{{port}}->OSPEEDR & ~mask2({{loop.index0}})) | (i(speed) * mask2({{loop.index0}}, 0b01));
+ GPIO{{port}}->OTYPER = (GPIO{{port}}->OTYPER & ~mask({{loop.index0}})) | (i(type) ? mask({{loop.index0}}) : 0);
}
%% endfor
%% endif
@@ -112,14 +112,14 @@ public:
static void setInput()
{
-%% if target["family"] in ["f1"]
+%% if target.family in ["f1"]
configure(InputType::Floating);
%% else
- %% for port, id in ports.items()
- if constexpr (mask({{id}})) {
- GPIO{{port}}->MODER &= ~mask2({{id}});
- GPIO{{port}}->OTYPER &= ~mask({{id}});
- GPIO{{port}}->OSPEEDR &= ~mask2({{id}});
+ %% for port in ports
+ if constexpr (mask({{loop.index0}})) {
+ GPIO{{port}}->MODER &= ~mask2({{loop.index0}});
+ GPIO{{port}}->OTYPER &= ~mask({{loop.index0}});
+ GPIO{{port}}->OSPEEDR &= ~mask2({{loop.index0}});
}
%% endfor
%% endif
@@ -128,23 +128,23 @@ public:
static void setInput(InputType type)
{
configure(type);
-%% if target["family"] not in ["f1"]
+%% if target.family not in ["f1"]
setInput();
%% endif
}
static void setAnalogInput()
{
-%% if target["family"] in ["f1"]
- %% for port, id in ports.items()
- if constexpr (crl({{id}})) GPIO{{port}}->CRL &= ~crl({{id}});
- if constexpr (crh({{id}})) GPIO{{port}}->CRH &= ~crh({{id}});
+%% if target.family in ["f1"]
+ %% for port in ports
+ if constexpr (crl({{loop.index0}})) GPIO{{port}}->CRL &= ~crl({{loop.index0}});
+ if constexpr (crh({{loop.index0}})) GPIO{{port}}->CRH &= ~crh({{loop.index0}});
%% endfor
%% else
- %% for port, id in ports.items()
- if constexpr (mask({{id}})) GPIO{{port}}->MODER |= mask2({{id}}, i(Mode::Analog));
- %% if target["family"] in ["l4"] and target["name"] in ["71", "75", "76", "85", "86"]
- if constexpr (mask({{id}})) GPIO{{port}}->ASCR |= mask({{id}});
+ %% for port in ports
+ if constexpr (mask({{loop.index0}})) GPIO{{port}}->MODER |= mask2({{loop.index0}}, i(Mode::Analog));
+ %% if target.family in ["l4"] and target["name"] in ["71", "75", "76", "85", "86"]
+ if constexpr (mask({{loop.index0}})) GPIO{{port}}->ASCR |= mask({{loop.index0}});
%% endif
%% endfor
%% endif
@@ -152,16 +152,16 @@ public:
static void configure(InputType type)
{
-%% if target["family"] in ["f1"]
- %% for port, id in ports.items()
- if constexpr (crl({{id}})) GPIO{{port}}->CRL = (GPIO{{port}}->CRL & ~crl({{id}})) | ((i(type) & 0xc) * crl({{id}}, 0b0001));
- if constexpr (crh({{id}})) GPIO{{port}}->CRH = (GPIO{{port}}->CRH & ~crh({{id}})) | ((i(type) & 0xc) * crh({{id}}, 0b0001));
- if constexpr (mask({{id}})) GPIO{{port}}->BSRR = mask({{id}}) << ((type == InputType::PullUp) ? 0 : 16);
+%% if target.family in ["f1"]
+ %% for port in ports
+ if constexpr (crl({{loop.index0}})) GPIO{{port}}->CRL = (GPIO{{port}}->CRL & ~crl({{loop.index0}})) | ((i(type) & 0xc) * crl({{loop.index0}}, 0b0001));
+ if constexpr (crh({{loop.index0}})) GPIO{{port}}->CRH = (GPIO{{port}}->CRH & ~crh({{loop.index0}})) | ((i(type) & 0xc) * crh({{loop.index0}}, 0b0001));
+ if constexpr (mask({{loop.index0}})) GPIO{{port}}->BSRR = mask({{loop.index0}}) << ((type == InputType::PullUp) ? 0 : 16);
%% endfor
%% else
- %% for port, id in ports.items()
- if constexpr (mask({{id}})) {
- GPIO{{port}}->PUPDR = (GPIO{{port}}->PUPDR & ~mask2({{id}})) | (i(type) * mask2({{id}}, 0b01));
+ %% for port in ports
+ if constexpr (mask({{loop.index0}})) {
+ GPIO{{port}}->PUPDR = (GPIO{{port}}->PUPDR & ~mask2({{loop.index0}})) | (i(type) * mask2({{loop.index0}}, 0b01));
}
%% endfor
%% endif
@@ -169,8 +169,8 @@ public:
static void set()
{
-%% for port, id in ports.items()
- if constexpr (mask({{id}})) GPIO{{port}}->BSRR = (inverted({{id}}) << 16) | (mask({{id}}) & ~inverted({{id}}));
+%% for port in ports
+ if constexpr (mask({{loop.index0}})) GPIO{{port}}->BSRR = (inverted({{loop.index0}}) << 16) | (mask({{loop.index0}}) & ~inverted({{loop.index0}}));
%% endfor
}
@@ -182,17 +182,17 @@ public:
static void reset()
{
-%% for port, id in ports.items()
- if constexpr (mask({{id}})) GPIO{{port}}->BSRR = ((uint32_t(mask({{id}})) & ~inverted({{id}})) << 16) | inverted({{id}});
+%% for port in ports
+ if constexpr (mask({{loop.index0}})) GPIO{{port}}->BSRR = ((uint32_t(mask({{loop.index0}})) & ~inverted({{loop.index0}})) << 16) | inverted({{loop.index0}});
%% endfor
}
static void toggle()
{
-%% for port, id in ports.items()
- if constexpr (mask({{id}})) {
- uint32_t are_set = (GPIO{{port}}->ODR & mask({{id}}));
- uint32_t are_reset = mask({{id}}) ^ are_set;
+%% for port in ports
+ if constexpr (mask({{loop.index0}})) {
+ uint32_t are_set = (GPIO{{port}}->ODR & mask({{loop.index0}}));
+ uint32_t are_reset = mask({{loop.index0}}) ^ are_set;
GPIO{{port}}->BSRR = (are_set << 16) | are_reset;
}
%% endfor
@@ -200,11 +200,11 @@ public:
static void lock()
{
-%% for port, id in ports.items()
- if constexpr (mask({{id}})) {
- GPIO{{port}}->LCKR = 0x10000 | mask({{id}});
- GPIO{{port}}->LCKR = 0x00000 | mask({{id}});
- GPIO{{port}}->LCKR = 0x10000 | mask({{id}});
+%% for port in ports
+ if constexpr (mask({{loop.index0}})) {
+ GPIO{{port}}->LCKR = 0x10000 | mask({{loop.index0}});
+ GPIO{{port}}->LCKR = 0x00000 | mask({{loop.index0}});
+ GPIO{{port}}->LCKR = 0x10000 | mask({{loop.index0}});
(void) GPIO{{port}}->LCKR;
}
%% endfor
diff --git a/src/modm/platform/gpio/stm32/software_port.hpp.in b/src/modm/platform/gpio/stm32/software_port.hpp.in
index 093e774063..4e3e8832ec 100644
--- a/src/modm/platform/gpio/stm32/software_port.hpp.in
+++ b/src/modm/platform/gpio/stm32/software_port.hpp.in
@@ -66,7 +66,8 @@ public:
static PortType isSet()
{
PortType r{0};
-%% for port, id in ports.items()
+%% for port in ports
+ %% set id = loop.index0
if constexpr (mask({{id}})) {
const uint16_t p = (GPIO{{port}}->ODR & mask({{id}})) ^ inverted({{id}});
%% for pos in range(32)
@@ -79,7 +80,8 @@ public:
static void write(PortType data)
{
-%% for port, id in ports.items()
+%% for port in ports
+ %% set id = loop.index0
if constexpr (mask({{id}})) { uint32_t p{0};
%% for pos in range(32)
if constexpr ({{pos}} < width) if constexpr (constexpr auto pos = shift_mask({{id}}, {{pos}}); pos >= 0) p |= (data & (1ul << {{pos}})) ? (1ul << pos) : (1ul << (pos + 16));
@@ -93,7 +95,8 @@ public:
static PortType read()
{
PortType r{0};
-%% for port, id in ports.items()
+%% for port in ports
+ %% set id = loop.index0
if constexpr (mask({{id}})) {
const uint16_t p = (GPIO{{port}}->IDR & mask({{id}})) ^ inverted({{id}});
%% for pos in range(32)
diff --git a/src/modm/platform/gpio/stm32/unused.hpp.in b/src/modm/platform/gpio/stm32/unused.hpp.in
index c37b665c16..eea23970ca 100644
--- a/src/modm/platform/gpio/stm32/unused.hpp.in
+++ b/src/modm/platform/gpio/stm32/unused.hpp.in
@@ -111,12 +111,12 @@ public:
public:
/// @cond
-%% for name in all_signals
+%% for name in signal_names
template< Peripheral _ >
- struct {{ name }}
+ struct {{ name | modm.fmt }}
{
using Gpio = GpioUnused;
- static constexpr Gpio::Signal Signal = Gpio::Signal::{{ name }};
+ static constexpr Gpio::Signal Signal = Gpio::Signal::{{ name | modm.fmt }};
static void connect() {}
};
%% endfor
diff --git a/src/modm/platform/i2c/at90_tiny_mega/module.lb b/src/modm/platform/i2c/at90_tiny_mega/module.lb
index 30179ffe4e..80adff4bb0 100644
--- a/src/modm/platform/i2c/at90_tiny_mega/module.lb
+++ b/src/modm/platform/i2c/at90_tiny_mega/module.lb
@@ -32,16 +32,7 @@ def prepare(module, options):
return True
def build(env):
- device = env[":target"]
- driver = device.get_driver("i2c")
-
- properties = device.properties
- properties["target"] = device.identifier
- properties["driver"] = driver
-
- env.substitutions = properties
env.outbasepath = "modm/src/modm/platform/i2c"
-
env.template("i2c.hpp.in")
env.template("i2c_master.hpp.in")
env.template("i2c_master.cpp.in")
diff --git a/src/modm/platform/i2c/stm32-extended/module.lb b/src/modm/platform/i2c/stm32-extended/module.lb
index 4d37b4fc04..3de8ae191f 100644
--- a/src/modm/platform/i2c/stm32-extended/module.lb
+++ b/src/modm/platform/i2c/stm32-extended/module.lb
@@ -31,15 +31,10 @@ class Instance(Module):
return True
def build(self, env):
- device = env[":target"]
- driver = device.get_driver("i2c")
-
- properties = device.properties
- properties["target"] = target = device.identifier
- properties["id"] = self.instance
- properties["shared_interrupt"] = "0" in target.family
-
- env.substitutions = properties
+ env.substitutions = {
+ "shared_interrupt": "0" in env[":target"].identifier.family,
+ "id": self.instance,
+ }
env.outbasepath = "modm/src/modm/platform/i2c"
env.template("i2c_master.cpp.in", "i2c_master_{}.cpp".format(self.instance))
@@ -64,8 +59,8 @@ def prepare(module, options):
":container",
":platform:gpio")
- for instance in listify(device.get_driver("i2c")["instance"]):
- module.add_submodule(Instance(int(instance)))
+ for instance in device.driver("i2c").instances():
+ module.add_submodule(Instance(instance.number))
return True
diff --git a/src/modm/platform/i2c/stm32/module.lb b/src/modm/platform/i2c/stm32/module.lb
index d3bcd81941..67441b0fc4 100644
--- a/src/modm/platform/i2c/stm32/module.lb
+++ b/src/modm/platform/i2c/stm32/module.lb
@@ -32,14 +32,10 @@ class Instance(Module):
return True
def build(self, env):
- device = env[":target"]
- driver = device.get_driver("i2c")
-
- properties = device.properties
- properties["target"] = target = device.identifier
- properties["id"] = self.instance
-
- env.substitutions = properties
+ env.substitutions = {
+ "target": env[":target"].identifier,
+ "id": self.instance
+ }
env.outbasepath = "modm/src/modm/platform/i2c"
env.template("i2c_master.cpp.in", "i2c_master_{}.cpp".format(self.instance))
@@ -65,8 +61,8 @@ def prepare(module, options):
":container",
":platform:gpio")
- for instance in listify(device.get_driver("i2c")["instance"]):
- module.add_submodule(Instance(int(instance)))
+ for instance in device.driver("i2c").instances():
+ module.add_submodule(Instance(instance.number))
return True
diff --git a/src/modm/platform/i2c/xmega/module.lb b/src/modm/platform/i2c/xmega/module.lb
index 87a39601e1..4cea0db5b2 100644
--- a/src/modm/platform/i2c/xmega/module.lb
+++ b/src/modm/platform/i2c/xmega/module.lb
@@ -14,7 +14,7 @@
def get_properties(env):
device = env[":target"]
driver = device.get_driver("i2c:xmega")
- properties = device.properties
+ properties = {}
properties["target"] = device.identifier
properties["driver"] = driver
return properties
diff --git a/src/modm/platform/random/stm32/module.lb b/src/modm/platform/random/stm32/module.lb
index 6555b906bb..2e7230808a 100644
--- a/src/modm/platform/random/stm32/module.lb
+++ b/src/modm/platform/random/stm32/module.lb
@@ -22,12 +22,7 @@ def prepare(module, options):
return True
def build(env):
- device = env[":target"]
-
- properties = device.properties
- properties["target"] = device.identifier
-
- env.substitutions = properties
+ env.substitutions = {"target": env[":target"].identifier}
env.outbasepath = "modm/src/modm/platform/random"
env.template("random_number_generator.hpp.in")
diff --git a/src/modm/platform/spi/at90_tiny_mega/module.lb b/src/modm/platform/spi/at90_tiny_mega/module.lb
index 46fa67ee62..8a9667c1b3 100644
--- a/src/modm/platform/spi/at90_tiny_mega/module.lb
+++ b/src/modm/platform/spi/at90_tiny_mega/module.lb
@@ -11,15 +11,6 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
# -----------------------------------------------------------------------------
-def get_properties(env):
- device = env[":target"]
- driver = device.get_driver("spi:avr")
- properties = device.properties
- properties["target"] = device.identifier
- properties["partname"] = device.partname
- properties["driver"] = driver
- return properties
-
def load_options(module):
module.add_option(
BooleanOption(
@@ -42,10 +33,11 @@ class Instance(Module):
return True
def build(self, env):
- properties = get_properties(env)
- properties["id"] = self.instance
-
- env.substitutions = properties
+ env.substitutions = {
+ "target": env[":target"].identifier,
+ "partname": env[":target"].partname,
+ "id": self.instance,
+ }
env.outbasepath = "modm/src/modm/platform/spi"
env.template("spi.hpp.in", "spi{}.hpp".format(self.instance))
@@ -61,10 +53,10 @@ def prepare(module, options):
if not device.has_driver("spi:avr"):
return False
- driver = device.get_driver("spi:avr")
- if "instance" in driver:
- for instance in listify(driver["instance"]):
- module.add_submodule(Instance(int(instance)))
+ instances = device.driver("spi").instances()
+ if instances:
+ for instance in instances:
+ module.add_submodule(Instance(instance.number))
else:
load_options(module)
@@ -77,16 +69,14 @@ def prepare(module, options):
return True
def build(env):
- properties = get_properties(env)
- driver = properties["driver"]
-
- if "instance" not in driver:
- properties["id"] = ""
-
- env.substitutions = properties
- env.outbasepath = "modm/src/modm/platform/spi"
-
- if "instance" not in driver:
+ device = env[":target"]
+ if not device.driver("spi").instances():
+ env.substitutions = {
+ "target": device.identifier,
+ "partname": device.partname,
+ "id": "",
+ }
+ env.outbasepath = "modm/src/modm/platform/spi"
env.template("spi_master.hpp.in")
env.template("spi_master.cpp.in")
env.template("spi.hpp.in")
diff --git a/src/modm/platform/spi/at90_tiny_mega_uart/module.lb b/src/modm/platform/spi/at90_tiny_mega_uart/module.lb
index 24b0e88fcb..e73ed59a16 100644
--- a/src/modm/platform/spi/at90_tiny_mega_uart/module.lb
+++ b/src/modm/platform/spi/at90_tiny_mega_uart/module.lb
@@ -13,11 +13,7 @@
def get_properties(env):
device = env[":target"]
- driver = device.get_driver("spi:avr_uart")
- properties = device.properties
- properties["target"] = device.identifier
- properties["driver"] = driver
- return properties
+ return {"target": device.identifier}
class Instance(Module):
@@ -52,10 +48,8 @@ class Instance(Module):
return True
def build(self, env):
- properties = get_properties(env)
- properties["id"] = self.instance
-
- target = properties["target"]
+ target = env[":target"].identifier
+ properties = {"target": target, "id": self.instance}
properties["extended"] = False
if target["name"] in ["48", "88", "168", "328"] and target["type"] == "p":
@@ -96,11 +90,10 @@ def prepare(module, options):
":platform:gpio",
":platform:uart")
- for instance in listify(device.get_driver("spi:avr_uart")["instance"]):
- module.add_submodule(Instance(int(instance)))
+ for instance in device.driver("spi").instances():
+ module.add_submodule(Instance(instance.number))
return True
def build(env):
- env.substitutions = get_properties(env)
- env.outbasepath = "modm/src/modm/platform/spi_uart"
+ pass
diff --git a/src/modm/platform/spi/lpc/module.lb b/src/modm/platform/spi/lpc/module.lb
index 4fff669c2c..0a8f22d915 100644
--- a/src/modm/platform/spi/lpc/module.lb
+++ b/src/modm/platform/spi/lpc/module.lb
@@ -25,7 +25,7 @@ def build(env):
device = env[":target"]
driver = device.get_driver("spi")
- properties = device.properties
+ properties = {}
properties["target"] = target = device.identifier
properties["driver"] = driver
diff --git a/src/modm/platform/spi/stm32/module.lb b/src/modm/platform/spi/stm32/module.lb
index 783b3eb8a3..321d652202 100644
--- a/src/modm/platform/spi/stm32/module.lb
+++ b/src/modm/platform/spi/stm32/module.lb
@@ -21,7 +21,7 @@ def get_properties(env):
class Instance(Module):
def __init__(self, driver, instance):
- self.instance = int(instance)
+ self.instance = instance
self.driver = driver
def init(self, module):
@@ -65,9 +65,9 @@ def prepare(module, options):
":platform:gpio",
":platform:rcc")
- for driver in device.get_all_drivers("spi:stm32"):
- for instance in driver["instance"]:
- module.add_submodule(Instance(driver, instance))
+ for driver in device.drivers("spi:stm32"):
+ for instance in driver.instances():
+ module.add_submodule(Instance(driver, instance.number))
return True
diff --git a/src/modm/platform/spi/stm32_uart/module.lb b/src/modm/platform/spi/stm32_uart/module.lb
index 50d078b0df..5b0edbe235 100644
--- a/src/modm/platform/spi/stm32_uart/module.lb
+++ b/src/modm/platform/spi/stm32_uart/module.lb
@@ -10,14 +10,6 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
# -----------------------------------------------------------------------------
-def get_properties(env):
- device = env[":target"]
- driver = device.get_driver("usart:stm32")
- properties = device.properties
- properties["target"] = device.identifier
- properties["driver"] = driver
- return properties
-
class Instance(Module):
def __init__(self, instance, is_extended = False):
self.instance = instance
@@ -32,16 +24,17 @@ class Instance(Module):
return True
def build(self, env):
- properties = get_properties(env)
- properties["id"] = self.instance
- properties["extended"] = self.is_extended
-
- env.substitutions = properties
+ env.substitutions = {
+ "target": env[":target"].identifier,
+ "id": self.instance,
+ "extended": self.is_extended,
+ }
env.outbasepath = "modm/src/modm/platform/spi"
env.template("uart_spi_master.hpp.in", "uart_spi_master_{}.hpp".format(self.instance))
env.template("uart_spi_master.cpp.in", "uart_spi_master_{}.cpp".format(self.instance))
+
def init(module):
module.name = ":platform:uart.spi"
module.description = "USART in SPI Mode"
@@ -57,13 +50,9 @@ def prepare(module, options):
":platform:gpio",
":platform:uart")
- if device.get_driver("usart:stm32-extended"):
- for instance in device.get_driver("usart:stm32-extended")["instance"]:
- module.add_submodule(Instance(int(instance), True))
-
- if device.get_driver("usart:stm32"):
- for instance in device.get_driver("usart:stm32")["instance"]:
- module.add_submodule(Instance(int(instance)))
+ for driver in device.drivers("usart"):
+ for instance in driver.instances():
+ module.add_submodule(Instance(instance.number, "extended" in driver.type))
return True
diff --git a/src/modm/platform/spi/xmega/module.lb b/src/modm/platform/spi/xmega/module.lb
index d4de282bc3..84bb7d2deb 100644
--- a/src/modm/platform/spi/xmega/module.lb
+++ b/src/modm/platform/spi/xmega/module.lb
@@ -26,7 +26,7 @@ def build(env):
device = env[":target"]
driver = device.get_driver("spi")
- properties = device.properties
+ properties = {}
properties["target"] = device.identifier
properties["driver"] = driver
diff --git a/src/modm/platform/timer/lpc/module.lb b/src/modm/platform/timer/lpc/module.lb
index cc2c4fb86c..0696c64447 100644
--- a/src/modm/platform/timer/lpc/module.lb
+++ b/src/modm/platform/timer/lpc/module.lb
@@ -11,15 +11,6 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
# -----------------------------------------------------------------------------
-def get_properties(env):
- device = env[":target"]
- driver = device.get_driver("timer")
- properties = device.properties
- properties["target"] = device.identifier
- properties["driver"] = driver
- return properties
-
-
class Instance(Module):
def __init__(self, instance):
self.instance = instance
@@ -33,10 +24,8 @@ class Instance(Module):
return True
def build(self, env):
- properties = get_properties(env)
- properties["id"] = self.instance
-
- env.substitutions = properties
+ env.substitutions = {"target": env["target"].identifier,
+ "id": self.instance}
env.outbasepath = "modm/src/modm/platform/timer"
env.template("timer.hpp.in", "timer_{}.hpp".format(self.instance))
@@ -58,7 +47,7 @@ def prepare(module, options):
return True
def build(env):
- env.substitutions = get_properties(env)
+ env.substitutions = {"target": env["target"].identifier}
env.outbasepath = "modm/src/modm/platform/timer"
env.copy("timer_registers.hpp")
diff --git a/src/modm/platform/timer/stm32/module.lb b/src/modm/platform/timer/stm32/module.lb
index 5488d51495..ac5085b125 100644
--- a/src/modm/platform/timer/stm32/module.lb
+++ b/src/modm/platform/timer/stm32/module.lb
@@ -29,18 +29,18 @@ def get_connectors(instance):
return []
class Instance(Module):
- def __init__(self, driver, instance):
- self.driver = driver
- self.instance = int(instance)
+ def __init__(self, device, instance):
+ self.device = device
+ self.instance = instance
self.vectors = None
self.type = "general_purpose"
- if self.instance in [1, 8, 20]:
+ if self.instance.number in [1, 8, 20]:
self.type = "advanced"
- elif self.instance in [6, 7, 18]:
+ elif self.instance.number in [6, 7, 18]:
self.type = "basic"
def init(self, module):
- module.name = str(self.instance)
+ module.name = self.instance.name
module.description = "Instance {}".format(self.instance)
def prepare(self, module, options):
@@ -55,7 +55,8 @@ class Instance(Module):
"_CC": ["CaptureCompare1", "CaptureCompare2",
"CaptureCompare3", "CaptureCompare4"],
}
- self.vectors = {irq:[] for irq in props["timer_vectors"][self.instance]}
+ vectors = list(self.device.core.vectors(lambda v: "TIM"+self.instance.name in v.split("_")))
+ self.vectors = {irq:[] for irq in vectors}
for irq in self.vectors.keys():
for part, flags in vecmap.items():
if part in irq:
@@ -63,7 +64,7 @@ class Instance(Module):
if len(self.vectors) == 0:
raise ValidateException("No interrupts found for Timer{}! Possible IRQs are {}"
- .format(self.instance, props["timer_vectors"]))
+ .format(self.instance, list(self.device.core.vectors(lambda v: "TIM" in v))))
if self.type != "advanced":
if len(self.vectors) != 1:
raise ValidateException("Timer{} is only allowed to have one IRQ! Found {}"
@@ -72,15 +73,15 @@ class Instance(Module):
def build(self, env):
global props
- props["id"] = self.instance
- props["connectors"] = get_connectors(self.instance)
+ props["id"] = self.instance.number
+ props["connectors"] = get_connectors(self.instance.number)
props["vectors"] = self.vectors
props["types"].add(self.type)
env.substitutions = props
env.outbasepath = "modm/src/modm/platform/timer"
- env.template("{}.hpp.in".format(self.type), "timer_{}.hpp".format(self.instance))
- env.template("{}.cpp.in".format(self.type), "timer_{}.cpp".format(self.instance))
+ env.template("{}.hpp.in".format(self.type), "timer_{}.hpp".format(self.instance.name))
+ env.template("{}.cpp.in".format(self.type), "timer_{}.cpp".format(self.instance.name))
def init(module):
@@ -98,27 +99,18 @@ def prepare(module, options):
":platform:gpio",
":platform:rcc")
- timers = device.get_all_drivers("tim")
+ timers = device.drivers("tim")
instances = []
for driver in timers:
- for instance in driver["instance"]:
- module.add_submodule(Instance(driver, instance))
- instances.append(int(instance))
+ for instance in driver.instances():
+ module.add_submodule(Instance(device, instance))
+ instances.append(instance.number)
global props
device = options[":target"]
props["target"] = device.identifier
props["types"] = set()
- props["timer_vectors"] = tim_vectors = defaultdict(list)
- vectors = [v["name"] for v in device.get_driver("core")["vector"] if "TIM" in v["name"]]
- for instance in instances:
- timstr = "TIM{}".format(instance)
- for vector in vectors:
- if (vector == timstr or ("_"+timstr+"_") in vector or
- vector.startswith(timstr+"_") or vector.endswith("_"+timstr)):
- tim_vectors[instance].append(vector)
-
return True
def build(env):
diff --git a/src/modm/platform/timer/xmega/module.lb b/src/modm/platform/timer/xmega/module.lb
deleted file mode 100644
index 53732ebb0c..0000000000
--- a/src/modm/platform/timer/xmega/module.lb
+++ /dev/null
@@ -1,33 +0,0 @@
-#!/usr/bin/env python3
-# -*- coding: utf-8 -*-
-#
-# Copyright (c) 2016-2017, Niklas Hauser
-# Copyright (c) 2017, Fabian Greif
-#
-# This file is part of the modm project.
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-# -----------------------------------------------------------------------------
-
-def init(module):
- module.name = ":platform:timer"
-
-def prepare(module, options):
- if not options[":target"].has_driver("timer:xmega"):
- return False
-
- module.depends(":platform:core")
- return True
-
-def build(env):
- device = env[":target"]
- driver = device.get_driver("timer")
-
- properties = device.properties
- properties["target"] = target = device.identifier
- properties["driver"] = driver
-
- env.substitutions = properties
- env.outbasepath = "modm/src/modm/platform/timer"
diff --git a/src/modm/platform/uart/at90_tiny_mega/module.lb b/src/modm/platform/uart/at90_tiny_mega/module.lb
index 8d3a393cbf..6d67eacd33 100644
--- a/src/modm/platform/uart/at90_tiny_mega/module.lb
+++ b/src/modm/platform/uart/at90_tiny_mega/module.lb
@@ -11,14 +11,6 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
# -----------------------------------------------------------------------------
-def get_properties(env):
- device = env[":target"]
- driver = device.get_driver("usart:avr")
- properties = device.properties
- properties["target"] = device.identifier
- properties["driver"] = driver
- return properties
-
def load_options(module):
module.add_option(
BooleanOption(
@@ -52,16 +44,13 @@ class Instance(Module):
return True
def build(self, env):
- properties = get_properties(env)
- target = properties["target"]
-
- if target["family"] == "tiny" and target["name"] in ["828", "2313", "4313"]:
+ target = env[":target"].identifier
+ if target.family == "tiny" and target.name in ["828", "2313", "4313"]:
instance = ""
else:
instance = self.instance
- properties["id"] = instance
- env.substitutions = properties
+ env.substitutions = {"id": instance}
env.outbasepath = "modm/src/modm/platform/uart"
env.template("uart.hpp.in", "uart{}.hpp".format(instance))
@@ -85,28 +74,21 @@ def prepare(module, options):
":math:algorithm",
":platform:gpio")
- driver = device.get_driver("usart:avr")
- if "instance" in driver:
- for instance in listify(driver["instance"]):
- module.add_submodule(Instance(int(instance)))
+ instances = device.driver("usart").instances()
+ if instances:
+ for instance in instances:
+ module.add_submodule(Instance(instance.number))
else:
load_options(module)
return True
def build(env):
- properties = get_properties(env)
- driver = properties["driver"]
-
- if "instance" not in driver:
- properties["id"] = ""
-
- env.substitutions = properties
env.outbasepath = "modm/src/modm/platform/uart"
-
env.template("uart_defines.h")
- if "instance" not in driver:
+ if not env[":target"].driver("usart").instances():
+ env.substitutions = {"id": ""}
env.template("uart.hpp.in")
env.template("uart_tx.cpp.in")
env.template("uart_rx.cpp.in")
diff --git a/src/modm/platform/uart/lpc/module.lb b/src/modm/platform/uart/lpc/module.lb
index 4a81b74b84..e0a5da8d73 100644
--- a/src/modm/platform/uart/lpc/module.lb
+++ b/src/modm/platform/uart/lpc/module.lb
@@ -14,7 +14,7 @@
def get_properties(env):
device = env[":target"]
driver = device.get_driver("uart")
- properties = device.properties
+ properties = {}
properties["target"] = device.identifier
properties["driver"] = driver
return properties
diff --git a/src/modm/platform/uart/sam/module.lb b/src/modm/platform/uart/sam/module.lb
index 40126849d4..07d1b12442 100644
--- a/src/modm/platform/uart/sam/module.lb
+++ b/src/modm/platform/uart/sam/module.lb
@@ -15,12 +15,11 @@
props = {}
class Instance(Module):
- def __init__(self, driver, instance):
- self.driver = driver
- self.instance = int(instance)
+ def __init__(self, instance):
+ self.instance = instance
def init(self, module):
- module.name = str(self.instance)
+ module.name = self.instance.name
module.description = "Instance {}".format(self.instance)
def prepare(self, module, options):
@@ -29,11 +28,10 @@ class Instance(Module):
def build(self, env):
device = env[":target"].identifier
global props
- props["id"] = self.instance
- props["driver"] = self.driver
- props["features"] = self.driver["feature"] if "feature" in self.driver else []
+ props["id"] = self.instance.number
+ props["driver"] = self.instance.driver
props["uart_name"] = 'Uart'
- props["sercom_name"] = self.driver["name"].capitalize()
+ props["sercom_name"] = self.instance.driver.name.capitalize()
env.substitutions = props
env.outbasepath = "modm/src/modm/platform/uart"
@@ -72,11 +70,10 @@ def prepare(module, options):
props["tcbgt"] = ("feature" in drivers[0]) and ("tcbgt" in drivers[0]["feature"])
props["instances"] = []
- for driver in drivers:
- for instance in driver["instance"]:
- module.add_submodule(Instance(driver, instance))
-
props["target"] = device.identifier
+
+ for instance in device.driver("sercom").instances():
+ module.add_submodule(Instance(instance))
return True
def build(env):
diff --git a/src/modm/platform/uart/stm32/module.lb b/src/modm/platform/uart/stm32/module.lb
index fe2ee2aeec..052fd4e003 100644
--- a/src/modm/platform/uart/stm32/module.lb
+++ b/src/modm/platform/uart/stm32/module.lb
@@ -14,12 +14,11 @@
props = {}
class Instance(Module):
- def __init__(self, driver, instance):
- self.driver = driver
- self.instance = int(instance)
+ def __init__(self, instance):
+ self.instance = instance
def init(self, module):
- module.name = str(self.instance)
+ module.name = self.instance.name
module.description = "Instance {}".format(self.instance)
def prepare(self, module, options):
@@ -48,10 +47,10 @@ class Instance(Module):
def build(self, env):
device = env[":target"].identifier
global props
- props["id"] = self.instance
- props["driver"] = self.driver
- props["features"] = self.driver["feature"] if "feature" in self.driver else []
- props["uart_name"] = self.driver["name"].capitalize()
+ props["driver"] = self.instance.driver
+ props["id"] = self.instance.number
+ props["features"] = self.instance.features()
+ props["uart_name"] = self.instance.driver.name.capitalize()
env.substitutions = props
env.outbasepath = "modm/src/modm/platform/uart"
@@ -61,7 +60,7 @@ class Instance(Module):
env.template("uart.hpp.in", "uart_{}.hpp".format(self.instance))
env.template("uart.cpp.in", "uart_{}.cpp".format(self.instance))
- props["instances"].append(self.instance)
+ props["instances"].append(self.instance.number)
def init(module):
@@ -84,26 +83,23 @@ def prepare(module, options):
":platform:rcc")
global props
- drivers = (device.get_all_drivers("uart") + device.get_all_drivers("usart"))
- props["extended_driver"] = ("extended" in drivers[0]["type"])
- props["over8_sampling"] = ("feature" in drivers[0]) and ("over8" in drivers[0]["feature"])
- props["tcbgt"] = ("feature" in drivers[0]) and ("tcbgt" in drivers[0]["feature"])
+ drivers = device.drivers("usart", "uart")
+ props["extended_driver"] = ("extended" in drivers[0].type)
+ props["shared_features"] = features = drivers[0].features()
+ props["over8_sampling"] = "over8" in features
+ props["tcbgt"] = "tcbgt" in features
+ props["half_duplex"] = "half-duplex" in features
+ props["7_bit"] = "7-bit" in features
+ props["target"] = device.identifier
props["instances"] = []
- for driver in drivers:
- for instance in driver["instance"]:
- module.add_submodule(Instance(driver, instance))
-
- shared_irqs = [v["name"] for v in device.get_driver("core")["vector"]]
- shared_irqs = [v for v in shared_irqs if v.startswith("USART") and "_" in v]
- if len(shared_irqs):
- props["shared_irq"] = name = shared_irqs[0]
- parts = name[5:].split("_")
- props["shared_irq_ids"] = range(int(parts[0]), int(parts[1]) + 1)
- else:
- props["shared_irq_ids"] = []
+ shared_irqs = device.core.shared_irqs("USART")
+ props["shared_irq"] = next(iter(shared_irqs.keys()), None)
+ props["shared_irq_ids"] = shared_irqs.get(props["shared_irq"], [])
- props["target"] = device.identifier
+ for driver in drivers:
+ for instance in driver.instances():
+ module.add_submodule(Instance(instance))
return True
diff --git a/src/modm/platform/uart/xmega/module.lb b/src/modm/platform/uart/xmega/module.lb
index 93bee55b6d..ef0d191771 100644
--- a/src/modm/platform/uart/xmega/module.lb
+++ b/src/modm/platform/uart/xmega/module.lb
@@ -14,7 +14,7 @@
def get_properties(env):
device = env[":target"]
driver = device.get_driver("uart")
- properties = device.properties
+ properties = {}
properties["target"] = device.identifier
properties["driver"] = driver
return properties
diff --git a/src/modm/platform/usb/stm32/module.lb b/src/modm/platform/usb/stm32/module.lb
index 5cecd2517a..0752052d52 100644
--- a/src/modm/platform/usb/stm32/module.lb
+++ b/src/modm/platform/usb/stm32/module.lb
@@ -34,8 +34,7 @@ def common_usb_irqs(env):
:returns: a dictionary of USB interrupt properties
"""
- usb_vectors = {v["name"] for v in env[":target"].get_driver("core")["vector"]
- if any(v["name"].startswith(n) for n in ["USB", "OTG"])}
+ usb_vectors = set(env[":target"].core.vectors(lambda v: any(v.startswith(n) for n in ["USB", "OTG"])))
is_remap = any("_RMP" in v for v in usb_vectors)
port_irqs = defaultdict(list)
@@ -60,7 +59,7 @@ def generate_instance(env, port, otg=False):
irq_data = env.query(":platform:usb:irqs")
env.substitutions = {
"port": port,
- "peripheral": "Usbotg{}".format(port) if otg else "Usb",
+ "peripheral": "UsbOtg{}".format(port.capitalize()) if otg else "Usb",
"is_otg": otg,
"is_remap": irq_data["is_remap"],
"irqs": irq_data["port_irqs"][port],
diff --git a/test/modm/platform/gpio/module.lb b/test/modm/platform/gpio/module.lb
index 823beebc61..ad2cf47928 100644
--- a/test/modm/platform/gpio/module.lb
+++ b/test/modm/platform/gpio/module.lb
@@ -109,10 +109,10 @@ def build(env):
driver = device.get_driver("gpio")
gpios = [g for g in driver["gpio"] if (g["port"].upper(), int(g["pin"])) in test_io]
- peripherals = sorted([get_driver(s) for g in gpios for s in (g["signal"] if "signal" in g else [])])
+ peripherals = sorted([env.filter("modm.fmt.driver")(s) for g in gpios for s in g.get("signal", [])])
connections = OrderedDict()
for k in peripherals:
- rconns = [(g["port"].upper(), int(g["pin"]), get_name(s), get_af(s)) for g in gpios for s in (g["signal"] if "signal" in g else []) if get_driver(s) == k]
+ rconns = [(g["port"].upper(), int(g["pin"]), get_name(s), get_af(s)) for g in gpios for s in g.get("signal", []) if get_driver(s) == k]
# we need to remove duplicate GPIOs from this list
# since we cannot set the same GPIO to multiple different AFs!
conns = []
diff --git a/tools/build_script_generator/common.py b/tools/build_script_generator/common.py
index 9dcddee52d..de7b441bcc 100644
--- a/tools/build_script_generator/common.py
+++ b/tools/build_script_generator/common.py
@@ -122,7 +122,7 @@ def common_memories(env):
if "memory" in core_driver:
memories.extend([
{
- k:(int(v) if v.isdigit() else (int(v, 16) if v.startswith("0x") else v))
+ k:(int(v) if str(v).isdigit() else (int(v, 16) if v.startswith("0x") else v))
for k, v in memory.items()
}
for memory in core_driver["memory"]