/branches/dongfang_FC_rewrite/sendOutData.c |
---|
File deleted |
/branches/dongfang_FC_rewrite/- Copy (2).cproject |
---|
0,0 → 1,778 |
<?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.213957337"> |
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="0.213957337" moduleId="org.eclipse.cdt.core.settings" name="Default"> |
<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="${ProjName}" buildProperties="" description="" id="0.213957337" name="Default" parent="org.eclipse.cdt.build.core.prefbase.cfg"> |
<folderInfo id="0.213957337." name="/" resourcePath=""> |
<toolChain id="org.eclipse.cdt.build.core.prefbase.toolchain.1407298090" name="No ToolChain" resourceTypeBasedDiscovery="false" superClass="org.eclipse.cdt.build.core.prefbase.toolchain"> |
<targetPlatform id="org.eclipse.cdt.build.core.prefbase.toolchain.1407298090.387718105" name=""/> |
<builder id="org.eclipse.cdt.build.core.settings.default.builder.1420554535" 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.546321738" name="holder for library settings" superClass="org.eclipse.cdt.build.core.settings.holder.libs"/> |
<tool id="org.eclipse.cdt.build.core.settings.holder.1369884461" name="Assembly" superClass="org.eclipse.cdt.build.core.settings.holder"> |
<inputType id="org.eclipse.cdt.build.core.settings.holder.inType.245563341" 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.606246534" name="GNU C++" superClass="org.eclipse.cdt.build.core.settings.holder"> |
<inputType id="org.eclipse.cdt.build.core.settings.holder.inType.234895837" 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.508232992" name="GNU C" superClass="org.eclipse.cdt.build.core.settings.holder"> |
<option id="org.eclipse.cdt.build.core.settings.holder.incpaths.1552334249" name="Include Paths" superClass="org.eclipse.cdt.build.core.settings.holder.incpaths" valueType="includePath"> |
<listOptionValue builtIn="false" value=""C:\WinAVR-20100110\avr\include""/> |
</option> |
<inputType id="org.eclipse.cdt.build.core.settings.holder.inType.1030732404" 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> |
<sourceEntries> |
<entry excluding="*.d,*.o" flags="VALUE_WORKSPACE_PATH" kind="sourcePath" name=""/> |
</sourceEntries> |
</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 "${plugin_state_location}/${specs_file}"'" 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 "${plugin_state_location}/specs.cpp"'" 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 "${plugin_state_location}/specs.c"'" command="sh" useDefault="true"/> |
<parser enabled="true"/> |
</scannerInfoProvider> |
</profile> |
<profile id="org.eclipse.cdt.cross.arm.gnu.ARM_CS_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="arm-none-eabi-gcc" useDefault="true"/> |
<parser enabled="true"/> |
</scannerInfoProvider> |
</profile> |
<profile id="org.eclipse.cdt.cross.arm.gnu.ARM_CS_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="arm-none-eabi-g++" useDefault="true"/> |
<parser enabled="true"/> |
</scannerInfoProvider> |
</profile> |
<profile id="org.eclipse.cdt.cross.arm.gnu.ARM_CS_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="arm-none-eabi-gcc" useDefault="true"/> |
<parser enabled="true"/> |
</scannerInfoProvider> |
</profile> |
<profile id="org.eclipse.cdt.cross.arm.gnu.ARM_CS_GCCStandardMakePerFileProfile"> |
<buildOutputProvider> |
<openAction enabled="true" filePath=""/> |
<parser enabled="true"/> |
</buildOutputProvider> |
<scannerInfoProvider id="makefileGenerator"> |
<runAction arguments="-f ${project_name}_scd.mk" command="make" useDefault="true"/> |
<parser enabled="true"/> |
</scannerInfoProvider> |
</profile> |
<profile id="org.eclipse.cdt.cross.arm.gnu.ARM_CS_GCCWinManagedMakePerProjectProfileC"> |
<buildOutputProvider> |
<openAction enabled="true" filePath=""/> |
<parser enabled="true"/> |
</buildOutputProvider> |
<scannerInfoProvider id="specsFile"> |
<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.c" command="arm-none-eabi-gcc" useDefault="true"/> |
<parser enabled="true"/> |
</scannerInfoProvider> |
</profile> |
<profile id="org.eclipse.cdt.cross.arm.gnu.ARM_CS_GCCWinManagedMakePerProjectProfileCPP"> |
<buildOutputProvider> |
<openAction enabled="true" filePath=""/> |
<parser enabled="true"/> |
</buildOutputProvider> |
<scannerInfoProvider id="specsFile"> |
<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.cpp" command="arm-none-eabi-g++" useDefault="true"/> |
<parser enabled="true"/> |
</scannerInfoProvider> |
</profile> |
<profile id="org.eclipse.cdt.cross.arm.gnu.ARM_CS_GCCWinStandardMakePerProjectProfile"> |
<buildOutputProvider> |
<openAction enabled="true" filePath=""/> |
<parser enabled="true"/> |
</buildOutputProvider> |
<scannerInfoProvider id="specsFile"> |
<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="arm-none-eabi-gcc" useDefault="true"/> |
<parser enabled="true"/> |
</scannerInfoProvider> |
</profile> |
<profile id="org.eclipse.cdt.cross.arm.gnu.ARM_CS_GCCWinStandardMakePerFileProfile"> |
<buildOutputProvider> |
<openAction enabled="true" filePath=""/> |
<parser enabled="true"/> |
</buildOutputProvider> |
<scannerInfoProvider id="makefileGenerator"> |
<runAction arguments="-f ${project_name}_scd.mk" command="cs-make" useDefault="true"/> |
<parser enabled="true"/> |
</scannerInfoProvider> |
</profile> |
<profile id="org.eclipse.cdt.cross.arm.gnu.ARM_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="arm-elf-gcc" useDefault="true"/> |
<parser enabled="true"/> |
</scannerInfoProvider> |
</profile> |
<profile id="org.eclipse.cdt.cross.arm.gnu.ARM_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="arm-elf-g++" useDefault="true"/> |
<parser enabled="true"/> |
</scannerInfoProvider> |
</profile> |
<profile id="org.eclipse.cdt.cross.arm.gnu.ARM_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="arm-elf-gcc" useDefault="true"/> |
<parser enabled="true"/> |
</scannerInfoProvider> |
</profile> |
<profile id="org.eclipse.cdt.cross.arm.gnu.ARM_GCCStandardMakePerFileProfile"> |
<buildOutputProvider> |
<openAction enabled="true" filePath=""/> |
<parser enabled="true"/> |
</buildOutputProvider> |
<scannerInfoProvider id="makefileGenerator"> |
<runAction arguments="-f ${project_name}_scd.mk" command="make" useDefault="true"/> |
<parser enabled="true"/> |
</scannerInfoProvider> |
</profile> |
<profile id="org.eclipse.cdt.cross.arm.gnu.ARM_GCCWinManagedMakePerProjectProfileC"> |
<buildOutputProvider> |
<openAction enabled="true" filePath=""/> |
<parser enabled="true"/> |
</buildOutputProvider> |
<scannerInfoProvider id="specsFile"> |
<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.c" command="arm-elf-gcc" useDefault="true"/> |
<parser enabled="true"/> |
</scannerInfoProvider> |
</profile> |
<profile id="org.eclipse.cdt.cross.arm.gnu.ARM_GCCWinManagedMakePerProjectProfileCPP"> |
<buildOutputProvider> |
<openAction enabled="true" filePath=""/> |
<parser enabled="true"/> |
</buildOutputProvider> |
<scannerInfoProvider id="specsFile"> |
<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.cpp" command="arm-elf-g++" useDefault="true"/> |
<parser enabled="true"/> |
</scannerInfoProvider> |
</profile> |
<profile id="org.eclipse.cdt.cross.arm.gnu.ARM_GCCWinStandardMakePerProjectProfile"> |
<buildOutputProvider> |
<openAction enabled="true" filePath=""/> |
<parser enabled="true"/> |
</buildOutputProvider> |
<scannerInfoProvider id="specsFile"> |
<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="arm-elf-gcc" useDefault="true"/> |
<parser enabled="true"/> |
</scannerInfoProvider> |
</profile> |
<profile id="org.eclipse.cdt.cross.arm.gnu.ARM_GCCWinStandardMakePerFileProfile"> |
<buildOutputProvider> |
<openAction enabled="true" filePath=""/> |
<parser enabled="true"/> |
</buildOutputProvider> |
<scannerInfoProvider id="makefileGenerator"> |
<runAction arguments="-f ${project_name}_scd.mk" command="make" useDefault="true"/> |
<parser enabled="true"/> |
</scannerInfoProvider> |
</profile> |
<profile id="org.eclipse.cdt.cross.arm.gnu.ARM_YG_GCCWinManagedMakePerProjectProfileC"> |
<buildOutputProvider> |
<openAction enabled="true" filePath=""/> |
<parser enabled="true"/> |
</buildOutputProvider> |
<scannerInfoProvider id="specsFile"> |
<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.c" command="arm-none-eabi-gcc" useDefault="true"/> |
<parser enabled="true"/> |
</scannerInfoProvider> |
</profile> |
<profile id="org.eclipse.cdt.cross.arm.gnu.ARM_YG_GCCWinManagedMakePerProjectProfileCPP"> |
<buildOutputProvider> |
<openAction enabled="true" filePath=""/> |
<parser enabled="true"/> |
</buildOutputProvider> |
<scannerInfoProvider id="specsFile"> |
<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.cpp" command="arm-none-eabi-g++" useDefault="true"/> |
<parser enabled="true"/> |
</scannerInfoProvider> |
</profile> |
<profile id="org.eclipse.cdt.cross.arm.gnu.ARM_YG_GCCWinStandardMakePerProjectProfile"> |
<buildOutputProvider> |
<openAction enabled="true" filePath=""/> |
<parser enabled="true"/> |
</buildOutputProvider> |
<scannerInfoProvider id="specsFile"> |
<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="arm-none-eabi-gcc" useDefault="true"/> |
<parser enabled="true"/> |
</scannerInfoProvider> |
</profile> |
<profile id="org.eclipse.cdt.cross.arm.gnu.ARM_YG_GCCWinStandardMakePerFileProfile"> |
<buildOutputProvider> |
<openAction enabled="true" filePath=""/> |
<parser enabled="true"/> |
</buildOutputProvider> |
<scannerInfoProvider id="makefileGenerator"> |
<runAction arguments="-f ${project_name}_scd.mk" command="make" useDefault="true"/> |
<parser enabled="true"/> |
</scannerInfoProvider> |
</profile> |
<profile id="org.eclipse.cdt.cross.arm.gnu.ARM_DK_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="arm-eabi-gcc" useDefault="true"/> |
<parser enabled="true"/> |
</scannerInfoProvider> |
</profile> |
<profile id="org.eclipse.cdt.cross.arm.gnu.ARM_DK_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="arm-eabi-g++" useDefault="true"/> |
<parser enabled="true"/> |
</scannerInfoProvider> |
</profile> |
<profile id="org.eclipse.cdt.cross.arm.gnu.ARM_DK_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="arm-eabi-gcc" useDefault="true"/> |
<parser enabled="true"/> |
</scannerInfoProvider> |
</profile> |
<profile id="org.eclipse.cdt.cross.arm.gnu.ARM_DK_GCCStandardMakePerFileProfile"> |
<buildOutputProvider> |
<openAction enabled="true" filePath=""/> |
<parser enabled="true"/> |
</buildOutputProvider> |
<scannerInfoProvider id="makefileGenerator"> |
<runAction arguments="-f ${project_name}_scd.mk" command="make" useDefault="true"/> |
<parser enabled="true"/> |
</scannerInfoProvider> |
</profile> |
<profile id="org.eclipse.cdt.cross.arm.gnu.ARM_DK_GCCWinManagedMakePerProjectProfileC"> |
<buildOutputProvider> |
<openAction enabled="true" filePath=""/> |
<parser enabled="true"/> |
</buildOutputProvider> |
<scannerInfoProvider id="specsFile"> |
<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.c" command="arm-eabi-gcc" useDefault="true"/> |
<parser enabled="true"/> |
</scannerInfoProvider> |
</profile> |
<profile id="org.eclipse.cdt.cross.arm.gnu.ARM_DK_GCCWinManagedMakePerProjectProfileCPP"> |
<buildOutputProvider> |
<openAction enabled="true" filePath=""/> |
<parser enabled="true"/> |
</buildOutputProvider> |
<scannerInfoProvider id="specsFile"> |
<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.cpp" command="arm-eabi-g++" useDefault="true"/> |
<parser enabled="true"/> |
</scannerInfoProvider> |
</profile> |
<profile id="org.eclipse.cdt.cross.arm.gnu.ARM_DK_GCCWinStandardMakePerProjectProfile"> |
<buildOutputProvider> |
<openAction enabled="true" filePath=""/> |
<parser enabled="true"/> |
</buildOutputProvider> |
<scannerInfoProvider id="specsFile"> |
<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="arm-eabi-gcc" useDefault="true"/> |
<parser enabled="true"/> |
</scannerInfoProvider> |
</profile> |
<profile id="org.eclipse.cdt.cross.arm.gnu.ARM_DK_GCCWinStandardMakePerFileProfile"> |
<buildOutputProvider> |
<openAction enabled="true" filePath=""/> |
<parser enabled="true"/> |
</buildOutputProvider> |
<scannerInfoProvider id="makefileGenerator"> |
<runAction arguments="-f ${project_name}_scd.mk" command="make" useDefault="true"/> |
<parser enabled="true"/> |
</scannerInfoProvider> |
</profile> |
<scannerConfigBuildInfo instanceId="0.213957337"> |
<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 "${plugin_state_location}/${specs_file}"'" 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 "${plugin_state_location}/specs.cpp"'" 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 "${plugin_state_location}/specs.c"'" command="sh" useDefault="true"/> |
<parser enabled="true"/> |
</scannerInfoProvider> |
</profile> |
<profile id="org.eclipse.cdt.cross.arm.gnu.ARM_CS_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="arm-none-eabi-gcc" useDefault="true"/> |
<parser enabled="true"/> |
</scannerInfoProvider> |
</profile> |
<profile id="org.eclipse.cdt.cross.arm.gnu.ARM_CS_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="arm-none-eabi-g++" useDefault="true"/> |
<parser enabled="true"/> |
</scannerInfoProvider> |
</profile> |
<profile id="org.eclipse.cdt.cross.arm.gnu.ARM_CS_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="arm-none-eabi-gcc" useDefault="true"/> |
<parser enabled="true"/> |
</scannerInfoProvider> |
</profile> |
<profile id="org.eclipse.cdt.cross.arm.gnu.ARM_CS_GCCStandardMakePerFileProfile"> |
<buildOutputProvider> |
<openAction enabled="true" filePath=""/> |
<parser enabled="true"/> |
</buildOutputProvider> |
<scannerInfoProvider id="makefileGenerator"> |
<runAction arguments="-f ${project_name}_scd.mk" command="make" useDefault="true"/> |
<parser enabled="true"/> |
</scannerInfoProvider> |
</profile> |
<profile id="org.eclipse.cdt.cross.arm.gnu.ARM_CS_GCCWinManagedMakePerProjectProfileC"> |
<buildOutputProvider> |
<openAction enabled="true" filePath=""/> |
<parser enabled="true"/> |
</buildOutputProvider> |
<scannerInfoProvider id="specsFile"> |
<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.c" command="arm-none-eabi-gcc" useDefault="true"/> |
<parser enabled="true"/> |
</scannerInfoProvider> |
</profile> |
<profile id="org.eclipse.cdt.cross.arm.gnu.ARM_CS_GCCWinManagedMakePerProjectProfileCPP"> |
<buildOutputProvider> |
<openAction enabled="true" filePath=""/> |
<parser enabled="true"/> |
</buildOutputProvider> |
<scannerInfoProvider id="specsFile"> |
<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.cpp" command="arm-none-eabi-g++" useDefault="true"/> |
<parser enabled="true"/> |
</scannerInfoProvider> |
</profile> |
<profile id="org.eclipse.cdt.cross.arm.gnu.ARM_CS_GCCWinStandardMakePerProjectProfile"> |
<buildOutputProvider> |
<openAction enabled="true" filePath=""/> |
<parser enabled="true"/> |
</buildOutputProvider> |
<scannerInfoProvider id="specsFile"> |
<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="arm-none-eabi-gcc" useDefault="true"/> |
<parser enabled="true"/> |
</scannerInfoProvider> |
</profile> |
<profile id="org.eclipse.cdt.cross.arm.gnu.ARM_CS_GCCWinStandardMakePerFileProfile"> |
<buildOutputProvider> |
<openAction enabled="true" filePath=""/> |
<parser enabled="true"/> |
</buildOutputProvider> |
<scannerInfoProvider id="makefileGenerator"> |
<runAction arguments="-f ${project_name}_scd.mk" command="cs-make" useDefault="true"/> |
<parser enabled="true"/> |
</scannerInfoProvider> |
</profile> |
<profile id="org.eclipse.cdt.cross.arm.gnu.ARM_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="arm-elf-gcc" useDefault="true"/> |
<parser enabled="true"/> |
</scannerInfoProvider> |
</profile> |
<profile id="org.eclipse.cdt.cross.arm.gnu.ARM_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="arm-elf-g++" useDefault="true"/> |
<parser enabled="true"/> |
</scannerInfoProvider> |
</profile> |
<profile id="org.eclipse.cdt.cross.arm.gnu.ARM_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="arm-elf-gcc" useDefault="true"/> |
<parser enabled="true"/> |
</scannerInfoProvider> |
</profile> |
<profile id="org.eclipse.cdt.cross.arm.gnu.ARM_GCCStandardMakePerFileProfile"> |
<buildOutputProvider> |
<openAction enabled="true" filePath=""/> |
<parser enabled="true"/> |
</buildOutputProvider> |
<scannerInfoProvider id="makefileGenerator"> |
<runAction arguments="-f ${project_name}_scd.mk" command="make" useDefault="true"/> |
<parser enabled="true"/> |
</scannerInfoProvider> |
</profile> |
<profile id="org.eclipse.cdt.cross.arm.gnu.ARM_GCCWinManagedMakePerProjectProfileC"> |
<buildOutputProvider> |
<openAction enabled="true" filePath=""/> |
<parser enabled="true"/> |
</buildOutputProvider> |
<scannerInfoProvider id="specsFile"> |
<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.c" command="arm-elf-gcc" useDefault="true"/> |
<parser enabled="true"/> |
</scannerInfoProvider> |
</profile> |
<profile id="org.eclipse.cdt.cross.arm.gnu.ARM_GCCWinManagedMakePerProjectProfileCPP"> |
<buildOutputProvider> |
<openAction enabled="true" filePath=""/> |
<parser enabled="true"/> |
</buildOutputProvider> |
<scannerInfoProvider id="specsFile"> |
<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.cpp" command="arm-elf-g++" useDefault="true"/> |
<parser enabled="true"/> |
</scannerInfoProvider> |
</profile> |
<profile id="org.eclipse.cdt.cross.arm.gnu.ARM_GCCWinStandardMakePerProjectProfile"> |
<buildOutputProvider> |
<openAction enabled="true" filePath=""/> |
<parser enabled="true"/> |
</buildOutputProvider> |
<scannerInfoProvider id="specsFile"> |
<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="arm-elf-gcc" useDefault="true"/> |
<parser enabled="true"/> |
</scannerInfoProvider> |
</profile> |
<profile id="org.eclipse.cdt.cross.arm.gnu.ARM_GCCWinStandardMakePerFileProfile"> |
<buildOutputProvider> |
<openAction enabled="true" filePath=""/> |
<parser enabled="true"/> |
</buildOutputProvider> |
<scannerInfoProvider id="makefileGenerator"> |
<runAction arguments="-f ${project_name}_scd.mk" command="make" useDefault="true"/> |
<parser enabled="true"/> |
</scannerInfoProvider> |
</profile> |
<profile id="org.eclipse.cdt.cross.arm.gnu.ARM_YG_GCCWinManagedMakePerProjectProfileC"> |
<buildOutputProvider> |
<openAction enabled="true" filePath=""/> |
<parser enabled="true"/> |
</buildOutputProvider> |
<scannerInfoProvider id="specsFile"> |
<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.c" command="arm-none-eabi-gcc" useDefault="true"/> |
<parser enabled="true"/> |
</scannerInfoProvider> |
</profile> |
<profile id="org.eclipse.cdt.cross.arm.gnu.ARM_YG_GCCWinManagedMakePerProjectProfileCPP"> |
<buildOutputProvider> |
<openAction enabled="true" filePath=""/> |
<parser enabled="true"/> |
</buildOutputProvider> |
<scannerInfoProvider id="specsFile"> |
<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.cpp" command="arm-none-eabi-g++" useDefault="true"/> |
<parser enabled="true"/> |
</scannerInfoProvider> |
</profile> |
<profile id="org.eclipse.cdt.cross.arm.gnu.ARM_YG_GCCWinStandardMakePerProjectProfile"> |
<buildOutputProvider> |
<openAction enabled="true" filePath=""/> |
<parser enabled="true"/> |
</buildOutputProvider> |
<scannerInfoProvider id="specsFile"> |
<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="arm-none-eabi-gcc" useDefault="true"/> |
<parser enabled="true"/> |
</scannerInfoProvider> |
</profile> |
<profile id="org.eclipse.cdt.cross.arm.gnu.ARM_YG_GCCWinStandardMakePerFileProfile"> |
<buildOutputProvider> |
<openAction enabled="true" filePath=""/> |
<parser enabled="true"/> |
</buildOutputProvider> |
<scannerInfoProvider id="makefileGenerator"> |
<runAction arguments="-f ${project_name}_scd.mk" command="make" useDefault="true"/> |
<parser enabled="true"/> |
</scannerInfoProvider> |
</profile> |
<profile id="org.eclipse.cdt.cross.arm.gnu.ARM_DK_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="arm-eabi-gcc" useDefault="true"/> |
<parser enabled="true"/> |
</scannerInfoProvider> |
</profile> |
<profile id="org.eclipse.cdt.cross.arm.gnu.ARM_DK_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="arm-eabi-g++" useDefault="true"/> |
<parser enabled="true"/> |
</scannerInfoProvider> |
</profile> |
<profile id="org.eclipse.cdt.cross.arm.gnu.ARM_DK_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="arm-eabi-gcc" useDefault="true"/> |
<parser enabled="true"/> |
</scannerInfoProvider> |
</profile> |
<profile id="org.eclipse.cdt.cross.arm.gnu.ARM_DK_GCCStandardMakePerFileProfile"> |
<buildOutputProvider> |
<openAction enabled="true" filePath=""/> |
<parser enabled="true"/> |
</buildOutputProvider> |
<scannerInfoProvider id="makefileGenerator"> |
<runAction arguments="-f ${project_name}_scd.mk" command="make" useDefault="true"/> |
<parser enabled="true"/> |
</scannerInfoProvider> |
</profile> |
<profile id="org.eclipse.cdt.cross.arm.gnu.ARM_DK_GCCWinManagedMakePerProjectProfileC"> |
<buildOutputProvider> |
<openAction enabled="true" filePath=""/> |
<parser enabled="true"/> |
</buildOutputProvider> |
<scannerInfoProvider id="specsFile"> |
<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.c" command="arm-eabi-gcc" useDefault="true"/> |
<parser enabled="true"/> |
</scannerInfoProvider> |
</profile> |
<profile id="org.eclipse.cdt.cross.arm.gnu.ARM_DK_GCCWinManagedMakePerProjectProfileCPP"> |
<buildOutputProvider> |
<openAction enabled="true" filePath=""/> |
<parser enabled="true"/> |
</buildOutputProvider> |
<scannerInfoProvider id="specsFile"> |
<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.cpp" command="arm-eabi-g++" useDefault="true"/> |
<parser enabled="true"/> |
</scannerInfoProvider> |
</profile> |
<profile id="org.eclipse.cdt.cross.arm.gnu.ARM_DK_GCCWinStandardMakePerProjectProfile"> |
<buildOutputProvider> |
<openAction enabled="true" filePath=""/> |
<parser enabled="true"/> |
</buildOutputProvider> |
<scannerInfoProvider id="specsFile"> |
<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="arm-eabi-gcc" useDefault="true"/> |
<parser enabled="true"/> |
</scannerInfoProvider> |
</profile> |
<profile id="org.eclipse.cdt.cross.arm.gnu.ARM_DK_GCCWinStandardMakePerFileProfile"> |
<buildOutputProvider> |
<openAction enabled="true" filePath=""/> |
<parser enabled="true"/> |
</buildOutputProvider> |
<scannerInfoProvider id="makefileGenerator"> |
<runAction arguments="-f ${project_name}_scd.mk" command="make" useDefault="true"/> |
<parser enabled="true"/> |
</scannerInfoProvider> |
</profile> |
</scannerConfigBuildInfo> |
</storageModule> |
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/> |
<storageModule moduleId="org.eclipse.cdt.internal.ui.text.commentOwnerProjectMappings"/> |
<storageModule moduleId="org.eclipse.cdt.core.language.mapping"/> |
</cconfiguration> |
</storageModule> |
<storageModule moduleId="cdtBuildSystem" version="4.0.0"> |
<project id="dongfang_FC_rewrite.null.1063235677" name="dongfang_FC_rewrite"/> |
</storageModule> |
</cproject> |
/branches/dongfang_FC_rewrite/ADXRS610_FC2.0.c |
---|
1,18 → 1,19 |
#include "ADXRS610_FC2.0.h" |
#include "configuration.h" |
const uint8_t GYRO_REVERSED[3] = {0,0,0}; |
const uint8_t ACC_REVERSED[3] = {0,1,0}; |
const uint8_t GYRO_REVERSED[3] = { 0, 0, 0 }; |
const uint8_t ACC_REVERSED[3] = { 0, 1, 0 }; |
void gyro_calibrate(void) {} |
void gyro_calibrate(void) { |
} |
void gyro_setDefaults(void) { |
staticParams.GyroD = 5; |
staticParams.DriftComp = 10; |
staticParams.GyroAccFactor = 1; |
staticParams.GyroAccTrim = 5; |
staticParams.GyroD = 5; |
staticParams.DriftComp = 10; |
staticParams.GyroAccFactor = 1; |
staticParams.GyroAccTrim = 5; |
// Not used. |
staticParams.AngleTurnOverPitch = 78; |
staticParams.AngleTurnOverRoll = 78; |
// Not used. |
staticParams.AngleTurnOverPitch = 78; |
staticParams.AngleTurnOverRoll = 78; |
} |
/branches/dongfang_FC_rewrite/ENC-03_FC1.3.c |
---|
8,62 → 8,68 |
#define PITCHROLL_MINLIMIT GYRO_SUMMATION_FACTOR_PITCHROLL * 510 |
#define PITCHROLL_MAXLIMIT GYRO_SUMMATION_FACTOR_PITCHROLL * 515 |
const uint8_t GYRO_REVERSED[3] = {0,0,1}; |
const uint8_t ACC_REVERSED[3] = {0,1,0}; |
const uint8_t GYRO_REVERSED[3] = { 0, 0, 1 }; |
const uint8_t ACC_REVERSED[3] = { 0, 1, 0 }; |
// void gyro_init(void) {} |
void gyro_calibrate(void) { |
uint8_t i, axis, factor, numberOfAxesInRange = 0; |
uint16_t timeout; |
// GyroDefectNick = 0; GyroDefectRoll = 0; GyroDefectYaw = 0; |
timeout = SetDelay(2000); |
uint8_t i, axis, factor, numberOfAxesInRange = 0; |
uint16_t timeout; |
// GyroDefectNick = 0; GyroDefectRoll = 0; GyroDefectYaw = 0; |
timeout = SetDelay(2000); |
for(i = 140; i != 0; i--) { |
// If all 3 axis are in range, shorten the remaining number of iterations. |
if(numberOfAxesInRange == 3 && i > 10) i = 9; |
numberOfAxesInRange = 0; |
for (axis=PITCH; axis<=YAW; axis++) { |
if (axis==YAW) factor = GYRO_SUMMATION_FACTOR_YAW; |
else factor = GYRO_SUMMATION_FACTOR_PITCHROLL; |
if(rawGyroSum[axis] < 510 * factor) DACValues[axis]--; |
else if(rawGyroSum[axis] > 515 * factor) DACValues[axis]++; |
else numberOfAxesInRange++; |
/* Gyro is defective. But do keep DAC within bounds (it's an op amp not a differential amp). */ |
if(DACValues[axis] < 10) { |
DACValues[axis] = 10; |
} else if(DACValues[axis] > 245) { |
DACValues[axis] = 245; |
for (i = 140; i != 0; i--) { |
// If all 3 axis are in range, shorten the remaining number of iterations. |
if (numberOfAxesInRange == 3 && i > 10) |
i = 9; |
numberOfAxesInRange = 0; |
for (axis = PITCH; axis <= YAW; axis++) { |
if (axis == YAW) |
factor = GYRO_SUMMATION_FACTOR_YAW; |
else |
factor = GYRO_SUMMATION_FACTOR_PITCHROLL; |
if (rawGyroSum[axis] < 510 * factor) |
DACValues[axis]--; |
else if (rawGyroSum[axis] > 515 * factor) |
DACValues[axis]++; |
else |
numberOfAxesInRange++; |
/* Gyro is defective. But do keep DAC within bounds (it's an op amp not a differential amp). */ |
if (DACValues[axis] < 10) { |
DACValues[axis] = 10; |
} else if (DACValues[axis] > 245) { |
DACValues[axis] = 245; |
} |
} |
I2C_Start(TWI_STATE_GYRO_OFFSET_TX); // initiate data transmission |
// Wait for I2C to finish transmission. |
while (twi_state) { |
// Did it take too long? |
if (CheckDelay(timeout)) { |
printf("\r\n DAC or I2C Error! check I2C, 3Vref, DAC, and BL-Ctrl"); |
break; |
} |
} |
analog_start(); |
Delay_ms_Mess(i < 10 ? 10 : 2); |
} |
} |
I2C_Start(TWI_STATE_GYRO_OFFSET_TX); // initiate data transmission |
// Wait for I2C to finish transmission. |
while(twi_state) { |
// Did it take too long? |
if(CheckDelay(timeout)) { |
printf("\r\n DAC or I2C Error! check I2C, 3Vref, DAC, and BL-Ctrl"); |
break; |
} |
} |
analog_start(); |
Delay_ms_Mess(i<10 ? 10 : 2); |
} |
Delay_ms_Mess(70); |
Delay_ms_Mess(70); |
} |
void gyro_setDefaults(void) { |
staticParams.GyroD = 3; |
staticParams.DriftComp = 250; |
staticParams.GyroAccFactor = 10; |
staticParams.GyroAccTrim = 1; |
staticParams.GyroD = 3; |
staticParams.DriftComp = 250; |
staticParams.GyroAccFactor = 10; |
staticParams.GyroAccTrim = 1; |
// Not used. |
staticParams.AngleTurnOverPitch = 85; |
staticParams.AngleTurnOverRoll = 85; |
// Not used. |
staticParams.AngleTurnOverPitch = 85; |
staticParams.AngleTurnOverRoll = 85; |
} |
/branches/dongfang_FC_rewrite/ENC-03_FC1.3.h |
---|
1,26 → 1,26 |
/* |
#ifndef _ENC03_FC13_H |
#define _ENC03_FC13_H |
#ifndef _ENC03_FC13_H |
#define _ENC03_FC13_H |
#include "sensors.h" |
/ * |
#include "sensors.h" |
/ * |
* Configuration for the ENC-03 gyros and oriented and wired on FC 1.3 (with DAC). |
* / |
#define GYRO_HW_NAME "ENC" |
#define GYRO_HW_FACTOR 1.304f |
#define GYRO_HW_NAME "ENC" |
#define GYRO_HW_FACTOR 1.304f |
/ * |
/ * |
* Correction factor - determined experimentally: Hold the copter in the hand, and turn it 90 degrees. |
* If AnglePitch or AngleRoll in debug in MK-Tool changes by x degrees, multiply the value here by x/90. |
* If the hardware related contants are set correctly, flight should be OK without bothering to |
* make any adjustments here. It is only for luxury. |
* / |
#define GYRO_PITCHROLL_CORRECTION 1.11f |
#define GYRO_PITCHROLL_CORRECTION 1.11f |
/ * |
/ * |
* Same for yaw. |
* / |
#define GYRO_YAW_CORRECTION 1.28f |
#endif |
*/ |
#define GYRO_YAW_CORRECTION 1.28f |
#endif |
*/ |
/branches/dongfang_FC_rewrite/Flight-Ctrl_MEGA644p_MK3MAG__invenSense_V0_74df_SVN0001.hex |
---|
0,0 → 1,2113 |
:100000000C945C040C9479040C9479040C94790499 |
:100010000C9479040C9479040C9479040C9479046C |
:100020000C9479040C94E0130C9479040C947904E6 |
:100030000C9406260C9479040C9479040C9479049D |
:100040000C9479040C9479040C9439130C9479046D |
:100050000C94BB060C9479040C9484060C947904DB |
:100060000C9438140C9479040C9498230C9479040F |
:100070000C9461390C9479040C9479040A0A0D00EB |
:100080004E65757472616C20284143432D4D6F6439 |
:1000900065290048656164696E67486F6C64000A91 |
:1000A0000D436F6E74726F6C3A20000A0D537570B9 |
:1000B000706F727420666F722047505320617420F5 |
:1000C0003173742055415254000A0D537570706F8E |
:1000D000727420666F722047505320617420326E14 |
:1000E000642055415254000A0D537570706F72743C |
:1000F00020666F72204D4B334D414720436F6D702A |
:10010000617373000A0D3D3D3D3D3D3D3D3D3D3D2F |
:100110003D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D0F |
:100120003D3D3D3D3D3D3D3D3D000A0D3D3D3D3D9F |
:100130003D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3DEF |
:100140003D3D3D3D3D3D3D3D3D3D3D3D3D3D3D001C |
:100150000A0D536F6674776172653A205625642ED6 |
:10016000256425630070000D0A20202020204350C4 |
:10017000553A2041746D656761363434000A0D4884 |
:10018000617264776172653A20437573746F6D00B4 |
:100190000A0D466C69676874436F6E74726F6C0009 |
:1001A0000A0D3D3D3D3D3D3D3D3D3D3D3D3D3D3DE2 |
:1001B0003D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D6F |
:1001C0003D3D3D3D3D00416E676C6550697463681F |
:1001D000202020202020416E676C65526F6C6C20BF |
:1001E000202020202020416E676C655961772020F7 |
:1001F0002020202020204779726F5069746368287E |
:100200005049442920204779726F526F6C6C2850F6 |
:100210004944292020204779726F59617720202096 |
:100220002020202020204779726F5069746368284D |
:100230004143292020204779726F526F6C6C28410E |
:100240004329202020204779726F59617728414344 |
:10025000292020202020416363506974636820288E |
:10026000616E676C6529416363526F6C6C20286115 |
:100270006E676C6529205542617420202020202063 |
:100280002020202020205069746368205465726DFE |
:10029000202020202020526F6C6C205465726D202D |
:1002A000202020202020596177205465726D202065 |
:1002B0002020202020205468726F74746C652054B4 |
:1002C00065726D202020307468204F20436F727259 |
:1002D000207069746368307468204F20436F7272B5 |
:1002E00020726F6C6C204472696674436F6D704449 |
:1002F000656C746120504472696674436F6D70441C |
:10030000656C746120524144506974636847797226 |
:100310006F4F666673204144526F6C6C4779726F01 |
:100320004F66667320204D31202020202020202081 |
:100330002020202020204D3220202020202020207E |
:100340002020202020204D3320202020202020206D |
:100350002020202020204D3420202020202020205C |
:10036000202020202020436F6E74726F6C596177BB |
:1003700020202020202041697270726573732E2026 |
:1003800052616E6765204472696674436F6D705088 |
:100390006974636820204472696674436F6D70529B |
:1003A0006F6C6C20202041697270726573734669AE |
:1003B0006C746572656441697270726573734144EF |
:1003C000432020202020020100070603020105022D |
:1003D00001000706030201043132003131003130DF |
:1003E000002025632020202D2020202D2020202DBE |
:1003F0002000202563202020256320202025632045 |
:100400002020256320002025632020202563202034 |
:1004100020256320202025632000424C2D43747248 |
:100420006C20666F756E64200020253364202025C3 |
:1004300033642020253364202025336420002025C8 |
:100440003364202025336420202533642020253385 |
:1004500064200020253364202025336420202533A8 |
:100460006420202533642000424C2D4374726C209C |
:100470004572726F7273200048693A2534692020F2 |
:1004800043663A253469200047733A2534692020B1 |
:1004900059613A25346920004E693A253469202093 |
:1004A000526F3A253469200045787465726E436F47 |
:1004B0006E74726F6C202000506F343A20253369BF |
:1004C00020506F383A2025336900506F333A202589 |
:1004D000336920506F373A2025336900506F323A24 |
:1004E0002025336920506F363A2025336900506F3C |
:1004F000313A2025336920506F353A202533690081 |
:100500004F6666436F757273653A202535690048FA |
:10051000656164696E673A20202025356900436F64 |
:10052000757273653A2020202025356900436F6D70 |
:1005300070617373202020202020200052432D4C16 |
:100540006576656C3A2025356900566F6C74616775 |
:10055000653A20202533692E253169560050333AFB |
:10056000253469202050343A253469200050313A2E |
:10057000253469202050323A253469200047733AE7 |
:10058000253469202059613A25346920004E693AA2 |
:100590002534692020526F3A253469200043373AC8 |
:1005A000253469202043383A253469200043353A00 |
:1005B000253469202043363A253469200043333AF4 |
:1005C000253469202043343A253469200043313AE8 |
:1005D000253469202043323A25346920004865617A |
:1005E00064696E673A20202025356900526F6C6C73 |
:1005F0003A202020202020253569004E69636B3A7F |
:1006000020202020202025356900417474697475EC |
:1006100064650028632920486F6C67657220427505 |
:100620007373004D697373696E6720424C2D437478 |
:10063000726C3A256400493243204572726F722110 |
:1006400021210053657474696E673A202564202562 |
:10065000730048573A5625642E25642053573A258F |
:10066000642E25642563002B204D696B726F4B6FE0 |
:1006700070746572202B005B25695D005B25695DE8 |
:1006800000000047008F00D6001E016501AC01F399 |
:10069000013A028102C7020E0354039903DF0324C7 |
:1006A000046904AE04F20436057905BC05FE054074 |
:1006B000068206C306040744078307C20700083EF4 |
:1006C000087B08B708F2082D096809A109DA0912A0 |
:1006D0000A490A7F0AB50AE90A1D0B500B820BB4BE |
:1006E0000BE40B130C420C6F0C9C0CC70CF20C1B94 |
:1006F0000D440D6B0D920DB70DDB0DFE0D210E425D |
:100700000E610E800E9E0EBA0ED60EF00E090F214F |
:100710000F380F4D0F610F740F860F970FA60FB58F |
:100720000FC20FCE0FD80FE10FEA0FF00FF60FFA3E |
:100730000FFE0FFF0F0010000047008F00D7001EB4 |
:10074000016601AF01F70140028902D2021C036772 |
:1007500003B203FD034A049704E40433058205D37E |
:100760000524067706CB0620077607CE07270882E2 |
:1007700008DE083D099D09FF09640ACB0A340BA075 |
:100780000B0F0C800CF50C6D0DE90D680EEC0E7363 |
:100790000F001092102811C51168121113C2137B9B |
:1007A000143C150616DA16B917A3189B19A11AB628 |
:1007B0001BDD1C171E671FCE205022F023B2259A86 |
:1007C00027AE29F62B782E3E315534CC37B63B2C4C |
:1007D000404E45464B5052BE5A0565D971FF7FFFCA |
:1007E0007FFF7FFF7FFF7FFF7FFF7FFF7F0A0D0A75 |
:1007F0000D2121204D495353494E4720424C2D4352 |
:1008000054524C3A20256420212100256420000AFE |
:100810000D466F756E6420424C2D4374726C3A2005 |
:10082000000A0D3D3D3D3D3D3D3D3D3D3D3D3D3D98 |
:100830003D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3DE8 |
:100840003D000A0D4D697865722D436F6E666967CC |
:100850003A202725732720282575204D6F746F7245 |
:100860007329000A0D47656E65726174696E6720B1 |
:1008700064656661756C74204D6978657220546199 |
:10088000626C65000A0D5573696E67205061726174 |
:100890006D6574657220536574202564000A0D49E6 |
:1008A0006E697420506172616D6574657220696E45 |
:1008B00020454550524F4D0011241FBECFEFD0E1CF |
:1008C000DEBFCDBF12E0A0E0B1E0EAECF2E802C08A |
:1008D00005900D92AA32B107D9F716E0AAE2B2E06C |
:1008E00001C01D92A033B107E1F70E947B040C9474 |
:1008F00063410C9400000F931F93CF93DF93F89400 |
:100900000E941F3E8093ED020E942E3E982F8093FE |
:10091000DC0184B7877F84BF809160008861809309 |
:100920006000109260009A3009F4A3C1943109F478 |
:10093000A0C1289A0E94FF1F0E94C1120E94B013FA |
:100940000E940F088091ED02813011F40E94063957 |
:100950000E94D2250E94EA130E9433230E94E63FA0 |
:10096000789400D00F92ADB7BEB711961C92119734 |
:1009700080EA91E013969C938E9312970E94890FC0 |
:10098000EDB7FEB7118280E991E0938382830E94E4 |
:10099000890FADB7BEB711961C9211978DE791E004 |
:1009A00013969C938E9312970E94890FEDB7FEB712 |
:1009B000118287E691E0938382830E94890F0F90D2 |
:1009C0000F900F908091ED02813091F400D00F9242 |
:1009D000ADB7BEB711961C92119785E691E01396BC |
:1009E0009C938E9312970E94890F0F900F900F90F7 |
:1009F000EDB7FEB739970FB6F894FEBF0FBEEDBF47 |
:100A00003196ADB7BEB711961C9280E591E0928306 |
:100A10008183148213828AE490E09683858385EC37 |
:100A200090E0908787830E94890FEDB7FEB73696D6 |
:100A30000FB6F894FEBF0FBEEDBF11828AE291E0BF |
:100A4000938382830E94890F0F900F900F900E94D2 |
:100A5000333888EC90E00E94EF12EC0142988091CC |
:100A6000DC018C3008F009C129988A3009F403C1EF |
:100A7000843109F400C12898CE010E94F91288231C |
:100A8000D9F388EC90E00E94EF12EC01429A43986F |
:100A90008091DC018A3009F4F4C0843109F4F1C09A |
:100AA000289A8C3008F0EBC0299ACE010E94F912E6 |
:100AB0008823D9F388EC90E00E94EF12EC01CE017C |
:100AC0000E94F9128823D9F3439A0E94242500D06A |
:100AD0000F92ADB7BEB711961C92119784E091E0CA |
:100AE00013969C938E9312970E94890FEDB7FEB7D1 |
:100AF000118287EE90E0938382830E94890F0F908A |
:100B00000F900F908091ED02813009F4EAC000D07F |
:100B10000F92EDB7FEB711828BEA90E09383828348 |
:100B20000E94890F0F900F900F900E9402220E9446 |
:100B300062300E94D8130E94453680ED97E00E94F3 |
:100B40005E3E00D00F92ADB7BEB711961C921197C2 |
:100B50008FE990E013969C938E9312970E94890FD1 |
:100B6000809172050F900F900F9082FFA7C000D068 |
:100B70000F92EDB7FEB7118283E990E093838283F1 |
:100B80000E94890F0F900F900F9000D00F92EDB739 |
:100B9000FEB711828CE790E0938382830E94890FD5 |
:100BA0000F900F900F900E94001A88E893E19093A5 |
:100BB00084018093830105E010E080915302882333 |
:100BC000E1F3809116018823C1F3109253025C9ADD |
:100BD0000E9426315C982091DC012A3009F465C01E |
:100BE000243109F462C0289A809183019091840194 |
:100BF0000197909384018093830180918301909168 |
:100C00008401892B09F43FC080918F028823D9F594 |
:100C10002A3009F44EC0243109F44BC0289A80913F |
:100C20005302882321F080918A0280FD02C00E9435 |
:100C30009F090E940A0DCE010E94F9128823B1F08B |
:100C400080911401909115011816190654F4209101 |
:100C50001401309115018091830590E02817390720 |
:100C600054F184E190E00E94EF12EC010E947F2099 |
:100C7000A4CF28985FCE289AFFCE299AF6CE29983D |
:100C800014CF28980ECF2A3091F0243181F0289883 |
:100C90008091830190918401892B09F60E946F2332 |
:100CA0001093840100938301BACF28989DCF289A8E |
:100CB000EFCF2898B4CF0E94913ED3CF00D00F92AF |
:100CC000ADB7BEB711961C92119780E890E01396CD |
:100CD0009C938E9312970E94890F0F900F900F9004 |
:100CE00054CF00D00F92ADB7BEB711961C9211979A |
:100CF00089EC90E013969C938E9312970E94890F33 |
:100D00000F900F900F9011CF1F920F920FB60F926E |
:100D100011248F939F93EF93FF9380910101882378 |
:100D2000A9F480914F029091500201969093500245 |
:100D300080934F02FC01E851FC4FE081ED3099F0C7 |
:100D40008639910581F0E093C60004C010925002EC |
:100D500010924F02FF91EF919F918F910F900FBED4 |
:100D60000F901F9018951092500210924F0281E040 |
:100D700080930101E8CF1F920F920FB60F921124BA |
:100D80002F933F934F935F936F938F939F93AF9363 |
:100D9000BF93CF93DF93EF93FF936091C600809151 |
:100DA0003402882351F430914C023323C1F0363998 |
:100DB000C8F010924C0210923402FF91EF91DF9133 |
:100DC000CF91BF91AF919F918F916F915F914F9113 |
:100DD0003F912F910F900FBE0F901F901895633287 |
:100DE00009F43FC06D3099F0E32FF0E0EC50FD4F77 |
:100DF00060833F5F30934C0280914D0290914E0290 |
:100E0000860F911D90934E0280934D02D6CFA32F53 |
:100E1000B0E0FD01EE50FD4F9081ED01CD50DD4F72 |
:100E2000888140914D0250914E02491B5109481B47 |
:100E300051095F7050934E0240934D022081CA01C8 |
:100E40000024880F991F001C880F991F001C892FF0 |
:100E5000902D835C281789F01092340210924C0276 |
:100E6000ACCF6093F40281E080934C0283E290E087 |
:100E700090934E0280934D02A0CF9881842F8F7360 |
:100E8000835C981749F7AC50BD4F6C933F5F30932C |
:100E9000350281E0809334028091F6028235F1F6CA |
:100EA0002CE088E190E00FB6F894A895809360005C |
:100EB0000FBE20936000D2CFCF93DF93BC01009789 |
:100EC000A9F120E030E040E050E0FA01E851FC4FA9 |
:100ED0008081280F311D4F5F5F4F46175707A8F3DA |
:100EE0003F70C9010024880F991F001C880F991FAB |
:100EF000001C892F902D835CDB0111962F73235CDE |
:100F0000ED012196FB01E851FC4F8083A851BC4FB5 |
:100F10002C93C851DC4F8DE08883109201018091A1 |
:100F2000E8038093C600DF91CF910895E0E0F0E000 |
:100F30008DE3A1E0B0E02DE3C2E0D0E0E4CF50913A |
:100F40003502565009F457C033E043E01EC0972FD6 |
:100F50009D53F0E02295207F892F86958695282B3A |
:100F6000EC50FD4F2083E42FEE5F5230C1F153501F |
:100F7000F0E09295990F990F907C6D53962BEC5061 |
:100F8000FD4F90834D5F5523A1F1E32FF0E0EC502E |
:100F9000FD4F80813F5FE32FF0E0EC50FD4F20815B |
:100FA0002D533F5FE32FF0E0EC50FD4F70813F5F2A |
:100FB000E32FF0E0EC50FD4F60813F5F922F929560 |
:100FC0009F708D53880F880F892BE42FF0E0EC5031 |
:100FD000FD4F8083E42FEF5F513009F0B8CFE3502D |
:100FE00087EF92E09093370280933602E0933802C5 |
:100FF0000895E42FF4CFE0E0F3CF1F93182F8A3049 |
:1010000051F08091C00085FFFCCF1093C60080E0B6 |
:1010100090E01F9108958DE00E94FD07F2CF0F939D |
:101020001F930FB7F8948091C1008F778093C10010 |
:101030008091C1008F7B8093C100589A5098599A33 |
:10104000519A1092C5008AE28093C4008091C0003A |
:1010500082608093C00088E18093C1008091C200CB |
:101060008F778093C2008091C2008F7B8093C200F3 |
:101070008091C2008F7D8093C2008091C2008F7EDC |
:101080008093C2008091C200877F8093C2008091CC |
:10109000C1008B7F8093C1008091C20084608093E7 |
:1010A000C2008091C20082608093C2008091C00023 |
:1010B00087FF06C08091C6008091C00087FDFACFEF |
:1010C0008091C10080688093C1008091C1008064DC |
:1010D0008093C10080910201909103010E94EF1260 |
:1010E00090937F0480937E04109234021092370212 |
:1010F000109236021092380211E0109301018CED2B |
:1011000090E00E94EF1290938B0380938A031092D9 |
:101110009C038AE480939D0384E68093A0038AE085 |
:1011200080939E0310939F030FBF1F910F9108950B |
:10113000BF92CF92DF92EF92FF920F931F93DF93B4 |
:10114000CF93CDB7DEB78D852E8593E29093E803DC |
:101150008F598093E9038C858093EA03222379F4E5 |
:1011600063E070E0CB010E945C07CF91DF911F919B |
:101170000F91FF90EF90DF90CF90BF900895EF8494 |
:10118000F88803E1C02ED12CCC0EDD1E49895A8986 |
:101190004115510529F3022F015063E070E010E082 |
:1011A00062C0A12FB0E01F5FFA01AE0DBF1D8C9190 |
:1011B000AF014150504009F48BC0E12FF0E01F5FB8 |
:1011C000EE0DFF1DA0814150504009F06DC000237D |
:1011D00009F46AC096012E5F3F4FF601E080F1806E |
:1011E00012E0C12ED12CC20ED31EF90140815181D3 |
:1011F0000150382F32953F7090E08F7090702A2FF9 |
:101200002295269526952370880F991F880F991F80 |
:10121000282B235CAF73A35C10E08B2D86958695FD |
:10122000835CFB01E851FC4F80838B2D90E0837041 |
:10123000907082959295907F9827807F9827382B81 |
:10124000335CFB01E751FC4F3083FB01E651FC4F5F |
:101250002083FB01E551FC4FA0836C5F7F4F41155C |
:10126000510509F47FCFF701E10FF11DB0801F5F39 |
:101270004150504009F095CF002391F0F60132968D |
:10128000D601ED90FC9012E0C12ED12CCE0EDF1EC7 |
:101290000190F081E02D0150309709F04CC010E032 |
:1012A00030E02DE3ADE3B9CF382F32953F7090E0B9 |
:1012B0008F7090702A2F2295269526952370880F7F |
:1012C000991F880F991F282B235CAF73A35CA5CFB0 |
:1012D000002371F4382F32953F7090E08F7090703A |
:1012E000880F991F880F991F282F235CADE395CF96 |
:1012F000F6013296D601ED90FC90A2E0CA2ED12CD8 |
:10130000CE0EDF1E4081518101504115510521F063 |
:10131000E0E0F0E011E054CF382F32953F7090E0DC |
:101320008F709070880F991F880F991F282F235C4A |
:1013300010E0ADE372CFA0E0B0E011E036CF0F9344 |
:101340001F93DF93CF93CDB7DEB760970FB6F894B6 |
:10135000DEBF0FBECDBF80910101882309F4BAC062 |
:1013600080912A02882329F080910101882309F0C5 |
:10137000A0C180912C02882329F08091010188234B |
:1013800009F04DC280912D02882329F0809101013E |
:10139000882309F0E1C1609100016F3F09F441C069 |
:1013A00070E062957295707F7627607F76276A532A |
:1013B0007E4F8E010F5F1F4FC80140E150E00E9439 |
:1013C00012418DB79EB70B970FB6F8949EBF0FBE14 |
:1013D0008DBFEDB7FEB7319681E4ADB7BEB71196BC |
:1013E0008C9381E0818382E0828380E091E094832A |
:1013F000838381E090E0968385831087078380E173 |
:1014000090E0928781870E9498088FEF8093000177 |
:101410002DB73EB7255F3F4F0FB6F8943EBF0FBEC6 |
:101420002DBF80918004882329F0809101018823B9 |
:1014300009F0CCC18091020190910301892B09F040 |
:1014400054C080912E02882329F0809101018823C5 |
:1014500009F0ADC280914A0290914B02892B09F0AC |
:1014600021C280912F02882329F0809101018823D5 |
:1014700009F022C280912B02882329F0809101017A |
:10148000882309F040C180918A0390918B030E94C8 |
:10149000F912882329F080910101882309F097C06F |
:1014A00080913102882329F080910101882309F07D |
:1014B00079C080913002882329F08091010188232E |
:1014C00009F046C080913202882321F08091010109 |
:1014D0008823A9F460960FB6F894DEBF0FBECDBF87 |
:1014E000CF91DF911F910F91089580917E0490918B |
:1014F0007F040E94F912882309F0A7CFA2CF8DB7ED |
:101500009EB707970FB6F8949EBF0FBE8DBFEDB77D |
:10151000FEB7319688E5ADB7BEB711968C9381E0E2 |
:10152000818382838DED92E09483838380E190E0D8 |
:10153000968385830E949808109232022DB73EB799 |
:10154000295F3F4F0FB6F8943EBF0FBE2DBFC2CFED |
:101550002DB73EB7275030400FB6F8943EBF0FBEB0 |
:101560002DBFEDB7FEB7319680E5ADB7BEB711968A |
:101570008C9381E08183828388E195E094838383E7 |
:1015800084E190E0968385830E949808109230024F |
:101590002DB73EB7295F3F4F0FB6F8943EBF0FBE41 |
:1015A0002DBF90CF00D00F92EDB7FEB7319684E5F6 |
:1015B000ADB7BEB711968C9381E0818312820E94F1 |
:1015C0009808109231020F900F900F9072CF609197 |
:1015D0004E0570914F0580915005909151052AE07C |
:1015E00030E040E050E00E94834024E736E040E0F5 |
:1015F00050E00E94F740309329062093280660911E |
:1016000052057091530580915405909155052AE03B |
:1016100030E040E050E00E94834024E736E040E0C4 |
:1016200050E00E94F74030932B0620932A068091C9 |
:10163000BF0180932C068091C00180932D0680917C |
:101640009D0280932E068DB79EB707970FB6F8942C |
:101650009EBF0FBE8DBFEDB7FEB7319687E7ADB722 |
:10166000BEB711968C9383E0818381E0828388E208 |
:1016700096E09483838388E090E0968385830E943C |
:1016800098082DB73EB7295F3F4F0FB6F8943EBF7D |
:101690000FBE2DBF80919D02853010F010929D02EB |
:1016A00083E690E00E94EF1290938B0380938A036D |
:1016B000F7CE2DB73EB7275030400FB6F8943EBF57 |
:1016C0000FBE2DBFEDB7FEB7319686E5ADB7BEB7FD |
:1016D00011968C9381E0818382838CE993E09483DB |
:1016E00083838AE090E0968385830E949808109215 |
:1016F0002A022DB73EB7295F3F4F0FB6F8943EBF81 |
:101700000FBE2DBF36CE8DB79EB707970FB6F89494 |
:101710009EBF0FBE8DBFEDB7FEB7319687E4ADB764 |
:10172000BEB711968C9381E08183828388EB94E02D |
:10173000948383838BE090E0968385830E9498084E |
:1017400010922B022DB73EB7295F3F4F0FB6F8948A |
:101750003EBF0FBE2DBF97CE0E94091A8DB79EB710 |
:101760000F970FB6F8949EBF0FBE8DBFEDB7FEB7B3 |
:1017700031968CE4ADB7BEB711968C9381E081832E |
:1017800083E0828385E792E09483838321E030E0E5 |
:101790003683258382E391E0908787833287218790 |
:1017A00083E391E09487838780E590E0968785873F |
:1017B0000E94980810922D022DB73EB7215F3F4F2F |
:1017C0000FB6F8943EBF0FBE2DBFE5CD8DB79EB7C7 |
:1017D00007970FB6F8949EBF0FBE8DBFEDB7FEB74B |
:1017E000319682E4ADB7BEB711968C9381E08183C8 |
:1017F000828380E894E09483838381E090E0968301 |
:1018000085830E949808109280042DB73EB7295F07 |
:101810003F4F0FB6F8943EBF0FBE2DBF0BCE0E94B8 |
:10182000091A8DB79EB70B970FB6F8949EBF0FBEDF |
:101830008DBFEDB7FEB7319688E4ADB7BEB7119650 |
:101840008C9381E0818382E0828383E392E09483BE |
:10185000838381E090E0968385838091330224E145 |
:10186000829FC00111248D5C9E4F9087878384E105 |
:1018700090E0928781870E949808809133028F5F61 |
:10188000809333022DB73EB7255F3F4F0FB6F894D4 |
:101890003EBF0FBE2DBF843010F010923302109265 |
:1018A0002C0270CD80919A0390919B030E94F912B3 |
:1018B000882309F0DACDD5CD8DB79EB707970FB63F |
:1018C000F8949EBF0FBE8DBFEDB7FEB7319683E48F |
:1018D000ADB7BEB711968C9381E0818382838CE88B |
:1018E00093E0948383838EE090E0968385830E94C7 |
:1018F000980860914E0570914F0580915005909128 |
:1019000051052AE030E040E050E00E94834024E7A7 |
:1019100036E040E050E00E94F74030938D03209382 |
:101920008C036091520570915305809154059091FC |
:1019300055052AE030E040E050E00E94834024E773 |
:1019400036E040E050E00E94F74030938F03209350 |
:101950008E0360914A0570914B0580914C059091E2 |
:101960004D052AE030E040E050E00E94834026E848 |
:1019700032E040E050E00E94F74030939103209322 |
:1019800090032DB73EB7295F3F4F0FB6F8943EBF87 |
:101990000FBE2DBF80914A0290914B020E94EF1220 |
:1019A00090939B0380939A0310922F0263CD8DB77F |
:1019B0009EB707970FB6F8949EBF0FBE8DBFEDB7C9 |
:1019C000FEB7319684E4ADB7BEB711968C9381E033 |
:1019D0008183828386EA93E09483838382E490E028 |
:1019E000968385830E9498082DB73EB7295F3F4FA5 |
:1019F0000FB6F8943EBF0FBE2DBF809102019091AB |
:101A000003010E94EF1290937F0480937E04109252 |
:101A10002E0220CD0F931F93DF93CF9300D0CDB72D |
:101A2000DEB780913902882319F081508093390202 |
:101A300080913402882339F40F900F90CF91DF9179 |
:101A40001F910F9108950E949F078091F5028236A1 |
:101A5000B9F18091F602873609F47CC1883680F0AE |
:101A60008C3609F451C18D3608F4CFC0863709F49D |
:101A70006DC1883709F0CCC081E080933202C8C0C4 |
:101A8000823609F46BC1833608F4D1C0833609F479 |
:101A900049C1843609F0BCC0E0913602F0913702AA |
:101AA00080812AE0829FC0011124909303018093DA |
:101AB0000201892B09F4ACC081E080932E02A8C0FA |
:101AC0008091F602803709F470C18137A0F48D3619 |
:101AD00009F4E4C08E3609F46EC08B3409F0B9CF36 |
:101AE000E0913602F09137028081918190938801D4 |
:101AF00080938701AECF833709F4ABC0843709F4F4 |
:101B000058C1813709F0A5CF0091360210913702F4 |
:101B1000D8018C918F3F09F480C1D8018C91882322 |
:101B200009F06FC181E08C93009136021091370269 |
:101B3000D8018C910E94BF37E0913602F0913702B4 |
:101B4000E0818BE48A83809101018823E1F3E983BA |
:101B5000EDB7FEB73F970FB6F894FEBF0FBEEDBFCF |
:101B6000319681E5ADB7BEB711968C9381E0818344 |
:101B700083E08283CE0101969483838321E030E069 |
:101B800036832583CE01029690878783328721870B |
:101B90008AE695E0948783878DE590E09687858730 |
:101BA0000E949808EDB7FEB73F960FB6F894FEBFB7 |
:101BB0000FBEEDBF4ECF809101018823E1F38DB7B9 |
:101BC0009EB707970FB6F8949EBF0FBE8DBFEDB7B7 |
:101BD000FEB731968EE4ADB7BEB711968C9381E017 |
:101BE0008183828387EC95E0948383838DE490E006 |
:101BF000968385830E949808EDB7FEB737960FB697 |
:101C0000F894FEBF0FBEEDBF24CF883609F4B8C0EC |
:101C1000109237021092360210923802109234025B |
:101C20000F900F90CF91DF911F910F910895813602 |
:101C300079F7E0913602F0913702808180930001BC |
:101C4000803218F08FE1809300018FEF8093C304FE |
:101C5000DFCF80918A0280FDFCCE00913602109188 |
:101C60003702D8018C91882339F08C91863020F48A |
:101C700011968C918B34A9F11982809101018823EE |
:101C8000E1F38DB79EB707970FB6F8949EBF0FBECE |
:101C90008DBFEDB7FEB7319683E515C0E0913602F2 |
:101CA000F09137028081813009F4C2C019828DB76A |
:101CB0009EB707970FB6F8949EBF0FBE8DBFEDB7C6 |
:101CC000FEB731968DE4ADB7BEB711968C9381E027 |
:101CD00081838283CE0101969483838381E090E0A7 |
:101CE00087CFAAE6B5E0F80132968DE501900D9216 |
:101CF0008150E1F7F80180810E948B370E941A37EA |
:101D000089830E94B73EB9CF8FEF8093C304E091DF |
:101D10003602F091370280818093750281E08093D2 |
:101D20002D0276CFE0913602F091370280812AE0D1 |
:101D3000829FC001112490934B0280934A02892B09 |
:101D400009F466CF81E080932F0262CF81E0809317 |
:101D50002A025ECF81E080932B025ACFA8EBB4E039 |
:101D600080913602909137029C01F9018BE001903D |
:101D70000D928150E1F78091C1048093800465CF7A |
:101D80008FEF8093C304E0913602F0913702808197 |
:101D900090917602892B80937602882311F010921D |
:101DA000330281E080932C0233CF81E080933002B4 |
:101DB00050CE80913802853198F0AAE3B2E080914C |
:101DC0003602909137029C01F90180E101900D9259 |
:101DD0008150E1F78FEF809339028093C30439CEAD |
:101DE000E0913602F091370280819181A281B38126 |
:101DF00080933A0290933B02A0933C02B0933D0241 |
:101E0000E9CFF8018081863008F492CE85E08083A6 |
:101E100000913602109137028BCE82E090E00E9452 |
:101E20000437F8018083009136021091370275CE95 |
:101E3000A7ECB5E08DE401900D928150E1F70E948E |
:101E40006437809101018823E1F381E089832FCFFA |
:101E5000982F80918104813021F0892F0E94FD0705 |
:101E6000089580917702E82FF0E0ED5CFE4F9083BB |
:101E70008F5F8093770281E008951F93182F1816C3 |
:101E800034F480E30E94280F11501116D4F31F91EF |
:101E900008951F93182F181634F480E20E94280F1B |
:101EA00011501116D4F31F910895EF92FF920F93E2 |
:101EB0001F93CF93DF937C018B016115710569F04E |
:101EC000C0E0D0E0F701EC0FFD1FE4918E2F0E94DF |
:101ED000280F2196C017D107A9F7DF91CF911F9145 |
:101EE0000F91FF90EF9008950F931F93CF93DF937F |
:101EF0008C01EB016115710539F0F80181918F01B9 |
:101F00000E94280F2197C9F7DF91CF911F910F9160 |
:101F100008952F923F924F925F926F927F928F928D |
:101F20009F92AF92BF92CF92DF92EF92FF920F9368 |
:101F30001F93DF93CF93CDB7DEB7EA970FB6F89430 |
:101F4000DEBF0FBECDBF61962FAD619762963FADEC |
:101F5000629760968FAD60978093810442E5A42ECE |
:101F6000B12CAC0EBD1EC9018C016624772443013F |
:101F70009E01245D3F4F3AAF29AFF801F490FF2056 |
:101F8000A9F0F5E2FF1691F0680103C0F5E2FF1633 |
:101F900039F00894C11CD11CF601F490FF20B1F770 |
:101FA000B601601B710B09F075C08601FF2009F4B2 |
:101FB00095C20F5F1F4F1982EE24552444244A9482 |
:101FC000F8010F5F1F4FF490AE2DB0E0A170B0701C |
:101FD00025E7F21609F446C08F2D8062883709F490 |
:101FE00041C06501F0E2FF1609F44DC023E2F2168C |
:101FF00009F495C04AE2F41609F495C05DE2F516BD |
:1020000009F4A0C0FBE2FF1609F441C02EE2F2166B |
:1020100009F444C0E0E3FE1609F496C08F2D815305 |
:10202000893008F097C020E030E0C901880F991F7F |
:10203000880F991F880F991F220F331F280F391FF0 |
:102040002F0D311D20533040F8010F5F1F4FF490CA |
:102050008F2D80538A3048F3522E560125E7F21611 |
:1020600009F0BACF109709F445C094E0C92ED12CDD |
:10207000CA0CDB1CF5016080718082809380F0E2E5 |
:10208000FF1609F0B3CF8981882309F046C0F98291 |
:10209000560196CFC8010E94550F87CFF8010F5FF8 |
:1020A0001F4F94919A3209F45FC0892F80538A3070 |
:1020B00080F5692F20E030E0C901880F991F880F53 |
:1020C000991F880F991F220F331F280F391F260FC2 |
:1020D000311D20533040F8010F5F1F4F6491862F50 |
:1020E00080538A3048F3A90137FD10C0442EF62EE4 |
:1020F0005601B4CF82E0C82ED12CCA0CDB1CF501EE |
:10210000808191813C01882499246CCF4FEF5FEF4F |
:10211000EDCFF92E44245601A1CF560151CF38E01E |
:10212000E32A56014DCFA2E0AA2EB12CAC0CBD1C67 |
:10213000D6015C9057FE44CF5194B0E1EB2AEFED0D |
:10214000EE223ECF5601F9CFE4FCE7CFF0E2EF2AD2 |
:10215000560136CF28E6F216B9F04CE6F416C1F473 |
:1021600051E0E52A56012CCFF2E0AF2EB12CAC0C99 |
:10217000BD1CD6014D915C9157FD02C0442E20CF6D |
:102180004FEF5FEF442E1CCF34E0E32A560118CF07 |
:102190008F2DF60193E6F91609F405C1843409F48C |
:1021A00072C0843609F471C0893609F46EC08F3468 |
:1021B00009F47AC18F3609F474C1803709F479C102 |
:1021C000B3E7FB1609F430C155E5F51609F4D4C19F |
:1021D00085E7F81609F4CCC1E8E5FE1609F4F8C065 |
:1021E000F8E7FF1609F4F4C0FF2009F477C1FC8278 |
:1021F00019822E2D30E03DAB2CAB5601EE2434E09D |
:10220000232E312C2C0E3D1E81E091E0E0E021E0F8 |
:10221000C22ED12C2981222381F18F5F482E4E0EB0 |
:102220008CA99DA98073907098AF8FAB892B29F4EE |
:10223000852D84190E94490F29812223B9F49CA974 |
:1022400096FD8CC1EFA9F8ADB09709F482C18E2D2F |
:102250000E943D0FC101B6010E94740FFCA9F4FF5A |
:102260008CCE852D84190E94490F87CECE01019610 |
:1022700061E070E00E94740FE5CF5CA956FFCECFFD |
:10228000892F8E5FCBCFB1E0EB2AE0FE54C1B4E0E2 |
:10229000AB2EB12CAC0CBD1CF6016080718082802D |
:1022A000938097FC3BC1BAE0BEAB47FC02C05FED38 |
:1022B000E5227CE2272E312C2C0E3D1E6114710488 |
:1022C0008104910409F452C09EA9892F90E0A0E0F6 |
:1022D000B0E088AB99ABAAABBBAB6CE2C62ED12CFD |
:1022E000CC0EDD1E6CA67DA68EA69FA62AC050E34E |
:1022F000352E360ED6013E926D016CA57DA58EA5BC |
:102300009FA528A939A94AA95BA90E94D540B9016E |
:10231000FA01C901DA013C014D012CA53DA54EA5EC |
:102320005FA588A999A9AAA9BBA9281739074A07AF |
:102330005B0708F440C0CB01DF018CA79DA7AEA7C7 |
:10234000BFA76CA57DA58EA59FA528A939A94AA9D7 |
:102350005BA90E94D5406A3050F247E5342E360E14 |
:1023600048E5F41639F65FED3522C4CF442089F4F0 |
:10237000AE2DB0E0BDABACAB80E090E0442DE42EE0 |
:10238000E91AE7FCC4C0EE2DC82EDD24C7FCD094AA |
:1023900041CF3EA9232F30E040E050E028AB39ABDD |
:1023A0004AAB5BAB9ACFA2E0B0E0CA0EDB1E8081E5 |
:1023B0008C8319821ECF9EA99830D1F0AE2DB0E04B |
:1023C000BDABACABB9ADBC198B2F9B2F1601D6CFD3 |
:1023D000E3FE1AC06114710481049104A9F020E4A1 |
:1023E000E22A8F2D30E13EAB1982F82E56015DCFE7 |
:1023F000EE2DF0E0FDABECABE3FC0AC0F9ADFC194F |
:102400008F2F9F2F1601BACF8F2D40E14EABECCF0F |
:1024100020E3321609F45CC0F60140E3429389AD33 |
:102420008E1B982F1F01AACFF60120803180211426 |
:10243000310489F4F8E2FC832EE62D8335E73E83F0 |
:102440008CE68F83888789E289871A86F4E02F2EAD |
:10245000312C2C0E3D1E47FC1CC0442D552747FD3A |
:102460005095C10160E070E00E941B41009719F097 |
:10247000821948160CF4842DE2E0AE2EB12CAC0C7F |
:10248000BD1C1982982F4E2D50E05DAB4CAB40E047 |
:1024900076CFF10101900020E9F731978E2F821954 |
:1024A000EBCF28E02EABA0CF31E0E32A48E04EABE3 |
:1024B0009BCF82E090E0C80ED91E808191813C01C3 |
:1024C0008824992490E4E92A88E7A0E1AEAB8CCF78 |
:1024D00039AD3C19832F932F160150CFEA960FB6D2 |
:1024E000F894DEBF0FBECDBFCF91DF911F910F914A |
:1024F000FF90EF90DF90CF90BF90AF909F908F9024 |
:102500007F906F905F904F903F902F900895C82ECE |
:10251000DD24C7FCD094EE24E0E07CCE909480943F |
:1025200070946094611C711C811C911CEDE2E98324 |
:10253000FAE0FEABBACEA2E0AA2EB12CAC0CBD1CC8 |
:10254000D6018D919C913C01882477FC8094982C35 |
:10255000A8CE852D84190E943D0F79CEA0E3AA83D1 |
:10256000FB82CE01029662E070E00E94740F6ACE98 |
:102570008F2D9AE09EAB38CFA1E0EA2ABAE0BEAB3D |
:1025800033CF9FB7F8948091DC018A3029F13F9ACC |
:10259000479884B1886184B985B1877E85B984B54F |
:1025A0008F7A84BD84B5836A84BD85B5877385BD04 |
:1025B00085B5887F826085BD17BC88E788BD16BC5D |
:1025C00080916E00897F80936E0080916E008160A3 |
:1025D00080936E009FBF0895529A5A98DACF209147 |
:1025E00051023091520221503040280F391FC90149 |
:1025F00008952091510230915202821B930B8070FA |
:102600009078892F089520915102309152022150E3 |
:102610003040280F391F8091510290915202A90138 |
:10262000481B590BCA01807090789923A1F3089533 |
:10263000209151023091520221503040280F391F11 |
:102640008091510290915202A901481B590BCA0175 |
:1026500080709078992361F480911601882381F32A |
:102660001092160180917A00886C80937A00E8CFEE |
:1026700008951F920F920FB60F9211242F933F933C |
:102680004F935F936F937F938F939F93AF93BF937A |
:10269000EF93FF93809158028150809358028F5F8F |
:1026A000A9F489E0809358028091060191E089277E |
:1026B00080930601882309F44CC0809151029091C7 |
:1026C00052020196909352028093510280915602D9 |
:1026D00090915702892B89F180915602909157026F |
:1026E00001979093570280935602209156023091A1 |
:1026F0005702809104019091050182239323892B35 |
:1027000011F18091DC018A3039F1479A809172058C |
:10271000887211F00E94F03FFF91EF91BF91AF914D |
:102720009F918F917F916F915F914F913F912F91E9 |
:102730000F900FBE0F901F9018958FEF9FEF909303 |
:102740000501809304018091DC018A3039F04798BB |
:10275000DDCF90935302B1CF5A9AD8CF5A98D6CFA3 |
:102760009FB7F894579A5F983E9A469AA0EBB0E0CC |
:102770008C918F708C938C9183608C93E1EBF0E063 |
:1027800080818B73808380818B6080831092B20004 |
:102790008FEF8093B3008C9180688C93E0E7F0E03A |
:1027A00080818A7F80838081826080839FBF08953B |
:1027B00081E080935D02089510925D02469A08952B |
:1027C0001F920F920FB60F9211240F900FBE0F9011 |
:1027D0001F9018959FB7F89411B812B88FEF809397 |
:1027E0007E00ECE7F0E080818F7180838081807EC5 |
:1027F00082608083AAE7B0E087E08C93EBE7F0E0AB |
:102800008081887F80838C91886C8C939FBF089592 |
:102810009C01FB018081918182179307ACF06627B0 |
:102820007727621B730B80819181861797074CF085 |
:102830008081918150E04817590748F01182108239 |
:102840000895718360830895318320830895808182 |
:102850009181841B950B91838083089547B52091C6 |
:102860001301249F90011124280F391FC9010895D5 |
:102870001F920F920FB60F9211248F929F92BF92C8 |
:10288000CF92DF92EF92FF920F931F932F933F937C |
:102890004F935F936F937F938F939F93AF93BF9368 |
:1028A000CF93DF93EF93FF93E0913101F0E020911C |
:1028B000780030917900EE0FFF1FEC59FD4F8081B9 |
:1028C0009181820F931F9183808360917402B62E51 |
:1028D000B394B09274026D3009F4B4C16E3008F054 |
:1028E00042C06B3009F496C16C3008F462C180912B |
:1028F0002602882309F40BC280910D0190910E01EC |
:102900002091720230917302821B930B9093830487 |
:102910008093820440915E0250915F0280919D04F9 |
:10292000209182043091830460919D0490E001978E |
:10293000DC01A49FC001A59F900DB49F900D1124B0 |
:10294000820F931F70E00E94C24070935F026093F9 |
:102950005E02809182049091830463E974E041E017 |
:102960000E940814AFC0613108F0DCC06F3008F479 |
:1029700037C16F50C62FD0E0E2E0F0E0EC1BFD0B5A |
:10298000EE0FFF1FEC59FD4F808191816E01CC0C41 |
:10299000DD1CF601E956FB4F918380832081318154 |
:1029A0008091720587FDD5C203E2802E02E0902E51 |
:1029B0008C0E9D1ED4018C91882309F48CC1F601E4 |
:1029C000E95FFE4F0190F081E02DE21BF30BEE0F6B |
:1029D000FF1FEE0FFF1FAFEAEA2EA4E0FA2EEC0C69 |
:1029E000FD1CD7012D913C918091A90490E00197A5 |
:1029F000AC01249FC001259F900D349F900D1124A0 |
:102A00006091A9048E0F9F1F70E00E94C2408B014D |
:102A1000CC0FDD1FC857DB4FCB01BE0145E00E9444 |
:102A20000814F601E157FB4F408151818091A804C1 |
:102A3000D7012D913C916091A80490E00197DC01B1 |
:102A40004A9FC0014B9F900D5A9F900D1124821BED |
:102A5000930B800F911F70E00E94C24071836083CE |
:102A6000F70111830083F601E956FB4F2081318184 |
:102A7000D4018C91882309F421C1F601E95FFE4F4E |
:102A800040815181421B530B440F551F440F551F6A |
:102A9000F601E256FB4F208131818091AE046091B6 |
:102AA000AE0490E00197DC012A9FC0012B9F900D9E |
:102AB0003A9F900D1124840F951F70E00E94C24030 |
:102AC00071836083EB2DF0E0EA53FC4FE491E093D7 |
:102AD000310180917C00807EE82BE0937C00BB205C |
:102AE00029F080917A00886C80937A00FF91EF91B1 |
:102AF000DF91CF91BF91AF919F918F917F916F9116 |
:102B00005F914F913F912F911F910F91FF90EF9007 |
:102B1000DF90CF90BF909F908F900F900FBE0F903F |
:102B20001F901895613171F68091140190911501F3 |
:102B30009C01220F331F280F391F80916C02909146 |
:102B40006D0263E070E00E94AE40260F371F36959D |
:102B50002795369527953093150120931401809180 |
:102B60001401909115019093BF038093BE0381E0FF |
:102B70008093160180916202909163020196909376 |
:102B800063028093620210927402E4E6F2E0119212 |
:102B90001192B2E0E437FB07D1F7E6ECF3E0E49101 |
:102BA000E093310180917C00807EE82BE0937C00F3 |
:102BB0009DCF683009F086CF80912802882309F4E0 |
:102BC000B5C0809111019091120120916E02309157 |
:102BD0006F02821B930B909387048093860472CFBD |
:102BE00080912F0190913001009709F4AEC00197B8 |
:102BF0009093300180932F0187B58093DE0310926C |
:102C0000DF038091A6049091A7049093E70380933B |
:102C1000E60358CF209164023091650230939C0402 |
:102C200020939B0480912502882309F467C1809139 |
:102C30000B0190910C01821B930B90938D04809358 |
:102C40008C0440CF80912702882309F451C08091E1 |
:102C50000F01909110012091700230917102821B3E |
:102C6000930B90938504809384044091600250916B |
:102C7000610280919D0420918404309185046091CB |
:102C80009D0490E00197FC01E49FC001E59F900D39 |
:102C9000F49F900D1124820F931F70E00E94C24098 |
:102CA0007093610260936002809184049091850426 |
:102CB00065E974E041E00E94081404CFF601E95F81 |
:102CC000FE4F80819181A901481B590B440F551F6C |
:102CD000440F551FDDCEF601E95FFE4F80819181E3 |
:102CE000F901E81BF90BEE0FFF1FEE0FFF1F73CE6C |
:102CF00020910F013091100180917002909171022A |
:102D0000821B930B9093850480938404AECF209113 |
:102D10000D0130910E018091720290917302821B1D |
:102D2000930B9093830480938204F4CD209111013E |
:102D30003091120180916E0290916F02821B930B71 |
:102D40009093870480938604BDCEE0916A02F0914F |
:102D50006B0221E0E039F20708F4DBC036E0EF3621 |
:102D6000F307D8F027B56091130170E0660F771F65 |
:102D7000660F771F8EED94E00E94C240620F711DB6 |
:102D8000603F71050CF063C187B5AB01481B510969 |
:102D90005093300140932F0167BD27B580911301F7 |
:102DA000829FC00111248E0F9F1F9093A7048093D0 |
:102DB000A60487B58093DE031092DF038091A604FA |
:102DC0009091A7049093E7038093E6038091130109 |
:102DD0002091A6043091A7046FE0869FC0011124C2 |
:102DE0002817390708F0C5C0E0901301209113019E |
:102DF0004091A6045091A7048091A2049091A3044D |
:102E0000A091A404B091A504E69E700111240027AE |
:102E1000F7FC0095102FE80EF91E0A1F1B1F30E06B |
:102E200081EF9FEF289FB001299F700D389F700D93 |
:102E30001124640F751F80E090E029E130E040E04C |
:102E400050E00E948340E60EF71E081F191FE09213 |
:102E5000A204F092A3040093A4041093A50480910B |
:102E60008E048E5F80938E0480918E04803108F4EE |
:102E700029CEE090AA04F090AB040091AC0410912C |
:102E8000AD046091A2047091A3048091A404909178 |
:102E9000A5046C5F7F4F8F4F9F4FA8019701220FB2 |
:102EA000331F441F551F220F331F441F551F220F6E |
:102EB000331F441F551F2E193F09400B510B620F42 |
:102EC000731F841F951F28E030E040E050E00E940F |
:102ED000F740C901DA018093AA049093AB04A09350 |
:102EE000AC04B093AD041092A2041092A30410920B |
:102EF000A4041092A50410928E04E4CD80910B01DD |
:102F000090910C01281B390B30938D0420938C0475 |
:102F1000D9CD27B580911301682F70E0660F771F18 |
:102F2000660F771F709561957F4F8EED94E00E943C |
:102F3000C240620F711D603171050CF45BC087B532 |
:102F400090E0861B970B9093300180932F0167BD13 |
:102F500024CF20323105D4F58EE490E0D901A89F2A |
:102F60009001A99F300DB89F300D1124245C394089 |
:102F70001BCD809113012091A6043091A70460EF2E |
:102F8000869FC00111248217930708F041C0E0908A |
:102F90001301209113014091A6045091A704809140 |
:102FA000A2049091A304A091A404B091A504E69E6C |
:102FB000700111240027F7FC0095102FE80EF91E70 |
:102FC0000A1F1B1F30E080E19FEF2CCFBFE02D3D9B |
:102FD0003B070CF4E9CC2C5D3F408EE490E0F90116 |
:102FE000E89F9001E99F300DF89F300D1124245285 |
:102FF000304FDACC87B5882309F4CFCE87B581501E |
:1030000087BD81E090E09093300180932F01C5CE81 |
:1030100080918E048F3049F18091A6049091A7048D |
:103020002091A2043091A3044091A4045091A504DE |
:10303000A0E0B0E0820F931FA41FB51F8093A204ED |
:103040009093A304A093A404B093A50408CF87B5DC |
:103050008E3F08F0A2CE87B58F5F87BD81E090E0FC |
:103060009093300180932F0198CE8091A604909187 |
:10307000A7042091A2043091A3044091A40450918C |
:10308000A50496958795A0E0B0E0820F931FA41F3A |
:10309000B51F8093A2049093A304A093A404B093BB |
:1030A000A504DDCEEF92FF920F931F93DF93CF9392 |
:1030B000CDB7DEB72C970FB6F894DEBF0FBECDBFED |
:1030C0007E010894E11CF11CD701E7E1F1E08CE0FE |
:1030D00001900D928150E1F710E08AE090E00E94AB |
:1030E00018132091820430918304442737FD4095C2 |
:1030F000542F89819A81AB81BC81820F931FA41FB9 |
:10310000B51F89839A83AB83BC832091840430915B |
:103110008504442737FD4095542F8D819E81AF81D2 |
:10312000B885820F931FA41FB51F8D839E83AF8325 |
:10313000B8872091860430918704442737FD409555 |
:10314000542F89859A85AB85BC85820F931FA41F58 |
:10315000B51F89879A87AB87BC871F5F1A3009F034 |
:10316000BCCF00E010E0F701608171818281938122 |
:103170006B5F7F4F8F4F9F4F2AE030E040E050E081 |
:103180000E94F740D801AA0FBB1FFD01E35FFE4F6D |
:1031900040815181F801EA5DFD4F8081882319F05B |
:1031A000309521953F4F240F351FA35FBE4F1196D9 |
:1031B0003C932E930F5F1F4F84E090E0E80EF91EC2 |
:1031C0000330110581F660910D0170910E010E948E |
:1031D000863760910F017091100186E090E00E94A7 |
:1031E0008637609111017091120188E090E00E9491 |
:1031F00086371092960410929504809195049091D0 |
:103200009604909394048093930484E690E00E9443 |
:1032100018132C960FB6F894DEBF0FBECDBFCF911A |
:10322000DF911F910F91FF90EF900895CF92DF9261 |
:10323000EF92FF920F931F93DF93CF93CDB7DEB73B |
:103240002C970FB6F894DEBF0FBECDBF7E01089459 |
:10325000E11CF11CD701E3E2F1E08CE001900D925A |
:103260008150E1F74091C301842F83708F5F809379 |
:10327000A904242F30E0C9018C7090709595879532 |
:10328000959587958F5F8093AE0420733070359548 |
:1032900027953595279535952795359527952F5F52 |
:1032A0002093A80442954695469543704F5F4093FE |
:1032B0009D040E94D13F10E084E190E00E94181329 |
:1032C0002091970430919804442737FD4095542F5E |
:1032D00089819A81AB81BC81820F931FA41FB51F86 |
:1032E00089839A83AB83BC832091990430919A049B |
:1032F000442737FD4095542F8D819E81AF81B8853D |
:10330000820F931FA41FB51F8D839E83AF83B88741 |
:1033100020919B0430919C04442737FD4095542F05 |
:1033200089859A85AB85BC85820F931FA41FB51F25 |
:1033300089879A87AB87BC871F5F103209F0BCCFA3 |
:10334000670120EDE22E23E0F22E00E010E0F6010E |
:1033500061917191819191916F01605F7F4F8F4F6A |
:103360009F4F20E230E040E050E00E94F740F8013B |
:10337000EE0FFF1FE95FFE4F318320838081918133 |
:10338000F701819391937F010F5F1F4F0330110568 |
:10339000F1F610928B0410928A0480918A04909125 |
:1033A0008B04909389048093880484E090E00E94C9 |
:1033B000DF3790930E0180930D0186E090E00E942C |
:1033C000DF379093100180930F0188E090E00E9416 |
:1033D000DF37909312018093110184E690E00E9400 |
:1033E00018132C960FB6F894DEBF0FBECDBFCF9149 |
:1033F000DF911F910F91FF90EF90DF90CF90089594 |
:10340000E3E3F1E080E2819391E0E338F907D9F753 |
:103410000895FF920F931F938091760290E080FFB2 |
:1034200008C020917502222309F40DC12150209378 |
:1034300075023091320181FF08C020917502231777 |
:1034400009F406C12F5F2093750283709070039773 |
:1034500011F410927502E3E3F1E080E2819321E040 |
:10346000E338F207D9F720917502321718F4309338 |
:103470007502232F2A30C8F581E18093770200D0AE |
:1034800000D00F92EDB7FEB7319681E0ADB7BEB771 |
:1034900011968C938CE796E0928381832383148228 |
:1034A0000E94890F0F900F900F900F900F908091B6 |
:1034B0007502873009F430C3883040F18B3009F44D |
:1034C000F8C38C3008F0C7C0883009F4E2C48930F2 |
:1034D00009F460C4815080933201109275021092F9 |
:1034E00076021F910F91FF90089580E180937702FB |
:1034F00000D000D00F92EDB7FEB7319681E0ADB7A6 |
:10350000BEB711968C9387E796E0C6CF823009F458 |
:1035100083C2833008F050C18823E1F6109277020D |
:1035200000D00F9211E0EDB7FEB7118387E696E069 |
:10353000938382830E94890F84E180937702209194 |
:10354000DC018DB79EB70A970FB6F8949EBF0FBEE9 |
:103550008DBFEDB7FEB73196ADB7BEB711961C93D0 |
:1035600082E596E092838183822F6AE00E94A240E6 |
:1035700083831482822F0E94A24095831682108634 |
:1035800017828AE490E09287818785EC90E09487A7 |
:1035900083870E94890F88E280937702EDB7FEB798 |
:1035A0003D960FB6F894FEBF0FBEEDBF0E941A37CE |
:1035B0002DB73EB7275030400FB6F8943EBF0FBE30 |
:1035C0002DBFEDB7FEB73196ADB7BEB711961C93C0 |
:1035D00023E436E0328321838383148288EC95E0F0 |
:1035E000968385830E94890F809183019091840145 |
:1035F000EDB7FEB737960FB6F894FEBF0FBEEDBF1E |
:10360000069708F4BDC420918F02222309F4A6C4B2 |
:103610008CE38093770200D000D00F92EDB7FEB715 |
:103620003196ADB7BEB711961C9383E296E09283B4 |
:103630008183238314820E94890F0F900F900F9033 |
:103640000F900F904CCF3091320130937502F3CE32 |
:1036500010927502FACE8C3009F45DC18D3009F0FC |
:1036600039CF1092770200D00F9211E0ADB7BEB7FC |
:1036700011961C9311978AE194E013969C938E9374 |
:1036800012970E94890F84E180937702EDB7FEB70D |
:1036900038970FB6F894FEBF0FBEEDBF3196ADB7A9 |
:1036A000BEB711961C9386E094E09283818380914B |
:1036B000D50490E08D96948383838091DA0490E022 |
:1036C0008D96968385838091DF0490E08D96908718 |
:1036D00087838091E40490E08D96928781870E9491 |
:1036E000890F88E280937702EDB7FEB73196ADB7C8 |
:1036F000BEB711961C9382EF93E0928381838091F1 |
:10370000E90490E08D96948383838091EE0490E0A9 |
:103710008D96968385838091F30490E08D969087B3 |
:1037200087838091F80490E08D96928781870E942C |
:10373000890F8CE380937702EDB7FEB736960FB60C |
:10374000F894FEBF0FBEEDBF3196ADB7BEB7119670 |
:103750001C9381EE93E0928381838091FD0490E03D |
:103760008D96948383830E94890F0F900F900F9002 |
:103770000F900F9080910205882309F02EC480914C |
:103780000705882309F012C480910C05882309F4E9 |
:10379000A6CE88E48093770200D00F9281E0EDB747 |
:1037A000FEB7818388ED93E0938382830E94890F23 |
:1037B0000F900F900F9093CE833009F4FBC18430AB |
:1037C00009F088CE10927702E0916A05F0E0EE0FE2 |
:1037D000FF1FE85EFA4F40815181E0916B05F0E0F8 |
:1037E000EE0FFF1FE85EFA4F208131818DB79EB743 |
:1037F00007970FB6F8949EBF0FBE8DBFEDB7FEB70B |
:10380000319611E0ADB7BEB711961C938DE895E0E7 |
:103810009283818354834383368325830E94890F57 |
:1038200084E180937702E0916C05F0E0EE0FFF1FDA |
:10383000E85EFA4F40815181E0916D05F0E0EE0FB6 |
:10384000FF1FE85EFA4F20813181EDB7FEB7319658 |
:10385000ADB7BEB711961C938DE795E09283818337 |
:1038600054834383368325830E94890F88E28093A3 |
:103870007702E0916E05F0E0EE0FFF1FE85EFA4F71 |
:1038800040815181E0916F05F0E0EE0FFF1FE85E8F |
:10389000FA4F20813181EDB7FEB73196ADB7BEB793 |
:1038A00011961C938DE695E0928381835483438324 |
:1038B000368325830E94890F8CE380937702E09101 |
:1038C0007005F0E0EE0FFF1FE85EFA4F4081518176 |
:1038D000E0917105F0E0EE0FFF1FE85EFA4F2081E6 |
:1038E0003181EDB7FEB73196ADB7BEB711961C93D7 |
:1038F0008DE595E0928381835483438336832583CA |
:103900000E94890FEDB7FEB737960FB6F894FEBF49 |
:103910000FBEEDBFE4CD1092770200D00F9211E000 |
:10392000ADB7BEB711961C93119788E694E0139635 |
:103930009C938E9312970E94890F84E18093770263 |
:10394000EDB7FEB738970FB6F894FEBF0FBEEDBFC8 |
:103950003196ADB7BEB711961C9383E594E0928380 |
:1039600081838091D604838314828091DB048583D4 |
:1039700016828091E004878310868091E504818718 |
:1039800012860E94890F88E280937702EDB7FEB716 |
:103990003196ADB7BEB711961C938EE394E0928337 |
:1039A00081838091EA04838314828091EF0485836C |
:1039B00016828091F404878310868091F9048187B0 |
:1039C00012860E94890F8CE380937702EDB7FEB7D1 |
:1039D0003196ADB7BEB711961C9389E294E09283FD |
:1039E00081838091FE048383148280910305858303 |
:1039F0001682809108058783108680910D05818746 |
:103A000012860E94890FEDB7FEB73B960FB6F89469 |
:103A1000FEBF0FBEEDBF63CD1092770200D00F92B4 |
:103A2000FF24F394ADB7BEB71196FC9211978AE0CC |
:103A300096E013969C938E9312970E94890F84E1CF |
:103A40008093770200D000D00DB71EB70F5F1F4FD5 |
:103A5000EDB7FEB7F1828BEF95E0D80112969C93FB |
:103A60008E93119760914E0570914F05809150058E |
:103A70009091510524E736E040E050E00E94F74085 |
:103A8000F80123833483458356830E94890F88E29B |
:103A9000809377020DB71EB70F5F1F4FADB7BEB74C |
:103AA0001196FC928CEE95E0F801928381836091EF |
:103AB000520570915305809154059091550524E766 |
:103AC00036E040E050E00E94F740D80113962D9375 |
:103AD0003D934D935C9316970E94890F8CE38093DE |
:103AE00077020F900F90EDB7FEB73196ADB7BEB726 |
:103AF0001196FC928DED95E09283818380918701F0 |
:103B000090918801948383830E94890F0F900F9076 |
:103B10000F900F900F90E3CC84E180937702809117 |
:103B200014019091150100911401109115012DB708 |
:103B30003EB7275030400FB6F8943EBF0FBE2DBFA2 |
:103B4000EDB7FEB73196FF24F394ADB7BEB711962B |
:103B5000FC922AE435E0328321836AE070E00E941F |
:103B6000C24074836383C8016AE070E00E94C2406F |
:103B7000968385830E94890F88E280937702209143 |
:103B80009202309193020F900F90EDB7FEB73196ED |
:103B9000ADB7BEB71196FC928CE395E0928381831A |
:103BA000348323830E94890F0F900F900F900F9002 |
:103BB0000F9095CC1092770220911A0530911B0539 |
:103BC00040911C0550911D05EDB7FEB737970FB614 |
:103BD000F894FEBF0FBEEDBF319611E0ADB7BEB792 |
:103BE00011961C938DEC95E092838183348323831B |
:103BF000568345830E94890F84E180937702209148 |
:103C00001E0530911F054091200550912105EDB70B |
:103C1000FEB73196ADB7BEB711961C938DEB95E00C |
:103C20009283818334832383568345830E94890F43 |
:103C300088E28093770220912205309123054091FC |
:103C4000240550912505EDB7FEB73196ADB7BEB747 |
:103C500011961C938DEA95E09283818334832383AC |
:103C6000568345830E94890F8CE3809377022091CD |
:103C70002605309127054091280550912905EDB77B |
:103C8000FEB73196ADB7BEB711961C938DE995E09E |
:103C90009283818334832383568345830E94890FD3 |
:103CA000EDB7FEB737960FB6F894FEBF0FBEEDBF67 |
:103CB00016CC1092770200D00F9211E0ADB7BEB7CC |
:103CC00011961C93119788EA94E013969C938E9317 |
:103CD00012970E94890F84E18093770200D000D070 |
:103CE000EDB7FEB73196ADB7BEB711961C9388E914 |
:103CF00094E0928381838091BB04992787FD9095FE |
:103D0000948383838091BC04992787FD9095968343 |
:103D100085830E94890F88E280937702EDB7FEB712 |
:103D20003196ADB7BEB711961C9388E894E09283A4 |
:103D300081838091BE04838314828091BD0499277E |
:103D400087FD9095968385830E94890F8CE38093ED |
:103D50007702EDB7FEB73196ADB7BEB711961C939B |
:103D600088E794E0928381838091BF04992787FD3F |
:103D70009095948383838091C204858316820E94E8 |
:103D8000890FEDB7FEB737960FB6F894FEBF0FBE9A |
:103D9000EDBFA5CB10927702EDB7FEB737970FB600 |
:103DA000F894FEBF0FBEEDBF319611E0ADB7BEB7C0 |
:103DB00011961C938EEE94E0928381838091DD02B4 |
:103DC0009091DE02948383838091E5029091E602D4 |
:103DD000968385830E94890F84E180937702EDB7F3 |
:103DE000FEB73196ADB7BEB711961C938CED94E03B |
:103DF000928381838091DF029091E0029483838398 |
:103E00008091E7029091E802968385830E94890F52 |
:103E100088E280937702EDB7FEB73196ADB7BEB7B3 |
:103E200011961C938AEC94E0928381838091E10245 |
:103E30009091E202948383838091E9029091EA0257 |
:103E4000968385830E94890F8CE380937702EDB778 |
:103E5000FEB73196ADB7BEB711961C9388EB94E0D0 |
:103E6000928381838091E3029091E402948383831F |
:103E70008091EB029091EC02968385830E94890FDA |
:103E8000EDB7FEB737960FB6F894FEBF0FBEEDBF85 |
:103E900026CB1092770200D00F9211E0EDB7FEB75B |
:103EA00011838DE295E0938382830E94890F84E1E0 |
:103EB0008093770200D0EDB7FEB73196ADB7BEB7AD |
:103EC00011961C938EE195E0928381838091890104 |
:103ED00090918A01948383830E94890F88E2809362 |
:103EE0007702EDB7FEB73196ADB7BEB711961C930A |
:103EF0008FE095E092838183809187019091880182 |
:103F0000948383830E94890F8CE380937702EDB7BB |
:103F1000FEB73196ADB7BEB711961C9380E095E021 |
:103F2000928381838091870190918801845E9D4F67 |
:103F30002091890130918A01821B930B68E671E020 |
:103F40000E94C240845B9040948383830E94890FC7 |
:103F50000F900F900F900F900F90C1CA8CE3809339 |
:103F6000770200D00F92EDB7FEB7118383E196E0A0 |
:103F7000938382830E94890F0F900F900F90AFCA96 |
:103F80008CE38093770200D00F92ADB7BEB7119645 |
:103F90001C93119786E396E013969C938E93129749 |
:103FA0000E94890F0F900F900F9099CA84E480931C |
:103FB000770200D00F9281E0ADB7BEB711968C9317 |
:103FC00011978BED93E013969C938E9312970E941A |
:103FD000890F0F900F900F90D7CB80E480937702DA |
:103FE00000D00F92EDB7FEB711838EED93E093836F |
:103FF00082830E94890F0F900F900F90C0CB87B1E2 |
:104000008C6087B9429A439A1092B6041092B50414 |
:1040100080E88093B4048093B3040895382F6B3FF5 |
:1040200020F0273E20F52A3078F1A32FB0E0FD01E3 |
:10403000EB54FB4F8081815080838F5FB9F46150D6 |
:104040006083FD01ED54FB4F80818130B9F186958D |
:1040500080838081842331F528B184E090E002C020 |
:10406000880F991FAA95E2F7282B28B9089547FDD4 |
:104070000DC028B184E090E002C0880F991F3A95E6 |
:10408000E2F7282B28B9089547FDF3CF28B184E043 |
:1040900090E002C0880F991F3A95E2F7809582233D |
:1040A00088B9089528B184E090E002C0880F991F74 |
:1040B000AA95E2F78095822388B9089580E88083E5 |
:1040C000C8CF809178028150809378028F5F09F089 |
:1040D000089584E08093780280E06091A10540918A |
:1040E000A0052091CE010E940E2081E06091A305E1 |
:1040F0004091A2052091CF010E940E200895809149 |
:10410000A60386FF07C042988091A70386FD07C0DB |
:10411000439A0895429A8091A70386FFF9CF439866 |
:1041200008958091B7040895809186020895809142 |
:10413000870208950E94602908951F930E944828CD |
:10414000182F0E946E22811708F4812F1F91089565 |
:104150001F93CF93DF93CDEDD2E010E00BC02F3F44 |
:10416000310594F42F5F3F4F398328831F5F2296D8 |
:104170001830C1F0812F0E94282897FD17C0288190 |
:104180003981281739075CF3121613067CF782175A |
:10419000930764F721503040398328831F5F2296AC |
:1041A000183041F7DF91CF911F91089580E090E0A2 |
:1041B000E6CFEF92FF920F931F93CF93DF930E946E |
:1041C0001B270E9421220E94BB390E9425287C01C6 |
:1041D0000E9415228C01FC0180819181F7012081D0 |
:1041E0003181820F931F90937E0280937D02F801AC |
:1041F00082819381F70122813381820F931F9093F3 |
:10420000800280937F02F80184819581F7012481E7 |
:104210003581820F931F0E94D93E0E94913A90935C |
:10422000840280938302F80186819781F7012681B9 |
:104230003781820F931F9093820280938102809135 |
:104240007D0290917E029093C1038093C003809180 |
:104250007F02909180029093C3038093C2030E94D7 |
:104260009D20843008F08EC010928502EDE7F2E0C8 |
:10427000A9E7B2E0C4E6D0E0608171814D915C9124 |
:104280001197CB019C0197FD7AC0359527953595FF |
:10429000279537FD70C04217530708F03FC09B01B8 |
:1042A00077FD92C0C901959587959595879511964B |
:1042B0009C938E938536910518F01196DC93CE93DE |
:1042C0003296129682E0E138F807B1F60E9448284B |
:1042D000833008F075C000E00E946E22833008F041 |
:1042E0005CC090E0002309F05EC0992301F51092B4 |
:1042F0008702109286028091A6038F7E8093A60388 |
:10430000002369F58091A7038F7E8093A703DF9137 |
:10431000CF911F910F91FF90EF9008954115510596 |
:1043200079F24150504011965C934E93C9CF109250 |
:10433000870280918602981709F44AC090938602FA |
:104340000E9418228093B70480918702882399F2F3 |
:104350008091A60380618093A603002399F2809147 |
:10436000A70380618093A703DF91CF911F910F91E5 |
:10437000FF90EF900895309521953F4F8CCF2D5FA2 |
:104380003F4F83CF0E94A8200E94953B80918502D9 |
:104390000E94C9288093850269CF0E941B22982F12 |
:1043A000002309F4A2CF1092870280918602081799 |
:1043B00099F0009386020E946F288093B704C4CFBF |
:1043C0000E946628082F88CF309521953F4F6ACFED |
:1043D00081E080938702B2CF81E080938702E9CFAA |
:1043E0001F93CF93DF93CDEDD2E010E0812F0E9499 |
:1043F0002828899399931F5F1830C1F7DF91CF91D7 |
:104400001F9108950E9407220E94863908951092F4 |
:10441000C2041092BB041092BC041092BD0410920E |
:10442000BE0485E58093B804089584EC94E0089573 |
:104430008091C20408958091C004089580E090E0C6 |
:1044400008958091C304882389F41092CB041092BC |
:10445000CA041092C9041092C8041092C7041092A2 |
:10446000C6041092C5041092C4040895815080932C |
:10447000C3042091790530E08091BB04992787FD22 |
:104480009095AC01249FC001259F900D349F900D05 |
:1044900011249093C5048093C4048091BC0499278F |
:1044A00087FD9095AC01429FC001439F900D529FA4 |
:1044B000900D11249093C7048093C6048091BE048C |
:1044C0008093C8041092C9048091BD04992787FD88 |
:1044D00090959093CB048093CA0408958091C3046F |
:1044E000813580F4882359F48091C20480FF0DC087 |
:1044F00090E08091CD01813818F091E001C093E007 |
:10450000892F089594E0892F089590E0892F0895C8 |
:104510001092CD041092CC041092CF041092CE04CD |
:104520000895EF92FF920F931F9324E736E040E047 |
:1045300050E00E94F740CA01B90128E631E040E0AE |
:1045400050E00E94F740AC01CB01DA019C01AD01C3 |
:1045500057FD25C061E02A3531054105510564F05C |
:1045600084EB90E0A0E0B0E07C018D01E21AF30A58 |
:10457000040B150BA8019701E22FF0E0EE0FFF1FCF |
:10458000EF57F94F25913491613019F0309521950D |
:104590003F4FC9011F910F91FF90EF9008955095E3 |
:1045A0004095309521953F4F4F4F5F4F6FEFD3CFE1 |
:1045B000693C24E4720722E0820720E092073CF481 |
:1045C00068537B4B8D4F9F4F0E94912208956855F1 |
:1045D0007E4C864090400E949122089524E736E068 |
:1045E00040E050E00E94F740C901DA019C01AD01B2 |
:1045F0008A359105A105B105B4F024EB30E040E027 |
:1046000050E0281B390B4A0B5B0BE22FF0E0EE0F5A |
:10461000FF1FE95CF84F8591949122273327281BCF |
:10462000390BC9010895263A6FEF36076FEF460739 |
:104630006FEF560774F42C543F4F4F4F5F4FE22FEC |
:10464000F0E0EE0FFF1FE95CF84F25913491C901AE |
:104650000895B7FFF4CF22273327A901281B390B70 |
:104660004A0B5B0BD2CF9FB7F8943998389A88B130 |
:10467000836088B98091B9008C7F8093B9008AE209 |
:104680008093B80010928B0210928D0210928E02CD |
:10469000E4EDF4E01082118212821482359685E0F6 |
:1046A000E031F807B9F79FBF089580938B0285EA40 |
:1046B0008093BC00089580938B0284E98093BC00B2 |
:1046C00008958093BB0085E88093BC00089585EC35 |
:1046D0008093BC00089585E88093BC0008950F93F3 |
:1046E0001F9310928B020CEB10E084E9D8018C939D |
:1046F00010928B02EBEBF0E0808180938D021092A0 |
:104700008D0210928E0280E88C931092BD00109260 |
:10471000BA0010821092B9001092B8000E943323A0 |
:1047200010928B0285EAF80180831F910F91089502 |
:104730001F920F920FB60F9211242F938F939F9376 |
:10474000EF93FF9380918B028F5F80938B02815058 |
:10475000853009F4C3C0863020F1893009F497C050 |
:104760008A30E0F5873009F411C1883009F404C1BA |
:1047700010928B0284E98093BC008AE090E09093D1 |
:1047800084018093830110928D0210928E02FF911A |
:10479000EF919F918F912F910F900FBE0F901F90CF |
:1047A0001895823009F47FC0833080F1833009F49A |
:1047B000BCC08430E9F680918E022091BB0090E06D |
:1047C000FC01EE0FFF1FEE0FFF1FE80FF91FEC5269 |
:1047D000FB4F238385E88093BC00D9CF8A3009F44E |
:1047E0009DC08B3029F610928B0284E98093BC0027 |
:1047F0008AE090E0909384018093830180919002FD |
:10480000823008F417C110929002C1CF8823F9F0CA |
:10481000813009F0ADCF80918D0290E0FC01EE0F68 |
:10482000FF1FEE0FFF1FE80FF91FEC52FB4F8081B7 |
:104830008093BB0085E88093BC00A9CF80918D0256 |
:104840008C3088F480918D028F5F80938D02E0918F |
:104850008D02F0E0EE0FFF1FEE0FFF1FE953FA4F3E |
:10486000858518165CF780918D028C3008F495C010 |
:1048700010928D0283E080938B0280918E02880FCC |
:104880008D5A8093BB0085E88093BC0080CFE09177 |
:104890009002F0E0E053FB4F80818093BB0085E8FD |
:1048A0008093BC0074CF8091B900803309F484C038 |
:1048B00010928B0284E98093BC008AE090E0909390 |
:1048C00084018093830180918D028F5F80938D029C |
:1048D00010928B0285EA8093BC0059CF80918E02A2 |
:1048E0002091BB0090E0FC01EE0FFF1FEE0FFF1FB9 |
:1048F000E80FF91FEC52FB4F248380918E028F5FEB |
:1049000080938E0280918E028C3010F010928E0275 |
:1049100010928B0284E98093BC0039CF80E88093A9 |
:10492000BB0085E88093BC0032CF8091B900803411 |
:1049300009F46CC080918E0290E0FC01EE0FFF1F25 |
:10494000EE0FFF1FE80FF91FEC52FB4F1182809111 |
:104950008E028F5F80938E0280918E028C3048F59C |
:1049600010928B0284E98093BC0080919102809325 |
:104970008F02109291020BCF80919002880F805F7E |
:104980008093BB0085E88093BC0001CF88E98093C9 |
:10499000BB0085E88093BC00FACE80918D0290E048 |
:1049A0008996880F991F8093BB0085E88093BC008F |
:1049B000EECE10928E02D4CF80919102882329F4FA |
:1049C00080918D028F5F8093910280918D0290E0A3 |
:1049D000FC01EE0FFF1FEE0FFF1FE80FF91FEC5257 |
:1049E000FB4F82818F5F8283882309F061CF8091A2 |
:1049F0008D0290E0FC01EE0FFF1FEE0FFF1FE80F8E |
:104A0000F91FEC52FB4F8FEF828352CF80918E02C1 |
:104A100020918E0290E0FC01EE0FFF1FEE0FFF1FB2 |
:104A2000E80FF91FEC52FB4F2C5F218385EC80933C |
:104A3000BC009BCF8F5F8093900287E080938B02B6 |
:104A400085EA8093BC00A3CE8F929F92BF92CF92B3 |
:104A5000DF92EF92FF920F931F93CF93DF9300D0DB |
:104A60000F92ADB7BEB711961C9211978FE098E0E8 |
:104A700013969C938E9312970E94890FE4EDF4E0B5 |
:104A80000F900F900F9010823596B5E0E031FB0744 |
:104A9000D1F710928B0285EA8093BC0080E197E207 |
:104AA0000197F1F710928E028F010B531040E8012D |
:104AB00061E0E62EF12C55EAB52E40E1C42E47E226 |
:104AC000D42E3BE0832E38E0932E08C02596089420 |
:104AD000E11CF11CB5E0C131DB0739F110928B020A |
:104AE000B092BC00C6010197F1F78881882371F369 |
:104AF00000D000D00F92EDB7FEB73196ADB7BEB77C |
:104B000011961C9292828182F482E3820E94890F24 |
:104B10000F900F900F900F900F9025960894E11C26 |
:104B2000F11CB5E0C131DB07C9F6C4EDD5E021E0E9 |
:104B3000E22EF12C9DEEC92E97E0D92EF80180814E |
:104B40008823C1F488811816ACF400D000D00F92ED |
:104B5000EDB7FEB73196ADB7BEB711961C92D282B3 |
:104B6000C182F482E3820E94890F0F900F900F9010 |
:104B70000F900F90F80111820B5F1F4F249608943D |
:104B8000E11CF11CF5E001311F07C1F6DF91CF9167 |
:104B90001F910F91FF90EF90DF90CF90BF909F906B |
:104BA0008F9008959FB7F89456985E9A8AB188635B |
:104BB0008AB98BB1877C8BB98091ED02813011F07D |
:104BC000539A5B98809180008C70809380008091D4 |
:104BD0008100837E8093810080918100836C80932B |
:104BE0008100809182008F738093820080916F009A |
:104BF000887F80936F0080916F00806280936F0048 |
:104C000010929302109292029FBF08951F920F92EA |
:104C10000FB60F9211240F931F932F933F934F932F |
:104C20005F936F937F938F939F93AF93BF93CF9334 |
:104C3000DF93EF93FF93209186003091870080915E |
:104C4000960290919702281B390B809186009091D3 |
:104C500087009093970280939602C9018D549440E7 |
:104C6000835F9A4118F58091980290919902049778 |
:104C700014F01092850181E090E090939902809366 |
:104C80009802FF91EF91DF91CF91BF91AF919F91EA |
:104C90008F917F916F915F914F913F912F911F91D4 |
:104CA0000F910F900FBE0F901F901895C091980212 |
:104CB000D0919902C930D10524F7C9018B5F90408A |
:104CC000845B914008F055C0265D31408E01000F95 |
:104CD000111FF801E85EFA4F80819181F901E81B0C |
:104CE000F90BCF01F7FD60C006978CF4809192021A |
:104CF00090919302883C91050CF04FC080919202F4 |
:104D0000909193020A969093930280939202F801F5 |
:104D1000E85EFA4F8081918101972817390734F0B6 |
:104D2000808191810196821793077CF58091920290 |
:104D300090919302833C910514F1F801E85EFA4FDB |
:104D400080819181A901481B590BCA0163E070E081 |
:104D50000E94C240CB01880F991F860F971FF80150 |
:104D6000E45DFA4F91838083085E1A4FF801318326 |
:104D700020832196D0939902C093980282CFF801A4 |
:104D8000E45DFA4F11821082EFCF2F5F3F4F233047 |
:104D9000310570F420E030E0C9CF88EC90E09093CA |
:104DA000930280939202B3CF909581959F4F9CCFB1 |
:104DB00020813181BBCF80916C05E82FF0E0EE0FB0 |
:104DC000FF1FE85EFA4F8081918186359105C4F01E |
:104DD00080916D05E82FF0E0EE0FFF1FE85EFA4FBF |
:104DE00080819181863591053CF4808191818B5A37 |
:104DF0009F4F24F484E0089582E0089580E00895B0 |
:104E0000808191818B5A9F4FCCF780916D05E82F5F |
:104E1000F0E0EE0FFF1FE85EFA4F8081918186354A |
:104E200091053CF4808191818B5A9F4F3CF786E03D |
:104E3000089588E008951F93CF93DF9380919202A5 |
:104E400090919302892B09F4D7C08091920290919E |
:104E5000930201979093930280939202809185012F |
:104E60008150809385018F5F09F0B7C0E0916A059A |
:104E7000F0E0EE0FFF1FDF01A85EBA4F2D913C91CD |
:104E80006091790570E0E45DFA4F808191814091F5 |
:104E90007A0550E0FC01E49FC001E59F900DF49F6E |
:104EA000900D1124F901E69F9001E79F300DF69FC8 |
:104EB000300D1124820F931F9093110580931005DC |
:104EC000E0916B05F0E0EE0FFF1FDF01A85EBA4F27 |
:104ED0002D913C91E45DFA4F80819181FC01E49F2A |
:104EE000C001E59F900DF49F900D1124A901469FEC |
:104EF0009001479F300D569F300D1124820F931F54 |
:104F00009093130580931205E0916C05F0E0EE0F8D |
:104F1000FF1FDF01A85EBA4F2D913C91E45DFA4F6F |
:104F20004081518128583F4F8091C20190E0BC01DF |
:104F3000469FC001479F900D569F900D1124280F4A |
:104F4000391F309315052093140537FD71C0E0918A |
:104F50006D05F0E0EE0FFF1FDF01A85EBA4F2D9147 |
:104F60003C91E45DFA4F80819181CC27DD27C21B03 |
:104F7000D30BC81BD90B10917B05BE01882777FD89 |
:104F80008095982F212F30E040E050E00E94834030 |
:104F9000FE01D7FD55C09F01442737FD4095542F92 |
:104FA0000E94834020E032E040E050E00E94F74061 |
:104FB000812F90E0C89FB001C99F700DD89F700DE0 |
:104FC000112477FD3AC07595679575956795260FFD |
:104FD000371F30931705209316050E94DB26982F64 |
:104FE000809194029817E1F09093940210929502A8 |
:104FF000DF91CF911F910895109217051092160519 |
:1050000010921505109214051092130510921205B6 |
:105010001092110510921005DF91CF911F91089504 |
:1050200080919502883CC0F78F5F80939502F4CF02 |
:1050300010921505109214058ACF6D5F7F4FC3CF74 |
:10504000EE27FF27EC1BFD0BA6CF80E195E008952E |
:10505000843068F0E82FF0E0EE0FFF1FE65EFA4FB5 |
:105060000190F081E02DED58FF4FCF010895E82F1A |
:10507000F0E0E659FA4FE481F0E0EE0FFF1FE85E42 |
:10508000FA4F0190F081E02DED58FF4FCF010895C8 |
:105090008091920290919302803A910594F48091CC |
:1050A0009202909193028C3891054CF48091920277 |
:1050B000909193028837910534F481E0089583E05C |
:1050C000089584E0089582E00895089580919502FE |
:1050D000883C11F080E008958091940208958091B9 |
:1050E0006A05E82FF0E0EE0FFF1FE85EFA4F8081BF |
:1050F000918187349105B4F080916B05E82FF0E041 |
:10510000EE0FFF1FE85EFA4F808191818734910591 |
:105110003CF4808191818A5B9F4FFCF083E008958D |
:1051200082E00895808191818A5B9F4FC4F48091D1 |
:105130006B05E82FF0E0EE0FFF1FE85EFA4F80816D |
:105140009181873491053CF4808191818A5B9F4FE6 |
:10515000E4F087E0089588E0089584E00895809160 |
:105160006B05E82FF0E0EE0FFF1FE85EFA4F80813D |
:105170009181873491055CF4808191818A5B9F4F96 |
:1051800014F080E0089585E0089586E0089581E0B8 |
:105190000895CF93DF93682F80916B05A82FB0E01F |
:1051A000AA0FBB1FFD01E85EFA4F2081318180917B |
:1051B0009205482F50E04217530724F48091B5051B |
:1051C00082FD75C062FD61C0FD01E85EFA4F80811D |
:1051D0009181CC27DD27C41BD50B8C179D0724F4A8 |
:1051E0008091B50583FD61C063FD40C080916A0573 |
:1051F000A82FB0E0AA0FBB1FFD01E85EFA4F808127 |
:1052000091814817590724F48091B50580FD51C05C |
:1052100060FD1EC0FD01E85EFA4F808191818C1710 |
:105220009D0724F48091B50581FD45C061FF0CC048 |
:10523000A85EBA4F2D913C9180919305C81BD1096E |
:10524000C217D3070CF46D7E862FDF91CF9108959E |
:10525000FD01E85EFA4F2081318180919305481B62 |
:10526000510924173507B4F66E7ED4CFA85EBA4F25 |
:105270002D913C9180919305FE01E81BF109E21705 |
:10528000F3070CF0B3CF677DB1CFFD01E85EFA4FB5 |
:105290002081318180919305FA01E81BF1092E17D5 |
:1052A0003F070CF091CF6B7D8FCF68629FCF646218 |
:1052B0008BCF6161AFCF6261862FDF91CF9108956F |
:1052C00080916A05A82FB0E0AA0FBB1FFD01E85E20 |
:1052D000FA4F808191818D5E9F4F14F0109286016C |
:1052E000A85EBA4F8D919C918A5B9F4F44F4809148 |
:1052F0008601882321F481E080938601089580E06F |
:105300000895E82FF0E0EE0FFF1FE25AFD4F608195 |
:105310007181882777FD8095982F2CEE30E040E052 |
:1053200050E00E948340089560915E0270915F0298 |
:10533000882777FD8095982F2CEE30E040E050E0F4 |
:105340000E94834060934E0570934F0580935005F3 |
:10535000909351056091600270916102882777FDFA |
:105360008095982F0E948340609352057093530557 |
:10537000809354059093550508958091AF049091C2 |
:10538000B0042091A8023091A902820F931F63E01C |
:1053900070E00E94C2407093430560934205809183 |
:1053A0009E0490919F04820F931F63E070E00E941F |
:1053B000C24070935B0560935A0580918F04909171 |
:1053C00090049093570580935605809182049091A4 |
:1053D00083042091A2023091A302820F931F909325 |
:1053E000A3028093A2028091B1049091B204209113 |
:1053F000AA023091AB02820F931F63E070E00E941B |
:10540000C24070934505609344058091A00490913B |
:10541000A104820F931F63E070E00E94C24070936A |
:105420005D0560935C058091910490919204909346 |
:1054300059058093580580918404909185042091AA |
:10544000A4023091A502820F931F9093A50280932E |
:10545000A4028091A6029091A70201969093A702C0 |
:105460008093A60220918C0430918D048091AC022F |
:105470009091AD02820F931F909349058093480548 |
:1054800010921601EAE7F0E08081886C808308952D |
:105490002F923F924F925F926F927F928F929F9244 |
:1054A000AF92BF92CF92DF92EF92FF920F931F9332 |
:1054B000DF93CF9300D000D0CDB7DEB780918502C7 |
:1054C000882379F420918604309187048091C60165 |
:1054D000482F50E088279927841B950B28173907F8 |
:1054E000CCF58091A603877F8093A6038091A703C4 |
:1054F000877F8093A7031092BB031092BA03109288 |
:10550000BD031092BC031092C9031092C8031092FD |
:10551000CB031092CA031092A1021092A002109223 |
:105520009F0210929E020F900F900F900F90CF91BC |
:10553000DF911F910F91FF90EF90DF90CF90BF9080 |
:10554000AF909F908F907F906F905F904F903F9023 |
:105550002F900895809186049091870448175907E9 |
:105560000CF4BFCF8091A60388608093A60360915E |
:105570007E058091810290918202805C9F4F8138EC |
:10558000910508F0E5C021E08091790290917A02BE |
:105590008134910540F480917B0290917C028134AA |
:1055A000910508F4D8C066958091A703877F809302 |
:1055B000A703862F90E0A0E0B0E089839A83AB83B5 |
:1055C000BC8328EE622E23E0722E812C912C681A67 |
:1055D000790A8A0A9B0A60915E0270915F028827AD |
:1055E00077FD8095982F2CEE30E040E050E00E944F |
:1055F00083405B016C012AE030E040E050E00E9413 |
:10560000834024E736E040E050E00E94F7403093CA |
:10561000BB032093BA0320904E0530904F05409075 |
:10562000500550905105C401B301A20191010E949F |
:1056300083407B018C0169817A818B819C81A601E9 |
:1056400095010E948340E60EF71E081F191FC8012E |
:10565000B70128EE33E040E050E00E94F740C90176 |
:10566000DA0180934E0590934F05A0935005B093B7 |
:1056700051058219930920919E0230919F02280FB3 |
:10568000391F30939F0220939E029093C903809309 |
:10569000C8036091600270916102882777FD809550 |
:1056A000982F2CEE30E040E050E00E9483405B01F8 |
:1056B0006C012AE030E040E050E00E94834024E7A3 |
:1056C00036E040E050E00E94F7403093BD03209365 |
:1056D000BC032090520530905305409054055090E3 |
:1056E0005505C401B301A20191010E9483407B01D1 |
:1056F0008C0169817A818B819C81A60195010E9430 |
:105700008340E60EF71E081F191FC801B70128EED7 |
:1057100033E040E050E00E94F740C901DA01809395 |
:10572000520590935305A0935405B09355058219E3 |
:1057300093092091A0023091A102280F391F3093C4 |
:10574000A1022093A0029093CB038093CA03EBCED7 |
:10575000669520E019CF222309F426CF8091A70374 |
:1057600088608093A70325CF9F92AF92BF92CF927C |
:10577000DF92EF92FF920F931F93CF93DF9380916D |
:105780008D0190918E01019790938E0180938D01F0 |
:10579000892B09F052C080E091E090938E018093B4 |
:1057A0008D019090990580919A05A82EBB24CC2458 |
:1057B000DD24CA18DB085EE9E52E52E0F52EC8EAC2 |
:1057C000D2E00CEC13E0F70120813181B901660FC2 |
:1057D000771F620F731F882777FD8095982F605879 |
:1057E0007F4F8F4F9F4F20E031E040E050E00E941C |
:1057F000F740DA01C901692D70E00E94C2409B01A7 |
:1058000088819981860F971F998388838C159D05C0 |
:1058100004F5D982C882C601F80131832083958BB3 |
:10582000848BF701119211927F0122960E5F1F4F18 |
:10583000F2EAEF16F2E0FF0631F6DF91CF911F9109 |
:105840000F91FF90EF90DF90CF90BF90AF909F901F |
:105850000895A816B90604F7B982A882C501DCCF5D |
:10586000AF92BF92CF92DF92EF92FF920F931F936E |
:10587000CF93DF9380919D02882321F080918A024B |
:1058800080FF76C160914E0570914F058091500563 |
:105890009091510520E032E040E050E00E94F74056 |
:1058A000E90137FD7DC160915205709153058091EA |
:1058B00054059091550520E032E040E050E00E9410 |
:1058C000F740690137FD70C1CC16DD060CF4D6C077 |
:1058D000209187013091880137FD0AC080914805E9 |
:1058E0009091490597FD54C1813891050CF4FEC093 |
:1058F00060E070E0C0E0D0E080918B0190918C017D |
:10590000892B09F4BDC0B6017595679575956795A6 |
:10591000759567956F5F7F4FCE010E94C2409B01D6 |
:10592000442737FD4095542F80914A0590914B05AF |
:10593000A0914C05B0914D05280F391F4A1F5B1FE0 |
:1059400020934A0530934B0540934C0550934D05E9 |
:105950008091B901C82FD0E0CC9EC001CD9E900DA2 |
:10596000DC9E900D112497FD24C195958795959502 |
:1059700087959595879595958795959587955E01DA |
:10598000A81AB90AB7FCEDC080918B0190918C01E7 |
:10599000009709F0D6C0C0907B02D0907C02809125 |
:1059A000790290917A02C80ED91ED694C794D694E3 |
:1059B000C794D694C79480E490E0C80ED91E809115 |
:1059C000890190918A01AA2797FDA095BA2F7CE1C1 |
:1059D000E72E72E0F72E012D112DE81AF90A0A0BB5 |
:1059E0001B0BCA01B90126E832E040E050E00E94FA |
:1059F000F740E20EF31E041F151FC801B70128E689 |
:105A000031E040E050E00E94F740645B70406A9DE6 |
:105A1000C0016B9D900D7A9D900D1124B6010E94DE |
:105A2000C2409B01CE01880F991F8C0F9D1F8217CA |
:105A300093070CF4ABC044275527481B590BB901F9 |
:105A4000241735070CF4BA019B01442737FD409514 |
:105A5000542F8091620590916305A0916405B091E7 |
:105A60006505820F931FA41FB51F80936205909355 |
:105A70006305A0936405B093650568C06E0128CFE7 |
:105A800089E1C816D1040CF03ECF80914005909179 |
:105A90004105860F971F90934105809340058091A3 |
:105AA0009C02882309F42FCF88EC90E00E945E3E90 |
:105AB0000091870110918801B801882777FD8095B2 |
:105AC000982F26E832E040E050E00E948340609347 |
:105AD0004A0570934B0580934C0590934D051093A8 |
:105AE0008A010093890110929C020DCF245E3D4FE4 |
:105AF00079010027F7FC0095102F60914A057091FD |
:105B00004B0580914C0590914D052AE73DEF4FEFF5 |
:105B10005FEF0E94F740E20EF31E041F151FC8013D |
:105B2000B70128E631E040E050E00E94F740645BB6 |
:105B30007040EB01CC0FDD1FCC0FDD1FCC0FDD1F44 |
:105B4000DBCE019790938C0180938B01DF91CF91F5 |
:105B50001F910F91FF90EF90DF90CF90BF90AF908B |
:105B6000089584EF91E090938C0180938B01EECFA8 |
:105B70000E949A20882351F380919D028F5F809329 |
:105B80009D028530C0F40E94B73EE0CFBC015CCFDF |
:105B9000909581959F4F813891050CF0A9CEA6CFA5 |
:105BA000D095C195DF4F7FCED094C194D108D394C6 |
:105BB0008BCE4F96DACE88EE93E00E945E3EC6CF43 |
:105BC0002F923F924F925F926F927F928F929F920D |
:105BD000AF92BF92CF92DF92EF92FF920F931F93FB |
:105BE000DF93CF93CDB7DEB72C970FB6F894DEBF17 |
:105BF0000FBECDBF60914E0570914F05809150054D |
:105C0000909151050E94D8229A8389836091520510 |
:105C10007091530580915405909155050E94D822AA |
:105C20006C016091520570915305809154059091DB |
:105C300055050E9491228C0160914E0570914F058F |
:105C400080915005909151050E94EE221C016090B8 |
:105C50005A0570905B05882477FC8094982CC601C7 |
:105C6000AA2797FDA095BA2F8F839887A987BA870F |
:105C7000A0904805B0904905CC24B7FCC094DC2C1A |
:105C8000C801AA2797FDA095BA2F8B839C83AD836B |
:105C9000BE836F81788589859A85A40193010E94CE |
:105CA00083407B018C016B817C818D819E81A6016B |
:105CB00095010E948340E61AF70A080B190BC801E8 |
:105CC000B70120E030E140E050E00E94F74030931F |
:105CD0005F0520935E05A0915C05B0915D05BC87D2 |
:105CE000AB87609152057091530580915405909156 |
:105CF00055050E94D822AA2797FDA095BA2FBC016E |
:105D0000CD01A60195010E94834020E032E040E0F1 |
:105D100050E00E94F74079018A016B817C818D817E |
:105D20009E81A40193010E94834020E032E040E084 |
:105D300050E00E94F740E20EF31E041F151F44249A |
:105D400037FC4094542CC801B701A20191010E9474 |
:105D5000834020E030E840E050E00E94F740EB85CF |
:105D6000FC85E20FF31FF0936105E09360058981E4 |
:105D70009A815C01CC24B7FCC094DC2C20914805AE |
:105D800030914905442737FD4095542F6F81788520 |
:105D900089859A850E948340A60195010E94F7405B |
:105DA00079018A0120915A0530915B05442737FD1E |
:105DB0004095542F6B817C818D819E810E94834010 |
:105DC000A60195010E94F740E20EF31EF0924705EE |
:105DD000E09246052C960FB6F894DEBF0FBECDBFFD |
:105DE000CF91DF911F910F91FF90EF90DF90CF90B7 |
:105DF000BF90AF909F908F907F906F905F904F90EB |
:105E00003F902F900895EF92FF920F931F938091F0 |
:105E10008502882321F48091720586FD13C180914B |
:105E20005A0590915B0590935F0580935E05809184 |
:105E30005C0590915D05909361058093600560918C |
:105E40004805709149057093470560934605809118 |
:105E50004605909147057C010027F7FC0095102F1F |
:105E600080914A0590914B05A0914C05B0914D054C |
:105E7000E80EF91E0A1F1B1FE0924A05F0924B051F |
:105E800000934C0510934D059B01442737FD409529 |
:105E9000542F8091620590916305A0916405B091A3 |
:105EA0006505820F931FA41FB51F80936205909311 |
:105EB0006305A0936405B093650580E7E8168CE858 |
:105EC000F80683E0080780E018070CF482C080E938 |
:105ED00093E7ACEFBFEFE80EF91E0A1F1B1FE0921D |
:105EE0004A05F0924B0500934C0510934D058091A7 |
:105EF0005E0590915F059C01442737FD4095542F26 |
:105F000080914E0590914F05A0915005B09151059B |
:105F1000280F391F4A1F5B1F20934E0530934F05F2 |
:105F20004093500550935105213999E8390794E081 |
:105F3000490790E059070CF03FC02137A6E73A0720 |
:105F4000ABEF4A07AFEF5A070CF46FC080916005C2 |
:105F5000909161059C01442737FD4095542F809115 |
:105F6000520590915305A0915405B0915505280F05 |
:105F7000391F4A1F5B1F20935205309353054093EE |
:105F80005405509355052139B9E83B07B4E04B0758 |
:105F9000B0E05B078CF120523341494050402093E0 |
:105FA00052053093530540935405509355051F9166 |
:105FB0000F91FF90EF900895205233414940504097 |
:105FC00020934E0530934F05409350055093510553 |
:105FD000BDCF17FF8CCF80E79CE8A3E0B0E0E80ED0 |
:105FE000F91E0A1F1B1FE0924A05F0924B05009311 |
:105FF0004C0510934D057BCF213786E738078BEF93 |
:1060000048078FEF58079CF6205E3C4E464F5F4F87 |
:1060100020935205309353054093540550935505F2 |
:106020001F910F91FF90EF900895205E3C4E464FD8 |
:106030005F4F20934E0530934F054093500550938A |
:10604000510584CF0E94E02D60914805709149056B |
:10605000FECE0E94BD290E94032F80915E05909183 |
:106060005F059093B5038093B40380916005909190 |
:1060700061059093B7038093B60380914605909194 |
:1060800047059093B9038093B8038091420590919E |
:1060900043059093AF038093AE03809144059091A4 |
:1060A00045059093B1038093B0038091480590918A |
:1060B00049059093B3038093B2030E94482A0E943B |
:1060C000B42B08951092CA011092C9011092AD022A |
:1060D0001092AC0210924105109240051092AB0252 |
:1060E0001092AA021092A9021092A8021092A10284 |
:1060F0001092A00210929F0210929E020E94161906 |
:1061000060915E0270915F02882777FD8095982FDD |
:106110002CEE30E040E050E00E94834060934E055A |
:1061200070934F05809350059093510560916002E4 |
:1061300070916102882777FD8095982F0E94834097 |
:1061400060935205709353058093540590935505C1 |
:106150001092620510926305109264051092650515 |
:10616000609187017091880170938A016093890121 |
:10617000882777FD8095982F26E832E040E050E0B0 |
:106180000E94834060934A0570934B0580934C05B1 |
:1061900090934D0508959C018091C401823031F0A7 |
:1061A000833081F0813029F0C901089562177307A7 |
:1061B00064F4620F731F77FD0EC09B013595279520 |
:1061C000C901089526173707A4F3220F331F261B92 |
:1061D000370BC90108956F5F7F4FEFCF0F93382FB3 |
:1061E000E62F8CE398E2632F70E00E94C240709328 |
:1061F000900160938F01E0936805409367052093B9 |
:106200006605009369050F9108950F939091BE0163 |
:106210008091720582FD0EC04091BC012091BB01AE |
:10622000265F892F8F5F622F0091C5010E94EE309B |
:106230000F91089540E0F2CF0F9381E26AE548E7BD |
:106240002AE508E70E94EE300F9108952F923F92C1 |
:106250004F925F926F927F928F929F92AF92BF9276 |
:10626000CF92DF92EF92FF920F931F93DF93CF9322 |
:10627000CDB7DEB7E4970FB6F894DEBF0FBECDBF43 |
:106280000E94D9200E9429302091830230918402FB |
:10629000388F2F8B0E949D20833008F079C4809125 |
:1062A000DC018A3009F450C3843109F44DC32898C5 |
:1062B0000E94633E8091C7029091C802009709F442 |
:1062C0004DC301979093C8028093C70280918802C2 |
:1062D000909189028150914008F0C7C480918A0250 |
:1062E0008E7F80938A02E0918502EE2351F08091A7 |
:1062F000910590E02F89388D8217930714F4988FB9 |
:106300008F8B2091810230918202A90137FDA0C4B8 |
:1063100080917B0590E0880F991F880F991F841743 |
:1063200095070CF422C480917205682F70E0C901B2 |
:10633000AA2797FDA095BA2F209162053091630599 |
:106340004091640550916505281B390B4A0B5B0B86 |
:10635000209362053093630540936405509365056F |
:10636000203B8CE338078FEF48078FEF58070CF07E |
:10637000E0C380EB9CE3AFEFBFEF809362059093A7 |
:106380006305A0936405B093650568727070672B10 |
:1063900009F0E6C38091BA01A82FB0E0BE8BAD8BA7 |
:1063A0002E2F30E03CA32BA3309167053AA3432F57 |
:1063B00050E060E070E04E8F5F8F68A379A380911A |
:1063C0006805282E332444245524BE016B5F7F4F7B |
:1063D0007C8B6B8BCE0109969A8B898B42E4642E61 |
:1063E00045E0742E36E5832E35E0932E2EE4E22E22 |
:1063F00025E0F22E5B016C0100E010E080E190E00E |
:10640000002E02C0880F991F0A94E2F7ABA1BCA12D |
:106410008A239B23892B09F4BEC2F60111821082C4 |
:10642000D3012D913C91442737FD4095542FC20153 |
:10643000B1010E94834020E430E040E050E00E943F |
:10644000F740F40180819181AD89BE89A89FB00198 |
:10645000A99F700DB89F700D112477FD96C3759597 |
:106460006795759567957595679575956795620FAD |
:10647000731FF60180819181680F791FD5016D939B |
:106480007C93B0EC60307B070CF0B6C220E030ECBF |
:10649000F501318320830F5F1F4F22E030E0A20E11 |
:1064A000B31EC20ED31E620E731E820E931E44E0F4 |
:1064B00050E0E40EF51E0230110509F09FCFE09187 |
:1064C0004805F09149052091660590906905A090D6 |
:1064D0006205B0906305C0906405D0906505809119 |
:1064E0008F028823C1F080918802909189020297DF |
:1064F000C09758F46F89788D1616170634F481E02A |
:1065000090E0909389028093880280917C05A82F67 |
:10651000B0E0B88FAF8B2F88388C220C331C220C44 |
:10652000331CEE0FFF1FBF01882777FD8095982F42 |
:1065300030E040E050E00E94834020E430E040E062 |
:1065400050E00E94F74079018A01692D70E080E0F7 |
:1065500090E0A60195010E94834020EF35E540E0E0 |
:1065600050E00E94F740C701820F931FB0E48130D2 |
:106570009B0714F080E090E49C01E0EC80309E07E3 |
:1065800014F420E030EC8091810290918202880F17 |
:10659000991F880F991FA901481B590BF1EA2F1663 |
:1065A00031040CF4B7C2C10137FC6DC395958795D2 |
:1065B00022273327281B390B421753073CF0910140 |
:1065C00035952795421753070CF447C380917D05F5 |
:1065D000682F70E0788B6F87CB01880F991F880F29 |
:1065E000991F7101E81AF90A2E153F053CF082192E |
:1065F00093097901821793070CF47C019701F7FC4A |
:1066000022C335952795220D331DB901882777FDC3 |
:106610008095982F2091CC0130E040E050E00E941E |
:10662000834020E430E040E050E00E94F740390130 |
:1066300044245524421A530A80918F01909190016D |
:106640009C0140E050E02A8F3B8F4C8F5D8F09EC1E |
:10665000A02E02E0B02E1DE7812E12E0912E00E068 |
:1066600010E03AA1332309F4ABC1D4016D917C91C0 |
:10667000E989FA8920813181261B370B442737FDB0 |
:106680004095542FF50180819181A281B381820FC1 |
:10669000931FA41FB51F80839183A283B383AB890B |
:1066A000BC89CD90DC90C61AD70AF801EE0FFF1F07 |
:1066B000EE0FFF1FE753FD4F60817181828193814F |
:1066C000603026E072072FEF82072FEF92070CF061 |
:1066D000A4C140E056E06FEF7FEF408351836283B7 |
:1066E000738360E076E08FEF9FEF2A8D3B8D4C8DBA |
:1066F0005D8D0E94F7402C0D3D1DF801EE0FFF1F30 |
:1067000081E090E08C0F9D1FE80FF91F31832083FB |
:10671000241535050CF07AC1518240820F5F1F4F5E |
:10672000A4E0B0E0AA0EBB1EE989FA893296FA8B82 |
:10673000E98B22E030E0820E931E4B895C894E5F2C |
:106740005F4F5C8B4B8B0230110509F08ACF49817A |
:106750005A815093C1034093C0032B813C813093F5 |
:10676000C3032093C203F092C503E092C4033092A6 |
:10677000C7032092C60380917C05682F70E07E8756 |
:106780006D8770913902798FF4ED4F2EF4E05F2E12 |
:10679000E4ED8E2EE3E09E2E74EDA72E75E0B72E6D |
:1067A0006FEA662E62E0762ECC24DD24C901AA278A |
:1067B00097FDA095BA2F8DA39EA3AFA3B8A7BA014A |
:1067C000882777FD8095982F69A77AA78BA79CA724 |
:1067D000C101AA2797FDA095BA2F8DA79EA7AFA7A5 |
:1067E000B8AB9701442737FD4095542F29AB3AABFE |
:1067F0004BAB5CAB93C0D5013C9013140CF092C032 |
:1068000012966C91772767FD7095872F972F2DA192 |
:106810003EA14FA158A50E94834020E430E040E013 |
:1068200050E00E94F74079018A01F50161817727E4 |
:1068300067FD7095872F972F29A53AA54BA55CA5D5 |
:106840000E94834020E430E040E050E00E94F740A6 |
:10685000E20EF31E232D332727FD3095432F532FB0 |
:106860006DA57EA58FA598A90E94834020E430E005 |
:1068700040E050E00E94F740E20EF31ED50113966F |
:106880002C91332727FD3095432F532F69A97AA9DF |
:106890008BA99CA90E94834020E430E040E050E0B6 |
:1068A0000E94F740E20EF31EF30160817181C7017F |
:1068B0000E94CB30D3018C9311969C9397FD28C1F5 |
:1068C0009595879595958795ED85FE858E179F07FC |
:1068D0000CF055C0CF01009709F45BC0D2018C9336 |
:1068E000E3E0EC1528F0D2018C91F4018083118251 |
:1068F0000894C11CD11C25E030E0420E531E42E03A |
:1069000050E0840E951E64E070E0A60EB71E640E83 |
:10691000751E7CE0C716D10409F491C080918A02EB |
:1069200080FD69CFB98DBB23F9F0F601EE0FFF1F93 |
:10693000EE0FFF1FEC0DFD1DEC52FB4FD601A65CC8 |
:10694000BD4F8C918083CCCF289A0E94633E80916A |
:10695000C7029091C802009709F0B3CC80918A02D7 |
:106960008E7E80938A02BFCCF601EE0FFF1FEE0FE2 |
:10697000FF1FEC0DFD1DEC52FB4F1082B1CF2F8598 |
:106980003889281739070CF0A6CFC901009709F0FC |
:10699000A5CF81E0A3CFD7012D913D914D915C9181 |
:1069A0006E8D7F8D88A199A10E94834028EF3AE2E5 |
:1069B00040E050E00E94F740F6013183208330CD63 |
:1069C000EB89FC89C080D180D4018D919C91C81A3B |
:1069D000D90A9601442737FD4095542FF50180814F |
:1069E0009181A281B381820F931FA41FB51F808361 |
:1069F0009183A283B38359CE615070440CF44BCD84 |
:106A0000E0E0F0E4D501ED93FC9345CD621673060A |
:106A10000CF084CE7182608281CE61305AEF7507AE |
:106A200050E0850750E095070CF45FCE60E07AEF08 |
:106A300080E090E0608371838283938356CE80E010 |
:106A40000E94552380919101815080939101882368 |
:106A500009F045C088E18093910160914E057091E5 |
:106A60004F0580915005909151052AE030E040E0BB |
:106A700050E00E94834024E736E040E050E00E946E |
:106A8000F7403093A9032093A803609152057091B9 |
:106A9000530580915405909155052AE030E040E07F |
:106AA00050E00E94834024E736E040E050E00E943E |
:106AB000F7403093AB032093AA0360914A0570918D |
:106AC0004B0580914C0590914D0526E832E040E061 |
:106AD00050E00E94F7403093AD032093AC03E4965E |
:106AE0000FB6F894DEBF0FBECDBFCF91DF911F91DF |
:106AF0000F91FF90EF90DF90CF90BF90AF909F905D |
:106B00008F907F906F905F904F903F902F9008955F |
:106B10000396D6CECA014135510514F080E590E0C8 |
:106B20009C014FEF803B94070CF050CD20EB3FEFE2 |
:106B30004DCD2155334C404050400CF426CC80E5DF |
:106B400093ECA0E0B0E08093620590936305A0937E |
:106B50006405B093650568727070672B09F41ACCF0 |
:106B60000E94302CE091850215CC88EE93E0909342 |
:106B70008C0180938B0180917205682F70E084FDF9 |
:106B8000D6CB81E080939C02D2CB615F7F4F67CCF4 |
:106B90000E949D208330B0F080918A028F7E809386 |
:106BA0008A028091850590E028EE31E0BC01629F69 |
:106BB000C001639F900D729F900D11249093C802A5 |
:106BC0008093C7028F89988D8997B4F080918A024B |
:106BD00080FF12C08091880290918902AFEF8F3FB1 |
:106BE0009A0729F0019690938902809388020E9467 |
:106BF0004D3F0E94053177CB8091880290918902A8 |
:106C00008F3F910509F058F51092CD021092CE02F7 |
:106C10001092CF021092D0021092C9021092CA02B2 |
:106C20001092CB021092CC028A3F910501F781E0CD |
:106C300080939C0210926205109263051092640585 |
:106C400010926505D4CF222733272E193F09D9CCBE |
:106C500044275527421B530B5BCB9A01B7CC80913D |
:106C60008A02826080938A02C2CF80918405482F75 |
:106C700050E0588F4F8B80918A02806180938A0206 |
:106C80000E941C3130CB019691CC80918A028460A5 |
:106C900080938A028FEF8093D9011092DA0180E20B |
:106CA0008093DB010E94F0210895109288051092D4 |
:106CB000890510928A0588E080938B0585ED809385 |
:106CC0009C0582E080939D0588E780939E058AE07D |
:106CD00080939F050895EAE6F5E082E080936A05D7 |
:106CE00081E080936B0583E080936C0574E0709382 |
:106CF0006D0525E020936E05A6E0A0936F0587E063 |
:106D00008093700558E05093710584E48093720578 |
:106D10004EE1409373058BEF809375058AE0809375 |
:106D200076054093740540937805709377055093EA |
:106D300079058CE080937A0580937B0550937C05E0 |
:106D400086EE80937D0580E880937F0580E58093C3 |
:106D5000800534E6309381056FE56093830583E217 |
:106D600080938405409385051092860580E2809388 |
:106D7000870530938C0588E280938D051092B605C7 |
:106D800092E390938E0586E980938F05209390057A |
:106D9000909391052AE52093920590939305109284 |
:106DA000B5052093940583E480939505109296058C |
:106DB00090939B056093A00583EF8093A2058FE0DD |
:106DC0008093A1058093A3058DEF8093A405309354 |
:106DD000A5052093A60525AF26AF8BE487AF80934A |
:106DE000AA058093AB051092AC05A093AD05509316 |
:106DF000AE052093AF054093B0053093B1053093B5 |
:106E0000B2057093B3050895805090400E943841B8 |
:106E10000895682F863030F065E082E090E00E94AF |
:106E2000504108958823C9F761E082E090E00E9414 |
:106E30005041089582E090E00E943841863008F485 |
:106E4000089582E090E063E00E94504183E008955D |
:106E5000805090400E945041089581E08093C70582 |
:106E6000E4EDF5E080E009C090E0908311821282A9 |
:106E700013828F5F3496803159F08430A8F790E404 |
:106E800090831182128213828F5F34968031A9F72A |
:106E900090E49093D5059093D70580EC8093D90525 |
:106EA0009093DB058093DE058093DF059093E205E8 |
:106EB0008093E305A8ECB5E0E2E9F1E087E001901A |
:106EC0000D928150E1F708958091C705813011F04E |
:106ED00080E0089587EC95E068EE73E04DE450E0C3 |
:106EE0000E94464181E0089588EE93E00E94384177 |
:106EF000813011F080E0089587EC95E068EE73E052 |
:106F00004DE450E00E94284181E008958050904077 |
:106F10000E945E4108951F93182F863000F115E0FE |
:106F200068ED71E0605070408AE695E04DE550E014 |
:106F30000E94464182E690E06DE570E00E945E416D |
:106F40008AE695E060E570E048E050E00E94464146 |
:106F5000812F0E9409370E94FF1F1F9108958823E7 |
:106F6000E1F390E001972DE530E0829FB001839F2F |
:106F7000700D929F700D11246C597F4FD3CF982FB5 |
:106F80008150853068F06EE171E0605070408AE6B3 |
:106F900095E04DE550E00E9428410E94FF1F0895B2 |
:106FA000892F90E001972DE530E0829FB001839F0B |
:106FB000700D929F700D11246C597F4FE6CF805059 |
:106FC00090400E94404108950E946B360E94C23F4B |
:106FD0000E94553680EC8093720583E0809377059C |
:106FE00084E18093850586E4809396058EE1809305 |
:106FF000A1058093A305ABEBB5E0EAE9F1E089E0F8 |
:1070000001900D928150E1F708950E946B360E9425 |
:10701000C23F0E94553680EC8093720583E08093D6 |
:10702000770584E18093A1058093A305ABEBB5E0E0 |
:10703000E4EAF1E087E001900D928150E1F70895D4 |
:107040000E946B360E94C23F0E94553680EC8093AE |
:107050007205ABEBB5E0ECEAF1E086E001900D9251 |
:107060008150E1F708950F931F93CF93DF9381E051 |
:1070700090E00E9438418B3409F44FC000D00F9249 |
:10708000ADB7BEB711961C9211978DE998E0139693 |
:107090009C938E9312970E94890F0F900F900F90E0 |
:1070A00088EE93E06FEF0E94504180E590E00E94EF |
:1070B000384100E08C3008F494C080E08F5F843069 |
:1070C00011F00023D9F711E0123031F0133009F438 |
:1070D00085C0113009F47FC00E940538002379F083 |
:1070E000C0E0D0E0CE01805B9F4F0E943841FE019E |
:1070F000E659FA4F80832196C830D10599F7812F40 |
:107100000E948B371F5F1630F9F681E00E94093725 |
:1071100081E090E06BE40E9450410E941A370E9487 |
:10712000BF370E941A3700D000D00F92EDB7FEB7DC |
:107130003196ADB7BEB711961C9224E838E0328381 |
:107140002183838314820E94890F0F900F900F90E8 |
:107150000F900F900E947437882309F444C0E4ED27 |
:10716000F5E020E0808118160CF42F5F349686E05D |
:10717000E431F807B9F72093AE02ADB7BEB7179761 |
:107180000FB6F894BEBF0FBEADBFEDB7FEB73196D8 |
:1071900011961C9282E498E09283818388EC95E0BA |
:1071A00094838383258316820E94890F0F900F900A |
:1071B0000F900F90EDB7FEB7118281E298E09383B4 |
:1071C00082830E94890F0F900F900F90DF91CF91D3 |
:1071D0001F910F9108950E94203880CF0E94E437BC |
:1071E0007DCF01E06ACF00D00F92EDB7FEB71182DC |
:1071F00083E698E0938382830E94890F0F900F901B |
:107200000F900E942D370E946437A9CF9FB7F89442 |
:107210008091C9008F778093C9008091C9008F7BCE |
:107220008093C9008091C9008F7D8093C9005A9ACC |
:1072300052985B9A539A1092CD008AE28093CC00C8 |
:107240008091C80082608093C80088E18093C90063 |
:107250008091CA008F778093CA008091CA008F7B8B |
:107260008093CA008091CA008F7D8093CA0080916C |
:10727000CA008F7E8093CA008091CA00877F809366 |
:10728000CA008091C9008B7F8093C9008091CA0099 |
:1072900084608093CA008091CA0082608093CA0093 |
:1072A0008091C80087FF06C08091CE008091C80001 |
:1072B00087FDFACF8091C90080688093C9009FBF85 |
:1072C00008951F920F920FB60F9211248F93809101 |
:1072D000CE008F910F900FBE0F901F901895809148 |
:1072E000AA049091AB04A091AC04B091AD0420919C |
:1072F0002406309125064091260650912706281B2A |
:10730000390B4A0B5B0BB901CA0108958091AA049D |
:107310009091AB04A091AC04B091AD04809324068D |
:1073200090932506A0932606B09327062091AA04E1 |
:107330003091AB044091AC045091AD04821B930B8F |
:10734000A40BB50B8093180690931906A0931A0608 |
:10735000B0931B0610921406109215061092160692 |
:107360001092170610921C0610921D0610921E060F |
:1073700010921F0608958F929F92AF92BF92CF9264 |
:10738000DF92EF92FF920F931F938091AA04909146 |
:10739000AB04A091AC04B091AD044091240650918F |
:1073A00025066091260670912706481B590B6A0B2B |
:1073B0007B0B8091140690911506A0911606B09152 |
:1073C000170684179507A607B70744F440931406D9 |
:1073D00050931506609316067093170680917205F8 |
:1073E00081FF55C08091A60381608093A6038091A0 |
:1073F000B6018852803B08F47EC09091DC0299323D |
:1074000008F05AC0983209F47EC09F5F9093DC0266 |
:107410008091D7028F5F8093D702803309F054C0E8 |
:107420001092D70280917705882E9924AA24BB2434 |
:10743000C0901806D0901906E0901A06F0901B062E |
:10744000950184010C0D1D1D2E1D3F1D80912006F0 |
:1074500090912106A0912206B091230680179107F2 |
:10746000A207B3075CF497018601081919092A09D4 |
:107470003B09081719072A073B0734F10093180640 |
:107480001093190620931A0630931B061DC0809195 |
:10749000A6038E7F8093A6038091B60124E6829F87 |
:1074A000C0011124A0E0B0E0809320069093210653 |
:1074B000A0932206B09323068091D7028F5F80931A |
:1074C000D702803309F4ACCFCB01BA0124E630E017 |
:1074D00040E050E00E94F7403093E5032093E4033E |
:1074E0001F910F91FF90EF90DF90CF90BF90AF90E2 |
:1074F0009F908F9008951092DC028091A7038E7F59 |
:107500008093A703D9CF4093200650932106609320 |
:107510002206709323068091A70381608093A703BE |
:1075200074CFCF92DF92EF92FF920F931F93CF937E |
:10753000DF936C018091AA049091AB04A091AC04FC |
:10754000B091AD0420912406309125064091260685 |
:1075500050912706281B390B4A0B5B0BE09018064D |
:10756000F090190600911A0610911B068091D8021E |
:107570009091D902E901C81BD90B2093D80230930E |
:10758000D9024093DA025093DB021C161D060CF060 |
:10759000BEC08091A60382608093A6038091A7035A |
:1075A0008D7F8093A703E21AF30A040B150B209139 |
:1075B000760530E040E050E0C801B7010E9483400A |
:1075C00028EE33E040E050E00E94F74080917405DF |
:1075D00090E0BC01C69FC001C79F900DD69F900D43 |
:1075E0001124281B390B80917305482F50E0421756 |
:1075F00053074CF088279927841B950BA90128175E |
:1076000039070CF466C08091720580FF04C081FDCB |
:1076100075C0C40ED51E7E010027F7FC0095102F03 |
:107620006091D1027091D2028091D3029091D402E4 |
:1076300028E130E040E050E00E948340E60EF71E73 |
:10764000081F191FC801B70129E130E040E050E0F0 |
:107650000E94F74079018A01E092D102F092D202B1 |
:107660000093D3021093D4022091B3013091B4015E |
:10767000C901880F991F820F931F880F991F880FC8 |
:10768000991F880F991F8C0D9D1D69E170E00E9464 |
:10769000AE406093B3017093B401809188029091E1 |
:1076A0008902885E934030F083E0E816F10401051A |
:1076B00011058CF08091A6038B7F8093A603C601F1 |
:1076C000DF91CF911F910F91FF90EF90DF90CF90BE |
:1076D0000895AC0198CF2EEFE2162FEFF2062FEFB0 |
:1076E00002072FEF120734F36093D5027093D6028E |
:1076F0008091A60384608093A603E1CF8091B601B8 |
:107700008852803B08F487CFC40ED51E84CF2097C3 |
:1077100009F449CF8091A70382608093A7038091E9 |
:10772000A6038D7F8093A6033ECFCF93DF93E09196 |
:107730007505EF3F59F0EB3F08F4ACC1F0E0EE0FF8 |
:10774000FF1FE951FF4F80818093B601E0917405DE |
:10775000EF3F59F0EB3F08F49AC1F0E0EE0FFF1F46 |
:10776000E951FF4F80818093B5018091B501882355 |
:1077700009F04AC11092B501E0917605EF3F59F04A |
:10778000EB3F08F481C1F0E0EE0FFF1FE951FF4F1E |
:1077900080818093B7018091B701882309F02DC1C2 |
:1077A0001092B701E0917805EF3F59F0EB3F08F4F4 |
:1077B00068C1F0E0EE0FFF1FE951FF4F8081809319 |
:1077C000B801E0917F05EF3F59F0EB3F08F456C157 |
:1077D000F0E0EE0FFF1FE951FF4F80818093B90168 |
:1077E000E0918005EF3F59F0EB3F08F444C1F0E031 |
:1077F000EE0FFF1FE951FF4F80818093BB01809105 |
:10780000BB018B3008F0F3C08AE08093BB01E091AC |
:107810008105EF3F59F0EB3F08F42AC1F0E0EE0F8D |
:10782000FF1FE951FF4F80818093BC01E0918205E9 |
:10783000EF3F59F0EB3F08F418C1F0E0EE0FFF1FE7 |
:10784000E951FF4F80818093BA01E0918705EF3FB6 |
:1078500059F0EB3F08F406C1F0E0EE0FFF1FE951CD |
:10786000FF4F80818093BE01A8E8B5E0CFEBD1E067 |
:10787000EC91EF3F51F0EB3F08F4B7C0F0E0EE0FB2 |
:10788000FF1FE951FF4F808188831196219685E083 |
:10789000AC38B80769F75096C3ECD1E0EC91EF3FF4 |
:1078A00051F0EB3F08F49FC0F0E0EE0FFF1FE951ED |
:1078B000FF4F808188831196219685E0A03AB80712 |
:1078C00069F7E0918C05EF3F59F0EB3F08F4C7C032 |
:1078D000F0E0EE0FFF1FE951FF4F80818093C70159 |
:1078E000E0919105EF3F59F0EB3F08F4B5C0F0E0AF |
:1078F000EE0FFF1FE951FF4F80818093C801E09197 |
:107900009405EF3F59F0EB3F08F4A3C0F0E0EE0F11 |
:10791000FF1FE951FF4F80818093C901E0919505D8 |
:10792000EF3F59F0EB3F08F491C0F0E0EE0FFF1F7E |
:10793000E951FF4F80818093CA01E0919605EF3FA6 |
:1079400059F0EB3F08F47FC0F0E0EE0FFF1FE95164 |
:10795000FF4F80818093CB01E0919B05EF3F59F071 |
:10796000EB3F08F46DC0F0E0EE0FFF1FE951FF4F51 |
:1079700080818093CC01E091A105EF3F59F0EB3F6E |
:1079800008F453C0F0E0EE0FFF1FE951FF4F808174 |
:107990008093CE018091CE01823008F44DC08F3F9C |
:1079A00009F486C0E091A305EF3F51F0EB3F98F159 |
:1079B000F0E0EE0FFF1FE951FF4F80818093CF0170 |
:1079C0008091CF01823068F18F3F09F474C0E0915B |
:1079D000B405EF3F29F0EB3F08F05FC0E093CD0125 |
:1079E000DF91CF910895E88366CFE8834ECF8F3F34 |
:1079F00009F00DCF8093BB010ACF843608F4D2CEB4 |
:107A000084E68093B701CECE843608F4B5CE84E602 |
:107A10008093B501B1CEE093CF018091CF01823048 |
:107A200098F681E08093CF01D2CFE093CE01809190 |
:107A3000CE01823008F0B3CF81E08093CE01B2CF87 |
:107A4000E093CC0198CFE093CB0186CFE093CA01BD |
:107A500074CFE093C90162CFE093C80150CFE093A7 |
:107A6000C7013ECFE093BE01FFCEE093BA01EDCE59 |
:107A7000E093BC01DBCEE093BB01C1CEE093B90142 |
:107A8000AFCEE093B8019DCEE093B70184CEE093F2 |
:107A9000B5016BCEE093B60159CEF0E0EE0FFF1FBB |
:107AA000E951FF4F80818093CD01DF91CF910895FF |
:107AB0008093CE0177CF8093CF0189CF962F8B3FD4 |
:107AC00038F4682F691768F0461770F0862F08950C |
:107AD000E82FF0E0EE0FFF1FE951FF4F60816917BB |
:107AE00098F7692F862F0895642F862F0895CF93D6 |
:107AF000DF93ADEDB1E06DE570E08C9190E0869F95 |
:107B0000F001879FF00D969FF00D1124E659FA4F72 |
:107B1000408111968C9111974F3FE9F04B3F38F01F |
:107B2000E42FF0E0EE0FFF1FE951FF4F408190E09E |
:107B3000FC01EE0FFF1FEE0FFF1FEE0FFF1F9F0157 |
:107B4000220F331F220F331FE20FF31FE81BF90B25 |
:107B5000EB54FE4F4083129682E0A730B80769F6D7 |
:107B6000C7E0D2E099976DE570E0888190E0869F4C |
:107B7000F001879FF00D969FF00D1124E659FA4F02 |
:107B8000E0818C91EF3F21F14A819B81EB3F30F006 |
:107B9000F0E0EE0FFF1FE951FF4FE081E41720F006 |
:107BA0004E2F9E1708F4492F90E0FC01EE0FFF1FA7 |
:107BB000EE0FFF1FEE0FFF1F9F01220F331F220F3B |
:107BC000331FE20FF31FE81BF90BEB54FE4F40830A |
:107BD0002496129682E0CF31D80739F6A0E5B0E1BD |
:107BE000CBE3D3E0EC91EF3F49F0EB3F30F0F0E036 |
:107BF000EE0FFF1FE951FF4FE081E883A35ABF4F0B |
:107C0000A79681E1A43CB80769F7A4E9B7E1C7EDFD |
:107C1000D3E0EC91EF3F49F0EB3F30F0F0E0EE0FB6 |
:107C2000FF1FE951FF4FE081E883A35ABF4FA7969A |
:107C300089E1A830B80769F7DF91CF910895809165 |
:107C4000C800803219F090E0892F08958091CA0011 |
:107C500090E08630C9F791E0892F089585B18C7F37 |
:107C600085B9209888EE93E00197F1F783B190E011 |
:107C70008370907081309105A9F08230910569F090 |
:107C8000892BB1F484B1836084B98AE0289A8C305E |
:107C900010F0299A08952998089584B1836084B9D1 |
:107CA00084E1F4CF84B1836084B98BE02898EFCF6E |
:107CB00084B1836084B98DE02898E9CF909357020E |
:107CC00080935602089580910401909105018F5F81 |
:107CD0009F4F09F0089588E99AE3909357028093A3 |
:107CE000560280E09CE09093050180930401089582 |
:107CF00080910401909105018F5F9F4F09F00895D5 |
:107D000080918A0280FFFBCF80E197E29093570237 |
:107D10008093560280E890E09093050180930401DF |
:107D2000089580E093E09093050180930401809191 |
:107D3000560290915702892B31F480E797E1909396 |
:107D4000570280935602089587E090E090930501D2 |
:107D5000809304018091560290915702892B31F44F |
:107D600080E797E1909357028093560208951F93FE |
:107D7000CF93DF93982F8823C1F080918A0280FDF2 |
:107D800014C0192F1150C4E6D0E005C080918A02BA |
:107D9000115080FD0AC0D0935702C09356028AEF5B |
:107DA00090E00E940313112389F7DF91CF911F9177 |
:107DB0000895DF92EF92FF920F931F93CF93DF937B |
:107DC000EC0160914E0570914F05809150059091A6 |
:107DD00051050E94D8227C01609152057091530593 |
:107DE00080915405909155050E94D822AA2797FDAD |
:107DF000A095BA2F0027F7FC0095102FBC01CD01EC |
:107E0000A80197010E948340D090C1019B01AC0161 |
:107E10002030E0E03E07E0E84E07E0E05E0778F162 |
:107E20002150304040485F4F2F5F3F4F4F475040F9 |
:107E300030F1ED2CFF2400E010E01E2D0027FF2480 |
:107E4000EE242AE030E040E050E00E94F740C80114 |
:107E5000B7010E94F7408D2D90E0BC01660F771F9F |
:107E6000660F771F660F771F880F991F680F791F9E |
:107E700088279927861B970B820F931F02C080E0EB |
:107E800090E09C012C0F3D1FC901DF91CF911F9104 |
:107E90000F91FF90EF90DF9008950F931F930E9432 |
:107EA0009420182F0E949720082F0E949120982F2D |
:107EB00080918A0280FD05C0123021F1143009F44E |
:107EC0003FC0163089F0183019F01F910F910895B6 |
:107ED000109289021092880280918A028E7F80938C |
:107EE0008A021F910F91089581E090E0909389029A |
:107EF0008093880280918A02896080938A021F9110 |
:107F00000F910895002309F78091DC018C3010F166 |
:107F1000299A963018F5892F8150853078F10E9482 |
:107F20001A370E94BF370E9462300E9445360E9475 |
:107F300002220E941A370E94B73E1F910F910895A6 |
:107F4000002319F68091DC018C3030F0299A0E94D0 |
:107F50005218E9CF2998DDCF2998F9CF8091720581 |
:107F6000887209F4B2CF973009F0AFCF81E08093E7 |
:107F70009D0288EE93E00E945E3EA7CF892F0E946B |
:107F80000937CDCF83E08093820581E080937E0521 |
:107F90008AE080939A0585E58093970580939805FC |
:107FA0000895559B02C05D9906C05D9A559A84E676 |
:107FB00090E00E9403135D9881E090E00E9403131B |
:107FC0005D9A84E690E00E94181308953C98449AC4 |
:107FD0001092290210922E0681E080932F060895B8 |
:107FE0008091EE029091EF0201969093EF028093C0 |
:107FF000EE0201978858934109F475C0349B12C072 |
:108000008091F2029091F30201969093F302809393 |
:10801000F2028159914008F052C020912902222396 |
:1080200089F108956091F2027091F302CB010197FA |
:108030008956914010F56A30710508F45FC06A50A6 |
:10804000704080E090E029E134E040E050E00E94A0 |
:1080500083402AE096958795779567952A95D1F77D |
:1080600070938801609387018091A70390E489272A |
:108070008093A7038CE0809329021092F302109260 |
:10808000F202CBCF8091F0029091F1020E94F9129E |
:10809000882339F28091560290915702892B31F44E |
:1080A00084E690E0909357028093560284E690E035 |
:1080B0000E94EF129093F1028093F00208952091B4 |
:1080C0002902222329F0822F815080932902282F10 |
:1080D0008FEF9FEF90938801809387011092F302B6 |
:1080E0001092F2029CCF8091A60390E4892780939E |
:1080F000A6031092EF021092EE0280CF1092880138 |
:1081000010928701B7CF629FD001739FF001829FC9 |
:10811000E00DF11D649FE00DF11D929FF00D839F16 |
:10812000F00D749FF00D659FF00D9927729FB00DB3 |
:10813000E11DF91F639FB00DE11DF91FBD01CF01C6 |
:1081400011240895991B79E004C0991F961708F02F |
:10815000961B881F7A95C9F780950895AA1BBB1BAB |
:1081600051E107C0AA1FBB1FA617B70710F0A61B37 |
:10817000B70B881F991F5A95A9F780959095BC0158 |
:10818000CD01089597FB092E07260AD077FD04D06C |
:10819000E5DF06D000201AF4709561957F4F0895B1 |
:1081A000F6F7909581959F4F0895A1E21A2EAA1B8C |
:1081B000BB1BFD010DC0AA1FBB1FEE1FFF1FA21797 |
:1081C000B307E407F50720F0A21BB30BE40BF50B94 |
:1081D000661F771F881F991F1A9469F7609570951D |
:1081E000809590959B01AC01BD01CF01089597FB4F |
:1081F000092E05260ED057FD04D0D7DF0AD0001C6B |
:1082000038F450954095309521953F4F4F4F5F4F33 |
:108210000895F6F790958095709561957F4F8F4FF3 |
:108220009F4F0895FB01DC0102C005900D92415063 |
:108230005040D8F70895FC014150504030F0019073 |
:108240000616D1F73197CF01089588279927089509 |
:10825000DC01CB01FC01F999FECF06C0F2BDE1BD06 |
:10826000F89A319600B40D9241505040B8F70895F5 |
:10827000F999FECF92BD81BDF89A992780B50895EE |
:10828000A8E1B0E042E050E00C942A41DC01CB01CF |
:1082900003C02D910E94514141505040D0F70895A4 |
:1082A000262FF999FECF1FBA92BD81BD20BD0FB612 |
:1082B000F894FA9AF99A0FBE019608950E945041D7 |
:0A82C000272F0C945141F894FFCFD2 |
:1082CA00FF01F401FFFF0100080008000400040098 |
:1082DA000400026A640001000000000000000000BF |
:1082EA00000000000000000000000000000000196B |
:1082FA0000020D48656C6C6F20576F726C64000049 |
:10830A000000000000000000000000000000000063 |
:10831A000000000000000000000000000000000053 |
:10832A000000000000000000000000000000000043 |
:10833A000000000000000000000000000000000033 |
:10834A0000000064000101FFFFFFFFF40100013893 |
:10835A00010151756164726F0000426567696E6E52 |
:10836A00657200004E6F726D616C000053706F721F |
:10837A00740000320030FB103A40089696020A0058 |
:10838A000000000000000064465A414064000000FA |
:10839A000000000000000000000000000D0B010EAC |
:1083AA00031504170718051D09221227132A142B6F |
:1083BA00152C1631173A1B3B1C3C1D3D1E3E1F4215 |
:1083CA0020452246234A180A0000640C000096162B |
:1083DA000600FF371901FF391A01FF47210AFF007A |
:0A83EA000080000000000000010CFC |
:00000001FF |
/branches/dongfang_FC_rewrite/Flight-Ctrl_MEGA644p_NAVICTRL__ADXRS610_FC2.0_V0_74df_SVN0001.hex |
---|
0,0 → 1,2150 |
:100000000C943B040C9458040C9458040C9458041D |
:100010000C9458040C9458040C9458040C945804F0 |
:100020000C9458040C9400130C9458040C94580429 |
:100030000C9409250C9458040C9458040C945804FE |
:100040000C9458040C9458040C941D120C945804ED |
:100050000C948C060C9458040C9455060C9458047B |
:100060000C9458130C9458040C949B220C94580430 |
:100070000C942C380C9458040C9458040A0A0D0063 |
:100080004E65757472616C20284143432D4D6F6439 |
:1000900065290048656164696E67486F6C64000A91 |
:1000A0000D436F6E74726F6C3A20000A0D537570B9 |
:1000B000706F727420666F72204E6176694374723D |
:1000C0006C000A0D3D3D3D3D3D3D3D3D3D3D3D3DD1 |
:1000D0003D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D50 |
:1000E0003D3D3D3D3D3D3D000A0D3D3D3D3D3D3DE0 |
:1000F0003D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D30 |
:100100003D3D3D3D3D3D3D3D3D3D3D3D3D000A0DBF |
:10011000536F6674776172653A205625642E2564A4 |
:1001200025630070000D0A20202020204350553AFE |
:100130002041746D656761363434000A0D48617280 |
:1001400064776172653A20437573746F6D000A0DB0 |
:10015000466C69676874436F6E74726F6C000A0D49 |
:100160003D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3DBF |
:100170003D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3DAF |
:100180003D3D3D00416E676C655069746368202099 |
:1001900020202020416E676C65526F6C6C202020FF |
:1001A00020202020416E676C655961772020202037 |
:1001B000202020204779726F506974636828504965 |
:1001C000442920204779726F526F6C6C2850494443 |
:1001D000292020204779726F596177202020202024 |
:1001E000202020204779726F50697463682841434A |
:1001F000292020204779726F526F6C6C2841432967 |
:10020000202020204779726F5961772841432920A7 |
:100210002020202041636350697463682028616E48 |
:10022000676C6529416363526F6C6C2028616E674F |
:100230006C65292055426174202020202020202038 |
:10024000202020205069746368205465726D20203E |
:1002500020202020526F6C6C205465726D2020206D |
:1002600020202020596177205465726D20202020A5 |
:10027000202020205468726F74746C65205465725D |
:100280006D202020307468204F20436F72722070E0 |
:1002900069746368307468204F20436F72722072F3 |
:1002A0006F6C6C204472696674436F6D7044656C4A |
:1002B000746120504472696674436F6D7044656C5C |
:1002C00074612052414450697463684779726F4F7A |
:1002D000666673204144526F6C6C4779726F4F664B |
:1002E000667320204D312020202020202020202037 |
:1002F000202020204D3220202020202020202020BF |
:10030000202020204D3320202020202020202020AD |
:10031000202020204D34202020202020202020209C |
:1003200020202020436F6E74726F6C5961772020FB |
:100330002020202041697270726573732E205261F3 |
:100340006E6765204472696674436F6D705069749E |
:10035000636820204472696674436F6D70526F6CDD |
:100360006C202020416972707265737346696C74E9 |
:1003700065726564416972707265737341444320AC |
:1003800020202020020100070603020105020100CF |
:100390000706030201043132003131003130002000 |
:1003A00025632020202D2020202D2020202D2000FE |
:1003B0002025632020202563202020256320202065 |
:1003C0002563200020256320202025632020202570 |
:1003D0006320202025632000424C2D4374726C2042 |
:1003E000666F756E642000202533642020253364F9 |
:1003F0002020253364202025336420002025336409 |
:1004000020202533642020253364202025336420D8 |
:1004100000202533642020253364202025336420E8 |
:10042000202533642000424C2D4374726C204572A9 |
:10043000726F7273200048693A2534692020436640 |
:100440003A253469200047733A25346920205961E0 |
:100450003A25346920004E693A2534692020526FCC |
:100460003A253469200045787465726E436F6E7466 |
:10047000726F6C202000506F343A20253369205071 |
:100480006F383A2025336900506F333A202533699D |
:1004900020506F373A2025336900506F323A2025BB |
:1004A000336920506F363A2025336900506F313A56 |
:1004B0002025336920506F353A20253369004F6677 |
:1004C00066436F757273653A20253569004865612A |
:1004D00064696E673A20202025356900436F757284 |
:1004E00073653A2020202025356900436F6D7061C7 |
:1004F0007373202020202020200052432D4C65764D |
:10050000656C3A2025356900566F6C746167653AF1 |
:1005100020202533692E253169560050333A253481 |
:1005200069202050343A253469200050313A25346E |
:1005300069202050323A253469200047733A253427 |
:1005400069202059613A25346920004E693A2534E2 |
:10055000692020526F3A253469200043373A253408 |
:1005600069202043383A253469200043353A253440 |
:1005700069202043363A253469200043333A253434 |
:1005800069202043343A253469200043313A253428 |
:1005900069202043323A2534692000486561646946 |
:1005A0006E673A20202025356900526F6C6C3A2026 |
:1005B0002020202020253569004E69636B3A2020D9 |
:1005C00020202020253569004174746974756465A4 |
:1005D0000028632920486F6C676572204275737329 |
:1005E000004D697373696E6720424C2D4374726CC1 |
:1005F0003A256400493243204572726F72212121ED |
:100600000053657474696E673A2025642025730071 |
:1006100048573A5625642E25642053573A25642EB0 |
:1006200025642563002B204D696B726F4B6F7074CE |
:100630006572202B005B25695D005B25695D00000C |
:100640000047008F00D6001E016501AC01F3013A9E |
:10065000028102C7020E0354039903DF03240469D5 |
:1006600004AE04F20436057905BC05FE0540068299 |
:1006700006C306040744078307C20700083E087B39 |
:1006800008B708F2082D096809A109DA09120A4910 |
:100690000A7F0AB50AE90A1D0B500B820BB40BE462 |
:1006A0000B130C420C6F0C9C0CC70CF20C1B0D4472 |
:1006B0000D6B0D920DB70DDB0DFE0D210E420E617F |
:1006C0000E800E9E0EBA0ED60EF00E090F210F38B8 |
:1006D0000F4D0F610F740F860F970FA60FB50FC246 |
:1006E0000FCE0FD80FE10FEA0FF00FF60FFA0FFE43 |
:1006F0000FFF0F0010000047008F00D7001E01669B |
:1007000001AF01F70140028902D2021C036703B264 |
:1007100003FD034A049704E40433058205D305244A |
:10072000067706CB0620077607CE0727088208DE65 |
:10073000083D099D09FF09640ACB0A340BA00B0F81 |
:100740000C800CF50C6D0DE90D680EEC0E730F00AE |
:100750001092102811C51168121113C2137B143C9A |
:10076000150616DA16B917A3189B19A11AB61BDDC0 |
:100770001C171E671FCE205022F023B2259A27AEE9 |
:1007800029F62B782E3E315534CC37B63B2C404ED3 |
:1007900045464B5052BE5A0565D971FF7FFF7FFF1A |
:1007A0007FFF7FFF7FFF7FFF7FFF7F0A0D0A0D2105 |
:1007B00021204D495353494E4720424C2D4354521A |
:1007C0004C3A20256420212100256420000A0D4692 |
:1007D0006F756E6420424C2D4374726C3A20000A8F |
:1007E0000D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D69 |
:1007F0003D3D3D3D3D3D3D3D3D3D3D3D3D3D3D0066 |
:100800000A0D4D697865722D436F6E6669673A20EF |
:100810002725732720282575204D6F746F72732943 |
:10082000000A0D47656E65726174696E67206465C4 |
:100830006661756C74204D69786572205461626CD4 |
:1008400065000A0D5573696E6720506172616D65B0 |
:1008500074657220536574202564000A0D496E6921 |
:100860007420506172616D6574657220696E2045F7 |
:100870004550524F4D0011241FBECFEFD0E1DEBFD7 |
:10088000CDBF12E0A0E0B1E0ECE1F5E802C00590D8 |
:100890000D92A033B107D9F716E0A0E3B2E001C092 |
:1008A0001D92AF38B107E1F70E945A040C948C42B4 |
:1008B0000C940000EF92FF921F93CF93DF93F89474 |
:1008C0000E94EA3C8093F7020E94F93C982F8093A3 |
:1008D000DC0184B7877F84BF80916000886180934A |
:1008E0006000109260009A3009F4B0C1943109F4AC |
:1008F000ADC1289A0E94111F0E94EF110E94D012D0 |
:100900000E94E0078091F702813009F4A1C10E94A2 |
:10091000D5240E940A130E9436220E949F3E78949A |
:1009200000D00F92ADB7BEB711961C9211978EE50D |
:1009300091E013969C938E9312970E94B70EEDB799 |
:10094000FEB711828EE491E0938382830E94B70EFA |
:10095000ADB7BEB711961C9211978BE391E0139639 |
:100960009C938E9312970E94B70EEDB7FEB711823B |
:1009700085E291E0938382830E94B70E0F900F90DF |
:100980000F908091F702813009F47CC1EDB7FEB77A |
:1009900039970FB6F894FEBF0FBEEDBF3196ADB7D5 |
:1009A000BEB711961C928EE091E0928381831482EF |
:1009B00013828AE490E09683858385EC90E09087AB |
:1009C00087830E94B70EEDB7FEB736960FB6F89440 |
:1009D000FEBF0FBEEDBF118288EE90E0938382834D |
:1009E0000E94B70E0F900F900F900E94FE3688EC79 |
:1009F00090E00E948612EC01429A8091DC018C30DA |
:100A000008F03EC129988A3009F41EC1843109F4E6 |
:100A10001BC12898CE010E9490128823D9F388EC3C |
:100A200090E00E948612EC014298439A8091DC018A |
:100A30008A3009F407C1843109F404C1289A8C3042 |
:100A400008F01CC1299ACE010E9490128823D9F384 |
:100A500088EC90E00E948612EC01CE010E94901278 |
:100A60008823D9F343980E94272400D00F92ADB772 |
:100A7000BEB711961C92119782EC90E013969C934E |
:100A80008E9312970E94B70EEDB7FEB711828BEAD4 |
:100A900090E0938382830E94B70E0F900F900F9087 |
:100AA0000E9405210E94342F0E94F8120E941035E6 |
:100AB00080ED97E00E94293D00D00F92ADB7BEB700 |
:100AC00011961C9211978FE990E013969C938E9348 |
:100AD00012970E94B70E80917D050F900F900F9096 |
:100AE00082FFB9C000D00F92EDB7FEB7118283E943 |
:100AF00090E0938382830E94B70E0F900F900F9027 |
:100B000000D00F92EDB7FEB711828CE790E093838F |
:100B100082830E94B70E0F900F900F900E942019B1 |
:100B200088E893E1909384018093830114E085E049 |
:100B3000E82EF12C80915902882321F08091160132 |
:100B4000882371F480915E028823A1F70E94D33E2E |
:100B5000809159028823B1F380911601882391F383 |
:100B6000109259025C9A0E94F82F5C982091DC0147 |
:100B70002A3009F45EC0243109F45BC0289A8091C0 |
:100B80008301909184010197909384018093830164 |
:100B90008091830190918401892BC9F18091960203 |
:100BA0008823A9F52A3009F448C0243109F445C046 |
:100BB000289A80915902882321F08091910280FD2A |
:100BC00002C00E9466090E94460CCE010E9490124B |
:100BD0008823D1F0809114019091150118161906FF |
:100BE00054F4209114013091150180918E0590E00C |
:100BF0002817390724F10E94714110935E0284E1A5 |
:100C000090E00E948612EC010E94911F9BCF2A3037 |
:100C100091F0243181F02898809183019091840192 |
:100C2000892B39F60E947222F0928401E0928301AE |
:100C3000C0CF2898A4CF289AEFCF2898BACF0E9487 |
:100C40005C3DD9CF2898FBCE289AE4CE289852CE86 |
:100C50000E94D1375CCE00D00F92ADB7BEB71196CF |
:100C60001C92119780E890E013969C938E931297B4 |
:100C70000E94B70E0F900F900F9042CF2998E3CEAD |
:100C8000299AC1CE00D00F92ADB7BEB711961C9273 |
:100C9000119783E291E013969C938E9312970E9492 |
:100CA000B70E0F900F900F9071CE1F920F920FB64C |
:100CB0000F9211248F939F93EF93FF9380910101E3 |
:100CC0008823A9F480915502909156020196909341 |
:100CD000560280935502FC01ED50FC4FE081ED304F |
:100CE00099F08639910581F0E093C60004C0109216 |
:100CF000560210925502FF91EF919F918F910F90A4 |
:100D00000FBE0F901F901895109256021092550228 |
:100D100081E080930101E8CF1F920F920FB60F92EE |
:100D200011242F933F934F935F936F938F939F93D0 |
:100D3000AF93BF93CF93DF93EF93FF936091C60080 |
:100D400080913A02882351F4309152023323C1F04A |
:100D50003639C8F01092520210923A02FF91EF9188 |
:100D6000DF91CF91BF91AF919F918F916F915F91E3 |
:100D70004F913F912F910F900FBE0F901F9018959C |
:100D8000633209F43FC06D3099F0E32FF0E0EF5F7C |
:100D9000FC4F60833F5F30935202809153029091E9 |
:100DA0005402860F911D9093540280935302D6CF24 |
:100DB000A32FB0E0FD01E150FD4F9081ED01C05047 |
:100DC000DD4F88814091530250915402491B5109D3 |
:100DD000481B51095F705093540240935302208185 |
:100DE000CA010024880F991F001C880F991F001C3E |
:100DF000892F902D835C281789F010923A02109267 |
:100E00005202ACCF6093010381E08093520283E2EF |
:100E100090E09093540280935302A0CF9881842F46 |
:100E20008F73835C981749F7AF5FBC4F6C933F5F3C |
:100E300030933B0281E080933A0280910303823534 |
:100E4000F1F62CE088E190E00FB6F894A895809335 |
:100E500060000FBE20936000D2CFCF93DF93BC0120 |
:100E60000097A9F140E050E020E030E0FA01ED50B9 |
:100E7000FC4F8081280F311D4F5F5F4F461757078A |
:100E8000A8F33F70C9010024880F991F001C880F28 |
:100E9000991F001C892F902D835CDB0111962F7305 |
:100EA000235CED012196FB01ED50FC4F8083AD509A |
:100EB000BC4F2C93CD50DC4F8DE088831092010104 |
:100EC0008091F3038093C600DF91CF910895E0E015 |
:100ED000F0E08DE3A1E0B0E02DE3C2E0D0E0E4CFAC |
:100EE00050913B02565009F457C033E043E01EC016 |
:100EF000972F9D53F0E02295207F892F8695869528 |
:100F0000282BEF5FFC4F2083E42FEE5F5230C1F1BE |
:100F10005350F0E09295990F990F907C6D53962B5A |
:100F2000EF5FFC4F90834D5F5523A1F1E32FF0E07D |
:100F3000EF5FFC4F80813F5FE32FF0E0EF5FFC4FFE |
:100F400020812D533F5FE32FF0E0EF5FFC4F708176 |
:100F50003F5FE32FF0E0EF5FFC4F60813F5F922F38 |
:100F600092959F708D53880F880F892BE42FF0E0A6 |
:100F7000EF5FFC4F8083E42FEF5F513009F0B8CF73 |
:100F8000E35084E093E090933D0280933C02E09331 |
:100F90003E020895E42FF4CFE0E0F3CF1F93182F23 |
:100FA0008A3051F08091C00085FFFCCF1093C600BD |
:100FB00080E090E01F9108958DE00E94CE07F2CF6F |
:100FC0001F931FB7F8948091C1008F778093C10061 |
:100FD0008091C1008F7B8093C100589A5098599A94 |
:100FE000519A1092C5008AE28093C4008091C0009B |
:100FF00082608093C00088E18093C1008091C2002C |
:101000008F778093C2008091C2008F7B8093C20053 |
:101010008091C2008F7D8093C2008091C2008F7E3C |
:101020008093C2008091C200877F8093C20080912C |
:10103000C1008B7F8093C1008091C2008460809347 |
:10104000C2008091C20082608093C2008091C00083 |
:1010500087FF06C08091C6008091C00087FDFACF4F |
:101060008091C10080688093C1008091C10080643C |
:101070008093C10080910201909103010E94861229 |
:1010800090938A048093890410923A0210923D0250 |
:1010900010923C0210923E0291E090930101109256 |
:1010A000A7038AE48093A80384E68093AB038AE0D5 |
:1010B0008093A9039093AA031FBF1F910895BF9225 |
:1010C000CF92DF92EF92FF920F931F93DF93CF9314 |
:1010D000CDB7DEB78D852E8593E29093F3038F59BC |
:1010E0008093F4038C858093F503222379F463E0E5 |
:1010F00070E0CB010E942D07CF91DF911F910F91DE |
:10110000FF90EF90DF90CF90BF900895EF84F88824 |
:1011100003E1C02ED12CCC0EDD1E49895A89411520 |
:10112000510529F3022F015063E070E010E062C026 |
:10113000A12FB0E01F5FFA01AE0DBF1D8C91AF0172 |
:101140004150504009F48BC0E12FF0E01F5FEE0DDD |
:10115000FF1DA0814150504009F06DC0002309F4EB |
:101160006AC096012E5F3F4FF601E080F18012E0E9 |
:10117000C12ED12CC20ED31EF901408151810150E4 |
:10118000382F32953F7090E08F7090702A2F229503 |
:10119000269526952370880F991F880F991F282B55 |
:1011A000235CAF73A35C10E08B2D86958695835CE2 |
:1011B000FB01ED50FC4F80838B2D90E0837090708D |
:1011C00082959295907F9827807F9827382B335C63 |
:1011D000FB01EC50FC4F3083FB01EB50FC4F2083B4 |
:1011E000FB01EA50FC4FA0836C5F7F4F4115510516 |
:1011F00009F47FCFF701E10FF11DB0801F5F41506F |
:10120000504009F095CF002391F0F6013296D601B7 |
:10121000ED90FC9012E0C12ED12CCE0EDF1E01907D |
:10122000F081E02D0150309709F04CC010E030E023 |
:101230002DE3ADE3B9CF382F32953F7090E08F703A |
:1012400090702A2F2295269526952370880F991F36 |
:10125000880F991F282B235CAF73A35CA5CF0023B5 |
:1012600071F4382F32953F7090E08F709070880F36 |
:10127000991F880F991F282F235CADE395CFF601A6 |
:101280003296D601ED90FC90A2E0CA2ED12CCE0E63 |
:10129000DF1E4081518101504115510521F0E0E0F0 |
:1012A000F0E011E054CF382F32953F7090E08F700E |
:1012B0009070880F991F880F991F282F235C10E0CA |
:1012C000ADE372CFA0E0B0E011E036CF0F931F93F3 |
:1012D000DF93CF93CDB7DEB760970FB6F894DEBF3C |
:1012E0000FBECDBF80910101882309F4ADC080916C |
:1012F0003002882329F080910101882309F021C15F |
:1013000080913202882329F080910101882309F01D |
:1013100042C180913302882329F080910101882302 |
:1013200009F07CC1609100016F3F09F441C070E099 |
:1013300062957295707F7627607F76276C577E4F17 |
:101340008E010F5F1F4FC80140E150E00E943B42F9 |
:101350008DB79EB70B970FB6F8949EBF0FBE8DBF8B |
:10136000EDB7FEB7319681E4ADB7BEB711968C9359 |
:1013700081E0818382E0828380E091E094838383B3 |
:1013800081E090E0968385831087078380E190E079 |
:10139000928781870E945F088FEF809300012DB7AD |
:1013A0003EB7255F3F4F0FB6F8943EBF0FBE2DBF2F |
:1013B00080918B04882329F080910101882309F012 |
:1013C00067C18091020190910301892B09F047C008 |
:1013D00080913402882329F080910101882309F04B |
:1013E00022C28091500290915102892B09F0A2C132 |
:1013F00080913502882329F080910101882309F02A |
:10140000A3C180913102882329F0809101018823B2 |
:1014100009F067C180913702882329F0809101018A |
:10142000882309F079C080913602882329F08091C1 |
:101430000101882309F046C080913802882321F0F9 |
:10144000809101018823A9F460960FB6F894DEBF5D |
:101450000FBECDBFCF91DF911F910F910895809165 |
:10146000890490918A040E949012882309F0B4CFD5 |
:10147000AFCF8DB79EB707970FB6F8949EBF0FBE3C |
:101480008DBFEDB7FEB7319688E5ADB7BEB7119603 |
:101490008C9381E08183828387EE92E094838383BF |
:1014A00080E190E0968385830E945F081092380265 |
:1014B0002DB73EB7295F3F4F0FB6F8943EBF0FBE22 |
:1014C0002DBFC2CF2DB73EB7275030400FB6F8948E |
:1014D0003EBF0FBE2DBFEDB7FEB7319680E5ADB76D |
:1014E000BEB711968C9381E08183828383E295E07D |
:1014F0009483838384E190E0968385830E945F08D0 |
:10150000109236022DB73EB7295F3F4F0FB6F894C1 |
:101510003EBF0FBE2DBF90CF00D00F92EDB7FEB7EC |
:10152000319684E5ADB7BEB711968C9381E0818387 |
:1015300012820E945F08109237020F900F900F9056 |
:1015400072CF2DB73EB7275030400FB6F8943EBF4C |
:101550000FBE2DBFEDB7FEB7319686E5ADB7BEB76E |
:1015600011968C9381E08183828387EA93E0948350 |
:1015700083838AE090E0968385830E945F081092BF |
:1015800030022DB73EB7295F3F4F0FB6F8943EBFEC |
:101590000FBE2DBFB5CE0E9429198DB79EB70B97F0 |
:1015A0000FB6F8949EBF0FBE8DBFEDB7FEB7319654 |
:1015B00088E4ADB7BEB711968C9381E0818382E059 |
:1015C000828389E392E09483838381E090E0968331 |
:1015D00085838091390224E1829FC00111248D5CB2 |
:1015E0009E4F9087878384E190E0928781870E9455 |
:1015F0005F08809139028F5F809339022DB73EB723 |
:10160000255F3F4F0FB6F8943EBF0FBE2DBF84300D |
:1016100010F010923902109232027BCE0E942919EA |
:101620008DB79EB70F970FB6F8949EBF0FBE8DBFB4 |
:10163000EDB7FEB731968CE4ADB7BEB711968C937B |
:1016400081E0818383E082838CE792E094838383CB |
:1016500021E030E03683258382E391E09087878321 |
:101660003287218783E391E09487838780E590E048 |
:10167000968785870E945F08109233022DB73EB788 |
:10168000215F3F4F0FB6F8943EBF0FBE2DBF4ACE2D |
:101690008DB79EB707970FB6F8949EBF0FBE8DBF4C |
:1016A000EDB7FEB7319682E4ADB7BEB711968C9315 |
:1016B00081E0818382838BE894E09483838381E05B |
:1016C00090E0968385830E945F0810928B042DB76B |
:1016D0003EB7295F3F4F0FB6F8943EBF0FBE2DBFF8 |
:1016E00070CE8DB79EB707970FB6F8949EBF0FBE0A |
:1016F0008DBFEDB7FEB7319687E4ADB7BEB7119693 |
:101700008C9381E08183828383EC94E09483838350 |
:101710008BE090E0968385830E945F0810923102EF |
:101720002DB73EB7295F3F4F0FB6F8943EBF0FBEAF |
:101730002DBF70CE8091A5039091A6030E949012B8 |
:10174000882309F059CE54CE8DB79EB707970FB6B0 |
:10175000F8949EBF0FBE8DBFEDB7FEB7319683E400 |
:10176000ADB7BEB711968C9381E08183828387E900 |
:1017700093E0948383838EE090E0968385830E9438 |
:101780005F086091590570915A0580915B059091B1 |
:101790005C0529E830E040E050E00E9420423093B0 |
:1017A00098032093970360915D0570915E05809189 |
:1017B0005F059091600529E830E040E050E00E942C |
:1017C000204230939A0320939903609155057091BC |
:1017D000560580915705909158052AE030E040E089 |
:1017E00050E00E94AC412FEA34E040E050E00E941B |
:1017F000204230939C0320939B032DB73EB7295F73 |
:101800003F4F0FB6F8943EBF0FBE2DBF80915002E0 |
:10181000909151020E9486129093A6038093A50393 |
:1018200010923502EECD8DB79EB707970FB6F8949C |
:101830009EBF0FBE8DBFEDB7FEB7319684E4ADB746 |
:10184000BEB711968C9381E08183828381EB93E014 |
:101850009483838382E490E0968385830E945F086B |
:101860002DB73EB7295F3F4F0FB6F8943EBF0FBE6E |
:101870002DBF80910201909103010E9486129093E6 |
:101880008A048093890410923402ABCD0F931F9386 |
:10189000DF93CF9300D0CDB7DEB780913F0288238E |
:1018A00019F0815080933F0280913A02882339F4E5 |
:1018B0000F900F90CF91DF911F910F9108950E948B |
:1018C0007007809102038236B9F180910303873655 |
:1018D00009F46EC1883680F08C3609F443C18D3628 |
:1018E00008F4C1C0863709F45FC1883709F0BEC06B |
:1018F00081E080933802BAC0823609F45DC1833634 |
:1019000008F4C3C0833609F43BC1843609F0AEC085 |
:10191000E0913C02F0913D0280812AE0829FC0016B |
:1019200011249093030180930201892B09F49EC036 |
:1019300081E0809334029AC080910303803709F4D8 |
:1019400062C1813780F58D3609F4D6C08E3609F034 |
:10195000BCCF809101018823E1F38DB79EB7079733 |
:101960000FB6F8949EBF0FBE8DBFEDB7FEB7319690 |
:101970008EE4ADB7BEB711968C9381E081838283EC |
:1019800082ED95E0948383838DE490E09683858354 |
:101990000E945F08EDB7FEB737960FB6F894FEBF0A |
:1019A0000FBEEDBF92CF833709F481C0843709F4AD |
:1019B0002EC1813709F089CF00913C0210913D0280 |
:1019C000D8018C918F3F09F456C1D8018C9188239E |
:1019D00009F045C181E08C9300913C0210913D02D9 |
:1019E000D8018C910E948A36E0913C02F0913D0230 |
:1019F000E0818BE48A83809101018823E1F3E9830C |
:101A0000EDB7FEB73F970FB6F894FEBF0FBEEDBF20 |
:101A1000319681E5ADB7BEB711968C9381E0818395 |
:101A200083E08283CE0101969483838321E030E0BA |
:101A300036832583CE01029690878783328721875C |
:101A400085E795E0948783878DE590E09687858785 |
:101A50000E945F08EDB7FEB73F960FB6F894FEBF41 |
:101A60000FBEEDBF32CF883609F4B8C010923D02E8 |
:101A700010923C0210923E0210923A020F900F9088 |
:101A8000CF91DF911F910F910895813679F7E09101 |
:101A90003C02F0913D02808180930001803218F079 |
:101AA0008FE1809300018FEF8093CE04DFCF809190 |
:101AB000910280FD0ACF00913C0210913D02D801B5 |
:101AC0008C91882339F08C91863020F411968C917A |
:101AD0008B34A9F11982809101018823E1F38DB73C |
:101AE0009EB707970FB6F8949EBF0FBE8DBFEDB798 |
:101AF000FEB7319683E515C0E0913C02F0913D02BE |
:101B00008081813009F4C2C019828DB79EB70797D2 |
:101B10000FB6F8949EBF0FBE8DBFEDB7FEB73196DE |
:101B20008DE4ADB7BEB711968C9381E0818382833B |
:101B3000CE0101969483838381E090E027CFA5E7CF |
:101B4000B5E0F80132968DE501900D928150E1F7F4 |
:101B5000F80180810E9456360E94E53589830E94F3 |
:101B6000823DB9CF8FEF8093CE04E0913C02F0919B |
:101B70003D02808180937C0281E08093330276CFA6 |
:101B8000E0913C02F0913D0280812AE0829FC001F9 |
:101B900011249093510280935002892B09F466CF4F |
:101BA00081E08093350262CF81E0809330025ECF86 |
:101BB00081E0809331025ACFA3ECB4E080913C02E3 |
:101BC00090913D029C01F9018BE001900D928150B2 |
:101BD000E1F78091CC0480938B0465CF8FEF8093E5 |
:101BE000CE04E0913C02F0913D02808190917D0213 |
:101BF000892B80937D02882311F01092390281E0B5 |
:101C00008093320233CF81E0809336025ECE8091A2 |
:101C10003E02853198F0A0E4B2E080913C029091C0 |
:101C20003D029C01F90180E101900D928150E1F7A4 |
:101C30008FEF80933F028093CE0447CEE0913C0229 |
:101C4000F0913D0280819181A281B3818093400215 |
:101C500090934102A0934202B0934302E9CFF8016E |
:101C60008081863008F4BCCE85E0808300913C0200 |
:101C700010913D02B5CE82E090E00E94CF35F80190 |
:101C8000808300913C0210913D029FCEA2EDB5E011 |
:101C90008DE401900D928150E1F70E942F368091E2 |
:101CA00001018823E1F381E089832FCF982F809170 |
:101CB0008C04813021F0892F0E94CE0708958091F5 |
:101CC0007E02E82FF0E0ED5CFE4F90838F5F809303 |
:101CD0007E0281E008951F93182F181634F480E3D4 |
:101CE0000E94560E11501116D4F31F9108951F93A0 |
:101CF000182F181634F480E20E94560E1150111657 |
:101D0000D4F31F910895EF92FF920F931F93CF93F7 |
:101D1000DF937C018B016115710569F0C0E0D0E0B3 |
:101D2000F701EC0FFD1FE4918E2F0E94560E2196B5 |
:101D3000C017D107A9F7DF91CF911F910F91FF90A5 |
:101D4000EF9008950F931F93CF93DF938C01EB01D6 |
:101D50006115710539F0F80181918F010E94560ECD |
:101D60002197C9F7DF91CF911F910F9108952F927D |
:101D70003F924F925F926F927F928F929F92AF921B |
:101D8000BF92CF92DF92EF92FF920F931F93DF9358 |
:101D9000CF93CDB7DEB7EA970FB6F894DEBF0FBE8C |
:101DA000CDBF61962FAD619762963FAD6297609609 |
:101DB0008FAD609780938C0442E5A42EB12CAC0EBD |
:101DC000BD1EC9018C016624772443019E01245D58 |
:101DD0003F4F3AAF29AFF801F490FF20A9F0F5E2A8 |
:101DE000FF1691F0680103C0F5E2FF1639F0089480 |
:101DF000C11CD11CF601F490FF20B1F7B601601BA5 |
:101E0000710B09F075C08601FF2009F495C20F5FC0 |
:101E10001F4F1982EE24552444244A94F8010F5F81 |
:101E20001F4FF490AE2DB0E0A170B07025E7F21610 |
:101E300009F446C08F2D8062883709F441C06501DE |
:101E4000F0E2FF1609F44DC023E2F21609F495C042 |
:101E50004AE2F41609F495C05DE2F51609F4A0C053 |
:101E6000FBE2FF1609F441C02EE2F21609F444C069 |
:101E7000E0E3FE1609F496C08F2D8153893008F0F7 |
:101E800097C020E030E0C901880F991F880F991F83 |
:101E9000880F991F220F331F280F391F2F0D311D57 |
:101EA00020533040F8010F5F1F4FF4908F2D805367 |
:101EB0008A3048F3522E560125E7F21609F0BACFC0 |
:101EC000109709F445C094E0C92ED12CCA0CDB1C34 |
:101ED000F5016080718082809380F0E2FF1609F046 |
:101EE000B3CF8981882309F046C0F982560196CF85 |
:101EF000C8010E94830E87CFF8010F5F1F4F949196 |
:101F00009A3209F45FC0892F80538A3080F5692F97 |
:101F100020E030E0C901880F991F880F991F880FB2 |
:101F2000991F220F331F280F391F260F311D2053F1 |
:101F30003040F8010F5F1F4F6491862F80538A3025 |
:101F400048F3A90137FD10C0442EF62E5601B4CF38 |
:101F500082E0C82ED12CCA0CDB1CF5018081918156 |
:101F60003C01882499246CCF4FEF5FEFEDCFF92E21 |
:101F700044245601A1CF560151CF38E0E32A56013F |
:101F80004DCFA2E0AA2EB12CAC0CBD1CD6015C90AA |
:101F900057FE44CF5194B0E1EB2AEFEDEE223ECF55 |
:101FA0005601F9CFE4FCE7CFF0E2EF2A560136CF35 |
:101FB00028E6F216B9F04CE6F416C1F451E0E52A31 |
:101FC00056012CCFF2E0AF2EB12CAC0CBD1CD601CB |
:101FD0004D915C9157FD02C0442E20CF4FEF5FEF33 |
:101FE000442E1CCF34E0E32A560118CF8F2DF60182 |
:101FF00093E6F91609F405C1843409F472C08436F5 |
:1020000009F471C0893609F46EC08F3409F47AC1BD |
:102010008F3609F474C1803709F479C1B3E7FB1630 |
:1020200009F430C155E5F51609F4D4C185E7F81671 |
:1020300009F4CCC1E8E5FE1609F4F8C0F8E7FF168C |
:1020400009F4F4C0FF2009F477C1FC8219822E2D17 |
:1020500030E03DAB2CAB5601EE2434E0232E312C86 |
:102060002C0E3D1E81E091E0E0E021E0C22ED12C5B |
:102070002981222381F18F5F482E4E0E8CA99DA9C4 |
:102080008073907098AF8FAB892B29F4852D8419BC |
:102090000E94770E29812223B9F49CA996FD8CC158 |
:1020A000EFA9F8ADB09709F482C18E2D0E946B0E96 |
:1020B000C101B6010E94A20EFCA9F4FF8CCE852DB1 |
:1020C00084190E94770E87CECE01019661E070E000 |
:1020D0000E94A20EE5CF5CA956FFCECF892F8E5F5E |
:1020E000CBCFB1E0EB2AE0FE54C1B4E0AB2EB12C73 |
:1020F000AC0CBD1CF601608071808280938097FCDF |
:102100003BC1BAE0BEAB47FC02C05FEDE5227CE21A |
:10211000272E312C2C0E3D1E611471048104910474 |
:1021200009F452C09EA9892F90E0A0E0B0E088ABEE |
:1021300099ABAAABBBAB6CE2C62ED12CCC0EDD1E8C |
:102140006CA67DA68EA69FA62AC050E3352E360E1D |
:10215000D6013E926D016CA57DA58EA59FA528A9EF |
:1021600039A94AA95BA90E94FE41B901FA01C90136 |
:10217000DA013C014D012CA53DA54EA55FA588A91E |
:1021800099A9AAA9BBA9281739074A075B0708F428 |
:1021900040C0CB01DF018CA79DA7AEA7BFA76CA550 |
:1021A0007DA58EA59FA528A939A94AA95BA90E944A |
:1021B000FE416A3050F247E5342E360E48E5F416FB |
:1021C00039F65FED3522C4CF442089F4AE2DB0E05E |
:1021D000BDABACAB80E090E0442DE42EE91AE7FC07 |
:1021E000C4C0EE2DC82EDD24C7FCD09441CF3EA93B |
:1021F000232F30E040E050E028AB39AB4AAB5BAB7B |
:102200009ACFA2E0B0E0CA0EDB1E80818C831982D7 |
:102210001ECF9EA99830D1F0AE2DB0E0BDABACABD7 |
:10222000B9ADBC198B2F9B2F1601D6CFE3FE1AC078 |
:102230006114710481049104A9F020E4E22A8F2D35 |
:1022400030E13EAB1982F82E56015DCFEE2DF0E065 |
:10225000FDABECABE3FC0AC0F9ADFC198F2F9F2F4F |
:102260001601BACF8F2D40E14EABECCF20E33216F2 |
:1022700009F45CC0F60140E3429389AD8E1B982FB0 |
:102280001F01AACFF601208031802114310489F486 |
:10229000F8E2FC832EE62D8335E73E838CE68F83C0 |
:1022A000888789E289871A86F4E02F2E312C2C0E3C |
:1022B0003D1E47FC1CC0442D552747FD5095C101CC |
:1022C00060E070E00E944442009719F082194816BD |
:1022D0000CF4842DE2E0AE2EB12CAC0CBD1C1982A6 |
:1022E000982F4E2D50E05DAB4CAB40E076CFF10126 |
:1022F00001900020E9F731978E2F8219EBCF28E06B |
:102300002EABA0CF31E0E32A48E04EAB9BCF82E07A |
:1023100090E0C80ED91E808191813C0188249924C7 |
:1023200090E4E92A88E7A0E1AEAB8CCF39AD3C1947 |
:10233000832F932F160150CFEA960FB6F894DEBF85 |
:102340000FBECDBFCF91DF911F910F91FF90EF9006 |
:10235000DF90CF90BF90AF909F908F907F906F90C5 |
:102360005F904F903F902F900895C82EDD24C7FCBA |
:10237000D094EE24E0E07CCE9094809470946094AD |
:10238000611C711C811C911CEDE2E983FAE0FEAB3B |
:10239000BACEA2E0AA2EB12CAC0CBD1CD6018D91F8 |
:1023A0009C913C01882477FC8094982CA8CE852DA4 |
:1023B00084190E946B0E79CEA0E3AA83FB82CE0122 |
:1023C000029662E070E00E94A20E6ACE8F2D9AE023 |
:1023D0009EAB38CFA1E0EA2ABAE0BEAB33CF9FB7BD |
:1023E000F8948091DC018A3029F13F9A479884B1B2 |
:1023F000886184B985B1877E85B984B58F7A84BDBB |
:1024000084B5836A84BD85B5877385BD85B5887FAE |
:10241000826085BD17BC88E788BD16BC80916E00C0 |
:10242000897F80936E0080916E00816080936E0042 |
:102430009FBF0895529A5A98DACF1F920F920FB603 |
:102440000F9211242F933F938F939F9380915E025D |
:10245000882329F080915E02815080935E028091F2 |
:102460005F02815080935F028F5FA1F489E08093C7 |
:102470005F028091060191E08927809306018823FD |
:10248000F1F1809157029091580201969093580271 |
:102490008093570280915C0290915D02892BD9F064 |
:1024A00080915C0290915D02019790935D02809310 |
:1024B0005C0220915C0230915D0280910401909158 |
:1024C000050182239323892B61F08091DC018A30FE |
:1024D000C9F0479A0BC08FEF9FEF9093050180934F |
:1024E00004018091DC018A3079F047989F918F91A7 |
:1024F0003F912F910F900FBE0F901F9018959093C2 |
:102500005902BFCF5A9AF2CF5A98F0CF2091570272 |
:102510003091580221503040280F391FC9010895C9 |
:102520002091570230915802821B930B8070907853 |
:10253000892F089520915702309158022150304040 |
:10254000280F391F8091570290915802A901481B0A |
:10255000590BCA01807090789923A1F308952091B6 |
:1025600057023091580221503040280F391F809176 |
:10257000570290915802A901481B590BCA0180705B |
:102580009078992361F480911601882381F3109249 |
:10259000160180917A00886C80937A00E8CF0895C4 |
:1025A0009FB7F894579A5F983E9A469AA0EBB0E08E |
:1025B0008C918F708C938C9183608C93E1EBF0E025 |
:1025C00080818B73808380818B6080831092B200C6 |
:1025D0008FEF8093B3008C9180688C93E0E7F0E0FC |
:1025E00080818A7F80838081826080839FBF0895FD |
:1025F00081E080936402089510926402469A0895DF |
:102600001F920F920FB60F9211240F900FBE0F90D2 |
:102610001F9018959FB7F89411B812B88FEF809358 |
:102620007E00ECE7F0E080818F7180838081807E86 |
:1026300082608083AAE7B0E087E08C93EBE7F0E06C |
:102640008081887F80838C91886C8C939FBF089554 |
:102650009C01FB018081918182179307ACF0662772 |
:102660007727621B730B80819181861797074CF047 |
:102670008081918150E04817590748F011821082FB |
:102680000895718360830895318320830895808144 |
:102690009181841B950B91838083089547B5209188 |
:1026A0001301249F90011124280F391FC901089597 |
:1026B0001F920F920FB60F9211248F929F92BF928A |
:1026C000CF92DF92EF92FF920F931F932F933F933E |
:1026D0004F935F936F937F938F939F93AF93BF932A |
:1026E000CF93DF93EF93FF93E0913101F0E02091DE |
:1026F000780030917900EE0FFF1FE559FD4F808182 |
:102700009181820F931F9183808360917B02B62E0B |
:10271000B394B0927B026D3009F4B4C16E3008F00E |
:1027200042C06B3009F496C16C3008F462C18091EC |
:102730002602882309F40BC280910D0190910E01AD |
:102740002091790230917A02821B930B90938E0430 |
:1027500080938D0440916502509166028091A80497 |
:1027600020918D0430918E046091A80490E001972F |
:10277000DC01A49FC001A59F900DB49F900D112472 |
:10278000820F931F70E00E94EB417093660260938A |
:10279000650280918D0490918E046EE974E041E0B1 |
:1027A0000E942813AFC0613108F0DCC06F3008F41C |
:1027B00037C16F50C62FD0E0E2E0F0E0EC1BFD0B1C |
:1027C000EE0FFF1FE559FD4F808191816E01CC0C0A |
:1027D000DD1CF601EE55FB4F918380832081318112 |
:1027E00080917D0587FDD5C203E2802E02E0902E08 |
:1027F0008C0E9D1ED4018C91882309F48CC1F601A6 |
:10280000E95FFE4F0190F081E02DE21BF30BEE0F2C |
:10281000FF1FEE0FFF1FAAEBEA2EA4E0FA2EEC0C2E |
:10282000FD1CD7012D913C918091B40490E001975B |
:10283000AC01249FC001259F900D349F900D112461 |
:102840006091B4048E0F9F1F70E00E94EB418B01DA |
:10285000CC0FDD1FCD56DB4FCB01BE0145E00E9402 |
:102860002813F601E656FB4F408151818091B30455 |
:10287000D7012D913C916091B30490E00197DC0168 |
:102880004A9FC0014B9F900D5A9F900D1124821BAF |
:10289000930B800F911F70E00E94EB417183608366 |
:1028A000F70111830083F601EE55FB4F2081318142 |
:1028B000D4018C91882309F421C1F601E95FFE4F10 |
:1028C00040815181421B530B440F551F440F551F2C |
:1028D000F601E755FB4F208131818091B904609169 |
:1028E000B90490E00197DC012A9FC0012B9F900D55 |
:1028F0003A9F900D1124840F951F70E00E94EB41C8 |
:1029000071836083EB2DF0E0EC57FC4FE491E09392 |
:10291000310180917C00807EE82BE0937C00BB201D |
:1029200029F080917A00886C80937A00FF91EF9172 |
:10293000DF91CF91BF91AF919F918F917F916F91D7 |
:102940005F914F913F912F911F910F91FF90EF90C9 |
:10295000DF90CF90BF909F908F900F900FBE0F9001 |
:102960001F901895613171F68091140190911501B5 |
:102970009C01220F331F280F391F80917302909101 |
:10298000740263E070E00E94D741260F371F36952E |
:102990002795369527953093150120931401809142 |
:1029A0001401909115019093CA038093C90381E0AB |
:1029B000809316018091690290916A02019690932A |
:1029C0006A028093690210927B02EBE6F2E01192B8 |
:1029D0001192B2E0EB37FB07D1F7E4E8F3E0E491C2 |
:1029E000E093310180917C00807EE82BE0937C00B5 |
:1029F0009DCF683009F086CF80912802882309F4A2 |
:102A0000B5C0809111019091120120917502309111 |
:102A10007602821B930B909392048093910472CF61 |
:102A200080912F0190913001009709F4AEC0019779 |
:102A30009093300180932F0187B58093E903109222 |
:102A4000EA038091B1049091B2049093F2038093D1 |
:102A5000F10358CF20916B0230916C023093A704A0 |
:102A60002093A60480912502882309F467C18091F0 |
:102A70000B0190910C01821B930B9093980480930F |
:102A8000970440CF80912702882309F451C0809198 |
:102A90000F01909110012091770230917802821BF2 |
:102AA000930B9093900480938F0440916702509110 |
:102AB00068028091A80420918F0430919004609165 |
:102AC000A80490E00197FC01E49FC001E59F900DF0 |
:102AD000F49F900D1124820F931F70E00E94EB4130 |
:102AE000709368026093670280918F0490919004C4 |
:102AF00060EA74E041E00E94281304CFF601E95F28 |
:102B0000FE4F80819181A901481B590B440F551F2D |
:102B1000440F551FDDCEF601E95FFE4F80819181A4 |
:102B2000F901E81BF90BEE0FFF1FEE0FFF1F73CE2D |
:102B300020910F01309110018091770290917802DD |
:102B4000821B930B9093900480938F04AECF2091BF |
:102B50000D0130910E018091790290917A02821BD1 |
:102B6000930B90938E0480938D04F4CD20911101EA |
:102B7000309112018091750290917602821B930B25 |
:102B80009093920480939104BDCEE0917102F091F4 |
:102B9000720221E0E039F20708F4DBC036E0EF36DC |
:102BA000F307D8F027B56091130170E0660F771F27 |
:102BB000660F771F8EED94E00E94EB41620F711D4E |
:102BC000603F71050CF063C187B5AB01481B51092B |
:102BD0005093300140932F0167BD27B580911301B9 |
:102BE000829FC00111248E0F9F1F9093B204809387 |
:102BF000B10487B58093E9031092EA038091B10490 |
:102C00009091B2049093F2038093F10380911301A9 |
:102C10002091B1043091B2046FE0869FC00111246D |
:102C20002817390708F0C5C0E0901301209113015F |
:102C30004091B1045091B2048091AD049091AE04E2 |
:102C4000A091AF04B091B004E69E7001112400275A |
:102C5000F7FC0095102FE80EF91E0A1F1B1F30E02D |
:102C600081EF9FEF289FB001299F700D389F700D55 |
:102C70001124640F751F80E090E029E130E040E00E |
:102C800050E00E94AC41E60EF71E081F191FE092AB |
:102C9000AD04F092AE040093AF041093B0048091A1 |
:102CA00099048E5F8093990480919904803108F48F |
:102CB00029CEE090B504F090B6040091B7041091CD |
:102CC000B8046091AD047091AE048091AF0490910E |
:102CD000B0046C5F7F4F8F4F9F4FA8019701220F69 |
:102CE000331F441F551F220F331F441F551F220F30 |
:102CF000331F441F551F2E193F09400B510B620F04 |
:102D0000731F841F951F28E030E040E050E00E94D0 |
:102D10002042C901DA018093B5049093B604A093D0 |
:102D2000B704B093B8041092AD041092AE041092A0 |
:102D3000AF041092B00410929904E4CD80910B017D |
:102D400090910C01281B390B309398042093970421 |
:102D5000D9CD27B580911301682F70E0660F771FDA |
:102D6000660F771F709561957F4F8EED94E00E94FE |
:102D7000EB41620F711D603171050CF45BC087B5CA |
:102D800090E0861B970B9093300180932F0167BDD5 |
:102D900024CF20323105D4F58EE490E0D901A89FEC |
:102DA0009001A99F300DB89F300D1124245C39404B |
:102DB0001BCD809113012091B1043091B20460EFDA |
:102DC000869FC00111248217930708F041C0E0904C |
:102DD0001301209113014091B1045091B2048091EC |
:102DE000AD049091AE04A091AF04B091B004E69E02 |
:102DF000700111240027F7FC0095102FE80EF91E32 |
:102E00000A1F1B1F30E080E19FEF2CCFBFE02D3D5C |
:102E10003B070CF4E9CC2C5D3F408EE490E0F901D7 |
:102E2000E89F9001E99F300DF89F300D1124245246 |
:102E3000304FDACC87B5882309F4CFCE87B58150DF |
:102E400087BD81E090E09093300180932F01C5CE43 |
:102E5000809199048F3049F18091B1049091B2042E |
:102E60002091AD043091AE044091AF045091B00474 |
:102E7000A0E0B0E0820F931FA41FB51F8093AD04A4 |
:102E80009093AE04A093AF04B093B00408CF87B57D |
:102E90008E3F08F0A2CE87B58F5F87BD81E090E0BE |
:102EA0009093300180932F0198CE8091B10490913E |
:102EB000B2042091AD043091AE044091AF04509122 |
:102EC000B00496958795A0E0B0E0820F931FA41FF1 |
:102ED000B51F8093AD049093AE04A093AF04B0935C |
:102EE000B004DDCEEF92FF920F931F93DF93CF9349 |
:102EF000CDB7DEB72C970FB6F894DEBF0FBECDBFAF |
:102F00007E010894E11CF11CD701E7E1F1E08CE0BF |
:102F100001900D928150E1F710E08AE090E00E946C |
:102F2000AF1220918D0430918E04442737FD4095D7 |
:102F3000542F89819A81AB81BC81820F931FA41F7A |
:102F4000B51F89839A83AB83BC8320918F04309112 |
:102F50009004442737FD4095542F8D819E81AF8189 |
:102F6000B885820F931FA41FB51F8D839E83AF83E7 |
:102F7000B8872091910430919204442737FD409501 |
:102F8000542F89859A85AB85BC85820F931FA41F1A |
:102F9000B51F89879A87AB87BC871F5F1A3009F0F6 |
:102FA000BCCF00E010E0F7016081718182819381E4 |
:102FB0006B5F7F4F8F4F9F4F2AE030E040E050E043 |
:102FC0000E942042D801AA0FBB1FFD01E35FFE4F04 |
:102FD00040815181F801EA5DFD4F8081882319F01D |
:102FE000309521953F4F240F351FA35FBE4F11969B |
:102FF0003C932E930F5F1F4F84E090E0E80EF91E84 |
:103000000330110581F660910D0170910E010E944F |
:10301000513660910F017091100186E090E00E949E |
:103020005136609111017091120188E090E00E9488 |
:1030300051361092A1041092A0048091A0049091A6 |
:10304000A10490939F0480939E0484E690E00E94E4 |
:10305000AF122C960FB6F894DEBF0FBECDBFCF9146 |
:10306000DF911F910F91FF90EF900895CF92DF9223 |
:10307000EF92FF920F931F93DF93CF93CDB7DEB7FD |
:103080002C970FB6F894DEBF0FBECDBF7E0108941B |
:10309000E11CF11CD701E3E2F1E08CE001900D921C |
:1030A0008150E1F74091C301842F83708F5F80933B |
:1030B000B404242F30E0C9018C70907095958795E9 |
:1030C000959587958F5F8093B904207330703595FF |
:1030D00027953595279535952795359527952F5F14 |
:1030E0002093B30442954695469543704F5F4093B5 |
:1030F000A8040E948D3E10E084E190E00E94AF128F |
:103100002091A2043091A304442737FD4095542F09 |
:1031100089819A81AB81BC81820F931FA41FB51F47 |
:1031200089839A83AB83BC832091A4043091A50446 |
:10313000442737FD4095542F8D819E81AF81B885FE |
:10314000820F931FA41FB51F8D839E83AF83B88703 |
:103150002091A6043091A704442737FD4095542FB1 |
:1031600089859A85AB85BC85820F931FA41FB51FE7 |
:1031700089879A87AB87BC871F5F103209F0BCCF65 |
:1031800067012BEDE22E23E0F22E00E010E0F601C5 |
:1031900061917191819191916F01605F7F4F8F4F2C |
:1031A0009F4F20E230E040E050E00E942042F801D2 |
:1031B000EE0FFF1FE95FFE4F3183208380819181F5 |
:1031C000F701819391937F010F5F1F4F033011052A |
:1031D000F1F61092960410929504809195049091C6 |
:1031E0009604909394048093930484E090E00E946A |
:1031F000AA3690930E0180930D0186E090E00E9424 |
:10320000AA369093100180930F0188E090E00E940D |
:10321000AA36909312018093110184E690E00E94F7 |
:10322000AF122C960FB6F894DEBF0FBECDBFCF9174 |
:10323000DF911F910F91FF90EF90DF90CF90089555 |
:10324000E3E3F1E080E2819391E0E338F907D9F715 |
:103250000895FF920F931F9380917D0290E080FF6D |
:1032600008C020917C02222309F40DC12150209333 |
:103270007C023091320181FF08C020917C0223172B |
:1032800009F406C12F5F20937C028370907003972E |
:1032900011F410927C02E3E3F1E080E2819321E0FB |
:1032A000E338F207D9F720917C02321718F43093F3 |
:1032B0007C02232F2A30C8F581E180937E0200D062 |
:1032C00000D00F92EDB7FEB7319681E0ADB7BEB733 |
:1032D00011968C938AE396E09283818323831482F0 |
:1032E0000E94B70E0F900F900F900F900F9080914B |
:1032F0007C02873009F430C3883040F18B3009F408 |
:10330000F8C38C3008F0C7C0883009F4E2C48930B3 |
:1033100009F460C481508093320110927C021092B3 |
:103320007D021F910F91FF90089580E180937E02AE |
:1033300000D000D00F92EDB7FEB7319681E0ADB767 |
:10334000BEB711968C9385E396E0C6CF823009F420 |
:1033500083C2833008F050C18823E1F610927E02C8 |
:1033600000D00F9211E0EDB7FEB7118385E296E031 |
:10337000938382830E94B70E84E180937E02209122 |
:10338000DC018DB79EB70A970FB6F8949EBF0FBEAB |
:103390008DBFEDB7FEB73196ADB7BEB711961C9392 |
:1033A00080E196E092838183822F6AE00E94CB4184 |
:1033B00083831482822F0E94CB41958316821086CC |
:1033C00017828AE490E09287818785EC90E0948769 |
:1033D00083870E94B70E88E280937E02EDB7FEB726 |
:1033E0003D960FB6F894FEBF0FBEEDBF0E94E535C7 |
:1033F0002DB73EB7275030400FB6F8943EBF0FBEF2 |
:103400002DBFEDB7FEB73196ADB7BEB711961C9381 |
:1034100021E036E0328321838383148283ED95E0BB |
:10342000968385830E94B70E8091830190918401D9 |
:10343000EDB7FEB737960FB6F894FEBF0FBEEDBFDF |
:10344000069708F4AFC420919602222309F498C489 |
:103450008CE380937E0200D000D00F92EDB7FEB7D0 |
:103460003196ADB7BEB711961C9381EE95E092836D |
:103470008183238314820E94B70E0F900F900F90C8 |
:103480000F900F904CCF3091320130937C02F3CEED |
:1034900010927C02FACE8C3009F45DC18D3009F0B7 |
:1034A00039CF10927E0200D00F9211E0ADB7BEB7B7 |
:1034B00011961C93119788ED93E013969C938E932D |
:1034C00012970E94B70E84E180937E02EDB7FEB79B |
:1034D00038970FB6F894FEBF0FBEEDBF3196ADB76B |
:1034E000BEB711961C9384EC93E092838183809104 |
:1034F000E00490E08D96948383838091E50490E0CE |
:103500008D96968385838091EA0490E08D969087CE |
:1035100087838091EF0490E08D96928781870E9447 |
:10352000B70E88E280937E02EDB7FEB73196ADB755 |
:10353000BEB711961C9380EB93E0928381838091B8 |
:10354000F40490E08D96948383838091F90490E055 |
:103550008D96968385838091FE0490E08D9690876A |
:1035600087838091030590E08D96928781870E94E2 |
:10357000B70E8CE380937E02EDB7FEB736960FB69A |
:10358000F894FEBF0FBEEDBF3196ADB7BEB7119632 |
:103590001C938FE993E0928381838091080590E0EA |
:1035A0008D96948383830E94B70E0F900F900F9097 |
:1035B0000F900F9080910D05882309F020C4809111 |
:1035C0001205882309F004C480911705882309F4A3 |
:1035D000A6CE88E480937E0200D00F9281E0EDB702 |
:1035E000FEB7818386E993E0938382830E94B70EBE |
:1035F0000F900F900F9093CE833009F4FBC184306D |
:1036000009F088CE10927E02E0917505F0E0EE0F91 |
:10361000FF1FED5DFA4F40815181E0917605F0E0AA |
:10362000EE0FFF1FED5DFA4F208131818DB79EB700 |
:1036300007970FB6F8949EBF0FBE8DBFEDB7FEB7CC |
:10364000319611E0ADB7BEB711961C938BE495E0AF |
:103650009283818354834383368325830E94B70EEC |
:1036600084E180937E02E0917705F0E0EE0FFF1F8A |
:10367000ED5DFA4F40815181E0917805F0E0EE0F69 |
:10368000FF1FED5DFA4F20813181EDB7FEB7319616 |
:10369000ADB7BEB711961C938BE395E092838183FF |
:1036A00054834383368325830E94B70E88E2809338 |
:1036B0007E02E0917905F0E0EE0FFF1FED5DFA4F1D |
:1036C00040815181E0917A05F0E0EE0FFF1FED5D42 |
:1036D000FA4F20813181EDB7FEB73196ADB7BEB755 |
:1036E00011961C938BE295E09283818354834383EC |
:1036F000368325830E94B70E8CE380937E02E0918F |
:103700007B05F0E0EE0FFF1FED5DFA4F4081518128 |
:10371000E0917C05F0E0EE0FFF1FED5DFA4F208198 |
:103720003181EDB7FEB73196ADB7BEB711961C9398 |
:103730008BE195E092838183548343833683258391 |
:103740000E94B70EEDB7FEB737960FB6F894FEBFDE |
:103750000FBEEDBFE4CD10927E0200D00F9211E0BB |
:10376000ADB7BEB711961C93119786E294E01396FD |
:103770009C938E9312970E94B70E84E180937E02F1 |
:10378000EDB7FEB738970FB6F894FEBF0FBEEDBF8A |
:103790003196ADB7BEB711961C9381E194E0928348 |
:1037A00081838091E104838314828091E604858380 |
:1037B00016828091EB04878310868091F0048187C4 |
:1037C00012860E94B70E88E280937E02EDB7FEB7A4 |
:1037D0003196ADB7BEB711961C938CEF93E09283F0 |
:1037E00081838091F504838314828091FA04858318 |
:1037F00016828091FF04878310868091040581875B |
:1038000012860E94B70E8CE380937E02EDB7FEB75E |
:103810003196ADB7BEB711961C9387EE93E09283B5 |
:103820008183809109058383148280910E058583AD |
:1038300016828091130587831086809118058187F1 |
:1038400012860E94B70EEDB7FEB73B960FB6F894FE |
:10385000FEBF0FBEEDBF63CD10927E0200D00F926F |
:10386000FF24F394ADB7BEB71196FC92119788EC84 |
:1038700095E013969C938E9312970E94B70E84E165 |
:1038800080937E0200D000D00DB71EB70F5F1F4F90 |
:10389000EDB7FEB7F18289EB95E0D80112969C93C3 |
:1038A0008E9311976091590570915A0580915B052F |
:1038B00090915C052AE535E040E050E00E9420420E |
:1038C000F80123833483458356830E94B70E88E230 |
:1038D00080937E020DB71EB70F5F1F4FADB7BEB707 |
:1038E0001196FC928AEA95E0F801928381836091B7 |
:1038F0005D0570915E0580915F05909160052AE5F8 |
:1039000035E040E050E00E942042D80113962D930C |
:103910003D934D935C9316970E94B70E8CE3809372 |
:103920007E020F900F90EDB7FEB73196ADB7BEB7E0 |
:103930001196FC928BE995E09283818380918701B7 |
:1039400090918801948383830E94B70E0F900F900B |
:103950000F900F900F90E3CC84E180937E028091D2 |
:1039600014019091150100911401109115012DB7CA |
:103970003EB7275030400FB6F8943EBF0FBE2DBF64 |
:10398000EDB7FEB73196FF24F394ADB7BEB71196ED |
:10399000FC9228E035E0328321836AE070E00E94E7 |
:1039A000EB4174836383C8016AE070E00E94EB41DD |
:1039B000968385830E94B70E88E280937E022091D1 |
:1039C000990230919A020F900F90EDB7FEB73196A1 |
:1039D000ADB7BEB71196FC928AEF94E092838183D3 |
:1039E000348323830E94B70E0F900F900F900F9097 |
:1039F0000F9095CC10927E022091250530912605DE |
:103A00004091270550912805EDB7FEB737970FB6BF |
:103A1000F894FEBF0FBEEDBF319611E0ADB7BEB753 |
:103A200011961C938BE895E09283818334832383E2 |
:103A3000568345830E94B70E84E180937E022091D5 |
:103A4000290530912A0540912B0550912C05EDB7A1 |
:103A5000FEB73196ADB7BEB711961C938BE795E0D4 |
:103A60009283818334832383568345830E94B70ED8 |
:103A700088E280937E0220912D0530912E054091A1 |
:103A80002F0550913005EDB7FEB73196ADB7BEB7F3 |
:103A900011961C938BE695E0928381833483238374 |
:103AA000568345830E94B70E8CE380937E0220915B |
:103AB0003105309132054091330550913405EDB711 |
:103AC000FEB73196ADB7BEB711961C938BE595E066 |
:103AD0009283818334832383568345830E94B70E68 |
:103AE000EDB7FEB737960FB6F894FEBF0FBEEDBF29 |
:103AF00016CC10927E0200D00F9211E0ADB7BEB787 |
:103B000011961C93119786E694E013969C938E93DE |
:103B100012970E94B70E84E180937E0200D000D0FD |
:103B2000EDB7FEB73196ADB7BEB711961C9386E5DB |
:103B300094E0928381838091C604992787FD9095B4 |
:103B4000948383838091C704992787FD90959683FA |
:103B500085830E94B70E88E280937E02EDB7FEB7A0 |
:103B60003196ADB7BEB711961C9386E494E092836C |
:103B700081838091C904838314828091C80499272A |
:103B800087FD9095968385830E94B70E8CE3809382 |
:103B90007E02EDB7FEB73196ADB7BEB711961C9356 |
:103BA00086E394E0928381838091CA04992787FDFC |
:103BB0009095948383838091CD04858316820E949F |
:103BC000B70EEDB7FEB737960FB6F894FEBF0FBE2F |
:103BD000EDBFA5CB10927E02EDB7FEB737970FB6BB |
:103BE000F894FEBF0FBEEDBF319611E0ADB7BEB782 |
:103BF00011961C938CEA94E0928381838091E70272 |
:103C00009091E802948383838091EF029091F00277 |
:103C1000968385830E94B70E84E180937E02EDB780 |
:103C2000FEB73196ADB7BEB711961C938AE994E002 |
:103C3000928381838091E9029091EA029483838345 |
:103C40008091F1029091F202968385830E94B70ED3 |
:103C500088E280937E02EDB7FEB73196ADB7BEB76E |
:103C600011961C9388E894E0928381838091EB0203 |
:103C70009091EC02948383838091F3029091F402FB |
:103C8000968385830E94B70E8CE380937E02EDB706 |
:103C9000FEB73196ADB7BEB711961C9386E794E098 |
:103CA000928381838091ED029091EE0294838383CD |
:103CB0008091F5029091F602968385830E94B70E5B |
:103CC000EDB7FEB737960FB6F894FEBF0FBEEDBF47 |
:103CD00026CB10927E0200D00F9211E0EDB7FEB716 |
:103CE00011838BEE94E0938382830E94B70E84E16C |
:103CF00080937E0200D0EDB7FEB73196ADB7BEB768 |
:103D000011961C938CED94E09283818380918901BC |
:103D100090918A01948383830E94B70E88E28093F6 |
:103D20007E02EDB7FEB73196ADB7BEB711961C93C4 |
:103D30008DEC94E09283818380918701909188013A |
:103D4000948383830E94B70E8CE380937E02EDB749 |
:103D5000FEB73196ADB7BEB711961C938EEB94E0CB |
:103D6000928381838091A3029091A40294838383A0 |
:103D70000E94B70E0F900F900F900F900F90CFCA28 |
:103D80008CE380937E0200D00F92EDB7FEB71183D3 |
:103D900081ED95E0938382830E94B70E0F900F9080 |
:103DA0000F90BDCA8CE380937E0200D00F92ADB716 |
:103DB000BEB711961C93119784EF95E013969C93D0 |
:103DC0008E9312970E94B70E0F900F900F90A7CA74 |
:103DD00084E480937E0200D00F9281E0ADB7BEB73D |
:103DE00011968C93119789E993E013969C938E9387 |
:103DF00012970E94B70E0F900F900F90E5CB80E4C2 |
:103E000080937E0200D00F92EDB7FEB711838CE94C |
:103E100093E0938382830E94B70E0F900F900F90D0 |
:103E2000CECB87B18C6087B9429843981092C10479 |
:103E30001092C00480E88093BF048093BE0408956C |
:103E4000382F6B3F20F0273E28F52A3088F1A32F2A |
:103E5000B0E0FD01E054FB4F8081815080838F5F93 |
:103E6000C1F461506083FD01E254FB4F80818130D9 |
:103E7000B9F1869580838081842339F528B184E067 |
:103E800090E002C0880F991FAA95E2F780958223DF |
:103E900088B9089547FD0EC028B184E090E002C0C3 |
:103EA000880F991F3A95E2F78095822388B9089583 |
:103EB00047FDF2CF28B184E090E002C0880F991F3F |
:103EC0003A95E2F7282B28B9089528B184E090E0CC |
:103ED00002C0880F991FAA95E2F7282B28B90895E8 |
:103EE00080E88083C8CF80917F02815080937F02D9 |
:103EF0008F5F09F0089584E080937F0280E06091F5 |
:103F0000AC054091AB052091CE010E94201F81E0BD |
:103F10006091AE054091AD052091CF010E94201F18 |
:103F200008950E94731F08958091C204089580919E |
:103F30008D02089580918E0208950E94632808954D |
:103F40001F930E944B27182F0E947121811708F49C |
:103F5000812F1F9108951F93CF93DF93C7EED2E077 |
:103F600010E00BC02F3F310594F42F5F3F4F398392 |
:103F700028831F5F22961830C1F0812F0E942B27C3 |
:103F800097FD17C028813981281739075CF312166D |
:103F900013067CF78217930764F72150304039836A |
:103FA00028831F5F2296183041F7DF91CF911F9130 |
:103FB000089580E090E0E6CFEF92FF920F931F9379 |
:103FC000CF93DF930E941E260E9424210E948638F0 |
:103FD0000E9428277C010E9418218C01FC0180810D |
:103FE0009181F70120813181820F931F9093850287 |
:103FF00080938402F80182819381F70122813381C9 |
:10400000820F931F9093870280938602F801848128 |
:104010009581F70124813581820F931F0E94A43D71 |
:104020000E945C3990938B0280938A02F80186810A |
:104030009781F70126813781820F931F9093890220 |
:104040008093880280918402909185029093CC03A2 |
:104050008093CB0380918602909187029093CE0348 |
:104060008093CD030E94A01F843008F08EC0109270 |
:104070008C02E4E8F2E0A0E8B2E0C4E6D0E06081BF |
:1040800071814D915C911197CB019C0197FD7AC094 |
:10409000359527953595279537FD70C042175307FD |
:1040A00008F03FC09B0177FD92C0C90195958795A7 |
:1040B0009595879511969C938E938536910518F06A |
:1040C0001196DC93CE933296129682E0E838F80788 |
:1040D000B1F60E944B27833008F075C000E00E94C3 |
:1040E0007121833008F05CC090E0002309F05EC0CD |
:1040F000992301F510928E0210928D028091B103E6 |
:104100008F7E8093B103002369F58091B2038F7E87 |
:104110008093B203DF91CF911F910F91FF90EF90A9 |
:1041200008954115510579F24150504011965C9324 |
:104130004E93C9CF10928E0280918D02981709F488 |
:104140004AC090938D020E941B218093C2048091EB |
:104150008E02882399F28091B10380618093B1032C |
:10416000002399F28091B20380618093B203DF91C2 |
:10417000CF911F910F91FF90EF9008953095219569 |
:104180003F4F8CCF2D5F3F4F83CF0E94AB1F0E94CC |
:10419000603A80918C020E94CC2780938C0269CF78 |
:1041A0000E941E21982F002309F4A2CF10928E02A4 |
:1041B00080918D02081799F000938D020E9472275A |
:1041C0008093C204C4CF0E946927082F88CF3095FE |
:1041D00021953F4F6ACF81E080938E02B2CF81E07C |
:1041E00080938E02E9CF1F93CF93DF93C7EED2E087 |
:1041F00010E0812F0E942B27899399931F5F18301D |
:10420000C1F7DF91CF911F9108950E940A210E946A |
:10421000513808951092CD041092C6041092C7042C |
:104220001092C8041092C90485E58093C3040895D0 |
:104230008FEC94E008958091CD0408958091CB0493 |
:10424000089580E090E008958091CE04882389F459 |
:104250001092D6041092D5041092D4041092D30474 |
:104260001092D2041092D1041092D0041092CF0474 |
:10427000089581508093CE042091840530E0809190 |
:10428000C604992787FD9095AC01249FC001259F06 |
:10429000900D349F900D11249093D0048093CF04FF |
:1042A0008091C704992787FD9095AC01429FC0017A |
:1042B000439F900D529F900D11249093D2048093B0 |
:1042C000D1048091C9048093D3041092D4048091C6 |
:1042D000C804992787FD90959093D6048093D504C0 |
:1042E00008958091CE04813580F4882359F480911B |
:1042F000CD0480FF0DC090E08091CD01813818F091 |
:1043000091E001C093E0892F089594E0892F0895EA |
:1043100090E0892F08951092D8041092D70410923B |
:10432000DA041092D9040895EF92FF920F931F932D |
:104330002AE535E040E050E00E942042CA01B90180 |
:1043400028E631E040E050E00E942042AC01CB0181 |
:10435000DA019C01AD0157FD25C061E02A35310528 |
:104360004105510564F084EB90E0A0E0B0E07C01F1 |
:104370008D01E21AF30A040B150BA8019701E22F35 |
:10438000F0E0EE0FFF1FE15CF94F259134916130B1 |
:1043900019F0309521953F4FC9011F910F91FF9062 |
:1043A000EF90089550954095309521953F4F4F4F90 |
:1043B0005F4F6FEFD3CF653A21EE720721E082079E |
:1043C00020E092073CF46C557E418E4F9F4F0E9437 |
:1043D000942108956C5E744A854090400E94942117 |
:1043E00008952AE535E040E050E00E942042C901EE |
:1043F000DA019C01AD018A359105A105B105B4F042 |
:1044000024EB30E040E050E0281B390B4A0B5B0BFB |
:10441000E22FF0E0EE0FFF1FEB50F94F85919491E2 |
:1044200022273327281B390BC9010895263A6FEF3D |
:1044300036076FEF46076FEF560774F42C543F4F63 |
:104440004F4F5F4FE22FF0E0EE0FFF1FEB50F94FA1 |
:1044500025913491C9010895B7FFF4CF222733275E |
:10446000A901281B390B4A0B5B0BD2CF9FB7F894DD |
:104470003998389A88B1836088B98091B9008C7F67 |
:104480008093B9008AE28093B80010929202109251 |
:10449000940210929502EFEDF4E0108211821282E4 |
:1044A0001482359685E0EB31F807B9F79FBF089580 |
:1044B0008093920285EA8093BC00089580939202D3 |
:1044C00084E98093BC0008958093BB0085E88093C5 |
:1044D000BC00089585EC8093BC00089585E8809326 |
:1044E000BC0008950F931F93109292020CEB10E002 |
:1044F00084E9D8018C9310929202EBEBF0E080817A |
:1045000080939402109294021092950280E88C930A |
:104510001092BD001092BA0010821092B900109251 |
:10452000B8000E9436221092920285EAF801808338 |
:104530001F910F9108951F920F920FB60F921124A1 |
:104540002F938F939F93EF93FF93809192028F5FAE |
:10455000809392028150853009F4C3C0863020F1E7 |
:10456000893009F497C08A30E0F5873009F411C129 |
:10457000883009F404C11092920284E98093BC004F |
:104580008AE090E0909384018093830110929402DA |
:1045900010929502FF91EF919F918F912F910F9023 |
:1045A0000FBE0F901F901895823009F47FC08330A2 |
:1045B00080F1833009F4BCC08430E9F68091950223 |
:1045C0002091BB0090E0FC01EE0FFF1FEE0FFF1FDC |
:1045D000E80FF91FE152FB4F238385E88093BC006D |
:1045E000D9CF8A3009F49DC08B3029F610929202FF |
:1045F00084E98093BC008AE090E0909384018093EA |
:10460000830180919702823008F417C110929702BB |
:10461000C1CF8823F9F0813009F0ADCF80919402A9 |
:1046200090E0FC01EE0FFF1FEE0FFF1FE80FF91FD8 |
:10463000E152FB4F80818093BB0085E88093BC00F2 |
:10464000A9CF809194028C3088F4809194028F5F7E |
:1046500080939402E0919402F0E0EE0FFF1FEE0FC2 |
:10466000FF1FEE52FA4F858518165CF78091940271 |
:104670008C3008F495C01092940283E080939202EB |
:1046800080919502880F8D5A8093BB0085E88093B6 |
:10469000BC0080CFE0919702F0E0E552FB4F8081B3 |
:1046A0008093BB0085E88093BC0074CF8091B900F3 |
:1046B000803309F484C01092920284E98093BC0094 |
:1046C0008AE090E09093840180938301809194022A |
:1046D0008F5F809394021092920285EA8093BC00CF |
:1046E00059CF809195022091BB0090E0FC01EE0F24 |
:1046F000FF1FEE0FFF1FE80FF91FE152FB4F24834E |
:10470000809195028F5F80939502809195028C3005 |
:1047100010F0109295021092920284E98093BC00EE |
:1047200039CF80E88093BB0085E88093BC0032CF0E |
:104730008091B900803409F46CC08091950290E0BA |
:10474000FC01EE0FFF1FEE0FFF1FE80FF91FE152F4 |
:10475000FB4F1182809195028F5F8093950280912B |
:1047600095028C3048F51092920284E98093BC0047 |
:104770008091980280939602109298020BCF8091BC |
:104780009702880F805F8093BB0085E88093BC0010 |
:1047900001CF88E98093BB0085E88093BC00FACE06 |
:1047A0008091940290E08996880F991F8093BB00B6 |
:1047B00085E88093BC00EECE10929502D4CF809114 |
:1047C0009802882329F4809194028F5F8093980245 |
:1047D0008091940290E0FC01EE0FFF1FEE0FFF1F8F |
:1047E000E80FF91FE152FB4F82818F5F828388239C |
:1047F00009F061CF8091940290E0FC01EE0FFF1F61 |
:10480000EE0FFF1FE80FF91FE152FB4F8FEF82837E |
:1048100052CF809195022091950290E0FC01EE0F1D |
:10482000FF1FEE0FFF1FE80FF91FE152FB4F2C5F38 |
:10483000218385EC8093BC009BCF8F5F8093970290 |
:1048400087E08093920285EA8093BC00A3CE8F928A |
:104850009F92BF92CF92DF92EF92FF920F931F939E |
:10486000CF93DF9300D00F92ADB7BEB711961C92D5 |
:1048700011978DEC97E013969C938E9312970E945C |
:10488000B70EEFEDF4E00F900F900F901082359679 |
:10489000B5E0EB31FB07D1F71092920285EA8093E5 |
:1048A000BC0080E197E20197F1F7109295028F0129 |
:1048B0000B531040E80161E0E62EF12C55EAB52ECD |
:1048C00040E1C42E47E2D42E39EC832E37E0932EFC |
:1048D00008C025960894E11CF11CB5E0CC31DB073B |
:1048E00039F110929202B092BC00C6010197F1F723 |
:1048F0008881882371F300D000D00F92EDB7FEB706 |
:104900003196ADB7BEB711961C9292828182F48225 |
:10491000E3820E94B70E0F900F900F900F900F90B0 |
:1049200025960894E11CF11CB5E0CC31DB07C9F6F3 |
:10493000CFEDD5E021E0E22EF12C9BEAC92E97E0E5 |
:10494000D92EF80180818823C1F488811816ACF42F |
:1049500000D000D00F92EDB7FEB73196ADB7BEB71D |
:1049600011961C92D282C182F482E3820E94B70E19 |
:104970000F900F900F900F900F90F80111820B5F26 |
:104980001F4F24960894E11CF11CF5E00C311F0721 |
:10499000C1F6DF91CF911F910F91FF90EF90DF90C3 |
:1049A000CF90BF909F908F9008959FB7F89456989E |
:1049B0005E9A8AB188638AB98BB1877C8BB9809102 |
:1049C000F702813011F0539A5B98809180008C70CF |
:1049D0008093800080918100837E8093810080910C |
:1049E0008100836C80938100809182008F7380931B |
:1049F000820080916F00887F80936F0080916F00AC |
:104A0000806280936F0010929A02109299029FBF69 |
:104A100008951F920F920FB60F9211240F931F93B8 |
:104A20002F933F934F935F936F937F938F939F93B6 |
:104A3000AF93BF93CF93DF93EF93FF9320918600C3 |
:104A40003091870080919D0290919E02281B390B26 |
:104A5000809186009091870090939E0280939D02A2 |
:104A6000C9018D549440835F9A4118F580919F024B |
:104A70009091A002049714F01092850181E090E0DB |
:104A80009093A00280939F02FF91EF91DF91CF91CD |
:104A9000BF91AF919F918F917F916F915F914F9156 |
:104AA0003F912F911F910F910F900FBE0F901F906C |
:104AB0001895C0919F02D091A002C930D10524F76A |
:104AC000C9018B5F9040845B914008F055C0265D22 |
:104AD00031408E01000F111FF801ED5DFA4F80810A |
:104AE0009181F901E81BF90BCF01F7FD60C0069732 |
:104AF0008CF48091990290919A02883C91050CF077 |
:104B00004FC08091990290919A020A9690939A02CE |
:104B100080939902F801ED5DFA4F808191810197B0 |
:104B20002817390734F08081918101968217930705 |
:104B30007CF58091990290919A02833C910514F141 |
:104B4000F801ED5DFA4F80819181A901481B590B55 |
:104B5000CA0163E070E00E94EB41CB01880F991F0E |
:104B6000860F971FF801E95CFA4F918380830D5DF2 |
:104B70001A4FF801318320832196D093A002C0936D |
:104B80009F0282CFF801E95CFA4F11821082EFCFC9 |
:104B90002F5F3F4F2330310570F420E030E0C9CF64 |
:104BA00088EC90E090939A0280939902B3CF90950D |
:104BB00081959F4F9CCF20813181BBCF809177051C |
:104BC000E82FF0E0EE0FFF1FED5DFA4F808191813D |
:104BD00086359105C4F080917805E82FF0E0EE0F5E |
:104BE000FF1FED5DFA4F80819181863591053CF480 |
:104BF000808191818B5A9F4F24F484E0089582E054 |
:104C0000089580E00895808191818B5A9F4FCCF761 |
:104C100080917805E82FF0E0EE0FFF1FED5DFA4F71 |
:104C200080819181863591053CF4808191818B5AF8 |
:104C30009F4F3CF786E0089588E008951F93CF9337 |
:104C4000DF938091990290919A02892B09F4D7C041 |
:104C50008091990290919A02019790939A02809381 |
:104C60009902809185018150809385018F5F09F0C1 |
:104C7000B7C0E0917505F0E0EE0FFF1FDF01AD5DFD |
:104C8000BA4F2D913C916091840570E0E95CFA4F38 |
:104C9000808191814091850550E0FC01E49FC00135 |
:104CA000E59F900DF49F900D1124F901E69F90016E |
:104CB000E79F300DF69F300D1124820F931F9093C4 |
:104CC0001C0580931B05E0917605F0E0EE0FFF1FB9 |
:104CD000DF01AD5DBA4F2D913C91E95CFA4F8081C7 |
:104CE0009181FC01E49FC001E59F900DF49F900D20 |
:104CF0001124A901469F9001479F300D569F300D0A |
:104D00001124820F931F90931E0580931D05E0913F |
:104D10007705F0E0EE0FFF1FDF01AD5DBA4F2D917B |
:104D20003C91E95CFA4F4081518128583F4F809176 |
:104D3000C20190E0BC01469FC001479F900D569F65 |
:104D4000900D1124280F391F3093200520931F0543 |
:104D500037FD71C0E0917805F0E0EE0FFF1FDF0135 |
:104D6000AD5DBA4F2D913C91E95CFA4F8081918104 |
:104D7000CC27DD27C21BD30BC81BD90B109186058E |
:104D8000BE01882777FD8095982F212F30E040E0E5 |
:104D900050E00E94AC41FE01D7FD55C09F01442761 |
:104DA00037FD4095542F0E94AC4120E032E040E0B6 |
:104DB00050E00E942042812F90E0C89FB001C99F1F |
:104DC000700DD89F700D112477FD3AC075956795C9 |
:104DD00075956795260F371F30932205209321057F |
:104DE0000E94DE25982F80919B029817E1F0909306 |
:104DF0009B0210929C02DF91CF911F910895109217 |
:104E00002205109221051092200510921F05109284 |
:104E10001E0510921D0510921C0510921B05DF91B6 |
:104E2000CF911F91089580919C02883CC0F78F5FBD |
:104E300080939C02F4CF1092200510921F058ACF18 |
:104E40006D5F7F4FC3CFEE27FF27EC1BFD0BA6CF77 |
:104E50008BE195E00895843068F0E82FF0E0EE0FE4 |
:104E6000FF1FEB5DFA4F0190F081E02DED58FF4FF1 |
:104E7000CF010895E82FF0E0EB58FA4FE481F0E01D |
:104E8000EE0FFF1FED5DFA4F0190F081E02DED5820 |
:104E9000FF4FCF0108958091990290919A02803A34 |
:104EA000910594F48091990290919A028C38910521 |
:104EB0004CF48091990290919A028837910534F4CC |
:104EC00081E0089583E0089584E0089582E00895E4 |
:104ED000089580919C02883C11F080E008958091B3 |
:104EE0009B02089580917505E82FF0E0EE0FFF1FFB |
:104EF000ED5DFA4F8081918187349105B4F0809106 |
:104F00007605E82FF0E0EE0FFF1FED5DFA4F808190 |
:104F10009181873491053CF4808191818A5B9F4F18 |
:104F2000FCF083E0089582E00895808191818A5B9E |
:104F30009F4FC4F480917605E82FF0E0EE0FFF1F3D |
:104F4000ED5DFA4F80819181873491053CF4808139 |
:104F500091818A5B9F4FE4F087E0089588E008958F |
:104F600084E0089580917605E82FF0E0EE0FFF1FB2 |
:104F7000ED5DFA4F80819181873491055CF48081E9 |
:104F800091818A5B9F4F14F080E0089585E0089539 |
:104F900086E0089581E00895CF93DF93682F809194 |
:104FA0007605A82FB0E0AA0FBB1FFD01ED5DFA4FFB |
:104FB0002081318180919D05482F50E04217530791 |
:104FC00024F48091C00582FD75C062FD61C0FD01C1 |
:104FD000ED5DFA4F80819181CC27DD27C41BD50B75 |
:104FE0008C179D0724F48091C00583FD61C063FD8B |
:104FF00040C080917505A82FB0E0AA0FBB1FFD012E |
:10500000ED5DFA4F808191814817590724F4809112 |
:10501000C00580FD51C060FD1EC0FD01ED5DFA4F71 |
:10502000808191818C179D0724F48091C00581FDBA |
:1050300045C061FF0CC0AD5DBA4F2D913C91809190 |
:105040009E05C81BD109C217D3070CF46D7E862FAD |
:10505000DF91CF910895FD01ED5DFA4F20813181FF |
:1050600080919E05481B510924173507B4F66E7EC2 |
:10507000D4CFAD5DBA4F2D913C9180919E05FE013C |
:10508000E81BF109E217F3070CF0B3CF677DB1CF4E |
:10509000FD01ED5DFA4F2081318180919E05FA017D |
:1050A000E81BF1092E173F070CF091CF6B7D8FCFD6 |
:1050B00068629FCF64628BCF6161AFCF6261862FE0 |
:1050C000DF91CF91089580917505A82FB0E0AA0FC8 |
:1050D000BB1FFD01ED5DFA4F808191818D5E9F4F79 |
:1050E00014F010928601AD5DBA4F8D919C918A5B50 |
:1050F0009F4F44F480918601882321F481E08093BE |
:105100008601089580E00895E82FF0E0EE0FFF1F7C |
:10511000EB59FD4F60817181882777FD8095982F2D |
:1051200023EC30E040E050E00E94AC4108956091F3 |
:10513000650270916602882777FD8095982F23EC91 |
:1051400030E040E050E00E94AC416093590570931C |
:105150005A0580935B0590935C056091670270919E |
:105160006802882777FD8095982F0E94AC41609354 |
:105170005D0570935E0580935F05909360050895CB |
:105180008091BA049091BB042091B2023091B30295 |
:10519000820F931F67E070E00E94EB4170934E0511 |
:1051A00060934D058091A9049091AA04820F931FEA |
:1051B00067E070E00E94EB417093660560936505BF |
:1051C00080919A0490919B0490936205809361056D |
:1051D00080918D0490918E042091AC023091AD02AB |
:1051E000820F931F9093AD028093AC028091BC0418 |
:1051F0009091BD042091B4023091B502820F931FAB |
:1052000067E070E00E94EB417093500560934F059A |
:105210008091AB049091AC04820F931F67E070E023 |
:105220000E94EB41709368056093670580919C0430 |
:1052300090919D04909364058093630580918F0401 |
:10524000909190042091AE023091AF02820F931F93 |
:105250009093AF028093AE028091B0029091B10220 |
:1052600001969093B1028093B002209197043091FF |
:1052700098048091B6029091B702820F931F909389 |
:1052800054058093530510921601EAE7F0E08081FF |
:10529000886C808308952F923F924F925F926F9215 |
:1052A0007F928F929F92AF92BF92CF92DF92EF92B6 |
:1052B000FF920F931F93DF93CF93CDB7DEB728975D |
:1052C0000FB6F894DEBF0FBECDBF80918C0288234D |
:1052D00079F420919104309192048091C601482F75 |
:1052E00050E088279927841B950B28173907DCF590 |
:1052F0008091B103877F8093B1038091B203877F50 |
:105300008093B2031092C6031092C5031092C80393 |
:105310001092C7031092D4031092D3031092D603B5 |
:105320001092D5031092AB021092AA021092A90219 |
:105330001092A80228960FB6F894DEBF0FBECDBF1C |
:10534000CF91DF911F910F91FF90EF90DF90CF9061 |
:10535000BF90AF909F908F907F906F905F904F9095 |
:105360003F902F9008958091910490919204481756 |
:1053700059070CF4BDCF8091B10388608093B103CD |
:10538000209189058091880290918902805C9F4FCD |
:105390008138910508F09CC031E0809180029091A5 |
:1053A00081028134910540F48091820290918302C0 |
:1053B0008134910508F48FC026958091B203877FD0 |
:1053C0008093B203822F90E0A0E0B0E089839A83BB |
:1053D000AB83BC8348EE642E43E0742E812C912C69 |
:1053E000681A790A8A0A9B0A35EC432E33E0532E59 |
:1053F000A9E5B5E0BE83AD8328EA222E22E0322E55 |
:1054000018861F82EF81F885EE0FFF1FEB59FD4FC5 |
:1054100060817181882777FD8095982F23EC30E09B |
:1054200040E050E00E94AC417B018C0129E830E073 |
:1054300040E050E00E942042F20131832083AD81A0 |
:10544000BE81AD90BD90CD90DC90C801B70129819F |
:105450003A814B815C810E94AC417B018C01C4018B |
:10546000B301A60195010E94AC41E60EF71E081F8C |
:10547000191FC801B70128EE33E040E050E00E9458 |
:105480002042C901DA01ED81FE8181939193A193BC |
:10549000B193FE83ED838A199B09D1012D913C9133 |
:1054A000280F391FF101219331931F01D2011F965B |
:1054B0009C938E931E97EF81F8853196F887EF8342 |
:1054C00082E090E0480E591E329709F09BCF32CF10 |
:1054D000269530E062CF332309F46FCF8091B20379 |
:1054E00088608093B2036ECF9F92AF92BF92CF92AB |
:1054F000DF92EF92FF920F931F93CF93DF938091F0 |
:105500008D0190918E01019790938E0180938D0172 |
:10551000892B09F056C080E091E090938E01809332 |
:105520008D019090A4058091A505A82EBB24CC24C4 |
:10553000DD24CA18DB0868EAE62E62E0F62EC2EB2C |
:10554000D2E007ED13E0F70120813181B901660F48 |
:10555000771F660F771F660F771F621B730B8827F5 |
:1055600077FD8095982F60587F4F8F4F9F4F20E099 |
:1055700031E040E050E00E942042DA01C901692D8B |
:1055800070E00E94EB419B0188819981860F971FF3 |
:10559000998388838C159D0504F5D982C882C6013C |
:1055A000F80131832083958B848BF701119211923E |
:1055B0007F0122960E5F1F4FFCEAEF16F2E0FF0616 |
:1055C00011F6DF91CF911F910F91FF90EF90DF9037 |
:1055D000CF90BF90AF909F900895A816B90604F79A |
:1055E000B982A882C501DCCFAF92BF92CF92DF9281 |
:1055F000EF92FF920F931F93CF93DF938091A702B7 |
:10560000882321F08091910280FF68C16091590543 |
:1056100070915A0580915B0590915C0520E032E025 |
:1056200040E050E00E942042E90137FD92C16091C4 |
:105630005D0570915E0580915F059091600520E0A9 |
:1056400032E040E050E00E942042690137FD7CC119 |
:10565000CC16DD060CF410C1809187019091880171 |
:1056600097FD11C1845E9D4F7C010027F7FC0095DA |
:10567000102F6091550570915605809157059091B6 |
:10568000580521E53BEF4FEF5FEF0E942042E20E0D |
:10569000F31E041F151FC801B70128E631E040E0E2 |
:1056A00050E00E942042645B7040809153059091CD |
:1056B000540597FDF0C0813891050CF0F3C0EB0163 |
:1056C000CC0FDD1FCC0FDD1FCC0FDD1F80918B01B8 |
:1056D00090918C01892BA9F489E1C816D1048CF42E |
:1056E00080914B0590914C05860F971F90934C0528 |
:1056F00080934B058091A5029091A602892B09F019 |
:10570000FDC0B60175956795759567957595679513 |
:105710006F5F7F4FCE010E94EB419B01442737FD15 |
:105720004095542F8091550590915605A0915705AD |
:10573000B0915805280F391F4A1F5B1F209355054C |
:105740003093560540935705509358058091B90101 |
:10575000C82FD0E0CC9EC001CD9E900DDC9E900D58 |
:10576000112497FDEFC0959587959595879595950B |
:10577000879595958795959587955E01A81AB90A9D |
:10578000B7FCA5C080918B0190918C01009709F026 |
:105790008EC0C0908202D09083028091800290914E |
:1057A0008102C80ED91ED694C794D694C794D694B5 |
:1057B000C79480E490E0C80ED91E80918901909131 |
:1057C0008A01AA2797FDA095BA2FECE1EE2EE2E020 |
:1057D000FE2E012D112DE81AF90A0A0B1B0BCA0126 |
:1057E000B9012FEA34E040E050E00E942042E20E8E |
:1057F000F31E041F151FC801B70128E631E040E081 |
:1058000050E00E942042645B70406A9DC0016B9D25 |
:10581000900D7A9D900D1124B6010E94EB419B01E1 |
:10582000CE01880F991F8C0F9D1F821793070CF4D0 |
:1058300063C044275527481B590BB9012417350766 |
:105840000CF4BA019B01442737FD4095542F8091F9 |
:105850006D0590916E05A0916F05B0917005820F56 |
:10586000931FA41FB51F80936D0590936E05A093A1 |
:105870006F05B093700520C06E01809187019091F3 |
:10588000880197FFEFCE60E070E080915305909122 |
:10589000540597FF10CF909581959F4F81389105C2 |
:1058A0000CF40DCF60E070E0C0E0D0E00FCF0197C6 |
:1058B00090938C0180938B01DF91CF911F910F9179 |
:1058C000FF90EF90DF90CF90BF90AF90089584EF5E |
:1058D00091E090938C0180938B01EECF0E949D1FED |
:1058E000882351F38091A7028F5F8093A7028530B0 |
:1058F000A0F50E94823DE0CFBC01A4CF88EC90E0EF |
:105900000E94293D0091870110918801B8018827E4 |
:1059100077FD8095982F2FEA34E040E050E00E9418 |
:10592000AC4160935505709356058093570590934D |
:10593000580510938A01009389011092A6021092D3 |
:10594000A502DFCE4F960FCFD094C194D108D39447 |
:105950007FCED095C195DF4F6ACE88EE93E00E944E |
:10596000293DAACF2F923F924F925F926F927F92E2 |
:105970008F929F92AF92BF92CF92DF92EF92FF925F |
:105980000F931F93DF93CF93CDB7DEB72C970FB64E |
:10599000F894DEBF0FBECDBF6091590570915A05D6 |
:1059A00080915B0590915C050E94DB219A8389833D |
:1059B00060915D0570915E0580915F059091600535 |
:1059C0000E94DB216C0160915D0570915E05809104 |
:1059D0005F05909160050E9494218C0160915905AA |
:1059E00070915A0580915B0590915C050E94F121B0 |
:1059F0001C016090650570906605882477FC809492 |
:105A0000982CC601AA2797FDA095BA2F8F83988757 |
:105A1000A987BA87A0905305B0905405CC24B7FC51 |
:105A2000C094DC2CC801AA2797FDA095BA2F8B83C0 |
:105A30009C83AD83BE836F81788589859A85A40117 |
:105A400093010E94AC417B018C016B817C818D8133 |
:105A50009E81A60195010E94AC41E61AF70A080B47 |
:105A6000190BC801B70120E030E140E050E00E948E |
:105A7000204230936A0520936905A0916705B09193 |
:105A80006805BC87AB8760915D0570915E0580916C |
:105A90005F05909160050E94DB21AA2797FDA095E4 |
:105AA000BA2FBC01CD01A60195010E94AC4120E0B6 |
:105AB00032E040E050E00E94204279018A016B818F |
:105AC0007C818D819E81A40193010E94AC4120E0E4 |
:105AD00032E040E050E00E942042E20EF31E041F3C |
:105AE000151F442437FC4094542CC801B701A2016F |
:105AF00091010E94AC4120E030E840E050E00E947B |
:105B00002042EB85FC85E20FF31FF0936C05E093D8 |
:105B10006B0589819A815C01CC24B7FCC094DC2C94 |
:105B20002091530530915405442737FD4095542F5B |
:105B30006F81788589859A850E94AC41A60195017F |
:105B40000E94204279018A01209165053091660505 |
:105B5000442737FD4095542F6B817C818D819E8138 |
:105B60000E94AC41A60195010E942042E20EF31E64 |
:105B7000F0925205E09251052C960FB6F894DEBFD4 |
:105B80000FBECDBFCF91DF911F910F91FF90EF908E |
:105B9000DF90CF90BF90AF909F908F907F906F904D |
:105BA0005F904F903F902F900895EF92FF920F9348 |
:105BB0001F9380918C02882321F480917D0586FDBE |
:105BC00013C1809165059091660590936A05809355 |
:105BD0006905809167059091680590936C058093A5 |
:105BE0006B05609153057091540570935205609355 |
:105BF000510580915105909152057C010027F7FCD9 |
:105C00000095102F8091550590915605A09157054C |
:105C1000B0915805E80EF91E0A1F1B1FE0925505AA |
:105C2000F092560500935705109358059B014427A1 |
:105C300037FD4095542F80916D0590916E05A09190 |
:105C40006F05B0917005820F931FA41FB51F80933D |
:105C50006D0590936E05A0936F05B093700588E174 |
:105C6000E81686E9F80686E0080780E018070CF4D5 |
:105C700082C088EE99E6A9EFBFEFE80EF91E0A1F71 |
:105C80001B1FE0925505F09256050093570510939F |
:105C900058058091690590916A059C01442737FD5C |
:105CA0004095542F8091590590915A05A0915B051C |
:105CB000B0915C05280F391F4A1F5B1F20935905BF |
:105CC00030935A0540935B0550935C05293493EC5F |
:105CD000390793E0490790E059070CF03FC0293B92 |
:105CE000ACE33A07ACEF4A07AFEF5A070CF46FC0CA |
:105CF00080916B0590916C059C01442737FD409580 |
:105D0000542F80915D0590915E05A0915F05B09143 |
:105D10006005280F391F4A1F5B1F20935D053093D4 |
:105D20005E0540935F05509360052934B3EC3B0753 |
:105D3000B3E04B07B0E05B078CF120593648474091 |
:105D4000504020935D0530935E0540935F0550936E |
:105D500060051F910F91FF90EF90089520593648EC |
:105D6000474050402093590530935A0540935B05B6 |
:105D700050935C05BDCF17FF8CCF88E196E9A6E074 |
:105D8000B0E0E80EF91E0A1F1B1FE0925505F092C5 |
:105D9000560500935705109358057BCF293B8CE39C |
:105DA00038078CEF48078FEF58079CF62057394784 |
:105DB000484F5F4F20935D0530935E0540935F052C |
:105DC000509360051F910F91FF90EF900895205719 |
:105DD0003947484F5F4F2093590530935A054093F8 |
:105DE0005B0550935C0584CF0E94B22C60915305F3 |
:105DF00070915405FECE0E94C0280E94D52D80913E |
:105E0000690590916A059093C0038093BF038091C8 |
:105E10006B0590916C059093C2038093C1038091B0 |
:105E20005105909152059093C4038093C3038091D0 |
:105E30004D0590914E059093BA038093B9038091DC |
:105E40004F05909150059093BC038093BB038091C4 |
:105E50005305909154059093BE038093BD030E9417 |
:105E60004B290E94742A08951092CA011092C90108 |
:105E70001092B7021092B60210924C0510924B0588 |
:105E80001092B5021092B4021092B3021092B202B4 |
:105E90001092AB021092AA021092A9021092A802CC |
:105EA0000E9436186091650270916602882777FD1E |
:105EB0008095982F23EC30E040E050E00E94AC4108 |
:105EC0006093590570935A0580935B0590935C0528 |
:105ED0006091670270916802882777FD8095982FFE |
:105EE0000E94AC4160935D0570935E0580935F05F1 |
:105EF0009093600510926D0510926E0510926F05DB |
:105F000010927005609187017091880170938A01E9 |
:105F100060938901882777FD8095982F2FEA34E0D8 |
:105F200040E050E00E94AC416093550570935605E7 |
:105F3000809357059093580508959C018091C40162 |
:105F4000823031F0833081F0813029F0C901089529 |
:105F50006217730764F4620F731F77FD0EC09B0115 |
:105F600035952795C901089526173707A4F3220F01 |
:105F7000331F261B370BC90108956F5F7F4FEFCF8B |
:105F80000F93382FE62F8CE398E2632F70E00E9486 |
:105F9000EB417093900160938F01E0937305409300 |
:105FA000720520937105009374050F9108950F9366 |
:105FB0009091BE0180917D0582FD0EC04091BC0193 |
:105FC0002091BB01265F892F8F5F622F0091C50151 |
:105FD0000E94C02F0F91089540E0F2CF0F9381E20D |
:105FE0006AE548E72AE508E70E94C02F0F91089567 |
:105FF0002F923F924F925F926F927F928F929F92D9 |
:10600000AF92BF92CF92DF92EF92FF920F931F93C6 |
:10601000DF93CF93CDB7DEB7E4970FB6F894DEBF2A |
:106020000FBECDBF0E94DC1F0E94FB2E20918A0272 |
:1060300030918B02388F2F8B0E94A01F833008F085 |
:106040006FC48091DC018A3009F450C3843109F4B3 |
:106050004DC328980E942E3D8091D1029091D2028A |
:10606000009709F44DC301979093D2028093D10217 |
:1060700080918F02909190028150914008F0C0C4AD |
:10608000809191028E7F80939102E0918C02EE23A9 |
:1060900051F080919C0590E02F89388D82179307ED |
:1060A00014F4988F8F8B2091880230918902A90176 |
:1060B00037FD99C48091860590E0880F991F880F5D |
:1060C000991F841795070CF415C480917D05682FDE |
:1060D00070E0C901AA2797FDA095BA2F20916D0500 |
:1060E00030916E0540916F0550917005281B390B5A |
:1060F0004A0B5B0B20936D0530936E0540936F0543 |
:1061000050937005203B8CE338078FEF48078FEFE3 |
:1061100058070CF0D3C380EB9CE3AFEFBFEF809345 |
:106120006D0590936E05A0936F05B093700568722E |
:106130007070672B09F0D9C38091BA01A82FB0E025 |
:10614000BE8BAD8B2E2F30E03CA32BA3309172057C |
:106150003AA3432F50E060E070E04E8F5F8F68A35A |
:1061600079A380917305282E332444245524BE013D |
:106170006B5F7F4F7C8B6B8BCE0109969A8B898BE3 |
:106180004DE4642E45E0742E31E6832E35E0932EE7 |
:1061900029E5E22E25E0F22E5B016C0100E010E023 |
:1061A00080E190E0002E02C0880F991F0A94E2F768 |
:1061B000ABA1BCA18A239B23892B09F4BEC2F601A3 |
:1061C00011821082D3012D913C91442737FD4095D7 |
:1061D000542FC201B1010E94AC4120E430E040E004 |
:1061E00050E00E942042F40180819181AD89BE89F6 |
:1061F000A89FB001A99F700DB89F700D112477FD65 |
:106200008CC3759567957595679575956795759523 |
:106210006795620F731FF60180819181680F791F66 |
:10622000D5016D937C93B0EC60307B070CF0B6C267 |
:1062300020E030ECF501318320830F5F1F4F22E017 |
:1062400030E0A20EB31EC20ED31E620E731E820E6B |
:10625000931E44E050E0E40EF51E0230110509F0F3 |
:106260009FCFE0915305F0915405209171059090D6 |
:106270007405A0906D05B0906E05C0906F05D0902C |
:106280007005809196028823C1F080918F029091D1 |
:1062900090020297C09758F46F89788D16161706EA |
:1062A00034F481E090E09093900280938F0280918B |
:1062B0008705A82FB0E0B88FAF8B2F88388C220CC1 |
:1062C000331C220C331CEE0FFF1FBF01882777FD04 |
:1062D0008095982F30E040E050E00E94AC4120E4EF |
:1062E00030E040E050E00E94204279018A01692DAF |
:1062F00070E080E090E0A60195010E94AC4120EFA3 |
:1063000035E540E050E00E942042C701820F931F14 |
:10631000B0E481309B0714F080E090E49C01E0EC55 |
:1063200080309E0714F420E030EC80918802909138 |
:106330008902880F991F880F991FA901481B590BC3 |
:10634000F1EA2F1631040CF4AAC2C10137FC66C36E |
:106350009595879522273327281B390B421753071A |
:106360003CF0910135952795421753070CF440C333 |
:1063700080918805682F70E0788B6F87CB01880F3C |
:10638000991F880F991F7101E81AF90A2E153F0508 |
:106390003CF0821993097901821793070CF47C0170 |
:1063A0009701F7FC1BC335952795220D331DB901C5 |
:1063B000882777FD8095982F2091CC0130E040E030 |
:1063C00050E00E94AC4120E430E040E050E00E9408 |
:1063D0002042390144245524421A530A80918F01E6 |
:1063E000909190019C0140E050E02A8F3B8F4C8FB0 |
:1063F0005D8F03EDA02E02E0B02E14E8812E12E096 |
:10640000912E00E010E03AA1332309F4ABC1D4018E |
:106410006D917C91E989FA8920813181261B370BA6 |
:10642000442737FD4095542FF50180819181A28149 |
:10643000B381820F931FA41FB51F80839183A28312 |
:10644000B383AB89BC89CD90DC90C61AD70AF8011A |
:10645000EE0FFF1FEE0FFF1FED52FD4F60817181A8 |
:1064600082819381603026E072072FEF82072FEF41 |
:1064700092070CF0A4C140E056E06FEF7FEF40833D |
:1064800051836283738360E076E08FEF9FEF2A8D04 |
:106490003B8D4C8D5D8D0E9420422C0D3D1DF801E1 |
:1064A000EE0FFF1F81E090E08C0F9D1FE80FF91F9A |
:1064B00031832083241535050CF07AC15182408246 |
:1064C0000F5F1F4FA4E0B0E0AA0EBB1EE989FA8956 |
:1064D0003296FA8BE98B22E030E0820E931E4B89D4 |
:1064E0005C894E5F5F4F5C8B4B8B0230110509F06E |
:1064F0008ACF49815A815093CC034093CB032B819F |
:106500003C813093CE032093CD03F092D003E092F0 |
:10651000CF033092D2032092D10380918705682F58 |
:1065200070E07E876D8770913F02798FFFED4F2E6F |
:10653000F4E05F2EEFED8E2EE3E09E2E7FEDA72E92 |
:1065400075E0B72E69EB662E62E0762ECC24DD2452 |
:10655000C901AA2797FDA095BA2F8DA39EA3AFA32B |
:10656000B8A7BA01882777FD8095982F69A77AA7E1 |
:106570008BA79CA7C101AA2797FDA095BA2F8DA72D |
:106580009EA7AFA7B8AB9701442737FD4095542F7E |
:1065900029AB3AAB4BAB5CAB93C0D5013C90131429 |
:1065A0000CF092C012966C91772767FD7095872F3B |
:1065B000972F2DA13EA14FA158A50E94AC4120E4E8 |
:1065C00030E040E050E00E94204279018A01F5016C |
:1065D0006181772767FD7095872F972F29A53AA5A9 |
:1065E0004BA55CA50E94AC4120E430E040E050E0C7 |
:1065F0000E942042E20EF31E232D332727FD309503 |
:10660000432F532F6DA57EA58FA598A90E94AC415D |
:1066100020E430E040E050E00E942042E20EF31E11 |
:10662000D50113962C91332727FD3095432F532FF7 |
:1066300069A97AA98BA99CA90E94AC4120E430E009 |
:1066400040E050E00E942042E20EF31EF301608120 |
:106650007181C7010E949D2FD3018C9311969C9349 |
:1066600097FD1BC19595879595958795ED85FE8539 |
:106670008E179F070CF055C0CF01009709F45BC03F |
:10668000D2018C93E3E0EC1528F0D2018C91F40157 |
:10669000808311820894C11CD11C25E030E0420E99 |
:1066A000531E42E050E0840E951E64E070E0A60E9A |
:1066B000B71E640E751E7CE0C716D10409F491C0A4 |
:1066C0008091910280FD69CFB98DBB23F9F0F6016D |
:1066D000EE0FFF1FEE0FFF1FEC0DFD1DE152FB4FF4 |
:1066E000D601A05CBD4F8C918083CCCF289A0E94AC |
:1066F0002E3D8091D1029091D202009709F0B3CC47 |
:10670000809191028E7E80939102BFCCF601EE0FB4 |
:10671000FF1FEE0FFF1FEC0DFD1DE152FB4F10821E |
:10672000B1CF2F853889281739070CF0A6CFC901BA |
:10673000009709F0A5CF81E0A3CFD7012D913D911E |
:106740004D915C916E8D7F8D88A199A10E94AC4185 |
:1067500028EF3AE240E050E00E942042F601318307 |
:10676000208330CDEB89FC89C080D180D4018D910C |
:106770009C91C81AD90A9601442737FD4095542F99 |
:10678000F50180819181A281B381820F931FA41FA3 |
:10679000B51F80839183A283B38359CE6150704427 |
:1067A0000CF44BCDE0E0F0E4D501ED93FC9345CD46 |
:1067B000621673060CF084CE7182608281CE6130E5 |
:1067C0005AEF750750E0850750E095070CF45FCE4F |
:1067D00060E07AEF80E090E060837183828393834E |
:1067E00056CE80E00E945822809191018150809382 |
:1067F00091018823C9F588E1809391016091590541 |
:1068000070915A0580915B0590915C0529E830E014 |
:1068100040E050E00E9420423093B4032093B30341 |
:1068200060915D0570915E0580915F0590916005B6 |
:1068300029E830E040E050E00E9420423093B60367 |
:106840002093B503609155057091560580915705C9 |
:10685000909158052FEA34E040E050E00E94204239 |
:106860003093B8032093B703E4960FB6F894DEBFD5 |
:106870000FBECDBFCF91DF911F910F91FF90EF9091 |
:10688000DF90CF90BF90AF909F908F907F906F9050 |
:106890005F904F903F902F9008950396E3CECA01EA |
:1068A0004135510514F080E590E09C014FEF803BAD |
:1068B00094070CF05DCD20EB3FEF5ACD2155334CC2 |
:1068C000404050400CF433CC80E593ECA0E0B0E0C5 |
:1068D00080936D0590936E05A0936F05B09370053E |
:1068E00068727070672B09F427CC0E94F42AE0913B |
:1068F0008C0222CC88EE93E090938C0180938B01E4 |
:1069000080917D05682F70E084FDE3CB81E090E00D |
:106910009093A6028093A502DCCB615F7F4F71CC80 |
:106920000E94A01F8330B0F0809191028F7E8093EF |
:1069300091028091900590E028EE31E0BC01629FC9 |
:10694000C001639F900D729F900D11249093D2020D |
:106950008093D1028F89988D8997B4F080919102AC |
:1069600080FF12C080918F0290919002AFEF8F3F15 |
:106970009A0729F001969093900280938F020E94CB |
:10698000183E0E94D72F81CB80918F029091900268 |
:106990008F3F910509F070F51092D7021092D8023E |
:1069A0001092D9021092DA021092D3021092D402FD |
:1069B0001092D5021092D6028A3F910501F781E02C |
:1069C00090E09093A6028093A50210926D0510921C |
:1069D0006E0510926F0510927005D1CF22273327D4 |
:1069E0002E193F09E0CC44275527421B530B62CB9D |
:1069F0009A01BECC80919102826080939102BFCFB8 |
:106A000080918F05482F50E0588F4F8B80919102D5 |
:106A10008061809391020E94EE2F37CB019698CC33 |
:106A2000809191028460809391028FEF8093D901CD |
:106A30001092DA0180E28093DB010E94F320089536 |
:106A400010929305109294051092950588E080931A |
:106A5000960585ED8093A70582E08093A80588E7D9 |
:106A60008093A9058AE08093AA050895E5E7F5E0FB |
:106A700082E08093750581E08093760583E08093C2 |
:106A8000770574E07093780525E020937905A6E0FA |
:106A9000A0937A0587E080937B0558E050937C05AE |
:106AA00084E480937D054EE140937E058BEF8093D7 |
:106AB00080058AE08093810540937F05409383059C |
:106AC00070938205509384058CE0809385058093B4 |
:106AD00086055093870586EE8093880580E880932D |
:106AE0008A0580E580938B0534E630938C056FE54D |
:106AF00060938E0583E280938F05409390051092FA |
:106B0000910580E2809392053093970588E2809307 |
:106B100098051092C10592E39093990586E98093B8 |
:106B20009A0520939B0590939C052AE520939D054B |
:106B300090939E051092C00520939F0583E4809357 |
:106B4000A0051092A1059093A6056093AB0583EF75 |
:106B50008093AD058FE08093AC058093AE058DEFFB |
:106B60008093AF053093B0052093B10525AF26AFD4 |
:106B70008BE487AF8093B5058093B6051092B70577 |
:106B8000A093B8055093B9052093BA054093BB056F |
:106B90003093BC053093BD057093BE0508958050B9 |
:106BA00090400E9461420895682F863030F065E081 |
:106BB00082E090E00E94794208958823C9F761E05D |
:106BC00082E090E00E947942089582E090E00E9485 |
:106BD0006142863008F4089582E090E063E00E940C |
:106BE000794283E00895805090400E947942089550 |
:106BF00081E08093D205EFEDF5E080E009C090E000 |
:106C000090831182128213828F5F3496803159F003 |
:106C10008430A8F790E490831182128213828F5FF0 |
:106C200034968031A9F790E49093E0059093E205C3 |
:106C300080EC8093E4059093E6058093E9058093CA |
:106C4000EA059093ED058093EE05A3EDB5E0E2E94A |
:106C5000F1E087E001900D928150E1F70895809175 |
:106C6000D205813011F080E0089582ED95E068EE64 |
:106C700073E04DE450E00E946F4281E0089588EE99 |
:106C800093E00E946142813011F080E0089582ED2E |
:106C900095E068EE73E04DE450E00E94514281E0DF |
:106CA0000895805090400E94874208951F93182FA6 |
:106CB000863000F115E068ED71E06050704085E7C6 |
:106CC00095E04DE550E00E946F4282E690E06DE570 |
:106CD00070E00E94874285E795E060E570E048E05B |
:106CE00050E00E946F42812F0E94D4350E94111FF4 |
:106CF0001F9108958823E1F390E001972DE530E09E |
:106D0000829FB001839F700D929F700D11246C596A |
:106D10007F4FD3CF982F8150853068F06EE171E0BE |
:106D20006050704085E795E04DE550E00E9451428B |
:106D30000E94111F0895892F90E001972DE530E002 |
:106D4000829FB001839F700D929F700D11246C592A |
:106D50007F4FE6CF805090400E94694208950E9484 |
:106D600036350E948E3E0E94203580EC80937D0552 |
:106D700083E08093820584E18093900586E480938C |
:106D8000A1058EE18093AC058093AE05A6ECB5E03D |
:106D9000EAE9F1E089E001900D928150E1F7089570 |
:106DA0000E9436350E948E3E0E94203580EC8093F2 |
:106DB0007D0583E08093820584E18093AC05809318 |
:106DC000AE05A6ECB5E0E4EAF1E087E001900D92B3 |
:106DD0008150E1F708950E9436350E948E3E0E9450 |
:106DE000203580EC80937D05A6ECB5E0ECEAF1E07F |
:106DF00086E001900D928150E1F708950F931F9363 |
:106E0000CF93DF9381E090E00E9461428B3409F4DC |
:106E10004FC000D00F92ADB7BEB711961C9211971C |
:106E20008BE598E013969C938E9312970E94B70E71 |
:106E30000F900F900F9088EE93E06FEF0E947942D1 |
:106E400080E590E00E94614200E08C3008F494C03C |
:106E500080E08F5F843011F00023D9F711E0123009 |
:106E600031F0133009F485C0113009F47FC00E945D |
:106E7000D036002379F0C0E0D0E0CE01805B9F4F98 |
:106E80000E946142FE01EB58FA4F80832196C83080 |
:106E9000D10599F7812F0E9456361F5F1630F9F6FB |
:106EA00081E00E94D43581E090E06BE40E94794259 |
:106EB0000E94E5350E948A360E94E53500D000D058 |
:106EC0000F92EDB7FEB73196ADB7BEB711961C92D3 |
:106ED00022E438E032832183838314820E94B70E38 |
:106EE0000F900F900F900F900F900E943F368823C5 |
:106EF00009F444C0EFEDF5E020E0808118160CF4B1 |
:106F00002F5F349686E0EF31F807B9F72093B80287 |
:106F1000ADB7BEB717970FB6F894BEBF0FBEADBFE3 |
:106F2000EDB7FEB7319611961C9280E098E09283FF |
:106F3000818383ED95E094838383258316820E9469 |
:106F4000B70E0F900F900F900F90EDB7FEB7118214 |
:106F50008FED97E0938382830E94B70E0F900F907E |
:106F60000F90DF91CF911F910F9108950E94EB3602 |
:106F700080CF0E94AF367DCF01E06ACF00D00F9264 |
:106F8000EDB7FEB7118281E298E0938382830E947D |
:106F9000B70E0F900F900F900E94F8350E942F3679 |
:106FA000A9CF9FB7F8948091C9008F778093C900CB |
:106FB0008091C9008F7B8093C9008091C9008F7D2B |
:106FC0008093C9005A9A52985B9A539A1092CD00B6 |
:106FD0008AE28093CC008091C80082608093C800D0 |
:106FE00088E18093C9008091CA008F778093CA009E |
:106FF0008091CA008F7B8093CA008091CA008F7DE8 |
:107000008093CA008091CA008F7E8093CA008091CD |
:10701000CA00877F8093CA008091C9008B7F8093CC |
:10702000C9008091CA0084608093CA008091CA0020 |
:1070300082608093CA008091C80087FF06C080915B |
:10704000CE008091C80087FDFACF8091C90080688A |
:107050008093C9009FBF08951F920F920FB60F92A1 |
:1070600011248F938091CE008F910F900FBE0F90BF |
:107070001F9018958091B5049091B604A091B70423 |
:10708000B091B80420912F0630913006409131061E |
:1070900050913206281B390B4A0B5B0BB901CA0110 |
:1070A00008958091B5049091B604A091B704B09171 |
:1070B000B80480932F0690933006A0933106B093C6 |
:1070C00032062091B5043091B6044091B704509136 |
:1070D000B804821B930BA40BB50B809323069093EB |
:1070E0002406A0932506B093260610921F06109240 |
:1070F0002006109221061092220610922706109266 |
:1071000028061092290610922A0608958F929F92BF |
:10711000AF92BF92CF92DF92EF92FF920F931F93A5 |
:107120008091B5049091B604A091B704B091B804D1 |
:1071300040912F06509130066091310670913206D1 |
:10714000481B590B6A0B7B0B80911F069091200600 |
:10715000A0912106B091220684179507A607B707CC |
:1071600044F440931F0650932006609321067093C9 |
:10717000220680917D0581FF55C08091B103816019 |
:107180008093B1038091B6018852803B08F47EC0A1 |
:107190009091E602993208F05AC0983209F47EC004 |
:1071A0009F5F9093E6028091E1028F5F8093E102FE |
:1071B000803309F054C01092E10280918205882E3C |
:1071C0009924AA24BB24C0902306D0902406E090E2 |
:1071D0002506F0902606950184010C0D1D1D2E1D1F |
:1071E0003F1D80912B0690912C06A0912D06B09109 |
:1071F0002E0680179107A207B3075CF4970186015A |
:10720000081919092A093B09081719072A073B0712 |
:1072100034F100932306109324062093250630931F |
:1072200026061DC08091B1038E7F8093B1038091AB |
:10723000B60124E6829FC0011124A0E0B0E0809353 |
:107240002B0690932C06A0932D06B0932E068091CA |
:10725000E1028F5F8093E102803309F4ACCFCB0170 |
:10726000BA0124E630E040E050E00E942042309332 |
:10727000F0032093EF031F910F91FF90EF90DF90A9 |
:10728000CF90BF90AF909F908F9008951092E6029C |
:107290008091B2038E7F8093B203D9CF40932B06A7 |
:1072A00050932C0660932D0670932E068091B203A6 |
:1072B00081608093B20374CFCF92DF92EF92FF92FE |
:1072C0000F931F93CF93DF936C018091B50490913E |
:1072D000B604A091B704B091B80420912F06309164 |
:1072E00030064091310650913206281B390B4A0B6B |
:1072F0005B0BE0902306F090240600912506109188 |
:1073000026068091E2029091E302E901C81BD90BA5 |
:107310002093E2023093E3024093E4025093E502AB |
:107320001C161D060CF0BEC08091B10382608093D4 |
:10733000B1038091B2038D7F8093B203E21AF30A06 |
:10734000040B150B2091810530E040E050E0C801AE |
:10735000B7010E94AC4128EE33E040E050E00E94CB |
:10736000204280917F0590E0BC01C69FC001C79F6D |
:10737000900DD69F900D1124281B390B80917E050E |
:10738000482F50E0421753074CF088279927841B59 |
:10739000950BA901281739070CF466C080917D056B |
:1073A00080FF04C081FD75C0C40ED51E7E0100277C |
:1073B000F7FC0095102F6091DB027091DC02809148 |
:1073C000DD029091DE0228E130E040E050E00E94D2 |
:1073D000AC41E60EF71E081F191FC801B70129E1CD |
:1073E00030E040E050E00E94204279018A01E092C2 |
:1073F000DB02F092DC020093DD021093DE022091AA |
:10740000B3013091B401C901880F991F820F931FF6 |
:10741000880F991F880F991F880F991F8C0D9D1D2C |
:1074200069E170E00E94D7416093B3017093B401A9 |
:1074300080918F0290919002885E934030F083E0BB |
:10744000E816F104010511058CF08091B1038B7FE2 |
:107450008093B103C601DF91CF911F910F91FF90EF |
:10746000EF90DF90CF900895AC0198CF2EEFE21609 |
:107470002FEFF2062FEF02072FEF120734F360937E |
:10748000DF027093E0028091B10384608093B103C6 |
:10749000E1CF8091B6018852803B08F487CFC40EBB |
:1074A000D51E84CF209709F449CF8091B203826022 |
:1074B0008093B2038091B1038D7F8093B1033ECF5F |
:1074C000CF93DF93E0918005EF3F59F0EB3F08F455 |
:1074D000ACC1F0E0EE0FFF1FEF50FF4F80818093B3 |
:1074E000B601E0917F05EF3F59F0EB3F08F49AC1F8 |
:1074F000F0E0EE0FFF1FEF50FF4F80818093B5014A |
:107500008091B501882309F04AC11092B501E0913C |
:107510008105EF3F59F0EB3F08F481C1F0E0EE0F39 |
:10752000FF1FEF50FF4F80818093B7018091B7011B |
:10753000882309F02DC11092B701E0918305EF3F38 |
:1075400059F0EB3F08F468C1F0E0EE0FFF1FEF5079 |
:10755000FF4F80818093B801E0918A05EF3F59F099 |
:10756000EB3F08F456C1F0E0EE0FFF1FEF50FF4F66 |
:1075700080818093B901E0918B05EF3F59F0EB3F9B |
:1075800008F444C1F0E0EE0FFF1FEF50FF4F808181 |
:107590008093BB018091BB018B3008F0F3C08AE07F |
:1075A0008093BB01E0918C05EF3F59F0EB3F08F46D |
:1075B0002AC1F0E0EE0FFF1FEF50FF4F8081809354 |
:1075C000BC01E0918D05EF3F59F0EB3F08F418C185 |
:1075D000F0E0EE0FFF1FEF50FF4F80818093BA0164 |
:1075E000E0919205EF3F59F0EB3F08F406C1F0E05F |
:1075F000EE0FFF1FEF50FF4F80818093BE01A3E984 |
:10760000B5E0CFEBD1E0EC91EF3F51F0EB3F08F468 |
:10761000B7C0F0E0EE0FFF1FEF50FF4F808188836F |
:107620001196219685E0A739B80769F75096C3EC03 |
:10763000D1E0EC91EF3F51F0EB3F08F49FC0F0E058 |
:10764000EE0FFF1FEF50FF4F808188831196219628 |
:1076500085E0AB3AB80769F7E0919705EF3F59F03D |
:10766000EB3F08F4C7C0F0E0EE0FFF1FEF50FF4FF5 |
:1076700080818093C701E0919C05EF3F59F0EB3F7B |
:1076800008F4B5C0F0E0EE0FFF1FEF50FF4F808110 |
:107690008093C801E0919F05EF3F59F0EB3F08F45C |
:1076A000A3C0F0E0EE0FFF1FEF50FF4F80818093EB |
:1076B000C901E091A005EF3F59F0EB3F08F491C0FC |
:1076C000F0E0EE0FFF1FEF50FF4F80818093CA0163 |
:1076D000E091A105EF3F59F0EB3F08F47FC0F0E0E7 |
:1076E000EE0FFF1FEF50FF4F80818093CB01E091A1 |
:1076F000A605EF3F59F0EB3F08F46DC0F0E0EE0F48 |
:10770000FF1FEF50FF4F80818093CC01E091AC05CB |
:10771000EF3F59F0EB3F08F453C0F0E0EE0FFF1FCE |
:10772000EF50FF4F80818093CE018091CE01823057 |
:1077300008F44DC08F3F09F486C0E091AE05EF3FDD |
:1077400051F0EB3F98F1F0E0EE0FFF1FEF50FF4FCD |
:1077500080818093CF018091CF01823068F18F3F8B |
:1077600009F474C0E091BF05EF3F29F0EB3F08F04A |
:107770005FC0E093CD01DF91CF910895E88366CF9C |
:10778000E8834ECF8F3F09F00DCF8093BB010ACF26 |
:10779000843608F4D2CE84E68093B701CECE843608 |
:1077A00008F4B5CE84E68093B501B1CEE093CF0165 |
:1077B0008091CF01823098F681E08093CF01D2CFC3 |
:1077C000E093CE018091CE01823008F0B3CF81E00A |
:1077D0008093CE01B2CFE093CC0198CFE093CB0160 |
:1077E00086CFE093CA0174CFE093C90162CFE093E2 |
:1077F000C80150CFE093C7013ECFE093BE01FFCE5A |
:10780000E093BA01EDCEE093BC01DBCEE093BB0187 |
:10781000C1CEE093B901AFCEE093B8019DCEE09325 |
:10782000B70184CEE093B5016BCEE093B60159CE9B |
:10783000F0E0EE0FFF1FEF50FF4F80818093CD01EE |
:10784000DF91CF9108958093CE0177CF8093CF01C0 |
:1078500089CF962F8B3F38F4682F691768F0461749 |
:1078600070F0862F0895E82FF0E0EE0FFF1FEF5025 |
:10787000FF4F6081691798F7692F862F0895642F4D |
:10788000862F0895CF93DF93ADEDB1E06DE570E005 |
:107890008C9190E0869FF001879FF00D969FF00DF0 |
:1078A0001124EB58FA4F408111968C9111974F3F5C |
:1078B000E9F04B3F38F0E42FF0E0EE0FFF1FEF5000 |
:1078C000FF4F408190E0FC01EE0FFF1FEE0FFF1F06 |
:1078D000EE0FFF1F9F01220F331F220F331FE20FF6 |
:1078E000F31FE81BF90BEB54FE4F4083129682E026 |
:1078F000A730B80769F6C7E0D2E099976DE570E068 |
:10790000888190E0869FF001879FF00D969FF00D93 |
:107910001124EB58FA4FE0818C91EF3F21F14A811D |
:107920009B81EB3F30F0F0E0EE0FFF1FEF50FF4F79 |
:10793000E081E41720F04E2F9E1708F4492F90E0C5 |
:10794000FC01EE0FFF1FEE0FFF1FEE0FFF1F9F0149 |
:10795000220F331F220F331FE20FF31FE81BF90B17 |
:10796000EB54FE4F40832496129682E0CF31D80725 |
:1079700039F6ABE5B0E1CBE3D3E0EC91EF3F49F072 |
:10798000EB3F30F0F0E0EE0FFF1FEF50FF4FE081D4 |
:10799000E883A35ABF4FA79681E1AF3CB80769F7C8 |
:1079A000AFE9B7E1C7EDD3E0EC91EF3F49F0EB3F32 |
:1079B00030F0F0E0EE0FFF1FEF50FF4FE081E88363 |
:1079C000A35ABF4FA79689E1A331B80769F7DF91A2 |
:1079D000CF9108958091C800803219F090E0892FEE |
:1079E00008958091CA0090E08630C9F791E0892F10 |
:1079F000089585B18C7F85B9209888EE93E0019732 |
:107A0000F1F783B190E08370907081309105A9F017 |
:107A10008230910569F0892BB1F484B1836084B917 |
:107A20008AE0289A8C3010F0299A089529980895B0 |
:107A300084B1836084B984E1F4CF84B1836084B974 |
:107A40008BE02898EFCF84B1836084B98DE02898CB |
:107A5000E9CF90935D0280935C02089580910401C8 |
:107A6000909105018F5F9F4F09F0089588E99AE38F |
:107A700090935D0280935C0280E09CE0909305010E |
:107A800080930401089580910401909105018F5F16 |
:107A90009F4F09F008958091910280FFFBCF80E114 |
:107AA00097E290935D0280935C0280E890E090936F |
:107AB000050180930401089580E093E0909305010F |
:107AC0008093040180915C0290915D02892B31F4D6 |
:107AD00080E797E190935D0280935C02089587E0D0 |
:107AE00090E0909305018093040180915C02909155 |
:107AF0005D02892B31F480E797E190935D028093DA |
:107B00005C0208951F93CF93DF93982F8823C1F0D1 |
:107B10008091910280FD14C0192F1150C4E6D0E06D |
:107B200005C080919102115080FD0AC0D0935D0282 |
:107B3000C0935C028AEF90E00E949A12112389F7A9 |
:107B4000DF91CF911F910895DF92EF92FF920F93F3 |
:107B50001F93CF93DF93EC016091590570915A0503 |
:107B600080915B0590915C050E94DB217C01609116 |
:107B70005D0570915E0580915F05909160050E94A2 |
:107B8000DB21AA2797FDA095BA2F0027F7FC0095C7 |
:107B9000102FBC01CD01A80197010E94AC41D090EB |
:107BA000C1019B01AC012030E0E03E07E0E84E0758 |
:107BB000E0E05E0778F12150304040485F4F2F5F92 |
:107BC0003F4F4F47504030F1ED2CFF2400E010E0D4 |
:107BD0001E2D0027FF24EE242AE030E040E050E094 |
:107BE0000E942042C801B7010E9420428D2D90E0E2 |
:107BF000BC01660F771F660F771F660F771F880F10 |
:107C0000991F680F791F88279927861B970B820F6A |
:107C1000931F02C080E090E09C012C0F3D1FC90122 |
:107C2000DF91CF911F910F91FF90EF90DF9008951A |
:107C30000F931F930E94971F182F0E949A1F082FBF |
:107C40000E94941F982F8091910280FD05C01230F0 |
:107C500021F1143009F43FC0163089F0183019F0C2 |
:107C60001F910F9108951092900210928F028091AF |
:107C700091028E7F809391021F910F91089581E070 |
:107C800090E09093900280938F028091910289609E |
:107C9000809391021F910F910895002309F780911D |
:107CA000DC018C3010F1299A963018F5892F81501B |
:107CB000853078F10E94E5350E948A360E94342F83 |
:107CC0000E9410350E9405210E94E5350E94823DE8 |
:107CD0001F910F910895002319F68091DC018C30DB |
:107CE00030F0299A0E947217E9CF2998DDCF2998A0 |
:107CF000F9CF80917D05887209F4B2CF973009F0F1 |
:107D0000AFCF81E08093A70288EE93E00E94293DE7 |
:107D1000A7CF892F0E94D435CDCF089595E09093B9 |
:107D20008D058AE08093A50581E080938905909375 |
:107D3000A4058EE48093A2058093A305089584B1E1 |
:107D4000806A84B93D9A82E58CBD1DBC459A8DE65A |
:107D500096E090938E0680938D0681E080933306A3 |
:107D60008AEA80936D0683E880936E068AE08093AA |
:107D70006F061092710610927006109273061092A0 |
:107D800072061092FD021092FC021092FB021092F9 |
:107D900069068AE480936A0684E680936B0686E02F |
:107DA00080936C06089580913306882311F40DB4F6 |
:107DB00007FE089584E080935E02459A9EB5809107 |
:107DC0000003813009F458C0813008F039C01092A6 |
:107DD000F8029093FF02913809F44AC02091FA0208 |
:107DE000203220F081E0809333060895459800000A |
:107DF0000000000000000000000000000000000083 |
:107E00000000000000000000000000000000000072 |
:107E10000000000000000000000000000000E091F1 |
:107E20008D06F0918E06E20FF11D80818EBD90913E |
:107E30008C06890F80938C062F5F2093FA02089599 |
:107E4000823009F0CBCF8091F802E82FF0E0EC5CB3 |
:107E5000F94F90838F5F8093F8028A31C0F0809150 |
:107E6000FF029817D1F01092FB0210920003B6CFD8 |
:107E700081E080930003B2CF9535B9F78091FF027E |
:107E80008B5A8093FF0282E080930003A7CF8091FA |
:107E9000FF02890F8093FF02A1CFF894AEE4B6E011 |
:107EA000E4E3F6E08AE101900D928150E1F77894E5 |
:107EB00081E08093FB02D9CFF894609159057091CD |
:107EC0005A0580915B0590915C0529E830E040E01F |
:107ED00050E00E942042309371062093700660911A |
:107EE0005D0570915E0580915F059091600529E8C0 |
:107EF00030E040E050E00E9420423093730620932F |
:107F000072066091550570915605809157059091C4 |
:107F100058052AE030E040E050E00E94AC412FEAF2 |
:107F200034E040E050E00E942042309379062093F4 |
:107F30007806809165059091660590937B06809305 |
:107F40007A06809167059091680590937D068093ED |
:107F50007C06809153059091540590937F06809301 |
:107F60007E0680E00E94842829E830E040E050E06E |
:107F70000E942042309375062093740681E00E948F |
:107F8000842829E830E040E050E00E94204230930D |
:107F90007706209376061092B1021092B0021092EA |
:107FA000AF021092AE021092AD021092AC0280911C |
:107FB0006F068C3009F473C18D3008F460C08D30C9 |
:107FC00009F41AC18E3009F402C178948091FB0241 |
:107FD000882309F4D2C020914F0630915006C90180 |
:107FE00081509E4F8F5F934058F4409151065091BD |
:107FF0005206CA0181509E4F8F5F934008F4D7C04C |
:10800000809155069091560621E08936920724F416 |
:108010009093880180938701209187013091880196 |
:1080200037FD5AC1245E3D4F8091890190918A01AC |
:10803000A901481B590BCA0168E671E00E94EB4197 |
:10804000845B90409093A4028093A30220915906F0 |
:1080500030915A0680915C0290915D0282179307DD |
:1080600040F48091A702882321F430935D0220938D |
:108070005C0280914E06873609F488C008958A30E4 |
:1080800009F4EBC08B3009F0A0CFE0917705F0E068 |
:10809000EE0FFF1FED5DFA4F0190F081E02D4FEFE5 |
:1080A000E038F40714F4E0E8FFEFE038F10514F0ED |
:1080B000EFE7F0E0E0938006E0917805F0E0EE0F66 |
:1080C000FF1FED5DFA4F0190F081E02D5FEFE0388A |
:1080D000F50714F4E0E8FFEFE038F10514F0EFE7FE |
:1080E000F0E0E0938106E0917605F0E0EE0FFF1FEF |
:1080F000ED5DFA4F0190F081E02D6FEFE038F6076B |
:1081000014F4E0E8FFEFE038F10514F0EFE7F0E0F9 |
:10811000E0938206E0917505F0E0EE0FFF1FED5D44 |
:10812000FA4F0190F081E02D8FEFE038F80714F45A |
:10813000E0E8FFEFE038F10514F0EFE7F0E0E0935E |
:1081400083068091E702809384068091E902809300 |
:1081500085068091EB02809386068091ED028093E4 |
:1081600087068091990290919A028093880678946C |
:108170008091FB02882309F02ECF1092DA0410922E |
:10818000D9041092D8041092D704089580915B0608 |
:108190008093D90180915C068093DB0180915D061C |
:1081A0008093DA0180915E068093FD0208958091AC |
:1081B0007D0585FF25CF3093DA042093D9045093B1 |
:1081C000D8044093D7048AEF8093FC0219CF8091A2 |
:1081D00069068093800680916A068093810680916B |
:1081E0006B068093820680916C0680938306809153 |
:1081F000DC0180938406E9CE8091AF0580938006F0 |
:108200008091B005809381068091B10580938206AC |
:108210008091B205809383068091B3058093840694 |
:108220008091B705809385068091B8058093860676 |
:108230008091B905809387068091BC05809388065C |
:108240008091BA05809389068091BB0580938A0648 |
:108250008091BD0580938B06B8CEEFEBF1E0A0E8EE |
:10826000B6E081918D9321E0E73CF207D1F7809150 |
:1082700091028093880680919102837F809391027E |
:1082800080911401909115018093890680918E054B |
:1082900080938A060E94E53580938B0696CE809166 |
:1082A000A70280938006853010F01092A70280917B |
:1082B000BE058093810610928306109282068091FB |
:1082C000B405809384068091B505809385068091DE |
:1082D000B6058093860679CE1092A4021092A3026E |
:1082E000B5CE80913306882309F435C04598809136 |
:1082F000FE02E82FF0E0E75DFD4F908190936F065E |
:108300008F5F8093FE02863010F01092FE02109272 |
:1083100033060E945C3F81E08093FA020000000077 |
:10832000000000000000000000000000000000004D |
:10833000000000000000000000000000000000003D |
:1083400000000000000000000000000080916D06A9 |
:1083500080938C068EBD0895629FD001739FF001BB |
:10836000829FE00DF11D649FE00DF11D929FF00DC5 |
:10837000839FF00D749FF00D659FF00D9927729FFC |
:10838000B00DE11DF91F639FB00DE11DF91FBD0187 |
:10839000CF0111240895991B79E004C0991F961705 |
:1083A00008F0961B881F7A95C9F780950895AA1B37 |
:1083B000BB1B51E107C0AA1FBB1FA617B70710F0D0 |
:1083C000A61BB70B881F991F5A95A9F78095909502 |
:1083D000BC01CD01089597FB092E07260AD077FD31 |
:1083E00004D0E5DF06D000201AF4709561957F4F28 |
:1083F0000895F6F7909581959F4F0895A1E21A2E62 |
:10840000AA1BBB1BFD010DC0AA1FBB1FEE1FFF1F38 |
:10841000A217B307E407F50720F0A21BB30BE40B88 |
:10842000F50B661F771F881F991F1A9469F76095CF |
:108430007095809590959B01AC01BD01CF01089589 |
:1084400097FB092E05260ED057FD04D0D7DF0AD0A2 |
:10845000001C38F450954095309521953F4F4F4F73 |
:108460005F4F0895F6F790958095709561957F4FD1 |
:108470008F4F9F4F0895FB01DC0102C005900D92C4 |
:1084800041505040D8F70895FC014150504030F021 |
:1084900001900616D1F73197CF01089588279927C3 |
:1084A0000895DC01CB01FC01F999FECF06C0F2BDB5 |
:1084B000E1BDF89A319600B40D9241505040B8F7A2 |
:1084C0000895F999FECF92BD81BDF89A992780B59C |
:1084D0000895A8E1B0E042E050E00C945342DC0182 |
:1084E000CB0103C02D910E947A4241505040D0F7F9 |
:1084F0000895262FF999FECF1FBA92BD81BD20BDE8 |
:108500000FB6F894FA9AF99A0FBE019608950E9450 |
:0C8510007942272F0C947A42F894FFCF98 |
:10851C00FF01F401FFFF0100080008000400040043 |
:10852C000400026A6400010000000000000000006A |
:10853C000000000000000000000000000000001916 |
:10854C0000020D48656C6C6F20576F726C640000F4 |
:10855C00000000000000000000000000000000000F |
:10856C0000000000000000000000000000000000FF |
:10857C0000000000000000000000000000000000EF |
:10858C0000000000000000000000000000000000DF |
:10859C0000000064000101FFFFFFFFF4010001383F |
:1085AC00010151756164726F0000426567696E6EFE |
:1085BC00657200004E6F726D616C000053706F72CB |
:1085CC00740000320030FB103A40089696020A0004 |
:1085DC000000000000000064465A414064000000A6 |
:1085EC000000000000000000000000000D0B010E58 |
:1085FC00031504170718051D09221227132A142B1B |
:10860C00152C1631173A1B3B1C3C1D3D1E3E1F42C0 |
:10861C0020452246234A180A0000640C00009616D6 |
:10862C000600FF371901FF391A01FF47210AFF0025 |
:10863C000080000000000001000A0B0D0B0C0E0066 |
:00000001FF |
/branches/dongfang_FC_rewrite/GPSControl.c |
---|
4,5 → 4,5 |
int16_t GPSStickPitch, GPSStickRoll; |
void GPS_setNeutral(void) { |
GPSStickPitch = GPSStickRoll = 0; |
GPSStickPitch = GPSStickRoll = 0; |
} |
/branches/dongfang_FC_rewrite/analog.c |
---|
77,7 → 77,7 |
*/ |
volatile int16_t rawGyroSum[3]; |
volatile int16_t acc[3]; |
volatile int16_t filteredAcc[2]={0,0}; |
volatile int16_t filteredAcc[2] = { 0, 0 }; |
/* |
* These 4 exported variables are zero-offset. The "PID" ones are used |
94,17 → 94,11 |
* standing still. They are used for adjusting the gyro and acc. meter values |
* to be centered on zero. |
*/ |
volatile int16_t gyroOffset[3] = { |
512 * GYRO_SUMMATION_FACTOR_PITCHROLL, |
512 * GYRO_SUMMATION_FACTOR_PITCHROLL, |
512 * GYRO_SUMMATION_FACTOR_YAW |
}; |
volatile int16_t gyroOffset[3] = { 512 * GYRO_SUMMATION_FACTOR_PITCHROLL, 512 |
* GYRO_SUMMATION_FACTOR_PITCHROLL, 512 * GYRO_SUMMATION_FACTOR_YAW }; |
volatile int16_t accOffset[3] = { |
512 * ACC_SUMMATION_FACTOR_PITCHROLL, |
512 * ACC_SUMMATION_FACTOR_PITCHROLL, |
512 * ACC_SUMMATION_FACTOR_Z |
}; |
volatile int16_t accOffset[3] = { 512 * ACC_SUMMATION_FACTOR_PITCHROLL, 512 |
* ACC_SUMMATION_FACTOR_PITCHROLL, 512 * ACC_SUMMATION_FACTOR_Z }; |
/* |
* This allows some experimentation with the gyro filters. |
176,72 → 170,66 |
* at all. The cost is not significant. |
*/ |
const uint8_t channelsForStates[] PROGMEM = { |
AD_GYRO_PITCH, |
AD_GYRO_ROLL, |
AD_GYRO_YAW, |
const uint8_t channelsForStates[] PROGMEM = { AD_GYRO_PITCH, AD_GYRO_ROLL, |
AD_GYRO_YAW, |
AD_ACC_PITCH, |
AD_ACC_ROLL, |
AD_AIRPRESSURE, |
AD_GYRO_PITCH, |
AD_GYRO_ROLL, |
AD_ACC_Z, // at 8, measure Z acc. |
AD_ACC_PITCH, AD_ACC_ROLL, AD_AIRPRESSURE, |
AD_GYRO_PITCH, |
AD_GYRO_ROLL, |
AD_GYRO_YAW, // at 11, finish yaw gyro |
AD_GYRO_PITCH, AD_GYRO_ROLL, AD_ACC_Z, // at 8, measure Z acc. |
AD_ACC_PITCH, // at 12, finish pitch axis acc. |
AD_ACC_ROLL, // at 13, finish roll axis acc. |
AD_AIRPRESSURE, // at 14, finish air pressure. |
AD_GYRO_PITCH, AD_GYRO_ROLL, AD_GYRO_YAW, // at 11, finish yaw gyro |
AD_GYRO_PITCH, // at 15, finish pitch gyro |
AD_GYRO_ROLL, // at 16, finish roll gyro |
AD_UBAT // at 17, measure battery. |
}; |
AD_ACC_PITCH, // at 12, finish pitch axis acc. |
AD_ACC_ROLL, // at 13, finish roll axis acc. |
AD_AIRPRESSURE, // at 14, finish air pressure. |
AD_GYRO_PITCH, // at 15, finish pitch gyro |
AD_GYRO_ROLL, // at 16, finish roll gyro |
AD_UBAT // at 17, measure battery. |
}; |
// Feature removed. Could be reintroduced later - but should work for all gyro types then. |
// uint8_t GyroDefectPitch = 0, GyroDefectRoll = 0, GyroDefectYaw = 0; |
void analog_init(void) { |
uint8_t sreg = SREG; |
// disable all interrupts before reconfiguration |
cli(); |
uint8_t sreg = SREG; |
// disable all interrupts before reconfiguration |
cli(); |
//ADC0 ... ADC7 is connected to PortA pin 0 ... 7 |
DDRA = 0x00; |
PORTA = 0x00; |
// Digital Input Disable Register 0 |
// Disable digital input buffer for analog adc_channel pins |
DIDR0 = 0xFF; |
// external reference, adjust data to the right |
ADMUX &= ~((1 << REFS1)|(1 << REFS0)|(1 << ADLAR)); |
// set muxer to ADC adc_channel 0 (0 to 7 is a valid choice) |
ADMUX = (ADMUX & 0xE0) | AD_GYRO_PITCH; |
//Set ADC Control and Status Register A |
//Auto Trigger Enable, Prescaler Select Bits to Division Factor 128, i.e. ADC clock = SYSCKL/128 = 156.25 kHz |
ADCSRA = (0<<ADEN)|(0<<ADSC)|(0<<ADATE)|(1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0)|(0<<ADIE); |
//Set ADC Control and Status Register B |
//Trigger Source to Free Running Mode |
ADCSRB &= ~((1 << ADTS2)|(1 << ADTS1)|(1 << ADTS0)); |
// Start AD conversion |
analog_start(); |
// restore global interrupt flags |
SREG = sreg; |
//ADC0 ... ADC7 is connected to PortA pin 0 ... 7 |
DDRA = 0x00; |
PORTA = 0x00; |
// Digital Input Disable Register 0 |
// Disable digital input buffer for analog adc_channel pins |
DIDR0 = 0xFF; |
// external reference, adjust data to the right |
ADMUX &= ~((1 << REFS1) | (1 << REFS0) | (1 << ADLAR)); |
// set muxer to ADC adc_channel 0 (0 to 7 is a valid choice) |
ADMUX = (ADMUX & 0xE0) | AD_GYRO_PITCH; |
//Set ADC Control and Status Register A |
//Auto Trigger Enable, Prescaler Select Bits to Division Factor 128, i.e. ADC clock = SYSCKL/128 = 156.25 kHz |
ADCSRA = (0 << ADEN) | (0 << ADSC) | (0 << ADATE) | (1 << ADPS2) | (1 |
<< ADPS1) | (1 << ADPS0) | (0 << ADIE); |
//Set ADC Control and Status Register B |
//Trigger Source to Free Running Mode |
ADCSRB &= ~((1 << ADTS2) | (1 << ADTS1) | (1 << ADTS0)); |
// Start AD conversion |
analog_start(); |
// restore global interrupt flags |
SREG = sreg; |
} |
void measureNoise(const int16_t sensor, volatile uint16_t* const noiseMeasurement, const uint8_t damping) { |
if (sensor > (int16_t)(*noiseMeasurement)) { |
*noiseMeasurement = sensor; |
} else if (-sensor > (int16_t)(*noiseMeasurement)) { |
*noiseMeasurement = -sensor; |
} else if (*noiseMeasurement > damping) { |
*noiseMeasurement -= damping; |
} else { |
*noiseMeasurement = 0; |
} |
void measureNoise(const int16_t sensor, |
volatile uint16_t* const noiseMeasurement, const uint8_t damping) { |
if (sensor > (int16_t) (*noiseMeasurement)) { |
*noiseMeasurement = sensor; |
} else if (-sensor > (int16_t) (*noiseMeasurement)) { |
*noiseMeasurement = -sensor; |
} else if (*noiseMeasurement > damping) { |
*noiseMeasurement -= damping; |
} else { |
*noiseMeasurement = 0; |
} |
} |
/* |
249,7 → 237,7 |
* Max: About 106 * 240 + 2047 = 27487; it is OK with just a 16 bit type. |
*/ |
uint16_t getSimplePressure(int advalue) { |
return (uint16_t)OCR0A * (uint16_t)rangewidth + advalue; |
return (uint16_t) OCR0A * (uint16_t) rangewidth + advalue; |
} |
/***************************************************** |
258,247 → 246,262 |
* processed the interrupt is disabled and further |
* AD conversions are stopped. |
*****************************************************/ |
ISR(ADC_vect) { |
static uint8_t ad_channel = AD_GYRO_PITCH, state = 0; |
static uint16_t sensorInputs[8] = {0,0,0,0,0,0,0,0}; |
static uint16_t pressureAutorangingWait = 25; |
uint16_t rawAirPressure; |
uint8_t i, axis; |
int16_t newrange; |
// for various filters... |
int16_t tempOffsetGyro, tempGyro; |
sensorInputs[ad_channel] += ADC; |
ISR(ADC_vect) |
{ |
static uint8_t ad_channel = AD_GYRO_PITCH, state = 0; |
static uint16_t sensorInputs[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; |
static uint16_t pressureAutorangingWait = 25; |
uint16_t rawAirPressure; |
uint8_t i, axis; |
int16_t newrange; |
/* |
* Actually we don't need this "switch". We could do all the sampling into the |
* sensorInputs array first, and all the processing after the last sample. |
*/ |
switch(state++) { |
// for various filters... |
int16_t tempOffsetGyro, tempGyro; |
case 8: // Z acc |
if (ACC_REVERSED[Z]) |
acc[Z] = accOffset[Z] - sensorInputs[AD_ACC_Z]; |
else |
acc[Z] = sensorInputs[AD_ACC_Z] - accOffset[Z]; |
break; |
case 11: // yaw gyro |
rawGyroSum[YAW] = sensorInputs[AD_GYRO_YAW]; |
if (GYRO_REVERSED[YAW]) |
yawGyro = gyroOffset[YAW] - sensorInputs[AD_GYRO_YAW]; |
else |
yawGyro = sensorInputs[AD_GYRO_YAW] - gyroOffset[YAW]; |
break; |
case 12: // pitch axis acc. |
if (ACC_REVERSED[PITCH]) |
acc[PITCH] = accOffset[PITCH] - sensorInputs[AD_ACC_PITCH]; |
else |
acc[PITCH] = sensorInputs[AD_ACC_PITCH] - accOffset[PITCH]; |
sensorInputs[ad_channel] += ADC; |
filteredAcc[PITCH] = (filteredAcc[PITCH] * (ACC_FILTER-1) + acc[PITCH]) / ACC_FILTER; |
measureNoise(acc[PITCH], &accNoisePeak[PITCH], 1); |
break; |
case 13: // roll axis acc. |
if (ACC_REVERSED[ROLL]) |
acc[ROLL] = accOffset[ROLL] - sensorInputs[AD_ACC_ROLL]; |
else |
acc[ROLL] = sensorInputs[AD_ACC_ROLL] - accOffset[ROLL]; |
filteredAcc[ROLL] = (filteredAcc[ROLL] * (ACC_FILTER-1) + acc[ROLL]) / ACC_FILTER; |
measureNoise(acc[ROLL], &accNoisePeak[ROLL], 1); |
break; |
/* |
* Actually we don't need this "switch". We could do all the sampling into the |
* sensorInputs array first, and all the processing after the last sample. |
*/ |
switch (state++) { |
case 14: // air pressure |
if (pressureAutorangingWait) { |
//A range switch was done recently. Wait for steadying. |
pressureAutorangingWait--; |
DebugOut.Analog[27] = (uint16_t)OCR0A; |
DebugOut.Analog[31] = simpleAirPressure; |
break; |
} |
case 8: // Z acc |
if (ACC_REVERSED[Z]) |
acc[Z] = accOffset[Z] - sensorInputs[AD_ACC_Z]; |
else |
acc[Z] = sensorInputs[AD_ACC_Z] - accOffset[Z]; |
break; |
rawAirPressure = sensorInputs[AD_AIRPRESSURE]; |
if (rawAirPressure < MIN_RAWPRESSURE) { |
// value is too low, so decrease voltage on the op amp minus input, making the value higher. |
newrange = OCR0A - (MAX_RAWPRESSURE - MIN_RAWPRESSURE) / (rangewidth * 4); // 4; // (MAX_RAWPRESSURE - rawAirPressure) / (rangewidth * 2) + 1; |
if (newrange > MIN_RANGES_EXTRAPOLATION) { |
pressureAutorangingWait = (OCR0A - newrange) * AUTORANGE_WAIT_FACTOR; // = OCRA0 - OCRA0 + |
OCR0A = newrange; |
} else { |
if (OCR0A) { |
OCR0A--; |
pressureAutorangingWait = AUTORANGE_WAIT_FACTOR; |
} |
} |
} else if (rawAirPressure > MAX_RAWPRESSURE) { |
// value is too high, so increase voltage on the op amp minus input, making the value lower. |
// If near the end, make a limited increase |
newrange = OCR0A + (MAX_RAWPRESSURE - MIN_RAWPRESSURE) / (rangewidth * 4); // 4; // (rawAirPressure - MIN_RAWPRESSURE) / (rangewidth * 2) - 1; |
if (newrange < MAX_RANGES_EXTRAPOLATION) { |
pressureAutorangingWait = (newrange - OCR0A) * AUTORANGE_WAIT_FACTOR; |
OCR0A = newrange; |
} else { |
if (OCR0A<254) { |
OCR0A++; |
pressureAutorangingWait = AUTORANGE_WAIT_FACTOR; |
} |
} |
} |
case 11: // yaw gyro |
rawGyroSum[YAW] = sensorInputs[AD_GYRO_YAW]; |
if (GYRO_REVERSED[YAW]) |
yawGyro = gyroOffset[YAW] - sensorInputs[AD_GYRO_YAW]; |
else |
yawGyro = sensorInputs[AD_GYRO_YAW] - gyroOffset[YAW]; |
break; |
// Even if the sample is off-range, use it. |
simpleAirPressure = getSimplePressure(rawAirPressure); |
DebugOut.Analog[27] = (uint16_t)OCR0A; |
DebugOut.Analog[31] = simpleAirPressure; |
case 12: // pitch axis acc. |
if (ACC_REVERSED[PITCH]) |
acc[PITCH] = accOffset[PITCH] - sensorInputs[AD_ACC_PITCH]; |
else |
acc[PITCH] = sensorInputs[AD_ACC_PITCH] - accOffset[PITCH]; |
if (simpleAirPressure < MIN_RANGES_EXTRAPOLATION * rangewidth) { |
// Danger: pressure near lower end of range. If the measurement saturates, the |
// copter may climb uncontrolledly... Simulate a drastic reduction in pressure. |
airPressureSum += (int16_t)MIN_RANGES_EXTRAPOLATION * rangewidth + (simpleAirPressure - (int16_t)MIN_RANGES_EXTRAPOLATION * rangewidth) * PRESSURE_EXTRAPOLATION_COEFF; |
} else if (simpleAirPressure > MAX_RANGES_EXTRAPOLATION * rangewidth) { |
// Danger: pressure near upper end of range. If the measurement saturates, the |
// copter may descend uncontrolledly... Simulate a drastic increase in pressure. |
airPressureSum += (int16_t)MAX_RANGES_EXTRAPOLATION * rangewidth + (simpleAirPressure - (int16_t)MAX_RANGES_EXTRAPOLATION * rangewidth) * PRESSURE_EXTRAPOLATION_COEFF; |
} else { |
// normal case. |
// If AIRPRESSURE_SUMMATION_FACTOR is an odd number we only want to add half the double sample. |
// The 2 cases above (end of range) are ignored for this. |
if (pressureMeasurementCount == AIRPRESSURE_SUMMATION_FACTOR - 1) |
airPressureSum += simpleAirPressure / 2; |
else |
airPressureSum += simpleAirPressure; |
} |
filteredAcc[PITCH] = (filteredAcc[PITCH] * (ACC_FILTER - 1) + acc[PITCH]) |
/ ACC_FILTER; |
measureNoise(acc[PITCH], &accNoisePeak[PITCH], 1); |
break; |
// 2 samples were added. |
pressureMeasurementCount += 2; |
if (pressureMeasurementCount >= AIRPRESSURE_SUMMATION_FACTOR) { |
filteredAirPressure = (filteredAirPressure * (AIRPRESSURE_FILTER-1) + airPressureSum + AIRPRESSURE_FILTER/2) / AIRPRESSURE_FILTER; |
pressureMeasurementCount = airPressureSum = 0; |
} |
case 13: // roll axis acc. |
if (ACC_REVERSED[ROLL]) |
acc[ROLL] = accOffset[ROLL] - sensorInputs[AD_ACC_ROLL]; |
else |
acc[ROLL] = sensorInputs[AD_ACC_ROLL] - accOffset[ROLL]; |
filteredAcc[ROLL] = (filteredAcc[ROLL] * (ACC_FILTER - 1) + acc[ROLL]) |
/ ACC_FILTER; |
measureNoise(acc[ROLL], &accNoisePeak[ROLL], 1); |
break; |
break; |
case 14: // air pressure |
if (pressureAutorangingWait) { |
//A range switch was done recently. Wait for steadying. |
pressureAutorangingWait--; |
DebugOut.Analog[27] = (uint16_t) OCR0A; |
DebugOut.Analog[31] = simpleAirPressure; |
break; |
} |
case 15: |
case 16: // pitch or roll gyro. |
axis = state - 16; |
tempGyro = rawGyroSum[axis] = sensorInputs[AD_GYRO_PITCH - axis]; |
// DebugOut.Analog[6 + 3 * axis ] = tempGyro; |
/* |
* Process the gyro data for the PID controller. |
*/ |
// 1) Extrapolate: Near the ends of the range, we boost the input significantly. This simulates a |
// gyro with a wider range, and helps counter saturation at full control. |
rawAirPressure = sensorInputs[AD_AIRPRESSURE]; |
if (rawAirPressure < MIN_RAWPRESSURE) { |
// value is too low, so decrease voltage on the op amp minus input, making the value higher. |
newrange = OCR0A - (MAX_RAWPRESSURE - MIN_RAWPRESSURE) / (rangewidth * 4); // 4; // (MAX_RAWPRESSURE - rawAirPressure) / (rangewidth * 2) + 1; |
if (newrange > MIN_RANGES_EXTRAPOLATION) { |
pressureAutorangingWait = (OCR0A - newrange) * AUTORANGE_WAIT_FACTOR; // = OCRA0 - OCRA0 + |
OCR0A = newrange; |
} else { |
if (OCR0A) { |
OCR0A--; |
pressureAutorangingWait = AUTORANGE_WAIT_FACTOR; |
} |
} |
} else if (rawAirPressure > MAX_RAWPRESSURE) { |
// value is too high, so increase voltage on the op amp minus input, making the value lower. |
// If near the end, make a limited increase |
newrange = OCR0A + (MAX_RAWPRESSURE - MIN_RAWPRESSURE) / (rangewidth * 4); // 4; // (rawAirPressure - MIN_RAWPRESSURE) / (rangewidth * 2) - 1; |
if (newrange < MAX_RANGES_EXTRAPOLATION) { |
pressureAutorangingWait = (newrange - OCR0A) * AUTORANGE_WAIT_FACTOR; |
OCR0A = newrange; |
} else { |
if (OCR0A < 254) { |
OCR0A++; |
pressureAutorangingWait = AUTORANGE_WAIT_FACTOR; |
} |
} |
} |
if (staticParams.GlobalConfig & CFG_ROTARY_RATE_LIMITER) { |
if (tempGyro < SENSOR_MIN_PITCHROLL) { |
tempGyro = tempGyro * EXTRAPOLATION_SLOPE - EXTRAPOLATION_LIMIT; |
} |
else if (tempGyro > SENSOR_MAX_PITCHROLL) { |
tempGyro = (tempGyro - SENSOR_MAX_PITCHROLL) * EXTRAPOLATION_SLOPE + SENSOR_MAX_PITCHROLL; |
} |
} |
// Even if the sample is off-range, use it. |
simpleAirPressure = getSimplePressure(rawAirPressure); |
DebugOut.Analog[27] = (uint16_t) OCR0A; |
DebugOut.Analog[31] = simpleAirPressure; |
// 2) Apply sign and offset, scale before filtering. |
if (GYRO_REVERSED[axis]) { |
tempOffsetGyro = (gyroOffset[axis] - tempGyro) * GYRO_FACTOR_PITCHROLL; |
} else { |
tempOffsetGyro = (tempGyro - gyroOffset[axis]) * GYRO_FACTOR_PITCHROLL; |
} |
if (simpleAirPressure < MIN_RANGES_EXTRAPOLATION * rangewidth) { |
// Danger: pressure near lower end of range. If the measurement saturates, the |
// copter may climb uncontrolledly... Simulate a drastic reduction in pressure. |
airPressureSum += (int16_t) MIN_RANGES_EXTRAPOLATION * rangewidth |
+ (simpleAirPressure - (int16_t) MIN_RANGES_EXTRAPOLATION |
* rangewidth) * PRESSURE_EXTRAPOLATION_COEFF; |
} else if (simpleAirPressure > MAX_RANGES_EXTRAPOLATION * rangewidth) { |
// Danger: pressure near upper end of range. If the measurement saturates, the |
// copter may descend uncontrolledly... Simulate a drastic increase in pressure. |
airPressureSum += (int16_t) MAX_RANGES_EXTRAPOLATION * rangewidth |
+ (simpleAirPressure - (int16_t) MAX_RANGES_EXTRAPOLATION |
* rangewidth) * PRESSURE_EXTRAPOLATION_COEFF; |
} else { |
// normal case. |
// If AIRPRESSURE_SUMMATION_FACTOR is an odd number we only want to add half the double sample. |
// The 2 cases above (end of range) are ignored for this. |
if (pressureMeasurementCount == AIRPRESSURE_SUMMATION_FACTOR - 1) |
airPressureSum += simpleAirPressure / 2; |
else |
airPressureSum += simpleAirPressure; |
} |
// 3) Scale and filter. |
tempOffsetGyro = (gyro_PID[axis] * (GYROS_PID_FILTER-1) + tempOffsetGyro) / GYROS_PID_FILTER; |
// 2 samples were added. |
pressureMeasurementCount += 2; |
if (pressureMeasurementCount >= AIRPRESSURE_SUMMATION_FACTOR) { |
filteredAirPressure = (filteredAirPressure * (AIRPRESSURE_FILTER - 1) |
+ airPressureSum + AIRPRESSURE_FILTER / 2) / AIRPRESSURE_FILTER; |
pressureMeasurementCount = airPressureSum = 0; |
} |
// 4) Measure noise. |
measureNoise(tempOffsetGyro, &gyroNoisePeak[axis], GYRO_NOISE_MEASUREMENT_DAMPING); |
break; |
// 5) Differential measurement. |
gyroD[axis] = (gyroD[axis] * (GYROS_D_FILTER-1) + (tempOffsetGyro - gyro_PID[axis])) / GYROS_D_FILTER; |
case 15: |
case 16: // pitch or roll gyro. |
axis = state - 16; |
tempGyro = rawGyroSum[axis] = sensorInputs[AD_GYRO_PITCH - axis]; |
// DebugOut.Analog[6 + 3 * axis ] = tempGyro; |
/* |
* Process the gyro data for the PID controller. |
*/ |
// 1) Extrapolate: Near the ends of the range, we boost the input significantly. This simulates a |
// gyro with a wider range, and helps counter saturation at full control. |
// 6) Done. |
gyro_PID[axis] = tempOffsetGyro; |
if (staticParams.GlobalConfig & CFG_ROTARY_RATE_LIMITER) { |
if (tempGyro < SENSOR_MIN_PITCHROLL) { |
tempGyro = tempGyro * EXTRAPOLATION_SLOPE - EXTRAPOLATION_LIMIT; |
} else if (tempGyro > SENSOR_MAX_PITCHROLL) { |
tempGyro = (tempGyro - SENSOR_MAX_PITCHROLL) * EXTRAPOLATION_SLOPE |
+ SENSOR_MAX_PITCHROLL; |
} |
} |
/* |
* Now process the data for attitude angles. |
*/ |
tempGyro = rawGyroSum[axis]; |
// 1) Apply sign and offset, scale before filtering. |
if (GYRO_REVERSED[axis]) { |
tempOffsetGyro = (gyroOffset[axis] - tempGyro) * GYRO_FACTOR_PITCHROLL; |
} else { |
tempOffsetGyro = (tempGyro - gyroOffset[axis]) * GYRO_FACTOR_PITCHROLL; |
} |
// 2) Filter. |
gyro_ATT[axis] = (gyro_ATT[axis] * (GYROS_ATT_FILTER-1) + tempOffsetGyro) / GYROS_ATT_FILTER; |
break; |
case 17: |
// Battery. The measured value is: (V * 1k/11k)/3v * 1024 = 31.03 counts per volt (max. measurable is 33v). |
// This is divided by 3 --> 10.34 counts per volt. |
UBat = (3 * UBat + sensorInputs[AD_UBAT] / 3) / 4; |
DebugOut.Analog[11] = UBat; |
analogDataReady = 1; // mark |
ADCycleCount++; |
// Stop the sampling. Cycle is over. |
state = 0; |
for (i=0; i<8; i++) { |
sensorInputs[i] = 0; |
} |
break; |
default: {} // do nothing. |
} |
// 2) Apply sign and offset, scale before filtering. |
if (GYRO_REVERSED[axis]) { |
tempOffsetGyro = (gyroOffset[axis] - tempGyro) * GYRO_FACTOR_PITCHROLL; |
} else { |
tempOffsetGyro = (tempGyro - gyroOffset[axis]) * GYRO_FACTOR_PITCHROLL; |
} |
// set up for next state. |
ad_channel = pgm_read_byte(&channelsForStates[state]); |
// ad_channel = channelsForStates[state]; |
// set adc muxer to next ad_channel |
ADMUX = (ADMUX & 0xE0) | ad_channel; |
// after full cycle stop further interrupts |
if(state) analog_start(); |
// 3) Scale and filter. |
tempOffsetGyro = (gyro_PID[axis] * (GYROS_PID_FILTER - 1) + tempOffsetGyro) |
/ GYROS_PID_FILTER; |
// 4) Measure noise. |
measureNoise(tempOffsetGyro, &gyroNoisePeak[axis], |
GYRO_NOISE_MEASUREMENT_DAMPING); |
// 5) Differential measurement. |
gyroD[axis] = (gyroD[axis] * (GYROS_D_FILTER - 1) + (tempOffsetGyro |
- gyro_PID[axis])) / GYROS_D_FILTER; |
// 6) Done. |
gyro_PID[axis] = tempOffsetGyro; |
/* |
* Now process the data for attitude angles. |
*/ |
tempGyro = rawGyroSum[axis]; |
// 1) Apply sign and offset, scale before filtering. |
if (GYRO_REVERSED[axis]) { |
tempOffsetGyro = (gyroOffset[axis] - tempGyro) * GYRO_FACTOR_PITCHROLL; |
} else { |
tempOffsetGyro = (tempGyro - gyroOffset[axis]) * GYRO_FACTOR_PITCHROLL; |
} |
// 2) Filter. |
gyro_ATT[axis] = (gyro_ATT[axis] * (GYROS_ATT_FILTER - 1) + tempOffsetGyro) |
/ GYROS_ATT_FILTER; |
break; |
case 17: |
// Battery. The measured value is: (V * 1k/11k)/3v * 1024 = 31.03 counts per volt (max. measurable is 33v). |
// This is divided by 3 --> 10.34 counts per volt. |
UBat = (3 * UBat + sensorInputs[AD_UBAT] / 3) / 4; |
DebugOut.Analog[11] = UBat; |
analogDataReady = 1; // mark |
ADCycleCount++; |
// Stop the sampling. Cycle is over. |
state = 0; |
for (i = 0; i < 8; i++) { |
sensorInputs[i] = 0; |
} |
break; |
default: { |
} // do nothing. |
} |
// set up for next state. |
ad_channel = pgm_read_byte(&channelsForStates[state]); |
// ad_channel = channelsForStates[state]; |
// set adc muxer to next ad_channel |
ADMUX = (ADMUX & 0xE0) | ad_channel; |
// after full cycle stop further interrupts |
if (state) |
analog_start(); |
} |
void analog_calibrate(void) { |
#define GYRO_OFFSET_CYCLES 32 |
uint8_t i, axis; |
int32_t deltaOffsets[3] = {0,0,0}; |
uint8_t i, axis; |
int32_t deltaOffsets[3] = { 0, 0, 0 }; |
// Set the filters... to be removed again, once some good settings are found. |
GYROS_PID_FILTER = (dynamicParams.UserParams[4] & 0b00000011) + 1; |
GYROS_ATT_FILTER = ((dynamicParams.UserParams[4] & 0b00001100) >> 2) + 1; |
GYROS_D_FILTER = ((dynamicParams.UserParams[4] & 0b00110000) >> 4) + 1; |
ACC_FILTER = ((dynamicParams.UserParams[4] & 0b11000000) >> 6) + 1; |
// Set the filters... to be removed again, once some good settings are found. |
GYROS_PID_FILTER = (dynamicParams.UserParams[4] & 0b00000011) + 1; |
GYROS_ATT_FILTER = ((dynamicParams.UserParams[4] & 0b00001100) >> 2) + 1; |
GYROS_D_FILTER = ((dynamicParams.UserParams[4] & 0b00110000) >> 4) + 1; |
ACC_FILTER = ((dynamicParams.UserParams[4] & 0b11000000) >> 6) + 1; |
gyro_calibrate(); |
gyro_calibrate(); |
// determine gyro bias by averaging (requires that the copter does not rotate around any axis!) |
for(i=0; i < GYRO_OFFSET_CYCLES; i++) { |
Delay_ms_Mess(20); |
for (axis=PITCH; axis<=YAW; axis++) { |
deltaOffsets[axis] += rawGyroSum[axis]; |
} |
} |
// determine gyro bias by averaging (requires that the copter does not rotate around any axis!) |
for (i = 0; i < GYRO_OFFSET_CYCLES; i++) { |
Delay_ms_Mess(20); |
for (axis = PITCH; axis <= YAW; axis++) { |
deltaOffsets[axis] += rawGyroSum[axis]; |
} |
} |
for (axis=PITCH; axis<=YAW; axis++) { |
gyroOffset[axis] = (deltaOffsets[axis] + GYRO_OFFSET_CYCLES/2) / GYRO_OFFSET_CYCLES; |
DebugOut.Analog[20+axis] = gyroOffset[axis]; |
} |
for (axis = PITCH; axis <= YAW; axis++) { |
gyroOffset[axis] = (deltaOffsets[axis] + GYRO_OFFSET_CYCLES / 2) |
/ GYRO_OFFSET_CYCLES; |
DebugOut.Analog[20 + axis] = gyroOffset[axis]; |
} |
// Noise is relative to offset. So, reset noise measurements when changing offsets. |
gyroNoisePeak[PITCH] = gyroNoisePeak[ROLL] = 0; |
// Noise is relative to offset. So, reset noise measurements when changing offsets. |
gyroNoisePeak[PITCH] = gyroNoisePeak[ROLL] = 0; |
accOffset[PITCH] = GetParamWord(PID_ACC_PITCH); |
accOffset[ROLL] = GetParamWord(PID_ACC_ROLL); |
accOffset[Z] = GetParamWord(PID_ACC_Z); |
accOffset[PITCH] = GetParamWord(PID_ACC_PITCH); |
accOffset[ROLL] = GetParamWord(PID_ACC_ROLL); |
accOffset[Z] = GetParamWord(PID_ACC_Z); |
// Rough estimate. Hmm no nothing happens at calibration anyway. |
// airPressureSum = simpleAirPressure * (AIRPRESSURE_SUMMATION_FACTOR/2); |
// pressureMeasurementCount = 0; |
// Rough estimate. Hmm no nothing happens at calibration anyway. |
// airPressureSum = simpleAirPressure * (AIRPRESSURE_SUMMATION_FACTOR/2); |
// pressureMeasurementCount = 0; |
Delay_ms_Mess(100); |
Delay_ms_Mess(100); |
} |
/* |
510,60 → 513,61 |
*/ |
void analog_calibrateAcc(void) { |
#define ACC_OFFSET_CYCLES 10 |
uint8_t i, axis; |
int32_t deltaOffset[3] = {0,0,0}; |
int16_t filteredDelta; |
// int16_t pressureDiff, savedRawAirPressure; |
uint8_t i, axis; |
int32_t deltaOffset[3] = { 0, 0, 0 }; |
int16_t filteredDelta; |
// int16_t pressureDiff, savedRawAirPressure; |
for(i=0; i < ACC_OFFSET_CYCLES; i++) { |
Delay_ms_Mess(10); |
for (axis=PITCH; axis<=YAW; axis++) { |
deltaOffset[axis] += acc[axis]; |
} |
} |
for (i = 0; i < ACC_OFFSET_CYCLES; i++) { |
Delay_ms_Mess(10); |
for (axis = PITCH; axis <= YAW; axis++) { |
deltaOffset[axis] += acc[axis]; |
} |
} |
for (axis=PITCH; axis<=YAW; axis++) { |
filteredDelta = (deltaOffset[axis] + ACC_OFFSET_CYCLES / 2) / ACC_OFFSET_CYCLES; |
accOffset[axis] += ACC_REVERSED[axis] ? -filteredDelta : filteredDelta; |
} |
for (axis = PITCH; axis <= YAW; axis++) { |
filteredDelta = (deltaOffset[axis] + ACC_OFFSET_CYCLES / 2) |
/ ACC_OFFSET_CYCLES; |
accOffset[axis] += ACC_REVERSED[axis] ? -filteredDelta : filteredDelta; |
} |
// Save ACC neutral settings to eeprom |
SetParamWord(PID_ACC_PITCH, accOffset[PITCH]); |
SetParamWord(PID_ACC_ROLL, accOffset[ROLL]); |
SetParamWord(PID_ACC_Z, accOffset[Z]); |
// Save ACC neutral settings to eeprom |
SetParamWord(PID_ACC_PITCH, accOffset[PITCH]); |
SetParamWord(PID_ACC_ROLL, accOffset[ROLL]); |
SetParamWord(PID_ACC_Z, accOffset[Z]); |
// Noise is relative to offset. So, reset noise measurements when |
// changing offsets. |
accNoisePeak[PITCH] = accNoisePeak[ROLL] = 0; |
// Setting offset values has an influence in the analog.c ISR |
// Therefore run measurement for 100ms to achive stable readings |
Delay_ms_Mess(100); |
// Set the feedback so that air pressure ends up in the middle of the range. |
// (raw pressure high --> OCR0A also high...) |
/* |
OCR0A += ((rawAirPressure - 1024) / rangewidth) - 1; |
Delay_ms_Mess(1000); |
// Noise is relative to offset. So, reset noise measurements when |
// changing offsets. |
accNoisePeak[PITCH] = accNoisePeak[ROLL] = 0; |
pressureDiff = 0; |
// DebugOut.Analog[16] = rawAirPressure; |
#define PRESSURE_CAL_CYCLE_COUNT 5 |
for (i=0; i<PRESSURE_CAL_CYCLE_COUNT; i++) { |
savedRawAirPressure = rawAirPressure; |
OCR0A+=2; |
Delay_ms_Mess(500); |
// raw pressure will decrease. |
pressureDiff += (savedRawAirPressure - rawAirPressure); |
savedRawAirPressure = rawAirPressure; |
OCR0A-=2; |
Delay_ms_Mess(500); |
// raw pressure will increase. |
pressureDiff += (rawAirPressure - savedRawAirPressure); |
} |
rangewidth = (pressureDiff + PRESSURE_CAL_CYCLE_COUNT * 2 * 2 - 1) / (PRESSURE_CAL_CYCLE_COUNT * 2 * 2); |
DebugOut.Analog[27] = rangewidth; |
*/ |
// Setting offset values has an influence in the analog.c ISR |
// Therefore run measurement for 100ms to achive stable readings |
Delay_ms_Mess(100); |
// Set the feedback so that air pressure ends up in the middle of the range. |
// (raw pressure high --> OCR0A also high...) |
/* |
OCR0A += ((rawAirPressure - 1024) / rangewidth) - 1; |
Delay_ms_Mess(1000); |
pressureDiff = 0; |
// DebugOut.Analog[16] = rawAirPressure; |
#define PRESSURE_CAL_CYCLE_COUNT 5 |
for (i=0; i<PRESSURE_CAL_CYCLE_COUNT; i++) { |
savedRawAirPressure = rawAirPressure; |
OCR0A+=2; |
Delay_ms_Mess(500); |
// raw pressure will decrease. |
pressureDiff += (savedRawAirPressure - rawAirPressure); |
savedRawAirPressure = rawAirPressure; |
OCR0A-=2; |
Delay_ms_Mess(500); |
// raw pressure will increase. |
pressureDiff += (rawAirPressure - savedRawAirPressure); |
} |
rangewidth = (pressureDiff + PRESSURE_CAL_CYCLE_COUNT * 2 * 2 - 1) / (PRESSURE_CAL_CYCLE_COUNT * 2 * 2); |
DebugOut.Analog[27] = rangewidth; |
*/ |
} |
/branches/dongfang_FC_rewrite/analog.h |
---|
24,66 → 24,66 |
// #define ACC_FILTER 4 |
/* |
About setting constants for different gyros: |
Main parameters are positive directions and voltage/angular speed gain. |
The "Positive direction" is the rotation direction around an axis where |
the corresponding gyro outputs a voltage > the no-rotation voltage. |
A gyro is considered, in this code, to be "forward" if its positive |
direction is: |
- Nose down for pitch |
- Left hand side down for roll |
- Clockwise seen from above for yaw. |
Declare the GYRO_REVERSE_YAW, GYRO_REVERSE_ROLL and |
GYRO_REVERSE_PITCH #define's if the respective gyros are reverse. |
About setting constants for different gyros: |
Main parameters are positive directions and voltage/angular speed gain. |
The "Positive direction" is the rotation direction around an axis where |
the corresponding gyro outputs a voltage > the no-rotation voltage. |
A gyro is considered, in this code, to be "forward" if its positive |
direction is: |
- Nose down for pitch |
- Left hand side down for roll |
- Clockwise seen from above for yaw. |
Declare the GYRO_REVERSE_YAW, GYRO_REVERSE_ROLL and |
GYRO_REVERSE_PITCH #define's if the respective gyros are reverse. |
Setting gyro gain correctly: All sensor measurements in analog.c take |
place in a cycle, each cycle comprising all sensors. Some sensors are |
sampled more than ones, and the results added. The pitch and roll gyros |
are sampled 4 times and the yaw gyro 2 times in the original H&I V0.74 |
code. |
In the H&I code, the results for pitch and roll are multiplied by 2 (FC1.0) |
or 4 (other versions), offset to zero, low pass filtered and then assigned |
to the "HiResXXXX" and "AdWertXXXXFilter" variables, where XXXX is nick or |
roll. |
So: |
gyro = V * (ADCValue1 + ADCValue2 + ADCValue3 + ADCValue4), |
where V is 2 for FC1.0 and 4 for all others. |
Assuming constant ADCValue, in the H&I code: |
Setting gyro gain correctly: All sensor measurements in analog.c take |
place in a cycle, each cycle comprising all sensors. Some sensors are |
sampled more than ones, and the results added. The pitch and roll gyros |
are sampled 4 times and the yaw gyro 2 times in the original H&I V0.74 |
code. |
In the H&I code, the results for pitch and roll are multiplied by 2 (FC1.0) |
or 4 (other versions), offset to zero, low pass filtered and then assigned |
to the "HiResXXXX" and "AdWertXXXXFilter" variables, where XXXX is nick or |
roll. |
So: |
gyro = V * (ADCValue1 + ADCValue2 + ADCValue3 + ADCValue4), |
where V is 2 for FC1.0 and 4 for all others. |
Assuming constant ADCValue, in the H&I code: |
gyro = I * ADCValue. |
gyro = I * ADCValue. |
where I is 8 for FC1.0 and 16 for all others. |
where I is 8 for FC1.0 and 16 for all others. |
The relation between rotation rate and ADCValue: |
ADCValue [units] = |
rotational speed [deg/s] * |
gyro sensitivity [V / deg/s] * |
amplifier gain [units] * |
1024 [units] / |
3V full range [V] |
The relation between rotation rate and ADCValue: |
ADCValue [units] = |
rotational speed [deg/s] * |
gyro sensitivity [V / deg/s] * |
amplifier gain [units] * |
1024 [units] / |
3V full range [V] |
or: H is the number of steps the ADC value changes with, |
for a 1 deg/s change in rotational velocity: |
H = ADCValue [units] / rotation rate [deg/s] = |
gyro sensitivity [V / deg/s] * |
amplifier gain [units] * |
1024 [units] / |
3V full range [V] |
or: H is the number of steps the ADC value changes with, |
for a 1 deg/s change in rotational velocity: |
H = ADCValue [units] / rotation rate [deg/s] = |
gyro sensitivity [V / deg/s] * |
amplifier gain [units] * |
1024 [units] / |
3V full range [V] |
Examples: |
FC1.3 has 0.67 mV/deg/s gyros and amplifiers with a gain of 5.7: |
H = 0.00067 V / deg / s * 5.7 * 1024 / 3V = 1.304 units/(deg/s). |
FC2.0 has 6*(3/5) mV/deg/s gyros (they are ratiometric) and no amplifiers: |
H = 0.006 V / deg / s * 1 * 1024 * 3V / (3V * 5V) = 1.2288 units/(deg/s). |
My InvenSense copter has 2mV/deg/s gyros and no amplifiers: |
H = 0.002 V / deg / s * 1 * 1024 / 3V = 0.6827 units/(deg/s) |
(only about half as sensitive as V1.3. But it will take about twice the |
rotation rate!) |
Examples: |
FC1.3 has 0.67 mV/deg/s gyros and amplifiers with a gain of 5.7: |
H = 0.00067 V / deg / s * 5.7 * 1024 / 3V = 1.304 units/(deg/s). |
FC2.0 has 6*(3/5) mV/deg/s gyros (they are ratiometric) and no amplifiers: |
H = 0.006 V / deg / s * 1 * 1024 * 3V / (3V * 5V) = 1.2288 units/(deg/s). |
My InvenSense copter has 2mV/deg/s gyros and no amplifiers: |
H = 0.002 V / deg / s * 1 * 1024 / 3V = 0.6827 units/(deg/s) |
(only about half as sensitive as V1.3. But it will take about twice the |
rotation rate!) |
All together: gyro = I * H * rotation rate [units / (deg/s)]. |
*/ |
All together: gyro = I * H * rotation rate [units / (deg/s)]. |
*/ |
/* |
* A factor that the raw gyro values are multiplied by, |
108,38 → 108,38 |
#define ACC_SUMMATION_FACTOR_Z 1 |
/* |
Integration: |
The HiResXXXX values are divided by 8 (in H&I firmware) before integration. |
In the Killagreg rewrite of the H&I firmware, the factor 8 is called |
HIRES_GYRO_AMPLIFY. In this code, it is called HIRES_GYRO_INTEGRATION_FACTOR, |
and care has been taken that all other constants (gyro to degree factor, and |
180 degree flip-over detection limits) are corrected to it. Because the |
division by the constant takes place in the flight attitude code, the |
constant is there. |
Integration: |
The HiResXXXX values are divided by 8 (in H&I firmware) before integration. |
In the Killagreg rewrite of the H&I firmware, the factor 8 is called |
HIRES_GYRO_AMPLIFY. In this code, it is called HIRES_GYRO_INTEGRATION_FACTOR, |
and care has been taken that all other constants (gyro to degree factor, and |
180 degree flip-over detection limits) are corrected to it. Because the |
division by the constant takes place in the flight attitude code, the |
constant is there. |
The control loop executes every 2ms, and for each iteration |
gyro_ATT[PITCH/ROLL] is added to gyroIntegral[PITCH/ROLL]. |
Assuming a constant rotation rate v and a zero initial gyroIntegral |
(for this explanation), we get: |
gyroIntegral = |
N * gyro / HIRES_GYRO_INTEGRATION_FACTOR = |
N * I * H * v / HIRES_GYRO_INTEGRATION_FACTOR |
where N is the number of summations; N = t/2ms. |
The control loop executes every 2ms, and for each iteration |
gyro_ATT[PITCH/ROLL] is added to gyroIntegral[PITCH/ROLL]. |
Assuming a constant rotation rate v and a zero initial gyroIntegral |
(for this explanation), we get: |
For one degree of rotation: t*v = 1: |
gyroIntegral = |
N * gyro / HIRES_GYRO_INTEGRATION_FACTOR = |
N * I * H * v / HIRES_GYRO_INTEGRATION_FACTOR |
gyroIntegralXXXX = t/2ms * I * H * 1/t = INTEGRATION_FREQUENCY * I * H / HIRES_GYRO_INTEGRATION_FACTOR. |
where N is the number of summations; N = t/2ms. |
This number (INTEGRATION_FREQUENCY * I * H) is the integral-to-degree factor. |
For one degree of rotation: t*v = 1: |
Examples: |
FC1.3: I=2, H=1.304, HIRES_GYRO_INTEGRATION_FACTOR=8 --> integralDegreeFactor = 1304 |
FC2.0: I=2, H=2.048, HIRES_GYRO_INTEGRATION_FACTOR=13 --> integralDegreeFactor = 1260 |
My InvenSense copter: HIRES_GYRO_INTEGRATION_FACTOR=4, H=0.6827 --> integralDegreeFactor = 1365 |
*/ |
gyroIntegralXXXX = t/2ms * I * H * 1/t = INTEGRATION_FREQUENCY * I * H / HIRES_GYRO_INTEGRATION_FACTOR. |
This number (INTEGRATION_FREQUENCY * I * H) is the integral-to-degree factor. |
Examples: |
FC1.3: I=2, H=1.304, HIRES_GYRO_INTEGRATION_FACTOR=8 --> integralDegreeFactor = 1304 |
FC2.0: I=2, H=2.048, HIRES_GYRO_INTEGRATION_FACTOR=13 --> integralDegreeFactor = 1260 |
My InvenSense copter: HIRES_GYRO_INTEGRATION_FACTOR=4, H=0.6827 --> integralDegreeFactor = 1365 |
*/ |
/* |
* The value of gyro[PITCH/ROLL] for one deg/s = The hardware factor H * the number of samples * multiplier factor. |
* Will be about 10 or so for InvenSense, and about 33 for ADXRS610. |
239,7 → 239,6 |
*/ |
extern volatile uint8_t analogDataReady; |
void analog_init(void); |
// clear ADC enable & ADC Start Conversion & ADC Interrupt Enable bit |
/branches/dongfang_FC_rewrite/attitude.c |
---|
239,9 → 239,8 |
ACRate[PITCH] = ((int32_t) rate_ATT[PITCH] * cosroll - (int32_t) yawRate |
* sinroll) / (int32_t) MATH_UNIT_FACTOR; |
ACRate[ROLL] = rate_ATT[ROLL] + (((int32_t) rate_ATT[PITCH] * sinroll |
/ ANTIOVF * tanpitch + (int32_t) yawRate * int_cos(angle[ROLL]) |
/ ANTIOVF * tanpitch) / ((int32_t) MATH_UNIT_FACTOR / ANTIOVF |
* MATH_UNIT_FACTOR)); |
/ ANTIOVF * tanpitch + (int32_t) yawRate * int_cos(angle[ROLL]) / ANTIOVF |
* tanpitch) / ((int32_t) MATH_UNIT_FACTOR / ANTIOVF * MATH_UNIT_FACTOR)); |
ACYawRate = ((int32_t) rate_ATT[PITCH] * sinroll) / cospitch |
+ ((int32_t) yawRate * cosroll) / cospitch; |
} |
327,8 → 326,7 |
*/ |
for (axis = PITCH; axis <= ROLL; axis++) { |
accDerived = getAngleEstimateFromAcc(axis); |
DebugOut.Analog[9 + axis] = (10 * accDerived) |
/ GYRO_DEG_FACTOR_PITCHROLL; |
DebugOut.Analog[9 + axis] = (10 * accDerived) / GYRO_DEG_FACTOR_PITCHROLL; |
// 1000 * the correction amount that will be added to the gyro angle in next line. |
correction = angle[axis]; //(permilleAcc * (accDerived - angle[axis])) / 1000; |
370,16 → 368,14 |
timer = DRIFTCORRECTION_TIME; |
for (axis = PITCH; axis <= ROLL; axis++) { |
// Take the sum of corrections applied, add it to delta |
deltaCorrection = (correctionSum[axis] |
* HIRES_GYRO_INTEGRATION_FACTOR + DRIFTCORRECTION_TIME / 2) |
/ DRIFTCORRECTION_TIME; |
deltaCorrection = (correctionSum[axis] * HIRES_GYRO_INTEGRATION_FACTOR |
+ DRIFTCORRECTION_TIME / 2) / DRIFTCORRECTION_TIME; |
// Add the delta to the compensation. So positive delta means, gyro should have higher value. |
driftComp[axis] += deltaCorrection / staticParams.GyroAccTrim; |
CHECK_MIN_MAX(driftComp[axis], -staticParams.DriftComp, staticParams.DriftComp); |
// DebugOut.Analog[11 + axis] = correctionSum[axis]; |
DebugOut.Analog[18 + axis] = deltaCorrection |
/ staticParams.GyroAccTrim; |
DebugOut.Analog[18 + axis] = deltaCorrection / staticParams.GyroAccTrim; |
DebugOut.Analog[28 + axis] = driftComp[axis]; |
correctionSum[axis] = 0; |
432,16 → 428,16 |
v = abs(angle[ROLL] / 512); |
if (v > w) |
w = v; |
correction = w/8 + 1; |
correction = w / 8 + 1; |
// calculate the deviation of the yaw gyro heading and the compass heading |
if (compassHeading < 0) |
error = 0; // disable yaw drift compensation if compass heading is undefined |
else |
if (abs(yawRate) > 128) { // spinning fast |
else if (abs(yawRate) > 128) { // spinning fast |
error = 0; |
} else { |
// compassHeading - yawGyroHeading, on a -180..179 deg interval. |
error = ((540 + compassHeading - (yawGyroHeading / GYRO_DEG_FACTOR_YAW)) % 360) - 180; |
error = ((540 + compassHeading - (yawGyroHeading / GYRO_DEG_FACTOR_YAW)) |
% 360) - 180; |
} |
if (!ignoreCompassTimer && w < 25) { |
yawGyroDrift += error; |
456,10 → 452,11 |
yawGyroHeading += (error * 8) / correction; |
/* |
w = (w * dynamicParams.CompassYawEffect) / 32; |
w = dynamicParams.CompassYawEffect - w; |
*/ |
w = dynamicParams.CompassYawEffect - (w * dynamicParams.CompassYawEffect) / 32; |
w = (w * dynamicParams.CompassYawEffect) / 32; |
w = dynamicParams.CompassYawEffect - w; |
*/ |
w = dynamicParams.CompassYawEffect - (w * dynamicParams.CompassYawEffect) |
/ 32; |
// As readable formula: |
// w = dynamicParams.CompassYawEffect * (1-w/32); |
468,7 → 465,9 |
if (!ignoreCompassTimer) { |
v = 64 + (maxControl[PITCH] + maxControl[ROLL]) / 8; |
// yawGyroHeading - compassCourse on a -180..179 degree interval. |
r = ((540 + yawGyroHeading / GYRO_DEG_FACTOR_YAW - compassCourse) % 360) - 180; |
r |
= ((540 + yawGyroHeading / GYRO_DEG_FACTOR_YAW - compassCourse) |
% 360) - 180; |
v = (r * w) / v; // align to compass course |
// limit yaw rate |
w = 3 * dynamicParams.CompassYawEffect; |
/branches/dongfang_FC_rewrite/attitudeControl.c |
---|
8,39 → 8,40 |
#include "rc.h" |
// = cos^2(45 degs). |
const int32_t MINPROJECTION = (int32_t)MATH_UNIT_FACTOR * MATH_UNIT_FACTOR / 2; |
const int32_t MINPROJECTION = (int32_t) MATH_UNIT_FACTOR * MATH_UNIT_FACTOR / 2; |
// Takes 380 - 400 usec. Way too slow. |
// With static MINPROJECTION: 220 usec. |
uint16_t AC_getThrottle(uint16_t throttle) { |
int32_t projection; |
int32_t projection; |
// part1 start: 150 usec |
// It's factor (int32_t)MATH_UNIT_FACTOR^2 too high. |
projection = (int32_t)int_cos(angle[PITCH]) * (int32_t)int_cos(angle[ROLL]); |
// part1 end. |
// part1 start: 150 usec |
// It's factor (int32_t)MATH_UNIT_FACTOR^2 too high. |
projection = (int32_t) int_cos(angle[PITCH]) * (int32_t) int_cos(angle[ROLL]); |
// part1 end. |
uint8_t effect = dynamicParams.UserParams[2]; // Userparam 3 |
int16_t deltaThrottle; |
uint8_t effect = dynamicParams.UserParams[2]; // Userparam 3 |
int16_t deltaThrottle; |
if (projection < MINPROJECTION && projection >= 0) { |
// projection = MINPROJECTION; |
deltaThrottle = 0; |
} else if (projection >- MINPROJECTION && projection<0) { |
// projection = -MINPROJECITON; |
deltaThrottle = 0; |
} else |
/* |
* We need delta throttle = constant/projection1 |
* (constant * MATH_UNIT_FACTOR^2) / projection. |
*/ |
deltaThrottle = ((int32_t)effect * (int32_t)MATH_UNIT_FACTOR * (int32_t)MATH_UNIT_FACTOR) / (projection / 10) - effect * 10; |
// DebugOut.Analog[13] = deltaThrottle; |
if (projection < MINPROJECTION && projection >= 0) { |
// projection = MINPROJECTION; |
deltaThrottle = 0; |
} else if (projection > -MINPROJECTION && projection < 0) { |
// projection = -MINPROJECITON; |
deltaThrottle = 0; |
} else |
/* |
* We need delta throttle = constant/projection1 |
* (constant * MATH_UNIT_FACTOR^2) / projection. |
*/ |
deltaThrottle = ((int32_t) effect * (int32_t) MATH_UNIT_FACTOR |
* (int32_t) MATH_UNIT_FACTOR) / (projection / 10) - effect * 10; |
// DebugOut.Analog[13] = deltaThrottle; |
return throttle + deltaThrottle; |
return throttle + deltaThrottle; |
} |
/* |
har: R = e * k/p |
vil R = e * ( 1 - k/p ) |
= e - ek/p |
*/ |
har: R = e * k/p |
vil R = e * ( 1 - k/p ) |
= e - ek/p |
*/ |
/branches/dongfang_FC_rewrite/commands.c |
---|
57,69 → 57,70 |
#include "attitude.h" |
void commands_handleCommands(void) { |
/* |
* Get the current command (start/stop motors, calibrate), if any. |
*/ |
uint8_t command = controlMixer_getCommand(); |
uint8_t repeated = controlMixer_isCommandRepeated(); |
uint8_t argument = controlMixer_getArgument(); |
/* |
* Get the current command (start/stop motors, calibrate), if any. |
*/ |
uint8_t command = controlMixer_getCommand(); |
uint8_t repeated = controlMixer_isCommandRepeated(); |
uint8_t argument = controlMixer_getArgument(); |
if(!(MKFlags & MKFLAG_MOTOR_RUN)) { |
if (command == COMMAND_GYROCAL && !repeated) { |
// Run gyro calibration but do not repeat it. |
GRN_OFF; |
// TODO: out of here. Anyway, MKFLAG_MOTOR_RUN is cleared. Not enough? |
// isFlying = 0; |
// check roll/pitch stick position |
// if pitch stick is top or roll stick is left or right --> change parameter setting |
// according to roll/pitch stick position |
if (!(MKFlags & MKFLAG_MOTOR_RUN)) { |
if (command == COMMAND_GYROCAL && !repeated) { |
// Run gyro calibration but do not repeat it. |
GRN_OFF; |
if (argument < 6) { |
// Gyro calinbration, with or without selecting a new parameter-set. |
if(argument > 0 && argument < 6) { |
// A valid parameter-set (1..5) was chosen - use it. |
setActiveParamSet(argument); |
} |
ParamSet_ReadFromEEProm(getActiveParamSet()); |
attitude_setNeutral(); |
flight_setNeutral(); |
controlMixer_setNeutral(); |
beepNumber(getActiveParamSet()); |
} else if(staticParams.GlobalConfig & (CFG_COMPASS_ACTIVE | CFG_GPS_ACTIVE) && argument == 7) { |
// If right stick is centered and down |
// TODO: Out of here! State machine instead. |
compassCalState = 1; |
beep(1000); |
// TODO: out of here. Anyway, MKFLAG_MOTOR_RUN is cleared. Not enough? |
// isFlying = 0; |
// check roll/pitch stick position |
// if pitch stick is top or roll stick is left or right --> change parameter setting |
// according to roll/pitch stick position |
if (argument < 6) { |
// Gyro calinbration, with or without selecting a new parameter-set. |
if (argument > 0 && argument < 6) { |
// A valid parameter-set (1..5) was chosen - use it. |
setActiveParamSet(argument); |
} |
ParamSet_ReadFromEEProm(getActiveParamSet()); |
attitude_setNeutral(); |
flight_setNeutral(); |
controlMixer_setNeutral(); |
beepNumber(getActiveParamSet()); |
} else if (staticParams.GlobalConfig & (CFG_COMPASS_ACTIVE |
| CFG_GPS_ACTIVE) && argument == 7) { |
// If right stick is centered and down |
// TODO: Out of here! State machine instead. |
compassCalState = 1; |
beep(1000); |
} |
} |
// save the ACC neutral setting to eeprom |
else { |
if (command == COMMAND_ACCCAL && !repeated) { |
// Run gyro and acc. meter calibration but do not repeat it. |
GRN_OFF; |
analog_calibrateAcc(); |
attitude_setNeutral(); |
flight_setNeutral(); |
controlMixer_setNeutral(); |
beepNumber(getActiveParamSet()); |
} |
} |
} // end !MOTOR_RUN condition. |
if (command == COMMAND_START) { |
isFlying = 1; // TODO: Really???? |
// if (!controlMixer_isCommandRepeated()) { |
// attitude_startDynamicCalibration(); // Try sense the effect of the motors on sensors. |
MKFlags |= (MKFLAG_MOTOR_RUN | MKFLAG_START); // set flag RUN and START. TODO: Is that START flag used at all??? |
// } else { // Pilot is holding stick, ever after motor start. Continue to sense the effect of the motors on sensors. |
// attitude_continueDynamicCalibration(); |
// setPointYaw = 0; |
// IPartPitch = 0; |
// IPartRoll = 0; |
// } |
} else if (command == COMMAND_STOP) { |
isFlying = 0; |
MKFlags &= ~(MKFLAG_MOTOR_RUN); |
} |
} |
// save the ACC neutral setting to eeprom |
else { |
if(command == COMMAND_ACCCAL && !repeated) { |
// Run gyro and acc. meter calibration but do not repeat it. |
GRN_OFF; |
analog_calibrateAcc(); |
attitude_setNeutral(); |
flight_setNeutral(); |
controlMixer_setNeutral(); |
beepNumber(getActiveParamSet()); |
} |
} |
} // end !MOTOR_RUN condition. |
if (command == COMMAND_START) { |
isFlying = 1; // TODO: Really???? |
// if (!controlMixer_isCommandRepeated()) { |
// attitude_startDynamicCalibration(); // Try sense the effect of the motors on sensors. |
MKFlags |= (MKFLAG_MOTOR_RUN | MKFLAG_START); // set flag RUN and START. TODO: Is that START flag used at all??? |
// } else { // Pilot is holding stick, ever after motor start. Continue to sense the effect of the motors on sensors. |
// attitude_continueDynamicCalibration(); |
// setPointYaw = 0; |
// IPartPitch = 0; |
// IPartRoll = 0; |
// } |
} else if (command == COMMAND_STOP) { |
isFlying = 0; |
MKFlags &= ~(MKFLAG_MOTOR_RUN); |
} |
} |
/branches/dongfang_FC_rewrite/configuration.h |
---|
5,129 → 5,129 |
#include <avr/io.h> |
typedef struct { |
/*PMM*/ uint8_t HeightD; |
/* P */ uint8_t MaxHeight; |
/*PMM*/ uint8_t HeightP; |
/* P */ uint8_t Height_ACC_Effect; |
/* P */ uint8_t CompassYawEffect; |
/* P */ uint8_t GyroD; |
/*PMM*/ uint8_t GyroP; |
/* P */ uint8_t GyroI; |
/* Never used */ uint8_t StickYawP; |
/* P */ uint8_t IFactor; |
/* P */ uint8_t UserParams[8]; |
/* P */ uint8_t ServoPitchControl; |
/* P */ uint8_t LoopGasLimit; |
/* P */ uint8_t AxisCoupling1; |
/* P */ uint8_t AxisCoupling2; |
/* P */ uint8_t AxisCouplingYawCorrection; |
/* P */ uint8_t DynamicStability; |
/* P */ uint8_t ExternalControl; |
/*PMM*/ uint8_t J16Timing; |
/*PMM*/ uint8_t J17Timing; |
/* P */ uint8_t NaviGpsModeControl; |
/* P */ uint8_t NaviGpsGain; |
/* P */ uint8_t NaviGpsP; |
/* P */ uint8_t NaviGpsI; |
/* P */ uint8_t NaviGpsD; |
/* P */ uint8_t NaviGpsACC; |
/*PMM*/ uint8_t NaviOperatingRadius; |
/* P */ uint8_t NaviWindCorrection; |
/* P */ uint8_t NaviSpeedCompensation; |
int8_t KalmanK; |
int8_t KalmanMaxDrift; |
int8_t KalmanMaxFusion; |
/*PMM*/uint8_t HeightD; |
/* P */uint8_t MaxHeight; |
/*PMM*/uint8_t HeightP; |
/* P */uint8_t Height_ACC_Effect; |
/* P */uint8_t CompassYawEffect; |
/* P */uint8_t GyroD; |
/*PMM*/uint8_t GyroP; |
/* P */uint8_t GyroI; |
/* Never used */uint8_t StickYawP; |
/* P */uint8_t IFactor; |
/* P */uint8_t UserParams[8]; |
/* P */uint8_t ServoPitchControl; |
/* P */uint8_t LoopGasLimit; |
/* P */uint8_t AxisCoupling1; |
/* P */uint8_t AxisCoupling2; |
/* P */uint8_t AxisCouplingYawCorrection; |
/* P */uint8_t DynamicStability; |
/* P */uint8_t ExternalControl; |
/*PMM*/uint8_t J16Timing; |
/*PMM*/uint8_t J17Timing; |
/* P */uint8_t NaviGpsModeControl; |
/* P */uint8_t NaviGpsGain; |
/* P */uint8_t NaviGpsP; |
/* P */uint8_t NaviGpsI; |
/* P */uint8_t NaviGpsD; |
/* P */uint8_t NaviGpsACC; |
/*PMM*/uint8_t NaviOperatingRadius; |
/* P */uint8_t NaviWindCorrection; |
/* P */uint8_t NaviSpeedCompensation; |
int8_t KalmanK; |
int8_t KalmanMaxDrift; |
int8_t KalmanMaxFusion; |
} dynamicParam_t; |
extern dynamicParam_t dynamicParams; |
typedef struct { |
uint8_t sourceIdx, targetIdx; |
uint8_t min, max; |
uint8_t sourceIdx, targetIdx; |
uint8_t min, max; |
} MMXLATION; |
typedef struct { |
uint8_t sourceIdx, targetIdx; |
uint8_t sourceIdx, targetIdx; |
} XLATION; |
// values above 250 representing poti1 to poti4 |
typedef struct { |
uint8_t ChannelAssignment[8]; // see upper defines for details |
uint8_t GlobalConfig; // see upper defines for bitcoding |
uint8_t HeightMinGas; // Value : 0-100 |
uint8_t HeightD; // Value : 0-250 |
uint8_t MaxHeight; // Value : 0-32 |
uint8_t HeightP; // Value : 0-32 |
uint8_t Height_Gain; // Value : 0-50 |
uint8_t Height_ACC_Effect; // Value : 0-250 |
uint8_t StickP; // Value : 1-6 |
uint8_t StickD; // Value : 0-64 |
uint8_t StickYawP; // Value : 1-20 |
uint8_t MinThrottle; // Value : 0-32 |
uint8_t MaxThrottle; // Value : 33-250 |
uint8_t GyroAccFactor; // Value : 1-64 |
uint8_t CompassYawEffect; // Value : 0-32 |
uint8_t GyroP; // Value : 10-250 |
uint8_t GyroI; // Value : 0-250 |
uint8_t GyroD; // Value : 0-250 |
uint8_t LowVoltageWarning; // Value : 0-250 |
uint8_t EmergencyGas; // Value : 0-250 //Gaswert bei Emp�ngsverlust |
uint8_t EmergencyGasDuration; // Value : 0-250 // Zeitbis auf EmergencyGas geschaltet wird, wg. Rx-Problemen |
uint8_t Unused0; // |
uint8_t IFactor; // Value : 0-250 |
uint8_t UserParams1[4]; // Value : 0-250 |
/* |
uint8_t UserParam2; // Value : 0-250 |
uint8_t UserParam3; // Value : 0-250 |
uint8_t UserParam4; // Value : 0-250 |
*/ |
uint8_t ServoPitchControl; // Value : 0-250 // Stellung des Servos |
uint8_t ServoPitchComp; // Value : 0-250 // Einfluss Gyro/Servo |
uint8_t ServoPitchMin; // Value : 0-250 // Anschlag |
uint8_t ServoPitchMax; // Value : 0-250 // Anschlag |
uint8_t ServoRefresh; // Value: 0-250 // Refreshrate of servo pwm output |
uint8_t LoopGasLimit; // Value: 0-250 max. Gas w�hrend Looping |
uint8_t LoopThreshold; // Value: 0-250 Schwelle f�r Stickausschlag |
uint8_t LoopHysteresis; // Value: 0-250 Hysterese f�r Stickausschlag |
uint8_t AxisCoupling1; // Value: 0-250 Faktor, mit dem Yaw die Achsen Roll und Nick koppelt (NickRollMitkopplung) |
uint8_t AxisCoupling2; // Value: 0-250 Faktor, mit dem Nick und Roll verkoppelt werden |
uint8_t ChannelAssignment[8]; // see upper defines for details |
uint8_t GlobalConfig; // see upper defines for bitcoding |
uint8_t HeightMinGas; // Value : 0-100 |
uint8_t HeightD; // Value : 0-250 |
uint8_t MaxHeight; // Value : 0-32 |
uint8_t HeightP; // Value : 0-32 |
uint8_t Height_Gain; // Value : 0-50 |
uint8_t Height_ACC_Effect; // Value : 0-250 |
uint8_t StickP; // Value : 1-6 |
uint8_t StickD; // Value : 0-64 |
uint8_t StickYawP; // Value : 1-20 |
uint8_t MinThrottle; // Value : 0-32 |
uint8_t MaxThrottle; // Value : 33-250 |
uint8_t GyroAccFactor; // Value : 1-64 |
uint8_t CompassYawEffect; // Value : 0-32 |
uint8_t GyroP; // Value : 10-250 |
uint8_t GyroI; // Value : 0-250 |
uint8_t GyroD; // Value : 0-250 |
uint8_t LowVoltageWarning; // Value : 0-250 |
uint8_t EmergencyGas; // Value : 0-250 //Gaswert bei Emp�ngsverlust |
uint8_t EmergencyGasDuration; // Value : 0-250 // Zeitbis auf EmergencyGas geschaltet wird, wg. Rx-Problemen |
uint8_t Unused0; // |
uint8_t IFactor; // Value : 0-250 |
uint8_t UserParams1[4]; // Value : 0-250 |
/* |
uint8_t UserParam2; // Value : 0-250 |
uint8_t UserParam3; // Value : 0-250 |
uint8_t UserParam4; // Value : 0-250 |
*/ |
uint8_t ServoPitchControl; // Value : 0-250 // Stellung des Servos |
uint8_t ServoPitchComp; // Value : 0-250 // Einfluss Gyro/Servo |
uint8_t ServoPitchMin; // Value : 0-250 // Anschlag |
uint8_t ServoPitchMax; // Value : 0-250 // Anschlag |
uint8_t ServoRefresh; // Value: 0-250 // Refreshrate of servo pwm output |
uint8_t LoopGasLimit; // Value: 0-250 max. Gas w�hrend Looping |
uint8_t LoopThreshold; // Value: 0-250 Schwelle f�r Stickausschlag |
uint8_t LoopHysteresis; // Value: 0-250 Hysterese f�r Stickausschlag |
uint8_t AxisCoupling1; // Value: 0-250 Faktor, mit dem Yaw die Achsen Roll und Nick koppelt (NickRollMitkopplung) |
uint8_t AxisCoupling2; // Value: 0-250 Faktor, mit dem Nick und Roll verkoppelt werden |
uint8_t AxisCouplingYawCorrection;// Value: 0-250 Faktor, mit dem Nick und Roll verkoppelt werden |
uint8_t AngleTurnOverPitch; // Value: 0-250 180�-Punkt |
uint8_t AngleTurnOverRoll; // Value: 0-250 180�-Punkt |
uint8_t GyroAccTrim; // 1/k (Koppel_ACC_Wirkung) |
uint8_t DriftComp; // limit for gyrodrift compensation |
uint8_t DynamicStability; // PID limit for Attitude controller |
uint8_t UserParams2[4]; // Value : 0-250 |
/* |
uint8_t UserParam6; // Value : 0-250 |
uint8_t UserParam7; // Value : 0-250 |
uint8_t UserParam8; // Value : 0-250 |
*/ |
uint8_t J16Bitmask; // for the J16 Output |
uint8_t J16Timing; // for the J16 Output |
uint8_t J17Bitmask; // for the J17 Output |
uint8_t J17Timing; // for the J17 Output |
uint8_t NaviGpsModeControl; // Parameters for the Naviboard |
uint8_t NaviGpsGain; // overall gain for GPS-PID controller |
uint8_t NaviGpsP; // P gain for GPS-PID controller |
uint8_t NaviGpsI; // I gain for GPS-PID controller |
uint8_t NaviGpsD; // D gain for GPS-PID controller |
uint8_t NaviGpsPLimit; // P limit for GPS-PID controller |
uint8_t NaviGpsILimit; // I limit for GPS-PID controller |
uint8_t NaviGpsDLimit; // D limit for GPS-PID controller |
uint8_t NaviGpsACC; // ACC gain for GPS-PID controller |
uint8_t NaviGpsMinSat; // number of sattelites neccesary for GPS functions |
uint8_t NaviStickThreshold; // activation threshild for detection of manual stick movements |
uint8_t NaviWindCorrection; // streng of wind course correction |
uint8_t NaviSpeedCompensation; // D gain fefore position hold login |
uint8_t NaviOperatingRadius; // Radius limit in m around start position for GPS flights |
uint8_t NaviAngleLimitation; // limitation of attitude angle controlled by the gps algorithm |
uint8_t NaviPHLoginTime; // position hold logintimeout |
uint8_t ExternalControl; // for serial Control |
uint8_t BitConfig; // see upper defines for bitcoding |
uint8_t ServoPitchCompInvert; // Value : 0-250 0 oder 1 // WICHTIG!!! am Ende lassen |
uint8_t AngleTurnOverPitch; // Value: 0-250 180�-Punkt |
uint8_t AngleTurnOverRoll; // Value: 0-250 180�-Punkt |
uint8_t GyroAccTrim; // 1/k (Koppel_ACC_Wirkung) |
uint8_t DriftComp; // limit for gyrodrift compensation |
uint8_t DynamicStability; // PID limit for Attitude controller |
uint8_t UserParams2[4]; // Value : 0-250 |
/* |
uint8_t UserParam6; // Value : 0-250 |
uint8_t UserParam7; // Value : 0-250 |
uint8_t UserParam8; // Value : 0-250 |
*/ |
uint8_t J16Bitmask; // for the J16 Output |
uint8_t J16Timing; // for the J16 Output |
uint8_t J17Bitmask; // for the J17 Output |
uint8_t J17Timing; // for the J17 Output |
uint8_t NaviGpsModeControl; // Parameters for the Naviboard |
uint8_t NaviGpsGain; // overall gain for GPS-PID controller |
uint8_t NaviGpsP; // P gain for GPS-PID controller |
uint8_t NaviGpsI; // I gain for GPS-PID controller |
uint8_t NaviGpsD; // D gain for GPS-PID controller |
uint8_t NaviGpsPLimit; // P limit for GPS-PID controller |
uint8_t NaviGpsILimit; // I limit for GPS-PID controller |
uint8_t NaviGpsDLimit; // D limit for GPS-PID controller |
uint8_t NaviGpsACC; // ACC gain for GPS-PID controller |
uint8_t NaviGpsMinSat; // number of sattelites neccesary for GPS functions |
uint8_t NaviStickThreshold; // activation threshild for detection of manual stick movements |
uint8_t NaviWindCorrection; // streng of wind course correction |
uint8_t NaviSpeedCompensation; // D gain fefore position hold login |
uint8_t NaviOperatingRadius; // Radius limit in m around start position for GPS flights |
uint8_t NaviAngleLimitation; // limitation of attitude angle controlled by the gps algorithm |
uint8_t NaviPHLoginTime; // position hold logintimeout |
uint8_t ExternalControl; // for serial Control |
uint8_t BitConfig; // see upper defines for bitcoding |
uint8_t ServoPitchCompInvert; // Value : 0-250 0 oder 1 // WICHTIG!!! am Ende lassen |
uint8_t Reserved[4]; |
int8_t Name[12]; |
} paramset_t; |
} paramset_t; |
#define PARAMSET_STRUCT_LEN sizeof(paramset_t) |
134,10 → 134,10 |
extern paramset_t staticParams; |
typedef struct { |
uint8_t Revision; |
int8_t Name[12]; |
int8_t Motor[16][4]; |
} __attribute__((packed)) MixerTable_t; |
uint8_t Revision; |
int8_t Name[12]; |
int8_t Motor[16][4]; |
}__attribute__((packed)) MixerTable_t; |
extern MixerTable_t Mixer; |
/branches/dongfang_FC_rewrite/controlMixer.c |
---|
60,13 → 60,13 |
#include "commands.h" |
#include "output.h" |
uint16_t maxControl[2] = {0,0}; |
int16_t control[2] = {0,0}; |
uint16_t maxControl[2] = { 0, 0 }; |
int16_t control[2] = { 0, 0 }; |
int16_t controlYaw = 0, controlThrottle = 0; |
uint8_t looping = 0; |
// Internal variables for reading commands made with an R/C stick. |
uint8_t lastCommand = COMMAND_NONE; |
uint8_t lastCommand = COMMAND_NONE; |
uint8_t lastArgument; |
uint8_t isCommandRepeated = 0; |
80,7 → 80,7 |
* (read: Custom MK RC project) |
*/ |
uint8_t controlMixer_getArgument(void) { |
return lastArgument; |
return lastArgument; |
} |
/* |
88,16 → 88,16 |
* than the R/C (read: Custom MK R/C project) |
*/ |
uint8_t controlMixer_getCommand(void) { |
return lastCommand; |
return lastCommand; |
} |
uint8_t controlMixer_isCommandRepeated(void) { |
return isCommandRepeated; |
return isCommandRepeated; |
} |
void controlMixer_setNeutral() { |
EC_setNeutral(); |
HC_setGround(); |
EC_setNeutral(); |
HC_setGround(); |
} |
/* |
105,10 → 105,10 |
* No slew rate limitation. |
*/ |
void controlMixer_initVariables(void) { |
uint8_t i; |
for (i=0; i<8; i++) { |
variables[i] = RC_getVariable(i); |
} |
uint8_t i; |
for (i = 0; i < 8; i++) { |
variables[i] = RC_getVariable(i); |
} |
} |
/* |
116,20 → 116,24 |
* TODO: It assumes R/C as source. Not necessarily true. |
*/ |
void controlMixer_updateVariables(void) { |
uint8_t i; |
int16_t targetvalue; |
for (i=0; i<8; i++) { |
targetvalue = RC_getVariable(i); |
if (targetvalue < 0) targetvalue = 0; |
if (variables[i] < targetvalue && variables[i] < 255) variables[i]++; else if(variables[i] > 0 && variables[i] > targetvalue) variables[i]--; |
} |
uint8_t i; |
int16_t targetvalue; |
for (i = 0; i < 8; i++) { |
targetvalue = RC_getVariable(i); |
if (targetvalue < 0) |
targetvalue = 0; |
if (variables[i] < targetvalue && variables[i] < 255) |
variables[i]++; |
else if (variables[i] > 0 && variables[i] > targetvalue) |
variables[i]--; |
} |
} |
uint8_t controlMixer_getSignalQuality(void) { |
uint8_t rcQ = RC_getSignalQuality(); |
uint8_t ecQ = EC_getSignalQuality(); |
// This needs not be the only correct solution... |
return rcQ > ecQ ? rcQ : ecQ; |
uint8_t rcQ = RC_getSignalQuality(); |
uint8_t ecQ = EC_getSignalQuality(); |
// This needs not be the only correct solution... |
return rcQ > ecQ ? rcQ : ecQ; |
} |
/* |
136,87 → 140,98 |
* Update the variables indicating stick position from the sum of R/C, GPS and external control. |
*/ |
void controlMixer_update(void) { |
// calculate Stick inputs by rc channels (P) and changing of rc channels (D) |
// TODO: If no signal --> zero. |
uint8_t axis; |
// calculate Stick inputs by rc channels (P) and changing of rc channels (D) |
// TODO: If no signal --> zero. |
uint8_t axis; |
// takes almost no time... |
RC_update(); |
// takes almost no time... |
EC_update(); |
// takes almost no time... |
RC_update(); |
// takes about 80 usec. |
HC_update(); |
// takes almost no time... |
EC_update(); |
int16_t* RC_PRTY = RC_getPRTY(); |
int16_t* EC_PRTY = EC_getPRTY(); |
// takes about 80 usec. |
HC_update(); |
control[PITCH] = RC_PRTY[CONTROL_PITCH] + EC_PRTY[CONTROL_PITCH]; |
control[ROLL] = RC_PRTY[CONTROL_ROLL] + EC_PRTY[CONTROL_ROLL]; |
// This can be a CPU time killer if the function implementations are inefficient. |
controlThrottle = HC_getThrottle(AC_getThrottle(RC_PRTY[CONTROL_THROTTLE] + EC_PRTY[CONTROL_THROTTLE])); |
controlYaw = RC_PRTY[CONTROL_YAW] + EC_PRTY[CONTROL_YAW]; |
int16_t* RC_PRTY = RC_getPRTY(); |
int16_t* EC_PRTY = EC_getPRTY(); |
DebugOut.Analog[12] = control[PITCH]; |
DebugOut.Analog[13] = control[ROLL]; |
//DebugOut.Analog[26] = controlYaw; |
control[PITCH] = RC_PRTY[CONTROL_PITCH] + EC_PRTY[CONTROL_PITCH]; |
control[ROLL] = RC_PRTY[CONTROL_ROLL] + EC_PRTY[CONTROL_ROLL]; |
// This can be a CPU time killer if the function implementations are inefficient. |
controlThrottle = HC_getThrottle(AC_getThrottle(RC_PRTY[CONTROL_THROTTLE] |
+ EC_PRTY[CONTROL_THROTTLE])); |
controlYaw = RC_PRTY[CONTROL_YAW] + EC_PRTY[CONTROL_YAW]; |
if (controlMixer_getSignalQuality() >= SIGNAL_GOOD) { |
controlMixer_updateVariables(); |
configuration_applyVariablesToParams(); |
looping = RC_getLooping(looping); |
} else { // Signal is not OK |
// Could handle switch to emergency flight here. |
// throttle is handled elsewhere. |
looping = 0; |
} |
DebugOut.Analog[12] = control[PITCH]; |
DebugOut.Analog[13] = control[ROLL]; |
//DebugOut.Analog[26] = controlYaw; |
// part1a end. |
if (controlMixer_getSignalQuality() >= SIGNAL_GOOD) { |
controlMixer_updateVariables(); |
configuration_applyVariablesToParams(); |
looping = RC_getLooping(looping); |
} else { // Signal is not OK |
// Could handle switch to emergency flight here. |
// throttle is handled elsewhere. |
looping = 0; |
} |
/* This is not really necessary with the dead-gap feature on all sticks (see rc.c) |
if(staticParams.GlobalConfig & (CFG_COMPASS_ACTIVE | CFG_GPS_ACTIVE)) { |
if (controlYaw > 2) controlYaw-= 2; |
else if (controlYaw< -2) controlYaw += 2; |
else controlYaw = 0; |
} |
*/ |
// part1a end. |
/* |
* Record maxima |
*/ |
for (axis=PITCH; axis<=ROLL; axis++) { |
if(abs(control[axis] / CONTROL_SCALING) > maxControl[axis]) { |
maxControl[axis] = abs(control[axis]) / CONTROL_SCALING; |
if(maxControl[axis] > 100) maxControl[axis] = 100; |
} else if (maxControl[axis]) maxControl[axis]--; |
} |
/* This is not really necessary with the dead-gap feature on all sticks (see rc.c) |
if(staticParams.GlobalConfig & (CFG_COMPASS_ACTIVE | CFG_GPS_ACTIVE)) { |
if (controlYaw > 2) controlYaw-= 2; |
else if (controlYaw< -2) controlYaw += 2; |
else controlYaw = 0; |
} |
*/ |
uint8_t rcCommand = (RC_getSignalQuality() >= SIGNAL_OK) ? RC_getCommand() : COMMAND_NONE; |
uint8_t ecCommand = (EC_getSignalQuality() >= SIGNAL_OK) ? EC_getCommand() : COMMAND_NONE; |
if (rcCommand != COMMAND_NONE) { |
isCommandRepeated = (lastCommand == rcCommand); |
lastCommand = rcCommand; |
lastArgument = RC_getArgument(); |
} else if (ecCommand != COMMAND_NONE) { |
isCommandRepeated = (lastCommand == ecCommand); |
lastCommand = ecCommand; |
lastArgument = EC_getArgument(); |
} else { |
// Both sources have no command, or one or both are out. |
// Just set to false. There is no reason to check if the none-command was repeated anyway. |
isCommandRepeated = 0; |
lastCommand = COMMAND_NONE; |
} |
/* |
* Record maxima |
*/ |
for (axis = PITCH; axis <= ROLL; axis++) { |
if (abs(control[axis] / CONTROL_SCALING) > maxControl[axis]) { |
maxControl[axis] = abs(control[axis]) / CONTROL_SCALING; |
if (maxControl[axis] > 100) |
maxControl[axis] = 100; |
} else if (maxControl[axis]) |
maxControl[axis]--; |
} |
if (isCommandRepeated) DebugOut.Digital[0] |= DEBUG_COMMANDREPEATED; else DebugOut.Digital[0] &= ~DEBUG_COMMANDREPEATED; |
if (rcCommand) DebugOut.Digital[1] |= DEBUG_COMMANDREPEATED; else DebugOut.Digital[1] &= ~DEBUG_COMMANDREPEATED; |
uint8_t rcCommand = (RC_getSignalQuality() >= SIGNAL_OK) ? RC_getCommand() |
: COMMAND_NONE; |
uint8_t ecCommand = (EC_getSignalQuality() >= SIGNAL_OK) ? EC_getCommand() |
: COMMAND_NONE; |
// part1 end. |
if (rcCommand != COMMAND_NONE) { |
isCommandRepeated = (lastCommand == rcCommand); |
lastCommand = rcCommand; |
lastArgument = RC_getArgument(); |
} else if (ecCommand != COMMAND_NONE) { |
isCommandRepeated = (lastCommand == ecCommand); |
lastCommand = ecCommand; |
lastArgument = EC_getArgument(); |
} else { |
// Both sources have no command, or one or both are out. |
// Just set to false. There is no reason to check if the none-command was repeated anyway. |
isCommandRepeated = 0; |
lastCommand = COMMAND_NONE; |
} |
if (isCommandRepeated) |
DebugOut.Digital[0] |= DEBUG_COMMANDREPEATED; |
else |
DebugOut.Digital[0] &= ~DEBUG_COMMANDREPEATED; |
if (rcCommand) |
DebugOut.Digital[1] |= DEBUG_COMMANDREPEATED; |
else |
DebugOut.Digital[1] &= ~DEBUG_COMMANDREPEATED; |
// part1 end. |
} |
// TODO: Integrate into command system. |
uint8_t controlMixer_testCompassCalState(void) { |
return RC_testCompassCalState(); |
return RC_testCompassCalState(); |
} |
/branches/dongfang_FC_rewrite/controlMixer.h |
---|
7,7 → 7,7 |
* each other, the priorities between them and the behavior in case that one fails is simplified, |
* and all in one place. |
*/ |
/* |
* Signal qualities, used to determine the availability of a control. |
* NO_SIGNAL means there was never a signal. SIGNAL_LOST that there was a signal, but it was lost. |
47,25 → 47,25 |
* same interface. This struct of code pointers is used like an abstract class |
* definition from object-oriented languages, and all control input implementations |
* will declare an instance of the stuct (=implementation of the abstract class). |
*/ |
*/ |
typedef struct { |
/* Get the pitch input in the nominal range [-STICK_RANGE, STICK_RANGE]. */ |
int16_t(*getPitch)(void); |
/* Get the pitch input in the nominal range [-STICK_RANGE, STICK_RANGE]. */ |
int16_t(*getPitch)(void); |
/* Get the roll input in the nominal range [-STICK_RANGE, STICK_RANGE]. */ |
int16_t(*getRoll)(void); |
/* Get the yaw input in the nominal range [-STICK_RANGE, STICK_RANGE]. */ |
int16_t(*getYaw)(void); |
/* Get the throttle input in the nominal range [0, THROTTLE_RANGE]. */ |
uint16_t(*getThrottle)(void); |
int16_t(*getRoll)(void); |
/* Signal quality, by the above SIGNAL_... definitions. */ |
uint8_t (*getSignalQuality)(void); |
/* Get the yaw input in the nominal range [-STICK_RANGE, STICK_RANGE]. */ |
int16_t(*getYaw)(void); |
/* Calibrate sticks to their center positions (only relevant for R/C, really) */ |
void (*calibrate)(void); |
/* Get the throttle input in the nominal range [0, THROTTLE_RANGE]. */ |
uint16_t(*getThrottle)(void); |
/* Signal quality, by the above SIGNAL_... definitions. */ |
uint8_t (*getSignalQuality)(void); |
/* Calibrate sticks to their center positions (only relevant for R/C, really) */ |
void (*calibrate)(void); |
} t_control; |
/* |
/branches/dongfang_FC_rewrite/dongfangMath.c |
---|
2,230 → 2,228 |
#include <inttypes.h> |
#include <avr/pgmspace.h> |
const int16_t SIN_TABLE[] PROGMEM = { |
(int16_t) (0.0 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.01745240643728351 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.03489949670250097 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.05233595624294383 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.0697564737441253 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.08715574274765817 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.10452846326765346 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.12186934340514748 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.13917310096006544 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.15643446504023087 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.17364817766693033 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.1908089953765448 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.20791169081775931 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.224951054343865 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.24192189559966773 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.25881904510252074 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.27563735581699916 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.29237170472273677 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.3090169943749474 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.32556815445715664 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.3420201433256687 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.35836794954530027 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.374606593415912 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.3907311284892737 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.40673664307580015 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.42261826174069944 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.4383711467890774 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.45399049973954675 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.4694715627858908 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.48480962024633706 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.49999999999999994 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.5150380749100542 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.5299192642332049 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.5446390350150271 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.5591929034707469 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.573576436351046 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.5877852522924731 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.6018150231520483 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.6156614753256582 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.6293203910498374 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.6427876096865393 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.6560590289905072 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.6691306063588582 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.6819983600624985 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.6946583704589973 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.7071067811865475 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.7193398003386511 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.7313537016191705 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.7431448254773942 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.754709580222772 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.766044443118978 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.7771459614569708 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.788010753606722 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.7986355100472928 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.8090169943749475 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.8191520442889918 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.8290375725550417 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.8386705679454239 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.8480480961564261 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.8571673007021122 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.8660254037844386 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.8746197071393957 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.8829475928589269 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.8910065241883678 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.898794046299167 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.9063077870366499 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.9135454576426009 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.9205048534524403 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.9271838545667874 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.9335804264972017 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.9396926207859083 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.9455185755993167 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.9510565162951535 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.9563047559630354 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.9612616959383189 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.9659258262890683 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.9702957262759965 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.9743700647852352 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.9781476007338056 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.981627183447664 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.984807753012208 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.9876883405951378 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.9902680687415703 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.992546151641322 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.9945218953682733 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.9961946980917455 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.9975640502598242 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.9986295347545738 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.9993908270190958 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.9998476951563913 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (1.0 * MATH_UNIT_FACTOR) }; |
const int16_t SIN_TABLE[] PROGMEM = { (int16_t) (0.0 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.01745240643728351 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.03489949670250097 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.05233595624294383 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.0697564737441253 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.08715574274765817 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.10452846326765346 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.12186934340514748 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.13917310096006544 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.15643446504023087 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.17364817766693033 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.1908089953765448 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.20791169081775931 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.224951054343865 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.24192189559966773 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.25881904510252074 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.27563735581699916 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.29237170472273677 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.3090169943749474 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.32556815445715664 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.3420201433256687 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.35836794954530027 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.374606593415912 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.3907311284892737 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.40673664307580015 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.42261826174069944 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.4383711467890774 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.45399049973954675 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.4694715627858908 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.48480962024633706 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.49999999999999994 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.5150380749100542 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.5299192642332049 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.5446390350150271 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.5591929034707469 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.573576436351046 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.5877852522924731 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.6018150231520483 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.6156614753256582 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.6293203910498374 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.6427876096865393 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.6560590289905072 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.6691306063588582 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.6819983600624985 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.6946583704589973 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.7071067811865475 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.7193398003386511 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.7313537016191705 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.7431448254773942 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.754709580222772 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.766044443118978 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.7771459614569708 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.788010753606722 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.7986355100472928 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.8090169943749475 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.8191520442889918 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.8290375725550417 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.8386705679454239 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.8480480961564261 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.8571673007021122 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.8660254037844386 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.8746197071393957 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.8829475928589269 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.8910065241883678 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.898794046299167 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.9063077870366499 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.9135454576426009 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.9205048534524403 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.9271838545667874 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.9335804264972017 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.9396926207859083 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.9455185755993167 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.9510565162951535 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.9563047559630354 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.9612616959383189 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.9659258262890683 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.9702957262759965 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.9743700647852352 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.9781476007338056 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.981627183447664 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.984807753012208 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.9876883405951378 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.9902680687415703 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.992546151641322 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.9945218953682733 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.9961946980917455 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.9975640502598242 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.9986295347545738 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.9993908270190958 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.9998476951563913 * MATH_UNIT_FACTOR + 0.5), (int16_t) (1.0 |
* MATH_UNIT_FACTOR) }; |
const int16_t TAN_TABLE[] PROGMEM = { |
(int16_t) (0.0 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.017455064928217585 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.03492076949174773 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.0524077792830412 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.06992681194351041 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.08748866352592401 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.10510423526567646 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.1227845609029046 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.14054083470239145 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.15838444032453627 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.17632698070846498 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.19438030913771848 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.2125565616700221 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.23086819112556312 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.24932800284318068 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.2679491924311227 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.2867453857588079 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.3057306814586604 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.3249196962329063 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.3443276132896652 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.36397023426620234 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.3838640350354158 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.4040262258351568 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.4244748162096047 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.4452286853085361 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.4663076581549986 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.48773258856586144 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.5095254494944288 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.5317094316614788 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.554309051452769 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.5773502691896257 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.6008606190275604 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.6248693519093275 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.6494075931975106 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.6745085168424267 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.7002075382097097 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.7265425280053608 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.7535540501027942 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.7812856265067173 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.809784033195007 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.8390996311772799 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.8692867378162265 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.9004040442978399 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.9325150861376615 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.9656887748070739 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.9999999999999999 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (1.0355303137905694 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (1.0723687100246826 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (1.1106125148291928 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (1.1503684072210094 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (1.19175359259421 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (1.234897156535051 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (1.2799416321930788 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (1.3270448216204098 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (1.3763819204711734 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (1.4281480067421144 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (1.4825609685127403 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (1.5398649638145825 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (1.6003345290410504 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (1.6642794823505174 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (1.7320508075688767 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (1.8040477552714236 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (1.8807264653463318 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (1.9626105055051504 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (2.050303841579296 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (2.1445069205095586 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (2.2460367739042164 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (2.355852365823752 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (2.4750868534162964 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (2.6050890646938005 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (2.7474774194546216 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (2.904210877675822 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (3.0776835371752527 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (3.2708526184841404 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (3.4874144438409087 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (3.7320508075688776 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (4.010780933535842 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (4.331475874284157 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (4.704630109478451 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (5.144554015970307 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (5.671281819617707 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (6.313751514675041 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (7.115369722384195 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (8.144346427974593 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (9.514364454222587 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (11.430052302761348 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (14.300666256711896 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (19.08113668772816 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (28.636253282915515 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (57.289961630759876 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (32767) |
}; |
const int16_t TAN_TABLE[] PROGMEM |
= { (int16_t) (0.0 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.017455064928217585 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.03492076949174773 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.0524077792830412 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.06992681194351041 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.08748866352592401 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.10510423526567646 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.1227845609029046 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.14054083470239145 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.15838444032453627 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.17632698070846498 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.19438030913771848 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.2125565616700221 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.23086819112556312 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.24932800284318068 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.2679491924311227 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.2867453857588079 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.3057306814586604 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.3249196962329063 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.3443276132896652 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.36397023426620234 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.3838640350354158 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.4040262258351568 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.4244748162096047 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.4452286853085361 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.4663076581549986 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.48773258856586144 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.5095254494944288 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.5317094316614788 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.554309051452769 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.5773502691896257 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.6008606190275604 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.6248693519093275 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.6494075931975106 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.6745085168424267 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.7002075382097097 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.7265425280053608 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.7535540501027942 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.7812856265067173 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.809784033195007 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.8390996311772799 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.8692867378162265 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.9004040442978399 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.9325150861376615 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.9656887748070739 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (0.9999999999999999 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (1.0355303137905694 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (1.0723687100246826 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (1.1106125148291928 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (1.1503684072210094 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (1.19175359259421 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (1.234897156535051 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (1.2799416321930788 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (1.3270448216204098 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (1.3763819204711734 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (1.4281480067421144 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (1.4825609685127403 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (1.5398649638145825 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (1.6003345290410504 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (1.6642794823505174 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (1.7320508075688767 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (1.8040477552714236 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (1.8807264653463318 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (1.9626105055051504 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (2.050303841579296 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (2.1445069205095586 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (2.2460367739042164 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (2.355852365823752 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (2.4750868534162964 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (2.6050890646938005 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (2.7474774194546216 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (2.904210877675822 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (3.0776835371752527 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (3.2708526184841404 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (3.4874144438409087 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (3.7320508075688776 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (4.010780933535842 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (4.331475874284157 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (4.704630109478451 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (5.144554015970307 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (5.671281819617707 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (6.313751514675041 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (7.115369722384195 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (8.144346427974593 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (9.514364454222587 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (11.430052302761348 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (14.300666256711896 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (19.08113668772816 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (28.636253282915515 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (57.289961630759876 * MATH_UNIT_FACTOR + 0.5), |
(int16_t) (32767) }; |
int16_t int_sin(int32_t arg) { |
int8_t sign; |
int16_t result; |
arg /= MATH_DRG_FACTOR; |
arg %= 360; |
if (arg < 0) { |
arg = -arg; |
sign = -1; |
} else { |
sign = 1; |
} |
if (arg >= 90) { |
arg = 180 - arg; |
} |
result = pgm_read_word(&SIN_TABLE[(uint8_t) arg]); |
return (sign == 1) ? result : -result; |
int8_t sign; |
int16_t result; |
arg /= MATH_DRG_FACTOR; |
arg %= 360; |
if (arg < 0) { |
arg = -arg; |
sign = -1; |
} else { |
sign = 1; |
} |
if (arg >= 90) { |
arg = 180 - arg; |
} |
result = pgm_read_word(&SIN_TABLE[(uint8_t) arg]); |
return (sign == 1) ? result : -result; |
} |
int16_t int_cos(int32_t arg) { |
if (arg > 90L * MATH_DRG_FACTOR) |
return int_sin(arg + (90L - 360L) * MATH_DRG_FACTOR); |
return int_sin(arg + 90L * MATH_DRG_FACTOR); |
if (arg > 90L * MATH_DRG_FACTOR) |
return int_sin(arg + (90L - 360L) * MATH_DRG_FACTOR); |
return int_sin(arg + 90L * MATH_DRG_FACTOR); |
} |
int16_t int_tan(int32_t arg) { |
int8_t sign = 1; |
int16_t result; |
arg /= MATH_DRG_FACTOR; |
if (arg >= 90) { |
arg = 180 - arg; |
sign = -1; |
} else if (arg < -90) { |
arg += 180; |
} else if (arg < 0) { |
arg =- arg; |
sign = -1; |
} |
result = pgm_read_word(&TAN_TABLE[(uint8_t) arg]); |
return (sign == 1) ? result : -result; |
int8_t sign = 1; |
int16_t result; |
arg /= MATH_DRG_FACTOR; |
if (arg >= 90) { |
arg = 180 - arg; |
sign = -1; |
} else if (arg < -90) { |
arg += 180; |
} else if (arg < 0) { |
arg = -arg; |
sign = -1; |
} |
result = pgm_read_word(&TAN_TABLE[(uint8_t) arg]); |
return (sign == 1) ? result : -result; |
} |
/branches/dongfang_FC_rewrite/dsl.c |
---|
2,88 → 2,87 |
// This code has been derived from the implementation of Stefan Engelke. |
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
/* |
Copyright (c) 2008 Stefan Engelke <stefan@tinkerer.eu> |
Copyright (c) 2008 Stefan Engelke <stefan@tinkerer.eu> |
Permission is hereby granted, free of charge, to any person |
obtaining a copy of this software and associated documentation |
files (the "Software"), to deal in the Software without |
restriction, including without limitation the rights to use, copy, |
modify, merge, publish, distribute, sublicense, and/or sell copies |
of the Software, and to permit persons to whom the Software is |
furnished to do so, subject to the following conditions: |
Permission is hereby granted, free of charge, to any person |
obtaining a copy of this software and associated documentation |
files (the "Software"), to deal in the Software without |
restriction, including without limitation the rights to use, copy, |
modify, merge, publish, distribute, sublicense, and/or sell copies |
of the Software, and to permit persons to whom the Software is |
furnished to do so, subject to the following conditions: |
The above copyright notice and this permission notice shall be |
included in all copies or substantial portions of the Software. |
The above copyright notice and this permission notice shall be |
included in all copies or substantial portions of the Software. |
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT |
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, |
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
DEALINGS IN THE SOFTWARE. |
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT |
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, |
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
DEALINGS IN THE SOFTWARE. |
$Id: rcdsl.c 60 2008-08-21 07:50:48Z taser $ |
$Id: rcdsl.c 60 2008-08-21 07:50:48Z taser $ |
RCDSL.H and RCDSL.C is an INOFFICIAL implementation of the |
communication protocol used by DSL receivers of Act Europe. |
The DSL receivers have a serial communication port to connect |
two receivers in diversity mode. Each receiver is sending the |
received servo signals periodically over this port. This fact |
can be used to connect the receiver to the control unit of the |
model via UART instead of evaluating the PPM signal. |
RCDSL.H and RCDSL.C is an INOFFICIAL implementation of the |
communication protocol used by DSL receivers of Act Europe. |
The DSL receivers have a serial communication port to connect |
two receivers in diversity mode. Each receiver is sending the |
received servo signals periodically over this port. This fact |
can be used to connect the receiver to the control unit of the |
model via UART instead of evaluating the PPM signal. |
If you have any questions, fell free to send me an e-mail. |
If you have any questions, fell free to send me an e-mail. |
*/ |
*/ |
/* |
Connection of DSL to SV1 of FC: |
( DSL Pin1 is on side of channel 4 ) |
Connection of DSL to SV1 of FC: |
( DSL Pin1 is on side of channel 4 ) |
1. GND <--> pin 7 (GND) |
2. TXD <--> pin 3 (RXD1 Atmega644p) |
3. RXD <--> pin 4 (TXD1 Atmega644p) optional |
4. 5V <--> pin 2 (5V) |
1. GND <--> pin 7 (GND) |
2. TXD <--> pin 3 (RXD1 Atmega644p) |
3. RXD <--> pin 4 (TXD1 Atmega644p) optional |
4. 5V <--> pin 2 (5V) |
Do not connect the receiver via PPM-Sumsignal output the same time. |
Do not connect the receiver via PPM-Sumsignal output the same time. |
Data are send at every 20 ms @ 38400 Baud 8-N-1 |
Data are send at every 20 ms @ 38400 Baud 8-N-1 |
Data Frame: |0xFF|0xFF|0x1F|FREQALLOC|??|RSSI|VBAT|??|CRC|10|CH0D1|CH0D0|CH1D1|CH1D0|CRC| ...etc |
Data Frame: |0xFF|0xFF|0x1F|FREQALLOC|??|RSSI|VBAT|??|CRC|10|CH0D1|CH0D0|CH1D1|CH1D0|CRC| ...etc |
FREQALLOC = 35, 40, 72 |
RSSI = 0.. 255 // Received signal strength indicator |
VBAT = 0...255 // supply voltage (0.0V.. 7.8V) |
FREQALLOC = 35, 40, 72 |
RSSI = 0.. 255 // Received signal strength indicator |
VBAT = 0...255 // supply voltage (0.0V.. 7.8V) |
Servo Pair: |0x1X|CHXD1|CHXD0|CHX+1D1|CHX+1D0|CRC| |
X is channel index of 1 servo value |
D1D0 is servo value as u16 in range of 7373 (1ms) to 14745 (2ms) |
there are 8 channels submitted, i.e 4 servo pairs |
Servo Pair: |0x1X|CHXD1|CHXD0|CHX+1D1|CHX+1D0|CRC| |
X is channel index of 1 servo value |
D1D0 is servo value as u16 in range of 7373 (1ms) to 14745 (2ms) |
there are 8 channels submitted, i.e 4 servo pairs |
Frame examples with signel received |
Frame examples with signel received |
FFFF 1F23F079A304AD 1036012B1E6F 122AFB2AECB2 142B4D2B4404 1636872B33CE |
FFFF 1F23F079A304AD 1036002B1F6F 122AFE2AEBB0 142B4B2B4406 1636872B33CE |
FFFF 1F23F079A304AD 1035FF2B226E 122AFC2AEAB3 142B4E2B4304 1636882B33CD |
FFFF 1F23F079A304AD 1036022B1E6E 122AFB2AEEB0 142B4A2B4506 1636872B33CE |
FFFF 1F23F079A304AD 1036022B1E6E 122AFE2AEBB0 142B4B2B4406 1636882B33CD |
FFFF 1F23F079A304AD 1036012B1E6F 122AFD2AEAB2 142B4E2B4403 1636862B33CF |
FFFF 1F23F079A304AD 1036032B1D6E 122AFD2AEBB1 142B4C2B4504 1636862B33CF |
FFFF 1F23F079A304AD 1036012B1E6F 122AFB2AECB2 142B4D2B4404 1636872B33CE |
FFFF 1F23F079A304AD 1036002B1F6F 122AFE2AEBB0 142B4B2B4406 1636872B33CE |
FFFF 1F23F079A304AD 1035FF2B226E 122AFC2AEAB3 142B4E2B4304 1636882B33CD |
FFFF 1F23F079A304AD 1036022B1E6E 122AFB2AEEB0 142B4A2B4506 1636872B33CE |
FFFF 1F23F079A304AD 1036022B1E6E 122AFE2AEBB0 142B4B2B4406 1636882B33CD |
FFFF 1F23F079A304AD 1036012B1E6F 122AFD2AEAB2 142B4E2B4403 1636862B33CF |
FFFF 1F23F079A304AD 1036032B1D6E 122AFD2AEBB1 142B4C2B4504 1636862B33CF |
Frame examples with no signal received |
Frame examples with no signal received |
FFFF 1F23F000A30426 |
FFFF 1F23F000A30426 |
FFFF 1F23F000A30426 |
FFFF 1F23F000A30426 |
FFFF 1F23F000A30426 |
FFFF 1F23F000A30426 |
FFFF 1F23F000A30426 |
*/ |
FFFF 1F23F000A30426 |
FFFF 1F23F000A30426 |
FFFF 1F23F000A30426 |
FFFF 1F23F000A30426 |
FFFF 1F23F000A30426 |
FFFF 1F23F000A30426 |
FFFF 1F23F000A30426 |
*/ |
#include <stdlib.h> |
#include "dsl.h" |
96,47 → 95,48 |
uint8_t PacketBuffer[6]; |
//uint8_t Jitter = 0; // same measurement as RC_Quality in rc.c |
typedef union |
{ |
typedef union { |
int16_t Servo[2]; |
uint8_t byte[4]; |
uint8_t byte[4]; |
} ChannelPair_t; |
ChannelPair_t ChannelPair; |
// This function is called, when a new servo signal is properly received. |
// Parameters: servo - servo number (0-9) |
// signal - servo signal between 7373 (1ms) and 14745 (2ms) |
void dsl_new_signal(uint8_t channel, int16_t signal) |
{ |
int16_t tmp; |
uint8_t index = channel + 1; // mk channels start with 1 |
void dsl_new_signal(uint8_t channel, int16_t signal) { |
int16_t tmp; |
uint8_t index = channel + 1; // mk channels start with 1 |
//RC_Quality = (212 * (uint16_t)dsl_RSSI) / 128; // have to be scaled approx. by a factor of 1.66 to get 200 at full level |
//if(RC_Quality > 255) RC_Quality = 255; |
// signal from DSL-receiver is between 7373 (1ms) und 14745 (2ms). |
signal-= 11059; // shift to neutral |
signal/= 24; // scale to mk rc resolution |
// signal from DSL-receiver is between 7373 (1ms) und 14745 (2ms). |
signal -= 11059; // shift to neutral |
signal /= 24; // scale to mk rc resolution |
if(abs(signal-PPM_in[index]) < 6) |
{ |
if(RC_Quality < 200) RC_Quality +=10; |
else RC_Quality = 200; |
if (abs(signal-PPM_in[index]) < 6) { |
if (RC_Quality < 200) |
RC_Quality += 10; |
else |
RC_Quality = 200; |
} |
// calculate exponential history for signal |
// calculate exponential history for signal |
tmp = (3 * (PPM_in[index]) + signal) / 4; |
if(tmp > signal+1) tmp--; else |
if(tmp < signal-1) tmp++; |
if (tmp > signal + 1) |
tmp--; |
else if (tmp < signal - 1) |
tmp++; |
// calculate signal difference on good signal level |
if(RC_Quality >= 195) PPM_diff[index] = ((tmp - PPM_in[index]) / 3) * 3; // cut off lower 3 bit for noise reduction |
else PPM_diff[index] = 0; |
if (RC_Quality >= 195) |
PPM_diff[index] = ((tmp - PPM_in[index]) / 3) * 3; // cut off lower 3 bit for noise reduction |
else |
PPM_diff[index] = 0; |
PPM_in[index] = tmp; // update channel value |
if(index == 4) |
{ |
if (index == 4) { |
NewPpmData = 0; |
} |
} |
143,34 → 143,29 |
// This function is called within dsl_parser(), when a complete |
// data packet with valid checksum has been received. |
void dsl_decode_packet(void) |
{ |
uint8_t i; |
void dsl_decode_packet(void) { |
uint8_t i; |
// check for header condition |
if((PacketBuffer[0] & 0xF0) == 0x10) |
{ |
if(PacketBuffer[0] == 0x1F) // separate status frame |
if ((PacketBuffer[0] & 0xF0) == 0x10) { |
if (PacketBuffer[0] == 0x1F) // separate status frame |
{ |
dsl_Allocation = PacketBuffer[1]; // Get frequency allocation |
dsl_Allocation = PacketBuffer[1]; // Get frequency allocation |
// ?? = PacketBuffer[2]; |
dsl_RSSI = PacketBuffer[3]; // Get signal quality |
dsl_Battery = PacketBuffer[4]; // Get voltage of battery supply |
dsl_RSSI = PacketBuffer[3]; // Get signal quality |
dsl_Battery = PacketBuffer[4]; // Get voltage of battery supply |
// ?? = PacketBuffer[5]; |
if(dsl_RSSI == 0) |
{ |
if (dsl_RSSI == 0) { |
RC_Quality = 0; |
for (i = 0; i<5; i++) |
{ |
for (i = 0; i < 5; i++) { |
PPM_diff[i] = 0; |
PPM_in[i] = 0; |
} |
} |
} |
else // probably a channel pair |
} else // probably a channel pair |
{ |
i = PacketBuffer[0] & 0x0F; // last 4 bits of the header indicates the channel pair |
if(i < 10)// maximum 12 channels |
i = PacketBuffer[0] & 0x0F; // last 4 bits of the header indicates the channel pair |
if (i < 10)// maximum 12 channels |
{ |
// big to little endian |
ChannelPair.byte[1] = PacketBuffer[1]; |
177,47 → 172,47 |
ChannelPair.byte[0] = PacketBuffer[2]; |
ChannelPair.byte[3] = PacketBuffer[3]; |
ChannelPair.byte[2] = PacketBuffer[4]; |
dsl_new_signal(i, ChannelPair.Servo[0]); |
dsl_new_signal(i+1,ChannelPair.Servo[1]); |
dsl_new_signal(i, ChannelPair.Servo[0]); |
dsl_new_signal(i + 1, ChannelPair.Servo[1]); |
} |
} |
} // EOF header condition |
} |
// this function should be called within the UART RX ISR |
void dsl_parser(uint8_t c) |
{ |
void dsl_parser(uint8_t c) { |
static uint8_t last_c = 0; |
static uint8_t crc = 0; |
static uint8_t crc = 0; |
static uint8_t cnt = 0; |
static uint8_t packet_len = 0; |
// check for sync condition |
if ((c==0xFF) && (last_c==0xFF)) |
{ |
if ((c == 0xFF) && (last_c == 0xFF)) { |
cnt = 0; // reset byte counter |
crc = 0; // reset checksum |
return; |
} |
} |
if(cnt == 0) // begin of a packet |
if (cnt == 0) // begin of a packet |
{ |
if(c == 0x1F) packet_len = 5; // a status packet has 5 bytes + crc |
else packet_len = 4; // a channel pair packet has 4 bytes + crc |
if (c == 0x1F) |
packet_len = 5; // a status packet has 5 bytes + crc |
else |
packet_len = 4; // a channel pair packet has 4 bytes + crc |
} |
if(cnt > packet_len) // packet complete, crc byte received |
if (cnt > packet_len) // packet complete, crc byte received |
{ |
// calculate checksum |
crc = ~crc; |
if (crc == 0xFF) crc = 0xFE; |
if (crc == 0xFF) |
crc = 0xFE; |
// if crc matches decode the packet |
if (c == crc) dsl_decode_packet(); |
// handle next packet |
cnt = 0; |
crc = 0; |
} |
else // collect channel data bytes |
if (c == crc) |
dsl_decode_packet(); |
// handle next packet |
cnt = 0; |
crc = 0; |
} else // collect channel data bytes |
{ |
PacketBuffer[cnt++] = c; |
crc += c; |
/branches/dongfang_FC_rewrite/dsl.h |
---|
3,8 → 3,8 |
#include <inttypes.h> |
extern uint8_t dsl_RSSI; // Received signal strength indicator |
extern uint8_t dsl_Battery; // Battery voltage (0-255 [0V - 8.2V]) |
extern uint8_t dsl_RSSI; // Received signal strength indicator |
extern uint8_t dsl_Battery; // Battery voltage (0-255 [0V - 8.2V]) |
extern uint8_t dsl_Allocation; // Frequency allocation (35,40,72) |
#define USART1_BAUD 38400 |
12,4 → 12,3 |
extern void dsl_parser(uint8_t c); |
#endif //_DSL_H |
/branches/dongfang_FC_rewrite/eeprom.c |
---|
74,10 → 74,10 |
#include "sensors.h" |
// byte array in eeprom |
uint8_t EEPromArray[E2END+1] EEMEM; |
uint8_t EEPromArray[E2END + 1] EEMEM; |
paramset_t staticParams; |
MixerTable_t Mixer; |
paramset_t staticParams; |
MixerTable_t Mixer; |
/* |
* Default for your own experiments here, so you don't have to reset them |
84,90 → 84,90 |
* from MK-Tool all the time. |
*/ |
void setDefaultUserParams(void) { |
uint8_t i; |
for (i=0; i<sizeof(staticParams.UserParams1); i++) { |
staticParams.UserParams1[i] = 0; |
} |
for (i=0; i<sizeof(staticParams.UserParams2); i++) { |
staticParams.UserParams2[i] = 0; |
} |
/* |
* While we are still using userparams for flight parameters, do set |
* some safe & meaningful default values. |
*/ |
staticParams.UserParams1[3] = 8; // Throttle stick D=8 |
staticParams.UserParams2[0] = 0b11010101; // All gyro filter constants 2; acc. 4 |
staticParams.UserParams2[1] = 2; // H&I motor smoothing. |
staticParams.UserParams2[2] = 120; // Yaw I factor |
staticParams.UserParams2[3] = 10; // Max Z acceleration for acc. correction of angles. |
uint8_t i; |
for (i = 0; i < sizeof(staticParams.UserParams1); i++) { |
staticParams.UserParams1[i] = 0; |
} |
for (i = 0; i < sizeof(staticParams.UserParams2); i++) { |
staticParams.UserParams2[i] = 0; |
} |
/* |
* While we are still using userparams for flight parameters, do set |
* some safe & meaningful default values. |
*/ |
staticParams.UserParams1[3] = 8; // Throttle stick D=8 |
staticParams.UserParams2[0] = 0b11010101; // All gyro filter constants 2; acc. 4 |
staticParams.UserParams2[1] = 2; // H&I motor smoothing. |
staticParams.UserParams2[2] = 120; // Yaw I factor |
staticParams.UserParams2[3] = 10; // Max Z acceleration for acc. correction of angles. |
} |
void setOtherDefaults(void) { |
/* Channel assignments were changed to the normal: |
* Aileron/roll=1, elevator/pitch=2, throttle=3, yaw/rudder=4 |
*/ |
staticParams.ChannelAssignment[CH_PITCH] = 2; |
staticParams.ChannelAssignment[CH_ROLL] = 1; |
staticParams.ChannelAssignment[CH_THROTTLE] = 3; |
staticParams.ChannelAssignment[CH_YAW] = 4; |
staticParams.ChannelAssignment[CH_POTS+0] = 5; |
staticParams.ChannelAssignment[CH_POTS+1] = 6; |
staticParams.ChannelAssignment[CH_POTS+2] = 7; |
staticParams.ChannelAssignment[CH_POTS+3] = 8; |
staticParams.GlobalConfig = CFG_AXIS_COUPLING_ACTIVE | CFG_HEADING_HOLD; // CFG_COMPASS_ACTIVE | CFG_GPS_ACTIVE;//CFG_HEIGHT_CONTROL | CFG_HEIGHT_SWITCH | CFG_COMPASS_FIX; |
staticParams.HeightMinGas = 30; |
staticParams.MaxHeight = 251; |
staticParams.HeightP = 10; |
staticParams.HeightD = 30; |
staticParams.Height_ACC_Effect = 30; |
staticParams.Height_Gain = 4; |
staticParams.StickP = 8; |
staticParams.StickD = 12; |
staticParams.StickYawP = 12; |
staticParams.MinThrottle = 8; |
staticParams.MaxThrottle = 230; |
staticParams.CompassYawEffect = 128; |
staticParams.GyroP = 80; |
staticParams.GyroI = 100; |
staticParams.LowVoltageWarning = 95; |
staticParams.EmergencyGas = 35; |
staticParams.EmergencyGasDuration = 30; |
staticParams.Unused0 = 0; |
staticParams.IFactor = 32; |
staticParams.ServoPitchControl = 100; |
staticParams.ServoPitchComp = 40; |
staticParams.ServoPitchCompInvert = 0; |
staticParams.ServoPitchMin = 50; |
staticParams.ServoPitchMax = 150; |
staticParams.ServoRefresh = 5; |
staticParams.LoopGasLimit = 50; |
staticParams.LoopThreshold = 90; |
staticParams.LoopHysteresis = 50; |
staticParams.BitConfig = 0; |
staticParams.AxisCoupling1 = 90; |
staticParams.AxisCoupling2 = 67; |
staticParams.AxisCouplingYawCorrection = 0; |
staticParams.DynamicStability = 50; |
staticParams.J16Bitmask = 95; |
staticParams.J17Bitmask = 243; |
staticParams.J16Timing = 15; |
staticParams.J17Timing = 15; |
staticParams.NaviGpsModeControl = 253; |
staticParams.NaviGpsGain = 100; |
staticParams.NaviGpsP = 90; |
staticParams.NaviGpsI = 90; |
staticParams.NaviGpsD = 90; |
staticParams.NaviGpsPLimit = 75; |
staticParams.NaviGpsILimit = 75; |
staticParams.NaviGpsDLimit = 75; |
staticParams.NaviGpsACC = 0; |
staticParams.NaviGpsMinSat = 6; |
staticParams.NaviStickThreshold = 8; |
staticParams.NaviWindCorrection = 90; |
staticParams.NaviSpeedCompensation = 30; |
staticParams.NaviOperatingRadius = 100; |
staticParams.NaviAngleLimitation = 100; |
staticParams.NaviPHLoginTime = 4; |
/* Channel assignments were changed to the normal: |
* Aileron/roll=1, elevator/pitch=2, throttle=3, yaw/rudder=4 |
*/ |
staticParams.ChannelAssignment[CH_PITCH] = 2; |
staticParams.ChannelAssignment[CH_ROLL] = 1; |
staticParams.ChannelAssignment[CH_THROTTLE] = 3; |
staticParams.ChannelAssignment[CH_YAW] = 4; |
staticParams.ChannelAssignment[CH_POTS + 0] = 5; |
staticParams.ChannelAssignment[CH_POTS + 1] = 6; |
staticParams.ChannelAssignment[CH_POTS + 2] = 7; |
staticParams.ChannelAssignment[CH_POTS + 3] = 8; |
staticParams.GlobalConfig = CFG_AXIS_COUPLING_ACTIVE | CFG_HEADING_HOLD; // CFG_COMPASS_ACTIVE | CFG_GPS_ACTIVE;//CFG_HEIGHT_CONTROL | CFG_HEIGHT_SWITCH | CFG_COMPASS_FIX; |
staticParams.HeightMinGas = 30; |
staticParams.MaxHeight = 251; |
staticParams.HeightP = 10; |
staticParams.HeightD = 30; |
staticParams.Height_ACC_Effect = 30; |
staticParams.Height_Gain = 4; |
staticParams.StickP = 8; |
staticParams.StickD = 12; |
staticParams.StickYawP = 12; |
staticParams.MinThrottle = 8; |
staticParams.MaxThrottle = 230; |
staticParams.CompassYawEffect = 128; |
staticParams.GyroP = 80; |
staticParams.GyroI = 100; |
staticParams.LowVoltageWarning = 95; |
staticParams.EmergencyGas = 35; |
staticParams.EmergencyGasDuration = 30; |
staticParams.Unused0 = 0; |
staticParams.IFactor = 32; |
staticParams.ServoPitchControl = 100; |
staticParams.ServoPitchComp = 40; |
staticParams.ServoPitchCompInvert = 0; |
staticParams.ServoPitchMin = 50; |
staticParams.ServoPitchMax = 150; |
staticParams.ServoRefresh = 5; |
staticParams.LoopGasLimit = 50; |
staticParams.LoopThreshold = 90; |
staticParams.LoopHysteresis = 50; |
staticParams.BitConfig = 0; |
staticParams.AxisCoupling1 = 90; |
staticParams.AxisCoupling2 = 67; |
staticParams.AxisCouplingYawCorrection = 0; |
staticParams.DynamicStability = 50; |
staticParams.J16Bitmask = 95; |
staticParams.J17Bitmask = 243; |
staticParams.J16Timing = 15; |
staticParams.J17Timing = 15; |
staticParams.NaviGpsModeControl = 253; |
staticParams.NaviGpsGain = 100; |
staticParams.NaviGpsP = 90; |
staticParams.NaviGpsI = 90; |
staticParams.NaviGpsD = 90; |
staticParams.NaviGpsPLimit = 75; |
staticParams.NaviGpsILimit = 75; |
staticParams.NaviGpsDLimit = 75; |
staticParams.NaviGpsACC = 0; |
staticParams.NaviGpsMinSat = 6; |
staticParams.NaviStickThreshold = 8; |
staticParams.NaviWindCorrection = 90; |
staticParams.NaviSpeedCompensation = 30; |
staticParams.NaviOperatingRadius = 100; |
staticParams.NaviAngleLimitation = 100; |
staticParams.NaviPHLoginTime = 4; |
} |
/***************************************************/ |
174,11 → 174,12 |
/* Default Values for parameter set 1 */ |
/***************************************************/ |
void ParamSet_DefaultSet1(void) { // sport |
setOtherDefaults(); |
gyro_setDefaults(); |
setDefaultUserParams(); |
staticParams.GlobalConfig = CFG_ROTARY_RATE_LIMITER | CFG_AXIS_COUPLING_ACTIVE; |
memcpy(staticParams.Name, "Sport\0",6); |
setOtherDefaults(); |
gyro_setDefaults(); |
setDefaultUserParams(); |
staticParams.GlobalConfig = CFG_ROTARY_RATE_LIMITER |
| CFG_AXIS_COUPLING_ACTIVE; |
memcpy(staticParams.Name, "Sport\0", 6); |
} |
/***************************************************/ |
185,14 → 186,15 |
/* Default Values for parameter set 2 */ |
/***************************************************/ |
void ParamSet_DefaultSet2(void) { // normal |
setOtherDefaults(); |
gyro_setDefaults(); |
setDefaultUserParams(); |
staticParams.GlobalConfig = CFG_ROTARY_RATE_LIMITER | CFG_AXIS_COUPLING_ACTIVE; |
staticParams.Height_Gain = 3; |
staticParams.J16Timing = 20; |
staticParams.J17Timing = 20; |
memcpy(staticParams.Name, "Normal\0", 7); |
setOtherDefaults(); |
gyro_setDefaults(); |
setDefaultUserParams(); |
staticParams.GlobalConfig = CFG_ROTARY_RATE_LIMITER |
| CFG_AXIS_COUPLING_ACTIVE; |
staticParams.Height_Gain = 3; |
staticParams.J16Timing = 20; |
staticParams.J17Timing = 20; |
memcpy(staticParams.Name, "Normal\0", 7); |
} |
/***************************************************/ |
199,16 → 201,17 |
/* Default Values for parameter set 3 */ |
/***************************************************/ |
void ParamSet_DefaultSet3(void) { // beginner |
setOtherDefaults(); |
gyro_setDefaults(); |
setDefaultUserParams(); |
staticParams.GlobalConfig = CFG_ROTARY_RATE_LIMITER | CFG_AXIS_COUPLING_ACTIVE; |
staticParams.Height_Gain = 3; |
staticParams.EmergencyGasDuration = 20; |
staticParams.AxisCouplingYawCorrection = 70; |
staticParams.J16Timing = 30; |
staticParams.J17Timing = 30; |
memcpy(staticParams.Name, "Beginner\0", 9); |
setOtherDefaults(); |
gyro_setDefaults(); |
setDefaultUserParams(); |
staticParams.GlobalConfig = CFG_ROTARY_RATE_LIMITER |
| CFG_AXIS_COUPLING_ACTIVE; |
staticParams.Height_Gain = 3; |
staticParams.EmergencyGasDuration = 20; |
staticParams.AxisCouplingYawCorrection = 70; |
staticParams.J16Timing = 30; |
staticParams.J17Timing = 30; |
memcpy(staticParams.Name, "Beginner\0", 9); |
} |
/***************************************************/ |
215,7 → 218,7 |
/* Read Parameter from EEPROM as byte */ |
/***************************************************/ |
uint8_t GetParamByte(uint16_t param_id) { |
return eeprom_read_byte(&EEPromArray[EEPROM_ADR_PARAM_BEGIN + param_id]); |
return eeprom_read_byte(&EEPromArray[EEPROM_ADR_PARAM_BEGIN + param_id]); |
} |
/***************************************************/ |
222,7 → 225,7 |
/* Write Parameter to EEPROM as byte */ |
/***************************************************/ |
void SetParamByte(uint16_t param_id, uint8_t value) { |
eeprom_write_byte(&EEPromArray[EEPROM_ADR_PARAM_BEGIN + param_id], value); |
eeprom_write_byte(&EEPromArray[EEPROM_ADR_PARAM_BEGIN + param_id], value); |
} |
/***************************************************/ |
229,7 → 232,8 |
/* Read Parameter from EEPROM as word */ |
/***************************************************/ |
uint16_t GetParamWord(uint16_t param_id) { |
return eeprom_read_word((uint16_t *) &EEPromArray[EEPROM_ADR_PARAM_BEGIN + param_id]); |
return eeprom_read_word((uint16_t *) &EEPromArray[EEPROM_ADR_PARAM_BEGIN |
+ param_id]); |
} |
/***************************************************/ |
236,7 → 240,8 |
/* Write Parameter to EEPROM as word */ |
/***************************************************/ |
void SetParamWord(uint16_t param_id, uint16_t value) { |
eeprom_write_word((uint16_t *) &EEPromArray[EEPROM_ADR_PARAM_BEGIN + param_id], value); |
eeprom_write_word( |
(uint16_t *) &EEPromArray[EEPROM_ADR_PARAM_BEGIN + param_id], value); |
} |
/***************************************************/ |
244,9 → 249,12 |
/***************************************************/ |
// number [1..5] |
void ParamSet_ReadFromEEProm(uint8_t setnumber) { |
if((1 > setnumber) || (setnumber > 5)) setnumber = 3; |
eeprom_read_block((uint8_t *) &staticParams.ChannelAssignment[0], &EEPromArray[EEPROM_ADR_PARAMSET_BEGIN + PARAMSET_STRUCT_LEN * (setnumber - 1)], PARAMSET_STRUCT_LEN); |
output_init(); |
if ((1 > setnumber) || (setnumber > 5)) |
setnumber = 3; |
eeprom_read_block((uint8_t *) &staticParams.ChannelAssignment[0], |
&EEPromArray[EEPROM_ADR_PARAMSET_BEGIN + PARAMSET_STRUCT_LEN * (setnumber |
- 1)], PARAMSET_STRUCT_LEN); |
output_init(); |
} |
/***************************************************/ |
254,14 → 262,20 |
/***************************************************/ |
// number [1..5] |
void ParamSet_WriteToEEProm(uint8_t setnumber) { |
if(setnumber > 5) setnumber = 5; |
if(setnumber < 1) return; |
eeprom_write_block((uint8_t *) &staticParams.ChannelAssignment[0], &EEPromArray[EEPROM_ADR_PARAMSET_BEGIN + PARAMSET_STRUCT_LEN * (setnumber - 1)], PARAMSET_STRUCT_LEN); |
eeprom_write_word((uint16_t *) &EEPromArray[EEPROM_ADR_PARAMSET_LENGTH], PARAMSET_STRUCT_LEN); |
eeprom_write_block( &staticParams.ChannelAssignment[0], &EEPromArray[EEPROM_ADR_CHANNELS], 8); // backup the first 8 bytes that is the rc channel mapping |
// set this parameter set to active set |
setActiveParamSet(setnumber); |
output_init(); |
if (setnumber > 5) |
setnumber = 5; |
if (setnumber < 1) |
return; |
eeprom_write_block((uint8_t *) &staticParams.ChannelAssignment[0], |
&EEPromArray[EEPROM_ADR_PARAMSET_BEGIN + PARAMSET_STRUCT_LEN * (setnumber |
- 1)], PARAMSET_STRUCT_LEN); |
eeprom_write_word((uint16_t *) &EEPromArray[EEPROM_ADR_PARAMSET_LENGTH], |
PARAMSET_STRUCT_LEN); |
eeprom_write_block(&staticParams.ChannelAssignment[0], |
&EEPromArray[EEPROM_ADR_CHANNELS], 8); // backup the first 8 bytes that is the rc channel mapping |
// set this parameter set to active set |
setActiveParamSet(setnumber); |
output_init(); |
} |
/***************************************************/ |
268,13 → 282,13 |
/* Get active parameter set */ |
/***************************************************/ |
uint8_t getActiveParamSet(void) { |
uint8_t setnumber; |
setnumber = eeprom_read_byte(&EEPromArray[PID_ACTIVE_SET]); |
if(setnumber > 5) { |
setnumber = 3; |
eeprom_write_byte(&EEPromArray[PID_ACTIVE_SET], setnumber); |
} |
return(setnumber); |
uint8_t setnumber; |
setnumber = eeprom_read_byte(&EEPromArray[PID_ACTIVE_SET]); |
if (setnumber > 5) { |
setnumber = 3; |
eeprom_write_byte(&EEPromArray[PID_ACTIVE_SET], setnumber); |
} |
return (setnumber); |
} |
/***************************************************/ |
281,9 → 295,11 |
/* Set active parameter set */ |
/***************************************************/ |
void setActiveParamSet(uint8_t setnumber) { |
if(setnumber > 5) setnumber = 5; |
if(setnumber < 1) setnumber = 1; |
eeprom_write_byte(&EEPromArray[PID_ACTIVE_SET], setnumber); |
if (setnumber > 5) |
setnumber = 5; |
if (setnumber < 1) |
setnumber = 1; |
eeprom_write_byte(&EEPromArray[PID_ACTIVE_SET], setnumber); |
} |
/***************************************************/ |
290,11 → 306,13 |
/* Read MixerTable from EEPROM */ |
/***************************************************/ |
uint8_t MixerTable_ReadFromEEProm(void) { |
if(eeprom_read_byte(&EEPromArray[EEPROM_ADR_MIXER_TABLE]) == EEMIXER_REVISION) { |
eeprom_read_block((uint8_t *) &Mixer, &EEPromArray[EEPROM_ADR_MIXER_TABLE], sizeof(Mixer)); |
return 1; |
} |
else return 0; |
if (eeprom_read_byte(&EEPromArray[EEPROM_ADR_MIXER_TABLE]) |
== EEMIXER_REVISION) { |
eeprom_read_block((uint8_t *) &Mixer, &EEPromArray[EEPROM_ADR_MIXER_TABLE], |
sizeof(Mixer)); |
return 1; |
} else |
return 0; |
} |
/***************************************************/ |
301,11 → 319,12 |
/* Write Mixer Table to EEPROM */ |
/***************************************************/ |
uint8_t MixerTable_WriteToEEProm(void) { |
if(Mixer.Revision == EEMIXER_REVISION) { |
eeprom_write_block((uint8_t *) &Mixer, &EEPromArray[EEPROM_ADR_MIXER_TABLE], sizeof(Mixer)); |
return 1; |
} |
else return 0; |
if (Mixer.Revision == EEMIXER_REVISION) { |
eeprom_write_block((uint8_t *) &Mixer, |
&EEPromArray[EEPROM_ADR_MIXER_TABLE], sizeof(Mixer)); |
return 1; |
} else |
return 0; |
} |
/***************************************************/ |
312,21 → 331,25 |
/* Default Values for Mixer Table */ |
/***************************************************/ |
void MixerTable_Default(void) { // Quadro |
uint8_t i; |
Mixer.Revision = EEMIXER_REVISION; |
// clear mixer table (but preset throttle) |
for(i = 0; i < 16; i++) { |
Mixer.Motor[i][MIX_THROTTLE] = i < 4 ? 64 : 0; |
Mixer.Motor[i][MIX_PITCH] = 0; |
Mixer.Motor[i][MIX_ROLL] = 0; |
Mixer.Motor[i][MIX_YAW] = 0; |
} |
// default = Quadro |
Mixer.Motor[0][MIX_PITCH] = +64; Mixer.Motor[0][MIX_YAW] = +64; |
Mixer.Motor[1][MIX_PITCH] = -64; Mixer.Motor[1][MIX_YAW] = +64; |
Mixer.Motor[2][MIX_ROLL] = -64; Mixer.Motor[2][MIX_YAW] = -64; |
Mixer.Motor[3][MIX_ROLL] = +64; Mixer.Motor[3][MIX_YAW] = -64; |
memcpy(Mixer.Name, "Quadro\0", 7); |
uint8_t i; |
Mixer.Revision = EEMIXER_REVISION; |
// clear mixer table (but preset throttle) |
for (i = 0; i < 16; i++) { |
Mixer.Motor[i][MIX_THROTTLE] = i < 4 ? 64 : 0; |
Mixer.Motor[i][MIX_PITCH] = 0; |
Mixer.Motor[i][MIX_ROLL] = 0; |
Mixer.Motor[i][MIX_YAW] = 0; |
} |
// default = Quadro |
Mixer.Motor[0][MIX_PITCH] = +64; |
Mixer.Motor[0][MIX_YAW] = +64; |
Mixer.Motor[1][MIX_PITCH] = -64; |
Mixer.Motor[1][MIX_YAW] = +64; |
Mixer.Motor[2][MIX_ROLL] = -64; |
Mixer.Motor[2][MIX_YAW] = -64; |
Mixer.Motor[3][MIX_ROLL] = +64; |
Mixer.Motor[3][MIX_YAW] = -64; |
memcpy(Mixer.Name, "Quadro\0", 7); |
} |
/***************************************************/ |
333,62 → 356,64 |
/* Initialize EEPROM Parameter Sets */ |
/***************************************************/ |
void ParamSet_Init(void) { |
uint8_t Channel_Backup=1, i, j; |
// parameter version check |
if(eeprom_read_byte(&EEPromArray[PID_PARAM_REVISION]) != EEPARAM_REVISION) { |
// if version check faild |
printf("\n\rInit Parameter in EEPROM"); |
eeprom_write_byte(&EEPromArray[EEPROM_ADR_MIXER_TABLE], 0xFF); // reset also mixer table |
// check if channel mapping backup is valid |
for (j=0; j<4 && Channel_Backup; j++) { |
if (eeprom_read_byte(&EEPromArray[EEPROM_ADR_CHANNELS+0]) >= 12) |
Channel_Backup = 0; |
} |
// fill all 5 parameter settings |
for (i=1; i<6; i++) { |
switch(i) { |
case 1: |
ParamSet_DefaultSet1(); // Fill staticParams Structure to default parameter set 1 (Sport) |
break; |
case 2: |
ParamSet_DefaultSet2(); // Kamera |
break; |
case 3: |
ParamSet_DefaultSet3(); // Beginner |
break; |
default: |
ParamSet_DefaultSet2(); // Kamera |
break; |
} |
if(Channel_Backup) { // if we have a rc channel mapping backup in eeprom |
// restore it |
for (j=0; j<8; j++) { |
staticParams.ChannelAssignment[j] = eeprom_read_byte(&EEPromArray[EEPROM_ADR_CHANNELS+j]); |
uint8_t Channel_Backup = 1, i, j; |
// parameter version check |
if (eeprom_read_byte(&EEPromArray[PID_PARAM_REVISION]) != EEPARAM_REVISION) { |
// if version check faild |
printf("\n\rInit Parameter in EEPROM"); |
eeprom_write_byte(&EEPromArray[EEPROM_ADR_MIXER_TABLE], 0xFF); // reset also mixer table |
// check if channel mapping backup is valid |
for (j = 0; j < 4 && Channel_Backup; j++) { |
if (eeprom_read_byte(&EEPromArray[EEPROM_ADR_CHANNELS + 0]) >= 12) |
Channel_Backup = 0; |
} |
// fill all 5 parameter settings |
for (i = 1; i < 6; i++) { |
switch (i) { |
case 1: |
ParamSet_DefaultSet1(); // Fill staticParams Structure to default parameter set 1 (Sport) |
break; |
case 2: |
ParamSet_DefaultSet2(); // Kamera |
break; |
case 3: |
ParamSet_DefaultSet3(); // Beginner |
break; |
default: |
ParamSet_DefaultSet2(); // Kamera |
break; |
} |
if (Channel_Backup) { // if we have a rc channel mapping backup in eeprom |
// restore it |
for (j = 0; j < 8; j++) { |
staticParams.ChannelAssignment[j] = eeprom_read_byte( |
&EEPromArray[EEPROM_ADR_CHANNELS + j]); |
} |
} |
ParamSet_WriteToEEProm(i); |
} |
// default-Setting is parameter set 3 |
setActiveParamSet(1); |
// update version info |
SetParamByte(PID_PARAM_REVISION, EEPARAM_REVISION); |
} |
} |
ParamSet_WriteToEEProm(i); |
} |
// default-Setting is parameter set 3 |
setActiveParamSet(1); |
// update version info |
SetParamByte(PID_PARAM_REVISION, EEPARAM_REVISION); |
} |
// read active parameter set to staticParams stucture |
ParamSet_ReadFromEEProm(getActiveParamSet()); |
printf("\n\rUsing Parameter Set %d", getActiveParamSet()); |
// load mixer table |
if(!MixerTable_ReadFromEEProm()) { |
printf("\n\rGenerating default Mixer Table"); |
MixerTable_Default(); // Quadro |
MixerTable_WriteToEEProm(); |
} |
// determine motornumber |
RequiredMotors = 0; |
for(i = 0; i < 16; i++) { |
if(Mixer.Motor[i][MIX_THROTTLE] > 0) RequiredMotors++; |
} |
printf("\n\rMixer-Config: '%s' (%u Motors)",Mixer.Name, RequiredMotors); |
printf("\n\r=============================="); |
// read active parameter set to staticParams stucture |
ParamSet_ReadFromEEProm(getActiveParamSet()); |
printf("\n\rUsing Parameter Set %d", getActiveParamSet()); |
// load mixer table |
if (!MixerTable_ReadFromEEProm()) { |
printf("\n\rGenerating default Mixer Table"); |
MixerTable_Default(); // Quadro |
MixerTable_WriteToEEProm(); |
} |
// determine motornumber |
RequiredMotors = 0; |
for (i = 0; i < 16; i++) { |
if (Mixer.Motor[i][MIX_THROTTLE] > 0) |
RequiredMotors++; |
} |
printf("\n\rMixer-Config: '%s' (%u Motors)",Mixer.Name, RequiredMotors); |
printf("\n\r=============================="); |
} |
/branches/dongfang_FC_rewrite/eeprom.h |
---|
11,16 → 11,12 |
#define PID_ACC_PITCH 4 // word |
#define PID_ACC_ROLL 6 // word |
#define PID_ACC_Z 8 // word |
#define EEPROM_ADR_CHANNELS 80 // 8 bytes |
#define EEPROM_ADR_PARAMSET_LENGTH 98 // word |
#define EEPROM_ADR_PARAMSET_BEGIN 100 |
#define EEPROM_ADR_MIXER_TABLE 1000 // 1000 - 1076 |
#define EEPARAM_REVISION 75 // is count up, if paramater stucture has changed (compatibility) |
#define EEMIXER_REVISION 1 // is count up, if Mixer stucture has changed (compatibility) |
extern void ParamSet_Init(void); |
extern void ParamSet_ReadFromEEProm(uint8_t setnumber); |
extern void ParamSet_WriteToEEProm(uint8_t setnumber); |
/branches/dongfang_FC_rewrite/externalControl.c |
---|
9,59 → 9,62 |
// TODO: Who is going to call this |
void EC_setNeutral(void) { |
// if necessary. From main.c. |
externalControl.config = 0; |
externalControl.pitch = 0; |
externalControl.roll = 0; |
externalControl.yaw = 0; |
externalControl.throttle = 0; |
// From main.c. What does it do?? |
externalControl.digital[0] = 0x55; |
// if necessary. From main.c. |
externalControl.config = 0; |
externalControl.pitch = 0; |
externalControl.roll = 0; |
externalControl.yaw = 0; |
externalControl.throttle = 0; |
// From main.c. What does it do?? |
externalControl.digital[0] = 0x55; |
} |
int16_t* EC_getPRTY(void) { |
return EC_PRTY; |
return EC_PRTY; |
} |
uint8_t EC_getArgument(void) { |
return externalControl.config; |
return externalControl.config; |
} |
uint8_t EC_getCommand(void) { |
return externalControl.free; |
return externalControl.free; |
} |
// not implemented. |
int16_t EC_getVariable(uint8_t varNum) { |
return 0; |
return 0; |
} |
void EC_update() { |
if (externalControlActive) { |
externalControlActive--; |
EC_PRTY[CONTROL_PITCH] = (int16_t) externalControl.pitch * (int16_t) staticParams.StickP; |
EC_PRTY[CONTROL_ROLL] = externalControl.roll * (int16_t) staticParams.StickP; |
EC_PRTY[CONTROL_THROTTLE] = externalControl.throttle; |
EC_PRTY[CONTROL_YAW] = externalControl.yaw; // No stickP or similar?????? |
} else { |
EC_PRTY[CONTROL_PITCH] = EC_PRTY[CONTROL_ROLL] = EC_PRTY[CONTROL_THROTTLE] = EC_PRTY[CONTROL_YAW] = 0; |
} |
if (externalControlActive) { |
externalControlActive--; |
EC_PRTY[CONTROL_PITCH] = (int16_t) externalControl.pitch |
* (int16_t) staticParams.StickP; |
EC_PRTY[CONTROL_ROLL] = externalControl.roll |
* (int16_t) staticParams.StickP; |
EC_PRTY[CONTROL_THROTTLE] = externalControl.throttle; |
EC_PRTY[CONTROL_YAW] = externalControl.yaw; // No stickP or similar?????? |
} else { |
EC_PRTY[CONTROL_PITCH] = EC_PRTY[CONTROL_ROLL] = EC_PRTY[CONTROL_THROTTLE] |
= EC_PRTY[CONTROL_YAW] = 0; |
} |
} |
uint8_t EC_getSignalQuality(void) { |
if (externalControlActive > 80) |
// Configured and heard from recently |
return SIGNAL_GOOD; |
if (externalControlActive > 80) |
// Configured and heard from recently |
return SIGNAL_GOOD; |
if (externalControlActive) |
// Configured and heard from |
return SIGNAL_OK; |
if (externalControlActive) |
// Configured and heard from |
return SIGNAL_OK; |
if (!(externalControl.config & 0x01 && dynamicParams.ExternalControl > 128)) |
// External control is not even configured. |
return NO_SIGNAL; |
if (!(externalControl.config & 0x01 && dynamicParams.ExternalControl > 128)) |
// External control is not even configured. |
return NO_SIGNAL; |
// Configured but expired. |
return SIGNAL_LOST; |
// Configured but expired. |
return SIGNAL_LOST; |
} |
/branches/dongfang_FC_rewrite/externalControl.h |
---|
5,28 → 5,28 |
#include<inttypes.h> |
typedef struct { |
uint8_t digital[2]; |
uint8_t remoteButtons; |
int8_t pitch; |
int8_t roll; |
int8_t yaw; |
uint8_t throttle; |
int8_t height; |
uint8_t free; // Let's use that for commands now. |
uint8_t frame; |
uint8_t config; // Let's use that for arguemnts. |
} __attribute__((packed)) ExternalControl_t; |
uint8_t digital[2]; |
uint8_t remoteButtons; |
int8_t pitch; |
int8_t roll; |
int8_t yaw; |
uint8_t throttle; |
int8_t height; |
uint8_t free; // Let's use that for commands now. |
uint8_t frame; |
uint8_t config; // Let's use that for arguemnts. |
}__attribute__((packed)) ExternalControl_t; |
extern ExternalControl_t externalControl; |
extern uint8_t externalControlActive; |
void EC_update(void); |
int16_t* EC_getPRTY(void); |
uint8_t EC_getArgument(void); |
uint8_t EC_getCommand(void); |
int16_t EC_getVariable(uint8_t varNum); |
void EC_calibrate(void); |
uint8_t EC_getSignalQuality (void); |
void EC_setNeutral(void); |
void EC_update(void); |
int16_t* EC_getPRTY(void); |
uint8_t EC_getArgument(void); |
uint8_t EC_getCommand(void); |
int16_t EC_getVariable(uint8_t varNum); |
void EC_calibrate(void); |
uint8_t EC_getSignalQuality(void); |
void EC_setNeutral(void); |
#endif |
/branches/dongfang_FC_rewrite/flexcontrol.h |
---|
1,8 → 1,8 |
typedef struct { |
int16_t(*getPitch)(void); |
int16_t(*getRoll)(void); |
int16_t(*getYaw)(void); |
uint16_t(*getThrottle)(void); |
uint8_t isSignalGood(void); |
uint8_t isSignalUnreadable(void); |
int16_t(*getPitch)(void); |
int16_t(*getRoll)(void); |
int16_t(*getYaw)(void); |
uint16_t(*getThrottle)(void); |
uint8_t isSignalGood(void); |
uint8_t isSignalUnreadable(void); |
} t_control; |
/branches/dongfang_FC_rewrite/flight.c |
---|
81,7 → 81,7 |
*/ |
// int16_t naviAccPitch = 0, naviAccRoll = 0, naviCntAcc = 0; |
uint8_t gyroPFactor, gyroIFactor; // the PD factors for the attitude control |
uint8_t gyroPFactor, gyroIFactor; // the PD factors for the attitude control |
uint8_t yawPFactor, yawIFactor; // the PD factors for the yaw control |
// Some integral weight constant... |
95,23 → 95,24 |
/* Filter for motor value smoothing (necessary???) */ |
/************************************************************************/ |
int16_t motorFilter(int16_t newvalue, int16_t oldvalue) { |
switch(dynamicParams.UserParams[5]) { |
case 0: |
return newvalue; |
case 1: |
return (oldvalue + newvalue) / 2; |
case 2: |
if(newvalue > oldvalue) |
return (1 * (int16_t)oldvalue + newvalue) / 2; //mean of old and new |
else |
return newvalue - (oldvalue - newvalue) * 1; // 2 * new - old |
case 3: |
if(newvalue < oldvalue) |
return (1 * (int16_t)oldvalue + newvalue) / 2; //mean of old and new |
else |
return newvalue - (oldvalue - newvalue) * 1; // 2 * new - old |
default: return newvalue; |
} |
switch (dynamicParams.UserParams[5]) { |
case 0: |
return newvalue; |
case 1: |
return (oldvalue + newvalue) / 2; |
case 2: |
if (newvalue > oldvalue) |
return (1 * (int16_t) oldvalue + newvalue) / 2; //mean of old and new |
else |
return newvalue - (oldvalue - newvalue) * 1; // 2 * new - old |
case 3: |
if (newvalue < oldvalue) |
return (1 * (int16_t) oldvalue + newvalue) / 2; //mean of old and new |
else |
return newvalue - (oldvalue - newvalue) * 1; // 2 * new - old |
default: |
return newvalue; |
} |
} |
/************************************************************************/ |
118,345 → 119,345 |
/* Neutral Readings */ |
/************************************************************************/ |
void flight_setNeutral() { |
MKFlags |= MKFLAG_CALIBRATE; |
MKFlags |= MKFLAG_CALIBRATE; |
// not really used here any more. |
dynamicParams.KalmanK = -1; |
dynamicParams.KalmanMaxDrift = 0; |
dynamicParams.KalmanMaxFusion = 32; |
// not really used here any more. |
dynamicParams.KalmanK = -1; |
dynamicParams.KalmanMaxDrift = 0; |
dynamicParams.KalmanMaxFusion = 32; |
controlMixer_initVariables(); |
controlMixer_initVariables(); |
} |
void setFlightParameters(uint8_t _Ki, uint8_t _gyroPFactor, uint8_t _gyroIFactor, uint8_t _yawPFactor, uint8_t _yawIFactor) { |
Ki = 10300 / _Ki; |
gyroPFactor = _gyroPFactor; |
gyroIFactor = _gyroIFactor; |
yawPFactor = _yawPFactor; |
yawIFactor = _yawIFactor; |
void setFlightParameters(uint8_t _Ki, uint8_t _gyroPFactor, |
uint8_t _gyroIFactor, uint8_t _yawPFactor, uint8_t _yawIFactor) { |
Ki = 10300 / _Ki; |
gyroPFactor = _gyroPFactor; |
gyroIFactor = _gyroIFactor; |
yawPFactor = _yawPFactor; |
yawIFactor = _yawIFactor; |
} |
void setNormalFlightParameters(void) { |
setFlightParameters(dynamicParams.IFactor + 1, |
dynamicParams.GyroP + 10, |
staticParams.GlobalConfig & CFG_HEADING_HOLD ? 0 : dynamicParams.GyroI, |
dynamicParams.GyroP + 10, |
dynamicParams.UserParams[6] |
); |
setFlightParameters(dynamicParams.IFactor + 1, dynamicParams.GyroP + 10, |
staticParams.GlobalConfig & CFG_HEADING_HOLD ? 0 : dynamicParams.GyroI, |
dynamicParams.GyroP + 10, dynamicParams.UserParams[6]); |
} |
void setStableFlightParameters(void) { |
setFlightParameters(33, 90, 120, 90, 120); |
setFlightParameters(33, 90, 120, 90, 120); |
} |
/************************************************************************/ |
/* Main Flight Control */ |
/************************************************************************/ |
void flight_control(void) { |
int16_t tmp_int; |
// Mixer Fractions that are combined for Motor Control |
int16_t yawTerm, throttleTerm, term[2]; |
int16_t tmp_int; |
// Mixer Fractions that are combined for Motor Control |
int16_t yawTerm, throttleTerm, term[2]; |
// PID controller variables |
int16_t PDPart[2], PDPartYaw, PPart[2]; |
static int32_t IPart[2] = {0,0}; |
// static int32_t yawControlRate = 0; |
// PID controller variables |
int16_t PDPart[2], PDPartYaw, PPart[2]; |
static int32_t IPart[2] = { 0, 0 }; |
// static int32_t yawControlRate = 0; |
// Removed. Too complicated, and apparently not necessary with MEMS gyros anyway. |
// static int32_t IntegralGyroPitchError = 0, IntegralGyroRollError = 0; |
// static int32_t CorrectionPitch, CorrectionRoll; |
// Removed. Too complicated, and apparently not necessary with MEMS gyros anyway. |
// static int32_t IntegralGyroPitchError = 0, IntegralGyroRollError = 0; |
// static int32_t CorrectionPitch, CorrectionRoll; |
static uint16_t emergencyFlightTime; |
static int8_t debugDataTimer = 1; |
static uint16_t emergencyFlightTime; |
static int8_t debugDataTimer = 1; |
// High resolution motor values for smoothing of PID motor outputs |
static int16_t motorFilters[MAX_MOTORS]; |
// High resolution motor values for smoothing of PID motor outputs |
static int16_t motorFilters[MAX_MOTORS]; |
uint8_t i, axis; |
uint8_t i, axis; |
controlMixer_update(); |
controlMixer_update(); |
// Fire the main flight attitude calculation, including integration of angles. |
calculateFlightAttitude(); |
// Fire the main flight attitude calculation, including integration of angles. |
calculateFlightAttitude(); |
throttleTerm = controlThrottle; |
// This check removed. Is done on a per-motor basis, after output matrix multiplication. |
// if(throttleTerm < staticParams.MinThrottle + 10) throttleTerm = staticParams.MinThrottle + 10; |
// else if(throttleTerm > staticParams.MaxThrottle - 20) throttleTerm = (staticParams.MaxThrottle - 20); |
throttleTerm = controlThrottle; |
// This check removed. Is done on a per-motor basis, after output matrix multiplication. |
// if(throttleTerm < staticParams.MinThrottle + 10) throttleTerm = staticParams.MinThrottle + 10; |
// else if(throttleTerm > staticParams.MaxThrottle - 20) throttleTerm = (staticParams.MaxThrottle - 20); |
/************************************************************************/ |
/* RC-signal is bad */ |
/* This part could be abstracted, as having yet another control input */ |
/* to the control mixer: An emergency autopilot control. */ |
/************************************************************************/ |
/************************************************************************/ |
/* RC-signal is bad */ |
/* This part could be abstracted, as having yet another control input */ |
/* to the control mixer: An emergency autopilot control. */ |
/************************************************************************/ |
if(controlMixer_getSignalQuality() <= SIGNAL_BAD) { // the rc-frame signal is not reveived or noisy |
RED_ON; |
beepRCAlarm(); |
if(emergencyFlightTime) { |
// continue emergency flight |
emergencyFlightTime--; |
if(isFlying > 256) { |
// We're probably still flying. Descend slowly. |
throttleTerm = staticParams.EmergencyGas; // Set emergency throttle |
MKFlags |= (MKFLAG_EMERGENCY_LANDING); // Set flag for emergency landing |
setStableFlightParameters(); |
} else { |
MKFlags &= ~(MKFLAG_MOTOR_RUN); // Probably not flying, and bad R/C signal. Kill motors. |
} |
} else { |
// end emergency flight (just cut the motors???) |
MKFlags &= ~(MKFLAG_MOTOR_RUN | MKFLAG_EMERGENCY_LANDING); |
} |
} else { |
// signal is acceptable |
if(controlMixer_getSignalQuality() > SIGNAL_BAD) { |
// Reset emergency landing control variables. |
MKFlags &= ~(MKFLAG_EMERGENCY_LANDING); // clear flag for emergency landing |
// The time is in whole seconds. |
emergencyFlightTime = (uint16_t)staticParams.EmergencyGasDuration * 488; |
} |
if (controlMixer_getSignalQuality() <= SIGNAL_BAD) { // the rc-frame signal is not reveived or noisy |
RED_ON; |
beepRCAlarm(); |
// If some throttle is given, and the motor-run flag is on, increase the probability that we are flying. |
if(throttleTerm > 40 && (MKFlags & MKFLAG_MOTOR_RUN)) { |
// increment flight-time counter until overflow. |
if(isFlying != 0xFFFF) isFlying++; |
} else |
/* |
* When standing on the ground, do not apply I controls and zero the yaw stick. |
* Probably to avoid integration effects that will cause the copter to spin |
* or flip when taking off. |
*/ |
if(isFlying < 256) { |
IPart[PITCH] = IPart[ROLL] = 0; |
// TODO: Don't stomp on other modules' variables!!! |
// controlYaw = 0; |
PDPartYaw = 0; // instead. |
if(isFlying == 250) { |
// HC_setGround(); |
updateCompassCourse = 1; |
yawAngleDiff = 0; |
} |
} else { |
// Set fly flag. TODO: Hmmm what can we trust - the isFlying counter or the flag? |
// Answer: The counter. The flag is not read from anywhere anyway... except the NC maybe. |
MKFlags |= (MKFLAG_FLY); |
} |
if (emergencyFlightTime) { |
// continue emergency flight |
emergencyFlightTime--; |
if (isFlying > 256) { |
// We're probably still flying. Descend slowly. |
throttleTerm = staticParams.EmergencyGas; // Set emergency throttle |
MKFlags |= (MKFLAG_EMERGENCY_LANDING); // Set flag for emergency landing |
setStableFlightParameters(); |
} else { |
MKFlags &= ~(MKFLAG_MOTOR_RUN); // Probably not flying, and bad R/C signal. Kill motors. |
} |
} else { |
// end emergency flight (just cut the motors???) |
MKFlags &= ~(MKFLAG_MOTOR_RUN | MKFLAG_EMERGENCY_LANDING); |
} |
} else { |
// signal is acceptable |
if (controlMixer_getSignalQuality() > SIGNAL_BAD) { |
// Reset emergency landing control variables. |
MKFlags &= ~(MKFLAG_EMERGENCY_LANDING); // clear flag for emergency landing |
// The time is in whole seconds. |
emergencyFlightTime = (uint16_t) staticParams.EmergencyGasDuration * 488; |
} |
commands_handleCommands(); |
// If some throttle is given, and the motor-run flag is on, increase the probability that we are flying. |
if (throttleTerm > 40 && (MKFlags & MKFLAG_MOTOR_RUN)) { |
// increment flight-time counter until overflow. |
if (isFlying != 0xFFFF) |
isFlying++; |
} else |
/* |
* When standing on the ground, do not apply I controls and zero the yaw stick. |
* Probably to avoid integration effects that will cause the copter to spin |
* or flip when taking off. |
*/ |
if (isFlying < 256) { |
IPart[PITCH] = IPart[ROLL] = 0; |
// TODO: Don't stomp on other modules' variables!!! |
// controlYaw = 0; |
PDPartYaw = 0; // instead. |
if (isFlying == 250) { |
// HC_setGround(); |
updateCompassCourse = 1; |
yawAngleDiff = 0; |
} |
} else { |
// Set fly flag. TODO: Hmmm what can we trust - the isFlying counter or the flag? |
// Answer: The counter. The flag is not read from anywhere anyway... except the NC maybe. |
MKFlags |= (MKFLAG_FLY); |
} |
// if(controlMixer_getSignalQuality() >= SIGNAL_GOOD) { |
setNormalFlightParameters(); |
// } |
} // end else (not bad signal case) |
// end part1a: 750-800 usec. |
/* |
* Looping the H&I way basically is just a matter of turning off attitude angle measurement |
* by integration (because 300 deg/s gyros are too slow) and turning down the throttle. |
* This is the throttle part. |
*/ |
if(looping) { |
if(throttleTerm > staticParams.LoopGasLimit) throttleTerm = staticParams.LoopGasLimit; |
} |
/************************************************************************/ |
/* Yawing */ |
/************************************************************************/ |
if(abs(controlYaw) > 4 * staticParams.StickYawP) { // yaw stick is activated |
ignoreCompassTimer = 1000; |
if(!(staticParams.GlobalConfig & CFG_COMPASS_FIX)) { |
updateCompassCourse = 1; |
} |
} |
// yawControlRate = controlYaw; |
commands_handleCommands(); |
// Trim drift of yawAngleDiff with controlYaw. |
// TODO: We want NO feedback of control related stuff to the attitude related stuff. |
// This seems to be used as: Difference desired <--> real heading. |
yawAngleDiff -= controlYaw; |
// limit the effect |
CHECK_MIN_MAX(yawAngleDiff, -50000, 50000); |
/************************************************************************/ |
/* Compass is currently not supported. */ |
/************************************************************************/ |
if(staticParams.GlobalConfig & (CFG_COMPASS_ACTIVE|CFG_GPS_ACTIVE)) { |
updateCompass(); |
} |
// if(controlMixer_getSignalQuality() >= SIGNAL_GOOD) { |
setNormalFlightParameters(); |
// } |
} // end else (not bad signal case) |
// end part1a: 750-800 usec. |
/* |
* Looping the H&I way basically is just a matter of turning off attitude angle measurement |
* by integration (because 300 deg/s gyros are too slow) and turning down the throttle. |
* This is the throttle part. |
*/ |
if (looping) { |
if (throttleTerm > staticParams.LoopGasLimit) |
throttleTerm = staticParams.LoopGasLimit; |
} |
/************************************************************************/ |
/* Yawing */ |
/************************************************************************/ |
if (abs(controlYaw) > 4 * staticParams.StickYawP) { // yaw stick is activated |
ignoreCompassTimer = 1000; |
if (!(staticParams.GlobalConfig & CFG_COMPASS_FIX)) { |
updateCompassCourse = 1; |
} |
} |
// yawControlRate = controlYaw; |
// Trim drift of yawAngleDiff with controlYaw. |
// TODO: We want NO feedback of control related stuff to the attitude related stuff. |
// This seems to be used as: Difference desired <--> real heading. |
yawAngleDiff -= controlYaw; |
// limit the effect |
CHECK_MIN_MAX(yawAngleDiff, -50000, 50000); |
/************************************************************************/ |
/* Compass is currently not supported. */ |
/************************************************************************/ |
if (staticParams.GlobalConfig & (CFG_COMPASS_ACTIVE | CFG_GPS_ACTIVE)) { |
updateCompass(); |
} |
#if defined (USE_NAVICTRL) |
/************************************************************************/ |
/* GPS is currently not supported. */ |
/************************************************************************/ |
if(staticParams.GlobalConfig & CFG_GPS_ACTIVE) { |
GPS_Main(); |
MKFlags &= ~(MKFLAG_CALIBRATE | MKFLAG_START); |
} else { |
// GPSStickPitch = 0; |
// GPSStickRoll = 0; |
} |
/************************************************************************/ |
/* GPS is currently not supported. */ |
/************************************************************************/ |
if(staticParams.GlobalConfig & CFG_GPS_ACTIVE) { |
GPS_Main(); |
MKFlags &= ~(MKFLAG_CALIBRATE | MKFLAG_START); |
} else { |
// GPSStickPitch = 0; |
// GPSStickRoll = 0; |
} |
#endif |
// end part 1: 750-800 usec. |
// start part 3: 350 - 400 usec. |
// end part 1: 750-800 usec. |
// start part 3: 350 - 400 usec. |
#define SENSOR_LIMIT (4096 * 4) |
/************************************************************************/ |
/************************************************************************/ |
/* Calculate control feedback from angle (gyro integral) */ |
/* and angular velocity (gyro signal) */ |
/************************************************************************/ |
// The P-part is the P of the PID controller. That's the angle integrals (not rates). |
for (axis=PITCH; axis<=ROLL; axis++) { |
if(looping & ((1<<4)<<axis)) { |
PPart[axis] = 0; |
} else { // TODO: Where do the 44000 come from??? |
PPart[axis] = angle[axis] * gyroIFactor / (44000 / CONTROL_SCALING); // P-Part - Proportional to Integral |
} |
/* Calculate control feedback from angle (gyro integral) */ |
/* and angular velocity (gyro signal) */ |
/************************************************************************/ |
// The P-part is the P of the PID controller. That's the angle integrals (not rates). |
for (axis = PITCH; axis <= ROLL; axis++) { |
if (looping & ((1 << 4) << axis)) { |
PPart[axis] = 0; |
} else { // TODO: Where do the 44000 come from??? |
PPart[axis] = angle[axis] * gyroIFactor / (44000 / CONTROL_SCALING); // P-Part - Proportional to Integral |
} |
/* |
* Now blend in the D-part - proportional to the Differential of the integral = the rate. |
* Read this as: PDPart = PPart + rate_PID * pfactor * CONTROL_SCALING |
* where pfactor is in [0..1]. |
*/ |
PDPart[axis] = PPart[axis] + (int32_t)((int32_t)rate_PID[axis] * gyroPFactor / (256L / CONTROL_SCALING)) |
+ (differential[axis] * (int16_t)dynamicParams.GyroD) / 16; |
/* |
* Now blend in the D-part - proportional to the Differential of the integral = the rate. |
* Read this as: PDPart = PPart + rate_PID * pfactor * CONTROL_SCALING |
* where pfactor is in [0..1]. |
*/ |
PDPart[axis] = PPart[axis] + (int32_t) ((int32_t) rate_PID[axis] |
* gyroPFactor / (256L / CONTROL_SCALING)) + (differential[axis] |
* (int16_t) dynamicParams.GyroD) / 16; |
CHECK_MIN_MAX(PDPart[axis], -SENSOR_LIMIT, SENSOR_LIMIT); |
} |
CHECK_MIN_MAX(PDPart[axis], -SENSOR_LIMIT, SENSOR_LIMIT); |
} |
PDPartYaw = |
(int32_t)(yawRate * 2 * (int32_t)yawPFactor) / (256L / CONTROL_SCALING) |
+ (int32_t)(yawAngleDiff * yawIFactor) / (2 * (44000 / CONTROL_SCALING)); |
// limit control feedback |
CHECK_MIN_MAX(PDPartYaw, -SENSOR_LIMIT, SENSOR_LIMIT); |
/* |
* Compose throttle term. |
* If a Bl-Ctrl is missing, prevent takeoff. |
*/ |
if(missingMotor) { |
// if we are in the lift off condition. Hmmmmmm when is throttleTerm == 0 anyway??? |
if(isFlying > 1 && isFlying < 50 && throttleTerm > 0) |
isFlying = 1; // keep within lift off condition |
throttleTerm = staticParams.MinThrottle; // reduce gas to min to avoid lift of |
} |
PDPartYaw = (int32_t) (yawRate * 2 * (int32_t) yawPFactor) / (256L |
/ CONTROL_SCALING) + (int32_t) (yawAngleDiff * yawIFactor) / (2 * (44000 |
/ CONTROL_SCALING)); |
// Scale up to higher resolution. Hmm why is it not (from controlMixer and down) scaled already? |
throttleTerm *= CONTROL_SCALING; |
// limit control feedback |
CHECK_MIN_MAX(PDPartYaw, -SENSOR_LIMIT, SENSOR_LIMIT); |
/* |
* Compose yaw term. |
* The yaw term is limited: Absolute value is max. = the throttle term / 2. |
* However, at low throttle the yaw term is limited to a fixed value, |
* and at high throttle it is limited by the throttle reserve (the difference |
* between current throttle and maximum throttle). |
*/ |
/* |
* Compose throttle term. |
* If a Bl-Ctrl is missing, prevent takeoff. |
*/ |
if (missingMotor) { |
// if we are in the lift off condition. Hmmmmmm when is throttleTerm == 0 anyway??? |
if (isFlying > 1 && isFlying < 50 && throttleTerm > 0) |
isFlying = 1; // keep within lift off condition |
throttleTerm = staticParams.MinThrottle; // reduce gas to min to avoid lift of |
} |
// Scale up to higher resolution. Hmm why is it not (from controlMixer and down) scaled already? |
throttleTerm *= CONTROL_SCALING; |
/* |
* Compose yaw term. |
* The yaw term is limited: Absolute value is max. = the throttle term / 2. |
* However, at low throttle the yaw term is limited to a fixed value, |
* and at high throttle it is limited by the throttle reserve (the difference |
* between current throttle and maximum throttle). |
*/ |
#define MIN_YAWGAS (40 * CONTROL_SCALING) // yaw also below this gas value |
yawTerm = PDPartYaw - controlYaw * CONTROL_SCALING; |
// Limit yawTerm |
if(throttleTerm > MIN_YAWGAS) { |
CHECK_MIN_MAX(yawTerm, - (throttleTerm / 2), (throttleTerm / 2)); |
} else { |
CHECK_MIN_MAX(yawTerm, - (MIN_YAWGAS / 2), (MIN_YAWGAS / 2)); |
} |
yawTerm = PDPartYaw - controlYaw * CONTROL_SCALING; |
// Limit yawTerm |
if (throttleTerm > MIN_YAWGAS) { |
CHECK_MIN_MAX(yawTerm, - (throttleTerm / 2), (throttleTerm / 2)); |
} else { |
CHECK_MIN_MAX(yawTerm, - (MIN_YAWGAS / 2), (MIN_YAWGAS / 2)); |
} |
tmp_int = staticParams.MaxThrottle * CONTROL_SCALING; |
CHECK_MIN_MAX(yawTerm, -(tmp_int - throttleTerm), (tmp_int - throttleTerm)); |
tmp_int = staticParams.MaxThrottle * CONTROL_SCALING; |
CHECK_MIN_MAX(yawTerm, -(tmp_int - throttleTerm), (tmp_int - throttleTerm)); |
tmp_int = (int32_t)((int32_t)dynamicParams.DynamicStability * (int32_t)(throttleTerm + abs(yawTerm) / 2)) / 64; |
tmp_int = (int32_t) ((int32_t) dynamicParams.DynamicStability |
* (int32_t) (throttleTerm + abs(yawTerm) / 2)) / 64; |
for (axis=PITCH; axis<=ROLL; axis++) { |
/* |
* Compose pitch and roll terms. This is finally where the sticks come into play. |
*/ |
if(gyroIFactor) { |
// Integration mode: Integrate (angle - stick) = the difference between angle and stick pos. |
// That means: Holding the stick a little forward will, at constant flight attitude, cause this to grow (decline??) over time. |
// TODO: Find out why this seems to be proportional to stick position - not integrating it at all. |
IPart[axis] += PPart[axis] - control[axis]; // Integrate difference between P part (the angle) and the stick pos. |
} else { |
// "HH" mode: Integrate (rate - stick) = the difference between rotation rate and stick pos. |
// To keep up with a full stick PDPart should be about 156... |
IPart[axis] += PDPart[axis] - control[axis]; // With gyroIFactor == 0, PDPart is really just a D-part. Integrate D-part (the rot. rate) and the stick pos. |
} |
for (axis = PITCH; axis <= ROLL; axis++) { |
/* |
* Compose pitch and roll terms. This is finally where the sticks come into play. |
*/ |
if (gyroIFactor) { |
// Integration mode: Integrate (angle - stick) = the difference between angle and stick pos. |
// That means: Holding the stick a little forward will, at constant flight attitude, cause this to grow (decline??) over time. |
// TODO: Find out why this seems to be proportional to stick position - not integrating it at all. |
IPart[axis] += PPart[axis] - control[axis]; // Integrate difference between P part (the angle) and the stick pos. |
} else { |
// "HH" mode: Integrate (rate - stick) = the difference between rotation rate and stick pos. |
// To keep up with a full stick PDPart should be about 156... |
IPart[axis] += PDPart[axis] - control[axis]; // With gyroIFactor == 0, PDPart is really just a D-part. Integrate D-part (the rot. rate) and the stick pos. |
} |
// TODO: From which planet comes the 16000? |
CHECK_MIN_MAX(IPart[axis], -(CONTROL_SCALING * 16000L), (CONTROL_SCALING * 16000L)); |
// Add (P, D) parts minus stick pos. to the scaled-down I part. |
term[axis] = PDPart[axis] - control[axis] + IPart[axis] / Ki; // PID-controller for pitch |
// TODO: From which planet comes the 16000? |
CHECK_MIN_MAX(IPart[axis], -(CONTROL_SCALING * 16000L), (CONTROL_SCALING * 16000L)); |
// Add (P, D) parts minus stick pos. to the scaled-down I part. |
term[axis] = PDPart[axis] - control[axis] + IPart[axis] / Ki; // PID-controller for pitch |
/* |
* Apply "dynamic stability" - that is: Limit pitch and roll terms to a growing function of throttle and yaw(!). |
* The higher the dynamic stability parameter, the wider the bounds. 64 seems to be a kind of unity |
* (max. pitch or roll term is the throttle value). |
* TODO: Why a growing function of yaw? |
*/ |
CHECK_MIN_MAX(term[axis], -tmp_int, tmp_int); |
} |
// end part 3: 350 - 400 usec. |
/* |
* Apply "dynamic stability" - that is: Limit pitch and roll terms to a growing function of throttle and yaw(!). |
* The higher the dynamic stability parameter, the wider the bounds. 64 seems to be a kind of unity |
* (max. pitch or roll term is the throttle value). |
* TODO: Why a growing function of yaw? |
*/ |
CHECK_MIN_MAX(term[axis], -tmp_int, tmp_int); |
} |
// end part 3: 350 - 400 usec. |
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
// Universal Mixer |
// Each (pitch, roll, throttle, yaw) term is in the range [0..255 * CONTROL_SCALING]. |
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
// Universal Mixer |
// Each (pitch, roll, throttle, yaw) term is in the range [0..255 * CONTROL_SCALING]. |
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
DebugOut.Analog[12] = term[PITCH]; |
DebugOut.Analog[13] = term[ROLL]; |
DebugOut.Analog[14] = yawTerm; |
DebugOut.Analog[15] = throttleTerm; |
DebugOut.Analog[12] = term[PITCH]; |
DebugOut.Analog[13] = term[ROLL]; |
DebugOut.Analog[14] = yawTerm; |
DebugOut.Analog[15] = throttleTerm; |
for(i = 0; i < MAX_MOTORS; i++) { |
int16_t tmp; |
if (MKFlags & MKFLAG_MOTOR_RUN && Mixer.Motor[i][MIX_THROTTLE] > 0) { |
tmp = ((int32_t)throttleTerm * Mixer.Motor[i][MIX_THROTTLE]) / 64L; |
tmp += ((int32_t)term[PITCH] * Mixer.Motor[i][MIX_PITCH]) / 64L; |
tmp += ((int32_t)term[ROLL] * Mixer.Motor[i][MIX_ROLL]) / 64L; |
tmp += ((int32_t)yawTerm * Mixer.Motor[i][MIX_YAW]) / 64L; |
motorFilters[i] = motorFilter(tmp, motorFilters[i]); |
// Now we scale back down to a 0..255 range. |
tmp = motorFilters[i] / CONTROL_SCALING; |
// So this was the THIRD time a throttle was limited. But should the limitation |
// apply to the common throttle signal (the one used for setting the "power" of |
// all motors together) or should it limit the throttle set for each motor, |
// including mix components of pitch, roll and yaw? I think only the common |
// throttle should be limited. |
// --> WRONG. This caused motors to stall completely in tight maneuvers. |
// Apply to individual signals instead. |
CHECK_MIN_MAX(tmp, staticParams.MinThrottle, staticParams.MaxThrottle); |
CHECK_MIN_MAX(tmp, 1, 255); |
motor[i].SetPoint = tmp; |
} |
else if (motorTestActive) { |
motor[i].SetPoint = motorTest[i]; |
} else { |
motor[i].SetPoint = 0; |
} |
if (i < 4) |
DebugOut.Analog[22+i] = motor[i].SetPoint; |
} |
I2C_Start(TWI_STATE_MOTOR_TX); |
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
// Debugging |
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
if(!(--debugDataTimer)) { |
debugDataTimer = 24; // update debug outputs at 488 / 24 = 20.3 Hz. |
DebugOut.Analog[0] = (10 * angle[PITCH]) / GYRO_DEG_FACTOR_PITCHROLL; // in 0.1 deg |
DebugOut.Analog[1] = (10 * angle[ROLL]) / GYRO_DEG_FACTOR_PITCHROLL; // in 0.1 deg |
DebugOut.Analog[2] = yawGyroHeading / GYRO_DEG_FACTOR_YAW; |
for (i = 0; i < MAX_MOTORS; i++) { |
int16_t tmp; |
if (MKFlags & MKFLAG_MOTOR_RUN && Mixer.Motor[i][MIX_THROTTLE] > 0) { |
tmp = ((int32_t) throttleTerm * Mixer.Motor[i][MIX_THROTTLE]) / 64L; |
tmp += ((int32_t) term[PITCH] * Mixer.Motor[i][MIX_PITCH]) / 64L; |
tmp += ((int32_t) term[ROLL] * Mixer.Motor[i][MIX_ROLL]) / 64L; |
tmp += ((int32_t) yawTerm * Mixer.Motor[i][MIX_YAW]) / 64L; |
motorFilters[i] = motorFilter(tmp, motorFilters[i]); |
// Now we scale back down to a 0..255 range. |
tmp = motorFilters[i] / CONTROL_SCALING; |
// So this was the THIRD time a throttle was limited. But should the limitation |
// apply to the common throttle signal (the one used for setting the "power" of |
// all motors together) or should it limit the throttle set for each motor, |
// including mix components of pitch, roll and yaw? I think only the common |
// throttle should be limited. |
// --> WRONG. This caused motors to stall completely in tight maneuvers. |
// Apply to individual signals instead. |
CHECK_MIN_MAX(tmp, staticParams.MinThrottle, staticParams.MaxThrottle); |
CHECK_MIN_MAX(tmp, 1, 255); |
motor[i].SetPoint = tmp; |
} else if (motorTestActive) { |
motor[i].SetPoint = motorTest[i]; |
} else { |
motor[i].SetPoint = 0; |
} |
if (i < 4) |
DebugOut.Analog[22 + i] = motor[i].SetPoint; |
} |
I2C_Start(TWI_STATE_MOTOR_TX); |
/* |
DebugOut.Analog[23] = (yawRate * 2 * (int32_t)yawPFactor) / (256L / CONTROL_SCALING); |
DebugOut.Analog[24] = controlYaw; |
DebugOut.Analog[25] = yawAngleDiff / 100L; |
DebugOut.Analog[26] = accNoisePeak[PITCH]; |
DebugOut.Analog[27] = accNoisePeak[ROLL]; |
DebugOut.Analog[30] = gyroNoisePeak[PITCH]; |
DebugOut.Analog[31] = gyroNoisePeak[ROLL]; |
*/ |
} |
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
// Debugging |
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
if (!(--debugDataTimer)) { |
debugDataTimer = 24; // update debug outputs at 488 / 24 = 20.3 Hz. |
DebugOut.Analog[0] = (10 * angle[PITCH]) / GYRO_DEG_FACTOR_PITCHROLL; // in 0.1 deg |
DebugOut.Analog[1] = (10 * angle[ROLL]) / GYRO_DEG_FACTOR_PITCHROLL; // in 0.1 deg |
DebugOut.Analog[2] = yawGyroHeading / GYRO_DEG_FACTOR_YAW; |
/* |
DebugOut.Analog[23] = (yawRate * 2 * (int32_t)yawPFactor) / (256L / CONTROL_SCALING); |
DebugOut.Analog[24] = controlYaw; |
DebugOut.Analog[25] = yawAngleDiff / 100L; |
DebugOut.Analog[26] = accNoisePeak[PITCH]; |
DebugOut.Analog[27] = accNoisePeak[ROLL]; |
DebugOut.Analog[30] = gyroNoisePeak[PITCH]; |
DebugOut.Analog[31] = gyroNoisePeak[ROLL]; |
*/ |
} |
} |
/branches/dongfang_FC_rewrite/gps.c |
---|
202,8 → 202,7 |
if (pTargetPos->Status != INVALID) // and the position data are valid |
{ |
// if the target data are updated or the target pointer has changed |
if ((pTargetPos->Status != PROCESSED) || (pTargetPos |
!= pLastTargetPos)) { |
if ((pTargetPos->Status != PROCESSED) || (pTargetPos != pLastTargetPos)) { |
// reset error integral |
GPSPosDevIntegral_North = 0; |
GPSPosDevIntegral_East = 0; |
251,8 → 250,7 |
// I-Part |
I_North = ((int32_t) dynamicParams.NaviGpsI * GPSPosDevIntegral_North) |
/ 8192; |
I_East = ((int32_t) dynamicParams.NaviGpsI * GPSPosDevIntegral_East) |
/ 8192; |
I_East = ((int32_t) dynamicParams.NaviGpsI * GPSPosDevIntegral_East) / 8192; |
// combine P & I |
PID_North = P_North + I_North; |
412,8 → 410,8 |
// beep if signal is not sufficient |
if (!(GPSInfo.flags & FLAG_GPSFIXOK) && !(beep_rythm % 5)) |
BeepTime = 100; |
else if (GPSInfo.satnum < staticParams.NaviGpsMinSat |
&& !(beep_rythm % 5)) |
else if (GPSInfo.satnum < staticParams.NaviGpsMinSat && !(beep_rythm |
% 5)) |
BeepTime = 10; |
} |
} |
/branches/dongfang_FC_rewrite/gps.h |
---|
6,4 → 6,3 |
extern void GPS_Main(void); |
#endif //_GPS_H |
/branches/dongfang_FC_rewrite/heightControl.c |
---|
13,11 → 13,11 |
#define INTEGRAL_LIMIT 100000 |
/* |
#define DEBUGINTEGRAL 0 |
#define DEBUGDIFFERENTIAL 0 |
#define DEBUGHOVERTHROTTLE 0 |
#define DEBUGHEIGHTSWITCH 0 |
*/ |
#define DEBUGINTEGRAL 0 |
#define DEBUGDIFFERENTIAL 0 |
#define DEBUGHOVERTHROTTLE 0 |
#define DEBUGHEIGHTSWITCH 0 |
*/ |
#define LATCH_TIME 40 |
36,70 → 36,70 |
int32_t maxHeight; |
int32_t iHeight; |
/* |
These parameters are free to take: |
uint8_t HeightMinGas; // Value : 0-100 |
uint8_t HeightD; // Value : 0-250 |
uint8_t MaxHeight; // Value : 0-32 |
uint8_t HeightP; // Value : 0-32 |
uint8_t Height_Gain; // Value : 0-50 |
uint8_t Height_ACC_Effect; // Value : 0-250 |
These parameters are free to take: |
uint8_t HeightMinGas; // Value : 0-100 |
uint8_t HeightD; // Value : 0-250 |
uint8_t MaxHeight; // Value : 0-32 |
uint8_t HeightP; // Value : 0-32 |
uint8_t Height_Gain; // Value : 0-50 |
uint8_t Height_ACC_Effect; // Value : 0-250 |
*/ |
int32_t getHeight(void) { |
return groundPressure - filteredAirPressure; |
return groundPressure - filteredAirPressure; |
} |
void HC_setGround(void) { |
groundPressure = filteredAirPressure; |
// This should also happen when height control is enabled in-flight. |
rampedTargetHeight = getHeight(); |
maxHeight = 0; |
iHeight = 0; |
groundPressure = filteredAirPressure; |
// This should also happen when height control is enabled in-flight. |
rampedTargetHeight = getHeight(); |
maxHeight = 0; |
iHeight = 0; |
} |
void HC_update(void) { |
int32_t height = getHeight(); |
static uint8_t setHeightLatch = 0; |
int32_t height = getHeight(); |
static uint8_t setHeightLatch = 0; |
if (height > maxHeight) |
maxHeight = height; |
if (height > maxHeight) |
maxHeight = height; |
if (staticParams.GlobalConfig & CFG_HEIGHT_SWITCH) { |
// If switch is activated in config |
DebugOut.Digital[0] |= DEBUG_HEIGHT_SWITCH; |
if (dynamicParams.MaxHeight < 40 || dynamicParams.MaxHeight > 255-40) { |
// Switch is ON |
if (setHeightLatch <= LATCH_TIME) { |
if (setHeightLatch == LATCH_TIME) { |
// Freeze the height as target. We want to do this exactly once each time the switch is thrown ON. |
targetHeight = height; |
DebugOut.Digital[1] |= DEBUG_HEIGHT_SWITCH; |
if (staticParams.GlobalConfig & CFG_HEIGHT_SWITCH) { |
// If switch is activated in config |
DebugOut.Digital[0] |= DEBUG_HEIGHT_SWITCH; |
if (dynamicParams.MaxHeight < 40 || dynamicParams.MaxHeight > 255 - 40) { |
// Switch is ON |
if (setHeightLatch <= LATCH_TIME) { |
if (setHeightLatch == LATCH_TIME) { |
// Freeze the height as target. We want to do this exactly once each time the switch is thrown ON. |
targetHeight = height; |
DebugOut.Digital[1] |= DEBUG_HEIGHT_SWITCH; |
} |
// Time not yet reached. |
setHeightLatch++; |
} |
} else { |
// Switch is OFF. |
setHeightLatch = 0; |
DebugOut.Digital[1] &= ~DEBUG_HEIGHT_SWITCH; |
} |
} else { |
// Switch is not activated; take the "max-height" as the target height. |
DebugOut.Digital[0] &= ~DEBUG_HEIGHT_SWITCH; |
targetHeight = (uint16_t) dynamicParams.MaxHeight * 100; //getHeight() + 10 * 100; |
} |
// Time not yet reached. |
setHeightLatch++; |
} |
} else { |
// Switch is OFF. |
setHeightLatch = 0; |
DebugOut.Digital[1] &= ~DEBUG_HEIGHT_SWITCH; |
} |
} else { |
// Switch is not activated; take the "max-height" as the target height. |
DebugOut.Digital[0] &= ~DEBUG_HEIGHT_SWITCH; |
targetHeight = (uint16_t)dynamicParams.MaxHeight * 100; //getHeight() + 10 * 100; |
} |
if (++heightRampingTimer == INTEGRATION_FREQUENCY/10) { |
heightRampingTimer = 0; |
if (rampedTargetHeight + staticParams.Height_Gain <= targetHeight) { |
rampedTargetHeight += staticParams.Height_Gain; |
} else if (rampedTargetHeight - staticParams.Height_Gain >= targetHeight) { |
rampedTargetHeight -= staticParams.Height_Gain; |
} |
} |
// height, in meters (so the division factor is: 100) |
DebugOut.Analog[30] = height / 100; |
if (++heightRampingTimer == INTEGRATION_FREQUENCY / 10) { |
heightRampingTimer = 0; |
if (rampedTargetHeight + staticParams.Height_Gain <= targetHeight) { |
rampedTargetHeight += staticParams.Height_Gain; |
} else if (rampedTargetHeight - staticParams.Height_Gain >= targetHeight) { |
rampedTargetHeight -= staticParams.Height_Gain; |
} |
} |
// height, in meters (so the division factor is: 100) |
DebugOut.Analog[30] = height / 100; |
} |
// ParamSet.GlobalConfig & CFG_HEIGHT_CONTROL |
109,69 → 109,77 |
// takes 180-200 usec (with integral term). That is too heavy!!! |
// takes 100 usec without integral term. |
uint16_t HC_getThrottle(uint16_t throttle) { |
int32_t height = getHeight(); |
int32_t heightError = rampedTargetHeight - height; |
static int32_t lastHeight; |
int32_t height = getHeight(); |
int32_t heightError = rampedTargetHeight - height; |
int16_t dHeight = height - lastHeight; |
lastHeight = height; |
static int32_t lastHeight; |
// DebugOut.Analog[20] = dHeight; |
// DebugOut.Analog[21] = dynamicParams.MaxHeight; |
int16_t dHeight = height - lastHeight; |
lastHeight = height; |
// iHeight, at a difference of 5 meters and a freq. of 488 Hz, will grow with 244000 / sec.... |
// iHeight += heightError; |
// DebugOut.Analog[20] = dHeight; |
// DebugOut.Analog[21] = dynamicParams.MaxHeight; |
if (dHeight > 0) { |
DebugOut.Digital[0] |= DEBUG_HEIGHT_DIFF; |
DebugOut.Digital[1] &= ~DEBUG_HEIGHT_DIFF; |
} else if (dHeight < 0) { |
DebugOut.Digital[1] |= DEBUG_HEIGHT_DIFF; |
DebugOut.Digital[0] &= ~DEBUG_HEIGHT_DIFF; |
} |
// iHeight, at a difference of 5 meters and a freq. of 488 Hz, will grow with 244000 / sec.... |
// iHeight += heightError; |
/* |
if (iHeight > INTEGRAL_LIMIT) { iHeight = INTEGRAL_LIMIT; if (DEBUGINTEGRAL) {DebugOut.Digital[0] = 1; DebugOut.Digital[1] = 1;}} |
else if (iHeight < -INTEGRAL_LIMIT) { iHeight = -INTEGRAL_LIMIT; if (DEBUGINTEGRAL) {DebugOut.Digital[0] = 0; DebugOut.Digital[1] = 0; }} |
else if (iHeight > 0) { if (DEBUGINTEGRAL) DebugOut.Digital[0] = 1;} |
else if (iHeight < 0) { if (DEBUGINTEGRAL) DebugOut.Digital[1] = 1;} |
*/ |
if (dHeight > 0) { |
DebugOut.Digital[0] |= DEBUG_HEIGHT_DIFF; |
DebugOut.Digital[1] &= ~DEBUG_HEIGHT_DIFF; |
} else if (dHeight < 0) { |
DebugOut.Digital[1] |= DEBUG_HEIGHT_DIFF; |
DebugOut.Digital[0] &= ~DEBUG_HEIGHT_DIFF; |
} |
int16_t dThrottle = heightError * staticParams.HeightP / 1000 /*+ iHeight / 10000L * staticParams.Height_ACC_Effect */ - dHeight * staticParams.HeightD; |
/* |
if (iHeight > INTEGRAL_LIMIT) { iHeight = INTEGRAL_LIMIT; if (DEBUGINTEGRAL) {DebugOut.Digital[0] = 1; DebugOut.Digital[1] = 1;}} |
else if (iHeight < -INTEGRAL_LIMIT) { iHeight = -INTEGRAL_LIMIT; if (DEBUGINTEGRAL) {DebugOut.Digital[0] = 0; DebugOut.Digital[1] = 0; }} |
else if (iHeight > 0) { if (DEBUGINTEGRAL) DebugOut.Digital[0] = 1;} |
else if (iHeight < 0) { if (DEBUGINTEGRAL) DebugOut.Digital[1] = 1;} |
*/ |
// the "minGas" is now a limit for how much up / down the throttle can be varied |
if (dThrottle > staticParams.HeightMinGas) dThrottle = staticParams.HeightMinGas; |
else if (dThrottle < -staticParams.HeightMinGas) dThrottle = -staticParams.HeightMinGas; |
int16_t dThrottle = heightError * staticParams.HeightP / 1000 |
/*+ iHeight / 10000L * staticParams.Height_ACC_Effect */- dHeight |
* staticParams.HeightD; |
//DebugOut.Analog[18] = dThrottle; |
//DebugOut.Analog[19] = iHeight / 10000L; |
// the "minGas" is now a limit for how much up / down the throttle can be varied |
if (dThrottle > staticParams.HeightMinGas) |
dThrottle = staticParams.HeightMinGas; |
else if (dThrottle < -staticParams.HeightMinGas) |
dThrottle = -staticParams.HeightMinGas; |
// TODO: Eliminate repitition. |
if (staticParams.GlobalConfig & CFG_HEIGHT_CONTROL) { |
if (!(staticParams.GlobalConfig & CFG_HEIGHT_SWITCH) || (dynamicParams.MaxHeight < 40 || dynamicParams.MaxHeight > 255-40)) { |
// If switch is not in use --> Just apply height control. |
// If switch is in use --> only apply height control when switch is also ON. |
throttle += dThrottle; |
} |
} |
/* Experiment: Find hover-throttle */ |
stronglyFilteredHeightDiff = (stronglyFilteredHeightDiff * (HOVERTHROTTLEFILTER - 1) + dHeight) / HOVERTHROTTLEFILTER; |
stronglyFilteredThrottle = (stronglyFilteredThrottle * (HOVERTHROTTLEFILTER - 1) + throttle) / HOVERTHROTTLEFILTER; |
//DebugOut.Analog[18] = dThrottle; |
//DebugOut.Analog[19] = iHeight / 10000L; |
if (isFlying >= 1000 && stronglyFilteredHeightDiff < 3 && stronglyFilteredHeightDiff > -3) { |
hoverThrottle = stronglyFilteredThrottle; |
DebugOut.Digital[0] |= DEBUG_HOVERTHROTTLE; |
// DebugOut.Analog[18] = hoverThrottle; |
} else |
DebugOut.Digital[0] &= ~DEBUG_HOVERTHROTTLE; |
return throttle; |
// TODO: Eliminate repitition. |
if (staticParams.GlobalConfig & CFG_HEIGHT_CONTROL) { |
if (!(staticParams.GlobalConfig & CFG_HEIGHT_SWITCH) |
|| (dynamicParams.MaxHeight < 40 || dynamicParams.MaxHeight > 255 - 40)) { |
// If switch is not in use --> Just apply height control. |
// If switch is in use --> only apply height control when switch is also ON. |
throttle += dThrottle; |
} |
} |
/* Experiment: Find hover-throttle */ |
stronglyFilteredHeightDiff = (stronglyFilteredHeightDiff |
* (HOVERTHROTTLEFILTER - 1) + dHeight) / HOVERTHROTTLEFILTER; |
stronglyFilteredThrottle = (stronglyFilteredThrottle * (HOVERTHROTTLEFILTER |
- 1) + throttle) / HOVERTHROTTLEFILTER; |
if (isFlying >= 1000 && stronglyFilteredHeightDiff < 3 |
&& stronglyFilteredHeightDiff > -3) { |
hoverThrottle = stronglyFilteredThrottle; |
DebugOut.Digital[0] |= DEBUG_HOVERTHROTTLE; |
// DebugOut.Analog[18] = hoverThrottle; |
} else |
DebugOut.Digital[0] &= ~DEBUG_HOVERTHROTTLE; |
return throttle; |
} |
/* |
For a variometer thingy: |
When switch is thrown on, freeze throttle (capture it into variable) |
For each iter., add (throttle - frozen throttle) to target height. Maybe don't do ramping. |
Output = frozen throttle + whatever is computed +/-. Integral? |
*/ |
For a variometer thingy: |
When switch is thrown on, freeze throttle (capture it into variable) |
For each iter., add (throttle - frozen throttle) to target height. Maybe don't do ramping. |
Output = frozen throttle + whatever is computed +/-. Integral? |
*/ |
/branches/dongfang_FC_rewrite/heightControl.h |
---|
1,4 → 1,3 |
void HC_setGround(void); |
void HC_update(void); |
uint16_t HC_getThrottle(uint16_t throttle); |
void HC_setGround(void); |
void HC_update(void); |
uint16_t HC_getThrottle(uint16_t throttle); |
/branches/dongfang_FC_rewrite/invenSense.c |
---|
8,8 → 8,8 |
* Configuration for my prototype board with InvenSense gyros. |
* The FC 1.3 board is installed upside down, therefore Z acc is reversed but not roll. |
*/ |
const uint8_t GYRO_REVERSED[3] = {0,0,0}; |
const uint8_t ACC_REVERSED[3] = {0,0,1}; |
const uint8_t GYRO_REVERSED[3] = { 0, 0, 0 }; |
const uint8_t ACC_REVERSED[3] = { 0, 0, 1 }; |
#define AUTOZERO_PORT PORTD |
#define AUTOZERO_DDR DDRD |
16,27 → 16,28 |
#define AUTOZERO_BIT 5 |
void gyro_calibrate() { |
// If port not already set to output and high, do it. |
if (!(AUTOZERO_DDR & (1<<AUTOZERO_BIT)) || !(AUTOZERO_PORT & (1<<AUTOZERO_BIT))) { |
AUTOZERO_PORT |= (1<<AUTOZERO_BIT); |
AUTOZERO_DDR |= (1<<AUTOZERO_BIT); |
Delay_ms(100); |
} |
// Make a pulse on the auto-zero output line. |
AUTOZERO_PORT &= ~(1<<AUTOZERO_BIT); |
Delay_ms(1); |
AUTOZERO_PORT |= (1<<AUTOZERO_BIT); |
// Delay_ms(10); |
Delay_ms_Mess(100); |
// If port not already set to output and high, do it. |
if (!(AUTOZERO_DDR & (1 << AUTOZERO_BIT)) || !(AUTOZERO_PORT & (1 |
<< AUTOZERO_BIT))) { |
AUTOZERO_PORT |= (1 << AUTOZERO_BIT); |
AUTOZERO_DDR |= (1 << AUTOZERO_BIT); |
Delay_ms(100); |
} |
// Make a pulse on the auto-zero output line. |
AUTOZERO_PORT &= ~(1 << AUTOZERO_BIT); |
Delay_ms(1); |
AUTOZERO_PORT |= (1 << AUTOZERO_BIT); |
// Delay_ms(10); |
Delay_ms_Mess(100); |
} |
void gyro_setDefaults(void) { |
staticParams.GyroD = 3; |
staticParams.GyroAccFactor = 1; |
staticParams.DriftComp = 10; |
staticParams.GyroD = 3; |
staticParams.GyroAccFactor = 1; |
staticParams.DriftComp = 10; |
// Not used. |
staticParams.AngleTurnOverPitch = 85; |
staticParams.AngleTurnOverRoll = 85; |
// Not used. |
staticParams.AngleTurnOverPitch = 85; |
staticParams.AngleTurnOverRoll = 85; |
} |
/branches/dongfang_FC_rewrite/invenSense.h |
---|
1,30 → 1,30 |
/* |
#ifndef _INVENSENSE_H |
#define _INVENSENSE_H |
#ifndef _INVENSENSE_H |
#define _INVENSENSE_H |
#include "sensors.h" |
#include "sensors.h" |
#define GYRO_HW_NAME "ISens" |
#define GYRO_HW_NAME "ISens" |
/ * |
/ * |
* The InvenSense gyros have a lower sensitivity than for example the ADXRS610s on the FC 2.0 ME, |
* but they have a wider range too. |
* 2mV/deg/s gyros and no amplifiers: |
* H = 0.002 V / deg / s * 1 * 1024 / 3V = 0.6827 units/(deg/s) |
* / |
#define GYRO_HW_FACTOR 0.6827f |
#define GYRO_HW_FACTOR 0.6827f |
/ * |
/ * |
* Correction factor - determined experimentally: Hold the copter in the hand, and turn it 90 degrees. |
* If AnglePitch or AngleRoll in debug in MK-Tool changes by x degrees, multiply the value here by x/90. |
* If the hardware related contants are set correctly, flight should be OK without bothering to |
* make any adjustments here. It is only for luxury. |
* / |
#define GYRO_PITCHROLL_CORRECTION 0.93f |
#define GYRO_PITCHROLL_CORRECTION 0.93f |
/ * |
/ * |
* Same for yaw. |
* / |
#define GYRO_YAW_CORRECTION 0.97f |
#endif |
*/ |
#define GYRO_YAW_CORRECTION 0.97f |
#endif |
*/ |
/branches/dongfang_FC_rewrite/main.c |
---|
77,229 → 77,234 |
#endif |
#include "eeprom.h" |
int16_t main (void) { |
uint16_t timer; |
int16_t main(void) { |
uint16_t timer; |
// disable interrupts global |
cli(); |
// disable interrupts global |
cli(); |
// analyze hardware environment |
CPUType = getCPUType(); |
BoardRelease = getBoardRelease(); |
// analyze hardware environment |
CPUType = getCPUType(); |
BoardRelease = getBoardRelease(); |
// disable watchdog |
MCUSR &=~(1<<WDRF); |
WDTCSR |= (1<<WDCE)|(1<<WDE); |
WDTCSR = 0; |
// disable watchdog |
MCUSR &= ~(1 << WDRF); |
WDTCSR |= (1 << WDCE) | (1 << WDE); |
WDTCSR = 0; |
// PPM_in[CH_THROTTLE] = 0; |
// Why??? They are already initialized to 0. |
// stickPitch = stickRoll = stickYaw = 0; |
// PPM_in[CH_THROTTLE] = 0; |
// Why??? They are already initialized to 0. |
// stickPitch = stickRoll = stickYaw = 0; |
RED_OFF; |
RED_OFF; |
// initalize modules |
output_init(); |
timer0_init(); |
timer2_init(); |
usart0_Init(); |
if(CPUType == ATMEGA644P) usart1_Init(); |
RC_Init(); |
analog_init(); |
I2C_init(); |
// initalize modules |
output_init(); |
timer0_init(); |
timer2_init(); |
usart0_Init(); |
if (CPUType == ATMEGA644P) |
usart1_Init(); |
RC_Init(); |
analog_init(); |
I2C_init(); |
#ifdef USE_NAVICTRL |
SPI_MasterInit(); |
SPI_MasterInit(); |
#endif |
#ifdef USE_MK3MAG |
MK3MAG_Init(); |
MK3MAG_Init(); |
#endif |
// enable interrupts global |
sei(); |
printf("\n\r==================================="); |
printf("\n\rFlightControl"); |
printf("\n\rHardware: Custom"); |
printf("\r\n CPU: Atmega644"); |
if(CPUType == ATMEGA644P) |
printf("p"); |
printf("\n\rSoftware: V%d.%d%c",VERSION_MAJOR, VERSION_MINOR, VERSION_PATCH + 'a'); |
printf("\n\r==================================="); |
// enable interrupts global |
sei(); |
// Parameter Set handling |
ParamSet_Init(); |
printf("\n\r==================================="); |
printf("\n\rFlightControl"); |
printf("\n\rHardware: Custom"); |
printf("\r\n CPU: Atmega644"); |
if (CPUType == ATMEGA644P) |
printf("p"); |
printf("\n\rSoftware: V%d.%d%c",VERSION_MAJOR, VERSION_MINOR, VERSION_PATCH + 'a'); |
printf("\n\r==================================="); |
// Wait for a short time (otherwise the RC channel check won't work below) |
// timer = SetDelay(500); |
// while(!CheckDelay(timer)); |
// Parameter Set handling |
ParamSet_Init(); |
// Instead, while away the time by flashing the 2 outputs: |
// First J16, then J17. Makes it easier to see which is which. |
timer = SetDelay(200); |
OUTPUT_SET(0,1); |
GRN_OFF; |
RED_ON; |
while(!CheckDelay(timer)); |
// Wait for a short time (otherwise the RC channel check won't work below) |
// timer = SetDelay(500); |
// while(!CheckDelay(timer)); |
timer = SetDelay(200); |
OUTPUT_SET(0,0); |
OUTPUT_SET(1,1); |
RED_OFF; |
GRN_ON; |
while(!CheckDelay(timer)); |
// Instead, while away the time by flashing the 2 outputs: |
// First J16, then J17. Makes it easier to see which is which. |
timer = SetDelay(200); |
OUTPUT_SET(0,1); |
GRN_OFF; |
RED_ON; |
while (!CheckDelay(timer)) |
; |
timer = SetDelay(200); |
while(!CheckDelay(timer)); |
OUTPUT_SET(1,0); |
timer = SetDelay(200); |
OUTPUT_SET(0,0); |
OUTPUT_SET(1,1); |
RED_OFF; |
GRN_ON; |
while (!CheckDelay(timer)) |
; |
twi_diagnostics(); |
timer = SetDelay(200); |
while (!CheckDelay(timer)) |
; |
OUTPUT_SET(1,0); |
printf("\n\r==================================="); |
twi_diagnostics(); |
/* |
if(staticParams.GlobalConfig & CFG_HEIGHT_CONTROL) |
{ |
printf("\n\rCalibrating air pressure sensor.."); |
timer = SetDelay(1000); |
SearchAirPressureOffset(); |
while (!CheckDelay(timer)); |
printf("OK\n\r"); |
} |
*/ |
printf("\n\r==================================="); |
/* |
if(staticParams.GlobalConfig & CFG_HEIGHT_CONTROL) |
{ |
printf("\n\rCalibrating air pressure sensor.."); |
timer = SetDelay(1000); |
SearchAirPressureOffset(); |
while (!CheckDelay(timer)); |
printf("OK\n\r"); |
} |
*/ |
#ifdef USE_NAVICTRL |
printf("\n\rSupport for NaviCtrl"); |
printf("\n\rSupport for NaviCtrl"); |
#ifdef USE_RC_DSL |
printf("\r\nSupport for DSL RC at 2nd UART"); |
printf("\r\nSupport for DSL RC at 2nd UART"); |
#endif |
#ifdef USE_RC_SPECTRUM |
printf("\r\nSupport for SPECTRUM RC at 2nd UART"); |
printf("\r\nSupport for SPECTRUM RC at 2nd UART"); |
#endif |
#endif |
#ifdef USE_MK3MAG |
printf("\n\rSupport for MK3MAG Compass"); |
printf("\n\rSupport for MK3MAG Compass"); |
#endif |
#if (defined (USE_MK3MAG)) |
if(CPUType == ATMEGA644P) printf("\n\rSupport for GPS at 2nd UART"); |
else printf("\n\rSupport for GPS at 1st UART"); |
if(CPUType == ATMEGA644P) printf("\n\rSupport for GPS at 2nd UART"); |
else printf("\n\rSupport for GPS at 1st UART"); |
#endif |
controlMixer_setNeutral(); |
controlMixer_setNeutral(); |
// Cal. attitude sensors and reset integrals. |
attitude_setNeutral(); |
// Cal. attitude sensors and reset integrals. |
attitude_setNeutral(); |
Servo_On(); |
Servo_On(); |
// Init flight parameters |
flight_setNeutral(); |
// Init flight parameters |
flight_setNeutral(); |
// RED_OFF; |
// RED_OFF; |
beep(2000); |
printf("\n\rControl: "); |
if (staticParams.GlobalConfig & CFG_HEADING_HOLD) printf("HeadingHold"); |
else printf("Neutral (ACC-Mode)"); |
beep(2000); |
printf("\n\n\r"); |
printf("\n\rControl: "); |
if (staticParams.GlobalConfig & CFG_HEADING_HOLD) |
printf("HeadingHold"); |
else printf("Neutral (ACC-Mode)"); |
LCD_Clear(); |
printf("\n\n\r"); |
I2CTimeout = 5000; |
LCD_Clear(); |
while (1) { |
if(runFlightControl && analogDataReady) { // control interval |
runFlightControl = 0; // reset Flag, is enabled every 2 ms by ISR of timer0 |
J4HIGH; |
flight_control(); |
J4LOW; |
/* |
* If the motors are running (MKFlags & MKFLAG_MOTOR_RUN in flight.c), transmit |
* the throttle vector just computed. Otherwise, if motor test is engaged, transmit |
* the test throttle vector. If no testing, stop all motors. |
*/ |
// Obsoleted. |
// transmitMotorThrottleData(); |
RED_OFF; |
/* |
Does not belong here. Instead, external control should be ignored in |
controlMixer if there was no new data from there for some time. |
if(externalControlActive) externalControlActive--; |
else { |
externalControl.config = 0; |
externalStickPitch = 0; |
externalStickRoll = 0; |
externalStickYaw = 0; |
} |
*/ |
/* |
Does not belong here. |
if(RC_Quality) RC_Quality--; |
*/ |
/* Does not belong here. Well since we are not supporting navi right now anyway, leave out. |
I2CTimeout = 5000; |
while (1) { |
if (runFlightControl && analogDataReady) { // control interval |
runFlightControl = 0; // reset Flag, is enabled every 2 ms by ISR of timer0 |
J4HIGH; |
flight_control(); |
J4LOW; |
/* |
* If the motors are running (MKFlags & MKFLAG_MOTOR_RUN in flight.c), transmit |
* the throttle vector just computed. Otherwise, if motor test is engaged, transmit |
* the test throttle vector. If no testing, stop all motors. |
*/ |
// Obsoleted. |
// transmitMotorThrottleData(); |
RED_OFF; |
/* |
Does not belong here. Instead, external control should be ignored in |
controlMixer if there was no new data from there for some time. |
if(externalControlActive) externalControlActive--; |
else { |
externalControl.config = 0; |
externalStickPitch = 0; |
externalStickRoll = 0; |
externalStickYaw = 0; |
} |
*/ |
/* |
Does not belong here. |
if(RC_Quality) RC_Quality--; |
*/ |
/* Does not belong here. Well since we are not supporting navi right now anyway, leave out. |
#ifdef USE_NAVICTRL |
if(NCDataOkay) { |
if(--NCDataOkay == 0) // no data from NC |
{ // set gps control sticks neutral |
GPSStickPitch = 0; |
GPSStickRoll = 0; |
NCSerialDataOkay = 0; |
} |
} |
#endif |
*/ |
if (!--I2CTimeout || missingMotor) { // try to reset the i2c if motor is missing ot timeout |
RED_ON; |
if (!I2CTimeout) { |
I2C_Reset(); |
I2CTimeout = 5; |
} |
} else { |
RED_OFF; |
} |
// Allow Serial Data Transmit if motors must not updated or motors are not running |
if (!runFlightControl || !(MKFlags & MKFLAG_MOTOR_RUN)) { |
usart0_TransmitTxData(); |
} |
usart0_ProcessRxData(); |
if (CheckDelay(timer)) { |
if (UBat <= UBAT_AT_5V) { |
// Do nothing. The voltage on the input side of the regulator is <5V; |
// we must be running off USB power. Keep it quiet. |
} else if (UBat < staticParams.LowVoltageWarning) { |
beepBatteryAlarm(); |
} |
#ifdef USE_NAVICTRL |
if(NCDataOkay) { |
if(--NCDataOkay == 0) // no data from NC |
{ // set gps control sticks neutral |
GPSStickPitch = 0; |
GPSStickRoll = 0; |
NCSerialDataOkay = 0; |
} |
} |
SPI_StartTransmitPacket(); |
SendSPI = 4; |
#endif |
*/ |
if(!--I2CTimeout || missingMotor) { // try to reset the i2c if motor is missing ot timeout |
RED_ON; |
if(!I2CTimeout) { |
I2C_Reset(); |
I2CTimeout = 5; |
} |
} else { |
RED_OFF; |
} |
// Allow Serial Data Transmit if motors must not updated or motors are not running |
if( !runFlightControl || !(MKFlags & MKFLAG_MOTOR_RUN)) { |
usart0_TransmitTxData(); |
} |
usart0_ProcessRxData(); |
if(CheckDelay(timer)) { |
if (UBat <= UBAT_AT_5V) { |
// Do nothing. The voltage on the input side of the regulator is <5V; |
// we must be running off USB power. Keep it quiet. |
} else if(UBat < staticParams.LowVoltageWarning) { |
beepBatteryAlarm(); |
} |
timer = SetDelay(20); // every 20 ms |
} |
output_update(); |
} |
#ifdef USE_NAVICTRL |
SPI_StartTransmitPacket(); |
SendSPI = 4; |
if(!SendSPI) { |
// SendSPI is decremented in timer0.c with a rate of 9.765 kHz. |
// within the SPI_TransmitByte() routine the value is set to 4. |
// I.e. the SPI_TransmitByte() is called at a rate of 9.765 kHz/4= 2441.25 Hz, |
// and therefore the time of transmission of a complete spi-packet (32 bytes) is 32*4/9.765 kHz = 13.1 ms. |
SPI_TransmitByte(); |
} |
#endif |
timer = SetDelay(20); // every 20 ms |
} |
output_update(); |
} |
#ifdef USE_NAVICTRL |
if(!SendSPI) { |
// SendSPI is decremented in timer0.c with a rate of 9.765 kHz. |
// within the SPI_TransmitByte() routine the value is set to 4. |
// I.e. the SPI_TransmitByte() is called at a rate of 9.765 kHz/4= 2441.25 Hz, |
// and therefore the time of transmission of a complete spi-packet (32 bytes) is 32*4/9.765 kHz = 13.1 ms. |
SPI_TransmitByte(); |
} |
#endif |
} |
return (1); |
} |
return (1); |
} |
/branches/dongfang_FC_rewrite/menu.c |
---|
81,207 → 81,217 |
int8_t DisplayBuff[DISPLAYBUFFSIZE] = "Hello World"; |
uint8_t DispPtr = 0; |
/************************************/ |
/* Clear LCD Buffer */ |
/************************************/ |
void LCD_Clear(void) { |
uint8_t i; |
for( i = 0; i < DISPLAYBUFFSIZE; i++) DisplayBuff[i] = ' '; |
uint8_t i; |
for (i = 0; i < DISPLAYBUFFSIZE; i++) |
DisplayBuff[i] = ' '; |
} |
/************************************/ |
/* Update Menu on LCD */ |
/************************************/ |
// Display with 20 characters in 4 lines |
void LCD_PrintMenu(void) { |
if(RemoteKeys & KEY1) { |
if(MenuItem) MenuItem--; |
else MenuItem = MaxMenuItem; |
} |
if (RemoteKeys & KEY1) { |
if (MenuItem) |
MenuItem--; |
else |
MenuItem = MaxMenuItem; |
} |
if(RemoteKeys & KEY2) { |
if(MenuItem == MaxMenuItem) MenuItem = 0; |
else MenuItem++; |
} |
if((RemoteKeys & KEY1) && (RemoteKeys & KEY2)) MenuItem = 0; |
LCD_Clear(); |
if(MenuItem > MaxMenuItem) MenuItem = MaxMenuItem; |
// print menu item number in the upper right corner |
if(MenuItem < 10) { |
LCD_printfxy(17,0,"[%i]",MenuItem); |
} else { |
LCD_printfxy(16,0,"[%i]",MenuItem); |
} |
switch(MenuItem) { |
case 0:// Version Info Menu Item |
LCD_printfxy(0,0,"+ MikroKopter +"); |
LCD_printfxy(0,1,"HW:V%d.%d SW:%d.%d%c",BoardRelease/10,BoardRelease%10,VERSION_MAJOR, VERSION_MINOR, VERSION_PATCH+'a'); |
LCD_printfxy(0,2,"Setting: %d %s", getActiveParamSet(), Mixer.Name); |
if(I2CTimeout < 6) { |
LCD_printfxy(0,3,"I2C Error!!!"); |
} else if (missingMotor) { |
LCD_printfxy(0,3,"Missing BL-Ctrl:%d", missingMotor); |
} |
else LCD_printfxy(0,3,"(c) Holger Buss"); |
break; |
/* |
case 1:// Height Control Menu Item |
if(staticParams.GlobalConfig & CFG_HEIGHT_CONTROL) { |
LCD_printfxy(0,0,"Height: %5i",ReadingHeight); |
LCD_printfxy(0,1,"Set Point: %5i",SetPointHeight); |
LCD_printfxy(0,2,"Air Press.:%5i",0); |
LCD_printfxy(0,3,"Offset :%5i",0); |
} |
else |
{ |
LCD_printfxy(0,1,"No "); |
LCD_printfxy(0,2,"Height Control"); |
} |
break; |
*/ |
case 2:// Attitude Menu Item |
LCD_printfxy(0,0,"Attitude"); |
LCD_printfxy(0,1,"Nick: %5i", angle[PITCH] / GYRO_DEG_FACTOR_PITCHROLL); |
LCD_printfxy(0,2,"Roll: %5i", angle[ROLL ] / GYRO_DEG_FACTOR_PITCHROLL); |
LCD_printfxy(0,3,"Heading: %5i", compassHeading); |
break; |
case 3:// Remote Control Channel Menu Item |
LCD_printfxy(0,0,"C1:%4i C2:%4i ",PPM_in[1],PPM_in[2]); |
LCD_printfxy(0,1,"C3:%4i C4:%4i ",PPM_in[3],PPM_in[4]); |
LCD_printfxy(0,2,"C5:%4i C6:%4i ",PPM_in[5],PPM_in[6]); |
LCD_printfxy(0,3,"C7:%4i C8:%4i ",PPM_in[7],PPM_in[8]); |
break; |
case 4:// Remote Control Mapping Menu Item |
LCD_printfxy(0,0,"Ni:%4i Ro:%4i ",PPM_in[staticParams.ChannelAssignment[CH_PITCH]],PPM_in[staticParams.ChannelAssignment[CH_ROLL]]); |
LCD_printfxy(0,1,"Gs:%4i Ya:%4i ",PPM_in[staticParams.ChannelAssignment[CH_THROTTLE]],PPM_in[staticParams.ChannelAssignment[CH_YAW]]); |
LCD_printfxy(0,2,"P1:%4i P2:%4i ",PPM_in[staticParams.ChannelAssignment[CH_POTS]],PPM_in[staticParams.ChannelAssignment[CH_POTS+1]]); |
LCD_printfxy(0,3,"P3:%4i P4:%4i ",PPM_in[staticParams.ChannelAssignment[CH_POTS+2]],PPM_in[staticParams.ChannelAssignment[CH_POTS+3]]); |
break; |
/* |
case 5:// Gyro Sensor Menu Item |
LCD_printfxy(0,0,"Gyro - Sensor"); |
switch(BoardRelease) { |
case 10: |
LCD_printfxy(0,1,"Nick %4i (%3i.%i)", AdValueGyroNick - HiResNickOffset / HIRES_GYRO_AMPLIFY, HiResNickOffset / HIRES_GYRO_AMPLIFY, HiResNickOffset % HIRES_GYRO_AMPLIFY); |
LCD_printfxy(0,2,"Roll %4i (%3i.%i)", AdValueGyroRoll - HiResRollOffset / HIRES_GYRO_AMPLIFY, HiResRollOffset / HIRES_GYRO_AMPLIFY, HiResRollOffset % HIRES_GYRO_AMPLIFY); |
LCD_printfxy(0,3,"Yaw %4i (%3i)", AdValueGyroYaw , YawOffset); |
break; |
case 11: |
case 12: |
case 20: // divice Offests by 2 becuse 2 samples are added in adc isr |
LCD_printfxy(0,1,"Nick %4i (%3i.%i)",0, HiResNickOffset / (HIRES_GYRO_AMPLIFY * 2), (HiResNickOffset % (HIRES_GYRO_AMPLIFY * 2)) / 2); // division by 2 to push the reminder below 10 (15/2 = 7) |
LCD_printfxy(0,2,"Roll %4i (%3i.%i)",0, HiResRollOffset / (HIRES_GYRO_AMPLIFY * 2), (HiResRollOffset % (HIRES_GYRO_AMPLIFY * 2)) / 2); // division by 2 to push the reminder below 10 (15/2 = 7) |
LCD_printfxy(0,3,"Yaw %4i (%3i)",YawOffset - AdValueGyroYaw , YawOffset/2); |
break; |
case 13: |
default: // divice Offests by 2 becuse 2 samples are added in adc isr |
LCD_printfxy(0,1,"Nick %4i (%3i.%i)(%3i)",0, HiResNickOffset / (HIRES_GYRO_AMPLIFY * 2), (HiResNickOffset % (HIRES_GYRO_AMPLIFY * 2))/2, 0); // division by 2 to push the reminder below 10 (15/2 = 7) |
LCD_printfxy(0,2,"Roll %4i (%3i.%i)(%3i)",0, HiResRollOffset / (HIRES_GYRO_AMPLIFY * 2), (HiResRollOffset % (HIRES_GYRO_AMPLIFY * 2))/2, 0); // division by 2 to push the reminder below 10 (15/2 = 7) |
LCD_printfxy(0,3,"Yaw %4i (%3i)(%3i)",YawOffset - AdValueGyroYaw , YawOffset/2, 0); |
break; |
} |
break; |
case 6:// Acceleration Sensor Menu Item |
LCD_printfxy(0,0,"ACC - Sensor"); |
LCD_printfxy(0,1,"Nick %4i (%3i)",0,0); // factor 2 because of adding 2 samples in ADC ISR |
LCD_printfxy(0,2,"Roll %4i (%3i)",0,0); // factor 2 because of adding 2 samples in ADC ISR |
LCD_printfxy(0,3,"Height %4i (%3i)",0,0); |
break; |
*/ |
case 7:// Battery Voltage / Remote Control Level |
LCD_printfxy(0,1,"Voltage: %3i.%1iV",UBat/10, UBat%10); |
LCD_printfxy(0,2,"RC-Level: %5i",RC_Quality); |
break; |
case 8:// Compass Menu Item |
LCD_printfxy(0,0,"Compass "); |
LCD_printfxy(0,1,"Course: %5i", compassCourse); |
LCD_printfxy(0,2,"Heading: %5i", compassHeading); |
LCD_printfxy(0,3,"OffCourse: %5i", ((540 + compassHeading - compassCourse) % 360) - 180); |
break; |
case 9:// Poti Menu Item |
LCD_printfxy(0,0,"Po1: %3i Po5: %3i" ,variables[0], variables[4]); //PPM24-Extesion |
LCD_printfxy(0,1,"Po2: %3i Po6: %3i" ,variables[1], variables[5]); //PPM24-Extesion |
LCD_printfxy(0,2,"Po3: %3i Po7: %3i" ,variables[2], variables[6]); //PPM24-Extesion |
LCD_printfxy(0,3,"Po4: %3i Po8: %3i" ,variables[3], variables[7]); //PPM24-Extesion |
break; |
/* |
case 10:// Servo Menu Item |
LCD_printfxy(0,0,"Servo " ); |
LCD_printfxy(0,1,"Setpoint %3i",dynamicParams.ServoNickControl); |
LCD_printfxy(0,2,"Position: %3i",ServoNickValue); |
LCD_printfxy(0,3,"Range:%3i-%3i",staticParams.ServoNickMin, staticParams.ServoNickMax); |
break; |
*/ |
case 11://Extern Control |
LCD_printfxy(0,0,"ExternControl " ); |
LCD_printfxy(0,1,"Ni:%4i Ro:%4i ", externalControl.pitch, externalControl.roll); |
LCD_printfxy(0,2,"Gs:%4i Ya:%4i ", externalControl.throttle, externalControl.yaw); |
LCD_printfxy(0,3,"Hi:%4i Cf:%4i ", externalControl.height, externalControl.config); |
break; |
case 12://BL Communication errors |
LCD_printfxy(0,0,"BL-Ctrl Errors " ); |
LCD_printfxy(0,1," %3d %3d %3d %3d ",motor[0].Error,motor[1].Error,motor[2].Error,motor[3].Error); |
LCD_printfxy(0,2," %3d %3d %3d %3d ",motor[4].Error,motor[5].Error,motor[6].Error,motor[7].Error); |
LCD_printfxy(0,3," %3d %3d %3d %3d ",motor[8].Error,motor[9].Error,motor[10].Error,motor[11].Error); |
break; |
case 13://BL Overview |
LCD_printfxy(0,0,"BL-Ctrl found " ); |
LCD_printfxy(0,1," %c %c %c %c ",motor[0].Present + '-',motor[1].Present + '-',motor[2].Present + '-',motor[3].Present + '-'); |
LCD_printfxy(0,2," %c %c %c %c ",motor[4].Present + '-',motor[5].Present + '-',motor[6].Present + '-',motor[7].Present + '-'); |
LCD_printfxy(0,3," %c - - - ",motor[8].Present + '-'); |
if(motor[9].Present) LCD_printfxy(4,3,"10"); |
if(motor[10].Present) LCD_printfxy(8,3,"11"); |
if(motor[11].Present) LCD_printfxy(12,3,"12"); |
break; |
if (RemoteKeys & KEY2) { |
if (MenuItem == MaxMenuItem) |
MenuItem = 0; |
else |
MenuItem++; |
} |
if ((RemoteKeys & KEY1) && (RemoteKeys & KEY2)) |
MenuItem = 0; |
LCD_Clear(); |
if (MenuItem > MaxMenuItem) |
MenuItem = MaxMenuItem; |
// print menu item number in the upper right corner |
if (MenuItem < 10) { |
LCD_printfxy(17,0,"[%i]",MenuItem); |
} else { |
LCD_printfxy(16,0,"[%i]",MenuItem); |
} |
switch (MenuItem) { |
case 0:// Version Info Menu Item |
LCD_printfxy(0,0,"+ MikroKopter +") |
; |
LCD_printfxy(0,1,"HW:V%d.%d SW:%d.%d%c",BoardRelease/10,BoardRelease%10,VERSION_MAJOR, VERSION_MINOR, VERSION_PATCH+'a') |
; |
LCD_printfxy(0,2,"Setting: %d %s", getActiveParamSet(), Mixer.Name) |
; |
if (I2CTimeout < 6) { |
LCD_printfxy(0,3,"I2C Error!!!"); |
} else if (missingMotor) { |
LCD_printfxy(0,3,"Missing BL-Ctrl:%d", missingMotor); |
} else LCD_printfxy(0,3,"(c) Holger Buss"); |
break; |
/* |
case 1:// Height Control Menu Item |
if(staticParams.GlobalConfig & CFG_HEIGHT_CONTROL) { |
LCD_printfxy(0,0,"Height: %5i",ReadingHeight); |
LCD_printfxy(0,1,"Set Point: %5i",SetPointHeight); |
LCD_printfxy(0,2,"Air Press.:%5i",0); |
LCD_printfxy(0,3,"Offset :%5i",0); |
} |
else |
{ |
LCD_printfxy(0,1,"No "); |
LCD_printfxy(0,2,"Height Control"); |
} |
break; |
*/ |
case 2:// Attitude Menu Item |
LCD_printfxy(0,0,"Attitude"); |
LCD_printfxy(0,1,"Nick: %5i", angle[PITCH] / GYRO_DEG_FACTOR_PITCHROLL); |
LCD_printfxy(0,2,"Roll: %5i", angle[ROLL ] / GYRO_DEG_FACTOR_PITCHROLL); |
LCD_printfxy(0,3,"Heading: %5i", compassHeading); |
break; |
case 3:// Remote Control Channel Menu Item |
LCD_printfxy(0,0,"C1:%4i C2:%4i ",PPM_in[1],PPM_in[2]); |
LCD_printfxy(0,1,"C3:%4i C4:%4i ",PPM_in[3],PPM_in[4]); |
LCD_printfxy(0,2,"C5:%4i C6:%4i ",PPM_in[5],PPM_in[6]); |
LCD_printfxy(0,3,"C7:%4i C8:%4i ",PPM_in[7],PPM_in[8]); |
break; |
case 4:// Remote Control Mapping Menu Item |
LCD_printfxy(0,0,"Ni:%4i Ro:%4i ",PPM_in[staticParams.ChannelAssignment[CH_PITCH]],PPM_in[staticParams.ChannelAssignment[CH_ROLL]]); |
LCD_printfxy(0,1,"Gs:%4i Ya:%4i ",PPM_in[staticParams.ChannelAssignment[CH_THROTTLE]],PPM_in[staticParams.ChannelAssignment[CH_YAW]]); |
LCD_printfxy(0,2,"P1:%4i P2:%4i ",PPM_in[staticParams.ChannelAssignment[CH_POTS]],PPM_in[staticParams.ChannelAssignment[CH_POTS+1]]); |
LCD_printfxy(0,3,"P3:%4i P4:%4i ",PPM_in[staticParams.ChannelAssignment[CH_POTS+2]],PPM_in[staticParams.ChannelAssignment[CH_POTS+3]]); |
break; |
/* |
case 5:// Gyro Sensor Menu Item |
LCD_printfxy(0,0,"Gyro - Sensor"); |
switch(BoardRelease) { |
case 10: |
LCD_printfxy(0,1,"Nick %4i (%3i.%i)", AdValueGyroNick - HiResNickOffset / HIRES_GYRO_AMPLIFY, HiResNickOffset / HIRES_GYRO_AMPLIFY, HiResNickOffset % HIRES_GYRO_AMPLIFY); |
LCD_printfxy(0,2,"Roll %4i (%3i.%i)", AdValueGyroRoll - HiResRollOffset / HIRES_GYRO_AMPLIFY, HiResRollOffset / HIRES_GYRO_AMPLIFY, HiResRollOffset % HIRES_GYRO_AMPLIFY); |
LCD_printfxy(0,3,"Yaw %4i (%3i)", AdValueGyroYaw , YawOffset); |
break; |
case 11: |
case 12: |
case 20: // divice Offests by 2 becuse 2 samples are added in adc isr |
LCD_printfxy(0,1,"Nick %4i (%3i.%i)",0, HiResNickOffset / (HIRES_GYRO_AMPLIFY * 2), (HiResNickOffset % (HIRES_GYRO_AMPLIFY * 2)) / 2); // division by 2 to push the reminder below 10 (15/2 = 7) |
LCD_printfxy(0,2,"Roll %4i (%3i.%i)",0, HiResRollOffset / (HIRES_GYRO_AMPLIFY * 2), (HiResRollOffset % (HIRES_GYRO_AMPLIFY * 2)) / 2); // division by 2 to push the reminder below 10 (15/2 = 7) |
LCD_printfxy(0,3,"Yaw %4i (%3i)",YawOffset - AdValueGyroYaw , YawOffset/2); |
break; |
case 13: |
default: // divice Offests by 2 becuse 2 samples are added in adc isr |
LCD_printfxy(0,1,"Nick %4i (%3i.%i)(%3i)",0, HiResNickOffset / (HIRES_GYRO_AMPLIFY * 2), (HiResNickOffset % (HIRES_GYRO_AMPLIFY * 2))/2, 0); // division by 2 to push the reminder below 10 (15/2 = 7) |
LCD_printfxy(0,2,"Roll %4i (%3i.%i)(%3i)",0, HiResRollOffset / (HIRES_GYRO_AMPLIFY * 2), (HiResRollOffset % (HIRES_GYRO_AMPLIFY * 2))/2, 0); // division by 2 to push the reminder below 10 (15/2 = 7) |
LCD_printfxy(0,3,"Yaw %4i (%3i)(%3i)",YawOffset - AdValueGyroYaw , YawOffset/2, 0); |
break; |
} |
break; |
case 6:// Acceleration Sensor Menu Item |
LCD_printfxy(0,0,"ACC - Sensor"); |
LCD_printfxy(0,1,"Nick %4i (%3i)",0,0); // factor 2 because of adding 2 samples in ADC ISR |
LCD_printfxy(0,2,"Roll %4i (%3i)",0,0); // factor 2 because of adding 2 samples in ADC ISR |
LCD_printfxy(0,3,"Height %4i (%3i)",0,0); |
break; |
*/ |
case 7:// Battery Voltage / Remote Control Level |
LCD_printfxy(0,1,"Voltage: %3i.%1iV",UBat/10, UBat%10); |
LCD_printfxy(0,2,"RC-Level: %5i",RC_Quality); |
break; |
case 8:// Compass Menu Item |
LCD_printfxy(0,0,"Compass "); |
LCD_printfxy(0,1,"Course: %5i", compassCourse); |
LCD_printfxy(0,2,"Heading: %5i", compassHeading); |
LCD_printfxy(0,3,"OffCourse: %5i", ((540 + compassHeading - compassCourse) % 360) - 180); |
break; |
case 9:// Poti Menu Item |
LCD_printfxy(0,0,"Po1: %3i Po5: %3i" ,variables[0], variables[4]); //PPM24-Extesion |
LCD_printfxy(0,1,"Po2: %3i Po6: %3i" ,variables[1], variables[5]); //PPM24-Extesion |
LCD_printfxy(0,2,"Po3: %3i Po7: %3i" ,variables[2], variables[6]); //PPM24-Extesion |
LCD_printfxy(0,3,"Po4: %3i Po8: %3i" ,variables[3], variables[7]); //PPM24-Extesion |
break; |
/* |
case 10:// Servo Menu Item |
LCD_printfxy(0,0,"Servo " ); |
LCD_printfxy(0,1,"Setpoint %3i",dynamicParams.ServoNickControl); |
LCD_printfxy(0,2,"Position: %3i",ServoNickValue); |
LCD_printfxy(0,3,"Range:%3i-%3i",staticParams.ServoNickMin, staticParams.ServoNickMax); |
break; |
*/ |
case 11://Extern Control |
LCD_printfxy(0,0,"ExternControl " ); |
LCD_printfxy(0,1,"Ni:%4i Ro:%4i ", externalControl.pitch, externalControl.roll); |
LCD_printfxy(0,2,"Gs:%4i Ya:%4i ", externalControl.throttle, externalControl.yaw); |
LCD_printfxy(0,3,"Hi:%4i Cf:%4i ", externalControl.height, externalControl.config); |
break; |
case 12://BL Communication errors |
LCD_printfxy(0,0,"BL-Ctrl Errors " ); |
LCD_printfxy(0,1," %3d %3d %3d %3d ",motor[0].Error,motor[1].Error,motor[2].Error,motor[3].Error); |
LCD_printfxy(0,2," %3d %3d %3d %3d ",motor[4].Error,motor[5].Error,motor[6].Error,motor[7].Error); |
LCD_printfxy(0,3," %3d %3d %3d %3d ",motor[8].Error,motor[9].Error,motor[10].Error,motor[11].Error); |
break; |
case 13://BL Overview |
LCD_printfxy(0,0,"BL-Ctrl found " ); |
LCD_printfxy(0,1," %c %c %c %c ",motor[0].Present + '-',motor[1].Present + '-',motor[2].Present + '-',motor[3].Present + '-'); |
LCD_printfxy(0,2," %c %c %c %c ",motor[4].Present + '-',motor[5].Present + '-',motor[6].Present + '-',motor[7].Present + '-'); |
LCD_printfxy(0,3," %c - - - ",motor[8].Present + '-'); |
if (motor[9].Present) |
LCD_printfxy(4,3,"10"); |
if (motor[10].Present) |
LCD_printfxy(8,3,"11"); |
if (motor[11].Present) |
LCD_printfxy(12,3,"12"); |
break; |
#if (defined (USE_NAVICTRL)) |
case 14://GPS Lat/Lon coords |
if (GPSInfo.status == INVALID) { |
LCD_printfxy(0,0,"No GPS data!"); |
} else { |
switch (GPSInfo.satfix) |
{ |
case SATFIX_NONE: |
LCD_printfxy(0,0,"Sats: %d Fix: No", GPSInfo.satnum); |
break; |
case SATFIX_2D: |
LCD_printfxy(0,0,"Sats: %d Fix: 2D", GPSInfo.satnum); |
break; |
case SATFIX_3D: |
LCD_printfxy(0,0,"Sats: %d Fix: 3D", GPSInfo.satnum); |
break; |
case 14://GPS Lat/Lon coords |
if (GPSInfo.status == INVALID) { |
LCD_printfxy(0,0,"No GPS data!"); |
} else { |
switch (GPSInfo.satfix) |
{ |
case SATFIX_NONE: |
LCD_printfxy(0,0,"Sats: %d Fix: No", GPSInfo.satnum); |
break; |
case SATFIX_2D: |
LCD_printfxy(0,0,"Sats: %d Fix: 2D", GPSInfo.satnum); |
break; |
case SATFIX_3D: |
LCD_printfxy(0,0,"Sats: %d Fix: 3D", GPSInfo.satnum); |
break; |
default: |
LCD_printfxy(0,0,"Sats: %d Fix: ??", GPSInfo.satnum); |
break; |
} |
int16_t i1,i2,i3; |
i1 = (int16_t)(GPSInfo.longitude/10000000L); |
i2 = abs((int16_t)((GPSInfo.longitude%10000000L)/10000L)); |
i3 = abs((int16_t)(((GPSInfo.longitude%10000000L)%10000L)/10L)); |
LCD_printfxy(0,1,"Lon: %d.%03d%03d deg",i1, i2, i3); |
i1 = (int16_t)(GPSInfo.latitude/10000000L); |
i2 = abs((int16_t)((GPSInfo.latitude%10000000L)/10000L)); |
i3 = abs((int16_t)(((GPSInfo.latitude%10000000L)%10000L)/10L)); |
LCD_printfxy(0,2,"Lat: %d.%03d%03d deg",i1, i2, i3); |
i1 = (int16_t)(GPSInfo.altitude/1000L); |
i2 = abs((int16_t)(GPSInfo.altitude%1000L)); |
LCD_printfxy(0,3,"Alt: %d.%03d m",i1, i2); |
} |
break; |
#endif |
default: |
LCD_printfxy(0,0,"Sats: %d Fix: ??", GPSInfo.satnum); |
break; |
MaxMenuItem = MenuItem - 1; |
MenuItem = 0; |
break; |
} |
int16_t i1,i2,i3; |
i1 = (int16_t)(GPSInfo.longitude/10000000L); |
i2 = abs((int16_t)((GPSInfo.longitude%10000000L)/10000L)); |
i3 = abs((int16_t)(((GPSInfo.longitude%10000000L)%10000L)/10L)); |
LCD_printfxy(0,1,"Lon: %d.%03d%03d deg",i1, i2, i3); |
i1 = (int16_t)(GPSInfo.latitude/10000000L); |
i2 = abs((int16_t)((GPSInfo.latitude%10000000L)/10000L)); |
i3 = abs((int16_t)(((GPSInfo.latitude%10000000L)%10000L)/10L)); |
LCD_printfxy(0,2,"Lat: %d.%03d%03d deg",i1, i2, i3); |
i1 = (int16_t)(GPSInfo.altitude/1000L); |
i2 = abs((int16_t)(GPSInfo.altitude%1000L)); |
LCD_printfxy(0,3,"Alt: %d.%03d m",i1, i2); |
} |
break; |
#endif |
default: |
MaxMenuItem = MenuItem - 1; |
MenuItem = 0; |
break; |
} |
RemoteKeys = 0; |
RemoteKeys = 0; |
} |
/branches/dongfang_FC_rewrite/mk3mag.c |
---|
137,4 → 137,3 |
} |
} |
/branches/dongfang_FC_rewrite/mk3mag.h |
---|
2,10 → 2,10 |
#define _MK3MAG_H |
typedef struct { |
int16_t Attitude[2]; |
uint8_t UserParam[2]; |
uint8_t CalState; |
uint8_t Orientation; |
int16_t Attitude[2]; |
uint8_t UserParam[2]; |
uint8_t CalState; |
uint8_t Orientation; |
} ToMk3Mag_t; |
extern ToMk3Mag_t ToMk3Mag; |
17,4 → 17,3 |
void MK3MAG_Update(void); |
#endif //_MK3MAG_H |
/branches/dongfang_FC_rewrite/output.c |
---|
57,35 → 57,42 |
uint8_t flashCnt[2], flashMask[2]; |
// initializes the LED control outputs J16, J17 |
void output_init(void) { |
// set PC2 & PC3 as output (control of J16 & J17) |
DDRC |= (1<<DDC2)|(1<<DDC3); |
OUTPUT_SET(0,0); OUTPUT_SET(1,0); |
flashCnt[0] = flashCnt[1] = 0; |
flashMask[0] = flashMask[1] = 128; |
// set PC2 & PC3 as output (control of J16 & J17) |
DDRC |= (1 << DDC2) | (1 << DDC3); |
OUTPUT_SET(0,0); |
OUTPUT_SET(1,0); |
flashCnt[0] = flashCnt[1] = 0; |
flashMask[0] = flashMask[1] = 128; |
} |
void flashingLight(uint8_t port, uint8_t timing, uint8_t bitmask, uint8_t manual) { |
if (timing > 250 && manual > 230) { |
// "timing" is set to "manual" and the value is very high --> Set to the value in bitmask bit 7. |
OUTPUT_SET(port, bitmask & 128); |
} else if (timing > 250 && manual < 10) { |
// "timing" is set to "manual" and the value is very low --> Set to the negated value in bitmask bit 7. |
OUTPUT_SET(port, !(bitmask & 128)); |
} else if(!flashCnt[port]--) { |
// rotating mask over bitmask... |
flashCnt[port] = timing - 1; |
if(flashMask[port] == 1) flashMask[port] = 128; else flashMask[port] >>= 1; |
OUTPUT_SET(port, flashMask[port] & bitmask); |
} |
void flashingLight(uint8_t port, uint8_t timing, uint8_t bitmask, |
uint8_t manual) { |
if (timing > 250 && manual > 230) { |
// "timing" is set to "manual" and the value is very high --> Set to the value in bitmask bit 7. |
OUTPUT_SET(port, bitmask & 128); |
} else if (timing > 250 && manual < 10) { |
// "timing" is set to "manual" and the value is very low --> Set to the negated value in bitmask bit 7. |
OUTPUT_SET(port, !(bitmask & 128)); |
} else if (!flashCnt[port]--) { |
// rotating mask over bitmask... |
flashCnt[port] = timing - 1; |
if (flashMask[port] == 1) |
flashMask[port] = 128; |
else |
flashMask[port] >>= 1; |
OUTPUT_SET(port, flashMask[port] & bitmask); |
} |
} |
void flashingLights(void) { |
static int8_t delay = 0; |
if(!delay--) { // 10 ms intervals |
delay = 4; |
flashingLight(0, staticParams.J16Timing, staticParams.J16Bitmask, dynamicParams.J16Timing); |
flashingLight(1, staticParams.J17Timing, staticParams.J17Bitmask, dynamicParams.J17Timing); |
} |
static int8_t delay = 0; |
if (!delay--) { // 10 ms intervals |
delay = 4; |
flashingLight(0, staticParams.J16Timing, staticParams.J16Bitmask, |
dynamicParams.J16Timing); |
flashingLight(1, staticParams.J17Timing, staticParams.J17Bitmask, |
dynamicParams.J17Timing); |
} |
} |
/* |
95,11 → 102,11 |
#define DIGITAL_DEBUG_MASK DEBUG_MK3MAG |
void output_update(void) { |
uint8_t output0, output1; |
if (!DIGITAL_DEBUG_MASK) |
flashingLights(); |
else { |
OUTPUT_SET(0, DebugOut.Digital[0] & DIGITAL_DEBUG_MASK); |
OUTPUT_SET(1, DebugOut.Digital[1] & DIGITAL_DEBUG_MASK); |
} |
uint8_t output0, output1; |
if (!DIGITAL_DEBUG_MASK) |
flashingLights(); |
else { |
OUTPUT_SET(0, DebugOut.Digital[0] & DIGITAL_DEBUG_MASK); |
OUTPUT_SET(1, DebugOut.Digital[1] & DIGITAL_DEBUG_MASK); |
} |
} |
/branches/dongfang_FC_rewrite/rc.c |
---|
64,7 → 64,7 |
volatile uint8_t NewPpmData = 1; |
volatile int16_t RC_Quality = 0; |
int16_t RC_PRTY[4]; |
uint8_t lastRCCommand = COMMAND_NONE; |
uint8_t lastRCCommand = COMMAND_NONE; |
uint8_t commandTimer = 0; |
// Useless. Just trim on the R/C instead. |
73,54 → 73,55 |
/*************************************************************** |
* 16bit timer 1 is used to decode the PPM-Signal |
***************************************************************/ |
void RC_Init (void) { |
uint8_t sreg = SREG; |
void RC_Init(void) { |
uint8_t sreg = SREG; |
// disable all interrupts before reconfiguration |
cli(); |
// disable all interrupts before reconfiguration |
cli(); |
// PPM-signal is connected to the Input Capture Pin (PD6) of timer 1 |
DDRD &= ~(1<<DDD6); |
PORTD |= (1<<PORTD6); |
// PPM-signal is connected to the Input Capture Pin (PD6) of timer 1 |
DDRD &= ~(1 << DDD6); |
PORTD |= (1 << PORTD6); |
// Channel 5,6,7 is decoded to servo signals at pin PD5 (J3), PD4(J4), PD3(J5) |
// set as output |
DDRD |= (1<<DDD5)| (1<<DDD4) | (1<<DDD3); |
// low level |
PORTD &= ~((1<<PORTD5) | (1<<PORTD4) | (1<<PORTD3)); |
// Channel 5,6,7 is decoded to servo signals at pin PD5 (J3), PD4(J4), PD3(J5) |
// set as output |
DDRD |= (1 << DDD5) | (1 << DDD4) | (1 << DDD3); |
// low level |
PORTD &= ~((1 << PORTD5) | (1 << PORTD4) | (1 << PORTD3)); |
// PD3 can't be used if 2nd UART is activated |
// because TXD1 is at that port |
if(CPUType != ATMEGA644P) { |
DDRD |= (1<<PORTD3); |
PORTD &= ~(1<<PORTD3); |
} |
// PD3 can't be used if 2nd UART is activated |
// because TXD1 is at that port |
if (CPUType != ATMEGA644P) { |
DDRD |= (1 << PORTD3); |
PORTD &= ~(1 << PORTD3); |
} |
// Timer/Counter1 Control Register A, B, C |
// Timer/Counter1 Control Register A, B, C |
// Normal Mode (bits: WGM13=0, WGM12=0, WGM11=0, WGM10=0) |
// Compare output pin A & B is disabled (bits: COM1A1=0, COM1A0=0, COM1B1=0, COM1B0=0) |
// Set clock source to SYSCLK/64 (bit: CS12=0, CS11=1, CS10=1) |
// Enable input capture noise cancler (bit: ICNC1=1) |
// Trigger on positive edge of the input capture pin (bit: ICES1=1), |
// Therefore the counter incremets at a clock of 20 MHz/64 = 312.5 kHz or 3.2µs |
// The longest period is 0xFFFF / 312.5 kHz = 0.209712 s. |
TCCR1A &= ~((1<<COM1A1)|(1<<COM1A0)|(1<<COM1B1)|(1<<COM1B0)|(1<<WGM11)|(1<<WGM10)); |
TCCR1B &= ~((1<<WGM13)|(1<<WGM12)|(1<<CS12)); |
TCCR1B |= (1<<CS11)|(1<<CS10)|(1<<ICES1)|(1<<ICNC1); |
TCCR1C &= ~((1<<FOC1A)|(1<<FOC1B)); |
// Normal Mode (bits: WGM13=0, WGM12=0, WGM11=0, WGM10=0) |
// Compare output pin A & B is disabled (bits: COM1A1=0, COM1A0=0, COM1B1=0, COM1B0=0) |
// Set clock source to SYSCLK/64 (bit: CS12=0, CS11=1, CS10=1) |
// Enable input capture noise cancler (bit: ICNC1=1) |
// Trigger on positive edge of the input capture pin (bit: ICES1=1), |
// Therefore the counter incremets at a clock of 20 MHz/64 = 312.5 kHz or 3.2µs |
// The longest period is 0xFFFF / 312.5 kHz = 0.209712 s. |
TCCR1A &= ~((1 << COM1A1) | (1 << COM1A0) | (1 << COM1B1) | (1 << COM1B0) |
| (1 << WGM11) | (1 << WGM10)); |
TCCR1B &= ~((1 << WGM13) | (1 << WGM12) | (1 << CS12)); |
TCCR1B |= (1 << CS11) | (1 << CS10) | (1 << ICES1) | (1 << ICNC1); |
TCCR1C &= ~((1 << FOC1A) | (1 << FOC1B)); |
// Timer/Counter1 Interrupt Mask Register |
// Timer/Counter1 Interrupt Mask Register |
// Enable Input Capture Interrupt (bit: ICIE1=1) |
// Disable Output Compare A & B Match Interrupts (bit: OCIE1B=0, OICIE1A=0) |
// Enable Overflow Interrupt (bit: TOIE1=0) |
TIMSK1 &= ~((1<<OCIE1B)|(1<<OCIE1A)|(1<<TOIE1)); |
TIMSK1 |= (1<<ICIE1); |
// Enable Input Capture Interrupt (bit: ICIE1=1) |
// Disable Output Compare A & B Match Interrupts (bit: OCIE1B=0, OICIE1A=0) |
// Enable Overflow Interrupt (bit: TOIE1=0) |
TIMSK1 &= ~((1 << OCIE1B) | (1 << OCIE1A) | (1 << TOIE1)); |
TIMSK1 |= (1 << ICIE1); |
RC_Quality = 0; |
RC_Quality = 0; |
SREG = sreg; |
SREG = sreg; |
} |
/********************************************************************/ |
127,87 → 128,90 |
/* Every time a positive edge is detected at PD6 */ |
/********************************************************************/ |
/* t-Frame |
<-----------------------------------------------------------------------> |
____ ______ _____ ________ ______ sync gap ____ |
| | | | | | | | | | | |
| | | | | | | | | | | |
___| |_| |_| |_| |_.............| |________________| |
<-----><-------><------><--------> <------> <--- |
t0 t1 t2 t4 tn t0 |
<-----------------------------------------------------------------------> |
____ ______ _____ ________ ______ sync gap ____ |
| | | | | | | | | | | |
| | | | | | | | | | | |
___| |_| |_| |_| |_.............| |________________| |
<-----><-------><------><--------> <------> <--- |
t0 t1 t2 t4 tn t0 |
The PPM-Frame length is 22.5 ms. |
Channel high pulse width range is 0.7 ms to 1.7 ms completed by an 0.3 ms low pulse. |
The mininimum time delay of two events coding a channel is ( 0.7 + 0.3) ms = 1 ms. |
The maximum time delay of two events coding a chanel is ( 1.7 + 0.3) ms = 2 ms. |
The minimum duration of all channels at minimum value is 8 * 1 ms = 8 ms. |
The maximum duration of all channels at maximum value is 8 * 2 ms = 16 ms. |
The remaining time of (22.5 - 8 ms) ms = 14.5 ms to (22.5 - 16 ms) ms = 6.5 ms is |
the syncronization gap. |
*/ |
ISR(TIMER1_CAPT_vect) { // typical rate of 1 ms to 2 ms |
int16_t signal = 0, tmp; |
static int16_t index; |
static uint16_t oldICR1 = 0; |
// 16bit Input Capture Register ICR1 contains the timer value TCNT1 |
// at the time the edge was detected |
// calculate the time delay to the previous event time which is stored in oldICR1 |
// calculatiing the difference of the two uint16_t and converting the result to an int16_t |
// implicit handles a timer overflow 65535 -> 0 the right way. |
signal = (uint16_t) ICR1 - oldICR1; |
oldICR1 = ICR1; |
//sync gap? (3.52 ms < signal < 25.6 ms) |
if((signal > 1100) && (signal < 8000)) { |
// if a sync gap happens and there where at least 4 channels decoded before |
// then the NewPpmData flag is reset indicating valid data in the PPM_in[] array. |
if(index >= 4) { |
NewPpmData = 0; // Null means NewData for the first 4 channels |
} |
// synchronize channel index |
index = 1; |
} else { // within the PPM frame |
if(index < MAX_CHANNELS-1) { // PPM24 supports 12 channels |
// check for valid signal length (0.8 ms < signal < 2.1984 ms) |
// signal range is from 1.0ms/3.2us = 312 to 2.0ms/3.2us = 625 |
if((signal > 250) && (signal < 687)) { |
// shift signal to zero symmetric range -154 to 159 |
signal -= 470; // offset of 1.4912 ms ??? (469 * 3.2µs = 1.5008 ms) |
// check for stable signal |
if(abs(signal - PPM_in[index]) < 6) { |
if(RC_Quality < 200) RC_Quality +=10; |
else RC_Quality = 200; |
The PPM-Frame length is 22.5 ms. |
Channel high pulse width range is 0.7 ms to 1.7 ms completed by an 0.3 ms low pulse. |
The mininimum time delay of two events coding a channel is ( 0.7 + 0.3) ms = 1 ms. |
The maximum time delay of two events coding a chanel is ( 1.7 + 0.3) ms = 2 ms. |
The minimum duration of all channels at minimum value is 8 * 1 ms = 8 ms. |
The maximum duration of all channels at maximum value is 8 * 2 ms = 16 ms. |
The remaining time of (22.5 - 8 ms) ms = 14.5 ms to (22.5 - 16 ms) ms = 6.5 ms is |
the syncronization gap. |
*/ |
ISR(TIMER1_CAPT_vect) |
{ // typical rate of 1 ms to 2 ms |
int16_t signal = 0, tmp; |
static int16_t index; |
static uint16_t oldICR1 = 0; |
// 16bit Input Capture Register ICR1 contains the timer value TCNT1 |
// at the time the edge was detected |
// calculate the time delay to the previous event time which is stored in oldICR1 |
// calculatiing the difference of the two uint16_t and converting the result to an int16_t |
// implicit handles a timer overflow 65535 -> 0 the right way. |
signal = (uint16_t) ICR1 - oldICR1; |
oldICR1 = ICR1; |
//sync gap? (3.52 ms < signal < 25.6 ms) |
if ((signal > 1100) && (signal < 8000)) { |
// if a sync gap happens and there where at least 4 channels decoded before |
// then the NewPpmData flag is reset indicating valid data in the PPM_in[] array. |
if (index >= 4) { |
NewPpmData = 0; // Null means NewData for the first 4 channels |
} |
// synchronize channel index |
index = 1; |
} else { // within the PPM frame |
if (index < MAX_CHANNELS - 1) { // PPM24 supports 12 channels |
// check for valid signal length (0.8 ms < signal < 2.1984 ms) |
// signal range is from 1.0ms/3.2us = 312 to 2.0ms/3.2us = 625 |
if ((signal > 250) && (signal < 687)) { |
// shift signal to zero symmetric range -154 to 159 |
signal -= 470; // offset of 1.4912 ms ??? (469 * 3.2µs = 1.5008 ms) |
// check for stable signal |
if (abs(signal - PPM_in[index]) < 6) { |
if (RC_Quality < 200) |
RC_Quality += 10; |
else |
RC_Quality = 200; |
} |
// If signal is the same as before +/- 1, just keep it there. |
if (signal >= PPM_in[index] - 1 && signal <= PPM_in[index] + 1) { |
// In addition, if the signal is very close to 0, just set it to 0. |
if (signal >= -1 && signal <= 1) { |
tmp = 0; |
} else { |
tmp = PPM_in[index]; |
} |
} else |
tmp = signal; |
// calculate signal difference on good signal level |
if (RC_Quality >= 195) |
PPM_diff[index] = ((tmp - PPM_in[index]) / 3) * 3; // cut off lower 3 bit for nois reduction |
else |
PPM_diff[index] = 0; |
PPM_in[index] = tmp; // update channel value |
} |
index++; // next channel |
// demux sum signal for channels 5 to 7 to J3, J4, J5 |
// TODO: General configurability of this R/C channel forwarding. Or remove it completely - the |
// channels are usually available at the receiver anyway. |
// if(index == 5) J3HIGH; else J3LOW; |
// if(index == 6) J4HIGH; else J4LOW; |
// if(CPUType != ATMEGA644P) // not used as TXD1 |
// { |
// if(index == 7) J5HIGH; else J5LOW; |
// } |
} |
} |
// If signal is the same as before +/- 1, just keep it there. |
if (signal>=PPM_in[index]-1 && signal<=PPM_in[index]+1) { |
// In addition, if the signal is very close to 0, just set it to 0. |
if (signal >=-1 && signal <= 1) { |
tmp = 0; |
} else { |
tmp = PPM_in[index]; |
} |
} |
else |
tmp = signal; |
// calculate signal difference on good signal level |
if(RC_Quality >= 195) |
PPM_diff[index] = ((tmp - PPM_in[index]) / 3) * 3; // cut off lower 3 bit for nois reduction |
else PPM_diff[index] = 0; |
PPM_in[index] = tmp; // update channel value |
} |
index++; // next channel |
// demux sum signal for channels 5 to 7 to J3, J4, J5 |
// TODO: General configurability of this R/C channel forwarding. Or remove it completely - the |
// channels are usually available at the receiver anyway. |
// if(index == 5) J3HIGH; else J3LOW; |
// if(index == 6) J4HIGH; else J4LOW; |
// if(CPUType != ATMEGA644P) // not used as TXD1 |
// { |
// if(index == 7) J5HIGH; else J5LOW; |
// } |
} |
} |
} |
#define RCChannel(dimension) PPM_in[staticParams.ChannelAssignment[dimension]] |
218,23 → 222,23 |
// Internal. |
uint8_t RC_getStickCommand(void) { |
if(RCChannel(COMMAND_CHANNEL_VERTICAL) > COMMAND_THRESHOLD) { |
// vertical is up |
if(RCChannel(COMMAND_CHANNEL_HORIZONTAL) > COMMAND_THRESHOLD) |
return COMMAND_GYROCAL; |
if(RCChannel(COMMAND_CHANNEL_HORIZONTAL) < -COMMAND_THRESHOLD) |
return COMMAND_ACCCAL; |
return COMMAND_NONE; |
} else if(RCChannel(COMMAND_CHANNEL_VERTICAL) < -COMMAND_THRESHOLD) { |
// vertical is down |
if(RCChannel(COMMAND_CHANNEL_HORIZONTAL) > COMMAND_THRESHOLD) |
return COMMAND_STOP; |
if(RCChannel(COMMAND_CHANNEL_HORIZONTAL) < -COMMAND_THRESHOLD) |
return COMMAND_START; |
return COMMAND_NONE; |
} |
// vertical is around center |
return COMMAND_NONE; |
if (RCChannel(COMMAND_CHANNEL_VERTICAL) > COMMAND_THRESHOLD) { |
// vertical is up |
if (RCChannel(COMMAND_CHANNEL_HORIZONTAL) > COMMAND_THRESHOLD) |
return COMMAND_GYROCAL; |
if (RCChannel(COMMAND_CHANNEL_HORIZONTAL) < -COMMAND_THRESHOLD) |
return COMMAND_ACCCAL; |
return COMMAND_NONE; |
} else if (RCChannel(COMMAND_CHANNEL_VERTICAL) < -COMMAND_THRESHOLD) { |
// vertical is down |
if (RCChannel(COMMAND_CHANNEL_HORIZONTAL) > COMMAND_THRESHOLD) |
return COMMAND_STOP; |
if (RCChannel(COMMAND_CHANNEL_HORIZONTAL) < -COMMAND_THRESHOLD) |
return COMMAND_START; |
return COMMAND_NONE; |
} |
// vertical is around center |
return COMMAND_NONE; |
} |
/* |
241,32 → 245,39 |
* This must be called (as the only thing) for each control loop cycle (488 Hz). |
*/ |
void RC_update() { |
int16_t tmp1, tmp2; |
if(RC_Quality) { |
RC_Quality--; |
if (NewPpmData-- == 0) { |
RC_PRTY[CONTROL_PITCH] = RCChannel(CH_PITCH) * staticParams.StickP + RCDiff(CH_PITCH) * staticParams.StickD; |
RC_PRTY[CONTROL_ROLL] = RCChannel(CH_ROLL) * staticParams.StickP + RCDiff(CH_ROLL) * staticParams.StickD; |
RC_PRTY[CONTROL_THROTTLE] = RCChannel(CH_THROTTLE) + RCDiff(CH_THROTTLE) * dynamicParams.UserParams[3] + 120; |
if (RC_PRTY[CONTROL_THROTTLE] < 0) RC_PRTY[CONTROL_THROTTLE] = 0; // Throttle is non negative. |
tmp1 = -RCChannel(CH_YAW) - RCDiff(CH_YAW); |
// exponential stick sensitivity in yawing rate |
tmp2 = (int32_t) staticParams.StickYawP * ((int32_t)tmp1 * abs(tmp1)) / 512L; // expo y = ax + bx^2 |
tmp2 += (staticParams.StickYawP * tmp1) / 4; |
RC_PRTY[CONTROL_YAW] = tmp2; |
} |
uint8_t command = RC_getStickCommand(); |
if (lastRCCommand == command) { |
// Keep timer from overrunning. |
if (commandTimer < COMMAND_TIMER) commandTimer++; |
} else { |
// There was a change. |
lastRCCommand = command; |
commandTimer = 0; |
} |
} else { // Bad signal |
RC_PRTY[CONTROL_PITCH] = RC_PRTY[CONTROL_ROLL] = RC_PRTY[CONTROL_THROTTLE] = RC_PRTY[CONTROL_YAW] = 0; |
} |
int16_t tmp1, tmp2; |
if (RC_Quality) { |
RC_Quality--; |
if (NewPpmData-- == 0) { |
RC_PRTY[CONTROL_PITCH] = RCChannel(CH_PITCH) * staticParams.StickP |
+ RCDiff(CH_PITCH) * staticParams.StickD; |
RC_PRTY[CONTROL_ROLL] = RCChannel(CH_ROLL) * staticParams.StickP |
+ RCDiff(CH_ROLL) * staticParams.StickD; |
RC_PRTY[CONTROL_THROTTLE] = RCChannel(CH_THROTTLE) + RCDiff(CH_THROTTLE) |
* dynamicParams.UserParams[3] + 120; |
if (RC_PRTY[CONTROL_THROTTLE] < 0) |
RC_PRTY[CONTROL_THROTTLE] = 0; // Throttle is non negative. |
tmp1 = -RCChannel(CH_YAW) - RCDiff(CH_YAW); |
// exponential stick sensitivity in yawing rate |
tmp2 = (int32_t) staticParams.StickYawP * ((int32_t) tmp1 * abs(tmp1)) |
/ 512L; // expo y = ax + bx^2 |
tmp2 += (staticParams.StickYawP * tmp1) / 4; |
RC_PRTY[CONTROL_YAW] = tmp2; |
} |
uint8_t command = RC_getStickCommand(); |
if (lastRCCommand == command) { |
// Keep timer from overrunning. |
if (commandTimer < COMMAND_TIMER) |
commandTimer++; |
} else { |
// There was a change. |
lastRCCommand = command; |
commandTimer = 0; |
} |
} else { // Bad signal |
RC_PRTY[CONTROL_PITCH] = RC_PRTY[CONTROL_ROLL] = RC_PRTY[CONTROL_THROTTLE] |
= RC_PRTY[CONTROL_YAW] = 0; |
} |
} |
/* |
273,35 → 284,35 |
* Get Pitch, Roll, Throttle, Yaw values |
*/ |
int16_t* RC_getPRTY(void) { |
return RC_PRTY; |
return RC_PRTY; |
} |
/* |
* Get other channel value |
*/ |
int16_t RC_getVariable (uint8_t varNum) { |
if (varNum < 4) |
// 0th variable is 5th channel (1-based) etc. |
return RCChannel(varNum + 4) + POT_OFFSET; |
/* |
* Let's just say: |
* The RC variable 4 is hardwired to channel 5 |
* The RC variable 5 is hardwired to channel 6 |
* The RC variable 6 is hardwired to channel 7 |
* The RC variable 7 is hardwired to channel 8 |
* Alternatively, one could bind them to channel (4 + varNum) - or whatever... |
*/ |
return PPM_in[varNum + 1] + POT_OFFSET; |
int16_t RC_getVariable(uint8_t varNum) { |
if (varNum < 4) |
// 0th variable is 5th channel (1-based) etc. |
return RCChannel(varNum + 4) + POT_OFFSET; |
/* |
* Let's just say: |
* The RC variable 4 is hardwired to channel 5 |
* The RC variable 5 is hardwired to channel 6 |
* The RC variable 6 is hardwired to channel 7 |
* The RC variable 7 is hardwired to channel 8 |
* Alternatively, one could bind them to channel (4 + varNum) - or whatever... |
*/ |
return PPM_in[varNum + 1] + POT_OFFSET; |
} |
uint8_t RC_getSignalQuality(void) { |
if (RC_Quality >= 160) |
return SIGNAL_GOOD; |
if (RC_Quality >= 140) |
return SIGNAL_OK; |
if (RC_Quality >= 120) |
return SIGNAL_BAD; |
return SIGNAL_LOST; |
if (RC_Quality >= 160) |
return SIGNAL_GOOD; |
if (RC_Quality >= 140) |
return SIGNAL_OK; |
if (RC_Quality >= 120) |
return SIGNAL_BAD; |
return SIGNAL_LOST; |
} |
/* |
314,27 → 325,27 |
* of a stick, it may be useful. |
*/ |
void RC_calibrate(void) { |
// Do nothing. |
// Do nothing. |
} |
/* |
if (staticParams.GlobalConfig & CFG_HEADING_HOLD) { |
// In HH, it s OK to trim the R/C. The effect should not be conteracted here. |
stickOffsetPitch = stickOffsetRoll = 0; |
} else { |
stickOffsetPitch = RCChannel(CH_PITCH) * staticParams.StickP; |
stickOffsetRoll = RCChannel(CH_ROLL) * staticParams.StickP; |
} |
} |
*/ |
if (staticParams.GlobalConfig & CFG_HEADING_HOLD) { |
// In HH, it s OK to trim the R/C. The effect should not be conteracted here. |
stickOffsetPitch = stickOffsetRoll = 0; |
} else { |
stickOffsetPitch = RCChannel(CH_PITCH) * staticParams.StickP; |
stickOffsetRoll = RCChannel(CH_ROLL) * staticParams.StickP; |
} |
} |
*/ |
uint8_t RC_getCommand(void) { |
if (commandTimer == COMMAND_TIMER) { |
// Stick has been held long enough; command committed. |
return lastRCCommand; |
} |
// Not yet sure what the command is. |
return COMMAND_NONE; |
if (commandTimer == COMMAND_TIMER) { |
// Stick has been held long enough; command committed. |
return lastRCCommand; |
} |
// Not yet sure what the command is. |
return COMMAND_NONE; |
} |
/* |
356,70 → 367,79 |
#define ARGUMENT_CHANNEL_HORIZONTAL CH_ROLL |
uint8_t RC_getArgument(void) { |
if(RCChannel(ARGUMENT_CHANNEL_VERTICAL) > ARGUMENT_THRESHOLD) { |
// vertical is up |
if(RCChannel(ARGUMENT_CHANNEL_HORIZONTAL) > ARGUMENT_THRESHOLD) |
return 2; |
if(RCChannel(ARGUMENT_CHANNEL_HORIZONTAL) < -ARGUMENT_THRESHOLD) |
return 4; |
return 3; |
} else if(RCChannel(ARGUMENT_CHANNEL_VERTICAL) < -ARGUMENT_THRESHOLD) { |
// vertical is down |
if(RCChannel(ARGUMENT_CHANNEL_HORIZONTAL) > ARGUMENT_THRESHOLD) |
return 8; |
if(RCChannel(ARGUMENT_CHANNEL_HORIZONTAL) < -ARGUMENT_THRESHOLD) |
return 6; |
return 7; |
} else { |
// vertical is around center |
if(RCChannel(ARGUMENT_CHANNEL_HORIZONTAL) > ARGUMENT_THRESHOLD) |
return 1; |
if(RCChannel(ARGUMENT_CHANNEL_HORIZONTAL) < -ARGUMENT_THRESHOLD) |
return 5; |
return 0; |
} |
if (RCChannel(ARGUMENT_CHANNEL_VERTICAL) > ARGUMENT_THRESHOLD) { |
// vertical is up |
if (RCChannel(ARGUMENT_CHANNEL_HORIZONTAL) > ARGUMENT_THRESHOLD) |
return 2; |
if (RCChannel(ARGUMENT_CHANNEL_HORIZONTAL) < -ARGUMENT_THRESHOLD) |
return 4; |
return 3; |
} else if (RCChannel(ARGUMENT_CHANNEL_VERTICAL) < -ARGUMENT_THRESHOLD) { |
// vertical is down |
if (RCChannel(ARGUMENT_CHANNEL_HORIZONTAL) > ARGUMENT_THRESHOLD) |
return 8; |
if (RCChannel(ARGUMENT_CHANNEL_HORIZONTAL) < -ARGUMENT_THRESHOLD) |
return 6; |
return 7; |
} else { |
// vertical is around center |
if (RCChannel(ARGUMENT_CHANNEL_HORIZONTAL) > ARGUMENT_THRESHOLD) |
return 1; |
if (RCChannel(ARGUMENT_CHANNEL_HORIZONTAL) < -ARGUMENT_THRESHOLD) |
return 5; |
return 0; |
} |
} |
uint8_t RC_getLooping(uint8_t looping) { |
// static uint8_t looping = 0; |
// static uint8_t looping = 0; |
if(RCChannel(CH_ROLL) > staticParams.LoopThreshold && staticParams.BitConfig & CFG_LOOP_LEFT) { |
looping |= (LOOPING_ROLL_AXIS | LOOPING_LEFT); |
} else if((looping & LOOPING_LEFT) && RCChannel(CH_ROLL) < staticParams.LoopThreshold - staticParams.LoopHysteresis) { |
looping &= (~(LOOPING_ROLL_AXIS | LOOPING_LEFT)); |
} |
if(RCChannel(CH_ROLL) < -staticParams.LoopThreshold && staticParams.BitConfig & CFG_LOOP_RIGHT) { |
looping |= (LOOPING_ROLL_AXIS | LOOPING_RIGHT); |
} else if((looping & LOOPING_RIGHT) && RCChannel(CH_ROLL) > -staticParams.LoopThreshold - staticParams.LoopHysteresis) { |
looping &= (~(LOOPING_ROLL_AXIS | LOOPING_RIGHT)); |
} |
if(RCChannel(CH_PITCH) > staticParams.LoopThreshold && staticParams.BitConfig & CFG_LOOP_UP) { |
looping |= (LOOPING_PITCH_AXIS | LOOPING_UP); |
} else if((looping & LOOPING_UP) && RCChannel(CH_PITCH) < staticParams.LoopThreshold - staticParams.LoopHysteresis) { |
looping &= (~(LOOPING_PITCH_AXIS | LOOPING_UP)); |
} |
if(RCChannel(CH_PITCH) < -staticParams.LoopThreshold && staticParams.BitConfig & CFG_LOOP_DOWN) { |
looping |= (LOOPING_PITCH_AXIS | LOOPING_DOWN); |
} else if((looping & LOOPING_DOWN) && RCChannel(CH_PITCH) > -staticParams.LoopThreshold - staticParams.LoopHysteresis) { |
looping &= (~(LOOPING_PITCH_AXIS | LOOPING_DOWN)); |
} |
if (RCChannel(CH_ROLL) > staticParams.LoopThreshold && staticParams.BitConfig |
& CFG_LOOP_LEFT) { |
looping |= (LOOPING_ROLL_AXIS | LOOPING_LEFT); |
} else if ((looping & LOOPING_LEFT) && RCChannel(CH_ROLL) |
< staticParams.LoopThreshold - staticParams.LoopHysteresis) { |
looping &= (~(LOOPING_ROLL_AXIS | LOOPING_LEFT)); |
} |
return looping; |
if (RCChannel(CH_ROLL) < -staticParams.LoopThreshold |
&& staticParams.BitConfig & CFG_LOOP_RIGHT) { |
looping |= (LOOPING_ROLL_AXIS | LOOPING_RIGHT); |
} else if ((looping & LOOPING_RIGHT) && RCChannel(CH_ROLL) |
> -staticParams.LoopThreshold - staticParams.LoopHysteresis) { |
looping &= (~(LOOPING_ROLL_AXIS | LOOPING_RIGHT)); |
} |
if (RCChannel(CH_PITCH) > staticParams.LoopThreshold |
&& staticParams.BitConfig & CFG_LOOP_UP) { |
looping |= (LOOPING_PITCH_AXIS | LOOPING_UP); |
} else if ((looping & LOOPING_UP) && RCChannel(CH_PITCH) |
< staticParams.LoopThreshold - staticParams.LoopHysteresis) { |
looping &= (~(LOOPING_PITCH_AXIS | LOOPING_UP)); |
} |
if (RCChannel(CH_PITCH) < -staticParams.LoopThreshold |
&& staticParams.BitConfig & CFG_LOOP_DOWN) { |
looping |= (LOOPING_PITCH_AXIS | LOOPING_DOWN); |
} else if ((looping & LOOPING_DOWN) && RCChannel(CH_PITCH) |
> -staticParams.LoopThreshold - staticParams.LoopHysteresis) { |
looping &= (~(LOOPING_PITCH_AXIS | LOOPING_DOWN)); |
} |
return looping; |
} |
uint8_t RC_testCompassCalState(void) { |
static uint8_t stick = 1; |
// if pitch is centered or top set stick to zero |
if(RCChannel(CH_PITCH) > -20) stick = 0; |
// if pitch is down trigger to next cal state |
if((RCChannel(CH_PITCH) < -70) && !stick) { |
stick = 1; |
return 1; |
} |
return 0; |
static uint8_t stick = 1; |
// if pitch is centered or top set stick to zero |
if (RCChannel(CH_PITCH) > -20) |
stick = 0; |
// if pitch is down trigger to next cal state |
if ((RCChannel(CH_PITCH) < -70) && !stick) { |
stick = 1; |
return 1; |
} |
return 0; |
} |
/* |
* Abstract controls are not used at the moment. |
431,4 → 451,4 |
RC_getSignalQuality, |
RC_calibrate |
}; |
*/ |
*/ |
/branches/dongfang_FC_rewrite/rc.h |
---|
20,12 → 20,12 |
// Number of cycles a command must be repeated before commit. |
#define COMMAND_TIMER 200 |
extern void RC_Init (void); |
extern void RC_Init(void); |
// the RC-Signal. todo: Not export any more. |
extern volatile int16_t PPM_in[MAX_CHANNELS]; |
// extern volatile int16_t PPM_diff[MAX_CHANNELS]; // the differentiated RC-Signal. Should that be exported?? |
extern volatile uint8_t NewPpmData; // 0 indicates a new recieved PPM Frame |
extern volatile int16_t RC_Quality; // rc signal quality indicator (0 to 200) |
extern volatile uint8_t NewPpmData; // 0 indicates a new recieved PPM Frame |
extern volatile int16_t RC_Quality; // rc signal quality indicator (0 to 200) |
// defines for lookup staticParams.ChannelAssignment |
#define CH_PITCH 0 |
36,20 → 36,20 |
#define POT_OFFSET 115 |
/* |
int16_t RC_getPitch (void); |
int16_t RC_getYaw (void); |
int16_t RC_getRoll (void); |
uint16_t RC_getThrottle (void); |
uint8_t RC_hasNewRCData (void); |
*/ |
int16_t RC_getPitch (void); |
int16_t RC_getYaw (void); |
int16_t RC_getRoll (void); |
uint16_t RC_getThrottle (void); |
uint8_t RC_hasNewRCData (void); |
*/ |
void RC_update(void); |
int16_t* RC_getPRTY(void); |
uint8_t RC_getArgument(void); |
uint8_t RC_getCommand(void); |
int16_t RC_getVariable(uint8_t varNum); |
void RC_calibrate(void); |
uint8_t RC_getSignalQuality(void); |
uint8_t RC_getLooping(uint8_t looping); |
uint8_t RC_testCompassCalState(void); |
void RC_update(void); |
int16_t* RC_getPRTY(void); |
uint8_t RC_getArgument(void); |
uint8_t RC_getCommand(void); |
int16_t RC_getVariable(uint8_t varNum); |
void RC_calibrate(void); |
uint8_t RC_getSignalQuality(void); |
uint8_t RC_getLooping(uint8_t looping); |
uint8_t RC_testCompassCalState(void); |
#endif //_RC_H |
/branches/dongfang_FC_rewrite/sod2 |
---|
0,0 → 1,45 |
void SendOutData(uint8_t cmd, uint8_t addr, uint8_t numofbuffers, ...) { // uint8_t *pdata, uint8_t len, ... |
va_list ap; |
uint16_t txd_bufferIndex = 0; |
uint8_t *currentBuffer; |
uint8_t currentBufferIndex; |
uint16_t lengthOfCurrentBuffer; |
uint8_t shift = 0; |
txd_buffer[txd_bufferIndex++] = '#'; // Start character |
txd_buffer[txd_bufferIndex++] = 'a' + addr; // Address (a=0; b=1,...) |
txd_buffer[txd_bufferIndex++] = cmd; // Command |
va_start(ap, numofbuffers); |
while(numofbuffers) { |
currentBuffer = va_arg(ap, uint8_t*); |
lengthOfCurrentBuffer = va_arg(ap, int); |
currentBufferIndex = 0; |
// Encode data: 3 bytes of data are encoded into 4 bytes, |
// where the 2 most significant bits are both 0. |
while(currentBufferIndex != lengthOfCurrentBuffer) { |
if (!shift) txd_buffer[txd_bufferIndex] = 0; |
txd_buffer[txd_bufferIndex] |= currentBuffer[currentBufferIndex] >> (shift + 2); |
txd_buffer[++txd_bufferIndex] = (currentBuffer[currentBufferIndex] << (4 - shift)) & 0b00111111; |
shift += 2; |
if (shift == 6) { shift=0; txd_bufferIndex++; } |
currentBufferIndex++; |
} |
} |
// If the number of data bytes was not divisible by 3, stuff |
// with 0 pseudodata until length is again divisible by 3. |
if (shift == 2) { |
// We need to stuff with zero bytes at the end. |
txd_buffer[txd_bufferIndex] &= 0b00110000; |
txd_buffer[++txd_bufferIndex] = 0; |
shift = 4; |
} |
if (shift == 4) { |
// We need to stuff with zero bytes at the end. |
txd_buffer[txd_bufferIndex++] &= 0b00111100; |
txd_buffer[txd_bufferIndex] = 0; |
} |
va_end(ap); |
AddCRC(pt); // add checksum after data block and initates the transmission |
} |
/branches/dongfang_FC_rewrite/spectrum.c |
---|
1,6 → 1,6 |
/*####################################################################################### |
Decodieren eines RC Summen Signals oder Spektrum Empfänger-Satellit |
#######################################################################################*/ |
Decodieren eines RC Summen Signals oder Spektrum Empfänger-Satellit |
#######################################################################################*/ |
#include "Spectrum.h" |
7,58 → 7,71 |
//--------------------------------------------------------------// |
//--------------------------------------------------------------// |
void SpektrumBinding(void) |
{ |
unsigned int timerTimeout = SetDelay(10000); // Timeout 10 sec. |
unsigned char connected = 0; |
unsigned int delaycounter; |
UCSR1B &= ~(1 << RXCIE1); // disable rx-interrupt |
UCSR1B &= ~(1<<RXEN1); // disable Uart-Rx |
PORTD &= ~(1 << PORTD2); // disable pull-up |
printf("\n\rPlease connect Spektrum receiver for binding NOW..."); |
while(!CheckDelay(timerTimeout)) |
{ |
if (PIND & (1 << PORTD2)) { timerTimeout = SetDelay(90); connected = 1; break; } |
} |
if (connected) |
{ |
printf("ok.\n\r"); |
DDRD |= (1 << DDD2); // Rx as output |
void SpektrumBinding(void) { |
unsigned int timerTimeout = SetDelay(10000); // Timeout 10 sec. |
unsigned char connected = 0; |
unsigned int delaycounter; |
while(!CheckDelay(timerTimeout)); // delay after startup of RX |
for (delaycounter = 0; delaycounter < 100; delaycounter++) PORTD |= (1 << PORTD2); |
for (delaycounter = 0; delaycounter < 400; delaycounter++) PORTD &= ~(1 << PORTD2); |
for (delaycounter = 0; delaycounter < 10; delaycounter++) PORTD |= (1 << PORTD2); |
for (delaycounter = 0; delaycounter < 10; delaycounter++) PORTD &= ~(1 << PORTD2); |
for (delaycounter = 0; delaycounter < 400; delaycounter++) PORTD |= (1 << PORTD2); |
for (delaycounter = 0; delaycounter < 400; delaycounter++) PORTD &= ~(1 << PORTD2); |
for (delaycounter = 0; delaycounter < 10; delaycounter++) PORTD |= (1 << PORTD2); |
for (delaycounter = 0; delaycounter < 10; delaycounter++) PORTD &= ~(1 << PORTD2); |
for (delaycounter = 0; delaycounter < 400; delaycounter++) PORTD |= (1 << PORTD2); |
for (delaycounter = 0; delaycounter < 400; delaycounter++) PORTD &= ~(1 << PORTD2); |
UCSR1B &= ~(1 << RXCIE1); // disable rx-interrupt |
UCSR1B &= ~(1 << RXEN1); // disable Uart-Rx |
PORTD &= ~(1 << PORTD2); // disable pull-up |
for (delaycounter = 0; delaycounter < 10; delaycounter++) PORTD |= (1 << PORTD2); |
for (delaycounter = 0; delaycounter < 10; delaycounter++) PORTD &= ~(1 << PORTD2); |
for (delaycounter = 0; delaycounter < 400; delaycounter++) PORTD |= (1 << PORTD2); |
} |
else |
{ printf("Timeout.\n\r"); |
} |
DDRD &= ~(1 << DDD2); // RX as input |
PORTD &= ~(1 << PORTD2); |
printf("\n\rPlease connect Spektrum receiver for binding NOW..."); |
Uart1Init(); // init Uart again |
while (!CheckDelay(timerTimeout)) { |
if (PIND & (1 << PORTD2)) { |
timerTimeout = SetDelay(90); |
connected = 1; |
break; |
} |
} |
if (connected) { |
printf("ok.\n\r"); |
DDRD |= (1 << DDD2); // Rx as output |
while (!CheckDelay(timerTimeout)) |
; // delay after startup of RX |
for (delaycounter = 0; delaycounter < 100; delaycounter++) |
PORTD |= (1 << PORTD2); |
for (delaycounter = 0; delaycounter < 400; delaycounter++) |
PORTD &= ~(1 << PORTD2); |
for (delaycounter = 0; delaycounter < 10; delaycounter++) |
PORTD |= (1 << PORTD2); |
for (delaycounter = 0; delaycounter < 10; delaycounter++) |
PORTD &= ~(1 << PORTD2); |
for (delaycounter = 0; delaycounter < 400; delaycounter++) |
PORTD |= (1 << PORTD2); |
for (delaycounter = 0; delaycounter < 400; delaycounter++) |
PORTD &= ~(1 << PORTD2); |
for (delaycounter = 0; delaycounter < 10; delaycounter++) |
PORTD |= (1 << PORTD2); |
for (delaycounter = 0; delaycounter < 10; delaycounter++) |
PORTD &= ~(1 << PORTD2); |
for (delaycounter = 0; delaycounter < 400; delaycounter++) |
PORTD |= (1 << PORTD2); |
for (delaycounter = 0; delaycounter < 400; delaycounter++) |
PORTD &= ~(1 << PORTD2); |
for (delaycounter = 0; delaycounter < 10; delaycounter++) |
PORTD |= (1 << PORTD2); |
for (delaycounter = 0; delaycounter < 10; delaycounter++) |
PORTD &= ~(1 << PORTD2); |
for (delaycounter = 0; delaycounter < 400; delaycounter++) |
PORTD |= (1 << PORTD2); |
} else { |
printf("Timeout.\n\r"); |
} |
DDRD &= ~(1 << DDD2); // RX as input |
PORTD &= ~(1 << PORTD2); |
Uart1Init(); // init Uart again |
} |
//############################################################################ |
66,10 → 79,10 |
// USART1 initialisation from killagreg |
void Uart1Init(void) |
//############################################################################ |
{ |
{ |
// -- Start of USART1 initialisation for Spekturm seriell-mode |
// USART1 Control and Status Register A, B, C and baud rate register |
uint16_t ubrr = (uint16_t) ((uint32_t) SYSCLK/(8 * 115200) - 1); |
uint16_t ubrr = (uint16_t) ((uint32_t) SYSCLK / (8 * 115200) - 1); |
// disable RX-Interrupt |
UCSR1B &= ~(1 << RXCIE1); |
// disable TX-Interrupt |
82,9 → 95,9 |
DDRD &= ~(1 << DDD2); |
// USART0 Baud Rate Register |
// set clock divider |
UBRR1H = (uint8_t)(ubrr>>8); |
UBRR1L = (uint8_t)ubrr; |
UBRR1H = (uint8_t) (ubrr >> 8); |
UBRR1L = (uint8_t) ubrr; |
// enable double speed operation |
UCSR1A |= (1 << U2X1); |
// enable receiver and transmitter |
91,9 → 104,7 |
//UCSR1B = (1<<RXEN1)|(1<<TXEN1); |
UCSR1B = (1<<RXEN1); |
UCSR1B = (1 << RXEN1); |
// set asynchronous mode |
UCSR1C &= ~(1 << UMSEL11); |
UCSR1C &= ~(1 << UMSEL10); |
104,16 → 115,17 |
UCSR1C &= ~(1 << USBS1); |
// 8-bit |
UCSR1B &= ~(1 << UCSZ12); |
UCSR1C |= (1 << UCSZ11); |
UCSR1C |= (1 << UCSZ10); |
UCSR1C |= (1 << UCSZ11); |
UCSR1C |= (1 << UCSZ10); |
// flush receive buffer explicit |
while(UCSR1A & (1<<RXC1)) UDR1; |
while (UCSR1A & (1 << RXC1)) |
UDR1; |
// enable RX-interrupts at the end |
UCSR1B |= (1 << RXCIE1); |
// -- End of USART1 initialisation |
return; |
} |
return; |
} |
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
// + Copyright (c) Rainer Walther |
// + RC-routines from original MK rc.c (c) H&I |
186,124 → 198,113 |
//############################################################################ |
//Diese Routine startet und inizialisiert den USART1 für seriellen Spektrum satellite reciever |
SIGNAL(USART1_RX_vect) |
SIGNAL( USART1_RX_vect) |
//############################################################################ |
{ |
static unsigned int Sync=0, FrameCnt=0, ByteHigh=0, ReSync=1, Frame2=0, FrameTimer; |
static unsigned int Sync = 0, FrameCnt = 0, ByteHigh = 0, ReSync = 1, Frame2 = |
0, FrameTimer; |
unsigned int Channel, index; |
signed int signal, tmp; |
int bCheckDelay; |
uint8_t c; |
c = UDR1; // get data byte |
if (ReSync == 1) |
{ |
if (ReSync == 1) { |
// wait for beginning of new frame |
ReSync = 0; |
FrameTimer = SetDelay(7); // minimum 7ms zwischen den frames |
FrameTimer = SetDelay(7); // minimum 7ms zwischen den frames |
FrameCnt = 0; |
Sync = 0; |
ByteHigh = 0; |
} |
else |
{ |
bCheckDelay = CheckDelay(FrameTimer); |
if ( Sync == 0 ) |
{ |
if(bCheckDelay) |
{ |
// nach einer Pause von mind. 7ms erstes Sync-Character gefunden |
// Zeichen ignorieren, da Bedeutung unbekannt |
Sync = 1; |
FrameCnt ++; |
} else { |
bCheckDelay = CheckDelay(FrameTimer); |
if (Sync == 0) { |
if (bCheckDelay) { |
// nach einer Pause von mind. 7ms erstes Sync-Character gefunden |
// Zeichen ignorieren, da Bedeutung unbekannt |
Sync = 1; |
FrameCnt++; |
} else { |
// Zeichen kam vor Ablauf der 7ms Sync-Pause |
// warten auf erstes Sync-Zeichen |
} |
else |
{ |
// Zeichen kam vor Ablauf der 7ms Sync-Pause |
// warten auf erstes Sync-Zeichen |
} else if ((Sync == 1) && !bCheckDelay) { |
// zweites Sync-Character ignorieren, Bedeutung unbekannt |
Sync = 2; |
FrameCnt++; |
} else if ((Sync == 2) && !bCheckDelay) { |
// Datenbyte high |
ByteHigh = c; |
if (FrameCnt == 2) { |
// is 1st Byte of Channel-data |
// Frame 1 with Channel 1-7 comming next |
Frame2 = 0; |
if (ByteHigh & 0x80) { |
// DS9: Frame 2 with Channel 8-9 comming next |
Frame2 = 1; |
} |
} |
} |
else if((Sync == 1) && !bCheckDelay) |
{ |
// zweites Sync-Character ignorieren, Bedeutung unbekannt |
Sync = 2; |
FrameCnt ++; |
} |
else if((Sync == 2) && !bCheckDelay) |
{ |
// Datenbyte high |
ByteHigh = c; |
if (FrameCnt == 2) |
{ |
// is 1st Byte of Channel-data |
// Frame 1 with Channel 1-7 comming next |
Frame2 = 0; |
if(ByteHigh & 0x80) |
{ |
// DS9: Frame 2 with Channel 8-9 comming next |
Frame2 = 1; |
Sync = 3; |
FrameCnt++; |
} else if ((Sync == 3) && !bCheckDelay) { |
// Datenbyte low |
// High-Byte for next channel comes next |
Sync = 2; |
FrameCnt++; |
index = (ByteHigh >> 2) & 0x0f; |
index++; |
Channel = (ByteHigh << 8) | c; |
signal = Channel & 0x3ff; |
signal -= 0x200; // Offset, range 0x000..0x3ff? |
signal = signal / 3; // scaling to fit PPM resolution |
if (index >= 0 && index <= 10) { |
// Stabiles Signal |
if (abs(signal - PPM_in[index]) < 6) { |
if (SenderOkay < 200) |
SenderOkay += 10; |
else |
SenderOkay = 200; |
} |
} |
Sync = 3; |
FrameCnt ++; |
} |
else if((Sync == 3) && !bCheckDelay) |
{ |
// Datenbyte low |
// High-Byte for next channel comes next |
Sync = 2; |
FrameCnt ++; |
index = (ByteHigh >> 2) & 0x0f; |
index ++; |
Channel = (ByteHigh << 8) | c; |
signal = Channel & 0x3ff; |
signal -= 0x200; // Offset, range 0x000..0x3ff? |
signal = signal/3; // scaling to fit PPM resolution |
if(index >= 0 && index <= 10) |
{ |
// Stabiles Signal |
if(abs(signal - PPM_in[index]) < 6) { if(SenderOkay < 200) SenderOkay += 10; else SenderOkay = 200;} |
tmp = (3 * (PPM_in[index]) + signal) / 4; |
if(tmp > signal+1) tmp--; else |
if(tmp < signal-1) tmp++; |
if(SenderOkay >= 180) PPM_diff[index] = ((tmp - PPM_in[index]) / 3) * 3; |
else PPM_diff[index] = 0; |
PPM_in[index] = tmp; |
tmp = (3 * (PPM_in[index]) + signal) / 4; |
if (tmp > signal + 1) |
tmp--; |
else if (tmp < signal - 1) |
tmp++; |
if (SenderOkay >= 180) |
PPM_diff[index] = ((tmp - PPM_in[index]) / 3) * 3; |
else |
PPM_diff[index] = 0; |
PPM_in[index] = tmp; |
} |
} else { |
// hier stimmt was nicht: neu synchronisieren |
ReSync = 1; |
FrameCnt = 0; |
Frame2 = 0; |
} |
else |
{ |
// hier stimmt was nicht: neu synchronisieren |
ReSync = 1; |
FrameCnt = 0; |
Frame2 = 0; |
} |
// 16 Bytes per frame |
if(FrameCnt >= 16) |
{ |
// Frame complete |
if(Frame2 == 0) |
{ |
// Null bedeutet: Neue Daten |
// nur beim ersten Frame (CH 0-7) setzen |
NewPpmData = 0; |
// 16 Bytes per frame |
if (FrameCnt >= 16) { |
// Frame complete |
if (Frame2 == 0) { |
// Null bedeutet: Neue Daten |
// nur beim ersten Frame (CH 0-7) setzen |
NewPpmData = 0; |
} |
// new frame next, nach fruehestens 7ms erwartet |
FrameCnt = 0; |
Frame2 = 0; |
Sync = 0; |
// new frame next, nach fruehestens 7ms erwartet |
FrameCnt = 0; |
Frame2 = 0; |
Sync = 0; |
} |
// Zeit bis zum nächsten Zeichen messen |
FrameTimer = SetDelay(7); |
} |
} |
// Zeit bis zum nächsten Zeichen messen |
FrameTimer = SetDelay(7); |
} |
} |
/branches/dongfang_FC_rewrite/spectrum.h |
---|
1,6 → 1,6 |
/*####################################################################################### |
Dekodieren eines Spectrum Signals |
#######################################################################################*/ |
Dekodieren eines Spectrum Signals |
#######################################################################################*/ |
#ifndef _SPECTRUM_H |
#define _SPECTRUM_H |
/branches/dongfang_FC_rewrite/spi.c |
---|
126,27 → 126,24 |
#define SPI_RXSYNCBYTE2 0x55 |
typedef enum { |
SPI_SYNC1, |
SPI_SYNC2, |
SPI_DATA |
SPI_SYNC1, SPI_SYNC2, SPI_DATA |
} SPI_RXState_t; |
// data exchange packets to and From NaviCtrl |
ToNaviCtrl_t toNaviCtrl; |
FromNaviCtrl_t fromNaviCtrl; |
SPI_VersionInfo_t SPI_VersionInfo; |
ToNaviCtrl_t toNaviCtrl; |
FromNaviCtrl_t fromNaviCtrl; |
SPI_VersionInfo_t SPI_VersionInfo; |
// rx packet buffer |
#define SPI_RXBUFFER_LEN sizeof(fromNaviCtrl) |
uint8_t SPI_RxBuffer[SPI_RXBUFFER_LEN]; |
uint8_t SPI_RxBufferIndex = 0; |
uint8_t SPI_RxBufferIndex = 0; |
uint8_t SPI_RxBuffer_Request = 0; |
// tx packet buffer |
#define SPI_TXBUFFER_LEN sizeof(toNaviCtrl) |
uint8_t *SPI_TxBuffer; |
uint8_t SPI_TxBufferIndex = 0; |
uint8_t SPI_TxBufferIndex = 0; |
uint8_t SPITransferCompleted, SPI_ChkSum; |
uint8_t SPI_RxDataValid = 0; |
153,7 → 150,8 |
uint8_t NCDataOkay = 0; |
uint8_t NCSerialDataOkay = 0; |
uint8_t SPI_CommandSequence[] = { SPI_CMD_USER, SPI_CMD_STICK, SPI_CMD_PARAMETER1, SPI_CMD_STICK, SPI_CMD_MISC, SPI_CMD_VERSION }; |
uint8_t SPI_CommandSequence[] = { SPI_CMD_USER, SPI_CMD_STICK, |
SPI_CMD_PARAMETER1, SPI_CMD_STICK, SPI_CMD_MISC, SPI_CMD_VERSION }; |
uint8_t SPI_CommandCounter = 0; |
/*********************************************/ |
160,32 → 158,32 |
/* Initialize SPI interface to NaviCtrl */ |
/*********************************************/ |
void SPI_MasterInit(void) { |
DDR_SPI |= (1<<DD_MOSI)|(1<<DD_SCK); // Set MOSI and SCK output, all others input |
SLAVE_SELECT_DDR_PORT |= (1 << SPI_SLAVE_SELECT); // set Slave select port as output port |
SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR1)|(0<<SPR0)|(0<<SPIE); // Enable SPI, Master, set clock rate fck/64 |
SPSR = 0;//(1<<SPI2X); |
SLAVE_SELECT_PORT |= (1 << SPI_SLAVE_SELECT); // Deselect Slave |
SPI_TxBuffer = (uint8_t *) &toNaviCtrl; // set pointer to tx-buffer |
SPITransferCompleted = 1; |
// initialize data packet to NaviControl |
toNaviCtrl.Sync1 = SPI_TXSYNCBYTE1; |
toNaviCtrl.Sync2 = SPI_TXSYNCBYTE2; |
toNaviCtrl.Command = SPI_CMD_USER; |
toNaviCtrl.IntegralPitch = 0; |
toNaviCtrl.IntegralRoll = 0; |
NCSerialDataOkay = 0; |
NCDataOkay = 0; |
SPI_RxDataValid = 0; |
SPI_VersionInfo.Major = VERSION_MAJOR; |
SPI_VersionInfo.Minor = VERSION_MINOR; |
SPI_VersionInfo.Patch = VERSION_PATCH; |
SPI_VersionInfo.Compatible = NC_SPI_COMPATIBLE; |
DDR_SPI |= (1 << DD_MOSI) | (1 << DD_SCK); // Set MOSI and SCK output, all others input |
SLAVE_SELECT_DDR_PORT |= (1 << SPI_SLAVE_SELECT); // set Slave select port as output port |
SPCR = (1 << SPE) | (1 << MSTR) | (1 << SPR1) | (0 << SPR0) | (0 << SPIE); // Enable SPI, Master, set clock rate fck/64 |
SPSR = 0;//(1<<SPI2X); |
SLAVE_SELECT_PORT |= (1 << SPI_SLAVE_SELECT); // Deselect Slave |
SPI_TxBuffer = (uint8_t *) &toNaviCtrl; // set pointer to tx-buffer |
SPITransferCompleted = 1; |
// initialize data packet to NaviControl |
toNaviCtrl.Sync1 = SPI_TXSYNCBYTE1; |
toNaviCtrl.Sync2 = SPI_TXSYNCBYTE2; |
toNaviCtrl.Command = SPI_CMD_USER; |
toNaviCtrl.IntegralPitch = 0; |
toNaviCtrl.IntegralRoll = 0; |
NCSerialDataOkay = 0; |
NCDataOkay = 0; |
SPI_RxDataValid = 0; |
SPI_VersionInfo.Major = VERSION_MAJOR; |
SPI_VersionInfo.Minor = VERSION_MINOR; |
SPI_VersionInfo.Patch = VERSION_PATCH; |
SPI_VersionInfo.Compatible = NC_SPI_COMPATIBLE; |
} |
/**********************************************************/ |
192,155 → 190,203 |
/* Update Data transferd by the SPI from/to NaviCtrl */ |
/**********************************************************/ |
void UpdateSPI_Buffer(void) { |
uint8_t i; |
int16_t tmp; |
cli(); // stop all interrupts to avoid writing of new data during update of that packet. |
// update content of packet to NaviCtrl |
toNaviCtrl.IntegralPitch = (int16_t)((10 * angle[PITCH]) / GYRO_DEG_FACTOR_PITCHROLL); // convert to multiple of 0.1° |
toNaviCtrl.IntegralRoll = (int16_t)((10 * angle[ROLL]) / GYRO_DEG_FACTOR_PITCHROLL); // convert to multiple of 0.1° |
toNaviCtrl.GyroHeading = (int16_t)((10 * yawGyroHeading) / GYRO_DEG_FACTOR_YAW); // convert to multiple of 0.1° |
toNaviCtrl.GyroPitch = rate_ATT[PITCH]; |
toNaviCtrl.GyroRoll = rate_ATT[ROLL]; |
toNaviCtrl.GyroYaw = yawRate; |
toNaviCtrl.AccPitch = (10 * getAngleEstimateFromAcc(PITCH)) / GYRO_DEG_FACTOR_PITCHROLL; // convert to multiple of 0.1° |
toNaviCtrl.AccRoll = (10 * getAngleEstimateFromAcc(ROLL)) / GYRO_DEG_FACTOR_PITCHROLL; // convert to multiple of 0.1° |
// TODO: What are these little bastards? |
uint8_t i; |
int16_t tmp; |
cli(); |
// stop all interrupts to avoid writing of new data during update of that packet. |
averageAcc[PITCH] = averageAcc[ROLL] = averageAccCount = 0; |
switch(toNaviCtrl.Command) { |
case SPI_CMD_USER: |
for (i=0; i<sizeof(dynamicParams.UserParams); i++) { |
toNaviCtrl.Param.Byte[i] = dynamicParams.UserParams[i]; |
} |
toNaviCtrl.Param.Byte[8] = MKFlags; |
MKFlags &= ~(MKFLAG_CALIBRATE | MKFLAG_START); // calibrate and start are temporal states that are cleared immediately after transmitting |
toNaviCtrl.Param.Byte[9] = (uint8_t)UBat; |
toNaviCtrl.Param.Byte[10] = staticParams.LowVoltageWarning; |
toNaviCtrl.Param.Byte[11] = getActiveParamSet(); |
break; |
// update content of packet to NaviCtrl |
toNaviCtrl.IntegralPitch = (int16_t) ((10 * angle[PITCH]) |
/ GYRO_DEG_FACTOR_PITCHROLL); // convert to multiple of 0.1° |
toNaviCtrl.IntegralRoll = (int16_t) ((10 * angle[ROLL]) |
/ GYRO_DEG_FACTOR_PITCHROLL); // convert to multiple of 0.1° |
toNaviCtrl.GyroHeading = (int16_t) ((10 * yawGyroHeading) |
/ GYRO_DEG_FACTOR_YAW); // convert to multiple of 0.1° |
toNaviCtrl.GyroPitch = rate_ATT[PITCH]; |
toNaviCtrl.GyroRoll = rate_ATT[ROLL]; |
toNaviCtrl.GyroYaw = yawRate; |
toNaviCtrl.AccPitch = (10 * getAngleEstimateFromAcc(PITCH)) |
/ GYRO_DEG_FACTOR_PITCHROLL; // convert to multiple of 0.1° |
toNaviCtrl.AccRoll = (10 * getAngleEstimateFromAcc(ROLL)) |
/ GYRO_DEG_FACTOR_PITCHROLL; // convert to multiple of 0.1° |
case SPI_CMD_PARAMETER1: |
toNaviCtrl.Param.Byte[0] = staticParams.NaviGpsModeControl; // Parameters for the Naviboard |
toNaviCtrl.Param.Byte[1] = staticParams.NaviGpsGain; |
toNaviCtrl.Param.Byte[2] = staticParams.NaviGpsP; |
toNaviCtrl.Param.Byte[3] = staticParams.NaviGpsI; |
toNaviCtrl.Param.Byte[4] = staticParams.NaviGpsD; |
toNaviCtrl.Param.Byte[5] = staticParams.NaviGpsACC; |
toNaviCtrl.Param.Byte[6] = staticParams.NaviGpsMinSat; |
toNaviCtrl.Param.Byte[7] = staticParams.NaviStickThreshold; |
toNaviCtrl.Param.Byte[8] = staticParams.NaviOperatingRadius; |
toNaviCtrl.Param.Byte[9] = staticParams.NaviWindCorrection; |
toNaviCtrl.Param.Byte[10] = staticParams.NaviSpeedCompensation; |
toNaviCtrl.Param.Byte[11] = staticParams.NaviAngleLimitation; |
break; |
case SPI_CMD_STICK: |
tmp = PPM_in[staticParams.ChannelAssignment[CH_THROTTLE]]; if(tmp > 127) tmp = 127; else if(tmp < -128) tmp = -128; |
toNaviCtrl.Param.Byte[0] = (int8_t) tmp; |
tmp = PPM_in[staticParams.ChannelAssignment[CH_YAW]]; if(tmp > 127) tmp = 127; else if(tmp < -128) tmp = -128; |
toNaviCtrl.Param.Byte[1] = (int8_t) tmp; |
tmp = PPM_in[staticParams.ChannelAssignment[CH_ROLL]]; if(tmp > 127) tmp = 127; else if(tmp < -128) tmp = -128; |
toNaviCtrl.Param.Byte[2] = (int8_t) tmp; |
tmp = PPM_in[staticParams.ChannelAssignment[CH_PITCH]]; if(tmp > 127) tmp = 127; else if(tmp < -128) tmp = -128; |
toNaviCtrl.Param.Byte[3] = (int8_t) tmp; |
toNaviCtrl.Param.Byte[4] = (uint8_t) variables[0]; |
toNaviCtrl.Param.Byte[5] = (uint8_t) variables[1]; |
toNaviCtrl.Param.Byte[6] = (uint8_t) variables[2]; |
toNaviCtrl.Param.Byte[7] = (uint8_t) variables[3]; |
toNaviCtrl.Param.Byte[8] = (uint8_t) RC_Quality; |
break; |
case SPI_CMD_MISC: |
toNaviCtrl.Param.Byte[0] = compassCalState; |
if(compassCalState > 4) { // jump from 5 to 0 |
compassCalState = 0; |
} |
toNaviCtrl.Param.Byte[1] = staticParams.NaviPHLoginTime; |
// TODO: Height and in the correct scaling... |
toNaviCtrl.Param.Int[1] = 0; //readingHeight; // at address of Byte 2 and 3 |
toNaviCtrl.Param.Byte[4] = staticParams.NaviGpsPLimit; |
toNaviCtrl.Param.Byte[5] = staticParams.NaviGpsILimit; |
toNaviCtrl.Param.Byte[6] = staticParams.NaviGpsDLimit; |
break; |
case SPI_CMD_VERSION: |
toNaviCtrl.Param.Byte[0] = SPI_VersionInfo.Major; |
toNaviCtrl.Param.Byte[1] = SPI_VersionInfo.Minor; |
toNaviCtrl.Param.Byte[2] = SPI_VersionInfo.Patch; |
toNaviCtrl.Param.Byte[3] = SPI_VersionInfo.Compatible; |
toNaviCtrl.Param.Byte[4] = BoardRelease; |
break; |
default: |
break; |
} |
sei(); // enable all interrupts |
// analyze content of packet from NaviCtrl if valid |
if (SPI_RxDataValid) { |
// update gps controls |
if(abs(fromNaviCtrl.GPSStickPitch) < 512 && abs(fromNaviCtrl.GPSStickRoll) < 512 && (staticParams.GlobalConfig & CFG_GPS_ACTIVE)) { |
GPSStickPitch = fromNaviCtrl.GPSStickPitch; |
GPSStickRoll = fromNaviCtrl.GPSStickRoll; |
NCDataOkay = 250; |
} |
// update compass readings |
if(fromNaviCtrl.CompassHeading <= 360) { |
compassHeading = fromNaviCtrl.CompassHeading; |
} |
//if(compassHeading < 0) compassOffCourse = 0; |
//else compassOffCourse = ((540 + compassHeading - compassCourse) % 360) - 180; |
// NaviCtrl wants to beep? |
if (fromNaviCtrl.BeepTime > BeepTime && !compassCalState) BeepTime = fromNaviCtrl.BeepTime; |
switch (fromNaviCtrl.Command) { |
case SPI_KALMAN: |
dynamicParams.KalmanK = fromNaviCtrl.Param.Byte[0]; |
dynamicParams.KalmanMaxFusion = fromNaviCtrl.Param.Byte[1]; |
dynamicParams.KalmanMaxDrift = fromNaviCtrl.Param.Byte[2]; |
NCSerialDataOkay = fromNaviCtrl.Param.Byte[3]; |
break; |
default: |
break; |
} |
} else { // no valid data from NaviCtrl |
// disable GPS control |
GPSStickPitch = 0; |
GPSStickRoll = 0; |
} |
// TODO: What are these little bastards? |
averageAcc[PITCH] = averageAcc[ROLL] = averageAccCount = 0; |
switch (toNaviCtrl.Command) { |
case SPI_CMD_USER: |
for (i = 0; i < sizeof(dynamicParams.UserParams); i++) { |
toNaviCtrl.Param.Byte[i] = dynamicParams.UserParams[i]; |
} |
toNaviCtrl.Param.Byte[8] = MKFlags; |
MKFlags &= ~(MKFLAG_CALIBRATE | MKFLAG_START); // calibrate and start are temporal states that are cleared immediately after transmitting |
toNaviCtrl.Param.Byte[9] = (uint8_t) UBat; |
toNaviCtrl.Param.Byte[10] = staticParams.LowVoltageWarning; |
toNaviCtrl.Param.Byte[11] = getActiveParamSet(); |
break; |
case SPI_CMD_PARAMETER1: |
toNaviCtrl.Param.Byte[0] = staticParams.NaviGpsModeControl; // Parameters for the Naviboard |
toNaviCtrl.Param.Byte[1] = staticParams.NaviGpsGain; |
toNaviCtrl.Param.Byte[2] = staticParams.NaviGpsP; |
toNaviCtrl.Param.Byte[3] = staticParams.NaviGpsI; |
toNaviCtrl.Param.Byte[4] = staticParams.NaviGpsD; |
toNaviCtrl.Param.Byte[5] = staticParams.NaviGpsACC; |
toNaviCtrl.Param.Byte[6] = staticParams.NaviGpsMinSat; |
toNaviCtrl.Param.Byte[7] = staticParams.NaviStickThreshold; |
toNaviCtrl.Param.Byte[8] = staticParams.NaviOperatingRadius; |
toNaviCtrl.Param.Byte[9] = staticParams.NaviWindCorrection; |
toNaviCtrl.Param.Byte[10] = staticParams.NaviSpeedCompensation; |
toNaviCtrl.Param.Byte[11] = staticParams.NaviAngleLimitation; |
break; |
case SPI_CMD_STICK: |
tmp = PPM_in[staticParams.ChannelAssignment[CH_THROTTLE]]; |
if (tmp > 127) |
tmp = 127; |
else if (tmp < -128) |
tmp = -128; |
toNaviCtrl.Param.Byte[0] = (int8_t) tmp; |
tmp = PPM_in[staticParams.ChannelAssignment[CH_YAW]]; |
if (tmp > 127) |
tmp = 127; |
else if (tmp < -128) |
tmp = -128; |
toNaviCtrl.Param.Byte[1] = (int8_t) tmp; |
tmp = PPM_in[staticParams.ChannelAssignment[CH_ROLL]]; |
if (tmp > 127) |
tmp = 127; |
else if (tmp < -128) |
tmp = -128; |
toNaviCtrl.Param.Byte[2] = (int8_t) tmp; |
tmp = PPM_in[staticParams.ChannelAssignment[CH_PITCH]]; |
if (tmp > 127) |
tmp = 127; |
else if (tmp < -128) |
tmp = -128; |
toNaviCtrl.Param.Byte[3] = (int8_t) tmp; |
toNaviCtrl.Param.Byte[4] = (uint8_t) variables[0]; |
toNaviCtrl.Param.Byte[5] = (uint8_t) variables[1]; |
toNaviCtrl.Param.Byte[6] = (uint8_t) variables[2]; |
toNaviCtrl.Param.Byte[7] = (uint8_t) variables[3]; |
toNaviCtrl.Param.Byte[8] = (uint8_t) RC_Quality; |
break; |
case SPI_CMD_MISC: |
toNaviCtrl.Param.Byte[0] = compassCalState; |
if (compassCalState > 4) { // jump from 5 to 0 |
compassCalState = 0; |
} |
toNaviCtrl.Param.Byte[1] = staticParams.NaviPHLoginTime; |
// TODO: Height and in the correct scaling... |
toNaviCtrl.Param.Int[1] = 0; //readingHeight; // at address of Byte 2 and 3 |
toNaviCtrl.Param.Byte[4] = staticParams.NaviGpsPLimit; |
toNaviCtrl.Param.Byte[5] = staticParams.NaviGpsILimit; |
toNaviCtrl.Param.Byte[6] = staticParams.NaviGpsDLimit; |
break; |
case SPI_CMD_VERSION: |
toNaviCtrl.Param.Byte[0] = SPI_VersionInfo.Major; |
toNaviCtrl.Param.Byte[1] = SPI_VersionInfo.Minor; |
toNaviCtrl.Param.Byte[2] = SPI_VersionInfo.Patch; |
toNaviCtrl.Param.Byte[3] = SPI_VersionInfo.Compatible; |
toNaviCtrl.Param.Byte[4] = BoardRelease; |
break; |
default: |
break; |
} |
sei(); |
// enable all interrupts |
// analyze content of packet from NaviCtrl if valid |
if (SPI_RxDataValid) { |
// update gps controls |
if (abs(fromNaviCtrl.GPSStickPitch) < 512 && abs(fromNaviCtrl.GPSStickRoll) |
< 512 && (staticParams.GlobalConfig & CFG_GPS_ACTIVE)) { |
GPSStickPitch = fromNaviCtrl.GPSStickPitch; |
GPSStickRoll = fromNaviCtrl.GPSStickRoll; |
NCDataOkay = 250; |
} |
// update compass readings |
if (fromNaviCtrl.CompassHeading <= 360) { |
compassHeading = fromNaviCtrl.CompassHeading; |
} |
//if(compassHeading < 0) compassOffCourse = 0; |
//else compassOffCourse = ((540 + compassHeading - compassCourse) % 360) - 180; |
// NaviCtrl wants to beep? |
if (fromNaviCtrl.BeepTime > BeepTime && !compassCalState) |
BeepTime = fromNaviCtrl.BeepTime; |
switch (fromNaviCtrl.Command) { |
case SPI_KALMAN: |
dynamicParams.KalmanK = fromNaviCtrl.Param.Byte[0]; |
dynamicParams.KalmanMaxFusion = fromNaviCtrl.Param.Byte[1]; |
dynamicParams.KalmanMaxDrift = fromNaviCtrl.Param.Byte[2]; |
NCSerialDataOkay = fromNaviCtrl.Param.Byte[3]; |
break; |
default: |
break; |
} |
} else { // no valid data from NaviCtrl |
// disable GPS control |
GPSStickPitch = 0; |
GPSStickRoll = 0; |
} |
} |
/*********************************************/ |
/* Start Transmission of packet to NaviCtrl */ |
/*********************************************/ |
void SPI_StartTransmitPacket(void){ |
if (!SPITransferCompleted) return; // return immediately if transfer is in progress |
else // transmission was completed |
{ |
SLAVE_SELECT_PORT &= ~(1 << SPI_SLAVE_SELECT); // Select slave |
// cyclic commands |
toNaviCtrl.Command = SPI_CommandSequence[SPI_CommandCounter++]; |
if (SPI_CommandCounter >= sizeof(SPI_CommandSequence)) SPI_CommandCounter = 0; |
SPITransferCompleted = 0; // transfer is in progress |
UpdateSPI_Buffer(); // update data in toNaviCtrl |
SPI_TxBufferIndex = 1; //proceed with 2nd byte |
// -- Debug-Output --- |
//---- |
asm volatile ("nop"); asm volatile ("nop"); asm volatile ("nop"); asm volatile ("nop"); asm volatile ("nop"); asm volatile ("nop"); asm volatile ("nop"); asm volatile ("nop"); |
asm volatile ("nop"); asm volatile ("nop"); asm volatile ("nop"); asm volatile ("nop"); asm volatile ("nop"); asm volatile ("nop"); asm volatile ("nop"); asm volatile ("nop"); |
asm volatile ("nop"); asm volatile ("nop"); asm volatile ("nop"); asm volatile ("nop"); asm volatile ("nop"); asm volatile ("nop"); asm volatile ("nop"); asm volatile ("nop"); |
toNaviCtrl.Chksum = toNaviCtrl.Sync1; // init checksum |
SPDR = toNaviCtrl.Sync1; // send first byte |
} |
void SPI_StartTransmitPacket(void) { |
if (!SPITransferCompleted) |
return; // return immediately if transfer is in progress |
else // transmission was completed |
{ |
SLAVE_SELECT_PORT &= ~(1 << SPI_SLAVE_SELECT); // Select slave |
// cyclic commands |
toNaviCtrl.Command = SPI_CommandSequence[SPI_CommandCounter++]; |
if (SPI_CommandCounter >= sizeof(SPI_CommandSequence)) |
SPI_CommandCounter = 0; |
SPITransferCompleted = 0; // transfer is in progress |
UpdateSPI_Buffer(); // update data in toNaviCtrl |
SPI_TxBufferIndex = 1; //proceed with 2nd byte |
// -- Debug-Output --- |
//---- |
asm volatile ("nop"); |
asm volatile ("nop"); |
asm volatile ("nop"); |
asm volatile ("nop"); |
asm volatile ("nop"); |
asm volatile ("nop"); |
asm volatile ("nop"); |
asm volatile ("nop"); |
asm volatile ("nop"); |
asm volatile ("nop"); |
asm volatile ("nop"); |
asm volatile ("nop"); |
asm volatile ("nop"); |
asm volatile ("nop"); |
asm volatile ("nop"); |
asm volatile ("nop"); |
asm volatile ("nop"); |
asm volatile ("nop"); |
asm volatile ("nop"); |
asm volatile ("nop"); |
asm volatile ("nop"); |
asm volatile ("nop"); |
asm volatile ("nop"); |
asm volatile ("nop"); |
toNaviCtrl.Chksum = toNaviCtrl.Sync1; // init checksum |
SPDR = toNaviCtrl.Sync1; // send first byte |
} |
} |
//------------------------------------------------------ |
349,73 → 395,93 |
// the NaviCtrl and one byte of the packet from the NaviCtrl is possible transfered |
void SPI_TransmitByte(void) { |
static SPI_RXState_t SPI_RXState = SPI_SYNC1; |
uint8_t rxdata; |
static uint8_t rxchksum; |
if (SPITransferCompleted) return; // return immediatly if transfer was completed |
if (!(SPSR & (1 << SPIF))) return; // return if no SPI-IRQ pending |
SendSPI = 4; // mait 4 * 0.102 ms for the next call of SPI_TransmitByte() in the main loop |
SLAVE_SELECT_PORT |= (1 << SPI_SLAVE_SELECT); // DeselectSlave |
rxdata = SPDR; // save spi data register |
switch (SPI_RXState) { |
case SPI_SYNC1: // first sync byte |
SPI_RxBufferIndex = 0; // set pointer to start of rx buffer |
rxchksum = rxdata; // initialize checksum |
if (rxdata == SPI_RXSYNCBYTE1 ) |
{ // 1st Syncbyte found |
SPI_RXState = SPI_SYNC2; // trigger to state for second sync byte |
} |
break; |
case SPI_SYNC2: // second sync byte |
if (rxdata == SPI_RXSYNCBYTE2) |
{ // 2nd Syncbyte found |
rxchksum += rxdata; // update checksum |
SPI_RXState = SPI_DATA; // trigger to state for second sync byte |
} |
else // 2nd Syncbyte not found |
{ |
SPI_RXState = SPI_SYNC1; // jump back to 1st sync byte |
} |
break; |
case SPI_DATA: // data bytes |
SPI_RxBuffer[SPI_RxBufferIndex++] = rxdata; // copy data byte to spi buffer |
// if all bytes are received of a packet from the NaviCtrl |
if (SPI_RxBufferIndex >= SPI_RXBUFFER_LEN) { // last byte transfered is the checksum of the packet |
if (rxdata == rxchksum) { // checksum matching? |
// copy SPI_RxBuffer -> FromFlightCtrl |
uint8_t *ptr = (uint8_t *)&fromNaviCtrl; |
cli(); |
memcpy(ptr, (uint8_t *) SPI_RxBuffer, sizeof(fromNaviCtrl)); |
sei(); |
SPI_RxDataValid = 1; |
} else { // checksum does not match |
SPI_RxDataValid = 0; // reset valid flag |
} |
SPI_RXState = SPI_SYNC1; // reset state sync |
} else { // not all bytes transfered |
rxchksum += rxdata; // update checksum |
} |
break; |
}// eof switch(SPI_RXState) |
// if still some bytes left for transmission to NaviCtrl |
if (SPI_TxBufferIndex < SPI_TXBUFFER_LEN) { |
SLAVE_SELECT_PORT &= ~(1 << SPI_SLAVE_SELECT); // SelectSlave |
asm volatile ("nop"); asm volatile ("nop"); asm volatile ("nop"); asm volatile ("nop"); asm volatile ("nop"); asm volatile ("nop"); asm volatile ("nop"); asm volatile ("nop"); |
asm volatile ("nop"); asm volatile ("nop"); asm volatile ("nop"); asm volatile ("nop"); asm volatile ("nop"); asm volatile ("nop"); asm volatile ("nop"); asm volatile ("nop"); |
asm volatile ("nop"); asm volatile ("nop"); asm volatile ("nop"); asm volatile ("nop"); asm volatile ("nop"); asm volatile ("nop"); asm volatile ("nop"); asm volatile ("nop"); |
SPDR = SPI_TxBuffer[SPI_TxBufferIndex]; // transmit byte |
toNaviCtrl.Chksum += SPI_TxBuffer[SPI_TxBufferIndex]; // update checksum for everey byte that was sent |
SPI_TxBufferIndex++; |
} else { |
//Transfer of all bytes of the packet to NaviCtrl completed |
SPITransferCompleted = 1; |
} |
static SPI_RXState_t SPI_RXState = SPI_SYNC1; |
uint8_t rxdata; |
static uint8_t rxchksum; |
if (SPITransferCompleted) |
return; // return immediatly if transfer was completed |
if (!(SPSR & (1 << SPIF))) |
return; // return if no SPI-IRQ pending |
SendSPI = 4; // mait 4 * 0.102 ms for the next call of SPI_TransmitByte() in the main loop |
SLAVE_SELECT_PORT |= (1 << SPI_SLAVE_SELECT); // DeselectSlave |
rxdata = SPDR; // save spi data register |
switch (SPI_RXState) { |
case SPI_SYNC1: // first sync byte |
SPI_RxBufferIndex = 0; // set pointer to start of rx buffer |
rxchksum = rxdata; // initialize checksum |
if (rxdata == SPI_RXSYNCBYTE1) { // 1st Syncbyte found |
SPI_RXState = SPI_SYNC2; // trigger to state for second sync byte |
} |
break; |
case SPI_SYNC2: // second sync byte |
if (rxdata == SPI_RXSYNCBYTE2) { // 2nd Syncbyte found |
rxchksum += rxdata; // update checksum |
SPI_RXState = SPI_DATA; // trigger to state for second sync byte |
} else // 2nd Syncbyte not found |
{ |
SPI_RXState = SPI_SYNC1; // jump back to 1st sync byte |
} |
break; |
case SPI_DATA: // data bytes |
SPI_RxBuffer[SPI_RxBufferIndex++] = rxdata; // copy data byte to spi buffer |
// if all bytes are received of a packet from the NaviCtrl |
if (SPI_RxBufferIndex >= SPI_RXBUFFER_LEN) { // last byte transfered is the checksum of the packet |
if (rxdata == rxchksum) { // checksum matching? |
// copy SPI_RxBuffer -> FromFlightCtrl |
uint8_t *ptr = (uint8_t *) &fromNaviCtrl; |
cli(); |
memcpy(ptr, (uint8_t *) SPI_RxBuffer, sizeof(fromNaviCtrl)); |
sei(); |
SPI_RxDataValid = 1; |
} else { // checksum does not match |
SPI_RxDataValid = 0; // reset valid flag |
} |
SPI_RXState = SPI_SYNC1; // reset state sync |
} else { // not all bytes transfered |
rxchksum += rxdata; // update checksum |
} |
break; |
}// eof switch(SPI_RXState) |
// if still some bytes left for transmission to NaviCtrl |
if (SPI_TxBufferIndex < SPI_TXBUFFER_LEN) { |
SLAVE_SELECT_PORT &= ~(1 << SPI_SLAVE_SELECT); // SelectSlave |
asm volatile ("nop"); |
asm volatile ("nop"); |
asm volatile ("nop"); |
asm volatile ("nop"); |
asm volatile ("nop"); |
asm volatile ("nop"); |
asm volatile ("nop"); |
asm volatile ("nop"); |
asm volatile ("nop"); |
asm volatile ("nop"); |
asm volatile ("nop"); |
asm volatile ("nop"); |
asm volatile ("nop"); |
asm volatile ("nop"); |
asm volatile ("nop"); |
asm volatile ("nop"); |
asm volatile ("nop"); |
asm volatile ("nop"); |
asm volatile ("nop"); |
asm volatile ("nop"); |
asm volatile ("nop"); |
asm volatile ("nop"); |
asm volatile ("nop"); |
asm volatile ("nop"); |
SPDR = SPI_TxBuffer[SPI_TxBufferIndex]; // transmit byte |
toNaviCtrl.Chksum += SPI_TxBuffer[SPI_TxBufferIndex]; // update checksum for everey byte that was sent |
SPI_TxBufferIndex++; |
} else { |
//Transfer of all bytes of the packet to NaviCtrl completed |
SPITransferCompleted = 1; |
} |
} |
/branches/dongfang_FC_rewrite/spi.h |
---|
13,26 → 13,26 |
#define SPI_CMD_VERSION 14 |
typedef struct { |
uint8_t Sync1; |
uint8_t Sync2; |
uint8_t Command; |
int16_t IntegralPitch; |
int16_t IntegralRoll; |
int16_t AccPitch; |
int16_t AccRoll; |
int16_t GyroHeading; |
int16_t GyroPitch; |
int16_t GyroRoll; |
int16_t GyroYaw; |
union { |
int8_t sByte[12]; |
uint8_t Byte[12]; |
int16_t Int[6]; |
int32_t Long[3]; |
float Float[3]; |
} Param; |
uint8_t Chksum; |
} __attribute__((packed)) ToNaviCtrl_t; |
uint8_t Sync1; |
uint8_t Sync2; |
uint8_t Command; |
int16_t IntegralPitch; |
int16_t IntegralRoll; |
int16_t AccPitch; |
int16_t AccRoll; |
int16_t GyroHeading; |
int16_t GyroPitch; |
int16_t GyroRoll; |
int16_t GyroYaw; |
union { |
int8_t sByte[12]; |
uint8_t Byte[12]; |
int16_t Int[6]; |
int32_t Long[3]; |
float Float[3]; |
} Param; |
uint8_t Chksum; |
}__attribute__((packed)) ToNaviCtrl_t; |
#define SPI_CMD_OSD_DATA 100 |
#define SPI_CMD_GPS_POS 101 |
40,39 → 40,39 |
#define SPI_KALMAN 103 |
typedef struct { |
uint8_t Command; |
int16_t GPSStickPitch; |
int16_t GPSStickRoll; |
int16_t GPS_Yaw; |
int16_t CompassHeading; |
int16_t Status; |
uint16_t BeepTime; |
union { |
int8_t Byte[12]; |
int16_t Int[6]; |
int32_t Long[3]; |
float Float[3]; |
} Param; |
uint8_t Chksum; |
} __attribute__((packed)) FromNaviCtrl_t; |
uint8_t Command; |
int16_t GPSStickPitch; |
int16_t GPSStickRoll; |
int16_t GPS_Yaw; |
int16_t CompassHeading; |
int16_t Status; |
uint16_t BeepTime; |
union { |
int8_t Byte[12]; |
int16_t Int[6]; |
int32_t Long[3]; |
float Float[3]; |
} Param; |
uint8_t Chksum; |
}__attribute__((packed)) FromNaviCtrl_t; |
typedef struct { |
uint8_t Major; |
uint8_t Minor; |
uint8_t Patch; |
uint8_t Compatible; |
// unsigned char Hardware; |
} __attribute__((packed)) SPI_VersionInfo_t; |
uint8_t Major; |
uint8_t Minor; |
uint8_t Patch; |
uint8_t Compatible; |
// unsigned char Hardware; |
}__attribute__((packed)) SPI_VersionInfo_t; |
extern ToNaviCtrl_t toNaviCtrl; |
extern FromNaviCtrl_t fromNaviCtrl; |
extern ToNaviCtrl_t toNaviCtrl; |
extern FromNaviCtrl_t fromNaviCtrl; |
typedef struct { |
int8_t KalmanK; |
int8_t KalmanMaxDrift; |
int8_t KalmanMaxFusion; |
uint8_t SerialDataOkay; |
} __attribute__((packed)) NCData_t; |
int8_t KalmanK; |
int8_t KalmanMaxDrift; |
int8_t KalmanMaxFusion; |
uint8_t SerialDataOkay; |
}__attribute__((packed)) NCData_t; |
extern uint8_t NCDataOkay; |
extern uint8_t NCSerialDataOkay; |
/branches/dongfang_FC_rewrite/timer0.c |
---|
77,134 → 77,141 |
// timer 0 is used for the PWM generation to control the offset voltage at the air pressure sensor |
// Its overflow interrupt routine is used to generate the beep signal and the flight control motor update rate |
void timer0_init(void) { |
uint8_t sreg = SREG; |
uint8_t sreg = SREG; |
// disable all interrupts before reconfiguration |
cli(); |
// disable all interrupts before reconfiguration |
cli(); |
// Configure speaker port as output. |
if(BoardRelease == 10) { // Speaker at PD2 |
DDRD |= (1<<DDD2); |
PORTD &= ~(1<<PORTD2); |
} else { // Speaker at PC7 |
DDRC |= (1<<DDC7); |
PORTC &= ~(1<<PORTC7); |
} |
// Configure speaker port as output. |
// set PB3 and PB4 as output for the PWM used as offset for the pressure sensor |
DDRB |= (1<<DDB4)|(1<<DDB3); |
PORTB &= ~((1<<PORTB4)|(1<<PORTB3)); |
if (BoardRelease == 10) { // Speaker at PD2 |
DDRD |= (1 << DDD2); |
PORTD &= ~(1 << PORTD2); |
} else { // Speaker at PC7 |
DDRC |= (1 << DDC7); |
PORTC &= ~(1 << PORTC7); |
} |
// Timer/Counter 0 Control Register A |
// set PB3 and PB4 as output for the PWM used as offset for the pressure sensor |
DDRB |= (1 << DDB4) | (1 << DDB3); |
PORTB &= ~((1 << PORTB4) | (1 << PORTB3)); |
// Waveform Generation Mode is Fast PWM (Bits WGM02 = 0, WGM01 = 1, WGM00 = 1) |
// Clear OC0A on Compare Match, set OC0A at BOTTOM, noninverting PWM (Bits COM0A1 = 1, COM0A0 = 0) |
// Clear OC0B on Compare Match, set OC0B at BOTTOM, (Bits COM0B1 = 1, COM0B0 = 0) |
TCCR0A &= ~((1<<COM0A0)|(1<<COM0B0)); |
TCCR0A |= (1<<COM0A1)|(1<<COM0B1)|(1<<WGM01)|(1<<WGM00); |
// Timer/Counter 0 Control Register A |
// Timer/Counter 0 Control Register B |
// Waveform Generation Mode is Fast PWM (Bits WGM02 = 0, WGM01 = 1, WGM00 = 1) |
// Clear OC0A on Compare Match, set OC0A at BOTTOM, noninverting PWM (Bits COM0A1 = 1, COM0A0 = 0) |
// Clear OC0B on Compare Match, set OC0B at BOTTOM, (Bits COM0B1 = 1, COM0B0 = 0) |
TCCR0A &= ~((1 << COM0A0) | (1 << COM0B0)); |
TCCR0A |= (1 << COM0A1) | (1 << COM0B1) | (1 << WGM01) | (1 << WGM00); |
// set clock divider for timer 0 to SYSKLOCK/8 = 20MHz / 8 = 2.5MHz |
// i.e. the timer increments from 0x00 to 0xFF with an update rate of 2.5 MHz |
// hence the timer overflow interrupt frequency is 2.5 MHz / 256 = 9.765 kHz |
// Timer/Counter 0 Control Register B |
// divider 8 (Bits CS02 = 0, CS01 = 1, CS00 = 0) |
TCCR0B &= ~((1<<FOC0A)|(1<<FOC0B)|(1<<WGM02)); |
TCCR0B = (TCCR0B & 0xF8)|(0<<CS02)|(1<<CS01)|(0<<CS00); |
// set clock divider for timer 0 to SYSKLOCK/8 = 20MHz / 8 = 2.5MHz |
// i.e. the timer increments from 0x00 to 0xFF with an update rate of 2.5 MHz |
// hence the timer overflow interrupt frequency is 2.5 MHz / 256 = 9.765 kHz |
// initialize the Output Compare Register A & B used for PWM generation on port PB3 & PB4 |
OCR0A = 0; // for PB3 |
OCR0B = 120; // for PB4 |
// divider 8 (Bits CS02 = 0, CS01 = 1, CS00 = 0) |
TCCR0B &= ~((1 << FOC0A) | (1 << FOC0B) | (1 << WGM02)); |
TCCR0B = (TCCR0B & 0xF8) | (0 << CS02) | (1 << CS01) | (0 << CS00); |
// init Timer/Counter 0 Register |
TCNT0 = 0; |
// initialize the Output Compare Register A & B used for PWM generation on port PB3 & PB4 |
OCR0A = 0; // for PB3 |
OCR0B = 120; // for PB4 |
// Timer/Counter 0 Interrupt Mask Register |
// enable timer overflow interrupt only |
TIMSK0 &= ~((1<<OCIE0B)|(1<<OCIE0A)); |
TIMSK0 |= (1<<TOIE0); |
// init Timer/Counter 0 Register |
TCNT0 = 0; |
SREG = sreg; |
// Timer/Counter 0 Interrupt Mask Register |
// enable timer overflow interrupt only |
TIMSK0 &= ~((1 << OCIE0B) | (1 << OCIE0A)); |
TIMSK0 |= (1 << TOIE0); |
SREG = sreg; |
} |
/*****************************************************/ |
/* Interrupt Routine of Timer 0 */ |
/*****************************************************/ |
ISR(TIMER0_OVF_vect) { // 9765.625 Hz |
static uint8_t cnt_1ms = 1,cnt = 0; |
uint8_t Beeper_On = 0; |
ISR(TIMER0_OVF_vect) |
{ // 9765.625 Hz |
static uint8_t cnt_1ms = 1, cnt = 0; |
uint8_t Beeper_On = 0; |
#ifdef USE_NAVICTRL |
if(SendSPI) SendSPI--; // if SendSPI is 0, the transmit of a byte via SPI bus to and from The Navicontrol is done |
if(SendSPI) SendSPI--; // if SendSPI is 0, the transmit of a byte via SPI bus to and from The Navicontrol is done |
#endif |
if(!cnt--) { // every 10th run (9.765kHz/10 = 976Hz) |
cnt = 9; |
cnt_1ms^=1; |
if(!cnt_1ms) { |
runFlightControl = 1; // every 2nd run (976.5625 Hz/2 = 488.28125 Hz) |
} |
CountMilliseconds++; // increment millisecond counter |
} |
// beeper on if duration is not over |
if(BeepTime) { |
BeepTime--; // decrement BeepTime |
if(BeepTime & BeepModulation) Beeper_On = 1; |
else Beeper_On = 0; |
} |
else { // beeper off if duration is over |
Beeper_On = 0; |
BeepModulation = 0xFFFF; |
} |
// if beeper is on |
if(Beeper_On) { |
// set speaker port to high. |
if(BoardRelease == 10) PORTD |= (1<<PORTD2); // Speaker at PD2 |
else PORTC |= (1<<PORTC7); // Speaker at PC7 |
} else { // beeper is off |
// set speaker port to low |
if(BoardRelease == 10) PORTD &= ~(1<<PORTD2);// Speaker at PD2 |
else PORTC &= ~(1<<PORTC7);// Speaker at PC7 |
} |
if (!cnt--) { // every 10th run (9.765kHz/10 = 976Hz) |
cnt = 9; |
cnt_1ms ^= 1; |
if (!cnt_1ms) { |
runFlightControl = 1; // every 2nd run (976.5625 Hz/2 = 488.28125 Hz) |
} |
CountMilliseconds++; // increment millisecond counter |
} |
// beeper on if duration is not over |
if (BeepTime) { |
BeepTime--; // decrement BeepTime |
if (BeepTime & BeepModulation) |
Beeper_On = 1; |
else |
Beeper_On = 0; |
} else { // beeper off if duration is over |
Beeper_On = 0; |
BeepModulation = 0xFFFF; |
} |
// if beeper is on |
if (Beeper_On) { |
// set speaker port to high. |
if (BoardRelease == 10) |
PORTD |= (1 << PORTD2); // Speaker at PD2 |
else |
PORTC |= (1 << PORTC7); // Speaker at PC7 |
} else { // beeper is off |
// set speaker port to low |
if (BoardRelease == 10) |
PORTD &= ~(1 << PORTD2);// Speaker at PD2 |
else |
PORTC &= ~(1 << PORTC7);// Speaker at PC7 |
} |
#ifndef USE_NAVICTRL |
// update compass value if this option is enabled in the settings |
if(staticParams.GlobalConfig & (CFG_COMPASS_ACTIVE|CFG_GPS_ACTIVE)) { |
// update compass value if this option is enabled in the settings |
if (staticParams.GlobalConfig & (CFG_COMPASS_ACTIVE | CFG_GPS_ACTIVE)) { |
#ifdef USE_MK3MAG |
MK3MAG_Update(); // read out mk3mag pwm |
MK3MAG_Update(); // read out mk3mag pwm |
#endif |
} |
} |
#endif |
} |
// ----------------------------------------------------------------------- |
uint16_t SetDelay (uint16_t t) { |
return(CountMilliseconds + t - 1); |
uint16_t SetDelay(uint16_t t) { |
return (CountMilliseconds + t - 1); |
} |
// ----------------------------------------------------------------------- |
int8_t CheckDelay(uint16_t t) { |
return(((t - CountMilliseconds) & 0x8000) >> 8); // check sign bit |
return (((t - CountMilliseconds) & 0x8000) >> 8); // check sign bit |
} |
// ----------------------------------------------------------------------- |
void Delay_ms(uint16_t w) { |
uint16_t t_stop = SetDelay(w); |
while (!CheckDelay(t_stop)); |
uint16_t t_stop = SetDelay(w); |
while (!CheckDelay(t_stop)) |
; |
} |
// ----------------------------------------------------------------------- |
void Delay_ms_Mess(uint16_t w) { |
uint16_t t_stop; |
t_stop = SetDelay(w); |
while (!CheckDelay(t_stop)) { |
if(analogDataReady) { |
analogDataReady = 0; |
analog_start(); |
} |
} |
uint16_t t_stop; |
t_stop = SetDelay(w); |
while (!CheckDelay(t_stop)) { |
if (analogDataReady) { |
analogDataReady = 0; |
analog_start(); |
} |
} |
} |
/branches/dongfang_FC_rewrite/timer0.h |
---|
15,7 → 15,7 |
extern void timer0_init(void); |
extern void Delay_ms(uint16_t w); |
extern void Delay_ms_Mess(uint16_t w); |
extern uint16_t SetDelay (uint16_t t); |
extern int8_t CheckDelay (uint16_t t); |
extern uint16_t SetDelay(uint16_t t); |
extern int8_t CheckDelay(uint16_t t); |
#endif //_TIMER0_H |
/branches/dongfang_FC_rewrite/timer2.c |
---|
55,9 → 55,9 |
#include "rc.h" |
#include "attitude.h" |
volatile int16_t ServoPitchValue = 0; |
volatile int16_t ServoRollValue = 0; |
volatile uint8_t ServoActive = 0; |
volatile int16_t ServoPitchValue = 0; |
volatile int16_t ServoRollValue = 0; |
volatile uint8_t ServoActive = 0; |
#define HEF4017R_ON PORTC |= (1<<PORTC6) |
#define HEF4017R_OFF PORTC &= ~(1<<PORTC6) |
68,71 → 68,72 |
// The timer 2 is used to generate the PWM at PD7 (J7) |
// to control a camera servo for pitch compensation. |
void timer2_init(void) { |
uint8_t sreg = SREG; |
uint8_t sreg = SREG; |
// disable all interrupts before reconfiguration |
cli(); |
// disable all interrupts before reconfiguration |
cli(); |
// set PD7 as output of the PWM for pitch servo |
DDRD |= (1<<DDD7); |
PORTD &= ~(1<<PORTD7); // set PD7 to low |
// set PD7 as output of the PWM for pitch servo |
DDRD |= (1 << DDD7); |
PORTD &= ~(1 << PORTD7); // set PD7 to low |
DDRC |= (1<<DDC6); // set PC6 as output (Reset for HEF4017) |
//PORTC &= ~(1<<PORTC6); // set PC6 to low |
HEF4017R_ON; // enable reset |
DDRC |= (1 << DDC6); // set PC6 as output (Reset for HEF4017) |
//PORTC &= ~(1<<PORTC6); // set PC6 to low |
HEF4017R_ON; // enable reset |
// Timer/Counter 2 Control Register A |
// Timer/Counter 2 Control Register A |
// Timer Mode is FastPWM with timer reload at OCR2A (Bits: WGM22 = 1, WGM21 = 1, WGM20 = 1) |
// PD7: Normal port operation, OC2A disconnected, (Bits: COM2A1 = 0, COM2A0 = 0) |
// PD6: Normal port operation, OC2B disconnected, (Bits: COM2B1 = 0, COM2B0 = 0) |
TCCR2A &= ~((1<<COM2A1)|(1<<COM2A0)|(1<<COM2B1)|(1<<COM2B0)); |
TCCR2A |= (1<<WGM21)|(1<<WGM20); |
// Timer Mode is FastPWM with timer reload at OCR2A (Bits: WGM22 = 1, WGM21 = 1, WGM20 = 1) |
// PD7: Normal port operation, OC2A disconnected, (Bits: COM2A1 = 0, COM2A0 = 0) |
// PD6: Normal port operation, OC2B disconnected, (Bits: COM2B1 = 0, COM2B0 = 0) |
TCCR2A &= ~((1 << COM2A1) | (1 << COM2A0) | (1 << COM2B1) | (1 << COM2B0)); |
TCCR2A |= (1 << WGM21) | (1 << WGM20); |
// Timer/Counter 2 Control Register B |
// Timer/Counter 2 Control Register B |
// Set clock divider for timer 2 to SYSKLOCK/32 = 20MHz / 32 = 625 kHz |
// The timer increments from 0x00 to 0xFF with an update rate of 625 kHz or 1.6 us |
// hence the timer overflow interrupt frequency is 625 kHz / 256 = 2.44 kHz or 0.4096 ms |
// Set clock divider for timer 2 to SYSKLOCK/32 = 20MHz / 32 = 625 kHz |
// The timer increments from 0x00 to 0xFF with an update rate of 625 kHz or 1.6 us |
// hence the timer overflow interrupt frequency is 625 kHz / 256 = 2.44 kHz or 0.4096 ms |
// divider 32 (Bits: CS022 = 0, CS21 = 1, CS20 = 1) |
TCCR2B &= ~((1<<FOC2A)|(1<<FOC2B)|(1<<CS22)); |
TCCR2B |= (1<<CS21)|(1<<CS20)|(1<<WGM22); |
// divider 32 (Bits: CS022 = 0, CS21 = 1, CS20 = 1) |
TCCR2B &= ~((1 << FOC2A) | (1 << FOC2B) | (1 << CS22)); |
TCCR2B |= (1 << CS21) | (1 << CS20) | (1 << WGM22); |
// Initialize the Timer/Counter 2 Register |
TCNT2 = 0; |
// Initialize the Timer/Counter 2 Register |
TCNT2 = 0; |
// Initialize the Output Compare Register A used for PWM generation on port PD7. |
OCR2A = 255; |
TCCR2A |= (1<<COM2A1); // set or clear at compare match depends on value of COM2A0 |
// Initialize the Output Compare Register A used for PWM generation on port PD7. |
OCR2A = 255; |
TCCR2A |= (1 << COM2A1); // set or clear at compare match depends on value of COM2A0 |
// Timer/Counter 2 Interrupt Mask Register |
// Enable timer output compare match A Interrupt only |
TIMSK2 &= ~((1<<OCIE2B)|(1<<TOIE2)); |
TIMSK2 |= (1<<OCIE2A); |
// Timer/Counter 2 Interrupt Mask Register |
// Enable timer output compare match A Interrupt only |
TIMSK2 &= ~((1 << OCIE2B) | (1 << TOIE2)); |
TIMSK2 |= (1 << OCIE2A); |
SREG = sreg; |
SREG = sreg; |
} |
void Servo_On(void) { |
ServoActive = 1; |
ServoActive = 1; |
} |
void Servo_Off(void) { |
ServoActive = 0; |
HEF4017R_ON; // enable reset |
ServoActive = 0; |
HEF4017R_ON; // enable reset |
} |
/***************************************************** |
* Control Servo Position |
*****************************************************/ |
ISR(TIMER2_COMPA_vect) { |
// frame len 22.5 ms = 14063 * 1.6 us |
// stop pulse: 0.3 ms = 188 * 1.6 us |
// min servo pulse: 0.6 ms = 375 * 1.6 us |
// max servo pulse: 2.4 ms = 1500 * 1.6 us |
// resolution: 1500 - 375 = 1125 steps |
ISR(TIMER2_COMPA_vect) |
{ |
// frame len 22.5 ms = 14063 * 1.6 us |
// stop pulse: 0.3 ms = 188 * 1.6 us |
// min servo pulse: 0.6 ms = 375 * 1.6 us |
// max servo pulse: 2.4 ms = 1500 * 1.6 us |
// resolution: 1500 - 375 = 1125 steps |
#define PPM_STOPPULSE 188 |
#define PPM_FRAMELEN (1757 * .ServoRefresh) // 22.5 ms / 8 Channels = 2.8125ms per Servo Channel |
#define MINSERVOPULSE 375 |
140,157 → 141,157 |
#define SERVORANGE (MAXSERVOPULSE - MINSERVOPULSE) |
#if defined(USE_NON_4017_SERVO_OUTPUTS) || defined(USE_4017_SERVO_OUTPUTS) |
static uint8_t isGeneratingPulse = 0; |
static uint16_t remainingPulseLength = 0; |
static uint16_t ServoFrameTime = 0; |
static uint8_t ServoIndex = 0; |
static uint8_t isGeneratingPulse = 0; |
static uint16_t remainingPulseLength = 0; |
static uint16_t ServoFrameTime = 0; |
static uint8_t ServoIndex = 0; |
#define MULTIPLIER 4 |
static int16_t ServoPitchOffset = (255 / 2) * MULTIPLIER; // initial value near center position |
static int16_t ServoRollOffset = (255 / 2) * MULTIPLIER; // initial value near center position |
static int16_t ServoPitchOffset = (255 / 2) * MULTIPLIER; // initial value near center position |
static int16_t ServoRollOffset = (255 / 2) * MULTIPLIER; // initial value near center position |
#endif |
#ifdef USE_NON_4017_SERVO_OUTPUTS |
//--------------------------- |
// Pitch servo state machine |
//--------------------------- |
if (!isGeneratingPulse) { // pulse output complete on _next_ interrupt |
if(TCCR2A & (1<<COM2A0)) { // we are still outputting a high pulse |
TCCR2A &= ~(1<<COM2A0); // make a low pulse on _next_ interrupt, and now |
remainingPulseLength = MINSERVOPULSE + SERVORANGE / 2; // center position ~ 1.5ms |
ServoPitchOffset = (ServoPitchOffset * 3 + (int16_t)dynamicParams.ServoPitchControl) / 4; // lowpass offset |
if(staticParams.ServoPitchCompInvert & 0x01) { |
// inverting movement of servo |
// todo: function. |
ServoPitchValue = ServoPitchOffset + (int16_t)(((int32_t)staticParams.ServoPitchComp (integralGyroPitch / 128L )) / (256L)); |
} else { |
// todo: function. |
// non inverting movement of servo |
ServoPitchValue = ServoPitchOffset - (int16_t)(((int32_t)staticParams.ServoPitchComp (integralGyroPitch / 128L )) / (256L)); |
} |
// limit servo value to its parameter range definition |
if(ServoPitchValue < (int16_t)staticParams.ServoPitchMin) { |
ServoPitchValue = (int16_t)staticParams.ServoPitchMin; |
} else if(ServoPitchValue > (int16_t)staticParams.ServoPitchMax) { |
ServoPitchValue = (int16_t)staticParams.ServoPitchMax; |
} |
remainingPulseLength = (ServoPitchValue - 256 / 2) * MULTIPLIER; // shift ServoPitchValue to center position |
// range servo pulse width |
if(remainingPulseLength > MAXSERVOPULSE ) remainingPulseLength = MAXSERVOPULSE; // upper servo pulse limit |
else if(remainingPulseLength < MINSERVOPULSE) remainingPulseLength = MINSERVOPULSE; // lower servo pulse limit |
//--------------------------- |
// Pitch servo state machine |
//--------------------------- |
if (!isGeneratingPulse) { // pulse output complete on _next_ interrupt |
if(TCCR2A & (1<<COM2A0)) { // we are still outputting a high pulse |
TCCR2A &= ~(1<<COM2A0); // make a low pulse on _next_ interrupt, and now |
remainingPulseLength = MINSERVOPULSE + SERVORANGE / 2; // center position ~ 1.5ms |
ServoPitchOffset = (ServoPitchOffset * 3 + (int16_t)dynamicParams.ServoPitchControl) / 4; // lowpass offset |
if(staticParams.ServoPitchCompInvert & 0x01) { |
// inverting movement of servo |
// todo: function. |
ServoPitchValue = ServoPitchOffset + (int16_t)(((int32_t)staticParams.ServoPitchComp (integralGyroPitch / 128L )) / (256L)); |
} else { |
// todo: function. |
// non inverting movement of servo |
ServoPitchValue = ServoPitchOffset - (int16_t)(((int32_t)staticParams.ServoPitchComp (integralGyroPitch / 128L )) / (256L)); |
} |
// limit servo value to its parameter range definition |
if(ServoPitchValue < (int16_t)staticParams.ServoPitchMin) { |
ServoPitchValue = (int16_t)staticParams.ServoPitchMin; |
} else if(ServoPitchValue > (int16_t)staticParams.ServoPitchMax) { |
ServoPitchValue = (int16_t)staticParams.ServoPitchMax; |
} |
// accumulate time for correct update rate |
ServoFrameTime = remainingPulseLength; |
} else { // we had a high pulse |
TCCR2A |= (1<<COM2A0); // make a low pulse |
remainingPulseLength = PPM_FRAMELEN - ServoFrameTime; |
} |
// set pulse output active |
isGeneratingPulse = 1; |
} // EOF Pitch servo state machine |
remainingPulseLength = (ServoPitchValue - 256 / 2) * MULTIPLIER; // shift ServoPitchValue to center position |
// range servo pulse width |
if(remainingPulseLength > MAXSERVOPULSE ) remainingPulseLength = MAXSERVOPULSE; // upper servo pulse limit |
else if(remainingPulseLength < MINSERVOPULSE) remainingPulseLength = MINSERVOPULSE; // lower servo pulse limit |
// accumulate time for correct update rate |
ServoFrameTime = remainingPulseLength; |
} else { // we had a high pulse |
TCCR2A |= (1<<COM2A0); // make a low pulse |
remainingPulseLength = PPM_FRAMELEN - ServoFrameTime; |
} |
// set pulse output active |
isGeneratingPulse = 1; |
} // EOF Pitch servo state machine |
#elseif defined(USE_4017_SERVOS) |
//----------------------------------------------------- |
// PPM state machine, onboard demultiplexed by HEF4017 |
//----------------------------------------------------- |
if(!isGeneratingPulse) { // pulse output complete |
if(TCCR2A & (1<<COM2A0)) { // we had a low pulse |
TCCR2A &= ~(1<<COM2A0);// make a high pulse |
if(ServoIndex == 0) { // if we are at the sync gap |
remainingPulseLength = PPM_FRAMELEN - ServoFrameTime; // generate sync gap by filling time to full frame time |
ServoFrameTime = 0; // reset servo frame time |
HEF4017R_ON; // enable HEF4017 reset |
} else { // servo channels |
remainingPulseLength = MINSERVOPULSE + SERVORANGE/2; // center position ~ 1.5ms |
switch(ServoIndex) { // map servo channels |
case 1: // Pitch Compensation Servo |
ServoPitchOffset = (ServoPitchOffset * 3 + (int16_t)dynamicParams.ServoPitchControl * MULTIPLIER) / 4; // lowpass offset |
ServoPitchValue = ServoPitchOffset; // offset (Range from 0 to 255 * 3 = 765) |
if(staticParams.ServoPitchCompInvert & 0x01) { |
// inverting movement of servo |
ServoPitchValue += (int16_t)( ( (int32_t)staticParams.ServoPitchComp * MULTIPLIER * (integralGyroPitch / 128L ) ) / (256L) ); |
} else { // non inverting movement of servo |
ServoPitchValue -= (int16_t)( ( (int32_t)staticParams.ServoPitchComp * MULTIPLIER * (integralGyroPitch / 128L ) ) / (256L) ); |
//----------------------------------------------------- |
// PPM state machine, onboard demultiplexed by HEF4017 |
//----------------------------------------------------- |
if(!isGeneratingPulse) { // pulse output complete |
if(TCCR2A & (1<<COM2A0)) { // we had a low pulse |
TCCR2A &= ~(1<<COM2A0);// make a high pulse |
if(ServoIndex == 0) { // if we are at the sync gap |
remainingPulseLength = PPM_FRAMELEN - ServoFrameTime; // generate sync gap by filling time to full frame time |
ServoFrameTime = 0; // reset servo frame time |
HEF4017R_ON; // enable HEF4017 reset |
} else { // servo channels |
remainingPulseLength = MINSERVOPULSE + SERVORANGE/2; // center position ~ 1.5ms |
switch(ServoIndex) { // map servo channels |
case 1: // Pitch Compensation Servo |
ServoPitchOffset = (ServoPitchOffset * 3 + (int16_t)dynamicParams.ServoPitchControl * MULTIPLIER) / 4; // lowpass offset |
ServoPitchValue = ServoPitchOffset; // offset (Range from 0 to 255 * 3 = 765) |
if(staticParams.ServoPitchCompInvert & 0x01) { |
// inverting movement of servo |
ServoPitchValue += (int16_t)( ( (int32_t)staticParams.ServoPitchComp * MULTIPLIER * (integralGyroPitch / 128L ) ) / (256L) ); |
} else { // non inverting movement of servo |
ServoPitchValue -= (int16_t)( ( (int32_t)staticParams.ServoPitchComp * MULTIPLIER * (integralGyroPitch / 128L ) ) / (256L) ); |
} |
// limit servo value to its parameter range definition |
if(ServoPitchValue < ((int16_t)staticParams.ServoPitchMin * MULTIPLIER)) { |
ServoPitchValue = (int16_t)staticParams.ServoPitchMin * MULTIPLIER; |
} else if(ServoPitchValue > ((int16_t)staticParams.ServoPitchMax * MULTIPLIER)) { |
ServoPitchValue = (int16_t)staticParams.ServoPitchMax * MULTIPLIER; |
} |
remainingPulseLength += ServoPitchValue - (256 / 2) * MULTIPLIER; // shift ServoPitchValue to center position |
ServoPitchValue /= MULTIPLIER; |
break; |
case 2: // Roll Compensation Servo |
ServoRollOffset = (ServoRollOffset * 3 + (int16_t)80 * MULTIPLIER) / 4; // lowpass offset |
ServoRollValue = ServoRollOffset; // offset (Range from 0 to 255 * 3 = 765) |
//if(staticParams.ServoRollCompInvert & 0x01) |
{ // inverting movement of servo |
ServoRollValue += (int16_t)( ( (int32_t) 50 * MULTIPLIER * (integralGyroRoll / 128L ) ) / (256L) ); |
} |
/* else |
{ // non inverting movement of servo |
ServoRollValue -= (int16_t)( ( (int32_t) 40 * MULTIPLIER * (IntegralGyroRoll / 128L ) ) / (256L) ); |
} |
*/// limit servo value to its parameter range definition |
if(ServoRollValue < ((int16_t)staticParams.ServoPitchMin * MULTIPLIER)) { |
ServoRollValue = (int16_t)staticParams.ServoPitchMin * MULTIPLIER; |
} else if(ServoRollValue > ((int16_t)staticParams.ServoPitchMax * MULTIPLIER)) { |
ServoRollValue = (int16_t)staticParams.ServoPitchMax * MULTIPLIER; |
} |
remainingPulseLength += ServoRollValue - (256 / 2) * MULTIPLIER; // shift ServoRollValue to center position |
ServoRollValue /= MULTIPLIER; |
break; |
default: // other servo channels |
remainingPulseLength += 2 * PPM_in[ServoIndex]; // add channel value, factor of 2 because timer 1 increments 3.2µs |
break; |
} |
// range servo pulse width |
if(remainingPulseLength > MAXSERVOPULSE) remainingPulseLength = MAXSERVOPULSE; // upper servo pulse limit |
else if(remainingPulseLength < MINSERVOPULSE) remainingPulseLength = MINSERVOPULSE; // lower servo pulse limit |
// substract stop pulse width |
remainingPulseLength -= PPM_STOPPULSE; |
// accumulate time for correct sync gap |
ServoFrameTime += remainingPulseLength; |
} |
} else { // we had a high pulse |
TCCR2A |= (1<<COM2A0); // make a low pulse |
// set pulsewidth to stop pulse width |
remainingPulseLength = PPM_STOPPULSE; |
// accumulate time for correct sync gap |
ServoFrameTime += remainingPulseLength; |
if(ServoActive && RC_Quality > 180) HEF4017R_OFF; // disable HEF4017 reset |
ServoIndex++; // change to next servo channel |
if(ServoIndex > staticParams.ServoRefresh) ServoIndex = 0; // reset to the sync gap |
} |
// set pulse output active |
isGeneratingPulse = 1; |
} |
// limit servo value to its parameter range definition |
if(ServoPitchValue < ((int16_t)staticParams.ServoPitchMin * MULTIPLIER)) { |
ServoPitchValue = (int16_t)staticParams.ServoPitchMin * MULTIPLIER; |
} else if(ServoPitchValue > ((int16_t)staticParams.ServoPitchMax * MULTIPLIER)) { |
ServoPitchValue = (int16_t)staticParams.ServoPitchMax * MULTIPLIER; |
} |
remainingPulseLength += ServoPitchValue - (256 / 2) * MULTIPLIER; // shift ServoPitchValue to center position |
ServoPitchValue /= MULTIPLIER; |
break; |
case 2: // Roll Compensation Servo |
ServoRollOffset = (ServoRollOffset * 3 + (int16_t)80 * MULTIPLIER) / 4; // lowpass offset |
ServoRollValue = ServoRollOffset; // offset (Range from 0 to 255 * 3 = 765) |
//if(staticParams.ServoRollCompInvert & 0x01) |
{ // inverting movement of servo |
ServoRollValue += (int16_t)( ( (int32_t) 50 * MULTIPLIER * (integralGyroRoll / 128L ) ) / (256L) ); |
} |
/* else |
{ // non inverting movement of servo |
ServoRollValue -= (int16_t)( ( (int32_t) 40 * MULTIPLIER * (IntegralGyroRoll / 128L ) ) / (256L) ); |
} |
*/ // limit servo value to its parameter range definition |
if(ServoRollValue < ((int16_t)staticParams.ServoPitchMin * MULTIPLIER)) { |
ServoRollValue = (int16_t)staticParams.ServoPitchMin * MULTIPLIER; |
} else if(ServoRollValue > ((int16_t)staticParams.ServoPitchMax * MULTIPLIER)) { |
ServoRollValue = (int16_t)staticParams.ServoPitchMax * MULTIPLIER; |
} |
remainingPulseLength += ServoRollValue - (256 / 2) * MULTIPLIER; // shift ServoRollValue to center position |
ServoRollValue /= MULTIPLIER; |
break; |
default: // other servo channels |
remainingPulseLength += 2 * PPM_in[ServoIndex]; // add channel value, factor of 2 because timer 1 increments 3.2µs |
break; |
} |
// range servo pulse width |
if(remainingPulseLength > MAXSERVOPULSE) remainingPulseLength = MAXSERVOPULSE; // upper servo pulse limit |
else if(remainingPulseLength < MINSERVOPULSE) remainingPulseLength = MINSERVOPULSE; // lower servo pulse limit |
// substract stop pulse width |
remainingPulseLength -= PPM_STOPPULSE; |
// accumulate time for correct sync gap |
ServoFrameTime += remainingPulseLength; |
} |
} else { // we had a high pulse |
TCCR2A |= (1<<COM2A0); // make a low pulse |
// set pulsewidth to stop pulse width |
remainingPulseLength = PPM_STOPPULSE; |
// accumulate time for correct sync gap |
ServoFrameTime += remainingPulseLength; |
if(ServoActive && RC_Quality > 180) HEF4017R_OFF; // disable HEF4017 reset |
ServoIndex++; // change to next servo channel |
if(ServoIndex > staticParams.ServoRefresh) ServoIndex = 0; // reset to the sync gap |
} |
// set pulse output active |
isGeneratingPulse = 1; |
} |
#endif |
/* |
* Cases: |
* 1) 255 + 128 <= remainingPulseLength --> delta = 255 |
* 2) 255 <= remainingPulseLength < 255 + 128 --> delta = 255 - 128 |
* this is to avoid a too short delta on the last cycle, which would cause |
* an interupt-on-interrupt condition and the loss of the last interrupt. |
* 3) remainingPulseLength < 255 --> delta = remainingPulseLength |
*/ |
/* |
* Cases: |
* 1) 255 + 128 <= remainingPulseLength --> delta = 255 |
* 2) 255 <= remainingPulseLength < 255 + 128 --> delta = 255 - 128 |
* this is to avoid a too short delta on the last cycle, which would cause |
* an interupt-on-interrupt condition and the loss of the last interrupt. |
* 3) remainingPulseLength < 255 --> delta = remainingPulseLength |
*/ |
#if defined(USE_NON_4017_SERVO_OUTPUTS) || defined(USE_4017_SERVO_OUTPUTS) |
uint8_t delta; |
if (remainingPulseLength >= (255 + 128)) { |
delta = 255; |
} else if (remainingPulseLength >= 255) { |
delta = 255- 128; |
} else { |
delta = remainingPulseLength; |
isGeneratingPulse = 0; // trigger to stop pulse |
} |
OCR2A = delta; |
remainingPulseLength -= delta; |
uint8_t delta; |
if (remainingPulseLength >= (255 + 128)) { |
delta = 255; |
} else if (remainingPulseLength >= 255) { |
delta = 255- 128; |
} else { |
delta = remainingPulseLength; |
isGeneratingPulse = 0; // trigger to stop pulse |
} |
OCR2A = delta; |
remainingPulseLength -= delta; |
#endif |
} |
/branches/dongfang_FC_rewrite/twimaster.c |
---|
59,12 → 59,12 |
#include "configuration.h" |
#include "printf_P.h" |
volatile uint8_t twi_state = TWI_STATE_MOTOR_TX; |
volatile uint8_t dac_channel = 0; |
volatile uint8_t motor_write = 0; |
volatile uint8_t motor_read = 0; |
volatile uint16_t I2CTimeout = 100; |
uint8_t missingMotor = 0; |
volatile uint8_t twi_state = TWI_STATE_MOTOR_TX; |
volatile uint8_t dac_channel = 0; |
volatile uint8_t motor_write = 0; |
volatile uint8_t motor_read = 0; |
volatile uint16_t I2CTimeout = 100; |
uint8_t missingMotor = 0; |
MotorData_t motor[MAX_MOTORS]; |
78,36 → 78,36 |
* Initialize I2C (TWI) |
**************************************************/ |
void I2C_init(void) { |
uint8_t i; |
uint8_t sreg = SREG; |
cli(); |
// SDA is INPUT |
DDRC &= ~(1<<DDC1); |
// SCL is output |
DDRC |= (1<<DDC0); |
// pull up SDA |
PORTC |= (1<<PORTC0)|(1<<PORTC1); |
// TWI Status Register |
// prescaler 1 (TWPS1 = 0, TWPS0 = 0) |
TWSR &= ~((1<<TWPS1)|(1<<TWPS0)); |
// set TWI Bit Rate Register |
TWBR = ((SYSCLK/SCL_CLOCK)-16)/2; |
twi_state = TWI_STATE_MOTOR_TX; |
motor_write = 0; |
motor_read = 0; |
for(i=0; i < MAX_MOTORS; i++) { |
motor[i].SetPoint = 0; |
motor[i].Present = 0; |
motor[i].Error = 0; |
motor[i].MaxPWM = 0; |
} |
SREG = sreg; |
uint8_t i; |
uint8_t sreg = SREG; |
cli(); |
// SDA is INPUT |
DDRC &= ~(1 << DDC1); |
// SCL is output |
DDRC |= (1 << DDC0); |
// pull up SDA |
PORTC |= (1 << PORTC0) | (1 << PORTC1); |
// TWI Status Register |
// prescaler 1 (TWPS1 = 0, TWPS0 = 0) |
TWSR &= ~((1 << TWPS1) | (1 << TWPS0)); |
// set TWI Bit Rate Register |
TWBR = ((SYSCLK / SCL_CLOCK) - 16) / 2; |
twi_state = TWI_STATE_MOTOR_TX; |
motor_write = 0; |
motor_read = 0; |
for (i = 0; i < MAX_MOTORS; i++) { |
motor[i].SetPoint = 0; |
motor[i].Present = 0; |
motor[i].Error = 0; |
motor[i].MaxPWM = 0; |
} |
SREG = sreg; |
} |
/**************************************** |
114,16 → 114,16 |
* Start I2C |
****************************************/ |
void I2C_Start(uint8_t start_state) { |
twi_state = start_state; |
// TWI Control Register |
// clear TWI interrupt flag (TWINT=1) |
// disable TWI Acknowledge Bit (TWEA = 0) |
// enable TWI START Condition Bit (TWSTA = 1), MASTER |
// disable TWI STOP Condition Bit (TWSTO = 0) |
// disable TWI Write Collision Flag (TWWC = 0) |
// enable i2c (TWEN = 1) |
// enable TWI Interrupt (TWIE = 1) |
TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN) | (1<<TWIE); |
twi_state = start_state; |
// TWI Control Register |
// clear TWI interrupt flag (TWINT=1) |
// disable TWI Acknowledge Bit (TWEA = 0) |
// enable TWI START Condition Bit (TWSTA = 1), MASTER |
// disable TWI STOP Condition Bit (TWSTO = 0) |
// disable TWI Write Collision Flag (TWWC = 0) |
// enable i2c (TWEN = 1) |
// enable TWI Interrupt (TWIE = 1) |
TWCR = (1 << TWINT) | (1 << TWSTA) | (1 << TWEN) | (1 << TWIE); |
} |
/**************************************** |
130,16 → 130,16 |
* Stop I2C |
****************************************/ |
void I2C_Stop(uint8_t start_state) { |
twi_state = start_state; |
// TWI Control Register |
// clear TWI interrupt flag (TWINT=1) |
// disable TWI Acknowledge Bit (TWEA = 0) |
// diable TWI START Condition Bit (TWSTA = 1), no MASTER |
// enable TWI STOP Condition Bit (TWSTO = 1) |
// disable TWI Write Collision Flag (TWWC = 0) |
// enable i2c (TWEN = 1) |
// disable TWI Interrupt (TWIE = 0) |
TWCR = (1<<TWINT) | (1<<TWSTO) | (1<<TWEN); |
twi_state = start_state; |
// TWI Control Register |
// clear TWI interrupt flag (TWINT=1) |
// disable TWI Acknowledge Bit (TWEA = 0) |
// diable TWI START Condition Bit (TWSTA = 1), no MASTER |
// enable TWI STOP Condition Bit (TWSTO = 1) |
// disable TWI Write Collision Flag (TWWC = 0) |
// enable i2c (TWEN = 1) |
// disable TWI Interrupt (TWIE = 0) |
TWCR = (1 << TWINT) | (1 << TWSTO) | (1 << TWEN); |
} |
/**************************************** |
146,12 → 146,12 |
* Write to I2C |
****************************************/ |
void I2C_WriteByte(int8_t byte) { |
// move byte to send into TWI Data Register |
TWDR = byte; |
// clear interrupt flag (TWINT = 1) |
// enable i2c bus (TWEN = 1) |
// enable interrupt (TWIE = 1) |
TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWIE); |
// move byte to send into TWI Data Register |
TWDR = byte; |
// clear interrupt flag (TWINT = 1) |
// enable i2c bus (TWEN = 1) |
// enable interrupt (TWIE = 1) |
TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWIE); |
} |
/**************************************** |
158,14 → 158,14 |
* Receive byte and send ACK |
****************************************/ |
void I2C_ReceiveByte(void) { |
TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWIE) | (1<<TWEA); |
TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWIE) | (1 << TWEA); |
} |
/**************************************** |
* I2C receive last byte and send no ACK |
****************************************/ |
void I2C_ReceiveLastByte(void){ |
TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWIE); |
void I2C_ReceiveLastByte(void) { |
TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWIE); |
} |
/**************************************** |
172,139 → 172,148 |
* Reset I2C |
****************************************/ |
void I2C_Reset(void) { |
// stop i2c bus |
I2C_Stop(TWI_STATE_MOTOR_TX); |
twi_state = 0; |
motor_write = TWDR; |
motor_write = 0; |
motor_read = 0; |
TWCR = (1<<TWINT); // reset to original state incl. interrupt flag reset |
TWAMR = 0; |
TWAR = 0; |
TWDR = 0; |
TWSR = 0; |
TWBR = 0; |
I2C_init(); |
I2C_Start(TWI_STATE_MOTOR_TX); |
// stop i2c bus |
I2C_Stop(TWI_STATE_MOTOR_TX); |
twi_state = 0; |
motor_write = TWDR; |
motor_write = 0; |
motor_read = 0; |
TWCR = (1 << TWINT); // reset to original state incl. interrupt flag reset |
TWAMR = 0; |
TWAR = 0; |
TWDR = 0; |
TWSR = 0; |
TWBR = 0; |
I2C_init(); |
I2C_Start(TWI_STATE_MOTOR_TX); |
} |
/**************************************** |
* I2C ISR |
****************************************/ |
ISR (TWI_vect) { |
static uint8_t missing_motor = 0; |
switch (twi_state++) { // First i2c_start from SendMotorData() |
// Master Transmit |
case 0: // TWI_STATE_MOTOR_TX |
// skip motor if not used in mixer |
while((Mixer.Motor[motor_write][MIX_THROTTLE] <= 0) && (motor_write < MAX_MOTORS)) motor_write++; |
if(motor_write >= MAX_MOTORS) { // writing finished, read now |
motor_write = 0; |
twi_state = TWI_STATE_MOTOR_RX; |
I2C_WriteByte(0x53 + (motor_read * 2)); // select slave adress in rx mode |
} |
else I2C_WriteByte(0x52 + (motor_write * 2)); // select slave adress in tx mode |
break; |
case 1: // Send Data to Slave |
I2C_WriteByte(motor[motor_write].SetPoint); // transmit rotation rate setpoint |
break; |
case 2: // repeat case 0+1 for all motors |
if(TWSR == TW_MT_DATA_NACK) { // Data transmitted, NACK received |
if(!missing_motor) missing_motor = motor_write + 1; |
if(++motor[motor_write].Error == 0) motor[motor_write].Error = 255; // increment error counter and handle overflow |
} |
I2C_Stop(TWI_STATE_MOTOR_TX); |
I2CTimeout = 10; |
motor_write++; // next motor |
I2C_Start(TWI_STATE_MOTOR_TX); // Repeated start -> switch slave or switch Master Transmit -> Master Receive |
break; |
// Master Receive Data |
case 3: |
if(TWSR != TW_MR_SLA_ACK) { // SLA+R transmitted, if not ACK received |
// no response from the addressed slave received |
motor[motor_read].Present = 0; |
motor_read++; // next motor |
if(motor_read >= MAX_MOTORS) motor_read = 0; // restart reading of first motor if we have reached the last one |
I2C_Stop(TWI_STATE_MOTOR_TX); |
} else { |
motor[motor_read].Present = ('1' - '-') + motor_read; |
I2C_ReceiveByte(); //Transmit 1st byte |
} |
missingMotor = missing_motor; |
missing_motor = 0; |
break; |
case 4: //Read 1st byte and transmit 2nd Byte |
motor[motor_read].Current = TWDR; |
I2C_ReceiveLastByte(); // nack |
break; |
case 5: |
//Read 2nd byte |
motor[motor_read].MaxPWM = TWDR; |
motor_read++; // next motor |
if(motor_read >= MAX_MOTORS) motor_read = 0; // restart reading of first motor if we have reached the last one |
I2C_Stop(TWI_STATE_MOTOR_TX); |
break; |
// Writing ADC values. |
case 7: |
I2C_WriteByte(0x98); // Address the DAC |
break; |
case 8: |
I2C_WriteByte(0x10 + (DACChannel << 1)); // Select DAC Channel (0x10 = A, 0x12 = B, 0x14 = C) |
break; |
case 9: |
I2C_WriteByte(DACValues[DACChannel]); |
break; |
case 10: |
I2C_WriteByte(0x80); // 2nd byte for all channels is 0x80 |
break; |
case 11: |
I2C_Stop(TWI_STATE_MOTOR_TX); |
I2CTimeout = 10; |
// repeat case 7...10 until all DAC Channels are updated |
if(DACChannel < 2) { |
DACChannel ++; // jump to next channel |
I2C_Start(TWI_STATE_GYRO_OFFSET_TX); // start transmission for next channel |
} else { |
DACChannel = 0; // reset dac channel counter |
} |
break; |
default: |
I2C_Stop(TWI_STATE_MOTOR_TX); |
I2CTimeout = 10; |
motor_write = 0; |
motor_read = 0; |
} |
ISR (TWI_vect) |
{ |
static uint8_t missing_motor = 0; |
switch (twi_state++) { // First i2c_start from SendMotorData() |
// Master Transmit |
case 0: // TWI_STATE_MOTOR_TX |
// skip motor if not used in mixer |
while ((Mixer.Motor[motor_write][MIX_THROTTLE] <= 0) && (motor_write |
< MAX_MOTORS)) |
motor_write++; |
if (motor_write >= MAX_MOTORS) { // writing finished, read now |
motor_write = 0; |
twi_state = TWI_STATE_MOTOR_RX; |
I2C_WriteByte(0x53 + (motor_read * 2)); // select slave adress in rx mode |
} else |
I2C_WriteByte(0x52 + (motor_write * 2)); // select slave adress in tx mode |
break; |
case 1: // Send Data to Slave |
I2C_WriteByte(motor[motor_write].SetPoint); // transmit rotation rate setpoint |
break; |
case 2: // repeat case 0+1 for all motors |
if (TWSR == TW_MT_DATA_NACK) { // Data transmitted, NACK received |
if (!missing_motor) |
missing_motor = motor_write + 1; |
if (++motor[motor_write].Error == 0) |
motor[motor_write].Error = 255; // increment error counter and handle overflow |
} |
I2C_Stop(TWI_STATE_MOTOR_TX); |
I2CTimeout = 10; |
motor_write++; // next motor |
I2C_Start(TWI_STATE_MOTOR_TX); // Repeated start -> switch slave or switch Master Transmit -> Master Receive |
break; |
// Master Receive Data |
case 3: |
if (TWSR != TW_MR_SLA_ACK) { // SLA+R transmitted, if not ACK received |
// no response from the addressed slave received |
motor[motor_read].Present = 0; |
motor_read++; // next motor |
if (motor_read >= MAX_MOTORS) |
motor_read = 0; // restart reading of first motor if we have reached the last one |
I2C_Stop(TWI_STATE_MOTOR_TX); |
} else { |
motor[motor_read].Present = ('1' - '-') + motor_read; |
I2C_ReceiveByte(); //Transmit 1st byte |
} |
missingMotor = missing_motor; |
missing_motor = 0; |
break; |
case 4: //Read 1st byte and transmit 2nd Byte |
motor[motor_read].Current = TWDR; |
I2C_ReceiveLastByte(); // nack |
break; |
case 5: |
//Read 2nd byte |
motor[motor_read].MaxPWM = TWDR; |
motor_read++; // next motor |
if (motor_read >= MAX_MOTORS) |
motor_read = 0; // restart reading of first motor if we have reached the last one |
I2C_Stop(TWI_STATE_MOTOR_TX); |
break; |
// Writing ADC values. |
case 7: |
I2C_WriteByte(0x98); // Address the DAC |
break; |
case 8: |
I2C_WriteByte(0x10 + (DACChannel << 1)); // Select DAC Channel (0x10 = A, 0x12 = B, 0x14 = C) |
break; |
case 9: |
I2C_WriteByte(DACValues[DACChannel]); |
break; |
case 10: |
I2C_WriteByte(0x80); // 2nd byte for all channels is 0x80 |
break; |
case 11: |
I2C_Stop(TWI_STATE_MOTOR_TX); |
I2CTimeout = 10; |
// repeat case 7...10 until all DAC Channels are updated |
if (DACChannel < 2) { |
DACChannel++; // jump to next channel |
I2C_Start(TWI_STATE_GYRO_OFFSET_TX); // start transmission for next channel |
} else { |
DACChannel = 0; // reset dac channel counter |
} |
break; |
default: |
I2C_Stop(TWI_STATE_MOTOR_TX); |
I2CTimeout = 10; |
motor_write = 0; |
motor_read = 0; |
} |
} |
extern void twi_diagnostics(void) { |
// Check connected BL-Ctrls |
uint8_t i; |
printf("\n\rFound BL-Ctrl: "); |
for(i = 0; i < MAX_MOTORS; i++) { |
motor[i].SetPoint = 0; |
} |
// Check connected BL-Ctrls |
uint8_t i; |
I2C_Start(TWI_STATE_MOTOR_TX); |
_delay_ms(2); |
motor_read = 0; // read the first I2C-Data |
printf("\n\rFound BL-Ctrl: "); |
for(i = 0; i < MAX_MOTORS; i++) { |
I2C_Start(TWI_STATE_MOTOR_TX); |
_delay_ms(2); |
if(motor[i].Present) printf("%d ",i+1); |
} |
for (i = 0; i < MAX_MOTORS; i++) { |
motor[i].SetPoint = 0; |
} |
for(i = 0; i < MAX_MOTORS; i++) { |
if(!motor[i].Present && Mixer.Motor[i][MIX_THROTTLE] > 0) printf("\n\r\n\r!! MISSING BL-CTRL: %d !!",i + 1); |
motor[i].Error = 0; |
} |
I2C_Start(TWI_STATE_MOTOR_TX); |
_delay_ms(2); |
motor_read = 0; // read the first I2C-Data |
for (i = 0; i < MAX_MOTORS; i++) { |
I2C_Start(TWI_STATE_MOTOR_TX); |
_delay_ms(2); |
if (motor[i].Present) |
printf("%d ",i+1); |
} |
for (i = 0; i < MAX_MOTORS; i++) { |
if (!motor[i].Present && Mixer.Motor[i][MIX_THROTTLE] > 0) |
printf("\n\r\n\r!! MISSING BL-CTRL: %d !!",i + 1); |
motor[i].Error = 0; |
} |
} |
/branches/dongfang_FC_rewrite/twimaster.h |
---|
14,12 → 14,12 |
volatile extern uint8_t DACValues[4]; |
typedef struct { |
uint8_t SetPoint; // written by attitude controller |
uint8_t Present; // 0 if BL was found |
uint8_t Error; // I2C error counter |
uint8_t Current; // read byck from BL |
uint8_t MaxPWM; // read back from BL |
} __attribute__((packed)) MotorData_t; |
uint8_t SetPoint; // written by attitude controller |
uint8_t Present; // 0 if BL was found |
uint8_t Error; // I2C error counter |
uint8_t Current; // read byck from BL |
uint8_t MaxPWM; // read back from BL |
}__attribute__((packed)) MotorData_t; |
#define MAX_MOTORS 12 |
extern MotorData_t motor[MAX_MOTORS]; |
26,9 → 26,9 |
extern volatile uint16_t I2CTimeout; |
extern void I2C_init (void); // Initialize I2C |
extern void I2C_init(void); // Initialize I2C |
extern void I2C_Start(uint8_t start_state); // Start I2C |
extern void I2C_Stop (uint8_t start_state); // Stop I2C |
extern void I2C_Stop(uint8_t start_state); // Stop I2C |
extern void I2C_Reset(void); // Reset I2C |
extern void twi_diagnostics(void); |
/branches/dongfang_FC_rewrite/uart0.c |
---|
77,16 → 77,16 |
#define FALSE 0 |
#define TRUE 1 |
//int8_t test __attribute__ ((section (".noinit"))); |
uint8_t request_VerInfo = FALSE; |
uint8_t request_ExternalControl = FALSE; |
uint8_t request_Display = FALSE; |
uint8_t request_Display1 = FALSE; |
uint8_t request_DebugData = FALSE; |
uint8_t request_Data3D = FALSE; |
uint8_t request_DebugLabel = 255; |
uint8_t request_PPMChannels = FALSE; |
uint8_t request_MotorTest = FALSE; |
uint8_t request_variables = FALSE; |
uint8_t request_VerInfo = FALSE; |
uint8_t request_ExternalControl = FALSE; |
uint8_t request_Display = FALSE; |
uint8_t request_Display1 = FALSE; |
uint8_t request_DebugData = FALSE; |
uint8_t request_Data3D = FALSE; |
uint8_t request_DebugLabel = 255; |
uint8_t request_PPMChannels = FALSE; |
uint8_t request_MotorTest = FALSE; |
uint8_t request_variables = FALSE; |
uint8_t DisplayLine = 0; |
98,17 → 98,17 |
volatile uint8_t *pRxData = 0; |
volatile uint8_t RxDataLen = 0; |
uint8_t motorTestActive = 0; |
uint8_t motorTest[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; |
uint8_t motorTestActive = 0; |
uint8_t motorTest[16] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; |
uint8_t ConfirmFrame; |
typedef struct { |
int16_t Heading; |
} __attribute__((packed)) Heading_t; |
int16_t Heading; |
}__attribute__((packed)) Heading_t; |
DebugOut_t DebugOut; |
Data3D_t Data3D; |
UART_VersionInfo_t UART_VersionInfo; |
DebugOut_t DebugOut; |
Data3D_t Data3D; |
UART_VersionInfo_t UART_VersionInfo; |
uint16_t DebugData_Timer; |
uint16_t Data3D_Timer; |
121,210 → 121,211 |
// keep lables in flash to save 512 bytes of sram space |
const prog_uint8_t ANALOG_LABEL[32][16] = { |
//1234567890123456 |
"AnglePitch ", //0 |
"AngleRoll ", |
"AngleYaw ", |
"GyroPitch(PID) ", |
"GyroRoll(PID) ", |
"GyroYaw ", //5 |
"GyroPitch(AC) ", |
"GyroRoll(AC) ", |
"GyroYaw(AC) ", |
"AccPitch (angle)", |
"AccRoll (angle) ", //10 |
"UBat ", |
"Pitch Term ", |
"Roll Term ", |
"Yaw Term ", |
"Throttle Term ", //15 |
"0th O Corr pitch", |
"0th O Corr roll ", |
"DriftCompDelta P", |
"DriftCompDelta R", |
"ADPitchGyroOffs ", //20 |
"ADRollGyroOffs ", |
"M1 ", |
"M2 ", |
"M3 ", |
"M4 ", //25 |
"ControlYaw ", |
"Airpress. Range ", |
"DriftCompPitch ", |
"DriftCompRoll ", |
"AirpressFiltered", //30 |
"AirpressADC " |
}; |
//1234567890123456 |
"AnglePitch ", //0 |
"AngleRoll ", |
"AngleYaw ", |
"GyroPitch(PID) ", |
"GyroRoll(PID) ", |
"GyroYaw ", //5 |
"GyroPitch(AC) ", |
"GyroRoll(AC) ", |
"GyroYaw(AC) ", |
"AccPitch (angle)", |
"AccRoll (angle) ", //10 |
"UBat ", |
"Pitch Term ", |
"Roll Term ", |
"Yaw Term ", |
"Throttle Term ", //15 |
"0th O Corr pitch", "0th O Corr roll ", |
"DriftCompDelta P", |
"DriftCompDelta R", |
"ADPitchGyroOffs ", //20 |
"ADRollGyroOffs ", "M1 ", "M2 ", |
"M3 ", |
"M4 ", //25 |
"ControlYaw ", "Airpress. Range ", "DriftCompPitch ", |
"DriftCompRoll ", "AirpressFiltered", //30 |
"AirpressADC " }; |
/****************************************************************/ |
/* Initialization of the USART0 */ |
/****************************************************************/ |
void usart0_Init (void) { |
uint8_t sreg = SREG; |
uint16_t ubrr = (uint16_t) ((uint32_t) SYSCLK/(8 * USART0_BAUD) - 1); |
// disable all interrupts before configuration |
cli(); |
// disable RX-Interrupt |
UCSR0B &= ~(1 << RXCIE0); |
// disable TX-Interrupt |
UCSR0B &= ~(1 << TXCIE0); |
// set direction of RXD0 and TXD0 pins |
// set RXD0 (PD0) as an input pin |
PORTD |= (1 << PORTD0); |
DDRD &= ~(1 << DDD0); |
// set TXD0 (PD1) as an output pin |
PORTD |= (1 << PORTD1); |
DDRD |= (1 << DDD1); |
// USART0 Baud Rate Register |
// set clock divider |
UBRR0H = (uint8_t)(ubrr >> 8); |
UBRR0L = (uint8_t)ubrr; |
// USART0 Control and Status Register A, B, C |
// enable double speed operation in |
UCSR0A |= (1 << U2X0); |
// enable receiver and transmitter in |
UCSR0B = (1 << TXEN0) | (1 << RXEN0); |
// set asynchronous mode |
UCSR0C &= ~(1 << UMSEL01); |
UCSR0C &= ~(1 << UMSEL00); |
// no parity |
UCSR0C &= ~(1 << UPM01); |
UCSR0C &= ~(1 << UPM00); |
// 1 stop bit |
UCSR0C &= ~(1 << USBS0); |
// 8-bit |
UCSR0B &= ~(1 << UCSZ02); |
UCSR0C |= (1 << UCSZ01); |
UCSR0C |= (1 << UCSZ00); |
// flush receive buffer |
while ( UCSR0A & (1<<RXC0) ) UDR0; |
// enable interrupts at the end |
// enable RX-Interrupt |
UCSR0B |= (1 << RXCIE0); |
// enable TX-Interrupt |
UCSR0B |= (1 << TXCIE0); |
// initialize the debug timer |
DebugData_Timer = SetDelay(DebugData_Interval); |
// unlock rxd_buffer |
rxd_buffer_locked = FALSE; |
pRxData = 0; |
RxDataLen = 0; |
// no bytes to send |
txd_complete = TRUE; |
void usart0_Init(void) { |
uint8_t sreg = SREG; |
uint16_t ubrr = (uint16_t) ((uint32_t) SYSCLK / (8 * USART0_BAUD) - 1); |
// disable all interrupts before configuration |
cli(); |
// disable RX-Interrupt |
UCSR0B &= ~(1 << RXCIE0); |
// disable TX-Interrupt |
UCSR0B &= ~(1 << TXCIE0); |
// set direction of RXD0 and TXD0 pins |
// set RXD0 (PD0) as an input pin |
PORTD |= (1 << PORTD0); |
DDRD &= ~(1 << DDD0); |
// set TXD0 (PD1) as an output pin |
PORTD |= (1 << PORTD1); |
DDRD |= (1 << DDD1); |
// USART0 Baud Rate Register |
// set clock divider |
UBRR0H = (uint8_t) (ubrr >> 8); |
UBRR0L = (uint8_t) ubrr; |
// USART0 Control and Status Register A, B, C |
// enable double speed operation in |
UCSR0A |= (1 << U2X0); |
// enable receiver and transmitter in |
UCSR0B = (1 << TXEN0) | (1 << RXEN0); |
// set asynchronous mode |
UCSR0C &= ~(1 << UMSEL01); |
UCSR0C &= ~(1 << UMSEL00); |
// no parity |
UCSR0C &= ~(1 << UPM01); |
UCSR0C &= ~(1 << UPM00); |
// 1 stop bit |
UCSR0C &= ~(1 << USBS0); |
// 8-bit |
UCSR0B &= ~(1 << UCSZ02); |
UCSR0C |= (1 << UCSZ01); |
UCSR0C |= (1 << UCSZ00); |
// flush receive buffer |
while (UCSR0A & (1 << RXC0)) |
UDR0; |
// enable interrupts at the end |
// enable RX-Interrupt |
UCSR0B |= (1 << RXCIE0); |
// enable TX-Interrupt |
UCSR0B |= (1 << TXCIE0); |
// initialize the debug timer |
DebugData_Timer = SetDelay(DebugData_Interval); |
// unlock rxd_buffer |
rxd_buffer_locked = FALSE; |
pRxData = 0; |
RxDataLen = 0; |
// no bytes to send |
txd_complete = TRUE; |
#ifdef USE_MK3MAG |
Compass_Timer = SetDelay(220); |
Compass_Timer = SetDelay(220); |
#endif |
UART_VersionInfo.SWMajor = VERSION_MAJOR; |
UART_VersionInfo.SWMinor = VERSION_MINOR; |
UART_VersionInfo.SWPatch = VERSION_PATCH; |
UART_VersionInfo.ProtoMajor = VERSION_SERIAL_MAJOR; |
UART_VersionInfo.ProtoMinor = VERSION_SERIAL_MINOR; |
// restore global interrupt flags |
SREG = sreg; |
UART_VersionInfo.SWMajor = VERSION_MAJOR; |
UART_VersionInfo.SWMinor = VERSION_MINOR; |
UART_VersionInfo.SWPatch = VERSION_PATCH; |
UART_VersionInfo.ProtoMajor = VERSION_SERIAL_MAJOR; |
UART_VersionInfo.ProtoMinor = VERSION_SERIAL_MINOR; |
// restore global interrupt flags |
SREG = sreg; |
} |
/****************************************************************/ |
/* USART0 transmitter ISR */ |
/****************************************************************/ |
ISR(USART0_TX_vect) { |
static uint16_t ptr_txd_buffer = 0; |
uint8_t tmp_tx; |
if(!txd_complete) { // transmission not completed |
ptr_txd_buffer++; // die [0] wurde schon gesendet |
tmp_tx = txd_buffer[ptr_txd_buffer]; |
// if terminating character or end of txd buffer was reached |
if((tmp_tx == '\r') || (ptr_txd_buffer == TXD_BUFFER_LEN)) { |
ptr_txd_buffer = 0; // reset txd pointer |
txd_complete = 1; // stop transmission |
} |
UDR0 = tmp_tx; // send current byte will trigger this ISR again |
} |
// transmission completed |
else ptr_txd_buffer = 0; |
ISR(USART0_TX_vect) |
{ |
static uint16_t ptr_txd_buffer = 0; |
uint8_t tmp_tx; |
if (!txd_complete) { // transmission not completed |
ptr_txd_buffer++; // die [0] wurde schon gesendet |
tmp_tx = txd_buffer[ptr_txd_buffer]; |
// if terminating character or end of txd buffer was reached |
if ((tmp_tx == '\r') || (ptr_txd_buffer == TXD_BUFFER_LEN)) { |
ptr_txd_buffer = 0; // reset txd pointer |
txd_complete = 1; // stop transmission |
} |
UDR0 = tmp_tx; // send current byte will trigger this ISR again |
} |
// transmission completed |
else |
ptr_txd_buffer = 0; |
} |
/****************************************************************/ |
/* USART0 receiver ISR */ |
/****************************************************************/ |
ISR(USART0_RX_vect) { |
static uint16_t crc; |
static uint8_t ptr_rxd_buffer = 0; |
uint8_t crc1, crc2; |
uint8_t c; |
ISR(USART0_RX_vect) |
{ |
static uint16_t crc; |
static uint8_t ptr_rxd_buffer = 0; |
uint8_t crc1, crc2; |
uint8_t c; |
c = UDR0; // catch the received byte |
c = UDR0; // catch the received byte |
if(rxd_buffer_locked) return; // if rxd buffer is locked immediately return |
if (rxd_buffer_locked) |
return; // if rxd buffer is locked immediately return |
// the rxd buffer is unlocked |
if((ptr_rxd_buffer == 0) && (c == '#')) { // if rxd buffer is empty and syncronisation character is received |
rxd_buffer[ptr_rxd_buffer++] = c; // copy 1st byte to buffer |
crc = c; // init crc |
} |
// the rxd buffer is unlocked |
if ((ptr_rxd_buffer == 0) && (c == '#')) { // if rxd buffer is empty and syncronisation character is received |
rxd_buffer[ptr_rxd_buffer++] = c; // copy 1st byte to buffer |
crc = c; // init crc |
} |
#if 0 |
else if (ptr_rxd_buffer == 1) { // handle address |
rxd_buffer[ptr_rxd_buffer++] = c; // copy byte to rxd buffer |
crc += c; // update crc |
} |
else if (ptr_rxd_buffer == 1) { // handle address |
rxd_buffer[ptr_rxd_buffer++] = c; // copy byte to rxd buffer |
crc += c; // update crc |
} |
#endif |
else if (ptr_rxd_buffer < RXD_BUFFER_LEN) { // collect incomming bytes |
if(c != '\r') { // no termination character |
rxd_buffer[ptr_rxd_buffer++] = c; // copy byte to rxd buffer |
crc += c; // update crc |
} else { // termination character was received |
// the last 2 bytes are no subject for checksum calculation |
// they are the checksum itself |
crc -= rxd_buffer[ptr_rxd_buffer-2]; |
crc -= rxd_buffer[ptr_rxd_buffer-1]; |
// calculate checksum from transmitted data |
crc %= 4096; |
crc1 = '=' + crc / 64; |
crc2 = '=' + crc % 64; |
// compare checksum to transmitted checksum bytes |
if((crc1 == rxd_buffer[ptr_rxd_buffer-2]) && (crc2 == rxd_buffer[ptr_rxd_buffer-1])) { |
// checksum valid |
rxd_buffer[ptr_rxd_buffer] = '\r'; // set termination character |
ReceivedBytes = ptr_rxd_buffer + 1;// store number of received bytes |
rxd_buffer_locked = TRUE; // lock the rxd buffer |
// if 2nd byte is an 'R' enable watchdog that will result in an reset |
if(rxd_buffer[2] == 'R') {wdt_enable(WDTO_250MS);} // Reset-Commando |
} else { // checksum invalid |
rxd_buffer_locked = FALSE; // unlock rxd buffer |
} |
ptr_rxd_buffer = 0; // reset rxd buffer pointer |
} |
} else { // rxd buffer overrun |
ptr_rxd_buffer = 0; // reset rxd buffer |
rxd_buffer_locked = FALSE; // unlock rxd buffer |
} |
else if (ptr_rxd_buffer < RXD_BUFFER_LEN) { // collect incomming bytes |
if (c != '\r') { // no termination character |
rxd_buffer[ptr_rxd_buffer++] = c; // copy byte to rxd buffer |
crc += c; // update crc |
} else { // termination character was received |
// the last 2 bytes are no subject for checksum calculation |
// they are the checksum itself |
crc -= rxd_buffer[ptr_rxd_buffer - 2]; |
crc -= rxd_buffer[ptr_rxd_buffer - 1]; |
// calculate checksum from transmitted data |
crc %= 4096; |
crc1 = '=' + crc / 64; |
crc2 = '=' + crc % 64; |
// compare checksum to transmitted checksum bytes |
if ((crc1 == rxd_buffer[ptr_rxd_buffer - 2]) && (crc2 |
== rxd_buffer[ptr_rxd_buffer - 1])) { |
// checksum valid |
rxd_buffer[ptr_rxd_buffer] = '\r'; // set termination character |
ReceivedBytes = ptr_rxd_buffer + 1;// store number of received bytes |
rxd_buffer_locked = TRUE; // lock the rxd buffer |
// if 2nd byte is an 'R' enable watchdog that will result in an reset |
if (rxd_buffer[2] == 'R') { |
wdt_enable(WDTO_250MS); |
} // Reset-Commando |
} else { // checksum invalid |
rxd_buffer_locked = FALSE; // unlock rxd buffer |
} |
ptr_rxd_buffer = 0; // reset rxd buffer pointer |
} |
} else { // rxd buffer overrun |
ptr_rxd_buffer = 0; // reset rxd buffer |
rxd_buffer_locked = FALSE; // unlock rxd buffer |
} |
} |
// -------------------------------------------------------------------------- |
void AddCRC(uint16_t datalen) { |
uint16_t tmpCRC = 0, i; |
for(i = 0; i < datalen; i++) { |
tmpCRC += txd_buffer[i]; |
} |
tmpCRC %= 4096; |
txd_buffer[i++] = '=' + tmpCRC / 64; |
txd_buffer[i++] = '=' + tmpCRC % 64; |
txd_buffer[i++] = '\r'; |
txd_complete = FALSE; |
UDR0 = txd_buffer[0]; // initiates the transmittion (continued in the TXD ISR) |
uint16_t tmpCRC = 0, i; |
for (i = 0; i < datalen; i++) { |
tmpCRC += txd_buffer[i]; |
} |
tmpCRC %= 4096; |
txd_buffer[i++] = '=' + tmpCRC / 64; |
txd_buffer[i++] = '=' + tmpCRC % 64; |
txd_buffer[i++] = '\r'; |
txd_complete = FALSE; |
UDR0 = txd_buffer[0]; // initiates the transmittion (continued in the TXD ISR) |
} |
// -------------------------------------------------------------------------- |
331,393 → 332,428 |
// application example: |
// SendOutData('A', FC_ADDRESS, 2, (uint8_t *)&request_DebugLabel, sizeof(request_DebugLabel), label, 16); |
/* |
void SendOutData(uint8_t cmd, uint8_t addr, uint8_t numofbuffers, ...) { // uint8_t *pdata, uint8_t len, ... |
va_list ap; |
uint16_t txd_bufferIndex = 0; |
uint8_t *currentBuffer; |
uint8_t currentBufferIndex; |
uint16_t lengthOfCurrentBuffer; |
uint8_t shift = 0; |
txd_buffer[txd_bufferIndex++] = '#'; // Start character |
txd_buffer[txd_bufferIndex++] = 'a' + addr; // Address (a=0; b=1,...) |
txd_buffer[txd_bufferIndex++] = cmd; // Command |
va_start(ap, numofbuffers); |
void SendOutData(uint8_t cmd, uint8_t addr, uint8_t numofbuffers, ...) { // uint8_t *pdata, uint8_t len, ... |
va_list ap; |
uint16_t txd_bufferIndex = 0; |
uint8_t *currentBuffer; |
uint8_t currentBufferIndex; |
uint16_t lengthOfCurrentBuffer; |
uint8_t shift = 0; |
while(numofbuffers) { |
currentBuffer = va_arg(ap, uint8_t*); |
lengthOfCurrentBuffer = va_arg(ap, int); |
currentBufferIndex = 0; |
// Encode data: 3 bytes of data are encoded into 4 bytes, |
// where the 2 most significant bits are both 0. |
while(currentBufferIndex != lengthOfCurrentBuffer) { |
if (!shift) txd_buffer[txd_bufferIndex] = 0; |
txd_buffer[txd_bufferIndex] |= currentBuffer[currentBufferIndex] >> (shift + 2); |
txd_buffer[++txd_bufferIndex] = (currentBuffer[currentBufferIndex] << (4 - shift)) & 0b00111111; |
shift += 2; |
if (shift == 6) { shift=0; txd_bufferIndex++; } |
currentBufferIndex++; |
} |
} |
// If the number of data bytes was not divisible by 3, stuff |
// with 0 pseudodata until length is again divisible by 3. |
if (shift == 2) { |
// We need to stuff with zero bytes at the end. |
txd_buffer[txd_bufferIndex] &= 0b00110000; |
txd_buffer[++txd_bufferIndex] = 0; |
shift = 4; |
} |
if (shift == 4) { |
// We need to stuff with zero bytes at the end. |
txd_buffer[txd_bufferIndex++] &= 0b00111100; |
txd_buffer[txd_bufferIndex] = 0; |
} |
va_end(ap); |
AddCRC(pt); // add checksum after data block and initates the transmission |
} |
*/ |
txd_buffer[txd_bufferIndex++] = '#'; // Start character |
txd_buffer[txd_bufferIndex++] = 'a' + addr; // Address (a=0; b=1,...) |
txd_buffer[txd_bufferIndex++] = cmd; // Command |
va_start(ap, numofbuffers); |
while(numofbuffers) { |
currentBuffer = va_arg(ap, uint8_t*); |
lengthOfCurrentBuffer = va_arg(ap, int); |
currentBufferIndex = 0; |
// Encode data: 3 bytes of data are encoded into 4 bytes, |
// where the 2 most significant bits are both 0. |
while(currentBufferIndex != lengthOfCurrentBuffer) { |
if (!shift) txd_buffer[txd_bufferIndex] = 0; |
txd_buffer[txd_bufferIndex] |= currentBuffer[currentBufferIndex] >> (shift + 2); |
txd_buffer[++txd_bufferIndex] = (currentBuffer[currentBufferIndex] << (4 - shift)) & 0b00111111; |
shift += 2; |
if (shift == 6) { shift=0; txd_bufferIndex++; } |
currentBufferIndex++; |
} |
} |
// If the number of data bytes was not divisible by 3, stuff |
// with 0 pseudodata until length is again divisible by 3. |
if (shift == 2) { |
// We need to stuff with zero bytes at the end. |
txd_buffer[txd_bufferIndex] &= 0b00110000; |
txd_buffer[++txd_bufferIndex] = 0; |
shift = 4; |
} |
if (shift == 4) { |
// We need to stuff with zero bytes at the end. |
txd_buffer[txd_bufferIndex++] &= 0b00111100; |
txd_buffer[txd_bufferIndex] = 0; |
} |
va_end(ap); |
AddCRC(pt); // add checksum after data block and initates the transmission |
} |
*/ |
void SendOutData(uint8_t cmd, uint8_t addr, uint8_t numofbuffers, ...) { // uint8_t *pdata, uint8_t len, ... |
va_list ap; |
uint16_t pt = 0; |
uint8_t a,b,c; |
uint8_t ptr = 0; |
uint8_t *pdata = 0; |
int len = 0; |
txd_buffer[pt++] = '#'; // Start character |
txd_buffer[pt++] = 'a' + addr; // Address (a=0; b=1,...) |
txd_buffer[pt++] = cmd; // Command |
va_start(ap, numofbuffers); |
va_list ap; |
uint16_t pt = 0; |
uint8_t a, b, c; |
uint8_t ptr = 0; |
if(numofbuffers) { |
pdata = va_arg(ap, uint8_t*); |
len = va_arg(ap, int); |
ptr = 0; |
numofbuffers--; |
} |
uint8_t *pdata = 0; |
int len = 0; |
while(len){ |
if(len) { |
a = pdata[ptr++]; |
len--; |
if((!len) && numofbuffers) { |
pdata = va_arg(ap, uint8_t*); |
len = va_arg(ap, int); |
ptr = 0; |
numofbuffers--; |
} |
} |
else a = 0; |
if(len) { |
b = pdata[ptr++]; |
len--; |
if((!len) && numofbuffers) { |
pdata = va_arg(ap, uint8_t*); |
len = va_arg(ap, int); |
ptr = 0; |
numofbuffers--; |
} |
} else b = 0; |
if(len) { |
c = pdata[ptr++]; |
len--; |
if((!len) && numofbuffers) { |
pdata = va_arg(ap, uint8_t*); |
len = va_arg(ap, int); |
ptr = 0; |
numofbuffers--; |
} |
} |
else c = 0; |
txd_buffer[pt++] = '=' + (a >> 2); |
txd_buffer[pt++] = '=' + (((a & 0x03) << 4) | ((b & 0xf0) >> 4)); |
txd_buffer[pt++] = '=' + (((b & 0x0f) << 2) | ((c & 0xc0) >> 6)); |
txd_buffer[pt++] = '=' + ( c & 0x3f); |
} |
va_end(ap); |
AddCRC(pt); // add checksum after data block and initates the transmission |
txd_buffer[pt++] = '#'; // Start character |
txd_buffer[pt++] = 'a' + addr; // Address (a=0; b=1,...) |
txd_buffer[pt++] = cmd; // Command |
va_start(ap, numofbuffers); |
if (numofbuffers) { |
pdata = va_arg(ap, uint8_t*); |
len = va_arg(ap, int); |
ptr = 0; |
numofbuffers--; |
} |
while (len) { |
if (len) { |
a = pdata[ptr++]; |
len--; |
if ((!len) && numofbuffers) { |
pdata = va_arg(ap, uint8_t*); |
len = va_arg(ap, int); |
ptr = 0; |
numofbuffers--; |
} |
} else |
a = 0; |
if (len) { |
b = pdata[ptr++]; |
len--; |
if ((!len) && numofbuffers) { |
pdata = va_arg(ap, uint8_t*); |
len = va_arg(ap, int); |
ptr = 0; |
numofbuffers--; |
} |
} else |
b = 0; |
if (len) { |
c = pdata[ptr++]; |
len--; |
if ((!len) && numofbuffers) { |
pdata = va_arg(ap, uint8_t*); |
len = va_arg(ap, int); |
ptr = 0; |
numofbuffers--; |
} |
} else |
c = 0; |
txd_buffer[pt++] = '=' + (a >> 2); |
txd_buffer[pt++] = '=' + (((a & 0x03) << 4) | ((b & 0xf0) >> 4)); |
txd_buffer[pt++] = '=' + (((b & 0x0f) << 2) | ((c & 0xc0) >> 6)); |
txd_buffer[pt++] = '=' + (c & 0x3f); |
} |
va_end(ap); |
AddCRC(pt); // add checksum after data block and initates the transmission |
} |
// -------------------------------------------------------------------------- |
void Decode64(void) { |
uint8_t a,b,c,d; |
uint8_t x,y,z; |
uint8_t ptrIn = 3; |
uint8_t ptrOut = 3; |
uint8_t len = ReceivedBytes - 6; |
while(len) { |
a = rxd_buffer[ptrIn++] - '='; |
b = rxd_buffer[ptrIn++] - '='; |
c = rxd_buffer[ptrIn++] - '='; |
d = rxd_buffer[ptrIn++] - '='; |
//if(ptrIn > ReceivedBytes - 3) break; |
x = (a << 2) | (b >> 4); |
y = ((b & 0x0f) << 4) | (c >> 2); |
z = ((c & 0x03) << 6) | d; |
if(len--) rxd_buffer[ptrOut++] = x; else break; |
if(len--) rxd_buffer[ptrOut++] = y; else break; |
if(len--) rxd_buffer[ptrOut++] = z; else break; |
} |
pRxData = &rxd_buffer[3]; |
RxDataLen = ptrOut - 3; |
uint8_t a, b, c, d; |
uint8_t x, y, z; |
uint8_t ptrIn = 3; |
uint8_t ptrOut = 3; |
uint8_t len = ReceivedBytes - 6; |
while (len) { |
a = rxd_buffer[ptrIn++] - '='; |
b = rxd_buffer[ptrIn++] - '='; |
c = rxd_buffer[ptrIn++] - '='; |
d = rxd_buffer[ptrIn++] - '='; |
//if(ptrIn > ReceivedBytes - 3) break; |
x = (a << 2) | (b >> 4); |
y = ((b & 0x0f) << 4) | (c >> 2); |
z = ((c & 0x03) << 6) | d; |
if (len--) |
rxd_buffer[ptrOut++] = x; |
else |
break; |
if (len--) |
rxd_buffer[ptrOut++] = y; |
else |
break; |
if (len--) |
rxd_buffer[ptrOut++] = z; |
else |
break; |
} |
pRxData = &rxd_buffer[3]; |
RxDataLen = ptrOut - 3; |
} |
// -------------------------------------------------------------------------- |
void usart0_ProcessRxData(void) { |
// We control the motorTestActive var from here: Count it down. |
if (motorTestActive) motorTestActive--; |
// if data in the rxd buffer are not locked immediately return |
if(!rxd_buffer_locked) return; |
uint8_t tempchar1, tempchar2; |
Decode64(); // decode data block in rxd_buffer |
// We control the motorTestActive var from here: Count it down. |
if (motorTestActive) |
motorTestActive--; |
// if data in the rxd buffer are not locked immediately return |
if (!rxd_buffer_locked) |
return; |
uint8_t tempchar1, tempchar2; |
Decode64(); // decode data block in rxd_buffer |
switch(rxd_buffer[1] - 'a') { |
switch (rxd_buffer[1] - 'a') { |
case FC_ADDRESS: |
switch(rxd_buffer[2]) { |
case FC_ADDRESS: |
switch (rxd_buffer[2]) { |
#ifdef USE_MK3MAG |
case 'K':// compass value |
compassHeading = ((Heading_t *)pRxData)->Heading; |
compassOffCourse = ((540 + compassHeading - compassCourse) % 360) - 180; |
break; |
case 'K':// compass value |
compassHeading = ((Heading_t *)pRxData)->Heading; |
// compassOffCourse = ((540 + compassHeading - compassCourse) % 360) - 180; |
break; |
#endif |
case 't': // motor test |
if(RxDataLen > 20) { |
memcpy(&motorTest[0], (uint8_t*)pRxData, sizeof(motorTest)); |
} else { |
memcpy(&motorTest[0], (uint8_t*)pRxData, 4); |
} |
motorTestActive = 255; |
externalControlActive = 255; |
break; |
case 'n':// "Get Mixer Table |
while(!txd_complete); // wait for previous frame to be sent |
SendOutData('N', FC_ADDRESS, 1, (uint8_t *) &Mixer, sizeof(Mixer)); |
break; |
case 't': // motor test |
if (RxDataLen > 20) { |
memcpy(&motorTest[0], (uint8_t*) pRxData, sizeof(motorTest)); |
} else { |
memcpy(&motorTest[0], (uint8_t*) pRxData, 4); |
} |
motorTestActive = 255; |
externalControlActive = 255; |
break; |
case 'm':// "Set Mixer Table |
if(pRxData[0] == EEMIXER_REVISION) { |
memcpy(&Mixer, (uint8_t*)pRxData, sizeof(Mixer)); |
MixerTable_WriteToEEProm(); |
while(!txd_complete); // wait for previous frame to be sent |
tempchar1 = 1; |
} else { |
tempchar1 = 0; |
} |
SendOutData('M', FC_ADDRESS, 1, &tempchar1, 1); |
break; |
case 'n':// "Get Mixer Table |
while (!txd_complete) |
; // wait for previous frame to be sent |
SendOutData('N', FC_ADDRESS, 1, (uint8_t *) &Mixer, sizeof(Mixer)); |
break; |
case 'p': // get PPM channels |
request_PPMChannels = TRUE; |
break; |
case 'm':// "Set Mixer Table |
if (pRxData[0] == EEMIXER_REVISION) { |
memcpy(&Mixer, (uint8_t*) pRxData, sizeof(Mixer)); |
MixerTable_WriteToEEProm(); |
while (!txd_complete) |
; // wait for previous frame to be sent |
tempchar1 = 1; |
} else { |
tempchar1 = 0; |
} |
SendOutData('M', FC_ADDRESS, 1, &tempchar1, 1); |
break; |
case 'q':// request settings |
if(pRxData[0] == 0xFF) { |
pRxData[0] = GetParamByte(PID_ACTIVE_SET); |
} |
// limit settings range |
if(pRxData[0] < 1) pRxData[0] = 1; // limit to 1 |
else if(pRxData[0] > 5) pRxData[0] = 5; // limit to 5 |
// load requested parameter set |
ParamSet_ReadFromEEProm(pRxData[0]); |
tempchar1 = pRxData[0]; |
tempchar2 = EEPARAM_REVISION; |
while(!txd_complete); // wait for previous frame to be sent |
SendOutData('Q', FC_ADDRESS,3, &tempchar1, sizeof(tempchar1), &tempchar2, sizeof(tempchar2), (uint8_t *) &staticParams, sizeof(staticParams)); |
break; |
case 'p': // get PPM channels |
request_PPMChannels = TRUE; |
break; |
case 's': // save settings |
if(!(MKFlags & MKFLAG_MOTOR_RUN)) // save settings only if motors ar off |
{ |
if((1 <= pRxData[0]) && (pRxData[0] <= 5) && (pRxData[1] == EEPARAM_REVISION)) // check for setting to be in range and version of settings |
{ |
memcpy(&staticParams, (uint8_t*)&pRxData[2], sizeof(staticParams)); |
ParamSet_WriteToEEProm(pRxData[0]); |
/* |
TODO: Remove this encapsulation breach |
turnOver180Pitch = (int32_t) staticParams.AngleTurnOverPitch * 2500L; |
turnOver180Roll = (int32_t) staticParams.AngleTurnOverRoll * 2500L; |
*/ |
tempchar1 = getActiveParamSet(); |
beepNumber(tempchar1); |
} |
else |
{ |
tempchar1 = 0; //indicate bad data |
} |
while(!txd_complete); // wait for previous frame to be sent |
SendOutData('S', FC_ADDRESS,1, &tempchar1, sizeof(tempchar1)); |
} |
break; |
case 'q':// request settings |
if (pRxData[0] == 0xFF) { |
pRxData[0] = GetParamByte(PID_ACTIVE_SET); |
} |
// limit settings range |
if (pRxData[0] < 1) |
pRxData[0] = 1; // limit to 1 |
else if (pRxData[0] > 5) |
pRxData[0] = 5; // limit to 5 |
// load requested parameter set |
ParamSet_ReadFromEEProm(pRxData[0]); |
tempchar1 = pRxData[0]; |
tempchar2 = EEPARAM_REVISION; |
while (!txd_complete) |
; // wait for previous frame to be sent |
SendOutData('Q', FC_ADDRESS, 3, &tempchar1, sizeof(tempchar1), |
&tempchar2, sizeof(tempchar2), (uint8_t *) &staticParams, |
sizeof(staticParams)); |
break; |
default: |
//unsupported command received |
break; |
} // case FC_ADDRESS: |
case 's': // save settings |
if (!(MKFlags & MKFLAG_MOTOR_RUN)) // save settings only if motors are off |
{ |
if ((1 <= pRxData[0]) && (pRxData[0] <= 5) && (pRxData[1] |
== EEPARAM_REVISION)) // check for setting to be in range and version of settings |
{ |
memcpy(&staticParams, (uint8_t*) &pRxData[2], sizeof(staticParams)); |
ParamSet_WriteToEEProm(pRxData[0]); |
/* |
TODO: Remove this encapsulation breach |
turnOver180Pitch = (int32_t) staticParams.AngleTurnOverPitch * 2500L; |
turnOver180Roll = (int32_t) staticParams.AngleTurnOverRoll * 2500L; |
*/ |
tempchar1 = getActiveParamSet(); |
beepNumber(tempchar1); |
} else { |
tempchar1 = 0; //indicate bad data |
} |
while (!txd_complete) |
; // wait for previous frame to be sent |
SendOutData('S', FC_ADDRESS, 1, &tempchar1, sizeof(tempchar1)); |
} |
break; |
default: // any Slave Address |
switch(rxd_buffer[2]) { |
case 'a':// request for labels of the analog debug outputs |
request_DebugLabel = pRxData[0]; |
if(request_DebugLabel > 31) request_DebugLabel = 31; |
externalControlActive = 255; |
break; |
default: |
//unsupported command received |
break; |
} // case FC_ADDRESS: |
case 'b': // submit extern control |
memcpy(&externalControl, (uint8_t*)pRxData, sizeof(externalControl)); |
ConfirmFrame = externalControl.frame; |
externalControlActive = 255; |
break; |
default: // any Slave Address |
switch (rxd_buffer[2]) { |
case 'a':// request for labels of the analog debug outputs |
request_DebugLabel = pRxData[0]; |
if (request_DebugLabel > 31) |
request_DebugLabel = 31; |
externalControlActive = 255; |
break; |
case 'h':// request for display columns |
externalControlActive = 255; |
RemoteKeys |= pRxData[0]; |
if(RemoteKeys) DisplayLine = 0; |
request_Display = TRUE; |
break; |
case 'b': // submit extern control |
memcpy(&externalControl, (uint8_t*) pRxData, sizeof(externalControl)); |
ConfirmFrame = externalControl.frame; |
externalControlActive = 255; |
break; |
case 'l':// request for display columns |
externalControlActive = 255; |
MenuItem = pRxData[0]; |
request_Display1 = TRUE; |
break; |
case 'h':// request for display columns |
externalControlActive = 255; |
RemoteKeys |= pRxData[0]; |
if (RemoteKeys) |
DisplayLine = 0; |
request_Display = TRUE; |
break; |
case 'v': // request for version and board release |
request_VerInfo = TRUE; |
break; |
case 'l':// request for display columns |
externalControlActive = 255; |
MenuItem = pRxData[0]; |
request_Display1 = TRUE; |
break; |
case 'x': |
request_variables = TRUE; |
break; |
case 'v': // request for version and board release |
request_VerInfo = TRUE; |
break; |
case 'g':// get external control data |
request_ExternalControl = TRUE; |
break; |
case 'x': |
request_variables = TRUE; |
break; |
case 'd': // request for the debug data |
DebugData_Interval = (uint16_t) pRxData[0] * 10; |
if(DebugData_Interval > 0) request_DebugData = TRUE; |
break; |
case 'g':// get external control data |
request_ExternalControl = TRUE; |
break; |
case 'c': // request for the 3D data |
Data3D_Interval = (uint16_t) pRxData[0] * 10; |
if(Data3D_Interval > 0) request_Data3D = TRUE; |
break; |
case 'd': // request for the debug data |
DebugData_Interval = (uint16_t) pRxData[0] * 10; |
if (DebugData_Interval > 0) |
request_DebugData = TRUE; |
break; |
default: |
//unsupported command received |
break; |
} |
break; // default: |
} |
// unlock the rxd buffer after processing |
pRxData = 0; |
RxDataLen = 0; |
rxd_buffer_locked = FALSE; |
case 'c': // request for the 3D data |
Data3D_Interval = (uint16_t) pRxData[0] * 10; |
if (Data3D_Interval > 0) |
request_Data3D = TRUE; |
break; |
default: |
//unsupported command received |
break; |
} |
break; // default: |
} |
// unlock the rxd buffer after processing |
pRxData = 0; |
RxDataLen = 0; |
rxd_buffer_locked = FALSE; |
} |
/************************************************************************/ |
/* Routine für die Serielle Ausgabe */ |
/************************************************************************/ |
int16_t uart_putchar (int8_t c) { |
if (c == '\n') |
uart_putchar('\r'); |
// wait until previous character was send |
loop_until_bit_is_set(UCSR0A, UDRE0); |
// send character |
UDR0 = c; |
return (0); |
int16_t uart_putchar(int8_t c) { |
if (c == '\n') |
uart_putchar('\r'); |
// wait until previous character was send |
loop_until_bit_is_set(UCSR0A, UDRE0); |
// send character |
UDR0 = c; |
return (0); |
} |
//--------------------------------------------------------------------------------------------- |
void usart0_TransmitTxData(void) { |
if(!txd_complete) return; |
if (!txd_complete) |
return; |
if(request_VerInfo && txd_complete) { |
SendOutData('V', FC_ADDRESS, 1, (uint8_t *) &UART_VersionInfo, sizeof(UART_VersionInfo)); |
request_VerInfo = FALSE; |
} |
if(request_Display && txd_complete) { |
LCD_PrintMenu(); |
SendOutData('H', FC_ADDRESS, 2, &DisplayLine, sizeof(DisplayLine), &DisplayBuff[DisplayLine * 20], 20); |
DisplayLine++; |
if(DisplayLine >= 4) DisplayLine = 0; |
request_Display = FALSE; |
} |
if(request_Display1 && txd_complete) { |
LCD_PrintMenu(); |
SendOutData('L', FC_ADDRESS, 3, &MenuItem, sizeof(MenuItem), &MaxMenuItem, sizeof(MaxMenuItem), DisplayBuff, sizeof(DisplayBuff)); |
request_Display1 = FALSE; |
} |
if(request_DebugLabel != 0xFF) { // Texte für die Analogdaten |
uint8_t label[16]; // local sram buffer |
memcpy_P(label, ANALOG_LABEL[request_DebugLabel], 16); // read lable from flash to sram buffer |
SendOutData('A', FC_ADDRESS, 2, (uint8_t *) &request_DebugLabel, sizeof(request_DebugLabel), label, 16); |
request_DebugLabel = 0xFF; |
} |
if(ConfirmFrame && txd_complete) { // Datensatz ohne CRC bestätigen |
SendOutData('B', FC_ADDRESS, 1, (uint8_t*)&ConfirmFrame, sizeof(ConfirmFrame)); |
ConfirmFrame = 0; |
} |
if(((DebugData_Interval && CheckDelay(DebugData_Timer)) || request_DebugData) && txd_complete) { |
SendOutData('D', FC_ADDRESS, 1,(uint8_t *) &DebugOut, sizeof(DebugOut)); |
DebugData_Timer = SetDelay(DebugData_Interval); |
request_DebugData = FALSE; |
} |
if( ((Data3D_Interval && CheckDelay(Data3D_Timer)) || request_Data3D) && txd_complete) { |
SendOutData('C', FC_ADDRESS, 1,(uint8_t *) &Data3D, sizeof(Data3D)); |
Data3D.AngleNick = (int16_t)((10 * angle[PITCH]) / GYRO_DEG_FACTOR_PITCHROLL); // convert to multiple of 0.1° |
Data3D.AngleRoll = (int16_t)((10 * angle[ROLL]) / GYRO_DEG_FACTOR_PITCHROLL); // convert to multiple of 0.1° |
Data3D.Heading = (int16_t)((10 * yawGyroHeading) / GYRO_DEG_FACTOR_YAW); // convert to multiple of 0.1° |
Data3D_Timer = SetDelay(Data3D_Interval); |
request_Data3D = FALSE; |
} |
if (request_VerInfo && txd_complete) { |
SendOutData('V', FC_ADDRESS, 1, (uint8_t *) &UART_VersionInfo, |
sizeof(UART_VersionInfo)); |
request_VerInfo = FALSE; |
} |
if(request_ExternalControl && txd_complete) { |
SendOutData('G', FC_ADDRESS, 1,(uint8_t *) &externalControl, sizeof(externalControl)); |
request_ExternalControl = FALSE; |
} |
if (request_Display && txd_complete) { |
LCD_PrintMenu(); |
SendOutData('H', FC_ADDRESS, 2, &DisplayLine, sizeof(DisplayLine), |
&DisplayBuff[DisplayLine * 20], 20); |
DisplayLine++; |
if (DisplayLine >= 4) |
DisplayLine = 0; |
request_Display = FALSE; |
} |
if (request_Display1 && txd_complete) { |
LCD_PrintMenu(); |
SendOutData('L', FC_ADDRESS, 3, &MenuItem, sizeof(MenuItem), &MaxMenuItem, |
sizeof(MaxMenuItem), DisplayBuff, sizeof(DisplayBuff)); |
request_Display1 = FALSE; |
} |
if (request_DebugLabel != 0xFF) { // Texte für die Analogdaten |
uint8_t label[16]; // local sram buffer |
memcpy_P(label, ANALOG_LABEL[request_DebugLabel], 16); // read lable from flash to sram buffer |
SendOutData('A', FC_ADDRESS, 2, (uint8_t *) &request_DebugLabel, |
sizeof(request_DebugLabel), label, 16); |
request_DebugLabel = 0xFF; |
} |
if (ConfirmFrame && txd_complete) { // Datensatz ohne CRC bestätigen |
SendOutData('B', FC_ADDRESS, 1, (uint8_t*) &ConfirmFrame, |
sizeof(ConfirmFrame)); |
ConfirmFrame = 0; |
} |
if (((DebugData_Interval && CheckDelay(DebugData_Timer)) || request_DebugData) |
&& txd_complete) { |
SendOutData('D', FC_ADDRESS, 1, (uint8_t *) &DebugOut, sizeof(DebugOut)); |
DebugData_Timer = SetDelay(DebugData_Interval); |
request_DebugData = FALSE; |
} |
if (((Data3D_Interval && CheckDelay(Data3D_Timer)) || request_Data3D) |
&& txd_complete) { |
SendOutData('C', FC_ADDRESS, 1, (uint8_t *) &Data3D, sizeof(Data3D)); |
Data3D.AngleNick = (int16_t) ((10 * angle[PITCH]) |
/ GYRO_DEG_FACTOR_PITCHROLL); // convert to multiple of 0.1° |
Data3D.AngleRoll = (int16_t) ((10 * angle[ROLL]) |
/ GYRO_DEG_FACTOR_PITCHROLL); // convert to multiple of 0.1° |
Data3D.Heading = (int16_t) ((10 * yawGyroHeading) / GYRO_DEG_FACTOR_YAW); // convert to multiple of 0.1° |
Data3D_Timer = SetDelay(Data3D_Interval); |
request_Data3D = FALSE; |
} |
if (request_ExternalControl && txd_complete) { |
SendOutData('G', FC_ADDRESS, 1, (uint8_t *) &externalControl, |
sizeof(externalControl)); |
request_ExternalControl = FALSE; |
} |
#ifdef USE_MK3MAG |
if((CheckDelay(Compass_Timer)) && txd_complete) { |
ToMk3Mag.Attitude[0] = (int16_t)((10 * angle[PITCH]) / GYRO_DEG_FACTOR_PITCHROLL); // approx. 0.1 deg |
ToMk3Mag.Attitude[1] = (int16_t)((10 * angle[ROLL]) / GYRO_DEG_FACTOR_PITCHROLL); // approx. 0.1 deg |
ToMk3Mag.UserParam[0] = dynamicParams.UserParams[0]; |
ToMk3Mag.UserParam[1] = dynamicParams.UserParams[1]; |
ToMk3Mag.CalState = compassCalState; |
SendOutData('w', MK3MAG_ADDRESS, 1,(uint8_t *) &ToMk3Mag,sizeof(ToMk3Mag)); |
// the last state is 5 and should be send only once to avoid multiple flash writing |
if(compassCalState > 4) compassCalState = 0; |
Compass_Timer = SetDelay(99); |
} |
if((CheckDelay(Compass_Timer)) && txd_complete) { |
ToMk3Mag.Attitude[0] = (int16_t)((10 * angle[PITCH]) / GYRO_DEG_FACTOR_PITCHROLL); // approx. 0.1 deg |
ToMk3Mag.Attitude[1] = (int16_t)((10 * angle[ROLL]) / GYRO_DEG_FACTOR_PITCHROLL); // approx. 0.1 deg |
ToMk3Mag.UserParam[0] = dynamicParams.UserParams[0]; |
ToMk3Mag.UserParam[1] = dynamicParams.UserParams[1]; |
ToMk3Mag.CalState = compassCalState; |
SendOutData('w', MK3MAG_ADDRESS, 1,(uint8_t *) &ToMk3Mag,sizeof(ToMk3Mag)); |
// the last state is 5 and should be send only once to avoid multiple flash writing |
if(compassCalState > 4) compassCalState = 0; |
Compass_Timer = SetDelay(99); |
} |
#endif |
if(request_MotorTest && txd_complete) { |
SendOutData('T', FC_ADDRESS, 0); |
request_MotorTest = FALSE; |
} |
if(request_PPMChannels && txd_complete) { |
SendOutData('P', FC_ADDRESS, 1, (uint8_t *)&PPM_in, sizeof(PPM_in)); |
request_PPMChannels = FALSE; |
} |
if (request_MotorTest && txd_complete) { |
SendOutData('T', FC_ADDRESS, 0); |
request_MotorTest = FALSE; |
} |
if (request_variables && txd_complete) { |
SendOutData('X', FC_ADDRESS, 1, (uint8_t *)&variables, sizeof(variables)); |
request_variables = FALSE; |
} |
if (request_PPMChannels && txd_complete) { |
SendOutData('P', FC_ADDRESS, 1, (uint8_t *) &PPM_in, sizeof(PPM_in)); |
request_PPMChannels = FALSE; |
} |
if (request_variables && txd_complete) { |
SendOutData('X', FC_ADDRESS, 1, (uint8_t *) &variables, sizeof(variables)); |
request_variables = FALSE; |
} |
} |
/branches/dongfang_FC_rewrite/uart0.h |
---|
11,7 → 11,7 |
//Baud rate of the USART |
#define USART0_BAUD 57600 |
extern void usart0_Init (void); |
extern void usart0_Init(void); |
extern void usart0_TransmitTxData(void); |
extern void usart0_ProcessRxData(void); |
extern int16_t uart_putchar(int8_t c); |
22,26 → 22,26 |
extern uint8_t motorTest[16]; |
typedef struct { |
uint8_t Digital[2]; |
uint16_t Analog[32]; // Debugvalues |
} __attribute__((packed)) DebugOut_t; |
uint8_t Digital[2]; |
uint16_t Analog[32]; // Debugvalues |
}__attribute__((packed)) DebugOut_t; |
extern DebugOut_t DebugOut; |
typedef struct { |
int16_t AngleNick; // in 0.1 deg |
int16_t AngleRoll; // in 0.1 deg |
int16_t Heading; // in 0.1 deg |
uint8_t reserve[8]; |
} __attribute__((packed)) Data3D_t; |
int16_t AngleNick; // in 0.1 deg |
int16_t AngleRoll; // in 0.1 deg |
int16_t Heading; // in 0.1 deg |
uint8_t reserve[8]; |
}__attribute__((packed)) Data3D_t; |
typedef struct { |
uint8_t SWMajor; |
uint8_t SWMinor; |
uint8_t ProtoMajor; |
uint8_t ProtoMinor; |
uint8_t SWPatch; |
uint8_t Reserved[5]; |
} __attribute__((packed)) UART_VersionInfo_t; |
uint8_t SWMajor; |
uint8_t SWMinor; |
uint8_t ProtoMajor; |
uint8_t ProtoMinor; |
uint8_t SWPatch; |
uint8_t Reserved[5]; |
}__attribute__((packed)) UART_VersionInfo_t; |
#endif //_UART0_H |
/branches/dongfang_FC_rewrite/uart1.c |
---|
69,10 → 69,10 |
/****************************************************************/ |
/* Initialization of the USART1 */ |
/****************************************************************/ |
void usart1_Init (void) { |
void usart1_Init(void) { |
// USART1 Control and Status Register A, B, C and baud rate register |
uint8_t sreg = SREG; |
uint16_t ubrr = (uint16_t) ((uint32_t) SYSCLK/(8 * USART1_BAUD) - 1); |
uint16_t ubrr = (uint16_t) ((uint32_t) SYSCLK / (8 * USART1_BAUD) - 1); |
// disable all interrupts before reconfiguration |
cli(); |
91,12 → 91,12 |
// set TXD1 (PD3) as an output pin |
PORTD |= (1 << PORTD3); |
DDRD |= (1 << DDD3); |
DDRD |= (1 << DDD3); |
// USART0 Baud Rate Register |
// set clock divider |
UBRR1H = (uint8_t)(ubrr>>8); |
UBRR1L = (uint8_t)ubrr; |
UBRR1H = (uint8_t) (ubrr >> 8); |
UBRR1L = (uint8_t) ubrr; |
// enable double speed operation |
UCSR1A |= (1 << U2X1); |
112,11 → 112,12 |
UCSR1C &= ~(1 << USBS1); |
// 8-bit |
UCSR1B &= ~(1 << UCSZ12); |
UCSR1C |= (1 << UCSZ11); |
UCSR1C |= (1 << UCSZ10); |
UCSR1C |= (1 << UCSZ11); |
UCSR1C |= (1 << UCSZ10); |
// flush receive buffer explicit |
while ( UCSR1A & (1<<RXC1) ) UDR1; |
while (UCSR1A & (1 << RXC1)) |
UDR1; |
// enable interrupts at the end |
// enable RX-Interrupt |
127,7 → 128,7 |
//UCSR1B |= (1 << UDRIE1); |
// restore global interrupt flags |
SREG = sreg; |
SREG = sreg; |
} |
/****************************************************************/ |
134,25 → 135,26 |
/* USART1 data register empty ISR */ |
/****************************************************************/ |
/*ISR(USART1_UDRE_vect) { |
} |
*/ |
} |
*/ |
/****************************************************************/ |
/* USART1 transmitter ISR */ |
/****************************************************************/ |
/*ISR(USART1_TX_vect) { |
} |
*/ |
} |
*/ |
/****************************************************************/ |
/* USART1 receiver ISR */ |
/****************************************************************/ |
ISR(USART1_RX_vect) { |
ISR(USART1_RX_vect) |
{ |
uint8_t c; |
c = UDR1; // get data byte |
#ifdef USE_RC_DSL |
dsl_parser(c); // parse dsl data stream |
#endif |
#ifdef USE_RC_SPECTRUM |
spectrum_parser(c); // parse spectrum data stream |
#endif |
#ifdef USE_RC_DSL |
dsl_parser(c); // parse dsl data stream |
#endif |
#ifdef USE_RC_SPECTRUM |
spectrum_parser(c); // parse spectrum data stream |
#endif |
} |
/branches/dongfang_FC_rewrite/uart1.h |
---|
1,6 → 1,6 |
#ifndef _UART1_H |
#define _UART1_H |
extern void usart1_Init (void); |
extern void usart1_Init(void); |
#endif //_UART1_H |
/branches/dongfang_FC_rewrite |
---|
Property changes: |
Modified: svn:ignore |
*.map |
*.sym |
.project |
+.externalToolBuilders |
+.settings |
+.cproject |
+old files.zip |