aboutsummaryrefslogtreecommitdiffstats
path: root/src/Xpl2Client.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/Xpl2Client.cpp')
-rw-r--r--src/Xpl2Client.cpp136
1 files changed, 136 insertions, 0 deletions
diff --git a/src/Xpl2Client.cpp b/src/Xpl2Client.cpp
index 102970e..40118b1 100644
--- a/src/Xpl2Client.cpp
+++ b/src/Xpl2Client.cpp
@@ -6,6 +6,8 @@
#include <QDebug>
+#include <algorithm>
+
bool Xpl2Client::s_wireDebug = false;
/* ------------------------------------------------------------------ */
@@ -163,6 +165,10 @@ Xpl2Client::Xpl2Client (QObject *parent) : QObject (parent)
connect (&m_retryTimer, &QTimer::timeout, this,
&Xpl2Client::retryConnection);
+
+ m_jettingScanTimer.setSingleShot (true);
+ connect (&m_jettingScanTimer, &QTimer::timeout, this,
+ &Xpl2Client::onJettingScanTimeout);
}
/* ------------------------------------------------------------------ */
@@ -301,6 +307,12 @@ Xpl2Client::disconnectFromProxy ()
void
Xpl2Client::getJcVersion ()
{
+ qWarning ("%s getJcVersion() is unreliable on this controller (wrong "
+ "printhead count) — do not use. See docs/DISCREPANCIES.md (D3).",
+ qPrintable (logTag (&m_commandSocket)));
+ emit errorOccurred (
+ QStringLiteral ("getJcVersion() is unreliable on this controller (wrong "
+ "printhead count) — do not use it."));
sendCommand (&m_commandSocket, "GS_JC_VERSION");
}
@@ -317,6 +329,14 @@ Xpl2Client::getPhVersion (int printheadId)
void
Xpl2Client::jettingAllOn ()
{
+ qWarning (
+ "%s jettingAllOn() is broken on this controller (only drives heads "
+ "before the first ID gap) — use jettingAvailableOn(). See "
+ "docs/DISCREPANCIES.md (D6).",
+ qPrintable (logTag (&m_commandSocket)));
+ emit errorOccurred (QStringLiteral (
+ "jettingAllOn() is broken on this controller — use jettingAvailableOn() "
+ "instead."));
sendCommand (&m_commandSocket, "CN_JETTING_ALL_ON");
}
@@ -329,6 +349,13 @@ Xpl2Client::jettingOn (const QString &jettingMask)
void
Xpl2Client::jettingOff ()
{
+ qWarning ("%s jettingOff() mirrors the jettingAllOn() defect on this "
+ "controller — use jettingAvailableOff(). See "
+ "docs/DISCREPANCIES.md (D6).",
+ qPrintable (logTag (&m_commandSocket)));
+ emit errorOccurred (
+ QStringLiteral ("jettingOff() is unreliable on this controller — use "
+ "jettingAvailableOff() instead."));
sendCommand (&m_commandSocket, "CN_JETTING_OFF");
}
@@ -346,6 +373,106 @@ Xpl2Client::phJettingOff (int printheadId)
}
void
+Xpl2Client::jettingAvailableOn ()
+{
+ startJettingScan (true);
+}
+
+void
+Xpl2Client::jettingAvailableOff ()
+{
+ startJettingScan (false);
+}
+
+bool
+Xpl2Client::phVersionIsAvailable (const QString &mcuFirmwareVersion,
+ const QString &fpgaFirmwareVersion,
+ const QString &fpgaHardwareVersion,
+ const QString &bootloaderVersion)
+{
+ // Absent printheads reply with all-zero versions. mcuHardwareVersion and
+ // mcuFirmwareVariant read "00" even on present heads, so they are not part
+ // of the test (see docs/DISCREPANCIES.md).
+ return mcuFirmwareVersion.toDouble () != 0.0
+ || fpgaFirmwareVersion.toDouble () != 0.0
+ || fpgaHardwareVersion.toDouble () != 0.0
+ || bootloaderVersion.toDouble () != 0.0;
+}
+
+void
+Xpl2Client::startJettingScan (bool turnOn)
+{
+ if (!m_connected)
+ {
+ emit errorOccurred (
+ QStringLiteral ("Not connected for jettingAvailable%1")
+ .arg (turnOn ? QStringLiteral ("On") : QStringLiteral ("Off")));
+ return;
+ }
+ if (m_jettingScanActive)
+ {
+ qWarning ("%s jettingAvailable: a scan is already in progress, ignoring",
+ qPrintable (logTag (&m_commandSocket)));
+ return;
+ }
+
+ m_jettingScanActive = true;
+ m_jettingScanTurnOn = turnOn;
+ m_jettingScanAvailable.clear ();
+ m_jettingScanPending.clear ();
+ for (int id = 1; id <= MaxProbedPrintheadId; ++id)
+ {
+ m_jettingScanPending.insert (id);
+ getPhVersion (id);
+ }
+ m_jettingScanTimer.start (JettingScanTimeoutMs);
+ qDebug ("%s jettingAvailable%s: probing %d printheads",
+ qPrintable (logTag (&m_commandSocket)), turnOn ? "On" : "Off",
+ MaxProbedPrintheadId);
+}
+
+void
+Xpl2Client::finishJettingScan ()
+{
+ m_jettingScanTimer.stop ();
+ m_jettingScanActive = false;
+ m_jettingScanPending.clear ();
+ std::sort (m_jettingScanAvailable.begin (), m_jettingScanAvailable.end ());
+
+ if (m_connected)
+ for (int id : m_jettingScanAvailable)
+ {
+ if (m_jettingScanTurnOn)
+ phJettingOn (id, QString::fromLatin1 (AllNozzlesOnMask));
+ else
+ phJettingOff (id);
+ }
+ qDebug ("%s jettingAvailable%s: jetted %lld available printhead(s)",
+ qPrintable (logTag (&m_commandSocket)),
+ m_jettingScanTurnOn ? "On" : "Off",
+ static_cast<long long> (m_jettingScanAvailable.size ()));
+ emit jettingAvailableComplete (m_jettingScanTurnOn, m_jettingScanAvailable);
+}
+
+void
+Xpl2Client::onJettingScanTimeout ()
+{
+ if (!m_jettingScanActive)
+ return;
+ qWarning (
+ "%s jettingAvailable: timed out waiting for %lld version reply(ies);"
+ " proceeding with %lld available",
+ qPrintable (logTag (&m_commandSocket)),
+ static_cast<long long> (m_jettingScanPending.size ()),
+ static_cast<long long> (m_jettingScanAvailable.size ()));
+ emit errorOccurred (
+ QStringLiteral (
+ "jettingAvailable: %1 printhead(s) did not respond in time")
+ .arg (m_jettingScanPending.size ()));
+ finishJettingScan ();
+}
+
+void
Xpl2Client::jcIdLedOn ()
{
sendCommand (&m_commandSocket, "CN_JC_ID_LED_ON");
@@ -789,6 +916,15 @@ Xpl2Client::handleGsPhVersion (const QVariantList &params)
.arg (bootVer));
emit phVersionReceived (cid, phId, mcuFw, mcuHw, mcuFwVar, fpgaFw, fpgaHw,
bootVer);
+
+ // Feed an in-progress jettingAvailableOn()/Off() scan.
+ if (m_jettingScanActive && m_jettingScanPending.remove (phId))
+ {
+ if (phVersionIsAvailable (mcuFw, fpgaFw, fpgaHw, bootVer))
+ m_jettingScanAvailable.append (phId);
+ if (m_jettingScanPending.isEmpty ())
+ finishJettingScan ();
+ }
}
bool