1 /********************************** (C) COPYRIGHT *******************************
2 * File Name          : ch32f20x_pwr.c
3 * Author             : WCH
4 * Version            : V1.0.0
5 * Date               : 2021/08/08
6 * Description        : This file provides all the PWR firmware functions.
7 ********************************************************************************/
8 #include "ch32f20x_pwr.h"
9 #include "ch32f20x_rcc.h"
10 
11 /* PWR registers bit mask */
12 /* CTLR register bit mask */
13 #define CTLR_DS_MASK             ((uint32_t)0xFFFFFFFC)
14 #define CTLR_PLS_MASK            ((uint32_t)0xFFFFFF1F)
15 
16 /********************************************************************************
17 * Function Name  : PWR_DeInit
18 * Description    : Deinitializes the PWR peripheral registers to their default
19 *                  reset values.
20 * Input          : None
21 * Return         : None
22 *********************************************************************************/
PWR_DeInit(void)23 void PWR_DeInit(void)
24 {
25   RCC_APB1PeriphResetCmd(RCC_APB1Periph_PWR, ENABLE);
26   RCC_APB1PeriphResetCmd(RCC_APB1Periph_PWR, DISABLE);
27 }
28 
29 
30 /********************************************************************************
31 * Function Name  : PWR_BackupAccessCmd
32 * Description    : Enables or disables access to the RTC and backup registers.
33 * Input          : NewState: new state of the access to the RTC and backup registers,
34 *                            This parameter can be: ENABLE or DISABLE.
35 * Return         : None
36 *********************************************************************************/
PWR_BackupAccessCmd(FunctionalState NewState)37 void PWR_BackupAccessCmd(FunctionalState NewState)
38 {
39 	if(NewState)
40 	{
41 		PWR->CTLR |= ((uint32_t)1<<8);
42 	}
43 	else{
44 		PWR->CTLR &= ~((uint32_t)1<<8);
45 	}
46 }
47 
48 
49 /********************************************************************************
50 * Function Name  : PWR_PVDCmd
51 * Description    : Enables or disables the Power Voltage Detector(PVD).
52 * Input          : NewState: new state of the PVD(ENABLE or DISABLE).
53 * Return         : None
54 *********************************************************************************/
PWR_PVDCmd(FunctionalState NewState)55 void PWR_PVDCmd(FunctionalState NewState)
56 {
57 	if(NewState)
58 	{
59 		PWR->CTLR |= ((uint32_t)1<<4);
60 	}
61 	else{
62 		PWR->CTLR &= ~((uint32_t)1<<4);
63 	}
64 }
65 
66 
67 /********************************************************************************
68 * Function Name  : PWR_PVDLevelConfig
69 * Description    : Configures the voltage threshold detected by the Power Voltage
70 *                  Detector(PVD).
71 * Input          : PWR_PVDLevel: specifies the PVD detection level
72 *                     PWR_PVDLevel_2V2: PVD detection level set to 2.2V
73 *                     PWR_PVDLevel_2V3: PVD detection level set to 2.3V
74 *                     PWR_PVDLevel_2V4: PVD detection level set to 2.4V
75 *                     PWR_PVDLevel_2V5: PVD detection level set to 2.5V
76 *                     PWR_PVDLevel_2V6: PVD detection level set to 2.6V
77 *                     PWR_PVDLevel_2V7: PVD detection level set to 2.7V
78 *                     PWR_PVDLevel_2V8: PVD detection level set to 2.8V
79 *                     PWR_PVDLevel_2V9: PVD detection level set to 2.9V
80 * Return         : None
81 *********************************************************************************/
PWR_PVDLevelConfig(uint32_t PWR_PVDLevel)82 void PWR_PVDLevelConfig(uint32_t PWR_PVDLevel)
83 {
84   uint32_t tmpreg = 0;
85   tmpreg = PWR->CTLR;
86   tmpreg &= CTLR_PLS_MASK;
87   tmpreg |= PWR_PVDLevel;
88   PWR->CTLR = tmpreg;
89 }
90 
91 
92 /********************************************************************************
93 * Function Name  : PWR_WakeUpPinCmd
94 * Description    : Enables or disables the WakeUp Pin functionality.
95 * Input          : NewState: new state of the WakeUp Pin functionality(ENABLE or DISABLE).
96 * Return         : None
97 *********************************************************************************/
PWR_WakeUpPinCmd(FunctionalState NewState)98 void PWR_WakeUpPinCmd(FunctionalState NewState)
99 {
100 	if(NewState)
101 	{
102 		PWR->CSR |= ((uint32_t)1<<8);
103 	}
104 	else{
105 		PWR->CSR &= ~((uint32_t)1<<8);
106 	}
107 }
108 
109 
110 /********************************************************************************
111 * Function Name  : PWR_EnterSTOPMode
112 * Description    : Enters STOP mode.
113 * Input          : PWR_Regulator: specifies the regulator state in STOP mode.
114 *                    PWR_Regulator_ON: STOP mode with regulator ON
115 *                    PWR_Regulator_LowPower: STOP mode with regulator in low power mode
116 *                  PWR_STOPEntry: specifies if STOP mode in entered with WFI or WFE instruction.
117 *                    PWR_STOPEntry_WFI: enter STOP mode with WFI instruction
118 *                    PWR_STOPEntry_WFE: enter STOP mode with WFE instruction
119 * Return         : None
120 *********************************************************************************/
PWR_EnterSTOPMode(uint32_t PWR_Regulator,uint8_t PWR_STOPEntry)121 void PWR_EnterSTOPMode(uint32_t PWR_Regulator, uint8_t PWR_STOPEntry)
122 {
123   uint32_t tmpreg = 0;
124   tmpreg = PWR->CTLR;
125   tmpreg &= CTLR_DS_MASK;
126   tmpreg |= PWR_Regulator;
127   PWR->CTLR = tmpreg;
128   SCB->SCR |= SCB_SCR_SLEEPDEEP;
129 
130   if(PWR_STOPEntry == PWR_STOPEntry_WFI)
131   {
132     __WFI();
133   }
134   else
135   {
136     __WFE();
137   }
138 
139   SCB->SCR &= (uint32_t)~((uint32_t)SCB_SCR_SLEEPDEEP);
140 }
141 
142 /********************************************************************************
143 * Function Name  : PWR_EnterSTANDBYMode
144 * Description    : Enters STANDBY mode.
145 * Input          : None
146 * Return         : None
147 *********************************************************************************/
PWR_EnterSTANDBYMode(void)148 void PWR_EnterSTANDBYMode(void)
149 {
150   PWR->CTLR |= PWR_CTLR_CWUF;
151   PWR->CTLR |= PWR_CTLR_PDDS;
152   SCB->SCR |= SCB_SCR_SLEEPDEEP;
153 #if defined ( __CC_ARM   )
154   __force_stores();
155 #endif
156   __WFI();
157 }
158 
159 
160 /********************************************************************************
161 * Function Name  : PWR_GetFlagStatus
162 * Description    : Checks whether the specified PWR flag is set or not.
163 * Input          : PWR_FLAG: specifies the flag to check.
164 *                     PWR_FLAG_WU: Wake Up flag
165 *                     PWR_FLAG_SB: StandBy flag
166 *                     PWR_FLAG_PVDO: PVD Output
167 * Return         : The new state of PWR_FLAG (SET or RESET).
168 *********************************************************************************/
PWR_GetFlagStatus(uint32_t PWR_FLAG)169 FlagStatus PWR_GetFlagStatus(uint32_t PWR_FLAG)
170 {
171   FlagStatus bitstatus = RESET;
172 
173   if ((PWR->CSR & PWR_FLAG) != (uint32_t)RESET)
174   {
175     bitstatus = SET;
176   }
177   else
178   {
179     bitstatus = RESET;
180   }
181   return bitstatus;
182 }
183 
184 
185 /********************************************************************************
186 * Function Name  : PWR_ClearFlag
187 * Description    : Clears the PWR's pending flags.
188 * Input          : PWR_FLAG: specifies the flag to clear.
189 *                     PWR_FLAG_WU: Wake Up flag
190 *                     PWR_FLAG_SB: StandBy flag
191 * Return         : None
192 *********************************************************************************/
PWR_ClearFlag(uint32_t PWR_FLAG)193 void PWR_ClearFlag(uint32_t PWR_FLAG)
194 {
195   PWR->CTLR |=  PWR_FLAG << 2;
196 }
197 
198 /*******************************************************************************
199 * Function Name  : PWR_EnterSTOPMode_RAM
200 * Description    : Enters STOP mode with RAM data retention function on.
201 * Input          : PWR_Regulator: specifies the regulator state in STOP mode.
202 *                    PWR_Regulator_ON: STOP mode with regulator ON
203 *                    PWR_Regulator_LowPower: STOP mode with regulator in low power mode
204 *                  PWR_STOPEntry: specifies if STOP mode in entered with WFI or WFE instruction.
205 *                    PWR_STOPEntry_WFI: enter STOP mode with WFI instruction
206 *                    PWR_STOPEntry_WFE: enter STOP mode with WFE instruction
207 * Return         : None
208 *******************************************************************************/
PWR_EnterSTOPMode_RAM(uint32_t PWR_Regulator,uint8_t PWR_STOPEntry)209 void PWR_EnterSTOPMode_RAM(uint32_t PWR_Regulator, uint8_t PWR_STOPEntry)
210 {
211   uint32_t tmpreg = 0;
212   tmpreg = PWR->CTLR;
213   tmpreg &= CTLR_DS_MASK;
214   tmpreg |= PWR_Regulator;
215 
216   //2K+30K in standby w power.
217   tmpreg |= ((uint32_t)1<<16)|((uint32_t)1<<17);
218 
219   PWR->CTLR = tmpreg;
220   SCB->SCR |= SCB_SCR_SLEEPDEEP;
221 
222   if(PWR_STOPEntry == PWR_STOPEntry_WFI)
223   {
224     __WFI();
225   }
226   else
227   {
228     __WFE();
229   }
230 
231   SCB->SCR &= (uint32_t)~((uint32_t)SCB_SCR_SLEEPDEEP);
232 }
233 
234 
235 /*******************************************************************************
236 * Function Name  : PWR_EnterSTOPMode_RAM_LV
237 * Description    : Enters STOP mode with RAM data retention function and LV mode on.
238 * Input          : PWR_Regulator: specifies the regulator state in STOP mode.
239 *                    PWR_Regulator_ON: STOP mode with regulator ON
240 *                    PWR_Regulator_LowPower: STOP mode with regulator in low power mode
241 *                  PWR_STOPEntry: specifies if STOP mode in entered with WFI or WFE instruction.
242 *                    PWR_STOPEntry_WFI: enter STOP mode with WFI instruction
243 *                    PWR_STOPEntry_WFE: enter STOP mode with WFE instruction
244 * Return         : None
245 *******************************************************************************/
PWR_EnterSTOPMode_RAM_LV(uint32_t PWR_Regulator,uint8_t PWR_STOPEntry)246 void PWR_EnterSTOPMode_RAM_LV(uint32_t PWR_Regulator, uint8_t PWR_STOPEntry)
247 {
248   uint32_t tmpreg = 0;
249   tmpreg = PWR->CTLR;
250   tmpreg &= CTLR_DS_MASK;
251   tmpreg |= PWR_Regulator;
252 
253   //2K+30K in standby w power.
254   tmpreg |= ((uint32_t)1<<16)|((uint32_t)1<<17);
255   //LV bit on.
256   tmpreg |= ((uint32_t)1<<20);
257 
258   PWR->CTLR = tmpreg;
259   SCB->SCR |= SCB_SCR_SLEEPDEEP;
260 
261   if(PWR_STOPEntry == PWR_STOPEntry_WFI)
262   {
263     __WFI();
264   }
265   else
266   {
267     __WFE();
268   }
269 
270   SCB->SCR &= (uint32_t)~((uint32_t)SCB_SCR_SLEEPDEEP);
271 }
272 
273 
274 /*******************************************************************************
275 * Function Name  : PWR_EnterSTANDBYMode_RAM
276 * Description    : Enters STANDBY mode with RAM data retention function on.
277 * Input          : None
278 * Return         : None
279 *******************************************************************************/
PWR_EnterSTANDBYMode_RAM(void)280 void PWR_EnterSTANDBYMode_RAM(void)
281 {
282 	uint32_t tmpreg = 0;
283 	tmpreg = PWR->CTLR;
284 
285 	tmpreg |= PWR_CTLR_CWUF;
286 	tmpreg |= PWR_CTLR_PDDS;
287 
288 	//2K+30K in standby w power.
289 	tmpreg |= ((uint32_t)1<<16)|((uint32_t)1<<17);
290 
291 	PWR->CTLR = tmpreg;
292 
293   SCB->SCR |= SCB_SCR_SLEEPDEEP;
294 #if defined ( __CC_ARM   )
295   __force_stores();
296 #endif
297   __WFI();
298 }
299 
300 
301 /*******************************************************************************
302 * Function Name  : PWR_EnterSTANDBYMode_RAM_LV
303 * Description    : Enters STANDBY mode with RAM data retention function and LV mode on.
304 * Input          : None
305 * Return         : None
306 *******************************************************************************/
PWR_EnterSTANDBYMode_RAM_LV(void)307 void PWR_EnterSTANDBYMode_RAM_LV(void)
308 {
309   uint32_t tmpreg = 0;
310   tmpreg = PWR->CTLR;
311 
312   tmpreg |= PWR_CTLR_CWUF;
313   tmpreg |= PWR_CTLR_PDDS;
314 
315   //2K+30K in standby power.
316   tmpreg |= ((uint32_t)1<<16)|((uint32_t)1<<17);
317   //2K+30K in standby LV .
318   tmpreg |= ((uint32_t)1<<20);
319 
320   PWR->CTLR = tmpreg;
321 
322   SCB->SCR |= SCB_SCR_SLEEPDEEP;
323 #if defined ( __CC_ARM   )
324   __force_stores();
325 #endif
326   __WFI();
327 }
328 
329 
330 
331 
332