-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathdelays.c
44 lines (39 loc) · 1.37 KB
/
delays.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
#include "gpio.h"
#define SYSTMR_LO ((volatile unsigned int*)(MMIO_BASE+0x00003004))
#define SYSTMR_HI ((volatile unsigned int*)(MMIO_BASE+0x00003008))
// Wait N CPU cycles (ARM CPU only)
void wait_cycles(unsigned int n) {
if(n) while(n--) { asm volatile("nop"); }
}
// Wait N microsec (ARM CPU only)
void wait_msec(unsigned int n) {
register unsigned long f, t, r;
// get the current counter frequency
asm volatile ("mrs %0, cntfrq_el0" : "=r"(f));
// read the current counter
asm volatile ("mrs %0, cntpct_el0" : "=r"(t));
// calculate expire value for counter
t+=((f/1000)*n)/1000;
do{asm volatile ("mrs %0, cntpct_el0" : "=r"(r));}while(r<t);
}
// Get System Timer's counter
unsigned long get_system_timer() {
unsigned int h=-1, l;
// [must] read MMIO area as two separate 32 bit reads
h=*SYSTMR_HI;
l=*SYSTMR_LO;
// [must] repeat it if high word changed during read
if(h!=*SYSTMR_HI) {
h=*SYSTMR_HI;
l=*SYSTMR_LO;
}
// compose long int value
return ((unsigned long) h << 32) | l;
}
// Wait N microsec (with BCM System Timer)
void wait_msec_st(unsigned int n) {
unsigned long t=get_system_timer();
// we must check if it's non-zero, because qemu does not emulate
// system timer, and returning constant zero would mean infinite loop
if(t) while(get_system_timer() < t+n);
}