Skip to content

Commit 5f9365d

Browse files
feat: enhance LpTimerPwm with LL API and polarity configuration (#654)
* LpTimerPwmDelayed * Use LL API to start and stop timer channels Starting channels using the HAL API will automatically start the timer peripheral. The LL API allow more control. * Allow polarity configuration * Rename to LpTimerPwm * Apply suggested changes Co-authored-by: Richard Peters <[email protected]> --------- Co-authored-by: Richard Peters <[email protected]>
1 parent 2367982 commit 5f9365d

File tree

2 files changed

+71
-16
lines changed

2 files changed

+71
-16
lines changed

hal_st/stm32fxxx/LpTimerPwmStm.cpp

Lines changed: 42 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -47,19 +47,30 @@ namespace hal
4747
{
4848
LpTimerPwmBaseStm::LpTimerPwmBaseStm(uint8_t oneBasedIndex, LowPowerTimerBaseStm::Timing timing)
4949
: timer(oneBasedIndex, timing)
50-
{}
50+
{
51+
LL_LPTIM_SetWaveform(timer.Handle().Instance, LL_LPTIM_OUTPUT_WAVEFORM_PWM);
52+
}
5153

5254
LpPwmChannelGpio& LpTimerPwmBaseStm::Channel(uint8_t channelOneBasedIndex)
5355
{
5456
return channels[channelOneBasedIndex - 1];
5557
}
5658

57-
void LpTimerPwmBaseStm::Start()
59+
void LpTimerPwmBaseStm::StartTimer()
60+
{
61+
timer.Start();
62+
}
63+
64+
void LpTimerPwmBaseStm::StartChannels()
5865
{
5966
for (auto& channel : channels)
6067
channel.Start();
68+
}
6169

62-
timer.Start();
70+
void LpTimerPwmBaseStm::Start()
71+
{
72+
StartChannels();
73+
StartTimer();
6374
}
6475

6576
void LpTimerPwmBaseStm::Stop()
@@ -70,19 +81,41 @@ namespace hal
7081
channel.Stop();
7182
}
7283

73-
LpPwmChannelGpio::LpPwmChannelGpio(uint8_t timerOneBasedIndex, uint8_t channelOneBasedIndex, LPTIM_HandleTypeDef& handle, GpioPinStm& pin)
84+
LpTimerPwm::LpTimerPwm(infra::BoundedDeque<LpPwmChannelGpio>& channelStorage, uint8_t oneBasedIndex, LowPowerTimerBaseStm::Timing timing)
85+
: LpTimerPwmBaseStm(oneBasedIndex, timing)
86+
, channelStorage(channelStorage)
87+
, oneBasedIndex(oneBasedIndex)
88+
{}
89+
90+
LpPwmChannelGpio& LpTimerPwm::Channel(uint8_t channelOneBasedIndex)
91+
{
92+
for (auto& channel : channelStorage)
93+
{
94+
if (channel.channelIndex == channelOneBasedIndex - 1)
95+
return channel;
96+
}
97+
std::abort();
98+
}
99+
100+
void LpTimerPwm::ConfigureChannel(uint8_t channelOneBasedIndex, GpioPinStm& pin)
101+
{
102+
channelStorage.emplace_back(oneBasedIndex, channelOneBasedIndex, timer.Handle(), pin);
103+
channels = channelStorage.contiguous_range(channelStorage.begin());
104+
}
105+
106+
LpPwmChannelGpio::LpPwmChannelGpio(uint8_t timerOneBasedIndex, uint8_t channelOneBasedIndex, LPTIM_HandleTypeDef& handle, GpioPinStm& pin, uint32_t polarity)
74107
: timerIndex(timerOneBasedIndex - 1)
75108
, channelIndex(channelOneBasedIndex - 1)
76109
, handle(handle)
77110
, pin(pin, GetChannelPinConfig(channelIndex), timerOneBasedIndex)
78111
, ccr(GetCCRegister(handle.Instance, channelIndex))
79112
{
80-
ConfigChannelInit();
113+
ConfigurePolarity(polarity);
81114
}
82115

83-
void LpPwmChannelGpio::ConfigChannelInit()
116+
void LpPwmChannelGpio::ConfigurePolarity(uint32_t polarity)
84117
{
85-
LPTIM_OC_ConfigTypeDef sConfig = { .OCPolarity = LPTIM_OCPOLARITY_HIGH };
118+
LPTIM_OC_ConfigTypeDef sConfig = { .OCPolarity = polarity };
86119
auto result = HAL_LPTIM_OC_ConfigChannel(&handle, &sConfig, GetLpTimerChannel(channelIndex));
87120
assert(result == HAL_OK);
88121
}
@@ -101,14 +134,12 @@ namespace hal
101134

102135
void LpPwmChannelGpio::Start()
103136
{
104-
auto result = HAL_LPTIM_PWM_Start(&handle, GetLpTimerChannel(channelIndex));
105-
really_assert(result == HAL_OK);
137+
LL_LPTIM_CC_EnableChannel(handle.Instance, GetLpTimerChannel(channelIndex));
106138
}
107139

108140
void LpPwmChannelGpio::Stop()
109141
{
110-
auto result = HAL_LPTIM_PWM_Stop(&handle, GetLpTimerChannel(channelIndex));
111-
really_assert(result == HAL_OK);
142+
LL_LPTIM_CC_DisableChannel(handle.Instance, GetLpTimerChannel(channelIndex));
112143
}
113144
}
114145

