LPC17xx + Deep Sleep + EINT3 problem

javmss wrote on Saturday, June 25, 2011:

I am facing a problem with some LPC17 (LPC1768, LPC1759 and LPC1754) regarding to wake up from deep sleep or power down modes.

In a test program I just want to detect a button click and go to “deep sleep” or “power down” mode.
When running without a call to

vTaskStartScheduler( )

everything works fine. The MCU board, while running, consumes 10 to 12 mA and, when it goes to low power, about 7 mA (a LED stays alive). A button press generates a GPIO irq (shared with EINT3) and the MCU lives again, consuming the same 10 to 12 mA.

If I change the same test program to now use FreeRTOS, and making the very same endless function now a task, the MCU does not wake from low power anymore.

While running, the consumption is the same as before, 10 to 12 mA. The MCU successfully goes to low power, consuming the same 7 mA.
When I press the button, though, the MCU does not comes up to the working state, but flashes very quickly the to monitoring LEDs and goes to a zoombie state consuming about 24 mA.

Can anyone help me, please?
Should I post some code to clarify the things (it is not that big)?

rtel wrote on Saturday, June 25, 2011:

Does the tick interrupt still execute when you are in deep sleep mode?
What is the ‘zoombie’ state?  I mean, what code is executing when it is in that state?


javmss wrote on Saturday, June 25, 2011:

Hello, Richard. Thanks for a so fast response.

I was investigating more deeply some of your questions.

1) Does the tick interrupt still execute when you are in deep sleep mode?

I just called “vTaskSuspendAll( )” prior to “CLKPWR_PowerDown( )”, so I assume the tick is still running.
I tried “configUSE_PREEMPTION” as “0” and “1” with no change.

2) What is the ‘zoombie’ state?

I really’d like to know.
I can’t use the debbugger here. As LPC User Manual states, the WIC (Wake-up Interrupt Controller) doesn’t work if a debbugger is attached.

I am using two LEDs to try to catch the point of code it is running.
One of them just blinks twice a second in the only task I created and the other turns on when it enters “EINT3_Handler( )”.

Thats why I said in the first post that the monitoring LED flashes very fast before going zoombie.

I put a third LED to turn on just after the “CLKPWR_PowerDown(  )”.

Describing what happens when I first click the button (board initially running):

i) The board turns off all LEDs and goes low power. Consumption becomes about 7 mA.
ii) I press the button (holding it down or not - no difference). The EINT3 irq LED and the “just after CLKPWR_PowerDown(  )” LED flash very fast (barely visible).
iii) Current raises to 24 mA.

I suppose something is trying to preempt to an invalid memory location or something like, but I don’t know how to track it.
Any Ideas?

If I stop SysTick should I be able to prevent the scheduler from preempting before it is safe?


Just for information, right now I am using one of these boards:

javmss wrote on Saturday, June 25, 2011:

Please take a look at this code:

void	ping_task( void *params )
	while ( true )
		LED0::toggle( );		// Task alive monitor.
		delay( 250 );
		LED1::off( );			// Turned on in EINT3_Handler. Turn it off here.
		if ( button_released )	// Button was pressed and released (clicked).
			LED0::off( );		// Turn off all LEDs.
			LED1::off( );
			LED2::off( );
			sleeping = true;		// Flag used in EINT3_Handler to prevent generating a "click" on wake-up.
			vTaskSuspendAll( );	// Suspend all tasks while in power down.
			CLKPWR_PowerDown( );	// Enter "Power Down" mode.
				LED2::on( );	// Exit "Power Down" monitor.
				sleeping = false;
			taskEXIT_CRITICAL( );
//			vTaskDelay( 200 );		// <--- ZOOMBIE!
			delay( 200 );		// <--- AHA! Works!
			if( !xTaskResumeAll( ) )	// Woke up, resume tasks.
				taskYIELD( );
void delay( unsigned long tick )
	if ( xTaskGetSchedulerState( ) == taskSCHEDULER_RUNNING )
		vTaskDelay( tick );
		unsigned long systickcnt = SysTickCnt + tick;
		while ( systickcnt > SysTickCnt )

I can’t understand why using my “delay( )” function works while using “vTaskDelay( )” or even nothing just before “xTaskResumeAll( )” it fails.


rtel wrote on Saturday, June 25, 2011:

I think the first thing to do is check the data sheet for that part to see if the power down mode you have selected prevents the timer interrupt from executing.  The timer interrupt on Cortex-M3 cores uses the SysTick timer that is built into the Cortex-M3 core itself, so really there are two questions - first does the SysTick keep running in the power down mode, and second, if it does keep running is it still capable of bringing the CPU out of deep sleep to process interrupts before returning to the sleep mode.

vTaskSuspendAll() does not stop the tick interrupt, it nearly holds ticks that occur while the scheduler is suspended pending until the scheduler is un-suspended, so I don’t think that will make any difference.

One way or another, you also need to see what is executing when the strange behaviour is occurring.  It could be a null loop in an assert of exception handler, hence the higher current draw, but if you knew which you would be 90% to the way of knowing how to debug the problem.  Can you not run the test with the debugger already attached?  Or is what you are referring to above the fact that the debug module does not work in deep sleep mode, so will not work once the sleep mode is exited (or it could even cause a crash when the mode is exected)?


rtel wrote on Saturday, June 25, 2011:

Our two posts crossed each other.

Looking at your code I have two comments.

First, is it right that you are expecting the external interrupt to function inside a critical section?

Second - you cannot/should not call vTaskDelay() while the scheduler is suspended.  Suspending the scheduler will cause tick interrupts to be held pending until such time that the scheduler is unsuspended.  If ticks are held pending, time will be “standing still” and the delay period will never expire.


javmss wrote on Saturday, June 25, 2011:

I understand what you said.

I was really doing wrong calling “vTaskDelay()”.
My “delay( )” function, on the other side, showed me that the kernel was not running.
Curiously, the zoombie state occurs if I try to “xTaskResumeAll( )” soon after wake up, but does not if I wait about 150 ms or more.
This delay I still don’t understand.

I am running from internal RC, not using any PLL. The datasheet says it is a 4 cycles delay for stabilization in this situation.

I will try to do some further tinkering to find out the roots of the problem and I promess to tell everyone.
It is good to have a working program, but bat not to know why (or when)…

Really thanks!