1 /*
2  * Copyright (c) 2006-2022, RT-Thread Development Team
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  *
6  * Change Logs:
7  * Date           Author       Notes
8  * 2021-11-17     JasonHu      first version
9  */
10 
11 #include <rthw.h>
12 #include <rtthread.h>
13 #include <rtdevice.h>
14 #include <string.h>
15 #include <time.h>
16 #include <rtdbg.h>
17 
18 #include <sunxi_hal_rtc.h>
19 
20 #ifdef RT_USING_RTC
21 
rtc_init(struct rt_device * dev)22 static rt_err_t rtc_init(struct rt_device *dev)
23 {
24     if (hal_rtc_init() != 0)
25     {
26         LOG_E("init rtc hal failed!");
27         return -RT_ERROR;
28     }
29     return RT_EOK;
30 }
31 
rtc_control(rt_device_t dev,int cmd,void * args)32 static rt_err_t rtc_control(rt_device_t dev, int cmd, void *args)
33 {
34     rt_err_t result = RT_EOK;
35     struct tm time_temp;
36     struct tm *time_now;
37     struct rtc_time hal_rtc_time;
38     switch (cmd)
39     {
40     case RT_DEVICE_CTRL_RTC_GET_TIME:
41 
42         if (hal_rtc_gettime(&hal_rtc_time) != 0)
43         {
44             LOG_E("rtc gettime failed!\n");
45             return -RT_ERROR;
46         }
47 
48         time_temp.tm_sec = hal_rtc_time.tm_sec;
49         time_temp.tm_min = hal_rtc_time.tm_min;
50         time_temp.tm_hour = hal_rtc_time.tm_hour;
51         time_temp.tm_mday = hal_rtc_time.tm_mday;
52         time_temp.tm_mon = hal_rtc_time.tm_mon;
53         time_temp.tm_year = hal_rtc_time.tm_year;
54 
55         *((time_t *)args) = mktime(&time_temp);
56         break;
57     case RT_DEVICE_CTRL_RTC_SET_TIME:
58 
59         rt_enter_critical();
60         /* converts calendar time time into local time. */
61         time_now = localtime((const time_t *)args);
62         /* copy the statically located variable */
63         memcpy(&time_temp, time_now, sizeof(struct tm));
64         /* unlock scheduler. */
65         rt_exit_critical();
66 
67         hal_rtc_time.tm_sec = time_temp.tm_sec;
68         hal_rtc_time.tm_min = time_temp.tm_min;
69         hal_rtc_time.tm_hour = time_temp.tm_hour;
70         hal_rtc_time.tm_mday = time_temp.tm_mday;
71         hal_rtc_time.tm_mon = time_temp.tm_mon;
72         hal_rtc_time.tm_year = time_temp.tm_year;
73         if (hal_rtc_settime(&hal_rtc_time) != 0)
74         {
75             LOG_E("rtc settime failed!\n");
76             return -RT_ERROR;
77         }
78         break;
79     default:
80         return -RT_EINVAL;
81     }
82 
83     return result;
84 }
85 
86 #ifdef RT_USING_DEVICE_OPS
87 const static struct rt_device_ops rt_hw_rtc_ops =
88 {
89     rtc_init,
90     RT_NULL,
91     RT_NULL,
92     RT_NULL,
93     RT_NULL,
94     rtc_control
95 };
96 #endif
97 
rt_hw_rtc_init(void)98 int rt_hw_rtc_init(void)
99 {
100     rt_err_t ret = RT_EOK;
101     static struct rt_device rtc_dev;
102 
103     rtc_dev.type = RT_Device_Class_RTC;
104     rtc_dev.rx_indicate = RT_NULL;
105     rtc_dev.tx_complete = RT_NULL;
106 
107 #ifdef RT_USING_DEVICE_OPS
108     rtc_dev.ops = &rt_hw_rtc_ops;
109 #else
110     rtc_dev.init = rtc_init;
111     rtc_dev.open = RT_NULL;
112     rtc_dev.close = RT_NULL;
113     rtc_dev.read = RT_NULL;
114     rtc_dev.write = RT_NULL;
115     rtc_dev.control = rtc_control;
116 #endif
117 
118     rtc_dev.user_data = RT_NULL;
119 
120 #ifdef BSP_USING_RTC
121     ret = rt_device_register(&rtc_dev, "rtc", RT_DEVICE_FLAG_RDWR);
122 #endif
123 
124     return ret;
125 }
126 INIT_DEVICE_EXPORT(rt_hw_rtc_init);
127 
128 #endif
129