Quantcast
Channel: Infineon Forums
Viewing all articles
Browse latest Browse all 9892

XMC4500 32-bit concatenated timer

$
0
0
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?

Code:

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);
}


Viewing all articles
Browse latest Browse all 9892

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>