sleep.c
Go to the documentation of this file.00001
00052
00053 #include "em_device.h"
00054 #include "em_assert.h"
00055 #include "em_int.h"
00056 #include "em_rmu.h"
00057 #include "em_emu.h"
00058
00059
00060 #include "sleep.h"
00061
00062
00063 #include <stdlib.h>
00064
00065
00070
00084
00085
00086
00087
00090
00091
00092 #define SLEEP_NUMOF_LOW_ENERGY_MODES 3U
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111 static SLEEP_CbFuncPtr_t sleepCallback = NULL;
00112 static SLEEP_CbFuncPtr_t wakeUpCallback = NULL;
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122 static uint8_t sleepBlockCnt[SLEEP_NUMOF_LOW_ENERGY_MODES];
00123
00124
00125
00126
00127
00128 static void SLEEP_EnterEMx(SLEEP_EnergyMode_t eMode);
00129 static SLEEP_EnergyMode_t SLEEP_LowestEnergyModeGet(void);
00130
00133
00134
00135
00136
00137
00156 void SLEEP_Init(SLEEP_CbFuncPtr_t pSleepCb, SLEEP_CbFuncPtr_t pWakeUpCb)
00157 {
00158
00159 sleepCallback = pSleepCb;
00160 wakeUpCallback = pWakeUpCb;
00161
00162
00163 sleepBlockCnt[0U] = 0U;
00164 sleepBlockCnt[1U] = 0U;
00165 sleepBlockCnt[2U] = 0U;
00166
00167 #if (SLEEP_EM4_WAKEUP_CALLBACK_ENABLED == true) && defined(RMU_RSTCAUSE_EM4WURST)
00168
00169 if (RMU_ResetCauseGet() & RMU_RSTCAUSE_EM4WURST)
00170 {
00171
00172 RMU_ResetCauseClear();
00173
00174 if (NULL != wakeUpCallback)
00175 {
00176 wakeUpCallback(sleepEM4);
00177 }
00178 }
00179 #endif
00180 }
00181
00182
00183
00202 SLEEP_EnergyMode_t SLEEP_Sleep(void)
00203 {
00204 SLEEP_EnergyMode_t allowedEM;
00205
00206 INT_Disable();
00207
00208 allowedEM = SLEEP_LowestEnergyModeGet();
00209
00210 if ((allowedEM >= sleepEM1) && (allowedEM <= sleepEM3))
00211 {
00212 SLEEP_EnterEMx(allowedEM);
00213 }
00214 else
00215 {
00216 allowedEM = sleepEM0;
00217 }
00218
00219 INT_Enable();
00220
00221 return(allowedEM);
00222 }
00223
00224
00225
00238 void SLEEP_ForceSleepInEM4(void)
00239 {
00240 #if (SLEEP_HW_LOW_ENERGY_BLOCK_ENABLED == true)
00241
00242 EMU_EM2UnBlock();
00243 #endif
00244
00245
00246 SLEEP_EnterEMx(sleepEM4);
00247 }
00248
00249
00274 void SLEEP_SleepBlockBegin(SLEEP_EnergyMode_t eMode)
00275 {
00276 EFM_ASSERT((eMode >= sleepEM1) && (eMode < sleepEM4));
00277 EFM_ASSERT((sleepBlockCnt[(uint8_t) eMode - 1U]) < 255U);
00278
00279
00280 sleepBlockCnt[(uint8_t) eMode - 1U]++;
00281
00282 #if (SLEEP_HW_LOW_ENERGY_BLOCK_ENABLED == true)
00283
00284 if (eMode == sleepEM2)
00285 {
00286 EMU_EM2Block();
00287 }
00288 #endif
00289 }
00290
00291
00318 void SLEEP_SleepBlockEnd(SLEEP_EnergyMode_t eMode)
00319 {
00320 EFM_ASSERT((eMode >= sleepEM1) && (eMode < sleepEM4));
00321
00322
00323 if (sleepBlockCnt[(uint8_t) eMode - 1U] > 0U)
00324 {
00325 sleepBlockCnt[(uint8_t) eMode - 1U]--;
00326 }
00327
00328 #if (SLEEP_HW_LOW_ENERGY_BLOCK_ENABLED == true)
00329
00330 if (0U == sleepBlockCnt[(uint8_t) sleepEM2 - 1U])
00331 {
00332 EMU_EM2UnBlock();
00333 }
00334 #endif
00335 }
00336
00339
00354 static SLEEP_EnergyMode_t SLEEP_LowestEnergyModeGet(void)
00355 {
00356 SLEEP_EnergyMode_t tmpLowestEM = sleepEM0;
00357
00358
00359 if (0U == sleepBlockCnt[(uint8_t) sleepEM1 - 1U])
00360 {
00361 tmpLowestEM = sleepEM1;
00362 if (0U == sleepBlockCnt[(uint8_t) sleepEM2 - 1U])
00363 {
00364 tmpLowestEM = sleepEM2;
00365 if (0U == sleepBlockCnt[(uint8_t) sleepEM3 - 1U])
00366 {
00367 tmpLowestEM = sleepEM3;
00368 }
00369 }
00370 }
00371
00372
00373 if (SLEEP_LOWEST_ENERGY_MODE_DEFAULT < tmpLowestEM)
00374 {
00375 tmpLowestEM = SLEEP_LOWEST_ENERGY_MODE_DEFAULT;
00376 }
00377
00378 return tmpLowestEM;
00379 }
00380
00381
00382
00398 static void SLEEP_EnterEMx(SLEEP_EnergyMode_t eMode)
00399 {
00400 EFM_ASSERT((eMode > sleepEM0) && (eMode <= sleepEM4));
00401
00402
00403 if (NULL != sleepCallback)
00404 {
00405
00406 sleepCallback(eMode);
00407 }
00408
00409
00410 switch (eMode)
00411 {
00412 case sleepEM1:
00413 {
00414 EMU_EnterEM1();
00415 } break;
00416
00417 case sleepEM2:
00418 {
00419 EMU_EnterEM2(true);
00420 } break;
00421
00422 case sleepEM3:
00423 {
00424 EMU_EnterEM3(true);
00425 } break;
00426
00427 case sleepEM4:
00428 {
00429 EMU_EnterEM4();
00430 } break;
00431
00432 default:
00433 {
00434
00435 } break;
00436 }
00437
00438
00439 if (NULL != wakeUpCallback)
00440 {
00441 wakeUpCallback(eMode);
00442 }
00443 }