Author Topic: How to have correct tick count  (Read 16329 times)

alekmaul (OP)

  • Posts: 330
    • Portabledev
How to have correct tick count
« on: November 25, 2009, 10:17:49 am »
I have a little question regarding tickcount in OS Native dev.
Tell me if someone knows if there are differences calling OSTimeGet or GetTickCount, are they sending us the same value all the time or not ?

Harteex

  • * Administrator
  • Posts: 713
    • Harteex Productions
Re: How to have correct tick count
« Reply #1 on: November 25, 2009, 03:24:37 pm »
OSTimeGet is only giving you the time in the resolution of a hundredth of a second.

GetTickCount seems to give much more digits but I'm unsure if it actually is a higher timer resolution because when simply writing it out it looks a bit odd. The timer made by flatmush uses GetTickCount, but then again, he did leave this comment in main:
// HACK - Fixes timing glitch of unknown origin.

I haven't looked into it so I don't know what this glitch is.

Spiller

  • Posts: 106
Re: How to have correct tick count
« Reply #2 on: November 27, 2009, 08:46:36 am »
The original astrolander source used 64Hz for OSTimeGet and 1MHz for GetTickCount. It took me a while to find out that OSTimeGet is actually running at 100Hz. The 1MHz for GetTickCount seems to be right, even though early forum posts say it runs at 960KHz.

I have seen quite some glitches for GetTickCount. Especially when you guery it quite often, sometimes it returns a smaller value than the last time, resulting in a negative amount of elapsed time.  :P
« Last Edit: November 27, 2009, 08:48:36 am by Spiller »

alekmaul (OP)

  • Posts: 330
    • Portabledev
Re: How to have correct tick count
« Reply #3 on: November 27, 2009, 09:28:19 am »
Thanks for reply Spiller, i have same problem with GetTickCount, that's really strange ...
No so easy to know exactly how to handle it in program ...

flatmush

  • Posts: 288
Re: How to have correct tick count
« Reply #4 on: November 27, 2009, 11:48:12 am »
OSTimeGet gives you the tick in timeslices (each timeslice is roughly 15.625ms).

GetTickCount gives you a tick in microseconds from the cpu timer. I found it inaccurate in AstroLander and you'll see that once in a while the ship speeds up or jerks because of it, not sure if there's an easy way around it other than to guess the rough tick count and compare with the actual tick count (maybe using OSTimeGet), you could then use the predicted tick count for times when GetTickCount fails which would be smoother than just ignoring the glitches.

alekmaul (OP)

  • Posts: 330
    • Portabledev
Re: How to have correct tick count
« Reply #5 on: November 27, 2009, 12:22:34 pm »
Thanks for your help flatmush (and nice to see you again in this forum ^^).
I think i will use your idea of predicted tick count regarding the last one that was good.

flatmush

  • Posts: 288
Re: How to have correct tick count
« Reply #6 on: November 27, 2009, 01:07:13 pm »
Yeah, it's good to be back though still not much time to do stuff :(

Ah I remember one thing about the tick inaccuracy. The tickrate is generally only inaccurate when you yield timeslices to the OS using OSTimeDly, it seems that something in the operating system resets the cpu tick register for some reason, you could call GetTickCount before and after OSTimeDly, and if the tick value after is corrupt then just assume (15.625ms * delay) has passed.

alekmaul (OP)

  • Posts: 330
    • Portabledev
Re: How to have correct tick count
« Reply #7 on: November 27, 2009, 02:18:23 pm »
I'm not using TimeDly but a loop with things like that :
Quote
i assume i have a delay to do ...
...
start=GetTickCount();
while ((GetTickCount()-start) < delay);
...

flatmush

  • Posts: 288
Re: How to have correct tick count
« Reply #8 on: November 30, 2009, 10:34:34 am »
Ok, I'm starting to have some issues with trying to correct this. So far as I can tell the operating system time functions reset the timer regularly meaning that we can only use one or the other (or use some very complex wrappers to correct). The problem is that the operating system timer is inaccurate and low resolution (maybe not 64, seems like closer to 160 but needs proper testing).

Spiller

  • Posts: 106
Re: How to have correct tick count
« Reply #9 on: December 02, 2009, 08:55:24 pm »
The problem is that the operating system timer is inaccurate and low resolution (maybe not 64, seems like closer to 160 but needs proper testing).

In all the tests I did it is actually running quite stable at 100Hz.

Harteex

  • * Administrator
  • Posts: 713
    • Harteex Productions
Re: How to have correct tick count
« Reply #10 on: December 02, 2009, 09:38:03 pm »
The problem is that the operating system timer is inaccurate and low resolution (maybe not 64, seems like closer to 160 but needs proper testing).

In all the tests I did it is actually running quite stable at 100Hz.


Yes this is what I've seen aswell. It's a little slow though, so unless OSTimeDly also affects OSTimeGet, it's really about 99.9Hz

WAHa.06x36

  • Guest
Re: How to have correct tick count
« Reply #11 on: February 15, 2010, 12:06:09 am »
GetTickCount() is basically useless. What it actually does is return OSTimeGet()*10000 plus the value of a different timer. This other timer only counts to 520 or so, not to 9999 like it should, and it is NOT synchronized with the OSTimeGet() timer, which is why you sometimes have the value decreasing instead of increasing.

Don't bother with GetTickCount() at all, just use OSTimeGet() even though it's a bit crude.

And yes, it runs at 99.9 Hz, or more specifically, 328/32768 Hz.

slaanesh

  • Posts: 569
    • Slaanesh Dev
Re: How to have correct tick count
« Reply #12 on: November 01, 2012, 10:56:51 pm »
I've been playing around with TCU timers. Whilst it's easy enough to get one going, the calculations to determine their tick rate seems incorrect.

For example, using a timer with the RTC CLK as the input:

The RTC is a 32768hz clock.
Even using a prescaler of div1 doesn't seem to yield 32768 ticks in one second.

Code: [Select]
    #define MAX_TICKS   0xffff
    #define TIMER_NBR 5
    __tcu_stop_counter(TIMER_NBR);
    __tcu_set_pwm_output_shutdown_abrupt(TIMER_NBR);
    __tcu_disable_pwm_output(TIMER_NBR);
    __tcu_mask_half_match_irq(TIMER_NBR);
    __tcu_mask_full_match_irq(TIMER_NBR);
    __tcu_select_rtcclk(TIMER_NBR);
    __tcu_select_clk_div1(TIMER_NBR);
    REG_TCU_TDFR(TIMER_NBR) = MAX_TICKS;
    REG_TCU_TDHR(TIMER_NBR) = MAX_TICKS;
    __tcu_set_count(TIMER_NBR, 0);
    __tcu_start_counter(TIMER_NBR);
    __tcu_clear_full_match_flag(TIMER_NBR);

There is a curious addendum in the jz4740 docs:


Quote
Note:
The input clock of timer and the PCLK should keep to the rules as follows:

Input clock of timer: IN_CLK                                                                      Clock generated from the frequency divider (PRESCALE): DIV_CLK
PCK_EN == 0, RTC_EN == 1 and EXT_EN == 0 (IN_CLK = RTCCLK)      fDIV_CLK < ? fPCLK
PCK_EN == 0, RTC_EN == 0 and EXT_EN == 1 (IN_CLK = EXTAL)         fDIV_CLK < ? fPCLK
PCK_EN == 1, RTC_EN == 0 and EXT_EN == 0 (IN_CLK = PCLK)          ANY