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