Compare commits

..

53 Commits

Author SHA1 Message Date
InsanityAutomation 1bbae4676f Speed tweaks 2024-06-03 08:19:46 -04:00
InsanityAutomation 6802260626 Merge branch 'LPC4078_DevUpd' of https://github.com/InsanityAutomation/Marlin into LPC4078_DevUpd 2024-05-29 12:21:31 -04:00
InsanityAutomation ed34dbb4b6 Update Configuration_adv.h 2024-05-29 12:21:14 -04:00
InsanityAutomation 721209a898 uint64_t planner test 2024-05-29 12:21:04 -04:00
InsanityAutomation 7c6dfc4ec2 Update planner.cpp 2024-05-28 14:10:47 -04:00
Mihail Dumitrescu 62008024cd Protect pulse generation timing by disabling interrupts for longer. 2024-05-28 14:10:46 -04:00
Mihail Dumitrescu e09672edac Fully guard multistepping code in Stepper::pulse_phase_isr(). 2024-05-28 14:10:46 -04:00
Mihail Dumitrescu 825e0b800c Add 4th order S_CURVE_ACCELERATION with configurable S_CURVE_FACTOR. 2024-05-28 14:10:46 -04:00
Mihail Dumitrescu 0f489c6584 PR27035
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

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.

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.

group for clarity and review

as described

combined float sq

match modified names

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.

Save and use block->steps_per_mm to avoid many divisions.
2024-05-28 14:10:46 -04:00
John Robertson 6ae43349f7 PR26881
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.

Update planner.cpp

removed

Update planner.h

Moved MINIMAL_STEP_RATE to this file.

Update planner.h

Added calc for MINIMAL_STEP_RATE

Update planner.h

fix minimal_step_rate calc

Update planner.h

Remove MINIMAL_STEP_RATE

Revert "Update planner.cpp"

This reverts commit 5e0158a8ee1340e5b0e6a7313eb5f5f7058bfa15.

Revert "Update planner.h"

This reverts commit 3da5d0c00102620dc7eddf46a30044773770a667.

Update planner.cpp

Update planner.h

Update planner.cpp

ws

Apply to min_step_rate
2024-05-28 14:10:45 -04:00
Mihail Dumitrescu f6b52a80d6 PR26555
Fix menu responsiveness when HAS_MARLINUI_U8GLIB.

Co-Authored-By: Jason Smith <jason.inet@gmail.com>
2024-05-28 14:10:45 -04:00
InsanityAutomation 38711ed5e6 Update lpc176x.ini 2024-05-28 14:10:45 -04:00
InsanityAutomation 5a714c76b8 Update Configuration.h 2024-05-28 14:10:45 -04:00
InsanityAutomation 8c1a547f2a Config Tweak 2024-05-28 14:10:45 -04:00
InsanityAutomation 16be10d2f3 SPI updates from @p3p upstream 2024-05-28 14:10:44 -04:00
InsanityAutomation d4dde255ad Debug 2024-05-28 14:10:44 -04:00
InsanityAutomation b5c7712531 Update Configuration.h 2024-05-28 14:10:44 -04:00
InsanityAutomation 8dc8361f02 tmc5160 and spi 2024-05-28 14:10:44 -04:00
InsanityAutomation 433f3ba3ab Change read function for PS_ON and EDM pins 2024-05-28 14:10:37 -04:00
InsanityAutomation 78e2aa6eac Fix interupts and pin debugging 2024-05-28 14:10:29 -04:00
InsanityAutomation 54da1da13f Tweaks 2024-05-28 14:10:29 -04:00
InsanityAutomation 544765f1a1 Update Configuration.h 2024-05-28 14:10:25 -04:00
InsanityAutomation f261fea59a Redundant Power control with EDM - First Pass 2024-05-28 14:10:24 -04:00
InsanityAutomation 00785eb14e Update Configuration_adv.h
Co-Authored-By: Chris Pepper <24342+p3p@users.noreply.github.com>
2024-05-28 14:10:04 -04:00
InsanityAutomation 6713185aea LPC4078 Initial Commit
Co-Authored-By: Chris Pepper <24342+p3p@users.noreply.github.com>
2024-05-28 14:09:51 -04:00
InsanityAutomation 298c3f2344 Update planner.cpp 2024-05-28 11:15:33 -04:00
Mihail Dumitrescu 82c1171028 Protect pulse generation timing by disabling interrupts for longer. 2024-05-28 10:46:49 -04:00
Mihail Dumitrescu 122b01d253 Fully guard multistepping code in Stepper::pulse_phase_isr(). 2024-05-28 10:46:13 -04:00
Mihail Dumitrescu 42e4321b6f Add 4th order S_CURVE_ACCELERATION with configurable S_CURVE_FACTOR. 2024-05-28 10:45:45 -04:00
Mihail Dumitrescu 87faa73bee PR27035
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

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.

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.

group for clarity and review

as described

combined float sq

match modified names

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.

Save and use block->steps_per_mm to avoid many divisions.
2024-05-28 10:43:59 -04:00
John Robertson 666e8c0116 PR26881
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.

Update planner.cpp

removed

Update planner.h

Moved MINIMAL_STEP_RATE to this file.

Update planner.h

Added calc for MINIMAL_STEP_RATE

Update planner.h

fix minimal_step_rate calc

Update planner.h

Remove MINIMAL_STEP_RATE

Revert "Update planner.cpp"

This reverts commit 5e0158a8ee1340e5b0e6a7313eb5f5f7058bfa15.

Revert "Update planner.h"

This reverts commit 3da5d0c00102620dc7eddf46a30044773770a667.

Update planner.cpp

Update planner.h

Update planner.cpp

ws

Apply to min_step_rate
2024-05-28 10:29:03 -04:00
Mihail Dumitrescu 5a0332ddee PR26555
Fix menu responsiveness when HAS_MARLINUI_U8GLIB.

