µTasker Low-Leakage Wakeup (LLWU) Support
Many Kinetis derivatives include the LLWU to allow the processor to exit from one of it low power modes by either an external event (pin state change) or a supported peripheral that is either still operational or has an asynchronous event function in its own low power state. The unit is itself very low power and so enhances the overall low power capability of the devices.
The low-leakage power modes of the Kinetis processor allow the device to remain powered but draw very little current to remain in this state and hold various internal memory and register values. In order to achieve this low current consumption most, or all, clocks are disabled and many parts of the device are placed into a static state which means that they may retain state information but are not further operational until the low-leakage state is exited. An example of such operation may be a device that has an internal real-time-clock (RTC) set to wake it at a certain time and date and until then the device (probably battery operated) can be set to a sleeping mode so that it allows the RTC to operate, retains configuration information and performs the task when needed by switching back to an operational (RUN) mode. Such a device may also need to react to user input to change the details of what it does when woken and to change the time/date of the action.
In such cases the unit requires the low power mode to reserve as much battery power as possible and allow long periods of operation, but also wake in a manner to allow intermediate manipulation, before returing to the low power state, as well as to complete the programmed task.
The low leakage state of the Kinetis processors is named LLS. There are however different variations (some device family specific) such as VLLS0 (very low leakage state 0), VLLS1 (very low leakage state 1), VLLS2 (very low leakage state 2), VLLS3 (very low leakage state 3). In LLS, unmasked LLWU events can wake the processor so that it can return to the RUN mode of opertion. In VLLS modes, unmasked LLWU events can wake the processor but it causes recovery via a reset of the processor. Some types trigger a "Chip Reset" and some types trigger a "VLLS reset", whereby the configuration of the LLWU is retained through by VLLS resets.
Enabled NMI or RESET pins also cause wakeups from low-leakage power modes.
The LLWU is not ative in all operational modes apart from allowing its configuration to be programmed. When the processor is set to a low leakage mode the unit is then automatically activated so that it can perform its intended function.
Wakeup Input Pins
The LLWU enables a number of pins (named LLWU_Px) to be programmed as wakeup sources when they change for '1' to '0', '0' to '1' or on any change.
A limited number of selected external pins used as LLWU input sources are optionally filtered by the LPO (interal 1kHz low power clock) as long as the LPO remains operational in the particular low-leakage mode selected. When filtering is enabled the wakeup input pin must remain stable in the new state for 3 LPO cycles (3ms) in order to set the corresponding wakeup flag. There is an additional 2 clock synchronisation delay before the wakeup event causes the processor to exit from the low-leakage power mode. In case the LPO is disabled the filtering is bypassed, which is equivalent to having no filtering.
The following shows how to configure two LLWU port interrupts. It is assumed that the project defines SUPPORT_LOW_POWER and SUPPORT_LLWU are enabled so that the
µTasker scheduler manages moving between the low power states and for the LLWU driver to be included. The configuration interface uses the port interrupt
technique so that it is simple to configure either port interrupt or wakeup pin operation by simply changing the interrupt type between PORT_INTERRUPT and WAKEUP_INTERRUPT.
INTERRUPT_SETUP interrupt_setup; // interrupt configuration parameters interrupt_setup.int_handler = fnTemporaryWake; // handling function interrupt_setup.int_priority = PRIORITY_PORT_C_INT; // interrupt priority level interrupt_setup.int_port = PORTC; // the port that the interrupt input is on interrupt_setup.int_port_bits = PORTC_BIT6; // the IRQ input connected (SWITCH_2 on TWR_K24F120M) - this is LLWU_P10 interrupt_setup.int_port_sense = (IRQ_FALLING_EDGE | PULLUP_ON); // interrupt is to be falling edge sensitive interrupt_setup.int_type = WAKEUP_INTERRUPT; // configure as wake-up interrupt fnConfigureInterrupt((void *)&interrupt_setup); // configure interrupt interrupt_setup.int_handler = fnPermanentWake; // handling function interrupt_setup.int_port = PORTA; // the port that the interrupt input is on interrupt_setup.int_port_bits = PORTA_BIT13; // LLWU_P4 fnConfigureInterrupt((void *)&interrupt_setup); // configure interrupt
Multiple wakeup pins can be defined by setting multiple port bits in interrupt_setup.int_port_bits, such as (PORTA_BIT4 | PORTA_BIT13). The port pin or pins are then configured as LLWU inputs for the specified edge (pull-up/down settings can also be defined for the port pin, which is shared with the LLWU_Px mode*) and any of these pins then waking the processor results in the user handler function being executed from the wakeup interrupt. If ports are specified that don't have a LLWU mode there is no configuration to the pin performed - when working with the µTasker this will result in an exception to warn of the incorrect setting.
*Note that when pull-up/down is specified the port's characteristic is configured (including clocking if it was not yet clocked) but the port's multiplexing is not modified. This allows a LLWU input to be assigned to at a pin which is otherwise being used for a different function during RUN mode without disturbing this operation. When the low leakage power mode is entered the LLWU pin function is automatically enabled. When no pull-up/down is specified the port pin's characteristics are not configured and the port may be left in an unclocked state, if that is what it was in, since port clocking is not required for the LLWU functionality.
A further flag that can be used alongside the interrupt sensitivity setting is ENABLE_PORT_MODE. This sets the port pin's multiplexer to the GPIO position and can be important when the default state is a disabled or analogue function. If the LLWU input is not otherwise used for an alternative peripheral function it is advised to use this to ensure that the pull-up/down setting can operate and the LLWU function is correctly connected in the low leakage power state.
In the example above, two pins have been assigned to two individual interrupt handling routines and can be programmed to responds differently to the wakeup event, thus allowing simple reactions to be defined based on the exact wakeup source. One wakeup source may, for example, cause a task to be performed without changing the basic power mode and so, as soon as the scheduler determines that there are no further pending jobs to be completed, the system will automatically return to the LLS power mode again. Another wakeup source may cause the power mode to be adjusted (to RUN or WAIT) so that the system continues with full functionality.
Below the two such handlers are shown together with code that initially moves to the LLS power mode. It is to be noted that fnSetLowPowerMode() is a non-blocking call and the actual switch to the new mode is performed by the scheduler once it has ensured that there are no further events that must first be handled.
void fnSetLLS(void) { fnSetLowPowerMode(WAIT_MODE); // this is used to initiate the switch to the LLS mode fnDebugMsg("Switching to LLS power mode\r\n" // this debug message (non-blocking) will always be completely sent out before the scheduler commits the mode } static void fnTemporaryWake(void) // this interrupt handler is called when LLUW_P10 event occurs { fnDebugMsg("WOKEN - going to LSS again\r\n"); // once this message has been completed the scheduler will set the original LLS power mode again } static void fnPermanentWake(void) // this interrupt handler is called when LLUW_P4 event occurs { fnSetLowPowerMode(WAIT_MODE); // the power mode is changed to a fully functional one fnDebugMsg("WOKEN - restoring WAIT mode\r\n"); }
Finally it should be pointed out that moving to LLS mode causes most clocks to be stopped. When leaving the LLS mode due to a wakeup event the PLLs that may have been used previously will no longer be operational. The µTasker scheduler's low power interface handles details of re-reconfiguring these PLLs so that the wake up handlers are called with the same clock setting that were being used before the low-leakage power mode was moved to. Since PLLs need to re-lock, this time is a part of the overall LLS wakeup delay.
The LLWU inputs will also wake the Kinetis from VLLSx modes, which results in a reset rather than the user handler being called. See below for more information about the VLLSx modes.
Module Wakeup
The LLWU allows specific modules to act as wakeup sources. The modules supported are dependent on the particular implementation in the Kinetis part being used. As well as the module being enabled in the LLWU as a wakeup source, the particular module much be configured and operational, and its peripheral interrupt enabled.
Examples of wakeup module sources are the low power timer (LPTMR) which can be used in various low-leakage power modes, comparators and real time clock (RTC) alarm or seconds interrupts.
The interface for module wakeup follows the LLWU pin interface and also allows individual user interrupt callback handlers to be assigned to each wakeup module, or one to be assigned to multiple wakeup modules. Unlike the LLWU pin wakeup sources that are cleared in the LLWU module after the wakeup interrupt has ocurred, the wakeup module's request has to be cleared in the wakeup module itself; the LLWU interface handler takes care of clearing the wakeup interrupt source in the appropriate manner. In the case of a wakeup interrupt due to the low power timer (LPTRM) source that is also being used as the system TICK, the system TICK handler is called before the user interrupt call back.
The method of assigning the LPTRM as wakeup source is shown below, whereby the LPTMR itself is assumed to have already been configured for its general operation, including enabling its interrupt.
INTERRUPT_SETUP interrupt_setup; // interrupt configuration parameters interrupt_setup.int_priority = 3; // interrupt priority level interrupt_setup.int_handler = fnPermanentWake; // handling function interrupt_setup.int_port = PORT_MODULE; // the wakeup interrupt is from a module rather than an LLWU pin interrupt_setup.int_port_bits = MODULE_LPTMR0; // low power timer is the module interrupt_setup.int_type = WAKEUP_INTERRUPT; // configure as wake-up interrupt fnConfigureInterrupt((void *)&interrupt_setup); // configure interrupt
The effect of this configuration is that the Kinetis will wake from the LLS power mode when the module interrupt fires and the user interrupt callback be handled. In a VLLSx power mode the module's interrupt will cause a reset - see below for more information about the VLLSx modes.
VLLSx modes
Unlike LLS mode, where a wakeup causes the Kinetis to wakeup via a LLWU interrupt and return to the RUN mode, VLLSx modes can only wakeup via a reset. Depending again on the VLLSx mode used there could be peripherals and memory that have retained their previous content values and some of these are still isolated from the RUN mode after recovering via the reset. Each time the system starts/restarts the content of the reset controller's status is inspected to see whether its LLWU source flag is set, which indicates that the wakeup was due to a LLWU source. The isolated peripherals and I/Os are then acknowledged in the power management controller so that they are released back to their RUN modes.
The state of the LLWU itself is retained, which means that the interrupt flag corresponding to the wakeup source is still pending. This can be used to make program flow decisions after the reset if required. The flags are reset before re-enabling LLWU interrupt sources to avoid them from immediatly causing the LWU interrupt handler to be called.
Testing Low Power Mode and Wakeup Sources
The µTasker project allows low power modes to be controlled via its command line menu (in the "Administrator" sub-menu) or by user code. When low power support is enabled the processor will be set to the low power mode whenever there are no task operations that need to be executed. Usually the WAIT mode is used as default since it allows unrestricted operation but useful power savings in typical projects (often 50%..75% power consumption reduction is observed compared to always remaining in the the RUN state.
The present low power mode of operation is displayed with the command "show_lp" (example of a KL part that doesn't support VLLS1 mode):
#show_lp
0 = RUN
1 = WAIT [active]
2 = STOP
3 = VLPR
4 = VLPS
5 = LLS
6 = VLLS0
7 = VLLS1
8 = VLLS3
and a different operating mode set using "set_lp 2" (example to set STOP mode) or "set_lp 5" (for LLS mode).
Depending on the exact new mode set, the processor may be able to continue responding to all inputs (such as in RUN, WAIT, often in STOP and partly in VLPS) but will require a programmed wakeup source, NMI or reset to be able to exit the low-leakage modes. See the binaries on the individual board support pages for software allowing the low power modes to be controlled, whereby some have also LLWU inputs configured which allow temporarily waking or to restore the WAIT mode as discussed in the wake-up input section.
For the possibly definitive insiders' details to the LLWU unit see the discussion from Philip B. Drake and his updated application note.
See various videos showing low power modes:
uTasker
SHORT FRDM-KL05Z Low Leakage STOP mode
uTasker SHORT FRDM-KL26Z Low Power
uTasker SHORT FRDM-K22F - VLPS and Low Power Cycle option
For specific questions and feedback please use the following forum entry: LLWU forum
µTasker Low-Leakage Wakeup Unit support. Copyright (c) 2004..2018 M.J.Butcher Consulting