How to implement 32bit free running hardware timer with XMC

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

cross mob
User8819
Level 4
Level 4
Hi everyone,

What are the options for implementing 32bit free running "hardware" timer with XMC?

I have tried to use CCU4 and concatenate two 16bit timers but reading of timer value is not "atomic", I mean it can overflow when reading only MSB or LSB.

Thanks

Rum
0 Likes
15 Replies
Not applicable
Hi Rum,

Sorry, I don't really understand what you want to achieve?
However, I assume that you understand the meaning of MSB and LSB:
During the timer concatenation, whenever lower timer (LSB) has exceeded the max period value (0xFFFF), the higher timer (MSB) will count +1, and then lower timer will restart from zero.
You should be able to get periodic trigger by enabling the Compare/Period Match Interrupt.

Best regards,
Sophia
0 Likes
User8819
Level 4
Level 4
Hi Sophia,

The problem is that I cannot access two registers LSB and MSB using "one 32bit atomic read", if I read first MSB and then LSB, or in opposite sequence, since the timer is incrementing values I get are not consistent. The LSB may have overflowed or MSB not counted yet.

How can I solve this problem without having to "postprocess"? I don't need to trigger anything. I want to have just free running 32bit timer to provide base for some measurements.

Thanks for answer

Rum
0 Likes
Not applicable
Hi Rum,

I think you should be able to use Capture Mode without clearing the Timer upon capture event (eg. CC4yTC.CAPC = 00B). You can read Capture Register values (CC4yCxV.CAPTV) in Capture ISR.

Best regards,
Sophia
0 Likes
User8819
Level 4
Level 4
Hi Sophia,

But how to trigger capture by software? Is it possible because I can see that only external events are allowed for trigger? What I need is to trigger capture once on free running timer, and after some time trigger again and calculate the time difference. Without using the interrupts. I need to measure execution time of some portion of code.

Thanks

Rum
0 Likes
Not applicable
Hi Rum,

You can use set/clear Timer Run Bit (CC4yTCSET.TRBS/CC4yTCCLR.TRBC) to control the start/stop of the slice timer.

Best regards,
Sophia
0 Likes
User8819
Level 4
Level 4
Hi Sophia
Thank you for your support and suggestions. However approach you proposed is not suitable for my application. I need to measure 3 to 4 tasks which are running concurrently, that would consume at least 2 cut units. It seems that simplest approach with free running timer with 32 bit resolution is not possible with xmc
Rum
0 Likes
Not applicable
Hi Rum,

Which device are you using?
There are 4 CCU4 modules available for XMC4500 and each CCU4 module is comprised of 4 identical 16 bit timer slices. If you are using XMC1300, you can use CCU4 and CCU8.

Best regards,
Sophia
0 Likes
User9260
Level 1
Level 1
Hi Rum,

the XMC4400 has a 32-bit counter in its watchdog WDT which can be read atomically. You may configure the WDT to increment this counter wrapping from 0xFFFF.FFFF to 0x00 without resetting the CPU. I am not sure if you can configure the WDT to use a precise count frequency.

If the WDT is already used in your firmware, you may adapt algorithm below (from ARM for the Cortex-A9 64-bit timers, see ARM DDI 0407G, ID072711) for the 16-bit counters in the CCUs:

1. Read the upper 32-bit timer counter register
2. Read the lower 32-bit timer counter register
3. Read the upper 32-bit timer counter register again. If the value is different to the 32-bit upper value read previously, go back to step 2. Otherwise the 64-bit timer counter value is correct.

Going back to step 2 will happen only in rare cases.

HTH, Rudi
0 Likes
User8819
Level 4
Level 4
Hi Rudi,

Thanks for the effort, I use already WDT timer for WDT purpose. About the other technique, of course I am aware of it, this is what I meant by "post-processing". I only wonder why XMC does not have some 32 bit timer for such purpose. Would be great to have system timer as on Tricore/Aurix family.

BR

rum
0 Likes
Not applicable
Hi Rudi,

I have the same requirement for a free-running unsigned 32-bit count, that wraps from 0xFFFFFFFF to 0.

You were saying 'You may configure the WDT to increment this counter wrapping from 0xFFFF.FFFF to 0x00 without resetting the CPU'. May I ask, how to do so?

Looking through all the documentation, within DAVE and the Infineon XMC reference manual, I could find no way of doing so. Seemingly, if the timer exceeds the upper bound without WDT servicing, then the CPU self-resets, regardless.

And adding servicing of the watchdog doesn't help, as that resets the 32-bit counter, subverting the requirement for a free-running counter.

I am using an XMC4300 rather than an XMC4400. Perhaps the former lacks a wrap-without-reset ability.

If I can't use the WDT timer for a free-running counter, can anyone help with an example showing use instead of the CCU for that purpose, if possible ?

Best regards,

David King
0 Likes
User9260
Level 1
Level 1
Hi David,

the WDT has a pre-warning mode in which the first wrap does not immediately resets the CPU. This mode can be enabled by setting bit PRE in the CTR register.

Best regards,
Rudi
0 Likes
Not applicable
Hi Rudi,

Thanks for getting back to me. Meanwhile, I've been looking into the pre-warning alarm mode myself.

What I've found, from the documentation and experimentation, is that in that mode, if the WDT exceeds the configured upper bound ms, without the WD being serviced, then the WDT resumes counting from zero, and also triggers an interrupt (choice of regular or non-maskable). But as you say, doesn't trigger a CPU reset.

I guess, I can set the upper bound to a ms value corresponding to a WDT internal count of 0xFFFFFFFF, to achieve wrap from 0xFFFFFFFF to 0.

However, this only takes us part of the way.

Because, the *next* time the WDT exceeds the upper bound, a CPU reset *does* occur.

The only way to prevent that, it to issue a WDT alarm clear command, *and* to issue a WDT service command, before the upper bound is again exceeded.
These can be performed in either order. But both are needed.

Now, I can issue those two commands, within the handler for the mentioned interrupt.

Within that handler, right at the beginning, if I look at the WDT internal count, it is has typically reached a value of around 50. In other words, it has counted 50 times, since the CPU zeroing it, when the upper bound was exceeded. The figure of 50 represents the latency of the interrupt handling.

The WDT alarm clear command doesn't affect the WDT internal count, it carries on counting.

But the WDT service command *does* affect the WDT internal count, it gets changed from 50 back to zero again. Indeed, as an WDT service command always does.

Consequently, I 'lose' a little bit of time, each time that interrupt fires, and the WDT service command is issued.

Probably, I can live with that.

But it's not ideal.

Really, I just want a 32-bit counter that counts and wraps 0xFFFFFFFF to 0, all by itself.

Oh well..

Best regards,

David
0 Likes
User9260
Level 1
Level 1
Hi David,

the best way to achieve a precise timing should be the concatenation of two or even more of the 16bit timers. According to Infineon this should be quite easy using DAVE. BTW, I never used DAVE as it does not fulfill our requirements on professional firmware development. Perhaps you should search again for examples somewhere, i.e. not necessarily only on the web pages from Infineon.

Best regards, Rudi
0 Likes
lock attach
Attachments are accessible only for community members.
jferreira
Employee
Employee
10 sign-ins 5 sign-ins First like received
Hi,

Find attached an example using CCU4x timer slices.

Regards,
Jesus
0 Likes
Not applicable
Hi Jesus,

Many thanks, for that.

I see that using CCU4x timer slices is a fair bit more involved than just using the watchdog timer. But if it avoids the occasional time loss I mentioned, then great.

I'll take a look at your example.

Many thanks,

David
0 Likes