ESP32-S3 mcpwm.h - mcpwm_sync_config_t timer_val calculation

grini1809
Posts: 2
Joined: Wed Feb 15, 2023 1:50 pm

ESP32-S3 mcpwm.h - mcpwm_sync_config_t timer_val calculation

Postby grini1809 » Wed Feb 15, 2023 2:11 pm

Hi Guys,

New to the forum and ESP32-S3 on Arduino IDE - please be kind.

Question - regarding below structure defined in ESP-IDF v4.4

https://github.com/espressif/esp-idf/bl ... er/mcpwm.h

typedef struct {

mcpwm_sync_signal_t sync_sig; /*!<Set sync input signal that will cause timer to sync*/

uint32_t timer_val; /*!<Counter value to be set after sync, in 0 ~ 999, unit: 1 / 1000 * peak*/

mcpwm_timer_direction_t count_direction; /*!<Counting direction to be set after sync */

} mcpwm_sync_config_t;


Point of interest :
Counter value to be set after sync, in 0 ~ 999, unit: 1 / 1000 * peak

Is there anyone who knows how to calculate this "unit" please?
What is this "peak" and where is defined or how can be calculated?

What i need to do is to have MCPWM0 with Timer0 sync at 0 then Timer1 and Timer2 sync internally by Timer0 but phase shifted by 120 and 270 degree -> timer0 period has to be divided by 3 and Timer1 starts at 1/3 and timer2 starts at 2/3 of Timer0

I was not able to find anywhere how this 0 to 999 unit is calculated.
I used group and timer resolution functions (80MHz and 80MHz) but even with default group of 10MHz and timer 1MHz resolutions i doubt my calculations.

My practical tests with 80M group and 80M timer and frequency 66666Hz i have timer1 start at 274 and timer2 at 548 but i have some overlapping on my scope.

Thank you.

grini1809
Posts: 2
Joined: Wed Feb 15, 2023 1:50 pm

Re: ESP32-S3 mcpwm.h - mcpwm_sync_config_t timer_val calculation

Postby grini1809 » Fri Feb 17, 2023 1:13 am

Last night version of my MCPWM test - better timing but no real math behind.
i am using ESP32-S3-DevKitC-1

Code: Select all

#include "driver/mcpwm.h"


#define GPIO_PWM0A_OUT 13  //Set GPIO 13 as PWM0A
#define GPIO_PWM0B_OUT 14  //Set GPIO 14 as PWM0B
#define GPIO_PWM1A_OUT 15  //Set GPIO 15 as PWM1A
#define GPIO_PWM1B_OUT 16  //Set GPIO 16 as PWM1B
#define GPIO_PWM2A_OUT 17  //Set GPIO 17 as PWM2A
#define GPIO_PWM2B_OUT 18  //Set GPIO 18 as PWM2B


int freq0 = 66666;
float duty0 = 0.0;
int count = 0;


