Highspeed Timer(Counter)


notaz said:
here's the code that I use in PicoDrive:
It works perfectly, I finally get real accurate 60fps! Thank you very much for sharing this Notaz :)
 
Last edited by a moderator:
notaz said:
oh BTW 'memregl' is standard
Code:
volatile unsigned int *memregl;
memregl = mmap(0, 0x20000, PROT_READ|PROT_WRITE, MAP_SHARED, memdev, 0xc0000000);

I'm getting
Code:
'memdev' was not declared in this scope
Is there some header I forgot to include?
 
Last edited by a moderator:
Jan-Nik said:
notaz said:
oh BTW 'memregl' is standard
Code:
 volatile unsigned int *memregl;
 memregl = mmap(0, 0x20000, PROT_READ|PROT_WRITE, MAP_SHARED, memdev, 0xc0000000);

I'm getting
Code:
'memdev' was not declared in this scope
Is there some header I forgot to include?

I believe you need this
Code:
    /* open /dev/mem to access registers */
    memdev = open("/dev/mem", O_RDWR);
    if(memdev < 0) {
        printf("Could not open /dev/mem\n");
        return -1;
    }
 
Last edited by a moderator:
How would I handle the "wrap after an hour" correctly? See if the value was less than last time, and if so, add the last-time value, too?
 
Why would anything wrap after an hour specifically? If the timer in question is 32bits then use 32bit arithmetic when comparing time A and time B, and the wrapping will be taken care of.
 
the function is calle "_get_ticks_us", but "us" us used for nano (1/1000 of milli). Is the return value milli or nano seconds now?
 
us means microsecond, not nanosecond. Well, everything notaz said about it is true of course, it'll last somewhat more than an hour before it wraps. But like I said, so long as you keep arithmetic 32bits then you'll have no problem tracking spans so long as the spans themselves are under 4295 seconds. Let me show what you mean:

Say when you get the first time it's at 0xFFFFFFF0. Then the second time it's at 0x00000003. If you subtract the first from the second then what you get is 0x13, exactly what you expect. This is because the part that wrapped around also wraps off the edge of your subtraction. You only have to worry if the timer is less than 32bits, in which case you have to mask off the result bits yourself.

If you need to see if more than 4295 seconds have passed then yes, you can see if the new one is smaller than the old one. But you won't know how many times it has wrapped around. I can't imagine that you will need intervals higher than 4295 but smaller than twice that. You probably only need pretty small intervals.
 
You could mess it up if you wait for some timestamp, for though:

Code:
wait_until = get_ticks_us() + 16666;
draw_frame();
while (get_ticks_us() < wait_until)
  usleep(1000); // sleep on Wiz is a bad idea, this is just for illustration

So let's say wait_until ends up being 0xFFFFFFF0, but you return from draw_frame() at 0x00000003 and you are screwed.
 
Are Linux hrtimers (used with clock_gettime/clock_nanosleep etc.) not available on Wiz? They are in the Linux kernel since 2.6.21 if I remember correctly.

I did some tests back then on PC, and got very promising results - sleeping and wakeup with 0.4ms worst case error, as opposed to 10ms worst case error without hrtimers... (average error was 0.04ms vs 6ms).

Also clock_nanosleep seems to do a blocking sleep, so no busy-waiting...


Edit:
Maybe someone wants to try this: http://elinux.org/High_Resolution_Timers#How_to_detect_if_your_timer_system_supports_high_resolution

Edit 2:
I now own a Wiz myself :)
Code:
root@wiz:/proc# cat timer_list 
Timer List Version: v0.3
HRTIMER_MAX_CLOCK_BASES: 2
now at 106338437000 nsecs

cpu: 0
 clock 0:
  .index:      0
  .resolution: 10000000 nsecs
  .get_time:   ktime_get_real
active timers:
 clock 1:
  .index:      1
  .resolution: 10000000 nsecs
  .get_time:   ktime_get
active timers:
 #0: <c1ec9eb0>, hrtimer_wakeup, S:01
 # expires at 106337856000 nsecs [in 18446744073708970616 nsecs]
 #1: <c1ec9eb0>, hrtimer_wakeup, S:01
 # expires at 106338864000 nsecs [in 427000 nsecs]
 
Back
Top