Version 1.04e

Fixed bed probing issue in version 1.04d
Aux port now requires checksums by default
This commit is contained in:
David Crocker 2015-04-09 12:30:16 +01:00
parent 73b2820738
commit 9d0cfcf76d
8 changed files with 67 additions and 207 deletions

View file

@ -24,8 +24,8 @@ Licence: GPL
#define CONFIGURATION_H
#define NAME "RepRapFirmware"
#define VERSION "1.04d-dc42"
#define DATE "2015-04-05"
#define VERSION "1.04e-dc42"
#define DATE "2015-04-09"
#define AUTHORS "reprappro, dc42, zpl"
#define FLASH_SAVE_ENABLED (1)

Binary file not shown.

View file

@ -73,6 +73,7 @@ void GCodes::Reset()
fileGCode->Init();
serialGCode->Init();
auxGCode->Init();
auxGCode->SetCommsProperties(1); // by default, we require a checksum on the aux port
fileMacroGCode->Init();
moveAvailable = false;
fileBeingPrinted.Close();
@ -238,18 +239,9 @@ void GCodes::Spin()
break;
case GCodeState::setBed1:
if (reprap.GetMove()->NumberOfXYProbePoints() < 3)
{
HandleReply(false, gbCurrent, "Bed probing: there needs to be 3 or more points set.\n", 'G', 32, false);
state = GCodeState::normal;
}
else
{
// zpl 2014-11-02: When calling G32, ensure bed compensation parameters are initially reset
reprap.GetMove()->SetIdentityTransform();
probeCount = 0;
state = GCodeState::setBed2;
}
// no break
case GCodeState::setBed2:
@ -262,7 +254,7 @@ void GCodes::Spin()
{
zProbesSet = true;
reprap.GetMove()->FinishedBedProbing(0, reply);
HandleReply(false, gbCurrent, nullptr, 'G', 32, false);
HandleReply(false, gbCurrent, reply.Pointer(), 'G', 32, false);
state = GCodeState::normal;
}
}
@ -3866,7 +3858,7 @@ bool GCodes::HandleMcode(GCodeBuffer* gb, StringRef& reply)
if (!seen)
{
reply.printf("Endstop adjustments X%.2f Y%.2f Z%.2f\n",
params.GetEndstopAdjustment(X_AXIS),params.GetEndstopAdjustment(Y_AXIS), params.GetEndstopAdjustment(Z_AXIS));
params.GetEndstopAdjustment(X_AXIS), params.GetEndstopAdjustment(Y_AXIS), params.GetEndstopAdjustment(Z_AXIS));
}
}
break;

View file