Co-Authored-By: Jason Smith <jason.inet@gmail.com>
2024-05-28 10:29:02 -04:00
InsanityAutomation f67a0f847f Update lpc176x.ini 2024-05-28 09:39:16 -04:00
InsanityAutomation 0f1a5a7434 Update Configuration.h 2024-05-28 09:32:10 -04:00
thinkyhead e7c9cf3e1d [cron] Bump distribution date (2024-05-27) 2024-05-27 00:22:53 +00:00
InsanityAutomation 01df7e11dc Config Tweak 2024-05-26 15:04:33 -04:00
InsanityAutomation 9200e8c284 SPI updates from @p3p upstream 2024-05-26 14:59:09 -04:00
ellensp 6710616a09 🩹 Longer3D LK has ONBOARD_SDIO (#27129) 2024-05-26 12:09:18 -05:00
Scott Lahteine 2064c83c66 🚸 Fix SD nav after "one click print" (2) 2024-05-26 12:04:14 -05:00
thinkyhead 2e97ad1f4b [cron] Bump distribution date (2024-05-26) 2024-05-26 12:07:31 +00:00
Scott Lahteine 4f85f88ae3 🚸 Fix SD nav after "one click print" 2024-05-26 02:18:37 -05:00
InsanityAutomation 0dcfc91c9e Debug 2024-05-25 19:53:01 -04:00
InsanityAutomation acf53d6f84 Merge branch 'bugfix-2.1.x' into LPC4078_DevUpd 2024-05-25 18:34:14 -04:00
InsanityAutomation da068d5bb1 Update Configuration.h 2024-03-06 10:53:44 -05:00
InsanityAutomation 7f339f7001 tmc5160 and spi 2024-03-06 10:53:00 -05:00
ellensp 7150d0eb5c 🔨 No strlcpy in Windows (#26748) 2024-02-27 10:35:13 -05:00
InsanityAutomation ca18690349 Change read function for PS_ON and EDM pins 2024-01-30 11:52:57 -05:00
InsanityAutomation 0316242347 Fix interupts and pin debugging 2024-01-18 22:36:36 -05:00
InsanityAutomation 6087ab6347 Tweaks 2024-01-14 15:41:52 -05:00
InsanityAutomation a44871b272 Update Configuration.h 2024-01-14 15:38:54 -05:00
InsanityAutomation bef646d52c Redundant Power control with EDM - First Pass 2024-01-14 15:36:28 -05:00
InsanityAutomation 4d78a91cbd Update Configuration_adv.h
Co-Authored-By: Chris Pepper <24342+p3p@users.noreply.github.com>
2024-01-14 15:36:03 -05:00
InsanityAutomation 95bafca9d9 LPC4078 Initial Commit
Co-Authored-By: Chris Pepper <24342+p3p@users.noreply.github.com>
2024-01-14 15:35:57 -05:00
36 changed files with 971 additions and 921 deletions
+129 -123
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 0
//#define SERIAL_PORT_2 1
//#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 "22IDEX"
#define CUSTOM_MACHINE_NAME "FatBoy"
// 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,
* 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']
* 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']
*/
#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 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 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 TMC2209
//#define E1_DRIVER_TYPE A4988
//#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 2
#define EXTRUDERS 1
// 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,29 +392,38 @@
* 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 LOW // Set 'LOW' for ATX, 'HIGH' for X-Box
#define PSU_ACTIVE_STATE HIGH // Set 'LOW' for ATX, 'HIGH' for X-Box
//#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_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_OFF_REDUNDANT // Second pin for redundant power control
//#define PSU_OFF_REDUNDANT_INVERTED // Redundant pin state is the inverse of PSU_ACTIVE_STATE
#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_PIN P4_29 // Redundant pin required to enable power in combination with PS_ON_PIN
#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_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 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 POWER_OFF_TIMER // Enable M81 D<seconds> to power off after a delay
#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_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)
@@ -429,7 +438,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 120 // (s) Delay of poweroff after M81 command. Useful to let fans run for extra time.
//#define POWER_OFF_DELAY 60 // (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
@@ -553,17 +562,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 1047
#define TEMP_SENSOR_1 1047
#define TEMP_SENSOR_0 1
#define TEMP_SENSOR_1 0
#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 1
#define TEMP_SENSOR_BED 11
#define TEMP_SENSOR_PROBE 0
#define TEMP_SENSOR_CHAMBER 1
#define TEMP_SENSOR_CHAMBER 0
#define TEMP_SENSOR_COOLER 0
#define TEMP_SENSOR_BOARD 0
#define TEMP_SENSOR_SOC 0
@@ -588,13 +597,13 @@
#endif
#if HAS_E_TEMP_SENSOR
#define TEMP_RESIDENCY_TIME 5 // (seconds) Time to wait for hotend to "settle" in M109
#define TEMP_RESIDENCY_TIME 10 // (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 5 // (seconds) Time to wait for bed to "settle" in M190
#define TEMP_BED_RESIDENCY_TIME 10 // (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
@@ -637,16 +646,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 450
#define HEATER_1_MAXTEMP 450
#define HEATER_0_MAXTEMP 300
#define HEATER_1_MAXTEMP 275
#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 215
#define CHAMBER_MAXTEMP 110
#define BED_MAXTEMP 120
#define CHAMBER_MAXTEMP 60
/**
* Thermal Overshoot
@@ -671,8 +680,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 // 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 // ** EXPERIMENTAL ** 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
@@ -707,20 +716,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 { 50.0f, 50.0f } // (W) Heat cartridge powers.
#define MPC_HEATER_POWER { 40.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, 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.
#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.
#if ENABLED(MPC_INCLUDE_FAN)
#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.
#define MPC_AMBIENT_XFER_COEFF_FAN255 { 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.
@@ -731,7 +740,7 @@
// Filament Heat Capacity (joules/kelvin/mm)
// Set at runtime with M306 H<value>
#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).
#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).
// 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).
@@ -789,7 +798,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 ====================
@@ -810,7 +819,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
/**
@@ -856,7 +865,7 @@
* *** IT IS HIGHLY RECOMMENDED TO LEAVE THIS OPTION ENABLED! ***
*/
#define PREVENT_COLD_EXTRUSION
#define EXTRUDE_MINTEMP 150
#define EXTRUDE_MINTEMP 170
/**
* Prevent a single extrusion longer than EXTRUDE_MAXLENGTH.
@@ -906,7 +915,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
@@ -1015,6 +1024,9 @@
// 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
@@ -1033,19 +1045,23 @@
#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)
// 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)
// 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)
#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
@@ -1171,8 +1187,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 LOW
#define Y_MIN_ENDSTOP_HIT_STATE HIGH
#define X_MAX_ENDSTOP_HIT_STATE HIGH
#define Y_MIN_ENDSTOP_HIT_STATE LOW
#define Y_MAX_ENDSTOP_HIT_STATE HIGH
#define Z_MIN_ENDSTOP_HIT_STATE HIGH
#define Z_MAX_ENDSTOP_HIT_STATE HIGH
@@ -1229,14 +1245,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 { 80, 80, 400, 413, 413 }
#define DEFAULT_AXIS_STEPS_PER_UNIT { 40, 40, 200, 425 }
/**
* Enable support for M92. Disable to save at least ~530 bytes of flash.
@@ -1288,12 +1304,11 @@
* 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
@@ -1309,6 +1324,8 @@
#endif
#endif
#define DEFAULT_EJERK 5.0 // May be used by Linear Advance
/**
* Junction Deviation Factor
*
@@ -1333,7 +1350,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.3 // Initial and final acceleration factor, ideally 0.1 to 0.4
#define S_CURVE_FACTOR 0.35 // Initial and final acceleration factor, ideally 0.1 to 0.4
// Shouldn't generally require tuning
#endif
@@ -1411,7 +1428,7 @@
/**
* The BLTouch probe uses a Hall effect sensor and emulates a servo.
*/
//#define BLTOUCH
#define BLTOUCH
/**
* MagLev V4 probe by MDD
@@ -1453,17 +1470,6 @@
//#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
@@ -1482,20 +1488,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, { 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_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_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, { 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_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_5 { PROBE_STOW_FEEDRATE, { 0, 0, 0 } } // Extra move if needed
#endif
@@ -1686,7 +1692,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
@@ -1799,7 +1805,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
@@ -1826,16 +1832,16 @@
// @section geometry
// The size of the printable area
#define X_BED_SIZE 355
#define Y_BED_SIZE 350
#define X_BED_SIZE 1200
#define Y_BED_SIZE 1200
// Travel limits (linear=mm, rotational=°) after homing, corresponding to endstop positions.
#define X_MIN_POS -20.93
#define X_MIN_POS 0
#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 500
#define Z_MAX_POS 1000
//#define I_MIN_POS 0
//#define I_MAX_POS 50
//#define J_MIN_POS 0
@@ -1903,12 +1909,11 @@
* 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 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 NUM_RUNOUT_SENSORS 1 // Number of sensors, up to one per extruder. Define a FIL_RUNOUT#_PIN for each.
#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.
@@ -1951,18 +1956,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 T%c"
#define FILAMENT_RUNOUT_SCRIPT "M600"
// 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 15
//#define FILAMENT_RUNOUT_DISTANCE_MM 25
#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
@@ -2047,8 +2052,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
/**
@@ -2157,18 +2162,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 7 // Don't use more than 15 points per axis, implementation limited.
#define GRID_MAX_POINTS_X 10 // 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 0.0 // When the nozzle is off the mesh, this value is used
//#define UBL_Z_RAISE_WHEN_OFF_MESH 2.5 // 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
@@ -2214,7 +2219,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 4 // (mm) Z Range centered on Z_MIN_POS for LCD Z adjustment
#define LCD_PROBE_Z_RANGE 8 // (mm) Z Range centered on Z_MIN_POS for LCD Z adjustment
#define MESH_EDIT_MENU // Add a menu to edit mesh points
#endif
@@ -2224,8 +2229,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 raise 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 height of nozzle 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)
@@ -2367,7 +2372,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.
@@ -2474,7 +2479,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
@@ -2484,7 +2489,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 4 // Default number of pattern repetitions
#define NOZZLE_CLEAN_STROKES 12 // Default number of pattern repetitions
#if ENABLED(NOZZLE_CLEAN_PATTERN_ZIGZAG)
#define NOZZLE_CLEAN_TRIANGLES 3 // Default number of triangles
@@ -2492,8 +2497,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 { { 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) } }
#define NOZZLE_CLEAN_START_POINT { { 30, 30, (Z_MIN_POS + 1) } }
#define NOZZLE_CLEAN_END_POINT { { 100, 60, (Z_MIN_POS + 1) } }
#if ENABLED(NOZZLE_CLEAN_PATTERN_CIRCLE)
#define NOZZLE_CLEAN_CIRCLE_RADIUS 6.5 // (mm) Circular pattern radius
@@ -2505,7 +2510,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
@@ -2642,9 +2647,9 @@
#define DISPLAY_CHARSET_HD44780 JAPANESE
/**
* Info Screen Style (0:Classic, 1:Průša, 2:CNC)
* Info Screen Style (0:Classic, 1:Průša)
*
* :[0:'Classic', 1:'Průša', 2:'CNC']
* :[0:'Classic', 1:'Průša']
*/
#define LCD_INFO_SCREEN_STYLE 0
@@ -3045,7 +3050,7 @@
//
// Factory display for Creality CR-10 / CR-7 / Ender-3
// https://marlinfw.org/docs/hardware/controllers.html#cr10_stockdisplay
// https://www.aliexpress.com/item/32833148327.html
//
// Connect to EXP1 on RAMPS and compatible boards.
//
@@ -3422,6 +3427,7 @@
#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
@@ -3526,13 +3532,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 EFAN0_PIN
#define RGB_LED_G_PIN EFAN1_PIN
#define RGB_LED_B_PIN EFAN2_PIN
#define RGB_LED_W_PIN EFAN3_PIN
//#define RGB_LED_R_PIN 34
//#define RGB_LED_G_PIN 43
//#define RGB_LED_B_PIN 35
//#define RGB_LED_W_PIN -1
#endif
#if ANY(RGB_LED, RGBW_LED, PCA9632)
+115 -119
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 20 // (seconds)
#define THERMAL_PROTECTION_BED_PERIOD 90 // (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 (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_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_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 FAN3_PIN
#define E1_AUTO_FAN_PIN FAN3_PIN
#define E0_AUTO_FAN_PIN -1
#define E1_AUTO_FAN_PIN -1
#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 255 // Set default power-up brightness (0-255, requires PWM pin)
#define CASE_LIGHT_DEFAULT_BRIGHTNESS 105 // 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 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_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_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 175
#define DEFAULT_DUPLICATION_X_OFFSET 100
// 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 { { -44, 6.88 }, { 404, 6.88 }, { 209.3, 370.75 } }
//#define Z_STEPPER_ALIGN_XY { { 10, 190 }, { 100, 10 }, { 190, 190 } }
/**
* 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 { { -44, 6.88 }, { 404, 6.88 }, { 209.3, 370.75 } }
//#define Z_STEPPER_ALIGN_STEPPER_XY { { 210.7, 102.5 }, { 152.6, 220.0 }, { 94.5, 102.5 } }
#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 15 // (%) Maximum incline that G34 will handle
#define G34_MAX_GRADE 5 // (%) 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,32 +1185,33 @@
* 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_[XYZ], DEFAULT_AXIS_STEPS_PER_UNIT,
* calculated automatically from SHAPING_FREQ_[XY], 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>
* 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.
*/
//#define INPUT_SHAPING_X
//#define INPUT_SHAPING_Y
//#define INPUT_SHAPING_Z
#if ANY(INPUT_SHAPING_X, INPUT_SHAPING_Y, INPUT_SHAPING_Z)
#if ANY(INPUT_SHAPING_X, INPUT_SHAPING_Y)
#if ENABLED(INPUT_SHAPING_X)
#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).
#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).
#endif
#if ENABLED(INPUT_SHAPING_Y)
#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).
#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).
#endif
#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_MIN_FREQ 20 // 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
@@ -1262,18 +1263,18 @@
// Increase the slowdown divisor for larger buffer sizes.
#define SLOWDOWN
#if ENABLED(SLOWDOWN)
#define SLOWDOWN_DIVISOR 8
#define SLOWDOWN_DIVISOR 2
#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> S<min%> to change limits at runtime.
* Use M201 F<freq> G<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 S<min%>.
#define XY_FREQUENCY_MIN_PERCENT 5 // (%) Minimum FR percentage to apply. Set with M201 G<min%>.
#endif
//
@@ -1295,7 +1296,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"
@@ -1325,7 +1326,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..."
@@ -1341,7 +1342,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 flash).
// Uncomment to enable reporting (required for "G425 V", but consumes PROGMEM).
//#define CALIBRATION_REPORTING
// The true location and dimension the cube/bolt/washer on the bed.
@@ -1385,7 +1386,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 16 //: [1, 2, 4, 8, 16, 32, 64, 128]
#define MULTISTEPPING_LIMIT 32 //: [1, 2, 4, 8, 16, 32, 64, 128]
/**
* Adaptive Step Smoothing increases the resolution of multi-axis moves, particularly at step frequencies
@@ -1473,7 +1474,6 @@
#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,7 +1539,6 @@
* 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)
@@ -1581,9 +1580,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, HAS_MARLINUI_HD44780)
#if ANY(HAS_MARLINUI_U8GLIB, TOUCH_UI_FTDI_EVE)
//#define SHOW_CUSTOM_BOOTSCREEN // Show the bitmap in Marlin/_Bootscreen.h on startup.
#endif
#endif
@@ -1621,7 +1620,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
@@ -1742,28 +1741,23 @@
* 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 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 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_PULLUP // Set pullup / pulldown as appropriate for your sensor
//#define POWER_LOSS_PULLDOWN
//#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
//#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.
// 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)
@@ -1812,10 +1806,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
@@ -1834,7 +1828,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
@@ -1969,6 +1963,17 @@
// 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.
@@ -2217,20 +2222,13 @@
//#define TFT_BTOKMENU_COLOR 0x145F // 00010 100010 11111 Cyan
#endif
/**
* 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
*/
//
// 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 sleep / backlight timeout with M255 S<minutes> and a menu item
#define EDITABLE_DISPLAY_TIMEOUT // Edit timeout with M255 S<minutes> and a menu item
#endif
//
@@ -2273,7 +2271,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 1 // (steps or mm) Steps or millimeter distance for each Z babystep
#define BABYSTEP_MULTIPLICATOR_Z 25 // (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.
@@ -2291,7 +2289,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
@@ -2315,9 +2313,9 @@
#define LIN_ADVANCE
#if ENABLED(LIN_ADVANCE)
#if ENABLED(DISTINCT_E_FACTORS)
#define ADVANCE_K { 0.0 } // (mm) Compression length per 1mm/s extruder speed, per extruder
#define ADVANCE_K { 0.22 } // (mm) Compression length per 1mm/s extruder speed, per extruder
#else
#define ADVANCE_K 0.0 // (mm) Compression length applying to all extruders
#define ADVANCE_K 0.22 // (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.
@@ -2566,7 +2564,7 @@
*
* Override the default value based on the driver type set in Configuration.h.
*/
//#define MINIMUM_STEPPER_PULSE 10
//#define MINIMUM_STEPPER_PULSE 5
/**
* Maximum stepping rate (in Hz) the stepper driver allows
@@ -2597,9 +2595,9 @@
#if ALL(HAS_MEDIA, DIRECT_STEPPING)
#define BLOCK_BUFFER_SIZE 8
#elif HAS_MEDIA
#define BLOCK_BUFFER_SIZE 64
#define BLOCK_BUFFER_SIZE 32
#else
#define BLOCK_BUFFER_SIZE 64
#define BLOCK_BUFFER_SIZE 32
#endif
// @section serial
@@ -2697,7 +2695,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.
* Support is currently limited to some STM32 MCUs and all HC32 MCUs.
* Only some STM32 MCUs are currently supported.
* Note: This has no effect on emulated USB serial ports.
*/
//#define SERIAL_DMA
@@ -2768,7 +2766,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
@@ -2799,10 +2797,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 4 // (mm) Load / Unload length
#define TOOLCHANGE_FS_LENGTH 12 // (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)
@@ -2926,11 +2924,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
@@ -2952,14 +2950,17 @@
* 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
#if HAS_TRINAMIC_CONFIG || HAS_TMC26X
#define HOLD_MULTIPLIER 0.25 // Scales down the holding current from run current
#define HOLD_MULTIPLIER 0.7 // Scales down the holding current from run current
/**
* Interpolate microsteps to 256
@@ -2968,7 +2969,7 @@
#define INTERPOLATE true
#if AXIS_IS_TMC_CONFIG(X)
#define X_CURRENT 1800 // (mA) RMS current. Multiply by 1.414 for peak current.
#define X_CURRENT 800 // (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
@@ -2988,7 +2989,7 @@
#endif
#if AXIS_IS_TMC_CONFIG(Y)
#define Y_CURRENT 1800
#define Y_CURRENT 800
#define Y_CURRENT_HOME Y_CURRENT
#define Y_MICROSTEPS 16
#define Y_RSENSE 0.022
@@ -3008,7 +3009,7 @@
#endif
#if AXIS_IS_TMC_CONFIG(Z)
#define Z_CURRENT 1800
#define Z_CURRENT 800
#define Z_CURRENT_HOME Z_CURRENT
#define Z_MICROSTEPS 16
#define Z_RSENSE 0.11
@@ -3108,7 +3109,7 @@
#endif
#if AXIS_IS_TMC_CONFIG(E0)
#define E0_CURRENT 800
#define E0_CURRENT 900
#define E0_MICROSTEPS 16
#define E0_RSENSE 0.11
#define E0_CHAIN_POS -1
@@ -3213,7 +3214,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
@@ -3273,7 +3274,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
@@ -3299,11 +3300,11 @@
* Define your own with:
* { <off_time[1..15]>, <hysteresis_end[-3..12]>, hysteresis_start[1..8] }
*/
#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 CHOPPER_DEFAULT_36V // 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
@@ -3314,7 +3315,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
@@ -3404,12 +3405,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
@@ -3443,13 +3444,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.
@@ -3464,7 +3465,7 @@
*/
#define TMC_ADV() { }
#endif // HAS_TRINAMIC_CONFIG
#endif // HAS_TRINAMIC_CONFIG || HAS_TMC26X
// @section i2cbus
@@ -3557,7 +3558,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.
*
@@ -4114,7 +4115,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
@@ -4260,8 +4261,7 @@
/**
* Instant freeze / unfreeze functionality
* 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.
* Potentially useful for emergency stop that allows being resumed.
* @section interface
*/
//#define FREEZE_FEATURE
@@ -4308,7 +4308,6 @@
// 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
/**
@@ -4342,7 +4341,7 @@
* Extras for an ESP32-based motherboard with WIFISUPPORT
* These options don't apply to add-on WiFi modules based on ESP32 WiFi101.
*/
#if ANY(WIFISUPPORT, ESP3D_WIFISUPPORT)
#if ENABLED(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
@@ -4489,7 +4488,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
@@ -4525,6 +4524,3 @@
// 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-24"
//#define STRING_DISTRIBUTION_DATE "2024-05-27"
/**
* Defines a generic printer name to be output to the LCD after booting Marlin.
+1 -2
View File
@@ -53,12 +53,11 @@ 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
+25 -3
View File
@@ -165,14 +165,13 @@
// * @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] = { false };
static bool spiInitialised[BOARD_NR_SPI] = {};
SPIClass::SPIClass(uint8_t device) {
// // Init things specific to each SPI device
@@ -184,6 +183,12 @@ 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;
@@ -202,6 +207,18 @@ 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
@@ -216,6 +233,9 @@ 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() {
@@ -341,7 +361,9 @@ void SPIClass::setDataSize(uint32_t dataSize) { _currentSetting->dataSize = data
// /**
// * Set up/tear down
// */
void SPIClass::updateSettings() { }
void SPIClass::updateSettings() {
MCUI::SSP::configure(_currentSetting->device_id, _currentSetting->m_config);
}
SPIClass SPI(1);
+2
View File
@@ -120,6 +120,8 @@ 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 EITHER(FYSETC_MINI_12864, MKS_MINI_12864)
#if ANY(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 EITHER(FYSETC_MINI_12864, MKS_MINI_12864) // LCD SPI is running mode 3 while SD card is running mode 0
#if ANY(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 = 7500kHz
#define FTM0_TIMER_RATE (F_BUS / (FTM0_TIMER_PRESCALE)) // 60MHz / 8 = 7.5MHz
#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) sq(float(I))
#define FLOAT_SQ(I) float(sq(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,6 +1105,10 @@ 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,6 +1276,10 @@ 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
@@ -0,0 +1,36 @@
/**
* 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-24"
#define STRING_DISTRIBUTION_DATE "2024-05-27"
#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, row, sel), n);
n -= lcd_put_u8str_max(ui.scrolled_filename(theCard, n, 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, row, sel), n);
n -= lcd_put_u8str_max(ui.scrolled_filename(theCard, n, 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, row, sel), pixw);
pixel_len_t n = pixw - lcd_put_u8str_max(ui.scrolled_filename(theCard, maxlen, 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, row, sel), maxlen);
dwin_string.add(ui.scrolled_filename(theCard, maxlen, sel), maxlen);
uint8_t n = maxlen - dwin_string.length;
while (n > 0) { dwin_string.add(' '); --n; }
lcd_moveto(1, row);
+23 -26
View File
@@ -357,25 +357,21 @@ void MarlinUI::init() {
#if HAS_MEDIA
#if MARLINUI_SCROLL_NAME
uint8_t MarlinUI::filename_scroll_pos, MarlinUI::filename_scroll_max;
static uint8_t filename_scroll_pos, filename_scroll_max;
#endif
const char * MarlinUI::scrolled_filename(CardReader &theCard, const uint8_t maxlen, uint8_t hash, const bool doScroll) {
const char * MarlinUI::scrolled_filename(CardReader &theCard, const uint8_t maxlen, const bool doScroll) {
const char *outstr = theCard.longest_filename();
if (theCard.longFilename[0]) {
#if MARLINUI_SCROLL_NAME
if (doScroll) {
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
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);
}
// 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[
@@ -1003,22 +999,19 @@ void MarlinUI::init() {
#endif // HAS_MARLINUI_MENU
if (ELAPSED(ms, next_lcd_update_ms) || TERN0(HAS_MARLINUI_U8GLIB, drawing_screen)) {
const bool lcd_update_ms_elapsed = ELAPSED(ms, next_lcd_update_ms);
if (lcd_update_ms_elapsed) {
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()))
@@ -1083,12 +1076,17 @@ 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.
@@ -1097,19 +1095,23 @@ 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 ALL(HAS_MARLINUI_MENU, SCROLL_LONG_FILENAMES)
#if MARLINUI_SCROLL_NAME
// 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 && !lcd_status_update_delay--) {
if (currentScreen == menu_media && filename_scroll_max && !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;
@@ -1131,7 +1133,6 @@ 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;
@@ -1160,14 +1161,11 @@ 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);
@@ -1212,8 +1210,7 @@ void MarlinUI::init() {
case LCDVIEW_CALL_NO_REDRAW:
default: break;
} // switch
} // ELAPSED(ms, next_lcd_update_ms)
}
TERN_(HAS_GRAPHICAL_TFT, tft_idle());
}
+1 -4
View File
@@ -644,10 +644,7 @@ public:
#if ALL(SCROLL_LONG_FILENAMES, HAS_MARLINUI_MENU)
#define MARLINUI_SCROLL_NAME 1
#endif
#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);
static const char * scrolled_filename(CardReader &theCard, const uint8_t maxlen, 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
+10 -3
View File
@@ -25,6 +25,13 @@
#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([]{
@@ -33,9 +40,9 @@ void one_click_print() {
GET_TEXT_F(MSG_BUTTON_PRINT), GET_TEXT_F(MSG_BUTTON_CANCEL),
[]{
card.openAndPrintFile(card.filename);
ui.return_to_status();
ui.reset_status();
}, nullptr,
one_click_print_done();
},
one_click_print_done,
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, row, sel));
tft.add_text(MENU_ITEM_ICON_SPACE, MENU_TEXT_Y, COLOR_MENU_TEXT, ui.scrolled_filename(theCard, maxlen, sel));
}
#endif
+166 -249
View File
@@ -128,7 +128,6 @@ 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
@@ -150,7 +149,7 @@ planner_settings_t Planner::settings; // Initialized by settings.load(
const uint8_t laser_power_floor = cutter.pct_to_ocr(SPEED_POWER_MIN);
#endif
uint32_t Planner::max_acceleration_steps_per_s2[DISTINCT_AXES]; // (steps/s^2) Derived from mm_per_s2
uint64_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
@@ -170,7 +169,7 @@ uint32_t Planner::max_acceleration_steps_per_s2[DISTINCT_AXES]; // (steps/s^2) D
#endif
#if ENABLED(DIRECT_STEPPING)
uint32_t Planner::last_page_step_rate = 0;
uint64_t Planner::last_page_step_rate = 0;
AxisBits Planner::last_page_dir; // = 0
#endif
@@ -220,7 +219,7 @@ uint32_t Planner::max_acceleration_steps_per_s2[DISTINCT_AXES]; // (steps/s^2) D
xyze_long_t Planner::position{0};
uint32_t Planner::acceleration_long_cutoff;
uint64_t Planner::acceleration_long_cutoff;
xyze_float_t Planner::previous_speed;
float Planner::previous_nominal_speed;
@@ -248,7 +247,7 @@ float Planner::previous_nominal_speed;
#endif
#if HAS_WIRED_LCD
volatile uint32_t Planner::block_buffer_runtime_us = 0;
volatile uint64_t Planner::block_buffer_runtime_us = 0;
#endif
/**
@@ -338,7 +337,7 @@ void Planner::init() {
* // Compute initial estimation of 0x1000000/x -
* // Get most significant bit set on divider
* uint8_t idx = 0;
* uint32_t nr = d;
* uint64_t nr = d;
* if (!(nr & 0xFF0000)) {
* nr <<= 8; idx += 8;
* if (!(nr & 0xFF0000)) { nr <<= 8; idx += 8; }
@@ -348,16 +347,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
* uint32_t tidx = nr >> 15, // top 9 bits. bit8 is always set
* uint64_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 = 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
* 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
* if (r >= d) x++; // Check whether to adjust result
* return uint32_t(x); // x holds the proper estimation
* return uint64_t(x); // x holds the proper estimation
*/
static uint32_t get_period_inverse(uint32_t d) {
static uint64_t get_period_inverse(uint64_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,
@@ -381,7 +380,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 uint32_t small_inv_tab[111] PROGMEM = {
static const uint64_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,
@@ -718,20 +717,18 @@ void Planner::init() {
);
// Return the result
return r11 | (uint16_t(r12) << 8) | (uint32_t(r13) << 16);
return r11 | (uint16_t(r12) << 8) | (uint64_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 uint32_t get_period_inverse(const uint32_t d) {
FORCE_INLINE static uint64_t get_period_inverse(const uint64_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.
@@ -768,10 +765,6 @@ 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;
}
@@ -784,47 +777,55 @@ block_t* Planner::get_current_block() {
/**
* Calculate trapezoid parameters, multiplying the entry- and exit-speeds
* 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().
* 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().
**
* ############ 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, so it is safe to
* alter its values.
* is not and will not use the block while we modify it.
*/
void Planner::calculate_trapezoid_for_block(block_t * const block, const_float_t entry_factor, const_float_t exit_factor) {
void Planner::calculate_trapezoid_for_block(block_t * const block, const_float_t entry_speed, const_float_t exit_speed) {
uint32_t initial_rate = CEIL(block->nominal_rate * entry_factor),
final_rate = CEIL(block->nominal_rate * exit_factor); // (steps per second)
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));
// 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));
// 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);
#if ANY(S_CURVE_ACCELERATION, LIN_ADVANCE)
// If we have some plateau time, the cruise rate will be the nominal rate
uint32_t cruise_rate = block->nominal_rate;
uint64_t cruise_rate = block->nominal_rate;
#endif
// Steps for acceleration, plateau and deceleration
int32_t plateau_steps = block->step_event_count;
uint32_t accelerate_steps = 0,
decelerate_steps = 0;
int32_t plateau_steps = block->step_event_count,
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;
float half_inverse_accel = 0.5f * inverse_accel,
const 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 = FLOOR(decelerate_steps_float);
decelerate_steps = CEIL(decelerate_steps_float);
// Steps between acceleration and deceleration, if any
plateau_steps -= accelerate_steps + decelerate_steps;
@@ -834,13 +835,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_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);
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));
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
cruise_rate = final_speed(initial_rate, accel, accelerate_steps);
NOMORE(cruise_rate, final_speed(initial_rate, accel, accelerate_steps));
#endif
}
}
@@ -848,7 +849,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
uint32_t acceleration_time = rate_factor * float(cruise_rate - initial_rate),
uint64_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),
@@ -856,8 +857,8 @@ void Planner::calculate_trapezoid_for_block(block_t * const block, const_float_t
#endif
// Store new block parameters
block->accelerate_until = accelerate_steps;
block->decelerate_after = block->step_event_count - decelerate_steps;
block->accelerate_before = accelerate_steps;
block->decelerate_start = block->step_event_count - decelerate_steps;
block->initial_rate = initial_rate;
#if ENABLED(S_CURVE_ACCELERATION)
block->acceleration_time = acceleration_time;
@@ -937,16 +938,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 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.
* 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
*
* 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
@@ -954,28 +955,22 @@ 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, 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.
* 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
*
* 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
@@ -998,7 +993,8 @@ 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.
void Planner::reverse_pass_kernel(block_t * const current, const block_t * const next, const_float_t safe_exit_speed_sqr) {
// 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) {
// 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.
@@ -1016,196 +1012,136 @@ void 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). And don't set its speed, as it can't
// be updated at this time.
// recalculating BUSY blocks).
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.
* 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.
*/
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);
// 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;
// The ISR may change block_buffer_nonbusy so get a stable local copy.
uint8_t nonbusy_block_index = block_buffer_nonbusy;
// 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;
while (block_index != planned_block_index) {
// Perform the reverse pass
// Don't try to change the entry speed of the first non-busy block.
while (block_index != nonbusy_block_index) {
block_t *current = &block_buffer[block_index];
// Only process movement blocks
if (current->is_move()) {
reverse_pass_kernel(current, next, safe_exit_speed_sqr);
// If no entry speed increase was possible we end the reverse pass.
if (!reverse_pass_kernel(current, next, safe_exit_speed_sqr)) return;
next = current;
}
// Advance to the next
block_index = prev_block_index(block_index);
// The ISR could advance the block_buffer_planned while we were doing the reverse pass.
// The ISR could advance block_buffer_nonbusy 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 (planned_block_index != block_buffer_planned) {
while (nonbusy_block_index != block_buffer_nonbusy) {
// If we reached the busy block or an already processed block, break the loop now
if (block_index == planned_block_index) return;
if (block_index == nonbusy_block_index) return;
// Advance the pointer, following the busy block
planned_block_index = next_block_index(planned_block_index);
nonbusy_block_index = next_block_index(nonbusy_block_index);
}
}
}
// 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);
// 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);
// 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;
if (new_exit_speed_sqr < current->entry_speed_sqr) {
// Current entry speed limited by full acceleration from previous entry speed.
// Set optimal plan pointer.
block_buffer_planned = block_index;
}
else {
// Previous entry speed has been maximized.
block_buffer_planned = prev_block_index(block_index);
}
// 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;
}
// 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;
}
// The fully optimized entry speed is our new minimum speed.
current->min_entry_speed_sqr = current->entry_speed_sqr;
}
/**
* 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.
* Do the forward pass and recalculate the trapezoid speed profiles for all blocks in the plan
* according to entry/exit speeds.
*/
void Planner::recalculate_trapezoids(const_float_t safe_exit_speed_sqr) {
// The tail may be changed by the ISR so get a local copy.
// Start with the block that's about to execute or is executing.
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 current_entry_speed = 0.0f, next_entry_speed = 0.0f;
float next_entry_speed = 0.0f;
while (block_index != head_block_index) {
next = &block_buffer[block_index];
// Only process movement blocks
if (next->is_move()) {
next_entry_speed = SQRT(next->entry_speed_sqr);
// 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;
if (block) {
// 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 the next block is marked to RECALCULATE, also mark the previously-fetched one
if (next->flag.recalculate) block->flag.recalculate = true;
if (next->entry_speed_sqr != next->min_entry_speed_sqr)
forward_pass_kernel(block, next);
// Recalculate if current block entry or exit junction speed has changed.
if (block->flag.recalculate) {
const float current_entry_speed = next_entry_speed;
next_entry_speed = SQRT(next->entry_speed_sqr);
// 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);
calculate_trapezoid_for_block(block, current_entry_speed, next_entry_speed);
}
// Reset current only to ensure next trapezoid is computed - The
@@ -1215,30 +1151,17 @@ 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. Always recalculated.
if (block) {
// 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;
next_entry_speed = SQRT(safe_exit_speed_sqr);
// 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);
}
calculate_trapezoid_for_block(block, current_entry_speed, next_entry_speed);
// Reset block to ensure its trapezoid is computed - The stepper is free to use
// the block from now on.
@@ -1246,14 +1169,10 @@ 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) {
// 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();
}
reverse_pass(safe_exit_speed_sqr);
// The forward pass is done as part of recalculate_trapezoids()
recalculate_trapezoids(safe_exit_speed_sqr);
}
@@ -1662,7 +1581,7 @@ void Planner::quick_stop() {
const bool was_enabled = stepper.suspend();
// Drop all queue entries
block_buffer_nonbusy = block_buffer_planned = block_buffer_head = block_buffer_tail;
block_buffer_nonbusy = 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.
@@ -1966,15 +1885,10 @@ 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)
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_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_YX)
dm.a = (dist.a > 0); // Motor A direction
dm.b = (dist.b TERN(MARKFORGED_INVERSE, -, +) dist.a > 0); // Motor B direction
@@ -1995,9 +1909,9 @@ bool Planner::_populate_block(
#if HAS_EXTRUDERS
dm.e = (dist.e > 0);
const float esteps_float = dist.e * e_factor[extruder];
const uint32_t esteps = ABS(esteps_float);
const uint64_t esteps = ABS(esteps_float);
#else
constexpr uint32_t esteps = 0;
constexpr uint64_t esteps = 0;
#endif
// Clear all flags, including the "busy" bit
@@ -2436,7 +2350,8 @@ 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;
uint32_t accel;
block->steps_per_mm = steps_per_mm;
uint64_t accel;
#if ENABLED(LIN_ADVANCE)
bool use_advance_lead = false;
#endif
@@ -2446,7 +2361,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 uint32_t max_possible = max_acceleration_steps_per_s2[AXIS+INDX] * block->step_event_count / block->steps[AXIS]; \
const uint64_t max_possible = max_acceleration_steps_per_s2[AXIS+INDX] * block->step_event_count / block->steps[AXIS]; \
NOMORE(accel, max_possible); \
} \
}while(0)
@@ -2490,7 +2405,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 uint32_t max_accel_steps_per_s2 = MAX_E_JERK(extruder) / (extruder_advance_K[E_INDEX_N(extruder)] * e_D_ratio) * steps_per_mm;
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;
if (accel > max_accel_steps_per_s2) {
accel = max_accel_steps_per_s2;
if (ENABLED(LA_DEBUG)) SERIAL_ECHOLNPGM("Acceleration limited.");
@@ -2520,7 +2435,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 = (uint32_t)(accel * (float(1UL << 24) / (STEPPER_TIMER_RATE)));
block->acceleration_rate = (uint64_t)(accel * (float(1UL << 24) / (STEPPER_TIMER_RATE)));
#endif
#if ENABLED(LIN_ADVANCE)
@@ -2533,7 +2448,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 (uint32_t dividend = block->steps.e << 1; dividend <= (block->step_event_count >> 2); dividend <<= 1)
for (uint64_t dividend = block->steps.e << 1; dividend <= (block->step_event_count >> 2); dividend <<= 1)
block->la_scaling++;
#if ENABLED(LA_DEBUG)
@@ -2546,7 +2461,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));
@@ -2772,7 +2687,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 uint32_t previous_advance_rate;
static uint64_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.
@@ -2820,7 +2735,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.
@@ -2829,6 +2744,8 @@ 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;
@@ -3164,8 +3081,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_until = 0;
block->decelerate_after = block->step_event_count;
block->accelerate_before = 0;
block->decelerate_start = block->step_event_count;
// Will be set to last direction later if directional format.
block->direction_bits.reset();
@@ -3275,7 +3192,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() {
uint32_t highest_rate = 1;
uint64_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)))
@@ -3388,7 +3305,7 @@ void Planner::set_max_feedrate(const AxisEnum axis, float inMaxFeedrateMMS) {
const bool was_enabled = stepper.suspend();
#endif
uint32_t bbru = block_buffer_runtime_us;
uint64_t bbru = block_buffer_runtime_us;
#ifdef __AVR__
// Reenable Stepper ISR
+27 -20
View File
@@ -78,6 +78,14 @@
#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,
@@ -219,13 +227,14 @@ 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
};
uint32_t step_event_count; // The number of step events required to complete this block
uint64_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)
@@ -238,30 +247,30 @@ typedef struct PlannerBlock {
#endif
// Settings for the trapezoid generator
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
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
#if ENABLED(S_CURVE_ACCELERATION)
uint32_t cruise_rate, // The actual cruise rate to use, between end of the acceleration phase and start of deceleration phase
uint64_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
uint32_t acceleration_rate; // Acceleration rate in (2^24 steps)/timer_ticks*s
uint64_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)
uint32_t la_advance_rate; // The rate at which steps are added whilst accelerating
uint64_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
uint32_t nominal_rate, // The nominal step rate for this block in step_events/sec
uint64_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
@@ -283,11 +292,11 @@ typedef struct PlannerBlock {
#endif
#if HAS_WIRED_LCD
uint32_t segment_time_us;
uint64_t segment_time_us;
#endif
#if ENABLED(POWER_LOSS_RECOVERY)
uint32_t sdpos;
uint64_t sdpos;
xyze_pos_t start_position;
#endif
@@ -338,7 +347,7 @@ constexpr uint8_t block_inc_mod(const uint8_t v1, const uint8_t v2) {
#endif
typedef struct PlannerSettings {
uint32_t max_acceleration_mm_per_s2[DISTINCT_AXES], // (mm/s^2) M201 XYZE
uint64_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
@@ -442,7 +451,6 @@ 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
@@ -452,7 +460,7 @@ class Planner {
#endif
#if ENABLED(DIRECT_STEPPING)
static uint32_t last_page_step_rate; // Last page step rate given
static uint64_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
@@ -479,7 +487,7 @@ class Planner {
static laser_state_t laser_inline;
#endif
static uint32_t max_acceleration_steps_per_s2[DISTINCT_AXES]; // (steps/s^2) Derived from mm_per_s2
static uint64_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
@@ -569,7 +577,7 @@ class Planner {
/**
* Limit where 64bit math is necessary for acceleration calculation
*/
static uint32_t acceleration_long_cutoff;
static uint64_t acceleration_long_cutoff;
#ifdef MAX7219_DEBUG_SLOWDOWN
friend class Max7219;
@@ -586,7 +594,7 @@ class Planner {
#endif
#if HAS_WIRED_LCD
volatile static uint32_t block_buffer_runtime_us; // Theoretical block buffer runtime in µs
volatile static uint64_t block_buffer_runtime_us; // Theoretical block buffer runtime in µs
#endif
public:
@@ -804,7 +812,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_planned = block_buffer_head = block_buffer_tail = 0; }
FORCE_INLINE static void clear_block_buffer() { block_buffer_nonbusy = 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); }
@@ -1081,13 +1089,12 @@ class Planner {
}
#endif
static void calculate_trapezoid_for_block(block_t * const block, const_float_t entry_factor, const_float_t exit_factor);
static void calculate_trapezoid_for_block(block_t * const block, const_float_t entry_speed, const_float_t exit_speed);
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 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(const_float_t safe_exit_speed_sqr);
static void forward_pass();
static void recalculate_trapezoids(const_float_t safe_exit_speed_sqr);
+195 -123
View File
@@ -59,8 +59,8 @@
* time ----->
*
* The trapezoid is the shape the speed curve over time. It starts at block->initial_rate, accelerates
* 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.
* 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.
* 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
uint32_t Stepper::motor_current_setting[MOTOR_CURRENT_COUNT]; // Initialized by settings.load()
uint64_t Stepper::motor_current_setting[MOTOR_CURRENT_COUNT]; // Initialized by settings.load()
#if HAS_MOTOR_CURRENT_SPI
constexpr uint32_t Stepper::digipot_count[];
constexpr uint64_t Stepper::digipot_count[];
#endif
#endif
@@ -193,7 +193,8 @@ bool Stepper::abort_current_block;
;
#endif
uint32_t Stepper::acceleration_time, Stepper::deceleration_time;
// In timer_ticks
uint64_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
@@ -222,10 +223,10 @@ uint32_t Stepper::acceleration_time, Stepper::deceleration_time;
xyze_long_t Stepper::delta_error{0};
xyze_long_t Stepper::advance_dividend{0};
uint32_t Stepper::advance_divisor = 0,
uint64_t Stepper::advance_divisor = 0,
Stepper::step_events_completed = 0, // The number of step events executed in the current block
Stepper::accelerate_until, // The count at which to stop accelerating
Stepper::decelerate_after, // The count at which to start decelerating
Stepper::accelerate_before, // The count at which to start cruising
Stepper::decelerate_start, // 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)
@@ -238,8 +239,8 @@ uint32_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
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
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
#ifdef __AVR__
bool __attribute__((used)) Stepper::A_negative __asm__("A_negative"); // If A coefficient was negative
#endif
@@ -259,7 +260,7 @@ uint32_t Stepper::advance_divisor = 0,
ne_coeff_t Stepper::ne;
ne_fix_t Stepper::ne_fix;
int32_t Stepper::ne_edividend;
uint32_t Stepper::ne_scale;
uint64_t Stepper::ne_scale;
#endif
#if HAS_ZV_SHAPING
@@ -296,7 +297,7 @@ uint32_t Stepper::advance_divisor = 0,
hal_timer_t Stepper::ticks_nominal = 0;
#if DISABLED(S_CURVE_ACCELERATION)
uint32_t Stepper::acc_step_rate; // needed for deceleration start point
uint64_t Stepper::acc_step_rate; // needed for deceleration start point
#endif
xyz_long_t Stepper::endstops_trigsteps;
@@ -423,22 +424,9 @@ 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)); \
if (!extruder_duplication_enabled) { \
if (last_moved_extruder) \
X_DIR_WRITE(FWD); \
else X2_DIR_WRITE((FWD) ^ 1); \
}; \
}while(0)
#define Y_APPLY_DIR(FWD,Q) do{ Y_DIR_WRITE(FWD); Y2_DIR_WRITE(INVERT_DIR(Y2_VS_Y, FWD)); }while(0)
#if ENABLED(Y_DUAL_ENDSTOPS)
#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)
#define Y_APPLY_STEP(FWD,Q) DUAL_ENDSTOP_APPLY_STEP(Y,FWD)
#else
#define Y_APPLY_STEP(FWD,Q) do{ Y_STEP_WRITE(FWD); Y2_STEP_WRITE(FWD); }while(0)
#endif
@@ -801,34 +789,34 @@ void Stepper::apply_directions() {
*
* And for each point, evaluate the curve with the following sequence:
*
* void lsrs(uint32_t& d, uint32_t s, int cnt) {
* void lsrs(uint64_t& d, uint64_t s, int cnt) {
* d = s >> cnt;
* }
* void lsls(uint32_t& d, uint32_t s, int cnt) {
* void lsls(uint64_t& d, uint64_t s, int cnt) {
* d = s << cnt;
* }
* void lsrs(int32_t& d, uint32_t s, int cnt) {
* d = uint32_t(s) >> cnt;
* void lsrs(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 lsls(int32_t& d, uint64_t s, int cnt) {
* d = uint64_t(s) << cnt;
* }
* void umull(uint32_t& rlo, uint32_t& rhi, uint32_t op1, uint32_t op2) {
* void umull(uint64_t& rlo, uint64_t& rhi, uint64_t op1, uint64_t op2) {
* uint64_t res = uint64_t(op1) * op2;
* rlo = uint32_t(res & 0xFFFFFFFF);
* rhi = uint32_t((res >> 32) & 0xFFFFFFFF);
* rlo = uint64_t(res & 0xFFFFFFFF);
* rhi = uint64_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(uint32_t(rlo) | ((uint64_t(uint32_t(rhi)) << 32U)));
* int64_t s = int64_t(uint64_t(rlo) | ((uint64_t(uint64_t(rhi)) << 32U)));
* mul += s;
* rlo = int32_t(mul & 0xFFFFFFFF);
* rhi = int32_t((mul >> 32) & 0xFFFFFFFF);
* }
* 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 _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 alo = bezier_F;
* int32_t ahi = 0;
* int32_t A = bezier_A;
@@ -878,7 +866,7 @@ void Stepper::apply_directions() {
*
* And for each curve, estimate its coefficients with:
*
* void _calc_bezier_curve_coeffs(int32_t v0, int32_t v1, uint32_t av) {
* void _calc_bezier_curve_coeffs(int32_t v0, int32_t v1, uint64_t av) {
* // Calculate the Bézier coefficients
* if (v1 < v0) {
* A_negative = true;
@@ -903,14 +891,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 = (uint32_t(op1) * op2) >> 16;
* r = (uint64_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(uint32_t curr_step) {
* int32_t _eval_bezier_curve(uint64_t curr_step) {
* // To save computing, the first step is always the initial speed
* if (!curr_step)
* return bezier_F;
@@ -952,7 +940,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 uint32_t av) {
void Stepper::_calc_bezier_curve_coeffs(const int32_t v0, const int32_t v1, const uint64_t av) {
// Store advance
bezier_AV = av;
@@ -1054,7 +1042,7 @@ void Stepper::apply_directions() {
);
}
FORCE_INLINE int32_t Stepper::_eval_bezier_curve(const uint32_t curr_step) {
FORCE_INLINE int32_t Stepper::_eval_bezier_curve(const uint64_t curr_step) {
// If dealing with the first step, save expensive computing and return the initial speed
if (!curr_step)
@@ -1436,13 +1424,13 @@ void Stepper::apply_directions() {
:
:"cc","r0","r1"
);
return (r2 | (uint16_t(r3) << 8)) | (uint32_t(r4) << 16);
return (r2 | (uint16_t(r3) << 8)) | (uint64_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 uint32_t av) {
FORCE_INLINE void Stepper::_calc_bezier_curve_coeffs(const int32_t v0, const int32_t v1, const uint64_t av) {
// Calculate the Bézier coefficients
#ifndef S_CURVE_FACTOR
bezier_A = 768 * (v1 - v0);
@@ -1459,13 +1447,13 @@ void Stepper::apply_directions() {
bezier_AV = av;
}
FORCE_INLINE int32_t Stepper::_eval_bezier_curve(const uint32_t curr_step) {
FORCE_INLINE int32_t Stepper::_eval_bezier_curve(const uint64_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
uint32_t flo = 0;
uint32_t fhi = bezier_AV * curr_step;
uint32_t t = fhi;
uint64_t flo = 0;
uint64_t fhi = bezier_AV * curr_step;
uint64_t t = fhi;
int32_t alo = bezier_F;
int32_t ahi = 0;
int32_t A = bezier_A;
@@ -1507,7 +1495,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
uint32_t t = bezier_AV * curr_step; // t: Range 32 bits
uint64_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)
@@ -1516,13 +1504,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 += ((uint32_t) f >> 1) * (int64_t) bezier_C; // Range 29bits + 31 = 60bits (plus sign)
acc += ((uint64_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 += ((uint32_t) f >> 1) * (int64_t) bezier_B; // Range 29bits + 31 = 60bits (plus sign)
acc += ((uint64_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 += ((uint32_t) f >> 1) * (int64_t) bezier_A; // Range 28bits + 31 = 59bits (plus sign)
acc += ((uint64_t) f >> 1) * (int64_t) bezier_A; // Range 28bits + 31 = 59bits (plus sign)
acc >>= (31 + 7); // Range 24bits (plus sign)
return (int32_t) acc;
@@ -1537,7 +1525,14 @@ void Stepper::apply_directions() {
* Directly pulses the stepper motors at high frequency.
*/
HAL_STEP_TIMER_ISR() {
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_timer_isr_prologue(MF_TIMER_STEP);
Stepper::isr();
@@ -1555,12 +1550,6 @@ 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
@@ -1581,8 +1570,6 @@ 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;
@@ -1603,6 +1590,9 @@ 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?
@@ -1631,6 +1621,9 @@ 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
@@ -1644,7 +1637,7 @@ void Stepper::isr() {
#endif
// Get the interval to the next ISR call
interval = _MIN(nextMainISR, uint32_t(HAL_TIMER_TYPE_MAX)); // Time until the next Pulse / Block phase
interval = _MIN(nextMainISR, uint64_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
@@ -1764,7 +1757,7 @@ void Stepper::isr() {
#if MINIMUM_STEPPER_PULSE || MAXIMUM_STEPPER_RATE
#define ISR_PULSE_CONTROL 1
#endif
#if ISR_PULSE_CONTROL && DISABLED(I2S_STEPPER_STREAM)
#if ISR_PULSE_CONTROL && MULTISTEPPING_LIMIT > 1 && DISABLED(I2S_STEPPER_STREAM)
#define ISR_MULTI_STEPS 1
#endif
@@ -1807,17 +1800,15 @@ void Stepper::pulse_phase_isr() {
if (TERN0(FREEZE_FEATURE, frozen)) return;
// Count of pending loops and events for this iteration
const uint32_t pending_events = step_event_count - step_events_completed;
const uint64_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)
#if ISR_MULTI_STEPS
bool firstStep = true;
USING_TIMED_PULSE();
#endif
TERN_(ISR_MULTI_STEPS, bool firstStep = true);
// Direct Stepping page?
const bool is_page = current_block->is_page();
@@ -2006,7 +1997,7 @@ void Stepper::pulse_phase_isr() {
if (!is_page) {
// Give the compiler a clue to store advance_divisor in registers for what follows
const uint32_t advance_divisor_cached = advance_divisor;
const uint64_t advance_divisor_cached = advance_divisor;
// Determine if pulses are needed
#if HAS_X_STEP
@@ -2122,7 +2113,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_MULTI_STEPS
#if ISR_PULSE_CONTROL
START_TIMED_PULSE();
AWAIT_HIGH_PULSE();
#endif
@@ -2237,24 +2228,24 @@ void Stepper::pulse_phase_isr() {
#endif // HAS_ZV_SHAPING
// Calculate timer interval, with all limits applied.
hal_timer_t Stepper::calc_timer_interval(uint32_t step_rate) {
hal_timer_t Stepper::calc_timer_interval(uint64_t step_rate) {
constexpr uint64_t min_step_rate = MINIMAL_STEP_RATE;
#ifdef CPU_32_BIT
// A fast processor can just do integer division
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;
return step_rate > min_step_rate ? uint64_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 uint32_t(STEPPER_TIMER_RATE) / 0x10000;
return uint64_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));
@@ -2274,8 +2265,8 @@ hal_timer_t Stepper::calc_timer_interval(uint32_t step_rate) {
}
#if ENABLED(NONLINEAR_EXTRUSION)
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
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
int32_t vd = (((int64_t)ne_fix.A * velocity) >> 24) + (((((int64_t)ne_fix.B * velocity) >> 24) * velocity) >> 24);
NOLESS(vd, 0);
@@ -2284,19 +2275,19 @@ hal_timer_t Stepper::calc_timer_interval(uint32_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(uint32_t step_rate) {
hal_timer_t Stepper::calc_multistep_timer_interval(uint64_t step_rate) {
#if ENABLED(OLD_ADAPTIVE_MULTISTEPPING)
#if MULTISTEPPING_LIMIT == 1
// Just make sure the step rate is doable
NOMORE(step_rate, uint32_t(MAX_STEP_ISR_FREQUENCY_1X));
NOMORE(step_rate, uint64_t(MAX_STEP_ISR_FREQUENCY_1X));
#else
// The stepping frequency limits for each multistepping rate
static const uint32_t limit[] PROGMEM = {
static const uint64_t limit[] PROGMEM = {
( MAX_STEP_ISR_FREQUENCY_1X )
, (((F_CPU) / ISR_EXECUTION_CYCLES(1)) >> 1)
#if MULTISTEPPING_LIMIT >= 4
@@ -2321,7 +2312,7 @@ hal_timer_t Stepper::calc_multistep_timer_interval(uint32_t step_rate) {
// Find a doable step rate using multistepping
uint8_t multistep = 1;
for (uint8_t i = 0; i < COUNT(limit) && step_rate > uint32_t(pgm_read_dword(&limit[i])); ++i) {
for (uint8_t i = 0; i < COUNT(limit) && step_rate > uint64_t(pgm_read_dword(&limit[i])); ++i) {
step_rate >>= 1;
multistep <<= 1;
}
@@ -2476,11 +2467,11 @@ hal_timer_t Stepper::block_phase_isr() {
// Step events not completed yet...
// Are we in acceleration phase ?
if (step_events_completed <= accelerate_until) { // Calculate new timer value
if (step_events_completed < accelerate_before) { // Calculate new timer value
#if ENABLED(S_CURVE_ACCELERATION)
// Get the next speed to use (Jerk limited!)
uint32_t acc_step_rate = acceleration_time < current_block->acceleration_time
uint64_t acc_step_rate = acceleration_time < current_block->acceleration_time
? _eval_bezier_curve(acceleration_time)
: current_block->cruise_rate;
#else
@@ -2493,6 +2484,7 @@ 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);
@@ -2500,7 +2492,7 @@ hal_timer_t Stepper::block_phase_isr() {
#if ENABLED(LIN_ADVANCE)
if (la_active) {
const uint32_t la_step_rate = la_advance_steps < current_block->max_adv_steps ? current_block->la_advance_rate : 0;
const uint64_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
@@ -2514,16 +2506,13 @@ 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;
current_block->laser.trap_ramp_active_pwr += current_block->laser.trap_ramp_entry_incr * steps_per_isr;
}
}
// Not a powered move.
@@ -2532,30 +2521,24 @@ hal_timer_t Stepper::block_phase_isr() {
#endif
}
// Are we in Deceleration phase ?
else if (step_events_completed > decelerate_after) {
uint32_t step_rate;
else if (step_events_completed >= decelerate_start) {
uint64_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;
}
else {
// Calculate the next speed to use
step_rate = deceleration_time < current_block->deceleration_time
? _eval_bezier_curve(deceleration_time)
: current_block->final_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
// Using the old trapezoidal control
step_rate = STEP_MULTIPLY(deceleration_time, current_block->acceleration_rate);
if (step_rate < acc_step_rate) { // Still decelerating?
if (step_rate < acc_step_rate) {
step_rate = acc_step_rate - step_rate;
NOLESS(step_rate, current_block->final_rate);
}
@@ -2574,7 +2557,7 @@ hal_timer_t Stepper::block_phase_isr() {
#if ENABLED(LIN_ADVANCE)
if (la_active) {
const uint32_t la_step_rate = la_advance_steps > current_block->final_adv_steps ? current_block->la_advance_rate : 0;
const uint64_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);
@@ -2597,15 +2580,12 @@ hal_timer_t Stepper::block_phase_isr() {
}
#endif // LIN_ADVANCE
/**
* Adjust Laser Power - Decelerating
* trap_ramp_entry_decr - holds the precalculated value to decrease the current power per decel step.
*/
// Adjust Laser Power - Decelerating
#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;
current_block->laser.trap_ramp_active_pwr -= current_block->laser.trap_ramp_exit_decr * steps_per_isr;
cutter.apply_power(current_block->laser.trap_ramp_active_pwr);
}
// Not a powered move.
@@ -2621,6 +2601,9 @@ 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);
@@ -2630,6 +2613,20 @@ 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
@@ -2642,7 +2639,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_until) {
if (step_events_completed + 1 == accelerate_before) {
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;
@@ -2745,11 +2742,85 @@ hal_timer_t Stepper::block_phase_isr() {
}
#endif
// Set flags for all moving axes, accounting for kinematics
set_axis_moved_for_current_block();
// Flag all moving axes for proper endstop handling
// No acceleration / deceleration time elapsed so far
acceleration_time = deceleration_time = 0;
#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;
#if ENABLED(ADAPTIVE_STEP_SMOOTHING)
// Nonlinear Extrusion needs at least 2x oversampling to permit increase of E step rate
@@ -2758,7 +2829,7 @@ hal_timer_t Stepper::block_phase_isr() {
// Decide if axis smoothing is possible
if (stepper.adaptive_step_smoothing_enabled) {
uint32_t max_rate = current_block->nominal_rate; // Get the step event rate
uint64_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
@@ -2813,8 +2884,8 @@ hal_timer_t Stepper::block_phase_isr() {
step_events_completed = 0;
// Compute the acceleration and deceleration points
accelerate_until = current_block->accelerate_until << oversampling_factor;
decelerate_after = current_block->decelerate_after << oversampling_factor;
accelerate_before = current_block->accelerate_before << oversampling_factor;
decelerate_start = current_block->decelerate_start << oversampling_factor;
TERN_(MIXING_EXTRUDER, mixer.stepper_setup(current_block->b_color));
@@ -2900,7 +2971,8 @@ hal_timer_t Stepper::block_phase_isr() {
// Calculate the initial timer interval
interval = calc_multistep_timer_interval(current_block->initial_rate << oversampling_factor);
acceleration_time += interval;
// Initialize ac/deceleration time as if half the time passed.
acceleration_time = deceleration_time = interval / 2;
#if ENABLED(NONLINEAR_EXTRUSION)
calc_nonlinear_e(current_block->initial_rate << oversampling_factor);
@@ -2908,7 +2980,7 @@ hal_timer_t Stepper::block_phase_isr() {
#if ENABLED(LIN_ADVANCE)
if (la_active) {
const uint32_t la_step_rate = la_advance_steps < current_block->max_adv_steps ? current_block->la_advance_rate : 0;
const uint64_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
@@ -3328,7 +3400,7 @@ void Stepper::init() {
const bool was_on = hal.isr_state();
hal.isr_off();
const shaping_time_t delay = freq ? float(uint32_t(STEPPER_TIMER_RATE) / 2) / freq : shaping_time_t(-1);
const shaping_time_t delay = freq ? float(uint64_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); \
@@ -3813,7 +3885,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 > uint32_t(HAL_timer_get_count(MF_TIMER_PULSE) - pulse_start) * (PULSE_TIMER_PRESCALE)) { /* nada */ }
#define _PULSE_WAIT() while (EXTRA_CYCLES_BABYSTEP > uint64_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 uint32_t digipot_count[] = DIGIPOT_MOTOR_CURRENT;
static constexpr uint64_t digipot_count[] = DIGIPOT_MOTOR_CURRENT;
#define MOTOR_CURRENT_COUNT COUNT(Stepper::digipot_count)
#endif
static bool initialized;
static uint32_t motor_current_setting[MOTOR_CURRENT_COUNT]; // Initialized by settings.load()
static uint64_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 uint32_t acceleration_time, deceleration_time; // time measured in Stepper Timer ticks
static uint64_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 uint32_t advance_divisor,
static uint64_t advance_divisor,
step_events_completed, // The number of step events executed in the current block
accelerate_until, // The point from where we need to stop acceleration
decelerate_after, // The point from where we need to start decelerating
accelerate_before, // The point from where we need to stop acceleration
decelerate_start, // 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 uint32_t bezier_F, // F/free coefficient in Bézier speed curve
static uint64_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 uint32_t ne_scale;
static uint64_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 uint32_t acc_step_rate; // needed for deceleration start point
static uint64_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
static void isr();
FORCE_INLINE static void isr();
// The stepper pulse ISR phase
static void pulse_phase_isr();
FORCE_INLINE static void pulse_phase_isr();
// The stepper block processing ISR phase
static hal_timer_t block_phase_isr();
FORCE_INLINE static hal_timer_t block_phase_isr();
#if HAS_ZV_SHAPING
static void shaping_isr();
FORCE_INLINE static void shaping_isr();
#endif
#if ENABLED(LIN_ADVANCE)
// The Linear advance ISR phase
static void advance_isr();
FORCE_INLINE 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(uint32_t step_rate);
static hal_timer_t calc_timer_interval(uint64_t step_rate);
// Calculate timing interval and steps-per-ISR for the given step rate
static hal_timer_t calc_multistep_timer_interval(uint32_t step_rate);
static hal_timer_t calc_multistep_timer_interval(uint64_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(uint32_t step_rate);
static void calc_nonlinear_e(uint64_t step_rate);
#endif
#if ENABLED(S_CURVE_ACCELERATION)
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);
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);
#endif
#if HAS_MOTOR_CURRENT_SPI || HAS_MOTOR_CURRENT_PWM
+29 -32
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 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 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 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 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 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 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 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 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 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 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 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 E6_SERIAL_TX_PIN P0_27
#define E6_SERIAL_RX_PIN P0_27
#define E7_SERIAL_TX_PIN P2_29
@@ -181,7 +181,6 @@
#define TEMP_3_PIN P0_26
#define TEMP_BED_PIN P1_31
#define TEMP_CHAMBER_PIN TEMP_2_PIN
//
// Heaters / Fans
//
@@ -192,8 +191,6 @@
#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
+151 -163
View File
@@ -22,11 +22,31 @@
#pragma once
/**
* Native with a RAMPS like board with additional pins
* 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
*/
#ifndef BOARD_INFO_NAME
#define BOARD_INFO_NAME "RAMPS Native"
#define BOARD_INFO_NAME "RAMPS 1.4"
#endif
#ifndef DEFAULT_MACHINE_NAME
@@ -40,24 +60,28 @@
//
// Servos
//
#define SERVO0_PIN 151
#define SERVO1_PIN 152
#define SERVO2_PIN 153
#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
#ifndef SERVO3_PIN
#define SERVO3_PIN 154
#define SERVO3_PIN 4
#endif
//
// Limit Switches
//
#define X_MIN_PIN 155
#define X_MIN_PIN 3
#ifndef X_MAX_PIN
#define X_MAX_PIN 156
#define X_MAX_PIN 2
#endif
#define Y_MIN_PIN 157
#define Y_MAX_PIN 158
#define Z_MIN_PIN 159
#define Z_MAX_PIN 160
#define Y_MIN_PIN 14
#define Y_MAX_PIN 15
#define Z_MIN_PIN 18
#define Z_MAX_PIN 19
//
// Z Probe (when not Z_MIN_PIN)
@@ -104,60 +128,24 @@
#define E1_CS_PIN 44
#endif
#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 Z4_STEP_PIN 13
#define Z4_DIR_PIN 71
#define Z4_ENABLE_PIN 12
#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 Z2_STEP_PIN 4
#define Z2_DIR_PIN 5
#define Z2_ENABLE_PIN 6
#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
#define Z3_STEP_PIN 12
#define Z3_DIR_PIN 40
#define Z3_ENABLE_PIN 44
//
// Temperature Sensors
//
#define TEMP_0_PIN 0 // Analog Input
#define TEMP_1_PIN 1 // 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
#define TEMP_BED_PIN 2 // Analog Input
// SPI for MAX Thermocouple
#if !HAS_MEDIA
@@ -169,33 +157,55 @@
//
// Heaters / Fans
//
#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 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
#ifndef FAN0_PIN
#define FAN0_PIN 161 // IO pin. Buffer needed
#define FAN0_PIN 4 // 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 BOARD_NEOPIXEL_PIN 71
#define NEOPIXEL_PIN 71
#ifndef FILWIDTH_PIN
#define FILWIDTH_PIN 5 // Analog Input on AUX2
@@ -373,37 +383,9 @@
#endif
#endif
/** 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
//
//////////////////////////
// LCDs and Controllers //
//////////////////////////
#if ANY(TFT_COLOR_UI, TFT_CLASSIC_UI, TFT_LVGL_UI)
@@ -415,11 +397,10 @@
#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
@@ -504,9 +485,9 @@
//
#if ENABLED(REPRAPWORLD_GRAPHICAL_LCD)
#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
#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
#elif ALL(IS_NEWPANEL, PANEL_ONE)
@@ -521,12 +502,12 @@
#if ENABLED(CR10_STOCKDISPLAY)
#define LCD_PINS_RS EXP1_07_PIN
#define LCD_PINS_EN EXP1_08_PIN
#define LCD_PINS_D4 EXP1_06_PIN
#define LCD_PINS_RS 27
#define LCD_PINS_EN 29
#define LCD_PINS_D4 25
#if !IS_NEWPANEL
#define BEEPER_PIN EXP1_01_PIN
#define BEEPER_PIN 37
#endif
#elif ENABLED(ZONESTAR_LCD)
@@ -541,28 +522,38 @@
#else
#if ANY(MKS_12864OLED, MKS_12864OLED_SSD1306)
#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
#define LCD_PINS_DC 25 // Set as output on init
#define LCD_PINS_RS 27 // Pull low for 1s to init
// DOGM SPI LCD Support
#define DOGLCD_CS EXP1_04_PIN
#define DOGLCD_MOSI EXP1_03_PIN
#define DOGLCD_SCK EXP1_05_PIN
#define DOGLCD_CS 16
#define DOGLCD_MOSI 17
#define DOGLCD_SCK 23
#define DOGLCD_A0 LCD_PINS_DC
#else
#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
#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
#endif
#define LCD_PINS_D7 EXP1_08_PIN
#define LCD_PINS_D7 29
#if !IS_NEWPANEL
#define BEEPER_PIN EXP2_05_PIN
#define BEEPER_PIN 33
#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
//
@@ -572,19 +563,19 @@
#if ENABLED(REPRAP_DISCOUNT_SMART_CONTROLLER)
#define BEEPER_PIN EXP1_01_PIN
#define BEEPER_PIN 37
#if ENABLED(CR10_STOCKDISPLAY)
#define BTN_EN1 EXP1_03_PIN
#define BTN_EN2 EXP1_05_PIN
#define BTN_EN1 17
#define BTN_EN2 23
#else
#define BTN_EN1 EXP2_03_PIN
#define BTN_EN2 EXP2_05_PIN
#define BTN_EN1 31
#define BTN_EN2 33
#endif
#define BTN_ENC EXP1_02_PIN
#define SD_DETECT_PIN EXP2_07_PIN
#define KILL_PIN EXP2_08_PIN
#define BTN_ENC 35
#define SD_DETECT_PIN 49
#define KILL_PIN 41
#if ENABLED(BQ_LCD_SMART_CONTROLLER)
#define LCD_BACKLIGHT_PIN 39
@@ -634,34 +625,34 @@
#elif ENABLED(ELB_FULL_GRAPHIC_CONTROLLER)
#define DOGLCD_CS EXP1_08_PIN
#define DOGLCD_A0 EXP1_07_PIN
#define DOGLCD_CS 29
#define DOGLCD_A0 27
#define BEEPER_PIN EXP1_05_PIN
#define LCD_BACKLIGHT_PIN EXP2_05_PIN
#define BEEPER_PIN 23
#define LCD_BACKLIGHT_PIN 33
#define BTN_EN1 EXP1_02_PIN
#define BTN_EN2 EXP1_01_PIN
#define BTN_ENC EXP2_03_PIN
#define BTN_EN1 35
#define BTN_EN2 37
#define BTN_ENC 31
#define LCD_SDSS SDSS
#define SD_DETECT_PIN EXP2_07_PIN
#define KILL_PIN EXP2_08_PIN
#define SD_DETECT_PIN 49
#define KILL_PIN 41
#elif ENABLED(MKS_MINI_12864)
#define DOGLCD_A0 EXP1_07_PIN
#define DOGLCD_CS EXP1_06_PIN
#define DOGLCD_A0 27
#define DOGLCD_CS 25
#define BEEPER_PIN EXP1_01_PIN
#define BEEPER_PIN 37
// not connected to a pin
#define LCD_BACKLIGHT_PIN 65 // backlight LED on A11/D65
#define BTN_EN1 EXP2_03_PIN
#define BTN_EN2 EXP2_05_PIN
#define BTN_ENC EXP1_02_PIN
#define BTN_EN1 31
#define BTN_EN2 33
#define BTN_ENC 35
#define SD_DETECT_PIN EXP2_07_PIN
#define SD_DETECT_PIN 49
#define KILL_PIN 64
//#define LCD_SCREEN_ROTATE 180 // 0, 90, 180, 270
@@ -694,6 +685,7 @@
#else
// Beeper on AUX-4
#define BEEPER_PIN 33
// Buttons are directly attached to AUX-2
@@ -709,15 +701,15 @@
#define BTN_EN2 63 // AUX2 PIN 4
#define BTN_ENC 49 // AUX3 PIN 7
#else
#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
#define BTN_EN1 37
#define BTN_EN2 35
#define BTN_ENC 31
#define SD_DETECT_PIN 41
#endif
#if ENABLED(G3D_PANEL)
#define SD_DETECT_PIN EXP2_07_PIN
#define KILL_PIN EXP2_08_PIN
#define SD_DETECT_PIN 49
#define KILL_PIN 41
#endif
#endif
@@ -727,7 +719,3 @@
#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) || !defined(PS_ON1_PIN)
#if DISABLED(PSU_OFF_REDUNDANT) || DISABLED(PSU_CONTROL) || !defined(PS_ON1_PIN)
#undef PS_ON1_PIN
#define PS_ON1_PIN -1
#endif
+2 -1
View File
@@ -158,7 +158,8 @@
#define LCD_BRIGHTNESS_DEFAULT TFT_BACKLIGHT_PWM
#endif
#if ENABLED(ONBOARD_SDIO)
#if SD_CONNECTION_IS(ONBOARD)
#define 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();
const bool found = selectNewestFile(); // Changes the current workDir if found
if (found) {
//SERIAL_ECHO_MSG(" OCP File: ", longest_filename(), "\n");
//ui.init();
one_click_print();
one_click_print(); // Restores workkDir to root (eventually)
}
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 \
SKEW_CORRECTION SKEW_CORRECTION_FOR_Z SKEW_CORRECTION_GCODE ONE_CLICK_PRINT NO_SD_AUTOSTART \
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>
HAS_MENU_ONE_CLICK_PRINT = build_src_filter=+<src/lcd/menu/menu_one_click_print.cpp> +<src/gcode/sd/M1003.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>
+3 -5
View File
@@ -27,8 +27,7 @@ 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 -O3
build_unflags = -Os
-IMarlin/src/HAL/LPC1768/include -IMarlin/src/HAL/LPC1768/u8g
# debug options for backtrace
#-funwind-tables
#-mpoke-function-name
@@ -49,10 +48,9 @@ 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 = mega2560
default_envs = LPC4078
include_dir = Marlin
extra_configs =
Marlin/config.ini