Not applicable
May 10, 2017
04:58 AM
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
May 10, 2017
04:58 AM
Hi,
I'm trying to create a very simple 32-bit concatenated timer by using CCU4 (no DAVE app). It only needs to generate interrupts and call my ISR at my specified interval. I'm using the PERIOD_MATCH event.
I've posted the code below. It does in fact generate interrupts and call my ISR, but the interval times is incorrect. E.g. when I set the frequency to be 100 Hz, it generates interrupts in ~300 Hz. If I try another frequency, I get another actual frequency. It does not seem to follow any linear relationship.
If I remove the code for concatenation, it works perfectly (with only 16-bit timer). I've tried to write the code exactly like the example in "CCU4_SLICE_CONFIG_EXAMPLE_XMC47.zip", but that example uses the COMPARE_MATCH event so the code if a little bit different.
Can you please take a look at my code and tell me what is wrong?
I'm trying to create a very simple 32-bit concatenated timer by using CCU4 (no DAVE app). It only needs to generate interrupts and call my ISR at my specified interval. I'm using the PERIOD_MATCH event.
I've posted the code below. It does in fact generate interrupts and call my ISR, but the interval times is incorrect. E.g. when I set the frequency to be 100 Hz, it generates interrupts in ~300 Hz. If I try another frequency, I get another actual frequency. It does not seem to follow any linear relationship.
If I remove the code for concatenation, it works perfectly (with only 16-bit timer). I've tried to write the code exactly like the example in "CCU4_SLICE_CONFIG_EXAMPLE_XMC47.zip", but that example uses the COMPARE_MATCH event so the code if a little bit different.
Can you please take a look at my code and tell me what is wrong?
const XMC_CCU4_SLICE_COMPARE_CONFIG_t timer_config =
{
.timer_mode = XMC_CCU4_SLICE_TIMER_COUNT_MODE_EA,
.monoshot = XMC_CCU4_SLICE_TIMER_REPEAT_MODE_REPEAT,
.shadow_xfer_clear = 0U,
.dither_timer_period = 0U,
.dither_duty_cycle = 0U,
.prescaler_mode = (uint32_t)XMC_CCU4_SLICE_PRESCALER_MODE_NORMAL,
.mcm_enable = 0U,
.prescaler_initval = 0U,
.float_limit = 0U,
.dither_limit = 0U,
.passive_level = (uint32_t)XMC_CCU4_SLICE_OUTPUT_PASSIVE_LEVEL_LOW,
.timer_concatenation = 0U
};
const XMC_CCU4_SLICE_COMPARE_CONFIG_t timer_config2 =
{
.timer_mode = XMC_CCU4_SLICE_TIMER_COUNT_MODE_EA,
.monoshot = XMC_CCU4_SLICE_TIMER_REPEAT_MODE_REPEAT,
.shadow_xfer_clear = 0U,
.dither_timer_period = 0U,
.dither_duty_cycle = 0U,
.prescaler_mode = (uint32_t)XMC_CCU4_SLICE_PRESCALER_MODE_NORMAL,
.mcm_enable = 0U,
.prescaler_initval = 0U,
.float_limit = 0U,
.dither_limit = 0U,
.passive_level = (uint32_t)XMC_CCU4_SLICE_OUTPUT_PASSIVE_LEVEL_LOW,
.timer_concatenation = 1U
};
void CCU43_0_IRQHandler(void)
{
// This Interrupt Service Routine is called every time the timer times out
// Clear pending interrupt
XMC_CCU4_SLICE_ClearEvent(CCU43_CC40, XMC_CCU4_SLICE_IRQ_ID_PERIOD_MATCH);
XMC_CCU4_SLICE_ClearEvent(CCU43_CC41, XMC_CCU4_SLICE_IRQ_ID_PERIOD_MATCH);
events |= EventFlag;
}
void SetFrequency(uint32_t desiredFrequency)
{
uint32_t desiredSteps = 0;
uint16_t desiredStepsHigh = 0;
uint16_t desiredStepsLow = 0;
if (desiredFrequency == 0)
{
desiredSteps = 0xFFFFFFFF;
}
desiredSteps = SystemCoreClock / desiredFrequency;
desiredStepsHigh = desiredSteps >> 16;
desiredStepsLow = desiredSteps & 0xFFFF;
XMC_CCU4_SLICE_SetTimerPeriodMatch(CCU43_CC41, desiredStepsHigh);
XMC_CCU4_SLICE_SetTimerPeriodMatch(CCU43_CC40, desiredStepsLow);
XMC_CCU4_EnableShadowTransfer(CCU43, (uint32_t)XMC_CCU4_SHADOW_TRANSFER_SLICE_0);
XMC_CCU4_EnableShadowTransfer(CCU43, (uint32_t)XMC_CCU4_SHADOW_TRANSFER_SLICE_1);
}
void Initialize()
{
XMC_CCU4_Init(CCU43, XMC_CCU4_SLICE_MCMS_ACTION_TRANSFER_PR_CR);
XMC_CCU4_StartPrescaler(CCU43);
XMC_CCU4_SetModuleClock(CCU43, XMC_CCU4_CLOCK_SCU);
XMC_CCU4_SLICE_CompareInit(CCU43_CC40, &timer_config);
XMC_CCU4_SLICE_CompareInit(CCU43_CC41, &timer_config2);
XMC_CCU4_SLICE_SetTimerCompareMatch(CCU43_CC40, 0U);
XMC_CCU4_SLICE_SetTimerCompareMatch(CCU43_CC41, 0U);
XMC_CCU4_SLICE_SetTimerPeriodMatch(CCU43_CC40, 0xFFFF);
XMC_CCU4_SLICE_SetTimerPeriodMatch(CCU43_CC41, 0xFFFF);
XMC_CCU4_SLICE_SetPrescaler(CCU43_CC40, 0x00);
XMC_CCU4_SLICE_SetPrescaler(CCU43_CC41, 0x00);
XMC_CCU4_EnableShadowTransfer(CCU43, (uint32_t)(XMC_CCU4_SHADOW_TRANSFER_SLICE_0 | XMC_CCU4_SHADOW_TRANSFER_PRESCALER_SLICE_0 | XMC_CCU4_SHADOW_TRANSFER_DITHER_SLICE_0));
XMC_CCU4_EnableShadowTransfer(CCU43, (uint32_t)(XMC_CCU4_SHADOW_TRANSFER_SLICE_1 | XMC_CCU4_SHADOW_TRANSFER_PRESCALER_SLICE_1 | XMC_CCU4_SHADOW_TRANSFER_DITHER_SLICE_1));
/* Enable the event for CCU43_41 because it is AND-ed with the period match of CCU43_CC40 */
XMC_CCU4_SLICE_EnableEvent(CCU43_CC41, XMC_CCU4_SLICE_IRQ_ID_PERIOD_MATCH);
XMC_CCU4_SLICE_SetInterruptNode(CCU43_CC41, XMC_CCU4_SLICE_IRQ_ID_PERIOD_MATCH, XMC_CCU4_SLICE_SR_ID_0);
XMC_CCU4_EnableClock(CCU43, 0);
XMC_CCU4_EnableClock(CCU43, 1);
NVIC_SetPriority(CCU43_0_IRQn, 3U);
NVIC_EnableIRQ(CCU43_0_IRQn);
/* Set the frequency */
SetFrequency(100);
// TODO: Start simultaneously
XMC_CCU4_SLICE_StartTimer(CCU43_CC40);
XMC_CCU4_SLICE_StartTimer(CCU43_CC41);
}
Labels
3 Replies
May 21, 2017
08:05 PM
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
May 21, 2017
08:05 PM
Hello,
I was having similar problem with concatenated timers and the examples provided by infineon lack explanation of how formulas actually work out.
any way, a bit of search on the web I came across an example for the XMC1300 mcu, and the documentation is a bit better and I was able to make it work
for XMC4700.
The example I found in this thread: https://www.infineonforums.com/threads/3227-DAVE-4-PWM-App-Removed-timer-concatenation-support
Hope it helps.
I was having similar problem with concatenated timers and the examples provided by infineon lack explanation of how formulas actually work out.
any way, a bit of search on the web I came across an example for the XMC1300 mcu, and the documentation is a bit better and I was able to make it work
for XMC4700.
The example I found in this thread: https://www.infineonforums.com/threads/3227-DAVE-4-PWM-App-Removed-timer-concatenation-support
Hope it helps.
Not applicable
May 23, 2017
05:26 AM
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
May 23, 2017
05:26 AM
moisesesc wrote:
Hello,
I was having similar problem with concatenated timers and the examples provided by infineon lack explanation of how formulas actually work out.
any way, a bit of search on the web I came across an example for the XMC1300 mcu, and the documentation is a bit better and I was able to make it work
for XMC4700.
The example I found in this thread: https://www.infineonforums.com/threads/3227-DAVE-4-PWM-App-Removed-timer-concatenation-support
Hope it helps.
Thanks moisesesc.
I looked at the code that is posted in your link. It is doing exactly what I want to do. However I also see that I configure the timers exactly like in that example and my code does not work as expected.
My code works if I only use one CCU4 unit (16 bit timer). Of course I modify it a little bit from the code I posted above. But when I add the second CCU4 unit in concatenated mode (by setting the concatenated bit in the register), the period that is generated is not correct according to the period I set.
Am I missing something? Are there any other settings that must be done to make concatenation work properly?
Rickard
Not applicable
May 30, 2017
05:24 AM
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
May 30, 2017
05:24 AM
Hi!
I found the problem thanks to your code moisesesc! I made an error in how I calculated the upper and lower registers 🙂
Instead of:
it should be:
Rickard
I found the problem thanks to your code moisesesc! I made an error in how I calculated the upper and lower registers 🙂
Instead of:
desiredStepsHigh = desiredSteps >> 16;
desiredStepsLow = desiredSteps & 0xFFFF;
it should be:
for (i = 1; i < 65535; i++)
{
desiredStepsLow = desiredSteps / i;
if(desiredStepsLow < 65535U)
{
desiredStepsHigh = i - 1;
break;
}
}
Rickard