1 /*
2 * Copyright (c) 2015 - 2020, 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_TIMER_H__
33 #define NRFX_TIMER_H__
34
35 #include <nrfx.h>
36 #include <hal/nrf_timer.h>
37
38 #ifdef __cplusplus
39 extern "C" {
40 #endif
41
42 /**
43 * @defgroup nrfx_timer Timer driver
44 * @{
45 * @ingroup nrf_timer
46 * @brief TIMER peripheral driver.
47 */
48
49 /**
50 * @brief Timer driver instance data structure.
51 */
52 typedef struct
53 {
54 NRF_TIMER_Type * p_reg; ///< Pointer to the structure with TIMER peripheral instance registers.
55 uint8_t instance_id; ///< Index of the driver instance. For internal use only.
56 uint8_t cc_channel_count; ///< Number of capture/compare channels.
57 } nrfx_timer_t;
58
59 /** @brief Macro for creating a timer driver instance. */
60 #define NRFX_TIMER_INSTANCE(id) \
61 { \
62 .p_reg = NRFX_CONCAT_2(NRF_TIMER, id), \
63 .instance_id = NRFX_CONCAT_3(NRFX_TIMER, id, _INST_IDX), \
64 .cc_channel_count = NRF_TIMER_CC_CHANNEL_COUNT(id), \
65 }
66
67 #ifndef __NRFX_DOXYGEN__
68 enum {
69 #if NRFX_CHECK(NRFX_TIMER0_ENABLED)
70 NRFX_TIMER0_INST_IDX,
71 #endif
72 #if NRFX_CHECK(NRFX_TIMER1_ENABLED)
73 NRFX_TIMER1_INST_IDX,
74 #endif
75 #if NRFX_CHECK(NRFX_TIMER2_ENABLED)
76 NRFX_TIMER2_INST_IDX,
77 #endif
78 #if NRFX_CHECK(NRFX_TIMER3_ENABLED)
79 NRFX_TIMER3_INST_IDX,
80 #endif
81 #if NRFX_CHECK(NRFX_TIMER4_ENABLED)
82 NRFX_TIMER4_INST_IDX,
83 #endif
84 NRFX_TIMER_ENABLED_COUNT
85 };
86 #endif
87
88 /** @brief The configuration structure of the timer driver instance. */
89 typedef struct
90 {
91 nrf_timer_frequency_t frequency; ///< Frequency.
92 nrf_timer_mode_t mode; ///< Mode of operation.
93 nrf_timer_bit_width_t bit_width; ///< Bit width.
94 uint8_t interrupt_priority; ///< Interrupt priority.
95 void * p_context; ///< Context passed to interrupt handler.
96 } nrfx_timer_config_t;
97
98 /**
99 * @brief TIMER driver default configuration.
100 *
101 * This configuration sets up TIMER with the following options:
102 * - frequency: 16 MHz
103 * - works as timer
104 * - width: 16 bit
105 */
106 #define NRFX_TIMER_DEFAULT_CONFIG \
107 { \
108 .frequency = NRF_TIMER_FREQ_16MHz, \
109 .mode = NRF_TIMER_MODE_TIMER, \
110 .bit_width = NRF_TIMER_BIT_WIDTH_16, \
111 .interrupt_priority = NRFX_TIMER_DEFAULT_CONFIG_IRQ_PRIORITY, \
112 .p_context = NULL \
113 }
114
115 /**
116 * @brief Timer driver event handler type.
117 *
118 * @param[in] event_type Timer event.
119 * @param[in] p_context General purpose parameter set during initialization of
120 * the timer. This parameter can be used to pass
121 * additional information to the handler function, for
122 * example, the timer ID.
123 */
124 typedef void (* nrfx_timer_event_handler_t)(nrf_timer_event_t event_type,
125 void * p_context);
126
127 /**
128 * @brief Function for initializing the timer.
129 *
130 * @param[in] p_instance Pointer to the driver instance structure.
131 * @param[in] p_config Pointer to the structure with the initial configuration.
132 * @param[in] timer_event_handler Event handler provided by the user.
133 * Must not be NULL.
134 *
135 * @retval NRFX_SUCCESS Initialization was successful.
136 * @retval NRFX_ERROR_INVALID_STATE The instance is already initialized.
137 */
138 nrfx_err_t nrfx_timer_init(nrfx_timer_t const * p_instance,
139 nrfx_timer_config_t const * p_config,
140 nrfx_timer_event_handler_t timer_event_handler);
141
142 /**
143 * @brief Function for uninitializing the timer.
144 *
145 * @param[in] p_instance Pointer to the driver instance structure.
146 */
147 void nrfx_timer_uninit(nrfx_timer_t const * p_instance);
148
149 /**
150 * @brief Function for turning on the timer.
151 *
152 * @param[in] p_instance Pointer to the driver instance structure.
153 */
154 void nrfx_timer_enable(nrfx_timer_t const * p_instance);
155
156 /**
157 * @brief Function for turning off the timer.
158 *
159 * The timer will allow to enter the lowest possible SYSTEM_ON state
160 * only after this function is called.
161 *
162 * @param[in] p_instance Pointer to the driver instance structure.
163 */
164 void nrfx_timer_disable(nrfx_timer_t const * p_instance);
165
166 /**
167 * @brief Function for checking the timer state.
168 *
169 * @param[in] p_instance Pointer to the driver instance structure.
170 *
171 * @retval true Timer is enabled.
172 * @retval false Timer is not enabled.
173 */
174 bool nrfx_timer_is_enabled(nrfx_timer_t const * p_instance);
175
176 /**
177 * @brief Function for pausing the timer.
178 *
179 * @param[in] p_instance Pointer to the driver instance structure.
180 */
181 void nrfx_timer_pause(nrfx_timer_t const * p_instance);
182
183 /**
184 * @brief Function for resuming the timer.
185 *
186 * @param[in] p_instance Pointer to the driver instance structure.
187 */
188 void nrfx_timer_resume(nrfx_timer_t const * p_instance);
189
190 /**
191 * @brief Function for clearing the timer.
192 *
193 * @param[in] p_instance Pointer to the driver instance structure.
194 */
195 void nrfx_timer_clear(nrfx_timer_t const * p_instance);
196
197 /**
198 * @brief Function for incrementing the timer.
199 *
200 * @param[in] p_instance Pointer to the driver instance structure.
201 */
202 void nrfx_timer_increment(nrfx_timer_t const * p_instance);
203
204 /**
205 * @brief Function for returning the address of the specified timer task.
206 *
207 * @param[in] p_instance Pointer to the driver instance structure.
208 * @param[in] timer_task Timer task.
209 *
210 * @return Task address.
211 */
212 NRFX_STATIC_INLINE uint32_t nrfx_timer_task_address_get(nrfx_timer_t const * p_instance,
213 nrf_timer_task_t timer_task);
214
215 /**
216 * @brief Function for returning the address of the specified timer capture task.
217 *
218 * @param[in] p_instance Pointer to the driver instance structure.
219 * @param[in] channel Capture channel number.
220 *
221 * @return Task address.
222 */
223 NRFX_STATIC_INLINE uint32_t nrfx_timer_capture_task_address_get(nrfx_timer_t const * p_instance,
224 uint32_t channel);
225
226 /**
227 * @brief Function for returning the address of the specified timer event.
228 *
229 * @param[in] p_instance Pointer to the driver instance structure.
230 * @param[in] timer_event Timer event.
231 *
232 * @return Event address.
233 */
234 NRFX_STATIC_INLINE uint32_t nrfx_timer_event_address_get(nrfx_timer_t const * p_instance,
235 nrf_timer_event_t timer_event);
236
237 /**
238 * @brief Function for returning the address of the specified timer compare event.
239 *
240 * @param[in] p_instance Pointer to the driver instance structure.
241 * @param[in] channel Compare channel number.
242 *
243 * @return Event address.
244 */
245 NRFX_STATIC_INLINE uint32_t nrfx_timer_compare_event_address_get(nrfx_timer_t const * p_instance,
246 uint32_t channel);
247
248 /**
249 * @brief Function for capturing the timer value.
250 *
251 * @param[in] p_instance Pointer to the driver instance structure.
252 * @param[in] cc_channel Capture channel number.
253 *
254 * @return Captured value.
255 */
256 uint32_t nrfx_timer_capture(nrfx_timer_t const * p_instance,
257 nrf_timer_cc_channel_t cc_channel);
258
259 /**
260 * @brief Function for returning the capture value from the specified channel.
261 *
262 * Use this function to read channel values when PPI is used for capturing.
263 *
264 * @param[in] p_instance Pointer to the driver instance structure.
265 * @param[in] cc_channel Capture channel number.
266 *
267 * @return Captured value.
268 */
269 NRFX_STATIC_INLINE uint32_t nrfx_timer_capture_get(nrfx_timer_t const * p_instance,
270 nrf_timer_cc_channel_t cc_channel);
271
272 /**
273 * @brief Function for setting the timer channel in compare mode.
274 *
275 * @param[in] p_instance Pointer to the driver instance structure.
276 * @param[in] cc_channel Compare channel number.
277 * @param[in] cc_value Compare value.
278 * @param[in] enable_int Enable or disable the interrupt for the compare channel.
279 */
280 void nrfx_timer_compare(nrfx_timer_t const * p_instance,
281 nrf_timer_cc_channel_t cc_channel,
282 uint32_t cc_value,
283 bool enable_int);
284
285 /**
286 * @brief Function for setting the timer channel in the extended compare mode.
287 *
288 * @param[in] p_instance Pointer to the driver instance structure.
289 * @param[in] cc_channel Compare channel number.
290 * @param[in] cc_value Compare value.
291 * @param[in] timer_short_mask Shortcut between the compare event on the channel
292 * and the timer task (STOP or CLEAR).
293 * @param[in] enable_int Enable or disable the interrupt for the compare channel.
294 */
295 void nrfx_timer_extended_compare(nrfx_timer_t const * p_instance,
296 nrf_timer_cc_channel_t cc_channel,
297 uint32_t cc_value,
298 nrf_timer_short_mask_t timer_short_mask,
299 bool enable_int);
300
301 /**
302 * @brief Function for converting time in microseconds to timer ticks.
303 *
304 * @param[in] p_instance Pointer to the driver instance structure.
305 * @param[in] time_us Time in microseconds.
306 *
307 * @return Number of ticks.
308 */
309 NRFX_STATIC_INLINE uint32_t nrfx_timer_us_to_ticks(nrfx_timer_t const * p_instance,
310 uint32_t time_us);
311
312 /**
313 * @brief Function for converting time in milliseconds to timer ticks.
314 *
315 * @param[in] p_instance Pointer to the driver instance structure.
316 * @param[in] time_ms Time in milliseconds.
317 *
318 * @return Number of ticks.
319 */
320 NRFX_STATIC_INLINE uint32_t nrfx_timer_ms_to_ticks(nrfx_timer_t const * p_instance,
321 uint32_t time_ms);
322
323 /**
324 * @brief Function for enabling timer compare interrupt.
325 *
326 * @param[in] p_instance Pointer to the driver instance structure.
327 * @param[in] channel Compare channel.
328 */
329 void nrfx_timer_compare_int_enable(nrfx_timer_t const * p_instance,
330 uint32_t channel);
331
332 /**
333 * @brief Function for disabling timer compare interrupt.
334 *
335 * @param[in] p_instance Pointer to the driver instance structure.
336 * @param[in] channel Compare channel.
337 */
338 void nrfx_timer_compare_int_disable(nrfx_timer_t const * p_instance,
339 uint32_t channel);
340
341 #ifndef NRFX_DECLARE_ONLY
nrfx_timer_task_address_get(nrfx_timer_t const * p_instance,nrf_timer_task_t timer_task)342 NRFX_STATIC_INLINE uint32_t nrfx_timer_task_address_get(nrfx_timer_t const * p_instance,
343 nrf_timer_task_t timer_task)
344 {
345 return nrf_timer_task_address_get(p_instance->p_reg, timer_task);
346 }
347
nrfx_timer_capture_task_address_get(nrfx_timer_t const * p_instance,uint32_t channel)348 NRFX_STATIC_INLINE uint32_t nrfx_timer_capture_task_address_get(nrfx_timer_t const * p_instance,
349 uint32_t channel)
350 {
351 NRFX_ASSERT(channel < p_instance->cc_channel_count);
352 return nrf_timer_task_address_get(p_instance->p_reg, nrf_timer_capture_task_get(channel));
353 }
354
nrfx_timer_event_address_get(nrfx_timer_t const * p_instance,nrf_timer_event_t timer_event)355 NRFX_STATIC_INLINE uint32_t nrfx_timer_event_address_get(nrfx_timer_t const * p_instance,
356 nrf_timer_event_t timer_event)
357 {
358 return nrf_timer_event_address_get(p_instance->p_reg, timer_event);
359 }
360
nrfx_timer_compare_event_address_get(nrfx_timer_t const * p_instance,uint32_t channel)361 NRFX_STATIC_INLINE uint32_t nrfx_timer_compare_event_address_get(nrfx_timer_t const * p_instance,
362 uint32_t channel)
363 {
364 NRFX_ASSERT(channel < p_instance->cc_channel_count);
365 return nrf_timer_event_address_get(p_instance->p_reg, nrf_timer_compare_event_get(channel));
366 }
367
nrfx_timer_capture_get(nrfx_timer_t const * p_instance,nrf_timer_cc_channel_t cc_channel)368 NRFX_STATIC_INLINE uint32_t nrfx_timer_capture_get(nrfx_timer_t const * p_instance,
369 nrf_timer_cc_channel_t cc_channel)
370 {
371 return nrf_timer_cc_get(p_instance->p_reg, cc_channel);
372 }
373
nrfx_timer_us_to_ticks(nrfx_timer_t const * p_instance,uint32_t timer_us)374 NRFX_STATIC_INLINE uint32_t nrfx_timer_us_to_ticks(nrfx_timer_t const * p_instance,
375 uint32_t timer_us)
376 {
377 return nrf_timer_us_to_ticks(timer_us, nrf_timer_frequency_get(p_instance->p_reg));
378 }
379
nrfx_timer_ms_to_ticks(nrfx_timer_t const * p_instance,uint32_t timer_ms)380 NRFX_STATIC_INLINE uint32_t nrfx_timer_ms_to_ticks(nrfx_timer_t const * p_instance,
381 uint32_t timer_ms)
382 {
383 return nrf_timer_ms_to_ticks(timer_ms, nrf_timer_frequency_get(p_instance->p_reg));
384 }
385 #endif // NRFX_DECLARE_ONLY
386
387 /** @} */
388
389
390 void nrfx_timer_0_irq_handler(void);
391 void nrfx_timer_1_irq_handler(void);
392 void nrfx_timer_2_irq_handler(void);
393 void nrfx_timer_3_irq_handler(void);
394 void nrfx_timer_4_irq_handler(void);
395
396
397 #ifdef __cplusplus
398 }
399 #endif
400
401 #endif // NRFX_TIMER_H__
402
403