ESP-32 and MCPWM duty cycle changes in timer interrupts

I learnt some things and wanted to share.

Using the ESP-32 and the new Arduino IDE 2.3.2 for BLDC control, I wanted to update the PWM duty cycle in a timer interrupt (5KHz). The ESP-32 doesn’t like FPU operations in interrupts, so “mcpwm_set_duty()” doesn’t work well.

It was previously possible to write directly to the MCPWM registers, but they have recently changed the drivers.

Previously it used
MCPWM0.channel[0].cmpr_value[MCPWM_OPR_A].cmpr_val = PWMUU;
MCPWM0.channel[1].cmpr_value[MCPWM_OPR_A].cmpr_val = PWMVV;
MCPWM0.channel[2].cmpr_value[MCPWM_OPR_A].cmpr_val = PWMWW;
With the new driver
MCPWM0.operators[0].timestamp[0].gen=PWMUU;
MCPWM0.operators[1].timestamp[0].gen=PWMVV;
MCPWM0.operators[2].timestamp[0].gen=PWMWW;

This means that loop() can run slower and can be used to update an OLED display.

pseudio code

void ARDUINO_ISR_ATTR onTimer() {
get_encoder();
pos_ctrl();
Motor_Vector_Phases( target_angle, motor_output);

MCPWM0.operators[0].timestamp[0].gen=PWMUU;
MCPWM0.operators[1].timestamp[0].gen=PWMVV;
MCPWM0.operators[2].timestamp[0].gen=PWMWW;
}

void IRAM_ATTR loop() {
ssd1306_text();
}

3 Likes