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