static void WakeupTest(WKT_CLKSRC_T clkSrc, uint32_t timeoutInSecs, CHIP_PMU_MCUPOWER_T powerTest) { /* 10KHz clock source */ Chip_WKT_SetClockSource(LPC_WKT, clkSrc); /* Setup for wakeup in timeout */ Chip_WKT_LoadCount(LPC_WKT, Chip_WKT_GetClockRate(LPC_WKT) * timeoutInSecs); /* We can optionally call Chip_SYSCTL_SetDeepSleepPD() to power down the BOD and WDT if we aren't using them in deep sleep modes. */ Chip_SYSCTL_SetDeepSleepPD(SYSCTL_DEEPSLP_BOD_PD | SYSCTL_DEEPSLP_WDTOSC_PD); /* 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)); /* Tell PMU to go to sleep */ Chip_PMU_Sleep(LPC_PMU, powerTest); /* Power anything back up here that isn't powered up on wakeup. The example code below powers back up the BOD and WDT oscillator, which weren't setup to pwower up in the Chip_SYSCTL_SetWakeup() function. */ Chip_SYSCTL_SetDeepSleepPD(0); /* Will return here after wakeup and WKT IRQ, LED should be on */ Chip_WKT_Stop(LPC_WKT); }
/* 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 */ LPC_PWRD_API->power_mode_configure(PMU_SLEEP, (PMU_PD_WDOSC | PMU_PD_BOD | PMU_PD_ACMP0 | PMU_PD_ACMP1 | PMU_PD_ACMP2 |PMU_PD_ACMP3 | PMU_PD_IREF | PMU_PD_TS)); __WFI(); 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 */ LPC_PWRD_API->power_mode_configure(PMU_DEEP_SLEEP, (PMU_PD_WDOSC | PMU_PD_BOD | PMU_PD_ACMP0 | PMU_PD_ACMP1 | PMU_PD_ACMP2 |PMU_PD_ACMP3 | PMU_PD_IREF | PMU_PD_TS)); __WFI(); 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 */ LPC_PWRD_API->power_mode_configure(PMU_POWERDOWN, (PMU_PD_WDOSC | PMU_PD_BOD | PMU_PD_ACMP0 | PMU_PD_ACMP1 | PMU_PD_ACMP2 |PMU_PD_ACMP3 | PMU_PD_IREF | PMU_PD_TS)); __WFI(); 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 */ LPC_PWRD_API->power_mode_configure(PMU_DEEP_POWERDOWN, (PMU_PD_WDOSC | PMU_PD_BOD | PMU_PD_ACMP0 | PMU_PD_ACMP1 | PMU_PD_ACMP2 |PMU_PD_ACMP3 | PMU_PD_IREF | PMU_PD_TS)); __WFI(); break; } }
/** * @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; }
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; }