1 /* 2 * Copyright (c) 2016-2020 Nordic Semiconductor ASA 3 * 4 * SPDX-License-Identifier: Apache-2.0 5 */ 6 7 #ifndef ZEPHYR_INCLUDE_DRIVERS_TIMER_NRF_RTC_TIMER_H 8 #define ZEPHYR_INCLUDE_DRIVERS_TIMER_NRF_RTC_TIMER_H 9 10 #include <zephyr/sys_clock.h> 11 12 #ifdef __cplusplus 13 extern "C" { 14 #endif 15 16 /** @brief Maximum allowed time span that is considered to be in the future. 17 */ 18 #define NRF_RTC_TIMER_MAX_SCHEDULE_SPAN BIT(23) 19 20 /** @brief RTC timer compare event handler. 21 * 22 * Called from RTC ISR context when processing a compare event. 23 * 24 * @param id Compare channel ID. 25 * 26 * @param expire_time An actual absolute expiration time set for a compare 27 * channel. It can differ from the requested target time 28 * and the difference can be used to determine whether the 29 * time set was delayed. 30 * 31 * @param user_data Pointer to a user context data. 32 */ 33 typedef void (*z_nrf_rtc_timer_compare_handler_t)(int32_t id, 34 uint64_t expire_time, 35 void *user_data); 36 37 /** @brief Allocate RTC compare channel. 38 * 39 * Channel 0 is used for the system clock. 40 * 41 * @retval Non-negative indicates allocated channel ID. 42 * @retval -ENOMEM if channel cannot be allocated. 43 */ 44 int32_t z_nrf_rtc_timer_chan_alloc(void); 45 46 /** @brief Free RTC compare channel. 47 * 48 * @param chan Previously allocated channel ID. 49 */ 50 void z_nrf_rtc_timer_chan_free(int32_t chan); 51 52 /** @brief Read current absolute time. 53 * 54 * @return Current absolute time. 55 */ 56 uint64_t z_nrf_rtc_timer_read(void); 57 58 /** @brief Get COMPARE event register address. 59 * 60 * Address can be used for (D)PPI. 61 * 62 * @param chan Channel ID between 0 and CONFIG_NRF_RTC_TIMER_USER_CHAN_COUNT. 63 * 64 * @return Register address. 65 */ 66 uint32_t z_nrf_rtc_timer_compare_evt_address_get(int32_t chan); 67 68 /** @brief Get CAPTURE task register address. 69 * 70 * Address can be used for (D)PPI. 71 * 72 * @note Not all platforms have CAPTURE task. 73 * 74 * @param chan Channel ID between 1 and CONFIG_NRF_RTC_TIMER_USER_CHAN_COUNT. 75 * 76 * @return Register address. 77 */ 78 uint32_t z_nrf_rtc_timer_capture_task_address_get(int32_t chan); 79 80 /** @brief Safely disable compare event interrupt. 81 * 82 * Function returns key indicating whether interrupt was already disabled. 83 * 84 * @param chan Channel ID between 1 and CONFIG_NRF_RTC_TIMER_USER_CHAN_COUNT. 85 * 86 * @return key passed to @ref z_nrf_rtc_timer_compare_int_unlock. 87 */ 88 bool z_nrf_rtc_timer_compare_int_lock(int32_t chan); 89 90 /** @brief Safely enable compare event interrupt. 91 * 92 * Event interrupt is conditionally enabled based on @p key. 93 * 94 * @param chan Channel ID between 1 and CONFIG_NRF_RTC_TIMER_USER_CHAN_COUNT. 95 * 96 * @param key Key returned by @ref z_nrf_rtc_timer_compare_int_lock. 97 */ 98 void z_nrf_rtc_timer_compare_int_unlock(int32_t chan, bool key); 99 100 /** @brief Read compare register value. 101 * 102 * @param chan Channel ID between 0 and CONFIG_NRF_RTC_TIMER_USER_CHAN_COUNT. 103 * 104 * @return Value set in the compare register. 105 */ 106 uint32_t z_nrf_rtc_timer_compare_read(int32_t chan); 107 108 /** @brief Try to set compare channel to given value. 109 * 110 * Provided value is absolute and cannot be further in the future than 111 * @c NRF_RTC_TIMER_MAX_SCHEDULE_SPAN. If given value is in the past then an RTC 112 * interrupt is triggered immediately. Otherwise function continuously retries 113 * to set compare register until value that is written is far enough in the 114 * future and will generate an event. Because of that, compare register value 115 * may be different than the one requested. During this operation interrupt 116 * from that compare channel is disabled. Other interrupts are not locked during 117 * this operation. 118 * 119 * @param chan Channel ID between 1 and CONFIG_NRF_RTC_TIMER_USER_CHAN_COUNT. 120 * 121 * @param target_time Absolute target time in ticks. 122 * 123 * @param handler User function called in the context of the RTC interrupt. 124 * 125 * @param user_data Data passed to the handler. 126 * 127 * @retval 0 if the compare channel was set successfully. 128 * @retval -EINVAL if provided target time was further than 129 * @c NRF_RTC_TIMER_MAX_SCHEDULE_SPAN ticks in the future. 130 * 131 * @sa @ref z_nrf_rtc_timer_exact_set 132 */ 133 int z_nrf_rtc_timer_set(int32_t chan, uint64_t target_time, 134 z_nrf_rtc_timer_compare_handler_t handler, 135 void *user_data); 136 137 /** @brief Try to set compare channel exactly to given value. 138 * 139 * @note This function is similar to @ref z_nrf_rtc_timer_set, but the compare 140 * channel will be set to expected value only when it can be guaranteed that 141 * the hardware event will be generated exactly at expected @c target_time in 142 * the future. If the @c target_time is in the past or so close in the future 143 * that the reliable generation of event would require adjustment of compare 144 * value (as would @ref z_nrf_rtc_timer_set function do), neither the hardware 145 * event nor interrupt will be generated and the function fails. 146 * 147 * @param chan Channel ID between 1 and CONFIG_NRF_RTC_TIMER_USER_CHAN_COUNT. 148 * 149 * @param target_time Absolute target time in ticks. 150 * 151 * @param handler User function called in the context of the RTC interrupt. 152 * 153 * @param user_data Data passed to the handler. 154 * 155 * @retval 0 if the compare channel was set successfully. 156 * @retval -EINVAL if provided target time was further than 157 * @c NRF_RTC_TIMER_MAX_SCHEDULE_SPAN ticks in the future 158 * or the target time is in the past or is so close in the future that 159 * event generation could not be guaranteed without adjusting 160 * compare value of that channel. 161 */ 162 int z_nrf_rtc_timer_exact_set(int32_t chan, uint64_t target_time, 163 z_nrf_rtc_timer_compare_handler_t handler, 164 void *user_data); 165 166 /** @brief Abort a timer requested with @ref z_nrf_rtc_timer_set. 167 * 168 * If an abort operation is performed too late it is still possible for an event 169 * to fire. The user can detect a spurious event by comparing absolute time 170 * provided in callback and a result of @ref z_nrf_rtc_timer_read. During this 171 * operation interrupt from that compare channel is disabled. Other interrupts 172 * are not locked during this operation. 173 * 174 * @param chan Channel ID between 1 and CONFIG_NRF_RTC_TIMER_USER_CHAN_COUNT. 175 */ 176 void z_nrf_rtc_timer_abort(int32_t chan); 177 178 /** @brief Convert system clock time to RTC ticks. 179 * 180 * @p t can be absolute or relative. @p t cannot be further into the future 181 * from now than the RTC range (e.g. 512 seconds if RTC is running at 32768 Hz). 182 * 183 * @retval Positive value represents @p t in RTC tick value. 184 * @retval -EINVAL if @p t is out of range. 185 */ 186 uint64_t z_nrf_rtc_timer_get_ticks(k_timeout_t t); 187 188 /** @brief Get offset between nrf53 network cpu system clock and application cpu 189 * system clock. 190 * 191 * Returned value added to the current system tick on network cpu gives current 192 * application cpu system tick. Function can only be used on network cpu. It 193 * requires @ref CONFIG_NRF53_SYNC_RTC being enabled. 194 * 195 * @retval Non-negative offset given in RTC ticks. 196 * @retval -ENOSYS if operation is not supported. 197 * @retval -EBUSY if synchronization is not yet completed. 198 */ 199 int z_nrf_rtc_timer_nrf53net_offset_get(void); 200 201 /** @brief Move RTC counter forward using TRIGOVRFLW hardware feature. 202 * 203 * RTC has a hardware feature which can force counter to jump to 0xFFFFF0 value 204 * which is close to overflow. Function is using this feature and updates 205 * driver internal to perform time shift to the future. Operation can only be 206 * performed when there are no active alarms set. It should be used for testing 207 * only. 208 * 209 * @retval 0 on successful shift. 210 * @retval -EBUSY if there are active alarms. 211 * @retval -EAGAIN if current counter value is too close to overflow. 212 * @retval -ENOTSUP if option is disabled in Kconfig or additional channels are enabled. 213 */ 214 int z_nrf_rtc_timer_trigger_overflow(void); 215 216 #ifdef __cplusplus 217 } 218 #endif 219 220 #endif /* ZEPHYR_INCLUDE_DRIVERS_TIMER_NRF_RTC_TIMER_H */ 221