void EEPROM::init()
{
#if EEPROM_MODE != 0
    uint8_t check = computeChecksum();
    uint8_t storedcheck = HAL::eprGetByte(EPR_INTEGRITY_BYTE);
    if(HAL::eprGetByte(EPR_MAGIC_BYTE) == EEPROM_MODE && storedcheck == check)
    {
        readDataFromEEPROM();
        if (USE_CONFIGURATION_BAUD_RATE)
        {
            // Used if eeprom gets unusable baud rate set and communication wont work at all.
            if(HAL::eprGetInt32(EPR_BAUDRATE) != BAUDRATE)
            {
                HAL::eprSetInt32(EPR_BAUDRATE,BAUDRATE);
                baudrate = BAUDRATE;
                uint8_t newcheck = computeChecksum();
                if(newcheck != HAL::eprGetByte(EPR_INTEGRITY_BYTE))
                    HAL::eprSetByte(EPR_INTEGRITY_BYTE,newcheck);
            }
            Com::printFLN(PSTR("EEprom baud rate restored from configuration."));
            Com::printFLN(PSTR("RECOMPILE WITH USE_CONFIGURATION_BAUD_RATE == 0 to alter baud rate via EEPROM"));
        }
    }
    else
    {
        HAL::eprSetByte(EPR_MAGIC_BYTE,EEPROM_MODE); // Make datachange permanent
        initalizeUncached();
        storeDataIntoEEPROM(storedcheck != check);
    }
#endif
}
void EEPROM::init()
{
#if EEPROM_MODE!=0
    byte check = computeChecksum();
    byte storedcheck = HAL::epr_get_byte(EPR_INTEGRITY_BYTE);
    if(HAL::epr_get_byte(EPR_MAGIC_BYTE)==EEPROM_MODE && storedcheck==check)
    {
        readDataFromEEPROM();
    }
    else
    {
        HAL::epr_set_byte(EPR_MAGIC_BYTE,EEPROM_MODE); // Make datachange permanent
        storeDataIntoEEPROM(storedcheck!=check);
    }
#endif
}
void EEPROM::init()
{
#if EEPROM_MODE!=0
    uint8_t check = computeChecksum();
    uint8_t storedcheck = HAL::eprGetByte(EPR_INTEGRITY_BYTE);
    if(HAL::eprGetByte(EPR_MAGIC_BYTE)==EEPROM_MODE && storedcheck==check)
    {
        readDataFromEEPROM();
    }
    else
    {
        HAL::eprSetByte(EPR_MAGIC_BYTE,EEPROM_MODE); // Make datachange permanent
        initalizeUncached();
        storeDataIntoEEPROM(storedcheck!=check);
    }
#endif
}
void EEPROM::readDataFromEEPROM()
{
#if EEPROM_MODE!=0
    byte version = HAL::epr_get_byte(EPR_VERSION); // This is the saved version. Don't copy data not set in older versions!
    baudrate = HAL::epr_get_long(EPR_BAUDRATE);
    max_inactive_time = HAL::epr_get_long(EPR_MAX_INACTIVE_TIME);
    stepper_inactive_time = HAL::epr_get_long(EPR_STEPPER_INACTIVE_TIME);
//#define EPR_ACCELERATION_TYPE 1
    Printer::axisStepsPerMM[0] = HAL::epr_get_float(EPR_XAXIS_STEPS_PER_MM);
    Printer::axisStepsPerMM[1] = HAL::epr_get_float(EPR_YAXIS_STEPS_PER_MM);
    Printer::axisStepsPerMM[2] = HAL::epr_get_float(EPR_ZAXIS_STEPS_PER_MM);
    Printer::maxFeedrate[0] = HAL::epr_get_float(EPR_X_MAX_FEEDRATE);
    Printer::maxFeedrate[1] = HAL::epr_get_float(EPR_Y_MAX_FEEDRATE);
    Printer::maxFeedrate[2] = HAL::epr_get_float(EPR_Z_MAX_FEEDRATE);
    Printer::homingFeedrate[0] = HAL::epr_get_float(EPR_X_HOMING_FEEDRATE);
    Printer::homingFeedrate[1] = HAL::epr_get_float(EPR_Y_HOMING_FEEDRATE);
    Printer::homingFeedrate[2] = HAL::epr_get_float(EPR_Z_HOMING_FEEDRATE);
    Printer::maxJerk = HAL::epr_get_float(EPR_MAX_JERK);
    Printer::maxZJerk = HAL::epr_get_float(EPR_MAX_ZJERK);
#ifdef RAMP_ACCELERATION
    Printer::maxAccelerationMMPerSquareSecond[0] = HAL::epr_get_float(EPR_X_MAX_ACCEL);
    Printer::maxAccelerationMMPerSquareSecond[1] = HAL::epr_get_float(EPR_Y_MAX_ACCEL);
    Printer::maxAccelerationMMPerSquareSecond[2] = HAL::epr_get_float(EPR_Z_MAX_ACCEL);
    Printer::maxTravelAccelerationMMPerSquareSecond[0] = HAL::epr_get_float(EPR_X_MAX_TRAVEL_ACCEL);
    Printer::maxTravelAccelerationMMPerSquareSecond[1] = HAL::epr_get_float(EPR_Y_MAX_TRAVEL_ACCEL);
    Printer::maxTravelAccelerationMMPerSquareSecond[2] = HAL::epr_get_float(EPR_Z_MAX_TRAVEL_ACCEL);
#endif
#if USE_OPS==1
    Printer::opsMode = HAL::epr_get_byte(EPR_OPS_MODE);
    Printer::opsMoveAfter = HAL::epr_get_float(EPR_OPS_MOVE_AFTER);
    Printer::opsMinDistance = HAL::epr_get_float(EPR_OPS_MIN_DISTANCE);
    Printer::opsRetractDistance = HAL::epr_get_float(EPR_OPS_RETRACT_DISTANCE);
    Printer::opsRetractBacklash = HAL::epr_get_float(EPR_OPS_RETRACT_BACKLASH);
#endif
#if HAVE_HEATED_BED
    heatedBedController.heatManager= HAL::epr_get_byte(EPR_BED_HEAT_MANAGER);
#ifdef TEMP_PID
    heatedBedController.pidDriveMax = HAL::epr_get_byte(EPR_BED_DRIVE_MAX);
    heatedBedController.pidDriveMin = HAL::epr_get_byte(EPR_BED_DRIVE_MIN);
    heatedBedController.pidPGain = HAL::epr_get_float(EPR_BED_PID_PGAIN);
    heatedBedController.pidIGain = HAL::epr_get_float(EPR_BED_PID_IGAIN);
    heatedBedController.pidDGain = HAL::epr_get_float(EPR_BED_PID_DGAIN);
    heatedBedController.pidMax = HAL::epr_get_byte(EPR_BED_PID_MAX);
#endif
#endif
    Printer::xMin = HAL::epr_get_float(EPR_X_HOME_OFFSET);
    Printer::yMin = HAL::epr_get_float(EPR_Y_HOME_OFFSET);
    Printer::zMin = HAL::epr_get_float(EPR_Z_HOME_OFFSET);
    Printer::xLength = HAL::epr_get_float(EPR_X_LENGTH);
    Printer::yLength = HAL::epr_get_float(EPR_Y_LENGTH);
    Printer::zLength = HAL::epr_get_float(EPR_Z_LENGTH);
#if ENABLE_BACKLASH_COMPENSATION
    Printer::backlashX = HAL::epr_get_float(EPR_BACKLASH_X);
    Printer::backlashY = HAL::epr_get_float(EPR_BACKLASH_Y);
    Printer::backlashZ = HAL::epr_get_float(EPR_BACKLASH_Z);
#endif
#if FEATURE_AUTOLEVEL
    if(version>2)
    {
        for(byte i=0; i<9; i++)
            Printer::autolevelTransformation[i] = HAL::epr_get_float(EPR_AUTOLEVEL_MATRIX+((int)i)<<2);
        Printer::setAutolevelActive(HAL::epr_get_byte(EPR_AUTOLEVEL_ACTIVE));
        Com::printArrayFLN(Com::tInfo,Printer::autolevelTransformation,9,6);
    }
#endif
    // now the extruder
    for(byte i=0; i<NUM_EXTRUDER; i++)
    {
        int o=i*EEPROM_EXTRUDER_LENGTH+EEPROM_EXTRUDER_OFFSET;
        Extruder *e = &extruder[i];
        e->stepsPerMM = HAL::epr_get_float(o+EPR_EXTRUDER_STEPS_PER_MM);
        e->maxFeedrate = HAL::epr_get_float(o+EPR_EXTRUDER_MAX_FEEDRATE);
        e->maxStartFeedrate = HAL::epr_get_float(o+EPR_EXTRUDER_MAX_START_FEEDRATE);
        e->maxAcceleration = HAL::epr_get_float(o+EPR_EXTRUDER_MAX_ACCELERATION);
        e->tempControl.heatManager = HAL::epr_get_byte(o+EPR_EXTRUDER_HEAT_MANAGER);
#ifdef TEMP_PID
        e->tempControl.pidDriveMax = HAL::epr_get_byte(o+EPR_EXTRUDER_DRIVE_MAX);
        e->tempControl.pidDriveMin = HAL::epr_get_byte(o+EPR_EXTRUDER_DRIVE_MIN);
        e->tempControl.pidPGain = HAL::epr_get_float(o+EPR_EXTRUDER_PID_PGAIN);
        e->tempControl.pidIGain = HAL::epr_get_float(o+EPR_EXTRUDER_PID_IGAIN);
        e->tempControl.pidDGain = HAL::epr_get_float(o+EPR_EXTRUDER_PID_DGAIN);
        e->tempControl.pidMax = HAL::epr_get_byte(o+EPR_EXTRUDER_PID_MAX);
#endif
        e->xOffset = HAL::epr_get_long(o+EPR_EXTRUDER_X_OFFSET);
        e->yOffset = HAL::epr_get_long(o+EPR_EXTRUDER_Y_OFFSET);
        e->watchPeriod = HAL::epr_get_int(o+EPR_EXTRUDER_WATCH_PERIOD);
#if RETRACT_DURING_HEATUP
        e->waitRetractTemperature = HAL::epr_get_int(o+EPR_EXTRUDER_WAIT_RETRACT_TEMP);
        e->waitRetractUnits = HAL::epr_get_int(o+EPR_EXTRUDER_WAIT_RETRACT_UNITS);
#endif
#ifdef USE_ADVANCE
#ifdef ENABLE_QUADRATIC_ADVANCE
        e->advanceK = HAL::epr_get_float(o+EPR_EXTRUDER_ADVANCE_K);
#endif
        e->advanceL = HAL::epr_get_float(o+EPR_EXTRUDER_ADVANCE_L);
#endif
        if(version>1)
            e->coolerSpeed = HAL::epr_get_byte(o+EPR_EXTRUDER_COOLER_SPEED);
    }
    if(version!=EEPROM_PROTOCOL_VERSION)
    {
        Com::printInfoFLN(Com::tEPRProtocolChanged);
        if(version<3)
        {
            HAL::epr_set_float(EPR_Z_PROBE_HEIGHT,Z_PROBE_HEIGHT);
            HAL::epr_set_float(EPR_Z_PROBE_SPEED,Z_PROBE_SPEED);
            HAL::epr_set_float(EPR_Z_PROBE_XY_SPEED,Z_PROBE_XY_SPEED);
            HAL::epr_set_float(EPR_Z_PROBE_X_OFFSET,Z_PROBE_X_OFFSET);
            HAL::epr_set_float(EPR_Z_PROBE_Y_OFFSET,Z_PROBE_Y_OFFSET);
            HAL::epr_set_float(EPR_Z_PROBE_X1,Z_PROBE_X1);
            HAL::epr_set_float(EPR_Z_PROBE_Y1,Z_PROBE_Y1);
            HAL::epr_set_float(EPR_Z_PROBE_X2,Z_PROBE_X2);
            HAL::epr_set_float(EPR_Z_PROBE_Y2,Z_PROBE_Y2);
            HAL::epr_set_float(EPR_Z_PROBE_X3,Z_PROBE_X3);
            HAL::epr_set_float(EPR_Z_PROBE_Y3,Z_PROBE_Y3);
        }
        storeDataIntoEEPROM(false); // Store new fields for changed version
    }
    Extruder::selectExtruderById(current_extruder->id);
    Printer::updateDerivedParameter();
    Extruder::initHeatedBed();
#endif
}
void EEPROM::readDataFromEEPROM()
{
#if EEPROM_MODE!=0
    uint8_t version = HAL::eprGetByte(EPR_VERSION); // This is the saved version. Don't copy data not set in older versions!
    baudrate = HAL::eprGetInt32(EPR_BAUDRATE);
    maxInactiveTime = HAL::eprGetInt32(EPR_MAX_INACTIVE_TIME);
    stepperInactiveTime = HAL::eprGetInt32(EPR_STEPPER_INACTIVE_TIME);
//#define EPR_ACCELERATION_TYPE 1
    Printer::axisStepsPerMM[0] = HAL::eprGetFloat(EPR_XAXIS_STEPS_PER_MM);
    Printer::axisStepsPerMM[1] = HAL::eprGetFloat(EPR_YAXIS_STEPS_PER_MM);
    Printer::axisStepsPerMM[2] = HAL::eprGetFloat(EPR_ZAXIS_STEPS_PER_MM);
    Printer::maxFeedrate[0] = HAL::eprGetFloat(EPR_X_MAX_FEEDRATE);
    Printer::maxFeedrate[1] = HAL::eprGetFloat(EPR_Y_MAX_FEEDRATE);
    Printer::maxFeedrate[2] = HAL::eprGetFloat(EPR_Z_MAX_FEEDRATE);
    Printer::homingFeedrate[0] = HAL::eprGetFloat(EPR_X_HOMING_FEEDRATE);
    Printer::homingFeedrate[1] = HAL::eprGetFloat(EPR_Y_HOMING_FEEDRATE);
    Printer::homingFeedrate[2] = HAL::eprGetFloat(EPR_Z_HOMING_FEEDRATE);
    Printer::maxJerk = HAL::eprGetFloat(EPR_MAX_JERK);
#if DRIVE_SYSTEM!=3
    Printer::maxZJerk = HAL::eprGetFloat(EPR_MAX_ZJERK);
#endif
#ifdef RAMP_ACCELERATION
    Printer::maxAccelerationMMPerSquareSecond[0] = HAL::eprGetFloat(EPR_X_MAX_ACCEL);
    Printer::maxAccelerationMMPerSquareSecond[1] = HAL::eprGetFloat(EPR_Y_MAX_ACCEL);
    Printer::maxAccelerationMMPerSquareSecond[2] = HAL::eprGetFloat(EPR_Z_MAX_ACCEL);
    Printer::maxTravelAccelerationMMPerSquareSecond[0] = HAL::eprGetFloat(EPR_X_MAX_TRAVEL_ACCEL);
    Printer::maxTravelAccelerationMMPerSquareSecond[1] = HAL::eprGetFloat(EPR_Y_MAX_TRAVEL_ACCEL);
    Printer::maxTravelAccelerationMMPerSquareSecond[2] = HAL::eprGetFloat(EPR_Z_MAX_TRAVEL_ACCEL);
#endif
#if HAVE_HEATED_BED
    heatedBedController.heatManager= HAL::eprGetByte(EPR_BED_HEAT_MANAGER);
#ifdef TEMP_PID
    heatedBedController.pidDriveMax = HAL::eprGetByte(EPR_BED_DRIVE_MAX);
    heatedBedController.pidDriveMin = HAL::eprGetByte(EPR_BED_DRIVE_MIN);
    heatedBedController.pidPGain = HAL::eprGetFloat(EPR_BED_PID_PGAIN);
    heatedBedController.pidIGain = HAL::eprGetFloat(EPR_BED_PID_IGAIN);
    heatedBedController.pidDGain = HAL::eprGetFloat(EPR_BED_PID_DGAIN);
    heatedBedController.pidMax = HAL::eprGetByte(EPR_BED_PID_MAX);
#endif
#endif
    Printer::xMin = HAL::eprGetFloat(EPR_X_HOME_OFFSET);
    Printer::yMin = HAL::eprGetFloat(EPR_Y_HOME_OFFSET);
    Printer::zMin = HAL::eprGetFloat(EPR_Z_HOME_OFFSET);
    Printer::xLength = HAL::eprGetFloat(EPR_X_LENGTH);
    Printer::yLength = HAL::eprGetFloat(EPR_Y_LENGTH);
    Printer::zLength = HAL::eprGetFloat(EPR_Z_LENGTH);
#if ENABLE_BACKLASH_COMPENSATION
    Printer::backlashX = HAL::eprGetFloat(EPR_BACKLASH_X);
    Printer::backlashY = HAL::eprGetFloat(EPR_BACKLASH_Y);
    Printer::backlashZ = HAL::eprGetFloat(EPR_BACKLASH_Z);
#endif
#if FEATURE_AUTOLEVEL
    if(version>2)
    {
        for(uint8_t i=0; i<9; i++)
            Printer::autolevelTransformation[i] = HAL::eprGetFloat(EPR_AUTOLEVEL_MATRIX+((int)i)<<2);
        Printer::setAutolevelActive(HAL::eprGetByte(EPR_AUTOLEVEL_ACTIVE));
        //Com::printArrayFLN(Com::tInfo,Printer::autolevelTransformation,9,6);
    }
#endif
    // now the extruder
    for(uint8_t i=0; i<NUM_EXTRUDER; i++)
    {
#if FEATURE_WATCHDOG
    HAL::pingWatchdog();
#endif // FEATURE_WATCHDOG

        int o=i*EEPROM_EXTRUDER_LENGTH+EEPROM_EXTRUDER_OFFSET;
        Extruder *e = &extruder[i];
        e->stepsPerMM = HAL::eprGetFloat(o+EPR_EXTRUDER_STEPS_PER_MM);
        e->maxFeedrate = HAL::eprGetFloat(o+EPR_EXTRUDER_MAX_FEEDRATE);
        e->maxStartFeedrate = HAL::eprGetFloat(o+EPR_EXTRUDER_MAX_START_FEEDRATE);
        e->maxAcceleration = HAL::eprGetFloat(o+EPR_EXTRUDER_MAX_ACCELERATION);
        e->tempControl.heatManager = HAL::eprGetByte(o+EPR_EXTRUDER_HEAT_MANAGER);
#ifdef TEMP_PID
        e->tempControl.pidDriveMax = HAL::eprGetByte(o+EPR_EXTRUDER_DRIVE_MAX);
        e->tempControl.pidDriveMin = HAL::eprGetByte(o+EPR_EXTRUDER_DRIVE_MIN);
        e->tempControl.pidPGain = HAL::eprGetFloat(o+EPR_EXTRUDER_PID_PGAIN);
        e->tempControl.pidIGain = HAL::eprGetFloat(o+EPR_EXTRUDER_PID_IGAIN);
        e->tempControl.pidDGain = HAL::eprGetFloat(o+EPR_EXTRUDER_PID_DGAIN);
        e->tempControl.pidMax = HAL::eprGetByte(o+EPR_EXTRUDER_PID_MAX);
#endif
        e->xOffset = HAL::eprGetInt32(o+EPR_EXTRUDER_X_OFFSET);
        e->yOffset = HAL::eprGetInt32(o+EPR_EXTRUDER_Y_OFFSET);
        e->watchPeriod = HAL::eprGetInt16(o+EPR_EXTRUDER_WATCH_PERIOD);
#if RETRACT_DURING_HEATUP
        e->waitRetractTemperature = HAL::eprGetInt16(o+EPR_EXTRUDER_WAIT_RETRACT_TEMP);
        e->waitRetractUnits = HAL::eprGetInt16(o+EPR_EXTRUDER_WAIT_RETRACT_UNITS);
#endif
#ifdef USE_ADVANCE
#ifdef ENABLE_QUADRATIC_ADVANCE
        e->advanceK = HAL::eprGetFloat(o+EPR_EXTRUDER_ADVANCE_K);
#endif
        e->advanceL = HAL::eprGetFloat(o+EPR_EXTRUDER_ADVANCE_L);
#endif
        if(version>1)
            e->coolerSpeed = HAL::eprGetByte(o+EPR_EXTRUDER_COOLER_SPEED);
    }
    if(version!=EEPROM_PROTOCOL_VERSION)
    {
        Com::printInfoFLN(Com::tEPRProtocolChanged);
        if(version<3)
        {
            HAL::eprSetFloat(EPR_Z_PROBE_HEIGHT,Z_PROBE_HEIGHT);
            HAL::eprSetFloat(EPR_Z_PROBE_SPEED,Z_PROBE_SPEED);
            HAL::eprSetFloat(EPR_Z_PROBE_XY_SPEED,Z_PROBE_XY_SPEED);
            HAL::eprSetFloat(EPR_Z_PROBE_X_OFFSET,Z_PROBE_X_OFFSET);
            HAL::eprSetFloat(EPR_Z_PROBE_Y_OFFSET,Z_PROBE_Y_OFFSET);
            HAL::eprSetFloat(EPR_Z_PROBE_X1,Z_PROBE_X1);
            HAL::eprSetFloat(EPR_Z_PROBE_Y1,Z_PROBE_Y1);
            HAL::eprSetFloat(EPR_Z_PROBE_X2,Z_PROBE_X2);
            HAL::eprSetFloat(EPR_Z_PROBE_Y2,Z_PROBE_Y2);
            HAL::eprSetFloat(EPR_Z_PROBE_X3,Z_PROBE_X3);
            HAL::eprSetFloat(EPR_Z_PROBE_Y3,Z_PROBE_Y3);
        }
        if(version<4)
        {
#if DRIVE_SYSTEM==3
            HAL::eprSetFloat(EPR_DELTA_DIAGONAL_ROD_LENGTH,DELTA_DIAGONAL_ROD);
            HAL::eprSetFloat(EPR_DELTA_HORIZONTAL_RADIUS,DELTA_RADIUS);
            HAL::eprSetInt16(EPR_DELTA_SEGMENTS_PER_SECOND_PRINT,DELTA_SEGMENTS_PER_SECOND_PRINT);
            HAL::eprSetInt16(EPR_DELTA_SEGMENTS_PER_SECOND_MOVE,DELTA_SEGMENTS_PER_SECOND_MOVE);
            HAL::eprSetInt16(EPR_DELTA_TOWERX_OFFSET_STEPS,DELTA_X_ENDSTOP_OFFSET_STEPS);
            HAL::eprSetInt16(EPR_DELTA_TOWERY_OFFSET_STEPS,DELTA_Y_ENDSTOP_OFFSET_STEPS);
            HAL::eprSetInt16(EPR_DELTA_TOWERZ_OFFSET_STEPS,DELTA_Z_ENDSTOP_OFFSET_STEPS);
#endif
        }
#if DRIVE_SYSTEM==3
        if(version<5) {
            HAL::eprSetFloat(EPR_DELTA_ALPHA_A,DELTA_ALPHA_A);
            HAL::eprSetFloat(EPR_DELTA_ALPHA_B,DELTA_ALPHA_B);
            HAL::eprSetFloat(EPR_DELTA_ALPHA_C,DELTA_ALPHA_C);
        }
        if(version<6) {
            HAL::eprSetFloat(EPR_DELTA_RADIUS_CORR_A,DELTA_RADIUS_CORRECTION_A);
            HAL::eprSetFloat(EPR_DELTA_RADIUS_CORR_B,DELTA_RADIUS_CORRECTION_B);
            HAL::eprSetFloat(EPR_DELTA_RADIUS_CORR_C,DELTA_RADIUS_CORRECTION_C);
        }
#endif
        storeDataIntoEEPROM(false); // Store new fields for changed version
    }
    Printer::updateDerivedParameter();
    Extruder::initHeatedBed();
#endif
}
void EEPROM::readDataFromEEPROM()
{
#if EEPROM_MODE != 0
    uint8_t version = HAL::eprGetByte(EPR_VERSION); // This is the saved version. Don't copy data not set in older versions!
    baudrate = HAL::eprGetInt32(EPR_BAUDRATE);
    maxInactiveTime = HAL::eprGetInt32(EPR_MAX_INACTIVE_TIME);
    stepperInactiveTime = HAL::eprGetInt32(EPR_STEPPER_INACTIVE_TIME);
//#define EPR_ACCELERATION_TYPE 1
    Printer::axisStepsPerMM[X_AXIS] = HAL::eprGetFloat(EPR_XAXIS_STEPS_PER_MM);
    Printer::axisStepsPerMM[Y_AXIS] = HAL::eprGetFloat(EPR_YAXIS_STEPS_PER_MM);
    Printer::axisStepsPerMM[Z_AXIS] = HAL::eprGetFloat(EPR_ZAXIS_STEPS_PER_MM);
    Printer::maxFeedrate[X_AXIS] = HAL::eprGetFloat(EPR_X_MAX_FEEDRATE);
    Printer::maxFeedrate[Y_AXIS] = HAL::eprGetFloat(EPR_Y_MAX_FEEDRATE);
    Printer::maxFeedrate[Z_AXIS] = HAL::eprGetFloat(EPR_Z_MAX_FEEDRATE);
    Printer::homingFeedrate[X_AXIS] = HAL::eprGetFloat(EPR_X_HOMING_FEEDRATE);
    Printer::homingFeedrate[Y_AXIS] = HAL::eprGetFloat(EPR_Y_HOMING_FEEDRATE);
    Printer::homingFeedrate[Z_AXIS] = HAL::eprGetFloat(EPR_Z_HOMING_FEEDRATE);
    Printer::maxJerk = HAL::eprGetFloat(EPR_MAX_JERK);
#if DRIVE_SYSTEM!=DELTA
    Printer::maxZJerk = HAL::eprGetFloat(EPR_MAX_ZJERK);
#endif
#if RAMP_ACCELERATION
    Printer::maxAccelerationMMPerSquareSecond[X_AXIS] = HAL::eprGetFloat(EPR_X_MAX_ACCEL);
    Printer::maxAccelerationMMPerSquareSecond[Y_AXIS] = HAL::eprGetFloat(EPR_Y_MAX_ACCEL);
    Printer::maxAccelerationMMPerSquareSecond[Z_AXIS] = HAL::eprGetFloat(EPR_Z_MAX_ACCEL);
    Printer::maxTravelAccelerationMMPerSquareSecond[X_AXIS] = HAL::eprGetFloat(EPR_X_MAX_TRAVEL_ACCEL);
    Printer::maxTravelAccelerationMMPerSquareSecond[Y_AXIS] = HAL::eprGetFloat(EPR_Y_MAX_TRAVEL_ACCEL);
    Printer::maxTravelAccelerationMMPerSquareSecond[Z_AXIS] = HAL::eprGetFloat(EPR_Z_MAX_TRAVEL_ACCEL);
#endif
#if HAVE_HEATED_BED
    heatedBedController.heatManager= HAL::eprGetByte(EPR_BED_HEAT_MANAGER);
#if TEMP_PID
    heatedBedController.pidDriveMax = HAL::eprGetByte(EPR_BED_DRIVE_MAX);
    heatedBedController.pidDriveMin = HAL::eprGetByte(EPR_BED_DRIVE_MIN);
    heatedBedController.pidPGain = HAL::eprGetFloat(EPR_BED_PID_PGAIN);
    heatedBedController.pidIGain = HAL::eprGetFloat(EPR_BED_PID_IGAIN);
    heatedBedController.pidDGain = HAL::eprGetFloat(EPR_BED_PID_DGAIN);
    heatedBedController.pidMax = HAL::eprGetByte(EPR_BED_PID_MAX);
#endif
#endif
    Printer::xMin = HAL::eprGetFloat(EPR_X_HOME_OFFSET);
    Printer::yMin = HAL::eprGetFloat(EPR_Y_HOME_OFFSET);
    Printer::zMin = HAL::eprGetFloat(EPR_Z_HOME_OFFSET);
    Printer::xLength = HAL::eprGetFloat(EPR_X_LENGTH);
    Printer::yLength = HAL::eprGetFloat(EPR_Y_LENGTH);
    Printer::zLength = HAL::eprGetFloat(EPR_Z_LENGTH);
#if NONLINEAR_SYSTEM
    Printer::radius0 = HAL::eprGetFloat(EPR_DELTA_HORIZONTAL_RADIUS);
#endif
#if ENABLE_BACKLASH_COMPENSATION
    Printer::backlashX = HAL::eprGetFloat(EPR_BACKLASH_X);
    Printer::backlashY = HAL::eprGetFloat(EPR_BACKLASH_Y);
    Printer::backlashZ = HAL::eprGetFloat(EPR_BACKLASH_Z);
#endif
#if FEATURE_AUTOLEVEL
    if(version>2)
    {
        float sum = 0;
        for(uint8_t i=0; i<9; i++)
            Printer::autolevelTransformation[i] = HAL::eprGetFloat(EPR_AUTOLEVEL_MATRIX + (((int)i) << 2));
        if(isnan(Printer::autolevelTransformation[0]))   // a bug caused storage of matrix at the wrong place. Read from old position instead.
        {
            for(uint8_t i=0; i<9; i++)
                Printer::autolevelTransformation[i] = HAL::eprGetFloat((EPR_AUTOLEVEL_MATRIX + (int)i) << 2);
        }
        for(uint8_t i=0; i<9; i++)
        {
            if(isnan(Printer::autolevelTransformation[i]))
                sum += 10;
            else
                sum += RMath::sqr(Printer::autolevelTransformation[i]);
        }
        if(sum < 2.7 || sum > 3.3)
            Printer::resetTransformationMatrix(false);
        Printer::setAutolevelActive(HAL::eprGetByte(EPR_AUTOLEVEL_ACTIVE));
        Com::printArrayFLN(Com::tTransformationMatrix,Printer::autolevelTransformation,9,6);
    }
#endif
#if MIXING_EXTRUDER
    readMixingRatios();
#endif
    // now the extruder
    for(uint8_t i=0; i<NUM_EXTRUDER; i++)
    {
#if FEATURE_WATCHDOG
        HAL::pingWatchdog();
#endif // FEATURE_WATCHDOG

        int o=i*EEPROM_EXTRUDER_LENGTH+EEPROM_EXTRUDER_OFFSET;
        Extruder *e = &extruder[i];
        e->stepsPerMM = HAL::eprGetFloat(o+EPR_EXTRUDER_STEPS_PER_MM);
        e->maxFeedrate = HAL::eprGetFloat(o+EPR_EXTRUDER_MAX_FEEDRATE);
        e->maxStartFeedrate = HAL::eprGetFloat(o+EPR_EXTRUDER_MAX_START_FEEDRATE);
        e->maxAcceleration = HAL::eprGetFloat(o+EPR_EXTRUDER_MAX_ACCELERATION);
        e->tempControl.heatManager = HAL::eprGetByte(o+EPR_EXTRUDER_HEAT_MANAGER);
#if TEMP_PID
        e->tempControl.pidDriveMax = HAL::eprGetByte(o+EPR_EXTRUDER_DRIVE_MAX);
        e->tempControl.pidDriveMin = HAL::eprGetByte(o+EPR_EXTRUDER_DRIVE_MIN);
        e->tempControl.pidPGain = HAL::eprGetFloat(o+EPR_EXTRUDER_PID_PGAIN);
        e->tempControl.pidIGain = HAL::eprGetFloat(o+EPR_EXTRUDER_PID_IGAIN);
        e->tempControl.pidDGain = HAL::eprGetFloat(o+EPR_EXTRUDER_PID_DGAIN);
        e->tempControl.pidMax = HAL::eprGetByte(o+EPR_EXTRUDER_PID_MAX);
#endif
        e->xOffset = HAL::eprGetInt32(o+EPR_EXTRUDER_X_OFFSET);
        e->yOffset = HAL::eprGetInt32(o+EPR_EXTRUDER_Y_OFFSET);
        e->watchPeriod = HAL::eprGetInt16(o+EPR_EXTRUDER_WATCH_PERIOD);
#if RETRACT_DURING_HEATUP
        e->waitRetractTemperature = HAL::eprGetInt16(o+EPR_EXTRUDER_WAIT_RETRACT_TEMP);
        e->waitRetractUnits = HAL::eprGetInt16(o+EPR_EXTRUDER_WAIT_RETRACT_UNITS);
#endif
#if USE_ADVANCE
#if ENABLE_QUADRATIC_ADVANCE
        e->advanceK = HAL::eprGetFloat(o+EPR_EXTRUDER_ADVANCE_K);
#endif
        e->advanceL = HAL::eprGetFloat(o+EPR_EXTRUDER_ADVANCE_L);
#endif
        if(version>1)
            e->coolerSpeed = HAL::eprGetByte(o+EPR_EXTRUDER_COOLER_SPEED);
    }
    if(version!=EEPROM_PROTOCOL_VERSION)
    {
        Com::printInfoFLN(Com::tEPRProtocolChanged);
        if(version<3)
        {
            HAL::eprSetFloat(EPR_Z_PROBE_HEIGHT,Z_PROBE_HEIGHT);
            HAL::eprSetFloat(EPR_Z_PROBE_SPEED,Z_PROBE_SPEED);
            HAL::eprSetFloat(EPR_Z_PROBE_XY_SPEED,Z_PROBE_XY_SPEED);
            HAL::eprSetFloat(EPR_Z_PROBE_X_OFFSET,Z_PROBE_X_OFFSET);
            HAL::eprSetFloat(EPR_Z_PROBE_Y_OFFSET,Z_PROBE_Y_OFFSET);
            HAL::eprSetFloat(EPR_Z_PROBE_X1,Z_PROBE_X1);
            HAL::eprSetFloat(EPR_Z_PROBE_Y1,Z_PROBE_Y1);
            HAL::eprSetFloat(EPR_Z_PROBE_X2,Z_PROBE_X2);
            HAL::eprSetFloat(EPR_Z_PROBE_Y2,Z_PROBE_Y2);
            HAL::eprSetFloat(EPR_Z_PROBE_X3,Z_PROBE_X3);
            HAL::eprSetFloat(EPR_Z_PROBE_Y3,Z_PROBE_Y3);
        }
        if(version<4)
        {
#if DRIVE_SYSTEM==DELTA
            HAL::eprSetFloat(EPR_DELTA_DIAGONAL_ROD_LENGTH,DELTA_DIAGONAL_ROD);
            HAL::eprSetFloat(EPR_DELTA_HORIZONTAL_RADIUS,ROD_RADIUS);
            HAL::eprSetInt16(EPR_DELTA_SEGMENTS_PER_SECOND_PRINT,DELTA_SEGMENTS_PER_SECOND_PRINT);
            HAL::eprSetInt16(EPR_DELTA_SEGMENTS_PER_SECOND_MOVE,DELTA_SEGMENTS_PER_SECOND_MOVE);
            HAL::eprSetInt16(EPR_DELTA_TOWERX_OFFSET_STEPS,DELTA_X_ENDSTOP_OFFSET_STEPS);
            HAL::eprSetInt16(EPR_DELTA_TOWERY_OFFSET_STEPS,DELTA_Y_ENDSTOP_OFFSET_STEPS);
            HAL::eprSetInt16(EPR_DELTA_TOWERZ_OFFSET_STEPS,DELTA_Z_ENDSTOP_OFFSET_STEPS);
#endif
        }
#if DRIVE_SYSTEM==DELTA
        if(version<5)
        {
            HAL::eprSetFloat(EPR_DELTA_ALPHA_A,DELTA_ALPHA_A);
            HAL::eprSetFloat(EPR_DELTA_ALPHA_B,DELTA_ALPHA_B);
            HAL::eprSetFloat(EPR_DELTA_ALPHA_C,DELTA_ALPHA_C);
        }
        if(version<6)
        {
            HAL::eprSetFloat(EPR_DELTA_RADIUS_CORR_A,DELTA_RADIUS_CORRECTION_A);
            HAL::eprSetFloat(EPR_DELTA_RADIUS_CORR_B,DELTA_RADIUS_CORRECTION_B);
            HAL::eprSetFloat(EPR_DELTA_RADIUS_CORR_C,DELTA_RADIUS_CORRECTION_C);
        }
        if(version<7)
        {
            HAL::eprSetFloat(EPR_DELTA_MAX_RADIUS,DELTA_MAX_RADIUS);
            HAL::eprSetFloat(EPR_DELTA_DIAGONAL_CORRECTION_A,DELTA_DIAGONAL_CORRECTION_A);
            HAL::eprSetFloat(EPR_DELTA_DIAGONAL_CORRECTION_B,DELTA_DIAGONAL_CORRECTION_B);
            HAL::eprSetFloat(EPR_DELTA_DIAGONAL_CORRECTION_C,DELTA_DIAGONAL_CORRECTION_C);
        }
#endif
        if(version<7)
        {
            HAL::eprSetFloat(EPR_Z_PROBE_BED_DISTANCE,Z_PROBE_BED_DISTANCE);
        }
        if(version < 9)
        {
#if MIXING_EXTRUDER
            storeMixingRatios(false);
#endif
        }
        if(version < 10) {
            HAL::eprSetFloat(EPR_AXISCOMP_TANXY,AXISCOMP_TANXY);
            HAL::eprSetFloat(EPR_AXISCOMP_TANYZ,AXISCOMP_TANYZ);
            HAL::eprSetFloat(EPR_AXISCOMP_TANXZ,AXISCOMP_TANXZ);
        }
        /*        if (version<8) {
        #if DRIVE_SYSTEM==DELTA
                  // Prior to verion 8, the cartesian max was stored in the zmax
                  // Now, x,y and z max are used for tower a, b anc c
                  // Of tower min are all set at 0, tower max is larger than cartesian max
                  // by the height of any tower for coordinate 0,0,0
                  long cart[Z_AXIS_ARRAY], delta[TOWER_ARRAY];
                  cart[X_AXIS] = cart[Y_AXIS] = cart[Z_AXIS] = 0;
                  transformCartesianStepsToDeltaSteps(cart, delta);
                  // We can only count on ZLENGTH being set correctly, as it was used for all towers
                  Printer::xLength = Printer::zLength + delta[X_AXIS];
                  Printer::yLength = Printer::zLength + delta[Y_AXIS];
                  Printer::zLength += delta[Z_AXIS];
        #endif
                }*/

        storeDataIntoEEPROM(false); // Store new fields for changed version
    }
    Printer::updateDerivedParameter();
    Extruder::initHeatedBed();
#endif
}