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 
38     assert_param(IS_RTC_HOUR_FORMAT(init->hour_format));
39     assert_param(IS_RTC_OUTPUT_SEL(init->output));
40     assert_param(IS_RTC_OUTPUT_POLARITY(init->output_polarity));
41 
42     ald_rtc_reset();
43     RTC_UNLOCK();
44 
45     MODIFY_REG(RTC->CON, RTC_CON_HFM_MSK, init->hour_format << RTC_CON_HFM_POS);
46     MODIFY_REG(RTC->CON, RTC_CON_EOS_MSK, init->output << RTC_CON_EOS_POSS);
47     MODIFY_REG(RTC->CON, RTC_CON_POL_MSK, init->output_polarity << RTC_CON_POL_POS);
48     MODIFY_REG(RTC->PSR, RTC_PSR_SPRS_MSK, init->synch_pre_div << RTC_PSR_SPRS_POSS);
49     MODIFY_REG(RTC->PSR, RTC_PSR_APRS_MSK, init->asynch_pre_div << RTC_PSR_APRS_POSS);
50 
51     RTC_LOCK();
52     return;
53 }
54 
es32f0_rtc_control(rt_device_t dev,int cmd,void * args)55 static rt_err_t es32f0_rtc_control(rt_device_t dev, int cmd, void *args)
56 {
57     rt_err_t result = RT_EOK;
58     struct tm time_temp;
59     rtc_date_t date;
60     rtc_time_t time;
61 
62     switch (cmd)
63     {
64     case RT_DEVICE_CTRL_RTC_GET_TIME:
65 
66         ald_rtc_get_date_time(&date, &time, RTC_FORMAT_DEC);
67         time_temp.tm_sec = time.second;
68         time_temp.tm_min = time.minute;
69         time_temp.tm_hour = time.hour;
70         time_temp.tm_mday = date.day;
71         time_temp.tm_mon = date.month - 1;
72         time_temp.tm_year = date.year - 1900 + 2000;
73         *((time_t *)args) = timegm(&time_temp);
74         break;
75 
76     case RT_DEVICE_CTRL_RTC_SET_TIME:
77         gmtime_r((const time_t *)args, &time_temp);
78         time.hour = time_temp.tm_hour;
79         time.minute = time_temp.tm_min;
80         time.second = time_temp.tm_sec;
81         date.year = time_temp.tm_year + 1900 - 2000;
82         date.month = time_temp.tm_mon + 1;
83         date.day = time_temp.tm_mday;
84         ald_rtc_set_time(&time, RTC_FORMAT_DEC);
85         ald_rtc_set_date(&date, RTC_FORMAT_DEC);
86         /* start RTC */
87         RTC_UNLOCK();
88         SET_BIT(RTC->CON, RTC_CON_GO_MSK);
89         RTC_LOCK();
90         break;
91 
92     case RT_DEVICE_CTRL_RTC_GET_ALARM:
93         break;
94 
95     case RT_DEVICE_CTRL_RTC_SET_ALARM:
96         break;
97 
98     default:
99         break;
100     }
101 
102     return result;
103 }
104 
105 #ifdef RT_USING_DEVICE_OPS
106 const static struct rt_device_ops es32f0_rtc_ops =
107 {
108     RT_NULL,
109     RT_NULL,
110     RT_NULL,
111     RT_NULL,
112     RT_NULL,
113     es32f0_rtc_control
114 };
115 #endif
116 
rt_hw_rtc_init(void)117 int rt_hw_rtc_init(void)
118 {
119     rt_err_t ret = RT_EOK;
120     static struct rt_device rtc_dev;
121     rtc_init_t rtc_initstruct;
122 
123     /* enable clk */
124     ald_rtc_source_select(ES_RTC_CLK_SOURCE);
125 
126     if(ES_RTC_CLK_SOURCE == ES_C_RTC_SOURCE_LOSC)
127     {
128         CMU_LOSC_ENABLE();
129         ald_cmu_losc_safe_config(ENABLE);
130     }
131 
132     /* set default time */
133     RTC_UNLOCK();
134     WRITE_REG(RTC->TIME, 0x134251);
135     WRITE_REG(RTC->DATE, 0x1190401);
136     RTC_LOCK();
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 
144     __rtc_init(&rtc_initstruct);
145 
146     rtc_dev.type = RT_Device_Class_RTC;
147     rtc_dev.rx_indicate = RT_NULL;
148     rtc_dev.tx_complete = RT_NULL;
149 
150 #ifdef RT_USING_DEVICE_OPS
151     rtc_dev.ops = &es32f0_rtc_ops;
152 #else
153     rtc_dev.init = RT_NULL;
154     rtc_dev.open = RT_NULL;
155     rtc_dev.close = RT_NULL;
156     rtc_dev.read = RT_NULL;
157     rtc_dev.write = RT_NULL;
158     rtc_dev.control = es32f0_rtc_control;
159 #endif
160 
161     rtc_dev.user_data = RTC;
162 
163     ret = rt_device_register(&rtc_dev, ES_DEVICE_NAME_RTC, RT_DEVICE_FLAG_RDWR);
164 
165     return ret;
166 }
167 INIT_DEVICE_EXPORT(rt_hw_rtc_init);
168 
169 #endif
170