robert1356 wrote on Thursday, September 27, 2012:
I know about the master’s paper with power mode covering the EFM parts. However, my needs are not as complex and I’ve attempted to implement what I THINK I need, but I’m having some problems.
First off:
Processor: LPC1756
Compiler: LPCXpresso/CodeRed
FreeRTOS version: 6.0.0
Most of the time, I just go into CLKPWR_Sleep() mode in the vApplicationIdleHook(). This works perfectly. However, there are times when I want to go to sleep for a LONG time (could be hours or days) and will be awakened by an external device activating one of two interrupts:
Device 1: EINT0
Device 2: GPIO/EINT3 (a GPIO pin configured for interrupt)
I’m currently testing the situation with Device 2 only, i.e. Device 1 is never generating an interrupt.
In my vApplicationIdleHook(), I have a test to see if I need to go into the extra low power mode, CLKPWR_PowerDown();
If I do go into low power mode, I understand that all the task timers and such are suspended, but I don’t really care - I have no need to keep any level of “accurate” time while I’m suspended, there is nothing in MY code that needs to be serviced periodically. My code only needs to be able to wakeup when one of the two interrupts are activated. At that point, the tasks can pick up where they left off and continue processing.
The problem I’m having is that when the processor wakes up, it appears to be resetting after the vApplicationIdleHook() returns. I see all of my initialization strings on my UART debug console, these are NOT generated by the debug initialization seen below, they are part of my main() function
I know the processor is waking up because I see the DEBUG string, right before the xTaskResumeAll(), on my debug console. I am careful to disconnect the hardware debugger before testing since the debugger will disable the EINT IRQs. The Debug output functions are direct calls to the UART, they are not messages to another task.
So the question is, while my solution doesn’t keep track of time over the long powerdown mode, is there anything technically wrong with it that should/would cause the FreeRTOS to fail?
void EINT3_IRQHandler(void)
{
mlsDebugGPIO2Clear();
if(GPIO_GetIntStatus(PINSEL_PORT_2, PINSEL_PIN_8, 1)){
GPIO_ClearInt(PINSEL_PORT_2, (1<<PINSEL_PIN_8)); // clear the interrupt flag
}
mlsDebugGPIO2Set();
}
void vApplicationIdleHook()
{
if(doPowerDownMode)
{
vTaskSuspendAll(); // suspend the scheduler (does NOT disable the SysTick interrupt (???)
LOGD(MOD_663IRQ, “WaitOnIRQ - just before PLL disconnect\n”);
//-----------------------------------
// code per errata for rev A silicon
//
// NOTE: once this is complete, cannot use the UART until it is re-initialized! i.e. NO DEBUG MESSAGES!
//—
LPC_SC->PLL0CON &= ~(1<<1); /* Disconnect the main PLL (PLL0) */
LPC_SC->PLL0FEED = 0xAA; /* Feed */
LPC_SC->PLL0FEED = 0x55; /* Feed */
while ((LPC_SC->PLL0STAT & (1<<25)) != 0x00); /* Wait for main PLL (PLL0) to disconnect */
LPC_SC->PLL0CON &= ~(1<<0); /* Turn off the main PLL (PLL0) */
LPC_SC->PLL0FEED = 0xAA; /* Feed */
LPC_SC->PLL0FEED = 0x55; /* Feed */
while ((LPC_SC->PLL0STAT & (1<<24)) != 0x00); /* Wait for main PLL (PLL0) to shut down */
//—
//—
// Enter lowest power mode possible - we cannot go into DeepPowerDown because cannot have the GPIO pins disconnect
// At this stage, the ONLY thing that will wake up the processor is either the I2C_INT or the LPCD_INT
CLKPWR_PowerDown();
//—
// Reinitialize the system immediately after wakeup
// need to wait for the oscillators to achieve operational state (i.e. need to do all the clock setup stuff)
SystemInit(); // init the PLL and Flash
mlsDebugGPIOInit(); // config IO pins
debug_frmwrk_init(); // config the debug UART
LOGD(MOD_663IRQ, “WaitOnIRQ - just after SystemInit”);
xTaskResumeAll(); // restart the scheduler
}
else
{
CLKPWR_Sleep();
}
}