@ -1,128 +0,0 @@
RSEG ICODE:CODE(2)
CODE16
public isqrt
isqrt:
; Enter with R0 having low 32 bits and R1 having high 32 bits of input parameter
; Exits with R0 having 32 bit result
; Performs the following pseudo code:
; INPUT = 64 bit input
; RESIDULE = 96 bit variable
; RESULT = 32 bit accumulated result
; Clear RESULT
; Set RESIDULE = INPUT (top 32 bits will be clear)
; Do this loop 32 times:
; Loop start
; {
; RESIDULE = RESIDULE << 2
; RESULT = RESULT << 1
; if ((RESULT << 1) + 1) <= (RESIDULE >> 32) then
; { RESIDULE = RESIDULE - ((RESULT << 1) + 1) << 32
; RESULT = RESULT + 1
; }
; }
; Loop end
; Return RESULT
; For optimisation the 32 iterations are divided into 2 sets of 16 iterations. The first set can shift
; RESIDULE as a 64 bit variable, and the second shifts it as a 96 bit variable while performing
; 32 and 64 bit arithmetic operations respectively on RESIDULE.
;
; A third loop is also used if the INPUT has the top 32 bits clear (only need to iterate 16 times)
; The total number of iterations needed is in fact equal to half the number of significant bits in the input
; but the overhead required to implement only the required number of iterations would on average take more time
; than it saves.
;
; The 32 bit shifts do not need to be executed because they are achieved by operating on the appropriate
; High or Low 32 bit register
; Register usage:
; R0 = Low 32 bits of input - re-used for low 32 bits of residule
; R1 = High 32 bits of input - reused for middle 32 bits of residule
; R2 = Top 32 bits of the 96 bit residule
; R3 = Loop counter
; R4 = Result accumulator
; R5 = Potential new residule middle 32 bits
; R6 = Potential new residule top 32 bits
; R7 = zero constant - because thumb has no immediate mode for SBC instruction
push {r2,r3,r4,r5,r6,r7} ; Save registers changed (no need to save entry or exit registers)
; Set up initial variables
mov r2,#0 ; Clear residulal shift registers
mov r3,r2 ; ...
mov r4,r2 ; Clear result
mov r7,r2 ; Clear 0 constant
mov r3,#16 ; Do 16 iterations per loop
; See if we have any high bits
cmp r1,r7 ; Is high 32 bits clear?
beq Isqrt_Loop_32 ; Only need to do low 32 bits if so
Isqrt_Loop_High:
add r1,r1,r1 ; Shift the residual up 2 bits, overflowing into R2
adc r2,r2 ; ...
add r1,r1,r1 ; ...
adc r2,r2 ; ...
lsl r4,r4,#1 ; Shift accumulated result left 1 bit (this will clear the carry flag)
mov r5,r2 ; Thumb need source=destination
sbc r5,r4 ; Take potential new result +1 from shifted residual
bcc Loopback_High ; If result is already greater we don't set the bit
sub r5,r5,r4 ; R5 now has (result << 1 +1)
bcc Loopback_High ; If result is greater we don't set the bit
mov r2,r5 ; Replace if result was lower or equal
add r4,r4,#1 ; Set the bit in the result
Loopback_High: sub r3,r3,#1 ; Loop counter
bne Isqrt_Loop_High ; Loop 16 times
; R1 must now be clear (because it has been left shifted 32 times)
; Continue, this time using 64 bit arithmetic, re-using R1 for the high 32 bits (and R2 has the low 32 bits)
mov r3,#16 ; Do 16 iterations per loop
Isqrt_Loop_Low:
add r0,r0,r0 ; Shift the 64 bit residual up 2 bits (2 squared), overflowing into R1
adc r2,r2 ; ...
adc r1,r1 ; ...
add r0,r0,r0 ; ...
adc r2,r2 ; ...
adc r1,r1 ; ...
lsl r4,r4,#1 ; Shift accumulated result left 1 bit (this will clear the carry flag)
mov r5,r2 ; Thumb needs source-destination
mov r6,r1 ; Thumb needs source-destination
sbc r5,r4 ; Take potential new result +1 from shifted residual
sbc r6,r7 ; Deal with carry into top 32 bits
bcc Loopback_Low ; If result is already greater we don't set the bit
sbc r5,r4 ; Subtract result again (result << 1 +1)
sbc r6,r7 ; R5/R6 now has potential new value
bcc Loopback_Low ; If result is greater we don't set the bit
mov r2,r5 ; Replace if result was lower or equal
mov r1,r6 ; ...
add r4,r4,#1 ; Set the bit in the result
Loopback_Low: sub r3,r3,#1 ; Loop counter
bne Isqrt_Loop_Low ; Loop 16 times
mov r0,r4 ; Result back into R0
pop {r2,r3,r4,r5,r6,r7}; Recover registers
bx r14 ; Return
; This routine is used instead if the top 32 bits of the input are zero
Isqrt_Loop_32: add r0,r0,r0 ; Shift the 32 bit residual up 2 bits (2 squared), overflowing into R2
adc r2,r2 ; ...
add r0,r0,r0 ; ...
adc r2,r2 ; ...
lsl r4,r4,#1 ; Shift accumulated result left 1 bit (this will clear the carry flag)
mov r5,r2 ; Thumb need source=destination
sbc r5,r4 ; Take potential new result +1 from shifted residual
bcc Loopback_32 ; If result is already greater we don't set the bit
sub r5,r5,r4 ; R5 now has (result << 1 +1)
bcc Loopback_32 ; If result is greater we don't set the bit
mov r2,r5 ; Replace if result was lower or equal
add r4,r4,#1 ; Set the bit in the result
Loopback_32: sub r3,r3,#1 ; Loop counter
bne Isqrt_Loop_32 ; Loop 16 times
mov r0,r4 ; Result back into R0
pop {r2,r3,r4,r5,r6,r7}; Recover registers
bx r14 ; Return
END

