Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/Duet3D/RepRapFirmware.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Crocker <dcrocker@eschertech.com>2015-08-22 12:59:56 +0300
committerDavid Crocker <dcrocker@eschertech.com>2015-08-22 13:01:28 +0300
commit87980e2966c0312c0f63e44bab9910e21cff1df3 (patch)
treefa9b25e16e2c808cc3a806dcf93260166a481c78
parent9d6603c678109a7f240e940f276c9221034351fd (diff)
Version 1.09f
Fixed print quality problems that mostly affected delta printers e.g. on spiral vase cylinder When reconnecting a browser, cancel any file upload from the same IP address M111 now prints the number of each module with debugging enabled or disabled In special moves on delta printers, the F parameter is now interpreted as the speed of the tower that moves the most M114 now reports stepper positions as well as head position Default to output in Marlin mode M104 command defaults to the only tool if there is only one tool and it is not selected Trying different code for M999PERASE command to see if we can get it to unlock flash and reset more reliably When step errors are logged, report them immediately if Move debugging is enabled. Also reports the total number of step errors in M122. Changed interrupt priority to make tick interrupt higher priority than step interrupt, because we rely on the tick interrupt to check for over temperature conditions and kick the watchdog
-rw-r--r--.settings/org.eclipse.cdt.core.prefs4
-rw-r--r--Configuration.h4
-rw-r--r--DDA.cpp73
-rw-r--r--DDA.h5
-rw-r--r--DeltaParameters.cpp4
-rw-r--r--DriveMovement.cpp83
-rw-r--r--DriveMovement.h4
-rw-r--r--GCodes.cpp12
-rw-r--r--Move.cpp31
-rw-r--r--Move.h3
-rw-r--r--Platform.cpp52
-rw-r--r--Release/RepRapFirmware-1.09f-testing-dc42.binbin0 -> 228680 bytes
-rw-r--r--RepRapFirmware.cpp23
-rw-r--r--RepRapFirmware.h1
-rw-r--r--Reprap.h7
-rw-r--r--SD-image/sys-CoreXY/pause.g1
-rw-r--r--SD-image/sys-CoreXY/resume.g1
-rw-r--r--SD-image/sys-Huxley/pause.g1
-rw-r--r--SD-image/sys-Huxley/resume.g1
-rw-r--r--SD-image/sys-MiniKossel/homedelta.g4
-rw-r--r--SD-image/sys-MiniKossel/pause.g1
-rw-r--r--SD-image/sys-MiniKossel/resume.g1
-rw-r--r--SD-image/sys-Ormerod1/pause.g1
-rw-r--r--SD-image/sys-Ormerod1/resume.g1
-rw-r--r--SD-image/sys-Ormerod2/pause.g1
-rw-r--r--SD-image/sys-Ormerod2/resume.g1
-rw-r--r--Webserver.cpp3
27 files changed, 243 insertions, 80 deletions
diff --git a/.settings/org.eclipse.cdt.core.prefs b/.settings/org.eclipse.cdt.core.prefs
index 6d0b64af..7b5d9178 100644
--- a/.settings/org.eclipse.cdt.core.prefs
+++ b/.settings/org.eclipse.cdt.core.prefs
@@ -91,7 +91,7 @@ environment/project/it.baeyens.arduino.core.toolChain.release.674980254/A.COMPIL
environment/project/it.baeyens.arduino.core.toolChain.release.674980254/A.COMPILER.C.EXTRA_FLAGS/value=
environment/project/it.baeyens.arduino.core.toolChain.release.674980254/A.COMPILER.C.FLAGS/delimiter=;
environment/project/it.baeyens.arduino.core.toolChain.release.674980254/A.COMPILER.C.FLAGS/operation=replace
-environment/project/it.baeyens.arduino.core.toolChain.release.674980254/A.COMPILER.C.FLAGS/value=-c -g -O2 -w -ffunction-sections -fdata-sections -nostdlib --param max-inline-insns-single\=500 -Dprintf\=iprintf
+environment/project/it.baeyens.arduino.core.toolChain.release.674980254/A.COMPILER.C.FLAGS/value=-c -g -std\=gnu99 -O2 -ffunction-sections -fdata-sections -nostdlib --param max-inline-insns-single\=500 -Dprintf\=iprintf
environment/project/it.baeyens.arduino.core.toolChain.release.674980254/A.COMPILER.CPP.CMD/delimiter=;
environment/project/it.baeyens.arduino.core.toolChain.release.674980254/A.COMPILER.CPP.CMD/operation=replace
environment/project/it.baeyens.arduino.core.toolChain.release.674980254/A.COMPILER.CPP.CMD/value=arm-none-eabi-g++
@@ -100,7 +100,7 @@ environment/project/it.baeyens.arduino.core.toolChain.release.674980254/A.COMPIL
environment/project/it.baeyens.arduino.core.toolChain.release.674980254/A.COMPILER.CPP.EXTRA_FLAGS/value=
environment/project/it.baeyens.arduino.core.toolChain.release.674980254/A.COMPILER.CPP.FLAGS/delimiter=;
environment/project/it.baeyens.arduino.core.toolChain.release.674980254/A.COMPILER.CPP.FLAGS/operation=replace
-environment/project/it.baeyens.arduino.core.toolChain.release.674980254/A.COMPILER.CPP.FLAGS/value=-c -g -O2 -save-temps -w -ffunction-sections -fdata-sections -nostdlib -fno-threadsafe-statics --param max-inline-insns-single\=500 -fno-rtti -fno-exceptions -Dprintf\=iprintf
+environment/project/it.baeyens.arduino.core.toolChain.release.674980254/A.COMPILER.CPP.FLAGS/value=-c -g -std\=gnu++11 -O2 -ffunction-sections -fdata-sections -nostdlib -fno-threadsafe-statics --param max-inline-insns-single\=500 -fno-rtti -fno-exceptions -Dprintf\=iprintf
environment/project/it.baeyens.arduino.core.toolChain.release.674980254/A.COMPILER.DEFINE/delimiter=;
environment/project/it.baeyens.arduino.core.toolChain.release.674980254/A.COMPILER.DEFINE/operation=replace
environment/project/it.baeyens.arduino.core.toolChain.release.674980254/A.COMPILER.DEFINE/value=-DARDUINO\=
diff --git a/Configuration.h b/Configuration.h
index 968c792f..dd0c30fb 100644
--- a/Configuration.h
+++ b/Configuration.h
@@ -24,8 +24,8 @@ Licence: GPL
#define CONFIGURATION_H
#define NAME "RepRapFirmware"
-#define VERSION "1.09e-dc42"
-#define DATE "2015-08-10"
+#define VERSION "1.09f-dc42"
+#define DATE "2015-08-22"
#define AUTHORS "reprappro, dc42, zpl"
#define FLASH_SAVE_ENABLED (1)
diff --git a/DDA.cpp b/DDA.cpp
index 5af484e8..e68194bf 100644
--- a/DDA.cpp
+++ b/DDA.cpp
@@ -38,15 +38,21 @@ void DDA::DebugPrint() const
debugPrintf("DDA:");
if (endCoordinatesValid)
{
+ float startCoordinates[AXES];
+ for (size_t i = 0; i < AXES; ++i)
+ {
+ startCoordinates[i] = endCoordinates[i] - (totalDistance * directionVector[i]);
+ }
+ DebugPrintVector(" start", startCoordinates, AXES);
DebugPrintVector(" end", endCoordinates, AXES);
}
debugPrintf(" d=%f", totalDistance);
DebugPrintVector(" vec", directionVector, 5);
- debugPrintf(" a=%f reqv=%f topv=%f startv=%f endv=%f\n"
- "daccel=%f ddecel=%f fstep=%u\n",
+ debugPrintf("\na=%f reqv=%f topv=%f startv=%f endv=%f\n"
+ "daccel=%f ddecel=%f fstep=%u cks=%u\n",
acceleration, requestedSpeed, topSpeed, startSpeed, endSpeed,
- accelDistance, decelDistance, firstStepTime);
+ accelDistance, decelDistance, firstStepTime, clocksNeeded);
// reprap.GetPlatform()->GetLine()->Flush();
ddm[0].DebugPrint('x', isDeltaMovement);
ddm[1].DebugPrint('y', isDeltaMovement);
@@ -197,6 +203,8 @@ bool DDA::Init(const float nextMove[], EndstopChecks ce, bool doMotorMapping, Fi
}
else
{
+ // The distance to reversal is the solution to a quadratic equation. One root corresponds to the carriages being above the bed,
+ // the other root corresponds to the carriages being above the bed.
const float drev = ((directionVector[Z_AXIS] * sqrt(a2b2D2 - fsquare(A * directionVector[Y_AXIS] - B * directionVector[X_AXIS])))
- aAplusbB)/a2plusb2;
if (drev > 0.0 && drev < totalDistance) // if the reversal point is within range
@@ -250,7 +258,26 @@ bool DDA::Init(const float nextMove[], EndstopChecks ce, bool doMotorMapping, Fi
// Set the speed to the smaller of the requested and maximum speed.
// Also enforce a minimum speed of 0.5mm/sec. We need a minimum speed to avoid overflow in the movement calculations.
- requestedSpeed = max<float>(0.5, min<float>(nextMove[DRIVES], VectorBoxIntersection(normalisedDirectionVector, reprap.GetPlatform()->MaxFeedrates(), DRIVES)));
+ float reqSpeed = nextMove[DRIVES];
+ if (reprap.GetMove()->IsDeltaMode() && !isDeltaMovement)
+ {
+ // Special case of a raw or homing move on a delta printer
+ // We use the Cartesian motion system to implement these moves, so the feed rate will be interpreted in Cartesian coordinates.
+ // This is wrong, we want the feed rate to apply to the drive that is moving the farthest.
+ float maxDistance = 0.0;
+ for (size_t axis = 0; axis < AXES; ++axis)
+ {
+ if (normalisedDirectionVector[axis] > maxDistance)
+ {
+ maxDistance = normalisedDirectionVector[axis];
+ }
+ }
+ if (maxDistance != 0.0) // should always be true
+ {
+ reqSpeed /= maxDistance; // because normalisedDirectionVector is unit-normalised
+ }
+ }
+ requestedSpeed = max<float>(0.5, min<float>(reqSpeed, VectorBoxIntersection(normalisedDirectionVector, reprap.GetPlatform()->MaxFeedrates(), DRIVES)));
// On a Cartesian printer, it is OK to limit the X and Y speeds and accelerations independently, and in consequence to allow greater values
// for diagonal moves. On a delta, this is not OK and any movement in the XY plane should be limited to the X/Y axis values, which we assume to be equal.
@@ -622,7 +649,7 @@ void DDA::Prepare()
dm.stepsTillRecalc = 1;
uint32_t st = (isDeltaMovement && drive < AXES)
? dm.CalcNextStepTimeDelta(*this, drive)
- : dm.CalcNextStepTimeCartesian(drive);
+ : dm.CalcNextStepTimeCartesian(*this, drive);
if (st < firstStepTime)
{
firstStepTime = st;
@@ -633,10 +660,7 @@ void DDA::Prepare()
if (reprap.Debug(moduleDda) && reprap.Debug(moduleMove)) // temp show the prepared DDA if debug enabled for both modules
{
DebugPrint();
- reprap.GetPlatform()->GetLine()->Flush();
}
-//debugPrintf("Done\n");
-//reprap.GetPlatform()->GetLine()->Flush();
state = frozen; // must do this last so that the ISR doesn't start executing it before we have finished setting it up
}
@@ -645,6 +669,7 @@ void DDA::Prepare()
#pragma GCC optimize ("O3")
// Start executing the move, returning true if Step() needs to be called immediately. Must be called with interrupts disabled, to avoid a race condition.
+// Returns true if the caller needs to call the step ISR immediately.
bool DDA::Start(uint32_t tim)
//pre(state == frozen)
{
@@ -654,8 +679,7 @@ bool DDA::Start(uint32_t tim)
if (firstStepTime == DriveMovement::NoStepTime)
{
// No steps are pending. This should not happen!
- state = completed;
- return false;
+ return true; // schedule another interrupt immediately
}
else
{
@@ -707,14 +731,9 @@ bool DDA::Start(uint32_t tim)
extern uint32_t maxReps;
// This is called by the interrupt service routine to execute steps.
-// It returns true if it needs to be called again with the DDA of the next move, otherwise false.
+// It returns true if it needs to be called again on the DDA of the new current move, otherwise false.
bool DDA::Step()
{
- if (state != executing)
- {
- return false;
- }
-
bool repeat;
uint32_t numReps = 0;
do
@@ -803,7 +822,7 @@ bool DDA::Step()
if (now + minInterruptInterval >= st0)
{
reprap.GetPlatform()->StepHigh(drive);
- uint32_t st1 = (isDeltaMovement && drive < AXES) ? dm.CalcNextStepTimeDelta(*this, drive) : dm.CalcNextStepTimeCartesian(drive);
+ uint32_t st1 = (isDeltaMovement && drive < AXES) ? dm.CalcNextStepTimeDelta(*this, drive) : dm.CalcNextStepTimeCartesian(*this, drive);
if (st1 < nextInterruptTime)
{
nextInterruptTime = st1;
@@ -828,10 +847,10 @@ bool DDA::Step()
if (state == completed)
{
- uint32_t finishTime = Platform::GetInterruptClocks();
+ uint32_t finishTime = moveStartTime + clocksNeeded; // calculate how long this move should take
Move *move = reprap.GetMove();
- move->CurrentMoveCompleted(); // tell Move that the current move is complete
- return move->StartNextMove(finishTime); // schedule the next move
+ move->CurrentMoveCompleted(); // tell Move that the current move is complete
+ return move->StartNextMove(finishTime); // schedule the next move
}
repeat = reprap.GetPlatform()->ScheduleInterrupt(nextInterruptTime + moveStartTime);
} while (repeat);
@@ -890,21 +909,17 @@ void DDA::ReduceHomingSpeed()
}
}
-void DDA::PrintIfHasStepError()
+bool DDA::HasStepError() const
{
- bool printed = false;
for (size_t drive = 0; drive < DRIVES; ++drive)
{
- if (ddm[drive].stepError)
+ const DriveMovement& dm = ddm[drive];
+ if (dm.moving && dm.stepError)
{
- if (!printed)
- {
- DebugPrint();
- printed = true;
- }
- ddm[drive].stepError = false;
+ return true;
}
}
+ return false;
}
// Take a unit positive-hyperquadrant vector, and return the factor needed to obtain
diff --git a/DDA.h b/DDA.h
index ec0ee031..797046b7 100644
--- a/DDA.h
+++ b/DDA.h
@@ -37,10 +37,11 @@ public:
bool Step(); // Take one step of the DDA, called by timed interrupt.
void SetNext(DDA *n) { next = n; }
void SetPrevious(DDA *p) { prev = p; }
- void Release() { state = empty; }
+ void Complete() { state = completed; }
+ void Free() { state = empty; }
void Prepare(); // Calculate all the values and freeze this DDA
float CalcTime() const; // Calculate the time needed for this move (used for simulation)
- void PrintIfHasStepError();
+ bool HasStepError() const;
bool CanPause() const { return canPause; }
DDAState GetState() const { return state; }
diff --git a/DeltaParameters.cpp b/DeltaParameters.cpp
index 3c62259f..a81c6694 100644
--- a/DeltaParameters.cpp
+++ b/DeltaParameters.cpp
@@ -203,8 +203,8 @@ void DeltaParameters::Adjust(size_t numFactors, const float v[])
void DeltaParameters::PrintParameters(StringRef& reply) const
{
- reply.printf("Endstops X%.2f Y%.2f Z%.2f, height %.2f, diagonal %.2f, radius %.2f, xcorr %.2f, ycorr %.2f\n",
- endstopAdjustments[A_AXIS], endstopAdjustments[B_AXIS], endstopAdjustments[C_AXIS], homedHeight, diagonal, radius, xCorrection, yCorrection);
+ reply.printf("Endstops X%.2f Y%.2f Z%.2f, height %.2f, diagonal %.2f, radius %.2f, xcorr %.2f, ycorr %.2f, zcorr %.2f\n",
+ endstopAdjustments[A_AXIS], endstopAdjustments[B_AXIS], endstopAdjustments[C_AXIS], homedHeight, diagonal, radius, xCorrection, yCorrection, zCorrection);
}
// End
diff --git a/DriveMovement.cpp b/DriveMovement.cpp
index 04fc2bf7..bb03ecb7 100644
--- a/DriveMovement.cpp
+++ b/DriveMovement.cpp
@@ -60,7 +60,7 @@ void DriveMovement::PrepareDeltaAxis(const DDA& dda, const PrepParams& params, s
// First check whether there is any deceleration at all, otherwise we may get strange results because of rounding errors
if (dda.decelDistance * stepsPerMm < 0.5)
{
- mp.delta.decelStartDsK = (uint32_t)(dda.totalDistance * stepsPerMm * K2) * 2; // the *2 is to make sure it is definitely high enough
+ mp.delta.decelStartDsK = 0xFFFFFFFF;
topSpeedTimesCdivAPlusDecelStartClocks = 0;
twoDistanceToStopTimesCsquaredDivA = 0;
}
@@ -156,7 +156,7 @@ void DriveMovement::DebugPrint(char c, bool isDeltaMovement) const
if (moving || stepError)
{
debugPrintf("DM%c%s dir=%c steps=%u next=%u interval=%u sstcda=%u "
- "acmadtcdts=%d tstcdapdsc=%u tstdca2=%" PRIu64 "\n",
+ "acmadtcdts=%d tstcdapdsc=%u 2dtstc2diva=%" PRIu64 "\n",
c, (stepError) ? " ERR:" : ":", (direction) ? 'F' : 'B', totalSteps, nextStep, stepInterval, startSpeedTimesCdivA,
accelClocksMinusAccelDistanceTimesCdivTopSpeed, topSpeedTimesCdivAPlusDecelStartClocks, twoDistanceToStopTimesCsquaredDivA);
@@ -188,7 +188,8 @@ void DriveMovement::DebugPrint(char c, bool isDeltaMovement) const
#pragma GCC optimize ("O3")
// Calculate the time since the start of the move when the next step for the specified DriveMovement is due
-uint32_t DriveMovement::CalcNextStepTimeCartesian(size_t drive)
+// This is also used for extruders on delta machines
+uint32_t DriveMovement::CalcNextStepTimeCartesian(const DDA &dda, size_t drive)
{
if (nextStep >= totalSteps)
{
@@ -197,7 +198,7 @@ uint32_t DriveMovement::CalcNextStepTimeCartesian(size_t drive)
}
++nextStep;
- if (stepsTillRecalc > 1)
+ if (stepsTillRecalc > 1 && nextStep != totalSteps)
{
--stepsTillRecalc;
nextStepTime += stepInterval;
@@ -242,19 +243,42 @@ uint32_t DriveMovement::CalcNextStepTimeCartesian(size_t drive)
int32_t interval = (int32_t)nextStepTime - (int32_t)lastStepTime;
if (interval < DDA::MinStepInterval)
{
- stepInterval = (uint32_t)interval;
stepError = true;
- return NoStepTime;
+ if (reprap.Debug(moduleMove))
+ {
+ stepInterval = (uint32_t)interval;
+ return NoStepTime;
+ }
}
-
- // If the step interval is very short, flag not to recalculate it next time
- if (interval < DDA::MinCalcInterval)
+ else if (interval < DDA::MinCalcInterval)
{
+ // If the step interval is very short, flag not to recalculate it next time
stepInterval = (uint32_t)interval;
stepsTillRecalc = DDA::MinCalcInterval/stepInterval + 1;
}
}
}
+
+ if (nextStepTime > dda.clocksNeeded)
+ {
+ // The calculation makes this step late.
+ // When the end speed is very low, calculating the time of the last step is very sensitive to rounding error.
+ // So if this is the last step and it is late, bring it forward to the expected finish time.
+ if (nextStep == totalSteps)
+ {
+ nextStepTime = dda.clocksNeeded;
+ }
+ else
+ {
+ // We don't expect any step except the last to be late
+ stepError = true;
+ if (reprap.Debug(moduleMove))
+ {
+ stepInterval = 10000000 + nextStepTime; // so we can tell what happened in debug
+ return NoStepTime;
+ }
+ }
+ }
return nextStepTime;
}
@@ -268,7 +292,7 @@ uint32_t DriveMovement::CalcNextStepTimeDelta(const DDA &dda, size_t drive)
}
++nextStep;
- if (stepsTillRecalc > 1 && nextStep != mp.delta.reverseStartStep)
+ if (stepsTillRecalc > 1 && nextStep != mp.delta.reverseStartStep && nextStep != totalSteps)
{
--stepsTillRecalc;
nextStepTime += stepInterval;
@@ -290,6 +314,7 @@ uint32_t DriveMovement::CalcNextStepTimeDelta(const DDA &dda, size_t drive)
{
direction = false;
reprap.GetPlatform()->SetDirection(drive, false); // going down now
+ stepsTillRecalc = 1; // we can't trust the interval at the inflexion point
}
// Calculate d*s*K as an integer, where d = distance the head has travelled, s = steps/mm for this drive, K = a power of 2 to reduce the rounding errors
@@ -304,7 +329,9 @@ uint32_t DriveMovement::CalcNextStepTimeDelta(const DDA &dda, size_t drive)
const int32_t hmz0scK = (int32_t)(((int64_t)mp.delta.hmz0sK * dda.cKc)/Kc);
const int32_t t1 = mp.delta.minusAaPlusBbTimesKs + hmz0scK;
- const int32_t t2 = isqrt64(isquare64(t1) + mp.delta.dSquaredMinusAsquaredMinusBsquaredTimesKsquaredSsquared - isquare64(mp.delta.hmz0sK));
+ // Due to rounding error we can end up trying to take the square root of a negative number
+ const int64_t t2a = (int64_t)isquare64(t1) + mp.delta.dSquaredMinusAsquaredMinusBsquaredTimesKsquaredSsquared - (int64_t)isquare64(mp.delta.hmz0sK);
+ const int32_t t2 = (t2a > 0) ? isqrt64(t2a) : 0;
const int32_t dsK = (direction) ? t1 - t2 : t1 + t2;
// Now feed dsK into a modified version of the step algorithm for Cartesian motion without elasticity compensation
@@ -342,18 +369,42 @@ uint32_t DriveMovement::CalcNextStepTimeDelta(const DDA &dda, size_t drive)
if (interval < DDA::MinStepInterval)
{
stepError = true;
- stepInterval = (uint32_t)interval;
- return NoStepTime;
+ if (reprap.Debug(moduleMove))
+ {
+ stepInterval = (uint32_t)interval;
+ return NoStepTime;
+ }
}
-
- // If the step interval is very short, flag not to recalculate it next time
- if (interval < DDA::MinCalcInterval)
+ else if (interval < DDA::MinCalcInterval)
{
+ // If the step interval is very short, flag not to recalculate it next time
stepInterval = (uint32_t)interval;
stepsTillRecalc = DDA::MinCalcInterval/stepInterval + 1;
}
}
}
+
+ if (nextStepTime > dda.clocksNeeded)
+ {
+ // The calculation makes this step late.
+ // When the end speed is very low, calculating the time of the last step is very sensitive to rounding error.
+ // So if this is the last step and it is late, bring it forward to the expected finish time.
+ if (nextStep == totalSteps)
+ {
+ nextStepTime = dda.clocksNeeded;
+ }
+ else
+ {
+ // We don't expect any step except the last to be late
+ stepError = true;
+ if (reprap.Debug(moduleMove))
+ {
+ stepInterval = 10000000 + nextStepTime; // so we can tell what happened in debug
+ return NoStepTime;
+ }
+ }
+ }
+
return nextStepTime;
}
diff --git a/DriveMovement.h b/DriveMovement.h
index e3d8c1a1..05956f36 100644
--- a/DriveMovement.h
+++ b/DriveMovement.h
@@ -26,7 +26,7 @@ struct PrepParams
class DriveMovement
{
public:
- uint32_t CalcNextStepTimeCartesian(size_t drive);
+ uint32_t CalcNextStepTimeCartesian(const DDA &dda, size_t drive);
uint32_t CalcNextStepTimeDelta(const DDA &dda, size_t drive);
void PrepareCartesianAxis(const DDA& dda, const PrepParams& params, size_t drive);
void PrepareDeltaAxis(const DDA& dda, const PrepParams& params, size_t drive);
@@ -91,7 +91,7 @@ public:
static const uint32_t NoStepTime = 0xFFFFFFFF; // value to indicate that no further steps are needed when calculating the next step time
static const uint32_t K1 = 1024; // a power of 2 used to multiply the value mmPerStepTimesCdivtopSpeed to reduce rounding errors
static const uint32_t K2 = 512; // a power of 2 used in delta calculations to reduce rounding errors (but too large makes things worse)
- static const int32_t Kc = 4096; // a power of 2 for scaling the Z movement fraction
+ static const int32_t Kc = 1024 * 1024; // a power of 2 for scaling the Z movement fraction
};
#endif /* DRIVEMOVEMENT_H_ */
diff --git a/GCodes.cpp b/GCodes.cpp
index 0ebeb286..059d1ec3 100644
--- a/GCodes.cpp
+++ b/GCodes.cpp
@@ -1304,6 +1304,13 @@ void GCodes::GetCurrentCoordinates(StringRef& s) const
{
s.catf("E%u:%.1f ", i - AXES, liveCoordinates[i]);
}
+
+ // Print the stepper motor positions as Marlin does, as an aid to debugging
+ s.cat(" Count");
+ for (size_t i = 0; i < DRIVES; ++i)
+ {
+ s.catf(" %d", reprap.GetMove()->GetEndPoint(i));
+ }
}
bool GCodes::OpenFileToWrite(const char* directory, const char* fileName, GCodeBuffer *gb)
@@ -2785,6 +2792,11 @@ bool GCodes::HandleMcode(GCodeBuffer* gb, StringRef& reply)
else
{
tool = reprap.GetCurrentTool();
+ // If no tool is selected, and there is only one tool, set the active temperature for that one
+ if (tool == nullptr)
+ {
+ tool = reprap.GetOnlyTool();
+ }
}
SetToolHeaters(tool, temperature);
}
diff --git a/Move.cpp b/Move.cpp
index ca0af121..6679eca9 100644
--- a/Move.cpp
+++ b/Move.cpp
@@ -32,7 +32,7 @@ void Move::Init()
deltaProbing = false;
// Empty the ring
- ddaRingGetPointer = ddaRingAddPointer;
+ ddaRingGetPointer = ddaRingCheckPointer = ddaRingAddPointer;
DDA *dda = ddaRingAddPointer;
do
{
@@ -42,6 +42,7 @@ void Move::Init()
currentDda = nullptr;
addNoMoreMoves = false;
+ stepErrors = 0;
// Clear the transforms
SetIdentityTransform();
@@ -53,6 +54,7 @@ void Move::Init()
for (size_t i = 0; i < DRIVES; i++)
{
move[i] = 0.0;
+ liveEndPoints[i] = 0; // not actually right for a delta, but better than printing random values in response to M114
reprap.GetPlatform()->SetDirection(i, FORWARDS); // DC: I don't see any reason why we do this
}
SetLiveCoordinates(move);
@@ -104,14 +106,25 @@ void Move::Spin()
++idleCount;
}
+ // Check for DDA errors to print if Move debug is enabled
+ while (ddaRingCheckPointer->GetState() == DDA::completed)
+ {
+ if (ddaRingCheckPointer->HasStepError())
+ {
+ if (reprap.Debug(moduleMove))
+ {
+ ddaRingCheckPointer->DebugPrint();
+ }
+ ++stepErrors;
+ }
+ ddaRingCheckPointer->Free();
+ ddaRingCheckPointer = ddaRingCheckPointer->GetNext();
+ }
+
// See if we can add another move to the ring
if (!addNoMoreMoves && ddaRingAddPointer->GetState() == DDA::empty)
{
DDA *dda = ddaRingAddPointer;
- if (reprap.Debug(moduleMove))
- {
- dda->PrintIfHasStepError();
- }
// In order to react faster to speed and extrusion rate changes, only add more moves if the total duration of
// all un-frozen moves is less than 2 seconds, or the total duration of all but the first un-frozen move is
@@ -197,7 +210,7 @@ void Move::Spin()
DDA *dda = ddaRingGetPointer;
simulationTime += dda->CalcTime();
liveCoordinatesValid = dda->FetchEndPosition(const_cast<int32_t*>(liveEndPoints), const_cast<float *>(liveCoordinates));
- dda->Release();
+ dda->Complete();
ddaRingGetPointer = ddaRingGetPointer->GetNext();
}
}
@@ -333,7 +346,7 @@ FilePosition Move::PausePrint(float positions[DRIVES+1])
{
fPos = dda->GetFilePosition();
}
- dda->Release();
+ dda->Complete();
dda = dda->GetNext();
}
while (dda != savedDdaRingAddPointer);
@@ -356,7 +369,7 @@ extern uint64_t lastNum;
void Move::Diagnostics()
{
reprap.GetPlatform()->AppendMessage(BOTH_MESSAGE, "Move Diagnostics:\n");
- reprap.GetPlatform()->AppendMessage(BOTH_MESSAGE, "MaxReps: %u\n", maxReps);
+ reprap.GetPlatform()->AppendMessage(BOTH_MESSAGE, "MaxReps: %u, StepErrors: %u\n", maxReps, stepErrors);
maxReps = 0;
#if 0
@@ -1086,7 +1099,7 @@ void Move::CurrentMoveCompleted()
// Save the current motor coordinates, and the machine Cartesian coordinates if known
liveCoordinatesValid = currentDda->FetchEndPosition(const_cast<int32_t*>(liveEndPoints), const_cast<float *>(liveCoordinates));
- currentDda->Release();
+ currentDda->Complete();
currentDda = nullptr;
ddaRingGetPointer = ddaRingGetPointer->GetNext();
}
diff --git a/Move.h b/Move.h
index edc5dde3..188e6aa6 100644
--- a/Move.h
+++ b/Move.h
@@ -37,6 +37,7 @@ public:
void Spin(); // Called in a tight loop to keep the class going
void Exit(); // Shut down
void GetCurrentUserPosition(float m[DRIVES + 1], uint8_t moveType) const; // Return the position (after all queued moves have been executed) in transformed coords
+ int32_t GetEndPoint(size_t drive) const { return liveEndPoints[drive]; } // Get the current position of a motor
void LiveCoordinates(float m[DRIVES]); // Gives the last point at the end of the last complete DDA transformed to user coords
void Interrupt(); // The hardware's (i.e. platform's) interrupt should call this.
void InterruptTime(); // Test function - not used
@@ -123,6 +124,7 @@ private:
DDA* volatile currentDda;
DDA* ddaRingAddPointer;
DDA* volatile ddaRingGetPointer;
+ DDA* ddaRingCheckPointer;
bool addNoMoreMoves; // If true, allow no more moves to be added to the look-ahead
bool active; // Are we live and running?
@@ -156,6 +158,7 @@ private:
uint32_t deltaProbingStartTime;
bool deltaProbing;
int coreXYMode; // 0 = Cartesian, 1 = CoreXY, 2 = CoreXZ, 3 = CoreYZ
+ unsigned int stepErrors; // count of step errors, for diagnostics
};
//******************************************************************************************************
diff --git a/Platform.cpp b/Platform.cpp
index 4cf1e732..99e5bde7 100644
--- a/Platform.cpp
+++ b/Platform.cpp
@@ -568,7 +568,7 @@ bool Platform::MustHomeXYBeforeZ() const
void Platform::ResetNvData()
{
- nvData.compatibility = me;
+ nvData.compatibility = marlin; // default to Marlin because the common host programs expect the "OK" response to commands
ARRAY_INIT(nvData.ipAddress, IP_ADDRESS);
ARRAY_INIT(nvData.netMask, NET_MASK);
ARRAY_INIT(nvData.gateWay, GATE_WAY);
@@ -740,13 +740,49 @@ void Platform::Spin()
ClassReport(longWait);
}
+// Switch into boot mode and reset
+#if 1 // trying the Arduino code to see if it is more reliable
+
+__attribute__ ((long_call, section (".ramfunc")))
+void eraseAndReset() {
+ cpu_irq_disable();
+
+ // Set boot flag to run SAM-BA bootloader at restart
+ const int EEFC_FCMD_CGPB = 0x0C;
+ const int EEFC_KEY = 0x5A;
+ while ((EFC0->EEFC_FSR & EEFC_FSR_FRDY) == 0);
+ EFC0->EEFC_FCR =
+ EEFC_FCR_FCMD(EEFC_FCMD_CGPB) |
+ EEFC_FCR_FARG(1) |
+ EEFC_FCR_FKEY(EEFC_KEY);
+ while ((EFC0->EEFC_FSR & EEFC_FSR_FRDY) == 0);
+
+ // From here flash memory is no more available.
+ const int RSTC_KEY = 0xA5;
+ RSTC->RSTC_CR =
+ RSTC_CR_KEY(RSTC_KEY) |
+ RSTC_CR_PROCRST |
+ RSTC_CR_PERRST;
+
+ while (true);
+}
+
+#else
+
+void eraseAndReset()
+{
+ cpu_irq_disable();
+ flash_unlock(0x00080000, 0x000FFFFF, nullptr, nullptr);
+ flash_clear_gpnvm(1); // tell the system to boot from flash next time
+}
+
+#endif
+
void Platform::SoftwareReset(uint16_t reason)
{
if (reason == SoftwareResetReason::erase)
{
- cpu_irq_disable();
- flash_unlock(0x00080000, 0x000FFFFF, nullptr, nullptr);
- flash_clear_gpnvm(1); // tell the system to boot from flash next time
+ eraseAndReset();
}
else
{
@@ -789,6 +825,7 @@ void Platform::SoftwareReset(uint16_t reason)
for(;;) {}
}
+
//*****************************************************************************************************************
// Interrupts
@@ -823,6 +860,9 @@ void FanInterrupt()
void Platform::InitialiseInterrupts()
{
+ // Set the tick interrupt to the highest priority. We need to to monitor the heaters and kick the watchdog.
+ NVIC_SetPriority (SysTick_IRQn, 0); // set priority for tick interrupts
+
// Timer interrupt for stepper motors
// The clock rate we use is a compromise. Too fast and the 64-bit square roots take a long time to execute. Too slow and we lose resolution.
// We choose a clock divisor of 32, which gives us 0.38us resolution. The next option is 128 which would give 1.524us resolution.
@@ -832,7 +872,7 @@ void Platform::InitialiseInterrupts()
TC1 ->TC_CHANNEL[0].TC_IDR = ~(uint32_t)0; // interrupts disabled for now
TC_Start(TC1, 0);
TC_GetStatus(TC1, 0); // clear any pending interrupt
- NVIC_SetPriority(TC3_IRQn, 0); // set highest priority for this IRQ; it's time-critical
+ NVIC_SetPriority(TC3_IRQn, 2); // set high priority for this IRQ; it's time-critical
NVIC_EnableIRQ(TC3_IRQn);
// Timer interrupt to keep the networking timers running (called at 16Hz)
@@ -844,7 +884,7 @@ void Platform::InitialiseInterrupts()
TC_Start(TC1, 1);
TC1 ->TC_CHANNEL[1].TC_IER = TC_IER_CPCS;
TC1 ->TC_CHANNEL[1].TC_IDR = ~TC_IER_CPCS;
- NVIC_SetPriority(TC4_IRQn, 4); // step interrupt is time-critical
+ NVIC_SetPriority(TC4_IRQn, 4); // step interrupt is more time-critical than this one
NVIC_EnableIRQ(TC4_IRQn);
// Interrupt for 4-pin PWM fan sense line
diff --git a/Release/RepRapFirmware-1.09f-testing-dc42.bin b/Release/RepRapFirmware-1.09f-testing-dc42.bin
new file mode 100644
index 00000000..6804cb7e
--- /dev/null
+++ b/Release/RepRapFirmware-1.09f-testing-dc42.bin
Binary files differ
diff --git a/RepRapFirmware.cpp b/RepRapFirmware.cpp
index c42cd35a..954b7c44 100644
--- a/RepRapFirmware.cpp
+++ b/RepRapFirmware.cpp
@@ -427,11 +427,19 @@ void RepRap::PrintDebug()
if (debug != 0)
{
platform->Message(BOTH_MESSAGE, "Debugging enabled for modules:");
- for(uint8_t i=0; i<16;i++)
+ for (unsigned int i = 0; i < numModules; i++)
{
- if (debug & (1 << i))
+ if ((debug & (1 << i)) != 0)
{
- platform->AppendMessage(BOTH_MESSAGE, " %s", moduleName[i]);
+ platform->AppendMessage(BOTH_MESSAGE, " %s(%u)", moduleName[i], i);
+ }
+ }
+ platform->Message(BOTH_MESSAGE, "\nDebugging disabled for modules:");
+ for (unsigned int i = 0; i < numModules; i++)
+ {
+ if ((debug & (1 << i)) == 0)
+ {
+ platform->AppendMessage(BOTH_MESSAGE, " %s(%u)", moduleName[i], i);
}
}
platform->AppendMessage(BOTH_MESSAGE, "\n");
@@ -565,7 +573,7 @@ void RepRap::StandbyTool(int toolNumber)
platform->Message(BOTH_MESSAGE, "Attempt to standby a non-existent tool: %d.\n", toolNumber);
}
-Tool* RepRap::GetTool(int toolNumber)
+Tool* RepRap::GetTool(int toolNumber) const
{
Tool* tool = toolList;
@@ -580,6 +588,11 @@ Tool* RepRap::GetTool(int toolNumber)
return NULL; // Not an error
}
+Tool* RepRap::GetOnlyTool() const
+{
+ return (toolList != nullptr && toolList->Next() == nullptr) ? toolList : nullptr;
+}
+
#if 0 // not used
Tool* RepRap::GetToolByDrive(int driveNumber)
{
@@ -1573,7 +1586,7 @@ size_t StringRef::cat(const char* src)
// Utilities and storage not part of any class
-static char scratchStringBuffer[100]; // this is now used only for short messages
+static char scratchStringBuffer[120]; // this is now used only for short messages; needs to be long enough to print delta parameters
StringRef scratchString(scratchStringBuffer, ARRAY_SIZE(scratchStringBuffer));
// For debug use
diff --git a/RepRapFirmware.h b/RepRapFirmware.h
index 897f38da..a332f97d 100644
--- a/RepRapFirmware.h
+++ b/RepRapFirmware.h
@@ -37,6 +37,7 @@ enum Module
moduleHeat = 5,
moduleDda = 6,
modulePrintMonitor = 7,
+ numModules = 8, // make this one greater than the last module number
noModule = 15
};
diff --git a/Reprap.h b/Reprap.h
index 60890b22..e56b18db 100644
--- a/Reprap.h
+++ b/Reprap.h
@@ -52,8 +52,9 @@ class RepRap
void DeleteTool(Tool* t);
void SelectTool(int toolNumber);
void StandbyTool(int toolNumber);
- Tool* GetCurrentTool();
- Tool* GetTool(int toolNumber);
+ Tool* GetCurrentTool() const;
+ Tool* GetTool(int toolNumber) const;
+ Tool* GetOnlyTool() const;
//Tool* GetToolByDrive(int driveNumber);
void SetToolVariables(int toolNumber, float* standbyTemperatures, float* activeTemperatures);
@@ -151,7 +152,7 @@ inline PrintMonitor* RepRap::GetPrintMonitor() const { return printMonitor; }
inline bool RepRap::Debug(Module m) const { return debug & (1 << m); }
inline Module RepRap::GetSpinningModule() const { return spinningModule; }
-inline Tool* RepRap::GetCurrentTool() { return currentTool; }
+inline Tool* RepRap::GetCurrentTool() const { return currentTool; }
inline uint16_t RepRap::GetExtrudersInUse() const { return activeExtruders; }
inline uint16_t RepRap::GetHeatersInUse() const { return activeHeaters; }
inline bool RepRap::ColdExtrude() const { return coldExtrude; }
diff --git a/SD-image/sys-CoreXY/pause.g b/SD-image/sys-CoreXY/pause.g
index b098f19f..67f7cac7 100644
--- a/SD-image/sys-CoreXY/pause.g
+++ b/SD-image/sys-CoreXY/pause.g
@@ -1,4 +1,5 @@
; Pause macro file
+M83 ; relative extruder moves
G1 E-4 F2500 ; retract 4mm
G91 ; relative moves
G1 Z5 F5000 ; raise nozzle 2mm
diff --git a/SD-image/sys-CoreXY/resume.g b/SD-image/sys-CoreXY/resume.g
index 49e46853..152f5e80 100644
--- a/SD-image/sys-CoreXY/resume.g
+++ b/SD-image/sys-CoreXY/resume.g
@@ -1,4 +1,5 @@
; Resume macro file
G1 R1 Z2 F5000 ; move to 2mm above resume point
G1 R1 ; lower nozzle to resume point
+M83 ; relative extruder moves
G1 E4 F2500 ; undo the retraction \ No newline at end of file
diff --git a/SD-image/sys-Huxley/pause.g b/SD-image/sys-Huxley/pause.g
index 70c11cb5..b6d3af0d 100644
--- a/SD-image/sys-Huxley/pause.g
+++ b/SD-image/sys-Huxley/pause.g
@@ -1,4 +1,5 @@
; Pause macro file
+M83 ; relative extruder moves
G1 E-4 F2500 ; retract 4mm
G91 ; relative moves
G1 Z2 F5000 ; raise nozzle 2mm
diff --git a/SD-image/sys-Huxley/resume.g b/SD-image/sys-Huxley/resume.g
index 49e46853..152f5e80 100644
--- a/SD-image/sys-Huxley/resume.g
+++ b/SD-image/sys-Huxley/resume.g
@@ -1,4 +1,5 @@
; Resume macro file
G1 R1 Z2 F5000 ; move to 2mm above resume point
G1 R1 ; lower nozzle to resume point
+M83 ; relative extruder moves
G1 E4 F2500 ; undo the retraction \ No newline at end of file
diff --git a/SD-image/sys-MiniKossel/homedelta.g b/SD-image/sys-MiniKossel/homedelta.g
index d889e51d..34b294d8 100644
--- a/SD-image/sys-MiniKossel/homedelta.g
+++ b/SD-image/sys-MiniKossel/homedelta.g
@@ -1,8 +1,8 @@
; Homing file for RepRapFirmware on Mini Kossel
G91 ; use relative positioning
-;******* Change F500 in the following line by F5000 when you are finished commissioning
+;******* Change F300 in the following line to F3000 when you are finished commissioning
;******* Change 320 in the following to a higher value if your Kossel has taller towers
-G1 S1 X320 Y320 Z320 F500 ; move all carriages up 320mm, stopping at the endstops
+G1 S1 X320 Y320 Z320 F300 ; move all carriages up 320mm, stopping at the endstops
G1 S2 X-3 Y-3 Z-3 ; move all carriages down 3mm
G1 S1 X6 Y6 Z6 F250 ; move carriages slowly up 6mm, stopping at the endstops
G1 Z-5 F2000 ; down a few mm so that we can centre the head
diff --git a/SD-image/sys-MiniKossel/pause.g b/SD-image/sys-MiniKossel/pause.g
index 18855ff7..0cb1d1f9 100644
--- a/SD-image/sys-MiniKossel/pause.g
+++ b/SD-image/sys-MiniKossel/pause.g
@@ -1,4 +1,5 @@
; Pause macro file
+M83 ; relative extruder moves
G1 E-4 F2500 ; retract 4mm
G91 ; relative moves
G1 Z5 F5000 ; raise nozzle 2mm
diff --git a/SD-image/sys-MiniKossel/resume.g b/SD-image/sys-MiniKossel/resume.g
index 49e46853..152f5e80 100644
--- a/SD-image/sys-MiniKossel/resume.g
+++ b/SD-image/sys-MiniKossel/resume.g
@@ -1,4 +1,5 @@
; Resume macro file
G1 R1 Z2 F5000 ; move to 2mm above resume point
G1 R1 ; lower nozzle to resume point
+M83 ; relative extruder moves
G1 E4 F2500 ; undo the retraction \ No newline at end of file
diff --git a/SD-image/sys-Ormerod1/pause.g b/SD-image/sys-Ormerod1/pause.g
index b098f19f..67f7cac7 100644
--- a/SD-image/sys-Ormerod1/pause.g
+++ b/SD-image/sys-Ormerod1/pause.g
@@ -1,4 +1,5 @@
; Pause macro file
+M83 ; relative extruder moves
G1 E-4 F2500 ; retract 4mm
G91 ; relative moves
G1 Z5 F5000 ; raise nozzle 2mm
diff --git a/SD-image/sys-Ormerod1/resume.g b/SD-image/sys-Ormerod1/resume.g
index 49e46853..152f5e80 100644
--- a/SD-image/sys-Ormerod1/resume.g
+++ b/SD-image/sys-Ormerod1/resume.g
@@ -1,4 +1,5 @@
; Resume macro file
G1 R1 Z2 F5000 ; move to 2mm above resume point
G1 R1 ; lower nozzle to resume point
+M83 ; relative extruder moves
G1 E4 F2500 ; undo the retraction \ No newline at end of file
diff --git a/SD-image/sys-Ormerod2/pause.g b/SD-image/sys-Ormerod2/pause.g
index b098f19f..67f7cac7 100644
--- a/SD-image/sys-Ormerod2/pause.g
+++ b/SD-image/sys-Ormerod2/pause.g
@@ -1,4 +1,5 @@
; Pause macro file
+M83 ; relative extruder moves
G1 E-4 F2500 ; retract 4mm
G91 ; relative moves
G1 Z5 F5000 ; raise nozzle 2mm
diff --git a/SD-image/sys-Ormerod2/resume.g b/SD-image/sys-Ormerod2/resume.g
index 49e46853..152f5e80 100644
--- a/SD-image/sys-Ormerod2/resume.g
+++ b/SD-image/sys-Ormerod2/resume.g
@@ -1,4 +1,5 @@
; Resume macro file
G1 R1 Z2 F5000 ; move to 2mm above resume point
G1 R1 ; lower nozzle to resume point
+M83 ; relative extruder moves
G1 E4 F2500 ; undo the retraction \ No newline at end of file
diff --git a/Webserver.cpp b/Webserver.cpp
index 45b9a3da..1ed8249f 100644
--- a/Webserver.cpp
+++ b/Webserver.cpp
@@ -946,6 +946,7 @@ bool Webserver::HttpInterpreter::GetJsonResponse(const char* request, StringRef&
{
// This is only possible if we have at least one HTTP session left
response.copy("{\"err\":0}");
+
}
else
{
@@ -958,6 +959,8 @@ bool Webserver::HttpInterpreter::GetJsonResponse(const char* request, StringRef&
// Wrong password
response.copy("{\"err\":1}");
}
+
+ CancelUpload(); // if a file upload was in progress from this IP address, cancel it
}
else if (!IsAuthenticated())
{