Is there an example project for getting the CY8C20xx6A in and out of Deep Sleep?

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
StWa_1982846
Level 3
Level 3
First like received

I've been all over the Sleep Mode app note and tried everything there and then some -

AN47310 - PSoC® 1 Power Savings Using Sleep Mode

but I am unable to get a GPIO pin to interrupt the part out of regular sleep, much less deep sleep. The one example sleep project I found is way too simple and does not cover deep sleep or waking with GPIO. It also seems like the part is freezing up whenever the button (taking the GPIO pin low) to interrupt the part is pressed, whether in sleep or not.

Questions:

  1. What drive mode to use for the GPIO pin? One source said only Analog-HiZ input mode can interrupt, but I only had success with Open-Drain-Low, and only when not in sleep.
  2. How to properly use the sleep counter? I don't really need it but it seems to be necessary to get the part back out of sleep b/c the GPIO won't do it.
  3. The example had sleep prep set all port drive modes to Analog-HiZ prior to sleep, but when I tried that, the current went up, as though the act of setting and restoring the drives was costing more energy than saved by sleep, implying that something (like the sleep timer) is pulling the part awake far more often than expected.
  4. What registers and pins does one use to set/clear for Deep Sleep? I am not using USB or I2C or any analog blocks. If I set LSO_OFF in Sleep_CFG2 and SLEEP in CPU_SCR0 (with the M8C_Sleep macro), the part shuts down and cannot be awaken except by Reset or Power Down.
  5. Under 11.1.1, the TRM talks about the X32ON and ECO_EX bits in a way that makes no sense to me (I am only using internal oscillators):

... One point to note here is to not set the X32ON bit to '1' without setting the ECO_EX (ECO exists) bit in the

ECO_CFG (1,E1h) register to a '1'. If you do so, the deep sleep mode is not entered, but clk32K is also not running. This

implies that the sleep timer interrupt or the programmable timer interrupt cannot occur.

I am offering a reduced version of my project to illustrate the problems.

Thanks much for any help offered.

Steve

0 Likes
1 Solution

Hello Steve,

In your project, you are using lcall _Button1_ISR_Handler. Instead you should use ljmp _Button1_ISR_Handler. This is because _Button1_ISR_Handler is an ISR and has the reti instruction instead of ret. This is probably why the firmware hangs.

Best regards,

Sampath

View solution in original post

0 Likes
8 Replies
SampathS_11
Moderator
Moderator
Moderator
250 sign-ins 250 solutions authored 5 questions asked

Hello Steve,

It would take some time to reply to your questions. Can you kindly let me know which GPIO are you trying to use to wake up the device from deep sleep?

Best regards,

Sampath Selvaraj

0 Likes

Sampath,

Yes. Button1, on GPIO Port1, Bit 5. However, it is my understanding from the manuals that any port-pin should be capable of waking the part.

From PSoCSGIOINT.h:

// Button1 address and mask defines

#pragma ioport Button1_Data_ADDR: 0x4

BYTE Button1_Data_ADDR;

#pragma ioport Button1_IntEn_ADDR: 0x5

BYTE Button1_IntEn_ADDR;

#define Button1_MASK 0x20

// Button1 Shadow defines

//   Button1_DataShadow define

extern unsigned char Port_1_Data_SHADE;

#define Button1_DataShadow (*(unsigned char*)&Port_1_Data_SHADE)

Steve

0 Likes
SampathS_11
Moderator
Moderator
Moderator
250 sign-ins 250 solutions authored 5 questions asked

Hello Steve,

Questions:

  1. What drive mode to use for the GPIO pin? One source said only Analog-HiZ input mode can interrupt, but I only had success with Open-Drain-Low, and only when not in sleep.  - You can use all Drive Modes for GPIO interrupt to work. Kindly remember that interrupt from all GPIOs vector to the same handler.
  2. How to properly use the sleep counter? I don't really need it but it seems to be necessary to get the part back out of sleep b/c the GPIO won't do it. - Sleep Counter wakes up the device after the terminal count is reached from sleep mode only. The sleep timer is off in deep sleep mode.
  3. The example had sleep prep set all port drive modes to Analog-HiZ prior to sleep, but when I tried that, the current went up, as though the act of setting and restoring the drives was costing more energy than saved by sleep, implying that something (like the sleep timer) is pulling the part awake far more often than expected. I presume that you have seven segment LEDs connected to your GPIO ports. Hence there might be some condition which leads to current through the GPIOs. If we can see your schematic it would be nice.
  4. What registers and pins does one use to set/clear for Deep Sleep? I am not using USB or I2C or any analog blocks. If I set LSO_OFF in Sleep_CFG2 and SLEEP in CPU_SCR0 (with the M8C_Sleep macro), the part shuts down and cannot be awaken except by Reset or Power Down. If you set LSO_OFF, then the device can be woken up by GPIO interrupt,or an USB interrupt. In the Button1 ISR the correct usage should be M8C_ClearIntFlag(INT_CLR0, INT_MSK0_GPIO);. The next line would not be necessary.
  5. Under 11.1.1, the TRM talks about the X32ON and ECO_EX bits in a way that makes no sense to me (I am only using internal oscillators):

... One point to note here is to not set the X32ON bit to '1' without setting the ECO_EX (ECO exists) bit in the

ECO_CFG (1,E1h) register to a '1'. If you do so, the deep sleep mode is not entered, but clk32K is also not running. This

implies that the sleep timer interrupt or the programmable timer interrupt cannot occur.

If X32ON is set to 1, it means we are sourcing from external 32kHz crystal. In this case if ECO_EX is not 1, then the clock path is not completed. In case you are not using an external oscillator, you can leave these bits to the default values.

Best regards,

Sampath

0 Likes

Hi Sampath,

Follow-up comments & questions are in-line below…

Thanks for your continued help.

Steve

0 Likes

Hello Steve,

As per your schematics, you will have to set all GPIOs to Logic 0, or set the mode to Hiz before entering Sleep mode.

Best regards,

Sampath

0 Likes

Sampath,

I AM Setting all the LED outputs to 0 before entering sleep. Button1 is an input, so I do not set it to anything. When the GPIO interrupts are enabled, the program freezes instead of waking up when Button1 is pressed -- even if it is pressed BEFORE entering sleep. There must be something wrong with my interrupt service routine, or how the compiler implements it, but I don't see it.

Steve

0 Likes

Hello Steve,

In your project, you are using lcall _Button1_ISR_Handler. Instead you should use ljmp _Button1_ISR_Handler. This is because _Button1_ISR_Handler is an ISR and has the reti instruction instead of ret. This is probably why the firmware hangs.

Best regards,

Sampath

0 Likes

Sampath,

Thanks so much for discovering my slipup. The correction to using ljump works.

Now... Ahem. Interrupts must return to an address on the stack the same as any call. Excuse me for thinking an lcall was the correct instruction -- have a look at the _wakeup_Timer_ISR implementation for the SleepTimer!

IMO the reason for using ljmp in this case must be some hidden kruft behind the required "#pragma interrupt_handler" for the GPIO. What the hek? This inconsistency has now cost us several weeks of lost project time and a ton of worried hair pulling teeth grinding experimentation.

Whew. Glad that's over.

Steve

0 Likes