fix dependency check logic cause config always disabled
[lunaix-os.git] / lunaix-os / hal / timer / timer_device.c
1 #include <lunaix/spike.h>
2 #include <lunaix/time.h>
3
4 #include <hal/hwtimer.h>
5
6 const struct hwtimer_pot* systimer = NULL;
7
8 static struct device_alias* timer_alias;
9 static DEFINE_LLIST(timer_devices);
10
11 ticks_t
12 hwtimer_current_systicks()
13 {
14     assert(systimer);
15     return systimer->systick_raw;
16 }
17
18 ticks_t
19 hwtimer_to_ticks(u32_t value, int unit)
20 {
21     assert(systimer);
22
23     // in case system frequency is less than 1000Hz
24     if (unit != TIME_MS) {
25         return systimer->running_freq * unit * value;
26     }
27
28     ticks_t freq_ms = systimer->running_freq / 1000;
29
30     return freq_ms * value;
31 }
32
33 static struct hwtimer_pot*
34 __select_timer()
35 {
36     struct hwtimer_pot *pos, *n, *sel = NULL;
37
38     llist_for_each(pos, n, &timer_devices, timers)
39     {
40         if (unlikely(!sel)) {
41             sel = pos;
42             continue;
43         }
44
45         if (sel->precedence < pos->precedence) {
46             sel = pos;
47         }
48     }
49
50     return sel;
51 }
52
53 void
54 hwtimer_init(u32_t hertz, void* tick_callback)
55 {
56     struct hwtimer_pot* selected;
57     struct device* time_dev;
58
59     selected = __select_timer();
60
61     assert(selected);
62     systimer = selected;
63
64     selected->callback = tick_callback;
65     selected->running_freq = hertz;
66
67     selected->ops->calibrate(selected, hertz);
68
69     time_dev = potens_dev(selected);
70     timer_alias = device_addalias(NULL, dev_meta(time_dev), "timer");
71 }
72
73
74 struct hwtimer_pot*
75 hwtimer_attach_potens(struct device* dev, int precedence, 
76                       struct hwtimer_pot_ops* ops)
77 {
78     struct hwtimer_pot* hwpot;
79     struct potens_meta* pot;
80
81     if (!potens_check_unique(dev, potens(HWTIMER)))
82     {
83         return NULL;
84     }
85
86     hwpot = new_potens(potens(HWTIMER), struct hwtimer_pot);
87     hwpot->ops = ops;
88     hwpot->precedence = precedence;
89     
90     device_grant_potens(dev, potens_meta(hwpot));
91
92     llist_append(&timer_devices, &hwpot->timers);
93
94     return hwpot;
95 }