static void IRAM_ATTR setuppwm() {
  //set GPIO
  mcpwm_gpio_init(MCPWM_UNIT_0, MCPWM0A, GPIO_PWM0A_OUT);
  mcpwm_gpio_init(MCPWM_UNIT_0, MCPWM0B, GPIO_PWM0B_OUT);
  mcpwm_gpio_init(MCPWM_UNIT_0, MCPWM1A, GPIO_PWM1A_OUT);
  mcpwm_gpio_init(MCPWM_UNIT_0, MCPWM1B, GPIO_PWM1B_OUT);
  mcpwm_gpio_init(MCPWM_UNIT_0, MCPWM2A, GPIO_PWM2A_OUT);
  mcpwm_gpio_init(MCPWM_UNIT_0, MCPWM2B, GPIO_PWM2B_OUT);
  //end SetGPIO

  mcpwm_group_set_resolution(MCPWM_UNIT_0, 160000000);
  mcpwm_timer_set_resolution(MCPWM_UNIT_0, MCPWM_TIMER_0, 160000000);
  mcpwm_timer_set_resolution(MCPWM_UNIT_0, MCPWM_TIMER_1, 160000000);
  mcpwm_timer_set_resolution(MCPWM_UNIT_0, MCPWM_TIMER_2, 160000000);

  mcpwm_config_t pwm_config0;
  pwm_config0.frequency = freq0;
  pwm_config0.cmpr_a = 0;
  pwm_config0.cmpr_b = 0;
  pwm_config0.counter_mode = MCPWM_DOWN_COUNTER;
  pwm_config0.duty_mode = MCPWM_DUTY_MODE_0;

  mcpwm_init(MCPWM_UNIT_0, MCPWM_TIMER_0, &pwm_config0);
  mcpwm_init(MCPWM_UNIT_0, MCPWM_TIMER_1, &pwm_config0);
  mcpwm_init(MCPWM_UNIT_0, MCPWM_TIMER_2, &pwm_config0);


  mcpwm_stop(MCPWM_UNIT_0, MCPWM_TIMER_0);
  mcpwm_stop(MCPWM_UNIT_0, MCPWM_TIMER_1);
  mcpwm_stop(MCPWM_UNIT_0, MCPWM_TIMER_2);


  //freq
  mcpwm_set_frequency(MCPWM_UNIT_0, MCPWM_TIMER_0, freq0);
  mcpwm_set_frequency(MCPWM_UNIT_0, MCPWM_TIMER_1, freq0);
  mcpwm_set_frequency(MCPWM_UNIT_0, MCPWM_TIMER_2, freq0);
  //end freq
  
//Duty
  mcpwm_set_duty(MCPWM_UNIT_0, MCPWM_TIMER_0, MCPWM_GEN_A, duty0);
  mcpwm_set_duty(MCPWM_UNIT_0, MCPWM_TIMER_0, MCPWM_GEN_B, duty0);
  mcpwm_set_duty(MCPWM_UNIT_0, MCPWM_TIMER_1, MCPWM_GEN_A, duty0);
  mcpwm_set_duty(MCPWM_UNIT_0, MCPWM_TIMER_1, MCPWM_GEN_B, duty0);
  mcpwm_set_duty(MCPWM_UNIT_0, MCPWM_TIMER_2, MCPWM_GEN_A, duty0);
  mcpwm_set_duty(MCPWM_UNIT_0, MCPWM_TIMER_2, MCPWM_GEN_B, duty0);
  //end Duty


  //sync
  // configure timer0 as trigger source
  mcpwm_set_timer_sync_output(MCPWM_UNIT_0, MCPWM_TIMER_0, MCPWM_SWSYNC_SOURCE_SYNCIN);

  mcpwm_sync_config_t sync_conf0 = {
    .sync_sig = MCPWM_SELECT_TIMER0_SYNC,
    [b].timer_val = 0,[/b]
    .count_direction = MCPWM_TIMER_DIRECTION_DOWN,
  };

  mcpwm_sync_config_t sync_conf1 = {
    .sync_sig = MCPWM_SELECT_TIMER0_SYNC,
   [b] .timer_val = 268,[/b]
    .count_direction = MCPWM_TIMER_DIRECTION_DOWN,
  };
  mcpwm_sync_config_t sync_conf2 = {
    .sync_sig = MCPWM_SELECT_TIMER0_SYNC,
    [b].timer_val = 535,[/b]
    .count_direction = MCPWM_TIMER_DIRECTION_DOWN,
  };

  mcpwm_sync_configure(MCPWM_UNIT_0, MCPWM_TIMER_0, &sync_conf0);
  mcpwm_sync_configure(MCPWM_UNIT_0, MCPWM_TIMER_1, &sync_conf1);
  mcpwm_sync_configure(MCPWM_UNIT_0, MCPWM_TIMER_2, &sync_conf2);
  mcpwm_timer_trigger_soft_sync(MCPWM_UNIT_0, MCPWM_TIMER_0);

  //duty
  mcpwm_set_duty_type(MCPWM_UNIT_0, MCPWM_TIMER_0, MCPWM_GEN_A, MCPWM_DUTY_MODE_0);
  mcpwm_set_duty(MCPWM_UNIT_0, MCPWM_TIMER_0, MCPWM_GEN_A, duty0);
  mcpwm_set_duty_type(MCPWM_UNIT_0, MCPWM_TIMER_0, MCPWM_GEN_B, MCPWM_DUTY_MODE_1);
  mcpwm_set_duty(MCPWM_UNIT_0, MCPWM_TIMER_0, MCPWM_GEN_B, duty0);

  mcpwm_set_duty_type(MCPWM_UNIT_0, MCPWM_TIMER_1, MCPWM_GEN_A, MCPWM_DUTY_MODE_0);
  mcpwm_set_duty(MCPWM_UNIT_0, MCPWM_TIMER_1, MCPWM_GEN_A, duty0);
  mcpwm_set_duty_type(MCPWM_UNIT_0, MCPWM_TIMER_1, MCPWM_GEN_B, MCPWM_DUTY_MODE_1);
  mcpwm_set_duty(MCPWM_UNIT_0, MCPWM_TIMER_1, MCPWM_GEN_B, duty0);

  mcpwm_set_duty_type(MCPWM_UNIT_0, MCPWM_TIMER_2, MCPWM_GEN_A, MCPWM_DUTY_MODE_0);
  mcpwm_set_duty(MCPWM_UNIT_0, MCPWM_TIMER_2, MCPWM_GEN_A, duty0);
  mcpwm_set_duty_type(MCPWM_UNIT_0, MCPWM_TIMER_2, MCPWM_GEN_B, MCPWM_DUTY_MODE_1);
  mcpwm_set_duty(MCPWM_UNIT_0, MCPWM_TIMER_2, MCPWM_GEN_B, duty0);
  //end duty

  mcpwm_start(MCPWM_UNIT_0, MCPWM_TIMER_0);
  mcpwm_start(MCPWM_UNIT_0, MCPWM_TIMER_1);
  mcpwm_start(MCPWM_UNIT_0, MCPWM_TIMER_2);
}

void setup() {
  setuppwm();
}

void loop() {
  if (duty0 <= 32.7) {
    duty0 = duty0 + 0.00001;

    mcpwm_set_duty(MCPWM_UNIT_0, MCPWM_TIMER_0, MCPWM_GEN_A, duty0);
    mcpwm_set_duty(MCPWM_UNIT_0, MCPWM_TIMER_0, MCPWM_GEN_B, duty0);

    mcpwm_set_duty(MCPWM_UNIT_0, MCPWM_TIMER_1, MCPWM_GEN_A, duty0);
    mcpwm_set_duty(MCPWM_UNIT_0, MCPWM_TIMER_1, MCPWM_GEN_B, duty0);

    mcpwm_set_duty(MCPWM_UNIT_0, MCPWM_TIMER_2, MCPWM_GEN_A, duty0);
    mcpwm_set_duty(MCPWM_UNIT_0, MCPWM_TIMER_2, MCPWM_GEN_B, duty0);
  }
}

Who is online

Users browsing this forum: No registered users and 55 guests