Hello all,
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.
The code:
/*
===============================================================================
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-versavolatile 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 timefor (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 timefor (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.
Can anyone help?
PS. I notice that there are similar functions in syscon_8xx.h & pmu_8xx.h. Which should be used? A little confusing.
Thanks,
Leo
Well I think I found the issue, it seems that an additional line is required before loading the count into the SWT register, see below. I'm not quite sure but it seems like the inline function:
STATIC INLINE WKT_CLKSRC_T Chip_WKT_GetClockSource(LPC_WKT_T *pWKT)
{
return (WKT_CLKSRC_T) (pWKT->CTRL & WKT_CTRL_CLKSEL);
}
Was not returning the correct clock source. Still haven't discovered the reason..
As an aside it seems like there's some misnaming of the files in lpc_chip_8xx library I'm using. For example the WKT functions are contained in a file called wwdt_8xx.c & the WWDT functions in the wkt_8xx.c. A little confusing!!
Regards,
Leo
/*
===============================================================================
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){
// Disable wakeup pin
Chip_PMU_SetPowerDownControl(LPC_PMU, PMU_DPDCTRL_LPOSCEN | PMU_DPDCTRL_LPOSCDPDEN | PMU_DPDCTRL_WAKEPAD);
// Needed?
NVIC_ClearPendingIRQ(WKT_IRQn);
NVIC_DisableIRQ(WKT_IRQn);
// Init self wakeup timer (WKT)
/* Enable clock for WKT */
LPC_SYSCON->SYSAHBCLKCTRL |= (1 << 9);
/* Reset WKT */
LPC_SYSCON->PRESETCTRL &= ~(1 << 9);
LPC_SYSCON->PRESETCTRL |= (1 << 9);
/* set LPOSCDPDEN and LPOSCEN to 1 */
LPC_PMU->DPDCTRL |= (3 << 2);
/* Enable Interrupt for WKT in NVIC */
NVIC_EnableIRQ(WKT_IRQn);
/* Config WKT */
LPC_WKT->CTRL = (1 << 2);
Chip_WKT_SetClockSource(LPC_WKT, WKT_CLKSRC_10KHZ); // <<--------------LINE REQUIRED!
Chip_WKT_LoadCount(LPC_WKT, Chip_WKT_GetClockRate(LPC_WKT) * secs);
LPC_WKT->CTRL = 1;
/* WKT can wake up */
LPC_SYSCON->STARTERP1 = (1 << 15);
/* Go to deep power down mode */
LPC_PMU->PCON = 0x3;
Chip_PMU_DeepPowerDownState(LPC_PMU); // Includes __WFI();
//__WFI();
}
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) != FALSE){
// We woke from deep power down, must clear
Chip_PMU_ClearSleepFlags(LPC_PMU, PMU_PCON_DPDFLAG | PMU_PCON_SLEEPFLAG );
// Flash LED
//Chip_GPIO_SetPinState(LPC_GPIO_PORT, LED1_GPIO_PORT_NUM, LED1_GPIO_BIT_NUM, TRUE);
//delay_ms(300);
//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);
// 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);
deep_power_down(6);
}
return 0 ;
}
Hi,
Thank you for your interest in NXP Semiconductor products and for the opportunity to serve you.
To provide the fastest possible support, I'd highly recommend you to refer to the periph_wkt demo in the SDK library. And you can download the library via the link.
https://www.nxp.com/support/developer-resources/software-development-tools/lpc-developer-resources-/...
Have a great day,
TIC
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------