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