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 #define TICKER_USER_OP_T_SIZE 44 67 #else /* !CONFIG_BT_TICKER_SLOT_AGNOSTIC */ 68 #if defined(CONFIG_BT_TICKER_REMAINDER) 69 #define TICKER_USER_OP_T_SIZE 52 70 #else /* !CONFIG_BT_TICKER_REMAINDER */ 71 #define TICKER_USER_OP_T_SIZE 48 72 #endif /* !CONFIG_BT_TICKER_REMAINDER */ 73 #endif /* !CONFIG_BT_TICKER_SLOT_AGNOSTIC */ 74 #else /* !CONFIG_BT_TICKER_EXT */ 75 #if defined(CONFIG_BT_TICKER_SLOT_AGNOSTIC) 76 #define TICKER_USER_OP_T_SIZE 40 77 #else /* !CONFIG_BT_TICKER_SLOT_AGNOSTIC */ 78 #if defined(CONFIG_BT_TICKER_REMAINDER) 79 #define TICKER_USER_OP_T_SIZE 48 80 #else /* !CONFIG_BT_TICKER_REMAINDER */ 81 #define TICKER_USER_OP_T_SIZE 44 82 #endif /* !CONFIG_BT_TICKER_REMAINDER */ 83 #endif /* !CONFIG_BT_TICKER_SLOT_AGNOSTIC */ 84 #endif /* !CONFIG_BT_TICKER_EXT */ 85 86 #define TICKER_CALL_ID_NONE 0 87 #define TICKER_CALL_ID_ISR 1 88 #define TICKER_CALL_ID_TRIGGER 2 89 #define TICKER_CALL_ID_WORKER 3 90 #define TICKER_CALL_ID_JOB 4 91 #define TICKER_CALL_ID_PROGRAM 5 92 93 /* Use to ensure callback is invoked in all intervals, even when latencies 94 * occur. 95 */ 96 #define TICKER_LAZY_MUST_EXPIRE 0xFFFF 97 98 /* Use in ticker_start to set lazy to 0 and do not change the must_expire 99 * state. 100 */ 101 #define TICKER_LAZY_MUST_EXPIRE_KEEP 0xFFFE 102 103 /* Set this priority to ensure ticker node is always scheduled. Only one 104 * ticker node can have priority TICKER_PRIORITY_CRITICAL at a time 105 */ 106 #define TICKER_PRIORITY_CRITICAL -128 107 108 typedef uint8_t (*ticker_caller_id_get_cb_t)(uint8_t user_id); 109 typedef void (*ticker_sched_cb_t)(uint8_t caller_id, uint8_t callee_id, 110 uint8_t chain, void *instance); 111 typedef void (*ticker_trigger_set_cb_t)(uint32_t value); 112 113 /** \brief Timer timeout function type. 114 */ 115 typedef void (*ticker_timeout_func) (uint32_t ticks_at_expire, 116 uint32_t ticks_drift, uint32_t remainder, 117 uint16_t lazy, uint8_t force, 118 void *context); 119 120 121 struct ticker_expire_info { 122 uint32_t ticks_to_expire; 123 uint32_t remainder; 124 uint16_t lazy; 125 }; 126 127 struct ticker_ext_context { 128 void *context; 129 struct ticker_expire_info *other_expire_info; 130 }; 131 132 /** \brief Timer operation complete function type. 133 */ 134 typedef void (*ticker_op_func) (uint32_t status, void *op_context); 135 136 /** \brief Timer operation match callback function type. 137 */ 138 typedef bool (*ticker_op_match_func) (uint8_t ticker_id, uint32_t ticks_slot, 139 uint32_t ticks_to_expire, 140 void *op_context); 141 142 /** \brief Timer module initialization. 143 * 144 * \param[in] instance_index Timer mode instance 0 or 1 (uses RTC0 CMP0 or 145 * CMP1 respectively). 146 * \param[in] count_node Max. no. of ticker nodes to initialize. 147 * \param[in] node 148 * \param[in] count_user 149 * \param[in] user 150 * \param[in] count_op 151 * \param[in] user_op 152 */ 153 uint8_t ticker_init(uint8_t instance_index, uint8_t count_node, void *node, 154 uint8_t count_user, void *user, uint8_t count_op, 155 void *user_op, ticker_caller_id_get_cb_t caller_id_get_cb, 156 ticker_sched_cb_t sched_cb, 157 ticker_trigger_set_cb_t trigger_set_cb); 158 bool ticker_is_initialized(uint8_t instance_index); 159 void ticker_trigger(uint8_t instance_index); 160 void ticker_worker(void *param); 161 void ticker_job(void *param); 162 uint8_t ticker_start(uint8_t instance_index, uint8_t user_id, 163 uint8_t ticker_id, uint32_t ticks_anchor, 164 uint32_t ticks_first, uint32_t ticks_periodic, 165 uint32_t remainder_periodic, uint16_t lazy, 166 uint32_t ticks_slot, ticker_timeout_func fp_timeout_func, 167 void *context, ticker_op_func fp_op_func, 168 void *op_context); 169 uint8_t ticker_start_us(uint8_t instance_index, uint8_t user_id, 170 uint8_t ticker_id, uint32_t ticks_anchor, 171 uint32_t ticks_first, uint32_t remainder_first, 172 uint32_t ticks_periodic, uint32_t remainder_periodic, 173 uint16_t lazy, uint32_t ticks_slot, 174 ticker_timeout_func fp_timeout_func, void *context, 175 ticker_op_func fp_op_func, void *op_context); 176 uint8_t ticker_update(uint8_t instance_index, uint8_t user_id, 177 uint8_t ticker_id, uint32_t ticks_drift_plus, 178 uint32_t ticks_drift_minus, uint32_t ticks_slot_plus, 179 uint32_t ticks_slot_minus, uint16_t lazy, uint8_t force, 180 ticker_op_func fp_op_func, void *op_context); 181 uint8_t ticker_yield_abs(uint8_t instance_index, uint8_t user_id, 182 uint8_t ticker_id, uint32_t ticks_at_yield, 183 ticker_op_func fp_op_func, void *op_context); 184 uint8_t ticker_stop(uint8_t instance_index, uint8_t user_id, uint8_t ticker_id, 185 ticker_op_func fp_op_func, void *op_context); 186 uint8_t ticker_stop_abs(uint8_t instance_index, uint8_t user_id, 187 uint8_t ticker_id, uint32_t ticks_at_stop, 188 ticker_op_func fp_op_func, void *op_context); 189 uint8_t ticker_next_slot_get(uint8_t instance_index, uint8_t user_id, 190 uint8_t *ticker_id, uint32_t *ticks_current, 191 uint32_t *ticks_to_expire, 192 ticker_op_func fp_op_func, void *op_context); 193 uint8_t ticker_next_slot_get_ext(uint8_t instance_index, uint8_t user_id, 194 uint8_t *ticker_id, uint32_t *ticks_current, 195 uint32_t *ticks_to_expire, 196 uint32_t *remainder, uint16_t *lazy, 197 ticker_op_match_func fp_op_match_func, 198 void *match_op_context, 199 ticker_op_func fp_op_func, void *op_context); 200 uint8_t ticker_job_idle_get(uint8_t instance_index, uint8_t user_id, 201 ticker_op_func fp_op_func, void *op_context); 202 void ticker_job_sched(uint8_t instance_index, uint8_t user_id); 203 uint32_t ticker_ticks_now_get(void); 204 uint32_t ticker_ticks_diff_get(uint32_t ticks_now, uint32_t ticks_old); 205 206 #if !defined(CONFIG_BT_TICKER_LOW_LAT) && \ 207 !defined(CONFIG_BT_TICKER_SLOT_AGNOSTIC) 208 uint8_t ticker_priority_set(uint8_t instance_index, uint8_t user_id, 209 uint8_t ticker_id, int8_t priority, 210 ticker_op_func fp_op_func, void *op_context); 211 #endif /* !CONFIG_BT_TICKER_LOW_LAT && !CONFIG_BT_TICKER_SLOT_AGNOSTIC */ 212 213 #if defined(CONFIG_BT_TICKER_EXT) 214 struct ticker_ext { 215 #if !defined(CONFIG_BT_TICKER_SLOT_AGNOSTIC) 216 uint32_t ticks_slot_window;/* Window in which the slot 217 * reservation may be re-scheduled 218 * to avoid collision 219 */ 220 uint32_t ticks_drift; /* Actual drift since last expiry */ 221 uint8_t reschedule_state; /* State of re-scheduling of the 222 * node. See defines 223 * TICKER_RESCHEDULE_STATE_XXX 224 */ 225 #endif /* CONFIG_BT_TICKER_SLOT_AGNOSTIC */ 226 227 #if defined(CONFIG_BT_TICKER_EXT_EXPIRE_INFO) 228 uint8_t expire_info_id; /* Other ticker ID for which 229 * the ext_timeout_func should include expire 230 * info for 231 * Set to TICKER_NULL if not used 232 */ 233 ticker_timeout_func ext_timeout_func; 234 void *other_expire_info; 235 #endif /* CONFIG_BT_TICKER_EXT_EXPIRE_INFO */ 236 }; 237 238 uint8_t ticker_start_ext(uint8_t instance_index, uint8_t user_id, 239 uint8_t ticker_id, uint32_t ticks_anchor, 240 uint32_t ticks_first, uint32_t ticks_periodic, 241 uint32_t remainder_periodic, uint16_t lazy, 242 uint32_t ticks_slot, 243 ticker_timeout_func fp_timeout_func, void *context, 244 ticker_op_func fp_op_func, void *op_context, 245 struct ticker_ext *ext_data); 246 247 #if defined(CONFIG_BT_TICKER_EXT_EXPIRE_INFO) 248 uint8_t ticker_update_ext(uint8_t instance_index, uint8_t user_id, 249 uint8_t ticker_id, uint32_t ticks_drift_plus, 250 uint32_t ticks_drift_minus, 251 uint32_t ticks_slot_plus, uint32_t ticks_slot_minus, 252 uint16_t lazy, uint8_t force, 253 ticker_op_func fp_op_func, void *op_context, 254 uint8_t must_expire, uint8_t expire_info_id); 255 #else /* !CONFIG_BT_TICKER_EXT_EXPIRE_INFO */ 256 uint8_t ticker_update_ext(uint8_t instance_index, uint8_t user_id, 257 uint8_t ticker_id, uint32_t ticks_drift_plus, 258 uint32_t ticks_drift_minus, 259 uint32_t ticks_slot_plus, uint32_t ticks_slot_minus, 260 uint16_t lazy, uint8_t force, 261 ticker_op_func fp_op_func, void *op_context, 262 uint8_t must_expire); 263 #endif /* !CONFIG_BT_TICKER_EXT_EXPIRE_INFO */ 264 265 #endif /* CONFIG_BT_TICKER_EXT */ 266