Skip to content

Commit 4e933aa

Browse files
Merge pull request #492 from uLipe/feature/improve_mcpwm
ESP32: improve PWM driver fast funcrtions
2 parents 1520b63 + 6703dfe commit 4e933aa

File tree

3 files changed

+80
-80
lines changed

3 files changed

+80
-80
lines changed

src/drivers/hardware_specific/esp32/esp32_driver_mcpwm.cpp

Lines changed: 50 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
* 6 PWM independent signals per unit
1515
* unit(0/1) > timer(0-2) > operator(0-2) > comparator(0-1) > generator(0-1) > pwm(A/B)
1616
*
17-
* -------------------------------------- Table View -----------------------------
17+
* -------------------------------------- Table View -----------------------------
1818
*
1919
* group | timer | operator | comparator | generator | pwm
2020
* --------------------------------------------------------------------------------
@@ -28,31 +28,31 @@
2828
* ------------------------------------- Example 3PWM ------------------------------
2929
* ┌─ comparator 0 - generator 0 -> pwm A
3030
* ┌─ operator 0 -|
31-
* | └─ comparator 1 - generator 1 -> pmw B
31+
* | └─ comparator 1 - generator 1 -> pmw B
3232
* unit - timer 0-2 -|
3333
* 0-1 └─ operator 1 - comparator 0 - generator 0 - pwm C
34-
*
34+
*
3535
* ------------------------------------- Example 2PWM ------------------------------
3636
* ┌─ comparator 0 - generator 0 -> pwm A
3737
* unit - timer 0-2 - operator 0 -|
38-
* 0-1 └─ comparator 1 - generator 1 -> pmw B
38+
* 0-1 └─ comparator 1 - generator 1 -> pmw B
3939
*
40-
* -------------------------------------- Example 4PWM -----------------------------
40+
* -------------------------------------- Example 4PWM -----------------------------
4141
* ┌─ comparator 0 - generator 0 -> pwm A
4242
* ┌─ operator 0 -|
43-
* | └─ comparator 1 - generator 1 -> pmw B
44-
* unit - timer 0-2 -|
43+
* | └─ comparator 1 - generator 1 -> pmw B
44+
* unit - timer 0-2 -|
4545
* 0-1 | ┌─ comparator 0 - generator 0 -> pwm C
4646
* └─ operator 1 -|
47-
* └─ comparator 0 - generator 0 -> pwm D
47+
* └─ comparator 0 - generator 0 -> pwm D
4848
4949
5050
* Complementary mode
5151
* ------------------
5252
* - : 3 pairs of complementary PWM signals per unit
5353
* unit(0/1) > timer(0) > operator(0-2) > comparator(0-1) > generator(0-1) > pwm(high/low pair)
54-
*
55-
* -------------------------------------- Table View -----------------------------
54+
*
55+
* -------------------------------------- Table View -----------------------------
5656
*
5757
* group | timer | operator | comparator | generator | pwm
5858
* ------------------------------------------------------------------------
@@ -63,26 +63,26 @@
6363
* 0-1 | 0 | 2 | 0 | 0 | A
6464
* 0-1 | 0 | 2 | 1 | 1 | B
6565
*
66-
* -------------------------------------- Example 6PWM -----------------------------
67-
*
66+
* -------------------------------------- Example 6PWM -----------------------------
67+
*
6868
* ┌─ comparator 0 - generator 0 -> pwm A_h
69-
* ┌─ operator 0 -|
69+
* ┌─ operator 0 -|
7070
* | └─ comparator 1 - generator 1 -> pmw A_l
71-
* |
71+
* |
7272
* unit | ┌─ comparator 0 - generator 0 -> pwm B_h
7373
* (group) - timer 0 -|- operator 1 -|
7474
* 0-1 | └─ comparator 1 - generator 1 -> pmw B_l
7575
* |
7676
* | ┌─ comparator 0 - generator 0 -> pwm C_h
7777
* └─ operator 2 -|
7878
* └─ comparator 1 - generator 1 -> pmw C_l
79-
*
79+
*
8080
8181
8282
* More info
8383
* ----------
8484
* - timers can be associated with any operator, and multiple operators can be associated with the same timer
85-
* - comparators can be associated with any operator
85+
* - comparators can be associated with any operator
8686
* - two comparators per operator for independent mode
8787
* - one comparator per operator for complementary mode
8888
* - generators can be associated with any comparator
@@ -96,7 +96,7 @@
9696
* and here: // https://docs.espressif.com/projects/esp-idf/en/v5.1.4/esp32/migration-guides/release-5.x/5.0/peripherals.html
9797
*/
9898

