Tcodes.cpp 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. #include "Tcodes.h"
  2. #include "SpoolJoin.h"
  3. #include "Marlin.h"
  4. #include "language.h"
  5. #include "messages.h"
  6. #include "mmu2.h"
  7. #include "stepper.h"
  8. #include "ultralcd.h"
  9. #include <avr/pgmspace.h>
  10. #include <ctype.h>
  11. #include <stdint.h>
  12. #include <stdio.h>
  13. static const char duplicate_Tcode_ignored[] PROGMEM = "Duplicate T-code ignored.";
  14. inline bool IsInvalidTCode(char *const s, uint8_t i) {
  15. return ((s[i] < '0' || s[i] > '4') && s[i] != '?' && s[i] != 'x' && s[i] != 'c');
  16. }
  17. inline void TCodeInvalid() {
  18. SERIAL_ECHOLNPGM("Invalid T code.");
  19. }
  20. struct SChooseFromMenu {
  21. uint8_t slot:7;
  22. uint8_t loadToNozzle:1;
  23. inline constexpr SChooseFromMenu(uint8_t slot, bool loadToNozzle):slot(slot), loadToNozzle(loadToNozzle){}
  24. inline constexpr SChooseFromMenu():slot(0), loadToNozzle(false) { }
  25. };
  26. SChooseFromMenu TCodeChooseFromMenu() {
  27. if (MMU2::mmu2.Enabled()) {
  28. return SChooseFromMenu( choose_menu_P(_T(MSG_SELECT_FILAMENT), _T(MSG_FILAMENT)), true );
  29. } else {
  30. return SChooseFromMenu( choose_menu_P(_T(MSG_SELECT_EXTRUDER), _T(MSG_EXTRUDER)), false );
  31. }
  32. }
  33. void TCodes(char *const strchr_pointer, uint8_t codeValue) {
  34. uint8_t index = 1;
  35. for ( /*nothing*/ ; strchr_pointer[index] == ' ' || strchr_pointer[index] == '\t'; index++)
  36. ;
  37. strchr_pointer[index] = tolower(strchr_pointer[index]);
  38. if (IsInvalidTCode(strchr_pointer, index)){
  39. TCodeInvalid();
  40. } else if (strchr_pointer[index] == 'x'){
  41. // load to extruder gears; if mmu is not present do nothing
  42. if (MMU2::mmu2.Enabled()) {
  43. MMU2::mmu2.tool_change(strchr_pointer[index], choose_menu_P(_T(MSG_SELECT_EXTRUDER), _T(MSG_EXTRUDER)));
  44. }
  45. } else if (strchr_pointer[index] == 'c'){
  46. // load from extruder gears to nozzle (nozzle should be preheated)
  47. if (MMU2::mmu2.Enabled()) {
  48. MMU2::mmu2.tool_change(strchr_pointer[index], MMU2::mmu2.get_current_tool());
  49. }
  50. } else {
  51. SChooseFromMenu selectedSlot;
  52. if (strchr_pointer[index] == '?') {
  53. selectedSlot = TCodeChooseFromMenu();
  54. /*} else if (MMU2::mmu2.Enabled() && SpoolJoin::spooljoin.isSpoolJoinEnabled()) {
  55. // TODO: What if the next slot has no filament?
  56. selectedSlot.slot = SpoolJoin::spooljoin.nextSlot();*/
  57. } else {
  58. selectedSlot.slot = codeValue;
  59. }
  60. st_synchronize();
  61. if (MMU2::mmu2.Enabled()) {
  62. if (selectedSlot.slot == MMU2::mmu2.get_current_tool()){
  63. // don't execute the same T-code twice in a row
  64. puts_P(duplicate_Tcode_ignored);
  65. } else {
  66. #if defined(MMU_HAS_CUTTER) && defined(MMU_ALWAYS_CUT)
  67. if (EEPROM_MMU_CUTTER_ENABLED_always == eeprom_read_byte((uint8_t *)EEPROM_MMU_CUTTER_ENABLED)) {
  68. MMU2::mmu2.cut_filament(selectedSlot.slot);
  69. }
  70. #endif // defined(MMU_HAS_CUTTER) && defined(MMU_ALWAYS_CUT)
  71. if (selectedSlot.loadToNozzle){ // for single material usage with mmu
  72. MMU2::mmu2.load_filament_to_nozzle(selectedSlot.slot);
  73. } else {
  74. MMU2::mmu2.tool_change(selectedSlot.slot);
  75. }
  76. }
  77. } else {
  78. if (selectedSlot.slot >= EXTRUDERS) {
  79. SERIAL_ECHO_START;
  80. SERIAL_ECHO('T');
  81. SERIAL_ECHOLN(selectedSlot.slot + '0');
  82. SERIAL_ECHOLNRPGM(_n("Invalid extruder")); ////MSG_INVALID_EXTRUDER
  83. } else {
  84. // @@TODO if (code_seen('F')) {
  85. // next_feedrate = code_value();
  86. // if (next_feedrate > 0.0) {
  87. // feedrate = next_feedrate;
  88. // }
  89. // }
  90. SERIAL_ECHO_START;
  91. SERIAL_ECHORPGM(_n("Active Extruder: ")); ////MSG_ACTIVE_EXTRUDER
  92. SERIAL_ECHOLN(active_extruder + '0'); // this is not changed in our FW at all, can be optimized away
  93. }
  94. }
  95. }
  96. }