1 /* 2 * Copyright (c) 2014 - 2018, Nordic Semiconductor ASA 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright notice, this 9 * list of conditions and the following disclaimer. 10 * 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * 3. Neither the name of the copyright holder nor the names of its 16 * contributors may be used to endorse or promote products derived from this 17 * software without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 20 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 23 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 * POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32 #ifndef NRF_RTC_H 33 #define NRF_RTC_H 34 35 #include <nrfx.h> 36 37 #ifdef __cplusplus 38 extern "C" { 39 #endif 40 41 /** 42 * @defgroup nrf_rtc_hal RTC HAL 43 * @{ 44 * @ingroup nrf_rtc 45 * @brief Hardware access layer for managing the Real Time Counter (RTC) peripheral. 46 */ 47 48 /** @brief Macro for getting the number of compare channels available in a given RTC instance. */ 49 #define NRF_RTC_CC_CHANNEL_COUNT(id) NRFX_CONCAT_3(RTC, id, _CC_NUM) 50 51 #define RTC_INPUT_FREQ 32768 /**< Input frequency of the RTC instance. */ 52 53 /** @brief Macro for converting expected frequency to prescaler setting. */ 54 #define RTC_FREQ_TO_PRESCALER(FREQ) (uint16_t)(((RTC_INPUT_FREQ) / (FREQ)) - 1) 55 56 /**< Macro for wrapping values to RTC capacity. */ 57 #define RTC_WRAP(val) ((val) & RTC_COUNTER_COUNTER_Msk) 58 59 #define RTC_CHANNEL_INT_MASK(ch) \ 60 ((uint32_t)(NRF_RTC_INT_COMPARE0_MASK) << (ch)) 61 62 #define RTC_CHANNEL_EVENT_ADDR(ch) \ 63 (nrf_rtc_event_t)((NRF_RTC_EVENT_COMPARE_0) + (ch) * sizeof(uint32_t)) 64 65 /** @brief RTC tasks. */ 66 typedef enum 67 { 68 /*lint -save -e30*/ 69 NRF_RTC_TASK_START = offsetof(NRF_RTC_Type,TASKS_START), /**< Start. */ 70 NRF_RTC_TASK_STOP = offsetof(NRF_RTC_Type,TASKS_STOP), /**< Stop. */ 71 NRF_RTC_TASK_CLEAR = offsetof(NRF_RTC_Type,TASKS_CLEAR), /**< Clear. */ 72 NRF_RTC_TASK_TRIGGER_OVERFLOW = offsetof(NRF_RTC_Type,TASKS_TRIGOVRFLW),/**< Trigger overflow. */ 73 /*lint -restore*/ 74 } nrf_rtc_task_t; 75 76 /** @brief RTC events. */ 77 typedef enum 78 { 79 /*lint -save -e30*/ 80 NRF_RTC_EVENT_TICK = offsetof(NRF_RTC_Type,EVENTS_TICK), /**< Tick event. */ 81 NRF_RTC_EVENT_OVERFLOW = offsetof(NRF_RTC_Type,EVENTS_OVRFLW), /**< Overflow event. */ 82 NRF_RTC_EVENT_COMPARE_0 = offsetof(NRF_RTC_Type,EVENTS_COMPARE[0]), /**< Compare 0 event. */ 83 NRF_RTC_EVENT_COMPARE_1 = offsetof(NRF_RTC_Type,EVENTS_COMPARE[1]), /**< Compare 1 event. */ 84 NRF_RTC_EVENT_COMPARE_2 = offsetof(NRF_RTC_Type,EVENTS_COMPARE[2]), /**< Compare 2 event. */ 85 NRF_RTC_EVENT_COMPARE_3 = offsetof(NRF_RTC_Type,EVENTS_COMPARE[3]) /**< Compare 3 event. */ 86 /*lint -restore*/ 87 } nrf_rtc_event_t; 88 89 /** @brief RTC interrupts. */ 90 typedef enum 91 { 92 NRF_RTC_INT_TICK_MASK = RTC_INTENSET_TICK_Msk, /**< RTC interrupt from tick event. */ 93 NRF_RTC_INT_OVERFLOW_MASK = RTC_INTENSET_OVRFLW_Msk, /**< RTC interrupt from overflow event. */ 94 NRF_RTC_INT_COMPARE0_MASK = RTC_INTENSET_COMPARE0_Msk, /**< RTC interrupt from compare event on channel 0. */ 95 NRF_RTC_INT_COMPARE1_MASK = RTC_INTENSET_COMPARE1_Msk, /**< RTC interrupt from compare event on channel 1. */ 96 NRF_RTC_INT_COMPARE2_MASK = RTC_INTENSET_COMPARE2_Msk, /**< RTC interrupt from compare event on channel 2. */ 97 NRF_RTC_INT_COMPARE3_MASK = RTC_INTENSET_COMPARE3_Msk /**< RTC interrupt from compare event on channel 3. */ 98 } nrf_rtc_int_t; 99 100 /** 101 * @brief Function for setting a compare value for a channel. 102 * 103 * @param[in] p_reg Pointer to the structure of registers of the peripheral. 104 * @param[in] ch Channel. 105 * @param[in] cc_val Compare value to set. 106 */ 107 __STATIC_INLINE void nrf_rtc_cc_set(NRF_RTC_Type * p_reg, uint32_t ch, uint32_t cc_val); 108 109 /** 110 * @brief Function for returning the compare value for a channel. 111 * 112 * @param[in] p_reg Pointer to the structure of registers of the peripheral. 113 * @param[in] ch Channel. 114 * 115 * @return COMPARE[ch] value. 116 */ 117 __STATIC_INLINE uint32_t nrf_rtc_cc_get(NRF_RTC_Type * p_reg, uint32_t ch); 118 119 /** 120 * @brief Function for enabling interrupts. 121 * 122 * @param[in] p_reg Pointer to the structure of registers of the peripheral. 123 * @param[in] mask Interrupt mask to be enabled. 124 */ 125 __STATIC_INLINE void nrf_rtc_int_enable(NRF_RTC_Type * p_reg, uint32_t mask); 126 127 /** 128 * @brief Function for disabling interrupts. 129 * 130 * @param[in] p_reg Pointer to the structure of registers of the peripheral. 131 * @param[in] mask Interrupt mask to be disabled. 132 */ 133 __STATIC_INLINE void nrf_rtc_int_disable(NRF_RTC_Type * p_reg, uint32_t mask); 134 135 /** 136 * @brief Function for checking if interrupts are enabled. 137 * 138 * @param[in] p_reg Pointer to the structure of registers of the peripheral. 139 * @param[in] mask Mask of interrupt flags to check. 140 * 141 * @return Mask with enabled interrupts. 142 */ 143 __STATIC_INLINE uint32_t nrf_rtc_int_is_enabled(NRF_RTC_Type * p_reg, uint32_t mask); 144 145 /** 146 * @brief Function for returning the status of currently enabled interrupts. 147 * 148 * @param[in] p_reg Pointer to the structure of registers of the peripheral. 149 * 150 * @return Value in INTEN register. 151 */ 152 __STATIC_INLINE uint32_t nrf_rtc_int_get(NRF_RTC_Type * p_reg); 153 154 #if defined(DPPI_PRESENT) || defined(__NRFX_DOXYGEN__) 155 /** 156 * @brief Function for setting the subscribe configuration for a given 157 * RTC task. 158 * 159 * @param[in] p_reg Pointer to the structure of registers of the peripheral. 160 * @param[in] task Task for which to set the configuration. 161 * @param[in] channel Channel through which to subscribe events. 162 */ 163 __STATIC_INLINE void nrf_rtc_subscribe_set(NRF_RTC_Type * p_reg, 164 nrf_rtc_task_t task, 165 uint8_t channel); 166 167 /** 168 * @brief Function for clearing the subscribe configuration for a given 169 * RTC task. 170 * 171 * @param[in] p_reg Pointer to the structure of registers of the peripheral. 172 * @param[in] task Task for which to clear the configuration. 173 */ 174 __STATIC_INLINE void nrf_rtc_subscribe_clear(NRF_RTC_Type * p_reg, 175 nrf_rtc_task_t task); 176 177 /** 178 * @brief Function for setting the publish configuration for a given 179 * RTC event. 180 * 181 * @param[in] p_reg Pointer to the structure of registers of the peripheral. 182 * @param[in] event Event for which to set the configuration. 183 * @param[in] channel Channel through which to publish the event. 184 */ 185 __STATIC_INLINE void nrf_rtc_publish_set(NRF_RTC_Type * p_reg, 186 nrf_rtc_event_t event, 187 uint8_t channel); 188 189 /** 190 * @brief Function for clearing the publish configuration for a given 191 * RTC event. 192 * 193 * @param[in] p_reg Pointer to the structure of registers of the peripheral. 194 * @param[in] event Event for which to clear the configuration. 195 */ 196 __STATIC_INLINE void nrf_rtc_publish_clear(NRF_RTC_Type * p_reg, 197 nrf_rtc_event_t event); 198 #endif // defined(DPPI_PRESENT) || defined(__NRFX_DOXYGEN__) 199 200 /** 201 * @brief Function for checking if an event is pending. 202 * 203 * @param[in] p_reg Pointer to the structure of registers of the peripheral. 204 * @param[in] event Address of the event. 205 * 206 * @return Mask of pending events. 207 */ 208 __STATIC_INLINE uint32_t nrf_rtc_event_pending(NRF_RTC_Type * p_reg, nrf_rtc_event_t event); 209 210 /** 211 * @brief Function for clearing an event. 212 * 213 * @param[in] p_reg Pointer to the structure of registers of the peripheral. 214 * @param[in] event Event to clear. 215 */ 216 __STATIC_INLINE void nrf_rtc_event_clear(NRF_RTC_Type * p_reg, nrf_rtc_event_t event); 217 218 /** 219 * @brief Function for returning a counter value. 220 * 221 * @param[in] p_reg Pointer to the structure of registers of the peripheral. 222 * 223 * @return Counter value. 224 */ 225 __STATIC_INLINE uint32_t nrf_rtc_counter_get(NRF_RTC_Type * p_reg); 226 227 /** 228 * @brief Function for setting a prescaler value. 229 * 230 * @param[in] p_reg Pointer to the structure of registers of the peripheral. 231 * @param[in] val Value to set the prescaler to. 232 */ 233 __STATIC_INLINE void nrf_rtc_prescaler_set(NRF_RTC_Type * p_reg, uint32_t val); 234 235 /** 236 * @brief Function for returning the address of an event. 237 * 238 * @param[in] p_reg Pointer to the structure of registers of the peripheral. 239 * @param[in] event Requested event. 240 * 241 * @return Address of the requested event register. 242 */ 243 __STATIC_INLINE uint32_t nrf_rtc_event_address_get(NRF_RTC_Type * p_reg, nrf_rtc_event_t event); 244 245 /** 246 * @brief Function for returning the address of a task. 247 * 248 * @param[in] p_reg Pointer to the structure of registers of the peripheral. 249 * @param[in] task Requested task. 250 * 251 * @return Address of the requested task register. 252 */ 253 __STATIC_INLINE uint32_t nrf_rtc_task_address_get(NRF_RTC_Type * p_reg, nrf_rtc_task_t task); 254 255 /** 256 * @brief Function for starting a task. 257 * 258 * @param[in] p_reg Pointer to the structure of registers of the peripheral. 259 * @param[in] task Requested task. 260 */ 261 __STATIC_INLINE void nrf_rtc_task_trigger(NRF_RTC_Type * p_reg, nrf_rtc_task_t task); 262 263 /** 264 * @brief Function for enabling events. 265 * 266 * @param[in] p_reg Pointer to the structure of registers of the peripheral. 267 * @param[in] mask Mask of event flags to enable. 268 */ 269 __STATIC_INLINE void nrf_rtc_event_enable(NRF_RTC_Type * p_reg, uint32_t mask); 270 271 /** 272 * @brief Function for disabling an event. 273 * 274 * @param[in] p_reg Pointer to the structure of registers of the peripheral. 275 * @param[in] event Requested event. 276 */ 277 __STATIC_INLINE void nrf_rtc_event_disable(NRF_RTC_Type * p_reg, uint32_t event); 278 279 280 #ifndef SUPPRESS_INLINE_IMPLEMENTATION 281 282 __STATIC_INLINE void nrf_rtc_cc_set(NRF_RTC_Type * p_reg, uint32_t ch, uint32_t cc_val) 283 { 284 p_reg->CC[ch] = cc_val; 285 } 286 287 __STATIC_INLINE uint32_t nrf_rtc_cc_get(NRF_RTC_Type * p_reg, uint32_t ch) 288 { 289 return p_reg->CC[ch]; 290 } 291 292 __STATIC_INLINE void nrf_rtc_int_enable(NRF_RTC_Type * p_reg, uint32_t mask) 293 { 294 p_reg->INTENSET = mask; 295 } 296 297 __STATIC_INLINE void nrf_rtc_int_disable(NRF_RTC_Type * p_reg, uint32_t mask) 298 { 299 p_reg->INTENCLR = mask; 300 } 301 302 __STATIC_INLINE uint32_t nrf_rtc_int_is_enabled(NRF_RTC_Type * p_reg, uint32_t mask) 303 { 304 return (p_reg->INTENSET & mask); 305 } 306 307 __STATIC_INLINE uint32_t nrf_rtc_int_get(NRF_RTC_Type * p_reg) 308 { 309 return p_reg->INTENSET; 310 } 311 312 #if defined(DPPI_PRESENT) 313 __STATIC_INLINE void nrf_rtc_subscribe_set(NRF_RTC_Type * p_reg, 314 nrf_rtc_task_t task, 315 uint8_t channel) 316 { 317 *((volatile uint32_t *) ((uint8_t *) p_reg + (uint32_t) task + 0x80uL)) = 318 ((uint32_t)channel | RTC_SUBSCRIBE_START_EN_Msk); 319 } 320 321 __STATIC_INLINE void nrf_rtc_subscribe_clear(NRF_RTC_Type * p_reg, 322 nrf_rtc_task_t task) 323 { 324 *((volatile uint32_t *) ((uint8_t *) p_reg + (uint32_t) task + 0x80uL)) = 0; 325 } 326 327 __STATIC_INLINE void nrf_rtc_publish_set(NRF_RTC_Type * p_reg, 328 nrf_rtc_event_t event, 329 uint8_t channel) 330 { 331 *((volatile uint32_t *) ((uint8_t *) p_reg + (uint32_t) event + 0x80uL)) = 332 ((uint32_t)channel | RTC_PUBLISH_TICK_EN_Msk); 333 } 334 335 __STATIC_INLINE void nrf_rtc_publish_clear(NRF_RTC_Type * p_reg, 336 nrf_rtc_event_t event) 337 { 338 *((volatile uint32_t *) ((uint8_t *) p_reg + (uint32_t) event + 0x80uL)) = 0; 339 } 340 #endif // defined(DPPI_PRESENT) 341 342 __STATIC_INLINE uint32_t nrf_rtc_event_pending(NRF_RTC_Type * p_reg, nrf_rtc_event_t event) 343 { 344 return *(volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)event); 345 } 346 347 __STATIC_INLINE void nrf_rtc_event_clear(NRF_RTC_Type * p_reg, nrf_rtc_event_t event) 348 { 349 *((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)event)) = 0; 350 #if __CORTEX_M == 0x04 351 volatile uint32_t dummy = *((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)event)); 352 (void)dummy; 353 #endif 354 } 355 356 __STATIC_INLINE uint32_t nrf_rtc_counter_get(NRF_RTC_Type * p_reg) 357 { 358 return p_reg->COUNTER; 359 } 360 361 __STATIC_INLINE void nrf_rtc_prescaler_set(NRF_RTC_Type * p_reg, uint32_t val) 362 { 363 NRFX_ASSERT(val <= (RTC_PRESCALER_PRESCALER_Msk >> RTC_PRESCALER_PRESCALER_Pos)); 364 p_reg->PRESCALER = val; 365 } 366 __STATIC_INLINE uint32_t rtc_prescaler_get(NRF_RTC_Type * p_reg) 367 { 368 return p_reg->PRESCALER; 369 } 370 371 __STATIC_INLINE uint32_t nrf_rtc_event_address_get(NRF_RTC_Type * p_reg, nrf_rtc_event_t event) 372 { 373 return (uint32_t)p_reg + event; 374 } 375 376 __STATIC_INLINE uint32_t nrf_rtc_task_address_get(NRF_RTC_Type * p_reg, nrf_rtc_task_t task) 377 { 378 return (uint32_t)p_reg + task; 379 } 380 381 __STATIC_INLINE void nrf_rtc_task_trigger(NRF_RTC_Type * p_reg, nrf_rtc_task_t task) 382 { 383 *(__IO uint32_t *)((uint32_t)p_reg + task) = 1; 384 } 385 386 __STATIC_INLINE void nrf_rtc_event_enable(NRF_RTC_Type * p_reg, uint32_t mask) 387 { 388 p_reg->EVTENSET = mask; 389 } 390 __STATIC_INLINE void nrf_rtc_event_disable(NRF_RTC_Type * p_reg, uint32_t mask) 391 { 392 p_reg->EVTENCLR = mask; 393 } 394 #endif 395 396 /** @} */ 397 398 #ifdef __cplusplus 399 } 400 #endif 401 402 #endif /* NRF_RTC_H */ 403