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);