1 /*!
2 \file gd32e50x_rtc.c
3 \brief RTC driver
4
5 \version 2020-03-10, V1.0.0, firmware for GD32E50x
6 \version 2020-08-26, V1.1.0, firmware for GD32E50x
7 \version 2021-03-23, V1.2.0, firmware for GD32E50x
8 */
9
10 /*
11 Copyright (c) 2021, GigaDevice Semiconductor Inc.
12
13 Redistribution and use in source and binary forms, with or without modification,
14 are permitted provided that the following conditions are met:
15
16 1. Redistributions of source code must retain the above copyright notice, this
17 list of conditions and the following disclaimer.
18 2. Redistributions in binary form must reproduce the above copyright notice,
19 this list of conditions and the following disclaimer in the documentation
20 and/or other materials provided with the distribution.
21 3. Neither the name of the copyright holder nor the names of its contributors
22 may be used to endorse or promote products derived from this software without
23 specific prior written permission.
24
25 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
26 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
27 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
28 IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
29 INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
30 NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
31 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
32 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
33 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
34 OF SUCH DAMAGE.
35 */
36
37 #include "gd32e50x_rtc.h"
38
39 /* RTC register bit offset */
40 #define CNTH_16BIT_OFFSET ((uint32_t)0X00000010U)
41 #define PSCH_16BIT_OFFSET ((uint32_t)0X00000010U)
42 #define ALARMH_16BIT_OFFSET ((uint32_t)0X00000010U)
43
44 /*!
45 \brief enter RTC configuration mode
46 \param[in] none
47 \param[out] none
48 \retval none
49 */
rtc_configuration_mode_enter(void)50 void rtc_configuration_mode_enter(void)
51 {
52 RTC_CTL |= RTC_CTL_CMF;
53 }
54
55 /*!
56 \brief exit RTC configuration mode
57 \param[in] none
58 \param[out] none
59 \retval none
60 */
rtc_configuration_mode_exit(void)61 void rtc_configuration_mode_exit(void)
62 {
63 RTC_CTL &= ~RTC_CTL_CMF;
64 }
65
66 /*!
67 \brief wait RTC last write operation finished flag set
68 \param[in] none
69 \param[out] none
70 \retval none
71 */
rtc_lwoff_wait(void)72 void rtc_lwoff_wait(void)
73 {
74 /* loop until LWOFF flag is set */
75 while(RESET == (RTC_CTL & RTC_CTL_LWOFF)){
76 }
77 }
78
79 /*!
80 \brief wait RTC registers synchronized flag set
81 \param[in] none
82 \param[out] none
83 \retval none
84 */
rtc_register_sync_wait(void)85 void rtc_register_sync_wait(void)
86 {
87 /* clear RSYNF flag */
88 RTC_CTL &= ~RTC_CTL_RSYNF;
89 /* loop until RSYNF flag is set */
90 while(RESET == (RTC_CTL & RTC_CTL_RSYNF)){
91 }
92 }
93
94 /*!
95 \brief get RTC counter value
96 \param[in] none
97 \param[out] none
98 \retval RTC counter value
99 */
rtc_counter_get(void)100 uint32_t rtc_counter_get(void)
101 {
102 uint32_t temp = 0x0U;
103 temp = RTC_CNTL;
104 temp |= (RTC_CNTH << 16);
105 return temp;
106 }
107
108 /*!
109 \brief set RTC counter value
110 \param[in] cnt: RTC counter value(0x00000000~0xFFFFFFFF)
111 \param[out] none
112 \retval none
113 */
rtc_counter_set(uint32_t cnt)114 void rtc_counter_set(uint32_t cnt)
115 {
116 rtc_configuration_mode_enter();
117 /* set the RTC counter high bits */
118 RTC_CNTH = cnt >> CNTH_16BIT_OFFSET;
119 /* set the RTC counter low bits */
120 RTC_CNTL = (cnt & RTC_LOW_VALUE);
121 rtc_configuration_mode_exit();
122 }
123
124 /*!
125 \brief set RTC prescaler value
126 \param[in] psc: RTC prescaler value(0x00000000~0x000FFFFF)
127 \param[out] none
128 \retval none
129 */
rtc_prescaler_set(uint32_t psc)130 void rtc_prescaler_set(uint32_t psc)
131 {
132 rtc_configuration_mode_enter();
133 /* set the RTC prescaler high bits */
134 RTC_PSCH = (psc & RTC_HIGH_VALUE) >> PSCH_16BIT_OFFSET;
135 /* set the RTC prescaler low bits */
136 RTC_PSCL = (psc & RTC_LOW_VALUE);
137 rtc_configuration_mode_exit();
138 }
139
140 /*!
141 \brief set RTC alarm value
142 \param[in] alarm: RTC alarm value(0x00000000~0xFFFFFFFF)
143 \param[out] none
144 \retval none
145 */
rtc_alarm_config(uint32_t alarm)146 void rtc_alarm_config(uint32_t alarm)
147 {
148 rtc_configuration_mode_enter();
149 /* set the alarm high bits */
150 RTC_ALRMH = alarm >> ALARMH_16BIT_OFFSET;
151 /* set the alarm low bits */
152 RTC_ALRML = (alarm & RTC_LOW_VALUE);
153 rtc_configuration_mode_exit();
154 }
155
156 /*!
157 \brief get RTC divider value
158 \param[in] none
159 \param[out] none
160 \retval RTC divider value
161 */
rtc_divider_get(void)162 uint32_t rtc_divider_get(void)
163 {
164 uint32_t temp = 0x00U;
165 temp = (RTC_DIVH & RTC_DIVH_DIV) << 16;
166 temp |= RTC_DIVL;
167 return temp;
168 }
169
170 /*!
171 \brief enable RTC interrupt
172 \param[in] interrupt: specify which interrupt to enbale
173 only one parameter can be selected which is shown as below:
174 \arg RTC_INT_SECOND: second interrupt
175 \arg RTC_INT_ALARM: alarm interrupt
176 \arg RTC_INT_OVERFLOW: overflow interrupt
177 \param[out] none
178 \retval none
179 */
rtc_interrupt_enable(uint32_t interrupt)180 void rtc_interrupt_enable(uint32_t interrupt)
181 {
182 RTC_INTEN |= interrupt;
183 }
184
185 /*!
186 \brief disable RTC interrupt
187 \param[in] interrupt: specify which interrupt to disbale
188 only one parameter can be selected which is shown as below:
189 \arg RTC_INT_SECOND: second interrupt
190 \arg RTC_INT_ALARM: alarm interrupt
191 \arg RTC_INT_OVERFLOW: overflow interrupt
192 \param[out] none
193 \retval none
194 */
rtc_interrupt_disable(uint32_t interrupt)195 void rtc_interrupt_disable(uint32_t interrupt)
196 {
197 RTC_INTEN &= ~interrupt;
198 }
199
200 /*!
201 \brief get RTC flag status
202 \param[in] flag: specify which flag status to get
203 only one parameter can be selected which is shown as below:
204 \arg RTC_FLAG_SECOND: second interrupt flag
205 \arg RTC_FLAG_ALARM: alarm interrupt flag
206 \arg RTC_FLAG_OVERFLOW: overflow interrupt flag
207 \arg RTC_FLAG_RSYN: registers synchronized flag
208 \arg RTC_FLAG_LWOF: last write operation finished flag
209 \param[out] none
210 \retval SET or RESET
211 */
rtc_flag_get(uint32_t flag)212 FlagStatus rtc_flag_get(uint32_t flag)
213 {
214 if(RESET != (RTC_CTL & flag)){
215 return SET;
216 }else{
217 return RESET;
218 }
219 }
220
221 /*!
222 \brief clear RTC flag status
223 \param[in] flag: specify which flag status to clear
224 only one parameter can be selected which is shown as below:
225 \arg RTC_FLAG_SECOND: second interrupt flag
226 \arg RTC_FLAG_ALARM: alarm interrupt flag
227 \arg RTC_FLAG_OVERFLOW: overflow interrupt flag
228 \arg RTC_FLAG_RSYN: registers synchronized flag
229 \param[out] none
230 \retval none
231 */
rtc_flag_clear(uint32_t flag)232 void rtc_flag_clear(uint32_t flag)
233 {
234 /* clear RTC flag */
235 RTC_CTL &= ~flag;
236 }
237