feat: (devfs) a new filesystem for device exposure.
[lunaix-os.git] / lunaix-os / kernel / time / clock.c
1 #include <hal/rtc.h>
2 #include <lunaix/clock.h>
3 #include <lunaix/spike.h>
4 #include <lunaix/timer.h>
5
6 static volatile time_t sys_time;
7
8 void
9 clock_systime_counter(void* arg);
10
11 void
12 clock_init()
13 {
14     if (!timer_context()) {
15         panick("Systimer not initialized");
16     }
17
18     // 系统计时器每毫秒累加。
19     timer_run_ms(1, clock_systime_counter, NULL, TIMER_MODE_PERIODIC);
20 }
21
22 void
23 clock_systime_counter(void* arg)
24 {
25     sys_time++;
26 }
27
28 int
29 clock_datatime_eq(datetime_t* a, datetime_t* b)
30 {
31     return a->year == b->year && a->month == b->month && a->day == b->day &&
32            a->weekday == b->weekday && a->minute == b->minute &&
33            a->second == b->second;
34 }
35
36 void
37 clock_walltime(datetime_t* datetime)
38 {
39     datetime_t current;
40
41     do {
42         while (rtc_read_reg(RTC_REG_A) & 0x80)
43             ;
44         memcpy(&current, datetime, sizeof(datetime_t));
45
46         datetime->year = rtc_read_reg(RTC_REG_YRS);
47         datetime->month = rtc_read_reg(RTC_REG_MTH);
48         datetime->day = rtc_read_reg(RTC_REG_DAY);
49         datetime->weekday = rtc_read_reg(RTC_REG_WDY);
50         datetime->hour = rtc_read_reg(RTC_REG_HRS);
51         datetime->minute = rtc_read_reg(RTC_REG_MIN);
52         datetime->second = rtc_read_reg(RTC_REG_SEC);
53     } while (!clock_datatime_eq(datetime, &current));
54
55     uint8_t regbv = rtc_read_reg(RTC_REG_B);
56
57     // Convert from bcd to binary when needed
58     if (!RTC_BIN_ENCODED(regbv)) {
59         datetime->year = bcd2dec(datetime->year);
60         datetime->month = bcd2dec(datetime->month);
61         datetime->day = bcd2dec(datetime->day);
62         datetime->hour = bcd2dec(datetime->hour);
63         datetime->minute = bcd2dec(datetime->minute);
64         datetime->second = bcd2dec(datetime->second);
65     }
66
67     // To 24 hour format
68     if (!RTC_24HRS_ENCODED(regbv) && (datetime->hour >> 7)) {
69         datetime->hour = (12 + datetime->hour & 0x80);
70     }
71
72     datetime->year += RTC_CURRENT_CENTRY * 100;
73 }
74
75 time_t
76 clock_unixtime()
77 {
78     datetime_t dt;
79     clock_walltime(&dt);
80     return clock_tounixtime(&dt);
81 }
82
83 time_t
84 clock_systime()
85 {
86     return sys_time;
87 }