Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

inverting the mcpwm dead-time output is not selective per generator (IDFGH-10050) #11327

Closed
3 tasks done
moefear85 opened this issue May 3, 2023 · 5 comments
Closed
3 tasks done
Assignees
Labels
Status: Done Issue is done internally

Comments

@moefear85
Copy link

moefear85 commented May 3, 2023

Answers checklist.

  • I have read the documentation ESP-IDF Programming Guide and the issue is not addressed there.
  • I have updated my IDF branch (master or release) to the latest version and checked that the issue is present there.
  • I have searched the issue tracker for a similar issue and not found a similar issue.

IDF version.

fatal: No names found, cannot describe anything. (I'm on latest master).

Operating System used.

Linux

How did you build your project?

VS Code IDE

If you are using Windows, please specify command line type.

None

Development Kit.

esp32 rev1 module

Power Supply used.

External 3.3V

What is the expected behavior?

from the page MCPWM Dead-Times, I feel it is correct to assume that it is possible to selectively invert the output for only one signal but not the other, by setting dead_time_config.flags.invert_output = true; as in the following excerpt from that page:

mcpwm_dead_time_config_t dead_time_config = {
        .posedge_delay_ticks = 50,
        .negedge_delay_ticks = 0
    };
    ESP_ERROR_CHECK(mcpwm_generator_set_dead_time(gena, gena, &dead_time_config));
    dead_time_config.posedge_delay_ticks = 0;
    dead_time_config.negedge_delay_ticks = 100;
    dead_time_config.flags.invert_output = true;
    ESP_ERROR_CHECK(mcpwm_generator_set_dead_time(gena, genb, &dead_time_config));

When I try it myself, I expect it to selectively invert only one signal but not the other.

What is the actual behavior?

Either both signals are inverted simultaneously, or neither.

Steps to reproduce.

This bug exists since a long time, at least many months. Only now have I been able to distill a minimal example that exposes it (it is a c++ project, in case that is relevant):

#include "driver/mcpwm_prelude.h"
#include "driver/gpio.h"

uint32_t SIDES=2;

gpio_num_t pin_L=GPIO_NUM_23;
gpio_num_t pin_H=GPIO_NUM_18;

//uint32_t dead_ticks=0;
uint32_t mcpwm_tmr_rsltn=10000000; // 1 tick = 0.1us
uint32_t mcpwm_period=400; // 25KHz

mcpwm_timer_handle_t mcpwm_timer={};
mcpwm_oper_handle_t mcpwm_operator={};
mcpwm_gen_handle_t mcpwm_generators[SIDES]={};
mcpwm_cmpr_handle_t mcpwm_comparator={};
mcpwm_cap_timer_handle_t mcpwm_capture_timer={};

extern "C" void app_main(void)
{
     mcpwm_timer_config_t timer_config=
    {
        .group_id=0,
        .clk_src=MCPWM_TIMER_CLK_SRC_DEFAULT,
        .resolution_hz=mcpwm_tmr_rsltn,
        .count_mode=MCPWM_TIMER_COUNT_MODE_UP,
        .period_ticks=mcpwm_period,
    };
    ESP_ERROR_CHECK( mcpwm_new_timer(&timer_config, &mcpwm_timer) );
    

    mcpwm_operator_config_t operator_config=
    {
        .group_id=0,
        .flags=
        {
            .update_gen_action_on_tez=true,
            .update_dead_time_on_tez=true,
        },
    };
    ESP_ERROR_CHECK( mcpwm_new_operator(&operator_config, &mcpwm_operator) );
    ESP_ERROR_CHECK( mcpwm_operator_connect_timer(mcpwm_operator, mcpwm_timer) );


    mcpwm_comparator_config_t compare_config=
    {
        .flags=
        {
            .update_cmp_on_tez=true,
        },
    };
    ESP_ERROR_CHECK( mcpwm_new_comparator(mcpwm_operator, &compare_config, &mcpwm_comparator) );


    int gen_gpios[2]={pin_L,pin_H};
    mcpwm_generator_config_t gen_config={};
    for (int i=0;i<2;i++)
    {
        gen_config.gen_gpio_num = gen_gpios[i];
        ESP_ERROR_CHECK( mcpwm_new_generator(mcpwm_operator, &gen_config, &mcpwm_generators[i]) );
    }

    
    for (int i=0;i<2;i++)
    {
        ESP_ERROR_CHECK( mcpwm_generator_set_action_on_timer_event(mcpwm_generators[i],MCPWM_GEN_TIMER_EVENT_ACTION(MCPWM_TIMER_DIRECTION_UP, MCPWM_TIMER_EVENT_EMPTY, MCPWM_GEN_ACTION_HIGH)) );
        ESP_ERROR_CHECK( mcpwm_generator_set_action_on_compare_event(mcpwm_generators[i],MCPWM_GEN_COMPARE_EVENT_ACTION(MCPWM_TIMER_DIRECTION_UP, mcpwm_comparator, MCPWM_GEN_ACTION_LOW)) );
    }


    mcpwm_dead_time_config_t deadtime_config_L={.posedge_delay_ticks=1}; // necessary, otherwise deadtimes won't kick in
    deadtime_config_L.flags.invert_output=false;
    ESP_ERROR_CHECK( mcpwm_generator_set_dead_time(mcpwm_generators[0], mcpwm_generators[0], &deadtime_config_L) );
    mcpwm_dead_time_config_t deadtime_config_H={.posedge_delay_ticks=1};
    deadtime_config_H.flags.invert_output=true;
    ESP_ERROR_CHECK( mcpwm_generator_set_dead_time(mcpwm_generators[1], mcpwm_generators[1], &deadtime_config_H) );


    ESP_ERROR_CHECK( mcpwm_timer_enable(mcpwm_timer) );
    ESP_ERROR_CHECK( mcpwm_timer_start_stop(mcpwm_timer,MCPWM_TIMER_START_NO_STOP) );


    mcpwm_comparator_set_compare_value(mcpwm_comparator,mcpwm_period*0.25);
}

Debug Logs.

No response

More Information.

I know you might object that I've got the generators wrong in the call to mcpwm_generator_set_dead_time(...), but not only is the documentation confusing as to what it actually means, and not only does everything else work fine when I use the combination as above, but also there are 16 possible combinations in total, and I've iterated over all of them. Neither one produces the desired output.
So if selective inversion truly is possible, and there is a combination of generators that works, then there must be a bug in the library.

@moefear85 moefear85 added the Type: Bug bugs in IDF label May 3, 2023
@github-actions github-actions bot changed the title inverting the mcpwm dead-time output is not selective per generator inverting the mcpwm dead-time output is not selective per generator (IDFGH-10050) May 3, 2023
@espressif-bot espressif-bot added the Status: Opened Issue is new label May 3, 2023
@suda-morris
Copy link
Collaborator

suda-morris commented May 4, 2023

Hi @moefear85 the inverting is not applied to either generator, it's applied to the "deadtime path".

image

mcpwm_dead_time_config_t dead_time_config = {
        .posedge_delay_ticks = 50,
        .negedge_delay_ticks = 0
};
ESP_ERROR_CHECK(mcpwm_generator_set_dead_time(gena, gena, &dead_time_config));

This way, we're applying the dead time to the gena itself, we're going the gena->gena path, so we're configuring the switch S2 here.

    dead_time_config.posedge_delay_ticks = 0;
    dead_time_config.negedge_delay_ticks = 100;
    dead_time_config.flags.invert_output = true;
    ESP_ERROR_CHECK(mcpwm_generator_set_dead_time(gena, genb, &dead_time_config));

Now we're producing genb from the original gena, so we're going the gena->genb path, so we're configuring the switch S3.

S2 and S3 are independent.

The result is woking as expected:

image

@suda-morris suda-morris removed the Type: Bug bugs in IDF label May 4, 2023
@moefear85
Copy link
Author

moefear85 commented May 4, 2023

The documentation clearly is claiming that the inversion is done on the signal, not on the edgeness of the dead-time (whether applied to positive or negative). So if you are claiming the latter, then the documentation is not just misleading, it is outright wrong, and that still needs to be corrected.

Also, the o-scope diagram does not show anything, because it is unclear what is changing before and after applying the inversion. there are no labels. did you really miss that?

Anyways it's up to you to fix the problem. In case anyone wants to invert the signal, it is possible over the gpio matrix using the generator.

@suda-morris
Copy link
Collaborator

@moefear85
Thanks for telling me you're misled by the documentation. We will improve it ASAP. FYI, I can add more hints in this diagram: https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/peripherals/mcpwm.html#active-high-complementary to highlight the where the inversion happens.

@espressif-bot espressif-bot added Status: In Progress Work is in progress and removed Status: Opened Issue is new labels May 5, 2023
@suda-morris
Copy link
Collaborator

Okay, this is the hardware limitation:
you can't set rising edge delay for both MCPWM generator 0 and 1 at the same time.

Based on your snippet code, if we change the deadtime_config_H to

mcpwm_dead_time_config_t deadtime_config_H = {.negedge_delay_ticks = 1};

Then you can see the inverter works only for generator1, not for generator0.

image

We will update the programming guide to mention this limitation.

@espressif-bot espressif-bot added Status: Reviewing Issue is being reviewed Status: Done Issue is done internally Resolution: NA Issue resolution is unavailable and removed Status: In Progress Work is in progress Status: Reviewing Issue is being reviewed labels May 6, 2023
espressif-bot pushed a commit that referenced this issue May 13, 2023
This is a hardware limitation, one delay module can only be used by one generator at one time.

Closes #11327
espressif-bot pushed a commit that referenced this issue May 20, 2023
This is a hardware limitation, one delay module can only be used by one generator at one time.

Closes #11327
@suda-morris suda-morris removed Resolution: NA Issue resolution is unavailable Resolution: labels Jun 2, 2023
@IhorNehrutsa
Copy link
Contributor

@suda-morris

Hi @moefear85 the inverting is not applied to either generator, it's applied to the "deadtime path".

image

Please tell me which document this drawing is from?
Thanks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Status: Done Issue is done internally
Projects
None yet
Development

No branches or pull requests

4 participants