Skip to content

Commit

Permalink
[stm32] Extend Timer features: PWM modes and Comparator
Browse files Browse the repository at this point in the history
  • Loading branch information
victorandrehc committed Mar 7, 2024
1 parent 009bb06 commit 77e028e
Show file tree
Hide file tree
Showing 11 changed files with 235 additions and 24 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ Please [discover modm's peripheral drivers for your specific device][discover].
<td align="center">✅</td>
<td align="center">✕</td>
<td align="center">✕</td>
<td align="center"></td>
<td align="center"></td>
<td align="center">✅</td>
<td align="center">○</td>
<td align="center">○</td>
Expand Down
5 changes: 4 additions & 1 deletion src/modm/platform/comp/stm32/base.hpp.in
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand All @@ -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
Expand Down
50 changes: 44 additions & 6 deletions src/modm/platform/comp/stm32/comp.hpp.in
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand All @@ -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:
Expand Down Expand Up @@ -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:
Expand All @@ -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" -%}
Expand Down Expand Up @@ -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" -%}
Expand All @@ -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" -%}
Expand Down Expand Up @@ -350,7 +388,7 @@ namespace modm::platform
return static_cast<InvertingInput>(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.
*/
Expand All @@ -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 -%}
/**
Expand Down Expand Up @@ -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 -%}
}
Expand Down
15 changes: 12 additions & 3 deletions src/modm/platform/comp/stm32/module.lb
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Expand All @@ -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"



Expand Down Expand Up @@ -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
Expand All @@ -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

Expand All @@ -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"
Expand Down
2 changes: 1 addition & 1 deletion src/modm/platform/dma/stm32/dma.hpp.in
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
15 changes: 14 additions & 1 deletion src/modm/platform/timer/stm32/advanced.cpp.in
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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,
Expand Down
47 changes: 46 additions & 1 deletion src/modm/platform/timer/stm32/advanced.hpp.in
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,32 @@ public:
{
return (TIM{{ id }}->BDTR & TIM_BDTR_MOE);
}
%% if target.family in ["g0"]
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
Expand Down Expand Up @@ -357,7 +383,7 @@ public:
}

static inline void
setRepetitionCount(uint8_t repetitionCount)
setRepetitionCount(uint16_t repetitionCount)
{
TIM{{ id }}->RCR = repetitionCount;
}
Expand Down Expand Up @@ -407,6 +433,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<typename Signal>
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<Peripheral::Tim{{ id }}, Signal>();
configureOutputChannel(channel, mode, compareValue, out, polarity, out_n, polarity_n, preload);
}

/*
* Configure Output Channel without changing the Compare Value
*
Expand Down
7 changes: 7 additions & 0 deletions src/modm/platform/timer/stm32/advanced_base.hpp.in
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
37 changes: 30 additions & 7 deletions src/modm/platform/timer/stm32/general_purpose.cpp.in
Original file line number Diff line number Diff line change
Expand Up @@ -203,29 +203,53 @@ 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,
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<uint32_t>(mode) | static_cast<uint32_t>(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<uint32_t>(polarity_n) << 2) |
Expand All @@ -234,7 +258,6 @@ OutputComparePreload preload)

TIM{{ id }}->CCER |= flags << (channel * 4);
}
%% endif

// ----------------------------------------------------------------------------
void
Expand Down
Loading

0 comments on commit 77e028e

Please sign in to comment.