Преглед на файлове

Merge pull request #3365 from leptun/MK3_3.12_Optimizations

memory and flash optimizations for 3.12 PR2
Alex Voinea преди 2 години
родител
ревизия
e1ebc82654

+ 2 - 2
Firmware/ConfigurationStore.cpp

@@ -32,7 +32,7 @@ static bool EEPROM_writeData(uint8_t* pos, uint8_t* value, uint8_t size, const c
 #endif //DEBUG_EEPROM_WRITE
 {
 #ifdef DEBUG_EEPROM_WRITE
-	printf_P(PSTR("EEPROM_WRITE_VAR addr=0x%04x size=0x%02hhx name=%s\n"), pos, size, name);
+	printf_P(PSTR("EEPROM_WRITE_VAR addr=0x%04x size=0x%02x name=%s\n"), pos, size, name);
 #endif //DEBUG_EEPROM_WRITE
 	while (size--)
 	{
@@ -56,7 +56,7 @@ static void EEPROM_readData(uint8_t* pos, uint8_t* value, uint8_t size, const ch
 #endif //DEBUG_EEPROM_READ
 {
 #ifdef DEBUG_EEPROM_READ
-	printf_P(PSTR("EEPROM_READ_VAR addr=0x%04x size=0x%02hhx name=%s\n"), pos, size, name);
+	printf_P(PSTR("EEPROM_READ_VAR addr=0x%04x size=0x%02x name=%s\n"), pos, size, name);
 #endif //DEBUG_EEPROM_READ
     while(size--)
     {

+ 4 - 1
Firmware/Configuration_adv.h

@@ -13,7 +13,7 @@
 #ifdef PIDTEMP
   // this adds an experimental additional term to the heating power, proportional to the extrusion speed.
   // if Kc is chosen well, the additional required power due to increased melting should be compensated.
-  #define PID_ADD_EXTRUSION_RATE
+  // #define PID_ADD_EXTRUSION_RATE
   #ifdef PID_ADD_EXTRUSION_RATE
     #define  DEFAULT_Kc (1) //heating power=Kc*(e_speed)
   #endif
@@ -250,6 +250,9 @@
 	  #define HAS_FOLDER_SORTING (FOLDER_SORTING)
 	#endif
 
+// Enabe this option to get a pretty message whenever the endstop gets hit (as in the position at which the endstop got triggered)
+//#define VERBOSE_CHECK_HIT_ENDSTOPS
+
 // Enable the option to stop SD printing when hitting and endstops, needs to be enabled from the LCD menu when this option is enabled.
 //#define ABORT_ON_ENDSTOP_HIT_FEATURE_ENABLED
 

+ 1 - 1
Firmware/Dcodes.cpp

@@ -990,7 +990,7 @@ void __attribute__((noinline)) serial_dump_and_reset(dump_crash_reason reason)
 
     // sample SP/PC
     sp = SP;
-    GETPC(&pc);
+    pc = GETPC();
 
     // extend WDT long enough to allow writing the entire stream
     wdt_enable(WDTO_8S);

+ 16 - 11
Firmware/Marlin.h

@@ -277,6 +277,17 @@ FORCE_INLINE unsigned long millis_nc() {
 void setPwmFrequency(uint8_t pin, int val);
 #endif
 
+enum class HeatingStatus : uint8_t
+{
+    NO_HEATING = 0,
+    EXTRUDER_HEATING = 1,
+    EXTRUDER_HEATING_COMPLETE = 2,
+    BED_HEATING = 3,
+    BED_HEATING_COMPLETE = 4,
+};
+
+extern HeatingStatus heating_status;
+
 extern bool fans_check_enabled;
 extern float homing_feedrate[];
 extern uint8_t axis_relative_modes;
@@ -296,9 +307,9 @@ extern int8_t lcd_change_fil_state;
 extern float default_retraction;
 
 #ifdef TMC2130
-void homeaxis(int axis, uint8_t cnt = 1, uint8_t* pstep = 0);
+void homeaxis(uint8_t axis, uint8_t cnt = 1, uint8_t* pstep = 0);
 #else
-void homeaxis(int axis, uint8_t cnt = 1);
+void homeaxis(uint8_t axis, uint8_t cnt = 1);
 #endif //TMC2130
 
 
@@ -321,18 +332,13 @@ extern int bowden_length[4];
 extern bool is_usb_printing;
 extern bool homing_flag;
 extern bool loading_flag;
-extern unsigned int usb_printing_counter;
-
-extern unsigned long kicktime;
-
+extern uint8_t usb_printing_counter;
 extern unsigned long total_filament_used;
 void save_statistics(unsigned long _total_filament_used, unsigned long _total_print_time);
-extern unsigned int heating_status;
-extern unsigned int status_number;
-extern unsigned int heating_status_counter;
+extern uint8_t status_number;
+extern uint8_t heating_status_counter;
 extern char snmm_filaments_used;
 extern unsigned long PingTime;
-extern unsigned long NcTime;
 extern bool no_response;
 extern uint8_t important_status;
 extern uint8_t saved_filament_type;
@@ -350,7 +356,6 @@ extern unsigned long start_pause_print;
 extern unsigned long t_fan_rising_edge;
 
 extern bool mesh_bed_leveling_flag;
-extern bool mesh_bed_run_from_menu;
 
 // save/restore printing
 extern bool saved_printing;

+ 130 - 143
Firmware/Marlin_main.cpp

@@ -161,7 +161,6 @@ CardReader card;
 #endif
 
 unsigned long PingTime = _millis();
-unsigned long NcTime;
 
 uint8_t mbl_z_probe_nr = 3; //numer of Z measurements for each point in mesh bed leveling calibration
 
@@ -196,9 +195,7 @@ int bowden_length[4] = {385, 385, 385, 385};
 bool is_usb_printing = false;
 bool homing_flag = false;
 
-unsigned long kicktime = _millis()+100000;
-
-unsigned int  usb_printing_counter;
+uint8_t usb_printing_counter;
 
 int8_t lcd_change_fil_state = 0;
 
@@ -206,20 +203,21 @@ unsigned long pause_time = 0;
 unsigned long start_pause_print = _millis();
 unsigned long t_fan_rising_edge = _millis();
 LongTimer safetyTimer;
-static LongTimer crashDetTimer;
+static ShortTimer crashDetTimer;
 
 //unsigned long load_filament_time;
 
 bool mesh_bed_leveling_flag = false;
-bool mesh_bed_run_from_menu = false;
 
+#ifdef PRUSA_M28
 bool prusa_sd_card_upload = false;
+#endif
 
-unsigned int status_number = 0;
+uint8_t status_number = 0;
 
 unsigned long total_filament_used;
-unsigned int heating_status;
-unsigned int heating_status_counter;
+HeatingStatus heating_status;
+uint8_t heating_status_counter;
 bool loading_flag = false;
 
 #define XY_NO_RESTORE_FLAG (mesh_bed_leveling_flag || homing_flag)
@@ -349,20 +347,20 @@ static float next_feedrate;
 // Original feedrate saved during homing moves
 static float saved_feedrate;
 
-const int sensitive_pins[] = SENSITIVE_PINS; // Sensitive pin list for M42
+const int8_t sensitive_pins[] PROGMEM = SENSITIVE_PINS; // Sensitive pin list for M42
 
 //static float tt = 0;
 //static float bt = 0;
 
 //Inactivity shutdown variables
-static unsigned long previous_millis_cmd = 0;
+static LongTimer previous_millis_cmd;
 unsigned long max_inactive_time = 0;
 static unsigned long stepper_inactive_time = DEFAULT_STEPPER_DEACTIVE_TIME*1000l;
 static unsigned long safetytimer_inactive_time = DEFAULT_SAFETYTIMER_TIME_MINS*60*1000ul;
 
 unsigned long starttime=0;
 unsigned long stoptime=0;
-unsigned long _usb_timer = 0;
+ShortTimer _usb_timer;
 
 bool Stopped=false;
 
@@ -1518,7 +1516,7 @@ void setup()
 	xflash_rd_uid(uid);
 	puts_P(_n("XFLASH UID="));
 	for (uint8_t i = 0; i < 8; i ++)
-		printf_P(PSTR("%02hhx"), uid[i]);
+		printf_P(PSTR("%02x"), uid[i]);
 	putchar('\n');
 	list_sec_lang_from_external_flash();
 #endif //DEBUG_XFLASH
@@ -1677,7 +1675,7 @@ void setup()
 		  eeprom_update_byte((uint8_t*)EEPROM_UVLO, 0);
 		  lcd_update_enable(true);
 		  lcd_update(2);
-		  lcd_setstatuspgm(_T(WELCOME_MSG));
+		  lcd_setstatuspgm(MSG_WELCOME);
 	  }
 */
       manage_heater(); // Update temperatures 
@@ -1699,7 +1697,7 @@ void setup()
               eeprom_update_byte((uint8_t*)EEPROM_UVLO, 0); 
               lcd_update_enable(true); 
               lcd_update(2); 
-              lcd_setstatuspgm(_T(WELCOME_MSG)); 
+              lcd_setstatuspgm(MSG_WELCOME); 
           } 
       }
   }
@@ -1720,7 +1718,6 @@ void setup()
 #endif //WATCHDOG
 }
 
-
 static inline void crash_and_burn(dump_crash_reason reason)
 {
     WRITE(BEEPER, HIGH);
@@ -1752,13 +1749,12 @@ void stack_error() {
     crash_and_burn(dump_crash_reason::stack_error);
 }
 
-
+#ifdef PRUSA_M28
 void trace();
 
 #define CHUNK_SIZE 64 // bytes
 #define SAFETY_MARGIN 1
 char chunk[CHUNK_SIZE+SAFETY_MARGIN];
-int chunkHead = 0;
 
 void serial_read_stream() {
 
@@ -1824,6 +1820,7 @@ void serial_read_stream() {
         }
     }
 }
+#endif //PRUSA_M28
 
 
 /**
@@ -1892,11 +1889,11 @@ void loop()
 {
 	KEEPALIVE_STATE(NOT_BUSY);
 
-	if ((usb_printing_counter > 0) && ((_millis()-_usb_timer) > 1000))
+	if ((usb_printing_counter > 0) && _usb_timer.expired(1000))
 	{
 		is_usb_printing = true;
 		usb_printing_counter--;
-		_usb_timer = _millis();
+		_usb_timer.start(); // reset timer
 	}
 	if (usb_printing_counter == 0)
 	{
@@ -1914,12 +1911,14 @@ void loop()
     }
 #endif
 
+#ifdef PRUSA_M28
     if (prusa_sd_card_upload)
     {
         //we read byte-by byte
         serial_read_stream();
     } 
-    else 
+    else
+#endif
     {
 
         get_command();
@@ -2033,9 +2032,9 @@ DEFINE_PGM_READ_ANY(signed char, byte);
 #define XYZ_CONSTS_FROM_CONFIG(type, array, CONFIG) \
 static const PROGMEM type array##_P[3] =        \
     { X_##CONFIG, Y_##CONFIG, Z_##CONFIG };     \
-static inline type array(int axis)              \
+static inline type array(uint8_t axis)              \
     { return pgm_read_any(&array##_P[axis]); }  \
-type array##_ext(int axis)                      \
+type array##_ext(uint8_t axis)                      \
     { return pgm_read_any(&array##_P[axis]); }
 
 XYZ_CONSTS_FROM_CONFIG(float, base_min_pos,    MIN_POS);
@@ -2045,7 +2044,7 @@ XYZ_CONSTS_FROM_CONFIG(float, max_length,      MAX_LENGTH);
 XYZ_CONSTS_FROM_CONFIG(float, home_retract_mm, HOME_RETRACT_MM);
 XYZ_CONSTS_FROM_CONFIG(signed char, home_dir,  HOME_DIR);
 
-static void axis_is_at_home(int axis) {
+static void axis_is_at_home(uint8_t axis) {
   current_position[axis] = base_home_pos(axis) + cs.add_homing[axis];
   min_pos[axis] =          base_min_pos(axis) + cs.add_homing[axis];
   max_pos[axis] =          base_max_pos(axis) + cs.add_homing[axis];
@@ -2056,7 +2055,7 @@ static int setup_for_endstop_move(bool enable_endstops_now = true) {
     saved_feedrate = feedrate;
     int l_feedmultiply = feedmultiply;
     feedmultiply = 100;
-    previous_millis_cmd = _millis();
+    previous_millis_cmd.start();
     
     enable_endstops(enable_endstops_now);
     return l_feedmultiply;
@@ -2070,7 +2069,7 @@ static void clean_up_after_endstop_move(int original_feedmultiply) {
     
     feedrate = saved_feedrate;
     feedmultiply = original_feedmultiply;
-    previous_millis_cmd = _millis();
+    previous_millis_cmd.start();
 }
 
 
@@ -2361,9 +2360,9 @@ static void check_Z_crash(void)
 #endif //TMC2130
 
 #ifdef TMC2130
-void homeaxis(int axis, uint8_t cnt, uint8_t* pstep)
+void homeaxis(uint8_t axis, uint8_t cnt, uint8_t* pstep)
 #else
-void homeaxis(int axis, uint8_t cnt)
+void homeaxis(uint8_t axis, uint8_t cnt)
 #endif //TMC2130
 {
 	bool endstops_enabled  = enable_endstops(true); //RP: endstops should be allways enabled durring homing
@@ -2514,7 +2513,7 @@ void home_xy()
 
 void refresh_cmd_timeout(void)
 {
-  previous_millis_cmd = _millis();
+  previous_millis_cmd.start();
 }
 
 #ifdef FWRETRACT
@@ -2558,9 +2557,12 @@ void retract(bool retracting, bool swapretract = false) {
 } //retract
 #endif //FWRETRACT
 
+#ifdef PRUSA_M28
 void trace() {
     Sound_MakeCustom(25,440,true);
 }
+#endif
+
 /*
 void ramming() {
 //	  float tmp[4] = DEFAULT_MAX_FEEDRATE;
@@ -2813,14 +2815,9 @@ static void gcode_G28(bool home_x_axis, long home_x_value, bool home_y_axis, lon
       if (home_z)
         babystep_undo();
 
-      saved_feedrate = feedrate;
-      int l_feedmultiply = feedmultiply;
-      feedmultiply = 100;
-      previous_millis_cmd = _millis();
-
-      enable_endstops(true);
+      int l_feedmultiply = setup_for_endstop_move();
 
-      memcpy(destination, current_position, sizeof(destination));
+      set_destination_to_current();
       feedrate = 0.0;
 
       #if Z_HOME_DIR > 0                      // If homing away from BED do Z first
@@ -2834,7 +2831,7 @@ static void gcode_G28(bool home_x_axis, long home_x_value, bool home_y_axis, lon
       {
         current_position[X_AXIS] = 0;current_position[Y_AXIS] = 0;
 
-        int x_axis_home_dir = home_dir(X_AXIS);
+        uint8_t x_axis_home_dir = home_dir(X_AXIS);
 
         plan_set_position_curposXYZE();
         destination[X_AXIS] = 1.5 * max_length(X_AXIS) * x_axis_home_dir;destination[Y_AXIS] = 1.5 * max_length(Y_AXIS) * home_dir(Y_AXIS);
@@ -2993,13 +2990,7 @@ static void gcode_G28(bool home_x_axis, long home_x_value, bool home_y_axis, lon
       // contains the machine coordinates.
       plan_set_position_curposXYZE();
 
-      #ifdef ENDSTOPS_ONLY_FOR_HOMING
-        enable_endstops(false);
-      #endif
-
-      feedrate = saved_feedrate;
-      feedmultiply = l_feedmultiply;
-      previous_millis_cmd = _millis();
+      clean_up_after_endstop_move(l_feedmultiply);
       endstops_hit_on_purpose();
 #ifndef MESH_BED_LEVELING
 //-// Oct 2019 :: this part of code is (from) now probably un-compilable
@@ -3114,7 +3105,7 @@ static void gcode_G80()
 #endif //PINDA_THERMISTOR
     // Save custom message state, set a new custom message state to display: Calibrating point 9.
     CustomMsg custom_message_type_old = custom_message_type;
-    unsigned int custom_message_state_old = custom_message_state;
+    uint8_t custom_message_state_old = custom_message_state;
     custom_message_type = CustomMsg::MeshBedLeveling;
     custom_message_state = (nMeasPoints * nMeasPoints) + 10;
     lcd_update(1);
@@ -3452,10 +3443,9 @@ static void gcode_G80()
     }
     KEEPALIVE_STATE(NOT_BUSY);
     // Restore custom message state
-    lcd_setstatuspgm(_T(WELCOME_MSG));
+    lcd_setstatuspgm(MSG_WELCOME);
     custom_message_type = custom_message_type_old;
     custom_message_state = custom_message_state_old;
-    mesh_bed_run_from_menu = false;
     lcd_update(2);
 
     st_synchronize();
@@ -3843,7 +3833,7 @@ static void gcode_M600(bool automatic, float x_position, float y_position, float
     plan_set_e_position(lastpos[E_AXIS]);
 
     memcpy(current_position, lastpos, sizeof(lastpos));
-    memcpy(destination, current_position, sizeof(current_position));
+    set_destination_to_current();
 
     //Recover feed rate
     feedmultiply = feedmultiplyBckp;
@@ -3856,7 +3846,7 @@ static void gcode_M600(bool automatic, float x_position, float y_position, float
 	fsensor_check_autoload();
 #endif //IR_SENSOR
 
-    lcd_setstatuspgm(_T(WELCOME_MSG));
+    lcd_setstatuspgm(MSG_WELCOME);
     custom_message_type = CustomMsg::Status;
 }
 
@@ -3902,7 +3892,7 @@ void gcode_M701()
 		}
 		lcd_update_enable(true);
 		lcd_update(2);
-		lcd_setstatuspgm(_T(WELCOME_MSG));
+		lcd_setstatuspgm(MSG_WELCOME);
 		disable_z();
 		loading_flag = false;
 		custom_message_type = CustomMsg::Status;
@@ -4327,11 +4317,11 @@ void process_commands()
         codenum = 0;
         bool hasP = false, hasS = false;
         if (code_seen('P')) {
-            codenum = code_value(); // milliseconds to wait
+            codenum = code_value_long(); // milliseconds to wait
             hasP = codenum > 0;
         }
         if (code_seen('S')) {
-            codenum = code_value() * 1000; // seconds to wait
+            codenum = code_value_long() * 1000; // seconds to wait
             hasS = codenum > 0;
         }
         starpos = strchr(src, '*');
@@ -4352,7 +4342,7 @@ void process_commands()
         }
         lcd_ignore_click();				//call lcd_ignore_click also for else ???
         st_synchronize();
-        previous_millis_cmd = _millis();
+        previous_millis_cmd.start();
         if (codenum > 0 ) {
             codenum += _millis();  // keep track of when we started waiting
             KEEPALIVE_STATE(PAUSED_FOR_USER);
@@ -4369,7 +4359,7 @@ void process_commands()
         if (IS_SD_PRINTING)
             custom_message_type = CustomMsg::Status;
         else
-            LCD_MESSAGERPGM(_T(WELCOME_MSG));
+            LCD_MESSAGERPGM(MSG_WELCOME);
     }
 
 #ifdef TMC2130
@@ -4458,7 +4448,7 @@ void process_commands()
 				tmc2130_chopper_config[axis].hend = chop2 & 15;
 				tmc2130_chopper_config[axis].tbl = chop3 & 3;
 				tmc2130_setup_chopper(axis, tmc2130_mres[axis], tmc2130_current_h[axis], tmc2130_current_r[axis]);
-				//printf_P(_N("TMC_SET_CHOP_%c %hhd %hhd %hhd %hhd\n"), "xyze"[axis], chop0, chop1, chop2, chop3);
+				//printf_P(_N("TMC_SET_CHOP_%c %d %d %d %d\n"), "xyze"[axis], chop0, chop1, chop2, chop3);
 			}
 		}
 	}
@@ -4467,7 +4457,7 @@ void process_commands()
 	{
 		uint8_t bl = (uint8_t)strtol(CMDBUFFER_CURRENT_STRING + 10, NULL, 10);
 		st_backlash_x = bl;
-		printf_P(_N("st_backlash_x = %hhd\n"), st_backlash_x);
+		printf_P(_N("st_backlash_x = %d\n"), st_backlash_x);
 	}
 #endif //BACKLASH_X
 #ifdef BACKLASH_Y
@@ -4475,7 +4465,7 @@ void process_commands()
 	{
 		uint8_t bl = (uint8_t)strtol(CMDBUFFER_CURRENT_STRING + 10, NULL, 10);
 		st_backlash_y = bl;
-		printf_P(_N("st_backlash_y = %hhd\n"), st_backlash_y);
+		printf_P(_N("st_backlash_y = %d\n"), st_backlash_y);
 	}
 #endif //BACKLASH_Y
 #endif //TMC2130
@@ -4486,7 +4476,7 @@ void process_commands()
     
     Set of internal PRUSA commands
     #### Usage
-         PRUSA [ Ping | PRN | FAN | fn | thx | uvlo | MMURES | RESET | fv | M28 | SN | Fir | Rev | Lang | Lz | Beat | FR ]
+         PRUSA [ Ping | PRN | FAN | fn | thx | uvlo | MMURES | RESET | fv | M28 | SN | Fir | Rev | Lang | Lz | FR ]
     
     #### Parameters
       - `Ping` 
@@ -4504,7 +4494,6 @@ void process_commands()
       - `Rev`- Prints filament size, elelectronics, nozzle type
       - `Lang` - Reset the language
       - `Lz` 
-      - `Beat` - Kick farm link timer
       - `FR` - Full factory reset
       - `nozzle set <diameter>` - set nozzle diameter (farm mode only), e.g. `PRUSA nozzle set 0.4`
       - `nozzle D<diameter>` - check the nozzle diameter (farm mode only), works like M862.1 P, e.g. `PRUSA nozzle D0.4`
@@ -4518,7 +4507,7 @@ void process_commands()
 			}	  
 		}
 		else if (code_seen_P(PSTR("PRN"))) { // PRUSA PRN
-		  printf_P(_N("%d"), status_number);
+		  printf_P(_N("%u"), status_number);
 
         } else if( code_seen_P(PSTR("FANPINTST"))){
             gcode_PRUSA_BadRAMBoFanTest();
@@ -4563,12 +4552,16 @@ void process_commands()
 
         #endif // SDSUPPORT
 
-    } else if (code_seen_P(PSTR("M28"))) { // PRUSA M28
+    }
+#ifdef PRUSA_M28
+	else if (code_seen_P(PSTR("M28"))) { // PRUSA M28
         trace();
         prusa_sd_card_upload = true;
         card.openFileWrite(strchr_pointer+4);
 
-	} else if (code_seen_P(PSTR("SN"))) { // PRUSA SN
+	}
+#endif //PRUSA_M28
+	else if (code_seen_P(PSTR("SN"))) { // PRUSA SN
         char SN[20];
         eeprom_read_block(SN, (uint8_t*)EEPROM_PRUSA_SN, 20);
         if (SN[19])
@@ -4590,10 +4583,6 @@ void process_commands()
 	} else if(code_seen_P(PSTR("Lz"))) { // PRUSA Lz
       eeprom_update_word(reinterpret_cast<uint16_t *>(&(EEPROM_Sheets_base->s[(eeprom_read_byte(&(EEPROM_Sheets_base->active_sheet)))].z_offset)),0);
 
-	} else if(code_seen_P(PSTR("Beat"))) { // PRUSA Beat
-        // Kick farm link timer
-        kicktime = _millis();
-
     } else if(code_seen_P(PSTR("FR"))) { // PRUSA FR
         // Factory full reset
         factory_reset(0);
@@ -4688,7 +4677,7 @@ eeprom_update_word((uint16_t*)EEPROM_NOZZLE_DIAMETER_uM,0xFFFF);
   // }
   else if(code_seen('G'))
   {
-	gcode_in_progress = (int)code_value();
+	gcode_in_progress = code_value_short();
 //	printf_P(_N("BEGIN G-CODE=%u\n"), gcode_in_progress);
     switch (gcode_in_progress)
     {
@@ -4976,7 +4965,7 @@ if(eSoundMode!=e_SOUND_MODE_SILENT)
 	  if(codenum != 0) LCD_MESSAGERPGM(_n("Sleep..."));////MSG_DWELL
       st_synchronize();
       codenum += _millis();  // keep track of when we started waiting
-      previous_millis_cmd = _millis();
+      previous_millis_cmd.start();
       while(_millis() < codenum) {
         manage_heater();
         manage_inactivity();
@@ -5293,7 +5282,7 @@ if(eSoundMode!=e_SOUND_MODE_SILENT)
   */
 	case 75:
 	{
-		for (int i = 40; i <= 110; i++)
+		for (uint8_t i = 40; i <= 110; i++)
 			printf_P(_N("%d  %.2f"), i, temp_comp_interpolation(i));
 	}
 	break;
@@ -5633,8 +5622,8 @@ if(eSoundMode!=e_SOUND_MODE_SILENT)
                 SERIAL_PROTOCOLPGM("\nZ search height: ");
                 SERIAL_PROTOCOL(MESH_HOME_Z_SEARCH);
                 SERIAL_PROTOCOLLNPGM("\nMeasured points:");
-                for (int y = MESH_NUM_Y_POINTS-1; y >= 0; y--) {
-                    for (int x = 0; x < MESH_NUM_X_POINTS; x++) {
+                for (uint8_t y = MESH_NUM_Y_POINTS; y-- > 0;) {
+                    for (uint8_t x = 0; x < MESH_NUM_X_POINTS; x++) {
                         SERIAL_PROTOCOLPGM("  ");
                         SERIAL_PROTOCOL_F(mbl.z_values[y][x], 5);
                     }
@@ -5836,7 +5825,7 @@ if(eSoundMode!=e_SOUND_MODE_SILENT)
 
 	  } else
 	  {
-	  mcode_in_progress = (int)code_value();
+	  mcode_in_progress = code_value_short();
 //	printf_P(_N("BEGIN M-CODE=%u\n"), mcode_in_progress);
 
     switch(mcode_in_progress)
@@ -6102,13 +6091,13 @@ if(eSoundMode!=e_SOUND_MODE_SILENT)
     case 42:
       if (code_seen('S'))
       {
-        int pin_status = code_value();
-        int pin_number = LED_PIN;
-        if (code_seen('P') && pin_status >= 0 && pin_status <= 255)
-          pin_number = code_value();
-        for(int8_t i = 0; i < (int8_t)(sizeof(sensitive_pins)/sizeof(int)); i++)
+        uint8_t pin_status = code_value_uint8();
+        int8_t pin_number = LED_PIN;
+        if (code_seen('P'))
+          pin_number = code_value_uint8();
+        for(int8_t i = 0; i < (int8_t)(sizeof(sensitive_pins)/sizeof(sensitive_pins[0])); i++)
         {
-          if (sensitive_pins[i] == pin_number)
+          if ((int8_t)pgm_read_byte(&sensitive_pins[i]) == pin_number)
           {
             pin_number = -1;
             break;
@@ -6520,9 +6509,9 @@ Sigma_Exit:
     */
     case 73: //M73 show percent done, time remaining and time to change/pause
     {
-        if(code_seen('P')) print_percent_done_normal = code_value();
+        if(code_seen('P')) print_percent_done_normal = code_value_uint8();
         if(code_seen('R')) print_time_remaining_normal = code_value();
-        if(code_seen('Q')) print_percent_done_silent = code_value();
+        if(code_seen('Q')) print_percent_done_silent = code_value_uint8();
         if(code_seen('S')) print_time_remaining_silent = code_value();
         if(code_seen('C')){
             float print_time_to_change_normal_f = code_value_float();
@@ -6642,7 +6631,7 @@ Sigma_Exit:
             autoReportFeatures.SetPeriod( code_value_uint8() );
         }
         if (code_seen('C')){
-            autoReportFeatures.SetMask(code_value());
+            autoReportFeatures.SetMask(code_value_uint8());
         } else{
             autoReportFeatures.SetMask(1); //Backwards compability to host systems like Octoprint to send only temp if paramerter `C`isn't used.
         }
@@ -6673,7 +6662,7 @@ Sigma_Exit:
         break;
       }
       LCD_MESSAGERPGM(_T(MSG_HEATING));
-	  heating_status = 1;
+	  heating_status = HeatingStatus::EXTRUDER_HEATING;
 	  if (farm_mode) { prusa_statistics(1); };
 
 #ifdef AUTOTEMP
@@ -6707,11 +6696,11 @@ Sigma_Exit:
 
         LCD_MESSAGERPGM(_T(MSG_HEATING_COMPLETE));
 		KEEPALIVE_STATE(IN_HANDLER);
-		heating_status = 2;
+		heating_status = HeatingStatus::EXTRUDER_HEATING_COMPLETE;
 		if (farm_mode) { prusa_statistics(2); };
         
         //starttime=_millis();
-        previous_millis_cmd = _millis();
+        previous_millis_cmd.start();
       }
       break;
 
@@ -6733,7 +6722,7 @@ Sigma_Exit:
     {
         bool CooldownNoWait = false;
         LCD_MESSAGERPGM(_T(MSG_BED_HEATING));
-		heating_status = 3;
+		heating_status = HeatingStatus::BED_HEATING;
 		if (farm_mode) { prusa_statistics(1); };
         if (code_seen('S')) 
 		{
@@ -6773,9 +6762,9 @@ Sigma_Exit:
         }
         LCD_MESSAGERPGM(_T(MSG_BED_DONE));
 		KEEPALIVE_STATE(IN_HANDLER);
-		heating_status = 4;
+		heating_status = HeatingStatus::BED_HEATING_COMPLETE;
 
-        previous_millis_cmd = _millis();
+        previous_millis_cmd.start();
     }
     #endif
         break;
@@ -6793,10 +6782,10 @@ Sigma_Exit:
       */
       case 106: // M106 Sxxx Fan On S<speed> 0 .. 255
         if (code_seen('S')){
-           fanSpeed=constrain(code_value(),0,255);
+           fanSpeed = code_value_uint8();
         }
         else {
-          fanSpeed=255;
+          fanSpeed = 255;
         }
         break;
 
@@ -6827,7 +6816,7 @@ Sigma_Exit:
         #endif
 
           powersupply = true;
-          LCD_MESSAGERPGM(_T(WELCOME_MSG));
+          LCD_MESSAGERPGM(MSG_WELCOME);
           lcd_update(0);
         break;
 
@@ -7026,7 +7015,7 @@ Sigma_Exit:
     */
 	case 113:
 		if (code_seen('S')) {
-			host_keepalive_interval = (uint8_t)code_value_short();
+			host_keepalive_interval = code_value_uint8();
 //			NOMORE(host_keepalive_interval, 60);
 		}
 		else {
@@ -7252,7 +7241,7 @@ Sigma_Exit:
 
         uint8_t extruder = active_extruder;
         if(code_seen('T')) {
-          extruder = code_value();
+          extruder = code_value_uint8();
 		  if(extruder >= EXTRUDERS) {
             SERIAL_ECHO_START;
             SERIAL_ECHO(_n("M200 Invalid extruder "));////MSG_M200_INVALID_EXTRUDER
@@ -7260,14 +7249,14 @@ Sigma_Exit:
           }
         }
         if(code_seen('D')) {
-		  float diameter = (float)code_value();
+		  float diameter = code_value();
 		  if (diameter == 0.0) {
 			// setting any extruder filament size disables volumetric on the assumption that
 			// slicers either generate in extruder values as cubic mm or as as filament feeds
 			// for all extruders
 		    cs.volumetric_enabled = false;
 		  } else {
-            cs.filament_size[extruder] = (float)code_value();
+            cs.filament_size[extruder] = code_value();
 			// make sure all extruders have some sane value for the filament size
 			cs.filament_size[0] = (cs.filament_size[0] == 0.0 ? DEFAULT_NOMINAL_FILAMENT_DIA : cs.filament_size[0]);
             #if EXTRUDERS > 1
@@ -7513,8 +7502,7 @@ Sigma_Exit:
     {
       if(code_seen('S'))
       {
-        int t= code_value() ;
-        switch(t)
+        switch(code_value_uint8())
         {
           case 0: 
           {
@@ -7611,7 +7599,7 @@ Sigma_Exit:
         }
         if (code_seen('S'))
         {
-            feedmultiply = code_value();
+            feedmultiply = code_value_short();
             codesWereSeen = true;
         }
         if (code_seen('R')) //restore previous feedmultiply
@@ -7640,7 +7628,7 @@ Sigma_Exit:
     {
         if (code_seen('S'))
         {
-            int tmp_code = code_value();
+            int tmp_code = code_value_short();
             if (code_seen('T'))
             {
                 uint8_t extruder;
@@ -7675,16 +7663,16 @@ Sigma_Exit:
 	case 226: // M226 P<pin number> S<pin state>- Wait until the specified pin reaches the state required
 	{
       if(code_seen('P')){
-        int pin_number = code_value(); // pin number
+        int pin_number = code_value_short(); // pin number
         int pin_state = -1; // required pin state - default is inverted
 
-        if(code_seen('S')) pin_state = code_value(); // required pin state
+        if(code_seen('S')) pin_state = code_value_short(); // required pin state
 
         if(pin_state >= -1 && pin_state <= 1){
 
-          for(int8_t i = 0; i < (int8_t)(sizeof(sensitive_pins)/sizeof(int)); i++)
+          for(int8_t i = 0; i < (int8_t)(sizeof(sensitive_pins)/sizeof(sensitive_pins[0])); i++)
           {
-            if (sensitive_pins[i] == pin_number)
+            if (((int8_t)pgm_read_byte(&sensitive_pins[i]) == pin_number))
             {
               pin_number = -1;
               break;
@@ -7789,8 +7777,8 @@ Sigma_Exit:
     */
     case 300: // M300
     {
-      int beepS = code_seen('S') ? code_value() : 110;
-      int beepP = code_seen('P') ? code_value() : 1000;
+      uint16_t beepS = code_seen('S') ? code_value() : 110;
+      uint16_t beepP = code_seen('P') ? code_value() : 1000;
       if (beepS > 0)
       {
         #if BEEPER > 0
@@ -7956,13 +7944,13 @@ Sigma_Exit:
     case 303:
     {
       float temp = 150.0;
-      int e=0;
-      int c=5;
-      if (code_seen('E')) e=code_value();
-        if (e<0)
-          temp=70;
-      if (code_seen('S')) temp=code_value();
-      if (code_seen('C')) c=code_value();
+      int e = 0;
+      int c = 5;
+      if (code_seen('E')) e = code_value_short();
+        if (e < 0)
+          temp = 70;
+      if (code_seen('S')) temp = code_value();
+      if (code_seen('C')) c = code_value_short();
       PID_autotune(temp, e, c);
     }
     break;
@@ -7999,8 +7987,8 @@ Sigma_Exit:
 		{
 			uint8_t extruder = 255;
 			uint8_t filament = FILAMENT_UNDEFINED;
-			if(code_seen('E')) extruder = code_value();
-			if(code_seen('F')) filament = code_value();
+			if(code_seen('E')) extruder = code_value_uint8();
+			if(code_seen('F')) filament = code_value_uint8();
 			mmu_set_filament_type(extruder, filament);
 		}
 	}
@@ -8300,7 +8288,7 @@ Sigma_Exit:
 		int set_target_pinda = 0;
 
 		if (code_seen('S')) {
-			set_target_pinda = code_value();
+			set_target_pinda = code_value_short();
 		}
 		else {
 			break;
@@ -8393,9 +8381,9 @@ Sigma_Exit:
 			SERIAL_PROTOCOLLN("zerorized");
 		}
 		else if (code_seen('S')) { // Sxxx Iyyy - Set compensation ustep value S for compensation table index I
-			int16_t usteps = code_value();
+			int16_t usteps = code_value_short();
 			if (code_seen('I')) {
-			    uint8_t index = code_value();
+			    uint8_t index = code_value_uint8();
 				if (index < 5) {
 					EEPROM_save_B(EEPROM_PROBE_TEMP_SHIFT + index * 2, &usteps);
 					SERIAL_PROTOCOLLN("OK");
@@ -8885,7 +8873,7 @@ Sigma_Exit:
 	case 701:
 	{
 		if (mmu_enabled && code_seen('E'))
-			tmp_extruder = code_value();
+			tmp_extruder = code_value_uint8();
 		gcode_M701();
 	}
 	break;
@@ -9052,8 +9040,8 @@ Sigma_Exit:
               disable_e1();
               disable_e2();
 
-              pinMode(E_MUX0_PIN, OUTPUT);
-              pinMode(E_MUX1_PIN, OUTPUT);
+              SET_OUTPUT(E_MUX0_PIN);
+              SET_OUTPUT(E_MUX1_PIN);
 
               _delay(100);
               SERIAL_ECHO_START;
@@ -9106,7 +9094,7 @@ Sigma_Exit:
 #if EXTRUDERS > 1
                   if (tmp_extruder != active_extruder) {
                       // Save current position to return to after applying extruder offset
-                      memcpy(destination, current_position, sizeof(destination));
+                      set_destination_to_current();
                       // Offset extruder (only by XY)
                       int i;
                       for (i = 0; i < 2; i++) {
@@ -9142,7 +9130,7 @@ Sigma_Exit:
   */
   else if (code_seen('D')) // D codes (debug)
   {
-    switch((int)code_value())
+    switch(code_value_short())
     {
 
     /*!
@@ -9559,7 +9547,7 @@ void FlushSerialRequestResend()
 // Execution of a command from a SD card will not be confirmed.
 void ClearToSend()
 {
-	previous_millis_cmd = _millis();
+	previous_millis_cmd.start();
 	if (buflen && ((CMDBUFFER_CURRENT_TYPE == CMDBUFFER_CURRENT_TYPE_USB) || (CMDBUFFER_CURRENT_TYPE == CMDBUFFER_CURRENT_TYPE_USB_WITH_LINENR)))
 		SERIAL_PROTOCOLLNRPGM(MSG_OK);
 }
@@ -9610,7 +9598,7 @@ void get_coordinates()
     if(code_seen(axis_codes[i]))
     {
       bool relative = axis_relative_modes & (1 << i);
-      destination[i] = (float)code_value();
+      destination[i] = code_value();
       if (i == E_AXIS) {
         float emult = extruder_multiplier[active_extruder];
         if (emult != 1.) {
@@ -9735,7 +9723,7 @@ void mesh_plan_buffer_line(const float &x, const float &y, const float &z, const
 void prepare_move()
 {
   clamp_to_software_endstops(destination);
-  previous_millis_cmd = _millis();
+  previous_millis_cmd.start();
 
   // Do not use feedmultiply for E or Z only moves
   if( (current_position[X_AXIS] == destination [X_AXIS]) && (current_position[Y_AXIS] == destination [Y_AXIS])) {
@@ -9761,10 +9749,9 @@ void prepare_arc_move(bool isclockwise) {
   // As far as the parser is concerned, the position is now == target. In reality the
   // motion control system might still be processing the action and the real tool position
   // in any intermediate location.
-  for(int8_t i=0; i < NUM_AXIS; i++) {
-    current_position[i] = destination[i];
-  }
-  previous_millis_cmd = _millis();
+  set_current_to_destination();
+
+  previous_millis_cmd.start();
 }
 
 #if defined(CONTROLLERFAN_PIN) && CONTROLLERFAN_PIN > -1
@@ -9988,11 +9975,11 @@ if(0)
         get_command();
     }
 
-  if( (_millis() - previous_millis_cmd) >  max_inactive_time )
+  if(previous_millis_cmd.expired(max_inactive_time))
     if(max_inactive_time)
       kill(_n("Inactivity Shutdown"), 4);
   if(stepper_inactive_time)  {
-    if( (_millis() - previous_millis_cmd) >  stepper_inactive_time )
+    if(previous_millis_cmd.expired(stepper_inactive_time))
     {
       if(blocks_queued() == false && ignore_stepper_queue == false) {
         disable_x();
@@ -10039,7 +10026,7 @@ if(0)
     controllerFan(); //Check if fan should be turned on to cool stepper drivers down
   #endif
   #ifdef EXTRUDER_RUNOUT_PREVENT
-    if( (_millis() - previous_millis_cmd) >  EXTRUDER_RUNOUT_SECONDS*1000 )
+    if(previous_millis_cmd.expired(EXTRUDER_RUNOUT_SECONDS*1000))
     if(degHotend(active_extruder)>EXTRUDER_RUNOUT_MINTEMP)
     {
      bool oldstatus=READ(E0_ENABLE_PIN);
@@ -10052,7 +10039,7 @@ if(0)
      current_position[E_AXIS]=oldepos;
      destination[E_AXIS]=oldedes;
      plan_set_e_position(oldepos);
-     previous_millis_cmd=_millis();
+     previous_millis_cmd.start();
      st_synchronize();
      WRITE(E0_ENABLE_PIN,oldstatus);
     }
@@ -10286,7 +10273,7 @@ bool setTargetedHotend(int code, uint8_t &extruder)
 {
   extruder = active_extruder;
   if(code_seen('T')) {
-      extruder = code_value();
+      extruder = code_value_uint8();
     if(extruder >= EXTRUDERS) {
       SERIAL_ECHO_START;
       switch(code){
@@ -11148,7 +11135,7 @@ void uvlo_()
     eeprom_update_dword((uint32_t*)(EEPROM_FILE_POSITION), sd_position);
 
     // Store the mesh bed leveling offsets. This is 2*7*7=98 bytes, which takes 98*3.4us=333us in worst case.
-    for (int8_t mesh_point = 0; mesh_point < MESH_NUM_X_POINTS * MESH_NUM_Y_POINTS; ++ mesh_point) {
+    for (uint8_t mesh_point = 0; mesh_point < MESH_NUM_X_POINTS * MESH_NUM_Y_POINTS; ++ mesh_point) {
       uint8_t ix = mesh_point % MESH_NUM_X_POINTS; // from 0 to MESH_NUM_X_POINTS - 1
       uint8_t iy = mesh_point / MESH_NUM_X_POINTS;
       // Scale the z value to 1u resolution.
@@ -11438,7 +11425,7 @@ bool recover_machine_state_after_power_panic()
   // 5) Set the physical positions from the logical positions using the world2machine transformation
   // This is only done to inizialize Z/E axes with physical locations, since X/Y are unknown.
   clamp_to_software_endstops(current_position);
-  memcpy(destination, current_position, sizeof(destination));
+  set_destination_to_current();
   plan_set_position_curposXYZE();
   SERIAL_ECHOPGM("recover_machine_state_after_power_panic, initial ");
   print_world_coordinates();
@@ -11494,8 +11481,8 @@ void restore_print_from_eeprom(bool mbl_was_active) {
 	depth = eeprom_read_byte((uint8_t*)EEPROM_DIR_DEPTH);
 	
 	MYSERIAL.println(int(depth));
-	for (int i = 0; i < depth; i++) {
-		for (int j = 0; j < 8; j++) {
+	for (uint8_t i = 0; i < depth; i++) {
+		for (uint8_t j = 0; j < 8; j++) {
 			dir_name[j] = eeprom_read_byte((uint8_t*)EEPROM_DIRS + j + 8 * i);
 		}
 		dir_name[8] = '\0';
@@ -11504,7 +11491,7 @@ void restore_print_from_eeprom(bool mbl_was_active) {
 		card.chdir(dir_name, false);
 	}
 
-	for (int i = 0; i < 8; i++) {
+	for (uint8_t i = 0; i < 8; i++) {
 		filename[i] = eeprom_read_byte((uint8_t*)EEPROM_FILENAME + i);
 	}
 	filename[8] = '\0';
@@ -11771,7 +11758,7 @@ void stop_and_save_print_to_ram(float z_move, float e_move)
 		plan_buffer_line(saved_pos[X_AXIS], saved_pos[Y_AXIS], saved_pos[Z_AXIS] + z_move, saved_pos[E_AXIS] + e_move, homing_feedrate[Z_AXIS], active_extruder);
     st_synchronize(); //wait moving
     memcpy(current_position, saved_pos, sizeof(saved_pos));
-    memcpy(destination, current_position, sizeof(destination));
+    set_destination_to_current();
 #endif
     waiting_inside_plan_buffer_line_print_aborted = true; //unroll the stack
   }
@@ -11803,9 +11790,9 @@ void restore_print_from_ram_and_continue(float e_move)
 	if (degTargetHotend(saved_active_extruder) != saved_extruder_temperature)
 	{
 		setTargetHotendSafe(saved_extruder_temperature, saved_active_extruder);
-		heating_status = 1;
+		heating_status = HeatingStatus::EXTRUDER_HEATING;
 		wait_for_heater(_millis(), saved_active_extruder);
-		heating_status = 2;
+		heating_status = HeatingStatus::EXTRUDER_HEATING_COMPLETE;
 	}
 	axis_relative_modes ^= (-saved_extruder_relative_mode ^ axis_relative_modes) & E_AXIS_MASK;
 	float e = saved_pos[E_AXIS] - e_move;
@@ -11839,7 +11826,7 @@ void restore_print_from_ram_and_continue(float e_move)
 	feedmultiply = saved_feedmultiply2;
 
 	memcpy(current_position, saved_pos, sizeof(saved_pos));
-	memcpy(destination, current_position, sizeof(destination));
+	set_destination_to_current();
 	if (saved_printing_type == PRINTING_TYPE_SD) { //was sd printing
 		card.setIndex(saved_sdpos);
 		sdpos_atomic = saved_sdpos;
@@ -11854,7 +11841,7 @@ void restore_print_from_ram_and_continue(float e_move)
 		//not sd printing nor usb printing
 	}
 
-	lcd_setstatuspgm(_T(WELCOME_MSG));
+	lcd_setstatuspgm(MSG_WELCOME);
     saved_printing_type = PRINTING_TYPE_NONE;
 	saved_printing = false;
     waiting_inside_plan_buffer_line_print_aborted = true; //unroll the stack

+ 9 - 10
Firmware/Sd2Card.cpp

@@ -205,14 +205,14 @@ uint32_t Sd2Card::cardSize() {
 }
 //------------------------------------------------------------------------------
 void Sd2Card::chipSelectHigh() {
-  digitalWrite(chipSelectPin_, HIGH);
+  WRITE(SDSS, 1);
 }
 //------------------------------------------------------------------------------
 void Sd2Card::chipSelectLow() {
 #ifndef SOFTWARE_SPI
   spiInit(spiRate_);
 #endif  // SOFTWARE_SPI
-  digitalWrite(chipSelectPin_, LOW);
+  WRITE(SDSS, 0);
 }
 //------------------------------------------------------------------------------
 /** Erase a range of blocks.
@@ -283,26 +283,25 @@ bool Sd2Card::eraseSingleBlockEnable() {
  * the value zero, false, is returned for failure.  The reason for failure
  * can be determined by calling errorCode() and errorData().
  */
-bool Sd2Card::init(uint8_t sckRateID, uint8_t chipSelectPin) {
+bool Sd2Card::init(uint8_t sckRateID) {
   errorCode_ = type_ = 0;
-  chipSelectPin_ = chipSelectPin;
   // 16-bit init start time allows over a minute
   uint16_t t0 = (uint16_t)_millis();
   uint32_t arg;
 
   // set pin modes
-  pinMode(chipSelectPin_, OUTPUT);
   chipSelectHigh();
-  pinMode(SPI_MISO_PIN, INPUT);
-  pinMode(SPI_MOSI_PIN, OUTPUT);
-  pinMode(SPI_SCK_PIN, OUTPUT);
+  SET_OUTPUT(SDSS);
+  SET_INPUT(MISO);
+  SET_OUTPUT(MOSI);
+  SET_OUTPUT(SCK);
 
 #ifndef SOFTWARE_SPI
   // SS must be in output mode even it is not chip select
-  pinMode(SS_PIN, OUTPUT);
+  SET_OUTPUT(SS);
   // set SS high - may be chip select for another SPI device
 #if SET_SPI_SS_HIGH
-  digitalWrite(SS_PIN, HIGH);
+  WRITE(SS, 1);
 #endif  // SET_SPI_SS_HIGH
   // set SCK rate for initialization commands
   spiRate_ = SPI_SD_INIT_RATE;

+ 5 - 23
Firmware/Sd2Card.h

@@ -28,7 +28,6 @@
  * \brief Sd2Card class for V2 SD/SDHC cards
  */
 #include "SdFatConfig.h"
-#include "Sd2PinMap.h"
 #include "SdInfo.h"
 //------------------------------------------------------------------------------
 // SPI speed is F_CPU/2^(1 + index), 0 <= index <= 6
@@ -133,22 +132,7 @@ uint8_t const SD_CARD_TYPE_SDHC = 3;
 //------------------------------------------------------------------------------
 // SPI pin definitions - do not edit here - change in SdFatConfig.h
 //
-#ifndef SOFTWARE_SPI
-// hardware pin defs
-/** The default chip select pin for the SD card is SS. */
-uint8_t const  SD_CHIP_SELECT_PIN = SS_PIN;
-// The following three pins must not be redefined for hardware SPI.
-/** SPI Master Out Slave In pin */
-uint8_t const  SPI_MOSI_PIN = MOSI_PIN;
-/** SPI Master In Slave Out pin */
-uint8_t const  SPI_MISO_PIN = MISO_PIN;
-/** SPI Clock pin */
-uint8_t const  SPI_SCK_PIN = SCK_PIN;
-
-#else  // SOFTWARE_SPI
-
-/** SPI chip select pin */
-uint8_t const SD_CHIP_SELECT_PIN = SOFT_SPI_CS_PIN;
+#ifdef SOFTWARE_SPI
 /** SPI Master Out Slave In pin */
 uint8_t const SPI_MOSI_PIN = SOFT_SPI_MOSI_PIN;
 /** SPI Master In Slave Out pin */
@@ -176,17 +160,16 @@ class Sd2Card {
   /**
    * \return error code for last error. See Sd2Card.h for a list of error codes.
    */
-  int errorCode() const {return errorCode_;}
+  uint8_t errorCode() const {return errorCode_;}
   /** \return error data for last error. */
-  int errorData() const {return status_;}
+  uint8_t errorData() const {return status_;}
   /**
    * Initialize an SD flash memory card with default clock rate and chip
-   * select pin.  See sd2Card::init(uint8_t sckRateID, uint8_t chipSelectPin).
+   * select pin.  See sd2Card::init(uint8_t sckRateID).
    *
    * \return true for success or false for failure.
    */
-  bool init(uint8_t sckRateID = SPI_FULL_SPEED,
-    uint8_t chipSelectPin = SD_CHIP_SELECT_PIN);
+  bool init(uint8_t sckRateID = SPI_FULL_SPEED);
   bool readBlock(uint32_t block, uint8_t* dst);
   /**
    * Read a card's CID register. The CID contains card identification
@@ -232,7 +215,6 @@ class Sd2Card {
 
  private:
   //----------------------------------------------------------------------------
-  uint8_t chipSelectPin_;
   uint8_t errorCode_;
   uint8_t spiRate_;
   uint8_t status_;

+ 0 - 364
Firmware/Sd2PinMap.h

@@ -1,364 +0,0 @@
-/* Arduino SdFat Library
- * Copyright (C) 2010 by William Greiman
- *
- * This file is part of the Arduino SdFat Library
- *
- * This Library 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 Library 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 the Arduino SdFat Library.  If not, see
- * <http://www.gnu.org/licenses/>.
- */
-// Warning this file was generated by a program.
-#include "Marlin.h"
-#ifdef SDSUPPORT
-
-#ifndef Sd2PinMap_h
-#define Sd2PinMap_h
-#include <avr/io.h>
-//------------------------------------------------------------------------------
-/** struct for mapping digital pins */
-struct pin_map_t {
-  volatile uint8_t* ddr;
-  volatile uint8_t* pin;
-  volatile uint8_t* port;
-  uint8_t bit;
-};
-//------------------------------------------------------------------------------
-#if defined(__AVR_ATmega1280__)\
-|| defined(__AVR_ATmega2560__)
-// Mega
-
-#undef MOSI_PIN
-#undef MISO_PIN
-// SPI port
-uint8_t const SS_PIN = 53;    // B0
-uint8_t const MOSI_PIN = 51;  // B2
-uint8_t const MISO_PIN = 50;  // B3
-uint8_t const SCK_PIN = 52;   // B1
-
-static const pin_map_t digitalPinMap[] = {
-  {&DDRE, &PINE, &PORTE, 0},  // E0  0
-  {&DDRE, &PINE, &PORTE, 1},  // E1  1
-  {&DDRE, &PINE, &PORTE, 4},  // E4  2
-  {&DDRE, &PINE, &PORTE, 5},  // E5  3
-  {&DDRG, &PING, &PORTG, 5},  // G5  4
-  {&DDRE, &PINE, &PORTE, 3},  // E3  5
-  {&DDRH, &PINH, &PORTH, 3},  // H3  6
-  {&DDRH, &PINH, &PORTH, 4},  // H4  7
-  {&DDRH, &PINH, &PORTH, 5},  // H5  8
-  {&DDRH, &PINH, &PORTH, 6},  // H6  9
-  {&DDRB, &PINB, &PORTB, 4},  // B4 10
-  {&DDRB, &PINB, &PORTB, 5},  // B5 11
-  {&DDRB, &PINB, &PORTB, 6},  // B6 12
-  {&DDRB, &PINB, &PORTB, 7},  // B7 13
-  {&DDRJ, &PINJ, &PORTJ, 1},  // J1 14
-  {&DDRJ, &PINJ, &PORTJ, 0},  // J0 15
-  {&DDRH, &PINH, &PORTH, 1},  // H1 16
-  {&DDRH, &PINH, &PORTH, 0},  // H0 17
-  {&DDRD, &PIND, &PORTD, 3},  // D3 18
-  {&DDRD, &PIND, &PORTD, 2},  // D2 19
-  {&DDRD, &PIND, &PORTD, 1},  // D1 20
-  {&DDRD, &PIND, &PORTD, 0},  // D0 21
-  {&DDRA, &PINA, &PORTA, 0},  // A0 22
-  {&DDRA, &PINA, &PORTA, 1},  // A1 23
-  {&DDRA, &PINA, &PORTA, 2},  // A2 24
-  {&DDRA, &PINA, &PORTA, 3},  // A3 25
-  {&DDRA, &PINA, &PORTA, 4},  // A4 26
-  {&DDRA, &PINA, &PORTA, 5},  // A5 27
-  {&DDRA, &PINA, &PORTA, 6},  // A6 28
-  {&DDRA, &PINA, &PORTA, 7},  // A7 29
-  {&DDRC, &PINC, &PORTC, 7},  // C7 30
-  {&DDRC, &PINC, &PORTC, 6},  // C6 31
-  {&DDRC, &PINC, &PORTC, 5},  // C5 32
-  {&DDRC, &PINC, &PORTC, 4},  // C4 33
-  {&DDRC, &PINC, &PORTC, 3},  // C3 34
-  {&DDRC, &PINC, &PORTC, 2},  // C2 35
-  {&DDRC, &PINC, &PORTC, 1},  // C1 36
-  {&DDRC, &PINC, &PORTC, 0},  // C0 37
-  {&DDRD, &PIND, &PORTD, 7},  // D7 38
-  {&DDRG, &PING, &PORTG, 2},  // G2 39
-  {&DDRG, &PING, &PORTG, 1},  // G1 40
-  {&DDRG, &PING, &PORTG, 0},  // G0 41
-  {&DDRL, &PINL, &PORTL, 7},  // L7 42
-  {&DDRL, &PINL, &PORTL, 6},  // L6 43
-  {&DDRL, &PINL, &PORTL, 5},  // L5 44
-  {&DDRL, &PINL, &PORTL, 4},  // L4 45
-  {&DDRL, &PINL, &PORTL, 3},  // L3 46
-  {&DDRL, &PINL, &PORTL, 2},  // L2 47
-  {&DDRL, &PINL, &PORTL, 1},  // L1 48
-  {&DDRL, &PINL, &PORTL, 0},  // L0 49
-  {&DDRB, &PINB, &PORTB, 3},  // B3 50
-  {&DDRB, &PINB, &PORTB, 2},  // B2 51
-  {&DDRB, &PINB, &PORTB, 1},  // B1 52
-  {&DDRB, &PINB, &PORTB, 0},  // B0 53
-  {&DDRF, &PINF, &PORTF, 0},  // F0 54
-  {&DDRF, &PINF, &PORTF, 1},  // F1 55
-  {&DDRF, &PINF, &PORTF, 2},  // F2 56
-  {&DDRF, &PINF, &PORTF, 3},  // F3 57
-  {&DDRF, &PINF, &PORTF, 4},  // F4 58
-  {&DDRF, &PINF, &PORTF, 5},  // F5 59
-  {&DDRF, &PINF, &PORTF, 6},  // F6 60
-  {&DDRF, &PINF, &PORTF, 7},  // F7 61
-  {&DDRK, &PINK, &PORTK, 0},  // K0 62
-  {&DDRK, &PINK, &PORTK, 1},  // K1 63
-  {&DDRK, &PINK, &PORTK, 2},  // K2 64
-  {&DDRK, &PINK, &PORTK, 3},  // K3 65
-  {&DDRK, &PINK, &PORTK, 4},  // K4 66
-  {&DDRK, &PINK, &PORTK, 5},  // K5 67
-  {&DDRK, &PINK, &PORTK, 6},  // K6 68
-  {&DDRK, &PINK, &PORTK, 7}   // K7 69
-};
-//------------------------------------------------------------------------------
-#elif defined(__AVR_ATmega644P__)\
-|| defined(__AVR_ATmega644__)\
-|| defined(__AVR_ATmega1284P__)
-// Sanguino
-
-// Two Wire (aka I2C) ports
-uint8_t const SDA_PIN = 17;  // C1
-uint8_t const SCL_PIN = 18;  // C2
-
-// SPI port
-uint8_t const SS_PIN = 4;    // B4
-uint8_t const MOSI_PIN = 5;  // B5
-uint8_t const MISO_PIN = 6;  // B6
-uint8_t const SCK_PIN = 7;   // B7
-
-static const pin_map_t digitalPinMap[] = {
-  {&DDRB, &PINB, &PORTB, 0},  // B0  0
-  {&DDRB, &PINB, &PORTB, 1},  // B1  1
-  {&DDRB, &PINB, &PORTB, 2},  // B2  2
-  {&DDRB, &PINB, &PORTB, 3},  // B3  3
-  {&DDRB, &PINB, &PORTB, 4},  // B4  4
-  {&DDRB, &PINB, &PORTB, 5},  // B5  5
-  {&DDRB, &PINB, &PORTB, 6},  // B6  6
-  {&DDRB, &PINB, &PORTB, 7},  // B7  7
-  {&DDRD, &PIND, &PORTD, 0},  // D0  8
-  {&DDRD, &PIND, &PORTD, 1},  // D1  9
-  {&DDRD, &PIND, &PORTD, 2},  // D2 10
-  {&DDRD, &PIND, &PORTD, 3},  // D3 11
-  {&DDRD, &PIND, &PORTD, 4},  // D4 12
-  {&DDRD, &PIND, &PORTD, 5},  // D5 13
-  {&DDRD, &PIND, &PORTD, 6},  // D6 14
-  {&DDRD, &PIND, &PORTD, 7},  // D7 15
-  {&DDRC, &PINC, &PORTC, 0},  // C0 16
-  {&DDRC, &PINC, &PORTC, 1},  // C1 17
-  {&DDRC, &PINC, &PORTC, 2},  // C2 18
-  {&DDRC, &PINC, &PORTC, 3},  // C3 19
-  {&DDRC, &PINC, &PORTC, 4},  // C4 20
-  {&DDRC, &PINC, &PORTC, 5},  // C5 21
-  {&DDRC, &PINC, &PORTC, 6},  // C6 22
-  {&DDRC, &PINC, &PORTC, 7},  // C7 23
-  {&DDRA, &PINA, &PORTA, 7},  // A7 24
-  {&DDRA, &PINA, &PORTA, 6},  // A6 25
-  {&DDRA, &PINA, &PORTA, 5},  // A5 26
-  {&DDRA, &PINA, &PORTA, 4},  // A4 27
-  {&DDRA, &PINA, &PORTA, 3},  // A3 28
-  {&DDRA, &PINA, &PORTA, 2},  // A2 29
-  {&DDRA, &PINA, &PORTA, 1},  // A1 30
-  {&DDRA, &PINA, &PORTA, 0}   // A0 31
-};
-//------------------------------------------------------------------------------
-#elif defined(__AVR_ATmega32U4__)
-// Teensy 2.0
-
-// Two Wire (aka I2C) ports
-uint8_t const SDA_PIN = 6;  // D1
-uint8_t const SCL_PIN = 5;  // D0
-
-// SPI port
-uint8_t const SS_PIN = 0;    // B0
-uint8_t const MOSI_PIN = 2;  // B2
-uint8_t const MISO_PIN = 3;  // B3
-uint8_t const SCK_PIN = 1;   // B1
-
-static const pin_map_t digitalPinMap[] = {
-  {&DDRB, &PINB, &PORTB, 0},  // B0  0
-  {&DDRB, &PINB, &PORTB, 1},  // B1  1
-  {&DDRB, &PINB, &PORTB, 2},  // B2  2
-  {&DDRB, &PINB, &PORTB, 3},  // B3  3
-  {&DDRB, &PINB, &PORTB, 7},  // B7  4
-  {&DDRD, &PIND, &PORTD, 0},  // D0  5
-  {&DDRD, &PIND, &PORTD, 1},  // D1  6
-  {&DDRD, &PIND, &PORTD, 2},  // D2  7
-  {&DDRD, &PIND, &PORTD, 3},  // D3  8
-  {&DDRC, &PINC, &PORTC, 6},  // C6  9
-  {&DDRC, &PINC, &PORTC, 7},  // C7 10
-  {&DDRD, &PIND, &PORTD, 6},  // D6 11
-  {&DDRD, &PIND, &PORTD, 7},  // D7 12
-  {&DDRB, &PINB, &PORTB, 4},  // B4 13
-  {&DDRB, &PINB, &PORTB, 5},  // B5 14
-  {&DDRB, &PINB, &PORTB, 6},  // B6 15
-  {&DDRF, &PINF, &PORTF, 7},  // F7 16
-  {&DDRF, &PINF, &PORTF, 6},  // F6 17
-  {&DDRF, &PINF, &PORTF, 5},  // F5 18
-  {&DDRF, &PINF, &PORTF, 4},  // F4 19
-  {&DDRF, &PINF, &PORTF, 1},  // F1 20
-  {&DDRF, &PINF, &PORTF, 0},  // F0 21
-  {&DDRD, &PIND, &PORTD, 4},  // D4 22
-  {&DDRD, &PIND, &PORTD, 5},  // D5 23
-  {&DDRE, &PINE, &PORTE, 6}   // E6 24
-};
-//------------------------------------------------------------------------------
-#elif defined(__AVR_AT90USB646__)\
-|| defined(__AVR_AT90USB1286__)
-// Teensy++ 1.0 & 2.0
-
-// Two Wire (aka I2C) ports
-uint8_t const SDA_PIN = 1;  // D1
-uint8_t const SCL_PIN = 0;  // D0
-
-// SPI port
-uint8_t const SS_PIN    = 20;    // B0
-uint8_t const MOSI_PIN  = 22;    // B2
-uint8_t const MISO_PIN  = 23;    // B3
-uint8_t const SCK_PIN   = 21;    // B1
-
-static const pin_map_t digitalPinMap[] = {
-  {&DDRD, &PIND, &PORTD, 0},  // D0  0
-  {&DDRD, &PIND, &PORTD, 1},  // D1  1
-  {&DDRD, &PIND, &PORTD, 2},  // D2  2
-  {&DDRD, &PIND, &PORTD, 3},  // D3  3
-  {&DDRD, &PIND, &PORTD, 4},  // D4  4
-  {&DDRD, &PIND, &PORTD, 5},  // D5  5
-  {&DDRD, &PIND, &PORTD, 6},  // D6  6
-  {&DDRD, &PIND, &PORTD, 7},  // D7  7
-  {&DDRE, &PINE, &PORTE, 0},  // E0  8
-  {&DDRE, &PINE, &PORTE, 1},  // E1  9
-  {&DDRC, &PINC, &PORTC, 0},  // C0 10
-  {&DDRC, &PINC, &PORTC, 1},  // C1 11
-  {&DDRC, &PINC, &PORTC, 2},  // C2 12
-  {&DDRC, &PINC, &PORTC, 3},  // C3 13
-  {&DDRC, &PINC, &PORTC, 4},  // C4 14
-  {&DDRC, &PINC, &PORTC, 5},  // C5 15
-  {&DDRC, &PINC, &PORTC, 6},  // C6 16
-  {&DDRC, &PINC, &PORTC, 7},  // C7 17
-  {&DDRE, &PINE, &PORTE, 6},  // E6 18
-  {&DDRE, &PINE, &PORTE, 7},  // E7 19
-  {&DDRB, &PINB, &PORTB, 0},  // B0 20
-  {&DDRB, &PINB, &PORTB, 1},  // B1 21
-  {&DDRB, &PINB, &PORTB, 2},  // B2 22
-  {&DDRB, &PINB, &PORTB, 3},  // B3 23
-  {&DDRB, &PINB, &PORTB, 4},  // B4 24
-  {&DDRB, &PINB, &PORTB, 5},  // B5 25
-  {&DDRB, &PINB, &PORTB, 6},  // B6 26
-  {&DDRB, &PINB, &PORTB, 7},  // B7 27
-  {&DDRA, &PINA, &PORTA, 0},  // A0 28
-  {&DDRA, &PINA, &PORTA, 1},  // A1 29
-  {&DDRA, &PINA, &PORTA, 2},  // A2 30
-  {&DDRA, &PINA, &PORTA, 3},  // A3 31
-  {&DDRA, &PINA, &PORTA, 4},  // A4 32
-  {&DDRA, &PINA, &PORTA, 5},  // A5 33
-  {&DDRA, &PINA, &PORTA, 6},  // A6 34
-  {&DDRA, &PINA, &PORTA, 7},  // A7 35
-  {&DDRE, &PINE, &PORTE, 4},  // E4 36
-  {&DDRE, &PINE, &PORTE, 5},  // E5 37
-  {&DDRF, &PINF, &PORTF, 0},  // F0 38
-  {&DDRF, &PINF, &PORTF, 1},  // F1 39
-  {&DDRF, &PINF, &PORTF, 2},  // F2 40
-  {&DDRF, &PINF, &PORTF, 3},  // F3 41
-  {&DDRF, &PINF, &PORTF, 4},  // F4 42
-  {&DDRF, &PINF, &PORTF, 5},  // F5 43
-  {&DDRF, &PINF, &PORTF, 6},  // F6 44
-  {&DDRF, &PINF, &PORTF, 7}   // F7 45
-};
-//------------------------------------------------------------------------------
-#elif defined(__AVR_ATmega168__)\
-||defined(__AVR_ATmega168P__)\
-||defined(__AVR_ATmega328P__)
-// 168 and 328 Arduinos
-
-// Two Wire (aka I2C) ports
-uint8_t const SDA_PIN = 18;  // C4
-uint8_t const SCL_PIN = 19;  // C5
-
-// SPI port
-uint8_t const SS_PIN = 10;    // B2
-uint8_t const MOSI_PIN = 11;  // B3
-uint8_t const MISO_PIN = 12;  // B4
-uint8_t const SCK_PIN = 13;   // B5
-
-static const pin_map_t digitalPinMap[] = {
-  {&DDRD, &PIND, &PORTD, 0},  // D0  0
-  {&DDRD, &PIND, &PORTD, 1},  // D1  1
-  {&DDRD, &PIND, &PORTD, 2},  // D2  2
-  {&DDRD, &PIND, &PORTD, 3},  // D3  3
-  {&DDRD, &PIND, &PORTD, 4},  // D4  4
-  {&DDRD, &PIND, &PORTD, 5},  // D5  5
-  {&DDRD, &PIND, &PORTD, 6},  // D6  6
-  {&DDRD, &PIND, &PORTD, 7},  // D7  7
-  {&DDRB, &PINB, &PORTB, 0},  // B0  8
-  {&DDRB, &PINB, &PORTB, 1},  // B1  9
-  {&DDRB, &PINB, &PORTB, 2},  // B2 10
-  {&DDRB, &PINB, &PORTB, 3},  // B3 11
-  {&DDRB, &PINB, &PORTB, 4},  // B4 12
-  {&DDRB, &PINB, &PORTB, 5},  // B5 13
-  {&DDRC, &PINC, &PORTC, 0},  // C0 14
-  {&DDRC, &PINC, &PORTC, 1},  // C1 15
-  {&DDRC, &PINC, &PORTC, 2},  // C2 16
-  {&DDRC, &PINC, &PORTC, 3},  // C3 17
-  {&DDRC, &PINC, &PORTC, 4},  // C4 18
-  {&DDRC, &PINC, &PORTC, 5}   // C5 19
-};
-#else  // defined(__AVR_ATmega1280__)
-#error unknown chip
-#endif  // defined(__AVR_ATmega1280__)
-//------------------------------------------------------------------------------
-static const uint8_t digitalPinCount = sizeof(digitalPinMap)/sizeof(pin_map_t);
-
-uint8_t badPinNumber(void)
-  __attribute__((error("Pin number is too large or not a constant")));
-
-static inline __attribute__((always_inline))
-  bool getPinMode(uint8_t pin) {
-  if (__builtin_constant_p(pin) && pin < digitalPinCount) {
-    return (*digitalPinMap[pin].ddr >> digitalPinMap[pin].bit) & 1;
-  } else {
-    return badPinNumber();
-  }
-}
-static inline __attribute__((always_inline))
-  void setPinMode(uint8_t pin, uint8_t mode) {
-  if (__builtin_constant_p(pin) && pin < digitalPinCount) {
-    if (mode) {
-      *digitalPinMap[pin].ddr |= 1 << digitalPinMap[pin].bit;
-    } else {
-      *digitalPinMap[pin].ddr &= ~(1 << digitalPinMap[pin].bit);
-    }
-  } else {
-    badPinNumber();
-  }
-}
-static inline __attribute__((always_inline))
-  bool fastDigitalRead(uint8_t pin) {
-  if (__builtin_constant_p(pin) && pin < digitalPinCount) {
-    return (*digitalPinMap[pin].pin >> digitalPinMap[pin].bit) & 1;
-  } else {
-    return badPinNumber();
-  }
-}
-static inline __attribute__((always_inline))
-  void fastDigitalWrite(uint8_t pin, uint8_t value) {
-  if (__builtin_constant_p(pin) && pin < digitalPinCount) {
-    if (value) {
-      *digitalPinMap[pin].port |= 1 << digitalPinMap[pin].bit;
-    } else {
-      *digitalPinMap[pin].port &= ~(1 << digitalPinMap[pin].bit);
-    }
-  } else {
-    badPinNumber();
-  }
-}
-#endif  // Sd2PinMap_h
-
-
-#endif

+ 9 - 12
Firmware/asm.h

@@ -1,24 +1,21 @@
 #pragma once
 #include <stdint.h>
+#include "macros.h"
 
 #ifdef __AVR_ATmega2560__
 
 // return the current PC (on AVRs with 22bit PC)
-static inline void GETPC(uint32_t* v)
+FORCE_INLINE __uint24 GETPC(void)
 {
-  uint8_t a, b, c;
-  asm
-  (
+  __uint24 ret;
+  asm (
       "rcall .\n"
-      "pop %2\n"
-      "pop %1\n"
-      "pop %0\n"
-      : "=r" (a), "=r" (b), "=r" (c)
+      "pop %A0\n"
+      "pop %B0\n"
+      "pop %C0\n"
+      : "=&r" (ret)
   );
-  ((uint8_t*)v)[0] = a;
-  ((uint8_t*)v)[1] = b;
-  ((uint8_t*)v)[2] = c;
-  ((uint8_t*)v)[3] = 0;
+  return ret;
 }
 
 #endif

+ 18 - 26
Firmware/cardreader.cpp

@@ -25,7 +25,6 @@ CardReader::CardReader()
    cardOK = false;
    saving = false;
    logging = false;
-   autostart_atmillis=0;
    workDirDepth = 0;
    file_subcall_ctr=0;
    memset(workDirParents, 0, sizeof(workDirParents));
@@ -39,7 +38,7 @@ CardReader::CardReader()
     WRITE(SDPOWER,HIGH);
   #endif //SDPOWER
   
-  autostart_atmillis=_millis()+5000;
+  autostart_atmillis.start(); // reset timer
 }
 
 char *createFilename(char *buffer,const dir_t &p) //buffer>12characters
@@ -204,20 +203,13 @@ void CardReader::initsd(bool doPresort/* = true*/)
   if(root.isOpen())
     root.close();
 #ifdef SDSLOW
-  if (!card.init(SPI_HALF_SPEED,SDSS)
-  #if defined(LCD_SDSS) && (LCD_SDSS != SDSS)
-    && !card.init(SPI_HALF_SPEED,LCD_SDSS)
-  #endif
+  if (!card.init(SPI_HALF_SPEED)
     )
 #else
-  if (!card.init(SPI_FULL_SPEED,SDSS)
-  #if defined(LCD_SDSS) && (LCD_SDSS != SDSS)
-    && !card.init(SPI_FULL_SPEED,LCD_SDSS)
-  #endif
+  if (!card.init(SPI_FULL_SPEED)
     )
 #endif
   {
-    //if (!card.init(SPI_HALF_SPEED,SDSS))
     SERIAL_ECHO_START;
     SERIAL_ECHOLNRPGM(_n("SD init fail"));////MSG_SD_INIT_FAIL
   }
@@ -626,7 +618,7 @@ void CardReader::checkautostart(bool force)
   {
     if(!autostart_stilltocheck)
       return;
-    if(autostart_atmillis<_millis())
+    if(autostart_atmillis.expired(5000))
       return;
   }
   autostart_stilltocheck=false;
@@ -697,11 +689,11 @@ void CardReader::getfilename(uint16_t nr, const char * const match/*=NULL*/)
   
 }
 
-void CardReader::getfilename_simple(uint32_t position, const char * const match/*=NULL*/)
+void CardReader::getfilename_simple(uint16_t entry, const char * const match/*=NULL*/)
 {
 	curDir = &workDir;
 	nrFiles = 0;
-	curDir->seekSet(position);
+	curDir->seekSet((uint32_t)entry << 5);
 	lsDive("", *curDir, match, LS_GetFilename);
 }
 
@@ -783,7 +775,7 @@ void CardReader::updir()
 */
 void CardReader::getfilename_sorted(const uint16_t nr, uint8_t sdSort) {
     if (nr < sort_count)
-        getfilename_simple(sort_positions[(sdSort == SD_SORT_ALPHA) ? (sort_count - nr - 1) : nr]);
+        getfilename_simple(sort_entries[(sdSort == SD_SORT_ALPHA) ? (sort_count - nr - 1) : nr]);
     else
         getfilename(nr);
 }
@@ -840,7 +832,7 @@ void CardReader::presort() {
 				else
 					getfilename_next(position);
 				sort_order[i] = i;
-				sort_positions[i] = position;
+				sort_entries[i] = position >> 5;
 				#if HAS_FOLDER_SORTING
 				if (filenameIsDir) dirCnt++;
 				#endif
@@ -890,7 +882,7 @@ void CardReader::presort() {
 						
 						manage_heater();
 						uint8_t orderBckp = sort_order[i];
-						getfilename_simple(sort_positions[orderBckp]);
+						getfilename_simple(sort_entries[orderBckp]);
 						strcpy(name1, LONGEST_FILENAME); // save (or getfilename below will trounce it)
 						crmod_date_bckp = crmodDate;
 						crmod_time_bckp = crmodTime;
@@ -899,7 +891,7 @@ void CardReader::presort() {
 						#endif
 						
 						uint16_t j = i;
-						getfilename_simple(sort_positions[sort_order[j - gap]]);
+						getfilename_simple(sort_entries[sort_order[j - gap]]);
 						char *name2 = LONGEST_FILENAME; // use the string in-place
 						#if HAS_FOLDER_SORTING
 						while (j >= gap && ((sdSort == SD_SORT_TIME)?_SORT_CMP_TIME_DIR(FOLDER_SORTING):_SORT_CMP_DIR(FOLDER_SORTING)))
@@ -917,7 +909,7 @@ void CardReader::presort() {
 							printf_P(PSTR("i%2d j%2d gap%2d orderBckp%2d\n"), i, j, gap, orderBckp);
 							#endif
 							if (j < gap) break;
-							getfilename_simple(sort_positions[sort_order[j - gap]]);
+							getfilename_simple(sort_entries[sort_order[j - gap]]);
 							name2 = LONGEST_FILENAME; // use the string in-place
 						}
 						sort_order[j] = orderBckp;
@@ -958,14 +950,14 @@ void CardReader::presort() {
 					const uint16_t o1 = sort_order[j], o2 = sort_order[j + 1];
 
 					counter++;
-					getfilename_simple(sort_positions[o1]);
+					getfilename_simple(sort_entries[o1]);
 					strcpy(name1, LONGEST_FILENAME); // save (or getfilename below will trounce it)
 					crmod_date_bckp = crmodDate;
 					crmod_time_bckp = crmodTime;
 					#if HAS_FOLDER_SORTING
 					bool dir1 = filenameIsDir;
 					#endif
-					getfilename_simple(sort_positions[o2]);
+					getfilename_simple(sort_entries[o2]);
 					char *name2 = LONGEST_FILENAME; // use the string in-place
 
 													// Sort the current pair according to settings.
@@ -1003,26 +995,26 @@ void CardReader::presort() {
 			{
 				if (sort_order_reverse_index[i] != i)
 				{
-					uint32_t el = sort_positions[i];
+					uint32_t el = sort_entries[i];
 					uint8_t idx = sort_order_reverse_index[i];
 					while (idx != i)
 					{
-						uint32_t el1 = sort_positions[idx];
+						uint32_t el1 = sort_entries[idx];
 						uint8_t idx1 = sort_order_reverse_index[idx];
 						sort_order_reverse_index[idx] = idx;
-						sort_positions[idx] = el;
+						sort_entries[idx] = el;
 						idx = idx1;
 						el = el1;
 					}
 					sort_order_reverse_index[idx] = idx;
-					sort_positions[idx] = el;
+					sort_entries[idx] = el;
 				}
 			}
 			menu_progressbar_finish();
 		}
 		else {
 			getfilename(0);
-			sort_positions[0] = position;
+			sort_entries[0] = position >> 5;
 		}
 
 		sort_count = fileCnt;

+ 3 - 4
Firmware/cardreader.h

@@ -46,7 +46,7 @@ public:
   void printingHasFinished();
 
   void getfilename(uint16_t nr, const char* const match=NULL);
-  void getfilename_simple(uint32_t position, const char * const match = NULL);
+  void getfilename_simple(uint16_t entry, const char * const match = NULL);
   void getfilename_next(uint32_t position, const char * const match = NULL);
   uint16_t getnrfilenames();
   
@@ -111,7 +111,7 @@ private:
   // Sort files and folders alphabetically.
 #ifdef SDCARD_SORT_ALPHA
   uint16_t sort_count;        // Count of sorted items in the current directory
-  uint32_t sort_positions[SDSORT_LIMIT];
+  uint16_t sort_entries[SDSORT_LIMIT];
 
 #endif // SDCARD_SORT_ALPHA
 
@@ -130,13 +130,12 @@ private:
   char filenames[SD_PROCEDURE_DEPTH][MAXPATHNAMELENGTH];
   uint32_t filesize;
   //int16_t n;
-  unsigned long autostart_atmillis;
+  ShortTimer autostart_atmillis;
   uint32_t sdpos ;
 
   bool autostart_stilltocheck; //the sd start is delayed, because otherwise the serial cannot answer fast enought to make contact with the hostsoftware.
   
   uint16_t nrFiles; //counter for the files in the current directory and recycled as position counter for getting the nrFiles'th name in the directory.
-  char* diveDirName;
 
   bool diveSubfolder (const char *&fileName);
   void lsDive(const char *prepend, SdFile parent, const char * const match=NULL, LsAction lsAction = LS_GetFilename, ls_param lsParams = ls_param());

+ 8 - 17
Firmware/cmdqueue.cpp

@@ -24,8 +24,7 @@ int serial_count = 0;  //index of character read from serial line
 bool comment_mode = false;
 char *strchr_pointer; // just a pointer to find chars in the command string like X, Y, Z, E, etc
 
-unsigned long TimeSent = _millis();
-unsigned long TimeNow = _millis();
+ShortTimer farm_incomplete_command_timeout_timer;
 
 long gcode_N = 0;
 long gcode_LastN = 0;
@@ -95,7 +94,7 @@ void cmdqueue_reset()
 {
 	while (buflen)
 	{
-		// printf_P(PSTR("dumping: \"%s\" of type %hu\n"), cmdbuffer+bufindr+CMDHDRSIZE, CMDBUFFER_CURRENT_TYPE);
+		// printf_P(PSTR("dumping: \"%s\" of type %u\n"), cmdbuffer+bufindr+CMDHDRSIZE, CMDBUFFER_CURRENT_TYPE);
 		ClearToSend();
 		cmdqueue_pop_front();
 	}
@@ -394,14 +393,8 @@ void get_command()
   while (((MYSERIAL.available() > 0 && !saved_printing) || (MYSERIAL.available() > 0 && isPrintPaused)) && !cmdqueue_serial_disabled) {  //is print is saved (crash detection or filament detection), dont process data from serial line
 	
     char serial_char = MYSERIAL.read();
-/*    if (selectedSerialPort == 1)
-    {
-        selectedSerialPort = 0; 
-        MYSERIAL.write(serial_char); // for debuging serial line 2 in farm_mode
-        selectedSerialPort = 1; 
-    } */ //RP - removed
-      TimeSent = _millis();
-      TimeNow = _millis();
+
+    farm_incomplete_command_timeout_timer.start();
 
     if (serial_char < 0)
         // Ignore extended ASCII characters. These characters have no meaning in the G-code apart from the file names
@@ -448,7 +441,7 @@ void get_command()
 				  char *p = cmdbuffer+bufindw+CMDHDRSIZE;
 				  while (p != strchr_pointer)
 					  checksum = checksum^(*p++);
-				  if (int(strtol(strchr_pointer+1, NULL, 10)) != int(checksum)) {
+				  if (code_value_short() != (int16_t)checksum) {
 					  SERIAL_ERROR_START;
 					  SERIAL_ERRORRPGM(_n("checksum mismatch, Last Line: "));////MSG_ERR_CHECKSUM_MISMATCH
 					  SERIAL_ERRORLN(gcode_LastN);
@@ -491,8 +484,7 @@ void get_command()
                       is_usb_printing = true;
               }
             if (Stopped == true) {
-                int gcode = strtol(strchr_pointer+1, NULL, 10);
-                if (gcode >= 0 && gcode <= 3) {
+                if (code_value_uint8() <= 3) {
                     SERIAL_ERRORLNRPGM(MSG_ERR_STOPPED);
                     LCD_MESSAGERPGM(_T(MSG_STOPPED));
                 }
@@ -535,9 +527,8 @@ void get_command()
     }
   } // end of serial line processing loop
 
-    if(farm_mode){
-        TimeNow = _millis();
-        if ( ((TimeNow - TimeSent) > 800) && (serial_count > 0) ) {
+    if(farm_mode && (serial_count > 0)){
+        if (farm_incomplete_command_timeout_timer.expired(800)) {
             cmdbuffer[bufindw+serial_count+CMDHDRSIZE] = 0;
             
             bufindw += strlen(cmdbuffer+bufindw+CMDHDRSIZE) + (1 + CMDHDRSIZE);

+ 0 - 3
Firmware/cmdqueue.h

@@ -52,9 +52,6 @@ extern int serial_count;
 extern bool comment_mode;
 extern char *strchr_pointer;
 
-extern unsigned long TimeSent;
-extern unsigned long TimeNow;
-
 extern long gcode_N;
 extern long gcode_LastN;
 extern long Stopped_gcode_LastN;

+ 5 - 0
Firmware/eeprom.cpp

@@ -100,6 +100,11 @@ if (eeprom_read_byte((uint8_t*)EEPROM_PINDA_TEMP_COMPENSATION) == 0xff) eeprom_u
 
 	if (eeprom_read_dword((uint32_t*)EEPROM_JOB_ID) == EEPROM_EMPTY_VALUE32)
 		eeprom_update_dword((uint32_t*)EEPROM_JOB_ID, 0);
+
+    if (eeprom_read_byte((uint8_t *)EEPROM_TOTALTIME) == 255 && eeprom_read_byte((uint8_t *)EEPROM_TOTALTIME + 1) == 255 && eeprom_read_byte((uint8_t *)EEPROM_TOTALTIME + 2) == 255 && eeprom_read_byte((uint8_t *)EEPROM_TOTALTIME + 3) == 255) {
+        eeprom_update_dword((uint32_t *)EEPROM_TOTALTIME, 0);
+        eeprom_update_dword((uint32_t *)EEPROM_FILAMENTUSED, 0);
+    }
 }
 
 //! @brief Get default sheet name for index

+ 4 - 4
Firmware/fastio.h

@@ -931,10 +931,10 @@ pins
 #define	TXD					DIO1
 
 // SPI
-#define	SCK					DIO52
-#define	MISO				DIO50
-#define	MOSI				DIO51
-#define	SS					DIO53
+#define	SCK					52
+#define	MISO				50
+#define	MOSI				51
+#define	SS					53
 
 // TWI (I2C)
 #define	SCL					DIO21

+ 16 - 17
Firmware/fsensor.cpp

@@ -124,7 +124,7 @@ uint16_t fsensor_oq_sh_sum;
 ClFsensorPCB oFsensorPCB;
 ClFsensorActionNA oFsensorActionNA;
 bool bIRsensorStateFlag=false;
-unsigned long nIRsensorLastTime;
+ShortTimer tIRsensorCheckTimer;
 #endif //IR_SENSOR_ANALOG
 
 void fsensor_stop_and_save_print(void)
@@ -188,7 +188,7 @@ void fsensor_init(void)
 {
 #ifdef PAT9125
 	uint8_t pat9125 = pat9125_init();
-	printf_P(PSTR("PAT9125_init:%hhu\n"), pat9125);
+	printf_P(PSTR("PAT9125_init:%u\n"), pat9125);
 #endif //PAT9125
 	uint8_t fsensor_enabled = eeprom_read_byte((uint8_t*)EEPROM_FSENSOR);
 	fsensor_autoload_enabled=eeprom_read_byte((uint8_t*)EEPROM_FSENS_AUTOLOAD_ENABLED);
@@ -237,7 +237,7 @@ bool fsensor_enable(bool bUpdateEEPROM)
 
 	if (mmu_enabled == false) { //filament sensor is pat9125, enable only if it is working
 		uint8_t pat9125 = pat9125_init();
-		printf_P(PSTR("PAT9125_init:%hhu\n"), pat9125);
+		printf_P(PSTR("PAT9125_init:%u\n"), pat9125);
 		if (pat9125)
 			fsensor_not_responding = false;
 		else
@@ -349,7 +349,7 @@ bool fsensor_check_autoload(void)
 	if (!fsensor_enabled) return false;
 	if (!fsensor_autoload_enabled) return false;
 	if (ir_sensor_detected) {
-		if (digitalRead(IR_SENSOR_PIN) == 1) {
+		if (READ(IR_SENSOR_PIN)) {
 			fsensor_watch_autoload = true;
 		}
 		else if (fsensor_watch_autoload == true) {
@@ -435,8 +435,8 @@ void fsensor_oq_meassure_stop(void)
 {
 	if (!fsensor_enabled) return;
 	if (!fsensor_oq_meassure_enabled) return;
-	printf_P(PSTR("fsensor_oq_meassure_stop, %hhu samples\n"), fsensor_oq_samples);
-	printf_P(_N(" st_sum=%u yd_sum=%u er_sum=%u er_max=%hhu\n"), fsensor_oq_st_sum, fsensor_oq_yd_sum, fsensor_oq_er_sum, fsensor_oq_er_max);
+	printf_P(PSTR("fsensor_oq_meassure_stop, %u samples\n"), fsensor_oq_samples);
+	printf_P(_N(" st_sum=%u yd_sum=%u er_sum=%u er_max=%u\n"), fsensor_oq_st_sum, fsensor_oq_yd_sum, fsensor_oq_er_sum, fsensor_oq_er_max);
 	printf_P(_N(" yd_min=%u yd_max=%u yd_avg=%u sh_avg=%u\n"), fsensor_oq_yd_min, fsensor_oq_yd_max, (uint16_t)((uint32_t)fsensor_oq_yd_sum * fsensor_chunk_len / fsensor_oq_st_sum), (uint16_t)(fsensor_oq_sh_sum / fsensor_oq_samples));
 	fsensor_oq_meassure = false;
 }
@@ -453,10 +453,10 @@ bool fsensor_oq_result(void)
 	bool res_er_sum = (fsensor_oq_er_sum <= FSENSOR_OQ_MAX_ES);
 	printf_P(_N(" er_sum = %u %S\n"), fsensor_oq_er_sum, (res_er_sum?_OK:_NG));
 	bool res_er_max = (fsensor_oq_er_max <= FSENSOR_OQ_MAX_EM);
-	printf_P(_N(" er_max = %hhu %S\n"), fsensor_oq_er_max, (res_er_max?_OK:_NG));
+	printf_P(_N(" er_max = %u %S\n"), fsensor_oq_er_max, (res_er_max?_OK:_NG));
 	uint8_t yd_avg = ((uint32_t)fsensor_oq_yd_sum * fsensor_chunk_len / fsensor_oq_st_sum);
 	bool res_yd_avg = (yd_avg >= FSENSOR_OQ_MIN_YD) && (yd_avg <= FSENSOR_OQ_MAX_YD);
-	printf_P(_N(" yd_avg = %hhu %S\n"), yd_avg, (res_yd_avg?_OK:_NG));
+	printf_P(_N(" yd_avg = %u %S\n"), yd_avg, (res_yd_avg?_OK:_NG));
 	bool res_yd_max = (fsensor_oq_yd_max <= (yd_avg * FSENSOR_OQ_MAX_PD));
 	printf_P(_N(" yd_max = %u %S\n"), fsensor_oq_yd_max, (res_yd_max?_OK:_NG));
 	bool res_yd_min = (fsensor_oq_yd_min >= (yd_avg / FSENSOR_OQ_MAX_ND));
@@ -472,7 +472,7 @@ bool fsensor_oq_result(void)
 	bool res_sh_avg = (sh_avg <= FSENSOR_OQ_MAX_SH);
 	if (yd_qua >= 8) res_sh_avg = true;
 
-	printf_P(_N(" sh_avg = %hhu %S\n"), sh_avg, (res_sh_avg?_OK:_NG));
+	printf_P(_N(" sh_avg = %u %S\n"), sh_avg, (res_sh_avg?_OK:_NG));
 	bool res = res_er_sum && res_er_max && res_yd_avg && res_yd_max && res_yd_min && res_sh_avg;
 	printf_P(_N("fsensor_oq_result %S\n"), (res?_OK:_NG));
 	return res;
@@ -559,8 +559,8 @@ FORCE_INLINE static void fsensor_isr(int st_cnt)
 #ifdef DEBUG_FSENSOR_LOG
 	if (fsensor_log)
 	{
-		printf_P(_N("FSENSOR cnt=%d dy=%d err=%hhu %S\n"), st_cnt, pat9125_y, fsensor_err_cnt, (fsensor_err_cnt > old_err_cnt)?_N("NG!"):_N("OK"));
-		if (fsensor_oq_meassure) printf_P(_N("FSENSOR st_sum=%u yd_sum=%u er_sum=%u er_max=%hhu yd_max=%u\n"), fsensor_oq_st_sum, fsensor_oq_yd_sum, fsensor_oq_er_sum, fsensor_oq_er_max, fsensor_oq_yd_max);
+		printf_P(_N("FSENSOR cnt=%d dy=%d err=%u %S\n"), st_cnt, pat9125_y, fsensor_err_cnt, (fsensor_err_cnt > old_err_cnt)?_N("NG!"):_N("OK"));
+		if (fsensor_oq_meassure) printf_P(_N("FSENSOR st_sum=%u yd_sum=%u er_sum=%u er_max=%u yd_max=%u\n"), fsensor_oq_st_sum, fsensor_oq_yd_sum, fsensor_oq_er_sum, fsensor_oq_er_max, fsensor_oq_yd_max);
 	}
 #endif //DEBUG_FSENSOR_LOG
 
@@ -591,9 +591,8 @@ ISR(FSENSOR_INT_PIN_VECT)
 
 void fsensor_setup_interrupt(void)
 {
-
-	pinMode(FSENSOR_INT_PIN, OUTPUT);
-	digitalWrite(FSENSOR_INT_PIN, LOW);
+	WRITE(FSENSOR_INT_PIN, 0);
+	SET_OUTPUT(FSENSOR_INT_PIN);
 	fsensor_int_pin_old = 0;
 
 	//pciSetup(FSENSOR_INT_PIN);
@@ -687,17 +686,17 @@ void fsensor_update(void)
 #else //PAT9125
         if (CHECK_FSENSOR && ir_sensor_detected)
         {
-            if(digitalRead(IR_SENSOR_PIN))
+            if (READ(IR_SENSOR_PIN))
             {                                  // IR_SENSOR_PIN ~ H
 #ifdef IR_SENSOR_ANALOG
                 if(!bIRsensorStateFlag)
                 {
                     bIRsensorStateFlag=true;
-                    nIRsensorLastTime=_millis();
+                    tIRsensorCheckTimer.start();
                 }
                 else
                 {
-                    if((_millis()-nIRsensorLastTime)>IR_SENSOR_STEADY)
+                    if(tIRsensorCheckTimer.expired(IR_SENSOR_STEADY))
                     {
                         uint8_t nMUX1,nMUX2;
                         uint16_t nADC;

+ 2 - 2
Firmware/lcd.cpp

@@ -331,7 +331,7 @@ void lcd_no_autoscroll(void)
 
 void lcd_set_cursor(uint8_t col, uint8_t row)
 {
-	int row_offsets[] = { 0x00, 0x40, 0x14, 0x54 };
+	uint8_t row_offsets[] = { 0x00, 0x40, 0x14, 0x54 };
 	if (row >= LCD_HEIGHT)
 		row = LCD_HEIGHT - 1;    // we count rows starting w/0
 	lcd_currline = row;  
@@ -344,7 +344,7 @@ void lcd_createChar_P(uint8_t location, const uint8_t* charmap)
 {
   location &= 0x7; // we only have 8 locations 0-7
   lcd_command(LCD_SETCGRAMADDR | (location << 3));
-  for (int i=0; i<8; i++)
+  for (uint8_t i = 0; i < 8; i++)
     lcd_send(pgm_read_byte(&charmap[i]), HIGH);
 }
 

+ 2 - 4
Firmware/menu.cpp

@@ -150,9 +150,7 @@ void menu_submenu_no_reset(menu_func_t submenu)
 
 uint8_t menu_item_ret(void)
 {
-	lcd_beeper_quick_feedback();
-	lcd_draw_update = 2;
-	lcd_button_pressed = false;
+	lcd_quick_feedback();
 	return 1;
 }
 
@@ -511,7 +509,7 @@ static void _menu_edit_P(void)
 	if (lcd_draw_update)
 	{
 		if (lcd_encoder < _md->minEditValue) lcd_encoder = _md->minEditValue;
-		if (lcd_encoder > _md->maxEditValue) lcd_encoder = _md->maxEditValue;
+		else if (lcd_encoder > _md->maxEditValue) lcd_encoder = _md->maxEditValue;
 		lcd_set_cursor(0, 1);
 		menu_draw_P<T>(' ', _md->editLabel, (int)lcd_encoder);
 	}

+ 6 - 5
Firmware/mesh_bed_calibration.cpp

@@ -2240,7 +2240,7 @@ BedSkewOffsetDetectionResultType find_bed_offset_and_skew(int8_t verbosity_level
     /// Retry point scanning if a point with bad data appears.
     /// Bad data could be cause by "cold" sensor.
     /// This behavior vanishes after few point scans so retry will help.
-    for (int retries = 0; retries <= 1; ++retries) {
+    for (uint8_t retries = 0; retries <= 1; ++retries) {
         bool retry = false;
         for (int k = 0; k < 4; ++k) {
             // Don't let the manage_inactivity() function remove power from the motors.
@@ -2852,7 +2852,7 @@ bool sample_mesh_and_store_reference()
         current_position[Y_AXIS] = BED_Y0;
         world2machine_clamp(current_position[X_AXIS], current_position[Y_AXIS]);
         go_to_current(homing_feedrate[X_AXIS]/60);
-        memcpy(destination, current_position, sizeof(destination));
+        set_destination_to_current();
         enable_endstops(true);
         homeaxis(Z_AXIS);
 
@@ -2872,14 +2872,15 @@ bool sample_mesh_and_store_reference()
 		}
         mbl.set_z(0, 0, current_position[Z_AXIS]);
     }
-    for (int8_t mesh_point = 1; mesh_point != MESH_MEAS_NUM_X_POINTS * MESH_MEAS_NUM_Y_POINTS; ++ mesh_point) {
+    static_assert(MESH_MEAS_NUM_X_POINTS * MESH_MEAS_NUM_Y_POINTS <= 255, "overflow.....");
+    for (uint8_t mesh_point = 1; mesh_point != MESH_MEAS_NUM_X_POINTS * MESH_MEAS_NUM_Y_POINTS; ++ mesh_point) {
         // Don't let the manage_inactivity() function remove power from the motors.
         refresh_cmd_timeout();
         // Print the decrasing ID of the measurement point.
         current_position[Z_AXIS] = MESH_HOME_Z_SEARCH;
         go_to_current(homing_feedrate[Z_AXIS]/60);
-		int8_t ix = mesh_point % MESH_MEAS_NUM_X_POINTS;
-		int8_t iy = mesh_point / MESH_MEAS_NUM_X_POINTS;
+		uint8_t ix = mesh_point % MESH_MEAS_NUM_X_POINTS;
+		uint8_t iy = mesh_point / MESH_MEAS_NUM_X_POINTS;
 		if (iy & 1) ix = (MESH_MEAS_NUM_X_POINTS - 1) - ix; // Zig zag
 		current_position[X_AXIS] = BED_X(ix, MESH_MEAS_NUM_X_POINTS);
 		current_position[Y_AXIS] = BED_Y(iy, MESH_MEAS_NUM_Y_POINTS);

+ 5 - 6
Firmware/mesh_bed_calibration.h

@@ -129,16 +129,15 @@ inline bool world2machine_clamp(float &x, float &y)
     if (tmpx < X_MIN_POS) {
         tmpx = X_MIN_POS;
         clamped = true;
+    } else if (tmpx > X_MAX_POS) {
+        tmpx = X_MAX_POS;
+        clamped = true;
     }
+    
     if (tmpy < Y_MIN_POS) {
         tmpy = Y_MIN_POS;
         clamped = true;
-    }
-    if (tmpx > X_MAX_POS) {
-        tmpx = X_MAX_POS;
-        clamped = true;
-    }
-    if (tmpy > Y_MAX_POS) {
+    } else if (tmpy > Y_MAX_POS) {
         tmpy = Y_MAX_POS;
         clamped = true;
     }

+ 1 - 3
Firmware/mesh_bed_leveling.cpp

@@ -10,9 +10,7 @@ mesh_bed_leveling::mesh_bed_leveling() { reset(); }
 
 void mesh_bed_leveling::reset() {
     active = 0;
-    for (int y = 0; y < MESH_NUM_Y_POINTS; y++)
-        for (int x = 0; x < MESH_NUM_X_POINTS; x++)
-            z_values[y][x] = 0;
+    memset(z_values, 0, sizeof(float) * MESH_NUM_X_POINTS * MESH_NUM_Y_POINTS);
 }
 
 static inline bool vec_undef(const float v[2])

+ 1 - 6
Firmware/mesh_bed_leveling.h

@@ -24,12 +24,7 @@ public:
     static float get_x(int i) { return float(MESH_MIN_X) + float(MESH_X_DIST) * float(i); }
     static float get_y(int i) { return float(MESH_MIN_Y) + float(MESH_Y_DIST) * float(i); }
     
-    // Measurement point for the Z probe.
-    // If use_default=true, then the default positions for a correctly built printer are used.
-    // Otherwise a correction matrix is pulled from the EEPROM if available.
-    static void get_meas_xy(int ix, int iy, float &x, float &y, bool use_default);
-    
-    void set_z(int ix, int iy, float z) { z_values[iy][ix] = z; }
+    void set_z(uint8_t ix, uint8_t iy, float z) { z_values[iy][ix] = z; }
     
     int select_x_index(float x) {
         int i = 1;

+ 1 - 1
Firmware/messages.cpp

@@ -168,7 +168,7 @@ const char MSG_AUTO_DEPLETE[] PROGMEM_N1 = ISTR("SpoolJoin"); ////c=13
 const char MSG_FIRMWARE[] PROGMEM_N1 = ISTR("Firmware"); ////c=8
 const char MSG_TOSHIBA_FLASH_AIR_COMPATIBILITY[] PROGMEM_N1 = ISTR("FlashAir"); ////c=8
 const char MSG_PINDA[] PROGMEM_N1 = ISTR("PINDA");////c=5
-const char WELCOME_MSG[] PROGMEM_N1 = ISTR(CUSTOM_MENDEL_NAME " OK."); ////c=20
+const char MSG_WELCOME[] PROGMEM_N1 = WELCOME_MSG; ////c=20
 const char MSG_SD_WORKDIR_FAIL[] PROGMEM_N1 = "workDir open failed"; ////
 const char MSG_BROWNOUT_RESET[] PROGMEM_N1 = " Brown out Reset"; ////
 const char MSG_EXTERNAL_RESET[] PROGMEM_N1 = " External Reset"; ////

+ 3 - 1
Firmware/messages.h

@@ -7,6 +7,8 @@
 extern "C" {
 #endif //defined(__cplusplus)
 
+#define WELCOME_MSG (CUSTOM_MENDEL_NAME " OK.")
+
 // LCD Menu Messages
 //internationalized messages
 extern const char MSG_AUTO_HOME[];
@@ -123,7 +125,7 @@ extern const char MSG_WIZARD_WELCOME[];
 extern const char MSG_WIZARD_WELCOME_SHIPPING[];
 extern const char MSG_YES[];
 extern const char MSG_V2_CALIBRATION[];
-extern const char WELCOME_MSG[];
+extern const char MSG_WELCOME[];
 extern const char MSG_OFF[];
 extern const char MSG_ON[];
 extern const char MSG_NA[];

+ 23 - 23
Firmware/mmu.cpp

@@ -70,14 +70,14 @@ uint8_t mmu_extruder = MMU_FILAMENT_UNKNOWN;
 uint8_t tmp_extruder = MMU_FILAMENT_UNKNOWN;
 
 int8_t mmu_finda = -1;
-uint32_t mmu_last_finda_response = 0;
 
 int16_t mmu_version = -1;
 
 int16_t mmu_buildnr = -1;
 
-uint32_t mmu_last_request = 0;
-uint32_t mmu_last_response = 0;
+ShortTimer mmu_last_request;
+ShortTimer mmu_last_response;
+ShortTimer mmu_last_finda_response;
 
 MmuCmd mmu_last_cmd = MmuCmd::None;
 uint16_t mmu_power_failures = 0;
@@ -113,7 +113,7 @@ int mmu_puts_P(const char* str)
 {
 	mmu_clr_rx_buf();                          //clear rx buffer
     int r = fputs_P(str, uart2io);             //send command
-	mmu_last_request = _millis();
+	mmu_last_request.start();
 	return r;
 }
 
@@ -125,7 +125,7 @@ int mmu_printf_P(const char* format, ...)
 	mmu_clr_rx_buf();                          //clear rx buffer
 	int r = vfprintf_P(uart2io, format, args); //send command
 	va_end(args);
-	mmu_last_request = _millis();
+	mmu_last_request.start();
 	return r;
 }
 
@@ -133,7 +133,7 @@ int mmu_printf_P(const char* format, ...)
 int8_t mmu_rx_ok(void)
 {
 	int8_t res = uart2_rx_str_P(PSTR("ok\n"));
-	if (res == 1) mmu_last_response = _millis();
+	if (res == 1) mmu_last_response.start();
 	return res;
 }
 
@@ -141,7 +141,7 @@ int8_t mmu_rx_ok(void)
 int8_t mmu_rx_start(void)
 {
 	int8_t res = uart2_rx_str_P(PSTR("start\n"));
-	if (res == 1) mmu_last_response = _millis();
+	if (res == 1) mmu_last_response.start();
 	return res;
 }
 
@@ -149,8 +149,8 @@ int8_t mmu_rx_start(void)
 void mmu_init(void)
 {
 #ifdef MMU_HWRESET
-	digitalWrite(MMU_RST_PIN, HIGH);
-	pinMode(MMU_RST_PIN, OUTPUT);              //setup reset pin
+	WRITE(MMU_RST_PIN, 1);
+	SET_OUTPUT(MMU_RST_PIN);                   //setup reset pin
 #endif //MMU_HWRESET
 	uart2_init();                              //init uart2
 	_delay_ms(10);                             //wait 10ms for sure
@@ -264,8 +264,8 @@ void mmu_loop(void)
 	case S::GetFindaInit:
 		if (mmu_rx_ok() > 0)
 		{
-			fscanf_P(uart2io, PSTR("%hhu"), &mmu_finda); //scan finda from buffer
-			mmu_last_finda_response = _millis();
+			fscanf_P(uart2io, PSTR("%hhu"), &mmu_finda); //scan finda from buffer. MUST BE %hhu!!!
+			mmu_last_finda_response.start();
 			FDEBUG_PRINTF_P(PSTR("MMU => '%dok'\n"), mmu_finda);
 			puts_P(PSTR("MMU - ENABLED"));
 			mmu_enabled = true;
@@ -350,7 +350,7 @@ void mmu_loop(void)
 				mmu_printf_P(PSTR("M%d\n"), SilentModeMenu_MMU);
 				mmu_state = S::SwitchMode;
 		}
-		else if ((mmu_last_response + 300) < _millis()) //request every 300ms
+		else if (mmu_last_response.expired(300)) //request every 300ms
 		{
 #ifndef IR_SENSOR
 			if(check_for_ir_sensor()) ir_sensor_detected = true;
@@ -377,8 +377,8 @@ void mmu_loop(void)
         }
 		if (mmu_rx_ok() > 0)
 		{
-			fscanf_P(uart2io, PSTR("%hhu"), &mmu_finda); //scan finda from buffer
-			mmu_last_finda_response = _millis();
+			fscanf_P(uart2io, PSTR("%hhu"), &mmu_finda); //scan finda from buffer. MUST BE %hhu!!!
+			mmu_last_finda_response.start();
 			FDEBUG_PRINTF_P(PSTR("MMU => '%dok'\n"), mmu_finda);
 			//printf_P(PSTR("Eact: %d\n"), int(e_active()));
 			if (!mmu_finda && CHECK_FSENSOR && fsensor_enabled) {
@@ -398,7 +398,7 @@ void mmu_loop(void)
 			if (mmu_cmd == MmuCmd::None)
 				mmu_ready = true;
 		}
-		else if ((mmu_last_request + MMU_P0_TIMEOUT) < _millis())
+		else if (mmu_last_request.expired(MMU_P0_TIMEOUT))
 		{ //resend request after timeout (30s)
 			mmu_state = S::Idle;
 		}
@@ -424,7 +424,7 @@ void mmu_loop(void)
 			mmu_ready = true;
 			mmu_state = S::Idle;
 		}
-		else if ((mmu_last_request + MMU_CMD_TIMEOUT) < _millis())
+		else if (mmu_last_request.expired(MMU_CMD_TIMEOUT))
 		{ //resend request after timeout (5 min)
 			if (mmu_last_cmd != MmuCmd::None)
 			{
@@ -467,7 +467,7 @@ void mmu_loop(void)
 			mmu_ready = true;
 			mmu_state = S::Idle;
 		}
-		else if ((mmu_last_request + MMU_CMD_TIMEOUT) < _millis())
+		else if (mmu_last_request.expired(MMU_CMD_TIMEOUT))
 		{ //timeout 45 s
 			mmu_state = S::Idle;
 		}
@@ -479,7 +479,7 @@ void mmu_loop(void)
 			eeprom_update_byte((uint8_t*)EEPROM_MMU_STEALTH, SilentModeMenu_MMU);
 			mmu_state = S::Idle;
 		}
-		else if ((mmu_last_request + MMU_CMD_TIMEOUT) < _millis())
+		else if (mmu_last_request.expired(MMU_CMD_TIMEOUT))
 		{ //timeout 45 s
 			mmu_state = S::Idle;
 		}
@@ -490,9 +490,9 @@ void mmu_loop(void)
 void mmu_reset(void)
 {
 #ifdef MMU_HWRESET                             //HW - pulse reset pin
-	digitalWrite(MMU_RST_PIN, LOW);
+	WRITE(MMU_RST_PIN, 0);
 	_delay_us(100);
-	digitalWrite(MMU_RST_PIN, HIGH);
+	WRITE(MMU_RST_PIN, 1);
 #else                                          //SW - send X0 command
     mmu_puts_P(PSTR("X0\n"));
 #endif
@@ -924,8 +924,8 @@ void change_extr(int
 
 	mmu_extruder = extr;
 
-	pinMode(E_MUX0_PIN, OUTPUT);
-	pinMode(E_MUX1_PIN, OUTPUT);
+	SET_OUTPUT(E_MUX0_PIN);
+	SET_OUTPUT(E_MUX1_PIN);
 
 	switch (extr) {
 	case 1:
@@ -1363,7 +1363,7 @@ void lcd_mmu_load_to_nozzle(uint8_t filament_nr)
         lcd_return_to_status();
         lcd_update_enable(true);
         lcd_load_filament_color_check();
-        lcd_setstatuspgm(_T(WELCOME_MSG));
+        lcd_setstatuspgm(MSG_WELCOME);
         custom_message_type = CustomMsg::Status;
     }
     else

+ 2 - 1
Firmware/mmu.h

@@ -4,6 +4,7 @@
 #define MMU_H
 
 #include <inttypes.h>
+#include "Timer.h"
 
 
 extern bool mmu_enabled;
@@ -14,7 +15,7 @@ extern uint8_t mmu_extruder;
 extern uint8_t tmp_extruder;
 
 extern int8_t mmu_finda;
-extern uint32_t mmu_last_finda_response;
+extern ShortTimer mmu_last_finda_response;
 extern bool ir_sensor_detected;
 
 extern int16_t mmu_version;

+ 2 - 2
Firmware/pat9125.c

@@ -188,8 +188,8 @@ uint8_t pat9125_init(void)
 
 	pat9125_wr_reg(PAT9125_RES_X, PAT9125_XRES);
 	pat9125_wr_reg(PAT9125_RES_Y, PAT9125_YRES);
-	fprintf_P(uartout, PSTR("PAT9125_RES_X=%hhu\n"), pat9125_rd_reg(PAT9125_RES_X));
-	fprintf_P(uartout, PSTR("PAT9125_RES_Y=%hhu\n"), pat9125_rd_reg(PAT9125_RES_Y));
+	fprintf_P(uartout, PSTR("PAT9125_RES_X=%u\n"), pat9125_rd_reg(PAT9125_RES_X));
+	fprintf_P(uartout, PSTR("PAT9125_RES_Y=%u\n"), pat9125_rd_reg(PAT9125_RES_Y));
 	return 1;
 }
 

+ 8 - 19
Firmware/planner.cpp

@@ -459,10 +459,7 @@ void plan_init() {
   #ifdef LIN_ADVANCE
   memset(position_float, 0, sizeof(position_float)); // clear position
   #endif
-  previous_speed[0] = 0.0;
-  previous_speed[1] = 0.0;
-  previous_speed[2] = 0.0;
-  previous_speed[3] = 0.0;
+  memset(previous_speed, 0, sizeof(previous_speed));
   previous_nominal_speed = 0.0;
   plan_reset_next_e_queue = false;
   plan_reset_next_e_sched = false;
@@ -678,10 +675,7 @@ void planner_abort_hard()
 #endif
     // Resets planner junction speeds. Assumes start from rest.
     previous_nominal_speed = 0.0;
-    previous_speed[0] = 0.0;
-    previous_speed[1] = 0.0;
-    previous_speed[2] = 0.0;
-    previous_speed[3] = 0.0;
+    memset(previous_speed, 0, sizeof(previous_speed));
 
     plan_reset_next_e_queue = false;
     plan_reset_next_e_sched = false;
@@ -1023,7 +1017,7 @@ Having the real displacement of the head, we can calculate the total movement le
     // Calculate speed in mm/second for each axis. No divide by zero due to previous checks.
   float inverse_second = feed_rate * inverse_millimeters;
 
-  int moves_queued = moves_planned();
+  uint8_t moves_queued = moves_planned();
 
   // slow down when de buffer starts to empty, rather than wait at the corner for a buffer refill
 #ifdef SLOWDOWN
@@ -1044,14 +1038,12 @@ Having the real displacement of the head, we can calculate the total movement le
   // Calculate and limit speed in mm/sec for each axis
   float current_speed[4];
   float speed_factor = 1.0; //factor <=1 do decrease speed
-//  maxlimit_status &= ~0xf;
   for(int i=0; i < 4; i++)
   {
     current_speed[i] = delta_mm[i] * inverse_second;
 	if(fabs(current_speed[i]) > max_feedrate[i])
 	{
       speed_factor = min(speed_factor, max_feedrate[i] / fabs(current_speed[i]));
-	  maxlimit_status |= (1 << i);
 	}
   }
 
@@ -1133,13 +1125,13 @@ Having the real displacement of the head, we can calculate the total movement le
     // Limit acceleration per axis
     //FIXME Vojtech: One shall rather limit a projection of the acceleration vector instead of using the limit.
     if(((float)block->acceleration_st * (float)block->steps_x.wide / (float)block->step_event_count.wide) > axis_steps_per_sqr_second[X_AXIS])
-	{  block->acceleration_st = axis_steps_per_sqr_second[X_AXIS]; maxlimit_status |= (X_AXIS_MASK << 4); }
+	{  block->acceleration_st = axis_steps_per_sqr_second[X_AXIS]; }
     if(((float)block->acceleration_st * (float)block->steps_y.wide / (float)block->step_event_count.wide) > axis_steps_per_sqr_second[Y_AXIS])
-	{  block->acceleration_st = axis_steps_per_sqr_second[Y_AXIS]; maxlimit_status |= (Y_AXIS_MASK << 4); }
+	{  block->acceleration_st = axis_steps_per_sqr_second[Y_AXIS]; }
     if(((float)block->acceleration_st * (float)block->steps_e.wide / (float)block->step_event_count.wide) > axis_steps_per_sqr_second[E_AXIS])
-	{  block->acceleration_st = axis_steps_per_sqr_second[E_AXIS]; maxlimit_status |= (Z_AXIS_MASK << 4); }
+	{  block->acceleration_st = axis_steps_per_sqr_second[E_AXIS]; }
     if(((float)block->acceleration_st * (float)block->steps_z.wide / (float)block->step_event_count.wide ) > axis_steps_per_sqr_second[Z_AXIS])
-	{  block->acceleration_st = axis_steps_per_sqr_second[Z_AXIS]; maxlimit_status |= (E_AXIS_MASK << 4); }
+	{  block->acceleration_st = axis_steps_per_sqr_second[Z_AXIS]; }
   }
   // Acceleration of the segment, in mm/sec^2
   block->acceleration = block->acceleration_st / steps_per_mm;
@@ -1414,10 +1406,7 @@ void plan_set_position(float x, float y, float z, const float &e)
   #endif
   st_set_position(position[X_AXIS], position[Y_AXIS], position[Z_AXIS], position[E_AXIS]);
   previous_nominal_speed = 0.0; // Resets planner junction speeds. Assumes start from rest.
-  previous_speed[0] = 0.0;
-  previous_speed[1] = 0.0;
-  previous_speed[2] = 0.0;
-  previous_speed[3] = 0.0;
+  memset(previous_speed, 0, sizeof(previous_speed));
 }
 
 // Only useful in the bed leveling routine, when the mesh bed leveling is off.

+ 0 - 1
Firmware/planner.h

@@ -192,7 +192,6 @@ extern unsigned long* max_acceleration_units_per_sq_second;
 extern unsigned long axis_steps_per_sqr_second[NUM_AXIS];
 
 extern long position[NUM_AXIS];
-extern uint8_t maxlimit_status;
 
 
 #ifdef AUTOTEMP

+ 3 - 3
Firmware/sound.h

@@ -4,13 +4,13 @@
 
 
 #define e_SOUND_MODE_NULL 0xFF
-typedef enum
+typedef enum : uint8_t
      {e_SOUND_MODE_LOUD,e_SOUND_MODE_ONCE,e_SOUND_MODE_SILENT,e_SOUND_MODE_BLIND} eSOUND_MODE;
 #define e_SOUND_MODE_DEFAULT e_SOUND_MODE_LOUD
 
-typedef enum
+typedef enum : uint8_t
      {e_SOUND_TYPE_ButtonEcho,e_SOUND_TYPE_EncoderEcho,e_SOUND_TYPE_StandardPrompt,e_SOUND_TYPE_StandardConfirm,e_SOUND_TYPE_StandardWarning,e_SOUND_TYPE_StandardAlert,e_SOUND_TYPE_EncoderMove,e_SOUND_TYPE_BlindAlert} eSOUND_TYPE;
-typedef enum
+typedef enum : uint8_t
      {e_SOUND_CLASS_Echo,e_SOUND_CLASS_Prompt,e_SOUND_CLASS_Confirm,e_SOUND_CLASS_Warning,e_SOUND_CLASS_Alert} eSOUND_CLASS;
 
 

+ 88 - 74
Firmware/speed_lookuptable.h

@@ -8,86 +8,101 @@ extern const uint16_t speed_lookuptable_slow[256][2] PROGMEM;
 
 #ifndef _NO_ASM
 
-// intRes = intIn1 * intIn2 >> 8
-// uses:
-// r26 to store 0
-// r27 to store the byte 1 of the 24 bit result
-#define MultiU16X8toH16(intRes, charIn1, intIn2) \
-asm volatile ( \
-"clr r26 \n\t" \
-"mul %A1, %B2 \n\t" \
-"movw %A0, r0 \n\t" \
-"mul %A1, %A2 \n\t" \
-"add %A0, r1 \n\t" \
-"adc %B0, r26 \n\t" \
-"lsr r0 \n\t" \
-"adc %A0, r26 \n\t" \
-"adc %B0, r26 \n\t" \
-"clr r1 \n\t" \
-: \
-"=&r" (intRes) \
-: \
-"d" (charIn1), \
-"d" (intIn2) \
-: \
-"r26" \
-)
+// return ((x * y) >> 8) with rounding when shifting right
+FORCE_INLINE uint16_t MUL8x16R8(uint8_t x, uint16_t y) {
+    uint16_t out;
+    __asm__ (
+    // %0 out
+    // %1 x
+    // %2 y
+    // uint8_t: %An or %n
+    // uint16_t: %Bn %An
+    // __uint24: %Cn %Bn %An
+    // uint32_t: %Dn %Cn %Bn %An
+    //
+    //
+    //    B2 A2 *
+    //       A1
+    //---------
+    // B0 A0 RR
+    "mul %B2, %A1" "\n\t"
+    "movw %0, r0" "\n\t"
+    "mul %A2, %A1" "\n\t"
+    "lsl r0" "\n\t"         //push MSB to carry for rounding
+    "adc %A0, r1" "\n\t"    //add with carry (for rounding)
+    "clr r1" "\n\t"         //make r1 __zero_reg__ again
+    "adc %B0, r1" "\n\t"    //propagate carry of addition (add 0 with carry)
+    : "=&r" (out)
+    : "r" (x), "r" (y)
+    : "r0", "r1"            //clobbers: Technically these are either scratch registers or always 0 registers, but I'm making sure the compiler knows just in case.
+    );
+    return out;
+}
 
-// intRes = longIn1 * longIn2 >> 24
-// uses:
-// r26 to store 0
-// r27 to store the byte 1 of the 48bit result
-#define MultiU24X24toH16(intRes, longIn1, longIn2) \
-asm volatile ( \
-"clr r26 \n\t" \
-"mul %A1, %B2 \n\t" \
-"mov r27, r1 \n\t" \
-"mul %B1, %C2 \n\t" \
-"movw %A0, r0 \n\t" \
-"mul %C1, %C2 \n\t" \
-"add %B0, r0 \n\t" \
-"mul %C1, %B2 \n\t" \
-"add %A0, r0 \n\t" \
-"adc %B0, r1 \n\t" \
-"mul %A1, %C2 \n\t" \
-"add r27, r0 \n\t" \
-"adc %A0, r1 \n\t" \
-"adc %B0, r26 \n\t" \
-"mul %B1, %B2 \n\t" \
-"add r27, r0 \n\t" \
-"adc %A0, r1 \n\t" \
-"adc %B0, r26 \n\t" \
-"mul %C1, %A2 \n\t" \
-"add r27, r0 \n\t" \
-"adc %A0, r1 \n\t" \
-"adc %B0, r26 \n\t" \
-"mul %B1, %A2 \n\t" \
-"add r27, r1 \n\t" \
-"adc %A0, r26 \n\t" \
-"adc %B0, r26 \n\t" \
-"lsr r27 \n\t" \
-"adc %A0, r26 \n\t" \
-"adc %B0, r26 \n\t" \
-"clr r1 \n\t" \
-: \
-"=&r" (intRes) \
-: \
-"d" (longIn1), \
-"d" (longIn2) \
-: \
-"r26" , "r27" \
-)
+// return ((x * y) >> 24) with rounding when shifting right
+FORCE_INLINE uint16_t MUL24x24R24(__uint24 x, __uint24 y) {
+    uint16_t out;
+    __asm__ (
+    // %0 out
+    // %1 x
+    // %2 y
+    // uint8_t: %An or %n
+    // uint16_t: %Bn %An
+    // __uint24: %Cn %Bn %An
+    // uint32_t: %Dn %Cn %Bn %An
+    //
+    //
+    //          C2 B2 A2 *
+    //          C1 B1 A1
+    //------------------
+    // -- B0 A0 RR RR RR
+    "clr r26 \n\t"
+    "mul %A1, %B2 \n\t"
+    "mov r27, r1 \n\t"
+    "mul %B1, %C2 \n\t"
+    "movw %A0, r0 \n\t"
+    "mul %C1, %C2 \n\t"
+    "add %B0, r0 \n\t"
+    "mul %C1, %B2 \n\t"
+    "add %A0, r0 \n\t"
+    "adc %B0, r1 \n\t"
+    "mul %A1, %C2 \n\t"
+    "add r27, r0 \n\t"
+    "adc %A0, r1 \n\t"
+    "adc %B0, r26 \n\t"
+    "mul %B1, %B2 \n\t"
+    "add r27, r0 \n\t"
+    "adc %A0, r1 \n\t"
+    "adc %B0, r26 \n\t"
+    "mul %C1, %A2 \n\t"
+    "add r27, r0 \n\t"
+    "adc %A0, r1 \n\t"
+    "adc %B0, r26 \n\t"
+    "mul %B1, %A2 \n\t"
+    "add r27, r1 \n\t"
+    "adc %A0, r26 \n\t"
+    "adc %B0, r26 \n\t"
+    "lsl r27 \n\t"
+    "adc %A0, r26 \n\t"
+    "adc %B0, r26 \n\t"
+    "clr r1 \n\t"
+    : "=&r" (out)
+    : "r" (x), "r" (y)
+    : "r0", "r1", "r26" , "r27" //clobbers: Technically these are either scratch registers or always 0 registers, but I'm making sure the compiler knows just in case. R26 is __zero_reg__, R27 is a temporary register.
+    );
+    return out;
+}
 
 #else //_NO_ASM
 
-static inline void MultiU16X8toH16(uint16_t& intRes, uint8_t& charIn1, uint16_t& intIn2)
+FORCE_INLINE uint16_t MUL8x16R8(uint8_t charIn1, uint16_t intIn2)
 {
-    intRes = ((uint32_t)charIn1 * (uint32_t)intIn2) >> 8;
+    return ((uint32_t)charIn1 * (uint32_t)intIn2) >> 8;
 }
 
-static inline void MultiU24X24toH16(uint16_t& intRes, uint32_t& longIn1, uint32_t& longIn2)
+FORCE_INLINE uint16_t MUL24x24R24(uint32_t longIn1, uint32_t longIn2)
 {
-    intRes = ((uint64_t)longIn1 * (uint64_t)longIn2) >> 24;
+    return ((uint64_t)longIn1 * (uint64_t)longIn2) >> 24;
 }
 
 #endif //_NO_ASM
@@ -115,8 +130,7 @@ FORCE_INLINE unsigned short calc_timer(uint16_t step_rate, uint8_t& step_loops)
     unsigned short table_address = (unsigned short)&speed_lookuptable_fast[(unsigned char)(step_rate>>8)][0];
     unsigned char tmp_step_rate = (step_rate & 0x00ff);
     uint16_t gain = (uint16_t)pgm_read_word_near(table_address+2);
-    MultiU16X8toH16(timer, tmp_step_rate, gain);
-    timer = (unsigned short)pgm_read_word_near(table_address) - timer;
+    timer = (unsigned short)pgm_read_word_near(table_address) - MUL8x16R8(tmp_step_rate, gain);
   }
   else { // lower step rates
     unsigned short table_address = (unsigned short)&speed_lookuptable_slow[0][0];

+ 124 - 118
Firmware/stepper.cpp

@@ -108,12 +108,7 @@ static_assert(TMC2130_MINIMUM_DELAY 1, // this will fail to compile when non-emp
 //=============================public variables  ============================
 //===========================================================================
 block_t *current_block;  // A pointer to the block currently being traced
-bool x_min_endstop = false;
-bool x_max_endstop = false;
-bool y_min_endstop = false;
-bool y_max_endstop = false;
-bool z_min_endstop = false;
-bool z_max_endstop = false;
+
 //===========================================================================
 //=============================private variables ============================
 //===========================================================================
@@ -133,11 +128,11 @@ static uint8_t  step_loops;
 static uint16_t OCR1A_nominal;
 static uint8_t  step_loops_nominal;
 
+#ifdef VERBOSE_CHECK_HIT_ENDSTOPS
 volatile long endstops_trigsteps[3]={0,0,0};
-volatile long endstops_stepsTotal,endstops_stepsDone;
-static volatile bool endstop_x_hit=false;
-static volatile bool endstop_y_hit=false;
-static volatile bool endstop_z_hit=false;
+#endif //VERBOSE_CHECK_HIT_ENDSTOPS
+
+static volatile uint8_t endstop_hit = 0;
 #ifdef ABORT_ON_ENDSTOP_HIT_FEATURE_ENABLED
 bool abort_on_endstop_hit = false;
 #endif
@@ -147,17 +142,8 @@ bool abort_on_endstop_hit = false;
   int motor_current_setting_loud[3] = DEFAULT_PWM_MOTOR_CURRENT_LOUD;
 #endif
 
-#if ( (defined(X_MAX_PIN) && (X_MAX_PIN > -1)) || defined(TMC2130_SG_HOMING) ) && !defined(DEBUG_DISABLE_XMAXLIMIT)
-static bool old_x_max_endstop=false;
-#endif
-#if ( (defined(Y_MAX_PIN) && (Y_MAX_PIN > -1)) || defined(TMC2130_SG_HOMING) ) && !defined(DEBUG_DISABLE_YMAXLIMIT)
-static bool old_y_max_endstop=false;
-#endif
-
-static bool old_x_min_endstop=false;
-static bool old_y_min_endstop=false;
-static bool old_z_min_endstop=false;
-static bool old_z_max_endstop=false;
+static uint8_t endstop = 0;
+static uint8_t old_endstop = 0;
 
 static bool check_endstops = true;
 
@@ -206,25 +192,25 @@ extern uint16_t stepper_timer_overflow_last;
 
 void checkHitEndstops()
 {
- if( endstop_x_hit || endstop_y_hit || endstop_z_hit) {
+ if(endstop_hit) {
+#ifdef VERBOSE_CHECK_HIT_ENDSTOPS
    SERIAL_ECHO_START;
    SERIAL_ECHORPGM(MSG_ENDSTOPS_HIT);
-   if(endstop_x_hit) {
+   if(endstop_hit & _BV(X_AXIS)) {
      SERIAL_ECHOPAIR(" X:",(float)endstops_trigsteps[X_AXIS]/cs.axis_steps_per_unit[X_AXIS]);
 //     LCD_MESSAGERPGM(CAT2((MSG_ENDSTOPS_HIT), PSTR("X")));
    }
-   if(endstop_y_hit) {
+   if(endstop_hit & _BV(Y_AXIS)) {
      SERIAL_ECHOPAIR(" Y:",(float)endstops_trigsteps[Y_AXIS]/cs.axis_steps_per_unit[Y_AXIS]);
 //     LCD_MESSAGERPGM(CAT2((MSG_ENDSTOPS_HIT), PSTR("Y")));
    }
-   if(endstop_z_hit) {
+   if(endstop_hit & _BV(Z_AXIS)) {
      SERIAL_ECHOPAIR(" Z:",(float)endstops_trigsteps[Z_AXIS]/cs.axis_steps_per_unit[Z_AXIS]);
 //     LCD_MESSAGERPGM(CAT2((MSG_ENDSTOPS_HIT),PSTR("Z")));
    }
    SERIAL_ECHOLN("");
-   endstop_x_hit=false;
-   endstop_y_hit=false;
-   endstop_z_hit=false;
+#endif //VERBOSE_CHECK_HIT_ENDSTOPS
+   endstop_hit = 0;
 #if defined(ABORT_ON_ENDSTOP_HIT_FEATURE_ENABLED) && defined(SDSUPPORT)
    if (abort_on_endstop_hit)
    {
@@ -241,17 +227,17 @@ void checkHitEndstops()
 
 bool endstops_hit_on_purpose()
 {
-  bool hit = endstop_x_hit || endstop_y_hit || endstop_z_hit;
-  endstop_x_hit=false;
-  endstop_y_hit=false;
-  endstop_z_hit=false;
-  return hit;
+  uint8_t old = endstop_hit;
+  endstop_hit = 0;
+  return old;
 }
 
 bool endstop_z_hit_on_purpose()
 {
-  bool hit = endstop_z_hit;
-  endstop_z_hit=false;
+  bool hit = endstop_hit & _BV(Z_AXIS);
+CRITICAL_SECTION_START;
+  endstop_hit &= ~_BV(Z_AXIS);
+CRITICAL_SECTION_END;
   return hit;
 }
 
@@ -266,7 +252,9 @@ bool enable_z_endstop(bool check)
 {
 	bool old = check_z_endstop;
 	check_z_endstop = check;
-	endstop_z_hit = false;
+CRITICAL_SECTION_START;
+	endstop_hit &= ~_BV(Z_AXIS);
+CRITICAL_SECTION_END;
 	return old;
 }
 
@@ -501,6 +489,9 @@ FORCE_INLINE void stepper_check_endstops()
 {
   if(check_endstops) 
   {
+    uint8_t _endstop_hit = endstop_hit;
+    uint8_t _endstop = endstop;
+    uint8_t _old_endstop = old_endstop;
     #ifndef COREXY
     if ((out_bits & (1<<X_AXIS)) != 0) // stepping along -X axis
     #else
@@ -510,33 +501,35 @@ FORCE_INLINE void stepper_check_endstops()
       #if ( (defined(X_MIN_PIN) && (X_MIN_PIN > -1)) || defined(TMC2130_SG_HOMING) ) && !defined(DEBUG_DISABLE_XMINLIMIT)
       #ifdef TMC2130_SG_HOMING
         // Stall guard homing turned on
-        x_min_endstop = (READ(X_TMC2130_DIAG) != 0);
+        SET_BIT_TO(_endstop, X_AXIS, (READ(X_TMC2130_DIAG) != 0));
       #else
         // Normal homing
-        x_min_endstop = (READ(X_MIN_PIN) != X_MIN_ENDSTOP_INVERTING);
+        SET_BIT_TO(_endstop, X_AXIS, (READ(X_MIN_PIN) != X_MIN_ENDSTOP_INVERTING));
       #endif
-        if(x_min_endstop && old_x_min_endstop && (current_block->steps_x.wide > 0)) {
+        if((_endstop & _old_endstop & _BV(X_AXIS)) && (current_block->steps_x.wide > 0)) {
+#ifdef VERBOSE_CHECK_HIT_ENDSTOPS
           endstops_trigsteps[X_AXIS] = count_position[X_AXIS];
-          endstop_x_hit=true;
+#endif //VERBOSE_CHECK_HIT_ENDSTOPS
+          _endstop_hit |= _BV(X_AXIS);
           step_events_completed.wide = current_block->step_event_count.wide;
         }
-        old_x_min_endstop = x_min_endstop;
       #endif
     } else { // +direction
       #if ( (defined(X_MAX_PIN) && (X_MAX_PIN > -1)) || defined(TMC2130_SG_HOMING) ) && !defined(DEBUG_DISABLE_XMAXLIMIT)          
         #ifdef TMC2130_SG_HOMING
         // Stall guard homing turned on
-            x_max_endstop = (READ(X_TMC2130_DIAG) != 0);
+          SET_BIT_TO(_endstop, X_AXIS + 4, (READ(X_TMC2130_DIAG) != 0));
         #else
         // Normal homing
-        x_max_endstop = (READ(X_MAX_PIN) != X_MAX_ENDSTOP_INVERTING);
+          SET_BIT_TO(_endstop, X_AXIS + 4, (READ(X_MAX_PIN) != X_MAX_ENDSTOP_INVERTING));
         #endif
-        if(x_max_endstop && old_x_max_endstop && (current_block->steps_x.wide > 0)){
+        if((_endstop & _old_endstop & _BV(X_AXIS + 4)) && (current_block->steps_x.wide > 0)){
+#ifdef VERBOSE_CHECK_HIT_ENDSTOPS
           endstops_trigsteps[X_AXIS] = count_position[X_AXIS];
-          endstop_x_hit=true;
+#endif //VERBOSE_CHECK_HIT_ENDSTOPS
+          _endstop_hit |= _BV(X_AXIS);
           step_events_completed.wide = current_block->step_event_count.wide;
         }
-        old_x_max_endstop = x_max_endstop;
       #endif
     }
 
@@ -545,37 +538,39 @@ FORCE_INLINE void stepper_check_endstops()
     #else
     if ((((out_bits & (1<<X_AXIS)) != 0)&&(out_bits & (1<<Y_AXIS)) == 0)) // -Y occurs for -A and +B
     #endif
-    {        
+    {
       #if ( (defined(Y_MIN_PIN) && (Y_MIN_PIN > -1)) || defined(TMC2130_SG_HOMING) ) && !defined(DEBUG_DISABLE_YMINLIMIT)          
       #ifdef TMC2130_SG_HOMING
       // Stall guard homing turned on
-          y_min_endstop = (READ(Y_TMC2130_DIAG) != 0);
+        SET_BIT_TO(_endstop, Y_AXIS, (READ(Y_TMC2130_DIAG) != 0));
       #else
       // Normal homing
-      y_min_endstop = (READ(Y_MIN_PIN) != Y_MIN_ENDSTOP_INVERTING);
+        SET_BIT_TO(_endstop, Y_AXIS, (READ(Y_MIN_PIN) != Y_MIN_ENDSTOP_INVERTING));
       #endif
-        if(y_min_endstop && old_y_min_endstop && (current_block->steps_y.wide > 0)) {
+        if((_endstop & _old_endstop & _BV(Y_AXIS)) && (current_block->steps_y.wide > 0)) {
+#ifdef VERBOSE_CHECK_HIT_ENDSTOPS
           endstops_trigsteps[Y_AXIS] = count_position[Y_AXIS];
-          endstop_y_hit=true;
+#endif //VERBOSE_CHECK_HIT_ENDSTOPS
+          _endstop_hit |= _BV(Y_AXIS);
           step_events_completed.wide = current_block->step_event_count.wide;
         }
-        old_y_min_endstop = y_min_endstop;
       #endif
     } else { // +direction
       #if ( (defined(Y_MAX_PIN) && (Y_MAX_PIN > -1)) || defined(TMC2130_SG_HOMING) ) && !defined(DEBUG_DISABLE_YMAXLIMIT)                
         #ifdef TMC2130_SG_HOMING
         // Stall guard homing turned on
-            y_max_endstop = (READ(Y_TMC2130_DIAG) != 0);
+          SET_BIT_TO(_endstop, Y_AXIS + 4, (READ(Y_TMC2130_DIAG) != 0));
         #else
         // Normal homing
-        y_max_endstop = (READ(Y_MAX_PIN) != Y_MAX_ENDSTOP_INVERTING);
+          SET_BIT_TO(_endstop, Y_AXIS + 4, (READ(Y_MAX_PIN) != Y_MAX_ENDSTOP_INVERTING));
         #endif
-        if(y_max_endstop && old_y_max_endstop && (current_block->steps_y.wide > 0)){
+        if((_endstop & _old_endstop & _BV(Y_AXIS + 4)) && (current_block->steps_y.wide > 0)){
+#ifdef VERBOSE_CHECK_HIT_ENDSTOPS
           endstops_trigsteps[Y_AXIS] = count_position[Y_AXIS];
-          endstop_y_hit=true;
+#endif //VERBOSE_CHECK_HIT_ENDSTOPS
+          _endstop_hit |= _BV(Y_AXIS);
           step_events_completed.wide = current_block->step_event_count.wide;
         }
-        old_y_max_endstop = y_max_endstop;
       #endif
     }
 
@@ -586,20 +581,21 @@ FORCE_INLINE void stepper_check_endstops()
         #ifdef TMC2130_SG_HOMING
           // Stall guard homing turned on
 #ifdef TMC2130_STEALTH_Z
-		  if ((tmc2130_mode == TMC2130_MODE_SILENT) && !(tmc2130_sg_homing_axes_mask & 0x04))
-	          z_min_endstop = (READ(Z_MIN_PIN) != Z_MIN_ENDSTOP_INVERTING);
-		  else
+          if ((tmc2130_mode == TMC2130_MODE_SILENT) && !(tmc2130_sg_homing_axes_mask & 0x04))
+            SET_BIT_TO(_endstop, Z_AXIS, (READ(Z_MIN_PIN) != Z_MIN_ENDSTOP_INVERTING));
+          else
 #endif //TMC2130_STEALTH_Z
-	          z_min_endstop = (READ(Z_MIN_PIN) != Z_MIN_ENDSTOP_INVERTING) || (READ(Z_TMC2130_DIAG) != 0);
+            SET_BIT_TO(_endstop, Z_AXIS, (READ(Z_MIN_PIN) != Z_MIN_ENDSTOP_INVERTING) || (READ(Z_TMC2130_DIAG) != 0));
         #else
-          z_min_endstop = (READ(Z_MIN_PIN) != Z_MIN_ENDSTOP_INVERTING);
+          SET_BIT_TO(_endstop, Z_AXIS, (READ(Z_MIN_PIN) != Z_MIN_ENDSTOP_INVERTING));
         #endif //TMC2130_SG_HOMING
-        if(z_min_endstop && old_z_min_endstop && (current_block->steps_z.wide > 0)) {
+        if((_endstop & _old_endstop & _BV(Z_AXIS)) && (current_block->steps_z.wide > 0)) {
+#ifdef VERBOSE_CHECK_HIT_ENDSTOPS
           endstops_trigsteps[Z_AXIS] = count_position[Z_AXIS];
-          endstop_z_hit=true;
+#endif //VERBOSE_CHECK_HIT_ENDSTOPS
+          _endstop_hit |= _BV(Z_AXIS);
           step_events_completed.wide = current_block->step_event_count.wide;
         }
-        old_z_min_endstop = z_min_endstop;
       }
       #endif
     } else { // +direction
@@ -607,46 +603,57 @@ FORCE_INLINE void stepper_check_endstops()
         #ifdef TMC2130_SG_HOMING
         // Stall guard homing turned on
 #ifdef TMC2130_STEALTH_Z
-		  if ((tmc2130_mode == TMC2130_MODE_SILENT) && !(tmc2130_sg_homing_axes_mask & 0x04))
-	          z_max_endstop = false;
-		  else
+        if ((tmc2130_mode == TMC2130_MODE_SILENT) && !(tmc2130_sg_homing_axes_mask & 0x04))
+          SET_BIT_TO(_endstop, Z_AXIS + 4, 0);
+        else
 #endif //TMC2130_STEALTH_Z
-        z_max_endstop = (READ(Z_TMC2130_DIAG) != 0);
+          SET_BIT_TO(_endstop, Z_AXIS + 4, (READ(Z_TMC2130_DIAG) != 0));
         #else
-        z_max_endstop = (READ(Z_MAX_PIN) != Z_MAX_ENDSTOP_INVERTING);
+        SET_BIT_TO(_endstop, Z_AXIS + 4, (READ(Z_MAX_PIN) != Z_MAX_ENDSTOP_INVERTING));
         #endif //TMC2130_SG_HOMING
-        if(z_max_endstop && old_z_max_endstop && (current_block->steps_z.wide > 0)) {
+        if((_endstop & _old_endstop & _BV(Z_AXIS + 4)) && (current_block->steps_z.wide > 0)) {
+#ifdef VERBOSE_CHECK_HIT_ENDSTOPS
           endstops_trigsteps[Z_AXIS] = count_position[Z_AXIS];
-          endstop_z_hit=true;
+#endif //VERBOSE_CHECK_HIT_ENDSTOPS
+          _endstop_hit |= _BV(Z_AXIS);
           step_events_completed.wide = current_block->step_event_count.wide;
         }
-        old_z_max_endstop = z_max_endstop;
       #endif
     }
+    endstop = _endstop;
+    old_endstop = _endstop; //apply current endstop state to the old endstop
+    endstop_hit = _endstop_hit;
   }
 
   // Supporting stopping on a trigger of the Z-stop induction sensor, not only for the Z-minus movements.
   #if defined(Z_MIN_PIN) && (Z_MIN_PIN > -1) && !defined(DEBUG_DISABLE_ZMINLIMIT)
   if (check_z_endstop) {
+      uint8_t _endstop_hit = endstop_hit;
+      uint8_t _endstop = endstop;
+      uint8_t _old_endstop = old_endstop;
       // Check the Z min end-stop no matter what.
       // Good for searching for the center of an induction target.
       #ifdef TMC2130_SG_HOMING
       // Stall guard homing turned on
 #ifdef TMC2130_STEALTH_Z
-		  if ((tmc2130_mode == TMC2130_MODE_SILENT) && !(tmc2130_sg_homing_axes_mask & 0x04))
-	          z_min_endstop = (READ(Z_MIN_PIN) != Z_MIN_ENDSTOP_INVERTING);
-		  else
+      if ((tmc2130_mode == TMC2130_MODE_SILENT) && !(tmc2130_sg_homing_axes_mask & 0x04))
+        SET_BIT_TO(_endstop, Z_AXIS, (READ(Z_MIN_PIN) != Z_MIN_ENDSTOP_INVERTING));
+      else
 #endif //TMC2130_STEALTH_Z
-       z_min_endstop = (READ(Z_MIN_PIN) != Z_MIN_ENDSTOP_INVERTING) || (READ(Z_TMC2130_DIAG) != 0);
+        SET_BIT_TO(_endstop, Z_AXIS, (READ(Z_MIN_PIN) != Z_MIN_ENDSTOP_INVERTING) || (READ(Z_TMC2130_DIAG) != 0));
       #else
-        z_min_endstop = (READ(Z_MIN_PIN) != Z_MIN_ENDSTOP_INVERTING);
+      SET_BIT_TO(_endstop, Z_AXIS, (READ(Z_MIN_PIN) != Z_MIN_ENDSTOP_INVERTING));
       #endif //TMC2130_SG_HOMING
-      if(z_min_endstop && old_z_min_endstop) {
+      if(_endstop & _old_endstop & _BV(Z_AXIS)) {
+#ifdef VERBOSE_CHECK_HIT_ENDSTOPS
         endstops_trigsteps[Z_AXIS] = count_position[Z_AXIS];
-        endstop_z_hit=true;
+#endif //VERBOSE_CHECK_HIT_ENDSTOPS
+        _endstop_hit |= _BV(Z_AXIS);
         step_events_completed.wide = current_block->step_event_count.wide;
       }
-      old_z_min_endstop = z_min_endstop;
+      endstop = _endstop;
+      old_endstop = _endstop; //apply current endstop state to the old endstop
+      endstop_hit = _endstop_hit;
   }
   #endif
 }
@@ -845,7 +852,7 @@ FORCE_INLINE void isr() {
       //WRITE_NC(LOGIC_ANALYZER_CH1, true);
       if (step_events_completed.wide <= current_block->accelerate_until) {
         // v = t * a   ->   acc_step_rate = acceleration_time * current_block->acceleration_rate
-        MultiU24X24toH16(acc_step_rate, acceleration_time, current_block->acceleration_rate);
+        acc_step_rate = MUL24x24R24(acceleration_time, current_block->acceleration_rate);
         acc_step_rate += uint16_t(current_block->initial_rate);
         // upper limit
         if(acc_step_rate > uint16_t(current_block->nominal_rate))
@@ -865,8 +872,7 @@ FORCE_INLINE void isr() {
 #endif
       }
       else if (step_events_completed.wide > current_block->decelerate_after) {
-        uint16_t step_rate;
-        MultiU24X24toH16(step_rate, deceleration_time, current_block->acceleration_rate);
+        uint16_t step_rate = MUL24x24R24(deceleration_time, current_block->acceleration_rate);
 
         if (step_rate > acc_step_rate) { // Check step_rate stays positive
             step_rate = uint16_t(current_block->final_rate);
@@ -1564,9 +1570,9 @@ void st_current_init() //Initialize Digipot Motor Current
 #ifdef MOTOR_CURRENT_PWM_XY_PIN
   uint8_t SilentMode = eeprom_read_byte((uint8_t*)EEPROM_SILENT);
   SilentModeMenu = SilentMode;
-    pinMode(MOTOR_CURRENT_PWM_XY_PIN, OUTPUT);
-    pinMode(MOTOR_CURRENT_PWM_Z_PIN, OUTPUT);
-    pinMode(MOTOR_CURRENT_PWM_E_PIN, OUTPUT);
+    SET_OUTPUT(MOTOR_CURRENT_PWM_XY_PIN);
+    SET_OUTPUT(MOTOR_CURRENT_PWM_Z_PIN);
+    SET_OUTPUT(MOTOR_CURRENT_PWM_E_PIN);
     if((SilentMode == SILENT_MODE_OFF) || (farm_mode) ){
 
      motor_current_setting[0] = motor_current_setting_loud[0];
@@ -1605,20 +1611,20 @@ void microstep_init()
 {
 
   #if defined(E1_MS1_PIN) && E1_MS1_PIN > -1
-  pinMode(E1_MS1_PIN,OUTPUT);
-  pinMode(E1_MS2_PIN,OUTPUT); 
+  SET_OUTPUT(E1_MS1_PIN);
+  SET_OUTPUT(E1_MS2_PIN); 
   #endif
 
   #if defined(X_MS1_PIN) && X_MS1_PIN > -1
   const uint8_t microstep_modes[] = MICROSTEP_MODES;
-  pinMode(X_MS1_PIN,OUTPUT);
-  pinMode(X_MS2_PIN,OUTPUT);  
-  pinMode(Y_MS1_PIN,OUTPUT);
-  pinMode(Y_MS2_PIN,OUTPUT);
-  pinMode(Z_MS1_PIN,OUTPUT);
-  pinMode(Z_MS2_PIN,OUTPUT);
-  pinMode(E0_MS1_PIN,OUTPUT);
-  pinMode(E0_MS2_PIN,OUTPUT);
+  SET_OUTPUT(X_MS1_PIN);
+  SET_OUTPUT(X_MS2_PIN);  
+  SET_OUTPUT(Y_MS1_PIN);
+  SET_OUTPUT(Y_MS2_PIN);
+  SET_OUTPUT(Z_MS1_PIN);
+  SET_OUTPUT(Z_MS2_PIN);
+  SET_OUTPUT(E0_MS1_PIN);
+  SET_OUTPUT(E0_MS2_PIN);
   for(int i=0;i<=4;i++) microstep_mode(i,microstep_modes[i]);
   #endif
 }
@@ -1630,22 +1636,22 @@ void microstep_ms(uint8_t driver, int8_t ms1, int8_t ms2)
 {
   if(ms1 > -1) switch(driver)
   {
-    case 0: digitalWrite( X_MS1_PIN,ms1); break;
-    case 1: digitalWrite( Y_MS1_PIN,ms1); break;
-    case 2: digitalWrite( Z_MS1_PIN,ms1); break;
-    case 3: digitalWrite(E0_MS1_PIN,ms1); break;
+    case 0: WRITE( X_MS1_PIN,ms1); break;
+    case 1: WRITE( Y_MS1_PIN,ms1); break;
+    case 2: WRITE( Z_MS1_PIN,ms1); break;
+    case 3: WRITE(E0_MS1_PIN,ms1); break;
     #if defined(E1_MS1_PIN) && E1_MS1_PIN > -1
-    case 4: digitalWrite(E1_MS1_PIN,ms1); break;
+    case 4: WRITE(E1_MS1_PIN,ms1); break;
     #endif
   }
   if(ms2 > -1) switch(driver)
   {
-    case 0: digitalWrite( X_MS2_PIN,ms2); break;
-    case 1: digitalWrite( Y_MS2_PIN,ms2); break;
-    case 2: digitalWrite( Z_MS2_PIN,ms2); break;
-    case 3: digitalWrite(E0_MS2_PIN,ms2); break;
+    case 0: WRITE( X_MS2_PIN,ms2); break;
+    case 1: WRITE( Y_MS2_PIN,ms2); break;
+    case 2: WRITE( Z_MS2_PIN,ms2); break;
+    case 3: WRITE(E0_MS2_PIN,ms2); break;
     #if defined(E1_MS2_PIN) && E1_MS2_PIN > -1
-    case 4: digitalWrite(E1_MS2_PIN,ms2); break;
+    case 4: WRITE(E1_MS2_PIN,ms2); break;
     #endif
   }
 }
@@ -1664,23 +1670,23 @@ void microstep_mode(uint8_t driver, uint8_t stepping_mode)
 
 void microstep_readings()
 {
-      SERIAL_PROTOCOLPGM("MS1,MS2 Pins\n");
+      SERIAL_PROTOCOLLNPGM("MS1,MS2 Pins");
       SERIAL_PROTOCOLPGM("X: ");
-      SERIAL_PROTOCOL(   digitalRead(X_MS1_PIN));
-      SERIAL_PROTOCOLLN( digitalRead(X_MS2_PIN));
+      SERIAL_PROTOCOL(   READ(X_MS1_PIN));
+      SERIAL_PROTOCOLLN( READ(X_MS2_PIN));
       SERIAL_PROTOCOLPGM("Y: ");
-      SERIAL_PROTOCOL(   digitalRead(Y_MS1_PIN));
-      SERIAL_PROTOCOLLN( digitalRead(Y_MS2_PIN));
+      SERIAL_PROTOCOL(   READ(Y_MS1_PIN));
+      SERIAL_PROTOCOLLN( READ(Y_MS2_PIN));
       SERIAL_PROTOCOLPGM("Z: ");
-      SERIAL_PROTOCOL(   digitalRead(Z_MS1_PIN));
-      SERIAL_PROTOCOLLN( digitalRead(Z_MS2_PIN));
+      SERIAL_PROTOCOL(   READ(Z_MS1_PIN));
+      SERIAL_PROTOCOLLN( READ(Z_MS2_PIN));
       SERIAL_PROTOCOLPGM("E0: ");
-      SERIAL_PROTOCOL(   digitalRead(E0_MS1_PIN));
-      SERIAL_PROTOCOLLN( digitalRead(E0_MS2_PIN));
+      SERIAL_PROTOCOL(   READ(E0_MS1_PIN));
+      SERIAL_PROTOCOLLN( READ(E0_MS2_PIN));
       #if defined(E1_MS1_PIN) && E1_MS1_PIN > -1
       SERIAL_PROTOCOLPGM("E1: ");
-      SERIAL_PROTOCOL(   digitalRead(E1_MS1_PIN));
-      SERIAL_PROTOCOLLN( digitalRead(E1_MS2_PIN));
+      SERIAL_PROTOCOL(   READ(E1_MS1_PIN));
+      SERIAL_PROTOCOLLN( READ(E1_MS2_PIN));
       #endif
 }
 #endif //TMC2130

+ 0 - 4
Firmware/stepper.h

@@ -70,10 +70,6 @@ void invert_z_endstop(bool endstop_invert);
 void checkStepperErrors(); //Print errors detected by the stepper
 
 extern block_t *current_block;  // A pointer to the block currently being traced
-extern bool x_min_endstop;
-extern bool x_max_endstop;
-extern bool y_min_endstop;
-extern bool y_max_endstop;
 extern volatile long count_position[NUM_AXIS];
 
 void quickStop();

+ 13 - 13
Firmware/temperature.cpp

@@ -204,7 +204,7 @@ static float analog2tempAmbient(int raw);
 #endif
 static void updateTemperaturesFromRawValues();
 
-enum TempRunawayStates
+enum TempRunawayStates : uint8_t
 {
 	TempRunaway_INACTIVE = 0,
 	TempRunaway_PREHEAT = 1,
@@ -220,12 +220,12 @@ enum TempRunawayStates
 //===========================================================================
 
 #if (defined (TEMP_RUNAWAY_BED_HYSTERESIS) && TEMP_RUNAWAY_BED_TIMEOUT > 0) || (defined (TEMP_RUNAWAY_EXTRUDER_HYSTERESIS) && TEMP_RUNAWAY_EXTRUDER_TIMEOUT > 0)
-static float temp_runaway_status[4];
-static float temp_runaway_target[4];
-static float temp_runaway_timer[4];
-static int temp_runaway_error_counter[4];
+static uint8_t temp_runaway_status[1 + EXTRUDERS];
+static float temp_runaway_target[1 + EXTRUDERS];
+static uint32_t temp_runaway_timer[1 + EXTRUDERS];
+static uint16_t temp_runaway_error_counter[1 + EXTRUDERS];
 
-static void temp_runaway_check(int _heater_id, float _target_temperature, float _current_temperature, float _output, bool _isbed);
+static void temp_runaway_check(uint8_t _heater_id, float _target_temperature, float _current_temperature, float _output, bool _isbed);
 static void temp_runaway_stop(bool isPreheat, bool isBed);
 #endif
 
@@ -615,7 +615,7 @@ void fanSpeedError(unsigned char _fan) {
 	if (get_message_level() != 0 && isPrintPaused) return;
 	//to ensure that target temp. is not set to zero in case that we are resuming print
 	if (card.sdprinting || is_usb_printing) {
-		if (heating_status != 0) {
+		if (heating_status != HeatingStatus::NO_HEATING) {
 			lcd_print_stop();
 		}
 		else {
@@ -625,7 +625,7 @@ void fanSpeedError(unsigned char _fan) {
 	else {
 		// SERIAL_PROTOCOLLNRPGM(MSG_OCTOPRINT_PAUSED); //Why pause octoprint? is_usb_printing would be true in that case, so there is no need for this.
 		setTargetHotend0(0);
-        heating_status = 0;
+        heating_status = HeatingStatus::NO_HEATING;
         fan_check_error = EFCE_REPORTED;
 	}
 	switch (_fan) {
@@ -683,7 +683,7 @@ void manage_heater()
   temp_runaway_check(0, target_temperature_bed, current_temperature_bed, (int)soft_pwm_bed, true);
 #endif
 
-  for(int e = 0; e < EXTRUDERS; e++) 
+  for(uint8_t e = 0; e < EXTRUDERS; e++) 
   {
 
 #ifdef TEMP_RUNAWAY_EXTRUDER_HYSTERESIS
@@ -1240,15 +1240,15 @@ void tp_init()
 }
 
 #if (defined (TEMP_RUNAWAY_BED_HYSTERESIS) && TEMP_RUNAWAY_BED_TIMEOUT > 0) || (defined (TEMP_RUNAWAY_EXTRUDER_HYSTERESIS) && TEMP_RUNAWAY_EXTRUDER_TIMEOUT > 0)
-void temp_runaway_check(int _heater_id, float _target_temperature, float _current_temperature, float _output, bool _isbed)
+void temp_runaway_check(uint8_t _heater_id, float _target_temperature, float _current_temperature, float _output, bool _isbed)
 {
      float __delta;
 	float __hysteresis = 0;
-	int __timeout = 0;
+	uint16_t __timeout = 0;
 	bool temp_runaway_check_active = false;
 	static float __preheat_start[2] = { 0,0}; //currently just bed and one extruder
-	static int __preheat_counter[2] = { 0,0};
-	static int __preheat_errors[2] = { 0,0};
+	static uint8_t __preheat_counter[2] = { 0,0};
+	static uint8_t __preheat_errors[2] = { 0,0};
 		
 
 	if (_millis() - temp_runaway_timer[_heater_id] > 2000)

+ 7 - 5
Firmware/temperature.h

@@ -23,9 +23,8 @@
 
 #include "Marlin.h"
 #include "planner.h"
-#ifdef PID_ADD_EXTRUSION_RATE
-  #include "stepper.h"
-#endif
+
+#include "stepper.h"
 
 #include "config.h"
 
@@ -91,7 +90,10 @@ extern bool bedPWMDisabled;
 
 #ifdef PIDTEMP
   extern int pid_cycle, pid_number_of_cycles;
-  extern float Kc,_Kp,_Ki,_Kd;
+  extern float _Kp,_Ki,_Kd;
+#ifdef PID_ADD_EXTRUSION_RATE
+  extern float Kc;
+#endif
   extern bool pid_tuning_finished;
   float scalePID_i(float i);
   float scalePID_d(float d);
@@ -166,7 +168,7 @@ static inline void setTargetHotendSafe(const float &celsius, uint8_t extruder)
 // Doesn't save FLASH when not inlined.
 static inline void setAllTargetHotends(const float &celsius)
 {
-    for(int i=0;i<EXTRUDERS;i++) setTargetHotend(celsius,i);
+    for(uint8_t i = 0; i < EXTRUDERS; i++) setTargetHotend(celsius, i);
 }
 
 FORCE_INLINE void setTargetBed(const float &celsius) {  

+ 14 - 15
Firmware/tmc2130.cpp

@@ -8,6 +8,7 @@
 #include "ultralcd.h"
 #include "language.h"
 #include "spi.h"
+#include "Timer.h"
 
 #define TMC2130_GCONF_NORMAL 0x00000000 // spreadCycle
 #define TMC2130_GCONF_SGSENS 0x00003180 // spreadCycle with stallguard (stall activates DIAG0 and DIAG1 [pushpull])
@@ -71,7 +72,8 @@ uint16_t tmc2130_sg_cnt[4] = {0, 0, 0, 0};
 bool tmc2130_sg_change = false;
 #endif
 
-bool skip_debug_msg = false;
+//used for triggering a periodic check (1s) of the overtemperature pre-warning flag at ~120C (+-20C)
+ShortTimer tmc2130_overtemp_timer;
 
 #define DBG(args...)
 //printf_P(args)
@@ -392,16 +394,13 @@ bool tmc2130_wait_standstill_xy(int timeout)
 	return standstill;
 }
 
-
 void tmc2130_check_overtemp()
 {
-	static uint32_t checktime = 0;
-	if (_millis() - checktime > 1000 )
+	if (tmc2130_overtemp_timer.expired(1000) || !tmc2130_overtemp_timer.running())
 	{
 		for (uint_least8_t i = 0; i < 4; i++)
 		{
 			uint32_t drv_status = 0;
-			skip_debug_msg = true;
 			tmc2130_rd(i, TMC2130_REG_DRV_STATUS, &drv_status);
 			if (drv_status & ((uint32_t)1 << 26))
 			{ // BIT 26 - over temp prewarning ~120C (+-20C)
@@ -413,7 +412,7 @@ void tmc2130_check_overtemp()
 			}
 
 		}
-		checktime = _millis();
+		tmc2130_overtemp_timer.start();
 #ifdef DEBUG_CRASHDET_COUNTERS
 		tmc2130_sg_change = true;
 #endif
@@ -472,8 +471,8 @@ void tmc2130_setup_chopper(uint8_t axis, uint8_t mres, uint8_t current_h, uint8_
         intpol = 0;
     }
 #endif
-//	DBG(_n("tmc2130_setup_chopper(axis=%hhd, mres=%hhd, curh=%hhd, curr=%hhd\n"), axis, mres, current_h, current_r);
-//	DBG(_n(" toff=%hhd, hstr=%hhd, hend=%hhd, tbl=%hhd\n"), toff, hstrt, hend, tbl);
+//	DBG(_n("tmc2130_setup_chopper(axis=%d, mres=%d, curh=%d, curr=%d\n"), axis, mres, current_h, current_r);
+//	DBG(_n(" toff=%d, hstr=%d, hend=%d, tbl=%d\n"), toff, hstrt, hend, tbl);
 	if (current_r <= 31)
 	{
 		tmc2130_wr_CHOPCONF(axis, toff, hstrt, hend, fd3, 0, rndtf, chm, tbl, 1, 0, 0, 0, mres, intpol, dedge, 0);
@@ -512,7 +511,7 @@ void tmc2130_print_currents()
 
 void tmc2130_set_pwm_ampl(uint8_t axis, uint8_t pwm_ampl)
 {
-//	DBG(_n("tmc2130_set_pwm_ampl(axis=%hhd, pwm_ampl=%hhd\n"), axis, pwm_ampl);
+//	DBG(_n("tmc2130_set_pwm_ampl(axis=%d, pwm_ampl=%d\n"), axis, pwm_ampl);
 	tmc2130_pwm_ampl[axis] = pwm_ampl;
 	if (((axis == 0) || (axis == 1)) && (tmc2130_mode == TMC2130_MODE_SILENT))
 		tmc2130_wr_PWMCONF(axis, tmc2130_pwm_ampl[axis], tmc2130_pwm_grad[axis], tmc2130_pwm_freq[axis], tmc2130_pwm_auto[axis], 0, 0);
@@ -520,7 +519,7 @@ void tmc2130_set_pwm_ampl(uint8_t axis, uint8_t pwm_ampl)
 
 void tmc2130_set_pwm_grad(uint8_t axis, uint8_t pwm_grad)
 {
-//	DBG(_n("tmc2130_set_pwm_grad(axis=%hhd, pwm_grad=%hhd\n"), axis, pwm_grad);
+//	DBG(_n("tmc2130_set_pwm_grad(axis=%d, pwm_grad=%d\n"), axis, pwm_grad);
 	tmc2130_pwm_grad[axis] = pwm_grad;
 	if (((axis == 0) || (axis == 1)) && (tmc2130_mode == TMC2130_MODE_SILENT))
 		tmc2130_wr_PWMCONF(axis, tmc2130_pwm_ampl[axis], tmc2130_pwm_grad[axis], tmc2130_pwm_freq[axis], tmc2130_pwm_auto[axis], 0, 0);
@@ -894,7 +893,7 @@ void tmc2130_set_wave(uint8_t axis, uint8_t amp, uint8_t fac1000)
 {
 // TMC2130 wave compression algorithm
 // optimized for minimal memory requirements
-//	printf_P(PSTR("tmc2130_set_wave %hhd %hhd\n"), axis, fac1000);
+//	printf_P(PSTR("tmc2130_set_wave %d %d\n"), axis, fac1000);
 	if (fac1000 < TMC2130_WAVE_FAC1000_MIN) fac1000 = 0;
 	if (fac1000 > TMC2130_WAVE_FAC1000_MAX) fac1000 = TMC2130_WAVE_FAC1000_MAX;
 	float fac = 0;
@@ -908,11 +907,11 @@ void tmc2130_set_wave(uint8_t axis, uint8_t amp, uint8_t fac1000)
 	uint8_t x[3] = {255,255,255};  //X segment bounds (MSLUTSEL)
 	uint8_t s = 0;                 //current segment
 	int8_t b;                      //encoded bit value
-    int8_t dA;                     //delta value
-	int i;                         //microstep index
+	int8_t dA;                     //delta value
+	uint8_t i = 0;                         //microstep index
 	uint32_t reg = 0;              //tmc2130 register
 	tmc2130_wr_MSLUTSTART(axis, 0, amp);
-	for (i = 0; i < 256; i++)
+	do
 	{
 		if ((i & 0x1f) == 0)
 			reg = 0;
@@ -964,7 +963,7 @@ void tmc2130_set_wave(uint8_t axis, uint8_t amp, uint8_t fac1000)
 		else
 			reg >>= 1;
 //		printf("%3d\t%3d\t%2d\t%2d\t%2d\t%2d    %08x\n", i, vA, dA, b, w[s], s, reg);
-	}
+	} while (i++ != 255);
 	tmc2130_wr_MSLUTSEL(axis, x[0], x[1], x[2], w[0], w[1], w[2], w[3]);
 }
 

+ 57 - 91
Firmware/ultralcd.cpp

@@ -55,7 +55,7 @@
 
 
 int clock_interval = 0;
-
+static ShortTimer NcTime;
 static void lcd_sd_updir();
 static void lcd_mesh_bed_leveling_settings();
 #ifdef LCD_BL_PIN
@@ -78,16 +78,14 @@ LcdCommands lcd_commands_type = LcdCommands::Idle;
 static uint8_t lcd_commands_step = 0;
 
 CustomMsg custom_message_type = CustomMsg::Status;
-unsigned int custom_message_state = 0;
-
+uint8_t custom_message_state = 0;
 
 bool isPrintPaused = false;
 uint8_t farm_mode = 0;
-int farm_timer = 8;
-uint8_t farm_status = 0;
+uint8_t farm_timer = 8;
 bool printer_connected = true;
 
-unsigned long display_time; //just timer for showing pid finished message on lcd;
+static ShortTimer display_time; //just timer for showing pid finished message on lcd;
 float pid_temp = DEFAULT_PID_TEMP;
 
 static bool forceMenuExpire = false;
@@ -99,8 +97,7 @@ static float manual_feedrate[] = MANUAL_FEEDRATE;
 /* !Configuration settings */
 
 uint8_t lcd_status_message_level;
-char lcd_status_message[LCD_WIDTH + 1] = ""; //////WELCOME!
-unsigned char firstrun = 1;
+char lcd_status_message[LCD_WIDTH + 1] = WELCOME_MSG;
 
 static uint8_t lay1cal_filament = 0;
 
@@ -127,7 +124,7 @@ static void lcd_control_temperature_menu();
 #ifdef TMC2130
 static void lcd_settings_linearity_correction_menu_save();
 #endif
-static void prusa_stat_printerstatus(int _status);
+static void prusa_stat_printerstatus(uint8_t _status);
 static void prusa_stat_farm_number();
 static void prusa_stat_diameter();
 static void prusa_stat_temperatures();
@@ -161,8 +158,8 @@ static void lcd_belttest_v();
 static void lcd_selftest_v();
 
 #ifdef TMC2130
-static void reset_crash_det(unsigned char axis);
-static bool lcd_selfcheck_axis_sg(unsigned char axis);
+static void reset_crash_det(uint8_t axis);
+static bool lcd_selfcheck_axis_sg(uint8_t axis);
 #else
 static bool lcd_selfcheck_axis(int _axis, int _travel);
 static bool lcd_selfcheck_pulleys(int axis);
@@ -206,8 +203,8 @@ enum class TestError : uint_least8_t
     FsensorLevel
 };
 
-static int  lcd_selftest_screen(TestScreen screen, int _progress, int _progress_scale, bool _clear, int _delay);
-static void lcd_selftest_screen_step(int _row, int _col, int _state, const char *_name, const char *_indicator);
+static uint8_t  lcd_selftest_screen(TestScreen screen, uint8_t _progress, uint8_t _progress_scale, bool _clear, uint16_t _delay);
+static void lcd_selftest_screen_step(uint8_t _row, uint8_t _col, uint8_t _state, const char *_name, const char *_indicator);
 static bool lcd_selftest_manual_fan_check(int _fan, bool check_opposite,
 	bool _default=false);
 
@@ -456,7 +453,7 @@ void lcdui_print_percent_done(void)
 	const char* src = is_usb_printing?_N("USB"):(IS_SD_PRINTING?_N(" SD"):_N("   "));
 	char per[4];
 	bool num = IS_SD_PRINTING || (PRINTER_ACTIVE && (print_percent_done_normal != PRINT_PERCENT_DONE_INIT));
-	if (!num || heating_status) // either not printing or heating
+	if (!num || heating_status != HeatingStatus::NO_HEATING) // either not printing or heating
 	{
 		const int8_t sheetNR = eeprom_read_byte(&(EEPROM_Sheets_base->active_sheet));
 		const int8_t nextSheet = eeprom_next_initialized_sheet(sheetNR);
@@ -469,7 +466,7 @@ void lcdui_print_percent_done(void)
 			return; //do not also print the percentage
 		}
 	}
-	sprintf_P(per, num?_N("%3hhd"):_N("---"), calc_percent_done());
+	sprintf_P(per, num?_N("%3d"):_N("---"), calc_percent_done());
 	lcd_printf_P(_N("%3S%3s%%"), src, per);
 }
 
@@ -573,7 +570,7 @@ void lcdui_print_time(void)
 //! @Brief Print status line on status screen
 void lcdui_print_status_line(void)
 {
-    if (heating_status) { // If heating flag, show progress of heating
+    if (heating_status != HeatingStatus::NO_HEATING) { // If heating flag, show progress of heating
         heating_status_counter++;
         if (heating_status_counter > 13) {
             heating_status_counter = 0;
@@ -581,24 +578,24 @@ void lcdui_print_status_line(void)
         lcd_set_cursor(7, 3);
         lcd_space(13);
 
-        for (unsigned int dots = 0; dots < heating_status_counter; dots++) {
+        for (uint8_t dots = 0; dots < heating_status_counter; dots++) {
             lcd_putc_at(7 + dots, 3, '.');
         }
         switch (heating_status) {
-        case 1:
+        case HeatingStatus::EXTRUDER_HEATING:
             lcd_puts_at_P(0, 3, _T(MSG_HEATING));
             break;
-        case 2:
+        case HeatingStatus::EXTRUDER_HEATING_COMPLETE:
             lcd_puts_at_P(0, 3, _T(MSG_HEATING_COMPLETE));
-            heating_status = 0;
+            heating_status = HeatingStatus::NO_HEATING;
             heating_status_counter = 0;
             break;
-        case 3:
+        case HeatingStatus::BED_HEATING:
             lcd_puts_at_P(0, 3, _T(MSG_BED_HEATING));
             break;
-        case 4:
+        case HeatingStatus::BED_HEATING_COMPLETE:
             lcd_puts_at_P(0, 3, _T(MSG_BED_DONE));
-            heating_status = 0;
+            heating_status = HeatingStatus::NO_HEATING;
             heating_status_counter = 0;
             break;
         default:
@@ -608,15 +605,14 @@ void lcdui_print_status_line(void)
     else if ((IS_SD_PRINTING) && (custom_message_type == CustomMsg::Status)) { // If printing from SD, show what we are printing
 		const char* longFilenameOLD = (card.longFilename[0] ? card.longFilename : card.filename);
         if(strlen(longFilenameOLD) > LCD_WIDTH) {
-            int inters = 0;
-            int gh = scrollstuff;
-            while (((gh - scrollstuff) < LCD_WIDTH) && (inters == 0)) {
+            uint8_t gh = scrollstuff;
+            while (((gh - scrollstuff) < LCD_WIDTH)) {
                 if (longFilenameOLD[gh] == '\0') {
                     lcd_set_cursor(gh - scrollstuff, 3);
                     lcd_print(longFilenameOLD[gh - 1]);
                     scrollstuff = 0;
                     gh = scrollstuff;
-                    inters = 1;
+                    break;
                 } else {
                     lcd_set_cursor(gh - scrollstuff, 3);
                     lcd_print(longFilenameOLD[gh - 1]);
@@ -644,8 +640,7 @@ void lcdui_print_status_line(void)
             } else {
                 if (custom_message_state == 3)
                 {
-                    lcd_puts_P(_T(WELCOME_MSG));
-                    lcd_setstatuspgm(_T(WELCOME_MSG));
+                    lcd_setstatuspgm(MSG_WELCOME);
                     custom_message_type = CustomMsg::Status;
                 }
                 if (custom_message_state > 3 && custom_message_state <= 10 ) {
@@ -692,7 +687,7 @@ void lcdui_print_status_line(void)
     }
 
     // Fill the rest of line to have nice and clean output
-    for(int fillspace = 0; fillspace < LCD_WIDTH; fillspace++)
+    for(uint8_t fillspace = 0; fillspace < LCD_WIDTH; fillspace++)
         if ((lcd_status_message[fillspace] <= 31 ))
             lcd_print(' ');
 }
@@ -773,21 +768,6 @@ void lcdui_print_status_screen(void)
 // Main status screen. It's up to the implementation specific part to show what is needed. As this is very display dependent
 void lcd_status_screen()                          // NOT static due to using inside "Marlin_main" module ("manage_inactivity()")
 {
-	if (firstrun == 1) 
-	{
-		firstrun = 0;
-		if(lcd_status_message_level == 0)
-		{
-			strncpy_P(lcd_status_message, _T(WELCOME_MSG), LCD_WIDTH);
-			lcd_finishstatus();
-		}
-		if (eeprom_read_byte((uint8_t *)EEPROM_TOTALTIME) == 255 && eeprom_read_byte((uint8_t *)EEPROM_TOTALTIME + 1) == 255 && eeprom_read_byte((uint8_t *)EEPROM_TOTALTIME + 2) == 255 && eeprom_read_byte((uint8_t *)EEPROM_TOTALTIME + 3) == 255)
-		{
-			eeprom_update_dword((uint32_t *)EEPROM_TOTALTIME, 0);
-			eeprom_update_dword((uint32_t *)EEPROM_FILAMENTUSED, 0);
-		}
-	}
-
 #ifdef ULTIPANEL_FEEDMULTIPLY
 	// Dead zone at 100% feedrate
 	if ((feedmultiply < 100 && (feedmultiply + int(lcd_encoder)) > 100) ||
@@ -1164,7 +1144,7 @@ void lcd_commands()
 
 		if (lcd_commands_step == 1 && !blocks_queued() && cmd_buffer_empty())
 		{
-			lcd_setstatuspgm(_T(WELCOME_MSG));
+			lcd_setstatuspgm(MSG_WELCOME);
 			lcd_commands_step = 0;
 			lcd_commands_type = 0;
 			if (eeprom_read_byte((uint8_t*)EEPROM_WIZARD_ACTIVE) == 1) {
@@ -1253,7 +1233,7 @@ void lcd_commands()
                 lcd_commands_step = 1;
                 break;
             case 1:
-                lcd_setstatuspgm(_T(WELCOME_MSG));
+                lcd_setstatuspgm(MSG_WELCOME);
                 lcd_commands_step = 0;
                 lcd_commands_type = LcdCommands::Idle;
                 if (eeprom_read_byte((uint8_t*)EEPROM_WIZARD_ACTIVE) == 1)
@@ -1343,11 +1323,11 @@ void lcd_commands()
 			else {
 				SERIAL_ECHOPGM("Invalid PID cal. results. Not stored to EEPROM.");
 			}
-			display_time = _millis();
+			display_time.start();
 			lcd_commands_step = 1;
 		}
-		if ((lcd_commands_step == 1) && ((_millis()- display_time)>2000)) { //calibration finished message
-			lcd_setstatuspgm(_T(WELCOME_MSG));
+		if ((lcd_commands_step == 1) && display_time.expired(2000)) { //calibration finished message
+			lcd_setstatuspgm(MSG_WELCOME);
 			custom_message_type = CustomMsg::Status;
 			pid_temp = DEFAULT_PID_TEMP;
 			lcd_commands_step = 0;
@@ -1384,8 +1364,6 @@ void lcd_pause_usb_print()
     SERIAL_PROTOCOLLNRPGM(MSG_OCTOPRINT_PAUSE);
 }
 
-
-float move_menu_scale;
 static void lcd_move_menu_axis();
 
 
@@ -2706,7 +2684,7 @@ void lcd_menu_statistics()
 			"%S:\n"
 			"%18.2fm \n"
 			"%S:\n"
-			"%10ldh %02hhdm %02hhds"
+			"%10ldh %02dm %02ds"
 		    ),
             _i("Filament used"), _met,  ////MSG_FILAMENT_USED c=19
             _i("Print time"), _h, _m, _s);  ////MSG_PRINT_TIME c=19
@@ -2728,7 +2706,7 @@ void lcd_menu_statistics()
 			"%S:\n"
 			"%18.2fm \n"
 			"%S:\n"
-			"%10ldd %02hhdh %02hhdm"
+			"%10ldd %02dh %02dm"
             ),
             _i("Total filament"), _filament_m,  ////MSG_TOTAL_FILAMENT c=19
             _i("Total print time"), _days, _hours, _minutes);  ////MSG_TOTAL_PRINT_TIME c=19
@@ -2737,7 +2715,7 @@ void lcd_menu_statistics()
 }
 
 
-static void _lcd_move(const char *name, int axis, int min, int max)
+static void _lcd_move(const char *name, uint8_t axis, int min, int max)
 {
     if (homing_flag || mesh_bed_leveling_flag)
     {
@@ -2763,7 +2741,7 @@ static void _lcd_move(const char *name, int axis, int min, int max)
 		refresh_cmd_timeout();
 		if (! planner_queue_full())
 		{
-			current_position[axis] += float((int)lcd_encoder) * move_menu_scale;
+			current_position[axis] += float((int)lcd_encoder);
 			if (min_software_endstops && current_position[axis] < min) current_position[axis] = min;
 			if (max_software_endstops && current_position[axis] > max) current_position[axis] = max;
 			lcd_encoder = 0;
@@ -2791,7 +2769,7 @@ void lcd_move_e()
 			refresh_cmd_timeout();
 			if (! planner_queue_full())
 			{
-				current_position[E_AXIS] += float((int)lcd_encoder) * move_menu_scale;
+				current_position[E_AXIS] += float((int)lcd_encoder);
 				lcd_encoder = 0;
 				plan_buffer_line_curposXYZE(manual_feedrate[E_AXIS] / 60);
 				lcd_draw_update = 1;
@@ -3832,7 +3810,7 @@ static void lcd_show_sensors_state()
 	uint8_t idler_state = STATE_NA;
 
 	pinda_state = READ(Z_MIN_PIN);
-	if (mmu_enabled && ((_millis() - mmu_last_finda_response) < 1000ul) )
+	if (mmu_enabled && mmu_last_finda_response.expired(1000))
 	{
 		finda_state = mmu_finda;
 	}
@@ -3913,7 +3891,7 @@ static void prusa_statistics_case0(uint8_t statnr){
 	prusa_stat_printinfo();
 }
 
-void prusa_statistics(int _message, uint8_t _fil_nr) {
+void prusa_statistics(uint8_t _message, uint8_t _fil_nr) {
 #ifdef DEBUG_DISABLE_PRUSA_STATISTICS
 	return;
 #endif //DEBUG_DISABLE_PRUSA_STATISTICS
@@ -3944,7 +3922,6 @@ void prusa_statistics(int _message, uint8_t _fil_nr) {
 		break;
 
 	case 1:		// 1 heating
-		farm_status = 2;
 		SERIAL_ECHO('{');
 		prusa_stat_printerstatus(2);
 		prusa_stat_farm_number();
@@ -3953,7 +3930,6 @@ void prusa_statistics(int _message, uint8_t _fil_nr) {
 		break;
 
 	case 2:		// heating done
-		farm_status = 3;
 		SERIAL_ECHO('{');
 		prusa_stat_printerstatus(3);
 		prusa_stat_farm_number();
@@ -3963,7 +3939,6 @@ void prusa_statistics(int _message, uint8_t _fil_nr) {
 
 		if (IS_SD_PRINTING || loading_flag)
 		{
-			farm_status = 4;
 			SERIAL_ECHO('{');
 			prusa_stat_printerstatus(4);
 			prusa_stat_farm_number();
@@ -4059,7 +4034,7 @@ void prusa_statistics(int _message, uint8_t _fil_nr) {
 
 }
 
-static void prusa_stat_printerstatus(int _status)
+static void prusa_stat_printerstatus(uint8_t _status)
 {
 	SERIAL_ECHOPGM("[PRN:");
 	SERIAL_ECHO(_status);
@@ -4228,13 +4203,6 @@ void lcd_move_menu_axis()
 	MENU_END();
 }
 
-static void lcd_move_menu_1mm()
-{
-  move_menu_scale = 1.0;
-  lcd_move_menu_axis();
-}
-
-
 void EEPROM_save(int pos, uint8_t* value, uint8_t size)
 {
   do
@@ -4492,7 +4460,6 @@ static void lcd_language_menu()
 
 void lcd_mesh_bedleveling()
 {
-	mesh_bed_run_from_menu = true;
 	enquecommand_P(PSTR("G80"));
 	lcd_return_to_status();
 }
@@ -4707,7 +4674,7 @@ void lcd_v2_calibration()
 	    bool loaded = false;
 	    if (fsensor_enabled && ir_sensor_detected)
 	    {
-	        loaded = (digitalRead(IR_SENSOR_PIN) == 0);
+	        loaded = !READ(IR_SENSOR_PIN);
 	    }
 	    else
 	    {
@@ -5041,7 +5008,7 @@ void lcd_wizard(WizState state)
 
 		msg = _T(MSG_WIZARD_DONE);
 		lcd_reset_alert_level();
-		lcd_setstatuspgm(_T(WELCOME_MSG));
+		lcd_setstatuspgm(MSG_WELCOME);
 		lcd_return_to_status(); 
 		break;
 
@@ -5660,7 +5627,7 @@ static void lcd_settings_menu()
 
 	if (!PRINTER_ACTIVE || isPrintPaused)
     {
-	    MENU_ITEM_SUBMENU_P(_i("Move axis"), lcd_move_menu_1mm);////MSG_MOVE_AXIS c=18
+	    MENU_ITEM_SUBMENU_P(_i("Move axis"), lcd_move_menu_axis);////MSG_MOVE_AXIS c=18
 	    MENU_ITEM_GCODE_P(_i("Disable steppers"), PSTR("M84"));////MSG_DISABLE_STEPPERS c=18
     }
 
@@ -6308,7 +6275,7 @@ void unload_filament(bool automatic)
 
 	lcd_update_enable(true);
 
-	lcd_setstatuspgm(_T(WELCOME_MSG));
+	lcd_setstatuspgm(MSG_WELCOME);
 	custom_message_type = CustomMsg::Status;
 
 }
@@ -7032,7 +6999,7 @@ void lcd_print_stop()
 
     finishAndDisableSteppers(); //M84
 
-    lcd_setstatuspgm(_T(WELCOME_MSG));
+    lcd_setstatuspgm(MSG_WELCOME);
     custom_message_type = CustomMsg::Status;
 
     planner_abort_hard(); //needs to be done since plan_buffer_line resets waiting_inside_plan_buffer_line_print_aborted to false. Also copies current to destination.
@@ -7333,7 +7300,7 @@ static void lcd_selftest_v()
 
 bool lcd_selftest()
 {
-	int _progress = 0;
+	uint8_t _progress = 0;
 	bool _result = true;
 	bool _swapped_fan = false;
 #ifdef IR_SENSOR_ANALOG
@@ -7601,14 +7568,14 @@ bool lcd_selftest()
 
 #ifdef TMC2130
 
-static void reset_crash_det(unsigned char axis) {
+static void reset_crash_det(uint8_t axis) {
 	current_position[axis] += 10;
 	plan_buffer_line_curposXYZE(manual_feedrate[0] / 60);
 	st_synchronize();
 	if (eeprom_read_byte((uint8_t*)EEPROM_CRASH_DET)) tmc2130_sg_stop_on_crash = true;
 }
 
-static bool lcd_selfcheck_axis_sg(unsigned char axis) {
+static bool lcd_selfcheck_axis_sg(uint8_t axis) {
 // each axis length is measured twice	
 	float axis_length, current_position_init, current_position_final;
 	float measured_axis_length[2];
@@ -7731,7 +7698,7 @@ static bool lcd_selfcheck_axis(int _axis, int _travel)
 //	printf_P(PSTR("lcd_selfcheck_axis %d, %d\n"), _axis, _travel);
 	bool _stepdone = false;
 	bool _stepresult = false;
-	int _progress = 0;
+	uint8_t _progress = 0;
 	int _travel_done = 0;
 	int _err_endstop = 0;
 	int _lcd_refresh = 0;
@@ -7942,14 +7909,14 @@ static bool lcd_selfcheck_endstops()
 
 static bool lcd_selfcheck_check_heater(bool _isbed)
 {
-	int _counter = 0;
-	int _progress = 0;
+	uint8_t _counter = 0;
+	uint8_t _progress = 0;
 	bool _stepresult = false;
 	bool _docycle = true;
 
 	int _checked_snapshot = (_isbed) ? degBed() : degHotend(0);
 	int _opposite_snapshot = (_isbed) ? degHotend(0) : degBed();
-	int _cycles = (_isbed) ? 180 : 60; //~ 90s / 30s
+	uint8_t _cycles = (_isbed) ? 180 : 60; //~ 90s / 30s
 
 	target_temperature[0] = (_isbed) ? 0 : 200;
 	target_temperature_bed = (_isbed) ? 100 : 0;
@@ -8370,7 +8337,7 @@ static FanCheck lcd_selftest_fan_auto(int _fan)
 
 #endif //FANCHECK
 
-static int lcd_selftest_screen(TestScreen screen, int _progress, int _progress_scale, bool _clear, int _delay)
+static uint8_t lcd_selftest_screen(TestScreen screen, uint8_t _progress, uint8_t _progress_scale, bool _clear, uint16_t _delay)
 {
 
 	lcd_update_enable(false);
@@ -8442,7 +8409,7 @@ static int lcd_selftest_screen(TestScreen screen, int _progress, int _progress_s
 	return (_progress >= _progress_scale * 2) ? 0 : _progress;
 }
 
-static void lcd_selftest_screen_step(int _row, int _col, int _state, const char *_name_PROGMEM, const char *_indicator)
+static void lcd_selftest_screen_step(uint8_t _row, uint8_t _col, uint8_t _state, const char *_name_PROGMEM, const char *_indicator)
 {
 	lcd_set_cursor(_col, _row);
     uint8_t strlenNameP = strlen_P(_name_PROGMEM);
@@ -8497,7 +8464,7 @@ static bool check_file(const char* filename) {
 	cmdqueue_serial_disabled = false;
 	card.printingHasFinished();
 
-	lcd_setstatuspgm(_T(WELCOME_MSG));
+	lcd_setstatuspgm(MSG_WELCOME);
 	lcd_finishstatus();
 	return result;
 }
@@ -8583,7 +8550,7 @@ void ultralcd_init()
 #endif
 
 #if defined (SDSUPPORT) && defined(SDCARDDETECT) && (SDCARDDETECT > 0)
-  pinMode(SDCARDDETECT, INPUT);
+  SET_INPUT(SDCARDDETECT);
   WRITE(SDCARDDETECT, HIGH);
   lcd_oldcardstatus = IS_SD_INSERTED;
 #endif//(SDCARDDETECT > 0)
@@ -8599,10 +8566,10 @@ void lcd_printer_connected() {
 }
 
 static void lcd_send_status() {
-	if (farm_mode && no_response && ((_millis() - NcTime) > (NC_TIME * 1000))) {
+	if (farm_mode && no_response && (NcTime.expired(NC_TIME * 1000))) {
 		//send important status messages periodicaly
 		prusa_statistics(important_status, saved_filament_type);
-		NcTime = _millis();
+		NcTime.start();
 #ifdef FARM_CONNECT_MESSAGE
 		lcd_connect_printer();
 #endif //FARM_CONNECT_MESSAGE
@@ -8778,7 +8745,6 @@ void menu_lcd_longpress_func(void)
 #endif
         || menu_menu == lcd_support_menu
         ){
-            move_menu_scale = 1.0;
             menu_submenu(lcd_move_z);
         } else {
             // otherwise consume the long press as normal click
@@ -8839,7 +8805,7 @@ void menu_lcd_lcdupdate_func(void)
 				card.initsd(false); //delay the sorting to the sd menu. Otherwise, removing the SD card while sorting will not menu_back()
 				card.presort_flag = true; //force sorting of the SD menu
 			}
-			LCD_MESSAGERPGM(_T(WELCOME_MSG));
+			LCD_MESSAGERPGM(MSG_WELCOME);
 			bMain=false;                       // flag (i.e. 'fake parameter') for 'lcd_sdcard_menu()' function
 			menu_submenu(lcd_sdcard_menu);
 			lcd_timeoutToStatus.start();

+ 2 - 4
Firmware/ultralcd.h

@@ -47,7 +47,7 @@ void lcd_pause_print();
 void lcd_pause_usb_print();
 void lcd_resume_print();
 void lcd_print_stop();
-void prusa_statistics(int _message, uint8_t _col_nr = 0);
+void prusa_statistics(uint8_t _message, uint8_t _col_nr = 0);
 void lcd_load_filament_color_check();
 //void lcd_mylang();
 
@@ -126,11 +126,9 @@ enum class CustomMsg : uint_least8_t
 };
 
 extern CustomMsg custom_message_type;
-extern unsigned int custom_message_state;
+extern uint8_t custom_message_state;
 
 extern uint8_t farm_mode;
-extern int farm_timer;
-extern uint8_t farm_status;
 
 extern bool UserECoolEnabled();
 extern bool FarmOrUserECool();

+ 1 - 1
Firmware/xflash_dump.cpp

@@ -59,7 +59,7 @@ static void __attribute__((noinline)) xfdump_dump_core(dump_header_t& hdr, uint3
 
     // sample SP/PC
     hdr.sp = SP;
-    GETPC(&hdr.pc);
+    hdr.pc = GETPC();
 
     // write header
     static_assert(sizeof(hdr) <= 256, "header is larger than a single page write");