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

github.com/Duet3D/RepRapFirmware.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/CAN/CanInterface.cpp41
-rw-r--r--src/CAN/CanInterface.h2
-rw-r--r--src/CAN/CanMotion.cpp8
-rw-r--r--src/CAN/CanMotion.h2
-rw-r--r--src/Duet3_V06/Pins_Duet3_V06.h4
-rw-r--r--src/GCodes/GCodes2.cpp43
-rw-r--r--src/Heating/Heat.cpp32
-rw-r--r--src/Heating/Heater.cpp7
-rw-r--r--src/Heating/Heater.h4
-rw-r--r--src/Heating/LocalHeater.h1
-rw-r--r--src/Heating/RemoteHeater.cpp17
-rw-r--r--src/Heating/RemoteHeater.h1
-rw-r--r--src/Movement/DDA.cpp87
-rw-r--r--src/Movement/DDA.h4
-rw-r--r--src/Movement/DriveMovement.cpp4
-rw-r--r--src/Platform.cpp69
-rw-r--r--src/Platform.h2
-rw-r--r--src/Version.h2
18 files changed, 242 insertions, 88 deletions
diff --git a/src/CAN/CanInterface.cpp b/src/CAN/CanInterface.cpp
index 326a4d60..c3eda44b 100644
--- a/src/CAN/CanInterface.cpp
+++ b/src/CAN/CanInterface.cpp
@@ -476,7 +476,7 @@ static bool SetRemoteDriverValues(const CanDriversData& data, const StringRef& r
{
break;
}
- CanMessageBuffer * buf = CanMessageBuffer::Allocate();
+ CanMessageBuffer * const buf = CanMessageBuffer::Allocate();
if (buf == nullptr)
{
reply.lcat("No CAN buffer available");
@@ -514,7 +514,7 @@ static bool SetRemoteDriverStates(const CanDriversList& drivers, const StringRef
{
break;
}
- CanMessageBuffer * buf = CanMessageBuffer::Allocate();
+ CanMessageBuffer * const buf = CanMessageBuffer::Allocate();
if (buf == nullptr)
{
reply.lcat("No CAN buffer available");
@@ -697,6 +697,12 @@ bool CanInterface::SetRemoteDriverMicrostepping(const CanDriversData& data, cons
return SetRemoteDriverValues(data, reply, CanMessageType::setMicrostepping);
}
+// Set the pressure advance on remote drivers, returning true if successful
+bool CanInterface::SetRemotePressureAdvance(const CanDriversData& data, const StringRef& reply)
+{
+ return SetRemoteDriverValues(data, reply, CanMessageType::setPressureAdvance);
+}
+
// Handle M569 for a remote driver
GCodeResult CanInterface::ConfigureRemoteDriver(DriverId driver, GCodeBuffer& gb, const StringRef& reply)
pre(driver.IsRemote())
@@ -734,8 +740,7 @@ GCodeResult CanInterface::SetRemoteDriverStallParameters(const CanDriversList& d
return GCodeResult::ok;
}
-// Get diagnostics from and expansion board
-GCodeResult CanInterface::RemoteDiagnostics(MessageType mt, uint32_t boardAddress, GCodeBuffer& gb, const StringRef& reply)
+static GCodeResult GetRemoteInfo(uint8_t infoType, uint32_t boardAddress, GCodeBuffer& gb, const StringRef& reply)
{
if (boardAddress > CanId::MaxNormalAddress)
{
@@ -750,11 +755,31 @@ GCodeResult CanInterface::RemoteDiagnostics(MessageType mt, uint32_t boardAddres
return GCodeResult::error;
}
+ const CanRequestId rid = CanInterface::AllocateRequestId(boardAddress);
+ auto msg = buf->SetupRequestMessage<CanMessageReturnInfo>(rid, CanId::MasterAddress, (CanAddress)boardAddress);
+ msg->type = infoType;
+ return CanInterface::SendRequestAndGetStandardReply(buf, rid, reply);
+}
+
+// Get diagnostics from and expansion board
+GCodeResult CanInterface::RemoteDiagnostics(MessageType mt, uint32_t boardAddress, GCodeBuffer& gb, const StringRef& reply)
+{
reply.printf("Diagnostics for board %u:", (unsigned int)boardAddress);
- const CanRequestId rid = AllocateRequestId(boardAddress);
- auto msg = buf->SetupRequestMessage<CanMessageDiagnostics>(rid, CanId::MasterAddress, (CanAddress)boardAddress);
- msg->type = 0;
- return SendRequestAndGetStandardReply(buf, rid, reply);
+ GCodeResult rslt = GetRemoteInfo(CanMessageReturnInfo::typeFirmwareVersion, boardAddress, gb, reply);
+ if (rslt == GCodeResult::ok)
+ {
+ rslt = GetRemoteInfo(CanMessageReturnInfo::typeMemory, boardAddress, gb, reply);
+ }
+ if (rslt == GCodeResult::ok)
+ {
+ rslt = GetRemoteInfo(CanMessageReturnInfo::typePressureAdvance, boardAddress, gb, reply);
+ }
+ return rslt;
+}
+
+GCodeResult CanInterface::GetRemoteFirmwareDetails(uint32_t boardAddress, GCodeBuffer& gb, const StringRef& reply)
+{
+ return GetRemoteInfo(CanMessageReturnInfo::typeFirmwareVersion, boardAddress, gb, reply);
}
// Tell an expansion board to update
diff --git a/src/CAN/CanInterface.h b/src/CAN/CanInterface.h
index b201fed4..f66b4a4a 100644
--- a/src/CAN/CanInterface.h
+++ b/src/CAN/CanInterface.h
@@ -66,6 +66,7 @@ namespace CanInterface
void SendResponse(CanMessageBuffer *buf);
void SendBroadcast(CanMessageBuffer *buf);
+ GCodeResult GetRemoteFirmwareDetails(uint32_t boardAddress, GCodeBuffer& gb, const StringRef& reply);
GCodeResult RemoteDiagnostics(MessageType mt, uint32_t boardAddress, GCodeBuffer& gb, const StringRef& reply);
GCodeResult UpdateRemoteFirmware(uint32_t boardAddress, GCodeBuffer& gb, const StringRef& reply);
@@ -76,6 +77,7 @@ namespace CanInterface
bool SetRemoteStandstillCurrentPercent(const CanDriversData& data, const StringRef& reply);
bool SetRemoteDriverCurrents(const CanDriversData& data, const StringRef& reply);
bool SetRemoteDriverMicrostepping(const CanDriversData& data, const StringRef& reply);
+ bool SetRemotePressureAdvance(const CanDriversData& data, const StringRef& reply);
GCodeResult ConfigureRemoteDriver(DriverId driver, GCodeBuffer& gb, const StringRef& reply);
GCodeResult SetRemoteDriverStallParameters(const CanDriversList& drivers, GCodeBuffer& gb, const StringRef& reply);
}
diff --git a/src/CAN/CanMotion.cpp b/src/CAN/CanMotion.cpp
index bea0c271..6a69b516 100644
--- a/src/CAN/CanMotion.cpp
+++ b/src/CAN/CanMotion.cpp
@@ -41,7 +41,7 @@ void CanMotion::StartMovement(const DDA& dda)
// This is called by DDA::Prepare for each active CAN DM in the move
// If steps == 0 then the drivers just need to be enabled
-void CanMotion::AddMovement(const DDA& dda, const PrepParams& params, DriverId canDriver, int32_t steps)
+void CanMotion::AddMovement(const DDA& dda, const PrepParams& params, DriverId canDriver, int32_t steps, bool usePressureAdvance)
{
// Search for the correct movement buffer
CanMessageBuffer* buf = movementBufferList;
@@ -71,9 +71,9 @@ void CanMotion::AddMovement(const DDA& dda, const PrepParams& params, DriverId c
move->decelClocks = lrintf(params.decelTime * StepTimer::StepClockRate);
move->initialSpeedFraction = params.initialSpeedFraction;
move->finalSpeedFraction = params.finalSpeedFraction;
+ move->pressureAdvanceDrives = 0;
move->deltaDrives = 0; //TODO
move->endStopsToCheck = 0; //TODO
- move->pressureAdvanceDrives = 0; //TODO
move->stopAllDrivesOnEndstopHit = false; //TODO
// Additional parameters for delta movements
@@ -91,6 +91,10 @@ void CanMotion::AddMovement(const DDA& dda, const PrepParams& params, DriverId c
}
buf->msg.move.perDrive[canDriver.localDriver].steps = steps;
+ if (usePressureAdvance)
+ {
+ buf->msg.move.pressureAdvanceDrives |= 1u << canDriver.localDriver;
+ }
}
// This is called by DDA::Prepare when all DMs for CAN drives have been processed
diff --git a/src/CAN/CanMotion.h b/src/CAN/CanMotion.h
index 8d384c1c..da0f87eb 100644
--- a/src/CAN/CanMotion.h
+++ b/src/CAN/CanMotion.h
@@ -18,7 +18,7 @@ namespace CanMotion
{
void Init();
void StartMovement(const DDA& dda);
- void AddMovement(const DDA& dda, const PrepParams& params, DriverId canDriver, int32_t steps);
+ void AddMovement(const DDA& dda, const PrepParams& params, DriverId canDriver, int32_t steps, bool usePressureAdvance);
void FinishMovement(uint32_t moveStartTime);
bool CanPrepareMove();
void InsertHiccup(uint32_t numClocks);
diff --git a/src/Duet3_V06/Pins_Duet3_V06.h b/src/Duet3_V06/Pins_Duet3_V06.h
index 1ed452d6..3b7a2c6f 100644
--- a/src/Duet3_V06/Pins_Duet3_V06.h
+++ b/src/Duet3_V06/Pins_Duet3_V06.h
@@ -129,9 +129,9 @@ constexpr Pin DiagPin = PortCPin(20);
// SD cards
constexpr size_t NumSdCards = 1;
-constexpr Pin SdCardDetectPins[1] = { NoPin };
+constexpr Pin SdCardDetectPins[1] = { PortAPin(29) };
constexpr Pin SdWriteProtectPins[1] = { NoPin };
-constexpr Pin SdSpiCSPins[1] = { PortAPin(29) };
+constexpr Pin SdSpiCSPins[1] = { NoPin };
constexpr uint32_t ExpectedSdCardSpeed = 25000000;
// Ethernet
diff --git a/src/GCodes/GCodes2.cpp b/src/GCodes/GCodes2.cpp
index 545917ae..606a8ec1 100644
--- a/src/GCodes/GCodes2.cpp
+++ b/src/GCodes/GCodes2.cpp
@@ -1475,6 +1475,17 @@ bool GCodes::HandleMcode(GCodeBuffer& gb, const StringRef& reply)
}
else
{
+#if SUPPORT_CAN_EXPANSION
+ if (gb.Seen('B'))
+ {
+ const uint32_t board = gb.GetUIValue();
+ if (board != CanId::MasterAddress)
+ {
+ result = CanInterface::GetRemoteFirmwareDetails(board, gb, reply);
+ break;
+ }
+ }
+#endif
reply.printf("FIRMWARE_NAME: %s FIRMWARE_VERSION: %s ELECTRONICS: %s", FIRMWARE_NAME, VERSION, platform.GetElectronicsString());
#ifdef DUET_NG
const char* const expansionName = DuetExpansion::GetExpansionBoardName();
@@ -3358,40 +3369,12 @@ bool GCodes::HandleMcode(GCodeBuffer& gb, const StringRef& reply)
case 572: // Set/report pressure advance
if (gb.Seen('S'))
{
+ const float advance = gb.GetFValue();
if (!LockMovementAndWaitForStandstill(gb))
{
return false;
}
- const float advance = gb.GetFValue();
- if (gb.Seen('D'))
- {
- uint32_t eDrive[MaxExtruders];
- size_t eCount = MaxExtruders;
- gb.GetUnsignedArray(eDrive, eCount, false);
- for (size_t i = 0; i < eCount; i++)
- {
- if (eDrive[i] >= numExtruders)
- {
- reply.printf("Invalid extruder number '%" PRIu32 "'", eDrive[i]);
- result = GCodeResult::error;
- break;
- }
- platform.SetPressureAdvance(eDrive[i], advance);
- }
- }
- else
- {
- const Tool * const ct = reprap.GetCurrentTool();
- if (ct == nullptr)
- {
- reply.copy("No tool selected");
- result = GCodeResult::error;
- }
- else
- {
- ct->IterateExtruders([advance](unsigned int extruder) { reprap.GetPlatform().SetPressureAdvance(extruder, advance); });
- }
- }
+ result = platform.SetPressureAdvance(advance, gb, reply);
}
else
{
diff --git a/src/Heating/Heat.cpp b/src/Heating/Heat.cpp
index 43ce31a2..2f2b024f 100644
--- a/src/Heating/Heat.cpp
+++ b/src/Heating/Heat.cpp
@@ -752,22 +752,24 @@ bool Heat::WriteModelParameters(FileStore *f) const
// Process M570
GCodeResult Heat::ConfigureHeaterMonitoring(size_t heater, GCodeBuffer& gb, const StringRef& reply)
{
- if (heater < MaxHeaters && heaters[heater] != nullptr)
+ const auto h = FindHeater(heater);
+ if (h.IsNull())
{
- bool seenValue = false;
- float maxTempExcursion, maxFaultTime;
- heaters[heater]->GetFaultDetectionParameters(maxTempExcursion, maxFaultTime);
- gb.TryGetFValue('P', maxFaultTime, seenValue);
- gb.TryGetFValue('T', maxTempExcursion, seenValue);
- if (seenValue)
- {
- heaters[heater]->SetFaultDetectionParameters(maxTempExcursion, maxFaultTime);
- }
- else
- {
- reply.printf("Heater %u allowed excursion %.1f" DEGREE_SYMBOL "C, fault trigger time %.1f seconds", heater, (double)maxTempExcursion, (double)maxFaultTime);
- }
+ reply.printf("Heater %u not found", heater);
+ return GCodeResult::error;
+ }
+
+ bool seenValue = false;
+ float maxTempExcursion, maxFaultTime;
+ h->GetFaultDetectionParameters(maxTempExcursion, maxFaultTime);
+ gb.TryGetFValue('P', maxFaultTime, seenValue);
+ gb.TryGetFValue('T', maxTempExcursion, seenValue);
+ if (seenValue)
+ {
+ return h->SetFaultDetectionParameters(maxTempExcursion, maxFaultTime, reply);
}
+
+ reply.printf("Heater %u allowed excursion %.1f" DEGREE_SYMBOL "C, fault trigger time %.1f seconds", heater, (double)maxTempExcursion, (double)maxFaultTime);
return GCodeResult::ok;
}
@@ -949,6 +951,8 @@ HeaterProtection& Heat::AccessHeaterProtection(size_t index) const
// Updates the PIDs and HeaterProtection items after a heater change
void Heat::UpdateHeaterProtection()
{
+ ReadLocker lock(heatersLock);
+
// Reassign the first mapped heater protection item of each PID where applicable
// and rebuild the linked list of heater protection elements per heater
for (size_t heater : ARRAY_INDICES(heaters))
diff --git a/src/Heating/Heater.cpp b/src/Heating/Heater.cpp
index ac66a8ea..a5ecb54c 100644
--- a/src/Heating/Heater.cpp
+++ b/src/Heating/Heater.cpp
@@ -57,6 +57,13 @@ GCodeResult Heater::SetModel(float gain, float tc, float td, float maxPwm, float
return GCodeResult::error;
}
+GCodeResult Heater::SetFaultDetectionParameters(float pMaxTempExcursion, float pMaxFaultTime, const StringRef& reply)
+{
+ maxTempExcursion = pMaxTempExcursion;
+ maxHeatingFaultTime = pMaxFaultTime;
+ return UpdateFaultDetectionParameters(reply);
+}
+
HeaterStatus Heater::GetStatus() const
{
const HeaterMode mode = GetMode();
diff --git a/src/Heating/Heater.h b/src/Heating/Heater.h
index 53bfcada..1d358bbe 100644
--- a/src/Heating/Heater.h
+++ b/src/Heating/Heater.h
@@ -60,8 +60,7 @@ public:
void GetFaultDetectionParameters(float& pMaxTempExcursion, float& pMaxFaultTime) const
{ pMaxTempExcursion = maxTempExcursion; pMaxFaultTime = maxHeatingFaultTime; }
- void SetFaultDetectionParameters(float pMaxTempExcursion, float pMaxFaultTime)
- { maxTempExcursion = pMaxTempExcursion; maxHeatingFaultTime = pMaxFaultTime; }
+ GCodeResult SetFaultDetectionParameters(float pMaxTempExcursion, float pMaxFaultTime, const StringRef& reply);
float GetHighestTemperatureLimit() const; // Get the highest temperature limit
float GetLowestTemperatureLimit() const; // Get the lowest temperature limit
@@ -103,6 +102,7 @@ protected:
virtual HeaterMode GetMode() const = 0;
virtual GCodeResult SwitchOn(const StringRef& reply) = 0;
virtual GCodeResult UpdateModel(const StringRef& reply) = 0;
+ virtual GCodeResult UpdateFaultDetectionParameters(const StringRef& reply) = 0;
int GetSensorNumber() const { return sensorNumber; }
void SetSensorNumber(int sn) { sensorNumber = sn; }
diff --git a/src/Heating/LocalHeater.h b/src/Heating/LocalHeater.h
index dc76e69c..5c207714 100644
--- a/src/Heating/LocalHeater.h
+++ b/src/Heating/LocalHeater.h
@@ -51,6 +51,7 @@ protected:
HeaterMode GetMode() const override { return mode; }
GCodeResult SwitchOn(const StringRef& reply) override; // Turn the heater on and set the mode
GCodeResult UpdateModel(const StringRef& reply) override; // Called when the heater model has been changed
+ GCodeResult UpdateFaultDetectionParameters(const StringRef& reply) override { return GCodeResult::ok; }
private:
void SetHeater(float power) const; // Power is a fraction in [0,1]
diff --git a/src/Heating/RemoteHeater.cpp b/src/Heating/RemoteHeater.cpp
index c425213b..a1510a8d 100644
--- a/src/Heating/RemoteHeater.cpp
+++ b/src/Heating/RemoteHeater.cpp
@@ -197,6 +197,23 @@ GCodeResult RemoteHeater::UpdateModel(const StringRef& reply)
return GCodeResult::error;
}
+GCodeResult RemoteHeater::UpdateFaultDetectionParameters(const StringRef& reply)
+{
+ CanMessageBuffer *buf = CanMessageBuffer::Allocate();
+ if (buf != nullptr)
+ {
+ const CanRequestId rid = CanInterface::AllocateRequestId(boardAddress);
+ CanMessageSetHeaterFaultDetectionParameters * const msg = buf->SetupRequestMessage<CanMessageSetHeaterFaultDetectionParameters>(rid, CanInterface::GetCanAddress(), boardAddress);
+ msg->heater = GetHeaterNumber();
+ msg->maxFaultTime = GetMaxHeatingFaultTime();
+ msg->maxTempExcursion = GetMaxTemperatureExcursion();
+ return CanInterface::SendRequestAndGetStandardReply(buf, rid, reply);
+ }
+
+ reply.copy("No CAN buffer");
+ return GCodeResult::error;
+}
+
void RemoteHeater::UpdateRemoteStatus(CanAddress src, const CanHeaterReport& report)
{
if (src == boardAddress)
diff --git a/src/Heating/RemoteHeater.h b/src/Heating/RemoteHeater.h
index 3e9c0b12..f373f84a 100644
--- a/src/Heating/RemoteHeater.h
+++ b/src/Heating/RemoteHeater.h
@@ -38,6 +38,7 @@ protected:
HeaterMode GetMode() const override;
GCodeResult SwitchOn(const StringRef& reply) override; // Turn the heater on and set the mode
GCodeResult UpdateModel(const StringRef& reply) override; // Called when the heater model has been changed
+ GCodeResult UpdateFaultDetectionParameters(const StringRef& reply) override;
private:
static constexpr uint32_t RemoteStatusTimeout = 2000;
diff --git a/src/Movement/DDA.cpp b/src/Movement/DDA.cpp
index afb7a520..df134dff 100644
--- a/src/Movement/DDA.cpp
+++ b/src/Movement/DDA.cpp
@@ -1261,7 +1261,7 @@ void DDA::Prepare(uint8_t simMode, float extrusionPending[])
#if SUPPORT_CAN_EXPANSION
if (driver.IsRemote())
{
- CanMotion::AddMovement(*this, params, driver, delta);
+ CanMotion::AddMovement(*this, params, driver, delta, false);
}
else
#endif
@@ -1322,7 +1322,7 @@ void DDA::Prepare(uint8_t simMode, float extrusionPending[])
const DriverId driver = config.driverNumbers[i];
if (driver.IsRemote())
{
- CanMotion::AddMovement(*this, params, driver, delta);
+ CanMotion::AddMovement(*this, params, driver, delta, false);
}
}
#endif
@@ -1377,7 +1377,7 @@ void DDA::Prepare(uint8_t simMode, float extrusionPending[])
const DriverId driver = config.driverNumbers[i];
if (driver.IsRemote())
{
- CanMotion::AddMovement(*this, params, driver, delta);
+ CanMotion::AddMovement(*this, params, driver, delta, false);
}
}
#endif
@@ -1385,15 +1385,11 @@ void DDA::Prepare(uint8_t simMode, float extrusionPending[])
additionalAxisMotorsToEnable |= reprap.GetMove().GetKinematics().GetConnectedAxes(drive);
}
}
- else if (drive >= MaxAxes)
+ else
{
// It's an extruder drive
if (directionVector[drive] != 0.0)
{
- //TODO For now we allocate a DM even if the drive is remote so that we can use the code in PreparExtruder, but we ought to factor it out
- //TODO For remote drivers, I think we may be adjusting the net steps twice for pressure advance, once here in prepareExtruder and once on the expansion board
- DriveMovement* const pdm = DriveMovement::Allocate(drive, DMState::moving);
-
// If there is any extruder jerk in this move, in theory that means we need to instantly extrude or retract some amount of filament.
// Pass the speed change to PrepareExtruder
float speedChange;
@@ -1407,17 +1403,21 @@ void DDA::Prepare(uint8_t simMode, float extrusionPending[])
speedChange = 0.0;
}
- const bool stepsToDo = pdm->PrepareExtruder(*this, params, extrusionPending[drive - MaxAxes], speedChange, flags.usePressureAdvance);
-
#if SUPPORT_CAN_EXPANSION
const DriverId driver = platform.GetExtruderDriver(drive - MaxAxes);
if (driver.IsRemote())
{
- CanMotion::AddMovement(*this, params, driver, pdm->GetSteps());
+ const int32_t rawSteps = PrepareRemoteExtruder(drive, extrusionPending[drive - MaxAxes], speedChange);
+ if (rawSteps != 0)
+ {
+ CanMotion::AddMovement(*this, params, driver, rawSteps, flags.usePressureAdvance);
+ }
}
-#endif
- if (platform.GetDriversBitmap(drive) != 0) // if any of the drives is local
+ else
{
+#endif
+ DriveMovement* const pdm = DriveMovement::Allocate(drive, DMState::moving);
+ const bool stepsToDo = pdm->PrepareExtruder(*this, params, extrusionPending[drive - MaxAxes], speedChange, flags.usePressureAdvance);
reprap.GetPlatform().EnableLocalDrivers(drive);
if (stepsToDo)
@@ -1444,12 +1444,6 @@ void DDA::Prepare(uint8_t simMode, float extrusionPending[])
completedDMs = pdm;
}
}
- else
- {
- pdm->state = DMState::idle;
- pdm->nextDM = completedDMs;
- completedDMs = pdm;
- }
}
}
}
@@ -1472,7 +1466,7 @@ void DDA::Prepare(uint8_t simMode, float extrusionPending[])
const DriverId driver = config.driverNumbers[i];
if (driver.IsRemote())
{
- CanMotion::AddMovement(*this, params, driver, 0);
+ CanMotion::AddMovement(*this, params, driver, 0, false);
}
}
#endif
@@ -1481,7 +1475,7 @@ void DDA::Prepare(uint8_t simMode, float extrusionPending[])
const DDAState st = prev->state;
afterPrepare.moveStartTime = (st == DDAState::executing || st == DDAState::frozen)
- ? prev->afterPrepare.moveStartTime + prev->clocksNeeded // this move will follow the previous one, so calculate the start time assuming no more hiccups
+ ? prev->afterPrepare.moveStartTime + prev->clocksNeeded // this move will follow the previous one, so calculate the start time assuming no more hiccups
: StepTimer::GetInterruptClocks() + MovementStartDelayClocks; // else this move is the first so start it after a short delay
#if SUPPORT_CAN_EXPANSION
@@ -2031,6 +2025,56 @@ void DDA::LimitSpeedAndAcceleration(float maxSpeed, float maxAcceleration)
}
}
+#if SUPPORT_CAN_EXPANSION
+
+// Prepare a remote extruder, returning the number of steps we are going to do before allowing for pressure advance.
+// This replicates some of the functionality that DriveMovement::PrepareExtruder does for local extruder drives.
+int32_t DDA::PrepareRemoteExtruder(size_t drive, float& extrusionPending, float speedChange) const
+{
+ // Calculate the requested extrusion amount and a few other things
+ float extrusionRequired = totalDistance * directionVector[drive];
+
+#if SUPPORT_NONLINEAR_EXTRUSION
+ // Add the nonlinear extrusion correction to totalExtrusion
+ if (flags.isPrintingMove)
+ {
+ float a, b, limit;
+ if (reprap.GetPlatform().GetExtrusionCoefficients(drive - MaxAxes, a, b, limit))
+ {
+ const float averageExtrusionSpeed = (extrusionRequired * StepTimer::StepClockRate)/clocksNeeded;
+ const float factor = 1.0 + min<float>((averageExtrusionSpeed * a) + (averageExtrusionSpeed * averageExtrusionSpeed * b), limit);
+ extrusionRequired *= factor;
+ }
+ }
+#endif
+
+ // Add on any fractional extrusion pending from the previous move
+ extrusionRequired += extrusionPending;
+ const float rawStepsPerMm = reprap.GetPlatform().DriveStepsPerUnit(drive);
+ const int32_t originalSteps = lrintf(extrusionRequired * rawStepsPerMm);
+ int32_t netSteps;
+
+ if (flags.usePressureAdvance && extrusionRequired >= 0.0)
+ {
+ // Calculate the pressure advance parameters
+ const float compensationTime = reprap.GetPlatform().GetPressureAdvance(drive - MaxAxes);
+
+ // Calculate the net total extrusion to allow for compensation. It may be negative.
+ const float dv = extrusionRequired/totalDistance;
+ extrusionRequired += (endSpeed - startSpeed) * compensationTime * dv;
+ netSteps = lrintf(extrusionRequired * rawStepsPerMm);
+ }
+ else
+ {
+ netSteps = originalSteps;
+ }
+
+ extrusionPending = extrusionRequired - (float)netSteps/rawStepsPerMm;
+ return originalSteps;
+}
+
+#endif
+
#if SUPPORT_LASER
// Manage the laser power. Return the number of ticks until we should be called again, or 0 to be called at the start of the next move.
@@ -2082,4 +2126,5 @@ uint32_t DDA::ManageLaserPower() const
}
#endif
+
// End
diff --git a/src/Movement/DDA.h b/src/Movement/DDA.h
index 90f8c501..0799b96b 100644
--- a/src/Movement/DDA.h
+++ b/src/Movement/DDA.h
@@ -178,6 +178,10 @@ private:
float NormaliseXYZ(); // Make the direction vector unit-normal in XYZ
void AdjustAcceleration(); // Adjust the acceleration and deceleration to reduce ringing
+#if SUPPORT_CAN_EXPANSION
+ int32_t PrepareRemoteExtruder(size_t drive, float& extrusionPending, float speedChange) const;
+#endif
+
static void DoLookahead(DDARing& ring, DDA *laDDA) __attribute__ ((hot)); // Try to smooth out moves in the queue
static float Normalise(float v[], size_t dim1, size_t dim2); // Normalise a vector of dim1 dimensions to unit length in the first dim1 dimensions
static void Absolute(float v[], size_t dimensions); // Put a vector in the positive hyperquadrant
diff --git a/src/Movement/DriveMovement.cpp b/src/Movement/DriveMovement.cpp
index 015f3540..2d990b1c 100644
--- a/src/Movement/DriveMovement.cpp
+++ b/src/Movement/DriveMovement.cpp
@@ -211,7 +211,7 @@ bool DriveMovement::PrepareExtruder(const DDA& dda, const PrepParams& params, fl
// Add on any fractional extrusion pending from the previous move
extrusionRequired += extrusionPending;
dv = extrusionRequired/dda.totalDistance;
- direction = (dv >= 0.0);
+ direction = (extrusionRequired >= 0.0);
const float rawStepsPerMm = reprap.GetPlatform().DriveStepsPerUnit(drive);
const float effectiveStepsPerMm = fabsf(dv) * rawStepsPerMm;
@@ -249,7 +249,7 @@ bool DriveMovement::PrepareExtruder(const DDA& dda, const PrepParams& params, fl
mp.cart.accelStopStep = (uint32_t)(params.accelDistance * effectiveStepsPerMm) + 1;
}
- int32_t netSteps = (int32_t)(extrusionRequired * rawStepsPerMm);
+ int32_t netSteps = lrintf(extrusionRequired * rawStepsPerMm);
extrusionPending = extrusionRequired - (float)netSteps/rawStepsPerMm;
if (!direction)
diff --git a/src/Platform.cpp b/src/Platform.cpp
index 259cae88..d937891b 100644
--- a/src/Platform.cpp
+++ b/src/Platform.cpp
@@ -506,7 +506,7 @@ void Platform::Init()
{
extruderDrivers[extr].SetLocal(extr + MinAxes); // set up default extruder drive mapping
driveDriverBits[extr + MaxAxes] = StepPins::CalcDriverBitmap(extr + MinAxes);
- SetPressureAdvance(extr, 0.0); // no pressure advance
+ pressureAdvance[extr] = 0.0;
#if SUPPORT_NONLINEAR_EXTRUSION
nonlinearExtrusionA[extr] = nonlinearExtrusionB[extr] = 0.0;
nonlinearExtrusionLimit[extr] = DefaultNonlinearExtrusionLimit;
@@ -3592,12 +3592,73 @@ void Platform::AtxPowerOff(bool defer)
}
}
-void Platform::SetPressureAdvance(size_t extruder, float factor)
+GCodeResult Platform::SetPressureAdvance(float advance, GCodeBuffer& gb, const StringRef& reply)
{
- if (extruder < MaxExtruders)
+ GCodeResult rslt = GCodeResult::ok;
+
+#if SUPPORT_CAN_EXPANSION
+ CanDriversData canDriversToUpdate;
+#endif
+
+ if (gb.Seen('D'))
{
- pressureAdvance[extruder] = factor;
+ uint32_t eDrive[MaxExtruders];
+ size_t eCount = MaxExtruders;
+ gb.GetUnsignedArray(eDrive, eCount, false);
+ for (size_t i = 0; i < eCount; i++)
+ {
+ const uint32_t extruder = eDrive[i];
+ if (extruder >= reprap.GetGCodes().GetNumExtruders())
+ {
+ reply.printf("Invalid extruder number '%" PRIu32 "'", extruder);
+ rslt = GCodeResult::error;
+ break;
+ }
+ pressureAdvance[extruder] = advance;
+#if SUPPORT_CAN_EXPANSION
+ if (extruderDrivers[extruder].IsRemote())
+ {
+ canDriversToUpdate.AddEntry(extruderDrivers[extruder], (uint16_t)(advance * 1000.0));
+ }
+#endif
+ }
}
+ else
+ {
+ const Tool * const ct = reprap.GetCurrentTool();
+ if (ct == nullptr)
+ {
+ reply.copy("No tool selected");
+ rslt = GCodeResult::error;
+ }
+ else
+ {
+#if SUPPORT_CAN_EXPANSION
+ ct->IterateExtruders([this, advance, &canDriversToUpdate](unsigned int extruder)
+ {
+ pressureAdvance[extruder] = advance;
+ if (extruderDrivers[extruder].IsRemote())
+ {
+ canDriversToUpdate.AddEntry(extruderDrivers[extruder], (uint16_t)(advance * 1000.0));
+ }
+ }
+ );
+#else
+ ct->IterateExtruders([this, advance](unsigned int extruder)
+ {
+ pressureAdvance[extruder] = advance;
+ }
+ );
+#endif
+ }
+ }
+
+#if SUPPORT_CAN_EXPANSION
+ const bool remoteOk = CanInterface::SetRemotePressureAdvance(canDriversToUpdate, reply);
+ return (remoteOk) ? rslt : GCodeResult::error;
+#else
+ return rslt;
+#endif
}
#if SUPPORT_NONLINEAR_EXTRUSION
diff --git a/src/Platform.h b/src/Platform.h
index ecc3a971..590ecc05 100644
--- a/src/Platform.h
+++ b/src/Platform.h
@@ -413,7 +413,7 @@ public:
void SetAxisMinimum(size_t axis, float value, bool byProbing);
float AxisTotalLength(size_t axis) const;
float GetPressureAdvance(size_t extruder) const;
- void SetPressureAdvance(size_t extruder, float factor);
+ GCodeResult SetPressureAdvance(float advance, GCodeBuffer& gb, const StringRef& reply);
const AxisDriversConfig& GetAxisDriversConfig(size_t axis) const
pre(axis < MaxAxes)
diff --git a/src/Version.h b/src/Version.h
index 20d110d4..9a8fd5b3 100644
--- a/src/Version.h
+++ b/src/Version.h
@@ -20,7 +20,7 @@
#endif
#ifndef DATE
-# define DATE "2019-09-06b1"
+# define DATE "2019-09-09b2"
#endif
#define AUTHORS "reprappro, dc42, chrishamm, t3p3, dnewman, printm3d"