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 n32l40x_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 "n32l40x_pwr.h"
36
37 /** @addtogroup n32l40x_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 * @brief Enters SLEEP mode.
234 * @param SLEEPONEXIT: specifies the SLEEPONEXIT state in SLEEP mode.
235 * This parameter can be one of the following values:
236 * @arg 0: SLEEP mode with SLEEPONEXIT disable
237 * @arg 1: SLEEP mode with SLEEPONEXIT enable
238 * @param PWR_STOPEntry: specifies if SLEEP mode in entered with WFI or WFE instruction.
239 * This parameter can be one of the following values:
240 * @arg PWR_SLEEPEntry_WFI: enter SLEEP mode with WFI instruction
241 * @arg PWR_SLEEPEntry_WFE: enter SLEEP mode with WFE instruction
242 * @retval None
243 */
PWR_EnterSLEEPMode(uint8_t SLEEPONEXIT,uint8_t PWR_SLEEPEntry)244 void PWR_EnterSLEEPMode(uint8_t SLEEPONEXIT, uint8_t PWR_SLEEPEntry)
245 {
246 /* Check the parameters */
247 assert_param(IS_PWR_SLEEP_ENTRY(PWR_SLEEPEntry));
248
249 /* CLEAR SLEEPDEEP bit of Cortex System Control Register */
250 SCB->SCR &= (uint32_t)~((uint32_t)SCB_SCR_SLEEPDEEP);
251
252 /* Select SLEEPONEXIT mode entry --------------------------------------------------*/
253 if (SLEEPONEXIT == 1)
254 {
255 /* the MCU enters Sleep mode as soon as it exits the lowest priority ISR */
256 SCB->SCR |= SCB_SCR_SLEEPONEXIT;
257 }
258 else if (SLEEPONEXIT == 0)
259 {
260 /* Sleep-now */
261 SCB->SCR &= (uint32_t)~((uint32_t)SCB_SCR_SLEEPONEXIT);
262 }
263
264 /* Select SLEEP mode entry --------------------------------------------------*/
265 if (PWR_SLEEPEntry == PWR_SLEEPENTRY_WFI)
266 {
267 /* Request Wait For Interrupt */
268 __WFI();
269 }
270 else
271 {
272 /* Request Wait For Event */
273 __SEV();
274 __WFE();
275 __WFE();
276 }
277 }
278
279
280
281 /**
282 * @brief Enters STOP2 mode.
283 * @param PWR_STOPEntry specifies if STOP2 mode in entered with WFI or WFE instruction.
284 * This parameter can be one of the following values:
285 * @arg PWR_STOPENTRY_WFI enter STOP2 mode with WFI instruction
286 * @arg PWR_STOPENTRY_WFE enter STOP2 mode with WFE instruction
287 * @param RetentionMode: PWR_CTRL3_RAM1RET or PWR_CTRL3_RAM2RET
288 */
PWR_EnterSTOP2Mode(uint8_t PWR_STOPEntry,uint32_t RetentionMode)289 void PWR_EnterSTOP2Mode(uint8_t PWR_STOPEntry,uint32_t RetentionMode)
290 {
291 uint32_t tmpreg = 0;
292 /* Check the parameters */
293 assert_param(IS_PWR_STOP_ENTRY(PWR_STOPEntry));
294 /* Wait MR Voltage Adjust Complete */
295 while ((PWR->STS2 &0X2) != 2);
296 tmpreg = PWR->CTRL3;
297 /* Clear SRAMRET bits */
298 tmpreg &= (~PWR_CTRL3_RAMRETMASK);
299 /* Set SRAM1/2 select */
300 tmpreg |= RetentionMode;
301 PWR->CTRL3 = tmpreg;
302 /* Select the regulator state in STOP2 mode ---------------------------------*/
303 tmpreg = PWR->CTRL1;
304 /* Clear LPMS bits */
305 tmpreg &= (~PWR_CTRL1_LPMSELMASK);
306 /* Set stop2 mode select */
307 tmpreg |= PWR_CTRL1_STOP2;
308 /* Store the new value */
309 PWR->CTRL1 = tmpreg;
310 /* Set SLEEPDEEP bit of Cortex System Control Register */
311 SCB->SCR |= SCB_SCR_SLEEPDEEP;
312
313 /* Select STOP mode entry --------------------------------------------------*/
314 if (PWR_STOPEntry == PWR_STOPENTRY_WFI)
315 {
316 /* Request Wait For Interrupt */
317 __WFI();
318 }
319 else
320 {
321 /* Request Wait For Event */
322 __SEV();
323 __WFE();
324 __WFE();
325 }
326
327 /* Reset SLEEPDEEP bit of Cortex System Control Register */
328 SCB->SCR &= (uint32_t)~((uint32_t)SCB_SCR_SLEEPDEEP);
329 }
330
331
332 /**
333 * @brief Enters Low power run mode.
334 * @param
335 * @arg
336 * @arg
337 * @retval None
338 */
PWR_EnterLowPowerRunMode(void)339 void PWR_EnterLowPowerRunMode(void)
340 {
341 uint32_t tmpreg = 0;
342
343 SetSysClock_MSI();
344 FLASH_SetLatency(FLASH_LATENCY_2); //Configure the Flash read latency to be grater than 2, so LVE/SE timing requirement is guaranteed
345 //config FLASH enter the low power voltage mode
346 FLASH->AC |= FLASH_AC_LVMEN;
347 while ((FLASH->AC & FLASH_AC_LVMF) != FLASH_AC_LVMF);
348 FLASH_SetLatency(FLASH_LATENCY_0); //Configure the latency of Flash read cycle to proper value which depends on the Flash read access time.
349
350 _SetLprunSramVoltage(0);
351 _SetBandGapMode(0);
352 _SetPvdBorMode(0);
353 /* Select the regulator state in LPRUN mode ---------------------------------*/
354 tmpreg = PWR->CTRL1;
355 /* Clear LPMS bits */
356 tmpreg &= (~PWR_CTRL1_LPMSELMASK);
357 /* Set lpr to run the main power domain*/
358 tmpreg |= PWR_CTRL1_LPREN;
359 /* Store the new value */
360 PWR->CTRL1 = tmpreg;
361 while ((PWR->STS2 &PWR_STS2_LPRUNF) != 0);//LPRCNT flag ready
362 }
363
364 /**
365 * @brief Enters Low power run mode.
366 * @param
367 * @arg
368 * @arg
369 * @retval None
370 */
PWR_ExitLowPowerRunMode(void)371 void PWR_ExitLowPowerRunMode(void)
372 {
373 PWR->CTRL1 &= ~PWR_CTRL1_LPREN;
374 _SetLprunswitch(3);
375 while ((PWR->STS2 &PWR_STS2_MRF) != PWR_STS2_MRF);
376 while ((PWR->STS2 &PWR_STS2_LPRUNF) != PWR_STS2_LPRUNF);
377 FLASH_SetLatency(FLASH_LATENCY_2); //Configure the Flash read latency to be grater than 2, so LVE/SE timing requirement is guaranteed
378 FLASH->AC &= ~FLASH_AC_LVMEN; //clear LVMREQ
379 while ((FLASH->AC &FLASH_AC_LVMF) != 0); //wait LVE is deasserted by polling the LVMVLD bit
380
381 FLASH_SetLatency(FLASH_LATENCY_0); //Configure the latency of Flash read cycle to proper value which depends on the Flash read access time.
382 _SetLprunswitch(2);
383 while ((PWR->STS2 &0X2) != 0) // wait MF to be 0 first
384 {
385 }
386 while ((PWR->STS2 &0X2) != 2) // wait MF to be 1 then
387 {
388 }
389 }
390
391 /**
392 * @brief Enters LP_SLEEP mode.
393 * @param SLEEPONEXIT: specifies the SLEEPONEXIT state in SLEEP mode.
394 * This parameter can be one of the following values:
395 * @arg 0: SLEEP mode with SLEEPONEXIT disable
396 * @arg 1: SLEEP mode with SLEEPONEXIT enable
397 * @param PWR_STOPEntry: specifies if SLEEP mode in entered with WFI or WFE instruction.
398 * This parameter can be one of the following values:
399 * @arg PWR_SLEEPEntry_WFI: enter SLEEP mode with WFI instruction
400 * @arg PWR_SLEEPEntry_WFE: enter SLEEP mode with WFE instruction
401 * @retval None
402 */
PWR_EnterLowPowerSleepMode(uint8_t SLEEPONEXIT,uint8_t PWR_SLEEPEntry)403 void PWR_EnterLowPowerSleepMode(uint8_t SLEEPONEXIT, uint8_t PWR_SLEEPEntry)
404 {
405 PWR_EnterLowPowerRunMode();
406 PWR_EnterSLEEPMode(SLEEPONEXIT, PWR_SLEEPEntry);
407 }
408
409 /**
410 * @brief Enters STANDBY mode.
411 * @param PWR_STANDBYEntry: specifies if STANDBY mode in entered with WFI or WFE instruction.
412 * This parameter can be one of the following values:
413 * @arg PWR_STANDBYEntry_WFI: enter STANDBY mode with WFI instruction
414 * @arg PWR_CTRL3_RAM2RET: SRAM2 whether to retention
415 * @retval None
416 */
PWR_EnterSTANDBYMode(uint8_t PWR_STANDBYEntry,uint32_t Sam2Ret)417 void PWR_EnterSTANDBYMode(uint8_t PWR_STANDBYEntry,uint32_t Sam2Ret)
418 {
419 uint32_t tmpreg;
420 /* Clear Wake-up flag */
421 PWR->STSCLR |= PWR_STSCLR_CLRWKUP0;
422 PWR->STSCLR |= PWR_STSCLR_CLRWKUP1;
423 PWR->STSCLR |= PWR_STSCLR_CLRWKUP2;
424 tmpreg = PWR->CTRL3;
425 /* Clear SRAMRET bits */
426 tmpreg &= (~PWR_CTRL3_RAMRETMASK);
427 /* Set SRAM1/2 select */
428 tmpreg |= Sam2Ret;
429 PWR->CTRL3 = tmpreg;
430
431 tmpreg = PWR->CTRL1;
432 /* Clear LPMS bits */
433 tmpreg &= (~PWR_CTRL1_LPMSELMASK);
434 /* Select STANDBY mode */
435 tmpreg |= PWR_CTRL1_STANDBY;
436 PWR->CTRL1 = tmpreg;
437 /* Set SLEEPDEEP bit of Cortex System Control Register */
438 SCB->SCR |= SCB_SCR_SLEEPDEEP;
439 /* This option is used to ensure that store operations are completed */
440 #if defined ( __CC_ARM )
441 __force_stores();
442 #endif
443 /* Select STANDBY mode entry --------------------------------------------------*/
444 if (PWR_STANDBYEntry == PWR_STOPENTRY_WFI)
445 {
446 /* Request Wait For Interrupt */
447 __WFI();
448 }
449 else
450 {
451 /* Request Wait For Event */
452 __SEV();
453 __WFE();
454 __WFE();
455 }
456 }
457
458
459
460 /**
461 * @brief Checks whether the specified PWR flag is set or not.
462 * @param PWR_FLAG: specifies the flag to check.
463 * This parameter can be one of the following values:
464 * @arg PWR_WKUP0_FLAG/PWR_WKUP1_FLAG/PWR_WKUP2_FLAG: Wake Up flag
465 * @arg PWR_STBY_FLAG: StandBy flag
466 * @arg PWR_LPRUN_FLAG: low power work flag
467 * @arg PWR_MR_FLAG: MR work statue flag
468 * @arg PWR_PVDO_FLAG: PVD output flag
469 * @retval The new state of PWR_FLAG (SET or RESET).
470 */
PWR_GetFlagStatus(uint8_t STS,uint32_t PWR_FLAG)471 FlagStatus PWR_GetFlagStatus(uint8_t STS,uint32_t PWR_FLAG)
472 {
473 FlagStatus bitstatus = RESET;
474 /* Check the parameters */
475 assert_param(IS_PWR_GET_FLAG(PWR_FLAG));
476 if (STS == 1)
477 {
478 if ((PWR->STS1 & PWR_FLAG) != (uint32_t)RESET)
479 {
480 bitstatus = SET;
481 }
482 else
483 {
484 bitstatus = RESET;
485 }
486
487 }
488 else
489 {
490 if ((PWR->STS2 & PWR_FLAG) != (uint32_t)RESET)
491 {
492 bitstatus = SET;
493 }
494 else
495 {
496 bitstatus = RESET;
497 }
498
499 }
500
501 /* Return the flag status */
502 return bitstatus;
503 }
504
505 /**
506 * @brief Clears the PWR's pending flags.
507 * @param PWR_FLAG specifies the flag to clear.
508 * This parameter can be one of the following values:
509 * @arg PWR_WKUP1_FLAG/PWR_WKUP2_FLAG/PWR_WKUP3_FLAG: Wake Up flag
510 * @arg PWR_STBY_FLAG: StandBy flag
511 */
PWR_ClearFlag(uint32_t PWR_FLAG)512 void PWR_ClearFlag(uint32_t PWR_FLAG)
513 {
514 /* Check the parameters */
515 assert_param(IS_PWR_CLEAR_FLAG(PWR_FLAG));
516
517 PWR->STSCLR |= PWR_FLAG ;
518 }
519
520
521 /**
522 * @brief set system clock with MSI.
523 * @param void.
524 */
525
SetSysClock_MSI(void)526 void SetSysClock_MSI(void)
527 {
528 RCC_DeInit();
529
530 if (RESET == RCC_GetFlagStatus(RCC_CTRLSTS_FLAG_MSIRD))
531 {
532 /* Enable MSI and Config Clock */
533 RCC_ConfigMsi(RCC_MSI_ENABLE, RCC_MSI_RANGE_4M);
534 /* Waits for MSI start-up */
535 while (SUCCESS != RCC_WaitMsiStable());
536 }
537
538 /* Enable Prefetch Buffer */
539 FLASH_PrefetchBufSet(FLASH_PrefetchBuf_EN);
540
541 /* Select MSI as system clock source */
542 RCC_ConfigSysclk(RCC_SYSCLK_SRC_MSI);
543
544 /* Wait till MSI is used as system clock source */
545 while (RCC_GetSysclkSrc() != 0x00)
546 {
547 }
548
549 /* Flash 0 wait state */
550 //FLASH_SetLatency(FLASH_LATENCY_0);
551
552 /* HCLK = SYSCLK */
553 RCC_ConfigHclk(RCC_SYSCLK_DIV1);
554
555 /* PCLK2 = HCLK */
556 RCC_ConfigPclk2(RCC_HCLK_DIV1);
557
558 /* PCLK1 = HCLK */
559 RCC_ConfigPclk1(RCC_HCLK_DIV1);
560 }
561
562 /**
563 * @}
564 */
565
566 /**
567 * @}
568 */
569
570 /**
571 * @}
572 */
573