Compare commits

..

60 Commits

Author SHA1 Message Date
InsanityAutomation dd2af4aea5 Dual Markforged XY First Pass 2025-04-18 09:50:53 -04:00
InsanityAutomation f4c4e38f1f Fill actual positions 2025-04-18 09:50:26 -04:00
InsanityAutomation e020d10b97 Update lpc176x.ini 2025-04-02 09:48:30 -04:00
InsanityAutomation 32ec7e464d Update Configuration_adv.h 2025-04-02 09:47:29 -04:00
InsanityAutomation 0eb80c77ee Update lpc176x.ini 2025-04-02 09:03:15 -04:00
InsanityAutomation 66f9b16f0c 22IDEX Initial Commit 2025-04-01 16:26:51 -04:00
InsanityAutomation c3d3d0393a Rollback 1 2024-05-25 18:24:50 -04:00
InsanityAutomation 9eab42bbdf Revert "Merge branch 'pr/27031' into EBAB_EBAP"
This reverts commit 90f10e8943, reversing
changes made to a303ede8b9.
2024-05-25 18:23:21 -04:00
InsanityAutomation 6ae3622555 Merge branch 'bugfix-2.1.x' into EBAB_EBAP 2024-05-25 17:28:10 -04:00
InsanityAutomation 9648e399ef Merge branch 'bugfix-2.1.x' into EBAB_EBAP 2024-05-21 20:47:38 -04:00
InsanityAutomation 9cef6aced6 Update Configuration.h 2024-05-21 20:43:13 -04:00
Mihail Dumitrescu fcd4b7b2dc Add 4th order S_CURVE_ACCELERATION with configurable S_CURVE_FACTOR. 2024-05-19 19:58:29 -04:00
InsanityAutomation 6d153f8ca8 Merge branch 'bugfix-2.1.x' into EBAB_EBAP 2024-05-19 19:56:58 -04:00
InsanityAutomation 344a664dc9 tmc5160 and spi 2024-05-16 09:49:20 -04:00
InsanityAutomation ea3b0b6614 Drop out incomplete idex conversion changes until HW is ready 2024-05-16 09:35:58 -04:00
InsanityAutomation a7a8922c93 Update Configuration_adv.h 2024-05-16 09:30:28 -04:00
InsanityAutomation e4dd0f4f53 Add new hal file 2024-05-16 09:30:13 -04:00
InsanityAutomation 292512651a Fix interupts and pin debugging 2024-05-16 09:23:42 -04:00
InsanityAutomation 5492130292 tmc5160 and spi 2024-05-16 09:22:46 -04:00
InsanityAutomation ed59dc76c4 LPC4078 Initial Commit
Co-Authored-By: Chris Pepper <24342+p3p@users.noreply.github.com>
2024-05-16 09:22:08 -04:00
InsanityAutomation d494a0f54e Restore hal 2024-05-16 09:19:38 -04:00
InsanityAutomation 001070aa99 reapply somehow dropped LPC4078 env 2024-05-16 09:16:39 -04:00
John Robertson 4b2f682d59 Update planner.h
fix minimal_step_rate calc
2024-05-16 09:05:53 -04:00
John Robertson 471924e7fd Update planner.h
Added calc for MINIMAL_STEP_RATE
2024-05-16 09:05:53 -04:00
John Robertson d88953d03e Update planner.h
Moved MINIMAL_STEP_RATE to this file.
2024-05-16 09:05:52 -04:00
John Robertson 1a765b4d91 Update planner.cpp
removed 
#define MINIMAL_STEP_RATE 120
2024-05-16 09:05:52 -04:00
John Robertson efb4ffcc97 Fix planner wrong trap generation
If the planner `entry_rate` or `final_rate` are larger thanthe  `block->nominal_rate` then the trapezoid entry ramp continuously accelerates. Only happens if feed rate is less than MAXIMAL_STEP_RATE.
2024-05-16 09:05:52 -04:00
InsanityAutomation 3481add963 Merge branch 'pr/27035' into EBAB_EBAP 2024-05-16 08:59:01 -04:00
InsanityAutomation 3c7b77b973 Merge branch 'pr/27013' into EBAB_EBAP 2024-05-16 08:56:09 -04:00
InsanityAutomation 90f10e8943 Merge branch 'pr/27031' into EBAB_EBAP 2024-05-16 08:53:18 -04:00
InsanityAutomation a303ede8b9 Merge branch 'bugfix-2.1.x' into EBAB_EBAP 2024-05-16 08:51:35 -04:00
Scott Lahteine fb05d3d1e6 match modified names 2024-05-15 15:30:22 -05:00
Scott Lahteine e5c78767e9 Merge branch 'bugfix-2.1.x' into pr/27035 2024-05-15 15:22:45 -05:00
Scott Lahteine 7cd1fe3b6f Merge branch 'bugfix-2.1.x' into pr/27035 2024-05-15 15:14:05 -05:00
Scott Lahteine 81686a3901 Merge branch 'bugfix-2.1.x' into pr/27013 2024-05-11 12:36:20 -05:00
Mihail Dumitrescu 51d115670e Multiply laser ramp by steps_per_isr to fix multistepping case. 2024-05-10 19:02:16 +03:00
InsanityAutomation f49e93e5c4 Merge branch 'bugfix-2.1.x' into EBAB_EBAP 2024-05-10 10:03:28 -04:00
Scott Lahteine f2be86f735 combined float sq 2024-05-09 17:25:15 -05:00
Scott Lahteine c0d217de47 as described 2024-05-09 16:48:09 -05:00
Scott Lahteine 6ce4f039a2 group for clarity and review 2024-05-06 17:24:07 -05:00
Mihail Dumitrescu 50a38bb365 Optimal number of sqrts and trapezoid calculations.
Remove forward_pass(). Call forward_pass_kernel() from recalculate() instead.
Fix potential for large speed changes if planner falls behind.
2024-04-29 19:50:15 +03:00
Mihail Dumitrescu 5717a39422 Remove nominal_length, remove MINIMAL_STEP_RATE, add min_entry_speed_sqr, initial clean up of reverse_pass_kernel and forward_pass_kernel.
Removing MINIMAL_STEP_RATE allows for correct handling of moves with low acceleration, including fixing judder that's caused when the planner computes an entry speed based on minimum_planner_speed_sqr that's then promptly overriden by MINIMAL_STEP_RATE.

Added min_entry_speed_sqr to avoid a specific potential source of judder due to working with discrete steps rather continuous real-valued physics. The first step of any segment runs at initial_rate. If it is too low compared to acceleration_steps_per_s2 it will result in too much accumulated acceleration_time (see stepper.cpp) which will mean the following step will be at a much higher speed, and the speed change will significantly surpass the set acceleration_steps_per_s2 limit. Making sure we can match this limit is why we have minimum_planner_speed_sqr in the first place.
2024-04-29 19:50:15 +03:00
Mihail Dumitrescu f806f60fc1 Move cruise LASER_POWER_TRAP code to cruise block.
More succint comments.
2024-04-29 14:25:20 +03:00
Scott Lahteine 2fb1a2b7a3 correction 2024-04-26 19:24:03 -05:00
Scott Lahteine 89d7e17146 worms! 2024-04-24 19:11:32 -05:00
Scott Lahteine 30ece3d9e7 worms 2024-04-24 19:08:58 -05:00
Scott Lahteine b9c8e24f67 NOLESS+NOMORE=LIMIT 2024-04-24 19:06:51 -05:00
Scott Lahteine 1f3f416bd2 semantics changed 2024-04-24 18:51:23 -05:00
Mihail Dumitrescu 549a4f48f9 Smoother motion by fixing calculating trapezoids and ISR stepping.
Fix rounding directions in calculate_trapezoid_for_block().
Fix off-by-ones errors in ac/deceleration steps in block_phase_isr.
Half-initialize ac/deceleration_time to smooth the speed change shock that happens between segments, which is critical as jerk/deviation adds to this.

The result is a smoother motion profile that follows the imposed acceleration limits with a well defined 0.5-1.5x error factor (or 2x if axis is starting from ~0). Errors are due to converting a real-valued motion profile into discrete numbers of steps.
Fixes are general and improve S_CURVE_ACCELERATION too (no endorsement implied).

Tested by looking at the generated step/dir impulses with a logic analyzer.

Enjoy the smoother motion or use more aggresive acceleration/jerk/deviation values for faster prints.

