Mistake on this page?
Report an issue in GitHub or email us
mbed_wait_api.h
1 
2 /** \addtogroup platform */
3 /** @{*/
4 /**
5  * \defgroup platform_wait_api wait_api functions
6  * @{
7  */
8 
9 /* mbed Microcontroller Library
10  * Copyright (c) 2006-2013 ARM Limited
11  * SPDX-License-Identifier: Apache-2.0
12  *
13  * Licensed under the Apache License, Version 2.0 (the "License");
14  * you may not use this file except in compliance with the License.
15  * You may obtain a copy of the License at
16  *
17  * http://www.apache.org/licenses/LICENSE-2.0
18  *
19  * Unless required by applicable law or agreed to in writing, software
20  * distributed under the License is distributed on an "AS IS" BASIS,
21  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
22  * See the License for the specific language governing permissions and
23  * limitations under the License.
24  */
25 #ifndef MBED_WAIT_API_H
26 #define MBED_WAIT_API_H
27 
28 #include "platform/mbed_atomic.h"
29 #include "device.h"
30 
31 #ifdef __cplusplus
32 extern "C" {
33 #endif
34 
35 /** Generic wait functions.
36  *
37  * These provide simple NOP type wait capabilities.
38  *
39  * Example:
40  * @code
41  * #include "mbed.h"
42  *
43  * DigitalOut heartbeat(LED1);
44  *
45  * int main() {
46  * while (1) {
47  * heartbeat = 1;
48  * wait(0.5);
49  * heartbeat = 0;
50  * wait(0.5);
51  * }
52  * }
53  * @endcode
54  */
55 
56 /** Waits for a number of seconds, with microsecond resolution (within
57  * the accuracy of single precision floating point).
58  *
59  * @param s number of seconds to wait
60  *
61  * @note
62  * If the RTOS is present, this function spins to get the exact number of microseconds for
63  * microsecond precision up to 10 milliseconds. If delay is larger than 10 milliseconds and not in ISR, it is the same as
64  * `wait_ms`. We recommend `wait_us` and `wait_ms` over `wait`.
65  */
66 void wait(float s);
67 
68 /** Waits a number of milliseconds.
69  *
70  * @param ms the whole number of milliseconds to wait
71  *
72  * @note
73  * If the RTOS is present, it calls ThisThread::sleep_for(), which is same as CMSIS osDelay().
74  * You can't call this from interrupts, and it doesn't lock hardware sleep.
75  */
76 void wait_ms(int ms);
77 
78 /** Waits a number of microseconds.
79  *
80  * @param us the whole number of microseconds to wait
81  *
82  * @note
83  * This function always spins to get the exact number of microseconds.
84  * This will affect power and multithread performance. Therefore, spinning for
85  * millisecond wait is not recommended, and wait_ms() should
86  * be used instead.
87  *
88  * @note You may call this function from ISR context, but large delays may
89  * impact system stability - interrupt handlers should take less than
90  * 50us.
91  */
92 void wait_us(int us);
93 
94 /** Waits a number of nanoseconds.
95  *
96  * This function spins the CPU to produce a small delay. It should normally
97  * only be used for delays of 10us (10000ns) or less. As it is calculated
98  * based on the expected execution time of a software loop, it may well run
99  * slower than requested based on activity from other threads and interrupts.
100  * If greater precision is required, this can be called from inside a critical
101  * section.
102  *
103  * @param ns the number of nanoseconds to wait
104  *
105  * @note
106  * wait_us() will likely give more precise time than wait_ns for large-enough
107  * delays, as it is based on a timer, but its set-up time may be excessive
108  * for the smallest microsecond counts, at which point wait_ns() is better.
109  *
110  * @note
111  * Any delay larger than a millisecond (1000000ns) is liable to cause
112  * overflow in the internal loop calculation. You shouldn't normally be
113  * using this for such large delays anyway in real code, but be aware if
114  * calibrating. Make repeated calls for longer test runs.
115  *
116  * @note You may call this function from ISR context.
117  *
118  */
119 void wait_ns(unsigned int ns);
120 
121 /* Optimize if we know the rate */
122 #if DEVICE_USTICKER && defined US_TICKER_PERIOD_NUM
123 void _wait_us_ticks(uint32_t ticks);
124 void _wait_us_generic(unsigned int us);
125 
126 /* Further optimization if we know us_ticker is always running */
127 #if MBED_CONF_TARGET_INIT_US_TICKER_AT_BOOT
128 #define _us_ticker_is_initialized true
129 #else
130 extern bool _us_ticker_initialized;
131 #define _us_ticker_is_initialized core_util_atomic_load_bool(&_us_ticker_initialized)
132 #endif
133 
134 #if US_TICKER_PERIOD_DEN == 1 && (US_TICKER_MASK * US_TICKER_PERIOD_NUM) >= 0xFFFFFFFF
135 /* Ticker is wide and slow enough to have full 32-bit range - can always use it directly */
136 #define _us_is_small_enough(us) true
137 #else
138 /* Threshold is determined by specification of us_ticker_api.h - smallest possible
139  * time range for the us_ticker is 16-bit 8MHz, which gives 8192us. This also leaves
140  * headroom for the multiplication in 32 bits.
141  */
142 #define _us_is_small_enough(us) ((us) < 8192)
143 #endif
144 
145 /* Speed optimisation for small wait_us. Care taken to preserve binary compatibility */
146 inline void _wait_us_inline(unsigned int us)
147 {
148  /* Threshold is determined by specification of us_ticker_api.h - smallest possible
149  * time range for the us_ticker is 16-bit 8MHz, which gives 8192us. This also leaves
150  * headroom for the multiplication in 32 bits.
151  */
152  if (_us_is_small_enough(us) && _us_ticker_is_initialized) {
153  const uint32_t ticks = ((us * US_TICKER_PERIOD_DEN) + US_TICKER_PERIOD_NUM - 1) / US_TICKER_PERIOD_NUM;
154  _wait_us_ticks(ticks);
155  } else {
156  _wait_us_generic(us);
157  }
158 }
159 
160 #define wait_us(us) _wait_us_inline(us)
161 #endif // Known-rate, initialised timer
162 
163 #ifdef __cplusplus
164 }
165 #endif
166 
167 #endif
168 
169 /** @}*/
170 /** @}*/
void wait_us(int us)
Waits a number of microseconds.
void wait_ms(int ms)
Waits a number of milliseconds.
void wait_ns(unsigned int ns)
Waits a number of nanoseconds.
void wait(float s)
Generic wait functions.
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.