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

github.com/Duet3D/RepRapFirmware.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Hammacher <bmasterc@gmail.com>2018-05-30 15:49:59 +0300
committerChristian Hammacher <bmasterc@gmail.com>2018-05-30 15:49:59 +0300
commit59b10fb8bf6c66d0c3371fffae3ebd786664301e (patch)
treed20b0424dc3b730485c26edc5d99dbf6f5d3589d
parentdbdf5476e2d2935cf16e641380e65f5ff42df69d (diff)
parentbd024c6930f88aba6c0a9e25b3160fcd4d3ab67e (diff)
Merge remote-tracking branch 'origin/v2-dev' into v2-chrishamm
-rw-r--r--.cproject363
-rw-r--r--.settings/language.settings.xml56
-rw-r--r--src/BugList.txt22
-rw-r--r--src/Configuration.h4
-rw-r--r--src/DuetM/Pins_DuetM.h2
-rw-r--r--src/DuetNG/Pins_DuetNG.h3
-rw-r--r--src/DuetNG/TMC2660.cpp4
-rw-r--r--src/FilamentMonitors/Duet3DFilamentMonitor.cpp4
-rw-r--r--src/FilamentMonitors/FilamentMonitor.cpp86
-rw-r--r--src/FilamentMonitors/FilamentMonitor.h17
-rw-r--r--src/FilamentMonitors/SimpleFilamentMonitor.cpp16
-rw-r--r--src/FilamentMonitors/SimpleFilamentMonitor.h1
-rw-r--r--src/GCodes/GCodeInput.cpp25
-rw-r--r--src/GCodes/GCodeInput.h5
-rw-r--r--src/GCodes/GCodes.cpp29
-rw-r--r--src/GCodes/GCodes.h1
-rw-r--r--src/GCodes/GCodes2.cpp37
-rw-r--r--src/GCodes/GCodes3.cpp1
-rw-r--r--src/Heating/Heat.cpp2
-rw-r--r--src/Heating/Sensors/DhtSensor.cpp455
-rw-r--r--src/Heating/Sensors/DhtSensor.h84
-rw-r--r--src/Heating/Sensors/TemperatureSensor.cpp10
-rw-r--r--src/Heating/Sensors/TemperatureSensor.h5
-rw-r--r--src/Movement/DDA.cpp28
-rw-r--r--src/Movement/DDA.h17
-rw-r--r--src/Movement/DriveMovement.cpp24
-rw-r--r--src/Movement/Move.cpp13
-rw-r--r--src/Networking/Network.cpp21
-rw-r--r--src/Networking/Network.h2
-rw-r--r--src/Platform.cpp49
-rw-r--r--src/Platform.h18
-rw-r--r--src/PortControl.cpp2
-rw-r--r--src/RepRap.cpp44
-rw-r--r--src/RepRap.h1
-rw-r--r--src/RepRapFirmware.h30
-rw-r--r--src/SoftTimer.cpp3
-rw-r--r--src/Storage/FileInfoParser.cpp2
-rw-r--r--src/Storage/FileStore.cpp315
-rw-r--r--src/Storage/FileStore.h11
-rw-r--r--src/Storage/MassStorage.cpp24
-rw-r--r--src/Storage/MassStorage.h2
-rw-r--r--src/Version.h4
42 files changed, 814 insertions, 1028 deletions
diff --git a/.cproject b/.cproject
index 123fd2e3..b4789922 100644
--- a/.cproject
+++ b/.cproject
@@ -116,122 +116,6 @@
</storageModule>
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
</cconfiguration>
- <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="Duet2">
- <macros>
- <stringMacro name="LinkFlags2" type="VALUE_TEXT" value="-Wl,--end-group -lm"/>
- <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="/home/christian/duet-dc42/gcc-arm-none-eabi-7-2017-q4-major/bin/"/>
- </macros>
- <externalSettings/>
- <extensions>
- <extension id="org.eclipse.cdt.core.ELF" point="org.eclipse.cdt.core.BinaryParser"/>
- <extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
- <extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>
- <extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
- <extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
- <extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
- </extensions>
- </storageModule>
- <storageModule moduleId="cdtBuildSystem" version="4.0.0">
- <configuration artifactExtension="elf" artifactName="Duet2CombinedFirmware" 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="Duet2" parent="cdt.managedbuild.config.gnu.cross.exe.release" postannouncebuildStep="Generating binary file" postbuildStep="arm-none-eabi-objcopy -O binary ${workspace_loc:/${ProjName}/${ConfigName}}/Duet2CombinedFirmware.elf ${workspace_loc:/${ProjName}/${ConfigName}}/Duet2CombinedFirmware.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="${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" parallelBuildOn="true" parallelizationNumber="optimal" superClass="cdt.managedbuild.builder.gnu.cross"/>
- <tool id="cdt.managedbuild.tool.gnu.cross.assembler.1415072364" name="Cross GCC Assembler" superClass="cdt.managedbuild.tool.gnu.cross.assembler">
- <inputType id="cdt.managedbuild.tool.gnu.assembler.input.769576359" superClass="cdt.managedbuild.tool.gnu.assembler.input"/>
- </tool>
- <tool commandLinePattern="${COMMAND} ${FLAGS} ${OUTPUT_FLAG} ${OUTPUT_PREFIX}${OUTPUT} ${INPUTS}" id="cdt.managedbuild.tool.gnu.cross.c.compiler.242253222" name="Cross GCC Compiler" superClass="cdt.managedbuild.tool.gnu.cross.c.compiler">
- <option defaultValue="gnu.c.optimization.level.most" id="gnu.c.compiler.option.optimization.level.1507087276" name="Optimization Level" superClass="gnu.c.compiler.option.optimization.level" useByScannerDiscovery="false" value="gnu.c.optimization.level.more" valueType="enumerated"/>
- <option id="gnu.c.compiler.option.debugging.level.861326742" name="Debug Level" superClass="gnu.c.compiler.option.debugging.level" useByScannerDiscovery="false" value="gnu.c.debugging.level.none" valueType="enumerated"/>
- <option id="gnu.c.compiler.option.misc.verbose.2125396829" name="Verbose (-v)" superClass="gnu.c.compiler.option.misc.verbose" useByScannerDiscovery="false" value="false" valueType="boolean"/>
- <option id="gnu.c.compiler.option.misc.other.1007303238" name="Other flags" superClass="gnu.c.compiler.option.misc.other" useByScannerDiscovery="false" value="-c -std=gnu99 -mcpu=cortex-m4 -mthumb -mfpu=fpv4-sp-d16 -mfloat-abi=hard -ffunction-sections -fdata-sections -nostdlib -Wdouble-promotion -fsingle-precision-constant &quot;-Wa,-ahl=$*.s&quot;" valueType="string"/>
- <option id="gnu.c.compiler.option.include.paths.1527974989" name="Include paths (-I)" superClass="gnu.c.compiler.option.include.paths" useByScannerDiscovery="false" valueType="includePath">
- <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${CoreName}/cores/arduino}&quot;"/>
- <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${CoreName}/libraries/Storage}&quot;"/>
- <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${CoreName}/asf}&quot;"/>
- <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${CoreName}/asf/common/utils}&quot;"/>
- <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${CoreName}/asf/common/services/ioport}&quot;"/>
- <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${CoreName}/asf/sam/drivers}&quot;"/>
- <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${CoreName}/asf/sam/utils}&quot;"/>
- <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${CoreName}/asf/sam/utils/cmsis/sam4e/include}&quot;"/>
- <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${CoreName}/asf/sam/utils/header_files}&quot;"/>
- <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${CoreName}/asf/sam/utils/preprocessor}&quot;"/>
- <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${CoreName}/asf/thirdparty/CMSIS/Include}&quot;"/>
- <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${CoreName}/variants/duetNG}&quot;"/>
- </option>
- <option id="gnu.c.compiler.option.preprocessor.def.symbols.1695995740" name="Defined symbols (-D)" superClass="gnu.c.compiler.option.preprocessor.def.symbols" useByScannerDiscovery="false" valueType="definedSymbols">
- <listOptionValue builtIn="false" value="__SAM4E8E__"/>
- <listOptionValue builtIn="false" value="DUET_NG"/>
- </option>
- <inputType id="cdt.managedbuild.tool.gnu.c.compiler.input.763992947" superClass="cdt.managedbuild.tool.gnu.c.compiler.input"/>
- </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} ${LinkFlags1} &quot;${workspace_loc:/${CoreName}/SAM4E8E/cores/arduino/syscalls.o}&quot; ${INPUTS} ${LinkFlags2}" id="cdt.managedbuild.tool.gnu.cross.cpp.linker.2096521800" name="Cross G++ Linker" superClass="cdt.managedbuild.tool.gnu.cross.cpp.linker">
- <option id="gnu.cpp.link.option.nostdlibs.111689408" name="No startup or default libs (-nostdlib)" superClass="gnu.cpp.link.option.nostdlibs" useByScannerDiscovery="false" value="false" valueType="boolean"/>
- <option id="gnu.cpp.link.option.paths.314107745" name="Library search path (-L)" superClass="gnu.cpp.link.option.paths" useByScannerDiscovery="false" valueType="libPaths">
- <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${CoreName}/SAM4E8E/}&quot;"/>
- </option>
- <option id="gnu.cpp.link.option.libs.698547262" 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.337829872" name="Linker flags" superClass="gnu.cpp.link.option.flags" useByScannerDiscovery="false" value="-Os -Wl,--gc-sections -Wl,--fatal-warnings -mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=hard -T${workspace_loc:/${CoreName}/variants/duetNG/linker_scripts/gcc/flash.ld} -Wl,-Map,${workspace_loc:/${ProjName}/${ConfigName}}/${BuildArtifactFileBaseName}.map" valueType="string"/>
- <inputType id="cdt.managedbuild.tool.gnu.cpp.linker.input.557435524" superClass="cdt.managedbuild.tool.gnu.cpp.linker.input">
- <additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
- <additionalInput kind="additionalinput" paths="$(LIBS)"/>
- </inputType>
- </tool>
- <tool command="g++" id="cdt.managedbuild.tool.gnu.cross.cpp.compiler.1263200833" name="Cross G++ Compiler" superClass="cdt.managedbuild.tool.gnu.cross.cpp.compiler">
- <option id="gnu.cpp.compiler.option.optimization.level.402804038" name="Optimization Level" superClass="gnu.cpp.compiler.option.optimization.level" useByScannerDiscovery="false" value="gnu.cpp.compiler.optimization.level.more" valueType="enumerated"/>
- <option id="gnu.cpp.compiler.option.debugging.level.919930419" name="Debug Level" superClass="gnu.cpp.compiler.option.debugging.level" useByScannerDiscovery="false" value="gnu.cpp.compiler.debugging.level.none" valueType="enumerated"/>
- <option id="gnu.cpp.compiler.option.other.verbose.34932857" name="Verbose (-v)" superClass="gnu.cpp.compiler.option.other.verbose" useByScannerDiscovery="false" value="false" valueType="boolean"/>
- <option id="gnu.cpp.compiler.option.other.other.549139443" name="Other flags" superClass="gnu.cpp.compiler.option.other.other" useByScannerDiscovery="false" value="-c -std=gnu++14 -mcpu=cortex-m4 -mthumb -mfpu=fpv4-sp-d16 -mfloat-abi=hard -ffunction-sections -fdata-sections -fno-threadsafe-statics -fno-rtti -fno-exceptions -nostdlib -Wdouble-promotion -fsingle-precision-constant &quot;-Wa,-ahl=$*.s&quot;" valueType="string"/>
- <option id="gnu.cpp.compiler.option.include.paths.251815634" name="Include paths (-I)" superClass="gnu.cpp.compiler.option.include.paths" useByScannerDiscovery="false" valueType="includePath">
- <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${CoreName}/cores/arduino}&quot;"/>
- <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${CoreName}/libraries/Flash}&quot;"/>
- <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${CoreName}/libraries/SharedSpi}&quot;"/>
- <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${CoreName}/libraries/Storage}&quot;"/>
- <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${CoreName}/libraries/Wire}&quot;"/>
- <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${CoreName}/asf}&quot;"/>
- <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${CoreName}/asf/common/utils}&quot;"/>
- <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${CoreName}/asf/common/services/clock}&quot;"/>
- <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${CoreName}/asf/common/services/ioport}&quot;"/>
- <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${CoreName}/asf/sam/drivers}&quot;"/>
- <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${CoreName}/asf/sam/services/flash_efc}&quot;"/>
- <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${CoreName}/asf/sam/utils}&quot;"/>
- <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${CoreName}/asf/sam/utils/cmsis/sam4e/include}&quot;"/>
- <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${CoreName}/asf/sam/utils/header_files}&quot;"/>
- <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${CoreName}/asf/sam/utils/preprocessor}&quot;"/>
- <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${CoreName}/asf/thirdparty/CMSIS/Include}&quot;"/>
- <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${CoreName}/variants/duetNG}&quot;"/>
- <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/src}&quot;"/>
- <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/src/DuetNG}&quot;"/>
- <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/src/Networking}&quot;"/>
- <listOptionValue builtIn="false" value="&quot;${workspace_loc:/DuetWiFiSocketServer/src/include}&quot;"/>
- <listOptionValue builtIn="false" value="&quot;${workspace_loc:/FreeRTOS/src/include}&quot;"/>
- <listOptionValue builtIn="false" value="&quot;${workspace_loc:/FreeRTOS/src/portable/GCC/ARM_CM4F}&quot;"/>
- </option>
- <option id="gnu.cpp.compiler.option.preprocessor.def.1610427238" name="Defined symbols (-D)" superClass="gnu.cpp.compiler.option.preprocessor.def" useByScannerDiscovery="false" valueType="definedSymbols">
- <listOptionValue builtIn="false" value="__SAM4E8E__"/>
- <listOptionValue builtIn="false" value="DUET_NG"/>
- <listOptionValue builtIn="false" value="_XOPEN_SOURCE"/>
- </option>
- <inputType id="cdt.managedbuild.tool.gnu.cpp.compiler.input.151249281" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.input"/>
- </tool>
- </toolChain>
- </folderInfo>
- <sourceEntries>
- <entry excluding="src/Networking/LwipEthernet|src/Alligator|src/SAME70_TEST|src/Display|src/Duet|src/DuetM|src/RADDS" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name=""/>
- </sourceEntries>
- </configuration>
- </storageModule>
- <storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
- </cconfiguration>
<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>
@@ -463,253 +347,6 @@
</storageModule>
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
</cconfiguration>
- <cconfiguration id="cdt.managedbuild.config.gnu.cross.exe.release.516195201.976458850.241502451.1275216290.1979117592">
- <storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="cdt.managedbuild.config.gnu.cross.exe.release.516195201.976458850.241502451.1275216290.1979117592" moduleId="org.eclipse.cdt.core.settings" name="DuetM">
- <macros>
- <stringMacro name="LinkFlags2" type="VALUE_TEXT" value="-Wl,--end-group -lm"/>
- <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="/home/christian/duet-dc42/gcc-arm-none-eabi-7-2017-q4-major/bin/"/>
- </macros>
- <externalSettings/>
- <extensions>
- <extension id="org.eclipse.cdt.core.ELF" point="org.eclipse.cdt.core.BinaryParser"/>
- <extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
- <extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>
- <extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
- <extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
- <extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
- </extensions>
- </storageModule>
- <storageModule moduleId="cdtBuildSystem" version="4.0.0">
- <configuration artifactExtension="elf" artifactName="DuetMaestroFirmware" 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.1979117592" name="DuetM" parent="cdt.managedbuild.config.gnu.cross.exe.release" postannouncebuildStep="Generating binary file" postbuildStep="arm-none-eabi-objcopy -O binary ${workspace_loc:/${ProjName}/${ConfigName}}/DuetMaestroFirmware.elf ${workspace_loc:/${ProjName}/${ConfigName}}/DuetMaestroFirmware.bin">
- <folderInfo id="cdt.managedbuild.config.gnu.cross.exe.release.516195201.976458850.241502451.1275216290.1979117592." name="/" resourcePath="">
- <toolChain id="cdt.managedbuild.toolchain.gnu.cross.exe.release.366031386" name="Cross GCC" superClass="cdt.managedbuild.toolchain.gnu.cross.exe.release">
- <option id="cdt.managedbuild.option.gnu.cross.path.1130802612" name="Path" superClass="cdt.managedbuild.option.gnu.cross.path" useByScannerDiscovery="false" value="${GccPath}" valueType="string"/>
- <option id="cdt.managedbuild.option.gnu.cross.prefix.2006501500" 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.703840241" isAbstract="false" osList="all" superClass="cdt.managedbuild.targetPlatform.gnu.cross"/>
- <builder buildPath="${workspace_loc:/RepRapFirmware}/Release" id="cdt.managedbuild.builder.gnu.cross.891498508" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="Gnu Make Builder" parallelBuildOn="true" parallelizationNumber="optimal" superClass="cdt.managedbuild.builder.gnu.cross"/>
- <tool id="cdt.managedbuild.tool.gnu.cross.assembler.725393725" name="Cross GCC Assembler" superClass="cdt.managedbuild.tool.gnu.cross.assembler">
- <inputType id="cdt.managedbuild.tool.gnu.assembler.input.1095121794" superClass="cdt.managedbuild.tool.gnu.assembler.input"/>
- </tool>
- <tool commandLinePattern="${COMMAND} ${FLAGS} ${OUTPUT_FLAG} ${OUTPUT_PREFIX}${OUTPUT} ${INPUTS}" id="cdt.managedbuild.tool.gnu.cross.c.compiler.1499812394" name="Cross GCC Compiler" superClass="cdt.managedbuild.tool.gnu.cross.c.compiler">
- <option defaultValue="gnu.c.optimization.level.most" id="gnu.c.compiler.option.optimization.level.845554023" name="Optimization Level" superClass="gnu.c.compiler.option.optimization.level" useByScannerDiscovery="false" value="gnu.c.optimization.level.more" valueType="enumerated"/>
- <option id="gnu.c.compiler.option.debugging.level.590351259" name="Debug Level" superClass="gnu.c.compiler.option.debugging.level" useByScannerDiscovery="false" value="gnu.c.debugging.level.none" valueType="enumerated"/>
- <option id="gnu.c.compiler.option.misc.verbose.781620320" name="Verbose (-v)" superClass="gnu.c.compiler.option.misc.verbose" useByScannerDiscovery="false" value="false" valueType="boolean"/>
- <option id="gnu.c.compiler.option.misc.other.1000778171" name="Other flags" superClass="gnu.c.compiler.option.misc.other" useByScannerDiscovery="false" value="-c -std=gnu99 -mcpu=cortex-m4 -mthumb -ffunction-sections -fdata-sections -nostdlib -Wdouble-promotion -fsingle-precision-constant &quot;-Wa,-ahl=$*.s&quot;" valueType="string"/>
- <option id="gnu.c.compiler.option.include.paths.406147754" name="Include paths (-I)" superClass="gnu.c.compiler.option.include.paths" useByScannerDiscovery="false" valueType="includePath">
- <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${CoreName}/cores/arduino}&quot;"/>
- <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${CoreName}/libraries/Storage}&quot;"/>
- <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${CoreName}/asf}&quot;"/>
- <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${CoreName}/asf/common/utils}&quot;"/>
- <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${CoreName}/asf/common/services/ioport}&quot;"/>
- <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${CoreName}/asf/sam/drivers/hsmci}&quot;"/>
- <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${CoreName}/asf/sam/drivers/rstc}&quot;"/>
- <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${CoreName}/asf/sam/drivers/rtc}&quot;"/>
- <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${CoreName}/asf/sam/utils}&quot;"/>
- <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${CoreName}/asf/sam/utils/cmsis/sam4s/include}&quot;"/>
- <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${CoreName}/asf/sam/utils/header_files}&quot;"/>
- <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${CoreName}/asf/sam/utils/preprocessor}&quot;"/>
- <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${CoreName}/asf/thirdparty/CMSIS/Include}&quot;"/>
- <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${CoreName}/variants/sam4s}&quot;"/>
- <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/src/Networking/W5500Ethernet}&quot;"/>
- <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/src/Networking/W5500Ethernet/Wiznet/Ethernet}&quot;"/>
- </option>
- <option id="gnu.c.compiler.option.preprocessor.def.symbols.2086359888" name="Defined symbols (-D)" superClass="gnu.c.compiler.option.preprocessor.def.symbols" useByScannerDiscovery="false" valueType="definedSymbols">
- <listOptionValue builtIn="false" value="__SAM4S8C__"/>
- <listOptionValue builtIn="false" value="DUET_M"/>
- </option>
- <inputType id="cdt.managedbuild.tool.gnu.c.compiler.input.1068938062" superClass="cdt.managedbuild.tool.gnu.c.compiler.input"/>
- </tool>
- <tool id="cdt.managedbuild.tool.gnu.cross.c.linker.1542219221" name="Cross GCC Linker" superClass="cdt.managedbuild.tool.gnu.cross.c.linker"/>
- <tool id="cdt.managedbuild.tool.gnu.cross.archiver.345792883" name="Cross GCC Archiver" superClass="cdt.managedbuild.tool.gnu.cross.archiver"/>
- <tool command="gcc" commandLinePattern="${COMMAND} ${FLAGS} ${OUTPUT_FLAG} ${OUTPUT_PREFIX}${OUTPUT} ${LinkFlags1} &quot;${workspace_loc:/${CoreName}/SAM4S/cores/arduino/syscalls.o}&quot; ${INPUTS} ${LinkFlags2}" id="cdt.managedbuild.tool.gnu.cross.cpp.linker.2089103925" name="Cross G++ Linker" superClass="cdt.managedbuild.tool.gnu.cross.cpp.linker">
- <option id="gnu.cpp.link.option.nostdlibs.137133477" 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.857128754" name="Library search path (-L)" superClass="gnu.cpp.link.option.paths" useByScannerDiscovery="false" valueType="libPaths">
- <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${CoreName}/SAM4S/}&quot;"/>
- </option>
- <option id="gnu.cpp.link.option.libs.22224333" 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.119775687" name="Linker flags" superClass="gnu.cpp.link.option.flags" useByScannerDiscovery="false" value="-Os -Wl,--gc-sections -Wl,--fatal-warnings -mcpu=cortex-m4 -T${workspace_loc:/${CoreName}/variants/sam4s/linker_scripts/gcc/flash.ld} -Wl,-Map,${workspace_loc:/${ProjName}/${ConfigName}}/${BuildArtifactFileBaseName}.map" valueType="string"/>
- <inputType id="cdt.managedbuild.tool.gnu.cpp.linker.input.2016349335" superClass="cdt.managedbuild.tool.gnu.cpp.linker.input">
- <additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
- <additionalInput kind="additionalinput" paths="$(LIBS)"/>
- </inputType>
- </tool>
- <tool command="g++" id="cdt.managedbuild.tool.gnu.cross.cpp.compiler.1704683776" name="Cross G++ Compiler" superClass="cdt.managedbuild.tool.gnu.cross.cpp.compiler">
- <option id="gnu.cpp.compiler.option.optimization.level.20377069" name="Optimization Level" superClass="gnu.cpp.compiler.option.optimization.level" useByScannerDiscovery="false" value="gnu.cpp.compiler.optimization.level.more" valueType="enumerated"/>
- <option id="gnu.cpp.compiler.option.debugging.level.331115034" name="Debug Level" superClass="gnu.cpp.compiler.option.debugging.level" useByScannerDiscovery="false" value="gnu.cpp.compiler.debugging.level.none" valueType="enumerated"/>
- <option id="gnu.cpp.compiler.option.other.verbose.629252168" name="Verbose (-v)" superClass="gnu.cpp.compiler.option.other.verbose" useByScannerDiscovery="false" value="false" valueType="boolean"/>
- <option id="gnu.cpp.compiler.option.other.other.1110817524" name="Other flags" superClass="gnu.cpp.compiler.option.other.other" useByScannerDiscovery="false" value="-c -std=gnu++14 -mcpu=cortex-m4 -mthumb -ffunction-sections -fdata-sections -fno-threadsafe-statics -fno-rtti -fno-exceptions -nostdlib -Wdouble-promotion -fsingle-precision-constant &quot;-Wa,-ahl=$*.s&quot;" valueType="string"/>
- <option id="gnu.cpp.compiler.option.include.paths.1099513783" name="Include paths (-I)" superClass="gnu.cpp.compiler.option.include.paths" useByScannerDiscovery="false" valueType="includePath">
- <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${CoreName}/cores/arduino}&quot;"/>
- <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${CoreName}/libraries/Flash}&quot;"/>
- <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${CoreName}/libraries/SharedSpi}&quot;"/>
- <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${CoreName}/libraries/Storage}&quot;"/>
- <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${CoreName}/libraries/Wire}&quot;"/>
- <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${CoreName}/asf}&quot;"/>
- <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${CoreName}/asf/common/utils}&quot;"/>
- <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${CoreName}/asf/common/services/clock}&quot;"/>
- <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${CoreName}/asf/common/services/ioport}&quot;"/>
- <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${CoreName}/asf/sam/drivers}&quot;"/>
- <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${CoreName}/asf/sam/services/flash_efc}&quot;"/>
- <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${CoreName}/asf/sam/utils}&quot;"/>
- <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${CoreName}/asf/sam/utils/cmsis/sam4s/include}&quot;"/>
- <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${CoreName}/asf/sam/utils/header_files}&quot;"/>
- <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${CoreName}/asf/sam/utils/preprocessor}&quot;"/>
- <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${CoreName}/asf/thirdparty/CMSIS/Include}&quot;"/>
- <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${CoreName}/variants/sam4s}&quot;"/>
- <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/src}&quot;"/>
- <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/src/DuetM}&quot;"/>
- <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/src/Networking}&quot;"/>
- </option>
- <option id="gnu.cpp.compiler.option.preprocessor.def.1565207565" name="Defined symbols (-D)" superClass="gnu.cpp.compiler.option.preprocessor.def" useByScannerDiscovery="false" valueType="definedSymbols">
- <listOptionValue builtIn="false" value="__SAM4S8C__"/>
- <listOptionValue builtIn="false" value="DUET_M"/>
- <listOptionValue builtIn="false" value="_XOPEN_SOURCE"/>
- </option>
- <inputType id="cdt.managedbuild.tool.gnu.cpp.compiler.input.1354140799" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.input"/>
- </tool>
- </toolChain>
- </folderInfo>
- <sourceEntries>
- <entry excluding="src/Networking/ESP8266WiFi|src/Networking/LwipEthernet|src/DuetNG/DuetEthernet/Wiznet/Internet/TFTP|src/DuetNG/DuetEthernet/Ethernet3|src/DuetNG/DuetWiFi|src/DuetNG/DuetEthernet/Wiznet/Internet/FTPServer|src/Duet|src/DuetNG/DuetEthernet/Wiznet/Internet/SNTP|src/DuetNG/DuetEthernet/Ethernet3/examples|src/DuetNG|src/DuetNG/DuetEthernet/Wiznet/Internet/DNS|src/DuetNG/DuetEthernet/Wiznet/Application|src/DuetNG/DuetEthernet/Wiznet/Internet/MQTT|src/Alligator|src/DuetNG/DuetEthernet/Wiznet/Internet/FTPClient|src/SAME70_TEST|src/DuetNG/DuetEthernet/Wiznet/Internet/httpServer|src/DuetNG/DuetEthernet/Wiznet/Internet/SNMP|src/NetworkESP8266|src/Networking/ESP8266|src/RADDS" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name=""/>
- </sourceEntries>
- </configuration>
- </storageModule>
- <storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
- </cconfiguration>
- <cconfiguration id="cdt.managedbuild.config.gnu.cross.exe.release.516195201.976458850.241502451.1275216290.274082366.1645191116">
- <storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="cdt.managedbuild.config.gnu.cross.exe.release.516195201.976458850.241502451.1275216290.274082366.1645191116" moduleId="org.eclipse.cdt.core.settings" name="SAME70">
- <macros>
- <stringMacro name="LinkFlags2" type="VALUE_TEXT" value="-Wl,--end-group -lm"/>
- <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="/home/christian/duet-dc42/gcc-arm-none-eabi-7-2017-q4-major/bin/"/>
- </macros>
- <externalSettings/>
- <extensions>
- <extension id="org.eclipse.cdt.core.ELF" point="org.eclipse.cdt.core.BinaryParser"/>
- <extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
- <extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>
- <extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
- <extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
- <extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
- </extensions>
- </storageModule>
- <storageModule moduleId="cdtBuildSystem" version="4.0.0">
- <configuration artifactExtension="elf" artifactName="SAME70Firmware" 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.274082366.1645191116" name="SAME70" parent="cdt.managedbuild.config.gnu.cross.exe.release" postannouncebuildStep="Generating binary file" postbuildStep="arm-none-eabi-objcopy -O binary ${workspace_loc:/${ProjName}/${ConfigName}}/SAME70Firmware.elf ${workspace_loc:/${ProjName}/${ConfigName}}/SAME70Firmware.bin">
- <folderInfo id="cdt.managedbuild.config.gnu.cross.exe.release.516195201.976458850.241502451.1275216290.274082366.1645191116." name="/" resourcePath="">
- <toolChain id="cdt.managedbuild.toolchain.gnu.cross.exe.release.1208556935" name="Cross GCC" superClass="cdt.managedbuild.toolchain.gnu.cross.exe.release">
- <option id="cdt.managedbuild.option.gnu.cross.path.54036310" name="Path" superClass="cdt.managedbuild.option.gnu.cross.path" useByScannerDiscovery="false" value="${GccPath}" valueType="string"/>
- <option id="cdt.managedbuild.option.gnu.cross.prefix.680180206" 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.245858471" isAbstract="false" osList="all" superClass="cdt.managedbuild.targetPlatform.gnu.cross"/>
- <builder buildPath="${workspace_loc:/RepRapFirmware}/Release" id="cdt.managedbuild.builder.gnu.cross.1549857360" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="Gnu Make Builder" parallelBuildOn="true" parallelizationNumber="optimal" superClass="cdt.managedbuild.builder.gnu.cross"/>
- <tool id="cdt.managedbuild.tool.gnu.cross.assembler.51365542" name="Cross GCC Assembler" superClass="cdt.managedbuild.tool.gnu.cross.assembler">
- <inputType id="cdt.managedbuild.tool.gnu.assembler.input.930635937" superClass="cdt.managedbuild.tool.gnu.assembler.input"/>
- </tool>
- <tool commandLinePattern="${COMMAND} ${FLAGS} ${OUTPUT_FLAG} ${OUTPUT_PREFIX}${OUTPUT} ${INPUTS}" id="cdt.managedbuild.tool.gnu.cross.c.compiler.1860851793" name="Cross GCC Compiler" superClass="cdt.managedbuild.tool.gnu.cross.c.compiler">
- <option defaultValue="gnu.c.optimization.level.most" id="gnu.c.compiler.option.optimization.level.1218151514" name="Optimization Level" superClass="gnu.c.compiler.option.optimization.level" useByScannerDiscovery="false" value="gnu.c.optimization.level.more" valueType="enumerated"/>
- <option id="gnu.c.compiler.option.debugging.level.56217404" name="Debug Level" superClass="gnu.c.compiler.option.debugging.level" useByScannerDiscovery="false" value="gnu.c.debugging.level.default" valueType="enumerated"/>
- <option id="gnu.c.compiler.option.misc.verbose.625475772" name="Verbose (-v)" superClass="gnu.c.compiler.option.misc.verbose" useByScannerDiscovery="false" value="false" valueType="boolean"/>
- <option id="gnu.c.compiler.option.misc.other.551649360" name="Other flags" superClass="gnu.c.compiler.option.misc.other" useByScannerDiscovery="false" value="-c -std=gnu99 -mcpu=cortex-m7 -mthumb -mfpu=fpv5-d16 -mfloat-abi=hard -ffunction-sections -fdata-sections -nostdlib -Wdouble-promotion -fsingle-precision-constant" valueType="string"/>
- <option id="gnu.c.compiler.option.include.paths.279180230" name="Include paths (-I)" superClass="gnu.c.compiler.option.include.paths" useByScannerDiscovery="false" valueType="includePath">
- <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${CoreName}/cores/arduino}&quot;"/>
- <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${CoreName}/libraries/Storage}&quot;"/>
- <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${CoreName}/asf}&quot;"/>
- <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${CoreName}/asf/common/utils}&quot;"/>
- <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${CoreName}/asf/common/services/clock}&quot;"/>
- <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${CoreName}/asf/common/services/ioport}&quot;"/>
- <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${CoreName}/asf/sam/components/ethernet_phy/ksz8081rna}&quot;"/>
- <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${CoreName}/asf/sam/drivers/hsmci}&quot;"/>
- <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${CoreName}/asf/sam/drivers/gmac}&quot;"/>
- <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${CoreName}/asf/sam/drivers/pmc}&quot;"/>
- <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${CoreName}/asf/sam/drivers/rstc}&quot;"/>
- <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${CoreName}/asf/sam/drivers/rtc}&quot;"/>
- <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${CoreName}/asf/sam/utils}&quot;"/>
- <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${CoreName}/asf/sam/utils/cmsis/same70/include}&quot;"/>
- <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${CoreName}/asf/sam/utils/header_files}&quot;"/>
- <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${CoreName}/asf/sam/utils/preprocessor}&quot;"/>
- <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${CoreName}/asf/thirdparty/CMSIS/Include}&quot;"/>
- <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${CoreName}/variants/same70}&quot;"/>
- <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/src/SAME70_TEST}&quot;"/>
- <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/src/Networking/LwipEthernet}&quot;"/>
- <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/src/Networking/LwipEthernet/Lwip/src/include}&quot;"/>
- </option>
- <option id="gnu.c.compiler.option.preprocessor.def.symbols.1749077053" name="Defined symbols (-D)" superClass="gnu.c.compiler.option.preprocessor.def.symbols" useByScannerDiscovery="false" valueType="definedSymbols">
- <listOptionValue builtIn="false" value="__SAME70Q21__"/>
- <listOptionValue builtIn="false" value="SAME70_TEST_BOARD"/>
- </option>
- <option id="gnu.c.compiler.option.dialect.std.699989842" name="Language standard" superClass="gnu.c.compiler.option.dialect.std" useByScannerDiscovery="true" value="gnu.c.compiler.dialect.default" valueType="enumerated"/>
- <inputType id="cdt.managedbuild.tool.gnu.c.compiler.input.113093911" superClass="cdt.managedbuild.tool.gnu.c.compiler.input"/>
- </tool>
- <tool id="cdt.managedbuild.tool.gnu.cross.c.linker.533117704" name="Cross GCC Linker" superClass="cdt.managedbuild.tool.gnu.cross.c.linker"/>
- <tool id="cdt.managedbuild.tool.gnu.cross.archiver.1081354337" name="Cross GCC Archiver" superClass="cdt.managedbuild.tool.gnu.cross.archiver"/>
- <tool command="gcc" commandLinePattern="${COMMAND} ${FLAGS} ${OUTPUT_FLAG} ${OUTPUT_PREFIX}${OUTPUT} ${LinkFlags1} &quot;${workspace_loc:/${CoreName}/SAME70/cores/arduino/syscalls.o}&quot; ${INPUTS} ${LinkFlags2}" id="cdt.managedbuild.tool.gnu.cross.cpp.linker.910947184" name="Cross G++ Linker" superClass="cdt.managedbuild.tool.gnu.cross.cpp.linker">
- <option id="gnu.cpp.link.option.nostdlibs.1582617170" 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.190121832" name="Library search path (-L)" superClass="gnu.cpp.link.option.paths" useByScannerDiscovery="false" valueType="libPaths">
- <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${CoreName}/SAME70/}&quot;"/>
- <listOptionValue builtIn="false" value="&quot;${workspace_loc:/FreeRTOS/SAME70}&quot;"/>
- </option>
- <option id="gnu.cpp.link.option.libs.1037992649" name="Libraries (-l)" superClass="gnu.cpp.link.option.libs" useByScannerDiscovery="false" valueType="libs">
- <listOptionValue builtIn="false" value="${CoreName}"/>
- <listOptionValue builtIn="false" value="FreeRTOS"/>
- </option>
- <option id="gnu.cpp.link.option.flags.1385845561" name="Linker flags" superClass="gnu.cpp.link.option.flags" useByScannerDiscovery="false" value="-Os -Wl,--gc-sections -Wl,--fatal-warnings -mcpu=cortex-m7 -mthumb -mfpu=fpv5-d16 -mfloat-abi=hard -T${workspace_loc:/${CoreName}/variants/same70/linker_scripts/gcc/flash.ld} -Wl,-Map,${workspace_loc:/${ProjName}/${ConfigName}}/${BuildArtifactFileBaseName}.map" valueType="string"/>
- <inputType id="cdt.managedbuild.tool.gnu.cpp.linker.input.557767962" superClass="cdt.managedbuild.tool.gnu.cpp.linker.input">
- <additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
- <additionalInput kind="additionalinput" paths="$(LIBS)"/>
- </inputType>
- </tool>
- <tool command="g++" id="cdt.managedbuild.tool.gnu.cross.cpp.compiler.1203733011" name="Cross G++ Compiler" superClass="cdt.managedbuild.tool.gnu.cross.cpp.compiler">
- <option id="gnu.cpp.compiler.option.optimization.level.1851679280" name="Optimization Level" superClass="gnu.cpp.compiler.option.optimization.level" useByScannerDiscovery="false" value="gnu.cpp.compiler.optimization.level.more" valueType="enumerated"/>
- <option id="gnu.cpp.compiler.option.debugging.level.2074037572" name="Debug Level" superClass="gnu.cpp.compiler.option.debugging.level" useByScannerDiscovery="false" value="gnu.cpp.compiler.debugging.level.default" valueType="enumerated"/>
- <option id="gnu.cpp.compiler.option.other.verbose.1697711865" name="Verbose (-v)" superClass="gnu.cpp.compiler.option.other.verbose" useByScannerDiscovery="false" value="false" valueType="boolean"/>
- <option id="gnu.cpp.compiler.option.other.other.930112113" name="Other flags" superClass="gnu.cpp.compiler.option.other.other" useByScannerDiscovery="false" value="-c -std=gnu++14 -mcpu=cortex-m7 -mthumb -mfpu=fpv5-d16 -mfloat-abi=hard -ffunction-sections -fdata-sections -fno-threadsafe-statics -fno-rtti -fno-exceptions -nostdlib -Wdouble-promotion -fsingle-precision-constant" valueType="string"/>
- <option id="gnu.cpp.compiler.option.include.paths.2076704999" name="Include paths (-I)" superClass="gnu.cpp.compiler.option.include.paths" useByScannerDiscovery="false" valueType="includePath">
- <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${CoreName}/cores/arduino}&quot;"/>
- <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${CoreName}/libraries/Flash}&quot;"/>
- <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${CoreName}/libraries/SharedSpi}&quot;"/>
- <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${CoreName}/libraries/Storage}&quot;"/>
- <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${CoreName}/libraries/Wire}&quot;"/>
- <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${CoreName}/asf}&quot;"/>
- <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${CoreName}/asf/common/utils}&quot;"/>
- <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${CoreName}/asf/common/services/clock}&quot;"/>
- <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${CoreName}/asf/common/services/ioport}&quot;"/>
- <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${CoreName}/asf/sam/drivers}&quot;"/>
- <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${CoreName}/asf/sam/drivers/gmac}&quot;"/>
- <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${CoreName}/asf/sam/services/flash_efc}&quot;"/>
- <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${CoreName}/asf/sam/utils}&quot;"/>
- <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${CoreName}/asf/sam/utils/cmsis/same70/include}&quot;"/>
- <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${CoreName}/asf/sam/utils/header_files}&quot;"/>
- <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${CoreName}/asf/sam/utils/preprocessor}&quot;"/>
- <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${CoreName}/asf/thirdparty/CMSIS/Include}&quot;"/>
- <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${CoreName}/variants/same70}&quot;"/>
- <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/src}&quot;"/>
- <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/src/SAME70_TEST}&quot;"/>
- <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/src/Networking}&quot;"/>
- <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/src/Networking/LwipEthernet}&quot;"/>
- <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/src/Networking/LwipEthernet/Lwip/src/include}&quot;"/>
- <listOptionValue builtIn="false" value="&quot;${workspace_loc:/DuetWiFiSocketServer/src/include}&quot;"/>
- </option>
- <option id="gnu.cpp.compiler.option.preprocessor.def.178336065" name="Defined symbols (-D)" superClass="gnu.cpp.compiler.option.preprocessor.def" useByScannerDiscovery="false" valueType="definedSymbols">
- <listOptionValue builtIn="false" value="__SAME70Q21__"/>
- <listOptionValue builtIn="false" value="SAME70_TEST_BOARD"/>
- <listOptionValue builtIn="false" value="_XOPEN_SOURCE"/>
- </option>
- <option id="gnu.cpp.compiler.option.dialect.std.678634997" name="Language standard" superClass="gnu.cpp.compiler.option.dialect.std" useByScannerDiscovery="true" value="gnu.cpp.compiler.dialect.default" valueType="enumerated"/>
- <inputType id="cdt.managedbuild.tool.gnu.cpp.compiler.input.484276272" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.input"/>
- </tool>
- </toolChain>
- </folderInfo>
- <sourceEntries>
- <entry excluding="src/Networking/W5500Ethernet|src/DuetNG/DuetWiFi|src/Duet|src/DuetNG/DuetEthernet/Wiznet/Internet/SNTP|src/DuetNG|src/Networking/LwipEthernet/Lwip/test|src/DuetNG/DuetEthernet/Wiznet/Internet/DNS|src/DuetNG/DuetEthernet/Wiznet/Application|src/DuetNG/DuetEthernet/Wiznet/Internet/MQTT|src/Alligator|src/Display|src/Networking/LwipEthernet/Lwip/src/apps/mqtt|src/Networking/LwipEthernet/Lwip/doc|src/DuetNG/DuetEthernet/Wiznet/Internet/TFTP|src/DuetNG/DuetEthernet/Ethernet3|src/Networking/LwipEthernet/Lwip/src/apps/snmp|src/Networking/LwipEthernet/Lwip/src/apps/httpd|src/DuetNG/DuetEthernet/Wiznet/Internet/FTPServer|src/DuetNG/DuetEthernet/Ethernet3/examples|src/Networking/LwipEthernet/Lwip/src/apps/tftp|src/Networking/LwipEthernet/Lwip/src/netif/ppp|src/Networking/LwipEthernet/Lwip/src/apps/lwiperf|src/DuetNG/DuetEthernet/Wiznet/Internet/FTPClient|src/Networking/LwipEthernet/Lwip/src/apps/sntp|src/DuetNG/DuetEthernet/Wiznet/Internet/httpServer|src/DuetNG/DuetEthernet/Wiznet/Internet/SNMP|src/DuetM|src/RADDS" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name=""/>
- </sourceEntries>
- </configuration>
- </storageModule>
- <storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
- </cconfiguration>
<cconfiguration id="cdt.managedbuild.config.gnu.cross.exe.release.516195201.976458850.241502451.170574622">
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="cdt.managedbuild.config.gnu.cross.exe.release.516195201.976458850.241502451.170574622" moduleId="org.eclipse.cdt.core.settings" name="Duet2_RTOS">
<macros>
diff --git a/.settings/language.settings.xml b/.settings/language.settings.xml
index b0a398db..1998c537 100644
--- a/.settings/language.settings.xml
+++ b/.settings/language.settings.xml
@@ -5,18 +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="698946535669195332" id="org.eclipse.cdt.build.crossgcc.CrossGCCBuiltinSpecsDetector" keep-relative-paths="false" name="CDT Cross GCC Built-in Compiler Settings" parameter="${COMMAND} ${FLAGS} -E -P -v -dD &quot;${INPUTS}&quot;" prefer-non-shared="true">
- <language-scope id="org.eclipse.cdt.core.gcc"/>
- <language-scope id="org.eclipse.cdt.core.g++"/>
- </provider>
- </extension>
- </configuration>
- <configuration id="cdt.managedbuild.config.gnu.cross.exe.release.516195201.976458850.241502451" name="Duet2">
- <extension point="org.eclipse.cdt.core.LanguageSettingsProvider">
- <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="698946535669195332" id="org.eclipse.cdt.build.crossgcc.CrossGCCBuiltinSpecsDetector" keep-relative-paths="false" name="CDT Cross GCC Built-in Compiler Settings" parameter="${COMMAND} ${FLAGS} -E -P -v -dD &quot;${INPUTS}&quot;" prefer-non-shared="true">
+ <provider class="org.eclipse.cdt.internal.build.crossgcc.CrossGCCBuiltinSpecsDetector" console="false" env-hash="-114279925955362495" id="org.eclipse.cdt.build.crossgcc.CrossGCCBuiltinSpecsDetector" keep-relative-paths="false" name="CDT Cross GCC Built-in Compiler Settings" parameter="${COMMAND} ${FLAGS} -E -P -v -dD &quot;${INPUTS}&quot;" prefer-non-shared="true">
<language-scope id="org.eclipse.cdt.core.gcc"/>
<language-scope id="org.eclipse.cdt.core.g++"/>
</provider>
@@ -27,7 +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="698946535669195332" id="org.eclipse.cdt.build.crossgcc.CrossGCCBuiltinSpecsDetector" keep-relative-paths="false" name="CDT Cross GCC Built-in Compiler Settings" parameter="${COMMAND} ${FLAGS} -E -P -v -dD &quot;${INPUTS}&quot;" prefer-non-shared="true">
+ <provider class="org.eclipse.cdt.internal.build.crossgcc.CrossGCCBuiltinSpecsDetector" console="false" env-hash="-114279925955362495" id="org.eclipse.cdt.build.crossgcc.CrossGCCBuiltinSpecsDetector" keep-relative-paths="false" name="CDT Cross GCC Built-in Compiler Settings" parameter="${COMMAND} ${FLAGS} -E -P -v -dD &quot;${INPUTS}&quot;" prefer-non-shared="true">
<language-scope id="org.eclipse.cdt.core.gcc"/>
<language-scope id="org.eclipse.cdt.core.g++"/>
</provider>
@@ -38,29 +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="698946535669195332" id="org.eclipse.cdt.build.crossgcc.CrossGCCBuiltinSpecsDetector" keep-relative-paths="false" name="CDT Cross GCC Built-in Compiler Settings" parameter="${COMMAND} ${FLAGS} -E -P -v -dD &quot;${INPUTS}&quot;" prefer-non-shared="true">
- <language-scope id="org.eclipse.cdt.core.gcc"/>
- <language-scope id="org.eclipse.cdt.core.g++"/>
- </provider>
- </extension>
- </configuration>
- <configuration id="cdt.managedbuild.config.gnu.cross.exe.release.516195201.976458850.241502451.1275216290.1979117592" name="DuetM">
- <extension point="org.eclipse.cdt.core.LanguageSettingsProvider">
- <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="698946535669195332" id="org.eclipse.cdt.build.crossgcc.CrossGCCBuiltinSpecsDetector" keep-relative-paths="false" name="CDT Cross GCC Built-in Compiler Settings" parameter="${COMMAND} ${FLAGS} -E -P -v -dD &quot;${INPUTS}&quot;" prefer-non-shared="true">
- <language-scope id="org.eclipse.cdt.core.gcc"/>
- <language-scope id="org.eclipse.cdt.core.g++"/>
- </provider>
- </extension>
- </configuration>
- <configuration id="cdt.managedbuild.config.gnu.cross.exe.release.516195201.976458850.241502451.1275216290.274082366.1645191116" name="SAME70">
- <extension point="org.eclipse.cdt.core.LanguageSettingsProvider">
- <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="698946535669195332" id="org.eclipse.cdt.build.crossgcc.CrossGCCBuiltinSpecsDetector" keep-relative-paths="false" name="CDT Cross GCC Built-in Compiler Settings" parameter="${COMMAND} ${FLAGS} -E -P -v -dD &quot;${INPUTS}&quot;" prefer-non-shared="true">
+ <provider class="org.eclipse.cdt.internal.build.crossgcc.CrossGCCBuiltinSpecsDetector" console="false" env-hash="-114279925955362495" id="org.eclipse.cdt.build.crossgcc.CrossGCCBuiltinSpecsDetector" keep-relative-paths="false" name="CDT Cross GCC Built-in Compiler Settings" parameter="${COMMAND} ${FLAGS} -E -P -v -dD &quot;${INPUTS}&quot;" prefer-non-shared="true">
<language-scope id="org.eclipse.cdt.core.gcc"/>
<language-scope id="org.eclipse.cdt.core.g++"/>
</provider>
@@ -71,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="698946535669195332" id="org.eclipse.cdt.build.crossgcc.CrossGCCBuiltinSpecsDetector" keep-relative-paths="false" name="CDT Cross GCC Built-in Compiler Settings" parameter="${COMMAND} ${FLAGS} -E -P -v -dD &quot;${INPUTS}&quot;" prefer-non-shared="true">
+ <provider class="org.eclipse.cdt.internal.build.crossgcc.CrossGCCBuiltinSpecsDetector" console="false" env-hash="-114279925955362495" id="org.eclipse.cdt.build.crossgcc.CrossGCCBuiltinSpecsDetector" keep-relative-paths="false" name="CDT Cross GCC Built-in Compiler Settings" parameter="${COMMAND} ${FLAGS} -E -P -v -dD &quot;${INPUTS}&quot;" prefer-non-shared="true">
<language-scope id="org.eclipse.cdt.core.gcc"/>
<language-scope id="org.eclipse.cdt.core.g++"/>
</provider>
@@ -82,18 +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="698946535669195332" id="org.eclipse.cdt.build.crossgcc.CrossGCCBuiltinSpecsDetector" keep-relative-paths="false" name="CDT Cross GCC Built-in Compiler Settings" parameter="${COMMAND} ${FLAGS} -E -P -v -dD &quot;${INPUTS}&quot;" prefer-non-shared="true">
- <language-scope id="org.eclipse.cdt.core.gcc"/>
- <language-scope id="org.eclipse.cdt.core.g++"/>
- </provider>
- </extension>
- </configuration>
- <configuration id="cdt.managedbuild.config.gnu.cross.exe.release.516195201.976458850.241502451.1275216290.1979117592.1786125202" name="DuetM_RTOS">
- <extension point="org.eclipse.cdt.core.LanguageSettingsProvider">
- <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="698946535669195332" id="org.eclipse.cdt.build.crossgcc.CrossGCCBuiltinSpecsDetector" keep-relative-paths="false" name="CDT Cross GCC Built-in Compiler Settings" parameter="${COMMAND} ${FLAGS} -E -P -v -dD &quot;${INPUTS}&quot;" prefer-non-shared="true">
+ <provider class="org.eclipse.cdt.internal.build.crossgcc.CrossGCCBuiltinSpecsDetector" console="false" env-hash="-114279925955362495" id="org.eclipse.cdt.build.crossgcc.CrossGCCBuiltinSpecsDetector" keep-relative-paths="false" name="CDT Cross GCC Built-in Compiler Settings" parameter="${COMMAND} ${FLAGS} -E -P -v -dD &quot;${INPUTS}&quot;" prefer-non-shared="true">
<language-scope id="org.eclipse.cdt.core.gcc"/>
<language-scope id="org.eclipse.cdt.core.g++"/>
</provider>
@@ -104,7 +60,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="1552834014228" id="org.eclipse.cdt.build.crossgcc.CrossGCCBuiltinSpecsDetector" keep-relative-paths="false" name="CDT Cross GCC Built-in Compiler Settings" parameter="${COMMAND} ${FLAGS} -E -P -v -dD &quot;${INPUTS}&quot;" prefer-non-shared="true">
+ <provider class="org.eclipse.cdt.internal.build.crossgcc.CrossGCCBuiltinSpecsDetector" console="false" env-hash="-114279925955362495" id="org.eclipse.cdt.build.crossgcc.CrossGCCBuiltinSpecsDetector" keep-relative-paths="false" name="CDT Cross GCC Built-in Compiler Settings" parameter="${COMMAND} ${FLAGS} -E -P -v -dD &quot;${INPUTS}&quot;" prefer-non-shared="true">
<language-scope id="org.eclipse.cdt.core.gcc"/>
<language-scope id="org.eclipse.cdt.core.g++"/>
</provider>
diff --git a/src/BugList.txt b/src/BugList.txt
index 176d30b1..41a4892b 100644
--- a/src/BugList.txt
+++ b/src/BugList.txt
@@ -153,7 +153,7 @@ Fixes in RC4:
- [done, test] BUG extruder and additional axes don't work when doing G2/G3 moves
- [done, ok] Configuring a chamber heater on H7 with no DueX5 present causes a crash
-Fixes post RC4:
+Fixes in RC5:
- [done, ok] Connecting Internet Explorer crashes Duet due to trailing '?'
- [done] spurious stall warnings when simulating
- [done, test] Print monitor didn't think the print had started until a nozzle had reached target temperature
@@ -162,6 +162,26 @@ Fixes post RC4:
- [done] Extra axes were ignored in G2/G3 moves
- [done] DWC and the Duet could deadlock if the Duet ran out of output buffers
+Fixes post RC5:
+- [done] M569 report includes chopper configuration register for smart drivers
+- [done] If getting file info timed out it didn't close the file
+- [done] DHT sensor task was running out of stack space
+- [done] Correct bus conflict in DHT sensor code
+- [done] Fixed unreliable DHT sensor reading in RTOS build, caused by call to micros()
+- [done] Multiple DHT sensor support
+- [done] Support DHT sensor on Duet Maestro
+- [done] Pausing between the segments of a segmented move didn't happen even if the jerk settings were high enough
+- [done - need to test filament monitors!!!] If filament monitors were deleted or the type changed, this could result in an exception
+- [seems ok] Test Upload & print function, see https://forum.duet3d.com/topic/5394/new-firmware-2-0rc5-available/52
+- [done, test] When step rate limiting happens, various problems, see https://forum.duet3d.com/topic/5445/unable-to-run-128-or-256-microstepping (adjust move start time)
+- [can't reproduce] Kulitorum report that first move after a pause doesn't extrude, https://forum.duet3d.com/topic/5408/does-not-extrude-first-g1-after-a-pause/7
+- [done, test] when the SD card is removed it says 1 file was invalidated even if it was more
+- [done, ok] When SD card is removed during a print we get lots of internal error messages, and no "print abandoned" or similar message, also the heaters stay on
+- [done] Emergency stop should turn off all spindles
+- [looks like was caused by using M502] Report that filaments no longer work
+
+- M3 R parameter so it can restore the spinder/laser after a pause (https://forum.duet3d.com/topic/5418/cnc-laser-m3-unpause-r-parameter)
+- CNC: look at G17/18/19, see https://forum.duet3d.com/topic/4669/ooznest-workbee-screw-driven
- PanelDue won't connect if VIN velow minimum for stepper motors [PanelDue firmware needs to recognise status 'O']
- Add parameter to M116 to specify acceptable temperature difference
- Laser support, see https://forum.duet3d.com/topic/4702/laser-cnc-support-in-rrf-gcode-semantics/4
diff --git a/src/Configuration.h b/src/Configuration.h
index d843126e..3a94dfd6 100644
--- a/src/Configuration.h
+++ b/src/Configuration.h
@@ -113,8 +113,8 @@ constexpr unsigned int FirstMax31855ThermocoupleChannel = 100; // Temperature se
constexpr unsigned int FirstMax31856ThermocoupleChannel = 150; // Temperature sensor channels 150... are MAX31856 thermocouples
constexpr unsigned int FirstRtdChannel = 200; // Temperature sensor channels 200... are RTDs
constexpr unsigned int FirstLinearAdcChannel = 300; // Temperature sensor channels 300... use an ADC that provides a linear output over a temperature range
-constexpr unsigned int DhtTemperatureChannel = 400; // Temperature sensor channel 400 for DHTxx temperature
-constexpr unsigned int DhtHumidityChannel = 401; // Temperature sensor channel 401 for DHTxx humidity
+constexpr unsigned int FirstDhtTemperatureChannel = 400; // Temperature sensor channel 400 for DHTxx temperature
+constexpr unsigned int FirstDhtHumidityChannel = 450; // Temperature sensor channel 401 for DHTxx humidity
constexpr unsigned int FirstPT1000Channel = 500; // Temperature sensor channels 500... are PT1000 sensors connected to thermistor inputs
constexpr unsigned int CpuTemperatureSenseChannel = 1000; // Sensor 1000 is the MCJU's own temperature sensor
constexpr unsigned int FirstTmcDriversSenseChannel = 1001; // Sensors 1001..1002 are the TMC2660 driver temperature sense
diff --git a/src/DuetM/Pins_DuetM.h b/src/DuetM/Pins_DuetM.h
index 23c7dec0..50cf453a 100644
--- a/src/DuetM/Pins_DuetM.h
+++ b/src/DuetM/Pins_DuetM.h
@@ -32,7 +32,7 @@ constexpr size_t NumFirmwareUpdateModules = 1; // 1 module
#define SUPPORT_ROLAND 0 // set nonzero to support Roland mill
#define SUPPORT_SCANNER 0 // set zero to disable support for FreeLSS scanners
#define SUPPORT_IOBITS 0 // set to support P parameter in G0/G1 commands
-#define SUPPORT_DHT_SENSOR 0 // set nonzero to support DHT temperature/humidity sensors
+#define SUPPORT_DHT_SENSOR 1 // set nonzero to support DHT temperature/humidity sensors (requires RTOS)
#define SUPPORT_WORKPLACE_COORDINATES 1 // set nonzero to support G10 L2 and G53..59
#define SUPPORT_12864_LCD 1 // set nonzero to support 12864 LCD and rotary encoder
diff --git a/src/DuetNG/Pins_DuetNG.h b/src/DuetNG/Pins_DuetNG.h
index 22454a40..53624560 100644
--- a/src/DuetNG/Pins_DuetNG.h
+++ b/src/DuetNG/Pins_DuetNG.h
@@ -112,9 +112,6 @@ constexpr Pin SpiTempSensorCsPins[MaxSpiTempSensors] = { 28, 50, 51, 52, 24, 97,
#endif
-// DHTxx data pin
-constexpr Pin DhtDataPin = 97; // Pin CS6
-
// Pin that controls the ATX power on/off
constexpr Pin ATX_POWER_PIN = 79;
diff --git a/src/DuetNG/TMC2660.cpp b/src/DuetNG/TMC2660.cpp
index 6939578c..c601fcf0 100644
--- a/src/DuetNG/TMC2660.cpp
+++ b/src/DuetNG/TMC2660.cpp
@@ -421,7 +421,7 @@ void TmcDriverState::SetStallDetectFilter(bool sgFilter)
void TmcDriverState::SetStallMinimumStepsPerSecond(unsigned int stepsPerSecond)
{
- maxStallStepInterval = DDA::stepClockRate/max<unsigned int>(stepsPerSecond, 1);
+ maxStallStepInterval = StepClockRate/max<unsigned int>(stepsPerSecond, 1);
}
void TmcDriverState::SetCoolStep(uint16_t coolStepConfig)
@@ -439,7 +439,7 @@ void TmcDriverState::AppendStallConfig(const StringRef& reply) const
threshold -= 128;
}
reply.catf("stall threshold %d, filter %s, steps/sec %" PRIu32 ", coolstep %" PRIx32,
- threshold, ((filtered) ? "on" : "off"), DDA::stepClockRate/maxStallStepInterval, registers[SmartEnable] & 0xFFFF);
+ threshold, ((filtered) ? "on" : "off"), StepClockRate/maxStallStepInterval, registers[SmartEnable] & 0xFFFF);
}
// Append the driver status to a string, and reset the min/max load values
diff --git a/src/FilamentMonitors/Duet3DFilamentMonitor.cpp b/src/FilamentMonitors/Duet3DFilamentMonitor.cpp
index e517b2b7..9b108bad 100644
--- a/src/FilamentMonitors/Duet3DFilamentMonitor.cpp
+++ b/src/FilamentMonitors/Duet3DFilamentMonitor.cpp
@@ -8,7 +8,7 @@
#include "Duet3DFilamentMonitor.h"
#include "GCodes/GCodeBuffer.h"
#include "Platform.h"
-#include "Movement/DDA.h" // for stepClockRate
+#include "RepRap.h"
// Constructors
Duet3DFilamentMonitor::Duet3DFilamentMonitor(unsigned int extruder, int type)
@@ -63,7 +63,7 @@ Duet3DFilamentMonitor::PollResult Duet3DFilamentMonitor::PollReceiveBuffer(uint1
{
// For the Duet3D sensors we need to decode the received data from the transition times recorded in the edgeCaptures array
static constexpr uint32_t BitsPerSecond = 1000; // the nominal bit rate that the data is transmitted at
- static constexpr uint32_t NominalBitLength = DDA::stepClockRate/BitsPerSecond; // the nominal bit length in step clocks
+ static constexpr uint32_t NominalBitLength = StepClockRate/BitsPerSecond; // the nominal bit length in step clocks
static constexpr uint32_t MinBitLength = (NominalBitLength * 10)/13; // allow 30% clock speed tolerance
static constexpr uint32_t MaxBitLength = (NominalBitLength * 13)/10; // allow 30% clock speed tolerance
static constexpr uint32_t ErrorRecoveryDelayBits = 8; // before a start bit we want the line to be low for this long
diff --git a/src/FilamentMonitors/FilamentMonitor.cpp b/src/FilamentMonitors/FilamentMonitor.cpp
index 64458396..4c5254c2 100644
--- a/src/FilamentMonitors/FilamentMonitor.cpp
+++ b/src/FilamentMonitors/FilamentMonitor.cpp
@@ -17,14 +17,21 @@
#include "PrintMonitor.h"
// Static data
+Mutex FilamentMonitor::filamentSensorsMutex;
FilamentMonitor *FilamentMonitor::filamentSensors[MaxExtruders] = { 0 };
// Default destructor
FilamentMonitor::~FilamentMonitor()
{
+}
+
+// Call this to disable the interrupt before deleting or re-configuring a filament monitor
+void FilamentMonitor::Disable()
+{
if (pin != NoPin)
{
detachInterrupt(pin);
+ pin = NoPin;
}
}
@@ -61,6 +68,59 @@ bool FilamentMonitor::ConfigurePin(GCodeBuffer& gb, const StringRef& reply, Inte
return false;
}
+// Static initialisation
+/*static*/ void FilamentMonitor::InitStatic()
+{
+ filamentSensorsMutex.Create();
+}
+
+// Handle M591
+/*static*/ GCodeResult FilamentMonitor::Configure(GCodeBuffer& gb, const StringRef& reply, unsigned int extruder)
+{
+
+ bool seen = false;
+ long newSensorType;
+ gb.TryGetIValue('P', newSensorType, seen);
+
+ MutexLocker lock(filamentSensorsMutex);
+ FilamentMonitor*& sensor = filamentSensors[extruder];
+
+ if (seen)
+ {
+ // We are setting the filament monitor type, so see if it has changed
+ if (sensor != nullptr && newSensorType != sensor->GetType())
+ {
+ // We already have a sensor of a different type, so delete the old sensor
+ sensor->Disable();
+ delete sensor;
+ sensor = nullptr;
+ }
+
+ if (sensor == nullptr)
+ {
+ sensor = Create(extruder, newSensorType); // create the new sensor type, if any
+ }
+ }
+
+ if (sensor != nullptr)
+ {
+ // Configure the sensor
+ const bool error = sensor->Configure(gb, reply, seen);
+ if (error)
+ {
+ sensor->Disable();
+ delete sensor;
+ sensor = nullptr;
+ }
+ return GetGCodeResultFromError(error);
+ }
+ else if (!seen)
+ {
+ reply.printf("Extruder drive %u has no filament sensor", extruder);
+ }
+ return GCodeResult::ok;
+}
+
// Factory function
/*static*/ FilamentMonitor *FilamentMonitor::Create(unsigned int extruder, int type)
{
@@ -115,6 +175,8 @@ bool FilamentMonitor::ConfigurePin(GCodeBuffer& gb, const StringRef& reply, Inte
/*static*/ void FilamentMonitor::Spin(bool full)
{
+ MutexLocker lock(filamentSensorsMutex);
+
// Filament sensors
for (size_t extruder = 0; extruder < MaxExtruders; ++extruder)
{
@@ -164,30 +226,6 @@ bool FilamentMonitor::ConfigurePin(GCodeBuffer& gb, const StringRef& reply, Inte
}
}
-// Return the filament sensor associated with a particular extruder
-/*static*/ FilamentMonitor *FilamentMonitor::GetFilamentSensor(unsigned int extruder)
-{
- return (extruder < MaxExtruders) ? filamentSensors[extruder] : nullptr;
-}
-
-// Set the filament sensor associated with a particular extruder
-/*static*/ bool FilamentMonitor::SetFilamentSensorType(unsigned int extruder, int newSensorType)
-{
- if (extruder < MaxExtruders)
- {
- FilamentMonitor*& sensor = filamentSensors[extruder];
- const int oldSensorType = (sensor == nullptr) ? 0 : sensor->GetType();
- if (newSensorType != oldSensorType)
- {
- delete sensor;
- sensor = Create(extruder, newSensorType);
- return true;
- }
- }
-
- return false;
-}
-
// Send diagnostics info
/*static*/ void FilamentMonitor::Diagnostics(MessageType mtype)
{
diff --git a/src/FilamentMonitors/FilamentMonitor.h b/src/FilamentMonitors/FilamentMonitor.h
index 1fa4416f..1768460b 100644
--- a/src/FilamentMonitors/FilamentMonitor.h
+++ b/src/FilamentMonitors/FilamentMonitor.h
@@ -10,6 +10,8 @@
#include "RepRapFirmware.h"
#include "MessageType.h"
+#include "GCodes/GCodeResult.h"
+#include "RTOSIface.h"
enum class FilamentSensorStatus : uint8_t
{
@@ -39,23 +41,27 @@ public:
// ISR for when the pin state changes. It should return true if the ISR wants the commanded extrusion to be fetched.
virtual bool Interrupt() = 0;
+ // Call this to disable the interrupt before deleting a filament monitor
+ virtual void Disable();
+
// Override the virtual destructor if your derived class allocates any dynamic memory
virtual ~FilamentMonitor();
// Return the type of this sensor
int GetType() const { return type; }
+ // Static initialisation
+ static void InitStatic();
+
// Return an error message corresponding to a status code
static const char *GetErrorMessage(FilamentSensorStatus f);
// Poll the filament sensors
static void Spin(bool full);
- // Return the filament sensor associated with a particular extruder
- static FilamentMonitor *GetFilamentSensor(unsigned int extruder);
-
- // Set the filament sensor associated with a particular extruder
- static bool SetFilamentSensorType(unsigned int extruder, int newSensorType);
+ // Handle M591
+ static GCodeResult Configure(GCodeBuffer& gb, const StringRef& reply, unsigned int extruder)
+ pre(extruder < MaxExtruders);
// Send diagnostics info
static void Diagnostics(MessageType mtype);
@@ -75,6 +81,7 @@ private:
static void InterruptEntry(CallbackParameter param);
+ static Mutex filamentSensorsMutex;
static FilamentMonitor *filamentSensors[MaxExtruders];
int32_t isrExtruderStepsCommanded;
diff --git a/src/FilamentMonitors/SimpleFilamentMonitor.cpp b/src/FilamentMonitors/SimpleFilamentMonitor.cpp
index 5956fa71..7b0f1b57 100644
--- a/src/FilamentMonitors/SimpleFilamentMonitor.cpp
+++ b/src/FilamentMonitors/SimpleFilamentMonitor.cpp
@@ -8,9 +8,10 @@
#include "SimpleFilamentMonitor.h"
#include "RepRap.h"
#include "Platform.h"
+#include "GCodes/GCodeBuffer.h"
SimpleFilamentMonitor::SimpleFilamentMonitor(unsigned int extruder, int type)
- : FilamentMonitor(extruder, type), highWhenNoFilament(type == 2), filamentPresent(false)
+ : FilamentMonitor(extruder, type), highWhenNoFilament(type == 2), filamentPresent(false), enabled(false)
{
}
@@ -22,13 +23,20 @@ bool SimpleFilamentMonitor::Configure(GCodeBuffer& gb, const StringRef& reply, b
return true;
}
+ if (gb.Seen('S'))
+ {
+ seen = true;
+ enabled = (gb.GetIValue() > 0);
+ }
+
if (seen)
{
Check(true, false, false, 0.0);
}
else
{
- reply.printf("Simple filament sensor on endstop %d, output %s when no filament", GetEndstopNumber(), (highWhenNoFilament) ? "high" : "low");
+ reply.printf("Simple filament sensor on endstop %d, %s, output %s when no filament",
+ GetEndstopNumber(), (enabled) ? "enabled" : "disabled", (highWhenNoFilament) ? "high" : "low");
}
return false;
@@ -54,14 +62,14 @@ void SimpleFilamentMonitor::Poll()
FilamentSensorStatus SimpleFilamentMonitor::Check(bool full, bool hadNonPrintingMove, bool fromIsr, float filamentConsumed)
{
Poll();
- return (filamentPresent) ? FilamentSensorStatus::ok : FilamentSensorStatus::noFilament;
+ return (!enabled || filamentPresent) ? FilamentSensorStatus::ok : FilamentSensorStatus::noFilament;
}
// Clear the measurement state - called when we are not printing a file. Return the present/not present status if available.
FilamentSensorStatus SimpleFilamentMonitor::Clear(bool full)
{
Poll();
- return (filamentPresent) ? FilamentSensorStatus::ok : FilamentSensorStatus::noFilament;
+ return (!enabled || filamentPresent) ? FilamentSensorStatus::ok : FilamentSensorStatus::noFilament;
}
// Print diagnostic info for this sensor
diff --git a/src/FilamentMonitors/SimpleFilamentMonitor.h b/src/FilamentMonitors/SimpleFilamentMonitor.h
index 25593b2b..e07f53ba 100644
--- a/src/FilamentMonitors/SimpleFilamentMonitor.h
+++ b/src/FilamentMonitors/SimpleFilamentMonitor.h
@@ -26,6 +26,7 @@ private:
bool highWhenNoFilament;
bool filamentPresent;
+ bool enabled;
};
#endif /* SRC_FILAMENTSENSORS_SIMPLEFILAMENTMONITOR_H_ */
diff --git a/src/GCodes/GCodeInput.cpp b/src/GCodes/GCodeInput.cpp
index 935143a5..35371c26 100644
--- a/src/GCodes/GCodeInput.cpp
+++ b/src/GCodes/GCodeInput.cpp
@@ -60,7 +60,6 @@ size_t StreamGCodeInput::BytesCached() const
return device.available();
}
-
// Dynamic G-code input class for caching codes from software-defined sources
RegularGCodeInput::RegularGCodeInput()
@@ -189,15 +188,13 @@ void NetworkGCodeInput::Put(MessageType mtype, const char *buf)
MutexLocker lock(bufMutex, 200);
if (lock)
{
- if (len > BufferSpaceLeft())
+ // Only cache this if we have enough space left
+ if (len <= BufferSpaceLeft())
{
- // Don't cache this if we don't have enough space left
- return;
- }
-
- for (size_t i = 0; i < len; i++)
- {
- Put(mtype, buf[i]);
+ for (size_t i = 0; i < len; i++)
+ {
+ Put(mtype, buf[i]);
+ }
}
}
}
@@ -233,7 +230,7 @@ void FileGCodeInput::Reset(const FileData &file)
}
// Read another chunk of G-codes from the file and return true if more data is available
-bool FileGCodeInput::ReadFromFile(FileData &file)
+GCodeInputReadResult FileGCodeInput::ReadFromFile(FileData &file)
{
const size_t bytesCached = BytesCached();
@@ -264,14 +261,18 @@ bool FileGCodeInput::ReadFromFile(FileData &file)
// However, unless we can use a buffer of at least 512 bytes then that is redundant,
// because the data will be copied via the sector buffer in FatFS anyway. So we don't do that any more.
const int bytesRead = file.Read(buffer + writingPointer, min<size_t>(BufferSpaceLeft(), GCodeInputBufferSize - writingPointer));
+ if (bytesRead < 0)
+ {
+ return GCodeInputReadResult::error;
+ }
if (bytesRead > 0)
{
writingPointer = (writingPointer + (size_t)bytesRead) % GCodeInputBufferSize;
- return true;
+ return GCodeInputReadResult::haveData;
}
}
- return bytesCached > 0;
+ return (bytesCached > 0) ? GCodeInputReadResult::haveData : GCodeInputReadResult::noData;
}
// End
diff --git a/src/GCodes/GCodeInput.h b/src/GCodes/GCodeInput.h
index 861ccc93..ae7ae31c 100644
--- a/src/GCodes/GCodeInput.h
+++ b/src/GCodes/GCodeInput.h
@@ -83,17 +83,20 @@ protected:
char buffer[GCodeInputBufferSize];
};
+enum class GCodeInputReadResult : uint8_t { haveData, noData, error };
+
// This class is an expansion of the RegularGCodeInput class to buffer G-codes and to rewind file positions when
// nested G-code files are started. However buffered codes are not explicitly checked for M112.
class FileGCodeInput : public RegularGCodeInput
{
public:
+
FileGCodeInput() : RegularGCodeInput(), lastFile(nullptr) { }
void Reset() override; // This should be called when the associated file is being closed
void Reset(const FileData &file); // Should be called when a specific G-code or macro file is closed or re-opened outside the reading context
- bool ReadFromFile(FileData &file); // Read another chunk of G-codes from the file and return true if more data is available
+ GCodeInputReadResult ReadFromFile(FileData &file); // Read another chunk of G-codes from the file and return true if more data is available
private:
FileStore *lastFile;
diff --git a/src/GCodes/GCodes.cpp b/src/GCodes/GCodes.cpp
index a5790586..44bc3075 100644
--- a/src/GCodes/GCodes.cpp
+++ b/src/GCodes/GCodes.cpp
@@ -1416,16 +1416,21 @@ void GCodes::DoFilePrint(GCodeBuffer& gb, const StringRef& reply)
FileData& fd = gb.MachineState().fileState;
// Do we have more data to process?
- if (fileInput->ReadFromFile(fd))
+ switch (fileInput->ReadFromFile(fd))
{
+ case GCodeInputReadResult::haveData:
// Yes - fill up the GCodeBuffer and run the next code
if (fileInput->FillBuffer(&gb))
{
gb.SetFinished(ActOnCode(gb, reply));
}
- }
- else
- {
+ break;
+
+ case GCodeInputReadResult::error:
+ AbortPrint(gb);
+ break;
+
+ case GCodeInputReadResult::noData:
// We have reached the end of the file. Check for the last line of gcode not ending in newline.
if (!gb.StartingNewCode()) // if there is something in the buffer
{
@@ -1474,6 +1479,7 @@ void GCodes::DoFilePrint(GCodeBuffer& gb, const StringRef& reply)
}
}
}
+ break;
}
}
@@ -1599,20 +1605,22 @@ void GCodes::DoPause(GCodeBuffer& gb, PauseReason reason, const char *msg)
ToolOffsetInverseTransform(pauseRestorePoint.moveCoords, currentUserPosition); // transform the returned coordinates to user coordinates
ClearMove();
}
- else if (segmentsLeft != 0 && moveBuffer.canPauseBefore)
+ else if (segmentsLeft != 0)
{
// We were not able to skip any moves, however we can skip the move that is waiting
pauseRestorePoint.virtualExtruderPosition = moveBuffer.virtualExtruderPosition;
pauseRestorePoint.filePos = moveBuffer.filePos;
pauseRestorePoint.feedRate = moveBuffer.feedRate;
+ pauseRestorePoint.proportionDone = (float)(totalSegments - segmentsLeft)/(float)totalSegments;
ToolOffsetInverseTransform(pauseRestorePoint.moveCoords, currentUserPosition); // transform the returned coordinates to user coordinates
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
+ // We were not able to skip any moves, and there is no move waiting
pauseRestorePoint.feedRate = fileGCode->MachineState().feedRate;
pauseRestorePoint.virtualExtruderPosition = virtualExtruderPosition;
+ pauseRestorePoint.proportionDone = 0.0;
// TODO: when using 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
@@ -2423,6 +2431,7 @@ const char* GCodes::DoStraightMove(GCodeBuffer& gb, bool isCoordinated)
doingArcMove = false;
FinaliseMove(gb);
+ UnlockAll(gb); // allow pause
return nullptr;
}
@@ -2590,16 +2599,16 @@ const char* GCodes::DoArcMove(GCodeBuffer& gb, bool clockwise)
doingArcMove = true;
FinaliseMove(gb);
+ UnlockAll(gb); // allow pause
// debugPrintf("Radius %.2f, initial angle %.1f, increment %.1f, segments %u\n",
// arcRadius, arcCurrentAngle * RadiansToDegrees, arcAngleIncrement * RadiansToDegrees, segmentsLeft);
return nullptr;
}
-// Adjust the move parameters to account for segmentation and/or part of the move having been done already
+// Adjust the move parameters to account for segmentation and/or part of the move having been done already
void GCodes::FinaliseMove(GCodeBuffer& gb)
{
moveBuffer.canPauseAfter = (moveBuffer.endStopsToCheck == 0);
- moveBuffer.canPauseBefore = true;
moveBuffer.filePos = (&gb == fileGCode) ? gb.GetFilePosition(fileInput->BytesCached()) : noFilePosition;
moveBuffer.virtualExtruderPosition = virtualExtruderPosition;
@@ -2734,7 +2743,7 @@ void GCodes::ClearMove()
// Cancel any macro or print in progress
void GCodes::AbortPrint(GCodeBuffer& gb)
{
- gb.AbortFile(fileInput); // stop executing any files or macros that this GCodeBuffer is running
+ (void)gb.AbortFile(fileInput); // stop executing any files or macros that this GCodeBuffer is running
if (&gb == fileGCode) // if the current command came from a file being printed
{
StopPrint(StopPrintReason::abort);
@@ -4153,7 +4162,7 @@ GCodeResult GCodes::LoadFilament(GCodeBuffer& gb, const StringRef& reply)
// Unload the current filament from a tool
GCodeResult GCodes::UnloadFilament(GCodeBuffer& gb, const StringRef& reply)
{
- Tool *tool = reprap.GetCurrentTool();
+ Tool * const tool = reprap.GetCurrentTool();
if (tool == nullptr)
{
reply.copy("No tool selected");
diff --git a/src/GCodes/GCodes.h b/src/GCodes/GCodes.h
index 58cb449f..29190528 100644
--- a/src/GCodes/GCodes.h
+++ b/src/GCodes/GCodes.h
@@ -125,7 +125,6 @@ public:
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
- uint8_t canPauseBefore : 1; // true if we can pause before this move
uint8_t canPauseAfter : 1; // true if we can pause just after this move and successfully restart
uint8_t hasExtrusion : 1; // true if the move includes extrusion - only valid if the move was set up by SetupMove
uint8_t isCoordinated : 1; // true if this is a coordinates move
diff --git a/src/GCodes/GCodes2.cpp b/src/GCodes/GCodes2.cpp
index 616cb4b6..7d8d78e4 100644
--- a/src/GCodes/GCodes2.cpp
+++ b/src/GCodes/GCodes2.cpp
@@ -3168,18 +3168,17 @@ bool GCodes::HandleMcode(GCodeBuffer& gb, const StringRef& reply)
{
float timings[4];
platform.GetDriverStepTiming(drive, timings);
- reply.printf("Drive %u runs %s, active %s enable,"
-#if HAS_SMART_DRIVERS
- " mode %s,"
-#endif
- " step timing %.1f,%.1f,%.1f,%.1f microseconds",
+ reply.printf("Drive %u runs %s, active %s enable, step timing %.1f:%.1f:%.1f:%.1f us",
drive,
(platform.GetDirectionValue(drive)) ? "forwards" : "in reverse",
(platform.GetEnableValue(drive)) ? "high" : "low",
+ (double)timings[0], (double)timings[1], (double)timings[2], (double)timings[3]);
#if HAS_SMART_DRIVERS
- TranslateDriverMode(SmartDrivers::GetDriverMode(drive)),
+ if (drive < platform.GetNumSmartDrivers())
+ {
+ reply.catf(", mode %s, ccr 0x%05" PRIx32, TranslateDriverMode(SmartDrivers::GetDriverMode(drive)), SmartDrivers::GetChopperControlRegister(drive));
+ }
#endif
- (double)timings[0], (double)timings[1], (double)timings[2], (double)timings[3]);
}
}
}
@@ -3562,29 +3561,7 @@ bool GCodes::HandleMcode(GCodeBuffer& gb, const StringRef& reply)
const unsigned int extruder = gb.GetUIValue();
if (extruder < numExtruders)
{
- bool seen = false;
- long sensorType;
- gb.TryGetIValue('P', sensorType, seen);
- if (seen)
- {
- FilamentMonitor::SetFilamentSensorType(extruder, sensorType);
- }
-
- FilamentMonitor *sensor = FilamentMonitor::GetFilamentSensor(extruder);
- if (sensor != nullptr)
- {
- // Configure the sensor
- const bool error = sensor->Configure(gb, reply, seen);
- result = GetGCodeResultFromError(error);
- if (error)
- {
- FilamentMonitor::SetFilamentSensorType(extruder, 0); // delete the sensor
- }
- }
- else if (!seen)
- {
- reply.printf("Extruder drive %u has no filament sensor", extruder);
- }
+ result = FilamentMonitor::Configure(gb, reply, extruder);
}
}
break;
diff --git a/src/GCodes/GCodes3.cpp b/src/GCodes/GCodes3.cpp
index 7ed2812a..05cd8948 100644
--- a/src/GCodes/GCodes3.cpp
+++ b/src/GCodes/GCodes3.cpp
@@ -757,7 +757,6 @@ GCodeResult GCodes::ProbeTool(GCodeBuffer& gb, const StringRef& reply)
moveBuffer.usePressureAdvance = false;
moveBuffer.filePos = noFilePosition;
moveBuffer.canPauseAfter = false;
- moveBuffer.canPauseBefore = true;
// Decide which way and how far to go
if (gb.Seen('R'))
diff --git a/src/Heating/Heat.cpp b/src/Heating/Heat.cpp
index 4227f0d0..d56fbb83 100644
--- a/src/Heating/Heat.cpp
+++ b/src/Heating/Heat.cpp
@@ -139,7 +139,7 @@ void Heat::Init()
#if SUPPORT_DHT_SENSOR
// Initialise static fields of the DHT sensor
- DhtSensor::InitStatic();
+ DhtSensorHardwareInterface::InitStatic();
#endif
coldExtrude = false;
diff --git a/src/Heating/Sensors/DhtSensor.cpp b/src/Heating/Sensors/DhtSensor.cpp
index 1b1dad8f..016723af 100644
--- a/src/Heating/Sensors/DhtSensor.cpp
+++ b/src/Heating/Sensors/DhtSensor.cpp
@@ -12,101 +12,104 @@
#if SUPPORT_DHT_SENSOR
-const uint32_t MinimumReadInterval = 2000; // ms
-const uint32_t MaximumReadTime = 50; // ms
+constexpr uint32_t MinimumReadInterval = 2000; // ms
+constexpr uint32_t MaximumReadTime = 20; // ms
+constexpr uint32_t MinimumOneBitLength = 50; // microseconds
+constexpr uint32_t MinimumOneBitStepClocks = (StepClockRate * MinimumOneBitLength)/1000000;
+# include "Tasks.h"
-# ifdef RTOS
-
-# include "Tasks.h"
-
-constexpr uint32_t DhtTaskStackWords = 80; // task stack size in dwords
-static Task<DhtTaskStackWords> *dhtTask;
+// Static data members of class DhtSensorHardwareInterface
+Mutex DhtSensorHardwareInterface::dhtMutex;
+Task<DhtSensorHardwareInterface::DhtTaskStackWords> *DhtSensorHardwareInterface::dhtTask = nullptr;
+DhtSensorHardwareInterface *DhtSensorHardwareInterface::activeSensors[MaxSpiTempSensors] = { 0 };
extern "C" void DhtTask(void * pvParameters)
{
- DhtSensor::SensorTask();
+ DhtSensorHardwareInterface::SensorTask();
}
-# else
-
-uint32_t DhtSensor::lastReadTime = 0;
-DhtSensor::SensorState DhtSensor::state = Initialising;
-uint32_t DhtSensor::lastOperationTime = 0;
-
-# endif
-
-size_t DhtSensor::numInstances = 0;
-DhtSensorType DhtSensor::type = DhtSensorType::Dht11;
-TemperatureError DhtSensor::lastResult = TemperatureError::notInitialised;
-float DhtSensor::lastTemperature = BAD_ERROR_TEMPERATURE;
-float DhtSensor::lastHumidity = BAD_ERROR_TEMPERATURE;
-size_t DhtSensor::badTemperatureCount = 0;
-
-Mutex DhtSensor::dhtMutex;
+// Pulse ISR
+extern "C" void DhtDataTransition(CallbackParameter cp)
+{
+ static_cast<DhtSensorHardwareInterface*>(cp.vp)->Interrupt();
+}
+DhtSensorHardwareInterface::DhtSensorHardwareInterface(Pin p_pin)
+ : sensorPin(p_pin), type(DhtSensorType::none), lastResult(TemperatureError::notInitialised),
+ lastTemperature(BAD_ERROR_TEMPERATURE), lastHumidity(BAD_ERROR_TEMPERATURE), badTemperatureCount(0)
+{
+}
-DhtSensor::DhtSensor(unsigned int channel) : TemperatureSensor(channel, "DHTxx")
+TemperatureError DhtSensorHardwareInterface::GetTemperatureOrHumidity(float& t, bool wantHumidity) const
{
- numInstances++;
+ t = (wantHumidity) ? lastHumidity : lastTemperature;
+ return lastResult;
}
-DhtSensor::~DhtSensor()
+/*static*/ GCodeResult DhtSensorHardwareInterface::Configure(TemperatureSensor *ts, unsigned int relativeChannel, unsigned int mCode, unsigned int heater, GCodeBuffer& gb, const StringRef& reply)
{
- numInstances--;
+ MutexLocker lock(dhtMutex);
+
+ if (relativeChannel >= MaxSpiTempSensors || activeSensors[relativeChannel] == nullptr)
+ {
+ reply.copy("invalid channel");
+ return GCodeResult::error;
+ }
+
+ return activeSensors[relativeChannel]->Configure(ts, mCode, heater, gb, reply);
}
-GCodeResult DhtSensor::Configure(unsigned int mCode, unsigned int heater, GCodeBuffer& gb, const StringRef& reply)
+GCodeResult DhtSensorHardwareInterface::Configure(TemperatureSensor *ts, unsigned int mCode, unsigned int heater, GCodeBuffer& gb, const StringRef& reply)
{
GCodeResult rslt = GCodeResult::ok;
if (mCode == 305)
{
bool seen = false;
- TryConfigureHeaterName(gb, seen);
+ ts->TryConfigureHeaterName(gb, seen);
if (gb.Seen('T'))
{
- MutexLocker lock(dhtMutex);
seen = true;
const int dhtType = gb.GetIValue();
switch (dhtType)
{
- case 11:
- type = DhtSensorType::Dht11;
- break;
- case 21:
- type = DhtSensorType::Dht21;
- break;
- case 22:
- type = DhtSensorType::Dht22;
- break;
- default:
- reply.copy("Invalid DHT sensor type");
- rslt = GCodeResult::error;
- break;
+ case 11:
+ type = DhtSensorType::Dht11;
+ break;
+ case 21:
+ type = DhtSensorType::Dht21;
+ break;
+ case 22:
+ type = DhtSensorType::Dht22;
+ break;
+ default:
+ reply.copy("Invalid DHT sensor type");
+ rslt = GCodeResult::error;
+ break;
}
}
if (!seen && !gb.Seen('X'))
{
- CopyBasicHeaterDetails(heater, reply);
+ ts->CopyBasicHeaterDetails(heater, reply);
const char *sensorTypeString;
switch (type)
{
- case DhtSensorType::Dht11:
- sensorTypeString = "DHT11";
- break;
- case DhtSensorType::Dht21:
- sensorTypeString = "DHT21";
- break;
- case DhtSensorType::Dht22:
- sensorTypeString = "DHT22";
- break;
- default:
- sensorTypeString = "unknown";
- break;
+ case DhtSensorType::Dht11:
+ sensorTypeString = "DHT11";
+ break;
+ case DhtSensorType::Dht21:
+ sensorTypeString = "DHT21";
+ break;
+ case DhtSensorType::Dht22:
+ sensorTypeString = "DHT22";
+ break;
+ default:
+ sensorTypeString = "unknown";
+ break;
}
reply.catf(", sensor type %s", sensorTypeString);
}
@@ -114,246 +117,185 @@ GCodeResult DhtSensor::Configure(unsigned int mCode, unsigned int heater, GCodeB
return rslt;
}
-void DhtSensor::Init()
+// Create a hardware interface object re the specified channel if there isn't already
+DhtSensorHardwareInterface *DhtSensorHardwareInterface::Create(unsigned int relativeChannel)
{
-#ifdef RTOS
+ if (relativeChannel >= MaxSpiTempSensors)
+ {
+ return nullptr;
+ }
+
+ MutexLocker lock(dhtMutex);
+
+ if (activeSensors[relativeChannel] == nullptr)
+ {
+ activeSensors[relativeChannel] = new DhtSensorHardwareInterface(SpiTempSensorCsPins[relativeChannel]);
+ }
+
if (dhtTask == nullptr)
{
dhtTask = new Task<DhtTaskStackWords>;
dhtTask->Create(DhtTask, "DHTSENSOR", nullptr, TaskBase::HeatPriority);
}
-#endif
+
+ return activeSensors[relativeChannel];
}
-/*static*/ void DhtSensor::InitStatic()
+/*static*/ void DhtSensorHardwareInterface::InitStatic()
{
dhtMutex.Create();
}
-TemperatureError DhtSensor::GetTemperature(float& t)
+/*static*/ TemperatureError DhtSensorHardwareInterface::GetTemperatureOrHumidity(unsigned int relativeChannel, float& t, bool wantHumidity)
{
- MutexLocker lock(dhtMutex);
- switch (GetSensorChannel())
+ if (relativeChannel >= MaxSpiTempSensors)
{
- case DhtTemperatureChannel:
- t = lastTemperature;
- return lastResult;
-
- case DhtHumidityChannel:
- t = lastHumidity;
- return lastResult;
-
- default:
- return TemperatureError::unknownChannel;
+ t = BAD_ERROR_TEMPERATURE;
+ return TemperatureError::unknownChannel;
}
-}
-// Pulse ISR
-uint32_t lastPulseTime;
-volatile uint8_t numPulses;
-uint32_t pulses[41]; // 1 start bit + 40 data bits
+ MutexLocker lock(dhtMutex);
-void DhtDataTransition(CallbackParameter)
-{
- const uint32_t now = micros();
- if (digitalRead(DhtDataPin) == HIGH)
- {
- lastPulseTime = now;
- }
- else if (lastPulseTime > 0)
+ if (activeSensors[relativeChannel] == nullptr)
{
- pulses[numPulses++] = now - lastPulseTime;
- if (numPulses == ARRAY_SIZE(pulses))
- {
- detachInterrupt(DhtDataPin);
- }
+ t = BAD_ERROR_TEMPERATURE;
+ return TemperatureError::notInitialised;
}
-}
-#ifdef RTOS
+ return activeSensors[relativeChannel]->GetTemperatureOrHumidity(t, wantHumidity);
+}
-/*static*/ void DhtSensor::SensorTask()
+void DhtSensorHardwareInterface::Interrupt()
{
- for (;;)
+ if (numPulses < ARRAY_SIZE(pulses))
{
- // Don't do anything if the sensor is not configured
- if (numInstances == 0)
+ const uint16_t now = Platform::GetInterruptClocks16();
+ if (digitalRead(sensorPin))
{
- RTOSIface::Yield();
- continue;
+ lastPulseTime = now;
}
-
- // Send start signal. See DHT datasheet for full signal diagram:
- // http://www.adafruit.com/datasheets/Digital%20humidity%20and%20temperature%20sensor%20AM2302.pdf
- pinMode(DhtDataPin, OUTPUT_HIGH);
- delay(250);
- digitalWrite(DhtDataPin, LOW);
- delay(20);
-
- // End the start signal by setting data line high for 40 microseconds
- digitalWrite(DhtDataPin, HIGH);
- delayMicroseconds(40);
-
- // Now start reading the data line to get the value from the DHT sensor
- pinMode(DhtDataPin, INPUT_PULLUP);
- delayMicroseconds(10);
-
- // Read from the DHT sensor using an ISR
- numPulses = 0;
- lastPulseTime = 0;
- attachInterrupt(DhtDataPin, DhtDataTransition, INTERRUPT_MODE_CHANGE, nullptr);
-
- // Wait for the incoming signal to be read by the ISR (1 start bit + 40 data bits)
- // The loop below could be replaced by a semaphore as well.
- const uint32_t readStartTime = xTaskGetTickCount();
- do
+ else if (lastPulseTime != 0)
{
- // Make sure we don't time out
- if (xTaskGetTickCount() - readStartTime > MaximumReadTime)
+ pulses[numPulses++] = now - lastPulseTime;
+#if 0
+ if (numPulses == ARRAY_SIZE(pulses))
{
- detachInterrupt(DhtDataPin);
- lastResult = TemperatureError::timeout;
- break;
- }
-
- RTOSIface::Yield();
- }
- while (numPulses != ARRAY_SIZE(pulses));
-
- // If that succeeded, attempt to convert the signal into temp+RH values
- if (numPulses == ARRAY_SIZE(pulses))
- {
- MutexLocker lock(dhtMutex);
-
- ProcessReadings();
- if (lastResult == TemperatureError::success || badTemperatureCount > MAX_BAD_TEMPERATURE_COUNT)
- {
- badTemperatureCount = 0;
- }
- else
- {
- badTemperatureCount++;
- lastResult = TemperatureError::success;
+ vTaskNotifyGiveFromISR(dhtTask->GetHandle(), nullptr); // wake up the task
}
+#endif
}
-
- // Wait a moment before starting a new measurement
- delay(MinimumReadInterval);
}
}
-#else
-
-// Keep this sensor running
-/*static*/ void DhtSensor::Spin()
+void DhtSensorHardwareInterface::TakeReading()
{
- if (numInstances == 0 || millis() - lastReadTime < MinimumReadInterval)
- {
- return;
- }
-
- switch (state)
+ if (type != DhtSensorType::none) // if sensor has been configured
{
- case Initialising:
// Send start signal. See DHT datasheet for full signal diagram:
// http://www.adafruit.com/datasheets/Digital%20humidity%20and%20temperature%20sensor%20AM2302.pdf
- pinMode(DhtDataPin, OUTPUT_HIGH);
+ pinMode(sensorPin, OUTPUT_HIGH);
+ delay(250);
- state = Starting;
- lastOperationTime = millis();
- break;
+ digitalWrite(sensorPin, LOW);
+ delay(20);
- case Starting:
- // Wait 250ms
- if (millis() - lastOperationTime >= 250)
{
- digitalWrite(DhtDataPin, LOW);
+ TaskCriticalSectionLocker lock; // make sure the Heat task doesn't interrupt the sequence
- state = Starting2;
- lastOperationTime = millis();
- }
- break;
-
- case Starting2:
- // Wait 20ms
- if (millis() - lastOperationTime >= 20)
- {
- // End the start signal by setting data line high for 40 microseconds
- digitalWrite(DhtDataPin, HIGH);
- delayMicroseconds(40);
+ // End the start signal by setting data line high. the sensor will respond with the start bit in 20 to 40us.
+ // We need only force the data line high long enough to charge the line capacitance, after that the pullup resistor keeps it high.
+ digitalWrite(sensorPin, HIGH); // this will generate an interrupt, but we will ignore it
+ delayMicroseconds(3);
// Now start reading the data line to get the value from the DHT sensor
- pinMode(DhtDataPin, INPUT_PULLUP);
- delayMicroseconds(10);
+ pinMode(sensorPin, INPUT_PULLUP);
- // Read from the DHT sensor using an ISR, because we cannot use delays
- // due to the fact that this messes with the stepping ISR
- numPulses = 0;
+ // It appears that switching the pin to an output disables the interrupt, so we need to call attachInterrupt here
+ // We are likely to get an immediate interrupt at this point corresponding to the low-to-high transition. We must ignore this.
+ numPulses = ARRAY_SIZE(pulses); // tell the ISR not to collect data yet
+ attachInterrupt(sensorPin, DhtDataTransition, INTERRUPT_MODE_CHANGE, this);
lastPulseTime = 0;
- attachInterrupt(DhtDataPin, DhtDataTransition, INTERRUPT_MODE_CHANGE, nullptr);
-
- // Wait for the next operation to complete
- lastOperationTime = millis();
- state = Reading;
+ numPulses = 0; // tell the ISR to collect data
}
- break;
- case Reading:
- // Make sure we don't time out
- if (millis() - lastOperationTime > MaximumReadTime)
+ // Wait for the incoming signal to be read by the ISR (1 start bit + 40 data bits), or until timeout.
+ // We don't have the ISR wake the process up, because that would require the priority of the pin change interrupt to be reduced.
+ // So we just delay for long enough for the data to have been sent. It takes typically 4 to 5ms.
+ delay(MaximumReadTime);
+
+ detachInterrupt(sensorPin);
+
+ // Attempt to convert the signal into temp+RH values
+ const TemperatureError rslt = ProcessReadings();
+ if (rslt == TemperatureError::success)
{
- detachInterrupt(DhtDataPin);
- state = Initialising;
- lastReadTime = millis();
- lastResult = TemperatureError::timeout;
- break;
+ lastResult = rslt;
+ badTemperatureCount = 0;
}
-
- // Wait for the reading to complete (1 start bit + 40 data bits)
- if (numPulses != 41)
+ else if (badTemperatureCount < MAX_BAD_TEMPERATURE_COUNT)
+ {
+ badTemperatureCount++;
+ }
+ else
{
- break;
+ lastResult = rslt;
+ lastTemperature = BAD_ERROR_TEMPERATURE;
+ lastHumidity = BAD_ERROR_TEMPERATURE;
}
+ }
+}
- // We're done reading - reset the state and convert the pulses into final values
- state = Initialising;
- lastReadTime = millis();
+// Code executed by the DHT sensor task.
+// This is run at the same priority as the Heat task, so it must not sit in any spin loops.
+/*static*/ void DhtSensorHardwareInterface::SensorTask()
+{
+ for (;;)
+ {
+ for (DhtSensorHardwareInterface *&sensor : activeSensors)
+ {
+ {
+ MutexLocker lock(dhtMutex);
- ProcessReadings();
- break;
+ if (sensor != nullptr)
+ {
+ sensor->TakeReading();
+ }
+ }
+ delay(MinimumReadInterval/MaxSpiTempSensors);
+ }
}
}
-#endif
-
-/*static*/ void DhtSensor::ProcessReadings()
+// Process a reading. If success then update the temperature and humidity and return TemperatureError::success.
+// Else return the TemperatureError code but do not update the readings.
+TemperatureError DhtSensorHardwareInterface::ProcessReadings()
{
- // Check start bit
- if (pulses[0] < 40)
+ // Check enough bits received and check start bit
+ if (numPulses != ARRAY_SIZE(pulses) || pulses[0] < MinimumOneBitStepClocks)
{
- lastResult = TemperatureError::ioError;
- return;
+// debugPrintf("pulses %u p0 %u\n", numPulses, (unsigned int)pulses[0]);
+ return TemperatureError::ioError;
}
// Reset 40 bits of received data to zero
uint8_t data[5] = { 0, 0, 0, 0, 0 };
- // Inspect each high pulse and determine which ones
- // are 0 (less than 40us) or 1 (more than 40us)
+ // Inspect each high pulse and determine which ones are 0 (less than 50us) or 1 (more than 50us). Ignore the start bit.
for (size_t i = 0; i < 40; ++i)
{
data[i / 8] <<= 1;
- if (pulses[i + 1] > 40)
+ if (pulses[i + 1] >= MinimumOneBitStepClocks)
{
data[i / 8] |= 1;
}
}
+// debugPrintf("Data: %02x %02x %02x %02x %02x\n", data[0], data[1], data[2], data[3], data[4]);
// Verify checksum
if (((data[0] + data[1] + data[2] + data[3]) & 0xFF) != data[4])
{
- lastResult = TemperatureError::ioError;
- return;
+// debugPrintf("Cks err\n");
+ return TemperatureError::ioError;
}
// Generate final results
@@ -362,8 +304,7 @@ void DhtDataTransition(CallbackParameter)
case DhtSensorType::Dht11:
lastHumidity = data[0];
lastTemperature = data[2];
- lastResult = TemperatureError::success;
- break;
+ return TemperatureError::success;
case DhtSensorType::Dht21:
case DhtSensorType::Dht22:
@@ -373,17 +314,65 @@ void DhtDataTransition(CallbackParameter)
{
lastTemperature *= -1.0;
}
- lastResult = TemperatureError::success;
- break;
+ return TemperatureError::success;
default:
- lastHumidity = BAD_ERROR_TEMPERATURE;
- lastTemperature = BAD_ERROR_TEMPERATURE;
- lastResult = TemperatureError::notInitialised;
- break;
+ return TemperatureError::notInitialised;
}
}
+// Class DhtTemperatureSensor members
+DhtTemperatureSensor::DhtTemperatureSensor(unsigned int channel)
+ : TemperatureSensor(channel, "DHT-temperature")
+{
+}
+
+void DhtTemperatureSensor::Init()
+{
+ DhtSensorHardwareInterface::Create(GetSensorChannel() - FirstDhtTemperatureChannel);
+}
+
+GCodeResult DhtTemperatureSensor::Configure(unsigned int mCode, unsigned int heater, GCodeBuffer& gb, const StringRef& reply)
+{
+ return DhtSensorHardwareInterface::Configure(this, GetSensorChannel() - FirstDhtTemperatureChannel, mCode, heater, gb, reply);
+}
+
+DhtTemperatureSensor::~DhtTemperatureSensor()
+{
+ // We don't delete the hardware interface object because the humidity channel may still be using it
+}
+
+TemperatureError DhtTemperatureSensor::GetTemperature(float& t)
+{
+ return DhtSensorHardwareInterface::GetTemperatureOrHumidity(GetSensorChannel() - FirstDhtTemperatureChannel, t, false);
+}
+
+// Class DhtHumiditySensor members
+DhtHumiditySensor::DhtHumiditySensor(unsigned int channel)
+ : TemperatureSensor(channel, "DHT-humidity")
+{
+}
+
+void DhtHumiditySensor::Init()
+{
+ DhtSensorHardwareInterface::Create(GetSensorChannel() - FirstDhtHumidityChannel);
+}
+
+GCodeResult DhtHumiditySensor::Configure(unsigned int mCode, unsigned int heater, GCodeBuffer& gb, const StringRef& reply)
+{
+ return DhtSensorHardwareInterface::Configure(this, GetSensorChannel() - FirstDhtHumidityChannel, mCode, heater, gb, reply);
+}
+
+DhtHumiditySensor::~DhtHumiditySensor()
+{
+ // We don't delete the hardware interface object because the temperature channel may still be using it
+}
+
+TemperatureError DhtHumiditySensor::GetTemperature(float& t)
+{
+ return DhtSensorHardwareInterface::GetTemperatureOrHumidity(GetSensorChannel() - FirstDhtHumidityChannel, t, true);
+}
+
#endif
// End
diff --git a/src/Heating/Sensors/DhtSensor.h b/src/Heating/Sensors/DhtSensor.h
index 4688e267..c81ac1e8 100644
--- a/src/Heating/Sensors/DhtSensor.h
+++ b/src/Heating/Sensors/DhtSensor.h
@@ -12,56 +12,80 @@
#if SUPPORT_DHT_SENSOR
+#ifndef RTOS
+# error DHT sensors are only supported in RTOS builds
+#endif
+
# include "TemperatureSensor.h"
# include "RTOSIface.h"
enum class DhtSensorType
{
+ none,
Dht11,
Dht21,
Dht22
};
-class DhtSensor : public TemperatureSensor
+// This class represents a DHT sensor attached to a particular SPI CS pin
+class DhtSensorHardwareInterface
{
public:
- friend class Heat;
-
- DhtSensor(unsigned int channel);
- ~DhtSensor();
-#ifdef RTOS
- static void SensorTask();
-#endif
+ static GCodeResult Configure(TemperatureSensor *ts, unsigned int relativeChannel, unsigned int mCode, unsigned int heater, GCodeBuffer& gb, const StringRef& reply);
+ void Interrupt();
- GCodeResult Configure(unsigned int mCode, unsigned int heater, GCodeBuffer& gb, const StringRef& reply) override;
- void Init() override;
+ static DhtSensorHardwareInterface *Create(unsigned int relativeChannel);
+ static TemperatureError GetTemperatureOrHumidity(unsigned int relativeChannel, float& t, bool wantHumidity);
static void InitStatic();
- TemperatureError GetTemperature(float& t) override;
+ static void SensorTask();
private:
- static size_t numInstances;
- static DhtSensorType type;
- static TemperatureError lastResult;
- static float lastTemperature, lastHumidity;
- static size_t badTemperatureCount;
+ DhtSensorHardwareInterface(Pin p_pin);
+
+ GCodeResult Configure(TemperatureSensor *ts, unsigned int mCode, unsigned int heater, GCodeBuffer& gb, const StringRef& reply);
+ TemperatureError GetTemperatureOrHumidity(float& t, bool wantHumidity) const;
+ void TakeReading();
+ TemperatureError ProcessReadings();
+
+ static constexpr uint32_t DhtTaskStackWords = 100; // task stack size in dwords. 80 was not enough. Use 300 if debugging is enabled.
static Mutex dhtMutex;
+ static Task<DhtTaskStackWords> *dhtTask;
+ static DhtSensorHardwareInterface *activeSensors[MaxSpiTempSensors];
-#ifndef RTOS
- static uint32_t lastReadTime;
- static enum SensorState
- {
- Initialising,
- Starting,
- Starting2,
- Reading
- } state;
- static uint32_t lastOperationTime;
-
- static void Spin();
-#endif
+ Pin sensorPin;
+ DhtSensorType type;
+ TemperatureError lastResult;
+ float lastTemperature, lastHumidity;
+ size_t badTemperatureCount;
+
+ volatile uint16_t lastPulseTime;
+ volatile size_t numPulses;
+ uint16_t pulses[41]; // 1 start bit + 40 data bits
+};
+
+// This class represents a DHT temperature sensor
+class DhtTemperatureSensor : public TemperatureSensor
+{
+public:
+ DhtTemperatureSensor(unsigned int channel);
+ ~DhtTemperatureSensor();
- static void ProcessReadings();
+ TemperatureError GetTemperature(float& t) override;
+ GCodeResult Configure(unsigned int mCode, unsigned int heater, GCodeBuffer& gb, const StringRef& reply) override;
+ void Init() override;
+};
+
+// This class represents a DHT humidity sensor
+class DhtHumiditySensor : public TemperatureSensor
+{
+public:
+ DhtHumiditySensor(unsigned int channel);
+ ~DhtHumiditySensor();
+
+ TemperatureError GetTemperature(float& t) override;
+ GCodeResult Configure(unsigned int mCode, unsigned int heater, GCodeBuffer& gb, const StringRef& reply) override;
+ void Init() override;
};
#endif
diff --git a/src/Heating/Sensors/TemperatureSensor.cpp b/src/Heating/Sensors/TemperatureSensor.cpp
index b5e1600a..2f97a41a 100644
--- a/src/Heating/Sensors/TemperatureSensor.cpp
+++ b/src/Heating/Sensors/TemperatureSensor.cpp
@@ -111,9 +111,13 @@ TemperatureSensor *TemperatureSensor::Create(unsigned int channel)
ts = new CurrentLoopTemperatureSensor(channel);
}
#if SUPPORT_DHT_SENSOR
- else if (channel == DhtTemperatureChannel || channel == DhtHumidityChannel)
+ else if (FirstDhtTemperatureChannel <= channel && channel < FirstDhtTemperatureChannel + MaxSpiTempSensors)
{
- ts = new DhtSensor(channel);
+ ts = new DhtTemperatureSensor(channel);
+ }
+ else if (FirstDhtHumidityChannel <= channel && channel < FirstDhtHumidityChannel + MaxSpiTempSensors)
+ {
+ ts = new DhtHumiditySensor(channel);
}
#endif
#if HAS_CPU_TEMP_SENSOR
@@ -123,7 +127,7 @@ TemperatureSensor *TemperatureSensor::Create(unsigned int channel)
}
#endif
#if HAS_SMART_DRIVERS
- else if (channel >= FirstTmcDriversSenseChannel && channel < FirstTmcDriversSenseChannel + 2)
+ else if (channel >= FirstTmcDriversSenseChannel && channel < FirstTmcDriversSenseChannel + NumTmcDriversSenseChannels)
{
ts = new TmcDriverTemperatureSensor(channel);
}
diff --git a/src/Heating/Sensors/TemperatureSensor.h b/src/Heating/Sensors/TemperatureSensor.h
index fdb04775..fe5f6b59 100644
--- a/src/Heating/Sensors/TemperatureSensor.h
+++ b/src/Heating/Sensors/TemperatureSensor.h
@@ -41,12 +41,13 @@ public:
// Get the name. Returns nullptr if no name has been assigned.
const char *GetHeaterName() const { return heaterName; }
+ // Copy the basic details to the reply buffer
+ void CopyBasicHeaterDetails(unsigned int heater, const StringRef& reply) const;
+
// Factory method
static TemperatureSensor *Create(unsigned int channel);
protected:
- void CopyBasicHeaterDetails(unsigned int heater, const StringRef& reply) const;
-
static TemperatureError GetPT100Temperature(float& t, uint16_t ohmsx100); // shared function used by two derived classes
private:
diff --git a/src/Movement/DDA.cpp b/src/Movement/DDA.cpp
index d8fe556f..a969c6dc 100644
--- a/src/Movement/DDA.cpp
+++ b/src/Movement/DDA.cpp
@@ -381,7 +381,6 @@ bool DDA::Init(GCodes::RawMove &nextMove, bool doMotorMapping)
xAxes = nextMove.xAxes;
yAxes = nextMove.yAxes;
endStopsToCheck = nextMove.endStopsToCheck;
- canPauseBefore = nextMove.canPauseBefore;
canPauseAfter = nextMove.canPauseAfter;
usingStandardFeedrate = nextMove.usingStandardFeedrate;
filePos = nextMove.filePos;
@@ -537,7 +536,6 @@ bool DDA::Init(const float_t adjustments[DRIVES])
isPrintingMove = false;
xyMoving = false;
endStopsToCheck = 0;
- canPauseBefore = true;
canPauseAfter = true;
usingStandardFeedrate = false;
usePressureAdvance = false;
@@ -897,7 +895,7 @@ void DDA::RecalculateMove()
// We need to set the number of clocks needed here because we use it before the move has been frozen
const float totalTime = (2 * topSpeed - startSpeed - endSpeed)/acceleration + (totalDistance - accelDistance - decelDistance)/topSpeed;
- clocksNeeded = (uint32_t)(totalTime * stepClockRate);
+ clocksNeeded = (uint32_t)(totalTime * StepClockRate);
}
// Decide what speed we would really like this move to end at.
@@ -1027,10 +1025,10 @@ void DDA::Prepare(uint8_t simMode)
const float accelStopTime = (topSpeed - startSpeed)/acceleration;
const float decelStartTime = accelStopTime + (params.decelStartDistance - accelDistance)/topSpeed;
- startSpeedTimesCdivA = (uint32_t)roundU32((startSpeed * stepClockRate)/acceleration);
- params.topSpeedTimesCdivA = (uint32_t)roundU32((topSpeed * stepClockRate)/acceleration);
- topSpeedTimesCdivAPlusDecelStartClocks = params.topSpeedTimesCdivA + (uint32_t)roundU32(decelStartTime * stepClockRate);
- extraAccelerationClocks = roundS32((accelStopTime - (accelDistance/topSpeed)) * stepClockRate);
+ startSpeedTimesCdivA = (uint32_t)roundU32((startSpeed * StepClockRate)/acceleration);
+ params.topSpeedTimesCdivA = (uint32_t)roundU32((topSpeed * StepClockRate)/acceleration);
+ topSpeedTimesCdivAPlusDecelStartClocks = params.topSpeedTimesCdivA + (uint32_t)roundU32(decelStartTime * StepClockRate);
+ extraAccelerationClocks = roundS32((accelStopTime - (accelDistance/topSpeed)) * StepClockRate);
params.compFactor = (topSpeed - startSpeed)/topSpeed;
firstDM = nullptr;
@@ -1542,9 +1540,21 @@ bool DDA::Step()
break;
}
- // 7. Schedule next interrupt, or if it would be too soon, generate more steps immediately
+ // 7. Check whether we have been in this ISR for too long already and need to take a break
+ uint32_t nextStepDue = firstDM->nextStepTime + moveStartTime;
+ const uint32_t clocksTaken = (Platform::GetInterruptClocks16() - isrStartTime) & 0x0000FFFF;
+ if (clocksTaken >= DDA::MaxStepInterruptTime && (nextStepDue - isrStartTime) < (clocksTaken + DDA::MinInterruptInterval))
+ {
+ // Force a break by updating the move start time
+ const uint32_t delayClocks = (clocksTaken + DDA::MinInterruptInterval) - (nextStepDue - isrStartTime);
+ moveStartTime += delayClocks;
+ nextStepDue += delayClocks;
+ ++numHiccups;
+ }
+
+ // 8. Schedule next interrupt, or if it would be too soon, generate more steps immediately
// If we have already spent too much time in the ISR, delay the interrupt
- repeat = platform.ScheduleStepInterruptWithLimit(firstDM->nextStepTime + moveStartTime, isrStartTime);
+ repeat = platform.ScheduleStepInterrupt(nextStepDue);
} while (repeat);
if (state == completed)
diff --git a/src/Movement/DDA.h b/src/Movement/DDA.h
index 45f085c4..066f3405 100644
--- a/src/Movement/DDA.h
+++ b/src/Movement/DDA.h
@@ -50,7 +50,6 @@ public:
void Prepare(uint8_t simMode) __attribute__ ((hot)); // Calculate all the values and freeze this DDA
bool HasStepError() const;
bool CanPauseAfter() const { return canPauseAfter; }
- bool CanPauseBefore() const { return canPauseBefore; }
bool IsPrintingMove() const { return isPrintingMove; } // Return true if this involves both XY movement and extrusion
bool UsingStandardFeedrate() const { return usingStandardFeedrate; }
@@ -96,9 +95,6 @@ public:
void DebugPrint() const; // print the DDA only
void DebugPrintAll() const; // print the DDA and active DMs
- static constexpr uint32_t stepClockRate = VARIANT_MCK/128; // the frequency of the clock used for stepper pulse timing (see Platform::InitialiseInterrupts)
- static constexpr uint64_t stepClockRateSquared = (uint64_t)stepClockRate * stepClockRate;
-
// Note on the following constant:
// If we calculate the step interval on every clock, we reach a point where the calculation time exceeds the step interval.
// The worst case is pure Z movement on a delta. On a Mini Kossel with 80 steps/mm with this firmware running on a Duet (84MHx SAM3X8 processor),
@@ -107,16 +103,16 @@ public:
// Note: the above measurements were taken some time ago, before some firmware optimisations.
#if SAME70
// The system clock of the SAME70 is running at 150MHz. Use the same defaults as for the SAM4E for now.
- static constexpr uint32_t MinCalcIntervalDelta = (40 * stepClockRate)/1000000; // the smallest sensible interval between calculations (40us) in step timer clocks
- static constexpr uint32_t MinCalcIntervalCartesian = (40 * stepClockRate)/1000000; // same as delta for now, but could be lower
+ static constexpr uint32_t MinCalcIntervalDelta = (40 * StepClockRate)/1000000; // the smallest sensible interval between calculations (40us) in step timer clocks
+ static constexpr uint32_t MinCalcIntervalCartesian = (40 * StepClockRate)/1000000; // same as delta for now, but could be lower
static constexpr uint32_t MinInterruptInterval = 6; // about 6us minimum interval between interrupts, in step clocks
#elif SAM4E || SAM4S
- static constexpr uint32_t MinCalcIntervalDelta = (40 * stepClockRate)/1000000; // the smallest sensible interval between calculations (40us) in step timer clocks
- static constexpr uint32_t MinCalcIntervalCartesian = (40 * stepClockRate)/1000000; // same as delta for now, but could be lower
+ static constexpr uint32_t MinCalcIntervalDelta = (40 * StepClockRate)/1000000; // the smallest sensible interval between calculations (40us) in step timer clocks
+ static constexpr uint32_t MinCalcIntervalCartesian = (40 * StepClockRate)/1000000; // same as delta for now, but could be lower
static constexpr uint32_t MinInterruptInterval = 6; // about 6us minimum interval between interrupts, in step clocks
#else
- static constexpr uint32_t MinCalcIntervalDelta = (60 * stepClockRate)/1000000; // the smallest sensible interval between calculations (60us) in step timer clocks
- static constexpr uint32_t MinCalcIntervalCartesian = (60 * stepClockRate)/1000000; // same as delta for now, but could be lower
+ static constexpr uint32_t MinCalcIntervalDelta = (60 * StepClockRate)/1000000; // the smallest sensible interval between calculations (60us) in step timer clocks
+ static constexpr uint32_t MinCalcIntervalCartesian = (60 * StepClockRate)/1000000; // same as delta for now, but could be lower
static constexpr uint32_t MinInterruptInterval = 4; // about 6us minimum interval between interrupts, in step clocks
#endif
static constexpr uint32_t MaxStepInterruptTime = 10 * MinInterruptInterval; // the maximum time we spend looping in the ISR , in step clocks
@@ -167,7 +163,6 @@ private:
uint8_t endCoordinatesValid : 1; // True if endCoordinates can be relied on
uint8_t isDeltaMovement : 1; // True if this is a delta printer movement
uint8_t canPauseAfter : 1; // True if we can pause at the end of this move
- uint8_t canPauseBefore : 1; // True if we can pause just before this move
uint8_t isPrintingMove : 1; // True if this move includes XY movement and extrusion
uint8_t usePressureAdvance : 1; // True if pressure advance should be applied to any forward extrusion
uint8_t hadLookaheadUnderrun : 1; // True if the lookahead queue was not long enough to optimise this move
diff --git a/src/Movement/DriveMovement.cpp b/src/Movement/DriveMovement.cpp
index 5afcf344..f510d0a2 100644
--- a/src/Movement/DriveMovement.cpp
+++ b/src/Movement/DriveMovement.cpp
@@ -58,14 +58,14 @@ DriveMovement::DriveMovement(DriveMovement *next) : nextDM(next)
void DriveMovement::PrepareCartesianAxis(const DDA& dda, const PrepParams& params)
{
const float stepsPerMm = (float)totalSteps/dda.totalDistance;
- mp.cart.twoCsquaredTimesMmPerStepDivA = roundU64((double)(DDA::stepClockRateSquared * 2)/((double)stepsPerMm * (double)dda.acceleration));
+ mp.cart.twoCsquaredTimesMmPerStepDivA = roundU64((double)(StepClockRateSquared * 2)/((double)stepsPerMm * (double)dda.acceleration));
// Acceleration phase parameters
mp.cart.accelStopStep = (uint32_t)(dda.accelDistance * stepsPerMm) + 1;
mp.cart.compensationClocks = mp.cart.accelCompensationClocks = 0;
// Constant speed phase parameters
- mp.cart.mmPerStepTimesCKdivtopSpeed = roundU32(((float)((uint64_t)DDA::stepClockRate * K1))/(stepsPerMm * dda.topSpeed));
+ mp.cart.mmPerStepTimesCKdivtopSpeed = roundU32(((float)((uint64_t)StepClockRate * K1))/(stepsPerMm * dda.topSpeed));
// Deceleration phase parameters
// First check whether there is any deceleration at all, otherwise we may get strange results because of rounding errors
@@ -78,7 +78,7 @@ void DriveMovement::PrepareCartesianAxis(const DDA& dda, const PrepParams& param
{
mp.cart.decelStartStep = (uint32_t)(params.decelStartDistance * stepsPerMm) + 1;
const uint64_t initialDecelSpeedTimesCdivASquared = isquare64(params.topSpeedTimesCdivA);
- twoDistanceToStopTimesCsquaredDivA = initialDecelSpeedTimesCdivASquared + roundU64((params.decelStartDistance * (DDA::stepClockRateSquared * 2))/dda.acceleration);
+ twoDistanceToStopTimesCsquaredDivA = initialDecelSpeedTimesCdivASquared + roundU64((params.decelStartDistance * (StepClockRateSquared * 2))/dda.acceleration);
}
// No reverse phase
@@ -98,7 +98,7 @@ void DriveMovement::PrepareDeltaAxis(const DDA& dda, const PrepParams& params)
mp.delta.hmz0sK = roundS32(h0MinusZ0 * stepsPerMm * DriveMovement::K2);
mp.delta.minusAaPlusBbTimesKs = -roundS32(aAplusbB * stepsPerMm * DriveMovement::K2);
mp.delta.dSquaredMinusAsquaredMinusBsquaredTimesKsquaredSsquared = roundS64(dSquaredMinusAsquaredMinusBsquared * fsquare(stepsPerMm * DriveMovement::K2));
- mp.delta.twoCsquaredTimesMmPerStepDivA = roundU64((double)(2 * DDA::stepClockRateSquared)/((double)stepsPerMm * (double)dda.acceleration));
+ mp.delta.twoCsquaredTimesMmPerStepDivA = roundU64((double)(2 * StepClockRateSquared)/((double)stepsPerMm * (double)dda.acceleration));
// Calculate the distance at which we need to reverse direction.
if (params.a2plusb2 <= 0.0)
@@ -152,7 +152,7 @@ void DriveMovement::PrepareDeltaAxis(const DDA& dda, const PrepParams& params)
mp.delta.accelStopDsK = roundU32(dda.accelDistance * stepsPerMm * K2);
// Constant speed phase parameters
- mp.delta.mmPerStepTimesCKdivtopSpeed = roundU32(((float)DDA::stepClockRate * K1)/(stepsPerMm * dda.topSpeed));
+ mp.delta.mmPerStepTimesCKdivtopSpeed = roundU32(((float)StepClockRate * K1)/(stepsPerMm * dda.topSpeed));
// Deceleration phase parameters
// First check whether there is any deceleration at all, otherwise we may get strange results because of rounding errors
@@ -164,7 +164,7 @@ void DriveMovement::PrepareDeltaAxis(const DDA& dda, const PrepParams& params)
else
{
mp.delta.decelStartDsK = roundU32(params.decelStartDistance * stepsPerMm * K2);
- twoDistanceToStopTimesCsquaredDivA = isquare64(params.topSpeedTimesCdivA) + roundU64((params.decelStartDistance * (DDA::stepClockRateSquared * 2))/dda.acceleration);
+ twoDistanceToStopTimesCsquaredDivA = isquare64(params.topSpeedTimesCdivA) + roundU64((params.decelStartDistance * (StepClockRateSquared * 2))/dda.acceleration);
}
}
@@ -181,7 +181,7 @@ void DriveMovement::PrepareExtruder(const DDA& dda, const PrepParams& params, fl
float a, b, limit;
if (reprap.GetPlatform().GetExtrusionCoefficients(extruder, a, b, limit))
{
- const float averageExtrusionSpeed = (dda.totalDistance * dv * DDA::stepClockRate)/dda.clocksNeeded;
+ const float averageExtrusionSpeed = (dda.totalDistance * dv * StepClockRate)/dda.clocksNeeded;
const float factor = 1.0 + min<float>((averageExtrusionSpeed * a) + (averageExtrusionSpeed * averageExtrusionSpeed * b), limit);
stepsPerMm *= factor;
}
@@ -196,8 +196,8 @@ void DriveMovement::PrepareExtruder(const DDA& dda, const PrepParams& params, fl
{
// Calculate the pressure advance parameters
compensationTime = reprap.GetPlatform().GetPressureAdvance(extruder);
- mp.cart.compensationClocks = roundU32(compensationTime * (float)DDA::stepClockRate);
- mp.cart.accelCompensationClocks = roundU32(compensationTime * (float)DDA::stepClockRate * params.compFactor);
+ mp.cart.compensationClocks = roundU32(compensationTime * (float)StepClockRate);
+ mp.cart.accelCompensationClocks = roundU32(compensationTime * (float)StepClockRate * params.compFactor);
#ifdef COMPENSATE_SPEED_CHANGES
// If there is a speed change at the start of the move, theoretically we should instantly advance or retard the filament by the associated compensation amount.
@@ -223,10 +223,10 @@ void DriveMovement::PrepareExtruder(const DDA& dda, const PrepParams& params, fl
mp.cart.accelStopStep = (uint32_t)(dda.accelDistance * stepsPerMm) + 1;
}
- mp.cart.twoCsquaredTimesMmPerStepDivA = roundU64((double)(DDA::stepClockRateSquared * 2)/((double)stepsPerMm * (double)dda.acceleration));
+ mp.cart.twoCsquaredTimesMmPerStepDivA = roundU64((double)(StepClockRateSquared * 2)/((double)stepsPerMm * (double)dda.acceleration));
// Constant speed phase parameters
- mp.cart.mmPerStepTimesCKdivtopSpeed = (uint32_t)((float)((uint64_t)DDA::stepClockRate * K1)/(stepsPerMm * dda.topSpeed));
+ mp.cart.mmPerStepTimesCKdivtopSpeed = (uint32_t)((float)((uint64_t)StepClockRate * K1)/(stepsPerMm * dda.topSpeed));
// Calculate the deceleration and reverse phase parameters and update totalSteps
// First check whether there is any deceleration at all, otherwise we may get strange results because of rounding errors
@@ -243,7 +243,7 @@ void DriveMovement::PrepareExtruder(const DDA& dda, const PrepParams& params, fl
const int32_t initialDecelSpeedTimesCdivA = (int32_t)params.topSpeedTimesCdivA - (int32_t)mp.cart.compensationClocks; // signed because it may be negative and we square it
const uint64_t initialDecelSpeedTimesCdivASquared = isquare64(initialDecelSpeedTimesCdivA);
twoDistanceToStopTimesCsquaredDivA =
- initialDecelSpeedTimesCdivASquared + roundU64(((params.decelStartDistance + accelCompensationDistance) * (float)(DDA::stepClockRateSquared * 2))/dda.acceleration);
+ initialDecelSpeedTimesCdivASquared + roundU64(((params.decelStartDistance + accelCompensationDistance) * (float)(StepClockRateSquared * 2))/dda.acceleration);
// See whether there is a reverse phase
const float compensationSpeedChange = dda.acceleration * compensationTime;
diff --git a/src/Movement/Move.cpp b/src/Movement/Move.cpp
index 9dcf6cb6..1765ac71 100644
--- a/src/Movement/Move.cpp
+++ b/src/Movement/Move.cpp
@@ -37,8 +37,8 @@
#include "Platform.h"
#include "Tools/Tool.h"
-static constexpr uint32_t UsualMinimumPreparedTime = DDA::stepClockRate/10; // 100ms
-static constexpr uint32_t AbsoluteMinimumPreparedTime = DDA::stepClockRate/20; // 50ms
+constexpr uint32_t UsualMinimumPreparedTime = StepClockRate/10; // 100ms
+constexpr uint32_t AbsoluteMinimumPreparedTime = StepClockRate/20; // 50ms
Move::Move() : currentDda(nullptr), active(false), scheduledMoves(0), completedMoves(0)
{
@@ -197,7 +197,7 @@ void Move::Spin()
prevMoveTime = dda->GetClocksNeeded();
}
- canAddMove = (unPreparedTime < DDA::stepClockRate/2 || unPreparedTime + prevMoveTime < 2 * DDA::stepClockRate);
+ canAddMove = (unPreparedTime < StepClockRate/2 || unPreparedTime + prevMoveTime < 2 * StepClockRate);
}
if (canAddMove)
@@ -283,7 +283,7 @@ void Move::Spin()
DDA *cdda; // currentDda is declared volatile, so copy it in the next line
if (simulationMode != 0 && (cdda = currentDda) != nullptr)
{
- simulationTime += (float)cdda->GetClocksNeeded()/DDA::stepClockRate;
+ simulationTime += (float)cdda->GetClocksNeeded()/StepClockRate;
cdda->Complete();
CurrentMoveCompleted();
}
@@ -455,7 +455,7 @@ bool Move::PausePrint(RestorePoint& rp)
while (dda != savedDdaRingAddPointer)
{
- if (pauseOkHere && dda->CanPauseBefore())
+ if (pauseOkHere)
{
// We can pause before executing this move
ddaRingAddPointer = dda;
@@ -477,8 +477,6 @@ bool Move::PausePrint(RestorePoint& rp)
InverseAxisAndBedTransform(rp.moveCoords, prevDda->GetXAxes(), prevDda->GetYAxes()); // we assume that xAxes hasn't changed between the moves
- 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
@@ -489,6 +487,7 @@ bool Move::PausePrint(RestorePoint& rp)
}
dda = ddaRingAddPointer;
+ rp.proportionDone = dda->GetProportionDone(false); // get the proportion of the current multi-segment move that has been completed
if (dda->UsingStandardFeedrate())
{
rp.feedRate = dda->GetRequestedSpeed();
diff --git a/src/Networking/Network.cpp b/src/Networking/Network.cpp
index bdb49f9a..ddfc9099 100644
--- a/src/Networking/Network.cpp
+++ b/src/Networking/Network.cpp
@@ -91,6 +91,9 @@ void Network::Init()
{
iface->Init();
}
+
+ fastLoop = UINT32_MAX;
+ slowLoop = 0;
}
GCodeResult Network::EnableProtocol(unsigned int interface, NetworkProtocol protocol, int port, int secure, const StringRef& reply)
@@ -265,6 +268,8 @@ bool Network::IsWiFiInterface(unsigned int interface) const
// Main spin loop. If 'full' is true then we are being called from the main spin loop. If false then we are being called during HSMCI idle time.
void Network::Spin(bool full)
{
+ const uint32_t lastTime = Platform::GetInterruptClocks();
+
// Keep the network modules running
for (NetworkInterface *iface : interfaces)
{
@@ -289,6 +294,17 @@ void Network::Spin(bool full)
}
HttpResponder::CheckSessions(); // time out any sessions that have gone away
+
+ // Keep track of the loop time
+ const uint32_t dt = Platform::GetInterruptClocks() - lastTime;
+ if (dt < fastLoop)
+ {
+ fastLoop = dt;
+ }
+ if (dt > slowLoop)
+ {
+ slowLoop = dt;
+ }
}
// Process the network timer interrupt
@@ -303,6 +319,11 @@ void Network::Interrupt()
void Network::Diagnostics(MessageType mtype)
{
platform.Message(mtype, "=== Network ===\n");
+
+ platform.MessageF(mtype, "Slowest loop: %.2fms; fastest: %.2fms\n", (double)(slowLoop * StepClocksToMillis), (double)(fastLoop * StepClocksToMillis));
+ fastLoop = UINT32_MAX;
+ slowLoop = 0;
+
platform.Message(mtype, "Responder states:");
for (NetworkResponder *r = responders; r != nullptr; r = r->GetNext())
{
diff --git a/src/Networking/Network.h b/src/Networking/Network.h
index c7e84e82..0355e625 100644
--- a/src/Networking/Network.h
+++ b/src/Networking/Network.h
@@ -88,6 +88,8 @@ private:
Mutex httpMutex, telnetMutex;
+ uint32_t fastLoop, slowLoop;
+
char hostname[16]; // Limit DHCP hostname to 15 characters + terminating 0
};
diff --git a/src/Platform.cpp b/src/Platform.cpp
index 5ca13ac7..45c669f3 100644
--- a/src/Platform.cpp
+++ b/src/Platform.cpp
@@ -1833,7 +1833,7 @@ static void FanInterrupt(CallbackParameter)
++fanInterruptCount;
if (fanInterruptCount == fanMaxInterruptCount)
{
- const uint32_t now = micros();
+ const uint32_t now = Platform::GetInterruptClocks();
fanInterval = now - fanLastResetTime;
fanLastResetTime = now;
fanInterruptCount = 0;
@@ -2427,8 +2427,8 @@ bool Platform::DiagnosticTest(GCodeBuffer& gb, const StringRef& reply, int d)
}
}
reply.printf("Square roots: 62-bit %.2fus %s, 32-bit %.2fus %s\n",
- (double)(tim1 * 10000)/DDA::stepClockRate, (ok1) ? "ok" : "ERROR",
- (double)(tim2 * 10000)/DDA::stepClockRate, (ok2) ? "ok" : "ERROR");
+ (double)(tim1 * 10000)/StepClockRate, (ok1) ? "ok" : "ERROR",
+ (double)(tim2 * 10000)/StepClockRate, (ok2) ? "ok" : "ERROR");
}
break;
@@ -3126,7 +3126,7 @@ void Platform::SetDriverStepTiming(size_t driver, const float microseconds[4])
if (microseconds[i] > MinStepPulseTiming)
{
slowDriversBitmap |= CalcDriverBitmap(driver); // this drive does need extended timing
- const uint32_t clocks = (uint32_t)(((float)DDA::stepClockRate * microseconds[i] * 0.000001) + 0.99); // convert microseconds to step clocks, rounding up
+ const uint32_t clocks = (uint32_t)(((float)StepClockRate * microseconds[i] * 0.000001) + 0.99); // convert microseconds to step clocks, rounding up
if (clocks > slowDriverStepTimingClocks[i])
{
slowDriverStepTimingClocks[i] = clocks;
@@ -3141,7 +3141,7 @@ void Platform::GetDriverStepTiming(size_t driver, float microseconds[4]) const
for (size_t i = 0; i < 4; ++i)
{
microseconds[i] = (isSlowDriver)
- ? (float)slowDriverStepTimingClocks[i] * 1000000.0/(float)DDA::stepClockRate
+ ? (float)slowDriverStepTimingClocks[i] * 1000000.0/(float)StepClockRate
: 0.0;
}
}
@@ -3207,9 +3207,9 @@ float Platform::GetFanRPM() const
// We get 2 tacho pulses per revolution, hence 2 interrupts per revolution.
// However, if the fan stops then we get no interrupts and fanInterval stops getting updated.
// We must recognise this and return zero.
- return (fanInterval != 0 && micros() - fanLastResetTime < 3000000U) // if we have a reading and it is less than 3 second old
- ? (float)((30000000U * fanMaxInterruptCount)/fanInterval) // then calculate RPM assuming 2 interrupts per rev
- : 0.0; // else assume fan is off or tacho not connected
+ return (fanInterval != 0 && Platform::GetInterruptClocks() - fanLastResetTime < 3 * StepClockRate) // if we have a reading and it is less than 3 second old
+ ? (float)(3 * StepClockRate * fanMaxInterruptCount)/fanInterval // then calculate RPM assuming 2 interrupts per rev
+ : 0.0; // else assume fan is off or tacho not connected
}
bool Platform::FansHardwareInverted(size_t fanNumber) const
@@ -4447,39 +4447,6 @@ void STEP_TC_HANDLER()
return false;
}
-// Schedule an interrupt at the specified clock count, or return true if it has passed already
-// This version limits the time we can spend in the ISR
-/*static*/ bool Platform::ScheduleStepInterruptWithLimit(uint32_t tim, uint32_t isrStartTime)
-{
- const irqflags_t flags = cpu_irq_save();
- const uint32_t iClocks = GetInterruptClocksInterruptsDisabled();
- if ((int32_t)(tim - iClocks) < (int32_t)DDA::MinInterruptInterval) // if less than about 6us to go or already passed
- {
- if (iClocks - isrStartTime < DDA::MaxStepInterruptTime) // if we haven't already spent too much time looping inside the ISR
- {
- cpu_irq_restore(flags);
- return true; // tell the caller to simulate an interrupt instead
- }
- tim = iClocks + DDA::MinInterruptInterval; // delay the interrupt to avoid using all the CPU time
- ++DDA::numHiccups;
- }
-
- STEP_TC->TC_CHANNEL[STEP_TC_CHAN].TC_RA = tim; // set up the compare register
-
- // We would like to clear any pending step interrupt. To do this, we must read the TC status register.
- // Unfortunately, this would clear any other pending interrupts from the same TC.
- // So we don't, and the step ISR must allow for getting called prematurely.
- STEP_TC->TC_CHANNEL[STEP_TC_CHAN].TC_IER = TC_IER_CPAS; // enable the interrupt
- cpu_irq_restore(flags);
-
-#ifdef MOVE_DEBUG
- ++numInterruptsScheduled;
- nextInterruptTime = tim;
- nextInterruptScheduledAt = Platform::GetInterruptClocks();
-#endif
- return false;
-}
-
// Make sure we get no step interrupts
/*static*/ void Platform::DisableStepInterrupt()
{
diff --git a/src/Platform.h b/src/Platform.h
index 4d51e2e2..201c5cd4 100644
--- a/src/Platform.h
+++ b/src/Platform.h
@@ -279,10 +279,11 @@ typedef AveragingFilter<Z_PROBE_AVERAGE_READINGS> ZProbeAveragingFilter;
// Enumeration of error condition bits
enum class ErrorCode : uint32_t
{
- BadTemp = 1 << 0,
- BadMove = 1 << 1,
- OutputStarvation = 1 << 2,
- OutputStackOverflow = 1 << 3
+ BadTemp = 1u << 0,
+ BadMove = 1u << 1,
+ OutputStarvation = 1u << 2,
+ OutputStackOverflow = 1u << 3,
+ HsmciTimeout = 1u << 4
};
struct AxisDriversConfig
@@ -332,8 +333,8 @@ public:
// Timing
static uint32_t GetInterruptClocks() __attribute__ ((hot)); // Get the interrupt clock count
static uint32_t GetInterruptClocksInterruptsDisabled() __attribute__ ((hot)); // Get the interrupt clock count, when we know already that interrupts are disabled
+ static uint16_t GetInterruptClocks16(); // Get the interrupt clock count when we only care about the lowest 16 bits
static bool ScheduleStepInterrupt(uint32_t tim) __attribute__ ((hot)); // Schedule an interrupt at the specified clock count, or return true if it has passed already
- static bool ScheduleStepInterruptWithLimit(uint32_t tim, uint32_t isrStartTime) __attribute__ ((hot)); // Schedule an interrupt at the specified clock count, or return true if it has passed already
static void DisableStepInterrupt(); // Make sure we get no step interrupts
static bool ScheduleSoftTimerInterrupt(uint32_t tim); // Schedule an interrupt at the specified clock count, or return true if it has passed already
static void DisableSoftTimerInterrupt(); // Make sure we get no software timer interrupts
@@ -564,6 +565,7 @@ public:
#if HAS_SMART_DRIVERS
float GetTmcDriversTemperature(unsigned int board) const;
void DriverCoolingFansOn(uint32_t driverChannelsMonitored);
+ unsigned int GetNumSmartDrivers() const { return numSmartDrivers; }
#endif
#if HAS_STALL_DETECT
@@ -1161,6 +1163,12 @@ inline float Platform::GetPressureAdvance(size_t extruder) const
#endif
+// Get the interrupt clock count when we only care about the lowest 16 bits. More efficient than calling GetInterruptClocks on platforms with 16-bit timers.
+/*static*/ inline uint16_t Platform::GetInterruptClocks16()
+{
+ return (uint16_t)STEP_TC->TC_CHANNEL[STEP_TC_CHAN].TC_CV;
+}
+
// This is called by the tick ISR to get the raw Z probe reading to feed to the filter
inline uint16_t Platform::GetRawZProbeReading() const
{
diff --git a/src/PortControl.cpp b/src/PortControl.cpp
index 7af80de5..3e6d7f0a 100644
--- a/src/PortControl.cpp
+++ b/src/PortControl.cpp
@@ -101,7 +101,7 @@ bool PortControl::Configure(GCodeBuffer& gb, const StringRef& reply)
{
seen = true;
advanceMillis = (unsigned int)constrain<int>(gb.GetIValue(), 0, 1000);
- advanceClocks = (advanceMillis * (uint64_t)DDA::stepClockRate)/1000;
+ advanceClocks = (advanceMillis * (uint64_t)StepClockRate)/1000;
}
if (!seen)
{
diff --git a/src/RepRap.cpp b/src/RepRap.cpp
index b55b84bb..0c426c9c 100644
--- a/src/RepRap.cpp
+++ b/src/RepRap.cpp
@@ -33,6 +33,9 @@
# include "FreeRTOS.h"
# include "task.h"
+// We call vTaskNotifyGiveFromISR from various interrupts, so the following must be true
+static_assert(configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY <= NvicPriorityHSMCI, "configMAX_SYSCALL_INTERRUPT_PRIORITY is set too high");
+
static TaskHandle_t hsmciTask = nullptr; // the task that is waiting for a HSMCI command to complete
// Callback function from the hsmci driver, called while it is waiting for an SD card operation to complete
@@ -52,7 +55,11 @@ extern "C" void hsmciIdle(uint32_t stBits, uint32_t dmaBits)
#if SAME70
XDMAC->XDMAC_CHID[CONF_HSMCI_XDMAC_CHANNEL].XDMAC_CIE = dmaBits;
#endif
- ulTaskNotifyTake(pdTRUE, 200);
+ if (ulTaskNotifyTake(pdTRUE, 200) == 0)
+ {
+ // We timed out waiting for the HSMCI operation to complete
+ reprap.GetPlatform().LogError(ErrorCode::HsmciTimeout);
+ }
}
}
@@ -152,7 +159,7 @@ void RepRap::Init()
platform->Init();
network->Init();
- SetName(DEFAULT_MACHINE_NAME); // network must be initialised before calling this because this calls SetHostName
+ SetName(DEFAULT_MACHINE_NAME); // Network must be initialised before calling this because this calls SetHostName
gCodes->Init();
move->Init();
heat->Init();
@@ -166,6 +173,7 @@ void RepRap::Init()
portControl->Init();
#endif
printMonitor->Init();
+ FilamentMonitor::InitStatic();
#if SUPPORT_12864_LCD
display->Init();
#endif
@@ -223,7 +231,6 @@ void RepRap::Init()
fastLoop = UINT32_MAX;
slowLoop = 0;
- lastTime = micros();
}
void RepRap::Exit()
@@ -250,8 +257,12 @@ void RepRap::Exit()
void RepRap::Spin()
{
- if(!active)
+ if (!active)
+ {
return;
+ }
+
+ const uint32_t lastTime = Platform::GetInterruptClocks();
ticksInSpinState = 0;
spinningModule = modulePlatform;
@@ -344,8 +355,7 @@ void RepRap::Spin()
}
// Keep track of the loop time
- const uint32_t t = micros();
- const uint32_t dt = t - lastTime;
+ const uint32_t dt = Platform::GetInterruptClocks() - lastTime;
if (dt < fastLoop)
{
fastLoop = dt;
@@ -354,14 +364,13 @@ void RepRap::Spin()
{
slowLoop = dt;
}
- lastTime = t;
RTOSIface::Yield();
}
void RepRap::Timing(MessageType mtype)
{
- platform->MessageF(mtype, "Slowest main loop (seconds): %f; fastest: %f\n", (double)(slowLoop * 0.000001), (double)(fastLoop * 0.000001));
+ platform->MessageF(mtype, "Slowest loop: %.2fms; fastest: %.2fms\n", (double)(slowLoop * StepClocksToMillis), (double)(fastLoop * StepClocksToMillis));
fastLoop = UINT32_MAX;
slowLoop = 0;
}
@@ -405,9 +414,26 @@ void RepRap::EmergencyStop()
{
stopped = true;
- // Do not turn off ATX power here. If the nozzles are still hot, don't risk melting any surrounding parts...
+ // Do not turn off ATX power here. If the nozzles are still hot, don't risk melting any surrounding parts by turning fans off.
//platform->SetAtxPower(false);
+ switch (gCodes->GetMachineType())
+ {
+ case MachineType::cnc:
+ for (size_t i = 0; i < MaxSpindles; i++)
+ {
+ platform->AccessSpindle(i).TurnOff();
+ }
+ break;
+
+ case MachineType::laser:
+ platform->SetLaserPwm(0.0);
+ break;
+
+ default:
+ break;
+ }
+
// Deselect all tools (is this necessary?)
{
MutexLocker lock(toolListMutex);
diff --git a/src/RepRap.h b/src/RepRap.h
index 09f76796..213adde3 100644
--- a/src/RepRap.h
+++ b/src/RepRap.h
@@ -153,7 +153,6 @@ private:
uint16_t ticksInSpinState;
Module spinningModule;
uint32_t fastLoop, slowLoop;
- uint32_t lastTime;
uint32_t debug;
bool stopped;
diff --git a/src/RepRapFirmware.h b/src/RepRapFirmware.h
index fd4eda8d..b23855a8 100644
--- a/src/RepRapFirmware.h
+++ b/src/RepRapFirmware.h
@@ -224,6 +224,9 @@ template<typename BitmapType> BitmapType UnsignedArrayToBitMap(const uint32_t *a
}
// Common definitions used by more than one module
+constexpr uint32_t StepClockRate = VARIANT_MCK/128; // the frequency of the clock used for stepper pulse timing (see Platform::InitialiseInterrupts)
+constexpr uint64_t StepClockRateSquared = (uint64_t)StepClockRate * StepClockRate;
+
constexpr size_t ScratchStringLength = 220; // standard length of a scratch string, enough to print delta parameters to
constexpr size_t ShortScratchStringLength = 50;
@@ -238,6 +241,7 @@ constexpr float MinutesToSeconds = 60.0;
constexpr float SecondsToMinutes = 1.0/MinutesToSeconds;
constexpr float SecondsToMillis = 1000.0;
constexpr float MillisToSeconds = 0.001;
+constexpr float StepClocksToMillis = 1000.0/(float)StepClockRate;
constexpr float InchToMm = 25.4;
constexpr float Pi = 3.141592653589793;
constexpr float TwoPi = 3.141592653589793 * 2;
@@ -256,20 +260,28 @@ const uint32_t NvicPriorityWatchdog = 0; // the secondary watchdog has the high
#endif
const uint32_t NvicPriorityPanelDueUart = 1; // UART is highest to avoid character loss (it has only a 1-character receive buffer)
-const uint32_t NvicPriorityDriversSerialTMC = 2;// USART or UART used to control and monitor the smart drivers
+const uint32_t NvicPriorityDriversSerialTMC = 2; // USART or UART used to control and monitor the smart drivers
+
+#ifndef RTOS
const uint32_t NvicPrioritySystick = 3; // systick kicks the watchdog and starts the ADC conversions, so must be quite high
+#endif
+
const uint32_t NvicPriorityPins = 4; // priority for GPIO pin interrupts - filament sensors must be higher than step
-const uint32_t NvicPriorityStep = 5; // step interrupt is next highest, it can preempt most other interrupts
-const uint32_t NvicPriorityWiFiUart = 6; // UART used to receive debug data from the WiFi module
-const uint32_t NvicPriorityUSB = 6; // USB interrupt
-const uint32_t NvicPriorityHSMCI = 6; // HSMCI command complete interrupt
+
+// Currently we set configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY in FreeRTOS to 5.
+// This means that only interrupts with priority numerically at least 5 can make ISR-safe calls to FreeRTOS in an ISR.
+
+const uint32_t NvicPriorityStep = 6; // step interrupt is next highest, it can preempt most other interrupts
+const uint32_t NvicPriorityWiFiUart = 7; // UART used to receive debug data from the WiFi module
+const uint32_t NvicPriorityUSB = 7; // USB interrupt
+const uint32_t NvicPriorityHSMCI = 7; // HSMCI command complete interrupt
#if HAS_LWIP_NETWORKING
-const uint32_t NvicPriorityNetworkTick = 7; // priority for network tick interrupt
-const uint32_t NvicPriorityEthernet = 7; // priority for Ethernet interface
+const uint32_t NvicPriorityNetworkTick = 8; // priority for network tick interrupt
+const uint32_t NvicPriorityEthernet = 8; // priority for Ethernet interface
#endif
-const uint32_t NvicPrioritySpi = 7; // SPI is used for network transfers on Duet WiFi/Duet vEthernet
-const uint32_t NvicPriorityTwi = 8; // TWI is used to read endstop and other inputs on the DueXn
+const uint32_t NvicPrioritySpi = 8; // SPI is used for network transfers on Duet WiFi/Duet vEthernet
+const uint32_t NvicPriorityTwi = 9; // TWI is used to read endstop and other inputs on the DueXn
#endif
diff --git a/src/SoftTimer.cpp b/src/SoftTimer.cpp
index 8b0a5d77..95440e11 100644
--- a/src/SoftTimer.cpp
+++ b/src/SoftTimer.cpp
@@ -7,7 +7,6 @@
#include "SoftTimer.h"
#include "Platform.h"
-#include "Movement/DDA.h"
SoftTimer * volatile SoftTimer::pendingList = nullptr;
@@ -74,7 +73,7 @@ void SoftTimer::CancelCallback()
// Get the tick rate
/*static*/ SoftTimer::Ticks SoftTimer::GetTickRate()
{
- return DDA::stepClockRate; // the software timer uses the same counter as the step timer
+ return StepClockRate; // the software timer uses the same counter as the step timer
}
// ISR called from Platform. May sometimes get called prematurely.
diff --git a/src/Storage/FileInfoParser.cpp b/src/Storage/FileInfoParser.cpp
index f7872d62..4dfc90cf 100644
--- a/src/Storage/FileInfoParser.cpp
+++ b/src/Storage/FileInfoParser.cpp
@@ -346,6 +346,7 @@ bool FileInfoParser::GetFileInfo(const char *directory, const char *fileName, GC
default: // should not get here
parsedFileInfo.incomplete = false;
+ fileBeingParsed->Close();
info = parsedFileInfo;
parseState = notParsing;
return true;
@@ -356,6 +357,7 @@ bool FileInfoParser::GetFileInfo(const char *directory, const char *fileName, GC
if (quitEarly)
{
info = parsedFileInfo; // note that the 'incomplete' flag is still set
+ fileBeingParsed->Close();
parseState = notParsing;
return true;
}
diff --git a/src/Storage/FileStore.cpp b/src/Storage/FileStore.cpp
index 94b34a48..b46a68a2 100644
--- a/src/Storage/FileStore.cpp
+++ b/src/Storage/FileStore.cpp
@@ -5,6 +5,7 @@
#include "MassStorage.h"
#include "Platform.h"
#include "RepRap.h"
+#include "Movement/DDA.h"
uint32_t FileStore::longestWriteTime = 0;
@@ -15,8 +16,7 @@ FileStore::FileStore() : writeBuffer(nullptr)
void FileStore::Init()
{
- inUse = false;
- writing = false;
+ usageMode = FileUseMode::free;
openCount = 0;
closeRequested = false;
}
@@ -38,8 +38,8 @@ bool FileStore::Invalidate(const FATFS *fs, bool doClose)
reprap.GetPlatform().GetMassStorage()->ReleaseWriteBuffer(writeBuffer);
writeBuffer = nullptr;
}
- Init();
}
+ usageMode = FileUseMode::invalidated;
return true;
}
return false;
@@ -57,7 +57,7 @@ bool FileStore::Open(const char* directory, const char* fileName, OpenMode mode)
{
String<MaxFilenameLength> location;
MassStorage::CombineName(location.GetRef(), directory, fileName);
- writing = (mode == OpenMode::write || mode == OpenMode::append);
+ const bool writing = (mode == OpenMode::write || mode == OpenMode::append);
if (writing)
{
@@ -108,71 +108,91 @@ bool FileStore::Open(const char* directory, const char* fileName, OpenMode mode)
return false;
}
crc.Reset();
- inUse = true;
+ usageMode = (writing) ? FileUseMode::readWrite : FileUseMode::readOnly;
openCount = 1;
return true;
}
void FileStore::Duplicate()
{
- if (!inUse)
+ switch (usageMode)
{
+ case FileUseMode::free:
INTERNAL_ERROR;
- }
- else
- {
- irqflags_t flags = cpu_irq_save();
- ++openCount;
- cpu_irq_restore(flags);
+ break;
+
+ case FileUseMode::readOnly:
+ case FileUseMode::readWrite:
+ {
+ const irqflags_t flags = cpu_irq_save();
+ ++openCount;
+ cpu_irq_restore(flags);
+ }
+ break;
+
+ case FileUseMode::invalidated:
+ default:
+ break;
}
}
// This may be called from an ISR, in which case we need to defer the close
bool FileStore::Close()
{
- if (inInterrupt())
+ switch (usageMode)
{
- if (!inUse)
+ case FileUseMode::free:
+ if (!inInterrupt())
{
- return false;
+ INTERNAL_ERROR;
}
+ return false;
- const irqflags_t flags = cpu_irq_save();
- if (openCount > 1)
+ case FileUseMode::readOnly:
+ case FileUseMode::readWrite:
{
- --openCount;
+ const irqflags_t flags = cpu_irq_save();
+ if (openCount > 1)
+ {
+ --openCount;
+ cpu_irq_restore(flags);
+ return true;
+ }
+ else if (inInterrupt())
+ {
+ closeRequested = true;
+ cpu_irq_restore(flags);
+ return true;
+ }
+ else
+ {
+ cpu_irq_restore(flags);
+ return ForceClose();
+ }
}
- else
+
+ case FileUseMode::invalidated:
+ default:
{
- closeRequested = true;
+ const irqflags_t flags = cpu_irq_save();
+ if (openCount > 1)
+ {
+ --openCount;
+ }
+ else
+ {
+ usageMode = FileUseMode::free;
+ }
+ cpu_irq_restore(flags);
+ return true;
}
- cpu_irq_restore(flags);
- return true;
}
-
- if (!inUse)
- {
- INTERNAL_ERROR;
- return false;
- }
-
- const irqflags_t flags = cpu_irq_save();
- --openCount;
- bool leaveOpen = (openCount != 0);
- cpu_irq_restore(flags);
-
- if (leaveOpen)
- {
- return true;
- }
-
- return ForceClose();
}
bool FileStore::ForceClose()
{
bool ok = true;
- if (writing)
+ if (usageMode == FileUseMode::readWrite)
{
ok = Flush();
}
@@ -184,8 +204,7 @@ bool FileStore::ForceClose()
}
const FRESULT fr = f_close(&file);
- inUse = false;
- writing = false;
+ usageMode = FileUseMode::free;
closeRequested = false;
openCount = 0;
return ok && fr == FR_OK;
@@ -193,23 +212,30 @@ bool FileStore::ForceClose()
bool FileStore::Seek(FilePosition pos)
{
- if (!inUse)
+ switch (usageMode)
{
+ case FileUseMode::free:
INTERNAL_ERROR;
return false;
+
+ case FileUseMode::readOnly:
+ case FileUseMode::readWrite:
+ return f_lseek(&file, pos) == FR_OK;
+
+ case FileUseMode::invalidated:
+ default:
+ return false;
}
- FRESULT fr = f_lseek(&file, pos);
- return fr == FR_OK;
}
FilePosition FileStore::Position() const
{
- return (inUse) ? file.fptr : 0;
+ return (usageMode == FileUseMode::readOnly || usageMode == FileUseMode::readWrite) ? file.fptr : 0;
}
uint32_t FileStore::ClusterSize() const
{
- return (inUse) ? file.fs->csize * 512u : 1; // we divide by the cluster size so return 1 not 0 if there is an error
+ return (usageMode == FileUseMode::readOnly || usageMode == FileUseMode::readWrite) ? file.fs->csize * 512u : 1; // we divide by the cluster size so return 1 not 0 if there is an error
}
#if 0 // not currently used
@@ -221,13 +247,22 @@ bool FileStore::GoToEnd()
FilePosition FileStore::Length() const
{
- if (!inUse)
+ switch (usageMode)
{
+ case FileUseMode::free:
INTERNAL_ERROR;
return 0;
- }
- return (writeBuffer != nullptr) ? file.fsize + writeBuffer->BytesStored() : file.fsize;
+ case FileUseMode::readOnly:
+ return file.fsize;
+
+ case FileUseMode::readWrite:
+ return (writeBuffer != nullptr) ? file.fsize + writeBuffer->BytesStored() : file.fsize;
+
+ case FileUseMode::invalidated:
+ default:
+ return 0;
+ }
}
// Single character read
@@ -239,20 +274,29 @@ bool FileStore::Read(char& b)
// Returns the number of bytes read or -1 if the read process failed
int FileStore::Read(char* extBuf, size_t nBytes)
{
- if (!inUse)
+ switch (usageMode)
{
+ case FileUseMode::free:
INTERNAL_ERROR;
return -1;
- }
- UINT bytes_read;
- FRESULT readStatus = f_read(&file, extBuf, nBytes, &bytes_read);
- if (readStatus != FR_OK)
- {
- reprap.GetPlatform().Message(ErrorMessage, "Cannot read file.\n");
+ case FileUseMode::readOnly:
+ case FileUseMode::readWrite:
+ {
+ UINT bytes_read;
+ FRESULT readStatus = f_read(&file, extBuf, nBytes, &bytes_read);
+ if (readStatus != FR_OK)
+ {
+ reprap.GetPlatform().Message(ErrorMessage, "Cannot read file.\n");
+ return -1;
+ }
+ return (int)bytes_read;
+ }
+
+ case FileUseMode::invalidated:
+ default:
return -1;
}
- return (int)bytes_read;
}
// As Read but stop after '\n' or '\r\n' and null-terminate the string.
@@ -291,10 +335,10 @@ int FileStore::ReadLine(char* buf, size_t nBytes)
FRESULT FileStore::Store(const char *s, size_t len, size_t *bytesWritten)
{
- uint32_t time = micros();
+ uint32_t time = Platform::GetInterruptClocks();
crc.Update(s, len);
- FRESULT writeStatus = f_write(&file, s, len, bytesWritten);
- time = micros() - time;
+ const FRESULT writeStatus = f_write(&file, s, len, bytesWritten);
+ time = Platform::GetInterruptClocks() - time;
if (time > longestWriteTime)
{
longestWriteTime = time;
@@ -314,97 +358,121 @@ bool FileStore::Write(const char* b)
bool FileStore::Write(const char *s, size_t len)
{
- if (!inUse)
+ switch (usageMode)
{
+ case FileUseMode::free:
INTERNAL_ERROR;
return false;
- }
- size_t totalBytesWritten = 0;
- FRESULT writeStatus = FR_OK;
- if (writeBuffer == nullptr)
- {
- writeStatus = Store(s, len, &totalBytesWritten);
- }
- else
- {
- do
+ case FileUseMode::readOnly:
+ case FileUseMode::readWrite:
{
- size_t bytesStored = writeBuffer->Store(s + totalBytesWritten, len - totalBytesWritten);
- if (writeBuffer->BytesLeft() == 0)
+ size_t totalBytesWritten = 0;
+ FRESULT writeStatus = FR_OK;
+ if (writeBuffer == nullptr)
{
- const size_t bytesToWrite = writeBuffer->BytesStored();
- size_t bytesWritten;
- writeStatus = Store(writeBuffer->Data(), bytesToWrite, &bytesWritten);
- writeBuffer->DataTaken();
-
- if (bytesToWrite != bytesWritten)
+ writeStatus = Store(s, len, &totalBytesWritten);
+ }
+ else
+ {
+ do
{
- // Something went wrong
- break;
+ size_t bytesStored = writeBuffer->Store(s + totalBytesWritten, len - totalBytesWritten);
+ if (writeBuffer->BytesLeft() == 0)
+ {
+ const size_t bytesToWrite = writeBuffer->BytesStored();
+ size_t bytesWritten;
+ writeStatus = Store(writeBuffer->Data(), bytesToWrite, &bytesWritten);
+ writeBuffer->DataTaken();
+
+ if (bytesToWrite != bytesWritten)
+ {
+ // Something went wrong
+ break;
+ }
+ }
+ totalBytesWritten += bytesStored;
}
+ while (writeStatus == FR_OK && totalBytesWritten != len);
+ }
+
+ if ((writeStatus != FR_OK) || (totalBytesWritten != len))
+ {
+ reprap.GetPlatform().Message(ErrorMessage, "Failed to write to file. Drive may be full.\n");
+ return false;
}
- totalBytesWritten += bytesStored;
+ return true;
}
- while (writeStatus == FR_OK && totalBytesWritten != len);
- }
- if ((writeStatus != FR_OK) || (totalBytesWritten != len))
- {
- reprap.GetPlatform().Message(ErrorMessage, "Failed to write to file. Drive may be full.\n");
- return false;
+ case FileUseMode::invalidated:
+ default:
+ return 0;
}
- return true;
}
bool FileStore::Flush()
{
- if (!inUse)
+ switch (usageMode)
{
+ case FileUseMode::free:
INTERNAL_ERROR;
return false;
- }
- if (writeBuffer != nullptr)
- {
- const size_t bytesToWrite = writeBuffer->BytesStored();
- if (bytesToWrite != 0)
- {
- size_t bytesWritten;
- const FRESULT writeStatus = Store(writeBuffer->Data(), bytesToWrite, &bytesWritten);
- writeBuffer->DataTaken();
+ case FileUseMode::readOnly:
+ return true;
- if ((writeStatus != FR_OK) || (bytesToWrite != bytesWritten))
+ case FileUseMode::readWrite:
+ if (writeBuffer != nullptr)
+ {
+ const size_t bytesToWrite = writeBuffer->BytesStored();
+ if (bytesToWrite != 0)
{
- reprap.GetPlatform().Message(ErrorMessage, "Failed to write to file. Drive may be full.\n");
- return false;
+ size_t bytesWritten;
+ const FRESULT writeStatus = Store(writeBuffer->Data(), bytesToWrite, &bytesWritten);
+ writeBuffer->DataTaken();
+
+ if ((writeStatus != FR_OK) || (bytesToWrite != bytesWritten))
+ {
+ reprap.GetPlatform().Message(ErrorMessage, "Failed to write to file. Drive may be full.\n");
+ return false;
+ }
}
}
- }
+ return f_sync(&file) == FR_OK;
- return f_sync(&file) == FR_OK;
+ case FileUseMode::invalidated:
+ default:
+ return false;
+ }
}
// Truncate file at current file pointer
bool FileStore::Truncate()
{
- if (!inUse)
+ switch (usageMode)
{
+ case FileUseMode::free:
+ case FileUseMode::readOnly:
INTERNAL_ERROR;
return false;
- }
- if (!Flush())
- {
+ case FileUseMode::readWrite:
+ if (!Flush())
+ {
+ return false;
+ }
+ return f_truncate(&file) == FR_OK;
+
+ case FileUseMode::invalidated:
+ default:
return false;
}
-
- return f_truncate(&file) == FR_OK;
}
+// Return the file write time in milliseconds, and clear it
float FileStore::GetAndClearLongestWriteTime()
{
- float ret = (float)longestWriteTime/1000.0;
+ const float ret = (float)longestWriteTime * StepClocksToMillis;
longestWriteTime = 0;
return ret;
}
@@ -415,16 +483,25 @@ float FileStore::GetAndClearLongestWriteTime()
// The first element of the table must be set to the total number of 32-bit entries in the table before calling this.
bool FileStore::SetClusterMap(uint32_t tbl[])
{
- if (!inUse)
+ switch (usageMode)
{
+ case FileUseMode::free:
INTERNAL_ERROR;
return false;
- }
- file.cltbl = tbl;
- FRESULT ret = f_lseek(&file, CREATE_LINKMAP);
-// debugPrintf("ret %d need %u\n", (int)ret, tbl[0]);
- return ret == FR_OK;
+ case FileUseMode::readOnly:
+ case FileUseMode::readWrite:
+ {
+ file.cltbl = tbl;
+ const FRESULT ret = f_lseek(&file, CREATE_LINKMAP);
+// debugPrintf("ret %d need %u\n", (int)ret, tbl[0]);
+ return ret == FR_OK;
+ }
+
+ case FileUseMode::invalidated:
+ default:
+ return false;
+ }
}
#endif
diff --git a/src/Storage/FileStore.h b/src/Storage/FileStore.h
index dbaf200f..9f674a4b 100644
--- a/src/Storage/FileStore.h
+++ b/src/Storage/FileStore.h
@@ -17,6 +17,14 @@ enum class OpenMode : uint8_t
append // append to an existing file, or create a new file if it is not found
};
+enum class FileUseMode : uint8_t
+{
+ free, // file object is free
+ readOnly, // file object is in use for reading only
+ readWrite, // file object is in use for reading and writing
+ invalidated // file object is in use but file system has been invalidated
+};
+
class FileStore
{
public:
@@ -63,9 +71,8 @@ private:
FileWriteBuffer *writeBuffer;
volatile unsigned int openCount;
volatile bool closeRequested;
+ FileUseMode usageMode;
- bool inUse;
- bool writing;
CRC32 crc;
static uint32_t longestWriteTime;
diff --git a/src/Storage/MassStorage.cpp b/src/Storage/MassStorage.cpp
index 91c3e17d..a42c4281 100644
--- a/src/Storage/MassStorage.cpp
+++ b/src/Storage/MassStorage.cpp
@@ -126,17 +126,9 @@ FileStore* MassStorage::OpenFile(const char* directory, const char* fileName, Op
MutexLocker lock(fsMutex);
for (size_t i = 0; i < MAX_FILES; i++)
{
- if (!files[i].inUse)
+ if (files[i].usageMode == FileUseMode::free)
{
- if (files[i].Open(directory, fileName, mode))
- {
- files[i].inUse = true;
- return &files[i];
- }
- else
- {
- return nullptr;
- }
+ return (files[i].Open(directory, fileName, mode)) ? &files[i]: nullptr;
}
}
}
@@ -150,7 +142,7 @@ void MassStorage::CloseAllFiles()
MutexLocker lock(fsMutex);
for (FileStore& f : files)
{
- while (f.inUse)
+ while (f.usageMode != FileUseMode::free)
{
f.Close();
}
@@ -595,7 +587,7 @@ bool MassStorage::AnyFileOpen(const FATFS *fs) const
return false;
}
-// Invalidate all open files on the specified file system, returning true if any files were invalidated
+// Invalidate all open files on the specified file system, returning the number of files that were invalidated
unsigned int MassStorage::InvalidateFiles(const FATFS *fs, bool doClose)
{
unsigned int invalidated = 0;
@@ -630,13 +622,13 @@ bool MassStorage::IsCardDetected(size_t card) const
return info[card].cardState == CardDetectState::present;
}
-// Unmount a file system returning true if any pen files were invalidated
-bool MassStorage::InternalUnmount(size_t card, bool doClose)
+// Unmount a file system returning true if any open files were invalidated
+unsigned int MassStorage::InternalUnmount(size_t card, bool doClose)
{
SdCardInfo& inf = info[card];
MutexLocker lock1(fsMutex);
MutexLocker lock2(inf.volMutex);
- const bool invalidated = InvalidateFiles(&inf.fileSystem, doClose);
+ const unsigned int invalidated = InvalidateFiles(&inf.fileSystem, doClose);
f_mount(card, nullptr);
memset(&inf.fileSystem, 0, sizeof(inf.fileSystem));
sd_mmc_unmount(card);
@@ -650,7 +642,7 @@ unsigned int MassStorage::GetNumFreeFiles() const
MutexLocker lock(fsMutex);
for (const FileStore & fil : files)
{
- if (!fil.inUse)
+ if (fil.usageMode == FileUseMode::free)
{
++numFreeFiles;
}
diff --git a/src/Storage/MassStorage.h b/src/Storage/MassStorage.h
index a67f103c..ab42896f 100644
--- a/src/Storage/MassStorage.h
+++ b/src/Storage/MassStorage.h
@@ -96,7 +96,7 @@ private:
CardDetectState cardState;
};
- bool InternalUnmount(size_t card, bool doClose);
+ unsigned int InternalUnmount(size_t card, bool doClose);
static time_t ConvertTimeStamp(uint16_t fdate, uint16_t ftime);
SdCardInfo info[NumSdCards];
diff --git a/src/Version.h b/src/Version.h
index 567bb215..ebacee61 100644
--- a/src/Version.h
+++ b/src/Version.h
@@ -18,11 +18,11 @@
# define RTOSVER
#endif
-# define VERSION MAIN_VERSION RTOSVER "RC5"
+# define VERSION MAIN_VERSION RTOSVER "RC6"
#endif
#ifndef DATE
-# define DATE "2018-05-23b1"
+# define DATE "2018-05-30b1"
#endif
#define AUTHORS "reprappro, dc42, chrishamm, t3p3, dnewman"