Bump to head and add new filament runout option

This commit is contained in:
InsanityAutomation
2018-09-30 15:32:14 -04:00
parent 1ab0d240b9
commit 3f42b06bc2
102 changed files with 3798 additions and 2078 deletions
+11 -1
View File
@@ -439,10 +439,20 @@
*/
#if ENABLED(DISTINCT_E_FACTORS) && E_STEPPERS > 1
#define XYZE_N (XYZ + E_STEPPERS)
#if ENABLED(HANGPRINTER)
#define NUM_AXIS_N (ABCD + E_STEPPERS)
#else
#define NUM_AXIS_N (XYZ + E_STEPPERS)
#endif
#define E_AXIS_N (E_AXIS + extruder)
#else
#undef DISTINCT_E_FACTORS
#define XYZE_N XYZE
#if ENABLED(HANGPRINTER)
#define NUM_AXIS_N ABCDE
#else
#define NUM_AXIS_N XYZE
#endif
#define E_AXIS_N E_AXIS
#endif
@@ -496,7 +506,7 @@
* Set flags for enabled probes
*/
#define HAS_BED_PROBE (ENABLED(FIX_MOUNTED_PROBE) || ENABLED(Z_PROBE_ALLEN_KEY) || HAS_Z_SERVO_PROBE || ENABLED(Z_PROBE_SLED) || ENABLED(SOLENOID_PROBE))
#define PROBE_SELECTED (HAS_BED_PROBE || ENABLED(PROBE_MANUALLY))
#define PROBE_SELECTED (HAS_BED_PROBE || ENABLED(PROBE_MANUALLY) || ENABLED(MESH_BED_LEVELING))
#if !HAS_BED_PROBE
// Clear probe pin settings when no probe is selected
+128 -26
View File
@@ -29,7 +29,7 @@
#define CONDITIONALS_POST_H
#define IS_SCARA (ENABLED(MORGAN_SCARA) || ENABLED(MAKERARM_SCARA))
#define IS_KINEMATIC (ENABLED(DELTA) || IS_SCARA)
#define IS_KINEMATIC (ENABLED(DELTA) || IS_SCARA || ENABLED(HANGPRINTER))
#define IS_CARTESIAN !IS_KINEMATIC
/**
@@ -47,7 +47,7 @@
#define Y_BED_SIZE Y_MAX_LENGTH
#endif
// Require 0,0 bed center for Delta and SCARA
// Require 0,0 bed center for Delta, SCARA, and HANGPRINTER
#if IS_KINEMATIC
#define BED_CENTER_AT_0_0
#endif
@@ -68,6 +68,18 @@
#define Y_MIN_BED (Y_CENTER - (Y_BED_SIZE) / 2)
#define Y_MAX_BED (Y_CENTER + (Y_BED_SIZE) / 2)
/**
* Dual X Carriage
*/
#if ENABLED(DUAL_X_CARRIAGE)
#ifndef X1_MIN_POS
#define X1_MIN_POS X_MIN_POS
#endif
#ifndef X1_MAX_POS
#define X1_MAX_POS X_BED_SIZE
#endif
#endif
/**
* CoreXY, CoreXZ, and CoreYZ - and their reverse
*/
@@ -117,7 +129,7 @@
#ifdef MANUAL_X_HOME_POS
#define X_HOME_POS MANUAL_X_HOME_POS
#elif ENABLED(BED_CENTER_AT_0_0)
#if ENABLED(DELTA)
#if ENABLED(DELTA) || ENABLED(HANGPRINTER)
#define X_HOME_POS 0
#else
#define X_HOME_POS ((X_BED_SIZE) * (X_HOME_DIR) * 0.5)
@@ -133,7 +145,7 @@
#ifdef MANUAL_Y_HOME_POS
#define Y_HOME_POS MANUAL_Y_HOME_POS
#elif ENABLED(BED_CENTER_AT_0_0)
#if ENABLED(DELTA)
#if (ENABLED(DELTA) || ENABLED(HANGPRINTER))
#define Y_HOME_POS 0
#else
#define Y_HOME_POS ((Y_BED_SIZE) * (Y_HOME_DIR) * 0.5)
@@ -400,6 +412,63 @@
#define ARRAY_BY_HOTENDS(...) ARRAY_N(HOTENDS, __VA_ARGS__)
#define ARRAY_BY_HOTENDS1(v1) ARRAY_BY_HOTENDS(v1, v1, v1, v1, v1, v1)
/**
* Driver Timings
* NOTE: Driver timing order is longest-to-shortest duration.
* Preserve this ordering when adding new drivers.
*/
#ifndef MINIMUM_STEPPER_DIR_DELAY
#if HAS_DRIVER(TB6560)
#define MINIMUM_STEPPER_DIR_DELAY 15000
#elif HAS_DRIVER(TB6600)
#define MINIMUM_STEPPER_DIR_DELAY 1500
#elif HAS_DRIVER(DRV8825)
#define MINIMUM_STEPPER_DIR_DELAY 650
#elif HAS_DRIVER(LV8729)
#define MINIMUM_STEPPER_DIR_DELAY 500
#elif HAS_DRIVER(A4988)
#define MINIMUM_STEPPER_DIR_DELAY 200
#elif HAS_TRINAMIC || HAS_DRIVER(TMC2660) || HAS_DRIVER(TMC2130_STANDALONE) || HAS_DRIVER(TMC2208_STANDALONE) || HAS_DRIVER(TMC26X_STANDALONE) || HAS_DRIVER(TMC2660_STANDALONE)
#define MINIMUM_STEPPER_DIR_DELAY 20
#else
#define MINIMUM_STEPPER_DIR_DELAY 200 // Expect at least 10µS since one Stepper ISR must transpire
#endif
#endif
#ifndef MINIMUM_STEPPER_PULSE
#if HAS_DRIVER(TB6560)
#define MINIMUM_STEPPER_PULSE 30
#elif HAS_DRIVER(TB6600)
#define MINIMUM_STEPPER_PULSE 3
#elif HAS_DRIVER(DRV8825)
#define MINIMUM_STEPPER_PULSE 2
#elif HAS_DRIVER(A4988) || HAS_DRIVER(LV8729)
#define MINIMUM_STEPPER_PULSE 1
#elif HAS_TRINAMIC || HAS_DRIVER(TMC2660) || HAS_DRIVER(TMC2130_STANDALONE) || HAS_DRIVER(TMC2208_STANDALONE) || HAS_DRIVER(TMC26X_STANDALONE) || HAS_DRIVER(TMC2660_STANDALONE)
#define MINIMUM_STEPPER_PULSE 0
#else
#define MINIMUM_STEPPER_PULSE 1
#endif
#endif
#ifndef MAXIMUM_STEPPER_RATE
#if HAS_DRIVER(TB6560)
#define MAXIMUM_STEPPER_RATE 15000
#elif HAS_DRIVER(LV8729)
#define MAXIMUM_STEPPER_RATE 130000
#elif HAS_DRIVER(TB6600)
#define MAXIMUM_STEPPER_RATE 150000
#elif HAS_DRIVER(DRV8825)
#define MAXIMUM_STEPPER_RATE 250000
#elif HAS_TRINAMIC || HAS_DRIVER(TMC2660) || HAS_DRIVER(TMC2130_STANDALONE) || HAS_DRIVER(TMC2208_STANDALONE) || HAS_DRIVER(TMC26X_STANDALONE) || HAS_DRIVER(TMC2660_STANDALONE)
#define MAXIMUM_STEPPER_RATE 400000
#elif HAS_DRIVER(A4988)
#define MAXIMUM_STEPPER_RATE 500000
#else
#define MAXIMUM_STEPPER_RATE 500000
#endif
#endif
/**
* X_DUAL_ENDSTOPS endstop reassignment
*/
@@ -660,28 +729,42 @@
#define HAS_E4_MICROSTEPS (PIN_EXISTS(E4_MS1))
#define HAS_SOLENOID_4 (PIN_EXISTS(SOL4))
#if ENABLED(HANGPRINTER)
#define HAS_A_ENABLE (PIN_EXISTS(A_ENABLE))
#define HAS_A_DIR (PIN_EXISTS(A_DIR))
#define HAS_A_STEP (PIN_EXISTS(A_STEP))
#define HAS_A_MICROSTEPS (PIN_EXISTS(A_MS1))
#define HAS_B_ENABLE (PIN_EXISTS(B_ENABLE))
#define HAS_B_DIR (PIN_EXISTS(B_DIR))
#define HAS_B_STEP (PIN_EXISTS(B_STEP))
#define HAS_B_MICROSTEPS (PIN_EXISTS(B_MS1))
#define HAS_C_ENABLE (PIN_EXISTS(C_ENABLE))
#define HAS_C_DIR (PIN_EXISTS(C_DIR))
#define HAS_C_STEP (PIN_EXISTS(C_STEP))
#define HAS_C_MICROSTEPS (PIN_EXISTS(C_MS1))
#define HAS_D_ENABLE (PIN_EXISTS(D_ENABLE))
#define HAS_D_DIR (PIN_EXISTS(D_DIR))
#define HAS_D_STEP (PIN_EXISTS(D_STEP))
#define HAS_D_MICROSTEPS (PIN_EXISTS(D_MS1))
#endif
// Trinamic Stepper Drivers
#define HAS_TRINAMIC (ENABLED(HAVE_TMC2130) || ENABLED(HAVE_TMC2208) || ENABLED(IS_TRAMS))
#define X_IS_TRINAMIC (ENABLED( X_IS_TMC2130) || ENABLED( X_IS_TMC2208) || ENABLED(IS_TRAMS))
#define X2_IS_TRINAMIC (ENABLED(X2_IS_TMC2130) || ENABLED(X2_IS_TMC2208))
#define Y_IS_TRINAMIC (ENABLED( Y_IS_TMC2130) || ENABLED( Y_IS_TMC2208) || ENABLED(IS_TRAMS))
#define Y2_IS_TRINAMIC (ENABLED(Y2_IS_TMC2130) || ENABLED(Y2_IS_TMC2208))
#define Z_IS_TRINAMIC (ENABLED( Z_IS_TMC2130) || ENABLED( Z_IS_TMC2208) || ENABLED(IS_TRAMS))
#define Z2_IS_TRINAMIC (ENABLED(Z2_IS_TMC2130) || ENABLED(Z2_IS_TMC2208))
#define E0_IS_TRINAMIC (ENABLED(E0_IS_TMC2130) || ENABLED(E0_IS_TMC2208) || ENABLED(IS_TRAMS))
#define E1_IS_TRINAMIC (ENABLED(E1_IS_TMC2130) || ENABLED(E1_IS_TMC2208))
#define E2_IS_TRINAMIC (ENABLED(E2_IS_TMC2130) || ENABLED(E2_IS_TMC2208))
#define E3_IS_TRINAMIC (ENABLED(E3_IS_TMC2130) || ENABLED(E3_IS_TMC2208))
#define E4_IS_TRINAMIC (ENABLED(E4_IS_TMC2130) || ENABLED(E4_IS_TMC2208))
#define HAS_STEALTHCHOP (HAS_DRIVER(TMC2130) || HAS_DRIVER(TMC2208))
#define HAS_STALLGUARD HAS_DRIVER(TMC2130)
#define AXIS_HAS_STEALTHCHOP(ST) ( AXIS_DRIVER_TYPE(ST, TMC2130) || AXIS_DRIVER_TYPE(ST, TMC2208) )
#define AXIS_HAS_STALLGUARD(ST) AXIS_DRIVER_TYPE(ST, TMC2130)
#if ENABLED(SENSORLESS_HOMING)
// Disable Z axis sensorless homing if a probe is used to home the Z axis
#if HOMING_Z_WITH_PROBE
#undef Z_HOMING_SENSITIVITY
#endif
#define X_SENSORLESS (ENABLED(X_IS_TMC2130) && defined(X_HOMING_SENSITIVITY))
#define Y_SENSORLESS (ENABLED(Y_IS_TMC2130) && defined(Y_HOMING_SENSITIVITY))
#define Z_SENSORLESS (ENABLED(Z_IS_TMC2130) && defined(Z_HOMING_SENSITIVITY))
#define X_SENSORLESS (AXIS_HAS_STALLGUARD(X) && defined(X_HOMING_SENSITIVITY))
#define Y_SENSORLESS (AXIS_HAS_STALLGUARD(Y) && defined(Y_HOMING_SENSITIVITY))
#define Z_SENSORLESS (AXIS_HAS_STALLGUARD(Z) && defined(Z_HOMING_SENSITIVITY))
#endif
// Endstops and bed probe
@@ -1233,13 +1316,19 @@
#define Z_HOMING_HEIGHT Z_CLEARANCE_BETWEEN_PROBES
#endif
#endif
#ifndef Z_CLEARANCE_BETWEEN_PROBES
#define Z_CLEARANCE_BETWEEN_PROBES Z_HOMING_HEIGHT
#endif
#if Z_CLEARANCE_BETWEEN_PROBES > Z_HOMING_HEIGHT
#define MANUAL_PROBE_HEIGHT Z_CLEARANCE_BETWEEN_PROBES
#else
#define MANUAL_PROBE_HEIGHT Z_HOMING_HEIGHT
#if PROBE_SELECTED
#ifndef Z_CLEARANCE_BETWEEN_PROBES
#define Z_CLEARANCE_BETWEEN_PROBES Z_HOMING_HEIGHT
#endif
#if Z_CLEARANCE_BETWEEN_PROBES > Z_HOMING_HEIGHT
#define MANUAL_PROBE_HEIGHT Z_CLEARANCE_BETWEEN_PROBES
#else
#define MANUAL_PROBE_HEIGHT Z_HOMING_HEIGHT
#endif
#ifndef Z_CLEARANCE_MULTI_PROBE
#define Z_CLEARANCE_MULTI_PROBE Z_CLEARANCE_BETWEEN_PROBES
#endif
#endif
// Updated G92 behavior shifts the workspace
@@ -1312,4 +1401,17 @@
#define HAS_FOLDER_SORTING (FOLDER_SORTING || ENABLED(SDSORT_GCODE))
#endif
/**
* MOV_AXIS: number of independent axes driving the tool head's translational movement
* NUM_AXIS: number of movement axes + 1
* NUM_AXIS_N: number of movement axes + number of extruders (defined elsewhere)
*/
#if ENABLED(HANGPRINTER)
#define MOV_AXIS ABCD
#define NUM_AXIS ABCDE
#else
#define MOV_AXIS XYZ
#define NUM_AXIS XYZE
#endif
#endif // CONDITIONALS_POST_H
+8 -3
View File
@@ -6,7 +6,7 @@
// CUSTOMIZE FOR YOUR MACHINE BELOW
/**
* Enable if you replace the stepper drivers with TMC 2208. Be sure to remove MS3 jumper
* Enable if you replace the stepper drivers with TMC 2208. Be sure to remove MS3 jumper
* underneath the stepper driver! Plug and Play will result in Stealth Chop 2 Mode enabled
* Stealthchop with 2208 on E will disabe inear Advance! Please enable stealthchop if
* you require Linear Advance with a TMC2208 on the extruder!
@@ -30,6 +30,7 @@
* Enable if you install a filament runout sensor from www.formbotusa.com
*/
//#define RunoutSensor
//#define ledgeFilSensor //Modify filament sensor contact type for TM3D V2 sensors
/**
* Enable if you wish to change the auto level strategy to Unified Bed Leveling. Under CUSTOM COMMANDS, run Step 1 and 2 before setting Z Offset
@@ -952,7 +953,11 @@
#if ENABLED(FILAMENT_RUNOUT_SENSOR)
#define NUM_RUNOUT_SENSORS 1 // Number of sensors, up to one per extruder. Define a FIL_RUNOUT#_PIN for each.
#define FIL_RUNOUT_PIN 57
#define FIL_RUNOUT_INVERTING true // set to true to invert the logic of the sensor.
#if ENABLED(ledgeFilSensor)
#define FIL_RUNOUT_INVERTING false // set to true to invert the logic of the sensor.
#else
#define FIL_RUNOUT_INVERTING true // set to true to invert the logic of the sensor.
#endif
#define FIL_RUNOUT_PULLUP // Use internal pullup for filament runout pins.
#define FILAMENT_RUNOUT_SCRIPT "M600"
#endif
@@ -1141,7 +1146,7 @@
#endif
// Add a menu item to move between bed corners for manual bed adjustment
//#define LEVEL_BED_CORNERS
#define LEVEL_BED_CORNERS
/**
* Commands to execute at the end of G29 probing.
+6 -6
View File
@@ -198,7 +198,7 @@
destination[X_AXIS] = current_position[X_AXIS];
destination[Y_AXIS] = current_position[Y_AXIS];
destination[Z_AXIS] = z; // We know the last_z==z or we wouldn't be in this block of code.
destination[E_AXIS] = current_position[E_AXIS];
destination[E_CART] = current_position[E_CART];
G26_line_to_destination(feed_value);
set_destination_from_current();
@@ -212,7 +212,7 @@
destination[X_AXIS] = rx;
destination[Y_AXIS] = ry;
destination[E_AXIS] += e_delta;
destination[E_CART] += e_delta;
G26_line_to_destination(feed_value);
set_destination_from_current();
@@ -254,7 +254,7 @@
while (!is_lcd_clicked()) {
lcd_chirp();
destination[E_AXIS] += 0.25;
destination[E_CART] += 0.25;
#ifdef PREVENT_LENGTHY_EXTRUDE
Total_Prime += 0.25;
if (Total_Prime >= EXTRUDE_MAXLENGTH) return G26_ERR;
@@ -283,7 +283,7 @@
lcd_quick_feedback(true);
#endif
set_destination_from_current();
destination[E_AXIS] += g26_prime_length;
destination[E_CART] += g26_prime_length;
G26_line_to_destination(planner.max_feedrate_mm_s[E_AXIS] / 15.0);
set_destination_from_current();
retract_filament(destination);
@@ -697,7 +697,7 @@
if (turn_on_heaters() != G26_OK) goto LEAVE;
current_position[E_AXIS] = 0.0;
current_position[E_CART] = 0.0;
sync_plan_position_e();
if (g26_prime_flag && prime_nozzle() != G26_OK) goto LEAVE;
@@ -812,7 +812,7 @@
const float endpoint[XYZE] = {
ex, ey,
g26_layer_height,
current_position[E_AXIS] + (arc_length * g26_e_axis_feedrate * g26_extrusion_multiplier)
current_position[E_CART] + (arc_length * g26_e_axis_feedrate * g26_extrusion_multiplier)
};
if (dist_start > 2.0) {
+2 -3
View File
@@ -152,8 +152,6 @@ FORCE_INLINE void HAL_timer_start(const uint8_t timer_num, const uint32_t freque
#define _CAT(a, ...) a ## __VA_ARGS__
#define HAL_timer_set_compare(timer, compare) (_CAT(TIMER_OCR_, timer) = compare)
#define HAL_timer_restrain(timer, interval_ticks) NOLESS(_CAT(TIMER_OCR_, timer), _CAT(TIMER_COUNTER_, timer) + interval_ticks)
#define HAL_timer_get_compare(timer) _CAT(TIMER_OCR_, timer)
#define HAL_timer_get_count(timer) _CAT(TIMER_COUNTER_, timer)
@@ -327,7 +325,8 @@ inline void HAL_adc_init(void) {
#define HAL_START_ADC(pin) ADCSRB = 0; SET_ADMUX_ADCSRA(pin)
#endif
#define HAL_READ_ADC ADC
#define HAL_READ_ADC() ADC
#define HAL_ADC_READY() !TEST(ADCSRA, ADSC)
#define GET_PIN_MAP_PIN(index) index
#define GET_PIN_MAP_INDEX(pin) pin
+2 -3
View File
@@ -530,9 +530,8 @@ CSTANDARD = -std=gnu99
CXXSTANDARD = -std=gnu++11
CDEBUG = -g$(DEBUG)
CWARN = -Wall -Wstrict-prototypes
CTUNING = -funsigned-char -funsigned-bitfields -fpack-struct \
-fshort-enums -w -ffunction-sections -fdata-sections \
-flto \
CTUNING = -w -fsigned-char -funsigned-bitfields -fpack-struct \
-fshort-enums -ffunction-sections -fdata-sections -flto \
-DARDUINO=$(ARDUINO_VERSION)
ifneq ($(HARDWARE_MOTHERBOARD),)
CTUNING += -DMOTHERBOARD=${HARDWARE_MOTHERBOARD}
+99 -4
View File
@@ -96,7 +96,10 @@ extern const char axis_codes[XYZE];
/**
* Mixing steppers synchronize their enable (and direction) together
*/
#if MIXING_STEPPERS > 3
#if MIXING_STEPPERS > 4
#define enable_E0() { E0_ENABLE_WRITE( E_ENABLE_ON); E1_ENABLE_WRITE( E_ENABLE_ON); E2_ENABLE_WRITE( E_ENABLE_ON); E3_ENABLE_WRITE( E_ENABLE_ON); E4_ENABLE_WRITE( E_ENABLE_ON); }
#define disable_E0() { E0_ENABLE_WRITE(!E_ENABLE_ON); E1_ENABLE_WRITE(!E_ENABLE_ON); E2_ENABLE_WRITE(!E_ENABLE_ON); E3_ENABLE_WRITE(!E_ENABLE_ON); E4_ENABLE_WRITE(!E_ENABLE_ON); }
#elif MIXING_STEPPERS > 3
#define enable_E0() { E0_ENABLE_WRITE( E_ENABLE_ON); E1_ENABLE_WRITE( E_ENABLE_ON); E2_ENABLE_WRITE( E_ENABLE_ON); E3_ENABLE_WRITE( E_ENABLE_ON); }
#define disable_E0() { E0_ENABLE_WRITE(!E_ENABLE_ON); E1_ENABLE_WRITE(!E_ENABLE_ON); E2_ENABLE_WRITE(!E_ENABLE_ON); E3_ENABLE_WRITE(!E_ENABLE_ON); }
#elif MIXING_STEPPERS > 2
@@ -159,6 +162,42 @@ extern const char axis_codes[XYZE];
#endif // !MIXING_EXTRUDER
#if ENABLED(HANGPRINTER)
#define enable_A() enable_X()
#define enable_B() enable_Y()
#define enable_C() enable_Z()
#define __D_ENABLE(p) E##p##_ENABLE_WRITE(E_ENABLE_ON)
#define _D_ENABLE(p) __D_ENABLE(p)
#define enable_D() _D_ENABLE(EXTRUDERS)
// Don't allow any axes to be disabled
#undef disable_X
#undef disable_Y
#undef disable_Z
#define disable_X() NOOP
#define disable_Y() NOOP
#define disable_Z() NOOP
#if EXTRUDERS >= 1
#undef disable_E1
#define disable_E1() NOOP
#if EXTRUDERS >= 2
#undef disable_E2
#define disable_E2() NOOP
#if EXTRUDERS >= 3
#undef disable_E3
#define disable_E3() NOOP
#if EXTRUDERS >= 4
#undef disable_E4
#define disable_E4() NOOP
#endif // EXTRUDERS >= 4
#endif // EXTRUDERS >= 3
#endif // EXTRUDERS >= 2
#endif // EXTRUDERS >= 1
#endif // HANGPRINTER
#if ENABLED(G38_PROBE_TARGET)
extern bool G38_move, // flag to tell the interrupt handler that a G38 command is being run
G38_endstop_hit; // flag from the interrupt handler to indicate if the endstop went active
@@ -193,8 +232,8 @@ extern bool Running;
inline bool IsRunning() { return Running; }
inline bool IsStopped() { return !Running; }
bool enqueue_and_echo_command(const char* cmd, bool say_ok=false); // Add a single command to the end of the buffer. Return false on failure.
void enqueue_and_echo_commands_P(const char * const cmd); // Set one or more commands to be prioritized over the next Serial/SD command.
bool enqueue_and_echo_command(const char* cmd); // Add a single command to the end of the buffer. Return false on failure.
void enqueue_and_echo_commands_P(const char * const cmd); // Set one or more commands to be prioritized over the next Serial/SD command.
void clear_command_queue();
#if ENABLED(M100_FREE_MEMORY_WATCHER) || ENABLED(POWER_LOSS_RECOVERY)
@@ -299,10 +338,18 @@ extern float soft_endstop_min[XYZ], soft_endstop_max[XYZ];
bool select_coordinate_system(const int8_t _new);
#endif
void tool_change(const uint8_t tmp_extruder, const float fr_mm_s=0.0, bool no_move=false);
void home_all_axes();
void report_current_position();
#if IS_KINEMATIC
extern float delta[ABC];
#if ENABLED(HANGPRINTER)
extern float line_lengths[ABCD];
#else
extern float delta[ABC];
#endif
void inverse_kinematics(const float raw[XYZ]);
#endif
@@ -335,6 +382,51 @@ void report_current_position();
delta[C_AXIS] = DELTA_Z(V, C_AXIS); \
}while(0)
#elif ENABLED(HANGPRINTER)
// Don't collect anchor positions in array because there are no A_x, D_x or D_y
extern float anchor_A_y,
anchor_A_z,
anchor_B_x,
anchor_B_y,
anchor_B_z,
anchor_C_x,
anchor_C_y,
anchor_C_z,
anchor_D_z,
delta_segments_per_second,
line_lengths_origin[ABCD];
void recalc_hangprinter_settings();
#define HANGPRINTER_IK(V) do { \
line_lengths[A_AXIS] = SQRT(sq(anchor_A_z - V[Z_AXIS]) \
+ sq(anchor_A_y - V[Y_AXIS]) \
+ sq( V[X_AXIS])); \
line_lengths[B_AXIS] = SQRT(sq(anchor_B_z - V[Z_AXIS]) \
+ sq(anchor_B_y - V[Y_AXIS]) \
+ sq(anchor_B_x - V[X_AXIS])); \
line_lengths[C_AXIS] = SQRT(sq(anchor_C_z - V[Z_AXIS]) \
+ sq(anchor_C_y - V[Y_AXIS]) \
+ sq(anchor_C_x - V[X_AXIS])); \
line_lengths[D_AXIS] = SQRT(sq( V[X_AXIS]) \
+ sq( V[Y_AXIS]) \
+ sq(anchor_D_z - V[Z_AXIS])); \
}while(0)
// Inverse kinematics at origin
#define HANGPRINTER_IK_ORIGIN(LL) do { \
LL[A_AXIS] = SQRT(sq(anchor_A_z) \
+ sq(anchor_A_y)); \
LL[B_AXIS] = SQRT(sq(anchor_B_z) \
+ sq(anchor_B_y) \
+ sq(anchor_B_x)); \
LL[C_AXIS] = SQRT(sq(anchor_C_z) \
+ sq(anchor_C_y) \
+ sq(anchor_C_x)); \
LL[D_AXIS] = anchor_D_z; \
}while(0)
#elif IS_SCARA
void forward_kinematics_SCARA(const float &a, const float &b);
#endif
@@ -499,6 +591,9 @@ void do_blocking_move_to_xy(const float &rx, const float &ry, const float &fr_mm
inline bool position_is_reachable(const float &rx, const float &ry, const float inset=0) {
#if ENABLED(DELTA)
return HYPOT2(rx, ry) <= sq(DELTA_PRINTABLE_RADIUS - inset);
#elif ENABLED(HANGPRINTER)
// TODO: This is over simplified. Hangprinter's build volume is _not_ cylindrical.
return HYPOT2(rx, ry) <= sq(HANGPRINTER_PRINTABLE_RADIUS - inset);
#elif IS_SCARA
const float R2 = HYPOT2(rx - SCARA_OFFSET_X, ry - SCARA_OFFSET_Y);
return (
+1 -1
View File
@@ -9,7 +9,7 @@
================================================================================
Greetings! Thank you for choosing Marlin 2 as your 3D printer firmware.
Greetings! Thank you for choosing Marlin as your 3D printer firmware.
To configure Marlin you must edit Configuration.h and Configuration_adv.h
located in the root 'Marlin' folder. Check the example_configurations folder to
+1
View File
@@ -28,6 +28,7 @@
#include "Version.h"
#include "Configuration.h"
#include "Conditionals_LCD.h"
#include "drivers.h"
#include "Configuration_adv.h"
#if USE_MARLINSERIAL
+1097 -460
View File
File diff suppressed because it is too large Load Diff
+327 -189
View File
@@ -31,7 +31,7 @@
* #define MAX7219_DIN_PIN 78
* #define MAX7219_LOAD_PIN 79
*
* Max7219_init() is called automatically at startup, and then there are a number of
* send() is called automatically at startup, and then there are a number of
* support functions available to control the LEDs in the 8x8 grid.
*/
@@ -48,44 +48,92 @@
#include "Marlin.h"
#include "delay.h"
static uint8_t LEDs[8] = { 0 };
Max7219 max7219;
#ifndef MAX7219_ROTATE
#define MAX7219_ROTATE 0
#endif
#define _ROT ((MAX7219_ROTATE + 360) % 360)
#if _ROT == 0
#define _ROW_ y
#define _COL_ x
#define XOR_7219(x, y) LEDs[y] ^= _BV(7 - x)
#define BIT_7219(x, y) TEST(LEDs[y], 7 - x)
#define SEND_7219(R,V) Max7219(max7219_reg_digit0 + R, V)
#elif _ROT == 90
#define _ROW_ x
#define _COL_ y
#define XOR_7219(x, y) LEDs[x] ^= _BV(y)
#define BIT_7219(x, y) TEST(LEDs[x], y)
#define SEND_7219(R,V) Max7219(max7219_reg_digit0 + R, V)
#elif _ROT == 180
#define _ROW_ y
#define _COL_ x
#define XOR_7219(x, y) LEDs[y] ^= _BV(x)
#define BIT_7219(x, y) TEST(LEDs[y], x)
#define SEND_7219(R,V) Max7219(max7219_reg_digit7 - R, V)
#elif _ROT == 270
#define _ROW_ x
#define _COL_ y
#define XOR_7219(x, y) LEDs[x] ^= _BV(7 - y)
#define BIT_7219(x, y) TEST(LEDs[x], 7 - y)
#define SEND_7219(R,V) Max7219(max7219_reg_digit7 - R, V)
uint8_t Max7219::led_line[MAX7219_LINES]; // = { 0 };
#define LINE_REG(Q) (max7219_reg_digit0 + ((Q) & 0x7))
#if _ROT == 0 || _ROT == 270
#define _LED_BIT(Q) (7 - ((Q) & 0x7))
#define _LED_UNIT(Q) ((Q) & ~0x7)
#else
#error "MAX7219_ROTATE must be a multiple of +/- 90°."
#define _LED_BIT(Q) ((Q) & 0x7)
#define _LED_UNIT(Q) ((MAX7219_NUMBER_UNITS - 1 - ((Q) >> 3)) << 3)
#endif
#if _ROT < 180
#define _LED_IND(P,Q) (_LED_UNIT(P) + (Q))
#else
#define _LED_IND(P,Q) (_LED_UNIT(P) + (7 - ((Q) & 0x7)))
#endif
#if _ROT == 0 || _ROT == 180
#define LED_IND(X,Y) _LED_IND(X,Y)
#define LED_BIT(X,Y) _LED_BIT(X)
#elif _ROT == 90 || _ROT == 270
#define LED_IND(X,Y) _LED_IND(Y,X)
#define LED_BIT(X,Y) _LED_BIT(Y)
#endif
#define XOR_7219(X,Y) do{ led_line[LED_IND(X,Y)] ^= _BV(LED_BIT(X,Y)); }while(0)
#define SET_7219(X,Y) do{ led_line[LED_IND(X,Y)] |= _BV(LED_BIT(X,Y)); }while(0)
#define CLR_7219(X,Y) do{ led_line[LED_IND(X,Y)] &= ~_BV(LED_BIT(X,Y)); }while(0)
#define BIT_7219(X,Y) TEST(led_line[LED_IND(X,Y)], LED_BIT(X,Y))
#ifdef CPU_32_BIT
#define SIG_DELAY() DELAY_US(1) // Approximate a 1µs delay on 32-bit ARM
#undef CRITICAL_SECTION_START
#undef CRITICAL_SECTION_END
#define CRITICAL_SECTION_START NOOP
#define CRITICAL_SECTION_END NOOP
#else
#define SIG_DELAY() DELAY_NS(188) // Delay for 0.1875µs (16MHz AVR) or 0.15µs (20MHz AVR)
#endif
// Delay for 0.1875µs (16MHz AVR) or 0.15µs (20MHz AVR)
#define SIG_DELAY() DELAY_NS(188)
void Max7219::error(const char * const func, const int32_t v1, const int32_t v2/*=-1*/) {
#if ENABLED(MAX7219_ERRORS)
SERIAL_ECHOPGM("??? Max7219::");
serialprintPGM(func);
SERIAL_CHAR('(');
SERIAL_ECHO(v1);
if (v2 > 0) SERIAL_ECHOPAIR(", ", v2);
SERIAL_CHAR(')');
SERIAL_EOL();
#else
UNUSED(func); UNUSED(v1); UNUSED(v2);
#endif
}
void Max7219_PutByte(uint8_t data) {
/**
* Flip the lowest n_bytes of the supplied bits:
* flipped(x, 1) flips the low 8 bits of x.
* flipped(x, 2) flips the low 16 bits of x.
* flipped(x, 3) flips the low 24 bits of x.
* flipped(x, 4) flips the low 32 bits of x.
*/
inline uint32_t flipped(const uint32_t bits, const uint8_t n_bytes) {
uint32_t mask = 1, outbits = 0;
for (uint8_t b = 0; b < n_bytes * 8; b++) {
outbits <<= 1;
if (bits & mask) outbits |= 1;
mask <<= 1;
}
return outbits;
}
void Max7219::noop() {
CRITICAL_SECTION_START;
SIG_DELAY();
WRITE(MAX7219_DIN_PIN, LOW);
for (uint8_t i = 16; i--;) {
SIG_DELAY();
WRITE(MAX7219_CLK_PIN, LOW);
SIG_DELAY();
SIG_DELAY();
WRITE(MAX7219_CLK_PIN, HIGH);
SIG_DELAY();
}
CRITICAL_SECTION_END;
}
void Max7219::putbyte(uint8_t data) {
CRITICAL_SECTION_START;
for (uint8_t i = 8; i--;) {
SIG_DELAY();
@@ -100,26 +148,47 @@ void Max7219_PutByte(uint8_t data) {
CRITICAL_SECTION_END;
}
void Max7219(const uint8_t reg, const uint8_t data) {
void Max7219::pulse_load() {
SIG_DELAY();
CRITICAL_SECTION_START;
WRITE(MAX7219_LOAD_PIN, LOW); // begin
SIG_DELAY();
Max7219_PutByte(reg); // specify register
SIG_DELAY();
Max7219_PutByte(data); // put data
SIG_DELAY();
WRITE(MAX7219_LOAD_PIN, LOW); // and tell the chip to load the data
WRITE(MAX7219_LOAD_PIN, LOW); // tell the chip to load the data
SIG_DELAY();
WRITE(MAX7219_LOAD_PIN, HIGH);
CRITICAL_SECTION_END;
SIG_DELAY();
}
void Max7219::send(const uint8_t reg, const uint8_t data) {
SIG_DELAY();
CRITICAL_SECTION_START;
SIG_DELAY();
putbyte(reg); // specify register
SIG_DELAY();
putbyte(data); // put data
CRITICAL_SECTION_END;
}
// Send out a single native row of bits to all units
void Max7219::refresh_line(const uint8_t line) {
for (uint8_t u = MAX7219_NUMBER_UNITS; u--;)
send(LINE_REG(line), led_line[(u << 3) | (line & 0x7)]);
pulse_load();
}
// Send out a single native row of bits to just one unit
void Max7219::refresh_unit_line(const uint8_t line) {
for (uint8_t u = MAX7219_NUMBER_UNITS; u--;)
if (u == (line >> 3)) send(LINE_REG(line), led_line[line]); else noop();
pulse_load();
}
void Max7219::set(const uint8_t line, const uint8_t bits) {
led_line[line] = bits;
refresh_line(line);
}
#if ENABLED(MAX7219_NUMERIC)
// Draw an integer with optional leading zeros and optional decimal point
void Max7219_Print(const uint8_t start, int16_t value, uint8_t size, const bool leadzero=false, bool dec=false) {
void Max7219::print(const uint8_t start, int16_t value, uint8_t size, const bool leadzero=false, bool dec=false) {
constexpr uint8_t led_numeral[10] = { 0x7E, 0x60, 0x6D, 0x79, 0x63, 0x5B, 0x5F, 0x70, 0x7F, 0x7A },
led_decimal = 0x80, led_minus = 0x01;
@@ -128,10 +197,11 @@ void Max7219(const uint8_t reg, const uint8_t data) {
while (size--) {
const bool minus = neg && blank;
if (minus) neg = false;
Max7219(
send(
max7219_reg_digit0 + start + size,
minus ? led_minus : blank ? 0x00 : led_numeral[value % 10] | (dec ? led_decimal : 0x00)
);
pulse_load(); // tell the chips to load the clocked out data
value /= 10;
if (!value && !leadzero) blank = true;
dec = false;
@@ -139,175 +209,210 @@ void Max7219(const uint8_t reg, const uint8_t data) {
}
// Draw a float with a decimal point and optional digits
void Max7219_Print(const uint8_t start, const float value, const uint8_t pre_size, const uint8_t post_size, const bool leadzero=false) {
if (pre_size) Max7219_Print(start, value, pre_size, leadzero, !!post_size);
void Max7219::print(const uint8_t start, const float value, const uint8_t pre_size, const uint8_t post_size, const bool leadzero=false) {
if (pre_size) print(start, value, pre_size, leadzero, !!post_size);
if (post_size) {
const int16_t after = ABS(value) * (10 ^ post_size);
Max7219_Print(start + pre_size, after, post_size, true);
print(start + pre_size, after, post_size, true);
}
}
#endif // MAX7219_NUMERIC
inline void Max7219_Error(const char * const func, const int32_t v1, const int32_t v2=-1) {
#if ENABLED(MAX7219_ERRORS)
SERIAL_ECHOPGM("??? ");
serialprintPGM(func);
SERIAL_CHAR('(');
SERIAL_ECHO(v1);
if (v2 > 0) SERIAL_ECHOPAIR(", ", v2);
SERIAL_CHAR(')');
SERIAL_EOL();
#else
UNUSED(func); UNUSED(v1); UNUSED(v2);
#endif
}
inline uint8_t flipped(const uint8_t bits) {
uint8_t outbits = 0;
for (uint8_t b = 0; b < 8; b++)
if (bits & _BV(b)) outbits |= _BV(7 - b);
return outbits;
}
// Modify a single LED bit and send the changed line
void Max7219_LED_Set(const uint8_t x, const uint8_t y, const bool on) {
if (x > 7 || y > 7) return Max7219_Error(PSTR("Max7219_LED_Set"), x, y);
void Max7219::led_set(const uint8_t x, const uint8_t y, const bool on) {
if (x > MAX7219_X_LEDS - 1 || y > MAX7219_Y_LEDS - 1) return error(PSTR("led_set"), x, y);
if (BIT_7219(x, y) == on) return;
XOR_7219(x, y);
SEND_7219(_ROW_, LEDs[_ROW_]);
refresh_line(LED_IND(x, y));
}
void Max7219_LED_On(const uint8_t x, const uint8_t y) {
if (x > 7 || y > 7) return Max7219_Error(PSTR("Max7219_LED_On"), x, y);
Max7219_LED_Set(x, y, true);
void Max7219::led_on(const uint8_t x, const uint8_t y) {
if (x > MAX7219_X_LEDS - 1 || y > MAX7219_Y_LEDS - 1) return error(PSTR("led_on"), x, y);
led_set(x, y, true);
}
void Max7219_LED_Off(const uint8_t x, const uint8_t y) {
if (x > 7 || y > 7) return Max7219_Error(PSTR("Max7219_LED_Off"), x, y);
Max7219_LED_Set(x, y, false);
void Max7219::led_off(const uint8_t x, const uint8_t y) {
if (x > MAX7219_X_LEDS - 1 || y > MAX7219_Y_LEDS - 1) return error(PSTR("led_off"), x, y);
led_set(x, y, false);
}
void Max7219_LED_Toggle(const uint8_t x, const uint8_t y) {
if (x > 7 || y > 7) return Max7219_Error(PSTR("Max7219_LED_Toggle"), x, y);
Max7219_LED_Set(x, y, !BIT_7219(x, y));
void Max7219::led_toggle(const uint8_t x, const uint8_t y) {
if (x > MAX7219_X_LEDS - 1 || y > MAX7219_Y_LEDS - 1) return error(PSTR("led_toggle"), x, y);
led_set(x, y, !BIT_7219(x, y));
}
inline void _Max7219_Set_Reg(const uint8_t reg, const uint8_t val) {
LEDs[reg] = val;
SEND_7219(reg, val);
}
void Max7219_Set_Row(const uint8_t _ROW_, const uint8_t val) {
if (_ROW_ > 7) return Max7219_Error(PSTR("Max7219_Set_Row"), _ROW_);
#if _ROT == 90
for (uint8_t _COL_ = 0; _COL_ <= 7; _COL_++) Max7219_LED_Set(7 - _COL_, _ROW_, TEST(val, _COL_));
#elif _ROT == 180
_Max7219_Set_Reg(_ROW_, flipped(val));
#elif _ROT == 270
for (uint8_t _COL_ = 0; _COL_ <= 7; _COL_++) Max7219_LED_Set(_COL_, _ROW_, TEST(val, _COL_));
void Max7219::send_row(const uint8_t row) {
#if _ROT == 0 || _ROT == 180
refresh_line(LED_IND(0, row));
#else
_Max7219_Set_Reg(_ROW_, val);
UNUSED(row);
refresh();
#endif
}
void Max7219_Clear_Row(const uint8_t _ROW_) {
if (_ROW_ > 7) return Max7219_Error(PSTR("Max7219_Clear_Row"), _ROW_);
void Max7219::send_column(const uint8_t col) {
#if _ROT == 90 || _ROT == 270
for (uint8_t _COL_ = 0; _COL_ <= 7; _COL_++) Max7219_LED_Off(_COL_, _ROW_);
refresh_line(LED_IND(col, 0));
#else
_Max7219_Set_Reg(_ROW_, 0);
UNUSED(col);
refresh();
#endif
}
void Max7219_Set_Column(const uint8_t _COL_, const uint8_t val) {
if (_COL_ > 7) return Max7219_Error(PSTR("Max7219_Set_Column"), _COL_);
#if _ROT == 90
_Max7219_Set_Reg(_COL_, val);
#elif _ROT == 180
for (uint8_t _ROW_ = 0; _ROW_ <= 7; _ROW_++) Max7219_LED_Set(_COL_, _ROW_, TEST(val, _ROW_));
#elif _ROT == 270
_Max7219_Set_Reg(_COL_, flipped(val));
#else
for (uint8_t _ROW_ = 0; _ROW_ <= 7; _ROW_++) Max7219_LED_Set(_COL_, _ROW_, TEST(val, _ROW_));
void Max7219::clear() {
ZERO(led_line);
refresh();
}
void Max7219::fill() {
memset(led_line, 0xFF, sizeof(led_line));
refresh();
}
void Max7219::clear_row(const uint8_t row) {
if (row >= MAX7219_Y_LEDS) return error(PSTR("clear_row"), row);
for (uint8_t x = 0; x < MAX7219_X_LEDS; x++) CLR_7219(x, row);
send_row(row);
}
void Max7219::clear_column(const uint8_t col) {
if (col >= MAX7219_X_LEDS) return error(PSTR("set_column"), col);
for (uint8_t y = 0; y < MAX7219_Y_LEDS; y++) CLR_7219(col, y);
send_column(col);
}
/**
* Plot the low order bits of val to the specified row of the matrix.
* With 4 Max7219 units in the chain, it's possible to set 32 bits at once with
* one call to the function (if rotated 90° or 180°).
*/
void Max7219::set_row(const uint8_t row, const uint32_t val) {
if (row >= MAX7219_Y_LEDS) return error(PSTR("set_row"), row);
uint32_t mask = _BV32(MAX7219_X_LEDS - 1);
for (uint8_t x = 0; x < MAX7219_X_LEDS; x++) {
if (val & mask) SET_7219(x, row); else CLR_7219(x, row);
mask >>= 1;
}
send_row(row);
}
/**
* Plot the low order bits of val to the specified column of the matrix.
* With 4 Max7219 units in the chain, it's possible to set 32 bits at once with
* one call to the function (if rotated 90° or 180°).
*/
void Max7219::set_column(const uint8_t col, const uint32_t val) {
if (col >= MAX7219_X_LEDS) return error(PSTR("set_column"), col);
uint32_t mask = _BV32(MAX7219_Y_LEDS - 1);
for (uint8_t y = 0; y < MAX7219_Y_LEDS; y++) {
if (val & mask) SET_7219(col, y); else CLR_7219(col, y);
mask >>= 1;
}
send_column(col);
}
void Max7219::set_rows_16bits(const uint8_t y, uint32_t val) {
#if MAX7219_X_LEDS == 8
if (y > MAX7219_Y_LEDS - 2) return error(PSTR("set_rows_16bits"), y, val);
set_row(y + 1, val); val >>= 8;
set_row(y + 0, val);
#else // at least 16 bits on each row
if (y > MAX7219_Y_LEDS - 1) return error(PSTR("set_rows_16bits"), y, val);
set_row(y, val);
#endif
}
void Max7219_Clear_Column(const uint8_t _COL_) {
if (_COL_ > 7) return Max7219_Error(PSTR("Max7219_Clear_Column"), _COL_);
#if _ROT == 90 || _ROT == 270
_Max7219_Set_Reg(_COL_, 0);
#else
for (uint8_t _ROW_ = 0; _ROW_ <= 7; _ROW_++) Max7219_LED_Off(_COL_, _ROW_);
void Max7219::set_rows_32bits(const uint8_t y, uint32_t val) {
#if MAX7219_X_LEDS == 8
if (y > MAX7219_Y_LEDS - 4) return error(PSTR("set_rows_32bits"), y, val);
set_row(y + 3, val); val >>= 8;
set_row(y + 2, val); val >>= 8;
set_row(y + 1, val); val >>= 8;
set_row(y + 0, val);
#elif MAX7219_X_LEDS == 16
if (y > MAX7219_Y_LEDS - 2) return error(PSTR("set_rows_32bits"), y, val);
set_row(y + 1, val); val >>= 16;
set_row(y + 0, val);
#else // at least 24 bits on each row. In the 3 matrix case, just display the low 24 bits
if (y > MAX7219_Y_LEDS - 1) return error(PSTR("set_rows_32bits"), y, val);
set_row(y, val);
#endif
}
void Max7219_Clear() {
for (uint8_t r = 0; r < 8; r++) _Max7219_Set_Reg(r, 0);
void Max7219::set_columns_16bits(const uint8_t x, uint32_t val) {
#if MAX7219_Y_LEDS == 8
if (x > MAX7219_X_LEDS - 2) return error(PSTR("set_columns_16bits"), x, val);
set_column(x + 0, val); val >>= 8;
set_column(x + 1, val);
#else // at least 16 bits in each column
if (x > MAX7219_X_LEDS - 1) return error(PSTR("set_columns_16bits"), x, val);
set_column(x, val);
#endif
}
void Max7219_Set_2_Rows(const uint8_t y, uint16_t val) {
if (y > 6) return Max7219_Error(PSTR("Max7219_Set_2_Rows"), y, val);
Max7219_Set_Row(y + 0, val & 0xFF); val >>= 8;
Max7219_Set_Row(y + 1, val & 0xFF);
void Max7219::set_columns_32bits(const uint8_t x, uint32_t val) {
#if MAX7219_Y_LEDS == 8
if (x > MAX7219_X_LEDS - 4) return error(PSTR("set_rows_32bits"), x, val);
set_column(x + 3, val); val >>= 8;
set_column(x + 2, val); val >>= 8;
set_column(x + 1, val); val >>= 8;
set_column(x + 0, val);
#elif MAX7219_Y_LEDS == 16
if (x > MAX7219_X_LEDS - 2) return error(PSTR("set_rows_32bits"), x, val);
set_column(x + 1, val); val >>= 16;
set_column(x + 0, val);
#else // at least 24 bits on each row. In the 3 matrix case, just display the low 24 bits
if (x > MAX7219_X_LEDS - 1) return error(PSTR("set_rows_32bits"), x, val);
set_column(x, val);
#endif
}
void Max7219_Set_4_Rows(const uint8_t y, uint32_t val) {
if (y > 4) return Max7219_Error(PSTR("Max7219_Set_4_Rows"), y, val);
Max7219_Set_Row(y + 0, val & 0xFF); val >>= 8;
Max7219_Set_Row(y + 1, val & 0xFF); val >>= 8;
Max7219_Set_Row(y + 2, val & 0xFF); val >>= 8;
Max7219_Set_Row(y + 3, val & 0xFF);
}
// Initialize the Max7219
void Max7219::register_setup() {
for (uint8_t i = 0; i < MAX7219_NUMBER_UNITS; i++)
send(max7219_reg_scanLimit, 0x07);
pulse_load(); // tell the chips to load the clocked out data
void Max7219_Set_2_Columns(const uint8_t x, uint16_t val) {
if (x > 6) return Max7219_Error(PSTR("Max7219_Set_2_Columns"), x, val);
Max7219_Set_Column(x + 0, val & 0xFF); val >>= 8;
Max7219_Set_Column(x + 1, val & 0xFF);
}
for (uint8_t i = 0; i < MAX7219_NUMBER_UNITS; i++)
send(max7219_reg_decodeMode, 0x00); // using an led matrix (not digits)
pulse_load(); // tell the chips to load the clocked out data
void Max7219_Set_4_Columns(const uint8_t x, uint32_t val) {
if (x > 4) return Max7219_Error(PSTR("Max7219_Set_4_Columns"), x, val);
Max7219_Set_Column(x + 0, val & 0xFF); val >>= 8;
Max7219_Set_Column(x + 1, val & 0xFF); val >>= 8;
Max7219_Set_Column(x + 2, val & 0xFF); val >>= 8;
Max7219_Set_Column(x + 3, val & 0xFF);
}
for (uint8_t i = 0; i < MAX7219_NUMBER_UNITS; i++)
send(max7219_reg_shutdown, 0x01); // not in shutdown mode
pulse_load(); // tell the chips to load the clocked out data
void Max7219_register_setup() {
// Initialize the Max7219
Max7219(max7219_reg_scanLimit, 0x07);
Max7219(max7219_reg_decodeMode, 0x00); // using an led matrix (not digits)
Max7219(max7219_reg_shutdown, 0x01); // not in shutdown mode
Max7219(max7219_reg_displayTest, 0x00); // no display test
Max7219(max7219_reg_intensity, 0x01 & 0x0F); // the first 0x0F is the value you can set
// range: 0x00 to 0x0F
for (uint8_t i = 0; i < MAX7219_NUMBER_UNITS; i++)
send(max7219_reg_displayTest, 0x00); // no display test
pulse_load(); // tell the chips to load the clocked out data
for (uint8_t i = 0; i < MAX7219_NUMBER_UNITS; i++)
send(max7219_reg_intensity, 0x01 & 0x0F); // the first 0x0F is the value you can set
// range: 0x00 to 0x0F
pulse_load(); // tell the chips to load the clocked out data
}
#ifdef MAX7219_INIT_TEST
#if (MAX7219_INIT_TEST + 0) == 2
#if MAX7219_INIT_TEST == 2
inline void Max7219_spiral(const bool on, const uint16_t del) {
void Max7219::spiral(const bool on, const uint16_t del) {
constexpr int8_t way[] = { 1, 0, 0, 1, -1, 0, 0, -1 };
int8_t px = 0, py = 0, dir = 0;
for (uint8_t i = 64; i--;) {
Max7219_LED_Set(px, py, on);
for (uint8_t i = MAX7219_X_LEDS * MAX7219_Y_LEDS; i--;) {
led_set(px, py, on);
delay(del);
const int8_t x = px + way[dir], y = py + way[dir + 1];
if (!WITHIN(x, 0, 7) || !WITHIN(y, 0, 7) || BIT_7219(x, y) == on) dir = (dir + 2) & 0x7;
if (!WITHIN(x, 0, MAX7219_X_LEDS-1) || !WITHIN(y, 0, MAX7219_Y_LEDS-1) || BIT_7219(x, y) == on) dir = (dir + 2) & 0x7;
px += way[dir]; py += way[dir + 1];
}
}
#else
inline void Max7219_colset(const uint8_t x, const bool on) {
for (uint8_t y = 0; y <= 7; y++) Max7219_LED_Set(x, y, on);
}
inline void Max7219_sweep(const int8_t dir, const uint16_t ms, const bool on) {
uint8_t x = dir > 0 ? 0 : 7;
for (uint8_t i = 8; i--; x += dir) {
Max7219_Set_Column(x, on ? 0xFF : 0x00);
void Max7219::sweep(const int8_t dir, const uint16_t ms, const bool on) {
uint8_t x = dir > 0 ? 0 : MAX7219_X_LEDS-1;
for (uint8_t i = MAX7219_X_LEDS; i--; x += dir) {
set_column(x, on ? 0xFFFFFFFF : 0x00000000);
delay(ms);
}
}
@@ -315,32 +420,33 @@ void Max7219_register_setup() {
#endif
#endif // MAX7219_INIT_TEST
void Max7219_init() {
void Max7219::init() {
SET_OUTPUT(MAX7219_DIN_PIN);
SET_OUTPUT(MAX7219_CLK_PIN);
OUT_WRITE(MAX7219_LOAD_PIN, HIGH);
delay(1);
Max7219_register_setup();
register_setup();
for (uint8_t i = 0; i <= 7; i++) { // Empty registers to turn all LEDs off
LEDs[i] = 0x00;
Max7219(max7219_reg_digit0 + i, 0);
led_line[i] = 0x00;
send(max7219_reg_digit0 + i, 0);
pulse_load(); // tell the chips to load the clocked out data
}
#ifdef MAX7219_INIT_TEST
#if (MAX7219_INIT_TEST + 0) == 2
Max7219_spiral(true, 8);
#if MAX7219_INIT_TEST == 2
spiral(true, 8);
delay(150);
Max7219_spiral(false, 8);
spiral(false, 8);
#else
// Do an aesthetically-pleasing pattern to fully test the Max7219 module and LEDs.
// Light up and turn off columns, both forward and backward.
Max7219_sweep(1, 20, true);
Max7219_sweep(1, 20, false);
sweep(1, 20, true);
sweep(1, 20, false);
delay(150);
Max7219_sweep(-1, 20, true);
Max7219_sweep(-1, 20, false);
sweep(-1, 20, true);
sweep(-1, 20, false);
#endif
#endif
}
@@ -352,26 +458,58 @@ void Max7219_init() {
*/
// Apply changes to update a marker
inline void Max7219_Mark16(const uint8_t y, const uint8_t v1, const uint8_t v2) {
Max7219_LED_Off(v1 & 0x7, y + (v1 >= 8));
Max7219_LED_On(v2 & 0x7, y + (v2 >= 8));
void Max7219::mark16(const uint8_t y, const uint8_t v1, const uint8_t v2) {
#if MAX7219_X_LEDS == 8
#if MAX7219_Y_LEDS == 8
led_off(v1 & 0x7, y + (v1 >= 8));
led_on(v2 & 0x7, y + (v2 >= 8));
#else
led_off(y, v1 & 0xF); // At least 16 LEDs down. Use a single column.
led_on(y, v2 & 0xF);
#endif
#else
led_off(v1 & 0xF, y); // At least 16 LEDs across. Use a single row.
led_on(v2 & 0xF, y);
#endif
}
// Apply changes to update a tail-to-head range
inline void Max7219_Range16(const uint8_t y, const uint8_t ot, const uint8_t nt, const uint8_t oh, const uint8_t nh) {
if (ot != nt) for (uint8_t n = ot & 0xF; n != (nt & 0xF) && n != (nh & 0xF); n = (n + 1) & 0xF)
Max7219_LED_Off(n & 0x7, y + (n >= 8));
if (oh != nh) for (uint8_t n = (oh + 1) & 0xF; n != ((nh + 1) & 0xF); n = (n + 1) & 0xF)
Max7219_LED_On(n & 0x7, y + (n >= 8));
void Max7219::range16(const uint8_t y, const uint8_t ot, const uint8_t nt, const uint8_t oh, const uint8_t nh) {
#if MAX7219_X_LEDS == 8
#if MAX7219_Y_LEDS == 8
if (ot != nt) for (uint8_t n = ot & 0xF; n != (nt & 0xF) && n != (nh & 0xF); n = (n + 1) & 0xF)
led_off(n & 0x7, y + (n >= 8));
if (oh != nh) for (uint8_t n = (oh + 1) & 0xF; n != ((nh + 1) & 0xF); n = (n + 1) & 0xF)
led_on(n & 0x7, y + (n >= 8));
#else // The Max7219 Y-Axis has at least 16 LED's. So use a single column
if (ot != nt) for (uint8_t n = ot & 0xF; n != (nt & 0xF) && n != (nh & 0xF); n = (n + 1) & 0xF)
led_off(y, n & 0xF);
if (oh != nh) for (uint8_t n = (oh + 1) & 0xF; n != ((nh + 1) & 0xF); n = (n + 1) & 0xF)
led_on(y, n & 0xF);
#endif
#else // LED matrix has at least 16 LED's on the X-Axis. Use single line of LED's
if (ot != nt) for (uint8_t n = ot & 0xF; n != (nt & 0xF) && n != (nh & 0xF); n = (n + 1) & 0xF)
led_off(n & 0xF, y);
if (oh != nh) for (uint8_t n = (oh + 1) & 0xF; n != ((nh + 1) & 0xF); n = (n + 1) & 0xF)
led_on(n & 0xF, y);
#endif
}
// Apply changes to update a quantity
inline void Max7219_Quantity16(const uint8_t y, const uint8_t ov, const uint8_t nv) {
void Max7219::quantity16(const uint8_t y, const uint8_t ov, const uint8_t nv) {
for (uint8_t i = MIN(nv, ov); i < MAX(nv, ov); i++)
Max7219_LED_Set(i >> 1, y + (i & 1), nv >= ov);
#if MAX7219_X_LEDS == 8
#if MAX7219_Y_LEDS == 8
led_set(i >> 1, y + (i & 1), nv >= ov); // single 8x8 LED matrix. Use two lines to get 16 LED's
#else
led_set(y, i, nv >= ov); // The Max7219 Y-Axis has at least 16 LED's. So use a single column
#endif
#else
led_set(i, y, nv >= ov); // LED matrix has at least 16 LED's on the X-Axis. Use single line of LED's
#endif
}
void Max7219_idle_tasks() {
void Max7219::idle_tasks() {
#define MAX7219_USE_HEAD (defined(MAX7219_DEBUG_PLANNER_HEAD) || defined(MAX7219_DEBUG_PLANNER_QUEUE))
#define MAX7219_USE_TAIL (defined(MAX7219_DEBUG_PLANNER_TAIL) || defined(MAX7219_DEBUG_PLANNER_QUEUE))
#if MAX7219_USE_HEAD || MAX7219_USE_TAIL
@@ -402,12 +540,12 @@ void Max7219_idle_tasks() {
// corrupted, this will fix it within a couple seconds.
if (do_blink && ++refresh_cnt >= refresh_limit) {
refresh_cnt = 0;
Max7219_register_setup();
register_setup();
}
#if ENABLED(MAX7219_DEBUG_PRINTER_ALIVE)
if (do_blink) {
Max7219_LED_Toggle(7, 7);
led_toggle(MAX7219_X_LEDS - 1, MAX7219_Y_LEDS - 1);
next_blink = ms + 1000;
}
#endif
@@ -417,7 +555,7 @@ void Max7219_idle_tasks() {
static int16_t last_head_cnt = 0xF, last_tail_cnt = 0xF;
if (last_head_cnt != head || last_tail_cnt != tail) {
Max7219_Range16(MAX7219_DEBUG_PLANNER_HEAD, last_tail_cnt, tail, last_head_cnt, head);
range16(MAX7219_DEBUG_PLANNER_HEAD, last_tail_cnt, tail, last_head_cnt, head);
last_head_cnt = head;
last_tail_cnt = tail;
}
@@ -427,7 +565,7 @@ void Max7219_idle_tasks() {
#ifdef MAX7219_DEBUG_PLANNER_HEAD
static int16_t last_head_cnt = 0x1;
if (last_head_cnt != head) {
Max7219_Mark16(MAX7219_DEBUG_PLANNER_HEAD, last_head_cnt, head);
mark16(MAX7219_DEBUG_PLANNER_HEAD, last_head_cnt, head);
last_head_cnt = head;
}
#endif
@@ -435,7 +573,7 @@ void Max7219_idle_tasks() {
#ifdef MAX7219_DEBUG_PLANNER_TAIL
static int16_t last_tail_cnt = 0x1;
if (last_tail_cnt != tail) {
Max7219_Mark16(MAX7219_DEBUG_PLANNER_TAIL, last_tail_cnt, tail);
mark16(MAX7219_DEBUG_PLANNER_TAIL, last_tail_cnt, tail);
last_tail_cnt = tail;
}
#endif
@@ -446,7 +584,7 @@ void Max7219_idle_tasks() {
static int16_t last_depth = 0;
const int16_t current_depth = (head - tail + BLOCK_BUFFER_SIZE) & (BLOCK_BUFFER_SIZE - 1) & 0xF;
if (current_depth != last_depth) {
Max7219_Quantity16(MAX7219_DEBUG_PLANNER_QUEUE, last_depth, current_depth);
quantity16(MAX7219_DEBUG_PLANNER_QUEUE, last_depth, current_depth);
last_depth = current_depth;
}
#endif
+91 -23
View File
@@ -31,12 +31,33 @@
* #define MAX7219_DIN_PIN 78
* #define MAX7219_LOAD_PIN 79
*
* Max7219_init() is called automatically at startup, and then there are a number of
* max7219.init() is called automatically at startup, and then there are a number of
* support functions available to control the LEDs in the 8x8 grid.
*
* If you are using the Max7219 matrix for firmware debug purposes in time sensitive
* areas of the code, please be aware that the orientation (rotation) of the display can
* affect the speed. The Max7219 can update a single column fairly fast. It is much
* faster to do a Max7219_Set_Column() with a rotation of 90 or 270 degrees than to do
* a Max7219_Set_Row(). The opposite is true for rotations of 0 or 180 degrees.
*/
#pragma once
#ifndef __MAX7219_DEBUG_LEDS_H__
#define __MAX7219_DEBUG_LEDS_H__
#ifndef MAX7219_ROTATE
#define MAX7219_ROTATE 0
#endif
#define _ROT ((MAX7219_ROTATE + 360) % 360)
#define MAX7219_LINES (8 * (MAX7219_NUMBER_UNITS))
#if _ROT == 0 || _ROT == 180
#define MAX7219_Y_LEDS 8
#define MAX7219_X_LEDS MAX7219_LINES
#elif _ROT == 90 || _ROT == 270
#define MAX7219_X_LEDS 8
#define MAX7219_Y_LEDS MAX7219_LINES
#else
#error "MAX7219_ROTATE must be a multiple of +/- 90°."
#endif
//
// MAX7219 registers
@@ -57,30 +78,77 @@
#define max7219_reg_shutdown 0x0C
#define max7219_reg_displayTest 0x0F
void Max7219_init();
void Max7219_PutByte(uint8_t data);
class Max7219 {
public:
static uint8_t led_line[MAX7219_LINES];
// Set a single register (e.g., a whole native row)
void Max7219(const uint8_t reg, const uint8_t data);
Max7219() { }
// Set a single LED by XY coordinate
void Max7219_LED_Set(const uint8_t x, const uint8_t y, const bool on);
void Max7219_LED_On(const uint8_t x, const uint8_t y);
void Max7219_LED_Off(const uint8_t x, const uint8_t y);
void Max7219_LED_Toggle(const uint8_t x, const uint8_t y);
static void init();
static void register_setup();
static void putbyte(uint8_t data);
static void pulse_load();
// Set all 8 LEDs in a single column
void Max7219_Set_Column(const uint8_t col, const uint8_t val);
void Max7219_Clear_Column(const uint8_t col);
// Set a single register (e.g., a whole native row)
static void send(const uint8_t reg, const uint8_t data);
// Set all 8 LEDs in a single row
void Max7219_Set_Row(const uint8_t row, const uint8_t val);
void Max7219_Clear_Row(const uint8_t row);
// Refresh all units
inline static void refresh() { for (uint8_t i = 0; i < 8; i++) refresh_line(i); }
// Quickly clear the whole matrix
void Max7219_Clear();
// Update a single native line on all units
static void refresh_line(const uint8_t line);
// Apply custom code to update the matrix
void Max7219_idle_tasks();
// Update a single native line on just one unit
static void refresh_unit_line(const uint8_t line);
#endif // __MAX7219_DEBUG_LEDS_H__
// Set a single LED by XY coordinate
static void led_set(const uint8_t x, const uint8_t y, const bool on);
static void led_on(const uint8_t x, const uint8_t y);
static void led_off(const uint8_t x, const uint8_t y);
static void led_toggle(const uint8_t x, const uint8_t y);
// Set all LEDs in a single column
static void set_column(const uint8_t col, const uint32_t val);
static void clear_column(const uint8_t col);
// Set all LEDs in a single row
static void set_row(const uint8_t row, const uint32_t val);
static void clear_row(const uint8_t row);
// 16 and 32 bit versions of Row and Column functions
// Multiple rows and columns will be used to display the value if
// the array of matrix LED's is too narrow to accomplish the goal
static void set_rows_16bits(const uint8_t y, uint32_t val);
static void set_rows_32bits(const uint8_t y, uint32_t val);
static void set_columns_16bits(const uint8_t x, uint32_t val);
static void set_columns_32bits(const uint8_t x, uint32_t val);
// Quickly clear the whole matrix
static void clear();
// Quickly fill the whole matrix
static void fill();
// Apply custom code to update the matrix
static void idle_tasks();
private:
static void error(const char * const func, const int32_t v1, const int32_t v2=-1);
static void noop();
static void set(const uint8_t line, const uint8_t bits);
static void send_row(const uint8_t row);
static void send_column(const uint8_t col);
static void mark16(const uint8_t y, const uint8_t v1, const uint8_t v2);
static void range16(const uint8_t y, const uint8_t ot, const uint8_t nt, const uint8_t oh, const uint8_t nh);
static void quantity16(const uint8_t y, const uint8_t ov, const uint8_t nv);
#ifdef MAX7219_INIT_TEST
#if MAX7219_INIT_TEST == 2
static void spiral(const bool on, const uint16_t del);
#else
static void sweep(const int8_t dir, const uint16_t ms, const bool on);
#endif
#endif
};
extern Max7219 max7219;
+192 -263
View File
@@ -265,10 +265,28 @@
#elif defined(MEASURED_LOWER_LIMIT) || defined(MEASURED_UPPER_LIMIT)
#error "MEASURED_(UPPER|LOWER)_LIMIT is now FILWIDTH_ERROR_MARGIN. Please update your configuration."
#elif defined(HAVE_TMCDRIVER)
#error "HAVE_TMCDRIVER is now HAVE_TMC26X. Please update your Configuration_adv.h."
#error "HAVE_TMCDRIVER is now [AXIS]_DRIVER_TYPE TMC26X. Please update your Configuration.h."
#elif defined(HAVE_TMC26X)
#error "HAVE_TMC26X is now [AXIS]_DRIVER_TYPE TMC26X. Please update your Configuration.h."
#elif defined(HAVE_TMC2130)
#error "HAVE_TMC2130 is now [AXIS]_DRIVER_TYPE TMC2130. Please update your Configuration.h."
#elif defined(HAVE_L6470DRIVER)
#error "HAVE_L6470DRIVER is now [AXIS]_DRIVER_TYPE L6470. Please update your Configuration.h."
#elif defined(X_IS_TMC) || defined(X2_IS_TMC) || defined(Y_IS_TMC) || defined(Y2_IS_TMC) || defined(Z_IS_TMC) || defined(Z2_IS_TMC) \
|| defined(E0_IS_TMC) || defined(E1_IS_TMC) || defined(E2_IS_TMC) || defined(E3_IS_TMC) || defined(E4_IS_TMC)
#error "[AXIS]_IS_TMC is now [AXIS]_IS_TMC26X. Please update your Configuration_adv.h."
#error "[AXIS]_IS_TMC is now [AXIS]_DRIVER_TYPE TMC26X. Please update your Configuration.h."
#elif defined(X_IS_TMC26X) || defined(X2_IS_TMC26X) || defined(Y_IS_TMC26X) || defined(Y2_IS_TMC26X) || defined(Z_IS_TMC26X) || defined(Z2_IS_TMC26X) \
|| defined(E0_IS_TMC26X) || defined(E1_IS_TMC26X) || defined(E2_IS_TMC26X) || defined(E3_IS_TMC26X) || defined(E4_IS_TMC26X)
#error "[AXIS]_IS_TMC26X is now [AXIS]_DRIVER_TYPE TMC26X. Please update your Configuration.h."
#elif defined(X_IS_TMC2130) || defined(X2_IS_TMC2130) || defined(Y_IS_TMC2130) || defined(Y2_IS_TMC2130) || defined(Z_IS_TMC2130) || defined(Z2_IS_TMC2130) \
|| defined(E0_IS_TMC2130) || defined(E1_IS_TMC2130) || defined(E2_IS_TMC2130) || defined(E3_IS_TMC2130) || defined(E4_IS_TMC2130)
#error "[AXIS]_IS_TMC2130 is now [AXIS]_DRIVER_TYPE TMC2130. Please update your Configuration.h."
#elif defined(X_IS_TMC2208) || defined(X2_IS_TMC2208) || defined(Y_IS_TMC2208) || defined(Y2_IS_TMC2208) || defined(Z_IS_TMC2208) || defined(Z2_IS_TMC2208) \
|| defined(E0_IS_TMC2208) || defined(E1_IS_TMC2208) || defined(E2_IS_TMC2208) || defined(E3_IS_TMC2208) || defined(E4_IS_TMC2208)
#error "[AXIS]_IS_TMC2208 is now [AXIS]_DRIVER_TYPE TMC2208. Please update your Configuration.h."
#elif defined(X_IS_L6470) || defined(X2_IS_L6470) || defined(Y_IS_L6470) || defined(Y2_IS_L6470) || defined(Z_IS_L6470) || defined(Z2_IS_L6470) \
|| defined(E0_IS_L6470) || defined(E1_IS_L6470) || defined(E2_IS_L6470) || defined(E3_IS_L6470) || defined(E4_IS_L6470)
#error "[AXIS]_IS_L6470 is now [AXIS]_DRIVER_TYPE L6470. Please update your Configuration.h."
#elif defined(AUTOMATIC_CURRENT_CONTROL)
#error "AUTOMATIC_CURRENT_CONTROL is now MONITOR_DRIVER_STATUS. Please update your configuration."
#elif defined(FILAMENT_CHANGE_LOAD_LENGTH)
@@ -385,10 +403,10 @@ static_assert(X_MAX_LENGTH >= X_BED_SIZE && Y_MAX_LENGTH >= Y_BED_SIZE,
#if ENABLED(LCD_PROGRESS_BAR)
#if DISABLED(SDSUPPORT) && DISABLED(LCD_SET_PROGRESS_MANUALLY)
#error "LCD_PROGRESS_BAR requires SDSUPPORT or LCD_SET_PROGRESS_MANUALLY."
#elif DISABLED(ULTRA_LCD)
#error "LCD_PROGRESS_BAR requires a character LCD."
#elif ENABLED(DOGLCD)
#error "LCD_PROGRESS_BAR does not apply to graphical displays."
#elif DISABLED(ULTIPANEL)
#error "LCD_PROGRESS_BAR requires a character LCD."
#elif ENABLED(FILAMENT_LCD_DISPLAY)
#error "LCD_PROGRESS_BAR and FILAMENT_LCD_DISPLAY are not fully compatible. Comment out this line to use both."
#endif
@@ -447,6 +465,8 @@ static_assert(X_MAX_LENGTH >= X_BED_SIZE && Y_MAX_LENGTH >= Y_BED_SIZE,
#if ENABLED(BABYSTEPPING)
#if ENABLED(SCARA)
#error "BABYSTEPPING is not implemented for SCARA yet."
#elif ENABLED(HANGPRINTER)
#error "BABYSTEPPING is not implemented for HANGPRINTER."
#elif ENABLED(DELTA) && ENABLED(BABYSTEP_XY)
#error "BABYSTEPPING only implemented for Z axis on deltabots."
#elif ENABLED(BABYSTEP_ZPROBE_OFFSET) && ENABLED(MESH_BED_LEVELING)
@@ -509,8 +529,12 @@ static_assert(X_MAX_LENGTH >= X_BED_SIZE && Y_MAX_LENGTH >= Y_BED_SIZE,
/**
* Individual axis homing is useless for DELTAS
*/
#if ENABLED(INDIVIDUAL_AXIS_HOMING_MENU) && ENABLED(DELTA)
#error "INDIVIDUAL_AXIS_HOMING_MENU is incompatible with DELTA kinematics."
#if ENABLED(INDIVIDUAL_AXIS_HOMING_MENU)
#if ENABLED(DELTA)
#error "INDIVIDUAL_AXIS_HOMING_MENU is incompatible with DELTA kinematics."
#elif ENABLED(HANGPRINTER)
#error "INDIVIDUAL_AXIS_HOMING_MENU is incompatible with HANGPRINTER kinematics."
#endif
#endif
/**
@@ -668,6 +692,7 @@ static_assert(X_MAX_LENGTH >= X_BED_SIZE && Y_MAX_LENGTH >= Y_BED_SIZE,
* Allow only one kinematic type to be defined
*/
#if 1 < 0 \
+ ENABLED(HANGPRINTER) \
+ ENABLED(DELTA) \
+ ENABLED(MORGAN_SCARA) \
+ ENABLED(MAKERARM_SCARA) \
@@ -677,7 +702,7 @@ static_assert(X_MAX_LENGTH >= X_BED_SIZE && Y_MAX_LENGTH >= Y_BED_SIZE,
+ ENABLED(COREYX) \
+ ENABLED(COREZX) \
+ ENABLED(COREZY)
#error "Please enable only one of DELTA, MORGAN_SCARA, MAKERARM_SCARA, COREXY, COREYX, COREXZ, COREZX, COREYZ, or COREZY."
#error "Please enable only one of HANGPRINTER, DELTA, MORGAN_SCARA, MAKERARM_SCARA, COREXY, COREYX, COREXZ, COREZX, COREYZ, or COREZY."
#endif
/**
@@ -699,6 +724,42 @@ static_assert(X_MAX_LENGTH >= X_BED_SIZE && Y_MAX_LENGTH >= Y_BED_SIZE,
#endif
#endif
/**
* Hangprinter requirements
*/
#if ENABLED(HANGPRINTER)
#if EXTRUDERS > 4
#error "Marlin supports a maximum of 4 EXTRUDERS when driving a Hangprinter."
#elif ENABLED(CONVENTIONAL_GEOMETRY)
#if ANCHOR_A_Y > 0
#error "ANCHOR_A_Y should be negative by convention."
#elif (ANCHOR_B_X) * (ANCHOR_C_X) > 0
#error "ANCHOR_B_X and ANCHOR_C_X should have opposite signs by convention."
#elif ANCHOR_B_Y < 0
#error "ANCHOR_B_Y should be positive by convention."
#elif ANCHOR_C_Y < 0
#error "ANCHOR_C_Y should be positive by convention."
#elif ANCHOR_A_Z > 0
#error "ANCHOR_A_Z should be negative by convention."
#elif ANCHOR_B_Z > 0
#error "ANCHOR_B_Z should be negative by convention."
#elif ANCHOR_C_Z > 0
#error "ANCHOR_C_Z should be negative by convention."
#elif ANCHOR_D_Z < 0
#error "ANCHOR_D_Z should be positive by convention."
#endif
#endif
#elif ENABLED(LINE_BUILDUP_COMPENSATION_FEATURE)
#error "LINE_BUILDUP_COMPENSATION_FEATURE is only compatible with HANGPRINTER."
#endif
/**
* Mechaduino requirements
*/
#if ENABLED(MECHADUINO_I2C_COMMANDS) && DISABLED(EXPERIMENTAL_I2CBUS)
#error "MECHADUINO_I2C_COMMANDS requires EXPERIMENTAL_I2CBUS to be enabled."
#endif
/**
* Probes
*/
@@ -743,6 +804,14 @@ static_assert(X_MAX_LENGTH >= X_BED_SIZE && Y_MAX_LENGTH >= Y_BED_SIZE,
#if HAS_Z_SERVO_PROBE
#ifndef NUM_SERVOS
#error "You must set NUM_SERVOS for a Z servo probe (Z_PROBE_SERVO_NR)."
#elif Z_PROBE_SERVO_NR == 0 && !PIN_EXISTS(SERVO0)
#error "SERVO0_PIN must be defined for your servo or BLTOUCH probe."
#elif Z_PROBE_SERVO_NR == 1 && !PIN_EXISTS(SERVO1)
#error "SERVO1_PIN must be defined for your servo or BLTOUCH probe."
#elif Z_PROBE_SERVO_NR == 2 && !PIN_EXISTS(SERVO2)
#error "SERVO2_PIN must be defined for your servo or BLTOUCH probe."
#elif Z_PROBE_SERVO_NR == 3 && !PIN_EXISTS(SERVO3)
#error "SERVO3_PIN must be defined for your servo or BLTOUCH probe."
#elif Z_PROBE_SERVO_NR >= NUM_SERVOS
#error "Z_PROBE_SERVO_NR must be smaller than NUM_SERVOS."
#endif
@@ -792,6 +861,9 @@ static_assert(X_MAX_LENGTH >= X_BED_SIZE && Y_MAX_LENGTH >= Y_BED_SIZE,
#error "Z_PROBE_LOW_POINT must be less than or equal to 0."
#endif
static_assert(int(X_PROBE_OFFSET_FROM_EXTRUDER) == (X_PROBE_OFFSET_FROM_EXTRUDER), "X_PROBE_OFFSET_FROM_EXTRUDER must be an integer value.");
static_assert(int(Y_PROBE_OFFSET_FROM_EXTRUDER) == (Y_PROBE_OFFSET_FROM_EXTRUDER), "Y_PROBE_OFFSET_FROM_EXTRUDER must be an integer value.");
#else
/**
@@ -1182,6 +1254,7 @@ static_assert(X_MAX_LENGTH >= X_BED_SIZE && Y_MAX_LENGTH >= Y_BED_SIZE,
#endif
#endif
#endif
/**
* Endstop Tests
*/
@@ -1189,33 +1262,33 @@ static_assert(X_MAX_LENGTH >= X_BED_SIZE && Y_MAX_LENGTH >= Y_BED_SIZE,
#define _PLUG_UNUSED_TEST(AXIS,PLUG) (DISABLED(USE_##PLUG##MIN_PLUG) && DISABLED(USE_##PLUG##MAX_PLUG) && !(ENABLED(AXIS##_DUAL_ENDSTOPS) && WITHIN(AXIS##2_USE_ENDSTOP, _##PLUG##MAX_, _##PLUG##MIN_)))
#define _AXIS_PLUG_UNUSED_TEST(AXIS) (_PLUG_UNUSED_TEST(AXIS,X) && _PLUG_UNUSED_TEST(AXIS,Y) && _PLUG_UNUSED_TEST(AXIS,Z))
// At least 3 endstop plugs must be used
#if _AXIS_PLUG_UNUSED_TEST(X)
#error "You must enable USE_XMIN_PLUG or USE_XMAX_PLUG."
#endif
#if _AXIS_PLUG_UNUSED_TEST(Y)
#error "You must enable USE_YMIN_PLUG or USE_YMAX_PLUG."
#endif
#if _AXIS_PLUG_UNUSED_TEST(Z)
#error "You must enable USE_ZMIN_PLUG or USE_ZMAX_PLUG."
#endif
// Delta and Cartesian use 3 homing endstops
#if !IS_SCARA
#if X_HOME_DIR < 0 && DISABLED(USE_XMIN_PLUG)
#error "Enable USE_XMIN_PLUG when homing X to MIN."
#elif X_HOME_DIR > 0 && DISABLED(USE_XMAX_PLUG)
#error "Enable USE_XMAX_PLUG when homing X to MAX."
#elif Y_HOME_DIR < 0 && DISABLED(USE_YMIN_PLUG)
#error "Enable USE_YMIN_PLUG when homing Y to MIN."
#elif Y_HOME_DIR > 0 && DISABLED(USE_YMAX_PLUG)
#error "Enable USE_YMAX_PLUG when homing Y to MAX."
#if DISABLED(HANGPRINTER)
// At least 3 endstop plugs must be used
#if _AXIS_PLUG_UNUSED_TEST(X)
#error "You must enable USE_XMIN_PLUG or USE_XMAX_PLUG."
#elif _AXIS_PLUG_UNUSED_TEST(Y)
#error "You must enable USE_YMIN_PLUG or USE_YMAX_PLUG."
#elif _AXIS_PLUG_UNUSED_TEST(Z)
#error "You must enable USE_ZMIN_PLUG or USE_ZMAX_PLUG."
#endif
// Delta and Cartesian use 3 homing endstops
#if !IS_SCARA
#if X_HOME_DIR < 0 && DISABLED(USE_XMIN_PLUG)
#error "Enable USE_XMIN_PLUG when homing X to MIN."
#elif X_HOME_DIR > 0 && DISABLED(USE_XMAX_PLUG)
#error "Enable USE_XMAX_PLUG when homing X to MAX."
#elif Y_HOME_DIR < 0 && DISABLED(USE_YMIN_PLUG)
#error "Enable USE_YMIN_PLUG when homing Y to MIN."
#elif Y_HOME_DIR > 0 && DISABLED(USE_YMAX_PLUG)
#error "Enable USE_YMAX_PLUG when homing Y to MAX."
#endif
#endif
#if Z_HOME_DIR < 0 && DISABLED(USE_ZMIN_PLUG)
#error "Enable USE_ZMIN_PLUG when homing Z to MIN."
#elif Z_HOME_DIR > 0 && DISABLED(USE_ZMAX_PLUG)
#error "Enable USE_ZMAX_PLUG when homing Z to MAX."
#endif
#endif
#if Z_HOME_DIR < 0 && DISABLED(USE_ZMIN_PLUG)
#error "Enable USE_ZMIN_PLUG when homing Z to MIN."
#elif Z_HOME_DIR > 0 && DISABLED(USE_ZMAX_PLUG)
#error "Enable USE_ZMAX_PLUG when homing Z to MAX."
#endif
// Dual endstops requirements
@@ -1413,246 +1486,95 @@ static_assert(X_MAX_LENGTH >= X_BED_SIZE && Y_MAX_LENGTH >= Y_BED_SIZE,
#endif
/**
* Make sure HAVE_TMC26X is warranted
* Check existing CS pins against enabled TMC SPI drivers.
*/
#if ENABLED(HAVE_TMC26X) && !( \
ENABLED( X_IS_TMC26X) \
|| ENABLED(X2_IS_TMC26X) \
|| ENABLED( Y_IS_TMC26X) \
|| ENABLED(Y2_IS_TMC26X) \
|| ENABLED( Z_IS_TMC26X) \
|| ENABLED(Z2_IS_TMC26X) \
|| ENABLED(E0_IS_TMC26X) \
|| ENABLED(E1_IS_TMC26X) \
|| ENABLED(E2_IS_TMC26X) \
|| ENABLED(E3_IS_TMC26X) \
|| ENABLED(E4_IS_TMC26X) \
)
#error "HAVE_TMC26X requires at least one TMC26X stepper to be set."
#if AXIS_DRIVER_TYPE(X, TMC2130) && !PIN_EXISTS(X_CS)
#error "X_CS_PIN is required for TMC2130. Define X_CS_PIN in Configuration_adv.h."
#elif AXIS_DRIVER_TYPE(X2, TMC2130) && !PIN_EXISTS(X2_CS)
#error "X2_CS_PIN is required for X2. Define X2_CS_PIN in Configuration_adv.h."
#elif AXIS_DRIVER_TYPE(Y, TMC2130) && !PIN_EXISTS(Y_CS)
#error "Y_CS_PIN is required for TMC2130. Define Y_CS_PIN in Configuration_adv.h."
#elif AXIS_DRIVER_TYPE(Y2, TMC2130) && !PIN_EXISTS(Y2_CS)
#error "Y2_CS_PIN is required for TMC2130. Define Y2_CS_PIN in Configuration_adv.h."
#elif AXIS_DRIVER_TYPE(Z, TMC2130) && !PIN_EXISTS(Z_CS)
#error "Z_CS_PIN is required for TMC2130. Define Z_CS_PIN in Configuration_adv.h."
#elif AXIS_DRIVER_TYPE(Z2, TMC2130) && !PIN_EXISTS(Z2_CS)
#error "Z2_CS_PIN is required for TMC2130. Define Z2_CS_PIN in Configuration_adv.h."
#elif AXIS_DRIVER_TYPE(E0, TMC2130) && !PIN_EXISTS(E0_CS)
#error "E0_CS_PIN is required for TMC2130. Define E0_CS_PIN in Configuration_adv.h."
#elif AXIS_DRIVER_TYPE(E1, TMC2130) && !PIN_EXISTS(E1_CS)
#error "E1_CS_PIN is required for TMC2130. Define E1_CS_PIN in Configuration_adv.h."
#elif AXIS_DRIVER_TYPE(E2, TMC2130) && !PIN_EXISTS(E2_CS)
#error "E2_CS_PIN is required for TMC2130. Define E2_CS_PIN in Configuration_adv.h."
#elif AXIS_DRIVER_TYPE(E3, TMC2130) && !PIN_EXISTS(E3_CS)
#error "E3_CS_PIN is required for TMC2130. Define E3_CS_PIN in Configuration_adv.h."
#elif AXIS_DRIVER_TYPE(E4, TMC2130) && !PIN_EXISTS(E4_CS)
#error "E4_CS_PIN is required for TMC2130. Define E4_CS_PIN in Configuration_adv.h."
#endif
/**
* TMC2130 Requirements
* TMC2208 software UART and ENDSTOP_INTERRUPTS both use pin change interrupts (PCI)
*/
#if ENABLED(HAVE_TMC2130)
#if !( ENABLED( X_IS_TMC2130) \
|| ENABLED(X2_IS_TMC2130) \
|| ENABLED( Y_IS_TMC2130) \
|| ENABLED(Y2_IS_TMC2130) \
|| ENABLED( Z_IS_TMC2130) \
|| ENABLED(Z2_IS_TMC2130) \
|| ENABLED(E0_IS_TMC2130) \
|| ENABLED(E1_IS_TMC2130) \
|| ENABLED(E2_IS_TMC2130) \
|| ENABLED(E3_IS_TMC2130) \
|| ENABLED(E4_IS_TMC2130) )
#error "HAVE_TMC2130 requires at least one TMC2130 stepper to be set."
#elif ENABLED(HYBRID_THRESHOLD) && DISABLED(STEALTHCHOP)
#error "Enable STEALTHCHOP to use HYBRID_THRESHOLD."
#endif
#if ENABLED(X_IS_TMC2130) && !PIN_EXISTS(X_CS)
#error "X_CS_PIN is required for X_IS_TMC2130. Define X_CS_PIN in Configuration_adv.h."
#elif ENABLED(X2_IS_TMC2130) && !PIN_EXISTS(X2_CS)
#error "X2_CS_PIN is required for X2_IS_TMC2130. Define X2_CS_PIN in Configuration_adv.h."
#elif ENABLED(Y_IS_TMC2130) && !PIN_EXISTS(Y_CS)
#error "Y_CS_PIN is required for Y_IS_TMC2130. Define Y_CS_PIN in Configuration_adv.h."
#elif ENABLED(Y2_IS_TMC2130) && !PIN_EXISTS(Y2_CS)
#error "Y2_CS_PIN is required for Y2_IS_TMC2130. Define Y2_CS_PIN in Configuration_adv.h."
#elif ENABLED(Z_IS_TMC2130) && !PIN_EXISTS(Z_CS)
#error "Z_CS_PIN is required for Z_IS_TMC2130. Define Z_CS_PIN in Configuration_adv.h."
#elif ENABLED(Z2_IS_TMC2130) && !PIN_EXISTS(Z2_CS)
#error "Z2_CS_PIN is required for Z2_IS_TMC2130. Define Z2_CS_PIN in Configuration_adv.h."
#elif ENABLED(E0_IS_TMC2130) && !PIN_EXISTS(E0_CS)
#error "E0_CS_PIN is required for E0_IS_TMC2130. Define E0_CS_PIN in Configuration_adv.h."
#elif ENABLED(E1_IS_TMC2130) && !PIN_EXISTS(E1_CS)
#error "E1_CS_PIN is required for E1_IS_TMC2130. Define E1_CS_PIN in Configuration_adv.h."
#elif ENABLED(E2_IS_TMC2130) && !PIN_EXISTS(E2_CS)
#error "E2_CS_PIN is required for E2_IS_TMC2130. Define E2_CS_PIN in Configuration_adv.h."
#elif ENABLED(E3_IS_TMC2130) && !PIN_EXISTS(E3_CS)
#error "E3_CS_PIN is required for E3_IS_TMC2130. Define E3_CS_PIN in Configuration_adv.h."
#elif ENABLED(E4_IS_TMC2130) && !PIN_EXISTS(E4_CS)
#error "E4_CS_PIN is required for E4_IS_TMC2130. Define E4_CS_PIN in Configuration_adv.h."
#endif
#if ENABLED(SENSORLESS_HOMING)
// Require STEALTHCHOP for SENSORLESS_HOMING on DELTA as the transition from spreadCycle to stealthChop
// is necessary in order to reset the stallGuard indication between the initial movement of all three
// towers to +Z and the individual homing of each tower. This restriction can be removed once a means of
// clearing the stallGuard activated status is found.
#if ENABLED(DELTA) && !ENABLED(STEALTHCHOP)
#error "SENSORLESS_HOMING on DELTA currently requires STEALTHCHOP."
#elif X_SENSORLESS && X_HOME_DIR == -1 && (DISABLED(X_MIN_ENDSTOP_INVERTING) || DISABLED(ENDSTOPPULLUP_XMIN))
#error "SENSORLESS_HOMING requires X_MIN_ENDSTOP_INVERTING and ENDSTOPPULLUP_XMIN when homing to X_MIN."
#elif X_SENSORLESS && X_HOME_DIR == 1 && (DISABLED(X_MAX_ENDSTOP_INVERTING) || DISABLED(ENDSTOPPULLUP_XMAX))
#error "SENSORLESS_HOMING requires X_MAX_ENDSTOP_INVERTING and ENDSTOPPULLUP_XMAX when homing to X_MAX."
#elif Y_SENSORLESS && Y_HOME_DIR == -1 && (DISABLED(Y_MIN_ENDSTOP_INVERTING) || DISABLED(ENDSTOPPULLUP_YMIN))
#error "SENSORLESS_HOMING requires Y_MIN_ENDSTOP_INVERTING and ENDSTOPPULLUP_YMIN when homing to Y_MIN."
#elif Y_SENSORLESS && Y_HOME_DIR == 1 && (DISABLED(Y_MAX_ENDSTOP_INVERTING) || DISABLED(ENDSTOPPULLUP_YMAX))
#error "SENSORLESS_HOMING requires Y_MAX_ENDSTOP_INVERTING and ENDSTOPPULLUP_YMAX when homing to Y_MAX."
#elif Z_SENSORLESS && Z_HOME_DIR == -1 && (DISABLED(Z_MIN_ENDSTOP_INVERTING) || DISABLED(ENDSTOPPULLUP_ZMIN))
#error "SENSORLESS_HOMING requires Z_MIN_ENDSTOP_INVERTING and ENDSTOPPULLUP_ZMIN when homing to Z_MIN."
#elif Z_SENSORLESS && Z_HOME_DIR == 1 && (DISABLED(Z_MAX_ENDSTOP_INVERTING) || DISABLED(ENDSTOPPULLUP_ZMAX))
#error "SENSORLESS_HOMING requires Z_MAX_ENDSTOP_INVERTING and ENDSTOPPULLUP_ZMAX when homing to Z_MAX."
#elif ENABLED(ENDSTOP_NOISE_FILTER)
#error "SENSORLESS_HOMING is incompatible with ENDSTOP_NOISE_FILTER."
#endif
#endif
// Sensorless homing is required for both combined steppers in an H-bot
#if CORE_IS_XY && X_SENSORLESS != Y_SENSORLESS
#error "CoreXY requires both X and Y to use sensorless homing if either does."
#elif CORE_IS_XZ && X_SENSORLESS != Z_SENSORLESS
#error "CoreXZ requires both X and Z to use sensorless homing if either does."
#elif CORE_IS_YZ && Y_SENSORLESS != Z_SENSORLESS
#error "CoreYZ requires both Y and Z to use sensorless homing if either does."
#endif
#elif ENABLED(SENSORLESS_HOMING)
#error "SENSORLESS_HOMING requires TMC2130 stepper drivers."
#if HAS_DRIVER(TMC2208) && ENABLED(ENDSTOP_INTERRUPTS_FEATURE) && !( \
defined(X_HARDWARE_SERIAL ) \
|| defined(X2_HARDWARE_SERIAL) \
|| defined(Y_HARDWARE_SERIAL ) \
|| defined(Y2_HARDWARE_SERIAL) \
|| defined(Z_HARDWARE_SERIAL ) \
|| defined(Z2_HARDWARE_SERIAL) \
|| defined(E0_HARDWARE_SERIAL) \
|| defined(E1_HARDWARE_SERIAL) \
|| defined(E2_HARDWARE_SERIAL) \
|| defined(E3_HARDWARE_SERIAL) \
|| defined(E4_HARDWARE_SERIAL) )
#error "select hardware UART for TMC2208 to use both TMC2208 and ENDSTOP_INTERRUPTS_FEATURE."
#endif
/**
* TMC2208 Requirements
*/
#if ENABLED(HAVE_TMC2208)
#if !( ENABLED( X_IS_TMC2208) \
|| ENABLED(X2_IS_TMC2208) \
|| ENABLED( Y_IS_TMC2208) \
|| ENABLED(Y2_IS_TMC2208) \
|| ENABLED( Z_IS_TMC2208) \
|| ENABLED(Z2_IS_TMC2208) \
|| ENABLED(E0_IS_TMC2208) \
|| ENABLED(E1_IS_TMC2208) \
|| ENABLED(E2_IS_TMC2208) \
|| ENABLED(E3_IS_TMC2208) \
|| ENABLED(E4_IS_TMC2208 ) )
#error "HAVE_TMC2208 requires at least one TMC2208 stepper to be set."
// Software UART and ENDSTOP_INTERRUPTS both use Pin Change interrupts (PCI)
#elif ENABLED(ENDSTOP_INTERRUPTS_FEATURE) && \
!( defined( X_HARDWARE_SERIAL) \
|| defined(X2_HARDWARE_SERIAL) \
|| defined( Y_HARDWARE_SERIAL) \
|| defined(Y2_HARDWARE_SERIAL) \
|| defined( Z_HARDWARE_SERIAL) \
|| defined(Z2_HARDWARE_SERIAL) \
|| defined(E0_HARDWARE_SERIAL) \
|| defined(E1_HARDWARE_SERIAL) \
|| defined(E2_HARDWARE_SERIAL) \
|| defined(E3_HARDWARE_SERIAL) \
|| defined(E4_HARDWARE_SERIAL) )
#error "Select *_HARDWARE_SERIAL to use both TMC2208 and ENDSTOP_INTERRUPTS_FEATURE."
#if ENABLED(SENSORLESS_HOMING)
// Require STEALTHCHOP for SENSORLESS_HOMING on DELTA as the transition from spreadCycle to stealthChop
// is necessary in order to reset the stallGuard indication between the initial movement of all three
// towers to +Z and the individual homing of each tower. This restriction can be removed once a means of
// clearing the stallGuard activated status is found.
#if ENABLED(DELTA) && !ENABLED(STEALTHCHOP)
#error "SENSORLESS_HOMING on DELTA currently requires STEALTHCHOP."
#elif X_SENSORLESS && X_HOME_DIR == -1 && (DISABLED(X_MIN_ENDSTOP_INVERTING) || DISABLED(ENDSTOPPULLUP_XMIN))
#error "SENSORLESS_HOMING requires X_MIN_ENDSTOP_INVERTING and ENDSTOPPULLUP_XMIN when homing to X_MIN."
#elif X_SENSORLESS && X_HOME_DIR == 1 && (DISABLED(X_MAX_ENDSTOP_INVERTING) || DISABLED(ENDSTOPPULLUP_XMAX))
#error "SENSORLESS_HOMING requires X_MAX_ENDSTOP_INVERTING and ENDSTOPPULLUP_XMAX when homing to X_MAX."
#elif Y_SENSORLESS && Y_HOME_DIR == -1 && (DISABLED(Y_MIN_ENDSTOP_INVERTING) || DISABLED(ENDSTOPPULLUP_YMIN))
#error "SENSORLESS_HOMING requires Y_MIN_ENDSTOP_INVERTING and ENDSTOPPULLUP_YMIN when homing to Y_MIN."
#elif Y_SENSORLESS && Y_HOME_DIR == 1 && (DISABLED(Y_MAX_ENDSTOP_INVERTING) || DISABLED(ENDSTOPPULLUP_YMAX))
#error "SENSORLESS_HOMING requires Y_MAX_ENDSTOP_INVERTING and ENDSTOPPULLUP_YMAX when homing to Y_MAX."
#elif Z_SENSORLESS && Z_HOME_DIR == -1 && (DISABLED(Z_MIN_ENDSTOP_INVERTING) || DISABLED(ENDSTOPPULLUP_ZMIN))
#error "SENSORLESS_HOMING requires Z_MIN_ENDSTOP_INVERTING and ENDSTOPPULLUP_ZMIN when homing to Z_MIN."
#elif Z_SENSORLESS && Z_HOME_DIR == 1 && (DISABLED(Z_MAX_ENDSTOP_INVERTING) || DISABLED(ENDSTOPPULLUP_ZMAX))
#error "SENSORLESS_HOMING requires Z_MAX_ENDSTOP_INVERTING and ENDSTOPPULLUP_ZMAX when homing to Z_MAX."
#elif ENABLED(ENDSTOP_NOISE_FILTER)
#error "SENSORLESS_HOMING is incompatible with ENDSTOP_NOISE_FILTER."
#endif
#endif
// Sensorless homing is required for both combined steppers in an H-bot
#if CORE_IS_XY && X_SENSORLESS != Y_SENSORLESS
#error "CoreXY requires both X and Y to use sensorless homing if either does."
#elif CORE_IS_XZ && X_SENSORLESS != Z_SENSORLESS
#error "CoreXZ requires both X and Z to use sensorless homing if either does."
#elif CORE_IS_YZ && Y_SENSORLESS != Z_SENSORLESS
#error "CoreYZ requires both Y and Z to use sensorless homing if either does."
#endif
#if ENABLED(HYBRID_THRESHOLD) && DISABLED(STEALTHCHOP)
#error "Enable STEALTHCHOP to use HYBRID_THRESHOLD."
#endif
#if ENABLED(TMC_Z_CALIBRATION) && !Z_IS_TRINAMIC && !Z2_IS_TRINAMIC
#if ENABLED(TMC_Z_CALIBRATION) && !AXIS_IS_TMC(Z) && !AXIS_IS_TMC(Z2)
#error "TMC_Z_CALIBRATION requires at least one TMC driver on Z axis"
#endif
/**
* Make sure HAVE_L6470DRIVER is warranted
*/
#if ENABLED(HAVE_L6470DRIVER) && !( \
ENABLED( X_IS_L6470) \
|| ENABLED(X2_IS_L6470) \
|| ENABLED( Y_IS_L6470) \
|| ENABLED(Y2_IS_L6470) \
|| ENABLED( Z_IS_L6470) \
|| ENABLED(Z2_IS_L6470) \
|| ENABLED(E0_IS_L6470) \
|| ENABLED(E1_IS_L6470) \
|| ENABLED(E2_IS_L6470) \
|| ENABLED(E3_IS_L6470) \
|| ENABLED(E4_IS_L6470) \
)
#error "HAVE_L6470DRIVER requires at least one L6470 stepper to be set."
#if ENABLED(SENSORLESS_HOMING) && !HAS_STALLGUARD
#error "SENSORLESS_HOMING requires TMC2130 or TMC2660 stepper drivers."
#endif
/**
* Check that each axis has only one driver selected
*/
#if 1 < 0 \
+ ENABLED(X_IS_TMC26X) \
+ ENABLED(X_IS_TMC2130) \
+ ENABLED(X_IS_TMC2208) \
+ ENABLED(X_IS_L6470)
#error "Please enable only one stepper driver for the X axis."
#endif
#if 1 < 0 \
+ ENABLED(X2_IS_TMC26X) \
+ ENABLED(X2_IS_TMC2130) \
+ ENABLED(X2_IS_TMC2208) \
+ ENABLED(X2_IS_L6470)
#error "Please enable only one stepper driver for the X2 axis."
#endif
#if 1 < 0 \
+ ENABLED(Y_IS_TMC26X) \
+ ENABLED(Y_IS_TMC2130) \
+ ENABLED(Y_IS_TMC2208) \
+ ENABLED(Y_IS_L6470)
#error "Please enable only one stepper driver for the Y axis."
#endif
#if 1 < 0 \
+ ENABLED(Y2_IS_TMC26X) \
+ ENABLED(Y2_IS_TMC2130) \
+ ENABLED(Y2_IS_TMC2208) \
+ ENABLED(Y2_IS_L6470)
#error "Please enable only one stepper driver for the Y2 axis."
#endif
#if 1 < 0 \
+ ENABLED(Z_IS_TMC26X) \
+ ENABLED(Z_IS_TMC2130) \
+ ENABLED(Z_IS_TMC2208) \
+ ENABLED(Z_IS_L6470)
#error "Please enable only one stepper driver for the Z axis."
#endif
#if 1 < 0 \
+ ENABLED(Z2_IS_TMC26X) \
+ ENABLED(Z2_IS_TMC2130) \
+ ENABLED(Z2_IS_TMC2208) \
+ ENABLED(Z2_IS_L6470)
#error "Please enable only one stepper driver for the Z2 axis."
#endif
#if 1 < 0 \
+ ENABLED(E0_IS_TMC26X) \
+ ENABLED(E0_IS_TMC2130) \
+ ENABLED(E0_IS_TMC2208) \
+ ENABLED(E0_IS_L6470)
#error "Please enable only one stepper driver for the E0 axis."
#endif
#if 1 < 0 \
+ ENABLED(E1_IS_TMC26X) \
+ ENABLED(E1_IS_TMC2130) \
+ ENABLED(E1_IS_TMC2208) \
+ ENABLED(E1_IS_L6470)
#error "Please enable only one stepper driver for the E1 axis."
#endif
#if 1 < 0 \
+ ENABLED(E2_IS_TMC26X) \
+ ENABLED(E2_IS_TMC2130) \
+ ENABLED(E2_IS_TMC2208) \
+ ENABLED(E2_IS_L6470)
#error "Please enable only one stepper driver for the E2 axis."
#endif
#if 1 < 0 \
+ ENABLED(E3_IS_TMC26X) \
+ ENABLED(E3_IS_TMC2130) \
+ ENABLED(E3_IS_TMC2208) \
+ ENABLED(E3_IS_L6470)
#error "Please enable only one stepper driver for the E3 axis."
#endif
#if 1 < 0 \
+ ENABLED(E4_IS_TMC26X) \
+ ENABLED(E4_IS_TMC2130) \
+ ENABLED(E4_IS_TMC2208) \
+ ENABLED(E4_IS_L6470)
#error "Please enable only one stepper driver for the E4 axis."
#if ENABLED(STEALTHCHOP) && !HAS_STEALTHCHOP
#error "STEALTHCHOP requires TMC2130 or TMC2208 stepper drivers."
#endif
/**
@@ -1666,17 +1588,24 @@ static_assert(X_MAX_LENGTH >= X_BED_SIZE && Y_MAX_LENGTH >= Y_BED_SIZE,
#endif
/**
* Require 4 or more elements in per-axis initializers
* Require 5/4 or more elements in per-axis initializers
*/
#if ENABLED(HANGPRINTER)
#define MIN_ELEMENTS "5"
#else
#define MIN_ELEMENTS "4"
#endif
constexpr float sanity_arr_1[] = DEFAULT_AXIS_STEPS_PER_UNIT,
sanity_arr_2[] = DEFAULT_MAX_FEEDRATE,
sanity_arr_3[] = DEFAULT_MAX_ACCELERATION;
static_assert(COUNT(sanity_arr_1) >= XYZE, "DEFAULT_AXIS_STEPS_PER_UNIT requires 4 (or more) elements.");
static_assert(COUNT(sanity_arr_2) >= XYZE, "DEFAULT_MAX_FEEDRATE requires 4 (or more) elements.");
static_assert(COUNT(sanity_arr_3) >= XYZE, "DEFAULT_MAX_ACCELERATION requires 4 (or more) elements.");
static_assert(COUNT(sanity_arr_1) <= XYZE_N, "DEFAULT_AXIS_STEPS_PER_UNIT has too many elements.");
static_assert(COUNT(sanity_arr_2) <= XYZE_N, "DEFAULT_MAX_FEEDRATE has too many elements.");
static_assert(COUNT(sanity_arr_3) <= XYZE_N, "DEFAULT_MAX_ACCELERATION has too many elements.");
static_assert(COUNT(sanity_arr_1) >= NUM_AXIS, "DEFAULT_AXIS_STEPS_PER_UNIT requires " MIN_ELEMENTS " (or more) elements for HANGPRINTER.");
static_assert(COUNT(sanity_arr_2) >= NUM_AXIS, "DEFAULT_MAX_FEEDRATE requires " MIN_ELEMENTS " (or more) elements for HANGPRINTER.");
static_assert(COUNT(sanity_arr_3) >= NUM_AXIS, "DEFAULT_MAX_ACCELERATION requires " MIN_ELEMENTS " (or more) elements for HANGPRINTER.");
static_assert(COUNT(sanity_arr_1) <= NUM_AXIS_N, "DEFAULT_AXIS_STEPS_PER_UNIT has too many elements.");
static_assert(COUNT(sanity_arr_2) <= NUM_AXIS_N, "DEFAULT_MAX_FEEDRATE has too many elements.");
static_assert(COUNT(sanity_arr_3) <= NUM_AXIS_N, "DEFAULT_MAX_ACCELERATION has too many elements.");
/**
* Sanity checks for Spindle / Laser
+1 -1
View File
@@ -399,7 +399,7 @@ bool Sd2Card::readBlock(uint32_t blockNumber, uint8_t* dst) {
#if ENABLED(SD_CHECK_AND_RETRY)
uint8_t retryCnt = 3;
for(;;) {
for (;;) {
if (cardCommand(CMD17, blockNumber))
error(SD_CARD_ERROR_CMD17);
else if (readData(dst, 512))
+3 -3
View File
@@ -35,7 +35,7 @@
/**
* Marlin release version identifier
*/
#define SHORT_BUILD_VERSION "1.1.8-R7"
#define SHORT_BUILD_VERSION "1.1.9-R2"
/**
* Verbose version identifier which should contain a reference to the location
@@ -48,7 +48,7 @@
* here we define this default string as the date where the latest release
* version was tagged.
*/
#define STRING_DISTRIBUTION_DATE "2018-07-07"
#define STRING_DISTRIBUTION_DATE "2018-09-28"
/**
* Required minimum Configuration.h and Configuration_adv.h file versions.
@@ -89,6 +89,6 @@
* The WEBSITE_URL is the location where users can get more information such as
* documentation about a specific Marlin release.
*/
#define WEBSITE_URL "www.formbotusa.com"
#define WEBSITE_URL "tinymachines3d.com"
#endif // USE_AUTOMATIC_VERSIONING
+8 -10
View File
@@ -35,8 +35,6 @@
#include "power_loss_recovery.h"
#endif
#define LONGEST_FILENAME (longFilename[0] ? longFilename : filename)
CardReader::CardReader() {
#if ENABLED(SDCARD_SORT_ALPHA)
sort_count = 0;
@@ -731,7 +729,7 @@ void CardReader::setroot() {
getfilename(i);
#if ENABLED(SDSORT_DYNAMIC_RAM)
// Use dynamic method to copy long filename
sortnames[i] = strdup(LONGEST_FILENAME);
sortnames[i] = strdup(longest_filename());
#if ENABLED(SDSORT_CACHE_NAMES)
// When caching also store the short name, since
// we're replacing the getfilename() behavior.
@@ -740,10 +738,10 @@ void CardReader::setroot() {
#else
// Copy filenames into the static array
#if SORTED_LONGNAME_MAXLEN != LONG_FILENAME_LENGTH
strncpy(sortnames[i], LONGEST_FILENAME, SORTED_LONGNAME_MAXLEN);
strncpy(sortnames[i], longest_filename(), SORTED_LONGNAME_MAXLEN);
sortnames[i][SORTED_LONGNAME_MAXLEN - 1] = '\0';
#else
strncpy(sortnames[i], LONGEST_FILENAME, SORTED_LONGNAME_MAXLEN);
strncpy(sortnames[i], longest_filename(), SORTED_LONGNAME_MAXLEN);
#endif
#if ENABLED(SDSORT_CACHE_NAMES)
strcpy(sortshort[i], filename);
@@ -791,12 +789,12 @@ void CardReader::setroot() {
// throughout the loop. Slow if there are many.
#if DISABLED(SDSORT_USES_RAM)
getfilename(o1);
strcpy(name1, LONGEST_FILENAME); // save (or getfilename below will trounce it)
strcpy(name1, longest_filename()); // save (or getfilename below will trounce it)
#if HAS_FOLDER_SORTING
bool dir1 = filenameIsDir;
#endif
getfilename(o2);
char *name2 = LONGEST_FILENAME; // use the string in-place
char *name2 = longest_filename(); // use the string in-place
#endif // !SDSORT_USES_RAM
// Sort the current pair according to settings.
@@ -834,7 +832,7 @@ void CardReader::setroot() {
getfilename(0);
#if ENABLED(SDSORT_DYNAMIC_RAM)
sortnames = new char*[1];
sortnames[0] = strdup(LONGEST_FILENAME); // malloc
sortnames[0] = strdup(longest_filename()); // malloc
#if ENABLED(SDSORT_CACHE_NAMES)
sortshort = new char*[1];
sortshort[0] = strdup(filename); // malloc
@@ -842,10 +840,10 @@ void CardReader::setroot() {
isDir = new uint8_t[1];
#else
#if SORTED_LONGNAME_MAXLEN != LONG_FILENAME_LENGTH
strncpy(sortnames[0], LONGEST_FILENAME, SORTED_LONGNAME_MAXLEN);
strncpy(sortnames[0], longest_filename(), SORTED_LONGNAME_MAXLEN);
sortnames[0][SORTED_LONGNAME_MAXLEN - 1] = '\0';
#else
strncpy(sortnames[0], LONGEST_FILENAME, SORTED_LONGNAME_MAXLEN);
strncpy(sortnames[0], longest_filename(), SORTED_LONGNAME_MAXLEN);
#endif
#if ENABLED(SDSORT_CACHE_NAMES)
strcpy(sortshort[0], filename);
+2
View File
@@ -114,6 +114,8 @@ public:
}
#endif
FORCE_INLINE char* longest_filename() { return longFilename[0] ? longFilename : filename; }
public:
bool saving, logging, sdprinting, cardOK, filenameIsDir;
char filename[FILENAME_LENGTH], longFilename[LONG_FILENAME_LENGTH];
+262 -141
View File
@@ -95,19 +95,19 @@ typedef struct SettingsDataStruct {
//
// DISTINCT_E_FACTORS
//
uint8_t esteppers; // XYZE_N - XYZ
uint8_t esteppers; // NUM_AXIS_N - MOV_AXIS
uint32_t planner_max_acceleration_mm_per_s2[XYZE_N], // M201 XYZE planner.max_acceleration_mm_per_s2[XYZE_N]
planner_min_segment_time_us; // M205 B planner.min_segment_time_us
float planner_axis_steps_per_mm[XYZE_N], // M92 XYZE planner.axis_steps_per_mm[XYZE_N]
planner_max_feedrate_mm_s[XYZE_N], // M203 XYZE planner.max_feedrate_mm_s[XYZE_N]
planner_acceleration, // M204 P planner.acceleration
planner_retract_acceleration, // M204 R planner.retract_acceleration
planner_travel_acceleration, // M204 T planner.travel_acceleration
planner_min_feedrate_mm_s, // M205 S planner.min_feedrate_mm_s
planner_min_travel_feedrate_mm_s, // M205 T planner.min_travel_feedrate_mm_s
planner_max_jerk[XYZE], // M205 XYZE planner.max_jerk[XYZE]
planner_junction_deviation_mm; // M205 J planner.junction_deviation_mm
uint32_t planner_max_acceleration_mm_per_s2[NUM_AXIS_N], // M201 XYZE/ABCDE planner.max_acceleration_mm_per_s2[NUM_AXIS_N]
planner_min_segment_time_us; // M205 Q planner.min_segment_time_us
float planner_axis_steps_per_mm[NUM_AXIS_N], // M92 XYZE/ABCDE planner.axis_steps_per_mm[NUM_AXIS_N]
planner_max_feedrate_mm_s[NUM_AXIS_N], // M203 XYZE/ABCDE planner.max_feedrate_mm_s[NUM_AXIS_N]
planner_acceleration, // M204 P planner.acceleration
planner_retract_acceleration, // M204 R planner.retract_acceleration
planner_travel_acceleration, // M204 T planner.travel_acceleration
planner_min_feedrate_mm_s, // M205 S planner.min_feedrate_mm_s
planner_min_travel_feedrate_mm_s, // M205 T planner.min_travel_feedrate_mm_s
planner_max_jerk[NUM_AXIS], // M205 XYZE/ABCDE planner.max_jerk[NUM_AXIS]
planner_junction_deviation_mm; // M205 J planner.junction_deviation_mm
float home_offset[XYZ]; // M206 XYZ
@@ -163,6 +163,7 @@ typedef struct SettingsDataStruct {
// DELTA / [XYZ]_DUAL_ENDSTOPS
//
#if ENABLED(DELTA)
float delta_height, // M666 H
delta_endstop_adj[ABC], // M666 XYZ
delta_radius, // M665 R
@@ -170,10 +171,27 @@ typedef struct SettingsDataStruct {
delta_segments_per_second, // M665 S
delta_calibration_radius, // M665 B
delta_tower_angle_trim[ABC]; // M665 XYZ
#elif ENABLED(HANGPRINTER)
float anchor_A_y, // M665 W
anchor_A_z, // M665 E
anchor_B_x, // M665 R
anchor_B_y, // M665 T
anchor_B_z, // M665 Y
anchor_C_x, // M665 U
anchor_C_y, // M665 I
anchor_C_z, // M665 O
anchor_D_z, // M665 P
delta_segments_per_second, // M665 S
hangprinter_calibration_radius_placeholder;
#elif ENABLED(X_DUAL_ENDSTOPS) || ENABLED(Y_DUAL_ENDSTOPS) || ENABLED(Z_DUAL_ENDSTOPS)
float x_endstop_adj, // M666 X
y_endstop_adj, // M666 Y
z_endstop_adj; // M666 Z
#endif
//
@@ -285,6 +303,8 @@ void MarlinSettings::postprocess() {
// planner position so the stepper counts will be set correctly.
#if ENABLED(DELTA)
recalc_delta_settings();
#elif ENABLED(HANGPRINTER)
recalc_hangprinter_settings();
#endif
#if ENABLED(PIDTEMP)
@@ -418,7 +438,7 @@ void MarlinSettings::postprocess() {
_FIELD_TEST(esteppers);
const uint8_t esteppers = COUNT(planner.axis_steps_per_mm) - XYZ;
const uint8_t esteppers = NUM_AXIS_N - MOV_AXIS;
EEPROM_WRITE(esteppers);
EEPROM_WRITE(planner.max_acceleration_mm_per_s2);
@@ -432,7 +452,13 @@ void MarlinSettings::postprocess() {
EEPROM_WRITE(planner.min_travel_feedrate_mm_s);
#if ENABLED(JUNCTION_DEVIATION)
const float planner_max_jerk[] = { float(DEFAULT_XJERK), float(DEFAULT_YJERK), float(DEFAULT_ZJERK), float(DEFAULT_EJERK) };
const float planner_max_jerk[] = {
#if ENABLED(HANGPRINTER)
float(DEFAULT_AJERK), float(DEFAULT_BJERK), float(DEFAULT_CJERK), float(DEFAULT_DJERK), float(DEFAULT_EJERK)
#else
float(DEFAULT_XJERK), float(DEFAULT_YJERK), float(DEFAULT_ZJERK), float(DEFAULT_EJERK)
#endif
};
EEPROM_WRITE(planner_max_jerk);
EEPROM_WRITE(planner.junction_deviation_mm);
#else
@@ -560,6 +586,22 @@ void MarlinSettings::postprocess() {
EEPROM_WRITE(delta_calibration_radius); // 1 float
EEPROM_WRITE(delta_tower_angle_trim); // 3 floats
#elif ENABLED(HANGPRINTER)
dummy = 0.0f;
_FIELD_TEST(anchor_A_y);
EEPROM_WRITE(anchor_A_y); // 1 float
EEPROM_WRITE(anchor_A_z); // 1 float
EEPROM_WRITE(anchor_B_x); // 1 float
EEPROM_WRITE(anchor_B_y); // 1 float
EEPROM_WRITE(anchor_B_z); // 1 float
EEPROM_WRITE(anchor_C_x); // 1 float
EEPROM_WRITE(anchor_C_y); // 1 float
EEPROM_WRITE(anchor_C_z); // 1 float
EEPROM_WRITE(anchor_D_z); // 1 float
EEPROM_WRITE(delta_segments_per_second); // 1 float
EEPROM_WRITE(dummy); // 1 float
#elif ENABLED(X_DUAL_ENDSTOPS) || ENABLED(Y_DUAL_ENDSTOPS) || ENABLED(Z_DUAL_ENDSTOPS)
_FIELD_TEST(x_endstop_adj);
@@ -696,57 +738,57 @@ void MarlinSettings::postprocess() {
uint16_t tmc_stepper_current[TMC_AXES] = {
#if HAS_TRINAMIC
#if X_IS_TRINAMIC
#if AXIS_IS_TMC(X)
stepperX.getCurrent(),
#else
0,
#endif
#if Y_IS_TRINAMIC
#if AXIS_IS_TMC(Y)
stepperY.getCurrent(),
#else
0,
#endif
#if Z_IS_TRINAMIC
#if AXIS_IS_TMC(Z)
stepperZ.getCurrent(),
#else
0,
#endif
#if X2_IS_TRINAMIC
#if AXIS_IS_TMC(X2)
stepperX2.getCurrent(),
#else
0,
#endif
#if Y2_IS_TRINAMIC
#if AXIS_IS_TMC(Y2)
stepperY2.getCurrent(),
#else
0,
#endif
#if Z2_IS_TRINAMIC
#if AXIS_IS_TMC(Z2)
stepperZ2.getCurrent(),
#else
0,
#endif
#if E0_IS_TRINAMIC
#if AXIS_IS_TMC(E0)
stepperE0.getCurrent(),
#else
0,
#endif
#if E1_IS_TRINAMIC
#if AXIS_IS_TMC(E1)
stepperE1.getCurrent(),
#else
0,
#endif
#if E2_IS_TRINAMIC
#if AXIS_IS_TMC(E2)
stepperE2.getCurrent(),
#else
0,
#endif
#if E3_IS_TRINAMIC
#if AXIS_IS_TMC(E3)
stepperE3.getCurrent(),
#else
0,
#endif
#if E4_IS_TRINAMIC
#if AXIS_IS_TMC(E4)
stepperE4.getCurrent()
#else
0
@@ -765,57 +807,57 @@ void MarlinSettings::postprocess() {
uint32_t tmc_hybrid_threshold[TMC_AXES] = {
#if ENABLED(HYBRID_THRESHOLD)
#if X_IS_TRINAMIC
#if AXIS_HAS_STEALTHCHOP(X)
TMC_GET_PWMTHRS(X, X),
#else
X_HYBRID_THRESHOLD,
#endif
#if Y_IS_TRINAMIC
#if AXIS_HAS_STEALTHCHOP(Y)
TMC_GET_PWMTHRS(Y, Y),
#else
Y_HYBRID_THRESHOLD,
#endif
#if Z_IS_TRINAMIC
#if AXIS_HAS_STEALTHCHOP(Z)
TMC_GET_PWMTHRS(Z, Z),
#else
Z_HYBRID_THRESHOLD,
#endif
#if X2_IS_TRINAMIC
#if AXIS_HAS_STEALTHCHOP(X2)
TMC_GET_PWMTHRS(X, X2),
#else
X2_HYBRID_THRESHOLD,
#endif
#if Y2_IS_TRINAMIC
#if AXIS_HAS_STEALTHCHOP(Y2)
TMC_GET_PWMTHRS(Y, Y2),
#else
Y2_HYBRID_THRESHOLD,
#endif
#if Z2_IS_TRINAMIC
#if AXIS_HAS_STEALTHCHOP(Z2)
TMC_GET_PWMTHRS(Z, Z2),
#else
Z2_HYBRID_THRESHOLD,
#endif
#if E0_IS_TRINAMIC
#if AXIS_HAS_STEALTHCHOP(E0)
TMC_GET_PWMTHRS(E, E0),
#else
E0_HYBRID_THRESHOLD,
#endif
#if E1_IS_TRINAMIC
#if AXIS_HAS_STEALTHCHOP(E1)
TMC_GET_PWMTHRS(E, E1),
#else
E1_HYBRID_THRESHOLD,
#endif
#if E2_IS_TRINAMIC
#if AXIS_HAS_STEALTHCHOP(E2)
TMC_GET_PWMTHRS(E, E2),
#else
E2_HYBRID_THRESHOLD,
#endif
#if E3_IS_TRINAMIC
#if AXIS_HAS_STEALTHCHOP(E3)
TMC_GET_PWMTHRS(E, E3),
#else
E3_HYBRID_THRESHOLD,
#endif
#if E4_IS_TRINAMIC
#if AXIS_HAS_STEALTHCHOP(E4)
TMC_GET_PWMTHRS(E, E4)
#else
E4_HYBRID_THRESHOLD
@@ -833,17 +875,17 @@ void MarlinSettings::postprocess() {
//
int16_t tmc_sgt[XYZ] = {
#if ENABLED(SENSORLESS_HOMING)
#if defined(X_HOMING_SENSITIVITY) && (ENABLED(X_IS_TMC2130) || ENABLED(IS_TRAMS))
#if X_SENSORLESS
stepperX.sgt(),
#else
0,
#endif
#if defined(Y_HOMING_SENSITIVITY) && (ENABLED(Y_IS_TMC2130) || ENABLED(IS_TRAMS))
#if Y_SENSORLESS
stepperY.sgt(),
#else
0,
#endif
#if defined(Z_HOMING_SENSITIVITY) && (ENABLED(Z_IS_TMC2130) || ENABLED(IS_TRAMS))
#if Z_SENSORLESS
stepperZ.sgt()
#else
0
@@ -1010,17 +1052,17 @@ void MarlinSettings::postprocess() {
const uint32_t def1[] = DEFAULT_MAX_ACCELERATION;
const float def2[] = DEFAULT_AXIS_STEPS_PER_UNIT, def3[] = DEFAULT_MAX_FEEDRATE;
uint32_t tmp1[XYZ + esteppers];
uint32_t tmp1[MOV_AXIS + esteppers];
EEPROM_READ(tmp1); // max_acceleration_mm_per_s2
EEPROM_READ(planner.min_segment_time_us);
float tmp2[XYZ + esteppers], tmp3[XYZ + esteppers];
float tmp2[MOV_AXIS + esteppers], tmp3[MOV_AXIS + esteppers];
EEPROM_READ(tmp2); // axis_steps_per_mm
EEPROM_READ(tmp3); // max_feedrate_mm_s
if (!validating) LOOP_XYZE_N(i) {
planner.max_acceleration_mm_per_s2[i] = i < XYZ + esteppers ? tmp1[i] : def1[i < COUNT(def1) ? i : COUNT(def1) - 1];
planner.axis_steps_per_mm[i] = i < XYZ + esteppers ? tmp2[i] : def2[i < COUNT(def2) ? i : COUNT(def2) - 1];
planner.max_feedrate_mm_s[i] = i < XYZ + esteppers ? tmp3[i] : def3[i < COUNT(def3) ? i : COUNT(def3) - 1];
if (!validating) LOOP_NUM_AXIS_N(i) {
planner.max_acceleration_mm_per_s2[i] = i < MOV_AXIS + esteppers ? tmp1[i] : def1[i < COUNT(def1) ? i : COUNT(def1) - 1];
planner.axis_steps_per_mm[i] = i < MOV_AXIS + esteppers ? tmp2[i] : def2[i < COUNT(def2) ? i : COUNT(def2) - 1];
planner.max_feedrate_mm_s[i] = i < MOV_AXIS + esteppers ? tmp3[i] : def3[i < COUNT(def3) ? i : COUNT(def3) - 1];
}
EEPROM_READ(planner.acceleration);
@@ -1165,6 +1207,19 @@ void MarlinSettings::postprocess() {
EEPROM_READ(delta_calibration_radius); // 1 float
EEPROM_READ(delta_tower_angle_trim); // 3 floats
#elif ENABLED(HANGPRINTER)
EEPROM_READ(anchor_A_y); // 1 float
EEPROM_READ(anchor_A_z); // 1 float
EEPROM_READ(anchor_B_x); // 1 float
EEPROM_READ(anchor_B_y); // 1 float
EEPROM_READ(anchor_B_z); // 1 float
EEPROM_READ(anchor_C_x); // 1 float
EEPROM_READ(anchor_C_y); // 1 float
EEPROM_READ(anchor_C_z); // 1 float
EEPROM_READ(anchor_D_z); // 1 float
EEPROM_READ(delta_segments_per_second); // 1 float
EEPROM_READ(dummy); // 1 float
#elif ENABLED(X_DUAL_ENDSTOPS) || ENABLED(Y_DUAL_ENDSTOPS) || ENABLED(Z_DUAL_ENDSTOPS)
_FIELD_TEST(x_endstop_adj);
@@ -1325,37 +1380,37 @@ void MarlinSettings::postprocess() {
uint16_t currents[TMC_AXES];
EEPROM_READ(currents);
if (!validating) {
#if X_IS_TRINAMIC
#if AXIS_IS_TMC(X)
SET_CURR(X);
#endif
#if Y_IS_TRINAMIC
#if AXIS_IS_TMC(Y)
SET_CURR(Y);
#endif
#if Z_IS_TRINAMIC
#if AXIS_IS_TMC(Z)
SET_CURR(Z);
#endif
#if X2_IS_TRINAMIC
#if AXIS_IS_TMC(X2)
SET_CURR(X2);
#endif
#if Y2_IS_TRINAMIC
#if AXIS_IS_TMC(Y2)
SET_CURR(Y2);
#endif
#if Z2_IS_TRINAMIC
#if AXIS_IS_TMC(Z2)
SET_CURR(Z2);
#endif
#if E0_IS_TRINAMIC
#if AXIS_IS_TMC(E0)
SET_CURR(E0);
#endif
#if E1_IS_TRINAMIC
#if AXIS_IS_TMC(E1)
SET_CURR(E1);
#endif
#if E2_IS_TRINAMIC
#if AXIS_IS_TMC(E2)
SET_CURR(E2);
#endif
#if E3_IS_TRINAMIC
#if AXIS_IS_TMC(E3)
SET_CURR(E3);
#endif
#if E4_IS_TRINAMIC
#if AXIS_IS_TMC(E4)
SET_CURR(E4);
#endif
}
@@ -1369,37 +1424,37 @@ void MarlinSettings::postprocess() {
uint32_t tmc_hybrid_threshold[TMC_AXES];
EEPROM_READ(tmc_hybrid_threshold);
if (!validating) {
#if X_IS_TRINAMIC
#if AXIS_HAS_STEALTHCHOP(X)
TMC_SET_PWMTHRS(X, X);
#endif
#if Y_IS_TRINAMIC
#if AXIS_HAS_STEALTHCHOP(Y)
TMC_SET_PWMTHRS(Y, Y);
#endif
#if Z_IS_TRINAMIC
#if AXIS_HAS_STEALTHCHOP(Z)
TMC_SET_PWMTHRS(Z, Z);
#endif
#if X2_IS_TRINAMIC
#if AXIS_HAS_STEALTHCHOP(X2)
TMC_SET_PWMTHRS(X, X2);
#endif
#if Y2_IS_TRINAMIC
#if AXIS_HAS_STEALTHCHOP(Y2)
TMC_SET_PWMTHRS(Y, Y2);
#endif
#if Z2_IS_TRINAMIC
#if AXIS_HAS_STEALTHCHOP(Z2)
TMC_SET_PWMTHRS(Z, Z2);
#endif
#if E0_IS_TRINAMIC
#if AXIS_HAS_STEALTHCHOP(E0)
TMC_SET_PWMTHRS(E, E0);
#endif
#if E1_IS_TRINAMIC
#if AXIS_HAS_STEALTHCHOP(E1)
TMC_SET_PWMTHRS(E, E1);
#endif
#if E2_IS_TRINAMIC
#if AXIS_HAS_STEALTHCHOP(E2)
TMC_SET_PWMTHRS(E, E2);
#endif
#if E3_IS_TRINAMIC
#if AXIS_HAS_STEALTHCHOP(E3)
TMC_SET_PWMTHRS(E, E3);
#endif
#if E4_IS_TRINAMIC
#if AXIS_HAS_STEALTHCHOP(E4)
TMC_SET_PWMTHRS(E, E4);
#endif
}
@@ -1419,26 +1474,26 @@ void MarlinSettings::postprocess() {
#if ENABLED(SENSORLESS_HOMING)
if (!validating) {
#ifdef X_HOMING_SENSITIVITY
#if ENABLED(X_IS_TMC2130) || ENABLED(IS_TRAMS)
#if AXIS_HAS_STALLGUARD(X)
stepperX.sgt(tmc_sgt[0]);
#endif
#if ENABLED(X2_IS_TMC2130)
#if AXIS_HAS_STALLGUARD(X2)
stepperX2.sgt(tmc_sgt[0]);
#endif
#endif
#ifdef Y_HOMING_SENSITIVITY
#if ENABLED(Y_IS_TMC2130) || ENABLED(IS_TRAMS)
#if AXIS_HAS_STALLGUARD(Y)
stepperY.sgt(tmc_sgt[1]);
#endif
#if ENABLED(Y2_IS_TMC2130)
#if AXIS_HAS_STALLGUARD(Y2)
stepperY2.sgt(tmc_sgt[1]);
#endif
#endif
#ifdef Z_HOMING_SENSITIVITY
#if ENABLED(Z_IS_TMC2130) || ENABLED(IS_TRAMS)
#if AXIS_HAS_STALLGUARD(Z)
stepperZ.sgt(tmc_sgt[2]);
#endif
#if ENABLED(Z2_IS_TMC2130)
#if AXIS_HAS_STALLGUARD(Z2)
stepperZ2.sgt(tmc_sgt[2]);
#endif
#endif
@@ -1714,8 +1769,9 @@ void MarlinSettings::postprocess() {
*/
void MarlinSettings::reset() {
static const float tmp1[] PROGMEM = DEFAULT_AXIS_STEPS_PER_UNIT, tmp2[] PROGMEM = DEFAULT_MAX_FEEDRATE;
static const uint32_t tmp3[] PROGMEM = DEFAULT_MAX_ACCELERATION;
LOOP_XYZE_N(i) {
LOOP_NUM_AXIS_N(i) {
planner.axis_steps_per_mm[i] = pgm_read_float(&tmp1[i < COUNT(tmp1) ? i : COUNT(tmp1) - 1]);
planner.max_feedrate_mm_s[i] = pgm_read_float(&tmp2[i < COUNT(tmp2) ? i : COUNT(tmp2) - 1]);
planner.max_acceleration_mm_per_s2[i] = pgm_read_dword_near(&tmp3[i < COUNT(tmp3) ? i : COUNT(tmp3) - 1]);
@@ -1731,9 +1787,16 @@ void MarlinSettings::reset() {
#if ENABLED(JUNCTION_DEVIATION)
planner.junction_deviation_mm = float(JUNCTION_DEVIATION_MM);
#else
planner.max_jerk[X_AXIS] = DEFAULT_XJERK;
planner.max_jerk[Y_AXIS] = DEFAULT_YJERK;
planner.max_jerk[Z_AXIS] = DEFAULT_ZJERK;
#if ENABLED(HANGPRINTER)
planner.max_jerk[A_AXIS] = DEFAULT_AJERK;
planner.max_jerk[B_AXIS] = DEFAULT_BJERK;
planner.max_jerk[C_AXIS] = DEFAULT_CJERK;
planner.max_jerk[D_AXIS] = DEFAULT_DJERK;
#else
planner.max_jerk[X_AXIS] = DEFAULT_XJERK;
planner.max_jerk[Y_AXIS] = DEFAULT_YJERK;
planner.max_jerk[Z_AXIS] = DEFAULT_ZJERK;
#endif
planner.max_jerk[E_AXIS] = DEFAULT_EJERK;
#endif
@@ -1785,6 +1848,19 @@ void MarlinSettings::reset() {
delta_calibration_radius = DELTA_CALIBRATION_RADIUS;
COPY(delta_tower_angle_trim, dta);
#elif ENABLED(HANGPRINTER)
anchor_A_y = float(ANCHOR_A_Y);
anchor_A_z = float(ANCHOR_A_Z);
anchor_B_x = float(ANCHOR_B_X);
anchor_B_y = float(ANCHOR_B_Y);
anchor_B_z = float(ANCHOR_B_Z);
anchor_C_x = float(ANCHOR_C_X);
anchor_C_y = float(ANCHOR_C_Y);
anchor_C_z = float(ANCHOR_C_Z);
anchor_D_z = float(ANCHOR_D_Z);
delta_segments_per_second = KINEMATIC_SEGMENTS_PER_SECOND;
#elif ENABLED(X_DUAL_ENDSTOPS) || ENABLED(Y_DUAL_ENDSTOPS) || ENABLED(Z_DUAL_ENDSTOPS)
#if ENABLED(X_DUAL_ENDSTOPS)
@@ -1814,7 +1890,6 @@ void MarlinSettings::reset() {
#endif
);
#endif
#endif
#if ENABLED(ULTIPANEL)
@@ -2038,9 +2113,16 @@ void MarlinSettings::reset() {
SERIAL_ECHOLNPGM("Steps per unit:");
}
CONFIG_ECHO_START;
SERIAL_ECHOPAIR(" M92 X", LINEAR_UNIT(planner.axis_steps_per_mm[X_AXIS]));
SERIAL_ECHOPAIR(" Y", LINEAR_UNIT(planner.axis_steps_per_mm[Y_AXIS]));
SERIAL_ECHOPAIR(" Z", LINEAR_UNIT(planner.axis_steps_per_mm[Z_AXIS]));
#if ENABLED(HANGPRINTER)
SERIAL_ECHOPAIR(" M92 A", LINEAR_UNIT(planner.axis_steps_per_mm[A_AXIS]));
SERIAL_ECHOPAIR(" B", LINEAR_UNIT(planner.axis_steps_per_mm[B_AXIS]));
SERIAL_ECHOPAIR(" C", LINEAR_UNIT(planner.axis_steps_per_mm[C_AXIS]));
SERIAL_ECHOPAIR(" D", LINEAR_UNIT(planner.axis_steps_per_mm[D_AXIS]));
#else
SERIAL_ECHOPAIR(" M92 X", LINEAR_UNIT(planner.axis_steps_per_mm[X_AXIS]));
SERIAL_ECHOPAIR(" Y", LINEAR_UNIT(planner.axis_steps_per_mm[Y_AXIS]));
SERIAL_ECHOPAIR(" Z", LINEAR_UNIT(planner.axis_steps_per_mm[Z_AXIS]));
#endif
#if DISABLED(DISTINCT_E_FACTORS)
SERIAL_ECHOPAIR(" E", VOLUMETRIC_UNIT(planner.axis_steps_per_mm[E_AXIS]));
#endif
@@ -2058,9 +2140,16 @@ void MarlinSettings::reset() {
SERIAL_ECHOLNPGM("Maximum feedrates (units/s):");
}
CONFIG_ECHO_START;
SERIAL_ECHOPAIR(" M203 X", LINEAR_UNIT(planner.max_feedrate_mm_s[X_AXIS]));
SERIAL_ECHOPAIR(" Y", LINEAR_UNIT(planner.max_feedrate_mm_s[Y_AXIS]));
SERIAL_ECHOPAIR(" Z", LINEAR_UNIT(planner.max_feedrate_mm_s[Z_AXIS]));
#if ENABLED(HANGPRINTER)
SERIAL_ECHOPAIR(" M203 A", LINEAR_UNIT(planner.max_feedrate_mm_s[A_AXIS]));
SERIAL_ECHOPAIR(" B", LINEAR_UNIT(planner.max_feedrate_mm_s[B_AXIS]));
SERIAL_ECHOPAIR(" C", LINEAR_UNIT(planner.max_feedrate_mm_s[C_AXIS]));
SERIAL_ECHOPAIR(" D", LINEAR_UNIT(planner.max_feedrate_mm_s[D_AXIS]));
#else
SERIAL_ECHOPAIR(" M203 X", LINEAR_UNIT(planner.max_feedrate_mm_s[X_AXIS]));
SERIAL_ECHOPAIR(" Y", LINEAR_UNIT(planner.max_feedrate_mm_s[Y_AXIS]));
SERIAL_ECHOPAIR(" Z", LINEAR_UNIT(planner.max_feedrate_mm_s[Z_AXIS]));
#endif
#if DISABLED(DISTINCT_E_FACTORS)
SERIAL_ECHOPAIR(" E", VOLUMETRIC_UNIT(planner.max_feedrate_mm_s[E_AXIS]));
#endif
@@ -2078,9 +2167,16 @@ void MarlinSettings::reset() {
SERIAL_ECHOLNPGM("Maximum Acceleration (units/s2):");
}
CONFIG_ECHO_START;
SERIAL_ECHOPAIR(" M201 X", LINEAR_UNIT(planner.max_acceleration_mm_per_s2[X_AXIS]));
SERIAL_ECHOPAIR(" Y", LINEAR_UNIT(planner.max_acceleration_mm_per_s2[Y_AXIS]));
SERIAL_ECHOPAIR(" Z", LINEAR_UNIT(planner.max_acceleration_mm_per_s2[Z_AXIS]));
#if ENABLED(HANGPRINTER)
SERIAL_ECHOPAIR(" M201 A", LINEAR_UNIT(planner.max_acceleration_mm_per_s2[A_AXIS]));
SERIAL_ECHOPAIR(" B", LINEAR_UNIT(planner.max_acceleration_mm_per_s2[B_AXIS]));
SERIAL_ECHOPAIR(" C", LINEAR_UNIT(planner.max_acceleration_mm_per_s2[C_AXIS]));
SERIAL_ECHOPAIR(" D", LINEAR_UNIT(planner.max_acceleration_mm_per_s2[D_AXIS]));
#else
SERIAL_ECHOPAIR(" M201 X", LINEAR_UNIT(planner.max_acceleration_mm_per_s2[X_AXIS]));
SERIAL_ECHOPAIR(" Y", LINEAR_UNIT(planner.max_acceleration_mm_per_s2[Y_AXIS]));
SERIAL_ECHOPAIR(" Z", LINEAR_UNIT(planner.max_acceleration_mm_per_s2[Z_AXIS]));
#endif
#if DISABLED(DISTINCT_E_FACTORS)
SERIAL_ECHOPAIR(" E", VOLUMETRIC_UNIT(planner.max_acceleration_mm_per_s2[E_AXIS]));
#endif
@@ -2104,11 +2200,15 @@ void MarlinSettings::reset() {
if (!forReplay) {
CONFIG_ECHO_START;
SERIAL_ECHOPGM("Advanced: B<min_segment_time_us> S<min_feedrate> T<min_travel_feedrate>");
SERIAL_ECHOPGM("Advanced: Q<min_segment_time_us> S<min_feedrate> T<min_travel_feedrate>");
#if ENABLED(JUNCTION_DEVIATION)
SERIAL_ECHOPGM(" J<junc_dev>");
#else
SERIAL_ECHOPGM(" X<max_x_jerk> Y<max_y_jerk> Z<max_z_jerk>");
#if ENABLED(HANGPRINTER)
SERIAL_ECHOPGM(" A<max_a_jerk> B<max_b_jerk> C<max_c_jerk> D<max_d_jerk>");
#else
SERIAL_ECHOPGM(" X<max_x_jerk> Y<max_y_jerk> Z<max_z_jerk>");
#endif
#endif
#if DISABLED(JUNCTION_DEVIATION) || ENABLED(LIN_ADVANCE)
SERIAL_ECHOPGM(" E<max_e_jerk>");
@@ -2116,19 +2216,25 @@ void MarlinSettings::reset() {
SERIAL_EOL();
}
CONFIG_ECHO_START;
SERIAL_ECHOPAIR(" M205 B", LINEAR_UNIT(planner.min_segment_time_us));
SERIAL_ECHOPAIR(" M205 Q", LINEAR_UNIT(planner.min_segment_time_us));
SERIAL_ECHOPAIR(" S", LINEAR_UNIT(planner.min_feedrate_mm_s));
SERIAL_ECHOPAIR(" T", LINEAR_UNIT(planner.min_travel_feedrate_mm_s));
#if ENABLED(JUNCTION_DEVIATION)
SERIAL_ECHOPAIR(" J", LINEAR_UNIT(planner.junction_deviation_mm));
#else
SERIAL_ECHOPAIR(" X", LINEAR_UNIT(planner.max_jerk[X_AXIS]));
SERIAL_ECHOPAIR(" Y", LINEAR_UNIT(planner.max_jerk[Y_AXIS]));
SERIAL_ECHOPAIR(" Z", LINEAR_UNIT(planner.max_jerk[Z_AXIS]));
#if ENABLED(HANGPRINTER)
SERIAL_ECHOPAIR(" A", LINEAR_UNIT(planner.max_jerk[A_AXIS]));
SERIAL_ECHOPAIR(" B", LINEAR_UNIT(planner.max_jerk[B_AXIS]));
SERIAL_ECHOPAIR(" C", LINEAR_UNIT(planner.max_jerk[C_AXIS]));
SERIAL_ECHOPAIR(" D", LINEAR_UNIT(planner.max_jerk[D_AXIS]));
#else
SERIAL_ECHOPAIR(" X", LINEAR_UNIT(planner.max_jerk[X_AXIS]));
SERIAL_ECHOPAIR(" Y", LINEAR_UNIT(planner.max_jerk[Y_AXIS]));
SERIAL_ECHOPAIR(" Z", LINEAR_UNIT(planner.max_jerk[Z_AXIS]));
#endif
SERIAL_ECHOPAIR(" E", LINEAR_UNIT(planner.max_jerk[E_AXIS]));
#endif
SERIAL_EOL();
#if HAS_M206_COMMAND
@@ -2220,8 +2326,8 @@ void MarlinSettings::reset() {
SERIAL_ECHOLNPGM(" meshes.\n");
}
ubl.report_current_mesh();
//ubl.report_current_mesh(PORTVAR_SOLO); // This is too verbose for large mesh's. A better (more terse)
// solution needs to be found.
#elif ENABLED(AUTO_BED_LEVELING_BILINEAR)
if (leveling_is_valid()) {
@@ -2266,6 +2372,24 @@ void MarlinSettings::reset() {
SERIAL_ECHOPAIR(" Z", LINEAR_UNIT(delta_tower_angle_trim[C_AXIS]));
SERIAL_EOL();
#elif ENABLED(HANGPRINTER)
if (!forReplay) {
CONFIG_ECHO_START;
SERIAL_ECHOLNPGM("Hangprinter settings: W<Ay> E<Az> R<Bx> T<By> Y<Bz> U<Cx> I<Cy> O<Cz> P<Dz> S<segments_per_s>");
}
CONFIG_ECHO_START;
SERIAL_ECHOPAIR(" M665 W", anchor_A_y);
SERIAL_ECHOPAIR(" E", anchor_A_z);
SERIAL_ECHOPAIR(" R", anchor_B_x);
SERIAL_ECHOPAIR(" T", anchor_B_y);
SERIAL_ECHOPAIR(" Y", anchor_B_z);
SERIAL_ECHOPAIR(" U", anchor_C_x);
SERIAL_ECHOPAIR(" I", anchor_C_y);
SERIAL_ECHOPAIR(" O", anchor_C_z);
SERIAL_ECHOPAIR(" P", anchor_D_z);
SERIAL_ECHOPAIR(" S", delta_segments_per_second);
SERIAL_EOL();
#elif ENABLED(X_DUAL_ENDSTOPS) || ENABLED(Y_DUAL_ENDSTOPS) || ENABLED(Z_DUAL_ENDSTOPS)
if (!forReplay) {
@@ -2428,61 +2552,61 @@ void MarlinSettings::reset() {
#if HAS_TRINAMIC
/**
* TMC2130 / TMC2208 / TRAMS stepper driver current
* TMC2130 / TMC2208 stepper driver current
*/
if (!forReplay) {
CONFIG_ECHO_START;
SERIAL_ECHOLNPGM("Stepper driver current:");
}
CONFIG_ECHO_START;
#if X_IS_TRINAMIC || Y_IS_TRINAMIC || Z_IS_TRINAMIC
#if AXIS_IS_TMC(X) || AXIS_IS_TMC(Y) || AXIS_IS_TMC(Z)
say_M906();
#endif
#if X_IS_TRINAMIC
#if AXIS_IS_TMC(X)
SERIAL_ECHOPAIR(" X", stepperX.getCurrent());
#endif
#if Y_IS_TRINAMIC
#if AXIS_IS_TMC(Y)
SERIAL_ECHOPAIR(" Y", stepperY.getCurrent());
#endif
#if Z_IS_TRINAMIC
#if AXIS_IS_TMC(Z)
SERIAL_ECHOPAIR(" Z", stepperZ.getCurrent());
#endif
#if X_IS_TRINAMIC || Y_IS_TRINAMIC || Z_IS_TRINAMIC
#if AXIS_IS_TMC(X) || AXIS_IS_TMC(Y) || AXIS_IS_TMC(Z)
SERIAL_EOL();
#endif
#if X2_IS_TRINAMIC || Y2_IS_TRINAMIC || Z2_IS_TRINAMIC
#if AXIS_IS_TMC(X2) || AXIS_IS_TMC(Y2) || AXIS_IS_TMC(Z2)
say_M906();
SERIAL_ECHOPGM(" I1");
#endif
#if X2_IS_TRINAMIC
#if AXIS_IS_TMC(X2)
SERIAL_ECHOPAIR(" X", stepperX2.getCurrent());
#endif
#if Y2_IS_TRINAMIC
#if AXIS_IS_TMC(Y2)
SERIAL_ECHOPAIR(" Y", stepperY2.getCurrent());
#endif
#if Z2_IS_TRINAMIC
#if AXIS_IS_TMC(Z2)
SERIAL_ECHOPAIR(" Z", stepperZ2.getCurrent());
#endif
#if X2_IS_TRINAMIC || Y2_IS_TRINAMIC || Z2_IS_TRINAMIC
#if AXIS_IS_TMC(X2) || AXIS_IS_TMC(Y2) || AXIS_IS_TMC(Z2)
SERIAL_EOL();
#endif
#if E0_IS_TRINAMIC
#if AXIS_IS_TMC(E0)
say_M906();
SERIAL_ECHOLNPAIR(" T0 E", stepperE0.getCurrent());
#endif
#if E_STEPPERS > 1 && E1_IS_TRINAMIC
#if E_STEPPERS > 1 && AXIS_IS_TMC(E1)
say_M906();
SERIAL_ECHOLNPAIR(" T1 E", stepperE1.getCurrent());
#endif
#if E_STEPPERS > 2 && E2_IS_TRINAMIC
#if E_STEPPERS > 2 && AXIS_IS_TMC(E2)
say_M906();
SERIAL_ECHOLNPAIR(" T2 E", stepperE2.getCurrent());
#endif
#if E_STEPPERS > 3 && E3_IS_TRINAMIC
#if E_STEPPERS > 3 && AXIS_IS_TMC(E3)
say_M906();
SERIAL_ECHOLNPAIR(" T3 E", stepperE3.getCurrent());
#endif
#if E_STEPPERS > 4 && E4_IS_TRINAMIC
#if E_STEPPERS > 4 && AXIS_IS_TMC(E4)
say_M906();
SERIAL_ECHOLNPAIR(" T4 E", stepperE4.getCurrent());
#endif
@@ -2497,54 +2621,54 @@ void MarlinSettings::reset() {
SERIAL_ECHOLNPGM("Hybrid Threshold:");
}
CONFIG_ECHO_START;
#if X_IS_TRINAMIC || Y_IS_TRINAMIC || Z_IS_TRINAMIC
#if AXIS_IS_TMC(X) || AXIS_IS_TMC(Y) || AXIS_IS_TMC(Z)
say_M913();
#endif
#if X_IS_TRINAMIC
#if AXIS_IS_TMC(X)
SERIAL_ECHOPAIR(" X", TMC_GET_PWMTHRS(X, X));
#endif
#if Y_IS_TRINAMIC
#if AXIS_IS_TMC(Y)
SERIAL_ECHOPAIR(" Y", TMC_GET_PWMTHRS(Y, Y));
#endif
#if Z_IS_TRINAMIC
#if AXIS_IS_TMC(Z)
SERIAL_ECHOPAIR(" Z", TMC_GET_PWMTHRS(Z, Z));
#endif
#if X_IS_TRINAMIC || Y_IS_TRINAMIC || Z_IS_TRINAMIC
#if AXIS_IS_TMC(X) || AXIS_IS_TMC(Y) || AXIS_IS_TMC(Z)
SERIAL_EOL();
#endif
#if X2_IS_TRINAMIC || Y2_IS_TRINAMIC || Z2_IS_TRINAMIC
#if AXIS_IS_TMC(X2) || AXIS_IS_TMC(Y2) || AXIS_IS_TMC(Z2)
say_M913();
SERIAL_ECHOPGM(" I1");
#endif
#if X2_IS_TRINAMIC
#if AXIS_IS_TMC(X2)
SERIAL_ECHOPAIR(" X", TMC_GET_PWMTHRS(X, X2));
#endif
#if Y2_IS_TRINAMIC
#if AXIS_IS_TMC(Y2)
SERIAL_ECHOPAIR(" Y", TMC_GET_PWMTHRS(Y, Y2));
#endif
#if Z2_IS_TRINAMIC
#if AXIS_IS_TMC(Z2)
SERIAL_ECHOPAIR(" Z", TMC_GET_PWMTHRS(Z, Z2));
#endif
#if X2_IS_TRINAMIC || Y2_IS_TRINAMIC || Z2_IS_TRINAMIC
#if AXIS_IS_TMC(X2) || AXIS_IS_TMC(Y2) || AXIS_IS_TMC(Z2)
SERIAL_EOL();
#endif
#if E0_IS_TRINAMIC
#if AXIS_IS_TMC(E0)
say_M913();
SERIAL_ECHOLNPAIR(" T0 E", TMC_GET_PWMTHRS(E, E0));
#endif
#if E_STEPPERS > 1 && E1_IS_TRINAMIC
#if E_STEPPERS > 1 && AXIS_IS_TMC(E1)
say_M913();
SERIAL_ECHOLNPAIR(" T1 E", TMC_GET_PWMTHRS(E, E1));
#endif
#if E_STEPPERS > 2 && E2_IS_TRINAMIC
#if E_STEPPERS > 2 && AXIS_IS_TMC(E2)
say_M913();
SERIAL_ECHOLNPAIR(" T2 E", TMC_GET_PWMTHRS(E, E2));
#endif
#if E_STEPPERS > 3 && E3_IS_TRINAMIC
#if E_STEPPERS > 3 && AXIS_IS_TMC(E3)
say_M913();
SERIAL_ECHOLNPAIR(" T3 E", TMC_GET_PWMTHRS(E, E3));
#endif
#if E_STEPPERS > 4 && E4_IS_TRINAMIC
#if E_STEPPERS > 4 && AXIS_IS_TMC(E4)
say_M913();
SERIAL_ECHOLNPAIR(" T4 E", TMC_GET_PWMTHRS(E, E4));
#endif
@@ -2560,36 +2684,33 @@ void MarlinSettings::reset() {
SERIAL_ECHOLNPGM("Sensorless homing threshold:");
}
CONFIG_ECHO_START;
#define HAS_X_SENSORLESS (defined(X_HOMING_SENSITIVITY) && (ENABLED(X_IS_TMC2130) || ENABLED(IS_TRAMS)))
#define HAS_Y_SENSORLESS (defined(Y_HOMING_SENSITIVITY) && (ENABLED(Y_IS_TMC2130) || ENABLED(IS_TRAMS)))
#define HAS_Z_SENSORLESS (defined(Z_HOMING_SENSITIVITY) && (ENABLED(Z_IS_TMC2130) || ENABLED(IS_TRAMS)))
#if HAS_X_SENSORLESS || HAS_Y_SENSORLESS || HAS_Z_SENSORLESS
#if X_SENSORLESS || Y_SENSORLESS || Z_SENSORLESS
say_M914();
#if HAS_X_SENSORLESS
#if X_SENSORLESS
SERIAL_ECHOPAIR(" X", stepperX.sgt());
#endif
#if HAS_Y_SENSORLESS
#if Y_SENSORLESS
SERIAL_ECHOPAIR(" Y", stepperY.sgt());
#endif
#if HAS_Z_SENSORLESS
#if Z_SENSORLESS
SERIAL_ECHOPAIR(" Z", stepperZ.sgt());
#endif
SERIAL_EOL();
#endif
#define HAS_X2_SENSORLESS (defined(X_HOMING_SENSITIVITY) && ENABLED(X2_IS_TMC2130))
#define HAS_Y2_SENSORLESS (defined(Y_HOMING_SENSITIVITY) && ENABLED(Y2_IS_TMC2130))
#define HAS_Z2_SENSORLESS (defined(Z_HOMING_SENSITIVITY) && ENABLED(Z2_IS_TMC2130))
#if HAS_X2_SENSORLESS || HAS_Y2_SENSORLESS || HAS_Z2_SENSORLESS
#define X2_SENSORLESS (defined(X_HOMING_SENSITIVITY) && AXIS_HAS_STALLGUARD(X2))
#define Y2_SENSORLESS (defined(Y_HOMING_SENSITIVITY) && AXIS_HAS_STALLGUARD(Y2))
#define Z2_SENSORLESS (defined(Z_HOMING_SENSITIVITY) && AXIS_HAS_STALLGUARD(Z2))
#if X2_SENSORLESS || Y2_SENSORLESS || Z2_SENSORLESS
say_M914();
SERIAL_ECHOPGM(" I1");
#if HAS_X2_SENSORLESS
#if X2_SENSORLESS
SERIAL_ECHOPAIR(" X", stepperX2.sgt());
#endif
#if HAS_Y2_SENSORLESS
#if Y2_SENSORLESS
SERIAL_ECHOPAIR(" Y", stepperY2.sgt());
#endif
#if HAS_Z2_SENSORLESS
#if Z2_SENSORLESS
SERIAL_ECHOPAIR(" Z", stepperZ2.sgt());
#endif
SERIAL_EOL();
+73
View File
@@ -0,0 +1,73 @@
/**
* Marlin 3D Printer Firmware
* Copyright (C) 2016 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 <http://www.gnu.org/licenses/>.
*
*/
#ifndef _DRIVERS_H_
#define _DRIVERS_H_
#include "MarlinConfig.h"
#define A4988 0x001
#define DRV8825 0x002
#define LV8729 0x003
#define L6470 0x104
#define TB6560 0x005
#define TB6600 0x006
#define TMC2100 0x007
#define TMC2130 0x108
#define TMC2130_STANDALONE 0x008
#define TMC2208 0x109
#define TMC2208_STANDALONE 0x009
#define TMC26X 0x10A
#define TMC26X_STANDALONE 0x00A
#define TMC2660 0x10B
#define TMC2660_STANDALONE 0x00B
#define _AXIS_DRIVER_TYPE(A,T) ( defined(A##_DRIVER_TYPE) && (A##_DRIVER_TYPE == T) )
#define AXIS_DRIVER_TYPE_X(T) _AXIS_DRIVER_TYPE(X,T)
#define AXIS_DRIVER_TYPE_Y(T) _AXIS_DRIVER_TYPE(Y,T)
#define AXIS_DRIVER_TYPE_Z(T) _AXIS_DRIVER_TYPE(Z,T)
#define AXIS_DRIVER_TYPE_X2(T) (ENABLED(X_DUAL_STEPPER_DRIVERS) || ENABLED(DUAL_X_CARRIAGE)) && _AXIS_DRIVER_TYPE(X2,T)
#define AXIS_DRIVER_TYPE_Y2(T) (ENABLED(Y_DUAL_STEPPER_DRIVERS) && _AXIS_DRIVER_TYPE(Y2,T))
#define AXIS_DRIVER_TYPE_Z2(T) (ENABLED(Z_DUAL_STEPPER_DRIVERS) && _AXIS_DRIVER_TYPE(Z2,T))
#define AXIS_DRIVER_TYPE_E0(T) (E_STEPPERS > 0 && _AXIS_DRIVER_TYPE(E0,T))
#define AXIS_DRIVER_TYPE_E1(T) (E_STEPPERS > 1 && _AXIS_DRIVER_TYPE(E1,T))
#define AXIS_DRIVER_TYPE_E2(T) (E_STEPPERS > 2 && _AXIS_DRIVER_TYPE(E2,T))
#define AXIS_DRIVER_TYPE_E3(T) (E_STEPPERS > 3 && _AXIS_DRIVER_TYPE(E3,T))
#define AXIS_DRIVER_TYPE_E4(T) (E_STEPPERS > 4 && _AXIS_DRIVER_TYPE(E4,T))
#define AXIS_DRIVER_TYPE(A,T) AXIS_DRIVER_TYPE_##A(T)
#define HAS_DRIVER(T) (AXIS_DRIVER_TYPE_X(T) || AXIS_DRIVER_TYPE_X2(T) || \
AXIS_DRIVER_TYPE_Y(T) || AXIS_DRIVER_TYPE_Y2(T) || \
AXIS_DRIVER_TYPE_Z(T) || AXIS_DRIVER_TYPE_Z2(T) || \
AXIS_DRIVER_TYPE_E0(T) || AXIS_DRIVER_TYPE_E1(T) || \
AXIS_DRIVER_TYPE_E2(T) || AXIS_DRIVER_TYPE_E3(T) || \
AXIS_DRIVER_TYPE_E4(T) )
// Test for supported TMC drivers that require advanced configuration
// Does not match standalone configurations
#define HAS_TRINAMIC (HAS_DRIVER(TMC2130) || HAS_DRIVER(TMC2208))
#define AXIS_IS_TMC(A) ( AXIS_DRIVER_TYPE_##A(TMC2130) || \
AXIS_DRIVER_TYPE_##A(TMC2208) )
#endif // _DRIVERS_H_
+48 -21
View File
@@ -189,7 +189,7 @@ void Endstops::init() {
} // Endstops::init
// Called from ISR: Poll endstop state if required
// Called at ~1KHz from Temperature ISR: Poll endstop state if required
void Endstops::poll() {
#if ENABLED(PINS_DEBUGGING)
@@ -229,11 +229,13 @@ void Endstops::not_homing() {
#endif
}
// If the last move failed to trigger an endstop, call kill
void Endstops::validate_homing_move() {
if (!trigger_state()) kill(PSTR(MSG_ERR_HOMING_FAILED));
hit_on_purpose();
}
#if ENABLED(VALIDATE_HOMING_ENDSTOPS)
// If the last move failed to trigger an endstop, call kill
void Endstops::validate_homing_move() {
if (trigger_state()) hit_on_purpose();
else kill(PSTR(MSG_ERR_HOMING_FAILED));
}
#endif
// Enable / disable endstop z-probe checking
#if HAS_BED_PROBE
@@ -256,8 +258,9 @@ void Endstops::validate_homing_move() {
}
#endif
void Endstops::report_state() {
if (hit_state) {
void Endstops::event_handler() {
static uint8_t prev_hit_state; // = 0
if (hit_state && hit_state != prev_hit_state) {
#if ENABLED(ULTRA_LCD)
char chrX = ' ', chrY = ' ', chrZ = ' ', chrP = ' ';
#define _SET_STOP_CHAR(A,C) (chr## A = C)
@@ -293,8 +296,6 @@ void Endstops::report_state() {
lcd_status_printf_P(0, PSTR(MSG_LCD_ENDSTOPS " %c %c %c %c"), chrX, chrY, chrZ, chrP);
#endif
hit_on_purpose();
#if ENABLED(ABORT_ON_ENDSTOP_HIT_FEATURE_ENABLED) && ENABLED(SDSUPPORT)
if (planner.abort_on_endstop_hit) {
card.sdprinting = false;
@@ -304,14 +305,19 @@ void Endstops::report_state() {
}
#endif
}
prev_hit_state = hit_state;
} // Endstops::report_state
void Endstops::M119() {
static void print_es_state(const bool is_hit, const char * const label=NULL) {
if (label) serialprintPGM(label);
SERIAL_PROTOCOLPGM(": ");
serialprintPGM(is_hit ? PSTR(MSG_ENDSTOP_HIT) : PSTR(MSG_ENDSTOP_OPEN));
SERIAL_EOL();
}
void _O2 Endstops::M119() {
SERIAL_PROTOCOLLNPGM(MSG_M119_REPORT);
#define ES_REPORT(AXIS) do{ \
SERIAL_PROTOCOLPGM(MSG_##AXIS); \
SERIAL_PROTOCOLLN(((READ(AXIS##_PIN)^AXIS##_ENDSTOP_INVERTING) ? MSG_ENDSTOP_HIT : MSG_ENDSTOP_OPEN)); \
}while(0)
#define ES_REPORT(S) print_es_state(READ(S##_PIN) != S##_ENDSTOP_INVERTING, PSTR(MSG_##S))
#if HAS_X_MIN
ES_REPORT(X_MIN);
#endif
@@ -349,12 +355,33 @@ void Endstops::M119() {
ES_REPORT(Z2_MAX);
#endif
#if ENABLED(Z_MIN_PROBE_ENDSTOP)
SERIAL_PROTOCOLPGM(MSG_Z_PROBE);
SERIAL_PROTOCOLLN(((READ(Z_MIN_PROBE_PIN)^Z_MIN_PROBE_ENDSTOP_INVERTING) ? MSG_ENDSTOP_HIT : MSG_ENDSTOP_OPEN));
print_es_state(READ(Z_MIN_PROBE_PIN) != Z_MIN_PROBE_ENDSTOP_INVERTING, PSTR(MSG_Z_PROBE));
#endif
#if ENABLED(FILAMENT_RUNOUT_SENSOR)
SERIAL_PROTOCOLPGM(MSG_FILAMENT_RUNOUT_SENSOR);
SERIAL_PROTOCOLLN(((READ(FIL_RUNOUT_PIN)^FIL_RUNOUT_INVERTING) ? MSG_ENDSTOP_HIT : MSG_ENDSTOP_OPEN));
#if NUM_RUNOUT_SENSORS == 1
print_es_state(READ(FIL_RUNOUT_PIN) != FIL_RUNOUT_INVERTING, PSTR(MSG_FILAMENT_RUNOUT_SENSOR));
#else
for (uint8_t i = 1; i <= NUM_RUNOUT_SENSORS; i++) {
pin_t pin;
switch (i) {
default: continue;
case 1: pin = FIL_RUNOUT_PIN; break;
case 2: pin = FIL_RUNOUT2_PIN; break;
#if NUM_RUNOUT_SENSORS > 2
case 3: pin = FIL_RUNOUT3_PIN; break;
#if NUM_RUNOUT_SENSORS > 3
case 4: pin = FIL_RUNOUT4_PIN; break;
#if NUM_RUNOUT_SENSORS > 4
case 5: pin = FIL_RUNOUT5_PIN; break;
#endif
#endif
#endif
}
SERIAL_PROTOCOLPGM(MSG_FILAMENT_RUNOUT_SENSOR);
if (i > 1) { SERIAL_CHAR(' '); SERIAL_CHAR('0' + i); }
print_es_state(digitalRead(pin) != FIL_RUNOUT_INVERTING);
}
#endif
#endif
} // Endstops::M119
@@ -365,7 +392,7 @@ void Endstops::M119() {
#define _ENDSTOP_PIN(AXIS, MINMAX) AXIS ##_## MINMAX ##_PIN
#define _ENDSTOP_INVERTING(AXIS, MINMAX) AXIS ##_## MINMAX ##_ENDSTOP_INVERTING
// Check endstops - Could be called from ISR!
// Check endstops - Could be called from Temperature ISR!
void Endstops::update() {
#if DISABLED(ENDSTOP_NOISE_FILTER)
@@ -540,7 +567,7 @@ void Endstops::update() {
if (dual_hit) { \
_ENDSTOP_HIT(AXIS1, MINMAX); \
/* if not performing home or if both endstops were trigged during homing... */ \
if (!stepper.homing_dual_axis || dual_hit == 0x3) \
if (!stepper.homing_dual_axis || dual_hit == 0b11) \
planner.endstop_triggered(_AXIS(AXIS1)); \
} \
}while(0)
+9 -3
View File
@@ -29,6 +29,8 @@
#include "MarlinConfig.h"
#define VALIDATE_HOMING_ENDSTOPS
enum EndstopEnum : char {
X_MIN,
Y_MIN,
@@ -127,7 +129,7 @@ class Endstops {
/**
* Report endstop hits to serial. Called from loop().
*/
static void report_state();
static void event_handler();
/**
* Report endstop positions in response to M119
@@ -143,8 +145,12 @@ class Endstops {
// Disable / Enable endstops based on ENSTOPS_ONLY_FOR_HOMING and global enable
static void not_homing();
// If the last move failed to trigger an endstop, call kill
static void validate_homing_move();
#if ENABLED(VALIDATE_HOMING_ENDSTOPS)
// If the last move failed to trigger an endstop, call kill
static void validate_homing_move();
#else
FORCE_INLINE static void validate_homing_move() { hit_on_purpose(); }
#endif
// Clear endstops (i.e., they were hit intentionally) to suppress the report
FORCE_INLINE static void hit_on_purpose() { hit_state = 0; }
+12 -8
View File
@@ -39,10 +39,14 @@ enum AxisEnum : unsigned char {
B_AXIS = 1,
Z_AXIS = 2,
C_AXIS = 2,
E_AXIS = 3,
X_HEAD = 4,
Y_HEAD = 5,
Z_HEAD = 6,
E_CART = 3,
#if ENABLED(HANGPRINTER) // Hangprinter order: A_AXIS, B_AXIS, C_AXIS, D_AXIS, E_AXIS
D_AXIS = 3,
E_AXIS = 4,
#else
E_AXIS = 3,
#endif
X_HEAD, Y_HEAD, Z_HEAD,
ALL_AXES = 0xFE,
NO_AXIS = 0xFF
};
@@ -54,11 +58,11 @@ enum AxisEnum : unsigned char {
#define LOOP_NA(VAR) LOOP_L_N(VAR, NUM_AXIS)
#define LOOP_XYZ(VAR) LOOP_S_LE_N(VAR, X_AXIS, Z_AXIS)
#define LOOP_XYZE(VAR) LOOP_S_LE_N(VAR, X_AXIS, E_AXIS)
#define LOOP_XYZE(VAR) LOOP_S_LE_N(VAR, X_AXIS, E_CART)
#define LOOP_XYZE_N(VAR) LOOP_S_L_N(VAR, X_AXIS, XYZE_N)
#define LOOP_ABC(VAR) LOOP_S_LE_N(VAR, A_AXIS, C_AXIS)
#define LOOP_ABCE(VAR) LOOP_S_LE_N(VAR, A_AXIS, E_AXIS)
#define LOOP_ABCE_N(VAR) LOOP_S_L_N(VAR, A_AXIS, XYZE_N)
#define LOOP_MOV_AXIS(VAR) LOOP_S_L_N(VAR, A_AXIS, MOV_AXIS)
#define LOOP_NUM_AXIS(VAR) LOOP_S_L_N(VAR, A_AXIS, NUM_AXIS)
#define LOOP_NUM_AXIS_N(VAR) LOOP_S_L_N(VAR, A_AXIS, NUM_AXIS_N)
typedef enum {
LINEARUNIT_MM,
+3 -2
View File
@@ -23,8 +23,9 @@
/**
* Pin mapping for the 1280 and 2560
*
* Logical Pin: 22 23 24 25 26 27 28 29 53 52 51 50 10 11 12 13 37 36 35 34 33 32 31 30 21 20 19 18 81 82 83 38 00 01 78 05 02 03 79 80 54 55 56 57 58 59 60 61 41 40 39 71 70 04 17 16 84 06 07 08 09 85 15 14 72 73 75 76 77 74 62 63 64 65 66 67 68 69 49 48 47 46 45 44 43 42
* Port: A0 A1 A2 A3 A4 A5 A6 A7 B0 B1 B2 B3 B4 B5 B6 B7 C0 C1 C2 C3 C4 C5 C6 C7 D0 D1 D2 D3 D4 D5 D6 D7 E0 E1 E2 E3 E4 E5 E6 E7 F0 F1 F2 F3 F4 F5 F6 F7 G0 G1 G2 G3 G4 G5 H0 H1 H2 H3 H4 H5 H6 H7 J0 J1 J2 J3 J4 J5 J6 J7 K0 K1 K2 K3 K4 K5 K6 K7 L0 L1 L2 L3 L4 L5 L6 L7
* Hardware Pin : 02 03 06 07 01 05 15 16 17 18 23 24 25 26 64 63 13 12 46 45 44 43 78 77 76 75 74 73 72 71 60 59 58 57 56 55 54 53 50 70 52 51 42 41 40 39 38 37 36 35 22 21 20 19 97 96 95 94 93 92 91 90 89 88 87 86 85 84 83 82 04 08 09 10 11 14 27 28 29 30 31 32 33 34 47 48 49 61 62 65 66 67 68 69 79 80 81 98 99 100
* Port : E0 E1 E4 E5 G5 E3 H3 H4 H5 H6 B4 B5 B6 B7 J1 J0 H1 H0 D3 D2 D1 D0 A0 A1 A2 A3 A4 A5 A6 A7 C7 C6 C5 C4 C3 C2 C1 C0 D7 G2 G1 G0 L7 L6 L5 L4 L3 L2 L1 L0 B3 B2 B1 B0 F0 F1 F2 F3 F4 F5 F6 F7 K0 K1 K2 K3 K4 K5 K6 K7 E2 E6 E7 xx xx H2 H7 G3 G4 xx xx xx xx xx D4 D5 D6 xx xx J2 J3 J4 J5 J6 J7 xx xx xx xx xx
* Logical Pin : 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx
*/
#ifndef _FASTIO_1280
+6 -6
View File
@@ -123,7 +123,7 @@ void FWRetract::retract(const bool retracting
#endif
}
SERIAL_ECHOLNPAIR("current_position[z] ", current_position[Z_AXIS]);
SERIAL_ECHOLNPAIR("current_position[e] ", current_position[E_AXIS]);
SERIAL_ECHOLNPAIR("current_position[e] ", current_position[E_CART]);
SERIAL_ECHOLNPAIR("hop_amount ", hop_amount);
//*/
@@ -131,7 +131,7 @@ void FWRetract::retract(const bool retracting
renormalize = RECIPROCAL(planner.e_factor[active_extruder]),
base_retract = swapping ? swap_retract_length : retract_length,
old_z = current_position[Z_AXIS],
old_e = current_position[E_AXIS];
old_e = current_position[E_CART];
// The current position will be the destination for E and Z moves
set_destination_from_current();
@@ -139,7 +139,7 @@ void FWRetract::retract(const bool retracting
if (retracting) {
// Retract by moving from a faux E position back to the current E position
feedrate_mm_s = retract_feedrate_mm_s;
destination[E_AXIS] -= base_retract * renormalize;
destination[E_CART] -= base_retract * renormalize;
prepare_move_to_destination(); // set_current_to_destination
// Is a Z hop set, and has the hop not yet been done?
@@ -160,14 +160,14 @@ void FWRetract::retract(const bool retracting
hop_amount = 0.0; // Clear the hop amount
}
destination[E_AXIS] += (base_retract + (swapping ? swap_retract_recover_length : retract_recover_length)) * renormalize;
destination[E_CART] += (base_retract + (swapping ? swap_retract_recover_length : retract_recover_length)) * renormalize;
feedrate_mm_s = swapping ? swap_retract_recover_feedrate_mm_s : retract_recover_feedrate_mm_s;
prepare_move_to_destination(); // Recover E, set_current_to_destination
}
feedrate_mm_s = old_feedrate_mm_s; // Restore original feedrate
current_position[Z_AXIS] = old_z; // Restore Z and E positions
current_position[E_AXIS] = old_e;
current_position[E_CART] = old_e;
SYNC_PLAN_POSITION_KINEMATIC(); // As if the move never took place
retracted[active_extruder] = retracting; // Active extruder now retracted / recovered
@@ -190,7 +190,7 @@ void FWRetract::retract(const bool retracting
#endif
}
SERIAL_ECHOLNPAIR("current_position[z] ", current_position[Z_AXIS]);
SERIAL_ECHOLNPAIR("current_position[e] ", current_position[E_AXIS]);
SERIAL_ECHOLNPAIR("current_position[e] ", current_position[E_CART]);
SERIAL_ECHOLNPAIR("hop_amount ", hop_amount);
//*/
+14 -14
View File
@@ -149,23 +149,23 @@
#define MSG_RESEND "Resend: "
#define MSG_UNKNOWN_COMMAND "Unknown command: \""
#define MSG_ACTIVE_EXTRUDER "Active Extruder: "
#define MSG_X_MIN "x_min: "
#define MSG_X_MAX "x_max: "
#define MSG_X2_MIN "x2_min: "
#define MSG_X2_MAX "x2_max: "
#define MSG_Y_MIN "y_min: "
#define MSG_Y_MAX "y_max: "
#define MSG_Y2_MIN "y2_min: "
#define MSG_Y2_MAX "y2_max: "
#define MSG_Z_MIN "z_min: "
#define MSG_Z_MAX "z_max: "
#define MSG_Z2_MIN "z2_min: "
#define MSG_Z2_MAX "z2_max: "
#define MSG_Z_PROBE "z_probe: "
#define MSG_X_MIN "x_min"
#define MSG_X_MAX "x_max"
#define MSG_X2_MIN "x2_min"
#define MSG_X2_MAX "x2_max"
#define MSG_Y_MIN "y_min"
#define MSG_Y_MAX "y_max"
#define MSG_Y2_MIN "y2_min"
#define MSG_Y2_MAX "y2_max"
#define MSG_Z_MIN "z_min"
#define MSG_Z_MAX "z_max"
#define MSG_Z2_MIN "z2_min"
#define MSG_Z2_MAX "z2_max"
#define MSG_Z_PROBE "z_probe"
#define MSG_FILAMENT_RUNOUT_SENSOR "filament"
#define MSG_PROBE_Z_OFFSET "Probe Z Offset"
#define MSG_SKEW_MIN "min_skew_factor: "
#define MSG_SKEW_MAX "max_skew_factor: "
#define MSG_FILAMENT_RUNOUT_SENSOR "filament: "
#define MSG_ERR_MATERIAL_INDEX "M145 S<index> out of range (0-1)"
#define MSG_ERR_M355_NONE "No case light"
#define MSG_ERR_M421_PARAMETERS "M421 incorrect parameter usage"
+1
View File
@@ -44,6 +44,7 @@
#define MSG_AUTO_HOME_X _UxGT("Orichen X")
#define MSG_AUTO_HOME_Y _UxGT("Orichen Y")
#define MSG_AUTO_HOME_Z _UxGT("Orichen Z")
#define MSG_TMC_Z_CALIBRATION _UxGT("Calibrar Z")
#define MSG_LEVEL_BED_HOMING _UxGT("Orichen XYZ")
#define MSG_LEVEL_BED_WAITING _UxGT("Encetar (pretar)")
#define MSG_LEVEL_BED_NEXT_POINT _UxGT("Vinient punto")
+1
View File
@@ -41,6 +41,7 @@
#define MSG_AUTOSTART _UxGT("Автостарт")
#define MSG_DISABLE_STEPPERS _UxGT("Изкл. двигатели")
#define MSG_AUTO_HOME _UxGT("Паркиране")
#define MSG_TMC_Z_CALIBRATION _UxGT("Калибровка Z")
#define MSG_SET_HOME_OFFSETS _UxGT("Задай Начало")
#define MSG_SET_ORIGIN _UxGT("Изходна точка")
#define MSG_PREHEAT_1 _UxGT("Подгряване PLA")
+1
View File
@@ -47,6 +47,7 @@
#define MSG_AUTO_HOME_X _UxGT("X a origen")
#define MSG_AUTO_HOME_Y _UxGT("Y a origen")
#define MSG_AUTO_HOME_Z _UxGT("Z a origen")
#define MSG_TMC_Z_CALIBRATION _UxGT("Calibra Z")
#define MSG_LEVEL_BED_HOMING _UxGT("Origen XYZ")
#define MSG_LEVEL_BED_WAITING _UxGT("Premeu per iniciar")
#define MSG_LEVEL_BED_NEXT_POINT _UxGT("Següent punt")
+1
View File
@@ -40,6 +40,7 @@
#define MSG_AUTOSTART "\xb1\xb2\xb3\xb4"
#define MSG_DISABLE_STEPPERS "\xb5\xb6\xb7\xb8\xb9\xba"
#define MSG_AUTO_HOME "\xbb\xbc\xbd"
#define MSG_TMC_Z_CALIBRATION "Calibrate Z"
#define MSG_LEVEL_BED_HOMING "Homing XYZ"
#define MSG_LEVEL_BED_WAITING "Click to Begin"
#define MSG_LEVEL_BED_DONE "Leveling Done!"
+1
View File
@@ -50,6 +50,7 @@
#define MSG_AUTO_HOME_X _UxGT("Domu osa X")
#define MSG_AUTO_HOME_Y _UxGT("Domu osa Y")
#define MSG_AUTO_HOME_Z _UxGT("Domu osa Z")
#define MSG_TMC_Z_CALIBRATION _UxGT("Kalibrovat Z")
#define MSG_LEVEL_BED_HOMING _UxGT("Mereni podlozky")
#define MSG_LEVEL_BED_WAITING _UxGT("Kliknutim spustte")
#define MSG_LEVEL_BED_NEXT_POINT _UxGT("Dalsi bod")
+9
View File
@@ -44,6 +44,7 @@
#define MSG_SD_INSERTED _UxGT("Karta vložena")
#define MSG_SD_REMOVED _UxGT("Karta vyjmuta")
#define MSG_LCD_ENDSTOPS _UxGT("Endstopy") // max 8 znaku
#define MSG_LCD_SOFT_ENDSTOPS _UxGT("Soft Endstopy")
#define MSG_MAIN _UxGT("Hlavní nabídka")
#define MSG_AUTOSTART _UxGT("Autostart")
#define MSG_DISABLE_STEPPERS _UxGT("Uvolnit motory")
@@ -53,6 +54,7 @@
#define MSG_AUTO_HOME_X _UxGT("Domů osa X")
#define MSG_AUTO_HOME_Y _UxGT("Domů osa Y")
#define MSG_AUTO_HOME_Z _UxGT("Domů osa Z")
#define MSG_TMC_Z_CALIBRATION _UxGT("Kalibrovat Z")
#define MSG_LEVEL_BED_HOMING _UxGT("Měření podložky")
#define MSG_LEVEL_BED_WAITING _UxGT("Kliknutím spusťte")
#define MSG_LEVEL_BED_NEXT_POINT _UxGT("Další bod")
@@ -252,11 +254,13 @@
#define MSG_PAUSE_PRINT _UxGT("Pozastavit tisk")
#define MSG_RESUME_PRINT _UxGT("Obnovit tisk")
#define MSG_STOP_PRINT _UxGT("Zastavit tisk")
#define MSG_POWER_LOSS_RECOVERY _UxGT("Obnova vypadku")
#define MSG_CARD_MENU _UxGT("Tisknout z SD")
#define MSG_NO_CARD _UxGT("Žádná SD karta")
#define MSG_DWELL _UxGT("Uspáno...")
#define MSG_USERWAIT _UxGT("Čekání na uživ...")
#define MSG_PRINT_PAUSED _UxGT("Tisk pozastaven")
#define MSG_PRINTING _UxGT("Tisknu...")
#define MSG_PRINT_ABORTED _UxGT("Tisk zrušen")
#define MSG_NO_MOVE _UxGT("Žádný pohyb.")
#define MSG_KILLED _UxGT("PŘERUSENO. ")
@@ -292,8 +296,10 @@
#define MSG_BABYSTEP_Z _UxGT("Babystep Z")
#define MSG_ENDSTOP_ABORT _UxGT("Endstop abort")
#define MSG_HEATING_FAILED_LCD _UxGT("Chyba zahřívání")
#define MSG_HEATING_FAILED_LCD_BED _UxGT("Chyba zahř. podl.")
#define MSG_ERR_REDUNDANT_TEMP _UxGT("REDUND. TEPLOTA")
#define MSG_THERMAL_RUNAWAY _UxGT("TEPLOTNÍ SKOK")
#define MSG_THERMAL_RUNAWAY_BED _UxGT("PODL. TEPL. SKOK")
#define MSG_ERR_MAXTEMP _UxGT("VYSOKÁ TEPLOTA")
#define MSG_ERR_MINTEMP _UxGT("NÍZKA TEPLOTA")
#define MSG_ERR_MAXTEMP_BED _UxGT("VYS. TEPL. PODL.")
@@ -305,7 +311,9 @@
#define MSG_SHORT_HOUR _UxGT("h")
#define MSG_SHORT_MINUTE _UxGT("m")
#define MSG_HEATING _UxGT("Zahřívání...")
#define MSG_COOLING _UxGT("Chlazení")
#define MSG_BED_HEATING _UxGT("Zahřívání podl...")
#define MSG_BED_COOLING _UxGT("Chlazení podl...")
#define MSG_DELTA_CALIBRATE _UxGT("Delta Kalibrace")
#define MSG_DELTA_CALIBRATE_X _UxGT("Kalibrovat X")
#define MSG_DELTA_CALIBRATE_Y _UxGT("Kalibrovat Y")
@@ -314,6 +322,7 @@
#define MSG_DELTA_SETTINGS _UxGT("Delta nastavení")
#define MSG_DELTA_AUTO_CALIBRATE _UxGT("Autokalibrace")
#define MSG_DELTA_HEIGHT_CALIBRATE _UxGT("Nast.výšku delty")
#define MSG_DELTA_Z_OFFSET_CALIBRATE _UxGT("Nast. Z-ofset")
#define MSG_DELTA_DIAG_ROD _UxGT("Diag rameno")
#define MSG_DELTA_HEIGHT _UxGT("Výška")
#define MSG_DELTA_RADIUS _UxGT("Poloměr")
+1
View File
@@ -45,6 +45,7 @@
#define MSG_AUTO_HOME_X _UxGT("Home X")
#define MSG_AUTO_HOME_Y _UxGT("Home Y")
#define MSG_AUTO_HOME_Z _UxGT("Home Z")
#define MSG_TMC_Z_CALIBRATION _UxGT("Kalibrer Z")
#define MSG_LEVEL_BED_HOMING _UxGT("Homing XYZ")
#define MSG_LEVEL_BED_WAITING _UxGT("Klik når du er klar")
#define MSG_LEVEL_BED_NEXT_POINT _UxGT("Næste punkt")
+1
View File
@@ -50,6 +50,7 @@
#define MSG_AUTO_HOME_X _UxGT("Home X")
#define MSG_AUTO_HOME_Y _UxGT("Home Y")
#define MSG_AUTO_HOME_Z _UxGT("Home Z")
#define MSG_TMC_Z_CALIBRATION _UxGT("Kalibriere Z")
#define MSG_LEVEL_BED_HOMING _UxGT("Home XYZ")
#define MSG_LEVEL_BED_WAITING _UxGT("Klick für Start")
#define MSG_LEVEL_BED_NEXT_POINT _UxGT("Nächste Koordinate")
+1
View File
@@ -45,6 +45,7 @@
#define MSG_AUTO_HOME_X _UxGT("Αρχικό σημείο X")
#define MSG_AUTO_HOME_Y _UxGT("Αρχικό σημείο Y")
#define MSG_AUTO_HOME_Z _UxGT("Αρχικό σημείο Z")
#define MSG_TMC_Z_CALIBRATION _UxGT("Βαθμονόμηση Z")
#define MSG_LEVEL_BED_HOMING _UxGT("Επαναφορά στο αρχικό σημείο ΧΥΖ")
#define MSG_LEVEL_BED_WAITING _UxGT("Κάντε κλικ για να ξεκινήσετε")
#define MSG_LEVEL_BED_NEXT_POINT _UxGT("Επόμενο σημείο")
+1
View File
@@ -45,6 +45,7 @@
#define MSG_AUTO_HOME_X _UxGT("Αρχικό σημείο X")
#define MSG_AUTO_HOME_Y _UxGT("Αρχικό σημείο Y")
#define MSG_AUTO_HOME_Z _UxGT("Αρχικό σημείο Z")
#define MSG_TMC_Z_CALIBRATION _UxGT("Βαθμονόμηση Z")
#define MSG_LEVEL_BED_HOMING _UxGT("Επαναφορά Επ. Εκτύπωσης") //SHORTEN
#define MSG_LEVEL_BED_WAITING _UxGT("Επιπεδοποίηση επ. Εκτύπωσης περιμενει") //SHORTEN
#define MSG_LEVEL_BED_NEXT_POINT _UxGT("Επόμενο σημείο")
+6
View File
@@ -85,6 +85,9 @@
#ifndef MSG_AUTO_HOME_Z
#define MSG_AUTO_HOME_Z _UxGT("Home Z")
#endif
#ifndef MSG_TMC_Z_CALIBRATION
#define MSG_TMC_Z_CALIBRATION _UxGT("Calibrate Z")
#endif
#ifndef MSG_LEVEL_BED_HOMING
#define MSG_LEVEL_BED_HOMING _UxGT("Homing XYZ")
#endif
@@ -1055,6 +1058,9 @@
#ifndef MSG_FILAMENT_CHANGE_INSERT_1
#define MSG_FILAMENT_CHANGE_INSERT_1 _UxGT("Insert and Click")
#endif
#ifndef MSG_FILAMENT_CHANGE_HEAT_1
#define MSG_FILAMENT_CHANGE_HEAT_1 _UxGT("Click to heat")
#endif
#ifndef MSG_FILAMENT_CHANGE_HEATING_1
#define MSG_FILAMENT_CHANGE_HEATING_1 _UxGT("Heating...")
#endif
+1
View File
@@ -48,6 +48,7 @@
#define MSG_AUTO_HOME_X _UxGT("Origen X")
#define MSG_AUTO_HOME_Y _UxGT("Origen Y")
#define MSG_AUTO_HOME_Z _UxGT("Origen Z")
#define MSG_TMC_Z_CALIBRATION _UxGT("Calibrar Z")
#define MSG_LEVEL_BED_HOMING _UxGT("Origen XYZ")
#define MSG_LEVEL_BED_WAITING _UxGT("Iniciar (Presione)")
#define MSG_LEVEL_BED_NEXT_POINT _UxGT("Siguiente punto")
+1
View File
@@ -48,6 +48,7 @@
#define MSG_AUTO_HOME_X _UxGT("Origen X")
#define MSG_AUTO_HOME_Y _UxGT("Origen Y")
#define MSG_AUTO_HOME_Z _UxGT("Origen Z")
#define MSG_TMC_Z_CALIBRATION _UxGT("Calibrar Z")
#define MSG_LEVEL_BED_HOMING _UxGT("Origen XYZ")
#define MSG_LEVEL_BED_WAITING _UxGT("Iniciar (Presione)")
#define MSG_LEVEL_BED_NEXT_POINT _UxGT("Siguiente punto")
+1
View File
@@ -47,6 +47,7 @@
#define MSG_AUTO_HOME_X _UxGT("X jatorrira")
#define MSG_AUTO_HOME_Y _UxGT("Y jatorrira")
#define MSG_AUTO_HOME_Z _UxGT("Z jatorrira")
#define MSG_TMC_Z_CALIBRATION _UxGT("Kalibratu Z")
#define MSG_LEVEL_BED_HOMING _UxGT("XYZ hasieraratzen")
#define MSG_LEVEL_BED_WAITING _UxGT("Klik egin hasteko")
#define MSG_LEVEL_BED_NEXT_POINT _UxGT("Hurrengo Puntua")
+1
View File
@@ -41,6 +41,7 @@
#define MSG_AUTOSTART _UxGT("Automaatti")
#define MSG_DISABLE_STEPPERS _UxGT("Vapauta moottorit")
#define MSG_AUTO_HOME _UxGT("Aja referenssiin")
#define MSG_TMC_Z_CALIBRATION _UxGT("Kalibroi Z")
#define MSG_LEVEL_BED_HOMING _UxGT("Homing XYZ")
#define MSG_LEVEL_BED_WAITING _UxGT("Click to Begin")
#define MSG_LEVEL_BED_DONE _UxGT("Leveling Done!")
+3 -2
View File
@@ -47,6 +47,7 @@
#define MSG_AUTO_HOME_X _UxGT("Origine X Auto.")
#define MSG_AUTO_HOME_Y _UxGT("Origine Y Auto.")
#define MSG_AUTO_HOME_Z _UxGT("Origine Z Auto.")
#define MSG_TMC_Z_CALIBRATION _UxGT("Calibrer Z")
#define MSG_LEVEL_BED_HOMING _UxGT("Origine XYZ")
#define MSG_LEVEL_BED_WAITING _UxGT("Clic pour commencer")
#define MSG_LEVEL_BED_NEXT_POINT _UxGT("Point suivant")
@@ -58,13 +59,13 @@
#define MSG_PREHEAT_1 _UxGT("Prechauffage PLA")
#define MSG_PREHEAT_1_N _UxGT("Prechauff. PLA ")
#define MSG_PREHEAT_1_ALL _UxGT("Prech. PLA Tout")
#define MSG_PREHEAT_1_END MSG_PREHEAT_1 _UxGT(" fini")
#define MSG_PREHEAT_1_END MSG_PREHEAT_1 _UxGT(" buse")
#define MSG_PREHEAT_1_BEDONLY _UxGT("Prech. PLA lit")
#define MSG_PREHEAT_1_SETTINGS _UxGT("Regl. prech. PLA")
#define MSG_PREHEAT_2 _UxGT("Prechauffage ABS")
#define MSG_PREHEAT_2_N _UxGT("Prechauff. ABS ")
#define MSG_PREHEAT_2_ALL _UxGT("Prech. ABS Tout")
#define MSG_PREHEAT_2_END MSG_PREHEAT_2 _UxGT(" fini")
#define MSG_PREHEAT_2_END MSG_PREHEAT_2 _UxGT(" buse")
#define MSG_PREHEAT_2_BEDONLY _UxGT("Prech. ABS lit")
#define MSG_PREHEAT_2_SETTINGS _UxGT("Regl. prech. ABS")
#define MSG_COOLDOWN _UxGT("Refroidir")
+10 -9
View File
@@ -40,7 +40,7 @@
#define MSG_SD_REMOVED _UxGT("Carte retirée")
#define MSG_LCD_ENDSTOPS _UxGT("Butées") // Max length 8 characters
#define MSG_MAIN _UxGT("Menu principal")
#define MSG_AUTOSTART _UxGT("Demarrage auto")
#define MSG_AUTOSTART _UxGT("Démarrage auto")
#define MSG_DISABLE_STEPPERS _UxGT("Arrêter moteurs")
#define MSG_DEBUG_MENU _UxGT("Menu debug")
#define MSG_PROGRESS_BAR_TEST _UxGT("Test barre progress.")
@@ -48,6 +48,7 @@
#define MSG_AUTO_HOME_X _UxGT("Origine X Auto.")
#define MSG_AUTO_HOME_Y _UxGT("Origine Y Auto.")
#define MSG_AUTO_HOME_Z _UxGT("Origine Z Auto.")
#define MSG_TMC_Z_CALIBRATION _UxGT("Calibrer Z")
#define MSG_LEVEL_BED_HOMING _UxGT("Origine XYZ")
#define MSG_LEVEL_BED_WAITING _UxGT("Clic pour commencer")
#define MSG_LEVEL_BED_NEXT_POINT _UxGT("Point suivant")
@@ -59,18 +60,18 @@
#define MSG_PREHEAT_1 _UxGT("Préchauffage PLA")
#define MSG_PREHEAT_1_N _UxGT("Préchauff. PLA ")
#define MSG_PREHEAT_1_ALL _UxGT("Préch. PLA Tout")
#define MSG_PREHEAT_1_END MSG_PREHEAT_1 _UxGT(" fini")
#define MSG_PREHEAT_1_END MSG_PREHEAT_1 _UxGT(" buse")
#define MSG_PREHEAT_1_BEDONLY _UxGT("Préch. PLA lit")
#define MSG_PREHEAT_1_SETTINGS _UxGT("Régl. prech. PLA")
#define MSG_PREHEAT_2 _UxGT("Préchauffage ABS")
#define MSG_PREHEAT_2_N _UxGT("Préchauff. ABS ")
#define MSG_PREHEAT_2_ALL _UxGT("Préch. ABS Tout")
#define MSG_PREHEAT_2_END MSG_PREHEAT_2 _UxGT(" fini")
#define MSG_PREHEAT_2_END MSG_PREHEAT_2 _UxGT(" buse")
#define MSG_PREHEAT_2_BEDONLY _UxGT("Préch. ABS lit")
#define MSG_PREHEAT_2_SETTINGS _UxGT("Régl. prech. ABS")
#define MSG_COOLDOWN _UxGT("Refroidir")
#define MSG_SWITCH_PS_ON _UxGT("Allumer alim.")
#define MSG_SWITCH_PS_OFF _UxGT("Eteindre alim.")
#define MSG_SWITCH_PS_OFF _UxGT("Éteindre alim.")
#define MSG_EXTRUDE _UxGT("Extrusion")
#define MSG_RETRACT _UxGT("Retrait")
#define MSG_MOVE_AXIS _UxGT("Déplacer un axe")
@@ -86,9 +87,9 @@
#define MSG_UBL_TOOLS _UxGT("Outils UBL")
#define MSG_UBL_LEVEL_BED _UxGT("Niveau lit unifié")
#define MSG_UBL_MANUAL_MESH _UxGT("Maillage manuel")
#define MSG_UBL_BC_INSERT _UxGT("Poser câle & mesurer")
#define MSG_UBL_BC_INSERT _UxGT("Poser cale & mesurer")
#define MSG_UBL_BC_INSERT2 _UxGT("Mesure")
#define MSG_UBL_BC_REMOVE _UxGT("ôter et mesurer lit")
#define MSG_UBL_BC_REMOVE _UxGT("Ôter et mesurer lit")
#define MSG_UBL_MOVING_TO_NEXT _UxGT("Aller au suivant")
#define MSG_UBL_ACTIVATE_MESH _UxGT("Activer l'UBL")
#define MSG_UBL_DEACTIVATE_MESH _UxGT("Désactiver l'UBL")
@@ -96,8 +97,8 @@
#define MSG_UBL_CUSTOM_BED_TEMP MSG_UBL_SET_BED_TEMP
#define MSG_UBL_SET_HOTEND_TEMP _UxGT("Température buse")
#define MSG_UBL_CUSTOM_HOTEND_TEMP MSG_UBL_SET_HOTEND_TEMP
#define MSG_UBL_MESH_EDIT _UxGT("Editer maille")
#define MSG_UBL_EDIT_CUSTOM_MESH _UxGT("Editer maille perso")
#define MSG_UBL_MESH_EDIT _UxGT("Éditer maille")
#define MSG_UBL_EDIT_CUSTOM_MESH _UxGT("Éditer maille perso")
#define MSG_UBL_FINE_TUNE_MESH _UxGT("Réglage fin maille")
#define MSG_UBL_DONE_EDITING_MESH _UxGT("Terminer maille")
#define MSG_UBL_BUILD_CUSTOM_MESH _UxGT("Créer maille perso")
@@ -155,7 +156,7 @@
#define MSG_SET_LEDS_INDIGO _UxGT("Indigo")
#define MSG_SET_LEDS_VIOLET _UxGT("Violet")
#define MSG_SET_LEDS_WHITE _UxGT("Blanc")
#define MSG_SET_LEDS_DEFAULT _UxGT("Defaut")
#define MSG_SET_LEDS_DEFAULT _UxGT("Défaut")
#define MSG_CUSTOM_LEDS _UxGT("Lum. perso.")
#define MSG_INTENSITY_R _UxGT("Intensité rouge")
#define MSG_INTENSITY_G _UxGT("Intensité vert")
+1 -1
View File
@@ -45,6 +45,7 @@
#define MSG_AUTO_HOME_X _UxGT("Ir orixe X")
#define MSG_AUTO_HOME_Y _UxGT("Ir orixe Y")
#define MSG_AUTO_HOME_Z _UxGT("Ir orixe Z")
#define MSG_TMC_Z_CALIBRATION _UxGT("Calibrar Z")
#define MSG_LEVEL_BED_HOMING _UxGT("Ir orixes XYZ")
#define MSG_LEVEL_BED_WAITING _UxGT("Prema pulsador")
#define MSG_LEVEL_BED_NEXT_POINT _UxGT("Seguinte punto")
@@ -252,4 +253,3 @@
#endif // LCD_HEIGHT < 4
#endif // LANGUAGE_GL_H
+1
View File
@@ -44,6 +44,7 @@
#define MSG_AUTO_HOME_X _UxGT("Home-aj X")
#define MSG_AUTO_HOME_Y _UxGT("Home-aj Y")
#define MSG_AUTO_HOME_Z _UxGT("Home-aj Z")
#define MSG_TMC_Z_CALIBRATION _UxGT("Kalibriraj Z")
#define MSG_LEVEL_BED_HOMING _UxGT("Home-aj XYZ")
#define MSG_LEVEL_BED_WAITING _UxGT("Klikni za početak")
#define MSG_LEVEL_BED_NEXT_POINT _UxGT("Sljedeća točka")
+1
View File
@@ -47,6 +47,7 @@
#define MSG_AUTO_HOME_X _UxGT("Home asse X")
#define MSG_AUTO_HOME_Y _UxGT("Home asse Y")
#define MSG_AUTO_HOME_Z _UxGT("Home asse Z")
#define MSG_TMC_Z_CALIBRATION _UxGT("Calibra Z")
#define MSG_LEVEL_BED_HOMING _UxGT("Home assi XYZ")
#define MSG_LEVEL_BED_WAITING _UxGT("Premi per iniziare")
#define MSG_LEVEL_BED_NEXT_POINT _UxGT("Punto successivo")
+1
View File
@@ -50,6 +50,7 @@
#define MSG_AUTO_HOME_X "X\xbc\xde\xb8\x20\xb9\xde\xdd\xc3\xdd\xcc\xaf\xb7" // "Xジク ゲンテンフッキ" ("Home X")
#define MSG_AUTO_HOME_Y "Y\xbc\xde\xb8\x20\xb9\xde\xdd\xc3\xdd\xcc\xaf\xb7" // "Yジク ゲンテンフッキ" ("Home Y")
#define MSG_AUTO_HOME_Z "Z\xbc\xde\xb8\x20\xb9\xde\xdd\xc3\xdd\xcc\xaf\xb7" // "Zジク ゲンテンフッキ" ("Home Z")
#define MSG_TMC_Z_CALIBRATION "Z\xbc\xde\xb8\x20\xba\xb3\xbe\xb2" // "Zジク コウセイ" ("Calibrate Z")
#define MSG_LEVEL_BED_HOMING "\xb9\xde\xdd\xc3\xdd\xcc\xaf\xb7\xc1\xad\xb3" // "ゲンテンフッキチュウ" ("Homing XYZ")
#define MSG_LEVEL_BED_WAITING "\xda\xcd\xde\xd8\xdd\xb8\xde\xb6\xb2\xbc" // "レベリングカイシ" ("Click to Begin")
#define MSG_LEVEL_BED_NEXT_POINT "\xc2\xb7\xde\xc9\xbf\xb8\xc3\xb2\xc3\xdd\xcd" // "ツギノソクテイテンヘ" ("Next Point")
+1
View File
@@ -53,6 +53,7 @@
#define MSG_AUTO_HOME_X _UxGT("Xジク ゲンテンフッキ") // "Home X"
#define MSG_AUTO_HOME_Y _UxGT("Yジク ゲンテンフッキ") // "Home Y"
#define MSG_AUTO_HOME_Z _UxGT("Zジク ゲンテンフッキ") // "Home Z"
#define MSG_TMC_Z_CALIBRATION _UxGT("Zジク コウセイ") // "Calibrate Z"
#define MSG_LEVEL_BED_HOMING _UxGT("ゲンテンフッキチュウ") // "Homing XYZ"
#define MSG_LEVEL_BED_WAITING _UxGT("レベリングカイシ") // "Click to Begin"
#define MSG_LEVEL_BED_NEXT_POINT _UxGT("ツギノソクテイテンヘ") // "Next Point"
+1
View File
@@ -47,6 +47,7 @@
#define MSG_AUTO_HOME_X _UxGT("Home X")
#define MSG_AUTO_HOME_Y _UxGT("Home Y")
#define MSG_AUTO_HOME_Z _UxGT("Home Z")
#define MSG_TMC_Z_CALIBRATION _UxGT("Kalibreer Z")
#define MSG_LEVEL_BED_HOMING _UxGT("Homing XYZ")
#define MSG_LEVEL_BED_WAITING _UxGT("Klik voor begin")
#define MSG_LEVEL_BED_NEXT_POINT _UxGT("Volgende Plaats")
+1
View File
@@ -39,6 +39,7 @@
#define MSG_AUTO_HOME_X _UxGT("Zeruj X")
#define MSG_AUTO_HOME_Y _UxGT("Zeruj Y")
#define MSG_AUTO_HOME_Z _UxGT("Zeruj Z")
#define MSG_TMC_Z_CALIBRATION _UxGT("Kalibruj Z")
#define MSG_LEVEL_BED _UxGT("Poziom. stołu")
#define MSG_LEVEL_BED_HOMING _UxGT("Pozycja zerowa")
#define MSG_LEVEL_BED_WAITING _UxGT("Kliknij by rozp.")
+1
View File
@@ -40,6 +40,7 @@
#define MSG_AUTO_HOME_X _UxGT("Zeruj X")
#define MSG_AUTO_HOME_Y _UxGT("Zeruj Y")
#define MSG_AUTO_HOME_Z _UxGT("Zeruj Z")
#define MSG_TMC_Z_CALIBRATION _UxGT("Kalibruj Z")
#define MSG_LEVEL_BED _UxGT("Poziom. stolu")
#define MSG_LEVEL_BED_HOMING _UxGT("Pozycja zerowa")
#define MSG_LEVEL_BED_WAITING _UxGT("Kliknij by rozp.")
+1
View File
@@ -48,6 +48,7 @@
#define MSG_AUTO_HOME_Y _UxGT("Ir na origem Y")
#define MSG_AUTO_HOME_Z _UxGT("Ir na origem Z")
#define MSG_AUTO_HOME _UxGT("Ir na origem XYZ")
#define MSG_TMC_Z_CALIBRATION _UxGT("Calibrar Z")
#define MSG_LEVEL_BED_HOMING _UxGT("Indo para origem")
#define MSG_LEVEL_BED_WAITING _UxGT("Clique para Iniciar")
#define MSG_LEVEL_BED_NEXT_POINT _UxGT("Proximo Ponto")
+1
View File
@@ -50,6 +50,7 @@
#define MSG_AUTO_HOME_Y _UxGT("Ir na origem Y")
#define MSG_AUTO_HOME_Z _UxGT("Ir na origem Z")
#define MSG_AUTO_HOME _UxGT("Ir na origem XYZ")
#define MSG_TMC_Z_CALIBRATION _UxGT("Calibrar Z")
#define MSG_LEVEL_BED_HOMING _UxGT("Indo para origem")
#define MSG_LEVEL_BED_WAITING _UxGT("Clique para Iniciar")
#define MSG_LEVEL_BED_NEXT_POINT _UxGT("Próximo Ponto")
+1
View File
@@ -43,6 +43,7 @@
#define MSG_AUTO_HOME_X "Ir para origem X"
#define MSG_AUTO_HOME_Y "Ir para origem Y"
#define MSG_AUTO_HOME_Z "Ir para origem Z"
#define MSG_TMC_Z_CALIBRATION "Calibrar Z"
#define MSG_LEVEL_BED_HOMING "Indo para origem"
#define MSG_LEVEL_BED_WAITING "Click para iniciar"
#define MSG_LEVEL_BED_NEXT_POINT "Proximo ponto"
+1
View File
@@ -45,6 +45,7 @@
#define MSG_AUTO_HOME_X _UxGT("Ir para origem X")
#define MSG_AUTO_HOME_Y _UxGT("Ir para origem Y")
#define MSG_AUTO_HOME_Z _UxGT("Ir para origem Z")
#define MSG_TMC_Z_CALIBRATION _UxGT("Calibrar Z")
#define MSG_LEVEL_BED_HOMING _UxGT("Indo para origem")
#define MSG_LEVEL_BED_WAITING _UxGT("Click para iniciar")
#define MSG_LEVEL_BED_NEXT_POINT _UxGT("Próximo ponto")
+1
View File
@@ -49,6 +49,7 @@
#define MSG_AUTO_HOME_X _UxGT("Парковка X")
#define MSG_AUTO_HOME_Y _UxGT("Парковка Y")
#define MSG_AUTO_HOME_Z _UxGT("Парковка Z")
#define MSG_TMC_Z_CALIBRATION _UxGT("Калибровать Z")
#define MSG_LEVEL_BED_HOMING _UxGT("Нулевое положение")
#define MSG_LEVEL_BED_WAITING _UxGT("Нажмите чтобы начать")
#define MSG_LEVEL_BED_NEXT_POINT _UxGT("Следующая точка")
+1
View File
@@ -53,6 +53,7 @@
#define MSG_AUTO_HOME_X _UxGT("Domov os X")
#define MSG_AUTO_HOME_Y _UxGT("Domov os Y")
#define MSG_AUTO_HOME_Z _UxGT("Domov os Z")
#define MSG_TMC_Z_CALIBRATION _UxGT("Kalibrovať Z")
#define MSG_LEVEL_BED_HOMING _UxGT("Meranie podložky")
#define MSG_LEVEL_BED_WAITING _UxGT("Kliknutím spusťte")
#define MSG_LEVEL_BED_NEXT_POINT _UxGT("Ďalší bod")
+1
View File
@@ -52,6 +52,7 @@
#define MSG_AUTO_HOME_X _UxGT("X Sıfırla") // X Sıfırla
#define MSG_AUTO_HOME_Y _UxGT("Y Sıfırla") // Y Sıfırla
#define MSG_AUTO_HOME_Z _UxGT("Z Sıfırla") // Z Sıfırla
#define MSG_TMC_Z_CALIBRATION _UxGT("Ayarla Z") // Ayarla Z
#define MSG_LEVEL_BED_HOMING _UxGT("XYZ Sıfırlanıyor") // XYZ Sıfırlanıyor
#define MSG_LEVEL_BED_WAITING _UxGT("Başlatmak için tıkla") // Başlatmak için tıkla
#define MSG_LEVEL_BED_NEXT_POINT _UxGT("Sıradaki Nokta") // Sıradaki Nokta
+1
View File
@@ -45,6 +45,7 @@
#define MSG_AUTO_HOME_X _UxGT("Паркування X")
#define MSG_AUTO_HOME_Y _UxGT("Паркування Y")
#define MSG_AUTO_HOME_Z _UxGT("Паркування Z")
#define MSG_TMC_Z_CALIBRATION _UxGT("Калібрування Z")
#define MSG_LEVEL_BED_HOMING _UxGT("Паркування XYZ")
#define MSG_LEVEL_BED_WAITING _UxGT("Почати")
#define MSG_LEVEL_BED_NEXT_POINT _UxGT("Слідуюча Точка")
+1
View File
@@ -46,6 +46,7 @@
#define MSG_AUTO_HOME_X _UxGT("回X原位") //"Home X"
#define MSG_AUTO_HOME_Y _UxGT("回Y原位") //"Home Y"
#define MSG_AUTO_HOME_Z _UxGT("回Z原位") //"Home Z"
#define MSG_TMC_Z_CALIBRATION _UxGT("⊿校准Z") //"Calibrate Z"
#define MSG_LEVEL_BED_HOMING _UxGT("平台调平XYZ归原位") //"Homing XYZ"
#define MSG_LEVEL_BED_WAITING _UxGT("单击开始热床调平") //"Click to Begin"
#define MSG_LEVEL_BED_NEXT_POINT _UxGT("下个热床调平点") //"Next Point"
+1
View File
@@ -46,6 +46,7 @@
#define MSG_AUTO_HOME_X _UxGT("回X原點") //"Home X"
#define MSG_AUTO_HOME_Y _UxGT("回Y原點") //"Home Y"
#define MSG_AUTO_HOME_Z _UxGT("回Z原點") //"Home Z"
#define MSG_TMC_Z_CALIBRATION _UxGT("⊿校準Z") //"Calibrate Z"
#define MSG_LEVEL_BED_HOMING _UxGT("平台調平XYZ歸原點") //"Homing XYZ"
#define MSG_LEVEL_BED_WAITING _UxGT("單擊開始熱床調平") //"Click to Begin"
#define MSG_LEVEL_BED_NEXT_POINT _UxGT("下個熱床調平點") //"Next Point"
+12 -7
View File
@@ -23,13 +23,18 @@
#ifndef MACROS_H
#define MACROS_H
#define NUM_AXIS 4
#define ABCE 4
#define XYZE 4
#define ABC 3
#define XYZ 3
#define XYZ 3
#define XYZE 4
#define ABC 3
#define ABCD 4
#define ABCE 4
#define ABCDE 5
// For use in macros that take a single axis letter
/**
* For use in macros that take a single axis letter
* The axis order in all axis related arrays is X, Y, Z, E
* For Hangprinter it is A, B, C, D, E
*/
#define _AXIS(A) (A##_AXIS)
#define _XMIN_ 100
@@ -231,4 +236,4 @@
#define FMOD(x, y) fmodf(x, y)
#define HYPOT(x,y) SQRT(HYPOT2(x,y))
#endif //__MACROS_H
#endif // MACROS_H
+31 -19
View File
@@ -83,6 +83,9 @@
// Track incoming command bytes from the LCD
int inbound_count;
// For sending print completion messages
bool last_printing_status = false;
// Everything written needs the high bit set.
void write_to_lcd_P(const char * const message) {
char encoded_message[MAX_CURLY_COMMAND];
@@ -112,22 +115,23 @@ void write_to_lcd(const char * const message) {
* {C:P050}
* Set temp for bed to 50
*
* {C:S09} set feedrate to 90 %.
* {C:S12} set feedrate to 120 %.
*
* the command portion begins after the :
*/
void process_lcd_c_command(const char* command) {
switch (command[0]) {
case 'T': {
// M104 S<temperature>
char cmd[20];
sprintf_P(cmd, PSTR("M104 S%s"), command + 1);
enqueue_and_echo_command_now(cmd);
case 'C': {
int raw_feedrate = atoi(command + 1);
feedrate_percentage = raw_feedrate * 10;
feedrate_percentage = constrain(feedrate_percentage, 10, 999);
} break;
case 'T': {
thermalManager.setTargetHotend(atoi(command + 1), 0);
} break;
case 'P': {
// M140 S<temperature>
char cmd[20];
sprintf_P(cmd, PSTR("M140 S%s"), command + 1);
enqueue_and_echo_command_now(cmd);
thermalManager.setTargetBed(atoi(command + 1));
} break;
default:
@@ -246,6 +250,7 @@ void process_lcd_p_command(const char* command) {
#if ENABLED(SDSUPPORT)
// cancel print
write_to_lcd_P(PSTR("{SYS:CANCELING}"));
last_printing_status = false;
card.stopSDPrint(
#if SD_RESORT
true
@@ -286,7 +291,7 @@ void process_lcd_p_command(const char* command) {
}
else {
char message_buffer[MAX_CURLY_COMMAND];
sprintf_P(message_buffer, PSTR("{PRINTFILE:%s}"), card.filename);
sprintf_P(message_buffer, PSTR("{PRINTFILE:%s}"), card.longest_filename());
write_to_lcd(message_buffer);
write_to_lcd_P(PSTR("{SYS:BUILD}"));
card.openAndPrintFile(card.filename);
@@ -327,7 +332,7 @@ void process_lcd_s_command(const char* command) {
case 'H':
// Home all axis
enqueue_and_echo_command("G28", false);
enqueue_and_echo_command("G28");
break;
case 'L': {
@@ -344,7 +349,7 @@ void process_lcd_s_command(const char* command) {
uint16_t file_count = card.get_num_Files();
for (uint16_t i = 0; i < file_count; i++) {
card.getfilename(i);
sprintf_P(message_buffer, card.filenameIsDir ? PSTR("{DIR:%s}") : PSTR("{FILE:%s}"), card.filename);
sprintf_P(message_buffer, card.filenameIsDir ? PSTR("{DIR:%s}") : PSTR("{FILE:%s}"), card.longest_filename());
write_to_lcd(message_buffer);
}
@@ -439,14 +444,21 @@ void _O2 lcd_update() {
}
#if ENABLED(SDSUPPORT)
// If there's a print in progress, we need to emit the status as
// {TQ:<PERCENT>}
if (card.sdprinting) {
// We also need to send: T:-2538.0 E:0
// I have no idea what this means.
// The way last printing status works is simple:
// The UI needs to see at least one TQ which is not 100%
// and then when the print is complete, one which is.
static uint8_t last_percent_done = 100;
// If there was a print in progress, we need to emit the final
// print status as {TQ:100}. Reset last percent done so a new print will
// issue a percent of 0.
const uint8_t percent_done = card.sdprinting ? card.percentDone() : last_printing_status ? 100 : 0;
if (percent_done != last_percent_done) {
char message_buffer[10];
sprintf_P(message_buffer, PSTR("{TQ:%03i}"), card.percentDone());
sprintf_P(message_buffer, PSTR("{TQ:%03i}"), percent_done);
write_to_lcd(message_buffer);
last_percent_done = percent_done;
last_printing_status = card.sdprinting;
}
#endif
}
+5 -3
View File
@@ -161,9 +161,11 @@
#if ENABLED(NOZZLE_PARK_FEATURE)
void Nozzle::park(const uint8_t &z_action, const point_t &park /*= NOZZLE_PARK_POINT*/) {
const float fr_xy = NOZZLE_PARK_XY_FEEDRATE;
const float fr_z = NOZZLE_PARK_Z_FEEDRATE;
constexpr float npp[] = NOZZLE_PARK_POINT;
static_assert(COUNT(npp) == XYZ, "NOZZLE_PARK_POINT requires X, Y, and Z values.");
void Nozzle::park(const uint8_t &z_action, const point_t &park/*=NOZZLE_PARK_POINT*/) {
const float fr_xy = NOZZLE_PARK_XY_FEEDRATE, fr_z = NOZZLE_PARK_Z_FEEDRATE;
switch (z_action) {
case 1: // Go to Z-park height
+7 -1
View File
@@ -90,9 +90,15 @@ public:
#endif
#if ENABLED(DEBUG_GCODE_PARSER)
void debug();
static void debug();
#endif
GCodeParser() {
#if ENABLED(INCH_MODE_SUPPORT)
set_input_linear_units(LINEARUNIT_MM);
#endif
}
// Reset is done before parsing
static void reset();
+1 -1
View File
@@ -100,9 +100,9 @@ static void PCA9632_WriteAllRegisters(const byte addr, const byte regadd, const
#endif
void pca9632_set_led_color(const LEDColor &color) {
Wire.begin();
if (!PCA_init) {
PCA_init = 1;
Wire.begin();
PCA9632_WriteRegister(PCA9632_ADDRESS,PCA9632_MODE1, PCA9632_MODE1_VALUE);
PCA9632_WriteRegister(PCA9632_ADDRESS,PCA9632_MODE2, PCA9632_MODE2_VALUE);
}
+59 -10
View File
@@ -696,6 +696,7 @@
// Dual X-carriage, Dual Y, Dual Z support
//
#define _D_PINS
#define _X2_PINS
#define _Y2_PINS
#define _Z2_PINS
@@ -703,16 +704,64 @@
#define __EPIN(p,q) E##p##_##q##_PIN
#define _EPIN(p,q) __EPIN(p,q)
// The HANGPRINTER A, B, C, D axes
#if ENABLED(HANGPRINTER)
#define A_ENABLE_PIN X_ENABLE_PIN
#define A_DIR_PIN X_DIR_PIN
#define A_STEP_PIN X_STEP_PIN
#define A_MS1_PIN X_MS1_PIN
#define B_ENABLE_PIN Y_ENABLE_PIN
#define B_DIR_PIN Y_DIR_PIN
#define B_STEP_PIN Y_STEP_PIN
#define B_MS1_PIN Y_MS1_PIN
#define C_ENABLE_PIN Z_ENABLE_PIN
#define C_DIR_PIN Z_DIR_PIN
#define C_STEP_PIN Z_STEP_PIN
#define C_MS1_PIN Z_MS1_PIN
#ifndef D_STEP_PIN
#define D_STEP_PIN _EPIN(E_STEPPERS, STEP)
#define D_DIR_PIN _EPIN(E_STEPPERS, DIR)
#define D_ENABLE_PIN _EPIN(E_STEPPERS, ENABLE)
#ifndef D_CS_PIN
#define D_CS_PIN _EPIN(E_STEPPERS, CS)
#endif
#ifndef D_MS1_PIN
#define D_MS1_PIN _EPIN(E_STEPPERS, MS1)
#endif
#if E_STEPPERS >= MAX_EXTRUDERS || !PIN_EXISTS(D_ENABLE)
#error "No E stepper plug left for D Axis!"
#endif
#endif
#undef _D_PINS
#define ___D_PINS D_STEP_PIN, D_DIR_PIN, D_ENABLE_PIN,
#ifdef D_CS_PIN
#define __D_PINS ___D_PINS D_CS_PIN,
#else
#define __D_PINS ___D_PINS
#endif
#ifdef D_MS1_PIN
#define _D_PINS __D_PINS D_MS1_PIN,
#else
#define _D_PINS __D_PINS
#endif
#define X2_E_INDEX INCREMENT(E_STEPPERS)
#else
#define X2_E_INDEX E_STEPPERS
#endif
// The X2 axis, if any, should be the next open extruder port
#if ENABLED(DUAL_X_CARRIAGE) || ENABLED(X_DUAL_STEPPER_DRIVERS)
#ifndef X2_STEP_PIN
#define X2_STEP_PIN _EPIN(E_STEPPERS, STEP)
#define X2_DIR_PIN _EPIN(E_STEPPERS, DIR)
#define X2_ENABLE_PIN _EPIN(E_STEPPERS, ENABLE)
#define X2_STEP_PIN _EPIN(X2_E_INDEX, STEP)
#define X2_DIR_PIN _EPIN(X2_E_INDEX, DIR)
#define X2_ENABLE_PIN _EPIN(X2_E_INDEX, ENABLE)
#ifndef X2_CS_PIN
#define X2_CS_PIN _EPIN(E_STEPPERS, CS)
#define X2_CS_PIN _EPIN(X2_E_INDEX, CS)
#endif
#if E_STEPPERS > 4 || !PIN_EXISTS(X2_ENABLE)
#if X2_E_INDEX >= MAX_EXTRUDERS || !PIN_EXISTS(X2_ENABLE)
#error "No E stepper plug left for X2!"
#endif
#endif
@@ -723,9 +772,9 @@
#else
#define _X2_PINS __X2_PINS
#endif
#define Y2_E_INDEX INCREMENT(E_STEPPERS)
#define Y2_E_INDEX INCREMENT(X2_E_INDEX)
#else
#define Y2_E_INDEX E_STEPPERS
#define Y2_E_INDEX X2_E_INDEX
#endif
// The Y2 axis, if any, should be the next open extruder port
@@ -737,7 +786,7 @@
#ifndef Y2_CS_PIN
#define Y2_CS_PIN _EPIN(Y2_E_INDEX, CS)
#endif
#if Y2_E_INDEX > 4 || !PIN_EXISTS(Y2_ENABLE)
#if Y2_E_INDEX >= MAX_EXTRUDERS || !PIN_EXISTS(Y2_ENABLE)
#error "No E stepper plug left for Y2!"
#endif
#endif
@@ -762,7 +811,7 @@
#ifndef Z2_CS_PIN
#define Z2_CS_PIN _EPIN(Z2_E_INDEX, CS)
#endif
#if Z2_E_INDEX > 4 || !PIN_EXISTS(Z2_ENABLE)
#if Z2_E_INDEX >= MAX_EXTRUDERS || !PIN_EXISTS(Z2_ENABLE)
#error "No E stepper plug left for Z2!"
#endif
#endif
@@ -782,7 +831,7 @@
PS_ON_PIN, HEATER_BED_PIN, FAN_PIN, FAN1_PIN, FAN2_PIN, CONTROLLER_FAN_PIN, \
_E0_PINS _E1_PINS _E2_PINS _E3_PINS _E4_PINS BED_PINS \
_H0_PINS _H1_PINS _H2_PINS _H3_PINS _H4_PINS \
_X2_PINS _Y2_PINS _Z2_PINS \
_D_PINS _X2_PINS _Y2_PINS _Z2_PINS \
}
#define HAS_DIGIPOTSS (PIN_EXISTS(DIGIPOTSS))
+12
View File
@@ -443,6 +443,18 @@
#if PIN_EXISTS(FIL_RUNOUT)
REPORT_NAME_DIGITAL(__LINE__, FIL_RUNOUT_PIN)
#endif
#if PIN_EXISTS(FIL_RUNOUT2)
REPORT_NAME_DIGITAL(__LINE__, FIL_RUNOUT2_PIN)
#endif
#if PIN_EXISTS(FIL_RUNOUT3)
REPORT_NAME_DIGITAL(__LINE__, FIL_RUNOUT3_PIN)
#endif
#if PIN_EXISTS(FIL_RUNOUT4)
REPORT_NAME_DIGITAL(__LINE__, FIL_RUNOUT4_PIN)
#endif
#if PIN_EXISTS(FIL_RUNOUT5)
REPORT_NAME_DIGITAL(__LINE__, FIL_RUNOUT5_PIN)
#endif
#if PIN_EXISTS(HEATER_0)
REPORT_NAME_DIGITAL(__LINE__, HEATER_0_PIN)
#endif
+2 -2
View File
@@ -153,7 +153,7 @@
* REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER
*/
#if ENABLED(ULTRA_LCD) && ENABLED(NEWPANEL)
#if ENABLED(ULTRA_LCD)
#define LCD_SDSS 28
#if ENABLED(ADC_KEYPAD)
#define SERVO0_PIN 27 // free for BLTouch/3D-Touch
@@ -193,7 +193,7 @@
#endif
#else
#define SERVO0_PIN 27
#endif // ULTRA_LCD && NEWPANEL
#endif
/**
* ====================================================================
+6 -5
View File
@@ -33,10 +33,8 @@
//
// TMC2130 Configuration_adv defaults for EinsyRambo
//
#if DISABLED(HAVE_TMC2130)
#error "You must enable TMC2130 support in Configuration_adv.h for EinsyRambo."
#elif DISABLED(X_IS_TMC2130) || DISABLED(Y_IS_TMC2130) || DISABLED(Z_IS_TMC2130) || DISABLED(E0_IS_TMC2130)
#error "You must enable ([XYZ]|E0)_IS_TMC2130 in Configuration_adv.h for EinsyRambo."
#if !AXIS_DRIVER_TYPE(X, TMC2130) || !AXIS_DRIVER_TYPE(Y, TMC2130) || !AXIS_DRIVER_TYPE(Z, TMC2130) || !AXIS_DRIVER_TYPE(E0, TMC2130)
#error "You must set ([XYZ]|E0)_DRIVER_TYPE to TMC2130 in Configuration.h for EinsyRambo."
#endif
// TMC2130 Diag Pins (currently just for reference)
@@ -120,7 +118,10 @@
#ifndef FAN_PIN
#define FAN_PIN 8
#endif
#define FAN1_PIN 6
#ifndef FAN1_PIN
#define FAN1_PIN 6
#endif
//
// Misc. Functions
+2 -4
View File
@@ -33,10 +33,8 @@
//
// TMC2130 Configuration_adv defaults for EinsyRetro
//
#if DISABLED(HAVE_TMC2130)
#error "You must enable TMC2130 support in Configuration_adv.h for EinsyRetro."
#elif DISABLED(X_IS_TMC2130) || DISABLED(Y_IS_TMC2130) || DISABLED(Z_IS_TMC2130) || DISABLED(E0_IS_TMC2130)
#error "You must enable ([XYZ]|E0)_IS_TMC2130 in Configuration_adv.h for EinsyRetro."
#if !AXIS_DRIVER_TYPE(X, TMC2130) || !AXIS_DRIVER_TYPE(Y, TMC2130) || !AXIS_DRIVER_TYPE(Z, TMC2130) || !AXIS_DRIVER_TYPE(E0, TMC2130)
#error "You must set ([XYZ]|E0)_DRIVER_TYPE to TMC2130 in Configuration.h for EinsyRetro."
#endif
// TMC2130 Diag Pins (currently just for reference)
+1
View File
@@ -36,6 +36,7 @@
//
// MOSFET changes
//
#define RAMPS_D9_PIN 8 // FAN (by default)
#define RAMPS_D10_PIN 9 // EXTRUDER 1
#define MOSFET_D_PIN 12 // EXTRUDER 2 or FAN
+47 -2
View File
@@ -30,7 +30,52 @@
#define IS_RAMPS_EFB
#define FAN2_PIN 44
#define ORIG_E0_AUTO_FAN_PIN 44
// FAN0 / D9 - Typically used for the part fan on Anycubic Delta devices
#define FAN_PIN 9
// FAN1 / D7 - Typically unused, can be allocated as Case Fan
// FAN2 / D44 - Typical Extruder Fan on Anycubic Delta devices
#define FAN2_PIN 44
#define ORIG_E0_AUTO_FAN_PIN 44
#include "pins_RAMPS.h"
// TODO 1.4 boards do have an E1 stepper driver. However the pin definitions
// from pins_RAMPS.h are incorrect for this board. e.g., Pin 44 is the Extruder fan.
#undef E1_STEP_PIN
#undef E1_DIR_PIN
#undef E1_ENABLE_PIN
#undef E1_CS_PIN
//
// AnyCubic made the following changes to 1.1.0-RC8
// If these are appropriate for your LCD let us know.
//
#if 0 && ENABLED(ULTRA_LCD)
// LCD Display output pins
#if ENABLED(NEWPANEL) && ENABLED(PANEL_ONE)
#undef LCD_PINS_D6
#define LCD_PINS_D6 57
#endif
// LCD Display input pins
#if ENABLED(NEWPANEL)
#if ENABLED(VIKI2) || ENABLED(miniVIKI)
#undef DOGLCD_A0
#define DOGLCD_A0 23
#elif ENABLED(ELB_FULL_GRAPHIC_CONTROLLER)
#undef BEEPER_PIN
#define BEEPER_PIN 33
#undef LCD_BACKLIGHT_PIN
#define LCD_BACKLIGHT_PIN 67
#endif
#elif ENABLED(MINIPANEL)
#undef BEEPER_PIN
#define BEEPER_PIN 33
#undef DOGLCD_A0
#define DOGLCD_A0 42
#endif
#endif // ULTRA_LCD
+1 -1
View File
@@ -43,7 +43,7 @@
//
// Servos
//
#define SERVO0_PIN 13 // UNTESTED
#define SERVO0_PIN 11
//
// Limit Switches
+249 -88
View File
@@ -100,13 +100,13 @@ volatile uint8_t Planner::block_buffer_head, // Index of the next block to be
uint16_t Planner::cleaning_buffer_counter; // A counter to disable queuing of blocks
uint8_t Planner::delay_before_delivering; // This counter delays delivery of blocks when queue becomes empty to allow the opportunity of merging blocks
uint32_t Planner::max_acceleration_mm_per_s2[XYZE_N], // (mm/s^2) M201 XYZE
Planner::max_acceleration_steps_per_s2[XYZE_N], // (steps/s^2) Derived from mm_per_s2
Planner::min_segment_time_us; // (µs) M205 B
uint32_t Planner::max_acceleration_mm_per_s2[NUM_AXIS_N], // (mm/s^2) M201 XYZE
Planner::max_acceleration_steps_per_s2[NUM_AXIS_N], // (steps/s^2) Derived from mm_per_s2
Planner::min_segment_time_us; // (µs) M205 Q
float Planner::max_feedrate_mm_s[XYZE_N], // (mm/s) M203 XYZE - Max speeds
Planner::axis_steps_per_mm[XYZE_N], // (steps) M92 XYZE - Steps per millimeter
Planner::steps_to_mm[XYZE_N], // (mm) Millimeters per step
float Planner::max_feedrate_mm_s[NUM_AXIS_N], // (mm/s) M203 XYZE - Max speeds
Planner::axis_steps_per_mm[NUM_AXIS_N], // (steps) M92 XYZE - Steps per millimeter
Planner::steps_to_mm[NUM_AXIS_N], // (mm) Millimeters per step
Planner::min_feedrate_mm_s, // (mm/s) M205 S - Minimum linear feedrate
Planner::acceleration, // (mm/s^2) M204 S - Normal acceleration. DEFAULT ACCELERATION for all printing moves.
Planner::retract_acceleration, // (mm/s^2) M204 R - Retract acceleration. Filament pull-back and push-forward while standing still in the other axes
@@ -123,7 +123,14 @@ float Planner::max_feedrate_mm_s[XYZE_N], // (mm/s) M203 XYZE - Max speeds
#endif
#endif
#else
float Planner::max_jerk[XYZE]; // (mm/s^2) M205 XYZE - The largest speed change requiring no acceleration.
float Planner::max_jerk[NUM_AXIS]; // (mm/s^2) M205 XYZE - The largest speed change requiring no acceleration.
#endif
#if ENABLED(LINE_BUILDUP_COMPENSATION_FEATURE)
float Planner::k0[MOV_AXIS],
Planner::k1[MOV_AXIS],
Planner::k2[MOV_AXIS],
Planner::sqrtk1[MOV_AXIS];
#endif
#if ENABLED(ABORT_ON_ENDSTOP_HIT_FEATURE_ENABLED)
@@ -206,7 +213,7 @@ float Planner::previous_speed[NUM_AXIS],
#endif
#if HAS_POSITION_FLOAT
float Planner::position_float[XYZE]; // Needed for accurate maths. Steps cannot be used!
float Planner::position_float[NUM_AXIS]; // Needed for accurate maths. Steps cannot be used!
#endif
#if ENABLED(ULTRA_LCD)
@@ -1137,7 +1144,13 @@ void Planner::recalculate() {
float high = 0.0;
for (uint8_t b = block_buffer_tail; b != block_buffer_head; b = next_block_index(b)) {
block_t* block = &block_buffer[b];
if (block->steps[X_AXIS] || block->steps[Y_AXIS] || block->steps[Z_AXIS]) {
if (
#if ENABLED(HANGPRINTER)
block->steps[A_AXIS] || block->steps[B_AXIS] || block->steps[C_AXIS] || block->steps[D_AXIS]
#else
block->steps[X_AXIS] || block->steps[Y_AXIS] || block->steps[Z_AXIS]
#endif
) {
const float se = (float)block->steps[E_AXIS] / block->step_event_count * SQRT(block->nominal_speed_sqr); // mm/sec;
NOLESS(high, se);
}
@@ -1514,6 +1527,9 @@ float Planner::get_axis_position_mm(const AxisEnum axis) {
#else
axis_steps = stepper.position(axis);
#endif
#if ENABLED(LINE_BUILDUP_COMPENSATION_FEATURE)
if (axis != E_AXIS) return (sq(axis_steps / k0[axis] + sqrtk1[axis]) - k1[axis]) / k2[axis];
#endif
return axis_steps * steps_to_mm[axis];
}
@@ -1522,23 +1538,34 @@ float Planner::get_axis_position_mm(const AxisEnum axis) {
*/
void Planner::synchronize() { while (has_blocks_queued() || cleaning_buffer_counter) idle(); }
#if ENABLED(UNREGISTERED_MOVE_SUPPORT)
#define COUNT_MOVE count_it
#else
#define COUNT_MOVE true
#endif
/**
* Planner::_buffer_steps
*
* Add a new linear movement to the planner queue (in terms of steps).
*
* target - target position in steps units
* fr_mm_s - (target) speed of the move
* extruder - target extruder
* millimeters - the length of the movement, if known
* target - target position in steps units
* target_float - target position in mm (HAS_POSITION_FLOAT)
* fr_mm_s - (target) speed of the move
* extruder - target extruder
* millimeters - the length of the movement, if known
* count_it - apply this move to the counters (UNREGISTERED_MOVE_SUPPORT)
*
* Returns true if movement was properly queued, false otherwise
*/
bool Planner::_buffer_steps(const int32_t (&target)[XYZE]
bool Planner::_buffer_steps(const int32_t (&target)[NUM_AXIS]
#if HAS_POSITION_FLOAT
, const float (&target_float)[XYZE]
, const float (&target_float)[NUM_AXIS]
#endif
, float fr_mm_s, const uint8_t extruder, const float &millimeters/*=0.0*/
#if ENABLED(UNREGISTERED_MOVE_SUPPORT)
, const bool count_it/*=true*/
#endif
, float fr_mm_s, const uint8_t extruder, const float &millimeters
) {
// If we are cleaning, do not accept queuing of movements
@@ -1554,6 +1581,9 @@ bool Planner::_buffer_steps(const int32_t (&target)[XYZE]
, target_float
#endif
, fr_mm_s, extruder, millimeters
#if ENABLED(UNREGISTERED_MOVE_SUPPORT)
, count_it
#endif
)) {
// Movement was not queued, probably because it was too short.
// Simply accept that as movement queued and done
@@ -1585,24 +1615,33 @@ bool Planner::_buffer_steps(const int32_t (&target)[XYZE]
*
* Fills a new linear movement in the block (in terms of steps).
*
* target - target position in steps units
* fr_mm_s - (target) speed of the move
* extruder - target extruder
* target - target position in steps units
* target_float - target position in mm (HAS_POSITION_FLOAT)
* fr_mm_s - (target) speed of the move
* extruder - target extruder
* millimeters - the length of the movement, if known
* count_it - apply this move to the counters (UNREGISTERED_MOVE_SUPPORT)
*
* Returns true is movement is acceptable, false otherwise
*/
bool Planner::_populate_block(block_t * const block, bool split_move,
const int32_t (&target)[XYZE]
const int32_t (&target)[NUM_AXIS]
#if HAS_POSITION_FLOAT
, const float (&target_float)[XYZE]
, const float (&target_float)[NUM_AXIS]
#endif
, float fr_mm_s, const uint8_t extruder, const float &millimeters/*=0.0*/
#if ENABLED(UNREGISTERED_MOVE_SUPPORT)
, const bool count_it/*=true*/
#endif
) {
const int32_t da = target[A_AXIS] - position[A_AXIS],
db = target[B_AXIS] - position[B_AXIS],
dc = target[C_AXIS] - position[C_AXIS];
dc = target[C_AXIS] - position[C_AXIS]
#if ENABLED(HANGPRINTER)
, dd = target[D_AXIS] - position[D_AXIS]
#endif
;
int32_t de = target[E_AXIS] - position[E_AXIS];
/* <-- add a slash to enable
@@ -1622,10 +1661,12 @@ bool Planner::_populate_block(block_t * const block, bool split_move,
if (de) {
#if ENABLED(PREVENT_COLD_EXTRUSION)
if (thermalManager.tooColdToExtrude(extruder)) {
position[E_AXIS] = target[E_AXIS]; // Behave as if the move really took place, but ignore E part
#if HAS_POSITION_FLOAT
position_float[E_AXIS] = target_float[E_AXIS];
#endif
if (COUNT_MOVE) {
position[E_AXIS] = target[E_AXIS]; // Behave as if the move really took place, but ignore E part
#if HAS_POSITION_FLOAT
position_float[E_AXIS] = target_float[E_AXIS];
#endif
}
de = 0; // no difference
SERIAL_ECHO_START();
SERIAL_ECHOLNPGM(MSG_ERR_COLD_EXTRUDE_STOP);
@@ -1633,10 +1674,12 @@ bool Planner::_populate_block(block_t * const block, bool split_move,
#endif // PREVENT_COLD_EXTRUSION
#if ENABLED(PREVENT_LENGTHY_EXTRUDE)
if (ABS(de * e_factor[extruder]) > (int32_t)axis_steps_per_mm[E_AXIS_N] * (EXTRUDE_MAXLENGTH)) { // It's not important to get max. extrusion length in a precision < 1mm, so save some cycles and cast to int
position[E_AXIS] = target[E_AXIS]; // Behave as if the move really took place, but ignore E part
#if HAS_POSITION_FLOAT
position_float[E_AXIS] = target_float[E_AXIS];
#endif
if (COUNT_MOVE) {
position[E_AXIS] = target[E_AXIS]; // Behave as if the move really took place, but ignore E part
#if HAS_POSITION_FLOAT
position_float[E_AXIS] = target_float[E_AXIS];
#endif
}
de = 0; // no difference
SERIAL_ECHO_START();
SERIAL_ECHOLNPGM(MSG_ERR_LONG_EXTRUDE_STOP);
@@ -1665,6 +1708,11 @@ bool Planner::_populate_block(block_t * const block, bool split_move,
if (dc < 0) SBI(dm, Z_HEAD); // ...and Z
if (db + dc < 0) SBI(dm, B_AXIS); // Motor B direction
if (CORESIGN(db - dc) < 0) SBI(dm, C_AXIS); // Motor C direction
#elif ENABLED(HANGPRINTER)
if (da < 0) SBI(dm, A_AXIS);
if (db < 0) SBI(dm, B_AXIS);
if (dc < 0) SBI(dm, C_AXIS);
if (dd < 0) SBI(dm, D_AXIS);
#else
if (da < 0) SBI(dm, X_AXIS);
if (db < 0) SBI(dm, Y_AXIS);
@@ -1681,6 +1729,11 @@ bool Planner::_populate_block(block_t * const block, bool split_move,
// Set direction bits
block->direction_bits = dm;
// Specify if block is to be counted or not
#if ENABLED(UNREGISTERED_MOVE_SUPPORT)
block->count_it = count_it;
#endif
// Number of steps for each axis
// See http://www.corexy.com/theory.html
#if CORE_IS_XY
@@ -1699,6 +1752,11 @@ bool Planner::_populate_block(block_t * const block, bool split_move,
block->steps[A_AXIS] = ABS(da);
block->steps[B_AXIS] = ABS(db);
block->steps[Z_AXIS] = ABS(dc);
#elif ENABLED(HANGPRINTER)
block->steps[A_AXIS] = ABS(da);
block->steps[B_AXIS] = ABS(db);
block->steps[C_AXIS] = ABS(dc);
block->steps[D_AXIS] = ABS(dd);
#else
// default non-h-bot planning
block->steps[A_AXIS] = ABS(da);
@@ -1707,7 +1765,14 @@ bool Planner::_populate_block(block_t * const block, bool split_move,
#endif
block->steps[E_AXIS] = esteps;
block->step_event_count = MAX4(block->steps[A_AXIS], block->steps[B_AXIS], block->steps[C_AXIS], esteps);
block->step_event_count = (
#if ENABLED(HANGPRINTER)
MAX5(block->steps[A_AXIS], block->steps[B_AXIS], block->steps[C_AXIS], block->steps[D_AXIS], esteps)
#else
MAX4(block->steps[A_AXIS], block->steps[B_AXIS], block->steps[C_AXIS], esteps)
#endif
);
// Bail if this is a zero-length block
if (block->step_event_count < MIN_STEPS_PER_SEGMENT) return false;
@@ -1715,13 +1780,7 @@ bool Planner::_populate_block(block_t * const block, bool split_move,
// For a mixing extruder, get a magnified esteps for each
#if ENABLED(MIXING_EXTRUDER)
for (uint8_t i = 0; i < MIXING_STEPPERS; i++)
block->mix_steps[i] = mixing_factor[i] * (
#if ENABLED(LIN_ADVANCE)
esteps
#else
block->step_event_count
#endif
);
block->mix_steps[i] = mixing_factor[i] * esteps;
#endif
#if FAN_COUNT > 0
@@ -1761,7 +1820,7 @@ bool Planner::_populate_block(block_t * const block, bool split_move,
enable_Z();
}
if (block->steps[X_AXIS]) enable_X();
#else
#elif DISABLED(HANGPRINTER) // Hangprinters X, Y, Z, E0 axes should always be enabled anyways
if (block->steps[X_AXIS]) enable_X();
if (block->steps[Y_AXIS]) enable_Y();
#if DISABLED(Z_LATE_ENABLE)
@@ -1902,14 +1961,21 @@ bool Planner::_populate_block(block_t * const block, bool split_move,
delta_mm[C_AXIS] = CORESIGN(db - dc) * steps_to_mm[C_AXIS];
#endif
#else
float delta_mm[ABCE];
float delta_mm[NUM_AXIS];
delta_mm[A_AXIS] = da * steps_to_mm[A_AXIS];
delta_mm[B_AXIS] = db * steps_to_mm[B_AXIS];
delta_mm[C_AXIS] = dc * steps_to_mm[C_AXIS];
#if ENABLED(HANGPRINTER)
delta_mm[D_AXIS] = dd * steps_to_mm[D_AXIS];
#endif
#endif
delta_mm[E_AXIS] = esteps_float * steps_to_mm[E_AXIS_N];
if (block->steps[A_AXIS] < MIN_STEPS_PER_SEGMENT && block->steps[B_AXIS] < MIN_STEPS_PER_SEGMENT && block->steps[C_AXIS] < MIN_STEPS_PER_SEGMENT) {
if (block->steps[A_AXIS] < MIN_STEPS_PER_SEGMENT && block->steps[B_AXIS] < MIN_STEPS_PER_SEGMENT && block->steps[C_AXIS] < MIN_STEPS_PER_SEGMENT
#if ENABLED(HANGPRINTER)
&& block->steps[D_AXIS] < MIN_STEPS_PER_SEGMENT
#endif
) {
block->millimeters = ABS(delta_mm[E_AXIS]);
}
else if (!millimeters) {
@@ -1920,6 +1986,8 @@ bool Planner::_populate_block(block_t * const block, bool split_move,
sq(delta_mm[X_HEAD]) + sq(delta_mm[Y_AXIS]) + sq(delta_mm[Z_HEAD])
#elif CORE_IS_YZ
sq(delta_mm[X_AXIS]) + sq(delta_mm[Y_HEAD]) + sq(delta_mm[Z_HEAD])
#elif ENABLED(HANGPRINTER)
sq(delta_mm[A_AXIS]) + sq(delta_mm[B_AXIS]) + sq(delta_mm[C_AXIS]) + sq(delta_mm[D_AXIS])
#else
sq(delta_mm[X_AXIS]) + sq(delta_mm[Y_AXIS]) + sq(delta_mm[Z_AXIS])
#endif
@@ -2005,7 +2073,7 @@ bool Planner::_populate_block(block_t * const block, bool split_move,
// Calculate and limit speed in mm/sec for each axis
float current_speed[NUM_AXIS], speed_factor = 1.0f; // factor <1 decreases speed
LOOP_XYZE(i) {
LOOP_NUM_AXIS(i) {
const float cs = ABS((current_speed[i] = delta_mm[i] * inverse_secs));
#if ENABLED(DISTINCT_E_FACTORS)
if (i == E_AXIS) i += extruder;
@@ -2053,7 +2121,7 @@ bool Planner::_populate_block(block_t * const block, bool split_move,
// Correct the speed
if (speed_factor < 1.0f) {
LOOP_XYZE(i) current_speed[i] *= speed_factor;
LOOP_NUM_AXIS(i) current_speed[i] *= speed_factor;
block->nominal_rate *= speed_factor;
block->nominal_speed_sqr = block->nominal_speed_sqr * sq(speed_factor);
}
@@ -2061,7 +2129,11 @@ bool Planner::_populate_block(block_t * const block, bool split_move,
// Compute and limit the acceleration rate for the trapezoid generator.
const float steps_per_mm = block->step_event_count * inverse_millimeters;
uint32_t accel;
if (!block->steps[A_AXIS] && !block->steps[B_AXIS] && !block->steps[C_AXIS]) {
if (!block->steps[A_AXIS] && !block->steps[B_AXIS] && !block->steps[C_AXIS]
#if ENABLED(HANGPRINTER)
&& !block->steps[D_AXIS]
#endif
) {
// convert to: acceleration steps/sec^2
accel = CEIL(retract_acceleration * steps_per_mm);
#if ENABLED(LIN_ADVANCE)
@@ -2148,12 +2220,18 @@ bool Planner::_populate_block(block_t * const block, bool split_move,
LIMIT_ACCEL_LONG(A_AXIS, 0);
LIMIT_ACCEL_LONG(B_AXIS, 0);
LIMIT_ACCEL_LONG(C_AXIS, 0);
#if ENABLED(HANGPRINTER)
LIMIT_ACCEL_LONG(D_AXIS, 0);
#endif
LIMIT_ACCEL_LONG(E_AXIS, ACCEL_IDX);
}
else {
LIMIT_ACCEL_FLOAT(A_AXIS, 0);
LIMIT_ACCEL_FLOAT(B_AXIS, 0);
LIMIT_ACCEL_FLOAT(C_AXIS, 0);
#if ENABLED(HANGPRINTER)
LIMIT_ACCEL_FLOAT(D_AXIS, 0);
#endif
LIMIT_ACCEL_FLOAT(E_AXIS, ACCEL_IDX);
}
}
@@ -2279,27 +2357,27 @@ bool Planner::_populate_block(block_t * const block, bool split_move,
/**
* Adapted from Průša MKS firmware
* https://github.com/prusa3d/Prusa-Firmware
*
* Start with a safe speed (from which the machine may halt to stop immediately).
*/
const float nominal_speed = SQRT(block->nominal_speed_sqr);
// Exit speed limited by a jerk to full halt of a previous last segment
static float previous_safe_speed;
const float nominal_speed = SQRT(block->nominal_speed_sqr);
// Start with a safe speed (from which the machine may halt to stop immediately).
float safe_speed = nominal_speed;
uint8_t limited = 0;
LOOP_XYZE(i) {
const float jerk = ABS(current_speed[i]), maxj = max_jerk[i];
if (jerk > maxj) {
if (limited) {
const float mjerk = maxj * nominal_speed;
if (jerk * safe_speed > mjerk) safe_speed = mjerk / jerk;
LOOP_NUM_AXIS(i) {
const float jerk = ABS(current_speed[i]), // cs : Starting from zero, change in speed for this axis
maxj = max_jerk[i]; // mj : The max jerk setting for this axis
if (jerk > maxj) { // cs > mj : New current speed too fast?
if (limited) { // limited already?
const float mjerk = nominal_speed * maxj; // ns*mj
if (jerk * safe_speed > mjerk) safe_speed = mjerk / jerk; // ns*mj/cs
}
else {
++limited;
safe_speed = maxj;
safe_speed *= maxj / jerk; // Initial limit: ns*mj/cs
++limited; // Initially limited
}
}
}
@@ -2321,7 +2399,7 @@ bool Planner::_populate_block(block_t * const block, bool split_move,
// Now limit the jerk in all axes.
const float smaller_speed_factor = vmax_junction / previous_nominal_speed;
LOOP_XYZE(axis) {
LOOP_NUM_AXIS(axis) {
// Limit an axis. We have to differentiate: coasting, reversal of an axis, full stop.
float v_exit = previous_speed[axis] * smaller_speed_factor,
v_entry = current_speed[axis];
@@ -2381,12 +2459,22 @@ bool Planner::_populate_block(block_t * const block, bool split_move,
COPY(previous_speed, current_speed);
previous_nominal_speed_sqr = block->nominal_speed_sqr;
// Update the position
static_assert(COUNT(target) > 1, "Parameter to _buffer_steps must be (&target)[XYZE]!");
COPY(position, target);
#if HAS_POSITION_FLOAT
COPY(position_float, target_float);
#endif
// Update the position (only when a move was queued)
static_assert(COUNT(target) > 1, "Parameter to _populate_block must be (&target)["
#if ENABLED(HANGPRINTER)
"ABCD"
#else
"XYZ"
#endif
"E]!"
);
if (COUNT_MOVE) {
COPY(position, target);
#if HAS_POSITION_FLOAT
COPY(position_float, target_float);
#endif
}
// Movement was accepted
return true;
@@ -2409,6 +2497,9 @@ void Planner::buffer_sync_block() {
block->position[A_AXIS] = position[A_AXIS];
block->position[B_AXIS] = position[B_AXIS];
block->position[C_AXIS] = position[C_AXIS];
#if ENABLED(HANGPRINTER)
block->position[D_AXIS] = position[D_AXIS];
#endif
block->position[E_AXIS] = position[E_AXIS];
// If this is the first added movement, reload the delay, otherwise, cancel it.
@@ -2438,7 +2529,15 @@ void Planner::buffer_sync_block() {
* extruder - target extruder
* millimeters - the length of the movement, if known
*/
bool Planner::buffer_segment(const float &a, const float &b, const float &c, const float &e, const float &fr_mm_s, const uint8_t extruder, const float &millimeters/*=0.0*/) {
bool Planner::buffer_segment(const float &a, const float &b, const float &c
#if ENABLED(HANGPRINTER)
, const float &d
#endif
, const float &e, const float &fr_mm_s, const uint8_t extruder, const float &millimeters/*=0.0*/
#if ENABLED(UNREGISTERED_MOVE_SUPPORT)
, bool count_it /* = true */
#endif
) {
// If we are cleaning, do not accept queuing of movements
if (cleaning_buffer_counter) return false;
@@ -2453,23 +2552,40 @@ bool Planner::buffer_segment(const float &a, const float &b, const float &c, con
// The target position of the tool in absolute steps
// Calculate target position in absolute steps
const int32_t target[ABCE] = {
LROUND(a * axis_steps_per_mm[A_AXIS]),
LROUND(b * axis_steps_per_mm[B_AXIS]),
LROUND(c * axis_steps_per_mm[C_AXIS]),
const int32_t target[NUM_AXIS] = {
#if ENABLED(LINE_BUILDUP_COMPENSATION_FEATURE)
LROUND(k0[A_AXIS] * (SQRT(k1[A_AXIS] + a * k2[A_AXIS]) - sqrtk1[A_AXIS])),
LROUND(k0[B_AXIS] * (SQRT(k1[B_AXIS] + b * k2[B_AXIS]) - sqrtk1[B_AXIS])),
LROUND(k0[C_AXIS] * (SQRT(k1[C_AXIS] + c * k2[C_AXIS]) - sqrtk1[C_AXIS])),
LROUND(k0[D_AXIS] * (SQRT(k1[D_AXIS] + d * k2[D_AXIS]) - sqrtk1[D_AXIS])),
#else
LROUND(a * axis_steps_per_mm[A_AXIS]),
LROUND(b * axis_steps_per_mm[B_AXIS]),
LROUND(c * axis_steps_per_mm[C_AXIS]),
#if ENABLED(HANGPRINTER)
LROUND(d * axis_steps_per_mm[D_AXIS]),
#endif
#endif
LROUND(e * axis_steps_per_mm[E_AXIS_N])
};
#if HAS_POSITION_FLOAT
const float target_float[XYZE] = { a, b, c, e };
const float target_float[NUM_AXIS] = { a, b, c
#if ENABLED(HANGPRINTER)
, d
#endif
, e
};
#endif
// DRYRUN prevents E moves from taking place
if (DEBUGGING(DRYRUN)) {
position[E_AXIS] = target[E_AXIS];
#if HAS_POSITION_FLOAT
position_float[E_AXIS] = e;
#endif
if (COUNT_MOVE) {
position[E_AXIS] = target[E_AXIS];
#if HAS_POSITION_FLOAT
position_float[E_AXIS] = e;
#endif
}
}
/* <-- add a slash to enable
@@ -2487,13 +2603,18 @@ bool Planner::buffer_segment(const float &a, const float &b, const float &c, con
#endif
SERIAL_ECHOPAIR(" (", position[Y_AXIS]);
SERIAL_ECHOPAIR("->", target[Y_AXIS]);
#if ENABLED(DELTA)
#if ENABLED(DELTA) || ENABLED(HANGPRINTER)
SERIAL_ECHOPAIR(") C:", c);
#else
SERIAL_ECHOPAIR(") Z:", c);
#endif
SERIAL_ECHOPAIR(" (", position[Z_AXIS]);
SERIAL_ECHOPAIR("->", target[Z_AXIS]);
#if ENABLED(HANGPRINTER)
SERIAL_ECHOPAIR(") D:", d);
SERIAL_ECHOPAIR(" (", position[D_AXIS]);
SERIAL_ECHOPAIR("->", target[D_AXIS]);
#endif
SERIAL_ECHOPAIR(") E:", e);
SERIAL_ECHOPAIR(" (", position[E_AXIS]);
SERIAL_ECHOPAIR("->", target[E_AXIS]);
@@ -2501,12 +2622,15 @@ bool Planner::buffer_segment(const float &a, const float &b, const float &c, con
//*/
// Queue the movement
if (
if (
!_buffer_steps(target
#if HAS_POSITION_FLOAT
, target_float
#endif
, fr_mm_s, extruder, millimeters
#if ENABLED(UNREGISTERED_MOVE_SUPPORT)
, count_it
#endif
)
) return false;
@@ -2521,18 +2645,41 @@ bool Planner::buffer_segment(const float &a, const float &b, const float &c, con
* On CORE machines stepper ABC will be translated from the given XYZ.
*/
void Planner::_set_position_mm(const float &a, const float &b, const float &c, const float &e) {
void Planner::_set_position_mm(const float &a, const float &b, const float &c
#if ENABLED(HANGPRINTER)
, const float &d
#endif
, const float &e
) {
#if ENABLED(DISTINCT_E_FACTORS)
last_extruder = active_extruder;
#endif
position[A_AXIS] = LROUND(a * axis_steps_per_mm[A_AXIS]),
position[B_AXIS] = LROUND(b * axis_steps_per_mm[B_AXIS]),
position[C_AXIS] = LROUND(c * axis_steps_per_mm[C_AXIS]),
#if ENABLED(LINE_BUILDUP_COMPENSATION_FEATURE)
position[A_AXIS] = LROUND(k0[A_AXIS] * (SQRT(k1[A_AXIS] + a * k2[A_AXIS]) - sqrtk1[A_AXIS])),
position[B_AXIS] = LROUND(k0[B_AXIS] * (SQRT(k1[B_AXIS] + b * k2[B_AXIS]) - sqrtk1[B_AXIS])),
position[C_AXIS] = LROUND(k0[C_AXIS] * (SQRT(k1[C_AXIS] + c * k2[C_AXIS]) - sqrtk1[C_AXIS])),
position[D_AXIS] = LROUND(k0[D_AXIS] * (SQRT(k1[D_AXIS] + d * k2[D_AXIS]) - sqrtk1[D_AXIS])),
#else
position[A_AXIS] = LROUND(a * axis_steps_per_mm[A_AXIS]);
position[B_AXIS] = LROUND(b * axis_steps_per_mm[B_AXIS]);
position[C_AXIS] = LROUND(axis_steps_per_mm[C_AXIS] * (c + (
#if !IS_KINEMATIC && ENABLED(AUTO_BED_LEVELING_UBL)
leveling_active ? ubl.get_z_correction(a, b) :
#endif
0)
));
#if ENABLED(HANGPRINTER)
position[D_AXIS] = LROUND(d * axis_steps_per_mm[D_AXIS]),
#endif
#endif
position[E_AXIS] = LROUND(e * axis_steps_per_mm[_EINDEX]);
#if HAS_POSITION_FLOAT
position_float[A_AXIS] = a;
position_float[B_AXIS] = b;
position_float[C_AXIS] = c;
#if ENABLED(HANGPRINTER)
position_float[D_AXIS] = d;
#endif
position_float[E_AXIS] = e;
#endif
if (has_blocks_queued()) {
@@ -2541,21 +2688,32 @@ void Planner::_set_position_mm(const float &a, const float &b, const float &c, c
buffer_sync_block();
}
else
stepper.set_position(position[A_AXIS], position[B_AXIS], position[C_AXIS], position[E_AXIS]);
stepper.set_position(position[A_AXIS], position[B_AXIS], position[C_AXIS],
#if ENABLED(HANGPRINTER)
position[D_AXIS],
#endif
position[E_AXIS]
);
}
void Planner::set_position_mm_kinematic(const float (&cart)[XYZE]) {
#if PLANNER_LEVELING
float raw[XYZ] = { cart[X_AXIS], cart[Y_AXIS], cart[Z_AXIS] };
apply_leveling(raw);
#elif ENABLED(HANGPRINTER)
float raw[XYZ] = { cart[X_AXIS], cart[Y_AXIS], cart[Z_AXIS] };
#else
const float (&raw)[XYZE] = cart;
#endif
#if IS_KINEMATIC
inverse_kinematics(raw);
_set_position_mm(delta[A_AXIS], delta[B_AXIS], delta[C_AXIS], cart[E_AXIS]);
#if ENABLED(HANGPRINTER)
_set_position_mm(line_lengths[A_AXIS], line_lengths[B_AXIS], line_lengths[C_AXIS], line_lengths[D_AXIS], cart[E_CART]);
#else
_set_position_mm(delta[A_AXIS], delta[B_AXIS], delta[C_AXIS], cart[E_CART]);
#endif
#else
_set_position_mm(raw[X_AXIS], raw[Y_AXIS], raw[Z_AXIS], cart[E_AXIS]);
_set_position_mm(raw[X_AXIS], raw[Y_AXIS], raw[Z_AXIS], cart[E_CART]);
#endif
}
@@ -2569,14 +2727,17 @@ void Planner::set_position_mm(const AxisEnum axis, const float &v) {
#else
const uint8_t axis_index = axis;
#endif
position[axis] = LROUND(v * axis_steps_per_mm[axis_index]);
position[axis] = LROUND(axis_steps_per_mm[axis_index] * (v + (
#if ENABLED(AUTO_BED_LEVELING_UBL)
axis == Z_AXIS && leveling_active ? ubl.get_z_correction(current_position[X_AXIS], current_position[Y_AXIS]) :
#endif
0)
));
#if HAS_POSITION_FLOAT
position_float[axis] = v;
#endif
if (has_blocks_queued()) {
//previous_speed[axis] = 0.0;
if (has_blocks_queued())
buffer_sync_block();
}
else
stepper.set_position(axis, position[axis]);
}
@@ -2589,7 +2750,7 @@ void Planner::reset_acceleration_rates() {
#define AXIS_CONDITION true
#endif
uint32_t highest_rate = 1;
LOOP_XYZE_N(i) {
LOOP_NUM_AXIS_N(i) {
max_acceleration_steps_per_s2[i] = max_acceleration_mm_per_s2[i] * axis_steps_per_mm[i];
if (AXIS_CONDITION) NOLESS(highest_rate, max_acceleration_steps_per_s2[i]);
}
@@ -2601,7 +2762,7 @@ void Planner::reset_acceleration_rates() {
// Recalculate position, steps_to_mm if axis_steps_per_mm changes!
void Planner::refresh_positioning() {
LOOP_XYZE_N(i) steps_to_mm[i] = 1.0f / axis_steps_per_mm[i];
LOOP_NUM_AXIS_N(i) steps_to_mm[i] = 1.0f / axis_steps_per_mm[i];
set_position_mm_kinematic(current_position);
reset_acceleration_rates();
}
+93 -20
View File
@@ -76,6 +76,10 @@ typedef struct {
volatile uint8_t flag; // Block flags (See BlockFlag enum above) - Modified by ISR and main thread!
#if ENABLED(UNREGISTERED_MOVE_SUPPORT)
bool count_it;
#endif
// Fields used by the motion planner to manage acceleration
float nominal_speed_sqr, // The nominal speed for this block in (mm/sec)^2
entry_speed_sqr, // Entry speed at previous-current junction in (mm/sec)^2
@@ -188,12 +192,12 @@ class Planner {
// May be auto-adjusted by a filament width sensor
#endif
static uint32_t max_acceleration_mm_per_s2[XYZE_N], // (mm/s^2) M201 XYZE
max_acceleration_steps_per_s2[XYZE_N], // (steps/s^2) Derived from mm_per_s2
min_segment_time_us; // (µs) M205 B
static float max_feedrate_mm_s[XYZE_N], // (mm/s) M203 XYZE - Max speeds
axis_steps_per_mm[XYZE_N], // (steps) M92 XYZE - Steps per millimeter
steps_to_mm[XYZE_N], // (mm) Millimeters per step
static uint32_t max_acceleration_mm_per_s2[NUM_AXIS_N], // (mm/s^2) M201 XYZE
max_acceleration_steps_per_s2[NUM_AXIS_N], // (steps/s^2) Derived from mm_per_s2
min_segment_time_us; // (µs) M205 Q
static float max_feedrate_mm_s[NUM_AXIS_N], // (mm/s) M203 XYZE - Max speeds
axis_steps_per_mm[NUM_AXIS_N], // (steps) M92 XYZE - Steps per millimeter
steps_to_mm[NUM_AXIS_N], // (mm) Millimeters per step
min_feedrate_mm_s, // (mm/s) M205 S - Minimum linear feedrate
acceleration, // (mm/s^2) M204 S - Normal acceleration. DEFAULT ACCELERATION for all printing moves.
retract_acceleration, // (mm/s^2) M204 R - Retract acceleration. Filament pull-back and push-forward while standing still in the other axes
@@ -210,7 +214,19 @@ class Planner {
#endif
#endif
#else
static float max_jerk[XYZE]; // (mm/s^2) M205 XYZE - The largest speed change requiring no acceleration.
static float max_jerk[NUM_AXIS]; // (mm/s^2) M205 XYZE - The largest speed change requiring no acceleration.
#endif
#if ENABLED(LINE_BUILDUP_COMPENSATION_FEATURE)
/*
* Parameters for calculating target[]
* See buildup compensation theory:
* https://vitana.se/opr3d/tbear/2017.html#hangprinter_project_29
*/
static float k0[MOV_AXIS],
k1[MOV_AXIS],
k2[MOV_AXIS],
sqrtk1[MOV_AXIS];
#endif
#if HAS_LEVELING
@@ -230,7 +246,7 @@ class Planner {
#endif
#if HAS_POSITION_FLOAT
static float position_float[XYZE];
static float position_float[NUM_AXIS];
#endif
#if ENABLED(SKEW_CORRECTION)
@@ -429,11 +445,17 @@ class Planner {
#define ARG_X float rx
#define ARG_Y float ry
#define ARG_Z float rz
#if ENABLED(HANGPRINTER)
#define ARG_E1 float re1
#endif
static void unapply_leveling(float raw[XYZ]);
#else
#define ARG_X const float &rx
#define ARG_Y const float &ry
#define ARG_Z const float &rz
#if ENABLED(HANGPRINTER)
#define ARG_E1 const float &re1
#endif
#endif
// Number of moves currently in the planner including the busy block, if any
@@ -477,14 +499,18 @@ class Planner {
* fr_mm_s - (target) speed of the move
* extruder - target extruder
* millimeters - the length of the movement, if known
* count_it - apply this move to the counters (UNREGISTERED_MOVE_SUPPORT)
*
* Returns true if movement was buffered, false otherwise
*/
static bool _buffer_steps(const int32_t (&target)[XYZE]
static bool _buffer_steps(const int32_t (&target)[NUM_AXIS]
#if HAS_POSITION_FLOAT
, const float (&target_float)[XYZE]
, const float (&target_float)[NUM_AXIS]
#endif
, float fr_mm_s, const uint8_t extruder, const float &millimeters=0.0
#if ENABLED(UNREGISTERED_MOVE_SUPPORT)
, const bool count_it=true
#endif
);
/**
@@ -496,15 +522,19 @@ class Planner {
* fr_mm_s - (target) speed of the move
* extruder - target extruder
* millimeters - the length of the movement, if known
* count_it - apply this move to the counters (UNREGISTERED_MOVE_SUPPORT)
*
* Returns true is movement is acceptable, false otherwise
*/
static bool _populate_block(block_t * const block, bool split_move,
const int32_t (&target)[XYZE]
const int32_t (&target)[NUM_AXIS]
#if HAS_POSITION_FLOAT
, const float (&target_float)[XYZE]
, const float (&target_float)[NUM_AXIS]
#endif
, float fr_mm_s, const uint8_t extruder, const float &millimeters=0.0
#if ENABLED(UNREGISTERED_MOVE_SUPPORT)
, const bool count_it=true
#endif
);
/**
@@ -521,13 +551,28 @@ class Planner {
* Leveling and kinematics should be applied ahead of calling this.
*
* a,b,c,e - target positions in mm and/or degrees
* (a, b, c, d, e for Hangprinter)
* fr_mm_s - (target) speed of the move
* extruder - target extruder
* millimeters - the length of the movement, if known
* count_it - remember this move in its counters (UNREGISTERED_MOVE_SUPPORT)
*/
static bool buffer_segment(const float &a, const float &b, const float &c, const float &e, const float &fr_mm_s, const uint8_t extruder, const float &millimeters=0.0);
static bool buffer_segment(const float &a, const float &b, const float &c,
#if ENABLED(HANGPRINTER)
const float &d,
#endif
const float &e, const float &fr_mm_s, const uint8_t extruder, const float &millimeters=0.0
#if ENABLED(UNREGISTERED_MOVE_SUPPORT)
, bool count_it=true
#endif
);
static void _set_position_mm(const float &a, const float &b, const float &c, const float &e);
static void _set_position_mm(const float &a, const float &b, const float &c,
#if ENABLED(HANGPRINTER)
const float &d,
#endif
const float &e
);
/**
* Add a new linear movement to the buffer.
@@ -538,15 +583,26 @@ class Planner {
* (Cartesians may also call buffer_line_kinematic.)
*
* rx,ry,rz,e - target position in mm or degrees
* (rx, ry, rz, re1 for Hangprinter)
* fr_mm_s - (target) speed of the move (mm/s)
* extruder - target extruder
* millimeters - the length of the movement, if known
*/
FORCE_INLINE static bool buffer_line(ARG_X, ARG_Y, ARG_Z, const float &e, const float &fr_mm_s, const uint8_t extruder, const float millimeters = 0.0) {
FORCE_INLINE static bool buffer_line(ARG_X, ARG_Y, ARG_Z,
#if ENABLED(HANGPRINTER)
ARG_E1,
#endif
const float &e, const float &fr_mm_s, const uint8_t extruder, const float millimeters = 0.0
) {
#if PLANNER_LEVELING && IS_CARTESIAN
apply_leveling(rx, ry, rz);
#endif
return buffer_segment(rx, ry, rz, e, fr_mm_s, extruder, millimeters);
return buffer_segment(rx, ry, rz,
#if ENABLED(HANGPRINTER)
re1,
#endif
e, fr_mm_s, extruder, millimeters
);
}
/**
@@ -568,9 +624,16 @@ class Planner {
#endif
#if IS_KINEMATIC
inverse_kinematics(raw);
return buffer_segment(delta[A_AXIS], delta[B_AXIS], delta[C_AXIS], cart[E_AXIS], fr_mm_s, extruder, millimeters);
return buffer_segment(
#if ENABLED(HANGPRINTER)
line_lengths[A_AXIS], line_lengths[B_AXIS], line_lengths[C_AXIS], line_lengths[D_AXIS]
#else
delta[A_AXIS], delta[B_AXIS], delta[C_AXIS]
#endif
, cart[E_CART], fr_mm_s, extruder, millimeters
);
#else
return buffer_segment(raw[X_AXIS], raw[Y_AXIS], raw[Z_AXIS], cart[E_AXIS], fr_mm_s, extruder, millimeters);
return buffer_segment(raw[X_AXIS], raw[Y_AXIS], raw[Z_AXIS], cart[E_CART], fr_mm_s, extruder, millimeters);
#endif
}
@@ -583,11 +646,21 @@ class Planner {
*
* Clears previous speed values.
*/
FORCE_INLINE static void set_position_mm(ARG_X, ARG_Y, ARG_Z, const float &e) {
FORCE_INLINE static void set_position_mm(ARG_X, ARG_Y, ARG_Z,
#if ENABLED(HANGPRINTER)
ARG_E1,
#endif
const float &e
) {
#if PLANNER_LEVELING && IS_CARTESIAN
apply_leveling(rx, ry, rz);
#endif
_set_position_mm(rx, ry, rz, e);
_set_position_mm(rx, ry, rz,
#if ENABLED(HANGPRINTER)
re1,
#endif
e
);
}
static void set_position_mm_kinematic(const float (&cart)[XYZE]);
static void set_position_mm(const AxisEnum axis, const float &v);
+19 -19
View File
@@ -105,17 +105,17 @@ inline static float dist1(float x1, float y1, float x2, float y2) { return ABS(x
* the mitigation offered by MIN_STEP and the small computational
* power available on Arduino, I think it is not wise to implement it.
*/
void cubic_b_spline(const float position[NUM_AXIS], const float target[NUM_AXIS], const float offset[4], float fr_mm_s, uint8_t extruder) {
void cubic_b_spline(const float pos[XYZE], const float cart_target[XYZE], const float offset[4], float fr_mm_s, uint8_t extruder) {
// Absolute first and second control points are recovered.
const float first0 = position[X_AXIS] + offset[0],
first1 = position[Y_AXIS] + offset[1],
second0 = target[X_AXIS] + offset[2],
second1 = target[Y_AXIS] + offset[3];
const float first0 = pos[X_AXIS] + offset[0],
first1 = pos[Y_AXIS] + offset[1],
second0 = cart_target[X_AXIS] + offset[2],
second1 = cart_target[Y_AXIS] + offset[3];
float t = 0;
float bez_target[4];
bez_target[X_AXIS] = position[X_AXIS];
bez_target[Y_AXIS] = position[Y_AXIS];
float bez_target[XYZE];
bez_target[X_AXIS] = pos[X_AXIS];
bez_target[Y_AXIS] = pos[Y_AXIS];
float step = MAX_STEP;
millis_t next_idle_ms = millis() + 200UL;
@@ -134,13 +134,13 @@ void cubic_b_spline(const float position[NUM_AXIS], const float target[NUM_AXIS]
bool did_reduce = false;
float new_t = t + step;
NOMORE(new_t, 1);
float new_pos0 = eval_bezier(position[X_AXIS], first0, second0, target[X_AXIS], new_t),
new_pos1 = eval_bezier(position[Y_AXIS], first1, second1, target[Y_AXIS], new_t);
float new_pos0 = eval_bezier(pos[X_AXIS], first0, second0, cart_target[X_AXIS], new_t),
new_pos1 = eval_bezier(pos[Y_AXIS], first1, second1, cart_target[Y_AXIS], new_t);
for (;;) {
if (new_t - t < (MIN_STEP)) break;
const float candidate_t = 0.5f * (t + new_t),
candidate_pos0 = eval_bezier(position[X_AXIS], first0, second0, target[X_AXIS], candidate_t),
candidate_pos1 = eval_bezier(position[Y_AXIS], first1, second1, target[Y_AXIS], candidate_t),
candidate_pos0 = eval_bezier(pos[X_AXIS], first0, second0, cart_target[X_AXIS], candidate_t),
candidate_pos1 = eval_bezier(pos[Y_AXIS], first1, second1, cart_target[Y_AXIS], candidate_t),
interp_pos0 = 0.5f * (bez_target[X_AXIS] + new_pos0),
interp_pos1 = 0.5f * (bez_target[Y_AXIS] + new_pos1);
if (dist1(candidate_pos0, candidate_pos1, interp_pos0, interp_pos1) <= (SIGMA)) break;
@@ -155,8 +155,8 @@ void cubic_b_spline(const float position[NUM_AXIS], const float target[NUM_AXIS]
if (new_t - t > MAX_STEP) break;
const float candidate_t = t + 2 * (new_t - t);
if (candidate_t >= 1) break;
const float candidate_pos0 = eval_bezier(position[X_AXIS], first0, second0, target[X_AXIS], candidate_t),
candidate_pos1 = eval_bezier(position[Y_AXIS], first1, second1, target[Y_AXIS], candidate_t),
const float candidate_pos0 = eval_bezier(pos[X_AXIS], first0, second0, cart_target[X_AXIS], candidate_t),
candidate_pos1 = eval_bezier(pos[Y_AXIS], first1, second1, cart_target[Y_AXIS], candidate_t),
interp_pos0 = 0.5f * (bez_target[X_AXIS] + candidate_pos0),
interp_pos1 = 0.5f * (bez_target[Y_AXIS] + candidate_pos1);
if (dist1(new_pos0, new_pos1, interp_pos0, interp_pos1) > (SIGMA)) break;
@@ -184,14 +184,14 @@ void cubic_b_spline(const float position[NUM_AXIS], const float target[NUM_AXIS]
bez_target[Y_AXIS] = new_pos1;
// FIXME. The following two are wrong, since the parameter t is
// not linear in the distance.
bez_target[Z_AXIS] = interp(position[Z_AXIS], target[Z_AXIS], t);
bez_target[E_AXIS] = interp(position[E_AXIS], target[E_AXIS], t);
bez_target[Z_AXIS] = interp(pos[Z_AXIS], cart_target[Z_AXIS], t);
bez_target[E_CART] = interp(pos[E_CART], cart_target[E_CART], t);
clamp_to_software_endstops(bez_target);
#if HAS_UBL_AND_CURVES
float pos[XYZ] = { bez_target[X_AXIS], bez_target[Y_AXIS], bez_target[Z_AXIS] };
planner.apply_leveling(pos);
if (!planner.buffer_segment(pos[X_AXIS], pos[Y_AXIS], pos[Z_AXIS], bez_target[E_AXIS], fr_mm_s, active_extruder))
float bez_copy[XYZ] = { bez_target[X_AXIS], bez_target[Y_AXIS], bez_target[Z_AXIS] };
planner.apply_leveling(bez_copy);
if (!planner.buffer_segment(bez_copy[X_AXIS], bez_copy[Y_AXIS], bez_copy[Z_AXIS], bez_target[E_CART], fr_mm_s, active_extruder))
break;
#else
if (!planner.buffer_line_kinematic(bez_target, fr_mm_s, extruder))
+19 -7
View File
@@ -49,27 +49,39 @@ bool Power::is_power_needed() {
if (controllerFanSpeed > 0) return true;
#endif
// If any of the drivers or the bed are enabled...
if (X_ENABLE_READ == X_ENABLE_ON || Y_ENABLE_READ == Y_ENABLE_ON || Z_ENABLE_READ == Z_ENABLE_ON
#if HAS_HEATED_BED
|| thermalManager.soft_pwm_amount_bed > 0
#if HAS_HEATED_BED
|| thermalManager.soft_pwm_amount_bed > 0
#endif
#if HAS_X2_ENABLE
|| X2_ENABLE_READ == X_ENABLE_ON
#endif
|| E0_ENABLE_READ == E_ENABLE_ON // If any of the drivers are enabled...
#if HAS_Y2_ENABLE
|| Y2_ENABLE_READ == Y_ENABLE_ON
#endif
#if HAS_Z2_ENABLE
|| Z2_ENABLE_READ == Z_ENABLE_ON
#endif
|| E0_ENABLE_READ == E_ENABLE_ON
#if E_STEPPERS > 1
|| E1_ENABLE_READ == E_ENABLE_ON
#if HAS_X2_ENABLE
|| X2_ENABLE_READ == X_ENABLE_ON
#endif
#if E_STEPPERS > 2
|| E2_ENABLE_READ == E_ENABLE_ON
#if E_STEPPERS > 3
|| E3_ENABLE_READ == E_ENABLE_ON
#if E_STEPPERS > 4
|| E4_ENABLE_READ == E_ENABLE_ON
#endif
#endif
#endif
#endif
) return true;
HOTEND_LOOP() if (thermalManager.degTargetHotend(e) > 0) return true;
if (thermalManager.degTargetBed() > 0) return true;
#if HAS_HEATED_BED
if (thermalManager.degTargetBed() > 0) return true;
#endif
return false;
}
+16 -4
View File
@@ -159,7 +159,7 @@ void check_print_job_recovery() {
#endif
dtostrf(job_recovery_info.current_position[Z_AXIS] + 2, 1, 3, str_1);
dtostrf(job_recovery_info.current_position[E_AXIS]
dtostrf(job_recovery_info.current_position[E_CART]
#if ENABLED(SAVE_EACH_CMD_MODE)
- 5
#endif
@@ -201,12 +201,19 @@ void save_job_recovery_info() {
millis_t ms = millis();
#endif
if (
#if SAVE_INFO_INTERVAL_MS > 0
ELAPSED(ms, next_save_ms) ||
#endif
// Save on every command
#if ENABLED(SAVE_EACH_CMD_MODE)
true
#else
// Save if power loss pin is triggered
#if PIN_EXISTS(POWER_LOSS)
READ(POWER_LOSS_PIN) == POWER_LOSS_STATE ||
#endif
// Save if interval is elapsed
#if SAVE_INFO_INTERVAL_MS > 0
ELAPSED(ms, next_save_ms) ||
#endif
// Save on every new Z height
(current_position[Z_AXIS] > 0 && current_position[Z_AXIS] > job_recovery_info.current_position[Z_AXIS])
#endif
) {
@@ -266,6 +273,11 @@ void save_job_recovery_info() {
card.openJobRecoveryFile(false);
(void)card.saveJobRecoveryInfo();
// If power-loss pin was triggered, write just once then kill
#if PIN_EXISTS(POWER_LOSS)
if (READ(POWER_LOSS_PIN) == POWER_LOSS_STATE) kill(MSG_POWER_LOSS_RECOVERY);
#endif
}
}
+3 -3
View File
@@ -126,7 +126,7 @@ inline void lcd_implementation_status_message(const bool blink) {
static bool last_blink = false;
// Get the UTF8 character count of the string
uint8_t slen = lcd_strlen(lcd_status_message);
uint8_t slen = utf8_strlen(lcd_status_message);
// If the string fits into the LCD, just print it and do not scroll it
if (slen <= LCD_WIDTH) {
@@ -147,7 +147,7 @@ inline void lcd_implementation_status_message(const bool blink) {
const char *stat = lcd_status_message + status_scroll_offset;
// Get the string remaining length
const uint8_t rlen = lcd_strlen(stat);
const uint8_t rlen = utf8_strlen(stat);
// If we have enough characters to display
if (rlen >= LCD_WIDTH) {
@@ -183,7 +183,7 @@ inline void lcd_implementation_status_message(const bool blink) {
UNUSED(blink);
// Get the UTF8 character count of the string
uint8_t slen = lcd_strlen(lcd_status_message);
uint8_t slen = utf8_strlen(lcd_status_message);
// Just print the string to the LCD
lcd_print_utf(lcd_status_message, LCD_WIDTH);
+26 -18
View File
@@ -395,7 +395,7 @@ void ST7920_Lite_Status_Screen::draw_degree_symbol(uint8_t x, uint8_t y, bool dr
const uint8_t x_word = x >> 1;
const uint8_t y_top = degree_symbol_y_top;
const uint8_t y_bot = y_top + sizeof(degree_symbol)/sizeof(degree_symbol[0]);
for(uint8_t i = y_top; i < y_bot; i++) {
for (uint8_t i = y_top; i < y_bot; i++) {
uint8_t byte = pgm_read_byte_near(p_bytes++);
set_gdram_address(x_word,i+y*16);
begin_data();
@@ -618,7 +618,7 @@ void ST7920_Lite_Status_Screen::draw_status_message(const char *str) {
const uint8_t lcd_len = 16;
#if ENABLED(STATUS_MESSAGE_SCROLLING)
uint8_t slen = lcd_strlen(str);
uint8_t slen = utf8_strlen(str);
// If the string fits into the LCD, just print it and do not scroll it
if (slen <= lcd_len) {
@@ -639,7 +639,7 @@ void ST7920_Lite_Status_Screen::draw_status_message(const char *str) {
const char *stat = str + status_scroll_offset;
// Get the string remaining length
const uint8_t rlen = lcd_strlen(stat);
const uint8_t rlen = utf8_strlen(stat);
// If we have enough characters to display
if (rlen >= lcd_len) {
@@ -670,7 +670,7 @@ void ST7920_Lite_Status_Screen::draw_status_message(const char *str) {
}
#else
// Get the UTF8 character count of the string
uint8_t slen = lcd_strlen(str);
uint8_t slen = utf8_strlen(str);
// Just print the string to the LCD
write_str(str, lcd_len);
@@ -876,24 +876,32 @@ void ST7920_Lite_Status_Screen::update_status_or_position(bool forceUpdate) {
}
void ST7920_Lite_Status_Screen::update_progress(const bool forceUpdate) {
#if DISABLED(LCD_SET_PROGRESS_MANUALLY)
uint8_t progress_bar_percent;
#endif
#if ENABLED(LCD_SET_PROGRESS_MANUALLY) || ENABLED(SDSUPPORT)
// Set current percentage from SD when actively printing
#if ENABLED(SDSUPPORT)
if (IS_SD_PRINTING) progress_bar_percent = card.percentDone();
#endif
#if DISABLED(LCD_SET_PROGRESS_MANUALLY)
uint8_t progress_bar_percent; //=0
#endif
// Since the progress bar involves writing
// quite a few bytes to GDRAM, only do this
// when an update is actually necessary.
#if ENABLED(SDSUPPORT)
// Progress bar % comes from SD when actively printing
if (IS_SD_PRINTING) progress_bar_percent = card.percentDone();
#endif
static uint8_t last_progress = 0;
if (!forceUpdate && last_progress == progress_bar_percent) return;
last_progress = progress_bar_percent;
// Since the progress bar involves writing
// quite a few bytes to GDRAM, only do this
// when an update is actually necessary.
draw_progress_bar(progress_bar_percent);
static uint8_t last_progress = 0;
if (!forceUpdate && last_progress == progress_bar_percent) return;
last_progress = progress_bar_percent;
draw_progress_bar(progress_bar_percent);
#else
UNUSED(forceUpdate);
#endif // LCD_SET_PROGRESS_MANUALLY || SDSUPPORT
}
void ST7920_Lite_Status_Screen::update(const bool forceUpdate) {
+131 -53
View File
@@ -135,9 +135,8 @@ uint8_t Stepper::steps_per_isr;
#endif
uint8_t Stepper::oversampling_factor;
int32_t Stepper::delta_error[XYZE] = { 0 };
uint32_t Stepper::advance_dividend[XYZE] = { 0 },
int32_t Stepper::delta_error[NUM_AXIS] = { 0 };
uint32_t Stepper::advance_dividend[NUM_AXIS] = { 0 },
Stepper::advance_divisor = 0,
Stepper::step_events_completed = 0, // The number of step events executed in the current block
Stepper::accelerate_until, // The point from where we need to stop acceleration
@@ -180,14 +179,19 @@ uint32_t Stepper::nextMainISR = 0;
#endif // LIN_ADVANCE
int32_t Stepper::ticks_nominal = -1;
#if DISABLED(S_CURVE_ACCELERATION)
uint32_t Stepper::acc_step_rate; // needed for deceleration start point
#endif
volatile int32_t Stepper::endstops_trigsteps[XYZ];
volatile int32_t Stepper::count_position[NUM_AXIS] = { 0 };
int8_t Stepper::count_direction[NUM_AXIS] = { 0, 0, 0, 0 };
volatile int32_t Stepper::endstops_trigsteps[XYZ],
Stepper::count_position[NUM_AXIS] = { 0 };
int8_t Stepper::count_direction[NUM_AXIS] = {
1, 1, 1, 1
#if ENABLED(HANGPRINTER)
, 1
#endif
};
#if ENABLED(X_DUAL_ENDSTOPS) || ENABLED(Y_DUAL_ENDSTOPS) || ENABLED(Z_DUAL_ENDSTOPS)
#define DUAL_ENDSTOP_APPLY_STEP(A,V) \
@@ -260,6 +264,28 @@ int8_t Stepper::count_direction[NUM_AXIS] = { 0, 0, 0, 0 };
#define Z_APPLY_STEP(v,Q) Z_STEP_WRITE(v)
#endif
/**
* Hangprinter's mapping {A,B,C,D} <-> {X,Y,Z,E1} happens here.
* If you have two extruders: {A,B,C,D} <-> {X,Y,Z,E2}
* ... etc up to max 4 extruders.
* Place D connector on your first "free" extruder output.
*/
#if ENABLED(HANGPRINTER)
#define A_APPLY_DIR(v,Q) X_APPLY_DIR(v,Q)
#define A_APPLY_STEP(v,Q) X_APPLY_STEP(v,Q)
#define B_APPLY_DIR(v,Q) Y_APPLY_DIR(v,Q)
#define B_APPLY_STEP(v,Q) Y_APPLY_STEP(v,Q)
#define C_APPLY_DIR(v,Q) Z_APPLY_DIR(v,Q)
#define C_APPLY_STEP(v,Q) Z_APPLY_STEP(v,Q)
#define __D_APPLY(I,T,v) E##I##_##T##_WRITE(v)
#define _D_APPLY(I,T,v) __D_APPLY(I,T,v)
#define D_APPLY_DIR(v,Q) _D_APPLY(EXTRUDERS, DIR, v)
#define D_APPLY_STEP(v,Q) _D_APPLY(EXTRUDERS, STEP, v)
#endif
#if DISABLED(MIXING_EXTRUDER)
#define E_APPLY_STEP(v,Q) E_STEP_WRITE(active_extruder, v)
#endif
@@ -357,6 +383,9 @@ void Stepper::set_directions() {
#if HAS_Z_DIR
SET_STEP_DIR(Z); // C
#endif
#if ENABLED(HANGPRINTER)
SET_STEP_DIR(D);
#endif
#if DISABLED(LIN_ADVANCE)
#if ENABLED(MIXING_EXTRUDER)
@@ -1251,6 +1280,12 @@ void Stepper::isr() {
* call to this method that might cause variation in the timing. The aim
* is to keep pulse timing as regular as possible.
*/
#if ENABLED(UNREGISTERED_MOVE_SUPPORT)
#define COUNT_IT current_block->count_it
#else
#define COUNT_IT true
#endif
void Stepper::stepper_pulse_phase_isr() {
// If we must abort the current block, do so!
@@ -1289,7 +1324,7 @@ void Stepper::stepper_pulse_phase_isr() {
delta_error[_AXIS(AXIS)] += advance_dividend[_AXIS(AXIS)]; \
if (delta_error[_AXIS(AXIS)] >= 0) { \
_APPLY_STEP(AXIS)(!_INVERT_STEP_PIN(AXIS), 0); \
count_position[_AXIS(AXIS)] += count_direction[_AXIS(AXIS)]; \
if (COUNT_IT) count_position[_AXIS(AXIS)] += count_direction[_AXIS(AXIS)]; \
} \
}while(0)
@@ -1302,22 +1337,37 @@ void Stepper::stepper_pulse_phase_isr() {
}while(0)
// Pulse start
#if HAS_X_STEP
PULSE_START(X);
#endif
#if HAS_Y_STEP
PULSE_START(Y);
#endif
#if HAS_Z_STEP
PULSE_START(Z);
#endif
#if ENABLED(HANGPRINTER)
#if HAS_A_STEP
PULSE_START(A);
#endif
#if HAS_B_STEP
PULSE_START(B);
#endif
#if HAS_C_STEP
PULSE_START(C);
#endif
#if HAS_D_STEP
PULSE_START(D);
#endif
#else
#if HAS_X_STEP
PULSE_START(X);
#endif
#if HAS_Y_STEP
PULSE_START(Y);
#endif
#if HAS_Z_STEP
PULSE_START(Z);
#endif
#endif // HANGPRINTER
// Pulse E/Mixing extruders
#if ENABLED(LIN_ADVANCE)
// Tick the E axis, correct error term and update position
delta_error[E_AXIS] += advance_dividend[E_AXIS];
if (delta_error[E_AXIS] >= 0) {
count_position[E_AXIS] += count_direction[E_AXIS];
if (COUNT_IT) count_position[E_AXIS] += count_direction[E_AXIS];
delta_error[E_AXIS] -= advance_divisor;
// Don't step E here - But remember the number of steps to perform
@@ -1329,7 +1379,7 @@ void Stepper::stepper_pulse_phase_isr() {
// Tick the E axis
delta_error[E_AXIS] += advance_dividend[E_AXIS];
if (delta_error[E_AXIS] >= 0) {
count_position[E_AXIS] += count_direction[E_AXIS];
if (COUNT_IT) count_position[E_AXIS] += count_direction[E_AXIS];
delta_error[E_AXIS] -= advance_divisor;
}
@@ -1354,15 +1404,29 @@ void Stepper::stepper_pulse_phase_isr() {
// Add the delay needed to ensure the maximum driver rate is enforced
if (signed(added_step_ticks) > 0) pulse_end += hal_timer_t(added_step_ticks);
// Pulse stop
#if HAS_X_STEP
PULSE_STOP(X);
#endif
#if HAS_Y_STEP
PULSE_STOP(Y);
#endif
#if HAS_Z_STEP
PULSE_STOP(Z);
#if ENABLED(HANGPRINTER)
#if HAS_A_STEP
PULSE_STOP(A);
#endif
#if HAS_B_STEP
PULSE_STOP(B);
#endif
#if HAS_C_STEP
PULSE_STOP(C);
#endif
#if HAS_D_STEP
PULSE_STOP(D);
#endif
#else
#if HAS_X_STEP
PULSE_STOP(X);
#endif
#if HAS_Y_STEP
PULSE_STOP(Y);
#endif
#if HAS_Z_STEP
PULSE_STOP(Z);
#endif
#endif
#if DISABLED(LIN_ADVANCE)
@@ -1437,16 +1501,10 @@ uint32_t Stepper::stepper_block_phase_isr() {
#if ENABLED(LIN_ADVANCE)
if (LA_use_advance_lead) {
// Wake up eISR on first acceleration loop and fire ISR if final adv_rate is reached
if (step_events_completed == steps_per_isr || (LA_steps && LA_isr_rate != current_block->advance_speed)) {
nextAdvanceISR = 0;
LA_isr_rate = current_block->advance_speed;
}
}
else {
LA_isr_rate = LA_ADV_NEVER;
if (LA_steps) nextAdvanceISR = 0;
// Fire ISR if final adv_rate is reached
if (LA_steps && LA_isr_rate != current_block->advance_speed) nextAdvanceISR = 0;
}
else if (LA_steps) nextAdvanceISR = 0;
#endif // LIN_ADVANCE
}
// Are we in Deceleration phase ?
@@ -1488,17 +1546,13 @@ uint32_t Stepper::stepper_block_phase_isr() {
#if ENABLED(LIN_ADVANCE)
if (LA_use_advance_lead) {
if (step_events_completed <= decelerate_after + steps_per_isr ||
(LA_steps && LA_isr_rate != current_block->advance_speed)
) {
nextAdvanceISR = 0; // Wake up eISR on first deceleration loop
// Wake up eISR on first deceleration loop and fire ISR if final adv_rate is reached
if (step_events_completed <= decelerate_after + steps_per_isr || (LA_steps && LA_isr_rate != current_block->advance_speed)) {
nextAdvanceISR = 0;
LA_isr_rate = current_block->advance_speed;
}
}
else {
LA_isr_rate = LA_ADV_NEVER;
if (LA_steps) nextAdvanceISR = 0;
}
else if (LA_steps) nextAdvanceISR = 0;
#endif // LIN_ADVANCE
}
// We must be in cruise phase otherwise
@@ -1531,8 +1585,11 @@ uint32_t Stepper::stepper_block_phase_isr() {
// Sync block? Sync the stepper counts and return
while (TEST(current_block->flag, BLOCK_BIT_SYNC_POSITION)) {
_set_position(
current_block->position[A_AXIS], current_block->position[B_AXIS],
current_block->position[C_AXIS], current_block->position[E_AXIS]
current_block->position[A_AXIS], current_block->position[B_AXIS], current_block->position[C_AXIS],
#if ENABLED(HANGPRINTER)
current_block->position[D_AXIS],
#endif
current_block->position[E_AXIS]
);
planner.discard_current_block();
@@ -1678,7 +1735,11 @@ uint32_t Stepper::stepper_block_phase_isr() {
if ((LA_use_advance_lead = current_block->use_advance_lead)) {
LA_final_adv_steps = current_block->final_adv_steps;
LA_max_adv_steps = current_block->max_adv_steps;
//Start the ISR
nextAdvanceISR = 0;
LA_isr_rate = current_block->advance_speed;
}
else LA_isr_rate = LA_ADV_NEVER;
#endif
if (current_block->direction_bits != last_direction_bits
@@ -2015,7 +2076,12 @@ void Stepper::init() {
* This allows get_axis_position_mm to correctly
* derive the current XYZ position later on.
*/
void Stepper::_set_position(const int32_t &a, const int32_t &b, const int32_t &c, const int32_t &e) {
void Stepper::_set_position(const int32_t &a, const int32_t &b, const int32_t &c,
#if ENABLED(HANGPRINTER)
const int32_t &d,
#endif
const int32_t &e
) {
#if CORE_IS_XY
// corexy positioning
// these equations follow the form of the dA and dB equations on http://www.corexy.com/theory.html
@@ -2037,6 +2103,9 @@ void Stepper::_set_position(const int32_t &a, const int32_t &b, const int32_t &c
count_position[X_AXIS] = a;
count_position[Y_AXIS] = b;
count_position[Z_AXIS] = c;
#if ENABLED(HANGPRINTER)
count_position[D_AXIS] = d;
#endif
#endif
count_position[E_AXIS] = e;
}
@@ -2103,31 +2172,38 @@ void Stepper::report_positions() {
const int32_t xpos = count_position[X_AXIS],
ypos = count_position[Y_AXIS],
#if ENABLED(HANGPRINTER)
dpos = count_position[D_AXIS],
#endif
zpos = count_position[Z_AXIS];
if (was_enabled) ENABLE_STEPPER_DRIVER_INTERRUPT();
#if CORE_IS_XY || CORE_IS_XZ || IS_DELTA || IS_SCARA
#if CORE_IS_XY || CORE_IS_XZ || IS_DELTA || IS_SCARA || ENABLED(HANGPRINTER)
SERIAL_PROTOCOLPGM(MSG_COUNT_A);
#else
SERIAL_PROTOCOLPGM(MSG_COUNT_X);
#endif
SERIAL_PROTOCOL(xpos);
#if CORE_IS_XY || CORE_IS_YZ || IS_DELTA || IS_SCARA
#if CORE_IS_XY || CORE_IS_YZ || IS_DELTA || IS_SCARA || ENABLED(HANGPRINTER)
SERIAL_PROTOCOLPGM(" B:");
#else
SERIAL_PROTOCOLPGM(" Y:");
#endif
SERIAL_PROTOCOL(ypos);
#if CORE_IS_XZ || CORE_IS_YZ || IS_DELTA
#if CORE_IS_XZ || CORE_IS_YZ || IS_DELTA || ENABLED(HANGPRINTER)
SERIAL_PROTOCOLPGM(" C:");
#else
SERIAL_PROTOCOLPGM(" Z:");
#endif
SERIAL_PROTOCOL(zpos);
#if ENABLED(HANGPRINTER)
SERIAL_PROTOCOLPAIR(" D:", dpos);
#endif
SERIAL_EOL();
}
@@ -2171,7 +2247,7 @@ void Stepper::report_positions() {
const uint8_t old_dir = _READ_DIR(AXIS); \
_ENABLE(AXIS); \
_APPLY_DIR(AXIS, _INVERT_DIR(AXIS)^DIR^INVERT); \
DELAY_NS(400); /* DRV8825 */ \
DELAY_NS(MINIMUM_STEPPER_DIR_DELAY); \
_SAVE_START; \
_APPLY_STEP(AXIS)(!_INVERT_STEP_PIN(AXIS), true); \
_PULSE_WAIT; \
@@ -2243,7 +2319,9 @@ void Stepper::report_positions() {
Y_DIR_WRITE(INVERT_Y_DIR ^ z_direction);
Z_DIR_WRITE(INVERT_Z_DIR ^ z_direction);
DELAY_NS(400); // DRV8825
#if MINIMUM_STEPPER_DIR_DELAY > 0
DELAY_NS(MINIMUM_STEPPER_DIR_DELAY);
#endif
_SAVE_START;
+23 -5
View File
@@ -270,8 +270,8 @@ class Stepper {
#endif
// Delta error variables for the Bresenham line tracer
static int32_t delta_error[XYZE];
static uint32_t advance_dividend[XYZE],
static int32_t delta_error[NUM_AXIS];
static uint32_t advance_dividend[NUM_AXIS],
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
@@ -425,11 +425,21 @@ class Stepper {
#endif
// Set the current position in steps
inline static void set_position(const int32_t &a, const int32_t &b, const int32_t &c, const int32_t &e) {
inline static void set_position(const int32_t &a, const int32_t &b, const int32_t &c
#if ENABLED(HANGPRINTER)
, const int32_t &d
#endif
, const int32_t &e
) {
planner.synchronize();
const bool was_enabled = STEPPER_ISR_ENABLED();
if (was_enabled) DISABLE_STEPPER_DRIVER_INTERRUPT();
_set_position(a, b, c, e);
_set_position(a, b, c
#if ENABLED(HANGPRINTER)
, d
#endif
, e
);
if (was_enabled) ENABLE_STEPPER_DRIVER_INTERRUPT();
}
@@ -447,11 +457,19 @@ class Stepper {
private:
// Set the current position in steps
static void _set_position(const int32_t &a, const int32_t &b, const int32_t &c, const int32_t &e);
static void _set_position(const int32_t &a, const int32_t &b, const int32_t &c
#if ENABLED(HANGPRINTER)
, const int32_t &d
#endif
, const int32_t &e
);
// Set direction bits for all steppers
static void set_directions();
// Allow reset_stepper_drivers to access private set_directions
friend void reset_stepper_drivers();
FORCE_INLINE static uint32_t calc_timer_interval(uint32_t step_rate, uint8_t scale, uint8_t* loops) {
uint32_t timer;
+189 -143
View File
@@ -35,46 +35,48 @@
#include "MarlinConfig.h"
#include "stepper.h"
//
// TMC26X Driver objects and inits
//
#if ENABLED(HAVE_TMC26X)
#if HAS_DRIVER(TMC26X)
#include <SPI.h>
#include <TMC26XStepper.h>
#define _TMC26X_DEFINE(ST) TMC26XStepper stepper##ST(200, ST##_CS_PIN, ST##_STEP_PIN, ST##_DIR_PIN, ST##_MAX_CURRENT, ST##_SENSE_RESISTOR)
#if ENABLED(X_IS_TMC26X)
#if AXIS_DRIVER_TYPE(X, TMC26X)
_TMC26X_DEFINE(X);
#endif
#if ENABLED(X2_IS_TMC26X)
#if AXIS_DRIVER_TYPE(X2, TMC26X)
_TMC26X_DEFINE(X2);
#endif
#if ENABLED(Y_IS_TMC26X)
#if AXIS_DRIVER_TYPE(Y, TMC26X)
_TMC26X_DEFINE(Y);
#endif
#if ENABLED(Y2_IS_TMC26X)
#if AXIS_DRIVER_TYPE(Y2, TMC26X)
_TMC26X_DEFINE(Y2);
#endif
#if ENABLED(Z_IS_TMC26X)
#if AXIS_DRIVER_TYPE(Z, TMC26X)
_TMC26X_DEFINE(Z);
#endif
#if ENABLED(Z2_IS_TMC26X)
#if AXIS_DRIVER_TYPE(Z2, TMC26X)
_TMC26X_DEFINE(Z2);
#endif
#if ENABLED(E0_IS_TMC26X)
#if AXIS_DRIVER_TYPE(E0, TMC26X)
_TMC26X_DEFINE(E0);
#endif
#if ENABLED(E1_IS_TMC26X)
#if AXIS_DRIVER_TYPE(E1, TMC26X)
_TMC26X_DEFINE(E1);
#endif
#if ENABLED(E2_IS_TMC26X)
#if AXIS_DRIVER_TYPE(E2, TMC26X)
_TMC26X_DEFINE(E2);
#endif
#if ENABLED(E3_IS_TMC26X)
#if AXIS_DRIVER_TYPE(E3, TMC26X)
_TMC26X_DEFINE(E3);
#endif
#if ENABLED(E4_IS_TMC26X)
#if AXIS_DRIVER_TYPE(E4, TMC26X)
_TMC26X_DEFINE(E4);
#endif
@@ -84,46 +86,46 @@
}while(0)
void tmc26x_init_to_defaults() {
#if ENABLED(X_IS_TMC26X)
#if AXIS_DRIVER_TYPE(X, TMC26X)
_TMC26X_INIT(X);
#endif
#if ENABLED(X2_IS_TMC26X)
#if AXIS_DRIVER_TYPE(X2, TMC26X)
_TMC26X_INIT(X2);
#endif
#if ENABLED(Y_IS_TMC26X)
#if AXIS_DRIVER_TYPE(Y, TMC26X)
_TMC26X_INIT(Y);
#endif
#if ENABLED(Y2_IS_TMC26X)
#if AXIS_DRIVER_TYPE(Y2, TMC26X)
_TMC26X_INIT(Y2);
#endif
#if ENABLED(Z_IS_TMC26X)
#if AXIS_DRIVER_TYPE(Z, TMC26X)
_TMC26X_INIT(Z);
#endif
#if ENABLED(Z2_IS_TMC26X)
#if AXIS_DRIVER_TYPE(Z2, TMC26X)
_TMC26X_INIT(Z2);
#endif
#if ENABLED(E0_IS_TMC26X)
#if AXIS_DRIVER_TYPE(E0, TMC26X)
_TMC26X_INIT(E0);
#endif
#if ENABLED(E1_IS_TMC26X)
#if AXIS_DRIVER_TYPE(E1, TMC26X)
_TMC26X_INIT(E1);
#endif
#if ENABLED(E2_IS_TMC26X)
#if AXIS_DRIVER_TYPE(E2, TMC26X)
_TMC26X_INIT(E2);
#endif
#if ENABLED(E3_IS_TMC26X)
#if AXIS_DRIVER_TYPE(E3, TMC26X)
_TMC26X_INIT(E3);
#endif
#if ENABLED(E4_IS_TMC26X)
#if AXIS_DRIVER_TYPE(E4, TMC26X)
_TMC26X_INIT(E4);
#endif
}
#endif // HAVE_TMC26X
#endif // TMC26X
//
// TMC2130 Driver objects and inits
//
#if ENABLED(HAVE_TMC2130)
#if HAS_DRIVER(TMC2130)
#include <SPI.h>
#include <TMC2130Stepper.h>
@@ -141,37 +143,37 @@
#endif
// Stepper objects of TMC2130 steppers used
#if ENABLED(X_IS_TMC2130)
#if AXIS_DRIVER_TYPE(X, TMC2130)
_TMC2130_DEFINE(X);
#endif
#if ENABLED(X2_IS_TMC2130)
#if AXIS_DRIVER_TYPE(X2, TMC2130)
_TMC2130_DEFINE(X2);
#endif
#if ENABLED(Y_IS_TMC2130)
#if AXIS_DRIVER_TYPE(Y, TMC2130)
_TMC2130_DEFINE(Y);
#endif
#if ENABLED(Y2_IS_TMC2130)
#if AXIS_DRIVER_TYPE(Y2, TMC2130)
_TMC2130_DEFINE(Y2);
#endif
#if ENABLED(Z_IS_TMC2130)
#if AXIS_DRIVER_TYPE(Z, TMC2130)
_TMC2130_DEFINE(Z);
#endif
#if ENABLED(Z2_IS_TMC2130)
#if AXIS_DRIVER_TYPE(Z2, TMC2130)
_TMC2130_DEFINE(Z2);
#endif
#if ENABLED(E0_IS_TMC2130)
#if AXIS_DRIVER_TYPE(E0, TMC2130)
_TMC2130_DEFINE(E0);
#endif
#if ENABLED(E1_IS_TMC2130)
#if AXIS_DRIVER_TYPE(E1, TMC2130)
_TMC2130_DEFINE(E1);
#endif
#if ENABLED(E2_IS_TMC2130)
#if AXIS_DRIVER_TYPE(E2, TMC2130)
_TMC2130_DEFINE(E2);
#endif
#if ENABLED(E3_IS_TMC2130)
#if AXIS_DRIVER_TYPE(E3, TMC2130)
_TMC2130_DEFINE(E3);
#endif
#if ENABLED(E4_IS_TMC2130)
#if AXIS_DRIVER_TYPE(E4, TMC2130)
_TMC2130_DEFINE(E4);
#endif
@@ -208,75 +210,74 @@
#define _TMC2130_INIT(ST, SPMM) tmc2130_init(stepper##ST, ST##_CURRENT, ST##_MICROSTEPS, ST##_HYBRID_THRESHOLD, SPMM)
void tmc2130_init_to_defaults() {
#if ENABLED(X_IS_TMC2130)
#if AXIS_DRIVER_TYPE(X, TMC2130)
_TMC2130_INIT( X, planner.axis_steps_per_mm[X_AXIS]);
#endif
#if ENABLED(X2_IS_TMC2130)
#if AXIS_DRIVER_TYPE(X2, TMC2130)
_TMC2130_INIT(X2, planner.axis_steps_per_mm[X_AXIS]);
#endif
#if ENABLED(Y_IS_TMC2130)
#if AXIS_DRIVER_TYPE(Y, TMC2130)
_TMC2130_INIT( Y, planner.axis_steps_per_mm[Y_AXIS]);
#endif
#if ENABLED(Y2_IS_TMC2130)
#if AXIS_DRIVER_TYPE(Y2, TMC2130)
_TMC2130_INIT(Y2, planner.axis_steps_per_mm[Y_AXIS]);
#endif
#if ENABLED(Z_IS_TMC2130)
#if AXIS_DRIVER_TYPE(Z, TMC2130)
_TMC2130_INIT( Z, planner.axis_steps_per_mm[Z_AXIS]);
#endif
#if ENABLED(Z2_IS_TMC2130)
#if AXIS_DRIVER_TYPE(Z2, TMC2130)
_TMC2130_INIT(Z2, planner.axis_steps_per_mm[Z_AXIS]);
#endif
#if ENABLED(E0_IS_TMC2130)
#if AXIS_DRIVER_TYPE(E0, TMC2130)
_TMC2130_INIT(E0, planner.axis_steps_per_mm[E_AXIS]);
#endif
#if ENABLED(E1_IS_TMC2130)
#if AXIS_DRIVER_TYPE(E1, TMC2130)
{ constexpr int extruder = 1; _TMC2130_INIT(E1, planner.axis_steps_per_mm[E_AXIS_N]); }
#endif
#if ENABLED(E2_IS_TMC2130)
#if AXIS_DRIVER_TYPE(E2, TMC2130)
{ constexpr int extruder = 2; _TMC2130_INIT(E2, planner.axis_steps_per_mm[E_AXIS_N]); }
#endif
#if ENABLED(E3_IS_TMC2130)
#if AXIS_DRIVER_TYPE(E3, TMC2130)
{ constexpr int extruder = 3; _TMC2130_INIT(E3, planner.axis_steps_per_mm[E_AXIS_N]); }
#endif
#if ENABLED(E4_IS_TMC2130)
#if AXIS_DRIVER_TYPE(E4, TMC2130)
{ constexpr int extruder = 4; _TMC2130_INIT(E4, planner.axis_steps_per_mm[E_AXIS_N]); }
#endif
#if ENABLED(SENSORLESS_HOMING)
#define TMC_INIT_SGT(P,Q) stepper##Q.sgt(P##_HOMING_SENSITIVITY);
#if X_SENSORLESS
#if ENABLED(X_IS_TMC2130) || ENABLED(IS_TRAMS)
#if AXIS_DRIVER_TYPE(X, TMC2130)
stepperX.sgt(X_HOMING_SENSITIVITY);
#endif
#if ENABLED(X2_IS_TMC2130)
#if AXIS_DRIVER_TYPE(X2, TMC2130)
stepperX2.sgt(X_HOMING_SENSITIVITY);
#endif
#endif
#if Y_SENSORLESS
#if ENABLED(Y_IS_TMC2130) || ENABLED(IS_TRAMS)
#if AXIS_DRIVER_TYPE(Y, TMC2130)
stepperY.sgt(Y_HOMING_SENSITIVITY);
#endif
#if ENABLED(Y2_IS_TMC2130)
#if AXIS_DRIVER_TYPE(Y2, TMC2130)
stepperY2.sgt(Y_HOMING_SENSITIVITY);
#endif
#endif
#if Z_SENSORLESS
#if ENABLED(Z_IS_TMC2130) || ENABLED(IS_TRAMS)
#if AXIS_DRIVER_TYPE(Z, TMC2130)
stepperZ.sgt(Z_HOMING_SENSITIVITY);
#endif
#if ENABLED(Z2_IS_TMC2130)
#if AXIS_DRIVER_TYPE(Z2, TMC2130)
stepperZ2.sgt(Z_HOMING_SENSITIVITY);
#endif
#endif
#endif
}
#endif // HAVE_TMC2130
#endif // TMC2130
//
// TMC2208 Driver objects and inits
//
#if ENABLED(HAVE_TMC2208)
#if HAS_DRIVER(TMC2208)
#undef HardwareSerial_h // undo Marlin trickery
#include <SoftwareSerial.h>
@@ -289,81 +290,80 @@
#endif
#define _TMC2208_DEFINE_HARDWARE(ST) TMC2208Stepper stepper##ST(&ST##_HARDWARE_SERIAL)
#define _TMC2208_DEFINE_SOFTWARE(ST) SoftwareSerial ST##_HARDWARE_SERIAL = SoftwareSerial(ST##_SERIAL_RX_PIN, ST##_SERIAL_TX_PIN); \
TMC2208Stepper stepper##ST(&ST##_HARDWARE_SERIAL, ST##_SERIAL_RX_PIN > -1)
#define _TMC2208_DEFINE_SOFTWARE(ST) TMC2208Stepper stepper##ST(ST##_SERIAL_RX_PIN, ST##_SERIAL_TX_PIN, ST##_SERIAL_RX_PIN > -1)
// Stepper objects of TMC2208 steppers used
#if ENABLED(X_IS_TMC2208)
#if AXIS_DRIVER_TYPE(X, TMC2208)
#ifdef X_HARDWARE_SERIAL
_TMC2208_DEFINE_HARDWARE(X);
#else
_TMC2208_DEFINE_SOFTWARE(X);
#endif
#endif
#if ENABLED(X2_IS_TMC2208)
#if AXIS_DRIVER_TYPE(X2, TMC2208)
#ifdef X2_HARDWARE_SERIAL
_TMC2208_DEFINE_HARDWARE(X2);
#else
_TMC2208_DEFINE_SOFTWARE(X2);
#endif
#endif
#if ENABLED(Y_IS_TMC2208)
#if AXIS_DRIVER_TYPE(Y, TMC2208)
#ifdef Y_HARDWARE_SERIAL
_TMC2208_DEFINE_HARDWARE(Y);
#else
_TMC2208_DEFINE_SOFTWARE(Y);
#endif
#endif
#if ENABLED(Y2_IS_TMC2208)
#if AXIS_DRIVER_TYPE(Y2, TMC2208)
#ifdef Y2_HARDWARE_SERIAL
_TMC2208_DEFINE_HARDWARE(Y2);
#else
_TMC2208_DEFINE_SOFTWARE(Y2);
#endif
#endif
#if ENABLED(Z_IS_TMC2208)
#if AXIS_DRIVER_TYPE(Z, TMC2208)
#ifdef Z_HARDWARE_SERIAL
_TMC2208_DEFINE_HARDWARE(Z);
#else
_TMC2208_DEFINE_SOFTWARE(Z);
#endif
#endif
#if ENABLED(Z2_IS_TMC2208)
#if AXIS_DRIVER_TYPE(Z2, TMC2208)
#ifdef Z2_HARDWARE_SERIAL
_TMC2208_DEFINE_HARDWARE(Z2);
#else
_TMC2208_DEFINE_SOFTWARE(Z2);
#endif
#endif
#if ENABLED(E0_IS_TMC2208)
#if AXIS_DRIVER_TYPE(E0, TMC2208)
#ifdef E0_HARDWARE_SERIAL
_TMC2208_DEFINE_HARDWARE(E0);
#else
_TMC2208_DEFINE_SOFTWARE(E0);
#endif
#endif
#if ENABLED(E1_IS_TMC2208)
#if AXIS_DRIVER_TYPE(E1, TMC2208)
#ifdef E1_HARDWARE_SERIAL
_TMC2208_DEFINE_HARDWARE(E1);
#else
_TMC2208_DEFINE_SOFTWARE(E1);
#endif
#endif
#if ENABLED(E2_IS_TMC2208)
#if AXIS_DRIVER_TYPE(E2, TMC2208)
#ifdef E2_HARDWARE_SERIAL
_TMC2208_DEFINE_HARDWARE(E2);
#else
_TMC2208_DEFINE_SOFTWARE(E2);
#endif
#endif
#if ENABLED(E3_IS_TMC2208)
#if AXIS_DRIVER_TYPE(E3, TMC2208)
#ifdef E3_HARDWARE_SERIAL
_TMC2208_DEFINE_HARDWARE(E3);
#else
_TMC2208_DEFINE_SOFTWARE(E3);
#endif
#endif
#if ENABLED(E4_IS_TMC2208)
#if AXIS_DRIVER_TYPE(E4, TMC2208)
#ifdef E4_HARDWARE_SERIAL
_TMC2208_DEFINE_HARDWARE(E4);
#else
@@ -372,38 +372,82 @@
#endif
void tmc2208_serial_begin() {
#if ENABLED(X_IS_TMC2208)
X_HARDWARE_SERIAL.begin(115200);
#if AXIS_DRIVER_TYPE(X, TMC2208)
#ifdef X_HARDWARE_SERIAL
X_HARDWARE_SERIAL.begin(115200);
#else
stepperX.beginSerial(115200);
#endif
#endif
#if ENABLED(X2_IS_TMC2208)
X2_HARDWARE_SERIAL.begin(115200);
#if AXIS_DRIVER_TYPE(X2, TMC2208)
#ifdef X2_HARDWARE_SERIAL
X2_HARDWARE_SERIAL.begin(115200);
#else
stepperX2.beginSerial(115200);
#endif
#endif
#if ENABLED(Y_IS_TMC2208)
Y_HARDWARE_SERIAL.begin(115200);
#if AXIS_DRIVER_TYPE(Y, TMC2208)
#ifdef Y_HARDWARE_SERIAL
Y_HARDWARE_SERIAL.begin(115200);
#else
stepperY.beginSerial(115200);
#endif
#endif
#if ENABLED(Y2_IS_TMC2208)
Y2_HARDWARE_SERIAL.begin(115200);
#if AXIS_DRIVER_TYPE(Y2, TMC2208)
#ifdef Y2_HARDWARE_SERIAL
Y2_HARDWARE_SERIAL.begin(115200);
#else
stepperY2.beginSerial(115200);
#endif
#endif
#if ENABLED(Z_IS_TMC2208)
Z_HARDWARE_SERIAL.begin(115200);
#if AXIS_DRIVER_TYPE(Z, TMC2208)
#ifdef Z_HARDWARE_SERIAL
Z_HARDWARE_SERIAL.begin(115200);
#else
stepperZ.beginSerial(115200);
#endif
#endif
#if ENABLED(Z2_IS_TMC2208)
Z2_HARDWARE_SERIAL.begin(115200);
#if AXIS_DRIVER_TYPE(Z2, TMC2208)
#ifdef Z2_HARDWARE_SERIAL
Z2_HARDWARE_SERIAL.begin(115200);
#else
stepperZ2.beginSerial(115200);
#endif
#endif
#if ENABLED(E0_IS_TMC2208)
E0_HARDWARE_SERIAL.begin(115200);
#if AXIS_DRIVER_TYPE(E0, TMC2208)
#ifdef E0_HARDWARE_SERIAL
E0_HARDWARE_SERIAL.begin(115200);
#else
stepperE0.beginSerial(115200);
#endif
#endif
#if ENABLED(E1_IS_TMC2208)
E1_HARDWARE_SERIAL.begin(115200);
#if AXIS_DRIVER_TYPE(E1, TMC2208)
#ifdef E1_HARDWARE_SERIAL
E1_HARDWARE_SERIAL.begin(115200);
#else
stepperE1.beginSerial(115200);
#endif
#endif
#if ENABLED(E2_IS_TMC2208)
E2_HARDWARE_SERIAL.begin(115200);
#if AXIS_DRIVER_TYPE(E2, TMC2208)
#ifdef E2_HARDWARE_SERIAL
E2_HARDWARE_SERIAL.begin(115200);
#else
stepperE2.beginSerial(115200);
#endif
#endif
#if ENABLED(E3_IS_TMC2208)
E3_HARDWARE_SERIAL.begin(115200);
#if AXIS_DRIVER_TYPE(E3, TMC2208)
#ifdef E3_HARDWARE_SERIAL
E3_HARDWARE_SERIAL.begin(115200);
#else
stepperE3.beginSerial(115200);
#endif
#endif
#if ENABLED(E4_IS_TMC2208)
E4_HARDWARE_SERIAL.begin(115200);
#if AXIS_DRIVER_TYPE(E4, TMC2208)
#ifdef E4_HARDWARE_SERIAL
E4_HARDWARE_SERIAL.begin(115200);
#else
stepperE4.beginSerial(115200);
#endif
#endif
}
@@ -446,101 +490,103 @@
#define _TMC2208_INIT(ST, SPMM) tmc2208_init(stepper##ST, ST##_CURRENT, ST##_MICROSTEPS, ST##_HYBRID_THRESHOLD, SPMM)
void tmc2208_init_to_defaults() {
#if ENABLED(X_IS_TMC2208)
#if AXIS_DRIVER_TYPE(X, TMC2208)
_TMC2208_INIT(X, planner.axis_steps_per_mm[X_AXIS]);
#endif
#if ENABLED(X2_IS_TMC2208)
#if AXIS_DRIVER_TYPE(X2, TMC2208)
_TMC2208_INIT(X2, planner.axis_steps_per_mm[X_AXIS]);
#endif
#if ENABLED(Y_IS_TMC2208)
#if AXIS_DRIVER_TYPE(Y, TMC2208)
_TMC2208_INIT(Y, planner.axis_steps_per_mm[Y_AXIS]);
#endif
#if ENABLED(Y2_IS_TMC2208)
#if AXIS_DRIVER_TYPE(Y2, TMC2208)
_TMC2208_INIT(Y2, planner.axis_steps_per_mm[Y_AXIS]);
#endif
#if ENABLED(Z_IS_TMC2208)
#if AXIS_DRIVER_TYPE(Z, TMC2208)
_TMC2208_INIT(Z, planner.axis_steps_per_mm[Z_AXIS]);
#endif
#if ENABLED(Z2_IS_TMC2208)
#if AXIS_DRIVER_TYPE(Z2, TMC2208)
_TMC2208_INIT(Z2, planner.axis_steps_per_mm[Z_AXIS]);
#endif
#if ENABLED(E0_IS_TMC2208)
#if AXIS_DRIVER_TYPE(E0, TMC2208)
_TMC2208_INIT(E0, planner.axis_steps_per_mm[E_AXIS]);
#endif
#if ENABLED(E1_IS_TMC2208)
#if AXIS_DRIVER_TYPE(E1, TMC2208)
{ constexpr int extruder = 1; _TMC2208_INIT(E1, planner.axis_steps_per_mm[E_AXIS_N]); }
#endif
#if ENABLED(E2_IS_TMC2208)
#if AXIS_DRIVER_TYPE(E2, TMC2208)
{ constexpr int extruder = 2; _TMC2208_INIT(E2, planner.axis_steps_per_mm[E_AXIS_N]); }
#endif
#if ENABLED(E3_IS_TMC2208)
#if AXIS_DRIVER_TYPE(E3, TMC2208)
{ constexpr int extruder = 3; _TMC2208_INIT(E3, planner.axis_steps_per_mm[E_AXIS_N]); }
#endif
#if ENABLED(E4_IS_TMC2208)
#if AXIS_DRIVER_TYPE(E4, TMC2208)
{ constexpr int extruder = 4; _TMC2208_INIT(E4, planner.axis_steps_per_mm[E_AXIS_N]); }
#endif
}
#endif // HAVE_TMC2208
#endif // TMC2208
void restore_stepper_drivers() {
#if X_IS_TRINAMIC
#if AXIS_IS_TMC(X)
stepperX.push();
#endif
#if X2_IS_TRINAMIC
#if AXIS_IS_TMC(X2)
stepperX2.push();
#endif
#if Y_IS_TRINAMIC
#if AXIS_IS_TMC(Y)
stepperY.push();
#endif
#if Y2_IS_TRINAMIC
#if AXIS_IS_TMC(Y2)
stepperY2.push();
#endif
#if Z_IS_TRINAMIC
#if AXIS_IS_TMC(Z)
stepperZ.push();
#endif
#if Z2_IS_TRINAMIC
#if AXIS_IS_TMC(Z2)
stepperZ2.push();
#endif
#if E0_IS_TRINAMIC
#if AXIS_IS_TMC(E0)
stepperE0.push();
#endif
#if E1_IS_TRINAMIC
#if AXIS_IS_TMC(E1)
stepperE1.push();
#endif
#if E2_IS_TRINAMIC
#if AXIS_IS_TMC(E2)
stepperE2.push();
#endif
#if E3_IS_TRINAMIC
#if AXIS_IS_TMC(E3)
stepperE3.push();
#endif
#if E4_IS_TRINAMIC
#if AXIS_IS_TMC(E4)
stepperE4.push();
#endif
}
void reset_stepper_drivers() {
#if ENABLED(HAVE_TMC26X)
#if HAS_DRIVER(TMC26X)
tmc26x_init_to_defaults();
#endif
#if ENABLED(HAVE_TMC2130)
#if HAS_DRIVER(TMC2130)
delay(100);
tmc2130_init_to_defaults();
#endif
#if ENABLED(HAVE_TMC2208)
#if HAS_DRIVER(TMC2208)
delay(100);
tmc2208_init_to_defaults();
#endif
#ifdef TMC_ADV
TMC_ADV()
#endif
#if ENABLED(HAVE_L6470DRIVER)
#if HAS_DRIVER(L6470)
L6470_init_to_defaults();
#endif
stepper.set_directions();
}
//
// L6470 Driver objects and inits
//
#if ENABLED(HAVE_L6470DRIVER)
#if HAS_DRIVER(L6470)
#include <SPI.h>
#include <L6470.h>
@@ -548,37 +594,37 @@ void reset_stepper_drivers() {
#define _L6470_DEFINE(ST) L6470 stepper##ST(ST##_ENABLE_PIN)
// L6470 Stepper objects
#if ENABLED(X_IS_L6470)
#if AXIS_DRIVER_TYPE(X, L6470)
_L6470_DEFINE(X);
#endif
#if ENABLED(X2_IS_L6470)
#if AXIS_DRIVER_TYPE(X2, L6470)
_L6470_DEFINE(X2);
#endif
#if ENABLED(Y_IS_L6470)
#if AXIS_DRIVER_TYPE(Y, L6470)
_L6470_DEFINE(Y);
#endif
#if ENABLED(Y2_IS_L6470)
#if AXIS_DRIVER_TYPE(Y2, L6470)
_L6470_DEFINE(Y2);
#endif
#if ENABLED(Z_IS_L6470)
#if AXIS_DRIVER_TYPE(Z, L6470)
_L6470_DEFINE(Z);
#endif
#if ENABLED(Z2_IS_L6470)
#if AXIS_DRIVER_TYPE(Z2, L6470)
_L6470_DEFINE(Z2);
#endif
#if ENABLED(E0_IS_L6470)
#if AXIS_DRIVER_TYPE(E0, L6470)
_L6470_DEFINE(E0);
#endif
#if ENABLED(E1_IS_L6470)
#if AXIS_DRIVER_TYPE(E1, L6470)
_L6470_DEFINE(E1);
#endif
#if ENABLED(E2_IS_L6470)
#if AXIS_DRIVER_TYPE(E2, L6470)
_L6470_DEFINE(E2);
#endif
#if ENABLED(E3_IS_L6470)
#if AXIS_DRIVER_TYPE(E3, L6470)
_L6470_DEFINE(E3);
#endif
#if ENABLED(E4_IS_L6470)
#if AXIS_DRIVER_TYPE(E4, L6470)
_L6470_DEFINE(E4);
#endif
@@ -591,39 +637,39 @@ void reset_stepper_drivers() {
}while(0)
void L6470_init_to_defaults() {
#if ENABLED(X_IS_L6470)
#if AXIS_DRIVER_TYPE(X, L6470)
_L6470_INIT(X);
#endif
#if ENABLED(X2_IS_L6470)
#if AXIS_DRIVER_TYPE(X2, L6470)
_L6470_INIT(X2);
#endif
#if ENABLED(Y_IS_L6470)
#if AXIS_DRIVER_TYPE(Y, L6470)
_L6470_INIT(Y);
#endif
#if ENABLED(Y2_IS_L6470)
#if AXIS_DRIVER_TYPE(Y2, L6470)
_L6470_INIT(Y2);
#endif
#if ENABLED(Z_IS_L6470)
#if AXIS_DRIVER_TYPE(Z, L6470)
_L6470_INIT(Z);
#endif
#if ENABLED(Z2_IS_L6470)
#if AXIS_DRIVER_TYPE(Z2, L6470)
_L6470_INIT(Z2);
#endif
#if ENABLED(E0_IS_L6470)
#if AXIS_DRIVER_TYPE(E0, L6470)
_L6470_INIT(E0);
#endif
#if ENABLED(E1_IS_L6470)
#if AXIS_DRIVER_TYPE(E1, L6470)
_L6470_INIT(E1);
#endif
#if ENABLED(E2_IS_L6470)
#if AXIS_DRIVER_TYPE(E2, L6470)
_L6470_INIT(E2);
#endif
#if ENABLED(E3_IS_L6470)
#if AXIS_DRIVER_TYPE(E3, L6470)
_L6470_INIT(E3);
#endif
#if ENABLED(E4_IS_L6470)
#if AXIS_DRIVER_TYPE(E4, L6470)
_L6470_INIT(E4);
#endif
}
#endif // HAVE_L6470DRIVER
#endif // L6470
+48 -48
View File
@@ -47,25 +47,25 @@
#include "MarlinConfig.h"
// TMC26X drivers have STEP/DIR on normal pins, but ENABLE via SPI
#if ENABLED(HAVE_TMC26X)
#if HAS_DRIVER(TMC26X)
#include <SPI.h>
#include <TMC26XStepper.h>
void tmc26x_init_to_defaults();
#endif
#if ENABLED(HAVE_TMC2130)
#if HAS_DRIVER(TMC2130)
#include <TMC2130Stepper.h>
void tmc2130_init_to_defaults();
#endif
#if ENABLED(HAVE_TMC2208)
#if HAS_DRIVER(TMC2208)
#include <TMC2208Stepper.h>
void tmc2208_serial_begin();
void tmc2208_init_to_defaults();
#endif
// L6470 has STEP on normal pins, but DIR/ENABLE via SPI
#if ENABLED(HAVE_L6470DRIVER)
#if HAS_DRIVER(L6470)
#include <SPI.h>
#include <L6470.h>
void L6470_init_to_defaults();
@@ -75,7 +75,7 @@ void restore_stepper_drivers(); // Called by PSU_ON
void reset_stepper_drivers(); // Called by settings.load / settings.reset
// X Stepper
#if ENABLED(X_IS_L6470)
#if AXIS_DRIVER_TYPE(X, L6470)
extern L6470 stepperX;
#define X_ENABLE_INIT NOOP
#define X_ENABLE_WRITE(STATE) do{ if (STATE) stepperX.Step_Clock(stepperX.getStatus() & STATUS_HIZ); else stepperX.softFree(); }while(0)
@@ -84,15 +84,15 @@ void reset_stepper_drivers(); // Called by settings.load / settings.reset
#define X_DIR_WRITE(STATE) stepperX.Step_Clock(STATE)
#define X_DIR_READ (stepperX.getStatus() & STATUS_DIR)
#else
#if ENABLED(X_IS_TMC26X)
#if AXIS_DRIVER_TYPE(X, TMC26X)
extern TMC26XStepper stepperX;
#define X_ENABLE_INIT NOOP
#define X_ENABLE_WRITE(STATE) stepperX.setEnabled(STATE)
#define X_ENABLE_READ stepperX.isEnabled()
#else
#if ENABLED(X_IS_TMC2130)
#if AXIS_DRIVER_TYPE(X, TMC2130)
extern TMC2130Stepper stepperX;
#elif ENABLED(X_IS_TMC2208)
#elif AXIS_DRIVER_TYPE(X, TMC2208)
extern TMC2208Stepper stepperX;
#endif
#define X_ENABLE_INIT SET_OUTPUT(X_ENABLE_PIN)
@@ -108,7 +108,7 @@ void reset_stepper_drivers(); // Called by settings.load / settings.reset
#define X_STEP_READ READ(X_STEP_PIN)
// Y Stepper
#if ENABLED(Y_IS_L6470)
#if AXIS_DRIVER_TYPE(Y, L6470)
extern L6470 stepperY;
#define Y_ENABLE_INIT NOOP
#define Y_ENABLE_WRITE(STATE) do{ if (STATE) stepperY.Step_Clock(stepperY.getStatus() & STATUS_HIZ); else stepperY.softFree(); }while(0)
@@ -117,15 +117,15 @@ void reset_stepper_drivers(); // Called by settings.load / settings.reset
#define Y_DIR_WRITE(STATE) stepperY.Step_Clock(STATE)
#define Y_DIR_READ (stepperY.getStatus() & STATUS_DIR)
#else
#if ENABLED(Y_IS_TMC26X)
#if AXIS_DRIVER_TYPE(Y, TMC26X)
extern TMC26XStepper stepperY;
#define Y_ENABLE_INIT NOOP
#define Y_ENABLE_WRITE(STATE) stepperY.setEnabled(STATE)
#define Y_ENABLE_READ stepperY.isEnabled()
#else
#if ENABLED(Y_IS_TMC2130)
#if AXIS_DRIVER_TYPE(Y, TMC2130)
extern TMC2130Stepper stepperY;
#elif ENABLED(Y_IS_TMC2208)
#elif AXIS_DRIVER_TYPE(Y, TMC2208)
extern TMC2208Stepper stepperY;
#endif
#define Y_ENABLE_INIT SET_OUTPUT(Y_ENABLE_PIN)
@@ -141,7 +141,7 @@ void reset_stepper_drivers(); // Called by settings.load / settings.reset
#define Y_STEP_READ READ(Y_STEP_PIN)
// Z Stepper
#if ENABLED(Z_IS_L6470)
#if AXIS_DRIVER_TYPE(Z, L6470)
extern L6470 stepperZ;
#define Z_ENABLE_INIT NOOP
#define Z_ENABLE_WRITE(STATE) do{ if (STATE) stepperZ.Step_Clock(stepperZ.getStatus() & STATUS_HIZ); else stepperZ.softFree(); }while(0)
@@ -150,15 +150,15 @@ void reset_stepper_drivers(); // Called by settings.load / settings.reset
#define Z_DIR_WRITE(STATE) stepperZ.Step_Clock(STATE)
#define Z_DIR_READ (stepperZ.getStatus() & STATUS_DIR)
#else
#if ENABLED(Z_IS_TMC26X)
#if AXIS_DRIVER_TYPE(Z, TMC26X)
extern TMC26XStepper stepperZ;
#define Z_ENABLE_INIT NOOP
#define Z_ENABLE_WRITE(STATE) stepperZ.setEnabled(STATE)
#define Z_ENABLE_READ stepperZ.isEnabled()
#else
#if ENABLED(Z_IS_TMC2130)
#if AXIS_DRIVER_TYPE(Z, TMC2130)
extern TMC2130Stepper stepperZ;
#elif ENABLED(Z_IS_TMC2208)
#elif AXIS_DRIVER_TYPE(Z, TMC2208)
extern TMC2208Stepper stepperZ;
#endif
#define Z_ENABLE_INIT SET_OUTPUT(Z_ENABLE_PIN)
@@ -175,7 +175,7 @@ void reset_stepper_drivers(); // Called by settings.load / settings.reset
// X2 Stepper
#if HAS_X2_ENABLE
#if ENABLED(X2_IS_L6470)
#if AXIS_DRIVER_TYPE(X2, L6470)
extern L6470 stepperX2;
#define X2_ENABLE_INIT NOOP
#define X2_ENABLE_WRITE(STATE) do{ if (STATE) stepperX2.Step_Clock(stepperX2.getStatus() & STATUS_HIZ); else stepperX2.softFree(); }while(0)
@@ -184,15 +184,15 @@ void reset_stepper_drivers(); // Called by settings.load / settings.reset
#define X2_DIR_WRITE(STATE) stepperX2.Step_Clock(STATE)
#define X2_DIR_READ (stepperX2.getStatus() & STATUS_DIR)
#else
#if ENABLED(X2_IS_TMC26X)
#if AXIS_DRIVER_TYPE(X2, TMC26X)
extern TMC26XStepper stepperX2;
#define X2_ENABLE_INIT NOOP
#define X2_ENABLE_WRITE(STATE) stepperX2.setEnabled(STATE)
#define X2_ENABLE_READ stepperX2.isEnabled()
#else
#if ENABLED(X2_IS_TMC2130)
#if AXIS_DRIVER_TYPE(X2, TMC2130)
extern TMC2130Stepper stepperX2;
#elif ENABLED(X2_IS_TMC2208)
#elif AXIS_DRIVER_TYPE(X2, TMC2208)
extern TMC2208Stepper stepperX2;
#endif
#define X2_ENABLE_INIT SET_OUTPUT(X2_ENABLE_PIN)
@@ -210,7 +210,7 @@ void reset_stepper_drivers(); // Called by settings.load / settings.reset
// Y2 Stepper
#if HAS_Y2_ENABLE
#if ENABLED(Y2_IS_L6470)
#if AXIS_DRIVER_TYPE(Y2, L6470)
extern L6470 stepperY2;
#define Y2_ENABLE_INIT NOOP
#define Y2_ENABLE_WRITE(STATE) do{ if (STATE) stepperY2.Step_Clock(stepperY2.getStatus() & STATUS_HIZ); else stepperY2.softFree(); }while(0)
@@ -219,15 +219,15 @@ void reset_stepper_drivers(); // Called by settings.load / settings.reset
#define Y2_DIR_WRITE(STATE) stepperY2.Step_Clock(STATE)
#define Y2_DIR_READ (stepperY2.getStatus() & STATUS_DIR)
#else
#if ENABLED(Y2_IS_TMC26X)
#if AXIS_DRIVER_TYPE(Y2, TMC26X)
extern TMC26XStepper stepperY2;
#define Y2_ENABLE_INIT NOOP
#define Y2_ENABLE_WRITE(STATE) stepperY2.setEnabled(STATE)
#define Y2_ENABLE_READ stepperY2.isEnabled()
#else
#if ENABLED(Y2_IS_TMC2130)
#if AXIS_DRIVER_TYPE(Y2, TMC2130)
extern TMC2130Stepper stepperY2;
#elif ENABLED(Y2_IS_TMC2208)
#elif AXIS_DRIVER_TYPE(Y2, TMC2208)
extern TMC2208Stepper stepperY2;
#endif
#define Y2_ENABLE_INIT SET_OUTPUT(Y2_ENABLE_PIN)
@@ -245,7 +245,7 @@ void reset_stepper_drivers(); // Called by settings.load / settings.reset
// Z2 Stepper
#if HAS_Z2_ENABLE
#if ENABLED(Z2_IS_L6470)
#if AXIS_DRIVER_TYPE(Z2, L6470)
extern L6470 stepperZ2;
#define Z2_ENABLE_INIT NOOP
#define Z2_ENABLE_WRITE(STATE) do{ if (STATE) stepperZ2.Step_Clock(stepperZ2.getStatus() & STATUS_HIZ); else stepperZ2.softFree(); }while(0)
@@ -254,15 +254,15 @@ void reset_stepper_drivers(); // Called by settings.load / settings.reset
#define Z2_DIR_WRITE(STATE) stepperZ2.Step_Clock(STATE)
#define Z2_DIR_READ (stepperZ2.getStatus() & STATUS_DIR)
#else
#if ENABLED(Z2_IS_TMC26X)
#if AXIS_DRIVER_TYPE(Z2, TMC26X)
extern TMC26XStepper stepperZ2;
#define Z2_ENABLE_INIT NOOP
#define Z2_ENABLE_WRITE(STATE) stepperZ2.setEnabled(STATE)
#define Z2_ENABLE_READ stepperZ2.isEnabled()
#else
#if ENABLED(Z2_IS_TMC2130)
#if AXIS_DRIVER_TYPE(Z2, TMC2130)
extern TMC2130Stepper stepperZ2;
#elif ENABLED(Z2_IS_TMC2208)
#elif AXIS_DRIVER_TYPE(Z2, TMC2208)
extern TMC2208Stepper stepperZ2;
#endif
#define Z2_ENABLE_INIT SET_OUTPUT(Z2_ENABLE_PIN)
@@ -279,7 +279,7 @@ void reset_stepper_drivers(); // Called by settings.load / settings.reset
#endif
// E0 Stepper
#if ENABLED(E0_IS_L6470)
#if AXIS_DRIVER_TYPE(E0, L6470)
extern L6470 stepperE0;
#define E0_ENABLE_INIT NOOP
#define E0_ENABLE_WRITE(STATE) do{ if (STATE) stepperE0.Step_Clock(stepperE0.getStatus() & STATUS_HIZ); else stepperE0.softFree(); }while(0)
@@ -288,15 +288,15 @@ void reset_stepper_drivers(); // Called by settings.load / settings.reset
#define E0_DIR_WRITE(STATE) stepperE0.Step_Clock(STATE)
#define E0_DIR_READ (stepperE0.getStatus() & STATUS_DIR)
#else
#if ENABLED(E0_IS_TMC26X)
#if AXIS_DRIVER_TYPE(E0, TMC26X)
extern TMC26XStepper stepperE0;
#define E0_ENABLE_INIT NOOP
#define E0_ENABLE_WRITE(STATE) stepperE0.setEnabled(STATE)
#define E0_ENABLE_READ stepperE0.isEnabled()
#else
#if ENABLED(E0_IS_TMC2130)
#if AXIS_DRIVER_TYPE(E0, TMC2130)
extern TMC2130Stepper stepperE0;
#elif ENABLED(E0_IS_TMC2208)
#elif AXIS_DRIVER_TYPE(E0, TMC2208)
extern TMC2208Stepper stepperE0;
#endif
#define E0_ENABLE_INIT SET_OUTPUT(E0_ENABLE_PIN)
@@ -312,7 +312,7 @@ void reset_stepper_drivers(); // Called by settings.load / settings.reset
#define E0_STEP_READ READ(E0_STEP_PIN)
// E1 Stepper
#if ENABLED(E1_IS_L6470)
#if AXIS_DRIVER_TYPE(E1, L6470)
extern L6470 stepperE1;
#define E1_ENABLE_INIT NOOP
#define E1_ENABLE_WRITE(STATE) do{ if (STATE) stepperE1.Step_Clock(stepperE1.getStatus() & STATUS_HIZ); else stepperE1.softFree(); }while(0)
@@ -321,15 +321,15 @@ void reset_stepper_drivers(); // Called by settings.load / settings.reset
#define E1_DIR_WRITE(STATE) stepperE1.Step_Clock(STATE)
#define E1_DIR_READ (stepperE1.getStatus() & STATUS_DIR)
#else
#if ENABLED(E1_IS_TMC26X)
#if AXIS_DRIVER_TYPE(E1, TMC26X)
extern TMC26XStepper stepperE1;
#define E1_ENABLE_INIT NOOP
#define E1_ENABLE_WRITE(STATE) stepperE1.setEnabled(STATE)
#define E1_ENABLE_READ stepperE1.isEnabled()
#else
#if ENABLED(E1_IS_TMC2130)
#if AXIS_DRIVER_TYPE(E1, TMC2130)
extern TMC2130Stepper stepperE1;
#elif ENABLED(E1_IS_TMC2208)
#elif AXIS_DRIVER_TYPE(E1, TMC2208)
extern TMC2208Stepper stepperE1;
#endif
#define E1_ENABLE_INIT SET_OUTPUT(E1_ENABLE_PIN)
@@ -345,7 +345,7 @@ void reset_stepper_drivers(); // Called by settings.load / settings.reset
#define E1_STEP_READ READ(E1_STEP_PIN)
// E2 Stepper
#if ENABLED(E2_IS_L6470)
#if AXIS_DRIVER_TYPE(E2, L6470)
extern L6470 stepperE2;
#define E2_ENABLE_INIT NOOP
#define E2_ENABLE_WRITE(STATE) do{ if (STATE) stepperE2.Step_Clock(stepperE2.getStatus() & STATUS_HIZ); else stepperE2.softFree(); }while(0)
@@ -354,15 +354,15 @@ void reset_stepper_drivers(); // Called by settings.load / settings.reset
#define E2_DIR_WRITE(STATE) stepperE2.Step_Clock(STATE)
#define E2_DIR_READ (stepperE2.getStatus() & STATUS_DIR)
#else
#if ENABLED(E2_IS_TMC26X)
#if AXIS_DRIVER_TYPE(E2, TMC26X)
extern TMC26XStepper stepperE2;
#define E2_ENABLE_INIT NOOP
#define E2_ENABLE_WRITE(STATE) stepperE2.setEnabled(STATE)
#define E2_ENABLE_READ stepperE2.isEnabled()
#else
#if ENABLED(E2_IS_TMC2130)
#if AXIS_DRIVER_TYPE(E2, TMC2130)
extern TMC2130Stepper stepperE2;
#elif ENABLED(E2_IS_TMC2208)
#elif AXIS_DRIVER_TYPE(E2, TMC2208)
extern TMC2208Stepper stepperE2;
#endif
#define E2_ENABLE_INIT SET_OUTPUT(E2_ENABLE_PIN)
@@ -378,7 +378,7 @@ void reset_stepper_drivers(); // Called by settings.load / settings.reset
#define E2_STEP_READ READ(E2_STEP_PIN)
// E3 Stepper
#if ENABLED(E3_IS_L6470)
#if AXIS_DRIVER_TYPE(E3, L6470)
extern L6470 stepperE3;
#define E3_ENABLE_INIT NOOP
#define E3_ENABLE_WRITE(STATE) do{ if (STATE) stepperE3.Step_Clock(stepperE3.getStatus() & STATUS_HIZ); else stepperE3.softFree(); }while(0)
@@ -387,15 +387,15 @@ void reset_stepper_drivers(); // Called by settings.load / settings.reset
#define E3_DIR_WRITE(STATE) stepperE3.Step_Clock(STATE)
#define E3_DIR_READ (stepperE3.getStatus() & STATUS_DIR)
#else
#if ENABLED(E3_IS_TMC26X)
#if AXIS_DRIVER_TYPE(E3, TMC26X)
extern TMC26XStepper stepperE3;
#define E3_ENABLE_INIT NOOP
#define E3_ENABLE_WRITE(STATE) stepperE3.setEnabled(STATE)
#define E3_ENABLE_READ stepperE3.isEnabled()
#else
#if ENABLED(E3_IS_TMC2130)
#if AXIS_DRIVER_TYPE(E3, TMC2130)
extern TMC2130Stepper stepperE3;
#elif ENABLED(E3_IS_TMC2208)
#elif AXIS_DRIVER_TYPE(E3, TMC2208)
extern TMC2208Stepper stepperE3;
#endif
#define E3_ENABLE_INIT SET_OUTPUT(E3_ENABLE_PIN)
@@ -411,7 +411,7 @@ void reset_stepper_drivers(); // Called by settings.load / settings.reset
#define E3_STEP_READ READ(E3_STEP_PIN)
// E4 Stepper
#if ENABLED(E4_IS_L6470)
#if AXIS_DRIVER_TYPE(E4, L6470)
extern L6470 stepperE4;
#define E4_ENABLE_INIT NOOP
#define E4_ENABLE_WRITE(STATE) do{ if (STATE) stepperE4.Step_Clock(stepperE4.getStatus() & STATUS_HIZ); else stepperE4.softFree(); }while(0)
@@ -420,15 +420,15 @@ void reset_stepper_drivers(); // Called by settings.load / settings.reset
#define E4_DIR_WRITE(STATE) stepperE4.Step_Clock(STATE)
#define E4_DIR_READ (stepperE4.getStatus() & STATUS_DIR)
#else
#if ENABLED(E4_IS_TMC26X)
#if AXIS_DRIVER_TYPE(E4, TMC26X)
extern TMC26XStepper stepperE4;
#define E4_ENABLE_INIT NOOP
#define E4_ENABLE_WRITE(STATE) stepperE4.setEnabled(STATE)
#define E4_ENABLE_READ stepperE4.isEnabled()
#else
#if ENABLED(E4_IS_TMC2130)
#if AXIS_DRIVER_TYPE(E4, TMC2130)
extern TMC2130Stepper stepperE4;
#elif ENABLED(E4_IS_TMC2208)
#elif AXIS_DRIVER_TYPE(E4, TMC2208)
extern TMC2208Stepper stepperE4;
#endif
#define E4_ENABLE_INIT SET_OUTPUT(E4_ENABLE_PIN)
+159 -172
View File
@@ -260,19 +260,29 @@ uint8_t Temperature::soft_pwm_amount[HOTENDS];
workKp = 0, workKi = 0, workKd = 0,
max = 0, min = 10000;
#define HAS_TP_BED (ENABLED(THERMAL_PROTECTION_BED) && ENABLED(PIDTEMPBED))
#if HAS_TP_BED && ENABLED(THERMAL_PROTECTION_HOTENDS) && ENABLED(PIDTEMP)
#define TV(B,H) (hotend < 0 ? (B) : (H))
#elif HAS_TP_BED
#define TV(B,H) (B)
#if HAS_PID_FOR_BOTH
#define GHV(B,H) (hotend < 0 ? (B) : (H))
#define SHV(S,B,H) if (hotend < 0) S##_bed = B; else S [hotend] = H;
#elif ENABLED(PIDTEMPBED)
#define GHV(B,H) B
#define SHV(S,B,H) (S##_bed = B)
#else
#define TV(B,H) (H)
#define GHV(B,H) H
#define SHV(S,B,H) (S [hotend] = H)
#endif
#if WATCH_THE_BED || WATCH_HOTENDS
const uint16_t watch_temp_period = TV(WATCH_BED_TEMP_PERIOD, WATCH_TEMP_PERIOD);
const uint8_t watch_temp_increase = TV(WATCH_BED_TEMP_INCREASE, WATCH_TEMP_INCREASE);
const float watch_temp_target = target - float(watch_temp_increase + TV(TEMP_BED_HYSTERESIS, TEMP_HYSTERESIS) + 1);
#define HAS_TP_BED (ENABLED(THERMAL_PROTECTION_BED) && ENABLED(PIDTEMPBED))
#if HAS_TP_BED && ENABLED(THERMAL_PROTECTION_HOTENDS) && ENABLED(PIDTEMP)
#define GTV(B,H) (hotend < 0 ? (B) : (H))
#elif HAS_TP_BED
#define GTV(B,H) (B)
#else
#define GTV(B,H) (H)
#endif
const uint16_t watch_temp_period = GTV(WATCH_BED_TEMP_PERIOD, WATCH_TEMP_PERIOD);
const uint8_t watch_temp_increase = GTV(WATCH_BED_TEMP_INCREASE, WATCH_TEMP_INCREASE);
const float watch_temp_target = target - float(watch_temp_increase + GTV(TEMP_BED_HYSTERESIS, TEMP_HYSTERESIS) + 1);
millis_t temp_change_ms = next_temp_ms + watch_temp_period * 1000UL;
float next_watch_temp = 0.0;
bool heated = false;
@@ -302,16 +312,7 @@ uint8_t Temperature::soft_pwm_amount[HOTENDS];
disable_all_heaters(); // switch off all heaters.
#if HAS_PID_FOR_BOTH
if (hotend < 0)
soft_pwm_amount_bed = bias = d = (MAX_BED_POWER) >> 1;
else
soft_pwm_amount[hotend] = bias = d = (PID_MAX) >> 1;
#elif ENABLED(PIDTEMP)
soft_pwm_amount[hotend] = bias = d = (PID_MAX) >> 1;
#else
soft_pwm_amount_bed = bias = d = (MAX_BED_POWER) >> 1;
#endif
SHV(soft_pwm_amount, bias = d = (MAX_BED_POWER) >> 1, bias = d = (PID_MAX) >> 1);
wait_for_heatup = true; // Can be interrupted with M108
@@ -324,15 +325,7 @@ uint8_t Temperature::soft_pwm_amount[HOTENDS];
updateTemperaturesFromRawValues();
// Get the current temperature and constrain it
current =
#if HAS_PID_FOR_BOTH
hotend < 0 ? current_temperature_bed : current_temperature[hotend]
#elif ENABLED(PIDTEMP)
current_temperature[hotend]
#else
current_temperature_bed
#endif
;
current = GHV(current_temperature_bed, current_temperature[hotend]);
NOLESS(max, current);
NOMORE(min, current);
@@ -346,16 +339,7 @@ uint8_t Temperature::soft_pwm_amount[HOTENDS];
if (heating && current > target) {
if (ELAPSED(ms, t2 + 5000UL)) {
heating = false;
#if HAS_PID_FOR_BOTH
if (hotend < 0)
soft_pwm_amount_bed = (bias - d) >> 1;
else
soft_pwm_amount[hotend] = (bias - d) >> 1;
#elif ENABLED(PIDTEMP)
soft_pwm_amount[hotend] = (bias - d) >> 1;
#elif ENABLED(PIDTEMPBED)
soft_pwm_amount_bed = (bias - d) >> 1;
#endif
SHV(soft_pwm_amount, (bias - d) >> 1, (bias - d) >> 1);
t1 = ms;
t_high = t1 - t2;
max = target;
@@ -368,15 +352,7 @@ uint8_t Temperature::soft_pwm_amount[HOTENDS];
t2 = ms;
t_low = t2 - t1;
if (cycles > 0) {
long max_pow =
#if HAS_PID_FOR_BOTH
hotend < 0 ? MAX_BED_POWER : PID_MAX
#elif ENABLED(PIDTEMP)
PID_MAX
#else
MAX_BED_POWER
#endif
;
const long max_pow = GHV(MAX_BED_POWER, PID_MAX);
bias += (d * (t_high - t_low)) / (t_low + t_high);
bias = constrain(bias, 20, max_pow - 20);
d = (bias > max_pow >> 1) ? max_pow - 1 - bias : bias;
@@ -415,16 +391,7 @@ uint8_t Temperature::soft_pwm_amount[HOTENDS];
*/
}
}
#if HAS_PID_FOR_BOTH
if (hotend < 0)
soft_pwm_amount_bed = (bias + d) >> 1;
else
soft_pwm_amount[hotend] = (bias + d) >> 1;
#elif ENABLED(PIDTEMP)
soft_pwm_amount[hotend] = (bias + d) >> 1;
#else
soft_pwm_amount_bed = (bias + d) >> 1;
#endif
SHV(soft_pwm_amount, (bias + d) >> 1, (bias + d) >> 1);
cycles++;
min = target;
}
@@ -453,10 +420,10 @@ uint8_t Temperature::soft_pwm_amount[HOTENDS];
if (
#if WATCH_THE_BED && WATCH_HOTENDS
true
#elif WATCH_THE_BED
hotend < 0
#else
#elif WATCH_HOTENDS
hotend >= 0
#else
hotend < 0
#endif
) {
if (!heated) { // If not yet reached target...
@@ -487,7 +454,7 @@ uint8_t Temperature::soft_pwm_amount[HOTENDS];
SERIAL_PROTOCOLLNPGM(MSG_PID_AUTOTUNE_FINISHED);
#if HAS_PID_FOR_BOTH
const char* estring = hotend < 0 ? "bed" : "";
const char* estring = GHV("bed", "");
SERIAL_PROTOCOLPAIR("#define DEFAULT_", estring); SERIAL_PROTOCOLPAIR("Kp ", workKp); SERIAL_EOL();
SERIAL_PROTOCOLPAIR("#define DEFAULT_", estring); SERIAL_PROTOCOLPAIR("Ki ", workKi); SERIAL_EOL();
SERIAL_PROTOCOLPAIR("#define DEFAULT_", estring); SERIAL_PROTOCOLPAIR("Kd ", workKd); SERIAL_EOL();
@@ -575,7 +542,13 @@ int Temperature::getHeaterPower(const int heater) {
uint8_t fanDone = 0;
for (uint8_t f = 0; f < COUNT(fanPin); f++) {
pin_t pin = pgm_read_byte(&fanPin[f]);
const pin_t pin =
#ifdef ARDUINO
pgm_read_byte(&fanPin[f])
#else
fanPin[f]
#endif
;
const uint8_t bit = pgm_read_byte(&fanBit[f]);
if (pin >= 0 && !TEST(fanDone, bit)) {
uint8_t newFanSpeed = TEST(fanState, bit) ? EXTRUDER_AUTO_FAN_SPEED : 0;
@@ -596,7 +569,6 @@ int Temperature::getHeaterPower(const int heater) {
// Temperature Error Handlers
//
void Temperature::_temp_error(const int8_t e, const char * const serial_msg, const char * const lcd_msg) {
static bool killed = false;
if (IsRunning()) {
SERIAL_ERROR_START();
serialprintPGM(serial_msg);
@@ -604,6 +576,7 @@ void Temperature::_temp_error(const int8_t e, const char * const serial_msg, con
if (e >= 0) SERIAL_ERRORLN((int)e); else SERIAL_ERRORLNPGM(MSG_HEATER_BED);
}
#if DISABLED(BOGUS_TEMPERATURE_FAILSAFE_OVERRIDE)
static bool killed = false;
if (!killed) {
Running = false;
killed = true;
@@ -1770,8 +1743,89 @@ void Temperature::set_current_temp_raw() {
}
#endif // PINS_DEBUGGING
#if ENABLED(FILAMENT_WIDTH_SENSOR)
uint32_t raw_filwidth_value; // = 0
#endif
void Temperature::readings_ready() {
// Update the raw values if they've been read. Else we could be updating them during reading.
if (!temp_meas_ready) set_current_temp_raw();
// Filament Sensor - can be read any time since IIR filtering is used
#if ENABLED(FILAMENT_WIDTH_SENSOR)
current_raw_filwidth = raw_filwidth_value >> 10; // Divide to get to 0-16384 range since we used 1/128 IIR filter approach
#endif
ZERO(raw_temp_value);
#if HAS_HEATED_BED
raw_temp_bed_value = 0;
#endif
#if HAS_TEMP_CHAMBER
raw_temp_chamber_value = 0;
#endif
#define TEMPDIR(N) ((HEATER_##N##_RAW_LO_TEMP) > (HEATER_##N##_RAW_HI_TEMP) ? -1 : 1)
int constexpr temp_dir[] = {
#if ENABLED(HEATER_0_USES_MAX6675)
0
#else
TEMPDIR(0)
#endif
#if HOTENDS > 1
, TEMPDIR(1)
#if HOTENDS > 2
, TEMPDIR(2)
#if HOTENDS > 3
, TEMPDIR(3)
#if HOTENDS > 4
, TEMPDIR(4)
#endif // HOTENDS > 4
#endif // HOTENDS > 3
#endif // HOTENDS > 2
#endif // HOTENDS > 1
};
for (uint8_t e = 0; e < COUNT(temp_dir); e++) {
const int16_t tdir = temp_dir[e], rawtemp = current_temperature_raw[e] * tdir;
const bool heater_on = (target_temperature[e] > 0)
#if ENABLED(PIDTEMP)
|| (soft_pwm_amount[e] > 0)
#endif
;
if (rawtemp > maxttemp_raw[e] * tdir) max_temp_error(e);
if (rawtemp < minttemp_raw[e] * tdir && !is_preheating(e) && heater_on) {
#ifdef MAX_CONSECUTIVE_LOW_TEMPERATURE_ERROR_ALLOWED
if (++consecutive_low_temperature_error[e] >= MAX_CONSECUTIVE_LOW_TEMPERATURE_ERROR_ALLOWED)
#endif
min_temp_error(e);
}
#ifdef MAX_CONSECUTIVE_LOW_TEMPERATURE_ERROR_ALLOWED
else
consecutive_low_temperature_error[e] = 0;
#endif
}
#if HAS_HEATED_BED
#if HEATER_BED_RAW_LO_TEMP > HEATER_BED_RAW_HI_TEMP
#define GEBED <=
#else
#define GEBED >=
#endif
const bool bed_on = (target_temperature_bed > 0)
#if ENABLED(PIDTEMPBED)
|| (soft_pwm_amount_bed > 0)
#endif
;
if (current_temperature_bed_raw GEBED bed_maxttemp_raw) max_temp_error(-1);
if (bed_minttemp_raw GEBED current_temperature_bed_raw && bed_on) min_temp_error(-1);
#endif
}
/**
* Timer 0 is shared with millies so don't change the prescaler.
* Timer 0 is shared with millis so don't change the prescaler.
*
* This ISR uses the compare method so it runs at the base
* frequency (16 MHz / 64 / 256 = 976.5625 Hz), but at the TCNT0 set
@@ -1833,10 +1887,6 @@ void Temperature::isr() {
ISR_STATICS(BED);
#endif
#if ENABLED(FILAMENT_WIDTH_SENSOR)
static unsigned long raw_filwidth_value = 0;
#endif
#if DISABLED(SLOW_PWM_HEATERS)
constexpr uint8_t pwm_mask =
#if ENABLED(SOFT_PWM_DITHER)
@@ -2087,6 +2137,12 @@ void Temperature::isr() {
*
* This gives each ADC 0.9765ms to charge up.
*/
#define ACCUMULATE_ADC(var) do{ \
if (!HAL_ADC_READY()) next_sensor_state = adc_sensor_state; \
else var += HAL_READ_ADC(); \
}while(0)
ADCSensorState next_sensor_state = adc_sensor_state < SensorsReady ? (ADCSensorState)(int(adc_sensor_state) + 1) : StartSampling;
switch (adc_sensor_state) {
@@ -2096,21 +2152,30 @@ void Temperature::isr() {
constexpr int8_t extra_loops = MIN_ADC_ISR_LOOPS - (int8_t)SensorsReady;
static uint8_t delay_count = 0;
if (extra_loops > 0) {
if (delay_count == 0) delay_count = extra_loops; // Init this delay
if (--delay_count) // While delaying...
adc_sensor_state = (ADCSensorState)(int(SensorsReady) - 1); // retain this state (else, next state will be 0)
if (delay_count == 0) delay_count = extra_loops; // Init this delay
if (--delay_count) // While delaying...
next_sensor_state = SensorsReady; // retain this state (else, next state will be 0)
break;
}
else
adc_sensor_state = (ADCSensorState)0; // Fall-through to start first sensor now
else {
adc_sensor_state = StartSampling; // Fall-through to start sampling
next_sensor_state = (ADCSensorState)(int(StartSampling) + 1);
}
}
case StartSampling: // Start of sampling loops. Do updates/checks.
if (++temp_count >= OVERSAMPLENR) { // 10 * 16 * 1/(16000000/64/256) = 164ms.
temp_count = 0;
readings_ready();
}
break;
#if HAS_TEMP_ADC_0
case PrepareTemp_0:
HAL_START_ADC(TEMP_0_PIN);
break;
case MeasureTemp_0:
raw_temp_value[0] += HAL_READ_ADC;
ACCUMULATE_ADC(raw_temp_value[0]);
break;
#endif
@@ -2119,7 +2184,7 @@ void Temperature::isr() {
HAL_START_ADC(TEMP_BED_PIN);
break;
case MeasureTemp_BED:
raw_temp_bed_value += HAL_READ_ADC;
ACCUMULATE_ADC(raw_temp_bed_value);
break;
#endif
@@ -2128,7 +2193,7 @@ void Temperature::isr() {
HAL_START_ADC(TEMP_CHAMBER_PIN);
break;
case MeasureTemp_CHAMBER:
raw_temp_chamber_value += HAL_READ_ADC;
ACCUMULATE_ADC(raw_temp_chamber_value);
break;
#endif
@@ -2137,7 +2202,7 @@ void Temperature::isr() {
HAL_START_ADC(TEMP_1_PIN);
break;
case MeasureTemp_1:
raw_temp_value[1] += HAL_READ_ADC;
ACCUMULATE_ADC(raw_temp_value[1]);
break;
#endif
@@ -2146,7 +2211,7 @@ void Temperature::isr() {
HAL_START_ADC(TEMP_2_PIN);
break;
case MeasureTemp_2:
raw_temp_value[2] += HAL_READ_ADC;
ACCUMULATE_ADC(raw_temp_value[2]);
break;
#endif
@@ -2155,7 +2220,7 @@ void Temperature::isr() {
HAL_START_ADC(TEMP_3_PIN);
break;
case MeasureTemp_3:
raw_temp_value[3] += HAL_READ_ADC;
ACCUMULATE_ADC(raw_temp_value[3]);
break;
#endif
@@ -2164,7 +2229,7 @@ void Temperature::isr() {
HAL_START_ADC(TEMP_4_PIN);
break;
case MeasureTemp_4:
raw_temp_value[4] += HAL_READ_ADC;
ACCUMULATE_ADC(raw_temp_value[4]);
break;
#endif
@@ -2173,9 +2238,11 @@ void Temperature::isr() {
HAL_START_ADC(FILWIDTH_PIN);
break;
case Measure_FILWIDTH:
if (HAL_READ_ADC > 102) { // Make sure ADC is reading > 0.5 volts, otherwise don't read.
raw_filwidth_value -= (raw_filwidth_value >> 7); // Subtract 1/128th of the raw_filwidth_value
raw_filwidth_value += ((unsigned long)HAL_READ_ADC << 7); // Add new ADC reading, scaled by 128
if (!HAL_ADC_READY())
next_sensor_state = adc_sensor_state; // redo this state
else if (HAL_READ_ADC() > 102) { // Make sure ADC is reading > 0.5 volts, otherwise don't read.
raw_filwidth_value -= raw_filwidth_value >> 7; // Subtract 1/128th of the raw_filwidth_value
raw_filwidth_value += uint32_t(HAL_READ_ADC()) << 7; // Add new ADC reading, scaled by 128
}
break;
#endif
@@ -2185,8 +2252,10 @@ void Temperature::isr() {
HAL_START_ADC(ADC_KEYPAD_PIN);
break;
case Measure_ADC_KEY:
if (ADCKey_count < 16) {
raw_ADCKey_value = HAL_READ_ADC;
if (!HAL_ADC_READY())
next_sensor_state = adc_sensor_state; // redo this state
else if (ADCKey_count < 16) {
raw_ADCKey_value = HAL_READ_ADC();
if (raw_ADCKey_value > 900) {
//ADC Key release
ADCKey_count = 0;
@@ -2204,94 +2273,12 @@ void Temperature::isr() {
} // switch(adc_sensor_state)
if (!adc_sensor_state && ++temp_count >= OVERSAMPLENR) { // 10 * 16 * 1/(16000000/64/256) = 164ms.
// Go to the next state
adc_sensor_state = next_sensor_state;
temp_count = 0;
// Update the raw values if they've been read. Else we could be updating them during reading.
if (!temp_meas_ready) set_current_temp_raw();
// Filament Sensor - can be read any time since IIR filtering is used
#if ENABLED(FILAMENT_WIDTH_SENSOR)
current_raw_filwidth = raw_filwidth_value >> 10; // Divide to get to 0-16384 range since we used 1/128 IIR filter approach
#endif
ZERO(raw_temp_value);
#if HAS_HEATED_BED
raw_temp_bed_value = 0;
#endif
#if HAS_TEMP_CHAMBER
raw_temp_chamber_value = 0;
#endif
#define TEMPDIR(N) ((HEATER_##N##_RAW_LO_TEMP) > (HEATER_##N##_RAW_HI_TEMP) ? -1 : 1)
int constexpr temp_dir[] = {
#if ENABLED(HEATER_0_USES_MAX6675)
0
#else
TEMPDIR(0)
#endif
#if HOTENDS > 1
, TEMPDIR(1)
#if HOTENDS > 2
, TEMPDIR(2)
#if HOTENDS > 3
, TEMPDIR(3)
#if HOTENDS > 4
, TEMPDIR(4)
#endif // HOTENDS > 4
#endif // HOTENDS > 3
#endif // HOTENDS > 2
#endif // HOTENDS > 1
};
for (uint8_t e = 0; e < COUNT(temp_dir); e++) {
const int16_t tdir = temp_dir[e], rawtemp = current_temperature_raw[e] * tdir;
const bool heater_on = 0 <
#if ENABLED(PIDTEMP)
soft_pwm_amount[e]
#else
target_temperature[e]
#endif
;
if (rawtemp > maxttemp_raw[e] * tdir && heater_on) max_temp_error(e);
if (rawtemp < minttemp_raw[e] * tdir && !is_preheating(e) && heater_on) {
#ifdef MAX_CONSECUTIVE_LOW_TEMPERATURE_ERROR_ALLOWED
if (++consecutive_low_temperature_error[e] >= MAX_CONSECUTIVE_LOW_TEMPERATURE_ERROR_ALLOWED)
#endif
min_temp_error(e);
}
#ifdef MAX_CONSECUTIVE_LOW_TEMPERATURE_ERROR_ALLOWED
else
consecutive_low_temperature_error[e] = 0;
#endif
}
#if HAS_HEATED_BED
#if HEATER_BED_RAW_LO_TEMP > HEATER_BED_RAW_HI_TEMP
#define GEBED <=
#else
#define GEBED >=
#endif
const bool bed_on = 0 <
#if ENABLED(PIDTEMPBED)
soft_pwm_amount_bed
#else
target_temperature_bed
#endif
;
if (current_temperature_bed_raw GEBED bed_maxttemp_raw && bed_on) max_temp_error(-1);
if (bed_minttemp_raw GEBED current_temperature_bed_raw && bed_on) min_temp_error(-1);
#endif
} // temp_count >= OVERSAMPLENR
// Go to the next state, up to SensorsReady
adc_sensor_state = (ADCSensorState)(int(adc_sensor_state) + 1);
if (adc_sensor_state > SensorsReady) adc_sensor_state = (ADCSensorState)0;
//
// Additional ~1KHz Tasks
//
#if ENABLED(BABYSTEPPING)
LOOP_XYZ(axis) {
+2
View File
@@ -59,6 +59,7 @@
* States for ADC reading in the ISR
*/
enum ADCSensorState : char {
StartSampling,
#if HAS_TEMP_ADC_0
PrepareTemp_0,
MeasureTemp_0,
@@ -329,6 +330,7 @@ class Temperature {
/**
* Called from the Temperature ISR
*/
static void readings_ready();
static void isr();
/**
+2 -2
View File
@@ -28,8 +28,8 @@ const short temptable_501[][2] PROGMEM = {
{OV( 19), 280},
{OV( 23), 270},
{OV( 27), 260},
{OV( 32), 250},
{OV( 30), 240},
{OV( 31), 250},
{OV( 37), 240},
{OV( 47), 230},
{OV( 57), 220},
{OV( 68), 210},
+2 -80
View File
@@ -28,78 +28,26 @@
// R2 = 4700 Ohm
const short temptable_71[][2] PROGMEM = {
{ OV( 35), 300 },
{ OV( 51), 270 },
{ OV( 54), 265 },
{ OV( 58), 260 },
{ OV( 51), 269 },
{ OV( 59), 258 },
{ OV( 61), 256 },
{ OV( 63), 254 },
{ OV( 64), 252 },
{ OV( 66), 250 },
{ OV( 67), 249 },
{ OV( 68), 248 },
{ OV( 69), 247 },
{ OV( 70), 246 },
{ OV( 71), 245 },
{ OV( 72), 244 },
{ OV( 73), 243 },
{ OV( 74), 242 },
{ OV( 75), 241 },
{ OV( 76), 240 },
{ OV( 77), 239 },
{ OV( 78), 238 },
{ OV( 79), 237 },
{ OV( 80), 236 },
{ OV( 71), 244 },
{ OV( 81), 235 },
{ OV( 82), 234 },
{ OV( 84), 233 },
{ OV( 85), 232 },
{ OV( 86), 231 },
{ OV( 87), 230 },
{ OV( 89), 229 },
{ OV( 90), 228 },
{ OV( 91), 227 },
{ OV( 92), 226 },
{ OV( 94), 225 },
{ OV( 95), 224 },
{ OV( 97), 223 },
{ OV( 98), 222 },
{ OV( 99), 221 },
{ OV( 101), 220 },
{ OV( 102), 219 },
{ OV( 104), 218 },
{ OV( 106), 217 },
{ OV( 107), 216 },
{ OV( 109), 215 },
{ OV( 110), 214 },
{ OV( 112), 213 },
{ OV( 114), 212 },
{ OV( 115), 211 },
{ OV( 117), 210 },
{ OV( 119), 209 },
{ OV( 121), 208 },
{ OV( 123), 207 },
{ OV( 125), 206 },
{ OV( 126), 205 },
{ OV( 128), 204 },
{ OV( 130), 203 },
{ OV( 132), 202 },
{ OV( 134), 201 },
{ OV( 136), 200 },
{ OV( 139), 199 },
{ OV( 141), 198 },
{ OV( 143), 197 },
{ OV( 145), 196 },
{ OV( 147), 195 },
{ OV( 150), 194 },
{ OV( 152), 193 },
{ OV( 154), 192 },
{ OV( 157), 191 },
{ OV( 159), 190 },
{ OV( 162), 189 },
{ OV( 164), 188 },
{ OV( 167), 187 },
{ OV( 170), 186 },
{ OV( 172), 185 },
{ OV( 175), 184 },
{ OV( 178), 183 },
@@ -113,9 +61,7 @@ const short temptable_71[][2] PROGMEM = {
{ OV( 202), 175 },
{ OV( 205), 174 },
{ OV( 208), 173 },
{ OV( 212), 172 },
{ OV( 215), 171 },
{ OV( 219), 170 },
{ OV( 237), 165 },
{ OV( 256), 160 },
{ OV( 300), 150 },
@@ -123,46 +69,22 @@ const short temptable_71[][2] PROGMEM = {
{ OV( 470), 120 },
{ OV( 504), 115 },
{ OV( 538), 110 },
{ OV( 552), 108 },
{ OV( 566), 106 },
{ OV( 580), 104 },
{ OV( 594), 102 },
{ OV( 608), 100 },
{ OV( 622), 98 },
{ OV( 636), 96 },
{ OV( 650), 94 },
{ OV( 664), 92 },
{ OV( 678), 90 },
{ OV( 712), 85 },
{ OV( 745), 80 },
{ OV( 758), 78 },
{ OV( 770), 76 },
{ OV( 783), 74 },
{ OV( 795), 72 },
{ OV( 806), 70 },
{ OV( 818), 68 },
{ OV( 829), 66 },
{ OV( 840), 64 },
{ OV( 850), 62 },
{ OV( 860), 60 },
{ OV( 870), 58 },
{ OV( 879), 56 },
{ OV( 888), 54 },
{ OV( 897), 52 },
{ OV( 905), 50 },
{ OV( 924), 45 },
{ OV( 940), 40 },
{ OV( 955), 35 },
{ OV( 967), 30 },
{ OV( 970), 29 },
{ OV( 972), 28 },
{ OV( 974), 27 },
{ OV( 976), 26 },
{ OV( 978), 25 },
{ OV( 980), 24 },
{ OV( 982), 23 },
{ OV( 984), 22 },
{ OV( 985), 21 },
{ OV( 987), 20 },
{ OV( 995), 15 },
{ OV(1001), 10 },
+2 -2
View File
@@ -204,8 +204,8 @@
#endif
// The SCAN_THERMISTOR_TABLE macro needs alteration?
static_assert(HEATER_0_TEMPTABLE_LEN < 128 && HEATER_1_TEMPTABLE_LEN < 128 && HEATER_2_TEMPTABLE_LEN < 128 && HEATER_3_TEMPTABLE_LEN < 128 && HEATER_4_TEMPTABLE_LEN < 128 && BEDTEMPTABLE_LEN < 128 && CHAMBERTEMPTABLE_LEN < 128,
"Temperature conversion tables over 127 entries need special consideration."
static_assert(HEATER_0_TEMPTABLE_LEN < 256 && HEATER_1_TEMPTABLE_LEN < 256 && HEATER_2_TEMPTABLE_LEN < 256 && HEATER_3_TEMPTABLE_LEN < 256 && HEATER_4_TEMPTABLE_LEN < 256 && BEDTEMPTABLE_LEN < 256 && CHAMBERTEMPTABLE_LEN < 256,
"Temperature conversion tables over 255 entries need special consideration."
);
// Set the high and low raw values for the heaters
+46 -46
View File
@@ -50,7 +50,7 @@ bool report_tmc_status = false;
bool is_ot;
bool is_error;
};
#if ENABLED(HAVE_TMC2130)
#if HAS_DRIVER(TMC2130)
static uint32_t get_pwm_scale(TMC2130Stepper &st) { return st.PWM_SCALE(); }
static uint8_t get_status_response(TMC2130Stepper &st) { return st.status_response & 0xF; }
static TMC_driver_data get_driver_data(TMC2130Stepper &st) {
@@ -68,7 +68,7 @@ bool report_tmc_status = false;
return data;
}
#endif
#if ENABLED(HAVE_TMC2208)
#if HAS_DRIVER(TMC2208)
static uint32_t get_pwm_scale(TMC2208Stepper &st) { return st.pwm_scale_sum(); }
static uint8_t get_status_response(TMC2208Stepper &st) {
uint32_t drv_status = st.DRV_STATUS();
@@ -157,21 +157,21 @@ bool report_tmc_status = false;
}
}
#define HAS_HW_COMMS(ST) ENABLED(ST##_IS_TMC2130)|| (ENABLED(ST##_IS_TMC2208) && defined(ST##_HARDWARE_SERIAL))
#define HAS_HW_COMMS(ST) AXIS_DRIVER_TYPE(ST, TMC2130) || (AXIS_DRIVER_TYPE(ST, TMC2208) && defined(ST##_HARDWARE_SERIAL))
void monitor_tmc_driver() {
static millis_t next_cOT = 0;
if (ELAPSED(millis(), next_cOT)) {
next_cOT = millis() + 500;
#if HAS_HW_COMMS(X) || ENABLED(IS_TRAMS)
#if HAS_HW_COMMS(X)
static uint8_t x_otpw_cnt = 0;
monitor_tmc_driver(stepperX, TMC_X, x_otpw_cnt);
#endif
#if HAS_HW_COMMS(Y) || ENABLED(IS_TRAMS)
#if HAS_HW_COMMS(Y)
static uint8_t y_otpw_cnt = 0;
monitor_tmc_driver(stepperY, TMC_Y, y_otpw_cnt);
#endif
#if HAS_HW_COMMS(Z) || ENABLED(IS_TRAMS)
#if HAS_HW_COMMS(Z)
static uint8_t z_otpw_cnt = 0;
monitor_tmc_driver(stepperZ, TMC_Z, z_otpw_cnt);
#endif
@@ -187,7 +187,7 @@ bool report_tmc_status = false;
static uint8_t z2_otpw_cnt = 0;
monitor_tmc_driver(stepperZ2, TMC_Z, z2_otpw_cnt);
#endif
#if HAS_HW_COMMS(E0) || ENABLED(IS_TRAMS)
#if HAS_HW_COMMS(E0)
static uint8_t e0_otpw_cnt = 0;
monitor_tmc_driver(stepperE0, TMC_E0, e0_otpw_cnt);
#endif
@@ -309,7 +309,7 @@ void _tmc_say_sgt(const TMC_AxisEnum axis, const int8_t sgt) {
SERIAL_EOL();
}
#if ENABLED(HAVE_TMC2130)
#if HAS_DRIVER(TMC2130)
static void tmc_status(TMC2130Stepper &st, const TMC_debug_enum i) {
switch (i) {
case TMC_PWM_SCALE: SERIAL_PRINT(st.PWM_SCALE(), DEC); break;
@@ -329,7 +329,7 @@ void _tmc_say_sgt(const TMC_AxisEnum axis, const int8_t sgt) {
}
#endif
#if ENABLED(HAVE_TMC2208)
#if HAS_DRIVER(TMC2208)
static void tmc_status(TMC2208Stepper &st, const TMC_debug_enum i) {
switch (i) {
case TMC_TSTEP: { uint32_t data = 0; st.TSTEP(&data); SERIAL_PROTOCOL(data); break; }
@@ -418,52 +418,52 @@ void _tmc_say_sgt(const TMC_AxisEnum axis, const int8_t sgt) {
}
static void tmc_debug_loop(const TMC_debug_enum i) {
#if X_IS_TRINAMIC
#if AXIS_IS_TMC(X)
tmc_status(stepperX, TMC_X, i, planner.axis_steps_per_mm[X_AXIS]);
#endif
#if X2_IS_TRINAMIC
#if AXIS_IS_TMC(X2)
tmc_status(stepperX2, TMC_X2, i, planner.axis_steps_per_mm[X_AXIS]);
#endif
#if Y_IS_TRINAMIC
#if AXIS_IS_TMC(Y)
tmc_status(stepperY, TMC_Y, i, planner.axis_steps_per_mm[Y_AXIS]);
#endif
#if Y2_IS_TRINAMIC
#if AXIS_IS_TMC(Y2)
tmc_status(stepperY2, TMC_Y2, i, planner.axis_steps_per_mm[Y_AXIS]);
#endif
#if Z_IS_TRINAMIC
#if AXIS_IS_TMC(Z)
tmc_status(stepperZ, TMC_Z, i, planner.axis_steps_per_mm[Z_AXIS]);
#endif
#if Z2_IS_TRINAMIC
#if AXIS_IS_TMC(Z2)
tmc_status(stepperZ2, TMC_Z2, i, planner.axis_steps_per_mm[Z_AXIS]);
#endif
#if E0_IS_TRINAMIC
#if AXIS_IS_TMC(E0)
tmc_status(stepperE0, TMC_E0, i, planner.axis_steps_per_mm[E_AXIS]);
#endif
#if E1_IS_TRINAMIC
#if AXIS_IS_TMC(E1)
tmc_status(stepperE1, TMC_E1, i, planner.axis_steps_per_mm[E_AXIS
#if ENABLED(DISTINCT_E_FACTORS)
+ 1
#endif
]);
#endif
#if E2_IS_TRINAMIC
#if AXIS_IS_TMC(E2)
tmc_status(stepperE2, TMC_E2, i, planner.axis_steps_per_mm[E_AXIS
#if ENABLED(DISTINCT_E_FACTORS)
+ 2
#endif
]);
#endif
#if E3_IS_TRINAMIC
#if AXIS_IS_TMC(E3)
tmc_status(stepperE3, TMC_E3, i, planner.axis_steps_per_mm[E_AXIS
#if ENABLED(DISTINCT_E_FACTORS)
+ 3
#endif
]);
#endif
#if E4_IS_TRINAMIC
#if AXIS_IS_TMC(E4)
tmc_status(stepperE4, TMC_E4, i, planner.axis_steps_per_mm[E_AXIS
#if ENABLED(DISTINCT_E_FACTORS)
+ 4
@@ -475,40 +475,40 @@ void _tmc_say_sgt(const TMC_AxisEnum axis, const int8_t sgt) {
}
static void drv_status_loop(const TMC_drv_status_enum i) {
#if X_IS_TRINAMIC
#if AXIS_IS_TMC(X)
tmc_parse_drv_status(stepperX, TMC_X, i);
#endif
#if X2_IS_TRINAMIC
#if AXIS_IS_TMC(X2)
tmc_parse_drv_status(stepperX2, TMC_X2, i);
#endif
#if Y_IS_TRINAMIC
#if AXIS_IS_TMC(Y)
tmc_parse_drv_status(stepperY, TMC_Y, i);
#endif
#if Y2_IS_TRINAMIC
#if AXIS_IS_TMC(Y2)
tmc_parse_drv_status(stepperY2, TMC_Y2, i);
#endif
#if Z_IS_TRINAMIC
#if AXIS_IS_TMC(Z)
tmc_parse_drv_status(stepperZ, TMC_Z, i);
#endif
#if Z2_IS_TRINAMIC
#if AXIS_IS_TMC(Z2)
tmc_parse_drv_status(stepperZ2, TMC_Z2, i);
#endif
#if E0_IS_TRINAMIC
#if AXIS_IS_TMC(E0)
tmc_parse_drv_status(stepperE0, TMC_E0, i);
#endif
#if E1_IS_TRINAMIC
#if AXIS_IS_TMC(E1)
tmc_parse_drv_status(stepperE1, TMC_E1, i);
#endif
#if E2_IS_TRINAMIC
#if AXIS_IS_TMC(E2)
tmc_parse_drv_status(stepperE2, TMC_E2, i);
#endif
#if E3_IS_TRINAMIC
#if AXIS_IS_TMC(E3)
tmc_parse_drv_status(stepperE3, TMC_E3, i);
#endif
#if E4_IS_TRINAMIC
#if AXIS_IS_TMC(E4)
tmc_parse_drv_status(stepperE4, TMC_E4, i);
#endif
@@ -551,7 +551,7 @@ void _tmc_say_sgt(const TMC_AxisEnum axis, const int8_t sgt) {
TMC_REPORT("Stallguard thrs", TMC_SGT);
DRV_REPORT("DRVSTATUS", TMC_DRV_CODES);
#if ENABLED(HAVE_TMC2130)
#if HAS_DRIVER(TMC2130)
DRV_REPORT("stallguard\t", TMC_STALLGUARD);
DRV_REPORT("sg_result\t", TMC_SG_RESULT);
DRV_REPORT("fsactive\t", TMC_FSACTIVE);
@@ -563,7 +563,7 @@ void _tmc_say_sgt(const TMC_AxisEnum axis, const int8_t sgt) {
DRV_REPORT("s2ga\t", TMC_S2GA);
DRV_REPORT("otpw\t", TMC_DRV_OTPW);
DRV_REPORT("ot\t", TMC_OT);
#if ENABLED(HAVE_TMC2208)
#if HAS_DRIVER(TMC2208)
DRV_REPORT("157C\t", TMC_T157);
DRV_REPORT("150C\t", TMC_T150);
DRV_REPORT("143C\t", TMC_T143);
@@ -589,43 +589,43 @@ void _tmc_say_sgt(const TMC_AxisEnum axis, const int8_t sgt) {
#endif // SENSORLESS_HOMING
#if ENABLED(HAVE_TMC2130)
#if HAS_DRIVER(TMC2130)
#define SET_CS_PIN(st) OUT_WRITE(st##_CS_PIN, HIGH)
void tmc_init_cs_pins() {
#if ENABLED(X_IS_TMC2130)
#if AXIS_DRIVER_TYPE(X, TMC2130)
SET_CS_PIN(X);
#endif
#if ENABLED(Y_IS_TMC2130)
#if AXIS_DRIVER_TYPE(Y, TMC2130)
SET_CS_PIN(Y);
#endif
#if ENABLED(Z_IS_TMC2130)
#if AXIS_DRIVER_TYPE(Z, TMC2130)
SET_CS_PIN(Z);
#endif
#if ENABLED(X2_IS_TMC2130)
#if AXIS_DRIVER_TYPE(X2, TMC2130)
SET_CS_PIN(X2);
#endif
#if ENABLED(Y2_IS_TMC2130)
#if AXIS_DRIVER_TYPE(Y2, TMC2130)
SET_CS_PIN(Y2);
#endif
#if ENABLED(Z2_IS_TMC2130)
#if AXIS_DRIVER_TYPE(Z2, TMC2130)
SET_CS_PIN(Z2);
#endif
#if ENABLED(E0_IS_TMC2130)
#if AXIS_DRIVER_TYPE(E0, TMC2130)
SET_CS_PIN(E0);
#endif
#if ENABLED(E1_IS_TMC2130)
#if AXIS_DRIVER_TYPE(E1, TMC2130)
SET_CS_PIN(E1);
#endif
#if ENABLED(E2_IS_TMC2130)
#if AXIS_DRIVER_TYPE(E2, TMC2130)
SET_CS_PIN(E2);
#endif
#if ENABLED(E3_IS_TMC2130)
#if AXIS_DRIVER_TYPE(E3, TMC2130)
SET_CS_PIN(E3);
#endif
#if ENABLED(E4_IS_TMC2130)
#if AXIS_DRIVER_TYPE(E4, TMC2130)
SET_CS_PIN(E4);
#endif
}
#endif // HAVE_TMC2130
#endif // TMC2130
#endif // HAS_TRINAMIC
+3 -3
View File
@@ -25,11 +25,11 @@
#include "MarlinConfig.h"
#if ENABLED(HAVE_TMC2130)
#if HAS_DRIVER(TMC2130)
#include <TMC2130Stepper.h>
#endif
#if ENABLED(HAVE_TMC2208)
#if HAS_DRIVER(TMC2208)
#include <TMC2208Stepper.h>
#endif
@@ -100,7 +100,7 @@ void monitor_tmc_driver();
void tmc_sensorless_homing(TMC2130Stepper &st, const bool enable=true);
#endif
#if ENABLED(HAVE_TMC2130)
#if HAS_DRIVER(TMC2130)
void tmc_init_cs_pins();
#endif
+3 -3
View File
@@ -55,7 +55,7 @@ void TWIBus::address(const uint8_t adr) {
#endif
}
void TWIBus::addbyte(const char c) {
void TWIBus::addbyte(const byte c) {
if (this->buffer_s >= COUNT(this->buffer)) return;
this->buffer[this->buffer_s++] = c;
#if ENABLED(DEBUG_TWIBUS)
@@ -63,7 +63,7 @@ void TWIBus::addbyte(const char c) {
#endif
}
void TWIBus::addbytes(char src[], uint8_t bytes) {
void TWIBus::addbytes(byte src[], uint8_t bytes) {
#if ENABLED(DEBUG_TWIBUS)
debug(PSTR("addbytes"), bytes);
#endif
@@ -138,7 +138,7 @@ void TWIBus::relay(const uint8_t bytes) {
echodata(bytes, PSTR("i2c-reply"), this->addr);
}
uint8_t TWIBus::capture(char *dst, const uint8_t bytes) {
uint8_t TWIBus::capture(byte *dst, const uint8_t bytes) {
this->reset();
uint8_t count = 0;
while (count < bytes && Wire.available())
+10 -3
View File
@@ -33,6 +33,13 @@
typedef void (*twiReceiveFunc_t)(int bytes);
typedef void (*twiRequestFunc_t)();
#if ENABLED(MECHADUINO_I2C_COMMANDS)
typedef union {
float fval;
byte bval[sizeof(float)];
} i2cFloat;
#endif
#define TWIBUS_BUFFER_SIZE 32
/**
@@ -99,7 +106,7 @@ class TWIBus {
*
* @param c a data byte
*/
void addbyte(const char c);
void addbyte(const byte c);
/**
* @brief Add some bytes to the buffer
@@ -109,7 +116,7 @@ class TWIBus {
* @param src source data address
* @param bytes the number of bytes to add
*/
void addbytes(char src[], uint8_t bytes);
void addbytes(byte src[], uint8_t bytes);
/**
* @brief Add a null-terminated string to the buffer
@@ -172,7 +179,7 @@ class TWIBus {
* @param bytes the number of bytes to request
* @return the number of bytes captured to the buffer
*/
uint8_t capture(char *dst, const uint8_t bytes);
uint8_t capture(byte *dst, const uint8_t bytes);
/**
* @brief Flush the i2c bus.
+2 -2
View File
@@ -76,7 +76,7 @@
// ignore the status of the g26_debug_flag
if (*title != '!' && !g26_debug_flag) return;
const float de = destination[E_AXIS] - current_position[E_AXIS];
const float de = destination[E_CART] - current_position[E_CART];
if (de == 0.0) return; // Printing moves only
@@ -97,7 +97,7 @@
SERIAL_ECHOPGM(", ");
SERIAL_ECHO_F(current_position[Z_AXIS], 6);
SERIAL_ECHOPGM(", ");
SERIAL_ECHO_F(current_position[E_AXIS], 6);
SERIAL_ECHO_F(current_position[E_CART], 6);
SERIAL_ECHOPGM(" ) destination=( ");
debug_echo_axis(X_AXIS);
SERIAL_ECHOPGM(", ");
-1
View File
@@ -54,7 +54,6 @@ enum MeshPointType : char { INVALID, REAL, SET_IN_BITMAP };
// External references
char *ftostr43sign(const float&, char);
void home_all_axes();
extern uint8_t ubl_cnt;
+4 -4
View File
@@ -296,10 +296,10 @@
// Check for commands that require the printer to be homed
if (may_move) {
if (axis_unhomed_error()) home_all_axes();
#if ENABLED(DUAL_X_CARRIAGE)
if (active_extruder != 0) tool_change(0);
#endif
if (axis_unhomed_error()) home_all_axes();
}
// Invalidate Mesh Points. This command is a little bit asymmetrical because
@@ -1559,12 +1559,12 @@
incremental_LSF(&lsf_results, PROBE_PT_3_X, PROBE_PT_3_Y, measured_z);
}
}
STOW_PROBE();
#ifdef Z_AFTER_PROBING
move_z_after_probing();
#endif
if (abort_flag) {
SERIAL_ECHOPGM("?Error probing point. Aborting operation.\n");
return;
@@ -1625,7 +1625,7 @@
#ifdef Z_AFTER_PROBING
move_z_after_probing();
#endif
if (abort_flag || finish_incremental_LSF(&lsf_results)) {
SERIAL_ECHOPGM("Could not complete LSF!");
return;
+25 -20
View File
@@ -46,8 +46,8 @@
*/
#if ENABLED(SKEW_CORRECTION)
// For skew correction just adjust the destination point and we're done
float start[XYZE] = { current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS] },
end[XYZE] = { destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], destination[E_AXIS] };
float start[XYZE] = { current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_CART] },
end[XYZE] = { destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], destination[E_CART] };
planner.skew(start[X_AXIS], start[Y_AXIS], start[Z_AXIS]);
planner.skew(end[X_AXIS], end[Y_AXIS], end[Z_AXIS]);
#else
@@ -64,7 +64,7 @@
SERIAL_ECHOPAIR(" ubl.line_to_destination_cartesian(xe=", destination[X_AXIS]);
SERIAL_ECHOPAIR(", ye=", destination[Y_AXIS]);
SERIAL_ECHOPAIR(", ze=", destination[Z_AXIS]);
SERIAL_ECHOPAIR(", ee=", destination[E_AXIS]);
SERIAL_ECHOPAIR(", ee=", destination[E_CART]);
SERIAL_CHAR(')');
SERIAL_EOL();
debug_current_and_destination(PSTR("Start of ubl.line_to_destination_cartesian()"));
@@ -85,7 +85,7 @@
+ UBL_Z_RAISE_WHEN_OFF_MESH
#endif
;
planner.buffer_segment(end[X_AXIS], end[Y_AXIS], end[Z_AXIS] + z_raise, end[E_AXIS], feed_rate, extruder);
planner.buffer_segment(end[X_AXIS], end[Y_AXIS], end[Z_AXIS] + z_raise, end[E_CART], feed_rate, extruder);
set_current_from_destination();
if (g26_debug_flag)
@@ -112,7 +112,7 @@
// Undefined parts of the Mesh in z_values[][] are NAN.
// Replace NAN corrections with 0.0 to prevent NAN propagation.
planner.buffer_segment(end[X_AXIS], end[Y_AXIS], end[Z_AXIS] + (isnan(z0) ? 0.0 : z0), end[E_AXIS], feed_rate, extruder);
planner.buffer_segment(end[X_AXIS], end[Y_AXIS], end[Z_AXIS] + (isnan(z0) ? 0.0 : z0), end[E_CART], feed_rate, extruder);
if (g26_debug_flag)
debug_current_and_destination(PSTR("FINAL_MOVE in ubl.line_to_destination_cartesian()"));
@@ -149,7 +149,7 @@
const bool use_x_dist = adx > ady;
float on_axis_distance = use_x_dist ? dx : dy,
e_position = end[E_AXIS] - start[E_AXIS],
e_position = end[E_CART] - start[E_CART],
z_position = end[Z_AXIS] - start[Z_AXIS];
const float e_normalized_dist = e_position / on_axis_distance,
@@ -198,11 +198,11 @@
if (ry != start[Y_AXIS]) {
if (!inf_normalized_flag) {
on_axis_distance = use_x_dist ? rx - start[X_AXIS] : ry - start[Y_AXIS];
e_position = start[E_AXIS] + on_axis_distance * e_normalized_dist;
e_position = start[E_CART] + on_axis_distance * e_normalized_dist;
z_position = start[Z_AXIS] + on_axis_distance * z_normalized_dist;
}
else {
e_position = end[E_AXIS];
e_position = end[E_CART];
z_position = end[Z_AXIS];
}
@@ -249,11 +249,11 @@
if (rx != start[X_AXIS]) {
if (!inf_normalized_flag) {
on_axis_distance = use_x_dist ? rx - start[X_AXIS] : ry - start[Y_AXIS];
e_position = start[E_AXIS] + on_axis_distance * e_normalized_dist; // is based on X or Y because this is a horizontal move
e_position = start[E_CART] + on_axis_distance * e_normalized_dist; // is based on X or Y because this is a horizontal move
z_position = start[Z_AXIS] + on_axis_distance * z_normalized_dist;
}
else {
e_position = end[E_AXIS];
e_position = end[E_CART];
z_position = end[Z_AXIS];
}
@@ -308,11 +308,11 @@
if (!inf_normalized_flag) {
on_axis_distance = use_x_dist ? rx - start[X_AXIS] : next_mesh_line_y - start[Y_AXIS];
e_position = start[E_AXIS] + on_axis_distance * e_normalized_dist;
e_position = start[E_CART] + on_axis_distance * e_normalized_dist;
z_position = start[Z_AXIS] + on_axis_distance * z_normalized_dist;
}
else {
e_position = end[E_AXIS];
e_position = end[E_CART];
z_position = end[Z_AXIS];
}
if (!planner.buffer_segment(rx, next_mesh_line_y, z_position + z0, e_position, feed_rate, extruder))
@@ -331,11 +331,11 @@
if (!inf_normalized_flag) {
on_axis_distance = use_x_dist ? next_mesh_line_x - start[X_AXIS] : ry - start[Y_AXIS];
e_position = start[E_AXIS] + on_axis_distance * e_normalized_dist;
e_position = start[E_CART] + on_axis_distance * e_normalized_dist;
z_position = start[Z_AXIS] + on_axis_distance * z_normalized_dist;
}
else {
e_position = end[E_AXIS];
e_position = end[E_CART];
z_position = end[Z_AXIS];
}
@@ -378,7 +378,12 @@
#if ENABLED(DELTA) // apply delta inverse_kinematics
DELTA_IK(raw);
planner.buffer_segment(delta[A_AXIS], delta[B_AXIS], delta[C_AXIS], in_raw[E_AXIS], fr, active_extruder);
planner.buffer_segment(delta[A_AXIS], delta[B_AXIS], delta[C_AXIS], in_raw[E_CART], fr, active_extruder);
#elif ENABLED(HANGPRINTER) // apply hangprinter inverse_kinematics
HANGPRINTER_IK(raw);
planner.buffer_segment(line_lengths[A_AXIS], line_lengths[B_AXIS], line_lengths[C_AXIS], line_lengths[D_AXIS], in_raw[E_CART], fr, active_extruder);
#elif IS_SCARA // apply scara inverse_kinematics (should be changed to save raw->logical->raw)
@@ -391,11 +396,11 @@
scara_oldB = delta[B_AXIS];
float s_feedrate = MAX(adiff, bdiff) * scara_feed_factor;
planner.buffer_segment(delta[A_AXIS], delta[B_AXIS], delta[C_AXIS], in_raw[E_AXIS], s_feedrate, active_extruder);
planner.buffer_segment(delta[A_AXIS], delta[B_AXIS], delta[C_AXIS], in_raw[E_CART], s_feedrate, active_extruder);
#else // CARTESIAN
planner.buffer_segment(raw[X_AXIS], raw[Y_AXIS], raw[Z_AXIS], in_raw[E_AXIS], fr, active_extruder);
planner.buffer_segment(raw[X_AXIS], raw[Y_AXIS], raw[Z_AXIS], in_raw[E_CART], fr, active_extruder);
#endif
}
@@ -427,7 +432,7 @@
rtarget[X_AXIS] - current_position[X_AXIS],
rtarget[Y_AXIS] - current_position[Y_AXIS],
rtarget[Z_AXIS] - current_position[Z_AXIS],
rtarget[E_AXIS] - current_position[E_AXIS]
rtarget[E_CART] - current_position[E_CART]
};
const float cartesian_xy_mm = HYPOT(total[X_AXIS], total[Y_AXIS]); // total horizontal xy distance
@@ -454,7 +459,7 @@
total[X_AXIS] * inv_segments,
total[Y_AXIS] * inv_segments,
total[Z_AXIS] * inv_segments,
total[E_AXIS] * inv_segments
total[E_CART] * inv_segments
};
// Note that E segment distance could vary slightly as z mesh height
@@ -464,7 +469,7 @@
current_position[X_AXIS],
current_position[Y_AXIS],
current_position[Z_AXIS],
current_position[E_AXIS]
current_position[E_CART]
};
// Only compute leveling per segment if ubl active and target below z_fade_height.
+31 -29
View File
@@ -265,8 +265,8 @@ uint16_t max_display_update_time = 0;
#if ENABLED(SDSUPPORT)
void lcd_sdcard_menu();
void menu_action_sdfile(const char* filename, char* longFilename);
void menu_action_sddirectory(const char* filename, char* longFilename);
void menu_action_sdfile(CardReader& theCard);
void menu_action_sddirectory(CardReader& theCard);
#endif
////////////////////////////////////////////
@@ -756,7 +756,7 @@ void lcd_reset_status() {
msg = paused;
#if ENABLED(SDSUPPORT)
else if (card.sdprinting)
return lcd_setstatus(card.longFilename[0] ? card.longFilename : card.filename, true);
return lcd_setstatus(card.longest_filename(), true);
#endif
else if (print_job_timer.isRunning())
msg = printing;
@@ -874,7 +874,7 @@ void lcd_quick_feedback(const bool clear_buttons) {
lcd_return_to_status();
// Turn leveling off and home
enqueue_and_echo_commands_P(PSTR("M420 S0\nG28"
enqueue_and_echo_commands_P(PSTR("M420 S0\nG28 R0"
#if ENABLED(MARLIN_DEV_MODE)
" S"
#elif !IS_KINEMATIC
@@ -1275,7 +1275,7 @@ void lcd_quick_feedback(const bool clear_buttons) {
ubl_encoderPosition = (ubl.encoder_diff > 0) ? 1 : -1;
ubl.encoder_diff = 0;
mesh_edit_accumulator += float(ubl_encoderPosition) * 0.005f / 2.0f;
mesh_edit_accumulator += float(ubl_encoderPosition) * 0.005f * 0.5f;
mesh_edit_value = mesh_edit_accumulator;
encoderPosition = 0;
lcdDrawUpdate = LCDVIEW_CALL_REDRAW_NEXT;
@@ -2414,9 +2414,6 @@ void lcd_quick_feedback(const bool clear_buttons) {
void _lcd_ubl_output_map_lcd() {
static int16_t step_scaler = 0;
if (!all_axes_known())
return lcd_goto_screen(_lcd_ubl_map_homing);
if (use_click()) return _lcd_ubl_map_lcd_edit_cmd();
ENCODER_DIRECTION_NORMAL();
@@ -2678,6 +2675,13 @@ void lcd_quick_feedback(const bool clear_buttons) {
MENU_ITEM(gcode, MSG_AUTO_HOME_Z, PSTR("G28 Z"));
#endif
//
// TMC Z Calibration
//
#if ENABLED(TMC_Z_CALIBRATION)
MENU_ITEM(gcode, MSG_TMC_Z_CALIBRATION, PSTR("G28\nM915"));
#endif
//
// Level Bed
//
@@ -2922,7 +2926,7 @@ void lcd_quick_feedback(const bool clear_buttons) {
#if EXTRUDERS > 1
const int8_t old_extruder = active_extruder;
active_extruder = manual_move_e_index;
if (manual_move_axis == E_AXIS) active_extruder = manual_move_e_index;
#endif
// Set movement on a single axis
@@ -2948,7 +2952,7 @@ void lcd_quick_feedback(const bool clear_buttons) {
#else
planner.buffer_line_kinematic(current_position, MMM_TO_MMS(manual_feedrate_mm_m[manual_move_axis]), manual_move_e_index);
planner.buffer_line_kinematic(current_position, MMM_TO_MMS(manual_feedrate_mm_m[manual_move_axis]), manual_move_axis == E_AXIS ? manual_move_e_index : active_extruder);
manual_move_axis = (int8_t)NO_AXIS;
#endif
@@ -3073,7 +3077,7 @@ void lcd_quick_feedback(const bool clear_buttons) {
#if IS_KINEMATIC
manual_move_offset += diff;
#else
current_position[E_AXIS] += diff;
current_position[E_CART] += diff;
#endif
manual_move_to_current(E_AXIS
#if E_MANUAL > 1
@@ -3103,7 +3107,7 @@ void lcd_quick_feedback(const bool clear_buttons) {
#endif // E_MANUAL > 2
}
#endif // E_MANUAL > 1
lcd_implementation_drawedit(pos_label, ftostr41sign(current_position[E_AXIS]
lcd_implementation_drawedit(pos_label, ftostr41sign(current_position[E_CART]
#if IS_KINEMATIC
+ manual_move_offset
#endif
@@ -3518,7 +3522,7 @@ void lcd_quick_feedback(const bool clear_buttons) {
MENU_ITEM_EDIT(bool, MSG_AUTOTEMP, &planner.autotemp_enabled);
MENU_ITEM_EDIT(float3, MSG_MIN, &planner.autotemp_min, 0, float(HEATER_0_MAXTEMP) - 15);
MENU_ITEM_EDIT(float3, MSG_MAX, &planner.autotemp_max, 0, float(HEATER_0_MAXTEMP) - 15);
MENU_ITEM_EDIT(float52, MSG_FACTOR, &planner.autotemp_factor, 0.0, 1.0);
MENU_ITEM_EDIT(float52, MSG_FACTOR, &planner.autotemp_factor, 0, 1);
#endif
//
@@ -4034,9 +4038,9 @@ void lcd_quick_feedback(const bool clear_buttons) {
#endif
if (card.filenameIsDir)
MENU_ITEM(sddirectory, MSG_CARD_MENU, card.filename, card.longFilename);
MENU_ITEM(sddirectory, MSG_CARD_MENU, card);
else
MENU_ITEM(sdfile, MSG_CARD_MENU, card.filename, card.longFilename);
MENU_ITEM(sdfile, MSG_CARD_MENU, card);
}
else {
MENU_ITEM_DUMMY();
@@ -4846,13 +4850,13 @@ void lcd_quick_feedback(const bool clear_buttons) {
DEFINE_MENU_EDIT_TYPE(int16_t, int3, itostr3, 1);
DEFINE_MENU_EDIT_TYPE(uint8_t, int8, i8tostr3, 1);
DEFINE_MENU_EDIT_TYPE(float, float3, ftostr3, 1.0f);
DEFINE_MENU_EDIT_TYPE(float, float52, ftostr52, 100.0f);
DEFINE_MENU_EDIT_TYPE(float, float43, ftostr43sign, 1000.0f);
DEFINE_MENU_EDIT_TYPE(float, float3, ftostr3, 1);
DEFINE_MENU_EDIT_TYPE(float, float52, ftostr52, 100);
DEFINE_MENU_EDIT_TYPE(float, float43, ftostr43sign, 1000);
DEFINE_MENU_EDIT_TYPE(float, float5, ftostr5rj, 0.01f);
DEFINE_MENU_EDIT_TYPE(float, float51, ftostr51sign, 10.0f);
DEFINE_MENU_EDIT_TYPE(float, float52sign, ftostr52sign, 100.0f);
DEFINE_MENU_EDIT_TYPE(float, float62, ftostr62rj, 100.0f);
DEFINE_MENU_EDIT_TYPE(float, float51, ftostr51sign, 10);
DEFINE_MENU_EDIT_TYPE(float, float52sign, ftostr52sign, 100);
DEFINE_MENU_EDIT_TYPE(float, float62, ftostr62rj, 100);
DEFINE_MENU_EDIT_TYPE(uint32_t, long5, ftostr5rj, 0.01f);
/**
@@ -4957,19 +4961,17 @@ void lcd_quick_feedback(const bool clear_buttons) {
#if ENABLED(SDSUPPORT)
void menu_action_sdfile(const char* filename, char* longFilename) {
void menu_action_sdfile(CardReader& theCard) {
#if ENABLED(SD_REPRINT_LAST_SELECTED_FILE)
last_sdfile_encoderPosition = encoderPosition; // Save which file was selected for later use
#endif
UNUSED(longFilename);
card.openAndPrintFile(filename);
card.openAndPrintFile(theCard.filename);
lcd_return_to_status();
lcd_reset_status();
}
void menu_action_sddirectory(const char* filename, char* longFilename) {
UNUSED(longFilename);
card.chdir(filename);
void menu_action_sddirectory(CardReader& theCard) {
card.chdir(theCard.filename);
encoderTopLine = 0;
encoderPosition = 2 * ENCODER_STEPS_PER_MENU_ITEM;
screen_changed = true;
@@ -5053,7 +5055,7 @@ void lcd_init() {
#endif
}
int16_t lcd_strlen(const char* s) {
int16_t utf8_strlen(const char* s) {
int16_t i = 0, j = 0;
while (s[i]) {
if (START_OF_UTF8_CHAR(s[i])) j++;
@@ -5062,7 +5064,7 @@ int16_t lcd_strlen(const char* s) {
return j;
}
int16_t lcd_strlen_P(const char* s) {
int16_t utf8_strlen_P(const char* s) {
int16_t j = 0;
while (pgm_read_byte(s)) {
if (START_OF_UTF8_CHAR(pgm_read_byte(s))) j++;
+2 -2
View File
@@ -41,8 +41,8 @@
#include "Marlin.h"
int16_t lcd_strlen(const char* s);
int16_t lcd_strlen_P(const char* s);
int16_t utf8_strlen(const char* s);
int16_t utf8_strlen_P(const char* s);
bool lcd_hasstatus();
void lcd_setstatus(const char* message, const bool persist=false);
void lcd_setstatusPGM(const char* message, const int8_t level=0);
+15 -17
View File
@@ -356,10 +356,8 @@ static void lcd_implementation_init() {
OUT_WRITE(LCD_BACKLIGHT_PIN, HIGH);
#endif
#if ENABLED(MKS_12864OLED) || ENABLED(MKS_12864OLED_SSD1306)
OUT_WRITE(LCD_PINS_RS, LOW);
_delay_ms(500);
OUT_WRITE(LCD_PINS_RS, HIGH);
#if !defined(LCD_RESET_PIN) && (ENABLED(MKS_12864OLED) || ENABLED(MKS_12864OLED_SSD1306))
#define LCD_RESET_PIN LCD_PINS_RS
#endif
#if PIN_EXISTS(LCD_RESET)
@@ -369,7 +367,7 @@ static void lcd_implementation_init() {
_delay_ms(5); // delay to allow the display to initalize
#endif
#if PIN_EXISTS(LCD_RESET) || ENABLED(MKS_12864OLED) || ENABLED(MKS_12864OLED_SSD1306)
#if PIN_EXISTS(LCD_RESET)
u8g.begin();
#endif
@@ -468,7 +466,7 @@ void lcd_implementation_clear() { } // Automatically cleared by Picture Loop
int8_t n = LCD_WIDTH - (START_COL);
if (center && !valstr) {
int8_t pad = (LCD_WIDTH - lcd_strlen_P(pstr)) / 2;
int8_t pad = (LCD_WIDTH - utf8_strlen_P(pstr)) / 2;
while (--pad >= 0) { u8g.print(' '); n--; }
}
while (n > 0 && (c = pgm_read_byte(pstr))) {
@@ -514,7 +512,7 @@ void lcd_implementation_clear() { } // Automatically cleared by Picture Loop
if (!PAGE_CONTAINS(row_y1, row_y2)) return;
const uint8_t vallen = (pgm ? lcd_strlen_P(data) : (lcd_strlen((char*)data)));
const uint8_t vallen = (pgm ? utf8_strlen_P(data) : utf8_strlen((char*)data));
uint8_t n = LCD_WIDTH - (START_COL) - 2 - vallen;
while (char c = pgm_read_byte(pstr)) {
@@ -535,8 +533,8 @@ void lcd_implementation_clear() { } // Automatically cleared by Picture Loop
#define DRAW_BOOL_SETTING(sel, row, pstr, data) lcd_implementation_drawmenu_setting_edit_generic_P(sel, row, pstr, (*(data))?PSTR(MSG_ON):PSTR(MSG_OFF))
void lcd_implementation_drawedit(const char* const pstr, const char* const value=NULL) {
const uint8_t labellen = lcd_strlen_P(pstr),
vallen = lcd_strlen(value);
const uint8_t labellen = utf8_strlen_P(pstr),
vallen = utf8_strlen(value);
uint8_t rows = (labellen > LCD_WIDTH - 2 - vallen) ? 2 : 1;
@@ -586,7 +584,7 @@ void lcd_implementation_clear() { } // Automatically cleared by Picture Loop
#if ENABLED(SDSUPPORT)
static void _drawmenu_sd(const bool isSelected, const uint8_t row, const char* const pstr, const char* filename, char* const longFilename, const bool isDir) {
static void _drawmenu_sd(const bool isSelected, const uint8_t row, const char* const pstr, CardReader& theCard, const bool isDir) {
UNUSED(pstr);
lcd_implementation_mark_as_selected(row, isSelected);
@@ -594,23 +592,23 @@ void lcd_implementation_clear() { } // Automatically cleared by Picture Loop
if (!PAGE_CONTAINS(row_y1, row_y2)) return;
constexpr uint8_t maxlen = LCD_WIDTH - (START_COL) - 1;
const char *outstr = longFilename[0] ? longFilename : filename;
if (longFilename[0]) {
const char *outstr = theCard.longest_filename();
if (theCard.longFilename[0]) {
#if ENABLED(SCROLL_LONG_FILENAMES)
if (isSelected) {
uint8_t name_hash = row;
for (uint8_t l = FILENAME_LENGTH; l--;)
name_hash = ((name_hash << 1) | (name_hash >> 7)) ^ filename[l]; // rotate, xor
name_hash = ((name_hash << 1) | (name_hash >> 7)) ^ theCard.filename[l]; // rotate, xor
if (filename_scroll_hash != name_hash) { // If the hash changed...
filename_scroll_hash = name_hash; // Save the new hash
filename_scroll_max = MAX(0, lcd_strlen(longFilename) - maxlen); // Update the scroll limit
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
}
outstr += filename_scroll_pos;
}
#else
longFilename[maxlen] = '\0'; // cutoff at screen edge
theCard.longFilename[maxlen] = '\0'; // cutoff at screen edge
#endif
}
@@ -625,8 +623,8 @@ void lcd_implementation_clear() { } // Automatically cleared by Picture Loop
while (n) { --n; u8g.print(' '); }
}
#define lcd_implementation_drawmenu_sdfile(sel, row, pstr, filename, longFilename) _drawmenu_sd(sel, row, pstr, filename, longFilename, false)
#define lcd_implementation_drawmenu_sddirectory(sel, row, pstr, filename, longFilename) _drawmenu_sd(sel, row, pstr, filename, longFilename, true)
#define lcd_implementation_drawmenu_sdfile(sel, row, pstr, theCard) _drawmenu_sd(sel, row, pstr, theCard, false)
#define lcd_implementation_drawmenu_sddirectory(sel, row, pstr, theCard) _drawmenu_sd(sel, row, pstr, theCard, true)
#endif // SDSUPPORT

Some files were not shown because too many files have changed in this diff Show More