LPC2368 and GPIO wake up seems to be broken in hardware...

Started by arti_tevs September 24, 2009
Hi folks.

Already for several hours, I am trying to use GPIO interrupts (in this case special for P0.18) to wake up the CPU.
Ok the setup is pretty easy:

// react on falling edge
IO0_INT_EN_F |= (1 << 18);
IO0_INT_EN_R |= (1 << 18);

// setup pin as input (with pull-up enabled)
FIO0DIR &= ~(1 << 18);
PINSEL1 &= ~(3 << 4);
PINMODE1 &= ~(3 << 4);

// wake up on GPIO
INTWAKE |= GPIO0WAKE;
EXTINT = EINT3; // don't know if needed, however just do it (GPIO shared with EINT3)

...
PCON = 0x02; // go to sleep

// wakeup
EXTINT = EINT3; // again here to clear the interrupt flag
...

The code works perfectly the CPU can wake up on the GPIO interrupt, however next time the CPU should go to sleep, nothing happens :(

So its sounds like I have to clear the corresponding bit in EXTINT. So assuming EINT3 is shared with GPIO, so must clear the EINT3 bit. However it does not help. Just clearing every bit, also not helps. Even writing 0xFFFFFFFF to clear also reserved bits, also don't help.

If I do the same code, and try it for EINT0 (of course first mapping the port/pin to EINT0), then it works perfectly. Iterating sleep/running mode is then not a problem.

So I assume, either there is a bug in hardware, which cannot clear the external interrupt flag, if interrupt is caused by GPIO interrupt.
Or I am doing something wrong. No of the known errata sheets says something about that.

I hope somebody can help me out of this. I just want to use GPIO interrupts later to wake up the CPU not only once.

cheers,
art

An Engineer's Guide to the LPC2100 Series

*** Comments below

Cheers,
Bruce

-----Original Message-----
From: l... [mailto:l...] On Behalf
Of arti_tevs
Sent: Friday, 25 September 2009 7:43 AM
To: l...
Subject: [lpc2000] LPC2368 and GPIO wake up seems to be broken in
hardware...

Hi folks.

Already for several hours, I am trying to use GPIO interrupts (in this
case special for P0.18) to wake up the CPU.
Ok the setup is pretty easy:

// react on falling edge
IO0_INT_EN_F |= (1 << 18);
IO0_INT_EN_R |= (1 << 18);

*** You say you want to wakeup on falling edge, but you seem to have
programmed it to wake up on both edges ?

// setup pin as input (with pull-up enabled)
FIO0DIR &= ~(1 << 18);
PINSEL1 &= ~(3 << 4);
PINMODE1 &= ~(3 << 4);

// wake up on GPIO
INTWAKE |= GPIO0WAKE;
EXTINT = EINT3; // don't know if needed, however just do it (GPIO shared
with EINT3)

*** EINT3/EXTINT are not relevant here. They are the 'legacy' wakeup
mechanism (and *did* have bugs in some silicon versions). A bit like
IO0PIN is still supported but FIO0PIN is preferred now.

*** Good idea to clear any existing 'wakeup' bits using IO0IntClr (1<<18) here so you don't wake up immediately. I can't see anywhere in
your code where you've cleared these interrupt bits.

...
PCON = 0x02; // go to sleep

// wakeup
EXTINT = EINT3; // again here to clear the interrupt flag
...

*** Nope, EXTINT not relevant. Again IO0IntClr = (1<<18)

