delay.h 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. /**
  2. * Marlin 3D Printer Firmware
  3. * Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
  4. *
  5. * Based on Sprinter and grbl.
  6. * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
  7. *
  8. * This program is free software: you can redistribute it and/or modify
  9. * it under the terms of the GNU General Public License as published by
  10. * the Free Software Foundation, either version 3 of the License, or
  11. * (at your option) any later version.
  12. *
  13. * This program is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  20. *
  21. */
  22. /**
  23. * AVR busy wait delay Cycles routines:
  24. *
  25. * DELAY_CYCLES(count): Delay execution in cycles
  26. * DELAY_NS(count): Delay execution in nanoseconds
  27. * DELAY_US(count): Delay execution in microseconds
  28. */
  29. #ifndef MARLIN_DELAY_H
  30. #define MARLIN_DELAY_H
  31. #define nop() __asm__ __volatile__("nop;\n\t":::)
  32. FORCE_INLINE static void __delay_4cycles(uint8_t cy) {
  33. __asm__ __volatile__(
  34. L("1")
  35. A("dec %[cnt]")
  36. A("nop")
  37. A("brne 1b")
  38. : [cnt] "+r"(cy) // output: +r means input+output
  39. : // input:
  40. : "cc" // clobbers:
  41. );
  42. }
  43. /* ---------------- Delay in cycles */
  44. FORCE_INLINE static void DELAY_CYCLES(uint16_t x) {
  45. if (__builtin_constant_p(x)) {
  46. #define MAXNOPS 4
  47. if (x <= (MAXNOPS)) {
  48. switch (x) { case 4: nop(); case 3: nop(); case 2: nop(); case 1: nop(); }
  49. }
  50. else {
  51. const uint32_t rem = (x) % (MAXNOPS);
  52. switch (rem) { case 3: nop(); case 2: nop(); case 1: nop(); }
  53. if ((x = (x) / (MAXNOPS)))
  54. __delay_4cycles(x); // if need more then 4 nop loop is more optimal
  55. }
  56. #undef MAXNOPS
  57. }
  58. else
  59. __delay_4cycles(x / 4);
  60. }
  61. #undef nop
  62. /* ---------------- Delay in nanoseconds */
  63. #define DELAY_NS(x) DELAY_CYCLES( (x) * (F_CPU/1000000L) / 1000L )
  64. /* ---------------- Delay in microseconds */
  65. #define DELAY_US(x) DELAY_CYCLES( (x) * (F_CPU/1000000L) )
  66. #endif // MARLIN_DELAY_H