Open eriksl opened 4 days ago
Didn't reproduce the issue with the following init code:
TEST_CASE("mcpwm timer with different resolutions", "[mcpwm]")
{
mcpwm_timer_config_t timer_config = {
.group_id = 0,
.clk_src = MCPWM_TIMER_CLK_SRC_DEFAULT,
.resolution_hz = 80 * 1000 * 1000,
.period_ticks = 20 * 1000,
.count_mode = MCPWM_TIMER_COUNT_MODE_UP,
};
mcpwm_timer_handle_t timer0, timer1;
printf("create mcpwm timers\r\n");
TEST_ESP_OK(mcpwm_new_timer(&timer_config, &timer0));
timer_config.resolution_hz = 5 * 1000 * 1000;
TEST_ESP_OK(mcpwm_new_timer(&timer_config, &timer1));
printf("delete timers\r\n");
TEST_ESP_OK(mcpwm_del_timer(timer0));
TEST_ESP_OK(mcpwm_del_timer(timer1));
}
That's interesting. I have tested it more than once. I have run the same code on one and on two mcpwm groups, using two groups it works like a charm, on one group it doesn't.
I think I know where's the difference. I am always using a 16 bit (max) resolution timer.
Please try with:
mcpwm_timer_config_t timer_config =
{
.group_id = 0,
.clk_src = MCPWM_TIMER_CLK_SRC_DEFAULT,
.resolution_hz = FREQUENCY,
.count_mode = MCPWM_TIMER_COUNT_MODE_UP,
.period_ticks = TIMER_TICKS,
.intr_priority = 0,
.flags =
{
.update_period_on_empty = 0,
.update_period_on_sync = 0,
},
};
where either
This is where the problem occurs.
@eriksl this can be workaround by set the higher resolution first then the smaller resolution.
e.g.
TEST_CASE("mcpwm timer with different resolutions", "[mcpwm]")
{
mcpwm_timer_config_t timer_config = {
.group_id = 0,
.clk_src = MCPWM_TIMER_CLK_SRC_DEFAULT,
.resolution_hz = 160 * 1000 * 1000,
.period_ticks = 65535,
.count_mode = MCPWM_TIMER_COUNT_MODE_UP,
};
mcpwm_timer_handle_t timer0, timer1;
printf("create mcpwm timers\r\n");
TEST_ESP_OK(mcpwm_new_timer(&timer_config, &timer0));
timer_config.resolution_hz = 10 * 1000 * 1000;
TEST_ESP_OK(mcpwm_new_timer(&timer_config, &timer1));
printf("delete timers\r\n");
TEST_ESP_OK(mcpwm_del_timer(timer0));
TEST_ESP_OK(mcpwm_del_timer(timer1));
}
Answers checklist.
IDF version.
5.3.1
Espressif SoC revision.
ESP32-S3 0.1
Operating System used.
Linux
How did you build your project?
Command line with idf.py
If you are using Windows, please specify command line type.
None
Development Kit.
LilyGO S3 T7
Power Supply used.
USB
What is the expected behavior?
I expected to be able to run different timers within one MCPWM group to be able to run at different frequencies. I have selected APB frequency for timer0 and APB / 16 for timer1, so there should be no problem. The technical reference manual says (register overview) there is a common prescaler for all timers and a specific prescaler for each timer, so it should be possible. This is also what the text says, although the diagram of the MCPWM module is indecisive on this matter.
What is the actual behavior?
These reports and abort called:
Besides the first report being very cryptic, it looks like the code simply doesn't take the timer-specific prescaler into account. Or there is none and the documentation is incorrect.
Steps to reproduce.
Nothing more required than this.
When you create both timers with the same frequencies it works. If the timers are on separate groups, it works as well.
Debug Logs.
More Information.
I am forced to use MCPWM for my lighting ("LED") purposes as the "LEDPWM" has a resolution of only 14 bits, which is really too little. I don't understand why the "fast LEDPWM" channels where dropped (with the high resolution timers). I am now investigating ways to achieve similar PWM resolutions. The 16 bit width of MCPWM is step one, but I'd really like even more. I am thinking of having the cpu updating the PWM "value" on the fly after one or more timer overflow interrupts, but it sounds complex to implement. On the other hand, it may even be done on the LEDPWM module.
Other possible paths:
I am interested in any interesting hints to workaround this omission.