99-
#include "../../hardware_api.h"
99+
#include "../../hardware_api.h"
100100

101101
#if defined(ESP_H) && defined(ARDUINO_ARCH_ESP32) && defined(SOC_MCPWM_SUPPORTED) && !defined(SIMPLEFOC_ESP32_USELEDC)
102102

@@ -114,7 +114,7 @@
114114

115115
// MCPWM driver hardware timer pointers
116116
mcpwm_timer_handle_t timers[2][3] = {NULL};
117-
// MCPWM timer periods configured (directly related to the pwm frequency)
117+
// MCPWM timer periods configured (directly related to the pwm frequency)
118118
uint32_t pwm_periods[2][3];
119119
// how many pins from the groups 6 pins is used
120120
uint8_t group_pins_used[2] = {0};
@@ -143,7 +143,7 @@ uint8_t _findLastTimer(int group){
143143
// return the last index
144144
return i;
145145
}
146-
// returns the index of the next timer to instantiate
146+
// returns the index of the next timer to instantiate
147147
// -1 if no timers available
148148
uint8_t _findNextTimer(int group){
149149
int i = 0;
@@ -157,7 +157,7 @@ uint8_t _findNextTimer(int group){
157157

158158
/*
159159
* find the best group for the pins
160-
* if 6pwm
160+
* if 6pwm
161161
* - Only option is an an empty group
162162
* if 3pwm
163163
* - Best is an empty group (we can set a pwm frequency)
@@ -180,11 +180,11 @@ uint8_t _findNextTimer(int group){
180180
* For example if the group has already used 3pwms, there is one generator that has one pwm channel left.
181181
* If we use this channel we have to use the same timer it has been used with before, so we cannot change the pwm frequency.
182182
* Current implementation does use the remaining channel only if there isn't other options that would allow changing the pwm frequency.
183-
* In this example where we have 3pwms already configured, if we try to configure 2pws after, we will skip the remaining channel
183+
* In this example where we have 3pwms already configured, if we try to configure 2pws after, we will skip the remaining channel
184184
* and use a new timer and operator to allow changing the pwm frequency. In such cases we loose (cannot be used) the remaining channel.
185185
* TODO: use the pwm_frequency to avoid skipping pwm channels !
186186
*
187-
* returns
187+
* returns
188188
* - 1 if solution found in one group
189189
* - 2 if solution requires using both groups
190190
* - 0 if no solution possible
@@ -199,13 +199,13 @@ int _findBestGroup(int no_pins, long pwm_freq, int* group, int* timer){
199199
}
200200
}
201201

202-
// if 3 or 1pwm
202+
// if 3 or 1pwm
203203
// check if there is available space in one of the groups
204204
// otherwise fail
205205
if(no_pins == 3 || no_pins==1){
206-
// second best option is if there is a group with
207-
// pair number of pwms available as we can then
208-
// set the pwm frequency
206+
// second best option is if there is a group with
207+
// pair number of pwms available as we can then
208+
// set the pwm frequency
209209
for(int i=0; i<SOC_MCPWM_GROUPS; i++){
210210
if(_hasAvailablePins(i, no_pins+1)) {
211211
*group=i;
@@ -284,13 +284,13 @@ void* _configure6PWMPinsMCPWM(long pwm_frequency, int mcpwm_group, int timer_no,
284284
.pwm_frequency = pwm_frequency,
285285
.group_id = mcpwm_group
286286
};
287-
287+
288288
mcpwm_timer_config_t pwm_config;
289289
pwm_config.group_id = mcpwm_group;
290290
pwm_config.clk_src = MCPWM_TIMER_CLK_SRC_DEFAULT;
291291
pwm_config.resolution_hz = _PWM_TIMEBASE_RESOLUTION_HZ;
292-
pwm_config.count_mode = MCPWM_TIMER_COUNT_MODE_UP_DOWN;
293-
pwm_config.intr_priority = 0;
292+
pwm_config.count_mode = MCPWM_TIMER_COUNT_MODE_UP_DOWN;
293+
pwm_config.intr_priority = 0;
294294
pwm_config.period_ticks = _calcPWMPeriod(pwm_frequency);
295295
#ifdef ESP_IDF_VERSION_ABOVE_5_4_0
296296
pwm_config.flags.allow_pd = 0;
@@ -302,7 +302,7 @@ void* _configure6PWMPinsMCPWM(long pwm_frequency, int mcpwm_group, int timer_no,
302302
params->mcpwm_period = pwm_periods[mcpwm_group][timer_no];
303303

304304
uint8_t no_operators = 3; // use 3 comparators one per pair of pwms
305-
SIMPLEFOC_ESP32_DRV_DEBUG("Configuring " + String(no_operators) + " operators.");
305+
SIMPLEFOC_ESP32_DRV_DEBUG("Configuring " + String(no_operators) + " operators.");
306306
mcpwm_operator_config_t operator_config = { .group_id = mcpwm_group };
307307
operator_config.intr_priority = 0;
308308
operator_config.flags.update_gen_action_on_tep = true;
@@ -313,9 +313,9 @@ void* _configure6PWMPinsMCPWM(long pwm_frequency, int mcpwm_group, int timer_no,
313313
}
314314

315315
#if SIMPLEFOC_ESP32_HW_DEADTIME == true // hardware dead-time (hardware 6pwm)
316-
316+
317317
SIMPLEFOC_ESP32_DRV_DEBUG("Configuring 6PWM with hardware dead-time");
318-
318+
319319
SIMPLEFOC_ESP32_DRV_DEBUG("Configuring " + String(no_operators) + " comparators.");
320320
// Create and configure comparators
321321
mcpwm_comparator_config_t comparator_config = {0};
@@ -324,7 +324,7 @@ void* _configure6PWMPinsMCPWM(long pwm_frequency, int mcpwm_group, int timer_no,
324324
CHECK_ERR(mcpwm_new_comparator(params->oper[i], &comparator_config, &params->comparator[i]),"Could not create comparator: " + String(i));
325325
CHECK_ERR(mcpwm_comparator_set_compare_value(params->comparator[i], (0)), "Could not set duty on comparator: " + String(i));
326326
}
327-
327+
328328
#else // software dead-time (software 6pwm)
329329
// software dead-time (software 6pwm)
330330
SIMPLEFOC_ESP32_DRV_DEBUG("Configuring 6PWM with software dead-time");
@@ -339,7 +339,7 @@ void* _configure6PWMPinsMCPWM(long pwm_frequency, int mcpwm_group, int timer_no,
339339
CHECK_ERR(mcpwm_new_comparator(params->oper[oper_index], &comparator_config, &params->comparator[i]),"Could not create comparator: " + String(i));
340340
CHECK_ERR(mcpwm_comparator_set_compare_value(params->comparator[i], (0)), "Could not set duty on comparator: " + String(i));
341341
}
342-
#endif
342+
#endif
343343

344344
int no_generators = 6; // one per pwm
345345
SIMPLEFOC_ESP32_DRV_DEBUG("Configuring " + String(no_generators) + " generators.");
@@ -355,9 +355,9 @@ void* _configure6PWMPinsMCPWM(long pwm_frequency, int mcpwm_group, int timer_no,
355355

356356
#if SIMPLEFOC_ESP32_HW_DEADTIME == true // hardware dead-time (hardware 6pwm)
357357
for (int i = 0; i < no_operators; i++) {
358-
CHECK_ERR(_configureCenterAlign(params->generator[2*i],params->comparator[i]), "Failed to configure high-side center align pwm: " + String(2*i));
359-
CHECK_ERR(_configureCenterAlign(params->generator[2*i+1],params->comparator[i]), "Failed to configure low-side center align pwm: " + String(2*i+1));
360-
358+
CHECK_ERR(_configureCenterAlign(params->generator[2*i],params->comparator[i]), "Failed to configure high-side center align pwm: " + String(2*i));
359+
CHECK_ERR(_configureCenterAlign(params->generator[2*i+1],params->comparator[i]), "Failed to configure low-side center align pwm: " + String(2*i+1));
360+
361361
}
362362
// only available for 6pwm
363363
SIMPLEFOC_ESP32_DRV_DEBUG("Configuring dead-time.");
@@ -369,15 +369,15 @@ void* _configure6PWMPinsMCPWM(long pwm_frequency, int mcpwm_group, int timer_no,
369369
mcpwm_dead_time_config_t dt_config_low;
370370
dt_config_low.posedge_delay_ticks = 0;
371371
dt_config_low.negedge_delay_ticks = dead_time;
372-
dt_config_low.flags.invert_output = SIMPLEFOC_PWM_LOWSIDE_ACTIVE_HIGH;
372+
dt_config_low.flags.invert_output = SIMPLEFOC_PWM_LOWSIDE_ACTIVE_HIGH;
373373
for (int i = 0; i < no_operators; i++) {
374374
CHECK_ERR(mcpwm_generator_set_dead_time(params->generator[2*i], params->generator[2*i], &dt_config_high),"Could not set dead time for generator: " + String(i));
375375
CHECK_ERR(mcpwm_generator_set_dead_time(params->generator[2*i+1], params->generator[2*i+1], &dt_config_low),"Could not set dead time for generator: " + String(i+1));
376376
}
377377
#else // software dead-time (software 6pwm)
378378
for (int i = 0; i < 3; i++) {
379-
CHECK_ERR(_configureCenterAlign(params->generator[2*i],params->comparator[2*i], !SIMPLEFOC_PWM_HIGHSIDE_ACTIVE_HIGH), "Failed to configure high-side center align pwm: " + String(2*i));
380-
CHECK_ERR(_configureCenterAlign(params->generator[2*i+1],params->comparator[2*i+1], SIMPLEFOC_PWM_LOWSIDE_ACTIVE_HIGH) , "Failed to configure low-side center align pwm: " + String(2*i+1));
379+
CHECK_ERR(_configureCenterAlign(params->generator[2*i],params->comparator[2*i], !SIMPLEFOC_PWM_HIGHSIDE_ACTIVE_HIGH), "Failed to configure high-side center align pwm: " + String(2*i));
380+
CHECK_ERR(_configureCenterAlign(params->generator[2*i+1],params->comparator[2*i+1], SIMPLEFOC_PWM_LOWSIDE_ACTIVE_HIGH) , "Failed to configure low-side center align pwm: " + String(2*i+1));
381381
}
382382
#endif
383383

@@ -412,16 +412,16 @@ void* _configurePinsMCPWM(long pwm_frequency, int mcpwm_group, int timer_no, int
412412
.pwm_frequency = pwm_frequency,
413413
.group_id = mcpwm_group
414414
};
415-
415+
416416
bool shared_timer = false;
417417
// check if timer is configured
418418
if (timers[mcpwm_group][timer_no] == NULL){
419419
mcpwm_timer_config_t pwm_config;
420420
pwm_config.group_id = mcpwm_group;
421421
pwm_config.clk_src = MCPWM_TIMER_CLK_SRC_DEFAULT;
422422
pwm_config.resolution_hz = _PWM_TIMEBASE_RESOLUTION_HZ;
423-
pwm_config.count_mode = MCPWM_TIMER_COUNT_MODE_UP_DOWN;
424-
pwm_config.intr_priority = 0;
423+
pwm_config.count_mode = MCPWM_TIMER_COUNT_MODE_UP_DOWN;
424+
pwm_config.intr_priority = 0;
425425
pwm_config.period_ticks = _calcPWMPeriod(pwm_frequency);
426426
#ifdef ESP_IDF_VERSION_ABOVE_5_4_0
427427
pwm_config.flags.allow_pd = 0;
@@ -430,10 +430,10 @@ void* _configurePinsMCPWM(long pwm_frequency, int mcpwm_group, int timer_no, int
430430
CHECK_ERR(mcpwm_new_timer(&pwm_config, &timers[mcpwm_group][timer_no]), "Could not initialize the timer in group: " + String(mcpwm_group));
431431
// save variables for later
432432
pwm_periods[mcpwm_group][timer_no] = pwm_config.period_ticks / 2;
433-
params->timers[0] = timers[mcpwm_group][timer_no];
433+
params->timers[0] = timers[mcpwm_group][timer_no];
434434
// if the numer of used channels it not pair skip one channel
435435
// the skipped channel cannot be used with the new timer
436-
// TODO avoid loosing channels like this
436+
// TODO avoid loosing channels like this
437437
if(group_pins_used[mcpwm_group] %2) group_pins_used[mcpwm_group]++;
438438
}else{
439439
// we will use an already instantiated timer
@@ -446,7 +446,7 @@ void* _configurePinsMCPWM(long pwm_frequency, int mcpwm_group, int timer_no, int
446446
return SIMPLEFOC_DRIVER_INIT_FAILED;
447447
}
448448
CHECK_ERR(mcpwm_timer_start_stop( params->timers[0], MCPWM_TIMER_STOP_EMPTY), "Failed to stop the timer!");
449-
449+
450450
shared_timer = true;
451451
}
452452

@@ -463,7 +463,7 @@ void* _configurePinsMCPWM(long pwm_frequency, int mcpwm_group, int timer_no, int
463463
}
464464
CHECK_ERR(mcpwm_new_operator(&operator_config, &params->oper[i]),"Could not create operator "+String(i));
465465
CHECK_ERR(mcpwm_operator_connect_timer(params->oper[i], params->timers[0]),"Could not connect timer to operator: " + String(i));
466-
}
466+
}
467467
// save the last operator in this group
468468
last_operator[mcpwm_group] = params->oper[no_operators - 1];
469469

@@ -485,7 +485,7 @@ void* _configurePinsMCPWM(long pwm_frequency, int mcpwm_group, int timer_no, int
485485
int oper_index = shared_timer ? (int)floor((i + 1) / 2) : (int)floor(i / 2);
486486
CHECK_ERR(mcpwm_new_generator(params->oper[oper_index], &generator_config, &params->generator[i]), "Could not create generator " + String(i) +String(" on pin: ")+String(pins[i]));
487487
}
488-
488+
489489

490490
SIMPLEFOC_ESP32_DRV_DEBUG("Configuring center-aligned pwm.");
491491
for (int i = 0; i < no_pins; i++) {
@@ -507,15 +507,15 @@ void* _configurePinsMCPWM(long pwm_frequency, int mcpwm_group, int timer_no, int
507507
}
508508

509509
// function setting the duty cycle to the MCPWM pin
510-
void _setDutyCycle(mcpwm_cmpr_handle_t cmpr, uint32_t mcpwm_period, float duty_cycle){
510+
void IRAM_ATTR _setDutyCycle(mcpwm_cmpr_handle_t cmpr, uint32_t mcpwm_period, float duty_cycle){
511511
float duty = _constrain(duty_cycle, 0.0, 1.0);
512512
mcpwm_comparator_set_compare_value(cmpr, (uint32_t)(mcpwm_period*duty));
513513
}
514514

515515
// function setting the duty cycle to the MCPWM pin
516516
void _forcePhaseState(mcpwm_gen_handle_t generator_high, mcpwm_gen_handle_t generator_low, PhaseState phase_state){
517517
// phase state is forced in hardware pwm mode
518-
// esp-idf docs: https://docs.espressif.com/projects/esp-idf/en/v5.1.4/esp32/api-reference/peripherals/mcpwm.html#generator-force-actions
518+
// esp-idf docs: https://docs.espressif.com/projects/esp-idf/en/v5.1.4/esp32/api-reference/peripherals/mcpwm.html#generator-force-actions
519519
// github issue: https://github.com/espressif/esp-idf/issues/12237
520520
mcpwm_generator_set_force_level(generator_high, (phase_state == PHASE_ON || phase_state == PHASE_HI) ? -1 : 0, true);
521521
mcpwm_generator_set_force_level(generator_low, (phase_state == PHASE_ON || phase_state == PHASE_LO) ? -1 : 1, true);

0 commit comments

Comments
 (0)