diff options
51 files changed, 884 insertions, 469 deletions
@@ -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} "${workspace_loc:/${CoreName}/SAM3X8E/cores/arduino/syscalls.o}" ${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} "${workspace_loc:/${CoreName}/SAM3X8E/cores/arduino/syscalls.o}" ${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=""${workspace_loc:/${CoreName}/SAM3X8E/}""/> </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} "${workspace_loc:/${CoreName}/SAM4E8E/cores/arduino/syscalls.o}" ${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} "${workspace_loc:/${CoreName}/SAM4E8E/cores/arduino/syscalls.o}" ${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=""${workspace_loc:/${CoreName}/SAM4E8E/}""/> @@ -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} "${workspace_loc:/${CoreName}/RADDS/cores/arduino/syscalls.o}" ${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} "${workspace_loc:/${CoreName}/RADDS/cores/arduino/syscalls.o}" ${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=""${workspace_loc:/${CoreName}/RADDS/}""/> @@ -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} "${workspace_loc:/${CoreName}/SAM4E8E/cores/arduino/syscalls.o}" ${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} "${workspace_loc:/${CoreName}/SAM4E8E/cores/arduino/syscalls.o}" ${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=""${workspace_loc:/${CoreName}/SAM4E8E/}""/> @@ -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} "${workspace_loc:/${CoreName}/Alligator/cores/arduino/syscalls.o}" ${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} "${workspace_loc:/${CoreName}/Alligator/cores/arduino/syscalls.o}" ${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=""${workspace_loc:/${CoreName}/Alligator/}""/> 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 "${INPUTS}"" 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 "${INPUTS}"" 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 "${INPUTS}"" 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 "${INPUTS}"" 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 "${INPUTS}"" 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 "${INPUTS}"" 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 "${INPUTS}"" 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 "${INPUTS}"" 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 "${INPUTS}"" 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 "${INPUTS}"" 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 Binary files differdeleted file mode 100644 index 100d0371..00000000 --- a/Release/Duet-0.6-0.8.5/Edge/RepRapFirmware-1.20alpha4.bin +++ /dev/null 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 Binary files differdeleted file mode 100644 index 13f24d0a..00000000 --- a/Release/Duet-0.6-0.8.5/Edge/RepRapFirmware-1.20beta1.bin +++ /dev/null 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 Binary files differdeleted file mode 100644 index 8add86d9..00000000 --- a/Release/Duet-0.6-0.8.5/Edge/RepRapFirmware-1.20beta6.bin +++ /dev/null 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 Binary files differnew file mode 100644 index 00000000..9a9a7056 --- /dev/null +++ b/Release/Duet-0.6-0.8.5/Edge/RepRapFirmware-1.20beta8.bin diff --git a/Release/Duet-Ethernet/Edge/DuetEthernetFirmware-1.20beta1.bin b/Release/Duet-Ethernet/Edge/DuetEthernetFirmware-1.20beta1.bin Binary files differdeleted file mode 100644 index 393b3cf0..00000000 --- a/Release/Duet-Ethernet/Edge/DuetEthernetFirmware-1.20beta1.bin +++ /dev/null diff --git a/Release/Duet-Ethernet/Edge/DuetEthernetFirmware-1.20beta4.bin b/Release/Duet-Ethernet/Edge/DuetEthernetFirmware-1.20beta4.bin Binary files differdeleted file mode 100644 index 9736d30b..00000000 --- a/Release/Duet-Ethernet/Edge/DuetEthernetFirmware-1.20beta4.bin +++ /dev/null diff --git a/Release/Duet-Ethernet/Edge/DuetEthernetFirmware-1.20beta6.bin b/Release/Duet-Ethernet/Edge/DuetEthernetFirmware-1.20beta6.bin Binary files differdeleted file mode 100644 index 3f5f5fb1..00000000 --- a/Release/Duet-Ethernet/Edge/DuetEthernetFirmware-1.20beta6.bin +++ /dev/null diff --git a/Release/Duet-Ethernet/Edge/DuetEthernetFirmware-1.20beta8.bin b/Release/Duet-Ethernet/Edge/DuetEthernetFirmware-1.20beta8.bin Binary files differnew file mode 100644 index 00000000..85e146ec --- /dev/null +++ b/Release/Duet-Ethernet/Edge/DuetEthernetFirmware-1.20beta8.bin diff --git a/Release/Duet-WiFi/Edge/DuetWiFiFirmware-1.20beta1.bin b/Release/Duet-WiFi/Edge/DuetWiFiFirmware-1.20beta1.bin Binary files differdeleted file mode 100644 index 43eabb0b..00000000 --- a/Release/Duet-WiFi/Edge/DuetWiFiFirmware-1.20beta1.bin +++ /dev/null diff --git a/Release/Duet-WiFi/Edge/DuetWiFiFirmware-1.20beta4.bin b/Release/Duet-WiFi/Edge/DuetWiFiFirmware-1.20beta4.bin Binary files differdeleted file mode 100644 index 50a4be1d..00000000 --- a/Release/Duet-WiFi/Edge/DuetWiFiFirmware-1.20beta4.bin +++ /dev/null diff --git a/Release/Duet-WiFi/Edge/DuetWiFiFirmware-1.20beta6.bin b/Release/Duet-WiFi/Edge/DuetWiFiFirmware-1.20beta6.bin Binary files differdeleted file mode 100644 index f8213326..00000000 --- a/Release/Duet-WiFi/Edge/DuetWiFiFirmware-1.20beta6.bin +++ /dev/null diff --git a/Release/Duet-WiFi/Edge/DuetWiFiFirmware-1.20beta8.bin b/Release/Duet-WiFi/Edge/DuetWiFiFirmware-1.20beta8.bin Binary files differnew file mode 100644 index 00000000..7686f483 --- /dev/null +++ b/Release/Duet-WiFi/Edge/DuetWiFiFirmware-1.20beta8.bin diff --git a/Release/Duet-WiFi/Edge/DuetWiFiServer-1.20beta9.bin b/Release/Duet-WiFi/Edge/DuetWiFiServer-1.20beta9.bin Binary files differnew file mode 100644 index 00000000..903c3e8b --- /dev/null +++ b/Release/Duet-WiFi/Edge/DuetWiFiServer-1.20beta9.bin 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" |