Dec 14, 2014
12:20 PM
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Dec 14, 2014
12:20 PM
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
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
15 Replies
Not applicable
Dec 15, 2014
01:07 AM
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Dec 15, 2014
01:07 AM
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
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
Dec 15, 2014
11:59 AM
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Dec 15, 2014
11:59 AM
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
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
Not applicable
Dec 16, 2014
12:59 AM
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Dec 16, 2014
12:59 AM
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
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
Dec 20, 2014
05:15 AM
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Dec 20, 2014
05:15 AM
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
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
Not applicable
Dec 23, 2014
12:10 AM
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Dec 23, 2014
12:10 AM
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
You can use set/clear Timer Run Bit (CC4yTCSET.TRBS/CC4yTCCLR.TRBC) to control the start/stop of the slice timer.
Best regards,
Sophia
Dec 28, 2014
10:59 PM
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Dec 28, 2014
10:59 PM
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
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
Not applicable
Dec 30, 2014
01:04 AM
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Dec 30, 2014
01:04 AM
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
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
Jan 23, 2015
05:51 AM
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Jan 23, 2015
05:51 AM
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
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
Feb 03, 2015
04:32 AM
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Feb 03, 2015
04:32 AM
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
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
Not applicable
Apr 10, 2017
01:28 AM
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Apr 10, 2017
01:28 AM
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
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
Apr 10, 2017
03:42 AM
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Apr 10, 2017
03:42 AM
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
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
Not applicable
Apr 10, 2017
04:05 AM
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Apr 10, 2017
04:05 AM
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
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
Apr 10, 2017
04:40 AM
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Apr 10, 2017
04:40 AM
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
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
Attachments are accessible only for community members.
Apr 19, 2017
05:31 AM
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Apr 19, 2017
05:31 AM
Not applicable
Apr 20, 2017
12:04 AM
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Apr 20, 2017
12:04 AM
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
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