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