1 /*!
2  * @file       apm32e10x_pmu.c
3  *
4  * @brief      This file provides all the PMU firmware functions.
5  *
6  * @version     V1.0.2
7  *
8  * @date        2022-12-31
9  *
10  * @attention
11  *
12  *  Copyright (C) 2021-2023 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 "apm32e10x_pmu.h"
27 #include "apm32e10x_rcm.h"
28 
29 /** @addtogroup APM32E10x_StdPeriphDriver
30   @{
31 */
32 
33 /** @addtogroup PMU_Driver
34   * @brief PMU driver modules
35   @{
36 */
37 
38 /** @defgroup  PMU_Functions 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     Configure a voltage threshold detected by a power supply 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_2V2 : Config PVD detection level to 2.2V
109  *                   @arg PMU_PVD_LEVEL_2V3 : Config PVD detection level to 2.3V
110  *                   @arg PMU_PVD_LEVEL_2V4 : Config PVD detection level to 2.4V
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 
122     /* Clear PLS[7:5] bits */
123     PMU->CTRL_B.PLSEL = 0x0000;
124     /* Store the new value */
125     PMU->CTRL_B.PLSEL = level;
126 }
127 
128 /*!
129  * @brief     Enables the WakeUp Pin functionality.
130  *
131  * @param     None
132  *
133  * @retval    None
134  */
PMU_EnableWakeUpPin(void)135 void PMU_EnableWakeUpPin(void)
136 {
137     PMU->CSTS_B.WKUPCFG = ENABLE ;
138 }
139 
140 /*!
141  * @brief     Diaables the WakeUp Pin functionality.
142  *
143  * @param     None
144  *
145  * @retval    None
146  */
PMU_DisableWakeUpPin(void)147 void PMU_DisableWakeUpPin(void)
148 {
149     PMU->CSTS_B.WKUPCFG = DISABLE ;
150 }
151 
152 /*!
153  * @brief     Enters STOP mode.
154  *
155  * @param     regulator: specifies the regulator state in STOP mode.
156  *                       This parameter can be one of the following values:
157  *                         @arg PMU_REGULATOR_ON      : STOP mode with regulator ON
158  *                         @arg PMU_REGULATOR_LOWPOWER: STOP mode with regulator in low power mode
159  *
160  * @param     entry: specifies if STOP mode in entered with WFI or WFE instruction.
161  *                   This parameter can be one of the following values:
162  *                     @arg PMU_STOP_ENTRY_WFI: Enter STOP mode with WFI instruction
163  *                     @arg PMU_STOP_ENTRY_WFE: Enter STOP mode with WFE instruction
164  *
165  * @retval    None
166  */
PMU_EnterSTOPMode(PMU_REGULATOR_T regulator,PMU_STOP_ENTRY_T entry)167 void PMU_EnterSTOPMode(PMU_REGULATOR_T regulator, PMU_STOP_ENTRY_T entry)
168 {
169     /** Clear PDDSCFG and LPDSCFG bits */
170     PMU->CTRL_B.PDDSCFG = 0x00;
171     PMU->CTRL_B.LPDSCFG = 0x00;
172     /** Set LPDSCFG bit according to regulator value */
173     PMU->CTRL_B.LPDSCFG = regulator;
174     /** Set Cortex System Control Register */
175     SCB->SCR |= (uint32_t )0x04;
176     /** Select STOP mode entry*/
177     if(entry == PMU_STOP_ENTRY_WFI)
178     {
179         /** Request Wait For Interrupt */
180         __WFI();
181     }
182     else
183     {
184         /** Request Wait For Event */
185         __WFE();
186     }
187 
188     /** Reset SLEEPDEEP bit of Cortex System Control Register */
189     SCB->SCR &= (uint32_t)~((uint32_t)0x04);
190 
191 }
192 
193 /*!
194  * @brief     Enters STANDBY mode.
195  *
196  * @param     None
197  *
198  * @retval    None
199  */
PMU_EnterSTANDBYMode(void)200 void PMU_EnterSTANDBYMode(void)
201 {
202     /* Clear Wake-up flag */
203     PMU->CTRL_B.WUFLGCLR = BIT_SET;
204     /* Select STANDBY mode */
205     PMU->CTRL_B.PDDSCFG = BIT_SET;
206     /* Set Cortex System Control Register */
207     SCB->SCR |= (uint32_t )0x04;
208 #if defined ( __CC_ARM   )
209     __force_stores();
210 #endif
211     /* Request Wait For Interrupt */
212     __WFI();
213 
214 }
215 
216 /*!
217  * @brief     Read the specified PWR flag is set or not.
218  *
219  * @param     flag: Reads the status of specifies the flag.
220  *                  This parameter can be one of the following values:
221  *                    @arg PMU_FLAG_WUE : Wake Up flag
222  *                    @arg PMU_FLAG_SB  : StandBy flag
223  *                    @arg PMU_FLAG_PVDO: PVD Output flag
224  *
225  * @retval    The new state of PMU_FLAG (SET or RESET).
226  */
PMU_ReadStatusFlag(PMU_FLAG_T flag)227 uint8_t PMU_ReadStatusFlag(PMU_FLAG_T flag)
228 {
229     uint8_t BitStatus = BIT_RESET;
230 
231     if(flag == PMU_FLAG_WUE)
232     {
233         BitStatus = PMU->CSTS_B.WUEFLG;
234     }
235     else if(flag == PMU_FLAG_SB)
236     {
237         BitStatus = PMU->CSTS_B.SBFLG;
238     }
239     else if(flag == PMU_FLAG_PVDO)
240     {
241         BitStatus = PMU->CSTS_B.PVDOFLG;
242     }
243     return BitStatus;
244 }
245 
246 /*!
247  * @brief     Clears the PWR's pending flags.
248  *
249  * @param     flag: Clears the status of specifies the flag.
250  *                  This parameter can be one of the following values:
251  *                    @arg PMU_FLAG_WUE : Wake Up flag
252  *                    @arg PMU_FLAG_SB  : StandBy flag
253  *
254  * @retval    None
255  */
PMU_ClearStatusFlag(PMU_FLAG_T flag)256 void PMU_ClearStatusFlag(PMU_FLAG_T flag)
257 {
258     if(flag == PMU_FLAG_WUE)
259     {
260         PMU->CTRL_B.WUFLGCLR = BIT_SET;
261     }
262     else if(flag == PMU_FLAG_SB)
263     {
264         PMU->CTRL_B.SBFLGCLR = BIT_SET;
265     }
266 }
267 
268 /**@} end of group PMU_Functions */
269 /**@} end of group PMU_Driver */
270 /**@} end of group APM32E10x_StdPeriphDriver */
271