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