1 /********************************** (C) COPYRIGHT *******************************
2 * File Name          : ch32f20x_rtc.c
3 * Author             : WCH
4 * Version            : V1.0.0
5 * Date               : 2021/08/08
6 * Description        : This file provides all the RTC firmware functions.
7 ********************************************************************************/
8 #include "ch32f20x_rtc.h"
9 
10 /* RTC_Private_Defines */
11 #define RTC_LSB_MASK     ((uint32_t)0x0000FFFF)  /* RTC LSB Mask */
12 #define PRLH_MSB_MASK    ((uint32_t)0x000F0000)  /* RTC Prescaler MSB Mask */
13 
14 /********************************************************************************
15 * Function Name  : RTC_ITConfig
16 * Description    : Enables or disables the specified RTC interrupts.
17 * Input          : RTC_IT: specifies the RTC interrupts sources to be enabled or disabled.
18 *                     RTC_IT_OW: Overflow interrupt
19 *                     RTC_IT_ALR: Alarm interrupt
20 *                     RTC_IT_SEC: Second interrupt
21 * Return         : NewState: new state of the specified RTC interrupts(ENABLE or DISABLE).
22 *********************************************************************************/
RTC_ITConfig(uint16_t RTC_IT,FunctionalState NewState)23 void RTC_ITConfig(uint16_t RTC_IT, FunctionalState NewState)
24 {
25   if (NewState != DISABLE)
26   {
27     RTC->CTLRH |= RTC_IT;
28   }
29   else
30   {
31     RTC->CTLRH &= (uint16_t)~RTC_IT;
32   }
33 }
34 
35 /********************************************************************************
36 * Function Name  : RTC_EnterConfigMode
37 * Description    : Enters the RTC configuration mode.
38 * Input          : None
39 * Return         : None
40 *********************************************************************************/
RTC_EnterConfigMode(void)41 void RTC_EnterConfigMode(void)
42 {
43   RTC->CTLRL |= RTC_CTLRL_CNF;
44 }
45 
46 /********************************************************************************
47 * Function Name  : RTC_ExitConfigMode
48 * Description    : Exits from the RTC configuration mode.
49 * Input          : None
50 * Return         : None
51 *********************************************************************************/
RTC_ExitConfigMode(void)52 void RTC_ExitConfigMode(void)
53 {
54   RTC->CTLRL &= (uint16_t)~((uint16_t)RTC_CTLRL_CNF);
55 }
56 
57 /********************************************************************************
58 * Function Name  : RTC_GetCounter
59 * Description    : Gets the RTC counter value
60 * Input          : None
61 * Return         : RTC counter value
62 *********************************************************************************/
RTC_GetCounter(void)63 uint32_t RTC_GetCounter(void)
64 {
65   uint16_t high1 = 0, high2 = 0, low = 0;
66 
67   high1 = RTC->CNTH;
68   low   = RTC->CNTL;
69   high2 = RTC->CNTH;
70 
71   if (high1 != high2)
72   {
73     return (((uint32_t) high2 << 16 ) | RTC->CNTL);
74   }
75   else
76   {
77     return (((uint32_t) high1 << 16 ) | low);
78   }
79 }
80 
81 /********************************************************************************
82 * Function Name  : RTC_SetCounter
83 * Description    : Sets the RTC counter value.
84 * Input          : CounterValue: RTC counter new value.
85 * Return         : None
86 *********************************************************************************/
RTC_SetCounter(uint32_t CounterValue)87 void RTC_SetCounter(uint32_t CounterValue)
88 {
89   RTC_EnterConfigMode();
90   RTC->CNTH = CounterValue >> 16;
91   RTC->CNTL = (CounterValue & RTC_LSB_MASK);
92   RTC_ExitConfigMode();
93 }
94 
95 /********************************************************************************
96 * Function Name  : RTC_SetPrescaler
97 * Description    : Sets the RTC prescaler value
98 * Input          : PrescalerValue: RTC prescaler new value
99 * Return         : None
100 *********************************************************************************/
RTC_SetPrescaler(uint32_t PrescalerValue)101 void RTC_SetPrescaler(uint32_t PrescalerValue)
102 {
103   RTC_EnterConfigMode();
104   RTC->PSCRH = (PrescalerValue & PRLH_MSB_MASK) >> 16;
105   RTC->PSCRL = (PrescalerValue & RTC_LSB_MASK);
106   RTC_ExitConfigMode();
107 }
108 
109 /********************************************************************************
110 * Function Name  : RTC_SetAlarm
111 * Description    : Sets the RTC alarm value
112 * Input          : AlarmValue: RTC alarm new value
113 * Return         : None
114 *********************************************************************************/
RTC_SetAlarm(uint32_t AlarmValue)115 void RTC_SetAlarm(uint32_t AlarmValue)
116 {
117   RTC_EnterConfigMode();
118   RTC->ALRMH = AlarmValue >> 16;
119   RTC->ALRML = (AlarmValue & RTC_LSB_MASK);
120   RTC_ExitConfigMode();
121 }
122 
123 /********************************************************************************
124 * Function Name  : RTC_GetDivider
125 * Description    : Gets the RTC divider value
126 * Input          : None
127 * Return         : RTC Divider value
128 *********************************************************************************/
RTC_GetDivider(void)129 uint32_t RTC_GetDivider(void)
130 {
131   uint32_t tmp = 0x00;
132   tmp = ((uint32_t)RTC->DIVH & (uint32_t)0x000F) << 16;
133   tmp |= RTC->DIVL;
134   return tmp;
135 }
136 
137 /********************************************************************************
138 * Function Name  : RTC_WaitForLastTask
139 * Description    : Waits until last write operation on RTC registers has finished
140 * Input          : None
141 * Return         : None
142 *********************************************************************************/
RTC_WaitForLastTask(void)143 void RTC_WaitForLastTask(void)
144 {
145   while ((RTC->CTLRL & RTC_FLAG_RTOFF) == (uint16_t)RESET)
146   {
147   }
148 }
149 
150 /********************************************************************************
151 * Function Name  : RTC_WaitForSynchro
152 * Description    : Waits until the RTC registers
153 *                  are synchronized with RTC APB clock
154 * Input          : None
155 * Return         : None
156 *********************************************************************************/
RTC_WaitForSynchro(void)157 void RTC_WaitForSynchro(void)
158 {
159   RTC->CTLRL &= (uint16_t)~RTC_FLAG_RSF;
160   while ((RTC->CTLRL & RTC_FLAG_RSF) == (uint16_t)RESET)
161   {
162   }
163 }
164 
165 /********************************************************************************
166 * Function Name  : RTC_GetFlagStatus
167 * Description    : Checks whether the specified RTC flag is set or not
168 * Input          : RTC_FLAG: specifies the flag to check
169 *                    RTC_FLAG_RTOFF: RTC Operation OFF flag
170 *                    RTC_FLAG_RSF: Registers Synchronized flag
171 *                    RTC_FLAG_OW: Overflow flag
172 *                    RTC_FLAG_ALR: Alarm flag
173 *                    RTC_FLAG_SEC: Second flag
174 * Return         : The new state of RTC_FLAG (SET or RESET)
175 *********************************************************************************/
RTC_GetFlagStatus(uint16_t RTC_FLAG)176 FlagStatus RTC_GetFlagStatus(uint16_t RTC_FLAG)
177 {
178   FlagStatus bitstatus = RESET;
179   if ((RTC->CTLRL & RTC_FLAG) != (uint16_t)RESET)
180   {
181     bitstatus = SET;
182   }
183   else
184   {
185     bitstatus = RESET;
186   }
187   return bitstatus;
188 }
189 
190 /********************************************************************************
191 * Function Name  : RTC_ClearFlag
192 * Description    : Clears the RTC's pending flags
193 * Input          : RTC_FLAG: specifies the flag to clear
194 *                    RTC_FLAG_RSF: Registers Synchronized flag
195 *                    RTC_FLAG_OW: Overflow flag
196 *                    RTC_FLAG_ALR: Alarm flag
197 *                    RTC_FLAG_SEC: Second flag
198 * Return         : None
199 *********************************************************************************/
RTC_ClearFlag(uint16_t RTC_FLAG)200 void RTC_ClearFlag(uint16_t RTC_FLAG)
201 {
202   RTC->CTLRL &= (uint16_t)~RTC_FLAG;
203 }
204 
205 
206 /********************************************************************************
207 * Function Name  : RTC_GetITStatus
208 * Description    : Checks whether the specified RTC interrupt has occurred or not
209 * Input          : RTC_IT: specifies the RTC interrupts sources to check
210 *                    RTC_FLAG_OW: Overflow interrupt
211 *                    RTC_FLAG_ALR: Alarm interrupt
212 *                    RTC_FLAG_SEC: Second interrupt
213 * Return         : The new state of the RTC_IT (SET or RESET)
214 *********************************************************************************/
RTC_GetITStatus(uint16_t RTC_IT)215 ITStatus RTC_GetITStatus(uint16_t RTC_IT)
216 {
217   ITStatus bitstatus = RESET;
218 
219   bitstatus = (ITStatus)(RTC->CTLRL & RTC_IT);
220   if (((RTC->CTLRH & RTC_IT) != (uint16_t)RESET) && (bitstatus != (uint16_t)RESET))
221   {
222     bitstatus = SET;
223   }
224   else
225   {
226     bitstatus = RESET;
227   }
228   return bitstatus;
229 }
230 
231 /********************************************************************************
232 * Function Name  : RTC_ClearITPendingBit
233 * Description    : Clears the RTC's interrupt pending bits
234 * Input          : RTC_IT: specifies the interrupt pending bit to clear
235 *                    RTC_FLAG_OW: Overflow interrupt
236 *                    RTC_FLAG_ALR: Alarm interrupt
237 *                    RTC_FLAG_SEC: Second interrupt
238 * Return         : None
239 *********************************************************************************/
RTC_ClearITPendingBit(uint16_t RTC_IT)240 void RTC_ClearITPendingBit(uint16_t RTC_IT)
241 {
242   RTC->CTLRL &= (uint16_t)~RTC_IT;
243 }
244 
245