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:
authorChristian Hammacher <bmasterc@gmail.com>2021-10-28 14:58:15 +0300
committerChristian Hammacher <bmasterc@gmail.com>2021-10-28 14:58:15 +0300
commit8207b22cc13e7893ae1cb43f4aef4a7632cac5b3 (patch)
treebd49861385980e72aeb6fe16fae0c3acc5895852
parent5e9d621403eb54b00a84d4824b75c056121730aa (diff)
SBC improvements for 3.4-b6
Refactored various parts of the SBC interface Renamed Linux to SBC in various places CAN updater checks if file is present on SBC before update SBC task is only woken up when SPI transfers finish Bug fix: Codes that were sent back to the SBC (e.g. from USB) caused temp reports to be printed Bug fix: SBC reconnects could take longer than expected
-rw-r--r--.cproject20
-rw-r--r--src/CAN/CanInterface.cpp4
-rw-r--r--src/CAN/CommandProcessor.cpp12
-rw-r--r--src/CAN/ExpansionManager.cpp12
-rw-r--r--src/Display/Menu.cpp4
-rw-r--r--src/Duet3Mini/Pins_Duet3Mini.h2
-rw-r--r--src/Duet3_V06/Pins_Duet3_V06.h2
-rw-r--r--src/DuetNG/Pins_DuetNG.h6
-rw-r--r--src/Endstops/EndstopsManager.cpp2
-rw-r--r--src/Endstops/EndstopsManager.h2
-rw-r--r--src/Endstops/ZProbe.cpp2
-rw-r--r--src/Endstops/ZProbe.h2
-rw-r--r--src/Fans/Fan.cpp2
-rw-r--r--src/Fans/Fan.h2
-rw-r--r--src/Fans/FansManager.cpp2
-rw-r--r--src/Fans/FansManager.h2
-rw-r--r--src/GCodes/GCodeBuffer/BinaryParser.cpp2
-rw-r--r--src/GCodes/GCodeBuffer/BinaryParser.h4
-rw-r--r--src/GCodes/GCodeBuffer/GCodeBuffer.cpp64
-rw-r--r--src/GCodes/GCodeBuffer/GCodeBuffer.h28
-rw-r--r--src/GCodes/GCodeBuffer/StringParser.cpp10
-rw-r--r--src/GCodes/GCodeMachineState.cpp18
-rw-r--r--src/GCodes/GCodeMachineState.h10
-rw-r--r--src/GCodes/GCodeQueue.cpp8
-rw-r--r--src/GCodes/GCodeQueue.h2
-rw-r--r--src/GCodes/GCodes.cpp138
-rw-r--r--src/GCodes/GCodes.h18
-rw-r--r--src/GCodes/GCodes2.cpp65
-rw-r--r--src/GCodes/GCodes3.cpp12
-rw-r--r--src/GCodes/GCodes4.cpp24
-rw-r--r--src/GCodes/ObjectTracker.cpp2
-rw-r--r--src/GCodes/ObjectTracker.h2
-rw-r--r--src/Heating/FOPDT.cpp4
-rw-r--r--src/Heating/FOPDT.h2
-rw-r--r--src/Heating/Heat.cpp4
-rw-r--r--src/Heating/Heat.h2
-rw-r--r--src/Linux/LinuxInterface.cpp1722
-rw-r--r--src/Movement/BedProbing/Grid.cpp2
-rw-r--r--src/Movement/BedProbing/Grid.h6
-rw-r--r--src/Movement/Kinematics/HangprinterKinematics.cpp2
-rw-r--r--src/Movement/Kinematics/HangprinterKinematics.h4
-rw-r--r--src/Movement/Kinematics/Kinematics.h4
-rw-r--r--src/Movement/Kinematics/LinearDeltaKinematics.cpp2
-rw-r--r--src/Movement/Kinematics/LinearDeltaKinematics.h4
-rw-r--r--src/Movement/Kinematics/RotaryDeltaKinematics.cpp2
-rw-r--r--src/Movement/Kinematics/RotaryDeltaKinematics.h4
-rw-r--r--src/Movement/Kinematics/ZLeadscrewKinematics.cpp2
-rw-r--r--src/Movement/Kinematics/ZLeadscrewKinematics.h2
-rw-r--r--src/Movement/Move.cpp8
-rw-r--r--src/Movement/Move.h4
-rw-r--r--src/ObjectModel/ObjectModel.cpp2
-rw-r--r--src/Pins.h6
-rw-r--r--src/Platform/MessageType.h2
-rw-r--r--src/Platform/OutputMemory.cpp2
-rw-r--r--src/Platform/OutputMemory.h4
-rw-r--r--src/Platform/Platform.cpp58
-rw-r--r--src/Platform/Platform.h14
-rw-r--r--src/Platform/RepRap.cpp74
-rw-r--r--src/Platform/RepRap.h16
-rw-r--r--src/Platform/TaskPriorities.h2
-rw-r--r--src/PrintMonitor/PrintMonitor.cpp8
-rw-r--r--src/RepRapFirmware.cpp2
-rw-r--r--src/RepRapFirmware.h8
-rw-r--r--src/SBC/DataTransfer.cpp (renamed from src/Linux/DataTransfer.cpp)204
-rw-r--r--src/SBC/DataTransfer.h (renamed from src/Linux/DataTransfer.h)54
-rw-r--r--src/SBC/SbcInterface.cpp1785
-rw-r--r--src/SBC/SbcInterface.h (renamed from src/Linux/LinuxInterface.h)38
-rw-r--r--src/SBC/SbcMessageFormats.h (renamed from src/Linux/LinuxMessageFormats.h)27
-rw-r--r--src/Storage/FileData.h2
-rw-r--r--src/Storage/FileStore.cpp84
-rw-r--r--src/Storage/FileStore.h20
-rw-r--r--src/Storage/FileWriteBuffer.h12
-rw-r--r--src/Storage/MassStorage.cpp38
-rw-r--r--src/Storage/MassStorage.h6
-rw-r--r--src/Tools/Filament.cpp4
-rw-r--r--src/Tools/Tool.cpp2
-rw-r--r--src/Tools/Tool.h2
-rw-r--r--src/bossa/Flasher.cpp4
78 files changed, 2396 insertions, 2349 deletions
diff --git a/.cproject b/.cproject
index c8f80f53..87aa3c0b 100644
--- a/.cproject
+++ b/.cproject
@@ -129,7 +129,7 @@
</toolChain>
</folderInfo>
<sourceEntries>
- <entry excluding="src/Duet3Mini|src/Linux|src/Hardware/SAME70|src/Hardware/SAME5x|src/Networking/LwipEthernet|src/Duet3_V06|src/Hardware/ksz8081rna|src/Pccb|src/DuetM|src/Hardware/SAM4S" flags="VALUE_WORKSPACE_PATH" kind="sourcePath" name=""/>
+ <entry excluding="src/SBC|src/Duet3_V06|src/Hardware/SAME70|src/Hardware/SAME5x|src/Hardware/ksz8081rna|src/Duet3Mini|src/Networking/LwipEthernet|src/Pccb|src/Hardware/SAM4S|src/DuetM" flags="VALUE_WORKSPACE_PATH" kind="sourcePath" name=""/>
</sourceEntries>
</configuration>
</storageModule>
@@ -287,7 +287,7 @@
</toolChain>
</folderInfo>
<sourceEntries>
- <entry excluding="src/Hardware/SAM4E|src/Duet3Mini|src/Linux|src/Hardware/SAME70|src/Hardware/SAME5x|src/Networking/LwipEthernet|src/DuetNG|src/Duet3_V06|src/Hardware/ksz8081rna|src/Networking/ESP8266WiFi|src/Pccb" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name=""/>
+ <entry excluding="src/SBC|src/Duet3_V06|src/Hardware/SAME70|src/Hardware/SAME5x|src/Hardware/ksz8081rna|src/Networking/ESP8266WiFi|src/Duet3Mini|src/Hardware/SAM4E|src/Networking/LwipEthernet|src/Pccb|src/DuetNG" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name=""/>
</sourceEntries>
</configuration>
</storageModule>
@@ -446,7 +446,7 @@
</toolChain>
</folderInfo>
<sourceEntries>
- <entry excluding="src/Hardware/SAM4E|src/Duet3Mini|src/Linux|src/Hardware/SAME70|src/Hardware/SAME5x|src/Networking/LwipEthernet|src/DuetNG|src/Networking/W5500Ethernet/|src/Duet3_V06|src/Display|src/Hardware/ksz8081rna|src/Networking/ESP8266WiFi|src/DuetM" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name=""/>
+ <entry excluding="src/SBC|src/Hardware/SAME70|src/Hardware/SAME5x|src/Networking/LwipEthernet|src/DuetNG|src/Networking/W5500Ethernet/|src/Duet3_V06|src/Display|src/Hardware/ksz8081rna|src/Networking/ESP8266WiFi|src/Duet3Mini|src/Hardware/SAM4E|src/DuetM" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name=""/>
</sourceEntries>
</configuration>
</storageModule>
@@ -608,7 +608,7 @@
</toolChain>
</folderInfo>
<sourceEntries>
- <entry excluding="src/Hardware/SAM4E|src/Duet3Mini|/src/Networking/LwipEthernet/Lwip/test|src/DuetNG|src/Networking/W5500Ethernet|src/Display|src/Pccb|/src/Networking/LwipEthernet/Lwip/src/apps/mqtt|src/Networking/LwipEthernet/Lwip/doc|src/Networking/LwipEthernet/Lwip/src/apps/smtp|src/Networking/LwipEthernet/Lwip/src/apps/snmp|src/Networking/LwipEthernet/Lwip/src/apps/httpd|src/Hardware/SAME5x|src/Networking/LwipEthernet/Lwip/src/apps/tftp|src/Networking/LwipEthernet/Lwip/src/netif/ppp|src/Networking/LwipEthernet/Lwip/src/apps/lwiperf|src/Networking/LwipEthernet/Lwip/src/apps/altcp_tls|src/Networking/LwipEthernet/Lwip/src/apps/sntp|src/Networking/LwipEthernet/Lwip/src/apps/http|src/Networking/ESP8266WiFi|src/DuetM|src/Hardware/SAM4S" flags="VALUE_WORKSPACE_PATH" kind="sourcePath" name=""/>
+ <entry excluding="src/Networking/LwipEthernet/Lwip/src/apps/smtp|src/Networking/LwipEthernet/Lwip/src/apps/snmp|src/Networking/LwipEthernet/Lwip/src/apps/httpd|src/Hardware/SAME5x|/src/Networking/LwipEthernet/Lwip/test|src/DuetNG|src/Networking/LwipEthernet/Lwip/src/apps/tftp|src/Networking/W5500Ethernet|src/Networking/LwipEthernet/Lwip/src/netif/ppp|src/Networking/LwipEthernet/Lwip/src/apps/lwiperf|src/Networking/LwipEthernet/Lwip/src/apps/altcp_tls|src/Networking/LwipEthernet/Lwip/src/apps/sntp|src/Display|src/Networking/LwipEthernet/Lwip/src/apps/http|src/Networking/ESP8266WiFi|src/Duet3Mini|src/Hardware/SAM4E|src/Pccb|/src/Networking/LwipEthernet/Lwip/src/apps/mqtt|src/Hardware/SAM4S|src/DuetM|src/Networking/LwipEthernet/Lwip/doc" flags="VALUE_WORKSPACE_PATH" kind="sourcePath" name=""/>
</sourceEntries>
</configuration>
</storageModule>
@@ -769,7 +769,7 @@
</toolChain>
</folderInfo>
<sourceEntries>
- <entry excluding="src/Hardware/SAM4E|src/Duet3Mini|/src/Networking/LwipEthernet/Lwip/test|src/DuetNG|src/Networking/W5500Ethernet|src/Display|src/Pccb|/src/Networking/LwipEthernet/Lwip/src/apps/mqtt|src/Networking/LwipEthernet/Lwip/doc|src/Networking/LwipEthernet/Lwip/src/apps/smtp|src/Networking/LwipEthernet/Lwip/src/apps/snmp|src/Networking/LwipEthernet/Lwip/src/apps/httpd|src/Hardware/SAME5x|src/Networking/LwipEthernet/Lwip/src/apps/tftp|src/Networking/LwipEthernet/Lwip/src/netif/ppp|src/Networking/LwipEthernet/Lwip/src/apps/lwiperf|src/Networking/LwipEthernet/Lwip/src/apps/altcp_tls|src/Networking/LwipEthernet/Lwip/src/apps/sntp|src/Networking/LwipEthernet/Lwip/src/apps/http|src/Networking/ESP8266WiFi|src/DuetM|src/Hardware/SAM4S" flags="VALUE_WORKSPACE_PATH" kind="sourcePath" name=""/>
+ <entry excluding="src/Networking/LwipEthernet/Lwip/src/apps/smtp|src/Networking/LwipEthernet/Lwip/src/apps/snmp|src/Networking/LwipEthernet/Lwip/src/apps/httpd|src/Hardware/SAME5x|/src/Networking/LwipEthernet/Lwip/test|src/DuetNG|src/Networking/LwipEthernet/Lwip/src/apps/tftp|src/Networking/W5500Ethernet|src/Networking/LwipEthernet/Lwip/src/netif/ppp|src/Networking/LwipEthernet/Lwip/src/apps/lwiperf|src/Networking/LwipEthernet/Lwip/src/apps/altcp_tls|src/Networking/LwipEthernet/Lwip/src/apps/sntp|src/Display|src/Networking/LwipEthernet/Lwip/src/apps/http|src/Networking/ESP8266WiFi|src/Duet3Mini|src/Hardware/SAM4E|src/Pccb|/src/Networking/LwipEthernet/Lwip/src/apps/mqtt|src/Hardware/SAM4S|src/DuetM|src/Networking/LwipEthernet/Lwip/doc" flags="VALUE_WORKSPACE_PATH" kind="sourcePath" name=""/>
</sourceEntries>
</configuration>
</storageModule>
@@ -931,7 +931,7 @@
</toolChain>
</folderInfo>
<sourceEntries>
- <entry excluding="src/Duet3Mini|src/Hardware/SAME70|src/Hardware/SAME5x|src/Networking/LwipEthernet|src/Networking/W5500Ethernet/|src/Duet3_V06|src/Hardware/ksz8081rna|src/Networking/ESP8266WiFi/|src/Pccb|src/DuetM|src/Hardware/SAM4S" flags="VALUE_WORKSPACE_PATH" kind="sourcePath" name=""/>
+ <entry excluding="src/Duet3_V06|src/Hardware/SAME70|src/Hardware/SAME5x|src/Hardware/ksz8081rna|src/Networking/ESP8266WiFi/|src/Duet3Mini|src/Networking/LwipEthernet|src/Pccb|src/Hardware/SAM4S|src/DuetM|src/Networking/W5500Ethernet/" flags="VALUE_WORKSPACE_PATH" kind="sourcePath" name=""/>
</sourceEntries>
</configuration>
</storageModule>
@@ -1083,7 +1083,7 @@
</toolChain>
</folderInfo>
<sourceEntries>
- <entry excluding="src/Hardware/SAM4E|src/Networking/LwipEthernet/Lwip/src/apps/snmp|src/Networking/LwipEthernet/Lwip/src/apps/smtp|src/Hardware/SAME70|src/DuetNG|src/Networking/LwipEthernet/Lwip/src/apps/tftp|src/Networking/W5500Ethernet|src/Networking/LwipEthernet/Lwip/src/netif/ppp|src/Networking/LwipEthernet/Lwip/src/apps/lwiperf|src/Networking/LwipEthernet/Lwip/src/apps/altcp_tls|src/Networking/LwipEthernet/Lwip/src/apps/sntp|src/Networking/LwipEthernet/Lwip/src/apps/http|src/Duet3_V06|src/Pccb|src/Networking/LwipEthernet/Lwip/src/apps/mqtt|src/DuetM|src/Networking/LwipEthernet/Lwip/doc|src/Hardware/SAM4S" flags="VALUE_WORKSPACE_PATH" kind="sourcePath" name=""/>
+ <entry excluding="src/Networking/LwipEthernet/Lwip/src/apps/snmp|src/Networking/LwipEthernet/Lwip/src/apps/smtp|src/Hardware/SAME70|src/DuetNG|src/Networking/LwipEthernet/Lwip/src/apps/tftp|src/Networking/W5500Ethernet|src/Networking/LwipEthernet/Lwip/src/netif/ppp|src/Networking/LwipEthernet/Lwip/src/apps/lwiperf|src/Networking/LwipEthernet/Lwip/src/apps/altcp_tls|src/Networking/LwipEthernet/Lwip/src/apps/sntp|src/Networking/LwipEthernet/Lwip/src/apps/http|src/Duet3_V06|src/Hardware/SAM4E|src/Pccb|src/Hardware/SAM4S|src/Networking/LwipEthernet/Lwip/src/apps/mqtt|src/DuetM|src/Networking/LwipEthernet/Lwip/doc" flags="VALUE_WORKSPACE_PATH" kind="sourcePath" name=""/>
</sourceEntries>
</configuration>
</storageModule>
@@ -1240,7 +1240,7 @@
</toolChain>
</folderInfo>
<sourceEntries>
- <entry excluding="src/Hardware/SAM4E|src/Networking/LwipEthernet/Lwip/src/apps/snmp|src/Networking/LwipEthernet/Lwip/src/apps/smtp|src/Hardware/SAME70|src/DuetNG|src/Networking/LwipEthernet/Lwip/src/apps/tftp|src/Networking/W5500Ethernet|src/Networking/LwipEthernet/Lwip/src/netif/ppp|src/Networking/LwipEthernet/Lwip/src/apps/lwiperf|src/Networking/LwipEthernet/Lwip/src/apps/altcp_tls|src/Networking/LwipEthernet/Lwip/src/apps/sntp|src/Networking/LwipEthernet/Lwip/src/apps/http|src/Duet3_V06|src/Pccb|src/Networking/LwipEthernet/Lwip/src/apps/mqtt|src/DuetM|src/Networking/LwipEthernet/Lwip/doc|src/Hardware/SAM4S" flags="VALUE_WORKSPACE_PATH" kind="sourcePath" name=""/>
+ <entry excluding="src/Networking/LwipEthernet/Lwip/src/apps/snmp|src/Networking/LwipEthernet/Lwip/src/apps/smtp|src/Hardware/SAME70|src/DuetNG|src/Networking/LwipEthernet/Lwip/src/apps/tftp|src/Networking/W5500Ethernet|src/Networking/LwipEthernet/Lwip/src/netif/ppp|src/Networking/LwipEthernet/Lwip/src/apps/lwiperf|src/Networking/LwipEthernet/Lwip/src/apps/altcp_tls|src/Networking/LwipEthernet/Lwip/src/apps/sntp|src/Networking/LwipEthernet/Lwip/src/apps/http|src/Duet3_V06|src/Hardware/SAM4E|src/Pccb|src/Hardware/SAM4S|src/Networking/LwipEthernet/Lwip/src/apps/mqtt|src/DuetM|src/Networking/LwipEthernet/Lwip/doc" flags="VALUE_WORKSPACE_PATH" kind="sourcePath" name=""/>
</sourceEntries>
</configuration>
</storageModule>
@@ -1397,7 +1397,7 @@
</toolChain>
</folderInfo>
<sourceEntries>
- <entry excluding="src/Hardware/SAM4E|src/Networking/LwipEthernet/Lwip/src/apps/snmp|src/Networking/LwipEthernet/Lwip/src/apps/smtp|src/Hardware/SAME70|src/DuetNG|src/Networking/LwipEthernet/Lwip/src/apps/tftp|src/Networking/W5500Ethernet|src/Networking/LwipEthernet/Lwip/src/netif/ppp|src/Networking/LwipEthernet/Lwip/src/apps/lwiperf|src/Networking/LwipEthernet/Lwip/src/apps/altcp_tls|src/Networking/LwipEthernet/Lwip/src/apps/sntp|src/Networking/LwipEthernet/Lwip/src/apps/http|src/Duet3_V06|src/Pccb|src/Networking/LwipEthernet/Lwip/src/apps/mqtt|src/DuetM|src/Networking/LwipEthernet/Lwip/doc|src/Hardware/SAM4S" flags="VALUE_WORKSPACE_PATH" kind="sourcePath" name=""/>
+ <entry excluding="src/Networking/LwipEthernet/Lwip/src/apps/snmp|src/Networking/LwipEthernet/Lwip/src/apps/smtp|src/Hardware/SAME70|src/DuetNG|src/Networking/LwipEthernet/Lwip/src/apps/tftp|src/Networking/W5500Ethernet|src/Networking/LwipEthernet/Lwip/src/netif/ppp|src/Networking/LwipEthernet/Lwip/src/apps/lwiperf|src/Networking/LwipEthernet/Lwip/src/apps/altcp_tls|src/Networking/LwipEthernet/Lwip/src/apps/sntp|src/Networking/LwipEthernet/Lwip/src/apps/http|src/Duet3_V06|src/Hardware/SAM4E|src/Pccb|src/Hardware/SAM4S|src/Networking/LwipEthernet/Lwip/src/apps/mqtt|src/DuetM|src/Networking/LwipEthernet/Lwip/doc" flags="VALUE_WORKSPACE_PATH" kind="sourcePath" name=""/>
</sourceEntries>
</configuration>
</storageModule>
@@ -1566,7 +1566,7 @@
</toolChain>
</folderInfo>
<sourceEntries>
- <entry excluding="src/Hardware/SAM4E|src/Duet3Mini|/src/Networking/LwipEthernet/Lwip/test|src/DuetNG|src/Networking/W5500Ethernet|src/Display|src/Pccb|/src/Networking/LwipEthernet/Lwip/src/apps/mqtt|src/Networking/LwipEthernet/Lwip/doc|src/Networking/LwipEthernet/Lwip/src/apps/smtp|src/Networking/LwipEthernet/Lwip/src/apps/snmp|src/Networking/LwipEthernet/Lwip/src/apps/httpd|src/Hardware/SAME5x|src/Networking/LwipEthernet/Lwip/src/apps/tftp|src/Networking/LwipEthernet/Lwip/src/netif/ppp|src/Networking/LwipEthernet/Lwip/src/apps/lwiperf|src/Networking/LwipEthernet/Lwip/src/apps/altcp_tls|src/Networking/LwipEthernet/Lwip/src/apps/sntp|src/Networking/LwipEthernet/Lwip/src/apps/http|src/Networking/ESP8266WiFi|src/DuetM|src/Hardware/SAM4S" flags="VALUE_WORKSPACE_PATH" kind="sourcePath" name=""/>
+ <entry excluding="src/Networking/LwipEthernet/Lwip/src/apps/smtp|src/Networking/LwipEthernet/Lwip/src/apps/snmp|src/Networking/LwipEthernet/Lwip/src/apps/httpd|src/Hardware/SAME5x|/src/Networking/LwipEthernet/Lwip/test|src/DuetNG|src/Networking/LwipEthernet/Lwip/src/apps/tftp|src/Networking/W5500Ethernet|src/Networking/LwipEthernet/Lwip/src/netif/ppp|src/Networking/LwipEthernet/Lwip/src/apps/lwiperf|src/Networking/LwipEthernet/Lwip/src/apps/altcp_tls|src/Networking/LwipEthernet/Lwip/src/apps/sntp|src/Display|src/Networking/LwipEthernet/Lwip/src/apps/http|src/Networking/ESP8266WiFi|src/Duet3Mini|src/Hardware/SAM4E|src/Pccb|/src/Networking/LwipEthernet/Lwip/src/apps/mqtt|src/Hardware/SAM4S|src/DuetM|src/Networking/LwipEthernet/Lwip/doc" flags="VALUE_WORKSPACE_PATH" kind="sourcePath" name=""/>
</sourceEntries>
</configuration>
</storageModule>
diff --git a/src/CAN/CanInterface.cpp b/src/CAN/CanInterface.cpp
index 1a0f51d6..75d7e763 100644
--- a/src/CAN/CanInterface.cpp
+++ b/src/CAN/CanInterface.cpp
@@ -26,8 +26,8 @@
#include <ClosedLoop/ClosedLoop.h>
-#if HAS_LINUX_INTERFACE
-# include "Linux/LinuxInterface.h"
+#if HAS_SBC_INTERFACE
+# include "SBC/SbcInterface.h"
#endif
#include <memory>
diff --git a/src/CAN/CommandProcessor.cpp b/src/CAN/CommandProcessor.cpp
index ccaa5771..e1d5ec23 100644
--- a/src/CAN/CommandProcessor.cpp
+++ b/src/CAN/CommandProcessor.cpp
@@ -37,8 +37,8 @@
# include <Accelerometers/Accelerometers.h>
#endif
-#if HAS_LINUX_INTERFACE
-# include "Linux/LinuxInterface.h"
+#if HAS_SBC_INTERFACE
+# include "SBC/SbcInterface.h"
constexpr size_t MaxFileChunkSize = 448; // Maximum size of file chunks for reading files from the SBC. Should be a multiple of sizeof(CanMessageFirmwareUpdateResponse::data) for best CAN performance
char sbcFirmwareChunk[MaxFileChunkSize];
@@ -62,12 +62,12 @@ pre(buf->id.MsgType() == CanMessageType::firmwareBlockRequest)
uint32_t fileOffset = msg.fileOffset, fileLength = 0;
uint32_t lreq = msg.lengthRequested;
-#if HAS_LINUX_INTERFACE
- if (reprap.UsingLinuxInterface())
+#if HAS_SBC_INTERFACE
+ if (reprap.UsingSbcInterface())
{
// Fetch the firmware file from the SBC
uint32_t bytesRead = min<uint32_t>(lreq, MaxFileChunkSize);
- if (reprap.GetLinuxInterface().GetFileChunk(fname.c_str(), fileOffset, sbcFirmwareChunk, bytesRead, fileLength))
+ if (reprap.GetSbcInterface().GetFileChunk(fname.c_str(), fileOffset, sbcFirmwareChunk, bytesRead, fileLength))
{
if (fileOffset >= fileLength)
{
@@ -114,7 +114,7 @@ pre(buf->id.MsgType() == CanMessageType::firmwareBlockRequest)
if (bytesSent == (size_t)bytesRead)
{
bytesRead = min<uint32_t>(lreq, MaxFileChunkSize);
- if (!reprap.GetLinuxInterface().GetFileChunk(fname.c_str(), fileOffset, sbcFirmwareChunk, bytesRead, fileLength))
+ if (!reprap.GetSbcInterface().GetFileChunk(fname.c_str(), fileOffset, sbcFirmwareChunk, bytesRead, fileLength))
{
msgp = buf->SetupResponseMessage<CanMessageFirmwareUpdateResponse>(0, CanInterface::GetCurrentMasterAddress(), src);
msgp->dataLength = 0;
diff --git a/src/CAN/ExpansionManager.cpp b/src/CAN/ExpansionManager.cpp
index aabcc533..5e4494bd 100644
--- a/src/CAN/ExpansionManager.cpp
+++ b/src/CAN/ExpansionManager.cpp
@@ -246,16 +246,8 @@ GCodeResult ExpansionManager::UpdateRemoteFirmware(uint32_t boardAddress, GCodeB
reply.Clear();
firmwareFilename.cat(".bin");
- // Do not ask Linux for a file here because that would create a deadlock.
- // If blocking calls to Linux are supposed to be made from the Spin loop, the Linux interface,
- // or at least the code doing SPI data transfers, has to be moved to a separate task first
-#if HAS_MASS_STORAGE
- // It's fine to check if the file exists on the local SD though
- if (
-# if HAS_LINUX_INTERFACE
- !reprap.UsingLinuxInterface() &&
-# endif
- !reprap.GetPlatform().FileExists(FIRMWARE_DIRECTORY, firmwareFilename.c_str()))
+#if HAS_MASS_STORAGE || HAS_SBC_INTERFACE
+ if (!reprap.GetPlatform().FileExists(FIRMWARE_DIRECTORY, firmwareFilename.c_str()))
{
reply.printf("Firmware file %s not found", firmwareFilename.c_str());
return GCodeResult::error;
diff --git a/src/Display/Menu.cpp b/src/Display/Menu.cpp
index 92ff340e..964565a6 100644
--- a/src/Display/Menu.cpp
+++ b/src/Display/Menu.cpp
@@ -657,8 +657,8 @@ void Menu::EncoderAction(int action) noexcept
void Menu::Refresh() noexcept
{
if (
-#if HAS_LINUX_INTERFACE
- !reprap.UsingLinuxInterface() &&
+#if HAS_SBC_INTERFACE
+ !reprap.UsingSbcInterface() &&
#endif
#if HAS_MASS_STORAGE
!MassStorage::IsDriveMounted(0)
diff --git a/src/Duet3Mini/Pins_Duet3Mini.h b/src/Duet3Mini/Pins_Duet3Mini.h
index 7517864a..03b26543 100644
--- a/src/Duet3Mini/Pins_Duet3Mini.h
+++ b/src/Duet3Mini/Pins_Duet3Mini.h
@@ -33,7 +33,7 @@ constexpr uint32_t IAP_IMAGE_START = 0x20038000;
#define HAS_LWIP_NETWORKING 1
#define HAS_WIFI_NETWORKING 1
#define HAS_W5500_NETWORKING 0
-#define HAS_LINUX_INTERFACE 1
+#define HAS_SBC_INTERFACE 1
#define HAS_MASS_STORAGE 1
#define HAS_HIGH_SPEED_SD 1
diff --git a/src/Duet3_V06/Pins_Duet3_V06.h b/src/Duet3_V06/Pins_Duet3_V06.h
index ffccdec0..f674df88 100644
--- a/src/Duet3_V06/Pins_Duet3_V06.h
+++ b/src/Duet3_V06/Pins_Duet3_V06.h
@@ -18,7 +18,7 @@ constexpr uint32_t IAP_IMAGE_START = 0x20458000; // last 32kb of RAM
// Features definition
#define HAS_LWIP_NETWORKING 1
#define HAS_WIFI_NETWORKING 0
-#define HAS_LINUX_INTERFACE 1
+#define HAS_SBC_INTERFACE 1
#define HAS_MASS_STORAGE 1
#define HAS_HIGH_SPEED_SD 1
diff --git a/src/DuetNG/Pins_DuetNG.h b/src/DuetNG/Pins_DuetNG.h
index 579def4a..62b5e25f 100644
--- a/src/DuetNG/Pins_DuetNG.h
+++ b/src/DuetNG/Pins_DuetNG.h
@@ -42,12 +42,12 @@ constexpr uint32_t IAP_IMAGE_START = 0x20018000; // IAP is loaded into the last
#if defined(USE_SBC)
# define HAS_WIFI_NETWORKING 0
# define HAS_W5500_NETWORKING 0
-# define HAS_LINUX_INTERFACE 1
+# define HAS_SBC_INTERFACE 1
# define HAS_MASS_STORAGE 0
#else
# define HAS_WIFI_NETWORKING 1
# define HAS_W5500_NETWORKING 1
-# define HAS_LINUX_INTERFACE 0
+# define HAS_SBC_INTERFACE 0
#endif
#define HAS_CPU_TEMP_SENSOR 1
@@ -561,7 +561,7 @@ constexpr Pin SbcTfrReadyPin = PortDPin(31);
#define STEP_TC_ID ID_TC2
// DMA channel allocation
-#if HAS_LINUX_INTERFACE
+#if HAS_SBC_INTERFACE
constexpr DmaChannel DmacChanSbcTx = 1;
constexpr DmaChannel DmacChanSbcRx = 2;
#endif
diff --git a/src/Endstops/EndstopsManager.cpp b/src/Endstops/EndstopsManager.cpp
index 30000887..467a9fc2 100644
--- a/src/Endstops/EndstopsManager.cpp
+++ b/src/Endstops/EndstopsManager.cpp
@@ -565,7 +565,7 @@ GCodeResult EndstopsManager::ProgramZProbe(GCodeBuffer& gb, const StringRef& rep
return GCodeResult::error;
}
-#if HAS_MASS_STORAGE || HAS_LINUX_INTERFACE
+#if HAS_MASS_STORAGE || HAS_SBC_INTERFACE
bool EndstopsManager::WriteZProbeParameters(FileStore *f, bool includingG31) const noexcept
{
diff --git a/src/Endstops/EndstopsManager.h b/src/Endstops/EndstopsManager.h
index 398c93ee..7221b014 100644
--- a/src/Endstops/EndstopsManager.h
+++ b/src/Endstops/EndstopsManager.h
@@ -68,7 +68,7 @@ public:
void OnEndstopOrZProbeStatesChanged() noexcept;
#endif
-#if HAS_MASS_STORAGE || HAS_LINUX_INTERFACE
+#if HAS_MASS_STORAGE || HAS_SBC_INTERFACE
bool WriteZProbeParameters(FileStore *f, bool includingG31) const noexcept;
#endif
diff --git a/src/Endstops/ZProbe.cpp b/src/Endstops/ZProbe.cpp
index 921d8fc6..4429b2d5 100644
--- a/src/Endstops/ZProbe.cpp
+++ b/src/Endstops/ZProbe.cpp
@@ -134,7 +134,7 @@ float ZProbe::GetActualTriggerHeight() const noexcept
return -offsets[Z_AXIS];
}
-#if HAS_MASS_STORAGE || HAS_LINUX_INTERFACE
+#if HAS_MASS_STORAGE || HAS_SBC_INTERFACE
bool ZProbe::WriteParameters(FileStore *f, unsigned int probeNumber) const noexcept
{
diff --git a/src/Endstops/ZProbe.h b/src/Endstops/ZProbe.h
index 8be3b351..f43ea340 100644
--- a/src/Endstops/ZProbe.h
+++ b/src/Endstops/ZProbe.h
@@ -60,7 +60,7 @@ public:
void SetDeployedByUser(bool b) noexcept { isDeployedByUser = b; }
void SetLastStoppedHeight(float h) noexcept;
-#if HAS_MASS_STORAGE || HAS_LINUX_INTERFACE
+#if HAS_MASS_STORAGE || HAS_SBC_INTERFACE
bool WriteParameters(FileStore *f, unsigned int probeNumber) const noexcept;
#endif
diff --git a/src/Fans/Fan.cpp b/src/Fans/Fan.cpp
index 3b3dccbe..17d53cef 100644
--- a/src/Fans/Fan.cpp
+++ b/src/Fans/Fan.cpp
@@ -215,7 +215,7 @@ GCodeResult Fan::Configure(const CanMessageFanParameters& msg, const StringRef&
#endif
-#if HAS_MASS_STORAGE || HAS_LINUX_INTERFACE
+#if HAS_MASS_STORAGE || HAS_SBC_INTERFACE
// Save the settings of this fan if it isn't thermostatic
bool Fan::WriteSettings(FileStore *f, size_t fanNum) const noexcept
diff --git a/src/Fans/Fan.h b/src/Fans/Fan.h
index d0acc23b..b1af0d11 100644
--- a/src/Fans/Fan.h
+++ b/src/Fans/Fan.h
@@ -58,7 +58,7 @@ public:
unsigned int GetNumber() const { return fanNumber; }
const char *GetName() const noexcept { return name.c_str(); }
-#if HAS_MASS_STORAGE || HAS_LINUX_INTERFACE
+#if HAS_MASS_STORAGE || HAS_SBC_INTERFACE
bool WriteSettings(FileStore *f, size_t fanNum) const noexcept; // save the settings of this fan if it isn't thermostatic
#endif
diff --git a/src/Fans/FansManager.cpp b/src/Fans/FansManager.cpp
index d463c867..4efd7345 100644
--- a/src/Fans/FansManager.cpp
+++ b/src/Fans/FansManager.cpp
@@ -80,7 +80,7 @@ size_t FansManager::GetNumFansToReport() const noexcept
return numFans;
}
-#if HAS_MASS_STORAGE || HAS_LINUX_INTERFACE
+#if HAS_MASS_STORAGE || HAS_SBC_INTERFACE
bool FansManager::WriteFanSettings(FileStore *f) const noexcept
{
diff --git a/src/Fans/FansManager.h b/src/Fans/FansManager.h
index fad7bc88..382b722c 100644
--- a/src/Fans/FansManager.h
+++ b/src/Fans/FansManager.h
@@ -47,7 +47,7 @@ public:
GCodeResult SetFanSpeed(const CanMessageSetFanSpeed& msg, const StringRef& reply) noexcept;
unsigned int PopulateFansReport(CanMessageFansReport& msg) noexcept;
#endif
-#if HAS_MASS_STORAGE || HAS_LINUX_INTERFACE
+#if HAS_MASS_STORAGE || HAS_SBC_INTERFACE
bool WriteFanSettings(FileStore *f) const noexcept;
#endif
diff --git a/src/GCodes/GCodeBuffer/BinaryParser.cpp b/src/GCodes/GCodeBuffer/BinaryParser.cpp
index 8d98102d..954c4e29 100644
--- a/src/GCodes/GCodeBuffer/BinaryParser.cpp
+++ b/src/GCodes/GCodeBuffer/BinaryParser.cpp
@@ -7,7 +7,7 @@
#include "BinaryParser.h"
-#if HAS_LINUX_INTERFACE
+#if HAS_SBC_INTERFACE
#include "GCodeBuffer.h"
#include "ExpressionParser.h"
diff --git a/src/GCodes/GCodeBuffer/BinaryParser.h b/src/GCodes/GCodeBuffer/BinaryParser.h
index adb2286b..3c1dcbda 100644
--- a/src/GCodes/GCodeBuffer/BinaryParser.h
+++ b/src/GCodes/GCodeBuffer/BinaryParser.h
@@ -10,9 +10,9 @@
#include <RepRapFirmware.h>
-#if HAS_LINUX_INTERFACE
+#if HAS_SBC_INTERFACE
-#include <Linux/LinuxMessageFormats.h>
+#include <SBC/SbcMessageFormats.h>
#include <GCodes/GCodeException.h>
#include <GCodes/GCodeMachineState.h>
diff --git a/src/GCodes/GCodeBuffer/GCodeBuffer.cpp b/src/GCodes/GCodeBuffer/GCodeBuffer.cpp
index 404dc653..5f212eac 100644
--- a/src/GCodes/GCodeBuffer/GCodeBuffer.cpp
+++ b/src/GCodes/GCodeBuffer/GCodeBuffer.cpp
@@ -11,8 +11,8 @@
#if HAS_MASS_STORAGE || HAS_EMBEDDED_FILES
# include <GCodes/GCodeInput.h>
#endif
-#if HAS_LINUX_INTERFACE
-# include <Linux/LinuxInterface.h>
+#if HAS_SBC_INTERFACE
+# include <SBC/SbcInterface.h>
#endif
#include "BinaryParser.h"
#include "StringParser.h"
@@ -22,7 +22,7 @@
#include <Movement/StepTimer.h>
// Macros to reduce the amount of explicit conditional compilation in this file
-#if HAS_LINUX_INTERFACE
+#if HAS_SBC_INTERFACE
# define PARSER_OPERATION(_x) ((isBinaryBuffer) ? (binaryParser._x) : (stringParser._x))
# define IS_BINARY_OR(_x) ((isBinaryBuffer) || (_x))
@@ -93,16 +93,16 @@ GCodeBuffer::GCodeBuffer(GCodeChannel::RawType channel, GCodeInput *normalIn, Fi
fileInput(fileIn),
#endif
responseMessageType(mt), lastResult(GCodeResult::ok),
-#if HAS_LINUX_INTERFACE
+#if HAS_SBC_INTERFACE
binaryParser(*this),
#endif
stringParser(*this),
machineState(new GCodeMachineState()), whenReportDueTimerStarted(millis()),
-#if HAS_LINUX_INTERFACE
+#if HAS_SBC_INTERFACE
isBinaryBuffer(false),
#endif
timerRunning(false), motionCommanded(false)
-#if HAS_LINUX_INTERFACE
+#if HAS_SBC_INTERFACE
, isWaitingForMacro(false), invalidated(false)
#endif
{
@@ -114,7 +114,7 @@ GCodeBuffer::GCodeBuffer(GCodeChannel::RawType channel, GCodeInput *normalIn, Fi
// Reset it to its state after start-up
void GCodeBuffer::Reset() noexcept
{
-#if HAS_LINUX_INTERFACE
+#if HAS_SBC_INTERFACE
if (isWaitingForMacro)
{
ResolveMacroRequest(true, false);
@@ -123,7 +123,7 @@ void GCodeBuffer::Reset() noexcept
while (PopState()) { }
-#if HAS_LINUX_INTERFACE
+#if HAS_SBC_INTERFACE
isBinaryBuffer = false;
requestedMacroFile.Clear();
isWaitingForMacro = macroFileClosed = false;
@@ -136,7 +136,7 @@ void GCodeBuffer::Reset() noexcept
// Set it up to parse another G-code
void GCodeBuffer::Init() noexcept
{
-#if HAS_LINUX_INTERFACE
+#if HAS_SBC_INTERFACE
sendToSbc = false;
binaryParser.Init();
#endif
@@ -190,7 +190,7 @@ void GCodeBuffer::Diagnostics(MessageType mtype) noexcept
{
String<StringLength256> scratchString;
scratchString.copy(codeChannel.ToString());
-#if HAS_LINUX_INTERFACE
+#if HAS_SBC_INTERFACE
scratchString.cat(IsBinary() ? "* " : " ");
#else
scratchString.cat(" ");
@@ -235,7 +235,7 @@ void GCodeBuffer::Diagnostics(MessageType mtype) noexcept
// Add a character to the end
bool GCodeBuffer::Put(char c) noexcept
{
-#if HAS_LINUX_INTERFACE
+#if HAS_SBC_INTERFACE
machineState->lastCodeFromSbc = false;
isBinaryBuffer = false;
#endif
@@ -254,7 +254,7 @@ bool GCodeBuffer::CheckMetaCommand(const StringRef& reply)
return NOT_BINARY_AND(stringParser.CheckMetaCommand(reply));
}
-#if HAS_LINUX_INTERFACE
+#if HAS_SBC_INTERFACE
// Add an entire binary G-Code, overwriting any existing content
// CAUTION! This may be called with the task scheduler suspended, so don't do anything that might block or take more than a few microseconds to execute
@@ -271,7 +271,7 @@ void GCodeBuffer::PutBinary(const uint32_t *data, size_t len) noexcept
// Add an entire G-Code, overwriting any existing content
void GCodeBuffer::PutAndDecode(const char *str, size_t len) noexcept
{
-#if HAS_LINUX_INTERFACE
+#if HAS_SBC_INTERFACE
machineState->lastCodeFromSbc = false;
isBinaryBuffer = false;
#endif
@@ -281,7 +281,7 @@ void GCodeBuffer::PutAndDecode(const char *str, size_t len) noexcept
// Add a null-terminated string, overwriting any existing content
void GCodeBuffer::PutAndDecode(const char *str) noexcept
{
-#if HAS_LINUX_INTERFACE
+#if HAS_SBC_INTERFACE
machineState->lastCodeFromSbc = false;
isBinaryBuffer = false;
#endif
@@ -290,7 +290,7 @@ void GCodeBuffer::PutAndDecode(const char *str) noexcept
void GCodeBuffer::StartNewFile() noexcept
{
-#if HAS_LINUX_INTERFACE
+#if HAS_SBC_INTERFACE
machineState->SetFileExecuting();
#endif
machineState->lineNumber = 0; // reset line numbering when M32 is run
@@ -740,7 +740,7 @@ void GCodeBuffer::SetFinished(bool f) noexcept
{
if (f)
{
-#if HAS_LINUX_INTERFACE
+#if HAS_SBC_INTERFACE
sendToSbc = false;
#endif
LatestMachineState().firstCommandAfterRestart = false;
@@ -861,8 +861,8 @@ void GCodeBuffer::AbortFile(bool abortAll, bool requestAbort) noexcept
if (machineState->DoingFile())
{
#if HAS_MASS_STORAGE || HAS_EMBEDDED_FILES
-# if HAS_LINUX_INTERFACE
- if (!reprap.UsingLinuxInterface())
+# if HAS_SBC_INTERFACE
+ if (!reprap.UsingSbcInterface())
# endif
{
fileInput->Reset(machineState->fileState);
@@ -872,7 +872,7 @@ void GCodeBuffer::AbortFile(bool abortAll, bool requestAbort) noexcept
}
} while (PopState() && (abortAll || !machineState->DoingFile()));
-#if HAS_LINUX_INTERFACE
+#if HAS_SBC_INTERFACE
abortFile = requestAbort;
abortAllFiles = requestAbort && abortAll;
}
@@ -883,7 +883,7 @@ void GCodeBuffer::AbortFile(bool abortAll, bool requestAbort) noexcept
}
}
-#if HAS_LINUX_INTERFACE
+#if HAS_SBC_INTERFACE
void GCodeBuffer::SetFileFinished() noexcept
{
@@ -912,7 +912,7 @@ void GCodeBuffer::SetFileFinished() noexcept
if (macroFileId != NoFileId)
{
- reprap.GetLinuxInterface().EventOccurred();
+ reprap.GetSbcInterface().EventOccurred();
}
}
@@ -929,14 +929,14 @@ void GCodeBuffer::SetPrintFinished() noexcept
ms->fileFinished = true;
}
}
- reprap.GetLinuxInterface().EventOccurred();
+ reprap.GetSbcInterface().EventOccurred();
}
}
-// This is only called when using the Linux interface and returns if the macro file could be opened
+// This is only called when using the SBC interface and returns if the macro file could be opened
bool GCodeBuffer::RequestMacroFile(const char *filename, bool fromCode) noexcept
{
- if (!reprap.GetLinuxInterface().IsConnected())
+ if (!reprap.GetSbcInterface().IsConnected())
{
// Don't wait for a macro file if no SBC is connected
return false;
@@ -953,7 +953,7 @@ bool GCodeBuffer::RequestMacroFile(const char *filename, bool fromCode) noexcept
{
// Wait for a response (but not forever)
isWaitingForMacro = true;
- reprap.GetLinuxInterface().EventOccurred(true);
+ reprap.GetSbcInterface().EventOccurred(true);
if (!macroSemaphore.Take(SpiMacroRequestTimeout))
{
isWaitingForMacro = false;
@@ -962,7 +962,7 @@ bool GCodeBuffer::RequestMacroFile(const char *filename, bool fromCode) noexcept
}
}
- // When we get here we expect the Linux interface to have set the variables above for us
+ // When we get here we expect the SBC interface to have set the variables above for us
if (!macroFileError)
{
macroJustStarted = true;
@@ -984,7 +984,7 @@ void GCodeBuffer::MacroFileClosed() noexcept
machineState->CloseFile();
macroJustStarted = false;
macroFileClosed = true;
- reprap.GetLinuxInterface().EventOccurred();
+ reprap.GetSbcInterface().EventOccurred();
}
#endif
@@ -1000,9 +1000,9 @@ void GCodeBuffer::MessageAcknowledged(bool cancelled) noexcept
ms->waitingForAcknowledgement = false;
ms->messageAcknowledged = true;
ms->messageCancelled = cancelled;
-#if HAS_LINUX_INTERFACE
+#if HAS_SBC_INTERFACE
messageAcknowledged = !cancelled;
- reprap.GetLinuxInterface().EventOccurred();
+ reprap.GetSbcInterface().EventOccurred();
#endif
}
}
@@ -1010,7 +1010,7 @@ void GCodeBuffer::MessageAcknowledged(bool cancelled) noexcept
MessageType GCodeBuffer::GetResponseMessageType() const noexcept
{
-#if HAS_LINUX_INTERFACE
+#if HAS_SBC_INTERFACE
if (machineState->lastCodeFromSbc)
{
return (MessageType)((1u << codeChannel.ToBaseType()) | BinaryCodeReplyFlag);
@@ -1027,8 +1027,8 @@ FilePosition GCodeBuffer::GetFilePosition() const noexcept
void GCodeBuffer::WaitForAcknowledgement() noexcept
{
machineState->WaitForAcknowledgement();
-#if HAS_LINUX_INTERFACE
- if (reprap.UsingLinuxInterface())
+#if HAS_SBC_INTERFACE
+ if (reprap.UsingSbcInterface())
{
messagePromptPending = true;
}
diff --git a/src/GCodes/GCodeBuffer/GCodeBuffer.h b/src/GCodes/GCodeBuffer/GCodeBuffer.h
index 878bd2e6..98a5d47e 100644
--- a/src/GCodes/GCodeBuffer/GCodeBuffer.h
+++ b/src/GCodes/GCodeBuffer/GCodeBuffer.h
@@ -14,7 +14,9 @@
#include <RepRapFirmware.h>
#include <GCodes/GCodeChannel.h>
#include <GCodes/GCodeMachineState.h>
-#include <Linux/LinuxMessageFormats.h>
+#if HAS_SBC_INTERFACE
+# include <SBC/SbcMessageFormats.h>
+#endif
#include <ObjectModel/ObjectModel.h>
class FileGCodeInput;
@@ -48,7 +50,7 @@ public:
void Diagnostics(MessageType mtype) noexcept; // Write some debug info
bool Put(char c) noexcept SPEED_CRITICAL; // Add a character to the end
-#if HAS_LINUX_INTERFACE
+#if HAS_SBC_INTERFACE
void PutBinary(const uint32_t *data, size_t len) noexcept; // Add an entire binary G-Code, overwriting any existing content
#endif
void PutAndDecode(const char *data, size_t len) noexcept; // Add an entire G-Code, overwriting any existing content
@@ -150,7 +152,7 @@ public:
void WaitForAcknowledgement() noexcept; // Flag that we are waiting for acknowledgement
-#if HAS_LINUX_INTERFACE
+#if HAS_SBC_INTERFACE
bool IsBinary() const noexcept { return isBinaryBuffer; } // Return true if the code is in binary format
bool IsFileFinished() const noexcept; // Return true if this source has finished execution of a file
@@ -269,7 +271,7 @@ private:
GCodeResult lastResult;
-#if HAS_LINUX_INTERFACE
+#if HAS_SBC_INTERFACE
BinaryParser binaryParser;
#endif
@@ -282,20 +284,20 @@ private:
uint32_t whenReportDueTimerStarted; // When the report-due-timer has been started
static constexpr uint32_t reportDueInterval = 1000; // Interval in which we send in ms
-#if HAS_LINUX_INTERFACE
+#if HAS_SBC_INTERFACE
bool isBinaryBuffer;
#endif
bool timerRunning; // True if we are waiting
bool motionCommanded; // true if this GCode stream has commanded motion since it last waited for motion to stop
-#if HAS_LINUX_INTERFACE
+#if HAS_SBC_INTERFACE
alignas(4) char buffer[MaxCodeBufferSize]; // must be aligned because we do dword fetches from it
#else
char buffer[GCODE_LENGTH];
#endif
-#if HAS_LINUX_INTERFACE
- // Accessed by both the Main and Linux tasks
+#if HAS_SBC_INTERFACE
+ // Accessed by both the Main and SBC tasks
BinarySemaphore macroSemaphore;
volatile bool isWaitingForMacro; // Is this GB waiting in DoFileMacro?
volatile bool macroFileClosed; // Last macro file has been closed in RRF, tell the SBC
@@ -312,21 +314,21 @@ private:
messagePromptPending : 1, // Has the SBC been notified about a message waiting for acknowledgement?
messageAcknowledged : 1; // Last message has been acknowledged
- // Accessed only by the Linux task
+ // Accessed only by the SBC task
bool invalidated; // Set to true if the GB content is not valid and about to be cleared
#endif
};
inline bool GCodeBuffer::IsDoingFileMacro() const noexcept
{
-#if HAS_LINUX_INTERFACE
+#if HAS_SBC_INTERFACE
return machineState->doingFileMacro || IsMacroRequestPending();
#else
return machineState->doingFileMacro;
#endif
}
-#if HAS_LINUX_INTERFACE
+#if HAS_SBC_INTERFACE
inline bool GCodeBuffer::IsFileFinished() const noexcept
{
@@ -369,7 +371,7 @@ inline bool GCodeBuffer::CanQueueCodes() const noexcept
inline bool GCodeBuffer::IsDoingFile() const noexcept
{
-#if HAS_LINUX_INTERFACE
+#if HAS_SBC_INTERFACE
return machineState->DoingFile() || IsMacroRequestPending();
#else
return machineState->DoingFile();
@@ -389,7 +391,7 @@ inline bool GCodeBuffer::IsExecuting() const noexcept
// Return true if this source is executing a file from the local SD card
inline bool GCodeBuffer::IsDoingLocalFile() const noexcept
{
-#if HAS_LINUX_INTERFACE
+#if HAS_SBC_INTERFACE
return !IsBinary() && IsDoingFile();
#else
return IsDoingFile();
diff --git a/src/GCodes/GCodeBuffer/StringParser.cpp b/src/GCodes/GCodeBuffer/StringParser.cpp
index 9205e453..24a6aaa3 100644
--- a/src/GCodes/GCodeBuffer/StringParser.cpp
+++ b/src/GCodes/GCodeBuffer/StringParser.cpp
@@ -785,13 +785,13 @@ void StringParser::ProcessEchoCommand(const StringRef& reply) THROWS(GCodeExcept
{
SkipWhiteSpace();
-#if HAS_MASS_STORAGE || HAS_LINUX_INTERFACE
+#if HAS_MASS_STORAGE || HAS_SBC_INTERFACE
FileData outputFile;
#endif
if (gb.buffer[readPointer] == '>')
{
-#if HAS_MASS_STORAGE || HAS_LINUX_INTERFACE
+#if HAS_MASS_STORAGE || HAS_SBC_INTERFACE
// Redirect the line to file
++readPointer;
OpenMode openMode;
@@ -843,7 +843,7 @@ void StringParser::ProcessEchoCommand(const StringRef& reply) THROWS(GCodeExcept
}
}
-#if HAS_MASS_STORAGE || HAS_LINUX_INTERFACE
+#if HAS_MASS_STORAGE || HAS_SBC_INTERFACE
if (outputFile.IsLive())
{
reply.cat('\n');
@@ -1062,8 +1062,8 @@ FilePosition StringParser::GetFilePosition() const noexcept
{
#if HAS_MASS_STORAGE
if (gb.LatestMachineState().DoingFile()
-# if HAS_LINUX_INTERFACE
- && !reprap.UsingLinuxInterface()
+# if HAS_SBC_INTERFACE
+ && !reprap.UsingSbcInterface()
# endif
)
{
diff --git a/src/GCodes/GCodeMachineState.cpp b/src/GCodes/GCodeMachineState.cpp
index 01d35c88..ad02bdd8 100644
--- a/src/GCodes/GCodeMachineState.cpp
+++ b/src/GCodes/GCodeMachineState.cpp
@@ -13,7 +13,7 @@
// Create a default initialised GCodeMachineState
GCodeMachineState::GCodeMachineState() noexcept
: feedRate(ConvertSpeedFromMmPerMin(DefaultFeedRate)),
-#if HAS_LINUX_INTERFACE
+#if HAS_SBC_INTERFACE
fileId(NoFileId),
#endif
lineNumber(0),
@@ -21,7 +21,7 @@ GCodeMachineState::GCodeMachineState() noexcept
doingFileMacro(false), waitWhileCooling(false), runningM501(false), runningM502(false),
volumetricExtrusion(false), g53Active(false), runningSystemMacro(false), usingInches(false),
waitingForAcknowledgement(false), messageAcknowledged(false), localPush(false), macroRestartable(false), firstCommandAfterRestart(false), commandRepeated(false),
-#if HAS_LINUX_INTERFACE
+#if HAS_SBC_INTERFACE
lastCodeFromSbc(false), macroStartedByCode(false), fileFinished(false),
#endif
compatibility(Compatibility::RepRapFirmware),
@@ -37,7 +37,7 @@ GCodeMachineState::GCodeMachineState(GCodeMachineState& prev, bool withinSameFil
#if HAS_MASS_STORAGE || HAS_EMBEDDED_FILES
fileState(prev.fileState),
#endif
-#if HAS_LINUX_INTERFACE
+#if HAS_SBC_INTERFACE
fileId(prev.fileId),
#endif
lockedResources(prev.lockedResources),
@@ -46,7 +46,7 @@ GCodeMachineState::GCodeMachineState(GCodeMachineState& prev, bool withinSameFil
doingFileMacro(prev.doingFileMacro), waitWhileCooling(prev.waitWhileCooling), runningM501(prev.runningM501), runningM502(prev.runningM502),
volumetricExtrusion(false), g53Active(false), runningSystemMacro(prev.runningSystemMacro), usingInches(prev.usingInches),
waitingForAcknowledgement(false), messageAcknowledged(false), localPush(withinSameFile), firstCommandAfterRestart(prev.firstCommandAfterRestart), commandRepeated(false),
-#if HAS_LINUX_INTERFACE
+#if HAS_SBC_INTERFACE
lastCodeFromSbc(prev.lastCodeFromSbc), macroStartedByCode(prev.macroStartedByCode), fileFinished(prev.fileFinished),
#endif
compatibility(prev.compatibility),
@@ -90,7 +90,7 @@ bool GCodeMachineState::CanRestartMacro() const noexcept
return true;
}
-#if HAS_LINUX_INTERFACE
+#if HAS_SBC_INTERFACE
// Set the state to indicate a file is being processed
void GCodeMachineState::SetFileExecuting() noexcept
@@ -114,8 +114,8 @@ void GCodeMachineState::SetFileExecuting() noexcept
// Return true if we are reading GCode commands from a file or macro
bool GCodeMachineState::DoingFile() const noexcept
{
-#if HAS_LINUX_INTERFACE
- if (reprap.UsingLinuxInterface() && fileId != NoFileId)
+#if HAS_SBC_INTERFACE
+ if (reprap.UsingSbcInterface() && fileId != NoFileId)
{
return true;
}
@@ -130,8 +130,8 @@ bool GCodeMachineState::DoingFile() const noexcept
// Close the currently executing file
void GCodeMachineState::CloseFile() noexcept
{
-#if HAS_LINUX_INTERFACE
- if (reprap.UsingLinuxInterface())
+#if HAS_SBC_INTERFACE
+ if (reprap.UsingSbcInterface())
{
if (fileId != NoFileId)
{
diff --git a/src/GCodes/GCodeMachineState.h b/src/GCodes/GCodeMachineState.h
index f45e77f3..a6bb3e2a 100644
--- a/src/GCodes/GCodeMachineState.h
+++ b/src/GCodes/GCodeMachineState.h
@@ -117,7 +117,7 @@ enum class GCodeState : uint8_t
timingSDread,
#endif
-#if HAS_LINUX_INTERFACE
+#if HAS_SBC_INTERFACE
waitingForAcknowledgement,
#endif
@@ -139,7 +139,7 @@ enum class BlockType : uint8_t
loop // block inside a 'while' command
};
-#if HAS_LINUX_INTERFACE
+#if HAS_SBC_INTERFACE
typedef uint8_t FileId;
constexpr FileId NoFileId = 0;
@@ -203,7 +203,7 @@ public:
#if HAS_MASS_STORAGE || HAS_EMBEDDED_FILES
FileData fileState;
#endif
-#if HAS_LINUX_INTERFACE
+#if HAS_SBC_INTERFACE
FileId fileId; // virtual ID to distinguish files in different stack levels (only unique per GB)
#endif
ResourceBitmap lockedResources;
@@ -229,7 +229,7 @@ public:
macroRestartable : 1, // true if the current macro has used M98 R1 to say that it can be interrupted and restarted
firstCommandAfterRestart : 1, // true if this is the first command after restarting a macro that was interrupted
commandRepeated : 1 // true if the current command is being repeated because it returned GCodeResult::notFinished the first time
-#if HAS_LINUX_INTERFACE
+#if HAS_SBC_INTERFACE
, lastCodeFromSbc : 1,
macroStartedByCode : 1,
fileFinished : 1
@@ -244,7 +244,7 @@ public:
void WaitForAcknowledgement() noexcept;
-#if HAS_LINUX_INTERFACE
+#if HAS_SBC_INTERFACE
void SetFileExecuting() noexcept;
#endif
diff --git a/src/GCodes/GCodeQueue.cpp b/src/GCodes/GCodeQueue.cpp
index 4fc4cb02..cf11c03b 100644
--- a/src/GCodes/GCodeQueue.cpp
+++ b/src/GCodes/GCodeQueue.cpp
@@ -234,10 +234,10 @@ void GCodeQueue::Diagnostics(MessageType mtype) noexcept
const QueuedCode *item = queuedItems;
do
{
-#if HAS_LINUX_INTERFACE
+#if HAS_SBC_INTERFACE
// The following may output binary gibberish if this code is stored in binary.
// We could restore this message by using GCodeBuffer::AppendFullCommand but there is probably no need to
- if (!reprap.UsingLinuxInterface())
+ if (!reprap.UsingSbcInterface())
#endif
{
reprap.GetPlatform().MessageF(mtype, "Queued '%.*s' for move %" PRIu32 "\n", item->dataLength, item->data, item->executeAtMove);
@@ -250,7 +250,7 @@ void GCodeQueue::Diagnostics(MessageType mtype) noexcept
void QueuedCode::AssignFrom(GCodeBuffer &gb) noexcept
{
-#if HAS_LINUX_INTERFACE
+#if HAS_SBC_INTERFACE
isBinary = gb.IsBinary();
#endif
memcpy(data, gb.DataStart(), gb.DataLength());
@@ -259,7 +259,7 @@ void QueuedCode::AssignFrom(GCodeBuffer &gb) noexcept
void QueuedCode::AssignTo(GCodeBuffer *gb) noexcept
{
-#if HAS_LINUX_INTERFACE
+#if HAS_SBC_INTERFACE
if (isBinary)
{
// Note that the data has to remain on a 4-byte boundary for this to work
diff --git a/src/GCodes/GCodeQueue.h b/src/GCodes/GCodeQueue.h
index f29090e0..16a7fda9 100644
--- a/src/GCodes/GCodeQueue.h
+++ b/src/GCodes/GCodeQueue.h
@@ -48,7 +48,7 @@ public:
private:
QueuedCode *next;
-#if HAS_LINUX_INTERFACE
+#if HAS_SBC_INTERFACE
bool isBinary;
alignas(4) char data[BufferSizePerQueueItem];
#else
diff --git a/src/GCodes/GCodes.cpp b/src/GCodes/GCodes.cpp
index b148f5f6..440e981f 100644
--- a/src/GCodes/GCodes.cpp
+++ b/src/GCodes/GCodes.cpp
@@ -42,8 +42,8 @@
# include <Fans/LedStripDriver.h>
#endif
-#if HAS_LINUX_INTERFACE
-# include <Linux/LinuxInterface.h>
+#if HAS_SBC_INTERFACE
+# include <SBC/SbcInterface.h>
#endif
#if SUPPORT_REMOTE_COMMANDS
@@ -81,19 +81,18 @@ GCodes::GCodes(Platform& p) noexcept :
#endif
fileGCode = new GCodeBuffer(GCodeChannel::File, nullptr, fileInput, GenericMessage);
-# if SUPPORT_HTTP || HAS_LINUX_INTERFACE
+# if SUPPORT_HTTP || HAS_SBC_INTERFACE
httpInput = new NetworkGCodeInput();
httpGCode = new GCodeBuffer(GCodeChannel::HTTP, httpInput, fileInput, HttpMessage);
# else
httpGCode = nullptr;
-# endif // SUPPORT_HTTP || HAS_LINUX_INTERFACE
-# if SUPPORT_TELNET || HAS_LINUX_INTERFACE
+# endif // SUPPORT_HTTP || HAS_SBC_INTERFACE
+# if SUPPORT_TELNET || HAS_SBC_INTERFACE
telnetInput = new NetworkGCodeInput();
telnetGCode = new GCodeBuffer(GCodeChannel::Telnet, telnetInput, fileInput, TelnetMessage, Compatibility::Marlin);
# else
telnetGCode = nullptr;
-# endif // SUPPORT_TELNET || HAS_LINUX_INTERFACE
-
+# endif // SUPPORT_TELNET || HAS_SBC_INTERFACE
#if defined(SERIAL_MAIN_DEVICE)
# if SAME5x
// SAME5x USB driver already uses an efficient buffer for receiving data from USB
@@ -103,7 +102,7 @@ GCodes::GCodes(Platform& p) noexcept :
BufferedStreamGCodeInput * const usbInput = new BufferedStreamGCodeInput(SERIAL_MAIN_DEVICE);
# endif
usbGCode = new GCodeBuffer(GCodeChannel::USB, usbInput, fileInput, UsbMessage, Compatibility::Marlin);
-#elif HAS_LINUX_INTERFACE
+#elif HAS_SBC_INTERFACE
usbGCode = new GCodeBuffer(GCodeChannel::USB, nullptr, fileInput, UsbMessage, Compatbility::marlin);
#else
usbGCode = nullptr;
@@ -112,7 +111,7 @@ GCodes::GCodes(Platform& p) noexcept :
#if HAS_AUX_DEVICES
StreamGCodeInput * const auxInput = new StreamGCodeInput(SERIAL_AUX_DEVICE);
auxGCode = new GCodeBuffer(GCodeChannel::Aux, auxInput, fileInput, AuxMessage);
-#elif HAS_LINUX_INTERFACE
+#elif HAS_SBC_INTERFACE
auxGCode = new GCodeBuffer(GCodeChannel::Aux, nullptr, fileInput, AuxMessage);
#else
auxGCode = nullptr;
@@ -123,13 +122,13 @@ GCodes::GCodes(Platform& p) noexcept :
codeQueue = new GCodeQueue();
queuedGCode = new GCodeBuffer(GCodeChannel::Queue, codeQueue, fileInput, GenericMessage);
-#if SUPPORT_12864_LCD || HAS_LINUX_INTERFACE
+#if SUPPORT_12864_LCD || HAS_SBC_INTERFACE
lcdGCode = new GCodeBuffer(GCodeChannel::LCD, nullptr, fileInput, LcdMessage);
#else
lcdGCode = nullptr;
#endif
-#if HAS_LINUX_INTERFACE
+#if HAS_SBC_INTERFACE
spiGCode = new GCodeBuffer(GCodeChannel::SBC, nullptr, fileInput, GenericMessage);
#else
spiGCode = nullptr;
@@ -138,7 +137,7 @@ GCodes::GCodes(Platform& p) noexcept :
#if defined(SERIAL_AUX2_DEVICE)
StreamGCodeInput * const aux2Input = new StreamGCodeInput(SERIAL_AUX2_DEVICE);
aux2GCode = new GCodeBuffer(GCodeChannel::Aux2, aux2Input, fileInput, Aux2Message);
-#elif HAS_LINUX_INTERFACE
+#elif HAS_SBC_INTERFACE
aux2GCode = new GCodeBuffer(GCodeChannel::Aux2, nullptr, fileInput, Aux2Message);
#else
aux2GCode = nullptr;
@@ -292,7 +291,7 @@ void GCodes::Reset() noexcept
#endif
doingToolChange = false;
doingManualBedProbe = false;
-#if HAS_MASS_STORAGE || HAS_LINUX_INTERFACE || HAS_EMBEDDED_FILES
+#if HAS_MASS_STORAGE || HAS_SBC_INTERFACE || HAS_EMBEDDED_FILES
fileOffsetToPrint = 0;
restartMoveFractionDone = 0.0;
#endif
@@ -346,8 +345,8 @@ bool GCodes::WaitingForAcknowledgement() const noexcept
// May return noFilePosition if allowNoFilePos is true
FilePosition GCodes::GetFilePosition(bool allowNoFilePos) const noexcept
{
-#if HAS_LINUX_INTERFACE
- if (!reprap.UsingLinuxInterface())
+#if HAS_SBC_INTERFACE
+ if (!reprap.UsingSbcInterface())
#endif
{
#if HAS_MASS_STORAGE || HAS_EMBEDDED_FILES
@@ -359,7 +358,7 @@ FilePosition GCodes::GetFilePosition(bool allowNoFilePos) const noexcept
#endif
}
-#if HAS_MASS_STORAGE || HAS_EMBEDDED_FILES || HAS_LINUX_INTERFACE
+#if HAS_MASS_STORAGE || HAS_EMBEDDED_FILES || HAS_SBC_INTERFACE
const FilePosition pos = (fileGCode->IsDoingFileMacro())
? printFilePositionAtMacroStart // the position before we started executing the macro
: fileGCode->GetFilePosition(); // the actual position, allowing for bytes cached but not yet processed
@@ -441,7 +440,7 @@ void GCodes::Spin() noexcept
// Get the GCodeBuffer that we want to process a command from. Use round-robin scheduling but give priority to auto-pause.
GCodeBuffer *gbp = autoPauseGCode;
if (!autoPauseGCode->IsCompletelyIdle()
-#if HAS_MASS_STORAGE || HAS_LINUX_INTERFACE || HAS_EMBEDDED_FILES
+#if HAS_MASS_STORAGE || HAS_SBC_INTERFACE || HAS_EMBEDDED_FILES
|| autoPauseGCode->LatestMachineState().DoingFile()
#endif
) // if autoPause is active
@@ -474,9 +473,9 @@ void GCodes::Spin() noexcept
}
-#if HAS_LINUX_INTERFACE
+#if HAS_SBC_INTERFACE
// Need to check if the print has been stopped by the SBC
- if (reprap.UsingLinuxInterface() && reprap.GetLinuxInterface().IsPrintAborted())
+ if (reprap.UsingSbcInterface() && reprap.GetSbcInterface().IsPrintAborted())
{
StopPrint(StopPrintReason::abort);
}
@@ -535,8 +534,11 @@ bool GCodes::SpinGCodeBuffer(GCodeBuffer& gb) noexcept
result = true; // assume we did something useful (not necessarily true, e.g. could be waiting for movement to stop)
}
- if ( gb.IsExecuting()
- || (isWaiting && !cancelWait) // this is needed to get reports sent during M109 commands
+ if ((gb.IsExecuting()
+#if HAS_SBC_INTERFACE
+ && !gb.IsSendRequested()
+#endif
+ ) || (isWaiting && !cancelWait) // this is needed to get reports sent during M109 commands
)
{
CheckReportDue(gb, reply.GetRef());
@@ -614,10 +616,10 @@ bool GCodes::StartNextGCode(GCodeBuffer& gb, const StringRef& reply) noexcept
return true;
}
}
-#if HAS_LINUX_INTERFACE
- else if (reprap.UsingLinuxInterface())
+#if HAS_SBC_INTERFACE
+ else if (reprap.UsingSbcInterface())
{
- return reprap.GetLinuxInterface().FillBuffer(gb);
+ return reprap.GetSbcInterface().FillBuffer(gb);
}
#endif
}
@@ -627,8 +629,8 @@ bool GCodes::StartNextGCode(GCodeBuffer& gb, const StringRef& reply) noexcept
// Try to continue with a print from file, returning true if we did anything significant
bool GCodes::DoFilePrint(GCodeBuffer& gb, const StringRef& reply) noexcept
{
-#if HAS_LINUX_INTERFACE
- if (reprap.UsingLinuxInterface())
+#if HAS_SBC_INTERFACE
+ if (reprap.UsingSbcInterface())
{
if (gb.IsFileFinished())
{
@@ -680,7 +682,7 @@ bool GCodes::DoFilePrint(GCodeBuffer& gb, const StringRef& reply) noexcept
return true;
}
}
- return reprap.GetLinuxInterface().FillBuffer(gb);
+ return reprap.GetSbcInterface().FillBuffer(gb);
}
}
else
@@ -948,15 +950,15 @@ void GCodes::DoPause(GCodeBuffer& gb, PauseReason reason, const char *msg, uint1
pauseRestorePoint.moveCoords[axis] = moveState.currentUserPosition[axis];
}
-#if HAS_LINUX_INTERFACE
- if (reprap.UsingLinuxInterface())
+#if HAS_SBC_INTERFACE
+ if (reprap.UsingSbcInterface())
{
fileGCode->Init(); // clear the next move
UnlockAll(*fileGCode); // release any locks it had
}
else
- {
#endif
+ {
#if HAS_MASS_STORAGE
// If we skipped any moves, reset the file pointer to the start of the first move we need to replay
// The following could be delayed until we resume the print
@@ -970,9 +972,7 @@ void GCodes::DoPause(GCodeBuffer& gb, PauseReason reason, const char *msg, uint1
}
}
#endif
-#if HAS_LINUX_INTERFACE
}
-#endif
codeQueue->PurgeEntries();
@@ -992,7 +992,7 @@ void GCodes::DoPause(GCodeBuffer& gb, PauseReason reason, const char *msg, uint1
pauseRestorePoint.toolNumber = reprap.GetCurrentToolNumber();
pauseRestorePoint.fanSpeed = lastDefaultFanSpeed;
-#if HAS_MASS_STORAGE || HAS_LINUX_INTERFACE
+#if HAS_MASS_STORAGE || HAS_SBC_INTERFACE
if (!IsSimulating())
{
SaveResumeInfo(false); // create the resume file so that we can resume after power down
@@ -1027,8 +1027,8 @@ void GCodes::DoPause(GCodeBuffer& gb, PauseReason reason, const char *msg, uint1
gb.SetState(newState, param);
pauseState = PauseState::pausing;
-#if HAS_LINUX_INTERFACE
- if (reprap.UsingLinuxInterface())
+#if HAS_SBC_INTERFACE
+ if (reprap.UsingSbcInterface())
{
// Get the print pause reason that is compatible with the API
PrintPausedReason pauseReason = PrintPausedReason::user;
@@ -1059,8 +1059,8 @@ void GCodes::DoPause(GCodeBuffer& gb, PauseReason reason, const char *msg, uint1
break;
}
- // Prepare notification for the Linux side
- reprap.GetLinuxInterface().SetPauseReason(pauseRestorePoint.filePos, pauseReason);
+ // Prepare notification for the SBC
+ reprap.GetSbcInterface().SetPauseReason(pauseRestorePoint.filePos, pauseReason);
}
#endif
@@ -1168,11 +1168,11 @@ bool GCodes::DoEmergencyPause() noexcept
#endif
}
-#if HAS_LINUX_INTERFACE
- if (reprap.UsingLinuxInterface())
+#if HAS_SBC_INTERFACE
+ if (reprap.UsingSbcInterface())
{
PrintPausedReason reason = platform.IsPowerOk() ? PrintPausedReason::stall : PrintPausedReason::lowVoltage;
- reprap.GetLinuxInterface().SetEmergencyPauseReason(pauseRestorePoint.filePos, reason);
+ reprap.GetSbcInterface().SetEmergencyPauseReason(pauseRestorePoint.filePos, reason);
}
#endif
@@ -1331,7 +1331,7 @@ bool GCodes::ReHomeOnStall(DriversBitmap stalledDrivers) noexcept
#endif
-#if HAS_MASS_STORAGE || HAS_LINUX_INTERFACE
+#if HAS_MASS_STORAGE || HAS_SBC_INTERFACE
void GCodes::SaveResumeInfo(bool wasPowerFailure) noexcept
{
@@ -2780,8 +2780,8 @@ bool GCodes::DoFileMacro(GCodeBuffer& gb, const char* fileName, bool reportMissi
printFilePositionAtMacroStart = gb.GetFilePosition();
}
-#if HAS_LINUX_INTERFACE
- if (reprap.UsingLinuxInterface())
+#if HAS_SBC_INTERFACE
+ if (reprap.UsingSbcInterface())
{
if (!gb.RequestMacroFile(fileName, gb.IsBinary() && codeRunning != AsyncSystemMacroCode))
{
@@ -2842,7 +2842,7 @@ bool GCodes::DoFileMacro(GCodeBuffer& gb, const char* fileName, bool reportMissi
#endif
}
-#if HAS_LINUX_INTERFACE || HAS_MASS_STORAGE || HAS_EMBEDDED_FILES
+#if HAS_SBC_INTERFACE || HAS_MASS_STORAGE || HAS_EMBEDDED_FILES
gb.LatestMachineState().doingFileMacro = true;
// The following three flags need to be inherited in the case that a system macro calls another macro, e.g.homeall.g calls homez.g. The Push call copied them over already.
@@ -2873,8 +2873,8 @@ bool GCodes::DoFileMacro(GCodeBuffer& gb, const char* fileName, bool reportMissi
gb.SetState(GCodeState::normal);
gb.Init();
-# if HAS_LINUX_INTERFACE
- if (!reprap.UsingLinuxInterface() && codeRunning != AsyncSystemMacroCode)
+# if HAS_SBC_INTERFACE
+ if (!reprap.UsingSbcInterface() && codeRunning != AsyncSystemMacroCode)
# endif
{
// Don't notify DSF when files are requested asynchronously, it creates excessive traffic
@@ -2895,8 +2895,8 @@ void GCodes::FileMacroCyclesReturn(GCodeBuffer& gb) noexcept
{
if (gb.IsDoingFileMacro())
{
-#if HAS_LINUX_INTERFACE
- if (reprap.UsingLinuxInterface())
+#if HAS_SBC_INTERFACE
+ if (reprap.UsingSbcInterface())
{
gb.AbortFile(false);
}
@@ -3117,9 +3117,9 @@ GCodeResult GCodes::ProbeGrid(GCodeBuffer& gb, const StringRef& reply)
GCodeResult GCodes::LoadHeightMap(GCodeBuffer& gb, const StringRef& reply)
{
-#if HAS_LINUX_INTERFACE
- // If we have a Linux interface and we're using it, the Linux components will take care of file I/O and this should not be called.
- if (reprap.UsingLinuxInterface())
+#if HAS_SBC_INTERFACE
+ // If we have an SBC interface and we're using it, the SBC service will take care of file I/O and this should not be called
+ if (reprap.UsingSbcInterface())
{
reply.copy("Cannot use height map on local SD card when SBC interface is used");
return GCodeResult::error;
@@ -3169,9 +3169,9 @@ GCodeResult GCodes::LoadHeightMap(GCodeBuffer& gb, const StringRef& reply)
// Save the height map and append the success or error message to 'reply', returning true if an error occurred
bool GCodes::TrySaveHeightMap(const char *filename, const StringRef& reply) const noexcept
{
-#if HAS_LINUX_INTERFACE
- // If we have a Linux interface and we're using it, the Linux components will take care of file I/O.
- if (reprap.UsingLinuxInterface())
+#if HAS_SBC_INTERFACE
+ // If we have an SBC connected, the SBC service will take care of heightmap-related file I/O
+ if (reprap.UsingSbcInterface())
{
reply.copy("Cannot use height map on local SD card when SBC interface is used");
return true;
@@ -3209,7 +3209,7 @@ GCodeResult GCodes::SaveHeightMap(GCodeBuffer& gb, const StringRef& reply) const
{
ReadLocker locker(reprap.GetMove().heightMapLock);
- // No need to check if we're using the Linux interface here, because TrySaveHeightMap does that
+ // No need to check if we're using the SBC interface here, because TrySaveHeightMap does that already
if (gb.Seen('P'))
{
String<MaxFilenameLength> heightMapFileName;
@@ -3312,8 +3312,8 @@ void GCodes::StartPrinting(bool fromStart) noexcept
rawExtruderTotal = 0.0;
reprap.GetMove().ResetExtruderPositions();
-#if HAS_LINUX_INTERFACE
- if (!reprap.UsingLinuxInterface())
+#if HAS_SBC_INTERFACE
+ if (!reprap.UsingSbcInterface())
#endif
{
#if HAS_MASS_STORAGE || HAS_EMBEDDED_FILES
@@ -3755,8 +3755,8 @@ void GCodes::HandleReply(GCodeBuffer& gb, GCodeResult rslt, const char* reply) n
// Note that 'reply' may be empty. If it isn't, then we need to append newline when sending it.
void GCodes::HandleReplyPreserveResult(GCodeBuffer& gb, GCodeResult rslt, const char *reply) noexcept
{
-#if HAS_LINUX_INTERFACE
- // Deal with replies to the Linux interface
+#if HAS_SBC_INTERFACE
+ // Deal with replies to the SBC
if (gb.LatestMachineState().lastCodeFromSbc)
{
MessageType type = gb.GetResponseMessageType();
@@ -3859,8 +3859,8 @@ void GCodes::HandleReply(GCodeBuffer& gb, OutputBuffer *reply) noexcept
return;
}
-#if HAS_LINUX_INTERFACE
- // Deal with replies to the Linux interface
+#if HAS_SBC_INTERFACE
+ // Deal with replies to the SBC
if (gb.IsBinary())
{
platform.Message(gb.GetResponseMessageType(), reply);
@@ -4136,8 +4136,8 @@ void GCodes::StopPrint(StopPrintReason reason) noexcept
deferredPauseCommandPending = nullptr;
pauseState = PauseState::notPaused;
-#if HAS_LINUX_INTERFACE
- if (reprap.UsingLinuxInterface())
+#if HAS_SBC_INTERFACE
+ if (reprap.UsingSbcInterface())
{
fileGCode->LatestMachineState().CloseFile();
fileGCode->Init();
@@ -4250,7 +4250,7 @@ void GCodes::StopPrint(StopPrintReason reason) noexcept
platform.MessageF(LoggedGenericMessage, "%s printing file %s, print time was %" PRIu32 "h %" PRIu32 "m\n",
(reason == StopPrintReason::normalCompletion) ? "Finished" : "Cancelled",
printingFilename, printMinutes/60u, printMinutes % 60u);
-#if HAS_MASS_STORAGE || HAS_LINUX_INTERFACE
+#if HAS_MASS_STORAGE || HAS_SBC_INTERFACE
if (reason == StopPrintReason::normalCompletion && !IsSimulating())
{
platform.DeleteSysFile(RESUME_AFTER_POWER_FAIL_G);
@@ -4527,7 +4527,7 @@ void GCodes::SetAllAxesNotHomed() noexcept
}
}
-#if HAS_MASS_STORAGE || HAS_LINUX_INTERFACE
+#if HAS_MASS_STORAGE || HAS_SBC_INTERFACE
// Write the config-override file returning true if an error occurred
GCodeResult GCodes::WriteConfigOverrideFile(GCodeBuffer& gb, const StringRef& reply) const noexcept
@@ -4995,9 +4995,9 @@ void GCodes::ActivateHeightmap(bool activate) noexcept
reprap.GetMove().GetCurrentUserPosition(moveState.coords, 0, reprap.GetCurrentTool());
ToolOffsetInverseTransform(moveState.coords, moveState.currentUserPosition); // update user coordinates to reflect any height map offset at the current position
-#if HAS_LINUX_INTERFACE
+#if HAS_SBC_INTERFACE
// Set a dummy heightmap filename
- if (reprap.UsingLinuxInterface())
+ if (reprap.UsingSbcInterface())
{
HeightMap& map = reprap.GetMove().AccessHeightMap();
map.SetFileName(DefaultHeightMapFile);
@@ -5016,8 +5016,8 @@ bool GCodes::CheckNetworkCommandAllowed(GCodeBuffer& gb, const StringRef& reply,
return false; // just ignore the command but report success
}
-#if HAS_LINUX_INTERFACE
- if (reprap.UsingLinuxInterface())
+#if HAS_SBC_INTERFACE
+ if (reprap.UsingSbcInterface())
{
// Networking is disabled when using the SBC interface, to save RAM
reply.copy("Network-related commands are not supported when using an attached Single Board Computer");
diff --git a/src/GCodes/GCodes.h b/src/GCodes/GCodes.h
index 8863ff89..5724bc6e 100644
--- a/src/GCodes/GCodes.h
+++ b/src/GCodes/GCodes.h
@@ -67,7 +67,7 @@ enum class PauseReason
#endif
};
-// Keep this in sync with PrintStopReason in Linux/MessageFormats.h
+// Keep this in sync with PrintStopReason in SBC/SbcMessageFormats.h
enum class StopPrintReason
{
normalCompletion,
@@ -110,7 +110,7 @@ enum class SimulationMode : uint8_t
highest = partial
};
-class LinuxInterface;
+class SbcInterface;
// The GCode interpreter
@@ -228,7 +228,7 @@ public:
int GetNewToolNumber() const noexcept { return newToolNumber; }
size_t GetCurrentZProbeNumber() const noexcept { return currentZProbeNumber; }
- // These next two are public because they are used by class LinuxInterface
+ // These next two are public because they are used by class SbcInterface
void UnlockAll(const GCodeBuffer& gb) noexcept; // Release all locks
GCodeBuffer *GetGCodeBuffer(GCodeChannel channel) const noexcept { return gcodeSources[channel.ToBaseType()]; }
@@ -424,7 +424,7 @@ private:
#if SUPPORT_WORKPLACE_COORDINATES
GCodeResult GetSetWorkplaceCoordinates(GCodeBuffer& gb, const StringRef& reply, bool compute) THROWS(GCodeException); // Set workspace coordinates
-# if HAS_MASS_STORAGE || HAS_LINUX_INTERFACE
+# if HAS_MASS_STORAGE || HAS_SBC_INTERFACE
bool WriteWorkplaceCoordinates(FileStore *f) const noexcept;
# endif
#endif
@@ -483,13 +483,13 @@ private:
GCodeResult UpdateFirmware(GCodeBuffer& gb, const StringRef &reply) THROWS(GCodeException); // Handle M997
GCodeResult SendI2c(GCodeBuffer& gb, const StringRef &reply) THROWS(GCodeException); // Handle M260
GCodeResult ReceiveI2c(GCodeBuffer& gb, const StringRef &reply) THROWS(GCodeException); // Handle M261
-#if HAS_MASS_STORAGE || HAS_LINUX_INTERFACE || HAS_EMBEDDED_FILES
+#if HAS_MASS_STORAGE || HAS_SBC_INTERFACE || HAS_EMBEDDED_FILES
GCodeResult SimulateFile(GCodeBuffer& gb, const StringRef &reply, const StringRef& file, bool updateFile) THROWS(GCodeException); // Handle M37 to simulate a whole file
GCodeResult ChangeSimulationMode(GCodeBuffer& gb, const StringRef &reply, SimulationMode newSimMode) THROWS(GCodeException); // Handle M37 to change the simulation mode
#endif
GCodeResult WaitForPin(GCodeBuffer& gb, const StringRef &reply) THROWS(GCodeException); // Handle M577
-#if HAS_MASS_STORAGE || HAS_LINUX_INTERFACE
+#if HAS_MASS_STORAGE || HAS_SBC_INTERFACE
GCodeResult WriteConfigOverrideFile(GCodeBuffer& gb, const StringRef& reply) const noexcept; // Write the config-override file
bool WriteConfigOverrideHeader(FileStore *f) const noexcept; // Write the config-override header
#endif
@@ -507,7 +507,7 @@ private:
void EndSimulation(GCodeBuffer *gb) noexcept; // Restore positions etc. when exiting simulation mode
bool IsCodeQueueIdle() const noexcept; // Return true if the code queue is idle
-#if HAS_MASS_STORAGE || HAS_LINUX_INTERFACE
+#if HAS_MASS_STORAGE || HAS_SBC_INTERFACE
void SaveResumeInfo(bool wasPowerFailure) noexcept;
#endif
@@ -541,7 +541,7 @@ private:
Platform& platform; // The RepRap machine
-#if HAS_NETWORKING || HAS_LINUX_INTERFACE
+#if HAS_NETWORKING || HAS_SBC_INTERFACE
NetworkGCodeInput* httpInput; // These cache incoming G-codes...
NetworkGCodeInput* telnetInput; // ...
#endif
@@ -624,7 +624,7 @@ private:
#if HAS_MASS_STORAGE || HAS_EMBEDDED_FILES
FileData fileToPrint; // The next file to print
#endif
-#if HAS_MASS_STORAGE || HAS_LINUX_INTERFACE || HAS_EMBEDDED_FILES
+#if HAS_MASS_STORAGE || HAS_SBC_INTERFACE || HAS_EMBEDDED_FILES
FilePosition fileOffsetToPrint; // The offset to print from
#endif
diff --git a/src/GCodes/GCodes2.cpp b/src/GCodes/GCodes2.cpp
index 8cfa658d..8a41bb53 100644
--- a/src/GCodes/GCodes2.cpp
+++ b/src/GCodes/GCodes2.cpp
@@ -12,8 +12,8 @@
#include "GCodeException.h"
#include "GCodeQueue.h"
#include "Heating/Heat.h"
-#if HAS_LINUX_INTERFACE
-# include <Linux/LinuxInterface.h>
+#if HAS_SBC_INTERFACE
+# include <SBC/SbcInterface.h>
#endif
#include <Movement/Move.h>
#include <Networking/Network.h>
@@ -281,10 +281,10 @@ bool GCodes::HandleGcode(GCodeBuffer& gb, const StringRef& reply) THROWS(GCodeEx
case 29: // Grid-based bed probing
-#if HAS_LINUX_INTERFACE
- // Pass file- and system-related commands to DSF if they came from somewhere else.
+#if HAS_SBC_INTERFACE
+ // Pass file- and system-related commands to the SBC service if they came from anywhere else.
// They will be passed back to us via a binary buffer or separate SPI message if necessary.
- if (reprap.UsingLinuxInterface() && reprap.GetLinuxInterface().IsConnected() && !gb.IsBinary())
+ if (reprap.UsingSbcInterface() && reprap.GetSbcInterface().IsConnected() && !gb.IsBinary())
{
gb.SendToSbc();
return false;
@@ -471,9 +471,10 @@ bool GCodes::HandleMcode(GCodeBuffer& gb, const StringRef& reply) THROWS(GCodeEx
return true; // we don't simulate most M codes
}
-#if HAS_LINUX_INTERFACE
- // Pass file- and system-related commands to DSF if they came from somewhere else. They will be passed back to us via a binary buffer or separate SPI message if necessary.
- if ( reprap.UsingLinuxInterface() && reprap.GetLinuxInterface().IsConnected() && !gb.IsBinary()
+#if HAS_SBC_INTERFACE
+ // Pass file- and system-related commands to the SBC service if they came from somewhere else.
+ // They will be passed back to us via a binary buffer or separate SPI message if necessary.
+ if ( reprap.UsingSbcInterface() && reprap.GetSbcInterface().IsConnected() && !gb.IsBinary()
&& ( code == 0 || code == 1
|| code == 20 || code == 21 || code == 22 || code == 23 || code == 24 || code == 26 || code == 27 || code == 28 || code == 29
|| code == 30 || code == 32 || code == 36 || code == 37 || code == 38 || code == 39
@@ -847,7 +848,7 @@ bool GCodes::HandleMcode(GCodeBuffer& gb, const StringRef& reply) THROWS(GCodeEx
break;
#endif
-#if HAS_MASS_STORAGE || HAS_LINUX_INTERFACE || HAS_EMBEDDED_FILES
+#if HAS_MASS_STORAGE || HAS_SBC_INTERFACE || HAS_EMBEDDED_FILES
case 23: // Set file to print
case 32: // Select file and start SD print
// We now allow a file that is being printed to chain to another file. This is required for the resume-after-power-fail functionality.
@@ -866,8 +867,8 @@ bool GCodes::HandleMcode(GCodeBuffer& gb, const StringRef& reply) THROWS(GCodeEx
String<MaxFilenameLength> filename;
gb.GetUnprecedentedString(filename.GetRef());
if (
-#if HAS_LINUX_INTERFACE
- reprap.UsingLinuxInterface()
+#if HAS_SBC_INTERFACE
+ reprap.UsingSbcInterface()
# if HAS_MASS_STORAGE
||
# endif
@@ -932,15 +933,15 @@ bool GCodes::HandleMcode(GCodeBuffer& gb, const StringRef& reply) THROWS(GCodeEx
}
}
}
-#if HAS_MASS_STORAGE || HAS_LINUX_INTERFACE || HAS_EMBEDDED_FILES
+#if HAS_MASS_STORAGE || HAS_SBC_INTERFACE || HAS_EMBEDDED_FILES
else if (
# if HAS_MASS_STORAGE || HAS_EMBEDDED_FILES
!fileToPrint.IsLive()
# else
true
# endif
-# if HAS_LINUX_INTERFACE
- && !reprap.UsingLinuxInterface()
+# if HAS_SBC_INTERFACE
+ && !reprap.UsingSbcInterface()
# endif
)
{
@@ -964,8 +965,8 @@ bool GCodes::HandleMcode(GCodeBuffer& gb, const StringRef& reply) THROWS(GCodeEx
// We executed M26 to set the file offset, which normally means that we are executing resurrect.g.
// We need to copy the absolute/relative and volumetric extrusion flags over
fileGCode->OriginalMachineState().CopyStateFrom(gb.LatestMachineState());
-# if HAS_LINUX_INTERFACE
- if (!reprap.UsingLinuxInterface())
+# if HAS_SBC_INTERFACE
+ if (!reprap.UsingSbcInterface())
# endif
# if HAS_MASS_STORAGE || HAS_EMBEDDED_FILES
{
@@ -1057,7 +1058,7 @@ bool GCodes::HandleMcode(GCodeBuffer& gb, const StringRef& reply) THROWS(GCodeEx
}
break;
-#if HAS_MASS_STORAGE || HAS_LINUX_INTERFACE || HAS_EMBEDDED_FILES
+#if HAS_MASS_STORAGE || HAS_SBC_INTERFACE || HAS_EMBEDDED_FILES
case 26: // Set SD position
// This is used between executing M23 to set up the file to print, and M25 to print it
gb.MustSee('S');
@@ -1123,10 +1124,10 @@ bool GCodes::HandleMcode(GCodeBuffer& gb, const StringRef& reply) THROWS(GCodeEx
// For case 32, see case 23
-#if HAS_MASS_STORAGE || HAS_LINUX_INTERFACE || HAS_EMBEDDED_FILES
+#if HAS_MASS_STORAGE || HAS_SBC_INTERFACE || HAS_EMBEDDED_FILES
case 36: // Return file information
-# if HAS_LINUX_INTERFACE
- if (reprap.UsingLinuxInterface())
+# if HAS_SBC_INTERFACE
+ if (reprap.UsingSbcInterface())
{
reprap.GetFileInfoResponse(nullptr, outBuf, true);
}
@@ -1147,8 +1148,8 @@ bool GCodes::HandleMcode(GCodeBuffer& gb, const StringRef& reply) THROWS(GCodeEx
break;
case 37: // Simulation mode on/off, or simulate a whole file
-# if HAS_LINUX_INTERFACE
- if (reprap.UsingLinuxInterface() && !gb.IsBinary())
+# if HAS_SBC_INTERFACE
+ if (reprap.UsingSbcInterface() && !gb.IsBinary())
{
reply.copy("M37 can be only started from the SBC interface");
result = GCodeResult::error;
@@ -2558,8 +2559,8 @@ bool GCodes::HandleMcode(GCodeBuffer& gb, const StringRef& reply) THROWS(GCodeEx
// Don't lock the movement system, because if we do then only the channel that issues the M291 can move the axes
if (sParam == 2 || sParam == 3)
{
-#if HAS_LINUX_INTERFACE
- if (reprap.UsingLinuxInterface())
+#if HAS_SBC_INTERFACE
+ if (reprap.UsingSbcInterface())
{
gb.SetState(GCodeState::waitingForAcknowledgement);
}
@@ -2989,13 +2990,13 @@ bool GCodes::HandleMcode(GCodeBuffer& gb, const StringRef& reply) THROWS(GCodeEx
result = buildObjects.HandleM486(gb, reply, outBuf);
break;
-#if HAS_MASS_STORAGE || HAS_LINUX_INTERFACE
+#if HAS_MASS_STORAGE || HAS_SBC_INTERFACE
case 500: // Store parameters in config-override.g
result = WriteConfigOverrideFile(gb, reply);
break;
#endif
-#if HAS_MASS_STORAGE || HAS_EMBEDDED_FILES || HAS_LINUX_INTERFACE
+#if HAS_MASS_STORAGE || HAS_EMBEDDED_FILES || HAS_SBC_INTERFACE
case 501: // Load parameters from config-override.g
if (!gb.LatestMachineState().runningM502 && !gb.LatestMachineState().runningM501) // when running M502 we ignore config-override.g
{
@@ -3111,8 +3112,8 @@ bool GCodes::HandleMcode(GCodeBuffer& gb, const StringRef& reply) THROWS(GCodeEx
break;
case 550: // Set/report machine name
-#if HAS_LINUX_INTERFACE
- if (reprap.UsingLinuxInterface() && !gb.IsBinary())
+#if HAS_SBC_INTERFACE
+ if (reprap.UsingSbcInterface() && !gb.IsBinary())
{
result = GCodeResult::errorNotSupported;
}
@@ -3573,11 +3574,11 @@ bool GCodes::HandleMcode(GCodeBuffer& gb, const StringRef& reply) THROWS(GCodeEx
}
break;
-#if HAS_LINUX_INTERFACE
+#if HAS_SBC_INTERFACE
case 576: // Set SPI communication parameters
- if (reprap.UsingLinuxInterface())
+ if (reprap.UsingSbcInterface())
{
- result = reprap.GetLinuxInterface().HandleM576(gb, reply);
+ result = reprap.GetSbcInterface().HandleM576(gb, reply);
}
else
{
@@ -4444,7 +4445,7 @@ bool GCodes::HandleMcode(GCodeBuffer& gb, const StringRef& reply) THROWS(GCodeEx
break;
#endif
-#if HAS_MASS_STORAGE || HAS_LINUX_INTERFACE
+#if HAS_MASS_STORAGE || HAS_SBC_INTERFACE
case 916:
if (!platform.SysFileExists(RESUME_AFTER_POWER_FAIL_G))
{
diff --git a/src/GCodes/GCodes3.cpp b/src/GCodes/GCodes3.cpp
index b5ac630d..4bb98433 100644
--- a/src/GCodes/GCodes3.cpp
+++ b/src/GCodes/GCodes3.cpp
@@ -204,7 +204,7 @@ GCodeResult GCodes::GetSetWorkplaceCoordinates(GCodeBuffer& gb, const StringRef&
return GCodeResult::ok;
}
-# if HAS_MASS_STORAGE || HAS_LINUX_INTERFACE
+# if HAS_MASS_STORAGE || HAS_SBC_INTERFACE
// Save all the workplace coordinate offsets to file returning true if successful. Used by M500 and by SaveResumeInfo.
bool GCodes::WriteWorkplaceCoordinates(FileStore *f) const noexcept
@@ -405,7 +405,7 @@ GCodeResult GCodes::DefineGrid(GCodeBuffer& gb, const StringRef &reply) THROWS(G
}
-#if HAS_MASS_STORAGE || HAS_LINUX_INTERFACE || HAS_EMBEDDED_FILES
+#if HAS_MASS_STORAGE || HAS_SBC_INTERFACE || HAS_EMBEDDED_FILES
// Handle M37 to simulate a whole file
GCodeResult GCodes::SimulateFile(GCodeBuffer& gb, const StringRef &reply, const StringRef& file, bool updateFile)
@@ -418,8 +418,8 @@ GCodeResult GCodes::SimulateFile(GCodeBuffer& gb, const StringRef &reply, const
# if HAS_MASS_STORAGE || HAS_EMBEDDED_FILES
if (
-# if HAS_LINUX_INTERFACE
- reprap.UsingLinuxInterface() ||
+# if HAS_SBC_INTERFACE
+ reprap.UsingSbcInterface() ||
# endif
QueueFileToPrint(file.c_str(), reply))
# endif
@@ -432,8 +432,8 @@ GCodeResult GCodes::SimulateFile(GCodeBuffer& gb, const StringRef &reply, const
}
simulationTime = 0.0;
exitSimulationWhenFileComplete = true;
-# if HAS_LINUX_INTERFACE
- updateFileWhenSimulationComplete = updateFile && !reprap.UsingLinuxInterface();
+# if HAS_SBC_INTERFACE
+ updateFileWhenSimulationComplete = updateFile && !reprap.UsingSbcInterface();
# else
updateFileWhenSimulationComplete = updateFile;
# endif
diff --git a/src/GCodes/GCodes4.cpp b/src/GCodes/GCodes4.cpp
index 8351be96..fa1cc47d 100644
--- a/src/GCodes/GCodes4.cpp
+++ b/src/GCodes/GCodes4.cpp
@@ -8,8 +8,8 @@
#include <Heating/Heat.h>
#include <Endstops/ZProbe.h>
-#if HAS_LINUX_INTERFACE
-# include <Linux/LinuxInterface.h>
+#if HAS_SBC_INTERFACE
+# include <SBC/SbcInterface.h>
#endif
#if HAS_WIFI_NETWORKING || HAS_AUX_DEVICES
@@ -22,9 +22,9 @@
// So any large local objects allocated here increase the amount of MAIN stack size needed.
void GCodes::RunStateMachine(GCodeBuffer& gb, const StringRef& reply) noexcept
{
-#if HAS_LINUX_INTERFACE
+#if HAS_SBC_INTERFACE
// Wait for the G-code replies and abort requests to go before anything else is done in the state machine
- if (reprap.UsingLinuxInterface() && (gb.IsAbortRequested() || gb.IsAbortAllRequested()))
+ if (reprap.UsingSbcInterface() && (gb.IsAbortRequested() || gb.IsAbortAllRequested()))
{
return;
}
@@ -499,8 +499,8 @@ void GCodes::RunStateMachine(GCodeBuffer& gb, const StringRef& reply) noexcept
}
platform.MessageF(LogWarn, "%s\n", reply.c_str());
pauseState = PauseState::paused;
-#if HAS_LINUX_INTERFACE
- reportPause = reprap.UsingLinuxInterface();
+#if HAS_SBC_INTERFACE
+ reportPause = reprap.UsingSbcInterface();
#endif
gb.SetState(GCodeState::normal);
}
@@ -909,8 +909,8 @@ void GCodes::RunStateMachine(GCodeBuffer& gb, const StringRef& reply) noexcept
reply.printf("%" PRIu32 " points probed, min error %.3f, max error %.3f, mean %.3f, deviation %.3f\n",
numPointsProbed, (double)minError, (double)maxError, (double)deviation.GetMean(), (double)deviation.GetDeviationFromMean());
#if HAS_MASS_STORAGE
-# if HAS_LINUX_INTERFACE
- if (!reprap.UsingLinuxInterface())
+# if HAS_SBC_INTERFACE
+ if (!reprap.UsingSbcInterface())
# endif
{
if (TrySaveHeightMap(DefaultHeightMapFile, reply))
@@ -1440,7 +1440,7 @@ void GCodes::RunStateMachine(GCodeBuffer& gb, const StringRef& reply) noexcept
}
else
{
-# if HAS_MASS_STORAGE || HAS_LINUX_INTERFACE
+# if HAS_MASS_STORAGE || HAS_SBC_INTERFACE
SaveResumeInfo(true); // create the resume file so that we can resume after power down
# endif
platform.Message(LoggedGenericMessage, "Print auto-paused due to low voltage\n");
@@ -1521,7 +1521,7 @@ void GCodes::RunStateMachine(GCodeBuffer& gb, const StringRef& reply) noexcept
break;
#endif
-#if HAS_LINUX_INTERFACE
+#if HAS_SBC_INTERFACE
case GCodeState::waitingForAcknowledgement: // finished M291 and the SBC expects a response next
#endif
case GCodeState::checkError: // we return to this state after running the retractprobe macro when there may be a stored error message
@@ -1543,11 +1543,11 @@ void GCodes::RunStateMachine(GCodeBuffer& gb, const StringRef& reply) noexcept
HandleReply(gb, stateMachineResult, reply.c_str());
CheckForDeferredPause(gb);
-#if HAS_LINUX_INTERFACE
+#if HAS_SBC_INTERFACE
if (reportPause)
{
fileGCode->Invalidate();
- reprap.GetLinuxInterface().ReportPause();
+ reprap.GetSbcInterface().ReportPause();
}
#endif
}
diff --git a/src/GCodes/ObjectTracker.cpp b/src/GCodes/ObjectTracker.cpp
index fd1af4c1..5db37dbc 100644
--- a/src/GCodes/ObjectTracker.cpp
+++ b/src/GCodes/ObjectTracker.cpp
@@ -265,7 +265,7 @@ void ObjectTracker::ResumePrinting(GCodeBuffer& gb) noexcept
}
}
-#if HAS_MASS_STORAGE || HAS_LINUX_INTERFACE
+#if HAS_MASS_STORAGE || HAS_SBC_INTERFACE
// Write the object details to file, returning true if successful
bool ObjectTracker::WriteObjectDirectory(FileStore *f) const noexcept
diff --git a/src/GCodes/ObjectTracker.h b/src/GCodes/ObjectTracker.h
index a3b2b098..6f5d8670 100644
--- a/src/GCodes/ObjectTracker.h
+++ b/src/GCodes/ObjectTracker.h
@@ -52,7 +52,7 @@ public:
bool IsCancelled(size_t objectNumber) const noexcept { return objectsCancelled.IsBitSet(objectNumber); }
#endif
-#if HAS_MASS_STORAGE || HAS_LINUX_INTERFACE
+#if HAS_MASS_STORAGE || HAS_SBC_INTERFACE
bool WriteObjectDirectory(FileStore *f) const noexcept;
#endif
diff --git a/src/Heating/FOPDT.cpp b/src/Heating/FOPDT.cpp
index 911e9100..22b3f414 100644
--- a/src/Heating/FOPDT.cpp
+++ b/src/Heating/FOPDT.cpp
@@ -7,7 +7,7 @@
#include "FOPDT.h"
-#if HAS_MASS_STORAGE || HAS_LINUX_INTERFACE
+#if HAS_MASS_STORAGE || HAS_SBC_INTERFACE
# include "Storage/FileStore.h"
#endif
@@ -151,7 +151,7 @@ void FopDt::SetRawPidParameters(float p_kP, float p_recipTi, float p_tD) noexcep
pidParametersOverridden = true;
}
-#if HAS_MASS_STORAGE || HAS_LINUX_INTERFACE
+#if HAS_MASS_STORAGE || HAS_SBC_INTERFACE
// Write the model parameters to file returning true if no error
bool FopDt::WriteParameters(FileStore *f, size_t heater) const noexcept
diff --git a/src/Heating/FOPDT.h b/src/Heating/FOPDT.h
index 23802165..e69c3ac6 100644
--- a/src/Heating/FOPDT.h
+++ b/src/Heating/FOPDT.h
@@ -73,7 +73,7 @@ public:
return (forLoadChange) ? loadChangeParams : setpointChangeParams;
}
-#if HAS_MASS_STORAGE || HAS_LINUX_INTERFACE
+#if HAS_MASS_STORAGE || HAS_SBC_INTERFACE
bool WriteParameters(FileStore *f, size_t heater) const noexcept; // erite the model parameters to file returning true if no error
#endif
diff --git a/src/Heating/Heat.cpp b/src/Heating/Heat.cpp
index f5705c7d..93df38e2 100644
--- a/src/Heating/Heat.cpp
+++ b/src/Heating/Heat.cpp
@@ -889,7 +889,7 @@ float Heat::GetHighestTemperatureLimit() const noexcept
return limit;
}
-#if HAS_MASS_STORAGE || HAS_LINUX_INTERFACE
+#if HAS_MASS_STORAGE || HAS_SBC_INTERFACE
// Write heater model parameters to file returning true if no error
bool Heat::WriteModelParameters(FileStore *f) const noexcept
@@ -1255,7 +1255,7 @@ void Heat::InsertSensor(TemperatureSensor *newSensor) noexcept
}
}
-#if HAS_MASS_STORAGE || HAS_LINUX_INTERFACE
+#if HAS_MASS_STORAGE || HAS_SBC_INTERFACE
// Save some resume information returning true if successful.
// We assume that the bed and chamber heaters are either on and active, or off (not on standby).
diff --git a/src/Heating/Heat.h b/src/Heating/Heat.h
index 6d619e91..11418186 100644
--- a/src/Heating/Heat.h
+++ b/src/Heating/Heat.h
@@ -129,7 +129,7 @@ public:
void FeedForwardAdjustment(unsigned int heater, float fanPwmChange, float extrusionChange) const noexcept;
void SetExtrusionFeedForward(unsigned int heater, float pwm) const noexcept;
-#if HAS_MASS_STORAGE || HAS_LINUX_INTERFACE
+#if HAS_MASS_STORAGE || HAS_SBC_INTERFACE
bool WriteModelParameters(FileStore *f) const noexcept; // Write heater model parameters to file returning true if no error
bool WriteBedAndChamberTempSettings(FileStore *f) const noexcept; // Save some resume information
#endif
diff --git a/src/Linux/LinuxInterface.cpp b/src/Linux/LinuxInterface.cpp
deleted file mode 100644
index 202c75f7..00000000
--- a/src/Linux/LinuxInterface.cpp
+++ /dev/null
@@ -1,1722 +0,0 @@
-/*
- * LinuxInterface.cpp
- *
- * Created on: 29 Mar 2019
- * Author: Christian
- */
-
-#include "LinuxInterface.h"
-#include "DataTransfer.h"
-
-#if HAS_LINUX_INTERFACE
-
-#include <GCodes/GCodeBuffer/ExpressionParser.h>
-#include <GCodes/GCodeBuffer/GCodeBuffer.h>
-#include <Heating/Heat.h>
-#include <Movement/Move.h>
-#include <Platform/Platform.h>
-#include <PrintMonitor/PrintMonitor.h>
-#include <Tools/Filament.h>
-#include <Platform/RepRap.h>
-#include <RepRapFirmware.h>
-#include <Platform/Tasks.h>
-#include <Hardware/SoftwareReset.h>
-#include <Hardware/ExceptionHandlers.h>
-#include <Platform/TaskPriorities.h>
-
-extern char _estack; // defined by the linker
-
-volatile OutputStack LinuxInterface::gcodeReply;
-Mutex LinuxInterface::gcodeReplyMutex;
-
-// The SBC stack size needs to be enough to support rr_model and expression evaluation
-// In RRF 3.3beta3, 744 is only just enough for simple expression evaluation in a release build when using globals
-// In 3.3beta3.1 we have saved ~151 bytes (37 words) of stack compared to 3.3beta3
-#ifdef __LPC17xx__
-constexpr size_t SBCTaskStackWords = 375;
-#elif defined(DEBUG)
-constexpr size_t SBCTaskStackWords = 1200; // debug builds use more stack
-#else
-constexpr size_t SBCTaskStackWords = 1000; // increased from 820 so that we can evaluate "abs(move.calibration.initial.deviation - move.calibration.final.deviation) < 0.000"
-#endif
-
-constexpr uint32_t LinuxYieldTimeout = 10;
-
-static Task<SBCTaskStackWords> *sbcTask;
-
-extern "C" [[noreturn]] void SBCTaskStart(void * pvParameters) noexcept
-{
- reprap.GetLinuxInterface().TaskLoop();
-}
-
-LinuxInterface::LinuxInterface() noexcept : isConnected(false), numDisconnects(0), numTimeouts(0),
- maxDelayBetweenTransfers(SpiTransferDelay), maxFileOpenDelay(SpiFileOpenDelay), numMaxEvents(SpiEventsRequired),
- delaying(false), numEvents(0), reportPause(false), reportPauseWritten(false), printAborted(false),
- codeBuffer(nullptr), rxPointer(0), txPointer(0), txEnd(0), sendBufferUpdate(true), writingIap(false), iapWritePointer(IAP_IMAGE_START),
- waitingForFileChunk(false), fileMutex(), fileSemaphore(), fileOperation(FileOperation::none), fileOperationPending(false)
-#ifdef TRACK_FILE_CODES
- , fileCodesRead(0), fileCodesHandled(0), fileMacrosRunning(0), fileMacrosClosing(0)
-#endif
-{
-}
-
-void LinuxInterface::Init() noexcept
-{
- if (reprap.UsingLinuxInterface())
- {
- fileMutex.Create("SBCFile");
- gcodeReplyMutex.Create("SBCReply");
- codeBuffer = (char *)new uint32_t[(SpiCodeBufferSize + 3)/4];
-
-#if defined(DUET_NG)
- // Make sure that the Wifi module if present is disabled. The ESP Reset pin is already forced low in Platform::Init();
- pinMode(EspEnablePin, OUTPUT_LOW);
-#endif
-
- transfer.Init();
- sbcTask = new Task<SBCTaskStackWords>();
- sbcTask->Create(SBCTaskStart, "SBC", nullptr, TaskPriority::SbcPriority);
- iapRamAvailable = &_estack - Tasks::GetHeapTop();
- }
- else
- {
- // Set up the data transfer to exchange the header + response code. No task is started to save memory
- transfer.Init();
- }
-}
-
-void LinuxInterface::Spin() noexcept
-{
- if (transfer.IsReady())
- {
- // Don't process anything, just kick off the next transfer to report we're operating in standalone mode
- transfer.StartNextTransfer();
- }
-}
-
-[[noreturn]] void LinuxInterface::TaskLoop() noexcept
-{
- transfer.InitFromTask();
- transfer.StartNextTransfer();
-
- bool isReady = false, hadReset = false, skipNextDelay = false;
- for (;;)
- {
- if (hadReset)
- {
- isReady = true;
- hadReset = false;
- }
- else if (transfer.IsReady())
- {
- isReady = true;
- hadReset = isConnected && transfer.LinuxHadReset();
- }
- else
- {
- isReady = false;
- }
-
- if (isReady && !hadReset)
- {
- // Check if the connection state has changed
- if (!isConnected && !writingIap)
- {
- isConnected = true;
- reprap.GetPlatform().Message(NetworkInfoMessage, "Connection to Linux established!\n");
- }
-
- // Process incoming packets
- bool codeBufferAvailable = true;
- for (size_t i = 0; i < transfer.PacketsToRead(); i++)
- {
- const PacketHeader * const packet = transfer.ReadPacket();
- if (packet == nullptr)
- {
- if (reprap.Debug(moduleLinuxInterface))
- {
- debugPrintf("Error trying to read next SPI packet\n");
- }
- break;
- }
-
- if (packet->request >= (uint16_t)LinuxRequest::InvalidRequest)
- {
- REPORT_INTERNAL_ERROR;
- break;
- }
-
- bool packetAcknowledged = true;
- switch ((LinuxRequest)packet->request)
- {
- // Perform an emergency stop
- case LinuxRequest::EmergencyStop:
- reprap.EmergencyStop();
- break;
-
- // Reset the controller
- case LinuxRequest::Reset:
- SoftwareReset(SoftwareResetReason::user);
- break;
-
- // Perform a G/M/T-code
- case LinuxRequest::Code:
- {
- // Read the next code
- if (packet->length == 0)
- {
- reprap.GetPlatform().Message(WarningMessage, "Received empty binary code, discarding\n");
- break;
- }
-
- const CodeHeader *code = reinterpret_cast<const CodeHeader*>(transfer.ReadData(packet->length));
- const GCodeChannel channel(code->channel);
- GCodeBuffer * const gb = reprap.GetGCodes().GetGCodeBuffer(channel);
- if (gb->IsInvalidated())
- {
- // Don't deal with codes that will be thrown away
- break;
- }
-
- // Check if a GB is waiting for a macro file to be started
- if (gb->IsWaitingForMacro() && !gb->IsMacroRequestPending())
- {
- gb->ResolveMacroRequest(false, false);
-#ifdef TRACK_FILE_CODES
- if (channel == GCodeChannel::File)
- {
- fileMacrosRunning++;
- }
-#endif
- }
-
- // Don't process any more codes if we failed to store them last time...
- if (!codeBufferAvailable)
- {
- packetAcknowledged = false;
- break;
- }
-
- TaskCriticalSectionLocker locker;
-
- // Make sure no existing codes are overwritten
- uint16_t bufferedCodeSize = sizeof(BufferedCodeHeader) + packet->length;
- if ((txEnd == 0 && bufferedCodeSize > max<uint16_t>(rxPointer, SpiCodeBufferSize - txPointer)) ||
- (txEnd != 0 && bufferedCodeSize > rxPointer - txPointer))
- {
- //debugPrintf("Failed to store code, RX/TX %d/%d-%d\n", rxPointer, txPointer, txEnd);
- packetAcknowledged = codeBufferAvailable = false;
- break;
- }
-
- // Overlap if necessary
- if (txPointer + bufferedCodeSize > SpiCodeBufferSize)
- {
- txEnd = txPointer;
- txPointer = 0;
- sendBufferUpdate = true;
- }
-
- // Store the buffer header
- BufferedCodeHeader *bufHeader = reinterpret_cast<BufferedCodeHeader *>(codeBuffer + txPointer);
- bufHeader->isPending = true;
- bufHeader->length = packet->length;
-
- // Store the corresponding code. Binary codes are always aligned on a 4-byte boundary
- uint32_t *dst = reinterpret_cast<uint32_t *>(codeBuffer + txPointer + sizeof(BufferedCodeHeader));
- const uint32_t *src = reinterpret_cast<const uint32_t *>(code);
- memcpyu32(dst, src, packet->length / sizeof(uint32_t));
- txPointer += bufferedCodeSize;
- break;
- }
-
- // Get the object model
- case LinuxRequest::GetObjectModel:
- {
- String<StringLength100> key;
- String<StringLength20> flags;
- transfer.ReadGetObjectModel(packet->length, key.GetRef(), flags.GetRef());
-
- try
- {
- OutputBuffer *outBuf = reprap.GetModelResponse(key.c_str(), flags.c_str());
- if (outBuf == nullptr || !transfer.WriteObjectModel(outBuf))
- {
- // Failed to write the whole object model, try again later
- packetAcknowledged = false;
- OutputBuffer::ReleaseAll(outBuf);
- }
- }
- catch (const GCodeException& e)
- {
- // Get the error message and send it back to DSF
- OutputBuffer *buf;
- if (OutputBuffer::Allocate(buf))
- {
- String<StringLength100> errorMessage;
- e.GetMessage(errorMessage.GetRef(), nullptr);
- buf->cat(errorMessage.c_str());
- if (!transfer.WriteObjectModel(buf))
- {
- OutputBuffer::ReleaseAll(buf);
- packetAcknowledged = false;
- }
- }
- else
- {
- packetAcknowledged = false;
- }
- }
- break;
- }
-
- // Set value in the object model
- case LinuxRequest::SetObjectModel:
- {
- const size_t dataLength = packet->length;
- const char * const data = transfer.ReadData(dataLength);
- // TODO implement this
- (void)data;
- break;
- }
-
- // Print is about to be started, set file print info
- case LinuxRequest::SetPrintFileInfo:
- {
- String<MaxFilenameLength> filename;
- transfer.ReadPrintStartedInfo(packet->length, filename.GetRef(), fileInfo);
- reprap.GetPrintMonitor().SetPrintingFileInfo(filename.c_str(), fileInfo);
- break;
- }
-
- // Print has been stopped
- case LinuxRequest::PrintStopped:
- {
- const PrintStoppedReason reason = transfer.ReadPrintStoppedInfo();
- if (reason == PrintStoppedReason::abort)
- {
- // Stop the print with the given reason
- printAborted = true;
- InvalidateBufferedCodes(GCodeChannel::File);
- }
- else
- {
- // Just mark the print file as finished
- GCodeBuffer * const gb = reprap.GetGCodes().GetGCodeBuffer(GCodeChannel::File);
- MutexLocker locker(gb->mutex, LinuxYieldTimeout);
- if (locker.IsAcquired())
- {
- gb->SetPrintFinished();
- }
- else
- {
- packetAcknowledged = false;
- }
- }
- break;
- }
-
- // Macro file has been finished
- case LinuxRequest::MacroCompleted:
- {
- bool error;
- const GCodeChannel channel = transfer.ReadMacroCompleteInfo(error);
- if (channel.IsValid())
- {
- GCodeBuffer * const gb = reprap.GetGCodes().GetGCodeBuffer(channel);
- if (gb->IsWaitingForMacro() && !gb->IsMacroRequestPending())
- {
- gb->ResolveMacroRequest(error, true);
- if (reprap.Debug(moduleLinuxInterface))
- {
- debugPrintf("Waiting macro completed on channel %u\n", channel.ToBaseType());
- }
- }
- else
- {
- MutexLocker locker(gb->mutex, LinuxYieldTimeout);
- if (locker.IsAcquired())
- {
- if (error)
- {
- gb->CurrentFileMachineState().CloseFile();
- gb->PopState();
- gb->Init();
- }
- else
- {
-#ifdef TRACK_FILE_CODES
- if (channel == GCodeChannel::File)
- {
- fileMacrosClosing++;
- }
-#endif
- gb->SetFileFinished();
- }
-
- if (reprap.Debug(moduleLinuxInterface))
- {
- debugPrintf("Macro completed on channel %u\n", channel.ToBaseType());
- }
- }
- else
- {
- packetAcknowledged = false;
- }
- }
- }
- else
- {
- REPORT_INTERNAL_ERROR;
- }
- break;
- }
-
- // Return heightmap as generated by G29 S0
- case LinuxRequest::GetHeightMap:
- {
- ConditionalReadLocker locker(reprap.GetMove().heightMapLock);
- if (locker.IsLocked())
- {
- packetAcknowledged = transfer.WriteHeightMap();
- }
- else
- {
- packetAcknowledged = false;
- }
- break;
- }
-
- // Set heightmap via G29 S1
- case LinuxRequest::SetHeightMap:
- {
- ConditionalWriteLocker locker(reprap.GetMove().heightMapLock);
- if (locker.IsLocked())
- {
- if (!transfer.ReadHeightMap())
- {
- reprap.GetPlatform().Message(ErrorMessage, "Failed to set height map - bad data?\n");
- }
- }
- else
- {
- packetAcknowledged = false;
- }
- break;
- }
-
- // Lock movement and wait for standstill
- case LinuxRequest::LockMovementAndWaitForStandstill:
- {
- const GCodeChannel channel = transfer.ReadCodeChannel();
- if (channel.IsValid())
- {
- GCodeBuffer * const gb = reprap.GetGCodes().GetGCodeBuffer(channel);
- MutexLocker locker(gb->mutex, LinuxYieldTimeout);
- if (locker.IsAcquired() && reprap.GetGCodes().LockMovementAndWaitForStandstill(*gb))
- {
- transfer.WriteLocked(channel);
- }
- else
- {
- packetAcknowledged = false;
- }
- }
- else
- {
- REPORT_INTERNAL_ERROR;
- }
- break;
- }
-
- // Unlock everything
- case LinuxRequest::Unlock:
- {
- const GCodeChannel channel = transfer.ReadCodeChannel();
- if (channel.IsValid())
- {
- GCodeBuffer * const gb = reprap.GetGCodes().GetGCodeBuffer(channel);
- MutexLocker locker(gb->mutex, LinuxYieldTimeout);
- if (locker.IsAcquired())
- {
- reprap.GetGCodes().UnlockAll(*gb);
- }
- else
- {
- packetAcknowledged = false;
- }
- }
- else
- {
- REPORT_INTERNAL_ERROR;
- }
- break;
- }
-
- // Write another chunk of the IAP binary to the designated Flash area
- case LinuxRequest::WriteIap:
- {
- if (iapWritePointer == IAP_IMAGE_START) // if start of IAP write
- {
- reprap.PrepareToLoadIap();
- writingIap = true;
- }
-
- // Copy another IAP chunk. It's always bound on a 4-byte boundary
- uint32_t *dst = reinterpret_cast<uint32_t *>(iapWritePointer);
- const uint32_t *src = reinterpret_cast<const uint32_t *>(transfer.ReadData(packet->length));
- memcpyu32(dst, src, packet->length / sizeof(uint32_t));
- iapWritePointer += packet->length;
- break;
- }
-
- // Launch the IAP binary
- case LinuxRequest::StartIap:
- reprap.StartIap(nullptr);
- break;
-
- // Assign filament (deprecated)
- case LinuxRequest::AssignFilament_deprecated:
- (void)transfer.ReadData(packet->length); // skip the packet content
- break;
-
- // Return a file chunk
- case LinuxRequest::FileChunk:
- transfer.ReadFileChunk(requestedFileBuffer, requestedFileDataLength, requestedFileLength);
- requestedFileSemaphore.Give();
- break;
-
- // Evaluate an expression
- case LinuxRequest::EvaluateExpression:
- {
- String<GCODE_LENGTH> expression;
- const GCodeChannel channel = transfer.ReadEvaluateExpression(packet->length, expression.GetRef());
- if (channel.IsValid())
- {
- GCodeBuffer * const gb = reprap.GetGCodes().GetGCodeBuffer(channel);
-
- // If there is a macro file waiting, the first instruction must be conditional. Don't block any longer...
- if (gb->IsWaitingForMacro())
- {
- gb->ResolveMacroRequest(false, false);
-#ifdef TRACK_FILE_CODES
- if (channel == GCodeChannel::File)
- {
- fileMacrosRunning++;
- }
-#endif
- }
-
- try
- {
- // Evaluate the expression and send the result to DSF
- MutexLocker lock(gb->mutex, LinuxYieldTimeout);
- if (lock.IsAcquired())
- {
- ExpressionParser parser(*gb, expression.c_str(), expression.c_str() + expression.strlen());
- const ExpressionValue val = parser.Parse();
- packetAcknowledged = transfer.WriteEvaluationResult(expression.c_str(), val);
- }
- else
- {
- packetAcknowledged = false;
- }
- }
- catch (const GCodeException& e)
- {
- // Get the error message and send it back to DSF
- String<StringLength100> errorMessage;
- e.GetMessage(errorMessage.GetRef(), nullptr);
- packetAcknowledged = transfer.WriteEvaluationError(expression.c_str(), errorMessage.c_str());
- }
- }
- else
- {
- REPORT_INTERNAL_ERROR;
- }
- break;
- }
-
- // Send a firmware message, typically a response to a command that has been passed to DSF.
- // These responses can get quite long (e.g. responses to M20) so receive it into an OutputBuffer.
- case LinuxRequest::Message:
- {
- OutputBuffer *buf;
- if (OutputBuffer::Allocate(buf))
- {
- MessageType type;
- if (transfer.ReadMessage(type, buf))
- {
- // FIXME Push flag is not supported yet
- reprap.GetPlatform().Message(type, buf);
- }
- else
- {
- // Not enough memory for reading the whole message, try again later
- OutputBuffer::ReleaseAll(buf);
- packetAcknowledged = false;
- }
- }
- break;
- }
-
- // Macro file has been started
- case LinuxRequest::MacroStarted:
- {
- const GCodeChannel channel = transfer.ReadCodeChannel();
- if (channel.IsValid())
- {
- GCodeBuffer * const gb = reprap.GetGCodes().GetGCodeBuffer(channel);
- if (gb->IsWaitingForMacro() && !gb->IsMacroRequestPending())
- {
- // File exists and is open, but no code has arrived yet
- gb->ResolveMacroRequest(false, false);
-#ifdef TRACK_FILE_CODES
- if (channel == GCodeChannel::File)
- {
- fileMacrosRunning++;
- }
-#endif
- }
- else if (channel != GCodeChannel::Daemon)
- {
- reprap.GetPlatform().MessageF(WarningMessage, "Macro file has been started on channel %s but none was requested\n", channel.ToString());
- }
- else
- {
- // dameon.g is running, now the OM may report the file is being executed
- reprap.InputsUpdated();
- }
- }
- else
- {
- REPORT_INTERNAL_ERROR;
- }
- break;
- }
-
- // Invalidate all files and codes on a given channel
- case LinuxRequest::InvalidateChannel:
- {
- const GCodeChannel channel = transfer.ReadCodeChannel();
- if (channel.IsValid())
- {
- GCodeBuffer * const gb = reprap.GetGCodes().GetGCodeBuffer(channel);
- if (gb->IsWaitingForMacro())
- {
- gb->ResolveMacroRequest(true, false);
- }
-
- MutexLocker locker(gb->mutex, LinuxYieldTimeout);
- if (locker.IsAcquired())
- {
- // Note that we do not call StopPrint here or set any other variables; DSF already does that
- gb->AbortFile(true, false);
- InvalidateBufferedCodes(channel);
- }
- else
- {
- packetAcknowledged = false;
- }
- }
- else
- {
- REPORT_INTERNAL_ERROR;
- }
- break;
- }
-
- // Set the content of a variable
- case LinuxRequest::SetVariable:
- {
- bool createVariable;
- String<MaxVariableNameLength> varName;
- String<GCODE_LENGTH> expression;
- const GCodeChannel channel = transfer.ReadSetVariable(createVariable, varName.GetRef(), expression.GetRef());
-
- // Make sure we can access the gb safely...
- if (!channel.IsValid())
- {
- REPORT_INTERNAL_ERROR;
- break;
- }
-
- GCodeBuffer * const gb = reprap.GetGCodes().GetGCodeBuffer(channel);
- MutexLocker lock(gb->mutex, LinuxYieldTimeout);
- if (!lock.IsAcquired())
- {
- packetAcknowledged = false;
- break;
- }
-
- // Get the variable set
- const bool isGlobal = StringStartsWith(varName.c_str(), "global.");
- if (!isGlobal && !StringStartsWith(varName.c_str(), "var."))
- {
- packetAcknowledged = transfer.WriteSetVariableError(varName.c_str(), "expected a global or local variable");
- break;
- }
- WriteLockedPointer<VariableSet> vset = (isGlobal) ? reprap.GetGlobalVariablesForWriting() : WriteLockedPointer<VariableSet>(nullptr, &gb->GetVariables());
-
- // Check if the variable is valid
- const char *shortVarName = varName.c_str() + strlen(isGlobal ? "global." : "var.");
- Variable * const v = vset->Lookup(shortVarName);
- if (createVariable && v != nullptr)
- {
- // For now we don't allow an existing variable to be reassigned using a 'var' or 'global' statement. We may need to allow it for 'global' statements.
- // Save memory by re-using 'expression' to capture the error message
- expression.printf("variable '%s' already exists", varName.c_str());
- packetAcknowledged = transfer.WriteSetVariableError(varName.c_str(), expression.c_str());
- break;
- }
- if (!createVariable && v == nullptr)
- {
- // Save memory by re-using 'expression' to capture the error message
- expression.printf("unknown variable '%s'", varName.c_str());
- packetAcknowledged = transfer.WriteSetVariableError(varName.c_str(), expression.c_str());
- break;
- }
-
- // Evaluate the expression and assign it
- try
- {
- ExpressionParser parser(*gb, expression.c_str(), expression.c_str() + expression.strlen());
- ExpressionValue ev = parser.Parse();
- if (v == nullptr)
- {
- // DSF doesn't provide indent values but instructs RRF to delete local variables when the current block ends
- vset->InsertNew(shortVarName, ev, 0);
- }
- else
- {
- v->Assign(ev);
- }
-
- transfer.WriteSetVariableResult(varName.c_str(), ev);
- if (isGlobal)
- {
- reprap.GlobalUpdated();
- }
- }
- catch (const GCodeException& e)
- {
- // Get the error message and send it back to DSF
- // Save memory by re-using 'expression' to capture the error message
- e.GetMessage(expression.GetRef(), nullptr);
- packetAcknowledged = transfer.WriteSetVariableError(varName.c_str(), expression.c_str());
- }
- break;
- }
-
- // Delete a local variable
- case LinuxRequest::DeleteLocalVariable:
- {
- String<MaxVariableNameLength> varName;
- const GCodeChannel channel = transfer.ReadDeleteLocalVariable(varName.GetRef());
-
- // Make sure we can access the gb safely...
- if (!channel.IsValid())
- {
- REPORT_INTERNAL_ERROR;
- break;
- }
-
- GCodeBuffer * const gb = reprap.GetGCodes().GetGCodeBuffer(channel);
- MutexLocker lock(gb->mutex, LinuxYieldTimeout);
- if (!lock.IsAcquired())
- {
- packetAcknowledged = false;
- break;
- }
-
- // Try to delete the variable again
- WriteLockedPointer<VariableSet> vset = WriteLockedPointer<VariableSet>(nullptr, &gb->GetVariables());
- vset.Ptr()->Delete(varName.c_str());
- break;
- }
-
- // Result of a file exists check
- case LinuxRequest::CheckFileExistsResult:
- if (fileOperation == FileOperation::checkFileExists)
- {
- fileSuccess = transfer.ReadBoolean();
- fileOperation = FileOperation::none;
- fileSemaphore.Give();
- }
- else
- {
- REPORT_INTERNAL_ERROR;
- }
- break;
-
-
- // Result of a deletion request
- case LinuxRequest::FileDeleteResult:
- if (fileOperation == FileOperation::deleteFileOrDirectory)
- {
- fileSuccess = transfer.ReadBoolean();
- fileOperation = FileOperation::none;
- fileSemaphore.Give();
- }
- else
- {
- REPORT_INTERNAL_ERROR;
- }
- break;
-
- // Result of a file open request
- case LinuxRequest::OpenFileResult:
- if (fileOperation == FileOperation::openRead ||
- fileOperation == FileOperation::openWrite ||
- fileOperation == FileOperation::openAppend)
- {
- fileHandle = transfer.ReadOpenFileResult(fileOffset);
- fileSuccess = (fileHandle != noFileHandle);
- fileOperation = FileOperation::none;
- fileSemaphore.Give();
- }
- else
- {
- REPORT_INTERNAL_ERROR;
- }
- break;
-
- // Result of a file read request
- case LinuxRequest::FileReadResult:
- if (fileOperation == FileOperation::read)
- {
- int bytesRead = transfer.ReadFileData(fileReadBuffer, fileBufferLength);
- fileSuccess = bytesRead >= 0;
- fileOffset = fileSuccess ? bytesRead : 0;
- fileOperation = FileOperation::none;
- fileSemaphore.Give();
- }
- else
- {
- REPORT_INTERNAL_ERROR;
- }
- break;
-
- // Result of a file write request
- case LinuxRequest::FileWriteResult:
- if (fileOperation == FileOperation::write)
- {
- fileSuccess = transfer.ReadBoolean();
- if (!fileSuccess || fileBufferLength == 0)
- {
- fileOperationPending = false;
- fileOperation = FileOperation::none;
- fileSemaphore.Give();
- }
- }
- else
- {
- REPORT_INTERNAL_ERROR;
- }
- break;
-
- // Result of a file seek request
- case LinuxRequest::FileSeekResult:
- if (fileOperation == FileOperation::seek)
- {
- fileSuccess = transfer.ReadBoolean();
- fileOperation = FileOperation::none;
- fileSemaphore.Give();
- }
- else
- {
- REPORT_INTERNAL_ERROR;
- }
- break;
-
- // Result of a file seek request
- case LinuxRequest::FileTruncateResult:
- if (fileOperation == FileOperation::truncate)
- {
- fileSuccess = transfer.ReadBoolean();
- fileOperation = FileOperation::none;
- fileSemaphore.Give();
- }
- else
- {
- REPORT_INTERNAL_ERROR;
- }
- break;
-
- // Invalid request
- default:
- REPORT_INTERNAL_ERROR;
- break;
- }
-
- // Request the packet again if no response could be sent back
- if (!packetAcknowledged)
- {
- transfer.ResendPacket(packet);
- }
- }
-
- if (!writingIap) // it's not safe to access other resources once we have started writing the IAP
- {
- // Check if we can wait a short moment to reduce CPU load on the SBC
- if (!skipNextDelay && numEvents < numMaxEvents && !waitingForFileChunk &&
- !fileOperationPending && fileOperation == FileOperation::none)
- {
- delaying = true;
- if (!TaskBase::Take(MassStorage::AnyFileOpen() ? maxFileOpenDelay : maxDelayBetweenTransfers))
- {
- delaying = false;
- }
- }
- numEvents = 0;
- skipNextDelay = false;
-
- // Send code replies and generic messages
- if (!gcodeReply.IsEmpty())
- {
- MutexLocker lock(gcodeReplyMutex);
- while (!gcodeReply.IsEmpty())
- {
- const MessageType type = gcodeReply.GetFirstItemType();
- OutputBuffer *buffer = gcodeReply.GetFirstItem(); // this may be null
- if (!transfer.WriteCodeReply(type, buffer)) // this handles the null case too
- {
- break;
- }
- gcodeReply.SetFirstItem(buffer); // this does a pop if buffer is null
- }
- }
-
- // Notify DSF about the available buffer space
- if (!codeBufferAvailable || sendBufferUpdate)
- {
- TaskCriticalSectionLocker locker;
-
- const uint16_t bufferSpace = (txEnd == 0) ? max<uint16_t>(rxPointer, SpiCodeBufferSize - txPointer) : rxPointer - txPointer;
- sendBufferUpdate = !transfer.WriteCodeBufferUpdate(bufferSpace);
- }
-
- // Get another chunk of the file being requested
- if (waitingForFileChunk &&
- !fileChunkRequestSent && transfer.WriteFileChunkRequest(requestedFileName.c_str(), requestedFileOffset, requestedFileLength))
- {
- fileChunkRequestSent = true;
- }
-
- // Perform the next file operation if requested
- if (fileOperationPending)
- {
- switch (fileOperation)
- {
- case FileOperation::checkFileExists:
- fileOperationPending = !transfer.WriteCheckFileExists(filePath);
- break;
-
- case FileOperation::deleteFileOrDirectory:
- fileOperationPending = !transfer.WriteDeleteFileOrDirectory(filePath);
- break;
-
- case FileOperation::openRead:
- case FileOperation::openWrite:
- case FileOperation::openAppend:
- fileOperationPending = !transfer.WriteOpenFile(filePath, fileOperation == FileOperation::openWrite || fileOperation == FileOperation::openAppend, fileOperation == FileOperation::openAppend, filePreAllocSize);
- break;
-
- case FileOperation::read:
- fileOperationPending = !transfer.WriteReadFile(fileHandle, fileBufferLength);
- break;
-
- case FileOperation::write:
- {
- size_t bytesNotWritten = fileBufferLength;
- if (transfer.WriteFileData(fileHandle, fileWriteBuffer, fileBufferLength))
- {
- fileWriteBuffer += bytesNotWritten - fileBufferLength;
- if (fileBufferLength == 0)
- {
- fileOperationPending = false;
- }
- }
- break;
- }
-
- case FileOperation::seek:
- fileOperationPending = !transfer.WriteSeekFile(fileHandle, fileOffset);
- break;
-
- case FileOperation::truncate:
- fileOperationPending = !transfer.WriteTruncateFile(fileHandle);
- break;
-
- case FileOperation::close:
- fileOperationPending = !transfer.WriteCloseFile(fileHandle);
- if (!fileOperationPending)
- {
- // Close requests don't get a result back, so they can be resolved as soon as they are sent to the SBC
- fileOperation = FileOperation::none;
- fileSemaphore.Give();
- }
- break;
-
- default:
- REPORT_INTERNAL_ERROR;
- break;
- }
- }
-
- // Deal with code channel requests
- for (size_t i = 0; i < NumGCodeChannels; i++)
- {
- const GCodeChannel channel(i);
- GCodeBuffer * const gb = reprap.GetGCodes().GetGCodeBuffer(channel);
-
- // Invalidate buffered codes if required
- if (gb->IsInvalidated())
- {
- InvalidateBufferedCodes(gb->GetChannel());
- gb->Invalidate(false);
- }
-
- // Deal with macro files being closed
- if (gb->IsMacroFileClosed() && transfer.WriteMacroFileClosed(channel))
- {
- // Note this is only sent when a macro file has finished successfully
- gb->MacroFileClosedSent();
- }
-
- // Handle blocking macro requests
- if (gb->IsWaitingForMacro() && gb->IsMacroRequestPending())
- {
- const char * const requestedMacroFile = gb->GetRequestedMacroFile();
- bool fromCode = gb->IsMacroStartedByCode();
- if (transfer.WriteMacroRequest(channel, requestedMacroFile, fromCode))
- {
- if (reprap.Debug(moduleLinuxInterface))
- {
- debugPrintf("Requesting macro file '%s' (fromCode: %s)\n", requestedMacroFile, fromCode ? "true" : "false");
- }
- gb->MacroRequestSent();
- gb->Invalidate();
- }
- }
-
- // Deal with other requests unless we are still waiting in a semaphore
- if (!gb->IsWaitingForMacro())
- {
- MutexLocker gbLock(gb->mutex, LinuxYieldTimeout);
- if (gbLock.IsAcquired())
- {
- if (gb->GetChannel() != GCodeChannel::Daemon)
- {
- skipNextDelay |= gb->IsMacroRequestPending() || gb->HasJustStartedMacro();
- }
-
- // Handle file abort requests
- if (gb->IsAbortRequested() && transfer.WriteAbortFileRequest(channel, gb->IsAbortAllRequested()))
- {
-#ifdef TRACK_FILE_CODES
- if (channel == GCodeChannel::File)
- {
- if (gb->IsAbortAllRequested())
- {
- fileCodesRead = fileCodesHandled = fileMacrosRunning = fileMacrosClosing = 0;
- }
- else
- {
- fileMacrosClosing++;
- }
- }
-#endif
- gb->FileAbortSent();
- gb->Invalidate();
- }
-
- // Handle blocking messages and their results
- if (gb->LatestMachineState().waitingForAcknowledgement && gb->IsMessagePromptPending() &&
- transfer.WriteWaitForAcknowledgement(channel))
- {
- gb->MessagePromptSent();
- gb->Invalidate();
- }
- else if (gb->IsMessageAcknowledged() && transfer.WriteMessageAcknowledged(channel))
- {
- // Note this is only sent when a message was acknowledged in a regular way (i.e. by M292)
- gb->MessageAcknowledgementSent();
- }
-
- // Handle non-blocking macro requests (e.g. daemon.g)
- if (gb->IsMacroRequestPending())
- {
- const char * const requestedMacroFile = gb->GetRequestedMacroFile();
- bool fromCode = gb->IsMacroStartedByCode();
- if (transfer.WriteMacroRequest(channel, requestedMacroFile, fromCode))
- {
- if (reprap.Debug(moduleLinuxInterface))
- {
- debugPrintf("Requesting non-blocking macro file '%s' (fromCode: %s)\n", requestedMacroFile, fromCode ? "true" : "false");
- }
- gb->MacroRequestSent();
- gb->Invalidate();
- }
- }
-
- // Send pending firmware codes
- if (gb->IsSendRequested() && transfer.WriteDoCode(channel, gb->DataStart(), gb->DataLength()))
- {
- gb->SetFinished(true);
- }
- }
- }
- }
-
- // Send pause notification on demand
- if (reportPause && transfer.WritePrintPaused(pauseFilePosition, pauseReason))
- {
- reportPause = false;
- }
- }
-
- // Start the next transfer and wait for it to complete
- transfer.StartNextTransfer();
- }
- else if (!writingIap)
- {
- if (isConnected && (!transfer.IsConnected() || hadReset))
- {
- isConnected = false;
- numDisconnects++;
- if (!hadReset)
- {
- numTimeouts++;
- }
- reprap.GetPlatform().Message(NetworkInfoMessage, "Lost connection to Linux\n");
-
- rxPointer = txPointer = txEnd = 0;
- sendBufferUpdate = true;
- iapWritePointer = IAP_IMAGE_START;
-
- if (!requestedFileName.IsEmpty())
- {
- requestedFileDataLength = -1;
- requestedFileSemaphore.Give();
- }
-
- if (fileOperation != FileOperation::none)
- {
- fileOperation = FileOperation::none;
- fileSemaphore.Give();
- }
- MassStorage::InvalidateAllFiles();
-
- // Don't cache any messages if they cannot be sent
- {
- MutexLocker lock(gcodeReplyMutex);
- gcodeReply.ReleaseAll();
- }
-
- // Close all open G-code files
- for (size_t i = 0; i < NumGCodeChannels; i++)
- {
- GCodeBuffer *gb = reprap.GetGCodes().GetGCodeBuffer(GCodeChannel(i));
- if (gb->IsWaitingForMacro())
- {
- gb->ResolveMacroRequest(true, false);
- }
-
- MutexLocker locker(gb->mutex);
- if (gb->IsMacroRequestPending())
- {
- gb->MacroRequestSent();
- }
- gb->AbortFile(true, false);
- gb->MessageAcknowledged(true);
- }
-
- // Abort the print (if applicable)
- printAborted = true;
-
- // Turn off all the heaters
- reprap.GetHeat().SwitchOffAll(true);
-
- // Reset the SPI connection
- transfer.ResetConnection();
-
- if (hadReset)
- {
- // Let the main task invalidate resources
- TaskBase::Take(LinuxYieldTimeout);
- }
- }
- else if (isConnected || transfer.IsConnected())
- {
- // Wait for the next SPI transaction to complete or for a timeout to occur
- TaskBase::Take(SpiConnectionTimeout);
- }
- else
- {
- // Wait indefinitely for the next transfer
- TaskBase::Take();
- }
- }
- }
-}
-
-void LinuxInterface::Diagnostics(MessageType mtype) noexcept
-{
- reprap.GetPlatform().Message(mtype, "=== SBC interface ===\n");
- transfer.Diagnostics(mtype);
- reprap.GetPlatform().MessageF(mtype, "Disconnects: %" PRIu32 ", timeouts: %" PRIu32 ", IAP RAM available 0x%05" PRIx32 "\n", numDisconnects, numTimeouts, iapRamAvailable);
- reprap.GetPlatform().MessageF(mtype, "Buffer RX/TX: %d/%d-%d\n", (int)rxPointer, (int)txPointer, (int)txEnd);
-#ifdef TRACK_FILE_CODES
- reprap.GetPlatform().MessageF(mtype, "File codes read/handled: %d/%d, file macros open/closing: %d %d\n", (int)fileCodesRead, (int)fileCodesHandled, (int)fileMacrosRunning, (int)fileMacrosClosing);
-#endif
-}
-
-GCodeResult LinuxInterface::HandleM576(GCodeBuffer& gb, const StringRef& reply) noexcept
-{
- bool seen = false;
-
- if (gb.Seen('S'))
- {
- uint32_t sParam = gb.GetUIValue();
- if (sParam > SpiConnectionTimeout)
- {
- reply.printf("SPI transfer delay must not exceed %" PRIu32 "ms", SpiConnectionTimeout);
- return GCodeResult::error;
- }
- maxDelayBetweenTransfers = sParam;
- seen = true;
- }
-
- if (gb.Seen('F'))
- {
- uint32_t fParam = gb.GetUIValue();
- if (fParam > SpiConnectionTimeout)
- {
- reply.printf("SPI transfer delay must not exceed %" PRIu32 "ms", SpiConnectionTimeout);
- return GCodeResult::error;
- }
- maxFileOpenDelay = fParam;
- seen = true;
- }
-
- if (gb.Seen('P'))
- {
- numMaxEvents = gb.GetUIValue();
- seen = true;
- }
-
- if (!seen)
- {
- reply.printf("Max transfer delay %" PRIu32 "ms, max number of events during delays: %" PRIu32, maxDelayBetweenTransfers, numMaxEvents);
- }
- return GCodeResult::ok;
-}
-
-bool LinuxInterface::FillBuffer(GCodeBuffer &gb) noexcept
-{
- if (gb.IsInvalidated() || gb.IsMacroFileClosed() || gb.IsMessageAcknowledged() ||
- gb.IsAbortRequested() || (reportPause && gb.GetChannel() == GCodeChannel::File) ||
- (gb.LatestMachineState().waitingForAcknowledgement && gb.IsMessagePromptPending()))
- {
- // Don't process codes that are supposed to be suspended...
- return false;
- }
-
- bool gotCommand = false;
- {
- //TODO can we take the lock inside the loop body instead, if we re-read readPointer and writePointer after taking it?
- TaskCriticalSectionLocker locker;
- if (rxPointer != txPointer || txEnd != 0)
- {
- bool updateRxPointer = true;
- uint16_t readPointer = rxPointer;
- do
- {
- BufferedCodeHeader *bufHeader = reinterpret_cast<BufferedCodeHeader*>(codeBuffer + readPointer);
- readPointer += sizeof(BufferedCodeHeader);
- const CodeHeader *codeHeader = reinterpret_cast<const CodeHeader*>(codeBuffer + readPointer);
- readPointer += bufHeader->length;
-
- RRF_ASSERT(bufHeader->length > 0);
- RRF_ASSERT(readPointer <= SpiCodeBufferSize);
-
- if (bufHeader->isPending)
- {
- if (gb.GetChannel().RawValue() == codeHeader->channel)
- {
-#ifdef TRACK_FILE_CODES
- if (gb.GetChannel() == GCodeChannel::File && gb.GetCommandLetter() != 'Q')
- {
- fileMacrosRunning -= fileMacrosClosing;
- fileMacrosClosing = 0;
- if (fileCodesRead > fileCodesHandled + fileMacrosRunning)
- {
- // Note that we cannot use MessageF here because the task scheduler is suspended
- OutputBuffer *buf;
- if (OutputBuffer::Allocate(buf))
- {
- String<SHORT_GCODE_LENGTH> codeString;
- gb.PrintCommand(codeString.GetRef());
- buf->printf("Code %s did not return a code result, delta %d, running macros %d\n", codeString.c_str(), fileCodesRead - fileCodesHandled - fileMacrosRunning, fileMacrosRunning);
- gcodeReply.Push(buf, WarningMessage);
- }
- fileCodesRead = fileCodesHandled - fileMacrosRunning;
- }
- fileCodesRead++;
- }
-#endif
-
- // Process the next binary G-code
- gb.PutBinary(reinterpret_cast<const uint32_t *>(codeHeader), bufHeader->length / sizeof(uint32_t));
- bufHeader->isPending = false;
-
- // Check if we can reset the ring buffer pointers
- if (updateRxPointer)
- {
- sendBufferUpdate = true;
- if (readPointer == txPointer && txEnd == 0)
- {
- // Buffer completely read, reset RX/TX pointers
- rxPointer = txPointer = 0;
- }
- else if (readPointer == txEnd)
- {
- // Read last code before overlapping, restart from the beginning
- rxPointer = txEnd = 0;
- }
- else
- {
- // Code has been read, move on to the next one
- rxPointer = readPointer;
- }
- }
-
- gotCommand = true;
- break;
- }
- updateRxPointer = false;
- }
-
- if (readPointer == txEnd)
- {
- if (updateRxPointer)
- {
- // Skipped non-pending codes, restart from the beginning
- rxPointer = txEnd = 0;
- }
-
- // About to overlap, continue from the start
- readPointer = 0;
- }
- } while (readPointer != txPointer);
- }
- }
-
- if (gotCommand)
- {
- gb.DecodeCommand();
- return true;
- }
- return false;
-}
-
-bool LinuxInterface::FileExists(const char *filename) noexcept
-{
- // Don't do anything if the SBC is not connected
- if (!IsConnected())
- {
- return false;
- }
-
- // Set up the request content
- MutexLocker locker(fileMutex);
- filePath = filename;
- fileOperation = FileOperation::checkFileExists;
- fileOperationPending = true;
-
- // Let the SBC task process this request as quickly as possible
- if (delaying)
- {
- delaying = false;
- sbcTask->Give();
- }
- fileSemaphore.Take();
-
- // Return the result
- return fileSuccess;
-}
-
-bool LinuxInterface::DeleteFileOrDirectory(const char *fileOrDirectory) noexcept
-{
- // Don't do anything if the SBC is not connected
- if (!IsConnected())
- {
- return false;
- }
-
- // Set up the request content
- MutexLocker locker(fileMutex);
- filePath = fileOrDirectory;
- fileOperation = FileOperation::deleteFileOrDirectory;
- fileOperationPending = true;
-
- // Let the SBC task process this request as quickly as possible
- if (delaying)
- {
- delaying = false;
- sbcTask->Give();
- }
- fileSemaphore.Take();
-
- // Return the result
- return fileSuccess;
-}
-
-FileHandle LinuxInterface::OpenFile(const char *filename, OpenMode mode, FilePosition& fileLength, uint32_t preAllocSize) noexcept
-{
- // Don't do anything if the SBC is not connected
- if (!IsConnected())
- {
- return false;
- }
-
- // Set up the request content
- MutexLocker locker(fileMutex);
- filePath = filename;
- filePreAllocSize = preAllocSize;
- switch (mode)
- {
- case OpenMode::read:
- fileOperation = FileOperation::openRead;
- break;
-
- case OpenMode::write:
- case OpenMode::writeWithCrc:
- fileOperation = FileOperation::openWrite;
- break;
-
- case OpenMode::append:
- fileOperation = FileOperation::openAppend;
- break;
-
- default:
- filePath = nullptr;
- REPORT_INTERNAL_ERROR;
- break;
- }
- fileOperationPending = true;
-
- // Let the SBC task process this request as quickly as possible
- if (delaying)
- {
- delaying = false;
- sbcTask->Give();
- }
- fileSemaphore.Take();
-
- // Update the file length and return the handle
- fileLength = fileOffset;
- return fileHandle;
-}
-
-int LinuxInterface::ReadFile(FileHandle handle, char *buffer, size_t bufferLength) noexcept
-{
- // Don't do anything if the SBC is not connected
- if (!IsConnected())
- {
- return false;
- }
-
- // Set up the request content
- MutexLocker locker(fileMutex);
- fileHandle = handle;
- fileReadBuffer = buffer;
- fileBufferLength = bufferLength;
- fileOperation = FileOperation::read;
- fileOperationPending = true;
-
- // Let the SBC task process this request as quickly as possible
- if (delaying)
- {
- delaying = false;
- sbcTask->Give();
- }
- fileSemaphore.Take();
-;
-
- // Return the number of bytes read
- return fileSuccess ? (int)fileOffset : -1;
-}
-
-bool LinuxInterface::WriteFile(FileHandle handle, const char *buffer, size_t bufferLength) noexcept
-{
- // Don't do anything if the SBC is not connected
- if (!IsConnected())
- {
- return false;
- }
-
- // Set up the request content
- MutexLocker locker(fileMutex);
- fileHandle = handle;
- fileWriteBuffer = buffer;
- fileBufferLength = bufferLength;
- fileOperation = FileOperation::write;
- fileOperationPending = true;
-
- // Let the SBC task process this request as quickly as possible
- if (delaying)
- {
- delaying = false;
- sbcTask->Give();
- }
- fileSemaphore.Take();
-
- // Return the result
- return fileSuccess;
-}
-
-bool LinuxInterface::SeekFile(FileHandle handle, FilePosition offset) noexcept
-{
- // Don't do anything if the SBC is not connected
- if (!IsConnected())
- {
- return false;
- }
-
- // Set up the request content
- MutexLocker locker(fileMutex);
- fileHandle = handle;
- fileOffset = offset;
- fileOperation = FileOperation::seek;
- fileOperationPending = true;
-
- // Let the SBC task process this request as quickly as possible
- if (delaying)
- {
- delaying = false;
- sbcTask->Give();
- }
- fileSemaphore.Take();
-
- // Return the result
- return fileSuccess;
-}
-
-bool LinuxInterface::TruncateFile(FileHandle handle) noexcept
-{
- // Don't do anything if the SBC is not connected
- if (!IsConnected())
- {
- return false;
- }
-
- // Set up the request content
- MutexLocker locker(fileMutex);
- fileHandle = handle;
- fileOperation = FileOperation::truncate;
- fileOperationPending = true;
-
- // Let the SBC task process this request as quickly as possible
- if (delaying)
- {
- delaying = false;
- sbcTask->Give();
- }
- fileSemaphore.Take();
-
- // Return the result
- return fileSuccess;
-}
-
-void LinuxInterface::CloseFile(FileHandle handle) noexcept
-{
- // Don't do anything if the SBC is not connected
- if (!IsConnected())
- {
- return;
- }
-
- // Set up the request content
- MutexLocker locker(fileMutex);
- fileHandle = handle;
- fileOperation = FileOperation::close;
- fileOperationPending = true;
-
- // Let the SBC task process this request as quickly as possible
- if (delaying)
- {
- delaying = false;
- sbcTask->Give();
- }
- fileSemaphore.Take();
-}
-
-void LinuxInterface::HandleGCodeReply(MessageType mt, const char *reply) noexcept
-{
- if (!IsConnected())
- {
- return;
- }
-
-#ifdef TRACK_FILE_CODES
- if ((mt & (1 << GCodeChannel::File)) != 0)
- {
- fileCodesHandled++;
- }
-#endif
-
- MutexLocker lock(gcodeReplyMutex);
- OutputBuffer *buffer = gcodeReply.GetLastItem();
- if (buffer != nullptr && mt == gcodeReply.GetLastItemType() && (mt & PushFlag) != 0 && !buffer->IsReferenced())
- {
- // Try to save some space by combining segments that have the Push flag set
- buffer->cat(reply);
- }
- else if (reply[0] != 0 && OutputBuffer::Allocate(buffer))
- {
- // Attempt to allocate one G-code buffer per non-empty output message
- buffer->cat(reply);
- gcodeReply.Push(buffer, mt);
- }
- else
- {
- // Store nullptr to indicate an empty response. This way many OutputBuffer references can be saved
- gcodeReply.Push(nullptr, mt);
- }
- EventOccurred();
-}
-
-void LinuxInterface::HandleGCodeReply(MessageType mt, OutputBuffer *buffer) noexcept
-{
- if (!IsConnected())
- {
- OutputBuffer::ReleaseAll(buffer);
- return;
- }
-
-#ifdef TRACK_FILE_CODES
- if ((mt & (1 << GCodeChannel::File)) != 0)
- {
- fileCodesHandled++;
- }
-#endif
-
- MutexLocker lock(gcodeReplyMutex);
- gcodeReply.Push(buffer, mt);
- EventOccurred();
-}
-
-// Read a file chunk from the SBC. When a response has been received, the current task is woken up again.
-// It changes bufferLength to the number of received bytes
-// This method returns true on success and false if an error occurred (e.g. file not found)
-bool LinuxInterface::GetFileChunk(const char *filename, uint32_t offset, char *buffer, uint32_t& bufferLength, uint32_t& fileLength) noexcept
-{
- if (waitingForFileChunk)
- {
- reprap.GetPlatform().Message(ErrorMessage, "Trying to request a file chunk from two independent tasks\n");
- bufferLength = fileLength = 0;
- return false;
- }
-
- fileChunkRequestSent = false;
- requestedFileName.copy(filename);
- requestedFileLength = bufferLength;
- requestedFileOffset = offset;
- requestedFileBuffer = buffer;
-
- waitingForFileChunk = true;
- requestedFileSemaphore.Take();
-
- waitingForFileChunk = false;
- if (requestedFileDataLength < 0)
- {
- bufferLength = fileLength = 0;
- return false;
- }
- bufferLength = requestedFileDataLength;
- fileLength = requestedFileLength;
- return true;
-}
-
-void LinuxInterface::EventOccurred(bool timeCritical) noexcept
-{
- if (!IsConnected())
- {
- return;
- }
-
- // Increment the number of events
- if (timeCritical)
- {
- numEvents = numMaxEvents;
- }
- else
- {
- numEvents++;
- }
-
- // Stop delaying if the next transfer is time-critical
- if (delaying && numEvents >= numMaxEvents)
- {
- delaying = false;
- sbcTask->Give();
- }
-}
-
-void LinuxInterface::InvalidateBufferedCodes(GCodeChannel channel) noexcept
-{
- TaskCriticalSectionLocker locker;
- if (rxPointer != txPointer || txEnd != 0)
- {
- bool updateRxPointer = true;
- uint16_t readPointer = rxPointer;
- do
- {
- BufferedCodeHeader *bufHeader = reinterpret_cast<BufferedCodeHeader *>(codeBuffer + readPointer);
- if (bufHeader->isPending)
- {
- const CodeHeader *codeHeader = reinterpret_cast<const CodeHeader*>(codeBuffer + readPointer + sizeof(BufferedCodeHeader));
- if (codeHeader->channel == channel.RawValue())
- {
- bufHeader->isPending = false;
- }
- else
- {
- updateRxPointer = false;
- }
- }
- readPointer += sizeof(BufferedCodeHeader) + bufHeader->length;
-
- if (updateRxPointer)
- {
- sendBufferUpdate = true;
- if (readPointer == txPointer && txEnd == 0)
- {
- // Buffer is empty again, reset the pointers
- rxPointer = txPointer = 0;
- break;
- }
- else if (readPointer == txEnd)
- {
- // Invalidated last code before overlapping, continue from the beginning
- readPointer = 0;
- rxPointer = txEnd = 0;
- }
- else
- {
- // Invalidated next code
- rxPointer = readPointer;
- }
- }
- else if (readPointer == txEnd)
- {
- // About to overlap, continue from the start
- readPointer = 0;
- }
- } while (readPointer != txPointer);
- }
-}
-
-#endif
diff --git a/src/Movement/BedProbing/Grid.cpp b/src/Movement/BedProbing/Grid.cpp
index b94b5744..45b81a92 100644
--- a/src/Movement/BedProbing/Grid.cpp
+++ b/src/Movement/BedProbing/Grid.cpp
@@ -527,7 +527,7 @@ bool HeightMap::LoadFromFile(FileStore *f, const char *fname, const StringRef& r
#endif
-#if HAS_LINUX_INTERFACE
+#if HAS_SBC_INTERFACE
// Update the filename
void HeightMap::SetFileName(const char *name) noexcept
diff --git a/src/Movement/BedProbing/Grid.h b/src/Movement/BedProbing/Grid.h
index aa4436c0..0bcafb16 100644
--- a/src/Movement/BedProbing/Grid.h
+++ b/src/Movement/BedProbing/Grid.h
@@ -87,11 +87,11 @@ public:
bool LoadFromFile(FileStore *f, const char *fname, const StringRef& r) noexcept; // Load the grid from file returning true if an error occurred
#endif
-#if HAS_MASS_STORAGE || HAS_LINUX_INTERFACE
+#if HAS_MASS_STORAGE || HAS_SBC_INTERFACE
const char *GetFileName() const noexcept { return fileName.c_str(); }
#endif
-#if HAS_LINUX_INTERFACE
+#if HAS_SBC_INTERFACE
void SetFileName(const char *name) noexcept; // Update the filename
void SaveToArray(float *array, float zOffset) const noexcept // Save the grid Z coordinates to an array
pre(IsValid());
@@ -112,7 +112,7 @@ private:
GridDefinition def;
float gridHeights[MaxGridProbePoints]; // The Z coordinates of the points on the bed that were probed
LargeBitmap<MaxGridProbePoints> gridHeightSet; // Bitmap of which heights are set
-#if HAS_MASS_STORAGE || HAS_LINUX_INTERFACE
+#if HAS_MASS_STORAGE || HAS_SBC_INTERFACE
String<MaxFilenameLength> fileName; // The name of the file that this height map was loaded from or saved to
#endif
bool useMap; // True to do bed compensation
diff --git a/src/Movement/Kinematics/HangprinterKinematics.cpp b/src/Movement/Kinematics/HangprinterKinematics.cpp
index ae211220..1c05fc27 100644
--- a/src/Movement/Kinematics/HangprinterKinematics.cpp
+++ b/src/Movement/Kinematics/HangprinterKinematics.cpp
@@ -437,7 +437,7 @@ AxesBitmap HangprinterKinematics::MustBeHomedAxes(AxesBitmap axesMoving, bool di
return axesMoving;
}
-#if HAS_MASS_STORAGE || HAS_LINUX_INTERFACE
+#if HAS_MASS_STORAGE || HAS_SBC_INTERFACE
// Write the parameters to a file, returning true if success
bool HangprinterKinematics::WriteCalibrationParameters(FileStore *f) const noexcept
diff --git a/src/Movement/Kinematics/HangprinterKinematics.h b/src/Movement/Kinematics/HangprinterKinematics.h
index 1a9587a9..751d39f9 100644
--- a/src/Movement/Kinematics/HangprinterKinematics.h
+++ b/src/Movement/Kinematics/HangprinterKinematics.h
@@ -24,7 +24,7 @@ public:
bool SupportsAutoCalibration() const noexcept override { return true; }
bool IsReachable(float axesCoords[MaxAxes], AxesBitmap axes) const noexcept override;
void SetCalibrationDefaults() noexcept override { Init(); }
-#if HAS_MASS_STORAGE || HAS_LINUX_INTERFACE
+#if HAS_MASS_STORAGE || HAS_SBC_INTERFACE
bool WriteCalibrationParameters(FileStore *f) const noexcept override;
#endif
LimitPositionResult LimitPosition(float finalCoords[], const float * null initialCoords, size_t numAxes, AxesBitmap axesToLimit, bool isCoordinated, bool applyM208Limits) const noexcept override;
@@ -37,7 +37,7 @@ public:
AxesBitmap GetHomingFileName(AxesBitmap toBeHomed, AxesBitmap alreadyHomed, size_t numVisibleAxes, const StringRef& filename) const noexcept override;
bool QueryTerminateHomingMove(size_t axis) const noexcept override;
void OnHomingSwitchTriggered(size_t axis, bool highEnd, const float stepsPerMm[], DDA& dda) const noexcept override;
-#if HAS_MASS_STORAGE || HAS_LINUX_INTERFACE
+#if HAS_MASS_STORAGE || HAS_SBC_INTERFACE
bool WriteResumeSettings(FileStore *f) const noexcept override;
#endif
#if DUAL_CAN
diff --git a/src/Movement/Kinematics/Kinematics.h b/src/Movement/Kinematics/Kinematics.h
index 5ef95b11..7f587662 100644
--- a/src/Movement/Kinematics/Kinematics.h
+++ b/src/Movement/Kinematics/Kinematics.h
@@ -124,7 +124,7 @@ public:
// Do nothing if auto calibration is not supported.
virtual void SetCalibrationDefaults() noexcept { }
-#if HAS_MASS_STORAGE || HAS_LINUX_INTERFACE
+#if HAS_MASS_STORAGE || HAS_SBC_INTERFACE
// Write the parameters that are set by auto calibration to the config-override.g file, returning true if success
// Just return true if auto calibration is not supported.
virtual bool WriteCalibrationParameters(FileStore *f) const noexcept { return true; }
@@ -186,7 +186,7 @@ public:
// This default is good for Cartesian and Core printers, but not deltas or SCARA
virtual AxesBitmap MustBeHomedAxes(AxesBitmap axesMoving, bool disallowMovesBeforeHoming) const noexcept { return (disallowMovesBeforeHoming) ? axesMoving : AxesBitmap(); }
-#if HAS_MASS_STORAGE || HAS_LINUX_INTERFACE
+#if HAS_MASS_STORAGE || HAS_SBC_INTERFACE
// Write any calibration data that we need to resume a print after power fail, returning true if successful. Override where necessary.
virtual bool WriteResumeSettings(FileStore *f) const noexcept { return true; }
#endif
diff --git a/src/Movement/Kinematics/LinearDeltaKinematics.cpp b/src/Movement/Kinematics/LinearDeltaKinematics.cpp
index e504f31e..13f951a5 100644
--- a/src/Movement/Kinematics/LinearDeltaKinematics.cpp
+++ b/src/Movement/Kinematics/LinearDeltaKinematics.cpp
@@ -785,7 +785,7 @@ void LinearDeltaKinematics::PrintParameters(const StringRef& reply) const noexce
(double)(xTilt * 100.0), (double)(yTilt * 100.0));
}
-#if HAS_MASS_STORAGE || HAS_LINUX_INTERFACE
+#if HAS_MASS_STORAGE || HAS_SBC_INTERFACE
// Write the parameters that are set by auto calibration to a file, returning true if success
bool LinearDeltaKinematics::WriteCalibrationParameters(FileStore *f) const noexcept
diff --git a/src/Movement/Kinematics/LinearDeltaKinematics.h b/src/Movement/Kinematics/LinearDeltaKinematics.h
index d0e9cdcd..f00d63de 100644
--- a/src/Movement/Kinematics/LinearDeltaKinematics.h
+++ b/src/Movement/Kinematics/LinearDeltaKinematics.h
@@ -27,7 +27,7 @@ public:
bool DoAutoCalibration(size_t numFactors, const RandomProbePointSet& probePoints, const StringRef& reply) noexcept override;
void SetCalibrationDefaults() noexcept override { Init(); }
-#if HAS_MASS_STORAGE || HAS_LINUX_INTERFACE
+#if HAS_MASS_STORAGE || HAS_SBC_INTERFACE
bool WriteCalibrationParameters(FileStore *f) const noexcept override;
#endif
@@ -44,7 +44,7 @@ public:
bool QueryTerminateHomingMove(size_t axis) const noexcept override;
void OnHomingSwitchTriggered(size_t axis, bool highEnd, const float stepsPerMm[], DDA& dda) const noexcept override;
-#if HAS_MASS_STORAGE || HAS_LINUX_INTERFACE
+#if HAS_MASS_STORAGE || HAS_SBC_INTERFACE
bool WriteResumeSettings(FileStore *f) const noexcept override;
#endif
diff --git a/src/Movement/Kinematics/RotaryDeltaKinematics.cpp b/src/Movement/Kinematics/RotaryDeltaKinematics.cpp
index 595304a0..6ec33dc4 100644
--- a/src/Movement/Kinematics/RotaryDeltaKinematics.cpp
+++ b/src/Movement/Kinematics/RotaryDeltaKinematics.cpp
@@ -560,7 +560,7 @@ void RotaryDeltaKinematics::PrintParameters(const StringRef& reply) const noexce
(double)angleCorrections[DELTA_A_AXIS], (double)angleCorrections[DELTA_B_AXIS], (double)angleCorrections[DELTA_C_AXIS]);
}
-#if HAS_MASS_STORAGE || HAS_LINUX_INTERFACE
+#if HAS_MASS_STORAGE || HAS_SBC_INTERFACE
// Add a space, character, and 3-element vector to the string
static void CatVector3(const StringRef& str, char c, const float vec[3]) noexcept
diff --git a/src/Movement/Kinematics/RotaryDeltaKinematics.h b/src/Movement/Kinematics/RotaryDeltaKinematics.h
index 807e301c..4b3de297 100644
--- a/src/Movement/Kinematics/RotaryDeltaKinematics.h
+++ b/src/Movement/Kinematics/RotaryDeltaKinematics.h
@@ -24,7 +24,7 @@ public:
bool SupportsAutoCalibration() const noexcept override { return true; }
bool DoAutoCalibration(size_t numFactors, const RandomProbePointSet& probePoints, const StringRef& reply) noexcept override;
void SetCalibrationDefaults() noexcept override { Init(); }
-#if HAS_MASS_STORAGE || HAS_LINUX_INTERFACE
+#if HAS_MASS_STORAGE || HAS_SBC_INTERFACE
bool WriteCalibrationParameters(FileStore *f) const noexcept override;
#endif
LimitPositionResult LimitPosition(float finalCoords[], const float * null initialCoords, size_t numVisibleAxes, AxesBitmap axesToLimit, bool isCoordinated, bool applyM208Limits) const noexcept override;
@@ -37,7 +37,7 @@ public:
AxesBitmap GetHomingFileName(AxesBitmap toBeHomed, AxesBitmap alreadyHomed, size_t numVisibleAxes, const StringRef& filename) const noexcept override;
bool QueryTerminateHomingMove(size_t axis) const noexcept override;
void OnHomingSwitchTriggered(size_t axis, bool highEnd, const float stepsPerMm[], DDA& dda) const noexcept override;
-#if HAS_MASS_STORAGE || HAS_LINUX_INTERFACE
+#if HAS_MASS_STORAGE || HAS_SBC_INTERFACE
bool WriteResumeSettings(FileStore *f) const noexcept override;
#endif
diff --git a/src/Movement/Kinematics/ZLeadscrewKinematics.cpp b/src/Movement/Kinematics/ZLeadscrewKinematics.cpp
index 63c2201c..1d56972a 100644
--- a/src/Movement/Kinematics/ZLeadscrewKinematics.cpp
+++ b/src/Movement/Kinematics/ZLeadscrewKinematics.cpp
@@ -421,7 +421,7 @@ void ZLeadscrewKinematics::AppendCorrections(const floatc_t corrections[], const
}
}
-#if HAS_MASS_STORAGE || HAS_LINUX_INTERFACE
+#if HAS_MASS_STORAGE || HAS_SBC_INTERFACE
// Write any calibration data that we need to resume a print after power fail, returning true if successful
bool ZLeadscrewKinematics::WriteResumeSettings(FileStore *f) const noexcept
diff --git a/src/Movement/Kinematics/ZLeadscrewKinematics.h b/src/Movement/Kinematics/ZLeadscrewKinematics.h
index 75d2a489..4864204b 100644
--- a/src/Movement/Kinematics/ZLeadscrewKinematics.h
+++ b/src/Movement/Kinematics/ZLeadscrewKinematics.h
@@ -20,7 +20,7 @@ public:
bool Configure(unsigned int mCode, GCodeBuffer& gb, const StringRef& reply, bool& error) THROWS(GCodeException) override;
bool SupportsAutoCalibration() const noexcept override;
bool DoAutoCalibration(size_t numFactors, const RandomProbePointSet& probePoints, const StringRef& reply) noexcept override;
-#if HAS_MASS_STORAGE || HAS_LINUX_INTERFACE
+#if HAS_MASS_STORAGE || HAS_SBC_INTERFACE
bool WriteResumeSettings(FileStore *f) const noexcept override;
#endif
diff --git a/src/Movement/Move.cpp b/src/Movement/Move.cpp
index e5645c72..04781a55 100644
--- a/src/Movement/Move.cpp
+++ b/src/Movement/Move.cpp
@@ -144,7 +144,7 @@ constexpr ObjectModelTableEntry Move::objectModelTable[] =
// 6. move.compensation members
{ "fadeHeight", OBJECT_MODEL_FUNC((self->useTaper) ? self->taperHeight : std::numeric_limits<float>::quiet_NaN(), 1), ObjectModelEntryFlags::none },
-#if HAS_MASS_STORAGE || HAS_LINUX_INTERFACE
+#if HAS_MASS_STORAGE || HAS_SBC_INTERFACE
{ "file", OBJECT_MODEL_FUNC_IF(self->usingMesh, self->heightMap.GetFileName()), ObjectModelEntryFlags::none },
#endif
{ "liveGrid", OBJECT_MODEL_FUNC_IF(self->usingMesh, (const GridDefinition *)&self->GetGrid()), ObjectModelEntryFlags::none },
@@ -179,7 +179,7 @@ constexpr uint8_t Move::objectModelTableDescriptor[] =
3,
2,
2,
- 6 + (HAS_MASS_STORAGE || HAS_LINUX_INTERFACE),
+ 6 + (HAS_MASS_STORAGE || HAS_SBC_INTERFACE),
2,
4,
#if SUPPORT_COORDINATE_ROTATION
@@ -773,7 +773,7 @@ bool Move::SaveHeightMapToFile(FileStore *f, const char *fname) noexcept
#endif
-#if HAS_LINUX_INTERFACE
+#if HAS_SBC_INTERFACE
// Save the height map Z coordinates to an array
void Move::SaveHeightMapToArray(float *arr) const noexcept
@@ -980,7 +980,7 @@ void Move::SetIdleTimeout(float timeout) noexcept
reprap.MoveUpdated();
}
-#if HAS_MASS_STORAGE || HAS_LINUX_INTERFACE
+#if HAS_MASS_STORAGE || HAS_SBC_INTERFACE
// Write settings for resuming the print
// The GCodes module deals with the head position so all we need worry about is the bed compensation
diff --git a/src/Movement/Move.h b/src/Movement/Move.h
index ce67c023..239e8ea6 100644
--- a/src/Movement/Move.h
+++ b/src/Movement/Move.h
@@ -152,7 +152,7 @@ public:
bool SaveHeightMapToFile(FileStore *f, const char *fname) noexcept; // Save the height map to a file returning true if an error occurred
#endif
-#if HAS_LINUX_INTERFACE
+#if HAS_SBC_INTERFACE
void SaveHeightMapToArray(float *arr) const noexcept; // Save the height map Z coordinates to an array
#endif
@@ -168,7 +168,7 @@ public:
int32_t GetAccumulatedExtrusion(size_t drive, bool& isPrinting) noexcept; // Return and reset the accumulated commanded extrusion amount
-#if HAS_MASS_STORAGE || HAS_LINUX_INTERFACE
+#if HAS_MASS_STORAGE || HAS_SBC_INTERFACE
bool WriteResumeSettings(FileStore *f) const noexcept; // Write settings for resuming the print
#endif
diff --git a/src/ObjectModel/ObjectModel.cpp b/src/ObjectModel/ObjectModel.cpp
index a8a42ff4..165431e4 100644
--- a/src/ObjectModel/ObjectModel.cpp
+++ b/src/ObjectModel/ObjectModel.cpp
@@ -747,7 +747,7 @@ void ObjectModel::ReportItemAsJsonFull(OutputBuffer *buf, ObjectExplorationConte
break;
case TypeCode::Special:
-#if HAS_MASS_STORAGE || HAS_EMBEDDED_FILES || HAS_LINUX_INTERFACE
+#if HAS_MASS_STORAGE || HAS_EMBEDDED_FILES || HAS_SBC_INTERFACE
switch ((ExpressionValue::SpecialType)val.param)
{
case ExpressionValue::SpecialType::sysDir:
diff --git a/src/Pins.h b/src/Pins.h
index a77449ec..efa33b99 100644
--- a/src/Pins.h
+++ b/src/Pins.h
@@ -169,8 +169,8 @@
# define SUPPORT_TELNET HAS_NETWORKING
#endif
-#ifndef HAS_LINUX_INTERFACE
-# define HAS_LINUX_INTERFACE 0
+#ifndef HAS_SBC_INTERFACE
+# define HAS_SBC_INTERFACE 0
#endif
#ifndef HAS_MASS_STORAGE
@@ -181,7 +181,7 @@
# define HAS_EMBEDDED_FILES 0
#endif
-#if !HAS_MASS_STORAGE && !HAS_LINUX_INTERFACE
+#if !HAS_MASS_STORAGE && !HAS_SBC_INTERFACE
# if SUPPORT_12864_LCD
# error "12864 LCD support requires mass storage or SBC interface"
# endif
diff --git a/src/Platform/MessageType.h b/src/Platform/MessageType.h
index d1062542..4823dbb7 100644
--- a/src/Platform/MessageType.h
+++ b/src/Platform/MessageType.h
@@ -10,7 +10,7 @@
#include <cstdint>
-// Supported message destinations. This is now a bitmap. Note that this type is used by the Linux service as well
+// Supported message destinations. This is now a bitmap. Note that this type is used by the SBC service as well
enum MessageType : uint32_t
{
// Destinations (bytes 1-2)
diff --git a/src/Platform/OutputMemory.cpp b/src/Platform/OutputMemory.cpp
index 39ffda41..801427a5 100644
--- a/src/Platform/OutputMemory.cpp
+++ b/src/Platform/OutputMemory.cpp
@@ -540,7 +540,7 @@ MessageType OutputStack::GetFirstItemType() const volatile noexcept
return (count == 0) ? MessageType::NoDestinationMessage : types[0];
}
-#if HAS_LINUX_INTERFACE
+#if HAS_SBC_INTERFACE
// Update the first item of the stack
void OutputStack::SetFirstItem(OutputBuffer *buffer) volatile noexcept
diff --git a/src/Platform/OutputMemory.h b/src/Platform/OutputMemory.h
index 3b15855c..b86bb84f 100644
--- a/src/Platform/OutputMemory.h
+++ b/src/Platform/OutputMemory.h
@@ -11,7 +11,7 @@
#include <RepRapFirmware.h>
#include <Storage/FileData.h>
-#if HAS_LINUX_INTERFACE
+#if HAS_SBC_INTERFACE
const size_t OUTPUT_STACK_DEPTH = 64; // Number of OutputBuffer chains that can be pushed onto one stack instance
#else
const size_t OUTPUT_STACK_DEPTH = 4; // Number of OutputBuffer chains that can be pushed onto one stack instance
@@ -144,7 +144,7 @@ public:
// Returns the first item's type from the stack or NoDestinationMessage if none is available
MessageType GetFirstItemType() const volatile noexcept;
-#if HAS_LINUX_INTERFACE
+#if HAS_SBC_INTERFACE
// Set the first item of the stack. If it's NULL, then the first item will be removed
void SetFirstItem(OutputBuffer *buffer) volatile noexcept;
#endif
diff --git a/src/Platform/Platform.cpp b/src/Platform/Platform.cpp
index 5be4b3c9..be34c04a 100644
--- a/src/Platform/Platform.cpp
+++ b/src/Platform/Platform.cpp
@@ -86,9 +86,9 @@ using AnalogIn::AdcBits; // for compatibility with CoreNG, which doesn't have
# include "PortControl.h"
#endif
-#if HAS_LINUX_INTERFACE
-# include "Linux/LinuxInterface.h"
-# include "Linux/DataTransfer.h"
+#if HAS_SBC_INTERFACE
+# include "SBC/SbcInterface.h"
+# include "SBC/DataTransfer.h"
#endif
#if HAS_NETWORKING
@@ -227,7 +227,7 @@ constexpr ObjectModelTableEntry Platform::objectModelTable[] =
{ "firmwareFileName", OBJECT_MODEL_FUNC_NOSELF(IAP_FIRMWARE_FILE), ObjectModelEntryFlags::none },
{ "firmwareName", OBJECT_MODEL_FUNC_NOSELF(FIRMWARE_NAME), ObjectModelEntryFlags::none },
{ "firmwareVersion", OBJECT_MODEL_FUNC_NOSELF(VERSION), ObjectModelEntryFlags::none },
-#if HAS_LINUX_INTERFACE
+#if HAS_SBC_INTERFACE
{ "iapFileNameSBC", OBJECT_MODEL_FUNC_NOSELF(IAP_UPDATE_FILE_SBC), ObjectModelEntryFlags::none },
#endif
#if HAS_MASS_STORAGE
@@ -342,7 +342,7 @@ constexpr ObjectModelTableEntry Platform::objectModelTable[] =
constexpr uint8_t Platform::objectModelTableDescriptor[] =
{
10, // number of sections
- 9 + SUPPORT_ACCELEROMETERS + HAS_LINUX_INTERFACE + HAS_MASS_STORAGE + HAS_VOLTAGE_MONITOR + HAS_12V_MONITOR + HAS_CPU_TEMP_SENSOR + SUPPORT_CAN_EXPANSION + SUPPORT_12864_LCD + MCU_HAS_UNIQUE_ID, // section 0: boards[0]
+ 9 + SUPPORT_ACCELEROMETERS + HAS_SBC_INTERFACE + HAS_MASS_STORAGE + HAS_VOLTAGE_MONITOR + HAS_12V_MONITOR + HAS_CPU_TEMP_SENSOR + SUPPORT_CAN_EXPANSION + SUPPORT_12864_LCD + MCU_HAS_UNIQUE_ID, // section 0: boards[0]
#if HAS_CPU_TEMP_SENSOR
3, // section 1: mcuTemp
#else
@@ -413,7 +413,7 @@ Platform::Platform() noexcept :
#if HAS_AUX_DEVICES
panelDueUpdater(nullptr),
#endif
-#if HAS_MASS_STORAGE || HAS_LINUX_INTERFACE || HAS_EMBEDDED_FILES
+#if HAS_MASS_STORAGE || HAS_SBC_INTERFACE || HAS_EMBEDDED_FILES
sysDir(nullptr),
#endif
tickState(0), debugCode(0),
@@ -500,7 +500,7 @@ void Platform::Init() noexcept
pinMode(SdCardDetectPins[i], INPUT_PULLUP);
}
-#if HAS_MASS_STORAGE || HAS_LINUX_INTERFACE || HAS_EMBEDDED_FILES
+#if HAS_MASS_STORAGE || HAS_SBC_INTERFACE || HAS_EMBEDDED_FILES
MassStorage::Init();
#endif
@@ -1022,7 +1022,7 @@ void Platform::Spin() noexcept
#endif
-#if HAS_MASS_STORAGE || HAS_LINUX_INTERFACE || HAS_EMBEDDED_FILES
+#if HAS_MASS_STORAGE || HAS_SBC_INTERFACE || HAS_EMBEDDED_FILES
MassStorage::Spin();
#endif
@@ -1472,8 +1472,8 @@ bool Platform::IsPowerOk() const noexcept
{
// FIXME Implement auto-save for the SBC
return ( !autoSaveEnabled
-#if HAS_LINUX_INTERFACE
- || reprap.UsingLinuxInterface()
+#if HAS_SBC_INTERFACE
+ || reprap.UsingSbcInterface()
#endif
)
|| currentVin > autoPauseReading;
@@ -2254,17 +2254,17 @@ GCodeResult Platform::DiagnosticTest(GCodeBuffer& gb, const StringRef& reply, Ou
case (unsigned int)DiagnosticTestType::PrintObjectAddresses:
MessageF(MessageType::GenericMessage,
"Platform %08" PRIx32 "-%08" PRIx32
-#if HAS_LINUX_INTERFACE
- "\nLinuxInterface %08" PRIx32 "-%08" PRIx32
+#if HAS_SBC_INTERFACE
+ "\nSbcInterface %08" PRIx32 "-%08" PRIx32
#endif
"\nNetwork %08" PRIx32 "-%08" PRIx32
"\nGCodes %08" PRIx32 "-%08" PRIx32
"\nMove %08" PRIx32 "-%08" PRIx32
"\nHeat %08" PRIx32 "-%08" PRIx32
, reinterpret_cast<uint32_t>(this), reinterpret_cast<uint32_t>(this) + sizeof(Platform) - 1
-#if HAS_LINUX_INTERFACE
- , reinterpret_cast<uint32_t>(&reprap.GetLinuxInterface())
- , (reinterpret_cast<uint32_t>(&reprap.GetLinuxInterface()) == 0) ? 0 : reinterpret_cast<uint32_t>(&reprap.GetLinuxInterface()) + sizeof(LinuxInterface)
+#if HAS_SBC_INTERFACE
+ , reinterpret_cast<uint32_t>(&reprap.GetSbcInterface())
+ , (reinterpret_cast<uint32_t>(&reprap.GetSbcInterface()) == 0) ? 0 : reinterpret_cast<uint32_t>(&reprap.GetSbcInterface()) + sizeof(SbcInterface)
#endif
, reinterpret_cast<uint32_t>(&reprap.GetNetwork()), reinterpret_cast<uint32_t>(&reprap.GetNetwork()) + sizeof(Network) - 1
, reinterpret_cast<uint32_t>(&reprap.GetGCodes()), reinterpret_cast<uint32_t>(&reprap.GetGCodes()) + sizeof(GCodes) - 1
@@ -2443,7 +2443,7 @@ int Platform::GetAveragingFilterIndex(const IoPort& port) const noexcept
return -1;
}
-#if HAS_MASS_STORAGE || HAS_LINUX_INTERFACE
+#if HAS_MASS_STORAGE || HAS_SBC_INTERFACE
// Write the platform parameters to file
bool Platform::WritePlatformParameters(FileStore *f, bool includingG31) const noexcept
@@ -3367,8 +3367,8 @@ void Platform::Message(const MessageType type, OutputBuffer *buffer) noexcept
{
++numDestinations;
}
-#if HAS_LINUX_INTERFACE
- if (reprap.UsingLinuxInterface() && ((type & GenericMessage) == GenericMessage || (type & BinaryCodeReplyFlag) != 0))
+#if HAS_SBC_INTERFACE
+ if (reprap.UsingSbcInterface() && ((type & GenericMessage) == GenericMessage || (type & BinaryCodeReplyFlag) != 0))
{
++numDestinations;
}
@@ -3413,10 +3413,10 @@ void Platform::Message(const MessageType type, OutputBuffer *buffer) noexcept
AppendUsbReply(buffer);
}
-#if HAS_LINUX_INTERFACE
- if (reprap.UsingLinuxInterface() && ((type & GenericMessage) == GenericMessage || (type & BinaryCodeReplyFlag) != 0))
+#if HAS_SBC_INTERFACE
+ if (reprap.UsingSbcInterface() && ((type & GenericMessage) == GenericMessage || (type & BinaryCodeReplyFlag) != 0))
{
- reprap.GetLinuxInterface().HandleGCodeReply(type, buffer);
+ reprap.GetSbcInterface().HandleGCodeReply(type, buffer);
}
#endif
}
@@ -3425,11 +3425,11 @@ void Platform::Message(const MessageType type, OutputBuffer *buffer) noexcept
void Platform::MessageF(MessageType type, const char *fmt, va_list vargs) noexcept
{
String<FormatStringLength> formatString;
-#if HAS_LINUX_INTERFACE
- if (reprap.UsingLinuxInterface() && ((type & GenericMessage) == GenericMessage || (type & BinaryCodeReplyFlag) != 0))
+#if HAS_SBC_INTERFACE
+ if (reprap.UsingSbcInterface() && ((type & GenericMessage) == GenericMessage || (type & BinaryCodeReplyFlag) != 0))
{
formatString.vprintf(fmt, vargs);
- reprap.GetLinuxInterface().HandleGCodeReply(type, formatString.c_str());
+ reprap.GetSbcInterface().HandleGCodeReply(type, formatString.c_str());
if ((type & BinaryCodeReplyFlag) != 0)
{
return;
@@ -3465,11 +3465,11 @@ void Platform::MessageF(MessageType type, const char *fmt, ...) noexcept
void Platform::Message(MessageType type, const char *message) noexcept
{
-#if HAS_LINUX_INTERFACE
- if (reprap.UsingLinuxInterface() &&
+#if HAS_SBC_INTERFACE
+ if (reprap.UsingSbcInterface() &&
((type & BinaryCodeReplyFlag) != 0 || (type & GenericMessage) == GenericMessage || (type & LogOff) != LogOff))
{
- reprap.GetLinuxInterface().HandleGCodeReply(type, message);
+ reprap.GetSbcInterface().HandleGCodeReply(type, message);
if ((type & BinaryCodeReplyFlag) != 0)
{
return;
@@ -3979,7 +3979,7 @@ bool Platform::IsDuetWiFi() const noexcept
#endif
-#if HAS_MASS_STORAGE || HAS_LINUX_INTERFACE
+#if HAS_MASS_STORAGE || HAS_SBC_INTERFACE
bool Platform::Delete(const char* folder, const char *filename) const noexcept
{
@@ -3995,7 +3995,7 @@ bool Platform::DeleteSysFile(const char *filename) const noexcept
#endif
-#if HAS_MASS_STORAGE || HAS_LINUX_INTERFACE || HAS_EMBEDDED_FILES
+#if HAS_MASS_STORAGE || HAS_SBC_INTERFACE || HAS_EMBEDDED_FILES
// Open a file
FileStore* Platform::OpenFile(const char* folder, const char* fileName, OpenMode mode, uint32_t preAllocSize) const noexcept
diff --git a/src/Platform/Platform.h b/src/Platform/Platform.h
index b6383a8b..a2246047 100644
--- a/src/Platform/Platform.h
+++ b/src/Platform/Platform.h
@@ -398,10 +398,10 @@ public:
#endif
// File functions
-#if HAS_MASS_STORAGE || HAS_LINUX_INTERFACE || HAS_EMBEDDED_FILES
+#if HAS_MASS_STORAGE || HAS_SBC_INTERFACE || HAS_EMBEDDED_FILES
FileStore* OpenFile(const char* folder, const char* fileName, OpenMode mode, uint32_t preAllocSize = 0) const noexcept;
bool FileExists(const char* folder, const char *filename) const noexcept;
-# if HAS_MASS_STORAGE || HAS_LINUX_INTERFACE
+# if HAS_MASS_STORAGE || HAS_SBC_INTERFACE
bool Delete(const char* folder, const char *filename) const noexcept;
#endif
@@ -413,7 +413,7 @@ public:
GCodeResult SetSysDir(const char* dir, const StringRef& reply) noexcept; // Set the system files path
bool SysFileExists(const char *filename) const noexcept;
FileStore* OpenSysFile(const char *filename, OpenMode mode) const noexcept;
-# if HAS_MASS_STORAGE || HAS_LINUX_INTERFACE
+# if HAS_MASS_STORAGE || HAS_SBC_INTERFACE
bool DeleteSysFile(const char *filename) const noexcept;
# endif
bool MakeSysFileName(const StringRef& result, const char *filename) const noexcept;
@@ -522,7 +522,7 @@ public:
const volatile ZProbeAveragingFilter& GetZProbeOnFilter() const noexcept { return zProbeOnFilter; }
const volatile ZProbeAveragingFilter& GetZProbeOffFilter() const noexcept{ return zProbeOffFilter; }
-#if HAS_MASS_STORAGE || HAS_LINUX_INTERFACE
+#if HAS_MASS_STORAGE || HAS_SBC_INTERFACE
bool WritePlatformParameters(FileStore *f, bool includingG31) const noexcept;
#endif
@@ -799,7 +799,7 @@ private:
float axisMinima[MaxAxes];
AxesBitmap axisMinimaProbed, axisMaximaProbed;
-#if HAS_MASS_STORAGE || HAS_LINUX_INTERFACE
+#if HAS_MASS_STORAGE || HAS_SBC_INTERFACE
static bool WriteAxisLimits(FileStore *f, AxesBitmap axesProbed, const float limits[MaxAxes], int sParam) noexcept;
#endif
@@ -819,7 +819,7 @@ private:
#endif
// Files
-#if HAS_MASS_STORAGE || HAS_LINUX_INTERFACE || HAS_EMBEDDED_FILES
+#if HAS_MASS_STORAGE || HAS_SBC_INTERFACE || HAS_EMBEDDED_FILES
const char *sysDir;
mutable ReadWriteLock sysDirLock;
#endif
@@ -891,7 +891,7 @@ private:
static bool deliberateError; // true if we deliberately caused an exception for testing purposes. Must be static in case of exception during startup.
};
-#if HAS_MASS_STORAGE || HAS_LINUX_INTERFACE || HAS_EMBEDDED_FILES
+#if HAS_MASS_STORAGE || HAS_SBC_INTERFACE || HAS_EMBEDDED_FILES
// Where the htm etc files are
inline const char* Platform::GetWebDir() const noexcept
diff --git a/src/Platform/RepRap.cpp b/src/Platform/RepRap.cpp
index 8761ac03..57bfca22 100644
--- a/src/Platform/RepRap.cpp
+++ b/src/Platform/RepRap.cpp
@@ -46,8 +46,8 @@
# include "Display/Display.h"
#endif
-#if HAS_LINUX_INTERFACE
-# include "Linux/LinuxInterface.h"
+#if HAS_SBC_INTERFACE
+# include "SBC/SbcInterface.h"
#endif
#ifdef DUET3_ATE
@@ -249,7 +249,7 @@ constexpr ObjectModelTableEntry RepRap::objectModelTable[] =
// Within each group, these entries must be in alphabetical order
// 0. MachineModel root
{ "boards", OBJECT_MODEL_FUNC_NOSELF(&boardsArrayDescriptor), ObjectModelEntryFlags::live },
-#if HAS_MASS_STORAGE || HAS_EMBEDDED_FILES || HAS_LINUX_INTERFACE
+#if HAS_MASS_STORAGE || HAS_EMBEDDED_FILES || HAS_SBC_INTERFACE
{ "directories", OBJECT_MODEL_FUNC(self, 1), ObjectModelEntryFlags::none },
#endif
{ "fans", OBJECT_MODEL_FUNC_NOSELF(&fansArrayDescriptor), ObjectModelEntryFlags::live },
@@ -272,7 +272,7 @@ constexpr ObjectModelTableEntry RepRap::objectModelTable[] =
{ "volumes", OBJECT_MODEL_FUNC_NOSELF(&volumesArrayDescriptor), ObjectModelEntryFlags::none },
// 1. MachineModel.directories
-#if HAS_MASS_STORAGE || HAS_EMBEDDED_FILES || HAS_LINUX_INTERFACE
+#if HAS_MASS_STORAGE || HAS_EMBEDDED_FILES || HAS_SBC_INTERFACE
{ "filaments", OBJECT_MODEL_FUNC_NOSELF(FILAMENTS_DIRECTORY), ObjectModelEntryFlags::verbose },
{ "firmware", OBJECT_MODEL_FUNC_NOSELF(FIRMWARE_DIRECTORY), ObjectModelEntryFlags::verbose },
{ "gCodes", OBJECT_MODEL_FUNC(self->platform->GetGCodeDir()), ObjectModelEntryFlags::verbose },
@@ -367,7 +367,7 @@ constexpr ObjectModelTableEntry RepRap::objectModelTable[] =
// 6. MachineModel.seqs
{ "boards", OBJECT_MODEL_FUNC((int32_t)self->boardsSeq), ObjectModelEntryFlags::live },
-#if HAS_MASS_STORAGE || HAS_EMBEDDED_FILES || HAS_LINUX_INTERFACE
+#if HAS_MASS_STORAGE || HAS_EMBEDDED_FILES || HAS_SBC_INTERFACE
{ "directories", OBJECT_MODEL_FUNC((int32_t)self->directoriesSeq), ObjectModelEntryFlags::live },
#endif
{ "fans", OBJECT_MODEL_FUNC((int32_t)self->fansSeq), ObjectModelEntryFlags::live },
@@ -398,8 +398,8 @@ constexpr ObjectModelTableEntry RepRap::objectModelTable[] =
constexpr uint8_t RepRap::objectModelTableDescriptor[] =
{
7, // number of sub-tables
- 15 + SUPPORT_SCANNER + (HAS_MASS_STORAGE | HAS_EMBEDDED_FILES | HAS_LINUX_INTERFACE), // root
-#if HAS_MASS_STORAGE || HAS_EMBEDDED_FILES || HAS_LINUX_INTERFACE
+ 15 + SUPPORT_SCANNER + (HAS_MASS_STORAGE | HAS_EMBEDDED_FILES | HAS_SBC_INTERFACE), // root
+#if HAS_MASS_STORAGE || HAS_EMBEDDED_FILES || HAS_SBC_INTERFACE
8, // directories
#else
0, // directories
@@ -409,7 +409,7 @@ constexpr uint8_t RepRap::objectModelTableDescriptor[] =
2, // state.beep
6, // state.messageBox
12 + HAS_NETWORKING + SUPPORT_SCANNER +
- 2 * HAS_MASS_STORAGE + (HAS_MASS_STORAGE | HAS_EMBEDDED_FILES | HAS_LINUX_INTERFACE) // seqs
+ 2 * HAS_MASS_STORAGE + (HAS_MASS_STORAGE | HAS_EMBEDDED_FILES | HAS_SBC_INTERFACE) // seqs
};
DEFINE_GET_OBJECT_MODEL_TABLE(RepRap)
@@ -432,8 +432,8 @@ RepRap::RepRap() noexcept
previousToolNumber(-1),
diagnosticsDestination(MessageType::NoDestinationMessage), justSentDiagnostics(false),
spinningModule(noModule), stopped(false), active(false), processingConfig(true)
-#if HAS_LINUX_INTERFACE
- , usingLinuxInterface(false) // default to not using the SBC interface until we have checked for config.g on an SD card,
+#if HAS_SBC_INTERFACE
+ , usingSbcInterface(false) // default to not using the SBC interface until we have checked for config.g on an SD card,
// because a disconnected SBC interface can generate noise which may trigger interrupts and DMA
#endif
{
@@ -473,8 +473,8 @@ void RepRap::Init() noexcept
{
OutputBuffer::Init();
platform = new Platform();
-#if HAS_LINUX_INTERFACE
- linuxInterface = new LinuxInterface(); // needs to be allocated early on Duet 2 so as to avoid using any of the last 64K of RAM
+#if HAS_SBC_INTERFACE
+ sbcInterface = new SbcInterface(); // needs to be allocated early on Duet 2 so as to avoid using any of the last 64K of RAM
#endif
network = new Network(*platform);
gCodes = new GCodes(*platform);
@@ -535,7 +535,7 @@ void RepRap::Init() noexcept
#ifdef DUET3_ATE
Duet3Ate::Init();
#endif
- // linuxInterface is not initialised until we know we are using it, to prevent a disconnected SBC interface generating interrupts and DMA
+ // sbcInterface is not initialised until we know we are using it, to prevent a disconnected SBC interface generating interrupts and DMA
// Set up the timeout of the regular watchdog, and set up the backup watchdog if there is one.
#if SAME5x
@@ -585,9 +585,9 @@ void RepRap::Init() noexcept
platform->MessageF(UsbMessage, "%s\n", VersionText);
-#if HAS_LINUX_INTERFACE && !HAS_MASS_STORAGE
- usingLinuxInterface = true;
- linuxInterface->Init();
+#if HAS_SBC_INTERFACE && !HAS_MASS_STORAGE
+ usingSbcInterface = true;
+ sbcInterface->Init();
FileWriteBuffer::UsingSbcMode();
#endif
@@ -611,10 +611,10 @@ void RepRap::Init() noexcept
platform->Message(AddWarning(UsbMessage), "no configuration file found\n");
}
}
-# if HAS_LINUX_INTERFACE
+# if HAS_SBC_INTERFACE
else if (!MassStorage::IsCardDetected(0)) // if we failed to mount the SD card because there was no card in the slot
{
- usingLinuxInterface = true;
+ usingSbcInterface = true;
FileWriteBuffer::UsingSbcMode();
}
# endif
@@ -623,17 +623,17 @@ void RepRap::Init() noexcept
delay(3000); // Wait a few seconds so users have a chance to see this
platform->MessageF(AddWarning(UsbMessage), "%s\n", reply.c_str());
}
-# if HAS_LINUX_INTERFACE
- linuxInterface->Init();
+# if HAS_SBC_INTERFACE
+ sbcInterface->Init();
# endif
}
#endif
-#if HAS_LINUX_INTERFACE
- if (usingLinuxInterface)
+#if HAS_SBC_INTERFACE
+ if (usingSbcInterface)
{
// Keep spinning until the SBC connects
- while (!linuxInterface->IsConnected())
+ while (!sbcInterface->IsConnected())
{
Spin();
}
@@ -763,13 +763,13 @@ void RepRap::Spin() noexcept
display->Spin();
#endif
-#if HAS_LINUX_INTERFACE
- // Keep the Linux task spinning from the main task in standalone mode to respond to a SBC if necessary
- if (!UsingLinuxInterface())
+#if HAS_SBC_INTERFACE
+ // Keep the SBC task spinning from the main task in standalone mode to respond to a SBC if necessary
+ if (!UsingSbcInterface())
{
ticksInSpinState = 0;
- spinningModule = moduleLinuxInterface;
- linuxInterface->Spin();
+ spinningModule = moduleSbcInterface;
+ sbcInterface->Spin();
}
#endif
@@ -874,7 +874,7 @@ void RepRap::Diagnostics(MessageType mtype) noexcept
#ifdef __LPC17xx__
" at %uMhz" // clock speed
#endif
-#if HAS_LINUX_INTERFACE || SUPPORT_REMOTE_COMMANDS
+#if HAS_SBC_INTERFACE || SUPPORT_REMOTE_COMMANDS
" (%s mode)" // standalone, SBC or expansion mode
#endif
"\n",
@@ -892,13 +892,13 @@ void RepRap::Diagnostics(MessageType mtype) noexcept
#ifdef __LPC17xx__
, (unsigned int)(SystemCoreClock/1000000)
#endif
-#if HAS_LINUX_INTERFACE || SUPPORT_REMOTE_COMMANDS
+#if HAS_SBC_INTERFACE || SUPPORT_REMOTE_COMMANDS
,
# if SUPPORT_REMOTE_COMMANDS
(CanInterface::InExpansionMode()) ? "expansion" :
# endif
-# if HAS_LINUX_INTERFACE
- (UsingLinuxInterface()) ? "SBC" :
+# if HAS_SBC_INTERFACE
+ (UsingSbcInterface()) ? "SBC" :
# endif
"standalone"
#endif
@@ -935,10 +935,10 @@ void RepRap::Diagnostics(MessageType mtype) noexcept
#if SUPPORT_CAN_EXPANSION
CanInterface::Diagnostics(mtype);
#endif
-#if HAS_LINUX_INTERFACE
- if (usingLinuxInterface)
+#if HAS_SBC_INTERFACE
+ if (usingSbcInterface)
{
- linuxInterface->Diagnostics(mtype);
+ sbcInterface->Diagnostics(mtype);
}
else
#endif
@@ -2511,7 +2511,7 @@ void RepRap::ClearAlert() noexcept
size_t RepRap::GetStatusIndex() const noexcept
{
return (processingConfig) ? 0 // Reading the configuration file
-#if HAS_LINUX_INTERFACE && SUPPORT_CAN_EXPANSION
+#if HAS_SBC_INTERFACE && SUPPORT_CAN_EXPANSION
: (gCodes->IsFlashing() || expansion->IsFlashing()) ? 1 // Flashing a new firmware binary
#else
: (gCodes->IsFlashing()) ? 1 // Flashing a new firmware binary
@@ -2654,7 +2654,7 @@ GCodeResult RepRap::ClearTemperatureFault(int8_t wasDudHeater, const StringRef&
return rslt;
}
-#if HAS_MASS_STORAGE || HAS_LINUX_INTERFACE
+#if HAS_MASS_STORAGE || HAS_SBC_INTERFACE
// Save some resume information, returning true if successful
// We assume that the tool configuration doesn't change, only the temperatures and the mix
diff --git a/src/Platform/RepRap.h b/src/Platform/RepRap.h
index e3c11e28..a136f253 100644
--- a/src/Platform/RepRap.h
+++ b/src/Platform/RepRap.h
@@ -126,9 +126,9 @@ public:
const char *GetLatestMessage(uint16_t& sequence) const noexcept;
const MessageBox& GetMessageBox() const noexcept { return mbox; }
#endif
-#if HAS_LINUX_INTERFACE
- bool UsingLinuxInterface() const noexcept { return usingLinuxInterface; }
- LinuxInterface& GetLinuxInterface() const noexcept { return *linuxInterface; }
+#if HAS_SBC_INTERFACE
+ bool UsingSbcInterface() const noexcept { return usingSbcInterface; }
+ SbcInterface& GetSbcInterface() const noexcept { return *sbcInterface; }
#endif
#if SUPPORT_CAN_EXPANSION
ExpansionManager& GetExpansion() const noexcept { return *expansion; }
@@ -161,7 +161,7 @@ public:
void SetAlert(const char *msg, const char *title, int mode, float timeout, AxesBitmap controls) noexcept;
void ClearAlert() noexcept;
-#if HAS_MASS_STORAGE || HAS_LINUX_INTERFACE
+#if HAS_MASS_STORAGE || HAS_SBC_INTERFACE
bool WriteToolSettings(FileStore *f) noexcept; // save some information for the resume file
bool WriteToolParameters(FileStore *f, const bool forceWriteOffsets) noexcept; // save some information in config-override.g
#endif
@@ -248,8 +248,8 @@ private:
Display *display;
#endif
-#if HAS_LINUX_INTERFACE
- LinuxInterface *linuxInterface;
+#if HAS_SBC_INTERFACE
+ SbcInterface *sbcInterface;
#endif
#if SUPPORT_ROLAND
@@ -304,8 +304,8 @@ private:
bool stopped;
bool active;
bool processingConfig;
-#if HAS_LINUX_INTERFACE
- bool usingLinuxInterface;
+#if HAS_SBC_INTERFACE
+ bool usingSbcInterface;
#endif
};
diff --git a/src/Platform/TaskPriorities.h b/src/Platform/TaskPriorities.h
index b3023c3f..7a876799 100644
--- a/src/Platform/TaskPriorities.h
+++ b/src/Platform/TaskPriorities.h
@@ -13,7 +13,7 @@ namespace TaskPriority
{
constexpr unsigned int IdlePriority = 0;
constexpr unsigned int SpinPriority = 1; // priority for tasks that rarely block
-#if HAS_LINUX_INTERFACE
+#if HAS_SBC_INTERFACE
constexpr unsigned int SbcPriority = 2; // priority for SBC task
#endif
#if defined(LPC_NETWORKING)
diff --git a/src/PrintMonitor/PrintMonitor.cpp b/src/PrintMonitor/PrintMonitor.cpp
index 96cbac0f..c2c39f53 100644
--- a/src/PrintMonitor/PrintMonitor.cpp
+++ b/src/PrintMonitor/PrintMonitor.cpp
@@ -179,8 +179,8 @@ void PrintMonitor::SetSlicerTimeLeft(float seconds) noexcept
void PrintMonitor::Spin() noexcept
{
-#if HAS_LINUX_INTERFACE
- if (reprap.UsingLinuxInterface())
+#if HAS_SBC_INTERFACE
+ if (reprap.UsingSbcInterface())
{
if (!printingFileParsed)
{
@@ -292,8 +292,8 @@ void PrintMonitor::StartingPrint(const char* filename) noexcept
#if HAS_MASS_STORAGE || HAS_EMBEDDED_FILES
WriteLocker locker(printMonitorLock);
MassStorage::CombineName(filenameBeingPrinted.GetRef(), platform.GetGCodeDir(), filename);
-# if HAS_LINUX_INTERFACE
- if (!reprap.UsingLinuxInterface())
+# if HAS_SBC_INTERFACE
+ if (!reprap.UsingSbcInterface())
# endif
{
printingFileParsed = false;
diff --git a/src/RepRapFirmware.cpp b/src/RepRapFirmware.cpp
index 98a390cf..d91de2e3 100644
--- a/src/RepRapFirmware.cpp
+++ b/src/RepRapFirmware.cpp
@@ -197,7 +197,7 @@ static const char * const moduleName[] =
"FilamentSensors",
"WiFi",
"Display",
- "LinuxInterface",
+ "SbcInterface",
"CAN",
"none"
};
diff --git a/src/RepRapFirmware.h b/src/RepRapFirmware.h
index 1575632e..48470852 100644
--- a/src/RepRapFirmware.h
+++ b/src/RepRapFirmware.h
@@ -270,7 +270,7 @@ enum Module : uint8_t
moduleFilamentSensors = 13,
moduleWiFi = 14,
moduleDisplay = 15,
- moduleLinuxInterface = 16,
+ moduleSbcInterface = 16,
moduleCan = 17,
numModules = 18, // make this one greater than the last real module number
noModule = numModules
@@ -310,8 +310,8 @@ class PortControl;
class Display;
#endif
-#if HAS_LINUX_INTERFACE
-class LinuxInterface;
+#if HAS_SBC_INTERFACE
+class SbcInterface;
#endif
#if SUPPORT_CAN_EXPANSION
@@ -566,7 +566,7 @@ constexpr size_t NumCoordinateSystems = 1;
#define DEGREE_SYMBOL "\xC2\xB0" // degree-symbol encoding in UTF8
-#if HAS_LINUX_INTERFACE
+#if HAS_SBC_INTERFACE
typedef uint32_t FileHandle;
const FileHandle noFileHandle = 0;
#endif
diff --git a/src/Linux/DataTransfer.cpp b/src/SBC/DataTransfer.cpp
index 06a3f3bb..53166c38 100644
--- a/src/Linux/DataTransfer.cpp
+++ b/src/SBC/DataTransfer.cpp
@@ -7,9 +7,9 @@
#include "DataTransfer.h"
-#if HAS_LINUX_INTERFACE
+#if HAS_SBC_INTERFACE
-#include "LinuxInterface.h"
+#include "SbcInterface.h"
#include <Storage/CRC32.h>
#include <algorithm>
@@ -69,7 +69,7 @@ constexpr IRQn SBC_SPI_IRQn = SbcSpiSercomIRQn;
#include <General/IP4String.h>
-static TaskHandle linuxTaskHandle = nullptr;
+static TaskHandle sbcTaskHandle = nullptr;
#if USE_DMAC
@@ -89,7 +89,10 @@ static xdmac_channel_config_t xdmac_tx_cfg, xdmac_rx_cfg;
#endif
-volatile bool dataReceived = false; // warning: on the SAME5x this just means the transfer has started, not necessarily that it has ended!
+volatile bool dataReceived = false; // warning: on the SAME5x this just means the transfer has started, not necessarily that it has ended!
+#if SAME5x
+uint32_t transferStartTime = 0;
+#endif
volatile bool transferReadyHigh = false;
volatile unsigned int spiTxUnderruns = 0, spiRxOverruns = 0;
@@ -112,7 +115,6 @@ static void spi_dma_disable() noexcept
}
#if !SAME5x
-
static bool spi_dma_check_rx_complete() noexcept
{
#if USE_DMAC
@@ -271,6 +273,18 @@ pre(bytesToTransfer <= inBuffer.limit; bytesToTransfer <= outBuffer.limit)
#endif
}
+void disable_spi() noexcept
+{
+ spi_dma_disable();
+
+#if SAME5x
+ SbcSpiSercom->SPI.CTRLA.reg &= ~SERCOM_SPI_CTRLA_ENABLE;
+ while (SbcSpiSercom->SPI.SYNCBUSY.reg & (SERCOM_SPI_SYNCBUSY_SWRST | SERCOM_SPI_SYNCBUSY_ENABLE)) { };
+#else
+ spi_disable(SBC_SPI);
+#endif
+}
+
static void setup_spi(void *inBuffer, const void *outBuffer, size_t bytesToTransfer) noexcept
pre(bytesToTransfer <= inBuffer.limit; bytesToTransfer <= outBuffer.limit)
{
@@ -322,22 +336,13 @@ pre(bytesToTransfer <= inBuffer.limit; bytesToTransfer <= outBuffer.limit)
NVIC_EnableIRQ(SBC_SPI_IRQn);
// Begin transfer
+#if SAME5x
+ transferStartTime = 0;
+#endif
transferReadyHigh = !transferReadyHigh;
digitalWrite(SbcTfrReadyPin, transferReadyHigh);
}
-void disable_spi() noexcept
-{
- spi_dma_disable();
-
- // Disable SPI
-#if SAME5x
- SbcSpiSercom->SPI.CTRLA.reg &= ~SERCOM_SPI_CTRLA_ENABLE;
- while (SbcSpiSercom->SPI.SYNCBUSY.reg & (SERCOM_SPI_SYNCBUSY_SWRST | SERCOM_SPI_SYNCBUSY_ENABLE)) { };
-#else
- spi_disable(SBC_SPI);
-#endif
-}
#ifndef SBC_SPI_HANDLER
# error SBC_SPI_HANDLER undefined
@@ -354,8 +359,9 @@ extern "C" void SBC_SPI_HANDLER() noexcept
SbcSpiSercom->SPI.INTENCLR.reg = SERCOM_SPI_INTENSET_SSL; // disable the interrupt
SbcSpiSercom->SPI.INTFLAG.reg = SERCOM_SPI_INTENSET_SSL; // clear the status
+ // Wake up the SBC task
dataReceived = true;
- TaskBase::GiveFromISR(linuxTaskHandle);
+ TaskBase::GiveFromISR(sbcTaskHandle);
}
#else
const uint32_t status = SBC_SPI->SPI_SR; // read status and clear interrupt
@@ -375,9 +381,9 @@ extern "C" void SBC_SPI_HANDLER() noexcept
++spiTxUnderruns;
}
- // Wake up the Linux task
+ // Wake up the SBC task
dataReceived = true;
- TaskBase::GiveFromISR(linuxTaskHandle);
+ TaskBase::GiveFromISR(sbcTaskHandle);
}
#endif
}
@@ -391,11 +397,11 @@ __nocache TransferHeader DataTransfer::rxHeader;
__nocache TransferHeader DataTransfer::txHeader;
__nocache uint32_t DataTransfer::rxResponse;
__nocache uint32_t DataTransfer::txResponse;
-alignas(4) __nocache char DataTransfer::rxBuffer[LinuxTransferBufferSize];
-alignas(4) __nocache char DataTransfer::txBuffer[LinuxTransferBufferSize];
+alignas(4) __nocache char DataTransfer::rxBuffer[SbcTransferBufferSize];
+alignas(4) __nocache char DataTransfer::txBuffer[SbcTransferBufferSize];
#endif
-DataTransfer::DataTransfer() noexcept : state(SpiState::ExchangingData), lastTransferTime(0), lastTransferNumber(0), failedTransfers(0), checksumErrors(0),
+DataTransfer::DataTransfer() noexcept : state(InternalTransferState::ExchangingData), lastTransferNumber(0), failedTransfers(0), checksumErrors(0),
#if SAME5x
rxBuffer(nullptr), txBuffer(nullptr),
#endif
@@ -408,8 +414,8 @@ DataTransfer::DataTransfer() noexcept : state(SpiState::ExchangingData), lastTra
rxHeader.sequenceNumber = 0;
// Prepare TX header
- txHeader.formatCode = LinuxFormatCode;
- txHeader.protocolVersion = LinuxProtocolVersion;
+ txHeader.formatCode = SbcFormatCode;
+ txHeader.protocolVersion = SbcProtocolVersion;
txHeader.numPackets = 0;
txHeader.sequenceNumber = 0;
}
@@ -420,16 +426,16 @@ void DataTransfer::Init() noexcept
pinMode(SbcTfrReadyPin, OUTPUT_LOW);
#if !SAME70
- if (reprap.UsingLinuxInterface())
+ if (reprap.UsingSbcInterface())
{
// Allocate buffers in SBC mode
- rxBuffer = (char *)new uint32_t[(LinuxTransferBufferSize + 3)/4];
- txBuffer = (char *)new uint32_t[(LinuxTransferBufferSize + 3)/4];
+ rxBuffer = (char *)new uint32_t[(SbcTransferBufferSize + 3)/4];
+ txBuffer = (char *)new uint32_t[(SbcTransferBufferSize + 3)/4];
}
else
{
// Only send back the TX header + response code in standalone mode indicating we're running in standalone mode
- txHeader.formatCode = LinuxFormatCodeStandalone;
+ txHeader.formatCode = SbcFormatCodeStandalone;
}
#endif
@@ -489,7 +495,7 @@ void DataTransfer::Init() noexcept
matrix_set_slave_slot_cycle(0, 8);
#endif
- if (!reprap.UsingLinuxInterface())
+ if (!reprap.UsingSbcInterface())
{
// Start off the first transfer in standalone mode
StartNextTransfer();
@@ -498,13 +504,12 @@ void DataTransfer::Init() noexcept
void DataTransfer::InitFromTask() noexcept
{
- linuxTaskHandle = TaskBase::GetCallerTaskHandle();
+ sbcTaskHandle = TaskBase::GetCallerTaskHandle();
}
void DataTransfer::Diagnostics(MessageType mtype) noexcept
{
- reprap.GetPlatform().MessageF(mtype, "State: %d, failed transfers: %u, checksum errors: %u\n", (int)state, failedTransfers, checksumErrors);
- reprap.GetPlatform().MessageF(mtype, "Last transfer: %" PRIu32 "ms ago\n", millis() - lastTransferTime);
+ reprap.GetPlatform().MessageF(mtype, "Transfer state: %d, failed transfers: %u, checksum errors: %u\n", (int)state, failedTransfers, checksumErrors);
reprap.GetPlatform().MessageF(mtype, "RX/TX seq numbers: %d/%d\n", (int)rxHeader.sequenceNumber, (int)txHeader.sequenceNumber);
reprap.GetPlatform().MessageF(mtype, "SPI underruns %u, overruns %u\n", spiTxUnderruns, spiRxOverruns);
}
@@ -736,7 +741,7 @@ int DataTransfer::ReadFileData(char *buffer, size_t length) noexcept
void DataTransfer::ExchangeHeader() noexcept
{
Cache::FlushBeforeDMASend(&txHeader, sizeof(txHeader));
- state = SpiState::ExchangingHeader;
+ state = InternalTransferState::ExchangingHeader;
setup_spi(&rxHeader, &txHeader, sizeof(TransferHeader));
}
@@ -744,7 +749,7 @@ void DataTransfer::ExchangeResponse(uint32_t response) noexcept
{
txResponse = response;
Cache::FlushBeforeDMASend(&txResponse, sizeof(txResponse));
- state = (state == SpiState::ExchangingHeader) ? SpiState::ExchangingHeaderResponse : SpiState::ExchangingDataResponse;
+ state = (state == InternalTransferState::ExchangingHeader) ? InternalTransferState::ExchangingHeaderResponse : InternalTransferState::ExchangingDataResponse;
setup_spi(&rxResponse, &txResponse, sizeof(uint32_t));
}
@@ -752,15 +757,15 @@ void DataTransfer::ExchangeData() noexcept
{
Cache::FlushBeforeDMASend(txBuffer, txHeader.dataLength);
size_t bytesToExchange = max<size_t>(rxHeader.dataLength, txHeader.dataLength);
- state = SpiState::ExchangingData;
+ state = InternalTransferState::ExchangingData;
setup_spi(rxBuffer, txBuffer, bytesToExchange);
}
-void DataTransfer::StatefulTransferReset(bool ownRequest) noexcept
+void DataTransfer::ResetTransfer(bool ownRequest) noexcept
{
- if (reprap.Debug(moduleLinuxInterface))
+ if (reprap.Debug(moduleSbcInterface))
{
- debugPrintf(ownRequest ? "Resetting transfer\n" : "Resetting transfer due to Linux request\n");
+ debugPrintf(ownRequest ? "Resetting transfer\n" : "Resetting transfer due to Sbc request\n");
}
if (ownRequest)
@@ -768,69 +773,67 @@ void DataTransfer::StatefulTransferReset(bool ownRequest) noexcept
// Invalidate the data to send
txResponse = TransferResponse::BadResponse;
Cache::FlushBeforeDMASend(&txResponse, sizeof(txResponse));
- state = SpiState::Resetting;
+ state = InternalTransferState::Resetting;
setup_spi(&rxResponse, &txResponse, sizeof(uint32_t));
}
else
{
- // Linux wants to reset the state
+ // Sbc wants to reset the state
ExchangeHeader();
}
}
-bool DataTransfer::IsReady() noexcept
+TransferState DataTransfer::DoTransfer() noexcept
{
if (dataReceived)
{
#if SAME5x
// Unfortunately the SAME5x doesn't have an end-of-transfer interrupt, but SPI transfers typically don't take long
- uint32_t startTime = millis();
- while (!digitalRead(SbcSSPin)) // transfer is complete if SS is high
+ if (!digitalRead(SbcSSPin)) // transfer is complete if SS is high
{
- if (millis() - startTime > SpiTransferTimeout)
+ if (transferStartTime == 0)
{
- disable_spi(); // disable the SPI subsystem first, else only zeros are transferred
- StatefulTransferReset(true);
- return false;
+ transferStartTime = millis();
+ return TransferState::finishingTransfer;
}
+ return (millis() - transferStartTime > SpiMaxTransferTime) ? TransferState::connectionTimeout : TransferState::finishingTransfer;
}
+ transferStartTime = 0;
if (SbcSpiSercom->SPI.STATUS.bit.BUFOVF)
{
++spiRxOverruns;
}
-
disable_spi();
#else
// Wait for the current XDMA transfer to finish. Relying on the XDMAC IRQ for this is does not work well...
if (!spi_dma_check_rx_complete())
{
- return false;
+ return TransferState::finishingTransfer;
}
#endif
// Transfer has finished
dataReceived = false;
- lastTransferTime = millis();
switch (state)
{
- case SpiState::ExchangingHeader:
+ case InternalTransferState::ExchangingHeader:
{
Cache::InvalidateAfterDMAReceive(&rxHeader, sizeof(rxHeader));
// (1) Exchanged transfer headers
const uint32_t headerResponse = *reinterpret_cast<const uint32_t*>(&rxHeader);
if (headerResponse == TransferResponse::BadResponse)
{
- // Linux wants to restart the transfer
- StatefulTransferReset(false);
+ // Sbc wants to restart the transfer
+ ResetTransfer(false);
break;
}
const uint32_t checksum = CalcCRC32(reinterpret_cast<const char *>(&rxHeader), sizeof(TransferHeader) - sizeof(uint32_t));
if (rxHeader.crcHeader != checksum)
{
- if (reprap.Debug(moduleLinuxInterface))
+ if (reprap.Debug(moduleSbcInterface))
{
debugPrintf("Bad header CRC (expected %08" PRIx32 ", got %08" PRIx32 ")\n", rxHeader.crcHeader, checksum);
}
@@ -838,17 +841,17 @@ bool DataTransfer::IsReady() noexcept
break;
}
- if (rxHeader.formatCode != LinuxFormatCode)
+ if (rxHeader.formatCode != SbcFormatCode)
{
ExchangeResponse(TransferResponse::BadFormat);
break;
}
- if (rxHeader.protocolVersion != LinuxProtocolVersion)
+ if (rxHeader.protocolVersion != SbcProtocolVersion)
{
ExchangeResponse(TransferResponse::BadProtocolVersion);
break;
}
- if (rxHeader.dataLength > LinuxTransferBufferSize)
+ if (rxHeader.dataLength > SbcTransferBufferSize)
{
ExchangeResponse(TransferResponse::BadDataLength);
break;
@@ -858,12 +861,12 @@ bool DataTransfer::IsReady() noexcept
break;
}
- case SpiState::ExchangingHeaderResponse:
+ case InternalTransferState::ExchangingHeaderResponse:
// (2) Exchanged response to transfer header
Cache::InvalidateAfterDMAReceive(&rxResponse, sizeof(rxResponse));
if (rxResponse == TransferResponse::Success && txResponse == TransferResponse::Success)
{
- if (reprap.UsingLinuxInterface() && (rxHeader.dataLength != 0 || txHeader.dataLength != 0))
+ if (reprap.UsingSbcInterface() && (rxHeader.dataLength != 0 || txHeader.dataLength != 0))
{
// Perform the actual data transfer
ExchangeData();
@@ -873,14 +876,14 @@ bool DataTransfer::IsReady() noexcept
// Everything OK
rxPointer = txPointer = 0;
packetId = 0;
- state = SpiState::ProcessingData;
- return true;
+ state = InternalTransferState::ProcessingData;
+ return IsConnectionReset() ? TransferState::connectionReset : TransferState::finished;
}
}
else if (rxResponse == TransferResponse::BadResponse)
{
- // Linux wants to restart the transfer
- StatefulTransferReset(false);
+ // Sbc wants to restart the transfer
+ ResetTransfer(false);
}
else if (rxResponse == TransferResponse::BadHeaderChecksum || txResponse == TransferResponse::BadHeaderChecksum)
{
@@ -891,19 +894,19 @@ bool DataTransfer::IsReady() noexcept
else
{
// Received invalid response code
- StatefulTransferReset(true);
+ ResetTransfer(true);
}
break;
- case SpiState::ExchangingData:
+ case InternalTransferState::ExchangingData:
{
Cache::InvalidateAfterDMAReceive(rxBuffer, rxHeader.dataLength);
// (3) Exchanged data
if (*reinterpret_cast<uint32_t*>(rxBuffer) == TransferResponse::BadResponse)
{
- if (reprap.Debug(moduleLinuxInterface))
+ if (reprap.Debug(moduleSbcInterface))
{
- debugPrintf("Resetting state due to Linux request\n");
+ debugPrintf("Resetting state due to Sbc request\n");
}
failedTransfers++;
ExchangeHeader();
@@ -913,7 +916,7 @@ bool DataTransfer::IsReady() noexcept
const uint32_t checksum = CalcCRC32(rxBuffer, rxHeader.dataLength);
if (rxHeader.crcData != checksum)
{
- if (reprap.Debug(moduleLinuxInterface))
+ if (reprap.Debug(moduleSbcInterface))
{
debugPrintf("Bad data CRC (expected %08" PRIx32 ", got %08" PRIx32 ")\n", rxHeader.crcData, checksum);
}
@@ -925,7 +928,7 @@ bool DataTransfer::IsReady() noexcept
break;
}
- case SpiState::ExchangingDataResponse:
+ case InternalTransferState::ExchangingDataResponse:
// (4) Exchanged response to data transfer
Cache::InvalidateAfterDMAReceive(&rxResponse, sizeof(rxResponse));
if (rxResponse == TransferResponse::Success && txResponse == TransferResponse::Success)
@@ -933,14 +936,14 @@ bool DataTransfer::IsReady() noexcept
// Everything OK
rxPointer = txPointer = 0;
packetId = 0;
- state = SpiState::ProcessingData;
- return true;
+ state = InternalTransferState::ProcessingData;
+ return IsConnectionReset() ? TransferState::connectionReset : TransferState::finished;
}
if (rxResponse == TransferResponse::BadResponse)
{
- // Linux wants to restart the transfer
- StatefulTransferReset(false);
+ // Sbc wants to restart the transfer
+ ResetTransfer(false);
}
else if (rxResponse == TransferResponse::BadDataChecksum || txResponse == TransferResponse::BadDataChecksum)
{
@@ -951,11 +954,11 @@ bool DataTransfer::IsReady() noexcept
else
{
// Received invalid response, reset the SPI transfer
- StatefulTransferReset(true);
+ ResetTransfer(true);
}
break;
- case SpiState::Resetting:
+ case InternalTransferState::Resetting:
// Transmitted bad response, attempt to start a new transfer
ExchangeHeader();
break;
@@ -967,12 +970,7 @@ bool DataTransfer::IsReady() noexcept
break;
}
}
- else if (!reprap.GetLinuxInterface().IsWritingIap() && millis() - lastTransferTime > SpiTransferTimeout)
- {
- // Reset failed transfers automatically after a certain period of time
- ResetTransfer();
- }
- return false;
+ return (state == InternalTransferState::ExchangingHeader) ? TransferState::doingFullTransfer : TransferState::doingPartialTransfer;
}
void DataTransfer::StartNextTransfer() noexcept
@@ -994,41 +992,29 @@ void DataTransfer::StartNextTransfer() noexcept
txHeader.crcData = CalcCRC32(txBuffer, txPointer);
txHeader.crcHeader = CalcCRC32(reinterpret_cast<const char *>(&txHeader), sizeof(TransferHeader) - sizeof(uint32_t));
- // Begin SPI transfer
+ // Begin SPI transfe
ExchangeHeader();
}
-void DataTransfer::ResetTransfer() noexcept
+void DataTransfer::ResetConnection(bool fullReset) noexcept
{
+ // The Sbc interface is no longer connected...
+ disable_spi();
dataReceived = false;
- if (state != SpiState::ExchangingHeader)
- {
- disable_spi();
- failedTransfers++;
- transferReadyHigh = false;
- ExchangeHeader();
- }
-}
-void DataTransfer::ResetConnection() noexcept
-{
- if (lastTransferNumber != 0)
- {
- // The Linux interface is no longer connected...
- disable_spi();
- dataReceived = false;
-
- // Reset the sequence numbers and clear the data to send
- lastTransferNumber = 0;
- rxHeader.sequenceNumber = 0;
- txHeader.sequenceNumber = 0;
- rxPointer = txPointer = 0;
- packetId = 0;
+ // Reset the sequence numbers and clear the data to send
+ lastTransferNumber = 0;
+ rxHeader.sequenceNumber = 0;
+ txHeader.sequenceNumber = 0;
+ rxPointer = txPointer = 0;
+ packetId = 0;
- // Kick off a new transfer
+ // Kick off a new transfer
+ if (fullReset)
+ {
transferReadyHigh = false;
- StartNextTransfer();
}
+ StartNextTransfer();
}
bool DataTransfer::WriteObjectModel(OutputBuffer *data) noexcept
@@ -1685,7 +1671,7 @@ bool DataTransfer::WriteReadFile(FileHandle handle, size_t bufferSize) noexcept
// Write data header
ReadFileHeader *header = WriteDataHeader<ReadFileHeader>();
header->handle = handle;
- header->maxLength = min<uint32_t>(bufferSize, LinuxTransferBufferSize - sizeof(FileDataHeader));
+ header->maxLength = min<uint32_t>(bufferSize, SbcTransferBufferSize - sizeof(FileDataHeader));
return true;
}
diff --git a/src/Linux/DataTransfer.h b/src/SBC/DataTransfer.h
index 20b32f55..4882b703 100644
--- a/src/Linux/DataTransfer.h
+++ b/src/SBC/DataTransfer.h
@@ -5,16 +5,16 @@
* Author: Christian
*/
-#ifndef SRC_LINUX_DATATRANSFER_H_
-#define SRC_LINUX_DATATRANSFER_H_
+#ifndef SRC_SBC_DATATRANSFER_H_
+#define SRC_SBC_DATATRANSFER_H_
#include "RepRapFirmware.h"
-#if HAS_LINUX_INTERFACE
+#if HAS_SBC_INTERFACE
#include <GCodes/GCodeFileInfo.h>
#include <GCodes/GCodeChannel.h>
-#include "LinuxMessageFormats.h"
+#include "SbcMessageFormats.h"
#include <RTOSIface/RTOSIface.h>
class BinaryGCodeBuffer;
@@ -25,6 +25,16 @@ class HeightMap;
struct ExpressionValue;
+enum class TransferState
+{
+ doingFullTransfer,
+ doingPartialTransfer,
+ finishingTransfer,
+ connectionTimeout,
+ connectionReset,
+ finished
+};
+
class DataTransfer
{
public:
@@ -33,11 +43,9 @@ public:
void InitFromTask() noexcept;
void Diagnostics(MessageType mtype) noexcept;
- bool IsConnected() const noexcept; // Check if the connection to DCS is live
- bool IsReady() noexcept; // Returns true when data can be read
+ TransferState DoTransfer() noexcept; // Try to finish the current transfer
void StartNextTransfer() noexcept; // Kick off the next transfer
- void ResetConnection() noexcept; // Reset the connection after a longer timeout
- bool LinuxHadReset() const noexcept; // Check if the remote end reset
+ void ResetConnection(bool fullReset) noexcept; // Reset the connection after a longer timeout
size_t PacketsToRead() const noexcept;
const PacketHeader *ReadPacket() noexcept; // Attempt to read the next packet header or return null. Advances the read pointer to the next packet or the packet's data
@@ -85,7 +93,7 @@ public:
bool WriteCloseFile(FileHandle handle) noexcept;
private:
- enum class SpiState
+ enum class InternalTransferState
{
ExchangingHeader,
ExchangingHeaderResponse,
@@ -96,12 +104,10 @@ private:
} state;
// Transfer properties
- uint32_t lastTransferTime;
uint16_t lastTransferNumber;
unsigned int failedTransfers, checksumErrors;
// Transfer buffers
-
#if SAME70
// SAME70 has a write-back cache, so these must be in non-cached memory because we DMA to/from them.
// See http://ww1.microchip.com/downloads/en/DeviceDoc/Managing-Cache-Coherency-on-Cortex-M7-Based-MCUs-DS90003195A.pdf
@@ -110,8 +116,8 @@ private:
static __nocache TransferHeader txHeader;
static __nocache uint32_t rxResponse;
static __nocache uint32_t txResponse;
- alignas(4) static __nocache char rxBuffer[LinuxTransferBufferSize];
- alignas(4) static __nocache char txBuffer[LinuxTransferBufferSize];
+ alignas(4) static __nocache char rxBuffer[SbcTransferBufferSize];
+ alignas(4) static __nocache char txBuffer[SbcTransferBufferSize];
#else
// The other processors we support have write-through cache
// Allocate the buffers in the object so that we can delete the object and recycle the memory if the SBC interface is not being used
@@ -123,24 +129,23 @@ private:
char *rxBuffer; // not allocated until we know we need it
char *txBuffer; // not allocated until we know we need it
#endif
-
size_t rxPointer, txPointer;
// Packet properties
uint16_t packetId;
+ bool IsConnectionReset() const noexcept;
+
void ExchangeHeader() noexcept;
void ExchangeResponse(uint32_t response) noexcept;
void ExchangeData() noexcept;
- void ResetTransfer() noexcept;
- void StatefulTransferReset(bool ownRequest) noexcept;
+ void ResetTransfer(bool ownRequest) noexcept;
uint32_t CalcCRC32(const char *buffer, size_t length) const noexcept;
template<typename T> const T *ReadDataHeader() noexcept;
- // Always keep enough tx space to allow resend requests in case RRF runs out of
- // resources and cannot process an incoming request right away
- size_t FreeTxSpace() const noexcept { return LinuxTransferBufferSize - AddPadding(txPointer) - rxHeader.numPackets * sizeof(PacketHeader); }
+ // Always keep enough tx space to allow resend requests in case RRF runs out of resources and cannot process an incoming request right away
+ size_t FreeTxSpace() const noexcept { return SbcTransferBufferSize - AddPadding(txPointer) - rxHeader.numPackets * sizeof(PacketHeader); }
bool CanWritePacket(size_t dataLength = 0) const noexcept;
PacketHeader *WritePacketHeader(FirmwareRequest request, size_t dataLength = 0, uint16_t resendPacktId = 0) noexcept;
@@ -150,12 +155,7 @@ private:
size_t AddPadding(size_t length) const noexcept;
};
-inline bool DataTransfer::IsConnected() const noexcept
-{
- return lastTransferTime != 0 && (millis() - lastTransferTime < SpiConnectionTimeout);
-}
-
-inline bool DataTransfer::LinuxHadReset() const noexcept
+inline bool DataTransfer::IsConnectionReset() const noexcept
{
uint16_t nextTransferNumber = lastTransferNumber + 1;
return lastTransferNumber != 0 && (nextTransferNumber != rxHeader.sequenceNumber);
@@ -181,6 +181,6 @@ inline size_t DataTransfer::AddPadding(size_t length) const noexcept
size_t extraBytes = (length & 3);
return (extraBytes == 0) ? length : length + 4 - extraBytes;
}
-#endif // HAS_LINUX_INTERFACE
+#endif // HAS_SBC_INTERFACE
-#endif /* SRC_LINUX_DATATRANSFER_H_ */
+#endif /* SRC_SBC_DATATRANSFER_H_ */
diff --git a/src/SBC/SbcInterface.cpp b/src/SBC/SbcInterface.cpp
new file mode 100644
index 00000000..73cfb885
--- /dev/null
+++ b/src/SBC/SbcInterface.cpp
@@ -0,0 +1,1785 @@
+/*
+ * SbcInterface.cpp
+ *
+ * Created on: 29 Mar 2019
+ * Author: Christian
+ */
+
+#include "SbcInterface.h"
+#include "DataTransfer.h"
+
+#if HAS_SBC_INTERFACE
+
+#include <GCodes/GCodeBuffer/ExpressionParser.h>
+#include <GCodes/GCodeBuffer/GCodeBuffer.h>
+#include <Heating/Heat.h>
+#include <Movement/Move.h>
+#include <Platform/Platform.h>
+#include <PrintMonitor/PrintMonitor.h>
+#include <Tools/Filament.h>
+#include <Platform/RepRap.h>
+#include <RepRapFirmware.h>
+#include <Platform/Tasks.h>
+#include <Hardware/SoftwareReset.h>
+#include <Hardware/ExceptionHandlers.h>
+#include <Platform/TaskPriorities.h>
+
+extern char _estack; // defined by the linker
+
+volatile OutputStack SbcInterface::gcodeReply;
+Mutex SbcInterface::gcodeReplyMutex;
+
+// The SBC task's stack size needs to be enough to support rr_model and expression evaluation
+// In RRF 3.3beta3, 744 is only just enough for simple expression evaluation in a release build when using globals
+// In 3.3beta3.1 we have saved ~151 bytes (37 words) of stack compared to 3.3beta3
+#ifdef __LPC17xx__
+constexpr size_t SBCTaskStackWords = 375;
+#elif defined(DEBUG)
+constexpr size_t SBCTaskStackWords = 1200; // debug builds use more stack
+#else
+constexpr size_t SBCTaskStackWords = 1000; // increased from 820 so that we can evaluate "abs(move.calibration.initial.deviation - move.calibration.final.deviation) < 0.000"
+#endif
+
+constexpr uint32_t SbcYieldTimeout = 10;
+
+static Task<SBCTaskStackWords> *sbcTask;
+
+extern "C" [[noreturn]] void SBCTaskStart(void * pvParameters) noexcept
+{
+ reprap.GetSbcInterface().TaskLoop();
+}
+
+SbcInterface::SbcInterface() noexcept : isConnected(false), numDisconnects(0), numTimeouts(0),
+ maxDelayBetweenTransfers(SpiTransferDelay), maxFileOpenDelay(SpiFileOpenDelay), numMaxEvents(SpiEventsRequired),
+ delaying(false), numEvents(0), reportPause(false), reportPauseWritten(false), printAborted(false),
+ codeBuffer(nullptr), rxPointer(0), txPointer(0), txEnd(0), sendBufferUpdate(true),
+ waitingForFileChunk(false), fileMutex(), fileSemaphore(), fileOperation(FileOperation::none), fileOperationPending(false)
+#ifdef TRACK_FILE_CODES
+ , fileCodesRead(0), fileCodesHandled(0), fileMacrosRunning(0), fileMacrosClosing(0)
+#endif
+{
+}
+
+void SbcInterface::Init() noexcept
+{
+ if (reprap.UsingSbcInterface())
+ {
+ fileMutex.Create("SBCFile");
+ gcodeReplyMutex.Create("SBCReply");
+ codeBuffer = (char *)new uint32_t[(SpiCodeBufferSize + 3)/4];
+
+#if defined(DUET_NG)
+ // Make sure that the Wifi module if present is disabled. The ESP Reset pin is already forced low in Platform::Init();
+ pinMode(EspEnablePin, OUTPUT_LOW);
+#endif
+
+ transfer.Init();
+ sbcTask = new Task<SBCTaskStackWords>();
+ sbcTask->Create(SBCTaskStart, "SBC", nullptr, TaskPriority::SbcPriority);
+ iapRamAvailable = &_estack - Tasks::GetHeapTop();
+ }
+ else
+ {
+ // Set up the data transfer to exchange the header + response code. No task is started to save memory
+ transfer.Init();
+ }
+}
+
+void SbcInterface::Spin() noexcept
+{
+ if (transfer.DoTransfer() != TransferState::finishingTransfer)
+ {
+ // Don't process anything, just kick off the next transfer to report we're operating in standalone mode
+ transfer.StartNextTransfer();
+ }
+}
+
+[[noreturn]] void SbcInterface::TaskLoop() noexcept
+{
+ transfer.InitFromTask();
+ transfer.StartNextTransfer();
+
+ bool busy = false, transferComplete = false, hadTimeout = false, hadReset = false;
+ for (;;)
+ {
+ // Try to exchange data with the SBC
+ transferComplete = hadTimeout = hadReset = false;
+ do
+ {
+ busy = false;
+ state = transfer.DoTransfer();
+ switch (state)
+ {
+ case TransferState::doingFullTransfer:
+ hadTimeout = !TaskBase::Take(isConnected ? SpiConnectionTimeout : TaskBase::TimeoutUnlimited);
+ break;
+ case TransferState::doingPartialTransfer:
+ hadTimeout = !TaskBase::Take(SpiTransferTimeout);
+ break;
+ case TransferState::finishingTransfer:
+ busy = true;
+ break;
+ case TransferState::connectionTimeout:
+ hadTimeout = true;
+ break;
+ case TransferState::connectionReset:
+ hadReset = true;
+ break;
+ case TransferState::finished:
+ transferComplete = true;
+ break;
+ }
+ } while (busy);
+
+ // Handle connection errors
+ if (isConnected && (hadReset || hadTimeout))
+ {
+ isConnected = false;
+ numDisconnects++;
+ if (hadTimeout)
+ {
+ numTimeouts++;
+ }
+ reprap.GetPlatform().Message(NetworkInfoMessage, "Lost connection to SBC\n");
+
+ // Invalidate local resources
+ InvalidateResources();
+ if (hadReset)
+ {
+ // Let the main task invalidate resources before processing new data
+ TaskBase::Take(SbcYieldTimeout);
+
+ // Reset the SPI connection again
+ transfer.ResetConnection(false);
+ }
+ }
+
+ // Deal with received data
+ if (transferComplete)
+ {
+ if (!isConnected)
+ {
+ isConnected = true;
+ reprap.GetPlatform().Message(NetworkInfoMessage, "Connection to SBC established!\n");
+ }
+
+ // Handle exchanged data and kick off the next transfer
+ ExchangeData();
+ transfer.StartNextTransfer();
+ }
+ else if (hadTimeout)
+ {
+ // Reset the SPI connection if no data could be exchanged
+ transfer.ResetConnection(true);
+ }
+ }
+}
+
+void SbcInterface::ExchangeData() noexcept
+{
+ // Process incoming packets
+ bool codeBufferAvailable = true;
+ for (size_t i = 0; i < transfer.PacketsToRead(); i++)
+ {
+ const PacketHeader * const packet = transfer.ReadPacket();
+ if (packet == nullptr)
+ {
+ if (reprap.Debug(moduleSbcInterface))
+ {
+ debugPrintf("Error trying to read next SPI packet\n");
+ }
+ break;
+ }
+
+ if (packet->request >= (uint16_t)SbcRequest::InvalidRequest)
+ {
+ REPORT_INTERNAL_ERROR;
+ break;
+ }
+
+ bool packetAcknowledged = true;
+ switch ((SbcRequest)packet->request)
+ {
+ // Perform an emergency stop
+ case SbcRequest::EmergencyStop:
+ reprap.EmergencyStop();
+ break;
+
+ // Reset the controller
+ case SbcRequest::Reset:
+ SoftwareReset(SoftwareResetReason::user);
+ break;
+
+ // Perform a G/M/T-code
+ case SbcRequest::Code:
+ {
+ // Read the next code
+ if (packet->length == 0)
+ {
+ reprap.GetPlatform().Message(WarningMessage, "Received empty binary code, discarding\n");
+ break;
+ }
+
+ const CodeHeader *code = reinterpret_cast<const CodeHeader*>(transfer.ReadData(packet->length));
+ const GCodeChannel channel(code->channel);
+ GCodeBuffer * const gb = reprap.GetGCodes().GetGCodeBuffer(channel);
+ if (gb->IsInvalidated())
+ {
+ // Don't deal with codes that will be thrown away
+ break;
+ }
+
+ // Check if a GB is waiting for a macro file to be started
+ if (gb->IsWaitingForMacro() && !gb->IsMacroRequestPending())
+ {
+ gb->ResolveMacroRequest(false, false);
+#ifdef TRACK_FILE_CODES
+ if (channel == GCodeChannel::File)
+ {
+ fileMacrosRunning++;
+ }
+#endif
+ }
+
+ // Don't process any more codes if we failed to store them last time...
+ if (!codeBufferAvailable)
+ {
+ packetAcknowledged = false;
+ break;
+ }
+
+ TaskCriticalSectionLocker locker;
+
+ // Make sure no existing codes are overwritten
+ uint16_t bufferedCodeSize = sizeof(BufferedCodeHeader) + packet->length;
+ if ((txEnd == 0 && bufferedCodeSize > max<uint16_t>(rxPointer, SpiCodeBufferSize - txPointer)) ||
+ (txEnd != 0 && bufferedCodeSize > rxPointer - txPointer))
+ {
+#if false
+ // This isn't enabled because the debug call plus critical section would lead to software resets
+ debugPrintf("Failed to store code, RX/TX %d/%d-%d\n", rxPointer, txPointer, txEnd);
+#endif
+ packetAcknowledged = codeBufferAvailable = false;
+ break;
+ }
+
+ // Overlap if necessary
+ if (txPointer + bufferedCodeSize > SpiCodeBufferSize)
+ {
+ txEnd = txPointer;
+ txPointer = 0;
+ sendBufferUpdate = true;
+ }
+
+ // Store the buffer header
+ BufferedCodeHeader *bufHeader = reinterpret_cast<BufferedCodeHeader *>(codeBuffer + txPointer);
+ bufHeader->isPending = true;
+ bufHeader->length = packet->length;
+
+ // Store the corresponding code. Binary codes are always aligned on a 4-byte boundary
+ uint32_t *dst = reinterpret_cast<uint32_t *>(codeBuffer + txPointer + sizeof(BufferedCodeHeader));
+ const uint32_t *src = reinterpret_cast<const uint32_t *>(code);
+ memcpyu32(dst, src, packet->length / sizeof(uint32_t));
+ txPointer += bufferedCodeSize;
+ break;
+ }
+
+ // Get the object model
+ case SbcRequest::GetObjectModel:
+ {
+ String<StringLength100> key;
+ String<StringLength20> flags;
+ transfer.ReadGetObjectModel(packet->length, key.GetRef(), flags.GetRef());
+
+ try
+ {
+ OutputBuffer *outBuf = reprap.GetModelResponse(key.c_str(), flags.c_str());
+ if (outBuf == nullptr || !transfer.WriteObjectModel(outBuf))
+ {
+ // Failed to write the whole object model, try again later
+ packetAcknowledged = false;
+ OutputBuffer::ReleaseAll(outBuf);
+ }
+ }
+ catch (const GCodeException& e)
+ {
+ // Get the error message and send it back to DSF
+ OutputBuffer *buf;
+ if (OutputBuffer::Allocate(buf))
+ {
+ String<StringLength100> errorMessage;
+ e.GetMessage(errorMessage.GetRef(), nullptr);
+ buf->cat(errorMessage.c_str());
+ if (!transfer.WriteObjectModel(buf))
+ {
+ OutputBuffer::ReleaseAll(buf);
+ packetAcknowledged = false;
+ }
+ }
+ else
+ {
+ packetAcknowledged = false;
+ }
+ }
+ break;
+ }
+
+ // Set value in the object model
+ case SbcRequest::SetObjectModel:
+ {
+ const size_t dataLength = packet->length;
+ const char * const data = transfer.ReadData(dataLength);
+ // TODO implement this
+ (void)data;
+ break;
+ }
+
+ // Print is about to be started, set file print info
+ case SbcRequest::SetPrintFileInfo:
+ {
+ String<MaxFilenameLength> filename;
+ transfer.ReadPrintStartedInfo(packet->length, filename.GetRef(), fileInfo);
+ reprap.GetPrintMonitor().SetPrintingFileInfo(filename.c_str(), fileInfo);
+ break;
+ }
+
+ // Print has been stopped
+ case SbcRequest::PrintStopped:
+ {
+ const PrintStoppedReason reason = transfer.ReadPrintStoppedInfo();
+ if (reason == PrintStoppedReason::abort)
+ {
+ // Stop the print with the given reason
+ printAborted = true;
+ InvalidateBufferedCodes(GCodeChannel::File);
+ }
+ else
+ {
+ // Just mark the print file as finished
+ GCodeBuffer * const gb = reprap.GetGCodes().GetGCodeBuffer(GCodeChannel::File);
+ MutexLocker locker(gb->mutex, SbcYieldTimeout);
+ if (locker.IsAcquired())
+ {
+ gb->SetPrintFinished();
+ }
+ else
+ {
+ packetAcknowledged = false;
+ }
+ }
+ break;
+ }
+
+ // Macro file has been finished
+ case SbcRequest::MacroCompleted:
+ {
+ bool error;
+ const GCodeChannel channel = transfer.ReadMacroCompleteInfo(error);
+ if (channel.IsValid())
+ {
+ GCodeBuffer * const gb = reprap.GetGCodes().GetGCodeBuffer(channel);
+ if (gb->IsWaitingForMacro() && !gb->IsMacroRequestPending())
+ {
+ gb->ResolveMacroRequest(error, true);
+ if (reprap.Debug(moduleSbcInterface))
+ {
+ debugPrintf("Waiting macro completed on channel %u\n", channel.ToBaseType());
+ }
+ }
+ else
+ {
+ MutexLocker locker(gb->mutex, SbcYieldTimeout);
+ if (locker.IsAcquired())
+ {
+ if (error)
+ {
+ gb->CurrentFileMachineState().CloseFile();
+ gb->PopState();
+ gb->Init();
+ }
+ else
+ {
+#ifdef TRACK_FILE_CODES
+ if (channel == GCodeChannel::File)
+ {
+ fileMacrosClosing++;
+ }
+#endif
+ gb->SetFileFinished();
+ }
+
+ if (reprap.Debug(moduleSbcInterface))
+ {
+ debugPrintf("Macro completed on channel %u\n", channel.ToBaseType());
+ }
+ }
+ else
+ {
+ packetAcknowledged = false;
+ }
+ }
+ }
+ else
+ {
+ REPORT_INTERNAL_ERROR;
+ }
+ break;
+ }
+
+ // Return heightmap as generated by G29 S0
+ case SbcRequest::GetHeightMap:
+ {
+ ConditionalReadLocker locker(reprap.GetMove().heightMapLock);
+ if (locker.IsLocked())
+ {
+ packetAcknowledged = transfer.WriteHeightMap();
+ }
+ else
+ {
+ packetAcknowledged = false;
+ }
+ break;
+ }
+
+ // Set heightmap via G29 S1
+ case SbcRequest::SetHeightMap:
+ {
+ ConditionalWriteLocker locker(reprap.GetMove().heightMapLock);
+ if (locker.IsLocked())
+ {
+ if (!transfer.ReadHeightMap())
+ {
+ reprap.GetPlatform().Message(ErrorMessage, "Failed to set height map - bad data?\n");
+ }
+ }
+ else
+ {
+ packetAcknowledged = false;
+ }
+ break;
+ }
+
+ // Lock movement and wait for standstill
+ case SbcRequest::LockMovementAndWaitForStandstill:
+ {
+ const GCodeChannel channel = transfer.ReadCodeChannel();
+ if (channel.IsValid())
+ {
+ GCodeBuffer * const gb = reprap.GetGCodes().GetGCodeBuffer(channel);
+ MutexLocker locker(gb->mutex, SbcYieldTimeout);
+ if (locker.IsAcquired() && reprap.GetGCodes().LockMovementAndWaitForStandstill(*gb))
+ {
+ transfer.WriteLocked(channel);
+ }
+ else
+ {
+ packetAcknowledged = false;
+ }
+ }
+ else
+ {
+ REPORT_INTERNAL_ERROR;
+ }
+ break;
+ }
+
+ // Unlock everything
+ case SbcRequest::Unlock:
+ {
+ const GCodeChannel channel = transfer.ReadCodeChannel();
+ if (channel.IsValid())
+ {
+ GCodeBuffer * const gb = reprap.GetGCodes().GetGCodeBuffer(channel);
+ MutexLocker locker(gb->mutex, SbcYieldTimeout);
+ if (locker.IsAcquired())
+ {
+ reprap.GetGCodes().UnlockAll(*gb);
+ }
+ else
+ {
+ packetAcknowledged = false;
+ }
+ }
+ else
+ {
+ REPORT_INTERNAL_ERROR;
+ }
+ break;
+ }
+
+ // Write the first chunk of the IAP binary
+ case SbcRequest::WriteIap:
+ {
+ reprap.PrepareToLoadIap();
+ ReceiveAndStartIap(transfer.ReadData(packet->length), packet->length);
+ break;
+ }
+
+ // Assign filament (deprecated)
+ case SbcRequest::AssignFilament_deprecated:
+ (void)transfer.ReadData(packet->length); // skip the packet content
+ break;
+
+ // Return a file chunk
+ case SbcRequest::FileChunk:
+ transfer.ReadFileChunk(requestedFileBuffer, requestedFileDataLength, requestedFileLength);
+ requestedFileSemaphore.Give();
+ break;
+
+ // Evaluate an expression
+ case SbcRequest::EvaluateExpression:
+ {
+ String<GCODE_LENGTH> expression;
+ const GCodeChannel channel = transfer.ReadEvaluateExpression(packet->length, expression.GetRef());
+ if (channel.IsValid())
+ {
+ GCodeBuffer * const gb = reprap.GetGCodes().GetGCodeBuffer(channel);
+
+ // If there is a macro file waiting, the first instruction must be conditional. Don't block any longer...
+ if (gb->IsWaitingForMacro())
+ {
+ gb->ResolveMacroRequest(false, false);
+#ifdef TRACK_FILE_CODES
+ if (channel == GCodeChannel::File)
+ {
+ fileMacrosRunning++;
+ }
+#endif
+ }
+
+ try
+ {
+ // Evaluate the expression and send the result to DSF
+ MutexLocker lock(gb->mutex, SbcYieldTimeout);
+ if (lock.IsAcquired())
+ {
+ ExpressionParser parser(*gb, expression.c_str(), expression.c_str() + expression.strlen());
+ const ExpressionValue val = parser.Parse();
+ packetAcknowledged = transfer.WriteEvaluationResult(expression.c_str(), val);
+ }
+ else
+ {
+ packetAcknowledged = false;
+ }
+ }
+ catch (const GCodeException& e)
+ {
+ // Get the error message and send it back to DSF
+ String<StringLength100> errorMessage;
+ e.GetMessage(errorMessage.GetRef(), nullptr);
+ packetAcknowledged = transfer.WriteEvaluationError(expression.c_str(), errorMessage.c_str());
+ }
+ }
+ else
+ {
+ REPORT_INTERNAL_ERROR;
+ }
+ break;
+ }
+
+ // Send a firmware message, typically a response to a command that has been passed to DSF.
+ // These responses can get quite long (e.g. responses to M20) so receive it into an OutputBuffer.
+ case SbcRequest::Message:
+ {
+ OutputBuffer *buf;
+ if (OutputBuffer::Allocate(buf))
+ {
+ MessageType type;
+ if (transfer.ReadMessage(type, buf))
+ {
+ // FIXME Push flag is not supported yet
+ reprap.GetPlatform().Message(type, buf);
+ }
+ else
+ {
+ // Not enough memory for reading the whole message, try again later
+ OutputBuffer::ReleaseAll(buf);
+ packetAcknowledged = false;
+ }
+ }
+ break;
+ }
+
+ // Macro file has been started
+ case SbcRequest::MacroStarted:
+ {
+ const GCodeChannel channel = transfer.ReadCodeChannel();
+ if (channel.IsValid())
+ {
+ GCodeBuffer * const gb = reprap.GetGCodes().GetGCodeBuffer(channel);
+ if (gb->IsWaitingForMacro() && !gb->IsMacroRequestPending())
+ {
+ // File exists and is open, but no code has arrived yet
+ gb->ResolveMacroRequest(false, false);
+#ifdef TRACK_FILE_CODES
+ if (channel == GCodeChannel::File)
+ {
+ fileMacrosRunning++;
+ }
+#endif
+ }
+ else if (channel != GCodeChannel::Daemon)
+ {
+ reprap.GetPlatform().MessageF(WarningMessage, "Macro file has been started on channel %s but none was requested\n", channel.ToString());
+ }
+ else
+ {
+ // dameon.g is running, now the OM may report the file is being executed
+ reprap.InputsUpdated();
+ }
+ }
+ else
+ {
+ REPORT_INTERNAL_ERROR;
+ }
+ break;
+ }
+
+ // Invalidate all files and codes on a given channel
+ case SbcRequest::InvalidateChannel:
+ {
+ const GCodeChannel channel = transfer.ReadCodeChannel();
+ if (channel.IsValid())
+ {
+ GCodeBuffer * const gb = reprap.GetGCodes().GetGCodeBuffer(channel);
+ if (gb->IsWaitingForMacro())
+ {
+ gb->ResolveMacroRequest(true, false);
+ }
+
+ MutexLocker locker(gb->mutex, SbcYieldTimeout);
+ if (locker.IsAcquired())
+ {
+ // Note that we do not call StopPrint here or set any other variables; DSF already does that
+ gb->AbortFile(true, false);
+ InvalidateBufferedCodes(channel);
+ }
+ else
+ {
+ packetAcknowledged = false;
+ }
+ }
+ else
+ {
+ REPORT_INTERNAL_ERROR;
+ }
+ break;
+ }
+
+ // Set the content of a variable
+ case SbcRequest::SetVariable:
+ {
+ bool createVariable;
+ String<MaxVariableNameLength> varName;
+ String<GCODE_LENGTH> expression;
+ const GCodeChannel channel = transfer.ReadSetVariable(createVariable, varName.GetRef(), expression.GetRef());
+
+ // Make sure we can access the gb safely...
+ if (!channel.IsValid())
+ {
+ REPORT_INTERNAL_ERROR;
+ break;
+ }
+
+ GCodeBuffer * const gb = reprap.GetGCodes().GetGCodeBuffer(channel);
+ MutexLocker lock(gb->mutex, SbcYieldTimeout);
+ if (!lock.IsAcquired())
+ {
+ packetAcknowledged = false;
+ break;
+ }
+
+ // Get the variable set
+ const bool isGlobal = StringStartsWith(varName.c_str(), "global.");
+ if (!isGlobal && !StringStartsWith(varName.c_str(), "var."))
+ {
+ packetAcknowledged = transfer.WriteSetVariableError(varName.c_str(), "expected a global or local variable");
+ break;
+ }
+ WriteLockedPointer<VariableSet> vset = (isGlobal) ? reprap.GetGlobalVariablesForWriting() : WriteLockedPointer<VariableSet>(nullptr, &gb->GetVariables());
+
+ // Check if the variable is valid
+ const char *shortVarName = varName.c_str() + strlen(isGlobal ? "global." : "var.");
+ Variable * const v = vset->Lookup(shortVarName);
+ if (createVariable && v != nullptr)
+ {
+ // For now we don't allow an existing variable to be reassigned using a 'var' or 'global' statement. We may need to allow it for 'global' statements.
+ // Save memory by re-using 'expression' to capture the error message
+ expression.printf("variable '%s' already exists", varName.c_str());
+ packetAcknowledged = transfer.WriteSetVariableError(varName.c_str(), expression.c_str());
+ break;
+ }
+ if (!createVariable && v == nullptr)
+ {
+ // Save memory by re-using 'expression' to capture the error message
+ expression.printf("unknown variable '%s'", varName.c_str());
+ packetAcknowledged = transfer.WriteSetVariableError(varName.c_str(), expression.c_str());
+ break;
+ }
+
+ // Evaluate the expression and assign it
+ try
+ {
+ ExpressionParser parser(*gb, expression.c_str(), expression.c_str() + expression.strlen());
+ ExpressionValue ev = parser.Parse();
+ if (v == nullptr)
+ {
+ // DSF doesn't provide indent values but instructs RRF to delete local variables when the current block ends
+ vset->InsertNew(shortVarName, ev, 0);
+ }
+ else
+ {
+ v->Assign(ev);
+ }
+
+ transfer.WriteSetVariableResult(varName.c_str(), ev);
+ if (isGlobal)
+ {
+ reprap.GlobalUpdated();
+ }
+ }
+ catch (const GCodeException& e)
+ {
+ // Get the error message and send it back to DSF
+ // Save memory by re-using 'expression' to capture the error message
+ e.GetMessage(expression.GetRef(), nullptr);
+ packetAcknowledged = transfer.WriteSetVariableError(varName.c_str(), expression.c_str());
+ }
+ break;
+ }
+
+ // Delete a local variable
+ case SbcRequest::DeleteLocalVariable:
+ {
+ String<MaxVariableNameLength> varName;
+ const GCodeChannel channel = transfer.ReadDeleteLocalVariable(varName.GetRef());
+
+ // Make sure we can access the gb safely...
+ if (!channel.IsValid())
+ {
+ REPORT_INTERNAL_ERROR;
+ break;
+ }
+
+ GCodeBuffer * const gb = reprap.GetGCodes().GetGCodeBuffer(channel);
+ MutexLocker lock(gb->mutex, SbcYieldTimeout);
+ if (!lock.IsAcquired())
+ {
+ packetAcknowledged = false;
+ break;
+ }
+
+ // Try to delete the variable again
+ WriteLockedPointer<VariableSet> vset = WriteLockedPointer<VariableSet>(nullptr, &gb->GetVariables());
+ vset.Ptr()->Delete(varName.c_str());
+ break;
+ }
+
+ // Result of a file exists check
+ case SbcRequest::CheckFileExistsResult:
+ if (fileOperation == FileOperation::checkFileExists)
+ {
+ fileSuccess = transfer.ReadBoolean();
+ fileOperation = FileOperation::none;
+ fileSemaphore.Give();
+ }
+ else
+ {
+ REPORT_INTERNAL_ERROR;
+ }
+ break;
+
+ // Result of a deletion request
+ case SbcRequest::FileDeleteResult:
+ if (fileOperation == FileOperation::deleteFileOrDirectory)
+ {
+ fileSuccess = transfer.ReadBoolean();
+ fileOperation = FileOperation::none;
+ fileSemaphore.Give();
+ }
+ else
+ {
+ REPORT_INTERNAL_ERROR;
+ }
+ break;
+
+ // Result of a file open request
+ case SbcRequest::OpenFileResult:
+ if (fileOperation == FileOperation::openRead ||
+ fileOperation == FileOperation::openWrite ||
+ fileOperation == FileOperation::openAppend)
+ {
+ fileHandle = transfer.ReadOpenFileResult(fileOffset);
+ fileSuccess = (fileHandle != noFileHandle);
+ fileOperation = FileOperation::none;
+ fileSemaphore.Give();
+ }
+ else
+ {
+ REPORT_INTERNAL_ERROR;
+ }
+ break;
+
+ // Result of a file read request
+ case SbcRequest::FileReadResult:
+ if (fileOperation == FileOperation::read)
+ {
+ int bytesRead = transfer.ReadFileData(fileReadBuffer, fileBufferLength);
+ fileSuccess = bytesRead >= 0;
+ fileOffset = fileSuccess ? bytesRead : 0;
+ fileOperation = FileOperation::none;
+ fileSemaphore.Give();
+ }
+ else
+ {
+ REPORT_INTERNAL_ERROR;
+ }
+ break;
+
+ // Result of a file write request
+ case SbcRequest::FileWriteResult:
+ if (fileOperation == FileOperation::write)
+ {
+ fileSuccess = transfer.ReadBoolean();
+ if (!fileSuccess || fileBufferLength == 0)
+ {
+ fileOperationPending = false;
+ fileOperation = FileOperation::none;
+ fileSemaphore.Give();
+ }
+ }
+ else
+ {
+ REPORT_INTERNAL_ERROR;
+ }
+ break;
+
+ // Result of a file seek request
+ case SbcRequest::FileSeekResult:
+ if (fileOperation == FileOperation::seek)
+ {
+ fileSuccess = transfer.ReadBoolean();
+ fileOperation = FileOperation::none;
+ fileSemaphore.Give();
+ }
+ else
+ {
+ REPORT_INTERNAL_ERROR;
+ }
+ break;
+
+ // Result of a file seek request
+ case SbcRequest::FileTruncateResult:
+ if (fileOperation == FileOperation::truncate)
+ {
+ fileSuccess = transfer.ReadBoolean();
+ fileOperation = FileOperation::none;
+ fileSemaphore.Give();
+ }
+ else
+ {
+ REPORT_INTERNAL_ERROR;
+ }
+ break;
+
+ // Invalid request
+ default:
+ REPORT_INTERNAL_ERROR;
+ break;
+ }
+
+ // Request the packet again if no response could be sent back
+ if (!packetAcknowledged)
+ {
+ transfer.ResendPacket(packet);
+ }
+ }
+
+ // Check if we can wait a short moment to reduce CPU load on the SBC
+ if (!skipNextDelay && numEvents < numMaxEvents && !waitingForFileChunk &&
+ !fileOperationPending && fileOperation == FileOperation::none)
+ {
+ delaying = true;
+ if (!TaskBase::Take(MassStorage::AnyFileOpen() ? maxFileOpenDelay : maxDelayBetweenTransfers))
+ {
+ delaying = false;
+ }
+ }
+ numEvents = 0;
+ skipNextDelay = false;
+
+ // Send code replies and generic messages
+ if (!gcodeReply.IsEmpty())
+ {
+ MutexLocker lock(gcodeReplyMutex);
+ while (!gcodeReply.IsEmpty())
+ {
+ const MessageType type = gcodeReply.GetFirstItemType();
+ OutputBuffer *buffer = gcodeReply.GetFirstItem(); // this may be null
+ if (!transfer.WriteCodeReply(type, buffer)) // this handles the null case too
+ {
+ break;
+ }
+ gcodeReply.SetFirstItem(buffer); // this does a pop if buffer is null
+ }
+ }
+
+ // Notify DSF about the available buffer space
+ if (!codeBufferAvailable || sendBufferUpdate)
+ {
+ TaskCriticalSectionLocker locker;
+
+ const uint16_t bufferSpace = (txEnd == 0) ? max<uint16_t>(rxPointer, SpiCodeBufferSize - txPointer) : rxPointer - txPointer;
+ sendBufferUpdate = !transfer.WriteCodeBufferUpdate(bufferSpace);
+ }
+
+ // Get another chunk of the file being requested
+ if (waitingForFileChunk &&
+ !fileChunkRequestSent && transfer.WriteFileChunkRequest(requestedFileName.c_str(), requestedFileOffset, requestedFileLength))
+ {
+ fileChunkRequestSent = true;
+ }
+
+ // Perform the next file operation if requested
+ if (fileOperationPending)
+ {
+ switch (fileOperation)
+ {
+ case FileOperation::checkFileExists:
+ fileOperationPending = !transfer.WriteCheckFileExists(filePath);
+ break;
+
+ case FileOperation::deleteFileOrDirectory:
+ fileOperationPending = !transfer.WriteDeleteFileOrDirectory(filePath);
+ break;
+
+ case FileOperation::openRead:
+ case FileOperation::openWrite:
+ case FileOperation::openAppend:
+ fileOperationPending = !transfer.WriteOpenFile(filePath, fileOperation == FileOperation::openWrite || fileOperation == FileOperation::openAppend, fileOperation == FileOperation::openAppend, filePreAllocSize);
+ break;
+
+ case FileOperation::read:
+ fileOperationPending = !transfer.WriteReadFile(fileHandle, fileBufferLength);
+ break;
+
+ case FileOperation::write:
+ {
+ size_t bytesNotWritten = fileBufferLength;
+ if (transfer.WriteFileData(fileHandle, fileWriteBuffer, fileBufferLength))
+ {
+ fileWriteBuffer += bytesNotWritten - fileBufferLength;
+ if (fileBufferLength == 0)
+ {
+ fileOperationPending = false;
+ }
+ }
+ break;
+ }
+
+ case FileOperation::seek:
+ fileOperationPending = !transfer.WriteSeekFile(fileHandle, fileOffset);
+ break;
+
+ case FileOperation::truncate:
+ fileOperationPending = !transfer.WriteTruncateFile(fileHandle);
+ break;
+
+ case FileOperation::close:
+ fileOperationPending = !transfer.WriteCloseFile(fileHandle);
+ if (!fileOperationPending)
+ {
+ // Close requests don't get a result back, so they can be resolved as soon as they are sent to the SBC
+ fileOperation = FileOperation::none;
+ fileSemaphore.Give();
+ }
+ break;
+
+ default:
+ REPORT_INTERNAL_ERROR;
+ break;
+ }
+ }
+
+ // Deal with code channel requests
+ for (size_t i = 0; i < NumGCodeChannels; i++)
+ {
+ const GCodeChannel channel(i);
+ GCodeBuffer * const gb = reprap.GetGCodes().GetGCodeBuffer(channel);
+
+ // Invalidate buffered codes if required
+ if (gb->IsInvalidated())
+ {
+ InvalidateBufferedCodes(gb->GetChannel());
+ gb->Invalidate(false);
+ }
+
+ // Deal with macro files being closed
+ if (gb->IsMacroFileClosed() && transfer.WriteMacroFileClosed(channel))
+ {
+ // Note this is only sent when a macro file has finished successfully
+ gb->MacroFileClosedSent();
+ }
+
+ // Handle blocking macro requests
+ if (gb->IsWaitingForMacro() && gb->IsMacroRequestPending())
+ {
+ const char * const requestedMacroFile = gb->GetRequestedMacroFile();
+ bool fromCode = gb->IsMacroStartedByCode();
+ if (transfer.WriteMacroRequest(channel, requestedMacroFile, fromCode))
+ {
+ if (reprap.Debug(moduleSbcInterface))
+ {
+ debugPrintf("Requesting macro file '%s' (fromCode: %s)\n", requestedMacroFile, fromCode ? "true" : "false");
+ }
+ gb->MacroRequestSent();
+ gb->Invalidate();
+ }
+ }
+
+ // Deal with other requests unless we are still waiting in a semaphore
+ if (!gb->IsWaitingForMacro())
+ {
+ MutexLocker gbLock(gb->mutex, SbcYieldTimeout);
+ if (gbLock.IsAcquired())
+ {
+ if (gb->GetChannel() != GCodeChannel::Daemon)
+ {
+ skipNextDelay |= gb->IsMacroRequestPending() || gb->HasJustStartedMacro();
+ }
+
+ // Handle file abort requests
+ if (gb->IsAbortRequested() && transfer.WriteAbortFileRequest(channel, gb->IsAbortAllRequested()))
+ {
+#ifdef TRACK_FILE_CODES
+ if (channel == GCodeChannel::File)
+ {
+ if (gb->IsAbortAllRequested())
+ {
+ fileCodesRead = fileCodesHandled = fileMacrosRunning = fileMacrosClosing = 0;
+ }
+ else
+ {
+ fileMacrosClosing++;
+ }
+ }
+#endif
+ gb->FileAbortSent();
+ gb->Invalidate();
+ }
+
+ // Handle blocking messages and their results
+ if (gb->LatestMachineState().waitingForAcknowledgement && gb->IsMessagePromptPending() &&
+ transfer.WriteWaitForAcknowledgement(channel))
+ {
+ gb->MessagePromptSent();
+ gb->Invalidate();
+ }
+ else if (gb->IsMessageAcknowledged() && transfer.WriteMessageAcknowledged(channel))
+ {
+ // Note this is only sent when a message was acknowledged in a regular way (i.e. by M292)
+ gb->MessageAcknowledgementSent();
+ }
+
+ // Handle non-blocking macro requests (e.g. daemon.g)
+ if (gb->IsMacroRequestPending())
+ {
+ const char * const requestedMacroFile = gb->GetRequestedMacroFile();
+ bool fromCode = gb->IsMacroStartedByCode();
+ if (transfer.WriteMacroRequest(channel, requestedMacroFile, fromCode))
+ {
+ if (reprap.Debug(moduleSbcInterface))
+ {
+ debugPrintf("Requesting non-blocking macro file '%s' (fromCode: %s)\n", requestedMacroFile, fromCode ? "true" : "false");
+ }
+ gb->MacroRequestSent();
+ gb->Invalidate();
+ }
+ }
+
+ // Send pending firmware codes
+ if (gb->IsSendRequested() && transfer.WriteDoCode(channel, gb->DataStart(), gb->DataLength()))
+ {
+ gb->SetFinished(true);
+ }
+ }
+ }
+ }
+
+ // Send pause notification on demand
+ if (reportPause && transfer.WritePrintPaused(pauseFilePosition, pauseReason))
+ {
+ reportPause = false;
+ }
+}
+
+[[noreturn]] void SbcInterface::ReceiveAndStartIap(const char *iapChunk, size_t length) noexcept
+{
+ char *iapWritePointer = reinterpret_cast<char *>(IAP_IMAGE_START);
+ for(;;)
+ {
+ // Write the next IAP chunk
+ if (iapChunk != nullptr)
+ {
+ uint32_t *dst = reinterpret_cast<uint32_t *>(iapWritePointer);
+ const uint32_t *src = reinterpret_cast<const uint32_t *>(iapChunk);
+ memcpyu32(dst, src, length / sizeof(uint32_t));
+ iapWritePointer += length;
+ iapChunk = nullptr;
+ }
+
+ // Get the next IAP chunk
+ transfer.StartNextTransfer();
+ bool transferComplete = false;
+ do
+ {
+ switch (transfer.DoTransfer())
+ {
+#if SAME5x
+ case TransferState::connectionTimeout:
+#endif
+ case TransferState::connectionReset:
+ // Perform a firmware reset, we're in an unsafe state to resume regular operation
+ SoftwareReset(SoftwareResetReason::user);
+ break;
+ case TransferState::finished:
+ transferComplete = true;
+ break;
+ default:
+ // do nothing
+ break;
+ }
+ }
+ while (!transferComplete);
+
+ // Process only IAP-related packets
+ for (size_t i = 0; i < transfer.PacketsToRead(); i++)
+ {
+ const PacketHeader * const packet = transfer.ReadPacket();
+ switch ((SbcRequest)packet->request)
+ {
+ case SbcRequest::WriteIap: // Write another IAP chunk. It's always bound on a 4-byte boundary
+ {
+ iapChunk = transfer.ReadData(packet->length);
+ length = packet->length;
+ break;
+ }
+ case SbcRequest::StartIap: // Start the IAP binary
+ reprap.StartIap(nullptr);
+ break;
+ default: // Other packet types are not supported while IAP is being written
+ // do nothing
+ break;
+ }
+ }
+ }
+}
+
+void SbcInterface::InvalidateResources() noexcept
+{
+ rxPointer = txPointer = txEnd = 0;
+ sendBufferUpdate = true;
+
+ if (!requestedFileName.IsEmpty())
+ {
+ requestedFileDataLength = -1;
+ requestedFileSemaphore.Give();
+ }
+
+ if (fileOperation != FileOperation::none)
+ {
+ fileOperation = FileOperation::none;
+ fileSemaphore.Give();
+ }
+ MassStorage::InvalidateAllFiles();
+
+ // Don't cache any messages if they cannot be sent
+ {
+ MutexLocker lock(gcodeReplyMutex);
+ gcodeReply.ReleaseAll();
+ }
+
+ // Close all open G-code files
+ for (size_t i = 0; i < NumGCodeChannels; i++)
+ {
+ GCodeBuffer *gb = reprap.GetGCodes().GetGCodeBuffer(GCodeChannel(i));
+ if (gb->IsWaitingForMacro())
+ {
+ gb->ResolveMacroRequest(true, false);
+ }
+
+ MutexLocker locker(gb->mutex);
+ if (gb->IsMacroRequestPending())
+ {
+ gb->MacroRequestSent();
+ }
+ gb->AbortFile(true, false);
+ gb->MessageAcknowledged(true);
+ }
+
+ // Abort the print (if applicable)
+ printAborted = true;
+
+ // Turn off all the heaters
+ reprap.GetHeat().SwitchOffAll(true);
+}
+
+void SbcInterface::Diagnostics(MessageType mtype) noexcept
+{
+ reprap.GetPlatform().Message(mtype, "=== SBC interface ===\n");
+ transfer.Diagnostics(mtype);
+ reprap.GetPlatform().MessageF(mtype, "State: %d, disconnects: %" PRIu32 ", timeouts: %" PRIu32 ", IAP RAM available 0x%05" PRIx32 "\n", (int)state, numDisconnects, numTimeouts, iapRamAvailable);
+ reprap.GetPlatform().MessageF(mtype, "Buffer RX/TX: %d/%d-%d\n", (int)rxPointer, (int)txPointer, (int)txEnd);
+#ifdef TRACK_FILE_CODES
+ reprap.GetPlatform().MessageF(mtype, "File codes read/handled: %d/%d, file macros open/closing: %d %d\n", (int)fileCodesRead, (int)fileCodesHandled, (int)fileMacrosRunning, (int)fileMacrosClosing);
+#endif
+}
+
+GCodeResult SbcInterface::HandleM576(GCodeBuffer& gb, const StringRef& reply) noexcept
+{
+ bool seen = false;
+
+ if (gb.Seen('S'))
+ {
+ uint32_t sParam = gb.GetUIValue();
+ if (sParam > SpiConnectionTimeout)
+ {
+ reply.printf("SPI transfer delay must not exceed %" PRIu32 "ms", SpiConnectionTimeout);
+ return GCodeResult::error;
+ }
+ maxDelayBetweenTransfers = sParam;
+ seen = true;
+ }
+
+ if (gb.Seen('F'))
+ {
+ uint32_t fParam = gb.GetUIValue();
+ if (fParam > SpiConnectionTimeout)
+ {
+ reply.printf("SPI transfer delay must not exceed %" PRIu32 "ms", SpiConnectionTimeout);
+ return GCodeResult::error;
+ }
+ maxFileOpenDelay = fParam;
+ seen = true;
+ }
+
+ if (gb.Seen('P'))
+ {
+ numMaxEvents = gb.GetUIValue();
+ seen = true;
+ }
+
+ if (!seen)
+ {
+ reply.printf("Max transfer delay %" PRIu32 "ms, max number of events during delays: %" PRIu32, maxDelayBetweenTransfers, numMaxEvents);
+ }
+ return GCodeResult::ok;
+}
+
+bool SbcInterface::FillBuffer(GCodeBuffer &gb) noexcept
+{
+ if (gb.IsInvalidated() || gb.IsMacroFileClosed() || gb.IsMessageAcknowledged() ||
+ gb.IsAbortRequested() || (reportPause && gb.GetChannel() == GCodeChannel::File) ||
+ (gb.LatestMachineState().waitingForAcknowledgement && gb.IsMessagePromptPending()))
+ {
+ // Don't process codes that are supposed to be suspended...
+ return false;
+ }
+
+ bool gotCommand = false;
+ {
+ //TODO can we take the lock inside the loop body instead, if we re-read readPointer and writePointer after taking it?
+ TaskCriticalSectionLocker locker;
+ if (rxPointer != txPointer || txEnd != 0)
+ {
+ bool updateRxPointer = true;
+ uint16_t readPointer = rxPointer;
+ do
+ {
+ BufferedCodeHeader *bufHeader = reinterpret_cast<BufferedCodeHeader*>(codeBuffer + readPointer);
+ readPointer += sizeof(BufferedCodeHeader);
+ const CodeHeader *codeHeader = reinterpret_cast<const CodeHeader*>(codeBuffer + readPointer);
+ readPointer += bufHeader->length;
+
+ RRF_ASSERT(bufHeader->length > 0);
+ RRF_ASSERT(readPointer <= SpiCodeBufferSize);
+
+ if (bufHeader->isPending)
+ {
+ if (gb.GetChannel().RawValue() == codeHeader->channel)
+ {
+#ifdef TRACK_FILE_CODES
+ if (gb.GetChannel() == GCodeChannel::File && gb.GetCommandLetter() != 'Q')
+ {
+ fileMacrosRunning -= fileMacrosClosing;
+ fileMacrosClosing = 0;
+ if (fileCodesRead > fileCodesHandled + fileMacrosRunning)
+ {
+ // Note that we cannot use MessageF here because the task scheduler is suspended
+ OutputBuffer *buf;
+ if (OutputBuffer::Allocate(buf))
+ {
+ String<SHORT_GCODE_LENGTH> codeString;
+ gb.PrintCommand(codeString.GetRef());
+ buf->printf("Code %s did not return a code result, delta %d, running macros %d\n", codeString.c_str(), fileCodesRead - fileCodesHandled - fileMacrosRunning, fileMacrosRunning);
+ gcodeReply.Push(buf, WarningMessage);
+ }
+ fileCodesRead = fileCodesHandled - fileMacrosRunning;
+ }
+ fileCodesRead++;
+ }
+#endif
+
+ // Process the next binary G-code
+ gb.PutBinary(reinterpret_cast<const uint32_t *>(codeHeader), bufHeader->length / sizeof(uint32_t));
+ bufHeader->isPending = false;
+
+ // Check if we can reset the ring buffer pointers
+ if (updateRxPointer)
+ {
+ sendBufferUpdate = true;
+ if (readPointer == txPointer && txEnd == 0)
+ {
+ // Buffer completely read, reset RX/TX pointers
+ rxPointer = txPointer = 0;
+ }
+ else if (readPointer == txEnd)
+ {
+ // Read last code before overlapping, restart from the beginning
+ rxPointer = txEnd = 0;
+ }
+ else
+ {
+ // Code has been read, move on to the next one
+ rxPointer = readPointer;
+ }
+ }
+
+ gotCommand = true;
+ break;
+ }
+ updateRxPointer = false;
+ }
+
+ if (readPointer == txEnd)
+ {
+ if (updateRxPointer)
+ {
+ // Skipped non-pending codes, restart from the beginning
+ rxPointer = txEnd = 0;
+ }
+
+ // About to overlap, continue from the start
+ readPointer = 0;
+ }
+ } while (readPointer != txPointer);
+ }
+ }
+
+ if (gotCommand)
+ {
+ gb.DecodeCommand();
+ return true;
+ }
+ return false;
+}
+
+bool SbcInterface::FileExists(const char *filename) noexcept
+{
+ // Don't do anything if the SBC is not connected
+ if (!IsConnected())
+ {
+ return false;
+ }
+
+ // Set up the request content
+ MutexLocker locker(fileMutex);
+ filePath = filename;
+ fileOperation = FileOperation::checkFileExists;
+ fileOperationPending = true;
+
+ // Let the SBC task process this request as quickly as possible
+ if (delaying)
+ {
+ delaying = false;
+ sbcTask->Give();
+ }
+ fileSemaphore.Take();
+
+ // Return the result
+ return fileSuccess;
+}
+
+bool SbcInterface::DeleteFileOrDirectory(const char *fileOrDirectory) noexcept
+{
+ // Don't do anything if the SBC is not connected
+ if (!IsConnected())
+ {
+ return false;
+ }
+
+ // Set up the request content
+ MutexLocker locker(fileMutex);
+ filePath = fileOrDirectory;
+ fileOperation = FileOperation::deleteFileOrDirectory;
+ fileOperationPending = true;
+
+ // Let the SBC task process this request as quickly as possible
+ if (delaying)
+ {
+ delaying = false;
+ sbcTask->Give();
+ }
+ fileSemaphore.Take();
+
+ // Return the result
+ return fileSuccess;
+}
+
+FileHandle SbcInterface::OpenFile(const char *filename, OpenMode mode, FilePosition& fileLength, uint32_t preAllocSize) noexcept
+{
+ // Don't do anything if the SBC is not connected
+ if (!IsConnected())
+ {
+ return false;
+ }
+
+ // Set up the request content
+ MutexLocker locker(fileMutex);
+ filePath = filename;
+ filePreAllocSize = preAllocSize;
+ switch (mode)
+ {
+ case OpenMode::read:
+ fileOperation = FileOperation::openRead;
+ break;
+
+ case OpenMode::write:
+ case OpenMode::writeWithCrc:
+ fileOperation = FileOperation::openWrite;
+ break;
+
+ case OpenMode::append:
+ fileOperation = FileOperation::openAppend;
+ break;
+
+ default:
+ filePath = nullptr;
+ REPORT_INTERNAL_ERROR;
+ break;
+ }
+ fileOperationPending = true;
+
+ // Let the SBC task process this request as quickly as possible
+ if (delaying)
+ {
+ delaying = false;
+ sbcTask->Give();
+ }
+ fileSemaphore.Take();
+
+ // Update the file length and return the handle
+ fileLength = fileOffset;
+ return fileHandle;
+}
+
+int SbcInterface::ReadFile(FileHandle handle, char *buffer, size_t bufferLength) noexcept
+{
+ // Don't do anything if the SBC is not connected
+ if (!IsConnected())
+ {
+ return false;
+ }
+
+ // Set up the request content
+ MutexLocker locker(fileMutex);
+ fileHandle = handle;
+ fileReadBuffer = buffer;
+ fileBufferLength = bufferLength;
+ fileOperation = FileOperation::read;
+ fileOperationPending = true;
+
+ // Let the SBC task process this request as quickly as possible
+ if (delaying)
+ {
+ delaying = false;
+ sbcTask->Give();
+ }
+ fileSemaphore.Take();
+;
+
+ // Return the number of bytes read
+ return fileSuccess ? (int)fileOffset : -1;
+}
+
+bool SbcInterface::WriteFile(FileHandle handle, const char *buffer, size_t bufferLength) noexcept
+{
+ // Don't do anything if the SBC is not connected
+ if (!IsConnected())
+ {
+ return false;
+ }
+
+ // Set up the request content
+ MutexLocker locker(fileMutex);
+ fileHandle = handle;
+ fileWriteBuffer = buffer;
+ fileBufferLength = bufferLength;
+ fileOperation = FileOperation::write;
+ fileOperationPending = true;
+
+ // Let the SBC task process this request as quickly as possible
+ if (delaying)
+ {
+ delaying = false;
+ sbcTask->Give();
+ }
+ fileSemaphore.Take();
+
+ // Return the result
+ return fileSuccess;
+}
+
+bool SbcInterface::SeekFile(FileHandle handle, FilePosition offset) noexcept
+{
+ // Don't do anything if the SBC is not connected
+ if (!IsConnected())
+ {
+ return false;
+ }
+
+ // Set up the request content
+ MutexLocker locker(fileMutex);
+ fileHandle = handle;
+ fileOffset = offset;
+ fileOperation = FileOperation::seek;
+ fileOperationPending = true;
+
+ // Let the SBC task process this request as quickly as possible
+ if (delaying)
+ {
+ delaying = false;
+ sbcTask->Give();
+ }
+ fileSemaphore.Take();
+
+ // Return the result
+ return fileSuccess;
+}
+
+bool SbcInterface::TruncateFile(FileHandle handle) noexcept
+{
+ // Don't do anything if the SBC is not connected
+ if (!IsConnected())
+ {
+ return false;
+ }
+
+ // Set up the request content
+ MutexLocker locker(fileMutex);
+ fileHandle = handle;
+ fileOperation = FileOperation::truncate;
+ fileOperationPending = true;
+
+ // Let the SBC task process this request as quickly as possible
+ if (delaying)
+ {
+ delaying = false;
+ sbcTask->Give();
+ }
+ fileSemaphore.Take();
+
+ // Return the result
+ return fileSuccess;
+}
+
+void SbcInterface::CloseFile(FileHandle handle) noexcept
+{
+ // Don't do anything if the SBC is not connected
+ if (!IsConnected())
+ {
+ return;
+ }
+
+ // Set up the request content
+ MutexLocker locker(fileMutex);
+ fileHandle = handle;
+ fileOperation = FileOperation::close;
+ fileOperationPending = true;
+
+ // Let the SBC task process this request as quickly as possible
+ if (delaying)
+ {
+ delaying = false;
+ sbcTask->Give();
+ }
+ fileSemaphore.Take();
+}
+
+void SbcInterface::HandleGCodeReply(MessageType mt, const char *reply) noexcept
+{
+ if (!IsConnected())
+ {
+ return;
+ }
+
+#ifdef TRACK_FILE_CODES
+ if ((mt & (1 << GCodeChannel::File)) != 0)
+ {
+ fileCodesHandled++;
+ }
+#endif
+
+ MutexLocker lock(gcodeReplyMutex);
+ OutputBuffer *buffer = gcodeReply.GetLastItem();
+ if (buffer != nullptr && mt == gcodeReply.GetLastItemType() && (mt & PushFlag) != 0 && !buffer->IsReferenced())
+ {
+ // Try to save some space by combining segments that have the Push flag set
+ buffer->cat(reply);
+ }
+ else if (reply[0] != 0 && OutputBuffer::Allocate(buffer))
+ {
+ // Attempt to allocate one G-code buffer per non-empty output message
+ buffer->cat(reply);
+ gcodeReply.Push(buffer, mt);
+ }
+ else
+ {
+ // Store nullptr to indicate an empty response. This way many OutputBuffer references can be saved
+ gcodeReply.Push(nullptr, mt);
+ }
+ EventOccurred();
+}
+
+void SbcInterface::HandleGCodeReply(MessageType mt, OutputBuffer *buffer) noexcept
+{
+ if (!IsConnected())
+ {
+ OutputBuffer::ReleaseAll(buffer);
+ return;
+ }
+
+#ifdef TRACK_FILE_CODES
+ if ((mt & (1 << GCodeChannel::File)) != 0)
+ {
+ fileCodesHandled++;
+ }
+#endif
+
+ MutexLocker lock(gcodeReplyMutex);
+ gcodeReply.Push(buffer, mt);
+ EventOccurred();
+}
+
+// Read a file chunk from the SBC. When a response has been received, the current task is woken up again.
+// It changes bufferLength to the number of received bytes
+// This method returns true on success and false if an error occurred (e.g. file not found)
+bool SbcInterface::GetFileChunk(const char *filename, uint32_t offset, char *buffer, uint32_t& bufferLength, uint32_t& fileLength) noexcept
+{
+ if (waitingForFileChunk)
+ {
+ reprap.GetPlatform().Message(ErrorMessage, "Trying to request a file chunk from two independent tasks\n");
+ bufferLength = fileLength = 0;
+ return false;
+ }
+
+ fileChunkRequestSent = false;
+ requestedFileName.copy(filename);
+ requestedFileLength = bufferLength;
+ requestedFileOffset = offset;
+ requestedFileBuffer = buffer;
+
+ waitingForFileChunk = true;
+ requestedFileSemaphore.Take();
+
+ waitingForFileChunk = false;
+ if (requestedFileDataLength < 0)
+ {
+ bufferLength = fileLength = 0;
+ return false;
+ }
+ bufferLength = requestedFileDataLength;
+ fileLength = requestedFileLength;
+ return true;
+}
+
+void SbcInterface::EventOccurred(bool timeCritical) noexcept
+{
+ if (!IsConnected())
+ {
+ return;
+ }
+
+ // Increment the number of events
+ if (timeCritical)
+ {
+ numEvents = numMaxEvents;
+ }
+ else
+ {
+ numEvents++;
+ }
+
+ // Stop delaying if the next transfer is time-critical
+ if (delaying && numEvents >= numMaxEvents)
+ {
+ delaying = false;
+ sbcTask->Give();
+ }
+}
+
+void SbcInterface::InvalidateBufferedCodes(GCodeChannel channel) noexcept
+{
+ TaskCriticalSectionLocker locker;
+ if (rxPointer != txPointer || txEnd != 0)
+ {
+ bool updateRxPointer = true;
+ uint16_t readPointer = rxPointer;
+ do
+ {
+ BufferedCodeHeader *bufHeader = reinterpret_cast<BufferedCodeHeader *>(codeBuffer + readPointer);
+ if (bufHeader->isPending)
+ {
+ const CodeHeader *codeHeader = reinterpret_cast<const CodeHeader*>(codeBuffer + readPointer + sizeof(BufferedCodeHeader));
+ if (codeHeader->channel == channel.RawValue())
+ {
+ bufHeader->isPending = false;
+ }
+ else
+ {
+ updateRxPointer = false;
+ }
+ }
+ readPointer += sizeof(BufferedCodeHeader) + bufHeader->length;
+
+ if (updateRxPointer)
+ {
+ sendBufferUpdate = true;
+ if (readPointer == txPointer && txEnd == 0)
+ {
+ // Buffer is empty again, reset the pointers
+ rxPointer = txPointer = 0;
+ break;
+ }
+ else if (readPointer == txEnd)
+ {
+ // Invalidated last code before overlapping, continue from the beginning
+ readPointer = 0;
+ rxPointer = txEnd = 0;
+ }
+ else
+ {
+ // Invalidated next code
+ rxPointer = readPointer;
+ }
+ }
+ else if (readPointer == txEnd)
+ {
+ // About to overlap, continue from the start
+ readPointer = 0;
+ }
+ } while (readPointer != txPointer);
+ }
+}
+
+#endif
diff --git a/src/Linux/LinuxInterface.h b/src/SBC/SbcInterface.h
index 6629de24..7e0c7805 100644
--- a/src/Linux/LinuxInterface.h
+++ b/src/SBC/SbcInterface.h
@@ -1,23 +1,23 @@
/*
- * LinuxInterface.h
+ * SbcInterface.h
*
* Created on: 29 Mar 2019
* Authors: Christian
*/
-#ifndef SRC_LINUX_LINUXINTERFACE_H_
-#define SRC_LINUX_LINUXINTERFACE_H_
+#ifndef SRC_SBC_SBCINTERFACE_H_
+#define SRC_SBC_SBCINTERFACE_H_
#include <RepRapFirmware.h>
-#if HAS_LINUX_INTERFACE
+#if HAS_SBC_INTERFACE
#include "RTOSIface/RTOSIface.h"
#include "GCodes/GCodes.h"
#include "GCodes/GCodeChannel.h"
#include "GCodes/GCodeFileInfo.h"
-#include "LinuxMessageFormats.h"
+#include "SbcMessageFormats.h"
#include "DataTransfer.h"
class Platform;
@@ -30,18 +30,17 @@ class OutputStack;
//#define TRACK_FILE_CODES // Uncomment this to enable code <-> code reply tracking for the file G-code channel
// G-Code input class for an SPI channel
-class LinuxInterface
+class SbcInterface
{
public:
- LinuxInterface() noexcept;
+ SbcInterface() noexcept;
- // The Init method must be called prior to calling any of the other methods. Use reprap.UsingLinuxInterface() to guard calls to other members.
+ // The Init method must be called prior to calling any of the other methods. Use reprap.UsingSbcInterface() to guard calls to other members.
// OTOH, calling Init when we don't have a SBC connected may cause problems due to noise pickup on the SPI CS and clock inputs
void Init() noexcept;
void Spin() noexcept; // Only called in standalone mode by the main loop
[[noreturn]] void TaskLoop() noexcept;
void Diagnostics(MessageType mtype) noexcept;
- bool IsWritingIap() const noexcept { return writingIap; }
bool IsConnected() const noexcept { return isConnected; }
void EventOccurred(bool timeCritical = false) noexcept; // Called when a new event has happened. It can optionally start off a new transfer immediately
@@ -71,10 +70,12 @@ public:
private:
DataTransfer transfer;
- bool isConnected;
+ volatile bool isConnected;
+ TransferState state;
uint32_t numDisconnects, numTimeouts;
uint32_t maxDelayBetweenTransfers, maxFileOpenDelay, numMaxEvents;
+ bool skipNextDelay;
volatile bool delaying;
volatile uint32_t numEvents;
@@ -87,8 +88,6 @@ private:
volatile uint16_t rxPointer, txPointer, txEnd;
volatile bool sendBufferUpdate;
- bool writingIap;
- uint32_t iapWritePointer;
uint32_t iapRamAvailable; // must be at least 32Kb otherwise the SPI IAP can't work
// Data needed when a CAN expansion board requests a firmware file chunk
@@ -130,16 +129,19 @@ private:
FilePosition fileOffset;
static volatile OutputStack gcodeReply;
- static Mutex gcodeReplyMutex; // static so that the LinuxInterface is safe to delete even is the mutex is linked into the mutex chain or is in use
+ static Mutex gcodeReplyMutex; // static so that the SbcInterface is safe to delete even is the mutex is linked into the mutex chain or is in use
#ifdef TRACK_FILE_CODES
volatile size_t fileCodesRead, fileCodesHandled, fileMacrosRunning, fileMacrosClosing;
#endif
- void InvalidateBufferedCodes(GCodeChannel channel) noexcept; // Invalidate every buffered G-code of the corresponding channel from the buffer ring
+ void ExchangeData() noexcept; // Exchange data between RRF and the SBC
+ [[noreturn]] void ReceiveAndStartIap(const char *iapChunk, size_t length) noexcept; // Receive and start the IAP binary
+ void InvalidateResources() noexcept; // Invalidate local resources on connection errors
+ void InvalidateBufferedCodes(GCodeChannel channel) noexcept; // Invalidate every buffered G-code of the corresponding channel from the buffer ring
};
-inline void LinuxInterface::SetPauseReason(FilePosition position, PrintPausedReason reason) noexcept
+inline void SbcInterface::SetPauseReason(FilePosition position, PrintPausedReason reason) noexcept
{
TaskCriticalSectionLocker locker;
pauseFilePosition = position;
@@ -147,7 +149,7 @@ inline void LinuxInterface::SetPauseReason(FilePosition position, PrintPausedRea
reportPauseWritten = false;
}
-inline void LinuxInterface::SetEmergencyPauseReason(FilePosition position, PrintPausedReason reason) noexcept
+inline void SbcInterface::SetEmergencyPauseReason(FilePosition position, PrintPausedReason reason) noexcept
{
pauseFilePosition = position;
pauseReason = reason;
@@ -155,12 +157,12 @@ inline void LinuxInterface::SetEmergencyPauseReason(FilePosition position, Print
reportPause = true;
}
-inline void LinuxInterface::ReportPause() noexcept
+inline void SbcInterface::ReportPause() noexcept
{
reportPause = true;
}
-inline bool LinuxInterface::IsPrintAborted() noexcept
+inline bool SbcInterface::IsPrintAborted() noexcept
{
TaskCriticalSectionLocker locker;
if (printAborted)
diff --git a/src/Linux/LinuxMessageFormats.h b/src/SBC/SbcMessageFormats.h
index 725724f9..11991fb7 100644
--- a/src/Linux/LinuxMessageFormats.h
+++ b/src/SBC/SbcMessageFormats.h
@@ -1,14 +1,14 @@
/*
- * MessageFormats.h
+ * SbcMessageFormats.h
*
* Created on: 29 Mar 2019
* Author: Christian
*/
-#ifndef SRC_LINUX_MESSAGEFORMATS_H_
-#define SRC_LINUX_MESSAGEFORMATS_H_
+#ifndef SRC_SBC_MESSAGEFORMATS_H_
+#define SRC_SBC_MESSAGEFORMATS_H_
-#if HAS_LINUX_INTERFACE
+#if HAS_SBC_INTERFACE
#include <cstddef>
#include <cstdint>
@@ -16,14 +16,14 @@
#include <RepRapFirmware.h>
-constexpr uint8_t LinuxFormatCode = 0x5F; // standard format code for RRF SPI protocol
-constexpr uint8_t LinuxFormatCodeStandalone = 0x60; // used to indicate that RRF is running in stand-alone mode
+constexpr uint8_t SbcFormatCode = 0x5F; // standard format code for RRF SPI protocol
+constexpr uint8_t SbcFormatCodeStandalone = 0x60; // used to indicate that RRF is running in stand-alone mode
constexpr uint8_t InvalidFormatCode = 0xC9; // must be different from any other format code
-constexpr uint16_t LinuxProtocolVersion = 6;
+constexpr uint16_t SbcProtocolVersion = 6;
-constexpr size_t LinuxTransferBufferSize = 8192; // maximum length of a data transfer. Must be a multiple of 4 and kept in sync with Duet Control Server!
-static_assert(LinuxTransferBufferSize % sizeof(uint32_t) == 0, "LinuxTransferBufferSize must be a whole number of dwords");
+constexpr size_t SbcTransferBufferSize = 8192; // maximum length of a data transfer. Must be a multiple of 4 and kept in sync with Duet Control Server!
+static_assert(SbcTransferBufferSize % sizeof(uint32_t) == 0, "SbcTransferBufferSize must be a whole number of dwords");
constexpr size_t MaxCodeBufferSize = 256; // maximum length of a G/M/T-code in binary encoding
static_assert(MaxCodeBufferSize % sizeof(uint32_t) == 0, "MaxCodeBufferSize must be a whole number of dwords");
@@ -34,6 +34,7 @@ constexpr uint32_t SpiEventsRequired = 4; // number of events required to happ
constexpr uint32_t SpiMacroRequestTimeout = 3000; // maximum time to wait a macro file
constexpr uint32_t SpiTransferTimeout = 500; // maximum allowed delay between data exchanges during a full transfer (in ms)
+constexpr uint32_t SpiMaxTransferTime = 50; // maximum allowed time for a single SPI transfer
constexpr uint32_t SpiConnectionTimeout = 4000; // maximum time to wait for the next transfer (in ms)
constexpr uint16_t SpiCodeBufferSize = 4096; // number of bytes available for G-code caching
@@ -121,7 +122,7 @@ enum TransferResponse : uint32_t
BadResponse = 0xFEFEFEFE
};
-// RepRapFirmware to Linux
+// RepRapFirmware to Sbc
struct AbortFileHeader
{
uint8_t channel;
@@ -245,8 +246,8 @@ struct PrintPausedHeader
uint16_t paddingB;
};
-// Linux to RepRapFirmware
-enum class LinuxRequest : uint16_t
+// Sbc to RepRapFirmware
+enum class SbcRequest : uint16_t
{
EmergencyStop = 0, // Perform immediate emergency stop
Reset = 1, // Reset the controller
@@ -419,4 +420,4 @@ struct SetVariableHeader
#endif
-#endif /* SRC_LINUX_MESSAGEFORMATS_H_ */
+#endif /* SRC_SBC_MESSAGEFORMATS_H_ */
diff --git a/src/Storage/FileData.h b/src/Storage/FileData.h
index 14e4c900..ca2a000f 100644
--- a/src/Storage/FileData.h
+++ b/src/Storage/FileData.h
@@ -79,7 +79,7 @@ public:
return f->Read(buf, nBytes);
}
-# if HAS_MASS_STORAGE || HAS_LINUX_INTERFACE
+# if HAS_MASS_STORAGE || HAS_SBC_INTERFACE
bool Write(char b) noexcept
{
return f->Write(b);
diff --git a/src/Storage/FileStore.cpp b/src/Storage/FileStore.cpp
index a4a21c91..031d1716 100644
--- a/src/Storage/FileStore.cpp
+++ b/src/Storage/FileStore.cpp
@@ -2,7 +2,7 @@
#include "RepRapFirmware.h"
-#if HAS_MASS_STORAGE || HAS_LINUX_INTERFACE || HAS_EMBEDDED_FILES
+#if HAS_MASS_STORAGE || HAS_SBC_INTERFACE || HAS_EMBEDDED_FILES
#include <Platform/RepRap.h>
#include <Platform/Platform.h>
@@ -18,12 +18,12 @@
# include <Movement/StepTimer.h>
#endif
-#if HAS_LINUX_INTERFACE
-# include <Linux/LinuxInterface.h>
+#if HAS_SBC_INTERFACE
+# include <SBC/SbcInterface.h>
#endif
FileStore::FileStore() noexcept
-#if HAS_MASS_STORAGE || HAS_LINUX_INTERFACE
+#if HAS_MASS_STORAGE || HAS_SBC_INTERFACE
: writeBuffer(nullptr)
#endif
{
@@ -40,11 +40,11 @@ void FileStore::Init() noexcept
#if HAS_EMBEDDED_FILES
fileIndex = -1;
#endif
-#if HAS_LINUX_INTERFACE
+#if HAS_SBC_INTERFACE
handle = noFileHandle;
length = 0;
#endif
-#if HAS_EMBEDDED_FILES || HAS_LINUX_INTERFACE
+#if HAS_EMBEDDED_FILES || HAS_SBC_INTERFACE
offset = 0;
#endif
}
@@ -55,8 +55,8 @@ bool FileStore::Open(const char* filePath, OpenMode mode, uint32_t preAllocSize)
{
const bool writing = (mode == OpenMode::write || mode == OpenMode::writeWithCrc || mode == OpenMode::append);
#if HAS_EMBEDDED_FILES
-# if HAS_LINUX_INTERFACE
- if (!reprap.UsingLinuxInterface())
+# if HAS_SBC_INTERFACE
+ if (!reprap.UsingSbcInterface())
# endif
{
if (!writing)
@@ -81,7 +81,7 @@ bool FileStore::Open(const char* filePath, OpenMode mode, uint32_t preAllocSize)
}
#endif
-#if HAS_MASS_STORAGE || HAS_LINUX_INTERFACE
+#if HAS_MASS_STORAGE || HAS_SBC_INTERFACE
writeBuffer = nullptr;
// Try to allocate a write buffer
@@ -106,10 +106,10 @@ bool FileStore::Open(const char* filePath, OpenMode mode, uint32_t preAllocSize)
// Attempt to open the file
bool fileOpened = false;
-# if HAS_LINUX_INTERFACE
- if (reprap.UsingLinuxInterface())
+# if HAS_SBC_INTERFACE
+ if (reprap.UsingSbcInterface())
{
- handle = reprap.GetLinuxInterface().OpenFile(filePath, mode, length, preAllocSize);
+ handle = reprap.GetSbcInterface().OpenFile(filePath, mode, length, preAllocSize);
if (handle != noFileHandle)
{
offset = (mode == OpenMode::append) ? length : 0;
@@ -180,7 +180,7 @@ bool FileStore::Open(const char* filePath, OpenMode mode, uint32_t preAllocSize)
#endif
}
-#if HAS_MASS_STORAGE || HAS_LINUX_INTERFACE || HAS_EMBEDDED_FILES
+#if HAS_MASS_STORAGE || HAS_SBC_INTERFACE || HAS_EMBEDDED_FILES
// This may be called from an ISR, in which case we need to defer the close
bool FileStore::Close() noexcept
@@ -245,10 +245,10 @@ bool FileStore::Seek(FilePosition pos) noexcept
case FileUseMode::readOnly:
case FileUseMode::readWrite:
-#if HAS_LINUX_INTERFACE
- if (reprap.UsingLinuxInterface())
+#if HAS_SBC_INTERFACE
+ if (reprap.UsingSbcInterface())
{
- if (reprap.GetLinuxInterface().SeekFile(handle, pos))
+ if (reprap.GetSbcInterface().SeekFile(handle, pos))
{
offset = pos;
return true;
@@ -273,8 +273,8 @@ bool FileStore::Seek(FilePosition pos) noexcept
FilePosition FileStore::Position() const noexcept
{
-#if HAS_LINUX_INTERFACE
- if (reprap.UsingLinuxInterface())
+#if HAS_SBC_INTERFACE
+ if (reprap.UsingSbcInterface())
{
return offset;
}
@@ -297,8 +297,8 @@ FilePosition FileStore::Length() const noexcept
return 0;
case FileUseMode::readOnly:
-#if HAS_LINUX_INTERFACE
- if (reprap.UsingLinuxInterface())
+#if HAS_SBC_INTERFACE
+ if (reprap.UsingSbcInterface())
{
return length;
}
@@ -312,8 +312,8 @@ FilePosition FileStore::Length() const noexcept
#endif
case FileUseMode::readWrite:
-#if HAS_LINUX_INTERFACE
- if (reprap.UsingLinuxInterface())
+#if HAS_SBC_INTERFACE
+ if (reprap.UsingSbcInterface())
{
return (writeBuffer != nullptr) ? length + writeBuffer->BytesStored() : length;
}
@@ -332,7 +332,7 @@ FilePosition FileStore::Length() const noexcept
#endif
-#if HAS_MASS_STORAGE || HAS_LINUX_INTERFACE
+#if HAS_MASS_STORAGE || HAS_SBC_INTERFACE
// Truncate file at current file pointer
bool FileStore::Truncate() noexcept
@@ -349,11 +349,11 @@ bool FileStore::Truncate() noexcept
{
return false;
}
-#if HAS_LINUX_INTERFACE
- if (reprap.UsingLinuxInterface())
+#if HAS_SBC_INTERFACE
+ if (reprap.UsingSbcInterface())
{
length = offset;
- return reprap.GetLinuxInterface().TruncateFile(handle);
+ return reprap.GetSbcInterface().TruncateFile(handle);
}
#endif
#if HAS_MASS_STORAGE
@@ -370,7 +370,7 @@ bool FileStore::Truncate() noexcept
#endif
-#if HAS_MASS_STORAGE || HAS_LINUX_INTERFACE || HAS_EMBEDDED_FILES
+#if HAS_MASS_STORAGE || HAS_SBC_INTERFACE || HAS_EMBEDDED_FILES
// Returns the number of bytes read or -1 if the read process failed
int FileStore::Read(char* extBuf, size_t nBytes) noexcept
@@ -383,10 +383,10 @@ int FileStore::Read(char* extBuf, size_t nBytes) noexcept
case FileUseMode::readOnly:
case FileUseMode::readWrite:
-#if HAS_LINUX_INTERFACE
- if (reprap.UsingLinuxInterface())
+#if HAS_SBC_INTERFACE
+ if (reprap.UsingSbcInterface())
{
- int bytesRead = reprap.GetLinuxInterface().ReadFile(handle, extBuf, nBytes);
+ int bytesRead = reprap.GetSbcInterface().ReadFile(handle, extBuf, nBytes);
if (bytesRead > 0)
{
offset += bytesRead;
@@ -461,7 +461,7 @@ int FileStore::ReadLine(char* buf, size_t nBytes) noexcept
bool FileStore::ForceClose() noexcept
{
-#if HAS_MASS_STORAGE || HAS_LINUX_INTERFACE
+#if HAS_MASS_STORAGE || HAS_SBC_INTERFACE
bool ok = true;
if (usageMode == FileUseMode::readWrite)
{
@@ -475,10 +475,10 @@ bool FileStore::ForceClose() noexcept
}
#endif
-#if HAS_LINUX_INTERFACE
- if (reprap.UsingLinuxInterface())
+#if HAS_SBC_INTERFACE
+ if (reprap.UsingSbcInterface())
{
- reprap.GetLinuxInterface().CloseFile(handle);
+ reprap.GetSbcInterface().CloseFile(handle);
handle = noFileHandle;
offset = length = 0;
usageMode = FileUseMode::free;
@@ -530,7 +530,7 @@ void FileStore::Duplicate() noexcept
#endif
-#if HAS_MASS_STORAGE || HAS_LINUX_INTERFACE
+#if HAS_MASS_STORAGE || HAS_SBC_INTERFACE
bool FileStore::Store(const char *s, size_t len, size_t *bytesWritten) noexcept
{
@@ -539,10 +539,10 @@ bool FileStore::Store(const char *s, size_t len, size_t *bytesWritten) noexcept
crc.Update(s, len);
}
-#if HAS_LINUX_INTERFACE
- if (reprap.UsingLinuxInterface())
+#if HAS_SBC_INTERFACE
+ if (reprap.UsingSbcInterface())
{
- bool ok = (len > 0) ? reprap.GetLinuxInterface().WriteFile(handle, s, len) : true;
+ bool ok = (len > 0) ? reprap.GetSbcInterface().WriteFile(handle, s, len) : true;
*bytesWritten = ok ? len : 0;
offset += len;
if (offset > length)
@@ -658,8 +658,8 @@ bool FileStore::Flush() noexcept
return writeOk && (bytesToWrite == bytesWritten);
}
}
-#if HAS_LINUX_INTERFACE
- if (reprap.UsingLinuxInterface())
+#if HAS_SBC_INTERFACE
+ if (reprap.UsingSbcInterface())
{
return true;
}
@@ -674,7 +674,7 @@ bool FileStore::Flush() noexcept
}
}
-#if HAS_LINUX_INTERFACE // these functions are only supported in SBC mode
+#if HAS_SBC_INTERFACE // these functions are only supported in SBC mode
// Invalidate the file
void FileStore::Invalidate() noexcept
@@ -770,7 +770,7 @@ bool FileStore::SetClusterMap(uint32_t tbl[]) noexcept
#endif
-#endif // HAS_MASS_STORAGE || HAS_LINUX_INTERFACE
+#endif // HAS_MASS_STORAGE || HAS_SBC_INTERFACE
#endif
diff --git a/src/Storage/FileStore.h b/src/Storage/FileStore.h
index 683ed914..2588180c 100644
--- a/src/Storage/FileStore.h
+++ b/src/Storage/FileStore.h
@@ -7,7 +7,7 @@
#if HAS_MASS_STORAGE
# include "Libraries/Fatfs/ff.h"
#endif
-#if HAS_MASS_STORAGE || HAS_LINUX_INTERFACE
+#if HAS_MASS_STORAGE || HAS_SBC_INTERFACE
# include "CRC32.h"
#endif
@@ -18,7 +18,7 @@ class FileWriteBuffer;
typedef int32_t FileIndex;
#endif
-#if HAS_MASS_STORAGE || HAS_LINUX_INTERFACE || HAS_EMBEDDED_FILES
+#if HAS_MASS_STORAGE || HAS_SBC_INTERFACE || HAS_EMBEDDED_FILES
enum class OpenMode : uint8_t
{
@@ -59,7 +59,7 @@ public:
FilePosition Position() const noexcept; // Return the current position in the file, assuming we are reading the file
void Duplicate() noexcept; // Create a second reference to this file
-#if HAS_MASS_STORAGE || HAS_LINUX_INTERFACE
+#if HAS_MASS_STORAGE || HAS_SBC_INTERFACE
FileWriteBuffer *GetWriteBuffer() const noexcept; // Return a pointer to the remaining space for writing
bool Write(char b) noexcept; // Write 1 byte
bool Write(const char *s, size_t len) noexcept; // Write a block of len bytes
@@ -70,7 +70,7 @@ public:
uint32_t GetCRC32() const noexcept;
#endif
-#if HAS_LINUX_INTERFACE
+#if HAS_SBC_INTERFACE
void Invalidate() noexcept; // Invalidate the file
#endif
@@ -94,7 +94,7 @@ private:
volatile unsigned int openCount;
-#if HAS_MASS_STORAGE || HAS_LINUX_INTERFACE
+#if HAS_MASS_STORAGE || HAS_SBC_INTERFACE
FileWriteBuffer *writeBuffer;
CRC32 crc;
#endif
@@ -104,7 +104,7 @@ private:
static uint32_t longestWriteTime;
#endif
-#if HAS_LINUX_INTERFACE
+#if HAS_SBC_INTERFACE
FileHandle handle;
FilePosition length;
#endif
@@ -113,19 +113,19 @@ private:
FileIndex fileIndex;
#endif
-#if HAS_EMBEDDED_FILES || HAS_LINUX_INTERFACE
+#if HAS_EMBEDDED_FILES || HAS_SBC_INTERFACE
FilePosition offset;
#endif
volatile bool closeRequested;
FileUseMode usageMode;
-#if HAS_MASS_STORAGE || HAS_LINUX_INTERFACE
+#if HAS_MASS_STORAGE || HAS_SBC_INTERFACE
bool calcCrc;
#endif
};
-#if HAS_MASS_STORAGE || HAS_LINUX_INTERFACE
+#if HAS_MASS_STORAGE || HAS_SBC_INTERFACE
inline FileWriteBuffer *FileStore::GetWriteBuffer() const noexcept { return writeBuffer; }
@@ -138,6 +138,6 @@ inline uint32_t FileStore::GetCRC32() const noexcept
#endif
-#endif // HAS_MASS_STORAGE || HAS_LINUX_INTERFACE || HAS_EMBEDDED_FILES
+#endif // HAS_MASS_STORAGE || HAS_SBC_INTERFACE || HAS_EMBEDDED_FILES
#endif // #ifndef FILESTORE_H
diff --git a/src/Storage/FileWriteBuffer.h b/src/Storage/FileWriteBuffer.h
index 27fe9d5d..26f05fa4 100644
--- a/src/Storage/FileWriteBuffer.h
+++ b/src/Storage/FileWriteBuffer.h
@@ -13,23 +13,23 @@
#if SAM4E || SAM4S || SAME70 || SAME5x
constexpr size_t NumFileWriteBuffers = 2; // Number of write buffers
constexpr size_t FileWriteBufLen = 8192; // Size of each write buffer
-constexpr size_t LinuxFileWriteBufLen = 4192; // Available size of each write buffer in SBC mode
+constexpr size_t SbcFileWriteBufLen = 4192; // Available size of each write buffer in SBC mode
#elif defined(__LPC17xx__)
# if HAS_WIFI_NETWORKING
constexpr size_t NumFileWriteBuffers = 1;
constexpr size_t FileWriteBufLen = 1024;
-constexpr size_t LinuxFileWriteBufLen = 768;
+constexpr size_t SbcFileWriteBufLen = 768;
# else
constexpr size_t NumFileWriteBuffers = 1;
constexpr size_t FileWriteBufLen = 512;
-constexpr size_t LinuxFileWriteBufLen = 468;
+constexpr size_t SbcFileWriteBufLen = 468;
# endif
#else
constexpr size_t NumFileWriteBuffers = 1;
constexpr size_t FileWriteBufLen = 4096;
-constexpr size_t LinuxFileWriteBufLen = 3072;
+constexpr size_t SbcFileWriteBufLen = 3072;
#endif
-static_assert(FileWriteBufLen >= LinuxFileWriteBufLen, "File write buffer must be at least as big as the configured Linux threshold");
+static_assert(FileWriteBufLen >= SbcFileWriteBufLen, "File write buffer must be at least as big as the configured SBC threshold");
// Class to cache data that is about to be written to the SD card. This is NOT a ring buffer,
// instead it just provides simple interfaces to cache a certain amount of data so that fewer
@@ -42,7 +42,7 @@ public:
#else
FileWriteBuffer(FileWriteBuffer *n) noexcept : next(n), index(0) { }
#endif
- static void UsingSbcMode() { fileWriteBufLen = LinuxFileWriteBufLen; } // only called by RepRap on startup
+ static void UsingSbcMode() { fileWriteBufLen = SbcFileWriteBufLen; } // only called by RepRap on startup
FileWriteBuffer *Next() const noexcept { return next; }
void SetNext(FileWriteBuffer *n) noexcept { next = n; }
diff --git a/src/Storage/MassStorage.cpp b/src/Storage/MassStorage.cpp
index c9705e07..4c95caa8 100644
--- a/src/Storage/MassStorage.cpp
+++ b/src/Storage/MassStorage.cpp
@@ -15,8 +15,8 @@ static_assert(FF_MAX_LFN >= MaxFilenameLength, "FF_MAX_LFN too small");
static_assert(SD_MMC_MEM_CNT == NumSdCards);
#endif
-#if HAS_LINUX_INTERFACE
-# include <Linux/LinuxInterface.h>
+#if HAS_SBC_INTERFACE
+# include <SBC/SbcInterface.h>
#endif
// A note on using mutexes:
@@ -126,11 +126,11 @@ static Mutex dirMutex;
static FileInfoParser infoParser;
#endif
-#if HAS_MASS_STORAGE || HAS_LINUX_INTERFACE
+#if HAS_MASS_STORAGE || HAS_SBC_INTERFACE
static FileWriteBuffer *freeWriteBuffers;
#endif
-#if HAS_MASS_STORAGE || HAS_LINUX_INTERFACE || HAS_EMBEDDED_FILES
+#if HAS_MASS_STORAGE || HAS_SBC_INTERFACE || HAS_EMBEDDED_FILES
static Mutex fsMutex;
static FileStore files[MAX_FILES];
#endif
@@ -184,8 +184,8 @@ uint16_t MassStorage::GetVolumeSeq(unsigned int volume) noexcept
static bool VolumeUpdated(const char *path) noexcept
{
if (!StringEndsWithIgnoreCase(path, ".part")
-#if HAS_LINUX_INTERFACE
- && !reprap.UsingLinuxInterface()
+#if HAS_SBC_INTERFACE
+ && !reprap.UsingSbcInterface()
#endif
)
{
@@ -275,7 +275,7 @@ static const char* TranslateCardError(sd_mmc_err_t err) noexcept
#endif
-#if HAS_MASS_STORAGE || HAS_LINUX_INTERFACE || HAS_EMBEDDED_FILES
+#if HAS_MASS_STORAGE || HAS_SBC_INTERFACE || HAS_EMBEDDED_FILES
void MassStorage::Init() noexcept
{
@@ -285,7 +285,7 @@ void MassStorage::Init() noexcept
dirMutex.Create("DirSearch");
#endif
-# if HAS_MASS_STORAGE || HAS_LINUX_INTERFACE
+# if HAS_MASS_STORAGE || HAS_SBC_INTERFACE
freeWriteBuffers = nullptr;
for (size_t i = 0; i < NumFileWriteBuffers; ++i)
{
@@ -470,7 +470,7 @@ bool MassStorage::DirectoryExists(const StringRef& path) noexcept
#endif
-#if HAS_MASS_STORAGE || HAS_LINUX_INTERFACE
+#if HAS_MASS_STORAGE || HAS_SBC_INTERFACE
// Static helper functions
size_t FileWriteBuffer::fileWriteBufLen = FileWriteBufLen;
@@ -496,7 +496,7 @@ void MassStorage::ReleaseWriteBuffer(FileWriteBuffer *buffer) noexcept
freeWriteBuffers = buffer;
}
-# if HAS_LINUX_INTERFACE
+# if HAS_SBC_INTERFACE
// Return true if any files are open on the file system
bool MassStorage::AnyFileOpen() noexcept
@@ -587,10 +587,10 @@ static bool InternalDelete(const char* filePath, bool messageIfFailed) noexcept
// Delete a file or directory and update the volume sequence number returning true if successful
bool MassStorage::Delete(const char* filePath, bool messageIfFailed) noexcept
{
-#if HAS_LINUX_INTERFACE
- if (reprap.UsingLinuxInterface())
+#if HAS_SBC_INTERFACE
+ if (reprap.UsingSbcInterface())
{
- if (reprap.GetLinuxInterface().DeleteFileOrDirectory(filePath))
+ if (reprap.GetSbcInterface().DeleteFileOrDirectory(filePath))
{
return true;
}
@@ -728,8 +728,8 @@ const char* MassStorage::GetMonthName(const uint8_t month) noexcept
// Ensure that the path up to the last '/' (excluding trailing '/' characters) in filePath exists, returning true if successful
bool MassStorage::EnsurePath(const char* filePath, bool messageIfFailed) noexcept
{
-#if HAS_LINUX_INTERFACE
- if (reprap.UsingLinuxInterface())
+#if HAS_SBC_INTERFACE
+ if (reprap.UsingSbcInterface())
{
// This isn't needed in SBC mode because DSF does it automatically
return true;
@@ -837,15 +837,15 @@ bool MassStorage::Rename(const char *oldFilename, const char *newFilename, bool
}
#endif
-#if HAS_MASS_STORAGE || HAS_LINUX_INTERFACE
+#if HAS_MASS_STORAGE || HAS_SBC_INTERFACE
// Check if the specified file exists
bool MassStorage::FileExists(const char *filePath) noexcept
{
-#if HAS_LINUX_INTERFACE
- if (reprap.UsingLinuxInterface())
+#if HAS_SBC_INTERFACE
+ if (reprap.UsingSbcInterface())
{
- return reprap.GetLinuxInterface().FileExists(filePath);
+ return reprap.GetSbcInterface().FileExists(filePath);
}
#endif
diff --git a/src/Storage/MassStorage.h b/src/Storage/MassStorage.h
index 39cbd60d..3753923b 100644
--- a/src/Storage/MassStorage.h
+++ b/src/Storage/MassStorage.h
@@ -42,7 +42,7 @@ namespace MassStorage
bool CombineName(const StringRef& outbuf, const char* directory, const char* fileName) noexcept; // returns false if error i.e. filename too long
const char* GetMonthName(const uint8_t month) noexcept;
-#if HAS_MASS_STORAGE || HAS_LINUX_INTERFACE || HAS_EMBEDDED_FILES
+#if HAS_MASS_STORAGE || HAS_SBC_INTERFACE || HAS_EMBEDDED_FILES
void Init() noexcept;
FileStore* OpenFile(const char* filePath, OpenMode mode, uint32_t preAllocSize) noexcept;
bool FileExists(const char *filePath) noexcept;
@@ -50,14 +50,14 @@ namespace MassStorage
void Spin() noexcept;
#endif
-#if HAS_MASS_STORAGE || HAS_LINUX_INTERFACE
+#if HAS_MASS_STORAGE || HAS_SBC_INTERFACE
FileWriteBuffer *AllocateWriteBuffer() noexcept;
size_t GetFileWriteBufferLength() noexcept;
void ReleaseWriteBuffer(FileWriteBuffer *buffer) noexcept;
bool Delete(const char* filePath, bool messageIfFailed) noexcept;
#endif
-#if HAS_LINUX_INTERFACE
+#if HAS_SBC_INTERFACE
bool AnyFileOpen() noexcept; // Return true if any files are open on the file system
void InvalidateAllFiles() noexcept;
#endif
diff --git a/src/Tools/Filament.cpp b/src/Tools/Filament.cpp
index 75c268a9..b2003ce7 100644
--- a/src/Tools/Filament.cpp
+++ b/src/Tools/Filament.cpp
@@ -42,7 +42,7 @@ void Filament::Unload() noexcept
void Filament::LoadAssignment() noexcept
{
-#if HAS_MASS_STORAGE || HAS_LINUX_INTERFACE
+#if HAS_MASS_STORAGE || HAS_SBC_INTERFACE
FileStore * const file = reprap.GetPlatform().OpenSysFile(FilamentAssignmentFile, OpenMode::read);
if (file == nullptr)
{
@@ -84,7 +84,7 @@ void Filament::LoadAssignment() noexcept
// Update the OM when the filament has been changed
reprap.MoveUpdated();
-#if HAS_MASS_STORAGE || HAS_LINUX_INTERFACE
+#if HAS_MASS_STORAGE || HAS_SBC_INTERFACE
FileStore * const file = reprap.GetPlatform().OpenSysFile(FilamentAssignmentFile, OpenMode::write);
if (file == nullptr)
{
diff --git a/src/Tools/Tool.cpp b/src/Tools/Tool.cpp
index 3c86af74..ed5b8cda 100644
--- a/src/Tools/Tool.cpp
+++ b/src/Tools/Tool.cpp
@@ -581,7 +581,7 @@ void Tool::DefineMix(const float m[]) noexcept
reprap.ToolsUpdated();
}
-#if HAS_MASS_STORAGE || HAS_LINUX_INTERFACE
+#if HAS_MASS_STORAGE || HAS_SBC_INTERFACE
// Write the tool's settings to file returning true if successful. The settings written leave the tool selected unless it is off.
bool Tool::WriteSettings(FileStore *f) const noexcept
diff --git a/src/Tools/Tool.h b/src/Tools/Tool.h
index bcdccb98..5ff3da34 100644
--- a/src/Tools/Tool.h
+++ b/src/Tools/Tool.h
@@ -98,7 +98,7 @@ public:
uint32_t GetSpindleRpm() const noexcept { return spindleRpm; }
void SetSpindleRpm(uint32_t rpm) THROWS(GCodeException);
-#if HAS_MASS_STORAGE || HAS_LINUX_INTERFACE
+#if HAS_MASS_STORAGE || HAS_SBC_INTERFACE
bool WriteSettings(FileStore *f) const noexcept; // write the tool's settings to file
#endif
diff --git a/src/bossa/Flasher.cpp b/src/bossa/Flasher.cpp
index 85f65f86..0a6ec978 100644
--- a/src/bossa/Flasher.cpp
+++ b/src/bossa/Flasher.cpp
@@ -31,8 +31,8 @@
#include <Platform/RepRap.h>
#include <Platform/Platform.h>
#include <General/Vector.hpp>
-#if HAS_LINUX_INTERFACE
-# include <Linux/LinuxInterface.h>
+#if HAS_SBC_INTERFACE
+# include <SBC/SbcInterface.h>
#endif
void Flasher::erase(uint32_t foffset) THROWS(GCodeException)