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* --------------------------------------------------------------------------------
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* ------------------------------------------------------------------------
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
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
114114
115115// MCPWM driver hardware timer pointers
116116mcpwm_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)
118118uint32_t pwm_periods[2 ][3 ];
119119// how many pins from the groups 6 pins is used
120120uint8_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
148148uint8_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, ¶ms->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, ¶ms->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, ¶ms->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, ¶ms->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
516516void _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