Page 1 of 1

MCPWM change TIMERn Prescaler

Posted: Wed Mar 01, 2023 9:03 pm
by lucapassarella
Hi I'm developing a motion controller using ESP32-S3 (follow-up of https://esp32.com/viewtopic.php?f=13&t=30817, that suggestion worked perfectly, thanks)

I want to change at runtime the prescaler of a timer ( while keeping the group scaler the same )

On the struct definition https://github.com/espressif/esp-idf/bl ... L35-L39C36 it is written that the timer should be started and stopped to apply the prescaler change, but even if i do nothing happen



This is an example code of what i'm trying, all other parameter are working except for the prescaler (i'm checking with oscilloscope)

  1. mcpwm_config_t mcpwm_conf {
  2.     .frequency = APB_CLK_FREQ * 2,
  3.     .cmpr_a = 0,
  4.     .cmpr_b = 0,
  5.     .duty_mode = mcpwm_duty_type_t::MCPWM_DUTY_MODE_0,
  6.     .counter_mode = mcpwm_counter_type_t::MCPWM_UP_COUNTER
  7. };
  8.  
  9. ESP_ERROR_CHECK(mcpwm_init(0, 0, &mcpwm_conf));
  10.  
  11. MCPWM0.clk_cfg.clk_prescale = ( ( ( APB_CLK_FREQ / 1000000 ) * 2 ) - 1 ); //GROUP CLOCK_IN IS 160MHz, my target is 1us x tick
  12.  
  13. ESP_ERROR_CHECK(mcpwm_stop(0, 0));
  14.  
  15. MCPWM0.timer[0].timer_cfg0.timer_prescale = 30; //THIS IS NOT WORKING!!!
  16. MCPWM0.timer[0].timer_cfg1.timer_mod = 0;
  17. MCPWM0.timer[0].timer_cfg0.timer_period = 5;
  18.  
  19. //SETTING OPERATOR ACTIONS HERE
  20.  
  21. MCPWM0.update_cfg.global_force_up = 0; //I TRIED THIS TOO
  22. MCPWM0.update_cfg.global_force_up = 1; //I TRIED THIS TOO
  23.  
  24. ESP_ERROR_CHECK(mcpwm_start(0, 0));
  25.  
  26.  
  27. // DO OTHER STUFF
  28. // UPDATE TIMER PERIOD AGAIN
  29. // UPDATE TIMER PRESCALER AGAIN, NOT WORKING
  30.  
  31. // DO OTHER STUFF AGAIN
  32. // UPDATE TIMER PERIOD AGAIN
  33. // UPDATE TIMER PRESCALER AGAIN, NOT WORKING
  34.  
  35. // ECC
  36.  

What should i do to update it? Momentarily stopping the single timer is an option (but the other 2 in the group must keep working without interference)
I'm already modulating the Period of the timer, but some time I need a longer Period than the max value so I want to change the Prescaler
How can i achieve this?


Thanks,
Luca

Re: MCPWM change TIMERn Prescaler

Posted: Wed Mar 08, 2023 11:25 am
by rudi ;-)
lucapassarella wrote:
Wed Mar 01, 2023 9:03 pm
Hi I'm developing a motion controller using ESP32-S3 (follow-up of https://esp32.com/viewtopic.php?f=13&t=30817, that suggestion worked perfectly, thanks)

I want to change at runtime the prescaler of a timer ( while keeping the group scaler the same )

On the struct definition https://github.com/espressif/esp-idf/bl ... L35-L39C36 it is written that the timer should be started and stopped to apply the prescaler change, but even if i do nothing happen



