int main(void) { /* Initialize the SAM system */ SystemInit(); /** Init GPIOs */ /* - Enable GPIO clock */ PM->PM_UNLOCK = PM_UNLOCK_KEY(0xAAu)|PM_UNLOCK_ADDR((uint32_t)&PM->PM_PBCMASK); PM->PM_PBCMASK |= PM_PBCMASK_GPIO ; //- Disable GPIO control on Pin C24 GPIO->GPIO_PORT[2].GPIO_GPERC = (GPIO_GPERC_P24); //- Set Peripheral MuxB (B = 001) GPIO->GPIO_PORT[2].GPIO_PMR0S = (GPIO_PMR0_P24); GPIO->GPIO_PORT[2].GPIO_PMR1C = (GPIO_PMR1_P24); GPIO->GPIO_PORT[2].GPIO_PMR2C = (GPIO_PMR2_P24); //- Disable internal Pull-down GPIO->GPIO_PORT[2].GPIO_PDERC = (GPIO_PDERC_P24); //- Enable internal Pull-up GPIO->GPIO_PORT[2].GPIO_PUERS = (GPIO_PUERS_P24); /** Init EIC */ /* - Enable EIC clock */ PM->PM_UNLOCK = PM_UNLOCK_KEY(0xAAu)|PM_UNLOCK_ADDR((uint32_t)&PM->PM_PBDMASK); PM->PM_PBCMASK |= PM_PBDMASK_EIC ; /* Set EIC Interrupt 1 in Edge mode */ EIC->EIC_MODE &= ~(EIC_MODE_INT1); /* Set EIC Interrupt 1 edge detection to rising edge */ EIC->EIC_EDGE |= EIC_EDGE_INT1; /* Enable EIC Interrupt 1 interrupt*/ EIC->EIC_IER |= EIC_IER_INT1; /* Configure Asynchronous detection (for low power)*/ EIC->EIC_ASYNC |= EIC_ASYNC_INT1; /* Clear EIC interrupt flags */ EIC->EIC_ICR = 0xFF; /* - Enable EIC interrupt at code level */ NVIC_EnableIRQ(EIC_1_IRQn); /* - Enable EIC Interrupt 1 */ EIC->EIC_EN |= EIC_EN_INT1; while (1) { button_pressed = 0; while(!button_pressed); /** Enter Retention */ // - Set Sleep deep bit */ SCB->SCR |= (1 << SCB_SCR_SLEEPDEEP_Pos); /* - Set Low power mode to Retention */ BPM->BPM_UNLOCK = BPM_UNLOCK_KEY(0xAAu)|BPM_UNLOCK_ADDR((uint32_t)&BPM->BPM_PMCON); BPM->BPM_PMCON = BPM_PMCON_BKUP; // Enable EIC wake-up and Backup EIC pin MUX BPM->BPM_BKUPWEN |= BPM_BKUPWEN_EIC; // Disable BODs BSCIF->BSCIF_BOD18CTRL &= ~(BSCIF_BOD18CTRL_EN); BSCIF->BSCIF_BOD33CTRL &= ~(BSCIF_BOD33CTRL_EN); __WFI(); /* - Wait until VREG is ok */ while(!(BSCIF->BSCIF_PCLKSR & BSCIF_PCLKSR_VREGOK)); } }
static inline void sam_enable_fastwakeup(void) { uint32_t regval; regval = getreg32(SAM_BPM_PMCON); regval |= BPM_PMCON_FASTWKUP; putreg32(BPM_UNLOCK_KEY(0xaa) | BPM_UNLOCK_ADDR(SAM_BPM_PMCON_OFFSET), SAM_BPM_UNLOCK); putreg32(regval, SAM_BPM_PMCON); }
static __ramfunc__ void sam_instantiatepsm(uint32_t regval) { /* Set the BMP PCOM register (containing the new power scaling mode) */ putreg32(BPM_UNLOCK_KEY(0xaa) | BPM_UNLOCK_ADDR(SAM_BPM_PMCON_OFFSET), SAM_BPM_UNLOCK); putreg32(regval, SAM_BPM_PMCON); /* Wait for new power scaling mode to become active. There should be * timeout on this wait. */ while ((getreg32(SAM_BPM_SR) & BPM_INT_PSOK) == 0); }
void Clock_init(void){ /*Configure SAM4L to run at 48MHz*/ // - Switch Main clock to RCSYS for reconfiguration PM->PM_MCCTRL = PM_MCCTRL_MCSEL(0); // - Set CPU clock = Main clock PM->PM_CPUSEL = ((0<<PM_CPUSEL_CPUDIV_Pos)|(0<<PM_CPUSEL_CPUSEL_Pos)); // - Set Flash wait state to 1 HFLASHC->FLASHCALW_FCR |= (0x1 << FLASHCALW_FCR_FWS_Pos); // - Enable OSC0 SCIF->SCIF_UNLOCK = SCIF_UNLOCK_KEY(0xAAu)|SCIF_UNLOCK_ADDR((uint32_t)&SCIF->SCIF_OSCCTRL0 - (uint32_t)SCIF); SCIF->SCIF_OSCCTRL0 |= SCIF_OSCCTRL0_STARTUP(2)|SCIF_OSCCTRL0_GAIN(3)|SCIF_OSCCTRL0_MODE| SCIF_OSCCTRL0_OSCEN; while (!(SCIF->SCIF_PCLKSR & SCIF_PCLKSR_OSC0RDY)); // - Configure and enable PLL to generate 48MHz from OSC0 SCIF->SCIF_UNLOCK = SCIF_UNLOCK_KEY(0xAAu)|SCIF_UNLOCK_ADDR((uint32_t)&SCIF->SCIF_PLL[0] - (uint32_t)SCIF); SCIF->SCIF_PLL[0].SCIF_PLL|= SCIF_PLL_PLLOSC(0)|SCIF_PLL_PLLDIV(0)|SCIF_PLL_PLLMUL(3)|SCIF_PLL_PLLOPT(2); SCIF->SCIF_PLL[0].SCIF_PLL|= SCIF_PLL_PLLEN; //while (!(SCIF->SCIF_PCLKSR & SCIF_PCLKSR_PLL0LOCK));//wait while the PLL is not locked (not used refer to Datasheet errata rev B)... // - Select PLL0 as main clock source PM->PM_UNLOCK = PM_UNLOCK_KEY(0xAAu)|BPM_UNLOCK_ADDR((uint32_t)&PM->PM_MCCTRL); PM->PM_MCCTRL = PM_MCCTRL_MCSEL_PLL0; /* Enable required peripheral clocks */ PM->PM_UNLOCK = PM_UNLOCK_KEY(0xAAu)|BPM_UNLOCK_ADDR((uint32_t)&PM->PM_PBAMASK); PM->PM_PBAMASK |= PM_PBAMASK_USART0 ; PM->PM_UNLOCK = PM_UNLOCK_KEY(0xAAu)|BPM_UNLOCK_ADDR((uint32_t)&PM->PM_PBCMASK); PM->PM_PBCMASK |= PM_PBCMASK_GPIO ; PM->PM_UNLOCK = PM_UNLOCK_KEY(0xAAu)|BPM_UNLOCK_ADDR((uint32_t)&PM->PM_HSBMASK); PM->PM_HSBMASK |= PM_HSBMASK_PDCA ; PM->PM_UNLOCK = PM_UNLOCK_KEY(0xAAu)|BPM_UNLOCK_ADDR((uint32_t)&PM->PM_PBBMASK); PM->PM_PBBMASK |= PM_PBBMASK_PDCA ; }
/** * \internal * \brief Disable a maskable module clock. * \param bus_id Bus index, given by the \c PM_CLK_GRP_xxx definitions. * \param module_index Index of the module to be disabled. This is the * bit number in the corresponding xxxMASK register. */ void sysclk_priv_disable_module(uint32_t bus_id, uint32_t module_index) { irqflags_t flags; uint32_t mask; flags = cpu_irq_save(); /* Disable the clock */ mask = *(&PM->PM_CPUMASK + bus_id); mask &= ~(1U << module_index); PM->PM_UNLOCK = PM_UNLOCK_KEY(0xAAu) | BPM_UNLOCK_ADDR(((uint32_t)&PM->PM_CPUMASK - (uint32_t)PM) + (4 * bus_id)); *(&PM->PM_CPUMASK + bus_id) = mask; cpu_irq_restore(flags); }