Flotsam / Wakeup

Dependents:   Full-Project

Fork of WakeUp by Erik -

Committer:
Sissors
Date:
Wed Jul 23 19:54:52 2014 +0000
Revision:
7:bb411115f814
Added NUCLEO F030R8

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Sissors 7:bb411115f814 1 #ifdef TARGET_NUCLEO_F030R8
Sissors 7:bb411115f814 2
Sissors 7:bb411115f814 3 #include "WakeUp.h"
Sissors 7:bb411115f814 4 #include "rtc_api.h"
Sissors 7:bb411115f814 5 #include "stm32f0xx_rtc.h"
Sissors 7:bb411115f814 6
Sissors 7:bb411115f814 7 FunctionPointer WakeUp::callback;
Sissors 7:bb411115f814 8
Sissors 7:bb411115f814 9 void WakeUp::set_ms(uint32_t ms)
Sissors 7:bb411115f814 10 {
Sissors 7:bb411115f814 11 if (!rtc_isenabled()) //Make sure RTC is running
Sissors 7:bb411115f814 12 rtc_init();
Sissors 7:bb411115f814 13
Sissors 7:bb411115f814 14 //Alarm must be disabled to change anything
Sissors 7:bb411115f814 15 PWR_BackupAccessCmd(ENABLE);
Sissors 7:bb411115f814 16 RTC_AlarmCmd(RTC_Alarm_A, DISABLE);
Sissors 7:bb411115f814 17
Sissors 7:bb411115f814 18 if (ms == 0) { //Just disable alarm
Sissors 7:bb411115f814 19 PWR_BackupAccessCmd(DISABLE);
Sissors 7:bb411115f814 20 return;
Sissors 7:bb411115f814 21 }
Sissors 7:bb411115f814 22
Sissors 7:bb411115f814 23 //RTC prescaler + calculate how many sub-seconds should be added
Sissors 7:bb411115f814 24 uint32_t prescaler = (RTC->PRER & 0x7FFF) + 1;
Sissors 7:bb411115f814 25 uint32_t subsecsadd = ((ms % 1000) * prescaler) / 1000;
Sissors 7:bb411115f814 26
Sissors 7:bb411115f814 27 if ((ms < 1000) && (subsecsadd < 2))
Sissors 7:bb411115f814 28 subsecsadd = 2; //At least 2 subsecs delay to be sure interrupt is called
Sissors 7:bb411115f814 29
Sissors 7:bb411115f814 30 //Get current time
Sissors 7:bb411115f814 31 uint32_t subsecs = RTC->SSR;
Sissors 7:bb411115f814 32 time_t secs = rtc_read();
Sissors 7:bb411115f814 33
Sissors 7:bb411115f814 34 //Calculate alarm values
Sissors 7:bb411115f814 35 //Subseconds is countdown, so substract the 'added' sub-seconds and prevent underflow
Sissors 7:bb411115f814 36 if (subsecs < subsecsadd) {
Sissors 7:bb411115f814 37 subsecs += prescaler;
Sissors 7:bb411115f814 38 secs++;
Sissors 7:bb411115f814 39 }
Sissors 7:bb411115f814 40 subsecs -= subsecsadd;
Sissors 7:bb411115f814 41
Sissors 7:bb411115f814 42 //Set seconds correctly
Sissors 7:bb411115f814 43 secs += ms / 1000;
Sissors 7:bb411115f814 44 struct tm *timeinfo = localtime(&secs);
Sissors 7:bb411115f814 45
Sissors 7:bb411115f814 46 RTC_AlarmTypeDef alarmStruct;
Sissors 7:bb411115f814 47 alarmStruct.RTC_AlarmTime.RTC_Hours = timeinfo->tm_hour;
Sissors 7:bb411115f814 48 alarmStruct.RTC_AlarmTime.RTC_Minutes = timeinfo->tm_min;
Sissors 7:bb411115f814 49 alarmStruct.RTC_AlarmTime.RTC_Seconds = timeinfo->tm_sec;
Sissors 7:bb411115f814 50 alarmStruct.RTC_AlarmTime.RTC_H12 = RTC_HourFormat_24;
Sissors 7:bb411115f814 51 alarmStruct.RTC_AlarmMask = RTC_AlarmMask_None;
Sissors 7:bb411115f814 52 alarmStruct.RTC_AlarmDateWeekDaySel = RTC_AlarmDateWeekDaySel_Date;
Sissors 7:bb411115f814 53 alarmStruct.RTC_AlarmDateWeekDay = timeinfo->tm_mday;
Sissors 7:bb411115f814 54
Sissors 7:bb411115f814 55 //Enable EXTI interrupt of the RTC
Sissors 7:bb411115f814 56 EXTI_InitTypeDef extiStruct;
Sissors 7:bb411115f814 57 extiStruct.EXTI_Line = EXTI_Line17;
Sissors 7:bb411115f814 58 extiStruct.EXTI_Mode = EXTI_Mode_Interrupt;
Sissors 7:bb411115f814 59 extiStruct.EXTI_Trigger = EXTI_Trigger_Rising;
Sissors 7:bb411115f814 60 extiStruct.EXTI_LineCmd = ENABLE;
Sissors 7:bb411115f814 61
Sissors 7:bb411115f814 62 //Enable RTC interrupt
Sissors 7:bb411115f814 63 RTC_AlarmSubSecondConfig(RTC_Alarm_A, subsecs, RTC_AlarmSubSecondMask_None);
Sissors 7:bb411115f814 64 RTC_SetAlarm(RTC_Format_BIN, RTC_Alarm_A, &alarmStruct);
Sissors 7:bb411115f814 65 RTC_AlarmCmd(RTC_Alarm_A, ENABLE);
Sissors 7:bb411115f814 66 RTC_ITConfig(RTC_IT_ALRA, ENABLE);
Sissors 7:bb411115f814 67 PWR_BackupAccessCmd(DISABLE);
Sissors 7:bb411115f814 68
Sissors 7:bb411115f814 69 //Enable everything else
Sissors 7:bb411115f814 70 EXTI_Init(&extiStruct);
Sissors 7:bb411115f814 71 NVIC_SetVector(RTC_IRQn, (uint32_t)WakeUp::irq_handler);
Sissors 7:bb411115f814 72 NVIC_EnableIRQ(RTC_IRQn);
Sissors 7:bb411115f814 73 }
Sissors 7:bb411115f814 74
Sissors 7:bb411115f814 75
Sissors 7:bb411115f814 76 void WakeUp::irq_handler(void)
Sissors 7:bb411115f814 77 {
Sissors 7:bb411115f814 78 //Clear RTC + EXTI interrupt flags
Sissors 7:bb411115f814 79 PWR_BackupAccessCmd(ENABLE);
Sissors 7:bb411115f814 80 RTC_ClearFlag(RTC_FLAG_ALRAF);
Sissors 7:bb411115f814 81 EXTI_ClearFlag(EXTI_Line17);
Sissors 7:bb411115f814 82 PWR_BackupAccessCmd(DISABLE);
Sissors 7:bb411115f814 83 callback.call();
Sissors 7:bb411115f814 84 }
Sissors 7:bb411115f814 85
Sissors 7:bb411115f814 86 void WakeUp::calibrate(void)
Sissors 7:bb411115f814 87 {
Sissors 7:bb411115f814 88 //RTC, we assume it is accurate enough without calibration
Sissors 7:bb411115f814 89 }
Sissors 7:bb411115f814 90
Sissors 7:bb411115f814 91 #endif