Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of mbed-dev by
targets/TARGET_ONSEMI/TARGET_NCS36510/rtc.c@167:e84263d55307, 2017-06-21 (annotated)
- Committer:
- AnnaBridge
- Date:
- Wed Jun 21 17:46:44 2017 +0100
- Revision:
- 167:e84263d55307
- Parent:
- 150:02e0a0aed4ec
- Child:
- 174:b96e65c34a4d
This updates the lib to the mbed lib v 145
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
<> | 149:156823d33999 | 1 | /** |
<> | 149:156823d33999 | 2 | ******************************************************************************* |
<> | 149:156823d33999 | 3 | * @file rtc.c |
<> | 149:156823d33999 | 4 | * @brief Implementation of a Rtc driver |
<> | 149:156823d33999 | 5 | * @internal |
<> | 149:156823d33999 | 6 | * @author ON Semiconductor |
<> | 149:156823d33999 | 7 | * $Rev: 3525 $ |
<> | 149:156823d33999 | 8 | * $Date: 2015-07-20 15:24:25 +0530 (Mon, 20 Jul 2015) $ |
<> | 149:156823d33999 | 9 | ****************************************************************************** |
AnnaBridge | 167:e84263d55307 | 10 | * Copyright 2016 Semiconductor Components Industries LLC (d/b/a �ON Semiconductor�). |
<> | 149:156823d33999 | 11 | * All rights reserved. This software and/or documentation is licensed by ON Semiconductor |
<> | 149:156823d33999 | 12 | * under limited terms and conditions. The terms and conditions pertaining to the software |
<> | 149:156823d33999 | 13 | * and/or documentation are available at http://www.onsemi.com/site/pdf/ONSEMI_T&C.pdf |
AnnaBridge | 167:e84263d55307 | 14 | * (�ON Semiconductor Standard Terms and Conditions of Sale, Section 8 Software�) and |
<> | 149:156823d33999 | 15 | * if applicable the software license agreement. Do not use this software and/or |
<> | 149:156823d33999 | 16 | * documentation unless you have carefully read and you agree to the limited terms and |
<> | 149:156823d33999 | 17 | * conditions. By using this software and/or documentation, you agree to the limited |
<> | 149:156823d33999 | 18 | * terms and conditions. |
<> | 149:156823d33999 | 19 | * |
<> | 149:156823d33999 | 20 | * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED |
<> | 149:156823d33999 | 21 | * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF |
<> | 149:156823d33999 | 22 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. |
<> | 149:156823d33999 | 23 | * ON SEMICONDUCTOR SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, |
<> | 149:156823d33999 | 24 | * INCIDENTAL, OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. |
<> | 149:156823d33999 | 25 | * @endinternal |
<> | 149:156823d33999 | 26 | * |
<> | 149:156823d33999 | 27 | * @ingroup rtc |
<> | 149:156823d33999 | 28 | * |
<> | 149:156823d33999 | 29 | * @details |
<> | 149:156823d33999 | 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 |
<> | 149:156823d33999 | 31 | * freely running counters one for each time unit, The series of counters is linked as follows: a roll over event of |
<> | 149:156823d33999 | 32 | * the seconds counter produces a minutes enable pulse; a roll over event of the minutes counter produces an hours |
<> | 149:156823d33999 | 33 | * enable pulse, etc.Note that all Counter registers are in an undefined state on power-up. |
<> | 149:156823d33999 | 34 | * Use the Reset bit in the Control Register to reset the counters to their default values. |
<> | 149:156823d33999 | 35 | * DIVISOR is the register containing the value to divide the clock frequency to produce 1Hz strobe ; 1Hz strobe is used |
<> | 149:156823d33999 | 36 | * internally to time the incrementing of the Seconds Counter. |
<> | 149:156823d33999 | 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. |
<> | 149:156823d33999 | 38 | * There is another set of register to set the ALARM ...Each of the Alarm Registers can be programmed with a value that |
<> | 149:156823d33999 | 39 | * is used to compare to a Counter Register in order to produce an alarm (an interrupt) when the values match. |
<> | 149:156823d33999 | 40 | * There is a programmable bit in each Alarm Register that determines if the alarm occurs upon a value match, or |
<> | 149:156823d33999 | 41 | * if the alarm occurs upon a Counter increment condition. |
<> | 149:156823d33999 | 42 | * |
<> | 149:156823d33999 | 43 | */ |
<> | 149:156823d33999 | 44 | #include "rtc.h" |
<> | 149:156823d33999 | 45 | #include "mbed_assert.h" |
<> | 150:02e0a0aed4ec | 46 | #include "lp_ticker_api.h" |
<> | 149:156823d33999 | 47 | |
AnnaBridge | 167:e84263d55307 | 48 | static volatile uint64_t last_time_read; |
AnnaBridge | 167:e84263d55307 | 49 | |
AnnaBridge | 167:e84263d55307 | 50 | /** |
AnnaBridge | 167:e84263d55307 | 51 | * Convert sub seconds ticks to micro seconds. |
AnnaBridge | 167:e84263d55307 | 52 | * The clock running at 32kHz, a tick is 1/32768 of a second. |
AnnaBridge | 167:e84263d55307 | 53 | */ |
AnnaBridge | 167:e84263d55307 | 54 | static inline uint32_t ticks_to_us(uint16_t ticks) { |
AnnaBridge | 167:e84263d55307 | 55 | return (((uint64_t)ticks * RTC_SEC_TO_US) / RTC_CLOCK_HZ); |
AnnaBridge | 167:e84263d55307 | 56 | } |
AnnaBridge | 167:e84263d55307 | 57 | |
AnnaBridge | 167:e84263d55307 | 58 | /** |
AnnaBridge | 167:e84263d55307 | 59 | * Convert us into sub seconds ticks. |
AnnaBridge | 167:e84263d55307 | 60 | * @note result might be troncated to be in the range [0 - RTC_SUB_SEC_MASK]. |
AnnaBridge | 167:e84263d55307 | 61 | */ |
AnnaBridge | 167:e84263d55307 | 62 | static inline uint16_t us_to_ticks(uint32_t us) { |
AnnaBridge | 167:e84263d55307 | 63 | return (((uint64_t) us * RTC_CLOCK_HZ) / RTC_SEC_TO_US) & RTC_SUB_SEC_MASK; |
AnnaBridge | 167:e84263d55307 | 64 | } |
AnnaBridge | 167:e84263d55307 | 65 | |
AnnaBridge | 167:e84263d55307 | 66 | #define RTC_TICK_THRESHOLD 5 |
<> | 149:156823d33999 | 67 | |
<> | 149:156823d33999 | 68 | /* See rtc.h for details */ |
<> | 149:156823d33999 | 69 | void fRtcInit(void) |
<> | 149:156823d33999 | 70 | { |
<> | 149:156823d33999 | 71 | CLOCK_ENABLE(CLOCK_RTC); /* enable rtc peripheral */ |
<> | 149:156823d33999 | 72 | CLOCKREG->CCR.BITS.RTCEN = True; /* Enable RTC clock 32K */ |
<> | 149:156823d33999 | 73 | |
<> | 149:156823d33999 | 74 | /* Reset RTC control register */ |
AnnaBridge | 167:e84263d55307 | 75 | RTCREG->CONTROL.WORD = 0; |
<> | 149:156823d33999 | 76 | |
<> | 149:156823d33999 | 77 | /* Initialize all counters */ |
AnnaBridge | 167:e84263d55307 | 78 | RTCREG->SECOND_COUNTER = 0; |
AnnaBridge | 167:e84263d55307 | 79 | RTCREG->SUB_SECOND_COUNTER = 0; |
AnnaBridge | 167:e84263d55307 | 80 | RTCREG->SECOND_ALARM = 0; |
AnnaBridge | 167:e84263d55307 | 81 | RTCREG->SUB_SECOND_ALARM = 0; |
AnnaBridge | 167:e84263d55307 | 82 | last_time_read = 0; |
<> | 149:156823d33999 | 83 | |
<> | 149:156823d33999 | 84 | /* Reset RTC Status register */ |
AnnaBridge | 167:e84263d55307 | 85 | RTCREG->STATUS.WORD = 0; |
<> | 149:156823d33999 | 86 | |
<> | 149:156823d33999 | 87 | /* Clear interrupt status */ |
AnnaBridge | 167:e84263d55307 | 88 | RTCREG->INT_CLEAR.WORD = ( |
AnnaBridge | 167:e84263d55307 | 89 | (1 << RTC_INT_CLR_SUB_SEC_BIT_POS) | |
AnnaBridge | 167:e84263d55307 | 90 | (1 << RTC_INT_CLR_SEC_BIT_POS) |
AnnaBridge | 167:e84263d55307 | 91 | ); |
<> | 149:156823d33999 | 92 | |
AnnaBridge | 167:e84263d55307 | 93 | /* Wait previous write to complete */ |
AnnaBridge | 167:e84263d55307 | 94 | while(RTCREG->STATUS.BITS.BSY_CTRL_REG_WRT == True); |
<> | 149:156823d33999 | 95 | /* Start sec & sub_sec counter */ |
AnnaBridge | 167:e84263d55307 | 96 | RTCREG->CONTROL.WORD |= ( |
AnnaBridge | 167:e84263d55307 | 97 | (True << RTC_CONTROL_SUBSEC_CNT_START_BIT_POS) | |
AnnaBridge | 167:e84263d55307 | 98 | (True << RTC_CONTROL_SEC_CNT_START_BIT_POS) |
AnnaBridge | 167:e84263d55307 | 99 | ); |
<> | 149:156823d33999 | 100 | |
<> | 149:156823d33999 | 101 | /* enable interruption associated with the rtc at NVIC level */ |
AnnaBridge | 167:e84263d55307 | 102 | NVIC_SetVector(Rtc_IRQn,(uint32_t) fRtcHandler); /* TODO define lp_ticker_isr */ |
<> | 149:156823d33999 | 103 | NVIC_ClearPendingIRQ(Rtc_IRQn); |
<> | 149:156823d33999 | 104 | NVIC_EnableIRQ(Rtc_IRQn); |
<> | 149:156823d33999 | 105 | |
AnnaBridge | 167:e84263d55307 | 106 | /* Wait for RTC to finish writing register */ |
AnnaBridge | 167:e84263d55307 | 107 | while(RTCREG->STATUS.BITS.BSY_CTRL_REG_WRT == True); |
<> | 149:156823d33999 | 108 | } |
<> | 149:156823d33999 | 109 | |
<> | 149:156823d33999 | 110 | /* See rtc.h for details */ |
<> | 149:156823d33999 | 111 | void fRtcFree(void) |
<> | 149:156823d33999 | 112 | { |
AnnaBridge | 167:e84263d55307 | 113 | /* Disable interrupts and counter */ |
AnnaBridge | 167:e84263d55307 | 114 | RTCREG->CONTROL.WORD = 0; |
<> | 149:156823d33999 | 115 | |
<> | 149:156823d33999 | 116 | /* disable interruption associated with the rtc */ |
<> | 149:156823d33999 | 117 | NVIC_DisableIRQ(Rtc_IRQn); |
<> | 149:156823d33999 | 118 | |
AnnaBridge | 167:e84263d55307 | 119 | /* Wait for RTC to finish writing register */ |
AnnaBridge | 167:e84263d55307 | 120 | while(RTCREG->STATUS.BITS.BSY_CTRL_REG_WRT == True); |
<> | 149:156823d33999 | 121 | } |
<> | 149:156823d33999 | 122 | |
<> | 149:156823d33999 | 123 | /* See rtc.h for details */ |
<> | 149:156823d33999 | 124 | void fRtcSetInterrupt(uint32_t timestamp) |
<> | 149:156823d33999 | 125 | { |
AnnaBridge | 167:e84263d55307 | 126 | uint64_t current_time = fRtcRead(); |
<> | 149:156823d33999 | 127 | |
AnnaBridge | 167:e84263d55307 | 128 | /* compute delta between current time and timestamp. |
AnnaBridge | 167:e84263d55307 | 129 | * Note: the current time used to compute the delta is relative (truncated |
AnnaBridge | 167:e84263d55307 | 130 | * to 32 bits). |
AnnaBridge | 167:e84263d55307 | 131 | */ |
AnnaBridge | 167:e84263d55307 | 132 | int32_t delta = timestamp - (uint32_t) current_time; |
AnnaBridge | 167:e84263d55307 | 133 | if (delta <= 0) { |
AnnaBridge | 167:e84263d55307 | 134 | // event considered in the past, set the interrupt as pending. |
AnnaBridge | 167:e84263d55307 | 135 | NVIC_SetPendingIRQ(Rtc_IRQn); |
AnnaBridge | 167:e84263d55307 | 136 | return; |
AnnaBridge | 167:e84263d55307 | 137 | } |
<> | 149:156823d33999 | 138 | |
AnnaBridge | 167:e84263d55307 | 139 | uint64_t full_timestamp = (current_time & ~UINT32_MAX) | timestamp; |
AnnaBridge | 167:e84263d55307 | 140 | if ( (uint32_t)current_time > timestamp) { |
AnnaBridge | 167:e84263d55307 | 141 | full_timestamp += ((uint64_t) UINT32_MAX) + 1; |
AnnaBridge | 167:e84263d55307 | 142 | } |
<> | 149:156823d33999 | 143 | |
AnnaBridge | 167:e84263d55307 | 144 | uint32_t target_seconds = full_timestamp / RTC_SEC_TO_US; |
AnnaBridge | 167:e84263d55307 | 145 | uint16_t target_ticks = us_to_ticks(full_timestamp); |
<> | 149:156823d33999 | 146 | |
AnnaBridge | 167:e84263d55307 | 147 | /* |
AnnaBridge | 167:e84263d55307 | 148 | * If the interrupt is in more than one second from now then use the |
AnnaBridge | 167:e84263d55307 | 149 | * second alarm, otherwise use the subsecond alarm. |
AnnaBridge | 167:e84263d55307 | 150 | * In case of the second alarm is used, there is no need to preserve the |
AnnaBridge | 167:e84263d55307 | 151 | * remaining subsecond because the irq handler should manage spurious |
AnnaBridge | 167:e84263d55307 | 152 | * interrupts (like when the timestamp is in the past). In such case, irq |
AnnaBridge | 167:e84263d55307 | 153 | * handler will schedule a new interrupt with the remaining us. |
AnnaBridge | 167:e84263d55307 | 154 | */ |
AnnaBridge | 167:e84263d55307 | 155 | NVIC_DisableIRQ(Rtc_IRQn); |
AnnaBridge | 167:e84263d55307 | 156 | if (target_seconds != RTCREG->SECOND_COUNTER) { |
AnnaBridge | 167:e84263d55307 | 157 | RTCREG->SECOND_ALARM = target_seconds; |
<> | 149:156823d33999 | 158 | |
AnnaBridge | 167:e84263d55307 | 159 | uint32_t rtc_control = RTCREG->CONTROL.WORD; |
AnnaBridge | 167:e84263d55307 | 160 | rtc_control |= (1 << RTC_CONTROL_SEC_CNT_INT_BIT_POS); // enable seconds interrupt |
AnnaBridge | 167:e84263d55307 | 161 | rtc_control &= ~(1 << RTC_CONTROL_SUBSEC_CNT_INT_BIT_POS); // disable sub sec interrupt |
AnnaBridge | 167:e84263d55307 | 162 | RTCREG->CONTROL.WORD = rtc_control; |
AnnaBridge | 167:e84263d55307 | 163 | } else { |
AnnaBridge | 167:e84263d55307 | 164 | uint16_t current_ticks = RTCREG->SUB_SECOND_COUNTER; |
AnnaBridge | 167:e84263d55307 | 165 | if (current_ticks == target_ticks || |
AnnaBridge | 167:e84263d55307 | 166 | ((target_ticks > current_ticks) && ((target_ticks - current_ticks) < RTC_TICK_THRESHOLD)) || |
AnnaBridge | 167:e84263d55307 | 167 | ((target_ticks < current_ticks) && ((RTC_SUB_SEC_MASK - (current_ticks - target_ticks)) < RTC_TICK_THRESHOLD))) { |
AnnaBridge | 167:e84263d55307 | 168 | // target ticks too close; schedule the interrupt immediately |
AnnaBridge | 167:e84263d55307 | 169 | NVIC_SetPendingIRQ(Rtc_IRQn); |
AnnaBridge | 167:e84263d55307 | 170 | } else { |
AnnaBridge | 167:e84263d55307 | 171 | RTCREG->SUB_SECOND_ALARM = target_ticks; |
AnnaBridge | 167:e84263d55307 | 172 | |
AnnaBridge | 167:e84263d55307 | 173 | uint32_t rtc_control = RTCREG->CONTROL.WORD; |
AnnaBridge | 167:e84263d55307 | 174 | rtc_control &= ~(1 << RTC_CONTROL_SEC_CNT_INT_BIT_POS); // disable seconds interrupt |
AnnaBridge | 167:e84263d55307 | 175 | rtc_control |= (1 << RTC_CONTROL_SUBSEC_CNT_INT_BIT_POS); // enable sub sec interrupt |
AnnaBridge | 167:e84263d55307 | 176 | RTCREG->CONTROL.WORD = rtc_control; |
AnnaBridge | 167:e84263d55307 | 177 | } |
AnnaBridge | 167:e84263d55307 | 178 | } |
AnnaBridge | 167:e84263d55307 | 179 | NVIC_EnableIRQ(Rtc_IRQn); |
AnnaBridge | 167:e84263d55307 | 180 | |
AnnaBridge | 167:e84263d55307 | 181 | /* Wait for RTC to finish writing register - RTC operates on 32K clock as compared to 32M core*/ |
AnnaBridge | 167:e84263d55307 | 182 | while(RTCREG->STATUS.WORD & |
AnnaBridge | 167:e84263d55307 | 183 | ( |
AnnaBridge | 167:e84263d55307 | 184 | (True << RTC_STATUS_SUB_SEC_ALARM_WRT_BIT_POS) | |
AnnaBridge | 167:e84263d55307 | 185 | (True << RTC_STATUS_SEC_ALARM_WRT_BIT_POS) | |
AnnaBridge | 167:e84263d55307 | 186 | (True << RTC_STATUS_CONTROL_WRT_BIT_POS) |
AnnaBridge | 167:e84263d55307 | 187 | ) |
AnnaBridge | 167:e84263d55307 | 188 | ); |
<> | 149:156823d33999 | 189 | } |
<> | 149:156823d33999 | 190 | |
<> | 149:156823d33999 | 191 | /* See rtc.h for details */ |
<> | 149:156823d33999 | 192 | void fRtcDisableInterrupt(void) |
<> | 149:156823d33999 | 193 | { |
<> | 150:02e0a0aed4ec | 194 | NVIC_DisableIRQ(Rtc_IRQn); |
<> | 149:156823d33999 | 195 | } |
<> | 149:156823d33999 | 196 | |
<> | 149:156823d33999 | 197 | /* See rtc.h for details */ |
<> | 149:156823d33999 | 198 | void fRtcEnableInterrupt(void) |
<> | 149:156823d33999 | 199 | { |
<> | 150:02e0a0aed4ec | 200 | NVIC_EnableIRQ(Rtc_IRQn); |
<> | 149:156823d33999 | 201 | } |
<> | 149:156823d33999 | 202 | |
<> | 149:156823d33999 | 203 | /* See rtc.h for details */ |
<> | 149:156823d33999 | 204 | void fRtcClearInterrupt(void) |
<> | 149:156823d33999 | 205 | { |
<> | 149:156823d33999 | 206 | /* Disable subsec/sec interrupt */ |
<> | 149:156823d33999 | 207 | /* Clear sec & sub_sec interrupts */ |
<> | 149:156823d33999 | 208 | RTCREG->INT_CLEAR.WORD = ((True << RTC_INT_CLR_SUB_SEC_BIT_POS) | |
<> | 149:156823d33999 | 209 | (True << RTC_INT_CLR_SEC_BIT_POS)); |
<> | 150:02e0a0aed4ec | 210 | |
<> | 150:02e0a0aed4ec | 211 | while((RTCREG->STATUS.WORD & ((True << RTC_STATUS_SUB_SEC_INT_CLR_WRT_BIT_POS) | |
AnnaBridge | 167:e84263d55307 | 212 | (True << RTC_STATUS_SEC_INT_CLR_WRT_BIT_POS)))); /* Wait for RTC to finish writing register - RTC operates on 32K clock as compared to 32M core*/ |
<> | 149:156823d33999 | 213 | } |
<> | 149:156823d33999 | 214 | |
<> | 149:156823d33999 | 215 | /* See rtc.h for details */ |
<> | 149:156823d33999 | 216 | uint64_t fRtcRead(void) |
<> | 149:156823d33999 | 217 | { |
<> | 149:156823d33999 | 218 | /* Hardware Bug fix: The rollover of the sub-second counter initiates the increment of the second counter. |
<> | 149:156823d33999 | 219 | * That means there is one cycle where the sub-second has rolled back to zero and the second counter has not incremented |
<> | 149:156823d33999 | 220 | * and a read during that cycle will be incorrect. That will occur for one RTC cycle and that is about 31us of exposure. |
<> | 149:156823d33999 | 221 | * If you read a zero in the sub-second counter then increment the second counter by 1. |
<> | 149:156823d33999 | 222 | * Alternatively, subtract 1 from the Sub-seconds counter to align the Second and Sub-Second rollover. |
<> | 149:156823d33999 | 223 | */ |
AnnaBridge | 167:e84263d55307 | 224 | uint32_t seconds = RTCREG->SECOND_COUNTER; |
AnnaBridge | 167:e84263d55307 | 225 | uint16_t ticks = (RTCREG->SUB_SECOND_COUNTER - 1) & SUB_SEC_MASK; |
<> | 149:156823d33999 | 226 | |
AnnaBridge | 167:e84263d55307 | 227 | /* |
AnnaBridge | 167:e84263d55307 | 228 | * If seconds has changed while reading ticks, read them both again. |
AnnaBridge | 167:e84263d55307 | 229 | */ |
AnnaBridge | 167:e84263d55307 | 230 | while (seconds != RTCREG->SECOND_COUNTER) { |
AnnaBridge | 167:e84263d55307 | 231 | seconds = RTCREG->SECOND_COUNTER; |
AnnaBridge | 167:e84263d55307 | 232 | ticks = (RTCREG->SUB_SECOND_COUNTER - 1) & SUB_SEC_MASK; |
AnnaBridge | 167:e84263d55307 | 233 | } |
<> | 149:156823d33999 | 234 | |
AnnaBridge | 167:e84263d55307 | 235 | uint64_t current_time = ((uint64_t) seconds * RTC_SEC_TO_US) + ticks_to_us(ticks); |
<> | 149:156823d33999 | 236 | |
<> | 149:156823d33999 | 237 | /*check that the time did not go backwards */ |
AnnaBridge | 167:e84263d55307 | 238 | MBED_ASSERT(current_time >= last_time_read); |
AnnaBridge | 167:e84263d55307 | 239 | last_time_read = current_time; |
<> | 149:156823d33999 | 240 | |
AnnaBridge | 167:e84263d55307 | 241 | return current_time; |
<> | 149:156823d33999 | 242 | } |
<> | 149:156823d33999 | 243 | |
<> | 149:156823d33999 | 244 | /* See rtc.h for details */ |
<> | 149:156823d33999 | 245 | void fRtcWrite(uint64_t RtcTimeus) |
<> | 149:156823d33999 | 246 | { |
<> | 150:02e0a0aed4ec | 247 | uint32_t Second = False; |
<> | 150:02e0a0aed4ec | 248 | uint16_t SubSecond = False; |
<> | 149:156823d33999 | 249 | /* Stop RTC */ |
<> | 149:156823d33999 | 250 | RTCREG->CONTROL.WORD &= ~((True << RTC_CONTROL_SUBSEC_CNT_START_BIT_POS) | |
<> | 149:156823d33999 | 251 | (True << RTC_CONTROL_SEC_CNT_START_BIT_POS)); |
<> | 149:156823d33999 | 252 | |
<> | 149:156823d33999 | 253 | if(RtcTimeus > RTC_SEC_TO_US) { |
<> | 149:156823d33999 | 254 | /* TimeStamp is big enough to set second counter */ |
<> | 149:156823d33999 | 255 | Second = ((RtcTimeus / RTC_SEC_TO_US) & RTC_SEC_MASK); |
<> | 149:156823d33999 | 256 | } |
<> | 149:156823d33999 | 257 | RTCREG->SECOND_COUNTER = Second; |
<> | 149:156823d33999 | 258 | RtcTimeus = RtcTimeus - (Second * RTC_SEC_TO_US); |
<> | 149:156823d33999 | 259 | if(RtcTimeus > False) { |
<> | 149:156823d33999 | 260 | /* Convert TimeStamp to sub_seconds */ |
<> | 149:156823d33999 | 261 | SubSecond = (uint16_t)((float)(RtcTimeus * RTC_CLOCK_HZ / RTC_SEC_TO_US)) & RTC_SUB_SEC_MASK; |
<> | 149:156823d33999 | 262 | } |
<> | 149:156823d33999 | 263 | /* Set SUB_SEC_ALARM */ |
<> | 149:156823d33999 | 264 | RTCREG->SUB_SECOND_COUNTER = SubSecond; |
<> | 149:156823d33999 | 265 | |
<> | 149:156823d33999 | 266 | 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*/ |
<> | 149:156823d33999 | 267 | /* Start RTC */ |
<> | 149:156823d33999 | 268 | RTCREG->CONTROL.WORD |= ((True << RTC_CONTROL_SUBSEC_CNT_START_BIT_POS) | |
<> | 149:156823d33999 | 269 | (True << RTC_CONTROL_SEC_CNT_START_BIT_POS)); |
<> | 149:156823d33999 | 270 | |
<> | 149:156823d33999 | 271 | 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*/ |
<> | 149:156823d33999 | 272 | } |
<> | 149:156823d33999 | 273 | |
<> | 149:156823d33999 | 274 | /* See rtc.h for details */ |
<> | 149:156823d33999 | 275 | void fRtcHandler(void) |
<> | 149:156823d33999 | 276 | { |
<> | 149:156823d33999 | 277 | /* Disable RTC interrupt */ |
<> | 149:156823d33999 | 278 | NVIC_DisableIRQ(Rtc_IRQn); |
<> | 149:156823d33999 | 279 | |
<> | 149:156823d33999 | 280 | /* Clear sec & sub_sec interrupts */ |
AnnaBridge | 167:e84263d55307 | 281 | RTCREG->INT_CLEAR.WORD = ( |
AnnaBridge | 167:e84263d55307 | 282 | (True << RTC_INT_CLR_SUB_SEC_BIT_POS) | |
AnnaBridge | 167:e84263d55307 | 283 | (True << RTC_INT_CLR_SEC_BIT_POS) |
AnnaBridge | 167:e84263d55307 | 284 | ); |
<> | 149:156823d33999 | 285 | |
AnnaBridge | 167:e84263d55307 | 286 | /* Disable sub seconds and seconds interrupts */ |
AnnaBridge | 167:e84263d55307 | 287 | RTCREG->CONTROL.WORD &= ~( |
AnnaBridge | 167:e84263d55307 | 288 | (True << RTC_CONTROL_SUBSEC_CNT_INT_BIT_POS) | |
AnnaBridge | 167:e84263d55307 | 289 | (True << RTC_CONTROL_SEC_CNT_INT_BIT_POS) |
AnnaBridge | 167:e84263d55307 | 290 | ); |
<> | 149:156823d33999 | 291 | |
<> | 149:156823d33999 | 292 | NVIC_EnableIRQ(Rtc_IRQn); |
<> | 149:156823d33999 | 293 | |
AnnaBridge | 167:e84263d55307 | 294 | /* Wait for RTC to finish writing registers */ |
AnnaBridge | 167:e84263d55307 | 295 | while(RTCREG->STATUS.WORD & |
AnnaBridge | 167:e84263d55307 | 296 | ( |
AnnaBridge | 167:e84263d55307 | 297 | (True << RTC_STATUS_CONTROL_WRT_BIT_POS) | |
AnnaBridge | 167:e84263d55307 | 298 | (True << RTC_STATUS_SUB_SEC_INT_CLR_WRT_BIT_POS) | |
AnnaBridge | 167:e84263d55307 | 299 | (True << RTC_STATUS_SEC_INT_CLR_WRT_BIT_POS) |
AnnaBridge | 167:e84263d55307 | 300 | ) |
AnnaBridge | 167:e84263d55307 | 301 | ); |
<> | 149:156823d33999 | 302 | |
<> | 149:156823d33999 | 303 | lp_ticker_irq_handler(); |
<> | 149:156823d33999 | 304 | } |
<> | 149:156823d33999 | 305 | |
<> | 149:156823d33999 | 306 | boolean fIsRtcEnabled(void) |
<> | 149:156823d33999 | 307 | { |
<> | 149:156823d33999 | 308 | if(RTCREG->CONTROL.BITS.SUB_SEC_COUNTER_EN | RTCREG->CONTROL.BITS.SEC_COUNTER_EN) { |
<> | 149:156823d33999 | 309 | return True; |
<> | 149:156823d33999 | 310 | } else { |
<> | 149:156823d33999 | 311 | return False; |
<> | 149:156823d33999 | 312 | } |
<> | 149:156823d33999 | 313 | } |