This is an example code of what i'm trying, all other parameter are working except for the prescaler (i'm checking with oscilloscope)

  1. mcpwm_config_t mcpwm_conf {
  2.     .frequency = APB_CLK_FREQ * 2,
  3.     .cmpr_a = 0,
  4.     .cmpr_b = 0,
  5.     .duty_mode = mcpwm_duty_type_t::MCPWM_DUTY_MODE_0,
  6.     .counter_mode = mcpwm_counter_type_t::MCPWM_UP_COUNTER
  7. };
  8.  
  9. ESP_ERROR_CHECK(mcpwm_init(0, 0, &mcpwm_conf));
  10.  
  11. MCPWM0.clk_cfg.clk_prescale = ( ( ( APB_CLK_FREQ / 1000000 ) * 2 ) - 1 ); //GROUP CLOCK_IN IS 160MHz, my target is 1us x tick
  12.  
  13. ESP_ERROR_CHECK(mcpwm_stop(0, 0));
  14.  
  15. MCPWM0.timer[0].timer_cfg0.timer_prescale = 30; //THIS IS NOT WORKING!!!
  16. MCPWM0.timer[0].timer_cfg1.timer_mod = 0;
  17. MCPWM0.timer[0].timer_cfg0.timer_period = 5;
  18.  
  19. //SETTING OPERATOR ACTIONS HERE
  20.  
  21. MCPWM0.update_cfg.global_force_up = 0; //I TRIED THIS TOO
  22. MCPWM0.update_cfg.global_force_up = 1; //I TRIED THIS TOO
  23.  
  24. ESP_ERROR_CHECK(mcpwm_start(0, 0));
  25.  
  26.  
  27. // DO OTHER STUFF
  28. // UPDATE TIMER PERIOD AGAIN
  29. // UPDATE TIMER PRESCALER AGAIN, NOT WORKING
  30.  
  31. // DO OTHER STUFF AGAIN
  32. // UPDATE TIMER PERIOD AGAIN
  33. // UPDATE TIMER PRESCALER AGAIN, NOT WORKING
  34.  
  35. // ECC
  36.  

What should i do to update it? Momentarily stopping the single timer is an option (but the other 2 in the group must keep working without interference)
I'm already modulating the Period of the timer, but some time I need a longer Period than the max value so I want to change the Prescaler
How can i achieve this?


Thanks,
Luca


Based on the information you provided, it seems like you are trying to change the prescaler of a MCPWM timer on an ESP32-S3 microcontroller. However, you are facing difficulties in applying the prescaler changes at runtime using the given code.

The code you provided appears to be correct in terms of changing the prescaler of the timer. However, you mentioned that the prescaler change is not working for some reason.

One potential issue could be that you are not properly stopping and starting the timer after making changes to its configuration. According to the struct definition you provided, the timer should be stopped and restarted in order for certain configuration changes to take effect, including changes to the prescaler.

Therefore, I would suggest trying to modify your code to stop and restart the timer after changing the prescaler. Additionally, you may want to consider modifying the code to confirm that the prescaler value changes are actually being applied by reading back the prescaler value after setting it and checking that it matches the desired value.

I hope this helps, and if you have any further questions, please feel free to ask.


"AskRudi"

Re: MCPWM change TIMERn Prescaler

Posted: Wed Mar 15, 2023 11:56 am
by lucapassarella
Hi @rudi and thanks for the answer

Yes I'm inded trying this on the esp32-s3

Thank for the suggestion, but as I said:
lucapassarella wrote:
Wed Mar 01, 2023 9:03 pm
On the struct definition https://github.com/espressif/esp-idf/bl ... L35-L39C36 it is written that the timer should be started and stopped to apply the prescaler change, but even if i do nothing happen


I already tried to stop and star the timer in particular I'm doing something on the line of:
  1. ESP_ERROR_CHECK(mcpwm_stop(0, 0));
  2. MCPWM0.timer[0].timer_cfg0.timer_prescale = 30; //THIS IS NOT WORKING!!!
  3. MCPWM0.timer[0].timer_cfg0.timer_period = 1000; //THIS WORK
  4. ESP_ERROR_CHECK(mcpwm_start(0, 0));
I tried various configurations, order of operation, mcpwm_timer_trigger_soft_sync ( before, after and while) but nothing is working

I tried to stop and start the whole unit with:
  1. MCPWM0.clk.clk_en = 0;
  2. MCPWM0.clk.clk_en = 1;
But nothing is working...


Do you have any other idea? Or other way to stop and start the timer?


Thanks,
Luca

Re: MCPWM change TIMERn Prescaler

Posted: Tue Aug 29, 2023 5:34 pm
by makark
Hi Luca,
Were you able to solve this issue? I have been trying for the past couple of days, bot nothing seemed to help.

Best,
Makar