diff --git a/Firmware/Marlin.h b/Firmware/Marlin.h index baadf9966..c393471b8 100644 --- a/Firmware/Marlin.h +++ b/Firmware/Marlin.h @@ -360,7 +360,12 @@ extern uint8_t print_percent_done_normal; extern uint32_t print_time_remaining_normal; extern uint8_t print_percent_done_silent; extern uint32_t print_time_remaining_silent; + #define PRINT_TIME_REMAINING_INIT 0xffff + +extern uint16_t mcode_in_progress; +extern uint16_t gcode_in_progress; + #define PRINT_PERCENT_DONE_INIT 0xff #define PRINTER_ACTIVE (IS_SD_PRINTING || is_usb_printing || isPrintPaused || (custom_message_type == CUSTOM_MSG_TYPE_TEMCAL) || saved_printing || (lcd_commands_type == LCD_COMMAND_V2_CAL) || card.paused || mmu_print_saved) diff --git a/Firmware/Marlin_main.cpp b/Firmware/Marlin_main.cpp index ee40d0b31..4094c24ff 100644 --- a/Firmware/Marlin_main.cpp +++ b/Firmware/Marlin_main.cpp @@ -1962,8 +1962,8 @@ void loop() checkHitEndstops(); lcd_update(0); #ifdef FILAMENT_SENSOR - if (mcode_in_progress != 600) //M600 not in progress - fsensor_update(); + if (mcode_in_progress != 600 && !mmu_enabled) //M600 not in progress + fsensor_update(); #endif //FILAMENT_SENSOR #ifdef TMC2130 tmc2130_check_overtemp(); @@ -3092,7 +3092,7 @@ static void gcode_M600(bool automatic, float x_position, float y_position, float st_synchronize(); //Beep, manage nozzle heater and wait for user to start unload filament - if (!automatic) M600_wait_for_user(); + if(!mmu_enabled) M600_wait_for_user(); lcd_change_fil_state = 0; @@ -3117,6 +3117,8 @@ static void gcode_M600(bool automatic, float x_position, float y_position, float if (!automatic) M600_check_state(); + lcd_update_enable(true); + //Not let's go back to print fanSpeed = fanSpeedBckp; @@ -3137,12 +3139,6 @@ static void gcode_M600(bool automatic, float x_position, float y_position, float FILAMENTCHANGE_ZFEED, active_extruder); st_synchronize(); - //Unretract - current_position[E_AXIS] = current_position[E_AXIS] - e_shift; - plan_buffer_line(lastpos[X_AXIS], lastpos[Y_AXIS], lastpos[Z_AXIS], current_position[E_AXIS], - FILAMENTCHANGE_RFEED, active_extruder); - st_synchronize(); - //Set E position to original plan_set_e_position(lastpos[E_AXIS]); @@ -3164,15 +3160,21 @@ void gcode_M701() { printf_P(PSTR("gcode_M701 begin\n")); - if (mmu_enabled) - extr_adj(mmu_extruder);//loads current extruder + if (mmu_enabled) + { + extr_adj(tmp_extruder);//loads current extruder + mmu_extruder = tmp_extruder; + } else { enable_z(); custom_message_type = CUSTOM_MSG_TYPE_F_LOAD; #ifdef FILAMENT_SENSOR - fsensor_oq_meassure_start(40); + if (mmu_enabled == false) + { + fsensor_oq_meassure_start(40); + } #endif //FILAMENT_SENSOR lcd_setstatuspgm(_T(MSG_LOADING_FILAMENT)); @@ -3214,15 +3216,18 @@ void gcode_M701() custom_message_type = CUSTOM_MSG_TYPE_STATUS; #ifdef FILAMENT_SENSOR - fsensor_oq_meassure_stop(); - - if (!fsensor_oq_result()) + if (mmu_enabled == false) { - bool disable = lcd_show_fullscreen_message_yes_no_and_wait_P(_i("Fil. sensor response is poor, disable it?"), false, true); - lcd_update_enable(true); - lcd_update(2); - if (disable) - fsensor_disable(); + fsensor_oq_meassure_stop(); + + if (!fsensor_oq_result()) + { + bool disable = lcd_show_fullscreen_message_yes_no_and_wait_P(_i("Fil. sensor response is poor, disable it?"), false, true); + lcd_update_enable(true); + lcd_update(2); + if (disable) + fsensor_disable(); + } } #endif //FILAMENT_SENSOR } @@ -3410,7 +3415,9 @@ void process_commands() } #endif //BACKLASH_Y #endif //TMC2130 - + else if (code_seen("FSENSOR_RECOVER")) { + fsensor_restore_print_and_continue(); + } else if(code_seen("PRUSA")){ if (code_seen("Ping")) { //PRUSA Ping if (farm_mode) { @@ -6746,7 +6753,7 @@ if((eSoundMode==e_SOUND_MODE_LOUD)||(eSoundMode==e_SOUND_MODE_ONCE)) case 701: //M701: load filament { if (mmu_enabled && code_seen('E')) - mmu_extruder = code_value(); + tmp_extruder = code_value(); gcode_M701(); } break; @@ -6805,7 +6812,7 @@ if (mmu_enabled) mmu_command(MMU_CMD_T0 + tmp_extruder); manage_response(true, true); - + mmu_command(MMU_CMD_C0); mmu_extruder = tmp_extruder; //filament change is finished if (*(strchr_pointer + index) == '?')// for single material usage with mmu @@ -7303,38 +7310,41 @@ static void handleSafetyTimer() void manage_inactivity(bool ignore_stepper_queue/*=false*/) //default argument set in Marlin.h { #ifdef FILAMENT_SENSOR - if (mcode_in_progress != 600) //M600 not in progress + if (mmu_enabled == false) { - if (!moves_planned() && !IS_SD_PRINTING && !is_usb_printing && (lcd_commands_type != LCD_COMMAND_V2_CAL)) + if (mcode_in_progress != 600) //M600 not in progress { - if (fsensor_check_autoload()) + if (!moves_planned() && !IS_SD_PRINTING && !is_usb_printing && (lcd_commands_type != LCD_COMMAND_V2_CAL)) { - fsensor_autoload_check_stop(); - if (degHotend0() > EXTRUDE_MINTEMP) + if (fsensor_check_autoload()) { -if((eSoundMode==e_SOUND_MODE_LOUD)||(eSoundMode==e_SOUND_MODE_ONCE)) - tone(BEEPER, 1000); - delay_keep_alive(50); - noTone(BEEPER); - loading_flag = true; - enquecommand_front_P((PSTR("M701"))); - } - else - { - lcd_update_enable(false); - lcd_clear(); - lcd_set_cursor(0, 0); - lcd_puts_P(_T(MSG_ERROR)); - lcd_set_cursor(0, 2); - lcd_puts_P(_T(MSG_PREHEAT_NOZZLE)); - delay(2000); - lcd_clear(); - lcd_update_enable(true); + fsensor_autoload_check_stop(); + if (degHotend0() > EXTRUDE_MINTEMP) + { + if ((eSoundMode == e_SOUND_MODE_LOUD) || (eSoundMode == e_SOUND_MODE_ONCE)) + tone(BEEPER, 1000); + delay_keep_alive(50); + noTone(BEEPER); + loading_flag = true; + enquecommand_front_P((PSTR("M701"))); + } + else + { + lcd_update_enable(false); + lcd_clear(); + lcd_set_cursor(0, 0); + lcd_puts_P(_T(MSG_ERROR)); + lcd_set_cursor(0, 2); + lcd_puts_P(_T(MSG_PREHEAT_NOZZLE)); + delay(2000); + lcd_clear(); + lcd_update_enable(true); + } } } + else + fsensor_autoload_check_stop(); } - else - fsensor_autoload_check_stop(); } #endif //FILAMENT_SENSOR @@ -8844,8 +8854,7 @@ void M600_check_state() { //Wait for user to check the state lcd_change_fil_state = 0; - - while ((lcd_change_fil_state == 0)||(lcd_change_fil_state != 1)){ + while (lcd_change_fil_state != 1){ lcd_change_fil_state = 0; KEEPALIVE_STATE(PAUSED_FOR_USER); lcd_alright(); @@ -8869,10 +8878,9 @@ void M600_check_state() // Everything good default: lcd_change_success(); - lcd_update_enable(true); break; } - } + } } void M600_wait_for_user() { @@ -9035,7 +9043,7 @@ if((eSoundMode==e_SOUND_MODE_LOUD)||(eSoundMode==e_SOUND_MODE_ONCE)) fsensor_disable(); } #endif //FILAMENT_SENSOR - + lcd_update_enable(false); } #define FIL_LOAD_LENGTH 60 diff --git a/Firmware/eeprom.h b/Firmware/eeprom.h index 28498f139..54a216488 100644 --- a/Firmware/eeprom.h +++ b/Firmware/eeprom.h @@ -144,6 +144,7 @@ // Sound Mode //#define EEPROM_SOUND_MODE (EEPROM_EXTRUDEMULTIPLY-1) // uint8 #define EEPROM_SOUND_MODE (EEPROM_UVLO_TINY_Z_MICROSTEPS-1) // uint8 +#define EEPROM_AUTO_DEPLETE (EEPROM_SOUND_MODE-1) //bool // !!!!! // !!!!! this is end of EEPROM section ... all updates MUST BE inserted before this mark !!!!! diff --git a/Firmware/menu.cpp b/Firmware/menu.cpp index b63629edf..bd5238269 100644 --- a/Firmware/menu.cpp +++ b/Firmware/menu.cpp @@ -9,15 +9,20 @@ #include "Configuration.h" #include "Marlin.h" #include "ultralcd.h" +#include "language.h" extern int32_t lcd_encoder; +#define MENU_DEPTH_MAX 4 -menu_record_t menu_stack[MENU_DEPTH_MAX]; +static menu_record_t menu_stack[MENU_DEPTH_MAX]; uint8_t menu_data[MENU_DATA_SIZE]; +#ifndef __AVR__ +#error "menu_data is non-portable to non 8bit processor" +#endif uint8_t menu_depth = 0; @@ -33,6 +38,8 @@ uint8_t menu_leaving = 0; menu_func_t menu_menu = 0; +static_assert(sizeof(menu_data)>= sizeof(menu_data_edit_t),"menu_data_edit_t doesn't fit into menu_data"); + void menu_goto(menu_func_t menu, const uint32_t encoder, const bool feedback, bool reset_menu_state) { @@ -86,7 +93,7 @@ void menu_back(void) } } -void menu_back_no_reset(void) +static void menu_back_no_reset(void) { if (menu_depth > 0) { @@ -120,7 +127,7 @@ void menu_submenu(menu_func_t submenu) } } -void menu_submenu_no_reset(menu_func_t submenu) +static void menu_submenu_no_reset(menu_func_t submenu) { if (menu_depth <= MENU_DEPTH_MAX) { @@ -158,7 +165,7 @@ int menu_draw_item_printf_P(char type_char, const char* format, ...) } */ -int menu_draw_item_puts_P(char type_char, const char* str) +static int menu_draw_item_puts_P(char type_char, const char* str) { lcd_set_cursor(0, menu_row); int cnt = lcd_printf_P(PSTR("%c%-18S%c"), (lcd_encoder == menu_item)?'>':' ', str, type_char); @@ -263,8 +270,13 @@ const char menu_fmt_float31[] PROGMEM = "%c%.12S:%s%+06.1f"; const char menu_fmt_float13[] PROGMEM = "%c%.12S:%s%+06.3f"; +const char menu_fmt_float13off[] PROGMEM = "%c%.12S:%s%"; -void menu_draw_int3(char chr, const char* str, int16_t val) +template +static void menu_draw_P(char chr, const char* str, int16_t val); + +template<> +void menu_draw_P(char chr, const char* str, int16_t val) { int text_len = strlen_P(str); if (text_len > 15) text_len = 15; @@ -274,6 +286,27 @@ void menu_draw_int3(char chr, const char* str, int16_t val) lcd_printf_P(menu_fmt_int3, chr, str, spaces, val); } +template<> +void menu_draw_P(char chr, const char* str, int16_t val) +{ + menu_data_edit_t* _md = (menu_data_edit_t*)&(menu_data[0]); + int text_len = strlen_P(str); + if (text_len > 15) text_len = 15; + char spaces[21]; + strcpy_P(spaces, menu_20x_space); + spaces[12 - text_len] = 0; + float factor = 1.0 + static_cast(val) / 1000.0; + if (val <= _md->minEditValue) + { + lcd_printf_P(menu_fmt_float13off, chr, str, spaces); + lcd_puts_P(_i(" [off]")); + } + else + { + lcd_printf_P(menu_fmt_float13, chr, str, spaces, factor); + } +} + //draw up to 12 chars of text, ':' and float number in format +123.0 void menu_draw_float31(char chr, const char* str, float val) { @@ -296,16 +329,8 @@ void menu_draw_float13(char chr, const char* str, float val) lcd_printf_P(menu_fmt_float13, chr, str, spaces, val); } -typedef struct -{ - //Variables used when editing values. - const char* editLabel; - void* editValue; - int32_t minEditValue; - int32_t maxEditValue; -} menu_data_edit_t; - -void _menu_edit_int3(void) +template +static void _menu_edit_P(void) { menu_data_edit_t* _md = (menu_data_edit_t*)&(menu_data[0]); if (lcd_draw_update) @@ -313,16 +338,17 @@ void _menu_edit_int3(void) if (lcd_encoder < _md->minEditValue) lcd_encoder = _md->minEditValue; if (lcd_encoder > _md->maxEditValue) lcd_encoder = _md->maxEditValue; lcd_set_cursor(0, 1); - menu_draw_int3(' ', _md->editLabel, (int)lcd_encoder); + menu_draw_P(' ', _md->editLabel, (int)lcd_encoder); } if (LCD_CLICKED) { - *((int*)(_md->editValue)) = (int)lcd_encoder; + *((T)(_md->editValue)) = lcd_encoder; menu_back_no_reset(); } } -uint8_t menu_item_edit_int3(const char* str, int16_t* pval, int16_t min_val, int16_t max_val) +template +uint8_t menu_item_edit_P(const char* str, T pval, int16_t min_val, int16_t max_val) { menu_data_edit_t* _md = (menu_data_edit_t*)&(menu_data[0]); if (menu_item == menu_line) @@ -330,11 +356,11 @@ uint8_t menu_item_edit_int3(const char* str, int16_t* pval, int16_t min_val, int if (lcd_draw_update) { lcd_set_cursor(0, menu_row); - menu_draw_int3((lcd_encoder == menu_item)?'>':' ', str, *pval); + menu_draw_P((lcd_encoder == menu_item)?'>':' ', str, *pval); } if (menu_clicked && (lcd_encoder == menu_item)) { - menu_submenu_no_reset(_menu_edit_int3); + menu_submenu_no_reset(_menu_edit_P); _md->editLabel = str; _md->editValue = pval; _md->minEditValue = min_val; @@ -347,6 +373,9 @@ uint8_t menu_item_edit_int3(const char* str, int16_t* pval, int16_t min_val, int return 0; } +template uint8_t menu_item_edit_P(const char* str, int16_t *pval, int16_t min_val, int16_t max_val); +template uint8_t menu_item_edit_P(const char* str, uint8_t *pval, int16_t min_val, int16_t max_val); + #undef _menu_data diff --git a/Firmware/menu.h b/Firmware/menu.h index 06c901035..73e4925a6 100644 --- a/Firmware/menu.h +++ b/Firmware/menu.h @@ -4,9 +4,7 @@ #include -#define MENU_DEPTH_MAX 4 #define MENU_DATA_SIZE 32 -#define MENU_DATA_EDIT_SIZE 12 //Function pointer to menu functions. typedef void (*menu_func_t)(void); @@ -17,7 +15,14 @@ typedef struct int8_t position; } menu_record_t; -extern menu_record_t menu_stack[MENU_DEPTH_MAX]; +typedef struct +{ + //Variables used when editing values. + const char* editLabel; + void* editValue; + int32_t minEditValue; + int32_t maxEditValue; +} menu_data_edit_t; extern uint8_t menu_data[MENU_DATA_SIZE]; @@ -50,21 +55,16 @@ extern void menu_end(void); extern void menu_back(void); -extern void menu_back_no_reset(void); - extern void menu_back_if_clicked(void); extern void menu_back_if_clicked_fb(void); extern void menu_submenu(menu_func_t submenu); -extern void menu_submenu_no_reset(menu_func_t submenu); - extern uint8_t menu_item_ret(void); //extern int menu_draw_item_printf_P(char type_char, const char* format, ...); -extern int menu_draw_item_puts_P(char type_char, const char* str); //int menu_draw_item_puts_P_int16(char type_char, const char* str, int16_t val, ); @@ -91,17 +91,16 @@ extern const char menu_fmt_int3[]; extern const char menu_fmt_float31[]; -extern void menu_draw_int3(char chr, const char* str, int16_t val); extern void menu_draw_float31(char chr, const char* str, float val); extern void menu_draw_float13(char chr, const char* str, float val); -extern void _menu_edit_int3(void); -#define MENU_ITEM_EDIT_int3_P(str, pval, minval, maxval) do { if (menu_item_edit_int3(str, pval, minval, maxval)) return; } while (0) +#define MENU_ITEM_EDIT_int3_P(str, pval, minval, maxval) do { if (menu_item_edit_P(str, pval, minval, maxval)) return; } while (0) //#define MENU_ITEM_EDIT_int3_P(str, pval, minval, maxval) MENU_ITEM_EDIT(int3, str, pval, minval, maxval) -extern uint8_t menu_item_edit_int3(const char* str, int16_t* pval, int16_t min_val, int16_t max_val); +template +extern uint8_t menu_item_edit_P(const char* str, T pval, int16_t min_val, int16_t max_val); #endif //_MENU_H diff --git a/Firmware/mmu.cpp b/Firmware/mmu.cpp index 703b5b4c3..fd70da1c6 100644 --- a/Firmware/mmu.cpp +++ b/Firmware/mmu.cpp @@ -7,22 +7,22 @@ #include "uart2.h" #include "temperature.h" #include "Configuration_prusa.h" +#include "fsensor.h" +#include "cardreader.h" +#include "ultralcd.h" +#include "sound.h" - -extern const char* lcd_display_message_fullscreen_P(const char *msg); -extern void lcd_show_fullscreen_message_and_wait_P(const char *msg); -extern int8_t lcd_show_fullscreen_message_yes_no_and_wait_P(const char *msg, bool allow_timeouting = true, bool default_yes = false); -extern void lcd_return_to_status(); -extern void lcd_wait_for_heater(); -extern char choose_extruder_menu(); - +#define CHECK_FINDA ((IS_SD_PRINTING || is_usb_printing) && (mcode_in_progress != 600) && !saved_printing && e_active()) #define MMU_TODELAY 100 #define MMU_TIMEOUT 10 +#define MMU_CMD_TIMEOUT 300000ul //5min timeout for mmu commands (except P0) +#define MMU_P0_TIMEOUT 3000ul //timeout for P0 command: 3seconds #define MMU_HWRESET #define MMU_RST_PIN 76 +#define MMU_REQUIRED_FW_BUILDNR 81 bool mmu_enabled = false; @@ -138,6 +138,9 @@ void mmu_loop(void) { fscanf_P(uart2io, PSTR("%u"), &mmu_buildnr); //scan buildnr from buffer printf_P(PSTR("MMU => '%dok'\n"), mmu_buildnr); + bool version_valid = mmu_check_version(); + if (!version_valid) mmu_show_warning(); + else puts_P(PSTR("MMU version valid")); puts_P(PSTR("MMU <= 'P0'")); mmu_puts_P(PSTR("P0\n")); //send 'read finda' request mmu_state = -4; @@ -170,9 +173,21 @@ void mmu_loop(void) mmu_printf_P(PSTR("L%d\n"), filament); mmu_state = 3; // wait for response } + else if (mmu_cmd == MMU_CMD_C0) + { + printf_P(PSTR("MMU <= 'C0'\n")); + mmu_puts_P(PSTR("C0\n")); //send 'continue loading' + mmu_state = 3; + } + else if (mmu_cmd == MMU_CMD_U0) + { + printf_P(PSTR("MMU <= 'U0'\n")); + mmu_puts_P(PSTR("U0\n")); //send 'unload current filament' + mmu_state = 3; + } mmu_cmd = 0; } - else if ((mmu_last_response + 1000) < millis()) //request every 1s + else if ((mmu_last_response + 300) < millis()) //request every 300ms { puts_P(PSTR("MMU <= 'P0'")); mmu_puts_P(PSTR("P0\n")); //send 'read finda' request @@ -184,11 +199,18 @@ void mmu_loop(void) { fscanf_P(uart2io, PSTR("%hhu"), &mmu_finda); //scan finda from buffer printf_P(PSTR("MMU => '%dok'\n"), mmu_finda); + //printf_P(PSTR("Eact: %d\n"), int(e_active())); + if (!mmu_finda && CHECK_FINDA && fsensor_enabled) { + fsensor_stop_and_save_print(); + enquecommand_front_P(PSTR("FSENSOR_RECOVER")); //then recover + if (lcd_autoDeplete) enquecommand_front_P(PSTR("M600 AUTO")); //save print and run M600 command + else enquecommand_front_P(PSTR("M600")); //save print and run M600 command + } mmu_state = 1; if (mmu_cmd == 0) mmu_ready = true; } - else if ((mmu_last_request + 30000) < millis()) + else if ((mmu_last_request + MMU_P0_TIMEOUT) < millis()) { //resend request after timeout (30s) mmu_state = 1; } @@ -196,12 +218,12 @@ void mmu_loop(void) case 3: //response to commands T0-T4 if (mmu_rx_ok() > 0) { - printf_P(PSTR("MMU => 'ok'\n"), mmu_finda); + printf_P(PSTR("MMU => 'ok'\n")); mmu_ready = true; mmu_state = 1; } - else if ((mmu_last_request + 30000) < millis()) - { //resend request after timeout (30s) + else if ((mmu_last_request + MMU_CMD_TIMEOUT) < millis()) + { //resend request after timeout (5 min) mmu_state = 1; } return; @@ -297,7 +319,7 @@ void manage_response(bool move_axes, bool turn_off_nozzle) } st_synchronize(); mmu_print_saved = true; - + printf_P(PSTR("MMU not responding\n")); hotend_temp_bckp = degTargetHotend(active_extruder); if (move_axes) { z_position_bckp = current_position[Z_AXIS]; @@ -319,23 +341,28 @@ void manage_response(bool move_axes, bool turn_off_nozzle) if (turn_off_nozzle) { //set nozzle target temperature to 0 setAllTargetHotends(0); - printf_P(PSTR("MMU not responding\n")); - lcd_show_fullscreen_message_and_wait_P(_i("MMU needs user attention. Please press knob to resume nozzle target temperature.")); - setTargetHotend(hotend_temp_bckp, active_extruder); - while ((degTargetHotend(active_extruder) - degHotend(active_extruder)) > 5) { - delay_keep_alive(1000); - lcd_wait_for_heater(); - } } } - lcd_display_message_fullscreen_P(_i("Check MMU. Fix the issue and then press button on MMU unit.")); + lcd_display_message_fullscreen_P(_i("MMU needs user attention. Fix the issue and then press button on MMU unit.")); delay_keep_alive(1000); } else if (mmu_print_saved) { - printf_P(PSTR("MMU start responding\n")); - lcd_clear(); - lcd_display_message_fullscreen_P(_i("MMU OK. Resuming...")); + printf_P(PSTR("MMU starts responding\n")); + if (turn_off_nozzle) + { + lcd_clear(); + setTargetHotend(hotend_temp_bckp, active_extruder); + lcd_display_message_fullscreen_P(_i("MMU OK. Resuming temperature...")); + delay_keep_alive(3000); + while ((degTargetHotend(active_extruder) - degHotend(active_extruder)) > 5) + { + delay_keep_alive(1000); + lcd_wait_for_heater(); + } + } if (move_axes) { + lcd_clear(); + lcd_display_message_fullscreen_P(_i("MMU OK. Resuming position...")); current_position[X_AXIS] = x_position_bckp; current_position[Y_AXIS] = y_position_bckp; plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], 50, active_extruder); @@ -345,6 +372,8 @@ void manage_response(bool move_axes, bool turn_off_nozzle) st_synchronize(); } else { + lcd_clear(); + lcd_display_message_fullscreen_P(_i("MMU OK. Resuming...")); delay_keep_alive(1000); //delay just for showing MMU OK message for a while in case that there are no xyz movements } } @@ -377,33 +406,79 @@ void mmu_load_to_nozzle() if (!saved_e_relative_mode) axis_relative_modes[E_AXIS] = false; } +void mmu_M600_wait_and_beep() { + //Beep and wait for user to remove old filament and prepare new filament for load + + KEEPALIVE_STATE(PAUSED_FOR_USER); + + int counterBeep = 0; + lcd_display_message_fullscreen_P(_i("Remove old filament and press the knob to start loading new filament.")); + bool bFirst=true; + + while (!lcd_clicked()){ + manage_heater(); + manage_inactivity(true); + + #if BEEPER > 0 + if (counterBeep == 500) { + counterBeep = 0; + } + SET_OUTPUT(BEEPER); + if (counterBeep == 0) { + if((eSoundMode==e_SOUND_MODE_LOUD)||((eSoundMode==e_SOUND_MODE_ONCE)&&bFirst)) + { + bFirst=false; + WRITE(BEEPER, HIGH); + } + } + if (counterBeep == 20) { + WRITE(BEEPER, LOW); + } + + counterBeep++; + #endif //BEEPER > 0 + + delay_keep_alive(4); + } + WRITE(BEEPER, LOW); +} + void mmu_M600_load_filament(bool automatic) { //load filament for mmu v2 - uint8_t filament = mmu_extruder; + bool yes = false; + tmp_extruder = mmu_extruder; if (!automatic) { - bool yes = lcd_show_fullscreen_message_yes_no_and_wait_P(_i("Do you want to switch extruder?"), false); - if(yes) filament = choose_extruder_menu(); - } + mmu_M600_wait_and_beep(); +#ifdef MMU_M600_SWITCH_EXTRUDER + yes = lcd_show_fullscreen_message_yes_no_and_wait_P(_i("Do you want to switch extruder?"), false); + if(yes) tmp_extruder = choose_extruder_menu(); + else tmp_extruder = mmu_extruder; +#else + tmp_extruder = mmu_extruder; +#endif //MMU_M600_SWITCH_EXTRUDER + } else { - filament = (filament+1)%5; + tmp_extruder = (tmp_extruder+1)%5; } lcd_update_enable(false); lcd_clear(); lcd_set_cursor(0, 1); lcd_puts_P(_T(MSG_LOADING_FILAMENT)); lcd_print(" "); - lcd_print(filament + 1); - snmm_filaments_used |= (1 << filament); //for stop print + lcd_print(tmp_extruder + 1); + snmm_filaments_used |= (1 << tmp_extruder); //for stop print -// printf_P(PSTR("T code: %d \n"), filament); -// mmu_printf_P(PSTR("T%d\n"), filament); - mmu_command(MMU_CMD_T0 + filament); +// printf_P(PSTR("T code: %d \n"), tmp_extruder); +// mmu_printf_P(PSTR("T%d\n"), tmp_extruder); + mmu_command(MMU_CMD_T0 + tmp_extruder); manage_response(false, true); - mmu_extruder = filament; //filament change is finished + mmu_command(MMU_CMD_C0); + mmu_extruder = tmp_extruder; //filament change is finished mmu_load_to_nozzle(); + st_synchronize(); current_position[E_AXIS]+= FILAMENTCHANGE_FINALFEED ; plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], 2, active_extruder); @@ -577,9 +652,8 @@ void extr_unload() current_position[E_AXIS] -= 80; plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], 2500 / 60, active_extruder); st_synchronize(); - printf_P(PSTR("U0\n")); - fprintf_P(uart2io, PSTR("U0\n")); + mmu_command(MMU_CMD_U0); // get response manage_response(false, true); @@ -820,3 +894,14 @@ void extr_unload_4() change_extr(4); extr_unload(); } + +bool mmu_check_version() +{ + return (mmu_buildnr >= MMU_REQUIRED_FW_BUILDNR); +} + +void mmu_show_warning() +{ + printf_P(PSTR("MMU2 firmware version invalid. Required version: build number %d or higher."), MMU_REQUIRED_FW_BUILDNR); + kill(_i("Please update firmware in your MMU2. Waiting for reset.")); +} diff --git a/Firmware/mmu.h b/Firmware/mmu.h index 8b338d6cf..e5aad198a 100644 --- a/Firmware/mmu.h +++ b/Firmware/mmu.h @@ -26,6 +26,8 @@ extern int16_t mmu_buildnr; #define MMU_CMD_L2 0x22 #define MMU_CMD_L3 0x23 #define MMU_CMD_L4 0x24 +#define MMU_CMD_C0 0x30 +#define MMU_CMD_U0 0x40 extern int mmu_puts_P(const char* str); @@ -52,7 +54,7 @@ extern void manage_response(bool move_axes, bool turn_off_nozzle); extern void mmu_load_to_nozzle(); extern void mmu_M600_load_filament(bool automatic); - +extern void mmu_M600_wait_and_beep(); extern void extr_mov(float shift, float feed_rate); extern void change_extr(int extr); @@ -77,3 +79,7 @@ extern void extr_unload_1(); extern void extr_unload_2(); extern void extr_unload_3(); extern void extr_unload_4(); + +extern bool mmu_check_version(); +extern void mmu_show_warning(); + diff --git a/Firmware/planner.cpp b/Firmware/planner.cpp index ddbee23ec..98a62b9b8 100644 --- a/Firmware/planner.cpp +++ b/Firmware/planner.cpp @@ -494,6 +494,23 @@ void getHighESpeed() } #endif +bool e_active() +{ + unsigned char e_active = 0; + block_t *block; + if(block_buffer_tail != block_buffer_head) + { + uint8_t block_index = block_buffer_tail; + while(block_index != block_buffer_head) + { + block = &block_buffer[block_index]; + if(block->steps_e.wide != 0) e_active++; + block_index = (block_index+1) & (BLOCK_BUFFER_SIZE - 1); + } + } + return (e_active > 0) ? true : false ; +} + void check_axes_activity() { unsigned char x_active = 0; diff --git a/Firmware/planner.h b/Firmware/planner.h index 8d648c8e8..998a3595b 100644 --- a/Firmware/planner.h +++ b/Firmware/planner.h @@ -154,7 +154,7 @@ void plan_set_position(float x, float y, float z, const float &e); void plan_set_z_position(const float &z); void plan_set_e_position(const float &e); - +extern bool e_active(); void check_axes_activity(); diff --git a/Firmware/stepper.cpp b/Firmware/stepper.cpp index c39e61e5f..8eb4d0ea7 100644 --- a/Firmware/stepper.cpp +++ b/Firmware/stepper.cpp @@ -41,6 +41,8 @@ int fsensor_counter = 0; //counter for e-steps #endif //FILAMENT_SENSOR +#include "mmu.h" + #ifdef DEBUG_STACK_MONITOR uint16_t SP_min = 0x21FF; #endif //DEBUG_STACK_MONITOR @@ -468,8 +470,11 @@ FORCE_INLINE void stepper_next_block() #endif #ifdef FILAMENT_SENSOR - fsensor_counter = 0; - fsensor_st_block_begin(current_block); + if (mmu_enabled == false) + { + fsensor_counter = 0; + fsensor_st_block_begin(current_block); + } #endif //FILAMENT_SENSOR // The busy flag is set by the plan_get_current_block() call. // current_block->busy = true; @@ -891,7 +896,10 @@ FORCE_INLINE void isr() { if (step_loops < estep_loops) estep_loops = step_loops; #ifdef FILAMENT_SENSOR - fsensor_counter += estep_loops; + if (mmu_enabled == false) + { + fsensor_counter += estep_loops; + } #endif //FILAMENT_SENSOR do { WRITE_NC(E0_STEP_PIN, !INVERT_E_STEP_PIN); @@ -1017,7 +1025,9 @@ FORCE_INLINE void isr() { // There is not enough time to fit even a single additional tick. // Tick all the extruder ticks now. #ifdef FILAMENT_SENSOR - fsensor_counter += e_steps; + if (mmu_enabled == false) { + fsensor_counter += e_steps; + } #endif //FILAMENT_SENSOR MSerial.checkRx(); // Check for serial chars. do { @@ -1039,15 +1049,17 @@ FORCE_INLINE void isr() { // If current block is finished, reset pointer if (step_events_completed.wide >= current_block->step_event_count.wide) { #ifdef FILAMENT_SENSOR - fsensor_st_block_chunk(current_block, fsensor_counter); - fsensor_counter = 0; + if (mmu_enabled == false) { + fsensor_st_block_chunk(current_block, fsensor_counter); + fsensor_counter = 0; + } #endif //FILAMENT_SENSOR current_block = NULL; plan_discard_current_block(); } #ifdef FILAMENT_SENSOR - else if (fsensor_counter >= fsensor_chunk_len) + else if ((fsensor_counter >= fsensor_chunk_len) && (mmu_enabled == false)) { fsensor_st_block_chunk(current_block, fsensor_counter); fsensor_counter = 0; diff --git a/Firmware/ultralcd.cpp b/Firmware/ultralcd.cpp index 386e7b22f..ac046b214 100644 --- a/Firmware/ultralcd.cpp +++ b/Firmware/ultralcd.cpp @@ -85,6 +85,7 @@ unsigned long display_time; //just timer for showing pid finished message on lcd float pid_temp = DEFAULT_PID_TEMP; static bool forceMenuExpire = false; +bool lcd_autoDeplete; static float manual_feedrate[] = MANUAL_FEEDRATE; @@ -121,6 +122,7 @@ static void lcd_control_temperature_preheat_pla_settings_menu(); static void lcd_control_temperature_preheat_abs_settings_menu(); static void lcd_control_motion_menu(); static void lcd_control_volumetric_menu(); +static void lcd_settings_linearity_correction_menu_save(); static void prusa_stat_printerstatus(int _status); static void prusa_stat_farm_number(); static void prusa_stat_temperatures(); @@ -534,9 +536,9 @@ void lcdui_print_extruder(void) { int chars = 0; if (mmu_extruder == tmp_extruder) - chars = lcd_printf_P(_N(" T%u"), mmu_extruder); + chars = lcd_printf_P(_N(" T%u"), mmu_extruder+1); else - chars = lcd_printf_P(_N(" %u>%u"), mmu_extruder, tmp_extruder); + chars = lcd_printf_P(_N(" %u>%u"), mmu_extruder+1, tmp_extruder+1); lcd_space(5 - chars); } @@ -1886,20 +1888,22 @@ static void lcd_menu_extruder_info() // Shutter register is an index of LASER shutter time. It is automatically controlled by the chip's internal // auto-exposure algorithm. When the chip is tracking on a good reflection surface, the Shutter is small. // When the chip is tracking on a poor reflection surface, the Shutter is large. Value ranges from 0 to 46. - - if (!fsensor_enabled) - lcd_puts_P(_N("Filament sensor\n" "is disabled.")); - else + if (mmu_enabled == false) { - if (!moves_planned() && !IS_SD_PRINTING && !is_usb_printing && (lcd_commands_type != LCD_COMMAND_V2_CAL)) - pat9125_update(); - lcd_printf_P(_N( - "Fil. Xd:%3d Yd:%3d\n" - "Int: %3d Shut: %3d" - ), - pat9125_x, pat9125_y, - pat9125_b, pat9125_s - ); + if (!fsensor_enabled) + lcd_puts_P(_N("Filament sensor\n" "is disabled.")); + else + { + if (!moves_planned() && !IS_SD_PRINTING && !is_usb_printing && (lcd_commands_type != LCD_COMMAND_V2_CAL)) + pat9125_update(); + lcd_printf_P(_N( + "Fil. Xd:%3d Yd:%3d\n" + "Int: %3d Shut: %3d" + ), + pat9125_x, pat9125_y, + pat9125_b, pat9125_s + ); + } } #endif //FILAMENT_SENSOR @@ -2094,9 +2098,7 @@ static void lcd_support_menu() uint8_t ip[4]; // 4bytes char ip_str[3*4+3+1]; // 16bytes } _menu_data_t; -#if (22 > MENU_DATA_SIZE) -#error "check MENU_DATA_SIZE definition!" -#endif + static_assert(sizeof(menu_data)>= sizeof(_menu_data_t),"_menu_data_t doesn't fit into menu_data"); _menu_data_t* _md = (_menu_data_t*)&(menu_data[0]); if (_md->status == 0 || lcd_draw_update == 2) { @@ -2425,6 +2427,7 @@ static void lcd_menu_AutoLoadFilament() } else { + static_assert(sizeof(menu_data)>=sizeof(ShortTimer), "ShortTimer doesn't fit into menu_data"); ShortTimer* ptimer = (ShortTimer*)&(menu_data[0]); if (!ptimer->running()) ptimer->start(); lcd_set_cursor(0, 0); @@ -2540,9 +2543,7 @@ static void _lcd_move(const char *name, int axis, int min, int max) bool initialized; // 1byte bool endstopsEnabledPrevious; // 1byte } _menu_data_t; -#if (2 > MENU_DATA_SIZE) -#error "check MENU_DATA_SIZE definition!" -#endif + static_assert(sizeof(menu_data)>= sizeof(_menu_data_t),"_menu_data_t doesn't fit into menu_data"); _menu_data_t* _md = (_menu_data_t*)&(menu_data[0]); if (!_md->initialized) { @@ -2746,9 +2747,7 @@ static void _lcd_babystep(int axis, const char *msg) int babystepMem[3]; // 6bytes float babystepMemMM[3]; // 12bytes } _menu_data_t; -#if (19 > MENU_DATA_SIZE) -#error "check MENU_DATA_SIZE definition!" -#endif + static_assert(sizeof(menu_data)>= sizeof(_menu_data_t),"_menu_data_t doesn't fit into menu_data"); _menu_data_t* _md = (_menu_data_t*)&(menu_data[0]); if (_md->status == 0) { @@ -2820,16 +2819,14 @@ static void lcd_babystep_z() typedef struct { // 12bytes + 9bytes = 21bytes total - uint8_t reserved[MENU_DATA_EDIT_SIZE]; //12 bytes reserved for number editing functions + menu_data_edit_t reserved; //12 bytes reserved for number editing functions int8_t status; // 1byte int16_t left; // 2byte int16_t right; // 2byte int16_t front; // 2byte int16_t rear; // 2byte } _menu_data_adjust_bed_t; -#if (21 > MENU_DATA_SIZE) -#error "check MENU_DATA_SIZE definition!" -#endif +static_assert(sizeof(menu_data)>= sizeof(_menu_data_adjust_bed_t),"_menu_data_adjust_bed_t doesn't fit into menu_data"); void lcd_adjust_bed_reset(void) { @@ -4042,15 +4039,16 @@ static void lcd_crash_mode_set() static void lcd_fsensor_state_set() { FSensorStateMenu = !FSensorStateMenu; //set also from fsensor_enable() and fsensor_disable() - if (!FSensorStateMenu) { - fsensor_disable(); - if (fsensor_autoload_enabled) - menu_submenu(lcd_filament_autoload_info); - }else{ - fsensor_enable(); - if (fsensor_not_responding) - menu_submenu(lcd_fsensor_fail); - } + if (!FSensorStateMenu) { + fsensor_disable(); + if (fsensor_autoload_enabled && !mmu_enabled) + menu_submenu(lcd_filament_autoload_info); + } + else { + fsensor_enable(); + if (fsensor_not_responding && !mmu_enabled) + menu_submenu(lcd_fsensor_fail); + } } #endif //FILAMENT_SENSOR @@ -4490,28 +4488,182 @@ void lcd_wizard(int state) { lcd_return_to_status(); lcd_update(2); } -#ifdef LINEARITY_CORRECTION + +#ifdef TMC2130 void lcd_settings_linearity_correction_menu(void) { MENU_BEGIN(); - if (menu_item_back_P(_T(MSG_MAIN))) - { - lcd_settings_menu_back(); - return; - } -// MENU_ITEM_BACK_P(_T(MSG_SETTINGS)); + MENU_ITEM_BACK_P(_T(MSG_SETTINGS)); #ifdef TMC2130_LINEARITY_CORRECTION_XYZ //tmc2130_wave_fac[X_AXIS] - int corr[4] = {tmc2130_wave_fac[X_AXIS], tmc2130_wave_fac[Y_AXIS], tmc2130_wave_fac[Z_AXIS], tmc2130_wave_fac[E_AXIS]}; - MENU_ITEM_EDIT_int3_P(_i("X-correct"), &corr[X_AXIS], TMC2130_WAVE_FAC1000_MIN-TMC2130_WAVE_FAC1000_STP, TMC2130_WAVE_FAC1000_MAX);////MSG_EXTRUDER_CORRECTION c=9 r=0 - MENU_ITEM_EDIT_int3_P(_i("Y-correct"), &corr[Y_AXIS], TMC2130_WAVE_FAC1000_MIN-TMC2130_WAVE_FAC1000_STP, TMC2130_WAVE_FAC1000_MAX);////MSG_EXTRUDER_CORRECTION c=9 r=0 - MENU_ITEM_EDIT_int3_P(_i("Z-correct"), &corr[Z_AXIS], TMC2130_WAVE_FAC1000_MIN-TMC2130_WAVE_FAC1000_STP, TMC2130_WAVE_FAC1000_MAX);////MSG_EXTRUDER_CORRECTION c=9 r=0 + MENU_ITEM_EDIT_int3_P(_i("X-correct"), &tmc2130_wave_fac[X_AXIS], TMC2130_WAVE_FAC1000_MIN-TMC2130_WAVE_FAC1000_STP, TMC2130_WAVE_FAC1000_MAX);////MSG_EXTRUDER_CORRECTION c=9 r=0 + MENU_ITEM_EDIT_int3_P(_i("Y-correct"), &tmc2130_wave_fac[Y_AXIS], TMC2130_WAVE_FAC1000_MIN-TMC2130_WAVE_FAC1000_STP, TMC2130_WAVE_FAC1000_MAX);////MSG_EXTRUDER_CORRECTION c=9 r=0 + MENU_ITEM_EDIT_int3_P(_i("Z-correct"), &tmc2130_wave_fac[Z_AXIS], TMC2130_WAVE_FAC1000_MIN-TMC2130_WAVE_FAC1000_STP, TMC2130_WAVE_FAC1000_MAX);////MSG_EXTRUDER_CORRECTION c=9 r=0 #endif //TMC2130_LINEARITY_CORRECTION_XYZ - MENU_ITEM_EDIT_int3_P(_i("E-correct"), &corr[E_AXIS], TMC2130_WAVE_FAC1000_MIN-TMC2130_WAVE_FAC1000_STP, TMC2130_WAVE_FAC1000_MAX);////MSG_EXTRUDER_CORRECTION c=9 r=0 + MENU_ITEM_EDIT_int3_P(_i("E-correct"), &tmc2130_wave_fac[E_AXIS], TMC2130_WAVE_FAC1000_MIN-TMC2130_WAVE_FAC1000_STP, TMC2130_WAVE_FAC1000_MAX);////MSG_EXTRUDER_CORRECTION c=9 r=0 MENU_END(); + if(menu_leaving) + { + lcd_settings_linearity_correction_menu_save(); + } } -#endif //LINEARITY_CORRECTION +#endif // TMC2130 + +#ifdef FILAMENT_SENSOR +#define SETTINGS_FILAMENT_SENSOR \ +do\ +{\ + if (FSensorStateMenu == 0)\ + {\ + if (fsensor_not_responding)\ + {\ + /* Filament sensor not working*/\ + MENU_ITEM_FUNCTION_P(_i("Fil. sensor [N/A]"), lcd_fsensor_state_set);/*////MSG_FSENSOR_NA c=0 r=0*/\ + MENU_ITEM_SUBMENU_P(_T(MSG_FSENS_AUTOLOAD_NA), lcd_fsensor_fail);\ + }\ + else\ + {\ + /* Filament sensor turned off, working, no problems*/\ + MENU_ITEM_FUNCTION_P(_T(MSG_FSENSOR_OFF), lcd_fsensor_state_set);\ + if (mmu_enabled == false)if (mmu_enabled == false)\ + {\ + MENU_ITEM_SUBMENU_P(_T(MSG_FSENS_AUTOLOAD_NA), lcd_filament_autoload_info);\ + }\ + }\ + }\ + else\ + {\ + /* Filament sensor turned on, working, no problems*/\ + MENU_ITEM_FUNCTION_P(_T(MSG_FSENSOR_ON), lcd_fsensor_state_set);\ + if (mmu_enabled == false)\ + {\ + if (fsensor_autoload_enabled)\ + MENU_ITEM_FUNCTION_P(_i("F. autoload [on]"), lcd_set_filament_autoload);/*////MSG_FSENS_AUTOLOAD_ON c=17 r=1*/\ + else\ + MENU_ITEM_FUNCTION_P(_i("F. autoload [off]"), lcd_set_filament_autoload);/*////MSG_FSENS_AUTOLOAD_OFF c=17 r=1*/\ + }\ + }\ +}\ +while(0) + +#else //FILAMENT_SENSOR +#define SETTINGS_FILAMENT_SENSOR do{}while(0) +#endif //FILAMENT_SENSOR + +#ifdef TMC2130 +#define SETTINGS_SILENT_MODE \ +do\ +{\ + if(!farm_mode)\ + {\ + if (SilentModeMenu == SILENT_MODE_NORMAL)\ + {\ + MENU_ITEM_FUNCTION_P(_T(MSG_STEALTH_MODE_OFF), lcd_silent_mode_set);\ + }\ + else MENU_ITEM_FUNCTION_P(_T(MSG_STEALTH_MODE_ON), lcd_silent_mode_set);\ + if (SilentModeMenu == SILENT_MODE_NORMAL)\ + {\ + if (CrashDetectMenu == 0)\ + {\ + MENU_ITEM_FUNCTION_P(_T(MSG_CRASHDETECT_OFF), lcd_crash_mode_set);\ + }\ + else MENU_ITEM_FUNCTION_P(_T(MSG_CRASHDETECT_ON), lcd_crash_mode_set);\ + }\ + else MENU_ITEM_SUBMENU_P(_T(MSG_CRASHDETECT_NA), lcd_crash_mode_info);\ + }\ +}\ +while (0) + +#else //TMC2130 +#define SETTINGS_SILENT_MODE \ +do\ +{\ + if(!farm_mode)\ + {\ + switch (SilentModeMenu)\ + {\ + case SILENT_MODE_POWER:\ + MENU_ITEM_FUNCTION_P(_T(MSG_SILENT_MODE_OFF), lcd_silent_mode_set);\ + break;\ + case SILENT_MODE_SILENT:\ + MENU_ITEM_FUNCTION_P(_T(MSG_SILENT_MODE_ON), lcd_silent_mode_set);\ + break;\ + case SILENT_MODE_AUTO:\ + MENU_ITEM_FUNCTION_P(_T(MSG_AUTO_MODE_ON), lcd_silent_mode_set);\ + break;\ + default:\ + MENU_ITEM_FUNCTION_P(_T(MSG_SILENT_MODE_OFF), lcd_silent_mode_set);\ + break; /* (probably) not needed*/\ + }\ + }\ +}\ +while (0) +#endif //TMC2130 + +#ifdef SDCARD_SORT_ALPHA +#define SETTINGS_SD \ +do\ +{\ + if (card.ToshibaFlashAir_isEnabled())\ + MENU_ITEM_FUNCTION_P(_i("SD card [flshAir]"), lcd_toshiba_flash_air_compatibility_toggle);/*////MSG_TOSHIBA_FLASH_AIR_COMPATIBILITY_ON c=19 r=1*/\ + else\ + MENU_ITEM_FUNCTION_P(_i("SD card [normal]"), lcd_toshiba_flash_air_compatibility_toggle);/*////MSG_TOSHIBA_FLASH_AIR_COMPATIBILITY_OFF c=19 r=1*/\ +\ + if (!farm_mode)\ + {\ + uint8_t sdSort;\ + EEPROM_read(EEPROM_SD_SORT, (uint8_t*)&sdSort, sizeof(sdSort));\ + switch (sdSort)\ + {\ + case SD_SORT_TIME: MENU_ITEM_FUNCTION_P(_i("Sort: [time]"), lcd_sort_type_set); break;/*////MSG_SORT_TIME c=17 r=1*/\ + case SD_SORT_ALPHA: MENU_ITEM_FUNCTION_P(_i("Sort: [alphabet]"), lcd_sort_type_set); break;/*////MSG_SORT_ALPHA c=17 r=1*/\ + default: MENU_ITEM_FUNCTION_P(_i("Sort: [none]"), lcd_sort_type_set);/*////MSG_SORT_NONE c=17 r=1*/\ + }\ + }\ +}\ +while (0) +#else // SDCARD_SORT_ALPHA +#define SETTINGS_SD \ +do\ +{\ + if (card.ToshibaFlashAir_isEnabled())\ + MENU_ITEM_FUNCTION_P(_i("SD card [flshAir]"), lcd_toshiba_flash_air_compatibility_toggle);/*////MSG_TOSHIBA_FLASH_AIR_COMPATIBILITY_ON c=19 r=1*/\ + else\ + MENU_ITEM_FUNCTION_P(_i("SD card [normal]"), lcd_toshiba_flash_air_compatibility_toggle);/*////MSG_TOSHIBA_FLASH_AIR_COMPATIBILITY_OFF c=19 r=1*/\ +}\ +while (0) +#endif // SDCARD_SORT_ALPHA + +#define SETTINGS_SOUND \ +do\ +{\ + switch(eSoundMode)\ + {\ + case e_SOUND_MODE_LOUD:\ + MENU_ITEM_FUNCTION_P(_i(MSG_SOUND_MODE_LOUD),lcd_sound_state_set);\ + break;\ + case e_SOUND_MODE_ONCE:\ + MENU_ITEM_FUNCTION_P(_i(MSG_SOUND_MODE_ONCE),lcd_sound_state_set);\ + break;\ + case e_SOUND_MODE_SILENT:\ + MENU_ITEM_FUNCTION_P(_i(MSG_SOUND_MODE_SILENT),lcd_sound_state_set);\ + break;\ + case e_SOUND_MODE_MUTE:\ + MENU_ITEM_FUNCTION_P(_i(MSG_SOUND_MODE_MUTE),lcd_sound_state_set);\ + break;\ + default:\ + MENU_ITEM_FUNCTION_P(_i(MSG_SOUND_MODE_LOUD),lcd_sound_state_set);\ + }\ +}\ +while (0) + +static void auto_deplete_switch() +{ + lcd_autoDeplete = !lcd_autoDeplete; + eeprom_update_byte((unsigned char *)EEPROM_AUTO_DEPLETE, lcd_autoDeplete); +} + static void lcd_settings_menu() { EEPROM_read(EEPROM_SILENT, (uint8_t*)&SilentModeMenu, sizeof(SilentModeMenu)); @@ -4520,71 +4672,28 @@ static void lcd_settings_menu() MENU_ITEM_SUBMENU_P(_i("Temperature"), lcd_control_temperature_menu);////MSG_TEMPERATURE c=0 r=0 if (!homing_flag) - MENU_ITEM_SUBMENU_P(_i("Move axis"), lcd_move_menu_1mm);////MSG_MOVE_AXIS c=0 r=0 + MENU_ITEM_SUBMENU_P(_i("Move axis"), lcd_move_menu_1mm);////MSG_MOVE_AXIS c=0 r=0 if (!isPrintPaused) - MENU_ITEM_GCODE_P(_i("Disable steppers"), PSTR("M84"));////MSG_DISABLE_STEPPERS c=0 r=0 + MENU_ITEM_GCODE_P(_i("Disable steppers"), PSTR("M84"));////MSG_DISABLE_STEPPERS c=0 r=0 -#ifndef TMC2130 - if (!farm_mode) - { //dont show in menu if we are in farm mode - switch (SilentModeMenu) - { - case SILENT_MODE_POWER: MENU_ITEM_FUNCTION_P(_T(MSG_SILENT_MODE_OFF), lcd_silent_mode_set); break; - case SILENT_MODE_SILENT: MENU_ITEM_FUNCTION_P(_T(MSG_SILENT_MODE_ON), lcd_silent_mode_set); break; - case SILENT_MODE_AUTO: MENU_ITEM_FUNCTION_P(_T(MSG_AUTO_MODE_ON), lcd_silent_mode_set); break; - default: MENU_ITEM_FUNCTION_P(_T(MSG_SILENT_MODE_OFF), lcd_silent_mode_set); break; // (probably) not needed - } - } -#endif //TMC2130 + SETTINGS_FILAMENT_SENSOR; -#ifdef FILAMENT_SENSOR - if (FSensorStateMenu == 0) + if (mmu_enabled) { - if (fsensor_not_responding) - { - // Filament sensor not working - MENU_ITEM_FUNCTION_P(_i("Fil. sensor [N/A]"), lcd_fsensor_state_set);////MSG_FSENSOR_NA c=0 r=0 - MENU_ITEM_SUBMENU_P(_T(MSG_FSENS_AUTOLOAD_NA), lcd_fsensor_fail); - } - else - { - // Filament sensor turned off, working, no problems - MENU_ITEM_FUNCTION_P(_T(MSG_FSENSOR_OFF), lcd_fsensor_state_set); - MENU_ITEM_SUBMENU_P(_T(MSG_FSENS_AUTOLOAD_NA), lcd_filament_autoload_info); - } + if (lcd_autoDeplete) MENU_ITEM_FUNCTION_P(_i("Auto deplete [on]"), auto_deplete_switch); + else MENU_ITEM_FUNCTION_P(_i("Auto deplete[off]"), auto_deplete_switch); } - else - { - // Filament sensor turned on, working, no problems - MENU_ITEM_FUNCTION_P(_T(MSG_FSENSOR_ON), lcd_fsensor_state_set); - if (fsensor_autoload_enabled) - MENU_ITEM_FUNCTION_P(_i("F. autoload [on]"), lcd_set_filament_autoload);////MSG_FSENS_AUTOLOAD_ON c=17 r=1 - else - MENU_ITEM_FUNCTION_P(_i("F. autoload [off]"), lcd_set_filament_autoload);////MSG_FSENS_AUTOLOAD_OFF c=17 r=1 - } -#endif //FILAMENT_SENSOR if (fans_check_enabled == true) MENU_ITEM_FUNCTION_P(_i("Fans check [on]"), lcd_set_fan_check);////MSG_FANS_CHECK_ON c=17 r=1 else MENU_ITEM_FUNCTION_P(_i("Fans check [off]"), lcd_set_fan_check);////MSG_FANS_CHECK_OFF c=17 r=1 -#ifdef TMC2130 - if(!farm_mode) - { - if (SilentModeMenu == SILENT_MODE_NORMAL) { MENU_ITEM_FUNCTION_P(_T(MSG_STEALTH_MODE_OFF), lcd_silent_mode_set); } - else MENU_ITEM_FUNCTION_P(_T(MSG_STEALTH_MODE_ON), lcd_silent_mode_set); - if (SilentModeMenu == SILENT_MODE_NORMAL) - { - if (CrashDetectMenu == 0) { MENU_ITEM_FUNCTION_P(_T(MSG_CRASHDETECT_OFF), lcd_crash_mode_set); } - else MENU_ITEM_FUNCTION_P(_T(MSG_CRASHDETECT_ON), lcd_crash_mode_set); - } - else MENU_ITEM_SUBMENU_P(_T(MSG_CRASHDETECT_NA), lcd_crash_mode_info); - } -#ifdef LINEARITY_CORRECTION + SETTINGS_SILENT_MODE; + +#if defined (TMC2130) && defined (LINEARITY_CORRECTION) MENU_ITEM_SUBMENU_P(_i("Lin. correction"), lcd_settings_linearity_correction_menu); -#endif //LINEARITY_CORRECTION -#endif //TMC2130 +#endif //LINEARITY_CORRECTION && TMC2130 if (temp_cal_active == false) MENU_ITEM_FUNCTION_P(_i("Temp. cal. [off]"), lcd_temp_calibration_set);////MSG_TEMP_CALIBRATION_OFF c=20 r=1 @@ -4605,45 +4714,9 @@ static void lcd_settings_menu() MENU_ITEM_SUBMENU_P(_i("Select language"), lcd_language_menu);////MSG_LANGUAGE_SELECT c=0 r=0 #endif //(LANG_MODE != 0) - if (card.ToshibaFlashAir_isEnabled()) - MENU_ITEM_FUNCTION_P(_i("SD card [flshAir]"), lcd_toshiba_flash_air_compatibility_toggle);////MSG_TOSHIBA_FLASH_AIR_COMPATIBILITY_ON c=19 r=1 - else - MENU_ITEM_FUNCTION_P(_i("SD card [normal]"), lcd_toshiba_flash_air_compatibility_toggle);////MSG_TOSHIBA_FLASH_AIR_COMPATIBILITY_OFF c=19 r=1 + SETTINGS_SD; + SETTINGS_SOUND; -#ifdef SDCARD_SORT_ALPHA - if (!farm_mode) - { - uint8_t sdSort; - EEPROM_read(EEPROM_SD_SORT, (uint8_t*)&sdSort, sizeof(sdSort)); - switch (sdSort) - { - case SD_SORT_TIME: MENU_ITEM_FUNCTION_P(_i("Sort: [time]"), lcd_sort_type_set); break;////MSG_SORT_TIME c=17 r=1 - case SD_SORT_ALPHA: MENU_ITEM_FUNCTION_P(_i("Sort: [alphabet]"), lcd_sort_type_set); break;////MSG_SORT_ALPHA c=17 r=1 - default: MENU_ITEM_FUNCTION_P(_i("Sort: [none]"), lcd_sort_type_set);////MSG_SORT_NONE c=17 r=1 - } - } -#endif // SDCARD_SORT_ALPHA - - -//-// -switch(eSoundMode) - { - case e_SOUND_MODE_LOUD: - MENU_ITEM_FUNCTION_P(_i(MSG_SOUND_MODE_LOUD),lcd_sound_state_set); - break; - case e_SOUND_MODE_ONCE: - MENU_ITEM_FUNCTION_P(_i(MSG_SOUND_MODE_ONCE),lcd_sound_state_set); - break; - case e_SOUND_MODE_SILENT: - MENU_ITEM_FUNCTION_P(_i(MSG_SOUND_MODE_SILENT),lcd_sound_state_set); - break; - case e_SOUND_MODE_MUTE: - MENU_ITEM_FUNCTION_P(_i(MSG_SOUND_MODE_MUTE),lcd_sound_state_set); - break; - default: - MENU_ITEM_FUNCTION_P(_i(MSG_SOUND_MODE_LOUD),lcd_sound_state_set); - } -//-// if (farm_mode) { MENU_ITEM_SUBMENU_P(PSTR("Farm number"), lcd_farm_no); @@ -4653,7 +4726,6 @@ switch(eSoundMode) MENU_END(); } -#ifdef LINEARITY_CORRECTION #ifdef TMC2130 static void lcd_ustep_linearity_menu_save() { @@ -4664,7 +4736,8 @@ static void lcd_ustep_linearity_menu_save() } #endif //TMC2130 -static void lcd_settings_menu_back() + +static void lcd_settings_linearity_correction_menu_save() { #ifdef TMC2130 bool changed = false; @@ -4679,9 +4752,8 @@ static void lcd_settings_menu_back() lcd_ustep_linearity_menu_save(); if (changed) tmc2130_init(); #endif //TMC2130 - menu_menu = lcd_main_menu; } -#endif //LINEARITY_CORRECTION + static void lcd_calibration_menu() { @@ -5560,7 +5632,7 @@ static void lcd_main_menu() else { #ifdef FILAMENT_SENSOR - if ( ((fsensor_autoload_enabled == true) && (fsensor_enabled == true))) + if ((fsensor_autoload_enabled == true) && (fsensor_enabled == true) && (mmu_enabled == false)) MENU_ITEM_SUBMENU_P(_i("AutoLoad filament"), lcd_menu_AutoLoadFilament);////MSG_AUTOLOAD_FILAMENT c=17 r=0 else #endif //FILAMENT_SENSOR @@ -5635,16 +5707,14 @@ static void lcd_colorprint_change() { static void lcd_tune_menu() { typedef struct - { // 3bytes total - // To recognize, whether the menu has been just initialized. - int8_t status; // 1byte - // Backup of extrudemultiply, to recognize, that the value has been changed and - // it needs to be applied. - int16_t extrudemultiply; // 2byte + { + menu_data_edit_t reserved; //!< reserved for number editing functions + int8_t status; //!< To recognize, whether the menu has been just initialized. + //! Backup of extrudemultiply, to recognize, that the value has been changed and + //! it needs to be applied. + int16_t extrudemultiply; } _menu_data_t; -#if (3 > MENU_DATA_SIZE) -#error "check MENU_DATA_SIZE definition!" -#endif + static_assert(sizeof(menu_data)>= sizeof(_menu_data_t),"_menu_data_t doesn't fit into menu_data"); _menu_data_t* _md = (_menu_data_t*)&(menu_data[0]); if (_md->status == 0) { @@ -6050,14 +6120,19 @@ bool lcd_selftest() { _progress = lcd_selftest_screen(8, _progress, 3, true, 2000); //bed ok #ifdef FILAMENT_SENSOR - _progress = lcd_selftest_screen(9, _progress, 3, true, 2000); //check filaments sensor - _result = lcd_selftest_fsensor(); + if (mmu_enabled == false) { + _progress = lcd_selftest_screen(9, _progress, 3, true, 2000); //check filaments sensor + _result = lcd_selftest_fsensor(); + } #endif // FILAMENT_SENSOR } if (_result) { #ifdef FILAMENT_SENSOR - _progress = lcd_selftest_screen(10, _progress, 3, true, 2000); //fil sensor OK + if (mmu_enabled == false) + { + _progress = lcd_selftest_screen(10, _progress, 3, true, 2000); //fil sensor OK + } #endif // FILAMENT_SENSOR _progress = lcd_selftest_screen(11, _progress, 3, true, 5000); //all correct } @@ -6954,6 +7029,12 @@ void menu_action_sddirectory(const char* filename) void ultralcd_init() { + { + uint8_t autoDepleteRaw = eeprom_read_byte(reinterpret_cast(EEPROM_AUTO_DEPLETE)); + if (0xff == autoDepleteRaw) lcd_autoDeplete = false; + else lcd_autoDeplete = autoDepleteRaw; + + } lcd_init(); lcd_refresh(); lcd_longpress_func = menu_lcd_longpress_func; diff --git a/Firmware/ultralcd.h b/Firmware/ultralcd.h index 6c4ac0437..c6bbb900c 100644 --- a/Firmware/ultralcd.h +++ b/Firmware/ultralcd.h @@ -46,6 +46,7 @@ void lcd_menu_statistics(); extern const char* lcd_display_message_fullscreen_P(const char *msg, uint8_t &nlines); extern const char* lcd_display_message_fullscreen_P(const char *msg); +extern void lcd_return_to_status(); extern void lcd_wait_for_click(); extern void lcd_show_fullscreen_message_and_wait_P(const char *msg); // 0: no, 1: yes, -1: timeouted @@ -112,6 +113,7 @@ extern int8_t SilentModeMenu; extern bool cancel_heatup; extern bool isPrintPaused; +extern bool lcd_autoDeplete; void lcd_ignore_click(bool b=true); diff --git a/Firmware/variants/1_75mm_MK3-EINSy10a-E3Dv6full.h b/Firmware/variants/1_75mm_MK3-EINSy10a-E3Dv6full.h index dbce6a962..4dec83550 100644 --- a/Firmware/variants/1_75mm_MK3-EINSy10a-E3Dv6full.h +++ b/Firmware/variants/1_75mm_MK3-EINSy10a-E3Dv6full.h @@ -100,7 +100,7 @@ //Silent mode limits #define SILENT_MAX_ACCEL_XY 960ul // max acceleration in silent mode in mm/s^2 -#define SILENT_MAX_FEEDRATE_XY 172 // max feedrate in mm/s +#define SILENT_MAX_FEEDRATE_XY 100 // max feedrate in mm/s //Normal mode limits #define NORMAL_MAX_ACCEL_XY 2500ul // max acceleration in normal mode in mm/s^2