Skip to content

Commit 26d111d

Browse files
committed
added the 6wpm driver
1 parent ae4df18 commit 26d111d

File tree

1 file changed

+127
-34
lines changed

1 file changed

+127
-34
lines changed

src/drivers/hardware_specific/esp32/esp32_ledc_mcu.cpp

Lines changed: 127 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -75,11 +75,12 @@ bool _ledcAttachChannelAdvanced(uint8_t pin, int _channel, int _group, uint32_t
7575
ledc_timer.freq_hz = freq;
7676
ledc_timer.clk_cfg = LEDC_AUTO_CLK;
7777
if (ledc_timer_config(&ledc_timer) != ESP_OK) {
78+
SIMPLEFOC_DEBUG("EP32-DRV: ERROR - Failed to configure the timer:", LEDC_TIMER_0);
7879
return false;
7980
}
8081

8182
// if active high is false invert
82-
int pin_high_level = SIMPLEFOC_PWM_ACTIVE_HIGH ? 1 : 0;
83+
int pin_high_level = SIMPLEFOC_PWM_ACTIVE_HIGH ? 0 : 1;
8384
if (inverted) pin_high_level = !pin_high_level;
8485

8586
uint32_t duty = ledc_get_duty(group, channel);
@@ -91,28 +92,31 @@ bool _ledcAttachChannelAdvanced(uint8_t pin, int _channel, int _group, uint32_t
9192
ledc_channel.gpio_num = pin;
9293
ledc_channel.duty = duty;
9394
ledc_channel.hpoint = 0;
94-
ledc_channel.flags.output_invert = pin_high_level;
95+
ledc_channel.flags.output_invert = pin_high_level; // 0 is active high, 1 is active low
9596
if (ledc_channel_config(&ledc_channel)!= ESP_OK) {
97+
SIMPLEFOC_DEBUG("EP32-DRV: ERROR - Failed to attach channel:", _channel);
9698
return false;
9799
}
98100

99101
return true;
100102
}
101103

104+
105+
// returns the number of available channels in the group
106+
int _availableGroupChannels(int group){
107+
if(group == 0) return LEDC_CHANNELS_GROUP0 - group_channels_used[0];
108+
else if(group == 1) return LEDC_CHANNELS_GROUP1 - group_channels_used[1];
109+
return 0;
110+
}
111+
102112
// returns the number of the group that has enough channels available
103113
// returns -1 if no group has enough channels
104114
//
105115
// NOT IMPLEMENTED BUT COULD BE USEFUL
106116
// returns 2 if no group has enough channels but combined they do
107117
int _findGroupWithChannelsAvailable(int no_channels){
108-
if (group_channels_used[0] + no_channels < LEDC_CHANNELS_GROUP0){
109-
return 0;
110-
}else if (group_channels_used[1] + no_channels < LEDC_CHANNELS_GROUP1){
111-
return 1;
112-
}
113-
// else if (group_channels_used[0] + group_channels_used[1] + no_channels < LEDC_CHANNELS){
114-
// return 2;
115-
// }
118+
if(no_channels <= _availableGroupChannels(0)) return 0;
119+
if(no_channels <= _availableGroupChannels(1)) return 1;
116120
return -1;
117121
}
118122

@@ -132,11 +136,12 @@ void* _configure1PWM(long pwm_frequency, const int pinA) {
132136

133137
// configure the channel
134138
group_channels_used[group] += 1;
135-
if(!_ledcAttachChannelAdvanced(pinA, group_channels_used[group], group, pwm_frequency, _PWM_RES_BIT, false)) {
136-
SIMPLEFOC_DEBUG("EP32-DRV: ERROR - Failed to attach channel:", group_channels_used[group]);
139+
if(!_ledcAttachChannelAdvanced(pinA, group_channels_used[group], group, pwm_frequency, _PWM_RES_BIT, false)){
140+
SIMPLEFOC_DEBUG("EP32-DRV: ERROR - Failed to configure pin:", pinA);
137141
return SIMPLEFOC_DRIVER_INIT_FAILED;
138142
}
139-
143+
144+
140145
ESP32LEDCDriverParams* params = new ESP32LEDCDriverParams {
141146
.channels = { static_cast<ledc_channel_t>(group_channels_used[group]) },
142147
.groups = { (ledc_mode_t)group },
@@ -177,9 +182,10 @@ void* _configure2PWM(long pwm_frequency, const int pinA, const int pinB) {
177182
for(int i = 0; i < 2; i++){
178183
group_channels_used[group]++;
179184
if(!_ledcAttachChannelAdvanced(pins[i], group_channels_used[group], group, pwm_frequency, _PWM_RES_BIT, false)){
180-
SIMPLEFOC_DEBUG("EP32-DRV: ERROR - Failed to attach channel:", group_channels_used[group]);
185+
SIMPLEFOC_DEBUG("EP32-DRV: ERROR - Failed to configure pin:", pins[i]);
181186
return SIMPLEFOC_DRIVER_INIT_FAILED;
182187
}
188+
183189
params->channels[i] = static_cast<ledc_channel_t>(group_channels_used[group]);
184190
params->groups[i] = (ledc_mode_t)group;
185191
}
@@ -213,9 +219,10 @@ void* _configure3PWM(long pwm_frequency,const int pinA, const int pinB, const in
213219
for(int i = 0; i < 3; i++){
214220
group_channels_used[group]++;
215221
if(!_ledcAttachChannelAdvanced(pins[i], group_channels_used[group], group, pwm_frequency, _PWM_RES_BIT, false)){
216-
SIMPLEFOC_DEBUG("EP32-DRV: ERROR - Failed to attach channel:", group_channels_used[group]);
222+
SIMPLEFOC_DEBUG("EP32-DRV: ERROR - Failed to configure pin:", pins[i]);
217223
return SIMPLEFOC_DRIVER_INIT_FAILED;
218224
}
225+
219226
params->channels[i] = static_cast<ledc_channel_t>(group_channels_used[group]);
220227
params->groups[i] = (ledc_mode_t)group;
221228
}
@@ -229,31 +236,49 @@ void* _configure4PWM(long pwm_frequency,const int pinA, const int pinB, const in
229236
if(!pwm_frequency || !_isset(pwm_frequency) ) pwm_frequency = _PWM_FREQUENCY; // default frequency 25khz
230237
else pwm_frequency = _constrain(pwm_frequency, 0, _PWM_FREQUENCY_MAX); // constrain to 50kHz max
231238

232-
SIMPLEFOC_DEBUG("EP32-DRV: Configuring 4PWM");
233-
// check if enough channels available
234-
int group = _findGroupWithChannelsAvailable(4);
235-
if (group < 0){
236-
SIMPLEFOC_DEBUG("EP32-DRV: ERROR - Not enough channels available!");
237-
return SIMPLEFOC_DRIVER_INIT_FAILED;
238-
}
239-
SIMPLEFOC_DEBUG("EP32-DRV: 4PWM setup in group: ", (group));
239+
240240
ESP32LEDCDriverParams* params = new ESP32LEDCDriverParams {
241241
.channels = { static_cast<ledc_channel_t>(0)},
242242
.groups = { (ledc_mode_t)0 },
243243
.pwm_frequency = pwm_frequency
244244
};
245245

246+
SIMPLEFOC_DEBUG("EP32-DRV: Configuring 4PWM");
247+
// check if enough channels available
248+
int group = _findGroupWithChannelsAvailable(4);
249+
if (group < 0){
250+
// not enough channels available on any individual group
251+
// check if their combined number is enough (two channels per group)
252+
if(_availableGroupChannels(0) >=2 && _availableGroupChannels(1) >=2){
253+
group = 2;
254+
SIMPLEFOC_DEBUG("EP32-DRV: WARNING: Not enough available ledc channels for 4pwm in a single group! Using two groups!");
255+
SIMPLEFOC_DEBUG("EP32-DRV: 4PWM setup in groups: 0 and 1!");
256+
params->groups[2] = (ledc_mode_t)1;
257+
params->groups[3] = (ledc_mode_t)1;
258+
}else{
259+
SIMPLEFOC_DEBUG("EP32-DRV: ERROR - Not enough available ledc channels for 4pwm!");
260+
return SIMPLEFOC_DRIVER_INIT_FAILED;
261+
}
262+
}else{
263+
SIMPLEFOC_DEBUG("EP32-DRV: 4PWM setup in group: ", (group));
264+
params->groups[0] = (ledc_mode_t)group;
265+
params->groups[1] = (ledc_mode_t)group;
266+
params->groups[2] = (ledc_mode_t)group;
267+
params->groups[3] = (ledc_mode_t)group;
268+
}
269+
270+
271+
246272
int pins[4] = {pinA, pinB, pinC, pinD};
247273
for(int i = 0; i < 4; i++){
248-
group_channels_used[group]++;
249-
if(!_ledcAttachChannelAdvanced(pins[i], group_channels_used[group], group, pwm_frequency, _PWM_RES_BIT, false)){
250-
SIMPLEFOC_DEBUG("EP32-DRV: ERROR - Failed to attach channel:", group_channels_used[group]);
274+
group_channels_used[params->groups[i]]++;
275+
if(!_ledcAttachChannelAdvanced(pins[i], group_channels_used[params->groups[i]], params->groups[i], pwm_frequency, _PWM_RES_BIT, false)){
276+
SIMPLEFOC_DEBUG("EP32-DRV: ERROR - Failed to configure pin:", pins[i]);
251277
return SIMPLEFOC_DRIVER_INIT_FAILED;
252278
}
253-
params->channels[i] = static_cast<ledc_channel_t>(group_channels_used[group]);
254-
params->groups[i] = (ledc_mode_t)group;
279+
params->channels[i] = static_cast<ledc_channel_t>(group_channels_used[params->groups[i]]);
255280
}
256-
SIMPLEFOC_DEBUG("EP32-DRV: 4PWM setup successful in group: ", (group));
281+
SIMPLEFOC_DEBUG("EP32-DRV: 4PWM setup successful!");
257282
return params;
258283
}
259284

@@ -292,13 +317,81 @@ void _writeDutyCycle4PWM(float dc_1a, float dc_1b, float dc_2a, float dc_2b, vo
292317
}
293318

294319

295-
// TODO - implement 6PWM
296320
void* _configure6PWM(long pwm_frequency, float dead_zone, const int pinA_h, const int pinA_l, const int pinB_h, const int pinB_l, const int pinC_h, const int pinC_l){
297-
SIMPLEFOC_DEBUG("EP32-DRV: 6PWM not supported!");
298-
return SIMPLEFOC_DRIVER_INIT_FAILED;
321+
if(!pwm_frequency || !_isset(pwm_frequency) ) pwm_frequency = _PWM_FREQUENCY; // default frequency 25khz
322+
else pwm_frequency = _constrain(pwm_frequency, 0, _PWM_FREQUENCY_MAX); // constrain to 50kHz max
323+
324+
SIMPLEFOC_DEBUG("EP32-DRV: Configuring 6PWM");
325+
SIMPLEFOC_DEBUG("EP32-DRV: WARNING - 6PWM on LEDC is poorly supported and not tested, consider using MCPWM driver instead!");
326+
// check if enough channels available
327+
int group = _findGroupWithChannelsAvailable(6);
328+
if (group < 0){
329+
SIMPLEFOC_DEBUG("EP32-DRV: ERROR - Not enough channels available!");
330+
return SIMPLEFOC_DRIVER_INIT_FAILED;
331+
}
332+
SIMPLEFOC_DEBUG("EP32-DRV: 6PWM setup in group: ", (group));
333+
ESP32LEDCDriverParams* params = new ESP32LEDCDriverParams {
334+
.channels = { static_cast<ledc_channel_t>(0)},
335+
.groups = { (ledc_mode_t)group },
336+
.pwm_frequency = pwm_frequency,
337+
.dead_zone = dead_zone
338+
};
339+
340+
int high_side_invert = SIMPLEFOC_PWM_HIGHSIDE_ACTIVE_HIGH ? false : true;
341+
int low_side_invert = SIMPLEFOC_PWM_LOWSIDE_ACTIVE_HIGH ? true : false;
342+
343+
int pin_pairs[6][2] = {
344+
{pinA_h, pinA_l},
345+
{pinB_h, pinB_l},
346+
{pinC_h, pinC_l}
347+
};
348+
349+
for(int i = 0; i < 3; i++){
350+
group_channels_used[group]++;
351+
if(!_ledcAttachChannelAdvanced(pin_pairs[i][0], group_channels_used[group], group, pwm_frequency, _PWM_RES_BIT, high_side_invert)){
352+
SIMPLEFOC_DEBUG("EP32-DRV: ERROR - Failed to configure pin:", pin_pairs[i][0]);
353+
return SIMPLEFOC_DRIVER_INIT_FAILED;
354+
}
355+
356+
params->channels[2*i] = static_cast<ledc_channel_t>(group_channels_used[group]);
357+
params->groups[2*i] = (ledc_mode_t)group;
358+
359+
group_channels_used[group]++;
360+
if(!_ledcAttachChannelAdvanced(pin_pairs[i][1], group_channels_used[group], group, pwm_frequency, _PWM_RES_BIT, low_side_invert)){
361+
SIMPLEFOC_DEBUG("EP32-DRV: ERROR - Failed to configure pin:", pin_pairs[i][0]);
362+
return SIMPLEFOC_DRIVER_INIT_FAILED;
363+
}
364+
365+
params->channels[2*i+1] = static_cast<ledc_channel_t>(group_channels_used[group]);
366+
params->groups[2*i+1] = (ledc_mode_t)group;
367+
}
368+
369+
SIMPLEFOC_DEBUG("EP32-DRV: 6PWM setup successful in group: ", (group));
370+
return params;
299371
}
300-
void _writeDutyCycle6PWM(float dc_a, float dc_b, float dc_c, void* params) {
301-
SIMPLEFOC_DEBUG("EP32-DRV: 6PWM not supported");
372+
373+
void _setPwmPairDutyCycle( void* params, int ind_h, int ind_l, float val, float dead_time, PhaseState ps){
374+
float pwm_h = _constrain(val - dead_time/2.0, 0, 1.0);
375+
float pwm_l = _constrain(val + dead_time/2.0, 0, 1.0);
376+
377+
// determine the phase state and set the pwm accordingly
378+
// deactivate phases if needed
379+
if((ps == PhaseState::PHASE_OFF) || (ps == PhaseState::PHASE_LO)){
380+
_writeDutyCycle(0, params, ind_h);
381+
}else{
382+
_writeDutyCycle(pwm_h, params, ind_h);
383+
}
384+
if((ps == PhaseState::PHASE_OFF) || (ps == PhaseState::PHASE_HI)){
385+
_writeDutyCycle(0, params, ind_l);
386+
}else{
387+
_writeDutyCycle(pwm_l, params, ind_l);
388+
}
389+
}
390+
391+
void _writeDutyCycle6PWM(float dc_a, float dc_b, float dc_c, PhaseState *phase_state, void* params){
392+
_setPwmPairDutyCycle(params, 0, 1, dc_a, ((ESP32LEDCDriverParams*)params)->dead_zone, phase_state[0]);
393+
_setPwmPairDutyCycle(params, 2, 3, dc_b, ((ESP32LEDCDriverParams*)params)->dead_zone, phase_state[1]);
394+
_setPwmPairDutyCycle(params, 4, 5, dc_c, ((ESP32LEDCDriverParams*)params)->dead_zone, phase_state[2]);
302395
}
303396

304397
#endif

0 commit comments

Comments
 (0)