My Marlin configs for Fabrikator Mini and CTC i3 Pro B
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

timers.cpp 5.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. /**
  2. * Marlin 3D Printer Firmware
  3. *
  4. * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
  5. * Copyright (c) 2016 Bob Cousins bobcousins42@googlemail.com
  6. * Copyright (c) 2015-2016 Nico Tonnhofer wurstnase.reprap@gmail.com
  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. #if defined(ARDUINO_ARCH_STM32) && !defined(STM32GENERIC)
  23. #include "HAL.h"
  24. #include "timers.h"
  25. // ------------------------
  26. // Local defines
  27. // ------------------------
  28. #define NUM_HARDWARE_TIMERS 2
  29. #define __TIMER_DEV(X) TIM##X
  30. #define _TIMER_DEV(X) __TIMER_DEV(X)
  31. #define STEP_TIMER_DEV _TIMER_DEV(STEP_TIMER)
  32. #define TEMP_TIMER_DEV _TIMER_DEV(TEMP_TIMER)
  33. // ------------------------
  34. // Private Variables
  35. // ------------------------
  36. HardwareTimer *timer_instance[NUM_HARDWARE_TIMERS] = { NULL };
  37. bool timer_enabled[NUM_HARDWARE_TIMERS] = { false };
  38. // ------------------------
  39. // Public functions
  40. // ------------------------
  41. // frequency is in Hertz
  42. void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency) {
  43. if (!HAL_timer_initialized(timer_num)) {
  44. switch (timer_num) {
  45. case STEP_TIMER_NUM: // STEPPER TIMER - use a 32bit timer if possible
  46. timer_instance[timer_num] = new HardwareTimer(STEP_TIMER_DEV);
  47. /* Set the prescaler to the final desired value.
  48. * This will change the effective ISR callback frequency but when
  49. * HAL_timer_start(timer_num=0) is called in the core for the first time
  50. * the real frequency isn't important as long as, after boot, the ISR
  51. * gets called with the correct prescaler and count register. So here
  52. * we set the prescaler to the correct, final value and ignore the frequency
  53. * asked. We will call back the ISR in 1 second to start at full speed.
  54. *
  55. * The proper fix, however, would be a correct initialization OR a
  56. * HAL_timer_change(const uint8_t timer_num, const uint32_t frequency)
  57. * which changes the prescaler when an IRQ frequency change is needed
  58. * (for example when steppers are turned on)
  59. */
  60. timer_instance[timer_num]->setPrescaleFactor(STEPPER_TIMER_PRESCALE); //the -1 is done internally
  61. timer_instance[timer_num]->setOverflow(_MIN(hal_timer_t(HAL_TIMER_TYPE_MAX), (HAL_TIMER_RATE) / (STEPPER_TIMER_PRESCALE) /* /frequency */), TICK_FORMAT);
  62. break;
  63. case TEMP_TIMER_NUM: // TEMP TIMER - any available 16bit timer
  64. timer_instance[timer_num] = new HardwareTimer(TEMP_TIMER_DEV);
  65. // The prescale factor is computed automatically for HERTZ_FORMAT
  66. timer_instance[timer_num]->setOverflow(frequency, HERTZ_FORMAT);
  67. break;
  68. }
  69. HAL_timer_enable_interrupt(timer_num);
  70. /*
  71. * Initializes (and unfortunately starts) the timer.
  72. * This is needed to set correct IRQ priority at the moment but causes
  73. * no harm since every call to HAL_timer_start() is actually followed by
  74. * a call to HAL_timer_enable_interrupt() which means that there isn't
  75. * a case in which you want the timer to run without a callback.
  76. */
  77. timer_instance[timer_num]->resume(); // First call to resume() MUST follow the attachInterrupt()
  78. // This is fixed in Arduino_Core_STM32 1.8.
  79. // These calls can be removed and replaced with
  80. // timer_instance[timer_num]->setInterruptPriority
  81. switch (timer_num) {
  82. case STEP_TIMER_NUM:
  83. HAL_NVIC_SetPriority(STEP_TIMER_IRQ_NAME, STEP_TIMER_IRQ_PRIO, 0);
  84. break;
  85. case TEMP_TIMER_NUM:
  86. HAL_NVIC_SetPriority(TEMP_TIMER_IRQ_NAME, TEMP_TIMER_IRQ_PRIO, 0);
  87. break;
  88. }
  89. }
  90. }
  91. void HAL_timer_enable_interrupt(const uint8_t timer_num) {
  92. if (HAL_timer_initialized(timer_num) && !timer_enabled[timer_num]) {
  93. timer_enabled[timer_num] = true;
  94. switch (timer_num) {
  95. case STEP_TIMER_NUM:
  96. timer_instance[timer_num]->attachInterrupt(Step_Handler);
  97. break;
  98. case TEMP_TIMER_NUM:
  99. timer_instance[timer_num]->attachInterrupt(Temp_Handler);
  100. break;
  101. }
  102. }
  103. }
  104. void HAL_timer_disable_interrupt(const uint8_t timer_num) {
  105. if (HAL_timer_interrupt_enabled(timer_num)) {
  106. timer_instance[timer_num]->detachInterrupt();
  107. timer_enabled[timer_num] = false;
  108. }
  109. }
  110. bool HAL_timer_interrupt_enabled(const uint8_t timer_num) {
  111. return HAL_timer_initialized(timer_num) && timer_enabled[timer_num];
  112. }
  113. // Only for use within the HAL
  114. TIM_TypeDef * HAL_timer_device(const uint8_t timer_num) {
  115. switch (timer_num) {
  116. case STEP_TIMER_NUM: return STEP_TIMER_DEV;
  117. case TEMP_TIMER_NUM: return TEMP_TIMER_DEV;
  118. }
  119. return nullptr;
  120. }
  121. #endif // ARDUINO_ARCH_STM32 && !STM32GENERIC