1 /*****************************************************************************
2 * Copyright (c) 2019, Nations Technologies Inc.
3 *
4 * All rights reserved.
5 * ****************************************************************************
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions are met:
9 *
10 * - Redistributions of source code must retain the above copyright notice,
11 * this list of conditions and the disclaimer below.
12 *
13 * Nations' name may not be used to endorse or promote products derived from
14 * this software without specific prior written permission.
15 *
16 * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY NATIONS "AS IS" AND ANY EXPRESS OR
17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
19 * DISCLAIMED. IN NO EVENT SHALL NATIONS BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
21 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
22 * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
23 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
24 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
25 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 * ****************************************************************************/
27
28 /**
29 * @file n32wb452_pwr.c
30 * @author Nations
31 * @version v1.0.0
32 *
33 * @copyright Copyright (c) 2019, Nations Technologies Inc. All rights reserved.
34 */
35 #include "n32wb452_pwr.h"
36
37 /** @addtogroup N32WB452_StdPeriph_Driver
38 * @{
39 */
40
41 /** @addtogroup PWR
42 * @brief PWR driver modules
43 * @{
44 */
45
46 /** @addtogroup PWR_Private_TypesDefinitions
47 * @{
48 */
49
50 /**
51 * @}
52 */
53
54 /** @addtogroup PWR_Private_Defines
55 * @{
56 */
57
58 /* --------- PWR registers bit address in the alias region ---------- */
59 #define PWR_OFFSET (PWR_BASE - PERIPH_BASE)
60
61 /* --- CTRL Register ---*/
62
63 /* Alias word address of DBKP bit */
64 #define CTRL_OFFSET (PWR_OFFSET + 0x00)
65 #define DBKP_BITN 0x08
66 #define CTRL_DBKP_BB (PERIPH_BB_BASE + (CTRL_OFFSET * 32) + (DBKP_BITN * 4))
67
68 /* Alias word address of PVDEN bit */
69 #define PVDEN_BITN 0x04
70 #define CTRL_PVDEN_BB (PERIPH_BB_BASE + (CTRL_OFFSET * 32) + (PVDEN_BITN * 4))
71
72 /* --- CTRLSTS Register ---*/
73
74 /* Alias word address of WKUPEN bit */
75 #define CTRLSTS_OFFSET (PWR_OFFSET + 0x04)
76 #define WKUPEN_BITN 0x08
77 #define CTRLSTS_WKUPEN_BB (PERIPH_BB_BASE + (CTRLSTS_OFFSET * 32) + (WKUPEN_BITN * 4))
78
79 /* ------------------ PWR registers bit mask ------------------------ */
80
81 /* CTRL register bit mask */
82 #define CTRL_DS_MASK ((uint32_t)0xFFFFFFFC)
83 #define CTRL_PRS_MASK ((uint32_t)0xFFFFFD1F)
84
85 /**
86 * @}
87 */
88
89 /** @addtogroup PWR_Private_Macros
90 * @{
91 */
92
93 /**
94 * @}
95 */
96
97 /** @addtogroup PWR_Private_Variables
98 * @{
99 */
100
101 /**
102 * @}
103 */
104
105 /** @addtogroup PWR_Private_FunctionPrototypes
106 * @{
107 */
108
109 /**
110 * @}
111 */
112
113 /** @addtogroup PWR_Private_Functions
114 * @{
115 */
116
117 /**
118 * @brief Deinitializes the PWR peripheral registers to their default reset values.
119 */
PWR_DeInit(void)120 void PWR_DeInit(void)
121 {
122 RCC_EnableAPB1PeriphReset(RCC_APB1_PERIPH_PWR, ENABLE);
123 RCC_EnableAPB1PeriphReset(RCC_APB1_PERIPH_PWR, DISABLE);
124 }
125
126 /**
127 * @brief Enables or disables access to the RTC and backup registers.
128 * @param Cmd new state of the access to the RTC and backup registers.
129 * This parameter can be: ENABLE or DISABLE.
130 */
PWR_BackupAccessEnable(FunctionalState Cmd)131 void PWR_BackupAccessEnable(FunctionalState Cmd)
132 {
133 /* Check the parameters */
134 assert_param(IS_FUNCTIONAL_STATE(Cmd));
135 *(__IO uint32_t*)CTRL_DBKP_BB = (uint32_t)Cmd;
136 }
137
138 /**
139 * @brief Enables or disables the Power Voltage Detector(PVD).
140 * @param Cmd new state of the PVD.
141 * This parameter can be: ENABLE or DISABLE.
142 */
PWR_PvdEnable(FunctionalState Cmd)143 void PWR_PvdEnable(FunctionalState Cmd)
144 {
145 /* Check the parameters */
146 assert_param(IS_FUNCTIONAL_STATE(Cmd));
147 *(__IO uint32_t*)CTRL_PVDEN_BB = (uint32_t)Cmd;
148 }
149
150 /**
151 * @brief Configures the voltage threshold detected by the Power Voltage Detector(PVD).
152 * @param PWR_PVDLevel specifies the PVD detection level
153 * This parameter can be one of the following values:
154 * @arg PWR_PVDRANGRE_2V2 PVD detection level set to 2.2V
155 * @arg PWR_PVDRANGRE_2V3 PVD detection level set to 2.3V
156 * @arg PWR_PVDRANGRE_2V4 PVD detection level set to 2.4V
157 * @arg PWR_PVDRANGRE_2V5 PVD detection level set to 2.5V
158 * @arg PWR_PVDRANGRE_2V6 PVD detection level set to 2.6V
159 * @arg PWR_PVDRANGRE_2V7 PVD detection level set to 2.7V
160 * @arg PWR_PVDRANGRE_2V8 PVD detection level set to 2.8V
161 * @arg PWR_PVDRANGRE_2V9 PVD detection level set to 2.9V
162 */
PWR_PvdRangeConfig(uint32_t PWR_PVDLevel)163 void PWR_PvdRangeConfig(uint32_t PWR_PVDLevel)
164 {
165 uint32_t tmpregister = 0;
166 /* Check the parameters */
167 assert_param(IS_PWR_PVD_LEVEL(PWR_PVDLevel));
168 tmpregister = PWR->CTRL;
169 /* Clear PRS[7:5] bits */
170 tmpregister &= CTRL_PRS_MASK;
171 /* Set PRS[7:5] bits according to PWR_PVDLevel value */
172 tmpregister |= PWR_PVDLevel;
173 /* Store the new value */
174 PWR->CTRL = tmpregister;
175 }
176
177 /**
178 * @brief Enables or disables the WakeUp Pin functionality.
179 * @param Cmd new state of the WakeUp Pin functionality.
180 * This parameter can be: ENABLE or DISABLE.
181 */
PWR_WakeUpPinEnable(FunctionalState Cmd)182 void PWR_WakeUpPinEnable(FunctionalState Cmd)
183 {
184 /* Check the parameters */
185 assert_param(IS_FUNCTIONAL_STATE(Cmd));
186 *(__IO uint32_t*)CTRLSTS_WKUPEN_BB = (uint32_t)Cmd;
187 }
188
189 /**
190 * @brief Enters SLEEP mode.
191 * @param SLEEPONEXIT specifies the SLEEPONEXIT state in SLEEP mode.
192 * This parameter can be one of the following values:
193 * @arg 0 SLEEP mode with SLEEPONEXIT disable
194 * @arg 1 SLEEP mode with SLEEPONEXIT enable
195 * @param PWR_STOPEntry specifies if SLEEP mode in entered with WFI or WFE instruction.
196 * This parameter can be one of the following values:
197 * @arg PWR_STOPENTRY_WFI enter SLEEP mode with WFI instruction
198 * @arg PWR_STOPENTRY_WFE enter SLEEP mode with WFE instruction
199 */
PWR_EnterSLEEPMode(uint8_t SLEEPONEXIT,uint8_t PWR_STOPEntry)200 void PWR_EnterSLEEPMode(uint8_t SLEEPONEXIT, uint8_t PWR_STOPEntry)
201 {
202 // uint32_t tmpregister = 0;
203 /* Check the parameters */
204 assert_param(IS_PWR_STOP_ENTRY(PWR_STOPEntry));
205
206 /* CLEAR SLEEPDEEP bit of Cortex System Control Register */
207 SCB->SCR &= (uint32_t) ~((uint32_t)SCB_SCR_SLEEPDEEP);
208
209 /* Select SLEEPONEXIT mode entry --------------------------------------------------*/
210 if (SLEEPONEXIT == 1)
211 {
212 /* the MCU enters Sleep mode as soon as it exits the lowest priority INTSTS */
213 SCB->SCR |= SCB_SCR_SLEEPONEXIT;
214 }
215 else if (SLEEPONEXIT == 0)
216 {
217 /* Sleep-now */
218 SCB->SCR &= (uint32_t) ~((uint32_t)SCB_SCR_SLEEPONEXIT);
219 }
220
221 /* Select SLEEP mode entry --------------------------------------------------*/
222 if (PWR_STOPEntry == PWR_STOPENTRY_WFI)
223 {
224 /* Request Wait For Interrupt */
225 __WFI();
226 }
227 else
228 {
229 /* Request Wait For Event */
230 __SEV();
231 __WFE();
232 __WFE();
233 }
234 }
235
236 /**
237 * @brief Enters STOP mode.
238 * @param PWR_Regulator specifies the regulator state in STOP mode.
239 * This parameter can be one of the following values:
240 * @arg PWR_REGULATOR_ON STOP mode with regulator ON
241 * @arg PWR_REGULATOR_LOWPOWER STOP mode with regulator in low power mode
242 * @param PWR_STOPEntry specifies if STOP mode in entered with WFI or WFE instruction.
243 * This parameter can be one of the following values:
244 * @arg PWR_STOPENTRY_WFI enter STOP mode with WFI instruction
245 * @arg PWR_STOPENTRY_WFE enter STOP mode with WFE instruction
246 */
PWR_EnterStopState(uint32_t PWR_Regulator,uint8_t PWR_STOPEntry)247 void PWR_EnterStopState(uint32_t PWR_Regulator, uint8_t PWR_STOPEntry)
248 {
249 uint32_t tmpregister = 0;
250 /* Check the parameters */
251 assert_param(IS_PWR_REGULATOR(PWR_Regulator));
252 assert_param(IS_PWR_STOP_ENTRY(PWR_STOPEntry));
253
254 /* Select the regulator state in STOP mode ---------------------------------*/
255 tmpregister = PWR->CTRL;
256 /* Clear PDS and LPS bits */
257 tmpregister &= CTRL_DS_MASK;
258 /* Set LPS bit according to PWR_Regulator value */
259 tmpregister |= PWR_Regulator;
260 /* Store the new value */
261 PWR->CTRL = tmpregister;
262 /* Set SLEEPDEEP bit of Cortex System Control Register */
263 SCB->SCR |= SCB_SCR_SLEEPDEEP;
264
265 /* Select STOP mode entry --------------------------------------------------*/
266 if (PWR_STOPEntry == PWR_STOPENTRY_WFI)
267 {
268 /* Request Wait For Interrupt */
269 __WFI();
270 }
271 else
272 {
273 /* Request Wait For Event */
274 __SEV();
275 __WFE();
276 __WFE();
277 }
278
279 /* Reset SLEEPDEEP bit of Cortex System Control Register */
280 SCB->SCR &= (uint32_t) ~((uint32_t)SCB_SCR_SLEEPDEEP);
281 }
282
283 /**
284 * @brief Enters STOP2 mode.
285 * @param PWR_STOPEntry specifies if STOP2 mode in entered with WFI or WFE instruction.
286 * This parameter can be one of the following values:
287 * @arg PWR_STOPENTRY_WFI enter STOP2 mode with WFI instruction
288 * @arg PWR_STOPENTRY_WFE enter STOP2 mode with WFE instruction
289 */
PWR_EnterSTOP2Mode(uint8_t PWR_STOPEntry)290 void PWR_EnterSTOP2Mode(uint8_t PWR_STOPEntry)
291 {
292 uint32_t tmpregister = 0;
293 /* Check the parameters */
294 assert_param(IS_PWR_STOP_ENTRY(PWR_STOPEntry));
295
296 /* Select the regulator state in STOP2 mode ---------------------------------*/
297 tmpregister = PWR->CTRL;
298 /* Clear PDS and LPS bits */
299 tmpregister &= CTRL_DS_MASK;
300 /* Store the new value */
301 PWR->CTRL = tmpregister;
302 /*STOP2 sleep mode control-stop2s*/
303 PWR->CTRL2 |= PWR_CTRL2_STOP2S;
304 /* Set SLEEPDEEP bit of Cortex System Control Register */
305 SCB->SCR |= SCB_SCR_SLEEPDEEP;
306 // PWR_CTRL2.BIT0 STOP2S need?
307 /* Select STOP mode entry --------------------------------------------------*/
308 if (PWR_STOPEntry == PWR_STOPENTRY_WFI)
309 {
310 /* Request Wait For Interrupt */
311 __WFI();
312 }
313 else
314 {
315 /* Request Wait For Event */
316 __SEV();
317 __WFE();
318 __WFE();
319 }
320
321 /* Reset SLEEPDEEP bit of Cortex System Control Register */
322 SCB->SCR &= (uint32_t) ~((uint32_t)SCB_SCR_SLEEPDEEP);
323 }
324
325 /**
326 * @brief Enters STANDBY mode.
327 */
PWR_EnterStandbyState(void)328 void PWR_EnterStandbyState(void)
329 {
330 /* Clear Wake-up flag */
331 PWR->CTRL |= PWR_CTRL_CWKUP;
332 /* Clear PDS and LPS bits */
333 PWR->CTRL &= CTRL_DS_MASK;
334 /* Select STANDBY mode */
335 PWR->CTRL |= PWR_CTRL_PDS;
336 /* Set SLEEPDEEP bit of Cortex System Control Register */
337 SCB->SCR |= SCB_SCR_SLEEPDEEP;
338 /* This option is used to ensure that store operations are completed */
339 #if defined(__CC_ARM)
340 __force_stores();
341 #endif
342 /* Request Wait For Interrupt */
343 __WFI();
344 }
345
346 /**
347 * @brief Checks whether the specified PWR flag is set or not.
348 * @param PWR_FLAG specifies the flag to check.
349 * This parameter can be one of the following values:
350 * @arg PWR_WU_FLAG Wake Up flag
351 * @arg PWR_SB_FLAG StandBy flag
352 * @arg PWR_PVDO_FLAG PVD Output
353 * @arg PWR_VBATF_FLAG VBAT flag
354 * @return The new state of PWR_FLAG (SET or RESET).
355 */
PWR_GetFlagStatus(uint32_t PWR_FLAG)356 FlagStatus PWR_GetFlagStatus(uint32_t PWR_FLAG)
357 {
358 FlagStatus bitstatus = RESET;
359 /* Check the parameters */
360 assert_param(IS_PWR_GET_FLAG(PWR_FLAG));
361
362 if ((PWR->CTRLSTS & PWR_FLAG) != (uint32_t)RESET)
363 {
364 bitstatus = SET;
365 }
366 else
367 {
368 bitstatus = RESET;
369 }
370 /* Return the flag status */
371 return bitstatus;
372 }
373
374 /**
375 * @brief Clears the PWR's pending flags.
376 * @param PWR_FLAG specifies the flag to clear.
377 * This parameter can be one of the following values:
378 * @arg PWR_WU_FLAG Wake Up flag
379 * @arg PWR_SB_FLAG StandBy and VBAT flag
380 */
PWR_ClearFlag(uint32_t PWR_FLAG)381 void PWR_ClearFlag(uint32_t PWR_FLAG)
382 {
383 /* Check the parameters */
384 assert_param(IS_PWR_CLEAR_FLAG(PWR_FLAG));
385
386 PWR->CTRL |= PWR_FLAG << 2;
387 }
388
389 /**
390 * @}
391 */
392
393 /**
394 * @}
395 */
396
397 /**
398 * @}
399 */
400