/***************************************************************************//** * @brief * Initialize the Sleep module. * * @details * Use this function to initialize the Sleep module, should be called * only once! Pointers to sleep and wake-up callback functions shall be * provided when calling this function. * If SLEEP_EM4_WAKEUP_CALLBACK_ENABLED is set to true, this function checks * for the cause of the reset that implicitly called it and calls the wakeup * callback if the reset was a wakeup from EM4 (does not work on Gecko MCU). * * @param[in] pSleepCb * Pointer to the callback function that is being called before the device is * going to sleep. * * @param[in] pWakeUpCb * Pointer to the callback function that is being called after wake up. ******************************************************************************/ void SLEEP_Init(SLEEP_CbFuncPtr_t pSleepCb, SLEEP_CbFuncPtr_t pWakeUpCb) { /* Initialize callback functions. */ sleepCallback = pSleepCb; wakeUpCallback = pWakeUpCb; /* Reset sleep block counters. Note: not using for() saves code! */ sleepBlockCnt[0U] = 0U; sleepBlockCnt[1U] = 0U; #if (SLEEP_EM4_WAKEUP_CALLBACK_ENABLED == true) \ && (defined(RMU_RSTCAUSE_EM4WURST) || defined(RMU_RSTCAUSE_EM4RST)) /* Check if the Init() happened after an EM4 reset. */ #if defined(RMU_RSTCAUSE_EM4WURST) if (RMU_ResetCauseGet() & RMU_RSTCAUSE_EM4WURST) #elif defined(RMU_RSTCAUSE_EM4RST) if (RMU_ResetCauseGet() & RMU_RSTCAUSE_EM4RST) #endif { /* Clear the cause of the reset. */ RMU_ResetCauseClear(); /* Call wakeup callback with EM4 parameter. */ if (NULL != wakeUpCallback) { wakeUpCallback(sleepEM4); } } #endif }
/******************************************************************//** * @brief * Initialize all RTC module related hardware and register RTC device to kernel * * @details * * @note *********************************************************************/ void rt_hw_rtc_init(void) { rt_uint32_t reset; reset = RMU_ResetCauseGet(); // TODO: What is the current reset mode? if (reset & RMU_RSTCAUSE_PORST || reset & RMU_RSTCAUSE_EXTRST) { RTC_Init_TypeDef rtcInit; efm32_irq_hook_init_t hook; rtcInit.enable = true; rtcInit.debugRun = false; rtcInit.comp0Top = false; rtc_time = 0UL; rt_kprintf("rtc is not configured\n"); rt_kprintf("please configure with set_date and set_time\n"); /* Configuring clocks in the Clock Management Unit (CMU) */ startLfxoForRtc(); /* Initialize and enable RTC */ RTC_Init(&rtcInit); hook.type = efm32_irq_type_rtc; hook.unit = 0; hook.cbFunc = rt_hw_rtc_isr; hook.userPtr = RT_NULL; efm32_irq_hook_register(&hook); /* Enabling Interrupt from RTC */ RTC_IntEnable(RTC_IFC_OF); RTC_IntClear(RTC_IFC_OF); NVIC_ClearPendingIRQ(RTC_IRQn); NVIC_SetPriority(RTC_IRQn, EFM32_IRQ_PRI_DEFAULT); NVIC_EnableIRQ(RTC_IRQn); } /* register rtc device */ rt_hw_rtc_register(&rtc, RT_RTC_NAME, EFM32_NO_DATA); }
void halInternalClassifyReset(void) { // Table used to convert from RESET_EVENT register bits to reset types static const uint16_t resetEventTable[] = { #ifdef _EZR_DEVICE RESET_POWERON_HV, // bit 0: PORST RESET_BROWNOUT_UNREGPOWER, // bit 1: BODUNREGRST RESET_BROWNOUT_REGPOWER, // bit 2: BODREGRST RESET_EXTERNAL_PIN, // bit 3: EXTRST RESET_WATCHDOG_EXPIRED, // bit 4: WDOGRST RESET_FATAL_LOCKUP, // bit 5: LOCKUPRST RESET_SOFTWARE, // bit 6: SYSREQRST RESET_SOFTWARE_EM4, // bit 7: EM4RST RESET_EXTERNAL_EM4PIN, // bit 8: EM4WURST RESET_BROWNOUT_AVDD0, // bit 9: BODAVDD0 RESET_BROWNOUT_AVDD1, // bit 10: BODAVDD1 RESET_BROWNOUT_BACKUP_VDD_DREG, // bit 11: BUBODVDDDREG RESET_BROWNOUT_BACKUP_BU_VIN, // bit 12: BUBODBUVIN RESET_BROWNOUT_BACKUP_UNREGPOWER, // bit 13: BUBODUNREG RESET_BROWNOUT_BACKUP_REGPOWER, // bit 14: BUBODREG RESET_BROWNOUT_BACKUP_MODE, // bit 15: BUMODERST #elif defined _EFR_DEVICE RESET_POWERON_HV, // bit 0: PORST RESET_UNKNOWN_UNKNOWN, // bit 1: RESERVED RESET_BROWNOUT_AVDD, // bit 2: AVDDBOD RESET_BROWNOUT_DVDD, // bit 3: DVDDBOD RESET_BROWNOUT_DEC, // bit 4: DECBOD RESET_UNKNOWN_UNKNOWN, // bit 5: RESERVED RESET_UNKNOWN_UNKNOWN, // bit 6: RESERVED RESET_UNKNOWN_UNKNOWN, // bit 7: RESERVED RESET_EXTERNAL_PIN, // bit 8: EXTRST RESET_FATAL_LOCKUP, // bit 9: LOCKUPRST RESET_SOFTWARE, // bit 10: SYSREQRST RESET_WATCHDOG_EXPIRED, // bit 11: WDOGRST RESET_UNKNOWN_UNKNOWN, // bit 12: RESERVED RESET_UNKNOWN_UNKNOWN, // bit 13: RESERVED RESET_UNKNOWN_UNKNOWN, // bit 14: RESERVED RESET_UNKNOWN_UNKNOWN, // bit 15: RESERVED RESET_SOFTWARE_EM4, // bit 16: EM4RST #endif }; uint32_t resetEvent = RMU_ResetCauseGet(); RMU_ResetCauseClear(); uint16_t cause = RESET_UNKNOWN; uint16_t i; for (i = 0; i < sizeof(resetEventTable)/sizeof(resetEventTable[0]); i++) { if (resetEvent & (1 << i)) { cause = resetEventTable[i]; break; } } if (cause == RESET_SOFTWARE) { if((halResetInfo.crash.resetSignature == RESET_VALID_SIGNATURE) && (RESET_BASE_TYPE(halResetInfo.crash.resetReason) < NUM_RESET_BASE_TYPES)) { // The extended reset cause is recovered from RAM // This can be trusted because the hardware reset event was software // and additionally because the signature is valid savedResetCause = halResetInfo.crash.resetReason; } else { savedResetCause = RESET_SOFTWARE_UNKNOWN; } // mark the signature as invalid halResetInfo.crash.resetSignature = RESET_INVALID_SIGNATURE; } else if ( (cause == RESET_BOOTLOADER_DEEPSLEEP) && (halResetInfo.crash.resetSignature == RESET_VALID_SIGNATURE) && (halResetInfo.crash.resetReason == RESET_BOOTLOADER_DEEPSLEEP)) { // Save the crash info for bootloader deep sleep (even though it's not used // yet) and invalidate the resetSignature. halResetInfo.crash.resetSignature = RESET_INVALID_SIGNATURE; savedResetCause = halResetInfo.crash.resetReason; } else { savedResetCause = cause; } // If the last reset was due to an assert, save the assert info. if (savedResetCause == RESET_CRASH_ASSERT) { savedAssertInfo = halResetInfo.crash.data.assertInfo; } }