00001 00029 #include <stdint.h> 00030 #include <rtc.h> 00031 #include <intc.h> 00032 #include "timer.h" 00033 00034 00035 struct timeout_t { 00036 U32 tick; 00037 U32 expire_at_tick; 00038 Bool expired; 00039 U8 type; 00040 void (*cb)(void* ctx); 00041 void* ctx; 00042 }; 00043 00044 struct timer_t { 00045 volatile U32 tick; 00046 struct timeout_t timeout[8]; 00047 void (*tick_isr) (void* ctx); 00048 const U32 MS_PER_TICK; 00049 void *ctx; 00050 }; 00051 00052 #define ARRAY_SIZE(a) sizeof(a) / sizeof(a[0]) 00053 00054 static __attribute__((__interrupt__)) void irq_handler(void); 00055 00056 static struct timer_t TIMER = { 00057 .tick = 0, 00058 .MS_PER_TICK = TIMER_HZ, 00059 .timeout = { { 0 } }, 00060 }; 00061 00062 void timer_init(void (*tick_isr) (void* ctx), void* ctx) 00063 { 00064 struct timer_t* priv = &TIMER; 00065 uint8_t id; 00066 00067 INTC_register_interrupt(&irq_handler, AVR32_RTC_IRQ, AVR32_INTC_INT0); 00068 if (!rtc_init(&AVR32_RTC, RTC_OSC_RC, 0)) 00069 Assert(0); 00070 00071 priv->tick_isr = tick_isr; 00072 priv->ctx = ctx; 00073 rtc_set_top_value(&AVR32_RTC, 115 * priv->MS_PER_TICK / 2); 00074 rtc_enable_interrupt(&AVR32_RTC); 00075 rtc_enable(&AVR32_RTC); 00076 00077 for (id = 0; id < ARRAY_SIZE(priv->timeout); id++) 00078 priv->timeout[id].expired = TRUE; 00079 } 00080 00081 00082 U32 timer_get_ms(void) 00083 { 00084 struct timer_t* priv = &TIMER; 00085 return priv->tick * priv->MS_PER_TICK; 00086 } 00087 00088 void timer_delay(U32 ms) 00089 { 00090 struct timer_t* priv = &TIMER; 00091 U32 expire_at_tick = priv->tick + ms / priv->MS_PER_TICK; 00092 while (priv->tick < expire_at_tick); 00093 } 00094 00101 void timer_poll(void) 00102 { 00103 struct timer_t* priv = &TIMER; 00104 U8 i; 00105 00106 for (i = 0; i < ARRAY_SIZE(priv->timeout); i++) { 00107 struct timeout_t* tmo = &priv->timeout[i]; 00108 if (tmo->expired) 00109 continue; 00110 00111 if (tmo->expire_at_tick > priv->tick) 00112 continue; 00113 00114 if (tmo->cb) 00115 tmo->cb(tmo->ctx); 00116 00117 if (tmo->type == TIMEOUT_PERIODIC) 00118 tmo->expire_at_tick = priv->tick + tmo->tick; 00119 else 00120 tmo->expired = TRUE; 00121 } 00122 } 00123 00124 static U32 timer_sched_timeout(U32 ms, U8 type) 00125 { 00126 struct timer_t* priv = &TIMER; 00127 struct timeout_t* tmo; 00128 U8 id; 00129 00130 Assert(type == TIMEOUT_ONESHOT || type == TIMEOUT_PERIODIC); 00131 00132 for (id = 0; id < ARRAY_SIZE(priv->timeout); id++) { 00133 tmo = &priv->timeout[id]; 00134 if (tmo->expired) 00135 break; 00136 } 00137 00138 Assert(id != ARRAY_SIZE(priv->timeout)); 00139 00140 tmo->tick = ms / priv->MS_PER_TICK; 00141 tmo->expire_at_tick = priv->tick + tmo->tick; 00142 tmo->type = type; 00143 tmo->expired = FALSE; 00144 return id; 00145 } 00146 00147 U32 timer_sched_timeout_cb(U32 ms, U8 type, void (*cb)(void *ctx), void* ctx) 00148 { 00149 struct timer_t* priv = &TIMER; 00150 struct timeout_t* tmo; 00151 U8 id; 00152 00153 Assert(cb); 00154 id = timer_sched_timeout(ms, type); 00155 tmo = &priv->timeout[id]; 00156 00157 tmo->cb = cb; 00158 tmo->ctx = ctx; 00159 return id; 00160 } 00161 00162 00163 void timer_cancel_timeout(U32 id) 00164 { 00165 struct timer_t* priv = &TIMER; 00166 struct timeout_t* tmo; 00167 00168 tmo = &priv->timeout[id]; 00169 tmo->expired = TRUE; 00170 } 00171 00172 static __attribute__((__interrupt__)) void irq_handler(void) 00173 { 00174 volatile avr32_rtc_t *rtc = &AVR32_RTC; 00175 struct timer_t* priv = &TIMER; 00176 priv->tick++; 00177 00178 if(priv->tick_isr) 00179 priv->tick_isr(priv->ctx); 00180 00181 rtc->icr = AVR32_RTC_ICR_TOPI_MASK; 00182 rtc->isr; 00183 }