diff --git a/Firmware/Configuration.h b/Firmware/Configuration.h index 8a4ee3442..5bd897e17 100644 --- a/Firmware/Configuration.h +++ b/Firmware/Configuration.h @@ -72,6 +72,9 @@ // Magic string, indicating that the current or the previous firmware running was the Prusa3D firmware. #define EEPROM_FIRMWARE_PRUSA_MAGIC 0 +// Enable this for M767/M768 dump & restore EEPROM +#define EEPROM_SAVE_RESTORE + // This configuration file contains the basic settings. // Advanced settings can be found in Configuration_adv.h // BASIC SETTINGS: select your board type, temperature sensor type, axis scaling, and endstop configuration diff --git a/Firmware/Marlin_main.cpp b/Firmware/Marlin_main.cpp index 633f1baeb..389ce6117 100644 --- a/Firmware/Marlin_main.cpp +++ b/Firmware/Marlin_main.cpp @@ -1490,7 +1490,6 @@ void get_command() continue; if(serial_char == '\n' || serial_char == '\r' || - (serial_char == ':' && comment_mode == false) || serial_count >= (MAX_CMD_SIZE - 1) ) { if(!serial_count) { //if empty line @@ -1658,7 +1657,6 @@ void get_command() if(serial_char == '\n' || serial_char == '\r' || (serial_char == '#' && comment_mode == false) || - (serial_char == ':' && comment_mode == false) || serial_count >= (MAX_CMD_SIZE - 1)||n==-1) { if(card.eof()){ @@ -1918,6 +1916,171 @@ static float probe_pt(float x, float y, float z_before) { #endif // #ifdef ENABLE_AUTO_BED_LEVELING +#if defined(EEPROM_SAVE_RESTORE) + /** + * M767: Dump EEPROM to serial (suitable for restore) or to SD File + * Ex: M767 S --> dump to SD card 'eesave.hex' + * M767 P --> Write M768 P V to SERIAL + * M767 X --> dump entire EEPROM to SERIAL + * M768: Set EEPROM location from value + * Ex: M768 P V + * M768 R --> restore from SD card + * + */ +#ifdef SDSUPPORT +#define EECHUNKSIZE 32 +// :EOL +#define EELINESIZE (1 + 2 + 4 + 2 + (2 * EECHUNKSIZE) + 2 + 1) +static char linebfr[EELINESIZE + 1]; + +static uint16_t bfrVal(char *ptr, uint8_t len) +{ + uint16_t retval = 0; + char ch; + + for (uint8_t i = 0; i < len; i++) { + ch = *ptr++; + retval <<= 4; + if (ch >= 'A') + retval += 9 + (ch & 0x0F); + else + retval += ch & 0x0F; + } + + return retval; +} +#endif + + +void gcode_M767() { + if (code_seen('S')) { +#ifdef SDSUPPORT + // Save EEPROM to SD + uint8_t nch, i; + + // Only if no other files open and not printing + if (IS_SD_PRINTING || is_usb_printing) + return; + + // Reset SD card and write to root + card.initsd(); + // Overwrite existing + card.openFile((char *)"eesave.hex", false, true); + for (unsigned long ofs = 0; ofs < 4096; ofs += EECHUNKSIZE) { + int8_t cksum = EECHUNKSIZE; + nch = sprintf_P(linebfr, PSTR(":%02X%04X00"), EECHUNKSIZE, ofs); + cksum += (ofs & 0xFF) + ((ofs >> 8) & 0xFF); + for (i = 0; i < EECHUNKSIZE; i++) { + uint8_t eeval = eeprom_read_byte((unsigned char *)(ofs + i)); + cksum += eeval; + nch += sprintf_P(linebfr + nch, PSTR("%02X"), eeval); + } + + nch += sprintf_P(linebfr + nch, PSTR("%02X\n"), (-cksum) & 0xFF); + if (card.write_buf(linebfr, nch) != nch) { + SERIAL_ERROR_START; + SERIAL_ERRORLNRPGM(MSG_SD_ERR_WRITE_TO_FILE); + break; + } + } + + // Close file + card.closefile(false); + SERIAL_ECHOLNPGM("EEPROM saved"); +#else + return; +#endif + } else { + if (code_seen('P')) { + uint16_t addrs = code_value_short(); + SERIAL_ECHOPAIR("M768 P", (unsigned long)addrs); + SERIAL_ECHOPAIR(" V", (unsigned long)eeprom_read_byte((unsigned char *)addrs)); + SERIAL_ECHOLN(""); + } else { + if (code_seen('X')) { + for (unsigned long ofs = 0; ofs < 4096; ofs++) { + SERIAL_ECHOPAIR("M768 P", ofs); + SERIAL_ECHOPAIR(" V", (unsigned long)eeprom_read_byte((unsigned char *)ofs)); + SERIAL_ECHOLN(""); + } + } + } + } + + return; +} + +void gcode_M768() { + uint16_t addrs; + + if (code_seen('P')) { + addrs = code_value_short(); + + // Write value to offset + // Erase (set to 0xFF) if no value given + eeprom_update_byte((unsigned char *)addrs, + code_seen('V') ? code_value_uint8() : 0xFF); + } +#ifdef SDSUPPORT + else if (code_seen('R')) { + // Restore EEPROM from SD + // Only if no other files open and not printing + if (IS_SD_PRINTING || is_usb_printing) + return; + + // Reset SD card and write to root + card.initsd(); + // Open existing + card.openFile((char *)"eesave.hex", true); + if (!card.isFileOpen()) + return; + + for (unsigned long ofs = 0; ofs < 4096; ofs += EECHUNKSIZE) { + if (card.read_buf(linebfr, EELINESIZE) != EELINESIZE) + return; + + // Validate buffer header + if ((linebfr[0] != ':') || (bfrVal(&linebfr[1], 2) != EECHUNKSIZE) || + (bfrVal(&linebfr[7], 2) != 0)) { + SERIAL_ERROR_START; + SERIAL_ERRORLNPGM("Header mis-match"); + return; + } + + // Validate checksum + int8_t cksum = 0; + for (uint8_t i = 1; i < EELINESIZE - 1; i += 2) { + cksum += bfrVal(&linebfr[i], 2); + } + if (cksum != 0) { + SERIAL_ERROR_START; + SERIAL_ERRORLNPGM("Bad checksum"); + return; + } + + addrs = bfrVal(&linebfr[3], 4); + if (addrs > 4064) { + SERIAL_ERROR_START; + SERIAL_ERRORLNPGM("Bad EEPROM offset"); + return; + } + // Things look OK - (re-)write EEPROM + for (uint8_t i = 0; i < EECHUNKSIZE; i++) { + uint8_t eeval = bfrVal(&linebfr[9 + (i * 2)], 2); + eeprom_update_byte((unsigned char *)(addrs + i), eeval); + } + } + + // All done with restore + card.closefile(); + SERIAL_ECHOLNPGM("EEPROM restored"); + } +#endif + + return; +} +#endif // EEPROM_SAVE_RESTORE + #ifdef LIN_ADVANCE /** * M900: Set and/or Get advance K factor and WH/D ratio @@ -5820,6 +5983,15 @@ case 404: //M404 Enter the nominal filament width (3mm, 1.75mm ) N<3.0> or disp } break; +#if defined(EEPROM_SAVE_RESTORE) + case 767: // Dump eeprom + gcode_M767(); + break; + case 768: // Load eeprom location + gcode_M768(); + break; +#endif + case 999: // M999: Restart after being stopped Stopped = false; lcd_reset_alert_level(); diff --git a/Firmware/cardreader.h b/Firmware/cardreader.h index 3ce327d62..aa160259b 100644 --- a/Firmware/cardreader.h +++ b/Firmware/cardreader.h @@ -64,6 +64,11 @@ public: FORCE_INLINE uint8_t percentDone(){if(!isFileOpen()) return 0; if(filesize) return sdpos/((filesize+99)/100); else return 0;}; FORCE_INLINE char* getWorkDirName(){workDir.getFilename(filename);return filename;}; +#ifdef EEPROM_SAVE_RESTORE + FORCE_INLINE int16_t write_buf(void *buf, uint16_t cnt) { return file.write(buf, cnt); } + FORCE_INLINE int16_t read_buf(void *buf, uint16_t cnt) { return file.read(buf, cnt); } +#endif + bool ToshibaFlashAir_isEnabled() const { return card.getFlashAirCompatible(); } void ToshibaFlashAir_enable(bool enable) { card.setFlashAirCompatible(enable); } bool ToshibaFlashAir_GetIP(uint8_t *ip); diff --git a/Firmware/mesh_bed_calibration.cpp b/Firmware/mesh_bed_calibration.cpp index a3fd741f1..293d3b9a1 100644 --- a/Firmware/mesh_bed_calibration.cpp +++ b/Firmware/mesh_bed_calibration.cpp @@ -449,8 +449,8 @@ BedSkewOffsetDetectionResultType calculate_machine_skew_and_offset_LS( } #endif // SUPPORT_VERBOSITY - #if 0 - if (result == BED_SKEW_OFFSET_DETECTION_PERFECT && fabs(a1) < bed_skew_angle_mild && fabs(a2) < bed_skew_angle_mild) { + #if 1 + if (result == BED_SKEW_OFFSET_DETECTION_PERFECT) { if (verbosity_level > 0) SERIAL_ECHOLNPGM("Very little skew detected. Disabling skew correction."); // Just disable the skew correction. diff --git a/platformio.ini b/platformio.ini new file mode 100644 index 000000000..122994593 --- /dev/null +++ b/platformio.ini @@ -0,0 +1,31 @@ +; PlatformIO Project Configuration File +; +; Build options: build flags, source filter +; Upload options: custom upload port, speed and extra flags +; Library options: dependencies, extra library storages +; Advanced options: extra scripting +; +; Please visit documentation for the other options and examples +; http://docs.platformio.org/page/projectconf.html +; +; Note: set 'lib_dir' to installed location of Arduino libraries to use. Make sure you +; can build successfully with IDE first. +; +; $ platformio run --target clean +; $ platformio run +; +; Resultant image: ./pbuild/rambo/firmware.hex +; Flash image w/avrdude (for example) +; $ avrdude -v -p m2560 -c wiring -P /dev/ttyUSB0 -b 115200 -U "flash:w:firmware.hex:i" -D + +[platformio] +src_dir=./Firmware +lib_dir=/opt/arduino-1.8.4/libraries +envs_dir=./pbuild +env_default = rambo + +[env:rambo] +platform=atmelavr +board=reprap_rambo +framework=arduino +build_flags = -I$BUILDSRC_DIR -Wall -Wextra -Wno-unused-parameter -Wno-empty-body