1 /*
2  * Copyright (C) 2018 Shanghai Eastsoft Microelectronics Co., Ltd.
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  *
6  * Licensed under the Apache License, Version 2.0 (the License); you may
7  * not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  * www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an AS IS BASIS, WITHOUT
14  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *
18  * Change Logs:
19  * Date           Author       Notes
20  * 2019-03-22     wangyq       the first version
21  * 2019-11-01     wangyq        update libraries
22  * 2021-04-20     liuhy         the second version
23  */
24 
25 #include <rthw.h>
26 #include <rtthread.h>
27 #include <rtdevice.h>
28 #include <sys/time.h>
29 #include <string.h>
30 #include "board.h"
31 #include "drv_rtc.h"
32 
33 #ifdef RT_USING_RTC
34 
__rtc_init(rtc_init_t * init)35 static void __rtc_init(rtc_init_t *init)
36 {
37     assert_param(IS_RTC_HOUR_FORMAT(init->hour_format));
38     assert_param(IS_RTC_OUTPUT_SEL(init->output));
39     assert_param(IS_RTC_OUTPUT_POLARITY(init->output_polarity));
40 
41     ald_rtc_reset();
42     RTC_UNLOCK();
43 
44     MODIFY_REG(RTC->CON, RTC_CON_HFM_MSK, init->hour_format << RTC_CON_HFM_POS);
45     MODIFY_REG(RTC->CON, RTC_CON_EOS_MSK, init->output << RTC_CON_EOS_POSS);
46     MODIFY_REG(RTC->CON, RTC_CON_POL_MSK, init->output_polarity << RTC_CON_POL_POS);
47     MODIFY_REG(RTC->PSR, RTC_PSR_SPRS_MSK, init->synch_pre_div << RTC_PSR_SPRS_POSS);
48     MODIFY_REG(RTC->PSR, RTC_PSR_APRS_MSK, init->asynch_pre_div << RTC_PSR_APRS_POSS);
49 
50     RTC_LOCK();
51     return;
52 }
53 
es32f0_rtc_control(rt_device_t dev,int cmd,void * args)54 static rt_err_t es32f0_rtc_control(rt_device_t dev, int cmd, void *args)
55 {
56     rt_err_t result = RT_EOK;
57     struct tm time_temp;
58     rtc_date_t date;
59     rtc_time_t time;
60 
61     switch (cmd)
62     {
63     case RT_DEVICE_CTRL_RTC_GET_TIME:
64 
65         ald_rtc_get_date_time(&date, &time, RTC_FORMAT_DEC);
66         time_temp.tm_sec = time.second;
67         time_temp.tm_min = time.minute;
68         time_temp.tm_hour = time.hour;
69         time_temp.tm_mday = date.day;
70         time_temp.tm_mon = date.month - 1;
71         time_temp.tm_year = date.year - 1900 + 2000;
72         *((time_t *)args) = timegm(&time_temp);
73         break;
74 
75     case RT_DEVICE_CTRL_RTC_SET_TIME:
76         gmtime_r((const time_t *)args, &time_temp);
77         time.hour = time_temp.tm_hour;
78         time.minute = time_temp.tm_min;
79         time.second = time_temp.tm_sec;
80         date.year = time_temp.tm_year + 1900 - 2000;
81         date.month = time_temp.tm_mon + 1;
82         date.day = time_temp.tm_mday;
83         ald_rtc_set_time(&time, RTC_FORMAT_DEC);
84         ald_rtc_set_date(&date, RTC_FORMAT_DEC);
85         /* start RTC */
86         RTC_UNLOCK();
87         SET_BIT(RTC->CON, RTC_CON_GO_MSK);
88         RTC_LOCK();
89         break;
90 
91     case RT_DEVICE_CTRL_RTC_GET_ALARM:
92         break;
93 
94     case RT_DEVICE_CTRL_RTC_SET_ALARM:
95         break;
96 
97     default:
98         break;
99     }
100 
101     return result;
102 }
103 
104 #ifdef RT_USING_DEVICE_OPS
105 const static struct rt_device_ops es32f0_rtc_ops =
106 {
107     RT_NULL,
108     RT_NULL,
109     RT_NULL,
110     RT_NULL,
111     RT_NULL,
112     es32f0_rtc_control
113 };
114 #endif
115 
rt_hw_rtc_init(void)116 int rt_hw_rtc_init(void)
117 {
118     rt_err_t ret = RT_EOK;
119     static struct rt_device rtc_dev;
120     rtc_init_t rtc_initstruct;
121 
122     /* enable clk */
123     ald_rtc_source_select(ES_RTC_CLK_SOURCE);
124 
125     if(ES_RTC_CLK_SOURCE == ES_C_RTC_SOURCE_LOSC)
126     {
127         CMU_LOSC_ENABLE();
128         ald_cmu_losc_safe_config(ENABLE);
129     }
130 
131     /* set default time */
132     RTC_UNLOCK();
133     WRITE_REG(RTC->TIME, 0x134251);
134     WRITE_REG(RTC->DATE, 0x1190401);
135     RTC_LOCK();
136 
137     /* RTC function initialization */
138     rtc_initstruct.hour_format = RTC_HOUR_FORMAT_24;
139     rtc_initstruct.asynch_pre_div = 0;
140     rtc_initstruct.synch_pre_div = 32767;
141     rtc_initstruct.output = RTC_OUTPUT_DISABLE;
142     rtc_initstruct.output_polarity = RTC_OUTPUT_POLARITY_HIGH;
143     __rtc_init(&rtc_initstruct);
144 
145     rtc_dev.type = RT_Device_Class_RTC;
146     rtc_dev.rx_indicate = RT_NULL;
147     rtc_dev.tx_complete = RT_NULL;
148 
149 #ifdef RT_USING_DEVICE_OPS
150     rtc_dev.ops = &es32f0_rtc_ops;
151 #else
152     rtc_dev.init = RT_NULL;
153     rtc_dev.open = RT_NULL;
154     rtc_dev.close = RT_NULL;
155     rtc_dev.read = RT_NULL;
156     rtc_dev.write = RT_NULL;
157     rtc_dev.control = es32f0_rtc_control;
158 #endif
159 
160     rtc_dev.user_data = RTC;
161 
162     ret = rt_device_register(&rtc_dev, ES_DEVICE_NAME_RTC, RT_DEVICE_FLAG_RDWR);
163 
164     return ret;
165 }
166 INIT_DEVICE_EXPORT(rt_hw_rtc_init);
167 
168 #endif
169