update credits
[librepilot.git] / flight / pios / stm32f10x / pios_delay.c
blob9907f2c175792c6e228083a92672e1df6bb3056c
1 /**
2 ******************************************************************************
3 * @addtogroup PIOS PIOS Core hardware abstraction layer
4 * @{
5 * @addtogroup PIOS_DELAY Delay Functions
6 * @brief PiOS Delay functionality
7 * @{
9 * @file pios_delay.c
10 * @author Michael Smith Copyright (C) 2011
11 * @brief Delay Functions
12 * - Provides a micro-second granular delay using the CPU
13 * cycle counter.
14 * @see The GNU Public License (GPL) Version 3
16 *****************************************************************************/
18 * This program is free software; you can redistribute it and/or modify
19 * it under the terms of the GNU General Public License as published by
20 * the Free Software Foundation; either version 3 of the License, or
21 * (at your option) any later version.
23 * This program is distributed in the hope that it will be useful, but
24 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
25 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
26 * for more details.
28 * You should have received a copy of the GNU General Public License along
29 * with this program; if not, write to the Free Software Foundation, Inc.,
30 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
33 #include <pios.h>
35 #ifdef PIOS_INCLUDE_DELAY
37 /* cycles per microsecond */
38 static uint32_t us_ticks;
39 static uint32_t raw_hz;
41 /**
42 * Initialises the Timer used by PIOS_DELAY functions.
44 * \return always zero (success)
47 int32_t PIOS_DELAY_Init(void)
49 RCC_ClocksTypeDef clocks;
51 /* compute the number of system clocks per microsecond */
52 RCC_GetClocksFreq(&clocks);
53 us_ticks = clocks.SYSCLK_Frequency / 1000000;
54 PIOS_DEBUG_Assert(us_ticks > 1);
55 raw_hz = clocks.SYSCLK_Frequency;
57 /* turn on access to the DWT registers */
58 CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;
60 /* enable the CPU cycle counter */
61 DWT_CTRL |= CYCCNTENA;
63 return 0;
66 /**
67 * Waits for a specific number of uS
69 * Example:<BR>
70 * \code
71 * // Wait for 500 uS
72 * PIOS_DELAY_Wait_uS(500);
73 * \endcode
74 * \param[in] uS delay
75 * \return < 0 on errors
77 int32_t PIOS_DELAY_WaituS(uint32_t uS)
79 uint32_t elapsed = 0;
80 uint32_t last_count = DWT_CYCCNT;
82 for (;;) {
83 uint32_t current_count = PIOS_DELAY_GetRaw();
84 uint32_t elapsed_uS;
86 /* measure the time elapsed since the last time we checked */
87 elapsed += current_count - last_count;
88 last_count = current_count;
90 /* convert to microseconds */
91 elapsed_uS = elapsed / us_ticks;
92 if (elapsed_uS >= uS) {
93 break;
96 /* reduce the delay by the elapsed time */
97 uS -= elapsed_uS;
99 /* keep fractional microseconds for the next iteration */
100 elapsed %= us_ticks;
103 /* No error */
104 return 0;
108 * Waits for a specific number of mS
110 * Example:<BR>
111 * \code
112 * // Wait for 500 mS
113 * PIOS_DELAY_Wait_mS(500);
114 * \endcode
115 * \param[in] mS delay
116 * \return < 0 on errors
118 int32_t PIOS_DELAY_WaitmS(uint32_t mS)
120 while (mS--) {
121 PIOS_DELAY_WaituS(1000);
124 /* No error */
125 return 0;
129 * @brief Query the Delay timer for the current uS
130 * @return A microsecond value
132 uint32_t PIOS_DELAY_GetuS(void)
134 return PIOS_DELAY_GetRaw() / us_ticks;
138 * @brief Calculate time in microseconds since a previous time
139 * @param[in] t previous time
140 * @return time in us since previous time t.
142 uint32_t PIOS_DELAY_GetuSSince(uint32_t t)
144 return PIOS_DELAY_GetuS() - t;
148 * @brief Get the raw delay timer frequency
149 * @return raw delay timer frequency in Hz
151 uint32_t PIOS_DELAY_GetRawHz()
153 return raw_hz;
157 * @brief Compare to raw times to and convert to us
158 * @return A microsecond value
160 uint32_t PIOS_DELAY_DiffuS(uint32_t raw)
162 uint32_t diff = PIOS_DELAY_GetRaw() - raw;
164 return diff / us_ticks;
167 #endif /* PIOS_INCLUDE_DELAY */
170 * @}
171 * @}