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

Not applicable

Here is an example how to use the CCU4 as a capture timer to timestamp edges of external signals.

It is developed with the XMC 2Go with an XMC1100 chip.

  • Create a DAVE CE project
  • Add the CCU4GLOBAL app
  • Add the IO004 app and configure Output Enable (this is just used as a debug LED)
  • Use "Manual Pin Assignment" to direct the IO004 app to P1.0 (which is connected to a LED on the XMC 2Go board)
  • Solver, Generate Code
  • Put the following code to Main.c

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


volatile uint16_t Capture[NUM_CAPTURE];
volatile uint32_t CaptureLast;
volatile uint16_t CapturePtr;

void CCU40_1_IRQHandler() {
uint32_t CV;
// read capture value from CC4yC1V
CV = CCU40_CC41->CV[1];
Capture[CapturePtr] = (CV & 0xFFFF) - (CaptureLast & 0xFFFF);
CapturePtr = (CapturePtr + 1) & NUM_CAPTURE_MASK;
CaptureLast = CV;

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

* Manual CCU4 as Capture timer
* 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;

// map input signal (see p. 17-137ff) to one of three Events with CC4yINS.EVxIS
// and select active edge of the signal with CC4yINS.EVxEM
// --> map CCU41.IN1B = P0.7 as Event 0, select both edges
CCU40_CC41->INS = (0x1 << CCU4_CC4_INS_EV0IS_Pos) | (0x3 << CCU4_CC4_INS_EV0EM_Pos);
// select this Event as source for capture trigger 0 or 1 with CC4yCMC.CAP0S or .CAP1S, respectively
// capture trigger 0 --> timer is captured to CC4yC1V, old value moved to C0V
// sets full flag, a bit complicated, can be disabled by CC4yTC.CCS
CCU40_CC41->CMC = (0x1 << CCU4_CC4_CMC_CAP0S_Pos);
// set CC4yTC.SCE (use two pairs or four capture registers) and .CCS (use full flag)
// ?

// Set the prescaler value: clock is divided by 2^n, with n=0..15
CCU40_CC41->PSC = 0x000A; // divide 32MHz by 2^10 = 1024 --> 31250Hz
// Set the period of the timer (full range)
CCU40_CC41->PRS = 0xFFFF;
// Enable the synchronized transfer of the period value into the active register

// set CC4ySRS.ExSR to forward the event as a service request (and further as an interrupt)
WR_REG(CCU40_CC41->SRS, CCU4_CC4_SRS_E0SR_Msk, CCU4_CC4_SRS_E0SR_Pos, (uint32_t)0x01); // Service Request 1
// Enable Event 0 detection interrupt

/* Enables the timer */
/* Start the timer */

CaptureLast = 0;
CapturePtr = 0;

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

while(1) { }

return 0;

This example uses the CCU40 slice CC41 and uses P0.7 as its input. It generates an interrupt (using service request 1) for every captured signal edge (rising and falling). The ISR will toggle LED1 and store the time difference since the last capture event into the array "Capture". While debugging, just suspend the execution and inspect its contents.

For a test signal you can use a second XMC 2Go with the blinking LEDs example I've posted as a reply at
Just change the pin assignment of one of its two IO004 apps to, e.g., P0.7. Then connect this output to the P0.7 input of the XMC 2Go running the example in this post. Also connect VSS (GND) to avoid ringing. If DAVE3 complains that you have two possible targets, you can supply the blinking XMC 2Go separately, e.g. with your smart phone charger. Since its output is floating, it is mandatory to connect VSS.

When using the 1Hz signal (i.e., 0.5s on, 0.5s off), the values in "Capture" should be approx. 15625 (0x3D09). Note that the value will vary slightly due to drifting oscillators.

0 Replies