10 years, 4 months ago.

How to restart PLL0 after wakeup from power-down?

In the LPC176x User Manual, its stated:

PLL0 and Power-down mode: Power-down mode automatically turns off and disconnects PLL0. Wake-up from Power-down mode does not automatically restore PLL0 settings, this must be done in software. Typically, a routine to activate PLL0, wait for lock, and then connect PLL0 can be called at the beginning of any interrupt service routine that might be called due to the wake-up. It is important not to attempt to restart PLL0 by simply feeding it when execution resumes after a wake-up from Power-down mode. This would enable and connect PLL0 at the same time, before PLL lock is established.

I tried SystemInit() after wakeup and PLL0FEED, without success. The System clock/PLL Settings stay unrecovered.

Here is my code:

<<code title=power-down and wakeup>>

  1. include "mbed.h"
  2. include "adc.h"
  3. include "qweeky.h"
  4. include "VLSIcodec.h"
  5. include "SDFileSystem.h"
  1. define PinWakeup P2_12

InterruptIn wakeup(PinWakeup); DigitalOut led(LED1); DigitalOut led2(LED2); Serial pc(P0_10,P0_11); TXD, RXD

static void wakeUpHandler(void) { led2 = 1; wait(1); led2 = 0; return; }

void PowerDown(void) { from NXP LPC1765 Erratasheet okt. 10 / 2009 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 */

entering power-down mode: SCB->SCR |= 0x04; LPC_SC->PCON = 0x9; WFI(); }

int main () { wakeup.rise(wakeUpHandler);

led = 1; wait_ms(100); led = 0; pc.printf("going to sleep in 5s...\n"); wait(5);

while (1) { pc.printf("now going to sleep...\n"); wait(0.5); PowerDown();

LPC_SC->PLL0FEED = 0xAA; /* Feed */ LPC_SC->PLL0FEED = 0x55; /* Feed */ SystemInit();

pc.printf("Waking up and analysing Audio Signal...\r\n"); led = 1; wait_ms(100); led = 0; wait(5); pc.printf("done - ready to go back to sleep...\n"); wait_ms(0.5); } } <<code>>

Any help would be great! Thanks :-)

Your last code tag is wrong.

First question: Does it wake up from powerdown?

posted by Erik - 07 Aug 2014

Yes, it wakes up with a rising pulse on EINT2 like supposed. It then correctly initializes PLL and UART and fprints "in wakeupHandler... flashing LED2 now..." correctly. Then, the LED switches on and the system stalls. (led2 stays on forever). So something wrong with wait() after wakeup! ? ! weird.

static void wakeUpHandler(void)
{
    SystemInit();
    Serial pc(P0_10,P0_11); //TXD, RXD
    pc.printf("in wakeupHandler... flashing LED2 now...\n");
    led2 = 1;
    wait_ms(100);    // here it freezes !!??!!
    led2 = 0;
    return;
}

void PowerDown(void)
{
    //entering power-down mode:
    SCB->SCR |= 0x04;
    LPC_SC->PCON=0x1; // PM1=0, PM0=1, enter power down mode if the SLEEPDEEP bit in SCR is 1
   __WFI();
}
 
int main ()
{
    wakeup.rise(wakeUpHandler);  // Setup rising edge interrupt
    
    led = 1;
    wait_ms(100);
    led = 0;
    pc.printf("going to sleep in 5s...\n");
    wait(5);  // for debug purposes. Wait 5 Seconds to allow JTAG access in case System doesn't wake up. 
 
    while (1)
    {
        pc.printf("now going to sleep...\n");
        wait(0.5);
        PowerDown();
        pc.printf("Waking up and analysing Audio Signal...\r\n");
        led = 1;
        wait_ms(100);
        led = 0;
        wait(5);
        pc.printf("preparing to go back to sleep...\n");
    }
}
posted by Martin Heine 08 Aug 2014

I finally figured it out!

by replacing the mbed SystemInit(); with PLL0 config: https://mbed.org/users/hugozijlmans/notebook/pll0-config-script/

Wakeup from Power-Down works like charm.

posted by Martin Heine 11 Aug 2014

Ah didn't see your previous reply, but glad it works now.

posted by Erik - 11 Aug 2014

1 Answer

10 years, 4 months ago.

Now I ran into the next issue :(

everything seems to work fine as mentioned. However - I need to sample some sound for FFT sound recognition. So after my successfully wakeup - i am running this: https://mbed.org/users/simonb/code/ADC_test/

works fine after first wakeup. But when I go back to power-down a second time, and wakeup again, it doesn't sample a thing anymore. Weird again...

Looks like there are still quite a few more issues with that wakeup from power-down. ?

I quickly checked your code and the LPC1768 user manual. The other LPCs have a wakeup configuration register, which sets which peripherals are active after wake up, but I don't see it for the LPC1768. So I would guess the same as before sleep, but it might help to check the PCONP register, to see if it is indeed active after your wake event.

posted by Erik - 12 Aug 2014

I checked PCONP. Its 0001100000001001000100011110 after wakeup. Looks fine to me.

The weird thing is, that it does work one or two times after wakeup from deepsleep or powerdown. Then something crashes and - void sample_ADC(int chan, uint32_t value) - is not being called anymore . I also re-initialized the ADC Clock Devider using LPC_SC->PCLKSEL0 |= 0x1 << 24; But it had no effect.

When I use sleep instead of deepsleep or powerdown, it works like charm, However, I need to keep a battery living for a week, which is not possible with sleep.

posted by Martin Heine 12 Aug 2014

Assigned to Martin Heine 10 years, 4 months ago.

This means that the question has been accepted and is being worked on.