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.

M569.cpp 9.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239
  1. /**
  2. * Marlin 3D Printer Firmware
  3. * Copyright (c) 2020 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 <https://www.gnu.org/licenses/>.
  20. *
  21. */
  22. #include "../../../inc/MarlinConfig.h"
  23. #if HAS_STEALTHCHOP
  24. #if AXIS_COLLISION('I')
  25. #error "M569 parameter 'I' collision with axis name."
  26. #endif
  27. #include "../../gcode.h"
  28. #include "../../../feature/tmc_util.h"
  29. #include "../../../module/stepper/indirection.h"
  30. template<typename TMC>
  31. void tmc_say_stealth_status(TMC &st) {
  32. st.printLabel();
  33. SERIAL_ECHOPGM(" driver mode:\t");
  34. SERIAL_ECHOLNF(st.get_stealthChop() ? F("stealthChop") : F("spreadCycle"));
  35. }
  36. template<typename TMC>
  37. void tmc_set_stealthChop(TMC &st, const bool enable) {
  38. st.stored.stealthChop_enabled = enable;
  39. st.refresh_stepping_mode();
  40. }
  41. static void set_stealth_status(const bool enable, const int8_t eindex) {
  42. #define TMC_SET_STEALTH(Q) tmc_set_stealthChop(stepper##Q, enable)
  43. #if X2_HAS_STEALTHCHOP || Y2_HAS_STEALTHCHOP || Z2_HAS_STEALTHCHOP || Z3_HAS_STEALTHCHOP || Z4_HAS_STEALTHCHOP
  44. const int8_t index = parser.byteval('I', -1);
  45. #else
  46. constexpr int8_t index = -1;
  47. #endif
  48. LOOP_LOGICAL_AXES(i) if (parser.seen(AXIS_CHAR(i))) {
  49. switch (i) {
  50. case X_AXIS:
  51. TERN_(X_HAS_STEALTHCHOP, if (index < 0 || index == 0) TMC_SET_STEALTH(X));
  52. TERN_(X2_HAS_STEALTHCHOP, if (index < 0 || index == 1) TMC_SET_STEALTH(X2));
  53. break;
  54. #if HAS_Y_AXIS
  55. case Y_AXIS:
  56. TERN_(Y_HAS_STEALTHCHOP, if (index < 0 || index == 0) TMC_SET_STEALTH(Y));
  57. TERN_(Y2_HAS_STEALTHCHOP, if (index < 0 || index == 1) TMC_SET_STEALTH(Y2));
  58. break;
  59. #endif
  60. #if HAS_Z_AXIS
  61. case Z_AXIS:
  62. TERN_(Z_HAS_STEALTHCHOP, if (index < 0 || index == 0) TMC_SET_STEALTH(Z));
  63. TERN_(Z2_HAS_STEALTHCHOP, if (index < 0 || index == 1) TMC_SET_STEALTH(Z2));
  64. TERN_(Z3_HAS_STEALTHCHOP, if (index < 0 || index == 2) TMC_SET_STEALTH(Z3));
  65. TERN_(Z4_HAS_STEALTHCHOP, if (index < 0 || index == 3) TMC_SET_STEALTH(Z4));
  66. break;
  67. #endif
  68. #if I_HAS_STEALTHCHOP
  69. case I_AXIS: TMC_SET_STEALTH(I); break;
  70. #endif
  71. #if J_HAS_STEALTHCHOP
  72. case J_AXIS: TMC_SET_STEALTH(J); break;
  73. #endif
  74. #if K_HAS_STEALTHCHOP
  75. case K_AXIS: TMC_SET_STEALTH(K); break;
  76. #endif
  77. #if U_HAS_STEALTHCHOP
  78. case U_AXIS: TMC_SET_STEALTH(U); break;
  79. #endif
  80. #if V_HAS_STEALTHCHOP
  81. case V_AXIS: TMC_SET_STEALTH(V); break;
  82. #endif
  83. #if W_HAS_STEALTHCHOP
  84. case W_AXIS: TMC_SET_STEALTH(W); break;
  85. #endif
  86. #if E_STEPPERS
  87. case E_AXIS: {
  88. TERN_(E0_HAS_STEALTHCHOP, if (eindex < 0 || eindex == 0) TMC_SET_STEALTH(E0));
  89. TERN_(E1_HAS_STEALTHCHOP, if (eindex < 0 || eindex == 1) TMC_SET_STEALTH(E1));
  90. TERN_(E2_HAS_STEALTHCHOP, if (eindex < 0 || eindex == 2) TMC_SET_STEALTH(E2));
  91. TERN_(E3_HAS_STEALTHCHOP, if (eindex < 0 || eindex == 3) TMC_SET_STEALTH(E3));
  92. TERN_(E4_HAS_STEALTHCHOP, if (eindex < 0 || eindex == 4) TMC_SET_STEALTH(E4));
  93. TERN_(E5_HAS_STEALTHCHOP, if (eindex < 0 || eindex == 5) TMC_SET_STEALTH(E5));
  94. TERN_(E6_HAS_STEALTHCHOP, if (eindex < 0 || eindex == 6) TMC_SET_STEALTH(E6));
  95. TERN_(E7_HAS_STEALTHCHOP, if (eindex < 0 || eindex == 7) TMC_SET_STEALTH(E7));
  96. } break;
  97. #endif
  98. }
  99. }
  100. }
  101. static void say_stealth_status() {
  102. #define TMC_SAY_STEALTH_STATUS(Q) tmc_say_stealth_status(stepper##Q)
  103. OPTCODE( X_HAS_STEALTHCHOP, TMC_SAY_STEALTH_STATUS(X))
  104. OPTCODE(X2_HAS_STEALTHCHOP, TMC_SAY_STEALTH_STATUS(X2))
  105. OPTCODE( Y_HAS_STEALTHCHOP, TMC_SAY_STEALTH_STATUS(Y))
  106. OPTCODE(Y2_HAS_STEALTHCHOP, TMC_SAY_STEALTH_STATUS(Y2))
  107. OPTCODE( Z_HAS_STEALTHCHOP, TMC_SAY_STEALTH_STATUS(Z))
  108. OPTCODE(Z2_HAS_STEALTHCHOP, TMC_SAY_STEALTH_STATUS(Z2))
  109. OPTCODE(Z3_HAS_STEALTHCHOP, TMC_SAY_STEALTH_STATUS(Z3))
  110. OPTCODE(Z4_HAS_STEALTHCHOP, TMC_SAY_STEALTH_STATUS(Z4))
  111. OPTCODE( I_HAS_STEALTHCHOP, TMC_SAY_STEALTH_STATUS(I))
  112. OPTCODE( J_HAS_STEALTHCHOP, TMC_SAY_STEALTH_STATUS(J))
  113. OPTCODE( K_HAS_STEALTHCHOP, TMC_SAY_STEALTH_STATUS(K))
  114. OPTCODE( U_HAS_STEALTHCHOP, TMC_SAY_STEALTH_STATUS(U))
  115. OPTCODE( V_HAS_STEALTHCHOP, TMC_SAY_STEALTH_STATUS(V))
  116. OPTCODE( W_HAS_STEALTHCHOP, TMC_SAY_STEALTH_STATUS(W))
  117. OPTCODE(E0_HAS_STEALTHCHOP, TMC_SAY_STEALTH_STATUS(E0))
  118. OPTCODE(E1_HAS_STEALTHCHOP, TMC_SAY_STEALTH_STATUS(E1))
  119. OPTCODE(E2_HAS_STEALTHCHOP, TMC_SAY_STEALTH_STATUS(E2))
  120. OPTCODE(E3_HAS_STEALTHCHOP, TMC_SAY_STEALTH_STATUS(E3))
  121. OPTCODE(E4_HAS_STEALTHCHOP, TMC_SAY_STEALTH_STATUS(E4))
  122. OPTCODE(E5_HAS_STEALTHCHOP, TMC_SAY_STEALTH_STATUS(E5))
  123. OPTCODE(E6_HAS_STEALTHCHOP, TMC_SAY_STEALTH_STATUS(E6))
  124. OPTCODE(E7_HAS_STEALTHCHOP, TMC_SAY_STEALTH_STATUS(E7))
  125. }
  126. /**
  127. * M569: Enable stealthChop on an axis
  128. *
  129. * S[1|0] to enable or disable
  130. * XYZE to target an axis
  131. * No arguments reports the stealthChop status of all capable drivers.
  132. */
  133. void GcodeSuite::M569() {
  134. if (parser.seen('S'))
  135. set_stealth_status(parser.value_bool(), get_target_e_stepper_from_command(-2));
  136. else
  137. say_stealth_status();
  138. }
  139. void GcodeSuite::M569_report(const bool forReplay/*=true*/) {
  140. report_heading(forReplay, F(STR_DRIVER_STEPPING_MODE));
  141. auto say_M569 = [](const bool forReplay, FSTR_P const etc=nullptr, const bool eol=false) {
  142. if (!forReplay) SERIAL_ECHO_START();
  143. SERIAL_ECHOPGM(" M569 S1");
  144. if (etc) {
  145. SERIAL_CHAR(' ');
  146. SERIAL_ECHOF(etc);
  147. }
  148. if (eol) SERIAL_EOL();
  149. };
  150. const bool chop_x = TERN0(X_HAS_STEALTHCHOP, stepperX.get_stored_stealthChop()),
  151. chop_y = TERN0(Y_HAS_STEALTHCHOP, stepperY.get_stored_stealthChop()),
  152. chop_z = TERN0(Z_HAS_STEALTHCHOP, stepperZ.get_stored_stealthChop()),
  153. chop_i = TERN0(I_HAS_STEALTHCHOP, stepperI.get_stored_stealthChop()),
  154. chop_j = TERN0(J_HAS_STEALTHCHOP, stepperJ.get_stored_stealthChop()),
  155. chop_k = TERN0(K_HAS_STEALTHCHOP, stepperK.get_stored_stealthChop()),
  156. chop_u = TERN0(U_HAS_STEALTHCHOP, stepperU.get_stored_stealthChop()),
  157. chop_v = TERN0(V_HAS_STEALTHCHOP, stepperV.get_stored_stealthChop()),
  158. chop_w = TERN0(W_HAS_STEALTHCHOP, stepperW.get_stored_stealthChop());
  159. if (chop_x || chop_y || chop_z || chop_i || chop_j || chop_k || chop_u || chop_v || chop_w) {
  160. say_M569(forReplay);
  161. NUM_AXIS_CODE(
  162. if (chop_x) SERIAL_ECHOPGM_P(SP_X_STR),
  163. if (chop_y) SERIAL_ECHOPGM_P(SP_Y_STR),
  164. if (chop_z) SERIAL_ECHOPGM_P(SP_Z_STR),
  165. if (chop_i) SERIAL_ECHOPGM_P(SP_I_STR),
  166. if (chop_j) SERIAL_ECHOPGM_P(SP_J_STR),
  167. if (chop_k) SERIAL_ECHOPGM_P(SP_K_STR),
  168. if (chop_u) SERIAL_ECHOPGM_P(SP_U_STR),
  169. if (chop_v) SERIAL_ECHOPGM_P(SP_V_STR),
  170. if (chop_w) SERIAL_ECHOPGM_P(SP_W_STR)
  171. );
  172. SERIAL_EOL();
  173. }
  174. const bool chop_x2 = TERN0(X2_HAS_STEALTHCHOP, stepperX2.get_stored_stealthChop()),
  175. chop_y2 = TERN0(Y2_HAS_STEALTHCHOP, stepperY2.get_stored_stealthChop()),
  176. chop_z2 = TERN0(Z2_HAS_STEALTHCHOP, stepperZ2.get_stored_stealthChop());
  177. if (chop_x2 || chop_y2 || chop_z2) {
  178. say_M569(forReplay, F("I1"));
  179. if (chop_x2) SERIAL_ECHOPGM_P(SP_X_STR);
  180. #if HAS_Y_AXIS
  181. if (chop_y2) SERIAL_ECHOPGM_P(SP_Y_STR);
  182. #endif
  183. #if HAS_Z_AXIS
  184. if (chop_z2) SERIAL_ECHOPGM_P(SP_Z_STR);
  185. #endif
  186. SERIAL_EOL();
  187. }
  188. if (TERN0(Z3_HAS_STEALTHCHOP, stepperZ3.get_stored_stealthChop())) { say_M569(forReplay, F("I2 Z"), true); }
  189. if (TERN0(Z4_HAS_STEALTHCHOP, stepperZ4.get_stored_stealthChop())) { say_M569(forReplay, F("I3 Z"), true); }
  190. #if HAS_I_AXIS
  191. if (TERN0(I_HAS_STEALTHCHOP, stepperI.get_stored_stealthChop())) { say_M569(forReplay, FPSTR(SP_I_STR), true); }
  192. #endif
  193. #if HAS_J_AXIS
  194. if (TERN0(J_HAS_STEALTHCHOP, stepperJ.get_stored_stealthChop())) { say_M569(forReplay, FPSTR(SP_J_STR), true); }
  195. #endif
  196. #if HAS_K_AXIS
  197. if (TERN0(K_HAS_STEALTHCHOP, stepperK.get_stored_stealthChop())) { say_M569(forReplay, FPSTR(SP_K_STR), true); }
  198. #endif
  199. #if HAS_U_AXIS
  200. if (TERN0(U_HAS_STEALTHCHOP, stepperU.get_stored_stealthChop())) { say_M569(forReplay, FPSTR(SP_U_STR), true); }
  201. #endif
  202. #if HAS_V_AXIS
  203. if (TERN0(V_HAS_STEALTHCHOP, stepperV.get_stored_stealthChop())) { say_M569(forReplay, FPSTR(SP_V_STR), true); }
  204. #endif
  205. #if HAS_W_AXIS
  206. if (TERN0(W_HAS_STEALTHCHOP, stepperW.get_stored_stealthChop())) { say_M569(forReplay, FPSTR(SP_W_STR), true); }
  207. #endif
  208. if (TERN0(E0_HAS_STEALTHCHOP, stepperE0.get_stored_stealthChop())) { say_M569(forReplay, F("T0 E"), true); }
  209. if (TERN0(E1_HAS_STEALTHCHOP, stepperE1.get_stored_stealthChop())) { say_M569(forReplay, F("T1 E"), true); }
  210. if (TERN0(E2_HAS_STEALTHCHOP, stepperE2.get_stored_stealthChop())) { say_M569(forReplay, F("T2 E"), true); }
  211. if (TERN0(E3_HAS_STEALTHCHOP, stepperE3.get_stored_stealthChop())) { say_M569(forReplay, F("T3 E"), true); }
  212. if (TERN0(E4_HAS_STEALTHCHOP, stepperE4.get_stored_stealthChop())) { say_M569(forReplay, F("T4 E"), true); }
  213. if (TERN0(E5_HAS_STEALTHCHOP, stepperE5.get_stored_stealthChop())) { say_M569(forReplay, F("T5 E"), true); }
  214. if (TERN0(E6_HAS_STEALTHCHOP, stepperE6.get_stored_stealthChop())) { say_M569(forReplay, F("T6 E"), true); }
  215. if (TERN0(E7_HAS_STEALTHCHOP, stepperE7.get_stored_stealthChop())) { say_M569(forReplay, F("T7 E"), true); }
  216. }
  217. #endif // HAS_STEALTHCHOP