1 /* 2 * Copyright (c) 2016-2018 Nordic Semiconductor ASA 3 * Copyright (c) 2016 Vinayak Kariappa Chettimada 4 * 5 * SPDX-License-Identifier: Apache-2.0 6 */ 7 8 /** \defgroup Timer API return codes. 9 * 10 * @{ 11 */ 12 #define TICKER_STATUS_SUCCESS 0 /**< Success. */ 13 #define TICKER_STATUS_FAILURE 1 /**< Failure. */ 14 #define TICKER_STATUS_BUSY 2 /**< Busy, requested feature will 15 * complete later in time as job is 16 * disabled or at lower execution 17 * priority than the caller. 18 */ 19 /** 20 * @} 21 */ 22 23 /** \defgroup Timer API common defaults parameter values. 24 * 25 * @{ 26 */ 27 #define TICKER_NULL ((uint8_t)((uint8_t)0 - 1)) 28 #define TICKER_NULL_REMAINDER 0 29 #define TICKER_NULL_PERIOD 0 30 #define TICKER_NULL_SLOT 0 31 #define TICKER_NULL_LAZY 0 32 #define TICKER_NULL_MUST_EXPIRE 0 33 34 /** 35 * @} 36 */ 37 38 /** \brief Timer node type size. 39 */ 40 #if defined(CONFIG_BT_TICKER_EXT) 41 #if defined(CONFIG_BT_TICKER_SLOT_AGNOSTIC) 42 #define TICKER_NODE_T_SIZE 40 43 #elif defined(CONFIG_BT_TICKER_LOW_LAT) 44 #define TICKER_NODE_T_SIZE 44 45 #else 46 #define TICKER_NODE_T_SIZE 48 47 #endif /* CONFIG_BT_TICKER_SLOT_AGNOSTIC */ 48 #else /* CONFIG_BT_TICKER_EXT */ 49 #if defined(CONFIG_BT_TICKER_SLOT_AGNOSTIC) 50 #define TICKER_NODE_T_SIZE 36 51 #elif defined(CONFIG_BT_TICKER_LOW_LAT) 52 #define TICKER_NODE_T_SIZE 40 53 #else 54 #define TICKER_NODE_T_SIZE 44 55 #endif /* CONFIG_BT_TICKER_SLOT_AGNOSTIC */ 56 #endif /* CONFIG_BT_TICKER_EXT */ 57 58 /** \brief Timer user type size. 59 */ 60 #define TICKER_USER_T_SIZE 8 61 62 /** \brief Timer user operation type size. 63 */ 64 #if defined(CONFIG_BT_TICKER_EXT) 65 #if defined(CONFIG_BT_TICKER_SLOT_AGNOSTIC) 66 #if defined(CONFIG_BT_TICKER_REMAINDER_SUPPORT) 67 #define TICKER_USER_OP_T_SIZE 44 68 #else /* !CONFIG_BT_TICKER_REMAINDER_SUPPORT */ 69 #define TICKER_USER_OP_T_SIZE 40 70 #endif /* !CONFIG_BT_TICKER_REMAINDER_SUPPORT */ 71 #else /* !CONFIG_BT_TICKER_SLOT_AGNOSTIC */ 72 #if defined(CONFIG_BT_TICKER_REMAINDER_SUPPORT) 73 #if defined(CONFIG_BT_TICKER_START_REMAINDER) 74 #define TICKER_USER_OP_T_SIZE 52 75 #else /* !CONFIG_BT_TICKER_START_REMAINDER */ 76 #define TICKER_USER_OP_T_SIZE 48 77 #endif /* !CONFIG_BT_TICKER_START_REMAINDER */ 78 #else /* !CONFIG_BT_TICKER_REMAINDER_SUPPORT */ 79 #define TICKER_USER_OP_T_SIZE 44 80 #endif /* !CONFIG_BT_TICKER_REMAINDER_SUPPORT */ 81 #endif /* !CONFIG_BT_TICKER_SLOT_AGNOSTIC */ 82 #else /* !CONFIG_BT_TICKER_EXT */ 83 #if defined(CONFIG_BT_TICKER_SLOT_AGNOSTIC) 84 #if defined(CONFIG_BT_TICKER_REMAINDER_SUPPORT) 85 #define TICKER_USER_OP_T_SIZE 40 86 #else /* !CONFIG_BT_TICKER_REMAINDER_SUPPORT */ 87 #define TICKER_USER_OP_T_SIZE 36 88 #endif /* !CONFIG_BT_TICKER_REMAINDER_SUPPORT */ 89 #else /* !CONFIG_BT_TICKER_SLOT_AGNOSTIC */ 90 #if defined(CONFIG_BT_TICKER_REMAINDER_SUPPORT) 91 #if defined(CONFIG_BT_TICKER_START_REMAINDER) 92 #define TICKER_USER_OP_T_SIZE 48 93 #else /* !CONFIG_BT_TICKER_START_REMAINDER */ 94 #define TICKER_USER_OP_T_SIZE 44 95 #endif /* !CONFIG_BT_TICKER_START_REMAINDER */ 96 #else /* !CONFIG_BT_TICKER_REMAINDER_SUPPORT */ 97 #define TICKER_USER_OP_T_SIZE 40 98 #endif /* !CONFIG_BT_TICKER_REMAINDER_SUPPORT */ 99 #endif /* !CONFIG_BT_TICKER_SLOT_AGNOSTIC */ 100 #endif /* !CONFIG_BT_TICKER_EXT */ 101 102 #define TICKER_CALL_ID_NONE 0 103 #define TICKER_CALL_ID_ISR 1 104 #define TICKER_CALL_ID_TRIGGER 2 105 #define TICKER_CALL_ID_WORKER 3 106 #define TICKER_CALL_ID_JOB 4 107 #define TICKER_CALL_ID_PROGRAM 5 108 109 /* Use to ensure callback is invoked in all intervals, even when latencies 110 * occur. 111 */ 112 #define TICKER_LAZY_MUST_EXPIRE 0xFFFF 113 114 /* Use in ticker_start to set lazy to 0 and do not change the must_expire 115 * state. 116 */ 117 #define TICKER_LAZY_MUST_EXPIRE_KEEP 0xFFFE 118 119 /* Set this priority to ensure ticker node is always scheduled. Only one 120 * ticker node can have priority TICKER_PRIORITY_CRITICAL at a time 121 */ 122 #define TICKER_PRIORITY_CRITICAL -128 123 124 typedef uint8_t (*ticker_caller_id_get_cb_t)(uint8_t user_id); 125 typedef void (*ticker_sched_cb_t)(uint8_t caller_id, uint8_t callee_id, 126 uint8_t chain, void *instance); 127 typedef void (*ticker_trigger_set_cb_t)(uint32_t value); 128 129 /** \brief Timer timeout function type. 130 */ 131 typedef void (*ticker_timeout_func) (uint32_t ticks_at_expire, 132 uint32_t ticks_drift, uint32_t remainder, 133 uint16_t lazy, uint8_t force, 134 void *context); 135 136 137 struct ticker_expire_info { 138 uint32_t ticks_to_expire; 139 uint32_t remainder; 140 uint16_t lazy; 141 }; 142 143 struct ticker_ext_context { 144 void *context; 145 struct ticker_expire_info *other_expire_info; 146 }; 147 148 /** \brief Timer operation complete function type. 149 */ 150 typedef void (*ticker_op_func) (uint32_t status, void *op_context); 151 152 /** \brief Timer operation match callback function type. 153 */ 154 typedef bool (*ticker_op_match_func) (uint8_t ticker_id, uint32_t ticks_slot, 155 uint32_t ticks_to_expire, 156 void *op_context); 157 158 /** \brief Timer module initialization. 159 * 160 * \param[in] instance_index Timer mode instance 0 or 1 (uses RTC0 CMP0 or 161 * CMP1 respectively). 162 * \param[in] count_node Max. no. of ticker nodes to initialize. 163 * \param[in] node 164 * \param[in] count_user 165 * \param[in] user 166 * \param[in] count_op 167 * \param[in] user_op 168 */ 169 uint8_t ticker_init(uint8_t instance_index, uint8_t count_node, void *node, 170 uint8_t count_user, void *user, uint8_t count_op, 171 void *user_op, ticker_caller_id_get_cb_t caller_id_get_cb, 172 ticker_sched_cb_t sched_cb, 173 ticker_trigger_set_cb_t trigger_set_cb); 174 bool ticker_is_initialized(uint8_t instance_index); 175 void ticker_trigger(uint8_t instance_index); 176 void ticker_worker(void *param); 177 void ticker_job(void *param); 178 uint8_t ticker_start(uint8_t instance_index, uint8_t user_id, 179 uint8_t ticker_id, uint32_t ticks_anchor, 180 uint32_t ticks_first, uint32_t ticks_periodic, 181 uint32_t remainder_periodic, uint16_t lazy, 182 uint32_t ticks_slot, ticker_timeout_func fp_timeout_func, 183 void *context, ticker_op_func fp_op_func, 184 void *op_context); 185 uint8_t ticker_start_us(uint8_t instance_index, uint8_t user_id, 186 uint8_t ticker_id, uint32_t ticks_anchor, 187 uint32_t ticks_first, uint32_t remainder_first, 188 uint32_t ticks_periodic, uint32_t remainder_periodic, 189 uint16_t lazy, uint32_t ticks_slot, 190 ticker_timeout_func fp_timeout_func, void *context, 191 ticker_op_func fp_op_func, void *op_context); 192 uint8_t ticker_update(uint8_t instance_index, uint8_t user_id, 193 uint8_t ticker_id, uint32_t ticks_drift_plus, 194 uint32_t ticks_drift_minus, uint32_t ticks_slot_plus, 195 uint32_t ticks_slot_minus, uint16_t lazy, uint8_t force, 196 ticker_op_func fp_op_func, void *op_context); 197 uint8_t ticker_yield_abs(uint8_t instance_index, uint8_t user_id, 198 uint8_t ticker_id, uint32_t ticks_at_yield, 199 ticker_op_func fp_op_func, void *op_context); 200 uint8_t ticker_stop(uint8_t instance_index, uint8_t user_id, uint8_t ticker_id, 201 ticker_op_func fp_op_func, void *op_context); 202 uint8_t ticker_stop_abs(uint8_t instance_index, uint8_t user_id, 203 uint8_t ticker_id, uint32_t ticks_at_stop, 204 ticker_op_func fp_op_func, void *op_context); 205 uint8_t ticker_next_slot_get(uint8_t instance_index, uint8_t user_id, 206 uint8_t *ticker_id, uint32_t *ticks_current, 207 uint32_t *ticks_to_expire, 208 ticker_op_func fp_op_func, void *op_context); 209 uint8_t ticker_next_slot_get_ext(uint8_t instance_index, uint8_t user_id, 210 uint8_t *ticker_id, uint32_t *ticks_current, 211 uint32_t *ticks_to_expire, 212 uint32_t *remainder, uint16_t *lazy, 213 ticker_op_match_func fp_op_match_func, 214 void *match_op_context, 215 ticker_op_func fp_op_func, void *op_context); 216 uint8_t ticker_job_idle_get(uint8_t instance_index, uint8_t user_id, 217 ticker_op_func fp_op_func, void *op_context); 218 void ticker_job_sched(uint8_t instance_index, uint8_t user_id); 219 uint32_t ticker_ticks_now_get(void); 220 uint32_t ticker_ticks_diff_get(uint32_t ticks_now, uint32_t ticks_old); 221 222 #if !defined(CONFIG_BT_TICKER_LOW_LAT) && \ 223 !defined(CONFIG_BT_TICKER_SLOT_AGNOSTIC) 224 uint8_t ticker_priority_set(uint8_t instance_index, uint8_t user_id, 225 uint8_t ticker_id, int8_t priority, 226 ticker_op_func fp_op_func, void *op_context); 227 #endif /* !CONFIG_BT_TICKER_LOW_LAT && !CONFIG_BT_TICKER_SLOT_AGNOSTIC */ 228 229 #if defined(CONFIG_BT_TICKER_EXT) 230 struct ticker_ext { 231 #if !defined(CONFIG_BT_TICKER_SLOT_AGNOSTIC) 232 uint32_t ticks_slot_window; /* Window in which the slot 233 * reservation may be re-scheduled 234 * to avoid collision 235 */ 236 uint32_t ticks_drift; /* Actual drift since last expiry, 237 * includes any ticker update interface 238 * made changes plus drift due to 239 * reschedule when not 240 * is_jitter_in_window, otherwise is only 241 * the value of drift due to reschedule 242 */ 243 uint8_t reschedule_state:3; /* State of re-scheduling of the 244 * node. See defines 245 * TICKER_RESCHEDULE_STATE_XXX 246 */ 247 uint8_t is_drift_in_window:1; /* Drift in slot window, to be placed 248 * after an overlapping ticker 249 */ 250 #endif /* CONFIG_BT_TICKER_SLOT_AGNOSTIC */ 251 252 #if defined(CONFIG_BT_TICKER_EXT_EXPIRE_INFO) 253 uint8_t expire_info_id; /* Other ticker ID for which 254 * the ext_timeout_func should include expire 255 * info for 256 * Set to TICKER_NULL if not used 257 */ 258 ticker_timeout_func ext_timeout_func; 259 void *other_expire_info; 260 #endif /* CONFIG_BT_TICKER_EXT_EXPIRE_INFO */ 261 }; 262 263 uint8_t ticker_start_ext(uint8_t instance_index, uint8_t user_id, 264 uint8_t ticker_id, uint32_t ticks_anchor, 265 uint32_t ticks_first, uint32_t ticks_periodic, 266 uint32_t remainder_periodic, uint16_t lazy, 267 uint32_t ticks_slot, 268 ticker_timeout_func fp_timeout_func, void *context, 269 ticker_op_func fp_op_func, void *op_context, 270 struct ticker_ext *ext_data); 271 272 #if defined(CONFIG_BT_TICKER_EXT_EXPIRE_INFO) 273 uint8_t ticker_update_ext(uint8_t instance_index, uint8_t user_id, 274 uint8_t ticker_id, uint32_t ticks_drift_plus, 275 uint32_t ticks_drift_minus, 276 uint32_t ticks_slot_plus, uint32_t ticks_slot_minus, 277 uint16_t lazy, uint8_t force, 278 ticker_op_func fp_op_func, void *op_context, 279 uint8_t must_expire, uint8_t expire_info_id); 280 #else /* !CONFIG_BT_TICKER_EXT_EXPIRE_INFO */ 281 uint8_t ticker_update_ext(uint8_t instance_index, uint8_t user_id, 282 uint8_t ticker_id, uint32_t ticks_drift_plus, 283 uint32_t ticks_drift_minus, 284 uint32_t ticks_slot_plus, uint32_t ticks_slot_minus, 285 uint16_t lazy, uint8_t force, 286 ticker_op_func fp_op_func, void *op_context, 287 uint8_t must_expire); 288 #endif /* !CONFIG_BT_TICKER_EXT_EXPIRE_INFO */ 289 290 #endif /* CONFIG_BT_TICKER_EXT */ 291