1 /*****************************************************************************
2 * Copyright (c) 2022, 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 n32g43x_pwr.c
30 * @author Nations
31 * @version v1.2.0
32 *
33 * @copyright Copyright (c) 2022, Nations Technologies Inc. All rights reserved.
34 */
35 #include "n32g43x_pwr.h"
36
37 /** @addtogroup N32G43x_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
82 void SetSysClock_MSI(void);
83 /**
84 * @}
85 */
86
87 /** @addtogroup PWR_Private_Macros
88 * @{
89 */
90
91 /**
92 * @}
93 */
94
95 /** @addtogroup PWR_Private_Variables
96 * @{
97 */
98
99 /**
100 * @}
101 */
102
103 /** @addtogroup PWR_Private_FunctionPrototypes
104 * @{
105 */
106
107 /**
108 * @}
109 */
110
111 /** @addtogroup PWR_Private_Functions
112 * @{
113 */
114
115 /**
116 * @brief Deinitializes the PWR peripheral registers to their default reset values.
117 */
PWR_DeInit(void)118 void PWR_DeInit(void)
119 {
120 RCC_EnableAPB1PeriphReset(RCC_APB1_PERIPH_PWR, ENABLE);
121 RCC_EnableAPB1PeriphReset(RCC_APB1_PERIPH_PWR, DISABLE);
122 }
123
124 /**
125 * @brief Enables or disables access to the RTC and backup registers.
126 * @param Cmd new state of the access to the RTC and backup registers.
127 * This parameter can be: ENABLE or DISABLE.
128 */
PWR_BackupAccessEnable(FunctionalState Cmd)129 void PWR_BackupAccessEnable(FunctionalState Cmd)
130 {
131 /* Check the parameters */
132 assert_param(IS_FUNCTIONAL_STATE(Cmd));
133 *(__IO uint32_t*)CTRL_DBKP_BB = (uint32_t)Cmd;
134 }
135 /**
136 * @brief MR voltage selection.
137 * @param voltage value: 1.0V and 1.1V.
138 * This parameter can be: MR_1V0 or MR_1V1.
139 */
PWR_MRconfig(uint8_t voltage)140 void PWR_MRconfig(uint8_t voltage)
141 {
142 uint32_t tmpreg = 0;
143
144 tmpreg = PWR->CTRL1;
145 /* Clear MRSEL bits */
146 tmpreg &= (~PWR_CTRL1_MRSELMASK);
147 /* Set voltage*/
148 tmpreg |= (uint32_t)(voltage << 9);
149 PWR->CTRL1 = tmpreg;
150 }
151 /**
152 * @brief Get MR voltage value.
153 * @param voltage value: 1.0V and 1.1V.
154 * @return The value of voltage.
155 */
GetMrVoltage(void)156 uint8_t GetMrVoltage(void)
157 {
158 uint8_t tmp = 0;
159
160 tmp = (uint8_t)((PWR->CTRL1 >> 9) & 0x03);//2bits
161 return tmp ;
162 }
163 /**
164 * @brief Enables or disables the Power Voltage Detector(PVD).
165 * @param Cmd new state of the PVD.
166 * This parameter can be: ENABLE or DISABLE.
167 */
PWR_PvdEnable(FunctionalState Cmd)168 void PWR_PvdEnable(FunctionalState Cmd)
169 {
170 /* Check the parameters */
171 assert_param(IS_FUNCTIONAL_STATE(Cmd));
172 //*(__IO uint32_t*)CTRL_PVDEN_BB = (uint32_t)Cmd; //Can not enable the PVD bit
173 PWR->CTRL2 |= Cmd;
174
175 }
176
177 /**
178 * @brief Configures the voltage threshold detected by the Power Voltage Detector(PVD).
179 * @param PWR_PVDLevel: specifies the PVD detection level
180 * This parameter can be one of the following values:
181 * @arg PWR_CTRL2_PLS1: PVD detection level set to 2.1V
182 * @arg PWR_CTRL2_PLS2: PVD detection level set to 2.25V
183 * @arg PWR_CTRL2_PLS3: PVD detection level set to 2.4V
184 * @arg PWR_CTRL2_PLS4: PVD detection level set to 2.55V
185 * @arg PWR_CTRL2_PLS5: PVD detection level set to 2.7V
186 * @arg PWR_CTRL2_PLS6: PVD detection level set to 2.85V
187 * @arg PWR_CTRL2_PLS7: PVD detection level set to 2.95V
188 * @arg PWR_CTRL2_PLS8: external input analog voltage PVD_IN (compared internally to VREFINT)
189 * @retval None
190 */
PWR_PVDLevelConfig(uint32_t PWR_PVDLevel)191 void PWR_PVDLevelConfig(uint32_t PWR_PVDLevel)
192 {
193 uint32_t tmpregister = 0;
194 /* Check the parameters */
195 assert_param(IS_PWR_PVD_LEVEL(PWR_PVDLevel));
196 tmpregister = PWR->CTRL2;
197 /* Clear PLS[7:5] bits */
198 tmpregister &= (~PWR_CTRL2_PLSMASK);
199 /* Set PRS[7:5] bits according to PWR_PVDLevel value */
200 tmpregister |= PWR_PVDLevel;
201 /* Store the new value */
202 PWR->CTRL2 = tmpregister;
203 }
204
205 /**
206 * @brief Enables or disables the WakeUp Pin functionality.
207 * @param Pin: which PIN select to wakeup.
208 * This parameter can be one of the following values:
209 * @arg WAKEUP_PIN0
210 * @arg WAKEUP_PIN1
211 * @arg WAKEUP_PIN2
212 * @param Cmd new state of the WakeUp Pin functionality.
213 * This parameter can be: ENABLE or DISABLE.
214 */
PWR_WakeUpPinEnable(WAKEUP_PINX WKUP_Pin,FunctionalState Cmd)215 void PWR_WakeUpPinEnable(WAKEUP_PINX WKUP_Pin,FunctionalState Cmd)
216 {
217 uint32_t Temp = 0;
218 Temp = PWR->CTRL3;
219 if (ENABLE==Cmd)
220 {
221 Temp &= (~(PWR_CTRL3_WKUP0EN|PWR_CTRL3_WKUP1EN|PWR_CTRL3_WKUP2EN));
222 Temp |= (WKUP_Pin);
223 PWR->CTRL3 = Temp;
224 }
225 else
226 {
227 Temp &= (~(WKUP_Pin));
228 PWR->CTRL3 = Temp;
229 }
230 }
231
232
233
234
235 /**
236 * @brief Enters SLEEP mode.
237 * @param SLEEPONEXIT: specifies the SLEEPONEXIT state in SLEEP mode.
238 * This parameter can be one of the following values:
239 * @arg 0: SLEEP mode with SLEEPONEXIT disable
240 * @arg 1: SLEEP mode with SLEEPONEXIT enable
241 * @param PWR_STOPEntry: specifies if SLEEP mode in entered with WFI or WFE instruction.
242 * This parameter can be one of the following values:
243 * @arg PWR_SLEEPEntry_WFI: enter SLEEP mode with WFI instruction
244 * @arg PWR_SLEEPEntry_WFE: enter SLEEP mode with WFE instruction
245 * @retval None
246 */
PWR_EnterSLEEPMode(uint8_t SLEEPONEXIT,uint8_t PWR_SLEEPEntry)247 void PWR_EnterSLEEPMode(uint8_t SLEEPONEXIT, uint8_t PWR_SLEEPEntry)
248 {
249 /* Check the parameters */
250 assert_param(IS_PWR_SLEEP_ENTRY(PWR_SLEEPEntry));
251
252 /* CLEAR SLEEPDEEP bit of Cortex System Control Register */
253 SCB->SCR &= (uint32_t)~((uint32_t)SCB_SCR_SLEEPDEEP);
254
255 /* Select SLEEPONEXIT mode entry --------------------------------------------------*/
256 if (SLEEPONEXIT == 1)
257 {
258 /* the MCU enters Sleep mode as soon as it exits the lowest priority ISR */
259 SCB->SCR |= SCB_SCR_SLEEPONEXIT;
260 }
261 else if (SLEEPONEXIT == 0)
262 {
263 /* Sleep-now */
264 SCB->SCR &= (uint32_t)~((uint32_t)SCB_SCR_SLEEPONEXIT);
265 }
266
267 /* Select SLEEP mode entry --------------------------------------------------*/
268 if (PWR_SLEEPEntry == PWR_SLEEPENTRY_WFI)
269 {
270 /* Request Wait For Interrupt */
271 __WFI();
272 }
273 else
274 {
275 /* Request Wait For Event */
276 __SEV();
277 __WFE();
278 __WFE();
279 }
280 }
281
282
283
284 /**
285 * @brief Enters STOP2 mode.
286 * @param PWR_STOPEntry specifies if STOP2 mode in entered with WFI or WFE instruction.
287 * This parameter can be one of the following values:
288 * @arg PWR_STOPENTRY_WFI enter STOP2 mode with WFI instruction
289 * @arg PWR_STOPENTRY_WFE enter STOP2 mode with WFE instruction
290 * @param RetentionMode: PWR_CTRL3_RAM1RET or PWR_CTRL3_RAM2RET
291 */
PWR_EnterSTOP2Mode(uint8_t PWR_STOPEntry,uint32_t RetentionMode)292 void PWR_EnterSTOP2Mode(uint8_t PWR_STOPEntry,uint32_t RetentionMode)
293 {
294 uint32_t tmpreg = 0;
295 /* Check the parameters */
296 assert_param(IS_PWR_STOP_ENTRY(PWR_STOPEntry));
297 /* Wait MR Voltage Adjust Complete */
298 while ((PWR->STS2 &0X2) != 2);
299 tmpreg = PWR->CTRL3;
300 /* Clear SRAMRET bits */
301 tmpreg &= (~PWR_CTRL3_RAMRETMASK);
302 /* Set SRAM1/2 select */
303 tmpreg |= RetentionMode;
304 PWR->CTRL3 = tmpreg;
305 /* Select the regulator state in STOP2 mode ---------------------------------*/
306 tmpreg = PWR->CTRL1;
307 /* Clear LPMS bits */
308 tmpreg &= (~PWR_CTRL1_LPMSELMASK);
309 /* Set stop2 mode select */
310 tmpreg |= PWR_CTRL1_STOP2;
311 /* Store the new value */
312 PWR->CTRL1 = tmpreg;
313 /*Clear PWR_CTRL3_PBDTSTP2 for BOR always on*/
314 tmpreg = PWR->CTRL3;
315 tmpreg &= (~PWR_CTRL3_PBDTSTP2);
316 PWR->CTRL3 = tmpreg;
317 /* Set SLEEPDEEP bit of Cortex System Control Register */
318 SCB->SCR |= SCB_SCR_SLEEPDEEP;
319
320 /* Select STOP mode entry --------------------------------------------------*/
321 if (PWR_STOPEntry == PWR_STOPENTRY_WFI)
322 {
323 /* Request Wait For Interrupt */
324 __WFI();
325 }
326 else
327 {
328 /* Request Wait For Event */
329 __SEV();
330 __WFE();
331 __WFE();
332 }
333
334 /* Reset SLEEPDEEP bit of Cortex System Control Register */
335 SCB->SCR &= (uint32_t)~((uint32_t)SCB_SCR_SLEEPDEEP);
336 }
337
338
339 /**
340 * @brief Enters Low power run mode.
341 * @param
342 * @arg
343 * @arg
344 * @retval None
345 */
PWR_EnterLowPowerRunMode(void)346 void PWR_EnterLowPowerRunMode(void)
347 {
348 uint32_t tmpreg = 0;
349
350 SetSysClock_MSI();
351 FLASH_SetLatency(FLASH_LATENCY_2); //Configure the Flash read latency to be grater than 2, so LVE/SE timing requirement is guaranteed
352 //config FLASH enter the low power voltage mode
353 FLASH->AC |= FLASH_AC_LVMEN;
354 while ((FLASH->AC & FLASH_AC_LVMF) != FLASH_AC_LVMF);
355 FLASH_SetLatency(FLASH_LATENCY_0); //Configure the latency of Flash read cycle to proper value which depends on the Flash read access time.
356
357 _SetLprunSramVoltage(0);
358 _SetBandGapMode(0);
359 _SetPvdBorMode(0);
360 /* Select the regulator state in LPRUN mode ---------------------------------*/
361 tmpreg = PWR->CTRL1;
362 /* Clear LPMS bits */
363 tmpreg &= (~PWR_CTRL1_LPMSELMASK);
364 /* Set lpr to run the main power domain*/
365 tmpreg |= PWR_CTRL1_LPREN;
366 /* Store the new value */
367 PWR->CTRL1 = tmpreg;
368 /*Clear PWR_CTRL3_PBDTLPR for BOR always on*/
369 tmpreg = PWR->CTRL3;
370 tmpreg &= (~PWR_CTRL3_PBDTLPR);
371 PWR->CTRL3 = tmpreg;
372 while ((PWR->STS2 &PWR_STS2_LPRUNF) != 0);//LPRCNT flag ready
373 }
374
375 /**
376 * @brief Enters Low power run mode.
377 * @param
378 * @arg
379 * @arg
380 * @retval None
381 */
PWR_ExitLowPowerRunMode(void)382 void PWR_ExitLowPowerRunMode(void)
383 {
384 PWR->CTRL1 &= ~PWR_CTRL1_LPREN;
385 while ((PWR->STS2 &PWR_STS2_LPRUNF) != PWR_STS2_LPRUNF);
386 FLASH_SetLatency(FLASH_LATENCY_2); //Configure the Flash read latency to be grater than 2, so LVE/SE timing requirement is guaranteed
387 FLASH->AC &= ~FLASH_AC_LVMEN; //clear LVMREQ
388 while ((FLASH->AC &FLASH_AC_LVMF) != 0); //wait LVE is deasserted by polling the LVMVLD bit
389
390 FLASH_SetLatency(FLASH_LATENCY_0); //Configure the latency of Flash read cycle to proper value which depends on the Flash read access time.
391 }
392
393 /**
394 * @brief Enters LP_SLEEP mode.
395 * @param SLEEPONEXIT: specifies the SLEEPONEXIT state in SLEEP mode.
396 * This parameter can be one of the following values:
397 * @arg 0: SLEEP mode with SLEEPONEXIT disable
398 * @arg 1: SLEEP mode with SLEEPONEXIT enable
399 * @param PWR_STOPEntry: specifies if SLEEP mode in entered with WFI or WFE instruction.
400 * This parameter can be one of the following values:
401 * @arg PWR_SLEEPEntry_WFI: enter SLEEP mode with WFI instruction
402 * @arg PWR_SLEEPEntry_WFE: enter SLEEP mode with WFE instruction
403 * @retval None
404 */
PWR_EnterLowPowerSleepMode(uint8_t SLEEPONEXIT,uint8_t PWR_SLEEPEntry)405 void PWR_EnterLowPowerSleepMode(uint8_t SLEEPONEXIT, uint8_t PWR_SLEEPEntry)
406 {
407 PWR_EnterLowPowerRunMode();
408 PWR_EnterSLEEPMode(SLEEPONEXIT, PWR_SLEEPEntry);
409 }
410
411 /**
412 * @brief Enters STANDBY mode.
413 * @param PWR_STANDBYEntry: specifies if STANDBY mode in entered with WFI or WFE instruction.
414 * This parameter can be one of the following values:
415 * @arg PWR_STANDBYEntry_WFI: enter STANDBY mode with WFI instruction
416 * @arg PWR_CTRL3_RAM2RET: SRAM2 whether to retention
417 * @retval None
418 */
PWR_EnterSTANDBYMode(uint8_t PWR_STANDBYEntry,uint32_t Sam2Ret)419 void PWR_EnterSTANDBYMode(uint8_t PWR_STANDBYEntry,uint32_t Sam2Ret)
420 {
421 uint32_t tmpreg;
422 /* Clear Wake-up flag */
423 PWR->STSCLR |= PWR_STSCLR_CLRWKUP0;
424 PWR->STSCLR |= PWR_STSCLR_CLRWKUP1;
425 PWR->STSCLR |= PWR_STSCLR_CLRWKUP2;
426 tmpreg = PWR->CTRL3;
427 /* Clear SRAMRET bits */
428 tmpreg &= (~PWR_CTRL3_RAMRETMASK);
429 /* Set SRAM1/2 select */
430 tmpreg |= Sam2Ret;
431 PWR->CTRL3 = tmpreg;
432
433 tmpreg = PWR->CTRL1;
434 /* Clear LPMS bits */
435 tmpreg &= (~PWR_CTRL1_LPMSELMASK);
436 /* Select STANDBY mode */
437 tmpreg |= PWR_CTRL1_STANDBY;
438 PWR->CTRL1 = tmpreg;
439 /*Clear PWR_CTRL3_PBDTSTBY for BOR always on*/
440 tmpreg = PWR->CTRL3;
441 tmpreg &= (~PWR_CTRL3_PBDTSTBY);
442 PWR->CTRL3 = tmpreg;
443 /* Set SLEEPDEEP bit of Cortex System Control Register */
444 SCB->SCR |= SCB_SCR_SLEEPDEEP;
445 /* This option is used to ensure that store operations are completed */
446 #if defined ( __CC_ARM )
447 __force_stores();
448 #endif
449 /* Select STANDBY mode entry --------------------------------------------------*/
450 if (PWR_STANDBYEntry == PWR_STOPENTRY_WFI)
451 {
452 /* Request Wait For Interrupt */
453 __WFI();
454 }
455 else
456 {
457 /* Request Wait For Event */
458 __SEV();
459 __WFE();
460 __WFE();
461 }
462 }
463
464
465
466 /**
467 * @brief Checks whether the specified PWR flag is set or not.
468 * @param PWR_FLAG: specifies the flag to check.
469 * This parameter can be one of the following values:
470 * @arg PWR_WKUP0_FLAG/PWR_WKUP1_FLAG/PWR_WKUP2_FLAG: Wake Up flag
471 * @arg PWR_STBY_FLAG: StandBy flag
472 * @arg PWR_LPRUN_FLAG: low power work flag
473 * @arg PWR_MR_FLAG: MR work statue flag
474 * @arg PWR_PVDO_FLAG: PVD output flag
475 * @retval The new state of PWR_FLAG (SET or RESET).
476 */
PWR_GetFlagStatus(uint8_t STS,uint32_t PWR_FLAG)477 FlagStatus PWR_GetFlagStatus(uint8_t STS,uint32_t PWR_FLAG)
478 {
479 FlagStatus bitstatus = RESET;
480 /* Check the parameters */
481 assert_param(IS_PWR_GET_FLAG(PWR_FLAG));
482 if (STS == 1)
483 {
484 if ((PWR->STS1 & PWR_FLAG) != (uint32_t)RESET)
485 {
486 bitstatus = SET;
487 }
488 else
489 {
490 bitstatus = RESET;
491 }
492
493 }
494 else
495 {
496 if ((PWR->STS2 & PWR_FLAG) != (uint32_t)RESET)
497 {
498 bitstatus = SET;
499 }
500 else
501 {
502 bitstatus = RESET;
503 }
504
505 }
506
507 /* Return the flag status */
508 return bitstatus;
509 }
510
511 /**
512 * @brief Clears the PWR's pending flags.
513 * @param PWR_FLAG specifies the flag to clear.
514 * This parameter can be one of the following values:
515 * @arg PWR_WKUP1_FLAG/PWR_WKUP2_FLAG/PWR_WKUP3_FLAG: Wake Up flag
516 * @arg PWR_STBY_FLAG: StandBy flag
517 */
PWR_ClearFlag(uint32_t PWR_FLAG)518 void PWR_ClearFlag(uint32_t PWR_FLAG)
519 {
520 /* Check the parameters */
521 assert_param(IS_PWR_CLEAR_FLAG(PWR_FLAG));
522
523 PWR->STSCLR |= PWR_FLAG ;
524 }
525
526
527 /**
528 * @brief set system clock with MSI.
529 * @param void.
530 */
SetSysClock_MSI(void)531 void SetSysClock_MSI(void)
532 {
533 RCC_DeInit();
534
535 if (RESET == RCC_GetFlagStatus(RCC_CTRLSTS_FLAG_MSIRD))
536 {
537 /* Enable MSI and Config Clock */
538 RCC_ConfigMsi(RCC_MSI_ENABLE, RCC_MSI_RANGE_4M);
539 /* Waits for MSI start-up */
540 while (SUCCESS != RCC_WaitMsiStable());
541 }
542
543 /* Enable Prefetch Buffer */
544 FLASH_PrefetchBufSet(FLASH_PrefetchBuf_EN);
545
546 /* Select MSI as system clock source */
547 RCC_ConfigSysclk(RCC_SYSCLK_SRC_MSI);
548
549 /* Wait till MSI is used as system clock source */
550 while (RCC_GetSysclkSrc() != 0x00)
551 {
552 }
553
554 /* Flash 0 wait state */
555 //FLASH_SetLatency(FLASH_LATENCY_0);
556
557 /* HCLK = SYSCLK */
558 RCC_ConfigHclk(RCC_SYSCLK_DIV1);
559
560 /* PCLK2 = HCLK */
561 RCC_ConfigPclk2(RCC_HCLK_DIV1);
562
563 /* PCLK1 = HCLK */
564 RCC_ConfigPclk1(RCC_HCLK_DIV1);
565 }
566 /**
567 * @}
568 */
569
570 /**
571 * @}
572 */
573
574 /**
575 * @}
576 */
577