XMEGA Application Note | |||||
#include <stdint.h>
#include "avr_compiler.h"
#include "sleepmgr.h"
#include "config_sleepmgr.h"
Go to the source code of this file.
Functions | |
void | SLEEPMGR_CancelSleep (void) |
Cancel pending sleep attempt, e.g. when work is added from a device driver. | |
void | SLEEPMGR_Init (void) |
Initialize sleep manager. Call this before any other manager function. | |
void | SLEEPMGR_Lock (SLEEPMGR_mode_t mode) |
Increase lock for a mode, i.e. you need at least this awareness. | |
void | SLEEPMGR_Sleep (void) |
Enter the deepest possible sleep mode possible with current lock state. | |
void | SLEEPMGR_Unlock (SLEEPMGR_mode_t mode) |
Decrease lock for a mode, i.e. you no longer need this awareness. | |
Variables | |
SLEEPMGR_DEFINE_MODES | |
SLEEPMGR_lock_t | SLEEPMGR_locks [SLEEPMGR_NUM_MODES] |
Sleep mode lock counters. |
This file contains the function implementations of the sleep manager.
Copyright (c) 2008, Atmel Corporation All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
3. The name of ATMEL may not be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Definition in file sleepmgr.c.
void SLEEPMGR_CancelSleep | ( | void | ) |
Cancel pending sleep attempt, e.g. when work is added from a device driver.
This function cancels a sleep attempt, if called from a handler that interrupted the SLEEPMGR_Sleep() function. This function has no effect if called from elsewhere. It is intended to be called from interrupt domain whenever an interrupt causes more work, which means that sleeping is not ok. Normally, this function will be called from within WORKQUEUE_AddWork() and SOFTIRQ_Raise(), which in turn are called from device driver ISRs.
Definition at line 196 of file sleepmgr.c.
References SLEEPMGR_DISABLE_SLEEP.
00197 { 00198 // Disable sleep, so that any SLEEP instruction will fail. 00199 SLEEPMGR_DISABLE_SLEEP(); 00200 }
void SLEEPMGR_Init | ( | void | ) |
Initialize sleep manager. Call this before any other manager function.
This function initializes the sleep manager. The sleep manager must be initialized before any other modules can use it.
Definition at line 74 of file sleepmgr.c.
References SLEEPMGR_locks, and SLEEPMGR_NUM_MODES.
Referenced by ISR(), and main().
00075 { 00076 // Set all mode locks to zero, except the last one, which is handled below. 00077 for (uint8_t index = 0; index < (SLEEPMGR_NUM_MODES - 1); ++index) { 00078 SLEEPMGR_locks[index] = 0; 00079 } 00080 00081 // Lock the deepest sleep mode once and for all, to ease the search 00082 // implementation in SLEEPMGR_Sleep() later. 00083 SLEEPMGR_locks[SLEEPMGR_NUM_MODES - 1] = 1; 00084 }
void SLEEPMGR_Lock | ( | SLEEPMGR_mode_t | mode | ) |
Increase lock for a mode, i.e. you need at least this awareness.
This function increases the lock count for one particular sleep mode. This essentially tells the sleep manager that it should not enter deeper sleep modes than that.
It is ok to lock several modes from one module, and locking and unlocking need not be done in any particular order. However, it is important to unlock all modes previously locked.
If you want to change your requirements to a deeper sleep mode, it is not sufficient to just lock the deeper mode. You also need to unlock the shallower mode.
mode | The sleep mode to lock. |
Definition at line 102 of file sleepmgr.c.
References ENTER_CRITICAL_REGION, LEAVE_CRITICAL_REGION, and SLEEPMGR_locks.
Referenced by ISR(), and main().
00103 { 00104 // The following must be an atomic operation, to avoid race conditions. 00105 ENTER_CRITICAL_REGION(); 00106 00107 // Check that lock has not reached max value for its datatype. 00108 // By casting "-1L" to the correct datatype, we always get max value. 00109 // assert( SLEEPMGR_locks[mode] != (SLEEPMGR_mode_t) -1L ); 00110 // Now it's safe to increase the lock counter. 00111 ++SLEEPMGR_locks[mode]; 00112 00113 LEAVE_CRITICAL_REGION(); 00114 }
void SLEEPMGR_Sleep | ( | void | ) |
Enter the deepest possible sleep mode possible with current lock state.
This function computes the deepest sleep mode possible and enters that. If interrupt handlers want to cancel the sleep attempt, it can only be canceled by called SLEEPMGR_CancelSleep().
Definition at line 152 of file sleepmgr.c.
References SLEEPMGR_DISABLE_SLEEP, SLEEPMGR_locks, and SLEEPMGR_PREPARE_SLEEP.
Referenced by main().
00153 { 00154 // The following must be an atomic operation, to avoid race conditions. 00155 // No need to save the interrupt state, as we must enable global interrupts 00156 // anyway to be able to wake up from sleep. 00157 cli(); 00158 00159 // Make sure the deepest sleep mode is actually locked, which should have 00160 // been done in SLEEPMGR_Init at least. This ensures that the search 00161 // below will succeed. 00162 // assert( SLEEPMGR_locks[SLEEPMGR_NUM_MODES - 1] > 0 ); 00163 00164 // Search from shallowest sleep mode until a non-zero lock is found. 00165 SLEEPMGR_lock_t const * lockPtr = SLEEPMGR_locks; 00166 uint8_t PROGMEM_PTR_T modePtr = SLEEPMGR_modes; 00167 while (*lockPtr == 0) { 00168 ++lockPtr; 00169 ++modePtr; 00170 } 00171 00172 // Prepare sleep configuration, not touching other fields in register. 00173 uint8_t modeConfig = PROGMEM_READ_BYTE( modePtr ); 00174 SLEEPMGR_PREPARE_SLEEP( modeConfig ); 00175 00176 // Enable interrupts before sleeping, otherwise we won't wake up. 00177 sei(); 00178 00179 // Now, enter sleep mode. Any pending interrupts will cause the device 00180 // to instantaneously wake up. 00181 cpu_sleep(); 00182 00183 // After waking up, we disable sleep. 00184 SLEEPMGR_DISABLE_SLEEP(); 00185 }
void SLEEPMGR_Unlock | ( | SLEEPMGR_mode_t | mode | ) |
Decrease lock for a mode, i.e. you no longer need this awareness.
This function decreases the lock count for one particular sleep mode. This essentially tells the sleep manager that you are ok with deeper sleep modes, as long as no more locks exist on this or shallower sleep modes.
It is ok to lock several modes from one module, and locking and unlocking need not be done in any particular order. However, it is important to unlock all modes previously locked.
If you want to change your requirements to a deeper sleep mode, it is not sufficient to just lock the deeper mode. You also need to unlock the shallower mode.
mode | The sleep mode to unlock. |
Definition at line 132 of file sleepmgr.c.
References ENTER_CRITICAL_REGION, LEAVE_CRITICAL_REGION, and SLEEPMGR_locks.
Referenced by ISR().
00133 { 00134 // The following must be an atomic operation, to avoid race conditions. 00135 ENTER_CRITICAL_REGION(); 00136 00137 // Check that lock is not already zero, 00138 // which would mean lock/unlock has not been handle correctly. 00139 // assert( SLEEPMGR_locks[mode] != 0 ); 00140 // Now it's safe to decrease the lock counter. 00141 --SLEEPMGR_locks[mode]; 00142 00143 LEAVE_CRITICAL_REGION(); 00144 }
Definition at line 62 of file sleepmgr.c.
SLEEPMGR_lock_t SLEEPMGR_locks[SLEEPMGR_NUM_MODES] |
Sleep mode lock counters.
Definition at line 64 of file sleepmgr.c.
Referenced by SLEEPMGR_Init(), SLEEPMGR_Lock(), SLEEPMGR_Sleep(), and SLEEPMGR_Unlock().
Generated on Mon Nov 9 13:44:35 2009 for XMEGA power consumption evaluation code by ![]() |