Add PI GCS2 module

This commit is contained in:
Kurt Goetze
2012-06-08 14:07:41 +00:00
parent dcf068a9c4
commit 026a0b9729
36 changed files with 8305 additions and 0 deletions
+3
View File
@@ -39,6 +39,9 @@ MclennanSrc_DEPEND_DIRS = MotorSrc
DIRS += PiSrc
PiSrc_DEPEND_DIRS = MotorSrc
DIRS += PIGCS2Src
PIGCS2Src_DEPEND_DIRS = MotorSrc
DIRS += MicroMoSrc
MicroMoSrc_DEPEND_DIRS = MotorSrc
+586
View File
@@ -0,0 +1,586 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<?fileVersion 4.0.0?>
<cproject storage_type_id="org.eclipse.cdt.core.XmlProjectDescriptionStorage">
<storageModule moduleId="org.eclipse.cdt.core.settings">
<cconfiguration id="0.1864894712">
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="0.1864894712" moduleId="org.eclipse.cdt.core.settings" name="Debug">
<macros>
<stringMacro name="EPICS_HOST_ARCH" type="VALUE_TEXT" value="linux-x86-debug"/>
</macros>
<externalSettings/>
<extensions>
<extension id="org.eclipse.cdt.core.VCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<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 artifactName="PIasynSrcHg" buildProperties="" description="linux-x86-debug" id="0.1864894712" name="Debug" parent="org.eclipse.cdt.build.core.prefbase.cfg">
<folderInfo id="0.1864894712." name="/" resourcePath="">
<toolChain id="org.eclipse.cdt.build.core.prefbase.toolchain.989405490" name="No ToolChain" resourceTypeBasedDiscovery="false" superClass="org.eclipse.cdt.build.core.prefbase.toolchain">
<targetPlatform id="org.eclipse.cdt.build.core.prefbase.toolchain.989405490.193624300" name=""/>
<builder buildPath="${workspace_loc:/PIasynSrcHg}" id="org.eclipse.cdt.build.core.settings.default.builder.1962974436" keepEnvironmentInBuildfile="false" managedBuildOn="false" name="Gnu Make Builder" superClass="org.eclipse.cdt.build.core.settings.default.builder"/>
<tool id="org.eclipse.cdt.build.core.settings.holder.libs.214165044" name="holder for library settings" superClass="org.eclipse.cdt.build.core.settings.holder.libs"/>
<tool id="org.eclipse.cdt.build.core.settings.holder.561098644" name="Assembly" superClass="org.eclipse.cdt.build.core.settings.holder">
<inputType id="org.eclipse.cdt.build.core.settings.holder.inType.444003453" languageId="org.eclipse.cdt.core.assembly" languageName="Assembly" sourceContentType="org.eclipse.cdt.core.asmSource" superClass="org.eclipse.cdt.build.core.settings.holder.inType"/>
</tool>
<tool id="org.eclipse.cdt.build.core.settings.holder.708287581" name="GNU C++" superClass="org.eclipse.cdt.build.core.settings.holder">
<inputType id="org.eclipse.cdt.build.core.settings.holder.inType.1675982262" languageId="org.eclipse.cdt.core.g++" languageName="GNU C++" sourceContentType="org.eclipse.cdt.core.cxxSource,org.eclipse.cdt.core.cxxHeader" superClass="org.eclipse.cdt.build.core.settings.holder.inType"/>
</tool>
<tool id="org.eclipse.cdt.build.core.settings.holder.1921784774" name="GNU C" superClass="org.eclipse.cdt.build.core.settings.holder">
<inputType id="org.eclipse.cdt.build.core.settings.holder.inType.141379334" languageId="org.eclipse.cdt.core.gcc" languageName="GNU C" sourceContentType="org.eclipse.cdt.core.cSource,org.eclipse.cdt.core.cHeader" superClass="org.eclipse.cdt.build.core.settings.holder.inType"/>
</tool>
</toolChain>
</folderInfo>
</configuration>
</storageModule>
<storageModule moduleId="scannerConfiguration">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerProjectProfile">
<buildOutputProvider>
<openAction enabled="true" filePath=""/>
<parser enabled="true"/>
</buildOutputProvider>
<scannerInfoProvider id="specsFile">
<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
<parser enabled="true"/>
</scannerInfoProvider>
</profile>
<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerFileProfile">
<buildOutputProvider>
<openAction enabled="true" filePath=""/>
<parser enabled="true"/>
</buildOutputProvider>
<scannerInfoProvider id="makefileGenerator">
<runAction arguments="-E -P -v -dD" command="" useDefault="true"/>
<parser enabled="true"/>
</scannerInfoProvider>
</profile>
<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfile">
<buildOutputProvider>
<openAction enabled="true" filePath=""/>
<parser enabled="true"/>
</buildOutputProvider>
<scannerInfoProvider id="specsFile">
<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
<parser enabled="true"/>
</scannerInfoProvider>
</profile>
<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileCPP">
<buildOutputProvider>
<openAction enabled="true" filePath=""/>
<parser enabled="true"/>
</buildOutputProvider>
<scannerInfoProvider id="specsFile">
<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.cpp" command="g++" useDefault="true"/>
<parser enabled="true"/>
</scannerInfoProvider>
</profile>
<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC">
<buildOutputProvider>
<openAction enabled="true" filePath=""/>
<parser enabled="true"/>
</buildOutputProvider>
<scannerInfoProvider id="specsFile">
<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.c" command="gcc" useDefault="true"/>
<parser enabled="true"/>
</scannerInfoProvider>
</profile>
<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfile">
<buildOutputProvider>
<openAction enabled="true" filePath=""/>
<parser enabled="true"/>
</buildOutputProvider>
<scannerInfoProvider id="specsFile">
<runAction arguments="-c 'gcc -E -P -v -dD &quot;${plugin_state_location}/${specs_file}&quot;'" command="sh" useDefault="true"/>
<parser enabled="true"/>
</scannerInfoProvider>
</profile>
<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileCPP">
<buildOutputProvider>
<openAction enabled="true" filePath=""/>
<parser enabled="true"/>
</buildOutputProvider>
<scannerInfoProvider id="specsFile">
<runAction arguments="-c 'g++ -E -P -v -dD &quot;${plugin_state_location}/specs.cpp&quot;'" command="sh" useDefault="true"/>
<parser enabled="true"/>
</scannerInfoProvider>
</profile>
<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileC">
<buildOutputProvider>
<openAction enabled="true" filePath=""/>
<parser enabled="true"/>
</buildOutputProvider>
<scannerInfoProvider id="specsFile">
<runAction arguments="-c 'gcc -E -P -v -dD &quot;${plugin_state_location}/specs.c&quot;'" command="sh" useDefault="true"/>
<parser enabled="true"/>
</scannerInfoProvider>
</profile>
<scannerConfigBuildInfo instanceId="0.1624471516">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerProjectProfile">
<buildOutputProvider>
<openAction enabled="true" filePath=""/>
<parser enabled="true"/>
</buildOutputProvider>
<scannerInfoProvider id="specsFile">
<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
<parser enabled="true"/>
</scannerInfoProvider>
</profile>
<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerFileProfile">
<buildOutputProvider>
<openAction enabled="true" filePath=""/>
<parser enabled="true"/>
</buildOutputProvider>
<scannerInfoProvider id="makefileGenerator">
<runAction arguments="-E -P -v -dD" command="" useDefault="true"/>
<parser enabled="true"/>
</scannerInfoProvider>
</profile>
<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfile">
<buildOutputProvider>
<openAction enabled="true" filePath=""/>
<parser enabled="true"/>
</buildOutputProvider>
<scannerInfoProvider id="specsFile">
<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
<parser enabled="true"/>
</scannerInfoProvider>
</profile>
<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileCPP">
<buildOutputProvider>
<openAction enabled="true" filePath=""/>
<parser enabled="true"/>
</buildOutputProvider>
<scannerInfoProvider id="specsFile">
<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.cpp" command="g++" useDefault="true"/>
<parser enabled="true"/>
</scannerInfoProvider>
</profile>
<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC">
<buildOutputProvider>
<openAction enabled="true" filePath=""/>
<parser enabled="true"/>
</buildOutputProvider>
<scannerInfoProvider id="specsFile">
<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.c" command="gcc" useDefault="true"/>
<parser enabled="true"/>
</scannerInfoProvider>
</profile>
<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfile">
<buildOutputProvider>
<openAction enabled="true" filePath=""/>
<parser enabled="true"/>
</buildOutputProvider>
<scannerInfoProvider id="specsFile">
<runAction arguments="-c 'gcc -E -P -v -dD &quot;${plugin_state_location}/${specs_file}&quot;'" command="sh" useDefault="true"/>
<parser enabled="true"/>
</scannerInfoProvider>
</profile>
<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileCPP">
<buildOutputProvider>
<openAction enabled="true" filePath=""/>
<parser enabled="true"/>
</buildOutputProvider>
<scannerInfoProvider id="specsFile">
<runAction arguments="-c 'g++ -E -P -v -dD &quot;${plugin_state_location}/specs.cpp&quot;'" command="sh" useDefault="true"/>
<parser enabled="true"/>
</scannerInfoProvider>
</profile>
<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileC">
<buildOutputProvider>
<openAction enabled="true" filePath=""/>
<parser enabled="true"/>
</buildOutputProvider>
<scannerInfoProvider id="specsFile">
<runAction arguments="-c 'gcc -E -P -v -dD &quot;${plugin_state_location}/specs.c&quot;'" command="sh" useDefault="true"/>
<parser enabled="true"/>
</scannerInfoProvider>
</profile>
</scannerConfigBuildInfo>
<scannerConfigBuildInfo instanceId="0.1864894712">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerProjectProfile">
<buildOutputProvider>
<openAction enabled="true" filePath=""/>
<parser enabled="true"/>
</buildOutputProvider>
<scannerInfoProvider id="specsFile">
<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
<parser enabled="true"/>
</scannerInfoProvider>
</profile>
<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerFileProfile">
<buildOutputProvider>
<openAction enabled="true" filePath=""/>
<parser enabled="true"/>
</buildOutputProvider>
<scannerInfoProvider id="makefileGenerator">
<runAction arguments="-E -P -v -dD" command="" useDefault="true"/>
<parser enabled="true"/>
</scannerInfoProvider>
</profile>
<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfile">
<buildOutputProvider>
<openAction enabled="true" filePath=""/>
<parser enabled="true"/>
</buildOutputProvider>
<scannerInfoProvider id="specsFile">
<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
<parser enabled="true"/>
</scannerInfoProvider>
</profile>
<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileCPP">
<buildOutputProvider>
<openAction enabled="true" filePath=""/>
<parser enabled="true"/>
</buildOutputProvider>
<scannerInfoProvider id="specsFile">
<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.cpp" command="g++" useDefault="true"/>
<parser enabled="true"/>
</scannerInfoProvider>
</profile>
<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC">
<buildOutputProvider>
<openAction enabled="true" filePath=""/>
<parser enabled="true"/>
</buildOutputProvider>
<scannerInfoProvider id="specsFile">
<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.c" command="gcc" useDefault="true"/>
<parser enabled="true"/>
</scannerInfoProvider>
</profile>
<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfile">
<buildOutputProvider>
<openAction enabled="true" filePath=""/>
<parser enabled="true"/>
</buildOutputProvider>
<scannerInfoProvider id="specsFile">
<runAction arguments="-c 'gcc -E -P -v -dD &quot;${plugin_state_location}/${specs_file}&quot;'" command="sh" useDefault="true"/>
<parser enabled="true"/>
</scannerInfoProvider>
</profile>
<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileCPP">
<buildOutputProvider>
<openAction enabled="true" filePath=""/>
<parser enabled="true"/>
</buildOutputProvider>
<scannerInfoProvider id="specsFile">
<runAction arguments="-c 'g++ -E -P -v -dD &quot;${plugin_state_location}/specs.cpp&quot;'" command="sh" useDefault="true"/>
<parser enabled="true"/>
</scannerInfoProvider>
</profile>
<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileC">
<buildOutputProvider>
<openAction enabled="true" filePath=""/>
<parser enabled="true"/>
</buildOutputProvider>
<scannerInfoProvider id="specsFile">
<runAction arguments="-c 'gcc -E -P -v -dD &quot;${plugin_state_location}/specs.c&quot;'" command="sh" useDefault="true"/>
<parser enabled="true"/>
</scannerInfoProvider>
</profile>
</scannerConfigBuildInfo>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
<storageModule moduleId="org.eclipse.cdt.core.language.mapping"/>
<storageModule moduleId="org.eclipse.cdt.internal.ui.text.commentOwnerProjectMappings"/>
</cconfiguration>
<cconfiguration id="0.1864894712.1771981055">
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="0.1864894712.1771981055" moduleId="org.eclipse.cdt.core.settings" name="Release">
<macros>
<stringMacro name="EPICS_HOST_ARCH" type="VALUE_TEXT" value="linux-x86"/>
</macros>
<externalSettings/>
<extensions>
<extension id="org.eclipse.cdt.core.VCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<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 buildProperties="" description="linux-x86" id="0.1864894712.1771981055" name="Release" parent="org.eclipse.cdt.build.core.prefbase.cfg">
<folderInfo id="0.1864894712.1771981055." name="/" resourcePath="">
<toolChain id="org.eclipse.cdt.build.core.prefbase.toolchain.868478225" name="No ToolChain" resourceTypeBasedDiscovery="false" superClass="org.eclipse.cdt.build.core.prefbase.toolchain">
<targetPlatform id="org.eclipse.cdt.build.core.prefbase.toolchain.868478225.132781498" name=""/>
<builder id="org.eclipse.cdt.build.core.settings.default.builder.769300020" keepEnvironmentInBuildfile="false" managedBuildOn="false" name="Gnu Make Builder" superClass="org.eclipse.cdt.build.core.settings.default.builder"/>
<tool id="org.eclipse.cdt.build.core.settings.holder.libs.237853117" name="holder for library settings" superClass="org.eclipse.cdt.build.core.settings.holder.libs"/>
<tool id="org.eclipse.cdt.build.core.settings.holder.63972889" name="Assembly" superClass="org.eclipse.cdt.build.core.settings.holder">
<inputType id="org.eclipse.cdt.build.core.settings.holder.inType.894030566" languageId="org.eclipse.cdt.core.assembly" languageName="Assembly" sourceContentType="org.eclipse.cdt.core.asmSource" superClass="org.eclipse.cdt.build.core.settings.holder.inType"/>
</tool>
<tool id="org.eclipse.cdt.build.core.settings.holder.556486508" name="GNU C++" superClass="org.eclipse.cdt.build.core.settings.holder">
<inputType id="org.eclipse.cdt.build.core.settings.holder.inType.849152430" languageId="org.eclipse.cdt.core.g++" languageName="GNU C++" sourceContentType="org.eclipse.cdt.core.cxxSource,org.eclipse.cdt.core.cxxHeader" superClass="org.eclipse.cdt.build.core.settings.holder.inType"/>
</tool>
<tool id="org.eclipse.cdt.build.core.settings.holder.2054850057" name="GNU C" superClass="org.eclipse.cdt.build.core.settings.holder">
<inputType id="org.eclipse.cdt.build.core.settings.holder.inType.1101777661" languageId="org.eclipse.cdt.core.gcc" languageName="GNU C" sourceContentType="org.eclipse.cdt.core.cSource,org.eclipse.cdt.core.cHeader" superClass="org.eclipse.cdt.build.core.settings.holder.inType"/>
</tool>
</toolChain>
</folderInfo>
</configuration>
</storageModule>
<storageModule moduleId="scannerConfiguration">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerProjectProfile">
<buildOutputProvider>
<openAction enabled="true" filePath=""/>
<parser enabled="true"/>
</buildOutputProvider>
<scannerInfoProvider id="specsFile">
<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
<parser enabled="true"/>
</scannerInfoProvider>
</profile>
<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerFileProfile">
<buildOutputProvider>
<openAction enabled="true" filePath=""/>
<parser enabled="true"/>
</buildOutputProvider>
<scannerInfoProvider id="makefileGenerator">
<runAction arguments="-E -P -v -dD" command="" useDefault="true"/>
<parser enabled="true"/>
</scannerInfoProvider>
</profile>
<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfile">
<buildOutputProvider>
<openAction enabled="true" filePath=""/>
<parser enabled="true"/>
</buildOutputProvider>
<scannerInfoProvider id="specsFile">
<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
<parser enabled="true"/>
</scannerInfoProvider>
</profile>
<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileCPP">
<buildOutputProvider>
<openAction enabled="true" filePath=""/>
<parser enabled="true"/>
</buildOutputProvider>
<scannerInfoProvider id="specsFile">
<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.cpp" command="g++" useDefault="true"/>
<parser enabled="true"/>
</scannerInfoProvider>
</profile>
<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC">
<buildOutputProvider>
<openAction enabled="true" filePath=""/>
<parser enabled="true"/>
</buildOutputProvider>
<scannerInfoProvider id="specsFile">
<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.c" command="gcc" useDefault="true"/>
<parser enabled="true"/>
</scannerInfoProvider>
</profile>
<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfile">
<buildOutputProvider>
<openAction enabled="true" filePath=""/>
<parser enabled="true"/>
</buildOutputProvider>
<scannerInfoProvider id="specsFile">
<runAction arguments="-c 'gcc -E -P -v -dD &quot;${plugin_state_location}/${specs_file}&quot;'" command="sh" useDefault="true"/>
<parser enabled="true"/>
</scannerInfoProvider>
</profile>
<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileCPP">
<buildOutputProvider>
<openAction enabled="true" filePath=""/>
<parser enabled="true"/>
</buildOutputProvider>
<scannerInfoProvider id="specsFile">
<runAction arguments="-c 'g++ -E -P -v -dD &quot;${plugin_state_location}/specs.cpp&quot;'" command="sh" useDefault="true"/>
<parser enabled="true"/>
</scannerInfoProvider>
</profile>
<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileC">
<buildOutputProvider>
<openAction enabled="true" filePath=""/>
<parser enabled="true"/>
</buildOutputProvider>
<scannerInfoProvider id="specsFile">
<runAction arguments="-c 'gcc -E -P -v -dD &quot;${plugin_state_location}/specs.c&quot;'" command="sh" useDefault="true"/>
<parser enabled="true"/>
</scannerInfoProvider>
</profile>
<scannerConfigBuildInfo instanceId="0.1624471516">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerProjectProfile">
<buildOutputProvider>
<openAction enabled="true" filePath=""/>
<parser enabled="true"/>
</buildOutputProvider>
<scannerInfoProvider id="specsFile">
<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
<parser enabled="true"/>
</scannerInfoProvider>
</profile>
<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerFileProfile">
<buildOutputProvider>
<openAction enabled="true" filePath=""/>
<parser enabled="true"/>
</buildOutputProvider>
<scannerInfoProvider id="makefileGenerator">
<runAction arguments="-E -P -v -dD" command="" useDefault="true"/>
<parser enabled="true"/>
</scannerInfoProvider>
</profile>
<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfile">
<buildOutputProvider>
<openAction enabled="true" filePath=""/>
<parser enabled="true"/>
</buildOutputProvider>
<scannerInfoProvider id="specsFile">
<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
<parser enabled="true"/>
</scannerInfoProvider>
</profile>
<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileCPP">
<buildOutputProvider>
<openAction enabled="true" filePath=""/>
<parser enabled="true"/>
</buildOutputProvider>
<scannerInfoProvider id="specsFile">
<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.cpp" command="g++" useDefault="true"/>
<parser enabled="true"/>
</scannerInfoProvider>
</profile>
<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC">
<buildOutputProvider>
<openAction enabled="true" filePath=""/>
<parser enabled="true"/>
</buildOutputProvider>
<scannerInfoProvider id="specsFile">
<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.c" command="gcc" useDefault="true"/>
<parser enabled="true"/>
</scannerInfoProvider>
</profile>
<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfile">
<buildOutputProvider>
<openAction enabled="true" filePath=""/>
<parser enabled="true"/>
</buildOutputProvider>
<scannerInfoProvider id="specsFile">
<runAction arguments="-c 'gcc -E -P -v -dD &quot;${plugin_state_location}/${specs_file}&quot;'" command="sh" useDefault="true"/>
<parser enabled="true"/>
</scannerInfoProvider>
</profile>
<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileCPP">
<buildOutputProvider>
<openAction enabled="true" filePath=""/>
<parser enabled="true"/>
</buildOutputProvider>
<scannerInfoProvider id="specsFile">
<runAction arguments="-c 'g++ -E -P -v -dD &quot;${plugin_state_location}/specs.cpp&quot;'" command="sh" useDefault="true"/>
<parser enabled="true"/>
</scannerInfoProvider>
</profile>
<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileC">
<buildOutputProvider>
<openAction enabled="true" filePath=""/>
<parser enabled="true"/>
</buildOutputProvider>
<scannerInfoProvider id="specsFile">
<runAction arguments="-c 'gcc -E -P -v -dD &quot;${plugin_state_location}/specs.c&quot;'" command="sh" useDefault="true"/>
<parser enabled="true"/>
</scannerInfoProvider>
</profile>
</scannerConfigBuildInfo>
<scannerConfigBuildInfo instanceId="0.1864894712">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerProjectProfile">
<buildOutputProvider>
<openAction enabled="true" filePath=""/>
<parser enabled="true"/>
</buildOutputProvider>
<scannerInfoProvider id="specsFile">
<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
<parser enabled="true"/>
</scannerInfoProvider>
</profile>
<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerFileProfile">
<buildOutputProvider>
<openAction enabled="true" filePath=""/>
<parser enabled="true"/>
</buildOutputProvider>
<scannerInfoProvider id="makefileGenerator">
<runAction arguments="-E -P -v -dD" command="" useDefault="true"/>
<parser enabled="true"/>
</scannerInfoProvider>
</profile>
<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfile">
<buildOutputProvider>
<openAction enabled="true" filePath=""/>
<parser enabled="true"/>
</buildOutputProvider>
<scannerInfoProvider id="specsFile">
<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
<parser enabled="true"/>
</scannerInfoProvider>
</profile>
<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileCPP">
<buildOutputProvider>
<openAction enabled="true" filePath=""/>
<parser enabled="true"/>
</buildOutputProvider>
<scannerInfoProvider id="specsFile">
<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.cpp" command="g++" useDefault="true"/>
<parser enabled="true"/>
</scannerInfoProvider>
</profile>
<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC">
<buildOutputProvider>
<openAction enabled="true" filePath=""/>
<parser enabled="true"/>
</buildOutputProvider>
<scannerInfoProvider id="specsFile">
<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.c" command="gcc" useDefault="true"/>
<parser enabled="true"/>
</scannerInfoProvider>
</profile>
<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfile">
<buildOutputProvider>
<openAction enabled="true" filePath=""/>
<parser enabled="true"/>
</buildOutputProvider>
<scannerInfoProvider id="specsFile">
<runAction arguments="-c 'gcc -E -P -v -dD &quot;${plugin_state_location}/${specs_file}&quot;'" command="sh" useDefault="true"/>
<parser enabled="true"/>
</scannerInfoProvider>
</profile>
<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileCPP">
<buildOutputProvider>
<openAction enabled="true" filePath=""/>
<parser enabled="true"/>
</buildOutputProvider>
<scannerInfoProvider id="specsFile">
<runAction arguments="-c 'g++ -E -P -v -dD &quot;${plugin_state_location}/specs.cpp&quot;'" command="sh" useDefault="true"/>
<parser enabled="true"/>
</scannerInfoProvider>
</profile>
<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileC">
<buildOutputProvider>
<openAction enabled="true" filePath=""/>
<parser enabled="true"/>
</buildOutputProvider>
<scannerInfoProvider id="specsFile">
<runAction arguments="-c 'gcc -E -P -v -dD &quot;${plugin_state_location}/specs.c&quot;'" command="sh" useDefault="true"/>
<parser enabled="true"/>
</scannerInfoProvider>
</profile>
</scannerConfigBuildInfo>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
<storageModule moduleId="org.eclipse.cdt.core.language.mapping"/>
<storageModule moduleId="org.eclipse.cdt.internal.ui.text.commentOwnerProjectMappings"/>
</cconfiguration>
</storageModule>
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
<project id="PIasynSrcHg.null.746367885" name="PIasynSrcHg"/>
</storageModule>
</cproject>
+83
View File
@@ -0,0 +1,83 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>PIasynSrcHg</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name>
<triggers>clean,full,incremental,</triggers>
<arguments>
<dictionary>
<key>?name?</key>
<value></value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.append_environment</key>
<value>true</value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.autoBuildTarget</key>
<value>all</value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.buildArguments</key>
<value></value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.buildCommand</key>
<value>make</value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.buildLocation</key>
<value>${workspace_loc:/PIasynSrcHg}</value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.cleanBuildTarget</key>
<value>clean</value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.contents</key>
<value>org.eclipse.cdt.make.core.activeConfigSettings</value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.enableAutoBuild</key>
<value>false</value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.enableCleanBuild</key>
<value>true</value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.enableFullBuild</key>
<value>true</value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.fullBuildTarget</key>
<value>all</value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.stopOnError</key>
<value>true</value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.useDefaultBuildCmd</key>
<value>true</value>
</dictionary>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name>
<triggers>full,incremental,</triggers>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.cdt.core.cnature</nature>
<nature>org.eclipse.cdt.core.ccnature</nature>
<nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
<nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
</natures>
</projectDescription>
+23
View File
@@ -0,0 +1,23 @@
TOP=../..
include $(TOP)/configure/CONFIG
#----------------------------------------
# ADD MACRO DEFINITIONS AFTER THIS LINE
#----------------------------------------------------
# Optimization of db files using dbst (DEFAULT: NO)
#DB_OPT = YES
#----------------------------------------------------
# Create and install (or just install) into <top>/db
# databases, templates, substitutions like this
DB += PI_Support.db
DB += PI_SupportCtrl.db
#----------------------------------------------------
# If <anyname>.db template is not named <anyname>*.template add
# <anyname>_template = <templatename>
include $(TOP)/configure/RULES
#----------------------------------------
# ADD RULES AFTER THIS LINE
+7
View File
@@ -0,0 +1,7 @@
TOP = ..
include $(TOP)/configure/CONFIG
DIRS := $(DIRS) $(filter-out $(DIRS), $(wildcard *src*))
DIRS := $(DIRS) $(filter-out $(DIRS), $(wildcard *Src*))
DIRS := $(DIRS) $(filter-out $(DIRS), $(wildcard *db*))
DIRS := $(DIRS) $(filter-out $(DIRS), $(wildcard *Db*))
include $(TOP)/configure/RULES_DIRS
+36
View File
@@ -0,0 +1,36 @@
TOP=../..
include $(TOP)/configure/CONFIG
#----------------------------------------
# ADD MACRO DEFINITIONS AFTER THIS LINE
#=============================
#==================================================
# Build an IOC support library
LIBRARY_IOC += PI_GCS2Support
# motorRecord.h will be created from motorRecord.dbd
# install devMotorSoft.dbd into <top>/dbd
DBD += PI_GCS2Support.dbd
# The following are compiled and added to the Support library
PI_GCS2Support_SRCS += PIasynController.cpp
PI_GCS2Support_SRCS += PIasynAxis.cpp
PI_GCS2Support_SRCS += PIGCSController.cpp
PI_GCS2Support_SRCS += PIGCSMotorController.cpp
PI_GCS2Support_SRCS += PIGCSPiezoController.cpp
PI_GCS2Support_SRCS += PIE517Controller.cpp
PI_GCS2Support_SRCS += PIE755Controller.cpp
PI_GCS2Support_SRCS += PIHexapodController.cpp
PI_GCS2Support_SRCS += PIC702Controller.cpp
PI_GCS2Support_SRCS += translateerror.c
PI_GCS2Support_LIBS += motor
PI_GCS2Support_LIBS += asyn
PI_GCS2Support_LIBS += $(EPICS_BASE_IOC_LIBS)
include $(TOP)/configure/RULES
#----------------------------------------
# ADD RULES AFTER THIS LINE
@@ -0,0 +1,187 @@
/*
* PIC702Controller
*
* Author: sra
*/
#include "PIC702Controller.h"
#include "PIasynAxis.h"
#include <stdlib.h>
#include <math.h>
//#undef asynPrint
//#define asynPrint(user,reason,format...) 0
asynStatus PIC702Controller::getStatus(PIasynAxis* pAxis, int& homing, int& moving, int& negLimit, int& posLimit, int& servoControl)
{
int busy;
epicsTimeStamp now;
epicsTimeGetCurrent(&now);
if(epicsTimeDiffInSeconds(&now,&m_timeREFstarted) < 1.0)
{
homing = 1;
moving = 1;
return asynSuccess;
}
asynStatus status = getBusy(pAxis, busy);
if (status != asynSuccess)
{
return status;
}
negLimit = 0;
posLimit = 0;
homing = busy;
if (busy)
{
moving = busy;
return status;
}
status = getMoving(pAxis, moving);
if (status != asynSuccess)
{
return status;
}
return status;
}
asynStatus PIC702Controller::findConnectedAxes()
{
// GCS! - axes are not separated by LineFeeds
// axis identifier is only one single char, all axes returned as single "word"
m_nrFoundAxes = 0;
for (size_t i=0; i<MAX_NR_AXES; i++)
{
m_axesIDs[i] = NULL;
}
char allAxesIDs[127];
asynStatus status = PIGCSController::sendAndReceive("SAI?", allAxesIDs, 127);
if (asynSuccess != status)
{
return status;
}
m_nrFoundAxes = strlen(allAxesIDs);
if (MAX_NR_AXES <= m_nrFoundAxes)
{
return asynError;
}
char* p = m_allAxesIDs;
for (size_t i=0; i<m_nrFoundAxes; i++)
{
*p = allAxesIDs[m_nrFoundAxes - 1 - i];
m_axesIDs[i] = p;
p++;
*p = '\0';
p++;
}
return status;
}
asynStatus PIC702Controller::getMaxAcceleration(PIasynAxis* pAxis)
{
double maxAcc, maxDec;
asynStatus status = getGCSParameter(pAxis, PI_PARA_MOT_CURR_ACCEL, maxAcc);
if (asynSuccess != status)
return status;
status = getGCSParameter(pAxis, PI_PARA_MOT_CURR_DECEL, maxDec);
if (asynSuccess != status)
return status;
if (maxAcc < maxDec)
{
pAxis->m_maxAcceleration = maxAcc;
}
else
{
pAxis->m_maxAcceleration = maxDec;
}
return status;
}
asynStatus PIC702Controller::hasReferenceSensor(PIasynAxis* pAxis)
{
double hasref;
asynStatus status = getGCSParameter(pAxis, PI_PARA_MOT_HAT_REF, hasref);
if (asynSuccess != status)
{
return status;
}
pAxis->m_bHasReference = hasref > 0.1;
asynPrint(m_pCurrentLogSink, ASYN_TRACE_FLOW,
"PIC702Controller::hasReferenceSwitch() axis has %sreference sensor\n",
pAxis->m_bHasReference?"":"no ");
return status;
}
asynStatus PIC702Controller::getReferencedState(PIasynAxis* pAxis)
{
double isref;
asynStatus status = getGCSParameter(pAxis, PI_PARA_C702_REFERENCED, isref);
if (status != asynSuccess)
{
return status;
}
pAxis->m_homed = (isref > 0.1)?1:0;
return status;
}
asynStatus PIC702Controller::referenceVelCts( PIasynAxis* pAxis, double velocity, int forwards)
{
asynStatus status = setServo(pAxis, 1);
if (asynSuccess != status)
return status;
status = setVelocityCts(pAxis, velocity);
if (asynSuccess != status)
return status;
char cmd[100];
if (pAxis->m_bHasReference)
{
// call REF - find reference
sprintf(cmd,"REF %s", pAxis->m_szAxisName);
}
else if (pAxis->m_bHasLimitSwitches)
{
if (forwards)
{
// call MPL - find positive limit switch
sprintf(cmd,"MPL %s", pAxis->m_szAxisName);
}
else
{
// call MNL - find negative limit switch
sprintf(cmd,"MNL %s", pAxis->m_szAxisName);
}
}
else
{
asynPrint(m_pCurrentLogSink, ASYN_TRACE_ERROR,
"PIC702Controller::referenceVelCts() failed - axis has no reference/limit switch\n");
epicsSnprintf(pAxis->m_pasynUser->errorMessage,pAxis->m_pasynUser->errorMessageSize,
"PIC702Controller::referenceVelCts() failed - axis has no reference/limit switch\n");
return asynError;
}
status = sendOnly(cmd);
if (asynSuccess != status)
{
asynPrint(m_pCurrentLogSink, ASYN_TRACE_ERROR,
"PIC702Controller::referenceVelCts() failed\n");
return status;
}
pAxis->m_isHoming = 1;
epicsTimeGetCurrent(&m_timeREFstarted);
return asynSuccess;
}
@@ -0,0 +1,45 @@
/*
* PIC702Controller.h
*
* Author: sra
*/
#ifndef PIC702CONTROLLER_H_
#define PIC702CONTROLLER_H_
#include "PIGCSMotorController.h"
#include <epicsTime.h>
/**
* class representing PI C-702.
*
*/
class PIC702Controller : public PIGCSMotorController
{
public:
PIC702Controller(asynUser* pCom, const char* szIDN)
: PIGCSMotorController(pCom, szIDN)
{
}
~PIC702Controller() {}
virtual asynStatus getStatus(PIasynAxis* pAxis, int& homing, int& moving, int& negLimit, int& posLimit, int& servoControl);
virtual asynStatus getMaxAcceleration( PIasynAxis* pAxis );
virtual asynStatus hasReferenceSensor(PIasynAxis* pAxis);
virtual asynStatus getReferencedState(PIasynAxis* axis);
virtual asynStatus referenceVelCts( PIasynAxis* pAxis, double velocity, int forwards);
virtual bool IsGCS2() { return false; }
protected:
virtual asynStatus findConnectedAxes();
enum
{
PI_PARA_C702_REFERENCED = 0x000001CUL
};
private:
epicsTimeStamp m_timeREFstarted;
};
#endif /* PIC702CONTROLLER_H_ */
@@ -0,0 +1,73 @@
/*
* PIGCSPiezoController
*
* Created on: 15.12.2010
* Author: sra
*/
#include "PIE517Controller.h"
#include "PIasynAxis.h"
#include <stdlib.h>
#include <math.h>
#undef asynPrint
#define asynPrint(user,reason,format...) 0
asynStatus PIE517Controller::init()
{
asynStatus status;
status = PIGCSPiezoController::init();
if (asynSuccess != status)
{
return status;
}
// all output channels need to be set "online" before
// any commands are accepted over the interface.
status = getNrOutputChannels();
if (asynSuccess != status)
{
return status;
}
for (int ch=1; ch<=m_nrOutputChannels; ch++)
{
status = setOnline(ch, 1);
if (asynSuccess != status)
{
return status;
}
}
return status;
}
asynStatus PIE517Controller::setOnline(int channel, int onlineState)
{
char cmd[100];
sprintf(cmd, "ONL %d %d", channel, onlineState);
asynStatus status = sendOnly(cmd);
return status;
}
asynStatus PIE517Controller::getNrOutputChannels()
{
char buf[255];
asynStatus status = sendAndReceive("TPC?", buf, 99);
if (status != asynSuccess)
{
return status;
}
m_nrOutputChannels = atoi(buf);
return status;
}
asynStatus PIE517Controller::initAxis(PIasynAxis* pAxis)
{
pAxis->m_movingStateMask = pow(2.0, pAxis->getAxisNo());
return setServo(pAxis, 1);
}
@@ -0,0 +1,42 @@
/*
* PIGCScontroller.h
*
* Created on: 15.12.2010
* Author: sra
*/
#ifndef PIE517CONTROLLER_H_
#define PIE517CONTROLLER_H_
#include "PIGCSPiezoController.h"
/**
* class representing PI E-517 and E-545 controllers.
*
* Basically these controllers have the same functionality as a
* digital piezo controller. Specialties are "velocity control" mode
* and the "online" state. Output channels must be set to "online" mode
* before commands are accepted over the interface. This is done in
* init()
*/
class PIE517Controller : public PIGCSPiezoController
{
public:
PIE517Controller(asynUser* pCom, const char* szIDN)
: PIGCSPiezoController(pCom, szIDN)
{
}
~PIE517Controller() {}
virtual asynStatus init(void);
virtual asynStatus initAxis(PIasynAxis* pAxis);
private:
asynStatus setOnline(int outputChannel, int onlineState);
asynStatus getNrOutputChannels();
int m_nrOutputChannels;
};
#endif /* PIE517CONTROLLER_H_ */
@@ -0,0 +1,40 @@
/*
* PIE755Controller
*
* Author: sra
*/
#include "PIE755Controller.h"
#include "PIasynAxis.h"
#include <stdlib.h>
#undef asynPrint
#define asynPrint(user,reason,format...) 0
asynStatus PIE755Controller::getStatus(PIasynAxis* pAxis, int& homing, int& moving, int& negLimit, int& posLimit, int& servoControl)
{
int busy;
asynStatus status = getBusy(pAxis, busy);
if (status != asynSuccess)
{
return status;
}
negLimit = 0;
posLimit = 0;
homing = busy;
if (busy)
{
moving = busy;
return status;
}
status = getMoving(pAxis, moving);
if (status != asynSuccess)
{
return status;
}
return status;
}
@@ -0,0 +1,41 @@
/*
* PIE755Controller.h
*
* Author: sra
*/
#ifndef PIE755CONTROLLER_H_
#define PIE755CONTROLLER_H_
#include "PIGCSMotorController.h"
/**
* class representing PI E-755.
*
* These controllers share most of the parameters with digital piezo controllers.
* Encoders for Nexline stages are often only incremental, so they need to be homed.
* Homing works with "hard stops" and "Limit switches".
* From an EPICS point of view this behaves more like a motor than a piezo controller.
*/
class PIE755Controller : public PIGCSMotorController
{
public:
PIE755Controller(asynUser* pCom, const char* szIDN)
: PIGCSMotorController(pCom, szIDN)
{
}
~PIE755Controller() {}
virtual asynStatus getResolution(PIasynAxis* pAxis, double& resolution )
{
return PIGCSController::getResolution(pAxis, resolution);
}
virtual asynStatus setAccelerationCts( PIasynAxis* pAxis, double acceleration) { return asynSuccess; }
virtual asynStatus setAcceleration( PIasynAxis* pAxis, double acceleration) { return asynSuccess; }
virtual asynStatus getStatus(PIasynAxis* pAxis, int& homing, int& moving, int& negLimit, int& posLimit, int& servoControl);
private:
};
#endif /* PIE755CONTROLLER_H_ */
@@ -0,0 +1,811 @@
/*
* PIGCSController.cpp
*
* Created on: 15.12.2010
* Author: sra
*/
#include <asynOctetSyncIO.h>
#include <math.h>
#include <stdlib.h>
#include "PIGCSController.h"
#include "PIasynAxis.h"
#include "PIGCSMotorController.h"
#include "PIGCSPiezoController.h"
#include "PIE517Controller.h"
#include "PIE755Controller.h"
#include "PIHexapodController.h"
#include "PIC702Controller.h"
//#undef asynPrint
//#define asynPrint(user,reason,format...) 0
extern "C" {
int TranslatePIError(const int error, char* szBuffer, const int maxlen);
}
double PIGCSController::TIMEOUT = 5.0;
/**
* create instance of GCS controller depending on identification (\a szIDN)
*/
PIGCSController* PIGCSController::CreateGCSController(asynUser* pInterface, const char* szIDN)
{
if ( strstr(szIDN, "C-663") != NULL
|| strstr(szIDN, "C-863") != NULL
|| strstr(szIDN, "C-867") != NULL
)
{
return new PIGCSMotorController(pInterface, szIDN);
}
else if ( strstr(szIDN, "E-517") != NULL)
{
return new PIE517Controller(pInterface, szIDN);
}
else if ( strstr(szIDN, "E-755") != NULL)
{
return new PIE755Controller(pInterface, szIDN);
}
else if ( strstr(szIDN, "C-702") != NULL)
{
return new PIC702Controller(pInterface, szIDN);
}
else if ( strstr(szIDN, "HEXAPOD") != NULL
|| strstr(szIDN, "F-HEX") != NULL
|| strstr(szIDN, "F-206") != NULL
|| strstr(szIDN, "M-8") != NULL
|| strstr(szIDN, "C-887") != NULL
)
{
return new PIHexapodController(pInterface, szIDN);
}
else
{
return NULL;
}
}
asynStatus PIGCSController::sendOnly(asynUser* pInterface, const char *outputBuff, asynUser* logSink)
{
size_t nRequested=strlen(outputBuff);
size_t nActual;
asynStatus status;
asynPrint(logSink, ASYN_TRACEIO_DRIVER,
"PIGCSController::sendOnly() sending \"%s\"\n", outputBuff);
//printf("PIGCSController::sendOnly() sending \"%s\"\n", outputBuff);
status = pasynOctetSyncIO->write(pInterface, outputBuff,
nRequested, TIMEOUT, &nActual);
if (nActual != nRequested)
status = asynError;
status = pasynOctetSyncIO->write(pInterface, "\n",
1, TIMEOUT, &nActual);
if (status != asynSuccess)
{
asynPrint(logSink, ASYN_TRACE_ERROR|ASYN_TRACEIO_DRIVER,
"PIGCSController:sendOnly: error sending command %s, sent=%d, status=%d\n",
outputBuff, nActual, status);
}
return(status);
}
asynStatus PIGCSController::sendOnly(asynUser* pInterface, char c, asynUser* logSink)
{
size_t nActual;
asynStatus status;
asynPrint(logSink, ASYN_TRACEIO_DRIVER,
"PIGCSController::sendOnly() sending \"#%d\"\n", int(c));
//printf("PIGCSController::sendOnly() sending \"#%d\"\n", int(c));
status = pasynOctetSyncIO->write(pInterface, &c,
1, TIMEOUT, &nActual);
if (nActual != 1)
status = asynError;
if (status != asynSuccess)
{
asynPrint(logSink, ASYN_TRACE_ERROR|ASYN_TRACEIO_DRIVER,
"PIGCSController:sendOnly: error sending command %d, sent=%d, status=%d\n",
int(c), nActual, status);
//printf("PIGCSController::sendOnly() sending \"#%d\"\n", int(c));
}
return(status);
}
asynStatus PIGCSController::sendAndReceive(asynUser* pInterface, const char *outputBuff, char *inputBuff, int inputSize, asynUser* logSink)
{
size_t nWriteRequested=strlen(outputBuff);
size_t nWrite, nRead;
int eomReason;
asynStatus status;
size_t pos = 0;
asynPrint(logSink, ASYN_TRACEIO_DRIVER,
"PIGCSController::sendAndReceive() sending \"%s\"\n", outputBuff);
// //printf("PIGCSController::sendAndReceive() sending \"%s\"\n", outputBuff);
status = pasynOctetSyncIO->write(pInterface, outputBuff,
nWriteRequested, TIMEOUT, &nWrite);
if (nWrite != nWriteRequested)
{
asynPrint(logSink, ASYN_TRACE_ERROR|ASYN_TRACEIO_DRIVER,
"PIGCSController:sendAndReceive error calling write, output=%s status=%d, error=%s\n",
outputBuff, status, pInterface->errorMessage);
return asynError;
}
status = pasynOctetSyncIO->writeRead(pInterface,
"\n", 1,
inputBuff, inputSize,
TIMEOUT, &nWrite, &nRead, &eomReason);
if (nWrite != 1)
{
asynPrint(logSink, ASYN_TRACE_ERROR|ASYN_TRACEIO_DRIVER,
"PIGCSController:sendAndReceive error calling write, output=%s status=%d, error=%s\n",
outputBuff, status, pInterface->errorMessage);
return asynError;
}
if (status != asynSuccess)
{
asynPrint(logSink, ASYN_TRACE_ERROR|ASYN_TRACEIO_DRIVER,
"PIGCSController:sendAndReceive error calling writeRead, output=%s status=%d, error=%s\n",
outputBuff, status, pInterface->errorMessage);
}
while(inputBuff[strlen(inputBuff)-1] == ' ')
{
inputBuff[strlen(inputBuff)] = '\n';
pos += nRead + 1;
status = pasynOctetSyncIO->read(logSink,
inputBuff+pos, inputSize-pos,
TIMEOUT, &nRead, &eomReason);
}
asynPrint(logSink, ASYN_TRACEIO_DRIVER,
"PIGCSController::sendAndReceive() received \"%s\"\n", inputBuff);
// //printf("PIGCSController::sendAndReceive() received \"%s\"\n", inputBuff);
return(status);
}
asynStatus PIGCSController::sendOnly(const char *outputBuff)
{
asynUser* logSink = m_pCurrentLogSink;
if (NULL == logSink)
logSink = m_pInterface;
m_interfaceMutex.lock();
asynStatus status = sendOnly(m_pInterface, outputBuff, logSink);
m_interfaceMutex.unlock();
return status;
}
asynStatus PIGCSController::sendOnly(char c)
{
asynUser* logSink = m_pCurrentLogSink;
if (NULL == logSink)
logSink = m_pInterface;
m_interfaceMutex.lock();
asynStatus status = sendOnly(m_pInterface, c, logSink);
m_interfaceMutex.unlock();
return status;
}
asynStatus PIGCSController::sendAndReceive(char c, char *inputBuff, int inputSize)
{
asynUser* logSink = m_pCurrentLogSink;
if (NULL == logSink)
logSink = m_pInterface;
m_interfaceMutex.lock();
asynStatus status = sendAndReceive(m_pInterface, c, inputBuff, inputSize, logSink);
m_interfaceMutex.unlock();
return status;
}
asynStatus PIGCSController::sendAndReceive(const char* output, char *inputBuff, int inputSize)
{
asynUser* logSink = m_pCurrentLogSink;
if (NULL == logSink)
logSink = m_pInterface;
m_interfaceMutex.lock();
asynStatus status = sendAndReceive(m_pInterface, output, inputBuff, inputSize, logSink);
m_interfaceMutex.unlock();
return status;
}
asynStatus PIGCSController::sendAndReceive(asynUser* pInterface, char c, char *inputBuff, int inputSize, asynUser* logSink)
{
size_t nWrite, nRead;
int eomReason;
asynStatus status;
size_t pos = 0;
asynPrint(logSink, ASYN_TRACEIO_DRIVER,
"PIGCSController::sendAndReceive() sending \"#%d\"\n", int(c));
//printf("PIGCSController::sendAndReceive() sending \"#%d\"\n", int(c));
status = pasynOctetSyncIO->writeRead(pInterface,
&c, 1,
inputBuff, inputSize,
TIMEOUT, &nWrite, &nRead, &eomReason);
if (nWrite != 1)
status = asynError;
if (status != asynSuccess)
{
asynPrint(logSink, ASYN_TRACE_ERROR|ASYN_TRACEIO_DRIVER,
"PIGCSController::sendAndReceive error calling writeRead, output=%d status=%d, error=%s\n",
int(c), status, pInterface->errorMessage);
//printf("PIGCSController::sendAndReceive error calling writeRead, output=%d status=%d, error=%s\n", int(c), status, pInterface->errorMessage);
}
while(inputBuff[strlen(inputBuff)-1] == ' ')
{
pos += nRead;
status = pasynOctetSyncIO->writeRead(logSink,
&c, 1,
inputBuff+pos, inputSize-pos,
TIMEOUT, &nWrite, &nRead, &eomReason);
//printf("PIGCSController::sendAndReceive(char) in while loop. inputBuff: \"%s\"\n", inputBuff);
}
asynPrint(logSink, ASYN_TRACEIO_DRIVER,
"PIGCSController::sendAndReceive() received \"%s\"\n", inputBuff);
//printf("PIGCSController::sendAndReceive() received \"%s\" - (0x%02X)\n", inputBuff, int(inputBuff[0]));
return(status);
}
asynStatus PIGCSController::setVelocityCts( PIasynAxis* pAxis, double velocity )
{
char cmd[100];
velocity = fabs(velocity) * pAxis->m_CPUdenominator / pAxis->m_CPUnumerator;
sprintf(cmd,"VEL %s %f", pAxis->m_szAxisName, velocity);
asynStatus status = sendOnly(cmd);
if (asynSuccess == status)
{
pAxis->m_velocity = velocity;
}
return status;
}
asynStatus PIGCSController::moveCts( PIasynAxis** pAxesArray, int* pTargetCtsArray, int numAxes)
{
//TODO: "Use MVE or set vel/acc so axes reach target at the same time""
asynStatus status;
char cmd[1000] = "MOV";
char subCmd[100];
for (int axis = 0; axis <numAxes; axis++)
{
PIasynAxis* pAxis = pAxesArray[axis];
double target = double(pTargetCtsArray[axis]) * pAxis->m_CPUdenominator / pAxis->m_CPUnumerator;
sprintf(subCmd," %s %f", pAxis->m_szAxisName, target);
strcat(cmd, subCmd);
pAxis->m_lastDirection = (pTargetCtsArray[axis] > pAxis->m_positionCts) ? 1 : 0;
}
status = sendOnly(cmd);
if (asynSuccess != status)
{
return status;
}
int errorCode = getGCSError();
if (errorCode == 0)
return asynSuccess;
asynPrint(m_pInterface, ASYN_TRACE_FLOW|ASYN_TRACE_ERROR,
"PIGCSController::moveCts(array) failed, GCS error %d\n", errorCode);
return asynError;
}
asynStatus PIGCSController::moveCts( PIasynAxis* pAxis, int targetCts )
{
asynStatus status;
char cmd[100];
double target = double(targetCts) * pAxis->m_CPUdenominator / pAxis->m_CPUnumerator;
asynPrint(m_pInterface, ASYN_TRACE_FLOW|ASYN_TRACE_ERROR,
"PIGCSController::moveCts(, %d) \n", targetCts);
return move(pAxis, target);
}
asynStatus PIGCSController::move( PIasynAxis* pAxis, double target )
{
asynStatus status;
char cmd[100];
sprintf(cmd,"MOV %s %f", pAxis->m_szAxisName, target);
status = sendOnly(cmd);
if (asynSuccess != status)
{
return status;
}
asynPrint(m_pInterface, ASYN_TRACE_FLOW|ASYN_TRACE_ERROR,
"PIGCSController::move() sent \"%s\"\n", cmd);
pAxis->m_lastDirection = (target > pAxis->m_position) ? 1 : 0;
int errorCode = getGCSError();
if (errorCode == 0)
return asynSuccess;
asynPrint(m_pInterface, ASYN_TRACE_FLOW|ASYN_TRACE_ERROR,
"PIGCSController::move() failed, GCS error %d\n", errorCode);
return asynError;
}
int PIGCSController::getGCSError()
{
char buf[256];
asynStatus status = sendAndReceive("ERR?", buf, 255);
if (asynTimeout == status)
{
return COM_TIMEOUT;
}
else if (asynSuccess != status)
{
return COM_ERROR;
}
int errorCode = atoi(buf);
if (0 != errorCode)
{
m_LastError = errorCode;
asynPrint(m_pCurrentLogSink, ASYN_TRACE_ERROR|ASYN_TRACE_FLOW,
"PIGCSController::getGCSError() GCS error code = %d\n",
errorCode);
char szErrorMsg[1024];
if (TranslatePIError(errorCode, szErrorMsg, 1024))
{
asynPrint(m_pCurrentLogSink, ASYN_TRACE_ERROR|ASYN_TRACE_FLOW,
"PIGCSController::getGCSError() GCS error, %s\n",
szErrorMsg);
}
}
return errorCode;
}
asynStatus PIGCSController::haltAxis(PIasynAxis* pAxis)
{
char cmd[100];
sprintf(cmd,"HLT %s", pAxis->m_szAxisName);
asynStatus status = sendOnly(cmd);
if (status != asynSuccess)
{
return status;
}
int err = getGCSError();
// controller will set error code to PI_CNTR_STOP (10)
if (err != PI_CNTR_STOP)
{
asynPrint(m_pCurrentLogSink, ASYN_TRACE_FLOW|ASYN_TRACE_ERROR,
"PIGCSController::haltAxis() failed, GCS error %d", err);
return asynError;
}
return status;
}
/**
* get position of axis in physical units (EGU) as defined on the controller
*/
asynStatus PIGCSController::getAxisPosition(PIasynAxis* pAxis, double& position)
{
char cmd[100];
char buf[255];
sprintf(cmd, "POS? %s", pAxis->m_szAxisName);
asynStatus status = sendAndReceive(cmd, buf, 99);
if (status != asynSuccess)
{
return status;
}
if (!getValue(buf, position))
{
status = asynError;
}
return status;
}
/**
* get velocity of axis in physical units (EGU) as defined on the controller
* and set PIasynAxis::m_velocity
*/
asynStatus PIGCSController::getAxisVelocity(PIasynAxis* pAxis)
{
char cmd[100];
char buf[255];
sprintf(cmd, "VEL? %s", pAxis->m_szAxisName);
asynStatus status = sendAndReceive(cmd, buf, 99);
if (status != asynSuccess)
{
return status;
}
if (!getValue(buf, pAxis->m_velocity))
{
status = asynError;
}
return status;
}
/**
* Find travel range for axis.
*/
asynStatus PIGCSController::getTravelLimits(PIasynAxis* pAxis, double& negLimit, double& posLimit)
{
char cmd[100];
char buf[255];
sprintf(cmd, "TMN? %s", pAxis->m_szAxisName);
asynStatus status = sendAndReceive(cmd, buf, 99);
if (status != asynSuccess)
{
return status;
}
if (!getValue(buf, negLimit))
{
return asynError;
}
sprintf(cmd, "TMX? %s", pAxis->m_szAxisName);
status = sendAndReceive(cmd, buf, 99);
if (status != asynSuccess)
{
return status;
}
if (!getValue(buf, posLimit))
{
return asynError;
}
return status;
}
asynStatus PIGCSController::hasLimitSwitches(PIasynAxis* pAxis)
{
char cmd[100];
char buf[255];
sprintf(cmd, "LIM? %s", pAxis->m_szAxisName);
asynStatus status = sendAndReceive(cmd, buf, 99);
if (status != asynSuccess)
{
return status;
}
if (!getValue(buf, pAxis->m_bHasLimitSwitches))
{
return asynError;
}
if (!pAxis->m_bHasLimitSwitches)
{
sprintf(cmd, "HAR? %s", pAxis->m_szAxisName);
asynStatus status = sendAndReceive(cmd, buf, 99);
if (status == asynSuccess)
{
if (!getValue(buf, pAxis->m_bHasLimitSwitches))
{
return asynError;
}
}
else if (status == asynTimeout)
{
int err = getGCSError();
if (err == PI_CNTR_UNKNOWN_COMMAND)
{
// "HAR?" not known
pAxis->m_bHasLimitSwitches = false;
}
else
{
return status;
}
}
else
{
return status;
}
}
asynPrint(m_pCurrentLogSink, ASYN_TRACE_FLOW,
"PIGCSController::hasLimitSwitches() axis has %slimit switches\n",
pAxis->m_bHasLimitSwitches?"":"no ");
return status;
}
asynStatus PIGCSController::hasReferenceSensor(PIasynAxis* pAxis)
{
char cmd[100];
char buf[255];
sprintf(cmd, "TRS? %s", pAxis->m_szAxisName);
asynStatus status = sendAndReceive(cmd, buf, 99);
if (status != asynSuccess)
{
return status;
}
if (!getValue(buf, pAxis->m_bHasReference))
{
return asynError;
}
asynPrint(m_pCurrentLogSink, ASYN_TRACE_FLOW,
"PIGCSController::hasReferenceSwitch() axis has %sreference sensor\n",
pAxis->m_bHasReference?"":"no ");
return status;
}
/**
* get position of axis in counts as used in EPICS.
* getAxisPosition() is called and position is covnerted to counts using the
* counts-per-unit (CPU) fraction of the axis.
*/
asynStatus PIGCSController::getAxisPositionCts(PIasynAxis* pAxis)
{
double pos;
asynStatus status = getAxisPosition(pAxis, pos);
if (status != asynSuccess)
{
return status;
}
pAxis->m_position = pos;
if (pAxis->m_CPUdenominator==0 || pAxis->m_CPUnumerator==0)
{
pAxis->m_positionCts = pos;
return status;
}
pAxis->m_positionCts = int( (pos * double(pAxis->m_CPUnumerator) / double(pAxis->m_CPUdenominator))+0.5);
if (m_pCurrentLogSink != NULL)
{
asynPrint(m_pCurrentLogSink, ASYN_TRACE_FLOW,
"PIGCSController::getAxisPositionCts() pos:%d\n",
pAxis->m_positionCts);
}
return status;
}
//void PIGCSController::calcAxisPositionCts();
asynStatus PIGCSController::setServo(PIasynAxis* pAxis, int servoState)
{
char cmd[100];
sprintf(cmd, "SVO %s %d", pAxis->m_szAxisName, servoState);
asynStatus status = sendOnly(cmd);
if (status != asynSuccess)
{
return status;
}
int err = getGCSError();
if (COM_NO_ERROR == err)
{
pAxis->m_bServoControl = (servoState == 1);
if (pAxis->m_bProblem && pAxis->m_bServoControl)
{
pAxis->m_bProblem = false;
}
return asynSuccess;
}
asynPrint(m_pCurrentLogSink, ASYN_TRACE_ERROR|ASYN_TRACE_FLOW,
"Could not set servo state!\n");
return asynError;
}
asynStatus PIGCSController::getMoving(PIasynAxis* pAxis, int& moving)
{
char buf[255];
asynStatus status = sendAndReceive(char(5), buf, 99);;
if (status != asynSuccess)
{
//printf("PIGCSController::getMoving() failed, status %d", status);
return status;
}
char* pStr;
long movingState = strtol(buf, &pStr, 16);
moving = (movingState & pAxis->m_movingStateMask) != 0 ? 1 : 0;
return status;
}
asynStatus PIGCSController::getBusy(PIasynAxis* pAxis, int& busy)
{
char buf[255];
asynStatus status = sendAndReceive(char(7), buf, 99);;
if (status != asynSuccess)
{
return status;
}
unsigned char c = (unsigned char)buf[0];
busy = (c==0xB0);
return status;
}
asynStatus PIGCSController::setGCSParameter(PIasynAxis* pAxis, unsigned int paramID, double value)
{
char cmd[100];
sprintf(cmd, "SPA %s %d %.12g", pAxis->m_szAxisName, paramID, value);
asynStatus status = sendOnly(cmd);
return status;
}
asynStatus PIGCSController::getGCSParameter(PIasynAxis* pAxis, unsigned int paramID, double& value)
{
char cmd[100];
char buf[255];
sprintf(cmd, "SPA? %s %d", pAxis->m_szAxisName, paramID);
asynStatus status = sendAndReceive(cmd, buf, 99);
if (status != asynSuccess)
{
return status;
}
if (!getValue(buf, value))
{
return asynError;
}
return status;
}
PIGCSController::PIGCSController(asynUser* pCom, const char* szIDN)
: m_pCurrentLogSink(NULL)
, m_bAnyAxisMoving(false)
, m_pInterface(pCom)
, m_nrFoundAxes(0)
, m_LastError(0)
{
strncpy(szIdentification, szIDN, 199);
}
PIGCSController::~PIGCSController()
{
}
asynStatus PIGCSController::initAxis(PIasynAxis* pAxis)
{
// read stage name - to have it in logfile and find
// problems because of mis/non-configured controllers
char cmd[100];
char buf[255];
sprintf(cmd, "CST? %s", pAxis->m_szAxisName);
asynStatus status = sendAndReceive(cmd, buf, 99);;
if (status != asynSuccess)
{
return status;
}
if (NULL != m_pCurrentLogSink)
{
asynPrint(m_pCurrentLogSink, ASYN_TRACE_FLOW,
"PIGCSController::initAxis() stage configuration: %s\n", buf);
}
pAxis->m_movingStateMask = pow(2.0, pAxis->getAxisNo());
return setServo(pAxis, 1);
}
asynStatus PIGCSController::init(void)
{
asynStatus status;
status = findConnectedAxes();
return status;
}
asynStatus PIGCSController::findConnectedAxes()
{
m_nrFoundAxes = 0;
for (size_t i=0; i<MAX_NR_AXES; i++)
{
m_axesIDs[i] = NULL;
}
asynStatus status = PIGCSController::sendAndReceive("SAI?", m_allAxesIDs, 255);
if (asynSuccess != status)
{
return status;
}
char* szAxis = strtok(m_allAxesIDs, "\n");
while (szAxis != NULL)
{
int i=strlen(szAxis)-1;
while (szAxis[i] == ' ')
{
szAxis[i] = '\0';
i--;
}
if (MAX_NR_AXES <= m_nrFoundAxes)
{
return asynError;
}
m_axesIDs[m_nrFoundAxes] = szAxis;
m_nrFoundAxes++;
szAxis = strtok(NULL, "\n");
}
return status;
}
asynStatus PIGCSController::getReferencedState(PIasynAxis* pAxis)
{
char cmd[100];
char buf[255];
sprintf(cmd, "FRF? %s", pAxis->m_szAxisName);
asynStatus status = sendAndReceive(cmd, buf, 99);;
if (status != asynSuccess)
{
return status;
}
if (getValue(buf, pAxis->m_homed))
{
return asynError;
}
return status;
}
asynStatus PIGCSController::getResolution(PIasynAxis* pAxis, double& resolution )
{
resolution = 0.0001;
pAxis->m_CPUnumerator = 10000;
pAxis->m_CPUdenominator = 1;
return asynSuccess;
}
asynStatus PIGCSController::SetPivotX(double value)
{
if (NULL != m_pCurrentLogSink)
{
asynPrint(m_pCurrentLogSink, ASYN_TRACE_FLOW,
"PIGCSController::SetPivotX() ignored");
}
return asynSuccess;
}
asynStatus PIGCSController::SetPivotY(double value)
{
if (NULL != m_pCurrentLogSink)
{
asynPrint(m_pCurrentLogSink, ASYN_TRACE_FLOW,
"PIGCSController::SetPivotY() ignored");
}
return asynSuccess;
}
asynStatus PIGCSController::SetPivotZ(double value)
{
if (NULL != m_pCurrentLogSink)
{
asynPrint(m_pCurrentLogSink, ASYN_TRACE_FLOW,
"PIGCSController::SetPivotZ() ignored");
}
return asynSuccess;
}
bool PIGCSController::getValue(const char* szMsg, double& value)
{
const char* p = strstr(szMsg, "=");
if (p==NULL || *p == '\0')
{
return false;
}
value = atof(p+1);
return true;
}
bool PIGCSController::getValue(const char* szMsg, int& value)
{
const char* p = strstr(szMsg, "=");
if (p==NULL || *p == '\0')
{
return false;
}
value = atoi(p+1);
return true;
}
bool PIGCSController::getValue(const char* szMsg, bool& value)
{
const char* p = strstr(szMsg, "=");
if (p==NULL || *p == '\0')
{
return false;
}
int ivalue = atoi(p+1);
value = (ivalue =! 0);
return true;
}
+114
View File
@@ -0,0 +1,114 @@
/*
* PIGCScontroller.h
*
* Created on: 15.12.2010
* Author: sra
*/
#ifndef PIGCSCONTROLLER_H_
#define PIGCSCONTROLLER_H_
#include <asynDriver.h>
#include <string.h>
#include <epicsMutex.h>
#include "picontrollererrors.h"
class PIasynAxis;
class asynMotorAxis;
/**
* Base class for all PI GCS(2) controllers.
*
* Most functions will be implemented here, since for basic functionality
* GCS commands are always the same.
*/
class PIGCSController
{
public:
PIGCSController(asynUser* pCom, const char* szIDN);
virtual ~PIGCSController();
static PIGCSController* CreateGCSController(asynUser* pCom, const char* szIDN);
virtual asynStatus init(void);
virtual asynStatus initAxis(PIasynAxis* pAxis);
static asynStatus sendOnly(asynUser* pInterface, char c, asynUser* logSink);
static asynStatus sendOnly(asynUser* pInterface, const char *outputBuff, asynUser* logSink);
static asynStatus sendAndReceive(asynUser* pInterface, const char *outputBuff, char *inputBuff, int inputSize, asynUser* logSink);
static asynStatus sendAndReceive(asynUser* pInterface, char c, char *inputBuff, int inputSize, asynUser* logSink);
bool getValue(const char* szMsg, double& value);
bool getValue(const char* szMsg, int& value);
bool getValue(const char* szMsg, bool& value);
virtual asynStatus setVelocityCts( PIasynAxis* pAxis, double velocity );
virtual asynStatus setAccelerationCts( PIasynAxis* pAxis, double acceleration) { return asynSuccess; }
virtual asynStatus setAcceleration( PIasynAxis* pAxis, double acceleration) { return asynSuccess; }
virtual asynStatus move( PIasynAxis* pAxis, double target);
virtual asynStatus moveCts( PIasynAxis* pAxis, int target);
virtual asynStatus moveCts( PIasynAxis** pAxesArray, int* pTargetCtsArray, int numAxes);
virtual asynStatus referenceVelCts( PIasynAxis* pAxis, double velocity, int forwards) { return asynSuccess; }
virtual asynStatus haltAxis(PIasynAxis* pAxis);
virtual asynStatus getAxisPosition(PIasynAxis* pAxis, double& position);
virtual asynStatus getAxisVelocity(PIasynAxis* pAxis);
virtual asynStatus getAxisPositionCts(PIasynAxis* pAxis);
virtual asynStatus setServo(PIasynAxis* pAxis, int servoState);
virtual asynStatus getResolution(PIasynAxis* pAxis, double& resolution );
virtual asynStatus getStatus(PIasynAxis* pAxis, int& homing, int& moving, int& negLimit, int& posLimit, int& servoControl) = 0;
virtual asynStatus getGlobalState( asynMotorAxis** Axes, int numAxes ) { return asynSuccess; }
virtual asynStatus getMoving(PIasynAxis* pAxis, int& homing);
virtual asynStatus getBusy(PIasynAxis* pAxis, int& busy);
virtual asynStatus getTravelLimits(PIasynAxis* pAxis, double& negLimit, double& posLimit);
virtual asynStatus hasLimitSwitches(PIasynAxis* pAxis);
virtual asynStatus hasReferenceSensor(PIasynAxis* pAxis);
virtual asynStatus getReferencedState(PIasynAxis* axis);
virtual asynStatus SetPivotX(double value);
virtual asynStatus SetPivotY(double value);
virtual asynStatus SetPivotZ(double value);
virtual double GetPivotX() { return 0.0; }
virtual double GetPivotY() { return 0.0; }
virtual double GetPivotZ() { return 0.0; }
virtual bool AcceptsNewTarget() { return true; }
virtual bool CanCommunicateWhileHoming() { return true; }
asynStatus sendOnly(const char *outputBuff);
asynStatus sendOnly(char c);
asynStatus sendAndReceive(const char *outputBuff, char *inputBuff, int inputSize);
asynStatus sendAndReceive(char c, char *inputBuff, int inputSize);
const char* getAxesID(size_t axisIdx) { return m_axesIDs[axisIdx]; }
size_t getNrFoundAxes() { return m_nrFoundAxes; }
virtual bool IsGCS2() { return true; }
int getGCSError();
int GetLastError() { return m_LastError; }
asynUser* m_pCurrentLogSink;
static const size_t MAX_NR_AXES = 64;
bool m_bAnyAxisMoving;
protected:
asynStatus setGCSParameter(PIasynAxis* pAxis, unsigned int paramID, double value);
asynStatus getGCSParameter(PIasynAxis* pAxis, unsigned int paramID, double& value);
virtual asynStatus findConnectedAxes();
asynUser* m_pInterface;
epicsMutex m_interfaceMutex;
static double TIMEOUT;
char szIdentification[200];
int m_nrAxesOnController;
char* m_axesIDs[MAX_NR_AXES];
size_t m_nrFoundAxes;
char m_allAxesIDs[255];
int m_LastError;
};
#endif /* PIGCSCONTROLLER_H_ */
@@ -0,0 +1,189 @@
/*
* PIGCSMotorController.cpp
*
* Created on: 15.12.2010
* Author: sra
*/
#include "PIGCSMotorController.h"
#include "PIasynAxis.h"
#include <math.h>
#include <stdlib.h>
//#undef asynPrint
//#define asynPrint(user,reason,format...) 0
asynStatus PIGCSMotorController::initAxis(PIasynAxis* pAxis)
{
asynStatus status = hasLimitSwitches(pAxis);
if (asynSuccess != status)
{
return status;
}
status = hasReferenceSensor(pAxis);
if (asynSuccess != status)
{
return status;
}
return PIGCSController::initAxis(pAxis);
}
asynStatus PIGCSMotorController::setAccelerationCts( PIasynAxis* pAxis, double accelerationCts)
{
double acceleration = fabs(accelerationCts) * pAxis->m_CPUdenominator / pAxis->m_CPUnumerator;
if (acceleration == pAxis->m_acceleration)
return asynSuccess;
if (pAxis->m_maxAcceleration < 0)
{
getMaxAcceleration(pAxis);
}
if (acceleration > pAxis->m_maxAcceleration)
acceleration = pAxis->m_maxAcceleration;
return setAcceleration(pAxis, acceleration);
}
asynStatus PIGCSMotorController::referenceVelCts( PIasynAxis* pAxis, double velocity, int forwards)
{
asynStatus status = setServo(pAxis, 1);
if (asynSuccess != status)
return status;
char cmd[100];
if (velocity != 0)
{
velocity = fabs(velocity) * pAxis->m_CPUdenominator / pAxis->m_CPUnumerator;
sprintf(cmd,"SPA %s 0x50 %f", pAxis->m_szAxisName, velocity);
sendOnly(cmd);
}
if (pAxis->m_bHasReference)
{
// call FRF - find reference
sprintf(cmd,"FRF %s", pAxis->m_szAxisName);
}
else if (pAxis->m_bHasLimitSwitches)
{
if (forwards)
{
// call FPL - find positive limit switch
sprintf(cmd,"FPL %s", pAxis->m_szAxisName);
}
else
{
// call FNL - find negative limit switch
sprintf(cmd,"FNL %s", pAxis->m_szAxisName);
}
}
else
{
asynPrint(m_pCurrentLogSink, ASYN_TRACE_ERROR,
"PIGCSMotorController::referenceVelCts() failed - axis has no reference/limit switch\n");
epicsSnprintf(pAxis->m_pasynUser->errorMessage,pAxis->m_pasynUser->errorMessageSize,
"PIGCSMotorController::referenceVelCts() failed - axis has no reference/limit switch\n");
return asynError;
}
status = sendOnly(cmd);
if (asynSuccess != status)
return status;
int errorCode = getGCSError();
if (errorCode == 0)
{
return asynSuccess;
}
asynPrint(m_pCurrentLogSink, ASYN_TRACE_ERROR,
"PIGCSMotorController::referenceVelCts() failed\n");
epicsSnprintf(pAxis->m_pasynUser->errorMessage,pAxis->m_pasynUser->errorMessageSize,
"PIGCSMotorController::referenceVelCts() failed - GCS Error %d\n",errorCode);
return asynError;
}
/**
* Get encoder resolution from counts-per-unit (CPU) fraction of the axis.
*/
asynStatus PIGCSMotorController::getResolution(PIasynAxis* pAxis, double& resolution )
{
// CPU is "Counts Per Unit"
// this is stored as two integers in the controller
double num, denom;
asynStatus status = getGCSParameter(pAxis, PI_PARA_MOT_CPU_Z, num);
if (status != asynSuccess)
{
return status;
}
status = getGCSParameter(pAxis, PI_PARA_MOT_CPU_N, denom);
if (status != asynSuccess)
{
return status;
}
pAxis->m_CPUnumerator = num;
pAxis->m_CPUdenominator = denom;
resolution = double(pAxis->m_CPUdenominator) / double(pAxis->m_CPUnumerator) ;
return status;
}
asynStatus PIGCSMotorController::getStatus(PIasynAxis* pAxis, int& homing, int& moving, int& negLimit, int& posLimit, int& servoControl)
{
char buf[255];
asynStatus status = sendAndReceive(char(4), buf, 99);
if (status != asynSuccess)
{
return status;
}
// TODO this is for a single axis C-863/867 controller!!!!
// TODO a) change it to multi-axis code.
// TODO b) support other controllers which do not understand #4 or have different bit masks
int idx = 2 + pAxis->getAxisNo()*4;
buf[idx+4] = '\0';
char* szMask = buf+idx;
long mask = strtol(szMask, NULL, 16);
moving = (mask & 0x2000) ? 1 : 0;
homing = (mask & 0x4000) ? 1 : 0;
negLimit = (mask & 0x0001) ? 1 : 0;
posLimit = (mask & 0x0004) ? 1 : 0;
servoControl = (mask & 0x1000) ? 1 : 0;
asynPrint(m_pCurrentLogSink, ASYN_TRACE_FLOW,
"PIGCSMotorController::getStatus() buf:%s moving %d, svo: %d\n",
buf, moving, servoControl);
return status;
}
asynStatus PIGCSMotorController::getMaxAcceleration(PIasynAxis* pAxis)
{
double maxAcc, maxDec;
asynStatus status = getGCSParameter(pAxis, PI_PARA_MOT_MAX_ACCEL, maxAcc);
if (asynSuccess != status)
return status;
status = getGCSParameter(pAxis, PI_PARA_MOT_MAX_DECEL, maxDec);
if (asynSuccess != status)
return status;
if (maxAcc < maxDec)
{
pAxis->m_maxAcceleration = maxAcc;
}
else
{
pAxis->m_maxAcceleration = maxDec;
}
return status;
}
asynStatus PIGCSMotorController::setAcceleration( PIasynAxis* pAxis, double acceleration)
{
asynStatus status = setGCSParameter(pAxis, PI_PARA_MOT_CURR_ACCEL, acceleration);
if (asynSuccess != status)
return status;
status = setGCSParameter(pAxis, PI_PARA_MOT_CURR_DECEL, acceleration);
if (asynSuccess != status)
return status;
pAxis->m_acceleration = acceleration;
return status;
}
@@ -0,0 +1,53 @@
/*
* PIGCScontroller.h
*
* Created on: 15.12.2010
* Author: sra
*/
#ifndef PIGCSMOTORCONTROLLER_H_
#define PIGCSMOTORCONTROLLER_H_
#include "PIGCSController.h"
#include <asynDriver.h>
/**
* class representing PI GCS2 motor controllers.
*
* "motor" does not strictly restrict the driving principle to DC stages or
* stepper but includes other controller families (e.g. for piezo motors) also.
*/
class PIGCSMotorController : public PIGCSController
{
public:
PIGCSMotorController(asynUser* pCom, const char* szIDN)
: PIGCSController(pCom, szIDN)
{
}
~PIGCSMotorController() {}
virtual asynStatus initAxis(PIasynAxis* pAxis);
virtual asynStatus setAccelerationCts( PIasynAxis* pAxis, double acceleration);
virtual asynStatus setAcceleration( PIasynAxis* pAxis, double acceleration);
virtual asynStatus getMaxAcceleration( PIasynAxis* pAxis );
virtual asynStatus referenceVelCts( PIasynAxis* pAxis, double velocity, int forwards);
virtual asynStatus getResolution(PIasynAxis* pAxis, double& resolution );
virtual asynStatus getStatus(PIasynAxis* pAxis, int& homing, int& moving, int& negLimit, int& posLimit, int& servoControl);
protected:
enum
{
PI_PARA_MOT_CURR_ACCEL = 0x000000BUL,
PI_PARA_MOT_CURR_DECEL = 0x000000CUL,
PI_PARA_MOT_CPU_Z = 0x000000EUL,
PI_PARA_MOT_CPU_N = 0x000000FUL,
PI_PARA_MOT_HAT_REF = 0x0000014UL,
PI_PARA_MOT_MAX_ACCEL = 0x000004AUL,
PI_PARA_MOT_MAX_DECEL = 0x000004BUL
};
private:
};
#endif /* PIGCSMOTORCONTROLLER_H_ */
@@ -0,0 +1,37 @@
/*
* PIGCSPiezoController
*
* Created on: 15.12.2010
* Author: sra
*/
#include "PIGCSPiezoController.h"
#include "PIasynAxis.h"
#include <math.h>
#include <stdlib.h>
#undef asynPrint
#define asynPrint(user,reason,format...) 0
asynStatus PIGCSPiezoController::getStatus(PIasynAxis* pAxis, int& homing, int& moving, int& negLimit, int& posLimit, int& servoControl)
{
asynStatus status = getMoving(pAxis, moving);
if (status != asynSuccess)
{
return status;
}
homing = 0;
negLimit = 0;
posLimit = 0;
return status;
}
asynStatus PIGCSPiezoController::getReferencedState(PIasynAxis* pAxis)
{
pAxis->m_homed = 1;
return asynSuccess;
}
@@ -0,0 +1,38 @@
/*
* PIGCScontroller.h
*
* Created on: 15.12.2010
* Author: sra
*/
#ifndef PIGCSPIEZOCONTROLLER_H_
#define PIGCSPIEZOCONTROLLER_H_
#include "PIGCSController.h"
#include <asynDriver.h>
/**
* Class representing PI's GCS2 digital piezo controllers.
*
* Main difference to motor controllers is the usage of absolute sensors.
*/
class PIGCSPiezoController : public PIGCSController
{
public:
PIGCSPiezoController(asynUser* pCom, const char* szIDN)
: PIGCSController(pCom, szIDN)
{
}
~PIGCSPiezoController() {}
virtual asynStatus init(void) { return PIGCSController::init(); }
virtual asynStatus getStatus(PIasynAxis* pAxis, int& homing, int& moving, int& negLimit, int& posLimit, int& servoControl);
virtual asynStatus getReferencedState(PIasynAxis* pAxis);
private:
};
#endif /* PIGCSPIEZOCONTROLLER_H_ */
@@ -0,0 +1,444 @@
/*
* PIE755Controller
*
* Author: sra
*/
#include "PIHexapodController.h"
#include "PIasynAxis.h"
#include <stdlib.h>
#include <epicsThread.h>
//#undef asynPrint
//#define asynPrint(user,reason,format...) 0
asynStatus PIHexapodController::init(void)
{
asynStatus status = PIGCSController::init();
if (status != asynSuccess)
{
return status;
}
// Try to find out if #4 is supported
char buf[200];
status = sendAndReceive(char(4), buf, 199);
if (status == asynSuccess)
{
m_bCanReadStatusWithChar4 = true;
}
else if (status == asynTimeout)
{
m_bCanReadStatusWithChar4 = false;
getGCSError(); // clear error UNKNOWN COMMAND
}
// status = sendAndReceive(char(3), buf, 199);
// if (status == asynSuccess)
// {
// m_bCanReadPosWithChar3 = true;
// }
// else if (status == asynTimeout)
{
m_bCanReadPosWithChar3 = false;
getGCSError(); // clear error UNKNOWN COMMAND
}
m_bHoming = false;
ReadPivotSettings();
return status;
}
asynStatus PIHexapodController::getGlobalState(asynMotorAxis** pAxes, int numAxes)
{
// do not call moving here, at least simulation software does return
// values != 0 with bit 1 not set (e.g. "2")
char buf[255];
asynStatus status = sendAndReceive(char(5), buf, 99);;
if (status != asynSuccess)
{
printf("PIGCSController::getGlobalState() failed, status %d", status);
return status;
}
char* pStr;
long moving = strtol(buf, &pStr, 16);
m_bAnyAxisMoving = (moving != 0);
if (m_bHoming && (moving == 0))
{
m_bHoming = false;
}
for(int i=0; i<numAxes; i++)
{
((PIasynAxis*)pAxes[i])->m_bMoving = (moving != 0);
}
return asynSuccess;
}
asynStatus PIHexapodController::getStatus(PIasynAxis* pAxis, int& homing, int& moving, int& negLimit, int& posLimit, int& servoControl)
{
negLimit = 0;
posLimit = 0;
homing = m_bHoming ? 1:0;
moving = pAxis->m_bMoving || pAxis->deferred_move;
return asynSuccess;
}
asynStatus PIHexapodController::findConnectedAxes()
{
for (size_t i=0; i<MAX_NR_AXES; i++)
{
m_axesIDs[i] = NULL;
}
sprintf(m_allAxesIDs, "X\nY\nZ\nU\nV\nW");
char* szAxis = strtok(m_allAxesIDs, "\n");
while (szAxis != NULL)
{
int i=strlen(szAxis)-1;
while (szAxis[i] == ' ')
{
szAxis[i] = '\0';
i--;
}
if (MAX_NR_AXES <= m_nrFoundAxes)
{
return asynError;
}
m_axesIDs[m_nrFoundAxes] = szAxis;
m_nrFoundAxes++;
szAxis = strtok(NULL, "\n");
}
return asynSuccess;
}
asynStatus PIHexapodController::initAxis(PIasynAxis* pAxis)
{
pAxis->m_movingStateMask = 1;
return setServo(pAxis, 1);
}
asynStatus PIHexapodController::getReferencedState(PIasynAxis* pAxis)
{
if (!m_bCanReadStatusWithChar4)
{
pAxis->m_homed = 1;
return asynSuccess;
}
char buf[255];
asynStatus status = sendAndReceive(char(4), buf, 99);
if (status != asynSuccess)
{
return status;
}
long mask = strtol(buf, NULL, 10);
pAxis->m_homed = (mask & 0x10000) ? 1 : 0;
return status;
}
asynStatus PIHexapodController::moveCts( PIasynAxis* pAxis, int targetCts )
{
// printf("PIHexapodController::moveCts(,%d)...\n",targetCts);
asynStatus status;
char cmd[100];
double target = double(targetCts) * pAxis->m_CPUdenominator / pAxis->m_CPUnumerator;
sprintf(cmd,"MOV %s %f", pAxis->m_szAxisName, target);
status = sendOnly(cmd);
if (asynSuccess != status)
{
return status;
}
epicsThreadSleep( 0.2 ); // TODO test if we do need this
asynMotorAxis* pAsynAxis = (asynMotorAxis*)pAxis;
status = getGlobalState(&pAsynAxis, 1);
if (asynSuccess != status)
{
// printf("PIHexapodController::moveCts(,%d) - getGlobalState() failed, status=%d\n", targetCts, status);
return status;
}
if (!pAxis->m_bMoving)
{
int errorCode = getGCSError();
// printf("PIHexapodController::moveCts(,%d) - not moving after MOV() gcserror=%d\n",targetCts, errorCode);
if (errorCode != 0)
{
asynPrint(m_pInterface, ASYN_TRACE_FLOW|ASYN_TRACE_ERROR,
"PIHexapodController::moveCts() failed, GCS error %d\n", errorCode);
return asynError;
}
}
m_bAnyAxisMoving = true;
pAxis->m_lastDirection = (targetCts > pAxis->m_positionCts) ? 1 : 0;
printf("PIHexapodController::moveCts(,%d) - OK!\n",targetCts);
return status;
}
asynStatus PIHexapodController::moveCts( PIasynAxis** pAxesArray, int* pTargetCtsArray, int numAxes)
{
asynStatus status;
char cmd[1000] = "MOV";
char subCmd[100];
for (int axis = 0; axis <numAxes; axis++)
{
PIasynAxis* pAxis = pAxesArray[axis];
double target = double(pTargetCtsArray[axis]) * pAxis->m_CPUdenominator / pAxis->m_CPUnumerator;
sprintf(subCmd," %s %f", pAxis->m_szAxisName, target);
strcat(cmd, subCmd);
pAxis->m_lastDirection = (pTargetCtsArray[axis] > pAxis->m_positionCts) ? 1 : 0;
}
status = sendOnly(cmd);
if (asynSuccess != status)
{
return status;
}
epicsThreadSleep(0.2);
status = getGlobalState((asynMotorAxis**)pAxesArray, numAxes);
if (asynSuccess != status)
{
return status;
}
if (!pAxesArray[0]->m_bMoving)
{
int errorCode = getGCSError();
if (errorCode != 0)
{
asynPrint(m_pInterface, ASYN_TRACE_FLOW|ASYN_TRACE_ERROR,
"PIHexapodController::moveCts() failed, GCS error %d\n", errorCode);
return asynError;
}
}
m_bAnyAxisMoving = true;
return status;
}
asynStatus PIHexapodController::getAxisPosition(PIasynAxis* pAxis, double& position)
{
if (!m_bAnyAxisMoving)
{
return PIGCSController::getAxisPosition(pAxis, position);
}
if (m_bCanReadPosWithChar3)
{
char buf[255];
asynStatus status = sendAndReceive(char(3), buf, 99);
if (status != asynSuccess)
{
return status;
}
char *pStart = buf;
for(;;)
{
bool bEnd = false;
while(*pStart == ' ') pStart++;
char *pLF = strstr(pStart, "\n");
if (pLF != NULL)
{
*pLF = '\0';
}
else
{
bEnd = true;
}
// single line will look like "X = 1.0 \n"
if (pStart[0] == pAxis->m_szAxisName[0] )
{
double value;
if (!getValue(pStart, value))
{
return asynError;
}
position = value;
return status;
}
if (bEnd)
{
break;
}
pStart = pLF + 1;
if (*pStart == '\0')
{
break;
}
}
// should not come here!
return asynError;
}
// return last position
position = double(pAxis->m_positionCts) * double(pAxis->m_CPUdenominator) / double(pAxis->m_CPUnumerator);
return asynSuccess;
}
asynStatus PIHexapodController::SetPivotX(double value)
{
if (NULL != m_pCurrentLogSink)
{
asynPrint(m_pCurrentLogSink, ASYN_TRACE_FLOW,
"PIHexapodController::SetPivotX() value %f", value);
}
asynStatus status = SetPivot('R', value);
if (status== asynSuccess)
{
m_PivotX = value;
}
return status;
}
asynStatus PIHexapodController::SetPivotY(double value)
{
if (NULL != m_pCurrentLogSink)
{
asynPrint(m_pCurrentLogSink, ASYN_TRACE_FLOW,
"PIHexapodController::SetPivotY() value %f", value);
}
asynStatus status = SetPivot('S', value);
if (status== asynSuccess)
{
m_PivotY = value;
}
return status;
}
asynStatus PIHexapodController::SetPivotZ(double value)
{
if (NULL != m_pCurrentLogSink)
{
asynPrint(m_pCurrentLogSink, ASYN_TRACE_FLOW,
"PIHexapodController::SetPivotZ() value %f", value);
}
asynStatus status = SetPivot('T', value);
if (status== asynSuccess)
{
m_PivotZ = value;
}
return status;
}
asynStatus PIHexapodController::SetPivot(char cAxis, double value)
{
if (m_bAnyAxisMoving)
{
if (NULL != m_pCurrentLogSink)
{
asynPrint(m_pCurrentLogSink, ASYN_TRACE_FLOW,
"PIHexapodController::SetPivot() cannot change pivot point while platform is moving");
}
return asynError;
}
asynStatus status;
char cmd[100];
sprintf(cmd,"SPI %c %f", cAxis, value);
status = sendOnly(cmd);
if (asynSuccess != status)
{
return status;
}
int errorCode = getGCSError();
if (errorCode != 0)
{
asynPrint(m_pInterface, ASYN_TRACE_FLOW|ASYN_TRACE_ERROR,
"PIHexapodController::SetPivot() failed, GCS error %d\n", errorCode);
return asynError;
}
return status;
}
asynStatus PIHexapodController::ReadPivotSettings()
{
char buf[100];
char cmd[] = "SPI? RST";
asynStatus status = sendAndReceive(cmd, buf, 99);
if (status != asynSuccess)
{
return status;
}
char* pStart = buf;
bool bEnd = false;
double px = 0.0;
double py = 0.0;
double pz = 0.0;
for(;;)
{
while(*pStart == ' ') pStart++;
char *pLF = strstr(pStart, "\n");
if (pLF != NULL)
{
*pLF = '\0';
}
else
{
bEnd = true;
}
// single line will look like "R = 1.0 \n"
double value;
if (!getValue(pStart, value))
{
return asynError;
}
switch(pStart[0])
{
case'R': px = value; break;
case'S': py = value; break;
case'T': pz = value; break;
}
if (bEnd)
{
break;
}
pStart = pLF + 1;
if (*pStart == '\0')
{
break;
}
}
m_PivotX = px;
m_PivotY = py;
m_PivotZ = pz;
return status;
}
asynStatus PIHexapodController::referenceVelCts( PIasynAxis* pAxis, double velocity, int forwards)
{
asynStatus status = sendOnly("INI X");
if (asynSuccess != status)
{
int errorCode = getGCSError();
asynPrint(m_pCurrentLogSink, ASYN_TRACE_ERROR,
"PIHexapodController::referenceVelCts() failed\n");
epicsSnprintf(pAxis->m_pasynUser->errorMessage,pAxis->m_pasynUser->errorMessageSize,
"PIHexapodController::referenceVelCts() failed - GCS Error %d\n",errorCode);
return status;
}
m_bHoming = true;
return asynSuccess;
}
asynStatus PIHexapodController::haltAxis(PIasynAxis* pAxis)
{
asynStatus status = sendOnly(char(24));
if (status != asynSuccess)
{
return status;
}
//epicsThreadSleep(0.1); // TODO test value
int err = getGCSError();
// controller will set error code to PI_CNTR_STOP (10)
if (err != PI_CNTR_STOP)
{
asynPrint(m_pCurrentLogSink, ASYN_TRACE_FLOW|ASYN_TRACE_ERROR,
"PIGCSController::haltAxis() failed, GCS error %d", err);
return asynError;
}
return status;
}
@@ -0,0 +1,74 @@
/*
* PIE755Controller.h
*
* Author: sra
*/
#ifndef PIHEXAPODCONTROLLER_H_
#define PIHEXAPODCONTROLLER_H_
#include "PIGCSController.h"
/**
* class representing PI Hexapods.
*/
class PIHexapodController : public PIGCSController
{
public:
PIHexapodController(asynUser* pCom, const char* szIDN)
: PIGCSController(pCom, szIDN)
{
}
~PIHexapodController() {}
virtual asynStatus init(void);
virtual asynStatus initAxis(PIasynAxis* pAxis);
virtual asynStatus setAccelerationCts( PIasynAxis* pAxis, double acceleration) { return asynSuccess; }
virtual asynStatus setAcceleration( PIasynAxis* pAxis, double acceleration) { return asynSuccess; }
virtual asynStatus getStatus(PIasynAxis* pAxis, int& homing, int& moving, int& negLimit, int& posLimit, int& servoControl);
virtual asynStatus getGlobalState(asynMotorAxis** Axes, int numAxes);
virtual asynStatus getTravelLimits(PIasynAxis* pAxis, double& negLimit, double& posLimit)
{
negLimit = -100;
posLimit = 100;
return asynSuccess;
}
virtual asynStatus getReferencedState(PIasynAxis* pAxis);
virtual asynStatus haltAxis(PIasynAxis* pAxis);
virtual bool AcceptsNewTarget() { return !m_bAnyAxisMoving; }
virtual bool CanCommunicateWhileHoming() { return false; }
virtual asynStatus moveCts( PIasynAxis* pAxis, int target);
virtual asynStatus moveCts( PIasynAxis** pAxesArray, int* pTargetCtsArray, int numAxes);
virtual asynStatus getAxisPosition(PIasynAxis* pAxis, double& position);
virtual asynStatus SetPivotX(double value);
virtual asynStatus SetPivotY(double value);
virtual asynStatus SetPivotZ(double value);
virtual double GetPivotX() { return m_PivotX; }
virtual double GetPivotY() { return m_PivotY; }
virtual double GetPivotZ() { return m_PivotZ; }
virtual asynStatus referenceVelCts( PIasynAxis* pAxis, double velocity, int forwards);
protected:
virtual asynStatus findConnectedAxes();
asynStatus ReadPivotSettings();
asynStatus SetPivot(char cAxis, double value);
double m_PivotX;
double m_PivotY;
double m_PivotZ;
bool m_bHoming;
private:
bool m_bCanReadStatusWithChar4;
bool m_bCanReadPosWithChar3;
};
#endif /* PIHEXAPODCONTROLLER_H_ */
@@ -0,0 +1,6 @@
include "asyn.dbd"
include "motorRecord.dbd"
##device(motor,VME_IO,devPIasyn,"PI Motor GCS2")
##driver(PIasyn)
registrar(PIasynDriverRegister)
##registrar(PIasynRegister)
+305
View File
@@ -0,0 +1,305 @@
/*
FILENAME... PIasynController.cpp
USAGE... Simulated Motor Support.
Based on drvMotorSim.c
Mark Rivers
December 13, 2009
*/
#include <math.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <epicsTime.h>
#include <epicsThread.h>
#include <epicsString.h>
#include <epicsMutex.h>
#include <ellLib.h>
#include <iocsh.h>
#include <epicsExport.h>
#include <motor_interface.h>
#include "PIasynAxis.h"
#include "PIasynController.h"
#include "PIGCSController.h"
//#undef asynPrint
//#define asynPrint(user,reason,format...) 0
static const char *driverName = "PIasynAxis";
PIasynAxis::PIasynAxis(PIasynController *pController, PIGCSController* pGCSController, int axis, const char* szName )
: asynMotorAxis((asynMotorController*)pController, axis)
, pController_(pController)
, m_szAxisName(NULL)
, m_isHoming(0)
, m_homed(0)
, m_acceleration(0.0)
, m_maxAcceleration(-1.0)
, m_lastDirection(0)
, m_CPUnumerator(1000)
, m_CPUdenominator(1)
, m_pasynUser(NULL)
, m_bHasLimitSwitches(false)
, m_bHasReference(false)
, m_bProblem(false)
, m_bServoControl(false)
, m_bMoving(false)
, m_pGCSController(pGCSController)
{
if (szName != NULL)
{
m_szAxisName = new char[strlen(szName)+1];
strcpy(m_szAxisName, szName);
}
printf("PIasynAxis::PIasynAxis() %d: %s\n",
axis, m_szAxisName);
}
void PIasynAxis::Init(const char *portName)
{
asynUser* logSink = pasynManager->createAsynUser(0,0);
asynStatus status = pasynManager->connectDevice(logSink, portName, getAxisNo());
if (status != asynSuccess)
{
asynPrint(logSink, ASYN_TRACE_FLOW|ASYN_TRACE_ERROR,
"PIasynController::configAxis() - connectDevice() failed\n");
return;
}
m_pGCSController->m_pCurrentLogSink = logSink;
setIntegerParam(motorAxisHasClosedLoop, 1);
m_pGCSController->initAxis(this);
double resolution;
m_pGCSController->getResolution(this, resolution);
m_pGCSController->getAxisVelocity(this);
m_pGCSController->getAxisPositionCts(this);
setDoubleParam(pController_->motorPosition_, m_positionCts);
setDoubleParam(pController_->motorMoveAbs_, m_positionCts);
m_pGCSController->getTravelLimits(this, negLimit_, posLimit_);
setDoubleParam(pController_->motorLowLimit_, negLimit_);
setDoubleParam(pController_->motorHighLimit_, posLimit_);
m_pGCSController->getReferencedState(this);
setIntegerParam( pController_->motorStatusHomed_, m_homed );
callParamCallbacks();
pasynManager->freeAsynUser(logSink);
}
PIasynAxis::~PIasynAxis()
{
if (m_szAxisName != NULL)
{
delete [] m_szAxisName;
}
}
asynStatus PIasynAxis::poll(bool *returnMoving)
{
int done = 0;
int moving, negLimit, posLimit, servoControl;
int oldHoming = m_isHoming;
m_pGCSController->getStatus(this, m_isHoming, moving, negLimit, posLimit, servoControl);
if (moving == 0 && m_isHoming == 0)
done = 1;
m_bMoving = (done!=1);
if (!m_isHoming || m_pGCSController->CanCommunicateWhileHoming())
{
if (oldHoming && oldHoming != m_isHoming)
{
m_pGCSController->getReferencedState(this);
asynPrint(pasynUser_, ASYN_TRACE_ERROR, //FIXME: ASYN_TRACE_FLOW,
"PIasynAxis::poll() axis %d referencing state changed, homed = %d\n",
axisNo_, m_homed );
}
if (m_bServoControl && servoControl == 0) // servo changed without user interaction!
{
m_bProblem = true;
}
if (!m_isHoming || m_pGCSController->IsGCS2())
{
m_bServoControl = (servoControl == 1);
m_pGCSController->getAxisPositionCts(this);
double realPosition;
m_pGCSController->getAxisPosition(this, realPosition);
setDoubleParam(pController_->PI_SUP_POSITION, realPosition );
}
}
if (m_isHoming)
{
asynPrint(pasynUser_, ASYN_TRACE_FLOW,
"PIasynAxis::poll() axis %d referencing ...\n", axisNo_ );
}
setDoubleParam(pController_->motorPosition_, m_positionCts );
setDoubleParam(pController_->motorEncoderPosition_, m_positionCts);
setIntegerParam(pController_->motorStatusDirection_, m_lastDirection);
setIntegerParam(pController_->motorStatusDone_, done );
setIntegerParam(pController_->motorStatusHighLimit_, posLimit);
setIntegerParam(pController_->motorStatusHomed_, m_homed );
setIntegerParam(pController_->motorStatusMoving_, !done );
setIntegerParam(pController_->motorStatusLowLimit_, negLimit);
setIntegerParam(pController_->motorStatusGainSupport_, true);
setIntegerParam(pController_->motorStatusProblem_, m_bProblem);
setIntegerParam(pController_->motorStatusPowerOn_, m_bServoControl);
setIntegerParam(pController_->PI_SUP_SERVO, m_bServoControl );
callParamCallbacks();
*returnMoving = m_bMoving;
}
asynStatus PIasynAxis::move(double position, int relative, double minVelocity, double maxVelocity, double acceleration)
{
m_pGCSController->m_pCurrentLogSink = pasynUser_;
asynStatus status = asynError;
static const char *functionName = "moveAxis";
if (!m_pGCSController->AcceptsNewTarget())
{
asynPrint(pasynUser_, ASYN_TRACE_ERROR|ASYN_TRACE_FLOW,
"%s:%s: Set port %s, axis %d - controller does not accept new target (busy?)\n",
driverName, functionName, pC_->portName, axisNo_ );
printf("%s:%s: Set port %s, axis %d - controller does not accept new target (busy?)\n",
driverName, functionName, pC_->portName, axisNo_ );
return status;
}
if (relative)
{
//TODO: MVR oder letztes target!
//TODO: when is this used?
}
if (pController_->movesDeferred != 0)
{ /*Deferred moves.*/
deferred_position = position;
deferred_move = 1;
deferred_relative = relative;
setIntegerParam(pController_->motorStatusDone_, 0);
callParamCallbacks();
return asynSuccess;
}
else
{
if (maxVelocity != 0)
{
status = m_pGCSController->setVelocityCts(this, maxVelocity);
if (asynSuccess != status)
{
return status;
}
}
if (acceleration != 0)
{
status = m_pGCSController->setAccelerationCts(this, acceleration);
if (asynSuccess != status)
{
return status;
}
}
setIntegerParam(pController_->motorStatusDone_, 0);
callParamCallbacks();
status = m_pGCSController->moveCts(this, position);
}
epicsEventSignal(pController_->pollEventId_);
asynPrint(pasynUser_, ASYN_TRACE_FLOW,
"%s:%s: Set driver %s, axis %d move to %f, min vel=%f, max_vel=%f, accel=%f, deffered=%d - status=%d\n",
driverName, functionName, pC_->portName, axisNo_, position, minVelocity, maxVelocity, acceleration, pController_->movesDeferred, int(status) );
return status;
}
asynStatus PIasynAxis::moveVelocity(double minVelocity, double maxVelocity, double acceleration)
{
m_pGCSController->m_pCurrentLogSink = pasynUser_;
asynStatus status = asynError;
static const char *functionName = "moveVelocityAxis";
if (!m_pGCSController->AcceptsNewTarget())
{
asynPrint(pasynUser_, ASYN_TRACE_ERROR|ASYN_TRACE_FLOW,
"%s:%s: Set port %s, axis %d - controller does not accept new target (busy?)",
driverName, functionName, pController_->portName, axisNo_ );
return status;
}
setIntegerParam(pController_->motorStatusDone_, 0);
callParamCallbacks();
double target = maxVelocity > 0 ? posLimit_ : negLimit_;
asynPrint(pasynUser_, ASYN_TRACE_FLOW,
"%s:%s: Set port %s, axis %d move with velocity of %f, accel=%f / target %f - BEFORE MOV\n",
driverName, functionName, pController_->portName, axisNo_, maxVelocity, acceleration, target );
m_pGCSController->setVelocityCts(this, maxVelocity);
m_pGCSController->move(this, target);
epicsEventSignal(pController_->pollEventId_);
asynPrint(pasynUser_, ASYN_TRACE_FLOW,
"%s:%s: Set port %s, axis %d move with velocity of %f, accel=%f / target %f - AFTER MOV\n",
driverName, functionName, pController_->portName, axisNo_, maxVelocity, acceleration, target );
return status;
}
asynStatus PIasynAxis::stop(double acceleration)
{
m_pGCSController->m_pCurrentLogSink = pasynUser_;
static const char *functionName = "stopAxis";
deferred_move = 0;
m_pGCSController->haltAxis(this);
epicsEventSignal(pController_->pollEventId_);
asynPrint(pasynUser_, ASYN_TRACE_FLOW,
"%s:%s: Set axis %d to stop with accel=%f",
driverName, functionName, axisNo_, acceleration );
return asynSuccess;
}
asynStatus PIasynAxis::home(double minVelocity, double maxVelocity, double acceleration, int forwards)
{
m_pGCSController->m_pCurrentLogSink = pasynUser_;
asynStatus status = asynError;
static const char *functionName = "homeAxis";
m_isHoming = 1;
setIntegerParam(pController_->motorStatusDone_, 0 );
callParamCallbacks();
status = m_pGCSController->referenceVelCts(this, maxVelocity, forwards);
if (asynSuccess != status)
{
return status;
}
setIntegerParam(pController_->motorStatusHomed_, m_homed );
epicsEventSignal(pController_->pollEventId_);
asynPrint(pasynUser_, ASYN_TRACE_FLOW,
"%s:%s: Set driver %s, axis %d to home %s, min vel=%f, max_vel=%f, accel=%f",
driverName, functionName, pController_->portName, axisNo_, (forwards?"FORWARDS":"REVERSE"), minVelocity, maxVelocity, acceleration );
return status;
}
+74
View File
@@ -0,0 +1,74 @@
/*
FILENAME... PIasynController.cpp
USAGE... PI GCS Motor Support.
Based on drvMotorSim.c
Mark Rivers
December 13, 2009
Steffen Rau,
January 2011
*/
#include <asynDriver.h> // for asynStatus
#include <asynMotorAxis.h>
class PIasynController;
class PIGCSController;
class PIasynAxis : public asynMotorAxis
{
public:
PIasynAxis(class PIasynController *pController, PIGCSController* pGCSController, int axis, const char* szName);
virtual~PIasynAxis();
void Init(const char *portName);
class PIasynController *pController_;
int getAxisNo() { return axisNo_; }
virtual asynStatus poll(bool *moving);
virtual asynStatus move(double position, int relative, double minVelocity, double maxVelocity, double acceleration);
virtual asynStatus moveVelocity(double minVelocity, double maxVelocity, double acceleration);
virtual asynStatus home(double minVelocity, double maxVelocity, double acceleration, int forwards);
virtual asynStatus stop(double acceleration);
char* m_szAxisName; ///< GCS name
int m_isHoming; ///< if \b TRUE indicating that axis is currently homing/referencing
double deferred_position; ///< currently not used
int deferred_move; ///< currently not used
int deferred_relative; ///< currently not used
int m_homed; ///< if \b TRUE axis was homed and absolute positions are correct
double m_velocity;
double m_acceleration;
double m_maxAcceleration;
int m_positionCts;
double m_position;
int m_lastDirection;
int m_CPUnumerator;
int m_CPUdenominator;
asynUser* m_pasynUser;
bool m_bHasLimitSwitches;
bool m_bHasReference;
bool m_bProblem;
bool m_bServoControl;
bool m_bMoving;
int m_movingStateMask;
friend class PIasynController;
private:
double negLimit_;
double posLimit_;
PIGCSController* m_pGCSController;
};
@@ -0,0 +1,527 @@
/*
FILENAME... PIasynController.cpp
USAGE... PI GCS2 Motor Support.
Based on drvMotorSim.c
from Mark Rivers, December 13, 2009
Steffen Rau, Physik Instrumente (PI) GmbH & Co KG
*/
#include <math.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <epicsTime.h>
#include <epicsThread.h>
#include <epicsString.h>
#include <epicsMutex.h>
#include <ellLib.h>
#include <iocsh.h>
#include <epicsExport.h>
#include <asynOctetSyncIO.h>
#include <motor_interface.h>
#include <ctype.h>
#include "PIasynController.h"
#include "PIGCSController.h"
#include "PIasynAxis.h"
//#undef asynPrint
//#define asynPrint(user,reason,format...) 0
static const char *driverName = "PIasynDriver";
static ELLLIST PIasynControllerList;
static int PIasynControllerListInitialized = 0;
PIasynController::PIasynController(const char *portName, const char* asynPort, int numAxes, int priority, int stackSize, int movingPollPeriod, int idlePollPeriod)
: asynMotorController(portName, numAxes, 10,
asynInt32Mask | asynFloat64Mask,
asynInt32Mask | asynFloat64Mask,
ASYN_CANBLOCK | ASYN_MULTIDEVICE,
1, // autoconnect
priority, stackSize)
, m_pGCSController( NULL )
{
createParam(PI_SUP_POSITION_String, asynParamFloat64, &PI_SUP_POSITION);
createParam(PI_SUP_TARGET_String, asynParamFloat64, &PI_SUP_TARGET);
createParam(PI_SUP_SERVO_String, asynParamInt32, &PI_SUP_SERVO);
createParam(PI_SUP_LAST_ERR_String, asynParamInt32, &PI_SUP_LAST_ERR);
createParam(PI_SUP_PIVOT_X_String, asynParamFloat64, &PI_SUP_PIVOT_X);
createParam(PI_SUP_PIVOT_Y_String, asynParamFloat64, &PI_SUP_PIVOT_Y);
createParam(PI_SUP_PIVOT_Z_String, asynParamFloat64, &PI_SUP_PIVOT_Z);
createParam(PI_SUP_RBPIVOT_X_String, asynParamFloat64, &PI_SUP_RBPIVOT_X);
createParam(PI_SUP_RBPIVOT_Y_String, asynParamFloat64, &PI_SUP_RBPIVOT_Y);
createParam(PI_SUP_RBPIVOT_Z_String, asynParamFloat64, &PI_SUP_RBPIVOT_Z);
int axis;
PIasynAxis *pAxis;
PIasynControllerNode *pNode;
if (!PIasynControllerListInitialized)
{
PIasynControllerListInitialized = 1;
ellInit(&PIasynControllerList);
}
// We should make sure this portName is not already in the list */
pNode = (PIasynControllerNode*) calloc(1, sizeof(PIasynControllerNode));
pNode->portName = epicsStrDup(portName);
pNode->pController = this;
ellAdd(&PIasynControllerList, (ELLNODE *)pNode);
asynStatus status;
asynUser* pInterface;
status = pasynOctetSyncIO->connect(asynPort, 0, &pInterface, NULL);
if (status)
{
asynPrint(pInterface, ASYN_TRACE_ERROR|ASYN_TRACE_FLOW,
"echoHandler: unable to connect to port %s\n",
asynPort);
return;
}
status = pasynOctetSyncIO->setInputEos(pInterface, "\n", 1);
if (status) {
asynPrint(pInterface, ASYN_TRACE_ERROR|ASYN_TRACE_FLOW,
"echoHandler: unable to set input EOS on %s: %s\n",
asynPort, pInterface->errorMessage);
return;
}
status = pasynOctetSyncIO->setOutputEos(pInterface, "", 0);
if (status) {
asynPrint(pInterface, ASYN_TRACE_ERROR|ASYN_TRACE_FLOW,
"echoHandler: unable to set output EOS on %s: %s\n",
asynPort, pInterface->errorMessage);
return;
}
char inputBuff[256];
inputBuff[0] = '\0';
status = PIGCSController::sendAndReceive(pInterface, "*IDN?", inputBuff, 255, pInterface);
asynPrint(pInterface, ASYN_TRACE_ERROR|ASYN_TRACE_FLOW,
"read from %s: %s\n",
asynPort, inputBuff);
char* p = inputBuff;
while (*p != '\0') { *p = toupper(*p); p++; }
m_pGCSController = PIGCSController::CreateGCSController(pInterface, inputBuff);
if (NULL == m_pGCSController)
{
asynPrint(pInterface, ASYN_TRACE_ERROR|ASYN_TRACE_FLOW,
"PIasynController: unknown controller type %s: %s\n",
asynPort, inputBuff);
return;
}
m_pGCSController->init();
if (numAxes < 1 ) numAxes = 1;
this->numAxes_ = numAxes;
if (m_pGCSController->getNrFoundAxes()<size_t(numAxes))
{
// more axes configured than connected to controller
asynPrint(pInterface, ASYN_TRACE_ERROR|ASYN_TRACE_FLOW,
"PIasynController: requested number of axes (%d) out of range, only %d axis/axes supported\n",
numAxes, int(m_pGCSController->getNrFoundAxes()));
delete m_pGCSController;
m_pGCSController = NULL;
return;
}
for (axis=0; axis<numAxes; axis++)
{
pAxis = new PIasynAxis(this, m_pGCSController, axis, m_pGCSController->getAxesID(axis));
pAxis->Init(portName);
}
startPoller(double(movingPollPeriod)/1000, double(idlePollPeriod)/1000, 10);
}
void PIasynController::report(FILE *fp, int level)
{
int axis;
PIasynAxis *pAxis;
fprintf(fp, "Simulation motor driver %s, numAxes=%d\n",
this->portName, this->numAxes_);
for (axis=0; axis<this->numAxes_; axis++)
{
pAxis = getPIAxis(axis);
fprintf(fp, " axis %d\n",
pAxis->axisNo_);
if (level > 0)
{
if (pAxis->m_isHoming)
{
fprintf(fp, " Currently homing axis\n" );
}
}
}
// Call the base class method
asynMotorController::report(fp, level);
}
//PIasynAxis * PIasynController::getPIAxis(asynUser *pasynUser)
//{
// int axis;
// PIasynAxis *pAxis;
//
// getAddress(pasynUser, &axis);
// pAxis = this->m_pAxes[axis];
// pAxis->m_pasynUser = pasynUser;
// return(pAxis);
//}
asynStatus PIasynController::processDeferredMoves()
{
asynStatus status = asynError;
int axis;
PIasynAxis *pAxesArray[PIGCSController::MAX_NR_AXES];
int targetsCts[PIGCSController::MAX_NR_AXES];
int numDeferredAxes = 0;
for (axis=0; axis<this->numAxes_; axis++)
{
PIasynAxis *pAxis = getPIAxis(axis);
if (pAxis->deferred_move)
{
pAxesArray[numDeferredAxes] = pAxis;
targetsCts[numDeferredAxes] = pAxis->deferred_position;
pAxis->setIntegerParam(motorStatusDone_, 0);
pAxis->callParamCallbacks();
numDeferredAxes++;
}
}
if (numDeferredAxes > 0)
{
status = m_pGCSController->moveCts(pAxesArray, targetsCts, numDeferredAxes);
}
for (axis=0; axis<this->numAxes_; axis++)
{
if (getPIAxis(axis)->deferred_move)
{
getPIAxis(axis)->deferred_move = 0;
}
}
epicsEventSignal(pollEventId_);
return status;
}
asynStatus PIasynController::writeInt32(asynUser *pasynUser, epicsInt32 value)
{
if (NULL == m_pGCSController)
{
asynPrint(pasynUser, ASYN_TRACE_ERROR|ASYN_TRACE_FLOW,
"PIasynController::writeInt32() GCS controller not initialized!\n");
return asynError;
}
m_pGCSController->m_pCurrentLogSink = pasynUser;
int function = pasynUser->reason;
asynStatus status = asynSuccess;
PIasynAxis *pAxis = (PIasynAxis *)this->getAxis(pasynUser);
static const char *functionName = "writeInt32";
lock();
/* Set the parameter and readback in the parameter library. This may be overwritten when we read back the
* status at the end, but that's OK */
status = pAxis->setIntegerParam(function, value);
if (function == motorSetClosedLoop_)
{
asynPrint(pasynUser, ASYN_TRACE_FLOW,
"%s:%s: %sing Closed-Loop Control flag on driver %s\n",
value != 0.0?"Enabl":"Disabl",
driverName, functionName, this->portName);
status = m_pGCSController->setServo(pAxis, (value!=0)?1:0);
}
else if (function == motorDeferMoves_)
{
asynPrint(pasynUser, ASYN_TRACE_FLOW,
"%s:%s: %sing Deferred Move flag on driver %s\n",
value != 0.0?"Sett":"Clear",
driverName, functionName, this->portName);
if (value == 0.0 && this->movesDeferred != 0)
{
processDeferredMoves();
}
this->movesDeferred = value;
} else {
/* Call base class call its method (if we have our parameters check this here) */
status = asynMotorController::writeInt32(pasynUser, value);
}
unlock();
/* Do callbacks so higher layers see any changes */
pAxis->callParamCallbacks();
if (status)
asynPrint(pasynUser, ASYN_TRACE_ERROR|ASYN_TRACE_FLOW,
"%s:%s: error, status=%d function=%d, value=%d\n",
driverName, functionName, status, function, value);
else
asynPrint(pasynUser, ASYN_TRACEIO_DRIVER,
"%s:%s: function=%d, value=%d\n",
driverName, functionName, function, value);
return status;
}
asynStatus PIasynController::writeFloat64(asynUser *pasynUser, epicsFloat64 value)
{
if (NULL == m_pGCSController)
{
asynPrint(pasynUser, ASYN_TRACE_ERROR|ASYN_TRACE_FLOW,
"PIasynController::writeFloat64() GCS controller not initialized!\n");
return asynError;
}
m_pGCSController->m_pCurrentLogSink = pasynUser;
int function = pasynUser->reason;
asynStatus status = asynSuccess;
PIasynAxis *pAxis = (PIasynAxis *)this->getAxis(pasynUser);
static const char *functionName = "writeFloat64";
/* Set the parameter and readback in the parameter library. This may be overwritten when we read back the
* status at the end, but that's OK */
status = pAxis->setDoubleParam(function, value);
if (function == PI_SUP_TARGET)
{
printf("PI_SUP_TargetAO: %f for axis %d\n", value, pAxis->axisNo_);
}
else if (function == PI_SUP_PIVOT_X)
{
status = m_pGCSController->SetPivotX(value);
}
else if (function == PI_SUP_PIVOT_Y)
{
status = m_pGCSController->SetPivotY(value);
}
else if (function == PI_SUP_PIVOT_Z)
{
status = m_pGCSController->SetPivotZ(value);
}
else if (function == motorPosition_) // Entspricht das DFH ?
{
// pAxis->enc_offset = (double) value - pAxis->nextpoint.axis[0].p;
asynPrint(pasynUser, ASYN_TRACE_FLOW,
"%s:%s: Set axis %d to position %d",
driverName, functionName, pAxis->axisNo_, value);
}
else if (function == motorResolution_ )
{
/* Call base class call its method (if we have our parameters check this here) */
status = asynMotorController::writeFloat64(pasynUser, value);
}
else if (function == motorEncRatio_ )
{
/* Call base class call its method (if we have our parameters check this here) */
status = asynMotorController::writeFloat64(pasynUser, value);
}
else
{
/* Call base class call its method (if we have our parameters check this here) */
status = asynMotorController::writeFloat64(pasynUser, value);
}
/* Do callbacks so higher layers see any changes */
pAxis->callParamCallbacks();
if (status)
asynPrint(pasynUser, ASYN_TRACE_ERROR|ASYN_TRACE_FLOW,
"%s:%s: error, status=%d function=%d, value=%f\n",
driverName, functionName, status, function, value);
else
asynPrint(pasynUser, ASYN_TRACEIO_DRIVER,
"%s:%s: function=%d, value=%f\n",
driverName, functionName, function, value);
return status;
}
asynStatus PIasynController::profileMove(asynUser *pasynUser, int npoints, double positions[], double times[], int relative, int trigger )
{
asynPrint(pasynUser, ASYN_TRACE_FLOW|ASYN_TRACE_ERROR,
"PIasynController::profileMove() - not implemented\n");
return asynError;
}
asynStatus PIasynController::triggerProfile(asynUser *pasynUser)
{
asynPrint(pasynUser, ASYN_TRACE_FLOW|ASYN_TRACE_ERROR,
"PIasynController::profileMove() - not implemented\n");
return asynError;
}
asynStatus PIasynController::configAxis(PIasynAxis *pAxis)
{
asynUser* logSink = pasynManager->createAsynUser(0,0);
asynStatus status = pasynManager->connectDevice(logSink, portName, pAxis->getAxisNo());
if (status != asynSuccess)
{
asynPrint(logSink, ASYN_TRACE_FLOW|ASYN_TRACE_ERROR,
"PIasynController::configAxis() - connectDevice() failed\n");
return status;
}
m_pGCSController->m_pCurrentLogSink = logSink;
pAxis->setIntegerParam(motorAxisHasClosedLoop, 1);
pAxis->callParamCallbacks();
m_pGCSController->initAxis(pAxis);
double resolution;
m_pGCSController->getResolution(pAxis, resolution);
m_pGCSController->getAxisVelocity(pAxis);
m_pGCSController->getAxisPositionCts(pAxis);
pAxis->setDoubleParam(this->motorPosition_, pAxis->m_positionCts);
pAxis->setDoubleParam(this->motorMoveAbs_, pAxis->m_positionCts);
double negLimit, posLimit;
m_pGCSController->getTravelLimits(pAxis, negLimit, posLimit);
pAxis->setDoubleParam(this->motorLowLimit_, negLimit);
pAxis->setDoubleParam(this->motorHighLimit_, posLimit);
m_pGCSController->getReferencedState(pAxis);
pAxis->setIntegerParam( this->motorStatusHomed_, pAxis->m_homed );
pasynManager->freeAsynUser(logSink);
/* Send a signal to the poller task which will make it do a poll,
* updating values for this axis to use the new resolution (stepSize) */
epicsEventSignal(pollEventId_);
return(asynSuccess);
}
/**\defgroup PIasynTask Routines to implement the motor axis simulation task
@{
*/
/** Process one iteration of an axis
This routine takes a single axis and propogates its motion forward a given amount
of time.
\param pAxis [in] Pointer to axis information.
\param delta [in] Time in seconds to propogate motion forwards.
\return Integer indicating 0 (asynSuccess) for success or non-zero for failure.
*/
//
//static void PIasynTaskC(void *drvPvt)
//{
// PIasynController *pController = (PIasynController*)drvPvt;
// pController->PIasynTask();
//}
//
//
//
//void PIasynController::PIasynTask()
//{
// double timeout = m_idlePollingRate;
// int axis;
// PIasynAxis *pAxis;
// epicsEventSignal(pollEventId_); /* Force on poll at startup */
//
// int status;
// while ( 1 )
// {
// if (timeout != 0.) status = epicsEventWaitWithTimeout(pollEventId_, timeout);
// else status = epicsEventWait(pollEventId_);
//
// lock();
// m_pGCSController->getGlobalState(pAxes_, numAxes_);
// unlock();
//
// bool bAnyAxisMoving = false;
// for (axis=0; axis<this->numAxes_; axis++)
// {
// lock();
// pAxis = getPIAxis(axis);
// process(pAxis);
// pAxis->callParamCallbacks();
// unlock();
// bAnyAxisMoving = (pAxis->m_bMoving != 0);
// }
// m_pGCSController->m_bAnyAxisMoving = bAnyAxisMoving;
// if (m_pGCSController->m_bAnyAxisMoving)
// timeout = m_movingPollingRate;
// else
// timeout = m_idlePollingRate;
// }
//}
asynStatus PIasynController::poll()
{
return m_pGCSController->getGlobalState(pAxes_, numAxes_);
setDoubleParam( 0, PI_SUP_RBPIVOT_X, m_pGCSController->GetPivotX());
setDoubleParam( 0, PI_SUP_RBPIVOT_Y, m_pGCSController->GetPivotY());
setDoubleParam( 0, PI_SUP_RBPIVOT_Z, m_pGCSController->GetPivotZ());
setIntegerParam( 0, PI_SUP_LAST_ERR, m_pGCSController->GetLastError() );
callParamCallbacks();
}
/** Configuration command, called directly or from iocsh */
extern "C" int PI_GCS2_CreateController(const char *portName, const char* asynPort, int numAxes, int priority, int stackSize, int movingPollingRate, int idlePollingRate)
{
PIasynController *pasynController
= new PIasynController(portName, asynPort, numAxes, priority, stackSize, movingPollingRate, idlePollingRate);
pasynController = NULL;
return(asynSuccess);
}
/** Code for iocsh registration */
static const iocshArg PI_GCS2_CreateControllerArg0 = {"Port name", iocshArgString};
static const iocshArg PI_GCS2_CreateControllerArg1 = {"asyn Port name", iocshArgString};
static const iocshArg PI_GCS2_CreateControllerArg2 = {"Number of axes", iocshArgInt};
static const iocshArg PI_GCS2_CreateControllerArg3 = {"priority", iocshArgInt};
static const iocshArg PI_GCS2_CreateControllerArg4 = {"stackSize", iocshArgInt};
static const iocshArg PI_GCS2_CreateControllerArg5 = {"moving polling time [msec]", iocshArgInt};
static const iocshArg PI_GCS2_CreateControllerArg6 = {"idle polling time [msec]", iocshArgInt};
static const iocshArg * const PI_GCS2_CreateControllerArgs[] = {&PI_GCS2_CreateControllerArg0,
&PI_GCS2_CreateControllerArg1,
&PI_GCS2_CreateControllerArg2,
&PI_GCS2_CreateControllerArg3,
&PI_GCS2_CreateControllerArg4,
&PI_GCS2_CreateControllerArg5,
&PI_GCS2_CreateControllerArg6};
static const iocshFuncDef PI_GCS2_CreateControllerDef = {"PI_GCS2_CreateController", 7, PI_GCS2_CreateControllerArgs};
static void PI_GCS2_CreateControllerCallFunc(const iocshArgBuf *args)
{
PI_GCS2_CreateController(args[0].sval, args[1].sval, args[2].ival, args[3].ival, args[4].ival, args[5].ival, args[6].ival);
}
static void PIasynDriverRegister(void)
{
iocshRegister(&PI_GCS2_CreateControllerDef, PI_GCS2_CreateControllerCallFunc);
}
extern "C" {
epicsExportRegistrar(PIasynDriverRegister);
}
@@ -0,0 +1,80 @@
/*
FILENAME... PIasynController.cpp
USAGE... Simulated Motor Support.
Based on drvMotorSim.c
Mark Rivers
December 13, 2009
*/
#ifndef PI_ASYN_DRIVER_INCLUDED_
#define PI_ASYN_DRIVER_INCLUDED_
#include "asynMotorController.h"
#include "asynMotorAxis.h"
class PIasynAxis;
class PIGCSController;
class PIasynController : asynMotorController {
public:
PIasynController(const char *portName, const char* asynPort, int numAxes, int priority, int stackSize, int movingPollPeriod, int idlePollPeriod);
asynStatus writeInt32(asynUser *pasynUser, epicsInt32 value);
asynStatus writeFloat64(asynUser *pasynUser, epicsFloat64 value);
void report(FILE *fp, int level);
asynStatus profileMove(asynUser *pasynUser, int npoints, double positions[], double times[], int relative, int trigger);
asynStatus triggerProfile(asynUser *pasynUser);
asynStatus configAxis(PIasynAxis *pAxis);
PIasynAxis* getPIAxis(asynUser *pasynUser) { return (PIasynAxis*)asynMotorController::getAxis(pasynUser); }
PIasynAxis* getPIAxis(int axisNo) { return (PIasynAxis*)asynMotorController::getAxis(axisNo); }
virtual asynStatus poll();
friend class PIasynAxis;
private:
// void process(PIasynAxis *pAxis);
epicsThreadId motorThread;
int movesDeferred;
//int numAxes;
asynStatus processDeferredMoves();
//PIasynAxis** m_pAxes;
PIGCSController* m_pGCSController;
int PI_SUP_POSITION;
int PI_SUP_TARGET;
int PI_SUP_SERVO;
int PI_SUP_LAST_ERR;
int PI_SUP_PIVOT_X;
int PI_SUP_PIVOT_Y;
int PI_SUP_PIVOT_Z;
int PI_SUP_RBPIVOT_X;
int PI_SUP_RBPIVOT_Y;
int PI_SUP_RBPIVOT_Z;
};
#define PI_SUP_POSITION_String "PI_SUP_POSITION"
#define PI_SUP_TARGET_String "PI_SUP_TARGET"
#define PI_SUP_SERVO_String "PI_SUP_SERVO"
#define PI_SUP_LAST_ERR_String "PI_SUP_LAST_ERR"
#define PI_SUP_PIVOT_X_String "PI_SUP_PIVOT_X"
#define PI_SUP_PIVOT_Y_String "PI_SUP_PIVOT_Y"
#define PI_SUP_PIVOT_Z_String "PI_SUP_PIVOT_Z"
#define PI_SUP_RBPIVOT_X_String "PI_SUP_RBPIVOT_X"
#define PI_SUP_RBPIVOT_Y_String "PI_SUP_RBPIVOT_Y"
#define PI_SUP_RBPIVOT_Z_String "PI_SUP_RBPIVOT_Z"
typedef struct PIasynControllerNode {
ELLNODE node;
const char *portName;
PIasynController *pController;
} PIasynControllerNode;
#endif // PI_ASYN_DRIVER_INCLUDED_
+61
View File
@@ -0,0 +1,61 @@
Readme for PIasyn - EPICS support for PI GCS2 stages
========================================================
The PIasyn driver is written to support PI motion controllers which
support GCS2 (General Command Set) as commanding language.
Currently this is implemented with different C++ classes where the
differences and specialties are handled. This can be implemented
by querying the controller what features are supported. So in future
developments these classes may disappear.
Homing
========
a) stages with absolute sensors
Some PI stages, mostly piezo stages, use an absolute position sensor.
The correct absolute position is known to the controller immediately after power up.
For these stages homing is not necessary and thus not supported.
These stages will ignore HOMF and HOMR.
The HOME flag of the MSTA field is meaningless for these stages
and HOMED is always true,
b) stages with incremental sensors
Some PIStages needs to be referenced after controller power up. The state
is reflected by the HOMED flag of MSTA. There are different ways to home
a stage. The default is by using the reference switch. If a stage has
a reference switch HOMF and HOMR will move to this switch. The direction is
determined by the controller. The reference signal is edge based, so the controller
can find out on which side of the reference the stage is and can move using
the shortest path. HOMF and HOMR will trigger the same move. If the stage has
no reference switch the built in limit switches can be used to determine the absolute
position. In this case HOMF will send the stage to its positive limit switch and
HOMR to its negative limit switch. As the reference is edge based or not present the
HOME bit of the MSTA field is meaningless for these stages.
c) setting the homing velocity
Reducing the velocity used for homing is usually done to improve the accuracy.
PI controllers reach the reference every time from the same "side". So only this
last approach is performed with the homing velocity set with HVEL. The coarse move
to the proximity of the reference is done with the a velocity limited by the current
velocity (set with VELO) and the maximum possible velocity to decelerate in case of
hitting a limit switch.
"Motion Errors"
=================
If the controller detects a "motion error", i.e. the difference between target and
current position is greater than some given limit (also known as "following error"),
the driver will set the PROBLEM bit in MSTA. Servo control is also switched off.
The EA_POSITION bit of MSTA will reflect the "servo control" state. To re-enable
servo control use CNEN.
C-702
=======
The C-702 controller uses an older "dialect" of GCS1.
That's why at some points different parameter IDs are used and why there is no communication
during homing. So the position cannot be updated during homing and will "jump" to the final
position after homing is finished.
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+29
View File
@@ -0,0 +1,29 @@
# CONFIG - Load build configuration data
#
# Do not make changes to this file!
# Allow user to override where the build rules come from
RULES = $(EPICS_BASE)
# RELEASE files point to other application tops
include $(TOP)/configure/RELEASE
-include $(TOP)/configure/RELEASE.$(EPICS_HOST_ARCH).Common
ifdef T_A
-include $(TOP)/configure/RELEASE.Common.$(T_A)
-include $(TOP)/configure/RELEASE.$(EPICS_HOST_ARCH).$(T_A)
endif
CONFIG = $(RULES)/configure
include $(CONFIG)/CONFIG
# Override the Base definition:
INSTALL_LOCATION = $(TOP)
# CONFIG_SITE files contain other build configuration settings
include $(TOP)/configure/CONFIG_SITE
-include $(TOP)/configure/CONFIG_SITE.$(EPICS_HOST_ARCH).Common
ifdef T_A
-include $(TOP)/configure/CONFIG_SITE.Common.$(T_A)
-include $(TOP)/configure/CONFIG_SITE.$(EPICS_HOST_ARCH).$(T_A)
endif
+33
View File
@@ -0,0 +1,33 @@
# CONFIG_SITE
# Make any application-specific changes to the EPICS build
# configuration variables in this file.
#
# Host/target specific settings can be specified in files named
# CONFIG_SITE.$(EPICS_HOST_ARCH).Common
# CONFIG_SITE.Common.$(T_A)
# CONFIG_SITE.$(EPICS_HOST_ARCH).$(T_A)
# CHECK_RELEASE controls the consistency checking of the support
# applications pointed to by the RELEASE* files.
# Normally CHECK_RELEASE should be set to YES.
# Set CHECK_RELEASE to NO to disable checking completely.
# Set CHECK_RELEASE to WARN to perform consistency checking but
# continue building anyway if conflicts are found.
CHECK_RELEASE = YES
# Set this when you only want to compile this application
# for a subset of the cross-compiled target architectures
# that Base is built for.
#CROSS_COMPILER_TARGET_ARCHS = vxWorks-68040
# To install files into a location other than $(TOP) define
# INSTALL_LOCATION here.
#INSTALL_LOCATION=</path/name/to/install/top>
# Set this when your IOC and the host use different paths
# to access the application. This will be needed to boot
# from a Microsoft FTP server or with some NFS mounts.
# You must rebuild in the iocBoot directory for this to
# take effect.
#IOCS_APPL_TOP = </IOC/path/to/application/top>
+8
View File
@@ -0,0 +1,8 @@
TOP=..
include $(TOP)/configure/CONFIG
TARGETS = $(CONFIG_TARGETS)
CONFIGS += $(subst ../,,$(wildcard $(CONFIG_INSTALLS)))
include $(TOP)/configure/RULES
+36
View File
@@ -0,0 +1,36 @@
# RELEASE - Location of external support modules
#
# IF YOU MAKE ANY CHANGES to this file you must subsequently
# do a "gnumake rebuild" in this application's top level
# directory.
#
# The build process does not check dependencies against files
# that are outside this application, thus you should do a
# "gnumake rebuild" in the top level directory after EPICS_BASE
# or any other external module pointed to below is rebuilt.
#
# Host- or target-specific settings can be given in files named
# RELEASE.$(EPICS_HOST_ARCH).Common
# RELEASE.Common.$(T_A)
# RELEASE.$(EPICS_HOST_ARCH).$(T_A)
#
# This file should ONLY define paths to other support modules,
# or include statements that pull in similar RELEASE files.
# Build settings that are NOT module paths should appear in a
# CONFIG_SITE file.
TEMPLATE_TOP=$(EPICS_BASE)/templates/makeBaseApp/top
# If using the sequencer, point SNCSEQ at its top directory:
#SNCSEQ=$(EPICS_BASE)/../modules/soft/seq
# EPICS_BASE usually appears last so other apps can override stuff:
EPICS_BASE=/home/sra/epics/base
# Set RULES here if you want to take build rules from somewhere
# other than EPICS_BASE:
#RULES=/path/to/epics/support/module/rules/x-y
ASYN=/home/sra/epics/synApps_5_6/support/asyn-4-18
MOTOR=/home/sra/epics/synApps_5_6/support/motor-6-7
+6
View File
@@ -0,0 +1,6 @@
# RULES
include $(CONFIG)/RULES
# Library should be rebuilt because LIBOBJS may have changed.
$(LIBNAME): ../Makefile
+2
View File
@@ -0,0 +1,2 @@
#RULES.ioc
include $(CONFIG)/RULES.ioc
+2
View File
@@ -0,0 +1,2 @@
#RULES_DIRS
include $(CONFIG)/RULES_DIRS
+3
View File
@@ -0,0 +1,3 @@
#RULES_TOP
include $(CONFIG)/RULES_TOP