Nuvoton
/
NuMaker-mbed-tickless-example
NuMaker tickless example
wakeup_rtc.cpp
- Committer:
- ccli8
- Date:
- 2018-04-13
- Revision:
- 11:0c4b39c54af2
- Parent:
- 10:d2e2c79389e1
- Child:
- 12:b0d19e915d96
File content as of revision 11:0c4b39c54af2:
#include "mbed.h" #include "wakeup.h" #include "rtc_api.h" #include "mbed_mktime.h" #define YEAR0 1900 static Semaphore sem_rtc(0, 1); static void rtc_loop(void); static void schedule_rtc_alarm(uint32_t secs); #if defined(TARGET_NUMAKER_PFM_NANO130) /* This target doesn't support relocating vector table and requires overriding * vector handler at link-time. */ extern "C" void RTC_IRQHandler(void) #else void RTC_IRQHandler(void) #endif { /* Check if RTC alarm interrupt has occurred */ #if defined(TARGET_NUMAKER_PFM_NANO130) if (RTC->RIIR & RTC_RIIR_AIF_Msk) { /* Clear RTC alarm interrupt flag */ RTC->RIIR = RTC_RIIR_AIF_Msk; wakeup_eventflags.set(EventFlag_Wakeup_RTC_Alarm); } #elif defined(TARGET_NUMAKER_PFM_NUC472) if (RTC->INTSTS & RTC_INTSTS_ALMIF_Msk) { /* Clear RTC alarm interrupt flag */ RTC->INTSTS = RTC_INTSTS_ALMIF_Msk; wakeup_eventflags.set(EventFlag_Wakeup_RTC_Alarm); } #else if (RTC_GET_ALARM_INT_FLAG()) { /* Clear RTC alarm interrupt flag */ RTC_CLEAR_ALARM_INT_FLAG(); wakeup_eventflags.set(EventFlag_Wakeup_RTC_Alarm); } #endif /* Wake up RTC loop to schedule another RTC alarm */ sem_rtc.release(); } void config_rtc_wakeup(void) { static Thread thread_rtc(osPriorityNormal, 2048); Callback<void()> callback(&rtc_loop); thread_rtc.start(callback); } void rtc_loop(void) { /* Schedule RTC alarm in 3 secs */ schedule_rtc_alarm(3); while (true) { int32_t sem_tokens = sem_rtc.wait(osWaitForever); if (sem_tokens < 1) { printf("RTC Alarm fails with Semaphore.wait(): %d\n", sem_tokens); } else { /* Re-schedule RTC alarm in 3 secs */ schedule_rtc_alarm(3); } } } void schedule_rtc_alarm(uint32_t secs) { /* time() will call set_time(0) internally to set timestamp if rtc is not yet enabled, where the 0 timestamp * corresponds to 00:00 hours, Jan 1, 1970 UTC. But Nuvoton mcu's rtc supports calendar since 2000 and 1970 * is not supported. For this test, a timestamp after 2000 is explicitly set. */ { static bool time_inited = false; if (! time_inited) { time_inited = true; #define CUSTOM_TIME 1256729737 set_time(CUSTOM_TIME); // Set RTC time to Wed, 28 Oct 2009 11:35:37 } } #if defined(TARGET_NUMAKER_PFM_NANO130) RTC_DisableInt(RTC_RIER_AIER_Msk); #else RTC_DisableInt(RTC_INTEN_ALMIEN_Msk); #endif time_t t = time(NULL); t += secs; // Schedule RTC alarm after secs // Convert timestamp to struct tm struct tm timeinfo; if (_rtc_localtime(t, &timeinfo, RTC_FULL_LEAP_YEAR_SUPPORT) == false) { printf("config_rtc_alarm() fails\n"); return; } S_RTC_TIME_DATA_T rtc_datetime; // Convert struct tm to S_RTC_TIME_DATA_T rtc_datetime.u32Year = timeinfo.tm_year + YEAR0; rtc_datetime.u32Month = timeinfo.tm_mon + 1; rtc_datetime.u32Day = timeinfo.tm_mday; rtc_datetime.u32DayOfWeek = timeinfo.tm_wday; rtc_datetime.u32Hour = timeinfo.tm_hour; rtc_datetime.u32Minute = timeinfo.tm_min; rtc_datetime.u32Second = timeinfo.tm_sec; rtc_datetime.u32TimeScale = RTC_CLOCK_24; RTC_SetAlarmDateAndTime(&rtc_datetime); /* NOTE: The Mbed RTC HAL implementation of Nuvoton's targets doesn't use interrupt, so we can override vector handler (via NVIC_SetVector). */ /* NOTE: The name of symbol PWRWU_IRQHandler is mangled in C++ and cannot override that in startup file in C. * So the NVIC_SetVector call cannot be left out. */ NVIC_SetVector(RTC_IRQn, (uint32_t) RTC_IRQHandler); NVIC_EnableIRQ(RTC_IRQn); /* Enable RTC alarm interrupt and wake-up function will be enabled also */ #if defined(TARGET_NUMAKER_PFM_NANO130) RTC_EnableInt(RTC_RIER_AIER_Msk); #else RTC_EnableInt(RTC_INTEN_ALMIEN_Msk); #endif }