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 NRFX_RTC_H__ 33 #define NRFX_RTC_H__ 34 35 #include <nrfx.h> 36 #include <hal/nrf_rtc.h> 37 38 #ifdef __cplusplus 39 extern "C" { 40 #endif 41 42 /** 43 * @defgroup nrfx_rtc RTC driver 44 * @{ 45 * @ingroup nrf_rtc 46 * @brief Real Timer Counter (RTC) peripheral driver. 47 */ 48 49 /**@brief Macro to convert microseconds into ticks. */ 50 #define NRFX_RTC_US_TO_TICKS(us,freq) (((us) * (freq)) / 1000000U) 51 52 /**@brief RTC driver interrupt types. */ 53 typedef enum 54 { 55 NRFX_RTC_INT_COMPARE0 = 0, /**< Interrupt from COMPARE0 event. */ 56 NRFX_RTC_INT_COMPARE1 = 1, /**< Interrupt from COMPARE1 event. */ 57 NRFX_RTC_INT_COMPARE2 = 2, /**< Interrupt from COMPARE2 event. */ 58 NRFX_RTC_INT_COMPARE3 = 3, /**< Interrupt from COMPARE3 event. */ 59 NRFX_RTC_INT_TICK = 4, /**< Interrupt from TICK event. */ 60 NRFX_RTC_INT_OVERFLOW = 5 /**< Interrupt from OVERFLOW event. */ 61 } nrfx_rtc_int_type_t; 62 63 /**@brief RTC driver instance structure. */ 64 typedef struct 65 { 66 NRF_RTC_Type * p_reg; /**< Pointer to instance register set. */ 67 IRQn_Type irq; /**< Instance IRQ ID. */ 68 uint8_t instance_id; /**< Instance index. */ 69 uint8_t cc_channel_count; /**< Number of capture/compare channels. */ 70 } nrfx_rtc_t; 71 72 /**@brief Macro for creating RTC driver instance.*/ 73 #define NRFX_RTC_INSTANCE(id) \ 74 { \ 75 .p_reg = NRFX_CONCAT_2(NRF_RTC, id), \ 76 .irq = NRFX_CONCAT_3(RTC, id, _IRQn), \ 77 .instance_id = NRFX_CONCAT_3(NRFX_RTC, id, _INST_IDX), \ 78 .cc_channel_count = NRF_RTC_CC_CHANNEL_COUNT(id), \ 79 } 80 81 enum { 82 #if NRFX_CHECK(NRFX_RTC0_ENABLED) 83 NRFX_RTC0_INST_IDX, 84 #endif 85 #if NRFX_CHECK(NRFX_RTC1_ENABLED) 86 NRFX_RTC1_INST_IDX, 87 #endif 88 #if NRFX_CHECK(NRFX_RTC2_ENABLED) 89 NRFX_RTC2_INST_IDX, 90 #endif 91 NRFX_RTC_ENABLED_COUNT 92 }; 93 94 /**@brief RTC driver instance configuration structure. */ 95 typedef struct 96 { 97 uint16_t prescaler; /**< Prescaler. */ 98 uint8_t interrupt_priority; /**< Interrupt priority. */ 99 uint8_t tick_latency; /**< Maximum length of interrupt handler in ticks (max 7.7 ms). */ 100 bool reliable; /**< Reliable mode flag. */ 101 } nrfx_rtc_config_t; 102 103 /**@brief RTC instance default configuration. */ 104 #define NRFX_RTC_DEFAULT_CONFIG \ 105 { \ 106 .prescaler = RTC_FREQ_TO_PRESCALER(NRFX_RTC_DEFAULT_CONFIG_FREQUENCY), \ 107 .interrupt_priority = NRFX_RTC_DEFAULT_CONFIG_IRQ_PRIORITY, \ 108 .reliable = NRFX_RTC_DEFAULT_CONFIG_RELIABLE, \ 109 .tick_latency = NRFX_RTC_US_TO_TICKS(NRFX_RTC_MAXIMUM_LATENCY_US, \ 110 NRFX_RTC_DEFAULT_CONFIG_FREQUENCY), \ 111 } 112 113 /**@brief RTC driver instance handler type. */ 114 typedef void (*nrfx_rtc_handler_t)(nrfx_rtc_int_type_t int_type); 115 116 /**@brief Function for initializing the RTC driver instance. 117 * 118 * After initialization, the instance is in power off state. 119 * 120 * @param[in] p_instance Pointer to the driver instance structure. 121 * @param[in] p_config Pointer to the structure with initial configuration. 122 * @param[in] handler Event handler provided by the user. 123 * Must not be NULL. 124 * 125 * @retval NRFX_SUCCESS If successfully initialized. 126 * @retval NRFX_ERROR_INVALID_STATE If the instance is already initialized. 127 */ 128 nrfx_err_t nrfx_rtc_init(nrfx_rtc_t const * const p_instance, 129 nrfx_rtc_config_t const * p_config, 130 nrfx_rtc_handler_t handler); 131 132 /**@brief Function for uninitializing the RTC driver instance. 133 * 134 * After uninitialization, the instance is in idle state. The hardware should return to the state 135 * before initialization. The function asserts if the instance is in idle state. 136 * 137 * @param[in] p_instance Pointer to the driver instance structure. 138 */ 139 void nrfx_rtc_uninit(nrfx_rtc_t const * const p_instance); 140 141 /**@brief Function for enabling the RTC driver instance. 142 * 143 * @note Function asserts if instance is enabled. 144 * 145 * @param[in] p_instance Pointer to the driver instance structure. 146 */ 147 void nrfx_rtc_enable(nrfx_rtc_t const * const p_instance); 148 149 /**@brief Function for disabling the RTC driver instance. 150 * 151 * @note Function asserts if instance is disabled. 152 * 153 * @param[in] p_instance Pointer to the driver instance structure. 154 */ 155 void nrfx_rtc_disable(nrfx_rtc_t const * const p_instance); 156 157 /**@brief Function for setting a compare channel. 158 * 159 * The function asserts if the instance is not initialized or if the channel parameter is 160 * wrong. The function powers on the instance if the instance was in power off state. 161 * 162 * The driver is not entering a critical section when configuring RTC, which means that it can be 163 * preempted for a certain amount of time. When the driver was preempted and the value to be set 164 * is short in time, there is a risk that the driver sets a compare value that is 165 * behind. If RTCn_CONFIG_RELIABLE is 1 for the given instance, the Reliable mode handles that case. 166 * However, to detect if the requested value is behind, this mode makes the following assumptions: 167 * - The maximum preemption time in ticks (8 - bit value) is known and is less than 7.7 ms 168 * (for prescaler = 0, RTC frequency 32 kHz). 169 * - The requested absolute compare value is not bigger than (0x00FFFFFF) - tick_latency. It is 170 * the user's responsibility to ensure that. 171 * 172 * @param[in] p_instance Pointer to the driver instance structure. 173 * @param[in] channel One of the instance's channels. 174 * @param[in] val Absolute value to be set in the compare register. 175 * @param[in] enable_irq True to enable the interrupt. False to disable the interrupt. 176 * 177 * @retval NRFX_SUCCESS If the procedure was successful. 178 * @retval NRFX_ERROR_TIMEOUT If the compare was not set because the request value is behind the current counter 179 * value. This error can only be reported if RTCn_CONFIG_RELIABLE = 1. 180 */ 181 nrfx_err_t nrfx_rtc_cc_set(nrfx_rtc_t const * const p_instance, 182 uint32_t channel, 183 uint32_t val, 184 bool enable_irq); 185 186 /**@brief Function for disabling a channel. 187 * 188 * This function disables channel events and channel interrupts. The function asserts if the instance is not 189 * initialized or if the channel parameter is wrong. 190 * 191 * @param[in] p_instance Pointer to the driver instance structure. 192 * @param[in] channel One of the instance's channels. 193 * 194 * @retval NRFX_SUCCESS If the procedure was successful. 195 * @retval NRFX_ERROR_TIMEOUT If an interrupt was pending on the requested channel. 196 */ 197 nrfx_err_t nrfx_rtc_cc_disable(nrfx_rtc_t const * const p_instance, uint32_t channel); 198 199 /**@brief Function for enabling tick. 200 * 201 * This function enables the tick event and optionally the interrupt. The function asserts if the instance is not 202 * powered on. 203 * 204 * @param[in] p_instance Pointer to the driver instance structure. 205 * @param[in] enable_irq True to enable the interrupt. False to disable the interrupt. 206 */ 207 void nrfx_rtc_tick_enable(nrfx_rtc_t const * const p_instance, bool enable_irq); 208 209 /**@brief Function for disabling tick. 210 * 211 * This function disables the tick event and interrupt. 212 * 213 * @param[in] p_instance Pointer to the driver instance structure. 214 */ 215 void nrfx_rtc_tick_disable(nrfx_rtc_t const * const p_instance); 216 217 /**@brief Function for enabling overflow. 218 * 219 * This function enables the overflow event and optionally the interrupt. The function asserts if the instance is 220 * not powered on. 221 * 222 * @param[in] p_instance Pointer to the driver instance structure. 223 * @param[in] enable_irq True to enable the interrupt. False to disable the interrupt. 224 */ 225 void nrfx_rtc_overflow_enable(nrfx_rtc_t const * const p_instance, bool enable_irq); 226 227 /**@brief Function for disabling overflow. 228 * 229 * This function disables the overflow event and interrupt. 230 * 231 * @param[in] p_instance Pointer to the driver instance structure. 232 */ 233 void nrfx_rtc_overflow_disable(nrfx_rtc_t const * const p_instance); 234 235 /**@brief Function for getting the maximum relative ticks value that can be set in the compare channel. 236 * 237 * When a stack (for example SoftDevice) is used and it occupies high priority interrupts, 238 * the application code can be interrupted at any moment for a certain period of time. 239 * If Reliable mode is enabled, the provided maximum latency is taken into account 240 * and the return value is smaller than the RTC counter resolution. 241 * If Reliable mode is disabled, the return value equals the counter resolution. 242 * 243 * @param[in] p_instance Pointer to the driver instance structure. 244 * 245 * @retval ticks Maximum ticks value. 246 */ 247 uint32_t nrfx_rtc_max_ticks_get(nrfx_rtc_t const * const p_instance); 248 249 /**@brief Function for disabling all instance interrupts. 250 * 251 * @param[in] p_instance Pointer to the driver instance structure. 252 * @param[in] p_mask Pointer to the location where the mask is filled. 253 */ 254 __STATIC_INLINE void nrfx_rtc_int_disable(nrfx_rtc_t const * const p_instance, 255 uint32_t * p_mask); 256 257 /**@brief Function for enabling instance interrupts. 258 * 259 * @param[in] p_instance Pointer to the driver instance structure. 260 * @param[in] mask Mask of interrupts to enable. 261 */ 262 __STATIC_INLINE void nrfx_rtc_int_enable(nrfx_rtc_t const * const p_instance, uint32_t mask); 263 264 /**@brief Function for retrieving the current counter value. 265 * 266 * This function asserts if the instance is not powered on or if p_val is NULL. 267 * 268 * @param[in] p_instance Pointer to the driver instance structure. 269 * 270 * @retval value Counter value. 271 */ 272 __STATIC_INLINE uint32_t nrfx_rtc_counter_get(nrfx_rtc_t const * const p_instance); 273 274 /**@brief Function for clearing the counter value. 275 * 276 * This function asserts if the instance is not powered on. 277 * 278 * @param[in] p_instance Pointer to the driver instance structure. 279 */ 280 __STATIC_INLINE void nrfx_rtc_counter_clear(nrfx_rtc_t const * const p_instance); 281 282 /**@brief Function for returning a requested task address for the RTC driver instance. 283 * 284 * This function asserts if the output pointer is NULL. The task address can be used by the PPI module. 285 * 286 * @param[in] p_instance Pointer to the instance. 287 * @param[in] task One of the peripheral tasks. 288 * 289 * @retval Address of task register. 290 */ 291 __STATIC_INLINE uint32_t nrfx_rtc_task_address_get(nrfx_rtc_t const * const p_instance, 292 nrf_rtc_task_t task); 293 294 /**@brief Function for returning a requested event address for the RTC driver instance. 295 * 296 * This function asserts if the output pointer is NULL. The event address can be used by the PPI module. 297 * 298 * @param[in] p_instance Pointer to the driver instance structure. 299 * @param[in] event One of the peripheral events. 300 * 301 * @retval Address of event register. 302 */ 303 __STATIC_INLINE uint32_t nrfx_rtc_event_address_get(nrfx_rtc_t const * const p_instance, 304 nrf_rtc_event_t event); 305 306 #ifndef SUPPRESS_INLINE_IMPLEMENTATION 307 308 __STATIC_INLINE void nrfx_rtc_int_disable(nrfx_rtc_t const * const p_instance, 309 uint32_t * p_mask) 310 { 311 *p_mask = nrf_rtc_int_get(p_instance->p_reg); 312 nrf_rtc_int_disable(p_instance->p_reg, NRF_RTC_INT_TICK_MASK | 313 NRF_RTC_INT_OVERFLOW_MASK | 314 NRF_RTC_INT_COMPARE0_MASK | 315 NRF_RTC_INT_COMPARE1_MASK | 316 NRF_RTC_INT_COMPARE2_MASK | 317 NRF_RTC_INT_COMPARE3_MASK); 318 } 319 320 __STATIC_INLINE void nrfx_rtc_int_enable(nrfx_rtc_t const * const p_instance, uint32_t mask) 321 { 322 nrf_rtc_int_enable(p_instance->p_reg, mask); 323 } 324 325 __STATIC_INLINE uint32_t nrfx_rtc_counter_get(nrfx_rtc_t const * const p_instance) 326 { 327 return nrf_rtc_counter_get(p_instance->p_reg); 328 } 329 330 __STATIC_INLINE void nrfx_rtc_counter_clear(nrfx_rtc_t const * const p_instance) 331 { 332 nrf_rtc_task_trigger(p_instance->p_reg, NRF_RTC_TASK_CLEAR); 333 } 334 335 __STATIC_INLINE uint32_t nrfx_rtc_task_address_get(nrfx_rtc_t const * const p_instance, 336 nrf_rtc_task_t task) 337 { 338 return nrf_rtc_task_address_get(p_instance->p_reg, task); 339 } 340 341 __STATIC_INLINE uint32_t nrfx_rtc_event_address_get(nrfx_rtc_t const * const p_instance, 342 nrf_rtc_event_t event) 343 { 344 return nrf_rtc_event_address_get(p_instance->p_reg, event); 345 } 346 #endif // SUPPRESS_INLINE_IMPLEMENTATION 347 348 349 void nrfx_rtc_0_irq_handler(void); 350 void nrfx_rtc_1_irq_handler(void); 351 void nrfx_rtc_2_irq_handler(void); 352 353 354 /** @} */ 355 356 #ifdef __cplusplus 357 } 358 #endif 359 360 #endif // NRFX_RTC_H__ 361