PIC24FJ64GA104 FAMILY
Examples for implementing these cases are shown in
Example 9-2. It is recommended that an assembler, or
in-line C routine be used in these cases, to ensure that
the code executes in the number of cycles required.
9.2.4.2
Special Cases when Entering Deep
Sleep Mode
When entering Deep Sleep mode, there are certain
circumstances that require a delay between setting the
DSEN bit and executing the PWRSAVinstruction. These
can be generally reduced to three scenarios:
EXAMPLE 9-2:
IMPLEMENTING THE
SPECIAL CASES FOR
ENTERING DEEP SLEEP
1. Scenario (1): use an external wake-up source
(INT0) or the RTCC is used
// Case 1: simplest delay scenario
//
asm("bset DSCON, #15");
asm("nop");
asm("nop");
2. Scenario (2): with application-level interrupts
that can be temporarily disabled
3. Scenario (3): with interrupts that must be
monitored
In the first scenario, the application requires a wake-up
from Deep Sleep on the assertion of the INT0 pin or the
RTCC interrupt. In this case, three NOP instructions
must be inserted to properly synchronize the detection
of an asynchronous INT0 interrupt after the device
enters Deep Sleep mode. If the application does not
use wake-up on INT0 or RTCC, the NOP instructions
are optional.
asm("nop");
asm("pwrsav #0");
//
// Case 2: interrupts disabled
//
asm("disi #4");
asm("bset DSCON, #15");
asm("nop");
asm("nop");
asm("nop");
In the second scenario, the application also uses
interrupts which can be briefly ignored. With these
applications, an interrupt event during the execution of
the NOPinstructions may cause an ISR to be executed.
This means that more than three instruction cycles will
elapse before returning to the code and that the DSEN
bit will be cleared. To prevent the missed entry into
Deep Sleep, temporarily disable interrupts prior to
entering Deep Sleep mode. Invoking the DISIinstruc-
tion for four cycles is sufficient to prevent interrupts
from disrupting Deep Sleep entry.
asm("pwrsav #0");
//
// Case 3: interrupts disabled with
// interrupt testing
//
asm("disi #4");
asm("bset DSCON, #15");
asm("nop");
asm("nop");
asm("btss INTTREG, #15");
asm("pwrsav #0");
// continue with application code here
//
In the third scenario, interrupts cannot be ignored even
briefly; constant interrupt detection is required, even
during the interval between setting DSEN and
executing the PWRSAVinstruction. For these cases, it is
possible to disable interrupts and test for an interrupt
condition, skipping the PWRSAVinstruction if necessary.
Testing for interrupts can be accomplished by checking
the status of the CPUIRQ bit (INTTREG<15>). If an
unserviced interrupt is pending, this bit will be set. If
CPUIRQ is set prior to executing the PWRSAVinstruc-
tion, the instruction is skipped. At this point, the DISI
instruction has expired (being more than 4 instructions
from when it was executed) and the application vectors
to the appropriate ISR. When the application returns, it
can either attempt to re-enter Deep Sleep mode or per-
form some other system function. In either case, the
application must have some functional code located,
following the PWRSAVinstruction, in the event that the
PWRSAVinstruction is skipped and the device does not
enter Deep Sleep mode.
2010 Microchip Technology Inc.
DS39951C-page 113