/ Repetier / Eeprom.cpp
Eeprom.cpp
  1  /*
  2      This file is part of Repetier-Firmware.
  3  
  4      Repetier-Firmware is free software: you can redistribute it and/or modify
  5      it under the terms of the GNU General Public License as published by
  6      the Free Software Foundation, either version 3 of the License, or
  7      (at your option) any later version.
  8  
  9      Repetier-Firmware is distributed in the hope that it will be useful,
 10      but WITHOUT ANY WARRANTY; without even the implied warranty of
 11      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 12      GNU General Public License for more details.
 13  
 14      You should have received a copy of the GNU General Public License
 15      along with Repetier-Firmware.  If not, see <http://www.gnu.org/licenses/>.
 16  
 17      This firmware is a nearly complete rewrite of the sprinter firmware
 18      by kliment (https://github.com/kliment/Sprinter)
 19      which based on Tonokip RepRap firmware rewrite based off of Hydra-mmm firmware.
 20  
 21    Functions in this file are used to communicate using ascii or repetier protocol.
 22  */
 23  
 24  #include "Reptier.h"
 25  
 26  #if EEPROM_MODE!=0
 27  #include "Eeprom.h"
 28  extern void epr_eeprom_to_data();
 29  
 30  byte epr_compute_checksum() {
 31    int i;
 32    byte checksum=0;
 33    for(i=0;i<2048;i++) {
 34      if(i==EEPROM_OFFSET+EPR_INTEGRITY_BYTE) continue;
 35      checksum += eeprom_read_byte ((unsigned char *)(i));
 36    }
 37    return checksum;
 38  }
 39  
 40  
 41  
 42  inline void epr_set_byte(uint pos,byte value) {
 43    eeprom_write_byte((unsigned char *)(EEPROM_OFFSET+pos), value);
 44  }
 45  inline void epr_set_int(uint pos,int value) {
 46    eeprom_write_word((unsigned int*)(EEPROM_OFFSET+pos),value);
 47  }
 48  inline void epr_set_long(uint pos,long value) {
 49    eeprom_write_dword((unsigned long*)(EEPROM_OFFSET+pos),value);
 50  }
 51  inline void epr_set_float(uint pos,float value) {
 52    eeprom_write_block(&value,(void*)(EEPROM_OFFSET+pos), 4);
 53  }
 54  void epr_out_prefix(uint pos) {
 55    if(pos<EEPROM_EXTRUDER_OFFSET) return;
 56    int n = (pos-EEPROM_EXTRUDER_OFFSET)/EEPROM_EXTRUDER_LENGTH+1;
 57    OUT_P_I("Extr.",n);
 58    out.print(' ');
 59  }
 60  void epr_out_float(uint pos,PGM_P text) {
 61    OUT_P("EPR:3 ");
 62    OUT(pos);
 63    OUT(' ');
 64    OUT(epr_get_float(pos));
 65    OUT(' ');
 66    epr_out_prefix(pos);
 67    out.println_P(text);  
 68  }
 69  void epr_out_long(uint pos,PGM_P text) {
 70    OUT_P("EPR:2 ");
 71    OUT(pos);
 72    OUT(' ');
 73    OUT(epr_get_long(pos));
 74    OUT(' ');
 75    epr_out_prefix(pos);
 76    out.println_P(text);  
 77  }
 78  void epr_out_int(uint pos,PGM_P text) {
 79    OUT_P("EPR:1 ");
 80    OUT(pos);
 81    OUT(' ');
 82    OUT(epr_get_int(pos));
 83    OUT(' ');
 84    epr_out_prefix(pos);
 85    out.println_P(text);  
 86  }
 87  void epr_out_byte(uint pos,PGM_P text) {
 88    OUT_P("EPR:0 ");
 89    OUT(pos);
 90    OUT(' ');
 91    OUT((int)epr_get_byte(pos));
 92    OUT(' ');
 93    epr_out_prefix(pos);
 94    out.println_P(text);  
 95  }
 96  
 97  void epr_update(GCode *com) {
 98    if(GCODE_HAS_T(com) && GCODE_HAS_P(com)) switch(com->T) {
 99      case 0:
100        if(GCODE_HAS_S(com)) epr_set_byte(com->P,(byte)com->S);
101        break;
102      case 1:
103        if(GCODE_HAS_S(com)) epr_set_int(com->P,(int)com->S);
104        break;
105      case 2:
106        if(GCODE_HAS_S(com)) epr_set_long(com->P,(long)com->S);
107        break;
108      case 3:
109        if(GCODE_HAS_X(com)) epr_set_float(com->P,com->X);
110        break;
111    }
112    byte newcheck = epr_compute_checksum();
113    if(newcheck!=epr_get_byte(EPR_INTEGRITY_BYTE))
114      epr_set_byte(EPR_INTEGRITY_BYTE,newcheck);
115    epr_eeprom_to_data();
116  }
117  
118  /** \brief Copy data from EEPROM to variables.
119  */
120  void epr_eeprom_reset() {
121    byte version = EEPROM_PROTOCOL_VERSION;
122    baudrate = BAUDRATE;
123    max_inactive_time = MAX_INACTIVE_TIME*1000L;
124    stepper_inactive_time = STEPPER_INACTIVE_TIME*1000L;
125    axis_steps_per_unit[0] = XAXIS_STEPS_PER_MM;
126    axis_steps_per_unit[1] = YAXIS_STEPS_PER_MM; 
127    axis_steps_per_unit[2] = ZAXIS_STEPS_PER_MM;
128    axis_steps_per_unit[3] = 1;
129    max_feedrate[0] = MAX_FEEDRATE_X;
130    max_feedrate[1] = MAX_FEEDRATE_Y;
131    max_feedrate[2] = MAX_FEEDRATE_Z;
132    homing_feedrate[0] = HOMING_FEEDRATE_X;
133    homing_feedrate[1] = HOMING_FEEDRATE_Y;
134    homing_feedrate[2] = HOMING_FEEDRATE_Z;
135    printer_state.maxJerk = MAX_JERK;
136    printer_state.maxZJerk = MAX_ZJERK;
137  #ifdef RAMP_ACCELERATION
138    max_acceleration_units_per_sq_second[0] = MAX_ACCELERATION_UNITS_PER_SQ_SECOND_X;
139    max_acceleration_units_per_sq_second[1] = MAX_ACCELERATION_UNITS_PER_SQ_SECOND_Y;
140    max_acceleration_units_per_sq_second[2] = MAX_ACCELERATION_UNITS_PER_SQ_SECOND_Z;
141    max_travel_acceleration_units_per_sq_second[0] = MAX_TRAVEL_ACCELERATION_UNITS_PER_SQ_SECOND_X;
142    max_travel_acceleration_units_per_sq_second[1] = MAX_TRAVEL_ACCELERATION_UNITS_PER_SQ_SECOND_X;
143    max_travel_acceleration_units_per_sq_second[2] = MAX_TRAVEL_ACCELERATION_UNITS_PER_SQ_SECOND_X;
144  #endif
145  #if USE_OPS==1
146    printer_state.opsMode = OPS_MODE;
147    printer_state.opsMinDistance = OPS_MIN_DISTANCE;
148    printer_state.opsRetractDistance = OPS_RETRACT_DISTANCE;
149    printer_state.opsRetractBacklash = OPS_RETRACT_BACKLASH;
150    printer_state.opsMoveAfter = 0;
151  #endif
152  #if HAVE_HEATED_BED
153    heatedBedController.heatManager= HEATED_BED_HEAT_MANAGER;
154  #ifdef TEMP_PID
155    heatedBedController.pidDriveMax = HEATED_BED_PID_INTEGRAL_DRIVE_MAX;
156    heatedBedController.pidDriveMin = HEATED_BED_PID_INTEGRAL_DRIVE_MIN;
157    heatedBedController.pidPGain = HEATED_BED_PID_PGAIN;
158    heatedBedController.pidIGain = HEATED_BED_PID_IGAIN;
159    heatedBedController.pidDGain = HEATED_BED_PID_DGAIN;
160    heatedBedController.pidMax = HEATED_BED_PID_MAX;
161  #endif
162  #endif
163    printer_state.xLength = X_MAX_LENGTH;
164    printer_state.yLength = Y_MAX_LENGTH;
165    printer_state.zLength = Z_MAX_LENGTH;
166    printer_state.xMin = X_MIN_POS;
167    printer_state.yMin = Y_MIN_POS;
168    printer_state.zMin = Z_MIN_POS;
169  #if ENABLE_BACKLASH_COMPENSATION
170    printer_state.backlashX = X_BACKLASH;
171    printer_state.backlashY = Y_BACKLASH;
172    printer_state.backlashZ = Z_BACKLASH;
173  #endif
174    Extruder *e;
175  #if NUM_EXTRUDER>0
176    e = &extruder[0];
177    e->stepsPerMM = EXT0_STEPS_PER_MM;
178    e->maxFeedrate = EXT0_MAX_FEEDRATE;
179    e->maxStartFeedrate = EXT0_MAX_START_FEEDRATE;
180    e->maxAcceleration = EXT0_MAX_ACCELERATION;
181    e->tempControl.heatManager = EXT0_HEAT_MANAGER;
182  #ifdef TEMP_PID
183    e->tempControl.pidDriveMax = EXT0_PID_INTEGRAL_DRIVE_MAX;
184    e->tempControl.pidDriveMin = EXT0_PID_INTEGRAL_DRIVE_MIN;
185    e->tempControl.pidPGain = EXT0_PID_P;
186    e->tempControl.pidIGain = EXT0_PID_I;
187    e->tempControl.pidDGain = EXT0_PID_D;
188    e->tempControl.pidMax = EXT0_PID_MAX;
189  #endif
190    e->yOffset = EXT0_Y_OFFSET;
191    e->xOffset = EXT0_X_OFFSET;
192    e->watchPeriod = EXT0_WATCHPERIOD;
193  #if RETRACT_DURING_HEATUP
194    e->waitRetractTemperature = EXT0_WAIT_RETRACT_TEMP;
195    e->waitRetractUnits = EXT0_WAIT_RETRACT_UNITS;
196  #endif
197    e->coolerSpeed = EXT0_EXTRUDER_COOLER_SPEED;
198  #ifdef USE_ADVANCE
199  #ifdef ENABLE_QUADRATIC_ADVANCE
200    e->advanceK = EXT0_ADVANCE_K;
201  #endif
202    e->advanceL = EXT0_ADVANCE_L;
203  #endif
204  #endif // NUM_EXTRUDER>0
205  #if NUM_EXTRUDER>1
206    e = &extruder[1];
207    e->stepsPerMM = EXT1_STEPS_PER_MM;
208    e->maxFeedrate = EXT1_MAX_FEEDRATE;
209    e->maxStartFeedrate = EXT1_MAX_START_FEEDRATE;
210    e->maxAcceleration = EXT1_MAX_ACCELERATION;
211    e->tempControl.heatManager = EXT1_HEAT_MANAGER;
212  #ifdef TEMP_PID
213    e->tempControl.pidDriveMax = EXT1_PID_INTEGRAL_DRIVE_MAX;
214    e->tempControl.pidDriveMin = EXT1_PID_INTEGRAL_DRIVE_MIN;
215    e->tempControl.pidPGain = EXT1_PID_P;
216    e->tempControl.pidIGain = EXT1_PID_I;
217    e->tempControl.pidDGain = EXT1_PID_D;
218    e->tempControl.pidMax = EXT1_PID_MAX;
219  #endif
220    e->yOffset = EXT1_Y_OFFSET;
221    e->xOffset = EXT1_X_OFFSET;
222    e->watchPeriod = EXT1_WATCHPERIOD;
223  #if RETRACT_DURING_HEATUP
224    e->waitRetractTemperature = EXT1_WAIT_RETRACT_TEMP;
225    e->waitRetractUnits = EXT1_WAIT_RETRACT_UNITS;
226  #endif
227    e->coolerSpeed = EXT1_EXTRUDER_COOLER_SPEED;
228  #ifdef USE_ADVANCE
229  #ifdef ENABLE_QUADRATIC_ADVANCE
230    e->advanceK = EXT1_ADVANCE_K;
231  #endif
232    e->advanceL = EXT1_ADVANCE_L;
233  #endif
234  #endif // NUM_EXTRUDER > 1
235  #if NUM_EXTRUDER>2
236    e = &extruder[2];
237    e->stepsPerMM = EXT2_STEPS_PER_MM;
238    e->maxFeedrate = EXT2_MAX_FEEDRATE;
239    e->maxStartFeedrate = EXT2_MAX_START_FEEDRATE;
240    e->maxAcceleration = EXT2_MAX_ACCELERATION;
241    e->tempControl.heatManager = EXT2_HEAT_MANAGER;
242  #ifdef TEMP_PID
243    e->tempControl.pidDriveMax = EXT2_PID_INTEGRAL_DRIVE_MAX;
244    e->tempControl.pidDriveMin = EXT2_PID_INTEGRAL_DRIVE_MIN;
245    e->tempControl.pidPGain = EXT2_PID_P;
246    e->tempControl.pidIGain = EXT2_PID_I;
247    e->tempControl.pidDGain = EXT2_PID_D;
248    e->tempControl.pidMax = EXT2_PID_MAX;
249  #endif
250    e->yOffset = EXT2_Y_OFFSET;
251    e->xOffset = EXT2_X_OFFSET;
252    e->watchPeriod = EXT2_WATCHPERIOD;
253  #if RETRACT_DURING_HEATUP
254    e->waitRetractTemperature = EXT2_WAIT_RETRACT_TEMP;
255    e->waitRetractUnits = EXT2_WAIT_RETRACT_UNITS;
256  #endif
257    e->coolerSpeed = EXT2_EXTRUDER_COOLER_SPEED;
258  #ifdef USE_ADVANCE
259  #ifdef ENABLE_QUADRATIC_ADVANCE
260    e->advanceK = EXT2_ADVANCE_K;
261  #endif
262    e->advanceL = EXT2_ADVANCE_L;
263  #endif
264  #endif // NUM_EXTRUDER > 2
265  #if NUM_EXTRUDER>3
266    e = &extruder[3];
267    e->stepsPerMM = EXT3_STEPS_PER_MM;
268    e->maxFeedrate = EXT3_MAX_FEEDRATE;
269    e->maxStartFeedrate = EXT3_MAX_START_FEEDRATE;
270    e->maxAcceleration = EXT3_MAX_ACCELERATION;
271    e->tempControl.heatManager = EXT3_HEAT_MANAGER;
272  #ifdef TEMP_PID
273    e->tempControl.pidDriveMax = EXT3_PID_INTEGRAL_DRIVE_MAX;
274    e->tempControl.pidDriveMin = EXT3_PID_INTEGRAL_DRIVE_MIN;
275    e->tempControl.pidPGain = EXT3_PID_P;
276    e->tempControl.pidIGain = EXT3_PID_I;
277    e->tempControl.pidDGain = EXT3_PID_D;
278    e->tempControl.pidMax = EXT3_PID_MAX;
279  #endif
280    e->yOffset = EXT3_Y_OFFSET;
281    e->xOffset = EXT3_X_OFFSET;
282    e->watchPeriod = EXT3_WATCHPERIOD;
283  #if RETRACT_DURING_HEATUP
284    e->waitRetractTemperature = EXT3_WAIT_RETRACT_TEMP;
285    e->waitRetractUnits = EXT3_WAIT_RETRACT_UNITS;
286  #endif
287    e->coolerSpeed = EXT3_EXTRUDER_COOLER_SPEED;
288  #ifdef USE_ADVANCE
289  #ifdef ENABLE_QUADRATIC_ADVANCE
290    e->advanceK = EXT3_ADVANCE_K;
291  #endif
292    e->advanceL = EXT3_ADVANCE_L;
293  #endif
294  #endif // NUM_EXTRUDER > 3
295  #if NUM_EXTRUDER>4
296    e = &extruder[4];
297    e->stepsPerMM = EXT4_STEPS_PER_MM;
298    e->maxFeedrate = EXT4_MAX_FEEDRATE;
299    e->maxStartFeedrate = EXT4_MAX_START_FEEDRATE;
300    e->maxAcceleration = EXT4_MAX_ACCELERATION;
301    e->tempControl.heatManager = EXT4_HEAT_MANAGER;
302  #ifdef TEMP_PID
303    e->tempControl.pidDriveMax = EXT4_PID_INTEGRAL_DRIVE_MAX;
304    e->tempControl.pidDriveMin = EXT4_PID_INTEGRAL_DRIVE_MIN;
305    e->tempControl.pidPGain = EXT4_PID_P;
306    e->tempControl.pidIGain = EXT4_PID_I;
307    e->tempControl.pidDGain = EXT4_PID_D;
308    e->tempControl.pidMax = EXT4_PID_MAX;
309  #endif
310    e->yOffset = EXT4_Y_OFFSET;
311    e->xOffset = EXT4_X_OFFSET;
312    e->watchPeriod = EXT4_WATCHPERIOD;
313  #if RETRACT_DURING_HEATUP
314    e->waitRetractTemperature = EXT4_WAIT_RETRACT_TEMP;
315    e->waitRetractUnits = EXT4_WAIT_RETRACT_UNITS;
316  #endif
317    e->coolerSpeed = EXT4_EXTRUDER_COOLER_SPEED;
318  #ifdef USE_ADVANCE
319  #ifdef ENABLE_QUADRATIC_ADVANCE
320    e->advanceK = EXT4_ADVANCE_K;
321  #endif
322    e->advanceL = EXT4_ADVANCE_L;
323  #endif
324  #endif // NUM_EXTRUDER > 4
325  #if NUM_EXTRUDER>5
326    e = &extruder[5];
327    e->stepsPerMM = EXT5_STEPS_PER_MM;
328    e->maxFeedrate = EXT5_MAX_FEEDRATE;
329    e->maxStartFeedrate = EXT5_MAX_START_FEEDRATE;
330    e->maxAcceleration = EXT5_MAX_ACCELERATION;
331    e->tempControl.heatManager = EXT5_HEAT_MANAGER;
332  #ifdef TEMP_PID
333    e->tempControl.pidDriveMax = EXT5_PID_INTEGRAL_DRIVE_MAX;
334    e->tempControl.pidDriveMin = EXT5_PID_INTEGRAL_DRIVE_MIN;
335    e->tempControl.pidPGain = EXT5_PID_P;
336    e->tempControl.pidIGain = EXT5_PID_I;
337    e->tempControl.pidDGain = EXT5_PID_D;
338    e->tempControl.pidMax = EXT5_PID_MAX;
339  #endif
340    e->yOffset = EXT5_Y_OFFSET;
341    e->xOffset = EXT5_X_OFFSET;
342    e->watchPeriod = EXT5_WATCHPERIOD;
343  #if RETRACT_DURING_HEATUP
344    e->waitRetractTemperature = EXT5_WAIT_RETRACT_TEMP;
345    e->waitRetractUnits = EXT5_WAIT_RETRACT_UNITS;
346  #endif
347    e->coolerSpeed = EXT5_EXTRUDER_COOLER_SPEED;
348  #ifdef USE_ADVANCE
349  #ifdef ENABLE_QUADRATIC_ADVANCE
350    e->advanceK = EXT5_ADVANCE_K;
351  #endif
352    e->advanceL = EXT5_ADVANCE_L;
353  #endif
354  #endif // NUM_EXTRUDER > 5
355    extruder_select(current_extruder->id);
356    update_ramps_parameter();
357    initHeatedBed();
358  }
359  /** \brief Moves current settings to EEPROM.
360  
361  The values the are currently set are used to fill the eeprom.*/
362  void epr_data_to_eeprom(byte corrupted) {
363    epr_set_long(EPR_BAUDRATE,baudrate);
364    epr_set_long(EPR_MAX_INACTIVE_TIME,max_inactive_time);
365    epr_set_long(EPR_STEPPER_INACTIVE_TIME,stepper_inactive_time);
366  //#define EPR_ACCELERATION_TYPE 1
367    epr_set_float(EPR_XAXIS_STEPS_PER_MM,axis_steps_per_unit[0]);
368    epr_set_float(EPR_YAXIS_STEPS_PER_MM,axis_steps_per_unit[1]);
369    epr_set_float(EPR_ZAXIS_STEPS_PER_MM,axis_steps_per_unit[2]);
370    epr_set_float(EPR_X_MAX_FEEDRATE,max_feedrate[0]);
371    epr_set_float(EPR_Y_MAX_FEEDRATE,max_feedrate[1]);
372    epr_set_float(EPR_Z_MAX_FEEDRATE,max_feedrate[2]);
373    epr_set_float(EPR_X_HOMING_FEEDRATE,homing_feedrate[0]);
374    epr_set_float(EPR_Y_HOMING_FEEDRATE,homing_feedrate[1]);
375    epr_set_float(EPR_Z_HOMING_FEEDRATE,homing_feedrate[2]);
376    epr_set_float(EPR_MAX_JERK,printer_state.maxJerk);
377    epr_set_float(EPR_MAX_ZJERK,printer_state.maxZJerk);
378  #ifdef RAMP_ACCELERATION
379    epr_set_float(EPR_X_MAX_ACCEL,max_acceleration_units_per_sq_second[0]);
380    epr_set_float(EPR_Y_MAX_ACCEL,max_acceleration_units_per_sq_second[1]);
381    epr_set_float(EPR_Z_MAX_ACCEL,max_acceleration_units_per_sq_second[2]);
382    epr_set_float(EPR_X_MAX_TRAVEL_ACCEL,max_travel_acceleration_units_per_sq_second[0]);
383    epr_set_float(EPR_Y_MAX_TRAVEL_ACCEL,max_travel_acceleration_units_per_sq_second[1]);
384    epr_set_float(EPR_Z_MAX_TRAVEL_ACCEL,max_travel_acceleration_units_per_sq_second[2]);
385  #endif
386  #if USE_OPS==1
387    epr_set_float(EPR_OPS_MIN_DISTANCE,printer_state.opsMinDistance);
388    epr_set_byte(EPR_OPS_MODE,printer_state.opsMode);
389    epr_set_float(EPR_OPS_MOVE_AFTER,printer_state.opsMoveAfter);
390    epr_set_float(EPR_OPS_RETRACT_DISTANCE,printer_state.opsRetractDistance);
391    epr_set_float(EPR_OPS_RETRACT_BACKLASH,printer_state.opsRetractBacklash);
392  #else
393    epr_set_float(EPR_OPS_MIN_DISTANCE,OPS_MIN_DISTANCE);
394    epr_set_byte(EPR_OPS_MODE,OPS_MODE);
395    epr_set_float(EPR_OPS_MOVE_AFTER,OPS_MOVE_AFTER);
396    epr_set_float(EPR_OPS_RETRACT_DISTANCE,OPS_RETRACT_DISTANCE);
397    epr_set_float(EPR_OPS_RETRACT_BACKLASH,OPS_RETRACT_BACKLASH);
398  #endif
399  #if HAVE_HEATED_BED
400    epr_set_byte(EPR_BED_HEAT_MANAGER,heatedBedController.heatManager);
401  #else
402    epr_set_byte(EPR_BED_HEAT_MANAGER,HEATED_BED_HEAT_MANAGER);
403  #endif
404  #if defined(TEMP_PID) && HAVE_HEATED_BED
405    epr_set_byte(EPR_BED_DRIVE_MAX,heatedBedController.pidDriveMax);
406    epr_set_byte(EPR_BED_DRIVE_MIN,heatedBedController.pidDriveMin);
407    epr_set_float(EPR_BED_PID_PGAIN,heatedBedController.pidPGain);
408    epr_set_float(EPR_BED_PID_IGAIN,heatedBedController.pidIGain);
409    epr_set_float(EPR_BED_PID_DGAIN,heatedBedController.pidDGain);
410    epr_set_byte(EPR_BED_PID_MAX,heatedBedController.pidMax);
411  #else
412    epr_set_byte(EPR_BED_DRIVE_MAX,HEATED_BED_PID_INTEGRAL_DRIVE_MAX);
413    epr_set_byte(EPR_BED_DRIVE_MIN,HEATED_BED_PID_INTEGRAL_DRIVE_MIN);
414    epr_set_float(EPR_BED_PID_PGAIN,HEATED_BED_PID_PGAIN);
415    epr_set_float(EPR_BED_PID_IGAIN,HEATED_BED_PID_IGAIN);
416    epr_set_float(EPR_BED_PID_DGAIN,HEATED_BED_PID_DGAIN);
417    epr_set_byte(EPR_BED_PID_MAX,HEATED_BED_PID_MAX);
418  #endif
419    epr_set_float(EPR_X_HOME_OFFSET,printer_state.xMin);
420    epr_set_float(EPR_Y_HOME_OFFSET,printer_state.yMin);
421    epr_set_float(EPR_Z_HOME_OFFSET,printer_state.zMin);
422    epr_set_float(EPR_X_LENGTH,printer_state.xLength);
423    epr_set_float(EPR_Y_LENGTH,printer_state.yLength);
424    epr_set_float(EPR_Z_LENGTH,printer_state.zLength);
425  #if ENABLE_BACKLASH_COMPENSATION
426    epr_set_float(EPR_BACKLASH_X,printer_state.backlashX);
427    epr_set_float(EPR_BACKLASH_Y,printer_state.backlashY);
428    epr_set_float(EPR_BACKLASH_Z,printer_state.backlashZ);
429  #else
430    epr_set_float(EPR_BACKLASH_X,0);
431    epr_set_float(EPR_BACKLASH_Y,0);
432    epr_set_float(EPR_BACKLASH_Z,0);
433  #endif
434  
435    // now the extruder
436    for(byte i=0;i<NUM_EXTRUDER;i++) {
437      int o=i*EEPROM_EXTRUDER_LENGTH+EEPROM_EXTRUDER_OFFSET;
438      Extruder *e = &extruder[i];
439      epr_set_float(o+EPR_EXTRUDER_STEPS_PER_MM,e->stepsPerMM);
440      epr_set_float(o+EPR_EXTRUDER_MAX_FEEDRATE,e->maxFeedrate);
441      epr_set_float(o+EPR_EXTRUDER_MAX_START_FEEDRATE,e->maxStartFeedrate);
442      epr_set_float(o+EPR_EXTRUDER_MAX_ACCELERATION,e->maxAcceleration);
443      epr_set_byte(o+EPR_EXTRUDER_HEAT_MANAGER,e->tempControl.heatManager);
444  #ifdef TEMP_PID
445      epr_set_byte(o+EPR_EXTRUDER_DRIVE_MAX,e->tempControl.pidDriveMax);
446      epr_set_byte(o+EPR_EXTRUDER_DRIVE_MIN,e->tempControl.pidDriveMin);
447      epr_set_float(o+EPR_EXTRUDER_PID_PGAIN,e->tempControl.pidPGain);
448      epr_set_float(o+EPR_EXTRUDER_PID_IGAIN,e->tempControl.pidIGain);
449      epr_set_float(o+EPR_EXTRUDER_PID_DGAIN,e->tempControl.pidDGain);
450      epr_set_byte(o+EPR_EXTRUDER_PID_MAX,e->tempControl.pidMax);
451  #endif
452      epr_set_long(o+EPR_EXTRUDER_X_OFFSET,e->xOffset);
453      epr_set_long(o+EPR_EXTRUDER_Y_OFFSET,e->yOffset);
454      epr_set_int(o+EPR_EXTRUDER_WATCH_PERIOD,e->watchPeriod);
455  #if RETRACT_DURING_HEATUP
456      epr_set_int(o+EPR_EXTRUDER_WAIT_RETRACT_TEMP,e->waitRetractTemperature);
457      epr_set_int(o+EPR_EXTRUDER_WAIT_RETRACT_UNITS,e->waitRetractUnits);
458  #else
459      epr_set_int(o+EPR_EXTRUDER_WAIT_RETRACT_TEMP,EXT0_WAIT_RETRACT_TEMP);
460      epr_set_int(o+EPR_EXTRUDER_WAIT_RETRACT_UNITS,EXT0_WAIT_RETRACT_UNITS);
461  #endif
462      epr_set_byte(o+EPR_EXTRUDER_COOLER_SPEED,e->coolerSpeed);
463  #ifdef USE_ADVANCE
464  #ifdef ENABLE_QUADRATIC_ADVANCE
465      epr_set_float(o+EPR_EXTRUDER_ADVANCE_K,e->advanceK);
466  #else
467      epr_set_float(o+EPR_EXTRUDER_ADVANCE_K,0);
468  #endif
469      epr_set_float(o+EPR_EXTRUDER_ADVANCE_L,e->advanceL);
470  #else
471      epr_set_float(o+EPR_EXTRUDER_ADVANCE_K,0);
472      epr_set_float(o+EPR_EXTRUDER_ADVANCE_L,0);
473  #endif
474    }
475    if(corrupted) {
476      epr_set_long(EPR_PRINTING_TIME,0);
477      epr_set_float(EPR_PRINTING_DISTANCE,0);
478    }
479    // Save version and build checksum
480    epr_set_byte(EPR_VERSION,EEPROM_PROTOCOL_VERSION);
481    epr_set_byte(EPR_INTEGRITY_BYTE,epr_compute_checksum());
482  }
483  /** \brief Copy data from EEPROM to variables.
484  */
485  void epr_eeprom_to_data() {
486    byte version = epr_get_byte(EPR_VERSION); // This is the saved version. Don't copy data not set in older versions!
487    baudrate = epr_get_long(EPR_BAUDRATE);
488    max_inactive_time = epr_get_long(EPR_MAX_INACTIVE_TIME);
489    stepper_inactive_time = epr_get_long(EPR_STEPPER_INACTIVE_TIME);
490  //#define EPR_ACCELERATION_TYPE 1
491    axis_steps_per_unit[0] = epr_get_float(EPR_XAXIS_STEPS_PER_MM);
492    axis_steps_per_unit[1] = epr_get_float(EPR_YAXIS_STEPS_PER_MM);
493    axis_steps_per_unit[2] = epr_get_float(EPR_ZAXIS_STEPS_PER_MM);
494    max_feedrate[0] = epr_get_float(EPR_X_MAX_FEEDRATE);
495    max_feedrate[1] = epr_get_float(EPR_Y_MAX_FEEDRATE);
496    max_feedrate[2] = epr_get_float(EPR_Z_MAX_FEEDRATE);
497    homing_feedrate[0] = epr_get_float(EPR_X_HOMING_FEEDRATE);
498    homing_feedrate[1] = epr_get_float(EPR_Y_HOMING_FEEDRATE);
499    homing_feedrate[2] = epr_get_float(EPR_Z_HOMING_FEEDRATE);
500    printer_state.maxJerk = epr_get_float(EPR_MAX_JERK);
501    printer_state.maxZJerk = epr_get_float(EPR_MAX_ZJERK);
502  #ifdef RAMP_ACCELERATION
503    max_acceleration_units_per_sq_second[0] = epr_get_float(EPR_X_MAX_ACCEL);
504    max_acceleration_units_per_sq_second[1] = epr_get_float(EPR_Y_MAX_ACCEL);
505    max_acceleration_units_per_sq_second[2] = epr_get_float(EPR_Z_MAX_ACCEL);
506    max_travel_acceleration_units_per_sq_second[0] = epr_get_float(EPR_X_MAX_TRAVEL_ACCEL);
507    max_travel_acceleration_units_per_sq_second[1] = epr_get_float(EPR_Y_MAX_TRAVEL_ACCEL);
508    max_travel_acceleration_units_per_sq_second[2] = epr_get_float(EPR_Z_MAX_TRAVEL_ACCEL);
509  #endif
510  #if USE_OPS==1
511    printer_state.opsMode = epr_get_byte(EPR_OPS_MODE);
512    printer_state.opsMoveAfter = epr_get_float(EPR_OPS_MOVE_AFTER);
513    printer_state.opsMinDistance = epr_get_float(EPR_OPS_MIN_DISTANCE);
514    printer_state.opsRetractDistance = epr_get_float(EPR_OPS_RETRACT_DISTANCE);
515    printer_state.opsRetractBacklash = epr_get_float(EPR_OPS_RETRACT_BACKLASH);
516  #endif
517  #if HAVE_HEATED_BED
518    heatedBedController.heatManager= epr_get_byte(EPR_BED_HEAT_MANAGER);
519  #ifdef TEMP_PID
520    heatedBedController.pidDriveMax = epr_get_byte(EPR_BED_DRIVE_MAX);
521    heatedBedController.pidDriveMin = epr_get_byte(EPR_BED_DRIVE_MIN);
522    heatedBedController.pidPGain = epr_get_float(EPR_BED_PID_PGAIN);
523    heatedBedController.pidIGain = epr_get_float(EPR_BED_PID_IGAIN);
524    heatedBedController.pidDGain = epr_get_float(EPR_BED_PID_DGAIN);
525    heatedBedController.pidMax = epr_get_byte(EPR_BED_PID_MAX);
526  #endif
527  #endif
528    printer_state.xMin = epr_get_float(EPR_X_HOME_OFFSET);
529    printer_state.yMin = epr_get_float(EPR_Y_HOME_OFFSET);
530    printer_state.zMin = epr_get_float(EPR_Z_HOME_OFFSET);
531    printer_state.xLength = epr_get_float(EPR_X_LENGTH);
532    printer_state.yLength = epr_get_float(EPR_Y_LENGTH);
533    printer_state.zLength = epr_get_float(EPR_Z_LENGTH);
534  #if ENABLE_BACKLASH_COMPENSATION
535    printer_state.backlashX = epr_get_float(EPR_BACKLASH_X);
536    printer_state.backlashY = epr_get_float(EPR_BACKLASH_Y);
537    printer_state.backlashZ = epr_get_float(EPR_BACKLASH_Z);
538  #endif
539    // now the extruder
540    for(byte i=0;i<NUM_EXTRUDER;i++) {
541      int o=i*EEPROM_EXTRUDER_LENGTH+EEPROM_EXTRUDER_OFFSET;
542      Extruder *e = &extruder[i];
543      e->stepsPerMM = epr_get_float(o+EPR_EXTRUDER_STEPS_PER_MM);
544      e->maxFeedrate = epr_get_float(o+EPR_EXTRUDER_MAX_FEEDRATE);
545      e->maxStartFeedrate = epr_get_float(o+EPR_EXTRUDER_MAX_START_FEEDRATE);
546      e->maxAcceleration = epr_get_float(o+EPR_EXTRUDER_MAX_ACCELERATION);
547      e->tempControl.heatManager = epr_get_byte(o+EPR_EXTRUDER_HEAT_MANAGER);
548  #ifdef TEMP_PID
549      e->tempControl.pidDriveMax = epr_get_byte(o+EPR_EXTRUDER_DRIVE_MAX);
550      e->tempControl.pidDriveMin = epr_get_byte(o+EPR_EXTRUDER_DRIVE_MIN);
551      e->tempControl.pidPGain = epr_get_float(o+EPR_EXTRUDER_PID_PGAIN);
552      e->tempControl.pidIGain = epr_get_float(o+EPR_EXTRUDER_PID_IGAIN);
553      e->tempControl.pidDGain = epr_get_float(o+EPR_EXTRUDER_PID_DGAIN);
554      e->tempControl.pidMax = epr_get_byte(o+EPR_EXTRUDER_PID_MAX);
555  #endif
556      e->xOffset = epr_get_long(o+EPR_EXTRUDER_X_OFFSET);
557      e->yOffset = epr_get_long(o+EPR_EXTRUDER_Y_OFFSET);
558      e->watchPeriod = epr_get_int(o+EPR_EXTRUDER_WATCH_PERIOD);
559  #if RETRACT_DURING_HEATUP
560      e->waitRetractTemperature = epr_get_int(o+EPR_EXTRUDER_WAIT_RETRACT_TEMP);
561      e->waitRetractUnits = epr_get_int(o+EPR_EXTRUDER_WAIT_RETRACT_UNITS);
562  #endif
563   #ifdef USE_ADVANCE
564   #ifdef ENABLE_QUADRATIC_ADVANCE
565      e->advanceK = epr_get_float(o+EPR_EXTRUDER_ADVANCE_K);
566  #endif
567      e->advanceL = epr_get_float(o+EPR_EXTRUDER_ADVANCE_L);
568   #endif
569      if(version>1)
570        e->coolerSpeed = epr_get_byte(o+EPR_EXTRUDER_COOLER_SPEED);
571    }
572    if(version!=EEPROM_PROTOCOL_VERSION) {
573      OUT_P_LN("Protocol version changed, upgrading");
574      epr_data_to_eeprom(false); // Store new fields for changed version
575    }
576    extruder_select(current_extruder->id);
577    update_ramps_parameter();
578    initHeatedBed();
579  }
580  #endif
581  void epr_init_baudrate() {
582  #if EEPROM_MODE!=0
583    if(epr_get_byte(EPR_MAGIC_BYTE)==EEPROM_MODE) {
584      baudrate = epr_get_long(EPR_BAUDRATE);    
585    }
586  #endif
587  }
588  void epr_init() {
589  #if EEPROM_MODE!=0
590    byte check = epr_compute_checksum();
591    byte storedcheck = epr_get_byte(EPR_INTEGRITY_BYTE);
592    if(epr_get_byte(EPR_MAGIC_BYTE)==EEPROM_MODE && storedcheck==check) {
593      epr_eeprom_to_data();
594    } else {
595      epr_set_byte(EPR_MAGIC_BYTE,EEPROM_MODE); // Make datachange permanent
596      epr_data_to_eeprom(storedcheck!=check);
597    }
598  #endif
599  }
600  /**
601  */
602  void epr_update_usage() {
603  #if EEPROM_MODE!=0
604    if(printer_state.filamentPrinted==0) return; // No miles only enabled
605    unsigned long seconds = (millis()-printer_state.msecondsPrinting)/1000;
606    seconds += epr_get_long(EPR_PRINTING_TIME);
607    epr_set_long(EPR_PRINTING_TIME,seconds);
608    epr_set_float(EPR_PRINTING_DISTANCE,epr_get_float(EPR_PRINTING_DISTANCE)+printer_state.filamentPrinted*0.001);
609    OUT_P_F_LN("Adding filament:",printer_state.filamentPrinted);
610    printer_state.filamentPrinted = 0;
611    printer_state.msecondsPrinting = millis();
612    byte newcheck = epr_compute_checksum();
613    if(newcheck!=epr_get_byte(EPR_INTEGRITY_BYTE))
614      epr_set_byte(EPR_INTEGRITY_BYTE,newcheck);
615  #endif
616  }
617  
618  /** \brief Writes all eeprom settings to serial console.
619  
620  For each value stored, this function generates one line with syntax
621  
622  EPR: pos type value description
623  
624  With
625  - pos = Position in EEPROM, the data starts.
626  - type = Value type: 0 = byte, 1 = int, 2 = long, 3 = float
627  - value = The value currently stored
628  - description = Definition of the value
629  */
630  void epr_output_settings() {
631  #if EEPROM_MODE!=0
632    epr_out_long(EPR_BAUDRATE,PSTR("Baudrate"));
633    epr_out_float(EPR_PRINTING_DISTANCE,PSTR("Filament printed [m]"));
634    epr_out_long(EPR_PRINTING_TIME,PSTR("Printer active [s]"));
635    epr_out_long(EPR_MAX_INACTIVE_TIME,PSTR("Max. inactive time [ms,0=off]"));
636    epr_out_long(EPR_STEPPER_INACTIVE_TIME,PSTR("Stop stepper after inactivity [ms,0=off]"));
637  //#define EPR_ACCELERATION_TYPE 1
638    epr_out_float(EPR_XAXIS_STEPS_PER_MM,PSTR("X-axis steps per mm"));
639    epr_out_float(EPR_YAXIS_STEPS_PER_MM,PSTR("Y-axis steps per mm"));
640    epr_out_float(EPR_ZAXIS_STEPS_PER_MM,PSTR("Z-axis steps per mm"));
641    epr_out_float(EPR_X_MAX_FEEDRATE,PSTR("X-axis max. feedrate [mm/s]"));
642    epr_out_float(EPR_Y_MAX_FEEDRATE,PSTR("Y-axis max. feedrate [mm/s]"));
643    epr_out_float(EPR_Z_MAX_FEEDRATE,PSTR("Z-axis max. feedrate [mm/s]"));
644    epr_out_float(EPR_X_HOMING_FEEDRATE,PSTR("X-axis homing feedrate [mm/s]"));
645    epr_out_float(EPR_Y_HOMING_FEEDRATE,PSTR("Y-axis homing feedrate [mm/s]"));
646    epr_out_float(EPR_Z_HOMING_FEEDRATE,PSTR("Z-axis homing feedrate [mm/s]"));
647    epr_out_float(EPR_MAX_JERK,PSTR("Max. jerk [mm/s]"));
648    epr_out_float(EPR_MAX_ZJERK,PSTR("Max. Z-jerk [mm/s]"));
649    epr_out_float(EPR_X_HOME_OFFSET,PSTR("X home pos [mm]"));
650    epr_out_float(EPR_Y_HOME_OFFSET,PSTR("Y home pos [mm]"));
651    epr_out_float(EPR_Z_HOME_OFFSET,PSTR("Z home pos [mm]"));
652    epr_out_float(EPR_X_LENGTH,PSTR("X max length [mm]"));
653    epr_out_float(EPR_Y_LENGTH,PSTR("Y max length [mm]"));
654    epr_out_float(EPR_Z_LENGTH,PSTR("Z max length [mm]"));
655  #if ENABLE_BACKLASH_COMPENSATION
656    epr_out_float(EPR_BACKLASH_X,PSTR("X backlash [mm]"));
657    epr_out_float(EPR_BACKLASH_Y,PSTR("Y backlash [mm]"));
658    epr_out_float(EPR_BACKLASH_Z,PSTR("Z backlash [mm]"));
659  #endif
660  
661  #ifdef RAMP_ACCELERATION
662    //epr_out_float(EPR_X_MAX_START_SPEED,PSTR("X-axis start speed [mm/s]"));
663    //epr_out_float(EPR_Y_MAX_START_SPEED,PSTR("Y-axis start speed [mm/s]"));
664    //epr_out_float(EPR_Z_MAX_START_SPEED,PSTR("Z-axis start speed [mm/s]"));
665    epr_out_float(EPR_X_MAX_ACCEL,PSTR("X-axis acceleration [mm/s^2]"));
666    epr_out_float(EPR_Y_MAX_ACCEL,PSTR("Y-axis acceleration [mm/s^2]"));
667    epr_out_float(EPR_Z_MAX_ACCEL,PSTR("Z-axis acceleration [mm/s^2]"));
668    epr_out_float(EPR_X_MAX_TRAVEL_ACCEL,PSTR("X-axis travel acceleration [mm/s^2]"));
669    epr_out_float(EPR_Y_MAX_TRAVEL_ACCEL,PSTR("Y-axis travel acceleration [mm/s^2]"));
670    epr_out_float(EPR_Z_MAX_TRAVEL_ACCEL,PSTR("Z-axis travel acceleration [mm/s^2]"));
671  #endif
672  #if USE_OPS==1
673    epr_out_byte(EPR_OPS_MODE,PSTR("OPS operation mode [0=Off,1=Classic,2=Fast]"));
674    epr_out_float(EPR_OPS_MOVE_AFTER,PSTR("OPS move after x% retract [%]"));
675    epr_out_float(EPR_OPS_MIN_DISTANCE,PSTR("OPS min. distance for fil. retraction [mm]"));
676    epr_out_float(EPR_OPS_RETRACT_DISTANCE,PSTR("OPS retraction length [mm]"));
677    epr_out_float(EPR_OPS_RETRACT_BACKLASH,PSTR("OPS retraction backlash [mm]"));
678  #endif
679  #if HAVE_HEATED_BED
680    epr_out_byte(EPR_BED_HEAT_MANAGER,PSTR("Bed Heat Manager [0-2]"));
681  #ifdef TEMP_PID
682    epr_out_byte(EPR_BED_DRIVE_MAX,PSTR("Bed PID drive max"));
683    epr_out_byte(EPR_BED_DRIVE_MIN,PSTR("Bed PID drive min"));
684    epr_out_float(EPR_BED_PID_PGAIN,PSTR("Bed PID P-gain"));
685    epr_out_float(EPR_BED_PID_IGAIN,PSTR("Bed PID I-gain"));
686    epr_out_float(EPR_BED_PID_DGAIN,PSTR("Bed PID D-gain"));
687    epr_out_byte(EPR_BED_PID_MAX,PSTR("Bed PID max value [0-255]"));
688  #endif
689  #endif
690    // now the extruder
691    for(byte i=0;i<NUM_EXTRUDER;i++) {
692      int o=i*EEPROM_EXTRUDER_LENGTH+EEPROM_EXTRUDER_OFFSET;
693      Extruder *e = &extruder[i];
694      epr_out_float(o+EPR_EXTRUDER_STEPS_PER_MM,PSTR("steps per mm"));
695      epr_out_float(o+EPR_EXTRUDER_MAX_FEEDRATE,PSTR("max. feedrate [mm/s]"));
696      epr_out_float(o+EPR_EXTRUDER_MAX_START_FEEDRATE,PSTR("start feedrate [mm/s]"));
697      epr_out_float(o+EPR_EXTRUDER_MAX_ACCELERATION,PSTR("acceleration [mm/s^2]"));
698      epr_out_byte(o+EPR_EXTRUDER_HEAT_MANAGER,PSTR("heat manager [0-1]"));
699  #ifdef TEMP_PID
700      epr_out_byte(o+EPR_EXTRUDER_DRIVE_MAX,PSTR("PID drive max"));
701      epr_out_byte(o+EPR_EXTRUDER_DRIVE_MIN,PSTR("PID drive min"));
702      epr_out_float(o+EPR_EXTRUDER_PID_PGAIN,PSTR("PID P-gain"));
703      epr_out_float(o+EPR_EXTRUDER_PID_IGAIN,PSTR("PID I-gain"));
704      epr_out_float(o+EPR_EXTRUDER_PID_DGAIN,PSTR("PID D-gain"));
705      epr_out_byte(o+EPR_EXTRUDER_PID_MAX,PSTR("PID max value [0-255]"));
706  #endif
707      epr_out_long(o+EPR_EXTRUDER_X_OFFSET,PSTR("X-offset [steps]"));
708      epr_out_long(o+EPR_EXTRUDER_Y_OFFSET,PSTR("Y-offset [steps]"));
709      epr_out_int(o+EPR_EXTRUDER_WATCH_PERIOD,PSTR("temp. stabilize time [s]"));
710  #if RETRACT_DURING_HEATUP
711      epr_out_int(o+EPR_EXTRUDER_WAIT_RETRACT_TEMP,PSTR("temp. for retraction when heating [C]"));
712      epr_out_int(o+EPR_EXTRUDER_WAIT_RETRACT_UNITS,PSTR("distance to retract when heating [mm]"));
713  #endif
714      epr_out_byte(o+EPR_EXTRUDER_COOLER_SPEED,PSTR("extruder cooler speed [0-255]"));
715  #ifdef USE_ADVANCE
716  #ifdef ENABLE_QUADRATIC_ADVANCE
717      epr_out_float(o+EPR_EXTRUDER_ADVANCE_K,PSTR("advance K [0=off]"));
718  #endif
719      epr_out_float(o+EPR_EXTRUDER_ADVANCE_L,PSTR("advance L [0=off]"));
720  #endif    
721    }
722  #else
723    out.println_P(PSTR("No EEPROM support compiled."));
724  #endif
725  }
726