IP2022 Data Sheet www.ubicom.com 15 3.4 Low Power Support Software can change the execution speed of the CPU to
reduce power consumption. A mechanism is provided for
automatically  changing  the  speed  on  entry  and  return
from the interrupt service routine. The speed instruction
specifies power-saving modes that include a clock divisor
between 1 and 128. This divisor only affects the clock to
the CPU core, not the timers or ADC (see Figure 3-16).
The  speed  instruction  also  specifies  the  clock  source
(OSC clock, RTCLK oscillator, or PLL clock multiplier) and
whether to disable the OSC clock oscillator or the PLL.
The next two instructions after switching the clock source
will be run at the old speed.
For maximum power savings when running from the OSC
clock, disable the RTCLK oscillator (RTOSCEN bit in the
XCFG  register),  the  watchdog  timer  (WDTE  bit  in  the
FUSE1  register),  the  A/D  converter  (ADCGO  bit  in  the
ADCCFG register, and the analog comparator (CMPEN
bit   in   the   CMPCFG   register).   Check   that   no   flash
operation is in progress (FBUSY bit in the XCFG register)
before executing a speed instruction.
The speed instruction executes using the current clock
divisor.   The   new   clock   divisor   takes   effect   with   the
following  instruction,  as   shown   in   the  following  code
example.
Before executing the speed instruction, check that the
FBUSY  bit  in  the  XCFG  register  is  clear  and  that  the
FCFG register has appropriate settings for the new clock
frequency.
The SPDREG register holds the current settings for the
clock   divisor,   clock   source,   and   disable   bits.   These
settings can be explicitly changed by executing a speed
instruction, and they change automatically on interrupts.
The SPDREG register is read-only, and its contents may
only be changed by executing a speed instruction, taking
an    interrupt,    or    returning    from    an    interrupt.    Two
consecutive  speed  instructions  are  not  allowed.  The
INTSPD   register   specifies   the   settings   used   during
execution  of  the  interrupt  service  routine.  The  INTSPD
register is both readable and writeable.
On return from interrupts, the reti instruction includes a
bit   that   specifies   whether   the   pre-interrupt   speed   is
restored or the current speed is maintained.
The actual speed of the CPU is indicated by the SPDREG
register unless the specified speed is faster than the flash
access  time  and  the  program  is  executing  out  of  flash.
When  program execution  moves from program RAM to
program flash memory, the new clock divisor will be the
greater  (slower)  of  the  clock  divisor  indicated  by  the
SPDREG register and the clock divisor required to avoid
violating  the  flash  memory  access  time.  The  SPDREG
register does not indicate if the flash clock divisor is being
used.   The   value   indicated   by   the   SPDREG   will   be
overridden  only  if  the  speed  is  too  fast  for  the  flash
memory.
The FCFG register holds bits that specify the minimum
number  of  system  clock  cycles  for  each  flash  memory
cycle (see Section 4.7.1).
3.4.1 Speed Change Delay The automatic speed changes require a certain amount of
delay to take effect:
Changing the Clock Divisor—there is no delay when
the clock divisor is changed.
Changing the Clock Source—the delay is up to one
cycle of the slower clock. For example, changing be-
tween 32 kHz and 100 MHz could require up to 31.25
microseconds.
Turning  on  the  OSC  Clock  Oscillator  (clearing  the
OSC bit in the SPDREG register)—the system clock
suspend time is specified in the WUDX2:0 bits in the
FUSE0 register.
Turning on the PLL Clock Multiplier (clearing the PLL
bit in the SPRDREG register)—the system clock sus-
pend  time  is  specified  in  the  WUDP2:0  bits  in  the
FUSE0 register.
If   both   the   OSC   oscillator   and   PLL   are   re-enabled
simultaneously,   the   delay   is   controlled   by   only   the
WUDX2:0   bits.   Bits  in   the   FUSE0   register   are   flash
memory   cells   which   cannot   be   changed   dynamically
during program execution.
nop ;assume divisor is 4, so this
;instruction takes 4 cycles
speed  #0x06 ;change the divisor to 8,
;instruction takes 4 cycles
nop ;instruction takes 8 cycles speed  #0x0D ;change the divisor to 1,
;instruction takes 8 cycles
nop ;instruction takes 1 cycle