View file

@ -775,12 +775,10 @@ void Move::InverseTransform(float xyzPoint[AXES]) const
// Do the bed transform AFTER the axis transform
void Move::BedTransform(float xyzPoint[AXES]) const
{
if (!identityBedTransform)
{
switch(NumberOfProbePoints())
switch(numBedCompensationPoints)
{
case 0:
return;
break;
case 3:
xyzPoint[Z_AXIS] = xyzPoint[Z_AXIS] + aX*xyzPoint[X_AXIS] + aY*xyzPoint[Y_AXIS] + aC;
@ -797,18 +795,15 @@ void Move::BedTransform(float xyzPoint[AXES]) const
default:
reprap.GetPlatform()->Message(BOTH_ERROR_MESSAGE, "BedTransform: wrong number of sample points.");
}
}
}
// Invert the bed transform BEFORE the axis transform
void Move::InverseBedTransform(float xyzPoint[AXES]) const
{
if (!identityBedTransform)
{
switch(NumberOfProbePoints())
switch(numBedCompensationPoints)
{
case 0:
return;
break;
case 3:
xyzPoint[Z_AXIS] = xyzPoint[Z_AXIS] - (aX*xyzPoint[X_AXIS] + aY*xyzPoint[Y_AXIS] + aC);
@ -825,12 +820,11 @@ void Move::InverseBedTransform(float xyzPoint[AXES]) const
default:
reprap.GetPlatform()->Message(BOTH_ERROR_MESSAGE, "InverseBedTransform: wrong number of sample points.");
}
}
}
void Move::SetIdentityTransform()
{
identityBedTransform = true;
numBedCompensationPoints = 0;
}
float Move::AxisCompensation(int8_t axis) const
@ -915,22 +909,23 @@ float Move::TriangleZ(float x, float y) const
// sParam is the value of the S parameter in the G30 command that provoked this call.
void Move::FinishedBedProbing(int sParam, StringRef& reply)
{
const int numPoints = NumberOfProbePoints();
if (sParam < 0)
{
// A negative sParam just prints the probe heights
reply.copy("Bed probe heights:");
float sumOfSquares = 0.0;
for (size_t i = 0; i < NumberOfProbePoints(); ++i)
for (size_t i = 0; i < numPoints; ++i)
{
reply.catf(" %.3f", zBedProbePoints[i]);
sumOfSquares += fsquare(zBedProbePoints[i]);
}
reply.catf(", RMS error: %.3f\n", sqrt(sumOfSquares/NumberOfProbePoints()));
reply.catf(", RMS error: %.3f\n", sqrt(sumOfSquares/numPoints));
}
else if (NumberOfProbePoints() < sParam)
else if (numPoints < sParam)
{
reprap.GetPlatform()->Message(BOTH_ERROR_MESSAGE,
"Bed calibration error: %d factor calibration requested but only %d points provided\n", sParam, NumberOfProbePoints());
"Bed calibration error: %d factor calibration requested but only %d points provided\n", sParam, numPoints);
}
else
{
@ -938,17 +933,17 @@ void Move::FinishedBedProbing(int sParam, StringRef& reply)
{
debugPrintf("Z probe offsets:");
float sumOfSquares = 0.0;
for (size_t i = 0; i < NumberOfProbePoints(); ++i)
for (size_t i = 0; i < numPoints; ++i)
{
debugPrintf(" %.3f", zBedProbePoints[i]);
sumOfSquares += fsquare(zBedProbePoints[i]);
}
debugPrintf(", RMS error: %.3f\n", sqrt(sumOfSquares/NumberOfProbePoints()));
debugPrintf(", RMS error: %.3f\n", sqrt(sumOfSquares/numPoints));
}
if (sParam == 0)
{
sParam = NumberOfProbePoints();
sParam = numPoints;
}
if (IsDeltaMode())
@ -992,7 +987,6 @@ void Move::SetProbedBedEquation(size_t numPoints, StringRef& reply)
aX = -a / c;
aY = -b / c;
aC = -d / c;
identityBedTransform = false;
}
break;
@ -1012,7 +1006,6 @@ void Move::SetProbedBedEquation(size_t numPoints, StringRef& reply)
*/
xRectangle = 1.0 / (xBedProbePoints[3] - xBedProbePoints[0]);
yRectangle = 1.0 / (yBedProbePoints[1] - yBedProbePoints[0]);
identityBedTransform = false;
break;
case 5:
@ -1028,7 +1021,6 @@ void Move::SetProbedBedEquation(size_t numPoints, StringRef& reply)
baryXBedProbePoints[4] = xBedProbePoints[4];
baryYBedProbePoints[4] = yBedProbePoints[4];
baryZBedProbePoints[4] = zBedProbePoints[4];
identityBedTransform = false;
break;
default:
@ -1036,8 +1028,10 @@ void Move::SetProbedBedEquation(size_t numPoints, StringRef& reply)
return;
}
numBedCompensationPoints = numPoints;
reply.copy("Bed equation fits points");
for (size_t point = 0; point < NumberOfProbePoints(); point++)
for (size_t point = 0; point < numPoints; point++)
{
reply.catf(" [%.1f, %.1f, %.3f]", xBedProbePoints[point], yBedProbePoints[point], zBedProbePoints[point]);
}
@ -1469,7 +1463,7 @@ float Move::ZBedProbePoint(int index) const
bool Move::AllProbeCoordinatesSet(int index) const
{
return probePointSet[index] == (xSet | ySet | zSet);
return (probePointSet[index] & (xSet | ySet | zSet)) == (xSet | ySet | zSet);
}
bool Move::XYProbeCoordinatesSet(int index) const

