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