ADuCM4x50 Device Drivers API Reference Manual  Release 4.0.0.0
adi_pwr.c
1 
24 #include <stdlib.h> /* for 'NULL' */
25 #include <adi_callback.h>
26 #include <adi_pwr_config.h>
27 #include <rtos_map/adi_rtos_map.h>
28 #include <drivers/pwr/adi_pwr.h>
29 #include "adi_pwr_def.h"
30 #include <drivers/gpio/adi_gpio.h>
31 
32 #ifdef __ICCARM__
33 /*
34 * IAR MISRA C 2004 error suppressions.
35 *
36 * Pm011 (rule 6.3): Types which specify sign and size should be used
37 * We use bool which is accepted by MISRA but the toolchain does not accept it
38 * Pm073 (rule 14.7): a function should have a single point of exit
39 * Pm143 (rule 14.7): a function should have a single point of exit at the end of the function
40 * Multiple returns are used for error handling.
41 * Pm140 (rule 11.3): a cast should not be performed between a pointer type and an integral type
42 * The rule makes an exception for memory-mapped register accesses.
43 * Pm057 (rule 15.2): Every non-empty case clause in a switch statement shall be terminated with a break statement.
44 * In some cases we have return statement instead of break. It is not valid to both return and break in MISRA 2012.
45 */
46 #pragma diag_suppress=Pm011,Pm073,Pm050,Pm140,Pm143,Pm057
47 #endif /* __ICCARM__ */
48 
51 /*----------------------------------------------------------------------------
52  Internal Clock Variables. The external ones are defined in system.c
53  *---------------------------------------------------------------------------*/
54 #ifdef ADI_DEBUG
55 /* not needed unless its debug mode */
56 extern uint32_t lfClock; /* "lf_clk" coming out of LF mux */
57 #endif
58 
59 extern uint32_t hfClock; /* "root_clk" output of HF mux */
60 extern uint32_t gpioClock; /* external GPIO clock */
61 
62 static ADI_CALLBACK gpfCallbackFunction;
63 static void *gpPowcbParam = NULL;
64 static uint32_t gnLowPowerIntOccFlag = 0u;
65 
68 /*----------------------------------------------------------------------------
69  Clock functions
70  *---------------------------------------------------------------------------*/
78 {
79  /* Enable internal HF oscillators */
80  pADI_CLKG0_OSC->KEY = ADI_OSC_KEY;
81 
82  pADI_CLKG0_OSC->CTL = OSCCTRL_CONFIG_VALUE;
83 
84  gpfCallbackFunction = NULL;
85  pADI_CLKG0_OSC->KEY = ADI_OSC_KEY;
86 
87  /* Switch on the internal HF oscillator */
88  pADI_CLKG0_OSC->CTL |= BITM_CLKG_OSC_CTL_HFOSC_EN;
89 
90  /* wait for HF OSC to stabilize */
91  while ((pADI_CLKG0_OSC->CTL & (1U << BITP_CLKG_OSC_CTL_HFOSC_OK)) == 0u)
92  {
93  }
94 
95  /* Switch over to the internal HF oscillator */
96  pADI_CLKG0_CLK->CTL0 &= ~(BITM_CLKG_CLK_CTL0_CLKMUX);
97 
98  /* complete remaining reset sequence */
99  pADI_CLKG0_CLK->CTL0 = CLOCK_CTL0_CONFIG_VALUE;
100  pADI_CLKG0_CLK->CTL1 = CLOCK_CTL1_CONFIG_VALUE;
101 
102 #if defined(__ADUCM4x50__)
103  pADI_CLKG0_CLK->CTL2 = CLOCK_CTL2_CONFIG_VALUE;
104 #endif /*__ADUCM4x50__ */
105 
106  pADI_CLKG0_CLK->CTL3 = CLOCK_CTL3_CONFIG_VALUE;
107  /* No CLK CTL4 */
108  pADI_CLKG0_CLK->CTL5 = CLOCK_CTL5_CONFIG_VALUE;
109 
110  /*
111  * Configure the power management registers
112  */
113  pADI_PMG0->IEN = PWM_INTERRUPT_CONFIG;
114  pADI_PMG0->PWRMOD = PWM_PWRMOD_CONFIG;
115  pADI_PMG0->CTL1 = PWM_HPBUCK_CONTROL;
116 
117  /* disable external HF crystal oscillator */
118  /* (don't disable LF crystal or the RTC will lose time */
119  pADI_CLKG0_OSC->KEY = ADI_OSC_KEY;
120  pADI_CLKG0_OSC->CTL &= ~BITM_CLKG_OSC_CTL_HFX_EN;
121 
122  NVIC_EnableIRQ(PMG0_VREG_OVR_IRQn);
123  NVIC_EnableIRQ(PMG0_BATT_RANGE_IRQn);
124 
125  NVIC_EnableIRQ(CLKG_XTAL_OSC_EVT_IRQn);
126  NVIC_EnableIRQ(CLKG_PLL_EVT_IRQn);
127 
128  /* compute new internal clocks based on the newly reset controller */
130 
131  return(ADI_PWR_SUCCESS);
132 }
133 
134 
148 {
150  return(ADI_PWR_SUCCESS);
151 }
152 
167  const ADI_CALLBACK pfCallback,
168  void *pcbParam
169  )
170 {
171 
172 #ifdef ADI_DEBUG
173  if(pfCallback == NULL)
174  {
175  return(ADI_PWR_NULL_POINTER);
176  }
177 #endif
178 
179  gpfCallbackFunction = pfCallback;
180  gpPowcbParam = pcbParam;
181 
182  return ADI_PWR_SUCCESS;
183 }
184 
196 ADI_PWR_RESULT adi_pwr_SetExtClkFreq (const uint32_t ExtClkFreq)
197 {
198 #ifdef ADI_DEBUG
199  if(ExtClkFreq > MAXIMUM_EXT_CLOCK)
200  {
202  }
203 #endif
204  gpioClock = ExtClkFreq;
205  return(ADI_PWR_SUCCESS);
206 }
207 
220 {
221  uint32_t tmp;
222  ADI_INT_STATUS_ALLOC();
223 
224 #ifdef ADI_DEBUG
225  /* Validate the given clock ID */
226  switch (eClockID)
227  {
230 
231 #if defined(__ADUCM4x50__)
233 #endif /* __ADUCM4x50__ */
234  break;
235 
236 
237  /* Any other clock ID is not valid since we are configuring the SPLL clock multiplexer.
238  * Only valid input clock to the multiplexer is HFOSC, HFXTAL, GPIO */
239  default:
240  return(ADI_PWR_INVALID_CLOCK_ID);
241  }
242 #endif /* ADI_DEBUG */
243 
244  /* update the mux setting inside a critical region */
245  ADI_ENTER_CRITICAL_REGION();
246  tmp = (pADI_CLKG0_CLK->CTL0 & ~BITM_CLKG_CLK_CTL0_PLL_IPSEL);
247  tmp |= (( (uint32_t)eClockID - (uint32_t)ADI_CLOCK_MUX_SPLL_HFOSC) << BITP_CLKG_CLK_CTL0_PLL_IPSEL);
248  pADI_CLKG0_CLK->CTL0 = tmp;
249  ADI_EXIT_CRITICAL_REGION();
250 
251  return(ADI_PWR_SUCCESS);
252 }
253 
267 {
268  uint32_t tmp;
269  ADI_INT_STATUS_ALLOC();
270 
271 #ifdef ADI_DEBUG
272  switch (eClockID)
273  {
274 
277  break;
278  /* Any other clock ID is not valid since we are configuring the Low frequency clock multiplexer.
279  * Only valid input clock to the multiplexer is LFOSC, LFXTAL */
280 
281  default:
282  return(ADI_PWR_INVALID_CLOCK_ID);
283 
284  }
285 #endif /* ADI_DEBUG */
286 
287  /* update the mux setting inside a critical region */
288  ADI_ENTER_CRITICAL_REGION();
289 
290  pADI_CLKG0_OSC->KEY = ADI_OSC_KEY;
291  tmp = (pADI_CLKG0_OSC->CTL & ~BITM_CLKG_OSC_CTL_LFCLK_MUX);
292  tmp |=(((uint32_t)eClockID - (uint32_t)ADI_CLOCK_MUX_LFCLK_LFOSC) << BITP_CLKG_OSC_CTL_LFCLK_MUX);
293  pADI_CLKG0_OSC->CTL = tmp;
294 
295  ADI_EXIT_CRITICAL_REGION();
296 
297  return(ADI_PWR_SUCCESS);
298 }
299 
315 {
316  uint32_t tmp;
317  ADI_INT_STATUS_ALLOC();
318 
319 #ifdef ADI_DEBUG
320  switch (eClockID)
321  {
322 
326  break;
327  /* Any other clock ID is not valid since we are configuring the out clock multiplexer.*/
328 
329  default:
330  return(ADI_PWR_INVALID_CLOCK_ID);
331  }
332 #endif /* ADI_DEBUG */
333 
334  /* update the mux setting inside a critical region */
335  ADI_ENTER_CRITICAL_REGION();
336 
337  tmp = (pADI_CLKG0_CLK->CTL0 & ~BITM_CLKG_CLK_CTL0_RCLKMUX);
338  tmp |=(((uint32_t)eClockID - (uint32_t)ADI_CLOCK_MUX_REF_HFOSC_CLK) << BITP_CLKG_CLK_CTL0_RCLKMUX);
339  pADI_CLKG0_CLK->CTL0 = tmp;
340 
341  ADI_EXIT_CRITICAL_REGION();
342 
343  return(ADI_PWR_SUCCESS);
344 }
345 
359 {
360  uint32_t tmp;
361  ADI_INT_STATUS_ALLOC();
362 
363 #ifdef ADI_DEBUG
364  switch (eClockID)
365  {
370  break;
371  /* Any other clock ID is not valid since we are configuring the root clock multiplexer.
372  * Only valid input clock to the multiplexer is HFOSC, HFXTAL, SPLL, GPIO */
373  default:
374  return(ADI_PWR_INVALID_CLOCK_ID);
375  }
376 #endif /* ADI_DEBUG */
377 
378  /* update the mux setting inside a critical region */
379  ADI_ENTER_CRITICAL_REGION();
380 
381  tmp = (pADI_CLKG0_CLK->CTL0 & ~BITM_CLKG_CLK_CTL0_CLKMUX);
382  tmp |= (((uint32_t)eClockID - (uint32_t)ADI_CLOCK_MUX_ROOT_HFOSC) << BITP_CLKG_CLK_CTL0_CLKMUX);
383  pADI_CLKG0_CLK->CTL0 = tmp;
384 
385  ADI_EXIT_CRITICAL_REGION();
386 
387  return(ADI_PWR_SUCCESS);
388 }
389 
390 
403 {
404 #ifdef ADI_DEBUG
405  /* Trap here if the app fails to set the external clock frequency. */
406  if (0u == gpioClock)
407  {
408  return (ADI_PWR_FAILURE);
409  }
410 
411  if(pExtClock == NULL)
412  {
413  return (ADI_PWR_NULL_POINTER);
414  }
415 #endif
416  *pExtClock = gpioClock;
417  return ADI_PWR_SUCCESS;
418 }
419 
420 
435 ADI_PWR_RESULT adi_pwr_GetClockFrequency (const ADI_CLOCK_ID eClockId, uint32_t *pClock )
436 {
437  uint32_t src, nDiv;
438 
439 #ifdef ADI_DEBUG
440  /* trap here if the app fails to call SystemInit(). */
441  if ((0u == hfClock) || (0u == lfClock))
442  {
444  }
445 #endif
446 
447  /* refresh internal clock variables */
449  src = hfClock;
450 
451  switch (eClockId) {
452 
453  /* HCLOCK domain */
454  case ADI_CLOCK_HCLK:
455  nDiv = (pADI_CLKG0_CLK->CTL1 & BITM_CLKG_CLK_CTL1_HCLKDIVCNT) >> BITP_CLKG_CLK_CTL1_HCLKDIVCNT;
456  break;
457 
458  /* PCLOCK domain */
459  case ADI_CLOCK_PCLK:
460  nDiv = (pADI_CLKG0_CLK->CTL1 & BITM_CLKG_CLK_CTL1_PCLKDIVCNT) >> BITP_CLKG_CLK_CTL1_PCLKDIVCNT;
461  break;
462 
463  default:
465  } /* end switch */
466 
467  if(nDiv == 0u)
468  {
469  nDiv = 1u;
470  }
471 
472  *pClock = (src/nDiv);
473 
474  return ADI_PWR_SUCCESS;
475 }
476 
477 
491 ADI_PWR_RESULT adi_pwr_EnableClock (const ADI_CLOCK_GATE eClockGate, const bool bEnable)
492 {
493  uint32_t mask;
494  ADI_INT_STATUS_ALLOC();
495 
496  mask = (uint16_t)eClockGate;
497  /* update the Clock Gate register in a critical region */
498  ADI_ENTER_CRITICAL_REGION();
499 
500  /* NOTE NEGATIVE LOGIC!!! */
501  if (bEnable == true) {
502 
503  /* clear disable bit */
504  pADI_CLKG0_CLK->CTL5 &= ~mask;
505  } else {
506  /* set disable bit */
507  pADI_CLKG0_CLK->CTL5 |= mask;
508  }
509 
510  /* end critical region */
511  ADI_EXIT_CRITICAL_REGION();
512 
513  return ADI_PWR_SUCCESS;
514 }
515 
516 
533 ADI_PWR_RESULT adi_pwr_SetClockDivider (const ADI_CLOCK_ID eClockId, const uint16_t nDiv)
534 {
535  uint32_t mask;
536  uint32_t value;
537  uint32_t tmp;
538  ADI_INT_STATUS_ALLOC();
539 
540 #ifdef ADI_DEBUG
541  uint32_t hdiv, pdiv;
542 #endif /*ADI_DEBUG*/
543 
544  switch (eClockId)
545  {
546  case ADI_CLOCK_HCLK:
547 #ifdef ADI_DEBUG
548  /* Verify the divide factor is within the range */
549  if ((nDiv > CLOCK_MAX_DIV_VALUE) || (nDiv < CLOCK_MIN_DIV_VALUE))
550  {
552  }
553 
554  /* verify PCLK freq is <= requested HCLK */
555  pdiv = (pADI_CLKG0_CLK->CTL1 & BITM_CLKG_CLK_CTL1_PCLKDIVCNT) >> BITP_CLKG_CLK_CTL1_PCLKDIVCNT;
556  hdiv = nDiv;
557  if (hdiv > pdiv) {
559  }
560 
561  /* verify new PDIV:HDIV ratio will be integral */
562  if ((pdiv % hdiv) != 0u)
563  {
565  }
566 #endif /*ADI_DEBUG*/
567 
568  mask = BITM_CLKG_CLK_CTL1_HCLKDIVCNT;
569  value = (uint32_t)nDiv << BITP_CLKG_CLK_CTL1_HCLKDIVCNT;
570  break;
571 
572  case ADI_CLOCK_PCLK:
573 #ifdef ADI_DEBUG
574 
575  /* Verify the divide factor is within the range */
576  if ((nDiv > CLOCK_MAX_DIV_VALUE) || (nDiv < CLOCK_MIN_DIV_VALUE))
577  {
579  }
580 
581  /* verify requested PCLK freq is <= HCLK */
582  pdiv = nDiv;
583  hdiv = (pADI_CLKG0_CLK->CTL1 & BITM_CLKG_CLK_CTL1_HCLKDIVCNT) >> BITP_CLKG_CLK_CTL1_HCLKDIVCNT;
584  if (hdiv > pdiv) {
586  }
587 
588  /* verify new PDIV:HDIV ratio will be integral */
589  if ((pdiv % hdiv) != 0u)
590  {
592  }
593 #endif /*ADI_DEBUG*/
594  mask = BITM_CLKG_CLK_CTL1_PCLKDIVCNT;
595  value = (uint32_t)nDiv << BITP_CLKG_CLK_CTL1_PCLKDIVCNT;
596  break;
597 
598  case ADI_CLOCK_ACLK:
599 #ifdef ADI_DEBUG
600  /* Verify the divide factor is within the range */
601  if ((nDiv > ACLK_MAX_DIV_VALUE) || (nDiv < ACLK_MIN_DIV_VALUE))
602  {
604  }
605 
606  /* verify requested ACLK freq is <= HCLK */
607  pdiv = nDiv;
608  hdiv = (pADI_CLKG0_CLK->CTL1 & BITM_CLKG_CLK_CTL1_HCLKDIVCNT) >> BITP_CLKG_CLK_CTL1_HCLKDIVCNT;
609  if (hdiv > pdiv) {
611  }
612 
613  /* verify new PDIV:HDIV ratio will be integral */
614  if ((pdiv % hdiv) != 0u)
615  {
617  }
618 #endif /*ADI_DEBUG*/
619 
620  mask = BITM_CLKG_CLK_CTL1_ACLKDIVCNT;
621  value = (uint32_t)nDiv << BITP_CLKG_CLK_CTL1_ACLKDIVCNT;
622  break;
623 
624 
625  default:
627  } /* end switch */
628 
629  /* critical region */
630  ADI_ENTER_CRITICAL_REGION();
631 
632  /* read-modify-write without any interrupts */
633  /* change in a tmp variable and write entire new value all at once */
634  tmp = pADI_CLKG0_CLK->CTL1;
635  tmp &= ~mask; /* blank the field */
636  tmp |= value; /* set the new value */
637  pADI_CLKG0_CLK->CTL1 = tmp; /* write the new value */
638 
639  /* end critical region */
640  ADI_EXIT_CRITICAL_REGION();
641 
642  /* refresh internal clock variables */
644 
645  return ADI_PWR_SUCCESS;
646 }
647 
661 ADI_PWR_RESULT adi_pwr_EnableClockSource (const ADI_CLOCK_SOURCE_ID eClockSource, const bool bEnable)
662 {
663  uint32_t val = 0u;
664  volatile uint32_t *pReg = NULL;
665  uint32_t nMask = 0u;
666  ADI_INT_STATUS_ALLOC();
667 
668  /* This switch statement does not handle every value in the ADI_CLOCK_SOURCE_ID enumeration
669  * which results on a gcc warning. This is done intentionally:
670  * ADI_CLOCK_SOURCE_LFOSC is not checked because it is enabled always and it cannot be disabled
671  * ADI_CLOCK_SOURCE_GPIO is only checked if a specific configuration macro is defined
672  */
673  switch(eClockSource)
674  {
676  val = (1u << BITP_CLKG_OSC_CTL_HFX_EN);
677  pReg = &pADI_CLKG0_OSC->CTL;
678  nMask = BITM_CLKG_OSC_CTL_HFX_OK;
679  break;
680 
682  val = (1u << BITP_CLKG_OSC_CTL_LFX_EN);
683  pReg = &pADI_CLKG0_OSC->CTL;
684  nMask = BITM_CLKG_OSC_CTL_LFX_OK;
685  break;
686 
688  val = (1u << BITP_CLKG_OSC_CTL_HFOSC_EN);
689  pReg = &pADI_CLKG0_OSC->CTL;
690  nMask = BITM_CLKG_OSC_CTL_HFOSC_OK;
691  break;
692 
694  val = (1u << BITP_CLKG_CLK_CTL3_SPLLEN);
695  pReg = &pADI_CLKG0_CLK->CTL3;
696  nMask = BITM_CLKG_CLK_CTL3_SPLLEN;
697  break;
698 
699 #if (ADI_PWR_CFG_ENABLE_CLOCK_SOURCE_GPIO == 1)
702  {
703  return(ADI_PWR_FAILURE);
704  }
706  {
707  return(ADI_PWR_FAILURE);
708  }
709  return(ADI_PWR_SUCCESS);
710  break;
711 #endif
712 
713  default:
714  return(ADI_PWR_INVALID_PARAM);
715 
716  } /* end switch */
717 
718  ADI_ENTER_CRITICAL_REGION();
719 
720  pADI_CLKG0_OSC->KEY = ADI_OSC_KEY;
721  if (bEnable == true)
722  {
723  *pReg |= val;
724  if( eClockSource == ADI_CLOCK_SOURCE_SPLL )
725  {
726  /* Wait for the PLL to lock */
727  uint32_t read_status;
728  do {
729  read_status = ((*pREG_CLKG0_CLK_STAT0 & BITM_CLKG_CLK_STAT0_SPLL)>>BITP_CLKG_CLK_STAT0_SPLL);
730  } while (read_status != 1u);
731  }
732  }
733  else
734  {
735  *pReg &= ~val;
736  }
737 
738  ADI_EXIT_CRITICAL_REGION();
739 
740  if((nMask !=0u) && (bEnable == true))
741  {
742  while(0u== (pADI_CLKG0_OSC->CTL & nMask)){}
743  }
744 
745 
746  return (ADI_PWR_SUCCESS);
747 }
748 
749 
764 {
765  uint32_t val = pADI_CLKG0_OSC->CTL;
766 
767 #ifdef ADI_DEBUG
768  if(peStatus == NULL)
769  {
770  return ADI_PWR_NULL_POINTER;
771  }
772 #endif /* ADI_DEBUG */
773 
774  *peStatus = ADI_CLOCK_SOURCE_DISABLED;
775 
776  switch(eClockSource)
777  {
779  if ((val & BITM_CLKG_OSC_CTL_HFOSC_EN) != 0u)
780  {
781  /* Clock source enabled, now check for stable */
782  if ((val & BITM_CLKG_OSC_CTL_HFOSC_OK) != 0u)
783  {
785  }
786  else
787  {
789  }
790  }
791  break;
792 
794  if ((val & BITM_CLKG_OSC_CTL_HFX_EN) != 0u)
795  {
796  /* Clock source enabled, now check for stable */
797  if ((val & BITM_CLKG_OSC_CTL_HFX_OK) != 0u)
798  {
800  }
801  else
802  {
804  }
805  }
806  break;
807 
809  if ((val & BITM_CLKG_OSC_CTL_LFX_EN) != 0u)
810  {
811  /* Clock source enabled, now check for stable */
812  if ((val & BITM_CLKG_OSC_CTL_LFX_OK) != 0u)
813  {
815  }
816  else
817  {
819  }
820  }
821  break;
822 
824  /* Clock source enabled, now check for stable */
825  if ((val & BITM_CLKG_OSC_CTL_LFOSC_OK) != 0u)
826  {
828  }
829  else
830  {
832  }
833  break;
834 
835  /* Since the clock through GPIO is supplied externally we cannot get
836  the clock status for GPIO */
838  default:
839  *peStatus = ADI_CLOCK_SOURCE_ID_NOT_VALID;
840  break;
841 
842  } /* end switch */
843 
844  return ADI_PWR_SUCCESS;
845 }
846 
860 {
861  ADI_INT_STATUS_ALLOC();
862  volatile uint32_t *pReg = NULL;
863  uint32_t tmp;
864 
865  switch(eIrq)
866  {
867 #if defined(__ADUCM4x50__)
868 
870  pReg = &pADI_CLKG0_OSC->CTL;
871  break;
872 #endif /* __ADUCM4x50__ */
873 
876  pReg = &pADI_CLKG0_OSC->CTL;
877  break;
878 
881  pReg = &pADI_CLKG0_CLK->CTL0;
882  break;
883 
886  pReg = &pADI_CLKG0_CLK->CTL0;
887  break;
888 
891  pReg = &pADI_CLKG0_CLK->CTL3;
892  break;
893 
894  default:
895  break;
896  }
897 
898  ADI_ENTER_CRITICAL_REGION();
899 
900  tmp = *pReg;
901 
902  if(bEnable == true)
903  {
904  tmp |= (uint32_t)eIrq;
905  }
906  else
907  {
908  tmp &= ~((uint32_t)eIrq);
909  }
910 
911  /* If we have to write to oscillator control register unlock it */
912  if(pReg == &pADI_CLKG0_OSC->CTL)
913  {
914  pADI_CLKG0_OSC->KEY = ADI_OSC_KEY;
915  }
916  *pReg = tmp;
917 
918  ADI_EXIT_CRITICAL_REGION();
919 
920  return(ADI_PWR_SUCCESS);
921 }
922 
923 
942 ADI_PWR_RESULT adi_pwr_SetPll(uint8_t nDivFactor, const uint8_t nMulFactor, const bool bDiv2, const bool bMul2)
943 {
944  uint32_t val, cfg = 0u;
945  uint8_t nTempDivFactor = nDivFactor, nTempMulFactor = nMulFactor;
946  ADI_INT_STATUS_ALLOC();
947 
948 #ifdef ADI_DEBUG
949  /* Check if multiplication factor and division factor is more than 6 bits */
950  if (((nMulFactor & ~0x3Fu) != 0u) || ((nDivFactor & ~0x3Fu) != 0u))
951  {
953  }
954 
955  /* Check if the PLL is multipexed in as root clock source, parameters should not change in that case */
956  if((pADI_CLKG0_CLK->CTL0 & BITM_CLKG_CLK_CTL0_CLKMUX) ==
957  ((uint32_t)((ADI_CLOCK_MUX_ROOT_SPLL - ADI_CLOCK_MUX_ROOT_HFOSC) << BITP_CLKG_CLK_CTL0_CLKMUX)))
958  {
960  }
961 #endif
962 
963  if(nTempDivFactor < MINIMUM_PLL_DIVIDER)
964  {
965  nTempDivFactor = MINIMUM_PLL_DIVIDER;
966  }
967  if(nTempMulFactor < MINIMUM_PLL_MULTIPLIER)
968  {
969  nTempMulFactor = MINIMUM_PLL_MULTIPLIER;
970  }
971 
972  cfg = (((uint32_t)nTempDivFactor) << BITP_CLKG_CLK_CTL3_SPLLMSEL)|( ((uint32_t) nTempMulFactor) << BITP_CLKG_CLK_CTL3_SPLLNSEL);
973 
974  if(bDiv2 == true)
975  {
976  cfg |= (1u <<BITP_CLKG_CLK_CTL3_SPLLDIV2);
977  }
978  if(bMul2 == true)
979  {
980  cfg |= (1u <<BITP_CLKG_CLK_CTL3_SPLLMUL2);
981  }
982 
983  /* critical region */
984  ADI_ENTER_CRITICAL_REGION();
985 
986  val = pADI_CLKG0_CLK->CTL3;
987  val &= ~( BITM_CLKG_CLK_CTL3_SPLLMUL2 | BITM_CLKG_CLK_CTL3_SPLLMSEL | BITM_CLKG_CLK_CTL3_SPLLDIV2 | BITM_CLKG_CLK_CTL3_SPLLNSEL);
988  val |= cfg;
989  pADI_CLKG0_CLK->CTL3 = val;
990 
991  /* end critical region */
992  ADI_EXIT_CRITICAL_REGION();
993 
994  return ADI_PWR_SUCCESS;
995 }
996 
997 
1013 {
1014  ADI_INT_STATUS_ALLOC();
1015 
1016 #ifdef ADI_DEBUG
1017  if(((pADI_PMG0->IEN & BITM_PMG_IEN_RANGEBAT) == 0u) || (eIrq != ADI_PWR_BATTERY_VOLTAGE_RANGE_IEN))
1018  {
1019  return(ADI_PWR_FAILURE);
1020  }
1021 #endif
1022 
1023  ADI_ENTER_CRITICAL_REGION();
1024  if(bEnable == true)
1025  {
1026  pADI_PMG0->IEN |= (uint32_t)eIrq;
1027  }
1028  else
1029  {
1030  pADI_PMG0->IEN &= ~(uint32_t)(eIrq);
1031  }
1032  ADI_EXIT_CRITICAL_REGION();
1033 
1034  return(ADI_PWR_SUCCESS);
1035 }
1036 
1037 
1038 
1051 {
1052  volatile uint32_t nDelay = 0xFFFFFFu;
1053  if(bEnable == true)
1054  {
1055  /* Write the oscillator key */
1056  pADI_CLKG0_OSC->KEY = ADI_OSC_KEY;
1057  /* Disable the LFXTAL */
1058  pADI_CLKG0_OSC->CTL &= ~(BITM_CLKG_OSC_CTL_LFX_EN);
1059  /* Wait till status de-asserted. */
1060  while(nDelay != 0u)
1061  {
1062  if((pADI_CLKG0_OSC->CTL & BITM_CLKG_OSC_CTL_LFX_OK) == 0u)
1063  {
1064  break;
1065  }
1066  nDelay--;
1067  }
1068 #ifdef ADI_DEBUG
1069  if(nDelay == 0u)
1070  {
1071  return(ADI_PWR_FAILURE);
1072  }
1073 #endif
1074  pADI_CLKG0_OSC->KEY = ADI_OSC_KEY;
1075  /* Enable the BYPASS mode */
1076  pADI_CLKG0_OSC->CTL |= (BITM_CLKG_OSC_CTL_LFX_BYP);
1077  /* Wait till status asserted. */
1078  nDelay = 0xFFFFFFu;
1079  while(nDelay != 0u)
1080  {
1081  if(((pADI_CLKG0_OSC->CTL & BITM_CLKG_OSC_CTL_LFX_OK)== BITM_CLKG_OSC_CTL_LFX_OK))
1082  {
1083  break;
1084  }
1085  nDelay--;
1086  }
1087 #ifdef ADI_DEBUG
1088  if(nDelay == 0u)
1089  {
1090  return(ADI_PWR_FAILURE);
1091  }
1092 #endif
1093 
1094  }
1095  else
1096  {
1097  /* Write the oscillator key */
1098  pADI_CLKG0_OSC->KEY = ADI_OSC_KEY;
1099  /* Disable the BYPASS mode */
1100  pADI_CLKG0_OSC->CTL &= ~(BITM_CLKG_OSC_CTL_LFX_BYP);
1101  /* Wait till status de-asserted. */
1102  while(nDelay != 0u)
1103  {
1104  if((pADI_CLKG0_OSC->CTL & BITM_CLKG_OSC_CTL_LFX_OK) == 0u)
1105  {
1106  break;
1107  }
1108  nDelay--;
1109  }
1110 #ifdef ADI_DEBUG
1111  if(nDelay == 0u)
1112  {
1113  return(ADI_PWR_FAILURE);
1114  }
1115 #endif
1116  }
1117 
1118  return(ADI_PWR_SUCCESS);
1119 }
1120 
1121 
1122 #if defined(__ADUCM4x50__)
1123 
1134 {
1135  /* Write the oscillator key */
1136  pADI_CLKG0_OSC->KEY = ADI_OSC_KEY;
1137 
1138  if(bEnable == true)
1139  {
1140  pADI_CLKG0_OSC->CTL |= BITM_CLKG_OSC_CTL_LFX_AUTSW_EN;
1141  }
1142  else
1143  {
1144  pADI_CLKG0_OSC->CTL &= ~(BITM_CLKG_OSC_CTL_LFX_AUTSW_EN);
1145  }
1146  return(ADI_PWR_SUCCESS);
1147 }
1148 
1149 
1164 {
1165  /* Write the oscillator key */
1166  pADI_CLKG0_OSC->KEY = ADI_OSC_KEY;
1167 
1168  if(bEnable == true)
1169  {
1170  pADI_CLKG0_OSC->CTL |= BITM_CLKG_OSC_CTL_ROOT_AUTSW_EN;
1171  }
1172  else
1173  {
1174  pADI_CLKG0_OSC->CTL &= ~(BITM_CLKG_OSC_CTL_ROOT_AUTSW_EN);
1175  }
1176 
1177  return(ADI_PWR_SUCCESS);
1178 }
1179 
1180 
1198 {
1199  uint32_t tmp;
1200 
1201  tmp = (pADI_CLKG0_CLK->CTL2 & ~BITM_CLKG_CLK_CTL2_HFOSCDIVCLKSEL);
1202  tmp |= ((uint32_t) eDivFactor << BITP_CLKG_CLK_CTL2_HFOSCDIVCLKSEL);
1203  pADI_CLKG0_CLK->CTL2 = tmp;
1204 
1205  return(ADI_PWR_SUCCESS);
1206 }
1207 
1208 
1230 {
1231  if(bEnable == true)
1232  {
1233  pADI_CLKG0_CLK->CTL2 |= BITM_CLKG_CLK_CTL2_HFOSCAUTODIV_EN;
1234  }
1235  else
1236  {
1237  pADI_CLKG0_CLK->CTL2 &= ~(BITM_CLKG_CLK_CTL2_HFOSCAUTODIV_EN);
1238  }
1239 
1240  return(ADI_PWR_SUCCESS);
1241 }
1242 
1243 
1258 {
1259  uint32_t tmp;
1260 
1261  tmp = (pADI_CLKG0_CLK->CTL0 & ~BITM_CLKG_CLK_CTL0_CLKOUT);
1262  tmp |= ((uint32_t)eClockOutput << BITP_CLKG_CLK_CTL0_CLKOUT);
1263  pADI_CLKG0_CLK->CTL0 = tmp;
1264 
1265  return(ADI_PWR_SUCCESS);
1266 }
1267 
1280 {
1281  if(bEnable == true)
1282  {
1283  pADI_PMG0->CTL1 |= BITM_PMG_CTL1_HPBUCK_LOWPWR_MODE;
1284  }
1285  else
1286  {
1287  pADI_PMG0->CTL1 &= ~(BITM_PMG_CTL1_HPBUCK_LOWPWR_MODE);
1288  }
1289 
1290  return(ADI_PWR_SUCCESS);
1291 }
1292 
1306 {
1307  if(eLoadMode == ADI_PWR_HPBUCK_LD_MODE_HIGH)
1308  {
1309  pADI_PMG0->CTL1 |= BITM_PMG_CTL1_HPBUCK_LD_MODE;
1310  }
1311  else
1312  {
1313  pADI_PMG0->CTL1 &= ~(BITM_PMG_CTL1_HPBUCK_LD_MODE);
1314  }
1315 
1316  return(ADI_PWR_SUCCESS);
1317 }
1318 #endif /* ADUCM4x50 */
1319 
1330 {
1331  if(bEnable == true)
1332  {
1333  pADI_PMG0->CTL1 |= BITM_PMG_CTL1_HPBUCKEN;
1334  }
1335  else
1336  {
1337  pADI_PMG0->CTL1 &= ~(BITM_PMG_CTL1_HPBUCKEN);
1338  }
1339 
1340  return(ADI_PWR_SUCCESS);
1341 }
1342 
1352 {
1353  *peStatus =(ADI_PWR_WAKEUP_STATUS) pADI_PMG0->SHDN_STAT;
1354  return(ADI_PWR_SUCCESS);
1355 }
1356 
1357 
1369 {
1370  uint32_t tmp;
1371 
1372  tmp = (pADI_PMG0->IEN & ~BITM_PMG_IEN_RANGEBAT);
1373  tmp |= ((uint32_t)eRange << BITP_PMG_IEN_RANGEBAT);
1374  pADI_PMG0->IEN = tmp;
1375 
1376  return(ADI_PWR_SUCCESS);
1377 }
1378 
1381 /*
1382  * Interrupt handler for PLL interrupts.
1383  */
1384 void PLL_Int_Handler(void)
1385 {
1386  ISR_PROLOG();
1387 
1388  /* As the same status word is shared between two interrupts
1389  Crystal_osc_Int_Handler and PLL_Int_Handler
1390  check and clear status bits handled in this handler */
1391  uint32_t nStatus = (pADI_CLKG0_CLK->STAT0 &
1392  (BITM_CLKG_CLK_STAT0_SPLLUNLK | BITM_CLKG_CLK_STAT0_SPLLLK));
1393 
1394  /* If a callback is registered notify the events */
1395  if(gpfCallbackFunction != NULL)
1396  {
1397  if((nStatus & BITM_CLKG_CLK_STAT0_SPLLUNLK ) != 0u)
1398  {
1399  /* PLL unlock event */
1400  gpfCallbackFunction( gpPowcbParam, ADI_PWR_EVENT_PLLC_UNLOCK,(void *)0);
1401  }
1402  else if((nStatus & BITM_CLKG_CLK_STAT0_SPLLLK) != 0u)
1403  {
1404  /* PLL lock event */
1405  gpfCallbackFunction( gpPowcbParam, ADI_PWR_EVENT_PLLC_LOCK,(void *)0);
1406  }
1407  else
1408  {
1409  /* Do nothing */
1410  }
1411  }
1412 
1413  /* Clear the status bits */
1414  pADI_CLKG0_CLK->STAT0 = nStatus;
1415 
1416  ISR_EPILOG();
1417 }
1418 
1419 /*
1420  * Interrupt handler for oscillator interrupts.
1421  */
1422 void Crystal_osc_Int_Handler(void)
1423 {
1424  ISR_PROLOG();
1425 
1426  /* As the same status word is shared between two interrupts
1427  Crystal_osc_Int_Handler and PLL_Int_Handler
1428  check and clear status bits handled in this handler */
1429  uint32_t nClkStatus = (pADI_CLKG0_CLK->STAT0 &
1430  (BITM_CLKG_CLK_STAT0_HFXTALNOK |
1431  BITM_CLKG_CLK_STAT0_HFXTALOK |
1432  BITM_CLKG_CLK_STAT0_LFXTALOK |
1433  BITM_CLKG_CLK_STAT0_LFXTALNOK));
1434 #if defined(__ADUCM4x50__)
1435  /* Check if the interrupt was generated due to failure in Root Clock or LFXTAL */
1436  uint32_t nOscStatus = (pADI_CLKG0_OSC->CTL & (BITM_CLKG_OSC_CTL_LFX_FAIL_STA |
1437  BITM_CLKG_OSC_CTL_ROOT_FAIL_STA |
1438  BITM_CLKG_OSC_CTL_ROOT_AUTSW_STA |
1439  BITM_CLKG_OSC_CTL_LFX_AUTSW_STA ));
1440 #endif /* __ADUCM4x50__ */
1441 
1442  uint32_t nEvent = 0u;
1443 
1444 
1445  if(gpfCallbackFunction != NULL)
1446  {
1447  /* Is the interrupt caused due to HFXTAL or LFXTAL status */
1448  if(nClkStatus != 0u)
1449  {
1450  if ((nClkStatus & BITM_CLKG_CLK_STAT0_HFXTALNOK) != 0u) { nEvent |= ADI_PWR_EVENT_OSC_HFXTAL_CLOCK_NO_OK; }
1451  else if ((nClkStatus & BITM_CLKG_CLK_STAT0_HFXTALOK) != 0u) { nEvent |= ADI_PWR_EVENT_OSC_HFXTAL_CLOCK_OK; }
1452  else if ((nClkStatus & BITM_CLKG_CLK_STAT0_LFXTALOK) != 0u) { nEvent |= ADI_PWR_EVENT_OSC_LFXTAL_CLOCK_OK; }
1453  else if ((nClkStatus & BITM_CLKG_CLK_STAT0_LFXTALNOK) != 0u) { nEvent |= ADI_PWR_EVENT_OSC_LFXTAL_CLOCK_NO_OK; }
1454  else { /* do nothing */ }
1455 
1456  if(nEvent != 0u) { gpfCallbackFunction( gpPowcbParam, nEvent, (void *)0u); }
1457 
1458  }
1459 #if defined(__ADUCM4x50__)
1460  /* Or is the interrupt caused due to Root Clock or LFXTAL failure status */
1461  else if(nOscStatus != 0u)
1462  {
1463  /* Did the LFXTAL failed */
1464  if( (nOscStatus & BITM_CLKG_OSC_CTL_LFX_FAIL_STA) != 0u)
1465  {
1466  /* Notifiy LFXTAL failure */
1467  gpfCallbackFunction( gpPowcbParam, ADI_PWR_EVENT_OSC_LFXTAL_MON_FAIL, (void *)0u);
1468 
1469  /* Did the HW auto switched to LFOSC due to LFXTAL failure */
1470  if((nOscStatus & BITM_CLKG_OSC_CTL_LFX_AUTSW_STA) != 0u)
1471  {
1472  /* Notify about the auto switch to LFOSC */
1473  gpfCallbackFunction( gpPowcbParam, ADI_PWR_EVENT_OSC_LFXTAL_AUTO_SWITCH, (void *)0u);
1474  }
1475  }
1476  /* Did the root clock failed */
1477  else if((nOscStatus & BITM_CLKG_OSC_CTL_ROOT_FAIL_STA) != 0u)
1478  {
1479  /* Indicate about the root clock failure */
1480  gpfCallbackFunction( gpPowcbParam, ADI_PWR_EVENT_OSC_ROOT_CLOCK_MON_FAIL, (void *)0u);
1481 
1482  /* Did the HW auto switched to HFOSC due to root clock failure */
1483  if((nOscStatus & BITM_CLKG_OSC_CTL_ROOT_AUTSW_STA) != 0u)
1484  {
1485  /* Notify about auto switch to HFOSC */
1486  gpfCallbackFunction( gpPowcbParam, ADI_PWR_EVENT_OSC_ROOT_CLOCK_FAIL_AUTO_SWITCH, (void *)0u);
1487  }
1488  }
1489  else
1490  {
1491  /* Do nothing */
1492  }
1493  }
1494  else
1495  {
1496  /* Do nothing */
1497  }
1498 #endif /* __ADUCM4x50__ */
1499  }
1500 
1501  /* Clear the staus bits */
1502  if(nClkStatus != 0u)
1503  {
1504  pADI_CLKG0_CLK->STAT0 = nClkStatus;
1505  }
1506 #if defined(__ADUCM4x50__)
1507  else if(nOscStatus != 0u)
1508  {
1509  /* Write the oscillator key to clear the status bits */
1510  pADI_CLKG0_OSC->KEY = ADI_OSC_KEY;
1511 
1512  /* Clear only status bits */
1513  pADI_CLKG0_OSC->CTL |= nOscStatus;
1514  }
1515  else
1516  {
1517  /* Do nothing */
1518  }
1519 #endif /* __ADUCM4x50__ */
1520 
1521  ISR_EPILOG();
1522 }
1523 
1524 /*
1525  * Interrupt handler for battery voltage interrupt.
1526  */
1527 void Battery_Voltage_Int_Handler(void)
1528 {
1529  ISR_PROLOG();
1530  uint32_t nStatus = pADI_PMG0->PSM_STAT;
1531 
1532  if ((nStatus & BITM_PMG_PSM_STAT_VBATUNDR) != 0u)
1533  {
1534  if(gpfCallbackFunction != NULL)
1535  {
1536  gpfCallbackFunction( gpPowcbParam, (uint32_t)nStatus, (void *)0);
1537  }
1538  pADI_PMG0->PSM_STAT |= (BITM_PMG_PSM_STAT_VBATUNDR);
1539  }
1540  ISR_EPILOG();
1541 }
1542 
1543 /*
1544  * Interrupt handler for battery voltage interrupt.
1545  */
1546 void Vreg_over_Int_Handler(void)
1547 {
1548  ISR_PROLOG();
1549  uint32_t nStatus = pADI_PMG0->PSM_STAT;
1550 
1551  if(gpfCallbackFunction != NULL)
1552  {
1553  if ((nStatus & BITM_PMG_PSM_STAT_VREGOVR) != 0u)
1554  {
1555  gpfCallbackFunction(gpPowcbParam, (uint32_t)ADI_PWR_EVENT_VREG_OVER_VOLTAGE, NULL);
1556  }
1557  if ((nStatus & BITM_PMG_PSM_STAT_VREGUNDR) != 0u)
1558  {
1559  gpfCallbackFunction(gpPowcbParam, (uint32_t)ADI_PWR_EVENT_VREG_UNDER_VOLTAGE, NULL);
1560  }
1561  }
1562  pADI_PMG0->PSM_STAT |= (nStatus &(BITM_PMG_PSM_STAT_VREGOVR | BITM_PMG_PSM_STAT_VREGUNDR));
1563  ISR_EPILOG();
1564 }
1565 
1688  uint32_t volatile * pnInterruptOccurred,
1689  const uint8_t PriorityMask
1690  )
1691 {
1692  uint32_t savedPriority;
1693  uint32_t scrSetBits = 0u;
1694  uint32_t scrClrBits = 0u;
1695  uint16_t savedWDT;
1696  uint32_t savedDMA_STAT;
1697  ADI_INT_STATUS_ALLOC();
1698 
1699 #ifdef ADI_DEBUG
1700 
1701  /* verify the requested priority mask bits are right-justified and don't exceed __NVIC_PRIO_BITS in width */
1702  if ((PriorityMask & ~((1u << __NVIC_PRIO_BITS) - 1u)) != 0u)
1703  {
1704  return ADI_PWR_INVALID_PARAM;
1705  }
1706 
1707 #endif /* ADI_DEBUG */
1708 
1709  /* pre-calculate the sleep-on-exit set/clear bits */
1710  if(NULL == pnInterruptOccurred) {
1711  scrSetBits |= SCB_SCR_SLEEPONEXIT_Msk;
1712 
1713  /* point to private control variable when in hardware (sleep-on-exit) mode */
1714  pnInterruptOccurred = &gnLowPowerIntOccFlag;
1715  }
1716 
1717  /* pre-calculate the deepsleep and sleep-on-exit set/clear bits */
1718  switch (PowerMode) {
1719 
1720  case ADI_PWR_MODE_ACTIVE: /* Note: this value is a "reserved" PWRMODE register code. */
1721  return ADI_PWR_SUCCESS; /* avoids the reserved value "1" being written to PWRMODE. */
1722 
1723  case ADI_PWR_MODE_FLEXI: /* wfi without deepsleep or sleep-on-exit */
1724  scrClrBits |= (uint32_t)(BITM_NVIC_INTCON0_SLEEPDEEP | BITM_NVIC_INTCON0_SLEEPONEXIT);
1725  break;
1726 
1727  case ADI_PWR_MODE_HIBERNATE: /* wfi with deepsleep and sleep-on-exit per pnInterruptOccurred setting */
1728  scrSetBits |= BITM_NVIC_INTCON0_SLEEPDEEP;
1729 
1730  break;
1731 
1732  case ADI_PWR_MODE_SHUTDOWN: /* wfi with both deepsleep and sleep-on-exit */
1733  /* Note: sleep-on-exit causes WFI to never exit and wakeup is only through system reset. */
1734  scrSetBits |= (uint32_t)(BITM_NVIC_INTCON0_SLEEPDEEP | BITM_NVIC_INTCON0_SLEEPONEXIT);
1735  break;
1736 
1737  default:
1739 
1740  } /* end switch */
1741 
1742  /* put the power mode and system control mods, as well as the WFI loop inside a critical section */
1743  ADI_ENTER_CRITICAL_REGION();
1744 
1745  { /* these lines must be in a success-checking loop if they are not inside critical section */
1746  /* Uninterruptable unlock sequence */
1747  pADI_PMG0->PWRKEY = ADI_PMG_KEY;
1748 
1749  /* Clear the previous mode and set new mode */
1750  pADI_PMG0->PWRMOD = (uint32_t) ( ( pADI_PMG0->PWRMOD & (uint32_t) (~BITM_PMG_PWRMOD_MODE) ) | PowerMode );
1751  }
1752 
1753  /* Update the SCR (sleepdeep and sleep-on-exit bits) */
1754  SCB->SCR = ((SCB->SCR | scrSetBits) & ~scrClrBits);
1755 
1756  /* save/restore current Base Priority Level */
1757  savedPriority = __get_BASEPRI();
1758 
1759  /* NOTE: the watchdog timer(WDT)is reset by the core hardware with every exit from low-power mode.
1760  Therefore,even though we may have disabled it during startup, it will reset
1761  itself on exit from every hibernation state. Therefore, to avoid
1762  unintended system resets every 30 seconds because of unexpected WDT
1763  timeouts, we save/restore the WDT control register around
1764  hibernation entry and exit.
1765  */
1766 
1767  /* save WDT control register */
1768  savedWDT = pADI_WDT0->CTL;
1769 
1770  /* Save DMA STATUS register */
1771  savedDMA_STAT = pADI_DMA0->STAT;
1772 
1773  /* assert caller's priority threshold (left-justified) */
1774  __set_BASEPRI((uint32_t)PriorityMask << (8u -__NVIC_PRIO_BITS));
1775 
1776  /* if we are in the software looping mode, loop on the user's variable until set */
1777  while (0u == *pnInterruptOccurred) {
1778 
1779  __DSB(); /* bus sync to insure register writes from interrupt handlers are always complete before WFI */
1780 
1781  /* NOTE: aggressive compiler optimizations can muck up critical timing here, so reduce if hangs are present */
1782 
1783  /* The WFI loop MUST reside in a critical section because we need to insure that the interrupt
1784  that is planned to take us out of WFI (via a call to adi_pwr_ExitLowPowerMode()) is not
1785  dispatched until we get into the WFI. If that interrupt sneaks in prior to our getting to the
1786  WFI, then we may end up waiting (potentially forever) for an interrupt that has already occurred.
1787  */
1788  __WFI();
1789 
1790  /* Recycle the critical section so that other (non-wakeup) interrupts are dispatched.
1791  This allows *pnInterruptOccurred to be set from any interrupt context.
1792  */
1793  ADI_EXIT_CRITICAL_REGION();
1794  /* nop */
1795  ADI_ENTER_CRITICAL_REGION();
1796 
1797  } /* end while */
1798 
1799  /* ...still within critical section... */
1800 
1801  (*pnInterruptOccurred)--; /* decrement the completion variable on exit */
1802 
1803  /* Restore previous base priority */
1804  __set_BASEPRI(savedPriority);
1805 
1806  /* restore WDT control register */
1807  pADI_WDT0->CTL = savedWDT;
1808 
1809  /* re-enable DMA if it was enable before */
1810  if (savedDMA_STAT & BITM_DMA_STAT_MEN) {
1811  pADI_DMA0->CFG = BITM_DMA_CFG_MEN;
1812  }
1813 
1814  /* clear sleep-on-exit bit to avoid sleeping on exception return to thread level */
1815  SCB->SCR &= ~SCB_SCR_SLEEPONEXIT_Msk;
1816 
1817  __DSB(); /* bus sync before re-enabling interrupts */
1818 
1819  ADI_EXIT_CRITICAL_REGION();
1820 
1821  return ADI_PWR_SUCCESS;
1822 }
1823 
1824 
1839 ADI_PWR_RESULT adi_pwr_ExitLowPowerMode(uint32_t volatile * pnInterruptOccurred)
1840 {
1841  ADI_INT_STATUS_ALLOC();
1842 
1843  /* Manage the exit depending on pnInterruptOccurred convention... */
1844  /* NULL pointer means we are using the hardware sleep-on-exit feature */
1845  /* non-NULL pointer means we are using a software looping variable top sleep */
1846 
1847  if (NULL == pnInterruptOccurred) {
1848 
1849  pnInterruptOccurred = &gnLowPowerIntOccFlag; /* point to private control variable in hardware mode */
1850 
1851  /* clear hardware sleep-on-exit feature */
1852  ADI_ENTER_CRITICAL_REGION();
1853 
1854  /* Ensure hibernate/shutdown modes are cleared and flexi mode set */
1855  pADI_PMG0->PWRMOD &= (uint32_t) (~BITM_PMG_PWRMOD_MODE);
1856 
1857  /* Clear System Control Register bits SLEEPDEEP and SLEEPONEXIT */
1858  SCB->SCR &= ~(SCB_SCR_SLEEPONEXIT_Msk | SCB_SCR_SLEEPDEEP_Msk);
1859  __DSB(); /* bus sync before interrupt exit */
1860 
1861  ADI_EXIT_CRITICAL_REGION();
1862  }
1863 
1864  /* set control variable (whether hardware or software based) so WFI exits in SystemEnterLowPowerMode() */
1865  (*pnInterruptOccurred)++;
1866  return ADI_PWR_SUCCESS;
1867 }
1868 
1869 /*
1870 ** EOF
1871 */
1872 
ADI_PWR_RESULT adi_pwr_SetClockDivider(const ADI_CLOCK_ID eClockId, const uint16_t nDiv)
Sets the clock divide factor for an individual clock group.
Definition: adi_pwr.c:533
ADI_PWR_HPBUCK_LD_MODE
Definition: adi_pwr.h:408
ADI_PWR_RESULT adi_pwr_SetVoltageRange(const ADI_PWR_VOLTAGE_RANGE eRange)
To Monitor voltage range of battery.
Definition: adi_pwr.c:1368
ADI_PWR_POWER_MODE
Definition: adi_pwr.h:266
ADI_CLOCK_SOURCE_ID
Definition: adi_pwr.h:53
ADI_CLOCK_MUX_ID
Definition: adi_pwr.h:76
ADI_PWR_PMG_IRQ
Definition: adi_pwr.h:283
ADI_PWR_RESULT adi_pwr_SetPLLClockMux(const ADI_CLOCK_MUX_ID eClockID)
Sets the input clock source for PLL multiplexer.
Definition: adi_pwr.c:219
ADI_PWR_WAKEUP_STATUS
Definition: adi_pwr.h:377
ADI_CLOCK_ID
Definition: adi_pwr.h:42
ADI_PWR_RESULT adi_pwr_SetHPBuckLoadMode(const ADI_PWR_HPBUCK_LD_MODE eLoadMode)
Set the HP Buck load mode.
Definition: adi_pwr.c:1305
void SystemCoreClockUpdate(void)
Update the clock.
ADI_CLOCK_OUTPUT_ID
Definition: adi_pwr.h:135
ADI_PWR_RESULT adi_pwr_EnablePMGInterrupt(const ADI_PWR_PMG_IRQ eIrq, const bool bEnable)
Enable/Disable the power management interrupt.
Definition: adi_pwr.c:1012
ADI_PWR_CLOCK_IRQ
Definition: adi_pwr.h:300
ADI_PWR_RESULT adi_pwr_UpdateCoreClock(void)
Updates the internal SystemCoreClock variable with current core Clock retrieved from cpu registers.
Definition: adi_pwr.c:147
ADI_PWR_RESULT
Definition: adi_pwr.h:236
ADI_PWR_RESULT adi_pwr_SetGPIOClockOutput(const ADI_CLOCK_OUTPUT_ID eClockOutput)
Set the clock output through the GPIO.
Definition: adi_pwr.c:1257
ADI_PWR_RESULT adi_pwr_EnableHPBuck(const bool bEnable)
Enables or disables the HP Buck.
Definition: adi_pwr.c:1329
ADI_PWR_RESULT adi_pwr_EnableHPBuckLowPowerMode(const bool bEnable)
Enable or disable the HPBuck Low Power mode. The HPBUCK Low Power mode can be selected,...
Definition: adi_pwr.c:1279
ADI_PWR_RESULT adi_pwr_SetPll(uint8_t nDivFactor, const uint8_t nMulFactor, const bool bDiv2, const bool bMul2)
Program PLL frequency.
Definition: adi_pwr.c:942
ADI_PWR_RESULT adi_pwr_EnableClockSource(const ADI_CLOCK_SOURCE_ID eClockSource, const bool bEnable)
To Enable/disable clock sources.
Definition: adi_pwr.c:661
ADI_PWR_RESULT adi_pwr_EnterLowPowerMode(const ADI_PWR_POWER_MODE PowerMode, uint32_t volatile *pnInterruptOccurred, const uint8_t PriorityMask)
Puts the processor into given low power mode.
Definition: adi_pwr.c:1687
ADI_PWR_RESULT adi_pwr_ExitLowPowerMode(uint32_t volatile *pnInterruptOccurred)
Definition: adi_pwr.c:1839
ADI_PWR_RESULT adi_pwr_GetExtClkFreq(uint32_t *pExtClock)
Gets the system external clock frequency. Gets the clock frequency of the source connected to the ext...
Definition: adi_pwr.c:402
ADI_GPIO_RESULT adi_gpio_InputEnable(const ADI_GPIO_PORT Port, const ADI_GPIO_DATA Pins, const bool bFlag)
Enables/Disables the Input Drivers for GPIO Pin(s)
Definition: adi_gpio.c:578
ADI_PWR_RESULT adi_pwr_EnableClockInterrupt(const ADI_PWR_CLOCK_IRQ eIrq, const bool bEnable)
Enable/Disable the clock interrupt to monitor status of LFXTAL, HFXTAL and PLL.
Definition: adi_pwr.c:859
ADI_PWR_RESULT adi_pwr_RegisterCallback(const ADI_CALLBACK pfCallback, void *pcbParam)
Registers or unregister the callback function.
Definition: adi_pwr.c:166
ADI_CLOCK_GATE
Definition: adi_pwr.h:189
ADI_PWR_RESULT adi_pwr_EnableClock(const ADI_CLOCK_GATE eClockGate, const bool bEnable)
Enable/disable individual peripheral clocks.
Definition: adi_pwr.c:491
ADI_GPIO_RESULT adi_gpio_PullUpEnable(const ADI_GPIO_PORT Port, const ADI_GPIO_DATA Pins, const bool bFlag)
Enables/Disables the Pull-Up for GPIO Pin(s)
Definition: adi_gpio.c:682
ADI_PWR_RESULT adi_pwr_EnableLFXTALBypass(const bool bEnable)
Enable/disable LFXTAL bypass mode.
Definition: adi_pwr.c:1050
ADI_PWR_RESULT adi_pwr_GetClockFrequency(const ADI_CLOCK_ID eClockId, uint32_t *pClock)
Get the frequency of the given clock. Obtain individual peripheral clock frequencies.
Definition: adi_pwr.c:435
ADI_PWR_RESULT adi_pwr_SetExtClkFreq(const uint32_t ExtClkFreq)
Sets the system external clock frequency.
Definition: adi_pwr.c:196
ADI_PWR_RESULT adi_pwr_EnableRootClockFailAutoSwitch(const bool bEnable)
To enable/disable auto switching of root clock to HFOSC upon detection of Root clock failure....
Definition: adi_pwr.c:1163
ADI_PWR_RESULT adi_pwr_SetHFOscDivFactor(const ADI_PWR_HFOSC_DIV eDivFactor)
Sets the HF Oscillator divide factor.
Definition: adi_pwr.c:1197
ADI_PWR_RESULT adi_pwr_SetRootClockMux(const ADI_CLOCK_MUX_ID eClockID)
Sets the source for the root clock multiplexer.
Definition: adi_pwr.c:358
ADI_PWR_RESULT adi_pwr_EnableHFOscAutoDivBy1(const bool bEnable)
Enable or disable the HF oscillator automatic divide by 1 during wakeup from Flexi mode.
Definition: adi_pwr.c:1229
ADI_PWR_HFOSC_DIV
Definition: adi_pwr.h:214
ADI_PWR_RESULT adi_pwr_SetRefClockMux(const ADI_CLOCK_MUX_ID eClockID)
Sets clock source for the Reference clock multiplexer.
Definition: adi_pwr.c:314
ADI_PWR_VOLTAGE_RANGE
Definition: adi_pwr.h:393
ADI_PWR_RESULT adi_pwr_GetWakeUpStatus(ADI_PWR_WAKEUP_STATUS *peStatus)
Function to retrieve the wakeup from shut down mode status.
Definition: adi_pwr.c:1351
ADI_PWR_RESULT adi_pwr_GetClockStatus(const ADI_CLOCK_SOURCE_ID eClockSource, ADI_CLOCK_SOURCE_STATUS *peStatus)
Return the status of a clock source.
Definition: adi_pwr.c:763
#define ADI_GPIO_PIN_10
Definition: adi_gpio.h:107
ADI_PWR_RESULT adi_pwr_Init(void)
Definition: adi_pwr.c:77
ADI_PWR_RESULT adi_pwr_EnableLFXTALFailAutoSwitch(const bool bEnable)
Enable/Disable the LFXTAL Fail Auto switch. Enables/Disable automatic Switching of the LF Mux to LF O...
Definition: adi_pwr.c:1133
ADI_PWR_RESULT adi_pwr_SetLFClockMux(const ADI_CLOCK_MUX_ID eClockID)
Sets the input clock for low frequency clock multiplexer.
Definition: adi_pwr.c:266
ADI_CLOCK_SOURCE_STATUS
Definition: adi_pwr.h:120