diff options
Diffstat (limited to 'src/GCodes')
-rw-r--r-- | src/GCodes/DriverMode.cpp | 29 | ||||
-rw-r--r-- | src/GCodes/DriverMode.h | 27 | ||||
-rw-r--r-- | src/GCodes/GCodeBuffer.cpp | 10 | ||||
-rw-r--r-- | src/GCodes/GCodeBuffer.h | 1 | ||||
-rw-r--r-- | src/GCodes/GCodes.cpp | 94 | ||||
-rw-r--r-- | src/GCodes/GCodes.h | 9 | ||||
-rw-r--r-- | src/GCodes/GCodes2.cpp | 94 |
7 files changed, 190 insertions, 74 deletions
diff --git a/src/GCodes/DriverMode.cpp b/src/GCodes/DriverMode.cpp new file mode 100644 index 00000000..6450e115 --- /dev/null +++ b/src/GCodes/DriverMode.cpp @@ -0,0 +1,29 @@ +/* + * DriverMode.cpp + * + * Created on: 27 Apr 2018 + * Author: David + */ + +#include "DriverMode.h" +#include "RepRapFirmware.h" + +// This table must be in the same order as enum DriverMode +static const char * const DriverModeStrings[] = +{ + "constant off-time", + "random off-time", + "spreadCycle", + "stealthChop", + "unknown" +}; + +static_assert(ARRAY_SIZE(DriverModeStrings) == (unsigned int)DriverMode::unknown + 1, "bad driver mode string table"); + +const char* TranslateDriverMode(unsigned int mode) +{ + const unsigned int imode = min<unsigned int>(mode, (unsigned int)DriverMode::unknown); + return DriverModeStrings[imode]; +} + +// End diff --git a/src/GCodes/DriverMode.h b/src/GCodes/DriverMode.h new file mode 100644 index 00000000..594fbcf3 --- /dev/null +++ b/src/GCodes/DriverMode.h @@ -0,0 +1,27 @@ +/* + * DriverModes.h + * + * Created on: 27 Apr 2018 + * Author: David + */ + +#ifndef SRC_GCODES_DRIVERMODE_H_ +#define SRC_GCODES_DRIVERMODE_H_ + +enum class DriverMode : unsigned int +{ + constantOffTime = 0, + randomOffTime, + spreadCycle, + stealthChop, // includes stealthChop2 + unknown // must be last! +}; + +const char* TranslateDriverMode(unsigned int mode); + +inline const char* TranslateDriverMode(DriverMode mode) +{ + return TranslateDriverMode((unsigned int)mode); +} + +#endif /* SRC_GCODES_DRIVERMODE_H_ */ diff --git a/src/GCodes/GCodeBuffer.cpp b/src/GCodes/GCodeBuffer.cpp index e3222344..3c190852 100644 --- a/src/GCodes/GCodeBuffer.cpp +++ b/src/GCodes/GCodeBuffer.cpp @@ -750,6 +750,16 @@ void GCodeBuffer::TryGetUIValue(char c, uint32_t& val, bool& seen) } } +// If the specified parameter character is found, fetch 'value' as a Boolean and set 'seen'. Otherwise leave val and seen alone. +void GCodeBuffer::TryGetBValue(char c, bool& val, bool& seen) +{ + if (Seen(c)) + { + val = GetIValue() > 0; + seen = true; + } +} + // Try to get a float array exactly 'numVals' long after parameter letter 'c'. // If the wrong number of values is provided, generate an error message and return true. // Else set 'seen' if we saw the letter and value, and return false. diff --git a/src/GCodes/GCodeBuffer.h b/src/GCodes/GCodeBuffer.h index 81aefdc9..6675cf2a 100644 --- a/src/GCodes/GCodeBuffer.h +++ b/src/GCodes/GCodeBuffer.h @@ -46,6 +46,7 @@ public: void TryGetFValue(char c, float& val, bool& seen); void TryGetIValue(char c, int32_t& val, bool& seen); void TryGetUIValue(char c, uint32_t& val, bool& seen); + void TryGetBValue(char c, bool& val, bool& seen); bool TryGetFloatArray(char c, size_t numVals, float vals[], const StringRef& reply, bool& seen, bool doPad = false); bool TryGetQuotedString(char c, const StringRef& str, bool& seen); bool TryGetPossiblyQuotedString(char c, const StringRef& str, bool& seen); diff --git a/src/GCodes/GCodes.cpp b/src/GCodes/GCodes.cpp index 9f3917ae..dae9acf8 100644 --- a/src/GCodes/GCodes.cpp +++ b/src/GCodes/GCodes.cpp @@ -2330,7 +2330,7 @@ const char* GCodes::DoStraightMove(GCodeBuffer& gb, bool isCoordinated) // Check enough axes have been homed if (moveBuffer.moveType == 0) { - if (CheckEnoughAxesHomed(axesMentioned)) + if (!doingManualBedProbe && CheckEnoughAxesHomed(axesMentioned)) { return "G0/G1: insufficient axes homed"; } @@ -3040,7 +3040,7 @@ void GCodes::GetCurrentCoordinates(const StringRef& s) const for (size_t axis = 0; axis < numVisibleAxes; ++axis) { // Don't put a space after the colon in the response, it confuses Pronterface - s.catf("%c:%.3f ", axisLetters[axis], (double)currentUserPosition[axis]); + s.catf("%c:%.3f ", axisLetters[axis], HideNan(currentUserPosition[axis])); } for (size_t i = numTotalAxes; i < DRIVES; i++) { @@ -3055,11 +3055,11 @@ void GCodes::GetCurrentCoordinates(const StringRef& s) const s.catf(" %" PRIi32, reprap.GetMove().GetEndPoint(i)); } - // Add the user coordinates because they may be different from the machine coordinates under some conditions + // Add the machine coordinates because they may be different from the user coordinates under some conditions s.cat(" Machine"); for (size_t axis = 0; axis < numVisibleAxes; ++axis) { - s.catf(" %.3f", (double)liveCoordinates[axis]); + s.catf(" %.3f", HideNan(liveCoordinates[axis])); } } @@ -3522,12 +3522,12 @@ void GCodes::DisableDrives() SetAllAxesNotHomed(); } -bool GCodes::ChangeMicrostepping(size_t drive, unsigned int microsteps, int mode) const +bool GCodes::ChangeMicrostepping(size_t drive, unsigned int microsteps, bool interp) const { bool dummy; - const unsigned int oldSteps = platform.GetMicrostepping(drive, mode, dummy); - const bool success = platform.SetMicrostepping(drive, microsteps, mode); - if (success && mode <= 1) // modes higher than 1 are used for special functions + const unsigned int oldSteps = platform.GetMicrostepping(drive, dummy); + const bool success = platform.SetMicrostepping(drive, microsteps, interp); + if (success) { // We changed the microstepping, so adjust the steps/mm to compensate platform.SetDriveStepsPerUnit(drive, platform.DriveStepsPerUnit(drive) * (float)microsteps / (float)oldSteps); @@ -4587,18 +4587,26 @@ GCodeResult GCodes::WriteConfigOverrideFile(GCodeBuffer& gb, const StringRef& re return GCodeResult::ok; } -// Store a standard-format temperature report in 'reply'. This doesn't put a newline character at the end. -void GCodes::GenerateTemperatureReport(const StringRef& reply) const +// Report the temperatures of one tool in M105 format +void GCodes::ReportToolTemperatures(const StringRef& reply, const Tool *tool, bool includeNumber) const { - Heat& heat = reprap.GetHeat(); - - // Pronterface, Repetier etc. expect the temperatures to be reported for T0, T1 etc. - // So scan the tool list and report the temperature of the heaters associated with each tool. - // If the user configures tools T0, T1 etc. with 1 heater each, that will return what these programs expect. - reply.copy("T"); - char sep = ':'; - for (const Tool *tool = reprap.GetFirstTool(); tool != nullptr; tool = tool->Next()) + if (tool != nullptr && tool->HeaterCount() != 0) { + if (reply.strlen() != 0) + { + reply.cat(' '); + } + if (includeNumber) + { + reply.catf("T%u", tool->Number()); + } + else + { + reply.cat("T"); + } + + Heat& heat = reprap.GetHeat(); + char sep = ':'; for (size_t i = 0; i < tool->HeaterCount(); ++i) { const int heater = tool->Heater(i); @@ -4606,17 +4614,55 @@ void GCodes::GenerateTemperatureReport(const StringRef& reply) const sep = ' '; } } +} + +// Store a standard-format temperature report in 'reply'. This doesn't put a newline character at the end. +void GCodes::GenerateTemperatureReport(const StringRef& reply) const +{ + Heat& heat = reprap.GetHeat(); + + // The following is believed to be compatible with Marlin and Octoprint, based on thread https://github.com/foosel/OctoPrint/issues/2590#issuecomment-385023980 + ReportToolTemperatures(reply, reprap.GetCurrentTool(), false); + + for (const Tool *tool = reprap.GetFirstTool(); tool != nullptr; tool = tool->Next()) + { + ReportToolTemperatures(reply, tool, true); + } - const int bedHeater = (NumBedHeaters > 0) ? heat.GetBedHeater(0) : -1; // default to first heated bed - if (bedHeater >= 0) + for (size_t hn = 0; hn < NumBedHeaters && heat.GetBedHeater(hn) >= 0; ++hn) { - reply.catf(" B:%.1f /%.1f", (double)heat.GetTemperature(bedHeater), (double)heat.GetTargetTemperature(bedHeater)); + if (hn == 0) + { + if (reply.strlen() != 0) + { + reply.cat(' '); + } + reply.cat("B:"); + } + else + { + reply.catf(" B%u:", hn); + } + const int8_t heater = heat.GetBedHeater(hn); + reply.catf("%.1f /%.1f", (double)heat.GetTemperature(heater), (double)heat.GetTargetTemperature(heater)); } - const int chamberHeater = (NumChamberHeaters > 0) ? heat.GetChamberHeater(0) : -1; // default to first chamber heater - if (chamberHeater >= 0) + for (size_t hn = 0; hn < NumChamberHeaters && heat.GetChamberHeater(hn) >= 0; ++hn) { - reply.catf(" C:%.1f /%.1f", (double)heat.GetTemperature(chamberHeater), (double)heat.GetTargetTemperature(chamberHeater)); + if (hn == 0) + { + if (reply.strlen() != 0) + { + reply.cat(' '); + } + reply.cat("C:"); + } + else + { + reply.catf(" C%u:", hn); + } + const int8_t heater = heat.GetChamberHeater(hn); + reply.catf("%.1f /%.1f", (double)heat.GetTemperature(heater), (double)heat.GetTargetTemperature(heater)); } } diff --git a/src/GCodes/GCodes.h b/src/GCodes/GCodes.h index a952b92a..c839b481 100644 --- a/src/GCodes/GCodes.h +++ b/src/GCodes/GCodes.h @@ -295,6 +295,7 @@ private: bool ManageTool(GCodeBuffer& gb, const StringRef& reply); // Create a new tool definition, returning true if an error was reported void SetToolHeaters(Tool *tool, float temperature, bool both); // Set all a tool's heaters to the temperature, for M104/M109 bool ToolHeatersAtSetTemperatures(const Tool *tool, bool waitWhenCooling) const; // Wait for the heaters associated with the specified tool to reach their set temperatures + void ReportToolTemperatures(const StringRef& reply, const Tool *tool, bool includeNumber) const; void GenerateTemperatureReport(const StringRef& reply) const; // Store a standard-format temperature report in reply OutputBuffer *GenerateJsonStatusResponse(int type, int seq, ResponseSource source) const; // Generate a M408 response void CheckReportDue(GCodeBuffer& gb, const StringRef& reply) const; // Check whether we need to report temperatures or status @@ -311,7 +312,7 @@ private: GCodeResult RetractFilament(GCodeBuffer& gb, bool retract); // Retract or un-retract filaments GCodeResult LoadFilament(GCodeBuffer& gb, const StringRef& reply); // Load the specified filament into a tool GCodeResult UnloadFilament(GCodeBuffer& gb, const StringRef& reply); // Unload the current filament from a tool - bool ChangeMicrostepping(size_t drive, unsigned int microsteps, int mode) const; // Change microstepping on the specified drive + bool ChangeMicrostepping(size_t drive, unsigned int microsteps, bool interp) const; // Change microstepping on the specified drive void ListTriggers(const StringRef& reply, TriggerInputsBitmap mask); // Append a list of trigger inputs to a message void CheckTriggers(); // Check for and execute triggers void CheckFilament(); // Check for and respond to filament errors @@ -342,12 +343,12 @@ private: GCodeResult ChangeSimulationMode(GCodeBuffer& gb, const StringRef &reply, uint32_t newSimulationMode); // handle M37 to change the simulation mode GCodeResult WriteConfigOverrideFile(GCodeBuffer& gb, const StringRef& reply) const; // Write the config-override file - void CopyConfigFinalValues(GCodeBuffer& gb); // Copy the feed rate etc. from the daemon to the input channels + void CopyConfigFinalValues(GCodeBuffer& gb); // Copy the feed rate etc. from the daemon to the input channels void ClearBabyStepping() { currentBabyStepZOffset = 0.0; } - MessageType GetMessageBoxDevice(GCodeBuffer& gb) const; // Decide which device to display a message box on - void DoManualProbe(GCodeBuffer& gb); // Do a manual bed probe + MessageType GetMessageBoxDevice(GCodeBuffer& gb) const; // Decide which device to display a message box on + void DoManualProbe(GCodeBuffer& gb); // Do a manual bed probe void AppendAxes(const StringRef& reply, AxesBitmap axes) const; // Append a list of axes to a string diff --git a/src/GCodes/GCodes2.cpp b/src/GCodes/GCodes2.cpp index 7fe9747b..4562cfed 100644 --- a/src/GCodes/GCodes2.cpp +++ b/src/GCodes/GCodes2.cpp @@ -30,6 +30,12 @@ # include "FirmwareUpdater.h" #endif +#if defined(DUET_NG) +# include "TMC2660.h" +#elif defined(DUET_M) +# include "TMC22xx.h" +#endif + #if SUPPORT_12864_LCD # include "Display/Display.h" #endif @@ -2112,23 +2118,15 @@ bool GCodes::HandleMcode(GCodeBuffer& gb, const StringRef& reply) case 290: // Baby stepping if (gb.Seen('S') || gb.Seen('Z')) { + const float fval = gb.GetFValue(); if (!LockMovement(gb)) { return false; } - const float fval = constrain<float>(gb.GetFValue(), -1.0, 1.0); const bool absolute = (gb.Seen('R') && gb.GetIValue() == 0); - float difference; - if (absolute) - { - difference = fval - currentBabyStepZOffset; - currentBabyStepZOffset = fval; - } - else - { - difference = fval; - currentBabyStepZOffset += fval; - } + float difference = (absolute) ? fval - currentBabyStepZOffset : fval; + difference = constrain<float>(difference, -1.0, 1.0); + currentBabyStepZOffset += difference; const float amountPushed = reprap.GetMove().PushBabyStepping(difference); moveBuffer.initialCoords[Z_AXIS] += amountPushed; @@ -2357,11 +2355,7 @@ bool GCodes::HandleMcode(GCodeBuffer& gb, const StringRef& reply) case 350: // Set/report microstepping { - // interp is currently an int not a bool, because we use special values of interp to set the chopper control register - int32_t mode = 0; // this is usually the interpolation requested (0 = off, 1 = on) - bool dummy; - gb.TryGetIValue('I', mode, dummy); - + bool interp = (gb.Seen('I') && gb.GetIValue() > 0); bool seen = false; for (size_t axis = 0; axis < numTotalAxes; axis++) { @@ -2373,13 +2367,13 @@ bool GCodes::HandleMcode(GCodeBuffer& gb, const StringRef& reply) } seen = true; const unsigned int microsteps = gb.GetUIValue(); - if (ChangeMicrostepping(axis, microsteps, mode)) + if (ChangeMicrostepping(axis, microsteps, interp)) { SetAxisNotHomed(axis); } else { - reply.printf("Drive %c does not support %ux microstepping%s", axisLetters[axis], microsteps, ((mode) ? " with interpolation" : "")); + reply.printf("Drive %c does not support %ux microstepping%s", axisLetters[axis], microsteps, ((interp) ? " with interpolation" : "")); result = GCodeResult::error; } } @@ -2397,9 +2391,9 @@ bool GCodes::HandleMcode(GCodeBuffer& gb, const StringRef& reply) gb.GetUnsignedArray(eVals, eCount, true); for (size_t e = 0; e < eCount; e++) { - if (!ChangeMicrostepping(numTotalAxes + e, (int)eVals[e], mode)) + if (!ChangeMicrostepping(numTotalAxes + e, eVals[e], interp)) { - reply.printf("Drive E%u does not support %ux microstepping%s", e, (unsigned int)eVals[e], ((mode) ? " with interpolation" : "")); + reply.printf("Drive E%u does not support %ux microstepping%s", e, (unsigned int)eVals[e], ((interp) ? " with interpolation" : "")); result = GCodeResult::error; } } @@ -2410,16 +2404,16 @@ bool GCodes::HandleMcode(GCodeBuffer& gb, const StringRef& reply) reply.copy("Microstepping - "); for (size_t axis = 0; axis < numTotalAxes; ++axis) { - bool interp; - const unsigned int microsteps = platform.GetMicrostepping(axis, mode, interp); - reply.catf("%c:%u%s, ", axisLetters[axis], microsteps, (interp) ? "(on)" : ""); + bool actualInterp; + const unsigned int microsteps = platform.GetMicrostepping(axis, actualInterp); + reply.catf("%c:%u%s, ", axisLetters[axis], microsteps, (actualInterp) ? "(on)" : ""); } reply.cat("E"); for (size_t extruder = 0; extruder < numExtruders; extruder++) { - bool interp; - const unsigned int microsteps = platform.GetMicrostepping(extruder + numTotalAxes, mode, interp); - reply.catf(":%u%s", microsteps, (interp) ? "(on)" : ""); + bool actualInterp; + const unsigned int microsteps = platform.GetMicrostepping(extruder + numTotalAxes, actualInterp); + reply.catf(":%u%s", microsteps, (actualInterp) ? "(on)" : ""); } } } @@ -3081,8 +3075,8 @@ bool GCodes::HandleMcode(GCodeBuffer& gb, const StringRef& reply) { return false; } - platform.SetDirectionValue(drive, gb.GetIValue() != 0); seen = true; + platform.SetDirectionValue(drive, gb.GetIValue() != 0); } if (gb.Seen('R')) { @@ -3090,11 +3084,12 @@ bool GCodes::HandleMcode(GCodeBuffer& gb, const StringRef& reply) { return false; } - platform.SetEnableValue(drive, (int8_t)gb.GetIValue()); seen = true; + platform.SetEnableValue(drive, (int8_t)gb.GetIValue()); } if (gb.Seen('T')) { + seen = true; float timings[4]; size_t numTimings = ARRAY_SIZE(timings); gb.GetFloatArray(timings, numTimings, true); @@ -3105,33 +3100,42 @@ bool GCodes::HandleMcode(GCodeBuffer& gb, const StringRef& reply) break; } platform.SetDriverStepTiming(drive, timings); - seen = true; } - bool badParameter = false; - for (size_t axis = 0; axis < numTotalAxes; ++axis) + +#if HAS_SMART_DRIVERS + if (gb.Seen('D')) // set driver mode { - if (gb.Seen(axisLetters[axis])) + seen = true; + const unsigned int mode = gb.GetUIValue(); + if (!SmartDrivers::SetDriverMode(drive, mode)) { - badParameter = true; + reply.printf("Driver %u does not support mode '%s'", drive, TranslateDriverMode(mode)); + result = GCodeResult::error; + break; } } - if (gb.Seen(extrudeLetter)) - { - badParameter = true; - } - if (badParameter) + + if (gb.Seen('C')) // set chopper control register { - reply.copy("M569 no longer accepts XYZE parameters; use M584 instead"); - result = GCodeResult::error; + seen = true; + (void)SmartDrivers::SetChopperControlRegister(drive, gb.GetUIValue()); // currently this call never returns failure, so no error handling here } - else if (!seen) +#endif + if (!seen) { float timings[4]; platform.GetDriverStepTiming(drive, timings); - reply.printf("Drive %u runs %s, active %s enable, step timing %.1f,%.1f,%.1f,%.1f microseconds", + reply.printf("Drive %u runs %s, active %s enable," +#if HAS_SMART_DRIVERS + " mode %s," +#endif + " step timing %.1f,%.1f,%.1f,%.1f microseconds", drive, (platform.GetDirectionValue(drive)) ? "forwards" : "in reverse", (platform.GetEnableValue(drive)) ? "high" : "low", +#if HAS_SMART_DRIVERS + TranslateDriverMode(SmartDrivers::GetDriverMode(drive)), +#endif (double)timings[0], (double)timings[1], (double)timings[2], (double)timings[3]); } } @@ -3990,7 +3994,7 @@ bool GCodes::HandleMcode(GCodeBuffer& gb, const StringRef& reply) break; #if HAS_VOLTAGE_MONITOR - case 911: // Enable auto save + case 911: // Enable auto save on loss of power if (gb.Seen('S')) { const float saveVoltage = gb.GetFValue(); @@ -4087,7 +4091,6 @@ bool GCodes::HandleMcode(GCodeBuffer& gb, const StringRef& reply) break; #endif -#if HAS_VOLTAGE_MONITOR case 916: if (!platform.GetMassStorage()->FileExists(platform.GetSysDir(), RESUME_AFTER_POWER_FAIL_G)) { @@ -4104,7 +4107,6 @@ bool GCodes::HandleMcode(GCodeBuffer& gb, const StringRef& reply) DoFileMacro(gb, RESUME_AFTER_POWER_FAIL_G, true); } break; -#endif // For case 917, see 906 |