Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[stm32] Extend Timer features: PWM modes, Break Input and Comparator #1134

Merged
merged 2 commits into from
Mar 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
59 changes: 58 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,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
Expand Down Expand Up @@ -357,7 +395,7 @@ public:
}

static inline void
setRepetitionCount(uint8_t repetitionCount)
setRepetitionCount(uint16_t repetitionCount)
{
TIM{{ id }}->RCR = repetitionCount;
}
Expand Down Expand Up @@ -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<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