Commit 2ddac526 authored by MagoKimbra's avatar MagoKimbra

Merge remote-tracking branch 'refs/remotes/origin/master' into dev

parents 43a5e682 8ee235df
......@@ -9,7 +9,6 @@
* - Extruders number
* - Thermistor type
* - Temperature limits
* - UI Language
*
* Mechanisms-settings can be found in Configuration_Xxxxxx.h (where Xxxxxx can be: Cartesian - Delta - Core - Scara)
* Feature-settings can be found in Configuration_Feature.h
......@@ -239,34 +238,4 @@
#define GUM_PREHEAT_FAN_SPEED 255 // Insert Value between 0 and 255
/*****************************************************************************************************/
/***********************************************************************
*************************** UI Language ******************************
***********************************************************************
* *
* Select the language that you prefer and change LANGUAGE_CHOICE *
* *
* 1 English *
* 2 Polish *
* 3 French *
* 4 German *
* 5 Spanish *
* 6 Russian *
* 7 Italian *
* 8 Portuguese *
* 9 Finnish *
* 10 Aragonese *
* 11 Dutch *
* 12 Danish *
* 13 Catalan *
* 14 Basque-Euskera *
* 15 Portuguese (Brazil) *
* 16 Bulgarian *
* 17 Japanese *
* 18 Japanese utf *
* 19 Chinese *
* *
***********************************************************************/
#define LANGUAGE_CHOICE 1
/***********************************************************************/
#endif
......@@ -50,9 +50,11 @@
* - Filament diameter sensor
* - Filament Runout sensor
* - Power consumption sensor
* - RFID card sensor
* ADDON FEATURES:
* - EEPROM
* - SDCARD
* - LCD Language
* - LCD
* - Canon RC-1 Remote
* - Camera trigger
......@@ -1045,6 +1047,29 @@
/**************************************************************************/
/**************************************************************************
*********************** RIFD module card reader **************************
**************************************************************************
* *
* Support RFID module card reader width UART interface. *
* This module mount chip MFRC522 designed to communicate with *
* ISO/IEC 14443 A/MIFARE cards and transponders without additional *
* active circuitry *
* *
* New command for this system is: *
* M522 T<extruder> R<read> or W<write> *
* *
* Define if you used and Serial used. *
* *
**************************************************************************/
//#define RFID_MODULE
#define RFID_SERIAL 1
/**************************************************************************/
//===========================================================================
//============================= ADDON FEATURES ==============================
//===========================================================================
......@@ -1101,9 +1126,25 @@
/*****************************************************************************************/
/************************************************************************************************
********************************************* LCD **********************************************
************************************************************************************************/
/***********************************************************************
*************************** LCD Language ******************************
***********************************************************************
* *
* Here you may choose the language used by MK or MK4due *
* on the LCD menus, the following *
* *
* list of languages are available: *
* en, pl, fr, de, es, ru, it, pt, fi, an, nl, ca, eu *
* pt-br, bg, kana, kana_utf8, cn *
* *
***********************************************************************/
#define LCD_LANGUAGE en
/***********************************************************************/
/***********************************************************************
******************************* LCD ***********************************
***********************************************************************/
//Charset type
//Choose ONE of these 3 charsets. This has to match your hardware.
......
......@@ -51,6 +51,7 @@
#include "module/motion/planner.h"
#include "module/motion/stepper_indirection.h"
#include "module/motion/stepper.h"
#include "module/motion/endstops.h"
#include "module/motion/vector_3.h"
#include "module/motion/qr_solve.h"
#include "module/motion/cartesian_correction.h"
......
......@@ -120,7 +120,6 @@ Stopwatch print_job_timer = Stopwatch();
static uint8_t target_extruder;
bool no_wait_for_cooling = true;
bool software_endstops = true;
unsigned long printer_usage_seconds;
......@@ -811,7 +810,7 @@ void loop() {
commands_in_queue--;
cmd_queue_index_r = (cmd_queue_index_r + 1) % BUFSIZE;
}
checkHitEndstops();
endstops.report_state();
idle();
}
......@@ -1338,17 +1337,17 @@ static void setup_for_endstop_move() {
saved_feedrate_multiplier = feedrate_multiplier;
feedrate_multiplier = 100;
refresh_cmd_timeout();
enable_endstops(true);
endstops.enable();
}
static void clean_up_after_endstop_move() {
#if ENABLED(ENDSTOPS_ONLY_FOR_HOMING)
enable_endstops(false);
if (DEBUGGING(INFO)) ECHO_LM(INFO, "clean_up_after_endstop_move > ENDSTOPS_ONLY_FOR_HOMING > endstops.not_homing()");
#endif
endstops.not_homing();
feedrate = saved_feedrate;
feedrate_multiplier = saved_feedrate_multiplier;
refresh_cmd_timeout();
endstops_hit_on_purpose(); // clear endstop hit flags
}
static void axis_unhomed_error() {
......@@ -1466,6 +1465,12 @@ inline void do_blocking_move_to_z(float z) { do_blocking_move_to(current_positio
static void run_z_probe() {
/**
* To prevent stepper_inactive_time from running out and
* EXTRUDER_RUNOUT_PREVENT from extruding
*/
refresh_cmd_timeout();
plan_bed_level_matrix.set_to_identity();
feedrate = homing_feedrate[Z_AXIS];
......@@ -1482,7 +1487,7 @@ inline void do_blocking_move_to_z(float z) { do_blocking_move_to(current_positio
zPosition += home_bump_mm(Z_AXIS);
line_to_z(zPosition);
st_synchronize();
endstops_hit_on_purpose(); // clear endstop hit flags
endstops.hit_on_purpose(); // clear endstop hit flags
// move back down slowly to find bed
set_homing_bump_feedrate(Z_AXIS);
......@@ -1490,7 +1495,7 @@ inline void do_blocking_move_to_z(float z) { do_blocking_move_to(current_positio
zPosition -= home_bump_mm(Z_AXIS) * 2;
line_to_z(zPosition);
st_synchronize();
endstops_hit_on_purpose(); // clear endstop hit flags
endstops.hit_on_purpose(); // clear endstop hit flags
// Get the current stepper position after bumping an endstop
current_position[Z_AXIS] = st_get_axis_position_mm(Z_AXIS);
......@@ -1504,16 +1509,22 @@ inline void do_blocking_move_to_z(float z) { do_blocking_move_to(current_positio
if (DEBUGGING(INFO))
DEBUG_POS("deploy_z_probe", current_position);
if (endstops.z_probe_enabled) return;
#if HAS(SERVO_ENDSTOPS)
// Engage Z Servo endstop if enabled
if (servo_endstop_id[Z_AXIS] >= 0) servo[servo_endstop_id[Z_AXIS]].move(servo_endstop_angle[Z_AXIS][0]);
#endif
endstops.enable_z_probe();
}
static void stow_z_probe(bool doRaise = true) {
if (DEBUGGING(INFO))
DEBUG_POS("stow_z_probe", current_position);
if (!endstops.z_probe_enabled) return;
#if HAS(SERVO_ENDSTOPS)
// Retract Z Servo endstop if enabled
if (servo_endstop_id[Z_AXIS] >= 0) {
......@@ -1533,6 +1544,8 @@ inline void do_blocking_move_to_z(float z) { do_blocking_move_to(current_positio
servo[servo_endstop_id[Z_AXIS]].move(servo_endstop_angle[Z_AXIS][1]);
}
#endif
endstops.enable_z_probe(false);
}
enum ProbeAction {
......@@ -1661,14 +1674,14 @@ inline void do_blocking_move_to_z(float z) { do_blocking_move_to(current_positio
current_position[axis] = 0;
sync_plan_position();
enable_endstops(false); // Disable endstops while moving away
endstops.enable(false); // Disable endstops while moving away
// Move away from the endstop by the axis HOME_BUMP_MM
destination[axis] = -home_bump_mm(axis) * axis_home_dir;
line_to_destination();
st_synchronize();
enable_endstops(true); // Enable endstops for next homing move
endstops.enable(); // Enable endstops for next homing move
// Slow down the feedrate for the next move
set_homing_bump_feedrate(axis);
......@@ -1715,7 +1728,7 @@ inline void do_blocking_move_to_z(float z) { do_blocking_move_to(current_positio
destination[axis] = current_position[axis];
feedrate = 0.0;
endstops_hit_on_purpose(); // clear endstop hit flags
endstops.hit_on_purpose(); // clear endstop hit flags
axis_known_position[axis] = true;
axis_homed[axis] = true;
......@@ -1778,14 +1791,14 @@ inline void do_blocking_move_to_z(float z) { do_blocking_move_to(current_positio
current_position[axis] = 0;
sync_plan_position();
enable_endstops(false); // Disable endstops while moving away
endstops.enable(false); // Disable endstops while moving away
// Move away from the endstop by the axis HOME_BUMP_MM
destination[axis] = -home_bump_mm(axis) * axis_home_dir;
line_to_destination();
st_synchronize();
enable_endstops(true); // Enable endstops for next homing move
endstops.enable(); // Enable endstops for next homing move
// Slow down the feedrate for the next move
set_homing_bump_feedrate(axis);
......@@ -1797,7 +1810,7 @@ inline void do_blocking_move_to_z(float z) { do_blocking_move_to(current_positio
// retrace by the amount specified in endstop_adj
if (endstop_adj[axis] * axis_home_dir < 0) {
enable_endstops(false); // Disable Endstops while moving away
endstops.enable(false); // Disable Endstops while moving away
sync_plan_position();
destination[axis] = endstop_adj[axis];
if (DEBUGGING(INFO)) {
......@@ -1806,7 +1819,7 @@ inline void do_blocking_move_to_z(float z) { do_blocking_move_to(current_positio
}
line_to_destination();
st_synchronize();
enable_endstops(true); // Enable Endstops for next homing move
endstops.enable(); // Enable Endstops for next homing move
}
if (DEBUGGING(INFO)) ECHO_LMV(INFO, " > endstop_adj * axis_home_dir = ", endstop_adj[axis] * axis_home_dir);
......@@ -1820,7 +1833,7 @@ inline void do_blocking_move_to_z(float z) { do_blocking_move_to(current_positio
destination[axis] = current_position[axis];
feedrate = 0.0;
endstops_hit_on_purpose(); // clear Endstop hit flags
endstops.hit_on_purpose(); // clear Endstop hit flags
axis_known_position[axis] = true;
axis_homed[axis] = true;
}
......@@ -1905,6 +1918,9 @@ inline void do_blocking_move_to_z(float z) { do_blocking_move_to(current_positio
}
static void deploy_z_probe() {
if (endstops.z_probe_enabled) return;
#if HAS(SERVO_ENDSTOPS)
feedrate = homing_feedrate[Z_AXIS];
do_blocking_move_to_z( z_probe_deploy_start_location[Z_AXIS]);
......@@ -1932,19 +1948,23 @@ inline void do_blocking_move_to_z(float z) { do_blocking_move_to(current_positio
z_probe_deploy_start_location[Z_AXIS]);
#endif
endstops.enable_z_probe();
sync_plan_position_delta();
}
static void retract_z_probe() {
if (!endstops.z_probe_enabled) return;
#if HAS(SERVO_ENDSTOPS)
// Retract Z Servo endstop if enabled
if (servo_endstop_id[Z_AXIS] >= 0)
servo[servo_endstop_id[Z_AXIS]].move(servo_endstop_angle[Z_AXIS][1]);
feedrate = homing_feedrate[Z_AXIS];
do_blocking_move_to(z_probe_retract_start_location[X_AXIS],
z_probe_retract_start_location[Y_AXIS],
z_probe_retract_start_location[Z_AXIS]);
// Retract Z Servo endstop if enabled
if (servo_endstop_id[Z_AXIS] >= 0)
servo[servo_endstop_id[Z_AXIS]].move(servo_endstop_angle[Z_AXIS][1]);
#else
feedrate = homing_feedrate[Z_AXIS];
do_blocking_move_to(z_probe_retract_start_location[X_AXIS],
......@@ -1963,13 +1983,14 @@ inline void do_blocking_move_to_z(float z) { do_blocking_move_to(current_positio
z_probe_retract_start_location[Z_AXIS]);
#endif
endstops.enable_z_probe(false);
sync_plan_position_delta();
}
static void run_z_probe() {
refresh_cmd_timeout();
enable_endstops(true);
endstops.enable();
float start_z = current_position[Z_AXIS];
long start_steps = st_get_position(Z_AXIS);
......@@ -1977,9 +1998,9 @@ inline void do_blocking_move_to_z(float z) { do_blocking_move_to(current_positio
destination[Z_AXIS] = -20;
prepare_move_raw();
st_synchronize();
endstops_hit_on_purpose(); // clear endstop hit flags
endstops.hit_on_purpose(); // clear endstop hit flags
enable_endstops(false);
endstops.enable(false);
long stop_steps = st_get_position(Z_AXIS);
float mm = start_z - float(start_steps - stop_steps) / axis_steps_per_unit[Z_AXIS];
current_position[Z_AXIS] = mm;
......@@ -2606,7 +2627,7 @@ inline void do_blocking_move_to_z(float z) { do_blocking_move_to(current_positio
feedrate_multiplier = 100;
refresh_cmd_timeout();
enable_endstops(true);
endstops.enable();
set_destination_to_current();
......@@ -2621,7 +2642,7 @@ inline void do_blocking_move_to_z(float z) { do_blocking_move_to(current_positio
feedrate = 1.732 * homing_feedrate[X_AXIS];
line_to_destination();
st_synchronize();
endstops_hit_on_purpose(); // clear endstop hit flags
endstops.hit_on_purpose(); // clear endstop hit flags
// Destination reached
set_current_to_destination();
......@@ -2634,13 +2655,13 @@ inline void do_blocking_move_to_z(float z) { do_blocking_move_to(current_positio
sync_plan_position_delta();
#if ENABLED(ENDSTOPS_ONLY_FOR_HOMING)
enable_endstops(false);
endstops.enable(false);
#endif
feedrate = saved_feedrate;
feedrate_multiplier = saved_feedrate_multiplier;
refresh_cmd_timeout();
endstops_hit_on_purpose(); // clear endstop hit flags
endstops.hit_on_purpose(); // clear endstop hit flags
}
static void prepare_move_raw() {
......@@ -2779,12 +2800,12 @@ inline void do_blocking_move_to_z(float z) { do_blocking_move_to(current_positio
if (retracting) {
feedrate = retract_feedrate * 60;
current_position[E_AXIS] += (swapping ? retract_length_swap : retract_length) / volumetric_multiplier[active_extruder];
plan_set_e_position(current_position[E_AXIS]);
sync_plan_position_e();
prepare_move();
if (retract_zlift > 0.01) {
current_position[Z_AXIS] -= retract_zlift;
#if MECH(DELTA) || MECH(SCARA)
#if MECH(DELTA)
sync_plan_position_delta();
#else
sync_plan_position();
......@@ -2795,12 +2816,11 @@ inline void do_blocking_move_to_z(float z) { do_blocking_move_to(current_positio
else {
if (retract_zlift > 0.01) {
current_position[Z_AXIS] += retract_zlift;
#if MECH(DELTA) || MECH(SCARA)
#if MECH(DELTA)
sync_plan_position_delta();
#else
sync_plan_position();
#endif
//prepare_move();
}
feedrate = retract_recover_feedrate * 60;
......@@ -2813,8 +2833,8 @@ inline void do_blocking_move_to_z(float z) { do_blocking_move_to(current_positio
feedrate = oldFeedrate;
retracted[active_extruder] = retracting;
} // retract()
#endif //FWRETRACT
}
#endif // FWRETRACT
#if HAS(Z_PROBE_SLED)
......@@ -2912,18 +2932,10 @@ inline void do_blocking_move_to_z(float z) { do_blocking_move_to(current_positio
}
#endif
inline void wait_heater() {
bool wants_to_cool = isCoolingHotend(target_extruder);
// Exit if S<lower>, continue if S<higher>, R<lower>, or R<higher>
if (no_wait_for_cooling && wants_to_cool) return;
// Prevents a wait-forever situation if R is misused i.e. M109 R0
// Try to calculate a ballpark safe margin by halving EXTRUDE_MINTEMP
if (wants_to_cool && degTargetHotend(target_extruder) < (EXTRUDE_MINTEMP)/2) return;
inline void wait_heater(bool no_wait_for_cooling = true) {
#if ENABLED(TEMP_RESIDENCY_TIME)
long residency_start_ms = -1;
millis_t residency_start_ms = -1;
// Loop until the temperature has stabilized
#define TEMP_CONDITIONS (!residency_start_ms || PENDING(now, residency_start_ms + (TEMP_RESIDENCY_TIME) * 1000UL))
#else
......@@ -2931,13 +2943,18 @@ inline void wait_heater() {
#define TEMP_CONDITIONS (wants_to_cool ? isCoolingHotend(target_extruder) : isHeatingHotend(target_extruder))
#endif // TEMP_RESIDENCY_TIME
float theTarget = -1;
bool wants_to_cool;
cancel_heatup = false;
millis_t now, next_temp_ms = 0;
KEEPALIVE_STATE(NOT_BUSY);
do {
now = millis();
if (ELAPSED(now, next_temp_ms)) { //Print temp & remaining time every 1s while waiting
next_temp_ms = now + 1000UL;
#if HAS(TEMP_0) || HAS(TEMP_BED) || ENABLED(HEATER_0_USES_MAX6675)
#if HAS(TEMP_HOTEND) || HAS(TEMP_BED)
print_heaterstates();
#endif
#if TEMP_RESIDENCY_TIME > 0
......@@ -2954,11 +2971,24 @@ inline void wait_heater() {
#endif
}
// Target temperature might be changed during the loop
if (theTarget != degTargetHotend(target_extruder)) {
wants_to_cool = isCoolingHotend(target_extruder);
theTarget = degTargetHotend(target_extruder);
// Exit if S<lower>, continue if S<higher>, R<lower>, or R<higher>
if (no_wait_for_cooling && wants_to_cool) break;
// Prevent a wait-forever situation if R is misused i.e. M109 R0
// Try to calculate a ballpark safe margin by halving EXTRUDE_MINTEMP
if (wants_to_cool && theTarget < (EXTRUDE_MINTEMP) / 2) break;
}
idle();
refresh_cmd_timeout(); // to prevent stepper_inactive_time from running out
#if TEMP_RESIDENCY_TIME > 0
float temp_diff = fabs(degTargetHotend(target_extruder) - degHotend(target_extruder));
float temp_diff = fabs(theTarget - degHotend(target_extruder));
if (!residency_start_ms) {
// Start the TEMP_RESIDENCY_TIME timer when we reach target temp for the first time.
......@@ -2973,13 +3003,10 @@ inline void wait_heater() {
} while(!cancel_heatup && TEMP_CONDITIONS);
LCD_MESSAGEPGM(MSG_HEATING_COMPLETE);
KEEPALIVE_STATE(IN_HANDLER);
}
inline void wait_bed() {
bool wants_to_cool = isCoolingBed();
// Exit if the temperature is above target and not waiting for cooling
if (no_wait_for_cooling && wants_to_cool) return;
inline void wait_bed(bool no_wait_for_cooling = true) {
#if TEMP_BED_RESIDENCY_TIME > 0
millis_t residency_start_ms = 0;
......@@ -2990,9 +3017,13 @@ inline void wait_bed() {
#define TEMP_BED_CONDITIONS (wants_to_cool ? isCoolingBed() : isHeatingBed())
#endif // TEMP_BED_RESIDENCY_TIME > 0
float theTarget = -1;
bool wants_to_cool;
cancel_heatup = false;
millis_t now, next_temp_ms = 0;
KEEPALIVE_STATE(NOT_BUSY);
// Wait for temperature to come close enough
do {
now = millis();
......@@ -3013,11 +3044,24 @@ inline void wait_bed() {
#endif
}
// Target temperature might be changed during the loop
if (theTarget != degTargetBed()) {
wants_to_cool = isCoolingBed();
theTarget = degTargetBed();
// Exit if S<lower>, continue if S<higher>, R<lower>, or R<higher>
if (no_wait_for_cooling && wants_to_cool) break;
// Prevent a wait-forever situation if R is misused i.e. M190 R0
// Simply don't wait to cool a bed under 30C
if (wants_to_cool && theTarget < 30) break;
}
idle();
refresh_cmd_timeout(); // to prevent stepper_inactive_time from running out
#if TEMP_BED_RESIDENCY_TIME > 0
float temp_diff = fabs(degBed() - degTargetBed());
float temp_diff = fabs(theTarget - degTargetBed());
if (!residency_start_ms) {
// Start the TEMP_BED_RESIDENCY_TIME timer when we reach target temp for the first time.
......@@ -3031,6 +3075,7 @@ inline void wait_bed() {
} while (!cancel_heatup && TEMP_BED_CONDITIONS);
LCD_MESSAGEPGM(MSG_BED_DONE);
KEEPALIVE_STATE(IN_HANDLER);
}
......@@ -3297,7 +3342,7 @@ inline void gcode_G28() {
feedrate = 1.732 * homing_feedrate[X_AXIS];
line_to_destination();
st_synchronize();
endstops_hit_on_purpose(); // clear endstop hit flags
endstops.hit_on_purpose(); // clear endstop hit flags
// Destination reached
for (int i = X_AXIS; i <= Z_AXIS; i++) current_position[i] = destination[i];
......@@ -3376,7 +3421,7 @@ inline void gcode_G28() {
line_to_destination();
feedrate = 0.0;
st_synchronize();
endstops_hit_on_purpose(); // clear endstop hit flags
endstops.hit_on_purpose(); // clear endstop hit flags
current_position[X_AXIS] = destination[X_AXIS];
current_position[Y_AXIS] = destination[Y_AXIS];
......@@ -3445,7 +3490,7 @@ inline void gcode_G28() {
feedrate_multiplier = 100;
refresh_cmd_timeout();
enable_endstops(true);
endstops.enable();
for(uint8_t i = 0; i < NUM_AXIS; i++) {
destination[i] = current_position[i];
}
......@@ -3461,13 +3506,13 @@ inline void gcode_G28() {
sync_plan_position();
#if ENABLED(ENDSTOPS_ONLY_FOR_HOMING)
enable_endstops(false);
endstops.enable(false);
#endif
feedrate = saved_feedrate;
feedrate_multiplier = saved_feedrate_multiplier;
refresh_cmd_timeout();
endstops_hit_on_purpose(); // clear endstop hit flags
endstops.hit_on_purpose(); // clear endstop hit flags
sync_plan_position();
......@@ -5435,9 +5480,7 @@ inline void gcode_M109() {
if (target_extruder != active_extruder) return;
#endif
LCD_MESSAGEPGM(MSG_HEATING);
no_wait_for_cooling = code_seen('S');
bool no_wait_for_cooling = code_seen('S');
if (no_wait_for_cooling || code_seen('R')) {
float temp = code_value();
setTargetHotend(temp, target_extruder);
......@@ -5451,7 +5494,7 @@ inline void gcode_M109() {
* stand by mode, for instance in a dual extruder setup, without affecting
* the running print timer.
*/
if (temp <= (EXTRUDE_MINTEMP)/2) {
if (temp <= (EXTRUDE_MINTEMP) / 2) {
print_job_timer.stop();
LCD_MESSAGEPGM(WELCOME_MSG);
}
......@@ -5472,7 +5515,7 @@ inline void gcode_M109() {
if (code_seen('B')) autotemp_max = code_value();
#endif
wait_heater();
wait_heater(no_wait_for_cooling);
}
/**
......@@ -5550,50 +5593,17 @@ inline void gcode_M115() {
/**
* M119: Output endstop states to serial output
*/
inline void gcode_M119() {
ECHO_LM(DB, SERIAL_M119_REPORT);
#if HAS(X_MIN)
ECHO_EMT(SERIAL_X_MIN, ((READ(X_MIN_PIN)^X_MIN_ENDSTOP_INVERTING)?SERIAL_ENDSTOP_HIT:SERIAL_ENDSTOP_OPEN));
#endif
#if HAS(X_MAX)
ECHO_EMT(SERIAL_X_MAX, ((READ(X_MAX_PIN)^X_MAX_ENDSTOP_INVERTING)?SERIAL_ENDSTOP_HIT:SERIAL_ENDSTOP_OPEN));
#endif
#if HAS(Y_MIN)
ECHO_EMT(SERIAL_Y_MIN, ((READ(Y_MIN_PIN)^Y_MIN_ENDSTOP_INVERTING)?SERIAL_ENDSTOP_HIT:SERIAL_ENDSTOP_OPEN));
#endif
#if HAS(Y_MAX)
ECHO_EMT(SERIAL_Y_MAX, ((READ(Y_MAX_PIN)^Y_MAX_ENDSTOP_INVERTING)?SERIAL_ENDSTOP_HIT:SERIAL_ENDSTOP_OPEN));
#endif
#if HAS(Z_MIN)
ECHO_EMT(SERIAL_Z_MIN, ((READ(Z_MIN_PIN)^Z_MIN_ENDSTOP_INVERTING)?SERIAL_ENDSTOP_HIT:SERIAL_ENDSTOP_OPEN));
#endif
#if HAS(Z_MAX)
ECHO_EMT(SERIAL_Z_MAX, ((READ(Z_MAX_PIN)^Z_MAX_ENDSTOP_INVERTING)?SERIAL_ENDSTOP_HIT:SERIAL_ENDSTOP_OPEN));
#endif
#if HAS(Z2_MAX)
ECHO_EMT(SERIAL_Z2_MAX, ((READ(Z2_MAX_PIN)^Z2_MAX_ENDSTOP_INVERTING)?SERIAL_ENDSTOP_HIT:SERIAL_ENDSTOP_OPEN));
#endif
#if HAS(Z_PROBE)
ECHO_EMT(SERIAL_Z_PROBE, ((READ(Z_PROBE_PIN)^Z_PROBE_ENDSTOP_INVERTING)?SERIAL_ENDSTOP_HIT:SERIAL_ENDSTOP_OPEN));
#endif
#if HAS(E_MIN)
ECHO_EMT(SERIAL_E_MIN, ((READ(E_MIN_PIN)^E_MIN_ENDSTOP_INVERTING)?SERIAL_ENDSTOP_HIT:SERIAL_ENDSTOP_OPEN));
#endif
#if HAS(FILRUNOUT)
ECHO_EMT(SERIAL_FILRUNOUT_PIN, ((READ(FILRUNOUT_PIN)^FILRUNOUT_PIN_INVERTING)?SERIAL_ENDSTOP_HIT:SERIAL_ENDSTOP_OPEN));
#endif
ECHO_E;
}
inline void gcode_M119() { endstops.M119(); }
/**
* M120: Enable endstops
* M120: Enable endstops and set non-homing endstop state to "enabled"
*/
inline void gcode_M120() { enable_endstops(true); }
inline void gcode_M120() { endstops.enable_globally(true); }
/**
* M121: Disable endstops
* M121: Disable endstops and set non-homing endstop state to "disabled"
*/
inline void gcode_M121() { enable_endstops(false); }
inline void gcode_M121() { endstops.enable_globally(false); }
/**
* M122: Disable or enable software endstops
......@@ -5792,10 +5802,10 @@ inline void gcode_M140() {
if (DEBUGGING(DRYRUN)) return;
LCD_MESSAGEPGM(MSG_BED_HEATING);
no_wait_for_cooling = code_seen('S');
bool no_wait_for_cooling = code_seen('S');
if (no_wait_for_cooling || code_seen('R')) setTargetBed(code_value());
wait_bed();
wait_bed(no_wait_for_cooling);
}
#endif // HAS(TEMP_BED)
......@@ -7329,6 +7339,7 @@ inline void gcode_M999() {
*/
inline void gcode_T(uint8_t tmp_extruder) {
bool good_extruder = false;
float stored_feedrate = feedrate;
#if ENABLED(COLOR_MIXING_EXTRUDER) && MIXING_VIRTUAL_TOOLS > 1
......@@ -7347,21 +7358,18 @@ inline void gcode_T(uint8_t tmp_extruder) {
good_extruder = true;
target_extruder = tmp_extruder;
#if ENABLED(DONDOLO)
bool make_move = true;
#else
bool make_move = false;
#endif
if (code_seen('F')) {
#if EXTRUDERS > 1
make_move = true;
#endif
float next_feedrate = code_value();
if (next_feedrate > 0.0) feedrate = next_feedrate;
if (next_feedrate > 0.0) stored_feedrate = feedrate = next_feedrate;
}
else {
#if ENABLED(XY_TRAVEL_SPEED)
feedrate = XY_TRAVEL_SPEED;
#else
feedrate = min(max_feedrate[X_AXIS], max_feedrate[Y_AXIS]);
#endif
}
#if EXTRUDERS > 1
#if ENABLED(NPR2)
if(target_extruder != old_color)
......@@ -7603,7 +7611,7 @@ inline void gcode_T(uint8_t tmp_extruder) {
sync_plan_position();
#endif // !DELTA
// Move to the old position if 'F' was in the parameters
if (make_move && IsRunning()) prepare_move();
if (IsRunning()) prepare_move();
}
#if ENABLED(EXT_SOLENOID)
......@@ -7616,6 +7624,8 @@ inline void gcode_T(uint8_t tmp_extruder) {
}
#endif // !COLOR_MIXING_EXTRUDER
feedrate = stored_feedrate;
if (!good_extruder) {
ECHO_SMV(DB, "T", (int)tmp_extruder);
ECHO_EM(" " SERIAL_INVALID_EXTRUDER);
......@@ -8314,12 +8324,8 @@ static void report_current_position() {
adjust_delta(target);
if (DEBUGGING(DEBUG)) {
ECHO_LMV(DEB, "target[X_AXIS]=", target[X_AXIS]);
ECHO_LMV(DEB, "target[Y_AXIS]=", target[Y_AXIS]);
ECHO_LMV(DEB, "target[Z_AXIS]=", target[Z_AXIS]);
ECHO_LMV(DEB, "delta[TOWER_1]=", delta[TOWER_1]);
ECHO_LMV(DEB, "delta[TOWER_2]=", delta[TOWER_2]);
ECHO_LMV(DEB, "delta[TOWER_3]=", delta[TOWER_3]);
DEBUG_POS("prepare_move_delta", target);
DEBUG_POS("prepare_move_delta", delta);
}
plan_buffer_line(delta[TOWER_1], delta[TOWER_2], delta[TOWER_3], target[E_AXIS], frfm, active_extruder, active_driver);
......@@ -8404,13 +8410,10 @@ void prepare_move() {
if (!prepare_move_scara(destination)) return;
#elif MECH(DELTA)
if (!prepare_move_delta(destination)) return;
#endif
#else
#if ENABLED(DUAL_X_CARRIAGE)
if (!prepare_move_dual_x_carriage()) return;
#endif
#if MECH(CARTESIAN) || MECH(COREXY) || MECH(COREYX) || MECH(COREXZ) || MECH(COREZX)
if (!prepare_move_cartesian()) return;
#endif
......
......@@ -368,6 +368,17 @@
#define Y_MAX_LENGTH (Y_MAX_POS - (Y_MIN_POS))
#define Z_MAX_LENGTH (Z_MAX_POS - (Z_MIN_POS))
/**
* CoreXY or CoreYX or CoreXZ or CoreZX
*/
#if MECH(COREXY) || MECH(COREYX)
#define CORE_AXIS_2 B_AXIS
#define CORE_AXIS_3 Z_AXIS
#elif MECH(COREXZ) || MECH(COREZX)
#define CORE_AXIS_2 C_AXIS
#define CORE_AXIS_3 Y_AXIS
#endif
/**
* SCARA
*/
......@@ -740,6 +751,10 @@
#define HAS_DIGIPOTSS (PIN_EXISTS(DIGIPOTSS))
#define HAS_TEMP_HOTEND (HAS_TEMP_0 || ENABLED(HEATER_0_USES_MAX6675))
#define HAS_THERMALLY_PROTECTED_BED (HAS_TEMP_BED && HAS_HEATER_BED && ENABLED(THERMAL_PROTECTION_BED))
/**
* Shorthand for filament sensor and power sensor for ultralcd.cpp, dogm_lcd_implementation.h, ultralcd_implementation_hitachi_HD44780.h
*/
......
......@@ -23,32 +23,9 @@
#ifndef LANGUAGE_H
#define LANGUAGE_H
// NOTE: IF YOU CHANGE LANGUAGE FILES OR MERGE A FILE WITH CHANGES
//
// ==> ALWAYS TRY TO COMPILE MARLIN WITH/WITHOUT "ULTIPANEL" / "ULTRALCD" / "SDSUPPORT" #define IN "Configuration_Basic.h"
// ==> ALSO TRY ALL AVAILABLE "LANGUAGE_CHOICE" OPTIONS
// See also documentation/LCDLanguageFont.md
// Languages
// 1 English // Language base
// 2 Polish
// 3 French
// 4 German
// 5 Spanish
// 6 Russian
// 7 Italian
// 8 Portuguese
// 9 Finnish
// 10 Aragonese
// 11 Dutch
// 12 Danish
// 13 Catalan
// 14 Basque-Euskera
// 15 Portuguese (Brazil)
// 16 Bulgarian
// 17 Japanese
// 18 Japanese utf
// 19 Chinese
#ifndef LCD_LANGUAGE
#define LCD_LANGUAGE en
#endif
#define PROTOCOL_VERSION "2.0"
......@@ -251,45 +228,13 @@
#define SERIAL_BED_LEVELLING_Y " Y: "
#define SERIAL_BED_LEVELLING_Z " Z: "
#if LANGUAGE_CHOICE == 1 // English
#include "language_en.h"
#elif LANGUAGE_CHOICE == 2 // Polish
#include "language_pl.h"
#elif LANGUAGE_CHOICE == 3 // French
#include "language_fr.h"
#elif LANGUAGE_CHOICE == 4 // German
#include "language_de.h"
#elif LANGUAGE_CHOICE == 5 // Spanish
#include "language_es.h"
#elif LANGUAGE_CHOICE == 6 // Russian
#define MAPPER_D0D1 // For Cyrillic
#include "language_ru.h"
#elif LANGUAGE_CHOICE == 7 // Italian
#include "language_it.h"
#elif LANGUAGE_CHOICE == 8 // Portuguese
#include "language_pt.h"
#elif LANGUAGE_CHOICE == 9 // Finnish
#include "language_fi.h"
#elif LANGUAGE_CHOICE == 10 // Aragonese
#include "language_an.h"
#elif LANGUAGE_CHOICE == 11 // Dutch
#include "language_nl.h"
#elif LANGUAGE_CHOICE == 12 // Danish
#include "language_da.h"
#elif LANGUAGE_CHOICE == 13 // Catalan
#include "language_ca.h"
#elif LANGUAGE_CHOICE == 14 // Basque-Euskera
#include "language_eu.h"
#elif LANGUAGE_CHOICE == 15 // Portuguese - Brasil
#include "language_pt-br.h"
#elif LANGUAGE_CHOICE == 16 // Bulgarian
#include "language_bg.h"
#elif LANGUAGE_CHOICE == 17 // Japanese
#include "language_kana.h"
#elif LANGUAGE_CHOICE == 18 // Japanese utf
#include "language_kana_utf8.h"
#elif LANGUAGE_CHOICE == 19 // Chinese
#include "language_cn.h"
#endif
// LCD Menu Messages
#define LANGUAGE_INCL_(M) STRINGIFY_(language_##M.h)
#define LANGUAGE_INCL(M) LANGUAGE_INCL_(M)
#define INCLUDE_LANGUAGE LANGUAGE_INCL(LCD_LANGUAGE)
#include "language_en.h"
#include INCLUDE_LANGUAGE
#endif //__LANGUAGE_H
......@@ -195,8 +195,8 @@
FORCE_INLINE void lcd_reset_alert_level() {}
FORCE_INLINE bool lcd_detected(void) { return true; }
#define LCD_MESSAGEPGM(x) do{}while(0)
#define LCD_ALERTMESSAGEPGM(x) do{}while(0)
#define LCD_MESSAGEPGM(x) NOOP
#define LCD_ALERTMESSAGEPGM(x) NOOP
#endif //ULTRA_LCD
......
......@@ -76,4 +76,6 @@
#define NOOP do{}while(0)
#define _AXIS(AXIS) AXIS ##_AXIS
#endif //__MACROS_H
/**
* MK & MK4due 3D Printer Firmware
*
* Based on Marlin, Sprinter and grbl
* Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
* Copyright (C) 2013 - 2016 Alberto Cotronei @MagoKimbra
*
* 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/>.
*
*/
/**
* endstops.cpp - A singleton object to manage endstops
*/
#include "../../base.h"
#include "endstops.h"
// TEST_ENDSTOP: test the old and the current status of an endstop
#define TEST_ENDSTOP(ENDSTOP) (TEST(current_endstop_bits & old_endstop_bits, ENDSTOP))
Endstops endstops;
Endstops::Endstops() {
enable_globally(
#if ENABLED(ENDSTOPS_ONLY_FOR_HOMING)
true
#else
false
#endif
);
enable(true);
#if ENABLED(HAS_Z_PROBE)
enable_z_probe(false);
#endif
} // Endstops::Endstops
void Endstops::init() {
#if HAS(X_MIN)
SET_INPUT(X_MIN_PIN);
#if ENABLED(ENDSTOPPULLUP_XMIN)
PULLUP(X_MIN_PIN, HIGH);
#endif
#endif
#if HAS(Y_MIN)
SET_INPUT(Y_MIN_PIN);
#if ENABLED(ENDSTOPPULLUP_YMIN)
PULLUP(Y_MIN_PIN, HIGH);
#endif
#endif
#if HAS(Z_MIN)
SET_INPUT(Z_MIN_PIN);
#if ENABLED(ENDSTOPPULLUP_ZMIN)
PULLUP(Z_MIN_PIN, HIGH);
#endif
#endif
#if HAS(Z2_MIN)
SET_INPUT(Z2_MIN_PIN);
#if ENABLED(ENDSTOPPULLUP_Z2MIN)
PULLUP(Z2_MIN_PIN, HIGH);
#endif
#endif
#if HAS(E_MIN)
SET_INPUT(E_MIN_PIN);
#if ENABLED(ENDSTOPPULLUP_EMIN)
PULLUP(E_MIN_PIN, HIGH);
#endif
#endif
#if HAS(X_MAX)
SET_INPUT(X_MAX_PIN);
#if ENABLED(ENDSTOPPULLUP_XMAX)
PULLUP(X_MAX_PIN, HIGH);
#endif
#endif
#if HAS(Y_MAX)
SET_INPUT(Y_MAX_PIN);
#if ENABLED(ENDSTOPPULLUP_YMAX)
PULLUP(Y_MAX_PIN, HIGH);
#endif
#endif
#if HAS(Z_MAX)
SET_INPUT(Z_MAX_PIN);
#if ENABLED(ENDSTOPPULLUP_ZMAX)
PULLUP(Z_MAX_PIN, HIGH);
#endif
#endif
#if HAS(Z2_MAX)
SET_INPUT(Z2_MAX_PIN);
#if ENABLED(ENDSTOPPULLUP_Z2MAX)
PULLUP(Z2_MAX_PIN, HIGH);
#endif
#endif
#if HAS(Z_PROBE) // Check for Z_PROBE_ENDSTOP so we don't pull a pin high unless it's to be used.
SET_INPUT(Z_PROBE_PIN);
#if ENABLED(ENDSTOPPULLUP_ZPROBE)
PULLUP(Z_PROBE_PIN, HIGH);
#endif
#endif
} // Endstops::init
void Endstops::report_state() {
if (endstop_hit_bits) {
#if ENABLED(ULTRA_LCD)
char chrX = ' ', chrY = ' ', chrZ = ' ', chrP = ' ';
#define _SET_STOP_CHAR(A,C) (chr## A = C)
#else
#define _SET_STOP_CHAR(A,C) ;
#endif
#define _ENDSTOP_HIT_ECHO(A,C) do{ \
ECHO_MV(" " STRINGIFY(A) ":", triggered_position_mm(A ##_AXIS)); \
_SET_STOP_CHAR(A,C); }while(0)
#define _ENDSTOP_HIT_TEST(A,C) \
if (TEST(endstop_hit_bits, A ##_MIN) || TEST(endstop_hit_bits, A ##_MAX)) \
_ENDSTOP_HIT_ECHO(A,C)
ECHO_SM(ER, SERIAL_ENDSTOPS_HIT);
_ENDSTOP_HIT_TEST(X, 'X');
_ENDSTOP_HIT_TEST(Y, 'Y');
_ENDSTOP_HIT_TEST(Z, 'Z');
#if ENABLED(Z_PROBE_ENDSTOP)
#define P_AXIS Z_AXIS
if (TEST(endstop_hit_bits, Z_PROBE)) _ENDSTOP_HIT_ECHO(P, 'P');
#endif
ECHO_E;
#if ENABLED(ULTRA_LCD)
char msg[3 * strlen(MSG_ENDSTOPS_HIT) + 8 + 1]; // Room for a UTF 8 string
sprintf_P(msg, PSTR(MSG_ENDSTOPS_HIT " %c %c %c %c"), chrX, chrY, chrZ, chrP);
lcd_setstatus(msg);
#endif
hit_on_purpose();
#if ENABLED(ABORT_ON_ENDSTOP_HIT_FEATURE_ENABLED) && ENABLED(SDSUPPORT)
if (abort_on_endstop_hit) {
card.sdprinting = false;
card.closefile();
quickStop();
disable_all_heaters(); // switch off all heaters.
}
#endif
}
} // Endstops::report_state
void Endstops::M119() {
ECHO_LM(DB, SERIAL_M119_REPORT);
#if HAS(X_MIN)
ECHO_EMT(SERIAL_X_MIN, ((READ(X_MIN_PIN)^X_MIN_ENDSTOP_INVERTING)?SERIAL_ENDSTOP_HIT:SERIAL_ENDSTOP_OPEN));
#endif
#if HAS(X_MAX)
ECHO_EMT(SERIAL_X_MAX, ((READ(X_MAX_PIN)^X_MAX_ENDSTOP_INVERTING)?SERIAL_ENDSTOP_HIT:SERIAL_ENDSTOP_OPEN));
#endif
#if HAS(Y_MIN)
ECHO_EMT(SERIAL_Y_MIN, ((READ(Y_MIN_PIN)^Y_MIN_ENDSTOP_INVERTING)?SERIAL_ENDSTOP_HIT:SERIAL_ENDSTOP_OPEN));
#endif
#if HAS(Y_MAX)
ECHO_EMT(SERIAL_Y_MAX, ((READ(Y_MAX_PIN)^Y_MAX_ENDSTOP_INVERTING)?SERIAL_ENDSTOP_HIT:SERIAL_ENDSTOP_OPEN));
#endif
#if HAS(Z_MIN)
ECHO_EMT(SERIAL_Z_MIN, ((READ(Z_MIN_PIN)^Z_MIN_ENDSTOP_INVERTING)?SERIAL_ENDSTOP_HIT:SERIAL_ENDSTOP_OPEN));
#endif
#if HAS(Z_MAX)
ECHO_EMT(SERIAL_Z_MAX, ((READ(Z_MAX_PIN)^Z_MAX_ENDSTOP_INVERTING)?SERIAL_ENDSTOP_HIT:SERIAL_ENDSTOP_OPEN));
#endif
#if HAS(Z2_MAX)
ECHO_EMT(SERIAL_Z2_MAX, ((READ(Z2_MAX_PIN)^Z2_MAX_ENDSTOP_INVERTING)?SERIAL_ENDSTOP_HIT:SERIAL_ENDSTOP_OPEN));
#endif
#if HAS(Z_PROBE)
ECHO_EMT(SERIAL_Z_PROBE, ((READ(Z_PROBE_PIN)^Z_PROBE_ENDSTOP_INVERTING)?SERIAL_ENDSTOP_HIT:SERIAL_ENDSTOP_OPEN));
#endif
#if HAS(E_MIN)
ECHO_EMT(SERIAL_E_MIN, ((READ(E_MIN_PIN)^E_MIN_ENDSTOP_INVERTING)?SERIAL_ENDSTOP_HIT:SERIAL_ENDSTOP_OPEN));
#endif
#if HAS(FILRUNOUT)
ECHO_EMT(SERIAL_FILRUNOUT_PIN, ((READ(FILRUNOUT_PIN)^FILRUNOUT_PIN_INVERTING)?SERIAL_ENDSTOP_HIT:SERIAL_ENDSTOP_OPEN));
#endif
} // Endstops::M119
#if ENABLED(Z_DUAL_ENDSTOPS)
// Pass the result of the endstop test
void Endstops::test_dual_z_endstops(EndstopEnum es1, EndstopEnum es2) {
byte z_test = TEST_ENDSTOP(es1) | (TEST_ENDSTOP(es2) << 1); // bit 0 for Z, bit 1 for Z2
if (current_block->steps[Z_AXIS] > 0) {
endstop_triggered(Z_AXIS);
SBI(endstop_hit_bits, Z_MIN);
if (!performing_homing || (z_test == 0x3)) //if not performing home or if both endstops were trigged during homing...
kill_current_block();
}
}
#endif
// Check endstops - Called from ISR!
void Endstops::update() {
#define _ENDSTOP_PIN(AXIS, MINMAX) AXIS ##_## MINMAX ##_PIN
#define _ENDSTOP_INVERTING(AXIS, MINMAX) AXIS ##_## MINMAX ##_ENDSTOP_INVERTING
#define _ENDSTOP_HIT(AXIS) SBI(endstop_hit_bits, _ENDSTOP(AXIS, MIN))
#define _ENDSTOP(AXIS, MINMAX) AXIS ##_## MINMAX
// UPDATE_ENDSTOP_BIT: set the current endstop bits for an endstop to its status
#define UPDATE_ENDSTOP_BIT(AXIS, MINMAX) SET_BIT(current_endstop_bits, _ENDSTOP(AXIS, MINMAX), (READ(_ENDSTOP_PIN(AXIS, MINMAX)) != _ENDSTOP_INVERTING(AXIS, MINMAX)))
// COPY_BIT: copy the value of COPY_BIT to BIT in bits
#define COPY_BIT(bits, COPY_BIT, BIT) SET_BIT(bits, BIT, TEST(bits, COPY_BIT))
#define UPDATE_ENDSTOP(AXIS,MINMAX) do { \
UPDATE_ENDSTOP_BIT(AXIS, MINMAX); \
if (TEST_ENDSTOP(_ENDSTOP(AXIS, MINMAX)) && current_block->steps[_AXIS(AXIS)] > 0) { \
_ENDSTOP_HIT(AXIS); \
endstop_triggered(_AXIS(AXIS)); \
} \
} while(0)
#if MECH(COREXY) || MECH(COREYX)|| MECH(COREXZ) || MECH(COREZX)
// Head direction in -X axis for CoreXY and CoreXZ bots.
// If Delta1 == -Delta2, the movement is only in Y or Z axis
if ((current_block->steps[A_AXIS] != current_block->steps[CORE_AXIS_2]) || (motor_direction(A_AXIS) == motor_direction(CORE_AXIS_2))) {
if (motor_direction(X_HEAD))
#else
if (motor_direction(X_AXIS)) // stepping along -X axis (regular Cartesian bot)
#endif
{ // -direction
#if ENABLED(DUAL_X_CARRIAGE)
// with 2 x-carriages, endstops are only checked in the homing direction for the active extruder
if ((current_block->active_driver == 0 && X_HOME_DIR == -1) || (current_block->active_driver != 0 && X2_HOME_DIR == -1))
#endif
{
#if HAS(X_MIN)
UPDATE_ENDSTOP(X, MIN);
#endif
}
}
else { // +direction
#if ENABLED(DUAL_X_CARRIAGE)
// with 2 x-carriages, endstops are only checked in the homing direction for the active extruder
if ((current_block->active_driver == 0 && X_HOME_DIR == 1) || (current_block->active_driver != 0 && X2_HOME_DIR == 1))
#endif
{
#if HAS(X_MAX)
UPDATE_ENDSTOP(X, MAX);
#endif
}
}
#if MECH(COREXY) || MECH(COREYX) || MECH(COREXZ) || MECH(COREZX)
}
#endif
#if MECH(COREXY) || MECH(COREYX)
// Head direction in -Y axis for CoreXY bots.
// If DeltaX == DeltaY, the movement is only in X axis
if ((current_block->steps[A_AXIS] != current_block->steps[B_AXIS]) || (motor_direction(A_AXIS) != motor_direction(B_AXIS))) {
if (motor_direction(Y_HEAD))
#else
if (motor_direction(Y_AXIS)) // -direction
#endif
{ // -direction
#if HAS(Y_MIN)
UPDATE_ENDSTOP(Y, MIN);
#endif
}
else { // +direction
#if HAS(Y_MAX)
UPDATE_ENDSTOP(Y, MAX);
#endif
}
#if MECH(COREXY) || MECH(COREYX)
}
#endif
#if MECH(COREXZ) || MECH(COREZX)
// Head direction in -Z axis for CoreXZ bots.
// If DeltaX == DeltaZ, the movement is only in X axis
if ((current_block->steps[A_AXIS] != current_block->steps[C_AXIS]) || (motor_direction(A_AXIS) != motor_direction(C_AXIS))) {
if (motor_direction(Z_HEAD))
#else
if (motor_direction(Z_AXIS))
#endif
{ // z -direction
#if HAS(Z_MIN)
#if ENABLED(Z_DUAL_ENDSTOPS)
UPDATE_ENDSTOP_BIT(Z, MIN);
#if HAS_Z2_MIN
UPDATE_ENDSTOP_BIT(Z2, MIN);
#else
COPY_BIT(current_endstop_bits, Z_MIN, Z2_MIN);
#endif
test_dual_z_endstops(Z_MIN, Z2_MIN);
#else // !Z_DUAL_ENDSTOPS
UPDATE_ENDSTOP(Z, MIN);
#endif // !Z_DUAL_ENDSTOPS
#endif // HAS_Z_MIN
#if ENABLED(Z_PROBE_ENDSTOP)
if (z_probe_enabled) {
UPDATE_ENDSTOP(Z, PROBE);
if (TEST_ENDSTOP(Z_PROBE)) SBI(endstop_hit_bits, Z_PROBE);
}
#endif
}
else { // z +direction
#if HAS(Z_MAX)
#if ENABLED(Z_DUAL_ENDSTOPS)
UPDATE_ENDSTOP_BIT(Z, MAX);
#if HAS_Z2_MAX
UPDATE_ENDSTOP_BIT(Z2, MAX);
#else
COPY_BIT(current_endstop_bits, Z_MAX, Z2_MAX);
#endif
test_dual_z_endstops(Z_MAX, Z2_MAX);
#else // !Z_DUAL_ENDSTOPS
UPDATE_ENDSTOP(Z, MAX);
#endif // !Z_DUAL_ENDSTOPS
#endif // Z_MAX_PIN
}
#if MECH(COREXZ) || MECH(COREZX)
}
#endif
#if ENABLED(NPR2)
UPDATE_ENDSTOP(E, MIN);
#endif
old_endstop_bits = current_endstop_bits;
} // Endstops::update()
/**
* MK & MK4due 3D Printer Firmware
*
* Based on Marlin, Sprinter and grbl
* Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
* Copyright (C) 2013 - 2016 Alberto Cotronei @MagoKimbra
*
* 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/>.
*
*/
/**
* endstops.h - manages endstops
*/
#ifndef ENDSTOPS_H
#define ENDSTOPS_H
enum EndstopEnum {X_MIN = 0, Y_MIN = 1, Z_MIN = 2, Z_PROBE = 3, X_MAX = 4, Y_MAX = 5, Z_MAX = 6, Z2_MIN = 7, Z2_MAX = 8, E_MIN = 9};
class Endstops {
public:
volatile char endstop_hit_bits; // use X_MIN, Y_MIN, Z_MIN and Z_PROBE as BIT value
#if ENABLED(Z_DUAL_ENDSTOPS)
uint16_t current_endstop_bits = 0,
old_endstop_bits = 0;
#else
byte current_endstop_bits = 0,
old_endstop_bits = 0;
#endif
bool enabled = true;
bool enabled_globally =
#if ENABLED(ENDSTOPS_ONLY_FOR_HOMING)
false
#else
true
#endif
;
Endstops();
/**
* Initialize the endstop pins
*/
void init();
/**
* Update the endstops bits from the pins
*/
void update();
/**
* Print an error message reporting the position when the endstops were last hit.
*/
void report_state(); //call from somewhere to create an serial error message with the locations the endstops where hit, in case they were triggered
/**
* Report endstop positions in response to M119
*/
void M119();
// Enable / disable endstop checking globally
FORCE_INLINE void enable_globally(bool onoff = true) { enabled_globally = enabled = onoff; }
// Enable / disable endstop checking
FORCE_INLINE void enable(bool onoff = true) { enabled = onoff; }
// Disable / Enable endstops based on ENSTOPS_ONLY_FOR_HOMING and global enable
FORCE_INLINE void not_homing() { enabled = enabled_globally; }
// Clear endstops (i.e., they were hit intentionally) to suppress the report
FORCE_INLINE void hit_on_purpose() { endstop_hit_bits = 0; }
// Enable / disable endstop z-probe checking
#if ENABLED(HAS_Z_PROBE)
volatile bool z_probe_enabled = false;
FORCE_INLINE void enable_z_probe(bool onoff = true) { z_probe_enabled = onoff; }
#endif
private:
#if ENABLED(Z_DUAL_ENDSTOPS)
void test_dual_z_endstops(EndstopEnum es1, EndstopEnum es2);
#endif
};
extern Endstops endstops;
#endif // ENDSTOPS_H
......@@ -992,7 +992,7 @@ float junction_deviation = 0.1;
// Compute and limit the acceleration rate for the trapezoid generator.
float steps_per_mm = block->step_event_count / block->millimeters;
unsigned long bsx = block->steps[X_AXIS], bsy = block->steps[Y_AXIS], bsz = block->steps[Z_AXIS], bse = block->steps[E_AXIS];
long bsx = block->steps[X_AXIS], bsy = block->steps[Y_AXIS], bsz = block->steps[Z_AXIS], bse = block->steps[E_AXIS];
if (bsx == 0 && bsy == 0 && bsz == 0) {
block->acceleration_st = ceil(retract_acceleration[extruder] * steps_per_mm); // convert to: acceleration steps/sec^2
}
......
......@@ -68,11 +68,6 @@ block_t* current_block; // A pointer to the block currently being traced
static unsigned char last_direction_bits = 0; // The next stepping-bits to be output
static unsigned int cleaning_buffer_counter = 0;
//
// The direction of a single motor
//
FORCE_INLINE bool motor_direction(AxisEnum axis) { return TEST(last_direction_bits, axis); }
#if ENABLED(Z_DUAL_ENDSTOPS)
static bool performing_homing = false,
locked_z_motor = false,
......@@ -81,7 +76,9 @@ FORCE_INLINE bool motor_direction(AxisEnum axis) { return TEST(last_direction_bi
// Counter variables for the Bresenham line tracer
static long counter_X, counter_Y, counter_Z, counter_E;
volatile static unsigned long step_events_completed; // The number of step events executed in the current block
volatile unsigned long step_events_completed; // The number of step events executed in the current block
volatile long endstops_trigsteps[3];
volatile long endstops_stepsTotal, endstops_stepsDone;
#if ENABLED(ADVANCE) || ENABLED(ADVANCE_LPC)
unsigned char old_OCR0A;
......@@ -91,7 +88,7 @@ volatile static unsigned long step_events_completed; // The number of step event
static long e_steps[6];
#elif ENABLED(ADVANCE_LPC)
int extruder_advance_k = ADVANCE_LPC_K;
volatile int e_steps[EXTRUDERS];
volatile int e_steps[EXTRUDERS] = ARRAY_BY_EXTRUDERS(0);
static int final_estep_rate;
static int current_estep_rate[EXTRUDERS]; // Actual extruder speed [steps/s]
static int current_adv_steps[EXTRUDERS];
......@@ -105,25 +102,6 @@ static uint8_t step_loops;
static uint8_t step_loops_nominal;
static unsigned short OCR1A_nominal;
volatile long endstops_trigsteps[3] = { 0 };
volatile long endstops_stepsTotal, endstops_stepsDone;
static volatile char endstop_hit_bits = 0; // use X_MIN, Y_MIN, Z_MIN and Z_PROBE as BIT value
#if ENABLED(Z_DUAL_ENDSTOPS) || ENABLED(NPR2)
static uint16_t
#else
static byte
#endif
old_endstop_bits = 0; // use X_MIN, X_MAX... Z_MAX, Z_PROBE, Z2_MIN, Z2_MAX, E_MIN
#if ENABLED(ABORT_ON_ENDSTOP_HIT_FEATURE_ENABLED)
#if ENABLED(ABORT_ON_ENDSTOP_HIT_INIT)
bool abort_on_endstop_hit = ABORT_ON_ENDSTOP_HIT_INIT;
#else
bool abort_on_endstop_hit = false;
#endif
#endif
#if PIN_EXISTS(MOTOR_CURRENT_PWM_XY)
int motor_current_setting[3] = DEFAULT_PWM_MOTOR_CURRENT;
#endif
......@@ -290,273 +268,23 @@ volatile signed char count_direction[NUM_AXIS] = { 1 };
#define ENABLE_STEPPER_DRIVER_INTERRUPT() SBI(TIMSK1, OCIE1A)
#define DISABLE_STEPPER_DRIVER_INTERRUPT() CBI(TIMSK1, OCIE1A)
void endstops_hit_on_purpose() {
endstop_hit_bits = 0;
}
void checkHitEndstops() {
if (endstop_hit_bits) {
#if ENABLED(ABORT_ON_ENDSTOP_HIT_FEATURE_ENABLED)
if (abort_on_endstop_hit)
ECHO_SM(ER, SERIAL_ENDSTOPS_HIT);
else
ECHO_SM(DB, SERIAL_ENDSTOPS_HIT);
#else
ECHO_SM(DB, SERIAL_ENDSTOPS_HIT);
#endif
if (TEST(endstop_hit_bits, X_MIN)) {
ECHO_MV(SERIAL_ENDSTOP_X, (float)endstops_trigsteps[X_AXIS] / axis_steps_per_unit[X_AXIS]);
LCD_MESSAGEPGM(MSG_ENDSTOPS_HIT MSG_ENDSTOP_XS);
}
if (TEST(endstop_hit_bits, Y_MIN)) {
ECHO_MV(SERIAL_ENDSTOP_Y, (float)endstops_trigsteps[Y_AXIS] / axis_steps_per_unit[Y_AXIS]);
LCD_MESSAGEPGM(MSG_ENDSTOPS_HIT MSG_ENDSTOP_YS);
}
if (TEST(endstop_hit_bits, Z_MIN)) {
ECHO_MV(SERIAL_ENDSTOP_Z, (float)endstops_trigsteps[Z_AXIS] / axis_steps_per_unit[Z_AXIS]);
LCD_MESSAGEPGM(MSG_ENDSTOPS_HIT MSG_ENDSTOP_ZS);
}
#if ENABLED(Z_PROBE_ENDSTOP)
if (TEST(endstop_hit_bits, Z_PROBE)) {
ECHO_MV(SERIAL_ENDSTOP_PROBE, (float)endstops_trigsteps[Z_AXIS] / axis_steps_per_unit[Z_AXIS]);
LCD_MESSAGEPGM(MSG_ENDSTOPS_HIT MSG_ENDSTOP_ZPS);
}
#endif
#if ENABLED(NPR2)
if (TEST(endstop_hit_bits, E_MIN)) {
ECHO_MV(SERIAL_ENDSTOP_E, (float)endstops_trigsteps[E_AXIS] / axis_steps_per_unit[E_AXIS]);
LCD_MESSAGEPGM(MSG_ENDSTOPS_HIT MSG_ENDSTOP_ES);
}
#endif
ECHO_E;
#if ENABLED(ABORT_ON_ENDSTOP_HIT_FEATURE_ENABLED)
if (abort_on_endstop_hit && !(endstop_hit_bits & _BV(Z_PROBE)) && !(endstop_hit_bits & _BV(E_MIN))) {
#if ENABLED(SDSUPPORT)
card.sdprinting = false;
card.closeFile();
#endif
for (int i = 0; i < 3; i++) axis_known_position[i] = true; // not homed anymore
quickStop(); // kill the planner buffer
Stop(); // restart by M999
}
#endif
endstops_hit_on_purpose();
}
}
#if MECH(COREXY) || MECH(COREYX)
#define CORE_AXIS_2 B_AXIS
#elif MECH(COREXZ) || MECH(COREZX)
#define CORE_AXIS_2 C_AXIS
#endif
void enable_endstops(bool check) { check_endstops = check; }
// Check endstops - Called from ISR!
inline void update_endstops() {
#if ENABLED(Z_DUAL_ENDSTOPS) || ENABLED(NPR2)
uint16_t
#else
byte
#endif
current_endstop_bits = 0;
#define _ENDSTOP_PIN(AXIS, MINMAX) AXIS ##_## MINMAX ##_PIN
#define _ENDSTOP_INVERTING(AXIS, MINMAX) AXIS ##_## MINMAX ##_ENDSTOP_INVERTING
#define _AXIS(AXIS) AXIS ##_AXIS
#define _ENDSTOP_HIT(AXIS) SBI(endstop_hit_bits, _ENDSTOP(AXIS, MIN))
#define _ENDSTOP(AXIS, MINMAX) AXIS ##_## MINMAX
// SET_ENDSTOP_BIT: set the current endstop bits for an endstop to its status
#define SET_ENDSTOP_BIT(AXIS, MINMAX) SET_BIT(current_endstop_bits, _ENDSTOP(AXIS, MINMAX), (READ(_ENDSTOP_PIN(AXIS, MINMAX)) != _ENDSTOP_INVERTING(AXIS, MINMAX)))
// COPY_BIT: copy the value of COPY_BIT to BIT in bits
#define COPY_BIT(bits, COPY_BIT, BIT) SET_BIT(bits, BIT, TEST(bits, COPY_BIT))
// TEST_ENDSTOP: test the old and the current status of an endstop
#define TEST_ENDSTOP(ENDSTOP) (TEST(current_endstop_bits, ENDSTOP) && TEST(old_endstop_bits, ENDSTOP))
#if MECH(COREXY) || MECH(COREYX)|| MECH(COREXZ) || MECH(COREZX)
#define _SET_TRIGSTEPS(AXIS) do { \
float axis_pos = count_position[_AXIS(AXIS)]; \
if (_AXIS(AXIS) == A_AXIS) \
axis_pos = (axis_pos + count_position[CORE_AXIS_2]) / 2; \
else if (_AXIS(AXIS) == CORE_AXIS_2) \
axis_pos = (count_position[A_AXIS] - axis_pos) / 2; \
endstops_trigsteps[_AXIS(AXIS)] = axis_pos; \
} while(0)
#else
#define _SET_TRIGSTEPS(AXIS) endstops_trigsteps[_AXIS(AXIS)] = count_position[_AXIS(AXIS)]
#endif // COREXY || COREYX || COREXZ || COREZX
#define UPDATE_ENDSTOP(AXIS,MINMAX) do { \
SET_ENDSTOP_BIT(AXIS, MINMAX); \
if (TEST_ENDSTOP(_ENDSTOP(AXIS, MINMAX)) && current_block->steps[_AXIS(AXIS)] > 0) { \
_SET_TRIGSTEPS(AXIS); \
_ENDSTOP_HIT(AXIS); \
step_events_completed = current_block->step_event_count; \
} \
} while(0)
#if MECH(COREXY) || MECH(COREYX)|| MECH(COREXZ) || MECH(COREZX)
// Head direction in -X axis for CoreXY and CoreXZ bots.
// If Delta1 == -Delta2, the movement is only in Y or Z axis
if ((current_block->steps[A_AXIS] != current_block->steps[CORE_AXIS_2]) || motor_direction(A_AXIS) == motor_direction(CORE_AXIS_2)) {
if (motor_direction(X_HEAD))
#else
if (motor_direction(X_AXIS)) // stepping along -X axis (regular Cartesian bot)
#endif
{ // -direction
#if ENABLED(DUAL_X_CARRIAGE)
// with 2 x-carriages, endstops are only checked in the homing direction for the active extruder
if ((current_block->active_extruder == 0 && X_HOME_DIR == -1) || (current_block->active_extruder != 0 && X2_HOME_DIR == -1))
#endif
{
#if HAS(X_MIN)
UPDATE_ENDSTOP(X, MIN);
#endif
}
}
else { // +direction
#if ENABLED(DUAL_X_CARRIAGE)
// with 2 x-carriages, endstops are only checked in the homing direction for the active extruder
if ((current_block->active_extruder == 0 && X_HOME_DIR == 1) || (current_block->active_extruder != 0 && X2_HOME_DIR == 1))
#endif
{
#if HAS(X_MAX)
UPDATE_ENDSTOP(X, MAX);
#endif
}
}
#if MECH(COREXY) || MECH(COREYX)|| MECH(COREXZ) || MECH(COREZX)
}
#endif
#if MECH(COREXY) || MECH(COREYX)
// Head direction in -Y axis for CoreXY bots.
// If DeltaX == DeltaY, the movement is only in X axis
if ((current_block->steps[A_AXIS] != current_block->steps[B_AXIS]) || motor_direction(A_AXIS) != motor_direction(B_AXIS)) {
if (motor_direction(Y_HEAD))
#else
if (motor_direction(Y_AXIS)) // -direction
#endif
{ // -direction
#if HAS(Y_MIN)
UPDATE_ENDSTOP(Y, MIN);
#endif
}
else { // +direction
#if HAS(Y_MAX)
UPDATE_ENDSTOP(Y, MAX);
#endif
}
#if MECH(COREXY) || MECH(COREYX)
}
#endif
#if MECH(COREXZ) || MECH(COREZX)
// Head direction in -Z axis for CoreXZ bots.
// If DeltaX == DeltaZ, the movement is only in X axis
if ((current_block->steps[A_AXIS] != current_block->steps[C_AXIS]) || motor_direction(A_AXIS) != motor_direction(C_AXIS)) {
if (motor_direction(Z_HEAD))
#else
if (motor_direction(Z_AXIS))
#endif
{ // z -direction
#if HAS(Z_MIN)
#if ENABLED(Z_DUAL_ENDSTOPS)
SET_ENDSTOP_BIT(Z, MIN);
#if HAS(Z2_MIN)
SET_ENDSTOP_BIT(Z2, MIN);
#else
COPY_BIT(current_endstop_bits, Z_MIN, Z2_MIN);
#endif
byte z_test = TEST_ENDSTOP(Z_MIN) | (TEST_ENDSTOP(Z2_MIN) << 1); // bit 0 for Z, bit 1 for Z2
if (z_test && current_block->steps[Z_AXIS] > 0) { // z_test = Z_MIN || Z2_MIN
endstops_trigsteps[Z_AXIS] = count_position[Z_AXIS];
SBI(endstop_hit_bits, Z_MIN);
if (!performing_homing || (z_test == 0x3)) //if not performing home or if both endstops were trigged during homing...
step_events_completed = current_block->step_event_count;
}
#else // !Z_DUAL_ENDSTOPS
UPDATE_ENDSTOP(Z, MIN);
#endif // !Z_DUAL_ENDSTOPS
#endif // Z_MIN_PIN
#if ENABLED(Z_PROBE_ENDSTOP)
UPDATE_ENDSTOP(Z, PROBE);
if (TEST_ENDSTOP(Z_PROBE)) {
endstops_trigsteps[Z_AXIS] = count_position[Z_AXIS];
SBI(endstop_hit_bits, Z_PROBE);
}
#endif
}
else { // z +direction
#if HAS(Z_MAX)
#if ENABLED(Z_DUAL_ENDSTOPS)
SET_ENDSTOP_BIT(Z, MAX);
#if HAS(Z2_MAX)
SET_ENDSTOP_BIT(Z2, MAX);
#else
COPY_BIT(current_endstop_bits, Z_MAX, Z2_MAX);
#endif
byte z_test = TEST_ENDSTOP(Z_MAX) | (TEST_ENDSTOP(Z2_MAX) << 1); // bit 0 for Z, bit 1 for Z2
if (z_test && current_block->steps[Z_AXIS] > 0) { // t_test = Z_MAX || Z2_MAX
endstops_trigsteps[Z_AXIS] = count_position[Z_AXIS];
SBI(endstop_hit_bits, Z_MIN);
if (!performing_homing || (z_test == 0x3)) //if not performing home or if both endstops were trigged during homing...
step_events_completed = current_block->step_event_count;
}
#else // !Z_DUAL_ENDSTOPS
UPDATE_ENDSTOP(Z, MAX);
#endif // !Z_DUAL_ENDSTOPS
#endif // Z_MAX_PIN
}
#if MECH(COREXZ) || MECH(COREZX)
}
#endif
#if ENABLED(NPR2)
UPDATE_ENDSTOP(E, MIN);
#endif
old_endstop_bits = current_endstop_bits;
}
// __________________________
// /| |\ _________________ ^
// / | | \ /| |\ |
// / | | \ / | | \ s
// / | | | | | \ p
// / | | | | | \ e
// +-----+------------------------+---+--+---------------+----+ e
// | BLOCK 1 | BLOCK 2 | d
//
// time ----->
//
// The trapezoid is the shape the speed curve over time. It starts at block->initial_rate, accelerates
// first block->accelerate_until step_events_completed, then keeps going at constant speed until
// step_events_completed reaches block->decelerate_after after which it decelerates until the trapezoid generator is reset.
// The slope of acceleration is calculated using v = u + at where t is the accumulated timer values of the steps so far.
/**
* __________________________
* /| |\ _________________ ^
* / | | \ /| |\ |
* / | | \ / | | \ s
* / | | | | | \ p
* / | | | | | \ e
* +-----+------------------------+---+--+---------------+----+ e
* | BLOCK 1 | BLOCK 2 | d
*
* time ----->
*
* The trapezoid is the shape the speed curve over time. It starts at block->initial_rate, accelerates
* first block->accelerate_until step_events_completed, then keeps going at constant speed until
* step_events_completed reaches block->decelerate_after after which it decelerates until the trapezoid generator is reset.
* The slope of acceleration is calculated using v = u + at where t is the accumulated timer values of the steps so far.
*/
void st_wake_up() {
// TCNT1 = 0;
ENABLE_STEPPER_DRIVER_INTERRUPT();
......@@ -728,7 +456,11 @@ ISR(TIMER1_COMPA_vect) {
if (current_block != NULL) {
// Update endstops state, if enabled
if (check_endstops) update_endstops();
#if ENABLED(Z_PROBE_ENDSTOP)
if (endstops.enabled || endstops.z_probe_enabled) endstops.update();
#else
if (endstops.enabled) endstops.update();
#endif
// Take multiple steps per interrupt (For high speed moves)
for (uint8_t i = 0; i < step_loops; i++) {
......@@ -1100,77 +832,10 @@ void st_init() {
OUT_WRITE_RELE(E1E3_CHOICE_PIN, LOW);
#endif
//endstops and pullups
#if HAS(X_MIN)
SET_INPUT(X_MIN_PIN);
#if ENABLED(ENDSTOPPULLUP_XMIN)
PULLUP(X_MIN_PIN, HIGH);
#endif
#endif
#if HAS(Y_MIN)
SET_INPUT(Y_MIN_PIN);
#if ENABLED(ENDSTOPPULLUP_YMIN)
PULLUP(Y_MIN_PIN, HIGH);
#endif
#endif
#if HAS(Z_MIN)
SET_INPUT(Z_MIN_PIN);
#if ENABLED(ENDSTOPPULLUP_ZMIN)
PULLUP(Z_MIN_PIN, HIGH);
#endif
#endif
#if HAS(Z2_MIN)
SET_INPUT(Z2_MIN_PIN);
#if ENABLED(ENDSTOPPULLUP_Z2MIN)
PULLUP(Z2_MIN_PIN, HIGH);
#endif
#endif
#if HAS(E_MIN)
SET_INPUT(E_MIN_PIN);
#if ENABLED(ENDSTOPPULLUP_EMIN)
PULLUP(E_MIN_PIN, HIGH);
#endif
#endif
#if HAS(X_MAX)
SET_INPUT(X_MAX_PIN);
#if ENABLED(ENDSTOPPULLUP_XMAX)
PULLUP(X_MAX_PIN, HIGH);
#endif
#endif
#if HAS(Y_MAX)
SET_INPUT(Y_MAX_PIN);
#if ENABLED(ENDSTOPPULLUP_YMAX)
PULLUP(Y_MAX_PIN, HIGH);
#endif
#endif
#if HAS(Z_MAX)
SET_INPUT(Z_MAX_PIN);
#if ENABLED(ENDSTOPPULLUP_ZMAX)
PULLUP(Z_MAX_PIN, HIGH);
#endif
#endif
#if HAS(Z2_MAX)
SET_INPUT(Z2_MAX_PIN);
#if ENABLED(ENDSTOPPULLUP_Z2MAX)
PULLUP(Z2_MAX_PIN, HIGH);
#endif
#endif
#if HAS(Z_PROBE) // Check for Z_PROBE_ENDSTOP so we don't pull a pin high unless it's to be used.
SET_INPUT(Z_PROBE_PIN);
#if ENABLED(ENDSTOPPULLUP_ZPROBE)
PULLUP(Z_PROBE_PIN, HIGH);
#endif
#endif
//
// Init endstops and pullups here
//
endstops.init();
#define _STEP_INIT(AXIS) AXIS ##_STEP_INIT
#define _WRITE_STEP(AXIS, HIGHLOW) AXIS ##_STEP_WRITE(HIGHLOW)
......@@ -1261,7 +926,7 @@ void st_init() {
#endif // ADVANCE or ADVANCE_LPC
enable_endstops(true); // Start with endstops active. After homing they can be disabled
endstops.enable(true); // Start with endstops active. After homing they can be disabled
sei();
set_stepper_direction(); // Init directions to last_direction_bits = 0
......@@ -1383,6 +1048,26 @@ void quickStop() {
ENABLE_STEPPER_DRIVER_INTERRUPT();
}
void endstop_triggered(AxisEnum axis) {
#if MECH(COREXY) || MECH(COREYX) || MECH(COREXZ) || MECH(COREZX)
float axis_pos = count_position[axis];
if (axis == A_AXIS)
axis_pos = (axis_pos + count_position[CORE_AXIS_2]) / 2;
else if (axis == CORE_AXIS_2)
axis_pos = (count_position[A_AXIS] - axis_pos) / 2;
endstops_trigsteps[axis] = axis_pos;
#else // ! COREXY || COREYX || COREXZ || COREZX
endstops_trigsteps[axis] = count_position[axis];
#endif // ! COREXY || COREYX || COREXZ || COREZX
kill_current_block();
}
void report_positions() {
CRITICAL_SECTION_START;
long xpos = count_position[X_AXIS],
......@@ -1420,6 +1105,16 @@ void report_positions() {
ECHO_E;
}
void kill_current_block() {
step_events_completed = current_block->step_event_count;
}
float triggered_position_mm(AxisEnum axis) {
return endstops_trigsteps[axis] / axis_steps_per_unit[axis];
}
bool motor_direction(AxisEnum axis) { return TEST(last_direction_bits, axis); }
#if ENABLED(NPR2)
void colorstep(long csteps,const bool direction) {
enable_e1();
......
......@@ -34,11 +34,14 @@
* A_AXIS and C_AXIS are used by COREXZ or COREZX printers
* X_HEAD and Y_HEAD and Z_HEAD is used for systems that don't have a 1:1 relationship between X_AXIS and X Head movement, like CoreXY bots.
*/
enum AxisEnum {X_AXIS=0, A_AXIS=0, Y_AXIS=1, B_AXIS=1, Z_AXIS=2, C_AXIS=2, E_AXIS=3, X_HEAD=4, Y_HEAD=5, Z_HEAD=5};
enum EndstopEnum {X_MIN=0, Y_MIN=1, Z_MIN=2, Z_PROBE=3, X_MAX=4, Y_MAX=5, Z_MAX=6, Z2_MIN=7, Z2_MAX=8, E_MIN=9};
enum AxisEnum {X_AXIS = 0, A_AXIS = 0, Y_AXIS = 1, B_AXIS = 1, Z_AXIS = 2, C_AXIS = 2, E_AXIS = 3, X_HEAD = 4, Y_HEAD = 5, Z_HEAD = 5};
#if ENABLED(ABORT_ON_ENDSTOP_HIT_FEATURE_ENABLED)
extern bool abort_on_endstop_hit;
#if ENABLED(ABORT_ON_ENDSTOP_HIT_INIT)
bool abort_on_endstop_hit = ABORT_ON_ENDSTOP_HIT_INIT;
#else
bool abort_on_endstop_hit = false;
#endif
#endif
// Initialize and start the stepper motor subsystem
......@@ -69,10 +72,20 @@
//
void report_positions();
void checkHitEndstops(); //call from somewhere to create an serial error message with the locations the endstops where hit, in case they were triggered
void endstops_hit_on_purpose(); //avoid creation of the message, i.e. after homing and before a routine call of checkHitEndstops();
//
// Handle a triggered endstop
//
void endstop_triggered(AxisEnum axis);
//
// Triggered position of an axis in mm (not core-savvy)
//
float triggered_position_mm(AxisEnum axis);
void enable_endstops(bool check); // Enable/disable endstop checking
//
// The direction of a single motor
//
bool motor_direction(AxisEnum axis);
void checkStepperErrors(); //Print errors detected by the stepper
......@@ -91,6 +104,7 @@
void digipot_current(uint8_t driver, int current);
void microstep_init();
void microstep_readings();
void kill_current_block();
#if ENABLED(Z_DUAL_ENDSTOPS)
void In_Homing_Process(bool state);
......
......@@ -29,29 +29,29 @@ Stopwatch::Stopwatch() {
void Stopwatch::stop() {
#if ENABLED(DEBUG_STOPWATCH)
debug(PSTR("stop"));
Stopwatch::debug(PSTR("stop"));
#endif
if (!this->isRunning()) return;
this->status = STPWTCH_STOPPED;
this->state = STPWTCH_STOPPED;
this->stopTimestamp = millis();
}
void Stopwatch::pause() {
#if ENABLED(DEBUG_STOPWATCH)
debug(PSTR("pause"));
Stopwatch::debug(PSTR("pause"));
#endif
if (!this->isRunning()) return;
this->status = STPWTCH_PAUSED;
this->state = STPWTCH_PAUSED;
this->stopTimestamp = millis();
}
void Stopwatch::start() {
#if ENABLED(DEBUG_STOPWATCH)
debug(PSTR("start"));
Stopwatch::debug(PSTR("start"));
#endif
if (this->isRunning()) return;
......@@ -59,27 +59,27 @@ void Stopwatch::start() {
if (this->isPaused()) this->accumulator = this->duration();
else this->reset();
this->status = STPWTCH_RUNNING;
this->state = STPWTCH_RUNNING;
this->startTimestamp = millis();
}
void Stopwatch::reset() {
#if ENABLED(DEBUG_STOPWATCH)
debug(PSTR("reset"));
Stopwatch::debug(PSTR("reset"));
#endif
this->status = STPWTCH_STOPPED;
this->state = STPWTCH_STOPPED;
this->startTimestamp = 0;
this->stopTimestamp = 0;
this->accumulator = 0;
}
bool Stopwatch::isRunning() {
return (this->status == STPWTCH_RUNNING) ? true : false;
return (this->state == STPWTCH_RUNNING) ? true : false;
}
bool Stopwatch::isPaused() {
return (this->status == STPWTCH_PAUSED) ? true : false;
return (this->state == STPWTCH_PAUSED) ? true : false;
}
uint16_t Stopwatch::duration() {
......
......@@ -26,7 +26,7 @@
// Print debug messages with M111 S2 (Uses 156 bytes of PROGMEM)
//#define DEBUG_STOPWATCH
enum StopwatchStatus {
enum StopwatchState {
STPWTCH_STOPPED,
STPWTCH_RUNNING,
STPWTCH_PAUSED
......@@ -39,7 +39,7 @@
*/
class Stopwatch {
private:
StopwatchStatus status;
StopwatchState state;
uint16_t accumulator;
uint32_t startTimestamp;
uint32_t stopTimestamp;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment