I'm trying to get the self wakeup timer to restart an LPC810 (standalone, no board) after a deep power down. The application is to simulate a 'lighthouse' type effect with an LED, power down & after approx 8 secs reset & repeat.
/*
===============================================================================
Name : lighthouseD.c
Author : $(OFO)
Version : v.01
Copyright : $(OFO)
Description : Create lighthouse type effect with LED
: Final project for release onto stand alone chip!!
: NOTE: If board becomes 'bricked' connect pins 7 & 8 of port J7 together
: i.e. PIO0_1 Pin 5
: then connect USB cable (places into ISP mode)
===============================================================================
*/
#if defined (__USE_LPCOPEN)
#if defined(NO_BOARD_LIB)
#include "chip.h"
#else
#include "board.h"
#endif
#endif
#include <cr_section_macros.h>
#define LED1_GPIO_PORT_NUM 0
#define LED1_GPIO_BIT_NUM 0
#define RAMP_TIME 2 // How many seconds to go from off to full bright & vice-versa
volatile uint32_t millis = 0; //millisecond counter
void SysTick_Handler(void) {
//our systick interrupt handler
millis++;
}
void delay_ms(uint32_t ms) {
//delay (ms)
uint32_t now = millis;
while ((millis - now) < ms);
}
void WKT_IRQHandler(void){
/* Clear self wakeup timer (WKT) interrupt request */
Chip_WKT_ClearIntStatus(LPC_WKT);
}
void deep_power_down (uint32_t secs){
// Function to put micro into deep power down (most power saving mode)
// Woken by self wake-up timer
// Full reset on wake-up
// Disable wakeup pin
Chip_PMU_SetPowerDownControl(LPC_PMU, PMU_DPDCTRL_WAKEPAD);
/* Alarm/wake timer as chip wakeup source */
Chip_SYSCTL_EnablePeriphWakeup(SYSCTL_WAKEUP_WKTINT);
/* Enable and reset WKT clock */
Chip_Clock_EnablePeriphClock(SYSCTL_CLOCK_WKT);
Chip_SYSCTL_PeriphReset(RESET_WKT);
/* 10KHz clock source */
Chip_WKT_SetClockSource(LPC_WKT, WKT_CLKSRC_10KHZ);
/* Setup for wakeup in 5s */
Chip_WKT_LoadCount(LPC_WKT, Chip_WKT_GetClockRate(LPC_WKT) * 8);
// Enable deep power down mode
// Will restart with full reset
// Note: This function includes a __WFI !!
Chip_PMU_DeepPowerDownState(LPC_PMU);
/*
Chip_PMU_SetPowerDownControl(LPC_PMU, PMU_DPDCTRL_LPOSCEN | PMU_DPDCTRL_LPOSCDPDEN | PMU_DPDCTRL_WAKEPAD);
// Ensure deep power down not inhibited (PCON, bit 3)
// Can only be cleared by chip reset
// Setup for wakeup in X s
Chip_WKT_LoadCount(LPC_WKT, Chip_WKT_GetClockRate(LPC_WKT) * secs);
// Enable deep power down mode
// Will restart with full reset
// Note: This function includes a __WFI !!
Chip_PMU_DeepPowerDownState(LPC_PMU);
*/
}
int main(void) {
volatile static int c;
int time_per = 0; // Percentage time for LED to be on
int ms_old = 0;
#if defined (__USE_LPCOPEN)
// Read clock settings and update SystemCoreClock variable
SystemCoreClockUpdate();
#if !defined(NO_BOARD_LIB)
// Set up and initialize all required blocks and
// functions related to the board hardware
Board_Init();
// Set the LED to the state of "On"
//Board_LED_Set(0, true);
#endif
#endif
// Setup systick clock interrupt @1ms
// This function is in core_cm0plus.h in lpc_chip_8xx project
SysTick_Config(Chip_Clock_GetSystemClockRate()/1000);
// Setup LED port pin
Chip_GPIO_SetPinDIROutput(LPC_GPIO_PORT, LED1_GPIO_PORT_NUM, LED1_GPIO_BIT_NUM);
Chip_GPIO_SetPinState(LPC_GPIO_PORT, LED1_GPIO_PORT_NUM, LED1_GPIO_BIT_NUM, true);
Chip_GPIO_SetPinState(LPC_GPIO_PORT, LED1_GPIO_PORT_NUM, LED1_GPIO_BIT_NUM, false); // Ensure off
// Check did we restart from deep power down?
if ((Chip_PMU_GetSleepFlags(LPC_PMU) & PMU_PCON_DPDFLAG) == TRUE){
// We woke from deep power down, must clear
Chip_PMU_ClearSleepFlags(LPC_PMU, PMU_PCON_DPDFLAG);
// Flash LED
Chip_GPIO_SetPinState(LPC_GPIO_PORT, LED1_GPIO_PORT_NUM, LED1_GPIO_BIT_NUM, TRUE);
delay_ms(1000);
Chip_GPIO_SetPinState(LPC_GPIO_PORT, LED1_GPIO_PORT_NUM, LED1_GPIO_BIT_NUM, FALSE);
}
while (1){
// Get brighter over RAMP_TIME
ms_old = millis; // Record time
for (time_per = 1; time_per < 100;){
Chip_GPIO_SetPinState(LPC_GPIO_PORT, LED1_GPIO_PORT_NUM, LED1_GPIO_BIT_NUM, TRUE);
// Wait
for (c = 0; c < time_per; c++);
Chip_GPIO_SetPinState(LPC_GPIO_PORT, LED1_GPIO_PORT_NUM, LED1_GPIO_BIT_NUM, FALSE);
// Wait
for (c = 0; c < (100 -time_per); c++);
if ((millis - ms_old) > (RAMP_TIME * 10)){
// Increase brightness
time_per++;
ms_old = millis;
}
}
// Dwell
Chip_GPIO_SetPinState(LPC_GPIO_PORT, LED1_GPIO_PORT_NUM, LED1_GPIO_BIT_NUM, TRUE);
//delay_ms(1000);
//deep_sleep(1);
// Get dimmer over RAMP_TIME
ms_old = millis; // Record time
for (time_per = 100; time_per > 1;){
Chip_GPIO_SetPinState(LPC_GPIO_PORT, LED1_GPIO_PORT_NUM, LED1_GPIO_BIT_NUM, TRUE);
// Wait
for (c = 0; c < time_per; c++);
Chip_GPIO_SetPinState(LPC_GPIO_PORT, LED1_GPIO_PORT_NUM, LED1_GPIO_BIT_NUM, FALSE);
// Wait
for (c = 0; c < (100 -time_per); c++);
if ((millis - ms_old) > (RAMP_TIME * 10)){
// decrease brightness
time_per--;
ms_old = millis;
}
}
// Switch off & wait
Chip_GPIO_SetPinState(LPC_GPIO_PORT, LED1_GPIO_PORT_NUM, LED1_GPIO_BIT_NUM, FALSE);
//delay_ms (8000);
deep_power_down(8);
}
return 0 ;
}
The chip appears to successfully enter a power down state but fails to restart.
PS. I notice that there are similar functions in syscon_8xx.h & pmu_8xx.h. Which should be used? A little confusing.