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.

Servo_Due.cpp 6.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. /**
  2. * Marlin 3D Printer Firmware
  3. * Copyright (c) 2019 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. Copyright (c) 2013 Arduino LLC. All right reserved.
  24. This library is free software; you can redistribute it and/or
  25. modify it under the terms of the GNU Lesser General Public
  26. License as published by the Free Software Foundation; either
  27. version 2.1 of the License, or (at your option) any later version.
  28. This library is distributed in the hope that it will be useful,
  29. but WITHOUT ANY WARRANTY; without even the implied warranty of
  30. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  31. Lesser General Public License for more details.
  32. You should have received a copy of the GNU Lesser General Public
  33. License along with this library; if not, write to the Free Software
  34. Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  35. */
  36. #ifdef ARDUINO_ARCH_SAM
  37. #include "../../inc/MarlinConfig.h"
  38. #if HAS_SERVOS
  39. #include "../shared/Marduino.h"
  40. #include "../shared/servo.h"
  41. #include "../shared/servo_private.h"
  42. static volatile int8_t Channel[_Nbr_16timers]; // counter for the servo being pulsed for each timer (or -1 if refresh interval)
  43. //------------------------------------------------------------------------------
  44. /// Interrupt handler for the TC0 channel 1.
  45. //------------------------------------------------------------------------------
  46. void Servo_Handler(timer16_Sequence_t timer, Tc *pTc, uint8_t channel);
  47. #ifdef _useTimer1
  48. void HANDLER_FOR_TIMER1(void) { Servo_Handler(_timer1, TC_FOR_TIMER1, CHANNEL_FOR_TIMER1); }
  49. #endif
  50. #ifdef _useTimer2
  51. void HANDLER_FOR_TIMER2(void) { Servo_Handler(_timer2, TC_FOR_TIMER2, CHANNEL_FOR_TIMER2); }
  52. #endif
  53. #ifdef _useTimer3
  54. void HANDLER_FOR_TIMER3(void) { Servo_Handler(_timer3, TC_FOR_TIMER3, CHANNEL_FOR_TIMER3); }
  55. #endif
  56. #ifdef _useTimer4
  57. void HANDLER_FOR_TIMER4(void) { Servo_Handler(_timer4, TC_FOR_TIMER4, CHANNEL_FOR_TIMER4); }
  58. #endif
  59. #ifdef _useTimer5
  60. void HANDLER_FOR_TIMER5(void) { Servo_Handler(_timer5, TC_FOR_TIMER5, CHANNEL_FOR_TIMER5); }
  61. #endif
  62. void Servo_Handler(timer16_Sequence_t timer, Tc *tc, uint8_t channel) {
  63. // clear interrupt
  64. tc->TC_CHANNEL[channel].TC_SR;
  65. if (Channel[timer] < 0)
  66. tc->TC_CHANNEL[channel].TC_CCR |= TC_CCR_SWTRG; // channel set to -1 indicated that refresh interval completed so reset the timer
  67. else if (SERVO_INDEX(timer, Channel[timer]) < ServoCount && SERVO(timer, Channel[timer]).Pin.isActive)
  68. extDigitalWrite(SERVO(timer, Channel[timer]).Pin.nbr, LOW); // pulse this channel low if activated
  69. Channel[timer]++; // increment to the next channel
  70. if (SERVO_INDEX(timer, Channel[timer]) < ServoCount && Channel[timer] < SERVOS_PER_TIMER) {
  71. tc->TC_CHANNEL[channel].TC_RA = tc->TC_CHANNEL[channel].TC_CV + SERVO(timer,Channel[timer]).ticks;
  72. if (SERVO(timer,Channel[timer]).Pin.isActive) // check if activated
  73. extDigitalWrite(SERVO(timer, Channel[timer]).Pin.nbr, HIGH); // its an active channel so pulse it high
  74. }
  75. else {
  76. // finished all channels so wait for the refresh period to expire before starting over
  77. tc->TC_CHANNEL[channel].TC_RA =
  78. tc->TC_CHANNEL[channel].TC_CV < usToTicks(REFRESH_INTERVAL) - 4
  79. ? (unsigned int)usToTicks(REFRESH_INTERVAL) // allow a few ticks to ensure the next OCR1A not missed
  80. : tc->TC_CHANNEL[channel].TC_CV + 4; // at least REFRESH_INTERVAL has elapsed
  81. Channel[timer] = -1; // this will get incremented at the end of the refresh period to start again at the first channel
  82. }
  83. }
  84. static void _initISR(Tc *tc, uint32_t channel, uint32_t id, IRQn_Type irqn) {
  85. pmc_enable_periph_clk(id);
  86. TC_Configure(tc, channel,
  87. TC_CMR_TCCLKS_TIMER_CLOCK3 | // MCK/32
  88. TC_CMR_WAVE | // Waveform mode
  89. TC_CMR_WAVSEL_UP_RC ); // Counter running up and reset when equals to RC
  90. /* 84MHz, MCK/32, for 1.5ms: 3937 */
  91. TC_SetRA(tc, channel, 2625); // 1ms
  92. /* Configure and enable interrupt */
  93. NVIC_EnableIRQ(irqn);
  94. // TC_IER_CPAS: RA Compare
  95. tc->TC_CHANNEL[channel].TC_IER = TC_IER_CPAS;
  96. // Enables the timer clock and performs a software reset to start the counting
  97. TC_Start(tc, channel);
  98. }
  99. void initISR(timer16_Sequence_t timer) {
  100. #ifdef _useTimer1
  101. if (timer == _timer1)
  102. _initISR(TC_FOR_TIMER1, CHANNEL_FOR_TIMER1, ID_TC_FOR_TIMER1, IRQn_FOR_TIMER1);
  103. #endif
  104. #ifdef _useTimer2
  105. if (timer == _timer2)
  106. _initISR(TC_FOR_TIMER2, CHANNEL_FOR_TIMER2, ID_TC_FOR_TIMER2, IRQn_FOR_TIMER2);
  107. #endif
  108. #ifdef _useTimer3
  109. if (timer == _timer3)
  110. _initISR(TC_FOR_TIMER3, CHANNEL_FOR_TIMER3, ID_TC_FOR_TIMER3, IRQn_FOR_TIMER3);
  111. #endif
  112. #ifdef _useTimer4
  113. if (timer == _timer4)
  114. _initISR(TC_FOR_TIMER4, CHANNEL_FOR_TIMER4, ID_TC_FOR_TIMER4, IRQn_FOR_TIMER4);
  115. #endif
  116. #ifdef _useTimer5
  117. if (timer == _timer5)
  118. _initISR(TC_FOR_TIMER5, CHANNEL_FOR_TIMER5, ID_TC_FOR_TIMER5, IRQn_FOR_TIMER5);
  119. #endif
  120. }
  121. void finISR(timer16_Sequence_t timer) {
  122. #ifdef _useTimer1
  123. TC_Stop(TC_FOR_TIMER1, CHANNEL_FOR_TIMER1);
  124. #endif
  125. #ifdef _useTimer2
  126. TC_Stop(TC_FOR_TIMER2, CHANNEL_FOR_TIMER2);
  127. #endif
  128. #ifdef _useTimer3
  129. TC_Stop(TC_FOR_TIMER3, CHANNEL_FOR_TIMER3);
  130. #endif
  131. #ifdef _useTimer4
  132. TC_Stop(TC_FOR_TIMER4, CHANNEL_FOR_TIMER4);
  133. #endif
  134. #ifdef _useTimer5
  135. TC_Stop(TC_FOR_TIMER5, CHANNEL_FOR_TIMER5);
  136. #endif
  137. }
  138. #endif // HAS_SERVOS
  139. #endif // ARDUINO_ARCH_SAM