Initial cut of the open ath9k htc firmware.
[open-ath9k-htc-firmware.git] / target_firmware / magpie_fw_dev / build / magpie_1_1 / sboot / cmnos / timer / src / cmnos_timer.c
1
2 #include "sys_cfg.h"
3 #include "athos_api.h"
4
5 #if SYSTEM_MODULE_TIMER
6
7 //#define TIMER_NOT_IN_USE ((cmnos_timer_t *)-1)
8 #define TIMER_NOT_IN_USE NULL
9
10 /* convert milliseconds to ticks */
11 #define MILLIS_TO_TIMER_TICKS(ms)       (ms*ONE_MSEC)   
12
13 /* Current tick time */
14 //#define NOW()                             xthal_get_ccount()
15
16 #define TIMER_IS_EARLIER(t1, t2)          ((A_INT32)((A_UINT32)t1-(A_UINT32)t2)<=0)
17
18
19 typedef struct cmnos_timer_s {
20     struct cmnos_timer_s    *timer_next;
21     A_UINT32                 timer_expire;
22     A_UINT32                 timer_period;
23     A_TIMER_FUNC            *timer_function;
24     void                    *timer_arg;
25 } cmnos_timer_t; /*  A_timer_t */
26
27 LOCAL cmnos_timer_t *timer_list = NULL;
28
29
30 /* Initialize a timer. Initially, it is unarmed. */
31 LOCAL void
32 cmnos_timer_setfn(A_timer_t *A_timer, A_TIMER_FUNC *pfunction, void *parg)
33 {
34     cmnos_timer_t *ptimer = (cmnos_timer_t *)A_timer;
35
36     ptimer->timer_next = TIMER_NOT_IN_USE;
37     ptimer->timer_expire = 0; /* sanity */
38     ptimer->timer_function = pfunction;
39     ptimer->timer_arg = parg;
40 }
41
42 /* Arm a timer to trigger after the specified time */
43 LOCAL void
44 cmnos_timer_arm(A_timer_t *A_timer,
45                 unsigned int milliseconds)
46 {
47     cmnos_timer_t *ptimer = (cmnos_timer_t *)A_timer;
48     A_UINT32 timer_expire;
49     A_UINT32 timer_ticks;
50     cmnos_timer_t *curr, *prev = NULL;
51
52     /* Convert milliseconds to ticks */
53     timer_ticks = MILLIS_TO_TIMER_TICKS(milliseconds);
54     
55     /* Calculate expiring tick time */
56     timer_expire = NOW() + timer_ticks;
57     
58     /* Find the right place to insert */
59     for (curr = timer_list;
60          curr;
61          prev=curr, curr = curr->timer_next)
62     {
63         if (TIMER_IS_EARLIER(timer_expire, curr->timer_expire))
64             break;
65     }
66
67     /* Inster timer to the list */
68     ptimer->timer_next = curr;
69     ptimer->timer_expire = timer_expire;
70     if (prev) {
71         prev->timer_next = ptimer;
72     } else {
73         /* Insert at head of the timer list */
74         timer_list = ptimer;
75     }
76     
77     return;
78 }
79
80 /* Disarm a timer, if it is currently armed. */
81 LOCAL void
82 cmnos_timer_disarm(A_timer_t *A_timer)
83 {
84     cmnos_timer_t *ptimer = (cmnos_timer_t *)A_timer;
85     cmnos_timer_t *curr, *prev = NULL;
86     
87     /* Find desired timer */
88     for (curr = timer_list;
89          curr;
90          prev=curr, curr = curr->timer_next)
91     {
92         if (ptimer == curr) {
93             break;
94         }
95     }
96
97     /* Remove it from the timer list */
98     if (curr) {
99         if (prev) {
100             prev->timer_next = curr->timer_next;
101         } else {
102             timer_list = curr->timer_next;
103         }
104     }
105
106     /* Clear timer parameters */
107     ptimer->timer_next = TIMER_NOT_IN_USE;
108     ptimer->timer_period = 0;
109 }
110
111 /* Initialize timer software.  Called once during initialization. */
112 LOCAL void
113 cmnos_timer_init(void)
114 {
115     timer_list = NULL;
116 }
117
118 /* Handler for LF0 Timer. */
119 LOCAL void
120 cmnos_timer_handler(void)
121 {
122     cmnos_timer_t *ptimer;
123
124     while (timer_list &&
125            TIMER_IS_EARLIER(timer_list->timer_expire, NOW()))
126     {
127         ptimer = timer_list;
128         timer_list = timer_list->timer_next;
129         ptimer->timer_next = TIMER_NOT_IN_USE;
130         ptimer->timer_function((A_HANDLE)ptimer, ptimer->timer_arg);
131     }
132     return;
133 }
134
135 void
136 cmnos_timer_module_install(struct timer_api *tbl)
137 {
138     tbl->_timer_init         = cmnos_timer_init;
139     tbl->_timer_arm          = cmnos_timer_arm;
140     tbl->_timer_disarm       = cmnos_timer_disarm;
141     tbl->_timer_setfn        = cmnos_timer_setfn;
142     tbl->_timer_run          = cmnos_timer_handler;
143 }
144
145 //#define CMNOS_TIMER_UT
146 #ifdef CMNOS_TIMER_UT
147
148 #include <adf_os_timer.h>
149
150 adf_os_timer_t timer1;
151 adf_os_timer_t timer2;
152
153 void test_timer(void *arg)
154 {
155     adf_os_timer_t *tmp = (adf_os_timer_t *) arg;
156     
157     if ( tmp == &timer1 ) {
158         adf_os_print("Timer1 is fired\n");
159         adf_os_timer_start(&timer1, 1000);
160     } else {
161         adf_os_print("Timer2 is fired\n");
162         adf_os_timer_start(&timer2, 3000);        
163     }
164 }
165
166 void 
167 cmnos_timer_test()
168 {
169     adf_os_timer_init(NULL, &timer1, test_timer, &timer1);
170     adf_os_timer_init(NULL, &timer2, test_timer, &timer2);
171     adf_os_timer_start(&timer1, 1000);
172     adf_os_timer_start(&timer2, 3000);    
173 }
174
175 #endif
176
177 #endif /* end SYSTEM_MODULE_TIMER */
178