Statistics
| Branch: | Revision:

root / prex-0.9.0 / bsp / drv / lib / delay.c @ 03e9c04a

History | View | Annotate | Download (2.78 KB)

1
/*-
2
 * Copyright (c) 2005-2007, Kohsuke Ohtani
3
 * All rights reserved.
4
 *
5
 * Redistribution and use in source and binary forms, with or without
6
 * modification, are permitted provided that the following conditions
7
 * are met:
8
 * 1. Redistributions of source code must retain the above copyright
9
 *    notice, this list of conditions and the following disclaimer.
10
 * 2. Redistributions in binary form must reproduce the above copyright
11
 *    notice, this list of conditions and the following disclaimer in the
12
 *    documentation and/or other materials provided with the distribution.
13
 * 3. Neither the name of the author nor the names of any co-contributors
14
 *    may be used to endorse or promote products derived from this software
15
 *    without specific prior written permission.
16
 *
17
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27
 * SUCH DAMAGE.
28
 */
29

    
30
/*
31
 * delay.c - driver delay routine
32
 */
33

    
34
#include <driver.h>
35

    
36
#ifdef DEBUG
37
#define DPRINTF(a) printf a
38
#else
39
#define DPRINTF(a)
40
#endif
41

    
42
static u_long delay_count;        /* Loop count for 1ms */
43

    
44
static
45
void delay_loop(u_long count)
46
{
47
        volatile u_long i;
48

    
49
        for (i = 0; i < count; i++);
50
}
51

    
52
/*
53
 * Delay micro seconds (non-blocking)
54
 * timer_udelay() can be called from ISR at interrupt level.
55
 */
56
void
57
delay_usec(u_long usec)
58
{
59

    
60
        delay_loop(delay_count * usec / 1000);
61
}
62

    
63
/*
64
 * Compute the loop count for 1ms.
65
 * Assumes clock interrupt is enabled.
66
 */
67
void
68
calibrate_delay(void)
69
{
70
        u_long ticks, test_bit;
71

    
72
        DPRINTF(("Calibrating delay loop... "));
73
        delay_count = 1;
74
        for (;;) {
75
                delay_count <<= 1;
76

    
77
                ticks = timer_ticks();
78
                while (ticks == timer_ticks());
79

    
80
                ticks = timer_ticks();
81
                delay_loop(delay_count);
82
                if (ticks != timer_ticks())
83
                        break;
84
        }
85
        delay_count >>= 1;
86
        test_bit = delay_count;
87

    
88
        for (;;) {
89
                test_bit >>= 1;
90
                if (test_bit == 0)
91
                        break;
92
                delay_count |= test_bit;
93

    
94
                ticks = timer_ticks();
95
                while (ticks == timer_ticks());
96

    
97
                ticks = timer_ticks();
98
                delay_loop(delay_count);
99
                if (ticks != timer_ticks())
100
                        delay_count &= ~test_bit;
101
        }
102
        delay_count *= 1000;        /* count per 1sec */
103
        delay_count /= 1000;        /* count per 1ms */
104
        DPRINTF(("ok count=%ld\n", delay_count));
105
}