- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
A few weeks ago I reported a similar problem in my application with TCPWM Timers. Unfortunately, in that opportunity we couldn't reproduce the problem using a simplified Hello World example. Now I have the same problem with TCPWM in PWM mode. Like before, the only sure way to change its period is by deinint the PWM and reinit it with the new period.
But this time I could reproduce the problem in the Hello World example, which I uploaded here. For what I could pick up from the PDL documentation and other comments this should be the correct way to change the PWM period, but it does nothing:
/* validate frequency ranges */
if (_timer_frequency < MIN_FREQUENCY || _timer_frequency > MAX_FREQUENCY)
return;
Cy_TCPWM_TriggerStopOrKill(PWM_1_HW, PWM_1_NUM);
Cy_TCPWM_PWM_SetCounter(PWM_1_HW, PWM_1_MASK, 0);
uint32_t new_period = _timer_clock / _timer_frequency;
Cy_TCPWM_PWM_SetPeriod0(PWM_1_HW, PWM_1_MASK, new_period);
Cy_TCPWM_PWM_SetPeriod1(PWM_1_HW, PWM_1_MASK, new_period); // just in case!
Cy_TCPWM_TriggerReloadOrIndex_Single(PWM_1_HW, PWM_1_NUM);
the clock frequency is 10 KHz and the PWM range needed is 1 to 400 Hz. Nothing spectacular.
uncommenting //#define USE_REINIT_MODE at line 200 of main.c you can select the code above or the full reinit mode which actually works.
I left there the older Timer test routines, but the timer init is commented out in main(). The loop reads the debug terminal awaiting single key commands. P should change the PWM from 1 to 10 Hz that toggles the LED accordingly.
The PDL documentation should have complete examples of these functions A to Z. Not just a snippet with a line of comment.
Solved! Go to Solution.
- Labels:
-
PSoC 6 MCU
- Tags:
- pwm
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi ARH,
UPDATE
I reviewed my code once again, cross check with the API, and found what the error was in my code, induced by errors in the API example (!!!).
Here is the sample code for Cy_TCPWM_PWM_SetCounter()
Cy_TCPWM_PWM_SetCounter(PWM_1_HW, PWM_1_NUM, 0);
Cy_TCPWM_PWM_SetPeriod0(PWM_1_HW, PWM_1_NUM, new_period);
Cy_TCPWM_TriggerReloadOrIndex_Single(PWM_1_HW, PWM_1_NUM);
bool Set_PWM_1_Frequency(uint32_t _new_frequency)
{
/* validate frequency ranges */
if (_new_frequency< MIN_FREQUENCY || _new_frequency> MAX_FREQUENCY)
return true;
uint32_t new_period = _timer_clock / _new_frequency;
Cy_TCPWM_TriggerStopOrKill_Single(PWM_1_HW, PWM_1_NUM);
/* IMPORTANT: Wait until the counter has stopped before changing its parameters */
while ( Cy_TCPWM_PWM_GetStatus(PWM_1_HW, PWM_1_NUM) & CY_TCPWM_PWM_STATUS_COUNTER_RUNNING )
;
Cy_TCPWM_PWM_SetCounter(PWM_1_HW, PWM_1_NUM, 0);
Cy_TCPWM_PWM_SetPeriod0(PWM_1_HW, PWM_1_NUM, new_period);
Cy_TCPWM_TriggerReloadOrIndex_Single(PWM_1_HW, PWM_1_NUM);
return false;
}
Conclusion, a set of full blown examples known to work is not a bad idea after all.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I read your post several times and I am not sure that I understand.
You for sure can change the period of a TCPWM on the fly. The only thing that you need to be careful of is if you change the period to be less than the counter if you are counting up you will endup with really weird behavior (which I bet is what is happening)
As far as the documentation goes.... yes there is always improvements to be made. I will say that my personal bias was always to have SIMPLE code snippets that show one specific thing rather than more complete examples in the documentation which take more time to study. The strategy was always to make more complicated examples as code example.
The documentation tells you to stop the counter... then change the period... then restart .. this is obviously the safest thing to do... e..g. in a motor control example. Im 99% sure that in your chase you can just change it.
I would for sure make sure that you are down counting... as im almost sure that was the problem.
ARH
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi ARH,
UPDATE
I reviewed my code once again, cross check with the API, and found what the error was in my code, induced by errors in the API example (!!!).
Here is the sample code for Cy_TCPWM_PWM_SetCounter()
Cy_TCPWM_PWM_SetCounter(PWM_1_HW, PWM_1_NUM, 0);
Cy_TCPWM_PWM_SetPeriod0(PWM_1_HW, PWM_1_NUM, new_period);
Cy_TCPWM_TriggerReloadOrIndex_Single(PWM_1_HW, PWM_1_NUM);
bool Set_PWM_1_Frequency(uint32_t _new_frequency)
{
/* validate frequency ranges */
if (_new_frequency< MIN_FREQUENCY || _new_frequency> MAX_FREQUENCY)
return true;
uint32_t new_period = _timer_clock / _new_frequency;
Cy_TCPWM_TriggerStopOrKill_Single(PWM_1_HW, PWM_1_NUM);
/* IMPORTANT: Wait until the counter has stopped before changing its parameters */
while ( Cy_TCPWM_PWM_GetStatus(PWM_1_HW, PWM_1_NUM) & CY_TCPWM_PWM_STATUS_COUNTER_RUNNING )
;
Cy_TCPWM_PWM_SetCounter(PWM_1_HW, PWM_1_NUM, 0);
Cy_TCPWM_PWM_SetPeriod0(PWM_1_HW, PWM_1_NUM, new_period);
Cy_TCPWM_TriggerReloadOrIndex_Single(PWM_1_HW, PWM_1_NUM);
return false;
}
Conclusion, a set of full blown examples known to work is not a bad idea after all.