We are running a survey to help us improve the experience for all of our members. If you see the survey appear, please take the time to tell us about your experience if you can.
Hi,
I'm using NXP imx6ul-evk(single core cortex-a7 processor) and I'm trying to operate CPU at different frequencies(642MHz, 480MHz, 100MHz, 12MHz) and experiencing time drift on certain frequencies (Generic Timer's time lags Real Time), I'm using virtual timer. I've certain confusions which are following:
* Which clock is going to Generic timer,Why it has range, as I read it operates in range [1-50 MHz], if so then what is its relation with system's core clock which has range up to 696 MHz?
* On system side I've three memory mapped system_counter block (SYSTEM_COUNTER_CTRL = CNTControlBase), SYSTEM_COUNTER_CMP and (SYSTEM_COUNTER_RD = CNTReadBase).
* I consider the timer clock rate 8000000 Hz, load 80000 in CNTV_TVAL and it gives me 10 ms interval but changing the system frequency cause time drift?
I think only I can answer this question on planet , using timer cause this drift because we load timer with some value like 80000, and it counts down to zero generate interrupt and disable itself but servicing this interrupt take some time like 1ms or on lower frequencies(12MHz) up 20 ms which couldn't be figure out, so the other method.
Use compare register(cntv_cval) and counter(cntvct), read initial value of counter(Read Only) add your desire ticks like(80000) for 10ms and enable the timer from control register(cntv_ctl). every time when interrupt occurs, add 80000 in the previous value (don't read the fresh value because it can contain drift just give it 10ms slice and let the timer figure it out itself) and enable the time again from the control register. You've to use inline assembly instruction (like mrrc and mcrr). Enjoy drift proof timer.
sajjad,
To answer your other questions:
The clock going to the Generic Timer is some kind of counter source out in the system. It has little to no bearing on core frequency, in fact it absolutely must count at an absolutely constant 'rate' - the drift you experience is usually the time taken to service the interrupt, which the Generic Timer deals with by treating the TimerView of the counter as a signed value (therefore it shows how many ticks in the negative you are..). While it is possible that you could measure actual system counter drift, it is probably swamped by other factors.
On the i.MX6UL it seems the "System Counter" you're referencing is that Counter Module from Martin's post. It's probably not a good idea to actually use the memory-mapped system counter if you are able to use the system register interface. What that counter is doing is offering a programmable interface which controls up to 64 bits of counter value - either natural binary or greycoded to get around the system. The Generic Timer doesn't actually keep time, nor can you disable the counter from counting - the Generic Timer enable has no effect on the Counter Module. It is just two comparators against an input value, provided by that counter module, and the enable is simply whether the comparators would create an event.
Would it not be better to do:
time_to_event = 10ms - cntv_tval
cntv_tval = time_to_event
and use the TimerValue view of the timer? It seems like a lot less work..
If the time taken to countdown the same specific TVAL changes on CPU clock speed then NXP have broken the system counter (or given it the wrong clock root.. cross your fingers that it is configurable!)
Ta,
Matt
Thanks Matt, I used the same flow as you mentioned.
thanks, helpful. We are using 528MHz imx6ul on MYS-6ULX board.