3
Move.h
View file

@ -192,8 +192,9 @@ private:
uint8_t probePointSet[MaxProbePoints]; // Has the XY of this point been set? Has the Z been probed?
float aX, aY, aC; // Bed plane explicit equation z' = z + aX*x + aY*y + aC
float tanXY, tanYZ, tanXZ; // Axis compensation - 90 degrees + angle gives angle between axes
bool identityBedTransform; // Is the bed transform in operation?
int numBedCompensationPoints; // The number of points we are actually using for bed compensation, 0 means identity bed transform
float xRectangle, yRectangle; // The side lengths of the rectangle used for second-degree bed compensation
float idleTimeout; // How long we wait with no activity before we reduce motor currents to idle
float lastMoveTime; // The approximate time at which the last move was completed, or 0
float longWait; // A long time for things that need to be done occasionally

View file

@ -132,7 +132,8 @@ void Platform::Init()
baudRates[0] = BAUD_RATE;
baudRates[1] = AUX_BAUD_RATE;
commsParams[0] = commsParams[1] = 0;
commsParams[0] = 0;
commsParams[1] = 1; // by default we require a checksum on data from the aux port, to guard against overrun errors
SerialUSB.begin(baudRates[0]);
Serial.begin(baudRates[1]); // this can't be done in the constructor because the Arduino port initialisation isn't complete at that point

Binary file not shown.