1 /*!
2  * @file        apm32f4xx_pmu.c
3  *
4  * @brief       This file provides all the PMU firmware functions.
5  *
6  * @version     V1.0.2
7  *
8  * @date        2022-06-23
9  *
10  * @attention
11  *
12  *  Copyright (C) 2021-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 usefull 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 "apm32f4xx_pmu.h"
27 #include "apm32f4xx_rcm.h"
28 
29 /** @addtogroup APM32F4xx_StdPeriphDriver
30   @{
31 */
32 
33 /** @defgroup PMU_Driver
34   * @brief PMU driver modules
35   @{
36 */
37 
38 /** @defgroup PMU_Functions
39   @{
40 */
41 
42 /*!
43  * @brief     Reset the PMU peripheral register.
44  *
45  * @param     None
46  *
47  * @retval    None
48  */
PMU_Reset(void)49 void PMU_Reset(void)
50 {
51     RCM_EnableAPB1PeriphReset(RCM_APB1_PERIPH_PMU);
52     RCM_DisableAPB1PeriphReset(RCM_APB1_PERIPH_PMU);
53 }
54 
55 /*!
56  * @brief     Enables access to the RTC and backup registers.
57  *
58  * @param     None
59  *
60  * @retval    None
61  */
PMU_EnableBackupAccess(void)62 void PMU_EnableBackupAccess(void)
63 {
64     PMU->CTRL_B.BPWEN = ENABLE;
65 }
66 
67 /*!
68  * @brief     Disables access to the RTC and backup registers.
69  *
70  * @param     None
71  *
72  * @retval    None
73  */
PMU_DisableBackupAccess(void)74 void PMU_DisableBackupAccess(void)
75 {
76     PMU->CTRL_B.BPWEN = DISABLE;
77 }
78 
79 /*!
80  * @brief     Enables the Power Voltage Detector(PVD).
81  *
82  * @param     None
83  *
84  * @retval    None
85  */
PMU_EnablePVD(void)86 void PMU_EnablePVD(void)
87 {
88     PMU->CTRL_B.PVDEN = ENABLE;
89 }
90 
91 /*!
92  * @brief     Disables the Power Voltage Detector(PVD).
93  *
94  * @param     None
95  *
96  * @retval    None
97  */
PMU_DisablePVD(void)98 void PMU_DisablePVD(void)
99 {
100     PMU->CTRL_B.PVDEN = DISABLE;
101 }
102 
103 /*!
104  * @brief    Configures the voltage threshold detected by the Power Voltage Detector(PVD).
105  *
106  * @param    level: specifies the PVD detection level
107  *           This parameter can be one of the following values:
108  *              @arg PMU_PVD_LEVEL_2V0 : Config PVD detection level to 2.0V
109  *              @arg PMU_PVD_LEVEL_2V1 : Config PVD detection level to 2.1V
110  *              @arg PMU_PVD_LEVEL_2V3 : Config PVD detection level to 2.3V
111  *              @arg PMU_PVD_LEVEL_2V5 : Config PVD detection level to 2.5V
112  *              @arg PMU_PVD_LEVEL_2V6 : Config PVD detection level to 2.6V
113  *              @arg PMU_PVD_LEVEL_2V7 : Config PVD detection level to 2.7V
114  *              @arg PMU_PVD_LEVEL_2V8 : Config PVD detection level to 2.8V
115  *              @arg PMU_PVD_LEVEL_2V9 : Config PVD detection level to 2.9V
116  *
117  * @retval   None
118  */
PMU_ConfigPVDLevel(PMU_PVD_LEVEL_T level)119 void PMU_ConfigPVDLevel(PMU_PVD_LEVEL_T level)
120 {
121     PMU->CTRL_B.PLSEL = 0;
122     PMU->CTRL_B.PLSEL = level;
123 }
124 
125 /*!
126  * @brief     Enables the WakeUp Pin functionality.
127  *
128  * @param     None
129  *
130  * @retval    None
131  */
PMU_EnableWakeUpPin(void)132 void PMU_EnableWakeUpPin(void)
133 {
134     PMU->CSTS_B.WKUPCFG = ENABLE;
135 }
136 
137 /*!
138  * @brief     Diaables the WakeUp Pin functionality.
139  *
140  * @param     None
141  *
142  * @retval    None
143  */
PMU_DisableWakeUpPin(void)144 void PMU_DisableWakeUpPin(void)
145 {
146     PMU->CSTS_B.WKUPCFG = DISABLE;
147 }
148 
149 /*!
150  * @brief     Enables the Backup Regulator.
151  *
152  * @param     None
153  *
154  * @retval    None
155  */
PMU_EnableBackupRegulator(void)156 void PMU_EnableBackupRegulator(void)
157 {
158     PMU->CSTS_B.BKPREN = ENABLE;
159 }
160 
161 /*!
162  * @brief     Diaables the Backup Regulator.
163  *
164  * @param     None
165  *
166  * @retval    None
167  */
PMU_DisableBackupRegulator(void)168 void PMU_DisableBackupRegulator(void)
169 {
170     PMU->CSTS_B.BKPREN = DISABLE;
171 }
172 
173 /*!
174  * @brief     Configures the main internal regulator output voltage.
175  *
176  * @param     scale: This parameter can be one of the following values:
177  *               @arg PMU_REGULATOR_VOLTAGE_SCALE1 : Select regulator voltage scale 1
178  *               @arg PMU_REGULATOR_VOLTAGE_SCALE2 : Select regulator voltage scale 2
179  *
180  * @retval    None
181  */
PMU_ConfigMainRegulatorMode(PMU_REGULATOR_VOLTAGE_SCALE_T scale)182 void PMU_ConfigMainRegulatorMode(PMU_REGULATOR_VOLTAGE_SCALE_T scale)
183 {
184     PMU->CTRL_B.VOSSEL = 0;
185     PMU->CTRL_B.VOSSEL = scale;
186 }
187 
188 /*!
189  * @brief     Enables the Flash Power Down in STOP mode.
190  *
191  * @param     None
192  *
193  * @retval    None
194  */
PMU_EnableFlashPowerDown(void)195 void PMU_EnableFlashPowerDown(void)
196 {
197     PMU->CTRL_B.FPDSM = ENABLE ;
198 }
199 
200 /*!
201  * @brief     Diaables the Flash Power Down in STOP mode.
202  *
203  * @param     None
204  *
205  * @retval    None
206  */
PMU_DisableFlashPowerDown(void)207 void PMU_DisableFlashPowerDown(void)
208 {
209     PMU->CTRL_B.FPDSM = DISABLE ;
210 }
211 
212 /*!
213  * @brief     Enters STOP mode.
214  *
215  * @param     regulator: specifies the regulator state in STOP mode.
216  *            This parameter can be one of the following values:
217  *              @arg PMU_REGULATOR_ON        : STOP mode with regulator ON
218  *              @arg PMU_REGULATOR_LOWPOWER  : STOP mode with regulator in low power mode
219  *
220  * @param     entry: specifies if STOP mode in entered with WFI or WFE instruction.
221  *            This parameter can be one of the following values:
222  *              @arg PMU_STOP_ENTRY_WFI: Enter STOP mode with WFI instruction
223  *              @arg PMU_STOP_ENTRY_WFE: Enter STOP mode with WFE instruction
224  *
225  * @retval    None
226  */
PMU_EnterSTOPMode(PMU_REGULATOR_T regulator,PMU_STOP_ENTRY_T entry)227 void PMU_EnterSTOPMode(PMU_REGULATOR_T regulator, PMU_STOP_ENTRY_T entry)
228 {
229     /* Clear PDDSCFG and LPDSCFG bits */
230     PMU->CTRL_B.PDDSCFG = 0x00;
231     PMU->CTRL_B.LPDSCFG = 0x00;
232     /* Set LPDSCFG bit according to regulator value */
233     PMU->CTRL_B.LPDSCFG = regulator;
234     /* Set Cortex System Control Register */
235     SCB->SCR |= (uint32_t)0x04;
236     /* Select STOP mode entry*/
237     if (entry == PMU_STOP_ENTRY_WFI)
238     {
239         /* Request Wait For Interrupt */
240         __WFI();
241     }
242     else
243     {
244         /* Request Wait For Event */
245         __WFE();
246     }
247 
248     /* Reset SLEEPDEEP bit of Cortex System Control Register */
249     SCB->SCR &= (uint32_t)~((uint32_t)0x04);
250 }
251 
252 /*!
253  * @brief     Enters STANDBY mode.
254  *
255  * @param     None
256  *
257  * @retval    None
258  */
PMU_EnterSTANDBYMode(void)259 void PMU_EnterSTANDBYMode(void)
260 {
261     /* Select STANDBY mode */
262     PMU->CTRL_B.PDDSCFG = BIT_SET;
263     /* Set SLEEPDEEP bit of Cortex System Control Register */
264     SCB->SCR |= (uint32_t)0x04;
265 #if defined ( __CC_ARM   )
266     __force_stores();
267 #endif
268     /* Request Wait For Interrupt */
269     __WFI();
270 
271 }
272 
273 /*!
274  * @brief     Read the specified PMU flag is set or not.
275  *
276  * @param     flag: Reads the status of specifies the flag.
277  *                  This parameter can be one of the following values:
278  *                    @arg PMU_FLAG_WUE : Wake Up flag.
279  *                    @arg PMU_FLAG_SB  : StandBy flag.
280  *                    @arg PMU_FLAG_PVDO: PVD Output.
281  *                    @arg PMU_FLAG_BKPR: Backup regulator ready flag.
282  *                    @arg PMU_FLAG_VOSR: This flag indicates that the Regulator voltage
283  *                         scaling output selection is ready.
284  *
285  * @retval    The new state of PMU_FLAG (SET or RESET).
286  */
PMU_ReadStatusFlag(PMU_FLAG_T flag)287 uint8_t PMU_ReadStatusFlag(PMU_FLAG_T flag)
288 {
289     uint8_t BitStatus = BIT_RESET;
290 
291     if (flag == PMU_FLAG_WUE)
292     {
293         BitStatus = PMU->CSTS_B.WUEFLG;
294     }
295     else if (flag == PMU_FLAG_SB)
296     {
297         BitStatus = PMU->CSTS_B.SBFLG;
298     }
299     else if (flag == PMU_FLAG_PVDO)
300     {
301         BitStatus = PMU->CSTS_B.PVDOFLG;
302     }
303     else if (flag == PMU_FLAG_BKPR)
304     {
305         BitStatus = PMU->CSTS_B.BKPRFLG;
306     }
307     else if (flag == PMU_FLAG_VOSR)
308     {
309         BitStatus = PMU->CSTS_B.VOSRFLG;
310     }
311 
312     return BitStatus;
313 }
314 
315 /*!
316  * @brief     Clears the PMU's pending flags.
317  *
318  * @param     flag: specifies the flag to clear.
319  *            This parameter can be one of the following values:
320  *              @arg PMU_FLAG_WUE : Wake Up flag.
321  *              @arg PMU_FLAG_SB  : StandBy flag.
322  *
323  * @retval    None
324  */
PMU_ClearStatusFlag(PMU_FLAG_T flag)325 void PMU_ClearStatusFlag(PMU_FLAG_T flag)
326 {
327     if (flag == PMU_FLAG_WUE)
328     {
329         PMU->CTRL_B.WUFLGCLR = BIT_SET;
330     }
331     else if (flag == PMU_FLAG_SB)
332     {
333         PMU->CTRL_B.SBFLGCLR = BIT_SET;
334     }
335 }
336 
337 /**@} end of group PMU_Functions */
338 /**@} end of group PMU_Driver */
339 /**@} end of group APM32F4xx_StdPeriphDriver */
340