1 /*
2 * Copyright (c) 2006-2023, RT-Thread Development Team
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 *
6 * Change Logs:
7 * Date Author Notes
8 * 2024-01-13 ChuShicheng first version
9 */
10
11 #include "board.h"
12 #include <rtdevice.h>
13 #include "hardware/rtc.h"
14 #include "pico/util/datetime.h"
15
16 #define DBG_LEVEL DBG_LOG
17 #include <rtdbg.h>
18 #define LOG_TAG "DRV.RTC"
19
20 struct rtc_device_object
21 {
22 rt_rtc_dev_t rtc_dev;
23 };
24
25 static struct rtc_device_object rtc_device;
26
pico_rtc_get_timeval(struct timeval * tv)27 static rt_err_t pico_rtc_get_timeval(struct timeval *tv)
28 {
29 datetime_t t;
30 struct tm tm_new = {0};
31 rtc_get_datetime(&t);
32
33 tm_new.tm_sec = t.sec;
34 tm_new.tm_min = t.min;
35 tm_new.tm_hour = t.hour;
36 tm_new.tm_wday = t.dotw;
37 tm_new.tm_mday = t.day;
38 tm_new.tm_mon = t.month - 1;
39 tm_new.tm_year = t.year - 1900;
40
41 tv->tv_sec = timegm(&tm_new);
42
43 return RT_EOK;
44 }
45
pico_rtc_init(void)46 static rt_err_t pico_rtc_init(void)
47 {
48 rtc_init();
49
50 datetime_t t;
51 t.sec = 0 ;
52 t.min = 0;
53 t.hour = 0;
54 t.day = 01;
55 t.month = 01;
56 t.year = 1970;
57 t.dotw = 4;
58 rtc_set_datetime(&t);
59
60 return RT_EOK;
61 }
62
pico_rtc_get_secs(time_t * sec)63 static rt_err_t pico_rtc_get_secs(time_t *sec)
64 {
65 struct timeval tv;
66
67 pico_rtc_get_timeval(&tv);
68 *(time_t *) sec = tv.tv_sec;
69 LOG_D("RTC: get rtc_time %d", *sec);
70
71 return RT_EOK;
72 }
73
pico_rtc_set_secs(time_t * sec)74 static rt_err_t pico_rtc_set_secs(time_t *sec)
75 {
76 rt_err_t result = RT_EOK;
77 datetime_t t;
78 struct tm tm = {0};
79
80 gmtime_r(sec, &tm);
81
82 t.sec = tm.tm_sec ;
83 t.min = tm.tm_min ;
84 t.hour = tm.tm_hour;
85 t.day = tm.tm_mday;
86 t.month = tm.tm_mon + 1;
87 t.year = tm.tm_year + 1900;
88 t.dotw = tm.tm_wday;
89
90 rtc_set_datetime(&t);
91 LOG_D("RTC: set rtc_time");
92 #ifdef RT_USING_ALARM
93 rt_alarm_update(&rtc_device.rtc_dev.parent, 1);
94 #endif
95 return result;
96 }
97
98 static const struct rt_rtc_ops pico_rtc_ops =
99 {
100 pico_rtc_init,
101 pico_rtc_get_secs,
102 pico_rtc_set_secs,
103 RT_NULL,
104 RT_NULL,
105 pico_rtc_get_timeval,
106 RT_NULL,
107 };
108
rt_hw_rtc_init(void)109 static int rt_hw_rtc_init(void)
110 {
111 rt_err_t result;
112
113 rtc_device.rtc_dev.ops = &pico_rtc_ops;
114 result = rt_hw_rtc_register(&rtc_device.rtc_dev, "rtc", RT_DEVICE_FLAG_RDWR, RT_NULL);
115 if (result != RT_EOK)
116 {
117 LOG_E("rtc register err code: %d", result);
118 return result;
119 }
120 LOG_D("rtc init success");
121
122 return RT_EOK;
123 }
124 INIT_DEVICE_EXPORT(rt_hw_rtc_init);
125