add the implementation of LP1768 wakeup based on the old WakeUp library

Dependencies:   LPC1114_WakeInterruptIn

Fork of WakeUp by steven niu

Committer:
Sissors
Date:
Wed Jul 30 20:39:57 2014 +0000
Revision:
15:6bf547e1e62d
Parent:
10:29bdf5fed21a
Calibrate on LPC1114 now restores pin function settings afterwards (previously this broke wakeups were dp24 was used).
;
; Moved WakeInterruptIn to Device folder.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Sissors 10:29bdf5fed21a 1 #ifdef TARGET_STM
Sissors 10:29bdf5fed21a 2
Sissors 10:29bdf5fed21a 3 #include "WakeUp.h"
Sissors 10:29bdf5fed21a 4 #include "rtc_api.h"
Sissors 10:29bdf5fed21a 5
Sissors 10:29bdf5fed21a 6 #define BYTE2BCD(byte) ((byte % 10) | ((byte / 10) << 4))
Sissors 10:29bdf5fed21a 7 #define EXTI_RTC_LINE (1 << 17)
Sissors 10:29bdf5fed21a 8
Sissors 10:29bdf5fed21a 9 //Most things are pretty similar between the different STM targets.
Sissors 10:29bdf5fed21a 10 //Only the IRQ number the alarm is connected to differs. Any errors
Sissors 10:29bdf5fed21a 11 //with RTC_IRQn/RTC_Alarm_IRQn in them are related to this
Sissors 10:29bdf5fed21a 12 #if defined(TARGET_M4)
Sissors 10:29bdf5fed21a 13 #define RTC_IRQ RTC_Alarm_IRQn
Sissors 10:29bdf5fed21a 14 #else
Sissors 10:29bdf5fed21a 15 #define RTC_IRQ RTC_IRQn
Sissors 10:29bdf5fed21a 16 #endif
Sissors 10:29bdf5fed21a 17
Sissors 10:29bdf5fed21a 18 FunctionPointer WakeUp::callback;
Sissors 10:29bdf5fed21a 19
Sissors 10:29bdf5fed21a 20 void WakeUp::set_ms(uint32_t ms)
Sissors 10:29bdf5fed21a 21 {
Sissors 10:29bdf5fed21a 22 if (!rtc_isenabled()) { //Make sure RTC is running
Sissors 10:29bdf5fed21a 23 rtc_init();
Sissors 10:29bdf5fed21a 24 wait_us(250); //The f401 seems to want a delay after init
Sissors 10:29bdf5fed21a 25 }
Sissors 10:29bdf5fed21a 26
Sissors 10:29bdf5fed21a 27 PWR->CR |= PWR_CR_DBP; //Enable power domain
Sissors 10:29bdf5fed21a 28 RTC->WPR = 0xCA; //Disable RTC write protection
Sissors 10:29bdf5fed21a 29 RTC->WPR = 0x53;
Sissors 10:29bdf5fed21a 30
Sissors 10:29bdf5fed21a 31 //Alarm must be disabled to change anything
Sissors 10:29bdf5fed21a 32 RTC->CR &= ~RTC_CR_ALRAE;
Sissors 10:29bdf5fed21a 33 while(!(RTC->ISR & RTC_ISR_ALRAWF));
Sissors 10:29bdf5fed21a 34
Sissors 10:29bdf5fed21a 35 if (ms == 0) { //Just disable alarm
Sissors 10:29bdf5fed21a 36 PWR->CR &= ~PWR_CR_DBP; //Disable power domain
Sissors 10:29bdf5fed21a 37 RTC->WPR = 0xFF; //Enable RTC write protection
Sissors 10:29bdf5fed21a 38 return;
Sissors 10:29bdf5fed21a 39 }
Sissors 10:29bdf5fed21a 40
Sissors 10:29bdf5fed21a 41 //RTC prescaler + calculate how many sub-seconds should be added
Sissors 10:29bdf5fed21a 42 uint32_t prescaler = (RTC->PRER & 0x7FFF) + 1;
Sissors 10:29bdf5fed21a 43 uint32_t subsecsadd = ((ms % 1000) * prescaler) / 1000;
Sissors 10:29bdf5fed21a 44
Sissors 10:29bdf5fed21a 45 if ((ms < 1000) && (subsecsadd < 2))
Sissors 10:29bdf5fed21a 46 subsecsadd = 2; //At least 2 subsecs delay to be sure interrupt is called
Sissors 10:29bdf5fed21a 47
Sissors 10:29bdf5fed21a 48 __disable_irq(); //At this point we don't want IRQs anymore
Sissors 10:29bdf5fed21a 49
Sissors 10:29bdf5fed21a 50 //Get current time
Sissors 10:29bdf5fed21a 51 uint32_t subsecs = RTC->SSR;
Sissors 10:29bdf5fed21a 52 time_t secs = rtc_read();
Sissors 10:29bdf5fed21a 53
Sissors 10:29bdf5fed21a 54 //Calculate alarm values
Sissors 10:29bdf5fed21a 55 //Subseconds is countdown, so substract the 'added' sub-seconds and prevent underflow
Sissors 10:29bdf5fed21a 56 if (subsecs < subsecsadd) {
Sissors 10:29bdf5fed21a 57 subsecs += prescaler;
Sissors 10:29bdf5fed21a 58 secs++;
Sissors 10:29bdf5fed21a 59 }
Sissors 10:29bdf5fed21a 60 subsecs -= subsecsadd;
Sissors 10:29bdf5fed21a 61
Sissors 10:29bdf5fed21a 62 //Set seconds correctly
Sissors 10:29bdf5fed21a 63 secs += ms / 1000;
Sissors 10:29bdf5fed21a 64 struct tm *timeinfo = localtime(&secs);
Sissors 10:29bdf5fed21a 65
Sissors 10:29bdf5fed21a 66 //Enable rising edge EXTI interrupt of the RTC
Sissors 10:29bdf5fed21a 67 EXTI->IMR |= EXTI_RTC_LINE;
Sissors 10:29bdf5fed21a 68 EXTI->EMR &= ~EXTI_RTC_LINE;
Sissors 10:29bdf5fed21a 69 EXTI->RTSR |= EXTI_RTC_LINE;
Sissors 10:29bdf5fed21a 70 EXTI->FTSR &= ~EXTI_RTC_LINE;
Sissors 10:29bdf5fed21a 71
Sissors 10:29bdf5fed21a 72 //Calculate alarm register values
Sissors 10:29bdf5fed21a 73 uint32_t alarmreg = 0;
Sissors 10:29bdf5fed21a 74 alarmreg |= BYTE2BCD(timeinfo->tm_sec) << 0;
Sissors 10:29bdf5fed21a 75 alarmreg |= BYTE2BCD(timeinfo->tm_min) << 8;
Sissors 10:29bdf5fed21a 76 alarmreg |= BYTE2BCD(timeinfo->tm_hour) << 16;
Sissors 10:29bdf5fed21a 77 alarmreg |= BYTE2BCD(timeinfo->tm_mday) << 24;
Sissors 10:29bdf5fed21a 78
Sissors 10:29bdf5fed21a 79 //Enable RTC interrupt
Sissors 10:29bdf5fed21a 80 RTC->ALRMAR = alarmreg;
Sissors 10:29bdf5fed21a 81 RTC->ALRMASSR = subsecs | RTC_ALRMASSR_MASKSS; //Mask no subseconds
Sissors 10:29bdf5fed21a 82 RTC->CR |= RTC_CR_ALRAE | RTC_CR_ALRAIE; //Enable Alarm
Sissors 10:29bdf5fed21a 83
Sissors 10:29bdf5fed21a 84 RTC->WPR = 0xFF; //Enable RTC write protection
Sissors 10:29bdf5fed21a 85 PWR->CR &= ~PWR_CR_DBP; //Disable power domain
Sissors 10:29bdf5fed21a 86
Sissors 10:29bdf5fed21a 87 __enable_irq(); //Alarm is set, so irqs can be enabled again
Sissors 10:29bdf5fed21a 88
Sissors 10:29bdf5fed21a 89 //Enable everything else
Sissors 10:29bdf5fed21a 90 NVIC_SetVector(RTC_IRQ, (uint32_t)WakeUp::irq_handler);
Sissors 10:29bdf5fed21a 91 NVIC_EnableIRQ(RTC_IRQ);
Sissors 10:29bdf5fed21a 92 }
Sissors 10:29bdf5fed21a 93
Sissors 10:29bdf5fed21a 94
Sissors 10:29bdf5fed21a 95 void WakeUp::irq_handler(void)
Sissors 10:29bdf5fed21a 96 {
Sissors 10:29bdf5fed21a 97 //Clear RTC + EXTI interrupt flags
Sissors 10:29bdf5fed21a 98 PWR->CR |= PWR_CR_DBP; //Enable power domain
Sissors 10:29bdf5fed21a 99 RTC->ISR &= ~RTC_ISR_ALRAF;
Sissors 10:29bdf5fed21a 100 EXTI->PR = EXTI_RTC_LINE;
Sissors 10:29bdf5fed21a 101 PWR->CR &= ~PWR_CR_DBP; //Disable power domain
Sissors 10:29bdf5fed21a 102 callback.call();
Sissors 10:29bdf5fed21a 103 }
Sissors 10:29bdf5fed21a 104
Sissors 10:29bdf5fed21a 105 void WakeUp::calibrate(void)
Sissors 10:29bdf5fed21a 106 {
Sissors 10:29bdf5fed21a 107 //RTC, we assume it is accurate enough without calibration
Sissors 10:29bdf5fed21a 108 }
Sissors 10:29bdf5fed21a 109
Sissors 10:29bdf5fed21a 110
Sissors 10:29bdf5fed21a 111 #endif