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--Developer-documentation/New ESP8266 WiFi module code for Duet WiFi.odtbin0 -> 20703 bytes
-rw-r--r--Release/Duet-0.6-0.8.5/Edge/DuetWebControl-1.15-b2.zip (renamed from Release/Duet-Ethernet/Edge/DuetWebControl-1.14a.zip)bin478936 -> 493248 bytes
-rw-r--r--Release/Duet-0.6-0.8.5/Edge/RepRapFirmware-1.18beta3.binbin0 -> 309220 bytes
-rw-r--r--Release/Duet-Ethernet/Edge/DuetEthernetFirmware-1.18alpha2.binbin279732 -> 0 bytes
-rw-r--r--Release/Duet-Ethernet/Edge/DuetEthernetFirmware-1.18beta3.binbin0 -> 282292 bytes
-rw-r--r--Release/Duet-Ethernet/Edge/DuetWebControl-1.15-b2.zipbin0 -> 493248 bytes
-rw-r--r--Release/Duet-WiFi/Edge/DuetWebControl-1.15-b2.binbin0 -> 3125248 bytes
-rw-r--r--Release/Duet-WiFi/Edge/DuetWiFiFirmware-1.18beta3.binbin0 -> 267460 bytes
-rw-r--r--Release/RADDS/Edge/RepRapFirmware-RADDS-1.17a.binbin238436 -> 0 bytes
-rw-r--r--Release/RADDS/Edge/RepRapFirmware-RADDS-1.17b.binbin238420 -> 0 bytes
-rw-r--r--Release/RADDS/Edge/RepRapFirmware-RADDS-1.17c.binbin238876 -> 0 bytes
-rw-r--r--Release/RADDS/Edge/RepRapFirmware-RADDS-1.18alpha2.binbin237180 -> 0 bytes
-rw-r--r--Release/RADDS/Edge/RepRapFirmware-RADDS-1.18beta2.bin (renamed from Release/RADDS/Edge/RepRapFirmware-1.18beta2.bin)bin238620 -> 238620 bytes
-rw-r--r--Release/RADDS/Edge/RepRapFirmware-RADDS-1.18beta3.binbin0 -> 239076 bytes
-rw-r--r--src/Configuration.h8
-rw-r--r--src/DuetNG/DuetEthernet/Network.cpp187
-rw-r--r--src/DuetNG/DuetEthernet/Network.h30
-rw-r--r--src/DuetNG/DuetEthernet/NetworkBuffer.h3
-rw-r--r--src/DuetNG/DuetEthernet/NetworkDefs.h4
-rw-r--r--src/DuetNG/DuetEthernet/NetworkTransaction.cpp6
-rw-r--r--src/DuetNG/DuetEthernet/Socket.cpp261
-rw-r--r--src/DuetNG/DuetEthernet/Socket.h3
-rw-r--r--src/DuetNG/DuetEthernet/Webserver.cpp66
-rw-r--r--src/DuetNG/Pins_DuetNG.h2
-rw-r--r--src/GCodes/GCodes.cpp41
-rw-r--r--src/GCodes/GCodes.h5
-rw-r--r--src/GCodes/GCodes2.cpp2
-rw-r--r--src/Movement/Grid.cpp20
-rw-r--r--src/Movement/Grid.h2
-rw-r--r--src/Movement/Move.cpp4
-rw-r--r--src/Platform.cpp46
-rw-r--r--src/Platform.h2
-rw-r--r--src/Reprap.cpp32
-rw-r--r--src/Reprap.h3
-rw-r--r--src/Version.h4
35 files changed, 491 insertions, 240 deletions
diff --git a/Developer-documentation/New ESP8266 WiFi module code for Duet WiFi.odt b/Developer-documentation/New ESP8266 WiFi module code for Duet WiFi.odt
new file mode 100644
index 00000000..4285cce9
--- /dev/null
+++ b/Developer-documentation/New ESP8266 WiFi module code for Duet WiFi.odt
Binary files differ
diff --git a/Release/Duet-Ethernet/Edge/DuetWebControl-1.14a.zip b/Release/Duet-0.6-0.8.5/Edge/DuetWebControl-1.15-b2.zip
index 18e5ba2c..b9ff2f4a 100644
--- a/Release/Duet-Ethernet/Edge/DuetWebControl-1.14a.zip
+++ b/Release/Duet-0.6-0.8.5/Edge/DuetWebControl-1.15-b2.zip
Binary files differ
diff --git a/Release/Duet-0.6-0.8.5/Edge/RepRapFirmware-1.18beta3.bin b/Release/Duet-0.6-0.8.5/Edge/RepRapFirmware-1.18beta3.bin
new file mode 100644
index 00000000..b522c1fa
--- /dev/null
+++ b/Release/Duet-0.6-0.8.5/Edge/RepRapFirmware-1.18beta3.bin
Binary files differ
diff --git a/Release/Duet-Ethernet/Edge/DuetEthernetFirmware-1.18alpha2.bin b/Release/Duet-Ethernet/Edge/DuetEthernetFirmware-1.18alpha2.bin
deleted file mode 100644
index 718c0bc7..00000000
--- a/Release/Duet-Ethernet/Edge/DuetEthernetFirmware-1.18alpha2.bin
+++ /dev/null
Binary files differ
diff --git a/Release/Duet-Ethernet/Edge/DuetEthernetFirmware-1.18beta3.bin b/Release/Duet-Ethernet/Edge/DuetEthernetFirmware-1.18beta3.bin
new file mode 100644
index 00000000..6bd8aa99
--- /dev/null
+++ b/Release/Duet-Ethernet/Edge/DuetEthernetFirmware-1.18beta3.bin
Binary files differ
diff --git a/Release/Duet-Ethernet/Edge/DuetWebControl-1.15-b2.zip b/Release/Duet-Ethernet/Edge/DuetWebControl-1.15-b2.zip
new file mode 100644
index 00000000..b9ff2f4a
--- /dev/null
+++ b/Release/Duet-Ethernet/Edge/DuetWebControl-1.15-b2.zip
Binary files differ
diff --git a/Release/Duet-WiFi/Edge/DuetWebControl-1.15-b2.bin b/Release/Duet-WiFi/Edge/DuetWebControl-1.15-b2.bin
new file mode 100644
index 00000000..aa52cfcd
--- /dev/null
+++ b/Release/Duet-WiFi/Edge/DuetWebControl-1.15-b2.bin
Binary files differ
diff --git a/Release/Duet-WiFi/Edge/DuetWiFiFirmware-1.18beta3.bin b/Release/Duet-WiFi/Edge/DuetWiFiFirmware-1.18beta3.bin
new file mode 100644
index 00000000..3e440ac3
--- /dev/null
+++ b/Release/Duet-WiFi/Edge/DuetWiFiFirmware-1.18beta3.bin
Binary files differ
diff --git a/Release/RADDS/Edge/RepRapFirmware-RADDS-1.17a.bin b/Release/RADDS/Edge/RepRapFirmware-RADDS-1.17a.bin
deleted file mode 100644
index 52507c43..00000000
--- a/Release/RADDS/Edge/RepRapFirmware-RADDS-1.17a.bin
+++ /dev/null
Binary files differ
diff --git a/Release/RADDS/Edge/RepRapFirmware-RADDS-1.17b.bin b/Release/RADDS/Edge/RepRapFirmware-RADDS-1.17b.bin
deleted file mode 100644
index 85feeda5..00000000
--- a/Release/RADDS/Edge/RepRapFirmware-RADDS-1.17b.bin
+++ /dev/null
Binary files differ
diff --git a/Release/RADDS/Edge/RepRapFirmware-RADDS-1.17c.bin b/Release/RADDS/Edge/RepRapFirmware-RADDS-1.17c.bin
deleted file mode 100644
index bb3d11de..00000000
--- a/Release/RADDS/Edge/RepRapFirmware-RADDS-1.17c.bin
+++ /dev/null
Binary files differ
diff --git a/Release/RADDS/Edge/RepRapFirmware-RADDS-1.18alpha2.bin b/Release/RADDS/Edge/RepRapFirmware-RADDS-1.18alpha2.bin
deleted file mode 100644
index fd0b872a..00000000
--- a/Release/RADDS/Edge/RepRapFirmware-RADDS-1.18alpha2.bin
+++ /dev/null
Binary files differ
diff --git a/Release/RADDS/Edge/RepRapFirmware-1.18beta2.bin b/Release/RADDS/Edge/RepRapFirmware-RADDS-1.18beta2.bin
index 2dd10462..2dd10462 100644
--- a/Release/RADDS/Edge/RepRapFirmware-1.18beta2.bin
+++ b/Release/RADDS/Edge/RepRapFirmware-RADDS-1.18beta2.bin
Binary files differ
diff --git a/Release/RADDS/Edge/RepRapFirmware-RADDS-1.18beta3.bin b/Release/RADDS/Edge/RepRapFirmware-RADDS-1.18beta3.bin
new file mode 100644
index 00000000..519afe48
--- /dev/null
+++ b/Release/RADDS/Edge/RepRapFirmware-RADDS-1.18beta3.bin
Binary files differ
diff --git a/src/Configuration.h b/src/Configuration.h
index dd1dc3e0..8a1dd091 100644
--- a/src/Configuration.h
+++ b/src/Configuration.h
@@ -44,7 +44,7 @@ const float NEARLY_ABS_ZERO = -273.0; // Celsius
const float ROOM_TEMPERATURE = 21.0; // Celsius
const float LONG_TIME = 300.0; // Seconds
-const float MINIMUM_TOOL_WARNING_INTERVAL = 4.0; // Seconds
+const uint32_t MinimumWarningInterval = 4000; // Milliseconds
// Comms defaults
@@ -114,11 +114,13 @@ const unsigned int DefaultPinWritePwmFreq = 500; // default PWM frequency for M4
// So 16 points need 704 bytes of stack space.
#ifdef DUET_NG
const size_t MaxGridProbePoints = 441; // 441 allows us to probe e.g. 400x400 at 20mm intervals
-const size_t MaxProbePoints = 64; // Maximum number of probe points
+const size_t MaxXGridPoints = 41; // Maximum number of grid points in one X row
+const size_t MaxProbePoints = 64; // Maximum number of G30 probe points
const size_t MaxDeltaCalibrationPoints = 64; // Should a power of 2 for speed
#else
const size_t MaxGridProbePoints = 121; // 121 allows us to probe 200x200 at 20mm intervals
-const size_t MaxProbePoints = 32; // Maximum number of probe points
+const size_t MaxXGridPoints = 21; // Maximum number of grid points in one X row
+const size_t MaxProbePoints = 32; // Maximum number of G30 probe points
const size_t MaxDeltaCalibrationPoints = 32; // Should a power of 2 for speed
#endif
diff --git a/src/DuetNG/DuetEthernet/Network.cpp b/src/DuetNG/DuetEthernet/Network.cpp
index 4bb45f3c..ea27bc86 100644
--- a/src/DuetNG/DuetEthernet/Network.cpp
+++ b/src/DuetNG/DuetEthernet/Network.cpp
@@ -12,6 +12,10 @@
#include "wizchip_conf.h"
#include "Wiznet/Internet/DHCP/dhcp.h"
+const size_t HttpProtocolIndex = 0, FtpProtocolIndex = 1, TelnetProtocolIndex = 2; // index of theHTTP service above
+const Port DefaultPortNumbers[NumProtocols] = { DefaultHttpPort, DefaultFtpPort, DefaultTelnetPort };
+const char * const ProtocolNames[NumProtocols] = { "HTTP", "FTP", "TELNET" };
+
void Network::SetIPAddress(const uint8_t p_ipAddress[], const uint8_t p_netmask[], const uint8_t p_gateway[])
{
memcpy(ipAddress, p_ipAddress, sizeof(ipAddress));
@@ -21,8 +25,13 @@ void Network::SetIPAddress(const uint8_t p_ipAddress[], const uint8_t p_netmask[
Network::Network(Platform* p)
: platform(p), lastTickMillis(0),
- httpPort(DefaultHttpPort), state(NetworkState::disabled), activated(false)
+ state(NetworkState::disabled), activated(false)
{
+ for (size_t i = 0; i < NumProtocols; ++i)
+ {
+ portNumbers[i] = DefaultPortNumbers[i];
+ protocolEnabled[i] = (i == HttpProtocolIndex);
+ }
}
void Network::Init()
@@ -40,6 +49,136 @@ void Network::Init()
strcpy(hostname, HOSTNAME);
}
+void Network::EnableProtocol(int protocol, int port, int secure, StringRef& reply)
+{
+ if (secure != 0 && secure != -1)
+ {
+ reply.copy("Error: this firmware does not support TLS");
+ }
+ else if (protocol >= 0 && protocol < (int)NumProtocols)
+ {
+ const Port portToUse = (port < 0) ? DefaultPortNumbers[protocol] : port;
+ if (portToUse != portNumbers[protocol] && state == NetworkState::active)
+ {
+ // We need to shut down and restart the protocol if it is active because the port number has changed
+ ShutdownProtocol(protocol);
+ protocolEnabled[protocol] = false;
+ }
+ portNumbers[protocol] = portToUse;
+ if (!protocolEnabled[protocol])
+ {
+ protocolEnabled[protocol] = true;
+ if (state == NetworkState::active)
+ {
+ StartProtocol(protocol);
+#if 0 // mdns not implemented yet
+ if (state == NetworkState::active)
+ {
+ DoMdnsAnnounce();
+ }
+#endif
+ }
+ }
+ ReportOneProtocol(protocol, reply);
+ }
+ else
+ {
+ reply.copy("Invalid protocol parameter");
+ }
+}
+
+void Network::DisableProtocol(int protocol, StringRef& reply)
+{
+ if (protocol >= 0 && protocol < (int)NumProtocols)
+ {
+ if (state == NetworkState::active)
+ {
+ ShutdownProtocol(protocol);
+ }
+ protocolEnabled[protocol] = false;
+ ReportOneProtocol(protocol, reply);
+ }
+ else
+ {
+ reply.copy("Invalid protocol parameter");
+ }
+}
+
+void Network::StartProtocol(size_t protocol)
+{
+ switch(protocol)
+ {
+ case HttpProtocolIndex:
+ for (SocketNumber skt = 0; skt < NumHttpSockets; ++skt)
+ {
+ sockets[skt].Init(skt, portNumbers[HttpProtocolIndex]);
+ }
+ break;
+
+ case FtpProtocolIndex:
+ sockets[FtpSocketNumber].Init(FtpSocketNumber, portNumbers[FtpProtocolIndex]);
+ break;
+
+ case TelnetProtocolIndex:
+ sockets[TelnetSocketNumber].Init(TelnetSocketNumber, portNumbers[TelnetProtocolIndex]);
+ break;
+
+ default:
+ break;
+ }
+}
+
+void Network::ShutdownProtocol(size_t protocol)
+{
+ switch(protocol)
+ {
+ case HttpProtocolIndex:
+ for (SocketNumber skt = 0; skt < NumHttpSockets; ++skt)
+ {
+ sockets[skt].TerminateAndDisable();
+ }
+ break;
+
+ case FtpProtocolIndex:
+ sockets[FtpSocketNumber].TerminateAndDisable();
+ sockets[FtpDataSocketNumber].TerminateAndDisable();
+ break;
+
+ case TelnetProtocolIndex:
+ sockets[TelnetSocketNumber].TerminateAndDisable();
+ break;
+
+ default:
+ break;
+ }
+}
+
+// Report the protocols and ports in use
+void Network::ReportProtocols(StringRef& reply) const
+{
+ reply.Clear();
+ for (size_t i = 0; i < NumProtocols; ++i)
+ {
+ if (i != 0)
+ {
+ reply.cat('\n');
+ }
+ ReportOneProtocol(i, reply);
+ }
+}
+
+void Network::ReportOneProtocol(size_t protocol, StringRef& reply) const
+{
+ if (protocolEnabled[protocol])
+ {
+ reply.catf("%s is enabled on port %u", ProtocolNames[protocol], portNumbers[protocol]);
+ }
+ else
+ {
+ reply.catf("%s is disabled", ProtocolNames[protocol]);
+ }
+}
+
// This is called at the end of config.g processing.
// Start the network if it was enabled
void Network::Activate()
@@ -81,8 +220,8 @@ void Network::Spin(bool full)
else
{
// debugPrintf("Link established, network running\n");
- InitSockets();
state = NetworkState::active;
+ InitSockets();
}
}
break;
@@ -106,8 +245,8 @@ void Network::Spin(bool full)
// Send mDNS announcement so that some routers can perform hostname mapping
// if this board is connected via a non-IGMP capable WiFi bridge (like the TP-Link WR701N)
//mdns_announce();
- InitSockets();
state = NetworkState::active;
+ InitSockets();
}
}
else
@@ -241,16 +380,6 @@ const uint8_t *Network::GetIPAddress() const
return ipAddress;
}
-void Network::SetHttpPort(uint16_t port)
-{
- httpPort = port;
-}
-
-uint16_t Network::GetHttpPort() const
-{
- return httpPort;
-}
-
void Network::SetHostname(const char *name)
{
size_t i = 0;
@@ -333,10 +462,19 @@ NetworkTransaction *Network::GetTransaction(Connection conn)
return nullptr;
}
-void Network::OpenDataPort(Port port)
+Port Network::GetHttpPort() const
{
- sockets[FtpDataSocketNumber].Init(FtpDataSocketNumber, port);
- sockets[FtpDataSocketNumber].Poll(false);
+ return portNumbers[HttpProtocolIndex];
+}
+
+Port Network::GetFtpPort() const
+{
+ return portNumbers[FtpProtocolIndex];
+}
+
+Port Network::GetTelnetPort() const
+{
+ return portNumbers[TelnetProtocolIndex];
}
Port Network::GetDataPort() const
@@ -344,6 +482,13 @@ Port Network::GetDataPort() const
return sockets[FtpDataSocketNumber].GetLocalPort();
}
+void Network::OpenDataPort(Port port)
+{
+ sockets[FtpDataSocketNumber].Init(FtpDataSocketNumber, port);
+ delayMicroseconds(100); // give the W5500 time to process the command (not sure we need this)
+ sockets[FtpDataSocketNumber].Poll(true);
+}
+
// Close FTP data port and purge associated PCB
void Network::CloseDataPort()
{
@@ -366,13 +511,13 @@ bool Network::AcquireTransaction(size_t socketNumber)
void Network::InitSockets()
{
- for (SocketNumber skt = 0; skt < NumHttpSockets; ++skt)
+ for (size_t i = 0; i < NumProtocols; ++i)
{
- sockets[skt].Init(skt, httpPort);
+ if (protocolEnabled[i])
+ {
+ StartProtocol(i);
+ }
}
- sockets[FtpSocketNumber].Init(FtpSocketNumber, FTP_PORT);
- sockets[FtpDataSocketNumber].Init(FtpDataSocketNumber, 0); // FTP data port is allocated dynamically
- sockets[TelnetSocketNumber].Init(TelnetSocketNumber, TELNET_PORT);
nextSocketToPoll = currentTransactionSocketNumber = 0;
}
diff --git a/src/DuetNG/DuetEthernet/Network.h b/src/DuetNG/DuetEthernet/Network.h
index 7a847494..f35ab055 100644
--- a/src/DuetNG/DuetEthernet/Network.h
+++ b/src/DuetNG/DuetEthernet/Network.h
@@ -22,6 +22,8 @@ const SocketNumber TelnetSocketNumber = 6;
const size_t NumTcpSockets = 7;
const SocketNumber DhcpSocketNumber = 7; // TODO can we allocate this dynamically when required, to allow more http sockets most of the time?
+const size_t NumProtocols = 3; // number of network protocols we support
+
class Platform;
// The main network class that drives the network.
@@ -40,6 +42,10 @@ public:
void Start();
void Stop();
+ void EnableProtocol(int protocol, int port, int secure, StringRef& reply);
+ void DisableProtocol(int protocol, StringRef& reply);
+ void ReportProtocols(StringRef& reply) const;
+
bool Lock();
void Unlock();
bool InLwip() const;
@@ -48,8 +54,9 @@ public:
void Disable();
bool IsEnabled() const;
- void SetHttpPort(Port port);
Port GetHttpPort() const;
+ Port GetFtpPort() const;
+ Port GetTelnetPort() const;
void SetHostname(const char *name);
@@ -94,6 +101,15 @@ private:
bool AcquireTransaction(size_t socketNumber)
pre(socketNumber < NumTcpSockets);
+ void StartProtocol(size_t protocol)
+ pre(protocol < NumProtocols);
+
+ void ShutdownProtocol(size_t protocol)
+ pre(protocol < NumProtocols);
+
+ void ReportOneProtocol(size_t protocol, StringRef& reply) const
+ pre(protocol < NumProtocols);
+
Platform * const platform;
float longWait;
uint32_t lastTickMillis;
@@ -102,15 +118,17 @@ private:
size_t nextSocketToPoll; // next TCP socket number to poll for read/write operations
size_t currentTransactionSocketNumber; // the socket number of the last transaction we passed to the web server
- Port httpPort;
- uint8_t ipAddress[4];
- uint8_t netmask[4];
- uint8_t gateway[4];
- char hostname[16]; // Limit DHCP hostname to 15 characters + terminating 0
+ Port portNumbers[NumProtocols]; // port number used for each protocol
+ bool protocolEnabled[NumProtocols]; // whether each protocol is enabled
NetworkState state;
bool activated;
bool usingDhcp;
+
+ uint8_t ipAddress[4];
+ uint8_t netmask[4];
+ uint8_t gateway[4];
+ char hostname[16]; // Limit DHCP hostname to 15 characters + terminating 0
};
#endif
diff --git a/src/DuetNG/DuetEthernet/NetworkBuffer.h b/src/DuetNG/DuetEthernet/NetworkBuffer.h
index b7ffcc0a..17b39f79 100644
--- a/src/DuetNG/DuetEthernet/NetworkBuffer.h
+++ b/src/DuetNG/DuetEthernet/NetworkBuffer.h
@@ -47,6 +47,9 @@ public:
// Clear this buffer and release any successors
void Empty();
+ // Reset the data pointer to the start of the buffer
+ void ResetPointer() { readPointer = 0; }
+
// Append a buffer to a list
static void AppendToList(NetworkBuffer **list, NetworkBuffer *b);
diff --git a/src/DuetNG/DuetEthernet/NetworkDefs.h b/src/DuetNG/DuetEthernet/NetworkDefs.h
index e752f96a..ad175ba2 100644
--- a/src/DuetNG/DuetEthernet/NetworkDefs.h
+++ b/src/DuetNG/DuetEthernet/NetworkDefs.h
@@ -30,8 +30,8 @@ const uint8_t DefaultNetMask[4] = { 255, 255, 255, 0 };
const uint8_t DefaultGateway[4] = { 0, 0, 0, 0 };
const Port DefaultHttpPort = 80;
-const Port FTP_PORT = 21;
-const Port TELNET_PORT = 23;
+const Port DefaultFtpPort = 21;
+const Port DefaultTelnetPort = 23;
const unsigned int TCP_MSS = 1460;
diff --git a/src/DuetNG/DuetEthernet/NetworkTransaction.cpp b/src/DuetNG/DuetEthernet/NetworkTransaction.cpp
index 9012f1f8..0a4267a0 100644
--- a/src/DuetNG/DuetEthernet/NetworkTransaction.cpp
+++ b/src/DuetNG/DuetEthernet/NetworkTransaction.cpp
@@ -254,7 +254,11 @@ void NetworkTransaction::Commit(bool keepConnectionAlive)
//
void NetworkTransaction::Defer(DeferralMode mode)
{
- if (mode == DeferralMode::DiscardData)
+ if (mode == DeferralMode::ResetData)
+ {
+ cs->ResetDataPointer();
+ }
+ else if (mode == DeferralMode::DiscardData)
{
cs->DiscardReceivedData(); // discard the incoming data, because we don't need to process it any more
}
diff --git a/src/DuetNG/DuetEthernet/Socket.cpp b/src/DuetNG/DuetEthernet/Socket.cpp
index b39b4c7e..bfc019dc 100644
--- a/src/DuetNG/DuetEthernet/Socket.cpp
+++ b/src/DuetNG/DuetEthernet/Socket.cpp
@@ -17,7 +17,7 @@
//***************************************************************************************************
// Socket class
-Socket::Socket() : currentTransaction(nullptr), receivedData(nullptr), state(SocketState::inactive)
+Socket::Socket() : currentTransaction(nullptr), receivedData(nullptr), state(SocketState::disabled)
{
}
@@ -29,6 +29,12 @@ void Socket::Init(SocketNumber skt, Port serverPort)
ReInit();
}
+void Socket::TerminateAndDisable()
+{
+ Terminate();
+ state = SocketState::disabled;
+}
+
void Socket::ReInit()
{
// Discard any received data
@@ -66,19 +72,26 @@ void Socket::ReleaseTransaction()
// Terminate a connection immediately
void Socket::Terminate()
{
- disconnectNoWait(socketNum);
- isTerminated = true;
- state = SocketState::inactive;
- while (receivedData != nullptr)
+ if (state != SocketState::disabled)
{
- receivedData = receivedData->Release();
+ disconnectNoWait(socketNum);
+ isTerminated = true;
+ state = SocketState::inactive;
+ while (receivedData != nullptr)
+ {
+ receivedData = receivedData->Release();
+ }
+ ReleaseTransaction();
}
- ReleaseTransaction();
}
// Test whether we have a connection on this socket
bool Socket::IsConnected() const
{
+ if (state == SocketState::disabled)
+ {
+ return false;
+ }
const uint8_t stat = getSn_SR(socketNum);
return stat == SOCK_ESTABLISHED || stat == SOCK_CLOSE_WAIT;
}
@@ -86,12 +99,20 @@ bool Socket::IsConnected() const
// Return true if there is or may soon be more data to read
bool Socket::HasMoreDataToRead() const
{
+ if (state == SocketState::disabled)
+ {
+ return false;
+ }
return (receivedData != nullptr && receivedData->TotalRemaining() != 0) // already have more data
|| getSn_SR(socketNum) == SOCK_ESTABLISHED; // still fully connected, so we may receive more
}
bool Socket::CanWrite() const
{
+ if (state == SocketState::disabled)
+ {
+ return false;
+ }
const uint8_t stat = getSn_SR(socketNum);
return stat == SOCK_ESTABLISHED || stat == SOCK_CLOSE_WAIT;
}
@@ -146,151 +167,151 @@ bool Socket::ReadBuffer(const char *&buffer, size_t &len)
// Poll a socket to see if it needs to be serviced
void Socket::Poll(bool full)
{
- // The mechanism used by class OutputBuffer and now by NetworkBuffer of marking data taken as soon as we return a pointer to it
- // is DANGEROUS and will have to be rewritten for RTOS. We need to recycle empty buffers, otherwise multiple file uploads get stalled.
- // However, we MUST NOT do this until the data had DEFINITELY been finished with. Temporarily use this conditional to avoid a bug
- // with data corruption when this is not the case.
- if (full)
+ if (state != SocketState::disabled)
{
- // Recycle any receive buffers that are now empty
- while (receivedData != nullptr && receivedData->IsEmpty())
+ // The mechanism used by class OutputBuffer and now by NetworkBuffer of marking data taken as soon as we return a pointer to it
+ // is DANGEROUS and will have to be rewritten for RTOS. We need to recycle empty buffers, otherwise multiple file uploads get stalled.
+ // However, we MUST NOT do this until the data had DEFINITELY been finished with. Temporarily use this conditional to avoid a bug
+ // with data corruption when this is not the case.
+ if (full)
{
- receivedData = receivedData->Release(); // discard empty buffer at head of chain
+ // Recycle any receive buffers that are now empty
+ while (receivedData != nullptr && receivedData->IsEmpty())
+ {
+ receivedData = receivedData->Release(); // discard empty buffer at head of chain
+ }
}
- }
- switch(getSn_SR(socketNum))
- {
- case SOCK_INIT:
- // Socket has been initialised but is not listening yet
- if (localPort != 0) // localPort for the FTP data socket is 0 until we have decided what port number to use
+ switch(getSn_SR(socketNum))
{
- ExecCommand(socketNum, Sn_CR_LISTEN);
- state = SocketState::listening;
- }
- break;
+ case SOCK_INIT:
+ // Socket has been initialised but is not listening yet
+ if (localPort != 0) // localPort for the FTP data socket is 0 until we have decided what port number to use
+ {
+ ExecCommand(socketNum, Sn_CR_LISTEN);
+ state = SocketState::listening;
+ }
+ break;
- case SOCK_LISTEN: // Socket is listening but no client has connected to it yet
- break;
+ case SOCK_LISTEN: // Socket is listening but no client has connected to it yet
+ break;
- case SOCK_ESTABLISHED: // A client is connected to this socket
- if (getSn_IR(socketNum) & Sn_IR_CON)
- {
- // New connection, so retrieve the sending IP address and port, and clear the interrupt
- getSn_DIPR(socketNum, reinterpret_cast<uint8_t*>(&remoteIPAddress));
- remotePort = getSn_DPORT(socketNum);
- setSn_IR(socketNum, Sn_IR_CON);
- }
+ case SOCK_ESTABLISHED: // A client is connected to this socket
+ if (getSn_IR(socketNum) & Sn_IR_CON)
+ {
+ // New connection, so retrieve the sending IP address and port, and clear the interrupt
+ getSn_DIPR(socketNum, reinterpret_cast<uint8_t*>(&remoteIPAddress));
+ remotePort = getSn_DPORT(socketNum);
+ setSn_IR(socketNum, Sn_IR_CON);
+ }
- if (state == SocketState::listening) // if it is a new connection
- {
- if (socketNum == FtpSocketNumber || socketNum == FtpDataSocketNumber || socketNum == TelnetSocketNumber)
+ if (state == SocketState::listening) // if it is a new connection
{
- // FTP and Telnet protocols need a connection reply, so tell the Webserver module about the new connection
- if (currentTransaction == nullptr)
+ if (socketNum == FtpSocketNumber || socketNum == FtpDataSocketNumber || socketNum == TelnetSocketNumber)
{
- currentTransaction = NetworkTransaction::Allocate();
- if (currentTransaction != nullptr)
+ // FTP and Telnet protocols need a connection reply, so tell the Webserver module about the new connection
+ if (currentTransaction == nullptr)
{
- currentTransaction->Set(this, TransactionStatus::connected);
+ currentTransaction = NetworkTransaction::Allocate();
+ if (currentTransaction != nullptr)
+ {
+ currentTransaction->Set(this, TransactionStatus::connected);
+ }
+ }
+ else
+ {
+ // This should not happen
+// debugPrintf("ERROR:currentTransation should be null but isn't\n");
}
}
- else
+ state = SocketState::connected;
+ }
+
+ {
+ // See if the socket has received any data
+ const uint16_t len = getSn_RX_RSR(socketNum);
+ if (len != 0)
{
- // This should not happen
-// debugPrintf("ERROR:currentTransation should be null but isn't\n");
+// debugPrintf("%u available\n", len);
+ // There is data available, so allocate a buffer
+ //TODO: if there is already a buffer and it is in an appropriate state (i.e. receiving) and it has enough room, we could just append the data
+ NetworkBuffer * const buf = NetworkBuffer::Allocate();
+ if (buf != nullptr)
+ {
+ wiz_recv_data(socketNum, buf->Data(), len);
+ ExecCommand(socketNum, Sn_CR_RECV);
+ buf->dataLength = (size_t)len;
+ buf->readPointer = 0;
+ NetworkBuffer::AppendToList(&receivedData, buf);
+ }
+// else debugPrintf("no buffer\n");
}
}
- state = SocketState::connected;
- }
- {
- // See if the socket has received any data
- const uint16_t len = getSn_RX_RSR(socketNum);
- if (len != 0)
+ if (currentTransaction == nullptr && receivedData != nullptr)
{
-// debugPrintf("%u available\n", len);
- // There is data available, so allocate a buffer
- //TODO: if there is already a buffer and it is in an appropriate state (i.e. receiving) and it has enough room, we could just append the data
- NetworkBuffer * const buf = NetworkBuffer::Allocate();
- if (buf != nullptr)
+ currentTransaction = NetworkTransaction::Allocate();
+ if (currentTransaction != nullptr)
{
- wiz_recv_data(socketNum, buf->Data(), len);
- ExecCommand(socketNum, Sn_CR_RECV);
- buf->dataLength = (size_t)len;
- buf->readPointer = 0;
- NetworkBuffer::AppendToList(&receivedData, buf);
+ currentTransaction->Set(this, TransactionStatus::receiving);
}
-// else debugPrintf("no buffer\n");
}
- }
- if (currentTransaction == nullptr && receivedData != nullptr)
- {
- currentTransaction = NetworkTransaction::Allocate();
- if (currentTransaction != nullptr)
+ // See if we can send any data.
+ // Currently we don't send if we are being called from hsmci because we don't want to risk releasing a buffer that we may be reading data into.
+ // We could use a buffer locking mechanism instead. However, the speed of sending is not critical, so we don't do that yet.
+ if (full && IsSending() && TrySendData())
{
- currentTransaction->Set(this, TransactionStatus::receiving);
+ const bool closeAfterSending = currentTransaction->CloseAfterSending();
+ ReleaseTransaction();
+ if (closeAfterSending)
+ {
+ ExecCommand(socketNum, Sn_CR_DISCON);
+ state = SocketState::closing;
+ DiscardReceivedData();
+ }
}
- }
+ break;
- // See if we can send any data.
- // Currently we don't send if we are being called from hsmci because we don't want to risk releasing a buffer that we may be reading data into.
- // We could use a buffer locking mechanism instead. However, the speed of sending is not critical, so we don't do that yet.
- if (full && IsSending() && TrySendData())
- {
- const bool closeAfterSending = currentTransaction->CloseAfterSending();
- ReleaseTransaction();
- if (closeAfterSending)
+ case SOCK_CLOSE_WAIT: // A client has asked to disconnect
+ state = SocketState::clientDisconnecting;
+ if (IsSending() && TrySendData())
{
- ExecCommand(socketNum, Sn_CR_DISCON);
- state = SocketState::closing;
- DiscardReceivedData();
+ ReleaseTransaction(); // finished sending
}
- }
- break;
-
- case SOCK_CLOSE_WAIT: // A client has asked to disconnect
-#ifdef _HTTPSERVER_DEBUG_
- printf("> HTTPSocket[%d] : ClOSE_WAIT\r\n", socketNum);
-#endif
- state = SocketState::clientDisconnecting;
- if (IsSending() && TrySendData())
- {
- ReleaseTransaction(); // finished sending
- }
- // Although there is a transaction status for a client disconnecting, the webserver module does nothing with those transactions.
- // So we don't bother to generate them here.
- if (!IsSending() && currentTransaction == nullptr)
- {
- if (HasMoreDataToRead())
+ // Although there is a transaction status for a client disconnecting, the webserver module does nothing with those transactions.
+ // So we don't bother to generate them here.
+ if (!IsSending() && currentTransaction == nullptr)
{
- // We have more received data, so make it available to the webserver to process
- currentTransaction = NetworkTransaction::Allocate();
- if (currentTransaction != nullptr)
+ if (HasMoreDataToRead())
{
- currentTransaction->Set(this, TransactionStatus::receiving);
+ // We have more received data, so make it available to the webserver to process
+ currentTransaction = NetworkTransaction::Allocate();
+ if (currentTransaction != nullptr)
+ {
+ currentTransaction->Set(this, TransactionStatus::receiving);
+ }
+ }
+ else
+ {
+ ExecCommand(socketNum, Sn_CR_DISCON);
+ state = SocketState::closing;
}
}
- else
+ break;
+
+ case SOCK_CLOSED:
+ if (full) // don't make a call to webserver if we might be in it already
{
- ExecCommand(socketNum, Sn_CR_DISCON);
- state = SocketState::closing;
+ reprap.GetWebserver()->ConnectionLost(this); // the webserver needs this to be called for both graceful and disgraceful disconnects
+ ReInit();
}
- }
- break;
+ break;
- case SOCK_CLOSED:
- if (full) // don't make a call to webserver if we might be in it already
- {
- reprap.GetWebserver()->ConnectionLost(this); // the webserver needs this to be called for both graceful and disgraceful disconnects
- ReInit();
+ default:
+ break;
}
- break;
-
- default:
- break;
}
}
@@ -367,6 +388,14 @@ void Socket::DiscardReceivedData()
}
}
+void Socket::ResetDataPointer()
+{
+ if (receivedData != nullptr)
+ {
+ receivedData->ResetPointer();
+ }
+}
+
// The webserver calls this to tell the socket that it needs a transaction, e.g. for sending a Telnet or FTP response.
// An empty transaction will do.
// Return true if we can do it, false if the connection is closed or closing.
diff --git a/src/DuetNG/DuetEthernet/Socket.h b/src/DuetNG/DuetEthernet/Socket.h
index 96154a53..a9cc6ee4 100644
--- a/src/DuetNG/DuetEthernet/Socket.h
+++ b/src/DuetNG/DuetEthernet/Socket.h
@@ -17,6 +17,7 @@ class Socket
public:
Socket();
void Init(SocketNumber s, Port serverPort);
+ void TerminateAndDisable();
void Poll(bool full);
Port GetLocalPort() const { return localPort; }
uint32_t GetRemoteIP() const { return remoteIPAddress; }
@@ -34,11 +35,13 @@ public:
bool IsPersistentConnection() const { return persistConnection; }
bool CanWrite() const;
void DiscardReceivedData();
+ void ResetDataPointer();
bool AcquireTransaction();
private:
enum class SocketState : uint8_t
{
+ disabled,
inactive,
listening,
connected,
diff --git a/src/DuetNG/DuetEthernet/Webserver.cpp b/src/DuetNG/DuetEthernet/Webserver.cpp
index fa11a56a..6a5b5c6d 100644
--- a/src/DuetNG/DuetEthernet/Webserver.cpp
+++ b/src/DuetNG/DuetEthernet/Webserver.cpp
@@ -150,26 +150,17 @@ void Webserver::Spin()
// Take care of different protocol types here
ProtocolInterpreter *interpreter;
const uint16_t localPort = currentTransaction->GetLocalPort();
- switch (localPort)
+ if (localPort == network->GetHttpPort())
{
- 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;
- }
- else
- {
- interpreter = ftpInterpreter;
- }
- break;
+ interpreter = httpInterpreter;
+ }
+ else if (localPort == network->GetTelnetPort())
+ {
+ interpreter = telnetInterpreter;
+ }
+ else
+ {
+ interpreter = ftpInterpreter;
}
// See if we have to print some debug info
@@ -345,28 +336,20 @@ void Webserver::ConnectionLost(Connection conn)
// Inform protocol handlers that this connection has been lost
const uint16_t localPort = Network::GetLocalPort(conn);
ProtocolInterpreter *interpreter;
- switch (localPort)
+ if (localPort == network->GetHttpPort())
+ {
+ interpreter = httpInterpreter;
+ }
+ else if (localPort == network->GetFtpPort() || localPort == network->GetDataPort())
{
- case FTP_PORT: /* FTP */
interpreter = ftpInterpreter;
- break;
-
- case TELNET_PORT: /* Telnet */
+ }
+ else if (localPort == network->GetTelnetPort())
+ {
interpreter = telnetInterpreter;
- break;
-
- default: /* HTTP and FTP data */
- if (localPort == network->GetHttpPort())
- {
- interpreter = httpInterpreter;
- break;
- }
- else if (localPort == network->GetDataPort())
- {
- interpreter = ftpInterpreter;
- break;
- }
-
+ }
+ else
+ {
platform->MessageF(GENERIC_MESSAGE, "Error: Webserver should handle disconnect event at local port %d, but no handler was found!\n", localPort);
return;
}
@@ -1956,7 +1939,7 @@ void Webserver::FtpInterpreter::ConnectionEstablished()
// Is this a new connection on the data port?
NetworkTransaction * const transaction = webserver->currentTransaction;
- if (transaction->GetLocalPort() != FTP_PORT)
+ if (transaction->GetLocalPort() != network->GetFtpPort())
{
if (state == waitingForPasvPort)
{
@@ -1995,7 +1978,7 @@ void Webserver::FtpInterpreter::ConnectionLost(Connection conn)
{
connectedClients--;
- if (Network::GetLocalPort(conn) != FTP_PORT)
+ if (Network::GetLocalPort(conn) != network->GetFtpPort())
{
// Did everything work out? Usually this is only called for uploads
if (network->AcquireFTPTransaction())
@@ -2196,7 +2179,7 @@ void Webserver::FtpInterpreter::ProcessLine()
const uint8_t * const ip_address = network->GetIPAddress();
/* open random port > 1023 */
- uint16_t pasv_port = random(1024, 65535);
+ const uint16_t pasv_port = random(1024, 65535);
network->OpenDataPort(pasv_port);
portOpenTime = millis();
state = waitingForPasvPort;
@@ -2327,7 +2310,6 @@ void Webserver::FtpInterpreter::ProcessLine()
{
webserver->currentTransaction->Defer(DeferralMode::ResetData);
}
-
break;
case pasvPortConnected:
diff --git a/src/DuetNG/Pins_DuetNG.h b/src/DuetNG/Pins_DuetNG.h
index 8294ea12..f2a64da7 100644
--- a/src/DuetNG/Pins_DuetNG.h
+++ b/src/DuetNG/Pins_DuetNG.h
@@ -108,6 +108,8 @@ const Pin PowerMonitor5vDetectPin = 29; // AFE1_AD1/PB3 5V regulator inp
const float PowerFailVoltageRange = 11.0 * 3.3; // we use an 11:1 voltage divider
+const Pin VssaSensePin = 103;
+
// Digital pin number to turn the IR LED on (high) or off (low)
const Pin Z_PROBE_MOD_PIN = 34; // Digital pin number to turn the IR LED on (high) or off (low) on Duet v0.6 and v1.0 (PB21)
diff --git a/src/GCodes/GCodes.cpp b/src/GCodes/GCodes.cpp
index e4b734f8..f537eb5c 100644
--- a/src/GCodes/GCodes.cpp
+++ b/src/GCodes/GCodes.cpp
@@ -60,7 +60,7 @@ void GCodes::RestorePoint::Init()
GCodes::GCodes(Platform* p, Webserver* w) :
platform(p), webserver(w), active(false), isFlashing(false),
- fileBeingHashed(nullptr)
+ fileBeingHashed(nullptr), lastWarningMillis(0)
{
httpGCode = new GCodeBuffer("http", HTTP_MESSAGE);
telnetGCode = new GCodeBuffer("telnet", TELNET_MESSAGE);
@@ -164,7 +164,7 @@ void GCodes::Reset()
lastEndstopStates = platform->GetAllEndstopStates();
firmwareUpdateModuleMap = 0;
- cancelWait = isWaiting = false;
+ cancelWait = isWaiting = displayNoToolWarning = displayDeltaNotHomedWarning = false;
for (size_t i = 0; i < NumResources; ++i)
{
@@ -659,6 +659,23 @@ void GCodes::Spin()
nextGcodeSource = 0;
}
+ // Check if we need to display a warning
+ const uint32_t now = millis();
+ if (now - lastWarningMillis >= MinimumWarningInterval)
+ {
+ if (displayNoToolWarning)
+ {
+ platform->Message(GENERIC_MESSAGE, "Attempting to extrude with no tool selected.\n");
+ displayNoToolWarning = false;
+ lastWarningMillis = now;
+ }
+ if (displayDeltaNotHomedWarning)
+ {
+ platform->Message(GENERIC_MESSAGE, "Attempt to move the head of a delta printer before homing the towers\n");
+ displayDeltaNotHomedWarning = false;
+ lastWarningMillis = now;
+ }
+ }
platform->ClassReport(longWait);
}
@@ -1036,7 +1053,7 @@ bool GCodes::LoadExtrusionAndFeedrateFromGCode(GCodeBuffer& gb, int moveType)
Tool* const tool = reprap.GetCurrentTool();
if (tool == nullptr)
{
- platform->Message(GENERIC_MESSAGE, "Attempting to extrude with no tool selected.\n");
+ displayNoToolWarning = true;
return false;
}
const size_t eMoveCount = tool->DriveCount();
@@ -1306,7 +1323,7 @@ int GCodes::SetUpMove(GCodeBuffer& gb, StringRef& reply)
// This may be damaging and is almost certainly a user mistake, so ignore the move. But allow extruder-only moves.
if (gb.Seen(axisLetters[X_AXIS]) || gb.Seen(axisLetters[Y_AXIS]) || gb.Seen(axisLetters[Z_AXIS]))
{
- reply.copy("Attempt to move the head of a delta printer before homing the towers");
+ displayDeltaNotHomedWarning = true;
return 1;
}
}
@@ -2181,7 +2198,7 @@ bool GCodes::DefineGrid(GCodeBuffer& gb, StringRef &reply)
}
else
{
- reply.copy("ERROR: Wrong number of X values in M577, need 2");
+ reply.copy("Wrong number of X values in M577, need 2");
return true;
}
}
@@ -2195,7 +2212,7 @@ bool GCodes::DefineGrid(GCodeBuffer& gb, StringRef &reply)
}
else
{
- reply.copy("ERROR: Wrong number of Y values in M577, need 2");
+ reply.copy("Wrong number of Y values in M577, need 2");
return true;
}
}
@@ -2223,14 +2240,14 @@ bool GCodes::DefineGrid(GCodeBuffer& gb, StringRef &reply)
if (seenX != seenY)
{
- reply.copy("ERROR: specify both or neither of X and Y in M577");
+ reply.copy("specify both or neither of X and Y in M577");
return true;
}
if (!seenX && !seenR)
{
// Must have given just the S parameter
- reply.copy("ERROR: specify at least radius or X,Y ranges in M577");
+ reply.copy("specify at least radius or X,Y ranges in M577");
return true;
}
@@ -2245,7 +2262,7 @@ bool GCodes::DefineGrid(GCodeBuffer& gb, StringRef &reply)
}
else
{
- reply.copy("ERROR: M577 radius must be positive unless X and Y are specified");
+ reply.copy("M577 radius must be positive unless X and Y are specified");
return true;
}
}
@@ -2257,8 +2274,10 @@ bool GCodes::DefineGrid(GCodeBuffer& gb, StringRef &reply)
}
else
{
- reply.copy("ERROR: bad grid definition: ");
- newGrid.PrintError(reply);
+ const float xRange = (seenX) ? xValues[1] - xValues[0] : 2 * radius;
+ const float yRange = (seenX) ? yValues[1] - yValues[0] : 2 * radius;
+ reply.copy("bad grid definition: ");
+ newGrid.PrintError(xRange, yRange, reply);
return true;
}
}
diff --git a/src/GCodes/GCodes.h b/src/GCodes/GCodes.h
index 5b2e1077..ade82841 100644
--- a/src/GCodes/GCodes.h
+++ b/src/GCodes/GCodes.h
@@ -288,7 +288,6 @@ private:
size_t probeCount; // Counts multiple probe points
int8_t cannedCycleMoveCount; // Counts through internal (i.e. not macro) canned cycle moves
bool cannedCycleMoveQueued; // True if a canned cycle move has been set
- float longWait; // Timer for things that happen occasionally (seconds)
bool limitAxes; // Don't think outside the box.
uint32_t axesHomed; // Bitmap of which axes have been homed
float pausedFanValues[NUM_FANS]; // Fan speeds when the print was paused
@@ -331,8 +330,12 @@ private:
bool AdvanceHash(StringRef &reply);
// Misc
+ float longWait; // Timer for things that happen occasionally (seconds)
+ uint32_t lastWarningMillis; // When we last sent a warning message for things that can happen very often
bool isWaiting; // True if waiting to reach temperature
bool cancelWait; // Set true to cancel waiting
+ bool displayNoToolWarning; // True if we need to display a 'no tool selected' warning
+ bool displayDeltaNotHomedWarning; // True if we need to display a 'attempt to move before homing on a delta printer' message
};
//*****************************************************************************************************
diff --git a/src/GCodes/GCodes2.cpp b/src/GCodes/GCodes2.cpp
index 44faf305..023ccbb1 100644
--- a/src/GCodes/GCodes2.cpp
+++ b/src/GCodes/GCodes2.cpp
@@ -1825,7 +1825,7 @@ bool GCodes::HandleMcode(GCodeBuffer& gb, StringRef& reply)
}
else
{
- reply.printf("Baby stepping offset is %.3d", GetBabyStepOffset());
+ reply.printf("Baby stepping offset is %.3fmm", GetBabyStepOffset());
}
break;
diff --git a/src/Movement/Grid.cpp b/src/Movement/Grid.cpp
index 2b86f5e4..87e844b4 100644
--- a/src/Movement/Grid.cpp
+++ b/src/Movement/Grid.cpp
@@ -26,12 +26,13 @@ GridDefinition::GridDefinition(const float xRange[2], const float yRange[2], flo
numX = (xMax - xMin >= MinRange && spacing >= MinSpacing) ? (uint32_t)((xMax - xMin) * recipSpacing) + 1 : 0;
numY = (yMax - yMin >= MinRange && spacing >= MinSpacing) ? (uint32_t)((yMax - yMin) * recipSpacing) + 1 : 0;
CheckValidity();
-
}
void GridDefinition::CheckValidity()
{
- isValid = NumPoints() != 0 && NumPoints() <= MaxGridProbePoints && (radius < 0.0 || radius >= 1.0);
+ isValid = NumPoints() != 0 && NumPoints() <= MaxGridProbePoints
+ && (radius < 0.0 || radius >= 1.0)
+ && NumXpoints() <= MaxXGridPoints;
}
float GridDefinition::GetXCoordinate(unsigned int xIndex) const
@@ -84,7 +85,7 @@ bool GridDefinition::ReadParameters(const StringRef& s)
}
// Print what is wrong with the grid, appending it to the existing string
-void GridDefinition::PrintError(StringRef& r) const
+void GridDefinition::PrintError(float originalXrange, float originalYrange, StringRef& r) const
{
if (spacing < MinSpacing)
{
@@ -98,9 +99,16 @@ void GridDefinition::PrintError(StringRef& r) const
{
r.cat("Y range too small");
}
- else if (numX > MaxGridProbePoints || numY > MaxGridProbePoints || NumPoints() > MaxGridProbePoints) // check X and Y individually in case X*Y overflows
+ else if ( numX > MaxXGridPoints
+ || numX > MaxGridProbePoints || numY > MaxGridProbePoints // check X and Y individually in case X*Y overflows
+ || NumPoints() > MaxGridProbePoints
+ )
{
- r.catf("Too many grid points (maximum %d, needed %d)", MaxGridProbePoints, NumPoints());
+ const float totalRange = originalXrange + originalYrange;
+ const float area = originalXrange * originalYrange;
+ const float minSpacing = (totalRange + sqrtf(fsquare(totalRange) + 4.0 * (MaxGridProbePoints - 1) * area))/(2.0 * (MaxGridProbePoints - 1));
+ const float minXspacing = originalXrange/(MaxXGridPoints - 1);
+ r.catf("Too many grid points; suggest increase spacing to %.1fmm", max<float>(minSpacing, minXspacing));
}
else
{
@@ -210,7 +218,7 @@ bool HeightMap::SaveToFile(FileStore *f) const
// Load the grid from file, returning true if an error occurred with the error reason appended to the buffer
bool HeightMap::LoadFromFile(FileStore *f, StringRef& r)
{
- const size_t MaxLineLength = 200; // maximum length of a line in the height map file
+ const size_t MaxLineLength = (MaxXGridPoints * 8) + 2; // maximum length of a line in the height map file, need 8 characters per grid point
const char* const readFailureText = "failed to read line from file";
char buffer[MaxLineLength + 1];
StringRef s(buffer, ARRAY_SIZE(buffer));
diff --git a/src/Movement/Grid.h b/src/Movement/Grid.h
index 84d8b589..f12fe354 100644
--- a/src/Movement/Grid.h
+++ b/src/Movement/Grid.h
@@ -34,7 +34,7 @@ public:
static bool CheckHeading(const StringRef& s);
bool ReadParameters(const StringRef& s);
- void PrintError(StringRef& r) const
+ void PrintError(float originalXrange, float originalYrange, StringRef& r) const
pre(!IsValid());
private:
diff --git a/src/Movement/Move.cpp b/src/Movement/Move.cpp
index f831c0c3..f95a9d62 100644
--- a/src/Movement/Move.cpp
+++ b/src/Movement/Move.cpp
@@ -184,10 +184,10 @@ void Move::Spin()
// We have a new move
if (simulationMode < 2) // in simulation mode 2 and higher, we don't process incoming moves beyond this point
{
- const bool doMotorMapping = (nextMove.moveType == 0);
+ const bool doMotorMapping = (nextMove.moveType == 0) || (nextMove.moveType == 1 && !IsDeltaMode());
if (doMotorMapping)
{
- Transform(nextMove.coords, nextMove.xAxes, true);
+ Transform(nextMove.coords, nextMove.xAxes, nextMove.moveType == 0);
}
if (ddaRingAddPointer->Init(nextMove, doMotorMapping))
{
diff --git a/src/Platform.cpp b/src/Platform.cpp
index 9bd9140a..4658f777 100644
--- a/src/Platform.cpp
+++ b/src/Platform.cpp
@@ -207,6 +207,9 @@ bool ZProbeParameters::WriteParameters(FileStore *f, unsigned int probeType) con
Platform::Platform() :
board(DEFAULT_BOARD_TYPE), active(false), errorCodeBits(0),
auxGCodeReply(nullptr), fileStructureInitialised(false), tickState(0), debugCode(0)
+#ifdef DUET_NG
+ , lastWarningMillis(0)
+#endif
{
// Output
auxOutput = new OutputStack();
@@ -403,6 +406,21 @@ void Platform::Init()
// Initialise TMC2660 driver module
driversPowered = false;
TMC2660::Init(ENABLE_PINS, numTMC2660Drivers);
+
+ // Set up the VSSA sense pin. Older Duet WiFis don't have it connected, so we enable the pulldown resistor to keep it inactive.
+ {
+ pinMode(VssaSensePin, INPUT_PULLUP);
+ delayMicroseconds(10);
+ const bool vssaHighVal = digitalRead(VssaSensePin);
+ pinMode(VssaSensePin, INPUT_PULLDOWN);
+ delayMicroseconds(10);
+ const bool vssaLowVal = digitalRead(VssaSensePin);
+ vssaSenseWorking = vssaLowVal || !vssaHighVal;
+ if (vssaSenseWorking)
+ {
+ pinMode(VssaSensePin, INPUT);
+ }
+ }
#endif
// Allow extrusion ancilliary PWM to use FAN0 even if FAN0 has not been disabled, for backwards compatibility
@@ -786,12 +804,28 @@ bool Platform::MustHomeXYBeforeZ() const
// Check the prerequisites for updating the main firmware. Return True if satisfied, else print as message and return false.
bool Platform::CheckFirmwareUpdatePrerequisites()
{
- if (!GetMassStorage()->FileExists(GetSysDir(), IAP_FIRMWARE_FILE))
+ FileStore * const firmwareFile = GetFileStore(GetSysDir(), IAP_FIRMWARE_FILE, false);
+ if (firmwareFile == nullptr)
{
MessageF(GENERIC_MESSAGE, "Error: Firmware binary \"%s\" not found\n", IAP_FIRMWARE_FILE);
return false;
}
+ uint32_t firstDword;
+ bool ok = firmwareFile->Read(reinterpret_cast<char*>(&firstDword), sizeof(firstDword)) == (int)sizeof(firstDword);
+ firmwareFile->Close();
+ if (!ok || firstDword !=
+#if (SAM4S || SAM4E)
+ IRAM_ADDR + IRAM_SIZE
+#else
+ IRAM1_ADDR + IRAM1_SIZE
+#endif
+ )
+ {
+ MessageF(GENERIC_MESSAGE, "Error: Firmware binary \"%s\" is not valid for this electronics\n", IAP_FIRMWARE_FILE);
+ return false;
+ }
+
if (!GetMassStorage()->FileExists(GetSysDir(), IAP_UPDATE_FILE))
{
MessageF(GENERIC_MESSAGE, "Error: In-application programming binary \"%s\" not found\n", IAP_UPDATE_FILE);
@@ -804,7 +838,7 @@ bool Platform::CheckFirmwareUpdatePrerequisites()
// Update the firmware. Prerequisites should be checked before calling this.
void Platform::UpdateFirmware()
{
- FileStore *iapFile = GetFileStore(GetSysDir(), IAP_UPDATE_FILE, false);
+ FileStore * const iapFile = GetFileStore(GetSysDir(), IAP_UPDATE_FILE, false);
if (iapFile == nullptr)
{
MessageF(FIRMWARE_UPDATE_MESSAGE, "IAP not found\n");
@@ -1225,6 +1259,14 @@ void Platform::Spin()
driversPowered = true;
}
TMC2660::SetDriversPowered(driversPowered);
+
+ // Check for a VSSA fault
+ const uint32_t now = millis();
+ if (vssaSenseWorking && now - lastWarningMillis > MinimumWarningInterval && digitalRead(VssaSensePin))
+ {
+ Message(GENERIC_MESSAGE, "Error: VSSA fault\n");
+ lastWarningMillis = now;
+ }
#endif
// Update the time
diff --git a/src/Platform.h b/src/Platform.h
index cb0be103..a54c3b71 100644
--- a/src/Platform.h
+++ b/src/Platform.h
@@ -832,7 +832,9 @@ private:
volatile uint16_t currentVin, highestVin, lowestVin;
uint32_t numUnderVoltageEvents;
volatile uint32_t numOverVoltageEvents;
+ uint32_t lastWarningMillis; // When we last sent a warning message for things that can happen very often
bool driversPowered;
+ bool vssaSenseWorking;
#endif
// RTC
diff --git a/src/Reprap.cpp b/src/Reprap.cpp
index 3eee7bc6..004b620c 100644
--- a/src/Reprap.cpp
+++ b/src/Reprap.cpp
@@ -27,7 +27,7 @@ extern "C" void hsmciIdle()
// Do nothing more in the constructor; put what you want in RepRap:Init()
-RepRap::RepRap() : toolList(nullptr), currentTool(nullptr), lastToolWarningTime(0.0), activeExtruders(0),
+RepRap::RepRap() : toolList(nullptr), currentTool(nullptr), lastWarningMillis(0), activeExtruders(0),
activeToolHeaters(0), ticksInSpinState(0), spinningModule(noModule), debug(0), stopped(false),
active(false), resetting(false), processingConfig(true), beepFrequency(0), beepDuration(0)
{
@@ -180,24 +180,27 @@ void RepRap::Spin()
ticksInSpinState = 0;
// Check if we need to display a cold extrusion warning
-
- for (Tool *t = toolList; t != nullptr; t = t->Next())
+ const uint32_t now = millis();
+ if (now - lastWarningMillis >= MinimumWarningInterval)
{
- if (t->DisplayColdExtrudeWarning() && ToolWarningsAllowed())
+ for (Tool *t = toolList; t != nullptr; t = t->Next())
{
- platform->MessageF(GENERIC_MESSAGE, "Warning: Tool %d was not driven because its heater temperatures were not high enough or it has a heater fault\n", t->myNumber);
+ if (t->DisplayColdExtrudeWarning())
+ {
+ platform->MessageF(GENERIC_MESSAGE, "Warning: Tool %d was not driven because its heater temperatures were not high enough or it has a heater fault\n", t->myNumber);
+ lastWarningMillis = now;
+ }
}
}
// Keep track of the loop time
-
const float t = platform->Time();
const float dt = t - lastTime;
- if(dt < fastLoop)
+ if (dt < fastLoop)
{
fastLoop = dt;
}
- if(dt > slowLoop)
+ if (dt > slowLoop)
{
slowLoop = dt;
}
@@ -448,19 +451,6 @@ void RepRap::SetToolVariables(int toolNumber, const float* standbyTemperatures,
}
}
-// chrishamm 02-10-2015: I don't think it's a good idea to write tool warning message after every
-// short move, so only print them in a reasonable interval.
-bool RepRap::ToolWarningsAllowed()
-{
- const float now = platform->Time();
- if (now - lastToolWarningTime > MINIMUM_TOOL_WARNING_INTERVAL)
- {
- lastToolWarningTime = platform->Time();
- return true;
- }
- return false;
-}
-
bool RepRap::IsHeaterAssignedToTool(int8_t heater) const
{
for(Tool *tool = toolList; tool != nullptr; tool = tool->Next())
diff --git a/src/Reprap.h b/src/Reprap.h
index 194d869c..a79f4089 100644
--- a/src/Reprap.h
+++ b/src/Reprap.h
@@ -64,7 +64,6 @@ public:
Tool* GetCurrentOrDefaultTool() const;
uint32_t GetCurrentXAxes() const; // Get the current axes used as X axes
void SetToolVariables(int toolNumber, const float* standbyTemperatures, const float* activeTemperatures);
- bool ToolWarningsAllowed();
bool IsHeaterAssignedToTool(int8_t heater) const;
unsigned int GetNumberOfContiguousTools() const;
@@ -119,7 +118,7 @@ private:
Tool* toolList;
Tool* currentTool;
- float lastToolWarningTime;
+ uint32_t lastWarningMillis; // When we last sent a warning message for things that can happen very often
uint16_t activeExtruders;
uint16_t activeToolHeaters;
diff --git a/src/Version.h b/src/Version.h
index 99ebb10a..ce482ede 100644
--- a/src/Version.h
+++ b/src/Version.h
@@ -9,11 +9,11 @@
#define SRC_VERSION_H_
#ifndef VERSION
-# define VERSION "1.18beta2"
+# define VERSION "1.18beta3"
#endif
#ifndef DATE
-# define DATE "2017-03-10"
+# define DATE "2017-03-16"
#endif
#define AUTHORS "reprappro, dc42, chrishamm, t3p3, dnewman"