Преглед на файлове

Extend M106/M107 for better laser module support (#16082)

Co-authored-by: Scott Lahteine <thinkyhead@users.noreply.github.com>
Martijn Bosgraaf преди 3 години
родител
ревизия
30e7e2c276
No account linked to committer's email address

+ 12
- 0
Marlin/Configuration_adv.h Целия файл

@@ -3218,6 +3218,18 @@
3218 3218
 #endif
3219 3219
 
3220 3220
 /**
3221
+ * Synchronous Laser Control with M106/M107
3222
+ *
3223
+ * Marlin normally applies M106/M107 fan speeds at a time "soon after" processing
3224
+ * a planner block. This is too inaccurate for a PWM/TTL laser attached to the fan
3225
+ * header (as with some add-on laser kits). Enable this option to set fan/laser
3226
+ * speeds with much more exact timing for improved print fidelity.
3227
+ *
3228
+ * NOTE: This option sacrifices some cooling fan speed options.
3229
+ */
3230
+//#define LASER_SYNCHRONOUS_M106_M107
3231
+
3232
+/**
3221 3233
  * Coolant Control
3222 3234
  *
3223 3235
  * Add the M7, M8, and M9 commands to turn mist or flood coolant on and off.

+ 13
- 5
Marlin/src/gcode/temp/M106_M107.cpp Целия файл

@@ -28,6 +28,10 @@
28 28
 #include "../../module/motion.h"
29 29
 #include "../../module/temperature.h"
30 30
 
31
+#if ENABLED(LASER_SYNCHRONOUS_M106_M107)
32
+  #include "../../module/planner.h"
33
+#endif
34
+
31 35
 #if PREHEAT_COUNT
32 36
   #include "../../lcd/marlinui.h"
33 37
 #endif
@@ -82,6 +86,8 @@ void GcodeSuite::M106() {
82 86
     // Set speed, with constraint
83 87
     thermalManager.set_fan_speed(pfan, speed);
84 88
 
89
+    TERN_(LASER_SYNCHRONOUS_M106_M107, planner.buffer_sync_block(BLOCK_FLAG_SYNC_FANS));
90
+
85 91
     if (TERN0(DUAL_X_CARRIAGE, idex_is_duplicating()))  // pfan == 0 when duplicating
86 92
       thermalManager.set_fan_speed(1 - pfan, speed);
87 93
   }
@@ -92,12 +98,14 @@ void GcodeSuite::M106() {
92 98
  */
93 99
 void GcodeSuite::M107() {
94 100
   const uint8_t pfan = parser.byteval('P', _ALT_P);
95
-  if (pfan < _CNT_P) {
96
-    thermalManager.set_fan_speed(pfan, 0);
101
+  if (pfan >= _CNT_P) return;
97 102
 
98
-    if (TERN0(DUAL_X_CARRIAGE, idex_is_duplicating()))  // pfan == 0 when duplicating
99
-      thermalManager.set_fan_speed(1 - pfan, 0);
100
-  }
103
+  thermalManager.set_fan_speed(pfan, 0);
104
+
105
+  if (TERN0(DUAL_X_CARRIAGE, idex_is_duplicating()))  // pfan == 0 when duplicating
106
+    thermalManager.set_fan_speed(1 - pfan, 0);
107
+
108
+  TERN_(LASER_SYNCHRONOUS_M106_M107, planner.buffer_sync_block(BLOCK_FLAG_SYNC_FANS));
101 109
 }
102 110
 
103 111
 #endif // HAS_FAN

+ 11
- 0
Marlin/src/inc/SanityCheck.h Целия файл

@@ -1218,6 +1218,17 @@ static_assert(Y_MAX_LENGTH >= Y_BED_SIZE, "Movement bounds (Y_MIN_POS, Y_MAX_POS
1218 1218
 #endif
1219 1219
 
1220 1220
 /**
1221
+ * Synchronous M106/M107 checks
1222
+ */
1223
+#if ENABLED(LASER_SYNCHRONOUS_M106_M107)
1224
+  #if FAN_KICKSTART_TIME
1225
+    #error "FAN_KICKSTART_TIME must be 0 with LASER_SYNCHRONOUS_M106_M107 (because the laser will always come on at FULL power)."
1226
+  #elif FAN_MIN_PWM
1227
+    #error "FAN_MIN_PWM must be 0 with LASER_SYNCHRONOUS_M106_M107 (otherwise the laser will never turn OFF)."
1228
+  #endif
1229
+#endif
1230
+
1231
+/**
1221 1232
  * Chamber Heating Options - PID vs Limit Switching
1222 1233
  */
1223 1234
 #if BOTH(PIDTEMPCHAMBER, CHAMBER_LIMIT_SWITCHING)

+ 2
- 2
Marlin/src/lcd/TFTGLCD/marlinui_TFTGLCD.cpp Целия файл

@@ -760,7 +760,7 @@ void MarlinUI::draw_status_screen() {
760 760
     #endif
761 761
   #endif // HAS_HEATED_BED
762 762
 
763
-  #if FAN_COUNT > 0
763
+  #if HAS_FAN
764 764
     uint16_t spd = thermalManager.fan_speed[0];
765 765
 
766 766
     #if ENABLED(ADAPTIVE_FAN_SLOWING)
@@ -783,7 +783,7 @@ void MarlinUI::draw_status_screen() {
783 783
     else
784 784
       picBits &= ~ICON_FAN;
785 785
 
786
-  #endif // FAN_COUNT > 0
786
+  #endif // HAS_FAN
787 787
 
788 788
   //
789 789
   // Line 9, 10 - icons

+ 1
- 1
Marlin/src/lcd/dwin/e3v2/dwin.cpp Целия файл

@@ -2152,7 +2152,7 @@ void HMI_SelectFile() {
2152 2152
 
2153 2153
       card.openAndPrintFile(card.filename);
2154 2154
 
2155
-      #if FAN_COUNT > 0
2155
+      #if HAS_FAN
2156 2156
         // All fans on for Ender 3 v2 ?
2157 2157
         // The slicer should manage this for us.
2158 2158
         //for (uint8_t i = 0; i < FAN_COUNT; i++)

+ 16
- 13
Marlin/src/lcd/marlinui.cpp Целия файл

@@ -22,6 +22,8 @@
22 22
 
23 23
 #include "../inc/MarlinConfig.h"
24 24
 
25
+#include "../MarlinCore.h" // for printingIsPaused
26
+
25 27
 #ifdef LED_BACKLIGHT_TIMEOUT
26 28
   #include "../feature/leds/leds.h"
27 29
 #endif
@@ -39,21 +41,21 @@
39 41
 MarlinUI ui;
40 42
 
41 43
 #if HAS_DISPLAY
42
-  #include "../module/printcounter.h"
43
-  #include "../MarlinCore.h"
44 44
   #include "../gcode/queue.h"
45 45
   #include "fontutils.h"
46 46
   #include "../sd/cardreader.h"
47 47
 #endif
48 48
 
49 49
 #if ENABLED(DWIN_CREALITY_LCD)
50
-  #include "../module/printcounter.h"
51
-  #include "../MarlinCore.h"
52 50
   #include "dwin/e3v2/dwin.h"
53 51
 #endif
54 52
 
55
-#if HAS_STATUS_MESSAGE
56
-  #define START_OF_UTF8_CHAR(C) (((C) & 0xC0u) != 0x80U)
53
+#if ENABLED(LCD_PROGRESS_BAR) && !IS_TFTGLCD_PANEL
54
+  #define BASIC_PROGRESS_BAR 1
55
+#endif
56
+
57
+#if ANY(HAS_DISPLAY, HAS_STATUS_MESSAGE, BASIC_PROGRESS_BAR)
58
+  #include "../module/printcounter.h"
57 59
 #endif
58 60
 
59 61
 #if LCD_HAS_WAIT_FOR_MOVE
@@ -535,7 +537,7 @@ bool MarlinUI::get_blink() {
535 537
  * This is very display-dependent, so the lcd implementation draws this.
536 538
  */
537 539
 
538
-#if ENABLED(LCD_PROGRESS_BAR) && !IS_TFTGLCD_PANEL
540
+#if BASIC_PROGRESS_BAR
539 541
   millis_t MarlinUI::progress_bar_ms; // = 0
540 542
   #if PROGRESS_MSG_EXPIRE > 0
541 543
     millis_t MarlinUI::expire_status_ms; // = 0
@@ -546,7 +548,7 @@ void MarlinUI::status_screen() {
546 548
 
547 549
   TERN_(HAS_LCD_MENU, ENCODER_RATE_MULTIPLY(false));
548 550
 
549
-  #if ENABLED(LCD_PROGRESS_BAR) && !IS_TFTGLCD_PANEL
551
+  #if BASIC_PROGRESS_BAR
550 552
 
551 553
     //
552 554
     // HD44780 implements the following message blinking and
@@ -586,7 +588,7 @@ void MarlinUI::status_screen() {
586 588
 
587 589
     #endif // PROGRESS_MSG_EXPIRE
588 590
 
589
-  #endif // LCD_PROGRESS_BAR
591
+  #endif // BASIC_PROGRESS_BAR
590 592
 
591 593
   #if HAS_LCD_MENU
592 594
     if (use_click()) {
@@ -1353,6 +1355,7 @@ void MarlinUI::update() {
1353 1355
   /**
1354 1356
    * Reset the status message
1355 1357
    */
1358
+
1356 1359
   void MarlinUI::reset_status(const bool no_welcome) {
1357 1360
     #if SERVICE_INTERVAL_1 > 0
1358 1361
       static PGMSTR(service1, "> " SERVICE_NAME_1 "!");
@@ -1438,9 +1441,9 @@ void MarlinUI::update() {
1438 1441
 
1439 1442
   void MarlinUI::finish_status(const bool persist) {
1440 1443
 
1441
-    #if HAS_SPI_LCD
1444
+    #if HAS_WIRED_LCD
1442 1445
 
1443
-      #if !(ENABLED(LCD_PROGRESS_BAR) && (PROGRESS_MSG_EXPIRE) > 0)
1446
+      #if !(BASIC_PROGRESS_BAR && (PROGRESS_MSG_EXPIRE) > 0)
1444 1447
         UNUSED(persist);
1445 1448
       #endif
1446 1449
 
@@ -1448,7 +1451,7 @@ void MarlinUI::update() {
1448 1451
         const millis_t ms = millis();
1449 1452
       #endif
1450 1453
 
1451
-      #if ENABLED(LCD_PROGRESS_BAR)
1454
+      #if BASIC_PROGRESS_BAR
1452 1455
         progress_bar_ms = ms;
1453 1456
         #if PROGRESS_MSG_EXPIRE > 0
1454 1457
           expire_status_ms = persist ? 0 : ms + PROGRESS_MSG_EXPIRE;
@@ -1462,7 +1465,7 @@ void MarlinUI::update() {
1462 1465
       #if ENABLED(STATUS_MESSAGE_SCROLLING)
1463 1466
         status_scroll_offset = 0;
1464 1467
       #endif
1465
-    #else // HAS_SPI_LCD
1468
+    #else // HAS_WIRED_LCD
1466 1469
       UNUSED(persist);
1467 1470
     #endif
1468 1471
 

+ 2
- 0
Marlin/src/lcd/marlinui.h Целия файл

@@ -56,6 +56,8 @@
56 56
   #include "../module/motion.h" // for active_extruder
57 57
 #endif
58 58
 
59
+#define START_OF_UTF8_CHAR(C) (((C) & 0xC0u) != 0x80U)
60
+
59 61
 #if HAS_WIRED_LCD
60 62
 
61 63
   enum LCDViewAction : uint8_t {

+ 85
- 58
Marlin/src/module/planner.cpp Целия файл

@@ -1015,8 +1015,8 @@ void Planner::reverse_pass() {
1015 1015
     // Perform the reverse pass
1016 1016
     block_t *current = &block_buffer[block_index];
1017 1017
 
1018
-    // Only consider non sync and page blocks
1019
-    if (!TEST(current->flag, BLOCK_BIT_SYNC_POSITION) && !IS_PAGE(current)) {
1018
+    // Only consider non sync-and-page blocks
1019
+    if (!(current->flag & BLOCK_MASK_SYNC) && !IS_PAGE(current)) {
1020 1020
       reverse_pass_kernel(current, next);
1021 1021
       next = current;
1022 1022
     }
@@ -1111,7 +1111,7 @@ void Planner::forward_pass() {
1111 1111
     block = &block_buffer[block_index];
1112 1112
 
1113 1113
     // Skip SYNC and page blocks
1114
-    if (!TEST(block->flag, BLOCK_BIT_SYNC_POSITION) && !IS_PAGE(block)) {
1114
+    if (!(block->flag & BLOCK_MASK_SYNC) && !IS_PAGE(block)) {
1115 1115
       // If there's no previous block or the previous block is not
1116 1116
       // BUSY (thus, modifiable) run the forward_pass_kernel. Otherwise,
1117 1117
       // the previous block became BUSY, so assume the current block's
@@ -1147,7 +1147,7 @@ void Planner::recalculate_trapezoids() {
1147 1147
     block_t *prev = &block_buffer[prev_index];
1148 1148
 
1149 1149
     // If not dealing with a sync block, we are done. The last block is not a SYNC block
1150
-    if (!TEST(prev->flag, BLOCK_BIT_SYNC_POSITION)) break;
1150
+    if (!(prev->flag & BLOCK_MASK_SYNC)) break;
1151 1151
 
1152 1152
     // Examine the previous block. This and all following are SYNC blocks
1153 1153
     head_block_index = prev_index;
@@ -1161,7 +1161,7 @@ void Planner::recalculate_trapezoids() {
1161 1161
     next = &block_buffer[block_index];
1162 1162
 
1163 1163
     // Skip sync and page blocks
1164
-    if (!TEST(next->flag, BLOCK_BIT_SYNC_POSITION) && !IS_PAGE(next)) {
1164
+    if (!(next->flag & BLOCK_MASK_SYNC) && !IS_PAGE(next)) {
1165 1165
       next_entry_speed = SQRT(next->entry_speed_sqr);
1166 1166
 
1167 1167
       if (block) {
@@ -1248,6 +1248,63 @@ void Planner::recalculate() {
1248 1248
   recalculate_trapezoids();
1249 1249
 }
1250 1250
 
1251
+#if HAS_FAN && DISABLED(LASER_SYNCHRONOUS_M106_M107)
1252
+  #define HAS_TAIL_FAN_SPEED 1
1253
+#endif
1254
+
1255
+/**
1256
+ * Apply fan speeds
1257
+ */
1258
+#if HAS_FAN
1259
+
1260
+  void Planner::sync_fan_speeds(uint8_t (&fan_speed)[FAN_COUNT]) {
1261
+
1262
+    #if FAN_MIN_PWM != 0 || FAN_MAX_PWM != 255
1263
+      #define CALC_FAN_SPEED(f) (fan_speed[f] ? map(fan_speed[f], 1, 255, FAN_MIN_PWM, FAN_MAX_PWM) : FAN_OFF_PWM)
1264
+    #else
1265
+      #define CALC_FAN_SPEED(f) (fan_speed[f] ?: FAN_OFF_PWM)
1266
+    #endif
1267
+
1268
+    #if ENABLED(FAN_SOFT_PWM)
1269
+      #define _FAN_SET(F) thermalManager.soft_pwm_amount_fan[F] = CALC_FAN_SPEED(F);
1270
+    #elif ENABLED(FAST_PWM_FAN)
1271
+      #define _FAN_SET(F) set_pwm_duty(FAN##F##_PIN, CALC_FAN_SPEED(F));
1272
+    #else
1273
+      #define _FAN_SET(F) analogWrite(pin_t(FAN##F##_PIN), CALC_FAN_SPEED(F));
1274
+    #endif
1275
+    #define FAN_SET(F) do{ kickstart_fan(fan_speed, ms, F); _FAN_SET(F); }while(0)
1276
+
1277
+    const millis_t ms = millis();
1278
+    TERN_(HAS_FAN0, FAN_SET(0));
1279
+    TERN_(HAS_FAN1, FAN_SET(1));
1280
+    TERN_(HAS_FAN2, FAN_SET(2));
1281
+    TERN_(HAS_FAN3, FAN_SET(3));
1282
+    TERN_(HAS_FAN4, FAN_SET(4));
1283
+    TERN_(HAS_FAN5, FAN_SET(5));
1284
+    TERN_(HAS_FAN6, FAN_SET(6));
1285
+    TERN_(HAS_FAN7, FAN_SET(7));
1286
+  }
1287
+
1288
+  #if FAN_KICKSTART_TIME
1289
+
1290
+    void Planner::kickstart_fan(uint8_t (&fan_speed)[FAN_COUNT], const millis_t &ms, const uint8_t f) {
1291
+      static millis_t fan_kick_end[FAN_COUNT] = { 0 };
1292
+      if (fan_speed[f]) {
1293
+        if (fan_kick_end[f] == 0) {
1294
+          fan_kick_end[f] = ms + FAN_KICKSTART_TIME;
1295
+          fan_speed[f] = 255;
1296
+        }
1297
+        else if (PENDING(ms, fan_kick_end[f]))
1298
+          fan_speed[f] = 255;
1299
+      }
1300
+      else
1301
+        fan_kick_end[f] = 0;
1302
+    }
1303
+
1304
+  #endif
1305
+
1306
+#endif // HAS_FAN
1307
+
1251 1308
 /**
1252 1309
  * Maintain fans, paste extruder pressure,
1253 1310
  */
@@ -1257,7 +1314,7 @@ void Planner::check_axes_activity() {
1257 1314
     xyze_bool_t axis_active = { false };
1258 1315
   #endif
1259 1316
 
1260
-  #if HAS_FAN
1317
+  #if HAS_TAIL_FAN_SPEED
1261 1318
     uint8_t tail_fan_speed[FAN_COUNT];
1262 1319
   #endif
1263 1320
 
@@ -1272,13 +1329,12 @@ void Planner::check_axes_activity() {
1272 1329
 
1273 1330
   if (has_blocks_queued()) {
1274 1331
 
1275
-    #if HAS_FAN || ENABLED(BARICUDA)
1332
+    #if EITHER(HAS_TAIL_FAN_SPEED, BARICUDA)
1276 1333
       block_t *block = &block_buffer[block_buffer_tail];
1277 1334
     #endif
1278 1335
 
1279
-    #if HAS_FAN
1280
-      FANS_LOOP(i)
1281
-        tail_fan_speed[i] = thermalManager.scaledFanSpeed(i, block->fan_speed[i]);
1336
+    #if HAS_TAIL_FAN_SPEED
1337
+      FANS_LOOP(i) tail_fan_speed[i] = thermalManager.scaledFanSpeed(i, block->fan_speed[i]);
1282 1338
     #endif
1283 1339
 
1284 1340
     #if ENABLED(BARICUDA)
@@ -1300,9 +1356,8 @@ void Planner::check_axes_activity() {
1300 1356
 
1301 1357
     TERN_(HAS_CUTTER, cutter.refresh());
1302 1358
 
1303
-    #if HAS_FAN
1304
-      FANS_LOOP(i)
1305
-        tail_fan_speed[i] = thermalManager.scaledFanSpeed(i);
1359
+    #if HAS_TAIL_FAN_SPEED
1360
+      FANS_LOOP(i) tail_fan_speed[i] = thermalManager.scaledFanSpeed(i);
1306 1361
     #endif
1307 1362
 
1308 1363
     #if ENABLED(BARICUDA)
@@ -1321,48 +1376,11 @@ void Planner::check_axes_activity() {
1321 1376
 
1322 1377
   //
1323 1378
   // Update Fan speeds
1379
+  // Only if synchronous M106/M107 is disabled
1324 1380
   //
1325
-  #if HAS_FAN
1326
-
1327
-    #if FAN_KICKSTART_TIME > 0
1328
-      static millis_t fan_kick_end[FAN_COUNT] = { 0 };
1329
-      #define KICKSTART_FAN(f)                         \
1330
-        if (tail_fan_speed[f]) {                       \
1331
-          millis_t ms = millis();                      \
1332
-          if (fan_kick_end[f] == 0) {                  \
1333
-            fan_kick_end[f] = ms + FAN_KICKSTART_TIME; \
1334
-            tail_fan_speed[f] = 255;                   \
1335
-          } else if (PENDING(ms, fan_kick_end[f]))     \
1336
-            tail_fan_speed[f] = 255;                   \
1337
-        } else fan_kick_end[f] = 0
1338
-    #else
1339
-      #define KICKSTART_FAN(f) NOOP
1340
-    #endif
1341
-
1342
-    #if FAN_MIN_PWM != 0 || FAN_MAX_PWM != 255
1343
-      #define CALC_FAN_SPEED(f) (tail_fan_speed[f] ? map(tail_fan_speed[f], 1, 255, FAN_MIN_PWM, FAN_MAX_PWM) : FAN_OFF_PWM)
1344
-    #else
1345
-      #define CALC_FAN_SPEED(f) (tail_fan_speed[f] ?: FAN_OFF_PWM)
1346
-    #endif
1347
-
1348
-    #if ENABLED(FAN_SOFT_PWM)
1349
-      #define _FAN_SET(F) thermalManager.soft_pwm_amount_fan[F] = CALC_FAN_SPEED(F);
1350
-    #elif ENABLED(FAST_PWM_FAN)
1351
-      #define _FAN_SET(F) set_pwm_duty(FAN##F##_PIN, CALC_FAN_SPEED(F));
1352
-    #else
1353
-      #define _FAN_SET(F) analogWrite(pin_t(FAN##F##_PIN), CALC_FAN_SPEED(F));
1354
-    #endif
1355
-    #define FAN_SET(F) do{ KICKSTART_FAN(F); _FAN_SET(F); }while(0)
1356
-
1357
-    TERN_(HAS_FAN0, FAN_SET(0));
1358
-    TERN_(HAS_FAN1, FAN_SET(1));
1359
-    TERN_(HAS_FAN2, FAN_SET(2));
1360
-    TERN_(HAS_FAN3, FAN_SET(3));
1361
-    TERN_(HAS_FAN4, FAN_SET(4));
1362
-    TERN_(HAS_FAN5, FAN_SET(5));
1363
-    TERN_(HAS_FAN6, FAN_SET(6));
1364
-    TERN_(HAS_FAN7, FAN_SET(7));
1365
-  #endif // HAS_FAN
1381
+  #if HAS_TAIL_FAN_SPEED
1382
+    sync_fan_speeds(tail_fan_speed);
1383
+  #endif
1366 1384
 
1367 1385
   TERN_(AUTOTEMP, getHighESpeed());
1368 1386
 
@@ -2675,9 +2693,14 @@ bool Planner::_populate_block(block_t * const block, bool split_move,
2675 2693
 
2676 2694
 /**
2677 2695
  * Planner::buffer_sync_block
2678
- * Add a block to the buffer that just updates the position
2696
+ * Add a block to the buffer that just updates the position,
2697
+ * or in case of LASER_SYNCHRONOUS_M106_M107 the fan PWM
2679 2698
  */
2680
-void Planner::buffer_sync_block() {
2699
+void Planner::buffer_sync_block(TERN_(LASER_SYNCHRONOUS_M106_M107, uint8_t sync_flag)) {
2700
+  #if DISABLED(LASER_SYNCHRONOUS_M106_M107)
2701
+    constexpr uint8_t sync_flag = BLOCK_FLAG_SYNC_POSITION;
2702
+  #endif
2703
+
2681 2704
   // Wait for the next available block
2682 2705
   uint8_t next_buffer_head;
2683 2706
   block_t * const block = get_next_free_block(next_buffer_head);
@@ -2685,10 +2708,14 @@ void Planner::buffer_sync_block() {
2685 2708
   // Clear block
2686 2709
   memset(block, 0, sizeof(block_t));
2687 2710
 
2688
-  block->flag = BLOCK_FLAG_SYNC_POSITION;
2711
+  block->flag = sync_flag;
2689 2712
 
2690 2713
   block->position = position;
2691 2714
 
2715
+  #if BOTH(HAS_FAN, LASER_SYNCHRONOUS_M106_M107)
2716
+    FANS_LOOP(i) block->fan_speed[i] = thermalManager.fan_speed[i];
2717
+  #endif
2718
+
2692 2719
   // If this is the first added movement, reload the delay, otherwise, cancel it.
2693 2720
   if (block_buffer_head == block_buffer_tail) {
2694 2721
     // If it was the first queued block, restart the 1st block delivery delay, to
@@ -2876,7 +2903,7 @@ bool Planner::buffer_line(const float &rx, const float &ry, const float &rz, con
2876 2903
 
2877 2904
     block->flag = BLOCK_FLAG_IS_PAGE;
2878 2905
 
2879
-    #if FAN_COUNT > 0
2906
+    #if HAS_FAN
2880 2907
       FANS_LOOP(i) block->fan_speed[i] = thermalManager.fan_speed[i];
2881 2908
     #endif
2882 2909
 

+ 25
- 2
Marlin/src/module/planner.h Целия файл

@@ -102,6 +102,11 @@ enum BlockFlagBit : char {
102 102
   #if ENABLED(DIRECT_STEPPING)
103 103
     , BLOCK_BIT_IS_PAGE
104 104
   #endif
105
+
106
+  // Sync the fan speeds from the block
107
+  #if ENABLED(LASER_SYNCHRONOUS_M106_M107)
108
+    , BLOCK_BIT_SYNC_FANS
109
+  #endif
105 110
 };
106 111
 
107 112
 enum BlockFlag : char {
@@ -112,8 +117,13 @@ enum BlockFlag : char {
112 117
   #if ENABLED(DIRECT_STEPPING)
113 118
     , BLOCK_FLAG_IS_PAGE            = _BV(BLOCK_BIT_IS_PAGE)
114 119
   #endif
120
+  #if ENABLED(LASER_SYNCHRONOUS_M106_M107)
121
+    , BLOCK_FLAG_SYNC_FANS          = _BV(BLOCK_BIT_SYNC_FANS)
122
+  #endif
115 123
 };
116 124
 
125
+#define BLOCK_MASK_SYNC ( BLOCK_FLAG_SYNC_POSITION | TERN0(LASER_SYNCHRONOUS_M106_M107, BLOCK_FLAG_SYNC_FANS) )
126
+
117 127
 #if ENABLED(LASER_POWER_INLINE)
118 128
 
119 129
   typedef struct {
@@ -499,6 +509,16 @@ class Planner {
499 509
     // Manage fans, paste pressure, etc.
500 510
     static void check_axes_activity();
501 511
 
512
+    // Apply fan speeds
513
+    #if HAS_FAN
514
+      static void sync_fan_speeds(uint8_t (&fan_speed)[FAN_COUNT]);
515
+      #if FAN_KICKSTART_TIME
516
+        static void kickstart_fan(uint8_t (&fan_speed)[FAN_COUNT], const millis_t &ms, const uint8_t f);
517
+      #else
518
+        FORCE_INLINE static void kickstart_fan(uint8_t (&)[FAN_COUNT], const millis_t &, const uint8_t) {}
519
+      #endif
520
+    #endif
521
+
502 522
     #if ENABLED(FILAMENT_WIDTH_SENSOR)
503 523
       void apply_filament_width_sensor(const int8_t encoded_ratio);
504 524
 
@@ -721,9 +741,12 @@ class Planner {
721 741
 
722 742
     /**
723 743
      * Planner::buffer_sync_block
724
-     * Add a block to the buffer that just updates the position
744
+     * Add a block to the buffer that just updates the position or in
745
+     * case of LASER_SYNCHRONOUS_M106_M107 the fan pwm
725 746
      */
726
-    static void buffer_sync_block();
747
+    static void buffer_sync_block(
748
+      TERN_(LASER_SYNCHRONOUS_M106_M107, uint8_t sync_flag=BLOCK_FLAG_SYNC_POSITION)
749
+    );
727 750
 
728 751
   #if IS_KINEMATIC
729 752
     private:

+ 12
- 3
Marlin/src/module/stepper.cpp Целия файл

@@ -1988,9 +1988,18 @@ uint32_t Stepper::block_phase_isr() {
1988 1988
     // Anything in the buffer?
1989 1989
     if ((current_block = planner.get_current_block())) {
1990 1990
 
1991
-      // Sync block? Sync the stepper counts and return
1992
-      while (TEST(current_block->flag, BLOCK_BIT_SYNC_POSITION)) {
1993
-        _set_position(current_block->position);
1991
+      // Sync block? Sync the stepper counts or fan speeds and return
1992
+      while (current_block->flag & BLOCK_MASK_SYNC) {
1993
+
1994
+        #if ENABLED(LASER_SYNCHRONOUS_M106_M107)
1995
+          const bool is_sync_fans = TEST(current_block->flag, BLOCK_BIT_SYNC_FANS);
1996
+          if (is_sync_fans) planner.sync_fan_speeds(current_block->fan_speed);
1997
+        #else
1998
+          constexpr bool is_sync_fans = false;
1999
+        #endif
2000
+
2001
+        if (!is_sync_fans) _set_position(current_block->position);
2002
+
1994 2003
         discard_current_block();
1995 2004
 
1996 2005
         // Try to get a new block

+ 1
- 1
Marlin/src/module/temperature.cpp Целия файл

@@ -197,7 +197,7 @@
197 197
 #endif
198 198
 
199 199
 #if HAS_SERVOS
200
-  #include "./servo.h"
200
+  #include "servo.h"
201 201
 #endif
202 202
 
203 203
 #if ANY(TEMP_SENSOR_0_IS_THERMISTOR, TEMP_SENSOR_1_IS_THERMISTOR, TEMP_SENSOR_2_IS_THERMISTOR, TEMP_SENSOR_3_IS_THERMISTOR, \

+ 4
- 2
Marlin/src/pins/stm32f4/pins_MKS_ROBIN_NANO_V3.h Целия файл

@@ -322,7 +322,8 @@
322 322
 
323 323
   #define TFT_BUFFER_SIZE                  14400
324 324
 
325
-#elif HAS_SPI_LCD
325
+#elif HAS_WIRED_LCD
326
+
326 327
   #define BEEPER_PIN                        PC5
327 328
   #define BTN_ENC                           PE13
328 329
   #define LCD_PINS_ENABLE                   PD13
@@ -358,4 +359,5 @@
358 359
     #define BOARD_ST7920_DELAY_3    DELAY_NS(600)
359 360
 
360 361
   #endif // !MKS_MINI_12864
361
-#endif // HAS_SPI_LCD
362
+
363
+#endif // HAS_WIRED_LCD

+ 4
- 2
Marlin/src/pins/stm32f4/pins_MKS_ROBIN_PRO_V2.h Целия файл

@@ -327,7 +327,8 @@
327 327
   //#define TFT_DRIVER                    ST7796
328 328
   #define TFT_BUFFER_SIZE                  14400
329 329
 
330
-#elif HAS_SPI_LCD
330
+#elif HAS_WIRED_LCD
331
+
331 332
   #define BEEPER_PIN                        PC5
332 333
   #define BTN_ENC                           PE13
333 334
   #define LCD_PINS_ENABLE                   PD13
@@ -369,4 +370,5 @@
369 370
     #endif
370 371
 
371 372
   #endif // !MKS_MINI_12864
372
-#endif // HAS_SPI_LCD
373
+
374
+#endif // HAS_WIRED_LCD

+ 1
- 0
buildroot/tests/ARMED Целия файл

@@ -12,6 +12,7 @@ set -e
12 12
 restore_configs
13 13
 use_example_configs ArmEd
14 14
 opt_set X_DRIVER_TYPE TMC2130 Y_DRIVER_TYPE TMC2208
15
+opt_enable LASER_SYNCHRONOUS_M106_M107
15 16
 exec_test $1 $2 "ArmEd Example Configuration with mixed TMC Drivers" "$3"
16 17
 
17 18
 # clean up

Loading…
Отказ
Запис