hal_st/stm32fxxx/LpTimerPwmStm.hpp

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#include "hal/interfaces/PulseWidthModulation.hpp"
55
#include "hal_st/stm32fxxx/GpioStm.hpp"
66
#include "hal_st/stm32fxxx/LpTimerStm.hpp"
7+
#include "infra/util/BoundedDeque.hpp"
78
#include "infra/util/MemoryRange.hpp"
89
#include <array>
910
#include <cstddef>
@@ -19,7 +20,7 @@ namespace hal
1920
template<typename T, std::size_t... Is>
2021
constexpr std::array<T, sizeof...(Is)> CreateArray(uint8_t timerOneBasedIndex, LPTIM_HandleTypeDef& handle, infra::MemoryRange<GpioPinStm> pins, std::index_sequence<Is...>)
2122
{
22-
return {{(Is, T{timerOneBasedIndex, Is + 1, handle, pins[Is]})...}};
23+
return { { (Is, T{ timerOneBasedIndex, Is + 1, handle, pins[Is] })... } };
2324
}
2425
}
2526

@@ -36,8 +37,11 @@ namespace hal
3637
public:
3738
LpTimerPwmBaseStm(uint8_t oneBasedIndex, LowPowerTimerBaseStm::Timing timing);
3839

39-
LpPwmChannelGpio& Channel(uint8_t channelOneBasedIndex);
40+
virtual LpPwmChannelGpio& Channel(uint8_t channelOneBasedIndex);
4041

42+
// Timer and configured channels can either be started independently from each other by invoking StartTimer() and StartChannels(), or together by invoking Start()
43+
void StartTimer();
44+
void StartChannels();
4145
void Start();
4246
void Stop();
4347

@@ -62,25 +66,45 @@ namespace hal
6266
std::array<LpPwmChannelGpio, Channels> channelStorage;
6367
};
6468

69+
class LpTimerPwm
70+
: public LpTimerPwmBaseStm
71+
{
72+
public:
73+
template<std::size_t Channels>
74+
using WithChannels = infra::WithStorage<LpTimerPwm, infra::BoundedDeque<LpPwmChannelGpio>::WithMaxSize<Channels>>;
75+
76+
LpTimerPwm(infra::BoundedDeque<LpPwmChannelGpio>& channelStorage, uint8_t oneBasedIndex, LowPowerTimerBaseStm::Timing timing);
77+
78+
void ConfigureChannel(uint8_t channelOneBasedIndex, GpioPinStm& pin);
79+
LpPwmChannelGpio& Channel(uint8_t channelOneBasedIndex) override;
80+
81+
private:
82+
infra::BoundedDeque<LpPwmChannelGpio>& channelStorage;
83+
uint8_t oneBasedIndex;
84+
};
85+
6586
class LpPwmChannelGpio
6687
: public PulseWidthModulation
6788
{
6889
public:
69-
LpPwmChannelGpio(uint8_t timerOneBasedIndex, uint8_t channelOneBasedIndex, LPTIM_HandleTypeDef& handle, GpioPinStm& pin);
90+
LpPwmChannelGpio(uint8_t timerOneBasedIndex, uint8_t channelOneBasedIndex, LPTIM_HandleTypeDef& handle, GpioPinStm& pin, uint32_t polarity = LPTIM_OCPOLARITY_HIGH);
7091

92+
// Implementation of PulseWidthModulation
7193
void SetDuty(uint8_t dutyPercent) override;
7294
void SetPulse(uint32_t pulseOn, uint32_t period) override;
7395
void Start() override;
7496
void Stop() override;
7597

98+
void ConfigurePolarity(uint32_t polarity);
99+
76100
private:
101+
friend LpTimerPwm;
102+
77103
uint8_t timerIndex;
78104
uint8_t channelIndex;
79105
LPTIM_HandleTypeDef& handle;
80106
PeripheralPinStm pin;
81107
volatile std::uint32_t* ccr;
82-
83-
void ConfigChannelInit();
84108
};
85109
}
86110

0 commit comments

Comments
 (0)