1 /*
2 * Copyright (c) 2021-2023 HPMicro
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 *
6 * Change Logs:
7 * Date Author Notes
8 * 2021-09-19 HPMicro First version
9 * 2023-05-08 HPMicro Adapt RT-Thread V5.0.0
10 */
11 #include "board.h"
12 #include "drv_rtc.h"
13 #include "hpm_rtc_drv.h"
14 #include "hpm_bpor_drv.h"
15
16 #include <rtthread.h>
17 #include <rtdevice.h>
18 #include <rtdbg.h>
19
20 #ifdef RT_USING_RTC
21
22 /*******************************************************************************************
23 *
24 * Prototypes
25 *
26 ******************************************************************************************/
27 static rt_err_t hpm_rtc_init(rt_device_t dev);
28 static rt_err_t hpm_rtc_open(rt_device_t dev, rt_uint16_t oflag);
29 static rt_err_t hpm_rtc_close(rt_device_t dev);
30 static rt_ssize_t hpm_rtc_read(rt_device_t dev, rt_off_t pos, void *buf, rt_size_t size);
31 static rt_ssize_t hpm_rtc_write(rt_device_t dev, rt_off_t pos, const void *buf, rt_size_t size);
32 static rt_err_t hpm_rtc_control(rt_device_t dev, int cmd, void *args);
33
34 static time_t hpm_rtc_get_timestamp(void);
35 static int hpm_rtc_set_timestamp(time_t timestamp);
36
37 /*******************************************************************************************
38 *
39 * Variables
40 *
41 ******************************************************************************************/
42 #ifdef RT_USING_DEVICE_OPS
43 const struct rt_device_ops hpm_rtc_ops = {
44 .init = hpm_rtc_init,
45 .open = hpm_rtc_open,
46 .close = hpm_rtc_close,
47 .read = hpm_rtc_read,
48 .write = hpm_rtc_write,
49 .control = hpm_rtc_control,
50 };
51 #endif
52 static struct rt_device hpm_rtc= {
53 .type = RT_Device_Class_RTC,
54 #ifdef RT_USING_DEVICE_OPS
55 .ops = &hpm_rtc_ops,
56 #else
57 .init = hpm_rtc_init,
58 .open = hpm_rtc_open,
59 .close = hpm_rtc_close,
60 .read = hpm_rtc_read,
61 .write = hpm_rtc_write,
62 .control = hpm_rtc_control,
63 #endif
64 };
65
66 /*******************************************************************************************
67 *
68 * Codes
69 *
70 ******************************************************************************************/
hpm_rtc_init(rt_device_t dev)71 static rt_err_t hpm_rtc_init(rt_device_t dev)
72 {
73 /* Enable Power retention mode for the battery domain */
74 bpor_enable_reg_value_retention(HPM_BPOR);
75 return RT_EOK;
76 }
hpm_rtc_open(rt_device_t dev,rt_uint16_t oflag)77 static rt_err_t hpm_rtc_open(rt_device_t dev, rt_uint16_t oflag)
78 {
79 return RT_EOK;
80 }
hpm_rtc_close(rt_device_t dev)81 static rt_err_t hpm_rtc_close(rt_device_t dev)
82 {
83 return RT_EOK;
84 }
hpm_rtc_read(rt_device_t dev,rt_off_t pos,void * buf,rt_size_t size)85 static rt_ssize_t hpm_rtc_read(rt_device_t dev, rt_off_t pos, void *buf, rt_size_t size)
86 {
87 return 0;
88 }
hpm_rtc_write(rt_device_t dev,rt_off_t pos,const void * buf,rt_size_t size)89 static rt_ssize_t hpm_rtc_write(rt_device_t dev, rt_off_t pos, const void *buf, rt_size_t size)
90 {
91 return 0;
92 }
hpm_rtc_control(rt_device_t dev,int cmd,void * args)93 static rt_err_t hpm_rtc_control(rt_device_t dev, int cmd, void *args)
94 {
95 RT_ASSERT(dev != RT_NULL);
96
97 rt_err_t err = RT_EOK;
98
99 switch(cmd) {
100 case RT_DEVICE_CTRL_RTC_GET_TIME:
101 *(uint32_t *)args = hpm_rtc_get_timestamp();
102 break;
103 case RT_DEVICE_CTRL_RTC_SET_TIME:
104 hpm_rtc_set_timestamp(*(time_t *)args);
105 break;
106 default:
107 err = RT_EINVAL;
108 break;
109 }
110
111 return err;
112 }
113
hpm_rtc_get_timestamp(void)114 static time_t hpm_rtc_get_timestamp(void)
115 {
116 time_t time = rtc_get_time(HPM_RTC);
117
118 return time;
119 }
120
hpm_rtc_set_timestamp(time_t timestamp)121 static int hpm_rtc_set_timestamp(time_t timestamp)
122 {
123 (void)rtc_config_time(HPM_RTC, timestamp);
124
125 return RT_EOK;
126 }
127
128
rt_hw_rtc_init(void)129 int rt_hw_rtc_init(void)
130 {
131 rt_err_t err = RT_EOK;
132
133 err = rt_device_register(&hpm_rtc, "rtc", RT_DEVICE_FLAG_RDWR);
134 if (err != RT_EOK) {
135 LOG_E("rt device %s failed, status=%d\n", "rtc", err);
136 return err;
137 }
138
139 rt_device_open(&hpm_rtc, RT_DEVICE_FLAG_RDWR);
140
141 return RT_EOK;
142 }
143
144 INIT_DEVICE_EXPORT(rt_hw_rtc_init);
145
146 #endif /* RT_USING_RTC */
147