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

github.com/Duet3D/RepRapFirmware.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.cproject45
-rw-r--r--.settings/language.settings.xml10
-rw-r--r--.settings/org.eclipse.cdt.core.prefs30
-rw-r--r--Release/Duet-0.6-0.8.5/Edge/RepRapFirmware-1.20alpha4.binbin343072 -> 0 bytes
-rw-r--r--Release/Duet-0.6-0.8.5/Edge/RepRapFirmware-1.20beta1.binbin345904 -> 0 bytes
-rw-r--r--Release/Duet-0.6-0.8.5/Edge/RepRapFirmware-1.20beta6.binbin352552 -> 0 bytes
-rw-r--r--Release/Duet-0.6-0.8.5/Edge/RepRapFirmware-1.20beta8.binbin0 -> 354816 bytes
-rw-r--r--Release/Duet-Ethernet/Edge/DuetEthernetFirmware-1.20beta1.binbin323952 -> 0 bytes
-rw-r--r--Release/Duet-Ethernet/Edge/DuetEthernetFirmware-1.20beta4.binbin332800 -> 0 bytes
-rw-r--r--Release/Duet-Ethernet/Edge/DuetEthernetFirmware-1.20beta6.binbin335008 -> 0 bytes
-rw-r--r--Release/Duet-Ethernet/Edge/DuetEthernetFirmware-1.20beta8.binbin0 -> 336536 bytes
-rw-r--r--Release/Duet-WiFi/Edge/DuetWiFiFirmware-1.20beta1.binbin326808 -> 0 bytes
-rw-r--r--Release/Duet-WiFi/Edge/DuetWiFiFirmware-1.20beta4.binbin335928 -> 0 bytes
-rw-r--r--Release/Duet-WiFi/Edge/DuetWiFiFirmware-1.20beta6.binbin338192 -> 0 bytes
-rw-r--r--Release/Duet-WiFi/Edge/DuetWiFiFirmware-1.20beta8.binbin0 -> 339312 bytes
-rw-r--r--Release/Duet-WiFi/Edge/DuetWiFiServer-1.20beta9.binbin0 -> 302928 bytes
-rw-r--r--src/Configuration.h3
-rw-r--r--src/DuetNG/DueXn.cpp22
-rw-r--r--src/DuetNG/DuetWiFi/Network.cpp55
-rw-r--r--src/DuetNG/DuetWiFi/Network.h6
-rw-r--r--src/DuetNG/SX1509.cpp93
-rw-r--r--src/DuetNG/SX1509.h24
-rw-r--r--src/GCodes/GCodes.cpp339
-rw-r--r--src/GCodes/GCodes.h44
-rw-r--r--src/GCodes/GCodes2.cpp196
-rw-r--r--src/GCodes/RestorePoint.cpp6
-rw-r--r--src/GCodes/RestorePoint.h4
-rw-r--r--src/Heating/FOPDT.cpp8
-rw-r--r--src/Heating/FOPDT.h4
-rw-r--r--src/Heating/Heat.cpp15
-rw-r--r--src/Heating/Heat.h10
-rw-r--r--src/Heating/Pid.cpp55
-rw-r--r--src/Heating/Pid.h2
-rw-r--r--src/Libraries/General/StringRef.h16
-rw-r--r--src/Logger.cpp4
-rw-r--r--src/Logger.h2
-rw-r--r--src/Movement/DDA.cpp21
-rw-r--r--src/Movement/DDA.h8
-rw-r--r--src/Movement/Kinematics/CoreXYUKinematics.cpp4
-rw-r--r--src/Movement/Move.cpp32
-rw-r--r--src/Movement/Move.h2
-rw-r--r--src/Platform.cpp151
-rw-r--r--src/Platform.h8
-rw-r--r--src/PortControl.cpp4
-rw-r--r--src/RepRap.cpp63
-rw-r--r--src/RepRap.h1
-rw-r--r--src/RepRapFirmware.cpp15
-rw-r--r--src/RepRapFirmware.h11
-rw-r--r--src/Tools/Tool.cpp32
-rw-r--r--src/Tools/Tool.h4
-rw-r--r--src/Version.h4
51 files changed, 884 insertions, 469 deletions
diff --git a/.cproject b/.cproject
index c564f5e3..45c9012a 100644
--- a/.cproject
+++ b/.cproject
@@ -4,7 +4,10 @@
<cconfiguration id="cdt.managedbuild.config.gnu.cross.exe.release.516195201.976458850">
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="cdt.managedbuild.config.gnu.cross.exe.release.516195201.976458850" moduleId="org.eclipse.cdt.core.settings" name="Duet085">
<macros>
+ <stringMacro name="LinkFlags2" type="VALUE_TEXT" value="-Wl,--end-group -lm -gcc"/>
+ <stringMacro name="LinkFlags1" type="VALUE_TEXT" value="-mthumb -Wl,--cref -Wl,--check-sections -Wl,--gc-sections -Wl,--entry=Reset_Handler -Wl,--unresolved-symbols=report-all -Wl,--warn-common -Wl,--warn-section-align -Wl,--warn-unresolved-symbols -Wl,--start-group"/>
<stringMacro name="CoreName" type="VALUE_TEXT" value="CoreNG"/>
+ <stringMacro name="GccPath" type="VALUE_TEXT" value="C:\Program Files (x86)\GNU Tools ARM Embedded\6 2017-q2-update\bin"/>
</macros>
<externalSettings/>
<extensions>
@@ -20,8 +23,8 @@
<configuration artifactExtension="elf" artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe,org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.release" cleanCommand="rm -rf" description="" id="cdt.managedbuild.config.gnu.cross.exe.release.516195201.976458850" name="Duet085" parent="cdt.managedbuild.config.gnu.cross.exe.release" postannouncebuildStep="Generating binary file" postbuildStep="arm-none-eabi-objcopy -O binary ${workspace_loc:/${ProjName}/${ConfigName}}/${ProjName}.elf ${workspace_loc:/${ProjName}/${ConfigName}}/${ProjName}.bin">
<folderInfo id="cdt.managedbuild.config.gnu.cross.exe.release.516195201.976458850." name="/" resourcePath="">
<toolChain id="cdt.managedbuild.toolchain.gnu.cross.exe.release.947353540" name="Cross GCC" superClass="cdt.managedbuild.toolchain.gnu.cross.exe.release">
- <option id="cdt.managedbuild.option.gnu.cross.path.1742191832" name="Path" superClass="cdt.managedbuild.option.gnu.cross.path" value="C:\Program Files (x86)\GNU Tools ARM Embedded\6 2017-q2-update" valueType="string"/>
- <option id="cdt.managedbuild.option.gnu.cross.prefix.1660769040" name="Prefix" superClass="cdt.managedbuild.option.gnu.cross.prefix" value="arm-none-eabi-" valueType="string"/>
+ <option id="cdt.managedbuild.option.gnu.cross.path.1742191832" name="Path" superClass="cdt.managedbuild.option.gnu.cross.path" useByScannerDiscovery="false" value="${GccPath}" valueType="string"/>
+ <option id="cdt.managedbuild.option.gnu.cross.prefix.1660769040" name="Prefix" superClass="cdt.managedbuild.option.gnu.cross.prefix" useByScannerDiscovery="false" value="arm-none-eabi-" valueType="string"/>
<targetPlatform archList="all" binaryParser="org.eclipse.cdt.core.ELF" id="cdt.managedbuild.targetPlatform.gnu.cross.223860525" isAbstract="false" osList="all" superClass="cdt.managedbuild.targetPlatform.gnu.cross"/>
<builder buildPath="${workspace_loc:/RepRapFirmware}/Release" id="cdt.managedbuild.builder.gnu.cross.13059261" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="Gnu Make Builder" superClass="cdt.managedbuild.builder.gnu.cross"/>
<tool id="cdt.managedbuild.tool.gnu.cross.assembler.163742171" name="Cross GCC Assembler" superClass="cdt.managedbuild.tool.gnu.cross.assembler">
@@ -56,15 +59,15 @@
</tool>
<tool id="cdt.managedbuild.tool.gnu.cross.c.linker.831729502" name="Cross GCC Linker" superClass="cdt.managedbuild.tool.gnu.cross.c.linker"/>
<tool id="cdt.managedbuild.tool.gnu.cross.archiver.586905748" name="Cross GCC Archiver" superClass="cdt.managedbuild.tool.gnu.cross.archiver"/>
- <tool command="gcc" commandLinePattern="${COMMAND} ${FLAGS} ${OUTPUT_FLAG} ${OUTPUT_PREFIX}${OUTPUT} ${LINK_FLAGS_1} &quot;${workspace_loc:/${CoreName}/SAM3X8E/cores/arduino/syscalls.o}&quot; ${INPUTS} ${LINK_FLAGS_2}" id="cdt.managedbuild.tool.gnu.cross.cpp.linker.77650722" name="Cross G++ Linker" superClass="cdt.managedbuild.tool.gnu.cross.cpp.linker">
- <option id="gnu.cpp.link.option.nostdlibs.296038599" name="No startup or default libs (-nostdlib)" superClass="gnu.cpp.link.option.nostdlibs" value="false" valueType="boolean"/>
- <option id="gnu.cpp.link.option.paths.75045718" name="Library search path (-L)" superClass="gnu.cpp.link.option.paths" valueType="libPaths">
+ <tool command="gcc" commandLinePattern="${COMMAND} ${FLAGS} ${OUTPUT_FLAG} ${OUTPUT_PREFIX}${OUTPUT} ${LinkFlags1} &quot;${workspace_loc:/${CoreName}/SAM3X8E/cores/arduino/syscalls.o}&quot; ${INPUTS} ${LinkFlags2}" id="cdt.managedbuild.tool.gnu.cross.cpp.linker.77650722" name="Cross G++ Linker" superClass="cdt.managedbuild.tool.gnu.cross.cpp.linker">
+ <option id="gnu.cpp.link.option.nostdlibs.296038599" name="No startup or default libs (-nostdlib)" superClass="gnu.cpp.link.option.nostdlibs" useByScannerDiscovery="false" value="false" valueType="boolean"/>
+ <option id="gnu.cpp.link.option.paths.75045718" name="Library search path (-L)" superClass="gnu.cpp.link.option.paths" useByScannerDiscovery="false" valueType="libPaths">
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${CoreName}/SAM3X8E/}&quot;"/>
</option>
- <option id="gnu.cpp.link.option.libs.1995000942" name="Libraries (-l)" superClass="gnu.cpp.link.option.libs" valueType="libs">
+ <option id="gnu.cpp.link.option.libs.1995000942" name="Libraries (-l)" superClass="gnu.cpp.link.option.libs" useByScannerDiscovery="false" valueType="libs">
<listOptionValue builtIn="false" value="${CoreName}"/>
</option>
- <option id="gnu.cpp.link.option.flags.1670739910" name="Linker flags" superClass="gnu.cpp.link.option.flags" value="-Os -Wl,--gc-sections -Wl,--fatal-warnings -mcpu=cortex-m3 -T${workspace_loc:/${CoreName}/variants/duet/linker_scripts/gcc/flash.ld} -Wl,-Map,${workspace_loc:/${ProjName}/${ConfigName}}/${BuildArtifactFileBaseName}.map" valueType="string"/>
+ <option id="gnu.cpp.link.option.flags.1670739910" name="Linker flags" superClass="gnu.cpp.link.option.flags" useByScannerDiscovery="false" value="-Os -Wl,--gc-sections -Wl,--fatal-warnings -mcpu=cortex-m3 -T${workspace_loc:/${CoreName}/variants/duet/linker_scripts/gcc/flash.ld} -Wl,-Map,${workspace_loc:/${ProjName}/${ConfigName}}/${BuildArtifactFileBaseName}.map" valueType="string"/>
<inputType id="cdt.managedbuild.tool.gnu.cpp.linker.input.1491196930" superClass="cdt.managedbuild.tool.gnu.cpp.linker.input">
<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
<additionalInput kind="additionalinput" paths="$(LIBS)"/>
@@ -116,7 +119,10 @@
<cconfiguration id="cdt.managedbuild.config.gnu.cross.exe.release.516195201.976458850.241502451">
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="cdt.managedbuild.config.gnu.cross.exe.release.516195201.976458850.241502451" moduleId="org.eclipse.cdt.core.settings" name="DuetWiFi">
<macros>
+ <stringMacro name="LinkFlags2" type="VALUE_TEXT" value="-Wl,--end-group -lm -gcc"/>
+ <stringMacro name="LinkFlags1" type="VALUE_TEXT" value="-mthumb -Wl,--cref -Wl,--check-sections -Wl,--gc-sections -Wl,--entry=Reset_Handler -Wl,--unresolved-symbols=report-all -Wl,--warn-common -Wl,--warn-section-align -Wl,--warn-unresolved-symbols -Wl,--start-group"/>
<stringMacro name="CoreName" type="VALUE_TEXT" value="CoreNG"/>
+ <stringMacro name="GccPath" type="VALUE_TEXT" value="C:\Program Files (x86)\GNU Tools ARM Embedded\6 2017-q2-update\bin"/>
</macros>
<externalSettings/>
<extensions>
@@ -132,7 +138,7 @@
<configuration artifactExtension="elf" artifactName="DuetWiFiFirmware" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe,org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.release" cleanCommand="rm -rf" description="" id="cdt.managedbuild.config.gnu.cross.exe.release.516195201.976458850.241502451" name="DuetWiFi" parent="cdt.managedbuild.config.gnu.cross.exe.release" postannouncebuildStep="Generating binary file" postbuildStep="arm-none-eabi-objcopy -O binary ${workspace_loc:/${ProjName}/${ConfigName}}/DuetWiFiFirmware.elf ${workspace_loc:/${ProjName}/${ConfigName}}/DuetWiFiFirmware.bin">
<folderInfo id="cdt.managedbuild.config.gnu.cross.exe.release.516195201.976458850.241502451." name="/" resourcePath="">
<toolChain id="cdt.managedbuild.toolchain.gnu.cross.exe.release.1362047835" name="Cross GCC" superClass="cdt.managedbuild.toolchain.gnu.cross.exe.release">
- <option id="cdt.managedbuild.option.gnu.cross.path.1491883811" name="Path" superClass="cdt.managedbuild.option.gnu.cross.path" useByScannerDiscovery="false" value="C:\Program Files (x86)\GNU Tools ARM Embedded\6 2017-q2-update" valueType="string"/>
+ <option id="cdt.managedbuild.option.gnu.cross.path.1491883811" name="Path" superClass="cdt.managedbuild.option.gnu.cross.path" useByScannerDiscovery="false" value="${GccPath}" valueType="string"/>
<option id="cdt.managedbuild.option.gnu.cross.prefix.353555591" name="Prefix" superClass="cdt.managedbuild.option.gnu.cross.prefix" useByScannerDiscovery="false" value="arm-none-eabi-" valueType="string"/>
<targetPlatform archList="all" binaryParser="org.eclipse.cdt.core.ELF" id="cdt.managedbuild.targetPlatform.gnu.cross.857793524" isAbstract="false" osList="all" superClass="cdt.managedbuild.targetPlatform.gnu.cross"/>
<builder buildPath="${workspace_loc:/RepRapFirmware}/Release" id="cdt.managedbuild.builder.gnu.cross.1026937542" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="Gnu Make Builder" superClass="cdt.managedbuild.builder.gnu.cross"/>
@@ -167,7 +173,7 @@
</tool>
<tool id="cdt.managedbuild.tool.gnu.cross.c.linker.1561858475" name="Cross GCC Linker" superClass="cdt.managedbuild.tool.gnu.cross.c.linker"/>
<tool id="cdt.managedbuild.tool.gnu.cross.archiver.367299064" name="Cross GCC Archiver" superClass="cdt.managedbuild.tool.gnu.cross.archiver"/>
- <tool command="gcc" commandLinePattern="${COMMAND} ${FLAGS} ${OUTPUT_FLAG} ${OUTPUT_PREFIX}${OUTPUT} ${LINK_FLAGS_1} &quot;${workspace_loc:/${CoreName}/SAM4E8E/cores/arduino/syscalls.o}&quot; ${INPUTS} ${LINK_FLAGS_2}" id="cdt.managedbuild.tool.gnu.cross.cpp.linker.2096521800" name="Cross G++ Linker" superClass="cdt.managedbuild.tool.gnu.cross.cpp.linker">
+ <tool command="gcc" commandLinePattern="${COMMAND} ${FLAGS} ${OUTPUT_FLAG} ${OUTPUT_PREFIX}${OUTPUT} ${LinkFlags1} &quot;${workspace_loc:/${CoreName}/SAM4E8E/cores/arduino/syscalls.o}&quot; ${INPUTS} ${LinkFlags2}" id="cdt.managedbuild.tool.gnu.cross.cpp.linker.2096521800" name="Cross G++ Linker" superClass="cdt.managedbuild.tool.gnu.cross.cpp.linker">
<option id="gnu.cpp.link.option.nostdlibs.111689408" name="No startup or default libs (-nostdlib)" superClass="gnu.cpp.link.option.nostdlibs" useByScannerDiscovery="false" value="false" valueType="boolean"/>
<option id="gnu.cpp.link.option.paths.314107745" name="Library search path (-L)" superClass="gnu.cpp.link.option.paths" useByScannerDiscovery="false" valueType="libPaths">
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${CoreName}/SAM4E8E/}&quot;"/>
@@ -230,7 +236,10 @@
<cconfiguration id="cdt.managedbuild.config.gnu.cross.exe.release.516195201.976458850.1027429289">
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="cdt.managedbuild.config.gnu.cross.exe.release.516195201.976458850.1027429289" moduleId="org.eclipse.cdt.core.settings" name="RADDS">
<macros>
+ <stringMacro name="LinkFlags2" type="VALUE_TEXT" value="-Wl,--end-group -lm -gcc"/>
+ <stringMacro name="LinkFlags1" type="VALUE_TEXT" value="-mthumb -Wl,--cref -Wl,--check-sections -Wl,--gc-sections -Wl,--entry=Reset_Handler -Wl,--unresolved-symbols=report-all -Wl,--warn-common -Wl,--warn-section-align -Wl,--warn-unresolved-symbols -Wl,--start-group"/>
<stringMacro name="CoreName" type="VALUE_TEXT" value="CoreNG"/>
+ <stringMacro name="GccPath" type="VALUE_TEXT" value="C:\Program Files (x86)\GNU Tools ARM Embedded\6 2017-q2-update\bin"/>
</macros>
<externalSettings/>
<extensions>
@@ -246,7 +255,7 @@
<configuration artifactExtension="elf" artifactName="${ProjName}-RADDS" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe,org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.release" cleanCommand="rm -rf" description="" id="cdt.managedbuild.config.gnu.cross.exe.release.516195201.976458850.1027429289" name="RADDS" parent="cdt.managedbuild.config.gnu.cross.exe.release" postannouncebuildStep="Generating binary file" postbuildStep="arm-none-eabi-objcopy -O binary ${workspace_loc:/${ProjName}/${ConfigName}}/${ProjName}-RADDS.elf ${workspace_loc:/${ProjName}/${ConfigName}}/${ProjName}-RADDS.bin">
<folderInfo id="cdt.managedbuild.config.gnu.cross.exe.release.516195201.976458850.1027429289." name="/" resourcePath="">
<toolChain id="cdt.managedbuild.toolchain.gnu.cross.exe.release.1973208555" name="Cross GCC" superClass="cdt.managedbuild.toolchain.gnu.cross.exe.release">
- <option id="cdt.managedbuild.option.gnu.cross.path.2092504710" name="Path" superClass="cdt.managedbuild.option.gnu.cross.path" useByScannerDiscovery="false" value="C:\Program Files (x86)\GNU Tools ARM Embedded\6 2017-q2-update" valueType="string"/>
+ <option id="cdt.managedbuild.option.gnu.cross.path.2092504710" name="Path" superClass="cdt.managedbuild.option.gnu.cross.path" useByScannerDiscovery="false" value="${GccPath}" valueType="string"/>
<option id="cdt.managedbuild.option.gnu.cross.prefix.1606498191" name="Prefix" superClass="cdt.managedbuild.option.gnu.cross.prefix" useByScannerDiscovery="false" value="arm-none-eabi-" valueType="string"/>
<targetPlatform archList="all" binaryParser="org.eclipse.cdt.core.ELF" id="cdt.managedbuild.targetPlatform.gnu.cross.342355349" isAbstract="false" osList="all" superClass="cdt.managedbuild.targetPlatform.gnu.cross"/>
<builder buildPath="${workspace_loc:/RepRapFirmware}/Release" id="cdt.managedbuild.builder.gnu.cross.1336978387" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="Gnu Make Builder" superClass="cdt.managedbuild.builder.gnu.cross"/>
@@ -279,7 +288,7 @@
</tool>
<tool id="cdt.managedbuild.tool.gnu.cross.c.linker.1692168928" name="Cross GCC Linker" superClass="cdt.managedbuild.tool.gnu.cross.c.linker"/>
<tool id="cdt.managedbuild.tool.gnu.cross.archiver.1755453550" name="Cross GCC Archiver" superClass="cdt.managedbuild.tool.gnu.cross.archiver"/>
- <tool command="gcc" commandLinePattern="${COMMAND} ${FLAGS} ${OUTPUT_FLAG} ${OUTPUT_PREFIX}${OUTPUT} ${LINK_FLAGS_1} &quot;${workspace_loc:/${CoreName}/RADDS/cores/arduino/syscalls.o}&quot; ${INPUTS} ${LINK_FLAGS_2}" id="cdt.managedbuild.tool.gnu.cross.cpp.linker.1176271302" name="Cross G++ Linker" superClass="cdt.managedbuild.tool.gnu.cross.cpp.linker">
+ <tool command="gcc" commandLinePattern="${COMMAND} ${FLAGS} ${OUTPUT_FLAG} ${OUTPUT_PREFIX}${OUTPUT} ${LinkFlags1} &quot;${workspace_loc:/${CoreName}/RADDS/cores/arduino/syscalls.o}&quot; ${INPUTS} ${LinkFlags2}" id="cdt.managedbuild.tool.gnu.cross.cpp.linker.1176271302" name="Cross G++ Linker" superClass="cdt.managedbuild.tool.gnu.cross.cpp.linker">
<option id="gnu.cpp.link.option.nostdlibs.706270025" name="No startup or default libs (-nostdlib)" superClass="gnu.cpp.link.option.nostdlibs" useByScannerDiscovery="false" value="false" valueType="boolean"/>
<option id="gnu.cpp.link.option.paths.1160723414" name="Library search path (-L)" superClass="gnu.cpp.link.option.paths" useByScannerDiscovery="false" valueType="libPaths">
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${CoreName}/RADDS/}&quot;"/>
@@ -337,7 +346,10 @@
<cconfiguration id="cdt.managedbuild.config.gnu.cross.exe.release.516195201.976458850.241502451.1275216290">
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="cdt.managedbuild.config.gnu.cross.exe.release.516195201.976458850.241502451.1275216290" moduleId="org.eclipse.cdt.core.settings" name="DuetEthernet">
<macros>
+ <stringMacro name="LinkFlags2" type="VALUE_TEXT" value="-Wl,--end-group -lm -gcc"/>
+ <stringMacro name="LinkFlags1" type="VALUE_TEXT" value="-mthumb -Wl,--cref -Wl,--check-sections -Wl,--gc-sections -Wl,--entry=Reset_Handler -Wl,--unresolved-symbols=report-all -Wl,--warn-common -Wl,--warn-section-align -Wl,--warn-unresolved-symbols -Wl,--start-group"/>
<stringMacro name="CoreName" type="VALUE_TEXT" value="CoreNG"/>
+ <stringMacro name="GccPath" type="VALUE_TEXT" value="C:\Program Files (x86)\GNU Tools ARM Embedded\6 2017-q2-update\bin"/>
</macros>
<externalSettings/>
<extensions>
@@ -353,7 +365,7 @@
<configuration artifactExtension="elf" artifactName="DuetEthernetFirmware" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe,org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.release" cleanCommand="rm -rf" description="" id="cdt.managedbuild.config.gnu.cross.exe.release.516195201.976458850.241502451.1275216290" name="DuetEthernet" parent="cdt.managedbuild.config.gnu.cross.exe.release" postannouncebuildStep="Generating binary file" postbuildStep="arm-none-eabi-objcopy -O binary ${workspace_loc:/${ProjName}/${ConfigName}}/DuetEthernetFirmware.elf ${workspace_loc:/${ProjName}/${ConfigName}}/DuetEthernetFirmware.bin">
<folderInfo id="cdt.managedbuild.config.gnu.cross.exe.release.516195201.976458850.241502451.1275216290." name="/" resourcePath="">
<toolChain id="cdt.managedbuild.toolchain.gnu.cross.exe.release.311889538" name="Cross GCC" superClass="cdt.managedbuild.toolchain.gnu.cross.exe.release">
- <option id="cdt.managedbuild.option.gnu.cross.path.1965306885" name="Path" superClass="cdt.managedbuild.option.gnu.cross.path" useByScannerDiscovery="false" value="C:\Program Files (x86)\GNU Tools ARM Embedded\6 2017-q2-update" valueType="string"/>
+ <option id="cdt.managedbuild.option.gnu.cross.path.1965306885" name="Path" superClass="cdt.managedbuild.option.gnu.cross.path" useByScannerDiscovery="false" value="${GccPath}" valueType="string"/>
<option id="cdt.managedbuild.option.gnu.cross.prefix.444696517" name="Prefix" superClass="cdt.managedbuild.option.gnu.cross.prefix" useByScannerDiscovery="false" value="arm-none-eabi-" valueType="string"/>
<targetPlatform archList="all" binaryParser="org.eclipse.cdt.core.ELF" id="cdt.managedbuild.targetPlatform.gnu.cross.252007317" isAbstract="false" osList="all" superClass="cdt.managedbuild.targetPlatform.gnu.cross"/>
<builder buildPath="${workspace_loc:/RepRapFirmware}/Release" id="cdt.managedbuild.builder.gnu.cross.310136248" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="Gnu Make Builder" superClass="cdt.managedbuild.builder.gnu.cross"/>
@@ -392,7 +404,7 @@
</tool>
<tool id="cdt.managedbuild.tool.gnu.cross.c.linker.212863977" name="Cross GCC Linker" superClass="cdt.managedbuild.tool.gnu.cross.c.linker"/>
<tool id="cdt.managedbuild.tool.gnu.cross.archiver.136873036" name="Cross GCC Archiver" superClass="cdt.managedbuild.tool.gnu.cross.archiver"/>
- <tool command="gcc" commandLinePattern="${COMMAND} ${FLAGS} ${OUTPUT_FLAG} ${OUTPUT_PREFIX}${OUTPUT} ${LINK_FLAGS_1} &quot;${workspace_loc:/${CoreName}/SAM4E8E/cores/arduino/syscalls.o}&quot; ${INPUTS} ${LINK_FLAGS_2}" id="cdt.managedbuild.tool.gnu.cross.cpp.linker.394147701" name="Cross G++ Linker" superClass="cdt.managedbuild.tool.gnu.cross.cpp.linker">
+ <tool command="gcc" commandLinePattern="${COMMAND} ${FLAGS} ${OUTPUT_FLAG} ${OUTPUT_PREFIX}${OUTPUT} ${LinkFlags1} &quot;${workspace_loc:/${CoreName}/SAM4E8E/cores/arduino/syscalls.o}&quot; ${INPUTS} ${LinkFlags2}" id="cdt.managedbuild.tool.gnu.cross.cpp.linker.394147701" name="Cross G++ Linker" superClass="cdt.managedbuild.tool.gnu.cross.cpp.linker">
<option id="gnu.cpp.link.option.nostdlibs.278980629" name="No startup or default libs (-nostdlib)" superClass="gnu.cpp.link.option.nostdlibs" useByScannerDiscovery="false" value="false" valueType="boolean"/>
<option id="gnu.cpp.link.option.paths.1667456082" name="Library search path (-L)" superClass="gnu.cpp.link.option.paths" useByScannerDiscovery="false" valueType="libPaths">
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${CoreName}/SAM4E8E/}&quot;"/>
@@ -474,7 +486,10 @@
<cconfiguration id="cdt.managedbuild.config.gnu.cross.exe.release.516195201.976458850.1745168887">
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="cdt.managedbuild.config.gnu.cross.exe.release.516195201.976458850.1745168887" moduleId="org.eclipse.cdt.core.settings" name="Alligator">
<macros>
+ <stringMacro name="LinkFlags2" type="VALUE_TEXT" value="-Wl,--end-group -lm -gcc"/>
+ <stringMacro name="LinkFlags1" type="VALUE_TEXT" value="-mthumb -Wl,--cref -Wl,--check-sections -Wl,--gc-sections -Wl,--entry=Reset_Handler -Wl,--unresolved-symbols=report-all -Wl,--warn-common -Wl,--warn-section-align -Wl,--warn-unresolved-symbols -Wl,--start-group"/>
<stringMacro name="CoreName" type="VALUE_TEXT" value="CoreNG"/>
+ <stringMacro name="GccPath" type="VALUE_TEXT" value="C:\Program Files (x86)\GNU Tools ARM Embedded\6 2017-q2-update\bin"/>
</macros>
<externalSettings/>
<extensions>
@@ -490,7 +505,7 @@
<configuration artifactExtension="elf" artifactName="${ProjName}-Alligator" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe,org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.release" cleanCommand="rm -rf" description="" id="cdt.managedbuild.config.gnu.cross.exe.release.516195201.976458850.1745168887" name="Alligator" parent="cdt.managedbuild.config.gnu.cross.exe.release" postannouncebuildStep="Generating binary file" postbuildStep="arm-none-eabi-objcopy -O binary ${workspace_loc:/${ProjName}/${ConfigName}}/${ProjName}-Alligator.elf ${workspace_loc:/${ProjName}/${ConfigName}}/${ProjName}-Alligator.bin">
<folderInfo id="cdt.managedbuild.config.gnu.cross.exe.release.516195201.976458850.1745168887." name="/" resourcePath="">
<toolChain id="cdt.managedbuild.toolchain.gnu.cross.exe.release.623324432" name="Cross GCC" superClass="cdt.managedbuild.toolchain.gnu.cross.exe.release">
- <option id="cdt.managedbuild.option.gnu.cross.path.645044151" name="Path" superClass="cdt.managedbuild.option.gnu.cross.path" useByScannerDiscovery="false" value="C:\Program Files (x86)\GNU Tools ARM Embedded\6 2017-q2-update" valueType="string"/>
+ <option id="cdt.managedbuild.option.gnu.cross.path.645044151" name="Path" superClass="cdt.managedbuild.option.gnu.cross.path" useByScannerDiscovery="false" value="${GccPath}" valueType="string"/>
<option id="cdt.managedbuild.option.gnu.cross.prefix.629438941" name="Prefix" superClass="cdt.managedbuild.option.gnu.cross.prefix" useByScannerDiscovery="false" value="arm-none-eabi-" valueType="string"/>
<targetPlatform archList="all" binaryParser="org.eclipse.cdt.core.ELF" id="cdt.managedbuild.targetPlatform.gnu.cross.878309876" isAbstract="false" osList="all" superClass="cdt.managedbuild.targetPlatform.gnu.cross"/>
<builder buildPath="${workspace_loc:/RepRapFirmware}/Release" id="cdt.managedbuild.builder.gnu.cross.56178753" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="Gnu Make Builder" superClass="cdt.managedbuild.builder.gnu.cross"/>
@@ -528,7 +543,7 @@
</tool>
<tool id="cdt.managedbuild.tool.gnu.cross.c.linker.1510685625" name="Cross GCC Linker" superClass="cdt.managedbuild.tool.gnu.cross.c.linker"/>
<tool id="cdt.managedbuild.tool.gnu.cross.archiver.2031955379" name="Cross GCC Archiver" superClass="cdt.managedbuild.tool.gnu.cross.archiver"/>
- <tool command="gcc" commandLinePattern="${COMMAND} ${FLAGS} ${OUTPUT_FLAG} ${OUTPUT_PREFIX}${OUTPUT} ${LINK_FLAGS_1} &quot;${workspace_loc:/${CoreName}/Alligator/cores/arduino/syscalls.o}&quot; ${INPUTS} ${LINK_FLAGS_2}" id="cdt.managedbuild.tool.gnu.cross.cpp.linker.1616069436" name="Cross G++ Linker" superClass="cdt.managedbuild.tool.gnu.cross.cpp.linker">
+ <tool command="gcc" commandLinePattern="${COMMAND} ${FLAGS} ${OUTPUT_FLAG} ${OUTPUT_PREFIX}${OUTPUT} ${LinkFlags1} &quot;${workspace_loc:/${CoreName}/Alligator/cores/arduino/syscalls.o}&quot; ${INPUTS} ${LinkFlags2}" id="cdt.managedbuild.tool.gnu.cross.cpp.linker.1616069436" name="Cross G++ Linker" superClass="cdt.managedbuild.tool.gnu.cross.cpp.linker">
<option id="gnu.cpp.link.option.nostdlibs.760089516" name="No startup or default libs (-nostdlib)" superClass="gnu.cpp.link.option.nostdlibs" useByScannerDiscovery="false" value="false" valueType="boolean"/>
<option id="gnu.cpp.link.option.paths.1593340130" name="Library search path (-L)" superClass="gnu.cpp.link.option.paths" useByScannerDiscovery="false" valueType="libPaths">
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${CoreName}/Alligator/}&quot;"/>
diff --git a/.settings/language.settings.xml b/.settings/language.settings.xml
index 12317ec3..497e9709 100644
--- a/.settings/language.settings.xml
+++ b/.settings/language.settings.xml
@@ -5,7 +5,7 @@
<provider copy-of="extension" id="org.eclipse.cdt.ui.UserLanguageSettingsProvider"/>
<provider-reference id="org.eclipse.cdt.core.ReferencedProjectsLanguageSettingsProvider" ref="shared-provider"/>
<provider-reference id="org.eclipse.cdt.managedbuilder.core.MBSLanguageSettingsProvider" ref="shared-provider"/>
- <provider class="org.eclipse.cdt.internal.build.crossgcc.CrossGCCBuiltinSpecsDetector" console="false" env-hash="-120605374140718211" id="org.eclipse.cdt.build.crossgcc.CrossGCCBuiltinSpecsDetector" keep-relative-paths="false" name="CDT Cross GCC Built-in Compiler Settings" parameter="${COMMAND} ${FLAGS} -E -P -v -dD &quot;${INPUTS}&quot;" prefer-non-shared="true">
+ <provider class="org.eclipse.cdt.internal.build.crossgcc.CrossGCCBuiltinSpecsDetector" console="false" env-hash="-1419419586637520295" id="org.eclipse.cdt.build.crossgcc.CrossGCCBuiltinSpecsDetector" keep-relative-paths="false" name="CDT Cross GCC Built-in Compiler Settings" parameter="${COMMAND} ${FLAGS} -E -P -v -dD &quot;${INPUTS}&quot;" prefer-non-shared="true">
<language-scope id="org.eclipse.cdt.core.gcc"/>
<language-scope id="org.eclipse.cdt.core.g++"/>
</provider>
@@ -16,7 +16,7 @@
<provider copy-of="extension" id="org.eclipse.cdt.ui.UserLanguageSettingsProvider"/>
<provider-reference id="org.eclipse.cdt.core.ReferencedProjectsLanguageSettingsProvider" ref="shared-provider"/>
<provider-reference id="org.eclipse.cdt.managedbuilder.core.MBSLanguageSettingsProvider" ref="shared-provider"/>
- <provider class="org.eclipse.cdt.internal.build.crossgcc.CrossGCCBuiltinSpecsDetector" console="false" env-hash="-120605374140718211" id="org.eclipse.cdt.build.crossgcc.CrossGCCBuiltinSpecsDetector" keep-relative-paths="false" name="CDT Cross GCC Built-in Compiler Settings" parameter="${COMMAND} ${FLAGS} -E -P -v -dD &quot;${INPUTS}&quot;" prefer-non-shared="true">
+ <provider class="org.eclipse.cdt.internal.build.crossgcc.CrossGCCBuiltinSpecsDetector" console="false" env-hash="-1419419586637520295" id="org.eclipse.cdt.build.crossgcc.CrossGCCBuiltinSpecsDetector" keep-relative-paths="false" name="CDT Cross GCC Built-in Compiler Settings" parameter="${COMMAND} ${FLAGS} -E -P -v -dD &quot;${INPUTS}&quot;" prefer-non-shared="true">
<language-scope id="org.eclipse.cdt.core.gcc"/>
<language-scope id="org.eclipse.cdt.core.g++"/>
</provider>
@@ -27,7 +27,7 @@
<provider copy-of="extension" id="org.eclipse.cdt.ui.UserLanguageSettingsProvider"/>
<provider-reference id="org.eclipse.cdt.core.ReferencedProjectsLanguageSettingsProvider" ref="shared-provider"/>
<provider-reference id="org.eclipse.cdt.managedbuilder.core.MBSLanguageSettingsProvider" ref="shared-provider"/>
- <provider class="org.eclipse.cdt.internal.build.crossgcc.CrossGCCBuiltinSpecsDetector" console="false" env-hash="-120605374140718211" id="org.eclipse.cdt.build.crossgcc.CrossGCCBuiltinSpecsDetector" keep-relative-paths="false" name="CDT Cross GCC Built-in Compiler Settings" parameter="${COMMAND} ${FLAGS} -E -P -v -dD &quot;${INPUTS}&quot;" prefer-non-shared="true">
+ <provider class="org.eclipse.cdt.internal.build.crossgcc.CrossGCCBuiltinSpecsDetector" console="false" env-hash="-1419419586637520295" id="org.eclipse.cdt.build.crossgcc.CrossGCCBuiltinSpecsDetector" keep-relative-paths="false" name="CDT Cross GCC Built-in Compiler Settings" parameter="${COMMAND} ${FLAGS} -E -P -v -dD &quot;${INPUTS}&quot;" prefer-non-shared="true">
<language-scope id="org.eclipse.cdt.core.gcc"/>
<language-scope id="org.eclipse.cdt.core.g++"/>
</provider>
@@ -38,7 +38,7 @@
<provider copy-of="extension" id="org.eclipse.cdt.ui.UserLanguageSettingsProvider"/>
<provider-reference id="org.eclipse.cdt.core.ReferencedProjectsLanguageSettingsProvider" ref="shared-provider"/>
<provider-reference id="org.eclipse.cdt.managedbuilder.core.MBSLanguageSettingsProvider" ref="shared-provider"/>
- <provider class="org.eclipse.cdt.internal.build.crossgcc.CrossGCCBuiltinSpecsDetector" console="false" env-hash="-120605374140718211" id="org.eclipse.cdt.build.crossgcc.CrossGCCBuiltinSpecsDetector" keep-relative-paths="false" name="CDT Cross GCC Built-in Compiler Settings" parameter="${COMMAND} ${FLAGS} -E -P -v -dD &quot;${INPUTS}&quot;" prefer-non-shared="true">
+ <provider class="org.eclipse.cdt.internal.build.crossgcc.CrossGCCBuiltinSpecsDetector" console="false" env-hash="-1419419586637520295" id="org.eclipse.cdt.build.crossgcc.CrossGCCBuiltinSpecsDetector" keep-relative-paths="false" name="CDT Cross GCC Built-in Compiler Settings" parameter="${COMMAND} ${FLAGS} -E -P -v -dD &quot;${INPUTS}&quot;" prefer-non-shared="true">
<language-scope id="org.eclipse.cdt.core.gcc"/>
<language-scope id="org.eclipse.cdt.core.g++"/>
</provider>
@@ -49,7 +49,7 @@
<provider copy-of="extension" id="org.eclipse.cdt.ui.UserLanguageSettingsProvider"/>
<provider-reference id="org.eclipse.cdt.core.ReferencedProjectsLanguageSettingsProvider" ref="shared-provider"/>
<provider-reference id="org.eclipse.cdt.managedbuilder.core.MBSLanguageSettingsProvider" ref="shared-provider"/>
- <provider class="org.eclipse.cdt.internal.build.crossgcc.CrossGCCBuiltinSpecsDetector" console="false" env-hash="-120605374140718211" id="org.eclipse.cdt.build.crossgcc.CrossGCCBuiltinSpecsDetector" keep-relative-paths="false" name="CDT Cross GCC Built-in Compiler Settings" parameter="${COMMAND} ${FLAGS} -E -P -v -dD &quot;${INPUTS}&quot;" prefer-non-shared="true">
+ <provider class="org.eclipse.cdt.internal.build.crossgcc.CrossGCCBuiltinSpecsDetector" console="false" env-hash="-1419419586637520295" id="org.eclipse.cdt.build.crossgcc.CrossGCCBuiltinSpecsDetector" keep-relative-paths="false" name="CDT Cross GCC Built-in Compiler Settings" parameter="${COMMAND} ${FLAGS} -E -P -v -dD &quot;${INPUTS}&quot;" prefer-non-shared="true">
<language-scope id="org.eclipse.cdt.core.gcc"/>
<language-scope id="org.eclipse.cdt.core.g++"/>
</provider>
diff --git a/.settings/org.eclipse.cdt.core.prefs b/.settings/org.eclipse.cdt.core.prefs
index 4252b5c1..c393e9a3 100644
--- a/.settings/org.eclipse.cdt.core.prefs
+++ b/.settings/org.eclipse.cdt.core.prefs
@@ -1,26 +1,8 @@
eclipse.preferences.version=1
-environment/project/cdt.managedbuild.config.gnu.cross.exe.release.516195201.976458850.1027429289/LINK_FLAGS_1/delimiter=;
-environment/project/cdt.managedbuild.config.gnu.cross.exe.release.516195201.976458850.1027429289/LINK_FLAGS_1/operation=append
-environment/project/cdt.managedbuild.config.gnu.cross.exe.release.516195201.976458850.1027429289/LINK_FLAGS_1/value=-mthumb -Wl,--cref -Wl,--check-sections -Wl,--gc-sections -Wl,--entry\=Reset_Handler -Wl,--unresolved-symbols\=report-all -Wl,--warn-common -Wl,--warn-section-align -Wl,--warn-unresolved-symbols -Wl,--start-group
-environment/project/cdt.managedbuild.config.gnu.cross.exe.release.516195201.976458850.1027429289/LINK_FLAGS_2/delimiter=;
-environment/project/cdt.managedbuild.config.gnu.cross.exe.release.516195201.976458850.1027429289/LINK_FLAGS_2/operation=append
-environment/project/cdt.managedbuild.config.gnu.cross.exe.release.516195201.976458850.1027429289/LINK_FLAGS_2/value=-Wl,--end-group -lm -gcc
environment/project/cdt.managedbuild.config.gnu.cross.exe.release.516195201.976458850.1027429289/append=true
environment/project/cdt.managedbuild.config.gnu.cross.exe.release.516195201.976458850.1027429289/appendContributed=true
-environment/project/cdt.managedbuild.config.gnu.cross.exe.release.516195201.976458850.1745168887/LINK_FLAGS_1/delimiter=;
-environment/project/cdt.managedbuild.config.gnu.cross.exe.release.516195201.976458850.1745168887/LINK_FLAGS_1/operation=append
-environment/project/cdt.managedbuild.config.gnu.cross.exe.release.516195201.976458850.1745168887/LINK_FLAGS_1/value=-mthumb -Wl,--cref -Wl,--check-sections -Wl,--gc-sections -Wl,--entry\=Reset_Handler -Wl,--unresolved-symbols\=report-all -Wl,--warn-common -Wl,--warn-section-align -Wl,--warn-unresolved-symbols -Wl,--start-group
-environment/project/cdt.managedbuild.config.gnu.cross.exe.release.516195201.976458850.1745168887/LINK_FLAGS_2/delimiter=;
-environment/project/cdt.managedbuild.config.gnu.cross.exe.release.516195201.976458850.1745168887/LINK_FLAGS_2/operation=append
-environment/project/cdt.managedbuild.config.gnu.cross.exe.release.516195201.976458850.1745168887/LINK_FLAGS_2/value=-Wl,--end-group -lm -gcc
environment/project/cdt.managedbuild.config.gnu.cross.exe.release.516195201.976458850.1745168887/append=true
environment/project/cdt.managedbuild.config.gnu.cross.exe.release.516195201.976458850.1745168887/appendContributed=true
-environment/project/cdt.managedbuild.config.gnu.cross.exe.release.516195201.976458850.241502451.1275216290/LINK_FLAGS_1/delimiter=;
-environment/project/cdt.managedbuild.config.gnu.cross.exe.release.516195201.976458850.241502451.1275216290/LINK_FLAGS_1/operation=append
-environment/project/cdt.managedbuild.config.gnu.cross.exe.release.516195201.976458850.241502451.1275216290/LINK_FLAGS_1/value=-mthumb -Wl,--cref -Wl,--check-sections -Wl,--gc-sections -Wl,--entry\=Reset_Handler -Wl,--unresolved-symbols\=report-all -Wl,--warn-common -Wl,--warn-section-align -Wl,--warn-unresolved-symbols -Wl,--start-group
-environment/project/cdt.managedbuild.config.gnu.cross.exe.release.516195201.976458850.241502451.1275216290/LINK_FLAGS_2/delimiter=;
-environment/project/cdt.managedbuild.config.gnu.cross.exe.release.516195201.976458850.241502451.1275216290/LINK_FLAGS_2/operation=append
-environment/project/cdt.managedbuild.config.gnu.cross.exe.release.516195201.976458850.241502451.1275216290/LINK_FLAGS_2/value=-Wl,--end-group -lm -gcc
environment/project/cdt.managedbuild.config.gnu.cross.exe.release.516195201.976458850.241502451.1275216290/append=true
environment/project/cdt.managedbuild.config.gnu.cross.exe.release.516195201.976458850.241502451.1275216290/appendContributed=true
environment/project/cdt.managedbuild.config.gnu.cross.exe.release.516195201.976458850.241502451.286403080/LINK_FLAGS_1/delimiter=;
@@ -31,20 +13,8 @@ environment/project/cdt.managedbuild.config.gnu.cross.exe.release.516195201.9764
environment/project/cdt.managedbuild.config.gnu.cross.exe.release.516195201.976458850.241502451.286403080/LINK_FLAGS_2/value=-Wl,--end-group -lm -gcc
environment/project/cdt.managedbuild.config.gnu.cross.exe.release.516195201.976458850.241502451.286403080/append=true
environment/project/cdt.managedbuild.config.gnu.cross.exe.release.516195201.976458850.241502451.286403080/appendContributed=true
-environment/project/cdt.managedbuild.config.gnu.cross.exe.release.516195201.976458850.241502451/LINK_FLAGS_1/delimiter=;
-environment/project/cdt.managedbuild.config.gnu.cross.exe.release.516195201.976458850.241502451/LINK_FLAGS_1/operation=append
-environment/project/cdt.managedbuild.config.gnu.cross.exe.release.516195201.976458850.241502451/LINK_FLAGS_1/value=-mthumb -Wl,--cref -Wl,--check-sections -Wl,--gc-sections -Wl,--entry\=Reset_Handler -Wl,--unresolved-symbols\=report-all -Wl,--warn-common -Wl,--warn-section-align -Wl,--warn-unresolved-symbols -Wl,--start-group
-environment/project/cdt.managedbuild.config.gnu.cross.exe.release.516195201.976458850.241502451/LINK_FLAGS_2/delimiter=;
-environment/project/cdt.managedbuild.config.gnu.cross.exe.release.516195201.976458850.241502451/LINK_FLAGS_2/operation=append
-environment/project/cdt.managedbuild.config.gnu.cross.exe.release.516195201.976458850.241502451/LINK_FLAGS_2/value=-Wl,--end-group -lm -gcc
environment/project/cdt.managedbuild.config.gnu.cross.exe.release.516195201.976458850.241502451/append=true
environment/project/cdt.managedbuild.config.gnu.cross.exe.release.516195201.976458850.241502451/appendContributed=true
-environment/project/cdt.managedbuild.config.gnu.cross.exe.release.516195201.976458850/LINK_FLAGS_1/delimiter=;
-environment/project/cdt.managedbuild.config.gnu.cross.exe.release.516195201.976458850/LINK_FLAGS_1/operation=append
-environment/project/cdt.managedbuild.config.gnu.cross.exe.release.516195201.976458850/LINK_FLAGS_1/value=-mthumb -Wl,--cref -Wl,--check-sections -Wl,--gc-sections -Wl,--entry\=Reset_Handler -Wl,--unresolved-symbols\=report-all -Wl,--warn-common -Wl,--warn-section-align -Wl,--warn-unresolved-symbols -Wl,--start-group
-environment/project/cdt.managedbuild.config.gnu.cross.exe.release.516195201.976458850/LINK_FLAGS_2/delimiter=;
-environment/project/cdt.managedbuild.config.gnu.cross.exe.release.516195201.976458850/LINK_FLAGS_2/operation=append
-environment/project/cdt.managedbuild.config.gnu.cross.exe.release.516195201.976458850/LINK_FLAGS_2/value=-Wl,--end-group -lm -gcc
environment/project/cdt.managedbuild.config.gnu.cross.exe.release.516195201.976458850/append=true
environment/project/cdt.managedbuild.config.gnu.cross.exe.release.516195201.976458850/appendContributed=true
environment/project/cdt.managedbuild.config.gnu.cross.exe.release.516195201/LINK_FLAGS_1/delimiter=;
diff --git a/Release/Duet-0.6-0.8.5/Edge/RepRapFirmware-1.20alpha4.bin b/Release/Duet-0.6-0.8.5/Edge/RepRapFirmware-1.20alpha4.bin
deleted file mode 100644
index 100d0371..00000000
--- a/Release/Duet-0.6-0.8.5/Edge/RepRapFirmware-1.20alpha4.bin
+++ /dev/null
Binary files differ
diff --git a/Release/Duet-0.6-0.8.5/Edge/RepRapFirmware-1.20beta1.bin b/Release/Duet-0.6-0.8.5/Edge/RepRapFirmware-1.20beta1.bin
deleted file mode 100644
index 13f24d0a..00000000
--- a/Release/Duet-0.6-0.8.5/Edge/RepRapFirmware-1.20beta1.bin
+++ /dev/null
Binary files differ
diff --git a/Release/Duet-0.6-0.8.5/Edge/RepRapFirmware-1.20beta6.bin b/Release/Duet-0.6-0.8.5/Edge/RepRapFirmware-1.20beta6.bin
deleted file mode 100644
index 8add86d9..00000000
--- a/Release/Duet-0.6-0.8.5/Edge/RepRapFirmware-1.20beta6.bin
+++ /dev/null
Binary files differ
diff --git a/Release/Duet-0.6-0.8.5/Edge/RepRapFirmware-1.20beta8.bin b/Release/Duet-0.6-0.8.5/Edge/RepRapFirmware-1.20beta8.bin
new file mode 100644
index 00000000..9a9a7056
--- /dev/null
+++ b/Release/Duet-0.6-0.8.5/Edge/RepRapFirmware-1.20beta8.bin
Binary files differ
diff --git a/Release/Duet-Ethernet/Edge/DuetEthernetFirmware-1.20beta1.bin b/Release/Duet-Ethernet/Edge/DuetEthernetFirmware-1.20beta1.bin
deleted file mode 100644
index 393b3cf0..00000000
--- a/Release/Duet-Ethernet/Edge/DuetEthernetFirmware-1.20beta1.bin
+++ /dev/null
Binary files differ
diff --git a/Release/Duet-Ethernet/Edge/DuetEthernetFirmware-1.20beta4.bin b/Release/Duet-Ethernet/Edge/DuetEthernetFirmware-1.20beta4.bin
deleted file mode 100644
index 9736d30b..00000000
--- a/Release/Duet-Ethernet/Edge/DuetEthernetFirmware-1.20beta4.bin
+++ /dev/null
Binary files differ
diff --git a/Release/Duet-Ethernet/Edge/DuetEthernetFirmware-1.20beta6.bin b/Release/Duet-Ethernet/Edge/DuetEthernetFirmware-1.20beta6.bin
deleted file mode 100644
index 3f5f5fb1..00000000
--- a/Release/Duet-Ethernet/Edge/DuetEthernetFirmware-1.20beta6.bin
+++ /dev/null
Binary files differ
diff --git a/Release/Duet-Ethernet/Edge/DuetEthernetFirmware-1.20beta8.bin b/Release/Duet-Ethernet/Edge/DuetEthernetFirmware-1.20beta8.bin
new file mode 100644
index 00000000..85e146ec
--- /dev/null
+++ b/Release/Duet-Ethernet/Edge/DuetEthernetFirmware-1.20beta8.bin
Binary files differ
diff --git a/Release/Duet-WiFi/Edge/DuetWiFiFirmware-1.20beta1.bin b/Release/Duet-WiFi/Edge/DuetWiFiFirmware-1.20beta1.bin
deleted file mode 100644
index 43eabb0b..00000000
--- a/Release/Duet-WiFi/Edge/DuetWiFiFirmware-1.20beta1.bin
+++ /dev/null
Binary files differ
diff --git a/Release/Duet-WiFi/Edge/DuetWiFiFirmware-1.20beta4.bin b/Release/Duet-WiFi/Edge/DuetWiFiFirmware-1.20beta4.bin
deleted file mode 100644
index 50a4be1d..00000000
--- a/Release/Duet-WiFi/Edge/DuetWiFiFirmware-1.20beta4.bin
+++ /dev/null
Binary files differ
diff --git a/Release/Duet-WiFi/Edge/DuetWiFiFirmware-1.20beta6.bin b/Release/Duet-WiFi/Edge/DuetWiFiFirmware-1.20beta6.bin
deleted file mode 100644
index f8213326..00000000
--- a/Release/Duet-WiFi/Edge/DuetWiFiFirmware-1.20beta6.bin
+++ /dev/null
Binary files differ
diff --git a/Release/Duet-WiFi/Edge/DuetWiFiFirmware-1.20beta8.bin b/Release/Duet-WiFi/Edge/DuetWiFiFirmware-1.20beta8.bin
new file mode 100644
index 00000000..7686f483
--- /dev/null
+++ b/Release/Duet-WiFi/Edge/DuetWiFiFirmware-1.20beta8.bin
Binary files differ
diff --git a/Release/Duet-WiFi/Edge/DuetWiFiServer-1.20beta9.bin b/Release/Duet-WiFi/Edge/DuetWiFiServer-1.20beta9.bin
new file mode 100644
index 00000000..903c3e8b
--- /dev/null
+++ b/Release/Duet-WiFi/Edge/DuetWiFiServer-1.20beta9.bin
Binary files differ
diff --git a/src/Configuration.h b/src/Configuration.h
index c6b9754f..d75c50d7 100644
--- a/src/Configuration.h
+++ b/src/Configuration.h
@@ -71,11 +71,12 @@ constexpr float HOT_ENOUGH_TO_RETRACT = 90.0; // Celsius
constexpr uint8_t MAX_BAD_TEMPERATURE_COUNT = 4; // Number of bad temperature samples permitted before a heater fault is reported
constexpr float BAD_LOW_TEMPERATURE = -10.0; // Celsius
-constexpr float DefaultExtruderTemperatureLimit = 288.0; // Celsius - E3D say to tighten the hot end at 285C
+constexpr float DefaultExtruderTemperatureLimit = 290.0; // Celsius - E3D say to tighten the hot end at 285C
constexpr float DefaultBedTemperatureLimit = 125.0; // Celsius
constexpr float HOT_END_FAN_TEMPERATURE = 45.0; // Temperature at which a thermostatic hot end fan comes on
constexpr float ThermostatHysteresis = 1.0; // How much hysteresis we use to prevent noise turning fans on/off too often
constexpr float BAD_ERROR_TEMPERATURE = 2000.0; // Must exceed any reasonable 5temperature limit including DEFAULT_TEMPERATURE_LIMIT
+constexpr uint32_t DefaultHeaterFaultTimeout = 10 * 60 * 1000; // How long we wait (in milliseconds) for user intervention after a heater fault before shutting down
// Heating model default parameters. For the chamber heater, we use the same values as for the bed heater.
// These parameters are about right for an E3Dv6 hot end with 30W heater.
diff --git a/src/DuetNG/DueXn.cpp b/src/DuetNG/DueXn.cpp
index 8f35a223..4eb80210 100644
--- a/src/DuetNG/DueXn.cpp
+++ b/src/DuetNG/DueXn.cpp
@@ -56,23 +56,23 @@ namespace DuetExpansion
// Identify which expansion board (if any) is attached and initialise it
ExpansionBoardType DueXnInit()
{
- uint8_t ret = dueXnExpander.begin(DueXnAddress);
- if (ret != 1)
+ bool ret = dueXnExpander.begin(DueXnAddress);
+ if (!ret)
{
delay(100); // wait a little while
ret = dueXnExpander.begin(DueXnAddress); // do 1 retry
}
- if (ret != 1)
- {
- dueXnBoardType = ExpansionBoardType::none; // no device found at that address, or a serious error
- }
- else
+ if (ret)
{
dueXnExpander.pinModeMultiple(BoardTypePins, INPUT_PULLUP);
const uint16_t data = dueXnExpander.digitalReadAll();
dueXnBoardType = boardTypes[(data & BoardTypePins) >> BoardTypeShift];
}
+ else
+ {
+ dueXnBoardType = ExpansionBoardType::none; // no device found at that address, or a serious error
+ }
if (dueXnBoardType != ExpansionBoardType::none)
{
@@ -98,14 +98,14 @@ namespace DuetExpansion
// Look for an additional output pin expander
void AdditionalOutputInit()
{
- uint8_t ret = additionalIoExpander.begin(AdditionalIoExpanderAddress);
- if (ret != 1)
+ bool ret = additionalIoExpander.begin(AdditionalIoExpanderAddress);
+ if (!ret)
{
delay(100); // wait a little while
ret = additionalIoExpander.begin(AdditionalIoExpanderAddress); // do 1 retry
}
- if (ret == 1)
+ if (ret)
{
additionalIoExpander.pinModeMultiple((1u << 16) - 1, INPUT_PULLDOWN);
additionalIoInputBits = additionalIoExpander.digitalReadAll();
@@ -173,7 +173,7 @@ namespace DuetExpansion
break;
case INPUT_PULLUP:
case INPUT_PULLDOWN:
- mode = INPUT; // we are using 5rV-tolerant input with external pullup resistors, so don't enable internal pullup/pulldown resistors
+ mode = INPUT; // we are using 5V-tolerant input with external pullup resistors, so don't enable internal pullup/pulldown resistors
break;
default:
break;
diff --git a/src/DuetNG/DuetWiFi/Network.cpp b/src/DuetNG/DuetWiFi/Network.cpp
index c776fc7c..70032b99 100644
--- a/src/DuetNG/DuetWiFi/Network.cpp
+++ b/src/DuetNG/DuetWiFi/Network.cpp
@@ -103,8 +103,8 @@ static inline void DisableEspInterrupt()
// WiFi interface class
Network::Network(Platform& p) : platform(p), nextResponderToPoll(nullptr), uploader(nullptr), currentSocket(0), ftpDataPort(0),
- state(NetworkState::disabled), requestedMode(WiFiState::disabled), currentMode(WiFiState::disabled), activated(false), serialRunning(false),
- espStatusChanged(false), spiTxUnderruns(0), spiRxOverruns(0)
+ state(NetworkState::disabled), requestedMode(WiFiState::disabled), currentMode(WiFiState::disabled), activated(false),
+ espStatusChanged(false), spiTxUnderruns(0), spiRxOverruns(0), serialRunning(false)
{
for (size_t i = 0; i < NumProtocols; ++i)
{
@@ -476,7 +476,6 @@ void Network::Spin(bool full)
{
if (espStatusChanged && digitalRead(EspTransferRequestPin))
{
- Platform::softwareResetDebugInfo = 1;
if (reprap.Debug(moduleNetwork))
{
debugPrintf("ESP reported status change\n");
@@ -489,7 +488,6 @@ void Network::Spin(bool full)
&& currentMode != WiFiState::autoReconnecting
)
{
- Platform::softwareResetDebugInfo = 2;
// Tell the wifi module to change mode
int32_t rslt = ResponseUnknownError;
if (currentMode != WiFiState::idle)
@@ -518,7 +516,6 @@ void Network::Spin(bool full)
}
else if (currentMode == WiFiState::connected || currentMode == WiFiState::runningAsAccessPoint)
{
- Platform::softwareResetDebugInfo = 3;
// Find the next socket to poll
const size_t startingSocket = currentSocket;
do
@@ -553,7 +550,6 @@ void Network::Spin(bool full)
{
nr = responders; // 'responders' can't be null at this point
}
- Platform::softwareResetDebugInfo = 4;
doneSomething = nr->Spin();
nr = nr->GetNext();
} while (!doneSomething && nr != nextResponderToPoll);
@@ -561,16 +557,6 @@ void Network::Spin(bool full)
}
}
}
- else if (currentMode == requestedMode && (currentMode == WiFiState::connected || currentMode == WiFiState::runningAsAccessPoint))
- {
- Platform::softwareResetDebugInfo = 5;
- sockets[currentSocket].Poll(full);
- ++currentSocket;
- if (currentSocket == NumTcpSockets)
- {
- currentSocket = 0;
- }
- }
break;
case NetworkState::changingMode:
@@ -614,9 +600,40 @@ void Network::Spin(bool full)
break;
}
- Platform::softwareResetDebugInfo = 0;
+ // Check for debug info received from the WiFi module
+ if (serialRunning)
+ {
+ while (!debugPrintPending && Serial1.available() != 0)
+ {
+ const char c = (char)Serial1.read();
+ if (c == '\n')
+ {
+ debugPrintPending = true;
+ }
+ else if (c != '\r')
+ {
+ const size_t len = debugMessageBuffer.cat(c);
+ if (len == debugMessageBuffer.MaxLength())
+ {
+ debugPrintPending = true;
+ }
+ }
+ }
+ }
+
if (full)
{
+ // Check for debug info received from the WiFi module
+ if (debugPrintPending)
+ {
+ if (reprap.Debug(moduleWiFi))
+ {
+ debugPrintf("WiFi: %s\n", debugMessageBuffer.Pointer());
+ }
+ debugMessageBuffer.Clear();
+ debugPrintPending = false;
+ }
+
platform.ClassReport(longWait);
}
}
@@ -1385,8 +1402,10 @@ void Network::StartWiFi()
{
digitalWrite(EspResetPin, HIGH);
ConfigurePin(g_APinDescription[APINS_UART1]); // connect the pins to UART1
- Serial1.begin(115200); // initialise the UART, to receive debug info
+ Serial1.begin(WiFiBaudRate); // initialise the UART, to receive debug info
+ debugMessageBuffer.Clear();
serialRunning = true;
+ debugPrintPending = false;
}
// Reset the ESP8266 and leave held in reset
diff --git a/src/DuetNG/DuetWiFi/Network.h b/src/DuetNG/DuetWiFi/Network.h
index c2081895..de20b7cf 100644
--- a/src/DuetNG/DuetWiFi/Network.h
+++ b/src/DuetNG/DuetWiFi/Network.h
@@ -147,7 +147,6 @@ private:
WiFiState requestedMode;
WiFiState currentMode;
bool activated;
- bool serialRunning;
volatile bool espStatusChanged;
uint8_t ipAddress[4];
@@ -165,6 +164,11 @@ private:
unsigned int responseTimeoutCount;
char wiFiServerVersion[16];
+
+ // For processing debug messages from the WiFi module
+ bool serialRunning;
+ bool debugPrintPending;
+ String<100> debugMessageBuffer;
};
#endif
diff --git a/src/DuetNG/SX1509.cpp b/src/DuetNG/SX1509.cpp
index d2e628bf..73ac5c3e 100644
--- a/src/DuetNG/SX1509.cpp
+++ b/src/DuetNG/SX1509.cpp
@@ -26,12 +26,11 @@ Distributed as-is; no warranty is given.
#include "SX1509.h"
#include "SX1509Registers.h"
-SX1509::SX1509()
+SX1509::SX1509() : _clkX(0)
{
- _clkX = 0;
}
-uint8_t SX1509::begin(uint8_t address)
+bool SX1509::begin(uint8_t address)
{
// Store the received parameters into member variables
deviceAddress = address;
@@ -41,20 +40,18 @@ uint8_t SX1509::begin(uint8_t address)
reset();
- // Communication test. We'll read from two registers with different
- // default values to verify communication.
- unsigned int testRegisters = 0;
- testRegisters = readWord(REG_INTERRUPT_MASK_A); // this should return 0xFF00
+ pwmPins = 0;
- // Then read a byte that should be 0x00
- if (testRegisters == 0xFF00)
+ // Communication test. We'll read from two registers with different default values to verify communication.
+ const uint16_t testRegisters = readWord(REG_INTERRUPT_MASK_A); // this should return 0xFF00
+ const bool ok = (testRegisters == 0xFF00);
+ if (ok)
{
clock(DefaultOscDivider);
- writeWord(REG_HIGH_INPUT_B, 0xFFFF); // set all inputs to be 5V-tolerant
- return 1;
+ writeWord(REG_HIGH_INPUT_B, 0xFFFF); // set all inputs to be 5V-tolerant
}
- return 0;
+ return ok;
}
void SX1509::reset()
@@ -66,15 +63,32 @@ void SX1509::reset()
void SX1509::setBitsInWord(uint8_t registerAddress, uint16_t bits)
{
- const uint16_t regVal = readWord(registerAddress);
- writeWord(registerAddress, regVal | bits);
+ if (bits != 0)
+ {
+ const uint16_t regVal = readWord(registerAddress);
+ writeWord(registerAddress, regVal | bits);
+ }
}
void SX1509::clearBitsInWord(uint8_t registerAddress, uint16_t bits)
{
- const uint16_t regVal = readWord(registerAddress);
- writeWord(registerAddress, regVal & (~bits));
+ if (bits != 0)
+ {
+ const uint16_t regVal = readWord(registerAddress);
+ writeWord(registerAddress, regVal & (~bits));
+ }
+}
+void SX1509::analogWriteMultiple(uint16_t pins, uint8_t pwm)
+{
+ for (uint8_t pin = 0; pins != 0; ++pin)
+ {
+ if ((pins & 1u) != 0)
+ {
+ analogWrite(pin, pwm);
+ }
+ pins >>= 1;
+ }
}
void SX1509::pinMode(uint8_t pin, PinMode inOut)
@@ -82,12 +96,14 @@ void SX1509::pinMode(uint8_t pin, PinMode inOut)
pinModeMultiple(1u << pin, inOut);
}
+// Set the pin mode for multiple pins.
+// Once we have enabled LED driver mode, disabling it doesn't seem to work.
+// So we track which pins are in PWM (i.e. LED driver) mode, and we never try to switch them back to being ordinary outputs.
void SX1509::pinModeMultiple(uint16_t pins, PinMode inOut)
{
switch (inOut)
{
case INPUT:
- clearBitsInWord(REG_LED_DRIVER_ENABLE_B, pins);
clearBitsInWord(REG_INPUT_DISABLE_B, pins);
setBitsInWord(REG_DIR_B, pins);
clearBitsInWord(REG_PULL_UP_B, pins);
@@ -95,7 +111,6 @@ void SX1509::pinModeMultiple(uint16_t pins, PinMode inOut)
break;
case INPUT_PULLUP:
- clearBitsInWord(REG_LED_DRIVER_ENABLE_B, pins);
clearBitsInWord(REG_INPUT_DISABLE_B, pins);
setBitsInWord(REG_DIR_B, pins);
clearBitsInWord(REG_PULL_DOWN_B, pins);
@@ -103,7 +118,6 @@ void SX1509::pinModeMultiple(uint16_t pins, PinMode inOut)
break;
case INPUT_PULLDOWN:
- clearBitsInWord(REG_LED_DRIVER_ENABLE_B, pins);
clearBitsInWord(REG_INPUT_DISABLE_B, pins);
setBitsInWord(REG_DIR_B, pins);
clearBitsInWord(REG_PULL_UP_B, pins);
@@ -111,39 +125,39 @@ void SX1509::pinModeMultiple(uint16_t pins, PinMode inOut)
break;
case OUTPUT_LOW:
- clearBitsInWord(REG_LED_DRIVER_ENABLE_B, pins);
clearBitsInWord(REG_PULL_UP_B, pins);
clearBitsInWord(REG_PULL_DOWN_B, pins);
- clearBitsInWord(REG_DATA_B, pins);
+ clearBitsInWord(REG_DATA_B, pins & ~pwmPins);
clearBitsInWord(REG_OPEN_DRAIN_B, pins);
clearBitsInWord(REG_DIR_B, pins);
+ analogWriteMultiple(pins & pwmPins, 0);
break;
case OUTPUT_HIGH:
- clearBitsInWord(REG_LED_DRIVER_ENABLE_B, pins);
clearBitsInWord(REG_PULL_UP_B, pins);
clearBitsInWord(REG_PULL_DOWN_B, pins);
- setBitsInWord(REG_DATA_B, pins);
+ setBitsInWord(REG_DATA_B, pins & ~pwmPins);
clearBitsInWord(REG_OPEN_DRAIN_B, pins);
clearBitsInWord(REG_DIR_B, pins);
+ analogWriteMultiple(pins & pwmPins, 255);
break;
case OUTPUT_LOW_OPEN_DRAIN:
- clearBitsInWord(REG_LED_DRIVER_ENABLE_B, pins);
clearBitsInWord(REG_PULL_UP_B, pins);
clearBitsInWord(REG_PULL_DOWN_B, pins);
- clearBitsInWord(REG_DATA_B, pins);
+ clearBitsInWord(REG_DATA_B, pins & ~pwmPins);
setBitsInWord(REG_OPEN_DRAIN_B, pins);
clearBitsInWord(REG_DIR_B, pins);
+ analogWriteMultiple(pins & pwmPins, 0);
break;
case OUTPUT_HIGH_OPEN_DRAIN:
- clearBitsInWord(REG_LED_DRIVER_ENABLE_B, pins);
clearBitsInWord(REG_PULL_UP_B, pins);
clearBitsInWord(REG_PULL_DOWN_B, pins);
- setBitsInWord(REG_DATA_B, pins);
+ setBitsInWord(REG_DATA_B, pins & ~pwmPins);
setBitsInWord(REG_OPEN_DRAIN_B, pins);
clearBitsInWord(REG_DIR_B, pins);
+ analogWriteMultiple(pins & pwmPins, 255);
break;
case OUTPUT_PWM_LOW:
@@ -162,7 +176,11 @@ void SX1509::pinModeMultiple(uint16_t pins, PinMode inOut)
void SX1509::digitalWrite(uint8_t pin, bool highLow)
{
- if (highLow)
+ if (((1u << pin) & pwmPins) != 0)
+ {
+ analogWrite(pin, (highLow) ? 255 : 0);
+ }
+ else if (highLow)
{
setBitsInWord(REG_DATA_B, 1u << pin);
}
@@ -189,11 +207,15 @@ uint16_t SX1509::digitalReadAll()
return readWord(REG_DATA_B);
}
+#if 0 // unused
+
void SX1509::ledDriverInit(uint8_t pin, bool log, bool openDrain)
{
ledDriverInitMultiple(1u << pin, log, openDrain);
}
+#endif
+
void SX1509::ledDriverInitMultiple(uint16_t pins, bool log, bool openDrain)
{
if (openDrain)
@@ -208,7 +230,6 @@ void SX1509::ledDriverInitMultiple(uint16_t pins, bool log, bool openDrain)
clearBitsInWord(REG_PULL_UP_B, pins); // disable pullup
clearBitsInWord(REG_PULL_DOWN_B, pins); // disable pulldown
clearBitsInWord(REG_DIR_B, pins); // set as an output
-
// Configure LED driver clock and mode (REG_MISC)
uint8_t tempByte = readByte(REG_MISC);
@@ -227,6 +248,8 @@ void SX1509::ledDriverInitMultiple(uint16_t pins, bool log, bool openDrain)
// Set REG_DATA bit low ~ LED driver started
clearBitsInWord(REG_DATA_B, pins);
+
+ pwmPins |= pins; // record which pins are in LED driver mode
}
void SX1509::analogWrite(uint8_t pin, uint8_t iOn)
@@ -239,6 +262,8 @@ void SX1509::analogWrite(uint8_t pin, uint8_t iOn)
writeByte(REG_I_ON[pin], ~iOn);
}
+#if 0 // these functions are not used
+
void SX1509::blink(uint8_t pin, unsigned long tOn, unsigned long tOff, uint8_t onIntensity, uint8_t offIntensity)
{
const uint8_t onReg = calculateLEDTRegister(tOn);
@@ -489,6 +514,8 @@ void SX1509::debounceKeypad(uint8_t time, uint8_t numRows, uint8_t numCols)
}
}
+#endif
+
void SX1509::enableInterrupt(uint8_t pin, uint8_t riseFall)
{
enableInterruptMultiple(1u << pin, riseFall);
@@ -650,7 +677,7 @@ uint16_t SX1509::readWord(uint8_t registerAddress)
Wire.endTransmission();
Wire.requestFrom(deviceAddress, (uint8_t) 2);
- while ((Wire.available() < 2) && (timeout != 0))
+ while (Wire.available() < 2 && timeout != 0)
{
timeout--;
}
@@ -660,8 +687,8 @@ uint16_t SX1509::readWord(uint8_t registerAddress)
return 0;
}
- uint16_t msb = (Wire.read() & 0x00FF) << 8;
- uint16_t lsb = (Wire.read() & 0x00FF);
+ const uint16_t msb = (Wire.read() & 0x00FF) << 8;
+ const uint16_t lsb = (Wire.read() & 0x00FF);
return msb | lsb;
}
@@ -772,7 +799,7 @@ void SX1509::writeBytes(uint8_t firstRegisterAddress, uint8_t * writeArray, uint
{
Wire.beginTransmission(deviceAddress);
Wire.write(firstRegisterAddress);
- for (uint8_t i=0; i < length; i++)
+ for (uint8_t i = 0; i < length; i++)
{
Wire.write(writeArray[i]);
}
diff --git a/src/DuetNG/SX1509.h b/src/DuetNG/SX1509.h
index d4a0fc53..6a4653e6 100644
--- a/src/DuetNG/SX1509.h
+++ b/src/DuetNG/SX1509.h
@@ -36,6 +36,7 @@ private:
// Misc variables:
uint32_t _clkX;
+ uint16_t pwmPins; // bitmap of pins configured as PWM output pins
// Read Functions:
uint8_t readByte(uint8_t registerAddress);
@@ -50,6 +51,7 @@ private:
void writeBytes(uint8_t firstRegisterAddress, uint8_t * writeArray, uint8_t length);
void setBitsInWord(uint8_t registerAddress, uint16_t bits);
void clearBitsInWord(uint8_t registerAddress, uint16_t bits);
+ void analogWriteMultiple(uint16_t pins, uint8_t pwm);
// Helper functions:
@@ -76,10 +78,10 @@ public:
// - address: should be the 7-bit address of the SX1509. This should be
// one of four values - 0x3E, 0x3F, 0x70, 0x71 - all depending on what the
// ADDR0 and ADDR1 pins are set to. This variable is required.
- // Output: Returns a 1 if communication is successful, 0 on error.
+ // Output: Returns true if communication is successful, false on error.
// -----------------------------------------------------------------------------
- uint8_t begin(uint8_t address);
-
+ bool begin(uint8_t address);
+
// -----------------------------------------------------------------------------
// reset(): This function resets the SX1509. A software
// reset writes a 0x12 then 0x34 to the REG_RESET as outlined in the
@@ -97,7 +99,7 @@ public:
// inOut parameter. They do what they say!
// -----------------------------------------------------------------------------
void pinMode(uint8_t pin, PinMode inOut);
-
+
// pinModeMultiple(uint16_t pins, PinMode inOut): This function sets several of the SX1509's 16
// outputs to either an INPUT or OUTPUT.
//
@@ -130,12 +132,13 @@ public:
// This function returns true if HIGH, false if LOW
// -----------------------------------------------------------------------------
bool digitalRead(uint8_t pin);
-
+
// -----------------------------------------------------------------------------
// digitalReadAll(): This function reads all 16 pins.
// -----------------------------------------------------------------------------
uint16_t digitalReadAll();
+#if 0 // unused
// -----------------------------------------------------------------------------
// ledDriverInit(uint8_t pin, bool log): This function initializes LED
// driving on a pin. It must be called if you want to use the pwm or blink
@@ -148,7 +151,8 @@ public:
// - currently log sets both bank A and B to the same mode
// -----------------------------------------------------------------------------
void ledDriverInit(uint8_t pin, bool log, bool openDrain);
-
+#endif
+
// -----------------------------------------------------------------------------
// ledDriverInitMultiple(uint16_t pins, bool log): This function initializes LED
// driving on a pin. It must be called if you want to use the pwm or blink
@@ -174,7 +178,9 @@ public:
// Note: ledDriverInit should be called on the pin before calling this.
// -----------------------------------------------------------------------------
void analogWrite(uint8_t pin, uint8_t iOn);
-
+
+#if 0 // these functions are not used
+
// -----------------------------------------------------------------------------
// setupBlink(uint8_t pin, uint8_t tOn, uint8_t tOff, uint8_t offIntensity, uint8_t tRise, uint8_t
// tFall): blink performs both the blink and breath LED driver functions.
@@ -352,6 +358,8 @@ public:
// -----------------------------------------------------------------------------
void debounceKeypad(uint8_t time, uint8_t numRows, uint8_t numCols);
+#endif
+
// -----------------------------------------------------------------------------
// enableInterrupt(uint8_t pin, uint8_t riseFall): This function sets up an interrupt
// on a pin. Interrupts can occur on all SX1509 pins, and can be generated
@@ -370,7 +378,7 @@ public:
// pull-up/down resistors! Do that before (or after).
// -----------------------------------------------------------------------------
void enableInterrupt(uint8_t pin, uint8_t riseFall);
-
+
// -----------------------------------------------------------------------------
// enableInterruptMultiple(uint16_t pins, uint8_t riseFall): This function sets up an interrupt
// on a pin. Interrupts can occur on all SX1509 pins, and can be generated
diff --git a/src/GCodes/GCodes.cpp b/src/GCodes/GCodes.cpp
index dfb93a62..e5a25f75 100644
--- a/src/GCodes/GCodes.cpp
+++ b/src/GCodes/GCodes.cpp
@@ -110,9 +110,14 @@ void GCodes::Init()
retractSpeed = unRetractSpeed = DefaultRetractSpeed * SecondsToMinutes;
isRetracted = false;
lastAuxStatusReportType = -1; // no status reports requested yet
+
spindleMaxRpm = DefaultMaxSpindleRpm;
laserMaxPower = DefaultMaxLaserPower;
+ heaterFaultState = HeaterFaultState::noFault;
+ heaterFaultTime = 0;
+ heaterFaultTimeout = DefaultHeaterFaultTimeout;
+
#if SUPPORT_SCANNER
reprap.GetScanner().SetGCodeBuffer(serialGCode);
#endif
@@ -260,6 +265,7 @@ void GCodes::Spin()
}
CheckTriggers();
+ CheckHeaterFault();
CheckFilament();
// Get the GCodeBuffer that we want to process a command from. Give priority to auto-pause.
@@ -583,6 +589,7 @@ void GCodes::RunStateMachine(GCodeBuffer& gb, StringRef& reply)
virtualExtruderPosition = pauseRestorePoint.virtualExtruderPosition; // reset the extruder position in case we are receiving absolute extruder moves
moveBuffer.virtualExtruderPosition = pauseRestorePoint.virtualExtruderPosition;
fileGCode->MachineState().feedrate = pauseRestorePoint.feedRate;
+ moveFractionToSkip = pauseRestorePoint.proportionDone;
isPaused = false;
reply.copy("Printing resumed");
platform.Message(LogMessage, "Printing resumed\n");
@@ -640,7 +647,7 @@ void GCodes::RunStateMachine(GCodeBuffer& gb, StringRef& reply)
{
reprap.StandbyTool(tool->Number());
}
- reprap.GetHeat().SwitchOffAll();
+ reprap.GetHeat().SwitchOffAll(true);
}
// chrishamm 2014-18-10: Although RRP says M0 is supposed to turn off all drives and heaters,
@@ -1203,7 +1210,7 @@ void GCodes::RunStateMachine(GCodeBuffer& gb, StringRef& reply)
}
else
{
- SaveResumeInfo(true); // create the resume file so that we can resume after power down
+ SaveResumeInfo(true); // create the resume file so that we can resume after power down
platform.Message(LoggedGenericMessage, "Print auto-paused due to low voltage\n");
gb.SetState(GCodeState::normal);
}
@@ -1419,7 +1426,8 @@ void GCodes::CheckFilament()
&& LockMovement(*autoPauseGCode) // need to lock movement before executing the pause macro
)
{
- DoPause(*autoPauseGCode, PauseReason::filament, "Extruder %u reports %s", lastFilamentErrorExtruder, FilamentSensor::GetErrorMessage(lastFilamentError));
+ scratchString.printf("Extruder %u reports %s", lastFilamentErrorExtruder, FilamentSensor::GetErrorMessage(lastFilamentError));
+ DoPause(*autoPauseGCode, PauseReason::filament, scratchString.Pointer());
lastFilamentError = FilamentSensorStatus::ok;
}
}
@@ -1443,7 +1451,7 @@ void GCodes::DoEmergencyStop()
}
// Pause the print. Before calling this, check that we are doing a file print that isn't already paused and get the movement lock.
-void GCodes::DoPause(GCodeBuffer& gb, PauseReason reason, const char *msg, ...)
+void GCodes::DoPause(GCodeBuffer& gb, PauseReason reason, const char *msg)
{
if (&gb == fileGCode)
{
@@ -1464,13 +1472,10 @@ void GCodes::DoPause(GCodeBuffer& gb, PauseReason reason, const char *msg, ...)
else if (segmentsLeft != 0 && moveBuffer.canPauseBefore)
{
// We were not able to skip any moves, however we can skip the move that is waiting
- ToolOffsetInverseTransform(moveBuffer.initialCoords, currentUserPosition);
- pauseRestorePoint.feedRate = moveBuffer.feedRate;
pauseRestorePoint.virtualExtruderPosition = moveBuffer.virtualExtruderPosition;
pauseRestorePoint.filePos = moveBuffer.filePos;
-#if SUPPORT_IOBITS
- pauseRestorePoint.ioBits = moveBuffer.ioBits;
-#endif
+ pauseRestorePoint.feedRate = moveBuffer.feedRate;
+ ToolOffsetInverseTransform(pauseRestorePoint.moveCoords, currentUserPosition); // transform the returned coordinates to user coordinates
ClearMove();
}
else
@@ -1511,6 +1516,8 @@ void GCodes::DoPause(GCodeBuffer& gb, PauseReason reason, const char *msg, ...)
}
SaveFanSpeeds();
+ pauseRestorePoint.toolNumber = reprap.GetCurrentToolNumber();
+
if (simulationMode == 0)
{
SaveResumeInfo(false); // create the resume file so that we can resume after power down
@@ -1521,11 +1528,7 @@ void GCodes::DoPause(GCodeBuffer& gb, PauseReason reason, const char *msg, ...)
if (msg != nullptr)
{
- va_list vargs;
- va_start(vargs, msg);
- scratchString.vprintf(msg, vargs);
- va_end(vargs);
- platform.SendAlert(GenericMessage, scratchString.Pointer(), "Printing paused", 1, 0.0, 0);
+ platform.SendAlert(GenericMessage, msg, "Printing paused", 1, 0.0, 0);
}
}
@@ -1580,6 +1583,69 @@ bool GCodes::IsReallyPrinting() const
return reprap.GetPrintMonitor().IsPrinting() && IsRunning();
}
+#if HAS_VOLTAGE_MONITOR || HAS_SMART_DRIVERS
+
+// Do an emergency pause following loss of power or a motor stall returning true if successful, false if needs to be retried
+bool GCodes::DoEmergencyPause()
+{
+ if (!autoPauseGCode->IsCompletelyIdle())
+ {
+ return false; // we can't pause if the auto pause thread is busy already
+ }
+
+ // Save the resume info, stop movement immediately and run the low voltage pause script to lift the nozzle etc.
+ GrabMovement(*autoPauseGCode);
+
+ const bool movesSkipped = reprap.GetMove().LowPowerPause(pauseRestorePoint);
+ if (movesSkipped)
+ {
+ // The PausePrint call has filled in the restore point with machine coordinates
+ ToolOffsetInverseTransform(pauseRestorePoint.moveCoords, currentUserPosition); // transform the returned coordinates to user coordinates
+ ClearMove();
+ }
+ else if (segmentsLeft != 0 && moveBuffer.filePos != noFilePosition)
+ {
+ // We were not able to skip any moves, however we can skip the remaining segments of this current move
+ ToolOffsetInverseTransform(moveBuffer.initialCoords, currentUserPosition);
+ pauseRestorePoint.feedRate = moveBuffer.feedRate;
+ pauseRestorePoint.virtualExtruderPosition = moveBuffer.virtualExtruderPosition;
+ pauseRestorePoint.filePos = moveBuffer.filePos;
+ pauseRestorePoint.proportionDone = (float)(totalSegments - segmentsLeft)/(float)totalSegments;
+#if SUPPORT_IOBITS
+ pauseRestorePoint.ioBits = moveBuffer.ioBits;
+#endif
+ ClearMove();
+ }
+ else
+ {
+ // We were not able to skip any moves, and if there is a move waiting then we can't skip that one either
+ pauseRestorePoint.feedRate = fileGCode->MachineState().feedrate;
+ pauseRestorePoint.virtualExtruderPosition = virtualExtruderPosition;
+
+ // TODO: when we use RTOS there is a possible race condition in the following,
+ // because we might try to pause when a waiting move has just been added but before the gcode buffer has been re-initialised ready for the next command
+ pauseRestorePoint.filePos = fileGCode->GetFilePosition(fileInput->BytesCached());
+ pauseRestorePoint.proportionDone = 0.0;
+#if SUPPORT_IOBITS
+ pauseRestorePoint.ioBits = moveBuffer.ioBits;
+#endif
+ }
+
+ // Replace the paused machine coordinates by user coordinates, which we updated earlier
+ for (size_t axis = 0; axis < numVisibleAxes; ++axis)
+ {
+ pauseRestorePoint.moveCoords[axis] = currentUserPosition[axis];
+ }
+
+ SaveFanSpeeds();
+ pauseRestorePoint.toolNumber = reprap.GetCurrentToolNumber();
+ isPaused = true;
+
+ return true;
+}
+
+#endif
+
#if HAS_VOLTAGE_MONITOR
// Try to pause the current SD card print, returning true if successful, false if needs to be called again
@@ -1590,7 +1656,7 @@ bool GCodes::LowVoltagePause()
return true; // ignore the low voltage indication
}
- reprap.GetHeat().SuspendHeaters(true); // turn heaters off to conserve power for the motors to execute the pause
+ reprap.GetHeat().SuspendHeaters(true); // turn the heaters off to conserve power for the motors to execute the pause
if (IsResuming())
{
// This is an unlucky situation, because the resume macro is probably being run, which will probably lower the head back on to the print.
@@ -1613,64 +1679,17 @@ bool GCodes::LowVoltagePause()
if (reprap.GetPrintMonitor().IsPrinting())
{
- if (!autoPauseGCode->IsCompletelyIdle())
- {
- return false; // we can't pause if the auto pause thread is busy already
- }
-
- // Save the resume info, stop movement immediately and run the low voltage pause script to lift the nozzle etc.
- GrabMovement(*autoPauseGCode);
-
- const bool movesSkipped = reprap.GetMove().LowPowerPause(pauseRestorePoint);
- if (movesSkipped)
- {
- // The PausePrint call has filled in the restore point with machine coordinates
- ToolOffsetInverseTransform(pauseRestorePoint.moveCoords, currentUserPosition); // transform the returned coordinates to user coordinates
- ClearMove();
- }
- else if (segmentsLeft != 0 && moveBuffer.filePos != noFilePosition)
- {
- // We were not able to skip any moves, however we can skip the remaining segments of this current move
- ToolOffsetInverseTransform(moveBuffer.initialCoords, currentUserPosition);
- pauseRestorePoint.feedRate = moveBuffer.feedRate;
- pauseRestorePoint.virtualExtruderPosition = moveBuffer.virtualExtruderPosition;
- pauseRestorePoint.filePos = moveBuffer.filePos;
- pauseRestorePoint.proportionDone = (float)(totalSegments - segmentsLeft)/(float)totalSegments;
-#if SUPPORT_IOBITS
- pauseRestorePoint.ioBits = moveBuffer.ioBits;
-#endif
- ClearMove();
- }
- else
+ if (!DoEmergencyPause())
{
- // We were not able to skip any moves, and if there is a move waiting then we can't skip that one either
- pauseRestorePoint.feedRate = fileGCode->MachineState().feedrate;
- pauseRestorePoint.virtualExtruderPosition = virtualExtruderPosition;
-
- // TODO: when we use RTOS there is a possible race condition in the following,
- // because we might try to pause when a waiting move has just been added but before the gcode buffer has been re-initialised ready for the next command
- pauseRestorePoint.filePos = fileGCode->GetFilePosition(fileInput->BytesCached());
- pauseRestorePoint.proportionDone = 0.0;
-#if SUPPORT_IOBITS
- pauseRestorePoint.ioBits = moveBuffer.ioBits;
-#endif
- }
-
- // Replace the paused machine coordinates by user coordinates, which we updated earlier
- for (size_t axis = 0; axis < numVisibleAxes; ++axis)
- {
- pauseRestorePoint.moveCoords[axis] = currentUserPosition[axis];
+ return false;
}
- SaveFanSpeeds();
-
// Run the auto-pause script
if (powerFailScript != nullptr)
{
autoPauseGCode->Put(powerFailScript);
}
autoPauseGCode->SetState(GCodeState::powerFailPausing1);
- isPaused = true;
isPowerFailPaused = true;
// Don't do any more here, we want the auto pause thread to run as soon as possible
@@ -1683,22 +1702,60 @@ bool GCodes::LowVoltagePause()
// If the pause was short enough, resume automatically.
bool GCodes::LowVoltageResume()
{
- reprap.GetHeat().SuspendHeaters(false); // turn heaters off to conserve power for the motors to execute the pause
+ reprap.GetHeat().SuspendHeaters(false); // turn the heaters on again
if (isPaused && isPowerFailPaused)
{
+ isPowerFailPaused = false; // pretend it's a normal pause
// Run resurrect.g automatically
//TODO qq;
- platform.Message(LoggedGenericMessage, "Print auto-resumed\n");
+ //platform.Message(LoggedGenericMessage, "Print auto-resumed\n");
+ }
+ return true;
+}
+
+#endif
+
+#if HAS_SMART_DRIVERS
+
+// Pause the print because the specified driver has reported a stall
+bool GCodes::PauseOnStall(DriversBitmap stalledDrivers)
+{
+ if (!IsReallyPrinting())
+ {
+ return true; // if not printing, acknowledge it but take no action
+ }
+ if (!autoPauseGCode->IsCompletelyIdle())
+ {
+ return false; // can't handle it yet
}
+ if (!LockMovement(*autoPauseGCode))
+ {
+ return false;
+ }
+
+ scratchString.printf("Stall detected on driver(s)");
+ ListDrivers(scratchString, stalledDrivers);
+ DoPause(*autoPauseGCode, PauseReason::stall, scratchString.Pointer());
return true;
}
-// Permit printing to be resumed after it has been suspended
-bool GCodes::AutoResumeAfterShutdown()
+// Re-home and resume the print because the specified driver has reported a stall
+bool GCodes::ReHomeOnStall(DriversBitmap stalledDrivers)
{
- // Currently we don't do anything here
+ if (!IsReallyPrinting())
+ {
+ return true; // if not printing, acknowledge it but take no action
+ }
+ if (!DoEmergencyPause())
+ {
+ return false; // can't handle it yet
+ }
+
+ autoPauseGCode->SetState(GCodeState::resuming1); // set up to resume after rehoming
+ DoFileMacro(*autoPauseGCode, REHOME_G, true); // run the SD card rehome-and-resume script
return true;
}
+
#endif
void GCodes::SaveResumeInfo(bool wasPowerFailure)
@@ -1989,12 +2046,9 @@ bool GCodes::DoStraightMove(GCodeBuffer& gb, StringRef& reply, bool isCoordinate
moveBuffer.isCoordinated = isCoordinated;
moveBuffer.endStopsToCheck = 0;
moveBuffer.moveType = 0;
- doingArcMove = false;
moveBuffer.xAxes = reprap.GetCurrentXAxes();
moveBuffer.yAxes = reprap.GetCurrentYAxes();
moveBuffer.usePressureAdvance = false;
- moveBuffer.filePos = (&gb == fileGCode) ? gb.GetFilePosition(fileInput->BytesCached()) : noFilePosition;
- moveBuffer.virtualExtruderPosition = virtualExtruderPosition;
axesToSenseLength = 0;
// Check to see if the move is a 'homing' move that endstops are checked on.
@@ -2060,9 +2114,6 @@ bool GCodes::DoStraightMove(GCodeBuffer& gb, StringRef& reply, bool isCoordinate
}
}
- moveBuffer.canPauseAfter = (moveBuffer.endStopsToCheck == 0);
- moveBuffer.canPauseBefore = true;
-
// Check for 'R' parameter to move relative to a restore point
int rParam = (moveBuffer.moveType == 0 && gb.Seen('R')) ? gb.GetIValue() : 0;
const RestorePoint * const rp = (rParam == 1) ? &pauseRestorePoint : (rParam == 2) ? &toolChangeRestorePoint : nullptr;
@@ -2192,11 +2243,12 @@ bool GCodes::DoStraightMove(GCodeBuffer& gb, StringRef& reply, bool isCoordinate
}
}
- segmentsLeft = totalSegments;
+ doingArcMove = false;
+ FinaliseMove(gb);
return false;
}
-// Execute an arc move returning true if it was badly-formed
+// Execute an arc move, returning true if it was badly-formed
// We already have the movement lock and the last move has gone
// Currently, we do not process new babystepping when executing an arc move
bool GCodes::DoArcMove(GCodeBuffer& gb, bool clockwise)
@@ -2256,13 +2308,9 @@ bool GCodes::DoArcMove(GCodeBuffer& gb, bool clockwise)
// Set up default move parameters
moveBuffer.endStopsToCheck = 0;
moveBuffer.moveType = 0;
- moveBuffer.canPauseAfter = moveBuffer.canPauseBefore = true;
moveBuffer.xAxes = reprap.GetCurrentXAxes();
moveBuffer.yAxes = reprap.GetCurrentYAxes();
- moveBuffer.virtualExtruderPosition = virtualExtruderPosition;
- moveBuffer.endStopsToCheck = 0;
moveBuffer.isCoordinated = true;
- moveBuffer.filePos = (&gb == fileGCode) ? gb.GetFilePosition(fileInput->BytesCached()) : noFilePosition;
// Set up the arc centre coordinates and record which axes behave like an X axis.
// The I and J parameters are always relative to present position.
@@ -2299,14 +2347,45 @@ bool GCodes::DoArcMove(GCodeBuffer& gb, bool clockwise)
{
arcAngleIncrement = -arcAngleIncrement;
}
- doingArcMove = true;
- segmentsLeft = totalSegments; // must do this last for RTOS
+ doingArcMove = true;
+ FinaliseMove(gb);
// debugPrintf("Radius %.2f, initial angle %.1f, increment %.1f, segments %u\n",
// arcRadius, arcCurrentAngle * RadiansToDegrees, arcAngleIncrement * RadiansToDegrees, segmentsLeft);
return false;
}
+// Adjust the move parameters to account for segmentation and/or part of the move having been done already
+void GCodes::FinaliseMove(const GCodeBuffer& gb)
+{
+ moveBuffer.canPauseAfter = (moveBuffer.endStopsToCheck == 0);
+ moveBuffer.canPauseBefore = true;
+ moveBuffer.filePos = (&gb == fileGCode) ? gb.GetFilePosition(fileInput->BytesCached()) : noFilePosition;
+ moveBuffer.virtualExtruderPosition = virtualExtruderPosition;
+
+ if (totalSegments > 1)
+ {
+ for (size_t drive = numTotalAxes; drive < DRIVES; ++drive)
+ {
+ moveBuffer.coords[drive] /= totalSegments; // change the extrusion to extrusion per segment
+ }
+
+ if (moveFractionToSkip != 0.0)
+ {
+ const float fseg = floor(totalSegments * moveFractionToSkip); // round down to the start of a move
+ segmentsLeftToStartAt = totalSegments - (unsigned int)fseg;
+ firstSegmentFractionToSkip = (moveFractionToSkip * totalSegments) - fseg;
+ segmentsLeft = totalSegments; // do this last, ready for RTOS
+ return;
+ }
+ }
+
+ segmentsLeftToStartAt = totalSegments;
+ firstSegmentFractionToSkip = moveFractionToSkip;
+
+ segmentsLeft = totalSegments; // do this last, ready for RTOS
+}
+
// The Move class calls this function to find what to do next.
bool GCodes::ReadMove(RawMove& m)
{
@@ -2320,16 +2399,20 @@ bool GCodes::ReadMove(RawMove& m)
if (segmentsLeft == 1)
{
// If there is just 1 segment left, it doesn't matter if it is an arc move or not, just move to the end position
+ if (segmentsLeftToStartAt == 1 && firstSegmentFractionToSkip != 0.0) // if this is the segment we are starting at and we need to skip some of it
+ {
+ // Reduce the extrusion by the amount to be skipped
+ for (size_t drive = numTotalAxes; drive < DRIVES; ++drive)
+ {
+ m.coords[drive] *= (1.0 - firstSegmentFractionToSkip);
+ }
+ }
+ m.proportionLeft = 0.0;
ClearMove();
- m.proportionRemaining = 0;
}
else
{
// This move needs to be divided into 2 or more segments
- m.canPauseAfter = false; // we can only do a controlled pause pause after the final segment
- moveBuffer.canPauseBefore = false; // we can't do a controlled pause before any of the remaining segments
- m.proportionRemaining = (uint8_t)min<unsigned int>((((totalSegments - segmentsLeft - 1) * 256) + (totalSegments/2))/totalSegments, 255);
-
// Do the axes
if (doingArcMove)
{
@@ -2359,20 +2442,23 @@ bool GCodes::ReadMove(RawMove& m)
m.coords[drive] = moveBuffer.initialCoords[drive];
}
- // Do the extruders
- for (size_t drive = numTotalAxes; drive < DRIVES; ++drive)
- {
- const float extrusionToDo = moveBuffer.coords[drive]/segmentsLeft;
- m.coords[drive] = extrusionToDo;
- moveBuffer.coords[drive] -= extrusionToDo;
- }
-
- --segmentsLeft;
- if ((unsigned int)moveFractionToSkip + (unsigned int)m.proportionRemaining > 256)
+ if (segmentsLeftToStartAt < segmentsLeft)
{
// We are resuming a print part way through a move and we printed this segment already
+ --segmentsLeft;
return false;
}
+ if (segmentsLeftToStartAt == segmentsLeft && firstSegmentFractionToSkip != 0.0) // if this is the segment we are starting at and we need to skip some of it
+ {
+ // Reduce the extrusion by the amount to be skipped
+ for (size_t drive = numTotalAxes; drive < DRIVES; ++drive)
+ {
+ m.coords[drive] *= (1.0 - firstSegmentFractionToSkip);
+ }
+ }
+ --segmentsLeft;
+
+ m.proportionLeft = (float)segmentsLeft/(float)totalSegments;
}
return true;
@@ -2385,7 +2471,7 @@ void GCodes::ClearMove()
moveBuffer.endStopsToCheck = 0;
moveBuffer.moveType = 0;
moveBuffer.isFirmwareRetraction = false;
- moveFractionToSkip = 0;
+ moveFractionToSkip = 0.0;
}
// Run a file macro. Prior to calling this, 'state' must be set to the state we want to enter when the macro has been completed.
@@ -3059,7 +3145,7 @@ bool GCodes::QueueFileToPrint(const char* fileName, StringRef& reply)
fileToPrint.Set(f);
fileOffsetToPrint = 0;
- moveFractionToStartAt = 0;
+ moveFractionToStartAt = 0.0;
return true;
}
@@ -4466,12 +4552,59 @@ const char* GCodes::GetMachineModeString() const
}
}
-// Respond to a heater fault. The heater has already been turned off and its status set to 'fault' when this is called.
+// Respond to a heater fault. The heater has already been turned off and its status set to 'fault' when this is called from the Heat module.
+// The Heat module will generate an appropriate error message, so on need to do that here.
void GCodes::HandleHeaterFault(int heater)
{
- if (IsReallyPrinting())
+ if (heaterFaultState == HeaterFaultState::noFault && fileGCode->OriginalMachineState().fileState.IsLive())
{
- DoPause(*autoPauseGCode, PauseReason::heaterFault, "Fault on heater %d", heater);
+ heaterFaultState = HeaterFaultState::pausePending;
+ heaterFaultTime = millis();
+ }
+}
+
+// Check for and respond to a heater fault, returning true if we should exit
+void GCodes::CheckHeaterFault()
+{
+ switch (heaterFaultState)
+ {
+ case HeaterFaultState::noFault:
+ default:
+ break;
+
+ case HeaterFaultState::pausePending:
+ if ( IsReallyPrinting()
+ && autoPauseGCode->IsCompletelyIdle()
+ && LockMovement(*autoPauseGCode) // need to lock movement before executing the pause macro
+ )
+ {
+ reprap.GetHeat().SwitchOffAll(false); // turn off all extruder heaters
+ DoPause(*autoPauseGCode, PauseReason::heaterFault, "Heater fault");
+ heaterFaultState = HeaterFaultState::timing;
+ }
+ else if (IsPausing() || IsPaused())
+ {
+ heaterFaultState = HeaterFaultState::timing;
+ }
+ // no break
+
+ case HeaterFaultState::timing:
+ if (millis() - heaterFaultTime >= heaterFaultTimeout)
+ {
+ StopPrint(false);
+ reprap.GetHeat().SwitchOffAll(true);
+ reprap.GetPlatform().MessageF(ErrorMessage, "Shutting down due to un-cleared heater fault after %lu seconds\n", heaterFaultTimeout/1000);
+ heaterFaultState = HeaterFaultState::stopping;
+ }
+ break;
+
+ case HeaterFaultState::stopping:
+ if (millis() - heaterFaultTime >= 2000) // wait 2 seconds for the message to be picked up by DWC and PanelDue
+ {
+ reprap.GetPlatform().SetAtxPower(false);
+ heaterFaultState = HeaterFaultState::stopped;
+ }
+ break;
}
}
diff --git a/src/GCodes/GCodes.h b/src/GCodes/GCodes.h
index e44f7756..72bf6bd1 100644
--- a/src/GCodes/GCodes.h
+++ b/src/GCodes/GCodes.h
@@ -107,6 +107,7 @@ public:
float feedRate; // feed rate of this move
float virtualExtruderPosition; // the virtual extruder position at the start of this move
FilePosition filePos; // offset in the file being printed at the start of reading this move
+ float proportionLeft; // what proportion of the entire move remains after this segment
AxesBitmap xAxes; // axes that X is mapped to
AxesBitmap yAxes; // axes that Y is mapped to
EndstopChecks endStopsToCheck; // endstops to check
@@ -114,7 +115,6 @@ public:
IoBits_t ioBits; // I/O bits to set/clear at the start of this move
#endif
uint8_t moveType; // the S parameter from the G0 or G1 command, 0 for a normal move
- uint8_t proportionRemaining; // what proportion of the entire move remains after this segment
uint8_t isFirmwareRetraction : 1; // true if this is a firmware retraction/un-retraction move
uint8_t usePressureAdvance : 1; // true if we want to us extruder pressure advance, if there is any extrusion
@@ -185,7 +185,11 @@ public:
#if HAS_VOLTAGE_MONITOR
bool LowVoltagePause();
bool LowVoltageResume();
- bool AutoResumeAfterShutdown();
+#endif
+
+#if HAS_SMART_DRIVERS
+ bool PauseOnStall(DriversBitmap stalledDrivers);
+ bool ReHomeOnStall(DriversBitmap stalledDrivers);
#endif
const char *GetAxisLetters() const { return axisLetters; } // Return a null-terminated string of axis letters indexed by drive
@@ -193,7 +197,7 @@ public:
private:
GCodes(const GCodes&); // private copy constructor to prevent copying
- enum class CannedMoveType : uint8_t { none, relative, absolute };
+ enum class HeaterFaultState : uint8_t { noFault, pausePending, timing, stopping, stopped };
// Resources that can be locked.
// To avoid deadlock, if you need multiple resources then you must lock them in increasing numerical order.
@@ -231,6 +235,7 @@ private:
bool DoStraightMove(GCodeBuffer& gb, StringRef& reply, bool isCoordinated) __attribute__((hot)); // Execute a straight move returning true if an error was written to 'reply'
bool DoArcMove(GCodeBuffer& gb, bool clockwise) // Execute an arc move returning true if it was badly-formed
pre(segmentsLeft == 0; resourceOwners[MoveResource] == &gb);
+ void FinaliseMove(const GCodeBuffer& gb); // Adjust the move parameters to account for segmentation and/or part of the move having been done already
GCodeResult DoDwell(GCodeBuffer& gb); // Wait for a bit
GCodeResult DoDwellTime(GCodeBuffer& gb, uint32_t dwellMillis); // Really wait for a bit
@@ -278,10 +283,15 @@ private:
void ListTriggers(StringRef reply, TriggerInputsBitmap mask); // Append a list of trigger inputs to a message
void CheckTriggers(); // Check for and execute triggers
void CheckFilament(); // Check for and respond to filament errors
+ void CheckHeaterFault(); // Check for and respond to a heater fault, returning true if we should exit
void DoEmergencyStop(); // Execute an emergency stop
- void DoPause(GCodeBuffer& gb, PauseReason reason, const char *msg, ...) __attribute__ ((format (printf, 4, 5))); // Pause the print
- pre(resourceOwners[movementResource] = &gb);
+ void DoPause(GCodeBuffer& gb, PauseReason reason, const char *msg) // Pause the print
+ pre(resourceOwners[movementResource] = &gb);
+
+#if HAS_VOLTAGE_MONITOR || HAS_SMART_DRIVERS
+ bool DoEmergencyPause(); // Do an emergency pause following loss of power or a motor stall
+#endif
void SetMappedFanSpeed(); // Set the speeds of fans mapped for the current tool
void SaveFanSpeeds(); // Save the speeds of all fans
@@ -338,10 +348,7 @@ private:
bool runningConfigFile; // We are running config.g during the startup process
bool doingToolChange; // We are running tool change macros
- uint8_t moveFractionToStartAt; // how much of the next move was printed before the power failure
- uint8_t moveFractionToSkip;
-
- #if HAS_VOLTAGE_MONITOR
+#if HAS_VOLTAGE_MONITOR
bool isPowerFailPaused; // true if the print was paused automatically because of a power failure
char *powerFailScript; // the commands run when there is a power failure
#endif
@@ -353,6 +360,12 @@ private:
RawMove moveBuffer; // Move details to pass to Move class
unsigned int segmentsLeft; // The number of segments left to do in the current move, or 0 if no move available
unsigned int totalSegments; // The total number of segments left in the complete move
+
+ unsigned int segmentsLeftToStartAt;
+ float moveFractionToStartAt; // how much of the next move was printed before the power failure
+ float moveFractionToSkip;
+ float firstSegmentFractionToSkip;
+
float arcCentre[MaxAxes];
float arcRadius;
float arcCurrentAngle;
@@ -448,6 +461,11 @@ private:
float spindleMaxRpm;
float laserMaxPower;
+ // Heater fault handler
+ HeaterFaultState heaterFaultState; // whether there is a heater fault and what we have done about it so far
+ uint32_t heaterFaultTime; // when the heater fault occurred
+ uint32_t heaterFaultTimeout; // how long we wait for the user to fix it before turning everything off
+
// Misc
uint32_t longWait; // Timer for things that happen occasionally (seconds)
uint32_t lastWarningMillis; // When we last sent a warning message for things that can happen very often
@@ -459,7 +477,9 @@ private:
bool displayDeltaNotHomedWarning; // True if we need to display a 'attempt to move before homing on a delta printer' message
char filamentToLoad[FilamentNameLength]; // Name of the filament being loaded
+ // Standard macro filenames
static constexpr const char* BED_EQUATION_G = "bed.g";
+ static constexpr const char* PAUSE_G = "pause.g";
static constexpr const char* RESUME_G = "resume.g";
static constexpr const char* CANCEL_G = "cancel.g";
static constexpr const char* STOP_G = "stop.g";
@@ -467,14 +487,14 @@ private:
static constexpr const char* CONFIG_OVERRIDE_G = "config-override.g";
static constexpr const char* DEPLOYPROBE_G = "deployprobe.g";
static constexpr const char* RETRACTPROBE_G = "retractprobe.g";
- static constexpr const char* PAUSE_G = "pause.g";
- static constexpr const char* HOME_ALL_G = "homeall.g";
- static constexpr const char* HOME_DELTA_G = "homedelta.g";
static constexpr const char* DefaultHeightMapFile = "heightmap.csv";
static constexpr const char* LOAD_FILAMENT_G = "load.g";
static constexpr const char* UNLOAD_FILAMENT_G = "unload.g";
static constexpr const char* RESUME_AFTER_POWER_FAIL_G = "resurrect.g";
static constexpr const char* RESUME_PROLOGUE_G = "resurrect-prologue.g";
+#if HAS_SMART_DRIVERS
+ static constexpr const char* REHOME_G = "rehome.g";
+#endif
static constexpr const float MinServoPulseWidth = 544.0, MaxServoPulseWidth = 2400.0;
static const uint16_t ServoRefreshFrequency = 50;
diff --git a/src/GCodes/GCodes2.cpp b/src/GCodes/GCodes2.cpp
index 69626468..33dfdc64 100644
--- a/src/GCodes/GCodes2.cpp
+++ b/src/GCodes/GCodes2.cpp
@@ -19,6 +19,7 @@
#include "RepRap.h"
#include "Tools/Tool.h"
#include "FilamentSensors/FilamentSensor.h"
+#include "Libraries/General/IP4String.h"
#include "Version.h"
#if SUPPORT_IOBITS
@@ -88,13 +89,13 @@ bool GCodes::HandleGcode(GCodeBuffer& gb, StringRef& reply)
switch (code)
{
- case 0: // There are no rapid moves...
+ case 0: // Rapid move
case 1: // Ordinary move
- if (!LockMovement(gb))
+ if (segmentsLeft != 0) // do this check first to avoid locking movement unnecessarily
{
return false;
}
- if (segmentsLeft != 0)
+ if (!LockMovement(gb))
{
return false;
}
@@ -107,11 +108,11 @@ bool GCodes::HandleGcode(GCodeBuffer& gb, StringRef& reply)
case 2: // Clockwise arc
case 3: // Anti clockwise arc
// We only support X and Y axes in these (and optionally Z for corkscrew moves), but you can map them to other axes in the tool definitions
- if (!LockMovement(gb))
+ if (segmentsLeft != 0) // do this check first to avoid locking movement unnecessarily
{
return false;
}
- if (segmentsLeft != 0)
+ if (!LockMovement(gb))
{
return false;
}
@@ -691,7 +692,7 @@ bool GCodes::HandleMcode(GCodeBuffer& gb, StringRef& reply)
fileOffsetToPrint = (FilePosition)gb.GetUIValue();
if (gb.Seen('P'))
{
- moveFractionToStartAt = (uint8_t)constrain<unsigned long>(lrintf(gb.GetFValue()), 0, 255);
+ moveFractionToStartAt = constrain<float>(gb.GetFValue(), 0.0, 1.0);
}
}
break;
@@ -891,32 +892,54 @@ bool GCodes::HandleMcode(GCodeBuffer& gb, StringRef& reply)
if (gb.Seen('P'))
{
const LogicalPin logicalPin = gb.GetIValue();
- Pin pin;
- bool invert;
- if (platform.GetFirmwarePin(logicalPin, PinAccess::pwm, pin, invert))
+ if (gb.Seen('S'))
{
- if (gb.Seen('S'))
+ float val = gb.GetFValue();
+ if (val > 1.0)
+ {
+ val /= 255.0;
+ }
+ val = constrain<float>(val, 0.0, 1.0);
+
+ // The SX1509B I/O expander chip doesn't seem to work if you set PWM mode and then set digital output mode.
+ // This cases a problem if M42 is used to write to some pins and then M670 is used to set up the G1 P parameter port mapping.
+ // The first part of the fix for this is to not select PWM mode if we don't need to.
+ bool usePwm;
+ uint16_t freq;
+ if (gb.Seen('F'))
+ {
+ freq = constrain<int32_t>(gb.GetIValue(), 1, 65536);
+ usePwm = true;
+ }
+ else
+ {
+ freq = DefaultPinWritePwmFreq;
+ usePwm = (val != 0.0 && val != 1.0);
+ }
+
+ Pin pin;
+ bool invert;
+ if (platform.GetFirmwarePin(logicalPin, (usePwm) ? PinAccess::pwm : PinAccess::write, pin, invert))
{
- float val = gb.GetFValue();
- if (val > 1.0)
- {
- val /= 255.0;
- }
- val = constrain<float>(val, 0.0, 1.0);
if (invert)
{
val = 1.0 - val;
}
- const uint16_t freq = (gb.Seen('F')) ? (uint16_t)constrain<int32_t>(gb.GetIValue(), 1, 65536) : DefaultPinWritePwmFreq;
- IoPort::WriteAnalog(pin, val, freq);
+ if (usePwm)
+ {
+ IoPort::WriteAnalog(pin, val, freq);
+ }
+ else
+ {
+ IoPort::WriteDigital(pin, val == 1.0);
+ }
+ }
+ else
+ {
+ reply.printf("Logical pin %d is not available for writing", logicalPin);
+ result = GCodeResult::error;
}
- // Ignore the command if no S parameter provided
- }
- else
- {
- reply.printf("Logical pin %d is not available for writing", logicalPin);
- result = GCodeResult::error;
}
}
break;
@@ -2014,7 +2037,8 @@ bool GCodes::HandleMcode(GCodeBuffer& gb, StringRef& reply)
float gain = model.GetGain(),
tc = model.GetTimeConstant(),
td = model.GetDeadTime(),
- maxPwm = model.GetMaxPwm();
+ maxPwm = model.GetMaxPwm(),
+ voltage = model.GetVoltage();
int32_t dontUsePid = model.UsePid() ? 0 : 1;
gb.TryGetFValue('A', gain, seen);
@@ -2022,10 +2046,11 @@ bool GCodes::HandleMcode(GCodeBuffer& gb, StringRef& reply)
gb.TryGetFValue('D', td, seen);
gb.TryGetIValue('B', dontUsePid, seen);
gb.TryGetFValue('S', maxPwm, seen);
+ gb.TryGetFValue('V', voltage, seen);
if (seen)
{
- if (!reprap.GetHeat().SetHeaterModel(heater, gain, tc, td, maxPwm, dontUsePid == 0))
+ if (!reprap.GetHeat().SetHeaterModel(heater, gain, tc, td, maxPwm, voltage, dontUsePid == 0))
{
reply.copy("Error: bad model parameters");
}
@@ -2036,11 +2061,11 @@ bool GCodes::HandleMcode(GCodeBuffer& gb, StringRef& reply)
}
else
{
- const char* mode = (!model.UsePid()) ? "bang-bang"
- : (model.ArePidParametersOverridden()) ? "custom PID"
- : "PID";
- reply.printf("Heater %u model: gain %.1f, time constant %.1f, dead time %.1f, max PWM %.2f, mode: %s",
- heater, (double)model.GetGain(), (double)model.GetTimeConstant(), (double)model.GetDeadTime(), (double)model.GetMaxPwm(), mode);
+ const char* const mode = (!model.UsePid()) ? "bang-bang"
+ : (model.ArePidParametersOverridden()) ? "custom PID"
+ : "PID";
+ reply.printf("Heater %u model: gain %.1f, time constant %.1f, dead time %.1f, max PWM %.2f, calibration voltage %.1f, mode: %s",
+ heater, (double)model.GetGain(), (double)model.GetTimeConstant(), (double)model.GetDeadTime(), (double)model.GetMaxPwm(), (double)model.GetVoltage(), mode);
if (model.UsePid())
{
// When reporting the PID parameters, we scale them by 255 for compatibility with older firmware and other firmware
@@ -2672,6 +2697,15 @@ bool GCodes::HandleMcode(GCodeBuffer& gb, StringRef& reply)
result = GCodeResult::error;
}
}
+ else
+ {
+ // Clear all heater faults
+ for (int heater = 0; heater < (int)Heaters; ++heater)
+ {
+ reprap.ClearTemperatureFault(heater);
+ }
+ }
+ heaterFaultState = HeaterFaultState::noFault;
break;
case 563: // Define tool
@@ -3518,47 +3552,38 @@ bool GCodes::HandleMcode(GCodeBuffer& gb, StringRef& reply)
else
{
// List remembered networks
- const size_t declaredBufferLength = (MaxRememberedNetworks + 1) * (SsidLength + 1) + 1; // enough for all the remembered SSIDs with newline terminator, plus an extra null
- uint32_t buffer[NumDwords(declaredBufferLength + 1)];
- const int32_t rslt = reprap.GetNetwork().SendCommand(NetworkCommand::networkListSsids, 0, 0, nullptr, 0, buffer, declaredBufferLength);
+ const size_t declaredBufferLength = (MaxRememberedNetworks + 1) * ReducedWirelessConfigurationDataSize; // enough for all the remembered SSID data
+ uint32_t buffer[NumDwords(declaredBufferLength)];
+ const int32_t rslt = reprap.GetNetwork().SendCommand(NetworkCommand::networkRetrieveSsidData, 0, 0, nullptr, 0, buffer, declaredBufferLength);
if (rslt >= 0)
{
- char* const cbuf = reinterpret_cast<char *>(buffer);
- cbuf[declaredBufferLength] = 0; // ensure null terminated
-
- // DuetWiFiServer 1.19beta7 and later include the SSID used in access point mode at the start
- char *bufp = strchr(cbuf, '\n');
- if (bufp == nullptr)
+ OutputBuffer *response = nullptr;
+ size_t offset = ReducedWirelessConfigurationDataSize; // skip own SSID details
+ while (offset + ReducedWirelessConfigurationDataSize <= (size_t)rslt)
{
- bufp = cbuf; // must be an old version of DuetWiFiServer
- }
- else
- {
- ++bufp; // slip the first entry
- }
-
- // If there is a trailing newline, remove it
- {
- const size_t len = strlen(bufp);
- if (len != 0 && bufp[len - 1] == '\n')
+ WirelessConfigurationData* const wp = reinterpret_cast<WirelessConfigurationData *>(reinterpret_cast<char*>(buffer) + offset);
+ if (wp->ssid[0] != 0)
{
- bufp[len - 1] = 0;
+ if (response == nullptr)
+ {
+ if (!OutputBuffer::Allocate(response))
+ {
+ return false; // try again later
+ }
+ response->copy("Remembered networks:");
+ }
+ wp->ssid[ARRAY_UPB(wp->ssid)] = 0;
+ response->catf("\n%s IP=%s GW=%s NM=%s", wp->ssid, IP4String(wp->ip).c_str(), IP4String(wp->gateway).c_str(), IP4String(wp->netmask).c_str());
}
+ offset += ReducedWirelessConfigurationDataSize;
}
- if (strlen(bufp) == 0)
+ if (response == nullptr)
{
reply.copy("No remembered networks");
}
else
{
- OutputBuffer *response;
- if (!OutputBuffer::Allocate(response))
- {
- return false; // try again later
- }
- response->copy("Remembered networks:\n");
- response->cat(bufp);
HandleReply(gb, false, response);
return true;
}
@@ -3633,10 +3658,10 @@ bool GCodes::HandleMcode(GCodeBuffer& gb, StringRef& reply)
ok = gb.GetIPAddress(config.ip);
config.channel = (gb.Seen('C')) ? gb.GetIValue() : 0;
}
- }
- else
- {
- ok = false;
+ else
+ {
+ ok = false;
+ }
}
}
}
@@ -3657,23 +3682,24 @@ bool GCodes::HandleMcode(GCodeBuffer& gb, StringRef& reply)
}
else
{
- const size_t declaredBufferLength = (MaxRememberedNetworks + 1) * (SsidLength + 1) + 1; // enough for all the remembered SSIDs with null terminator, plus an extra null
- uint32_t buffer[NumDwords(declaredBufferLength + 1)];
- const int32_t rslt = reprap.GetNetwork().SendCommand(NetworkCommand::networkListSsids, 0, 0, nullptr, 0, buffer, declaredBufferLength);
+ uint32_t buffer[NumDwords(ReducedWirelessConfigurationDataSize)];
+ const int32_t rslt = reprap.GetNetwork().SendCommand(NetworkCommand::networkRetrieveSsidData, 0, 0, nullptr, 0, buffer, ReducedWirelessConfigurationDataSize);
if (rslt >= 0)
{
- char* const cbuf = reinterpret_cast<char *>(buffer);
- cbuf[declaredBufferLength] = 0; // ensure null terminated
- char *p = strchr(cbuf, '\n');
- if (p != nullptr)
+ WirelessConfigurationData* const wp = reinterpret_cast<WirelessConfigurationData *>(buffer);
+ if (wp->ssid[0] == 0)
+ {
+ reply.copy("Own SSID not configured");
+ }
+ else
{
- *p = 0;
+ wp->ssid[ARRAY_UPB(wp->ssid)] = 0;
+ reply.printf("Own SSID: %s IP=%s GW=%s NM=%s", wp->ssid, IP4String(wp->ip).c_str(), IP4String(wp->gateway).c_str(), IP4String(wp->netmask).c_str());
}
- reply.printf("Own SSID: %s", (cbuf[0] == 0) ? "not configured" : cbuf);
}
else
{
- reply.copy("Failed to remove SSID from remembered list");
+ reply.copy("Failed to retrieve own SSID data");
result = GCodeResult::error;
}
}
@@ -4319,7 +4345,7 @@ bool GCodes::HandleMcode(GCodeBuffer& gb, StringRef& reply)
{
return false;
}
- reprap.GetHeat().SwitchOffAll(); // turn all heaters off because the main loop may get suspended
+ reprap.GetHeat().SwitchOffAll(true); // turn all heaters off because the main loop may get suspended
DisableDrives(); // all motors off
if (firmwareUpdateModuleMap == 0) // have we worked out which modules to update?
@@ -4453,17 +4479,27 @@ bool GCodes::HandleTcode(GCodeBuffer& gb, StringRef& reply)
return true; // when running M502 we don't execute T commands
}
+ bool seen = false;
+ int toolNum;
if (gb.HasCommandNumber())
{
+ seen = true;
+ toolNum = gb.GetCommandNumber();
+ toolNum += gb.GetToolNumberAdjust();
+ }
+ else if (gb.Seen('R') && gb.GetIValue() == 1)
+ {
+ seen = true;
+ toolNum = pauseRestorePoint.toolNumber;
+ }
+
+ if (seen)
+ {
if (!LockMovementAndWaitForStandstill(gb))
{
return false;
}
- // See if the tool can be changed
- int toolNum = gb.GetCommandNumber();
- toolNum += gb.GetToolNumberAdjust();
-
const Tool * const oldTool = reprap.GetCurrentTool();
// If old and new are the same we no longer follow the sequence. User can deselect and then reselect the tool if he wants the macros run.
if (oldTool == nullptr || oldTool->Number() != toolNum)
@@ -4477,7 +4513,7 @@ bool GCodes::HandleTcode(GCodeBuffer& gb, StringRef& reply)
}
else
{
- // Even though the tool is selected, we may have turned it off e.g. when upgrading the WiFi firmware.
+ // Even though the tool is selected, we may have turned it off e.g. when upgrading the WiFi firmware or following a heater fault that has been cleared.
// So make sure the tool heaters are on.
reprap.SelectTool(toolNum, simulationMode != 0);
}
diff --git a/src/GCodes/RestorePoint.cpp b/src/GCodes/RestorePoint.cpp
index 977730de..b75fe8a4 100644
--- a/src/GCodes/RestorePoint.cpp
+++ b/src/GCodes/RestorePoint.cpp
@@ -18,13 +18,17 @@ void RestorePoint::Init()
{
moveCoords[i] = 0.0;
}
+
feedRate = DefaultFeedrate * SecondsToMinutes;
virtualExtruderPosition = 0.0;
- proportionDone = 0.0;
filePos = noFilePosition;
+ proportionDone = 0.0;
+
#if SUPPORT_IOBITS
ioBits = 0;
#endif
+
+ toolNumber = -1;
}
// End
diff --git a/src/GCodes/RestorePoint.h b/src/GCodes/RestorePoint.h
index 129d6100..70a93d3b 100644
--- a/src/GCodes/RestorePoint.h
+++ b/src/GCodes/RestorePoint.h
@@ -19,11 +19,13 @@ struct RestorePoint
float moveCoords[MaxAxes]; // The axis locations when we paused
float feedRate; // The feed rate for the current move
float virtualExtruderPosition; // The virtual extruder position at the start of this move
- float proportionDone; // How much of this move we have already done (zero unless we interrupts a move)
+ float proportionDone; // How much of this move we have already done (zero unless we interrupted a move)
FilePosition filePos; // The file position that this move was read from
+
#if SUPPORT_IOBITS
IoBits_t ioBits; // The output port bits setting for this move
#endif
+ int toolNumber; // The tool number that was active
RestorePoint();
void Init();
diff --git a/src/Heating/FOPDT.cpp b/src/Heating/FOPDT.cpp
index 0625b28e..6acc67ab 100644
--- a/src/Heating/FOPDT.cpp
+++ b/src/Heating/FOPDT.cpp
@@ -14,13 +14,13 @@ extern StringRef scratchString;
// Heater 6 on the Duet 0.8.5 is disabled by default at startup so that we can use fan 2.
// Set up sensible defaults here in case the user enables the heater without specifying values for all the parameters.
FopDt::FopDt()
- : gain(DefaultHotEndHeaterGain), timeConstant(DefaultHotEndHeaterTimeConstant), deadTime(DefaultHotEndHeaterDeadTime), maxPwm(1.0),
+ : gain(DefaultHotEndHeaterGain), timeConstant(DefaultHotEndHeaterTimeConstant), deadTime(DefaultHotEndHeaterDeadTime), maxPwm(1.0), standardVoltage(0.0),
enabled(false), usePid(true), pidParametersOverridden(false)
{
}
// Check the model parameters are sensible, if they are then save them and return true.
-bool FopDt::SetParameters(float pg, float ptc, float pdt, float pMaxPwm, float temperatureLimit, bool pUsePid)
+bool FopDt::SetParameters(float pg, float ptc, float pdt, float pMaxPwm, float temperatureLimit, float voltage, bool pUsePid)
{
if (pg == -1.0 && ptc == -1.0 && pdt == -1.0)
{
@@ -37,6 +37,7 @@ bool FopDt::SetParameters(float pg, float ptc, float pdt, float pMaxPwm, float t
timeConstant = ptc;
deadTime = pdt;
maxPwm = pMaxPwm;
+ standardVoltage = voltage;
usePid = pUsePid;
enabled = true;
CalcPidConstants();
@@ -69,7 +70,8 @@ void FopDt::SetM301PidParameters(const M301PidParameters& pp)
// Write the model parameters to file returning true if no error
bool FopDt::WriteParameters(FileStore *f, size_t heater) const
{
- scratchString.printf("M307 H%u A%.1f C%.1f D%.1f S%.2f B%d\n", heater, (double)gain, (double)timeConstant, (double)deadTime, (double)maxPwm, (usePid) ? 0 : 1);
+ scratchString.printf("M307 H%u A%.1f C%.1f D%.1f S%.2f V%.1f B%d\n",
+ heater, (double)gain, (double)timeConstant, (double)deadTime, (double)maxPwm, (double)standardVoltage, (usePid) ? 0 : 1);
bool ok = f->Write(scratchString.Pointer());
if (ok && pidParametersOverridden)
{
diff --git a/src/Heating/FOPDT.h b/src/Heating/FOPDT.h
index 36fd6355..2cf2c62c 100644
--- a/src/Heating/FOPDT.h
+++ b/src/Heating/FOPDT.h
@@ -35,12 +35,13 @@ class FopDt
public:
FopDt();
- bool SetParameters(float pg, float ptc, float pdt, float pMaxPwm, float temperatureLimit, bool pUsePid);
+ bool SetParameters(float pg, float ptc, float pdt, float pMaxPwm, float temperatureLimit, float voltage, bool pUsePid);
float GetGain() const { return gain; }
float GetTimeConstant() const { return timeConstant; }
float GetDeadTime() const { return deadTime; }
float GetMaxPwm() const { return maxPwm; }
+ float GetVoltage() const { return standardVoltage; }
bool UsePid() const { return usePid; }
bool IsEnabled() const { return enabled; }
bool ArePidParametersOverridden() const { return pidParametersOverridden; }
@@ -61,6 +62,7 @@ private:
float timeConstant;
float deadTime;
float maxPwm;
+ float standardVoltage; // power voltage reading at which tuning was done, or 0 if unknown
bool enabled;
bool usePid;
bool pidParametersOverridden;
diff --git a/src/Heating/Heat.cpp b/src/Heating/Heat.cpp
index e1326c76..05dd890b 100644
--- a/src/Heating/Heat.cpp
+++ b/src/Heating/Heat.cpp
@@ -45,11 +45,11 @@ void Heat::ResetHeaterModels()
{
if ((int)heater == DefaultBedHeater || (int)heater == DefaultChamberHeater)
{
- pids[heater]->SetModel(DefaultBedHeaterGain, DefaultBedHeaterTimeConstant, DefaultBedHeaterDeadTime, 1.0, false);
+ pids[heater]->SetModel(DefaultBedHeaterGain, DefaultBedHeaterTimeConstant, DefaultBedHeaterDeadTime, 1.0, 0.0, false);
}
else
{
- pids[heater]->SetModel(DefaultHotEndHeaterGain, DefaultHotEndHeaterTimeConstant, DefaultHotEndHeaterDeadTime, 1.0, true);
+ pids[heater]->SetModel(DefaultHotEndHeaterGain, DefaultHotEndHeaterTimeConstant, DefaultHotEndHeaterDeadTime, 1.0, 0.0, true);
}
}
}
@@ -284,11 +284,14 @@ void Heat::SwitchOff(int8_t heater)
}
}
-void Heat::SwitchOffAll()
+void Heat::SwitchOffAll(bool includingChamberAndBed)
{
- for (PID *p : pids)
+ for (int heater = 0; heater < (int)Heaters; ++heater)
{
- p->SwitchOff();
+ if (includingChamberAndBed || (heater != bedHeater && heater != chamberHeater))
+ {
+ pids[heater]->SwitchOff();
+ }
}
}
@@ -319,7 +322,7 @@ uint32_t Heat::GetLastSampleTime(size_t heater) const
return pids[heater]->GetLastSampleTime();
}
-bool Heat::UseSlowPwm(int8_t heater) const
+bool Heat::IsBedOrChamberHeater(int8_t heater) const
{
return heater == bedHeater || heater == chamberHeater;
}
diff --git a/src/Heating/Heat.h b/src/Heating/Heat.h
index cdfc9c99..35b21181 100644
--- a/src/Heating/Heat.h
+++ b/src/Heating/Heat.h
@@ -71,7 +71,7 @@ public:
float GetTargetTemperature(int8_t heater) const; // Get the target temperature
HeaterStatus GetStatus(int8_t heater) const; // Get the off/standby/active status
void SwitchOff(int8_t heater); // Turn off a specific heater
- void SwitchOffAll(); // Turn all heaters off
+ void SwitchOffAll(bool includingChamberAndBed); // Turn all heaters off
void ResetFault(int8_t heater); // Reset a heater fault - only call this if you know what you are doing
bool AllHeatersAtSetTemperatures(bool includingBed) const; // Is everything at temperature within tolerance?
bool HeaterAtSetTemperature(int8_t heater, bool waitWhenCooling) const; // Is a specific heater at temperature within tolerance?
@@ -80,7 +80,7 @@ public:
float GetAveragePWM(size_t heater) const // Return the running average PWM to the heater as a fraction in [0, 1].
pre(heater < Heaters);
- bool UseSlowPwm(int8_t heater) const; // Queried by the Platform class
+ bool IsBedOrChamberHeater(int8_t heater) const; // Queried by the Platform class
uint32_t GetLastSampleTime(size_t heater) const
pre(heater < Heaters);
@@ -96,7 +96,7 @@ public:
const FopDt& GetHeaterModel(size_t heater) const // Get the process model for the specified heater
pre(heater < Heaters);
- bool SetHeaterModel(size_t heater, float gain, float tc, float td, float maxPwm, bool usePid) // Set the heater process model
+ bool SetHeaterModel(size_t heater, float gain, float tc, float td, float maxPwm, float voltage, bool usePid) // Set the heater process model
pre(heater < Heaters);
void GetHeaterProtection(size_t heater, float& maxTempExcursion, float& maxFaultTime) const
@@ -187,9 +187,9 @@ inline const FopDt& Heat::GetHeaterModel(size_t heater) const
}
// Set the heater process model
-inline bool Heat::SetHeaterModel(size_t heater, float gain, float tc, float td, float maxPwm, bool usePid)
+inline bool Heat::SetHeaterModel(size_t heater, float gain, float tc, float td, float maxPwm, float voltage, bool usePid)
{
- return pids[heater]->SetModel(gain, tc, td, maxPwm, usePid);
+ return pids[heater]->SetModel(gain, tc, td, maxPwm, voltage, usePid);
}
// Is the heater enabled?
diff --git a/src/Heating/Pid.cpp b/src/Heating/Pid.cpp
index 236981bb..aa9db611 100644
--- a/src/Heating/Pid.cpp
+++ b/src/Heating/Pid.cpp
@@ -31,6 +31,11 @@ float PID::tuningPeakTemperature; // the peak temperature reached, averaged ov
uint32_t PID::tuningHeatingTime; // how long we had the heating on for
uint32_t PID::tuningPeakDelay; // how many milliseconds the temperature continues to rise after turning the heater off
+#if HAS_VOLTAGE_MONITOR
+unsigned int voltageSamplesTaken; // how many readings we accumulated
+float tuningVoltageAccumulator; // sum of the voltage readings we take during the heating phase
+#endif
+
// Member functions and constructors
PID::PID(Platform& p, int8_t h) : platform(p), heater(h), mode(HeaterMode::off)
@@ -47,7 +52,7 @@ void PID::Init(float pGain, float pTc, float pTd, float tempLimit, bool usePid)
temperatureLimit = tempLimit;
maxTempExcursion = DefaultMaxTempExcursion;
maxHeatingFaultTime = DefaultMaxHeatingFaultTime;
- model.SetParameters(pGain, pTc, pTd, 1.0, tempLimit, usePid);
+ model.SetParameters(pGain, pTc, pTd, 1.0, tempLimit, 0.0, usePid);
Reset();
if (model.IsEnabled())
@@ -80,10 +85,10 @@ void PID::Reset()
}
// Set the process model
-bool PID::SetModel(float gain, float tc, float td, float maxPwm, bool usePid)
+bool PID::SetModel(float gain, float tc, float td, float maxPwm, float voltage, bool usePid)
{
const float temperatureLimit = reprap.GetHeat().GetTemperatureLimit(heater);
- const bool rslt = model.SetParameters(gain, tc, td, maxPwm, temperatureLimit, usePid);
+ const bool rslt = model.SetParameters(gain, tc, td, maxPwm, temperatureLimit, voltage, usePid);
if (rslt)
{
#if defined(DUET_06_085)
@@ -216,6 +221,7 @@ void PID::Spin()
tuningTempReadings = nullptr;
}
mode = HeaterMode::fault;
+ reprap.GetGCodes().HandleHeaterFault(heater);
platform.MessageF(ErrorMessage, "Temperature reading fault on heater %d: %s\n", heater, TemperatureErrorString(err));
reprap.FlagTemperatureFault(heater);
}
@@ -356,15 +362,33 @@ void PID::Spin()
}
else
{
+#if 1 // try normal PWM instead, because it looks like the modified PWM may be causing undershoot on initial heating
+ const float errorToUse = error;
+#else
// In the following we use a modified PID when the temperature is a long way off target.
// During initial heating or cooling, the D term represents expected overshoot, which we don't want to add to the I accumulator.
// When we are in load mode, the I term is much larger and the D term doesn't represent overshoot, so use normal PID.
const float errorToUse = (inLoadMode || model.ArePidParametersOverridden()) ? error : errorMinusDterm;
+#endif
iAccumulator = constrain<float>
(iAccumulator + (errorToUse * params.kP * params.recipTi * platform.HeatSampleInterval() * MillisToSeconds),
0.0, model.GetMaxPwm());
lastPwm = constrain<float>(pPlusD + iAccumulator, 0.0, model.GetMaxPwm());
}
+#if HAS_VOLTAGE_MONITOR
+ // Scale the PID based on the current voltage vs. the calibration voltage
+ if (lastPwm < 1.0 && model.GetVoltage() >= 10.0) // if heater is not fully on and we know the voltage we tuned the heater at
+ {
+ if (!reprap.GetHeat().IsBedOrChamberHeater(heater))
+ {
+ const float currentVoltage = platform.GetCurrentPowerVoltage();
+ if (currentVoltage >= 10.0) // if we have a sensible reading
+ {
+ lastPwm = min<float>(lastPwm * fsquare(model.GetVoltage()/currentVoltage), 1.0); // adjust the PWM by the square of the voltage ratio
+ }
+ }
+ }
+#endif
}
else
{
@@ -447,9 +471,12 @@ void PID::Standby()
void PID::ResetFault()
{
- mode = HeaterMode::off;
- SwitchOff();
badTemperatureCount = 0;
+ if (mode == HeaterMode::fault)
+ {
+ mode = HeaterMode::off;
+ SwitchOff();
+ }
}
float PID::GetAveragePWM() const
@@ -610,6 +637,10 @@ void PID::DoTuningStep()
{
// Starting temperature is stable, so move on
tuningReadingsTaken = 1;
+#if HAS_VOLTAGE_MONITOR
+ tuningVoltageAccumulator = 0.0;
+ voltageSamplesTaken = 0;
+#endif
tuningTempReadings[0] = tuningStartTemp = temperature;
timeSetHeating = tuningPhaseStartTime = millis();
lastPwm = tuningPwm; // turn on heater at specified power
@@ -629,7 +660,7 @@ void PID::DoTuningStep()
case HeaterMode::tuning1:
// Heating up
{
- const bool isBedOrChamberHeater = (heater == reprap.GetHeat().GetBedHeater() || heater == reprap.GetHeat().GetChamberHeater());
+ const bool isBedOrChamberHeater = reprap.GetHeat().IsBedOrChamberHeater(heater);
const uint32_t heatingTime = millis() - tuningPhaseStartTime;
const float extraTimeAllowed = (isBedOrChamberHeater) ? 60.0 : 30.0;
if (heatingTime > (uint32_t)((model.GetDeadTime() + extraTimeAllowed) * SecondsToMillis) && (temperature - tuningStartTemp) < 3.0)
@@ -645,6 +676,10 @@ void PID::DoTuningStep()
break;
}
+#if HAS_VOLTAGE_MONITOR
+ tuningVoltageAccumulator += platform.GetCurrentPowerVoltage();
+ ++voltageSamplesTaken;
+#endif
if (temperature >= tuningTargetTemp) // if reached target
{
tuningHeatingTime = heatingTime;
@@ -828,7 +863,13 @@ void PID::CalculateModel()
//const float td = (float)(tuningPeakDelay + 500) * 0.00065; // take the dead time as 65% of the delay to peak rounded up to a half second
const float td = tc * logf((gain + tuningStartTemp - tuningHeaterOffTemp)/(gain + tuningStartTemp - tuningPeakTemperature)) * 1.3;
- tuned = SetModel(gain, tc, td, tuningPwm, true);
+ tuned = SetModel(gain, tc, td, tuningPwm,
+#if HAS_VOLTAGE_MONITOR
+ tuningVoltageAccumulator/voltageSamplesTaken,
+#else
+ 0.0,
+#endif
+ true);
if (tuned)
{
platform.MessageF(LoggedGenericMessage,
diff --git a/src/Heating/Pid.h b/src/Heating/Pid.h
index 1ca9b5d3..b436060c 100644
--- a/src/Heating/Pid.h
+++ b/src/Heating/Pid.h
@@ -66,7 +66,7 @@ public:
const FopDt& GetModel() const // Get the process model
{ return model; }
- bool SetModel(float gain, float tc, float td, float maxPwm, bool usePid); // Set the process model
+ bool SetModel(float gain, float tc, float td, float maxPwm, float voltage, bool usePid); // Set the process model
bool IsHeaterEnabled() const // Is this heater enabled?
{ return model.IsEnabled(); }
diff --git a/src/Libraries/General/StringRef.h b/src/Libraries/General/StringRef.h
index 4bfe4dba..1edcc2b1 100644
--- a/src/Libraries/General/StringRef.h
+++ b/src/Libraries/General/StringRef.h
@@ -60,11 +60,25 @@ public:
const char *Pointer() const { return storage; }
char& operator[](size_t index) { return storage[index]; }
char operator[](size_t index) const { return storage[index]; }
+ size_t MaxLength() const { return Len; }
- void Clear() const { storage[0] = 0; }
+ void Clear() { storage[0] = 0; }
+ size_t cat(char c);
private:
char storage[Len + 1];
};
+// Append a character if it will fit and return the new length
+template<size_t Len> size_t String<Len>::cat(char c)
+{
+ size_t length = strlen();
+ if (length + 1 < Len)
+ {
+ storage[length++] = c;
+ storage[length] = 0;
+ }
+ return length;
+}
+
#endif /* STRINGREF_H_ */
diff --git a/src/Logger.cpp b/src/Logger.cpp
index 7d19237a..e40f9856 100644
--- a/src/Logger.cpp
+++ b/src/Logger.cpp
@@ -111,7 +111,7 @@ void Logger::InternalLogMessage(time_t time, const char *message)
}
// This is called regularly by Platform to give the logger an opportunity to flush the file buffer
-void Logger::Flush()
+void Logger::Flush(bool forced)
{
if (logFile.IsLive() && dirty && !inLogger)
{
@@ -122,7 +122,7 @@ void Logger::Flush()
// 2. If it hasn't been flushed for LogFlushInterval milliseconds.
const FilePosition currentPos = logFile.GetPosition();
const uint32_t now = millis();
- if (now - lastFlushTime >= LogFlushInterval || currentPos/512 != lastFlushFileSize/512)
+ if (forced || now - lastFlushTime >= LogFlushInterval || currentPos/512 != lastFlushFileSize/512)
{
Lock loggerLock(inLogger);
logFile.Flush();
diff --git a/src/Logger.h b/src/Logger.h
index 04397efe..d0cbdab8 100644
--- a/src/Logger.h
+++ b/src/Logger.h
@@ -22,7 +22,7 @@ public:
void Stop(time_t time);
void LogMessage(time_t time, const char *message);
void LogMessage(time_t time, OutputBuffer *buf);
- void Flush();
+ void Flush(bool forced);
bool IsActive() const { return logFile.IsLive(); }
private:
diff --git a/src/Movement/DDA.cpp b/src/Movement/DDA.cpp
index 090afbbf..037f5af1 100644
--- a/src/Movement/DDA.cpp
+++ b/src/Movement/DDA.cpp
@@ -348,7 +348,8 @@ bool DDA::Init(GCodes::RawMove &nextMove, bool doMotorMapping)
isPrintingMove = xyMoving && extruding;
usePressureAdvance = nextMove.usePressureAdvance;
virtualExtruderPosition = nextMove.virtualExtruderPosition;
- proportionRemaining = nextMove.proportionRemaining;
+ proportionLeft = nextMove.proportionLeft;
+
hadLookaheadUnderrun = false;
isLeadscrewAdjustmentMove = false;
goingSlow = false;
@@ -1529,18 +1530,18 @@ void DDA::MoveAborted()
state = completed;
}
-// Return the approximate (to within 1%) proportion of extrusion for the complete multi-segment move that remains to be done.
+// Return the proportion of extrusion for the complete multi-segment move that has already been done.
// The move was either not started or was aborted.
-float DDA::GetProportionDone() const
+float DDA::GetProportionDone(bool moveWasAborted) const
{
// Get the proportion of extrusion already done at the start of this segment
- unsigned int proportionDone = (filePos != noFilePosition && filePos == prev->filePos)
- ? 256 - prev->proportionRemaining
- : 0;
- if (state == completed)
+ float proportionDone = (filePos != noFilePosition && filePos == prev->filePos)
+ ? 1.0 - prev->proportionLeft
+ : 0.0;
+ if (moveWasAborted)
{
// The move was aborted, so subtract how much was done
- const unsigned int proportionDoneAtEnd = 256 - proportionRemaining;
+ const float proportionDoneAtEnd = 1.0 - proportionLeft;
if (proportionDoneAtEnd > proportionDone)
{
int32_t taken = 0, left = 0;
@@ -1554,13 +1555,13 @@ float DDA::GetProportionDone() const
}
}
const int32_t total = taken + left;
- if (total > 0) // if the move has net extrusion
+ if (total > 0) // if the move has net extrusion
{
proportionDone += (((proportionDoneAtEnd - proportionDone) * taken) + (total/2)) / total;
}
}
}
- return (float)proportionDone/256.0;
+ return proportionDone;
}
// Reduce the speed of this move to the indicated speed.
diff --git a/src/Movement/DDA.h b/src/Movement/DDA.h
index c45c453f..ed974d15 100644
--- a/src/Movement/DDA.h
+++ b/src/Movement/DDA.h
@@ -74,7 +74,8 @@ public:
void LimitSpeedAndAcceleration(float maxSpeed, float maxAcceleration); // Limit the speed an acceleration of this move
int32_t GetStepsTaken(size_t drive) const;
- float GetProportionDone() const; // Return the proportion of extrusion for the complete multi-segment move already done
+
+ float GetProportionDone(bool moveWasAborted) const; // Return the proportion of extrusion for the complete multi-segment move already done
void MoveAborted();
@@ -146,8 +147,7 @@ private:
DDA *prev; // The previous one in the ring
volatile DDAState state; // What state this DDA is in
- uint8_t proportionRemaining; // What proportion of the extrusion in the G1 or G0 move of which this is a part remains to be done after this segment is complete
- // - we use a uint8_t instead of a float to save space because it only affects the extrusion amount, so ~0.4% error is acceptable
+
union
{
struct
@@ -197,6 +197,8 @@ private:
uint32_t clocksNeeded; // in clocks
uint32_t moveStartTime; // clock count at which the move was started
+ float proportionLeft; // what proportion of the extrusion in the G1 or G0 move of which this is a part remains to be done after this segment is complete
+
#if SUPPORT_IOBITS
IoBits_t ioBits; // port state required during this move
#endif
diff --git a/src/Movement/Kinematics/CoreXYUKinematics.cpp b/src/Movement/Kinematics/CoreXYUKinematics.cpp
index 80ab8f84..060fa5dc 100644
--- a/src/Movement/Kinematics/CoreXYUKinematics.cpp
+++ b/src/Movement/Kinematics/CoreXYUKinematics.cpp
@@ -9,10 +9,6 @@
#include "GCodes/GCodes.h"
#include "Movement/DDA.h"
-const size_t CoreXYU_AXES = 5;
-const size_t U_AXIS = 3; // X2
-const size_t V_AXIS = 4; // Y2
-
CoreXYUKinematics::CoreXYUKinematics() : CoreBaseKinematics(KinematicsType::coreXYU)
{
}
diff --git a/src/Movement/Move.cpp b/src/Movement/Move.cpp
index 4d0248df..fc13803e 100644
--- a/src/Movement/Move.cpp
+++ b/src/Movement/Move.cpp
@@ -397,7 +397,9 @@ bool Move::PausePrint(RestorePoint& rp)
// So on return we need to signal one of the following to GCodes:
// 1. We have skipped some moves in the queue. Pass back the file address of the first move we have skipped, the feed rate at the start of that move
// and the iobits at the start of that move, and return true.
- // 2. All moves in the queue need to be executed. Also any move held by GCodes needs to be completed it is it not the first segment. Return false.
+ // 2. All moves in the queue need to be executed. Also any move held by GCodes needs to be completed it is it not the first segment.
+ // Update the restore point with the coordinates and iobits as at the end of the previous move and return false.
+ // The extruder position, file position and feed rate are not filled in.
//
// In general, we can pause after a move if it is the last segment and its end speed is slow enough.
// We can pause before a move if it is the first segment in that move.
@@ -432,12 +434,7 @@ bool Move::PausePrint(RestorePoint& rp)
cpu_irq_enable();
- if (ddaRingAddPointer == savedDdaRingAddPointer)
- {
- return false; // we can't skip any moves
- }
-
- // We are going to skip some moves. Get the end coordinate of the previous move.
+ // We may be going to skip some moves. Get the end coordinate of the previous move.
DDA * const prevDda = ddaRingAddPointer->GetPrevious();
const size_t numVisibleAxes = reprap.GetGCodes().GetVisibleAxes();
for (size_t axis = 0; axis < numVisibleAxes; ++axis)
@@ -447,15 +444,22 @@ bool Move::PausePrint(RestorePoint& rp)
InverseAxisAndBedTransform(rp.moveCoords, prevDda->GetXAxes(), prevDda->GetYAxes()); // we assume that xAxes hasn't changed between the moves
- dda = ddaRingAddPointer;
- rp.feedRate = dda->GetRequestedSpeed();
- rp.virtualExtruderPosition = dda->GetVirtualExtruderPosition();
- rp.filePos = dda->GetFilePosition();
+ rp.proportionDone = ddaRingAddPointer->GetProportionDone(false); // get the proportion of the current multi-segment move that has been completed
#if SUPPORT_IOBITS
rp.ioBits = dda->GetIoBits();
#endif
+ if (ddaRingAddPointer == savedDdaRingAddPointer)
+ {
+ return false; // we can't skip any moves
+ }
+
+ dda = ddaRingAddPointer;
+ rp.feedRate = dda->GetRequestedSpeed();
+ rp.virtualExtruderPosition = dda->GetVirtualExtruderPosition();
+ rp.filePos = dda->GetFilePosition();
+
// Free the DDAs for the moves we are going to skip
do
{
@@ -468,6 +472,8 @@ bool Move::PausePrint(RestorePoint& rp)
return true;
}
+#if HAS_VOLTAGE_MONITOR
+
// Pause the print immediately, returning true if we were able to skip or abort any moves and setting up to the move we aborted
bool Move::LowPowerPause(RestorePoint& rp)
{
@@ -514,7 +520,7 @@ bool Move::LowPowerPause(RestorePoint& rp)
rp.feedRate = dda->GetRequestedSpeed();
rp.virtualExtruderPosition = dda->GetVirtualExtruderPosition();
rp.filePos = dda->GetFilePosition();
- rp.proportionDone = dda->GetProportionDone(); // store how much of the complete multi-segment move's extrusion has been done
+ rp.proportionDone = dda->GetProportionDone(abortedMove); // store how much of the complete multi-segment move's extrusion has been done
#if SUPPORT_IOBITS
rp.ioBits = dda->GetIoBits();
@@ -542,6 +548,8 @@ bool Move::LowPowerPause(RestorePoint& rp)
return true;
}
+#endif
+
#if 0
// For debugging
extern uint32_t sqSum1, sqSum2, sqCount, sqErrors, lastRes1, lastRes2;
diff --git a/src/Movement/Move.h b/src/Movement/Move.h
index 86eb6ab3..195226a9 100644
--- a/src/Movement/Move.h
+++ b/src/Movement/Move.h
@@ -99,7 +99,9 @@ public:
void PrintCurrentDda() const; // For debugging
bool PausePrint(RestorePoint& rp); // Pause the print as soon as we can, returning true if we were able to
+#if HAS_VOLTAGE_MONITOR
bool LowPowerPause(RestorePoint& rp); // Pause the print immediately, returning true if we were able to
+#endif
bool NoLiveMovement() const; // Is a move running, or are there any queued?
diff --git a/src/Platform.cpp b/src/Platform.cpp
index 130fa306..068f8cbc 100644
--- a/src/Platform.cpp
+++ b/src/Platform.cpp
@@ -568,7 +568,8 @@ void Platform::Init()
}
}
- temperatureShutdownDrivers = temperatureWarningDrivers = shortToGroundDrivers = openLoadDrivers = stalledDrivers = previousStalledDrivers = 0;
+ temperatureShutdownDrivers = temperatureWarningDrivers = shortToGroundDrivers = openLoadDrivers = stalledDrivers = 0;
+ stalledDriversToLog = stalledDriversToPause = stalledDriversToRehome = 0;
onBoardDriversFanRunning = offBoardDriversFanRunning = false;
autoSaveEnabled = false;
autoSaveState = AutoSaveState::starting;
@@ -662,7 +663,7 @@ void Platform::Init()
AnalogInEnableChannel(vInMonitorAdcChannel, true);
currentVin = highestVin = 0;
lowestVin = 9999;
- numUnderVoltageEvents = numOverVoltageEvents = 0;
+ numUnderVoltageEvents = previousUnderVoltageEvents = numOverVoltageEvents = previousOverVoltageEvents = 0;
#endif
// Clear the spare pin configuration
@@ -1385,7 +1386,7 @@ void Platform::Spin()
}
else
{
- // Poll one TMC2660 for temperature warning or temperature shutdown
+ // Check one TMC2660 for temperature warning or temperature shutdown
if (enableValues[nextDriveToPoll] >= 0) // don't poll driver if it is flagged "no poll"
{
const uint32_t stat = SmartDrivers::GetAccumulatedStatus(nextDriveToPoll, 0);
@@ -1425,10 +1426,47 @@ void Platform::Spin()
}
if ((stat & TMC_RR_SG) != 0)
{
+ if ((stalledDrivers & mask) == 0)
+ {
+ // This stall is new and we are printing, so check whether we need to perform some action in response to the stall
+ if ((rehomeOnStallDrivers & mask) != 0)
+ {
+ stalledDriversToRehome |= mask;
+ }
+ else if ((pauseOnStallDrivers & mask) != 0)
+ {
+ stalledDriversToPause |= mask;
+ }
+ else if ((logOnStallDrivers & mask) != 0)
+ {
+ stalledDriversToLog |= mask;
+ }
+ }
stalledDrivers |= mask;
}
- // We don't clear any stalled driver bits here because a stall may be transient
+ else
+ {
+ stalledDrivers &= ~mask;
+ }
}
+
+ // Action any pause or rehome actions due to motor stalls. This may have to be done more than once.
+ if (stalledDriversToRehome != 0)
+ {
+ if (reprap.GetGCodes().ReHomeOnStall(stalledDriversToRehome))
+ {
+ stalledDriversToRehome = 0;
+ }
+ }
+ else if (stalledDriversToPause != 0)
+ {
+ if (reprap.GetGCodes().PauseOnStall(stalledDriversToPause))
+ {
+ stalledDriversToPause = 0;
+ }
+ }
+
+ // Advance drive number ready for next time
++nextDriveToPoll;
if (nextDriveToPoll == numSmartDrivers)
{
@@ -1489,27 +1527,31 @@ void Platform::Spin()
}
// Check for stalled drivers that need to be reported and logged
- const DriversBitmap currentStalledDrivers = stalledDrivers & logOnStallDrivers;
- DriversBitmap newStalledDrivers = currentStalledDrivers & ~previousStalledDrivers;
- if (newStalledDrivers != 0 && reprap.GetGCodes().IsReallyPrinting())
+ if (stalledDriversToLog != 0 && reprap.GetGCodes().IsReallyPrinting())
{
- // Report the newly-stalled drivers
scratchString.Clear();
- for (unsigned int driver = 0; newStalledDrivers != 0; ++driver)
- {
- if ((newStalledDrivers & 1) != 0)
- {
- scratchString.catf(" %u", driver);
- }
- newStalledDrivers >>= 1;
- }
+ ListDrivers(scratchString, stalledDriversToLog);
+ stalledDriversToLog = 0;
float liveCoordinates[DRIVES];
reprap.GetMove().LiveCoordinates(liveCoordinates, reprap.GetCurrentXAxes(), reprap.GetCurrentYAxes());
- MessageF(WarningMessage, "Driver(s)%s stalled at Z height %.1f", scratchString.Pointer(), (double)liveCoordinates[Z_AXIS]);
+ MessageF(WarningMessage, "Driver(s)%s stalled at Z height %.2f", scratchString.Pointer(), (double)liveCoordinates[Z_AXIS]);
+ reported = true;
+ }
+#endif
+
+#if HAS_VOLTAGE_MONITOR
+ if (numOverVoltageEvents != previousOverVoltageEvents)
+ {
+ MessageF(WarningMessage, "VIN over-voltage event (%.1fV)", (double)GetCurrentPowerVoltage());
+ previousOverVoltageEvents = numOverVoltageEvents;
+ reported = true;
+ }
+ if (numUnderVoltageEvents != previousUnderVoltageEvents)
+ {
+ MessageF(WarningMessage, "VIN under-voltage event (%.1fV)", (double)GetCurrentPowerVoltage());
+ previousUnderVoltageEvents = numUnderVoltageEvents;
reported = true;
}
- previousStalledDrivers = currentStalledDrivers;
- stalledDrivers = 0;
#endif
#ifdef DUET_NG
@@ -1569,7 +1611,7 @@ void Platform::Spin()
// Flush the log file it it is time. This may take some time, so do it last.
if (logger != nullptr)
{
- logger->Flush();
+ logger->Flush(false);
}
ClassReport(longWait);
@@ -1592,11 +1634,30 @@ void Platform::ReportDrivers(DriversBitmap whichDrivers, const char* text, bool&
}
whichDrivers >>= 1;
}
- MessageF(GenericMessage, "%s\n", scratchString.Pointer());
+ MessageF(WarningMessage, "%s\n", scratchString.Pointer());
reported = true;
}
}
+// Return true if any motor driving this axis or extruder is stalled
+bool Platform::AnyMotorStalled(size_t drive) const
+{
+ const size_t numAxes = reprap.GetGCodes().GetTotalAxes();
+ if (drive < numAxes)
+ {
+ for (size_t i = 0; i < axisDrivers[drive].numDrivers; ++i)
+ {
+ if ((SmartDrivers::GetLiveStatus(axisDrivers[drive].driverNumbers[i]) & TMC_RR_SG) != 0)
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ return (SmartDrivers::GetLiveStatus(extruderDrivers[drive - numAxes]) & TMC_RR_SG) != 0;
+}
+
#endif
#if HAS_VOLTAGE_MONITOR
@@ -2278,7 +2339,7 @@ void Platform::SetHeater(size_t heater, float power)
{
if (heatOnPins[heater] != NoPin)
{
- const uint16_t freq = (reprap.GetHeat().UseSlowPwm(heater)) ? SlowHeaterPwmFreq : NormalHeaterPwmFreq;
+ const uint16_t freq = (reprap.GetHeat().IsBedOrChamberHeater(heater)) ? SlowHeaterPwmFreq : NormalHeaterPwmFreq;
const float pwm =
#if ACTIVE_LOW_HEAT_ON
1.0 - power;
@@ -2341,12 +2402,40 @@ EndStopHit Platform::Stopped(size_t drive) const
#if HAS_SMART_DRIVERS
case EndStopInputType::motorStall:
- for (size_t i = 0; i < axisDrivers[drive].numDrivers; ++i)
{
- if ((SmartDrivers::GetLiveStatus(axisDrivers[drive].driverNumbers[i]) & TMC_RR_SG) != 0)
+ bool motorIsStalled;
+ switch (reprap.GetMove().GetKinematics().GetKinematicsType())
{
- return (endStopPos[drive] == EndStopPosition::highEndStop) ? EndStopHit::highHit : EndStopHit::lowHit;
+ case KinematicsType::coreXY:
+ // Both X and Y motors are involved in homing X or Y
+ motorIsStalled = (drive == X_AXIS || drive == Y_AXIS)
+ ? AnyMotorStalled(X_AXIS) || AnyMotorStalled(Y_AXIS)
+ : AnyMotorStalled(drive);
+ break;
+
+ case KinematicsType::coreXYU:
+ // Both X and Y motors are involved in homing X or Y, and both U and V motors are involved in homing U
+ motorIsStalled = (drive == X_AXIS || drive == Y_AXIS)
+ ? AnyMotorStalled(X_AXIS) || AnyMotorStalled(Y_AXIS)
+ : (drive == U_AXIS)
+ ? AnyMotorStalled(U_AXIS) || AnyMotorStalled(V_AXIS)
+ : AnyMotorStalled(drive);
+ break;
+
+ case KinematicsType::coreXZ:
+ // Both X and Z motors are involved in homing X or Z
+ motorIsStalled = (drive == X_AXIS || drive == Z_AXIS)
+ ? AnyMotorStalled(X_AXIS) || AnyMotorStalled(Z_AXIS)
+ : AnyMotorStalled(drive);
+ break;
+
+ default:
+ motorIsStalled = AnyMotorStalled(drive);
+ break;
}
+ return (!motorIsStalled) ? EndStopHit::noStop
+ : (endStopPos[drive] == EndStopPosition::highEndStop) ? EndStopHit::highHit
+ : EndStopHit::lowHit;
}
break;
#endif
@@ -3396,10 +3485,15 @@ bool Platform::AtxPower() const
void Platform::SetAtxPower(bool on)
{
+ if (!on && logger != nullptr)
+ {
+ logger->LogMessage(realTime, "Power off commanded");
+ logger->Flush(true);
+ // We don't call logger->Stop() here because we don't now whether turning ofrf the power will work
+ }
IoPort::WriteDigital(ATX_POWER_PIN, on);
}
-
void Platform::SetPressureAdvance(size_t extruder, float factor)
{
if (extruder < MaxExtruders)
@@ -3812,6 +3906,11 @@ void Platform::GetPowerVoltages(float& minV, float& currV, float& maxV) const
maxV = AdcReadingToPowerVoltage(highestVin);
}
+float Platform::GetCurrentPowerVoltage() const
+{
+ return AdcReadingToPowerVoltage(currentVin);
+}
+
#endif
#if HAS_SMART_DRIVERS
diff --git a/src/Platform.h b/src/Platform.h
index 84c44edb..8c10fec9 100644
--- a/src/Platform.h
+++ b/src/Platform.h
@@ -543,6 +543,7 @@ public:
#if HAS_VOLTAGE_MONITOR
// Power in voltage
void GetPowerVoltages(float& minV, float& currV, float& maxV) const;
+ float GetCurrentPowerVoltage() const;
bool IsPowerOk() const;
void DisableAutoSave();
void EnableAutoSave(float saveVoltage, float resumeVoltage);
@@ -602,6 +603,7 @@ private:
#if HAS_SMART_DRIVERS
void ReportDrivers(DriversBitmap whichDrivers, const char* text, bool& reported);
+ bool AnyMotorStalled(size_t drive) const pre(drive < DRIVES);
#endif
// These are the structures used to hold our non-volatile data.
@@ -720,7 +722,7 @@ private:
size_t numSmartDrivers; // the number of TMC2660 drivers we have, the remaining are simple enable/step/dir drivers
DriversBitmap logOnStallDrivers, pauseOnStallDrivers, rehomeOnStallDrivers;
DriversBitmap temperatureShutdownDrivers, temperatureWarningDrivers, shortToGroundDrivers, openLoadDrivers, stalledDrivers;
- DriversBitmap previousStalledDrivers;
+ DriversBitmap stalledDriversToLog, stalledDriversToPause, stalledDriversToRehome;
uint8_t nextDriveToPoll;
bool driversPowered;
bool onBoardDriversFanRunning; // true if a fan is running to cool the on-board drivers
@@ -858,8 +860,8 @@ private:
AnalogChannelNumber vInMonitorAdcChannel;
volatile uint16_t currentVin, highestVin, lowestVin;
uint16_t autoPauseReading, autoResumeReading;
- uint32_t numUnderVoltageEvents;
- volatile uint32_t numOverVoltageEvents;
+ uint32_t numUnderVoltageEvents, previousUnderVoltageEvents;
+ volatile uint32_t numOverVoltageEvents, previousOverVoltageEvents;
bool autoSaveEnabled;
enum class AutoSaveState : uint8_t
diff --git a/src/PortControl.cpp b/src/PortControl.cpp
index c3f1d26c..44cbdbdd 100644
--- a/src/PortControl.cpp
+++ b/src/PortControl.cpp
@@ -78,14 +78,14 @@ bool PortControl::Configure(GCodeBuffer& gb, StringRef& reply)
gb.GetLongArray(portNumbers, numPorts);
for (size_t i = 0; i < numPorts; ++i)
{
- long pnum = portNumbers[i];
+ const long pnum = portNumbers[i];
if (pnum < 0 || pnum > HighestLogicalPin)
{
reply.printf("Port number %ld out of range", pnum);
return true;
}
IoPort& pm = portMap[i];
- if (!pm.Set(pnum, PinAccess::write))
+ if (!pm.Set((LogicalPin)pnum, PinAccess::write))
{
reply.printf("Port number %ld is not available", pnum);
return true;
diff --git a/src/RepRap.cpp b/src/RepRap.cpp
index a7033656..ee95198c 100644
--- a/src/RepRap.cpp
+++ b/src/RepRap.cpp
@@ -308,13 +308,16 @@ void RepRap::EmergencyStop()
void RepRap::SetDebug(Module m, bool enable)
{
- if (enable)
+ if (m < numModules)
{
- debug |= (1u << m);
- }
- else
- {
- debug &= ~(1u << m);
+ if (enable)
+ {
+ debug |= (1u << m);
+ }
+ else
+ {
+ debug &= ~(1u << m);
+ }
}
PrintDebug();
}
@@ -404,35 +407,27 @@ void RepRap::DeleteTool(Tool* tool)
platform->UpdateConfiguredHeaters();
}
+// Select the specified tool, putting the existing current tool into standby
void RepRap::SelectTool(int toolNumber, bool simulating)
{
- Tool* tool = toolList;
-
- while(tool != nullptr)
+ Tool* const newTool = GetTool(toolNumber);
+ if (!simulating)
{
- if (tool->Number() == toolNumber)
+ if (currentTool != nullptr && currentTool != newTool)
{
- if (!simulating)
- {
- tool->Activate(currentTool);
- }
- currentTool = tool;
- return;
+ currentTool->Standby();
+ }
+ if (newTool != nullptr)
+ {
+ newTool->Activate();
}
- tool = tool->Next();
- }
-
- // Selecting a non-existent tool is valid. It sets them all to standby.
- if (currentTool != nullptr && !simulating)
- {
- StandbyTool(currentTool->Number());
}
- currentTool = nullptr;
+ currentTool = newTool;
}
void RepRap::PrintTool(int toolNumber, StringRef& reply) const
{
- Tool* tool = GetTool(toolNumber);
+ const Tool* const tool = GetTool(toolNumber);
if (tool != nullptr)
{
tool->Print(reply);
@@ -445,7 +440,7 @@ void RepRap::PrintTool(int toolNumber, StringRef& reply) const
void RepRap::StandbyTool(int toolNumber)
{
- Tool* tool = GetTool(toolNumber);
+ Tool* const tool = GetTool(toolNumber);
if (tool != nullptr)
{
tool->Standby();
@@ -474,6 +469,12 @@ Tool* RepRap::GetTool(int toolNumber) const
return nullptr; // Not an error
}
+// Return the current tool number, or -1 if no tool selected
+int RepRap::GetCurrentToolNumber() const
+{
+ return (currentTool == nullptr) ? -1 : currentTool->Number();
+}
+
// Get the current tool, or failing that the default tool. May return nullptr if we can't
// Called when a M104 or M109 command doesn't specify a tool number.
Tool* RepRap::GetCurrentOrDefaultTool() const
@@ -497,9 +498,9 @@ void RepRap::SetToolVariables(int toolNumber, const float* standbyTemperatures,
bool RepRap::IsHeaterAssignedToTool(int8_t heater) const
{
- for(Tool *tool = toolList; tool != nullptr; tool = tool->Next())
+ for (Tool *tool = toolList; tool != nullptr; tool = tool->Next())
{
- for(size_t i = 0; i < tool->HeaterCount(); i++)
+ for (size_t i = 0; i < tool->HeaterCount(); i++)
{
if (tool->Heater(i) == heater)
{
@@ -631,8 +632,7 @@ OutputBuffer *RepRap::GetStatusResponse(uint8_t type, ResponseSource source)
}
// Current tool number
- const int toolNumber = (currentTool == nullptr) ? -1 : currentTool->Number();
- response->catf("]},\"currentTool\":%d", toolNumber);
+ response->catf("]},\"currentTool\":%d", GetCurrentToolNumber());
// Output notifications
{
@@ -1313,8 +1313,7 @@ OutputBuffer *RepRap::GetLegacyStatusResponse(uint8_t type, int seq)
response->catf(",\"babystep\":%.03f", (double)(gCodes->GetBabyStepOffset()));
// Send the current tool number
- const int toolNumber = (currentTool == nullptr) ? 0 : currentTool->Number();
- response->catf(",\"tool\":%d", toolNumber);
+ response->catf(",\"tool\":%d", GetCurrentToolNumber());
// Send the Z probe value
const int v0 = platform->GetZProbeReading();
diff --git a/src/RepRap.h b/src/RepRap.h
index 8d77df7c..a163f480 100644
--- a/src/RepRap.h
+++ b/src/RepRap.h
@@ -59,6 +59,7 @@ public:
void SelectTool(int toolNumber, bool simulating);
void StandbyTool(int toolNumber);
Tool* GetCurrentTool() const;
+ int GetCurrentToolNumber() const;
Tool* GetTool(int toolNumber) const;
Tool* GetCurrentOrDefaultTool() const;
const Tool* GetFirstTool() const { return toolList; } // Return the lowest-numbered tool
diff --git a/src/RepRapFirmware.cpp b/src/RepRapFirmware.cpp
index 904cb598..8093866a 100644
--- a/src/RepRapFirmware.cpp
+++ b/src/RepRapFirmware.cpp
@@ -185,7 +185,7 @@ const char *moduleName[] =
"PortControl",
"DuetExpansion",
"FilamentSensors",
- "?",
+ "WiFi",
"none"
};
@@ -289,4 +289,17 @@ void SafeStrncat(char *dst, const char *src, size_t length)
dst[length - 1] = 0;
}
+// Append a list of driver numbers to a string, with a space before each one
+void ListDrivers(const StringRef& str, DriversBitmap drivers)
+{
+ for (unsigned int d = 0; drivers != 0; ++d)
+ {
+ if ((drivers & 1) != 0)
+ {
+ scratchString.catf(" %u", d);
+ }
+ drivers >>= 1;
+ }
+}
+
// End
diff --git a/src/RepRapFirmware.h b/src/RepRapFirmware.h
index 3a1037c6..11f3a7b5 100644
--- a/src/RepRapFirmware.h
+++ b/src/RepRapFirmware.h
@@ -31,6 +31,7 @@ Licence: GPL
#include "Core.h"
#include "Configuration.h"
#include "Pins.h"
+
#include "Libraries/General/StringRef.h"
// Module numbers and names, used for diagnostics and debug
@@ -110,6 +111,8 @@ int StringContains(const char* string, const char* match);
void SafeStrncpy(char *dst, const char *src, size_t length) pre(length != 0);
void SafeStrncat(char *dst, const char *src, size_t length) pre(length != 0);
+void ListDrivers(const StringRef& str, DriversBitmap drivers);
+
// Macro to assign an array from an initialiser list
#define ARRAY_INIT(_dest, _init) static_assert(sizeof(_dest) == sizeof(_init), "Incompatible array types"); memcpy(_dest, _init, sizeof(_init));
@@ -194,6 +197,8 @@ extern StringRef scratchString;
// Common definitions used by more than one module
const size_t XYZ_AXES = 3; // The number of Cartesian axes
const size_t X_AXIS = 0, Y_AXIS = 1, Z_AXIS = 2, E0_AXIS = 3; // The indices of the Cartesian axes in drive arrays
+const size_t CoreXYU_AXES = 5; // The number of axes in a CoreXYU machine
+const size_t U_AXIS = 3, V_AXIS = 4; // The indices of the U and V motors in a CoreXYU machine (needed by Platform)
// Common conversion factors
const float MinutesToSeconds = 60.0;
@@ -211,11 +216,7 @@ typedef uint32_t FilePosition;
const FilePosition noFilePosition = 0xFFFFFFFF;
// Interrupt priorities - must be chosen with care! 0 is the highest priority, 15 is the lowest.
-#if SAM4E || SAM4S
-const uint32_t NvicPriorityWatchdog = 0; // watchdog has highest priority (SAM4 only)
-#endif
-
-const uint32_t NvicPriorityUart = 1; // UART is next to avoid character loss
+const uint32_t NvicPriorityUart = 1; // UART is highest to avoid character loss (it has only a 1-character receive buffer)
const uint32_t NvicPriorityDriversUsart = 2; // USART used to control and monitor the TMC2660 drivers
const uint32_t NvicPrioritySystick = 3; // systick kicks the watchdog and starts the ADC conversions, so must be quite high
const uint32_t NvicPriorityPins = 4; // priority for GPIO pin interrupts - filament sensors must be higher than step
diff --git a/src/Tools/Tool.cpp b/src/Tools/Tool.cpp
index 76628141..f4776eb2 100644
--- a/src/Tools/Tool.cpp
+++ b/src/Tools/Tool.cpp
@@ -139,7 +139,7 @@ Tool * Tool::freelist = nullptr;
}
}
-void Tool::Print(StringRef& reply)
+void Tool::Print(StringRef& reply) const
{
reply.printf("Tool %d - ", myNumber);
if (!StringEquals(name, ""))
@@ -301,35 +301,25 @@ bool Tool::AllHeatersAtHighTemperature(bool forExtrusion) const
return true;
}
-void Tool::Activate(Tool* currentlyActive)
+void Tool::Activate()
{
- if (state != ToolState::active)
+ for (size_t heater = 0; heater < heaterCount; heater++)
{
- if (currentlyActive != nullptr && currentlyActive != this)
- {
- currentlyActive->Standby();
- }
- for (size_t heater = 0; heater < heaterCount; heater++)
- {
- reprap.GetHeat().SetActiveTemperature(heaters[heater], activeTemperatures[heater]);
- reprap.GetHeat().SetStandbyTemperature(heaters[heater], standbyTemperatures[heater]);
- reprap.GetHeat().Activate(heaters[heater]);
- }
- state = ToolState::active;
+ reprap.GetHeat().SetActiveTemperature(heaters[heater], activeTemperatures[heater]);
+ reprap.GetHeat().SetStandbyTemperature(heaters[heater], standbyTemperatures[heater]);
+ reprap.GetHeat().Activate(heaters[heater]);
}
+ state = ToolState::active;
}
void Tool::Standby()
{
- if (state != ToolState::standby)
+ for (size_t heater = 0; heater < heaterCount; heater++)
{
- for (size_t heater = 0; heater < heaterCount; heater++)
- {
- reprap.GetHeat().SetStandbyTemperature(heaters[heater], standbyTemperatures[heater]);
- reprap.GetHeat().Standby(heaters[heater], this);
- }
- state = ToolState::standby;
+ reprap.GetHeat().SetStandbyTemperature(heaters[heater], standbyTemperatures[heater]);
+ reprap.GetHeat().Standby(heaters[heater], this);
}
+ state = ToolState::standby;
}
void Tool::SetVariables(const float* standby, const float* active)
diff --git a/src/Tools/Tool.h b/src/Tools/Tool.h
index 9f06e908..5e56b1d0 100644
--- a/src/Tools/Tool.h
+++ b/src/Tools/Tool.h
@@ -63,7 +63,7 @@ public:
const float* GetMix() const;
float MaxFeedrate() const;
float InstantDv() const;
- void Print(StringRef& reply);
+ void Print(StringRef& reply) const;
AxesBitmap GetXAxisMap() const { return xMapping; }
AxesBitmap GetYAxisMap() const { return yMapping; }
FansBitmap GetFanMapping() const { return fanMapping; }
@@ -75,7 +75,7 @@ public:
friend class RepRap;
protected:
- void Activate(Tool* currentlyActive);
+ void Activate();
void Standby();
void FlagTemperatureFault(int8_t dudHeater);
void ClearTemperatureFault(int8_t wasDudHeater);
diff --git a/src/Version.h b/src/Version.h
index d419161c..a6ce7a3f 100644
--- a/src/Version.h
+++ b/src/Version.h
@@ -9,11 +9,11 @@
#define SRC_VERSION_H_
#ifndef VERSION
-# define VERSION "1.20beta7"
+# define VERSION "1.20beta8"
#endif
#ifndef DATE
-# define DATE "2017-11-11"
+# define DATE "2017-11-17"
#endif
#define AUTHORS "reprappro, dc42, chrishamm, t3p3, dnewman"