diff --git a/Firmware/Marlin.h b/Firmware/Marlin.h index 509880922..afc018596 100755 --- a/Firmware/Marlin.h +++ b/Firmware/Marlin.h @@ -323,7 +323,6 @@ extern float retract_recover_length_swap; extern uint8_t host_keepalive_interval; - extern unsigned long starttime; extern unsigned long stoptime; extern int bowden_length[4]; diff --git a/Firmware/Marlin_main.cpp b/Firmware/Marlin_main.cpp index c8f5feb63..d9e210b62 100755 --- a/Firmware/Marlin_main.cpp +++ b/Firmware/Marlin_main.cpp @@ -1076,6 +1076,7 @@ void setup() SERIAL_ECHO_START; printf_P(PSTR(" " FW_VERSION_FULL "\n")); + //SERIAL_ECHOPAIR("Active sheet before:", static_cast(eeprom_read_byte(&(EEPROM_Sheets_base->active_sheet)))); #ifdef DEBUG_SEC_LANG lang_table_header_t header; @@ -1424,20 +1425,7 @@ void setup() printf_P(PSTR("Card NG!\n")); #endif //DEBUG_SD_SPEED_TEST - if (eeprom_read_byte((uint8_t*)EEPROM_POWER_COUNT) == 0xff) eeprom_write_byte((uint8_t*)EEPROM_POWER_COUNT, 0); - if (eeprom_read_byte((uint8_t*)EEPROM_CRASH_COUNT_X) == 0xff) eeprom_write_byte((uint8_t*)EEPROM_CRASH_COUNT_X, 0); - if (eeprom_read_byte((uint8_t*)EEPROM_CRASH_COUNT_Y) == 0xff) eeprom_write_byte((uint8_t*)EEPROM_CRASH_COUNT_Y, 0); - if (eeprom_read_byte((uint8_t*)EEPROM_FERROR_COUNT) == 0xff) eeprom_write_byte((uint8_t*)EEPROM_FERROR_COUNT, 0); - if (eeprom_read_word((uint16_t*)EEPROM_POWER_COUNT_TOT) == 0xffff) eeprom_write_word((uint16_t*)EEPROM_POWER_COUNT_TOT, 0); - if (eeprom_read_word((uint16_t*)EEPROM_CRASH_COUNT_X_TOT) == 0xffff) eeprom_write_word((uint16_t*)EEPROM_CRASH_COUNT_X_TOT, 0); - if (eeprom_read_word((uint16_t*)EEPROM_CRASH_COUNT_Y_TOT) == 0xffff) eeprom_write_word((uint16_t*)EEPROM_CRASH_COUNT_Y_TOT, 0); - if (eeprom_read_word((uint16_t*)EEPROM_FERROR_COUNT_TOT) == 0xffff) eeprom_write_word((uint16_t*)EEPROM_FERROR_COUNT_TOT, 0); - - if (eeprom_read_word((uint16_t*)EEPROM_MMU_FAIL_TOT) == 0xffff) eeprom_update_word((uint16_t *)EEPROM_MMU_FAIL_TOT, 0); - if (eeprom_read_word((uint16_t*)EEPROM_MMU_LOAD_FAIL_TOT) == 0xffff) eeprom_update_word((uint16_t *)EEPROM_MMU_LOAD_FAIL_TOT, 0); - if (eeprom_read_byte((uint8_t*)EEPROM_MMU_FAIL) == 0xff) eeprom_update_byte((uint8_t *)EEPROM_MMU_FAIL, 0); - if (eeprom_read_byte((uint8_t*)EEPROM_MMU_LOAD_FAIL) == 0xff) eeprom_update_byte((uint8_t *)EEPROM_MMU_LOAD_FAIL, 0); - + eeprom_init(); #ifdef SNMM if (eeprom_read_dword((uint32_t*)EEPROM_BOWDEN_LENGTH) == 0x0ffffffff) { //bowden length used for SNMM int _z = BOWDEN_LENGTH; @@ -1504,7 +1492,6 @@ void setup() SilentModeMenu_MMU = 1; eeprom_write_byte((uint8_t*)EEPROM_MMU_STEALTH, SilentModeMenu_MMU); } - check_babystep(); //checking if Z babystep is in allowed range #if !defined(DEBUG_DISABLE_FANCHECK) && defined(FANCHECK) && defined(TACH_1) && TACH_1 >-1 setup_fan_interrupt(); @@ -1650,7 +1637,6 @@ void setup() #ifdef WATCHDOG wdt_enable(WDTO_4S); #endif //WATCHDOG - } @@ -8159,12 +8145,15 @@ static void wait_for_heater(long codenum, uint8_t extruder) { void check_babystep() { - int babystep_z; - EEPROM_read_B(EEPROM_BABYSTEP_Z, &babystep_z); + int babystep_z = eeprom_read_word(reinterpret_cast(&(EEPROM_Sheets_base-> + s[(eeprom_read_byte(&(EEPROM_Sheets_base->active_sheet)))].z_offset))); + if ((babystep_z < Z_BABYSTEP_MIN) || (babystep_z > Z_BABYSTEP_MAX)) { babystep_z = 0; //if babystep value is out of min max range, set it to 0 SERIAL_ECHOLNPGM("Z live adjust out of range. Setting to 0"); - EEPROM_save_B(EEPROM_BABYSTEP_Z, &babystep_z); + eeprom_write_word(reinterpret_cast(&(EEPROM_Sheets_base-> + s[(eeprom_read_byte(&(EEPROM_Sheets_base->active_sheet)))].z_offset)), + babystep_z); lcd_show_fullscreen_message_and_wait_P(PSTR("Z live adjust out of range. Setting to 0. Click to continue.")); lcd_update_enable(true); } diff --git a/Firmware/eeprom.cpp b/Firmware/eeprom.cpp new file mode 100644 index 000000000..1be708d00 --- /dev/null +++ b/Firmware/eeprom.cpp @@ -0,0 +1,83 @@ +//! @file +//! @date Jun 20, 2019 +//! @author Marek Běl + +#include "eeprom.h" +#include "Marlin.h" + +#include +#include + + +#include "language.h" + +#if 0 +template +static T eeprom_read(T *address); + +template<> +char eeprom_read(char *address) +{ + return eeprom_read_byte(reinterpret_cast(address)); +} +#endif + +template +static void eeprom_write(T *address, T value); + +template<> +void eeprom_write(char *addres, char value) +{ + eeprom_write_byte(reinterpret_cast(addres), static_cast(value)); +} + + +template +static bool eeprom_is_uninitialized(T *address); + +template <> +bool eeprom_is_uninitialized(char *address) +{ + return (0xff == eeprom_read_byte(reinterpret_cast(address))); +} + +bool is_sheet_initialized(){ + return (0xffff != eeprom_read_word(reinterpret_cast(&(EEPROM_Sheets_base-> + s[eeprom_read_byte(&(EEPROM_Sheets_base->active_sheet))].z_offset)))); +} + +void eeprom_init() +{ + if (eeprom_read_byte((uint8_t*)EEPROM_POWER_COUNT) == 0xff) eeprom_write_byte((uint8_t*)EEPROM_POWER_COUNT, 0); + if (eeprom_read_byte((uint8_t*)EEPROM_CRASH_COUNT_X) == 0xff) eeprom_write_byte((uint8_t*)EEPROM_CRASH_COUNT_X, 0); + if (eeprom_read_byte((uint8_t*)EEPROM_CRASH_COUNT_Y) == 0xff) eeprom_write_byte((uint8_t*)EEPROM_CRASH_COUNT_Y, 0); + if (eeprom_read_byte((uint8_t*)EEPROM_FERROR_COUNT) == 0xff) eeprom_write_byte((uint8_t*)EEPROM_FERROR_COUNT, 0); + if (eeprom_read_word((uint16_t*)EEPROM_POWER_COUNT_TOT) == 0xffff) eeprom_write_word((uint16_t*)EEPROM_POWER_COUNT_TOT, 0); + if (eeprom_read_word((uint16_t*)EEPROM_CRASH_COUNT_X_TOT) == 0xffff) eeprom_write_word((uint16_t*)EEPROM_CRASH_COUNT_X_TOT, 0); + if (eeprom_read_word((uint16_t*)EEPROM_CRASH_COUNT_Y_TOT) == 0xffff) eeprom_write_word((uint16_t*)EEPROM_CRASH_COUNT_Y_TOT, 0); + if (eeprom_read_word((uint16_t*)EEPROM_FERROR_COUNT_TOT) == 0xffff) eeprom_write_word((uint16_t*)EEPROM_FERROR_COUNT_TOT, 0); + + if (eeprom_read_word((uint16_t*)EEPROM_MMU_FAIL_TOT) == 0xffff) eeprom_update_word((uint16_t *)EEPROM_MMU_FAIL_TOT, 0); + if (eeprom_read_word((uint16_t*)EEPROM_MMU_LOAD_FAIL_TOT) == 0xffff) eeprom_update_word((uint16_t *)EEPROM_MMU_LOAD_FAIL_TOT, 0); + if (eeprom_read_byte((uint8_t*)EEPROM_MMU_FAIL) == 0xff) eeprom_update_byte((uint8_t *)EEPROM_MMU_FAIL, 0); + if (eeprom_read_byte((uint8_t*)EEPROM_MMU_LOAD_FAIL) == 0xff) eeprom_update_byte((uint8_t *)EEPROM_MMU_LOAD_FAIL, 0); + if (eeprom_read_byte(&(EEPROM_Sheets_base->active_sheet)) == 0xff) eeprom_update_byte(&(EEPROM_Sheets_base->active_sheet), 0); + for (uint_least8_t i = 0; i < (sizeof(Sheets::s)/sizeof(Sheets::s[0])); ++i) + { + bool is_uninitialized = true; + for (uint_least8_t j = 0; j < (sizeof(Sheet::name)/sizeof(Sheet::name[0])); ++j) + { + if (!eeprom_is_uninitialized(&(EEPROM_Sheets_base->s[i].name[j]))) is_uninitialized = false; + } + if(is_uninitialized) + { + eeprom_write(&(EEPROM_Sheets_base->s[i].name[0]), static_cast(i + '1')); + eeprom_write(&(EEPROM_Sheets_base->s[i].name[1]), '\0'); + } + } + check_babystep(); +} + + + + diff --git a/Firmware/eeprom.h b/Firmware/eeprom.h index 70f9f726b..f4e20e5d2 100644 --- a/Firmware/eeprom.h +++ b/Firmware/eeprom.h @@ -1,6 +1,10 @@ #ifndef EEPROM_H #define EEPROM_H +#include + +void eeprom_init(); + // The total size of the EEPROM is // 4096 for the Atmega2560 #define EEPROM_TOP 4096 @@ -167,31 +171,38 @@ #define EEPROM_NOZZLE_DIAMETER (EEPROM_CHECK_MODE-1) // uint8 #define EEPROM_NOZZLE_DIAMETER_uM (EEPROM_NOZZLE_DIAMETER-2) // uint16 +typedef struct +{ + char name[7]; //!< Can be null terminated, doesn't need to be null terminated + int16_t z_offset; //!< Z_BABYSTEP_MIN .. Z_BABYSTEP_MAX = Z_BABYSTEP_MIN*2/1000 [mm] .. Z_BABYSTEP_MAX*2/1000 [mm] + uint8_t bed_temp; //!< 0 .. 254 [°C] + uint8_t pinda_temp; //!< 0 .. 254 [°C] +} Sheet; + +typedef struct +{ + Sheet s[3]; + uint8_t active_sheet; +} Sheets; +// sizeof(Sheets). Do not change it unless EEPROM_Sheets_base is last item in EEPROM. +// Otherwise it would move following items. +#define EEPROM_SHEETS_SIZEOF 34 + +static Sheets * const EEPROM_Sheets_base = (Sheets*)(EEPROM_NOZZLE_DIAMETER - EEPROM_SHEETS_SIZEOF); + +#ifdef __cplusplus +extern bool is_sheet_initialized(); +static_assert(sizeof(Sheets) == EEPROM_SHEETS_SIZEOF, "Sizeof(Sheets) is not EEPROM_SHEETS_SIZEOF."); +#endif + +//This is supposed to point to last item to allow EEPROM overrun check. Please update when adding new items. +#define EEPROM_LAST_ITEM ((uint16_t)EEPROM_Sheets_base) + // !!!!! // !!!!! this is end of EEPROM section ... all updates MUST BE inserted before this mark !!!!! // !!!!! -//TMC2130 configuration -#define EEPROM_TMC_AXIS_SIZE //axis configuration block size -#define EEPROM_TMC_X (EEPROM_TMC + 0 * EEPROM_TMC_AXIS_SIZE) //X axis configuration blok -#define EEPROM_TMC_Y (EEPROM_TMC + 1 * EEPROM_TMC_AXIS_SIZE) //Y axis -#define EEPROM_TMC_Z (EEPROM_TMC + 2 * EEPROM_TMC_AXIS_SIZE) //Z axis -#define EEPROM_TMC_E (EEPROM_TMC + 3 * EEPROM_TMC_AXIS_SIZE) //E axis -//TMC2130 - X axis -#define EEPROM_TMC_X_USTEPS_INTPOL (EEPROM_TMC_X + 0) // 1byte, bit 0..4 USTEPS, bit 7 INTPOL -#define EEPROM_TMC_X_PWM_AMPL (EEPROM_TMC_X + 1) // 1byte (0..255) -#define EEPROM_TMC_X_PWM_GRAD_FREQ (EEPROM_TMC_X + 2) // 1byte, bit 0..3 GRAD, bit 4..5 FREQ -#define EEPROM_TMC_X_TCOOLTHRS (EEPROM_TMC_X + 3) // 2bytes (0..) -#define EEPROM_TMC_X_SG_THRS (EEPROM_TMC_X + 5) // 1byte, (-64..+63) -#define EEPROM_TMC_X_CURRENT_H (EEPROM_TMC_X + 6) // 1byte, (0..63) -#define EEPROM_TMC_X_CURRENT_R (EEPROM_TMC_X + 7) // 1byte, (0..63) -#define EEPROM_TMC_X_HOME_SG_THRS (EEPROM_TMC_X + 8) // 1byte, (-64..+63) -#define EEPROM_TMC_X_HOME_CURRENT_R (EEPROM_TMC_X + 9) // 1byte, (-64..+63) -#define EEPROM_TMC_X_HOME_DTCOOLTHRS (EEPROM_TMC_X + 10) // 1byte (-128..+127) -#define EEPROM_TMC_X_DTCOOLTHRS_LOW (EEPROM_TMC_X + 11) // 1byte (-128..+127) -#define EEPROM_TMC_X_DTCOOLTHRS_HIGH (EEPROM_TMC_X + 12) // 1byte (-128..+127) -#define EEPROM_TMC_X_SG_THRS_LOW (EEPROM_TMC_X + 13) // 1byte, (-64..+63) -#define EEPROM_TMC_X_SG_THRS_HIGH (EEPROM_TMC_X + 14) // 1byte, (-64..+63) + // Currently running firmware, each digit stored as uint16_t. // The flavor differentiates a dev, alpha, beta, release candidate or a release version. @@ -205,7 +216,9 @@ #ifdef __cplusplus #include "ConfigurationStore.h" -static M500_conf * const EEPROM_M500_base = reinterpret_cast(20); //offset for storing settings using M500 +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_assert(((sizeof(M500_conf) + 20) < EEPROM_LAST_ITEM), "M500_conf address space conflicts with previous items."); #endif enum diff --git a/Firmware/menu.cpp b/Firmware/menu.cpp index e0364056e..2a8e32abb 100755 --- a/Firmware/menu.cpp +++ b/Firmware/menu.cpp @@ -168,16 +168,40 @@ int menu_draw_item_printf_P(char type_char, const char* format, ...) } */ +static char menu_selection_mark(){ + return (lcd_encoder == menu_item)?'>':' '; +} + static void menu_draw_item_puts_P(char type_char, const char* str) { lcd_set_cursor(0, menu_row); - lcd_printf_P(PSTR("%c%-18.18S%c"), (lcd_encoder == menu_item)?'>':' ', str, type_char); + lcd_printf_P(PSTR("%c%-18.18S%c"), menu_selection_mark(), str, type_char); +} + +//! @brief Format sheet name +//! +//! @param[in] sheet_E Sheet in EEPROM +//! @param[out] buffer for formatted output +void menu_format_sheet_E(const Sheet &sheet_E, SheetFormatBuffer &buffer) +{ + uint_least8_t index = sprintf_P(buffer.c, PSTR("%.10S "), _T(MSG_SHEET)); + eeprom_read_block(&(buffer.c[index]), sheet_E.name, 7); + //index += 7; + buffer.c[index + 7] = '\0'; +} + +static void menu_draw_item_puts_E(char type_char, const Sheet &sheet) +{ + lcd_set_cursor(0, menu_row); + SheetFormatBuffer buffer; + menu_format_sheet_E(sheet, buffer); + lcd_printf_P(PSTR("%c%-18.18s%c"), menu_selection_mark(), buffer.c, type_char); } static void menu_draw_item_puts_P(char type_char, const char* str, char num) { lcd_set_cursor(0, menu_row); - lcd_printf_P(PSTR("%c%-.16S "), (lcd_encoder == menu_item)?'>':' ', str); + lcd_printf_P(PSTR("%c%-.16S "), menu_selection_mark(), str); lcd_putc(num); lcd_set_cursor(19, menu_row); lcd_putc(type_char); @@ -224,6 +248,21 @@ uint8_t menu_item_submenu_P(const char* str, menu_func_t submenu) return 0; } +uint8_t menu_item_submenu_E(const Sheet &sheet, menu_func_t submenu) +{ + if (menu_item == menu_line) + { + if (lcd_draw_update) menu_draw_item_puts_E(LCD_STR_ARROW_RIGHT[0], sheet); + if (menu_clicked && (lcd_encoder == menu_item)) + { + menu_submenu(submenu); + return menu_item_ret(); + } + } + menu_item++; + return 0; +} + uint8_t menu_item_back_P(const char* str) { if (menu_item == menu_line) @@ -399,7 +438,7 @@ uint8_t menu_item_edit_P(const char* str, T pval, int16_t min_val, int16_t max_v if (lcd_draw_update) { lcd_set_cursor(0, menu_row); - menu_draw_P((lcd_encoder == menu_item)?'>':' ', str, *pval); + menu_draw_P(menu_selection_mark(), str, *pval); } if (menu_clicked && (lcd_encoder == menu_item)) { diff --git a/Firmware/menu.h b/Firmware/menu.h index 5f73e18b0..a4cb30104 100755 --- a/Firmware/menu.h +++ b/Firmware/menu.h @@ -3,6 +3,7 @@ #define _MENU_H #include +#include "eeprom.h" #define MENU_DATA_SIZE 32 @@ -99,6 +100,10 @@ extern uint8_t menu_item_text_P(const char* str); #define MENU_ITEM_SUBMENU_P(str, submenu) do { if (menu_item_submenu_P(str, submenu)) return; } while (0) extern uint8_t menu_item_submenu_P(const char* str, menu_func_t submenu); +#define MENU_ITEM_SUBMENU_E(sheet, submenu) do { if (menu_item_submenu_E(sheet, submenu)) return; } while (0) +extern uint8_t menu_item_submenu_E(const Sheet &sheet, menu_func_t submenu); + + #define MENU_ITEM_BACK_P(str) do { if (menu_item_back_P(str)) return; } while (0) extern uint8_t menu_item_back_P(const char* str); @@ -125,6 +130,13 @@ extern void menu_draw_float31(const char* str, float val); extern void menu_draw_float13(const char* str, float val); +struct SheetFormatBuffer +{ + char c[19]; +}; + +extern void menu_format_sheet_E(const Sheet &sheet_E, SheetFormatBuffer &buffer); + #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) diff --git a/Firmware/mesh_bed_calibration.cpp b/Firmware/mesh_bed_calibration.cpp index 91dadaefa..1edac56bf 100644 --- a/Firmware/mesh_bed_calibration.cpp +++ b/Firmware/mesh_bed_calibration.cpp @@ -3031,7 +3031,8 @@ void babystep_load() check_babystep(); //checking if babystep is in allowed range, otherwise setting babystep to 0 // End of G80: Apply the baby stepping value. - EEPROM_read_B(EEPROM_BABYSTEP_Z, &babystepLoadZ); + babystepLoadZ = eeprom_read_word(reinterpret_cast(&(EEPROM_Sheets_base-> + s[(eeprom_read_byte(&(EEPROM_Sheets_base->active_sheet)))].z_offset))); #if 0 SERIAL_ECHO("Z baby step: "); @@ -3186,4 +3187,4 @@ void mbl_interpolation(uint8_t meas_points) { } } } -} \ No newline at end of file +} diff --git a/Firmware/messages.c b/Firmware/messages.c index 53ec20e86..67f32bc3e 100644 --- a/Firmware/messages.c +++ b/Firmware/messages.c @@ -10,7 +10,7 @@ //internationalized messages const char MSG_AUTO_HOME[] PROGMEM_I1 = ISTR("Auto home"); //// const char MSG_AUTO_MODE_ON[] PROGMEM_I1 = ISTR("Mode [auto power]"); //// -const char MSG_BABYSTEP_Z[] PROGMEM_I1 = ISTR("Live adjust Z"); //// +const char MSG_BABYSTEP_Z[] PROGMEM_I1 = ISTR("Live adjust Z"); //// c=18 const char MSG_BABYSTEP_Z_NOT_SET[] PROGMEM_I1 = ISTR("Distance between tip of the nozzle and the bed surface has not been set yet. Please follow the manual, chapter First steps, section First layer calibration."); ////c=20 r=12 const char MSG_BED[] PROGMEM_I1 = ISTR("Bed"); //// const char MSG_BED_DONE[] PROGMEM_I1 = ISTR("Bed done"); //// @@ -55,6 +55,7 @@ const char MSG_CUT_FILAMENT[] PROGMEM_I1 = ISTR("Cut filament"); //// Number 1 t const char MSG_M117_V2_CALIBRATION[] PROGMEM_I1 = ISTR("M117 First layer cal."); ////c=25 r=1 const char MSG_MAIN[] PROGMEM_I1 = ISTR("Main"); //// const char MSG_BACK[] PROGMEM_I1 = ISTR("Back"); //// +const char MSG_SHEET[] PROGMEM_I1 = ISTR("Sheet"); ////c=10 const char MSG_MEASURE_BED_REFERENCE_HEIGHT_LINE1[] PROGMEM_I1 = ISTR("Measuring reference height of calibration point"); ////c=60 const char MSG_MEASURE_BED_REFERENCE_HEIGHT_LINE2[] PROGMEM_I1 = ISTR(" of 9"); ////c=14 const char MSG_MENU_CALIBRATION[] PROGMEM_I1 = ISTR("Calibration"); //// @@ -126,3 +127,6 @@ const char MSG_ENDSTOP_OPEN[] PROGMEM_N1 = "open"; //// const char MSG_POWERUP[] PROGMEM_N1 = "PowerUp"; //// const char MSG_ERR_STOPPED[] PROGMEM_N1 = "Printer stopped due to errors. Fix the error and use M999 to restart. (Temperature is reset. Set it after restarting)"; //// const char MSG_ENDSTOP_HIT[] PROGMEM_N1 = "TRIGGERED"; //// +const char MSG_V2_CALIBRATION[] PROGMEM_N1 = "First layer cal."; ////c=17 r=1 +const char MSG_SELECT[] PROGMEM_N1 = "Select"; //// +const char MSG_RENAME[] PROGMEM_N1 = "Rename"; //// diff --git a/Firmware/messages.h b/Firmware/messages.h index d74412fca..da72d073c 100644 --- a/Firmware/messages.h +++ b/Firmware/messages.h @@ -54,6 +54,7 @@ extern const char MSG_LOADING_FILAMENT[]; extern const char MSG_M117_V2_CALIBRATION[]; extern const char MSG_MAIN[]; extern const char MSG_BACK[]; +extern const char MSG_SHEET[]; extern const char MSG_MEASURE_BED_REFERENCE_HEIGHT_LINE1[]; extern const char MSG_MEASURE_BED_REFERENCE_HEIGHT_LINE2[]; extern const char MSG_MENU_CALIBRATION[]; @@ -127,6 +128,9 @@ extern const char MSG_ERR_STOPPED[]; extern const char MSG_ENDSTOP_HIT[]; extern const char MSG_EJECT_FILAMENT[]; extern const char MSG_CUT_FILAMENT[]; +extern const char MSG_V2_CALIBRATION[]; +extern const char MSG_SELECT[]; +extern const char MSG_RENAME[]; #if defined(__cplusplus) } diff --git a/Firmware/mmu.cpp b/Firmware/mmu.cpp index fa4a55172..c207a74d9 100755 --- a/Firmware/mmu.cpp +++ b/Firmware/mmu.cpp @@ -81,9 +81,11 @@ uint16_t mmu_power_failures = 0; #ifdef MMU_DEBUG +static const auto DEBUG_PUTCHAR = putchar; static const auto DEBUG_PUTS_P = puts_P; static const auto DEBUG_PRINTF_P = printf_P; #else //MMU_DEBUG +#define DEBUG_PUTCHAR(c) #define DEBUG_PUTS_P(str) #define DEBUG_PRINTF_P( __fmt, ... ) #endif //MMU_DEBUG @@ -1447,26 +1449,69 @@ bFilamentAction=false; // NOT in "mmu_fil_eject_menu( } } +//! @brief Fits filament tip into heatbreak? +//! +//! If PTFE tube is jammed, this causes filament to be unloaded and no longer +//! being detected by the pulley IR sensor. +//! @retval true Fits +//! @retval false Doesn't fit +static bool can_load() +{ + current_position[E_AXIS] += 60; + plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], + current_position[E_AXIS], MMU_LOAD_FEEDRATE, active_extruder); + current_position[E_AXIS] -= 52; + plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], + current_position[E_AXIS], MMU_LOAD_FEEDRATE, active_extruder); + st_synchronize(); + + uint_least8_t filament_detected_count = 0; + const float e_increment = 0.2; + const uint_least8_t steps = 6.0 / e_increment; + DEBUG_PUTS_P(PSTR("MMU can_load:")); + for(uint_least8_t i = 0; i < steps; ++i) + { + current_position[E_AXIS] -= e_increment; + plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], + current_position[E_AXIS], MMU_LOAD_FEEDRATE, active_extruder); + st_synchronize(); + if(0 == PIN_GET(IR_SENSOR_PIN)) + { + ++filament_detected_count; + DEBUG_PUTCHAR('O'); + } + else + { + DEBUG_PUTCHAR('o'); + } + } + if (filament_detected_count > steps - 4) + { + DEBUG_PUTS_P(PSTR(" succeeded.")); + return true; + } + else + { + DEBUG_PUTS_P(PSTR(" failed.")); + return false; + } +} + //! @brief load more //! //! Try to feed more filament from MMU if it is not detected by filament sensor. -//! Move filament back and forth to nozzle in order to detect jam. -//! If PTFE tube is jammed, this cause filament to be unloaded and no longer -//! detected by pulley IR sensor in next step. -static void load_more() +//! @retval true Success, filament detected by IR sensor +//! @retval false Failed, filament not detected by IR sensor after maximum number of attempts +static bool load_more() { for (uint8_t i = 0; i < MMU_IDLER_SENSOR_ATTEMPTS_NR; i++) { - if (PIN_GET(IR_SENSOR_PIN) == 0) break; + if (PIN_GET(IR_SENSOR_PIN) == 0) return true; DEBUG_PRINTF_P(PSTR("Additional load attempt nr. %d\n"), i); mmu_command(MmuCmd::C0); manage_response(true, true, MMU_LOAD_MOVE); } - current_position[E_AXIS] += 60; - plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], MMU_LOAD_FEEDRATE, active_extruder); - current_position[E_AXIS] -= 58; - plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], MMU_LOAD_FEEDRATE, active_extruder); - st_synchronize(); + return false; } static void increment_load_fail() @@ -1507,7 +1552,8 @@ void mmu_continue_loading(bool blocking) return; } - load_more(); + bool success = load_more(); + if (success) success = can_load(); enum class Ls : uint_least8_t { @@ -1517,7 +1563,10 @@ void mmu_continue_loading(bool blocking) }; Ls state = Ls::Enter; - while (PIN_GET(IR_SENSOR_PIN) != 0) + const uint_least8_t max_retry = 2; + uint_least8_t retry = 0; + + while (!success) { switch (state) { @@ -1534,8 +1583,10 @@ void mmu_continue_loading(bool blocking) #endif //MMU_HAS_CUTTER mmu_command(MmuCmd::T0 + tmp_extruder); manage_response(true, true, MMU_TCODE_MOVE); - load_more(); - state = Ls::Unload; + success = load_more(); + if (success) success = can_load(); + ++retry; // overflow not handled, as it is not dangerous. + if (retry >= max_retry) state = Ls::Unload; break; case Ls::Unload: stop_and_save_print_to_ram(0, 0); diff --git a/Firmware/ultralcd.cpp b/Firmware/ultralcd.cpp index 608b8c291..2d420c0c5 100755 --- a/Firmware/ultralcd.cpp +++ b/Firmware/ultralcd.cpp @@ -3068,13 +3068,13 @@ static void lcd_move_z() { * other value leads to storing Z_AXIS * @param msg text to be displayed */ -static void _lcd_babystep(int axis, const char *msg) +static void lcd_babystep_z() { typedef struct - { // 19bytes total - int8_t status; // 1byte - int babystepMem[3]; // 6bytes - float babystepMemMM[3]; // 12bytes + { + int8_t status; + int16_t babystepMemZ; + float babystepMemMMZ; } _menu_data_t; 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]); @@ -3084,18 +3084,20 @@ static void _lcd_babystep(int axis, const char *msg) // Initialize its status. _md->status = 1; check_babystep(); - - EEPROM_read_B(EEPROM_BABYSTEP_X, &_md->babystepMem[0]); - EEPROM_read_B(EEPROM_BABYSTEP_Y, &_md->babystepMem[1]); - EEPROM_read_B(EEPROM_BABYSTEP_Z, &_md->babystepMem[2]); + + if(!is_sheet_initialized()){ + _md->babystepMemZ = 0; + } + else{ + _md->babystepMemZ = eeprom_read_word(reinterpret_cast(&(EEPROM_Sheets_base-> + s[(eeprom_read_byte(&(EEPROM_Sheets_base->active_sheet)))].z_offset))); + } // same logic as in babystep_load if (calibration_status() >= CALIBRATION_STATUS_LIVE_ADJUST) - _md->babystepMem[2] = 0; + _md->babystepMemZ = 0; - _md->babystepMemMM[0] = _md->babystepMem[0]/cs.axis_steps_per_unit[X_AXIS]; - _md->babystepMemMM[1] = _md->babystepMem[1]/cs.axis_steps_per_unit[Y_AXIS]; - _md->babystepMemMM[2] = _md->babystepMem[2]/cs.axis_steps_per_unit[Z_AXIS]; + _md->babystepMemMMZ = _md->babystepMemZ/cs.axis_steps_per_unit[Z_AXIS]; lcd_draw_update = 1; //SERIAL_ECHO("Z baby step: "); //SERIAL_ECHO(_md->babystepMem[2]); @@ -3106,46 +3108,49 @@ static void _lcd_babystep(int axis, const char *msg) if (lcd_encoder != 0) { if (homing_flag) lcd_encoder = 0; - _md->babystepMem[axis] += (int)lcd_encoder; - if (axis == 2) - { - if (_md->babystepMem[axis] < Z_BABYSTEP_MIN) _md->babystepMem[axis] = Z_BABYSTEP_MIN; //-3999 -> -9.99 mm - else if (_md->babystepMem[axis] > Z_BABYSTEP_MAX) _md->babystepMem[axis] = Z_BABYSTEP_MAX; //0 - else - { - CRITICAL_SECTION_START - babystepsTodo[axis] += (int)lcd_encoder; - CRITICAL_SECTION_END - } - } - _md->babystepMemMM[axis] = _md->babystepMem[axis]/cs.axis_steps_per_unit[axis]; + _md->babystepMemZ += (int)lcd_encoder; + + if (_md->babystepMemZ < Z_BABYSTEP_MIN) _md->babystepMemZ = Z_BABYSTEP_MIN; //-3999 -> -9.99 mm + else if (_md->babystepMemZ > Z_BABYSTEP_MAX) _md->babystepMemZ = Z_BABYSTEP_MAX; //0 + else + { + CRITICAL_SECTION_START + babystepsTodo[Z_AXIS] += (int)lcd_encoder; + CRITICAL_SECTION_END + } + + _md->babystepMemMMZ = _md->babystepMemZ/cs.axis_steps_per_unit[Z_AXIS]; _delay(50); lcd_encoder = 0; lcd_draw_update = 1; } if (lcd_draw_update) { + SheetFormatBuffer buffer; + menu_format_sheet_E(EEPROM_Sheets_base->s[(eeprom_read_byte(&(EEPROM_Sheets_base->active_sheet)))], buffer); + lcd_set_cursor(0, 0); + lcd_print(buffer.c); lcd_set_cursor(0, 1); - menu_draw_float13(msg, _md->babystepMemMM[axis]); + menu_draw_float13(_i("Adjusting Z:"), _md->babystepMemMMZ); ////MSG_BABYSTEPPING_Z c=15 Beware: must include the ':' as its last character } if (LCD_CLICKED || menu_leaving) { // Only update the EEPROM when leaving the menu. - EEPROM_save_B( - (axis == X_AXIS) ? EEPROM_BABYSTEP_X : ((axis == Y_AXIS) ? EEPROM_BABYSTEP_Y : EEPROM_BABYSTEP_Z), - &_md->babystepMem[axis]); - if(Z_AXIS == axis) calibration_status_store(CALIBRATION_STATUS_CALIBRATED); + eeprom_update_word(reinterpret_cast(&(EEPROM_Sheets_base-> + s[(eeprom_read_byte(&(EEPROM_Sheets_base->active_sheet)))].z_offset)), + _md->babystepMemZ); + eeprom_update_byte(&(EEPROM_Sheets_base->s[(eeprom_read_byte( + &(EEPROM_Sheets_base->active_sheet)))].bed_temp), + target_temperature_bed); + eeprom_update_byte(&(EEPROM_Sheets_base->s[(eeprom_read_byte( + &(EEPROM_Sheets_base->active_sheet)))].pinda_temp), + current_temperature_pinda); + calibration_status_store(CALIBRATION_STATUS_CALIBRATED); } if (LCD_CLICKED) menu_back(); } -static void lcd_babystep_z() -{ - _lcd_babystep(Z_AXIS, (_i("Adjusting Z:")));////MSG_BABYSTEPPING_Z c=15 Beware: must include the ':' as its last character -} - - typedef struct { // 12bytes + 9bytes = 21bytes total menu_data_edit_t reserved; //12 bytes reserved for number editing functions @@ -6300,6 +6305,95 @@ void lcd_resume_print() isPrintPaused = false; } +static void change_sheet(uint8_t sheet_num) +{ + eeprom_update_byte(&(EEPROM_Sheets_base->active_sheet), sheet_num); + if(is_sheet_initialized()) + calibration_status_store(CALIBRATION_STATUS_CALIBRATED); + else + calibration_status_store(CALIBRATION_STATUS_LIVE_ADJUST); + + menu_back(3); +} + +static void lcd_select_sheet_0_menu() +{ + change_sheet(0); +} +static void lcd_select_sheet_1_menu() +{ + change_sheet(1); +} +static void lcd_select_sheet_2_menu() +{ + change_sheet(2); +} + +static void lcd_select_sheet_menu() +{ + MENU_BEGIN(); + MENU_ITEM_BACK_P(_T(MSG_BACK)); + MENU_ITEM_SUBMENU_E(EEPROM_Sheets_base->s[0], lcd_select_sheet_0_menu); + MENU_ITEM_SUBMENU_E(EEPROM_Sheets_base->s[1], lcd_select_sheet_1_menu); + MENU_ITEM_SUBMENU_E(EEPROM_Sheets_base->s[2], lcd_select_sheet_2_menu); + MENU_END(); +} + +static void lcd_rename_sheet_menu() +{ + struct MenuData + { + bool initialized; + uint8_t selected; + char name[sizeof(Sheet::name)]; + }; + static_assert(sizeof(menu_data)>= sizeof(MenuData),"MenuData doesn't fit into menu_data"); + MenuData* menuData = (MenuData*)&(menu_data[0]); + + if (!menuData->initialized) + { + eeprom_read_block(menuData->name, EEPROM_Sheets_base->s[(eeprom_read_byte(&(EEPROM_Sheets_base->active_sheet)))].name, sizeof(Sheet::name)); + lcd_encoder = menuData->name[0]; + menuData->initialized = true; + } + if (lcd_encoder < '\x20') lcd_encoder = '\x20'; + if (lcd_encoder > '\x7F') lcd_encoder = '\x7F'; + + menuData->name[menuData->selected] = lcd_encoder; + lcd_set_cursor(0,0); + for (uint_least8_t i = 0; i < sizeof(Sheet::name); ++i) + { + lcd_putc(menuData->name[i]); + } + lcd_set_cursor(menuData->selected, 1); + lcd_putc('^'); + if (lcd_clicked()) + { + if ((menuData->selected + 1u) < sizeof(Sheet::name)) + { + lcd_encoder = menuData->name[++(menuData->selected)]; + } + else + { + eeprom_update_block(menuData->name, + EEPROM_Sheets_base->s[(eeprom_read_byte(&(EEPROM_Sheets_base->active_sheet)))].name, + sizeof(Sheet::name)); + menu_back(); + } + } +} + +static void lcd_sheet_menu() +{ + MENU_BEGIN(); + MENU_ITEM_BACK_P(_T(MSG_MAIN)); + MENU_ITEM_SUBMENU_P(_T(MSG_SELECT), lcd_select_sheet_menu); //// c=18 + MENU_ITEM_SUBMENU_P(_T(MSG_RENAME), lcd_rename_sheet_menu); //// c=18 + MENU_ITEM_SUBMENU_P(_T(MSG_V2_CALIBRATION), lcd_v2_calibration); ////MSG_V2_CALIBRATION c=17 r=1 + + MENU_END(); +} + static void lcd_main_menu() { @@ -6321,55 +6415,6 @@ static void lcd_main_menu() MENU_ITEM_FUNCTION_P(PSTR("recover print"), recover_print); MENU_ITEM_FUNCTION_P(PSTR("power panic"), uvlo_); #endif //TMC2130_DEBUG - - /* if (farm_mode && !IS_SD_PRINTING ) - { - - int tempScrool = 0; - if (lcd_draw_update == 0 && LCD_CLICKED == 0) - //_delay(100); - return; // nothing to do (so don't thrash the SD card) - uint16_t fileCnt = card.getnrfilenames(); - - card.getWorkDirName(); - if (card.filename[0] == '/') - { -#if SDCARDDETECT == -1 - MENU_ITEM_FUNCTION_P(_T(MSG_REFRESH), lcd_sd_refresh); -#endif - } else { - MENU_ITEM_FUNCTION_P(PSTR(LCD_STR_FOLDER ".."), lcd_sd_updir); - } - - for (uint16_t i = 0; i < fileCnt; i++) - { - if (menu_item == menu_line) - { -#ifndef SDCARD_RATHERRECENTFIRST - card.getfilename(i); -#else - card.getfilename(fileCnt - 1 - i); -#endif - if (card.filenameIsDir) - { - MENU_ITEM_SDDIR(_T(MSG_CARD_MENU), card.filename, card.longFilename); - } else { - - MENU_ITEM_SDFILE(_T(MSG_CARD_MENU), card.filename, card.longFilename); - - - - - } - } else { - MENU_ITEM_DUMMY(); - } - } - - MENU_ITEM_BACK_P(PSTR("- - - - - - - - -")); - - - }*/ if ( ( IS_SD_PRINTING || is_usb_printing || (lcd_commands_type == LcdCommands::Layer1Cal)) && (current_position[Z_AXIS] < Z_HEIGHT_HIDE_LIVE_ADJUST_MENU) && !homing_flag && !mesh_bed_leveling_flag) { @@ -6385,6 +6430,8 @@ static void lcd_main_menu() MENU_ITEM_SUBMENU_P(_i("Preheat"), lcd_preheat_menu);////MSG_PREHEAT } + + #ifdef SDSUPPORT if (card.cardOK || lcd_commands_type == LcdCommands::Layer1Cal) { @@ -6475,6 +6522,8 @@ static void lcd_main_menu() } + if(!isPrintPaused)MENU_ITEM_SUBMENU_E(EEPROM_Sheets_base->s[(eeprom_read_byte(&(EEPROM_Sheets_base->active_sheet)))], lcd_sheet_menu); + if (!is_usb_printing && (lcd_commands_type != LcdCommands::Layer1Cal)) { MENU_ITEM_SUBMENU_P(_i("Statistics "), lcd_menu_statistics);////MSG_STATISTICS diff --git a/PF-build.sh b/PF-build.sh index a7cc25a9e..3c0c31ddc 100755 --- a/PF-build.sh +++ b/PF-build.sh @@ -426,14 +426,14 @@ do sleep 2 #$BUILDER -dump-prefs -logger=machine -hardware $ARDUINO/hardware -hardware $ARDUINO/portable/packages -tools $ARDUINO/tools-builder -tools $ARDUINO/hardware/tools/avr -tools $ARDUINO/portable/packages -built-in-libraries $ARDUINO/libraries -libraries $ARDUINO/portable/sketchbook/libraries -fqbn=rambo:avr:rambo -ide-version=10805 -build-path=$BUILD_PATH -warnings=none -quiet $SCRIPT_PATH/Firmware/Firmware.ino || exit 12 #$BUILDER -compile -logger=machine -hardware $ARDUINO/hardware -hardware $ARDUINO/portable/packages -tools $ARDUINO/tools-builder -tools $ARDUINO/hardware/tools/avr -tools $ARDUINO/portable/packages -built-in-libraries $ARDUINO/libraries -libraries $ARDUINO/portable/sketchbook/libraries -fqbn=rambo:avr:rambo -ide-version=10805 -build-path=$BUILD_PATH -warnings=none -quiet $SCRIPT_PATH/Firmware/Firmware.ino || exit 13 - $BUILDER -compile -hardware $ARDUINO/hardware -hardware $ARDUINO/portable/packages -tools $ARDUINO/tools-builder -tools $ARDUINO/hardware/tools/avr -tools $ARDUINO/portable/packages -built-in-libraries $ARDUINO/libraries -libraries $ARDUINO/portable/sketchbook/libraries -fqbn=rambo:avr:rambo -ide-version=10805 -build-path=$BUILD_PATH -warnings=default $SCRIPT_PATH/Firmware/Firmware.ino || exit 14 + $BUILDER -compile -hardware $ARDUINO/hardware -hardware $ARDUINO/portable/packages -tools $ARDUINO/tools-builder -tools $ARDUINO/hardware/tools/avr -tools $ARDUINO/portable/packages -built-in-libraries $ARDUINO/libraries -libraries $ARDUINO/portable/sketchbook/libraries -fqbn=rambo:avr:rambo -ide-version=10805 -build-path=$BUILD_PATH -warnings=all $SCRIPT_PATH/Firmware/Firmware.ino || exit 14 echo "$(tput sgr 0)" fi if [ $OSTYPE == "linux-gnu" ] ; then echo "Start to build Prusa Firmware under Linux 64..." echo "Using variant $VARIANT$(tput setaf 3)" sleep 2 - $BUILD_ENV_PATH/arduino $SCRIPT_PATH/Firmware/Firmware.ino --verify --board rambo:avr:rambo --pref build.path=$BUILD_PATH || exit 14 + $BUILD_ENV_PATH/arduino $SCRIPT_PATH/Firmware/Firmware.ino --verify --board rambo:avr:rambo --pref build.path=$BUILD_PATH --pref compiler.warning_level=all || exit 14 echo "$(tput sgr 0)" fi diff --git a/README.md b/README.md index f86389613..765204a50 100644 --- a/README.md +++ b/README.md @@ -14,8 +14,8 @@ # Build ## Linux -Run shell script build.sh to build for MK3 and flash with Sli3er. -If you have different printel model, follow step [2.b](#2b) from Windows build first. +Run shell script build.sh to build for MK3 and flash with Slic3er. +If you have a different printer model, follow step [2.b](#2b) from Windows build first. If you wish to flash from Arduino, follow step [2.c](#2c) from Windows build first. The script downloads Arduino with our modifications and Rambo board support installed, unpacks it into folder PF-build-env-\ on the same level, as your Prusa-Firmware folder is located, builds firmware for MK3 using that Arduino in Prusa-Firmware-build folder on the same level as Prusa-Firmware, runs secondary language support scripts. Firmware with secondary language support is generated in lang subfolder. Use firmware.hex for MK3 variant. Use firmware_\.hex for other printers. Don't forget to follow step [2.b](#2b) first for non-MK3 printers. @@ -40,11 +40,11 @@ type location or you can 'manually' modify the item `"boardsmanager.additional.urls=....."` at the file `"preferences.txt"` (this parameter allows you to write a comma-separated list of addresses) -_note: you can find location of this file on your disk by following way: +_note: you can find location of this file on your disk by doing the following: `File->Preferences->Settings` (`"More preferences can be edited in file ..."`)_ -than do it +then choose `Tools->Board->BoardsManager` -from viewed list select an item `"RAMBo"` (will probably be labeled as `"RepRap Arduino-compatible Mother Board (RAMBo) by UltiMachine"` +from viewed list and select the item labeled `"RAMBo"` (will probably be labeled as `"RepRap Arduino-compatible Mother Board (RAMBo) by UltiMachine"` _note: select this item for any variant of board used in printers `'Prusa i3 MKx'`, that is for `RAMBo-mini x.y` and `EINSy x.y` to_ 'clicking' the item will display the installation button; select choice `"1.0.1"` from the list(last known version as of the date of issue of this document) _(after installation, the item is labeled as `"INSTALLED"` and can then be used for target board selection)_ @@ -66,7 +66,7 @@ b. In the subdirectory `"Firmware/variants/"` select the config c. In file `"Firmware/config.h"` set LANG_MODE to 0. -run `"Arduino IDE"`; select the file `"Firmware.ino"` from the subdirectory `"Firmware/"` at the location, where you placed the source codes +run `"Arduino IDE"`; select the file `"Firmware.ino"` from the subdirectory `"Firmware/"` at the location, where you placed the source code `File->Open` make the desired code customizations; **all changes are on your own risk!** @@ -146,7 +146,7 @@ cmake build system - ninja or gnu make ## Building -Create folder where you want to build tests. +Create a folder where you want to build tests. Example: diff --git a/lang/lang-build.sh b/lang/lang-build.sh index e528ff94d..b8c2476eb 100755 --- a/lang/lang-build.sh +++ b/lang/lang-build.sh @@ -82,7 +82,7 @@ generate_binary() rm -f lang_$1.dat LNG=$1 #check lang dictionary - /usr/bin/env python lang-check.py $1 + /usr/bin/env python lang-check.py $1 --no-warning #create lang_xx.tmp - different processing for 'en' language if [ "$1" = "en" ]; then #remove comments and empty lines