diff --git a/Firmware/Marlin_main.cpp b/Firmware/Marlin_main.cpp index 92df0122..1cf7be2c 100755 --- a/Firmware/Marlin_main.cpp +++ b/Firmware/Marlin_main.cpp @@ -454,10 +454,13 @@ static void print_time_remaining_init(); static void wait_for_heater(long codenum, uint8_t extruder); static void gcode_G28(bool home_x_axis, bool home_y_axis, bool home_z_axis); static void gcode_M105(uint8_t extruder); + +#ifndef PINDA_THERMISTOR static void temp_compensation_start(); static void temp_compensation_apply(); +#endif -static bool get_PRUSA_SN(char* SN); +static uint8_t get_PRUSA_SN(char* SN); uint16_t gcode_in_progress = 0; uint16_t mcode_in_progress = 0; @@ -741,7 +744,7 @@ static void factory_reset(char level) case 2: // Level 2: Prepare for shipping factory_reset_stats(); - // [[fallthrough]] // there is no break intentionally + // FALLTHRU case 3: // Level 3: Preparation after being serviced // Force language selection at the next boot up. @@ -1071,18 +1074,21 @@ void setup() } #endif //TMC2130 - //saved EEPROM SN is not valid. Try to retrieve it. - //SN is valid only if it is NULL terminated. Any other character means either uninitialized or corrupted - if (eeprom_read_byte((uint8_t*)EEPROM_PRUSA_SN + 19)) + //Check for valid SN in EEPROM. Try to retrieve it in case it's invalid. + //SN is valid only if it is NULL terminated and starts with "CZPX". { char SN[20]; - if (get_PRUSA_SN(SN)) + eeprom_read_block(SN, (uint8_t*)EEPROM_PRUSA_SN, 20); + if (SN[19] || strncmp_P(SN, PSTR("CZPX"), 4)) { - eeprom_update_block(SN, (uint8_t*)EEPROM_PRUSA_SN, 20); - puts_P(PSTR("SN updated")); + if (!get_PRUSA_SN(SN)) + { + eeprom_update_block(SN, (uint8_t*)EEPROM_PRUSA_SN, 20); + puts_P(PSTR("SN updated")); + } + else + puts_P(PSTR("SN update failed")); } - else - puts_P(PSTR("SN update failed")); } @@ -1727,6 +1733,32 @@ void serial_read_stream() { } } + +/** + * Output autoreport values according to features requested in M155 + */ +#if defined(AUTO_REPORT) +static void host_autoreport() +{ + if (autoReportFeatures.TimerExpired()) + { + if(autoReportFeatures.Temp()){ + gcode_M105(active_extruder); + } + if(autoReportFeatures.Pos()){ + gcode_M114(); + } +#if defined(AUTO_REPORT) && (defined(FANCHECK) && (((defined(TACH_0) && (TACH_0 >-1)) || (defined(TACH_1) && (TACH_1 > -1))))) + if(autoReportFeatures.Fans()){ + gcode_M123(); + } +#endif //AUTO_REPORT and (FANCHECK and TACH_0 or TACH_1) + autoReportFeatures.TimerStart(); + } +} +#endif //AUTO_REPORT + + /** * Output a "busy" message at regular intervals * while the machine is not accepting commands. @@ -1738,27 +1770,6 @@ void host_keepalive() { if (farm_mode) return; long ms = _millis(); -#if defined(AUTO_REPORT) - { - if (autoReportFeatures.TimerExpired()) - { - if(autoReportFeatures.Temp()){ - gcode_M105(active_extruder); - } - if(autoReportFeatures.Pos()){ - gcode_M114(); - } - #if defined(AUTO_REPORT) && (defined(FANCHECK) && (((defined(TACH_0) && (TACH_0 >-1)) || (defined(TACH_1) && (TACH_1 > -1))))) - if(autoReportFeatures.Fans()){ - gcode_M123(); - } -#endif //AUTO_REPORT and (FANCHECK and TACH_0 or TACH_1) - autoReportFeatures.TimerStart(); - } - } -#endif //AUTO_REPORT - - if (host_keepalive_interval && busy_state != NOT_BUSY) { if ((ms - prev_busy_signal_ms) < (long)(1000L * host_keepalive_interval)) return; switch (busy_state) { @@ -3493,11 +3504,13 @@ bool gcode_M45(bool onlyZ, int8_t verbosity_level) bool result = sample_mesh_and_store_reference(); if (result) { - if (calibration_status() == CALIBRATION_STATUS_Z_CALIBRATION) - // Shipped, the nozzle height has been set already. The user can start printing now. - calibration_status_store(CALIBRATION_STATUS_CALIBRATED); - final_result = true; - // babystep_apply(); + if (calibration_status() == CALIBRATION_STATUS_Z_CALIBRATION) + { + // Shipped, the nozzle height has been set already. The user can start printing now. + calibration_status_store(CALIBRATION_STATUS_CALIBRATED); + } + final_result = true; + // babystep_apply(); } } else @@ -3823,33 +3836,47 @@ void gcode_M701() * * Send command ;S to serial port 0 to retrieve serial number stored in 32U2 processor, * reply is stored in *SN. - * Operation takes typically 23 ms. If the retransmit is not finished until 100 ms, - * it is interrupted, so less, or no characters are retransmitted, the function returns false + * Operation takes typically 23 ms. If no valid SN can be retrieved within the 250ms window, the function aborts + * and returns a general failure flag. * The command will fail if the 32U2 processor is unpowered via USB since it is isolated from the rest of the electronics. * In that case the value that is stored in the EEPROM should be used instead. * - * @return 1 on success - * @return 0 on general failure + * @return 0 on success + * @return 1 on general failure */ -static bool get_PRUSA_SN(char* SN) +static uint8_t get_PRUSA_SN(char* SN) { uint8_t selectedSerialPort_bak = selectedSerialPort; - selectedSerialPort = 0; - SERIAL_ECHOLNRPGM(PSTR(";S")); - uint8_t numbersRead = 0; + uint8_t rxIndex; + bool SN_valid = false; ShortTimer timeout; - timeout.start(); - while (numbersRead < 19) { - if (MSerial.available() > 0) { - SN[numbersRead] = MSerial.read(); - numbersRead++; + selectedSerialPort = 0; + timeout.start(); + + while (!SN_valid) + { + rxIndex = 0; + _delay(50); + MYSERIAL.flush(); //clear RX buffer + SERIAL_ECHOLNRPGM(PSTR(";S")); + while (rxIndex < 19) + { + if (timeout.expired(250u)) + goto exit; + if (MYSERIAL.available() > 0) + { + SN[rxIndex] = MYSERIAL.read(); + rxIndex++; + } } - if (timeout.expired(100u)) break; + SN[rxIndex] = 0; + // printf_P(PSTR("SN:%s\n"), SN); + SN_valid = (strncmp_P(SN, PSTR("CZPX"), 4) == 0); } - SN[numbersRead] = 0; +exit: selectedSerialPort = selectedSerialPort_bak; - return (numbersRead == 19); + return !SN_valid; } //! Detection of faulty RAMBo 1.1b boards equipped with bigger capacitors //! at the TACH_1 pin, which causes bad detection of print fan speed. @@ -8841,7 +8868,7 @@ Sigma_Exit: bool load_to_nozzle = false; for (index = 1; *(strchr_pointer + index) == ' ' || *(strchr_pointer + index) == '\t'; index++); - *(strchr_pointer + index) = tolower(*(strchr_pointer + index)); + *(strchr_pointer + index) = tolower(*(strchr_pointer + index)); if ((*(strchr_pointer + index) < '0' || *(strchr_pointer + index) > '4') && *(strchr_pointer + index) != '?' && *(strchr_pointer + index) != 'x' && *(strchr_pointer + index) != 'c') { SERIAL_ECHOLNPGM("Invalid T code."); @@ -9901,6 +9928,10 @@ if(0) #endif check_axes_activity(); mmu_loop(); +#if defined(AUTO_REPORT) + host_autoreport(); +#endif //AUTO_REPORT + host_keepalive(); } void kill(const char *full_screen_message, unsigned char id) diff --git a/Firmware/cardreader.cpp b/Firmware/cardreader.cpp index a86c49e1..b0c972fc 100644 --- a/Firmware/cardreader.cpp +++ b/Firmware/cardreader.cpp @@ -196,7 +196,7 @@ void CardReader::ls(ls_param params) } -void CardReader::initsd() +void CardReader::initsd(bool doPresort/* = true*/) { cardOK = false; if(root.isOpen()) @@ -240,7 +240,8 @@ void CardReader::initsd() workDirDepth = 0; #ifdef SDCARD_SORT_ALPHA - presort(); + if (doPresort) + presort(); #endif /* diff --git a/Firmware/cardreader.h b/Firmware/cardreader.h index c6e55428..f7e3acc9 100644 --- a/Firmware/cardreader.h +++ b/Firmware/cardreader.h @@ -27,7 +27,7 @@ public: inline ls_param(bool LFN, bool timestamp):LFN(LFN), timestamp(timestamp) { } } __attribute__((packed)); - void initsd(); + void initsd(bool doPresort = true); void write_command(char *buf); void write_command_no_newline(char *buf); //files auto[0-9].g on the sd card are performed in a row diff --git a/Firmware/eeprom.h b/Firmware/eeprom.h index 1db8a406..6ed11525 100644 --- a/Firmware/eeprom.h +++ b/Firmware/eeprom.h @@ -564,7 +564,7 @@ static Sheets * const EEPROM_Sheets_base = (Sheets*)(EEPROM_SHEETS_BASE); #ifdef __cplusplus #include "ConfigurationStore.h" static_assert(EEPROM_FIRMWARE_VERSION_END < 20, "Firmware version EEPROM address conflicts with EEPROM_M500_base"); -static constexpr M500_conf * const EEPROM_M500_base = reinterpret_cast(20); //offset for storing settings using M500 +static M500_conf * const EEPROM_M500_base = reinterpret_cast(20); //offset for storing settings using M500 static_assert(((sizeof(M500_conf) + 20) < EEPROM_LAST_ITEM), "M500_conf address space conflicts with previous items."); #endif diff --git a/Firmware/heatbed_pwm.cpp b/Firmware/heatbed_pwm.cpp index b97da52c..85432d18 100755 --- a/Firmware/heatbed_pwm.cpp +++ b/Firmware/heatbed_pwm.cpp @@ -153,7 +153,6 @@ ISR(TIMER0_OVF_vect) // timer compare interrupt service routine return; // want full duty for the next ONE cycle again - so keep on heating and just wait for the next timer ovf } // otherwise moving towards FALL - state = States::ONE;//_TO_FALL; state=States::FALL; fastCounter = fastMax - 1;// we'll do 16-1 cycles of RISE TCNT0 = 255; // force overflow on the next clock cycle diff --git a/Firmware/mmu.cpp b/Firmware/mmu.cpp index a9471139..c64f1936 100755 --- a/Firmware/mmu.cpp +++ b/Firmware/mmu.cpp @@ -1555,7 +1555,7 @@ void mmu_continue_loading(bool blocking) { case Ls::Enter: increment_load_fail(); - // no break + // FALLTHRU case Ls::Retry: ++retry; // overflow not handled, as it is not dangerous. if (retry >= max_retry) diff --git a/Firmware/optiboot_xflash.cpp b/Firmware/optiboot_xflash.cpp index fb1f8075..9e1cfc7b 100644 --- a/Firmware/optiboot_xflash.cpp +++ b/Firmware/optiboot_xflash.cpp @@ -68,6 +68,8 @@ static void getNch(uint8_t count) { typedef uint16_t pagelen_t; +//Thou shalt not change these messages, else the avrdude-slicer xflash implementation will no longer work and the language upload will fail. +//Right now we support 2 xflash chips - the original w25x20cl and a new one GD25Q20C static const char entry_magic_send [] PROGMEM = "start\n"; static const char entry_magic_receive[] PROGMEM = "w25x20cl_enter\n"; static const char entry_magic_cfm [] PROGMEM = "w25x20cl_cfm\n"; diff --git a/Firmware/pat9125.c b/Firmware/pat9125.c index 58308a9a..ea22c015 100644 --- a/Firmware/pat9125.c +++ b/Firmware/pat9125.c @@ -131,8 +131,8 @@ uint8_t pat9125_init(void) if (!pat9125_probe()) return 0; - // Verify that the sensor responds with its correct product ID. - pat9125_PID1 = pat9125_rd_reg(PAT9125_PID1); + // Verify that the sensor responds with its correct product ID. + pat9125_PID1 = pat9125_rd_reg(PAT9125_PID1); pat9125_PID2 = pat9125_rd_reg(PAT9125_PID2); if ((pat9125_PID1 != 0x31) || (pat9125_PID2 != 0x91)) { diff --git a/Firmware/sound.cpp b/Firmware/sound.cpp index bf10271e..f4c6ee1d 100644 --- a/Firmware/sound.cpp +++ b/Firmware/sound.cpp @@ -129,7 +129,7 @@ switch(eSoundMode) Sound_DoSound_Encoder_Move(); if(eSoundType==e_SOUND_TYPE_BlindAlert) Sound_DoSound_Blind_Alert(); - break; + break; default: break; } diff --git a/Firmware/temperature.cpp b/Firmware/temperature.cpp index 35b05f0e..4d00089f 100755 --- a/Firmware/temperature.cpp +++ b/Firmware/temperature.cpp @@ -197,7 +197,9 @@ static uint8_t heater_ttbllen_map[EXTRUDERS] = ARRAY_BY_EXTRUDERS( HEATER_0_TEMP static float analog2temp(int raw, uint8_t e); static float analog2tempBed(int raw); +#ifdef AMBIENT_MAXTEMP static float analog2tempAmbient(int raw); +#endif static void updateTemperaturesFromRawValues(); enum TempRunawayStates @@ -567,10 +569,7 @@ void checkFanSpeed() static unsigned char fan_speed_errors[2] = { 0,0 }; #if (defined(FANCHECK) && defined(TACH_0) && (TACH_0 >-1)) if ((fan_speed[0] < 20) && (current_temperature[0] > EXTRUDER_AUTO_FAN_TEMPERATURE)){ fan_speed_errors[0]++;} - else{ - fan_speed_errors[0] = 0; - host_keepalive(); - } + else fan_speed_errors[0] = 0; #endif #if (defined(FANCHECK) && defined(TACH_1) && (TACH_1 >-1)) if ((fan_speed[1] < 5) && ((blocks_queued() ? block_buffer[block_buffer_tail].fan_speed : fanSpeed) > MIN_PRINT_FAN_SPEED)) fan_speed_errors[1]++; @@ -902,8 +901,6 @@ void manage_heater() timer02_set_pwm0(soft_pwm_bed << 1); } #endif - - host_keepalive(); } #define PGM_RD_W(x) (short)pgm_read_word(&x) diff --git a/Firmware/tmc2130.cpp b/Firmware/tmc2130.cpp index a62268f0..dbce5ea0 100755 --- a/Firmware/tmc2130.cpp +++ b/Firmware/tmc2130.cpp @@ -826,11 +826,11 @@ void tmc2130_do_steps(uint8_t axis, uint16_t steps, uint8_t dir, uint16_t delay_ { if (tmc2130_get_dir(axis) != dir) tmc2130_set_dir(axis, dir); - while (steps--) - { + while (steps--) + { tmc2130_do_step(axis); delayMicroseconds(delay_us); - } + } } void tmc2130_goto_step(uint8_t axis, uint8_t step, uint8_t dir, uint16_t delay_us, uint16_t microstep_resolution) diff --git a/Firmware/ultralcd.cpp b/Firmware/ultralcd.cpp index 02b9d308..b1d13b8f 100755 --- a/Firmware/ultralcd.cpp +++ b/Firmware/ultralcd.cpp @@ -59,7 +59,9 @@ int clock_interval = 0; static void lcd_sd_updir(); static void lcd_mesh_bed_leveling_settings(); +#ifdef LCD_BL_PIN static void lcd_backlight_menu(); +#endif int8_t ReInitLCD = 0; uint8_t scrollstuff = 0; @@ -123,7 +125,9 @@ static void lcd_tune_menu(); static void lcd_settings_menu(); static void lcd_calibration_menu(); 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_farm_number(); static void prusa_stat_diameter(); @@ -160,7 +164,6 @@ 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 bool lcd_selfcheck_axis(int _axis, int _travel); #else static bool lcd_selfcheck_axis(int _axis, int _travel); static bool lcd_selfcheck_pulleys(int axis); @@ -248,7 +251,9 @@ static void fil_unload_menu(); #endif // SNMM || SNMM_V2 static void lcd_disable_farm_mode(); static void lcd_set_fan_check(); +#ifdef MMU_HAS_CUTTER static void lcd_cutter_enabled(); +#endif #ifdef SNMM static char snmm_stop_print_menu(); #endif //SNMM @@ -635,7 +640,7 @@ void lcdui_print_status_line(void) case CustomMsg::MeshBedLeveling: // If mesh bed leveling in progress, show the status if (custom_message_state > 10) { lcd_set_cursor(0, 3); - lcd_space(20); + lcd_space(LCD_WIDTH); lcd_puts_at_P(0, 3, _T(MSG_CALIBRATE_Z_AUTO)); lcd_puts_P(PSTR(" : ")); lcd_print(custom_message_state-10); @@ -690,7 +695,7 @@ void lcdui_print_status_line(void) } // Fill the rest of line to have nice and clean output - for(int fillspace = 0; fillspace < 20; fillspace++) + for(int fillspace = 0; fillspace < LCD_WIDTH; fillspace++) if ((lcd_status_message[fillspace] <= 31 )) lcd_print(' '); } @@ -2090,7 +2095,7 @@ if(lcd_clicked()) { case FilamentAction::AutoLoad: eFilamentAction=FilamentAction::None; // i.e. non-autoLoad - // no break + // FALLTHRU case FilamentAction::Load: loading_flag=true; enquecommand_P(PSTR("M701")); // load filament @@ -2201,14 +2206,21 @@ void mFilamentItem(uint16_t nTemp, uint16_t nTempBed) } else { - if (!bFilamentWaitingFlag) + if (!bFilamentWaitingFlag || lcd_draw_update) { - // First run after the filament preheat selection: - // setup the fixed LCD parts and raise Z as we wait + // First entry from another menu OR first run after the filament preheat selection. Use + // bFilamentWaitingFlag to distinguish: this flag is reset exactly once when entering + // the menu and is used to raise the carriage *once*. In other cases, the LCD has been + // modified elsewhere and needs to be redrawn in full. + + // reset bFilamentWaitingFlag immediately to avoid re-entry from raise_z_above()! + bool once = !bFilamentWaitingFlag; bFilamentWaitingFlag = true; - lcd_clear(); + // also force-enable lcd_draw_update (might be 0 when called from outside a menu) lcd_draw_update = 1; + + lcd_clear(); lcd_puts_at_P(0, 3, _T(MSG_CANCEL)); ////MSG_CANCEL lcd_set_cursor(0, 1); @@ -2218,12 +2230,12 @@ void mFilamentItem(uint16_t nTemp, uint16_t nTempBed) case FilamentAction::AutoLoad: case FilamentAction::MmuLoad: lcd_puts_P(_i("Preheating to load")); ////MSG_PREHEATING_TO_LOAD c=20 - raise_z_above(MIN_Z_FOR_LOAD); + if (once) raise_z_above(MIN_Z_FOR_LOAD); break; case FilamentAction::UnLoad: case FilamentAction::MmuUnLoad: lcd_puts_P(_i("Preheating to unload")); ////MSG_PREHEATING_TO_UNLOAD c=20 - raise_z_above(MIN_Z_FOR_UNLOAD); + if (once) raise_z_above(MIN_Z_FOR_UNLOAD); break; case FilamentAction::MmuEject: lcd_puts_P(_i("Preheating to eject")); ////MSG_PREHEATING_TO_EJECT c=20 @@ -2419,7 +2431,7 @@ void lcd_change_success() { static void lcd_loading_progress_bar(uint16_t loading_time_ms) { - for (uint_least8_t i = 0; i < 20; i++) { + for (uint_least8_t i = 0; i < LCD_WIDTH; i++) { lcd_putc_at(i, 3, '.'); //loading_time_ms/20 delay for (uint_least8_t j = 0; j < 5; j++) { @@ -3332,10 +3344,10 @@ static const char* lcd_display_message_fullscreen_nonBlocking_P(const char *msg, // End of the message. break; lcd_set_cursor(0, row); - uint8_t linelen = min(strlen_P(msg), 20); + uint8_t linelen = min(strlen_P(msg), LCD_WIDTH); const char *msgend2 = msg + linelen; msgend = msgend2; - if (row == 3 && linelen == 20) { + if (row == 3 && linelen == LCD_WIDTH) { // Last line of the display, full line shall be displayed. // Find out, whether this message will be split into multiple screens. while (pgm_is_whitespace(msgend)) @@ -5999,7 +6011,7 @@ char reset_menu() { int8_t enc_dif = 0; char cursor_pos = 0; - const char *const item[items_no] PROGMEM = {PSTR("Language"), PSTR("Statistics"), PSTR("Shipping prep"), PSTR("Service prep"), PSTR("All Data") + const char *const item[items_no] = {PSTR("Language"), PSTR("Statistics"), PSTR("Shipping prep"), PSTR("Service prep"), PSTR("All Data") #ifdef SNMM , PSTR("Bowden length") #endif @@ -7134,8 +7146,8 @@ void lcd_sdcard_menu() _md->fileCnt = card.getnrfilenames(); _md->sdSort = eeprom_read_byte((uint8_t*)EEPROM_SD_SORT); _md->menuState = _standard; - // FALLTHRU } + // FALLTHRU case _standard: //normal menu structure. { if (!_md->lcd_scrollTimer.running()) //if the timer is not running, then the menu state was just switched, so redraw the screen. @@ -7400,7 +7412,7 @@ bool lcd_selftest() break; case FanCheck::SwappedFan: _swapped_fan = true; - // no break + // FALLTHRU default: _result = true; break; @@ -7423,7 +7435,7 @@ bool lcd_selftest() break; case FanCheck::SwappedFan: _swapped_fan = true; - // no break + // FALLTHRU default: _result = true; break; @@ -8854,25 +8866,28 @@ void menu_lcd_lcdupdate_func(void) lcd_draw_update = 2; lcd_oldcardstatus = IS_SD_INSERTED; lcd_refresh(); // to maybe revive the LCD if static electricity killed it. - backlight_wake(); + backlight_wake(); if (lcd_oldcardstatus) { - card.initsd(); - LCD_MESSAGERPGM(_T(WELCOME_MSG)); - bMain=false; // flag (i.e. 'fake parameter') for 'lcd_sdcard_menu()' function - menu_submenu(lcd_sdcard_menu); - //get_description(); + if (!card.cardOK) + { + 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)); + bMain=false; // flag (i.e. 'fake parameter') for 'lcd_sdcard_menu()' function + menu_submenu(lcd_sdcard_menu); } else { - if(menu_menu==lcd_sdcard_menu) - menu_back(); + if(menu_menu==lcd_sdcard_menu) + menu_back(); card.release(); LCD_MESSAGERPGM(_i("Card removed"));////MSG_SD_REMOVED c=20 } } #endif//CARDINSERTED - backlight_update(); + backlight_update(); if (lcd_next_update_millis < _millis()) { if (abs(lcd_encoder_diff) >= ENCODER_PULSES_PER_STEP) diff --git a/Firmware/ultralcd.h b/Firmware/ultralcd.h index 3aab932d..a58d48ee 100755 --- a/Firmware/ultralcd.h +++ b/Firmware/ultralcd.h @@ -205,12 +205,6 @@ void lcd_printer_connected(); void lcd_ping(); void lcd_calibrate_extruder(); -void lcd_farm_sdcard_menu(); - -//void getFileDescription(char *name, char *description); - -void lcd_farm_sdcard_menu_w(); -//void get_description(); void lcd_wait_for_heater(); void lcd_wait_for_cool_down();