void board_save_misc_power(void) { int i; /* disable USB clock */ pmc_disable_upll_clock(); pmc_disable_upll_bias(); /* disable system clocks */ pmc_disable_system_clock(PMC_SYSTEM_CLOCK_DDR); pmc_disable_system_clock(PMC_SYSTEM_CLOCK_LCD); pmc_disable_system_clock(PMC_SYSTEM_CLOCK_SMD); pmc_disable_system_clock(PMC_SYSTEM_CLOCK_UHP); pmc_disable_system_clock(PMC_SYSTEM_CLOCK_UDP); pmc_disable_system_clock(PMC_SYSTEM_CLOCK_PCK0); pmc_disable_system_clock(PMC_SYSTEM_CLOCK_PCK1); pmc_disable_system_clock(PMC_SYSTEM_CLOCK_PCK2); pmc_disable_system_clock(PMC_SYSTEM_CLOCK_ISC); /* disable all peripheral clocks except PIOA for JTAG, serial debug port */ for (i = ID_PIT; i < ID_PERIPH_COUNT; i++) { if (i == ID_PIOA) continue; pmc_disable_peripheral(i); } }
/** * \brief Initialize SAM3N_EK board for low power test. */ void init_specific_board(void) { /* Configure all PIOs as inputs to save power */ pio_set_input(PIOA, 0xFFFFFFFF, PIO_PULLUP); pio_set_input(PIOB, 0xFFFFFFFF, PIO_PULLUP); pio_set_input(PIOC, 0xFFFFFFFF, PIO_PULLUP); /* Disable USB Clock */ pmc_disable_upll_clock(); /* Disable PIO pull-up for PA0 (VBUS_USB) */ pio_pull_up(PIOA, (0x1 << 0), 0); /* Initialize ADC pin as ADC input mode to save power */ adc_enable_channel(ADC, ADC_CHANNEL_0); adc12b_enable_channel(ADC12B, ADC_CHANNEL_3); /* Enable the PMC clocks of push button for wakeup */ pmc_enable_periph_clk(ID_PIOA); pio_handler_set_priority(PIOA, PIOA_IRQn, IRQ_PRIOR_PIO); }
/** * Save clock settings and shutdown PLLs */ __always_inline static void pmc_save_clock_settings( uint32_t *p_osc_setting, uint32_t *p_pll0_setting, uint32_t *p_pll1_setting, uint32_t *p_mck_setting) { if (p_osc_setting) { *p_osc_setting = PMC->CKGR_MOR; } if (p_pll0_setting) { *p_pll0_setting = PMC->CKGR_PLLAR; } if (p_pll1_setting) { #if (SAM3S || SAM4S) *p_pll1_setting = PMC->CKGR_PLLBR; #elif (SAM3U || SAM3XA) *p_pll1_setting = PMC->CKGR_UCKR; #else *p_pll1_setting = 0; #endif } if (p_mck_setting) { *p_mck_setting = PMC->PMC_MCKR; } /* Switch MCK to internal 4/8/12M RC for fast wakeup and disable unused clock for power saving. */ pmc_switch_mck_to_sclk(PMC_MCKR_PRES_CLK_1); pmc_switch_mainck_to_fastrc(CKGR_MOR_MOSCRCF_12_MHz); pmc_osc_disable_xtal(0); pmc_disable_pllack(); #if (SAM3S || SAM4S) pmc_disable_pllbck(); #elif (SAM3U || SAM3XA) pmc_disable_upll_clock(); #endif pmc_switch_mck_to_mainck(PMC_MCKR_PRES_CLK_1); }
/** * \brief Initialize SAM3N_EK board for low power test. */ void init_specific_board(void) { /* Configure all PIOs as inputs to save power */ pio_set_input(PIOA, 0xFFFFFFFF, PIO_PULLUP); pio_set_input(PIOB, 0x0FFFFFFF, PIO_PULLUP); /* Exclude JTAG pins */ pio_set_input(PIOC, 0xFFFFFFFF, PIO_PULLUP); pio_set_input(PIOD, 0x7FFFFFFF, PIO_PULLUP); pio_set_input(PIOE, 0xFFFFFFFF, PIO_PULLUP); pio_set_input(PIOF, 0x3F, PIO_PULLUP); /* Disable USB Clock */ pmc_disable_udpck(); pmc_disable_upll_clock(); /* Disable PIO pull-up for PB4, PB5, PB6, PB7 */ pio_pull_up(PIOB, (0xF << 4), 0); /* Initialize ADC pin as ADC input mode to save power */ adc_enable_channel(ADC, ADC_CHANNEL_1); /* Enable the PMC clocks of push button for wakeup */ pmc_enable_periph_clk(ID_PIOB); pio_handler_set_priority(PIOB, PIOB_IRQn, IRQ_PRIOR_PIO); }
/** * Save clock settings and shutdown PLLs */ __always_inline static void pmc_save_clock_settings( uint32_t *p_osc_setting, uint32_t *p_pll0_setting, uint32_t *p_pll1_setting, uint32_t *p_mck_setting, uint32_t *p_fmr_setting, #if defined(EFC1) uint32_t *p_fmr_setting1, #endif const bool disable_xtal) { uint32_t mor = PMC->CKGR_MOR; uint32_t mckr = PMC->PMC_MCKR; uint32_t fmr = EFC0->EEFC_FMR; # if defined(EFC1) uint32_t fmr1 = EFC1->EEFC_FMR; # endif if (p_osc_setting) { *p_osc_setting = mor; } if (p_pll0_setting) { *p_pll0_setting = PMC->CKGR_PLLAR; } if (p_pll1_setting) { #if (SAM3S || SAM4S || SAM4C || SAM4CM || SAM4CP) *p_pll1_setting = PMC->CKGR_PLLBR; #elif (SAM3U || SAM3XA) *p_pll1_setting = PMC->CKGR_UCKR; #else *p_pll1_setting = 0; #endif } if (p_mck_setting) { *p_mck_setting = mckr; } if (p_fmr_setting) { *p_fmr_setting = fmr; } #if defined(EFC1) if (p_fmr_setting1) { *p_fmr_setting1 = fmr1; } #endif /* Enable FAST RC */ PMC->CKGR_MOR = CKGR_MOR_KEY_PASSWD | mor | CKGR_MOR_MOSCRCEN; /* if MCK source is PLL, switch to mainck */ if ((mckr & PMC_MCKR_CSS_Msk) > PMC_MCKR_CSS_MAIN_CLK) { /* MCK -> MAINCK */ mckr = (mckr & (~PMC_MCKR_CSS_Msk)) | PMC_MCKR_CSS_MAIN_CLK; PMC->PMC_MCKR = mckr; while(!(PMC->PMC_SR & PMC_SR_MCKRDY)); } /* MCK prescale -> 1 */ if (mckr & PMC_MCKR_PRES_Msk) { mckr = (mckr & (~PMC_MCKR_PRES_Msk)); PMC->PMC_MCKR = mckr; while(!(PMC->PMC_SR & PMC_SR_MCKRDY)); } /* Disable PLLs */ pmc_disable_pllack(); #if (SAM3S || SAM4S || SAM4C || SAM4CM || SAM4CP) pmc_disable_pllbck(); #elif (SAM3U || SAM3XA) pmc_disable_upll_clock(); #endif /* Prepare for entering WAIT mode */ /* Wait fast RC ready */ while (!(PMC->PMC_SR & PMC_SR_MOSCRCS)); /* Switch mainck to FAST RC */ #if SAMG /** * For the sleepwalking feature, we need an accurate RC clock. Only 24M and * 16M are trimmed in production. Here we select the 24M. * And so wait state need to be 1. */ EFC0->EEFC_FMR = (fmr & (~EEFC_FMR_FWS_Msk)) | EEFC_FMR_FWS(1); PMC->CKGR_MOR = (PMC->CKGR_MOR & ~CKGR_MOR_MOSCSEL) | CKGR_MOR_MOSCRCF_24_MHz | CKGR_MOR_KEY_PASSWD; #else PMC->CKGR_MOR = (PMC->CKGR_MOR & ~CKGR_MOR_MOSCSEL) | CKGR_MOR_KEY_PASSWD; #endif while (!(PMC->PMC_SR & PMC_SR_MOSCSELS)); #if (!SAMG) /* FWS update */ EFC0->EEFC_FMR = fmr & (~EEFC_FMR_FWS_Msk); #if defined(EFC1) EFC1->EEFC_FMR = fmr1 & (~EEFC_FMR_FWS_Msk); #endif #endif /* Disable XTALs */ if (disable_xtal) { PMC->CKGR_MOR = (PMC->CKGR_MOR & ~CKGR_MOR_MOSCXTEN) | CKGR_MOR_KEY_PASSWD; } }