Version 1.17d+1
Save several words of stsck after a hard fault and print them in the M122 software reset report Increased the maximum step frequency before the firmware switches to double stepping Added diagnostic test for timing the square root calculation Minor firmware optimisations
This commit is contained in:
parent
f35c8cb759
commit
8f6d8e9da7
10 changed files with 111 additions and 86 deletions
|
@ -534,4 +534,5 @@
|
|||
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC"/>
|
||||
</scannerConfigBuildInfo>
|
||||
</storageModule>
|
||||
<storageModule moduleId="org.eclipse.cdt.make.core.buildtargets"/>
|
||||
</cproject>
|
||||
|
|
|
@ -1,8 +1,5 @@
|
|||
#include "RepRapFirmware.h"
|
||||
|
||||
// The remaining functions are speed-critical, so use full optimisation
|
||||
#pragma GCC optimize ("O3")
|
||||
|
||||
// Fast 62-bit integer square root function (thanks dmould)
|
||||
uint32_t isqrt64(uint64_t num)
|
||||
{
|
||||
|
@ -58,7 +55,7 @@ uint32_t isqrt64(uint64_t num)
|
|||
iter64a(14) iter64a(12) iter64a(10) iter64a(8)
|
||||
iter64a(6) iter64a(4) iter64a(2) iter64a(0)
|
||||
|
||||
// resHigh is twice the square root of the msw, in the range 0..2^17-1
|
||||
// resHigh is twice the square root of the msw, in the range 0..2^16-1 with the input restricted to 62 bits
|
||||
uint64_t numAll = ((uint64_t)numHigh << 32) | (uint32_t)num;
|
||||
|
||||
#define iter64b(N) \
|
||||
|
@ -74,7 +71,7 @@ uint32_t isqrt64(uint64_t num)
|
|||
|
||||
// We need to do 16 iterations.
|
||||
// After the last iteration, numAll may be between 0 and (1 + 2 * res) inclusive.
|
||||
// So to take square roots of numbers up to 64 bits, we need to do all these iterations using 64 bit maths.
|
||||
// So to take square roots of numbers up to 62 bits, we need to do all these iterations using 64 bit maths.
|
||||
// If we restricted the input to e.g. 48 bits, then we could do some of the final iterations using 32-bit maths.
|
||||
iter64b(30) iter64b(28) iter64b(26) iter64b(24)
|
||||
iter64b(22) iter64b(20) iter64b(18) iter64b(16)
|
||||
|
|
|
@ -838,9 +838,9 @@ void DDA::Prepare()
|
|||
dm.nextStepTime = 0;
|
||||
dm.stepInterval = 999999; // initialise to a large value so that we will calculate the time for just one step
|
||||
dm.stepsTillRecalc = 0; // so that we don't skip the calculation
|
||||
bool stepsToDo = (isDeltaMovement && drive < numAxes)
|
||||
? dm.CalcNextStepTimeDelta(*this, false)
|
||||
: dm.CalcNextStepTimeCartesian(*this, false);
|
||||
const bool stepsToDo = (isDeltaMovement && drive < numAxes)
|
||||
? dm.CalcNextStepTimeDelta(*this, false)
|
||||
: dm.CalcNextStepTimeCartesian(*this, false);
|
||||
if (stepsToDo)
|
||||
{
|
||||
InsertDM(&dm);
|
||||
|
|
|
@ -68,21 +68,22 @@ public:
|
|||
|
||||
void DebugPrint() const;
|
||||
|
||||
static const uint32_t stepClockRate = VARIANT_MCK/32; // the frequency of the clock used for stepper pulse timing, about 0.38us resolution on the Duet
|
||||
static const uint32_t stepClockRate = VARIANT_MCK/128; // the frequency of the clock used for stepper pulse timing (see Platform::InitialiseInterrupts)
|
||||
static const uint64_t stepClockRateSquared = (uint64_t)stepClockRate * stepClockRate;
|
||||
|
||||
// Note on the following constant:
|
||||
// If we calculate the step interval on every clock, we reach a point where the calculation time exceeds the step interval.
|
||||
// The worst case is pure Z movement on a delta. On a Mini Kossel with 80 steps/mm with this firmware running on a Duet (84MHx SAM3X8 processor),
|
||||
// the calculation can just be managed in time at speeds of 15000mm/min (step interval 50us), but not at 20000mm/min (step interval 37.5us).
|
||||
// Therefore, where the step interval falls below 70us, we don't calculate on every step.
|
||||
// Therefore, where the step interval falls below 60us, we don't calculate on every step.
|
||||
// Note: the above measurements were taken some time ago, before some firmware optimisations.
|
||||
#ifdef DUET_NG
|
||||
static const int32_t MinCalcIntervalDelta = (50 * stepClockRate)/1000000; // the smallest sensible interval between calculations (70us) in step timer clocks
|
||||
static const int32_t MinCalcIntervalCartesian = (50 * stepClockRate)/1000000; // same as delta for now, but could be lower
|
||||
static const int32_t MinCalcIntervalDelta = (40 * stepClockRate)/1000000; // the smallest sensible interval between calculations (40us) in step timer clocks
|
||||
static const int32_t MinCalcIntervalCartesian = (40 * stepClockRate)/1000000; // same as delta for now, but could be lower
|
||||
static const uint32_t minInterruptInterval = 6; // about 2us minimum interval between interrupts, in clocks
|
||||
#else
|
||||
static const int32_t MinCalcIntervalDelta = (70 * stepClockRate)/1000000; // the smallest sensible interval between calculations (70us) in step timer clocks
|
||||
static const int32_t MinCalcIntervalCartesian = (70 * stepClockRate)/1000000; // same as delta for now, but could be lower
|
||||
static const int32_t MinCalcIntervalDelta = (60 * stepClockRate)/1000000; // the smallest sensible interval between calculations (60us) in step timer clocks
|
||||
static const int32_t MinCalcIntervalCartesian = (60 * stepClockRate)/1000000; // same as delta for now, but could be lower
|
||||
static const uint32_t minInterruptInterval = 6; // about 2us minimum interval between interrupts, in clocks
|
||||
#endif
|
||||
|
||||
|
|
|
@ -199,7 +199,7 @@ bool DriveMovement::CalcNextStepTimeCartesianFull(const DDA &dda, bool live)
|
|||
pre(nextStep < totalSteps; stepsTillRecalc == 0)
|
||||
{
|
||||
// Work out how many steps to calculate at a time.
|
||||
uint32_t shiftFactor;
|
||||
uint32_t shiftFactor = 0; // assume single stepping
|
||||
if (stepInterval < DDA::MinCalcIntervalCartesian)
|
||||
{
|
||||
uint32_t stepsToLimit = ((nextStep <= reverseStartStep && reverseStartStep <= totalSteps)
|
||||
|
@ -218,19 +218,12 @@ pre(nextStep < totalSteps; stepsTillRecalc == 0)
|
|||
{
|
||||
shiftFactor = 1; // double stepping
|
||||
}
|
||||
else
|
||||
{
|
||||
shiftFactor = 0; // single stepping
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
shiftFactor = 0; // single stepping
|
||||
}
|
||||
|
||||
stepsTillRecalc = (1u << shiftFactor) - 1u; // store number of additional steps to generate
|
||||
|
||||
uint32_t nextCalcStep = nextStep + stepsTillRecalc;
|
||||
uint32_t lastStepTime = nextStepTime; // pick up the time of the last step
|
||||
const uint32_t nextCalcStep = nextStep + stepsTillRecalc;
|
||||
const uint32_t lastStepTime = nextStepTime; // pick up the time of the last step
|
||||
if (nextCalcStep < mp.cart.accelStopStep)
|
||||
{
|
||||
// acceleration phase
|
||||
|
@ -244,7 +237,7 @@ pre(nextStep < totalSteps; stepsTillRecalc == 0)
|
|||
else if (nextCalcStep < reverseStartStep)
|
||||
{
|
||||
// deceleration phase, not reversed yet
|
||||
uint64_t temp = mp.cart.twoCsquaredTimesMmPerStepDivA * nextCalcStep;
|
||||
const uint64_t temp = mp.cart.twoCsquaredTimesMmPerStepDivA * nextCalcStep;
|
||||
// Allow for possible rounding error when the end speed is zero or very small
|
||||
nextStepTime = (twoDistanceToStopTimesCsquaredDivA > temp)
|
||||
? topSpeedTimesCdivAPlusDecelStartClocks - isqrt64(twoDistanceToStopTimesCsquaredDivA - temp)
|
||||
|
@ -273,7 +266,7 @@ pre(nextStep < totalSteps; stepsTillRecalc == 0)
|
|||
// When the end speed is very low, calculating the time of the last step is very sensitive to rounding error.
|
||||
// So if this is the last step and it is late, bring it forward to the expected finish time.
|
||||
// Very rarely on a delta, the penultimate step may also be calculated late. Allow for that here in case it affects Cartesian axes too.
|
||||
if (nextStep == totalSteps || nextStep + 1 == totalSteps)
|
||||
if (nextStep + 1 >= totalSteps)
|
||||
{
|
||||
nextStepTime = dda.clocksNeeded;
|
||||
}
|
||||
|
@ -295,7 +288,7 @@ pre(nextStep < totalSteps; stepsTillRecalc == 0)
|
|||
{
|
||||
// Work out how many steps to calculate at a time.
|
||||
// The simulator suggests that at 200steps/mm, the minimum step pulse interval for 400mm/sec movement is 4.5us
|
||||
uint32_t shiftFactor;
|
||||
uint32_t shiftFactor = 0; // assume single stepping
|
||||
if (stepInterval < DDA::MinCalcIntervalDelta)
|
||||
{
|
||||
const uint32_t stepsToLimit = ((nextStep < reverseStartStep && reverseStartStep <= totalSteps)
|
||||
|
@ -318,15 +311,8 @@ pre(nextStep < totalSteps; stepsTillRecalc == 0)
|
|||
{
|
||||
shiftFactor = 1; // double stepping
|
||||
}
|
||||
else
|
||||
{
|
||||
shiftFactor = 0; // single stepping
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
shiftFactor = 0; // single stepping
|
||||
}
|
||||
|
||||
stepsTillRecalc = (1u << shiftFactor) - 1; // store number of additional steps to generate
|
||||
|
||||
if (nextStep == reverseStartStep)
|
||||
|
@ -339,19 +325,19 @@ pre(nextStep < totalSteps; stepsTillRecalc == 0)
|
|||
}
|
||||
|
||||
// Calculate d*s*K as an integer, where d = distance the head has travelled, s = steps/mm for this drive, K = a power of 2 to reduce the rounding errors
|
||||
if (direction)
|
||||
{
|
||||
mp.delta.hmz0sK += (int32_t)(K2 << shiftFactor);
|
||||
}
|
||||
else
|
||||
{
|
||||
mp.delta.hmz0sK -= (int32_t)(K2 << shiftFactor);
|
||||
int32_t shiftedK2 = (int32_t)(K2 << shiftFactor);
|
||||
if (!direction)
|
||||
{
|
||||
shiftedK2 = -shiftedK2;
|
||||
}
|
||||
mp.delta.hmz0sK += shiftedK2;
|
||||
}
|
||||
|
||||
const int32_t hmz0scK = (int32_t)(((int64_t)mp.delta.hmz0sK * dda.cKc)/Kc);
|
||||
const int32_t t1 = mp.delta.minusAaPlusBbTimesKs + hmz0scK;
|
||||
// Due to rounding error we can end up trying to take the square root of a negative number if we do not take precautions here
|
||||
const int64_t t2a = (int64_t)isquare64(t1) + mp.delta.dSquaredMinusAsquaredMinusBsquaredTimesKsquaredSsquared - (int64_t)isquare64(mp.delta.hmz0sK);
|
||||
const int64_t t2a = mp.delta.dSquaredMinusAsquaredMinusBsquaredTimesKsquaredSsquared - (int64_t)isquare64(mp.delta.hmz0sK) + (int64_t)isquare64(t1);
|
||||
const int32_t t2 = (t2a > 0) ? isqrt64(t2a) : 0;
|
||||
const int32_t dsK = (direction) ? t1 - t2 : t1 + t2;
|
||||
|
||||
|
@ -363,7 +349,7 @@ pre(nextStep < totalSteps; stepsTillRecalc == 0)
|
|||
return false;
|
||||
}
|
||||
|
||||
uint32_t lastStepTime = nextStepTime; // pick up the time of the last step
|
||||
const uint32_t lastStepTime = nextStepTime; // pick up the time of the last step
|
||||
if ((uint32_t)dsK < mp.delta.accelStopDsK)
|
||||
{
|
||||
// Acceleration phase
|
||||
|
@ -376,7 +362,7 @@ pre(nextStep < totalSteps; stepsTillRecalc == 0)
|
|||
}
|
||||
else
|
||||
{
|
||||
uint64_t temp = (uint64_t)mp.delta.twoCsquaredTimesMmPerStepDivAK * (uint32_t)dsK;
|
||||
const uint64_t temp = (uint64_t)mp.delta.twoCsquaredTimesMmPerStepDivAK * (uint32_t)dsK;
|
||||
// Because of possible rounding error when the end speed is zero or very small, we need to check that the square root will work OK
|
||||
nextStepTime = (temp < twoDistanceToStopTimesCsquaredDivA)
|
||||
? topSpeedTimesCdivAPlusDecelStartClocks - isqrt64(twoDistanceToStopTimesCsquaredDivA - temp)
|
||||
|
@ -391,13 +377,13 @@ pre(nextStep < totalSteps; stepsTillRecalc == 0)
|
|||
// When the end speed is very low, calculating the time of the last step is very sensitive to rounding error.
|
||||
// So if this is the last step and it is late, bring it forward to the expected finish time.
|
||||
// Very rarely, the penultimate step may be calculated late, so allow for that too.
|
||||
if (nextStep == totalSteps || nextStep + 1 == totalSteps)
|
||||
if (nextStep + 1 >= totalSteps)
|
||||
{
|
||||
nextStepTime = dda.clocksNeeded;
|
||||
}
|
||||
else
|
||||
{
|
||||
// We don't expect any step except the last to be late
|
||||
// We don't expect any steps except the last two to be late
|
||||
state = DMState::stepError;
|
||||
stepInterval = 10000000 + nextStepTime; // so we can tell what happened in the debug print
|
||||
return false;
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#include "Network.h"
|
||||
#include "RepRap.h"
|
||||
#include "Webserver.h"
|
||||
#include "Libraries/Math/Isqrt.h"
|
||||
|
||||
#include "sam/drivers/tc/tc.h"
|
||||
#include "sam/drivers/hsmci/hsmci.h"
|
||||
|
@ -145,8 +146,7 @@ extern "C"
|
|||
// Also get the program counter when the exception occurred.
|
||||
void prvGetRegistersFromStack(const uint32_t *pulFaultStackAddress)
|
||||
{
|
||||
const uint32_t pc = pulFaultStackAddress[6];
|
||||
reprap.GetPlatform()->SoftwareReset((uint16_t)SoftwareResetReason::hardFault, pc);
|
||||
reprap.GetPlatform()->SoftwareReset((uint16_t)SoftwareResetReason::hardFault, pulFaultStackAddress + 6);
|
||||
}
|
||||
|
||||
// The fault handler implementation calls a function called prvGetRegistersFromStack()
|
||||
|
@ -1219,7 +1219,8 @@ void Platform::Spin()
|
|||
ClassReport(longWait);
|
||||
}
|
||||
|
||||
void Platform::SoftwareReset(uint16_t reason, uint32_t pc)
|
||||
// Perform a software reset. 'stk' points to the program counter on the stack if the cause is an exception, otherwise it is nullptr.
|
||||
void Platform::SoftwareReset(uint16_t reason, const uint32_t *stk)
|
||||
{
|
||||
wdt_restart(WDT); // kick the watchdog
|
||||
if (reason == (uint16_t)SoftwareResetReason::erase)
|
||||
|
@ -1280,7 +1281,14 @@ void Platform::SoftwareReset(uint16_t reason, uint32_t pc)
|
|||
GetStackUsage(NULL, NULL, &srdBuf[slot].neverUsedRam);
|
||||
srdBuf[slot].hfsr = SCB->HFSR;
|
||||
srdBuf[slot].cfsr = SCB->CFSR;
|
||||
srdBuf[slot].pc = pc;
|
||||
srdBuf[slot].icsr = SCB->ICSR;
|
||||
if (stk != nullptr)
|
||||
{
|
||||
for (size_t i = 0; i < ARRAY_SIZE(srdBuf[slot].stack); ++i)
|
||||
{
|
||||
srdBuf[slot].stack[i] = stk[i];
|
||||
}
|
||||
}
|
||||
|
||||
// Save diagnostics data to Flash
|
||||
#ifdef DUET_NG
|
||||
|
@ -1331,10 +1339,10 @@ void Platform::InitialiseInterrupts()
|
|||
|
||||
// Timer interrupt for stepper motors
|
||||
// The clock rate we use is a compromise. Too fast and the 64-bit square roots take a long time to execute. Too slow and we lose resolution.
|
||||
// We choose a clock divisor of 32, which gives us 0.38us resolution. The next option is 128 which would give 1.524us resolution.
|
||||
// We choose a clock divisor of 128 which gives 1.524us resolution on the Duet 085 (84MHz clock) and 0.9375us resolution on the Duet WiFi.
|
||||
pmc_set_writeprotect(false);
|
||||
pmc_enable_periph_clk((uint32_t) STEP_TC_IRQN);
|
||||
tc_init(STEP_TC, STEP_TC_CHAN, TC_CMR_WAVE | TC_CMR_WAVSEL_UP | TC_CMR_TCCLKS_TIMER_CLOCK3);
|
||||
tc_init(STEP_TC, STEP_TC_CHAN, TC_CMR_WAVE | TC_CMR_WAVSEL_UP | TC_CMR_TCCLKS_TIMER_CLOCK4);
|
||||
STEP_TC->TC_CHANNEL[STEP_TC_CHAN].TC_IDR = ~(uint32_t)0; // interrupts disabled for now
|
||||
tc_start(STEP_TC, STEP_TC_CHAN);
|
||||
tc_get_status(STEP_TC, STEP_TC_CHAN); // clear any pending interrupt
|
||||
|
@ -1445,9 +1453,15 @@ void Platform::Diagnostics(MessageType mtype)
|
|||
Message(mtype, "Last software reset code ");
|
||||
if (slot >= 0 && srdBuf[slot].magic == SoftwareResetData::magicValue)
|
||||
{
|
||||
MessageF(mtype, "0x%04x, PC 0x%08x, HFSR 0x%08x, CFSR 0x%08x, available RAM %u bytes (slot %d)\n",
|
||||
srdBuf[slot].resetReason, srdBuf[slot].pc, srdBuf[slot].hfsr, srdBuf[slot].cfsr, srdBuf[slot].neverUsedRam, slot);
|
||||
MessageF(mtype, "Spinning module during software reset: %s\n", moduleName[srdBuf[slot].resetReason & 0x0F]);
|
||||
scratchString.Clear();
|
||||
for (size_t i = 0; i < ARRAY_SIZE(srdBuf[slot].stack); ++i)
|
||||
{
|
||||
scratchString.catf(" %08x", srdBuf[slot].stack[i]);
|
||||
}
|
||||
MessageF(mtype, "0x%04x, HFSR 0x%08x, CFSR 0x%08x, ICSR 0x%08x\nStack:%s\n",
|
||||
srdBuf[slot].resetReason, srdBuf[slot].hfsr, srdBuf[slot].cfsr, srdBuf[slot].icsr, scratchString.Pointer());
|
||||
MessageF(mtype, "Spinning module during software reset: %s, available RAM %u bytes (slot %d)\n",
|
||||
moduleName[srdBuf[slot].resetReason & 0x0F], srdBuf[slot].neverUsedRam, slot);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1583,6 +1597,23 @@ void Platform::DiagnosticTest(int d)
|
|||
DDA::PrintMoves();
|
||||
break;
|
||||
|
||||
case (int)DiagnosticTestType::TimeSquareRoot: // Show the square root calculation time. The displayed value is subject to interrupts.
|
||||
{
|
||||
const uint32_t num1 = 0x7265ac3d;
|
||||
const uint32_t now1 = Platform::GetInterruptClocks();
|
||||
const uint32_t num1a = isqrt64((uint64_t)num1 * num1);
|
||||
const uint32_t tim1 = Platform::GetInterruptClocks() - now1;
|
||||
|
||||
const uint32_t num2 = 0x0000a4c5;
|
||||
const uint32_t now2 = Platform::GetInterruptClocks();
|
||||
const uint32_t num2a = isqrt64((uint64_t)num2 * num2);
|
||||
const uint32_t tim2 = Platform::GetInterruptClocks() - now2;
|
||||
MessageF(GENERIC_MESSAGE, "Square roots: 64-bit %.1fus %s, 32-bit %.1fus %s\n",
|
||||
(float)(tim1 * 1000000)/DDA::stepClockRate, (num1a == num1) ? "ok" : "ERROR",
|
||||
(float)(tim2 * 1000000)/DDA::stepClockRate, (num2a == num2) ? "ok" : "ERROR");
|
||||
}
|
||||
break;
|
||||
|
||||
#ifdef DUET_NG
|
||||
case (int)DiagnosticTestType::PrintExpanderStatus:
|
||||
MessageF(GENERIC_MESSAGE, "Expander status %04X\n", DuetExpansion::DiagnosticRead());
|
||||
|
|
|
@ -180,6 +180,7 @@ enum class DiagnosticTestType : int
|
|||
#ifdef DUET_NG
|
||||
PrintExpanderStatus = 101, // print DueXn expander status
|
||||
#endif
|
||||
TimeSquareRoot = 102 // do a timing test on the square roor function
|
||||
};
|
||||
|
||||
// Enumeration to describe what we want to do with a logical pin
|
||||
|
@ -326,7 +327,7 @@ public:
|
|||
void ClassReport(float &lastTime); // Called on Spin() return to check everything's live.
|
||||
void LogError(ErrorCode e) { errorCodeBits |= (uint32_t)e; }
|
||||
|
||||
void SoftwareReset(uint16_t reason, uint32_t pc = 0);
|
||||
void SoftwareReset(uint16_t reason, const uint32_t *stk = nullptr);
|
||||
bool AtxPower() const;
|
||||
void SetAtxPower(bool on);
|
||||
void SetBoardType(BoardType bt);
|
||||
|
@ -609,22 +610,30 @@ private:
|
|||
// directly from/to flash memory.
|
||||
struct SoftwareResetData
|
||||
{
|
||||
static const uint16_t versionValue = 4; // increment this whenever this struct changes
|
||||
static const uint16_t versionValue = 6; // increment this whenever this struct changes
|
||||
static const uint16_t magicValue = 0x7D00 | versionValue; // value we use to recognise that all the flash data has been written
|
||||
static const uint32_t nvAddress = 0; // must be 4-byte aligned
|
||||
static const size_t numberOfSlots = 8; // number of storage slots used to implement wear levelling
|
||||
static const size_t numberOfSlots = 6; // number of storage slots used to implement wear levelling
|
||||
|
||||
uint16_t magic; // the magic number, including the version
|
||||
uint16_t resetReason; // this records why we did a software reset, for diagnostic purposes
|
||||
uint32_t neverUsedRam; // the amount of never used RAM at the last abnormal software reset
|
||||
uint32_t hfsr; // hard fault status register
|
||||
uint32_t cfsr; // configurable fault status register
|
||||
uint32_t pc; // program counter when the exception occurred
|
||||
uint32_t icsr; // interrupt control and state register
|
||||
uint32_t stack[16]; // stack when the exception occurred, with the program counter at the bottom
|
||||
|
||||
bool isVacant() const // return true if this struct can be written without erasing it first
|
||||
{
|
||||
return magic == 0xFFFF && resetReason == 0xFFFF && neverUsedRam == 0xFFFFFFFF
|
||||
&& hfsr == 0xFFFFFFFF && cfsr == 0xFFFFFFFF && pc == 0xFFFFFFFF;
|
||||
const uint32_t *p = reinterpret_cast<const uint32_t*>(this);
|
||||
for (size_t i = 0; i < sizeof(*this)/sizeof(uint32_t); ++i)
|
||||
{
|
||||
if (*p != 0xFFFFFFFF)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
++p;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -186,7 +186,7 @@ const char *moduleName[] =
|
|||
|
||||
// Utilities and storage not part of any class
|
||||
|
||||
static char scratchStringBuffer[140]; // this is now used only for short messages; needs to be long enough to print delta parameters
|
||||
static char scratchStringBuffer[150]; // this is now used only for short messages; needs to be long enough to print delta parameters and 12 words of stack (132 bytes)
|
||||
StringRef scratchString(scratchStringBuffer, ARRAY_SIZE(scratchStringBuffer));
|
||||
|
||||
// For debug use
|
||||
|
|
|
@ -9,11 +9,11 @@
|
|||
#define SRC_VERSION_H_
|
||||
|
||||
#ifndef VERSION
|
||||
# define VERSION "1.17d"
|
||||
# define VERSION "1.17d+1"
|
||||
#endif
|
||||
|
||||
#ifndef DATE
|
||||
# define DATE "2017-01-28"
|
||||
# define DATE "2017-02-01"
|
||||
#endif
|
||||
|
||||
#define AUTHORS "reprappro, dc42, chrishamm, t3p3, dnewman"
|
||||
|
|
|
@ -343,32 +343,32 @@ uint16_t Webserver::GetGCodeBufferSpace(const WebSource source) const
|
|||
void Webserver::ConnectionLost(Connection conn)
|
||||
{
|
||||
// Inform protocol handlers that this connection has been lost
|
||||
uint16_t localPort = Network::GetLocalPort(conn);
|
||||
const uint16_t localPort = Network::GetLocalPort(conn);
|
||||
ProtocolInterpreter *interpreter;
|
||||
switch (localPort)
|
||||
{
|
||||
case FTP_PORT: /* FTP */
|
||||
case FTP_PORT: /* FTP */
|
||||
interpreter = ftpInterpreter;
|
||||
break;
|
||||
|
||||
case TELNET_PORT: /* Telnet */
|
||||
interpreter = telnetInterpreter;
|
||||
break;
|
||||
|
||||
default: /* HTTP and FTP data */
|
||||
if (localPort == network->GetHttpPort())
|
||||
{
|
||||
interpreter = httpInterpreter;
|
||||
break;
|
||||
}
|
||||
else if (localPort == network->GetDataPort())
|
||||
{
|
||||
interpreter = ftpInterpreter;
|
||||
break;
|
||||
}
|
||||
|
||||
case TELNET_PORT: /* Telnet */
|
||||
interpreter = telnetInterpreter;
|
||||
break;
|
||||
|
||||
default: /* HTTP and FTP data */
|
||||
if (localPort == network->GetHttpPort())
|
||||
{
|
||||
interpreter = httpInterpreter;
|
||||
break;
|
||||
}
|
||||
else if (localPort == network->GetDataPort())
|
||||
{
|
||||
interpreter = ftpInterpreter;
|
||||
break;
|
||||
}
|
||||
|
||||
platform->MessageF(GENERIC_MESSAGE, "Error: Webserver should handle disconnect event at local port %d, but no handler was found!\n", localPort);
|
||||
return;
|
||||
platform->MessageF(GENERIC_MESSAGE, "Error: Webserver should handle disconnect event at local port %d, but no handler was found!\n", localPort);
|
||||
return;
|
||||
}
|
||||
|
||||
// Print some debug information and notify the protocol interpreter
|
||||
|
|
Reference in a new issue