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