1 /*!
2  * @file        apm32f0xx_pmu.c
3  *
4  * @brief       This file contains all the functions for the PMU peripheral
5  *
6  * @version     V1.0.3
7  *
8  * @date        2022-09-20
9  *
10  * @attention
11  *
12  *  Copyright (C) 2020-2022 Geehy Semiconductor
13  *
14  *  You may not use this file except in compliance with the
15  *  GEEHY COPYRIGHT NOTICE (GEEHY SOFTWARE PACKAGE LICENSE).
16  *
17  *  The program is only for reference, which is distributed in the hope
18  *  that it will be useful and instructional for customers to develop
19  *  their software. Unless required by applicable law or agreed to in
20  *  writing, the program is distributed on an "AS IS" BASIS, WITHOUT
21  *  ANY WARRANTY OR CONDITIONS OF ANY KIND, either express or implied.
22  *  See the GEEHY SOFTWARE PACKAGE LICENSE for the governing permissions
23  *  and limitations under the License.
24  */
25 
26 #include "apm32f0xx_pmu.h"
27 #include "apm32f0xx_rcm.h"
28 
29 /** @addtogroup APM32F0xx_StdPeriphDriver
30   @{
31 */
32 
33 /** @addtogroup PMU_Driver  PMU Driver
34   @{
35 */
36 
37 /** @defgroup PMU_Macros Macros
38   @{
39 */
40 
41 /**@} end of group PMU_Macros*/
42 
43 /** @defgroup PMU_Enumerations Enumerations
44   @{
45 */
46 
47 /**@} end of group PMU_Enumerations*/
48 
49 /** @defgroup PMU_Structures Structures
50   @{
51 */
52 
53 /**@} end of group PMU_Structures*/
54 
55 /** @defgroup PMU_Variables Variables
56   @{
57 */
58 
59 /**@} end of group PMU_Variables*/
60 
61 /** @defgroup  PMU_Functions Functions
62   @{
63 */
64 
65 /*!
66  * @brief   Resets the PWR peripheral registers to their default reset values
67  *
68  * @param   None
69  *
70  * @retval  None
71  */
PMU_Reset(void)72 void PMU_Reset(void)
73 {
74     RCM_EnableAPB1PeriphClock(RCM_APB1_PERIPH_PMU);
75     RCM_DisableAPB1PeriphClock(RCM_APB1_PERIPH_PMU);
76 }
77 
78 /*!
79  * @brief   Enables access to the Backup domain registers
80  *
81  * @param   None
82  *
83  * @retval  None
84  */
PMU_EnableBackupAccess(void)85 void PMU_EnableBackupAccess(void)
86 {
87     PMU->CTRL_B.BPWEN = BIT_SET;
88 }
89 
90 /*!
91  * @brief   Disables access to the Backup domain registers
92  *
93  * @param   None
94  *
95  * @retval  None
96  */
PMU_DisableBackupAccess(void)97 void PMU_DisableBackupAccess(void)
98 {
99     PMU->CTRL_B.BPWEN = BIT_RESET;
100 }
101 
102 /*!
103  * @brief   Configures the PMU PVD Level
104  *
105  * @param   level: specifies the PVD Level
106  *                 This parameter can be one of the following values
107  *                 @arg PMU_PVDLEVEL_0
108  *                 @arg PMU_PVDLEVEL_1
109  *                 @arg PMU_PVDLEVEL_2
110  *                 @arg PMU_PVDLEVEL_3
111  *                 @arg PMU_PVDLEVEL_4
112  *                 @arg PMU_PVDLEVEL_5
113  *                 @arg PMU_PVDLEVEL_6
114  *                 @arg PMU_PVDLEVEL_7
115  *
116  * @retval  None
117  *
118  * @note    It's not for APM32F030 devices
119  */
PMU_ConfigPVDLevel(PMU_PVDLEVEL_T level)120 void PMU_ConfigPVDLevel(PMU_PVDLEVEL_T level)
121 {
122     PMU->CTRL_B.PLSEL = level;
123 }
124 
125 /*!
126  * @brief   Enables Power voltage detector
127  *
128  * @param   None
129  *
130  * @retval  None
131  *
132  * @note    It's not for APM32F030 devices
133  */
PMU_EnablePVD(void)134 void PMU_EnablePVD(void)
135 {
136     PMU->CTRL_B.PVDEN = BIT_SET;
137 }
138 /*!
139  * @brief   Disables Power voltage detector
140  *
141  * @param   None
142  *
143  * @retval  None
144  *
145  * @note    It's not for APM32F030 devices
146  */
PMU_DisablePVD(void)147 void PMU_DisablePVD(void)
148 {
149     PMU->CTRL_B.PVDEN = BIT_RESET;
150 }
151 
152 /*!
153  * @brief   Enables the WakeUp Pin functionality
154  *
155  * @param   pin: specifies the WakeUpPin
156  *               This parameter can be one of the following values
157  *               @arg PMU_WAKEUPPIN_1
158  *               @arg PMU_WAKEUPPIN_2
159  *               @arg PMU_WAKEUPPIN_3 It's Only for APM32F072/091 devices
160  *               @arg PMU_WAKEUPPIN_4 It's Only for APM32F072/091 devices
161  *               @arg PMU_WAKEUPPIN_5 It's Only for APM32F072/091 devices
162  *               @arg PMU_WAKEUPPIN_6 It's Only for APM32F072/091 devices
163  *               @arg PMU_WAKEUPPIN_7 It's Only for APM32F072/091 devices
164  *               @arg PMU_WAKEUPPIN_8 It's Only for APM32F072/091 devices
165  *
166  * @retval  None
167  */
PMU_EnableWakeUpPin(PMU_WAKEUPPIN_T pin)168 void PMU_EnableWakeUpPin(PMU_WAKEUPPIN_T pin)
169 {
170     PMU->CSTS |= pin;
171 }
172 
173 /*!
174  * @brief   DIsable the WakeUp Pin functionality
175  *
176  * @param   pin: specifies the WakeUpPin
177  *               This parameter can be one of the following values
178  *               @arg PMU_WAKEUPPIN_1
179  *               @arg PMU_WAKEUPPIN_2
180  *               @arg PMU_WAKEUPPIN_3 It's Only for APM32F072/091 devices
181  *               @arg PMU_WAKEUPPIN_4 It's Only for APM32F072/091 devices
182  *               @arg PMU_WAKEUPPIN_5 It's Only for APM32F072/091 devices
183  *               @arg PMU_WAKEUPPIN_6 It's Only for APM32F072/091 devices
184  *               @arg PMU_WAKEUPPIN_7 It's Only for APM32F072/091 devices
185  *               @arg PMU_WAKEUPPIN_8 It's Only for APM32F072/091 devices
186  *
187  * @retval  None
188  */
PMU_DisableWakeUpPin(PMU_WAKEUPPIN_T pin)189 void PMU_DisableWakeUpPin(PMU_WAKEUPPIN_T pin)
190 {
191     PMU->CSTS &= ~pin;
192 }
193 
194 /*!
195  * @brief   Enters Sleep mode
196  *
197  * @param   entry :specifies if SLEEP mode in entered with WFI or WFE instruction
198  *                 This parameter can be one of the following values:
199  *                 @arg PMU_SLEEPENTRY_WFI: enter SLEEP mode with WFI instruction
200  *                 @arg PMU_SLEEPENTRY_WFE: enter SLEEP mode with WFE instruction
201  *
202  * @retval  None
203  */
PMU_EnterSleepMode(PMU_SLEEPENTRY_T entry)204 void PMU_EnterSleepMode(PMU_SLEEPENTRY_T entry)
205 {
206     SCB->SCR &= (uint32_t)~((uint32_t)SCB_SCR_SLEEPDEEP_Msk);
207 
208     if (entry == PMU_SLEEPENTRY_WFI)
209     {
210         __WFI();
211     }
212     else
213     {
214         __SEV();
215         __WFE();
216         __WFE();
217     }
218 }
219 
220 /*!
221  * @brief   Enters STOP mode
222  *
223  * @param   regulator: specifies the regulator state in STOP mode
224  *                     This parameter can be one of the following values:
225  *                     @arg PMU_REGULATOR_ON: STOP mode with regulator ON
226  *                     @arg PMU_REGULATOR_LowPower: STOP mode with regulator in low power mode
227  *
228  * @param   entry:     specifies if STOP mode in entered with WFI or WFE instruction
229  *                     This parameter can be one of the following values:
230  *                     @arg PMU_STOPENTRY_WFI: enter STOP mode with WFI instruction
231  *                     @arg PMU_STOPENTRY_WFE: enter STOP mode with WFE instruction
232  *                     @arg PMU_STOPENTRY_SLEEPONEXIT: enter STOP mode with SLEEPONEXIT instruction
233  *
234  * @retval  None
235  */
PMU_EnterSTOPMode(PMU_REGULATOR_T regulator,PMU_STOPENTRY_T entry)236 void PMU_EnterSTOPMode(PMU_REGULATOR_T regulator, PMU_STOPENTRY_T entry)
237 {
238     PMU->CTRL_B.PDDSCFG = BIT_RESET;
239 
240     PMU->CTRL_B.LPDSCFG = regulator;
241 
242     SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
243 
244     switch (entry)
245     {
246         case PMU_STOPENTRY_WFI:
247 
248             __WFI();
249             SCB->SCR &= (uint32_t)~((uint32_t)SCB_SCR_SLEEPDEEP_Msk);
250             break;
251 
252         case  PMU_STOPENTRY_WFE:
253             __WFE();
254             SCB->SCR &= (uint32_t)~((uint32_t)SCB_SCR_SLEEPDEEP_Msk);
255             break;
256 
257         case PMU_STOPENTRY_SLEEPONEXIT:
258             SCB->SCR |= SCB_SCR_SLEEPONEXIT_Msk;
259             break;
260 
261         default:
262             break;
263     }
264 }
265 
266 /*!
267  * @brief   Enters STANDBY mode
268  *
269  * @param   None
270  *
271  * @retval  None
272  */
PMU_EnterSTANDBYMode(void)273 void PMU_EnterSTANDBYMode(void)
274 {
275     PMU->CTRL_B.PDDSCFG = BIT_SET;
276 
277     SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
278 
279     __WFI();
280 }
281 
282 /*!
283  * @brief   Checks whether the specified PMU flag is set or not
284  *
285  * @param   flag: specifies the flag to check
286  *                This parameter can be one of the following values:
287  *                @arg PMU_FLAG_WUPF: Wake Up flag
288  *                @arg PMU_FLAG_STDBYF: StandBy flag
289  *                @arg PMU_FLAG_PVDOF: PVD output flag (Not for APM32F030)
290  *                @arg PMU_FLAG_VREFINTF: VREFINT flag
291  *
292  * @retval  The new state of PMU_FLAG (SET or RESET)
293  */
PMU_ReadStatusFlag(PMU_FLAG_T flag)294 uint8_t PMU_ReadStatusFlag(PMU_FLAG_T flag)
295 {
296     uint8_t bit;
297 
298     if ((PMU->CSTS & flag) != (uint32_t)RESET)
299     {
300         bit = SET;
301     }
302     else
303     {
304         bit = RESET;
305     }
306 
307     /** Return the flag status */
308     return bit;
309 }
310 
311 /*!
312  * @brief   Clears the PWR's pending flags
313  *
314  * @param   flag: specifies the flag to clear
315  *                This parameter can be one of the following values:
316  *                @arg PMU_FLAG_WUPF: Wake Up flag
317  *                @arg PMU_FLAG_STDBYF: StandBy flag
318  *
319  * @retval  None
320  */
PMU_ClearStatusFlag(uint8_t flag)321 void PMU_ClearStatusFlag(uint8_t flag)
322 {
323     if (flag == PMU_FLAG_WUPF)
324     {
325         PMU->CTRL_B.WUFLGCLR = BIT_SET;
326     }
327     else if (flag == PMU_FLAG_STDBYF)
328     {
329         PMU->CTRL_B.SBFLGCLR = BIT_SET;
330     }
331 }
332 
333 /**@} end of group PMU_Functions*/
334 /**@} end of group PMU_Driver */
335 /**@} end of group APM32F0xx_StdPeriphDriver*/
336