Content originally posted in LPCWare by Ben302 on Tue Nov 11 07:52:36 MST 2014
Struggling with this one. I've looked at examples : microbuiler and NXP an11069 so I think I have everything correct but yet the WAKEUP_IRQHandler is never entered.
I'm successfully switching to the watchdog osc from the IRC and I can see the Timer waggling the MAT3 pin of Timer32B0 pin 0.11. If I stop the debugger just before it sleeps (so the timer is running) I can flip the NVIC ISPR0 bit (0x800) and my interrupt is entered.
I've tried running in in Release mode with no debugger connected.
Currently I'm just trying to wake up and toggle the LED but eventually I'll reset the clock to IRC and do some activity before returning to deep sleep.
void WAKEUP_IRQHandler(void)
{
dword dwRegVal;
LPC_SYSCON->SYSAHBCLKCTRL |= SYSAHBCLKCTRL_IOCON | SYSAHBCLKCTRL_GPIO; //@TODO: needed???
dwRegVal = LPC_SYSCON->STARTSRP0;
if (dwRegVal != 0)
{
LPC_SYSCON->STARTRSRP0CLR = dwRegVal;
}
#if 1
if ( boGPIODDgetPin( SYS_LED ) )
{
vGPIODDsetInactive( SYS_LED ); // off
}
else
{
vGPIODDsetActive( SYS_LED ); // on
}
#endif
/* See tracker for bug report. */
__asm volatile ("NOP");
return;
}
static void vDeepSleep( void )
{
vGPIODDconfigurePin( GPIO_TIMER32_0_MAT3, PIN_IN, FALSE ); // make input but with no pull-up/down
LPC_SYSCON->STARTAPRP0 &= ~(1<<11); // rising edge on pin 0_11
LPC_SYSCON->STARTRSRP0CLR |= (1<<11); // clear all pending bits
LPC_SYSCON->STARTERP0 |= (1<<11); // Enable start logic on pin 0_11
// - and enable the wake up interrupt
NVIC_ClearPendingIRQ(WAKEUP11_IRQn); // P0.11 (CT32B0_MAT3)
NVIC_EnableIRQ(WAKEUP11_IRQn); // P0.11 (CT32B0_MAT3)
/* Configure watchdog clock */
LPC_SYSCON->WDTCLKDIV = 0x1;
/* Freq. = 0.6MHz, div = 64: WDT_OSC = 9375 Hz */
LPC_SYSCON->WDTOSCCTRL = 0x3F;
/* Enable WDT clock - PDRUNCFG is set bit for power down state */
LPC_SYSCON->PDRUNCFG &= ~(PDRUNCFG_WDTOSC_PD);
// peripherals to power up on deep sleep wake
LPC_SYSCON->PDAWAKECFG = LPC_SYSCON->PDRUNCFG; // @TODO: note WD is powered during awake mode - not required in final version
// wdog osc on, BOD off in deep sleep
LPC_SYSCON->PDSLEEPCFG = 0x18BF;
LPC_PMU->PCON &= ~(PCON_DPDEN); // deep sleep not deep power down mode
LPC_PMU->PCON |= PCON_DPD; // clear DPDFLAG in power control register
LPC_PMU->PCON |= PCON_SLEEP; // clear SLEEPFLAG in power control register
// - enable clock for CT32B0 in case not already
LPC_SYSCON->SYSAHBCLKCTRL |= SYSAHBCLKCTRL_CT32B0;
LPC_SYSCON->SYSAHBCLKCTRL |= SYSAHBCLKCTRL_IOCON | SYSAHBCLKCTRL_GPIO;
// - reset and disable the timer
LPC_TMR32B0->TCR = (0x1 << 1);
LPC_TMR32B0->TCR = 0x00;
// - prescale by 1
LPC_TMR32B0->PR = 0;
LPC_TMR32B0->PC = 0; // clear prescalar counter
// - clear timer counter current value
LPC_TMR32B0->TC = 0;
// - reset & INT on Match MR0, for next wake
LPC_TMR32B0->MCR = (0x3);
// set timer value
LPC_TMR32B0->MR0 = (937); // @TODO: timer value - ms at 9375 Hz (600000/64)
// configure external match register
LPC_TMR32B0->EMR &= ~(0xFF << 4); // clear all the config
LPC_TMR32B0->EMR |= (0x3 << 10); // toggle MAT3 on match
// Clear match bit on timer
LPC_TMR32B0->EMR &= ~(1<<3); // MAT3
// Switch main clock to WDT output
LPC_SYSCON->MAINCLKSEL = MAINCLKSEL_WDT;
LPC_SYSCON->MAINCLKUEN |= MAINCLKUEN_ENA; // Update clock source
LPC_SYSCON->MAINCLKUEN &= ~MAINCLKUEN_ENA; // Toggle update register once
LPC_SYSCON->MAINCLKUEN |= MAINCLKUEN_ENA;
// Wait until the clock is updated
while (!(LPC_SYSCON->MAINCLKUEN & MAINCLKUEN_ENA));
// start wake timer
LPC_TMR32B0->TCR = 0x01;
// deep sleep mode
SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
while(1)
{
__WFI();
}
}
Any gotcha's there? I've check the Errata and nothing seems to apply. Getting to the end of my tether! I wish they wouldn't keep me on a tether.