Skip to content

Commit 925a1e4

Browse files
author
Richard Unger
committed
stm32 PWM polarity via SIMPLEFOC_PWM_ACTIVE_HIGH
1 parent 3915891 commit 925a1e4

File tree

3 files changed

+66
-48
lines changed

3 files changed

+66
-48
lines changed

src/drivers/hardware_api.h

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,27 @@
66
#include "../communication/SimpleFOCDebug.h"
77

88

9+
// these defines determine the polarity of the PWM output. Normally, the polarity is active-high,
10+
// i.e. a high-level PWM output is expected to switch on the MOSFET. But should your driver design
11+
// require inverted polarity, you can change the defines below, or set them via your build environment
12+
// or board definition files.
13+
14+
// used for 1-PWM, 2-PWM, 3-PWM, and 4-PWM modes
15+
#ifndef SIMPLEFOC_PWM_ACTIVE_HIGH
16+
#define SIMPLEFOC_PWM_ACTIVE_HIGH true
17+
#endif
18+
// used for 6-PWM mode, high-side
19+
#ifndef SIMPLEFOC_PWM_HIGHSIDE_ACTIVE_HIGH
20+
#define SIMPLEFOC_PWM_HIGHSIDE_ACTIVE_HIGH true
21+
#endif
22+
// used for 6-PWM mode, low-side
23+
#ifndef SIMPLEFOC_PWM_LOWSIDE_ACTIVE_HIGH
24+
#define SIMPLEFOC_PWM_LOWSIDE_ACTIVE_HIGH true
25+
#endif
26+
27+
28+
29+
930
// flag returned if driver init fails
1031
#define SIMPLEFOC_DRIVER_INIT_FAILED ((void*)-1)
1132

src/drivers/hardware_specific/rp2040_mcu.cpp

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -9,24 +9,6 @@
99
#include "../hardware_api.h"
1010
#include "./rp2040_mcu.h"
1111

12-
// these defines determine the polarity of the PWM output. Normally, the polarity is active-high,
13-
// i.e. a high-level PWM output is expected to switch on the MOSFET. But should your driver design
14-
// require inverted polarity, you can change the defines below, or set them via your build environment
15-
// or board definition files.
16-
17-
// used for 2-PWM, 3-PWM, and 4-PWM modes
18-
#ifndef SIMPLEFOC_PWM_ACTIVE_HIGH
19-
#define SIMPLEFOC_PWM_ACTIVE_HIGH true
20-
#endif
21-
// used fof 6-PWM mode, high-side
22-
#ifndef SIMPLEFOC_PWM_HIGHSIDE_ACTIVE_HIGH
23-
#define SIMPLEFOC_PWM_HIGHSIDE_ACTIVE_HIGH true
24-
#endif
25-
// used fof 6-PWM mode, low-side
26-
#ifndef SIMPLEFOC_PWM_LOWSIDE_ACTIVE_HIGH
27-
#define SIMPLEFOC_PWM_LOWSIDE_ACTIVE_HIGH true
28-
#endif
29-
3012

3113
#define _PWM_FREQUENCY 24000
3214
#define _PWM_FREQUENCY_MAX 66000

src/drivers/hardware_specific/stm32_mcu.cpp

