dRonin  adbada4
dRonin firmware
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
pios_delay.c
Go to the documentation of this file.
1 
17 /*
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.
22  *
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.
27  *
28  * You should have received a copy of the GNU General Public License along
29  * with this program; if not, see <http://www.gnu.org/licenses/>
30  */
31 
32 /* Project Includes */
33 #include <pios.h>
34 
35 /* This will result in a value of 32000 -- about 15 bits */
36 #define SYSTICK_HZ 1250
37 #define RTC_DIVIDER 2 /* Must be power of 2; this results in 625Hz "RTC" */
38 
39 #define PIOS_RTC_MAX_CALLBACKS 3
40 
42  void (*fn)(uintptr_t);
43  uintptr_t data;
44 };
45 
47 
48 static void PIOS_DELAY_Systick_Handler(void) __attribute__((isr));
49 static void PIOS_RTC_Tick();
50 
51 const void *_systick_vector __attribute((section(".systick_vector"))) = PIOS_DELAY_Systick_Handler;
52 
53 static volatile uint32_t systick_cnt;
54 
55 static void PIOS_DELAY_Systick_Handler(void)
56 {
57  systick_cnt++;
58 
59  if ((systick_cnt & (RTC_DIVIDER - 1)) == 0) {
60  PIOS_RTC_Tick();
61  }
62 }
63 
69 int32_t PIOS_DELAY_Init(void)
70 {
71  /* Count up at HCLK frequency .. */
72  SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK);
73  /* Request ~1ms tickiness -- .977ms actually */
74 
75  SysTick_Config(SYSCLK_FREQ / SYSTICK_HZ);
76 
77  return 0;
78 }
79 
91 int32_t PIOS_DELAY_WaituS(uint32_t us)
92 {
93  PIOS_Assert(us < 0x80000000);
94 
95  uint32_t initial = PIOS_DELAY_GetuS();
96  uint32_t expires = initial + us;
97  uint32_t offset = 0;
98 
99  if (initial > expires) {
100  offset = 0x80000000;
101  expires += offset;
102  }
103 
104  while ((PIOS_DELAY_GetuS() + offset) < expires);
105 
106  /* No error */
107  return 0;
108 }
109 
121 int32_t PIOS_DELAY_WaitmS(uint32_t ms)
122 {
123  // ~ 2147 seconds is a long time to busywait.
124  PIOS_Assert(ms < (0x8000000 / 1000));
125 
126  return PIOS_DELAY_WaituS(ms * 1000);
127 }
128 
133 uint32_t PIOS_DELAY_GetuS()
134 {
135  /* XXX fixup to be more precise */
136  return systick_cnt * SYSTICK_HZ;
137 }
138 
144 uint32_t PIOS_DELAY_GetuSSince(uint32_t t)
145 {
146  return PIOS_DELAY_GetuS() - t;
147 }
148 
153 uint32_t PIOS_DELAY_GetRaw()
154 {
155  return PIOS_DELAY_GetuS();
156 }
157 
162 uint32_t PIOS_DELAY_DiffuS(uint32_t raw)
163 {
164  return PIOS_DELAY_GetuSSince(raw);
165 }
166 
171 uint32_t PIOS_DELAY_DiffuS2(uint32_t raw, uint32_t later) {
172  return later - raw;
173 }
174 
176 {
177  return ((float) SYSTICK_HZ) / RTC_DIVIDER;
178 }
179 
181 {
182  return 1000 / ((float) SYSTICK_HZ) * RTC_DIVIDER;
183 }
184 
185 bool PIOS_RTC_RegisterTickCallback(void (*fn)(uintptr_t id), uintptr_t data)
186 {
187  for (int i = 0; i < PIOS_RTC_MAX_CALLBACKS; i++) {
188  if (!rtc_callback_list[i].fn) {
189  struct rtc_callback_entry *cb;
190 
191  cb = &rtc_callback_list[i];
192 
193  cb->fn = fn;
194  cb->data = data;
195 
196  return true;
197  }
198  }
199 
200  return false;
201 }
202 
203 static void PIOS_RTC_Tick()
204 {
205  for (int i = 0; i < PIOS_RTC_MAX_CALLBACKS; i++) {
206  if (rtc_callback_list[i].fn) {
208  }
209  }
210 }
211 
uint32_t PIOS_DELAY_DiffuS(uint32_t raw)
Subtract raw time from now and convert to us.
Definition: pios_delay.c:159
uint32_t PIOS_DELAY_GetuS()
Query the Delay timer for the current uS.
Definition: pios_delay.c:173
Main PiOS header to include all the compiled in PiOS options.
bool PIOS_RTC_RegisterTickCallback(void(*fn)(uintptr_t id), uintptr_t data)
Definition: pios_delay.c:185
#define RTC_DIVIDER
Definition: pios_delay.c:37
struct msp_ident __attribute((packed))
uint32_t PIOS_DELAY_DiffuS2(uint32_t raw, uint32_t baseline)
Subrtact two raw times and convert to us.
Definition: pios_delay.c:164
Definition: pios_delay.c:41
uint32_t PIOS_DELAY_GetuSSince(uint32_t t)
Calculate time in microseconds since a previous time.
Definition: pios_delay.c:183
int32_t PIOS_DELAY_Init(void)
Definition: pios_delay.c:98
float PIOS_RTC_Rate()
Definition: pios_delay.c:175
uint8_t data[XFER_BYTES_PER_PACKET]
Definition: bl_messages.h:129
static struct rtc_callback_entry rtc_callback_list[PIOS_RTC_MAX_CALLBACKS]
Definition: pios_delay.c:46
#define SYSTICK_HZ
Definition: pios_delay.c:36
static void PIOS_DELAY_Systick_Handler(void)
Definition: pios_delay.c:48
uintptr_t data
Definition: pios_delay.c:43
void(* fn)(uintptr_t)
Definition: pios_delay.c:42
uint8_t i
Definition: msp_messages.h:97
float PIOS_RTC_MsPerTick()
Definition: pios_delay.c:180
uint32_t offset
Definition: uavtalk_priv.h:51
static void PIOS_RTC_Tick()
Definition: pios_delay.c:203
#define PIOS_RTC_MAX_CALLBACKS
Definition: pios_delay.c:39
#define PIOS_Assert(test)
Definition: pios_debug.h:52
int32_t PIOS_DELAY_WaitmS(uint32_t mS)
Definition: pios_delay.c:140
int32_t PIOS_DELAY_WaituS(uint32_t uS)
Definition: pios_delay.c:116
uint32_t PIOS_DELAY_GetRaw()
Get the raw delay timer, useful for timing.
Definition: pios_delay.c:153