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 
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 
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