1 /*
2  * Copyright (c) 2006-2021, RT-Thread Development Team
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  *
6  * Change Logs:
7  * Date         Author         Notes
8  * 2022-05-16   shelton        first version
9  * 2023-04-08   shelton        add support f423
10  * 2023-10-18   shelton        add support f402/f405
11  * 2024-04-12   shelton        add support a403a and a423
12  * 2024-08-30   shelton        add support m412 and m416
13  * 2024-12-18   shelton        add support f455/f456 and f457
14  */
15 
16 #include <rtthread.h>
17 #include <rtdevice.h>
18 #include <sys/time.h>
19 #include "drv_common.h"
20 
21 #ifdef BSP_USING_RTC
22 
23 //#define DRV_DEBUG
24 #define LOG_TAG                         "drv.rtc"
25 #include <drv_log.h>
26 
27 #define BKUP_REG_DATA                   0xA5A5
28 
29 #if   defined (SOC_SERIES_AT32F403A) || defined (SOC_SERIES_AT32F407) || \
30       defined (SOC_SERIES_AT32F413)  || defined (SOC_SERIES_AT32A403A)
31 #define Alarm_IRQn                      RTCAlarm_IRQn
32 #define Alarm_IRQHandler                RTCAlarm_IRQHandler
33 #elif defined (SOC_SERIES_AT32F421)  || defined (SOC_SERIES_AT32F425)
34 #define Alarm_IRQn                      RTC_IRQn
35 #define Alarm_IRQHandler                RTC_IRQHandler
36 #else
37 #define Alarm_IRQn                      ERTCAlarm_IRQn
38 #define Alarm_IRQHandler                ERTCAlarm_IRQHandler
39 #endif
40 
41 struct rtc_device_object
42 {
43     rt_rtc_dev_t rtc_dev;
44 #ifdef RT_USING_ALARM
45     struct rt_rtc_wkalarm   wkalarm;
46 #endif
47 };
48 
49 static struct rtc_device_object rtc_device;
50 
get_rtc_timestamp(void)51 static time_t get_rtc_timestamp(void)
52 {
53 #if defined (SOC_SERIES_AT32F435) || defined (SOC_SERIES_AT32F437) || \
54     defined (SOC_SERIES_AT32F415) || defined (SOC_SERIES_AT32F421) || \
55     defined (SOC_SERIES_AT32F425) || defined (SOC_SERIES_AT32F423) || \
56     defined (SOC_SERIES_AT32F402) || defined (SOC_SERIES_AT32F405) || \
57     defined (SOC_SERIES_AT32A423) || defined (SOC_SERIES_AT32M412) || \
58     defined (SOC_SERIES_AT32M416) || defined (SOC_SERIES_AT32F455) || \
59     defined (SOC_SERIES_AT32F456) || defined (SOC_SERIES_AT32F457)
60     struct tm tm_new;
61     ertc_time_type ertc_time_struct;
62 
63     ertc_calendar_get(&ertc_time_struct);
64 
65     tm_new.tm_sec = ertc_time_struct.sec;
66     tm_new.tm_min = ertc_time_struct.min;
67     tm_new.tm_hour = ertc_time_struct.hour;
68     tm_new.tm_mday = ertc_time_struct.day;
69     tm_new.tm_mon = ertc_time_struct.month - 1;
70     tm_new.tm_year = ertc_time_struct.year + 100;
71 
72     LOG_D("get rtc time.");
73 
74     return timegm(&tm_new);
75 #else
76     return rtc_counter_get();
77 #endif
78 }
79 
set_rtc_time_stamp(time_t time_stamp)80 static rt_err_t set_rtc_time_stamp(time_t time_stamp)
81 {
82 #if defined (SOC_SERIES_AT32F435) || defined (SOC_SERIES_AT32F437) || \
83     defined (SOC_SERIES_AT32F415) || defined (SOC_SERIES_AT32F421) || \
84     defined (SOC_SERIES_AT32F425) || defined (SOC_SERIES_AT32F423) || \
85     defined (SOC_SERIES_AT32F402) || defined (SOC_SERIES_AT32F405) || \
86     defined (SOC_SERIES_AT32A423) || defined (SOC_SERIES_AT32M412) || \
87     defined (SOC_SERIES_AT32M416) || defined (SOC_SERIES_AT32F455) || \
88     defined (SOC_SERIES_AT32F456) || defined (SOC_SERIES_AT32F457)
89     struct tm now;
90 
91     gmtime_r(&time_stamp, &now);
92     if (now.tm_year < 100)
93     {
94         return -RT_ERROR;
95     }
96 
97     /* set time */
98     if(ertc_time_set(now.tm_hour, now.tm_min, now.tm_sec, ERTC_AM) != SUCCESS)
99     {
100         return -RT_ERROR;
101     }
102 
103     /* set date */
104     if(ertc_date_set(now.tm_year - 100, now.tm_mon + 1, now.tm_mday, now.tm_wday + 1) != SUCCESS)
105     {
106         return -RT_ERROR;
107     }
108 
109     LOG_D("set rtc time.");
110 
111     /* indicator for the ertc configuration */
112     ertc_bpr_data_write(ERTC_DT1, BKUP_REG_DATA);
113 #else
114     /* set the rtc counter value */
115     rtc_counter_set(time_stamp);
116     /* wait until last write operation on rtc registers has finished */
117     rtc_wait_config_finish();
118     LOG_D("set rtc time.");
119 
120     bpr_data_write(BPR_DATA1, BKUP_REG_DATA);
121 #endif
122 
123     return RT_EOK;
124 }
125 
rt_rtc_config(void)126 static rt_err_t rt_rtc_config(void)
127 {
128     /* allow access to pattery powered domain */
129     pwc_battery_powered_domain_access(TRUE);
130 
131 #if defined (SOC_SERIES_AT32F435) || defined (SOC_SERIES_AT32F437) || \
132     defined (SOC_SERIES_AT32F415) || defined (SOC_SERIES_AT32F421) || \
133     defined (SOC_SERIES_AT32F425) || defined (SOC_SERIES_AT32F423) || \
134     defined (SOC_SERIES_AT32F402) || defined (SOC_SERIES_AT32F405) || \
135     defined (SOC_SERIES_AT32A423) || defined (SOC_SERIES_AT32M412) || \
136     defined (SOC_SERIES_AT32M416) || defined (SOC_SERIES_AT32F455) || \
137     defined (SOC_SERIES_AT32F456) || defined (SOC_SERIES_AT32F457)
138 
139     /* select rtc clock source */
140 #ifdef BSP_RTC_USING_LICK
141     crm_ertc_clock_select(CRM_ERTC_CLOCK_LICK);
142 #else
143     crm_ertc_clock_select(CRM_ERTC_CLOCK_LEXT);
144 #endif /* BSP_RTC_USING_LICK */
145 
146     /* enable rtc */
147     crm_ertc_clock_enable(TRUE);
148 
149     /* wait for ertc registers update */
150     ertc_wait_update();
151 
152     if (ertc_bpr_data_read(ERTC_DT1)!= BKUP_REG_DATA)
153     {
154         LOG_I("RTC hasn't been configured, please use <date> command to config.");
155 
156         /* configure the ertc divider */
157         ertc_divider_set(0x7F, 0xFF);
158         /* configure the ertc hour mode */
159         ertc_hour_mode_set(ERTC_HOUR_MODE_24);
160     }
161 #else
162 
163 #ifdef BSP_RTC_USING_LICK
164     crm_rtc_clock_select(CRM_RTC_CLOCK_LICK);
165 #else
166     crm_rtc_clock_select(CRM_RTC_CLOCK_LEXT);
167 #endif /* BSP_RTC_USING_LICK */
168     /* enable rtc */
169     crm_rtc_clock_enable(TRUE);
170 
171     /* wait for rtc registers update finish */
172     rtc_wait_update_finish();
173     /* wait until last write operation on rtc registers has finished */
174     rtc_wait_config_finish();
175 
176     if (bpr_data_read(BPR_DATA1) != BKUP_REG_DATA)
177     {
178         LOG_I("RTC hasn't been configured, please use <date> command to config.");
179         /* set rtc divider: set rtc period to 1sec */
180         rtc_divider_set(32767);
181         /* wait until last write operation on rtc registers has finished */
182         rtc_wait_config_finish();
183     }
184 #endif
185 
186     return RT_EOK;
187 }
188 
_rtc_init(void)189 static rt_err_t _rtc_init(void)
190 {
191     crm_periph_clock_enable(CRM_PWC_PERIPH_CLOCK, TRUE);
192 
193 #if defined (SOC_SERIES_AT32F403A) || defined (SOC_SERIES_AT32F407) || \
194     defined (SOC_SERIES_AT32F413)  || defined (SOC_SERIES_AT32A403A)
195     crm_periph_clock_enable(CRM_BPR_PERIPH_CLOCK, TRUE);
196 #endif
197 
198 #ifdef BSP_RTC_USING_LICK
199     crm_clock_source_enable(CRM_CLOCK_SOURCE_LICK, TRUE);
200     while(crm_flag_get(CRM_LICK_STABLE_FLAG) == RESET);
201 #else
202     pwc_battery_powered_domain_access(TRUE);
203     crm_clock_source_enable(CRM_CLOCK_SOURCE_LEXT, TRUE);
204     while(crm_flag_get(CRM_LEXT_STABLE_FLAG) == RESET);
205 #endif /* BSP_RTC_USING_LICK */
206 
207     if (rt_rtc_config() != RT_EOK)
208     {
209         LOG_E("rtc init failed.");
210         return -RT_ERROR;
211     }
212 
213     return RT_EOK;
214 }
215 
_rtc_get_secs(time_t * args)216 static rt_err_t _rtc_get_secs(time_t *args)
217 {
218     *(rt_uint32_t *)args = get_rtc_timestamp();
219     LOG_D("RTC: get rtc_time %x\n", *(rt_uint32_t *)args);
220 
221     return RT_EOK;
222 }
223 
_rtc_set_secs(time_t * args)224 static rt_err_t _rtc_set_secs(time_t *args)
225 {
226     rt_err_t result = RT_EOK;
227 
228     if (set_rtc_time_stamp(*(rt_uint32_t *)args))
229     {
230         result = -RT_ERROR;
231     }
232     LOG_D("RTC: set rtc_time %x\n", *(rt_uint32_t *)args);
233 
234     return result;
235 }
236 
237 #ifdef RT_USING_ALARM
rtc_alarm_time_set(struct rtc_device_object * p_dev)238 static rt_err_t rtc_alarm_time_set(struct rtc_device_object* p_dev)
239 {
240     exint_init_type exint_init_struct;
241 
242 #if defined (SOC_SERIES_AT32F403A) || defined (SOC_SERIES_AT32F407) || \
243     defined (SOC_SERIES_AT32F413)  || defined (SOC_SERIES_AT32A403A)
244     struct tm tm_new;
245     time_t sec_count;
246 #endif
247     /* config the exint line of the rtc alarm */
248     exint_init_struct.line_select = EXINT_LINE_17;
249     exint_init_struct.line_enable = TRUE;
250     exint_init_struct.line_mode = EXINT_LINE_INTERRUPUT;
251     exint_init_struct.line_polarity = EXINT_TRIGGER_RISING_EDGE;
252     exint_init(&exint_init_struct);
253 
254     if (p_dev->wkalarm.enable)
255     {
256         nvic_irq_enable(Alarm_IRQn, 0, 0);
257 
258 #if defined (SOC_SERIES_AT32F403A) || defined (SOC_SERIES_AT32F407) || \
259     defined (SOC_SERIES_AT32F413)  || defined (SOC_SERIES_AT32A403A)
260         /* clear alarm flag */
261         rtc_flag_clear(RTC_TA_FLAG);
262         /* wait for the register write to complete */
263         rtc_wait_config_finish();
264         /* enable alarm interrupt */
265         rtc_interrupt_enable(RTC_TA_INT, TRUE);
266         /* wait for the register write to complete */
267         rtc_wait_config_finish();
268 
269         tm_new.tm_sec = p_dev->wkalarm.tm_sec;
270         tm_new.tm_min = p_dev->wkalarm.tm_min;
271         tm_new.tm_hour = p_dev->wkalarm.tm_hour;
272         tm_new.tm_mday = p_dev->wkalarm.tm_mday;
273         tm_new.tm_mon = p_dev->wkalarm.tm_mon;
274         tm_new.tm_year = p_dev->wkalarm.tm_year;
275 
276         sec_count = timegm(&tm_new);
277         rtc_alarm_set(sec_count);
278         /* wait for the register write to complete */
279         rtc_wait_config_finish();
280 #else
281         ertc_alarm_enable(ERTC_ALA, FALSE);
282         ertc_flag_clear(ERTC_ALAF_FLAG);
283         ertc_alarm_mask_set(ERTC_ALA, ERTC_ALARM_MASK_DATE_WEEK);
284         ertc_alarm_week_date_select(ERTC_ALA, ERTC_SLECT_DATE);
285         ertc_alarm_set(ERTC_ALA, p_dev->wkalarm.tm_mday, p_dev->wkalarm.tm_hour, \
286                        p_dev->wkalarm.tm_min, p_dev->wkalarm.tm_sec, ERTC_24H);
287 
288         ertc_interrupt_enable(ERTC_ALA_INT, TRUE);
289         ertc_alarm_enable(ERTC_ALA, TRUE);
290         ertc_flag_clear(ERTC_ALAF_FLAG);
291 #endif
292     }
293 
294     return RT_EOK;
295 }
296 
Alarm_IRQHandler(void)297 void Alarm_IRQHandler(void)
298 {
299     rt_interrupt_enter();
300 
301 #if defined (SOC_SERIES_AT32F403A) || defined (SOC_SERIES_AT32F407) || \
302     defined (SOC_SERIES_AT32F413)  || defined (SOC_SERIES_AT32A403A)
303     if(rtc_flag_get(RTC_TA_FLAG) != RESET)
304     {
305         /* clear exint line flag */
306         exint_flag_clear(EXINT_LINE_17);
307 
308         /* wait for the register write to complete */
309         rtc_wait_config_finish();
310 
311         /* clear alarm flag */
312         rtc_flag_clear(RTC_TA_FLAG);
313 
314         /* wait for the register write to complete */
315         rtc_wait_config_finish();
316 
317         rt_alarm_update(&rtc_device.rtc_dev.parent, 1);
318     }
319 #else
320     if(ertc_flag_get(ERTC_ALAF_FLAG) != RESET)
321     {
322         /* clear alarm flag */
323         ertc_flag_clear(ERTC_ALAF_FLAG);
324 
325         /* clear exint flag */
326         exint_flag_clear(EXINT_LINE_17);
327 
328         rt_alarm_update(&rtc_device.rtc_dev.parent, 1);
329     }
330 #endif
331     rt_interrupt_leave();
332 }
333 #endif
334 
_rtc_get_alarm(struct rt_rtc_wkalarm * alarm)335 static rt_err_t _rtc_get_alarm(struct rt_rtc_wkalarm *alarm)
336 {
337 #ifdef RT_USING_ALARM
338     *alarm = rtc_device.wkalarm;
339     LOG_D("GET_ALARM %d:%d:%d",rtc_device.wkalarm.tm_hour,
340         rtc_device.wkalarm.tm_min,rtc_device.wkalarm.tm_sec);
341     return RT_EOK;
342 #else
343     return -RT_ERROR;
344 #endif
345 }
346 
_rtc_set_alarm(struct rt_rtc_wkalarm * alarm)347 static rt_err_t _rtc_set_alarm(struct rt_rtc_wkalarm *alarm)
348 {
349 #ifdef RT_USING_ALARM
350     LOG_D("RT_DEVICE_CTRL_RTC_SET_ALARM");
351     if (alarm != RT_NULL)
352     {
353         rtc_device.wkalarm.enable = alarm->enable;
354         rtc_device.wkalarm.tm_year = alarm->tm_year;
355         rtc_device.wkalarm.tm_mon = alarm->tm_mon;
356         rtc_device.wkalarm.tm_mday = alarm->tm_mday;
357         rtc_device.wkalarm.tm_hour = alarm->tm_hour;
358         rtc_device.wkalarm.tm_min = alarm->tm_min;
359         rtc_device.wkalarm.tm_sec = alarm->tm_sec;
360         rtc_alarm_time_set(&rtc_device);
361     }
362     else
363     {
364         LOG_E("RT_DEVICE_CTRL_RTC_SET_ALARM error!!");
365         return -RT_ERROR;
366     }
367     LOG_D("SET_ALARM %d:%d:%d",alarm->tm_hour,
368         alarm->tm_min, alarm->tm_sec);
369     return RT_EOK;
370 #else
371     return -RT_ERROR;
372 #endif
373 }
374 
_rtc_get_timeval(struct timeval * tv)375 static rt_err_t _rtc_get_timeval(struct timeval *tv)
376 {
377     tv->tv_sec = get_rtc_timestamp();
378 
379     return RT_EOK;
380 }
381 
382 static const struct rt_rtc_ops _rtc_ops =
383 {
384     _rtc_init,
385     _rtc_get_secs,
386     _rtc_set_secs,
387     _rtc_get_alarm,
388     _rtc_set_alarm,
389     _rtc_get_timeval,
390     RT_NULL,
391 };
392 
rt_hw_rtc_init(void)393 int rt_hw_rtc_init(void)
394 {
395     rt_err_t result;
396     rtc_device.rtc_dev.ops = &_rtc_ops;
397     result = rt_hw_rtc_register(&rtc_device.rtc_dev, "rtc", RT_DEVICE_FLAG_RDWR, RT_NULL);
398     if (result != RT_EOK)
399     {
400         LOG_E("rtc register err code: %d", result);
401         return result;
402     }
403     LOG_D("rtc init success");
404     return RT_EOK;
405 }
406 
407 INIT_DEVICE_EXPORT(rt_hw_rtc_init);
408 
409 #endif /* BSP_USING_RTC */
410