Mistake on this page?
Report an issue in GitHub or email us
us_ticker_api.h
1 
2 /** \addtogroup hal */
3 /** @{*/
4 /* mbed Microcontroller Library
5  * Copyright (c) 2006-2015 ARM Limited
6  * SPDX-License-Identifier: Apache-2.0
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  */
20 #ifndef MBED_US_TICKER_API_H
21 #define MBED_US_TICKER_API_H
22 
23 #include <stdint.h>
24 #include "hal/ticker_api.h"
25 
26 #ifdef __cplusplus
27 extern "C" {
28 #endif
29 
30 /**
31  * \defgroup hal_us_ticker Microsecond Ticker
32  * Low level interface to the microsecond ticker of a target
33  *
34  * # Defined behavior
35  * * Has a reported frequency between 250KHz and 8MHz for counters which are less than 32 bits wide - Verified by test ::us_ticker_info_test
36  * * Has a reported frequency up to 100MHz for counters which are 32 bits wide - Verified by test ::us_ticker_info_test
37  * * Has a counter that is at least 16 bits wide - Verified by test ::us_ticker_info_test
38  * * All behavior defined by the @ref hal_ticker_shared "ticker specification"
39  *
40  * # Undefined behavior
41  * * See the @ref hal_ticker_shared "ticker specification"
42  *
43  * @see hal_us_ticker_tests
44  *
45  * # Compile-time optimization macros
46  *
47  * To permit compile-time optimization, particularly of wait_us, the following macros should
48  * be defined by a target's device.h:
49  *
50  * US_TICKER_PERIOD_NUM, US_TICKER_PERIOD_DEN: These denote the ratio (numerator, denominator)
51  * of the ticker period to a microsecond. For example, an 8MHz ticker would have NUM = 1, DEN = 8;
52  * a 1MHz ticker would have NUM = 1, DEN = 1; a 250kHz ticker would have NUM = 4, DEN = 1.
53  * Both numerator and denominator must be 16 bits or less.
54  *
55  * US_TICKER_MASK: The value mask for the ticker - eg 0x07FFFFFF for a 27-bit ticker.
56  *
57  * If any are defined, all 3 must be defined, and the macros are checked for consistency with
58  * us_ticker_get_info by test ::us_ticker_info_test.
59 
60  * @{
61  */
62 
63 /**
64  * \defgroup hal_us_ticker_tests Microsecond Ticker tests
65  * Tests to validate the proper implementation of the microsecond ticker
66  *
67  * To run the microsecond ticker hal tests use the command:
68  *
69  * mbed test -t <toolchain> -m <target> -n tests-mbed_hal-common_ticker*,tests-mbed_hal-us_ticker*
70  *
71  * @see hal_ticker_tests
72  *
73  */
74 
75 /**
76  * \defgroup hal_ticker_shared Ticker Hal
77  * Low level interface to the ticker of a target
78  *
79  * # Defined behavior
80  * * The function ticker_init is safe to call repeatedly - Verified by test ::ticker_init_test
81  * * The function ticker_init allows the ticker to keep counting and disables the ticker interrupt - Verified by test ::ticker_init_test
82  * * Ticker frequency is non-zero and counter is at least 8 bits - Verified by ::ticker_info_test
83  * * The ticker rolls over at (1 << bits) and continues counting starting from 0 - Verified by ::ticker_overflow_test
84  * * The ticker counts at the specified frequency +- 10% - Verified by ::ticker_frequency_test
85  * * The ticker increments by 1 each tick - Verified by ::ticker_increment_test
86  * * The ticker interrupt fires only when the ticker times increments to or past the value set by ticker_set_interrupt.
87  * Verified by ::ticker_interrupt_test and ::ticker_past_test
88  * * It is safe to call ticker_set_interrupt repeatedly before the handler is called - Verified by ::ticker_repeat_reschedule_test
89  * * The function ticker_fire_interrupt causes ticker_irq_handler to be called immediately from interrupt context -
90  * Verified by ::ticker_fire_now_test
91  * * The ticker operations ticker_read, ticker_clear_interrupt, ticker_set_interrupt and ticker_fire_interrupt
92  * take less than 20us to complete - Verified by ::ticker_speed_test
93  * * The ticker operations ticker_init and ticker_read are atomic.
94  *
95  * # Undefined behavior
96  * * Calling any function other than ticker_init before the initialization of the ticker
97  * * Whether ticker_irq_handler is called a second time if the time wraps and matches the value set by ticker_set_interrupt again
98  * * Calling ticker_set_interrupt with a value that has more than the supported number of bits
99  * * Calling any function other than us_ticker_init after calling us_ticker_free
100  *
101  * # Potential bugs
102  * * Drift due to reschedule - Verified by ::ticker_repeat_reschedule_test
103  * * Incorrect overflow handling of timers - Verified by ::ticker_overflow_test
104  * * Interrupting at a time of 0 - Verified by ::ticker_overflow_test
105  * * Interrupt triggered more than once - Verified by ::ticker_interrupt_test
106  *
107  * @ingroup hal_us_ticker
108  * @ingroup hal_lp_ticker
109  */
110 
111 /**
112  * \defgroup hal_ticker_tests Ticker Tests
113  * Tests to validate the proper implementation of a ticker
114  *
115  * To run the ticker hal tests use the command:
116  *
117  * mbed test -t <toolchain> -m <target> -n tests-mbed_hal-common_ticker*
118  *
119  * @ingroup hal_us_ticker
120  * @ingroup hal_lp_ticker
121  */
122 
123 
124 typedef void (*ticker_irq_handler_type)(const ticker_data_t *const);
125 
126 /** Set ticker IRQ handler
127  *
128  * @param ticker_irq_handler IRQ handler to be connected
129  *
130  * @return previous ticker IRQ handler
131  *
132  * @note by default IRQ handler is set to ::ticker_irq_handler
133  * @note this function is primarily for testing purposes and it's not required part of HAL implementation
134  *
135  */
136 ticker_irq_handler_type set_us_ticker_irq_handler(ticker_irq_handler_type ticker_irq_handler);
137 
138 /** Get ticker's data
139  *
140  * @return The microsecond ticker data
141  */
142 const ticker_data_t *get_us_ticker_data(void);
143 
144 
145 /** The wrapper for ticker_irq_handler, to pass us ticker's data
146  *
147  */
148 void us_ticker_irq_handler(void);
149 
150 /* HAL us ticker */
151 
152 /** Initialize the ticker
153  *
154  * Initialize or re-initialize the ticker. This resets all the
155  * clocking and prescaler registers, along with disabling
156  * the compare interrupt.
157  *
158  * @note Initialization properties tested by ::ticker_init_test
159  *
160  * Pseudo Code:
161  * @code
162  * void us_ticker_init()
163  * {
164  * // Enable clock gate so processor can read TIMER registers
165  * POWER_CTRL |= POWER_CTRL_TIMER_Msk;
166  *
167  * // Disable the timer and ensure it is powered down
168  * TIMER_CTRL &= ~(TIMER_CTRL_ENABLE_Msk | TIMER_CTRL_COMPARE_ENABLE_Msk);
169  *
170  * // Configure divisors
171  * uint32_t prescale = SystemCoreClock / 1000000;
172  * TIMER_PRESCALE = prescale - 1;
173  * TIMER_CTRL |= TIMER_CTRL_ENABLE_Msk;
174  *
175  * // Install the interrupt handler
176  * NVIC_SetVector(TIMER_IRQn, (uint32_t)us_ticker_irq_handler);
177  * NVIC_EnableIRQ(TIMER_IRQn);
178  * }
179  * @endcode
180  */
181 void us_ticker_init(void);
182 
183 /** Deinitialize the us ticker
184  *
185  * Powerdown the us ticker in preparation for sleep, powerdown, or reset.
186  *
187  * After this function is called, no other ticker functions should be called
188  * except us_ticker_init(), calling any function other than init is undefined.
189  *
190  * @note This function stops the ticker from counting.
191  *
192  * Pseudo Code:
193  * @code
194  * uint32_t us_ticker_free()
195  * {
196  * // Disable timer
197  * TIMER_CTRL &= ~TIMER_CTRL_ENABLE_Msk;
198  *
199  * // Disable the compare interrupt
200  * TIMER_CTRL &= ~TIMER_CTRL_COMPARE_ENABLE_Msk;
201  *
202  * // Disable timer interrupt
203  * NVIC_DisableIRQ(TIMER_IRQn);
204  *
205  * // Disable clock gate so processor cannot read TIMER registers
206  * POWER_CTRL &= ~POWER_CTRL_TIMER_Msk;
207  * }
208  * @endcode
209  *
210  */
211 void us_ticker_free(void);
212 
213 /** Read the current counter
214  *
215  * Read the current counter value without performing frequency conversions.
216  * If no rollover has occurred, the seconds passed since us_ticker_init()
217  * was called can be found by dividing the ticks returned by this function
218  * by the frequency returned by ::us_ticker_get_info.
219  *
220  * @return The current timer's counter value in ticks
221  *
222  * Pseudo Code:
223  * @code
224  * uint32_t us_ticker_read()
225  * {
226  * return TIMER_COUNT;
227  * }
228  * @endcode
229  */
230 uint32_t (us_ticker_read)(void);
231 
232 /** Set interrupt for specified timestamp
233  *
234  * @param timestamp The time in ticks to be set
235  *
236  * @note no special handling needs to be done for times in the past
237  * as the common timer code will detect this and call
238  * us_ticker_fire_interrupt() if this is the case
239  *
240  * @note calling this function with timestamp of more than the supported
241  * number of bits returned by ::us_ticker_get_info results in undefined
242  * behavior.
243  *
244  * Pseudo Code:
245  * @code
246  * void us_ticker_set_interrupt(timestamp_t timestamp)
247  * {
248  * TIMER_COMPARE = timestamp;
249  * TIMER_CTRL |= TIMER_CTRL_COMPARE_ENABLE_Msk;
250  * }
251  * @endcode
252  */
253 void us_ticker_set_interrupt(timestamp_t timestamp);
254 
255 /** Disable us ticker interrupt
256  *
257  * Pseudo Code:
258  * @code
259  * void us_ticker_disable_interrupt(void)
260  * {
261  * // Disable the compare interrupt
262  * TIMER_CTRL &= ~TIMER_CTRL_COMPARE_ENABLE_Msk;
263  * }
264  * @endcode
265  */
266 void us_ticker_disable_interrupt(void);
267 
268 /** Clear us ticker interrupt
269  *
270  * Pseudo Code:
271  * @code
272  * void us_ticker_clear_interrupt(void)
273  * {
274  * // Write to the ICR (interrupt clear register) of the TIMER
275  * TIMER_ICR = TIMER_ICR_COMPARE_Msk;
276  * }
277  * @endcode
278  */
279 void us_ticker_clear_interrupt(void);
280 
281 /** Set pending interrupt that should be fired right away.
282  *
283  * The ticker should be initialized prior calling this function.
284  *
285  * Pseudo Code:
286  * @code
287  * void us_ticker_fire_interrupt(void)
288  * {
289  * NVIC_SetPendingIRQ(TIMER_IRQn);
290  * }
291  * @endcode
292  */
293 void us_ticker_fire_interrupt(void);
294 
295 /** Get frequency and counter bits of this ticker.
296  *
297  * Pseudo Code:
298  * @code
299  * const ticker_info_t* us_ticker_get_info()
300  * {
301  * static const ticker_info_t info = {
302  * 1000000, // 1 MHz
303  * 32 // 32 bit counter
304  * };
305  * return &info;
306  * }
307  * @endcode
308  */
309 const ticker_info_t *us_ticker_get_info(void);
310 
311 /**@}*/
312 
313 #ifdef __cplusplus
314 }
315 #endif
316 
317 #endif
318 
319 /** @}*/
ticker_irq_handler_type set_us_ticker_irq_handler(ticker_irq_handler_type ticker_irq_handler)
Set ticker IRQ handler.
Information about the ticker implementation.
Definition: ticker_api.h:53
void us_ticker_disable_interrupt(void)
Disable us ticker interrupt.
void us_ticker_irq_handler(void)
The wrapper for ticker_irq_handler, to pass us ticker&#39;s data.
void us_ticker_fire_interrupt(void)
Set pending interrupt that should be fired right away.
Ticker&#39;s data structure.
Definition: ticker_api.h:93
void us_ticker_set_interrupt(timestamp_t timestamp)
Set interrupt for specified timestamp.
uint32_t() us_ticker_read(void)
Read the current counter.
void us_ticker_free(void)
Deinitialize the us ticker.
const ticker_data_t * get_us_ticker_data(void)
Get ticker&#39;s data.
void ticker_irq_handler(const ticker_data_t *const ticker)
IRQ handler that goes through the events to trigger overdue events.
void us_ticker_init(void)
Initialize the ticker.
const ticker_info_t * us_ticker_get_info(void)
Get frequency and counter bits of this ticker.
uint32_t timestamp_t
Legacy format representing a timestamp in us.
Definition: ticker_api.h:33
void us_ticker_clear_interrupt(void)
Clear us ticker interrupt.
Important Information for this Arm website

This site uses cookies to store information on your computer. By continuing to use our site, you consent to our cookies. If you are not happy with the use of these cookies, please review our Cookie Policy to learn how they can be disabled. By disabling cookies, some features of the site will not work.