sleep.c
Go to the documentation of this file.00001
00033
00034 #include "em_device.h"
00035 #include "em_assert.h"
00036 #include "em_int.h"
00037 #include "em_rmu.h"
00038 #include "em_emu.h"
00039
00040
00041 #include "sleep.h"
00042
00043
00044 #include <stdlib.h>
00045
00046
00051
00065
00066
00067
00068
00071
00072
00073 #define SLEEP_NUMOF_LOW_ENERGY_MODES 3U
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092 static SLEEP_CbFuncPtr_t sleepCallback = NULL;
00093 static SLEEP_CbFuncPtr_t wakeUpCallback = NULL;
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103 static uint8_t sleepBlockCnt[SLEEP_NUMOF_LOW_ENERGY_MODES];
00104
00105
00106
00107
00108
00109 static void SLEEP_EnterEMx(SLEEP_EnergyMode_t eMode);
00110
00111
00114
00115
00116
00117
00118
00137 void SLEEP_Init(SLEEP_CbFuncPtr_t pSleepCb, SLEEP_CbFuncPtr_t pWakeUpCb)
00138 {
00139
00140 sleepCallback = pSleepCb;
00141 wakeUpCallback = pWakeUpCb;
00142
00143
00144 sleepBlockCnt[0U] = 0U;
00145 sleepBlockCnt[1U] = 0U;
00146 sleepBlockCnt[2U] = 0U;
00147
00148 #if (SLEEP_EM4_WAKEUP_CALLBACK_ENABLED == true) && defined(RMU_RSTCAUSE_EM4WURST)
00149
00150 if (RMU_ResetCauseGet() & RMU_RSTCAUSE_EM4WURST)
00151 {
00152
00153 RMU_ResetCauseClear();
00154
00155 if (NULL != wakeUpCallback)
00156 {
00157 wakeUpCallback(sleepEM4);
00158 }
00159 }
00160 #endif
00161 }
00162
00163
00164
00183 SLEEP_EnergyMode_t SLEEP_Sleep(void)
00184 {
00185 SLEEP_EnergyMode_t allowedEM;
00186
00187 INT_Disable();
00188
00189 allowedEM = SLEEP_LowestEnergyModeGet();
00190
00191 if ((allowedEM >= sleepEM1) && (allowedEM <= sleepEM3))
00192 {
00193 SLEEP_EnterEMx(allowedEM);
00194 }
00195 else
00196 {
00197 allowedEM = sleepEM0;
00198 }
00199
00200 INT_Enable();
00201
00202 return(allowedEM);
00203 }
00204
00205
00206
00219 void SLEEP_ForceSleepInEM4(void)
00220 {
00221 #if (SLEEP_HW_LOW_ENERGY_BLOCK_ENABLED == true)
00222
00223 EMU_EM2UnBlock();
00224 #endif
00225
00226
00227 SLEEP_EnterEMx(sleepEM4);
00228 }
00229
00230
00255 void SLEEP_SleepBlockBegin(SLEEP_EnergyMode_t eMode)
00256 {
00257 EFM_ASSERT((eMode >= sleepEM1) && (eMode < sleepEM4));
00258 EFM_ASSERT((sleepBlockCnt[(uint8_t) eMode - 1U]) < 255U);
00259
00260
00261 sleepBlockCnt[(uint8_t) eMode - 1U]++;
00262
00263 #if (SLEEP_HW_LOW_ENERGY_BLOCK_ENABLED == true)
00264
00265 if (eMode == sleepEM2)
00266 {
00267 EMU_EM2Block();
00268 }
00269 #endif
00270 }
00271
00272
00299 void SLEEP_SleepBlockEnd(SLEEP_EnergyMode_t eMode)
00300 {
00301 EFM_ASSERT((eMode >= sleepEM1) && (eMode < sleepEM4));
00302
00303
00304 if (sleepBlockCnt[(uint8_t) eMode - 1U] > 0U)
00305 {
00306 sleepBlockCnt[(uint8_t) eMode - 1U]--;
00307 }
00308
00309 #if (SLEEP_HW_LOW_ENERGY_BLOCK_ENABLED == true)
00310
00311 if (0U == sleepBlockCnt[(uint8_t) sleepEM2 - 1U])
00312 {
00313 EMU_EM2UnBlock();
00314 }
00315 #endif
00316 }
00317
00318
00333 SLEEP_EnergyMode_t SLEEP_LowestEnergyModeGet(void)
00334 {
00335 SLEEP_EnergyMode_t tmpLowestEM = sleepEM0;
00336
00337
00338 if (0U == sleepBlockCnt[(uint8_t) sleepEM1 - 1U])
00339 {
00340 tmpLowestEM = sleepEM1;
00341 if (0U == sleepBlockCnt[(uint8_t) sleepEM2 - 1U])
00342 {
00343 tmpLowestEM = sleepEM2;
00344 if (0U == sleepBlockCnt[(uint8_t) sleepEM3 - 1U])
00345 {
00346 tmpLowestEM = sleepEM3;
00347 }
00348 }
00349 }
00350
00351
00352 if (SLEEP_LOWEST_ENERGY_MODE_DEFAULT < tmpLowestEM)
00353 {
00354 tmpLowestEM = SLEEP_LOWEST_ENERGY_MODE_DEFAULT;
00355 }
00356
00357 return tmpLowestEM;
00358 }
00359
00362
00378 static void SLEEP_EnterEMx(SLEEP_EnergyMode_t eMode)
00379 {
00380 EFM_ASSERT((eMode > sleepEM0) && (eMode <= sleepEM4));
00381
00382
00383 if (NULL != sleepCallback)
00384 {
00385
00386 sleepCallback(eMode);
00387 }
00388
00389
00390 switch (eMode)
00391 {
00392 case sleepEM1:
00393 {
00394 EMU_EnterEM1();
00395 } break;
00396
00397 case sleepEM2:
00398 {
00399 EMU_EnterEM2(true);
00400 } break;
00401
00402 case sleepEM3:
00403 {
00404 EMU_EnterEM3(true);
00405 } break;
00406
00407 case sleepEM4:
00408 {
00409 EMU_EnterEM4();
00410 } break;
00411
00412 default:
00413 {
00414
00415 } break;
00416 }
00417
00418
00419 if (NULL != wakeUpCallback)
00420 {
00421 wakeUpCallback(eMode);
00422 }
00423 }