diff --git a/README.md b/README.md
index f549319882..abcd5befd8 100644
--- a/README.md
+++ b/README.md
@@ -188,7 +188,7 @@ Please [discover modm's peripheral drivers for your specific device][discover].
✅ |
✕ |
✕ |
-○ |
+✅ |
✅ |
○ |
○ |
diff --git a/src/modm/platform/comp/stm32/base.hpp.in b/src/modm/platform/comp/stm32/base.hpp.in
index 46443a8940..aca544793f 100644
--- a/src/modm/platform/comp/stm32/base.hpp.in
+++ b/src/modm/platform/comp/stm32/base.hpp.in
@@ -34,6 +34,9 @@ namespace modm::platform
MediumSpeed = 0b01 << 2,
//MediumSpeed2 = 0b10 << 2,
UltraLowPower = 0b11 << 2,
+ {% elif driver.type in ["stm32-tsmc90_orcazero_cube"] -%}
+ HighSpeed = 0b00 << 2,
+ MediumSpeed = 0b01 << 2,
{% endif -%}
};
protected:
@@ -50,7 +53,7 @@ namespace modm::platform
protected:
static constexpr uint32_t PolarityMask = 0b1 << 15;
- {% if driver.type in ["stm32-v1.3", "stm32-tsmc90_cube"] -%}
+ {% if driver.type in ["stm32-v1.3", "stm32-tsmc90_cube", "stm32-tsmc90_orcazero_cube"] -%}
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 440871f77d..e0cb6d9ac2 100644
--- a/src/modm/platform/comp/stm32/comp.hpp.in
+++ b/src/modm/platform/comp/stm32/comp.hpp.in
@@ -108,6 +108,26 @@ namespace modm::platform
GpioD15 = 0b110 << 4,
GpioB12 = 0b111 << 4,
{% endif -%}
+ {% elif target.family == "g0" -%}
+ Vref1Div4 = 0b0000 << 4,
+ Vref1Div2 = 0b0001 << 4,
+ Vref3Div4 = 0b0010 << 4,
+ Vref = 0b0011 << 4,
+ Dac1Ch1 = 0b0100 << 4,
+ Dac1Ch2 = 0b0101 << 4,
+ {% if id == 1 -%}
+ GpioB1 = 0b0110 << 4,
+ GpioC4 = 0b0111 << 4,
+ GpioA0 = 0b1000 << 4,
+ {% elif id == 2 -%}
+ GpioB3 = 0b0110 << 4,
+ GpioB7 = 0b0111 << 4,
+ GpioA2 = 0b1000 << 4,
+ {% elif id == 3 -%}
+ GpioB2 = 0b0110 << 4,
+ GpioC0 = 0b0111 << 4,
+ GpioE8 = 0b1000 << 4,
+ {% endif -%}
{% endif -%}
};
protected:
@@ -117,6 +137,8 @@ namespace modm::platform
static constexpr uint32_t InvertingInputMask = (0b111 << 4) | (0b11 << 22) | (0b11 << 25);
{% elif target.family in ["g4"] -%}
static constexpr uint32_t InvertingInputMask = (0b1111 << 4) | (0b11 << 22);
+ {% elif target.family in ["g0"] -%}
+ static constexpr uint32_t InvertingInputMask = (0b1111 << 4);
{% endif -%}
public:
@@ -160,6 +182,20 @@ namespace modm::platform
GpioB14 = 0b0 << 8,
GpioD14 = 0b1 << 8,
{% endif -%}
+ {% elif target.family in ["g0"] -%}
+ {% if id == 1 -%}
+ GpioC5 = 0b00 << 8,
+ GpioB2 = 0b01 << 8,
+ GpioA1 = 0b10 << 8,
+ {% elif id == 2 -%}
+ GpioB4 = 0b00 << 8,
+ GpioB6 = 0b01 << 8,
+ GpioA3 = 0b10 << 8,
+ {% elif id == 3 -%}
+ GpioB0 = 0b00 << 8,
+ GpioC1 = 0b01 << 8,
+ GpioE7 = 0b10 << 8,
+ {% endif -%}
{% endif -%}
};
protected:
@@ -169,6 +205,8 @@ namespace modm::platform
static constexpr uint32_t NonInvertingInputMask = 0b1 << 8;
{% elif target.family in ["l4"] -%}
static constexpr uint32_t NonInvertingInputMask = 0b11 << 7;
+ {% elif target.family in ["g0"] -%}
+ static constexpr uint32_t NonInvertingInputMask = 0b11 << 8;
{% endif -%}
{% if target.family == "f3" -%}
@@ -227,7 +265,7 @@ namespace modm::platform
static inline void
initialize(
InvertingInput n_in,
- {% if (target.family == "f3" and id > 1) or target.family in ["l4", "g4"] -%}
+ {% if (target.family == "f3" and id > 1) or target.family in ["l4", "g4", "g0"] -%}
NonInvertingInput p_in,
{% endif -%}
{% if target.family == "f3" -%}
@@ -241,7 +279,7 @@ namespace modm::platform
bool lock_comp = false)
{
setInvertingInput(n_in);
- {% if (target.family == "f3" and id > 1) or target.family in ["l4", "g4"] -%}
+ {% if (target.family == "f3" and id > 1) or target.family in ["l4", "g4", "g0"] -%}
setNonInvertingInput(p_in);
{% endif -%}
{% if target.family == "f3" -%}
@@ -350,7 +388,7 @@ namespace modm::platform
return static_cast(COMP{{ id }}->CSR & InvertingInputMask);
}
- {% if (target.family == "f3" and id > 1) or target.family in ["l4", "g4"] -%}
+ {% if (target.family == "f3" and id > 1) or target.family in ["l4", "g4", "g0"] -%}
/**
* \brief Selects what the non-inverting input is connected to.
*/
@@ -370,10 +408,10 @@ namespace modm::platform
}
{% endif -%}
- {% if (target.family == "f3" and (id == 2 or id == 4 or id == 6)) or (target.family == "l4" and id == 2) -%}
+ {% if (target.family == "f3" and (id == 2 or id == 4 or id == 6)) or (target.family == "l4" and id == 2) or (target.family == "g0") -%}
{% if target.family == "f3" -%}
{% set windowmode = "WNDWEN" %}
- {% elif target.family == "l4" -%}
+ {% elif target.family in ["l4", "g0"] -%}
{% set windowmode = "WINMODE" %}
{% endif -%}
/**
@@ -481,7 +519,7 @@ namespace modm::platform
{
{% if target.family == "f3" -%}
return COMP{{ id }}->CSR & {{ csr }}OUT;
- {% elif target.family in ["l4", "g4"] -%}
+ {% elif target.family in ["l4", "g4", "g0"] -%}
return COMP{{ id }}->CSR & {{ csr }}VALUE;
{% endif -%}
}
diff --git a/src/modm/platform/comp/stm32/module.lb b/src/modm/platform/comp/stm32/module.lb
index 87aee6f45d..2cadd24df0 100644
--- a/src/modm/platform/comp/stm32/module.lb
+++ b/src/modm/platform/comp/stm32/module.lb
@@ -31,7 +31,7 @@ class Instance(Module):
instance_id = int(self.instance)
properties["id"] = instance_id
properties["driver"] = driver
- properties["csr"] = "COMP_CSR_" if device.identifier["family"] in ["l4", "g4"] else "COMP_CSR_COMPx"
+ properties["csr"] = "COMP_CSR_" if device.identifier["family"] in ["l4", "g4", "g0"] else "COMP_CSR_COMPx"
properties["blanking_source"] = dict()
if device.identifier["family"] in ["g4"]:
properties["blanking_source"]["b001"] = ["Tim1Oc5", "Tim1Oc5", "Tim1Oc5", "Tim3Oc4", "Tim2Oc3", "Tim8Oc5", "Tim1Oc5"][instance_id - 1]
@@ -49,6 +49,13 @@ class Instance(Module):
properties["blanking_source"]["b001"] = "Tim1Oc5"
properties["blanking_source"]["b010"] = "Tim2Oc3"
properties["blanking_source"]["b011"] = "Tim3Oc3"
+ elif device.identifier["family"] in ["g0"]:
+ properties["blanking_source"]["b00000"] = None
+ properties["blanking_source"]["b00001"] = "Tim1Oc4"
+ properties["blanking_source"]["b00010"] = "Tim1Oc5"
+ properties["blanking_source"]["b00100"] = "Tim2Oc3"
+ properties["blanking_source"]["b01000"] = "Tim3Oc3"
+ properties["blanking_source"]["b10000"] = "Tim15Oc2"
@@ -83,7 +90,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.get_driver("comp")["type"] in ["stm32-v1.3", "stm32-tsmc90_cube", "stm32-tsmc90_g4_rockfish_cube", "stm32-tsmc90_orcazero_cube"]:
return False
# Only some STM32F3 and STM32L4
@@ -95,6 +102,8 @@ def prepare(module, options):
return False
elif device.identifier["family"] == "g4":
pass
+ elif device.identifier["family"] == "g0":
+ pass
else:
return False
@@ -112,7 +121,7 @@ def build(env):
properties = device.properties
properties["target"] = device.identifier
properties["driver"] = driver
- properties["csr"] = "COMP_CSR_" if device.identifier["family"] in ["l4", "g4"] else "COMP_CSR_COMPx"
+ properties["csr"] = "COMP_CSR_" if device.identifier["family"] in ["l4", "g4", "g0"] else "COMP_CSR_COMPx"
env.substitutions = properties
env.outbasepath = "modm/src/modm/platform/comp"
diff --git a/src/modm/platform/dma/stm32/dma.hpp.in b/src/modm/platform/dma/stm32/dma.hpp.in
index 265f1954ba..4a8e895a58 100644
--- a/src/modm/platform/dma/stm32/dma.hpp.in
+++ b/src/modm/platform/dma/stm32/dma.hpp.in
@@ -452,7 +452,7 @@ public:
static constexpr std::array muxChannels = {
%% for channel in dma["mux-channels"][0]["mux-channel"]
- MuxChannel({{ channel.position }}, {{ channel["dma-instance"] }}, {{ channel["dma-channel"] }}){{ "," if not loop.last }}
+ MuxChannel({{ channel.position }}, {{ channel["dma-instance"] }}, {{ channel["dma-channel"] }}){{ "," if not loop.last else '' }}
%% endfor
};
%% endif
diff --git a/src/modm/platform/timer/stm32/advanced.cpp.in b/src/modm/platform/timer/stm32/advanced.cpp.in
index e54e7dcfa5..41ac2b5ea7 100644
--- a/src/modm/platform/timer/stm32/advanced.cpp.in
+++ b/src/modm/platform/timer/stm32/advanced.cpp.in
@@ -167,7 +167,7 @@ modm::platform::Timer{{ id }}::configureInputChannel(uint32_t channel,
// ----------------------------------------------------------------------------
void
modm::platform::Timer{{ id }}::configureOutputChannel(uint32_t channel,
- OutputCompareMode mode, uint16_t compareValue, PinState out)
+ OutputCompareMode mode, Value compareValue, PinState out)
{
channel -= 1; // 1..4 -> 0..3
@@ -216,6 +216,19 @@ modm::platform::Timer{{ id }}::configureOutputChannel(uint32_t channel,
}
}
+void
+modm::platform::Timer{{ id }}::configureOutputChannel(uint32_t channel,
+OutputCompareMode mode, Value compareValue,
+PinState out, OutputComparePolarity polarity,
+PinState out_n, OutputComparePolarity polarity_n,
+OutputComparePreload preload)
+{
+ // disable output
+ TIM{{ id }}->CCER &= ~(0xf << ((channel-1) * 4));
+ setCompareValue(channel, compareValue);
+ configureOutputChannel(channel, mode, out, polarity, out_n, polarity_n, preload);
+}
+
void
modm::platform::Timer{{ id }}::configureOutputChannel(uint32_t channel,
OutputCompareMode mode,
diff --git a/src/modm/platform/timer/stm32/advanced.hpp.in b/src/modm/platform/timer/stm32/advanced.hpp.in
index 7884521bf5..6e5741ba5c 100644
--- a/src/modm/platform/timer/stm32/advanced.hpp.in
+++ b/src/modm/platform/timer/stm32/advanced.hpp.in
@@ -260,6 +260,44 @@ public:
{
return (TIM{{ id }}->BDTR & TIM_BDTR_MOE);
}
+%% if target.family in ["g0"]
+ static inline void
+ enableBreak()
+ {
+ TIM{{ id }}->BDTR |= TIM_BDTR_BKE;
+ }
+
+ static inline void
+ disableBreak()
+ {
+ TIM{{ id }}->BDTR &= ~(TIM_BDTR_BKE);
+ }
+
+ static inline void
+ enableBreakInput()
+ {
+ TIM{{ id }}->AF1 |= TIM{{ id }}_AF1_BKINE;
+ }
+
+ static inline void
+ disableBreakInput()
+ {
+ TIM{{ id }}->AF1 &= ~(TIM{{ id }}_AF1_BKINE);
+ }
+
+ static inline void
+ setBreakPolarity(BreakInputPolarity polarity)
+ {
+ if (BreakInputPolarity::ActiveLow == polarity)
+ {
+ TIM{{ id }}->BDTR &= ~(TIM_BDTR_BKP);
+ }
+ else
+ {
+ TIM{{ id }}->BDTR |= TIM_BDTR_BKP;
+ }
+ }
+%% endif
/*
* Enable/Disable automatic set of MOE bit at the next update event
@@ -357,7 +395,7 @@ public:
}
static inline void
- setRepetitionCount(uint8_t repetitionCount)
+ setRepetitionCount(uint16_t repetitionCount)
{
TIM{{ id }}->RCR = repetitionCount;
}
@@ -407,6 +445,25 @@ public:
configureOutputChannel(channel, mode, compareValue, out);
}
+ static void
+ configureOutputChannel(uint32_t channel, OutputCompareMode mode,
+ Value compareValue, PinState out,
+ OutputComparePolarity polarity, PinState out_n,
+ OutputComparePolarity polarity_n = OutputComparePolarity::ActiveHigh,
+ OutputComparePreload preload = OutputComparePreload::Disable);
+
+ template
+ static void
+ configureOutputChannel(OutputCompareMode mode,
+ Value compareValue, PinState out,
+ OutputComparePolarity polarity, PinState out_n,
+ OutputComparePolarity polarity_n = OutputComparePolarity::ActiveHigh,
+ OutputComparePreload preload = OutputComparePreload::Disable)
+ {
+ constexpr auto channel = signalToChannel();
+ configureOutputChannel(channel, mode, compareValue, out, polarity, out_n, polarity_n, preload);
+ }
+
/*
* Configure Output Channel without changing the Compare Value
*
diff --git a/src/modm/platform/timer/stm32/advanced_base.hpp.in b/src/modm/platform/timer/stm32/advanced_base.hpp.in
index fb65edb7c1..70d6f72c5b 100644
--- a/src/modm/platform/timer/stm32/advanced_base.hpp.in
+++ b/src/modm/platform/timer/stm32/advanced_base.hpp.in
@@ -122,6 +122,13 @@ public:
Reset = 0,
Set = TIM_CR2_OIS1,
};
+%% if target.family in ["g0"]
+ enum class BreakInputPolarity : uint32_t
+ {
+ ActiveLow = 0,
+ ActiveHigh = 1,
+ };
+%% endif
};
} // namespace platform
diff --git a/src/modm/platform/timer/stm32/general_purpose.cpp.in b/src/modm/platform/timer/stm32/general_purpose.cpp.in
index 3c1f8a62b3..1649913dd1 100644
--- a/src/modm/platform/timer/stm32/general_purpose.cpp.in
+++ b/src/modm/platform/timer/stm32/general_purpose.cpp.in
@@ -203,7 +203,18 @@ modm::platform::Timer{{ id }}::configureOutputChannel(uint32_t channel,
}
}
-%% if id in [15, 16, 17]
+void
+modm::platform::Timer{{ id }}::configureOutputChannel(uint32_t channel,
+OutputCompareMode mode, Value compareValue,
+PinState out, OutputComparePolarity polarity,
+OutputComparePreload preload)
+{
+ // disable output
+ TIM{{ id }}->CCER &= ~(0xf << ((channel-1) * 4));
+ setCompareValue(channel, compareValue);
+ configureOutputChannel(channel, mode, out, polarity, PinState::Disable, OutputComparePolarity::ActiveHigh, preload);
+}
+
void
modm::platform::Timer{{ id }}::configureOutputChannel(uint32_t channel,
OutputCompareMode mode,
@@ -211,21 +222,34 @@ PinState out, OutputComparePolarity polarity,
PinState out_n, OutputComparePolarity polarity_n,
OutputComparePreload preload)
{
+%% if id in [15, 16, 17]
modm_assert(channel == 1, "Timer{{ id }}", "This timer has complementary output only on channel 1!", "{{ id }}");
+%% endif
- channel -= 1;
+ channel -= 1; // 1..4 -> 0..3
// disable output
TIM{{ id }}->CCER &= ~(0xf << (channel * 4));
uint32_t flags = static_cast(mode) | static_cast(preload);
- const uint32_t offset = 8 * channel;
+ if (channel <= 1)
+ {
+ const uint32_t offset = 8 * channel;
+
+ flags <<= offset;
+ flags |= TIM{{ id }}->CCMR1 & ~(0xff << offset);
+
+ TIM{{ id }}->CCMR1 = flags;
+ }
+ else {
+ const uint32_t offset = 8 * (channel - 2);
- flags <<= offset;
- flags |= TIM{{ id }}->CCMR1 & ~(0xff << offset);
+ flags <<= offset;
+ flags |= TIM{{ id }}->CCMR2 & ~(0xff << offset);
- TIM{{ id }}->CCMR1 = flags;
+ TIM{{ id }}->CCMR2 = flags;
+ }
// CCER Flags (Enable/Polarity)
flags = (static_cast(polarity_n) << 2) |
@@ -234,7 +258,6 @@ OutputComparePreload preload)
TIM{{ id }}->CCER |= flags << (channel * 4);
}
-%% endif
// ----------------------------------------------------------------------------
void
diff --git a/src/modm/platform/timer/stm32/general_purpose.hpp.in b/src/modm/platform/timer/stm32/general_purpose.hpp.in
index 3e40462598..c401847d58 100644
--- a/src/modm/platform/timer/stm32/general_purpose.hpp.in
+++ b/src/modm/platform/timer/stm32/general_purpose.hpp.in
@@ -257,6 +257,14 @@ public:
TIM{{ id }}->CNT = value;
}
+%% if id in [15, 16, 17]
+ static inline void
+ setRepetitionCount(uint8_t repetitionCount)
+ {
+ TIM{{ id }}->RCR = repetitionCount;
+ }
+%% endif
+
%% if target.family not in ["l0", "l1"] and id in [15, 16, 17]
static inline bool
@@ -433,7 +441,35 @@ public:
configureOutputChannel(channel, mode, compareValue, out, enableComparePreload);
}
-%% if id in [15, 16, 17]
+ static void
+ configureOutputChannel(uint32_t channel, OutputCompareMode mode,
+ Value compareValue, PinState out,
+ OutputComparePolarity polarity,
+ OutputComparePreload preload = OutputComparePreload::Disable);
+
+ template
+ static void
+ configureOutputChannel(OutputCompareMode mode,
+ Value compareValue, PinState out,
+ OutputComparePolarity polarity,
+ OutputComparePreload preload = OutputComparePreload::Disable)
+ {
+ constexpr auto channel = signalToChannel();
+ configureOutputChannel(channel, mode, compareValue, out, polarity, PinState::Disable, OutputComparePolarity::ActiveHigh, preload);
+ }
+
+ /*
+ * Configure Output Channel without changing the Compare Value
+ *
+ * Normally used to reconfigure the Output channel without touching
+ * the compare value. This can e.g. be useful for commutation of a
+ * bldc motor.
+ *
+ * This function probably won't be used for a one time setup but
+ * rather for adjusting the output setting periodically.
+ * Therefore it aims to provide the best performance possible
+ * without sacrificing code readability.
+ */
static void
configureOutputChannel(uint32_t channel, OutputCompareMode mode,
PinState out, OutputComparePolarity polarity,
@@ -450,10 +486,11 @@ public:
OutputComparePreload preload = OutputComparePreload::Disable)
{
constexpr auto channel = signalToChannel();
- static_assert(channel == 1, "Timer{{ id }} has complementary output only on channel 1");
+%% if id in [15, 16, 17]
+ static_assert(channel == 1, "Timer{{ id }} has complementary output only on channel 1");
+%% endif
configureOutputChannel(channel, mode, out, polarity, out_n, polarity_n, preload);
}
-%% endif
/// Switch to Pwm Mode 2
///
diff --git a/src/modm/platform/timer/stm32/general_purpose_base.hpp.in b/src/modm/platform/timer/stm32/general_purpose_base.hpp.in
index 810aa10882..b8ddcaf9c4 100644
--- a/src/modm/platform/timer/stm32/general_purpose_base.hpp.in
+++ b/src/modm/platform/timer/stm32/general_purpose_base.hpp.in
@@ -141,6 +141,42 @@ public:
* capture/compare register, else inactive.
*/
Pwm2 = TIM_CCMR1_OC1M_2 | TIM_CCMR1_OC1M_1 | TIM_CCMR1_OC1M_0,
+
+#ifdef TIM_CCMR1_OC1M_3
+ /**
+ * Combined PWM mode 1.
+ *
+ * OC1REF has the same behavior as in PWM mode 1.
+ * OC1REFC is the logical OR between OC1REF and OC2REF.
+ */
+ Combined1 = TIM_CCMR1_OC1M_3 | TIM_CCMR1_OC1M_2,
+
+ /**
+ * Combined PWM mode 2.
+ *
+ * OC1REF has the same behavior as in PWM mode 2.
+ * OC1REFC is the logical AND between OC1REF and OC2REF.
+ */
+ Combined2 = TIM_CCMR1_OC1M_3 | TIM_CCMR1_OC1M_2 | TIM_CCMR1_OC1M_0,
+
+ /**
+ * Asymmetric PWM mode 1.
+ *
+ * OC1REF has the same behavior as in PWM mode 1.
+ * OC1REFC outputs OC1REF when the counter is counting up,
+ * OC2REF when it is counting down.
+ */
+ Asymmetric1 = TIM_CCMR1_OC1M_3 | TIM_CCMR1_OC1M_2 | TIM_CCMR1_OC1M_1,
+
+ /**
+ * Asymmetric PWM mode 2.
+ *
+ * OC1REF has the same behavior as in PWM mode 2.
+ * OC1REFC outputs OC1REF when the counter is counting up,
+ * OC2REF when it is counting down.
+ */
+ Asymmetric2 = TIM_CCMR1_OC1M_3 | TIM_CCMR1_OC1M_2 | TIM_CCMR1_OC1M_1 | TIM_CCMR1_OC1M_0,
+#endif
};
MODM_FLAGS32(OutputCompareMode);