diff --git a/Configuration.h b/Configuration.h index a70a204..bb9a140 100644 --- a/Configuration.h +++ b/Configuration.h @@ -26,11 +26,11 @@ Licence: GPL #define NAME "RepRapFirmware" #ifndef VERSION -#define VERSION "1.09i-dc42" +#define VERSION "1.09j-dc42" #endif #ifndef DATE -#define DATE "2015-09-02" +#define DATE "2015-09-06" #endif #define AUTHORS "reprappro, dc42, zpl, t3p3, dnewman" diff --git a/DDA.cpp b/DDA.cpp index 28d10c6..7075b35 100644 --- a/DDA.cpp +++ b/DDA.cpp @@ -831,11 +831,11 @@ bool DDA::Step() } const uint32_t elapsedTime = (Platform::GetInterruptClocks() - moveStartTime) + minInterruptInterval; - while (elapsedTime >= dm->nextStepTime) // if the next step is due + while (elapsedTime >= dm->nextStepTime) // if the next step is due { size_t drive = dm->drive; - reprap.GetPlatform()->StepHigh(drive); ++numReps; + reprap.GetPlatform()->StepHigh(drive); firstDM = dm->nextDM; bool moreSteps = (isDeltaMovement && drive < AXES) ? dm->CalcNextStepTimeDelta(*this, drive) : dm->CalcNextStepTimeCartesian(*this, drive); if (moreSteps) diff --git a/DDA.h b/DDA.h index 5d2b1e1..22ba97b 100644 --- a/DDA.h +++ b/DDA.h @@ -140,11 +140,12 @@ inline void DDA::SetDriveCoordinate(int32_t a, size_t drive) endCoordinatesValid = false; } -// Insert the specified drive into the step list, in step time order +// Insert the specified drive into the step list, in step time order. +// We insert the drive after any existing entries with the same step time so that we service them in round-robin order. inline void DDA::InsertDM(DriveMovement *dm) { DriveMovement **dmp = &firstDM; - while (*dmp != nullptr && (*dmp)->nextStepTime < dm->nextStepTime) + while (*dmp != nullptr && (*dmp)->nextStepTime <= dm->nextStepTime) { dmp = &((*dmp)->nextDM); } diff --git a/GCodes.cpp b/GCodes.cpp index ae9aec8..162cf03 100644 --- a/GCodes.cpp +++ b/GCodes.cpp @@ -890,9 +890,23 @@ bool GCodes::DoCannedCycleMove(EndstopChecks ce) // This sets positions. I.e. it handles G92. bool GCodes::SetPositions(GCodeBuffer *gb) { - if (!AllMovesAreFinishedAndMoveBufferIsLoaded()) + // Don't pause the machine if only extruder drives are being reset (DC, 2015-09-06) + bool doPause = false; + for (size_t drive = 0; drive < AXES; ++drive) { - return false; + if (gb->Seen(axisLetters[drive])) + { + doPause = true; + break; + } + } + + if (doPause) + { + if (!AllMovesAreFinishedAndMoveBufferIsLoaded()) + { + return false; + } } reprap.GetMove()->GetCurrentUserPosition(moveBuffer, 0); // make sure move buffer is up to date @@ -4264,21 +4278,36 @@ bool GCodes::HandleMcode(GCodeBuffer* gb, StringRef& reply) case 667: // Set CoreXY mode { Move* move = reprap.GetMove(); + bool seen = false; + float positionNow[DRIVES]; + move->GetCurrentUserPosition(positionNow, 0); // get the current position, we may need it later if (gb->Seen('S')) { - float positionNow[DRIVES]; - move->GetCurrentUserPosition(positionNow, 0); // get the current position, we may need it later - int newMode = gb->GetIValue(); - if (newMode != move->GetCoreXYMode()) + move->SetCoreXYMode(gb->GetIValue()); + seen = true; + } + for (size_t axis = 0; axis < AXES; ++axis) + { + if (gb->Seen(axisLetters[axis])) { - move->SetCoreXYMode(newMode); - SetPositions(positionNow); - SetAllAxesNotHomed(); + move->setCoreAxisFactor(axis, gb->GetFValue()); + seen = true; } } + + if (seen) + { + SetPositions(positionNow); + SetAllAxesNotHomed(); + } else { - reply.printf("Printer mode is %s\n", move->GetGeometryString()); + reply.printf("Printer mode is %s with axis factors", move->GetGeometryString()); + for (size_t axis = 0; axis < AXES; ++axis) + { + reply.catf(" %c:%f", move->GetCoreAxisFactor(axis)); + } + reply.cat("\n"); } } break; diff --git a/Move.cpp b/Move.cpp index ccdf253..0ad7279 100644 --- a/Move.cpp +++ b/Move.cpp @@ -29,6 +29,10 @@ void Move::Init() // Reset Cartesian mode deltaParams.Init(); coreXYMode = 0; + for (size_t axis = 0; axis < AXES; ++axis) + { + axisFactors[axis] = 1.0; + } deltaProbing = false; // Empty the ring @@ -297,6 +301,7 @@ FilePosition Move::PausePrint(float positions[DRIVES+1]) DDA *dda = currentDda; if (dda != nullptr) { + // A move is being executed. See if we can safely pause at the end of it. if (dda->CanPause()) { ddaRingAddPointer = dda->GetNext(); @@ -311,6 +316,11 @@ FilePosition Move::PausePrint(float positions[DRIVES+1]) if (dda->CanPause()) { ddaRingAddPointer = dda->GetNext(); + if (ddaRingAddPointer->GetState() == DDA::frozen) + { + // Change the state so that the ISR won't start executing this move + ddaRingAddPointer->Free(); + } break; } dda = dda->GetNext(); @@ -319,8 +329,10 @@ FilePosition Move::PausePrint(float positions[DRIVES+1]) } else { + // No move being executed ddaRingAddPointer = ddaRingGetPointer; } + cpu_irq_enable(); FilePosition fPos = noFilePosition; @@ -350,7 +362,7 @@ FilePosition Move::PausePrint(float positions[DRIVES+1]) { fPos = dda->GetFilePosition(); } - dda->Complete(); + dda->Free(); dda = dda->GetNext(); } while (dda != savedDdaRingAddPointer); @@ -454,21 +466,27 @@ void Move::MachineToEndPoint(const int32_t motorPos[], float machinePos[], size_ switch (coreXYMode) { case 1: // CoreXY - machinePos[X_AXIS] = ((motorPos[X_AXIS] * stepsPerUnit[Y_AXIS]) - (motorPos[Y_AXIS] * stepsPerUnit[X_AXIS]))/(2 * stepsPerUnit[X_AXIS] * stepsPerUnit[Y_AXIS]); - machinePos[Y_AXIS] = ((motorPos[X_AXIS] * stepsPerUnit[Y_AXIS]) + (motorPos[Y_AXIS] * stepsPerUnit[X_AXIS]))/(2 * stepsPerUnit[X_AXIS] * stepsPerUnit[Y_AXIS]); + machinePos[X_AXIS] = ((motorPos[X_AXIS] * stepsPerUnit[Y_AXIS]) - (motorPos[Y_AXIS] * stepsPerUnit[X_AXIS])) + /(2 * axisFactors[X_AXIS] * stepsPerUnit[X_AXIS] * stepsPerUnit[Y_AXIS]); + machinePos[Y_AXIS] = ((motorPos[X_AXIS] * stepsPerUnit[Y_AXIS]) + (motorPos[Y_AXIS] * stepsPerUnit[X_AXIS])) + /(2 * axisFactors[Y_AXIS] * stepsPerUnit[X_AXIS] * stepsPerUnit[Y_AXIS]); machinePos[Z_AXIS] = motorPos[Z_AXIS]/stepsPerUnit[Z_AXIS]; break; case 2: // CoreXZ - machinePos[X_AXIS] = ((motorPos[X_AXIS] * stepsPerUnit[Z_AXIS]) - (motorPos[Z_AXIS] * stepsPerUnit[X_AXIS]))/(2 * stepsPerUnit[X_AXIS] * stepsPerUnit[Z_AXIS]); + machinePos[X_AXIS] = ((motorPos[X_AXIS] * stepsPerUnit[Z_AXIS]) - (motorPos[Z_AXIS] * stepsPerUnit[X_AXIS])) + /(2 * axisFactors[X_AXIS] * stepsPerUnit[X_AXIS] * stepsPerUnit[Z_AXIS]); machinePos[Y_AXIS] = motorPos[Y_AXIS]/stepsPerUnit[Y_AXIS]; - machinePos[Z_AXIS] = ((motorPos[X_AXIS] * stepsPerUnit[Z_AXIS]) + (motorPos[Z_AXIS] * stepsPerUnit[X_AXIS]))/(2 * stepsPerUnit[X_AXIS] * stepsPerUnit[Z_AXIS]); + machinePos[Z_AXIS] = ((motorPos[X_AXIS] * stepsPerUnit[Z_AXIS]) + (motorPos[Z_AXIS] * stepsPerUnit[X_AXIS])) + /(2 * axisFactors[Z_AXIS] * stepsPerUnit[X_AXIS] * stepsPerUnit[Z_AXIS]); break; case 3: // CoreYZ machinePos[X_AXIS] = motorPos[X_AXIS]/stepsPerUnit[X_AXIS]; - machinePos[Y_AXIS] = ((motorPos[Y_AXIS] * stepsPerUnit[Z_AXIS]) - (motorPos[Z_AXIS] * stepsPerUnit[Y_AXIS]))/(2 * stepsPerUnit[Y_AXIS] * stepsPerUnit[Z_AXIS]); - machinePos[Z_AXIS] = ((motorPos[Y_AXIS] * stepsPerUnit[Z_AXIS]) + (motorPos[Z_AXIS] * stepsPerUnit[Y_AXIS]))/(2 * stepsPerUnit[Y_AXIS] * stepsPerUnit[Z_AXIS]); + machinePos[Y_AXIS] = ((motorPos[Y_AXIS] * stepsPerUnit[Z_AXIS]) - (motorPos[Z_AXIS] * stepsPerUnit[Y_AXIS])) + /(2 * axisFactors[Y_AXIS] * stepsPerUnit[Y_AXIS] * stepsPerUnit[Z_AXIS]); + machinePos[Z_AXIS] = ((motorPos[Y_AXIS] * stepsPerUnit[Z_AXIS]) + (motorPos[Z_AXIS] * stepsPerUnit[Y_AXIS])) + /(2 * axisFactors[Z_AXIS] * stepsPerUnit[Y_AXIS] * stepsPerUnit[Z_AXIS]); break; default: @@ -505,25 +523,25 @@ void Move::MotorTransform(const float machinePos[AXES], int32_t motorPos[AXES]) { switch (coreXYMode) { - case 1: - motorPos[X_AXIS] = MotorEndPointToMachine(X_AXIS, machinePos[X_AXIS] + machinePos[Y_AXIS]); - motorPos[Y_AXIS] = MotorEndPointToMachine(Y_AXIS, machinePos[Y_AXIS] - machinePos[X_AXIS]); + case 1: // CoreXY + motorPos[X_AXIS] = MotorEndPointToMachine(X_AXIS, (machinePos[X_AXIS] * axisFactors[X_AXIS]) + (machinePos[Y_AXIS] * axisFactors[Y_AXIS])); + motorPos[Y_AXIS] = MotorEndPointToMachine(Y_AXIS, (machinePos[Y_AXIS] * axisFactors[Y_AXIS]) - (machinePos[X_AXIS] * axisFactors[X_AXIS])); motorPos[Z_AXIS] = MotorEndPointToMachine(Z_AXIS, machinePos[Z_AXIS]); break; - case 2: - motorPos[X_AXIS] = MotorEndPointToMachine(X_AXIS, machinePos[X_AXIS] + machinePos[Z_AXIS]); + case 2: // CoreXZ + motorPos[X_AXIS] = MotorEndPointToMachine(X_AXIS, (machinePos[X_AXIS] * axisFactors[X_AXIS]) + (machinePos[Z_AXIS] * axisFactors[Z_AXIS])); motorPos[Y_AXIS] = MotorEndPointToMachine(Y_AXIS, machinePos[Y_AXIS]); - motorPos[Z_AXIS] = MotorEndPointToMachine(Z_AXIS, machinePos[Z_AXIS] - machinePos[X_AXIS]); + motorPos[Z_AXIS] = MotorEndPointToMachine(Z_AXIS, (machinePos[Z_AXIS] * axisFactors[Z_AXIS]) - (machinePos[X_AXIS] * axisFactors[X_AXIS])); break; - case 3: + case 3: // CoreYZ motorPos[X_AXIS] = MotorEndPointToMachine(X_AXIS, machinePos[X_AXIS]); - motorPos[Y_AXIS] = MotorEndPointToMachine(Y_AXIS, machinePos[Y_AXIS] + machinePos[Z_AXIS]); - motorPos[Z_AXIS] = MotorEndPointToMachine(Z_AXIS, machinePos[Z_AXIS] - machinePos[Y_AXIS]); + motorPos[Y_AXIS] = MotorEndPointToMachine(Y_AXIS, (machinePos[Y_AXIS] * axisFactors[Y_AXIS]) + (machinePos[Z_AXIS] * axisFactors[Z_AXIS])); + motorPos[Z_AXIS] = MotorEndPointToMachine(Z_AXIS, (machinePos[Z_AXIS] * axisFactors[Z_AXIS]) - (machinePos[Y_AXIS] * axisFactors[Y_AXIS])); break; - default: + default: // Cartesian motorPos[X_AXIS] = MotorEndPointToMachine(X_AXIS, machinePos[X_AXIS]); motorPos[Y_AXIS] = MotorEndPointToMachine(Y_AXIS, machinePos[Y_AXIS]); motorPos[Z_AXIS] = MotorEndPointToMachine(Z_AXIS, machinePos[Z_AXIS]); diff --git a/Move.h b/Move.h index 188e6aa..fa7c0d0 100644 --- a/Move.h +++ b/Move.h @@ -76,6 +76,8 @@ public: int GetCoreXYMode() const { return coreXYMode; } void SetCoreXYMode(int mode) { coreXYMode = mode; } + float GetCoreAxisFactor(size_t axis) const { return axisFactors[axis]; } + void setCoreAxisFactor(size_t axis, float f) { axisFactors[axis] = f; } bool IsCoreXYAxis(size_t axis) const; // return true if the specified axis shares its motors with another void CurrentMoveCompleted(); // signals that the current move has just been completed @@ -158,6 +160,7 @@ private: uint32_t deltaProbingStartTime; bool deltaProbing; int coreXYMode; // 0 = Cartesian, 1 = CoreXY, 2 = CoreXZ, 3 = CoreYZ + float axisFactors[AXES]; // How much further the motors need to move for each axis movement, on a CoreXY/CoreXZ/CoreYZ machine unsigned int stepErrors; // count of step errors, for diagnostics }; diff --git a/Platform.cpp b/Platform.cpp index de37035..37209a1 100644 --- a/Platform.cpp +++ b/Platform.cpp @@ -251,8 +251,10 @@ void Platform::Init() SetElasticComp(drive, 0.0); if (drive <= AXES) { - endStopType[drive] = EndStopType::lowEndStop; // assume all endstops are low endstops - endStopLogicLevel[drive] = true; // assume all endstops use active high logic e.g. normally-closed switch to ground + endStopType[drive] = (drive == Y_AXIS) + ? EndStopType::lowEndStop // for Ormerod 2/Huxley/Mendel compatibility + : EndStopType::noEndStop; // for Ormerod/Huxley/Mendel compatibility + endStopLogicLevel[drive] = true; // assume all endstops use active high logic e.g. normally-closed switch to ground } } @@ -1247,12 +1249,15 @@ void Platform::SetHeater(size_t heater, float power) EndStopHit Platform::Stopped(size_t drive) const { - if (nvData.zProbeType > 0 && drive < AXES && nvData.zProbeAxes[drive]) + if (endStopType[drive] == EndStopType::noEndStop) { - return GetZProbeResult(); // using the Z probe as am endstop for this axis, so just get its result + // No homing switch is configured for this axis, so see if we should use the Z probe + if (nvData.zProbeType > 0 && drive < AXES && nvData.zProbeAxes[drive]) + { + return GetZProbeResult(); // using the Z probe as a low homing stop for this axis, so just get its result + } } - - if (endStopPins[drive] >= 0 && endStopType[drive] != EndStopType::noEndStop) + else if (endStopPins[drive] >= 0) { if (digitalReadNonDue(endStopPins[drive]) == ((endStopLogicLevel[drive]) ? 1 : 0)) { diff --git a/Release/RepRapFirmware-1.09j-dc42.bin b/Release/RepRapFirmware-1.09j-dc42.bin new file mode 100644 index 0000000..6b587a8 Binary files /dev/null and b/Release/RepRapFirmware-1.09j-dc42.bin differ