Version 1.09a
Merged in zpl's latest changes to Network and Print Monitor modules, providing DHCP and Netbios name support Added command M999 S4321 to unlock flash memory, reset and boot to BOSSA port Z dive height is now relative to Z probe trigger height and default is reduced to 3mm Added experimental support for acoustic probe for delta printers Bug fix: firmware once again prevents Z homing before X and Y are homed, if the Z probe is used for Z homing Various code tidying
This commit is contained in:
parent
7d11c9e217
commit
4cc0a512b4
26 changed files with 1285 additions and 542 deletions
|
@ -24,8 +24,8 @@ Licence: GPL
|
|||
#define CONFIGURATION_H
|
||||
|
||||
#define NAME "RepRapFirmware"
|
||||
#define VERSION "1.04g-dc42"
|
||||
#define DATE "2015-04-20"
|
||||
#define VERSION "1.09a-dc42"
|
||||
#define DATE "2015-05-17"
|
||||
#define AUTHORS "reprappro, dc42, zpl"
|
||||
|
||||
#define FLASH_SAVE_ENABLED (1)
|
||||
|
@ -77,7 +77,7 @@ const float DefaultFeedRate = 3000; // The initial requested feed rate after
|
|||
const size_t MaxProbePoints = 16; // Maximum number of probe points
|
||||
const size_t MaxDeltaCalibrationPoints = 16; // Must be <= MaxProbePoints, may be smaller to reduce matrix storage requirements. Preferably a power of 2.
|
||||
|
||||
const float DefaultZDive = 5.0; // Default height from which to probe the bed (mm)
|
||||
const float DefaultZDive = 3.0; // Default height from which to probe the bed (mm)
|
||||
|
||||
#define TRIANGLE_0 -0.001 // Slightly less than 0 for point-in-triangle tests
|
||||
|
||||
|
|
10
DDA.cpp
10
DDA.cpp
|
@ -730,12 +730,12 @@ bool DDA::Step()
|
|||
// because we have both a high endstop and a Z probe, and the Z motor is not the same thing as the Z axis.
|
||||
switch (reprap.GetPlatform()->GetZProbeResult())
|
||||
{
|
||||
case lowHit:
|
||||
case EndStopHit::lowHit:
|
||||
MoveAborted(now); // set the state to completed and recalculate the endpoints
|
||||
reprap.GetMove()->ZProbeTriggered(this);
|
||||
break;
|
||||
|
||||
case lowNear:
|
||||
case EndStopHit::lowNear:
|
||||
ReduceHomingSpeed(reprap.GetPlatform()->ConfiguredInstantDv(Z_AXIS));
|
||||
break;
|
||||
|
||||
|
@ -757,7 +757,7 @@ bool DDA::Step()
|
|||
{
|
||||
switch(reprap.GetPlatform()->Stopped(drive))
|
||||
{
|
||||
case lowHit:
|
||||
case EndStopHit::lowHit:
|
||||
endStopsToCheck &= ~(1 << drive); // clear this check so that we can check for more
|
||||
if (endStopsToCheck == 0) // if no more endstops to check
|
||||
{
|
||||
|
@ -770,7 +770,7 @@ bool DDA::Step()
|
|||
reprap.GetMove()->HitLowStop(drive, this);
|
||||
break;
|
||||
|
||||
case highHit:
|
||||
case EndStopHit::highHit:
|
||||
endStopsToCheck &= ~(1 << drive); // clear this check so that we can check for more
|
||||
if (endStopsToCheck == 0) // if no more endstops to check
|
||||
{
|
||||
|
@ -783,7 +783,7 @@ bool DDA::Step()
|
|||
reprap.GetMove()->HitHighStop(drive, this);
|
||||
break;
|
||||
|
||||
case lowNear:
|
||||
case EndStopHit::lowNear:
|
||||
// Only reduce homing speed if there are no more axes to be homed.
|
||||
// This allows us to home X and Y simultaneously.
|
||||
if (endStopsToCheck == (1 << drive))
|
||||
|
|
248
DeltaParameters.cpp
Normal file
248
DeltaParameters.cpp
Normal file
|
@ -0,0 +1,248 @@
|
|||
/*
|
||||
* DeltaParameters.cpp
|
||||
*
|
||||
* Created on: 20 Apr 2015
|
||||
* Author: David
|
||||
*/
|
||||
|
||||
#include "RepRapFirmware.h"
|
||||
|
||||
void DeltaParameters::Init()
|
||||
{
|
||||
deltaMode = false;
|
||||
diagonal = 0.0;
|
||||
radius = 0.0;
|
||||
printRadius = defaultPrintRadius;
|
||||
homedHeight = defaultDeltaHomedHeight;
|
||||
isEquilateral = true;
|
||||
|
||||
for (size_t axis = 0; axis < AXES; ++axis)
|
||||
{
|
||||
endstopAdjustments[axis] = 0.0;
|
||||
towerX[axis] = towerY[axis] = 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
void DeltaParameters::SetRadius(float r)
|
||||
{
|
||||
radius = r;
|
||||
isEquilateral = true;
|
||||
|
||||
const float cos30 = sqrtf(3.0)/2.0;
|
||||
const float sin30 = 0.5;
|
||||
|
||||
towerX[A_AXIS] = -(r * cos30);
|
||||
towerX[B_AXIS] = r * cos30;
|
||||
towerX[C_AXIS] = 0.0;
|
||||
|
||||
towerY[A_AXIS] = towerY[B_AXIS] = -(r * sin30);
|
||||
towerY[C_AXIS] = r;
|
||||
|
||||
Recalc();
|
||||
}
|
||||
|
||||
void DeltaParameters::Recalc()
|
||||
{
|
||||
deltaMode = (radius > 0.0 && diagonal > radius);
|
||||
if (deltaMode)
|
||||
{
|
||||
Xbc = towerX[C_AXIS] - towerX[B_AXIS];
|
||||
Xca = towerX[A_AXIS] - towerX[C_AXIS];
|
||||
Xab = towerX[B_AXIS] - towerX[A_AXIS];
|
||||
Ybc = towerY[C_AXIS] - towerY[B_AXIS];
|
||||
Yca = towerY[A_AXIS] - towerY[C_AXIS];
|
||||
Yab = towerY[B_AXIS] - towerY[A_AXIS];
|
||||
coreFa = fsquare(towerX[A_AXIS]) + fsquare(towerY[A_AXIS]);
|
||||
coreFb = fsquare(towerX[B_AXIS]) + fsquare(towerY[B_AXIS]);
|
||||
coreFc = fsquare(towerX[C_AXIS]) + fsquare(towerY[C_AXIS]);
|
||||
Q = 2 * (Xca * Yab - Xab * Yca);
|
||||
Q2 = fsquare(Q);
|
||||
D2 = fsquare(diagonal);
|
||||
|
||||
// Calculate the base carriage height when the printer is homed.
|
||||
const float tempHeight = diagonal; // any sensible height will do here, probably even zero
|
||||
float machinePos[AXES];
|
||||
InverseTransform(tempHeight + endstopAdjustments[X_AXIS], tempHeight + endstopAdjustments[Y_AXIS], tempHeight + endstopAdjustments[X_AXIS],
|
||||
machinePos);
|
||||
homedCarriageHeight = homedHeight + tempHeight - machinePos[Z_AXIS];
|
||||
}
|
||||
}
|
||||
|
||||
// Make the average of the endstop adjustments zero, without changing the individual homed carriage heights
|
||||
void DeltaParameters::NormaliseEndstopAdjustments()
|
||||
{
|
||||
const float eav = (endstopAdjustments[A_AXIS] + endstopAdjustments[B_AXIS] + endstopAdjustments[C_AXIS])/3.0;
|
||||
endstopAdjustments[A_AXIS] -= eav;
|
||||
endstopAdjustments[B_AXIS] -= eav;
|
||||
endstopAdjustments[C_AXIS] -= eav;
|
||||
homedHeight += eav;
|
||||
homedCarriageHeight += eav; // no need for a full recalc, this is sufficient
|
||||
}
|
||||
|
||||
// Calculate the motor position for a single tower from a Cartesian coordinate
|
||||
float DeltaParameters::Transform(const float machinePos[AXES], size_t axis) const
|
||||
{
|
||||
return machinePos[Z_AXIS]
|
||||
+ sqrt(D2 - fsquare(machinePos[X_AXIS] - towerX[axis]) - fsquare(machinePos[Y_AXIS] - towerY[axis]));
|
||||
}
|
||||
|
||||
void DeltaParameters::InverseTransform(float Ha, float Hb, float Hc, float machinePos[AXES]) const
|
||||
{
|
||||
const float Fa = coreFa + fsquare(Ha);
|
||||
const float Fb = coreFb + fsquare(Hb);
|
||||
const float Fc = coreFc + fsquare(Hc);
|
||||
|
||||
// debugPrintf("Ha=%f Hb=%f Hc=%f Fa=%f Fb=%f Fc=%f Xbc=%f Xca=%f Xab=%f Ybc=%f Yca=%f Yab=%f\n",
|
||||
// Ha, Hb, Hc, Fa, Fb, Fc, Xbc, Xca, Xab, Ybc, Yca, Yab);
|
||||
|
||||
// Setup PQRSU such that x = -(S - uz)/P, y = (P - Rz)/Q
|
||||
const float P = (Xbc * Fa) + (Xca * Fb) + (Xab * Fc);
|
||||
const float S = (Ybc * Fa) + (Yca * Fb) + (Yab * Fc);
|
||||
|
||||
const float R = 2 * ((Xbc * Ha) + (Xca * Hb) + (Xab * Hc));
|
||||
const float U = 2 * ((Ybc * Ha) + (Yca * Hb) + (Yab * Hc));
|
||||
|
||||
// debugPrintf("P= %f R=%f S=%f U=%f Q=%f\n", P, R, S, U, Q);
|
||||
|
||||
const float R2 = fsquare(R), U2 = fsquare(U);
|
||||
|
||||
float A = U2 + R2 + Q2;
|
||||
float minusHalfB = S * U + P * R + Ha * Q2 + towerX[A_AXIS] * U * Q - towerY[A_AXIS] * R * Q;
|
||||
float C = fsquare(S + towerX[A_AXIS] * Q) + fsquare(P - towerY[A_AXIS] * Q) + (fsquare(Ha) - D2) * Q2;
|
||||
|
||||
// debugPrintf("A=%f minusHalfB=%f C=%f\n", A, minusHalfB, C);
|
||||
|
||||
float z = (minusHalfB - sqrtf(fsquare(minusHalfB) - A * C)) / A;
|
||||
machinePos[X_AXIS] = (U * z - S) / Q;
|
||||
machinePos[Y_AXIS] = (P - R * z) / Q;
|
||||
machinePos[Z_AXIS] = z;
|
||||
}
|
||||
|
||||
// Compute the derivative of height with respect to a parameter at the specified motor endpoints.
|
||||
// 'deriv' indicates the parameter as follows:
|
||||
// 0, 1, 2 = X, Y, Z tower endstop adjustments
|
||||
// 3, 4 = X, Y tower X position
|
||||
// 5 = Z tower Y position
|
||||
// 6 = diagonal rod length
|
||||
// 7 = delta radius (only if isEquilateral is true)
|
||||
float DeltaParameters::ComputeDerivative(unsigned int deriv, float ha, float hb, float hc)
|
||||
{
|
||||
const float perturb = 0.2; // perturbation amount in mm
|
||||
DeltaParameters hiParams(*this), loParams(*this);
|
||||
switch(deriv)
|
||||
{
|
||||
case 0:
|
||||
case 1:
|
||||
case 2:
|
||||
break;
|
||||
|
||||
case 3:
|
||||
case 4:
|
||||
hiParams.towerX[deriv - 3] += perturb;
|
||||
loParams.towerX[deriv - 3] -= perturb;
|
||||
break;
|
||||
|
||||
case 5:
|
||||
{
|
||||
const float yAdj = perturb * (1.0/3.0);
|
||||
hiParams.towerY[A_AXIS] -= yAdj;
|
||||
hiParams.towerY[B_AXIS] -= yAdj;
|
||||
hiParams.towerY[C_AXIS] += (perturb - yAdj);
|
||||
loParams.towerY[A_AXIS] += yAdj;
|
||||
loParams.towerY[B_AXIS] += yAdj;
|
||||
loParams.towerY[C_AXIS] -= (perturb - yAdj);
|
||||
}
|
||||
break;
|
||||
|
||||
case 6:
|
||||
hiParams.diagonal += perturb;
|
||||
loParams.diagonal -= perturb;
|
||||
break;
|
||||
|
||||
case 7:
|
||||
hiParams.SetRadius(radius + perturb);
|
||||
loParams.SetRadius(radius - perturb);
|
||||
break;
|
||||
}
|
||||
|
||||
hiParams.Recalc();
|
||||
loParams.Recalc();
|
||||
|
||||
float newPos[AXES];
|
||||
hiParams.InverseTransform((deriv == 0) ? ha + perturb : ha, (deriv == 1) ? hb + perturb : hb, (deriv == 2) ? hc + perturb : hc, newPos);
|
||||
float zHi = newPos[Z_AXIS];
|
||||
loParams.InverseTransform((deriv == 0) ? ha - perturb : ha, (deriv == 1) ? hb - perturb : hb, (deriv == 2) ? hc - perturb : hc, newPos);
|
||||
float zLo = newPos[Z_AXIS];
|
||||
|
||||
return (zHi - zLo)/(2 * perturb);
|
||||
}
|
||||
|
||||
// Perform 3, 4, 6 or 7-factor adjustment.
|
||||
// The input vector contains the following parameters in this order:
|
||||
// X, Y and Z endstop adjustments
|
||||
// If we are doing 4-factor adjustment, the next argument is the delta radius. Otherwise:
|
||||
// X tower X position adjustment
|
||||
// Y tower X position adjustment
|
||||
// Z tower Y position adjustment
|
||||
// Diagonal rod length adjustment
|
||||
void DeltaParameters::Adjust(size_t numFactors, const float v[])
|
||||
{
|
||||
const float oldCarriageHeightA = GetHomedCarriageHeight(A_AXIS); // save for later
|
||||
|
||||
// Update endstop adjustments
|
||||
endstopAdjustments[A_AXIS] += v[0];
|
||||
endstopAdjustments[B_AXIS] += v[1];
|
||||
endstopAdjustments[C_AXIS] += v[2];
|
||||
NormaliseEndstopAdjustments();
|
||||
|
||||
if (numFactors == 4)
|
||||
{
|
||||
// 4-factor adjustment, so update delta radius
|
||||
SetRadius(radius + v[3]); // this sets isEquilateral true, recalculates tower positions, then calls Recalc()
|
||||
}
|
||||
else if (numFactors > 3)
|
||||
{
|
||||
// 6- or 7-factor adjustment
|
||||
towerX[A_AXIS] += v[3];
|
||||
towerX[B_AXIS] += v[4];
|
||||
|
||||
const float yAdj = v[5] * (1.0/3.0);
|
||||
towerY[A_AXIS] -= yAdj;
|
||||
towerY[B_AXIS] -= yAdj;
|
||||
towerY[C_AXIS] += (v[5] - yAdj);
|
||||
isEquilateral = false;
|
||||
|
||||
if (numFactors == 7)
|
||||
{
|
||||
diagonal += v[6];
|
||||
}
|
||||
|
||||
Recalc();
|
||||
}
|
||||
|
||||
// Adjusting the diagonal and the tower positions affects the homed carriage height.
|
||||
// We need to adjust homedHeight to allow for this, to get the change that was requested in the endstop corrections.
|
||||
const float heightError = GetHomedCarriageHeight(A_AXIS) - oldCarriageHeightA - v[0];
|
||||
homedHeight -= heightError;
|
||||
homedCarriageHeight -= heightError;
|
||||
}
|
||||
|
||||
void DeltaParameters::PrintParameters(StringRef& reply, bool full)
|
||||
{
|
||||
reply.printf("Endstops X%.2f Y%.2f Z%.2f, height %.2f, diagonal %.2f, ",
|
||||
endstopAdjustments[A_AXIS], endstopAdjustments[B_AXIS], endstopAdjustments[C_AXIS], homedHeight, diagonal);
|
||||
if (isEquilateral && !full)
|
||||
{
|
||||
reply.catf("radius %.2f\n", radius);
|
||||
}
|
||||
else
|
||||
{
|
||||
reply.catf("towers (%.2f,%.2f) (%.2f,%.2f) (%.2f,%.2f)\n",
|
||||
towerX[A_AXIS], towerY[A_AXIS], towerX[B_AXIS], towerY[B_AXIS], towerX[C_AXIS], towerY[C_AXIS]);
|
||||
}
|
||||
}
|
||||
|
||||
// End
|
||||
|
||||
|
||||
|
67
DeltaParameters.h
Normal file
67
DeltaParameters.h
Normal file
|
@ -0,0 +1,67 @@
|
|||
/*
|
||||
* DeltaParameters.h
|
||||
*
|
||||
* Created on: 20 Apr 2015
|
||||
* Author: David
|
||||
*/
|
||||
|
||||
#ifndef DELTAPARAMETERS_H_
|
||||
#define DELTAPARAMETERS_H_
|
||||
|
||||
// Class to hold the parameter for a delta machine.
|
||||
// Some of the values that are currently calculated on demand could be pre-calculated in Recalc() and stored instead.
|
||||
class DeltaParameters
|
||||
{
|
||||
public:
|
||||
DeltaParameters() { Init(); }
|
||||
|
||||
bool IsDeltaMode() const { return deltaMode; }
|
||||
bool IsEquilateral() const { return isEquilateral; }
|
||||
float GetDiagonal() const { return diagonal; }
|
||||
float GetRadius() const { return radius; }
|
||||
float GetPrintRadius() const { return printRadius; }
|
||||
float GetTowerX(size_t axis) const { return towerX[axis]; }
|
||||
float GetTowerY(size_t axis) const { return towerY[axis]; }
|
||||
float GetEndstopAdjustment(size_t axis) const { return endstopAdjustments[axis]; }
|
||||
float GetHomedCarriageHeight(size_t axis) const { return homedCarriageHeight + endstopAdjustments[axis]; }
|
||||
float GetPrintRadiusSquared() const { return printRadiusSquared; }
|
||||
|
||||
void Init();
|
||||
void SetDiagonal(float d) { diagonal = d; Recalc(); }
|
||||
void SetRadius(float r);
|
||||
void SetEndstopAdjustment(size_t axis, float x) { endstopAdjustments[axis] = x; }
|
||||
void SetPrintRadius(float r) { printRadius = r; printRadiusSquared = r * r; }
|
||||
float GetHomedHeight() const { return homedHeight; }
|
||||
void SetHomedHeight(float h) { homedHeight = h; Recalc(); }
|
||||
|
||||
float Transform(const float machinePos[AXES], size_t axis) const; // Calculate the motor position for a single tower from a Cartesian coordinate
|
||||
void InverseTransform(float Ha, float Hb, float Hc, float machinePos[AXES]) const; // Calculate the Cartesian position from the motor positions
|
||||
|
||||
float ComputeDerivative(unsigned int deriv, float ha, float hb, float hc); // Compute the derivative of height with respect to a parameter at a set of motor endpoints
|
||||
void Adjust(size_t numFactors, const float v[]); // Perform 4-, 6- or 7-factor adjustment
|
||||
void PrintParameters(StringRef& reply, bool full);
|
||||
|
||||
private:
|
||||
void Recalc();
|
||||
void NormaliseEndstopAdjustments(); // Make the average of the endstop adjustments zero
|
||||
|
||||
// Core parameters
|
||||
float diagonal; // The diagonal rod length, all 3 are assumed to be the same length
|
||||
float radius; // The nominal delta radius, before any fine tuning of tower positions
|
||||
float towerX[AXES]; // The X coordinate of each tower
|
||||
float towerY[AXES]; // The Y coordinate of each tower
|
||||
float endstopAdjustments[AXES]; // How much above or below the ideal position each endstop is
|
||||
float printRadius;
|
||||
float homedHeight;
|
||||
|
||||
// Derived values
|
||||
bool deltaMode; // True if this is a delta printer
|
||||
bool isEquilateral; // True if the towers are at the corners of an equilateral triangle
|
||||
float printRadiusSquared;
|
||||
float homedCarriageHeight;
|
||||
float Xbc, Xca, Xab, Ybc, Yca, Yab;
|
||||
float coreFa, coreFb, coreFc;
|
||||
float Q, Q2, D2;
|
||||
};
|
||||
|
||||
#endif /* DELTAPARAMETERS_H_ */
|
136
DeltaProbe.cpp
Normal file
136
DeltaProbe.cpp
Normal file
|
@ -0,0 +1,136 @@
|
|||
/*
|
||||
* DeltaProbe.cpp
|
||||
*
|
||||
* Created on: 20 Apr 2015
|
||||
* Author: David
|
||||
*/
|
||||
|
||||
#include "RepRapFirmware.h"
|
||||
|
||||
// Set up to probe
|
||||
bool DeltaProbe::Init(float frequency, float amplitude, float rate, float height)
|
||||
{
|
||||
debugPrintf("Start probe f=%.1f a=%.2f r=%.2f h=%.1f\n", frequency, amplitude, rate, height);
|
||||
// Sanity check the inputs (we check the max amplitude later)
|
||||
if (frequency < 50.0 || frequency > 1000.0 || amplitude < 0.02 || rate < 0.1 || rate > 10.0 || height < 0.5)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
debugPrintf("ok so far\n");
|
||||
// Calculate the number of steps for the peak to peak amplitude
|
||||
const float zRate = reprap.GetPlatform()->DriveStepsPerUnit(Z_AXIS);
|
||||
normalSteps = (size_t)(amplitude * zRate);
|
||||
if (normalSteps > MaxSteps)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
debugPrintf("normalSteps=%u\n", normalSteps);
|
||||
// Build the tables of step times for sinusoidal motion
|
||||
const float recipOmega = (float)DDA::stepClockRate/(frequency * 2.0 * PI);
|
||||
|
||||
for (size_t i = 0; i < normalSteps - 1; ++i)
|
||||
{
|
||||
normalStepTable[i] = acos(1.0 - (float)(2 * (i + 1))/(float)normalSteps) * recipOmega;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < normalSteps; ++i)
|
||||
{
|
||||
incStepTable[i] = acos(1.0 - (float)(2 * (i + 1))/(float)(normalSteps + 1)) * recipOmega;
|
||||
}
|
||||
|
||||
halfCycleTime = (uint32_t)((float)DDA::stepClockRate/(2.0 * frequency));
|
||||
incStepTable[normalSteps] = normalStepTable[normalSteps - 1] = halfCycleTime;
|
||||
|
||||
halfCyclesPerIncrement = 2 * (unsigned int)((frequency / (rate * zRate)) + 0.5);
|
||||
if (halfCyclesPerIncrement < 4)
|
||||
{
|
||||
halfCyclesPerIncrement = 4;
|
||||
}
|
||||
maxIncrements = height * zRate;
|
||||
|
||||
const float peakAccel = fsquare(2.0 * PI * frequency) * amplitude * 0.5;
|
||||
debugPrintf("halfCycleTime=%u halfCyclesPerIncrement=%u peak accel=%.1f\n", halfCycleTime, halfCyclesPerIncrement, peakAccel);
|
||||
debugPrintf("normalTable=");
|
||||
for (unsigned int i = 0; i < normalSteps; ++i)
|
||||
{
|
||||
debugPrintf(" %u", normalStepTable[i]);
|
||||
}
|
||||
debugPrintf(" incStepTable=");
|
||||
for (unsigned int i = 0; i <= normalSteps; ++i)
|
||||
{
|
||||
debugPrintf(" %u", incStepTable[i]);
|
||||
}
|
||||
debugPrintf("\n");
|
||||
return true;
|
||||
}
|
||||
|
||||
// Start probing, and return the time that the next step is due
|
||||
uint32_t DeltaProbe::Start()
|
||||
{
|
||||
// Initialise the dynamic values
|
||||
stepsDone = 0;
|
||||
halfCycleCount = 0;
|
||||
numIncrements = 0;
|
||||
incrementing = false;
|
||||
state = State::normal;
|
||||
return normalStepTable[0];
|
||||
}
|
||||
|
||||
bool DeltaProbe::GetDirection() const
|
||||
{
|
||||
return (halfCycleCount & 1) ? FORWARDS : BACKWARDS;
|
||||
}
|
||||
|
||||
// Calculate the next step time. Returns 0xFFFFFFFF to stop.
|
||||
uint32_t DeltaProbe::CalcNextStepTime()
|
||||
{
|
||||
if (state == State::stopped || state == State::overran)
|
||||
{
|
||||
return 0xFFFFFFFF;
|
||||
}
|
||||
|
||||
++stepsDone;
|
||||
if (stepsDone == ((incrementing) ? normalSteps + 1 : normalSteps))
|
||||
{
|
||||
stepsDone = 0;
|
||||
++halfCycleCount;
|
||||
if (state == State::stopping && (halfCycleCount & 1) == 0)
|
||||
{
|
||||
state = State::stopped;
|
||||
return 0xFFFFFFFF;
|
||||
}
|
||||
|
||||
if (incrementing)
|
||||
{
|
||||
++numIncrements;
|
||||
incrementing = false;
|
||||
}
|
||||
|
||||
if (halfCycleCount == halfCyclesPerIncrement)
|
||||
{
|
||||
if (numIncrements == maxIncrements)
|
||||
{
|
||||
state = State::overran; // another increment is due, but we have already gone down as far as we were asked to
|
||||
return 0xFFFFFFFF;
|
||||
}
|
||||
halfCycleCount = 0;
|
||||
incrementing = true;
|
||||
}
|
||||
}
|
||||
|
||||
return (incrementing)
|
||||
? (halfCyclesPerIncrement * numIncrements * halfCycleTime) + incStepTable[stepsDone]
|
||||
: (halfCyclesPerIncrement * numIncrements * halfCycleTime) + normalStepTable[stepsDone];
|
||||
}
|
||||
|
||||
void DeltaProbe::Trigger()
|
||||
{
|
||||
if (state == State::normal)
|
||||
{
|
||||
state = State::stopping;
|
||||
}
|
||||
}
|
||||
|
||||
// End
|
44
DeltaProbe.h
Normal file
44
DeltaProbe.h
Normal file
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* DeltaProbe.h
|
||||
*
|
||||
* Created on: 20 Apr 2015
|
||||
* Author: David
|
||||
*/
|
||||
|
||||
#ifndef DELTAPROBE_H_
|
||||
#define DELTAPROBE_H_
|
||||
|
||||
// Class to hold the parameters for my new Z probing method
|
||||
class DeltaProbe
|
||||
{
|
||||
enum class State { normal, stopping, stopped, overran };
|
||||
|
||||
// Fixed parameters
|
||||
static const unsigned int MaxSteps = 30; // 15 corresponds to 0.375mm p-p movement @ 80 steps/mm
|
||||
|
||||
// Static parameters, set up before we start probing and unchanged during probing
|
||||
unsigned int normalSteps; // the number of steps we use to achieve the requested amplitude
|
||||
unsigned int halfCyclesPerIncrement; // how many half cycles between lowering the head by 1 step
|
||||
unsigned int maxIncrements; // max number of steps we lower the head
|
||||
uint32_t halfCycleTime; // how many interrupt clocks per quarter cycle
|
||||
uint32_t normalStepTable[MaxSteps]; // table of step times for the first half cycle, in interrupt clocks from start
|
||||
uint32_t incStepTable[MaxSteps + 1]; // table of step times for the first half cycle, when we are moving down a step
|
||||
|
||||
// Dynamic parameters, to track the progress of the probe
|
||||
unsigned int stepsDone; // how many steps since the start of this quarter cycle
|
||||
unsigned int halfCycleCount; // how many quarter cycles since we started or lowered the head
|
||||
unsigned int numIncrements; // how many steps we have lowered the head since we started
|
||||
bool incrementing; // true if we are lowering the head 2 step in this half cycle
|
||||
State state; // what state the probe is in
|
||||
|
||||
public:
|
||||
bool Init(float frequency, float amplitude, float rate, float height); // Get ready to probe
|
||||
uint32_t Start(); // start the process, return the next step time
|
||||
bool GetDirection() const; // get the direction for the current step
|
||||
uint32_t CalcNextStepTime(); // calculate when the next step is due
|
||||
void Trigger(); // cease probing
|
||||
bool Finished() const { return state == State::stopped || state == State::overran; }
|
||||
bool Overran() const { return state == State::overran; }
|
||||
};
|
||||
|
||||
#endif /* DELTAPROBE_H_ */
|
227
GCodes.cpp
227
GCodes.cpp
|
@ -152,6 +152,7 @@ void GCodes::DoFilePrint(GCodeBuffer* gb, StringRef& reply)
|
|||
else if (AllMovesAreFinishedAndMoveBufferIsLoaded())
|
||||
{
|
||||
fileBeingPrinted.Close();
|
||||
reprap.GetPrintMonitor()->StoppedPrint();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -170,7 +171,7 @@ void GCodes::Spin()
|
|||
// Check for M105 poll requests from Pronterface and PanelDue so that the status is kept up to date during execution of file macros etc.
|
||||
// No need to read multiple characters at a time in this case because the polling rate is quite low.
|
||||
if (!serialGCode->Active() && serialGCode->WritingFileDirectory() == nullptr
|
||||
&& (platform->GetLine()->Status() & byteAvailable))
|
||||
&& (platform->GetLine()->Status() & (uint8_t)IOStatus::byteAvailable))
|
||||
{
|
||||
char b;
|
||||
platform->GetLine()->Read(b);
|
||||
|
@ -184,7 +185,7 @@ void GCodes::Spin()
|
|||
}
|
||||
}
|
||||
|
||||
if (!auxGCode->Active() && (platform->GetAux()->Status() & byteAvailable))
|
||||
if (!auxGCode->Active() && (platform->GetAux()->Status() & (uint8_t)IOStatus::byteAvailable))
|
||||
{
|
||||
char b;
|
||||
platform->GetAux()->Read(b);
|
||||
|
@ -407,7 +408,7 @@ void GCodes::StartNextGCode(StringRef& reply)
|
|||
|
||||
// Now the serial interfaces.
|
||||
|
||||
if (platform->GetLine()->Status() & byteAvailable)
|
||||
if (platform->GetLine()->Status() & (uint8_t)IOStatus::byteAvailable)
|
||||
{
|
||||
// First check the special case of uploading the reprap.htm file
|
||||
if (serialGCode->WritingFileDirectory() == platform->GetWebDir())
|
||||
|
@ -443,7 +444,7 @@ void GCodes::StartNextGCode(StringRef& reply)
|
|||
break; // stop after receiving a complete gcode in case we haven't finished processing it
|
||||
}
|
||||
++i;
|
||||
} while (i < 16 && (platform->GetLine()->Status() & byteAvailable));
|
||||
} while (i < 16 && (platform->GetLine()->Status() & (uint8_t)IOStatus::byteAvailable));
|
||||
platform->ClassReport(longWait);
|
||||
return;
|
||||
}
|
||||
|
@ -451,7 +452,7 @@ void GCodes::StartNextGCode(StringRef& reply)
|
|||
|
||||
// Now run the G-Code buffers. It's important to fill up the G-Code buffers before we do this,
|
||||
// otherwise we wouldn't have a chance to pause/cancel running prints.
|
||||
if (!auxGCode->Active() && (platform->GetAux()->Status() & byteAvailable))
|
||||
if (!auxGCode->Active() && (platform->GetAux()->Status() & (uint8_t)IOStatus::byteAvailable))
|
||||
{
|
||||
int8_t i = 0;
|
||||
do
|
||||
|
@ -465,7 +466,7 @@ void GCodes::StartNextGCode(StringRef& reply)
|
|||
break; // stop after receiving a complete gcode in case we haven't finished processing it
|
||||
}
|
||||
++i;
|
||||
} while (i < 16 && (platform->GetAux()->Status() & byteAvailable));
|
||||
} while (i < 16 && (platform->GetAux()->Status() & (uint8_t)IOStatus::byteAvailable));
|
||||
}
|
||||
else if (webGCode->Active())
|
||||
{
|
||||
|
@ -949,7 +950,7 @@ bool GCodes::DoSingleZProbeAtPoint(int probePointIndex)
|
|||
switch (cannedCycleMoveCount)
|
||||
{
|
||||
case 0: // Move Z to the dive height. This only does anything on the first move; on all the others Z is already there
|
||||
moveToDo[Z_AXIS] = platform->GetZProbeDiveHeight();
|
||||
moveToDo[Z_AXIS] = platform->GetZProbeDiveHeight() + max<float>(platform->ZProbeStopHeight(), 0.0);
|
||||
activeDrive[Z_AXIS] = true;
|
||||
moveToDo[DRIVES] = platform->MaxFeedrate(Z_AXIS);
|
||||
activeDrive[DRIVES] = true;
|
||||
|
@ -973,50 +974,50 @@ bool GCodes::DoSingleZProbeAtPoint(int probePointIndex)
|
|||
return false;
|
||||
|
||||
case 2: // Probe the bed
|
||||
if (!cannedCycleMoveQueued && reprap.GetPlatform()->GetZProbeResult() == lowHit)
|
||||
{
|
||||
// Z probe is already triggered at the start of the move, so abandon the probe and record an error
|
||||
platform->Message(BOTH_ERROR_MESSAGE, "Z probe warning: probe already triggered at start of probing move\n");
|
||||
cannedCycleMoveCount = 0;
|
||||
reprap.GetMove()->SetZBedProbePoint(probePointIndex, platform->GetZProbeDiveHeight(), true, true);
|
||||
return true;
|
||||
}
|
||||
const float height = (axisIsHomed[Z_AXIS])
|
||||
? 2 * platform->GetZProbeDiveHeight() // Z axis has been homed, so no point in going very far
|
||||
: 1.1 * platform->AxisTotalLength(Z_AXIS); // Z axis not homed yet, so treat this as a homing move
|
||||
switch(DoZProbe(height))
|
||||
{
|
||||
case 0:
|
||||
// Z probe is already triggered at the start of the move, so abandon the probe and record an error
|
||||
platform->Message(BOTH_ERROR_MESSAGE, "Z probe warning: probe already triggered at start of probing move\n");
|
||||
cannedCycleMoveCount++;
|
||||
reprap.GetMove()->SetZBedProbePoint(probePointIndex, platform->GetZProbeDiveHeight(), true, true);
|
||||
break;
|
||||
|
||||
moveToDo[Z_AXIS] = (axisIsHomed[Z_AXIS])
|
||||
? -platform->GetZProbeDiveHeight() // Z axis has been homed, so no point in going very far
|
||||
: -1.1 * platform->AxisTotalLength(Z_AXIS); // Z axis not homed yet, so treat this as a homing move
|
||||
activeDrive[Z_AXIS] = true;
|
||||
moveToDo[DRIVES] = platform->HomeFeedRate(Z_AXIS);
|
||||
activeDrive[DRIVES] = true;
|
||||
if (DoCannedCycleMove(ZProbeActive))
|
||||
{
|
||||
// The head has been moved down until the probe was triggered. Get the height from the live coordinates.
|
||||
// DoCannedCycleMove has already loaded the current position into moveBuffer
|
||||
if (axisIsHomed[Z_AXIS])
|
||||
{
|
||||
lastProbedZ = moveBuffer[Z_AXIS] - platform->ZProbeStopHeight();
|
||||
case 1:
|
||||
if (axisIsHomed[Z_AXIS])
|
||||
{
|
||||
lastProbedZ = moveBuffer[Z_AXIS] - platform->ZProbeStopHeight();
|
||||
}
|
||||
else
|
||||
{
|
||||
// The Z axis has not yet been homed, so treat this probe as a homing move.
|
||||
moveBuffer[Z_AXIS] = platform->ZProbeStopHeight();
|
||||
SetPositions(moveBuffer);
|
||||
axisIsHomed[Z_AXIS] = true;
|
||||
lastProbedZ = 0.0;
|
||||
}
|
||||
reprap.GetMove()->SetZBedProbePoint(probePointIndex, lastProbedZ, true, false);
|
||||
cannedCycleMoveCount++;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
// The Z axis has not yet been homed, so treat this probe as a homing move.
|
||||
moveBuffer[Z_AXIS] = platform->ZProbeStopHeight();
|
||||
SetPositions(moveBuffer);
|
||||
axisIsHomed[Z_AXIS] = true;
|
||||
lastProbedZ = 0.0;
|
||||
}
|
||||
cannedCycleMoveCount++;
|
||||
}
|
||||
return false;
|
||||
|
||||
case 3: // Raise the head back up to the dive height
|
||||
moveToDo[Z_AXIS] = platform->GetZProbeDiveHeight();
|
||||
moveToDo[Z_AXIS] = platform->GetZProbeDiveHeight() + max<float>(platform->ZProbeStopHeight(), 0.0);
|
||||
activeDrive[Z_AXIS] = true;
|
||||
moveToDo[DRIVES] = platform->MaxFeedrate(Z_AXIS);
|
||||
activeDrive[DRIVES] = true;
|
||||
if (DoCannedCycleMove(0))
|
||||
{
|
||||
cannedCycleMoveCount = 0;
|
||||
reprap.GetMove()->SetZBedProbePoint(probePointIndex, lastProbedZ, true, false);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -1027,30 +1028,62 @@ bool GCodes::DoSingleZProbeAtPoint(int probePointIndex)
|
|||
}
|
||||
}
|
||||
|
||||
// This simply moves down till the Z probe/switch is triggered.
|
||||
// This simply moves down till the Z probe/switch is triggered. Call it repeatedly until it returns true.
|
||||
// Called when we do a G30 with no P parameter.
|
||||
bool GCodes::DoSingleZProbe()
|
||||
{
|
||||
for (size_t drive = 0; drive <= DRIVES; drive++)
|
||||
switch (DoZProbe(1.1 * platform->AxisTotalLength(Z_AXIS)))
|
||||
{
|
||||
activeDrive[drive] = false;
|
||||
}
|
||||
case 0: // failed
|
||||
return true;
|
||||
|
||||
moveToDo[Z_AXIS] = -1.1 * platform->AxisTotalLength(Z_AXIS);
|
||||
activeDrive[Z_AXIS] = true;
|
||||
moveToDo[DRIVES] = platform->HomeFeedRate(Z_AXIS);
|
||||
activeDrive[DRIVES] = true;
|
||||
if (DoCannedCycleMove(ZProbeActive))
|
||||
{
|
||||
// The head has been moved down until the probe was triggered. Get the height from the live coordinates.
|
||||
// DoCannedCycleMove has already loaded the current position into moveBuffer
|
||||
case 1: // success
|
||||
moveBuffer[Z_AXIS] = platform->ZProbeStopHeight();
|
||||
SetPositions(moveBuffer);
|
||||
axisIsHomed[Z_AXIS] = true;
|
||||
lastProbedZ = 0.0;
|
||||
return true;
|
||||
|
||||
default: // not finished yet
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Do a Z probe cycle up to the maximum specified distance.
|
||||
// Returns -1 if not complete yet
|
||||
// Returns 0 if failed
|
||||
// Returns 1 if success, with lastProbedZ set to the height we stopped at and the current position in moveBuffer
|
||||
int GCodes::DoZProbe(float distance)
|
||||
{
|
||||
if (platform->GetZProbeType() == 5)
|
||||
{
|
||||
const ZProbeParameters& params = platform->GetZProbeParameters();
|
||||
return reprap.GetMove()->DoDeltaProbe(params.param1, params.param2, platform->HomeFeedRate(Z_AXIS), distance);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!cannedCycleMoveQueued && reprap.GetPlatform()->GetZProbeResult() == EndStopHit::lowHit)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Do a normal canned cycle Z movement with Z probe enabled
|
||||
for (size_t drive = 0; drive <= DRIVES; drive++)
|
||||
{
|
||||
activeDrive[drive] = false;
|
||||
}
|
||||
|
||||
moveToDo[Z_AXIS] = -distance;
|
||||
activeDrive[Z_AXIS] = true;
|
||||
moveToDo[DRIVES] = platform->HomeFeedRate(Z_AXIS);
|
||||
activeDrive[DRIVES] = true;
|
||||
|
||||
if (DoCannedCycleMove(ZProbeActive))
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// This is called to execute a G30.
|
||||
|
@ -1339,11 +1372,17 @@ void GCodes::WriteGCodeToFile(GCodeBuffer *gb)
|
|||
// Set up a file to print, but don't print it yet.
|
||||
void GCodes::QueueFileToPrint(const char* fileName)
|
||||
{
|
||||
fileToPrint.Close();
|
||||
fileGCode->CancelPause(); // if we paused it and then asked to print a new file, cancel any pending command
|
||||
FileStore *f = platform->GetFileStore(platform->GetGCodeDir(), fileName, false);
|
||||
if (f != NULL)
|
||||
{
|
||||
// Cancel current print if there is any
|
||||
if (PrintingAFile())
|
||||
{
|
||||
CancelPrint();
|
||||
}
|
||||
|
||||
fileGCode->SetToolNumberAdjust(0); // clear tool number adjustment
|
||||
|
||||
// Reset all extruder positions when starting a new print
|
||||
for (size_t extruder = AXES; extruder < DRIVES; extruder++)
|
||||
{
|
||||
|
@ -1351,10 +1390,6 @@ void GCodes::QueueFileToPrint(const char* fileName)
|
|||
}
|
||||
|
||||
fileToPrint.Set(f);
|
||||
if (!fileBeingPrinted.IsLive())
|
||||
{
|
||||
fileGCode->SetToolNumberAdjust(0); // clear tool number adjustment
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -2092,9 +2127,21 @@ bool GCodes::HandleGcode(GCodeBuffer* gb, StringRef& reply)
|
|||
|
||||
if (toBeHomed == 0 || toBeHomed == ((1 << X_AXIS) | (1 << Y_AXIS) | (1 << Z_AXIS)))
|
||||
{
|
||||
// Homing everything
|
||||
SetAllAxesNotHomed();
|
||||
DoFileMacro(HOME_ALL_G);
|
||||
}
|
||||
else if ( platform->MustHomeXYBeforeZ()
|
||||
&& ((toBeHomed & (1 << Z_AXIS)) != 0)
|
||||
&& ( (((toBeHomed & (1 << X_AXIS)) == 0) && !axisIsHomed[X_AXIS])
|
||||
|| (((toBeHomed & (1 << Y_AXIS)) == 0) && !axisIsHomed[Y_AXIS])
|
||||
)
|
||||
)
|
||||
{
|
||||
// We can only home Z if both X and Y have already been homed or are being homed
|
||||
reply.copy("Must home X and Y before homing Z");
|
||||
error = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
state = GCodeState::homing;
|
||||
|
@ -2215,6 +2262,9 @@ bool GCodes::HandleMcode(GCodeBuffer* gb, StringRef& reply)
|
|||
isPaused = false;
|
||||
reply.copy("Print cancelled\n");
|
||||
}
|
||||
|
||||
// Reset everything
|
||||
CancelPrint();
|
||||
break;
|
||||
|
||||
case 18: // Motors off
|
||||
|
@ -2332,10 +2382,10 @@ bool GCodes::HandleMcode(GCodeBuffer* gb, StringRef& reply)
|
|||
|
||||
{
|
||||
const char* filename = gb->GetUnprecedentedString();
|
||||
reprap.GetPrintMonitor()->StartingFilePrint(filename);
|
||||
QueueFileToPrint(filename);
|
||||
if (fileToPrint.IsLive())
|
||||
{
|
||||
reprap.GetPrintMonitor()->StartingPrint(filename);
|
||||
if (platform->Emulating() == marlin && gb == serialGCode)
|
||||
{
|
||||
reply.copy("File opened\nFile selected\n");
|
||||
|
@ -2349,7 +2399,7 @@ bool GCodes::HandleMcode(GCodeBuffer* gb, StringRef& reply)
|
|||
if (code == 32)
|
||||
{
|
||||
fileBeingPrinted.MoveFrom(fileToPrint);
|
||||
reprap.GetPrintMonitor()->StartedFilePrint();
|
||||
reprap.GetPrintMonitor()->StartedPrint();
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -2379,7 +2429,7 @@ bool GCodes::HandleMcode(GCodeBuffer* gb, StringRef& reply)
|
|||
else
|
||||
{
|
||||
fileBeingPrinted.MoveFrom(fileToPrint);
|
||||
reprap.GetPrintMonitor()->StartedFilePrint();
|
||||
reprap.GetPrintMonitor()->StartedPrint();
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -2859,19 +2909,19 @@ bool GCodes::HandleMcode(GCodeBuffer* gb, StringRef& reply)
|
|||
const char* es;
|
||||
switch (platform->Stopped(axis))
|
||||
{
|
||||
case lowHit:
|
||||
case EndStopHit::lowHit:
|
||||
es = "at min stop";
|
||||
break;
|
||||
|
||||
case highHit:
|
||||
case EndStopHit::highHit:
|
||||
es = "at max stop";
|
||||
break;
|
||||
|
||||
case lowNear:
|
||||
case EndStopHit::lowNear:
|
||||
es = "near min stop";
|
||||
break;
|
||||
|
||||
case noStop:
|
||||
case EndStopHit::noStop:
|
||||
default:
|
||||
es = "not stopped";
|
||||
}
|
||||
|
@ -3522,10 +3572,31 @@ bool GCodes::HandleMcode(GCodeBuffer* gb, StringRef& reply)
|
|||
seen = true;
|
||||
}
|
||||
|
||||
if (gb->Seen('S'))
|
||||
{
|
||||
ZProbeParameters params = platform->GetZProbeParameters();
|
||||
params.param1 = gb->GetFValue();
|
||||
platform->SetZProbeParameters(params);
|
||||
seen = true;
|
||||
}
|
||||
|
||||
if (gb->Seen('T'))
|
||||
{
|
||||
ZProbeParameters params = platform->GetZProbeParameters();
|
||||
params.param2 = gb->GetFValue();
|
||||
platform->SetZProbeParameters(params);
|
||||
seen = true;
|
||||
}
|
||||
|
||||
if (!seen)
|
||||
{
|
||||
reply.printf("Z Probe type is %d on channel %d with dive height %.1f and it is used for these axes:",
|
||||
platform->GetZProbeType(), platform->GetZProbeChannel(), platform->GetZProbeDiveHeight());
|
||||
reply.printf("Z Probe type %d, channel %d, dive height %.1f", platform->GetZProbeType(), platform->GetZProbeChannel(), platform->GetZProbeDiveHeight());
|
||||
if (platform->GetZProbeType() == 5)
|
||||
{
|
||||
ZProbeParameters params = platform->GetZProbeParameters();
|
||||
reply.catf(", parameters %.2f %.2f", params.param1, params.param2);
|
||||
}
|
||||
reply.cat(", used for these axes:");
|
||||
for (size_t axis = 0; axis < AXES; axis++)
|
||||
{
|
||||
if (zProbeAxes[axis])
|
||||
|
@ -3773,8 +3844,8 @@ bool GCodes::HandleMcode(GCodeBuffer* gb, StringRef& reply)
|
|||
bool logic;
|
||||
platform->GetEndStopConfiguration(axis, config, logic);
|
||||
reply.catf(" %c %s %s %c", axisLetters[axis],
|
||||
(config == highEndStop) ? "high end" : (config == lowEndStop) ? "low end" : "none",
|
||||
(config == noEndStop) ? "" : (logic) ? " (active high)" : " (active low)",
|
||||
(config == EndStopType::highEndStop) ? "high end" : (config == EndStopType::lowEndStop) ? "low end" : "none",
|
||||
(config == EndStopType::noEndStop) ? "" : (logic) ? " (active high)" : " (active low)",
|
||||
(axis == AXES - 1) ? '\n' : ',');
|
||||
}
|
||||
}
|
||||
|
@ -3996,7 +4067,10 @@ bool GCodes::HandleMcode(GCodeBuffer* gb, StringRef& reply)
|
|||
result = DoDwellTime(0.5);// wait half a second to allow the response to be sent back to the web server, otherwise it may retry
|
||||
if (result)
|
||||
{
|
||||
platform->SoftwareReset(SoftwareResetReason::user); // doesn't return
|
||||
uint16_t reason = (gb->Seen('S') && gb->GetIValue() == 4321)
|
||||
? SoftwareResetReason::erase
|
||||
: SoftwareResetReason::user;
|
||||
platform->SoftwareReset(reason); // doesn't return
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -4056,6 +4130,21 @@ void GCodes::PauseSDPrint()
|
|||
}
|
||||
}
|
||||
|
||||
// Cancel the current SD card print
|
||||
void GCodes::CancelPrint()
|
||||
{
|
||||
moveAvailable = false;
|
||||
|
||||
fileGCode->Init();
|
||||
|
||||
if (fileBeingPrinted.IsLive())
|
||||
{
|
||||
fileBeingPrinted.Close();
|
||||
}
|
||||
|
||||
reprap.GetPrintMonitor()->StoppedPrint();
|
||||
}
|
||||
|
||||
// Return true if all the heaters for the specified tool are at their set temperatures
|
||||
bool GCodes::ToolHeatersAtSetTemperatures(const Tool *tool) const
|
||||
{
|
||||
|
|
6
GCodes.h
6
GCodes.h
|
@ -119,11 +119,13 @@ class GCodes
|
|||
bool HandleGcode(GCodeBuffer* gb, StringRef& reply); // Do a G code
|
||||
bool HandleMcode(GCodeBuffer* gb, StringRef& reply); // Do an M code
|
||||
bool HandleTcode(GCodeBuffer* gb, StringRef& reply); // Do a T code
|
||||
void CancelPrint(); // Cancel the current print
|
||||
int SetUpMove(GCodeBuffer* gb, StringRef& reply); // Pass a move on to the Move module
|
||||
bool DoDwell(GCodeBuffer *gb); // Wait for a bit
|
||||
bool DoDwellTime(float dwell); // Really wait for a bit
|
||||
bool DoSingleZProbeAtPoint(int probePointIndex); // Probe at a given point
|
||||
bool DoSingleZProbe(); // Probe where we are
|
||||
int DoZProbe(float distance); // Do a Z probe cycle up to the maximum specified distance
|
||||
bool SetSingleZProbeAtAPosition(GCodeBuffer *gb, StringRef& reply); // Probes at a given position - see the comment at the head of the function itself
|
||||
void SetBedEquationWithProbe(int sParam, StringRef& reply); // Probes a series of points and sets the bed equation
|
||||
bool SetPrintZProbe(GCodeBuffer *gb, StringRef& reply); // Either return the probe value, or set its threshold
|
||||
|
@ -232,8 +234,8 @@ inline bool GCodes::HaveIncomingData() const
|
|||
{
|
||||
return fileBeingPrinted.IsLive() ||
|
||||
webserver->GCodeAvailable() ||
|
||||
(platform->GetLine()->Status() & byteAvailable) ||
|
||||
(platform->GetAux()->Status() & byteAvailable);
|
||||
(platform->GetLine()->Status() & (uint8_t)IOStatus::byteAvailable) ||
|
||||
(platform->GetAux()->Status() & (uint8_t)IOStatus::byteAvailable);
|
||||
}
|
||||
|
||||
// This function takes care of the fact that the heater and head indices don't match because the bed is heater 0.
|
||||
|
|
|
@ -68,23 +68,13 @@
|
|||
#include "lwip/src/include/netif/etharp.h"
|
||||
#include "lwip/src/sam/include/netif/ethernetif.h"
|
||||
|
||||
#include "emac.h"
|
||||
#include "include/emac.h"
|
||||
|
||||
extern void RepRapNetworkMessage(const char*);
|
||||
|
||||
/* Global variable containing MAC Config (hw addr, IP, GW, ...) */
|
||||
struct netif gs_net_if;
|
||||
|
||||
//*****************************AB
|
||||
//Pass through function for interface status
|
||||
//by including ethernetif.h directly and calling ethernetif_phy_link_status(); this function is not required
|
||||
bool status_link_up()
|
||||
{
|
||||
return ethernetif_phy_link_status();
|
||||
}
|
||||
//*****************************AB
|
||||
|
||||
|
||||
struct netif* ethernet_get_configuration()
|
||||
{
|
||||
return &gs_net_if;
|
||||
|
@ -193,10 +183,13 @@ static void ethernet_configure_interface(unsigned char ipAddress[], unsigned cha
|
|||
/** \brief Initialize the Ethernet subsystem.
|
||||
*
|
||||
*/
|
||||
void init_ethernet(void)
|
||||
void init_ethernet(const u8_t macAddress[], const char *hostname)
|
||||
{
|
||||
lwip_init();
|
||||
ethernet_hardware_init();
|
||||
|
||||
ethernetif_set_mac_address(macAddress);
|
||||
netif_set_hostname(&gs_net_if, hostname);
|
||||
}
|
||||
|
||||
/** \brief Try to establish a physical link at, returning true if successful.
|
||||
|
@ -216,13 +209,6 @@ void start_ethernet(const unsigned char ipAddress[], const unsigned char netMask
|
|||
ethernet_configure_interface(ipAddress, netMask, gateWay);
|
||||
}
|
||||
|
||||
/** \brief Set the DHCP hostname.
|
||||
*
|
||||
*/
|
||||
void set_dhcp_hostname(const char *hostname)
|
||||
{
|
||||
gs_net_if.hostname = hostname;
|
||||
}
|
||||
|
||||
//*************************************************************************************************************
|
||||
/**
|
||||
|
@ -237,7 +223,7 @@ void ethernet_status_callback(struct netif *netif)
|
|||
{
|
||||
RepRapNetworkMessage("Network up, IP=");
|
||||
ipaddr_ntoa_r(&(netif->ip_addr), c_mess, sizeof(c_mess));
|
||||
strncat(c_mess, sizeof(c_mess) - strlen(c_mess) - 1, "\n");
|
||||
strncat(c_mess, sizeof(c_mess) - 1, "\n");
|
||||
RepRapNetworkMessage(c_mess);
|
||||
netif->flags |= NETIF_FLAG_LINK_UP;
|
||||
}
|
||||
|
@ -248,11 +234,10 @@ void ethernet_status_callback(struct netif *netif)
|
|||
}
|
||||
|
||||
|
||||
|
||||
/**0
|
||||
* \brief Manage the Ethernet packets, if any received process them.
|
||||
* After processing any packets, manage the lwIP timers.
|
||||
*
|
||||
*
|
||||
* \return Returns true if data has been processed.
|
||||
*/
|
||||
bool ethernet_read(void)
|
||||
|
@ -275,6 +260,5 @@ bool ethernet_read(void)
|
|||
*/
|
||||
void ethernet_set_rx_callback(emac_dev_tx_cb_t callback)
|
||||
{
|
||||
|
||||
ethernetif_set_rx_callback(callback);
|
||||
}
|
|
@ -54,18 +54,14 @@ extern "C" {
|
|||
/**INDENT-ON**/
|
||||
/// @endcond
|
||||
|
||||
bool status_link_up();//*****************************AB
|
||||
|
||||
/**
|
||||
* \brief Initialize the ethernet interface.
|
||||
*
|
||||
*/
|
||||
//void init_ethernet(void);
|
||||
void init_ethernet(const u8_t macAddress[], const char *hostname);
|
||||
|
||||
void init_ethernet(void);
|
||||
bool establish_ethernet_link(void);
|
||||
void start_ethernet(const unsigned char ipAddress[], const unsigned char netMask[], const unsigned char gateWay[]);
|
||||
void set_dhcp_hostname(const char *hostname);
|
||||
|
||||
struct netif* ethernet_get_configuration();
|
||||
|
337
Libraries/Lwip/contrib/apps/netbios/netbios.c
Normal file
337
Libraries/Lwip/contrib/apps/netbios/netbios.c
Normal file
|
@ -0,0 +1,337 @@
|
|||
/**
|
||||
* @file
|
||||
* NetBIOS name service sample
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||
* OF SUCH DAMAGE.
|
||||
*
|
||||
* This file is part of the lwIP TCP/IP stack.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "lwipopts.h"
|
||||
|
||||
#if LWIP_UDP /* don't build if not configured for use in lwipopts.h */
|
||||
|
||||
#include "lwip/src/include/lwip/udp.h"
|
||||
#include "lwip/src/include/lwip/netif.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
/** This is an example implementation of a NetBIOS name server.
|
||||
* It responds to name queries for a configurable name.
|
||||
* Name resolving is not supported.
|
||||
*
|
||||
* Note that the device doesn't broadcast it's own name so can't
|
||||
* detect duplicate names!
|
||||
*/
|
||||
|
||||
/** NetBIOS name of LWIP device
|
||||
* This must be uppercase until NETBIOS_STRCMP() is defined to a string
|
||||
* comparision function that is case insensitive.
|
||||
* If you want to use the netif's hostname, use this (with LWIP_NETIF_HOSTNAME):
|
||||
* (ip_current_netif() != NULL ? ip_current_netif()->hostname != NULL ? ip_current_netif()->hostname : "" : "")
|
||||
*/
|
||||
#ifndef NETBIOS_LWIP_NAME
|
||||
#define NETBIOS_LWIP_NAME (ip_current_netif() != NULL ? ip_current_netif()->hostname != NULL ? ip_current_netif()->hostname : "DUET" : "DUET")
|
||||
#endif
|
||||
|
||||
/** Since there's no standard function for case-insensitive string comparision,
|
||||
* we need another define here:
|
||||
* define this to stricmp() for windows or strcasecmp() for linux.
|
||||
* If not defined, comparision is case sensitive and NETBIOS_LWIP_NAME must be
|
||||
* uppercase
|
||||
*/
|
||||
#ifndef NETBIOS_STRCMP
|
||||
#define NETBIOS_STRCMP(str1, str2) stricmp(str1, str2)
|
||||
#endif
|
||||
|
||||
/** default port number for "NetBIOS Name service */
|
||||
#define NETBIOS_PORT 137
|
||||
|
||||
/** size of a NetBIOS name */
|
||||
#define NETBIOS_NAME_LEN 16
|
||||
|
||||
/** The Time-To-Live for NetBIOS name responds (in seconds)
|
||||
* Default is 300000 seconds (3 days, 11 hours, 20 minutes) */
|
||||
#define NETBIOS_NAME_TTL 300000
|
||||
|
||||
/** NetBIOS header flags */
|
||||
#define NETB_HFLAG_RESPONSE 0x8000U
|
||||
#define NETB_HFLAG_OPCODE 0x7800U
|
||||
#define NETB_HFLAG_OPCODE_NAME_QUERY 0x0000U
|
||||
#define NETB_HFLAG_AUTHORATIVE 0x0400U
|
||||
#define NETB_HFLAG_TRUNCATED 0x0200U
|
||||
#define NETB_HFLAG_RECURS_DESIRED 0x0100U
|
||||
#define NETB_HFLAG_RECURS_AVAILABLE 0x0080U
|
||||
#define NETB_HFLAG_BROADCAST 0x0010U
|
||||
#define NETB_HFLAG_REPLYCODE 0x0008U
|
||||
#define NETB_HFLAG_REPLYCODE_NOERROR 0x0000U
|
||||
|
||||
/** NetBIOS name flags */
|
||||
#define NETB_NFLAG_UNIQUE 0x8000U
|
||||
#define NETB_NFLAG_NODETYPE 0x6000U
|
||||
#define NETB_NFLAG_NODETYPE_HNODE 0x6000U
|
||||
#define NETB_NFLAG_NODETYPE_MNODE 0x4000U
|
||||
#define NETB_NFLAG_NODETYPE_PNODE 0x2000U
|
||||
#define NETB_NFLAG_NODETYPE_BNODE 0x0000U
|
||||
|
||||
/** NetBIOS message header */
|
||||
#ifdef PACK_STRUCT_USE_INCLUDES
|
||||
# include "arch/bpstruct.h"
|
||||
#endif
|
||||
PACK_STRUCT_BEGIN
|
||||
struct netbios_hdr {
|
||||
PACK_STRUCT_FIELD(u16_t trans_id);
|
||||
PACK_STRUCT_FIELD(u16_t flags);
|
||||
PACK_STRUCT_FIELD(u16_t questions);
|
||||
PACK_STRUCT_FIELD(u16_t answerRRs);
|
||||
PACK_STRUCT_FIELD(u16_t authorityRRs);
|
||||
PACK_STRUCT_FIELD(u16_t additionalRRs);
|
||||
} PACK_STRUCT_STRUCT;
|
||||
PACK_STRUCT_END
|
||||
#ifdef PACK_STRUCT_USE_INCLUDES
|
||||
# include "arch/epstruct.h"
|
||||
#endif
|
||||
|
||||
/** NetBIOS message name part */
|
||||
#ifdef PACK_STRUCT_USE_INCLUDES
|
||||
# include "arch/bpstruct.h"
|
||||
#endif
|
||||
PACK_STRUCT_BEGIN
|
||||
struct netbios_name_hdr {
|
||||
PACK_STRUCT_FIELD(u8_t nametype);
|
||||
PACK_STRUCT_FIELD(u8_t encname[(NETBIOS_NAME_LEN*2)+1]);
|
||||
PACK_STRUCT_FIELD(u16_t type);
|
||||
PACK_STRUCT_FIELD(u16_t cls);
|
||||
PACK_STRUCT_FIELD(u32_t ttl);
|
||||
PACK_STRUCT_FIELD(u16_t datalen);
|
||||
PACK_STRUCT_FIELD(u16_t flags);
|
||||
PACK_STRUCT_FIELD(ip_addr_p_t addr);
|
||||
} PACK_STRUCT_STRUCT;
|
||||
PACK_STRUCT_END
|
||||
#ifdef PACK_STRUCT_USE_INCLUDES
|
||||
# include "arch/epstruct.h"
|
||||
#endif
|
||||
|
||||
/** NetBIOS message */
|
||||
#ifdef PACK_STRUCT_USE_INCLUDES
|
||||
# include "arch/bpstruct.h"
|
||||
#endif
|
||||
PACK_STRUCT_BEGIN
|
||||
struct netbios_resp
|
||||
{
|
||||
struct netbios_hdr resp_hdr;
|
||||
struct netbios_name_hdr resp_name;
|
||||
} PACK_STRUCT_STRUCT;
|
||||
PACK_STRUCT_END
|
||||
#ifdef PACK_STRUCT_USE_INCLUDES
|
||||
# include "arch/epstruct.h"
|
||||
#endif
|
||||
|
||||
/** NetBIOS decoding name */
|
||||
static int
|
||||
netbios_name_decoding( char *name_enc, char *name_dec, int name_dec_len)
|
||||
{
|
||||
char *pname;
|
||||
char cname;
|
||||
char cnbname;
|
||||
int index = 0;
|
||||
|
||||
LWIP_UNUSED_ARG(name_dec_len);
|
||||
|
||||
/* Start decoding netbios name. */
|
||||
pname = name_enc;
|
||||
for (;;) {
|
||||
/* Every two characters of the first level-encoded name
|
||||
* turn into one character in the decoded name. */
|
||||
cname = *pname;
|
||||
if (cname == '\0')
|
||||
break; /* no more characters */
|
||||
if (cname == '.')
|
||||
break; /* scope ID follows */
|
||||
if (cname < 'A' || cname > 'Z') {
|
||||
/* Not legal. */
|
||||
return -1;
|
||||
}
|
||||
cname -= 'A';
|
||||
cnbname = cname << 4;
|
||||
pname++;
|
||||
|
||||
cname = *pname;
|
||||
if (cname == '\0' || cname == '.') {
|
||||
/* No more characters in the name - but we're in
|
||||
* the middle of a pair. Not legal. */
|
||||
return -1;
|
||||
}
|
||||
if (cname < 'A' || cname > 'Z') {
|
||||
/* Not legal. */
|
||||
return -1;
|
||||
}
|
||||
cname -= 'A';
|
||||
cnbname |= cname;
|
||||
pname++;
|
||||
|
||||
/* Do we have room to store the character? */
|
||||
if (index < NETBIOS_NAME_LEN) {
|
||||
/* Yes - store the character. */
|
||||
name_dec[index++] = (cnbname!=' '?cnbname:'\0');
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if 0 /* function currently unused */
|
||||
/** NetBIOS encoding name */
|
||||
static int
|
||||
netbios_name_encoding(char *name_enc, char *name_dec, int name_dec_len)
|
||||
{
|
||||
char *pname;
|
||||
char cname;
|
||||
unsigned char ucname;
|
||||
int index = 0;
|
||||
|
||||
/* Start encoding netbios name. */
|
||||
pname = name_enc;
|
||||
|
||||
for (;;) {
|
||||
/* Every two characters of the first level-encoded name
|
||||
* turn into one character in the decoded name. */
|
||||
cname = *pname;
|
||||
if (cname == '\0')
|
||||
break; /* no more characters */
|
||||
if (cname == '.')
|
||||
break; /* scope ID follows */
|
||||
if ((cname < 'A' || cname > 'Z') && (cname < '0' || cname > '9')) {
|
||||
/* Not legal. */
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Do we have room to store the character? */
|
||||
if (index >= name_dec_len) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Yes - store the character. */
|
||||
ucname = cname;
|
||||
name_dec[index++] = ('A'+((ucname>>4) & 0x0F));
|
||||
name_dec[index++] = ('A'+( ucname & 0x0F));
|
||||
pname++;
|
||||
}
|
||||
|
||||
/* Fill with "space" coding */
|
||||
for (;index<name_dec_len-1;) {
|
||||
name_dec[index++] = 'C';
|
||||
name_dec[index++] = 'A';
|
||||
}
|
||||
|
||||
/* Terminate string */
|
||||
name_dec[index]='\0';
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif /* 0 */
|
||||
|
||||
/** NetBIOS Name service recv callback */
|
||||
static void
|
||||
netbios_recv(void *arg, struct udp_pcb *upcb, struct pbuf *p, ip_addr_t *addr, u16_t port)
|
||||
{
|
||||
LWIP_UNUSED_ARG(arg);
|
||||
|
||||
/* if packet is valid */
|
||||
if (p != NULL) {
|
||||
char netbios_name[NETBIOS_NAME_LEN+1];
|
||||
struct netbios_hdr* netbios_hdr = (struct netbios_hdr*)p->payload;
|
||||
struct netbios_name_hdr* netbios_name_hdr = (struct netbios_name_hdr*)(netbios_hdr+1);
|
||||
|
||||
/* we only answer if we got a default interface */
|
||||
if (netif_default != NULL) {
|
||||
/* @todo: do we need to check answerRRs/authorityRRs/additionalRRs? */
|
||||
/* if the packet is a NetBIOS name query question */
|
||||
if (((netbios_hdr->flags & PP_NTOHS(NETB_HFLAG_OPCODE)) == PP_NTOHS(NETB_HFLAG_OPCODE_NAME_QUERY)) &&
|
||||
((netbios_hdr->flags & PP_NTOHS(NETB_HFLAG_RESPONSE)) == 0) &&
|
||||
(netbios_hdr->questions == PP_NTOHS(1))) {
|
||||
/* decode the NetBIOS name */
|
||||
netbios_name_decoding( (char*)(netbios_name_hdr->encname), netbios_name, sizeof(netbios_name));
|
||||
/* if the packet is for us */
|
||||
if (NETBIOS_STRCMP(netbios_name, NETBIOS_LWIP_NAME) == 0) {
|
||||
struct pbuf *q;
|
||||
struct netbios_resp *resp;
|
||||
|
||||
q = pbuf_alloc(PBUF_TRANSPORT, sizeof(struct netbios_resp), PBUF_RAM);
|
||||
if (q != NULL) {
|
||||
resp = (struct netbios_resp*)q->payload;
|
||||
|
||||
/* prepare NetBIOS header response */
|
||||
resp->resp_hdr.trans_id = netbios_hdr->trans_id;
|
||||
resp->resp_hdr.flags = PP_HTONS(NETB_HFLAG_RESPONSE |
|
||||
NETB_HFLAG_OPCODE_NAME_QUERY |
|
||||
NETB_HFLAG_AUTHORATIVE |
|
||||
NETB_HFLAG_RECURS_DESIRED);
|
||||
resp->resp_hdr.questions = 0;
|
||||
resp->resp_hdr.answerRRs = PP_HTONS(1);
|
||||
resp->resp_hdr.authorityRRs = 0;
|
||||
resp->resp_hdr.additionalRRs = 0;
|
||||
|
||||
/* prepare NetBIOS header datas */
|
||||
MEMCPY( resp->resp_name.encname, netbios_name_hdr->encname, sizeof(netbios_name_hdr->encname));
|
||||
resp->resp_name.nametype = netbios_name_hdr->nametype;
|
||||
resp->resp_name.type = netbios_name_hdr->type;
|
||||
resp->resp_name.cls = netbios_name_hdr->cls;
|
||||
resp->resp_name.ttl = PP_HTONL(NETBIOS_NAME_TTL);
|
||||
resp->resp_name.datalen = PP_HTONS(sizeof(resp->resp_name.flags)+sizeof(resp->resp_name.addr));
|
||||
resp->resp_name.flags = PP_HTONS(NETB_NFLAG_NODETYPE_BNODE);
|
||||
ip_addr_copy(resp->resp_name.addr, netif_default->ip_addr);
|
||||
|
||||
/* send the NetBIOS response */
|
||||
udp_sendto(upcb, q, addr, port);
|
||||
|
||||
/* free the "reference" pbuf */
|
||||
pbuf_free(q);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/* free the pbuf */
|
||||
pbuf_free(p);
|
||||
}
|
||||
}
|
||||
|
||||
void netbios_init(void)
|
||||
{
|
||||
struct udp_pcb *pcb;
|
||||
|
||||
LWIP_ASSERT("NetBIOS name is too long!", strlen(NETBIOS_LWIP_NAME) < NETBIOS_NAME_LEN);
|
||||
|
||||
pcb = udp_new();
|
||||
if (pcb != NULL) {
|
||||
/* we have to be allowed to send broadcast packets! */
|
||||
pcb->so_options |= SOF_BROADCAST;
|
||||
udp_bind(pcb, IP_ADDR_ANY, NETBIOS_PORT);
|
||||
udp_recv(pcb, netbios_recv, pcb);
|
||||
}
|
||||
}
|
||||
#endif /* LWIP_UDP */
|
6
Libraries/Lwip/contrib/apps/netbios/netbios.h
Normal file
6
Libraries/Lwip/contrib/apps/netbios/netbios.h
Normal file
|
@ -0,0 +1,6 @@
|
|||
#ifndef __NETBIOS_H__
|
||||
#define __NETBIOS_H__
|
||||
|
||||
void netbios_init(void);
|
||||
|
||||
#endif /* __NETBIOS_H__ */
|
|
@ -76,7 +76,7 @@ typedef u8_t sys_mbox_t;
|
|||
*/
|
||||
#define SYS_MBOX_EMPTY SYS_ARCH_TIMEOUT
|
||||
|
||||
#include "lwip/err.h"
|
||||
#include "err.h"
|
||||
#include "arch/sys_arch.h"
|
||||
|
||||
/** Function prototype for thread functions */
|
||||
|
|
|
@ -53,12 +53,11 @@
|
|||
bool ethernetif_phy_link_status(void); //*****************************AB
|
||||
|
||||
err_t ethernetif_init(struct netif *netif);
|
||||
void ethernetif_set_params(const u8_t macAddress[], const char *hostname);
|
||||
|
||||
bool ethernetif_input(void *pv_parameters);
|
||||
|
||||
void ethernet_hardware_init(void);
|
||||
bool ethernet_establish_link(void);
|
||||
void RepRapNetworkSetMACAddress(const u8_t macAddress[]);
|
||||
void ethernetif_set_rx_callback(emac_dev_tx_cb_t callback);
|
||||
|
||||
#endif /* ETHERNETIF_H_INCLUDED */
|
||||
|
|
|
@ -423,34 +423,18 @@ bool ethernetif_input(void * pvParameters)
|
|||
struct netif *netif = (struct netif *)pvParameters;
|
||||
struct pbuf *p;
|
||||
|
||||
#ifdef FREERTOS_USED
|
||||
for( ;; ) {
|
||||
do {
|
||||
#endif
|
||||
/* move received packet into a new pbuf */
|
||||
p = low_level_input( netif );
|
||||
if( p == NULL )
|
||||
{
|
||||
#ifdef FREERTOS_USED
|
||||
/* No packet could be read. Wait a for an interrupt to tell us
|
||||
there is more data available. */
|
||||
vTaskDelay(100);
|
||||
}
|
||||
}while( p == NULL );
|
||||
#else
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
if( ERR_OK != netif->input( p, netif ) )
|
||||
{
|
||||
pbuf_free(p);
|
||||
p = NULL;
|
||||
}
|
||||
#ifdef FREERTOS_USED
|
||||
/* move received packet into a new pbuf */
|
||||
p = low_level_input( netif );
|
||||
if( p == NULL )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
if( ERR_OK != netif->input( p, netif ) )
|
||||
{
|
||||
pbuf_free(p);
|
||||
p = NULL;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -475,7 +459,7 @@ err_t ethernetif_init(struct netif *netif)
|
|||
|
||||
#if LWIP_NETIF_HOSTNAME
|
||||
/* Initialize interface hostname */
|
||||
netif->hostname = "lwip";
|
||||
// netif->hostname = "lwip"; // Unused! Duet sets hostname explicitly
|
||||
#endif /* LWIP_NETIF_HOSTNAME */
|
||||
|
||||
/*
|
||||
|
@ -517,17 +501,15 @@ err_t ethernetif_init(struct netif *netif)
|
|||
return ERR_OK;
|
||||
}
|
||||
|
||||
void RepRapNetworkSetMACAddress(const u8_t macAddress[])
|
||||
{
|
||||
size_t i;
|
||||
for (i = 0; i < 8; ++i)
|
||||
{
|
||||
gs_uc_mac_address[i] = macAddress[i];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ethernetif_set_rx_callback(emac_dev_tx_cb_t callback)
|
||||
{
|
||||
emac_dev_set_rx_callback(&gs_emac_dev, callback);
|
||||
}
|
||||
|
||||
void ethernetif_set_mac_address(const u8_t macAddress[])
|
||||
{
|
||||
for (size_t i = 0; i < 8; ++i)
|
||||
{
|
||||
gs_uc_mac_address[i] = macAddress[i];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -53,9 +53,6 @@
|
|||
/* Include user defined options first */
|
||||
#include "conf_eth.h"
|
||||
|
||||
#ifdef LWIP_DEBUG
|
||||
#include "lwip/src/include/lwip/debug.h"
|
||||
#endif
|
||||
|
||||
/* ---------- System options ---------- */
|
||||
/* Specify NO_SYS because we are not using an RTOS */
|
||||
|
@ -101,10 +98,10 @@ a lot of data that needs to be copied, this should be set high. */
|
|||
#define UDP_TTL 255
|
||||
/* MEMP_NUM_UDP_PCB: the number of UDP protocol control blocks. One
|
||||
per active UDP "connection". */
|
||||
#define MEMP_NUM_UDP_PCB 1
|
||||
#define MEMP_NUM_UDP_PCB 2
|
||||
|
||||
/* MEMP_NUM_TCP_PCB: the number of simultaneously active TCP connections. */
|
||||
#define MEMP_NUM_TCP_PCB 12
|
||||
#define MEMP_NUM_TCP_PCB 16
|
||||
/* MEMP_NUM_TCP_PCB_LISTEN: the number of listening TCP connections. */
|
||||
#define MEMP_NUM_TCP_PCB_LISTEN 4
|
||||
/* MEMP_NUM_TCP_SEG: the number of simultaneously queued TCP segments. */
|
||||
|
@ -268,11 +265,4 @@ a lot of data that needs to be copied, this should be set high. */
|
|||
|
||||
// \note For a list of all possible lwIP configurations, check http://lwip.wikia.com/wiki/Lwipopts.h
|
||||
|
||||
/** EMAC PHY address */
|
||||
#define BOARD_EMAC_PHY_ADDR 2
|
||||
/*! EMAC RMII mode */
|
||||
#define BOARD_EMAC_MODE_RMII 1
|
||||
|
||||
/**/
|
||||
|
||||
#endif /* __LWIPOPTS_H__ */
|
334
Move.cpp
334
Move.cpp
|
@ -7,242 +7,6 @@
|
|||
|
||||
#include "RepRapFirmware.h"
|
||||
|
||||
void DeltaParameters::Init()
|
||||
{
|
||||
deltaMode = false;
|
||||
diagonal = 0.0;
|
||||
radius = 0.0;
|
||||
printRadius = defaultPrintRadius;
|
||||
homedHeight = defaultDeltaHomedHeight;
|
||||
isEquilateral = true;
|
||||
|
||||
for (size_t axis = 0; axis < AXES; ++axis)
|
||||
{
|
||||
endstopAdjustments[axis] = 0.0;
|
||||
towerX[axis] = towerY[axis] = 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
void DeltaParameters::SetRadius(float r)
|
||||
{
|
||||
radius = r;
|
||||
isEquilateral = true;
|
||||
|
||||
const float cos30 = sqrtf(3.0)/2.0;
|
||||
const float sin30 = 0.5;
|
||||
|
||||
towerX[A_AXIS] = -(r * cos30);
|
||||
towerX[B_AXIS] = r * cos30;
|
||||
towerX[C_AXIS] = 0.0;
|
||||
|
||||
towerY[A_AXIS] = towerY[B_AXIS] = -(r * sin30);
|
||||
towerY[C_AXIS] = r;
|
||||
|
||||
Recalc();
|
||||
}
|
||||
|
||||
void DeltaParameters::Recalc()
|
||||
{
|
||||
deltaMode = (radius > 0.0 && diagonal > radius);
|
||||
if (deltaMode)
|
||||
{
|
||||
Xbc = towerX[C_AXIS] - towerX[B_AXIS];
|
||||
Xca = towerX[A_AXIS] - towerX[C_AXIS];
|
||||
Xab = towerX[B_AXIS] - towerX[A_AXIS];
|
||||
Ybc = towerY[C_AXIS] - towerY[B_AXIS];
|
||||
Yca = towerY[A_AXIS] - towerY[C_AXIS];
|
||||
Yab = towerY[B_AXIS] - towerY[A_AXIS];
|
||||
coreFa = fsquare(towerX[A_AXIS]) + fsquare(towerY[A_AXIS]);
|
||||
coreFb = fsquare(towerX[B_AXIS]) + fsquare(towerY[B_AXIS]);
|
||||
coreFc = fsquare(towerX[C_AXIS]) + fsquare(towerY[C_AXIS]);
|
||||
Q = 2 * (Xca * Yab - Xab * Yca);
|
||||
Q2 = fsquare(Q);
|
||||
D2 = fsquare(diagonal);
|
||||
|
||||
// Calculate the base carriage height when the printer is homed.
|
||||
const float tempHeight = diagonal; // any sensible height will do here, probably even zero
|
||||
float machinePos[AXES];
|
||||
InverseTransform(tempHeight + endstopAdjustments[X_AXIS], tempHeight + endstopAdjustments[Y_AXIS], tempHeight + endstopAdjustments[X_AXIS],
|
||||
machinePos);
|
||||
homedCarriageHeight = homedHeight + tempHeight - machinePos[Z_AXIS];
|
||||
}
|
||||
}
|
||||
|
||||
// Make the average of the endstop adjustments zero, without changing the individual homed carriage heights
|
||||
void DeltaParameters::NormaliseEndstopAdjustments()
|
||||
{
|
||||
const float eav = (endstopAdjustments[A_AXIS] + endstopAdjustments[B_AXIS] + endstopAdjustments[C_AXIS])/3.0;
|
||||
endstopAdjustments[A_AXIS] -= eav;
|
||||
endstopAdjustments[B_AXIS] -= eav;
|
||||
endstopAdjustments[C_AXIS] -= eav;
|
||||
homedHeight += eav;
|
||||
homedCarriageHeight += eav; // no need for a full recalc, this is sufficient
|
||||
}
|
||||
|
||||
// Calculate the motor position for a single tower from a Cartesian coordinate
|
||||
float DeltaParameters::Transform(const float machinePos[AXES], size_t axis) const
|
||||
{
|
||||
return machinePos[Z_AXIS]
|
||||
+ sqrt(D2 - fsquare(machinePos[X_AXIS] - towerX[axis]) - fsquare(machinePos[Y_AXIS] - towerY[axis]));
|
||||
}
|
||||
|
||||
void DeltaParameters::InverseTransform(float Ha, float Hb, float Hc, float machinePos[AXES]) const
|
||||
{
|
||||
const float Fa = coreFa + fsquare(Ha);
|
||||
const float Fb = coreFb + fsquare(Hb);
|
||||
const float Fc = coreFc + fsquare(Hc);
|
||||
|
||||
// debugPrintf("Ha=%f Hb=%f Hc=%f Fa=%f Fb=%f Fc=%f Xbc=%f Xca=%f Xab=%f Ybc=%f Yca=%f Yab=%f\n",
|
||||
// Ha, Hb, Hc, Fa, Fb, Fc, Xbc, Xca, Xab, Ybc, Yca, Yab);
|
||||
|
||||
// Setup PQRSU such that x = -(S - uz)/P, y = (P - Rz)/Q
|
||||
const float P = (Xbc * Fa) + (Xca * Fb) + (Xab * Fc);
|
||||
const float S = (Ybc * Fa) + (Yca * Fb) + (Yab * Fc);
|
||||
|
||||
const float R = 2 * ((Xbc * Ha) + (Xca * Hb) + (Xab * Hc));
|
||||
const float U = 2 * ((Ybc * Ha) + (Yca * Hb) + (Yab * Hc));
|
||||
|
||||
// debugPrintf("P= %f R=%f S=%f U=%f Q=%f\n", P, R, S, U, Q);
|
||||
|
||||
const float R2 = fsquare(R), U2 = fsquare(U);
|
||||
|
||||
float A = U2 + R2 + Q2;
|
||||
float minusHalfB = S * U + P * R + Ha * Q2 + towerX[A_AXIS] * U * Q - towerY[A_AXIS] * R * Q;
|
||||
float C = fsquare(S + towerX[A_AXIS] * Q) + fsquare(P - towerY[A_AXIS] * Q) + (fsquare(Ha) - D2) * Q2;
|
||||
|
||||
// debugPrintf("A=%f minusHalfB=%f C=%f\n", A, minusHalfB, C);
|
||||
|
||||
float z = (minusHalfB - sqrtf(fsquare(minusHalfB) - A * C)) / A;
|
||||
machinePos[X_AXIS] = (U * z - S) / Q;
|
||||
machinePos[Y_AXIS] = (P - R * z) / Q;
|
||||
machinePos[Z_AXIS] = z;
|
||||
}
|
||||
|
||||
// Compute the derivative of height with respect to a parameter at the specified motor endpoints.
|
||||
// 'deriv' indicates the parameter as follows:
|
||||
// 0, 1, 2 = X, Y, Z tower endstop adjustments
|
||||
// 3, 4 = X, Y tower X position
|
||||
// 5 = Z tower Y position
|
||||
// 6 = diagonal rod length
|
||||
// 7 = delta radius (only if isEquilateral is true)
|
||||
float DeltaParameters::ComputeDerivative(unsigned int deriv, float ha, float hb, float hc)
|
||||
{
|
||||
const float perturb = 0.2; // perturbation amount in mm
|
||||
DeltaParameters hiParams(*this), loParams(*this);
|
||||
switch(deriv)
|
||||
{
|
||||
case 0:
|
||||
case 1:
|
||||
case 2:
|
||||
break;
|
||||
|
||||
case 3:
|
||||
case 4:
|
||||
hiParams.towerX[deriv - 3] += perturb;
|
||||
loParams.towerX[deriv - 3] -= perturb;
|
||||
break;
|
||||
|
||||
case 5:
|
||||
{
|
||||
const float yAdj = perturb * (1.0/3.0);
|
||||
hiParams.towerY[A_AXIS] -= yAdj;
|
||||
hiParams.towerY[B_AXIS] -= yAdj;
|
||||
hiParams.towerY[C_AXIS] += (perturb - yAdj);
|
||||
loParams.towerY[A_AXIS] += yAdj;
|
||||
loParams.towerY[B_AXIS] += yAdj;
|
||||
loParams.towerY[C_AXIS] -= (perturb - yAdj);
|
||||
}
|
||||
break;
|
||||
|
||||
case 6:
|
||||
hiParams.diagonal += perturb;
|
||||
loParams.diagonal -= perturb;
|
||||
break;
|
||||
|
||||
case 7:
|
||||
hiParams.SetRadius(radius + perturb);
|
||||
loParams.SetRadius(radius - perturb);
|
||||
break;
|
||||
}
|
||||
|
||||
hiParams.Recalc();
|
||||
loParams.Recalc();
|
||||
|
||||
float newPos[AXES];
|
||||
hiParams.InverseTransform((deriv == 0) ? ha + perturb : ha, (deriv == 1) ? hb + perturb : hb, (deriv == 2) ? hc + perturb : hc, newPos);
|
||||
float zHi = newPos[Z_AXIS];
|
||||
loParams.InverseTransform((deriv == 0) ? ha - perturb : ha, (deriv == 1) ? hb - perturb : hb, (deriv == 2) ? hc - perturb : hc, newPos);
|
||||
float zLo = newPos[Z_AXIS];
|
||||
|
||||
return (zHi - zLo)/(2 * perturb);
|
||||
}
|
||||
|
||||
// Perform 3, 4, 6 or 7-factor adjustment.
|
||||
// The input vector contains the following parameters in this order:
|
||||
// X, Y and Z endstop adjustments
|
||||
// If we are doing 4-factor adjustment, the next argument is the delta radius. Otherwise:
|
||||
// X tower X position adjustment
|
||||
// Y tower X position adjustment
|
||||
// Z tower Y position adjustment
|
||||
// Diagonal rod length adjustment
|
||||
void DeltaParameters::Adjust(size_t numFactors, const float v[])
|
||||
{
|
||||
const float oldCarriageHeightA = GetHomedCarriageHeight(A_AXIS); // save for later
|
||||
|
||||
// Update endstop adjustments
|
||||
endstopAdjustments[A_AXIS] += v[0];
|
||||
endstopAdjustments[B_AXIS] += v[1];
|
||||
endstopAdjustments[C_AXIS] += v[2];
|
||||
NormaliseEndstopAdjustments();
|
||||
|
||||
if (numFactors == 4)
|
||||
{
|
||||
// 4-factor adjustment, so update delta radius
|
||||
SetRadius(radius + v[3]); // this sets isEquilateral true, recalculates tower positions, then calls Recalc()
|
||||
}
|
||||
else if (numFactors > 3)
|
||||
{
|
||||
// 6- or 7-factor adjustment
|
||||
towerX[A_AXIS] += v[3];
|
||||
towerX[B_AXIS] += v[4];
|
||||
|
||||
const float yAdj = v[5] * (1.0/3.0);
|
||||
towerY[A_AXIS] -= yAdj;
|
||||
towerY[B_AXIS] -= yAdj;
|
||||
towerY[C_AXIS] += (v[5] - yAdj);
|
||||
isEquilateral = false;
|
||||
|
||||
if (numFactors == 7)
|
||||
{
|
||||
diagonal += v[6];
|
||||
}
|
||||
|
||||
Recalc();
|
||||
}
|
||||
|
||||
// Adjusting the diagonal and the tower positions affects the homed carriage height.
|
||||
// We need to adjust homedHeight to allow for this, to get the change that was requested in the endstop corrections.
|
||||
const float heightError = GetHomedCarriageHeight(A_AXIS) - oldCarriageHeightA - v[0];
|
||||
homedHeight -= heightError;
|
||||
homedCarriageHeight -= heightError;
|
||||
}
|
||||
|
||||
void DeltaParameters::PrintParameters(StringRef& reply, bool full)
|
||||
{
|
||||
reply.printf("Endstops X%.2f Y%.2f Z%.2f, height %.2f, diagonal %.2f, ",
|
||||
endstopAdjustments[A_AXIS], endstopAdjustments[B_AXIS], endstopAdjustments[C_AXIS], homedHeight, diagonal);
|
||||
if (isEquilateral && !full)
|
||||
{
|
||||
reply.catf("radius %.2f\n", radius);
|
||||
}
|
||||
else
|
||||
{
|
||||
reply.catf("towers (%.2f,%.2f) (%.2f,%.2f) (%.2f,%.2f)\n",
|
||||
towerX[A_AXIS], towerY[A_AXIS], towerX[B_AXIS], towerY[B_AXIS], towerX[C_AXIS], towerY[C_AXIS]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Move::Move(Platform* p, GCodes* g) : currentDda(NULL)
|
||||
{
|
||||
active = false;
|
||||
|
@ -265,6 +29,7 @@ void Move::Init()
|
|||
// Reset Cartesian mode
|
||||
deltaParams.Init();
|
||||
coreXYMode = 0;
|
||||
deltaProbing = false;
|
||||
|
||||
// Empty the ring
|
||||
ddaRingGetPointer = ddaRingAddPointer;
|
||||
|
@ -437,7 +202,7 @@ void Move::Spin()
|
|||
ddaRingGetPointer = ddaRingGetPointer->GetNext();
|
||||
}
|
||||
}
|
||||
else
|
||||
else if (!deltaProbing)
|
||||
{
|
||||
// See whether we need to kick off a move
|
||||
DDA *cdda = currentDda; // currentDda is volatile, so copy it
|
||||
|
@ -1242,13 +1007,59 @@ float Move::SecondDegreeTransformZ(float x, float y) const
|
|||
return (1.0 - x)*(1.0 - y)*zBedProbePoints[0] + x*(1.0 - y)*zBedProbePoints[3] + (1.0 - x)*y*zBedProbePoints[1] + x*y*zBedProbePoints[2];
|
||||
}
|
||||
|
||||
static void ShortDelay()
|
||||
{
|
||||
for (unsigned int i = 0; i < 10; ++i)
|
||||
{
|
||||
asm volatile("nop");
|
||||
asm volatile("nop");
|
||||
asm volatile("nop");
|
||||
asm volatile("nop");
|
||||
asm volatile("nop");
|
||||
asm volatile("nop");
|
||||
asm volatile("nop");
|
||||
asm volatile("nop");
|
||||
asm volatile("nop");
|
||||
}
|
||||
}
|
||||
|
||||
// This is the function that's called by the timer interrupt to step the motors.
|
||||
void Move::Interrupt()
|
||||
{
|
||||
bool again = true;
|
||||
while (again && currentDda != nullptr)
|
||||
if (deltaProbing)
|
||||
{
|
||||
again = currentDda->Step();
|
||||
bool again = true;
|
||||
while (again)
|
||||
{
|
||||
if (reprap.GetPlatform()->GetZProbeResult() == EndStopHit::lowHit)
|
||||
{
|
||||
deltaProbe.Trigger();
|
||||
}
|
||||
|
||||
bool dir = deltaProbe.GetDirection();
|
||||
Platform *platform = reprap.GetPlatform();
|
||||
platform->SetDirection(X_AXIS, dir);
|
||||
platform->SetDirection(Y_AXIS, dir);
|
||||
platform->SetDirection(Z_AXIS, dir);
|
||||
ShortDelay();
|
||||
platform->StepHigh(X_AXIS);
|
||||
platform->StepHigh(Y_AXIS);
|
||||
platform->StepHigh(Z_AXIS);
|
||||
ShortDelay();
|
||||
platform->StepLow(X_AXIS);
|
||||
platform->StepLow(Y_AXIS);
|
||||
platform->StepLow(Z_AXIS);
|
||||
uint32_t tim = deltaProbe.CalcNextStepTime();
|
||||
again = (tim != 0xFFFFFFFF && platform->ScheduleInterrupt(tim + deltaProbingStartTime));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
bool again = true;
|
||||
while (again && currentDda != nullptr)
|
||||
{
|
||||
again = currentDda->Step();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1530,6 +1341,49 @@ const char* Move::GetGeometryString() const
|
|||
: "cartesian";
|
||||
}
|
||||
|
||||
// Do a delta probe returning -1 if still probing, 0 if failed, 1 if success
|
||||
int Move::DoDeltaProbe(float frequency, float amplitude, float rate, float distance)
|
||||
{
|
||||
if (deltaProbing)
|
||||
{
|
||||
if (deltaProbe.Finished())
|
||||
{
|
||||
deltaProbing = false;
|
||||
return (deltaProbe.Overran()) ? 0 : 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (currentDda != nullptr || !DDARingEmpty())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if (!deltaProbe.Init(frequency, amplitude, rate, distance))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
const uint32_t firstInterruptTime = deltaProbe.Start();
|
||||
if (firstInterruptTime != 0xFFFFFFFF)
|
||||
{
|
||||
Platform *platform = reprap.GetPlatform();
|
||||
platform->EnableDrive(X_AXIS);
|
||||
platform->EnableDrive(Y_AXIS);
|
||||
platform->EnableDrive(Z_AXIS);
|
||||
deltaProbing = true;
|
||||
iState = IdleState::busy;
|
||||
const irqflags_t flags = cpu_irq_save();
|
||||
deltaProbingStartTime = platform->GetInterruptClocks();
|
||||
if (platform->ScheduleInterrupt(firstInterruptTime + deltaProbingStartTime))
|
||||
{
|
||||
Interrupt();
|
||||
}
|
||||
cpu_irq_restore(flags);
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*static*/ void Move::PrintMatrix(const char* s, const MathMatrix<float>& m, size_t maxRows, size_t maxCols)
|
||||
{
|
||||
debugPrintf("%s\n", s);
|
||||
|
|
63
Move.h
63
Move.h
|
@ -10,6 +10,8 @@
|
|||
|
||||
#include "DDA.h"
|
||||
#include "Matrix.h"
|
||||
#include "DeltaParameters.h"
|
||||
#include "DeltaProbe.h"
|
||||
|
||||
const unsigned int DdaRingLength = 20;
|
||||
|
||||
|
@ -23,62 +25,6 @@ enum PointCoordinateSet
|
|||
probeError = 16
|
||||
};
|
||||
|
||||
// Class to hold the parameter for a delta machine.
|
||||
// Some of the values that are currently calculated on demand could be pre-calculated in Recalc() and stored instead.
|
||||
class DeltaParameters
|
||||
{
|
||||
public:
|
||||
DeltaParameters() { Init(); }
|
||||
|
||||
bool IsDeltaMode() const { return deltaMode; }
|
||||
bool IsEquilateral() const { return isEquilateral; }
|
||||
float GetDiagonal() const { return diagonal; }
|
||||
float GetRadius() const { return radius; }
|
||||
float GetPrintRadius() const { return printRadius; }
|
||||
float GetTowerX(size_t axis) const { return towerX[axis]; }
|
||||
float GetTowerY(size_t axis) const { return towerY[axis]; }
|
||||
float GetEndstopAdjustment(size_t axis) const { return endstopAdjustments[axis]; }
|
||||
float GetHomedCarriageHeight(size_t axis) const { return homedCarriageHeight + endstopAdjustments[axis]; }
|
||||
float GetPrintRadiusSquared() const { return printRadiusSquared; }
|
||||
|
||||
void Init();
|
||||
void SetDiagonal(float d) { diagonal = d; Recalc(); }
|
||||
void SetRadius(float r);
|
||||
void SetEndstopAdjustment(size_t axis, float x) { endstopAdjustments[axis] = x; }
|
||||
void SetPrintRadius(float r) { printRadius = r; printRadiusSquared = r * r; }
|
||||
float GetHomedHeight() const { return homedHeight; }
|
||||
void SetHomedHeight(float h) { homedHeight = h; Recalc(); }
|
||||
|
||||
float Transform(const float machinePos[AXES], size_t axis) const; // Calculate the motor position for a single tower from a Cartesian coordinate
|
||||
void InverseTransform(float Ha, float Hb, float Hc, float machinePos[AXES]) const; // Calculate the Cartesian position from the motor positions
|
||||
|
||||
float ComputeDerivative(unsigned int deriv, float ha, float hb, float hc); // Compute the derivative of height with respect to a parameter at a set of motor endpoints
|
||||
void Adjust(size_t numFactors, const float v[]); // Perform 4-, 6- or 7-factor adjustment
|
||||
void PrintParameters(StringRef& reply, bool full);
|
||||
|
||||
private:
|
||||
void Recalc();
|
||||
void NormaliseEndstopAdjustments(); // Make the average of the endstop adjustments zero
|
||||
|
||||
// Core parameters
|
||||
float diagonal; // The diagonal rod length, all 3 are assumed to be the same length
|
||||
float radius; // The nominal delta radius, before any fine tuning of tower positions
|
||||
float towerX[AXES]; // The X coordinate of each tower
|
||||
float towerY[AXES]; // The Y coordinate of each tower
|
||||
float endstopAdjustments[AXES]; // How much above or below the ideal position each endstop is
|
||||
float printRadius;
|
||||
float homedHeight;
|
||||
|
||||
// Derived values
|
||||
bool deltaMode; // True if this is a delta printer
|
||||
bool isEquilateral; // True if the towers are at the corners of an equilateral triangle
|
||||
float printRadiusSquared;
|
||||
float homedCarriageHeight;
|
||||
float Xbc, Xca, Xab, Ybc, Yca, Yab;
|
||||
float coreFa, coreFb, coreFc;
|
||||
float Q, Q2, D2;
|
||||
};
|
||||
|
||||
/**
|
||||
* This is the master movement class. It controls all movement in the machine.
|
||||
*/
|
||||
|
@ -143,6 +89,8 @@ public:
|
|||
FilePosition PausePrint(float positions[DRIVES+1]); // Pause the print as soon as we can
|
||||
bool NoLiveMovement() const; // Is a move running, or are there any queued?
|
||||
|
||||
int DoDeltaProbe(float frequency, float amplitude, float rate, float distance);
|
||||
|
||||
static int32_t MotorEndPointToMachine(size_t drive, float coord); // Convert a single motor position to number of steps
|
||||
static float MotorEndpointToPosition(int32_t endpoint, size_t drive); // Convert number of motor steps to motor position
|
||||
|
||||
|
@ -202,6 +150,9 @@ private:
|
|||
IdleState iState; // whether the idle timer is active
|
||||
|
||||
DeltaParameters deltaParams; // Information about the delta parameters of this machine
|
||||
DeltaProbe deltaProbe; // Delta probing state
|
||||
uint32_t deltaProbingStartTime;
|
||||
bool deltaProbing;
|
||||
int coreXYMode; // 0 = Cartesian, 1 = CoreXY, 2 = CoreXZ, 3 = CoreYZ
|
||||
};
|
||||
|
||||
|
|
46
Network.cpp
46
Network.cpp
|
@ -49,8 +49,7 @@ extern "C"
|
|||
{
|
||||
#include "lwipopts.h"
|
||||
#include "lwip/src/include/lwip/tcp.h"
|
||||
|
||||
void RepRapNetworkSetMACAddress(const u8_t macAddress[]);
|
||||
#include "contrib/apps/netbios/netbios.h"
|
||||
}
|
||||
|
||||
static tcp_pcb *http_pcb = NULL;
|
||||
|
@ -326,23 +325,24 @@ Network::Network(Platform* p)
|
|||
freeTransactions(NULL), readyTransactions(NULL), writingTransactions(NULL),
|
||||
dataCs(NULL), ftpCs(NULL), telnetCs(NULL), freeSendBuffers(NULL), freeConnections(NULL)
|
||||
{
|
||||
for (unsigned int i = 0; i < networkTransactionCount; i++)
|
||||
for (size_t i = 0; i < networkTransactionCount; i++)
|
||||
{
|
||||
freeTransactions = new NetworkTransaction(freeTransactions);
|
||||
}
|
||||
|
||||
for (unsigned int i = 0; i < tcpOutputBufferCount; i++)
|
||||
for (size_t i = 0; i < tcpOutputBufferCount; i++)
|
||||
{
|
||||
freeSendBuffers = new SendBuffer(freeSendBuffers);
|
||||
}
|
||||
|
||||
for (unsigned int i = 0; i < numConnections; i++)
|
||||
for (size_t i = 0; i < numConnections; i++)
|
||||
{
|
||||
ConnectionState *cs = new ConnectionState;
|
||||
cs->next = freeConnections;
|
||||
freeConnections = cs;
|
||||
}
|
||||
|
||||
strcpy(hostname, HOSTNAME);
|
||||
ethPinsInit();
|
||||
}
|
||||
|
||||
|
@ -369,8 +369,7 @@ void Network::Init()
|
|||
platform->Message(HOST_MESSAGE, "Attempting to start the network when it is disabled.\n");
|
||||
return;
|
||||
}
|
||||
RepRapNetworkSetMACAddress(platform->MACAddress());
|
||||
init_ethernet();
|
||||
init_ethernet(platform->MACAddress(), hostname);
|
||||
longWait = platform->Time();
|
||||
state = NetworkInitializing;
|
||||
}
|
||||
|
@ -426,12 +425,13 @@ void Network::Spin()
|
|||
}
|
||||
else if (state == NetworkInitializing && establish_ethernet_link())
|
||||
{
|
||||
set_dhcp_hostname(reprap.GetName());
|
||||
start_ethernet(platform->IPAddress(), platform->NetMask(), platform->GateWay());
|
||||
ethernet_set_rx_callback(&emac_read_packet);
|
||||
|
||||
httpd_init();
|
||||
ftpd_init();
|
||||
telnetd_init();
|
||||
ethernet_set_rx_callback(&emac_read_packet);
|
||||
netbios_init();
|
||||
state = NetworkActive;
|
||||
}
|
||||
|
||||
|
@ -1039,6 +1039,34 @@ bool Network::AcquireTransaction(ConnectionState *cs)
|
|||
return true;
|
||||
}
|
||||
|
||||
// Set the DHCP hostname. Removes all whitespaces and converts the name to lower-case.
|
||||
void Network::SetHostname(const char *name)
|
||||
{
|
||||
size_t i = 0;
|
||||
while (*name && i < ARRAY_UPB(hostname))
|
||||
{
|
||||
char c = *name++;
|
||||
if (c >= 'A' && c <= 'Z')
|
||||
{
|
||||
c += 'a' - 'A';
|
||||
}
|
||||
|
||||
if ((c >= 'a' && c <= 'z') || (c >= '0' && c <= '9') || (c == '-') || (c == '_'))
|
||||
{
|
||||
hostname[i++] = c;
|
||||
}
|
||||
}
|
||||
|
||||
if (i)
|
||||
{
|
||||
hostname[i] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
strcpy(hostname, HOSTNAME);
|
||||
}
|
||||
}
|
||||
|
||||
// Initialise a ConnectionState for a new connection
|
||||
void ConnectionState::Init(tcp_pcb *p)
|
||||
{
|
||||
|
|
|
@ -38,6 +38,7 @@ const float writeTimeout = 4.0; // seconds to wait for data we have writ
|
|||
#define IP_ADDRESS {192, 168, 1, 10} // Need some sort of default...
|
||||
#define NET_MASK {255, 255, 255, 0}
|
||||
#define GATE_WAY {192, 168, 1, 1}
|
||||
#define HOSTNAME "duet"
|
||||
|
||||
|
||||
/****************************************************************************************************/
|
||||
|
@ -183,6 +184,8 @@ public:
|
|||
void SetHttpPort(uint16_t port);
|
||||
uint16_t GetHttpPort() const;
|
||||
|
||||
void SetHostname(const char *name);
|
||||
|
||||
private:
|
||||
|
||||
Platform* platform;
|
||||
|
@ -202,6 +205,7 @@ private:
|
|||
enum { NetworkInactive, NetworkInitializing, NetworkActive } state;
|
||||
bool isEnabled;
|
||||
bool volatile readingData;
|
||||
char hostname[16]; // limit DHCP hostname to 15 characters + terminating 0
|
||||
|
||||
ConnectionState *dataCs;
|
||||
ConnectionState *ftpCs;
|
||||
|
|
112
Platform.cpp
112
Platform.cpp
|
@ -240,7 +240,7 @@ void Platform::Init()
|
|||
SetElasticComp(drive, 0.0);
|
||||
if (drive <= AXES)
|
||||
{
|
||||
endStopType[drive] = lowEndStop; // assume all endstops are low endstops
|
||||
endStopType[drive] = EndStopType::lowEndStop; // assume all endstops are low endstops
|
||||
endStopLogicLevel[drive] = true;
|
||||
}
|
||||
}
|
||||
|
@ -337,6 +337,9 @@ void Platform::InitZProbe()
|
|||
pinModeNonDue(endStopPins[E0_AXIS], INPUT_PULLUP);
|
||||
break;
|
||||
|
||||
case 5:
|
||||
break; //TODO
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -375,6 +378,8 @@ int Platform::ZProbe() const
|
|||
// Because of noise, it is possible to get a negative reading, so allow for this.
|
||||
return (int) (((int32_t) zProbeOnFilter.GetSum() - (int32_t) zProbeOffFilter.GetSum())
|
||||
/ (int)(4 * numZProbeReadingsAveraged));
|
||||
case 5:
|
||||
return (int) ((zProbeOnFilter.GetSum() + zProbeOffFilter.GetSum()) / (8 * numZProbeReadingsAveraged)); //TODO this is temporary
|
||||
|
||||
default:
|
||||
break;
|
||||
|
@ -436,6 +441,7 @@ float Platform::ZProbeStopHeight() const
|
|||
case 2:
|
||||
return nvData.irZProbeParameters.GetStopHeight(GetTemperature(0));
|
||||
case 3:
|
||||
case 5:
|
||||
return nvData.alternateZProbeParameters.GetStopHeight(GetTemperature(0));
|
||||
default:
|
||||
return 0;
|
||||
|
@ -450,6 +456,7 @@ float Platform::GetZProbeDiveHeight() const
|
|||
case 2:
|
||||
return nvData.irZProbeParameters.diveHeight;
|
||||
case 3:
|
||||
case 5:
|
||||
return nvData.alternateZProbeParameters.diveHeight;
|
||||
case 4:
|
||||
return nvData.switchZProbeParameters.diveHeight;
|
||||
|
@ -467,6 +474,7 @@ void Platform::SetZProbeDiveHeight(float h)
|
|||
nvData.irZProbeParameters.diveHeight = h;
|
||||
break;
|
||||
case 3:
|
||||
case 5:
|
||||
nvData.alternateZProbeParameters.diveHeight = h;
|
||||
break;
|
||||
case 4:
|
||||
|
@ -479,7 +487,7 @@ void Platform::SetZProbeDiveHeight(float h)
|
|||
|
||||
void Platform::SetZProbeType(int pt)
|
||||
{
|
||||
int newZProbeType = (pt >= 0 && pt <= 4) ? pt : 0;
|
||||
int newZProbeType = (pt >= 0 && pt <= 5) ? pt : 0;
|
||||
if (newZProbeType != nvData.zProbeType)
|
||||
{
|
||||
nvData.zProbeType = newZProbeType;
|
||||
|
@ -503,6 +511,7 @@ const ZProbeParameters& Platform::GetZProbeParameters() const
|
|||
case 2:
|
||||
return nvData.irZProbeParameters;
|
||||
case 3:
|
||||
case 5:
|
||||
return nvData.alternateZProbeParameters;
|
||||
}
|
||||
}
|
||||
|
@ -534,6 +543,7 @@ bool Platform::SetZProbeParameters(const struct ZProbeParameters& params)
|
|||
}
|
||||
return true;
|
||||
case 3:
|
||||
case 5:
|
||||
if (nvData.alternateZProbeParameters != params)
|
||||
{
|
||||
nvData.alternateZProbeParameters = params;
|
||||
|
@ -730,41 +740,49 @@ void Platform::Spin()
|
|||
|
||||
void Platform::SoftwareReset(uint16_t reason)
|
||||
{
|
||||
if (reason != SoftwareResetReason::user)
|
||||
if (reason == SoftwareResetReason::erase)
|
||||
{
|
||||
if (line->inWrite)
|
||||
{
|
||||
reason |= SoftwareResetReason::inUsbOutput; // if we are resetting because we are stuck in a Spin function, record whether we are trying to send to USB
|
||||
}
|
||||
if (reprap.GetNetwork()->InLwip())
|
||||
{
|
||||
reason |= SoftwareResetReason::inLwipSpin;
|
||||
}
|
||||
if (aux->inWrite)
|
||||
{
|
||||
reason |= SoftwareResetReason::inAuxOutput; // if we are resetting because we are stuck in a Spin function, record whether we are trying to send to aux
|
||||
}
|
||||
}
|
||||
reason |= reprap.GetSpinningModule();
|
||||
|
||||
// Record the reason for the software reset
|
||||
SoftwareResetData temp;
|
||||
temp.magic = SoftwareResetData::magicValue;
|
||||
temp.resetReason = reason;
|
||||
GetStackUsage(NULL, NULL, &temp.neverUsedRam);
|
||||
if (reason != SoftwareResetReason::user)
|
||||
{
|
||||
strncpy(temp.lastMessage, messageString.Pointer(), sizeof(temp.lastMessage) - 1);
|
||||
temp.lastMessage[sizeof(temp.lastMessage) - 1] = 0;
|
||||
}
|
||||
cpu_irq_disable();
|
||||
flash_unlock(0x00080000, 0x000FFFFF, nullptr, nullptr);
|
||||
flash_clear_gpnvm(1); // tell the system to boot from flash next time
|
||||
}
|
||||
else
|
||||
{
|
||||
temp.lastMessage[0] = 0;
|
||||
if (reason != SoftwareResetReason::user)
|
||||
{
|
||||
if (line->inWrite)
|
||||
{
|
||||
reason |= SoftwareResetReason::inUsbOutput; // if we are resetting because we are stuck in a Spin function, record whether we are trying to send to USB
|
||||
}
|
||||
if (reprap.GetNetwork()->InLwip())
|
||||
{
|
||||
reason |= SoftwareResetReason::inLwipSpin;
|
||||
}
|
||||
if (aux->inWrite)
|
||||
{
|
||||
reason |= SoftwareResetReason::inAuxOutput; // if we are resetting because we are stuck in a Spin function, record whether we are trying to send to aux
|
||||
}
|
||||
}
|
||||
reason |= reprap.GetSpinningModule();
|
||||
|
||||
// Record the reason for the software reset
|
||||
SoftwareResetData temp;
|
||||
temp.magic = SoftwareResetData::magicValue;
|
||||
temp.resetReason = reason;
|
||||
GetStackUsage(NULL, NULL, &temp.neverUsedRam);
|
||||
if (reason != SoftwareResetReason::user)
|
||||
{
|
||||
strncpy(temp.lastMessage, messageString.Pointer(), sizeof(temp.lastMessage) - 1);
|
||||
temp.lastMessage[sizeof(temp.lastMessage) - 1] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
temp.lastMessage[0] = 0;
|
||||
}
|
||||
|
||||
// Save diagnostics data to Flash and reset the software
|
||||
DueFlashStorage::write(SoftwareResetData::nvAddress, &temp, sizeof(SoftwareResetData));
|
||||
}
|
||||
|
||||
// Save diagnostics data to Flash and reset the software
|
||||
DueFlashStorage::write(SoftwareResetData::nvAddress, &temp, sizeof(SoftwareResetData));
|
||||
|
||||
rstc_start_software_reset(RSTC);
|
||||
for(;;) {}
|
||||
}
|
||||
|
@ -1190,14 +1208,14 @@ EndStopHit Platform::Stopped(size_t drive) const
|
|||
return GetZProbeResult(); // using the Z probe as am endstop for this axis, so just get its result
|
||||
}
|
||||
|
||||
if (endStopPins[drive] >= 0 && endStopType[drive] != noEndStop)
|
||||
if (endStopPins[drive] >= 0 && endStopType[drive] != EndStopType::noEndStop)
|
||||
{
|
||||
if (digitalReadNonDue(endStopPins[drive]) == ((endStopLogicLevel[drive]) ? 1 : 0))
|
||||
{
|
||||
return (endStopType[drive] == highEndStop) ? highHit : lowHit;
|
||||
return (endStopType[drive] == EndStopType::highEndStop) ? EndStopHit::highHit : EndStopHit::lowHit;
|
||||
}
|
||||
}
|
||||
return noStop;
|
||||
return EndStopHit::noStop;
|
||||
}
|
||||
|
||||
// Return the Z probe result. We assume that if the Z probe is used as an endstop, it is used as the low stop.
|
||||
|
@ -1208,9 +1226,9 @@ EndStopHit Platform::GetZProbeResult() const
|
|||
(nvData.zProbeType == 4) ? nvData.switchZProbeParameters.adcValue
|
||||
: (nvData.zProbeType == 3) ? nvData.alternateZProbeParameters.adcValue
|
||||
: nvData.irZProbeParameters.adcValue;
|
||||
return (zProbeVal >= zProbeADValue) ? lowHit
|
||||
: (zProbeVal * 10 >= zProbeADValue * 9) ? lowNear // if we are at/above 90% of the target value
|
||||
: noStop;
|
||||
return (zProbeVal >= zProbeADValue) ? EndStopHit::lowHit
|
||||
: (zProbeVal * 10 >= zProbeADValue * 9) ? EndStopHit::lowNear // if we are at/above 90% of the target value
|
||||
: EndStopHit::noStop;
|
||||
}
|
||||
|
||||
// This is called from the step ISR as well as other places, so keep it fast, especially in the case where the motor is already enabled
|
||||
|
@ -2094,18 +2112,18 @@ float FileStore::FractionRead() const
|
|||
return (float)GetPosition() / (float)len;
|
||||
}
|
||||
|
||||
int8_t FileStore::Status()
|
||||
uint8_t FileStore::Status()
|
||||
{
|
||||
if (!inUse)
|
||||
return nothing;
|
||||
return (uint8_t)IOStatus::nothing;
|
||||
|
||||
if (lastBufferEntry == FILE_BUF_LEN)
|
||||
return byteAvailable;
|
||||
return (uint8_t)IOStatus::byteAvailable;
|
||||
|
||||
if (bufferPointer < lastBufferEntry)
|
||||
return byteAvailable;
|
||||
return (uint8_t)IOStatus::byteAvailable;
|
||||
|
||||
return nothing;
|
||||
return (uint8_t)IOStatus::nothing;
|
||||
}
|
||||
|
||||
bool FileStore::ReadBuffer()
|
||||
|
@ -2282,11 +2300,9 @@ Line::Line(Stream& p_iface) : iface(p_iface)
|
|||
{
|
||||
}
|
||||
|
||||
int8_t Line::Status() const
|
||||
uint8_t Line::Status() const
|
||||
{
|
||||
// if(alternateInput != NULL)
|
||||
// return alternateInput->Status();
|
||||
return inputNumChars == 0 ? nothing : byteAvailable;
|
||||
return inputNumChars == 0 ? (uint8_t)IOStatus::nothing : (uint8_t)IOStatus::byteAvailable;
|
||||
}
|
||||
|
||||
// This is only ever called on initialisation, so we
|
||||
|
|
19
Platform.h
19
Platform.h
|
@ -218,7 +218,7 @@ const size_t messageStringLength = 256; // max length of a message chunk sent
|
|||
|
||||
/****************************************************************************************************/
|
||||
|
||||
enum EndStopHit
|
||||
enum class EndStopHit
|
||||
{
|
||||
noStop = 0, // no endstop hit
|
||||
lowHit = 1, // low switch hit, or Z-probe in use and above threshold
|
||||
|
@ -227,7 +227,7 @@ enum EndStopHit
|
|||
};
|
||||
|
||||
// The values of the following enumeration must tally with the definitions for the M574 command
|
||||
enum EndStopType
|
||||
enum class EndStopType
|
||||
{
|
||||
noEndStop = 0,
|
||||
lowEndStop = 1,
|
||||
|
@ -236,7 +236,7 @@ enum EndStopType
|
|||
|
||||
/***************************************************************************************************/
|
||||
|
||||
// Input and output - these are ORed into an int8_t
|
||||
// Input and output - these are ORed into a uint8_t
|
||||
// By the Status() functions of the IO classes.
|
||||
|
||||
enum IOStatus
|
||||
|
@ -255,6 +255,7 @@ namespace SoftwareResetReason
|
|||
enum
|
||||
{
|
||||
user = 0, // M999 command
|
||||
erase = 55, // special M999 command to erase firmware and reset
|
||||
inAuxOutput = 0x0800, // this bit is or'ed in if we were in aux output at the time
|
||||
stuckInSpin = 0x1000, // we got stuck in a Spin() function for too long
|
||||
inLwipSpin = 0x2000, // we got stuck in a call to LWIP for too long
|
||||
|
@ -279,7 +280,7 @@ class Line
|
|||
{
|
||||
public:
|
||||
|
||||
int8_t Status() const; // Returns OR of IOStatus
|
||||
uint8_t Status() const; // Returns OR of IOStatus
|
||||
int Read(char& b);
|
||||
void Write(char b, bool block = false);
|
||||
void Write(const char* s, bool block = false);
|
||||
|
@ -367,7 +368,7 @@ class FileStore
|
|||
{
|
||||
public:
|
||||
|
||||
int8_t Status(); // Returns OR of IOStatus
|
||||
uint8_t Status(); // Returns OR of IOStatus
|
||||
bool Read(char& b); // Read 1 byte
|
||||
int Read(char* buf, unsigned int nBytes); // Read a block of nBytes length
|
||||
bool Write(char b); // Write 1 byte
|
||||
|
@ -425,6 +426,7 @@ struct ZProbeParameters
|
|||
float calibTemperature; // the temperature at which we did the calibration
|
||||
float temperatureCoefficient; // the variation of height with bed temperature
|
||||
float diveHeight; // the dive height we use when probing
|
||||
float param1, param2; // extra parameters used by some types of probe e.g. Delta probe
|
||||
|
||||
void Init(float h)
|
||||
{
|
||||
|
@ -434,6 +436,7 @@ struct ZProbeParameters
|
|||
calibTemperature = 20.0;
|
||||
temperatureCoefficient = 0.0; // no default temperature correction
|
||||
diveHeight = DefaultZDive;
|
||||
param1 = param2 = 0.0;
|
||||
}
|
||||
|
||||
float GetStopHeight(float temperature) const
|
||||
|
@ -449,7 +452,9 @@ struct ZProbeParameters
|
|||
&& yOffset == other.yOffset
|
||||
&& calibTemperature == other.calibTemperature
|
||||
&& temperatureCoefficient == other.temperatureCoefficient
|
||||
&& diveHeight == other.diveHeight;
|
||||
&& diveHeight == other.diveHeight
|
||||
&& param1 == other.param1
|
||||
&& param2 == other.param2;
|
||||
}
|
||||
|
||||
bool operator!=(const ZProbeParameters& other) const
|
||||
|
@ -1303,7 +1308,7 @@ inline void Platform::GetEndStopConfiguration(size_t axis, EndStopType& esType,
|
|||
// This is called by the tick ISR to get the raw Z probe reading to feed to the filter
|
||||
inline uint16_t Platform::GetRawZProbeReading() const
|
||||
{
|
||||
if (nvData.zProbeType == 4)
|
||||
if (nvData.zProbeType >= 4)
|
||||
{
|
||||
bool b = (bool)digitalRead(endStopPins[E0_AXIS]);
|
||||
if (!endStopLogicLevel[AXES])
|
||||
|
|
|
@ -26,6 +26,11 @@ PrintMonitor::PrintMonitor(Platform *p, GCodes *gc) : platform(p), gCodes(gc), f
|
|||
{
|
||||
}
|
||||
|
||||
void PrintMonitor::Init()
|
||||
{
|
||||
longWait = platform->Time();
|
||||
}
|
||||
|
||||
void PrintMonitor::Spin()
|
||||
{
|
||||
if (gCodes->IsPausing() || gCodes->IsPaused() || gCodes->IsResuming())
|
||||
|
@ -135,7 +140,7 @@ void PrintMonitor::Spin()
|
|||
}
|
||||
else
|
||||
{
|
||||
for(unsigned int i=1; i<MAX_LAYER_SAMPLES; i++)
|
||||
for(size_t i=1; i<MAX_LAYER_SAMPLES; i++)
|
||||
{
|
||||
layerDurations[i - 1] = layerDurations[i];
|
||||
filamentUsagePerLayer[i - 1] = filamentUsagePerLayer[i];
|
||||
|
@ -153,7 +158,7 @@ void PrintMonitor::Spin()
|
|||
if (numLayerSamples)
|
||||
{
|
||||
avgLayerTime = 0.0;
|
||||
for(unsigned int layer=0; layer<numLayerSamples; layer++)
|
||||
for(size_t layer=0; layer<numLayerSamples; layer++)
|
||||
{
|
||||
avgLayerTime += layerDurations[layer];
|
||||
if (layer)
|
||||
|
@ -183,33 +188,29 @@ void PrintMonitor::Spin()
|
|||
}
|
||||
}
|
||||
}
|
||||
else if (printStartTime > 0.0 && reprap.GetMove()->NoLiveMovement())
|
||||
{
|
||||
currentLayer = numLayerSamples = 0;
|
||||
firstLayerDuration = firstLayerHeight = firstLayerFilament = firstLayerProgress = 0.0;
|
||||
layerEstimatedTimeLeft = printStartTime = warmUpDuration = 0.0;
|
||||
lastLayerTime = lastLayerFilament = 0.0;
|
||||
}
|
||||
platform->ClassReport(longWait);
|
||||
}
|
||||
|
||||
void PrintMonitor::Init()
|
||||
{
|
||||
longWait = platform->Time();
|
||||
}
|
||||
|
||||
void PrintMonitor::StartingFilePrint(const char* filename)
|
||||
void PrintMonitor::StartingPrint(const char* filename)
|
||||
{
|
||||
fileInfoDetected = GetFileInfo(platform->GetGCodeDir(), filename, currentFileInfo);
|
||||
strncpy(fileBeingPrinted, filename, ARRAY_SIZE(fileBeingPrinted));
|
||||
fileBeingPrinted[ARRAY_UPB(fileBeingPrinted)] = 0;
|
||||
}
|
||||
|
||||
void PrintMonitor::StartedFilePrint()
|
||||
void PrintMonitor::StartedPrint()
|
||||
{
|
||||
printStartTime = platform->Time();
|
||||
}
|
||||
|
||||
void PrintMonitor::StoppedPrint()
|
||||
{
|
||||
currentLayer = numLayerSamples = 0;
|
||||
firstLayerDuration = firstLayerHeight = firstLayerFilament = firstLayerProgress = 0.0;
|
||||
layerEstimatedTimeLeft = printStartTime = warmUpDuration = 0.0;
|
||||
lastLayerTime = lastLayerFilament = 0.0;
|
||||
}
|
||||
|
||||
bool PrintMonitor::GetFileInfo(const char *directory, const char *fileName, GcodeFileInfo& info) const
|
||||
{
|
||||
if (reprap.GetPlatform()->GetMassStorage()->PathExists(directory, fileName))
|
||||
|
@ -225,11 +226,11 @@ bool PrintMonitor::GetFileInfo(const char *directory, const char *fileName, Gcod
|
|||
info.fileSize = f->Length();
|
||||
info.objectHeight = 0.0;
|
||||
info.layerHeight = 0.0;
|
||||
info.numFilaments = DRIVES - AXES;
|
||||
info.numFilaments = 0;
|
||||
info.generatedBy[0] = 0;
|
||||
for (size_t i = 0; i < DRIVES - AXES; ++i)
|
||||
for(size_t extr=0; extr<DRIVES - AXES; extr++)
|
||||
{
|
||||
info.filamentNeeded[i] = 0.0;
|
||||
info.filamentNeeded[extr] = 0.0;
|
||||
}
|
||||
|
||||
if (info.fileSize != 0 && (StringEndsWith(fileName, ".gcode") || StringEndsWith(fileName, ".g") || StringEndsWith(fileName, ".gco") || StringEndsWith(fileName, ".gc")))
|
||||
|
@ -261,7 +262,7 @@ bool PrintMonitor::GetFileInfo(const char *directory, const char *fileName, Gcod
|
|||
nFilaments = FindFilamentUsed(buf, sizeToRead, filaments, DRIVES - AXES);
|
||||
if (nFilaments != 0 && nFilaments >= filamentsFound)
|
||||
{
|
||||
filamentsFound = min<unsigned int>(nFilaments, info.numFilaments);
|
||||
filamentsFound = nFilaments;
|
||||
for (unsigned int i = 0; i < filamentsFound; ++i)
|
||||
{
|
||||
info.filamentNeeded[i] = filaments[i];
|
||||
|
@ -374,7 +375,7 @@ bool PrintMonitor::GetFileInfo(const char *directory, const char *fileName, Gcod
|
|||
nFilaments = FindFilamentUsed(buf, sizeToScan, filaments, DRIVES - AXES);
|
||||
if (nFilaments != 0 && nFilaments >= filamentsFound)
|
||||
{
|
||||
filamentsFound = min<unsigned int>(nFilaments, info.numFilaments);
|
||||
filamentsFound = nFilaments;
|
||||
for (unsigned int i = 0; i < filamentsFound; ++i)
|
||||
{
|
||||
info.filamentNeeded[i] = filaments[i];
|
||||
|
|
|
@ -44,8 +44,9 @@ class PrintMonitor
|
|||
void Spin();
|
||||
void Init();
|
||||
|
||||
void StartingFilePrint(const char *filename); // called to indicate a file will be printed (see M23)
|
||||
void StartedFilePrint(); // called whenever a new live print starts (see M24)
|
||||
void StartingPrint(const char *filename); // called to indicate a file will be printed (see M23)
|
||||
void StartedPrint(); // called whenever a new live print starts (see M24)
|
||||
void StoppedPrint(); // called whenever a file print has stopped
|
||||
|
||||
bool GetFileInfo(const char *directory, const char *fileName, GcodeFileInfo& info) const;
|
||||
void GetFileInfoResponse(StringRef& response, const char* filename) const;
|
||||
|
|
BIN
Release/RepRapFirmware-1.09a-dc42.bin
Normal file
BIN
Release/RepRapFirmware-1.09a-dc42.bin
Normal file
Binary file not shown.
|
@ -1456,6 +1456,9 @@ void RepRap::SetName(const char* nm)
|
|||
{
|
||||
// Users sometimes put a tab character between the machine name and the comment, so allow for this
|
||||
CopyParameterText(nm, myName, ARRAY_SIZE(myName));
|
||||
|
||||
// Set new DHCP hostname
|
||||
network->SetHostname(myName);
|
||||
}
|
||||
|
||||
// Given that we want to extrude/etract the specified extruder drives, check if they are allowed.
|
||||
|
|
Reference in a new issue