The code works perfectly the CPU can wake up on the GPIO interrupt,
however next time the CPU should go to sleep, nothing happens :(

So its sounds like I have to clear the corresponding bit in EXTINT. So
assuming EINT3 is shared with GPIO, so must clear the EINT3 bit. However
it does not help. Just clearing every bit, also not helps. Even writing
0xFFFFFFFF to clear also reserved bits, also don't help.

If I do the same code, and try it for EINT0 (of course first mapping the
port/pin to EINT0), then it works perfectly. Iterating sleep/running
mode is then not a problem.

So I assume, either there is a bug in hardware, which cannot clear the
external interrupt flag, if interrupt is caused by GPIO interrupt.
Or I am doing something wrong. No of the known errata sheets says
something about that.

*** You're doing something wrong :)

I hope somebody can help me out of this. I just want to use GPIO
interrupts later to wake up the CPU not only once.

cheers,
art

No no, sorry, my code was correct. I just put it out of the context, so it seems to be wrong (about the falling/rising edge). The CPU can wakeup however by the next time it just did not get into sleep mode.

My problem was, as you found out, is to clear the interrupt by using IO0IntClr registers. In the manual, in the section about power down mode/wake up there is nothing about how to clear GPIO interrupts. Therefor I did not knew, how to do it right and tried it with clearing EXTINT.

Thank you very much you helped my a lot!

cheers,
art

So what was eventually found as the cause of the one-time operation? I want to know because I have the same problem with my lpc2148. It wakes up once and then will never go to sleep again. I am not using interrupts just "continuing" after the restart pulse.

--- In l..., "Bruce Paterson" wrote:
>
> *** Comments below
>
> Cheers,
> Bruce
>
> -----Original Message-----
> From: l... [mailto:l...] On Behalf
> Of arti_tevs
> Sent: Friday, 25 September 2009 7:43 AM
> To: l...
> Subject: [lpc2000] LPC2368 and GPIO wake up seems to be broken in
> hardware...
>
> Hi folks.
>
> Already for several hours, I am trying to use GPIO interrupts (in this
> case special for P0.18) to wake up the CPU.
> Ok the setup is pretty easy:
>
> // react on falling edge
> IO0_INT_EN_F |= (1 << 18);
> IO0_INT_EN_R |= (1 << 18);
>
> *** You say you want to wakeup on falling edge, but you seem to have
> programmed it to wake up on both edges ?
>
> // setup pin as input (with pull-up enabled)
> FIO0DIR &= ~(1 << 18);
> PINSEL1 &= ~(3 << 4);
> PINMODE1 &= ~(3 << 4);
>
> // wake up on GPIO
> INTWAKE |= GPIO0WAKE;
> EXTINT = EINT3; // don't know if needed, however just do it (GPIO shared
> with EINT3)
>
> *** EINT3/EXTINT are not relevant here. They are the 'legacy' wakeup
> mechanism (and *did* have bugs in some silicon versions). A bit like
> IO0PIN is still supported but FIO0PIN is preferred now.
>
> *** Good idea to clear any existing 'wakeup' bits using IO0IntClr > (1<<18) here so you don't wake up immediately. I can't see anywhere in
> your code where you've cleared these interrupt bits.
>
> ...
> PCON = 0x02; // go to sleep
>
> // wakeup
> EXTINT = EINT3; // again here to clear the interrupt flag
> ...
>
> *** Nope, EXTINT not relevant. Again IO0IntClr = (1<<18)
>
> The code works perfectly the CPU can wake up on the GPIO interrupt,
> however next time the CPU should go to sleep, nothing happens :(
>
> So its sounds like I have to clear the corresponding bit in EXTINT. So
> assuming EINT3 is shared with GPIO, so must clear the EINT3 bit. However
> it does not help. Just clearing every bit, also not helps. Even writing
> 0xFFFFFFFF to clear also reserved bits, also don't help.
>
> If I do the same code, and try it for EINT0 (of course first mapping the
> port/pin to EINT0), then it works perfectly. Iterating sleep/running
> mode is then not a problem.
>
> So I assume, either there is a bug in hardware, which cannot clear the
> external interrupt flag, if interrupt is caused by GPIO interrupt.
> Or I am doing something wrong. No of the known errata sheets says
> something about that.
>
> *** You're doing something wrong :)
>
> I hope somebody can help me out of this. I just want to use GPIO
> interrupts later to wake up the CPU not only once.
>
> cheers,
> art
>
>
Are you quoting the email you intended to quote ?

The one you have quoted has fairly explicit details of what is wrong.

-----Original Message-----
From: l... [mailto:l...] On Behalf Of mayotte_d
Sent: Wednesday, 26 May 2010 8:26 AM
To: l...
Subject: [lpc2000] Re: LPC2368 and GPIO wake up seems to be broken in hardware...

So what was eventually found as the cause of the one-time operation? I want to know because I have the same problem with my lpc2148. It wakes up once and then will never go to sleep again. I am not using interrupts just "continuing" after the restart pulse.

--- In l..., "Bruce Paterson" wrote:
>
> *** Comments below
>
> Cheers,
> Bruce
>
> -----Original Message-----
> From: l... [mailto:l...] On Behalf
> Of arti_tevs
> Sent: Friday, 25 September 2009 7:43 AM
> To: l...
> Subject: [lpc2000] LPC2368 and GPIO wake up seems to be broken in
> hardware...
>
> Hi folks.
>
> Already for several hours, I am trying to use GPIO interrupts (in this
> case special for P0.18) to wake up the CPU.
> Ok the setup is pretty easy:
>
> // react on falling edge
> IO0_INT_EN_F |= (1 << 18);
> IO0_INT_EN_R |= (1 << 18);
>
> *** You say you want to wakeup on falling edge, but you seem to have
> programmed it to wake up on both edges ?
>
> // setup pin as input (with pull-up enabled)
> FIO0DIR &= ~(1 << 18);
> PINSEL1 &= ~(3 << 4);
> PINMODE1 &= ~(3 << 4);
>
> // wake up on GPIO
> INTWAKE |= GPIO0WAKE;
> EXTINT = EINT3; // don't know if needed, however just do it (GPIO shared
> with EINT3)
>
> *** EINT3/EXTINT are not relevant here. They are the 'legacy' wakeup
> mechanism (and *did* have bugs in some silicon versions). A bit like
> IO0PIN is still supported but FIO0PIN is preferred now.
>
> *** Good idea to clear any existing 'wakeup' bits using IO0IntClr > (1<<18) here so you don't wake up immediately. I can't see anywhere in
> your code where you've cleared these interrupt bits.
>
> ...
> PCON = 0x02; // go to sleep
>
> // wakeup
> EXTINT = EINT3; // again here to clear the interrupt flag
> ...
>
> *** Nope, EXTINT not relevant. Again IO0IntClr = (1<<18)
>
> The code works perfectly the CPU can wake up on the GPIO interrupt,
> however next time the CPU should go to sleep, nothing happens :(
>
> So its sounds like I have to clear the corresponding bit in EXTINT. So
> assuming EINT3 is shared with GPIO, so must clear the EINT3 bit. However
> it does not help. Just clearing every bit, also not helps. Even writing
> 0xFFFFFFFF to clear also reserved bits, also don't help.
>
> If I do the same code, and try it for EINT0 (of course first mapping the
> port/pin to EINT0), then it works perfectly. Iterating sleep/running
> mode is then not a problem.
>
> So I assume, either there is a bug in hardware, which cannot clear the
> external interrupt flag, if interrupt is caused by GPIO interrupt.
> Or I am doing something wrong. No of the known errata sheets says
> something about that.
>
> *** You're doing something wrong :)
>
> I hope somebody can help me out of this. I just want to use GPIO
> interrupts later to wake up the CPU not only once.
>
> cheers,
> art
>
>