1 /*
2 * Copyright (c) 2006-2020, RT-Thread Development Team
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 *
6 * Change Logs:
7 * Date Author Notes
8 * 2020-06-08 hqfang first implementation.
9 */
10
11 #include "drv_rtc.h"
12
13 #ifdef BSP_USING_RTC
14
get_timestamp(void)15 static time_t get_timestamp(void)
16 {
17 return (time_t)rtc_counter_get();
18 }
19
set_timestamp(time_t timestamp)20 static int set_timestamp(time_t timestamp)
21 {
22 /* wait until last write operation on RTC registers has finished */
23 rtc_lwoff_wait();
24 /* change the current time */
25 rtc_counter_set((uint32_t)timestamp);
26 /* wait until last write operation on RTC registers has finished */
27 rtc_lwoff_wait();
28 return RT_EOK;
29 }
30
rtc_configuration(void)31 static void rtc_configuration(void)
32 {
33 /* enable PMU and BKPI clocks */
34 rcu_periph_clock_enable(RCU_BKPI);
35 rcu_periph_clock_enable(RCU_PMU);
36 /* allow access to BKP domain */
37 pmu_backup_write_enable();
38
39 /* reset backup domain */
40 bkp_deinit();
41
42 /* enable LXTAL */
43 rcu_osci_on(RCU_LXTAL);
44 /* wait till LXTAL is ready */
45 rcu_osci_stab_wait(RCU_LXTAL);
46
47 /* select RCU_LXTAL as RTC clock source */
48 rcu_rtc_clock_config(RCU_RTCSRC_LXTAL);
49
50 /* enable RTC Clock */
51 rcu_periph_clock_enable(RCU_RTC);
52
53 /* wait for RTC registers synchronization */
54 rtc_register_sync_wait();
55
56 /* wait until last write operation on RTC registers has finished */
57 rtc_lwoff_wait();
58
59 /* wait until last write operation on RTC registers has finished */
60 rtc_lwoff_wait();
61
62 /* set RTC prescaler: set RTC period to 1s */
63 rtc_prescaler_set(32767);
64
65 /* wait until last write operation on RTC registers has finished */
66 rtc_lwoff_wait();
67 }
68
gd32_rtc_init(rt_device_t dev)69 static rt_err_t gd32_rtc_init(rt_device_t dev)
70 {
71 if (bkp_data_read(BKP_DATA_0) != 0xA5A5)
72 {
73 rtc_configuration();
74 bkp_data_write(BKP_DATA_0, 0xA5A5);
75 }
76 else
77 {
78 /* allow access to BKP domain */
79 rcu_periph_clock_enable(RCU_PMU);
80 pmu_backup_write_enable();
81
82 /* wait for RTC registers synchronization */
83 rtc_register_sync_wait();
84 /* wait until last write operation on RTC registers has finished */
85 rtc_lwoff_wait();
86 }
87
88 return RT_EOK;
89 }
90
gd32_rtc_open(rt_device_t dev,rt_uint16_t oflag)91 static rt_err_t gd32_rtc_open(rt_device_t dev, rt_uint16_t oflag)
92 {
93 return RT_EOK;
94 }
95
gd32_rtc_close(rt_device_t dev)96 static rt_err_t gd32_rtc_close(rt_device_t dev)
97 {
98 return RT_EOK;
99 }
100
gd32_rtc_read(rt_device_t dev,rt_off_t pos,void * buffer,rt_size_t size)101 static rt_ssize_t gd32_rtc_read(rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t size)
102 {
103 return RT_EOK;
104 }
105
gd32_rtc_write(rt_device_t dev,rt_off_t pos,const void * buffer,rt_size_t size)106 static rt_ssize_t gd32_rtc_write(rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size)
107 {
108 return RT_EOK;
109 }
110
gd32_rtc_control(rt_device_t dev,int cmd,void * args)111 static rt_err_t gd32_rtc_control(rt_device_t dev, int cmd, void *args)
112 {
113 RT_ASSERT(dev != RT_NULL);
114
115 switch (cmd)
116 {
117 case RT_DEVICE_CTRL_RTC_GET_TIME:
118 {
119 *(uint32_t *)args = get_timestamp();
120 }
121 break;
122
123 case RT_DEVICE_CTRL_RTC_SET_TIME:
124 {
125 set_timestamp(*(time_t *)args);
126 }
127 break;
128
129 default:
130 return -RT_EINVAL;
131 }
132
133 return RT_EOK;
134 }
135
136 static struct rt_device rtc_device =
137 {
138 .type = RT_Device_Class_RTC,
139 .init = gd32_rtc_init,
140 .open = gd32_rtc_open,
141 .close = gd32_rtc_close,
142 .read = gd32_rtc_read,
143 .write = gd32_rtc_write,
144 .control = gd32_rtc_control,
145 };
146
rt_hw_rtc_init(void)147 int rt_hw_rtc_init(void)
148 {
149 rt_err_t ret = RT_EOK;
150
151 ret = rt_device_register(&rtc_device, "rtc", RT_DEVICE_FLAG_RDWR);
152
153 rt_device_open(&rtc_device, RT_DEVICE_OFLAG_RDWR);
154
155 return RT_EOK;
156 }
157
158 INIT_DEVICE_EXPORT(rt_hw_rtc_init);
159
160 #endif /* BSP_USING_RTC */
161