Also improves: #12491
2024-04-24 19:18:17 +03:00
InsanityAutomation 7b44fb8cca Config start 2023-11-13 10:37:54 -05:00
InsanityAutomation 83bdfeb5cb Merge branch 'bugfix-2.1.x' of https://github.com/MarlinFirmware/Marlin into bugfix-2.1.x 2023-11-08 09:39:42 -05:00
InsanityAutomation 6128d61186 Merge branch 'bugfix-2.1.x' of https://github.com/MarlinFirmware/Marlin into bugfix-2.1.x 2023-08-04 09:47:12 -04:00
InsanityAutomation 6657c44cc7 Merge branch 'bugfix-2.1.x' of https://github.com/MarlinFirmware/Marlin into bugfix-2.1.x 2023-07-26 11:52:43 -04:00
InsanityAutomation 52c37ee699 Merge branch 'bugfix-2.1.x' of https://github.com/MarlinFirmware/Marlin into bugfix-2.1.x 2023-06-23 09:26:59 -04:00
InsanityAutomation 134958a535 Merge branch 'bugfix-2.1.x' of https://github.com/MarlinFirmware/Marlin into bugfix-2.1.x 2023-04-24 13:25:58 -04:00
InsanityAutomation 0f7ef6b586 Merge branch 'bugfix-2.1.x' of https://github.com/MarlinFirmware/Marlin into bugfix-2.1.x 2023-03-10 09:10:03 -05:00
InsanityAutomation 9cbb6b1512 Merge branch 'bugfix-2.1.x' of https://github.com/MarlinFirmware/Marlin into bugfix-2.1.x 2023-02-06 15:59:13 -05:00
InsanityAutomation af85a271a5 Merge branch 'bugfix-2.1.x' of https://github.com/MarlinFirmware/Marlin into bugfix-2.1.x 2023-02-03 15:20:56 -05:00
MarkMan0 a7eacbcc49 🐛 Fix, Refactor PID scaling (#25096) 2022-12-17 23:48:33 -06:00
Scott Lahteine 05e2e059e3 🐛 Fix M593 F 2022-12-17 23:04:49 -06:00
36 changed files with 921 additions and 971 deletions
+123 -129
View File
@@ -101,7 +101,7 @@
* Currently Ethernet (-2) is only supported on Teensy 4.1 boards.
* :[-2, -1, 0, 1, 2, 3, 4, 5, 6, 7]
*/
//#define SERIAL_PORT_2 1
#define SERIAL_PORT_2 0
//#define BAUDRATE_2 250000 // :[2400, 9600, 19200, 38400, 57600, 115200, 250000, 500000, 1000000] Enable to override BAUDRATE
/**
@@ -116,7 +116,7 @@
//#define BLUETOOTH
// Name displayed in the LCD "Ready" message and Info menu
#define CUSTOM_MACHINE_NAME "FatBoy"
#define CUSTOM_MACHINE_NAME "22IDEX"
// Printer's unique ID, used by some programs to differentiate between machines.
// Choose your own or use a service like https://www.uuidgenerator.net/version4
@@ -135,18 +135,18 @@
* Options: A4988, A5984, DRV8825, LV8729, TB6560, TB6600, TMC2100,
* TMC2130, TMC2130_STANDALONE, TMC2160, TMC2160_STANDALONE,
* TMC2208, TMC2208_STANDALONE, TMC2209, TMC2209_STANDALONE,
* TMC26X, TMC26X_STANDALONE, TMC2660, TMC2660_STANDALONE,
* TMC5130, TMC5130_STANDALONE, TMC5160, TMC5160_STANDALONE
* :['A4988', 'A5984', 'DRV8825', 'LV8729', 'TB6560', 'TB6600', 'TMC2100', 'TMC2130', 'TMC2130_STANDALONE', 'TMC2160', 'TMC2160_STANDALONE', 'TMC2208', 'TMC2208_STANDALONE', 'TMC2209', 'TMC2209_STANDALONE', 'TMC26X', 'TMC26X_STANDALONE', 'TMC2660', 'TMC2660_STANDALONE', 'TMC5130', 'TMC5130_STANDALONE', 'TMC5160', 'TMC5160_STANDALONE']
* TMC2660, TMC2660_STANDALONE, TMC5130, TMC5130_STANDALONE,
* TMC5160, TMC5160_STANDALONE
* :['A4988', 'A5984', 'DRV8825', 'LV8729', 'TB6560', 'TB6600', 'TMC2100', 'TMC2130', 'TMC2130_STANDALONE', 'TMC2160', 'TMC2160_STANDALONE', 'TMC2208', 'TMC2208_STANDALONE', 'TMC2209', 'TMC2209_STANDALONE', 'TMC2660', 'TMC2660_STANDALONE', 'TMC5130', 'TMC5130_STANDALONE', 'TMC5160', 'TMC5160_STANDALONE']
*/
#define X_DRIVER_TYPE TMC5160
#define Y_DRIVER_TYPE TMC5160
#define Z_DRIVER_TYPE TMC5160_STANDALONE
//#define X2_DRIVER_TYPE A4988
#define Y2_DRIVER_TYPE TMC5160
#define Z2_DRIVER_TYPE TMC5160_STANDALONE
#define Z3_DRIVER_TYPE TMC5160_STANDALONE
#define Z4_DRIVER_TYPE TMC5160_STANDALONE
#define X_DRIVER_TYPE TMC2209
#define Y_DRIVER_TYPE TMC2209
#define Z_DRIVER_TYPE TMC2209
#define X2_DRIVER_TYPE TMC2209
#define Y2_DRIVER_TYPE TMC2209
#define Z2_DRIVER_TYPE TMC2209
#define Z3_DRIVER_TYPE TMC2209
//#define Z4_DRIVER_TYPE TB6600
//#define I_DRIVER_TYPE A4988
//#define J_DRIVER_TYPE A4988
//#define K_DRIVER_TYPE A4988
@@ -154,7 +154,7 @@
//#define V_DRIVER_TYPE A4988
//#define W_DRIVER_TYPE A4988
#define E0_DRIVER_TYPE TMC2209
//#define E1_DRIVER_TYPE A4988
#define E1_DRIVER_TYPE TMC2209
//#define E2_DRIVER_TYPE A4988
//#define E3_DRIVER_TYPE A4988
//#define E4_DRIVER_TYPE A4988
@@ -208,7 +208,7 @@
// This defines the number of extruders
// :[0, 1, 2, 3, 4, 5, 6, 7, 8]
#define EXTRUDERS 1
#define EXTRUDERS 2
// Generally expected filament diameter (1.75, 2.85, 3.0, ...). Used for Volumetric, Filament Width Sensor, etc.
#define DEFAULT_NOMINAL_FILAMENT_DIA 1.75
@@ -392,38 +392,29 @@
* Enable and connect the power supply to the PS_ON_PIN.
* Specify whether the power supply is active HIGH or active LOW.
*/
//#define PSU_CONTROL
#define PSU_CONTROL
//#define PSU_NAME "Power Supply"
#if ENABLED(PSU_CONTROL)
//#define MKS_PWC // Using the MKS PWC add-on
//#define PS_OFF_CONFIRM // Confirm dialog when power off
//#define PS_OFF_SOUND // Beep 1s when power off
#define PSU_ACTIVE_STATE HIGH // Set 'LOW' for ATX, 'HIGH' for X-Box
#define PSU_ACTIVE_STATE LOW // Set 'LOW' for ATX, 'HIGH' for X-Box
#define PSU_DEFAULT_OFF // Keep power off until enabled directly with M80
#define PSU_POWERUP_DELAY 750 // (ms) Delay for the PSU to warm up to full power
//#define LED_POWEROFF_TIMEOUT 10000 // (ms) Turn off LEDs after power-off, with this amount of delay
//#define PSU_DEFAULT_OFF // Keep power off until enabled directly with M80
//#define PSU_POWERUP_DELAY 250 // (ms) Delay for the PSU to warm up to full power
//#define LED_POWEROFF_TIMEOUT 10000 // (ms) Turn off LEDs after power-off, with this amount of delay
#define PSU_OFF_REDUNDANT // Second pin for redundant power control
//#define PSU_OFF_REDUNDANT_OPPOSING // Redundant pin works opposite standard pin
#define PS_ON_PIN P4_28 // Redundant Pin
#define PS_ON1_PIN P1_03 // Redundant Pin
//#define PSU_OFF_REDUNDANT // Second pin for redundant power control
//#define PSU_OFF_REDUNDANT_INVERTED // Redundant pin state is the inverse of PSU_ACTIVE_STATE
#define PS_ON_EDM_PIN P4_29 // EDM Pins to monitor feedback on external power control relay. Fault on mismatch.
#define PS_ON1_EDM_PIN P1_17
#define PS_EDM_RESPONSE 1000 // Time in MS to allow for relay action
#define PS_ON_PIN P4_29 // Redundant pin required to enable power in combination with PS_ON_PIN
#define PSU_OFF_REDUNDANT // Second pin for redundant power control
//#define PSU_OFF_REDUNDANT_OPPOSING // Redundant pin works opposite standard pin
#define PS_ON_PIN P4_28 // Redundant Pin
#define PS_ON1_PIN P1_03 // Redundant Pin
//#define PS_ON_EDM_PIN 8 // External Device Monitoring pins for external power control relay feedback. Fault on mismatch.
//#define PS_ON1_EDM_PIN 9
#define PS_EDM_RESPONSE 250 // (ms) Time to allow for relay action
#define PS_ON_EDM_PIN P4_29 // EDM Pins to monitor feedback on external power control relay. Fault on mismatch.
#define PS_ON1_EDM_PIN P1_17
#define PS_EDM_RESPONSE 1000 // Time in MS to allow for relay action
//#define POWER_OFF_TIMER // Enable M81 D<seconds> to power off after a delay
#define POWER_OFF_TIMER // Enable M81 D<seconds> to power off after a delay
//#define POWER_OFF_WAIT_FOR_COOLDOWN // Enable M81 S to power off only after cooldown
//#define PSU_POWERUP_GCODE "M355 S1" // G-code to run after power-on (e.g., case light on)
@@ -438,7 +429,7 @@
#define AUTO_POWER_COOLER_FAN // Turn on PSU for Cooler Fan
#define AUTO_POWER_SPINDLE_LASER // Turn on PSU for Spindle/Laser
#define POWER_TIMEOUT 30 // (s) Turn off power if the machine is idle for this duration
//#define POWER_OFF_DELAY 60 // (s) Delay of poweroff after M81 command. Useful to let fans run for extra time.
#define POWER_OFF_DELAY 120 // (s) Delay of poweroff after M81 command. Useful to let fans run for extra time.
#endif
#if ANY(AUTO_POWER_CONTROL, POWER_OFF_WAIT_FOR_COOLDOWN)
//#define AUTO_POWER_E_TEMP 50 // (°C) PSU on if any extruder is over this temperature
@@ -562,17 +553,17 @@
* 998 : Dummy Table that ALWAYS reads 25°C or the temperature defined below.
* 999 : Dummy Table that ALWAYS reads 100°C or the temperature defined below.
*/
#define TEMP_SENSOR_0 1
#define TEMP_SENSOR_1 0
#define TEMP_SENSOR_0 1047
#define TEMP_SENSOR_1 1047
#define TEMP_SENSOR_2 0
#define TEMP_SENSOR_3 0
#define TEMP_SENSOR_4 0
#define TEMP_SENSOR_5 0
#define TEMP_SENSOR_6 0
#define TEMP_SENSOR_7 0
#define TEMP_SENSOR_BED 11
#define TEMP_SENSOR_BED 1
#define TEMP_SENSOR_PROBE 0
#define TEMP_SENSOR_CHAMBER 0
#define TEMP_SENSOR_CHAMBER 1
#define TEMP_SENSOR_COOLER 0
#define TEMP_SENSOR_BOARD 0
#define TEMP_SENSOR_SOC 0
@@ -597,13 +588,13 @@
#endif
#if HAS_E_TEMP_SENSOR
#define TEMP_RESIDENCY_TIME 10 // (seconds) Time to wait for hotend to "settle" in M109
#define TEMP_RESIDENCY_TIME 5 // (seconds) Time to wait for hotend to "settle" in M109
#define TEMP_WINDOW 1 // (°C) Temperature proximity for the "temperature reached" timer
#define TEMP_HYSTERESIS 3 // (°C) Temperature proximity considered "close enough" to the target
#endif
#if TEMP_SENSOR_BED
#define TEMP_BED_RESIDENCY_TIME 10 // (seconds) Time to wait for bed to "settle" in M190
#define TEMP_BED_RESIDENCY_TIME 5 // (seconds) Time to wait for bed to "settle" in M190
#define TEMP_BED_WINDOW 1 // (°C) Temperature proximity for the "temperature reached" timer
#define TEMP_BED_HYSTERESIS 3 // (°C) Temperature proximity considered "close enough" to the target
#endif
@@ -646,16 +637,16 @@
// Above this temperature the heater will be switched off.
// This can protect components from overheating, but NOT from shorts and failures.
// (Use MINTEMP for thermistor short/failure protection.)
#define HEATER_0_MAXTEMP 300
#define HEATER_1_MAXTEMP 275
#define HEATER_0_MAXTEMP 450
#define HEATER_1_MAXTEMP 450
#define HEATER_2_MAXTEMP 275
#define HEATER_3_MAXTEMP 275
#define HEATER_4_MAXTEMP 275
#define HEATER_5_MAXTEMP 275
#define HEATER_6_MAXTEMP 275
#define HEATER_7_MAXTEMP 275
#define BED_MAXTEMP 120
#define CHAMBER_MAXTEMP 60
#define BED_MAXTEMP 215
#define CHAMBER_MAXTEMP 110
/**
* Thermal Overshoot
@@ -680,8 +671,8 @@
* PIDTEMP : PID temperature control (~4.1K)
* MPCTEMP : Predictive Model temperature control. (~1.8K without auto-tune)
*/
#define PIDTEMP // See the PID Tuning Guide at https://reprap.org/wiki/PID_Tuning
//#define MPCTEMP // ** EXPERIMENTAL ** See https://marlinfw.org/docs/features/model_predictive_control.html
//#define PIDTEMP // See the PID Tuning Guide at https://reprap.org/wiki/PID_Tuning
#define MPCTEMP // See https://marlinfw.org/docs/features/model_predictive_control.html
#define PID_MAX 255 // Limit hotend current while PID is active (see PID_FUNCTIONAL_RANGE below); 255=full current
#define PID_K1 0.95 // Smoothing factor within any PID loop
@@ -716,20 +707,20 @@
*/
#if ENABLED(MPCTEMP)
#define MPC_AUTOTUNE // Include a method to do MPC auto-tuning (~6.3K bytes of flash)
//#define MPC_EDIT_MENU // Add MPC editing to the "Advanced Settings" menu. (~1.3K bytes of flash)
//#define MPC_AUTOTUNE_MENU // Add MPC auto-tuning to the "Advanced Settings" menu. (~350 bytes of flash)
#define MPC_EDIT_MENU // Add MPC editing to the "Advanced Settings" menu. (~1.3K bytes of flash)
#define MPC_AUTOTUNE_MENU // Add MPC auto-tuning to the "Advanced Settings" menu. (~350 bytes of flash)
#define MPC_MAX 255 // (0..255) Current to nozzle while MPC is active.
#define MPC_HEATER_POWER { 40.0f } // (W) Heat cartridge powers.
#define MPC_HEATER_POWER { 50.0f, 50.0f } // (W) Heat cartridge powers.
#define MPC_INCLUDE_FAN // Model the fan speed?
//#define MPC_INCLUDE_FAN // Model the fan speed?
// Measured physical constants from M306
#define MPC_BLOCK_HEAT_CAPACITY { 16.7f } // (J/K) Heat block heat capacities.
#define MPC_SENSOR_RESPONSIVENESS { 0.22f } // (K/s per ∆K) Rate of change of sensor temperature from heat block.
#define MPC_AMBIENT_XFER_COEFF { 0.068f } // (W/K) Heat transfer coefficients from heat block to room air with fan off.
#define MPC_BLOCK_HEAT_CAPACITY { 16.7f, 16.7f } // (J/K) Heat block heat capacities.
#define MPC_SENSOR_RESPONSIVENESS { 0.22f, 0.22f } // (K/s per ∆K) Rate of change of sensor temperature from heat block.
#define MPC_AMBIENT_XFER_COEFF { 0.068f, 0.068f } // (W/K) Heat transfer coefficients from heat block to room air with fan off.
#if ENABLED(MPC_INCLUDE_FAN)
#define MPC_AMBIENT_XFER_COEFF_FAN255 { 0.097f } // (W/K) Heat transfer coefficients from heat block to room air with fan on full.
#define MPC_AMBIENT_XFER_COEFF_FAN255 { 0.097f, 0.097f } // (W/K) Heat transfer coefficients from heat block to room air with fan on full.
#endif
// For one fan and multiple hotends MPC needs to know how to apply the fan cooling effect.
@@ -740,7 +731,7 @@
// Filament Heat Capacity (joules/kelvin/mm)
// Set at runtime with M306 H<value>
#define FILAMENT_HEAT_CAPACITY_PERMM { 5.6e-3f } // 0.0056 J/K/mm for 1.75mm PLA (0.0149 J/K/mm for 2.85mm PLA).
#define FILAMENT_HEAT_CAPACITY_PERMM { 5.6e-3f, 5.6e-3f } // 0.0056 J/K/mm for 1.75mm PLA (0.0149 J/K/mm for 2.85mm PLA).
// 0.0036 J/K/mm for 1.75mm PETG (0.0094 J/K/mm for 2.85mm PETG).
// 0.00515 J/K/mm for 1.75mm ABS (0.0137 J/K/mm for 2.85mm ABS).
// 0.00522 J/K/mm for 1.75mm Nylon (0.0138 J/K/mm for 2.85mm Nylon).
@@ -798,7 +789,7 @@
#endif
// Add 'M190 R T' for more gradual M190 R bed cooling.
//#define BED_ANNEALING_GCODE
#define BED_ANNEALING_GCODE
//===========================================================================
//==================== PID > Chamber Temperature Control ====================
@@ -819,7 +810,7 @@
* the issues involved, don't use chamber PID until someone else verifies that your hardware works.
* @section chamber temp
*/
//#define PIDTEMPCHAMBER
#define PIDTEMPCHAMBER
//#define CHAMBER_LIMIT_SWITCHING
/**
@@ -865,7 +856,7 @@
* *** IT IS HIGHLY RECOMMENDED TO LEAVE THIS OPTION ENABLED! ***
*/
#define PREVENT_COLD_EXTRUSION
#define EXTRUDE_MINTEMP 170
#define EXTRUDE_MINTEMP 150
/**
* Prevent a single extrusion longer than EXTRUDE_MAXLENGTH.
@@ -915,7 +906,7 @@
// MarkForged Kinematics
// See https://reprap.org/forum/read.php?152,504042
//
//#define MARKFORGED_XY
#define MARKFORGED_XY
//#define MARKFORGED_YX
#if ANY(MARKFORGED_XY, MARKFORGED_YX)
//#define MARKFORGED_INVERSE // Enable for an inverted Markforged kinematics belt path
@@ -1024,9 +1015,6 @@
// Radius around the center where the arm cannot reach
#define MIDDLE_DEAD_ZONE_R 0 // (mm)
#define THETA_HOMING_OFFSET 0 // Calculated from Calibration Guide and M360 / M114. See https://www.morgan3dp.com/morgan-calibration-guide/
#define PSI_HOMING_OFFSET 0 // Calculated from Calibration Guide and M364 / M114. See https://www.morgan3dp.com/morgan-calibration-guide/
#elif ENABLED(MP_SCARA)
#define SCARA_OFFSET_THETA1 12 // degrees
@@ -1045,23 +1033,19 @@
#define DEFAULT_SEGMENTS_PER_SECOND 200
// Length of inner and outer support arms. Measure arm lengths precisely.
#define TPARA_LINKAGE_1 120 // (mm)
#define TPARA_LINKAGE_2 120 // (mm)
#define TPARA_LINKAGE_1 120 // (mm)
#define TPARA_LINKAGE_2 120 // (mm)
// SCARA tower offset (position of Tower relative to bed zero position)
// This needs to be reasonably accurate as it defines the printbed position in the SCARA space.
#define TPARA_OFFSET_X 0 // (mm)
#define TPARA_OFFSET_Y 0 // (mm)
#define TPARA_OFFSET_Z 0 // (mm)
// TPARA tower offset (position of Tower relative to bed zero position)
// This needs to be reasonably accurate as it defines the printbed position in the TPARA space.
#define TPARA_OFFSET_X 0 // (mm)
#define TPARA_OFFSET_Y 0 // (mm)
#define TPARA_OFFSET_Z 0 // (mm)
#define FEEDRATE_SCALING // Convert XY feedrate from mm/s to degrees/s on the fly
// Radius around the center where the arm cannot reach
#define MIDDLE_DEAD_ZONE_R 0 // (mm)
// Calculated from Calibration Guide and M360 / M114. See https://www.morgan3dp.com/morgan-calibration-guide/
#define THETA_HOMING_OFFSET 0
#define PSI_HOMING_OFFSET 0
#endif
// @section polar
@@ -1187,8 +1171,8 @@
* Set to the state (HIGH or LOW) that applies to each endstop.
*/
#define X_MIN_ENDSTOP_HIT_STATE LOW
#define X_MAX_ENDSTOP_HIT_STATE HIGH
#define Y_MIN_ENDSTOP_HIT_STATE LOW
#define X_MAX_ENDSTOP_HIT_STATE LOW
#define Y_MIN_ENDSTOP_HIT_STATE HIGH
#define Y_MAX_ENDSTOP_HIT_STATE HIGH
#define Z_MIN_ENDSTOP_HIT_STATE HIGH
#define Z_MAX_ENDSTOP_HIT_STATE HIGH
@@ -1245,14 +1229,14 @@
* following movement settings. If fewer factors are given than the
* total number of extruders, the last value applies to the rest.
*/
//#define DISTINCT_E_FACTORS
#define DISTINCT_E_FACTORS
/**
* Default Axis Steps Per Unit (linear=steps/mm, rotational=steps/°)
* Override with M92 (when enabled below)
* X, Y, Z [, I [, J [, K...]]], E0 [, E1[, E2...]]
*/
#define DEFAULT_AXIS_STEPS_PER_UNIT { 40, 40, 200, 425 }
#define DEFAULT_AXIS_STEPS_PER_UNIT { 80, 80, 400, 413, 413 }
/**
* Enable support for M92. Disable to save at least ~530 bytes of flash.
@@ -1304,11 +1288,12 @@
* When changing speed and direction, if the difference is less than the
* value set here, it may happen instantaneously.
*/
//#define CLASSIC_JERK
#define CLASSIC_JERK
#if ENABLED(CLASSIC_JERK)
#define DEFAULT_XJERK 10.0
#define DEFAULT_YJERK 10.0
#define DEFAULT_ZJERK 0.3
#define DEFAULT_EJERK 5.0
//#define DEFAULT_IJERK 0.3
//#define DEFAULT_JJERK 0.3
//#define DEFAULT_KJERK 0.3
@@ -1324,8 +1309,6 @@
#endif
#endif
#define DEFAULT_EJERK 5.0 // May be used by Linear Advance
/**
* Junction Deviation Factor
*
@@ -1350,7 +1333,7 @@
#define S_CURVE_ACCELERATION
#if ENABLED(S_CURVE_ACCELERATION)
// Uncomment to use 4th instead of 6th order motion curve
#define S_CURVE_FACTOR 0.35 // Initial and final acceleration factor, ideally 0.1 to 0.4
#define S_CURVE_FACTOR 0.3 // Initial and final acceleration factor, ideally 0.1 to 0.4
// Shouldn't generally require tuning
#endif
@@ -1428,7 +1411,7 @@
/**
* The BLTouch probe uses a Hall effect sensor and emulates a servo.
*/
#define BLTOUCH
//#define BLTOUCH
/**
* MagLev V4 probe by MDD
@@ -1470,6 +1453,17 @@
//#define BD_SENSOR_PROBE_NO_STOP // Probe bed without stopping at each probe point
#endif
/**
* BIQU MicroProbe
*
* A lightweight, solenoid-driven probe.
* For information about this sensor https://github.com/bigtreetech/MicroProbe
*
* Also requires: PROBE_ENABLE_DISABLE
*/
//#define BIQU_MICROPROBE_V1 // Triggers HIGH
//#define BIQU_MICROPROBE_V2 // Triggers LOW
// A probe that is deployed and stowed with a solenoid pin (SOL1_PIN)
//#define SOLENOID_PROBE
@@ -1488,20 +1482,20 @@
* Magnetically Mounted Probe
* For probes such as Euclid, Klicky, Klackender, etc.
*/
//#define MAG_MOUNTED_PROBE
#define MAG_MOUNTED_PROBE
#if ENABLED(MAG_MOUNTED_PROBE)
#define PROBE_DEPLOY_FEEDRATE (133*60) // (mm/min) Probe deploy speed
#define PROBE_STOW_FEEDRATE (133*60) // (mm/min) Probe stow speed
#define MAG_MOUNTED_DEPLOY_1 { PROBE_DEPLOY_FEEDRATE, { 245, 114, 30 } } // Move to side Dock & Attach probe
#define MAG_MOUNTED_DEPLOY_2 { PROBE_DEPLOY_FEEDRATE, { 210, 114, 30 } } // Move probe off dock
#define MAG_MOUNTED_DEPLOY_1 { PROBE_DEPLOY_FEEDRATE, { 200, 400, 0 } } // Move to side Dock & Attach probe
#define MAG_MOUNTED_DEPLOY_2 { PROBE_DEPLOY_FEEDRATE, { 100, 400, 0 } } // Move probe off dock
#define MAG_MOUNTED_DEPLOY_3 { PROBE_DEPLOY_FEEDRATE, { 0, 0, 0 } } // Extra move if needed
#define MAG_MOUNTED_DEPLOY_4 { PROBE_DEPLOY_FEEDRATE, { 0, 0, 0 } } // Extra move if needed
#define MAG_MOUNTED_DEPLOY_5 { PROBE_DEPLOY_FEEDRATE, { 0, 0, 0 } } // Extra move if needed
#define MAG_MOUNTED_STOW_1 { PROBE_STOW_FEEDRATE, { 245, 114, 20 } } // Move to dock
#define MAG_MOUNTED_STOW_2 { PROBE_STOW_FEEDRATE, { 245, 114, 0 } } // Place probe beside remover
#define MAG_MOUNTED_STOW_3 { PROBE_STOW_FEEDRATE, { 230, 114, 0 } } // Side move to remove probe
#define MAG_MOUNTED_STOW_4 { PROBE_STOW_FEEDRATE, { 210, 114, 20 } } // Side move to remove probe
#define MAG_MOUNTED_STOW_1 { PROBE_STOW_FEEDRATE, { 100, 400, 0 } } // Move to dock
#define MAG_MOUNTED_STOW_2 { PROBE_STOW_FEEDRATE, { 200, 400, 0 } } // Place probe beside remover
#define MAG_MOUNTED_STOW_3 { PROBE_STOW_FEEDRATE, { 200, 300, 0 } } // Side move to remove probe
#define MAG_MOUNTED_STOW_4 { PROBE_STOW_FEEDRATE, { 0, 0, 0 } } // Side move to remove probe
#define MAG_MOUNTED_STOW_5 { PROBE_STOW_FEEDRATE, { 0, 0, 0 } } // Extra move if needed
#endif
@@ -1692,7 +1686,7 @@
//#define PROBE_OFFSET_ZMAX 20 // (mm)
// Enable the M48 repeatability test to test probe accuracy
//#define Z_MIN_PROBE_REPEATABILITY_TEST
#define Z_MIN_PROBE_REPEATABILITY_TEST
// Before deploy/stow pause for user confirmation
//#define PAUSE_BEFORE_DEPLOY_STOW
@@ -1805,7 +1799,7 @@
// Direction of endstops when homing; 1=MAX, -1=MIN
// :[-1,1]
#define X_HOME_DIR -1
#define Y_HOME_DIR -1
#define Y_HOME_DIR 1
#define Z_HOME_DIR -1
//#define I_HOME_DIR -1
//#define J_HOME_DIR -1
@@ -1832,16 +1826,16 @@
// @section geometry
// The size of the printable area
#define X_BED_SIZE 1200
#define Y_BED_SIZE 1200
#define X_BED_SIZE 355
#define Y_BED_SIZE 350
// Travel limits (linear=mm, rotational=°) after homing, corresponding to endstop positions.
#define X_MIN_POS 0
#define X_MIN_POS -20.93
#define Y_MIN_POS 0
#define Z_MIN_POS 0
#define X_MAX_POS X_BED_SIZE
#define Y_MAX_POS Y_BED_SIZE
#define Z_MAX_POS 1000
#define Z_MAX_POS 500
//#define I_MIN_POS 0
//#define I_MAX_POS 50
//#define J_MIN_POS 0
@@ -1909,11 +1903,12 @@
* RAMPS-based boards use SERVO3_PIN for the first runout sensor.
* For other boards you may need to define FIL_RUNOUT_PIN, FIL_RUNOUT2_PIN, etc.
*/
//#define FILAMENT_RUNOUT_SENSOR
#define FILAMENT_RUNOUT_SENSOR
#if ENABLED(FILAMENT_RUNOUT_SENSOR)
#define FIL_RUNOUT_ENABLED_DEFAULT true // Enable the sensor on startup. Override with M412 followed by M500.
#define NUM_RUNOUT_SENSORS 1 // Number of sensors, up to one per extruder. Define a FIL_RUNOUT#_PIN for each.
#define NUM_RUNOUT_SENSORS 2 // Number of sensors, up to one per extruder. Define a FIL_RUNOUT#_PIN for each.
#define FIL_RUNOUT_PIN Z_MIN_PIN
#define FIL_RUNOUT2_PIN Z_MAX_PIN
#define FIL_RUNOUT_STATE LOW // Pin state indicating that filament is NOT present.
#define FIL_RUNOUT_PULLUP // Use internal pullup for filament runout pins.
//#define FIL_RUNOUT_PULLDOWN // Use internal pulldown for filament runout pins.
@@ -1956,18 +1951,18 @@
// Commands to execute on filament runout.
// With multiple runout sensors use the %c placeholder for the current tool in commands (e.g., "M600 T%c")
// NOTE: After 'M412 H1' the host handles filament runout and this script does not apply.
#define FILAMENT_RUNOUT_SCRIPT "M600"
#define FILAMENT_RUNOUT_SCRIPT "M600 T%c"
// After a runout is detected, continue printing this length of filament
// before executing the runout script. Useful for a sensor at the end of
// a feed tube. Requires 4 bytes SRAM per sensor, plus 4 bytes overhead.
//#define FILAMENT_RUNOUT_DISTANCE_MM 25
#define FILAMENT_RUNOUT_DISTANCE_MM 15
#ifdef FILAMENT_RUNOUT_DISTANCE_MM
// Enable this option to use an encoder disc that toggles the runout pin
// as the filament moves. (Be sure to set FILAMENT_RUNOUT_DISTANCE_MM
// large enough to avoid false positives.)
//#define FILAMENT_MOTION_SENSOR
#define FILAMENT_MOTION_SENSOR
#if ENABLED(FILAMENT_MOTION_SENSOR)
//#define FILAMENT_SWITCH_AND_MOTION
@@ -2052,8 +2047,8 @@
*/
//#define AUTO_BED_LEVELING_3POINT
//#define AUTO_BED_LEVELING_LINEAR
#define AUTO_BED_LEVELING_BILINEAR
//#define AUTO_BED_LEVELING_UBL
//#define AUTO_BED_LEVELING_BILINEAR
#define AUTO_BED_LEVELING_UBL
//#define MESH_BED_LEVELING
/**
@@ -2162,18 +2157,18 @@
//#define MESH_EDIT_GFX_OVERLAY // Display a graphics overlay while editing the mesh
#define MESH_INSET 1 // Set Mesh bounds as an inset region of the bed
#define GRID_MAX_POINTS_X 10 // Don't use more than 15 points per axis, implementation limited.
#define GRID_MAX_POINTS_X 7 // Don't use more than 15 points per axis, implementation limited.
#define GRID_MAX_POINTS_Y GRID_MAX_POINTS_X
//#define UBL_HILBERT_CURVE // Use Hilbert distribution for less travel when probing multiple points
#define UBL_HILBERT_CURVE // Use Hilbert distribution for less travel when probing multiple points
//#define UBL_TILT_ON_MESH_POINTS // Use nearest mesh points with G29 J for better Z reference
//#define UBL_TILT_ON_MESH_POINTS_3POINT // Use nearest mesh points with G29 J0 (3-point)
#define UBL_TILT_ON_MESH_POINTS // Use nearest mesh points with G29 J for better Z reference
#define UBL_TILT_ON_MESH_POINTS_3POINT // Use nearest mesh points with G29 J0 (3-point)
#define UBL_MESH_EDIT_MOVES_Z // Sophisticated users prefer no movement of nozzle
#define UBL_SAVE_ACTIVE_ON_M500 // Save the currently active mesh in the current slot on M500
//#define UBL_Z_RAISE_WHEN_OFF_MESH 2.5 // When the nozzle is off the mesh, this value is used
#define UBL_Z_RAISE_WHEN_OFF_MESH 0.0 // When the nozzle is off the mesh, this value is used
// as the Z-Height correction value.
//#define UBL_MESH_WIZARD // Run several commands in a row to get a complete mesh
@@ -2219,7 +2214,7 @@
#if ENABLED(LCD_BED_LEVELING)
#define MESH_EDIT_Z_STEP 0.025 // (mm) Step size while manually probing Z axis.
#define LCD_PROBE_Z_RANGE 8 // (mm) Z Range centered on Z_MIN_POS for LCD Z adjustment
#define LCD_PROBE_Z_RANGE 4 // (mm) Z Range centered on Z_MIN_POS for LCD Z adjustment
#define MESH_EDIT_MENU // Add a menu to edit mesh points
#endif
@@ -2229,8 +2224,8 @@
#if ENABLED(LCD_BED_TRAMMING)
#define BED_TRAMMING_INSET_LFRB { 30, 30, 30, 30 } // (mm) Left, Front, Right, Back insets
#define BED_TRAMMING_HEIGHT 0.0 // (mm) Z height of nozzle at tramming points
#define BED_TRAMMING_Z_HOP 4.0 // (mm) Z height of nozzle between tramming points
//#define BED_TRAMMING_INCLUDE_CENTER // Move to the center after the last corner
#define BED_TRAMMING_Z_HOP 4.0 // (mm) Z raise between tramming points
#define BED_TRAMMING_INCLUDE_CENTER // Move to the center after the last corner
//#define BED_TRAMMING_USE_PROBE
#if ENABLED(BED_TRAMMING_USE_PROBE)
#define BED_TRAMMING_PROBE_TOLERANCE 0.1 // (mm)
@@ -2372,7 +2367,7 @@
#define EEPROM_SETTINGS // Persistent storage with M500 and M501
//#define DISABLE_M503 // Saves ~2700 bytes of flash. Disable for release!
#define EEPROM_CHITCHAT // Give feedback on EEPROM commands. Disable to save PROGMEM.
#define EEPROM_BOOT_SILENT // Keep M503 quiet and only give errors during first load
//#define EEPROM_BOOT_SILENT // Keep M503 quiet and only give errors during first load
#if ENABLED(EEPROM_SETTINGS)
#define EEPROM_AUTO_INIT // Init EEPROM automatically on any errors.
//#define EEPROM_INIT_NOW // Init EEPROM on first boot after a new build.
@@ -2479,7 +2474,7 @@
*
* Caveats: The ending Z should be the same as starting Z.
*/
//#define NOZZLE_CLEAN_FEATURE
#define NOZZLE_CLEAN_FEATURE
#if ENABLED(NOZZLE_CLEAN_FEATURE)
#define NOZZLE_CLEAN_PATTERN_LINE // Provide 'G12 P0' - a simple linear cleaning pattern
@@ -2489,7 +2484,7 @@
// Default pattern to use when 'P' is not provided to G12. One of the enabled options above.
#define NOZZLE_CLEAN_DEFAULT_PATTERN 0
#define NOZZLE_CLEAN_STROKES 12 // Default number of pattern repetitions
#define NOZZLE_CLEAN_STROKES 4 // Default number of pattern repetitions
#if ENABLED(NOZZLE_CLEAN_PATTERN_ZIGZAG)
#define NOZZLE_CLEAN_TRIANGLES 3 // Default number of triangles
@@ -2497,8 +2492,8 @@
// Specify positions for each tool as { { X, Y, Z }, { X, Y, Z } }
// Dual hotend system may use { { -20, (Y_BED_SIZE / 2), (Z_MIN_POS + 1) }, { 420, (Y_BED_SIZE / 2), (Z_MIN_POS + 1) }}
#define NOZZLE_CLEAN_START_POINT { { 30, 30, (Z_MIN_POS + 1) } }
#define NOZZLE_CLEAN_END_POINT { { 100, 60, (Z_MIN_POS + 1) } }
#define NOZZLE_CLEAN_START_POINT { { 25, 100, (Z_MIN_POS + 1) }, { 375, 100, (Z_MIN_POS + 1) }}
#define NOZZLE_CLEAN_END_POINT { { 5, 101, (Z_MIN_POS + 1) }, { 400, 101, (Z_MIN_POS + 1) } }
#if ENABLED(NOZZLE_CLEAN_PATTERN_CIRCLE)
#define NOZZLE_CLEAN_CIRCLE_RADIUS 6.5 // (mm) Circular pattern radius
@@ -2510,7 +2505,7 @@
#define NOZZLE_CLEAN_GOBACK
// For a purge/clean station that's always at the gantry height (thus no Z move)
//#define NOZZLE_CLEAN_NO_Z
#define NOZZLE_CLEAN_NO_Z
// For a purge/clean station mounted on the X axis
//#define NOZZLE_CLEAN_NO_Y
@@ -2647,9 +2642,9 @@
#define DISPLAY_CHARSET_HD44780 JAPANESE
/**
* Info Screen Style (0:Classic, 1:Průša)
* Info Screen Style (0:Classic, 1:Průša, 2:CNC)
*
* :[0:'Classic', 1:'Průša']
* :[0:'Classic', 1:'Průša', 2:'CNC']
*/
#define LCD_INFO_SCREEN_STYLE 0
@@ -3050,7 +3045,7 @@
//
// Factory display for Creality CR-10 / CR-7 / Ender-3
// https://www.aliexpress.com/item/32833148327.html
// https://marlinfw.org/docs/hardware/controllers.html#cr10_stockdisplay
//
// Connect to EXP1 on RAMPS and compatible boards.
//
@@ -3427,7 +3422,6 @@
#define BUTTON_DELAY_MENU 250 // (ms) Button repeat delay for menus
//#define DISABLE_ENCODER // Disable the click encoder, if any
//#define TOUCH_IDLE_SLEEP_MINS 5 // (minutes) Display Sleep after a period of inactivity. Set with M255 S.
#define TOUCH_SCREEN_CALIBRATION
@@ -3532,13 +3526,13 @@
// LED Type. Enable only one of the following two options:
//#define RGB_LED
//#define RGBW_LED
#define RGBW_LED
#if ANY(RGB_LED, RGBW_LED)
//#define RGB_LED_R_PIN 34
//#define RGB_LED_G_PIN 43
//#define RGB_LED_B_PIN 35
//#define RGB_LED_W_PIN -1
#define RGB_LED_R_PIN EFAN0_PIN
#define RGB_LED_G_PIN EFAN1_PIN
#define RGB_LED_B_PIN EFAN2_PIN
#define RGB_LED_W_PIN EFAN3_PIN
#endif
#if ANY(RGB_LED, RGBW_LED, PCA9632)
+119 -115
View File
@@ -309,7 +309,7 @@
#define ADAPTIVE_FAN_SLOWING // Slow down the part-cooling fan if the temperature drops
#if ENABLED(ADAPTIVE_FAN_SLOWING)
//#define REPORT_ADAPTIVE_FAN_SLOWING // Report fan slowing activity to the console
#define REPORT_ADAPTIVE_FAN_SLOWING // Report fan slowing activity to the console
#if ANY(MPCTEMP, PIDTEMP)
#define TEMP_TUNING_MAINTAIN_FAN // Don't slow down the fan speed during M303 or M306 T
#endif
@@ -335,7 +335,7 @@
* Thermal Protection parameters for the bed are just as above for hotends.
*/
#if ENABLED(THERMAL_PROTECTION_BED)
#define THERMAL_PROTECTION_BED_PERIOD 90 // (seconds)
#define THERMAL_PROTECTION_BED_PERIOD 20 // (seconds)
#define THERMAL_PROTECTION_BED_HYSTERESIS 2 // (°C)
/**
@@ -459,7 +459,7 @@
#define PID_FAN_SCALING_LIN_FACTOR (PID_FAN_SCALING_AT_FULL_SPEED-DEFAULT_Kf)/255.0
#else
#define PID_FAN_SCALING_LIN_FACTOR (0) // Power loss due to cooling = Kf * (fan_speed)
#define PID_FAN_SCALING_LIN_FACTOR (0) // Power-loss due to cooling = Kf * (fan_speed)
#define DEFAULT_Kf 10 // A constant value added to the PID-tuner
#define PID_FAN_SCALING_MIN_SPEED 10 // Minimum fan speed at which to enable PID_FAN_SCALING
#endif
@@ -549,8 +549,8 @@
*/
#define HOTEND_IDLE_TIMEOUT
#if ENABLED(HOTEND_IDLE_TIMEOUT)
#define HOTEND_IDLE_TIMEOUT_SEC (30*60) // (seconds) Time without extruder movement to trigger protection
#define HOTEND_IDLE_MIN_TRIGGER 170 // (°C) Minimum temperature to enable hotend protection
#define HOTEND_IDLE_TIMEOUT_SEC (5*60) // (seconds) Time without extruder movement to trigger protection
#define HOTEND_IDLE_MIN_TRIGGER 180 // (°C) Minimum temperature to enable hotend protection
#define HOTEND_IDLE_NOZZLE_TARGET 0 // (°C) Safe temperature for the nozzle after timeout
#define HOTEND_IDLE_BED_TARGET 0 // (°C) Safe temperature for the bed after timeout
#endif
@@ -603,7 +603,7 @@
* (Does not work on Sanguinololu with FAN_SOFT_PWM.)
*/
#define FAN_KICKSTART_TIME 100 // (ms)
#define FAN_KICKSTART_POWER 180 // 64-255
//#define FAN_KICKSTART_POWER 180 // 64-255
// Some coolers may require a non-zero "off" state.
//#define FAN_OFF_PWM 1
@@ -681,8 +681,8 @@
* Multiple extruders can be assigned to the same pin in which case
* the fan will turn on when any selected extruder is above the threshold.
*/
#define E0_AUTO_FAN_PIN -1
#define E1_AUTO_FAN_PIN -1
#define E0_AUTO_FAN_PIN FAN3_PIN
#define E1_AUTO_FAN_PIN FAN3_PIN
#define E2_AUTO_FAN_PIN -1
#define E3_AUTO_FAN_PIN -1
#define E4_AUTO_FAN_PIN -1
@@ -748,12 +748,12 @@
* @section caselight
* M355 Case Light on-off / brightness
*/
//#define CASE_LIGHT_ENABLE
#define CASE_LIGHT_ENABLE
#if ENABLED(CASE_LIGHT_ENABLE)
//#define CASE_LIGHT_PIN 4 // Override the default pin if needed
#define INVERT_CASE_LIGHT false // Set true if Case Light is ON when pin is LOW
#define CASE_LIGHT_DEFAULT_ON true // Set default power-up state on
#define CASE_LIGHT_DEFAULT_BRIGHTNESS 105 // Set default power-up brightness (0-255, requires PWM pin)
#define CASE_LIGHT_DEFAULT_BRIGHTNESS 255 // Set default power-up brightness (0-255, requires PWM pin)
//#define CASE_LIGHT_NO_BRIGHTNESS // Disable brightness control. Enable for non-PWM lighting.
//#define CASE_LIGHT_MAX_PWM 128 // Limit PWM duty cycle (0-255)
//#define CASE_LIGHT_MENU // Add Case Light options to the LCD menu
@@ -761,7 +761,7 @@
//#define CASE_LIGHT_USE_NEOPIXEL // Use NeoPixel LED as case light
#endif
#if ANY(RGB_LED, RGBW_LED)
//#define CASE_LIGHT_USE_RGB_LED // Use RGB / RGBW LED as case light
#define CASE_LIGHT_USE_RGB_LED // Use RGB / RGBW LED as case light
#endif
#if ANY(CASE_LIGHT_USE_NEOPIXEL, CASE_LIGHT_USE_RGB_LED)
#define CASE_LIGHT_DEFAULT_COLOR { 255, 255, 255, 255 } // { Red, Green, Blue, White }
@@ -815,12 +815,12 @@
* Set the initial X offset and temperature differential with M605 S2 X[offs] R[deg] and
* follow with M605 S3 to initiate mirrored movement.
*/
//#define DUAL_X_CARRIAGE
#define DUAL_X_CARRIAGE
#if ENABLED(DUAL_X_CARRIAGE)
#define X1_MIN_POS X_MIN_POS // Set to X_MIN_POS
#define X1_MAX_POS X_BED_SIZE // A max coordinate so the X1 carriage can't hit the parked X2 carriage
#define X2_MIN_POS 80 // A min coordinate so the X2 carriage can't hit the parked X1 carriage
#define X2_MAX_POS 353 // The max position of the X2 carriage, typically also the home position
#define X2_MIN_POS 10 // A min coordinate so the X2 carriage can't hit the parked X1 carriage
#define X2_MAX_POS 369 // The max position of the X2 carriage, typically also the home position
#define X2_HOME_POS X2_MAX_POS // Default X2 home position. Set to X2_MAX_POS.
// NOTE: For Dual X Carriage use M218 T1 Xn to override the X2_HOME_POS.
// This allows recalibration of endstops distance without a rebuild.
@@ -830,10 +830,10 @@
#define DEFAULT_DUAL_X_CARRIAGE_MODE DXC_AUTO_PARK_MODE
// Default x offset in duplication mode (typically set to half print bed width)
#define DEFAULT_DUPLICATION_X_OFFSET 100
#define DEFAULT_DUPLICATION_X_OFFSET 175
// Default action to execute following M605 mode change commands. Typically G28X to apply new mode.
//#define EVENT_GCODE_IDEX_AFTER_MODECHANGE "G28X"
#define EVENT_GCODE_IDEX_AFTER_MODECHANGE "G28X"
#endif
// @section multi stepper
@@ -860,7 +860,7 @@
*/
#if HAS_X2_STEPPER && DISABLED(DUAL_X_CARRIAGE)
//#define INVERT_X2_VS_X_DIR // X2 direction signal is the opposite of X
//#define X_DUAL_ENDSTOPS // X2 has its own endstop
#define X_DUAL_ENDSTOPS // X2 has its own endstop
#if ENABLED(X_DUAL_ENDSTOPS)
//#define X2_STOP_PIN X_MAX_PIN // X2 endstop pin override
#define X2_ENDSTOP_ADJUSTMENT 0 // X2 offset relative to X endstop
@@ -868,8 +868,8 @@
#endif
#if HAS_Y2_STEPPER
//#define INVERT_Y2_VS_Y_DIR // Y2 direction signal is the opposite of Y
//#define Y_DUAL_ENDSTOPS // Y2 has its own endstop
#define INVERT_Y2_VS_Y_DIR // Y2 direction signal is the opposite of Y
#define Y_DUAL_ENDSTOPS // Y2 has its own endstop
#if ENABLED(Y_DUAL_ENDSTOPS)
//#define Y2_STOP_PIN Y_MAX_PIN // Y2 endstop pin override
#define Y2_ENDSTOP_ADJUSTMENT 0 // Y2 offset relative to Y endstop
@@ -932,7 +932,7 @@
//#define XY_COUNTERPART_BACKOFF_MM 0 // (mm) Backoff X after homing Y, and vice-versa
#define QUICK_HOME // If G28 contains XY do a diagonal move first
//#define HOME_Y_BEFORE_X // If G28 contains XY home Y before X
#define HOME_Y_BEFORE_X // If G28 contains XY home Y before X
//#define HOME_Z_FIRST // Home Z first. Requires a real endstop (not a probe).
//#define CODEPENDENT_XY_HOMING // If X/Y can't home without homing Y/X first
@@ -1028,7 +1028,7 @@
* If not defined, probe limits will be used.
* Override with 'M422 S<index> X<pos> Y<pos>'.
*/
//#define Z_STEPPER_ALIGN_XY { { 10, 190 }, { 100, 10 }, { 190, 190 } }
//#define Z_STEPPER_ALIGN_XY { { -44, 6.88 }, { 404, 6.88 }, { 209.3, 370.75 } }
/**
* Orientation for the automatically-calculated probe positions.
@@ -1061,7 +1061,7 @@
* positions in the bed carriage, with one position per Z stepper in stepper
* driver order.
*/
//#define Z_STEPPER_ALIGN_STEPPER_XY { { 210.7, 102.5 }, { 152.6, 220.0 }, { 94.5, 102.5 } }
#define Z_STEPPER_ALIGN_STEPPER_XY { { -44, 6.88 }, { 404, 6.88 }, { 209.3, 370.75 } }
#ifndef Z_STEPPER_ALIGN_STEPPER_XY
// Amplification factor. Used to scale the correction step up or down in case
@@ -1070,7 +1070,7 @@
#endif
// On a 300mm bed a 5% grade would give a misalignment of ~1.5cm
#define G34_MAX_GRADE 5 // (%) Maximum incline that G34 will handle
#define G34_MAX_GRADE 15 // (%) Maximum incline that G34 will handle
#define Z_STEPPER_ALIGN_ITERATIONS 5 // Number of iterations to apply during alignment
#define Z_STEPPER_ALIGN_ACC 0.02 // Stop iterating early if the accuracy is better than this
#define RESTORE_LEVELING_AFTER_G34 // Restore leveling after G34 is done?
@@ -1185,33 +1185,32 @@
* Zero Vibration (ZV) Input Shaping for X and/or Y movements.
*
* This option uses a lot of SRAM for the step buffer. The buffer size is
* calculated automatically from SHAPING_FREQ_[XY], DEFAULT_AXIS_STEPS_PER_UNIT,
* calculated automatically from SHAPING_FREQ_[XYZ], DEFAULT_AXIS_STEPS_PER_UNIT,
* DEFAULT_MAX_FEEDRATE and ADAPTIVE_STEP_SMOOTHING. The default calculation can
* be overridden by setting SHAPING_MIN_FREQ and/or SHAPING_MAX_FEEDRATE.
* The higher the frequency and the lower the feedrate, the smaller the buffer.
* If the buffer is too small at runtime, input shaping will have reduced
* effectiveness during high speed movements.
*
* Tune with M593 D<factor> F<frequency>:
*
* D<factor> Set the zeta/damping factor. If axes (X, Y, etc.) are not specified, set for all axes.
* F<frequency> Set the frequency. If axes (X, Y, etc.) are not specified, set for all axes.
* T[map] Input Shaping type, 0:ZV, 1:EI, 2:2H EI (not implemented yet)
* X<1> Set the given parameters only for the X axis.
* Y<1> Set the given parameters only for the Y axis.
* Tune with M593 D<factor> F<frequency>
*/
//#define INPUT_SHAPING_X
//#define INPUT_SHAPING_Y
#if ANY(INPUT_SHAPING_X, INPUT_SHAPING_Y)
//#define INPUT_SHAPING_Z
#if ANY(INPUT_SHAPING_X, INPUT_SHAPING_Y, INPUT_SHAPING_Z)
#if ENABLED(INPUT_SHAPING_X)
#define SHAPING_FREQ_X 40 // (Hz) The default dominant resonant frequency on the X axis.
#define SHAPING_ZETA_X 0.15f // Damping ratio of the X axis (range: 0.0 = no damping to 1.0 = critical damping).
#define SHAPING_FREQ_X 40.0 // (Hz) The default dominant resonant frequency on the X axis.
#define SHAPING_ZETA_X 0.15 // Damping ratio of the X axis (range: 0.0 = no damping to 1.0 = critical damping).
#endif
#if ENABLED(INPUT_SHAPING_Y)
#define SHAPING_FREQ_Y 40 // (Hz) The default dominant resonant frequency on the Y axis.
#define SHAPING_ZETA_Y 0.15f // Damping ratio of the Y axis (range: 0.0 = no damping to 1.0 = critical damping).
#define SHAPING_FREQ_Y 40.0 // (Hz) The default dominant resonant frequency on the Y axis.
#define SHAPING_ZETA_Y 0.15 // Damping ratio of the Y axis (range: 0.0 = no damping to 1.0 = critical damping).
#endif
//#define SHAPING_MIN_FREQ 20 // By default the minimum of the shaping frequencies. Override to affect SRAM usage.
#if ENABLED(INPUT_SHAPING_Z)
#define SHAPING_FREQ_Z 40.0 // (Hz) The default dominant resonant frequency on the Z axis.
#define SHAPING_ZETA_Z 0.15 // Damping ratio of the Z axis (range: 0.0 = no damping to 1.0 = critical damping).
#endif
//#define SHAPING_MIN_FREQ 20.0 // (Hz) By default the minimum of the shaping frequencies. Override to affect SRAM usage.
//#define SHAPING_MAX_STEPRATE 10000 // By default the maximum total step rate of the shaped axes. Override to affect SRAM usage.
//#define SHAPING_MENU // Add a menu to the LCD to set shaping parameters.
#endif
@@ -1263,18 +1262,18 @@
// Increase the slowdown divisor for larger buffer sizes.
#define SLOWDOWN
#if ENABLED(SLOWDOWN)
#define SLOWDOWN_DIVISOR 2
#define SLOWDOWN_DIVISOR 8
#endif
/**
* XY Frequency limit
* Reduce resonance by limiting the frequency of small zigzag infill moves.
* See https://hydraraptor.blogspot.com/2010/12/frequency-limit.html
* Use M201 F<freq> G<min%> to change limits at runtime.
* Use M201 F<freq> S<min%> to change limits at runtime.
*/
//#define XY_FREQUENCY_LIMIT 10 // (Hz) Maximum frequency of small zigzag infill moves. Set with M201 F<hertz>.
#ifdef XY_FREQUENCY_LIMIT
#define XY_FREQUENCY_MIN_PERCENT 5 // (%) Minimum FR percentage to apply. Set with M201 G<min%>.
#define XY_FREQUENCY_MIN_PERCENT 5 // (%) Minimum FR percentage to apply. Set with M201 S<min%>.
#endif
//
@@ -1296,7 +1295,7 @@
//#define BACKLASH_SMOOTHING_MM 3 // (mm)
// Add runtime configuration and tuning of backlash values (M425)
#define BACKLASH_GCODE
//#define BACKLASH_GCODE
#if ENABLED(BACKLASH_GCODE)
// Measure the Z backlash when probing (G29) and set with "M425 Z"
@@ -1326,7 +1325,7 @@
* Note: HOTEND_OFFSET and CALIBRATION_OBJECT_CENTER must be set to within
* ±5mm of true values for G425 to succeed.
*/
//#define CALIBRATION_GCODE
#define CALIBRATION_GCODE
#if ENABLED(CALIBRATION_GCODE)
//#define CALIBRATION_SCRIPT_PRE "M117 Starting Auto-Calibration\nT0\nG28\nG12\nM117 Calibrating..."
@@ -1342,7 +1341,7 @@
#define CALIBRATION_NOZZLE_TIP_HEIGHT 1.0 // mm
#define CALIBRATION_NOZZLE_OUTER_DIAMETER 2.0 // mm
// Uncomment to enable reporting (required for "G425 V", but consumes PROGMEM).
// Uncomment to enable reporting (required for "G425 V", but consumes flash).
//#define CALIBRATION_REPORTING
// The true location and dimension the cube/bolt/washer on the bed.
@@ -1386,7 +1385,7 @@
* Multi-stepping sends steps in bursts to reduce MCU usage for high step-rates.
* This allows higher feedrates than the MCU could otherwise support.
*/
#define MULTISTEPPING_LIMIT 32 //: [1, 2, 4, 8, 16, 32, 64, 128]
#define MULTISTEPPING_LIMIT 16 //: [1, 2, 4, 8, 16, 32, 64, 128]
/**
* Adaptive Step Smoothing increases the resolution of multi-axis moves, particularly at step frequencies
@@ -1474,6 +1473,7 @@
#if IS_ULTIPANEL
#define MANUAL_E_MOVES_RELATIVE // Display extruder move distance rather than "position"
#define ULTIPANEL_FEEDMULTIPLY // Encoder sets the feedrate multiplier on the Status Screen
//#define ULTIPANEL_FLOWPERCENT // Encoder sets the flow percentage on the Status Screen
#endif
#endif
@@ -1539,6 +1539,7 @@
* Axis moves <= 1/2 the axis length and Extruder moves <= EXTRUDE_MAXLENGTH
* will be shown in the move submenus.
*/
#define MANUAL_MOVE_DISTANCE_MM 10, 1.0, 0.1 // (mm)
//#define MANUAL_MOVE_DISTANCE_MM 100, 50, 10, 1.0, 0.1 // (mm)
//#define MANUAL_MOVE_DISTANCE_MM 500, 100, 50, 10, 1.0, 0.1 // (mm)
@@ -1580,9 +1581,9 @@
#define BOOT_MARLIN_LOGO_SMALL // Show a smaller Marlin logo on the Boot Screen (saving lots of flash)
#endif
#if HAS_MARLINUI_U8GLIB
#define BOOT_MARLIN_LOGO_ANIMATED // Animated Marlin logo. Costs ~3260 (or ~940) bytes of flash.
//#define BOOT_MARLIN_LOGO_ANIMATED // Animated Marlin logo. Costs ~3260 (or ~940) bytes of flash.
#endif
#if ANY(HAS_MARLINUI_U8GLIB, TOUCH_UI_FTDI_EVE)
#if ANY(HAS_MARLINUI_U8GLIB, TOUCH_UI_FTDI_EVE, HAS_MARLINUI_HD44780)
//#define SHOW_CUSTOM_BOOTSCREEN // Show the bitmap in Marlin/_Bootscreen.h on startup.
#endif
#endif
@@ -1620,7 +1621,7 @@
* LED Control Menu
* Add LED Control to the LCD menu
*/
//#define LED_CONTROL_MENU
#define LED_CONTROL_MENU
#if ENABLED(LED_CONTROL_MENU)
#define LED_COLOR_PRESETS // Enable the Preset Color menu option
//#define NEO2_COLOR_PRESETS // Enable a second NeoPixel Preset Color menu option
@@ -1741,23 +1742,28 @@
* an option on the LCD screen to continue the print from the last-known
* point in the file.
*/
//#define POWER_LOSS_RECOVERY
#define POWER_LOSS_RECOVERY
#if ENABLED(POWER_LOSS_RECOVERY)
#define PLR_ENABLED_DEFAULT false // Power Loss Recovery enabled by default. (Set with 'M413 Sn' & M500)
#define PLR_ENABLED_DEFAULT false // Power-Loss Recovery enabled by default. (Set with 'M413 Sn' & M500)
//#define PLR_BED_THRESHOLD BED_MAXTEMP // (°C) Skip user confirmation at or above this bed temperature (0 to disable)
//#define BACKUP_POWER_SUPPLY // Backup power / UPS to move the steppers on power loss
//#define POWER_LOSS_ZRAISE 2 // (mm) Z axis raise on resume (on power loss with UPS)
//#define POWER_LOSS_PIN 44 // Pin to detect power loss. Set to -1 to disable default pin on boards without module.
//#define POWER_LOSS_STATE HIGH // State of pin indicating power loss
//#define POWER_LOSS_PIN 44 // Pin to detect power-loss. Set to -1 to disable default pin on boards without module, or comment to use board default.
//#define POWER_LOSS_STATE HIGH // State of pin indicating power-loss
//#define POWER_LOSS_PULLUP // Set pullup / pulldown as appropriate for your sensor
//#define POWER_LOSS_PULLDOWN
//#define POWER_LOSS_PURGE_LEN 20 // (mm) Length of filament to purge on resume
//#define POWER_LOSS_RETRACT_LEN 10 // (mm) Length of filament to retract on fail. Requires backup power.
//#define POWER_LOSS_ZRAISE 2 // (mm) Z axis raise on resume (on power-loss with UPS)
//#define POWER_LOSS_PURGE_LEN 20 // (mm) Length of filament to purge on resume
// Without a POWER_LOSS_PIN the following option helps reduce wear on the SD card,
// especially with "vase mode" printing. Set too high and vases cannot be continued.
#define POWER_LOSS_MIN_Z_CHANGE 0.05 // (mm) Minimum Z change before saving power-loss data
//#define BACKUP_POWER_SUPPLY // Backup power / UPS to move the steppers on power-loss
#if ENABLED(BACKUP_POWER_SUPPLY)
//#define POWER_LOSS_RETRACT_LEN 10 // (mm) Length of filament to retract on fail
#endif
// Enable if Z homing is needed for proper recovery. 99.9% of the time this should be disabled!
//#define POWER_LOSS_RECOVER_ZHOME
#if ENABLED(POWER_LOSS_RECOVER_ZHOME)
@@ -1806,10 +1812,10 @@
// Allow international symbols in long filenames. To display correctly, the
// LCD's font must contain the characters. Check your selected LCD language.
#define UTF_FILENAME_SUPPORT
//#define UTF_FILENAME_SUPPORT
#define LONG_FILENAME_HOST_SUPPORT // Get the long filename of a file/folder with 'M33 <dosname>' and list long filenames with 'M20 L'
//#define LONG_FILENAME_WRITE_SUPPORT // Create / delete files with long filenames via M28, M30, and Binary Transfer Protocol
#define LONG_FILENAME_WRITE_SUPPORT // Create / delete files with long filenames via M28, M30, and Binary Transfer Protocol
//#define M20_TIMESTAMP_SUPPORT // Include timestamps by adding the 'T' flag to M20 commands
#define SCROLL_LONG_FILENAMES // Scroll long filenames in the SD card menu
@@ -1828,7 +1834,7 @@
//#define SD_REPRINT_LAST_SELECTED_FILE // On print completion open the LCD Menu and select the same file
//#define AUTO_REPORT_SD_STATUS // Auto-report media status with 'M27 S<seconds>'
#define AUTO_REPORT_SD_STATUS // Auto-report media status with 'M27 S<seconds>'
/**
* Support for USB thumb drives using an Arduino USB Host Shield or
@@ -1963,17 +1969,6 @@
// Western only. Not available for Cyrillic, Kana, Turkish, Greek, or Chinese.
//#define USE_SMALL_INFOFONT
/**
* Graphical Display Sleep
*
* The U8G library provides sleep / wake functions for SH1106, SSD1306,
* SSD1309, and some other DOGM displays.
* Enable this option to save energy and prevent OLED pixel burn-in.
* Adds the menu item Configuration > LCD Timeout (m) to set a wait period
* from 0 (disabled) to 99 minutes.
*/
//#define DISPLAY_SLEEP_MINUTES 2 // (minutes) Timeout before turning off the screen. Set with M255 S.
/**
* ST7920-based LCDs can emulate a 16 x 4 character display using
* the ST7920 character-generator for very fast screen updates.
@@ -2222,13 +2217,20 @@
//#define TFT_BTOKMENU_COLOR 0x145F // 00010 100010 11111 Cyan
#endif
//
// LCD Backlight Timeout
// Requires a display with a controllable backlight
//
/**
* Display Sleep
* Enable this option to save energy and prevent OLED pixel burn-in.
*/
//#define DISPLAY_SLEEP_MINUTES 2 // (minutes) Timeout before turning off the screen
/**
* LCD Backlight Timeout
* Requires a display with a controllable backlight
*/
//#define LCD_BACKLIGHT_TIMEOUT_MINS 1 // (minutes) Timeout before turning off the backlight
#if defined(DISPLAY_SLEEP_MINUTES) || defined(LCD_BACKLIGHT_TIMEOUT_MINS)
#define EDITABLE_DISPLAY_TIMEOUT // Edit timeout with M255 S<minutes> and a menu item
#define EDITABLE_DISPLAY_TIMEOUT // Edit sleep / backlight timeout with M255 S<minutes> and a menu item
#endif
//
@@ -2271,7 +2273,7 @@
//#define BABYSTEP_XY // Also enable X/Y Babystepping. Not supported on DELTA!
//#define BABYSTEP_INVERT_Z // Enable if Z babysteps should go the other way
//#define BABYSTEP_MILLIMETER_UNITS // Specify BABYSTEP_MULTIPLICATOR_(XY|Z) in mm instead of micro-steps
#define BABYSTEP_MULTIPLICATOR_Z 25 // (steps or mm) Steps or millimeter distance for each Z babystep
#define BABYSTEP_MULTIPLICATOR_Z 1 // (steps or mm) Steps or millimeter distance for each Z babystep
#define BABYSTEP_MULTIPLICATOR_XY 1 // (steps or mm) Steps or millimeter distance for each XY babystep
#define DOUBLECLICK_FOR_Z_BABYSTEPPING // Double-click on the Status Screen for Z Babystepping.
@@ -2289,7 +2291,7 @@
#define BABYSTEP_ZPROBE_OFFSET // Combine M851 Z and Babystepping
#if ENABLED(BABYSTEP_ZPROBE_OFFSET)
//#define BABYSTEP_HOTEND_Z_OFFSET // For multiple hotends, babystep relative Z offsets
//#define BABYSTEP_GFX_OVERLAY // Enable graphical overlay on Z-offset editor
#define BABYSTEP_GFX_OVERLAY // Enable graphical overlay on Z-offset editor
#endif
#endif
@@ -2313,9 +2315,9 @@
#define LIN_ADVANCE
#if ENABLED(LIN_ADVANCE)
#if ENABLED(DISTINCT_E_FACTORS)
#define ADVANCE_K { 0.22 } // (mm) Compression length per 1mm/s extruder speed, per extruder
#define ADVANCE_K { 0.0 } // (mm) Compression length per 1mm/s extruder speed, per extruder
#else
#define ADVANCE_K 0.22 // (mm) Compression length applying to all extruders
#define ADVANCE_K 0.0 // (mm) Compression length applying to all extruders
#endif
//#define ADVANCE_K_EXTRA // Add a second linear advance constant, configurable with M900 L.
//#define LA_DEBUG // Print debug information to serial during operation. Disable for production use.
@@ -2564,7 +2566,7 @@
*
* Override the default value based on the driver type set in Configuration.h.
*/
//#define MINIMUM_STEPPER_PULSE 5
//#define MINIMUM_STEPPER_PULSE 10
/**
* Maximum stepping rate (in Hz) the stepper driver allows
@@ -2595,9 +2597,9 @@
#if ALL(HAS_MEDIA, DIRECT_STEPPING)
#define BLOCK_BUFFER_SIZE 8
#elif HAS_MEDIA
#define BLOCK_BUFFER_SIZE 32
#define BLOCK_BUFFER_SIZE 64
#else
#define BLOCK_BUFFER_SIZE 32
#define BLOCK_BUFFER_SIZE 64
#endif
// @section serial
@@ -2695,7 +2697,7 @@
* This feature is EXPERIMENTAL so use with caution and test thoroughly.
* Enable this option to receive data on the serial ports via the onboard DMA
* controller for more stable and reliable high-speed serial communication.
* Only some STM32 MCUs are currently supported.
* Support is currently limited to some STM32 MCUs and all HC32 MCUs.
* Note: This has no effect on emulated USB serial ports.
*/
//#define SERIAL_DMA
@@ -2766,7 +2768,7 @@
// Z raise distance for tool-change, as needed for some extruders
#define TOOLCHANGE_ZRAISE 2 // (mm)
//#define TOOLCHANGE_ZRAISE_BEFORE_RETRACT // Apply raise before swap retraction (if enabled)
//#define TOOLCHANGE_NO_RETURN // Never return to previous position on tool-change
#define TOOLCHANGE_NO_RETURN // Never return to previous position on tool-change
#if ENABLED(TOOLCHANGE_NO_RETURN)
//#define EVENT_GCODE_AFTER_TOOLCHANGE "G12X" // Extra G-code to run after tool-change
#endif
@@ -2797,10 +2799,10 @@
* Retract and prime filament on tool-change to reduce
* ooze and stringing and to get cleaner transitions.
*/
//#define TOOLCHANGE_FILAMENT_SWAP
#define TOOLCHANGE_FILAMENT_SWAP
#if ENABLED(TOOLCHANGE_FILAMENT_SWAP)
// Load / Unload
#define TOOLCHANGE_FS_LENGTH 12 // (mm) Load / Unload length
#define TOOLCHANGE_FS_LENGTH 4 // (mm) Load / Unload length
#define TOOLCHANGE_FS_EXTRA_RESUME_LENGTH 0 // (mm) Extra length for better restart. Adjust with LCD or M217 B.
#define TOOLCHANGE_FS_RETRACT_SPEED (50*60) // (mm/min) (Unloading)
#define TOOLCHANGE_FS_UNRETRACT_SPEED (25*60) // (mm/min) (On SINGLENOZZLE or Bowden loading must be slowed down)
@@ -2924,11 +2926,11 @@
//#define FILAMENT_CHANGE_RESUME_ON_INSERT // Automatically continue / load filament when runout sensor is triggered again.
//#define PAUSE_REHEAT_FAST_RESUME // Reduce number of waits by not prompting again post-timeout before continuing.
#define PARK_HEAD_ON_PAUSE // Park the nozzle during pause and filament change.
//#define PARK_HEAD_ON_PAUSE // Park the nozzle during pause and filament change.
//#define HOME_BEFORE_FILAMENT_CHANGE // If needed, home before parking for filament change
#define FILAMENT_LOAD_UNLOAD_GCODES // Add M701/M702 Load/Unload G-codes, plus Load/Unload in the LCD Prepare menu.
#define FILAMENT_UNLOAD_ALL_EXTRUDERS // Allow M702 to unload all extruders above a minimum target temp (as set by M302)
//#define FILAMENT_LOAD_UNLOAD_GCODES // Add M701/M702 Load/Unload G-codes, plus Load/Unload in the LCD Prepare menu.
//#define FILAMENT_UNLOAD_ALL_EXTRUDERS // Allow M702 to unload all extruders above a minimum target temp (as set by M302)
#define CONFIGURE_FILAMENT_CHANGE // Add M603 G-code and menu items. Requires ~1.3K bytes of flash.
#endif
@@ -2950,17 +2952,14 @@
* Some boards have simple jumper connections! See your board's documentation.
* - These drivers can also be used with Hardware Serial.
*
* The TMC26XStepper library is required for TMC26X stepper drivers.
* https://github.com/MarlinFirmware/TMC26XStepper
*
* The TMCStepper library is required for other TMC stepper drivers.
* https://github.com/teemuatlut/TMCStepper
*
* @section tmc/config
*/
#if HAS_TRINAMIC_CONFIG || HAS_TMC26X
#if HAS_TRINAMIC_CONFIG
#define HOLD_MULTIPLIER 0.7 // Scales down the holding current from run current
#define HOLD_MULTIPLIER 0.25 // Scales down the holding current from run current
/**
* Interpolate microsteps to 256
@@ -2969,7 +2968,7 @@
#define INTERPOLATE true
#if AXIS_IS_TMC_CONFIG(X)
#define X_CURRENT 800 // (mA) RMS current. Multiply by 1.414 for peak current.
#define X_CURRENT 1800 // (mA) RMS current. Multiply by 1.414 for peak current.
#define X_CURRENT_HOME X_CURRENT // (mA) RMS current for sensorless homing
#define X_MICROSTEPS 16 // 0..256
#define X_RSENSE 0.022 // Multiplied x1000 for TMC26X
@@ -2989,7 +2988,7 @@
#endif
#if AXIS_IS_TMC_CONFIG(Y)
#define Y_CURRENT 800
#define Y_CURRENT 1800
#define Y_CURRENT_HOME Y_CURRENT
#define Y_MICROSTEPS 16
#define Y_RSENSE 0.022
@@ -3009,7 +3008,7 @@
#endif
#if AXIS_IS_TMC_CONFIG(Z)
#define Z_CURRENT 800
#define Z_CURRENT 1800
#define Z_CURRENT_HOME Z_CURRENT
#define Z_MICROSTEPS 16
#define Z_RSENSE 0.11
@@ -3109,7 +3108,7 @@
#endif
#if AXIS_IS_TMC_CONFIG(E0)
#define E0_CURRENT 900
#define E0_CURRENT 800
#define E0_MICROSTEPS 16
#define E0_RSENSE 0.11
#define E0_CHAIN_POS -1
@@ -3214,7 +3213,7 @@
* The default SW SPI pins are defined the respective pins files,
* but you can override or define them here.
*/
#define TMC_USE_SW_SPI
//#define TMC_USE_SW_SPI
//#define TMC_SPI_MOSI -1
//#define TMC_SPI_MISO -1
//#define TMC_SPI_SCK -1
@@ -3274,7 +3273,7 @@
* When disabled, Marlin will use spreadCycle stepping mode.
*/
#if HAS_STEALTHCHOP
//#define STEALTHCHOP_XY
#define STEALTHCHOP_XY
#define STEALTHCHOP_Z
#define STEALTHCHOP_I
#define STEALTHCHOP_J
@@ -3300,11 +3299,11 @@
* Define your own with:
* { <off_time[1..15]>, <hysteresis_end[-3..12]>, hysteresis_start[1..8] }
*/
//#define CHOPPER_TIMING CHOPPER_DEFAULT_36V // All axes (override below)
#define CHOPPER_TIMING_X CHOPPER_DEFAULT_36V // For X Axes (override below)
#define CHOPPER_TIMING CHOPPER_DEFAULT_24V // All axes (override below)
//#define CHOPPER_TIMING_X CHOPPER_DEFAULT_36V // For X Axes (override below)
//#define CHOPPER_TIMING_X2 CHOPPER_TIMING_X
#define CHOPPER_TIMING_Y CHOPPER_DEFAULT_36V // For Y Axes (override below)
#define CHOPPER_TIMING_Y2 CHOPPER_TIMING_Y
//#define CHOPPER_TIMING_Y CHOPPER_DEFAULT_36V // For Y Axes (override below)
//#define CHOPPER_TIMING_Y2 CHOPPER_TIMING_Y
//#define CHOPPER_TIMING_Z CHOPPER_TIMING // For Z Axes (override below)
//#define CHOPPER_TIMING_Z2 CHOPPER_TIMING_Z
//#define CHOPPER_TIMING_Z3 CHOPPER_TIMING_Z
@@ -3315,7 +3314,7 @@
//#define CHOPPER_TIMING_U CHOPPER_TIMING // For U Axis
//#define CHOPPER_TIMING_V CHOPPER_TIMING // For V Axis
//#define CHOPPER_TIMING_W CHOPPER_TIMING // For W Axis
#define CHOPPER_TIMING_E CHOPPER_DEFAULT_24V // For Extruders (override below)
//#define CHOPPER_TIMING_E CHOPPER_DEFAULT_24V // For Extruders (override below)
//#define CHOPPER_TIMING_E1 CHOPPER_TIMING_E
//#define CHOPPER_TIMING_E2 CHOPPER_TIMING_E
//#define CHOPPER_TIMING_E3 CHOPPER_TIMING_E
@@ -3405,12 +3404,12 @@
* Comment *_STALL_SENSITIVITY to disable sensorless homing for that axis.
* @section tmc/stallguard
*/
//#define SENSORLESS_HOMING // StallGuard capable drivers only
#define SENSORLESS_HOMING // StallGuard capable drivers only
#if ANY(SENSORLESS_HOMING, SENSORLESS_PROBING)
// TMC2209: 0...255. TMC2130: -64...63
#define X_STALL_SENSITIVITY 8
#define X2_STALL_SENSITIVITY X_STALL_SENSITIVITY
//#define X_STALL_SENSITIVITY 8
//#define X2_STALL_SENSITIVITY X_STALL_SENSITIVITY
#define Y_STALL_SENSITIVITY 8
#define Y2_STALL_SENSITIVITY Y_STALL_SENSITIVITY
//#define Z_STALL_SENSITIVITY 8
@@ -3444,13 +3443,13 @@
/**
* Step on both rising and falling edge signals (as with a square wave).
*/
#define EDGE_STEPPING
//#define EDGE_STEPPING
/**
* Enable M122 debugging command for TMC stepper drivers.
* M122 S0/1 will enable continuous reporting.
*/
//#define TMC_DEBUG
#define TMC_DEBUG
/**
* You can set your own advanced settings by filling in predefined functions.
@@ -3465,7 +3464,7 @@
*/
#define TMC_ADV() { }
#endif // HAS_TRINAMIC_CONFIG || HAS_TMC26X
#endif // HAS_TRINAMIC_CONFIG
// @section i2cbus
@@ -3558,7 +3557,7 @@
* Add the M3, M4, and M5 commands to turn the spindle/laser on and off, and
* to set spindle speed, spindle direction, and laser power.
*
* SuperPid is a router/spindle speed controller used in the CNC milling community.
* SuperPID is a router/spindle speed controller used in the CNC milling community.
* Marlin can be used to turn the spindle on and off. It can also be used to set
* the spindle speed from 5,000 to 30,000 RPM.
*
@@ -4115,7 +4114,7 @@
*/
#define HOST_ACTION_COMMANDS
#if ENABLED(HOST_ACTION_COMMANDS)
//#define HOST_PAUSE_M76 // Tell the host to pause in response to M76
#define HOST_PAUSE_M76 // Tell the host to pause in response to M76
#define HOST_PROMPT_SUPPORT // Initiate host prompts to get user feedback
#if ENABLED(HOST_PROMPT_SUPPORT)
#define HOST_STATUS_NOTIFICATIONS // Send some status messages to the host as notifications
@@ -4261,7 +4260,8 @@
/**
* Instant freeze / unfreeze functionality
* Potentially useful for emergency stop that allows being resumed.
* Potentially useful for rapid stop that allows being resumed. Halts stepper movement.
* Note this does NOT pause spindles, lasers, fans, heaters or any other auxiliary device.
* @section interface
*/
//#define FREEZE_FEATURE
@@ -4308,6 +4308,7 @@
// See class CodeProfiler.
//#define MAX7219_DEBUG_MULTISTEPPING 6 // Show multi-stepping 1 to 128 on this LED matrix row.
//#define MAX7219_DEBUG_SLOWDOWN 6 // Count (mod 16) how many times SLOWDOWN has reduced print speed.
//#define MAX7219_REINIT_ON_POWERUP // Re-initialize MAX7129 when power supply turns on
#endif
/**
@@ -4341,7 +4342,7 @@
* Extras for an ESP32-based motherboard with WIFISUPPORT
* These options don't apply to add-on WiFi modules based on ESP32 WiFi101.
*/
#if ENABLED(WIFISUPPORT)
#if ANY(WIFISUPPORT, ESP3D_WIFISUPPORT)
//#define WEBSUPPORT // Start a webserver (which may include auto-discovery) using SPIFFS
//#define OTASUPPORT // Support over-the-air firmware updates
//#define WIFI_CUSTOM_COMMAND // Accept feature config commands (e.g., WiFi ESP3D) from the host
@@ -4488,7 +4489,7 @@
//
// M42 - Set pin states
//
#define DIRECT_PIN_CONTROL
//#define DIRECT_PIN_CONTROL
//
// M43 - display pin status, toggle pins, watch pins, watch endstops & toggle LED, test servo probe
@@ -4524,3 +4525,6 @@
// Report uncleaned reset reason from register r2 instead of MCUSR. Supported by Optiboot on AVR.
//#define OPTIBOOT_RESET_REASON
// Shrink the build for smaller boards by sacrificing some serial feedback
//#define MARLIN_SMALL_BUILD
+1 -1
View File
@@ -41,7 +41,7 @@
* here we define this default string as the date where the latest release
* version was tagged.
*/
//#define STRING_DISTRIBUTION_DATE "2024-05-27"
//#define STRING_DISTRIBUTION_DATE "2024-05-24"
/**
* Defines a generic printer name to be output to the LCD after booting Marlin.
+2 -1
View File
@@ -53,11 +53,12 @@ typedef uint64_t hal_timer_t;
#if ENABLED(I2S_STEPPER_STREAM)
#define STEPPER_TIMER_PRESCALE 1
#define STEPPER_TIMER_RATE 250000 // 250khz, 4µs pulses of i2s word clock
#define STEPPER_TIMER_TICKS_PER_US ((STEPPER_TIMER_RATE) / 1000000) // stepper timer ticks per µs // wrong would be 0.25
#else
#define STEPPER_TIMER_PRESCALE 40
#define STEPPER_TIMER_RATE ((HAL_TIMER_RATE) / (STEPPER_TIMER_PRESCALE)) // frequency of stepper timer, 2MHz
#define STEPPER_TIMER_TICKS_PER_US ((STEPPER_TIMER_RATE) / 1000000) // stepper timer ticks per µs
#endif
#define STEPPER_TIMER_TICKS_PER_US ((STEPPER_TIMER_RATE) / 1000000) // stepper timer ticks per µs
#define STEP_TIMER_MIN_INTERVAL 8 // minimum time in µs between stepper interrupts
+3 -25
View File
@@ -165,13 +165,14 @@
// * @brief Wait until TXE (tx empty) flag is set and BSY (busy) flag unset.
// */
static inline void waitSpiTxEnd(void *spi_d) {
#warning unimplemented
// while (SSP_GetStatus(spi_d, SSP_STAT_TXFIFO_EMPTY) == RESET) { /* nada */ } // wait until TXE=1
// while (SSP_GetStatus(spi_d, SSP_STAT_BUSY) == SET) { /* nada */ } // wait until BSY=0
}
// // Retain the pin init state of the SPI, to avoid init more than once,
// // even if more instances of SPIClass exist
static bool spiInitialised[BOARD_NR_SPI] = {};
static bool spiInitialised[BOARD_NR_SPI] = { false };
SPIClass::SPIClass(uint8_t device) {
// // Init things specific to each SPI device
@@ -183,12 +184,6 @@ SPIClass::SPIClass(uint8_t device) {
_settings[0].m_config.pin_mosi = BOARD_SPI1_MOSI_PIN;
_settings[0].m_config.pin_sck = BOARD_SPI1_SCK_PIN;
_settings[0].m_config.pin_ssel = BOARD_SPI1_NSS_PIN;
_settings[0].m_config.frequency = 100000;
_settings[0].m_config.data_bits = 8;
_settings[0].m_config.mode = 0;
_settings[0].m_config.format = MCUI::SSP::Config::Format::SPI;
// _settings[0].dataMode = SPI_MODE0;
// _settings[0].dataSize = DATA_SIZE_8BIT;
// _settings[0].clock = SPI_CLOCK_MAX;
@@ -207,18 +202,6 @@ SPIClass::SPIClass(uint8_t device) {
// //_settings[1].clockDivider = determine_baud_rate(_settings[1].spi_d, _settings[1].clock);
#endif
#if BOARD_NR_SPI >= 3
_settings[2].device_id = 1;
_settings[2].m_config.pin_miso = BOARD_SPI3_MISO_PIN;
_settings[2].m_config.pin_mosi = BOARD_SPI3_MOSI_PIN;
_settings[2].m_config.pin_sck = BOARD_SPI3_SCK_PIN;
_settings[2].m_config.pin_ssel = BOARD_SPI3_NSS_PIN;
// _settings[1].dataMode = SPI_MODE0;
// _settings[1].dataSize = DATA_SIZE_8BIT;
// _settings[1].clock = SPI_CLOCK_MAX;
// //_settings[1].clockDivider = determine_baud_rate(_settings[1].spi_d, _settings[1].clock);
#endif
setModule(device);
// // Init the GPDMA controller
@@ -233,9 +216,6 @@ SPIClass::SPIClass(pin_t mosi, pin_t miso, pin_t sclk, pin_t ssel) {
#if BOARD_NR_SPI >= 2
if (mosi == BOARD_SPI2_MOSI_PIN) SPIClass(2);
#endif
#if BOARD_NR_SPI >= 3
if (mosi == BOARD_SPI3_MOSI_PIN) SPIClass(3);
#endif
}
void SPIClass::begin() {
@@ -361,9 +341,7 @@ void SPIClass::setDataSize(uint32_t dataSize) { _currentSetting->dataSize = data
// /**
// * Set up/tear down
// */
void SPIClass::updateSettings() {
MCUI::SSP::configure(_currentSetting->device_id, _currentSetting->m_config);
}
void SPIClass::updateSettings() { }
SPIClass SPI(1);
-2
View File
@@ -120,8 +120,6 @@ private:
bitOrder = inBitOrder;
dataMode = inDataMode;
dataSize = inDataSize;
m_config = {};
m_config.frequency = 400000;
}
MCUI::SSP::Config m_config;
@@ -132,7 +132,7 @@ uint8_t swSpiTransfer_mode_3(uint8_t b, const uint8_t spi_speed, const pin_t sck
static uint8_t SPI_speed = 0;
static void u8g_sw_spi_HAL_LPC1768_shift_out(uint8_t dataPin, uint8_t clockPin, uint8_t val) {
#if ANY(FYSETC_MINI_12864, MKS_MINI_12864)
#if EITHER(FYSETC_MINI_12864, MKS_MINI_12864)
swSpiTransfer_mode_3(val, SPI_speed, clockPin, -1, dataPin);
#else
swSpiTransfer_mode_0(val, SPI_speed, clockPin, -1, dataPin);
@@ -160,7 +160,7 @@ uint8_t u8g_com_HAL_LPC1768_sw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val,
break;
case U8G_COM_MSG_CHIP_SELECT:
#if ANY(FYSETC_MINI_12864, MKS_MINI_12864) // LCD SPI is running mode 3 while SD card is running mode 0
#if EITHER(FYSETC_MINI_12864, MKS_MINI_12864) // LCD SPI is running mode 3 while SD card is running mode 0
if (arg_val) { // SCK idle state needs to be set to the proper idle state before
// the next chip select goes active
u8g_SetPILevel(u8g, U8G_PI_SCK, 1); // Set SCK to mode 3 idle state before CS goes active
+1 -1
View File
@@ -41,7 +41,7 @@ typedef uint32_t hal_timer_t;
#define FTM0_TIMER_PRESCALE_BITS 0b011
#define FTM1_TIMER_PRESCALE_BITS 0b010
#define FTM0_TIMER_RATE (F_BUS / (FTM0_TIMER_PRESCALE)) // 60MHz / 8 = 7.5MHz
#define FTM0_TIMER_RATE (F_BUS / (FTM0_TIMER_PRESCALE)) // 60MHz / 8 = 7500kHz
#define FTM1_TIMER_RATE (F_BUS / (FTM1_TIMER_PRESCALE)) // 60MHz / 4 = 15MHz
#define HAL_TIMER_RATE (FTM0_TIMER_RATE)
+1 -1
View File
@@ -89,7 +89,7 @@
#define HYPOT2(x,y) (sq(x)+sq(y))
#define NORMSQ(x,y,z) (sq(x)+sq(y)+sq(z))
#define FLOAT_SQ(I) float(sq(I))
#define FLOAT_SQ(I) sq(float(I))
#define CIRCLE_AREA(R) (float(M_PI) * FLOAT_SQ(R))
#define CIRCLE_CIRC(R) (2 * float(M_PI) * float(R))
-4
View File
@@ -1105,10 +1105,6 @@ void GcodeSuite::process_parsed_command(const bool no_ok/*=false*/) {
case 1002: M1002(); break; // M1002: [INTERNAL] Tool-change and Relative E Move
#endif
#if ENABLED(ONE_CLICK_PRINT)
case 1003: M1003(); break; // M1003: [INTERNAL] Set the current dir to /
#endif
#if ENABLED(UBL_MESH_WIZARD)
case 1004: M1004(); break; // M1004: UBL Mesh Wizard
#endif
-4
View File
@@ -1276,10 +1276,6 @@ private:
static void M1002();
#endif
#if ENABLED(ONE_CLICK_PRINT)
static void M1003();
#endif
#if ENABLED(UBL_MESH_WIZARD)
static void M1004();
#endif
-36
View File
@@ -1,36 +0,0 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2024 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
#include "../../inc/MarlinConfig.h"
#if ENABLED(ONE_CLICK_PRINT)
#include "../gcode.h"
#include "../../sd/cardreader.h"
/**
* M1003: Set the current dir to /. Should come after 'M24'.
* Prevents the SD menu getting stuck in the newest file's workDir.
*/
void GcodeSuite::M1003() { card.cdroot(); }
#endif // ONE_CLICK_PRINT
+5 -5
View File
@@ -1842,8 +1842,8 @@ static_assert(NUM_SERVOS <= NUM_SERVO_PLUGS, "NUM_SERVOS (or some servo index) i
#if ENABLED(DUAL_X_CARRIAGE)
#if EXTRUDERS < 2
#error "DUAL_X_CARRIAGE requires 2 (or more) extruders."
#elif ANY(CORE_IS_XY, CORE_IS_XZ, MARKFORGED_XY, MARKFORGED_YX)
#error "DUAL_X_CARRIAGE cannot be used with COREXY, COREYX, COREXZ, COREZX, MARKFORGED_YX, or MARKFORGED_XY."
//#elif ANY(CORE_IS_XY, CORE_IS_XZ, MARKFORGED_XY, MARKFORGED_YX)
//#error "DUAL_X_CARRIAGE cannot be used with COREXY, COREYX, COREXZ, COREZX, MARKFORGED_YX, or MARKFORGED_XY."
#elif !GOOD_AXIS_PINS(X2)
#error "DUAL_X_CARRIAGE requires X2 stepper pins to be defined."
#elif !USE_X_MAX
@@ -3217,7 +3217,7 @@ static_assert(NUM_SERVOS <= NUM_SERVO_PLUGS, "NUM_SERVOS (or some servo index) i
#endif
#elif Y_HOME_TO_MAX && Y_MAX_ENDSTOP_HIT_STATE != _HIT_STATE
#if _HIT_STATE
#error "SENSORLESS_HOMING requires Y_MAX_ENDSTOP_HIT_STATE HIGH for Y MAX homing with TMC2209."
//#error "SENSORLESS_HOMING requires Y_MAX_ENDSTOP_HIT_STATE HIGH for Y MAX homing with TMC2209."
#else
#error "SENSORLESS_HOMING requires Y_MAX_ENDSTOP_HIT_STATE LOW for Y MAX homing."
#endif
@@ -3383,8 +3383,8 @@ static_assert(NUM_SERVOS <= NUM_SERVO_PLUGS, "NUM_SERVOS (or some servo index) i
#error "CoreXZ requires both X and Z to use sensorless homing if either one does."
#elif CORE_IS_YZ && Y_SENSORLESS != Z_SENSORLESS && !HOMING_Z_WITH_PROBE
#error "CoreYZ requires both Y and Z to use sensorless homing if either one does."
#elif ANY(MARKFORGED_XY, MARKFORGED_YX) && X_SENSORLESS != Y_SENSORLESS
#error "MARKFORGED requires both X and Y to use sensorless homing if either one does."
//#elif ANY(MARKFORGED_XY, MARKFORGED_YX) && X_SENSORLESS != Y_SENSORLESS
//#error "MARKFORGED requires both X and Y to use sensorless homing if either one does."
#endif
// TMC Hybrid Threshold
+1 -1
View File
@@ -42,7 +42,7 @@
* version was tagged.
*/
#ifndef STRING_DISTRIBUTION_DATE
#define STRING_DISTRIBUTION_DATE "2024-05-27"
#define STRING_DISTRIBUTION_DATE "2024-05-24"
#endif
/**
+1 -1
View File
@@ -1343,7 +1343,7 @@ void MarlinUI::draw_status_screen() {
void MenuItem_sdbase::draw(const bool sel, const uint8_t row, FSTR_P const, CardReader &theCard, const bool isDir) {
lcd_put_lchar(0, row, sel ? LCD_STR_ARROW_RIGHT[0] : ' ');
uint8_t n = LCD_WIDTH - 2;
n -= lcd_put_u8str_max(ui.scrolled_filename(theCard, n, sel), n);
n -= lcd_put_u8str_max(ui.scrolled_filename(theCard, n, row, sel), n);
for (; n; --n) lcd_put_u8str(F(" "));
lcd_put_lchar(isDir ? LCD_STR_FOLDER[0] : ' ');
}
+1 -1
View File
@@ -1086,7 +1086,7 @@ void MarlinUI::draw_status_screen() {
lcd_moveto(0, row);
lcd.write(sel ? LCD_STR_ARROW_RIGHT[0] : ' ');
uint8_t n = LCD_WIDTH - 2;
n -= lcd_put_u8str_max(ui.scrolled_filename(theCard, n, sel), n);
n -= lcd_put_u8str_max(ui.scrolled_filename(theCard, n, row, sel), n);
for (; n; --n) lcd.write(' ');
lcd.write(isDir ? LCD_STR_FOLDER[0] : ' ');
lcd.print_line();
+1 -1
View File
@@ -606,7 +606,7 @@ void MarlinUI::clear_lcd() { } // Automatically cleared by Picture Loop
const uint8_t maxlen = LCD_WIDTH - isDir;
if (isDir) lcd_put_lchar(LCD_STR_FOLDER[0]);
const pixel_len_t pixw = maxlen * (MENU_FONT_WIDTH);
pixel_len_t n = pixw - lcd_put_u8str_max(ui.scrolled_filename(theCard, maxlen, sel), pixw);
pixel_len_t n = pixw - lcd_put_u8str_max(ui.scrolled_filename(theCard, maxlen, row, sel), pixw);
for (; n > MENU_FONT_WIDTH; n -= MENU_FONT_WIDTH) lcd_put_u8str(F(" "));
}
+1 -1
View File
@@ -487,7 +487,7 @@ void MarlinUI::draw_status_message(const bool blink) {
maxlen -= 2;
}
dwin_string.add(ui.scrolled_filename(theCard, maxlen, sel), maxlen);
dwin_string.add(ui.scrolled_filename(theCard, maxlen, row, sel), maxlen);
uint8_t n = maxlen - dwin_string.length;
while (n > 0) { dwin_string.add(' '); --n; }
lcd_moveto(1, row);
+26 -23
View File
@@ -357,21 +357,25 @@ void MarlinUI::init() {
#if HAS_MEDIA
#if MARLINUI_SCROLL_NAME
static uint8_t filename_scroll_pos, filename_scroll_max;
uint8_t MarlinUI::filename_scroll_pos, MarlinUI::filename_scroll_max;
#endif
const char * MarlinUI::scrolled_filename(CardReader &theCard, const uint8_t maxlen, const bool doScroll) {
const char * MarlinUI::scrolled_filename(CardReader &theCard, const uint8_t maxlen, uint8_t hash, const bool doScroll) {
const char *outstr = theCard.longest_filename();
if (theCard.longFilename[0]) {
#if MARLINUI_SCROLL_NAME
if (doScroll) {
filename_scroll_max = _MAX(0, utf8_strlen(theCard.longFilename) - maxlen);
if (filename_scroll_max) {
// Ensure filename_scroll_pos isn't out of bounds even though it should never happen.
if (filename_scroll_pos > filename_scroll_max) filename_scroll_pos = 0;
// Advance byte position corresponding to filename_scroll_pos char position
outstr += TERN(UTF_FILENAME_SUPPORT, utf8_byte_pos_by_char_num(outstr, filename_scroll_pos), filename_scroll_pos);
for (uint8_t l = FILENAME_LENGTH; l--;)
hash = ((hash << 1) | (hash >> 7)) ^ theCard.filename[l]; // rotate, xor
static uint8_t filename_scroll_hash;
if (filename_scroll_hash != hash) { // If the hash changed...
filename_scroll_hash = hash; // Save the new hash
filename_scroll_max = _MAX(0, utf8_strlen(theCard.longFilename) - maxlen); // Update the scroll limit
filename_scroll_pos = 0; // Reset scroll to the start
lcd_status_update_delay = 8; // Don't scroll right away
}
// Advance byte position corresponding to filename_scroll_pos char position
outstr += TERN(UTF_FILENAME_SUPPORT, utf8_byte_pos_by_char_num(outstr, filename_scroll_pos), filename_scroll_pos);
}
#else
theCard.longFilename[
@@ -999,19 +1003,22 @@ void MarlinUI::init() {
#endif // HAS_MARLINUI_MENU
const bool lcd_update_ms_elapsed = ELAPSED(ms, next_lcd_update_ms);
if (lcd_update_ms_elapsed) {
if (ELAPSED(ms, next_lcd_update_ms) || TERN0(HAS_MARLINUI_U8GLIB, drawing_screen)) {
next_lcd_update_ms = ms + LCD_UPDATE_INTERVAL;
#if HAS_TOUCH_BUTTONS
if (on_status_screen()) next_lcd_update_ms += (LCD_UPDATE_INTERVAL) * 2;
TERN_(HAS_ENCODER_ACTION, touch_buttons = touchBt.read_buttons());
#endif
TERN_(LCD_HAS_STATUS_INDICATORS, update_indicators());
#if HAS_ENCODER_ACTION
TERN_(HAS_SLOW_BUTTONS, slow_buttons = read_slow_buttons()); // Buttons that take too long to read in interrupt context
if (TERN0(IS_RRW_KEYPAD, handle_keypad()))
@@ -1076,17 +1083,12 @@ void MarlinUI::init() {
#endif
refresh(LCDVIEW_REDRAW_NOW);
TERN_(HAS_MARLINUI_U8GLIB, drawing_screen = false);
#if MARLINUI_SCROLL_NAME
filename_scroll_max = 0;
filename_scroll_pos = 0;
lcd_status_update_delay = 9;
#endif
#if LED_POWEROFF_TIMEOUT > 0
if (!powerManager.psu_on) leds.reset_timeout(ms);
#endif
} // encoder activity
#endif // HAS_ENCODER_ACTION
// This runs every ~100ms when idling often enough.
@@ -1095,23 +1097,19 @@ void MarlinUI::init() {
lcd_status_update_delay = TERN(HAS_MARLINUI_U8GLIB, 12, 9);
if (max_display_update_time) max_display_update_time--; // Be sure never go to a very big number
refresh(LCDVIEW_REDRAW_NOW);
TERN_(HAS_MARLINUI_U8GLIB, drawing_screen = false);
}
#if MARLINUI_SCROLL_NAME
#if ALL(HAS_MARLINUI_MENU, SCROLL_LONG_FILENAMES)
// If scrolling of long file names is enabled and we are in the sd card menu,
// cause a refresh to occur until all the text has scrolled into view.
if (currentScreen == menu_media && filename_scroll_max && !lcd_status_update_delay--) {
if (currentScreen == menu_media && !lcd_status_update_delay--) {
lcd_status_update_delay = ++filename_scroll_pos >= filename_scroll_max ? 12 : 4; // Long delay at end and start
if (filename_scroll_pos > filename_scroll_max) filename_scroll_pos = 0;
refresh(LCDVIEW_REDRAW_NOW);
TERN_(HAS_MARLINUI_U8GLIB, drawing_screen = false);
reset_status_timeout(ms);
}
#endif
}
if (lcd_update_ms_elapsed || drawing_screen) {
// Then we want to use only 50% of the time
const uint16_t bbr2 = planner.block_buffer_runtime() >> 1;
@@ -1133,6 +1131,7 @@ void MarlinUI::init() {
TERN_(HAS_ADC_BUTTONS, keypad_buttons = 0);
#if HAS_MARLINUI_U8GLIB
#if ENABLED(LIGHTWEIGHT_UI)
const bool in_status = on_status_screen(),
do_u8g_loop = !in_status;
@@ -1161,11 +1160,14 @@ void MarlinUI::init() {
return;
}
}
#else
run_current_screen();
// Apply all DWIN drawing after processing
TERN_(IS_DWIN_MARLINUI, dwinUpdateLCD());
#endif
TERN_(HAS_MARLINUI_MENU, lcd_clicked = false);
@@ -1210,7 +1212,8 @@ void MarlinUI::init() {
case LCDVIEW_CALL_NO_REDRAW:
default: break;
} // switch
}
} // ELAPSED(ms, next_lcd_update_ms)
TERN_(HAS_GRAPHICAL_TFT, tft_idle());
}
+4 -1
View File
@@ -644,7 +644,10 @@ public:
#if ALL(SCROLL_LONG_FILENAMES, HAS_MARLINUI_MENU)
#define MARLINUI_SCROLL_NAME 1
#endif
static const char * scrolled_filename(CardReader &theCard, const uint8_t maxlen, const bool doScroll);
#if MARLINUI_SCROLL_NAME
static uint8_t filename_scroll_pos, filename_scroll_max;
#endif
static const char * scrolled_filename(CardReader &theCard, const uint8_t maxlen, uint8_t hash, const bool doScroll);
#endif
#if HAS_PREHEAT
+7 -7
View File
@@ -523,12 +523,12 @@ void menu_backlash();
// M204 T Travel Acceleration
EDIT_ITEM_FAST(float5_25, MSG_A_TRAVEL, &planner.settings.travel_acceleration, 25, max_accel);
//#define EDIT_AMAX(Q,L) EDIT_ITEM_FAST_N(long5_25, _AXIS(Q), MSG_AMAX_N, &planner.settings.max_acceleration_mm_per_s2[_AXIS(Q)], L, max_accel_edit_scaled[_AXIS(Q)], []{ planner.refresh_acceleration_rates(); })
//NUM_AXIS_CODE(
// EDIT_AMAX(A, 100), EDIT_AMAX(B, 100), EDIT_AMAX(C, 10),
// EDIT_AMAX(I, 10), EDIT_AMAX(J, 10), EDIT_AMAX(K, 10),
// EDIT_AMAX(U, 10), EDIT_AMAX(V, 10), EDIT_AMAX(W, 10)
//);
#define EDIT_AMAX(Q,L) EDIT_ITEM_FAST_N(long5_25, _AXIS(Q), MSG_AMAX_N, &planner.settings.max_acceleration_mm_per_s2[_AXIS(Q)], L, max_accel_edit_scaled[_AXIS(Q)], []{ planner.refresh_acceleration_rates(); })
NUM_AXIS_CODE(
EDIT_AMAX(A, 100), EDIT_AMAX(B, 100), EDIT_AMAX(C, 10),
EDIT_AMAX(I, 10), EDIT_AMAX(J, 10), EDIT_AMAX(K, 10),
EDIT_AMAX(U, 10), EDIT_AMAX(V, 10), EDIT_AMAX(W, 10)
);
#if ENABLED(DISTINCT_E_FACTORS)
EDIT_ITEM_FAST(long5_25, MSG_AMAX_E, &planner.settings.max_acceleration_mm_per_s2[E_AXIS_N(active_extruder)], 100, max_accel_edit_scaled.e, []{ planner.refresh_acceleration_rates(); });
@@ -538,7 +538,7 @@ void menu_backlash();
planner.refresh_acceleration_rates();
});
#elif E_STEPPERS
//EDIT_ITEM_FAST(long5_25, MSG_AMAX_E, &planner.settings.max_acceleration_mm_per_s2[E_AXIS], 100, max_accel_edit_scaled.e, []{ planner.refresh_acceleration_rates(); });
EDIT_ITEM_FAST(long5_25, MSG_AMAX_E, &planner.settings.max_acceleration_mm_per_s2[E_AXIS], 100, max_accel_edit_scaled.e, []{ planner.refresh_acceleration_rates(); });
#endif
#ifdef XY_FREQUENCY_LIMIT
+3 -10
View File
@@ -25,13 +25,6 @@
#if ENABLED(ONE_CLICK_PRINT)
#include "menu.h"
#include "../../gcode/queue.h"
static void one_click_print_done() {
ui.return_to_status();
ui.reset_status();
queue.enqueue_one_now(F("M1003")); // Make sure SD card browsing doesn't break!
}
void one_click_print() {
ui.goto_screen([]{
@@ -40,9 +33,9 @@ void one_click_print() {
GET_TEXT_F(MSG_BUTTON_PRINT), GET_TEXT_F(MSG_BUTTON_CANCEL),
[]{
card.openAndPrintFile(card.filename);
one_click_print_done();
},
one_click_print_done,
ui.return_to_status();
ui.reset_status();
}, nullptr,
GET_TEXT_F(MSG_START_PRINT), filename, F("?")
);
});
+1 -1
View File
@@ -386,7 +386,7 @@ void MenuItem_static::draw(const uint8_t row, FSTR_P const ftpl, const uint8_t s
menu_item(row, sel);
if (isDir) tft.add_image(MENU_ITEM_ICON_X, MENU_ITEM_ICON_Y, imgDirectory, COLOR_MENU_TEXT, sel ? COLOR_SELECTION_BG : COLOR_BACKGROUND);
uint8_t maxlen = (MENU_ITEM_HEIGHT) - (MENU_TEXT_Y) + 1;
tft.add_text(MENU_ITEM_ICON_SPACE, MENU_TEXT_Y, COLOR_MENU_TEXT, ui.scrolled_filename(theCard, maxlen, sel));
tft.add_text(MENU_ITEM_ICON_SPACE, MENU_TEXT_Y, COLOR_MENU_TEXT, ui.scrolled_filename(theCard, maxlen, row, sel));
}
#endif
+249 -166
View File
@@ -128,6 +128,7 @@ Planner planner;
block_t Planner::block_buffer[BLOCK_BUFFER_SIZE];
volatile uint8_t Planner::block_buffer_head, // Index of the next block to be pushed
Planner::block_buffer_nonbusy, // Index of the first non-busy block
Planner::block_buffer_planned, // Index of the optimally planned block
Planner::block_buffer_tail; // Index of the busy block, if any
uint16_t Planner::cleaning_buffer_counter; // A counter to disable queuing of blocks
uint8_t Planner::delay_before_delivering; // Delay block delivery so initial blocks in an empty queue may merge
@@ -149,7 +150,7 @@ planner_settings_t Planner::settings; // Initialized by settings.load(
const uint8_t laser_power_floor = cutter.pct_to_ocr(SPEED_POWER_MIN);
#endif
uint64_t Planner::max_acceleration_steps_per_s2[DISTINCT_AXES]; // (steps/s^2) Derived from mm_per_s2
uint32_t Planner::max_acceleration_steps_per_s2[DISTINCT_AXES]; // (steps/s^2) Derived from mm_per_s2
#if HAS_JUNCTION_DEVIATION
float Planner::junction_deviation_mm; // (mm) M205 J
@@ -169,7 +170,7 @@ uint64_t Planner::max_acceleration_steps_per_s2[DISTINCT_AXES]; // (steps/s^2) D
#endif
#if ENABLED(DIRECT_STEPPING)
uint64_t Planner::last_page_step_rate = 0;
uint32_t Planner::last_page_step_rate = 0;
AxisBits Planner::last_page_dir; // = 0
#endif
@@ -219,7 +220,7 @@ uint64_t Planner::max_acceleration_steps_per_s2[DISTINCT_AXES]; // (steps/s^2) D
xyze_long_t Planner::position{0};
uint64_t Planner::acceleration_long_cutoff;
uint32_t Planner::acceleration_long_cutoff;
xyze_float_t Planner::previous_speed;
float Planner::previous_nominal_speed;
@@ -247,7 +248,7 @@ float Planner::previous_nominal_speed;
#endif
#if HAS_WIRED_LCD
volatile uint64_t Planner::block_buffer_runtime_us = 0;
volatile uint32_t Planner::block_buffer_runtime_us = 0;
#endif
/**
@@ -337,7 +338,7 @@ void Planner::init() {
* // Compute initial estimation of 0x1000000/x -
* // Get most significant bit set on divider
* uint8_t idx = 0;
* uint64_t nr = d;
* uint32_t nr = d;
* if (!(nr & 0xFF0000)) {
* nr <<= 8; idx += 8;
* if (!(nr & 0xFF0000)) { nr <<= 8; idx += 8; }
@@ -347,16 +348,16 @@ void Planner::init() {
* if (!(nr & 0x800000)) { nr <<= 1; idx += 1; }
*
* // Isolate top 9 bits of the denominator, to be used as index into the initial estimation table
* uint64_t tidx = nr >> 15, // top 9 bits. bit8 is always set
* uint32_t tidx = nr >> 15, // top 9 bits. bit8 is always set
* ie = inv_tab[tidx & 0xFF] + 256, // Get the table value. bit9 is always set
* x = idx <= 8 ? (ie >> (8 - idx)) : (ie << (idx - 8)); // Position the estimation at the proper place
*
* x = uint64_t((x * uint64_t(_BV(25) - x * d)) >> 24); // Refine estimation by newton-raphson. 1 iteration is enough
* const uint64_t r = _BV(24) - x * d; // Estimate remainder
* x = uint32_t((x * uint64_t(_BV(25) - x * d)) >> 24); // Refine estimation by newton-raphson. 1 iteration is enough
* const uint32_t r = _BV(24) - x * d; // Estimate remainder
* if (r >= d) x++; // Check whether to adjust result
* return uint64_t(x); // x holds the proper estimation
* return uint32_t(x); // x holds the proper estimation
*/
static uint64_t get_period_inverse(uint64_t d) {
static uint32_t get_period_inverse(uint32_t d) {
static const uint8_t inv_tab[256] PROGMEM = {
255,253,252,250,248,246,244,242,240,238,236,234,233,231,229,227,
@@ -380,7 +381,7 @@ void Planner::init() {
// For small denominators, it is cheaper to directly store the result.
// For bigger ones, just ONE Newton-Raphson iteration is enough to get
// maximum precision we need
static const uint64_t small_inv_tab[111] PROGMEM = {
static const uint32_t small_inv_tab[111] PROGMEM = {
16777216,16777216,8388608,5592405,4194304,3355443,2796202,2396745,2097152,1864135,1677721,1525201,1398101,1290555,1198372,1118481,
1048576,986895,932067,883011,838860,798915,762600,729444,699050,671088,645277,621378,599186,578524,559240,541200,
524288,508400,493447,479349,466033,453438,441505,430185,419430,409200,399457,390167,381300,372827,364722,356962,
@@ -717,18 +718,20 @@ void Planner::init() {
);
// Return the result
return r11 | (uint16_t(r12) << 8) | (uint64_t(r13) << 16);
return r11 | (uint16_t(r12) << 8) | (uint32_t(r13) << 16);
}
#else
// All other 32-bit MPUs can easily do inverse using hardware division,
// so we don't need to reduce precision or to use assembly language at all.
// This routine, for all other archs, returns 0x100000000 / d ~= 0xFFFFFFFF / d
FORCE_INLINE static uint64_t get_period_inverse(const uint64_t d) {
FORCE_INLINE static uint32_t get_period_inverse(const uint32_t d) {
return d ? 0xFFFFFFFF / d : 0xFFFFFFFF;
}
#endif
#endif
#define MINIMAL_STEP_RATE 120
/**
* Get the current block for processing
* and mark the block as busy.
@@ -765,6 +768,10 @@ block_t* Planner::get_current_block() {
// As this block is busy, advance the nonbusy block pointer
block_buffer_nonbusy = next_block_index(block_buffer_tail);
// Push block_buffer_planned pointer, if encountered.
if (block_buffer_tail == block_buffer_planned)
block_buffer_planned = block_buffer_nonbusy;
// Return the block
return block;
}
@@ -777,55 +784,47 @@ block_t* Planner::get_current_block() {
/**
* Calculate trapezoid parameters, multiplying the entry- and exit-speeds
* by the provided factors. If entry_factor is 0 don't change the initial_rate.
* Assumes that the implied initial_rate and final_rate are no less than
* sqrt(block->acceleration_steps_per_s2 / 2). This is ensured through
* minimum_planner_speed_sqr / min_entry_speed_sqr though note there's one
* exception in recalculate_trapezoids().
* by the provided factors. Requires that initial_rate and final_rate are
* no less than sqrt(block->acceleration_steps_per_s2 / 2), which is ensured
* through minimum_planner_speed_sqr in _populate_block().
**
* ############ VERY IMPORTANT ############
* NOTE that the PRECONDITION to call this function is that the block is
* NOT BUSY and it is marked as RECALCULATE. That WARRANTIES the Stepper ISR
* is not and will not use the block while we modify it.
* is not and will not use the block while we modify it, so it is safe to
* alter its values.
*/
void Planner::calculate_trapezoid_for_block(block_t * const block, const_float_t entry_speed, const_float_t exit_speed) {
void Planner::calculate_trapezoid_for_block(block_t * const block, const_float_t entry_factor, const_float_t exit_factor) {
const float spmm = block->steps_per_mm;
uint64_t initial_rate = entry_speed ? _MAX(long(MINIMAL_STEP_RATE), LROUND(entry_speed * spmm)) : block->initial_rate,
final_rate = _MAX(long(MINIMAL_STEP_RATE), LROUND(exit_speed * spmm));
uint32_t initial_rate = CEIL(block->nominal_rate * entry_factor),
final_rate = CEIL(block->nominal_rate * exit_factor); // (steps per second)
// Legacy check against supposed timer overflow. However Stepper::calc_timer_interval() already
// should protect against it. But removing this code produces judder in direction-switching
// moves. This is because the current discrete stepping math diverges from physical motion under
// constant acceleration when acceleration_steps_per_s2 is large compared to initial/final_rate.
NOLESS(initial_rate, uint64_t(MINIMAL_STEP_RATE)); // Enforce the minimum speed
NOLESS(final_rate, uint64_t(MINIMAL_STEP_RATE));
NOLESS(block->nominal_rate, MINIMAL_STEP_RATE);
NOMORE(initial_rate, block->nominal_rate); // NOTE: The nominal rate may be less than MINIMAL_STEP_RATE!
NOMORE(final_rate, block->nominal_rate);
// Limit minimal step rate (Otherwise the timer will overflow.)
NOLESS(initial_rate, uint32_t(MINIMAL_STEP_RATE));
NOLESS(final_rate, uint32_t(MINIMAL_STEP_RATE));
#if ANY(S_CURVE_ACCELERATION, LIN_ADVANCE)
// If we have some plateau time, the cruise rate will be the nominal rate
uint64_t cruise_rate = block->nominal_rate;
uint32_t cruise_rate = block->nominal_rate;
#endif
// Steps for acceleration, plateau and deceleration
int32_t plateau_steps = block->step_event_count,
accelerate_steps = 0,
decelerate_steps = 0;
int32_t plateau_steps = block->step_event_count;
uint32_t accelerate_steps = 0,
decelerate_steps = 0;
const int32_t accel = block->acceleration_steps_per_s2;
float inverse_accel = 0.0f;
if (accel != 0) {
inverse_accel = 1.0f / accel;
const float half_inverse_accel = 0.5f * inverse_accel,
float half_inverse_accel = 0.5f * inverse_accel,
nominal_rate_sq = FLOAT_SQ(block->nominal_rate),
// Steps required for acceleration, deceleration to/from nominal rate
decelerate_steps_float = half_inverse_accel * (nominal_rate_sq - FLOAT_SQ(final_rate)),
accelerate_steps_float = half_inverse_accel * (nominal_rate_sq - FLOAT_SQ(initial_rate));
// Aims to fully reach nominal and final rates
accelerate_steps = CEIL(accelerate_steps_float);
decelerate_steps = CEIL(decelerate_steps_float);
decelerate_steps = FLOOR(decelerate_steps_float);
// Steps between acceleration and deceleration, if any
plateau_steps -= accelerate_steps + decelerate_steps;
@@ -835,13 +834,13 @@ void Planner::calculate_trapezoid_for_block(block_t * const block, const_float_t
// Calculate accel / braking time in order to reach the final_rate exactly
// at the end of this block.
if (plateau_steps < 0) {
accelerate_steps = LROUND((block->step_event_count + accelerate_steps_float - decelerate_steps_float) * 0.5f);
LIMIT(accelerate_steps, 0, int32_t(block->step_event_count));
accelerate_steps_float = CEIL((block->step_event_count + accelerate_steps_float - decelerate_steps_float) * 0.5f);
accelerate_steps = _MIN(uint32_t(_MAX(accelerate_steps_float, 0)), block->step_event_count);
decelerate_steps = block->step_event_count - accelerate_steps;
#if ANY(S_CURVE_ACCELERATION, LIN_ADVANCE)
// We won't reach the cruising rate. Let's calculate the speed we will reach
NOMORE(cruise_rate, final_speed(initial_rate, accel, accelerate_steps));
cruise_rate = final_speed(initial_rate, accel, accelerate_steps);
#endif
}
}
@@ -849,7 +848,7 @@ void Planner::calculate_trapezoid_for_block(block_t * const block, const_float_t
#if ENABLED(S_CURVE_ACCELERATION)
const float rate_factor = inverse_accel * (STEPPER_TIMER_RATE);
// Jerk controlled speed requires to express speed versus time, NOT steps
uint64_t acceleration_time = rate_factor * float(cruise_rate - initial_rate),
uint32_t acceleration_time = rate_factor * float(cruise_rate - initial_rate),
deceleration_time = rate_factor * float(cruise_rate - final_rate),
// And to offload calculations from the ISR, we also calculate the inverse of those times here
acceleration_time_inverse = get_period_inverse(acceleration_time),
@@ -857,8 +856,8 @@ void Planner::calculate_trapezoid_for_block(block_t * const block, const_float_t
#endif
// Store new block parameters
block->accelerate_before = accelerate_steps;
block->decelerate_start = block->step_event_count - decelerate_steps;
block->accelerate_until = accelerate_steps;
block->decelerate_after = block->step_event_count - decelerate_steps;
block->initial_rate = initial_rate;
#if ENABLED(S_CURVE_ACCELERATION)
block->acceleration_time = acceleration_time;
@@ -938,16 +937,16 @@ void Planner::calculate_trapezoid_for_block(block_t * const block, const_float_t
*
* Recalculates the motion plan according to the following basic guidelines:
*
* 1. Go over blocks sequentially in reverse order and maximize the entry junction speed:
* a. Entry speed should stay below/at the pre-computed maximum junction speed limit
* b. Aim for the maximum entry speed which is the one reverse-computed from its exit speed
* (next->entry_speed) if assuming maximum deceleration over the full block travel distance
* c. The last (newest appended) block uses safe_exit_speed exit speed (there's no 'next')
* 2. Go over blocks in chronological (forward) order and fix the exit junction speed:
* a. Exit speed (next->entry_speed) must be below/at the maximum exit speed forward-computed
* from its entry speed if assuming maximum acceleration over the full block travel distance
* b. Exit speed should stay above/at the pre-computed minimum junction speed limit
* 3. Convert entry / exit speeds (mm/s) into final/initial steps/s
* 1. Go over every feasible block sequentially in reverse order and calculate the junction speeds
* (i.e. current->entry_speed) such that:
* a. No junction speed exceeds the pre-computed maximum junction speed limit or nominal speeds of
* neighboring blocks.
* b. A block entry speed cannot exceed one reverse-computed from its exit speed (next->entry_speed)
* with a maximum allowable deceleration over the block travel distance.
* c. The last (or newest appended) block is planned from safe_exit_speed_sqr.
* 2. Go over every block in chronological (forward) order and dial down junction speed values if
* a. The exit speed exceeds the one forward-computed from its entry speed with the maximum allowable
* acceleration over the block travel distance.
*
* When these stages are complete, the planner will have maximized the velocity profiles throughout the all
* of the planner blocks, where every block is operating at its maximum allowable acceleration limits. In
@@ -955,22 +954,28 @@ void Planner::calculate_trapezoid_for_block(block_t * const block, const_float_t
* are possible. If a new block is added to the buffer, the plan is recomputed according to the said
* guidelines for a new optimal plan.
*
* To increase computational efficiency of these guidelines:
* 1. We keep track of which blocks need calculation (block->flag.recalculate)
* 2. We stop the reverse pass on the first block whose entry_speed == max_entry_speed. As soon
* as that happens, there can be no further increases (ensured by the previous recalculate)
* 3. On the forward pass we skip through to the first block with a modified exit speed
* (next->entry_speed)
* 4. On the forward pass if we encounter a full acceleration block that limits its exit speed
* (next->entry_speed) we also update the maximum for that junction (next->max_entry_speed)
* so it's never updated again
* 5. We use speed squared (ex: entry_speed_sqr in mm^2/s^2) in acceleration limit computations
* 6. We don't recompute sqrt(entry_speed_sqr) if the block's entry speed didn't change
* To increase computational efficiency of these guidelines, a set of planner block pointers have been
* created to indicate stop-compute points for when the planner guidelines cannot logically make any further
* changes or improvements to the plan when in normal operation and new blocks are streamed and added to the
* planner buffer. For example, if a subset of sequential blocks in the planner have been planned and are
* bracketed by junction velocities at their maximums (or by the first planner block as well), no new block
* added to the planner buffer will alter the velocity profiles within them. So we no longer have to compute
* them. Or, if a set of sequential blocks from the first block in the planner (or a optimal stop-compute
* point) are all accelerating, they are all optimal and can not be altered by a new block added to the
* planner buffer, as this will only further increase the plan speed to chronological blocks until a maximum
* junction velocity is reached. However, if the operational conditions of the plan changes from infrequently
* used feed holds or feedrate overrides, the stop-compute pointers will be reset and the entire plan is
* recomputed as stated in the general guidelines.
*
* Planner buffer index mapping:
* - block_buffer_tail: Points to the beginning of the planner buffer. First to be executed or being executed.
* - block_buffer_head: Points to the buffer block after the last block in the buffer. Used to indicate whether
* the buffer is full or empty. As described for standard ring buffers, this block is always empty.
* - block_buffer_planned: Points to the first buffer block after the last optimally planned block for normal
* streaming operating conditions. Use for planning optimizations by avoiding recomputing parts of the
* planner buffer that don't change with the addition of a new block, as describe above. In addition,
* this block can never be less than block_buffer_tail and will always be pushed forward and maintain
* this requirement when encountered by the Planner::release_current_block() routine during a cycle.
*
* NOTE: Since the planner only computes on what's in the planner buffer, some motions with many short
* segments (e.g., complex curves) may seem to move slowly. This is because there simply isn't
@@ -993,8 +998,7 @@ void Planner::calculate_trapezoid_for_block(block_t * const block, const_float_t
*/
// The kernel called by recalculate() when scanning the plan from last to first entry.
// Returns true if it could increase the current block's entry speed.
bool Planner::reverse_pass_kernel(block_t * const current, const block_t * const next, const_float_t safe_exit_speed_sqr) {
void Planner::reverse_pass_kernel(block_t * const current, const block_t * const next, const_float_t safe_exit_speed_sqr) {
// We need to recalculate only for the last block added or if next->entry_speed_sqr changed.
if (!next || next->flag.recalculate) {
// And only if we're not already at max entry speed.
@@ -1012,136 +1016,196 @@ bool Planner::reverse_pass_kernel(block_t * const current, const block_t * const
// become BUSY just before being marked RECALCULATE, so check for that!
if (stepper.is_block_busy(current)) {
// Block became busy. Clear the RECALCULATE flag (no point in
// recalculating BUSY blocks).
// recalculating BUSY blocks). And don't set its speed, as it can't
// be updated at this time.
current->flag.recalculate = false;
}
else {
// Block is not BUSY so this is ahead of the Stepper ISR:
// Just Set the new entry speed.
current->entry_speed_sqr = new_entry_speed_sqr;
return true;
}
}
}
}
return false;
}
/**
* recalculate() needs to go over the current plan twice.
* Once in reverse and once forward. This implements the reverse pass that
* coarsely maximizes the entry speeds starting from last block.
* Requires there's at least one block with flag.recalculate in the buffer.
* Once in reverse and once forward. This implements the reverse pass.
*/
void Planner::reverse_pass(const_float_t safe_exit_speed_sqr) {
// Initialize block index to the last block in the planner buffer.
// This last block will have flag.recalculate set.
uint8_t block_index = prev_block_index(block_buffer_head);
// The ISR may change block_buffer_nonbusy so get a stable local copy.
uint8_t nonbusy_block_index = block_buffer_nonbusy;
// Read the index of the last buffer planned block.
// The ISR may change it so get a stable local copy.
uint8_t planned_block_index = block_buffer_planned;
// If there was a race condition and block_buffer_planned was incremented
// or was pointing at the head (queue empty) break loop now and avoid
// planning already consumed blocks
if (planned_block_index == block_buffer_head) return;
// Reverse Pass: Coarsely maximize all possible deceleration curves back-planning from the last
// block in buffer. Cease planning when the last optimal planned or tail pointer is reached.
// NOTE: Forward pass will later refine and correct the reverse pass to create an optimal plan.
const block_t *next = nullptr;
// Don't try to change the entry speed of the first non-busy block.
while (block_index != nonbusy_block_index) {
while (block_index != planned_block_index) {
// Perform the reverse pass
block_t *current = &block_buffer[block_index];
// Only process movement blocks
if (current->is_move()) {
// If no entry speed increase was possible we end the reverse pass.
if (!reverse_pass_kernel(current, next, safe_exit_speed_sqr)) return;
reverse_pass_kernel(current, next, safe_exit_speed_sqr);
next = current;
}
// Advance to the next
block_index = prev_block_index(block_index);
// The ISR could advance block_buffer_nonbusy while we were doing the reverse pass.
// The ISR could advance the block_buffer_planned while we were doing the reverse pass.
// We must try to avoid using an already consumed block as the last one - So follow
// changes to the pointer and make sure to limit the loop to the currently busy block
while (nonbusy_block_index != block_buffer_nonbusy) {
while (planned_block_index != block_buffer_planned) {
// If we reached the busy block or an already processed block, break the loop now
if (block_index == nonbusy_block_index) return;
if (block_index == planned_block_index) return;
// Advance the pointer, following the busy block
nonbusy_block_index = next_block_index(nonbusy_block_index);
planned_block_index = next_block_index(planned_block_index);
}
}
}
// The kernel called during the forward pass. Assumes current->flag.recalculate.
void Planner::forward_pass_kernel(const block_t * const previous, block_t * const current) {
// Check if the previous block is accelerating.
if (previous->entry_speed_sqr < current->entry_speed_sqr) {
// Compute the maximum achievable speed if the previous block was fully accelerating.
float new_exit_speed_sqr = max_allowable_speed_sqr(-previous->acceleration, previous->entry_speed_sqr, previous->millimeters);
// The kernel called by recalculate() when scanning the plan from first to last entry.
void Planner::forward_pass_kernel(const block_t * const previous, block_t * const current, const uint8_t block_index) {
// Check against previous speed only on current->entry_speed_sqr changes (or if first time).
if (current->flag.recalculate) {
// If the previous block is accelerating check if it's too short to complete the full speed
// change then adjust the entry speed accordingly. Entry speeds have already been maximized.
if (previous->entry_speed_sqr < current->entry_speed_sqr) {
float new_entry_speed_sqr = max_allowable_speed_sqr(-previous->acceleration, previous->entry_speed_sqr, previous->millimeters);
if (new_exit_speed_sqr < current->entry_speed_sqr) {
// Current entry speed limited by full acceleration from previous entry speed.
// If true, previous block is full-acceleration and we can move the planned pointer forward.
if (new_entry_speed_sqr < current->entry_speed_sqr) {
// Current entry speed limited by full acceleration from previous entry speed.
// Make sure entry speed not lower than minimum_planner_speed_sqr.
NOLESS(new_entry_speed_sqr, current->min_entry_speed_sqr);
current->entry_speed_sqr = new_entry_speed_sqr;
// Make sure entry speed not lower than minimum_planner_speed_sqr.
NOLESS(new_exit_speed_sqr, current->min_entry_speed_sqr);
current->entry_speed_sqr = new_exit_speed_sqr;
// Ensure we don't try updating entry_speed_sqr again.
current->max_entry_speed_sqr = new_exit_speed_sqr;
// Set optimal plan pointer.
block_buffer_planned = block_index;
}
else {
// Previous entry speed has been maximized.
block_buffer_planned = prev_block_index(block_index);
}
}
}
// The fully optimized entry speed is our new minimum speed.
current->min_entry_speed_sqr = current->entry_speed_sqr;
// Any block set at its maximum entry speed also creates an optimal plan up to this
// point in the buffer. When the plan is bracketed by either the beginning of the
// buffer and a maximum entry speed or two maximum entry speeds, every block in between
// cannot logically be further improved. Hence, we don't have to recompute them anymore.
if (current->entry_speed_sqr == current->max_entry_speed_sqr)
block_buffer_planned = block_index;
}
}
/**
* Do the forward pass and recalculate the trapezoid speed profiles for all blocks in the plan
* according to entry/exit speeds.
* recalculate() needs to go over the current plan twice.
* Once in reverse and once forward. This implements the forward pass.
*/
void Planner::forward_pass() {
// Forward Pass: Forward plan the acceleration curve from the planned pointer onward.
// Also scans for optimal plan breakpoints and appropriately updates the planned pointer.
// Begin at buffer planned pointer. Note that block_buffer_planned can be modified
// by the stepper ISR, so read it ONCE. It it guaranteed that block_buffer_planned
// will never lead head, so the loop is safe to execute. Also note that the forward
// pass will never modify the values at the tail.
uint8_t block_index = block_buffer_planned;
block_t *block;
const block_t * previous = nullptr;
while (block_index != block_buffer_head) {
// Perform the forward pass
block = &block_buffer[block_index];
// Only process movement blocks
if (block->is_move()) {
// If there's no previous block or the previous block is not
// BUSY (thus, modifiable) run the forward_pass_kernel. Otherwise,
// the previous block became BUSY, so assume the current block's
// entry speed can't be altered (since that would also require
// updating the exit speed of the previous block).
if (previous && !stepper.is_block_busy(previous))
forward_pass_kernel(previous, block, block_index);
previous = block;
}
// Advance to the previous
block_index = next_block_index(block_index);
}
}
/**
* Recalculate the trapezoid speed profiles for all blocks in the plan
* according to the entry_factor for each junction. Must be called by
* recalculate() after updating the blocks.
*/
void Planner::recalculate_trapezoids(const_float_t safe_exit_speed_sqr) {
// Start with the block that's about to execute or is executing.
// The tail may be changed by the ISR so get a local copy.
uint8_t block_index = block_buffer_tail,
head_block_index = block_buffer_head;
// Since there could be a sync block in the head of the queue, and the
// next loop must not recalculate the head block (as it needs to be
// specially handled), scan backwards to the first non-SYNC block.
while (head_block_index != block_index) {
// Go back (head always point to the first free block)
const uint8_t prev_index = prev_block_index(head_block_index);
// Get the pointer to the block
block_t *prev = &block_buffer[prev_index];
// It the block is a move, we're done with this loop
if (prev->is_move()) break;
// Examine the previous block. This and all following are SYNC blocks
head_block_index = prev_index;
}
// Go from the tail (currently executed block) to the first block, without including it)
block_t *block = nullptr, *next = nullptr;
float next_entry_speed = 0.0f;
float current_entry_speed = 0.0f, next_entry_speed = 0.0f;
while (block_index != head_block_index) {
next = &block_buffer[block_index];
// Only process movement blocks
if (next->is_move()) {
// Check if the next block's entry speed changed
if (next->flag.recalculate) {
if (!block) {
// 'next' is the first move due to either being the first added move or due to the planner
// having completely fallen behind. Revert any reverse pass change.
next->entry_speed_sqr = next->min_entry_speed_sqr;
next_entry_speed = SQRT(next->min_entry_speed_sqr);
}
else {
// Try to fix exit speed which requires trapezoid recalculation
block->flag.recalculate = true;
next_entry_speed = SQRT(next->entry_speed_sqr);
// But there is an inherent race condition here, as the block may have
// become BUSY just before being marked RECALCULATE, so check for that!
if (stepper.is_block_busy(block)) {
// Block is BUSY so we can't change the exit speed. Revert any reverse pass change.
next->entry_speed_sqr = next->min_entry_speed_sqr;
if (!next->initial_rate) {
// 'next' was never calculated. Planner is falling behind so for maximum efficiency
// set next's stepping speed directly and forgo checking against min_entry_speed_sqr.
// calculate_trapezoid_for_block() can handle it, albeit sub-optimally.
next->initial_rate = block->final_rate;
}
// Note that at this point next_entry_speed is (still) 0.
}
else {
// Block is not BUSY: we won the race against the ISR or recalculate was already set
if (block) {
if (next->entry_speed_sqr != next->min_entry_speed_sqr)
forward_pass_kernel(block, next);
// If the next block is marked to RECALCULATE, also mark the previously-fetched one
if (next->flag.recalculate) block->flag.recalculate = true;
const float current_entry_speed = next_entry_speed;
next_entry_speed = SQRT(next->entry_speed_sqr);
// Recalculate if current block entry or exit junction speed has changed.
if (block->flag.recalculate) {
calculate_trapezoid_for_block(block, current_entry_speed, next_entry_speed);
// But there is an inherent race condition here, as the block maybe
// became BUSY, just before it was marked as RECALCULATE, so check
// if that is the case!
if (!stepper.is_block_busy(block)) {
// Block is not BUSY, we won the race against the Stepper ISR:
// NOTE: Entry and exit factors always > 0 by all previous logic operations.
const float nomr = 1.0f / block->nominal_speed;
calculate_trapezoid_for_block(block, current_entry_speed * nomr, next_entry_speed * nomr);
}
// Reset current only to ensure next trapezoid is computed - The
@@ -1151,17 +1215,30 @@ void Planner::recalculate_trapezoids(const_float_t safe_exit_speed_sqr) {
}
block = next;
current_entry_speed = next_entry_speed;
}
block_index = next_block_index(block_index);
}
// Last/newest block in buffer. The above guarantees it's a move block.
if (block && block->flag.recalculate) {
const float current_entry_speed = next_entry_speed;
// Last/newest block in buffer. Always recalculated.
if (block) {
next_entry_speed = SQRT(safe_exit_speed_sqr);
calculate_trapezoid_for_block(block, current_entry_speed, next_entry_speed);
// Mark the next(last) block as RECALCULATE, to prevent the Stepper ISR running it.
// As the last block is always recalculated here, there is a chance the block isn't
// marked as RECALCULATE yet. That's the reason for the following line.
block->flag.recalculate = true;
// But there is an inherent race condition here, as the block maybe
// became BUSY, just before it was marked as RECALCULATE, so check
// if that is the case!
if (!stepper.is_block_busy(block)) {
// Block is not BUSY, we won the race against the Stepper ISR:
const float nomr = 1.0f / block->nominal_speed;
calculate_trapezoid_for_block(block, current_entry_speed * nomr, next_entry_speed * nomr);
}
// Reset block to ensure its trapezoid is computed - The stepper is free to use
// the block from now on.
@@ -1169,10 +1246,14 @@ void Planner::recalculate_trapezoids(const_float_t safe_exit_speed_sqr) {
}
}
// Requires there's at least one block with flag.recalculate in the buffer
void Planner::recalculate(const_float_t safe_exit_speed_sqr) {
reverse_pass(safe_exit_speed_sqr);
// The forward pass is done as part of recalculate_trapezoids()
// Initialize block index to the last block in the planner buffer.
const uint8_t block_index = prev_block_index(block_buffer_head);
// If there is just one block, no planning can be done. Avoid it!
if (block_index != block_buffer_planned) {
reverse_pass(safe_exit_speed_sqr);
forward_pass();
}
recalculate_trapezoids(safe_exit_speed_sqr);
}
@@ -1581,7 +1662,7 @@ void Planner::quick_stop() {
const bool was_enabled = stepper.suspend();
// Drop all queue entries
block_buffer_nonbusy = block_buffer_head = block_buffer_tail;
block_buffer_nonbusy = block_buffer_planned = block_buffer_head = block_buffer_tail;
// Restart the block delay for the first movement - As the queue was
// forced to empty, there's no risk the ISR will touch this.
@@ -1885,10 +1966,15 @@ bool Planner::_populate_block(
dm.x = (dist.a > 0); // Axis X direction
dm.b = (dist.b + dist.c > 0); // Motor B direction
dm.c = (CORESIGN(dist.b - dist.c) > 0); // Motor C direction
#elif ENABLED(MARKFORGED_XY)
dm.a = (dist.a TERN(MARKFORGED_INVERSE, -, +) dist.b > 0); // Motor A direction
dm.b = (dist.b > 0); // Motor B direction
TERN_(HAS_Z_AXIS, dm.z = (dist.c > 0)); // Axis Z direction
#elif ENABLED(MARKFORGED_XY)
if (extruder == 0) {
dm.a = (dist.a + dist.b > 0); // Motor A direction
dm.b = (dist.b > 0); // Motor B direction
}
else {
dm.a = (dist.a - dist.b > 0); // Motor A direction
dm.b = (dist.b> 0); // Motor B direction
}
#elif ENABLED(MARKFORGED_YX)
dm.a = (dist.a > 0); // Motor A direction
dm.b = (dist.b TERN(MARKFORGED_INVERSE, -, +) dist.a > 0); // Motor B direction
@@ -1909,9 +1995,9 @@ bool Planner::_populate_block(
#if HAS_EXTRUDERS
dm.e = (dist.e > 0);
const float esteps_float = dist.e * e_factor[extruder];
const uint64_t esteps = ABS(esteps_float);
const uint32_t esteps = ABS(esteps_float);
#else
constexpr uint64_t esteps = 0;
constexpr uint32_t esteps = 0;
#endif
// Clear all flags, including the "busy" bit
@@ -2350,8 +2436,7 @@ bool Planner::_populate_block(
// Compute and limit the acceleration rate for the trapezoid generator.
const float steps_per_mm = block->step_event_count * inverse_millimeters;
block->steps_per_mm = steps_per_mm;
uint64_t accel;
uint32_t accel;
#if ENABLED(LIN_ADVANCE)
bool use_advance_lead = false;
#endif
@@ -2361,7 +2446,7 @@ bool Planner::_populate_block(
else {
#define LIMIT_ACCEL_LONG(AXIS,INDX) do{ \
if (block->steps[AXIS] && max_acceleration_steps_per_s2[AXIS+INDX] < accel) { \
const uint64_t max_possible = max_acceleration_steps_per_s2[AXIS+INDX] * block->step_event_count / block->steps[AXIS]; \
const uint32_t max_possible = max_acceleration_steps_per_s2[AXIS+INDX] * block->step_event_count / block->steps[AXIS]; \
NOMORE(accel, max_possible); \
} \
}while(0)
@@ -2405,7 +2490,7 @@ bool Planner::_populate_block(
use_advance_lead = false;
else {
// Scale E acceleration so that it will be possible to jump to the advance speed.
const uint64_t max_accel_steps_per_s2 = MAX_E_JERK(extruder) / (extruder_advance_K[E_INDEX_N(extruder)] * e_D_ratio) * steps_per_mm;
const uint32_t max_accel_steps_per_s2 = MAX_E_JERK(extruder) / (extruder_advance_K[E_INDEX_N(extruder)] * e_D_ratio) * steps_per_mm;
if (accel > max_accel_steps_per_s2) {
accel = max_accel_steps_per_s2;
if (ENABLED(LA_DEBUG)) SERIAL_ECHOLNPGM("Acceleration limited.");
@@ -2435,7 +2520,7 @@ bool Planner::_populate_block(
block->acceleration_steps_per_s2 = accel;
block->acceleration = accel / steps_per_mm;
#if DISABLED(S_CURVE_ACCELERATION)
block->acceleration_rate = (uint64_t)(accel * (float(1UL << 24) / (STEPPER_TIMER_RATE)));
block->acceleration_rate = (uint32_t)(accel * (float(1UL << 24) / (STEPPER_TIMER_RATE)));
#endif
#if ENABLED(LIN_ADVANCE)
@@ -2448,7 +2533,7 @@ bool Planner::_populate_block(
// reduce LA ISR frequency by calling it only often enough to ensure that there will
// never be more than four extruder steps per call
for (uint64_t dividend = block->steps.e << 1; dividend <= (block->step_event_count >> 2); dividend <<= 1)
for (uint32_t dividend = block->steps.e << 1; dividend <= (block->step_event_count >> 2); dividend <<= 1)
block->la_scaling++;
#if ENABLED(LA_DEBUG)
@@ -2461,7 +2546,7 @@ bool Planner::_populate_block(
// Formula for the average speed over a 1 step worth of distance if starting from zero and
// accelerating at the current limit. Since we can only change the speed every step this is a
// good lower limit for the entry and exit speeds. Note that for calculate_trapezoid_for_block()
// to work correctly this must be accurately set and propagated.
// to work correctly, this must be accurately set and propagated.
minimum_planner_speed_sqr = 0.5f * block->acceleration / steps_per_mm;
// Go straight to/from nominal speed if block->acceleration is too high for it.
NOMORE(minimum_planner_speed_sqr, sq(block->nominal_speed));
@@ -2687,7 +2772,7 @@ bool Planner::_populate_block(
// Advance affects E_AXIS speed and therefore jerk. Add a speed correction whenever
// LA is turned OFF. No correction is applied when LA is turned ON (because it didn't
// perform well; it takes more time/effort to push/melt filament than the reverse).
static uint64_t previous_advance_rate;
static uint32_t previous_advance_rate;
static float previous_e_mm_per_step;
if (dist.e < 0 && previous_advance_rate) {
// Retract move after a segment with LA that ended with an E speed decrease.
@@ -2735,7 +2820,7 @@ bool Planner::_populate_block(
#endif // CLASSIC_JERK
// High acceleration limits override low jerk/junction deviation limits (as fixing trapezoids
// or reducing acceleration introduces too much complexity and/or too much compute).
// or reducing acceleration introduces too much complexity and/or too much compute)
NOLESS(vmax_junction_sqr, minimum_planner_speed_sqr);
// Max entry speed of this block equals the max exit speed of the previous block.
@@ -2744,8 +2829,6 @@ bool Planner::_populate_block(
block->entry_speed_sqr = minimum_planner_speed_sqr;
// Set min entry speed. Rarely it could be higher than the previous nominal speed but that's ok.
block->min_entry_speed_sqr = minimum_planner_speed_sqr;
// Zero the initial_rate to indicate that calculate_trapezoid_for_block() hasn't been called yet.
block->initial_rate = 0;
block->flag.recalculate = true;
@@ -3081,8 +3164,8 @@ bool Planner::buffer_line(const xyze_pos_t &cart, const_feedRate_t fr_mm_s
block->step_event_count = num_steps;
block->initial_rate = block->final_rate = block->nominal_rate = last_page_step_rate; // steps/s
block->accelerate_before = 0;
block->decelerate_start = block->step_event_count;
block->accelerate_until = 0;
block->decelerate_after = block->step_event_count;
// Will be set to last direction later if directional format.
block->direction_bits.reset();
@@ -3192,7 +3275,7 @@ void Planner::set_position_mm(const xyze_pos_t &xyze) {
// Recalculate the steps/s^2 acceleration rates, based on the mm/s^2
void Planner::refresh_acceleration_rates() {
uint64_t highest_rate = 1;
uint32_t highest_rate = 1;
LOOP_DISTINCT_AXES(i) {
max_acceleration_steps_per_s2[i] = settings.max_acceleration_mm_per_s2[i] * settings.axis_steps_per_mm[i];
if (TERN1(DISTINCT_E_FACTORS, i < E_AXIS || i == E_AXIS_N(active_extruder)))
@@ -3305,7 +3388,7 @@ void Planner::set_max_feedrate(const AxisEnum axis, float inMaxFeedrateMMS) {
const bool was_enabled = stepper.suspend();
#endif
uint64_t bbru = block_buffer_runtime_us;
uint32_t bbru = block_buffer_runtime_us;
#ifdef __AVR__
// Reenable Stepper ISR
+20 -27
View File
@@ -78,14 +78,6 @@
#include "../feature/closedloop.h"
#endif
constexpr uint64_t MINIMAL_STEP_RATE = (
#ifdef CPU_32_BIT
_MAX((STEPPER_TIMER_RATE) / HAL_TIMER_TYPE_MAX, 1U) // 32-bit shouldn't go below 1
#else
(F_CPU) / 500000U // AVR shouldn't go below 32 (16MHz) or 40 (20MHz)
#endif
);
// Feedrate for manual moves
#ifdef MANUAL_FEEDRATE
constexpr xyze_feedrate_t manual_feedrate_mm_m = MANUAL_FEEDRATE,
@@ -227,14 +219,13 @@ typedef struct PlannerBlock {
min_entry_speed_sqr, // Minimum allowable junction entry speed in (mm/sec)^2
max_entry_speed_sqr, // Maximum allowable junction entry speed in (mm/sec)^2
millimeters, // The total travel of this block in mm
steps_per_mm, // steps/mm
acceleration; // acceleration mm/sec^2
union {
abce_ulong_t steps; // Step count along each axis
abce_long_t position; // New position to force when this sync block is executed
};
uint64_t step_event_count; // The number of step events required to complete this block
uint32_t step_event_count; // The number of step events required to complete this block
#if HAS_MULTI_EXTRUDER
uint8_t extruder; // The extruder to move (if E move)
@@ -247,30 +238,30 @@ typedef struct PlannerBlock {
#endif
// Settings for the trapezoid generator
uint64_t accelerate_before, // The index of the step event on which to start cruising
decelerate_start; // The index of the step event on which to start decelerating
uint32_t accelerate_until, // The index of the step event on which to stop acceleration
decelerate_after; // The index of the step event on which to start decelerating
#if ENABLED(S_CURVE_ACCELERATION)
uint64_t cruise_rate, // The actual cruise rate to use, between end of the acceleration phase and start of deceleration phase
uint32_t cruise_rate, // The actual cruise rate to use, between end of the acceleration phase and start of deceleration phase
acceleration_time, // Acceleration time and deceleration time in STEP timer counts
deceleration_time,
acceleration_time_inverse, // Inverse of acceleration and deceleration periods, expressed as integer. Scale depends on CPU being used
deceleration_time_inverse;
#else
uint64_t acceleration_rate; // Acceleration rate in (2^24 steps)/timer_ticks*s
uint32_t acceleration_rate; // Acceleration rate in (2^24 steps)/timer_ticks*s
#endif
AxisBits direction_bits; // Direction bits set for this block, where 1 is negative motion
// Advance extrusion
#if ENABLED(LIN_ADVANCE)
uint64_t la_advance_rate; // The rate at which steps are added whilst accelerating
uint32_t la_advance_rate; // The rate at which steps are added whilst accelerating
uint8_t la_scaling; // Scale ISR frequency down and step frequency up by 2 ^ la_scaling
uint16_t max_adv_steps, // Max advance steps to get cruising speed pressure
final_adv_steps; // Advance steps for exit speed pressure
#endif
uint64_t nominal_rate, // The nominal step rate for this block in step_events/sec
uint32_t nominal_rate, // The nominal step rate for this block in step_events/sec
initial_rate, // The jerk-adjusted step rate at start of block
final_rate, // The minimal rate at exit
acceleration_steps_per_s2; // acceleration steps/sec^2
@@ -292,11 +283,11 @@ typedef struct PlannerBlock {
#endif
#if HAS_WIRED_LCD
uint64_t segment_time_us;
uint32_t segment_time_us;
#endif
#if ENABLED(POWER_LOSS_RECOVERY)
uint64_t sdpos;
uint32_t sdpos;
xyze_pos_t start_position;
#endif
@@ -347,7 +338,7 @@ constexpr uint8_t block_inc_mod(const uint8_t v1, const uint8_t v2) {
#endif
typedef struct PlannerSettings {
uint64_t max_acceleration_mm_per_s2[DISTINCT_AXES], // (mm/s^2) M201 XYZE
uint32_t max_acceleration_mm_per_s2[DISTINCT_AXES], // (mm/s^2) M201 XYZE
min_segment_time_us; // (µs) M205 B
// (steps) M92 XYZE - Steps per millimeter
@@ -451,6 +442,7 @@ class Planner {
static block_t block_buffer[BLOCK_BUFFER_SIZE];
static volatile uint8_t block_buffer_head, // Index of the next block to be pushed
block_buffer_nonbusy, // Index of the first non busy block
block_buffer_planned, // Index of the optimally planned block
block_buffer_tail; // Index of the busy block, if any
static uint16_t cleaning_buffer_counter; // A counter to disable queuing of blocks
static uint8_t delay_before_delivering; // This counter delays delivery of blocks when queue becomes empty to allow the opportunity of merging blocks
@@ -460,7 +452,7 @@ class Planner {
#endif
#if ENABLED(DIRECT_STEPPING)
static uint64_t last_page_step_rate; // Last page step rate given
static uint32_t last_page_step_rate; // Last page step rate given
static AxisBits last_page_dir; // Last page direction given, where 1 represents forward or positive motion
#endif
@@ -487,7 +479,7 @@ class Planner {
static laser_state_t laser_inline;
#endif
static uint64_t max_acceleration_steps_per_s2[DISTINCT_AXES]; // (steps/s^2) Derived from mm_per_s2
static uint32_t max_acceleration_steps_per_s2[DISTINCT_AXES]; // (steps/s^2) Derived from mm_per_s2
#if ENABLED(EDITABLE_STEPS_PER_UNIT)
static float mm_per_step[DISTINCT_AXES]; // Millimeters per step
@@ -577,7 +569,7 @@ class Planner {
/**
* Limit where 64bit math is necessary for acceleration calculation
*/
static uint64_t acceleration_long_cutoff;
static uint32_t acceleration_long_cutoff;
#ifdef MAX7219_DEBUG_SLOWDOWN
friend class Max7219;
@@ -594,7 +586,7 @@ class Planner {
#endif
#if HAS_WIRED_LCD
volatile static uint64_t block_buffer_runtime_us; // Theoretical block buffer runtime in µs
volatile static uint32_t block_buffer_runtime_us; // Theoretical block buffer runtime in µs
#endif
public:
@@ -812,7 +804,7 @@ class Planner {
FORCE_INLINE static uint8_t nonbusy_movesplanned() { return block_dec_mod(block_buffer_head, block_buffer_nonbusy); }
// Remove all blocks from the buffer
FORCE_INLINE static void clear_block_buffer() { block_buffer_nonbusy = block_buffer_head = block_buffer_tail = 0; }
FORCE_INLINE static void clear_block_buffer() { block_buffer_nonbusy = block_buffer_planned = block_buffer_head = block_buffer_tail = 0; }
// Check if movement queue is full
FORCE_INLINE static bool is_full() { return block_buffer_tail == next_block_index(block_buffer_head); }
@@ -1089,12 +1081,13 @@ class Planner {
}
#endif
static void calculate_trapezoid_for_block(block_t * const block, const_float_t entry_speed, const_float_t exit_speed);
static void calculate_trapezoid_for_block(block_t * const block, const_float_t entry_factor, const_float_t exit_factor);
static bool reverse_pass_kernel(block_t * const current, const block_t * const next, const_float_t safe_exit_speed_sqr);
static void forward_pass_kernel(const block_t * const previous, block_t * const current);
static void reverse_pass_kernel(block_t * const current, const block_t * const next, const_float_t safe_exit_speed_sqr);
static void forward_pass_kernel(const block_t * const previous, block_t * const current, uint8_t block_index);
static void reverse_pass(const_float_t safe_exit_speed_sqr);
static void forward_pass();
static void recalculate_trapezoids(const_float_t safe_exit_speed_sqr);
+123 -195
View File
@@ -59,8 +59,8 @@
* time ----->
*
* The trapezoid is the shape the speed curve over time. It starts at block->initial_rate, accelerates
* while step_events_completed < block->accelerate_before, then starts cruising at constant speed while
* step_events_completed < block->decelerate_start, then it decelerates until the trapezoid generator is reset.
* first block->accelerate_until step_events_completed, then keeps going at constant speed until
* step_events_completed reaches block->decelerate_after after which it decelerates until the trapezoid generator is reset.
* The slope of acceleration is calculated using v = u + at where t is the accumulated timer values of the steps so far.
*/
@@ -154,9 +154,9 @@ Stepper stepper; // Singleton
#if HAS_MOTOR_CURRENT_SPI || HAS_MOTOR_CURRENT_PWM
bool Stepper::initialized; // = false
uint64_t Stepper::motor_current_setting[MOTOR_CURRENT_COUNT]; // Initialized by settings.load()
uint32_t Stepper::motor_current_setting[MOTOR_CURRENT_COUNT]; // Initialized by settings.load()
#if HAS_MOTOR_CURRENT_SPI
constexpr uint64_t Stepper::digipot_count[];
constexpr uint32_t Stepper::digipot_count[];
#endif
#endif
@@ -193,8 +193,7 @@ bool Stepper::abort_current_block;
;
#endif
// In timer_ticks
uint64_t Stepper::acceleration_time, Stepper::deceleration_time;
uint32_t Stepper::acceleration_time, Stepper::deceleration_time;
#if MULTISTEPPING_LIMIT > 1
uint8_t Stepper::steps_per_isr = 1; // Count of steps to perform per Stepper ISR call
@@ -223,10 +222,10 @@ uint64_t Stepper::acceleration_time, Stepper::deceleration_time;
xyze_long_t Stepper::delta_error{0};
xyze_long_t Stepper::advance_dividend{0};
uint64_t Stepper::advance_divisor = 0,
uint32_t Stepper::advance_divisor = 0,
Stepper::step_events_completed = 0, // The number of step events executed in the current block
Stepper::accelerate_before, // The count at which to start cruising
Stepper::decelerate_start, // The count at which to start decelerating
Stepper::accelerate_until, // The count at which to stop accelerating
Stepper::decelerate_after, // The count at which to start decelerating
Stepper::step_event_count; // The total event count for the current block
#if ANY(HAS_MULTI_EXTRUDER, MIXING_EXTRUDER)
@@ -239,8 +238,8 @@ uint64_t Stepper::advance_divisor = 0,
int32_t __attribute__((used)) Stepper::bezier_A __asm__("bezier_A"); // A coefficient in Bézier speed curve with alias for assembler
int32_t __attribute__((used)) Stepper::bezier_B __asm__("bezier_B"); // B coefficient in Bézier speed curve with alias for assembler
int32_t __attribute__((used)) Stepper::bezier_C __asm__("bezier_C"); // C coefficient in Bézier speed curve with alias for assembler
uint64_t __attribute__((used)) Stepper::bezier_F __asm__("bezier_F"); // F coefficient in Bézier speed curve with alias for assembler
uint64_t __attribute__((used)) Stepper::bezier_AV __asm__("bezier_AV"); // AV coefficient in Bézier speed curve with alias for assembler
uint32_t __attribute__((used)) Stepper::bezier_F __asm__("bezier_F"); // F coefficient in Bézier speed curve with alias for assembler
uint32_t __attribute__((used)) Stepper::bezier_AV __asm__("bezier_AV"); // AV coefficient in Bézier speed curve with alias for assembler
#ifdef __AVR__
bool __attribute__((used)) Stepper::A_negative __asm__("A_negative"); // If A coefficient was negative
#endif
@@ -260,7 +259,7 @@ uint64_t Stepper::advance_divisor = 0,
ne_coeff_t Stepper::ne;
ne_fix_t Stepper::ne_fix;
int32_t Stepper::ne_edividend;
uint64_t Stepper::ne_scale;
uint32_t Stepper::ne_scale;
#endif
#if HAS_ZV_SHAPING
@@ -297,7 +296,7 @@ uint64_t Stepper::advance_divisor = 0,
hal_timer_t Stepper::ticks_nominal = 0;
#if DISABLED(S_CURVE_ACCELERATION)
uint64_t Stepper::acc_step_rate; // needed for deceleration start point
uint32_t Stepper::acc_step_rate; // needed for deceleration start point
#endif
xyz_long_t Stepper::endstops_trigsteps;
@@ -424,9 +423,22 @@ xyze_int8_t Stepper::count_direction{0};
#endif
#if HAS_SYNCED_Y_STEPPERS
#define Y_APPLY_DIR(FWD,Q) do{ Y_DIR_WRITE(FWD); Y2_DIR_WRITE(INVERT_DIR(Y2_VS_Y, FWD)); }while(0)
#define Y_APPLY_DIR(FWD,Q) do{ Y_DIR_WRITE(FWD); Y2_DIR_WRITE(INVERT_DIR(Y2_VS_Y, FWD)); \
if (!extruder_duplication_enabled) { \
if (last_moved_extruder) \
X_DIR_WRITE(FWD); \
else X2_DIR_WRITE((FWD) ^ 1); \
}; \
}while(0)
#if ENABLED(Y_DUAL_ENDSTOPS)
#define Y_APPLY_STEP(FWD,Q) DUAL_ENDSTOP_APPLY_STEP(Y,FWD)
#define Y_APPLY_STEP(FWD,Q) do { \
DUAL_ENDSTOP_APPLY_STEP(Y,FWD); \
if (!extruder_duplication_enabled) { \
if (last_moved_extruder) \
X_STEP_WRITE(FWD); \
else X2_STEP_WRITE(FWD); \
}; \
}while(0)
#else
#define Y_APPLY_STEP(FWD,Q) do{ Y_STEP_WRITE(FWD); Y2_STEP_WRITE(FWD); }while(0)
#endif
@@ -789,34 +801,34 @@ void Stepper::apply_directions() {
*
* And for each point, evaluate the curve with the following sequence:
*
* void lsrs(uint64_t& d, uint64_t s, int cnt) {
* void lsrs(uint32_t& d, uint32_t s, int cnt) {
* d = s >> cnt;
* }
* void lsls(uint64_t& d, uint64_t s, int cnt) {
* void lsls(uint32_t& d, uint32_t s, int cnt) {
* d = s << cnt;
* }
* void lsrs(int32_t& d, uint64_t s, int cnt) {
* d = uint64_t(s) >> cnt;
* void lsrs(int32_t& d, uint32_t s, int cnt) {
* d = uint32_t(s) >> cnt;
* }
* void lsls(int32_t& d, uint64_t s, int cnt) {
* d = uint64_t(s) << cnt;
* void lsls(int32_t& d, uint32_t s, int cnt) {
* d = uint32_t(s) << cnt;
* }
* void umull(uint64_t& rlo, uint64_t& rhi, uint64_t op1, uint64_t op2) {
* void umull(uint32_t& rlo, uint32_t& rhi, uint32_t op1, uint32_t op2) {
* uint64_t res = uint64_t(op1) * op2;
* rlo = uint64_t(res & 0xFFFFFFFF);
* rhi = uint64_t((res >> 32) & 0xFFFFFFFF);
* rlo = uint32_t(res & 0xFFFFFFFF);
* rhi = uint32_t((res >> 32) & 0xFFFFFFFF);
* }
* void smlal(int32_t& rlo, int32_t& rhi, int32_t op1, int32_t op2) {
* int64_t mul = int64_t(op1) * op2;
* int64_t s = int64_t(uint64_t(rlo) | ((uint64_t(uint64_t(rhi)) << 32U)));
* int64_t s = int64_t(uint32_t(rlo) | ((uint64_t(uint32_t(rhi)) << 32U)));
* mul += s;
* rlo = int32_t(mul & 0xFFFFFFFF);
* rhi = int32_t((mul >> 32) & 0xFFFFFFFF);
* }
* int32_t _eval_bezier_curve_arm(uint64_t curr_step) {
* uint64_t flo = 0;
* uint64_t fhi = bezier_AV * curr_step;
* uint64_t t = fhi;
* int32_t _eval_bezier_curve_arm(uint32_t curr_step) {
* uint32_t flo = 0;
* uint32_t fhi = bezier_AV * curr_step;
* uint32_t t = fhi;
* int32_t alo = bezier_F;
* int32_t ahi = 0;
* int32_t A = bezier_A;
@@ -866,7 +878,7 @@ void Stepper::apply_directions() {
*
* And for each curve, estimate its coefficients with:
*
* void _calc_bezier_curve_coeffs(int32_t v0, int32_t v1, uint64_t av) {
* void _calc_bezier_curve_coeffs(int32_t v0, int32_t v1, uint32_t av) {
* // Calculate the Bézier coefficients
* if (v1 < v0) {
* A_negative = true;
@@ -891,14 +903,14 @@ void Stepper::apply_directions() {
* }
* // unsigned multiplication of 16 bits x 16bits, return upper 16 bits
* void umul16x16to16hi(uint16_t& r, uint16_t op1, uint16_t op2) {
* r = (uint64_t(op1) * op2) >> 16;
* r = (uint32_t(op1) * op2) >> 16;
* }
* // unsigned multiplication of 16 bits x 24bits, return upper 24 bits
* void umul16x24to24hi(uint24_t& r, uint16_t op1, uint24_t op2) {
* r = uint24_t((uint64_t(op1) * op2) >> 16);
* }
*
* int32_t _eval_bezier_curve(uint64_t curr_step) {
* int32_t _eval_bezier_curve(uint32_t curr_step) {
* // To save computing, the first step is always the initial speed
* if (!curr_step)
* return bezier_F;
@@ -940,7 +952,7 @@ void Stepper::apply_directions() {
#ifdef __AVR__
// For AVR we use assembly to maximize speed
void Stepper::_calc_bezier_curve_coeffs(const int32_t v0, const int32_t v1, const uint64_t av) {
void Stepper::_calc_bezier_curve_coeffs(const int32_t v0, const int32_t v1, const uint32_t av) {
// Store advance
bezier_AV = av;
@@ -1042,7 +1054,7 @@ void Stepper::apply_directions() {
);
}
FORCE_INLINE int32_t Stepper::_eval_bezier_curve(const uint64_t curr_step) {
FORCE_INLINE int32_t Stepper::_eval_bezier_curve(const uint32_t curr_step) {
// If dealing with the first step, save expensive computing and return the initial speed
if (!curr_step)
@@ -1424,13 +1436,13 @@ void Stepper::apply_directions() {
:
:"cc","r0","r1"
);
return (r2 | (uint16_t(r3) << 8)) | (uint64_t(r4) << 16);
return (r2 | (uint16_t(r3) << 8)) | (uint32_t(r4) << 16);
}
#else
// For all the other 32bit CPUs
FORCE_INLINE void Stepper::_calc_bezier_curve_coeffs(const int32_t v0, const int32_t v1, const uint64_t av) {
FORCE_INLINE void Stepper::_calc_bezier_curve_coeffs(const int32_t v0, const int32_t v1, const uint32_t av) {
// Calculate the Bézier coefficients
#ifndef S_CURVE_FACTOR
bezier_A = 768 * (v1 - v0);
@@ -1447,13 +1459,13 @@ void Stepper::apply_directions() {
bezier_AV = av;
}
FORCE_INLINE int32_t Stepper::_eval_bezier_curve(const uint64_t curr_step) {
FORCE_INLINE int32_t Stepper::_eval_bezier_curve(const uint32_t curr_step) {
#if (defined(__arm__) || defined(__thumb__)) && __ARM_ARCH >= 6 && !defined(STM32G0B1xx) // TODO: Test define STM32G0xx versus STM32G0B1xx
// For ARM Cortex M3/M4 CPUs, we have the optimized assembler version, that takes 43 cycles to execute
uint64_t flo = 0;
uint64_t fhi = bezier_AV * curr_step;
uint64_t t = fhi;
uint32_t flo = 0;
uint32_t fhi = bezier_AV * curr_step;
uint32_t t = fhi;
int32_t alo = bezier_F;
int32_t ahi = 0;
int32_t A = bezier_A;
@@ -1495,7 +1507,7 @@ void Stepper::apply_directions() {
// For non ARM targets, we provide a fallback implementation. Really doubt it
// will be useful, unless the processor is fast and 32bit
uint64_t t = bezier_AV * curr_step; // t: Range 32 bits
uint32_t t = bezier_AV * curr_step; // t: Range 32 bits
uint64_t f = t;
#ifndef S_CURVE_FACTOR
f *= t; // Range 32*2 = 64 bits (unsigned)
@@ -1504,13 +1516,13 @@ void Stepper::apply_directions() {
f >>= 32; // Range 32 bits : f = t^3 (unsigned)
#endif
int64_t acc = (int64_t) bezier_F << 31; // Range 63 bits (signed)
acc += ((uint64_t) f >> 1) * (int64_t) bezier_C; // Range 29bits + 31 = 60bits (plus sign)
acc += ((uint32_t) f >> 1) * (int64_t) bezier_C; // Range 29bits + 31 = 60bits (plus sign)
f *= t; // Range 32*2 = 64 bits
f >>= 32; // Range 32 bits : f = t^3 (unsigned)
acc += ((uint64_t) f >> 1) * (int64_t) bezier_B; // Range 29bits + 31 = 60bits (plus sign)
acc += ((uint32_t) f >> 1) * (int64_t) bezier_B; // Range 29bits + 31 = 60bits (plus sign)
f *= t; // Range 32*2 = 64 bits
f >>= 32; // Range 32 bits : f = t^3 (unsigned)
acc += ((uint64_t) f >> 1) * (int64_t) bezier_A; // Range 28bits + 31 = 59bits (plus sign)
acc += ((uint32_t) f >> 1) * (int64_t) bezier_A; // Range 28bits + 31 = 59bits (plus sign)
acc >>= (31 + 7); // Range 24bits (plus sign)
return (int32_t) acc;
@@ -1525,14 +1537,7 @@ void Stepper::apply_directions() {
* Directly pulses the stepper motors at high frequency.
*/
extern "C" [[gnu::section(".ramcode")]] void TIMER0_IRQHandler() {
#ifndef __AVR__
// Disable interrupts, to avoid ISR preemption while we reprogram the period
// (AVR enters the ISR with global interrupts disabled, so no need to do it here)
hal.isr_off();
#endif
HAL_STEP_TIMER_ISR() {
HAL_timer_isr_prologue(MF_TIMER_STEP);
Stepper::isr();
@@ -1550,6 +1555,12 @@ void Stepper::isr() {
static hal_timer_t nextMainISR = 0; // Interval until the next main Stepper Pulse phase (0 = Now)
#ifndef __AVR__
// Disable interrupts, to avoid ISR preemption while we reprogram the period
// (AVR enters the ISR with global interrupts disabled, so no need to do it here)
hal.isr_off();
#endif
// Program timer compare for the maximum period, so it does NOT
// flag an interrupt while this ISR is running - So changes from small
// periods to big periods are respected and the timer does not reset to 0
@@ -1570,6 +1581,8 @@ void Stepper::isr() {
// We need this variable here to be able to use it in the following loop
hal_timer_t min_ticks;
do {
// Enable ISRs to reduce USART processing latency
hal.isr_on();
hal_timer_t interval = 0;
@@ -1590,9 +1603,6 @@ void Stepper::isr() {
NOLESS(nextBabystepISR, nextMainISR / 2); // TODO: Only look at axes enabled for baby-stepping
#endif
// Enable ISRs to reduce latency for higher priority ISRs, or all ISRs if no prioritization.
hal.isr_on();
interval = nextMainISR; // Interval is either some old nextMainISR or FTM_MIN_TICKS
TERN_(BABYSTEPPING, NOMORE(interval, nextBabystepISR)); // Come back early for Babystepping?
@@ -1621,9 +1631,6 @@ void Stepper::isr() {
if (is_babystep) nextBabystepISR = babystepping_isr();
#endif
// Enable ISRs to reduce latency for higher priority ISRs, or all ISRs if no prioritization.
hal.isr_on();
// ^== Time critical. NOTHING besides pulse generation should be above here!!!
if (!nextMainISR) nextMainISR = block_phase_isr(); // Manage acc/deceleration, get next block
@@ -1637,7 +1644,7 @@ void Stepper::isr() {
#endif
// Get the interval to the next ISR call
interval = _MIN(nextMainISR, uint64_t(HAL_TIMER_TYPE_MAX)); // Time until the next Pulse / Block phase
interval = _MIN(nextMainISR, uint32_t(HAL_TIMER_TYPE_MAX)); // Time until the next Pulse / Block phase
TERN_(INPUT_SHAPING_X, NOMORE(interval, ShapingQueue::peek_x())); // Time until next input shaping echo for X
TERN_(INPUT_SHAPING_Y, NOMORE(interval, ShapingQueue::peek_y())); // Time until next input shaping echo for Y
TERN_(INPUT_SHAPING_Z, NOMORE(interval, ShapingQueue::peek_z())); // Time until next input shaping echo for Z
@@ -1757,7 +1764,7 @@ void Stepper::isr() {
#if MINIMUM_STEPPER_PULSE || MAXIMUM_STEPPER_RATE
#define ISR_PULSE_CONTROL 1
#endif
#if ISR_PULSE_CONTROL && MULTISTEPPING_LIMIT > 1 && DISABLED(I2S_STEPPER_STREAM)
#if ISR_PULSE_CONTROL && DISABLED(I2S_STEPPER_STREAM)
#define ISR_MULTI_STEPS 1
#endif
@@ -1800,15 +1807,17 @@ void Stepper::pulse_phase_isr() {
if (TERN0(FREEZE_FEATURE, frozen)) return;
// Count of pending loops and events for this iteration
const uint64_t pending_events = step_event_count - step_events_completed;
const uint32_t pending_events = step_event_count - step_events_completed;
uint8_t events_to_do = _MIN(pending_events, steps_per_isr);
// Just update the value we will get at the end of the loop
step_events_completed += events_to_do;
TERN_(ISR_PULSE_CONTROL, USING_TIMED_PULSE());
// Take multiple steps per interrupt (For high speed moves)
TERN_(ISR_MULTI_STEPS, bool firstStep = true);
#if ISR_MULTI_STEPS
bool firstStep = true;
USING_TIMED_PULSE();
#endif
// Direct Stepping page?
const bool is_page = current_block->is_page();
@@ -1997,7 +2006,7 @@ void Stepper::pulse_phase_isr() {
if (!is_page) {
// Give the compiler a clue to store advance_divisor in registers for what follows
const uint64_t advance_divisor_cached = advance_divisor;
const uint32_t advance_divisor_cached = advance_divisor;
// Determine if pulses are needed
#if HAS_X_STEP
@@ -2113,7 +2122,7 @@ void Stepper::pulse_phase_isr() {
TERN_(I2S_STEPPER_STREAM, i2s_push_sample());
// TODO: need to deal with MINIMUM_STEPPER_PULSE over i2s
#if ISR_PULSE_CONTROL
#if ISR_MULTI_STEPS
START_TIMED_PULSE();
AWAIT_HIGH_PULSE();
#endif
@@ -2228,24 +2237,24 @@ void Stepper::pulse_phase_isr() {
#endif // HAS_ZV_SHAPING
// Calculate timer interval, with all limits applied.
hal_timer_t Stepper::calc_timer_interval(uint64_t step_rate) {
constexpr uint64_t min_step_rate = MINIMAL_STEP_RATE;
hal_timer_t Stepper::calc_timer_interval(uint32_t step_rate) {
#ifdef CPU_32_BIT
// A fast processor can just do integer division
return step_rate > min_step_rate ? uint64_t(STEPPER_TIMER_RATE) / step_rate : HAL_TIMER_TYPE_MAX;
constexpr uint32_t min_step_rate = uint32_t(STEPPER_TIMER_RATE) / HAL_TIMER_TYPE_MAX;
return step_rate > min_step_rate ? uint32_t(STEPPER_TIMER_RATE) / step_rate : HAL_TIMER_TYPE_MAX;
#else
constexpr uint32_t min_step_rate = (F_CPU) / 500000U; // i.e., 32 or 40
if (step_rate >= 0x0800) { // higher step rate
// AVR is able to keep up at around 65kHz Stepping ISR rate at most.
// So values for step_rate > 65535 might as well be truncated.
// Handle it as quickly as possible. i.e., assume highest byte is zero
// because non-zero would represent a step rate far beyond AVR capabilities.
if (uint8_t(step_rate >> 16))
return uint64_t(STEPPER_TIMER_RATE) / 0x10000;
return uint32_t(STEPPER_TIMER_RATE) / 0x10000;
const uintptr_t table_address = uintptr_t(&speed_lookuptable_fast[uint8_t(step_rate >> 8)]);
const uint16_t base = uint16_t(pgm_read_word(table_address));
@@ -2265,8 +2274,8 @@ hal_timer_t Stepper::calc_timer_interval(uint64_t step_rate) {
}
#if ENABLED(NONLINEAR_EXTRUSION)
void Stepper::calc_nonlinear_e(uint64_t step_rate) {
const uint64_t velocity = ne_scale * step_rate; // Scale step_rate first so all intermediate values stay in range of 8.24 fixed point math
void Stepper::calc_nonlinear_e(uint32_t step_rate) {
const uint32_t velocity = ne_scale * step_rate; // Scale step_rate first so all intermediate values stay in range of 8.24 fixed point math
int32_t vd = (((int64_t)ne_fix.A * velocity) >> 24) + (((((int64_t)ne_fix.B * velocity) >> 24) * velocity) >> 24);
NOLESS(vd, 0);
@@ -2275,19 +2284,19 @@ hal_timer_t Stepper::calc_timer_interval(uint64_t step_rate) {
#endif
// Get the timer interval and the number of loops to perform per tick
hal_timer_t Stepper::calc_multistep_timer_interval(uint64_t step_rate) {
hal_timer_t Stepper::calc_multistep_timer_interval(uint32_t step_rate) {
#if ENABLED(OLD_ADAPTIVE_MULTISTEPPING)
#if MULTISTEPPING_LIMIT == 1
// Just make sure the step rate is doable
NOMORE(step_rate, uint64_t(MAX_STEP_ISR_FREQUENCY_1X));
NOMORE(step_rate, uint32_t(MAX_STEP_ISR_FREQUENCY_1X));
#else
// The stepping frequency limits for each multistepping rate
static const uint64_t limit[] PROGMEM = {
static const uint32_t limit[] PROGMEM = {
( MAX_STEP_ISR_FREQUENCY_1X )
, (((F_CPU) / ISR_EXECUTION_CYCLES(1)) >> 1)
#if MULTISTEPPING_LIMIT >= 4
@@ -2312,7 +2321,7 @@ hal_timer_t Stepper::calc_multistep_timer_interval(uint64_t step_rate) {
// Find a doable step rate using multistepping
uint8_t multistep = 1;
for (uint8_t i = 0; i < COUNT(limit) && step_rate > uint64_t(pgm_read_dword(&limit[i])); ++i) {
for (uint8_t i = 0; i < COUNT(limit) && step_rate > uint32_t(pgm_read_dword(&limit[i])); ++i) {
step_rate >>= 1;
multistep <<= 1;
}
@@ -2467,11 +2476,11 @@ hal_timer_t Stepper::block_phase_isr() {
// Step events not completed yet...
// Are we in acceleration phase ?
if (step_events_completed < accelerate_before) { // Calculate new timer value
if (step_events_completed <= accelerate_until) { // Calculate new timer value
#if ENABLED(S_CURVE_ACCELERATION)
// Get the next speed to use (Jerk limited!)
uint64_t acc_step_rate = acceleration_time < current_block->acceleration_time
uint32_t acc_step_rate = acceleration_time < current_block->acceleration_time
? _eval_bezier_curve(acceleration_time)
: current_block->cruise_rate;
#else
@@ -2484,7 +2493,6 @@ hal_timer_t Stepper::block_phase_isr() {
// step_rate to timer interval and steps per stepper isr
interval = calc_multistep_timer_interval(acc_step_rate << oversampling_factor);
acceleration_time += interval;
deceleration_time = 0; // Reset since we're doing acceleration first.
#if ENABLED(NONLINEAR_EXTRUSION)
calc_nonlinear_e(acc_step_rate << oversampling_factor);
@@ -2492,7 +2500,7 @@ hal_timer_t Stepper::block_phase_isr() {
#if ENABLED(LIN_ADVANCE)
if (la_active) {
const uint64_t la_step_rate = la_advance_steps < current_block->max_adv_steps ? current_block->la_advance_rate : 0;
const uint32_t la_step_rate = la_advance_steps < current_block->max_adv_steps ? current_block->la_advance_rate : 0;
la_interval = calc_timer_interval((acc_step_rate + la_step_rate) >> current_block->la_scaling);
}
#endif
@@ -2506,13 +2514,16 @@ hal_timer_t Stepper::block_phase_isr() {
* Laser power variables are calulated and stored in this block by the planner code.
* trap_ramp_active_pwr - the active power in this block across accel or decel trap steps.
* trap_ramp_entry_incr - holds the precalculated value to increase the current power per accel step.
*
* Apply the starting active power and then increase power per step by the trap_ramp_entry_incr value if positive.
*/
#if ENABLED(LASER_POWER_TRAP)
if (cutter.cutter_mode == CUTTER_MODE_CONTINUOUS) {
if (planner.laser_inline.status.isPowered && planner.laser_inline.status.isEnabled) {
if (current_block->laser.trap_ramp_entry_incr > 0) {
cutter.apply_power(current_block->laser.trap_ramp_active_pwr);
current_block->laser.trap_ramp_active_pwr += current_block->laser.trap_ramp_entry_incr * steps_per_isr;
current_block->laser.trap_ramp_active_pwr += current_block->laser.trap_ramp_entry_incr;
}
}
// Not a powered move.
@@ -2521,24 +2532,30 @@ hal_timer_t Stepper::block_phase_isr() {
#endif
}
// Are we in Deceleration phase ?
else if (step_events_completed >= decelerate_start) {
uint64_t step_rate;
else if (step_events_completed > decelerate_after) {
uint32_t step_rate;
#if ENABLED(S_CURVE_ACCELERATION)
// If this is the 1st time we process the 2nd half of the trapezoid...
if (!bezier_2nd_half) {
// Initialize the Bézier speed curve
_calc_bezier_curve_coeffs(current_block->cruise_rate, current_block->final_rate, current_block->deceleration_time_inverse);
bezier_2nd_half = true;
// The first point starts at cruise rate. Just save evaluation of the Bézier curve
step_rate = current_block->cruise_rate;
}
// Calculate the next speed to use
step_rate = deceleration_time < current_block->deceleration_time
? _eval_bezier_curve(deceleration_time)
: current_block->final_rate;
else {
// Calculate the next speed to use
step_rate = deceleration_time < current_block->deceleration_time
? _eval_bezier_curve(deceleration_time)
: current_block->final_rate;
}
#else
// Using the old trapezoidal control
step_rate = STEP_MULTIPLY(deceleration_time, current_block->acceleration_rate);
if (step_rate < acc_step_rate) {
if (step_rate < acc_step_rate) { // Still decelerating?
step_rate = acc_step_rate - step_rate;
NOLESS(step_rate, current_block->final_rate);
}
@@ -2557,7 +2574,7 @@ hal_timer_t Stepper::block_phase_isr() {
#if ENABLED(LIN_ADVANCE)
if (la_active) {
const uint64_t la_step_rate = la_advance_steps > current_block->final_adv_steps ? current_block->la_advance_rate : 0;
const uint32_t la_step_rate = la_advance_steps > current_block->final_adv_steps ? current_block->la_advance_rate : 0;
if (la_step_rate != step_rate) {
const bool forward_e = la_step_rate < step_rate;
la_interval = calc_timer_interval((forward_e ? step_rate - la_step_rate : la_step_rate - step_rate) >> current_block->la_scaling);
@@ -2580,12 +2597,15 @@ hal_timer_t Stepper::block_phase_isr() {
}
#endif // LIN_ADVANCE
// Adjust Laser Power - Decelerating
/**
* Adjust Laser Power - Decelerating
* trap_ramp_entry_decr - holds the precalculated value to decrease the current power per decel step.
*/
#if ENABLED(LASER_POWER_TRAP)
if (cutter.cutter_mode == CUTTER_MODE_CONTINUOUS) {
if (planner.laser_inline.status.isPowered && planner.laser_inline.status.isEnabled) {
if (current_block->laser.trap_ramp_exit_decr > 0) {
current_block->laser.trap_ramp_active_pwr -= current_block->laser.trap_ramp_exit_decr * steps_per_isr;
current_block->laser.trap_ramp_active_pwr -= current_block->laser.trap_ramp_exit_decr;
cutter.apply_power(current_block->laser.trap_ramp_active_pwr);
}
// Not a powered move.
@@ -2601,9 +2621,6 @@ hal_timer_t Stepper::block_phase_isr() {
if (ticks_nominal == 0) {
// step_rate to timer interval and loops for the nominal speed
ticks_nominal = calc_multistep_timer_interval(current_block->nominal_rate << oversampling_factor);
// Prepare for deceleration
IF_DISABLED(S_CURVE_ACCELERATION, acc_step_rate = current_block->nominal_rate);
deceleration_time = ticks_nominal / 2;
#if ENABLED(NONLINEAR_EXTRUSION)
calc_nonlinear_e(current_block->nominal_rate << oversampling_factor);
@@ -2613,20 +2630,6 @@ hal_timer_t Stepper::block_phase_isr() {
if (la_active)
la_interval = calc_timer_interval(current_block->nominal_rate >> current_block->la_scaling);
#endif
// Adjust Laser Power - Cruise
#if ENABLED(LASER_POWER_TRAP)
if (cutter.cutter_mode == CUTTER_MODE_CONTINUOUS) {
if (planner.laser_inline.status.isPowered && planner.laser_inline.status.isEnabled) {
if (current_block->laser.trap_ramp_entry_incr > 0) {
current_block->laser.trap_ramp_active_pwr = current_block->laser.power;
cutter.apply_power(current_block->laser.power);
}
}
// Not a powered move.
else cutter.apply_power(0);
}
#endif
}
// The timer interval is just the nominal value for the nominal speed
@@ -2639,7 +2642,7 @@ hal_timer_t Stepper::block_phase_isr() {
*/
#if ENABLED(LASER_POWER_TRAP)
if (cutter.cutter_mode == CUTTER_MODE_CONTINUOUS) {
if (step_events_completed + 1 == accelerate_before) {
if (step_events_completed + 1 == accelerate_until) {
if (planner.laser_inline.status.isPowered && planner.laser_inline.status.isEnabled) {
if (current_block->laser.trap_ramp_entry_incr > 0) {
current_block->laser.trap_ramp_active_pwr = current_block->laser.power;
@@ -2742,85 +2745,11 @@ hal_timer_t Stepper::block_phase_isr() {
}
#endif
// Flag all moving axes for proper endstop handling
// Set flags for all moving axes, accounting for kinematics
set_axis_moved_for_current_block();
#if IS_CORE
// Define conditions for checking endstops
#define S_(N) current_block->steps[CORE_AXIS_##N]
#define D_(N) current_block->direction_bits[CORE_AXIS_##N]
#endif
#if CORE_IS_XY || CORE_IS_XZ
/**
* Head direction in -X axis for CoreXY and CoreXZ bots.
*
* If steps differ, both axes are moving.
* If DeltaA == -DeltaB, the movement is only in the 2nd axis (Y or Z, handled below)
* If DeltaA == DeltaB, the movement is only in the 1st axis (X)
*/
#if ANY(COREXY, COREXZ)
#define X_CMP(A,B) ((A)==(B))
#else
#define X_CMP(A,B) ((A)!=(B))
#endif
#define X_MOVE_TEST ( S_(1) != S_(2) || (S_(1) > 0 && X_CMP(D_(1),D_(2))) )
#elif ENABLED(MARKFORGED_XY)
#define X_MOVE_TEST (current_block->steps.a != current_block->steps.b)
#else
#define X_MOVE_TEST !!current_block->steps.a
#endif
#if CORE_IS_XY || CORE_IS_YZ
/**
* Head direction in -Y axis for CoreXY / CoreYZ bots.
*
* If steps differ, both axes are moving
* If DeltaA == DeltaB, the movement is only in the 1st axis (X or Y)
* If DeltaA == -DeltaB, the movement is only in the 2nd axis (Y or Z)
*/
#if ANY(COREYX, COREYZ)
#define Y_CMP(A,B) ((A)==(B))
#else
#define Y_CMP(A,B) ((A)!=(B))
#endif
#define Y_MOVE_TEST ( S_(1) != S_(2) || (S_(1) > 0 && Y_CMP(D_(1),D_(2))) )
#elif ENABLED(MARKFORGED_YX)
#define Y_MOVE_TEST (current_block->steps.a != current_block->steps.b)
#else
#define Y_MOVE_TEST !!current_block->steps.b
#endif
#if CORE_IS_XZ || CORE_IS_YZ
/**
* Head direction in -Z axis for CoreXZ or CoreYZ bots.
*
* If steps differ, both axes are moving
* If DeltaA == DeltaB, the movement is only in the 1st axis (X or Y, already handled above)
* If DeltaA == -DeltaB, the movement is only in the 2nd axis (Z)
*/
#if ANY(COREZX, COREZY)
#define Z_CMP(A,B) ((A)==(B))
#else
#define Z_CMP(A,B) ((A)!=(B))
#endif
#define Z_MOVE_TEST ( S_(1) != S_(2) || (S_(1) > 0 && Z_CMP(D_(1),D_(2))) )
#else
#define Z_MOVE_TEST !!current_block->steps.c
#endif
AxisBits didmove;
NUM_AXIS_CODE(
if (X_MOVE_TEST) didmove.a = true,
if (Y_MOVE_TEST) didmove.b = true,
if (Z_MOVE_TEST) didmove.c = true,
if (!!current_block->steps.i) didmove.i = true,
if (!!current_block->steps.j) didmove.j = true,
if (!!current_block->steps.k) didmove.k = true,
if (!!current_block->steps.u) didmove.u = true,
if (!!current_block->steps.v) didmove.v = true,
if (!!current_block->steps.w) didmove.w = true
);
axis_did_move = didmove;
// No acceleration / deceleration time elapsed so far
acceleration_time = deceleration_time = 0;
#if ENABLED(ADAPTIVE_STEP_SMOOTHING)
// Nonlinear Extrusion needs at least 2x oversampling to permit increase of E step rate
@@ -2829,7 +2758,7 @@ hal_timer_t Stepper::block_phase_isr() {
// Decide if axis smoothing is possible
if (stepper.adaptive_step_smoothing_enabled) {
uint64_t max_rate = current_block->nominal_rate; // Get the step event rate
uint32_t max_rate = current_block->nominal_rate; // Get the step event rate
while (max_rate < MIN_STEP_ISR_FREQUENCY) { // As long as more ISRs are possible...
max_rate <<= 1; // Try to double the rate
if (max_rate < MIN_STEP_ISR_FREQUENCY) // Don't exceed the estimated ISR limit
@@ -2884,8 +2813,8 @@ hal_timer_t Stepper::block_phase_isr() {
step_events_completed = 0;
// Compute the acceleration and deceleration points
accelerate_before = current_block->accelerate_before << oversampling_factor;
decelerate_start = current_block->decelerate_start << oversampling_factor;
accelerate_until = current_block->accelerate_until << oversampling_factor;
decelerate_after = current_block->decelerate_after << oversampling_factor;
TERN_(MIXING_EXTRUDER, mixer.stepper_setup(current_block->b_color));
@@ -2971,8 +2900,7 @@ hal_timer_t Stepper::block_phase_isr() {
// Calculate the initial timer interval
interval = calc_multistep_timer_interval(current_block->initial_rate << oversampling_factor);
// Initialize ac/deceleration time as if half the time passed.
acceleration_time = deceleration_time = interval / 2;
acceleration_time += interval;
#if ENABLED(NONLINEAR_EXTRUSION)
calc_nonlinear_e(current_block->initial_rate << oversampling_factor);
@@ -2980,7 +2908,7 @@ hal_timer_t Stepper::block_phase_isr() {
#if ENABLED(LIN_ADVANCE)
if (la_active) {
const uint64_t la_step_rate = la_advance_steps < current_block->max_adv_steps ? current_block->la_advance_rate : 0;
const uint32_t la_step_rate = la_advance_steps < current_block->max_adv_steps ? current_block->la_advance_rate : 0;
la_interval = calc_timer_interval((current_block->initial_rate + la_step_rate) >> current_block->la_scaling);
}
#endif
@@ -3400,7 +3328,7 @@ void Stepper::init() {
const bool was_on = hal.isr_state();
hal.isr_off();
const shaping_time_t delay = freq ? float(uint64_t(STEPPER_TIMER_RATE) / 2) / freq : shaping_time_t(-1);
const shaping_time_t delay = freq ? float(uint32_t(STEPPER_TIMER_RATE) / 2) / freq : shaping_time_t(-1);
#define SHAPING_SET_FREQ_FOR_AXIS(AXISN, AXISL) \
if (axis == AXISN) { \
ShapingQueue::set_delay(AXISN, delay); \
@@ -3885,7 +3813,7 @@ void Stepper::report_positions() {
#if EXTRA_CYCLES_BABYSTEP > 20
#define _SAVE_START() const hal_timer_t pulse_start = HAL_timer_get_count(MF_TIMER_PULSE)
#define _PULSE_WAIT() while (EXTRA_CYCLES_BABYSTEP > uint64_t(HAL_timer_get_count(MF_TIMER_PULSE) - pulse_start) * (PULSE_TIMER_PRESCALE)) { /* nada */ }
#define _PULSE_WAIT() while (EXTRA_CYCLES_BABYSTEP > uint32_t(HAL_timer_get_count(MF_TIMER_PULSE) - pulse_start) * (PULSE_TIMER_PRESCALE)) { /* nada */ }
#else
#define _SAVE_START() NOOP
#if EXTRA_CYCLES_BABYSTEP > 0
+19 -19
View File
@@ -309,11 +309,11 @@ class Stepper {
#endif
#define MOTOR_CURRENT_COUNT 3
#elif HAS_MOTOR_CURRENT_SPI
static constexpr uint64_t digipot_count[] = DIGIPOT_MOTOR_CURRENT;
static constexpr uint32_t digipot_count[] = DIGIPOT_MOTOR_CURRENT;
#define MOTOR_CURRENT_COUNT COUNT(Stepper::digipot_count)
#endif
static bool initialized;
static uint64_t motor_current_setting[MOTOR_CURRENT_COUNT]; // Initialized by settings.load()
static uint32_t motor_current_setting[MOTOR_CURRENT_COUNT]; // Initialized by settings.load()
#endif
// Last-moved extruder, as set when the last movement was fetched from planner
@@ -363,7 +363,7 @@ class Stepper {
;
#endif
static uint64_t acceleration_time, deceleration_time; // time measured in Stepper Timer ticks
static uint32_t acceleration_time, deceleration_time; // time measured in Stepper Timer ticks
#if MULTISTEPPING_LIMIT == 1
static constexpr uint8_t steps_per_isr = 1; // Count of steps to perform per Stepper ISR call
@@ -384,10 +384,10 @@ class Stepper {
// Delta error variables for the Bresenham line tracer
static xyze_long_t delta_error;
static xyze_long_t advance_dividend;
static uint64_t advance_divisor,
static uint32_t advance_divisor,
step_events_completed, // The number of step events executed in the current block
accelerate_before, // The point from where we need to stop acceleration
decelerate_start, // The point from where we need to start decelerating
accelerate_until, // The point from where we need to stop acceleration
decelerate_after, // The point from where we need to start decelerating
step_event_count; // The total event count for the current block
#if ANY(HAS_MULTI_EXTRUDER, MIXING_EXTRUDER)
@@ -400,7 +400,7 @@ class Stepper {
static int32_t bezier_A, // A coefficient in Bézier speed curve
bezier_B, // B coefficient in Bézier speed curve
bezier_C; // C coefficient in Bézier speed curve
static uint64_t bezier_F, // F/free coefficient in Bézier speed curve
static uint32_t bezier_F, // F/free coefficient in Bézier speed curve
bezier_AV; // AV coefficient in Bézier speed curve
#ifdef __AVR__
static bool A_negative; // If A coefficient was negative
@@ -432,7 +432,7 @@ class Stepper {
#if ENABLED(NONLINEAR_EXTRUSION)
static int32_t ne_edividend;
static uint64_t ne_scale;
static uint32_t ne_scale;
static ne_fix_t ne_fix;
#endif
@@ -447,7 +447,7 @@ class Stepper {
static hal_timer_t ticks_nominal;
#if DISABLED(S_CURVE_ACCELERATION)
static uint64_t acc_step_rate; // needed for deceleration start point
static uint32_t acc_step_rate; // needed for deceleration start point
#endif
// Exact steps at which an endstop was triggered
@@ -478,21 +478,21 @@ class Stepper {
}
// The ISR scheduler
FORCE_INLINE static void isr();
static void isr();
// The stepper pulse ISR phase
FORCE_INLINE static void pulse_phase_isr();
static void pulse_phase_isr();
// The stepper block processing ISR phase
FORCE_INLINE static hal_timer_t block_phase_isr();
static hal_timer_t block_phase_isr();
#if HAS_ZV_SHAPING
FORCE_INLINE static void shaping_isr();
static void shaping_isr();
#endif
#if ENABLED(LIN_ADVANCE)
// The Linear advance ISR phase
FORCE_INLINE static void advance_isr();
static void advance_isr();
#endif
#if ENABLED(BABYSTEPPING)
@@ -677,21 +677,21 @@ class Stepper {
static void _set_position(const abce_long_t &spos);
// Calculate the timing interval for the given step rate
static hal_timer_t calc_timer_interval(uint64_t step_rate);
static hal_timer_t calc_timer_interval(uint32_t step_rate);
// Calculate timing interval and steps-per-ISR for the given step rate
static hal_timer_t calc_multistep_timer_interval(uint64_t step_rate);
static hal_timer_t calc_multistep_timer_interval(uint32_t step_rate);
// Evaluate axis motions and set bits in axis_did_move
static void set_axis_moved_for_current_block();
#if ENABLED(NONLINEAR_EXTRUSION)
static void calc_nonlinear_e(uint64_t step_rate);
static void calc_nonlinear_e(uint32_t step_rate);
#endif
#if ENABLED(S_CURVE_ACCELERATION)
static void _calc_bezier_curve_coeffs(const int32_t v0, const int32_t v1, const uint64_t av);
static int32_t _eval_bezier_curve(const uint64_t curr_step);
static void _calc_bezier_curve_coeffs(const int32_t v0, const int32_t v1, const uint32_t av);
static int32_t _eval_bezier_curve(const uint32_t curr_step);
#endif
#if HAS_MOTOR_CURRENT_SPI || HAS_MOTOR_CURRENT_PWM
+32 -29
View File
@@ -32,7 +32,7 @@
#define LED_PIN P3_18 // PWM0_3
// EXTRA PINS
#define FIL_RUNOUT_PIN P1_12
//#define FIL_RUNOUT_PIN P1_12
// DRIVERS EXTRA PINS
#define DRIVERS_SCK P1_20
@@ -99,29 +99,29 @@
#define E1_CS_PIN P1_18
#define E1_DIAG_PIN P2_19
#define E2_STEP_PIN P3_26
#define E2_DIR_PIN P2_25
#define E2_ENABLE_PIN P3_25
#define E2_CS_PIN P3_24
#define E2_DIAG_PIN P2_26
#define X2_STEP_PIN P3_26
#define X2_DIR_PIN P2_25
#define X2_ENABLE_PIN P3_25
#define X2_CS_PIN P3_24
#define X2_DIAG_PIN P2_26
#define E3_STEP_PIN P4_19
#define E3_DIR_PIN P4_20
#define E3_ENABLE_PIN P4_26
#define E3_CS_PIN P4_21
#define E3_DIAG_PIN P0_22
#define Y2_STEP_PIN P4_19
#define Y2_DIR_PIN P4_20
#define Y2_ENABLE_PIN P4_26
#define Y2_CS_PIN P4_21
#define Y2_DIAG_PIN P0_22
#define E4_STEP_PIN P4_17
#define E4_DIR_PIN P4_18
#define E4_ENABLE_PIN P4_05
#define E4_CS_PIN P2_12
#define E4_DIAG_PIN P2_11
#define Z2_STEP_PIN P4_17
#define Z2_DIR_PIN P4_18
#define Z2_ENABLE_PIN P4_05
#define Z2_CS_PIN P2_12
#define Z2_DIAG_PIN P2_11
#define E5_STEP_PIN P0_11
#define E5_DIR_PIN P2_15
#define E5_ENABLE_PIN P4_04
#define E5_CS_PIN P4_16
#define E5_DIAG_PIN P2_13
#define Z3_STEP_PIN P0_11
#define Z3_DIR_PIN P2_15
#define Z3_ENABLE_PIN P4_04
#define Z3_CS_PIN P4_16
#define Z3_DIAG_PIN P2_13
#define E6_STEP_PIN P2_28
#define E6_DIR_PIN P0_28
@@ -153,14 +153,14 @@
#define E0_SERIAL_RX_PIN P4_00
#define E1_SERIAL_TX_PIN P1_18
#define E1_SERIAL_RX_PIN P1_18
#define E2_SERIAL_TX_PIN P3_24
#define E2_SERIAL_RX_PIN P3_24
#define E3_SERIAL_TX_PIN P4_21
#define E3_SERIAL_RX_PIN P4_21
#define E4_SERIAL_TX_PIN P2_12
#define E4_SERIAL_RX_PIN P2_12
#define E5_SERIAL_TX_PIN P4_16
#define E5_SERIAL_RX_PIN P4_16
#define X2_SERIAL_TX_PIN P3_24
#define X2_SERIAL_RX_PIN P3_24
#define Y2_SERIAL_TX_PIN P4_21
#define Y2_SERIAL_RX_PIN P4_21
#define Z2_SERIAL_TX_PIN P2_12
#define Z2_SERIAL_RX_PIN P2_12
#define Z3_SERIAL_TX_PIN P4_16
#define Z3_SERIAL_RX_PIN P4_16
#define E6_SERIAL_TX_PIN P0_27
#define E6_SERIAL_RX_PIN P0_27
#define E7_SERIAL_TX_PIN P2_29
@@ -181,6 +181,7 @@
#define TEMP_3_PIN P0_26
#define TEMP_BED_PIN P1_31
#define TEMP_CHAMBER_PIN TEMP_2_PIN
//
// Heaters / Fans
//
@@ -191,6 +192,8 @@
#define HEATER_3_PIN P1_09
#define HEATER_BED_PIN P4_23
#define HEATER_CHAMBER_PIN HEATER_2_PIN
#define FAN0_PIN P3_08
#define FAN1_PIN P3_00
#define FAN2_PIN P3_27 //PWM1_4
+163 -151
View File
@@ -22,31 +22,11 @@
#pragma once
/**
* Arduino Mega with RAMPS v1.4 (or v1.3) pin assignments
*
* Applies to the following boards:
*
* RAMPS_14_EFB (Hotend, Fan, Bed)
* RAMPS_14_EEB (Hotend0, Hotend1, Bed)
* RAMPS_14_EFF (Hotend, Fan0, Fan1)
* RAMPS_14_EEF (Hotend0, Hotend1, Fan)
* RAMPS_14_SF (Spindle, Controller Fan)
*
* RAMPS_13_EFB (Hotend, Fan, Bed)
* RAMPS_13_EEB (Hotend0, Hotend1, Bed)
* RAMPS_13_EFF (Hotend, Fan0, Fan1)
* RAMPS_13_EEF (Hotend0, Hotend1, Fan)
* RAMPS_13_SF (Spindle, Controller Fan)
*
* Other pins_MYBOARD.h files may override these defaults
*
* Differences between
* RAMPS_13 | RAMPS_14
* 7 | 11
* Native with a RAMPS like board with additional pins
*/
#ifndef BOARD_INFO_NAME
#define BOARD_INFO_NAME "RAMPS 1.4"
#define BOARD_INFO_NAME "RAMPS Native"
#endif
#ifndef DEFAULT_MACHINE_NAME
@@ -60,28 +40,24 @@
//
// Servos
//
#ifdef IS_RAMPS_13
#define SERVO0_PIN 7 // RAMPS_13 // Will conflict with BTN_EN2 on LCD_I2C_VIKI
#else
#define SERVO0_PIN 11
#endif
#define SERVO1_PIN 6
#define SERVO2_PIN 5
#define SERVO0_PIN 151
#define SERVO1_PIN 152
#define SERVO2_PIN 153
#ifndef SERVO3_PIN
#define SERVO3_PIN 4
#define SERVO3_PIN 154
#endif
//
// Limit Switches
//
#define X_MIN_PIN 3
#define X_MIN_PIN 155
#ifndef X_MAX_PIN
#define X_MAX_PIN 2
#define X_MAX_PIN 156
#endif
#define Y_MIN_PIN 14
#define Y_MAX_PIN 15
#define Z_MIN_PIN 18
#define Z_MAX_PIN 19
#define Y_MIN_PIN 157
#define Y_MAX_PIN 158
#define Z_MIN_PIN 159
#define Z_MAX_PIN 160
//
// Z Probe (when not Z_MIN_PIN)
@@ -128,24 +104,60 @@
#define E1_CS_PIN 44
#endif
#define Z4_STEP_PIN 13
#define Z4_DIR_PIN 71
#define Z4_ENABLE_PIN 12
#define E2_STEP_PIN 100
#define E2_DIR_PIN 101
#define E2_ENABLE_PIN 102
#ifndef E2_CS_PIN
#define E2_CS_PIN 103
#endif
#define Z2_STEP_PIN 4
#define Z2_DIR_PIN 5
#define Z2_ENABLE_PIN 6
#define E3_STEP_PIN 104
#define E3_DIR_PIN 105
#define E3_ENABLE_PIN 106
#ifndef E3_CS_PIN
#define E3_CS_PIN 107
#endif
#define Z3_STEP_PIN 12
#define Z3_DIR_PIN 40
#define Z3_ENABLE_PIN 44
#define E4_STEP_PIN 108
#define E4_DIR_PIN 109
#define E4_ENABLE_PIN 110
#ifndef E4_CS_PIN
#define E4_CS_PIN 111
#endif
#define E5_STEP_PIN 112
#define E5_DIR_PIN 113
#define E5_ENABLE_PIN 114
#ifndef E5_CS_PIN
#define E5_CS_PIN 115
#endif
#define E6_STEP_PIN 116
#define E6_DIR_PIN 117
#define E6_ENABLE_PIN 118
#ifndef E6_CS_PIN
#define E6_CS_PIN 119
#endif
#define E7_STEP_PIN 120
#define E7_DIR_PIN 121
#define E7_ENABLE_PIN 122
#ifndef E7_CS_PIN
#define E7_CS_PIN 123
#endif
//
// Temperature Sensors
//
#define TEMP_0_PIN 0 // Analog Input
#define TEMP_1_PIN 1 // Analog Input
#define TEMP_BED_PIN 2 // Analog Input
#define TEMP_2_PIN 2 // Analog Input
#define TEMP_3_PIN 3 // Analog Input
#define TEMP_4_PIN 4 // Analog Input
#define TEMP_5_PIN 5 // Analog Input
#define TEMP_6_PIN 6 // Analog Input
#define TEMP_7_PIN 7 // Analog Input
#define TEMP_BED_PIN 8 // Analog Input
// SPI for MAX Thermocouple
#if !HAS_MEDIA
@@ -157,55 +169,33 @@
//
// Heaters / Fans
//
#ifndef MOSFET_A_PIN
#define MOSFET_A_PIN 10
#endif
#ifndef MOSFET_B_PIN
#define MOSFET_B_PIN 9
#endif
#ifndef MOSFET_C_PIN
#define MOSFET_C_PIN 8
#endif
#ifndef MOSFET_D_PIN
#define MOSFET_D_PIN -1
#endif
#define HEATER_0_PIN MOSFET_A_PIN
#if FET_ORDER_EFB // Hotend, Fan, Bed
#define FAN0_PIN MOSFET_B_PIN
#define HEATER_BED_PIN MOSFET_C_PIN
#elif FET_ORDER_EEF // Hotend, Hotend, Fan
#define HEATER_1_PIN MOSFET_B_PIN
#define FAN0_PIN MOSFET_C_PIN
#elif FET_ORDER_EEB // Hotend, Hotend, Bed
#define HEATER_1_PIN MOSFET_B_PIN
#define HEATER_BED_PIN MOSFET_C_PIN
#elif FET_ORDER_EFF // Hotend, Fan, Fan
#define FAN0_PIN MOSFET_B_PIN
#define FAN1_PIN MOSFET_C_PIN
#elif FET_ORDER_SF // Spindle, Fan
#define FAN0_PIN MOSFET_C_PIN
#else // Non-specific are "EFB" (i.e., "EFBF" or "EFBE")
#define FAN0_PIN MOSFET_B_PIN
#define HEATER_BED_PIN MOSFET_C_PIN
#if HOTENDS == 1 && DISABLED(HEATERS_PARALLEL)
#define FAN1_PIN MOSFET_D_PIN
#else
#define HEATER_1_PIN MOSFET_D_PIN
#endif
#endif
#define HEATER_0_PIN 10
#define HEATER_1_PIN 9
#define HEATER_2_PIN 8
#define HEATER_3_PIN 125
#define HEATER_4_PIN 126
#define HEATER_5_PIN 127
#define HEATER_6_PIN 128
#define HEATER_7_PIN 129
#define HEATER_BED_PIN 108
#ifndef FAN0_PIN
#define FAN0_PIN 4 // IO pin. Buffer needed
#define FAN0_PIN 161 // IO pin. Buffer needed
#endif
#define FAN1_PIN 162 // IO pin. Buffer needed
#define FAN2_PIN 163 // IO pin. Buffer needed
#define FAN3_PIN 164 // IO pin. Buffer needed
#define FAN4_PIN 165 // IO pin. Buffer needed
#define FAN5_PIN 166 // IO pin. Buffer needed
#define FAN6_PIN 167 // IO pin. Buffer needed
#define FAN7_PIN 168 // IO pin. Buffer needed
//
// Misc. Functions
//
#define SDSS 53
#define LED_PIN 13
#define NEOPIXEL_PIN 71
#define BOARD_NEOPIXEL_PIN 71
#ifndef FILWIDTH_PIN
#define FILWIDTH_PIN 5 // Analog Input on AUX2
@@ -383,9 +373,37 @@
#endif
#endif
//////////////////////////
// LCDs and Controllers //
//////////////////////////
/** Faux Expansion Headers
* ------ ------
* (BEEP) 37 | 1 2 | 35 (ENC) (MISO) 50 | 1 2 | 52 (SCK)
* (LCD_EN) 17 | 3 4 | 16 (LCD_RS) (EN1) 31 | 3 4 | 53 (SDSS)
* (LCD_D4) 23 5 6 | 25 (LCD_D5) (EN2) 33 5 6 | 51 (MOSI)
* (LCD_D6) 27 | 7 8 | 29 (LCD_D7) (SD_DET) 49 | 7 8 | 41 (KILL)
* -- | 9 10 | -- -- | 9 10 | --
* ------ ------
* EXP1 EXP2
*/
#define EXP1_01_PIN 37 // BEEPER
#define EXP1_02_PIN 35 // ENC
#define EXP1_03_PIN 17 // LCD_EN
#define EXP1_04_PIN 16 // LCD_RS
#define EXP1_05_PIN 23 // LCD_D4
#define EXP1_06_PIN 25 // LCD_D5
#define EXP1_07_PIN 27 // LCD_D6
#define EXP1_08_PIN 29 // LCD_D7
#define EXP2_01_PIN 50 // MISO
#define EXP2_02_PIN 52 // SCK
#define EXP2_03_PIN 31 // EN1
#define EXP2_04_PIN 53 // SDSS
#define EXP2_05_PIN 33 // EN2
#define EXP2_06_PIN 51 // MOSI
#define EXP2_07_PIN 49 // SD_DET
#define EXP2_08_PIN 41 // KILL
//
// LCD / Controller
//
#if ANY(TFT_COLOR_UI, TFT_CLASSIC_UI, TFT_LVGL_UI)
@@ -397,10 +415,11 @@
#define TFT_MOSI_PIN SD_MOSI_PIN
#define LCD_USE_DMA_SPI
#define BEEPER_PIN 42
#define BTN_ENC 59
#define BTN_EN1 40
#define BTN_EN2 63
#define BTN_ENC 59
#define BEEPER_PIN 42
#define TOUCH_CS_PIN 33
@@ -485,9 +504,9 @@
//
#if ENABLED(REPRAPWORLD_GRAPHICAL_LCD)
#define LCD_PINS_RS 49 // CS chip select /SS chip slave select
#define LCD_PINS_EN 51 // SID (MOSI)
#define LCD_PINS_D4 52 // SCK (CLK) clock
#define LCD_PINS_RS EXP2_07_PIN // CS chip select /SS chip slave select
#define LCD_PINS_EN EXP2_06_PIN // SID (MOSI)
#define LCD_PINS_D4 EXP2_02_PIN // SCK (CLK) clock
#elif ALL(IS_NEWPANEL, PANEL_ONE)
@@ -502,12 +521,12 @@
#if ENABLED(CR10_STOCKDISPLAY)
#define LCD_PINS_RS 27
#define LCD_PINS_EN 29
#define LCD_PINS_D4 25
#define LCD_PINS_RS EXP1_07_PIN
#define LCD_PINS_EN EXP1_08_PIN
#define LCD_PINS_D4 EXP1_06_PIN
#if !IS_NEWPANEL
#define BEEPER_PIN 37
#define BEEPER_PIN EXP1_01_PIN
#endif
#elif ENABLED(ZONESTAR_LCD)
@@ -522,38 +541,28 @@
#else
#if ANY(MKS_12864OLED, MKS_12864OLED_SSD1306)
#define LCD_PINS_DC 25 // Set as output on init
#define LCD_PINS_RS 27 // Pull low for 1s to init
#define LCD_PINS_DC EXP1_06_PIN // Set as output on init
#define LCD_PINS_RS EXP1_07_PIN // Pull low for 1s to init
// DOGM SPI LCD Support
#define DOGLCD_CS 16
#define DOGLCD_MOSI 17
#define DOGLCD_SCK 23
#define DOGLCD_CS EXP1_04_PIN
#define DOGLCD_MOSI EXP1_03_PIN
#define DOGLCD_SCK EXP1_05_PIN
#define DOGLCD_A0 LCD_PINS_DC
#else
#define LCD_PINS_RS 16
#define LCD_PINS_EN 17
#define LCD_PINS_D4 23
#define LCD_PINS_D5 25
#define LCD_PINS_D6 27
#define LCD_PINS_RS EXP1_04_PIN
#define LCD_PINS_EN EXP1_03_PIN
#define LCD_PINS_D4 EXP1_05_PIN
#define LCD_PINS_D5 EXP1_06_PIN
#define LCD_PINS_D6 EXP1_07_PIN
#endif
#define LCD_PINS_D7 29
#define LCD_PINS_D7 EXP1_08_PIN
#if !IS_NEWPANEL
#define BEEPER_PIN 33
#define BEEPER_PIN EXP2_05_PIN
#endif
#endif
#if !IS_NEWPANEL
// Buttons attached to a shift register
// Not wired yet
//#define SHIFT_CLK_PIN 38
//#define SHIFT_LD_PIN 42
//#define SHIFT_OUT_PIN 40
//#define SHIFT_EN_PIN 17
#endif
#endif
//
@@ -563,19 +572,19 @@
#if ENABLED(REPRAP_DISCOUNT_SMART_CONTROLLER)
#define BEEPER_PIN 37
#define BEEPER_PIN EXP1_01_PIN
#if ENABLED(CR10_STOCKDISPLAY)
#define BTN_EN1 17
#define BTN_EN2 23
#define BTN_EN1 EXP1_03_PIN
#define BTN_EN2 EXP1_05_PIN
#else
#define BTN_EN1 31
#define BTN_EN2 33
#define BTN_EN1 EXP2_03_PIN
#define BTN_EN2 EXP2_05_PIN
#endif
#define BTN_ENC 35
#define SD_DETECT_PIN 49
#define KILL_PIN 41
#define BTN_ENC EXP1_02_PIN
#define SD_DETECT_PIN EXP2_07_PIN
#define KILL_PIN EXP2_08_PIN
#if ENABLED(BQ_LCD_SMART_CONTROLLER)
#define LCD_BACKLIGHT_PIN 39
@@ -625,34 +634,34 @@
#elif ENABLED(ELB_FULL_GRAPHIC_CONTROLLER)
#define DOGLCD_CS 29
#define DOGLCD_A0 27
#define DOGLCD_CS EXP1_08_PIN
#define DOGLCD_A0 EXP1_07_PIN
#define BEEPER_PIN 23
#define LCD_BACKLIGHT_PIN 33
#define BEEPER_PIN EXP1_05_PIN
#define LCD_BACKLIGHT_PIN EXP2_05_PIN
#define BTN_EN1 35
#define BTN_EN2 37
#define BTN_ENC 31
#define BTN_EN1 EXP1_02_PIN
#define BTN_EN2 EXP1_01_PIN
#define BTN_ENC EXP2_03_PIN
#define LCD_SDSS SDSS
#define SD_DETECT_PIN 49
#define KILL_PIN 41
#define SD_DETECT_PIN EXP2_07_PIN
#define KILL_PIN EXP2_08_PIN
#elif ENABLED(MKS_MINI_12864)
#define DOGLCD_A0 27
#define DOGLCD_CS 25
#define DOGLCD_A0 EXP1_07_PIN
#define DOGLCD_CS EXP1_06_PIN
#define BEEPER_PIN 37
#define BEEPER_PIN EXP1_01_PIN
// not connected to a pin
#define LCD_BACKLIGHT_PIN 65 // backlight LED on A11/D65
#define BTN_EN1 31
#define BTN_EN2 33
#define BTN_ENC 35
#define BTN_EN1 EXP2_03_PIN
#define BTN_EN2 EXP2_05_PIN
#define BTN_ENC EXP1_02_PIN
#define SD_DETECT_PIN 49
#define SD_DETECT_PIN EXP2_07_PIN
#define KILL_PIN 64
//#define LCD_SCREEN_ROTATE 180 // 0, 90, 180, 270
@@ -685,7 +694,6 @@
#else
// Beeper on AUX-4
#define BEEPER_PIN 33
// Buttons are directly attached to AUX-2
@@ -701,15 +709,15 @@
#define BTN_EN2 63 // AUX2 PIN 4
#define BTN_ENC 49 // AUX3 PIN 7
#else
#define BTN_EN1 37
#define BTN_EN2 35
#define BTN_ENC 31
#define SD_DETECT_PIN 41
#define BTN_EN1 EXP1_01_PIN
#define BTN_EN2 EXP1_02_PIN
#define BTN_ENC EXP2_03_PIN
#define SD_DETECT_PIN EXP2_08_PIN
#endif
#if ENABLED(G3D_PANEL)
#define SD_DETECT_PIN 49
#define KILL_PIN 41
#define SD_DETECT_PIN EXP2_07_PIN
#define KILL_PIN EXP2_08_PIN
#endif
#endif
@@ -719,3 +727,7 @@
#endif // IS_NEWPANEL
#endif // HAS_WIRED_LCD
#ifndef KILL_PIN
#define KILL_PIN EXP2_08_PIN
#endif
+1 -1
View File
@@ -477,7 +477,7 @@
#undef PS_ON_PIN
#define PS_ON_PIN -1
#endif
#if DISABLED(PSU_OFF_REDUNDANT) || DISABLED(PSU_CONTROL) || !defined(PS_ON1_PIN)
#if DISABLED(PSU_OFF_REDUNDANT) || !defined(PS_ON1_PIN)
#undef PS_ON1_PIN
#define PS_ON1_PIN -1
#endif
+1 -2
View File
@@ -158,8 +158,7 @@
#define LCD_BRIGHTNESS_DEFAULT TFT_BACKLIGHT_PWM
#endif
#if SD_CONNECTION_IS(ONBOARD)
#define ONBOARD_SDIO
#if ENABLED(ONBOARD_SDIO)
#define SD_SS_PIN -1 // else SDSS set to PA4 in M43 (spi_pins.h)
#endif
+2 -2
View File
@@ -902,11 +902,11 @@ void CardReader::write_command(char * const buf) {
* Select the newest file and ask the user if they want to print it.
*/
bool CardReader::one_click_check() {
const bool found = selectNewestFile(); // Changes the current workDir if found
const bool found = selectNewestFile();
if (found) {
//SERIAL_ECHO_MSG(" OCP File: ", longest_filename(), "\n");
//ui.init();
one_click_print(); // Restores workkDir to root (eventually)
one_click_print();
}
return found;
}
+1 -1
View File
@@ -29,7 +29,7 @@ opt_enable REPRAP_DISCOUNT_SMART_CONTROLLER LCD_PROGRESS_BAR LCD_PROGRESS_BAR_TE
ADVANCED_PAUSE_FEATURE FILAMENT_LOAD_UNLOAD_GCODES FILAMENT_UNLOAD_ALL_EXTRUDERS \
PASSWORD_FEATURE PASSWORD_ON_STARTUP PASSWORD_ON_SD_PRINT_MENU PASSWORD_AFTER_SD_PRINT_END PASSWORD_AFTER_SD_PRINT_ABORT \
AUTO_BED_LEVELING_BILINEAR Z_MIN_PROBE_REPEATABILITY_TEST DISTINCT_E_FACTORS \
SKEW_CORRECTION SKEW_CORRECTION_FOR_Z SKEW_CORRECTION_GCODE ONE_CLICK_PRINT NO_SD_AUTOSTART \
SKEW_CORRECTION SKEW_CORRECTION_FOR_Z SKEW_CORRECTION_GCODE \
BACKLASH_COMPENSATION BACKLASH_GCODE BAUD_RATE_GCODE BEZIER_CURVE_SUPPORT \
FWRETRACT ARC_P_CIRCLES CNC_WORKSPACE_PLANES CNC_COORDINATE_SYSTEMS \
PSU_CONTROL LED_POWEROFF_TIMEOUT PS_OFF_CONFIRM PS_OFF_SOUND POWER_OFF_WAIT_FOR_COOLDOWN \
+1 -1
View File
@@ -183,7 +183,7 @@ HAS_MENU_LED = build_src_filter=+<src/lcd/menu/menu_le
HAS_MENU_MEDIA = build_src_filter=+<src/lcd/menu/menu_media.cpp>
HAS_MENU_MIXER = build_src_filter=+<src/lcd/menu/menu_mixer.cpp>
HAS_MENU_MMU2 = build_src_filter=+<src/lcd/menu/menu_mmu2.cpp>
HAS_MENU_ONE_CLICK_PRINT = build_src_filter=+<src/lcd/menu/menu_one_click_print.cpp> +<src/gcode/sd/M1003.cpp>
HAS_MENU_ONE_CLICK_PRINT = build_src_filter=+<src/lcd/menu/menu_one_click_print.cpp>
HAS_MENU_PASSWORD = build_src_filter=+<src/lcd/menu/menu_password.cpp>
HAS_MENU_POWER_MONITOR = build_src_filter=+<src/lcd/menu/menu_power_monitor.cpp>
HAS_MENU_CUTTER = build_src_filter=+<src/lcd/menu/menu_spindle_laser.cpp>
+5 -3
View File
@@ -27,7 +27,8 @@ lib_deps = ${common.lib_deps}
custom_marlin.USES_LIQUIDCRYSTAL = arduino-libraries/LiquidCrystal@~1.0.7
custom_marlin.NEOPIXEL_LED = Adafruit NeoPixel=https://github.com/p3p/Adafruit_NeoPixel/archive/1.5.0.zip
build_flags = ${common.build_flags} -DU8G_HAL_LINKS -DPLATFORM_M997_SUPPORT
-IMarlin/src/HAL/LPC1768/include -IMarlin/src/HAL/LPC1768/u8g
-IMarlin/src/HAL/LPC1768/include -IMarlin/src/HAL/LPC1768/u8g -O3
build_unflags = -Os
# debug options for backtrace
#-funwind-tables
#-mpoke-function-name
@@ -48,9 +49,10 @@ board = nxp_lpc1769
#
[env:LPC4078]
board = nxp_lpc4078
#platform = symlink:///home/p3p/workspace/EBAB_workspace/platform-mcui
#platform_packages = framework-arduino-mcui@symlink:///home/p3p/workspace/EBAB_workspace/framework-arduino-mcui
platform = https://github.com/p3p/pio-platform-mcui/archive/refs/heads/master.zip
platform_packages = framework-arduino-mcui@https://github.com/p3p/pio-framework-arduino-mcui/archive/refs/heads/master.zip
#platform = symlink://E:\EBAB\ebab_platform\platform-mcui
#platform_packages = framework-arduino-mcui@symlink://E:\EBAB\ebab_platform\framework-arduino-mcui
framework = arduino
upload_protocol = jlink
debug_tool = jlink
+1 -1
View File
@@ -13,7 +13,7 @@
[platformio]
src_dir = Marlin
boards_dir = buildroot/share/PlatformIO/boards
default_envs = LPC4078
default_envs = mega2560
include_dir = Marlin
extra_configs =
Marlin/config.ini