/* Put some of the peripheral in sleep mode */ void Chip_PMU_Sleep(LPC_PMU_T *pPMU, CHIP_PMU_MCUPOWER_T SleepMode) { if (SleepMode == PMU_MCU_DEEP_SLEEP) { Chip_PMU_DeepSleepState(pPMU); } else if (SleepMode == PMU_MCU_POWER_DOWN) { Chip_PMU_PowerDownState(pPMU); } else if (SleepMode == PMU_MCU_DEEP_PWRDOWN) { Chip_PMU_DeepPowerDownState(pPMU); } else { /* PMU_MCU_SLEEP */ Chip_PMU_SleepState(pPMU); } }
int32_t main(void) { int32_t i,cnt=0; uint8_t RC5_System_prev=0; uint8_t RC5_Command_prev=0; CHIP_PMU_MCUPOWER_T mcupower=PMU_MCU_SLEEP; SystemCoreClockUpdate(); // init GPIO Chip_GPIO_Init(LPC_GPIO_PORT); Chip_SYSCTL_PeriphReset(RESET_GPIO); // init SPI0 at SystemCoreClock speed Chip_SPI_Init(LPC_SPI0); Chip_SPI_ConfigureSPI(LPC_SPI0,SPI_MODE_MASTER| SPI_CLOCK_CPHA0_CPOL0| SPI_DATA_MSB_FIRST| SPI_SSEL_ACTIVE_LO); LPC_SPI0->DIV=0; Chip_SPI_Enable(LPC_SPI0); // init MRT Chip_MRT_Init(); // init SWM Chip_SWM_Init(); Chip_SWM_DisableFixedPin(SWM_FIXED_SWCLK);//PIO0_3 Chip_SWM_DisableFixedPin(SWM_FIXED_SWDIO);//PIO0_2 Chip_SWM_DisableFixedPin(SWM_FIXED_ACMP_I2);//PIO0_1 Chip_SWM_DisableFixedPin(SWM_FIXED_ACMP_I1);//PIO0_0 Chip_SWM_MovablePinAssign(SWM_SPI0_SCK_IO,CLK_PIN); Chip_SWM_MovablePinAssign(SWM_SPI0_MOSI_IO,MOSI_PIN); Chip_SWM_MovablePinAssign(SWM_CTIN_0_I,IR_PIN); Chip_SWM_Deinit(); // init onboard LED Chip_GPIO_SetPinState(LPC_GPIO_PORT,0,LED_PIN,true); Chip_GPIO_SetPinDIROutput(LPC_GPIO_PORT,0,LED_PIN); // init LCD reset pin Chip_GPIO_SetPinDIROutput(LPC_GPIO_PORT,0,RESET_PIN); // init LCD LCDInit(); LCDClearScreenBlack(); // init SCT Chip_SCT_Init(LPC_SCT); // set prescaler, SCT clock = 1 MHz, clear counter LPC_SCT->CTRL_L |= SCT_CTRL_PRE_L(SystemCoreClock/1000000-1) | SCT_CTRL_CLRCTR_L; sct_fsm_init(); NVIC_EnableIRQ(SCT_IRQn); // init PIO0_3 pin interrupt for wakeup from sleep mode Chip_SYSCTL_SetPinInterrupt(IR_IRQ,IR_PIN); Chip_PININT_EnableIntLow(LPC_PININT, PININTCH(IR_IRQ)); NVIC_EnableIRQ(PININT3_IRQn); Chip_SYSCTL_EnablePINTWakeup(IR_IRQ); // set sleep options Chip_SYSCTL_SetDeepSleepPD(SYSCTL_DEEPSLP_BOD_PD | SYSCTL_DEEPSLP_WDTOSC_PD); Chip_SYSCTL_SetWakeup(~(SYSCTL_SLPWAKE_IRCOUT_PD | SYSCTL_SLPWAKE_IRC_PD | SYSCTL_SLPWAKE_FLASH_PD )); LCDPutStr("kbiva.wordpress.com", MAX_X / 2 + 50, 10, WHITE, BLACK); LCDPutStr("RC5 Decoder", MAX_X / 2 + 35, 35, WHITE, BLACK); LCDPutStr("Frame:", MAX_X / 2 + 20, 1, WHITE, BLACK); LCDPutStr("System:", MAX_X / 2 + 5 , 1, WHITE, BLACK); LCDPutStr("Cmd:", MAX_X / 2 - 10, 1, WHITE, BLACK); LCDPutStr("Toggle:", MAX_X / 2 - 25, 1, WHITE, BLACK); LCDPutStr("Count:", MAX_X / 2 - 40, 1, WHITE, BLACK); while (1) { // put chip to sleep switch(mcupower) { case PMU_MCU_SLEEP: default: LCDPutStr("SLEEP ", MAX_X / 2 - 60, 10, WHITE, BLACK); Chip_PMU_SleepState(LPC_PMU); break; case PMU_MCU_DEEP_SLEEP: LCDPutStr("DEEP-SLEEP", MAX_X / 2 - 60, 10, WHITE, BLACK); Chip_PMU_DeepSleepState(LPC_PMU); break; case PMU_MCU_POWER_DOWN: LCDPutStr("POWER-DOWN", MAX_X / 2 - 60, 10, WHITE, BLACK); Chip_PMU_PowerDownState(LPC_PMU); break; } // start MRT timer channel 0 Chip_MRT_SetInterval(LPC_MRT_CH0, SystemCoreClock | MRT_INTVAL_LOAD); Chip_MRT_SetMode(LPC_MRT_CH0,MRT_MODE_ONESHOT); Chip_MRT_SetEnabled(LPC_MRT_CH0); // turn on onboard LED Chip_GPIO_SetPinState(LPC_GPIO_PORT,0,LED_PIN,false); // start SCT LPC_SCT->CTRL_L &= ~SCT_CTRL_HALT_L; // wait for timeout while(!RC5_timeout) {}; // stop SCT LPC_SCT->CTRL_L |= SCT_CTRL_HALT_L; if (RC5_flag) { // if frame received, output information on LCD if((RC5_System != RC5_System_prev) || (RC5_Command != RC5_Command_prev)) { cnt = 1; } else { cnt++; } for (i = 3; i >= 0; i--){ LCDPutChar(ascii[(RC5_Frame >> (i * 4)) & 0x0F],MAX_X / 2 + 20,80+(3-i)*7,WHITE, BLACK); if(i < 2) { if((RC5_System!=RC5_System_prev) || (RC5_Command!=RC5_Command_prev)){ LCDPutChar(ascii[(RC5_System >> (i * 4)) & 0x0F],MAX_X / 2 + 5,66+(3-i)*7,WHITE, BLACK); LCDPutChar(ascii[(RC5_Command >> (i * 4)) & 0x0F],MAX_X / 2 - 10,66+(3-i)*7,WHITE, BLACK); } } LCDPutChar(ascii[(cnt >> (i * 4)) & 0x0F],MAX_X / 2 - 40,80+(3-i)*7,WHITE, BLACK); } LCDPutStr(RC5_Toggle ? "ON ":"OFF", MAX_X / 2 - 25, 80, WHITE, BLACK); switch(RC5_Command) { case 0x50: mcupower = PMU_MCU_SLEEP; break; case 0x55: if(RC5_Toggle){ spi0Transfer(SLEEPOUT); spi0Transfer(DISPON); } else { spi0Transfer(DISPOFF); spi0Transfer(SLEEPIN); } break; case 0x56: mcupower = PMU_MCU_DEEP_SLEEP; break; case 0x6B: mcupower = PMU_MCU_POWER_DOWN; break; } RC5_System_prev = RC5_System; RC5_Command_prev = RC5_Command; } // turn off onboard LED Chip_GPIO_SetPinState(LPC_GPIO_PORT,0,LED_PIN,true); // clear flags RC5_flag = 0; RC5_timeout = 0; }
/** * @brief Main program body * @return int */ int main(void) { int stateCounter = 0; uint32_t ticks = 0; /* Setup SystemCoreClock and any needed board code */ SystemCoreClockUpdate(); Board_Init(); /* Enable the RTC oscillator, oscillator rate can be determined by calling Chip_Clock_GetRTCOscRate() */ Chip_Clock_EnableRTCOsc(); /* Initialize RTC driver (enables RTC clocking) */ Chip_RTC_Init(LPC_RTC); /* Enable RTC as a peripheral wakeup event */ Chip_SYSCTL_EnableERP1PeriphWakeup(SYSCTL_ERP1_WAKEUP_RTCALARMINT | SYSCTL_ERP1_WAKEUP_RTCWAKEINT); /* RTC reset */ Chip_RTC_Reset(LPC_RTC); /* Start RTC at a count of 0 when RTC is disabled. If the RTC is enabled, you need to disable it before setting the initial RTC count. */ Chip_RTC_Disable(LPC_RTC); Chip_RTC_SetCount(LPC_RTC, 0); /* Set a long alarm time so the interrupt won't trigger */ Chip_RTC_SetAlarm(LPC_RTC, 1000); /* Enable RTC and high resolution timer - this can be done in a single call with Chip_RTC_EnableOptions(LPC_RTC, (RTC_CTRL_RTC1KHZ_EN | RTC_CTRL_RTC_EN)); */ Chip_RTC_Enable1KHZ(LPC_RTC); Chip_RTC_Enable(LPC_RTC); /* Clear latched RTC interrupt statuses */ Chip_RTC_ClearStatus(LPC_RTC, (RTC_CTRL_OFD | RTC_CTRL_ALARM1HZ | RTC_CTRL_WAKE1KHZ)); /* Enable RTC wake and alarm interrupts */ NVIC_EnableIRQ(RTC_ALARM_IRQn); NVIC_EnableIRQ(RTC_WAKE_IRQn); /* Enable RTC alarm interrupt */ Chip_RTC_EnableWakeup(LPC_RTC, (RTC_CTRL_ALARMDPD_EN | RTC_CTRL_WAKEDPD_EN)); /* Sleep and do all the work in the RTC interrupt handler */ while (1) { ticks = 0; DEBUGOUT("Tick number: %d, 1KHZ int:%d, alarm int:%d\r\n", stateCounter, rtcWake, rtcAlarm); rtcWake = rtcAlarm = false; /* 10 high resolution ticks that get slower each tick */ if (stateCounter < 10) { /* Wakeup in 300, 400, 500, etc. milliSeconds */ Chip_RTC_SetWake(LPC_RTC, (300 + (stateCounter * 100))); stateCounter++; } else { DEBUGOUT("Setting alarm to wake up in 4s\r\n"); /* Set alarm to wakeup in 4 seconds */ Chip_RTC_SetAlarm(LPC_RTC, Chip_RTC_GetCount(LPC_RTC) + 4); stateCounter = 0; } Chip_SYSCTL_SetWakeup(~(SYSCTL_SLPWAKE_IRCOUT_PD | SYSCTL_SLPWAKE_IRC_PD | SYSCTL_SLPWAKE_FLASH_PD | SYSCTL_SLPWAKE_SYSOSC_PD | SYSCTL_SLPWAKE_SYSPLL_PD)); Chip_SYSCTL_EnableERP1PeriphWakeup(SYSCTL_ERP1_WAKEUP_RTCALARMINT | SYSCTL_ERP1_WAKEUP_RTCWAKEINT); /* Delay to allow serial transmission to complete*/ while(ticks++ < 10000) {} /* Enter MCU Deep Sleep mode */ Chip_PMU_DeepSleepState(LPC_PMU); } return 0; }
/* Handle interrupt from GPIO pin or GPIO pin mapped to PININT */ static void ProcessPowerState(CHIP_PMU_MCUPOWER_T crntPowerSetting) { volatile uint32_t tempTimeout; /* Output power status message, add separating space */ DEBUGSTR("\r\n"); /* Switch on current selected power setting */ switch (crntPowerSetting) { case PMU_MCU_SLEEP: default: DEBUGSTR("-----------------------------------------------------------------\r\n"); DEBUGSTR(" Entering SLEEP power setting\r\n"); DEBUGOUT(" (System will exit SLEEP in %d seconds)\r\n", POWER_CYCLE_SEC_DELAY); DEBUGSTR("-----------------------------------------------------------------\r\n\r\n"); /* Wait for all serial characters to be output */ DelayForSerialOutput(); /* Enter MCU Sleep mode */ Chip_PMU_SleepState(LPC_PMU); break; case PMU_MCU_DEEP_SLEEP: DEBUGSTR("-----------------------------------------------------------------\r\n"); DEBUGSTR(" Entering DEEP SLEEP power setting\r\n"); DEBUGOUT(" (System will exit DEEP SLEEP in %d seconds)\r\n", POWER_CYCLE_SEC_DELAY); DEBUGSTR("-----------------------------------------------------------------\r\n\r\n"); /* Wait for all serial characters to be output */ DelayForSerialOutput(); /* We should call Chip_SYSCTL_SetWakeup() to setup any peripherals we want to power back up on wakeup. For this example, we'll power back up the IRC, FLASH, the system oscillator, and the PLL */ Chip_SYSCTL_SetWakeup(~(SYSCTL_SLPWAKE_IRCOUT_PD | SYSCTL_SLPWAKE_IRC_PD | SYSCTL_SLPWAKE_FLASH_PD | SYSCTL_SLPWAKE_SYSOSC_PD | SYSCTL_SLPWAKE_SYSPLL_PD)); Chip_SYSCTL_EnableERP1PeriphWakeup(SYSCTL_ERP1_WAKEUP_RTCALARMINT); /* Enter MCU Deep Sleep mode */ Chip_PMU_DeepSleepState(LPC_PMU); break; case PMU_MCU_POWER_DOWN: DEBUGSTR("-----------------------------------------------------------------\r\n"); DEBUGSTR(" Entering POWER DOWN power setting\r\n"); DEBUGOUT(" (System will exit POWER DOWN in %d seconds)\r\n", POWER_CYCLE_SEC_DELAY); DEBUGSTR("-----------------------------------------------------------------\r\n\r\n"); /* Wait for all serial characters to be output */ DelayForSerialOutput(); /* We should call Chip_SYSCTL_SetWakeup() to setup any peripherals we want to power back up on wakeup. For this example, we'll power back up the IRC, FLASH, the system oscillator, and the PLL */ Chip_SYSCTL_SetWakeup(~(SYSCTL_SLPWAKE_IRCOUT_PD | SYSCTL_SLPWAKE_IRC_PD | SYSCTL_SLPWAKE_FLASH_PD | SYSCTL_SLPWAKE_SYSOSC_PD | SYSCTL_SLPWAKE_SYSPLL_PD)); Chip_SYSCTL_EnableERP1PeriphWakeup(SYSCTL_ERP1_WAKEUP_RTCALARMINT); /* Enter MCU Power down mode */ Chip_PMU_PowerDownState(LPC_PMU); break; case PMU_MCU_DEEP_PWRDOWN: DEBUGSTR("-----------------------------------------------------------------\r\n"); DEBUGSTR(" Entering DEEP POWER DOWN power setting\r\n"); DEBUGOUT(" (System will exit DEEP POWER DOWN in %d seconds)\r\n", POWER_CYCLE_SEC_DELAY); DEBUGSTR("-----------------------------------------------------------------\r\n\r\n"); /* Wait for all serial characters to be output */ DelayForSerialOutput(); /* Enable wakeup from deep power down mode due to RTC Alarm Match */ Chip_RTC_EnableWakeup(LPC_RTC, RTC_CTRL_ALARMDPD_EN); /* Enter MCU Deep Power down mode */ Chip_PMU_DeepPowerDownState(LPC_PMU); break; } }