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