mbed-os
Fork of mbed-os by
targets/TARGET_ONSEMI/TARGET_NCS36510/rtc.c@1:3deb71413561, 2017-07-20 (annotated)
- Committer:
- xuaner
- Date:
- Thu Jul 20 14:26:57 2017 +0000
- Revision:
- 1:3deb71413561
- Parent:
- 0:f269e3021894
mbed_os
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
elessair | 0:f269e3021894 | 1 | /** |
elessair | 0:f269e3021894 | 2 | ******************************************************************************* |
elessair | 0:f269e3021894 | 3 | * @file rtc.c |
elessair | 0:f269e3021894 | 4 | * @brief Implementation of a Rtc driver |
elessair | 0:f269e3021894 | 5 | * @internal |
elessair | 0:f269e3021894 | 6 | * @author ON Semiconductor |
elessair | 0:f269e3021894 | 7 | * $Rev: 3525 $ |
elessair | 0:f269e3021894 | 8 | * $Date: 2015-07-20 15:24:25 +0530 (Mon, 20 Jul 2015) $ |
elessair | 0:f269e3021894 | 9 | ****************************************************************************** |
elessair | 0:f269e3021894 | 10 | * Copyright 2016 Semiconductor Components Industries LLC (d/b/a ON Semiconductor). |
elessair | 0:f269e3021894 | 11 | * All rights reserved. This software and/or documentation is licensed by ON Semiconductor |
elessair | 0:f269e3021894 | 12 | * under limited terms and conditions. The terms and conditions pertaining to the software |
elessair | 0:f269e3021894 | 13 | * and/or documentation are available at http://www.onsemi.com/site/pdf/ONSEMI_T&C.pdf |
elessair | 0:f269e3021894 | 14 | * (ON Semiconductor Standard Terms and Conditions of Sale, Section 8 Software) and |
elessair | 0:f269e3021894 | 15 | * if applicable the software license agreement. Do not use this software and/or |
elessair | 0:f269e3021894 | 16 | * documentation unless you have carefully read and you agree to the limited terms and |
elessair | 0:f269e3021894 | 17 | * conditions. By using this software and/or documentation, you agree to the limited |
elessair | 0:f269e3021894 | 18 | * terms and conditions. |
elessair | 0:f269e3021894 | 19 | * |
elessair | 0:f269e3021894 | 20 | * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED |
elessair | 0:f269e3021894 | 21 | * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF |
elessair | 0:f269e3021894 | 22 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. |
elessair | 0:f269e3021894 | 23 | * ON SEMICONDUCTOR SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, |
elessair | 0:f269e3021894 | 24 | * INCIDENTAL, OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. |
elessair | 0:f269e3021894 | 25 | * @endinternal |
elessair | 0:f269e3021894 | 26 | * |
elessair | 0:f269e3021894 | 27 | * @ingroup rtc |
elessair | 0:f269e3021894 | 28 | * |
elessair | 0:f269e3021894 | 29 | * @details |
elessair | 0:f269e3021894 | 30 | * A real-time clock (RTC) is a computer clock ,that keeps track of the current time. The heart of the RTC is a series of |
elessair | 0:f269e3021894 | 31 | * freely running counters one for each time unit, The series of counters is linked as follows: a roll over event of |
elessair | 0:f269e3021894 | 32 | * the seconds counter produces a minutes enable pulse; a roll over event of the minutes counter produces an hours |
elessair | 0:f269e3021894 | 33 | * enable pulse, etc.Note that all Counter registers are in an undefined state on power-up. |
elessair | 0:f269e3021894 | 34 | * Use the Reset bit in the Control Register to reset the counters to their default values. |
elessair | 0:f269e3021894 | 35 | * DIVISOR is the register containing the value to divide the clock frequency to produce 1Hz strobe ; 1Hz strobe is used |
elessair | 0:f269e3021894 | 36 | * internally to time the incrementing of the Seconds Counter. |
elessair | 0:f269e3021894 | 37 | * There is a set of register to set the values in the counter for each time unit.from where time is start to increment. |
elessair | 0:f269e3021894 | 38 | * There is another set of register to set the ALARM ...Each of the Alarm Registers can be programmed with a value that |
elessair | 0:f269e3021894 | 39 | * is used to compare to a Counter Register in order to produce an alarm (an interrupt) when the values match. |
elessair | 0:f269e3021894 | 40 | * There is a programmable bit in each Alarm Register that determines if the alarm occurs upon a value match, or |
elessair | 0:f269e3021894 | 41 | * if the alarm occurs upon a Counter increment condition. |
elessair | 0:f269e3021894 | 42 | * |
elessair | 0:f269e3021894 | 43 | */ |
elessair | 0:f269e3021894 | 44 | #include "rtc.h" |
elessair | 0:f269e3021894 | 45 | #include "mbed_assert.h" |
elessair | 0:f269e3021894 | 46 | |
elessair | 0:f269e3021894 | 47 | static uint16_t SubSecond; |
elessair | 0:f269e3021894 | 48 | static uint64_t LastRtcTimeus; |
elessair | 0:f269e3021894 | 49 | |
elessair | 0:f269e3021894 | 50 | /* See rtc.h for details */ |
elessair | 0:f269e3021894 | 51 | void fRtcInit(void) |
elessair | 0:f269e3021894 | 52 | { |
elessair | 0:f269e3021894 | 53 | CLOCK_ENABLE(CLOCK_RTC); /* enable rtc peripheral */ |
elessair | 0:f269e3021894 | 54 | CLOCKREG->CCR.BITS.RTCEN = True; /* Enable RTC clock 32K */ |
elessair | 0:f269e3021894 | 55 | |
elessair | 0:f269e3021894 | 56 | /* Reset RTC control register */ |
elessair | 0:f269e3021894 | 57 | RTCREG->CONTROL.WORD = False; |
elessair | 0:f269e3021894 | 58 | |
elessair | 0:f269e3021894 | 59 | /* Initialize all counters */ |
elessair | 0:f269e3021894 | 60 | RTCREG->SECOND_COUNTER = False; |
elessair | 0:f269e3021894 | 61 | RTCREG->SUB_SECOND_COUNTER = False; |
elessair | 0:f269e3021894 | 62 | RTCREG->SECOND_ALARM = False; |
elessair | 0:f269e3021894 | 63 | RTCREG->SUB_SECOND_ALARM = False; |
elessair | 0:f269e3021894 | 64 | LastRtcTimeus = 0; |
elessair | 0:f269e3021894 | 65 | |
elessair | 0:f269e3021894 | 66 | /* Reset RTC Status register */ |
elessair | 0:f269e3021894 | 67 | RTCREG->STATUS.WORD = False; |
elessair | 0:f269e3021894 | 68 | |
elessair | 0:f269e3021894 | 69 | /* Clear interrupt status */ |
elessair | 0:f269e3021894 | 70 | RTCREG->INT_CLEAR.WORD = False; |
elessair | 0:f269e3021894 | 71 | |
elessair | 0:f269e3021894 | 72 | /* Start sec & sub_sec counter */ |
elessair | 0:f269e3021894 | 73 | while(RTCREG->STATUS.BITS.BSY_CTRL_REG_WRT == True);/* Wait previous write to complete */ |
elessair | 0:f269e3021894 | 74 | RTCREG->CONTROL.WORD |= ((True << RTC_CONTROL_SUBSEC_CNT_START_BIT_POS) | |
elessair | 0:f269e3021894 | 75 | (True << RTC_CONTROL_SEC_CNT_START_BIT_POS)); |
elessair | 0:f269e3021894 | 76 | |
elessair | 0:f269e3021894 | 77 | /* enable interruption associated with the rtc at NVIC level */ |
elessair | 0:f269e3021894 | 78 | NVIC_SetVector(Rtc_IRQn,(uint32_t)fRtcHandler); /* TODO define lp_ticker_isr */ |
elessair | 0:f269e3021894 | 79 | NVIC_ClearPendingIRQ(Rtc_IRQn); |
elessair | 0:f269e3021894 | 80 | NVIC_EnableIRQ(Rtc_IRQn); |
elessair | 0:f269e3021894 | 81 | |
elessair | 0:f269e3021894 | 82 | while(RTCREG->STATUS.BITS.BSY_CTRL_REG_WRT == True); /* Wait for RTC to finish writing register - RTC operates on 32K clock as compared to 32M core*/ |
elessair | 0:f269e3021894 | 83 | |
elessair | 0:f269e3021894 | 84 | return; |
elessair | 0:f269e3021894 | 85 | } |
elessair | 0:f269e3021894 | 86 | |
elessair | 0:f269e3021894 | 87 | /* See rtc.h for details */ |
elessair | 0:f269e3021894 | 88 | void fRtcFree(void) |
elessair | 0:f269e3021894 | 89 | { |
elessair | 0:f269e3021894 | 90 | /* Reset RTC control register */ |
elessair | 0:f269e3021894 | 91 | RTCREG->CONTROL.WORD = False; |
elessair | 0:f269e3021894 | 92 | |
elessair | 0:f269e3021894 | 93 | /* disable interruption associated with the rtc */ |
elessair | 0:f269e3021894 | 94 | NVIC_DisableIRQ(Rtc_IRQn); |
elessair | 0:f269e3021894 | 95 | |
elessair | 0:f269e3021894 | 96 | while(RTCREG->STATUS.BITS.BSY_CTRL_REG_WRT == True); /* Wait for RTC to finish writing register - RTC operates on 32K clock as compared to 32M core*/ |
elessair | 0:f269e3021894 | 97 | } |
elessair | 0:f269e3021894 | 98 | |
elessair | 0:f269e3021894 | 99 | /* See rtc.h for details */ |
elessair | 0:f269e3021894 | 100 | void fRtcSetInterrupt(uint32_t timestamp) |
elessair | 0:f269e3021894 | 101 | { |
elessair | 0:f269e3021894 | 102 | SubSecond = False; |
elessair | 0:f269e3021894 | 103 | uint32_t Second = False; |
elessair | 0:f269e3021894 | 104 | uint8_t DividerAdjust = 1; |
elessair | 0:f269e3021894 | 105 | |
elessair | 0:f269e3021894 | 106 | if(timestamp) { |
elessair | 0:f269e3021894 | 107 | if(timestamp >= RTC_SEC_TO_US) { |
elessair | 0:f269e3021894 | 108 | /* TimeStamp is big enough to set second alarm */ |
elessair | 0:f269e3021894 | 109 | Second = ((timestamp / RTC_SEC_TO_US) & RTC_SEC_MASK); /* Convert micro second to second */ |
elessair | 0:f269e3021894 | 110 | RTCREG->SECOND_ALARM = Second; /* Write to alarm register */ |
elessair | 0:f269e3021894 | 111 | |
elessair | 0:f269e3021894 | 112 | /* Enable second interrupt */ |
elessair | 0:f269e3021894 | 113 | RTCREG->CONTROL.WORD |= (True << RTC_CONTROL_SEC_CNT_INT_BIT_POS); |
elessair | 0:f269e3021894 | 114 | } |
elessair | 0:f269e3021894 | 115 | timestamp = timestamp - Second * RTC_SEC_TO_US; /* Take out micro second for sub second alarm */ |
elessair | 0:f269e3021894 | 116 | if(timestamp > False) { |
elessair | 0:f269e3021894 | 117 | /* We have some thing for sub second */ |
elessair | 0:f269e3021894 | 118 | |
elessair | 0:f269e3021894 | 119 | /* Convert micro second to sub_seconds(each count = 30.5 us) */ |
elessair | 0:f269e3021894 | 120 | if(timestamp > 131000) { |
elessair | 0:f269e3021894 | 121 | DividerAdjust = 100; |
elessair | 0:f269e3021894 | 122 | } |
elessair | 0:f269e3021894 | 123 | |
elessair | 0:f269e3021894 | 124 | volatile uint64_t Temp = (timestamp / DividerAdjust * RTC_CLOCK_HZ); |
elessair | 0:f269e3021894 | 125 | Temp = (uint64_t)(Temp / RTC_SEC_TO_US * DividerAdjust); |
elessair | 0:f269e3021894 | 126 | SubSecond = Temp & RTC_SUB_SEC_MASK; |
elessair | 0:f269e3021894 | 127 | |
elessair | 0:f269e3021894 | 128 | if(SubSecond <= 5) { |
elessair | 0:f269e3021894 | 129 | SubSecond = 0; |
elessair | 0:f269e3021894 | 130 | } |
elessair | 0:f269e3021894 | 131 | |
elessair | 0:f269e3021894 | 132 | |
elessair | 0:f269e3021894 | 133 | if(SubSecond > False) { |
elessair | 0:f269e3021894 | 134 | /* Second interrupt not enabled */ |
elessair | 0:f269e3021894 | 135 | |
elessair | 0:f269e3021894 | 136 | /* Set SUB SEC_ALARM */ |
elessair | 0:f269e3021894 | 137 | RTCREG->SUB_SECOND_ALARM = SubSecond; /* Write to sub second alarm */ |
elessair | 0:f269e3021894 | 138 | |
elessair | 0:f269e3021894 | 139 | /* Enable sub second interrupt */ |
elessair | 0:f269e3021894 | 140 | while(RTCREG->STATUS.BITS.BSY_CTRL_REG_WRT == True); |
elessair | 0:f269e3021894 | 141 | RTCREG->CONTROL.WORD |= (True << RTC_CONTROL_SUBSEC_CNT_INT_BIT_POS); |
elessair | 0:f269e3021894 | 142 | } |
elessair | 0:f269e3021894 | 143 | } |
elessair | 0:f269e3021894 | 144 | |
elessair | 0:f269e3021894 | 145 | while(RTCREG->STATUS.BITS.BSY_ANY_WRT == True); /* Wait for RTC to finish writing register - RTC operates on 32K clock as compared to 32M core*/ |
elessair | 0:f269e3021894 | 146 | } |
elessair | 0:f269e3021894 | 147 | return; |
elessair | 0:f269e3021894 | 148 | } |
elessair | 0:f269e3021894 | 149 | |
elessair | 0:f269e3021894 | 150 | /* See rtc.h for details */ |
elessair | 0:f269e3021894 | 151 | void fRtcDisableInterrupt(void) |
elessair | 0:f269e3021894 | 152 | { |
elessair | 0:f269e3021894 | 153 | /* Disable subsec/sec interrupt */ |
elessair | 0:f269e3021894 | 154 | RTCREG->CONTROL.WORD &= ~((RTC_ALL_INTERRUPT_BIT_VAL) << RTC_CONTROL_SUBSEC_CNT_INT_BIT_POS); |
elessair | 0:f269e3021894 | 155 | while(RTCREG->STATUS.BITS.BSY_CTRL_REG_WRT == True); /* Wait for RTC to finish writing register - RTC operates on 32K clock as compared to 32M core*/ |
elessair | 0:f269e3021894 | 156 | } |
elessair | 0:f269e3021894 | 157 | |
elessair | 0:f269e3021894 | 158 | /* See rtc.h for details */ |
elessair | 0:f269e3021894 | 159 | void fRtcEnableInterrupt(void) |
elessair | 0:f269e3021894 | 160 | { |
elessair | 0:f269e3021894 | 161 | /* Disable subsec/sec interrupt */ |
elessair | 0:f269e3021894 | 162 | RTCREG->CONTROL.WORD |= ((RTC_ALL_INTERRUPT_BIT_VAL) << RTC_CONTROL_SUBSEC_CNT_INT_BIT_POS); |
elessair | 0:f269e3021894 | 163 | while(RTCREG->STATUS.BITS.BSY_CTRL_REG_WRT == True); /* Wait for RTC to finish writing register - RTC operates on 32K clock as compared to 32M core*/ |
elessair | 0:f269e3021894 | 164 | } |
elessair | 0:f269e3021894 | 165 | |
elessair | 0:f269e3021894 | 166 | /* See rtc.h for details */ |
elessair | 0:f269e3021894 | 167 | void fRtcClearInterrupt(void) |
elessair | 0:f269e3021894 | 168 | { |
elessair | 0:f269e3021894 | 169 | /* Disable subsec/sec interrupt */ |
elessair | 0:f269e3021894 | 170 | /* Clear sec & sub_sec interrupts */ |
elessair | 0:f269e3021894 | 171 | RTCREG->INT_CLEAR.WORD = ((True << RTC_INT_CLR_SUB_SEC_BIT_POS) | |
elessair | 0:f269e3021894 | 172 | (True << RTC_INT_CLR_SEC_BIT_POS)); |
elessair | 0:f269e3021894 | 173 | while(RTCREG->STATUS.BITS.BSY_ANY_WRT == True); /* Wait for RTC to finish writing register - RTC operates on 32K clock as compared to 32M core*/ |
elessair | 0:f269e3021894 | 174 | } |
elessair | 0:f269e3021894 | 175 | |
elessair | 0:f269e3021894 | 176 | /* See rtc.h for details */ |
elessair | 0:f269e3021894 | 177 | uint64_t fRtcRead(void) |
elessair | 0:f269e3021894 | 178 | { |
elessair | 0:f269e3021894 | 179 | uint32_t Second; |
elessair | 0:f269e3021894 | 180 | uint16_t SubSecond; |
elessair | 0:f269e3021894 | 181 | |
elessair | 0:f269e3021894 | 182 | /* Hardware Bug fix: The rollover of the sub-second counter initiates the increment of the second counter. |
elessair | 0:f269e3021894 | 183 | * That means there is one cycle where the sub-second has rolled back to zero and the second counter has not incremented |
elessair | 0:f269e3021894 | 184 | * and a read during that cycle will be incorrect. That will occur for one RTC cycle and that is about 31us of exposure. |
elessair | 0:f269e3021894 | 185 | * If you read a zero in the sub-second counter then increment the second counter by 1. |
elessair | 0:f269e3021894 | 186 | * Alternatively, subtract 1 from the Sub-seconds counter to align the Second and Sub-Second rollover. |
elessair | 0:f269e3021894 | 187 | */ |
elessair | 0:f269e3021894 | 188 | |
elessair | 0:f269e3021894 | 189 | /* Read the Second and Sub-second counters, then read the Second counter again. |
elessair | 0:f269e3021894 | 190 | * If it changed, then the Second rolled over while reading Sub-seconds, so go back and read them both again. |
elessair | 0:f269e3021894 | 191 | */ |
elessair | 0:f269e3021894 | 192 | |
elessair | 0:f269e3021894 | 193 | do { |
elessair | 0:f269e3021894 | 194 | Second = RTCREG->SECOND_COUNTER; /* Get SEC_COUNTER reg value */ |
elessair | 0:f269e3021894 | 195 | SubSecond = (RTCREG->SUB_SECOND_COUNTER - 1) & 0x7FFF; /* Get SUB_SEC_COUNTER reg value */ |
elessair | 0:f269e3021894 | 196 | } while (Second != RTCREG->SECOND_COUNTER); /* Repeat if the second has changed */ |
elessair | 0:f269e3021894 | 197 | |
elessair | 0:f269e3021894 | 198 | //note: casting to float removed to avoid reduction in resolution |
elessair | 0:f269e3021894 | 199 | uint64_t RtcTimeus = ((uint64_t)SubSecond * RTC_SEC_TO_US / RTC_CLOCK_HZ) + ((uint64_t)Second * RTC_SEC_TO_US); |
elessair | 0:f269e3021894 | 200 | |
elessair | 0:f269e3021894 | 201 | /*check that the time did not go backwards */ |
elessair | 0:f269e3021894 | 202 | MBED_ASSERT(RtcTimeus >= LastRtcTimeus); |
elessair | 0:f269e3021894 | 203 | LastRtcTimeus = RtcTimeus; |
elessair | 0:f269e3021894 | 204 | |
elessair | 0:f269e3021894 | 205 | return RtcTimeus; |
elessair | 0:f269e3021894 | 206 | } |
elessair | 0:f269e3021894 | 207 | |
elessair | 0:f269e3021894 | 208 | /* See rtc.h for details */ |
elessair | 0:f269e3021894 | 209 | void fRtcWrite(uint64_t RtcTimeus) |
elessair | 0:f269e3021894 | 210 | { |
elessair | 0:f269e3021894 | 211 | uint32_t Second = 0; |
elessair | 0:f269e3021894 | 212 | uint16_t SubSecond = 0; |
elessair | 0:f269e3021894 | 213 | /* Stop RTC */ |
elessair | 0:f269e3021894 | 214 | RTCREG->CONTROL.WORD &= ~((True << RTC_CONTROL_SUBSEC_CNT_START_BIT_POS) | |
elessair | 0:f269e3021894 | 215 | (True << RTC_CONTROL_SEC_CNT_START_BIT_POS)); |
elessair | 0:f269e3021894 | 216 | |
elessair | 0:f269e3021894 | 217 | if(RtcTimeus > RTC_SEC_TO_US) { |
elessair | 0:f269e3021894 | 218 | /* TimeStamp is big enough to set second counter */ |
elessair | 0:f269e3021894 | 219 | Second = ((RtcTimeus / RTC_SEC_TO_US) & RTC_SEC_MASK); |
elessair | 0:f269e3021894 | 220 | } |
elessair | 0:f269e3021894 | 221 | RTCREG->SECOND_COUNTER = Second; |
elessair | 0:f269e3021894 | 222 | RtcTimeus = RtcTimeus - (Second * RTC_SEC_TO_US); |
elessair | 0:f269e3021894 | 223 | if(RtcTimeus > False) { |
elessair | 0:f269e3021894 | 224 | /* Convert TimeStamp to sub_seconds */ |
elessair | 0:f269e3021894 | 225 | SubSecond = (uint16_t)((float)(RtcTimeus * RTC_CLOCK_HZ / RTC_SEC_TO_US)) & RTC_SUB_SEC_MASK; |
elessair | 0:f269e3021894 | 226 | } |
elessair | 0:f269e3021894 | 227 | /* Set SUB_SEC_ALARM */ |
elessair | 0:f269e3021894 | 228 | RTCREG->SUB_SECOND_COUNTER = SubSecond; |
elessair | 0:f269e3021894 | 229 | |
elessair | 0:f269e3021894 | 230 | while(RTCREG->STATUS.BITS.BSY_CTRL_REG_WRT == True); /* Wait for RTC to finish writing register - RTC operates on 32K clock as compared to 32M core*/ |
elessair | 0:f269e3021894 | 231 | /* Start RTC */ |
elessair | 0:f269e3021894 | 232 | RTCREG->CONTROL.WORD |= ((True << RTC_CONTROL_SUBSEC_CNT_START_BIT_POS) | |
elessair | 0:f269e3021894 | 233 | (True << RTC_CONTROL_SEC_CNT_START_BIT_POS)); |
elessair | 0:f269e3021894 | 234 | |
elessair | 0:f269e3021894 | 235 | while(RTCREG->STATUS.BITS.BSY_ANY_WRT == True); /* Wait for RTC to finish writing register - RTC operates on 32K clock as compared to 32M core*/ |
elessair | 0:f269e3021894 | 236 | } |
elessair | 0:f269e3021894 | 237 | |
elessair | 0:f269e3021894 | 238 | /* See rtc.h for details */ |
elessair | 0:f269e3021894 | 239 | void fRtcHandler(void) |
elessair | 0:f269e3021894 | 240 | { |
elessair | 0:f269e3021894 | 241 | /* SUB_SECOND/SECOND interrupt occured */ |
elessair | 0:f269e3021894 | 242 | volatile uint32_t TempStatus = RTCREG->STATUS.WORD; |
elessair | 0:f269e3021894 | 243 | |
elessair | 0:f269e3021894 | 244 | /* Disable RTC interrupt */ |
elessair | 0:f269e3021894 | 245 | NVIC_DisableIRQ(Rtc_IRQn); |
elessair | 0:f269e3021894 | 246 | |
elessair | 0:f269e3021894 | 247 | /* Clear sec & sub_sec interrupts */ |
elessair | 0:f269e3021894 | 248 | RTCREG->INT_CLEAR.WORD = ((True << RTC_INT_CLR_SUB_SEC_BIT_POS) | |
elessair | 0:f269e3021894 | 249 | (True << RTC_INT_CLR_SEC_BIT_POS)); |
elessair | 0:f269e3021894 | 250 | |
elessair | 0:f269e3021894 | 251 | /* TODO ANDing SUB_SEC & SEC interrupt - work around for RTC issue - will be resolved in REV G */ |
elessair | 0:f269e3021894 | 252 | if(TempStatus & RTC_SEC_INT_STATUS_MASK) { |
elessair | 0:f269e3021894 | 253 | /* Second interrupt occured */ |
elessair | 0:f269e3021894 | 254 | if(SubSecond > False) { |
elessair | 0:f269e3021894 | 255 | /* Set SUB SEC_ALARM */ |
elessair | 0:f269e3021894 | 256 | RTCREG->SUB_SECOND_ALARM = SubSecond + RTCREG->SUB_SECOND_COUNTER; |
elessair | 0:f269e3021894 | 257 | /* Enable sub second interrupt */ |
elessair | 0:f269e3021894 | 258 | RTCREG->CONTROL.WORD |= (True << RTC_CONTROL_SUBSEC_CNT_INT_BIT_POS); |
elessair | 0:f269e3021894 | 259 | } else { |
elessair | 0:f269e3021894 | 260 | /* We reach here after second interrupt is occured */ |
elessair | 0:f269e3021894 | 261 | RTCREG->CONTROL.WORD &= ~(True << RTC_CONTROL_SUBSEC_CNT_INT_BIT_POS) | |
elessair | 0:f269e3021894 | 262 | (True << RTC_CONTROL_SEC_CNT_INT_BIT_POS); |
elessair | 0:f269e3021894 | 263 | } |
elessair | 0:f269e3021894 | 264 | } else { |
elessair | 0:f269e3021894 | 265 | /* We reach here after sub_second or (Sub second + second) interrupt occured */ |
elessair | 0:f269e3021894 | 266 | /* Disable Second and sub_second interrupt */ |
elessair | 0:f269e3021894 | 267 | RTCREG->CONTROL.WORD &= ~(True << RTC_CONTROL_SUBSEC_CNT_INT_BIT_POS) | |
elessair | 0:f269e3021894 | 268 | (True << RTC_CONTROL_SEC_CNT_INT_BIT_POS); |
elessair | 0:f269e3021894 | 269 | } |
elessair | 0:f269e3021894 | 270 | |
elessair | 0:f269e3021894 | 271 | NVIC_EnableIRQ(Rtc_IRQn); |
elessair | 0:f269e3021894 | 272 | |
elessair | 0:f269e3021894 | 273 | while(RTCREG->STATUS.BITS.BSY_ANY_WRT == True); /* Wait for RTC to finish writing register - RTC operates on 32K clock as compared to 32M core*/ |
elessair | 0:f269e3021894 | 274 | |
elessair | 0:f269e3021894 | 275 | lp_ticker_irq_handler(); |
elessair | 0:f269e3021894 | 276 | } |
elessair | 0:f269e3021894 | 277 | |
elessair | 0:f269e3021894 | 278 | boolean fIsRtcEnabled(void) |
elessair | 0:f269e3021894 | 279 | { |
elessair | 0:f269e3021894 | 280 | if(RTCREG->CONTROL.BITS.SUB_SEC_COUNTER_EN | RTCREG->CONTROL.BITS.SEC_COUNTER_EN) { |
elessair | 0:f269e3021894 | 281 | return True; |
elessair | 0:f269e3021894 | 282 | } else { |
elessair | 0:f269e3021894 | 283 | return False; |
elessair | 0:f269e3021894 | 284 | } |
elessair | 0:f269e3021894 | 285 | } |