wait.h 3.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. #pragma once
  2. #include <inttypes.h>
  3. #ifdef __cplusplus
  4. extern "C" {
  5. #endif
  6. #if defined(__ARMEL__) || defined(__ARMEB__)
  7. # ifndef __OPTIMIZE__
  8. # pragma message "Compiler optimizations disabled; wait_cpuclock() won't work as designed"
  9. # endif
  10. # define wait_cpuclock(x) wait_cpuclock_allnop(x)
  11. # define CLOCK_DELAY_NOP8 "nop\n\t nop\n\t nop\n\t nop\n\t nop\n\t nop\n\t nop\n\t nop\n\t"
  12. __attribute__((always_inline))
  13. static inline void wait_cpuclock_allnop(unsigned int n) { /* n: 1..135 */
  14. /* The argument n must be a constant expression.
  15. * That way, compiler optimization will remove unnecessary code. */
  16. if (n < 1) { return; }
  17. if (n > 8) {
  18. unsigned int n8 = n/8;
  19. n = n - n8*8;
  20. switch (n8) {
  21. case 16: asm volatile (CLOCK_DELAY_NOP8::: "memory");
  22. case 15: asm volatile (CLOCK_DELAY_NOP8::: "memory");
  23. case 14: asm volatile (CLOCK_DELAY_NOP8::: "memory");
  24. case 13: asm volatile (CLOCK_DELAY_NOP8::: "memory");
  25. case 12: asm volatile (CLOCK_DELAY_NOP8::: "memory");
  26. case 11: asm volatile (CLOCK_DELAY_NOP8::: "memory");
  27. case 10: asm volatile (CLOCK_DELAY_NOP8::: "memory");
  28. case 9: asm volatile (CLOCK_DELAY_NOP8::: "memory");
  29. case 8: asm volatile (CLOCK_DELAY_NOP8::: "memory");
  30. case 7: asm volatile (CLOCK_DELAY_NOP8::: "memory");
  31. case 6: asm volatile (CLOCK_DELAY_NOP8::: "memory");
  32. case 5: asm volatile (CLOCK_DELAY_NOP8::: "memory");
  33. case 4: asm volatile (CLOCK_DELAY_NOP8::: "memory");
  34. case 3: asm volatile (CLOCK_DELAY_NOP8::: "memory");
  35. case 2: asm volatile (CLOCK_DELAY_NOP8::: "memory");
  36. case 1: asm volatile (CLOCK_DELAY_NOP8::: "memory");
  37. case 0: break;
  38. }
  39. }
  40. switch (n) {
  41. case 8: asm volatile ("nop"::: "memory");
  42. case 7: asm volatile ("nop"::: "memory");
  43. case 6: asm volatile ("nop"::: "memory");
  44. case 5: asm volatile ("nop"::: "memory");
  45. case 4: asm volatile ("nop"::: "memory");
  46. case 3: asm volatile ("nop"::: "memory");
  47. case 2: asm volatile ("nop"::: "memory");
  48. case 1: asm volatile ("nop"::: "memory");
  49. case 0: break;
  50. }
  51. }
  52. #endif
  53. #if defined(__AVR__)
  54. # include <util/delay.h>
  55. # define wait_ms(ms) _delay_ms(ms)
  56. # define wait_us(us) _delay_us(us)
  57. # define wait_cpuclock(x) __builtin_avr_delay_cycles(x)
  58. #elif defined PROTOCOL_CHIBIOS
  59. # include <ch.h>
  60. # define wait_ms(ms) \
  61. do { \
  62. if (ms != 0) { \
  63. chThdSleepMilliseconds(ms); \
  64. } else { \
  65. chThdSleepMicroseconds(1); \
  66. } \
  67. } while (0)
  68. # define wait_us(us) \
  69. do { \
  70. if (us != 0) { \
  71. chThdSleepMicroseconds(us); \
  72. } else { \
  73. chThdSleepMicroseconds(1); \
  74. } \
  75. } while (0)
  76. #elif defined PROTOCOL_ARM_ATSAM
  77. # include "clks.h"
  78. # define wait_ms(ms) CLK_delay_ms(ms)
  79. # define wait_us(us) CLK_delay_us(us)
  80. #else // Unit tests
  81. void wait_ms(uint32_t ms);
  82. # define wait_us(us) wait_ms(us / 1000)
  83. #endif
  84. #ifdef __cplusplus
  85. }
  86. #endif