Commit f32fb713 authored by Simone Primarosa's avatar Simone Primarosa

Update 4.2.0 RC

Compilation test passed
parent 9e22582c
...@@ -52,12 +52,6 @@ ...@@ -52,12 +52,6 @@
// Bed Printer radius // Bed Printer radius
#define PRINTER_RADIUS 75 // mm #define PRINTER_RADIUS 75 // mm
// Radius for probe
#define DELTA_PROBABLE_RADIUS (PRINTER_RADIUS)
// Effective horizontal distance bridged by diagonal push rods.
#define DEFAULT_DELTA_RADIUS (DELTA_SMOOTH_ROD_OFFSET-DELTA_EFFECTOR_OFFSET-DELTA_CARRIAGE_OFFSET)
// Uncomment to enable autocalibration debug messages // Uncomment to enable autocalibration debug messages
#define DEBUG_MESSAGES #define DEBUG_MESSAGES
......
...@@ -2,3 +2,498 @@ ...@@ -2,3 +2,498 @@
* Configuration_Overall.h * Configuration_Overall.h
* Here you can define all your custom settings and they will overwrite configurations in the main configuration files. * Here you can define all your custom settings and they will overwrite configurations in the main configuration files.
*/ */
#define MECHANISM MECH_CARTESIAN
#define BAUDRATE 115200
#define MOTHERBOARD BOARD_RAMPS_13_EFB
#define POWER_SUPPLY 0
#define TEMP_SENSOR_0 1
#define TEMP_SENSOR_1 0
#define TEMP_SENSOR_2 0
#define TEMP_SENSOR_3 0
#define TEMP_SENSOR_BED 4
#define HEATER_0_MAXTEMP 275
#define HEATER_1_MAXTEMP 275
#define HEATER_2_MAXTEMP 275
#define HEATER_3_MAXTEMP 275
#define BED_MAXTEMP 150
#define HEATER_0_MINTEMP 5
#define HEATER_1_MINTEMP 5
#define HEATER_2_MINTEMP 5
#define HEATER_3_MINTEMP 5
#define BED_MINTEMP 5
#define PLA_PREHEAT_HOTEND_TEMP 190
#define PLA_PREHEAT_HPB_TEMP 60
#define PLA_PREHEAT_FAN_SPEED 255
#define ABS_PREHEAT_HOTEND_TEMP 240
#define ABS_PREHEAT_HPB_TEMP 100
#define ABS_PREHEAT_FAN_SPEED 255
#define GUM_PREHEAT_HOTEND_TEMP 230
#define GUM_PREHEAT_HPB_TEMP 60
#define GUM_PREHEAT_FAN_SPEED 255
#define EXTRUDERS 4
#define DRIVER_EXTRUDERS 1
#define LANGUAGE_CHOICE 7
#define CUSTOM_MACHINE_NAME "Prusa I3"
#undef ENDSTOPPULLUPS
#define ENDSTOPPULLUP_YMIN
#define ENDSTOPPULLUP_Z2MIN
#define ENDSTOPPULLUP_XMAX
#define ENDSTOPPULLUP_YMAX
#define ENDSTOPPULLUP_ZMAX
#define ENDSTOPPULLUP_Z2MAX
#define ENDSTOPPULLUP_ZPROBE
#define ENDSTOPPULLUP_EMIN
#define X_MIN_ENDSTOP_LOGIC false
#define Y_MIN_ENDSTOP_LOGIC false
#define Z_MIN_ENDSTOP_LOGIC false
#define Z2_MIN_ENDSTOP_LOGIC false
#define X_MAX_ENDSTOP_LOGIC false
#define Y_MAX_ENDSTOP_LOGIC false
#define Z_MAX_ENDSTOP_LOGIC false
#define Z2_MAX_ENDSTOP_LOGIC false
#define Z_PROBE_ENDSTOP_LOGIC false
#define E_MIN_ENDSTOP_LOGIC false
#define X_HOME_DIR -1
#define Y_HOME_DIR -1
#define Z_HOME_DIR -1
#define E_HOME_DIR -1
#define X_ENABLE_ON 0
#define Y_ENABLE_ON 0
#define Z_ENABLE_ON 0
#define E_ENABLE_ON 0
#define INVERT_X_DIR true
#define INVERT_Y_DIR false
#define INVERT_Z_DIR false
#define INVERT_E0_DIR false
#define INVERT_E1_DIR false
#define INVERT_E2_DIR false
#define INVERT_E3_DIR false
#define DISABLE_X false
#define DISABLE_Y false
#define DISABLE_Z false
#define DISABLE_E false
#define X_MAX_POS 200
#define X_MIN_POS 0
#define Y_MAX_POS 200
#define Y_MIN_POS 0
#define Z_MAX_POS 200
#define Z_MIN_POS 0
#define LEFT_PROBE_BED_POSITION 20
#define RIGHT_PROBE_BED_POSITION 180
#define FRONT_PROBE_BED_POSITION 20
#define BACK_PROBE_BED_POSITION 180
#define DEFAULT_AXIS_STEPS_PER_UNIT {80,80,4000,625,625,625,625}
#define DEFAULT_MAX_FEEDRATE {300,300,2,100,100,100,100}
#define DEFAULT_MAX_ACCELERATION {3000,3000,50,3000,3000,3000,3000}
#define DEFAULT_RETRACT_ACCELERATION {10000,10000,10000,10000}
#define DEFAULT_ACCELERATION 2500
#define DEFAULT_TRAVEL_ACCELERATION 3000
#define DEFAULT_XYJERK 10
#define DEFAULT_ZJERK 0.4
#define DEFAULT_EJERK {5.0,5.0,5.0,5.0}
#define HOMING_FEEDRATE {100*60,100*60,2*60,0}
#define PIDTEMP
#define DEFAULT_Kp {41.51,41.51,41.51,41.51}
#define DEFAULT_Ki {7.28,7.28,7.28,7.28}
#define DEFAULT_Kd {59.17,59.17,59.17,59.17}
#define PIDTEMPBED
#define DEFAULT_bedKp 10
#define DEFAULT_bedKi 1
#define DEFAULT_bedKd 305
#define EXTRUDER_AUTO_FAN_TEMPERATURE 50
#define EXTRUDER_AUTO_FAN_SPEED 255
#define PREVENT_DANGEROUS_EXTRUDE
#define PREVENT_LENGTHY_EXTRUDE
#define SINGLENOZZLE
#define MKR4
#define BOWDEN_LENGTH 250
#define LCD_PURGE_LENGTH 10
#define LCD_RETRACT_LENGTH 5
#define LCD_PURGE_FEEDRATE 3
#define LCD_RETRACT_FEEDRATE 5
#define LCD_LOAD_FEEDRATE 20
#define LCD_UNLOAD_FEEDRATE 20
#define Z_PROBE_REPEATABILITY_TEST // If not commented out, Z-Probe Repeatability test will be included if Auto Bed Leveling is Enabled.
#define AUTO_BED_LEVELING_GRID
#define AUTO_BED_LEVELING_GRID_POINTS 2
#define ABL_PROBE_PT_1_X 15
#define ABL_PROBE_PT_1_Y 180
#define ABL_PROBE_PT_2_X 15
#define ABL_PROBE_PT_2_Y 15
#define ABL_PROBE_PT_3_X 180
#define ABL_PROBE_PT_3_Y 15
#define X_PROBE_OFFSET_FROM_EXTRUDER 0
#define Y_PROBE_OFFSET_FROM_EXTRUDER 0
#define Z_PROBE_OFFSET_FROM_EXTRUDER -1
#define Z_RAISE_BEFORE_HOMING 10
#define Z_RAISE_BEFORE_PROBING 10
#define Z_RAISE_BETWEEN_PROBINGS 10
#define NUM_SERVOS 0
#define INVERT_Y2_VS_Y_DIR false
#define FILAMENT_SENSOR
#define FILAMENT_SENSOR_EXTRUDER_NUM 0
#define DEFAULT_NOMINAL_FILAMENT_DIA 1.75
#define MEASURED_UPPER_LIMIT 2
#define MEASURED_LOWER_LIMIT 1.35
#define FILRUNOUT_PIN_INVERTING false;
#define FILAMENT_RUNOUT_SCRIPT "M600"
#define EEPROM_SETTINGS
#define EEPROM_CHITCHAT // Uncomment this to enable EEPROM Serial responses.
#define NEXTION
#define PROGRESS_BAR_BAR_TIME 3000
#define PROGRESS_BAR_MSG_TIME 1000
#define PROGRESS_MSG_EXPIRE 0
#define MICROSTEP_MODES {16,16,16,16}
#define MOTOR_CURRENT {1,1,1,1,1,1,1}
/* Below you will find the configuration string, that created with Configurator tool online marlinkimbra.it
========== Start configuration string ==========
{
"mechanism": 0,
"motherboards": "BOARD_RAMPS_13_EFB",
"printer": "custom",
"baudrates": 115200,
"testmode": "0",
"processor": 0,
"version": 0,
"extruders": 4,
"driverextruders": 1,
"singlenozzle": "1",
"mkr4": "1",
"npr2": "0",
"E0E1pin": -1,
"E0E2pin": -1,
"E0E3pin": -1,
"E1E3pin": -1,
"power": "0",
"defaultpower": "0",
"tempsensor0": "1",
"tempsensor1": "0",
"tempsensor2": "0",
"tempsensor3": "0",
"tempsensorbed": "4",
"heater0pin": "ORIG_HEATER_0_PIN",
"heater1pin": "ORIG_HEATER_1_PIN",
"heater2pin": "ORIG_HEATER_2_PIN",
"heater3pin": "ORIG_HEATER_3_PIN",
"heaterbedpin": "ORIG_HEATER_BED_PIN",
"temp0pin": "ORIG_TEMP_0_PIN",
"temp1pin": "ORIG_TEMP_1_PIN",
"temp2pin": "ORIG_TEMP_2_PIN",
"temp3pin": "ORIG_TEMP_3_PIN",
"tempbedpin": "ORIG_TEMP_BED_PIN",
"mintemp0": 5,
"mintemp1": 5,
"mintemp2": 5,
"mintemp3": 5,
"mintempbed": 5,
"maxtemp0": 275,
"maxtemp1": 275,
"maxtemp2": 275,
"maxtemp3": 275,
"maxtempbed": 150,
"pidtemp": "1",
"pidkp0": 41.51,
"pidki0": 7.28,
"pidkd0": 59.17,
"pidkp1": 41.51,
"pidki1": 7.28,
"pidkd1": 59.17,
"pidkp2": 41.51,
"pidki2": 7.28,
"pidkd2": 59.17,
"pidkp3": 41.51,
"pidki3": 7.28,
"pidkd3": 59.17,
"pidbedtemp": "1",
"pidbedkp": 10,
"pidbedki": 1,
"pidbedkd": 305,
"dangerousextrude": "1",
"lengthyextrude": "1",
"extrudemintemp": 170,
"autobed": "0",
"zprobingrepeat": "1",
"gridmode": "1",
"gridpoint": 2,
"Zsafehoming": "0",
"ZsafehomingX": 100,
"ZsafehomingY": 100,
"leftprobe": 20,
"rightprobe": 180,
"backprobe": 180,
"frontprobe": 20,
"Xprobe1": 15,
"Yprobe1": 180,
"Xprobe2": 15,
"Yprobe2": 15,
"Xprobe3": 180,
"Yprobe3": 15,
"Xprobeoffset": 0,
"Yprobeoffset": 0,
"Zprobeoffset": -1,
"Zraisebeforehoming": 10,
"Zraisebeforeprobe": 10,
"Zraisebetweenprobe": 10,
"Xmotor": {
"name": "X motor",
"step": "ORIG_X_STEP_PIN",
"dir": "ORIG_X_DIR_PIN",
"enable": "ORIG_X_ENABLE_PIN"
},
"Ymotor": {
"name": "Y motor",
"step": "ORIG_Y_STEP_PIN",
"dir": "ORIG_Y_DIR_PIN",
"enable": "ORIG_Y_ENABLE_PIN"
},
"Zmotor": {
"name": "Z motor",
"step": "ORIG_Z_STEP_PIN",
"dir": "ORIG_Z_DIR_PIN",
"enable": "ORIG_Z_ENABLE_PIN"
},
"Y2motor": {
"name": "Extruder 1",
"step": "ORIG_E1_STEP_PIN",
"dir": "ORIG_E1_DIR_PIN",
"enable": "ORIG_E1_ENABLE_PIN"
},
"Z2motor": {
"name": "Extruder 1",
"step": "ORIG_E1_STEP_PIN",
"dir": "ORIG_E1_DIR_PIN",
"enable": "ORIG_E1_ENABLE_PIN"
},
"E0motor": {
"name": "Extruder 0",
"step": "ORIG_E0_STEP_PIN",
"dir": "ORIG_E0_DIR_PIN",
"enable": "ORIG_E0_ENABLE_PIN"
},
"E1motor": {
"name": "Extruder 1",
"step": "ORIG_E1_STEP_PIN",
"dir": "ORIG_E1_DIR_PIN",
"enable": "ORIG_E1_ENABLE_PIN"
},
"E2motor": {
"name": "Extruder 2",
"step": "ORIG_E2_STEP_PIN",
"dir": "ORIG_E2_DIR_PIN",
"enable": "ORIG_E2_ENABLE_PIN"
},
"E3motor": {
"name": "Extruder 3",
"step": "ORIG_E3_STEP_PIN",
"dir": "ORIG_E3_DIR_PIN",
"enable": "ORIG_E3_ENABLE_PIN"
},
"Ydualstepper": "0",
"Y2vsYdir": "0",
"Zdualstepper": "0",
"Zdualendstop": "0",
"Xminpos": 0,
"Xmaxpos": 200,
"Yminpos": 0,
"Ymaxpos": 200,
"Zminpos": 0,
"Zmaxpos": 200,
"defaultacceleration": 2500,
"defaulttravelacceleration": 3000,
"maxXYjerk": 10,
"maxZjerk": 0.4,
"maxE0jerk": 5,
"maxE1jerk": 5,
"maxE2jerk": 5,
"maxE3jerk": 5,
"deltasegmentpersecond": 200,
"deltadiagonalrod": 220,
"deltasmoothrodoffset": 145,
"deltaeffectoroffset": 20,
"deltacarriageoffset": 20,
"deltaprinterradius": 70,
"deltaheight": 210,
"deltaautoprecision": 0.1,
"deltaautogrid": 20,
"deltaXprobeoffset": 0,
"deltaYprobeoffset": 0,
"deltaZprobeoffset": -10,
"deltaXdeploystart": 0,
"deltaYdeploystart": 0,
"deltaZdeploystart": 30,
"deltaXdeployend": 0,
"deltaYdeployend": 0,
"deltaZdeployend": 0,
"deltaXretractstart": 0,
"deltaYretractstart": 0,
"deltaZretractstart": 30,
"deltaXretractend": 0,
"deltaYretractend": 0,
"deltaZretractend": 0,
"Xmicrostep": 16,
"Ymicrostep": 16,
"Zmicrostep": 16,
"Emicrostep": 16,
"Xcurrent": 1000,
"Ycurrent": 1000,
"Zcurrent": 1000,
"E0current": 1000,
"E1current": 1000,
"E2current": 1000,
"E3current": 1000,
"Xstepspermm": 80,
"Ystepspermm": 80,
"Zstepspermm": 4000,
"E0stepspermm": 625,
"E1stepspermm": 625,
"E2stepspermm": 625,
"E3stepspermm": 625,
"Xmaxspeed": 300,
"Ymaxspeed": 300,
"Zmaxspeed": 2,
"E0maxspeed": 100,
"E1maxspeed": 100,
"E2maxspeed": 100,
"E3maxspeed": 100,
"E0retractionspeed": 100,
"E1retractionspeed": 100,
"E2retractionspeed": 100,
"E3retractionspeed": 100,
"Xhomingspeed": 100,
"Yhomingspeed": 100,
"Zhomingspeed": 2,
"Xmaxacceleration": 3000,
"Ymaxacceleration": 3000,
"Zmaxacceleration": 50,
"E0maxacceleration": 3000,
"E1maxacceleration": 3000,
"E2maxacceleration": 3000,
"E3maxacceleration": 3000,
"E0retractacceleration": 10000,
"E1retractacceleration": 10000,
"E2retractacceleration": 10000,
"E3retractacceleration": 10000,
"Xinvert": "1",
"Yinvert": 0,
"Zinvert": 0,
"E0invert": 0,
"E1invert": 0,
"E2invert": 0,
"E3invert": 0,
"Xinvertenable": 0,
"Yinvertenable": 0,
"Zinvertenable": 0,
"Einvertenable": 0,
"disableX": 0,
"disableY": 0,
"disableZ": 0,
"disableE": 0,
"Xhoming": 0,
"Yhoming": 0,
"Zhoming": 0,
"Ehoming": 0,
"Xminendstop": "0",
"Xmaxendstop": "0",
"Yminendstop": "0",
"Ymaxendstop": "0",
"Zminendstop": "0",
"Zmaxendstop": "0",
"Z2minendstop": "0",
"Z2maxendstop": "0",
"Zprobeendstop": "0",
"Eminendstop": "0",
"Xminpullup": "0",
"Xmaxpullup": "1",
"Yminpullup": "1",
"Ymaxpullup": "1",
"Zminpullup": "0",
"Zmaxpullup": "1",
"Z2minpullup": "1",
"Z2maxpullup": "1",
"Zprobepullup": "1",
"Eminpullup": "1",
"E0coolerpin": -1,
"E1coolerpin": -1,
"E2coolerpin": -1,
"E3coolerpin": -1,
"Ecoolerspeed": 255,
"Ecoolertemp": 50,
"fanpin": "ORIG_FAN_PIN",
"sdsupport": "0",
"eeprom": "1",
"eepromchitchat": "1",
"laserbeam": "0",
"laserpwrpin": 41,
"laserttlpin": 42,
"toshiba": "0",
"powerconsumption": "1",
"powerconsumptionpin": 11,
"filamentrunout": "0",
"filrunoutpin": 7,
"filamentrunoutsensor": "0",
"filamentrunoutscript": "M600",
"servos": "0",
"numservos": 0,
"Xservo": -1,
"Yservo": -1,
"Zservo": -1,
"angleextendservosX": 0,
"angleretractservosX": 0,
"angleextendservosY": 0,
"angleretractservosY": 0,
"angleextendservosZ": 0,
"angleretractservosZ": 0,
"displays": 12,
"invertrotaryswitch": 0,
"uilanguages": 7,
"uiprintername": "Prusa I3",
"easyload": 0,
"bowdenlenght": 250,
"lcdpurgelenght": 10,
"lcdretractlenght": 5,
"lcdpurgefeedrate": 3,
"lcdretractfeedrate": 5,
"lcdloadfeedrate": 20,
"lcdunloadfeedrate": 20,
"lcdprogressbar": 0,
"lcdprogressbarbartime": 3,
"lcdprogressbarmsgtime": 1,
"lcdprogressbarmsgexpire": 0,
"plahotendtemp": 190,
"plabedtemp": 60,
"plafanspeed": 255,
"abshotendtemp": 240,
"absbedtemp": 100,
"absfanspeed": 255,
"gumhotendtemp": 230,
"gumbedtemp": 60,
"gumfanspeed": 255,
"filamentsensor": "1",
"filamentsensorpin": 10,
"filamentsensorlcd": "0",
"filamentsensorextruder": 0,
"filamentsensordia": 1.75,
"filamentsensormaxdia": 2,
"filamentsensormindia": 1.35
}
========== End configuration string ==========
*/
...@@ -151,6 +151,7 @@ ...@@ -151,6 +151,7 @@
* or use S<seconds> to specify an inactivity timeout, after which the steppers will be disabled. S0 to disable the timeout. * or use S<seconds> to specify an inactivity timeout, after which the steppers will be disabled. S0 to disable the timeout.
* M85 - Set inactivity shutdown timer with parameter S<seconds>. To disable set zero (default) * M85 - Set inactivity shutdown timer with parameter S<seconds>. To disable set zero (default)
* M92 - Set axis_steps_per_unit - same syntax as G92 * M92 - Set axis_steps_per_unit - same syntax as G92
* M100 - Watch Free Memory (For Debugging Only)
* M104 - Set extruder target temp * M104 - Set extruder target temp
* M105 - Read current temp * M105 - Read current temp
* M106 - Fan on * M106 - Fan on
...@@ -158,7 +159,6 @@ ...@@ -158,7 +159,6 @@
* M109 - Sxxx Wait for extruder current temp to reach target temp. Waits only when heating * M109 - Sxxx Wait for extruder current temp to reach target temp. Waits only when heating
* Rxxx Wait for extruder current temp to reach target temp. Waits when heating and cooling * Rxxx Wait for extruder current temp to reach target temp. Waits when heating and cooling
* IF AUTOTEMP is enabled, S<mintemp> B<maxtemp> F<factor>. Exit autotemp by any M109 without F * IF AUTOTEMP is enabled, S<mintemp> B<maxtemp> F<factor>. Exit autotemp by any M109 without F
* M100 - Watch Free Memory (For Debugging Only)
* M110 - Set the current line number * M110 - Set the current line number
* M111 - Set debug flags with S<mask>. See flag bits defined in Marlin.h. * M111 - Set debug flags with S<mask>. See flag bits defined in Marlin.h.
* M112 - Emergency stop * M112 - Emergency stop
...@@ -496,6 +496,7 @@ unsigned long printer_usage_seconds; ...@@ -496,6 +496,7 @@ unsigned long printer_usage_seconds;
//=========================================================================== //===========================================================================
//================================ Functions ================================ //================================ Functions ================================
//=========================================================================== //===========================================================================
inline void refresh_cmd_timeout() { previous_cmd_ms = millis(); }
void process_next_command(); void process_next_command();
...@@ -531,6 +532,53 @@ bool setTargetedHotend(int code); ...@@ -531,6 +532,53 @@ bool setTargetedHotend(int code);
#endif // !SDSUPPORT #endif // !SDSUPPORT
#endif #endif
#if ENABLED(M100_FREE_MEMORY_WATCHER)
// top_of_stack() returns the location of a variable on its stack frame. The value returned is above
// the stack once the function returns to the caller.
unsigned char *top_of_stack() {
unsigned char x;
return &x + 1; // x is pulled on return;
}
//
// 3 support routines to print hex numbers. We can print a nibble, byte and word
//
void prt_hex_nibble( unsigned int n ) {
if ( n <= 9 )
ECHO_V(n);
else
ECHO_V( (char) ('A'+n-10) );
delay(2);
}
void prt_hex_byte(unsigned int b) {
prt_hex_nibble( ( b & 0xf0 ) >> 4 );
prt_hex_nibble( b & 0x0f );
}
void prt_hex_word(unsigned int w) {
prt_hex_byte( ( w & 0xff00 ) >> 8 );
prt_hex_byte( w & 0x0ff );
}
// how_many_E5s_are_here() is a utility function to easily find out how many 0xE5's are
// at the specified location. Having this logic as a function simplifies the search code.
//
int how_many_E5s_are_here( unsigned char *p) {
int n;
for(n = 0; n < 32000; n++) {
if ( *(p+n) != (unsigned char) 0xe5)
return n-1;
}
return -1;
}
#endif
/** /**
* Inject the next command from the command queue, when possible * Inject the next command from the command queue, when possible
* Return false only if no command was pending * Return false only if no command was pending
...@@ -4852,6 +4900,193 @@ inline void gcode_M92() { ...@@ -4852,6 +4900,193 @@ inline void gcode_M92() {
plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]); plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]);
} }
// M100 Free Memory Watcher
//
// This code watches the free memory block between the bottom of the heap and the top of the stack.
// This memory block is initialized and watched via the M100 command.
//
// M100 I Initializes the free memory block and prints vitals statistics about the area
// M100 F Identifies how much of the free memory block remains free and unused. It also
// detects and reports any corruption within the free memory block that may have
// happened due to errant firmware.
// M100 D Does a hex display of the free memory block along with a flag for any errant
// data that does not match the expected value.
// M100 C x Corrupts x locations within the free memory block. This is useful to check the
// correctness of the M100 F and M100 D commands.
//
// Initial version by Roxy-3DPrintBoard
//
//
#if ENABLED(M100_FREE_MEMORY_WATCHER)
inline void gcode_M100() {
static int m100_not_initialized = 1;
unsigned char *sp, *ptr;
int i, j, n;
//
// M100 D dumps the free memory block from __brkval to the stack pointer.
// malloc() eats memory from the start of the block and the stack grows
// up from the bottom of the block. Solid 0xE5's indicate nothing has
// used that memory yet. There should not be anything but 0xE5's within
// the block of 0xE5's. If there is, that would indicate memory corruption
// probably caused by bad pointers. Any unexpected values will be flagged in
// the right hand column to help spotting them.
//
#if ENABLED(M100_FREE_MEMORY_DUMPER) // Comment out to remove Dump sub-command
if ( code_seen('D') ) {
ptr = (unsigned char *) __brkval;
//
// We want to start and end the dump on a nice 16 byte boundry even though
// the values we are using are not 16 byte aligned.
//
ECHO_M("\n__brkval : ");
prt_hex_word( (unsigned int) ptr );
ptr = (unsigned char *) ((unsigned long) ptr & 0xfff0);
sp = top_of_stack();
ECHO_M("\nStack Pointer : ");
prt_hex_word( (unsigned int) sp );
ECHO_M("\n");
sp = (unsigned char *) ((unsigned long) sp | 0x000f);
n = sp - ptr;
//
// This is the main loop of the Dump command.
//
while ( ptr < sp ) {
prt_hex_word( (unsigned int) ptr); // Print the address
ECHO_M(":");
for(i = 0; i < 16; i++) { // and 16 data bytes
prt_hex_byte( *(ptr+i));
ECHO_M(" ");
delay(2);
}
ECHO_M("|"); // now show where non 0xE5's are
for(i = 0; i < 16; i++) {
delay(2);
if ( *(ptr+i)==0xe5)
ECHO_M(" ");
else
ECHO_M("?");
}
ECHO_M("\n");
ptr += 16;
delay(2);
}
ECHO_M("Done.\n");
return;
}
#endif
//
// M100 F requests the code to return the number of free bytes in the memory pool along with
// other vital statistics that define the memory pool.
//
if ( code_seen('F') ) {
int max_addr = (int) __brkval;
int max_cnt = 0;
int block_cnt = 0;
ptr = (unsigned char *) __brkval;
sp = top_of_stack();
n = sp - ptr;
// Scan through the range looking for the biggest block of 0xE5's we can find
for(i = 0; i < n; i++) {
if ( *(ptr+i) == (unsigned char) 0xe5) {
j = how_many_E5s_are_here( (unsigned char *) ptr+i );
if ( j > 8) {
ECHO_MV("Found ", j );
ECHO_M(" bytes free at 0x");
prt_hex_word( (int) ptr+i );
ECHO_M("\n");
i += j;
block_cnt++;
}
if ( j>max_cnt) { // We don't do anything with this information yet
max_cnt = j; // but we do know where the biggest free memory block is.
max_addr = (int) ptr+i;
}
}
}
if (block_cnt>1)
ECHO_EM("\nMemory Corruption detected in free memory area.\n");
ECHO_M("\nDone.\n");
return;
}
//
// M100 C x Corrupts x locations in the free memory pool and reports the locations of the corruption.
// This is useful to check the correctness of the M100 D and the M100 F commands.
//
#if ENABLED(M100_FREE_MEMORY_CORRUPTOR)
if ( code_seen('C') ) {
int x; // x gets the # of locations to corrupt within the memory pool
x = code_value();
ECHO_EM("Corrupting free memory block.\n");
ptr = (unsigned char *) __brkval;
ECHO_MV("\n__brkval : ",(long) ptr );
ptr += 8;
sp = top_of_stack();
ECHO_MV("\nStack Pointer : ",(long) sp );
ECHO_EM("\n");
n = sp - ptr - 64; // -64 just to keep us from finding interrupt activity that
// has altered the stack.
j = n / (x+1);
for(i = 1; i <= x; i++) {
*(ptr+(i*j)) = i;
ECHO_M("\nCorrupting address: 0x");
prt_hex_word( (unsigned int) (ptr+(i*j)) );
}
ECHO_EM("\n");
return;
}
#endif
//
// M100 I Initializes the free memory pool so it can be watched and prints vital
// statistics that define the free memory pool.
//
if (m100_not_initialized || code_seen('I') ) { // If no sub-command is specified, the first time
ECHO_EM("Initializing free memory block.\n"); // this happens, it will Initialize.
ptr = (unsigned char *) __brkval; // Repeated M100 with no sub-command will not destroy the
ECHO_MV("\n__brkval : ",(long) ptr ); // state of the initialized free memory pool.
ptr += 8;
sp = top_of_stack();
ECHO_MV("\nStack Pointer : ",(long) sp );
ECHO_EM("\n");
n = sp - ptr - 64; // -64 just to keep us from finding interrupt activity that
// has altered the stack.
ECHO_V( n );
ECHO_EM(" bytes of memory initialized.\n");
for(i = 0; i < n; i++)
*(ptr+i) = (unsigned char) 0xe5;
for(i = 0; i < n; i++) {
if ( *(ptr+i) != (unsigned char) 0xe5 ) {
ECHO_MV("? address : ", (unsigned long) ptr+i );
ECHO_MV("=", *(ptr+i) );
ECHO_EM("\n");
}
}
m100_not_initialized = 0;
ECHO_EM("Done.\n");
return;
}
return;
}
#endif
/** /**
* M104: Set hot end temperature * M104: Set hot end temperature
*/ */
...@@ -7604,26 +7839,6 @@ void plan_arc( ...@@ -7604,26 +7839,6 @@ void plan_arc(
#endif #endif
void enable_all_steppers() {
enable_x();
enable_y();
enable_z();
enable_e0();
enable_e1();
enable_e2();
enable_e3();
}
void disable_all_steppers() {
disable_x();
disable_y();
disable_z();
disable_e0();
disable_e1();
disable_e2();
disable_e3();
}
/** /**
* Standard idle routine keeps the machine alive * Standard idle routine keeps the machine alive
*/ */
......
...@@ -4,97 +4,12 @@ ...@@ -4,97 +4,12 @@
#ifndef MARLIN_H #ifndef MARLIN_H
#define MARLIN_H #define MARLIN_H
typedef unsigned long millis_t;
void get_command(); void get_command();
void idle(bool ignore_stepper_queue = false); void idle(bool ignore_stepper_queue = false);
void manage_inactivity(bool ignore_stepper_queue=false); void manage_inactivity(bool ignore_stepper_queue=false);
#if ENABLED(DUAL_X_CARRIAGE) && HAS(X_ENABLE) && HAS(X2_ENABLE)
#define enable_x() do { X_ENABLE_WRITE( X_ENABLE_ON); X2_ENABLE_WRITE( X_ENABLE_ON); } while (0)
#define disable_x() do { X_ENABLE_WRITE(!X_ENABLE_ON); X2_ENABLE_WRITE(!X_ENABLE_ON); axis_known_position[X_AXIS] = false; } while (0)
#elif HAS(X_ENABLE)
#define enable_x() X_ENABLE_WRITE( X_ENABLE_ON)
#define disable_x() { X_ENABLE_WRITE(!X_ENABLE_ON); axis_known_position[X_AXIS] = false; }
#else
#define enable_x() ;
#define disable_x() ;
#endif
#if HAS(Y_ENABLE)
#if ENABLED(Y_DUAL_STEPPER_DRIVERS)
#define enable_y() { Y_ENABLE_WRITE( Y_ENABLE_ON); Y2_ENABLE_WRITE(Y_ENABLE_ON); }
#define disable_y() { Y_ENABLE_WRITE(!Y_ENABLE_ON); Y2_ENABLE_WRITE(!Y_ENABLE_ON); axis_known_position[Y_AXIS] = false; }
#else
#define enable_y() Y_ENABLE_WRITE( Y_ENABLE_ON)
#define disable_y() { Y_ENABLE_WRITE(!Y_ENABLE_ON); axis_known_position[Y_AXIS] = false; }
#endif
#else
#define enable_y() ;
#define disable_y() ;
#endif
#if HAS(Z_ENABLE)
#if ENABLED(Z_DUAL_STEPPER_DRIVERS)
#define enable_z() { Z_ENABLE_WRITE( Z_ENABLE_ON); Z2_ENABLE_WRITE(Z_ENABLE_ON); }
#define disable_z() { Z_ENABLE_WRITE(!Z_ENABLE_ON); Z2_ENABLE_WRITE(!Z_ENABLE_ON); axis_known_position[Z_AXIS] = false; }
#else
#define enable_z() Z_ENABLE_WRITE( Z_ENABLE_ON)
#define disable_z() { Z_ENABLE_WRITE(!Z_ENABLE_ON); axis_known_position[Z_AXIS] = false; }
#endif
#else
#define enable_z() ;
#define disable_z() ;
#endif
#if HAS(E0_ENABLE)
#define enable_e0() E0_ENABLE_WRITE( E_ENABLE_ON)
#define disable_e0() E0_ENABLE_WRITE(!E_ENABLE_ON)
#else
#define enable_e0() /* nothing */
#define disable_e0() /* nothing */
#endif
#if (DRIVER_EXTRUDERS > 1) && HAS(E1_ENABLE)
#define enable_e1() E1_ENABLE_WRITE( E_ENABLE_ON)
#define disable_e1() E1_ENABLE_WRITE(!E_ENABLE_ON)
#else
#define enable_e1() /* nothing */
#define disable_e1() /* nothing */
#endif
#if (DRIVER_EXTRUDERS > 2) && HAS(E2_ENABLE)
#define enable_e2() E2_ENABLE_WRITE( E_ENABLE_ON)
#define disable_e2() E2_ENABLE_WRITE(!E_ENABLE_ON)
#else
#define enable_e2() /* nothing */
#define disable_e2() /* nothing */
#endif
#if (DRIVER_EXTRUDERS > 3) && HAS(E3_ENABLE)
#define enable_e3() E3_ENABLE_WRITE( E_ENABLE_ON)
#define disable_e3() E3_ENABLE_WRITE(!E_ENABLE_ON)
#else
#define enable_e3() /* nothing */
#define disable_e3() /* nothing */
#endif
#define disable_e() {disable_e0(); disable_e1(); disable_e2(); disable_e3();}
/**
* Axis indices as enumerated constants
*
* A_AXIS and B_AXIS are used by COREXY printers
* X_HEAD and Y_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};
void enable_all_steppers();
void disable_all_steppers();
void FlushSerialRequestResend(); void FlushSerialRequestResend();
void ok_to_send(); void ok_to_send();
...@@ -149,6 +64,9 @@ enum DebugFlags { ...@@ -149,6 +64,9 @@ enum DebugFlags {
DEBUG_DRYRUN = BIT(3), DEBUG_DRYRUN = BIT(3),
DEBUG_COMMUNICATION = BIT(4) DEBUG_COMMUNICATION = BIT(4)
}; };
void clamp_to_software_endstops(float target[3]);
extern uint8_t debugLevel; extern uint8_t debugLevel;
extern bool Running; extern bool Running;
...@@ -162,7 +80,7 @@ void prepare_arc_move(char isclockwise); ...@@ -162,7 +80,7 @@ void prepare_arc_move(char isclockwise);
void clamp_to_software_endstops(float target[3]); void clamp_to_software_endstops(float target[3]);
extern millis_t previous_cmd_ms; extern millis_t previous_cmd_ms;
inline void refresh_cmd_timeout() { previous_cmd_ms = millis(); } inline void refresh_cmd_timeout();
#if ENABLED(FAST_PWM_FAN) #if ENABLED(FAST_PWM_FAN)
void setPwmFrequency(uint8_t pin, int val); void setPwmFrequency(uint8_t pin, int val);
...@@ -292,4 +210,26 @@ extern uint8_t active_driver; ...@@ -292,4 +210,26 @@ extern uint8_t active_driver;
extern void calculate_volumetric_multipliers(); extern void calculate_volumetric_multipliers();
#if ENABLED(M100_FREE_MEMORY_WATCHER)
extern void *__brkval;
extern size_t __heap_start, __heap_end, __flp;
//
// Declare all the functions we need from Marlin_Main.cpp to do the work!
//
float code_value();
long code_value_long();
bool code_seen(char );
//
// Utility functions used by M100 to get its work done.
//
unsigned char *top_of_stack();
void prt_hex_nibble( unsigned int );
void prt_hex_byte(unsigned int );
void prt_hex_word(unsigned int );
int how_many_E5s_are_here( unsigned char *);
#endif
#endif //MARLIN_H #endif //MARLIN_H
...@@ -327,6 +327,9 @@ ...@@ -327,6 +327,9 @@
#define RIGHT_PROBE_BED_POSITION DELTA_PROBABLE_RADIUS #define RIGHT_PROBE_BED_POSITION DELTA_PROBABLE_RADIUS
#define FRONT_PROBE_BED_POSITION -DELTA_PROBABLE_RADIUS #define FRONT_PROBE_BED_POSITION -DELTA_PROBABLE_RADIUS
#define BACK_PROBE_BED_POSITION DELTA_PROBABLE_RADIUS #define BACK_PROBE_BED_POSITION DELTA_PROBABLE_RADIUS
// Radius for probe
#define DELTA_PROBABLE_RADIUS (PRINTER_RADIUS)
#endif #endif
/** /**
......
...@@ -1531,6 +1531,8 @@ ...@@ -1531,6 +1531,8 @@
#define N_ARC_CORRECTION 25 #define N_ARC_CORRECTION 25
//#define M100_FREE_MEMORY_WATCHER // Uncomment to add the M100 Free Memory Watcher for debug purpose //#define M100_FREE_MEMORY_WATCHER // Uncomment to add the M100 Free Memory Watcher for debug purpose
#define M100_FREE_MEMORY_DUMPER // Comment out to remove Dump sub-command
#define M100_FREE_MEMORY_CORRUPTOR // Comment out to remove Corrupt sub-command
/****************************************************************************************/ /****************************************************************************************/
......
...@@ -4,6 +4,8 @@ ...@@ -4,6 +4,8 @@
#include "vector_3.h" #include "vector_3.h"
#endif #endif
#include "planner.h" #include "planner.h"
#include "stepper_indirection.h"
#include "stepper.h"
#include "temperature.h" #include "temperature.h"
#include "ultralcd.h" #include "ultralcd.h"
#include "configuration_store.h" #include "configuration_store.h"
......
#ifndef CONFIGURATIONS_H
#define CONFIGURATIONS_H
#include "Configuration_Version.h"
#include "Configuration_Basic.h"
#if MECH(CARTESIAN)
#include "Configuration_Cartesian.h"
#elif MECH(COREXY)
#include "Configuration_Core.h"
#elif MECH(COREXZ)
#include "Configuration_Core.h"
#elif MECH(DELTA)
#include "Configuration_Delta.h"
#elif MECH(SCARA)
#include "Configuration_Scara.h"
#endif
#include "Configuration_Feature.h"
#include "Configuration_Overall.h"
#endif
\ No newline at end of file
#ifndef ELEMENTS_H #ifndef ELEMENTS_H
#define ELEMENTS_H #define ELEMENTS_H
#warning called
#include "Arduino.h" #include "Arduino.h"
#include "pins_arduino.h" #include "pins_arduino.h"
...@@ -27,10 +27,29 @@ ...@@ -27,10 +27,29 @@
#include "macros.h" #include "macros.h"
#include "boards.h" #include "boards.h"
#include "mechanics.h" #include "mechanics.h"
#include "configurations.h"
#include "Configuration_Version.h"
#include "Configuration_Basic.h"
#include "Configuration_Overall.h"
#if MECH(CARTESIAN)
#include "Configuration_Cartesian.h"
#elif MECH(COREXY)
#include "Configuration_Core.h"
#elif MECH(COREXZ)
#include "Configuration_Core.h"
#elif MECH(DELTA)
#include "Configuration_Delta.h"
#elif MECH(SCARA)
#include "Configuration_Scara.h"
#endif
#include "Configuration_Feature.h"
#include "Configuration_Overall.h"
#include "language.h" #include "language.h"
#include "dependencies.h"
#include "conditionals.h" #include "conditionals.h"
#include "dependencies.h"
#include "conflicts.h" #include "conflicts.h"
#include "comunication.h" #include "comunication.h"
......
/*
Test.h
Tools for firmware test
By MagoKimbra
*/
#include "elements.h"
#if ENABLED(FIRMWARE_TEST)
#include "Marlin_main.h"
#if ENABLED(AUTO_BED_LEVELING_FEATURE)
#include "vector_3.h"
#endif
#include "planner.h"
#include "stepper_indirection.h"
#include "stepper.h"
#include "temperature.h"
#include "firmware_test.h"
static char serial_answer;
void FirmwareTest()
{
ECHO_EM("---------- FIRMWARE TEST --------------");
ECHO_EM("--------- by MarlinKimbra -------------");
ECHO_EV(MSG_FWTEST_01);
ECHO_EV(MSG_FWTEST_02);
ECHO_EV(MSG_FWTEST_YES_NO);
serial_answer = ' ';
while(serial_answer!='y' && serial_answer!='Y' && serial_answer!='n' && serial_answer!='N') {
serial_answer = MYSERIAL.read();
}
if (serial_answer=='y' || serial_answer=='Y') {
ECHO_EV(MSG_FWTEST_03);
ECHO_EM(" ");
ECHO_EM("***** ENDSTOP X *****");
#if EXIST(X_MIN_PIN) && X_MIN_PIN > -1 && X_HOME_DIR == -1
if (!READ(X_MIN_PIN)^X_MIN_ENDSTOP_INVERTING) {
ECHO_M("MIN ENDSTOP X: ");
ECHO_EV(MSG_ENDSTOP_OPEN);
}
else
{
ECHO_M("X ENDSTOP ");
ECHO_EM(MSG_FWTEST_ERROR);
ECHO_M(MSG_FWTEST_INVERT);
ECHO_M("#define X_MIN_ENDSTOP_LOGIC ");
ECHO_M(MSG_FWTEST_INTO);
#if MECH(CARTESIAN)
ECHO_EM("Configuration_Cartesian.h");
#elif MECH(COREXY)
ECHO_EM("Configuration_Core.h");
#elif MECH(COREXZ)
ECHO_EM("Configuration_Core.h");
#elif MECH(DELTA)
ECHO_EM("Configuration_Delta.h");
#elif MECH(SCARA)
ECHO_EM("Configuration_Scara.h");
#endif
return;
}
ECHO_V(MSG_FWTEST_PRESS);
ECHO_EM("X");
ECHO_EV(MSG_FWTEST_YES);
serial_answer = ' ';
while(serial_answer!='y' && serial_answer!='Y' && !(READ(X_MIN_PIN)^X_MIN_ENDSTOP_INVERTING)){
serial_answer = MYSERIAL.read();
}
if (READ(X_MIN_PIN)^X_MIN_ENDSTOP_INVERTING) {
ECHO_M("MIN ENDSTOP X: ");
ECHO_EV(MSG_ENDSTOP_HIT);
}
else
{
ECHO_M("X ");
ECHO_EV(MSG_FWTEST_ENDSTOP_ERR);
return;
}
#elif EXIST(X_MAX_PIN) && X_MAX_PIN > -1 && X_HOME_DIR == 1
if (!READ(X_MAX_PIN)^X_MAX_ENDSTOP_INVERTING) {
ECHO_M("MAX ENDSTOP X: ");
ECHO_EV(MSG_ENDSTOP_OPEN);
}
else
{
ECHO_M("X ENDSTOP ");
ECHO_EM(MSG_FWTEST_ERROR);
ECHO_M(MSG_FWTEST_INVERT);
ECHO_M("#define X_MAX_ENDSTOP_LOGIC ");
ECHO_M(MSG_FWTEST_INTO);
#if MECH(CARTESIAN)
ECHO_EM("Configuration_Cartesian.h");
#elif MECH(COREXY)
ECHO_EM("Configuration_Core.h");
#elif MECH(COREXZ)
ECHO_EM("Configuration_Core.h");
#elif MECH(DELTA)
ECHO_EM("Configuration_Delta.h");
#elif MECH(SCARA)
ECHO_EM("Configuration_Scara.h");
#endif
return;
}
ECHO_V(MSG_FWTEST_PRESS);
ECHO_EM("X");
ECHO_EV(MSG_FWTEST_YES);
serial_answer = ' ';
while(serial_answer!='y' && serial_answer!='Y' && !(READ(X_MAX_PIN)^X_MAX_ENDSTOP_INVERTING)) {
serial_answer = MYSERIAL.read();
}
if (READ(X_MAX_PIN)^X_MAX_ENDSTOP_INVERTING) {
ECHO_M("MAX ENDSTOP X: ");
ECHO_EV(MSG_ENDSTOP_HIT);
}
else
{
ECHO_M("X ");
ECHO_EV(MSG_FWTEST_ENDSTOP_ERR);
return;
}
#elif X_HOME_DIR == -1
ECHO_M(MSG_FWTEST_ERROR);
ECHO_M("!!! X_MIN_PIN ");
ECHO_EM(MSG_FWTEST_NDEF);
return;
#elif X_HOME_DIR == 1
ECHO_M(MSG_FWTEST_ERROR);
ECHO_M("!!! X_MAX_PIN ");
ECHO_EM(MSG_FWTEST_NDEF);
return;
#endif
ECHO_EM(" ");
ECHO_EM("***** ENDSTOP Y *****");
#if EXIST(Y_MIN_PIN) && Y_MIN_PIN > -1 && Y_HOME_DIR == -1
if (!READ(Y_MIN_PIN)^Y_MIN_ENDSTOP_INVERTING){
ECHO_M("MIN ENDSTOP Y: ");
ECHO_EV(MSG_ENDSTOP_OPEN);
}
else
{
ECHO_M("Y ENDSTOP ");
ECHO_EM(MSG_FWTEST_ERROR);
ECHO_M(MSG_FWTEST_INVERT);
ECHO_M("#define Y_MIN_ENDSTOP_LOGIC ");
ECHO_M(MSG_FWTEST_INTO);
#if MECH(CARTESIAN)
ECHO_EM("Configuration_Cartesian.h");
#elif MECH(COREXY)
ECHO_EM("Configuration_Core.h");
#elif MECH(COREXZ)
ECHO_EM("Configuration_Core.h");
#elif MECH(DELTA)
ECHO_EM("Configuration_Delta.h");
#elif MECH(SCARA)
ECHO_EM("Configuration_Scara.h");
#endif
return;
}
ECHO_V(MSG_FWTEST_PRESS);
ECHO_EM("Y");
ECHO_EV(MSG_FWTEST_YES);
serial_answer = ' ';
while(serial_answer!='y' && serial_answer!='Y' && !(READ(Y_MIN_PIN)^Y_MIN_ENDSTOP_INVERTING)){
serial_answer = MYSERIAL.read();
}
if (READ(Y_MIN_PIN)^Y_MIN_ENDSTOP_INVERTING){
ECHO_M("MIN ENDSTOP Y: ");
ECHO_EV(MSG_ENDSTOP_HIT);
}
else
{
ECHO_M("Y ");
ECHO_EV(MSG_FWTEST_ENDSTOP_ERR);
return;
}
#elif EXIST(Y_MAX_PIN) && Y_MAX_PIN > -1 && Y_HOME_DIR == 1
if (!READ(Y_MAX_PIN)^Y_MAX_ENDSTOP_INVERTING){
ECHO_M("MAX ENDSTOP Y: ");
ECHO_EV(MSG_ENDSTOP_OPEN);
}
else
{
ECHO_M("Y ENDSTOP ");
ECHO_EM(MSG_FWTEST_ERROR);
ECHO_M(MSG_FWTEST_INVERT);
ECHO_M("#define Y_MAX_ENDSTOP_LOGIC ");
ECHO_M(MSG_FWTEST_INTO);
#if MECH(CARTESIAN)
ECHO_EM("Configuration_Cartesian.h");
#elif MECH(COREXY)
ECHO_EM("Configuration_Core.h");
#elif MECH(COREXZ)
ECHO_EM("Configuration_Core.h");
#elif MECH(DELTA)
ECHO_EM("Configuration_Delta.h");
#elif MECH(SCARA)
ECHO_EM("Configuration_Scara.h");
#endif
return;
}
ECHO_V(MSG_FWTEST_PRESS);
ECHO_EM("Y");
ECHO_EV(MSG_FWTEST_YES);
serial_answer = ' ';
while(serial_answer!='y' && serial_answer!='Y' && !(READ(Y_MAX_PIN)^Y_MAX_ENDSTOP_INVERTING)){
serial_answer = MYSERIAL.read();
}
if (READ(Y_MAX_PIN)^Y_MAX_ENDSTOP_INVERTING){
ECHO_M("MAX ENDSTOP Y: ");
ECHO_EV(MSG_ENDSTOP_HIT);
}
else
{
ECHO_M("Y ");
ECHO_EV(MSG_FWTEST_ENDSTOP_ERR);
return;
}
#elif Y_HOME_DIR == -1
ECHO_M(MSG_FWTEST_ERROR);
ECHO_M("!!! Y_MIN_PIN ");
ECHO_EM(MSG_FWTEST_NDEF);
return;
#elif Y_HOME_DIR == 1
ECHO_M(MSG_FWTEST_ERROR);
ECHO_M("!!! Y_MAX_PIN ");
ECHO_EM(MSG_FWTEST_NDEF);
return;
#endif
ECHO_EM(" ");
ECHO_EM("***** ENDSTOP Z *****");
#if EXIST(Z_MIN_PIN) && Z_MIN_PIN > -1 && Z_HOME_DIR == -1
if (!READ(Z_MIN_PIN)^Z_MIN_ENDSTOP_INVERTING){
ECHO_M("MIN ENDSTOP Z: ");
ECHO_EV(MSG_ENDSTOP_OPEN);
}
else
{
ECHO_M("Z ENDSTOP ");
ECHO_EM(MSG_FWTEST_ERROR);
ECHO_M(MSG_FWTEST_INVERT);
ECHO_M("#define Z_MIN_ENDSTOP_LOGIC ");
ECHO_M(MSG_FWTEST_INTO);
#if MECH(CARTESIAN)
ECHO_EM("Configuration_Cartesian.h");
#elif MECH(COREXY)
ECHO_EM("Configuration_Core.h");
#elif MECH(COREXZ)
ECHO_EM("Configuration_Core.h");
#elif MECH(DELTA)
ECHO_EM("Configuration_Delta.h");
#elif MECH(SCARA)
ECHO_EM("Configuration_Scara.h");
#endif
return;
}
ECHO_V(MSG_FWTEST_PRESS);
ECHO_EM("Z");
ECHO_EV(MSG_FWTEST_YES);
serial_answer = ' ';
while(serial_answer!='y' && serial_answer!='Y' && !(READ(Z_MIN_PIN)^Z_MIN_ENDSTOP_INVERTING)){
serial_answer = MYSERIAL.read();
}
if (READ(Z_MIN_PIN)^Z_MIN_ENDSTOP_INVERTING){
ECHO_M("MIN ENDSTOP Z: ");
ECHO_EV(MSG_ENDSTOP_HIT);
}
else
{
ECHO_M("Z ");
ECHO_EV(MSG_FWTEST_ENDSTOP_ERR);
return;
}
#elif EXIST(Z_MAX_PIN) && Z_MAX_PIN > -1 && Z_HOME_DIR == 1
if (!READ(Z_MAX_PIN)^Z_MAX_ENDSTOP_INVERTING){
ECHO_M("MAX ENDSTOP Z: ");
ECHO_EV(MSG_ENDSTOP_OPEN);
}
else
{
ECHO_M("Z ENDSTOP ");
ECHO_EM(MSG_FWTEST_ERROR);
ECHO_M(MSG_FWTEST_INVERT);
ECHO_M("#define Z_MAX_ENDSTOP_LOGIC ");
ECHO_M(MSG_FWTEST_INTO);
#if MECH(CARTESIAN)
ECHO_EM("Configuration_Cartesian.h");
#elif MECH(COREXY)
ECHO_EM("Configuration_Core.h");
#elif MECH(COREXZ)
ECHO_EM("Configuration_Core.h");
#elif MECH(DELTA)
ECHO_EM("Configuration_Delta.h");
#elif MECH(SCARA)
ECHO_EM("Configuration_Scara.h");
#endif
return;
}
ECHO_V(MSG_FWTEST_PRESS);
ECHO_EM("Z");
ECHO_EV(MSG_FWTEST_YES);
serial_answer = ' ';
while(serial_answer!='y' && serial_answer!='Y' && !(READ(Z_MAX_PIN)^Z_MAX_ENDSTOP_INVERTING)){
serial_answer = MYSERIAL.read();
}
if (READ(Z_MAX_PIN)^Z_MAX_ENDSTOP_INVERTING){
ECHO_M("MAX ENDSTOP Z: ");
ECHO_EV(MSG_ENDSTOP_HIT);
}
else
{
ECHO_M("Z ");
ECHO_EV(MSG_FWTEST_ENDSTOP_ERR);
return;
}
#elif Z_HOME_DIR == -1
ECHO_M(MSG_FWTEST_ERROR);
ECHO_M("!!! Z_MIN_PIN ");
ECHO_EM(MSG_FWTEST_NDEF);
return;
#elif Z_HOME_DIR == 1
ECHO_M(MSG_FWTEST_ERROR);
ECHO_M("!!! Z_MAX_PIN ");
ECHO_EM(MSG_FWTEST_NDEF);
return;
#endif
ECHO_EM("ENDSTOP ");
ECHO_M(MSG_FWTEST_OK);
ECHO_EM(" ");
}
#if HAS(POWER_SWITCH)
SET_OUTPUT(PS_ON_PIN);
WRITE(PS_ON_PIN, PS_ON_AWAKE);
#endif
// Reset position to 0
st_synchronize();
for(int8_t i=0; i < NUM_AXIS; i++) current_position[i] = 0;
plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]);
ECHO_EM("***** TEST MOTOR *****");
ECHO_EV(MSG_FWTEST_ATTENTION);
ECHO_EV(MSG_FWTEST_YES);
serial_answer = ' ';
while(serial_answer!='y' && serial_answer!='Y'){
serial_answer = MYSERIAL.read();
}
ECHO_EV(MSG_FWTEST_04);
ECHO_EM(" ");
ECHO_EM("***** MOTOR X *****");
destination[X_AXIS] = 10;
prepare_move();
st_synchronize();
ECHO_EV(MSG_FWTEST_XAXIS);
ECHO_EV(MSG_FWTEST_YES_NO);
serial_answer = ' ';
while(serial_answer!='y' && serial_answer!='Y' && serial_answer!='n' && serial_answer!='N'){
serial_answer = MYSERIAL.read();
}
if(serial_answer=='y' || serial_answer=='Y'){
ECHO_EM("MOTOR X ");
ECHO_M(MSG_FWTEST_OK);
}
else
{
ECHO_M(MSG_FWTEST_INVERT);
ECHO_M("#define INVERT_X_DIR ");
ECHO_M(MSG_FWTEST_INTO);
#if MECH(CARTESIAN)
ECHO_EM("Configuration_Cartesian.h");
#elif MECH(COREXY)
ECHO_EM("Configuration_Core.h");
#elif MECH(COREXZ)
ECHO_EM("Configuration_Core.h");
#elif MECH(DELTA)
ECHO_EM("Configuration_Delta.h");
#elif MECH(SCARA)
ECHO_EM("Configuration_Scara.h");
#endif
return;
}
ECHO_EM(" ");
ECHO_EM("***** MOTOR Y *****");
destination[Y_AXIS] = 10;
prepare_move();
st_synchronize();
ECHO_EV(MSG_FWTEST_YAXIS);
ECHO_EV(MSG_FWTEST_YES_NO);
serial_answer = ' ';
while(serial_answer!='y' && serial_answer!='Y' && serial_answer!='n' && serial_answer!='N'){
serial_answer = MYSERIAL.read();
}
if(serial_answer=='y' || serial_answer=='Y'){
ECHO_EM("MOTOR Y ");
ECHO_M(MSG_FWTEST_OK);
}
else
{
ECHO_M(MSG_FWTEST_INVERT);
ECHO_M("#define INVERT_Y_DIR ");
ECHO_M(MSG_FWTEST_INTO);
#if MECH(CARTESIAN)
ECHO_EM("Configuration_Cartesian.h");
#elif MECH(COREXY)
ECHO_EM("Configuration_Core.h");
#elif MECH(COREXZ)
ECHO_EM("Configuration_Core.h");
#elif MECH(DELTA)
ECHO_EM("Configuration_Delta.h");
#elif MECH(SCARA)
ECHO_EM("Configuration_Scara.h");
#endif
return;
}
ECHO_EM(" ");
ECHO_EM("***** MOTOR Z *****");
destination[Z_AXIS] = 10;
prepare_move();
st_synchronize();
ECHO_EV(MSG_FWTEST_ZAXIS);
ECHO_EV(MSG_FWTEST_YES_NO);
serial_answer = ' ';
while(serial_answer!='y' && serial_answer!='Y' && serial_answer!='n' && serial_answer!='N'){
serial_answer = MYSERIAL.read();
}
if(serial_answer=='y' || serial_answer=='Y'){
ECHO_EM("MOTOR Z ");
ECHO_M(MSG_FWTEST_OK);
}
else
{
ECHO_M(MSG_FWTEST_INVERT);
ECHO_M("#define INVERT_Z_DIR ");
ECHO_M(MSG_FWTEST_INTO);
#if MECH(CARTESIAN)
ECHO_EM("Configuration_Cartesian.h");
#elif MECH(COREXY)
ECHO_EM("Configuration_Core.h");
#elif MECH(COREXZ)
ECHO_EM("Configuration_Core.h");
#elif MECH(DELTA)
ECHO_EM("Configuration_Delta.h");
#elif MECH(SCARA)
ECHO_EM("Configuration_Scara.h");
#endif
return;
}
ECHO_EM("MOTOR ");
ECHO_M(MSG_FWTEST_OK);
ECHO_EM(" ");
ECHO_V(MSG_FWTEST_END);
}
#endif
\ No newline at end of file
/* #ifndef FIRMWARE_TEST_H
Test.h #define FIRMWARE_TEST_H
Tools for firmware test
By MagoKimbra
*/
#include "elements.h" void FirmwareTest();
#include "Marlin_main.h"
#if ENABLED(AUTO_BED_LEVELING_FEATURE)
#include "vector_3.h"
#endif #endif
\ No newline at end of file
#include "planner.h"
#include "stepper_indirection.h"
#include "stepper.h"
#include "temperature.h"
static char serial_answer;
void FirmwareTest()
{
ECHO_EM("---------- FIRMWARE TEST --------------");
ECHO_EM("--------- by MarlinKimbra -------------");
ECHO_EV(MSG_FWTEST_01);
ECHO_EV(MSG_FWTEST_02);
ECHO_EV(MSG_FWTEST_YES_NO);
serial_answer = ' ';
while(serial_answer!='y' && serial_answer!='Y' && serial_answer!='n' && serial_answer!='N') {
serial_answer = MYSERIAL.read();
}
if (serial_answer=='y' || serial_answer=='Y') {
ECHO_EV(MSG_FWTEST_03);
ECHO_EM(" ");
ECHO_EM("***** ENDSTOP X *****");
#if EXIST(X_MIN_PIN) && X_MIN_PIN > -1 && X_HOME_DIR == -1
if (!READ(X_MIN_PIN)^X_MIN_ENDSTOP_INVERTING) {
ECHO_M("MIN ENDSTOP X: ");
ECHO_EV(MSG_ENDSTOP_OPEN);
}
else
{
ECHO_M("X ENDSTOP ");
ECHO_EM(MSG_FWTEST_ERROR);
ECHO_M(MSG_FWTEST_INVERT);
ECHO_M("#define X_MIN_ENDSTOP_LOGIC ");
ECHO_M(MSG_FWTEST_INTO);
#if MECH(CARTESIAN)
ECHO_EM("Configuration_Cartesian.h");
#elif MECH(COREXY)
ECHO_EM("Configuration_Core.h");
#elif MECH(COREXZ)
ECHO_EM("Configuration_Core.h");
#elif MECH(DELTA)
ECHO_EM("Configuration_Delta.h");
#elif MECH(SCARA)
ECHO_EM("Configuration_Scara.h");
#endif
return;
}
ECHO_V(MSG_FWTEST_PRESS);
ECHO_EM("X");
ECHO_EV(MSG_FWTEST_YES);
serial_answer = ' ';
while(serial_answer!='y' && serial_answer!='Y' && !(READ(X_MIN_PIN)^X_MIN_ENDSTOP_INVERTING)){
serial_answer = MYSERIAL.read();
}
if (READ(X_MIN_PIN)^X_MIN_ENDSTOP_INVERTING) {
ECHO_M("MIN ENDSTOP X: ");
ECHO_EV(MSG_ENDSTOP_HIT);
}
else
{
ECHO_M("X ");
ECHO_EV(MSG_FWTEST_ENDSTOP_ERR);
return;
}
#elif EXIST(X_MAX_PIN) && X_MAX_PIN > -1 && X_HOME_DIR == 1
if (!READ(X_MAX_PIN)^X_MAX_ENDSTOP_INVERTING) {
ECHO_M("MAX ENDSTOP X: ");
ECHO_EV(MSG_ENDSTOP_OPEN);
}
else
{
ECHO_M("X ENDSTOP ");
ECHO_EM(MSG_FWTEST_ERROR);
ECHO_M(MSG_FWTEST_INVERT);
ECHO_M("#define X_MAX_ENDSTOP_LOGIC ");
ECHO_M(MSG_FWTEST_INTO);
#if MECH(CARTESIAN)
ECHO_EM("Configuration_Cartesian.h");
#elif MECH(COREXY)
ECHO_EM("Configuration_Core.h");
#elif MECH(COREXZ)
ECHO_EM("Configuration_Core.h");
#elif MECH(DELTA)
ECHO_EM("Configuration_Delta.h");
#elif MECH(SCARA)
ECHO_EM("Configuration_Scara.h");
#endif
return;
}
ECHO_V(MSG_FWTEST_PRESS);
ECHO_EM("X");
ECHO_EV(MSG_FWTEST_YES);
serial_answer = ' ';
while(serial_answer!='y' && serial_answer!='Y' && !(READ(X_MAX_PIN)^X_MAX_ENDSTOP_INVERTING)) {
serial_answer = MYSERIAL.read();
}
if (READ(X_MAX_PIN)^X_MAX_ENDSTOP_INVERTING) {
ECHO_M("MAX ENDSTOP X: ");
ECHO_EV(MSG_ENDSTOP_HIT);
}
else
{
ECHO_M("X ");
ECHO_EV(MSG_FWTEST_ENDSTOP_ERR);
return;
}
#elif X_HOME_DIR == -1
ECHO_M(MSG_FWTEST_ERROR);
ECHO_M("!!! X_MIN_PIN ");
ECHO_EM(MSG_FWTEST_NDEF);
return;
#elif X_HOME_DIR == 1
ECHO_M(MSG_FWTEST_ERROR);
ECHO_M("!!! X_MAX_PIN ");
ECHO_EM(MSG_FWTEST_NDEF);
return;
#endif
ECHO_EM(" ");
ECHO_EM("***** ENDSTOP Y *****");
#if EXIST(Y_MIN_PIN) && Y_MIN_PIN > -1 && Y_HOME_DIR == -1
if (!READ(Y_MIN_PIN)^Y_MIN_ENDSTOP_INVERTING){
ECHO_M("MIN ENDSTOP Y: ");
ECHO_EV(MSG_ENDSTOP_OPEN);
}
else
{
ECHO_M("Y ENDSTOP ");
ECHO_EM(MSG_FWTEST_ERROR);
ECHO_M(MSG_FWTEST_INVERT);
ECHO_M("#define Y_MIN_ENDSTOP_LOGIC ");
ECHO_M(MSG_FWTEST_INTO);
#if MECH(CARTESIAN)
ECHO_EM("Configuration_Cartesian.h");
#elif MECH(COREXY)
ECHO_EM("Configuration_Core.h");
#elif MECH(COREXZ)
ECHO_EM("Configuration_Core.h");
#elif MECH(DELTA)
ECHO_EM("Configuration_Delta.h");
#elif MECH(SCARA)
ECHO_EM("Configuration_Scara.h");
#endif
return;
}
ECHO_V(MSG_FWTEST_PRESS);
ECHO_EM("Y");
ECHO_EV(MSG_FWTEST_YES);
serial_answer = ' ';
while(serial_answer!='y' && serial_answer!='Y' && !(READ(Y_MIN_PIN)^Y_MIN_ENDSTOP_INVERTING)){
serial_answer = MYSERIAL.read();
}
if (READ(Y_MIN_PIN)^Y_MIN_ENDSTOP_INVERTING){
ECHO_M("MIN ENDSTOP Y: ");
ECHO_EV(MSG_ENDSTOP_HIT);
}
else
{
ECHO_M("Y ");
ECHO_EV(MSG_FWTEST_ENDSTOP_ERR);
return;
}
#elif EXIST(Y_MAX_PIN) && Y_MAX_PIN > -1 && Y_HOME_DIR == 1
if (!READ(Y_MAX_PIN)^Y_MAX_ENDSTOP_INVERTING){
ECHO_M("MAX ENDSTOP Y: ");
ECHO_EV(MSG_ENDSTOP_OPEN);
}
else
{
ECHO_M("Y ENDSTOP ");
ECHO_EM(MSG_FWTEST_ERROR);
ECHO_M(MSG_FWTEST_INVERT);
ECHO_M("#define Y_MAX_ENDSTOP_LOGIC ");
ECHO_M(MSG_FWTEST_INTO);
#if MECH(CARTESIAN)
ECHO_EM("Configuration_Cartesian.h");
#elif MECH(COREXY)
ECHO_EM("Configuration_Core.h");
#elif MECH(COREXZ)
ECHO_EM("Configuration_Core.h");
#elif MECH(DELTA)
ECHO_EM("Configuration_Delta.h");
#elif MECH(SCARA)
ECHO_EM("Configuration_Scara.h");
#endif
return;
}
ECHO_V(MSG_FWTEST_PRESS);
ECHO_EM("Y");
ECHO_EV(MSG_FWTEST_YES);
serial_answer = ' ';
while(serial_answer!='y' && serial_answer!='Y' && !(READ(Y_MAX_PIN)^Y_MAX_ENDSTOP_INVERTING)){
serial_answer = MYSERIAL.read();
}
if (READ(Y_MAX_PIN)^Y_MAX_ENDSTOP_INVERTING){
ECHO_M("MAX ENDSTOP Y: ");
ECHO_EV(MSG_ENDSTOP_HIT);
}
else
{
ECHO_M("Y ");
ECHO_EV(MSG_FWTEST_ENDSTOP_ERR);
return;
}
#elif Y_HOME_DIR == -1
ECHO_M(MSG_FWTEST_ERROR);
ECHO_M("!!! Y_MIN_PIN ");
ECHO_EM(MSG_FWTEST_NDEF);
return;
#elif Y_HOME_DIR == 1
ECHO_M(MSG_FWTEST_ERROR);
ECHO_M("!!! Y_MAX_PIN ");
ECHO_EM(MSG_FWTEST_NDEF);
return;
#endif
ECHO_EM(" ");
ECHO_EM("***** ENDSTOP Z *****");
#if EXIST(Z_MIN_PIN) && Z_MIN_PIN > -1 && Z_HOME_DIR == -1
if (!READ(Z_MIN_PIN)^Z_MIN_ENDSTOP_INVERTING){
ECHO_M("MIN ENDSTOP Z: ");
ECHO_EV(MSG_ENDSTOP_OPEN);
}
else
{
ECHO_M("Z ENDSTOP ");
ECHO_EM(MSG_FWTEST_ERROR);
ECHO_M(MSG_FWTEST_INVERT);
ECHO_M("#define Z_MIN_ENDSTOP_LOGIC ");
ECHO_M(MSG_FWTEST_INTO);
#if MECH(CARTESIAN)
ECHO_EM("Configuration_Cartesian.h");
#elif MECH(COREXY)
ECHO_EM("Configuration_Core.h");
#elif MECH(COREXZ)
ECHO_EM("Configuration_Core.h");
#elif MECH(DELTA)
ECHO_EM("Configuration_Delta.h");
#elif MECH(SCARA)
ECHO_EM("Configuration_Scara.h");
#endif
return;
}
ECHO_V(MSG_FWTEST_PRESS);
ECHO_EM("Z");
ECHO_EV(MSG_FWTEST_YES);
serial_answer = ' ';
while(serial_answer!='y' && serial_answer!='Y' && !(READ(Z_MIN_PIN)^Z_MIN_ENDSTOP_INVERTING)){
serial_answer = MYSERIAL.read();
}
if (READ(Z_MIN_PIN)^Z_MIN_ENDSTOP_INVERTING){
ECHO_M("MIN ENDSTOP Z: ");
ECHO_EV(MSG_ENDSTOP_HIT);
}
else
{
ECHO_M("Z ");
ECHO_EV(MSG_FWTEST_ENDSTOP_ERR);
return;
}
#elif EXIST(Z_MAX_PIN) && Z_MAX_PIN > -1 && Z_HOME_DIR == 1
if (!READ(Z_MAX_PIN)^Z_MAX_ENDSTOP_INVERTING){
ECHO_M("MAX ENDSTOP Z: ");
ECHO_EV(MSG_ENDSTOP_OPEN);
}
else
{
ECHO_M("Z ENDSTOP ");
ECHO_EM(MSG_FWTEST_ERROR);
ECHO_M(MSG_FWTEST_INVERT);
ECHO_M("#define Z_MAX_ENDSTOP_LOGIC ");
ECHO_M(MSG_FWTEST_INTO);
#if MECH(CARTESIAN)
ECHO_EM("Configuration_Cartesian.h");
#elif MECH(COREXY)
ECHO_EM("Configuration_Core.h");
#elif MECH(COREXZ)
ECHO_EM("Configuration_Core.h");
#elif MECH(DELTA)
ECHO_EM("Configuration_Delta.h");
#elif MECH(SCARA)
ECHO_EM("Configuration_Scara.h");
#endif
return;
}
ECHO_V(MSG_FWTEST_PRESS);
ECHO_EM("Z");
ECHO_EV(MSG_FWTEST_YES);
serial_answer = ' ';
while(serial_answer!='y' && serial_answer!='Y' && !(READ(Z_MAX_PIN)^Z_MAX_ENDSTOP_INVERTING)){
serial_answer = MYSERIAL.read();
}
if (READ(Z_MAX_PIN)^Z_MAX_ENDSTOP_INVERTING){
ECHO_M("MAX ENDSTOP Z: ");
ECHO_EV(MSG_ENDSTOP_HIT);
}
else
{
ECHO_M("Z ");
ECHO_EV(MSG_FWTEST_ENDSTOP_ERR);
return;
}
#elif Z_HOME_DIR == -1
ECHO_M(MSG_FWTEST_ERROR);
ECHO_M("!!! Z_MIN_PIN ");
ECHO_EM(MSG_FWTEST_NDEF);
return;
#elif Z_HOME_DIR == 1
ECHO_M(MSG_FWTEST_ERROR);
ECHO_M("!!! Z_MAX_PIN ");
ECHO_EM(MSG_FWTEST_NDEF);
return;
#endif
ECHO_EM("ENDSTOP ");
ECHO_M(MSG_FWTEST_OK);
ECHO_EM(" ");
}
#if HAS(POWER_SWITCH)
SET_OUTPUT(PS_ON_PIN);
WRITE(PS_ON_PIN, PS_ON_AWAKE);
#endif
// Reset position to 0
st_synchronize();
for(int8_t i=0; i < NUM_AXIS; i++) current_position[i] = 0;
plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]);
ECHO_EM("***** TEST MOTOR *****");
ECHO_EV(MSG_FWTEST_ATTENTION);
ECHO_EV(MSG_FWTEST_YES);
serial_answer = ' ';
while(serial_answer!='y' && serial_answer!='Y'){
serial_answer = MYSERIAL.read();
}
ECHO_EV(MSG_FWTEST_04);
ECHO_EM(" ");
ECHO_EM("***** MOTOR X *****");
destination[X_AXIS] = 10;
prepare_move();
st_synchronize();
ECHO_EV(MSG_FWTEST_XAXIS);
ECHO_EV(MSG_FWTEST_YES_NO);
serial_answer = ' ';
while(serial_answer!='y' && serial_answer!='Y' && serial_answer!='n' && serial_answer!='N'){
serial_answer = MYSERIAL.read();
}
if(serial_answer=='y' || serial_answer=='Y'){
ECHO_EM("MOTOR X ");
ECHO_M(MSG_FWTEST_OK);
}
else
{
ECHO_M(MSG_FWTEST_INVERT);
ECHO_M("#define INVERT_X_DIR ");
ECHO_M(MSG_FWTEST_INTO);
#if MECH(CARTESIAN)
ECHO_EM("Configuration_Cartesian.h");
#elif MECH(COREXY)
ECHO_EM("Configuration_Core.h");
#elif MECH(COREXZ)
ECHO_EM("Configuration_Core.h");
#elif MECH(DELTA)
ECHO_EM("Configuration_Delta.h");
#elif MECH(SCARA)
ECHO_EM("Configuration_Scara.h");
#endif
return;
}
ECHO_EM(" ");
ECHO_EM("***** MOTOR Y *****");
destination[Y_AXIS] = 10;
prepare_move();
st_synchronize();
ECHO_EV(MSG_FWTEST_YAXIS);
ECHO_EV(MSG_FWTEST_YES_NO);
serial_answer = ' ';
while(serial_answer!='y' && serial_answer!='Y' && serial_answer!='n' && serial_answer!='N'){
serial_answer = MYSERIAL.read();
}
if(serial_answer=='y' || serial_answer=='Y'){
ECHO_EM("MOTOR Y ");
ECHO_M(MSG_FWTEST_OK);
}
else
{
ECHO_M(MSG_FWTEST_INVERT);
ECHO_M("#define INVERT_Y_DIR ");
ECHO_M(MSG_FWTEST_INTO);
#if MECH(CARTESIAN)
ECHO_EM("Configuration_Cartesian.h");
#elif MECH(COREXY)
ECHO_EM("Configuration_Core.h");
#elif MECH(COREXZ)
ECHO_EM("Configuration_Core.h");
#elif MECH(DELTA)
ECHO_EM("Configuration_Delta.h");
#elif MECH(SCARA)
ECHO_EM("Configuration_Scara.h");
#endif
return;
}
ECHO_EM(" ");
ECHO_EM("***** MOTOR Z *****");
destination[Z_AXIS] = 10;
prepare_move();
st_synchronize();
ECHO_EV(MSG_FWTEST_ZAXIS);
ECHO_EV(MSG_FWTEST_YES_NO);
serial_answer = ' ';
while(serial_answer!='y' && serial_answer!='Y' && serial_answer!='n' && serial_answer!='N'){
serial_answer = MYSERIAL.read();
}
if(serial_answer=='y' || serial_answer=='Y'){
ECHO_EM("MOTOR Z ");
ECHO_M(MSG_FWTEST_OK);
}
else
{
ECHO_M(MSG_FWTEST_INVERT);
ECHO_M("#define INVERT_Z_DIR ");
ECHO_M(MSG_FWTEST_INTO);
#if MECH(CARTESIAN)
ECHO_EM("Configuration_Cartesian.h");
#elif MECH(COREXY)
ECHO_EM("Configuration_Core.h");
#elif MECH(COREXZ)
ECHO_EM("Configuration_Core.h");
#elif MECH(DELTA)
ECHO_EM("Configuration_Delta.h");
#elif MECH(SCARA)
ECHO_EM("Configuration_Scara.h");
#endif
return;
}
ECHO_EM("MOTOR ");
ECHO_M(MSG_FWTEST_OK);
ECHO_EM(" ");
ECHO_V(MSG_FWTEST_END);
}
...@@ -63,9 +63,9 @@ ...@@ -63,9 +63,9 @@
#define MSG_FAN_SPEED "Ventilador" #define MSG_FAN_SPEED "Ventilador"
#define MSG_FLOW "Flujo" #define MSG_FLOW "Flujo"
#define MSG_CONTROL "Control" #define MSG_CONTROL "Control"
#define MSG_MIN STR_THERMOMETER " Min" #define MSG_MIN LCD_STR_THERMOMETER " Min"
#define MSG_MAX STR_THERMOMETER " Max" #define MSG_MAX LCD_STR_THERMOMETER " Max"
#define MSG_FACTOR STR_THERMOMETER " Fact" #define MSG_FACTOR LCD_STR_THERMOMETER " Fact"
#define MSG_IDLEOOZING "Anti oozing" #define MSG_IDLEOOZING "Anti oozing"
#define MSG_AUTOTEMP "Autotemp" #define MSG_AUTOTEMP "Autotemp"
#define MSG_ON "On " #define MSG_ON "On "
......
...@@ -61,9 +61,9 @@ ...@@ -61,9 +61,9 @@
#define MSG_FAN_SPEED "Haizagailua" #define MSG_FAN_SPEED "Haizagailua"
#define MSG_FLOW "Fluxua" #define MSG_FLOW "Fluxua"
#define MSG_CONTROL "Kontrola" #define MSG_CONTROL "Kontrola"
#define MSG_MIN " " STR_THERMOMETER " Min" #define MSG_MIN " " LCD_STR_THERMOMETER " Min"
#define MSG_MAX " " STR_THERMOMETER " Max" #define MSG_MAX " " LCD_STR_THERMOMETER " Max"
#define MSG_FACTOR " " STR_THERMOMETER " Fact" #define MSG_FACTOR " " LCD_STR_THERMOMETER " Fact"
#define MSG_IDLEOOZING "Anti oozing" #define MSG_IDLEOOZING "Anti oozing"
#define MSG_AUTOTEMP "Auto tenperatura" #define MSG_AUTOTEMP "Auto tenperatura"
#define MSG_ON "On " #define MSG_ON "On "
......
...@@ -61,9 +61,9 @@ ...@@ -61,9 +61,9 @@
#define MSG_FAN_SPEED "Tuul. nopeus" #define MSG_FAN_SPEED "Tuul. nopeus"
#define MSG_FLOW "Virtaus" #define MSG_FLOW "Virtaus"
#define MSG_CONTROL "Kontrolli" #define MSG_CONTROL "Kontrolli"
#define MSG_MIN STR_THERMOMETER " Min" #define MSG_MIN LCD_STR_THERMOMETER " Min"
#define MSG_MAX STR_THERMOMETER " Max" #define MSG_MAX LCD_STR_THERMOMETER " Max"
#define MSG_FACTOR STR_THERMOMETER " Kerr" #define MSG_FACTOR LCD_STR_THERMOMETER " Kerr"
#define MSG_IDLEOOZING "Anti oozing" #define MSG_IDLEOOZING "Anti oozing"
#define MSG_AUTOTEMP "Autotemp" #define MSG_AUTOTEMP "Autotemp"
#define MSG_ON "On " #define MSG_ON "On "
......
...@@ -62,9 +62,9 @@ ...@@ -62,9 +62,9 @@
#define MSG_FAN_SPEED "Vite. ventilateur" #define MSG_FAN_SPEED "Vite. ventilateur"
#define MSG_FLOW "Flux" #define MSG_FLOW "Flux"
#define MSG_CONTROL "Controler" #define MSG_CONTROL "Controler"
#define MSG_MIN " " STR_THERMOMETER " Min" #define MSG_MIN " " LCD_STR_THERMOMETER " Min"
#define MSG_MAX " " STR_THERMOMETER " Max" #define MSG_MAX " " LCD_STR_THERMOMETER " Max"
#define MSG_FACTOR " " STR_THERMOMETER " Facteur" #define MSG_FACTOR " " LCD_STR_THERMOMETER " Facteur"
#define MSG_IDLEOOZING "Anti oozing" #define MSG_IDLEOOZING "Anti oozing"
#define MSG_AUTOTEMP "Temp. Auto." #define MSG_AUTOTEMP "Temp. Auto."
#define MSG_ON "Marche " #define MSG_ON "Marche "
......
...@@ -61,9 +61,9 @@ ...@@ -61,9 +61,9 @@
#define MSG_FAN_SPEED "Fan snelheid" #define MSG_FAN_SPEED "Fan snelheid"
#define MSG_FLOW "Flow" #define MSG_FLOW "Flow"
#define MSG_CONTROL "Control" #define MSG_CONTROL "Control"
#define MSG_MIN " " STR_THERMOMETER " Min" #define MSG_MIN " " LCD_STR_THERMOMETER " Min"
#define MSG_MAX " " STR_THERMOMETER " Max" #define MSG_MAX " " LCD_STR_THERMOMETER " Max"
#define MSG_FACTOR " " STR_THERMOMETER " Fact" #define MSG_FACTOR " " LCD_STR_THERMOMETER " Fact"
#define MSG_IDLEOOZING "Anti oozing" #define MSG_IDLEOOZING "Anti oozing"
#define MSG_AUTOTEMP "Autotemp" #define MSG_AUTOTEMP "Autotemp"
#define MSG_ON "Aan " #define MSG_ON "Aan "
......
...@@ -61,9 +61,9 @@ ...@@ -61,9 +61,9 @@
#define MSG_FAN_SPEED "Obroty wiatraka" #define MSG_FAN_SPEED "Obroty wiatraka"
#define MSG_FLOW "Przeplyw" #define MSG_FLOW "Przeplyw"
#define MSG_CONTROL "Ustawienia" #define MSG_CONTROL "Ustawienia"
#define MSG_MIN " " STR_THERMOMETER " Min" #define MSG_MIN " " LCD_STR_THERMOMETER " Min"
#define MSG_MAX " " STR_THERMOMETER " Max" #define MSG_MAX " " LCD_STR_THERMOMETER " Max"
#define MSG_FACTOR " " STR_THERMOMETER " Fact" #define MSG_FACTOR " " LCD_STR_THERMOMETER " Fact"
#define MSG_IDLEOOZING "Anti oozing" #define MSG_IDLEOOZING "Anti oozing"
#define MSG_AUTOTEMP "Auto. temperatura" #define MSG_AUTOTEMP "Auto. temperatura"
#define MSG_ON "Wl. " #define MSG_ON "Wl. "
......
...@@ -61,9 +61,9 @@ ...@@ -61,9 +61,9 @@
#define MSG_FAN_SPEED "Velocidade do ar." #define MSG_FAN_SPEED "Velocidade do ar."
#define MSG_FLOW "Fluxo" #define MSG_FLOW "Fluxo"
#define MSG_CONTROL "Control" #define MSG_CONTROL "Control"
#define MSG_MIN " " STR_THERMOMETER " Min" #define MSG_MIN " " LCD_STR_THERMOMETER " Min"
#define MSG_MAX " " STR_THERMOMETER " Max" #define MSG_MAX " " LCD_STR_THERMOMETER " Max"
#define MSG_FACTOR " " STR_THERMOMETER " Fact" #define MSG_FACTOR " " LCD_STR_THERMOMETER " Fact"
#define MSG_IDLEOOZING "Anti oozing" #define MSG_IDLEOOZING "Anti oozing"
#define MSG_AUTOTEMP "Autotemp" #define MSG_AUTOTEMP "Autotemp"
#define MSG_ON "On " #define MSG_ON "On "
......
...@@ -61,9 +61,9 @@ ...@@ -61,9 +61,9 @@
#define MSG_FAN_SPEED "Куллер:" #define MSG_FAN_SPEED "Куллер:"
#define MSG_FLOW "Поток:" #define MSG_FLOW "Поток:"
#define MSG_CONTROL "Настройки" #define MSG_CONTROL "Настройки"
#define MSG_MIN " " STR_THERMOMETER "Минимум" #define MSG_MIN " " LCD_STR_THERMOMETER "Минимум"
#define MSG_MAX " " STR_THERMOMETER "Максимум" #define MSG_MAX " " LCD_STR_THERMOMETER "Максимум"
#define MSG_FACTOR " " STR_THERMOMETER "Фактор" #define MSG_FACTOR " " LCD_STR_THERMOMETER "Фактор"
#define MSG_IDLEOOZING "Anti oozing" #define MSG_IDLEOOZING "Anti oozing"
#define MSG_AUTOTEMP "Autotemp" #define MSG_AUTOTEMP "Autotemp"
#define MSG_ON "Вкл." #define MSG_ON "Вкл."
......
#define M100_FREE_MEMORY_DUMPER // Comment out to remove Dump sub-command
#define M100_FREE_MEMORY_CORRUPTOR // Comment out to remove Corrupt sub-command
// M100 Free Memory Watcher
//
// This code watches the free memory block between the bottom of the heap and the top of the stack.
// This memory block is initialized and watched via the M100 command.
//
// M100 I Initializes the free memory block and prints vitals statistics about the area
// M100 F Identifies how much of the free memory block remains free and unused. It also
// detects and reports any corruption within the free memory block that may have
// happened due to errant firmware.
// M100 D Does a hex display of the free memory block along with a flag for any errant
// data that does not match the expected value.
// M100 C x Corrupts x locations within the free memory block. This is useful to check the
// correctness of the M100 F and M100 D commands.
//
// Initial version by Roxy-3DPrintBoard
//
//
#include "Marlin.h"
#if ENABLED(M100_FREE_MEMORY_WATCHER)
extern void *__brkval;
extern size_t __heap_start, __heap_end, __flp;
//
// Declare all the functions we need from Marlin_Main.cpp to do the work!
//
float code_value();
long code_value_long();
bool code_seen(char );
//
// Utility functions used by M100 to get its work done.
//
unsigned char *top_of_stack();
void prt_hex_nibble( unsigned int );
void prt_hex_byte(unsigned int );
void prt_hex_word(unsigned int );
int how_many_E5s_are_here( unsigned char *);
void gcode_M100() {
static int m100_not_initialized = 1;
unsigned char *sp, *ptr;
int i, j, n;
//
// M100 D dumps the free memory block from __brkval to the stack pointer.
// malloc() eats memory from the start of the block and the stack grows
// up from the bottom of the block. Solid 0xE5's indicate nothing has
// used that memory yet. There should not be anything but 0xE5's within
// the block of 0xE5's. If there is, that would indicate memory corruption
// probably caused by bad pointers. Any unexpected values will be flagged in
// the right hand column to help spotting them.
//
#if ENABLED(M100_FREE_MEMORY_DUMPER) // Comment out to remove Dump sub-command
if ( code_seen('D') ) {
ptr = (unsigned char *) __brkval;
//
// We want to start and end the dump on a nice 16 byte boundry even though
// the values we are using are not 16 byte aligned.
//
ECHO_M("\n__brkval : ");
prt_hex_word( (unsigned int) ptr );
ptr = (unsigned char *) ((unsigned long) ptr & 0xfff0);
sp = top_of_stack();
ECHO_M("\nStack Pointer : ");
prt_hex_word( (unsigned int) sp );
ECHO_M("\n");
sp = (unsigned char *) ((unsigned long) sp | 0x000f);
n = sp - ptr;
//
// This is the main loop of the Dump command.
//
while ( ptr < sp ) {
prt_hex_word( (unsigned int) ptr); // Print the address
ECHO_M(":");
for(i = 0; i < 16; i++) { // and 16 data bytes
prt_hex_byte( *(ptr+i));
ECHO_M(" ");
delay(2);
}
ECHO_M("|"); // now show where non 0xE5's are
for(i = 0; i < 16; i++) {
delay(2);
if ( *(ptr+i)==0xe5)
ECHO_M(" ");
else
ECHO_M("?");
}
ECHO_M("\n");
ptr += 16;
delay(2);
}
ECHO_M("Done.\n");
return;
}
#endif
//
// M100 F requests the code to return the number of free bytes in the memory pool along with
// other vital statistics that define the memory pool.
//
if ( code_seen('F') ) {
int max_addr = (int) __brkval;
int max_cnt = 0;
int block_cnt = 0;
ptr = (unsigned char *) __brkval;
sp = top_of_stack();
n = sp - ptr;
// Scan through the range looking for the biggest block of 0xE5's we can find
for(i = 0; i < n; i++) {
if ( *(ptr+i) == (unsigned char) 0xe5) {
j = how_many_E5s_are_here( (unsigned char *) ptr+i );
if ( j > 8) {
ECHO_MV("Found ", j );
ECHO_M(" bytes free at 0x");
prt_hex_word( (int) ptr+i );
ECHO_M("\n");
i += j;
block_cnt++;
}
if ( j>max_cnt) { // We don't do anything with this information yet
max_cnt = j; // but we do know where the biggest free memory block is.
max_addr = (int) ptr+i;
}
}
}
if (block_cnt>1)
ECHO_EM("\nMemory Corruption detected in free memory area.\n");
ECHO_M("\nDone.\n");
return;
}
//
// M100 C x Corrupts x locations in the free memory pool and reports the locations of the corruption.
// This is useful to check the correctness of the M100 D and the M100 F commands.
//
#if ENABLED(M100_FREE_MEMORY_CORRUPTOR)
if ( code_seen('C') ) {
int x; // x gets the # of locations to corrupt within the memory pool
x = code_value();
ECHO_EM("Corrupting free memory block.\n");
ptr = (unsigned char *) __brkval;
ECHO_MV("\n__brkval : ",(long) ptr );
ptr += 8;
sp = top_of_stack();
ECHO_MV("\nStack Pointer : ",(long) sp );
ECHO_EM("\n");
n = sp - ptr - 64; // -64 just to keep us from finding interrupt activity that
// has altered the stack.
j = n / (x+1);
for(i = 1; i <= x; i++) {
*(ptr+(i*j)) = i;
ECHO_M("\nCorrupting address: 0x");
prt_hex_word( (unsigned int) (ptr+(i*j)) );
}
ECHO_EM("\n");
return;
}
#endif
//
// M100 I Initializes the free memory pool so it can be watched and prints vital
// statistics that define the free memory pool.
//
if (m100_not_initialized || code_seen('I') ) { // If no sub-command is specified, the first time
ECHO_EM("Initializing free memory block.\n"); // this happens, it will Initialize.
ptr = (unsigned char *) __brkval; // Repeated M100 with no sub-command will not destroy the
ECHO_MV("\n__brkval : ",(long) ptr ); // state of the initialized free memory pool.
ptr += 8;
sp = top_of_stack();
ECHO_MV("\nStack Pointer : ",(long) sp );
ECHO_EM("\n");
n = sp - ptr - 64; // -64 just to keep us from finding interrupt activity that
// has altered the stack.
ECHO_V( n );
ECHO_EM(" bytes of memory initialized.\n");
for(i = 0; i < n; i++)
*(ptr+i) = (unsigned char) 0xe5;
for(i = 0; i < n; i++) {
if ( *(ptr+i) != (unsigned char) 0xe5 ) {
ECHO_MV("? address : ", (unsigned long) ptr+i );
ECHO_MV("=", *(ptr+i) );
ECHO_EM("\n");
}
}
m100_not_initialized = 0;
ECHO_EM("Done.\n");
return;
}
return;
}
// top_of_stack() returns the location of a variable on its stack frame. The value returned is above
// the stack once the function returns to the caller.
unsigned char *top_of_stack() {
unsigned char x;
return &x + 1; // x is pulled on return;
}
//
// 3 support routines to print hex numbers. We can print a nibble, byte and word
//
void prt_hex_nibble( unsigned int n ) {
if ( n <= 9 )
ECHO_V(n);
else
ECHO_V( (char) ('A'+n-10) );
delay(2);
}
void prt_hex_byte(unsigned int b) {
prt_hex_nibble( ( b & 0xf0 ) >> 4 );
prt_hex_nibble( b & 0x0f );
}
void prt_hex_word(unsigned int w) {
prt_hex_byte( ( w & 0xff00 ) >> 8 );
prt_hex_byte( w & 0x0ff );
}
// how_many_E5s_are_here() is a utility function to easily find out how many 0xE5's are
// at the specified location. Having this logic as a function simplifies the search code.
//
int how_many_E5s_are_here( unsigned char *p) {
int n;
for(n = 0; n < 32000; n++) {
if ( *(p+n) != (unsigned char) 0xe5)
return n-1;
}
return -1;
}
#endif
#define M100_FREE_MEMORY_DUMPER // Comment out to remove Dump sub-command
#define M100_FREE_MEMORY_CORRUPTOR // Comment out to remove Corrupt sub-command
// M100 Free Memory Watcher
//
// This code watches the free memory block between the bottom of the heap and the top of the stack.
// This memory block is initialized and watched via the M100 command.
//
// M100 I Initializes the free memory block and prints vitals statistics about the area
// M100 F Identifies how much of the free memory block remains free and unused. It also
// detects and reports any corruption within the free memory block that may have
// happened due to errant firmware.
// M100 D Does a hex display of the free memory block along with a flag for any errant
// data that does not match the expected value.
// M100 C x Corrupts x locations within the free memory block. This is useful to check the
// correctness of the M100 F and M100 D commands.
//
// Initial version by Roxy-3DPrintBoard
//
//
#include "Marlin.h"
#if ENABLED(M100_FREE_MEMORY_WATCHER)
extern void *__brkval;
extern size_t __heap_start, __heap_end, __flp;
//
// Declare all the functions we need from Marlin_Main.cpp to do the work!
//
float code_value();
long code_value_long();
bool code_seen(char );
//
// Utility functions used by M100 to get its work done.
//
unsigned char *top_of_stack();
void prt_hex_nibble( unsigned int );
void prt_hex_byte(unsigned int );
void prt_hex_word(unsigned int );
int how_many_E5s_are_here( unsigned char *);
void gcode_M100() {
static int m100_not_initialized = 1;
unsigned char *sp, *ptr;
int i, j, n;
//
// M100 D dumps the free memory block from __brkval to the stack pointer.
// malloc() eats memory from the start of the block and the stack grows
// up from the bottom of the block. Solid 0xE5's indicate nothing has
// used that memory yet. There should not be anything but 0xE5's within
// the block of 0xE5's. If there is, that would indicate memory corruption
// probably caused by bad pointers. Any unexpected values will be flagged in
// the right hand column to help spotting them.
//
#if ENABLED(M100_FREE_MEMORY_DUMPER) // Comment out to remove Dump sub-command
if ( code_seen('D') ) {
ptr = (unsigned char *) __brkval;
//
// We want to start and end the dump on a nice 16 byte boundry even though
// the values we are using are not 16 byte aligned.
//
ECHO_M("\n__brkval : ");
prt_hex_word( (unsigned int) ptr );
ptr = (unsigned char *) ((unsigned long) ptr & 0xfff0);
sp = top_of_stack();
ECHO_M("\nStack Pointer : ");
prt_hex_word( (unsigned int) sp );
ECHO_M("\n");
sp = (unsigned char *) ((unsigned long) sp | 0x000f);
n = sp - ptr;
//
// This is the main loop of the Dump command.
//
while ( ptr < sp ) {
prt_hex_word( (unsigned int) ptr); // Print the address
ECHO_M(":");
for(i = 0; i < 16; i++) { // and 16 data bytes
prt_hex_byte( *(ptr+i));
ECHO_M(" ");
delay(2);
}
ECHO_M("|"); // now show where non 0xE5's are
for(i = 0; i < 16; i++) {
delay(2);
if ( *(ptr+i)==0xe5)
ECHO_M(" ");
else
ECHO_M("?");
}
ECHO_M("\n");
ptr += 16;
delay(2);
}
ECHO_M("Done.\n");
return;
}
#endif
//
// M100 F requests the code to return the number of free bytes in the memory pool along with
// other vital statistics that define the memory pool.
//
if ( code_seen('F') ) {
int max_addr = (int) __brkval;
int max_cnt = 0;
int block_cnt = 0;
ptr = (unsigned char *) __brkval;
sp = top_of_stack();
n = sp - ptr;
// Scan through the range looking for the biggest block of 0xE5's we can find
for(i = 0; i < n; i++) {
if ( *(ptr+i) == (unsigned char) 0xe5) {
j = how_many_E5s_are_here( (unsigned char *) ptr+i );
if ( j > 8) {
ECHO_MV("Found ", j );
ECHO_M(" bytes free at 0x");
prt_hex_word( (int) ptr+i );
ECHO_M("\n");
i += j;
block_cnt++;
}
if ( j>max_cnt) { // We don't do anything with this information yet
max_cnt = j; // but we do know where the biggest free memory block is.
max_addr = (int) ptr+i;
}
}
}
if (block_cnt>1)
ECHO_EM("\nMemory Corruption detected in free memory area.\n");
ECHO_M("\nDone.\n");
return;
}
//
// M100 C x Corrupts x locations in the free memory pool and reports the locations of the corruption.
// This is useful to check the correctness of the M100 D and the M100 F commands.
//
#if ENABLED(M100_FREE_MEMORY_CORRUPTOR)
if ( code_seen('C') ) {
int x; // x gets the # of locations to corrupt within the memory pool
x = code_value();
ECHO_EM("Corrupting free memory block.\n");
ptr = (unsigned char *) __brkval;
ECHO_MV("\n__brkval : ",(long) ptr );
ptr += 8;
sp = top_of_stack();
ECHO_MV("\nStack Pointer : ",(long) sp );
ECHO_EM("\n");
n = sp - ptr - 64; // -64 just to keep us from finding interrupt activity that
// has altered the stack.
j = n / (x+1);
for(i = 1; i <= x; i++) {
*(ptr+(i*j)) = i;
ECHO_M("\nCorrupting address: 0x");
prt_hex_word( (unsigned int) (ptr+(i*j)) );
}
ECHO_EM("\n");
return;
}
#endif
//
// M100 I Initializes the free memory pool so it can be watched and prints vital
// statistics that define the free memory pool.
//
if (m100_not_initialized || code_seen('I') ) { // If no sub-command is specified, the first time
ECHO_EM("Initializing free memory block.\n"); // this happens, it will Initialize.
ptr = (unsigned char *) __brkval; // Repeated M100 with no sub-command will not destroy the
ECHO_MV("\n__brkval : ",(long) ptr ); // state of the initialized free memory pool.
ptr += 8;
sp = top_of_stack();
ECHO_MV("\nStack Pointer : ",(long) sp );
ECHO_EM("\n");
n = sp - ptr - 64; // -64 just to keep us from finding interrupt activity that
// has altered the stack.
ECHO_V( n );
ECHO_EM(" bytes of memory initialized.\n");
for(i = 0; i < n; i++)
*(ptr+i) = (unsigned char) 0xe5;
for(i = 0; i < n; i++) {
if ( *(ptr+i) != (unsigned char) 0xe5 ) {
ECHO_MV("? address : ", (unsigned long) ptr+i );
ECHO_MV("=", *(ptr+i) );
ECHO_EM("\n");
}
}
m100_not_initialized = 0;
ECHO_EM("Done.\n");
return;
}
return;
}
// top_of_stack() returns the location of a variable on its stack frame. The value returned is above
// the stack once the function returns to the caller.
unsigned char *top_of_stack() {
unsigned char x;
return &x + 1; // x is pulled on return;
}
//
// 3 support routines to print hex numbers. We can print a nibble, byte and word
//
void prt_hex_nibble( unsigned int n ) {
if ( n <= 9 )
ECHO_V(n);
else
ECHO_V( (char) ('A'+n-10) );
delay(2);
}
void prt_hex_byte(unsigned int b) {
prt_hex_nibble( ( b & 0xf0 ) >> 4 );
prt_hex_nibble( b & 0x0f );
}
void prt_hex_word(unsigned int w) {
prt_hex_byte( ( w & 0xff00 ) >> 8 );
prt_hex_byte( w & 0x0ff );
}
// how_many_E5s_are_here() is a utility function to easily find out how many 0xE5's are
// at the specified location. Having this logic as a function simplifies the search code.
//
int how_many_E5s_are_here( unsigned char *p) {
int n;
for(n = 0; n < 32000; n++) {
if ( *(p+n) != (unsigned char) 0xe5)
return n-1;
}
return -1;
}
#endif
...@@ -1136,6 +1136,27 @@ long st_get_position(uint8_t axis) { ...@@ -1136,6 +1136,27 @@ long st_get_position(uint8_t axis) {
float st_get_position_mm(AxisEnum axis) { return st_get_position(axis) / axis_steps_per_unit[axis]; } float st_get_position_mm(AxisEnum axis) { return st_get_position(axis) / axis_steps_per_unit[axis]; }
void enable_all_steppers() {
enable_x();
enable_y();
enable_z();
enable_e0();
enable_e1();
enable_e2();
enable_e3();
}
void disable_all_steppers() {
disable_x();
disable_y();
disable_z();
disable_e0();
disable_e1();
disable_e2();
disable_e3();
}
void finishAndDisableSteppers() { void finishAndDisableSteppers() {
st_synchronize(); st_synchronize();
disable_all_steppers(); disable_all_steppers();
......
...@@ -21,6 +21,17 @@ ...@@ -21,6 +21,17 @@
#ifndef STEPPER_H #ifndef STEPPER_H
#define STEPPER_H #define STEPPER_H
/**
* Axis indices as enumerated constants
*
* A_AXIS and B_AXIS are used by COREXY printers
* X_HEAD and Y_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};
#if DRIVER_EXTRUDERS > 3 #if DRIVER_EXTRUDERS > 3
#define E_STEP_WRITE(v) { if(current_block->active_driver == 3) { E3_STEP_WRITE(v); } else { if(current_block->active_driver == 2) { E2_STEP_WRITE(v); } else { if(current_block->active_driver == 1) { E1_STEP_WRITE(v); } else { E0_STEP_WRITE(v); }}}} #define E_STEP_WRITE(v) { if(current_block->active_driver == 3) { E3_STEP_WRITE(v); } else { if(current_block->active_driver == 2) { E2_STEP_WRITE(v); } else { if(current_block->active_driver == 1) { E1_STEP_WRITE(v); } else { E0_STEP_WRITE(v); }}}}
#define NORM_E_DIR() { if(current_block->active_driver == 3) { E3_DIR_WRITE( !INVERT_E3_DIR); } else { if(current_block->active_driver == 2) { E2_DIR_WRITE(!INVERT_E2_DIR); } else { if(current_block->active_driver == 1) { E1_DIR_WRITE(!INVERT_E1_DIR); } else { E0_DIR_WRITE(!INVERT_E0_DIR); }}}} #define NORM_E_DIR() { if(current_block->active_driver == 3) { E3_DIR_WRITE( !INVERT_E3_DIR); } else { if(current_block->active_driver == 2) { E2_DIR_WRITE(!INVERT_E2_DIR); } else { if(current_block->active_driver == 1) { E1_DIR_WRITE(!INVERT_E1_DIR); } else { E0_DIR_WRITE(!INVERT_E0_DIR); }}}}
...@@ -77,6 +88,8 @@ void enable_endstops(bool check); // Enable/disable endstop checking ...@@ -77,6 +88,8 @@ void enable_endstops(bool check); // Enable/disable endstop checking
void checkStepperErrors(); //Print errors detected by the stepper void checkStepperErrors(); //Print errors detected by the stepper
void enable_all_steppers();
void disable_all_steppers();
void finishAndDisableSteppers(); void finishAndDisableSteppers();
extern block_t *current_block; // A pointer to the block currently being traced extern block_t *current_block; // A pointer to the block currently being traced
......
...@@ -152,6 +152,77 @@ ...@@ -152,6 +152,77 @@
#define E3_ENABLE_WRITE(STATE) WRITE(E3_ENABLE_PIN,STATE) #define E3_ENABLE_WRITE(STATE) WRITE(E3_ENABLE_PIN,STATE)
#define E3_ENABLE_READ READ(E3_ENABLE_PIN) #define E3_ENABLE_READ READ(E3_ENABLE_PIN)
#if ENABLED(DUAL_X_CARRIAGE) && HAS(X_ENABLE) && HAS(X2_ENABLE)
#define enable_x() do { X_ENABLE_WRITE( X_ENABLE_ON); X2_ENABLE_WRITE( X_ENABLE_ON); } while (0)
#define disable_x() do { X_ENABLE_WRITE(!X_ENABLE_ON); X2_ENABLE_WRITE(!X_ENABLE_ON); axis_known_position[X_AXIS] = false; } while (0)
#elif HAS(X_ENABLE)
#define enable_x() X_ENABLE_WRITE( X_ENABLE_ON)
#define disable_x() { X_ENABLE_WRITE(!X_ENABLE_ON); axis_known_position[X_AXIS] = false; }
#else
#define enable_x() ;
#define disable_x() ;
#endif
#if HAS(Y_ENABLE)
#if ENABLED(Y_DUAL_STEPPER_DRIVERS)
#define enable_y() { Y_ENABLE_WRITE( Y_ENABLE_ON); Y2_ENABLE_WRITE(Y_ENABLE_ON); }
#define disable_y() { Y_ENABLE_WRITE(!Y_ENABLE_ON); Y2_ENABLE_WRITE(!Y_ENABLE_ON); axis_known_position[Y_AXIS] = false; }
#else
#define enable_y() Y_ENABLE_WRITE( Y_ENABLE_ON)
#define disable_y() { Y_ENABLE_WRITE(!Y_ENABLE_ON); axis_known_position[Y_AXIS] = false; }
#endif
#else
#define enable_y() ;
#define disable_y() ;
#endif
#if HAS(Z_ENABLE)
#if ENABLED(Z_DUAL_STEPPER_DRIVERS)
#define enable_z() { Z_ENABLE_WRITE( Z_ENABLE_ON); Z2_ENABLE_WRITE(Z_ENABLE_ON); }
#define disable_z() { Z_ENABLE_WRITE(!Z_ENABLE_ON); Z2_ENABLE_WRITE(!Z_ENABLE_ON); axis_known_position[Z_AXIS] = false; }
#else
#define enable_z() Z_ENABLE_WRITE( Z_ENABLE_ON)
#define disable_z() { Z_ENABLE_WRITE(!Z_ENABLE_ON); axis_known_position[Z_AXIS] = false; }
#endif
#else
#define enable_z() ;
#define disable_z() ;
#endif
#if HAS(E0_ENABLE)
#define enable_e0() E0_ENABLE_WRITE( E_ENABLE_ON)
#define disable_e0() E0_ENABLE_WRITE(!E_ENABLE_ON)
#else
#define enable_e0() /* nothing */
#define disable_e0() /* nothing */
#endif
#if (DRIVER_EXTRUDERS > 1) && HAS(E1_ENABLE)
#define enable_e1() E1_ENABLE_WRITE( E_ENABLE_ON)
#define disable_e1() E1_ENABLE_WRITE(!E_ENABLE_ON)
#else
#define enable_e1() /* nothing */
#define disable_e1() /* nothing */
#endif
#if (DRIVER_EXTRUDERS > 2) && HAS(E2_ENABLE)
#define enable_e2() E2_ENABLE_WRITE( E_ENABLE_ON)
#define disable_e2() E2_ENABLE_WRITE(!E_ENABLE_ON)
#else
#define enable_e2() /* nothing */
#define disable_e2() /* nothing */
#endif
#if (DRIVER_EXTRUDERS > 3) && HAS(E3_ENABLE)
#define enable_e3() E3_ENABLE_WRITE( E_ENABLE_ON)
#define disable_e3() E3_ENABLE_WRITE(!E_ENABLE_ON)
#else
#define enable_e3() /* nothing */
#define disable_e3() /* nothing */
#endif
#define disable_e() {disable_e0(); disable_e1(); disable_e2(); disable_e3();}
////////////////////////////////// //////////////////////////////////
// Pin redefines for TMC drivers. // Pin redefines for TMC drivers.
// TMC26X drivers have step and dir on normal pins, but everything else via SPI // TMC26X drivers have step and dir on normal pins, but everything else via SPI
......
...@@ -20,6 +20,9 @@ ...@@ -20,6 +20,9 @@
#include "elements.h" #include "elements.h"
#include "Marlin_main.h" #include "Marlin_main.h"
#if ENABLED(AUTO_BED_LEVELING_FEATURE)
#include "vector_3.h"
#endif
#include "ultralcd.h" #include "ultralcd.h"
#include "planner.h" #include "planner.h"
#include "stepper_indirection.h" #include "stepper_indirection.h"
...@@ -867,7 +870,7 @@ static void updateTemperaturesFromRawValues() { ...@@ -867,7 +870,7 @@ static void updateTemperaturesFromRawValues() {
} }
#if HAS(FILAMENT_SENSOR) #if ENABLED(FILAMENT_SENSOR)
// Convert raw Filament Width to millimeters // Convert raw Filament Width to millimeters
float analog2widthFil() { float analog2widthFil() {
......
...@@ -25,7 +25,7 @@ ...@@ -25,7 +25,7 @@
void tp_init(); //initialize the heating void tp_init(); //initialize the heating
void manage_heater(); //it is critical that this is called periodically. void manage_heater(); //it is critical that this is called periodically.
#if HAS(FILAMENT_SENSOR) #if ENABLED(FILAMENT_SENSOR)
// For converting raw Filament Width to milimeters // For converting raw Filament Width to milimeters
float analog2widthFil(); float analog2widthFil();
......
...@@ -2391,6 +2391,7 @@ char *ftostr52(const float &x) { ...@@ -2391,6 +2391,7 @@ char *ftostr52(const float &x) {
#include "stepper_indirection.h" #include "stepper_indirection.h"
#include "stepper.h" #include "stepper.h"
#include "configuration_store.h" #include "configuration_store.h"
#include "ultralcd.h"
#include "Nextion.h" #include "Nextion.h"
bool NextionON = false; bool NextionON = false;
......
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