Lines changed: 45 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,34 @@ void _setPwm(HardwareTimer *HT, uint32_t channel, uint32_t value, int resolution
4141

4242

4343

44+
int getLLChannel(PinMap* timer) {
45+
#if defined(TIM_CCER_CC1NE)
46+
if (STM_PIN_INVERTED(timer->function)) {
47+
switch (STM_PIN_CHANNEL(timer->function)) {
48+
case 1: return LL_TIM_CHANNEL_CH1N;
49+
case 2: return LL_TIM_CHANNEL_CH2N;
50+
case 3: return LL_TIM_CHANNEL_CH3N;
51+
#if defined(LL_TIM_CHANNEL_CH4N)
52+
case 4: return LL_TIM_CHANNEL_CH4N;
53+
#endif
54+
default: return -1;
55+
}
56+
} else
57+
#endif
58+
{
59+
switch (STM_PIN_CHANNEL(timer->function)) {
60+
case 1: return LL_TIM_CHANNEL_CH1;
61+
case 2: return LL_TIM_CHANNEL_CH2;
62+
case 3: return LL_TIM_CHANNEL_CH3;
63+
case 4: return LL_TIM_CHANNEL_CH4;
64+
default: return -1;
65+
}
66+
}
67+
return -1;
68+
}
69+
70+
71+
4472

4573

4674
// init pin pwm
@@ -63,6 +91,9 @@ HardwareTimer* _initPinPWM(uint32_t PWM_freq, PinMap* timer) {
6391
if (init)
6492
HT->setOverflow(PWM_freq, HERTZ_FORMAT);
6593
HT->setMode(channel, TIMER_OUTPUT_COMPARE_PWM1, timer->pin);
94+
#if SIMPLEFOC_PWM_ACTIVE_HIGH==false
95+
LL_TIM_OC_SetPolarity(HT->getHandle()->Instance, getLLChannel(timer), LL_TIM_OCPOLARITY_LOW);
96+
#endif
6697
#ifdef SIMPLEFOC_STM32_DEBUG
6798
SIMPLEFOC_DEBUG("STM32-DRV: Configuring high timer ", (int)getTimerNumber(get_timer_index(HardwareTimer_Handle[index]->handle.Instance)));
6899
SIMPLEFOC_DEBUG("STM32-DRV: Configuring high channel ", (int)channel);
@@ -78,7 +109,11 @@ HardwareTimer* _initPinPWM(uint32_t PWM_freq, PinMap* timer) {
78109

79110
// init high side pin
80111
HardwareTimer* _initPinPWMHigh(uint32_t PWM_freq, PinMap* timer) {
81-
return _initPinPWM(PWM_freq, timer);
112+
HardwareTimer* HT = _initPinPWM(PWM_freq, timer);
113+
#if SIMPLEFOC_PWM_HIGHSIDE_ACTIVE_HIGH==false && SIMPLEFOC_PWM_ACTIVE_HIGH==true
114+
LL_TIM_OC_SetPolarity(HT->getHandle()->Instance, getLLChannel(timer), LL_TIM_OCPOLARITY_LOW);
115+
#endif
116+
return HT;
82117
}
83118

84119
// init low side pin
@@ -107,6 +142,9 @@ HardwareTimer* _initPinPWMLow(uint32_t PWM_freq, PinMap* timer)
107142
HT->setOverflow(PWM_freq, HERTZ_FORMAT);
108143
// sets internal fields of HT, but we can't set polarity here
109144
HT->setMode(channel, TIMER_OUTPUT_COMPARE_PWM2, timer->pin);
145+
#if SIMPLEFOC_PWM_LOWSIDE_ACTIVE_HIGH==false
146+
LL_TIM_OC_SetPolarity(HT->getHandle()->Instance, getLLChannel(timer), LL_TIM_OCPOLARITY_LOW);
147+
#endif
110148
return HT;
111149
}
112150

@@ -213,34 +251,6 @@ void _alignTimersNew() {
213251

214252

215253

216-
int getLLChannel(PinMap* timer) {
217-
#if defined(TIM_CCER_CC1NE)
218-
if (STM_PIN_INVERTED(timer->function)) {
219-
switch (STM_PIN_CHANNEL(timer->function)) {
220-
case 1: return LL_TIM_CHANNEL_CH1N;
221-
case 2: return LL_TIM_CHANNEL_CH2N;
222-
case 3: return LL_TIM_CHANNEL_CH3N;
223-
#if defined(LL_TIM_CHANNEL_CH4N)
224-
case 4: return LL_TIM_CHANNEL_CH4N;
225-
#endif
226-
default: return -1;
227-
}
228-
} else
229-
#endif
230-
{
231-
switch (STM_PIN_CHANNEL(timer->function)) {
232-
case 1: return LL_TIM_CHANNEL_CH1;
233-
case 2: return LL_TIM_CHANNEL_CH2;
234-
case 3: return LL_TIM_CHANNEL_CH3;
235-
case 4: return LL_TIM_CHANNEL_CH4;
236-
default: return -1;
237-
}
238-
}
239-
return -1;
240-
}
241-
242-
243-
244254

245255
// configure hardware 6pwm for a complementary pair of channels
246256
STM32DriverParams* _initHardware6PWMPair(long PWM_freq, float dead_zone, PinMap* pinH, PinMap* pinL, STM32DriverParams* params, int paramsPos) {
@@ -278,8 +288,13 @@ STM32DriverParams* _initHardware6PWMPair(long PWM_freq, float dead_zone, PinMap*
278288
uint32_t dead_time_ns = (float)(1e9f/PWM_freq)*dead_zone;
279289
uint32_t dead_time = __LL_TIM_CALC_DEADTIME(SystemCoreClock, LL_TIM_GetClockDivision(HT->getHandle()->Instance), dead_time_ns);
280290
LL_TIM_OC_SetDeadTime(HT->getHandle()->Instance, dead_time); // deadtime is non linear!
291+
#if SIMPLEFOC_PWM_HIGHSIDE_ACTIVE_HIGH==false
292+
LL_TIM_OC_SetPolarity(HT->getHandle()->Instance, getLLChannel(pinH), LL_TIM_OCPOLARITY_LOW);
293+
#endif
294+
#if SIMPLEFOC_PWM_LOWSIDE_ACTIVE_HIGH==false
295+
LL_TIM_OC_SetPolarity(HT->getHandle()->Instance, getLLChannel(pinL), LL_TIM_OCPOLARITY_LOW);
296+
#endif
281297
LL_TIM_CC_EnableChannel(HT->getHandle()->Instance, getLLChannel(pinH) | getLLChannel(pinL));
282-
283298
HT->pause();
284299

285300
params->timers[paramsPos] = HT;

0 commit comments

Comments
 (0)