1 /**
2 ******************************************************************************
3 * @file lib_pmu.c
4 * @author Application Team
5 * @version V4.4.0
6 * @date 2018-09-27
7 * @brief PMU library.
8 ******************************************************************************
9 * @attention
10 *
11 ******************************************************************************
12 */
13 #include "lib_pmu.h"
14 #include "lib_gpio.h"
15 #include "lib_CodeRAM.h"
16 #include "lib_clk.h"
17 #include "lib_cortex.h"
18
19 #define DSLEEPPASS_KEY 0xAA5555AA
20 #define DSLEEPEN_KEY 0x55AAAA55
21
22 extern __IO uint32_t ana_reg3_tmp;
23
24 /**
25 * @brief Enter Deep sleep mode.
26 * @param None
27 * @retval 1: Current mode is debug mode, function failed.
28 * 2: Enter deep-sleep mode failed.
29 */
PMU_EnterDSleepMode(void)30 uint32_t PMU_EnterDSleepMode(void)
31 {
32 uint32_t hclk;
33
34 /* Current MODE is 0, debug mode, return error */
35 if (!(PMU->STS & PMU_STS_MODE))
36 return 1;
37
38 /* Enter deep sleep when WKU event is cleared */
39 while (PMU->DSLEEPEN & PMU_DSLEEPEN_WKU)
40 {
41 }
42
43 /* Flash 1USCYCLE configure */
44 hclk = CLK_GetHCLKFreq();
45 if(hclk > 1000000)
46 {
47 MISC2->FLASHWC = (hclk/1000000)<<8;
48 }
49 else
50 {
51 MISC2->FLASHWC = 0<<8;
52 }
53
54 ANA->REG7 &= ~BIT5;
55 ANA->REGA |= BIT3 | BIT1;
56
57 PMU->DSLEEPPASS = DSLEEPPASS_KEY;
58 PMU->DSLEEPEN = DSLEEPEN_KEY;
59
60 return 2;
61 }
62
63 /**
64 * @brief Enter idel mode.
65 * @note Any interrupt generate to CPU will break idle mode.
66 * @param None
67 * @retval None
68 */
PMU_EnterIdleMode(void)69 void PMU_EnterIdleMode(void)
70 {
71 /* Clear SLEEPDEEP bit of Cortex-M0 System Control Register */
72 SCB->SCR &= (uint32_t)~((uint32_t)SCB_SCR_SLEEPDEEP_Msk);
73
74 __WFI();
75 }
76
77 /**
78 * @brief Enter sleep mode.
79 * @param None
80 * @retval 1: Current mode is debug mode, function failed.
81 * 0: Quit deep-sleep mode ucceeded.
82 */
PMU_EnterSleepMode(void)83 uint32_t PMU_EnterSleepMode(void)
84 {
85 uint32_t hclk;
86
87 /* Current MODE is 0, debug mode, return error */
88 if (!(PMU->STS & PMU_STS_MODE))
89 return 1;
90
91 /* Flash 1USCYCLE configure */
92 hclk = CLK_GetHCLKFreq();
93 if(hclk > 1000000)
94 {
95 MISC2->FLASHWC = (hclk/1000000)<<8;
96 }
97 else
98 {
99 MISC2->FLASHWC = 0<<8;
100 }
101
102 ANA->REG7 &= ~BIT5;
103 ANA->REGA |= BIT3 | BIT1;
104
105 /* Set SLEEPDEEP bit of Cortex-M0 System Control Register */
106 SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
107
108 __WFI();
109
110 return 0;
111 }
112
113 /**
114 * @brief PMU interrupt configuration.
115 * @param INTMask:(between PMU_INT_IOAEN,PMU_INT_32K and PMU_INT_6M, can use the | operator)
116 PMU_INT_IOAEN
117 PMU_INT_32K
118 PMU_INT_6M
119 NewState:
120 ENABLE
121 DISABLE
122 * @retval None
123 */
PMU_INTConfig(uint32_t INTMask,uint32_t NewState)124 void PMU_INTConfig(uint32_t INTMask, uint32_t NewState)
125 {
126 /* Check parameters */
127 assert_parameters(IS_PMU_INT(INTMask));
128 assert_parameters(IS_FUNCTIONAL_STATE(NewState));
129
130 if (NewState == ENABLE)
131 {
132 PMU->CONTROL |= INTMask;
133 }
134 else
135 {
136 PMU->CONTROL &= ~INTMask;
137 }
138 }
139
140 /**
141 * @brief Get interrupt status.
142 * @param INTMask:
143 PMU_INTSTS_32K
144 PMU_INTSTS_6M
145 PMU_INTSTS_EXTRST
146 PMU_INTSTS_PORST
147 PMU_INTSTS_DPORST
148 * @retval 1:status set
149 0:status reset
150 */
PMU_GetINTStatus(uint32_t INTMask)151 uint8_t PMU_GetINTStatus(uint32_t INTMask)
152 {
153 /* Check parameters */
154 assert_parameters(IS_PMU_INTFLAGR(INTMask));
155
156 if (PMU->STS&INTMask)
157 {
158 return 1;
159 }
160 else
161 {
162 return 0;
163 }
164 }
165
166 /**
167 * @brief Clear interrupt status.
168 * @param INTMask:specifies the flag to clear.
169 This parameter can be any combination of the following values
170 PMU_INTSTS_32K
171 PMU_INTSTS_6M
172 PMU_INTSTS_EXTRST
173 PMU_INTSTS_PORST
174 PMU_INTSTS_DPORST
175 * @retval None
176 */
PMU_ClearINTStatus(uint32_t INTMask)177 void PMU_ClearINTStatus(uint32_t INTMask)
178 {
179 /* Check parameters */
180 assert_parameters(IS_PMU_INTFLAGC(INTMask));
181
182 PMU->STS = INTMask;
183 }
184
185 /**
186 * @brief Get status.
187 * @param Mask:
188 PMU_STS_32K
189 PMU_STS_6M
190 * @retval 1:status set
191 0:status reset
192 */
PMU_GetStatus(uint32_t Mask)193 uint8_t PMU_GetStatus(uint32_t Mask)
194 {
195 /* Check parameters */
196 assert_parameters(IS_PMU_FLAG(Mask));
197
198 if (PMU->STS&Mask)
199 {
200 return 1;
201 }
202 else
203 {
204 return 0;
205 }
206 }
207
208 /**
209 * @brief Get all IOA interrupt status.
210 * @param None
211 * @retval IOA's interrupt status
212 */
PMU_GetIOAAllINTStatus(void)213 uint16_t PMU_GetIOAAllINTStatus(void)
214 {
215 return (PMU->IOAINTSTS);
216 }
217
218 /**
219 * @brief Get IOA interrupt status.
220 * @param INTMask:
221 GPIO_Pin_0 ~ GPIO_Pin_15
222 * @retval 1:status set
223 0:status reset
224 */
PMU_GetIOAINTStatus(uint16_t INTMask)225 uint16_t PMU_GetIOAINTStatus(uint16_t INTMask)
226 {
227 /* Check parameters */
228 assert_parameters(IS_GPIO_PINR(INTMask));
229
230 if (PMU->IOAINTSTS&INTMask)
231 {
232 return 1;
233 }
234 else
235 {
236 return 0;
237 }
238 }
239
240 /**
241 * @brief Clear IOA interrupt status.
242 * @param INTMask:
243 This parameter can be any combination of the following values
244 GPIO_Pin_0 ~ GPIO_Pin_15
245 * @retval None
246 */
PMU_ClearIOAINTStatus(uint16_t INTMask)247 void PMU_ClearIOAINTStatus(uint16_t INTMask)
248 {
249 /* Check parameters */
250 assert_parameters(IS_GPIO_PIN(INTMask));
251
252 PMU->IOAINTSTS = INTMask;
253 }
254
255 /**
256 * @brief Wake-up sources pin configuration.
257 * @param IOAx: GPIO_Pin_0 ~ GPIO_Pin_15
258 Wakeup_Event:
259 IOA_DISABLE
260 IOA_RISING
261 IOA_FALLING
262 IOA_HIGH
263 IOA_LOW
264 IOA_EDGEBOTH
265 * @retval None
266 */
PMU_WakeUpPinConfig(uint32_t IOAx,uint32_t Wakeup_Event)267 void PMU_WakeUpPinConfig(uint32_t IOAx, uint32_t Wakeup_Event)
268 {
269 uint32_t tmp;
270 uint32_t position = 0x00U;
271 uint32_t iocurrent = 0x00U;
272
273 /* Check parameters */
274 assert_parameters(IS_GPIO_PINR(IOAx));
275 assert_parameters(IS_PMU_WAKEUP(Wakeup_Event));
276
277 while ((IOAx >> position) != 0U)
278 {
279 /* Get current io position */
280 iocurrent = IOAx & (0x01U << position);
281
282 if (iocurrent)
283 {
284 /* Current IO Input configure*/
285 GPIOA->OEN |= iocurrent;
286 GPIOA->IE |= iocurrent;
287
288 tmp = PMU->IOAWKUEN;
289 tmp &= ~(3U << (2 * position));
290 switch (Wakeup_Event)
291 {
292 /* Disable wake-up function */
293 default:
294 case IOA_DISABLE:
295 break;
296
297 /* wake-up function: Rising */
298 case IOA_RISING:
299 GPIOA->DAT &= ~iocurrent;
300 tmp |= 1 << (2 * position);
301 break;
302
303 /* wake-up function: falling */
304 case IOA_FALLING:
305 GPIOA->DAT |= iocurrent;
306 tmp |= 1 << (2 * position);
307 break;
308
309 /* wake-up function: high level */
310 case IOA_HIGH:
311 GPIOA->DAT &= ~iocurrent;
312 tmp |= 2 << (2 * position);
313 break;
314
315 /* wake-up function: low level */
316 case IOA_LOW:
317 GPIOA->DAT |= iocurrent;
318 tmp |= 2 << (2 * position);
319 break;
320
321 /* wake-up function: boht edge */
322 case IOA_EDGEBOTH:
323 tmp |= 3 << (2 * position);
324 break;
325 }
326 PMU->IOAWKUEN = tmp;
327 }
328 position++;
329 }
330 }
331
332 /**
333 * @brief Control low-power configuration, enter deep-sleep mode.
334 *
335 * @param InitStruct : pointer to PMU_LowPWRTypeDef
336 COMP1Power:
337 PMU_COMP1PWR_ON
338 PMU_COMP1PWR_OFF
339 COMP2Power:
340 PMU_COMP2PWR_ON
341 PMU_COMP2PWR_OFF
342 TADCPower:
343 PMU_TADCPWR_ON
344 PMU_TADCPWR_OFF
345 BGPPower:
346 PMU_BGPPWR_ON
347 PMU_BGPPWR_OFF
348 AVCCPower:
349 PMU_AVCCPWR_ON
350 PMU_AVCCPWR_OFF
351 LCDPower:
352 PMU_LCDPWER_ON
353 PMU_LCDPWER_OFF
354 VDCINDetector:
355 PMU_VDCINDET_ENABLE
356 PMU_VDCINDET_DISABLE
357 VDDDetector:
358 PMU_VDDDET_ENABLE
359 PMU_VDDDET_DISABLE
360 APBPeriphralDisable:
361 PMU_APB_ALL
362 PMU_APB_DMA
363 PMU_APB_I2C
364 PMU_APB_SPI1
365 PMU_APB_SPI2
366 PMU_APB_UART0
367 PMU_APB_UART1
368 PMU_APB_UART2
369 PMU_APB_UART3
370 PMU_APB_UART4
371 PMU_APB_UART5
372 PMU_APB_ISO78160
373 PMU_APB_ISO78161
374 PMU_APB_TIMER
375 PMU_APB_MISC
376 PMU_APB_U32K0
377 PMU_APB_U32K1
378 AHBPeriphralDisable:
379 PMU_AHB_ALL
380 PMU_AHB_DMA
381 PMU_AHB_GPIO
382 PMU_AHB_LCD
383 PMU_AHB_CRYPT
384
385 * @note This function performs the following:
386 Comparator 1 power control ON or OFF(optional)
387 Comparator 2 power control ON or OFF(optional)
388 Tiny ADC power control ON or OFF(optional)
389 Bandgap power control ON or OFF(optional)
390 AVCC power control ON or OFF(optional)
391 LCD controller power control ON or OFF(optional)
392 VDCIN detector control Disable or Enable(optional)
393 VDD detector control Disable or Enable(optional)
394 Disable AHB/APB periphral clock Modules(optional)
395 Disable AVCC output
396 Power down ADC, Power down Temp sensor
397 Disable resistance/capacitance division for ADC input signal
398
399 * @retval 1: Current MODE is debug mode, enter deep-sleep mode failed.
400 2: VDCIN is not drop before enter deep-sleep mode or Failure to enter deep sleep mode.
401 */
PMU_EnterDSleep_LowPower(PMU_LowPWRTypeDef * InitStruct)402 uint8_t PMU_EnterDSleep_LowPower(PMU_LowPWRTypeDef *InitStruct)
403 {
404 uint32_t tmp;
405 uint32_t hclk;
406
407 /* Check parameters */
408 assert_parameters(IS_PMU_COMP1PWR(InitStruct->COMP1Power));
409 assert_parameters(IS_PMU_COMP2PWR(InitStruct->COMP2Power));
410 assert_parameters(IS_PMU_TADCPWR(InitStruct->TADCPower));
411 assert_parameters(IS_PMU_BGPPWR(InitStruct->BGPPower));
412 assert_parameters(IS_PMU_AVCCPWR(InitStruct->AVCCPower));
413 assert_parameters(IS_PMU_LCDPWER(InitStruct->LCDPower));
414 assert_parameters(IS_PMU_VDCINDET(InitStruct->VDCINDetector));
415 assert_parameters(IS_PMU_VDDDET(InitStruct->VDDDetector));
416
417 /* Current MODE is 0, debug mode, return error */
418 if (!(PMU->STS & PMU_STS_MODE))
419 return 1;
420
421 /* Disable AVCC output */
422 ANA->REGF &= ~ANA_REGF_AVCCO_EN;
423 /* Power down ADC */
424 ana_reg3_tmp &= ~ANA_REG3_ADCPDN;
425 ANA->REG3 = ana_reg3_tmp;
426 /* Power down Temp sensor */
427 while (ANA->ADCCTRL & ANA_ADCCTRL_MTRIG);
428 ANA->ADCCTRL &= ~(ANA_ADCCTRL_MCH | ANA_ADCCTRL_ACH);
429 /* Disable resistor/cap division for ADC input signal */
430 ANA->REG1 &= ~(ANA_REG1_RESDIV | ANA_REG1_GDE4);
431
432 /******** Comparator 1 power control ********/
433 ana_reg3_tmp &= ~ANA_REG3_CMP1PDN;
434 ana_reg3_tmp |= InitStruct->COMP1Power;
435 ANA->REG3 = ana_reg3_tmp;
436
437 /******** Comparator 2 power control ********/
438 ana_reg3_tmp &= ~ANA_REG3_CMP2PDN;
439 ana_reg3_tmp |= InitStruct->COMP2Power;
440 ANA->REG3 = ana_reg3_tmp;
441
442 /******** Tiny ADC power control ********/
443 tmp = ANA->REGF;
444 tmp &= ~ANA_REGF_PDNADT;
445 tmp |= InitStruct->TADCPower;
446 ANA->REGF = tmp;
447
448 /******** BGP power control ********/
449 ana_reg3_tmp &= ~ANA_REG3_BGPPD;
450 ana_reg3_tmp |= InitStruct->BGPPower;
451 ANA->REG3 = ana_reg3_tmp;
452
453 /******** AVCC power control ********/
454 tmp = ANA->REG8;
455 tmp &= ~ANA_REG8_PD_AVCCLDO;
456 tmp |= InitStruct->AVCCPower;
457 ANA->REG8 = tmp;
458
459 /******** LCD controller power control ********/
460 tmp = LCD->CTRL;
461 tmp &= ~LCD_CTRL_EN;
462 tmp |= InitStruct->LCDPower;
463 LCD->CTRL = tmp;
464 /* LCD power off, disable all SEG */
465 if (InitStruct->LCDPower == PMU_LCDPWER_OFF)
466 {
467 LCD->SEGCTRL0 = 0;
468 LCD->SEGCTRL1 = 0;
469 LCD->SEGCTRL2 = 0;
470 }
471
472 /******** VDCIN detector control ********/
473 tmp = ANA->REGA;
474 tmp &= ~ANA_REGA_PD_VDCINDET;
475 tmp |= InitStruct->VDCINDetector;
476 ANA->REGA = tmp;
477
478 /******** VDD detector control *********/
479 tmp = ANA->REG9;
480 tmp &= ~ANA_REG9_PDDET;
481 tmp |= InitStruct->VDDDetector;
482 ANA->REG9 = tmp;
483
484 /******** AHB Periphral clock disable selection ********/
485 tmp = MISC2->HCLKEN;
486 tmp &= ~((InitStruct->AHBPeriphralDisable) & PMU_AHB_ALL);
487 MISC2->HCLKEN = tmp;
488
489 /******** APB Periphral clock disable selection ********/
490 tmp = MISC2->PCLKEN;
491 tmp &= ~((InitStruct->APBPeriphralDisable) & PMU_APB_ALL);
492 MISC2->PCLKEN = tmp;
493
494 if ((InitStruct->VDCINDetector) != PMU_VDCINDET_DISABLE)
495 {
496 if (!(ANA->COMPOUT & ANA_COMPOUT_VDCINDROP))
497 {
498 return 2;
499 }
500 }
501 // make sure WKU is 0 before entering deep-sleep mode
502 while (PMU->DSLEEPEN & PMU_DSLEEPEN_WKU);
503
504 /* Flash 1USCYCLE configure */
505 hclk = CLK_GetHCLKFreq();
506 if(hclk > 1000000)
507 {
508 MISC2->FLASHWC = (hclk/1000000)<<8;
509 }
510 else
511 {
512 MISC2->FLASHWC = 0<<8;
513 }
514
515 ANA->REG7 &= ~BIT5;
516 ANA->REGA |= BIT3 | BIT1;
517 /* Enter deep-sleep mode */
518 PMU->DSLEEPPASS = DSLEEPPASS_KEY;
519 PMU->DSLEEPEN = DSLEEPEN_KEY;
520
521 return 2;
522 }
523
524 /**
525 * @brief Control low-power configuration, enter sleep mode.
526 *
527 * @param InitStruct : pointer to PMU_LowPWRTypeDef
528 COMP1Power:
529 PMU_COMP1PWR_ON
530 PMU_COMP1PWR_OFF
531 COMP2Power:
532 PMU_COMP2PWR_ON
533 PMU_COMP2PWR_OFF
534 TADCPower:
535 PMU_TADCPWR_ON
536 PMU_TADCPWR_OFF
537 BGPPower:
538 PMU_BGPPWR_ON
539 PMU_BGPPWR_OFF
540 AVCCPower:
541 PMU_AVCCPWR_ON
542 PMU_AVCCPWR_OFF
543 LCDPower:
544 PMU_LCDPWER_ON
545 PMU_LCDPWER_OFF
546 VDCINDetector:
547 PMU_VDCINDET_ENABLE
548 PMU_VDCINDET_DISABLE
549 VDDDetector:
550 PMU_VDDDET_ENABLE
551 PMU_VDDDET_DISABLE
552 APBPeriphralDisable:
553 PMU_APB_ALL
554 PMU_APB_DMA
555 PMU_APB_I2C
556 PMU_APB_SPI1
557 PMU_APB_SPI2
558 PMU_APB_UART0
559 PMU_APB_UART1
560 PMU_APB_UART2
561 PMU_APB_UART3
562 PMU_APB_UART4
563 PMU_APB_UART5
564 PMU_APB_ISO78160
565 PMU_APB_ISO78161
566 PMU_APB_TIMER
567 PMU_APB_MISC
568 PMU_APB_U32K0
569 PMU_APB_U32K1
570 AHBPeriphralDisable:
571 PMU_AHB_ALL
572 PMU_AHB_DMA
573 PMU_AHB_GPIO
574 PMU_AHB_LCD
575 PMU_AHB_CRYPT
576
577 * @note This function performs the following:
578 Comparator 1 power control ON or OFF(optional)
579 Comparator 2 power control ON or OFF(optional)
580 Tiny ADC power control ON or OFF(optional)
581 Bandgap power control ON or OFF(optional)
582 AVCC power control ON or OFF(optional)
583 LCD controller power control ON or OFF(optional)
584 VDCIN detector control Disable or Enable(optional)
585 VDD detector control Disable or Enable(optional)
586 Disable AHB/APB periphral clock Modules(optional)
587 Disable AVCC output
588 Power down ADC, Power down Temp sensor
589 Disable resistance/capacitance division for ADC input signal
590
591 * @retval 2: VDCIN is not drop before enter sleep mode(failed).
592 1: Current mode is debug mode, enter sleep mode failed.
593 0: Quit from sleep mode success.
594 */
PMU_EnterSleep_LowPower(PMU_LowPWRTypeDef * InitStruct)595 uint8_t PMU_EnterSleep_LowPower(PMU_LowPWRTypeDef *InitStruct)
596 {
597 uint32_t tmp;
598 uint32_t hclk;
599
600 /* Check parameters */
601 assert_parameters(IS_PMU_COMP1PWR(InitStruct->COMP1Power));
602 assert_parameters(IS_PMU_COMP2PWR(InitStruct->COMP2Power));
603 assert_parameters(IS_PMU_TADCPWR(InitStruct->TADCPower));
604 assert_parameters(IS_PMU_BGPPWR(InitStruct->BGPPower));
605 assert_parameters(IS_PMU_AVCCPWR(InitStruct->AVCCPower));
606 assert_parameters(IS_PMU_LCDPWER(InitStruct->LCDPower));
607 assert_parameters(IS_PMU_VDCINDET(InitStruct->VDCINDetector));
608 assert_parameters(IS_PMU_VDDDET(InitStruct->VDDDetector));
609
610 /* Current MODE is 0, debug mode, return error */
611 if (!(PMU->STS & PMU_STS_MODE))
612 return 1;
613
614 /* Disable AVCC output */
615 ANA->REGF &= ~ANA_REGF_AVCCO_EN;
616 /* Power down ADC */
617 ana_reg3_tmp &= ~ANA_REG3_ADCPDN;
618 ANA->REG3 = ana_reg3_tmp;
619 /* Power down Temp sensor */
620 while (ANA->ADCCTRL & ANA_ADCCTRL_MTRIG);
621 ANA->ADCCTRL &= ~(ANA_ADCCTRL_MCH | ANA_ADCCTRL_ACH);
622 /* Disable resistor/cap division for ADC input signal */
623 ANA->REG1 &= ~(ANA_REG1_RESDIV | ANA_REG1_GDE4);
624
625 /******** Comparator 1 power control ********/
626 ana_reg3_tmp &= ~ANA_REG3_CMP1PDN;
627 ana_reg3_tmp |= InitStruct->COMP1Power;
628 ANA->REG3 = ana_reg3_tmp;
629
630 /******** Comparator 2 power control ********/
631 ana_reg3_tmp &= ~ANA_REG3_CMP2PDN;
632 ana_reg3_tmp |= InitStruct->COMP2Power;
633 ANA->REG3 = ana_reg3_tmp;
634
635 /******** Tiny ADC power control ********/
636 tmp = ANA->REGF;
637 tmp &= ~ANA_REGF_PDNADT;
638 tmp |= InitStruct->TADCPower;
639 ANA->REGF = tmp;
640
641 /******** BGP power control ********/
642 ana_reg3_tmp &= ~ANA_REG3_BGPPD;
643 ana_reg3_tmp |= InitStruct->BGPPower;
644 ANA->REG3 = ana_reg3_tmp;
645
646 /******** AVCC power control ********/
647 tmp = ANA->REG8;
648 tmp &= ~ANA_REG8_PD_AVCCLDO;
649 tmp |= InitStruct->AVCCPower;
650 ANA->REG8 = tmp;
651
652 /******** LCD controller power control ********/
653 tmp = LCD->CTRL;
654 tmp &= ~LCD_CTRL_EN;
655 tmp |= InitStruct->LCDPower;
656 LCD->CTRL = tmp;
657 /* LCD power off, disable all SEG */
658 if (InitStruct->LCDPower == PMU_LCDPWER_OFF)
659 {
660 LCD->SEGCTRL0 = 0;
661 LCD->SEGCTRL1 = 0;
662 LCD->SEGCTRL2 = 0;
663 }
664
665 /******** VDCIN detector control ********/
666 tmp = ANA->REGA;
667 tmp &= ~ANA_REGA_PD_VDCINDET;
668 tmp |= InitStruct->VDCINDetector;
669 ANA->REGA = tmp;
670
671 /******** VDD detector control *********/
672 tmp = ANA->REG9;
673 tmp &= ~ANA_REG9_PDDET;
674 tmp |= InitStruct->VDDDetector;
675 ANA->REG9 = tmp;
676
677 /******** AHB Periphral clock disable selection ********/
678 tmp = MISC2->HCLKEN;
679 tmp &= ~((InitStruct->AHBPeriphralDisable) & PMU_AHB_ALL);
680 MISC2->HCLKEN = tmp;
681
682 /******** APB Periphral clock disable selection ********/
683 tmp = MISC2->PCLKEN;
684 tmp &= ~((InitStruct->APBPeriphralDisable) & PMU_APB_ALL);
685 MISC2->PCLKEN = tmp;
686
687 if ((InitStruct->VDCINDetector) != PMU_VDCINDET_DISABLE)
688 {
689 if (!(ANA->COMPOUT & ANA_COMPOUT_VDCINDROP))
690 {
691 return 2;
692 }
693 }
694
695 /* Flash 1USCYCLE configure */
696 hclk = CLK_GetHCLKFreq();
697 if(hclk > 1000000)
698 {
699 MISC2->FLASHWC = (hclk/1000000)<<8;
700 }
701 else
702 {
703 MISC2->FLASHWC = 0<<8;
704 }
705
706 ANA->REG7 &= ~BIT5;
707 ANA->REGA |= BIT3 | BIT1;
708 /* Set SLEEPDEEP bit of Cortex-M0 System Control Register */
709 SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
710 __WFI();
711
712 return 0;
713 }
714
715
716 /**
717 * @brief Flash deep standby, enter idle mode.
718 * @param None
719 * @retval None
720 */
721 #ifndef __GNUC__
PMU_EnterIdle_LowPower(void)722 void PMU_EnterIdle_LowPower(void)
723 {
724 uint32_t hclk;
725
726 /* Flash 1USCYCLE configure */
727 hclk = CLK_GetHCLKFreq();
728 if(hclk > 1000000)
729 {
730 MISC2->FLASHWC = (hclk/1000000)<<8;
731 }
732 else
733 {
734 MISC2->FLASHWC = 0<<8;
735 }
736
737 PMU_EnterIdle_FlashDSTB();
738 }
739 #endif
740
741 /**
742 * @brief IOA wake-up source configure about Sleep mode.
743 * @param IOAx: GPIO_Pin_0 ~ GPIO_Pin_15
744 Wakeup_Event:
745 IOA_DISABLE
746 IOA_RISING
747 IOA_FALLING
748 IOA_HIGH
749 IOA_LOW
750 IOA_EDGEBOTH
751 Priority: The preemption priority for the IRQn channel.
752 This parameter can be a value between 0 and 3.
753 * @retval
754 */
PMU_SleepWKUSRC_Config_IOA(uint16_t IOAx,uint32_t Wakeup_Event,uint32_t Priority)755 void PMU_SleepWKUSRC_Config_IOA(uint16_t IOAx, uint32_t Wakeup_Event, uint32_t Priority)
756 {
757 /* Check parameters */
758 assert_parameters(IS_GPIO_PINR(IOAx));
759 assert_parameters(IS_PMU_WAKEUP(Wakeup_Event));
760
761 /* Disable PMU interrupt in NVIC */
762 NVIC_DisableIRQ(PMU_IRQn);
763 /* Wake-up pins configuration */
764 PMU_WakeUpPinConfig(IOAx, Wakeup_Event);
765 /* Clear interrupt flag */
766 PMU->IOAINTSTS = IOAx;
767 /* Enable PMU interrupt */
768 PMU->CONTROL |= PMU_CONTROL_INT_IOA_EN;
769 CORTEX_SetPriority_ClearPending_EnableIRQ(PMU_IRQn, Priority);
770 }
771
772 /**
773 * @brief RTC wake-up source configure about Sleep mode.
774 * @param Wakeup_Event:
775 This parameter can be any combination of the following values
776 PMU_RTCEVT_ACDONE
777 PMU_RTCEVT_WKUCNT
778 PMU_RTCEVT_MIDNIGHT
779 PMU_RTCEVT_WKUHOUR
780 PMU_RTCEVT_WKUMIN
781 PMU_RTCEVT_WKUSEC
782 PMU_RTCEVT_TIMEILLE
783 Priority: The preemption priority for the IRQn channel.
784 This parameter can be a value between 0 and 3.
785 * @retval
786 */
PMU_SleepWKUSRC_Config_RTC(uint32_t Wakeup_Event,uint32_t Priority)787 void PMU_SleepWKUSRC_Config_RTC(uint32_t Wakeup_Event, uint32_t Priority)
788 {
789 /* Check parameters */
790 assert_parameters(IS_PMU_RTCEVT(Wakeup_Event));
791
792 /* Disable RTC interrupt in NVIC */
793 NVIC_DisableIRQ(RTC_IRQn);
794 /* Clear interrupt flag */
795 RTC->INTSTS = Wakeup_Event;
796 /* Enable RTC interrupt */
797 RTC->INTEN |= Wakeup_Event & (~0x01UL);
798 CORTEX_SetPriority_ClearPending_EnableIRQ(RTC_IRQn, Priority);
799 }
800 /**
801 * @brief IOA wake-up source configure about Deep-Sleep mode.
802 * @param IOAx: GPIO_Pin_0 ~ GPIO_Pin_15
803 Wakeup_Event:
804 IOA_DISABLE
805 IOA_RISING
806 IOA_FALLING
807 IOA_HIGH
808 IOA_LOW
809 IOA_EDGEBOTH
810 * @retval
811 */
PMU_DeepSleepWKUSRC_Config_IOA(uint16_t IOAx,uint32_t Wakeup_Event)812 void PMU_DeepSleepWKUSRC_Config_IOA(uint16_t IOAx, uint32_t Wakeup_Event)
813 {
814 /* Check parameters */
815 assert_parameters(IS_GPIO_PINR(IOAx));
816 assert_parameters(IS_PMU_WAKEUP(Wakeup_Event));
817
818 /* Wake-up pins configuration */
819 PMU_WakeUpPinConfig(IOAx, Wakeup_Event);
820 /* Clear interrupt flag */
821 PMU->IOAINTSTS = IOAx;
822 }
823
824 /**
825 * @brief RTC wake-up source configure about Deep-Sleep mode.
826 * @param Wakeup_Event:
827 This parameter can be any combination of the following values
828 PMU_RTCEVT_ACDONE
829 PMU_RTCEVT_WKUCNT
830 PMU_RTCEVT_MIDNIGHT
831 PMU_RTCEVT_WKUHOUR
832 PMU_RTCEVT_WKUMIN
833 PMU_RTCEVT_WKUSEC
834 PMU_RTCEVT_TIMEILLE
835 * @retval
836 */
PMU_DeepSleepWKUSRC_Config_RTC(uint32_t Wakeup_Event)837 void PMU_DeepSleepWKUSRC_Config_RTC(uint32_t Wakeup_Event)
838 {
839 /* Check parameters */
840 assert_parameters(IS_PMU_RTCEVT(Wakeup_Event));
841
842 /* Clear interrupt flag */
843 RTC->INTSTS = Wakeup_Event;
844 /* Enable RTC interrupt */
845 RTC->INTEN |= Wakeup_Event & (~0x01UL);
846 }
847
848 /**
849 * @brief Set the deep sleep behavior when VDD/VDCIN is not drop.
850 * @param VDCIN_PDNS:
851 PMU_VDCINPDNS_0 , can't enter deep-sleep mode when VDCIN is not drop
852 can wake-up mcu from deep-sleep, when VDCIN is not drop.
853 PMU_VDCINPDNS_1 , The condition for entering deep sleep mode is independent of VDCIN.
854 VDD_PDNS:
855 PMU_VDDPDNS_0 , can't enter deep-sleep mode when VDD is not drop(>Threshold)
856 can wake-up mcu from deep-sleep, when VDD is not drop.
857 PMU_VDDPDNS_1 , The condition for entering deep sleep mode is independent of VDD.
858 * @retval None
859 */
PMU_PDNDSleepConfig(uint32_t VDCIN_PDNS,uint32_t VDD_PDNS)860 void PMU_PDNDSleepConfig(uint32_t VDCIN_PDNS, uint32_t VDD_PDNS)
861 {
862 uint32_t tmp;
863
864 /* Check parameters */
865 assert_parameters(IS_PMU_VDCINPDNS(VDCIN_PDNS));
866 assert_parameters(IS_PMU_VDDPDNS(VDD_PDNS));
867
868 tmp = ANA->CTRL;
869 tmp &= ~(ANA_CTRL_PDNS | ANA_CTRL_PDNS2);
870 tmp |= (VDCIN_PDNS | VDD_PDNS);
871
872 ANA->CTRL = tmp;
873 }
874
875 /**
876 * @brief BGP power control.
877 * @param NewState:
878 * ENABLE
879 * DISABLE
880 * @retval None
881 */
PMU_BGP_Cmd(uint32_t NewState)882 void PMU_BGP_Cmd(uint32_t NewState)
883 {
884 /* Check parameters */
885 assert_parameters(IS_FUNCTIONAL_STATE(NewState));
886
887 if (NewState == ENABLE)
888 ana_reg3_tmp &= ~ANA_REG3_BGPPD;
889 else
890 ana_reg3_tmp |= ANA_REG3_BGPPD;
891 ANA->REG3 = ana_reg3_tmp;
892 }
893
894 /**
895 * @brief Configure VDD alarm threshold voltage.
896 * @param PowerThreshold:
897 * PMU_PWTH_4_5
898 * PMU_PWTH_4_2
899 * PMU_PWTH_3_9
900 * PMU_PWTH_3_6
901 * PMU_PWTH_3_2
902 * PMU_PWTH_2_9
903 * PMU_PWTH_2_6
904 * PMU_PWTH_2_3
905 * @retval None
906 */
PMU_VDDAlarmTHConfig(uint32_t PowerThreshold)907 void PMU_VDDAlarmTHConfig(uint32_t PowerThreshold)
908 {
909 uint32_t tmp;
910
911 /* Check parameters */
912 assert_parameters(IS_PMU_PWTH(PowerThreshold));
913
914 tmp = ANA->REG8;
915 tmp &= ~ANA_REG8_VDDPVDSEL;
916 tmp |= PowerThreshold;
917
918 ANA->REG8 = tmp;
919 }
920
921 /**
922 * @brief Get POWALARM status.
923 * @param None
924 * @retval POWALARM status
925 * 0: Voltage of VDD is higher than threshold.
926 * 1: Voltage of VDD is lower than threshold.
927 */
PMU_GetVDDALARMStatus(void)928 uint8_t PMU_GetVDDALARMStatus(void)
929 {
930 if (ANA->COMPOUT & ANA_COMPOUT_VDDALARM)
931 return 1;
932 else
933 return 0;
934 }
935
936 /**
937 * @brief VDD detector enable control.
938 * @param NewState:
939 * ENABLE
940 * DISABLE
941 * @retval None
942 */
PMU_VDDDetectorCmd(uint32_t NewState)943 void PMU_VDDDetectorCmd(uint32_t NewState)
944 {
945 /* Check parameter */
946 assert_parameters(IS_FUNCTIONAL_STATE(NewState));
947
948 if (NewState == ENABLE)
949 ANA->REG9 &= ~ANA_REG9_PDDET;
950 else
951 ANA->REG9 |= ANA_REG9_PDDET;
952 }
953
954 /**
955 * @brief Gets current MODE pin status.
956 * @param None
957 * @retval MODE pin status
958 * 0: Debug mode.
959 * 1: Normal mode.
960 */
PMU_GetModeStatus(void)961 uint8_t PMU_GetModeStatus(void)
962 {
963 if(PMU->STS & PMU_STS_MODE)
964 return 1;
965 else
966 return 0;
967 }
968
969 /**
970 * @brief Control AVCC enable.
971 * @param NewState:
972 * ENABLE
973 * DISABLE
974 * @retval None
975 */
PMU_AVCC_Cmd(uint32_t NewState)976 void PMU_AVCC_Cmd(uint32_t NewState)
977 {
978 /* Check parameters */
979 assert_parameters(IS_FUNCTIONAL_STATE(NewState));
980
981 if (NewState == ENABLE)
982 ANA->REG8 &= ~ANA_REG8_PD_AVCCLDO;
983 else
984 ANA->REG8 |= ANA_REG8_PD_AVCCLDO;
985 }
986
987 /**
988 * @brief Control VDD33_O pin power.
989 * @param NewState:
990 * ENABLE
991 * DISABLE
992 * @retval None
993 */
PMU_AVCCOutput_Cmd(uint32_t NewState)994 void PMU_AVCCOutput_Cmd(uint32_t NewState)
995 {
996 /* Check parameters */
997 assert_parameters(IS_FUNCTIONAL_STATE(NewState));
998
999 if (NewState == DISABLE)
1000 ANA->REGF &= ~ANA_REGF_AVCCO_EN;
1001 else
1002 ANA->REGF |= ANA_REGF_AVCCO_EN;
1003 }
1004
1005 /**
1006 * @brief AVCC Low Voltage detector power control.
1007 * @param NewState:
1008 * ENABLE
1009 * DISABLE
1010 * @retval None
1011 */
PMU_AVCCLVDetector_Cmd(uint32_t NewState)1012 void PMU_AVCCLVDetector_Cmd(uint32_t NewState)
1013 {
1014 /* Check parameters */
1015 assert_parameters(IS_FUNCTIONAL_STATE(NewState));
1016
1017 if (NewState == ENABLE)
1018 ANA->REG5 &= ~ANA_REG5_PD_AVCCDET;
1019 else
1020 ANA->REG5 |= ANA_REG5_PD_AVCCDET;
1021 }
1022
1023 /**
1024 * @brief Get AVCC low power status.
1025 * @param None
1026 * @retval low power status of AVCC
1027 * 0: status not set, AVCC is higher than 2.5V.
1028 * 1: status set, AVCC is lower than 2.5V.
1029 */
PMU_GetAVCCLVStatus(void)1030 uint8_t PMU_GetAVCCLVStatus(void)
1031 {
1032 if (ANA->COMPOUT & ANA_COMPOUT_AVCCLV)
1033 return 1;
1034 else
1035 return 0;
1036 }
1037
1038 /**
1039 * @brief Control VDCIN decector enable.
1040 * @param NewState:
1041 * ENABLE
1042 * DISABLE
1043 * @retval None
1044 */
PMU_VDCINDetector_Cmd(uint32_t NewState)1045 void PMU_VDCINDetector_Cmd(uint32_t NewState)
1046 {
1047 /* Check parameters */
1048 assert_parameters(IS_FUNCTIONAL_STATE(NewState));
1049
1050 if (NewState == ENABLE)
1051 ANA->REGA &= ~ANA_REGA_PD_VDCINDET;
1052 else
1053 ANA->REGA |= ANA_REGA_PD_VDCINDET;
1054 }
1055
1056 /**
1057 * @brief Get VDCIN drop status.
1058 * @param None
1059 * @retval drop status of VDCIN
1060 * 0: status not set, VDCIN is not drop.
1061 * 1: status set, VDCIN is drop.
1062 */
PMU_GetVDCINDropStatus(void)1063 uint8_t PMU_GetVDCINDropStatus(void)
1064 {
1065 if (ANA->COMPOUT & ANA_COMPOUT_VDCINDROP)
1066 return 1;
1067 else
1068 return 0;
1069 }
1070
1071 /**
1072 * @brief Discharge the BAT battery.
1073 * @param BATDisc:
1074 * PMU_BATRTC_DISC
1075 * NewState:
1076 * ENABLE
1077 * DISABLE
1078 * @retval None
1079 */
PMU_BATDischargeConfig(uint32_t BATDisc,uint32_t NewState)1080 void PMU_BATDischargeConfig(uint32_t BATDisc, uint32_t NewState)
1081 {
1082 /* Check parameters */
1083 assert_parameters(IS_PMU_BATRTCDISC(BATDisc));
1084 assert_parameters(IS_FUNCTIONAL_STATE(NewState));
1085
1086 if (NewState == ENABLE)
1087 ANA->REG6 |= BATDisc;
1088 else
1089 ANA->REG6 &= ~BATDisc;
1090 }
1091
1092 /**
1093 * @brief Power drop de-bounce control.
1094 * @param Debounce:
1095 * PMU_PWRDROP_DEB_0
1096 * PMU_PWRDROP_DEB_1
1097 * PMU_PWRDROP_DEB_2
1098 * PMU_PWRDROP_DEB_3
1099 * @retval None
1100 */
PMU_PWRDropDEBConfig(uint32_t Debounce)1101 void PMU_PWRDropDEBConfig(uint32_t Debounce)
1102 {
1103 uint32_t tmp;
1104
1105 /* Check parameters */
1106 assert_parameters(IS_PMU_PWRDROP_DEB(Debounce));
1107
1108 tmp = ANA->CTRL;
1109 tmp &= ~ANA_CTRL_PWRDROPDEB;
1110 tmp |= Debounce;
1111
1112 ANA->CTRL = tmp;
1113 }
1114
1115 /**
1116 * @brief Get last reset source.
1117 * @param RSTSource:
1118 PMU_RSTSRC_EXTRST
1119 PMU_RSTSRC_PORST
1120 PMU_RSTSRC_DPORST
1121 * @retval 1:status set
1122 0:status reset
1123 */
PMU_GetRSTSource(uint32_t RSTSource)1124 uint8_t PMU_GetRSTSource(uint32_t RSTSource)
1125 {
1126 /* Check parameters */
1127 assert_parameters(IS_PMU_RSTSRC(RSTSource));
1128
1129 if (PMU->STS & RSTSource)
1130 {
1131 PMU->STS = RSTSource; //Clear flag
1132 return (1);
1133 }
1134 else
1135 {
1136 return (0);
1137 }
1138 }
1139
1140 /**
1141 * @brief Get power status.
1142 * @param StatusMask:
1143 PMU_PWRSTS_AVCCLV
1144 PMU_PWRSTS_VDCINDROP
1145 PMU_PWRSTS_VDDALARM
1146 * @retval power status
1147 * 1 status set
1148 * 0 status not set
1149 */
PMU_GetPowerStatus(uint32_t StatusMask)1150 uint8_t PMU_GetPowerStatus(uint32_t StatusMask)
1151 {
1152 if (ANA->COMPOUT & StatusMask)
1153 return 1;
1154 else
1155 return 0;
1156 }
1157
1158 /*********************************** END OF FILE ******************************/
1159