gr55xx_delay.h
Go to the documentation of this file.
1
38 #ifndef __GR55xx_DELAY_H__
39 #define __GR55xx_DELAY_H__
40
41 #ifdef __cplusplus
42 extern "C" {
43 #endif
44
45 #include "gr55xx.h"
46
62 #define DELAY_US_DWT
64 #if defined ( __CC_ARM )
65
66 #ifndef __STATIC_FORCEINLINE
67 #define __STATIC_FORCEINLINE static __forceinline
68 #endif
69
70 #elif defined ( __GNUC__ )
71
72 #ifndef __STATIC_FORCEINLINE
73 #define __STATIC_FORCEINLINE __attribute__((always_inline)) static inline
74 #endif
75
76 #else
77
78 #ifndef __STATIC_FORCEINLINE
79 #define __STATIC_FORCEINLINE __STATIC_INLINE
80 #endif
81
82 #endif
83
85 #ifndef DELAY_US_DWT
86
92 typedef void (* delay_func_t)(uint32_t);
94 #endif
95
96 #if defined(GR5515_E)
97
108 void delay_us(uint32_t number_of_us);
111 #else
112 #ifdef DELAY_US_DWT
113
123 void hal_dwt_enable(uint32_t _demcr_initial, uint32_t _dwt_ctrl_initial);
124
132 void hal_dwt_disable(uint32_t _demcr_initial, uint32_t _dwt_ctrl_initial);
142 #define HAL_TIMEOUT_INIT() \
143 uint32_t _demcr_initial = CoreDebug->DEMCR; \
144 uint32_t _dwt_ctrl_initial = DWT->CTRL; \
145 do { \
146 hal_dwt_enable(_demcr_initial, _dwt_ctrl_initial); \
147 } while (0)
148
153 #define HAL_TIMEOUT_DEINIT() \
154 do { \
155 hal_dwt_disable(_demcr_initial, _dwt_ctrl_initial); \
156 } while(0)
157
170 __STATIC_FORCEINLINE void delay_us(uint32_t number_of_us)
171 {
172 const uint8_t clocks[] = {64, 48, 16, 24, 16, 32};
173 uint32_t cycles = number_of_us * (clocks[AON->PWR_RET01 & AON_PWR_REG01_SYS_CLK_SEL]);
174
175 if (number_of_us == 0)
176 {
177 return;
178 }
179
180 HAL_TIMEOUT_INIT();
181
182 // Get start value of the cycle counter.
183 uint32_t cyccnt_initial = DWT->CYCCNT;
184
185 // Wait time end
186 while ((DWT->CYCCNT - cyccnt_initial) < cycles)
187 {}
188
189 HAL_TIMEOUT_DEINIT();
190 }
192 #endif
193
194 #ifndef DELAY_US_DWT
195
196 #if defined ( __CC_ARM )
197
198 #pragma push
199 #pragma O2
200
211 __STATIC_FORCEINLINE void delay_us(uint32_t number_of_us)
212 {
213 uint32_t pc = (unsigned int)__current_pc();
214 uint8_t clocks[] = {64, 48, 16, 24, 16, 32};
215
216 if (number_of_us == 0)
217 {
218 return;
219 }
220
221 static const uint16_t delay_ramcode[] = {
222 0x3809, // SUBS r0, #9
223 0xd8fd, // BHI .-2
224 0x4770 // BX LR
225 };
226 // Set LSB to 1 to execute code in Thumb mode.
227 const delay_func_t delay_ram_cycles = (delay_func_t)((((uint32_t)delay_ramcode) | 1));
228
229 static const uint16_t delay_flashcode[] = {
230 0x3803, // SUBS r0, #3
231 0xd8fd, // BHI .-2
232 0x4770 // BX LR
233 };
234 // Set LSB to 1 to execute code in Thumb mode.
235 const delay_func_t delay_flash_cycles = (delay_func_t)((((uint32_t)delay_flashcode) | 1));
236
237 static const uint16_t delay_aliascode[] = {
238 0x3803, // SUBS r0, #3
239 0xd8fd, // BHI .-2
240 0x4770 // BX LR
241 };
242 // Set LSB to 1 to execute code in Thumb mode.
243 const delay_func_t delay_alias_cycles = (delay_func_t)((((uint32_t)delay_aliascode) | 1));
244
245 uint32_t cycles = number_of_us * (clocks[AON->PWR_RET01 & AON_PWR_REG01_SYS_CLK_SEL]);
246
247 if(pc & GR55XX_RAM_ADDRESS)
248 delay_ram_cycles(cycles);
249 else if(pc & GR55XX_FLASH_ADDRESS)
250 delay_flash_cycles(cycles);
251 else if(pc & GR55XX_ALIAS_ADDRESS)
252 delay_alias_cycles(cycles);
253 else
254 {
255 cycles = cycles / 4;
256 __asm
257 {
258 loop:
259 NOP
260 SUBS cycles, #1
261 BNE loop
262 }
263 }
264 }
265 #pragma pop
266
267 #elif defined ( _WIN32 ) || defined ( __unix ) || defined ( __APPLE__ )
268
269 #ifndef CUSTOM_DELAY_US
270
277 __STATIC_FORCEINLINE void delay_us(uint32_t number_of_us)
278 {
279 }
280 #endif
281
282 #elif defined ( __GNUC__ ) || ( __ICCARM__ )
283
290 __STATIC_FORCEINLINE void delay_us(uint32_t number_of_us)
291 {
292 uint8_t clocks[] = {64, 48, 16, 24, 16, 32};
293
294 if (number_of_us)
295 {
296 uint32_t cycles;
297 cycles = number_of_us*(clocks[AON->PWR_RET01 & AON_PWR_REG01_SYS_CLK_SEL])/6;
298 __asm__ volatile ("1:\n"
299 "NOP\n"
300 "NOP\n"
301 "NOP\n"
302 "SUBS %[cycles], %[cycles], #1\n"
303 "BNE.N 1b\n"
304 : [cycles] "=r" (cycles)
305 : "[cycles]" "r" (cycles)
306 );
307 }
308 }
310 #endif
311
312 #endif
313
314 #endif
315
331 #if defined(GR5515_E)
332 void delay_ms(uint32_t number_of_ms);
333 #else
334 __STATIC_FORCEINLINE void delay_ms(uint32_t number_of_ms)
335 {
336 delay_us(1000 * number_of_ms);
337 return;
338 }
339 #endif
340
342 #ifdef __cplusplus
343 }
344 #endif
345
346 #endif /* __GR55xx_DELAY_H__ */
347
hal_dwt_disable
void hal_dwt_disable(uint32_t _demcr_initial, uint32_t _dwt_ctrl_initial)
Disable the DWT.
HAL_TIMEOUT_INIT
#define HAL_TIMEOUT_INIT()
Timeout module init. This macro must be used in conjunction with the HAL_TIMEOUT_DEINIT macro.
Definition: gr55xx_delay.h:142
delay_ms
__STATIC_FORCEINLINE void delay_ms(uint32_t number_of_ms)
Function for delaying execution for number of milliseconds.
Definition: gr55xx_delay.h:334
delay_us
__STATIC_FORCEINLINE void delay_us(uint32_t number_of_us)
Function for delaying execution for number of us.
Definition: gr55xx_delay.h:170
hal_dwt_enable
void hal_dwt_enable(uint32_t _demcr_initial, uint32_t _dwt_ctrl_initial)
Enable the DWT.
__STATIC_FORCEINLINE
#define __STATIC_FORCEINLINE
Definition: gr55xx_delay.h:79
HAL_TIMEOUT_DEINIT
#define HAL_TIMEOUT_DEINIT()
Timeout module deinit. This macro must be used in conjunction with the HAL_TIMEOUT_INIT macro.
Definition: gr55xx_delay.h:153