Simple CCU4 Timer without APP and Systime

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
Not applicable
Hi,

here is a simple Timerroutine with CCU4.


#define CLOCK_DIV_BY_200 200
#define PERIOD_OF_TIMER 100

void CCU40_0_IRQHandler(){
static uint8_t cnt;
cnt++;
if(cnt == 156){
P0_6_toggle();
cnt = 0;
}
}

int main(){
//Disable the clock gating for CCU4 module
SCU_GENERAL->PASSWD = 0xC0U;
SET_BIT(SCU_CLK->CGATCLR0, SCU_CLK_CGATCLR0_CCU40_Pos);
SCU_GENERAL->PASSWD = 0xC3UL;
//Enable the prescaler block
SET_BIT(CCU40->GIDLC, CCU4_GIDLC_SPRB_Pos);
/* Set the prescaler value */
WR_REG(CCU40_CC40->PSC, CCU4_CC4_PSC_PSIV_Msk, CCU4_CC4_PSC_PSIV_Pos, (uint32_t)CLOCK_DIV_BY_200);
/* Control of CCU4 timer slices */
CCU40->GCTRL = (uint32_t)0;
/* Set the period of the timer */
WR_REG(CCU40_CC40->PRS, CCU4_CC4_PRS_PRS_Msk, CCU4_CC4_PRS_PRS_Pos, (uint32_t)PERIOD_OF_TIMER);
/* Enable the synchronized transfer of the period value into the active register */
SET_BIT(CCU40->GCSS, CCU4_GCSS_S0SE_Pos);
/* Set which interrupt line the timer interrupt is directed toward */
WR_REG(CCU40_CC40->SRS, CCU4_CC4_SRS_CMSR_Msk, CCU4_CC4_SRS_CMSR_Pos, (uint32_t)0x02); // Service Request 2
/* Enable interrupt generation on comparison match */
SET_BIT(CCU40_CC40->INTE, CCU4_CC4_INTE_PME_Pos);
/* Enables the timer */
SET_BIT(CCU40->GIDLC, CCU4_GIDLC_CS0I_Pos);
/* Start the timer */
SET_BIT(CCU40_CC40->TCSET, CCU4_CC4_TCSET_TRBS_Pos);

NVIC_SetPriority(CCU40_0_IRQn, 0xC0); //This CMSIS function configures node 1 to priority level 0 (highes Priority)
NVIC_ClearPendingIRQ(CCU40_0_IRQn); //This function clears node 1 pending status
NVIC_EnableIRQ(CCU40_0_IRQn); //This function enables node 1 for interrupt request generation

P0_6_set_mode(OUTPUT_PP_GP);




while(1){

}//End while
}//End main
0 Likes
1 Reply
Not applicable
Thanks for this example, it helped me a lot to get the CCU4 running as a simple timer!

Although, the above example has two bugs.

First, the value assigned to the prescaler CC4yPSC register should be a 4-bit value, i.e. 0..15, as documented e.g. on p. 17-116 of the XMC1100 Reference Manual V1.1. The CC4y clock will be the CCU peripheral input frequency devided by 2^PSC as documented on p. 17-58.

Secondly, the interrupt line is configured to use Service Request 2 (SRS register, see p. 17-130f). However, the above code configures the Compare Match Service Request to use SR2, but in the next line enables the Period Match interrupt (INTE register, p. 17-128f). Fortunately the Period Match Service Request defaults to SR0, for which the CCU interrupt is enabled and an ISR is present.

I've developed an example for the XMC 2Go blinking its LEDs using the CCU4 as a periodic interrupt source (like the above example).


  • Create a DAVE CE project
  • Add the CCU4GLOBAL app
  • Add two instances of the IO004 app and configure Output Enable for both
  • Use "Manual Pin Assignment" to direct the two IO004 apps to P1.0 and P1.1 (which are connected to the two LEDs on the XMC 2Go board)
  • Solver, Generate Code
  • Put the following code to Main.c



#include // Declarations from DAVE3 Code Generation (includes SFR declaration)

void CCU40_0_IRQHandler() {
IO004_TogglePin(IO004_Handle0);
IO004_TogglePin(IO004_Handle1);
}

int main(void) {
DAVE_Init(); // Initialization of DAVE Apps

/*
* Manual CCU4
*
* see example at http://www.infineonforums.com/threads/2045-Simple-CCU4-Timer-without-APP-and-Systime
*
*/
// Disable the clock gating for CCU4 module and Enable the prescaler block is done by CCU4GLOBAL
/* Control of CCU4 timer slices */
CCU40->GCTRL = (uint32_t)0;

// Set the prescaler value: clock is divided by 2^n, with n=0..15
CCU40_CC40->PSC = 0x000F; // divide 32MHz by 2^15 = 32768 --> 976.6Hz
// Set the period of the timer: 2x per second
CCU40_CC40->PRS = (977 >> 1)-1;
// Enable the synchronized transfer of the period value into the active register
CCU40->GCSS |= CCU4_GCSS_S0SE_Msk;
// Set which interrupt line the timer interrupt is directed toward
WR_REG(CCU40_CC40->SRS, CCU4_CC4_SRS_POSR_Msk, CCU4_CC4_SRS_POSR_Pos, (uint32_t)0x00); // Service Request 0
// Enable interrupt generation on period match
SET_BIT(CCU40_CC40->INTE, CCU4_CC4_INTE_PME_Pos);
/* Enables the timer */
SET_BIT(CCU40->GIDLC, CCU4_GIDLC_CS0I_Pos);
/* Start the timer */
SET_BIT(CCU40_CC40->TCSET, CCU4_CC4_TCSET_TRBS_Pos);

// configure and enable interrupt for CCU40 SR0
NVIC_SetPriority(CCU40_0_IRQn, 0xC0); //This CMSIS function configures node 1 to priority level 0 (highes Priority)
NVIC_ClearPendingIRQ(CCU40_0_IRQn); //This function clears node 1 pending status
NVIC_EnableIRQ(CCU40_0_IRQn); //This function enables node 1 for interrupt request generation

while(1) { }

return 0;
}


Then compile and debug. The LEDs should blink with 1Hz (0,5s on, 0,5s off).

Bye
Hansi
0 Likes