initial version

This commit is contained in:
rusefi 2014-04-22 17:13:46 -05:00
commit aadb01cf6d
258 changed files with 26303 additions and 0 deletions

305
firmware/.cproject Normal file
View File

@ -0,0 +1,305 @@
<?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="org.eclipse.cdt.cross.arm.gnu.sourcery.windows.elf.debug.1943399423">
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="org.eclipse.cdt.cross.arm.gnu.sourcery.windows.elf.debug.1943399423" moduleId="org.eclipse.cdt.core.settings" name="Debug">
<externalSettings/>
<extensions>
<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.MakeErrorParser" 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"/>
<extension id="org.eclipse.cdt.core.GNU_ELF" point="org.eclipse.cdt.core.BinaryParser"/>
</extensions>
</storageModule>
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
<configuration artifactName="rusefi" buildArtefactType="org.eclipse.cdt.cross.arm.gnu.buildArtefactType.application" buildProperties="org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.debug,org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.cross.arm.gnu.buildArtefactType.application" description="" id="org.eclipse.cdt.cross.arm.gnu.sourcery.windows.elf.debug.1943399423" name="Debug" parent="org.eclipse.cdt.cross.arm.gnu.sourcery.windows.elf.debug">
<folderInfo id="org.eclipse.cdt.cross.arm.gnu.sourcery.windows.elf.debug.1943399423." name="/" resourcePath="">
<toolChain id="org.eclipse.cdt.cross.arm.gnu.sourcery.windows.elf.toolchain.debug.747823419" name="ARM Windows GCC (Sourcery G++ Lite)" superClass="org.eclipse.cdt.cross.arm.gnu.sourcery.windows.elf.toolchain.debug">
<option id="org.eclipse.cdt.cross.arm.gnu.sourcery.windows.option.debugging.level.2128888061" name="Debug level" superClass="org.eclipse.cdt.cross.arm.gnu.sourcery.windows.option.debugging.level" value="org.eclipse.cdt.cross.arm.gnu.base.option.debugging.level.max" valueType="enumerated"/>
<option id="org.eclipse.cdt.cross.arm.gnu.sourcery.windows.option.addtools.createlisting.1809317580" name="Create Extended Listing" superClass="org.eclipse.cdt.cross.arm.gnu.sourcery.windows.option.addtools.createlisting" value="false" valueType="boolean"/>
<targetPlatform id="org.eclipse.cdt.cross.arm.gnu.sourcery.windows.elf.platform.debug.568472866" isAbstract="false" name="Windows Platform" superClass="org.eclipse.cdt.cross.arm.gnu.sourcery.windows.elf.platform.debug"/>
<builder buildPath="${workspace_loc:/chibios_template/Debug}" id="org.eclipse.cdt.cross.arm.gnu.sourcery.windows.elf.builder.debug.479710089" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="ARM Sourcery Windows GNU Make builder" parallelBuildOn="true" parallelizationNumber="optimal" superClass="org.eclipse.cdt.cross.arm.gnu.sourcery.windows.elf.builder.debug"/>
<tool id="org.eclipse.cdt.cross.arm.gnu.sourcery.windows.elf.assembler.debug.1465123421" name="ARM Sourcery Windows GCC Assembler" superClass="org.eclipse.cdt.cross.arm.gnu.sourcery.windows.elf.assembler.debug">
<inputType id="org.eclipse.cdt.cross.arm.gnu.sourcery.windows.assembler.base.input.1266531692" superClass="org.eclipse.cdt.cross.arm.gnu.sourcery.windows.assembler.base.input"/>
</tool>
<tool id="org.eclipse.cdt.cross.arm.gnu.sourcery.windows.elf.c.compiler.debug.1498722775" name="ARM Sourcery Windows GCC C Compiler" superClass="org.eclipse.cdt.cross.arm.gnu.sourcery.windows.elf.c.compiler.debug">
<option id="org.eclipse.cdt.cross.arm.gnu.c.compiler.option.optimization.level.1147268579" name="Optimization level" superClass="org.eclipse.cdt.cross.arm.gnu.c.compiler.option.optimization.level" value="org.eclipse.cdt.cross.arm.gnu.base.option.optimization.level.optimize" valueType="enumerated"/>
<option id="org.eclipse.cdt.cross.arm.gnu.c.compiler.option.include.paths.395281450" name="Include paths (-I)" superClass="org.eclipse.cdt.cross.arm.gnu.c.compiler.option.include.paths" valueType="includePath">
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/hw_layer/serial_over_usb}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/hw_layer/lcd}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/ext}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/ext_algo}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/chibios/os/various}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/hw_layer/algo}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/util}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/console}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/console/tunerstudio}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/config}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/config/engines}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/config/boards}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/controllers}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/controllers/algo}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/controllers/trigger}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/controllers/sensors}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/controllers/system}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/controllers/math}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/console_util}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/emulation}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/emulation/hw_layer}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/hw_layer}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/hw_layer/flash}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/russianefi}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/russianefi/algo}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/russianefi/ckp}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/russianefi/adc}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/config/system}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/splib}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/chibios/boards/ST_STM32F4_DISCOVERY}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/chibios/os/hal/platforms/STM32/TIMv1}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/chibios/os/hal/platforms/STM32/I2Cv1}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/chibios/os/hal/platforms/STM32}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/chibios/os/hal/platforms/STM32/RTCv2}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/chibios/os/hal/platforms/STM32/OTGv1}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/chibios/os/hal/platforms/STM32/GPIOv2}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/chibios/os/hal/platforms/STM32F4xx}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/chibios/os/hal/src}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/chibios/os/hal/include}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/chibios/os/kernel/include}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/chibios/os/ports/GCC/ARMCMx}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/chibios/os/ports/GCC/ARMCMx/STM32F4xx}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/chibios/os/ports/common/ARMCMx}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/chibios/os/hal/platforms/STM32/SPIv1}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/chibios/os/hal/platforms/STM32/USARTv1}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/chibios/os/ports/common/ARMCMx/CMSIS/include}&quot;"/>
</option>
<option id="org.eclipse.cdt.cross.arm.gnu.c.compiler.option.other.otherflags.720321025" name="Other flags" superClass="org.eclipse.cdt.cross.arm.gnu.c.compiler.option.other.otherflags" value="-fgnu89-inline -c -fmessage-length=0 -Werror=type-limits -Werror-implicit-function-declaration -Werror -Wno-error=pointer-sign -Wno-error=unused-function -Wno-error=unused-variable" valueType="string"/>
<option id="org.eclipse.cdt.cross.arm.gnu.c.compiler.option.misc.std.32943169" name="Language Standard" superClass="org.eclipse.cdt.cross.arm.gnu.c.compiler.option.misc.std" value="org.eclipse.cdt.cross.arm.gnu.c.compiler.option.misc.std.gnu99" valueType="enumerated"/>
<option id="org.eclipse.cdt.cross.arm.gnu.c.compiler.option.preprocessor.def.1323722868" name="Defined symbols (-D)" superClass="org.eclipse.cdt.cross.arm.gnu.c.compiler.option.preprocessor.def" valueType="definedSymbols">
<listOptionValue builtIn="false" value="CORTEX_USE_FPU=TRUE"/>
</option>
<option id="org.eclipse.cdt.cross.arm.gnu.c.compiler.option.optimization.flags.368011225" name="Other optimization flags" superClass="org.eclipse.cdt.cross.arm.gnu.c.compiler.option.optimization.flags" value="-mcpu=cortex-m4 -mfloat-abi=softfp -mfpu=fpv4-sp-d16 -fsingle-precision-constant" valueType="string"/>
<inputType id="org.eclipse.cdt.cross.arm.gnu.sourcery.windows.c.compiler.base.input.250064833" superClass="org.eclipse.cdt.cross.arm.gnu.sourcery.windows.c.compiler.base.input"/>
</tool>
<tool id="org.eclipse.cdt.cross.arm.gnu.sourcery.windows.elf.cpp.compiler.debug.866330458" name="ARM Sourcery Windows GCC C++ Compiler" superClass="org.eclipse.cdt.cross.arm.gnu.sourcery.windows.elf.cpp.compiler.debug">
<option id="org.eclipse.cdt.cross.arm.gnu.cpp.compiler.option.optimization.level.1285714959" name="Optimization level" superClass="org.eclipse.cdt.cross.arm.gnu.cpp.compiler.option.optimization.level" value="org.eclipse.cdt.cross.arm.gnu.base.option.optimization.level.none" valueType="enumerated"/>
<option id="org.eclipse.cdt.cross.arm.gnu.cpp.compiler.option.include.paths.356693673" name="Include paths (-I)" superClass="org.eclipse.cdt.cross.arm.gnu.cpp.compiler.option.include.paths" valueType="includePath">
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/hw_layer/serial_over_usb}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/hw_layer/lcd}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/ext}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/ext_algo}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/chibios/os/various}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/hw_layer/algo}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/util}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/console}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/console/tunerstudio}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/config}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/config/engines}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/config/boards}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/controllers}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/controllers/algo}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/controllers/trigger}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/controllers/sensors}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/controllers/system}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/controllers/math}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/console_util}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/emulation}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/emulation/hw_layer}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/hw_layer}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/hw_layer/flash}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/russianefi}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/russianefi/algo}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/russianefi/ckp}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/russianefi/adc}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/config/system}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/splib}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/chibios/boards/ST_STM32F4_DISCOVERY}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/chibios/os/hal/platforms/STM32/TIMv1}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/chibios/os/hal/platforms/STM32/I2Cv1}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/chibios/os/hal/platforms/STM32}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/chibios/os/hal/platforms/STM32/RTCv2}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/chibios/os/hal/platforms/STM32/OTGv1}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/chibios/os/hal/platforms/STM32/GPIOv2}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/chibios/os/hal/platforms/STM32F4xx}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/chibios/os/hal/src}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/chibios/os/hal/include}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/chibios/os/kernel/include}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/chibios/os/ports/GCC/ARMCMx}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/chibios/os/ports/GCC/ARMCMx/STM32F4xx}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/chibios/os/ports/common/ARMCMx}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/chibios/os/hal/platforms/STM32/SPIv1}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/chibios/os/hal/platforms/STM32/USARTv1}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/chibios/os/ports/common/ARMCMx/CMSIS/include}&quot;"/>
</option>
<inputType id="org.eclipse.cdt.cross.arm.gnu.sourcery.windows.cpp.compiler.base.input.1939416167" superClass="org.eclipse.cdt.cross.arm.gnu.sourcery.windows.cpp.compiler.base.input"/>
</tool>
<tool id="org.eclipse.cdt.cross.arm.gnu.sourcery.windows.elf.c.linker.debug.369587711" name="ARM Sourcery Windows GCC C Linker" superClass="org.eclipse.cdt.cross.arm.gnu.sourcery.windows.elf.c.linker.debug"/>
<tool id="org.eclipse.cdt.cross.arm.gnu.sourcery.windows.elf.cpp.linker.debug.790854990" name="ARM Sourcery Windows GCC C++ Linker" superClass="org.eclipse.cdt.cross.arm.gnu.sourcery.windows.elf.cpp.linker.debug">
<option id="org.eclipse.cdt.cross.arm.gnu.cpp.link.option.gcsections.1692062869" name="Remove unused sections (-Xlinker --gc-sections)" superClass="org.eclipse.cdt.cross.arm.gnu.cpp.link.option.gcsections" value="true" valueType="boolean"/>
<option id="org.eclipse.cdt.cross.arm.gnu.cpp.link.option.scriptfile.1659638949" name="Script file (-T)" superClass="org.eclipse.cdt.cross.arm.gnu.cpp.link.option.scriptfile" value="${workspace_loc}\\${ProjName}\config\system\STM32F407xG_CCM.ld" valueType="string"/>
<option id="org.eclipse.cdt.cross.arm.gnu.cpp.link.option.libs.266038076" name="Libraries (-l)" superClass="org.eclipse.cdt.cross.arm.gnu.cpp.link.option.libs"/>
<option id="org.eclipse.cdt.cross.arm.gnu.cpp.link.option.paths.1546594065" name="Library search path (-L)" superClass="org.eclipse.cdt.cross.arm.gnu.cpp.link.option.paths"/>
<inputType id="org.eclipse.cdt.cross.arm.gnu.cpp.linker.input.214430349" superClass="org.eclipse.cdt.cross.arm.gnu.cpp.linker.input">
<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
<additionalInput kind="additionalinput" paths="$(LIBS)"/>
</inputType>
</tool>
<tool id="org.eclipse.cdt.cross.arm.gnu.sourcery.windows.archiver.base.99249388" name="ARM Sourcery Windows GCC Archiver" superClass="org.eclipse.cdt.cross.arm.gnu.sourcery.windows.archiver.base"/>
<tool id="org.eclipse.cdt.cross.arm.gnu.sourcery.windows.elf.createflash.debug.283274370" name="ARM Sourcery Windows GNU Create Flash Image" superClass="org.eclipse.cdt.cross.arm.gnu.sourcery.windows.elf.createflash.debug"/>
<tool id="org.eclipse.cdt.cross.arm.gnu.sourcery.windows.elf.createlisting.debug.104214053" name="ARM Sourcery Windows GNU Create Listing" superClass="org.eclipse.cdt.cross.arm.gnu.sourcery.windows.elf.createlisting.debug"/>
<tool id="org.eclipse.cdt.cross.arm.gnu.sourcery.windows.elf.printsize.debug.1812095247" name="ARM Sourcery Windows GNU Print Size" superClass="org.eclipse.cdt.cross.arm.gnu.sourcery.windows.elf.printsize.debug"/>
</toolChain>
</folderInfo>
<sourceEntries>
<entry excluding="chibios/boards/simulator|chibios/os/ports/GCC/SIMIA32|chibios/os/hal/platforms/Win32|chibios/boards/OLIMEX_STM32_E407" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name=""/>
</sourceEntries>
</configuration>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
</cconfiguration>
<cconfiguration id="org.eclipse.cdt.cross.arm.gnu.sourcery.windows.elf.release.1422617130">
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="org.eclipse.cdt.cross.arm.gnu.sourcery.windows.elf.release.1422617130" moduleId="org.eclipse.cdt.core.settings" name="Release">
<externalSettings/>
<extensions>
<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.MakeErrorParser" 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"/>
<extension id="org.eclipse.cdt.core.GNU_ELF" point="org.eclipse.cdt.core.BinaryParser"/>
</extensions>
</storageModule>
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
<configuration artifactName="rusefi" buildArtefactType="org.eclipse.cdt.cross.arm.gnu.buildArtefactType.application" buildProperties="org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.release,org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.cross.arm.gnu.buildArtefactType.application" description="" id="org.eclipse.cdt.cross.arm.gnu.sourcery.windows.elf.release.1422617130" name="Release" parent="org.eclipse.cdt.cross.arm.gnu.sourcery.windows.elf.release">
<folderInfo id="org.eclipse.cdt.cross.arm.gnu.sourcery.windows.elf.release.1422617130." name="/" resourcePath="">
<toolChain id="org.eclipse.cdt.cross.arm.gnu.sourcery.windows.elf.toolchain.release.614122032" name="ARM Windows GCC (Sourcery G++ Lite)" superClass="org.eclipse.cdt.cross.arm.gnu.sourcery.windows.elf.toolchain.release">
<option id="org.eclipse.cdt.cross.arm.gnu.sourcery.windows.option.debugging.level.447783356" name="Debug level" superClass="org.eclipse.cdt.cross.arm.gnu.sourcery.windows.option.debugging.level" value="org.eclipse.cdt.cross.arm.gnu.base.option.debugging.level.none" valueType="enumerated"/>
<targetPlatform id="org.eclipse.cdt.cross.arm.gnu.sourcery.windows.elf.platform.release.1559197737" isAbstract="false" name="Windows Platform" superClass="org.eclipse.cdt.cross.arm.gnu.sourcery.windows.elf.platform.release"/>
<builder buildPath="${workspace_loc:/chibios_template/Release}" id="org.eclipse.cdt.cross.arm.gnu.sourcery.windows.elf.builder.release.845491162" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="ARM Sourcery Windows GNU Make builder" parallelBuildOn="true" parallelizationNumber="optimal" superClass="org.eclipse.cdt.cross.arm.gnu.sourcery.windows.elf.builder.release"/>
<tool id="org.eclipse.cdt.cross.arm.gnu.sourcery.windows.elf.assembler.release.1527944975" name="ARM Sourcery Windows GCC Assembler" superClass="org.eclipse.cdt.cross.arm.gnu.sourcery.windows.elf.assembler.release">
<inputType id="org.eclipse.cdt.cross.arm.gnu.sourcery.windows.assembler.base.input.1359572999" superClass="org.eclipse.cdt.cross.arm.gnu.sourcery.windows.assembler.base.input"/>
</tool>
<tool id="org.eclipse.cdt.cross.arm.gnu.sourcery.windows.elf.c.compiler.release.431693497" name="ARM Sourcery Windows GCC C Compiler" superClass="org.eclipse.cdt.cross.arm.gnu.sourcery.windows.elf.c.compiler.release">
<option id="org.eclipse.cdt.cross.arm.gnu.c.compiler.option.optimization.level.329705686" name="Optimization level" superClass="org.eclipse.cdt.cross.arm.gnu.c.compiler.option.optimization.level" value="org.eclipse.cdt.cross.arm.gnu.base.option.optimization.level.size" valueType="enumerated"/>
<option id="org.eclipse.cdt.cross.arm.gnu.c.compiler.option.include.paths.1664205045" name="Include paths (-I)" superClass="org.eclipse.cdt.cross.arm.gnu.c.compiler.option.include.paths" valueType="includePath">
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/controllers/system}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/console/algo}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/hw_layer/algo}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/controllers/algo}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/util}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/config}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/config/engines}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/config/boards}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/config/system}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/console}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/console_util}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/controllers}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/controllers/math}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/controllers/sensors}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/emulation}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/emulation/hw_layer}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/hw_layer}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/linked/controllers}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/linked/controllers/math}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/russianefi}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/russianefi/algo}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/russianefi/ckp}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/russianefi/adc}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/splib}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/chibios/boards/ST_STM32F4_DISCOVERY}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/chibios/os/hal/platforms/STM32}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/chibios/os/various}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/chibios/os/hal/platforms/STM32/OTGv1}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/chibios/os/hal/platforms/STM32/GPIOv2}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/chibios/os/hal/platforms/STM32F4xx}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/chibios/os/hal/src}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/chibios/os/kernel/include}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/chibios/os/hal/include}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/chibios/os/hal/platforms/STM32/SPIv1}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/chibios/os/hal/platforms/STM32/TIMv1}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/chibios/os/hal/platforms/STM32/USARTv1}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/chibios/os/ports/GCC/ARMCMx}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/chibios/os/ports/GCC/ARMCMx/STM32F4xx}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/chibios/os/ports/common/ARMCMx}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/chibios/os/ports/common/ARMCMx/CMSIS/include}&quot;"/>
</option>
<option id="org.eclipse.cdt.cross.arm.gnu.c.compiler.option.optimization.flags.536959381" name="Other optimization flags" superClass="org.eclipse.cdt.cross.arm.gnu.c.compiler.option.optimization.flags" value="-mcpu=cortex-m4 -mfloat-abi=softfp -mfpu=fpv4-sp-d16 -fsingle-precision-constant" valueType="string"/>
<option id="org.eclipse.cdt.cross.arm.gnu.c.compiler.option.other.otherflags.1251184343" name="Other flags" superClass="org.eclipse.cdt.cross.arm.gnu.c.compiler.option.other.otherflags" value="-c -fmessage-length=0 -Werror-implicit-function-declaration" valueType="string"/>
<option id="org.eclipse.cdt.cross.arm.gnu.c.compiler.option.misc.std.1869635512" name="Language Standard" superClass="org.eclipse.cdt.cross.arm.gnu.c.compiler.option.misc.std" value="org.eclipse.cdt.cross.arm.gnu.c.compiler.option.misc.std.gnu99" valueType="enumerated"/>
<option id="org.eclipse.cdt.cross.arm.gnu.c.compiler.option.preprocessor.def.2018981424" name="Defined symbols (-D)" superClass="org.eclipse.cdt.cross.arm.gnu.c.compiler.option.preprocessor.def" valueType="definedSymbols">
<listOptionValue builtIn="false" value="CORTEX_USE_FPU=TRUE"/>
</option>
<option id="org.eclipse.cdt.cross.arm.gnu.c.compiler.option.other.verbose.342060604" name="Verbose (-v)" superClass="org.eclipse.cdt.cross.arm.gnu.c.compiler.option.other.verbose" value="false" valueType="boolean"/>
<inputType id="org.eclipse.cdt.cross.arm.gnu.sourcery.windows.c.compiler.base.input.1479270851" superClass="org.eclipse.cdt.cross.arm.gnu.sourcery.windows.c.compiler.base.input"/>
</tool>
<tool id="org.eclipse.cdt.cross.arm.gnu.sourcery.windows.elf.cpp.compiler.release.487461954" name="ARM Sourcery Windows GCC C++ Compiler" superClass="org.eclipse.cdt.cross.arm.gnu.sourcery.windows.elf.cpp.compiler.release">
<option id="org.eclipse.cdt.cross.arm.gnu.cpp.compiler.option.optimization.level.74521503" name="Optimization level" superClass="org.eclipse.cdt.cross.arm.gnu.cpp.compiler.option.optimization.level" value="org.eclipse.cdt.cross.arm.gnu.base.option.optimization.level.size" valueType="enumerated"/>
<option id="org.eclipse.cdt.cross.arm.gnu.cpp.compiler.option.other.verbose.1350766121" name="Verbose (-v)" superClass="org.eclipse.cdt.cross.arm.gnu.cpp.compiler.option.other.verbose" value="false" valueType="boolean"/>
<inputType id="org.eclipse.cdt.cross.arm.gnu.sourcery.windows.cpp.compiler.base.input.815685204" superClass="org.eclipse.cdt.cross.arm.gnu.sourcery.windows.cpp.compiler.base.input"/>
</tool>
<tool id="org.eclipse.cdt.cross.arm.gnu.sourcery.windows.elf.c.linker.release.1692652942" name="ARM Sourcery Windows GCC C Linker" superClass="org.eclipse.cdt.cross.arm.gnu.sourcery.windows.elf.c.linker.release"/>
<tool id="org.eclipse.cdt.cross.arm.gnu.sourcery.windows.elf.cpp.linker.release.1996687940" name="ARM Sourcery Windows GCC C++ Linker" superClass="org.eclipse.cdt.cross.arm.gnu.sourcery.windows.elf.cpp.linker.release">
<option id="org.eclipse.cdt.cross.arm.gnu.cpp.link.option.gcsections.317072174" name="Remove unused sections (-Xlinker --gc-sections)" superClass="org.eclipse.cdt.cross.arm.gnu.cpp.link.option.gcsections" value="true" valueType="boolean"/>
<option id="org.eclipse.cdt.cross.arm.gnu.cpp.link.option.scriptfile.1008873450" name="Script file (-T)" superClass="org.eclipse.cdt.cross.arm.gnu.cpp.link.option.scriptfile" value="${workspace_loc}\\${ProjName}\config\system\STM32F407xG_CCM.ld" valueType="string"/>
<option id="org.eclipse.cdt.cross.arm.gnu.cpp.link.option.libs.855505987" name="Libraries (-l)" superClass="org.eclipse.cdt.cross.arm.gnu.cpp.link.option.libs"/>
<option id="org.eclipse.cdt.cross.arm.gnu.cpp.link.option.paths.1314593101" name="Library search path (-L)" superClass="org.eclipse.cdt.cross.arm.gnu.cpp.link.option.paths"/>
<inputType id="org.eclipse.cdt.cross.arm.gnu.cpp.linker.input.253018751" superClass="org.eclipse.cdt.cross.arm.gnu.cpp.linker.input">
<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
<additionalInput kind="additionalinput" paths="$(LIBS)"/>
</inputType>
</tool>
<tool id="org.eclipse.cdt.cross.arm.gnu.sourcery.windows.archiver.base.1966213403" name="ARM Sourcery Windows GCC Archiver" superClass="org.eclipse.cdt.cross.arm.gnu.sourcery.windows.archiver.base"/>
<tool id="org.eclipse.cdt.cross.arm.gnu.sourcery.windows.elf.createflash.release.966302019" name="ARM Sourcery Windows GNU Create Flash Image" superClass="org.eclipse.cdt.cross.arm.gnu.sourcery.windows.elf.createflash.release"/>
<tool id="org.eclipse.cdt.cross.arm.gnu.sourcery.windows.elf.createlisting.release.881059662" name="ARM Sourcery Windows GNU Create Listing" superClass="org.eclipse.cdt.cross.arm.gnu.sourcery.windows.elf.createlisting.release"/>
<tool id="org.eclipse.cdt.cross.arm.gnu.sourcery.windows.elf.printsize.release.1131501965" name="ARM Sourcery Windows GNU Print Size" superClass="org.eclipse.cdt.cross.arm.gnu.sourcery.windows.elf.printsize.release"/>
</toolChain>
</folderInfo>
<sourceEntries>
<entry excluding="chibios/boards/simulator|chibios/os/ports/GCC/SIMIA32|chibios/os/hal/platforms/Win32|chibios/boards/OLIMEX_STM32_E407" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name=""/>
</sourceEntries>
</configuration>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
</cconfiguration>
</storageModule>
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
<project id="chibios_template.org.eclipse.cdt.cross.arm.gnu.sourcery.windows.elf.391826329" name="ARM Cross Target Application" projectType="org.eclipse.cdt.cross.arm.gnu.sourcery.windows.elf"/>
</storageModule>
<storageModule moduleId="scannerConfiguration">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
<scannerConfigBuildInfo instanceId="org.eclipse.cdt.cross.arm.gnu.sourcery.windows.elf.release.1422617130;org.eclipse.cdt.cross.arm.gnu.sourcery.windows.elf.release.1422617130.;org.eclipse.cdt.cross.arm.gnu.sourcery.windows.elf.c.compiler.release.431693497;org.eclipse.cdt.cross.arm.gnu.sourcery.windows.c.compiler.base.input.1479270851">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="org.eclipse.cdt.cross.arm.gnu.ARM_CS_GCCWinManagedMakePerProjectProfileC"/>
</scannerConfigBuildInfo>
<scannerConfigBuildInfo instanceId="org.eclipse.cdt.cross.arm.gnu.sourcery.windows.elf.debug.1943399423;org.eclipse.cdt.cross.arm.gnu.sourcery.windows.elf.debug.1943399423.;org.eclipse.cdt.cross.arm.gnu.sourcery.windows.elf.assembler.debug.1465123421;org.eclipse.cdt.cross.arm.gnu.sourcery.windows.assembler.base.input.1266531692">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="org.eclipse.cdt.cross.arm.gnu.ARM_CS_GCCWinManagedMakePerProjectProfileC"/>
</scannerConfigBuildInfo>
<scannerConfigBuildInfo instanceId="org.eclipse.cdt.cross.arm.gnu.sourcery.windows.elf.debug.1943399423;org.eclipse.cdt.cross.arm.gnu.sourcery.windows.elf.debug.1943399423.;org.eclipse.cdt.cross.arm.gnu.sourcery.windows.elf.cpp.compiler.debug.866330458;org.eclipse.cdt.cross.arm.gnu.sourcery.windows.cpp.compiler.base.input.1939416167">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="org.eclipse.cdt.cross.arm.gnu.ARM_CS_GCCWinManagedMakePerProjectProfileCPP"/>
</scannerConfigBuildInfo>
<scannerConfigBuildInfo instanceId="org.eclipse.cdt.cross.arm.gnu.sourcery.windows.elf.release.1422617130;org.eclipse.cdt.cross.arm.gnu.sourcery.windows.elf.release.1422617130.;org.eclipse.cdt.cross.arm.gnu.sourcery.windows.elf.cpp.compiler.release.487461954;org.eclipse.cdt.cross.arm.gnu.sourcery.windows.cpp.compiler.base.input.815685204">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="org.eclipse.cdt.cross.arm.gnu.ARM_CS_GCCWinManagedMakePerProjectProfileCPP"/>
</scannerConfigBuildInfo>
<scannerConfigBuildInfo instanceId="org.eclipse.cdt.cross.arm.gnu.sourcery.windows.elf.debug.1943399423;org.eclipse.cdt.cross.arm.gnu.sourcery.windows.elf.debug.1943399423.;org.eclipse.cdt.cross.arm.gnu.sourcery.windows.elf.c.compiler.debug.1498722775;org.eclipse.cdt.cross.arm.gnu.sourcery.windows.c.compiler.base.input.250064833">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="org.eclipse.cdt.cross.arm.gnu.ARM_CS_GCCWinManagedMakePerProjectProfileC"/>
</scannerConfigBuildInfo>
<scannerConfigBuildInfo instanceId="org.eclipse.cdt.cross.arm.gnu.sourcery.windows.elf.release.1422617130;org.eclipse.cdt.cross.arm.gnu.sourcery.windows.elf.release.1422617130.;org.eclipse.cdt.cross.arm.gnu.sourcery.windows.elf.assembler.release.1527944975;org.eclipse.cdt.cross.arm.gnu.sourcery.windows.assembler.base.input.1359572999">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="org.eclipse.cdt.cross.arm.gnu.ARM_CS_GCCWinManagedMakePerProjectProfileC"/>
</scannerConfigBuildInfo>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>
<storageModule moduleId="refreshScope" versionNumber="2">
<configuration configurationName="Release">
<resource resourceType="PROJECT" workspacePath="/firmware"/>
</configuration>
<configuration configurationName="Debug">
<resource resourceType="PROJECT" workspacePath="/firmware"/>
</configuration>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.internal.ui.text.commentOwnerProjectMappings"/>
</cproject>

47
firmware/.project Normal file
View File

@ -0,0 +1,47 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>chibios_template</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name>
<triggers>clean,full,incremental,</triggers>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name>
<triggers>full,incremental,</triggers>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.cdt.core.cnature</nature>
<nature>org.eclipse.cdt.core.ccnature</nature>
<nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
<nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
</natures>
<filteredResources>
<filter>
<id>1381697360903</id>
<name></name>
<type>10</type>
<matcher>
<id>org.eclipse.ui.ide.multiFilter</id>
<arguments>1.0-name-matches-false-false-iar</arguments>
</matcher>
</filter>
<filter>
<id>1381675425786</id>
<name>chibios/os/ports</name>
<type>10</type>
<matcher>
<id>org.eclipse.ui.ide.multiFilter</id>
<arguments>1.0-name-matches-false-false-IAR</arguments>
</matcher>
</filter>
</filteredResources>
</projectDescription>

2316
firmware/Doxyfile Normal file

File diff suppressed because it is too large Load Diff

194
firmware/DoxygenLayout.xml Normal file
View File

@ -0,0 +1,194 @@
<doxygenlayout version="1.0">
<!-- Generated by doxygen 1.8.5 -->
<!-- Navigation index tabs for HTML output -->
<navindex>
<tab type="mainpage" visible="yes" title=""/>
<tab type="pages" visible="yes" title="" intro=""/>
<tab type="modules" visible="yes" title="" intro=""/>
<tab type="namespaces" visible="yes" title="">
<tab type="namespacelist" visible="yes" title="" intro=""/>
<tab type="namespacemembers" visible="yes" title="" intro=""/>
</tab>
<tab type="classes" visible="yes" title="">
<tab type="classlist" visible="yes" title="" intro=""/>
<tab type="classindex" visible="$ALPHABETICAL_INDEX" title=""/>
<tab type="hierarchy" visible="yes" title="" intro=""/>
<tab type="classmembers" visible="yes" title="" intro=""/>
</tab>
<tab type="files" visible="yes" title="">
<tab type="filelist" visible="yes" title="" intro=""/>
<tab type="globals" visible="yes" title="" intro=""/>
</tab>
<tab type="examples" visible="yes" title="" intro=""/>
</navindex>
<!-- Layout definition for a class page -->
<class>
<briefdescription visible="yes"/>
<includes visible="$SHOW_INCLUDE_FILES"/>
<inheritancegraph visible="$CLASS_GRAPH"/>
<collaborationgraph visible="$COLLABORATION_GRAPH"/>
<memberdecl>
<nestedclasses visible="yes" title=""/>
<publictypes title=""/>
<services title=""/>
<interfaces title=""/>
<publicslots title=""/>
<signals title=""/>
<publicmethods title=""/>
<publicstaticmethods title=""/>
<publicattributes title=""/>
<publicstaticattributes title=""/>
<protectedtypes title=""/>
<protectedslots title=""/>
<protectedmethods title=""/>
<protectedstaticmethods title=""/>
<protectedattributes title=""/>
<protectedstaticattributes title=""/>
<packagetypes title=""/>
<packagemethods title=""/>
<packagestaticmethods title=""/>
<packageattributes title=""/>
<packagestaticattributes title=""/>
<properties title=""/>
<events title=""/>
<privatetypes title=""/>
<privateslots title=""/>
<privatemethods title=""/>
<privatestaticmethods title=""/>
<privateattributes title=""/>
<privatestaticattributes title=""/>
<friends title=""/>
<related title="" subtitle=""/>
<membergroups visible="yes"/>
</memberdecl>
<detaileddescription title=""/>
<memberdef>
<inlineclasses title=""/>
<typedefs title=""/>
<enums title=""/>
<services title=""/>
<interfaces title=""/>
<constructors title=""/>
<functions title=""/>
<related title=""/>
<variables title=""/>
<properties title=""/>
<events title=""/>
</memberdef>
<allmemberslink visible="yes"/>
<usedfiles visible="$SHOW_USED_FILES"/>
<authorsection visible="yes"/>
</class>
<!-- Layout definition for a namespace page -->
<namespace>
<briefdescription visible="yes"/>
<memberdecl>
<nestednamespaces visible="yes" title=""/>
<constantgroups visible="yes" title=""/>
<classes visible="yes" title=""/>
<typedefs title=""/>
<enums title=""/>
<functions title=""/>
<variables title=""/>
<membergroups visible="yes"/>
</memberdecl>
<detaileddescription title=""/>
<memberdef>
<inlineclasses title=""/>
<typedefs title=""/>
<enums title=""/>
<functions title=""/>
<variables title=""/>
</memberdef>
<authorsection visible="yes"/>
</namespace>
<!-- Layout definition for a file page -->
<file>
<briefdescription visible="no"/>
<detaileddescription title=""/>
<memberdecl>
<classes visible="yes" title=""/>
<namespaces visible="yes" title=""/>
<constantgroups visible="yes" title=""/>
<defines title=""/>
<typedefs title=""/>
<enums title=""/>
<functions title=""/>
<variables title=""/>
<membergroups visible="yes"/>
</memberdecl>
<memberdef>
<inlineclasses title=""/>
<defines title=""/>
<typedefs title=""/>
<enums title=""/>
<functions title=""/>
<variables title=""/>
</memberdef>
<includes visible="$SHOW_INCLUDE_FILES"/>
<includegraph visible="$INCLUDE_GRAPH"/>
<includedbygraph visible="$INCLUDED_BY_GRAPH"/>
<sourcelink visible="yes"/>
<authorsection/>
</file>
<!-- Layout definition for a group page -->
<group>
<briefdescription visible="yes"/>
<groupgraph visible="$GROUP_GRAPHS"/>
<memberdecl>
<nestedgroups visible="yes" title=""/>
<dirs visible="yes" title=""/>
<files visible="yes" title=""/>
<namespaces visible="yes" title=""/>
<classes visible="yes" title=""/>
<defines title=""/>
<typedefs title=""/>
<enums title=""/>
<enumvalues title=""/>
<functions title=""/>
<variables title=""/>
<signals title=""/>
<publicslots title=""/>
<protectedslots title=""/>
<privateslots title=""/>
<events title=""/>
<properties title=""/>
<friends title=""/>
<membergroups visible="yes"/>
</memberdecl>
<detaileddescription title=""/>
<memberdef>
<pagedocs/>
<inlineclasses title=""/>
<defines title=""/>
<typedefs title=""/>
<enums title=""/>
<enumvalues title=""/>
<functions title=""/>
<variables title=""/>
<signals title=""/>
<publicslots title=""/>
<protectedslots title=""/>
<privateslots title=""/>
<events title=""/>
<properties title=""/>
<friends title=""/>
</memberdef>
<authorsection visible="yes"/>
</group>
<!-- Layout definition for a directory page -->
<directory>
<briefdescription visible="yes"/>
<directorygraph visible="yes"/>
<memberdecl>
<dirs visible="yes"/>
<files visible="yes"/>
</memberdecl>
<detaileddescription title=""/>
</directory>
</doxygenlayout>

298
firmware/Makefile Normal file
View File

@ -0,0 +1,298 @@
##############################################################################
# Build global options
# NOTE: Can be overridden externally.
#
PROJECT_DIR = .
CHIBIOS = chibios
# Compiler options here.
ifeq ($(USE_OPT),)
USE_OPT = $(RFLAGS) -O1 -fgnu89-inline -ggdb -fomit-frame-pointer -falign-functions=16 -std=gnu99 -Werror-implicit-function-declaration -Werror -Wno-error=pointer-sign -Wno-error=unused-function -Wno-error=unused-variable -Wno-error=sign-compare -Wno-error=unused-parameter -Wno-error=missing-field-initializers
endif
# C specific options here (added to USE_OPT).
ifeq ($(USE_COPT),)
USE_COPT =
endif
# C++ specific options here (added to USE_OPT).
ifeq ($(USE_CPPOPT),)
USE_CPPOPT = -fno-rtti -fno-exceptions -fno-use-cxa-atexit
endif
# Enable this if you want the linker to remove unused code and data
ifeq ($(USE_LINK_GC),)
USE_LINK_GC = yes
endif
# If enabled, this option allows to compile the application in THUMB mode.
ifeq ($(USE_THUMB),)
USE_THUMB = yes
endif
# Enable this if you want to see the full log while compiling.
ifeq ($(USE_VERBOSE_COMPILE),)
USE_VERBOSE_COMPILE = no
endif
#
# Build global options
##############################################################################
##############################################################################
# Architecture or project specific options
#
USE_FPU = yes
# Enables the use of FPU on Cortex-M4.
# Enable this if you really want to use the STM FWLib.
ifeq ($(USE_FPU),)
USE_FPU = no
endif
# Enable this if you really want to use the STM FWLib.
ifeq ($(USE_FWLIB),)
USE_FWLIB = no
endif
# List all default C defines here, like -D_DEBUG=1
DDEFS =
#
# Architecture or project specific options
##############################################################################
##############################################################################
# Project, sources and paths
#
# Define project name here
PROJECT = rusefi
#PROJECT_BOARD = OLIMEX_STM32_E407
ifneq ($(PROJECT_BOARD),OLIMEX_STM32_E407)
PROJECT_BOARD = ST_STM32F4_DISCOVERY
endif
DDEFS += -D$(PROJECT_BOARD)
# Imported source files and paths
include $(CHIBIOS)/boards/$(PROJECT_BOARD)/board.mk
include $(CHIBIOS)/os/hal/platforms/STM32F4xx/platform.mk
include $(CHIBIOS)/os/hal/hal.mk
include $(CHIBIOS)/os/ports/GCC/ARMCMx/STM32F4xx/port.mk
include $(CHIBIOS)/os/kernel/kernel.mk
include $(CHIBIOS)/os/various/cpp_wrappers/kernel.mk
include $(CHIBIOS)/os/various/fatfs_bindings/fatfs.mk
include console/tunerstudio/tunerstudio.mk
include ext/ext.mk
include hw_layer/hw_layer.mk
include emulation/emulation.mk
include controllers/controllers.mk
include $(PROJECT_DIR)/util/util.mk
include $(PROJECT_DIR)/config/engines/engines.mk
include $(PROJECT_DIR)/controllers/algo/algo.mk
include $(PROJECT_DIR)/controllers/math/math.mk
include $(PROJECT_DIR)/controllers/sensors/sensors.mk
include $(PROJECT_DIR)/controllers/system/system.mk
include $(PROJECT_DIR)/controllers/trigger/trigger.mk
include $(PROJECT_DIR)/console/console.mk
include $(PROJECT_DIR)/console_util/console_util.mk
# Define linker script file here
LDSCRIPT= config/system/STM32F407xG_CCM.ld
#LDSCRIPT= $(PORTLD)/STM32F407xG_CCM.ld
# C sources that can be compiled in ARM or THUMB mode depending on the global
# setting.
CSRC = $(PORTSRC) \
$(KERNSRC) \
$(VARIOUSSRC) \
chibios/os/various/chprintf.c \
chibios/os/various/memstreams.c \
chibios/os/various/chrtclib.c \
$(UTILSRC) \
$(ENGINES_SRC) \
$(CONSOLESRC) \
$(TUNERSTUDIOSRC) \
$(CONSOLEUTILSRC) \
$(HALSRC) \
$(EMULATIONSRC) \
$(HW_LAYERESRC) \
$(CONTROLLERSSRC) \
$(CONTROLLERS_ALGO_SRC) \
$(CONTROLLERS_MATH_SRC) \
$(CONTROLLERS_SENSORS_SRC) \
$(PLATFORMSRC) \
$(BOARDSRC) \
$(FATFSSRC) \
$(TRIGGERSRC) \
$(SYSTEMSRC)
# C++ sources that can be compiled in ARM or THUMB mode depending on the global
# setting.
CPPSRC = $(CHCPPSRC) \
$(CONTROLLERSSRC_CPP) \
$(EMULATIONSRC_CPP) \
$(CONTROLLERS_ALGO_SRC_CPP) \
$(SYSTEMSRC_CPP) \
$(ENGINES_SRC_CPP) \
$(UTILSRC_CPP) \
rusefi.cpp \
main.cpp
# C sources to be compiled in ARM mode regardless of the global setting.
# NOTE: Mixing ARM and THUMB mode enables the -mthumb-interwork compiler
# option that results in lower performance and larger code size.
ACSRC =
# C++ sources to be compiled in ARM mode regardless of the global setting.
# NOTE: Mixing ARM and THUMB mode enables the -mthumb-interwork compiler
# option that results in lower performance and larger code size.
ACPPSRC =
# C sources to be compiled in THUMB mode regardless of the global setting.
# NOTE: Mixing ARM and THUMB mode enables the -mthumb-interwork compiler
# option that results in lower performance and larger code size.
TCSRC =
# C sources to be compiled in THUMB mode regardless of the global setting.
# NOTE: Mixing ARM and THUMB mode enables the -mthumb-interwork compiler
# option that results in lower performance and larger code size.
TCPPSRC =
# List ASM source files here
ASMSRC = $(PORTASM)
INCDIR = $(PORTINC) $(KERNINC) $(TESTINC) \
$(HALINC) $(PLATFORMINC) $(BOARDINC) \
$(CHCPPINC) \
$(CHIBIOS)/os/various \
config/system \
config/engines \
config/boards \
config \
chibios/os/various \
ext \
ext_algo \
util \
console_util \
console \
console/tunerstudio \
hw_layer \
hw_layer/serial_over_usb \
hw_layer/algo \
hw_layer/lcd \
emulation/hw_layer \
emulation \
controllers \
controllers/sensors \
controllers/system \
controllers/algo \
controllers/math \
controllers/trigger
#
# Project, sources and paths
##############################################################################
##############################################################################
# Compiler settings
#
MCU = cortex-m4
#TRGT = arm-elf-
TRGT = arm-none-eabi-
CC = $(TRGT)gcc
CPPC = $(TRGT)g++
# Enable loading with g++ only if you need C++ runtime support.
# NOTE: You can use C++ even without C++ support if you are careful. C++
# runtime support makes code size explode.
#LD = $(TRGT)gcc
LD = $(TRGT)g++
CP = $(TRGT)objcopy
AS = $(TRGT)gcc -x assembler-with-cpp
OD = $(TRGT)objdump
HEX = $(CP) -O ihex
BIN = $(CP) -O binary
# ARM-specific options here
AOPT =
# THUMB-specific options here
TOPT = -mthumb -DTHUMB
# Define C warning options here
CWARN = -Wall -Wextra -Wstrict-prototypes
# Define C++ warning options here
CPPWARN = -Wall -Wextra
#
# Compiler settings
##############################################################################
##############################################################################
# Start of default section
#
# List all default ASM defines here, like -D_DEBUG=1
DADEFS =
# List all default directories to look for include files here
DINCDIR =
# List the default directory to look for the libraries here
DLIBDIR =
# List all default libraries here
DLIBS =
#
# End of default section
##############################################################################
##############################################################################
# Start of user section
#
# List all user C define here, like -D_DEBUG=1
UDEFS =
# Define ASM defines here
UADEFS =
# List all user directories here
UINCDIR =
# List the user directory to look for the libraries here
ULIBDIR =
# List all user libraries here
ULIBS = -lm
#
# End of user defines
##############################################################################
ifeq ($(USE_FPU),yes)
USE_OPT += -mfloat-abi=softfp -mfpu=fpv4-sp-d16 -fsingle-precision-constant
DDEFS += -DCORTEX_USE_FPU=TRUE
else
DDEFS += -DCORTEX_USE_FPU=FALSE
endif
ifeq ($(USE_FWLIB),yes)
include $(CHIBIOS)/ext/stm32lib/stm32lib.mk
CSRC += $(STM32SRC)
INCDIR += $(STM32INC)
USE_OPT += -DUSE_STDPERIPH_DRIVER
endif
include $(CHIBIOS)/os/ports/GCC/ARMCMx/rules.mk

172
firmware/chibios/file.lst Normal file
View File

@ -0,0 +1,172 @@
os/hal/hal.mk
os/hal/include/adc.h
os/hal/include/can.h
os/hal/include/ext.h
os/hal/include/gpt.h
os/hal/include/hal.h
os/hal/include/i2c.h
os/hal/include/icu.h
os/hal/include/io_block.h
os/hal/include/io_channel.h
os/hal/include/mac.h
os/hal/include/mii.h
os/hal/include/mmcsd.h
os/hal/include/mmc_spi.h
os/hal/include/pal.h
os/hal/include/pwm.h
os/hal/include/rtc.h
os/hal/include/sdc.h
os/hal/include/serial.h
os/hal/include/serial_usb.h
os/hal/include/spi.h
os/hal/include/tm.h
os/hal/include/uart.h
os/hal/include/usb.h
os/hal/platforms/STM32/can_lld.c
os/hal/platforms/STM32/can_lld.h
os/hal/platforms/STM32/ext_lld.c
os/hal/platforms/STM32/ext_lld.h
os/hal/platforms/STM32/GPIOv2/pal_lld.c
os/hal/platforms/STM32/GPIOv2/pal_lld.h
os/hal/platforms/STM32/i2s_lld.c
os/hal/platforms/STM32/i2s_lld.h
os/hal/platforms/STM32/mac_lld.c
os/hal/platforms/STM32/mac_lld.h
os/hal/platforms/STM32/OTGv1/stm32_otg.h
os/hal/platforms/STM32/OTGv1/usb_lld.c
os/hal/platforms/STM32/OTGv1/usb_lld.h
os/hal/platforms/STM32/RTCv2/rtc_lld.c
os/hal/platforms/STM32/RTCv2/rtc_lld.h
os/hal/platforms/STM32/sdc_lld.c
os/hal/platforms/STM32/sdc_lld.h
os/hal/platforms/STM32/SPIv1/spi_lld.c
os/hal/platforms/STM32/SPIv1/spi_lld.h
os/hal/platforms/STM32/stm32.h
os/hal/platforms/STM32/TIMv1/gpt_lld.c
os/hal/platforms/STM32/TIMv1/gpt_lld.h
os/hal/platforms/STM32/TIMv1/icu_lld.c
os/hal/platforms/STM32/TIMv1/icu_lld.h
os/hal/platforms/STM32/TIMv1/pwm_lld.c
os/hal/platforms/STM32/TIMv1/pwm_lld.h
os/hal/platforms/STM32/TIMv1/stm32_tim.h
os/hal/platforms/STM32/USARTv1/serial_lld.c
os/hal/platforms/STM32/USARTv1/serial_lld.h
os/hal/platforms/STM32/USARTv1/uart_lld.c
os/hal/platforms/STM32/USARTv1/uart_lld.h
os/hal/platforms/STM32F4xx/adc_lld.c
os/hal/platforms/STM32F4xx/adc_lld.h
os/hal/platforms/STM32F4xx/ext_lld_isr.c
os/hal/platforms/STM32F4xx/ext_lld_isr.h
os/hal/platforms/STM32F4xx/hal_lld.c
os/hal/platforms/STM32F4xx/hal_lld.h
os/hal/platforms/STM32F4xx/platform.dox
os/hal/platforms/STM32F4xx/platform.mk
os/hal/platforms/STM32F4xx/stm32f2xx.h
os/hal/platforms/STM32F4xx/stm32f4xx.h
os/hal/platforms/STM32F4xx/stm32_dma.c
os/hal/platforms/STM32F4xx/stm32_dma.h
os/hal/platforms/STM32F4xx/stm32_isr.h
os/hal/platforms/STM32F4xx/stm32_rcc.h
os/hal/src/adc.c
os/hal/src/can.c
os/hal/src/ext.c
os/hal/src/gpt.c
os/hal/src/hal.c
os/hal/src/i2c.c
os/hal/src/icu.c
os/hal/src/mac.c
os/hal/src/mmcsd.c
os/hal/src/mmc_spi.c
os/hal/src/pal.c
os/hal/src/pwm.c
os/hal/src/rtc.c
os/hal/src/sdc.c
os/hal/src/serial.c
os/hal/src/serial_usb.c
os/hal/src/spi.c
os/hal/src/tm.c
os/hal/src/uart.c
os/hal/src/usb.c
os/kernel/include/ch.h
os/kernel/include/chbsem.h
os/kernel/include/chcond.h
os/kernel/include/chdebug.h
os/kernel/include/chdynamic.h
os/kernel/include/chevents.h
os/kernel/include/chfiles.h
os/kernel/include/chheap.h
os/kernel/include/chinline.h
os/kernel/include/chlists.h
os/kernel/include/chmboxes.h
os/kernel/include/chmemcore.h
os/kernel/include/chmempools.h
os/kernel/include/chmsg.h
os/kernel/include/chmtx.h
os/kernel/include/chqueues.h
os/kernel/include/chregistry.h
os/kernel/include/chschd.h
os/kernel/include/chsem.h
os/kernel/include/chstreams.h
os/kernel/include/chsys.h
os/kernel/include/chthreads.h
os/kernel/include/chvt.h
os/kernel/kernel.mk
os/kernel/src/chcond.c
os/kernel/src/chdebug.c
os/kernel/src/chdynamic.c
os/kernel/src/chevents.c
os/kernel/src/chheap.c
os/kernel/src/chlists.c
os/kernel/src/chmboxes.c
os/kernel/src/chmemcore.c
os/kernel/src/chmempools.c
os/kernel/src/chmsg.c
os/kernel/src/chmtx.c
os/kernel/src/chqueues.c
os/kernel/src/chregistry.c
os/kernel/src/chschd.c
os/kernel/src/chsem.c
os/kernel/src/chsys.c
os/kernel/src/chthreads.c
os/kernel/src/chvt.c
os/ports/common/ARMCMx/CMSIS/include/arm_common_tables.h
os/ports/common/ARMCMx/CMSIS/include/arm_math.h
os/ports/common/ARMCMx/CMSIS/include/core_cm0.h
os/ports/common/ARMCMx/CMSIS/include/core_cm0plus.h
os/ports/common/ARMCMx/CMSIS/include/core_cm3.h
os/ports/common/ARMCMx/CMSIS/include/core_cm4.h
os/ports/common/ARMCMx/CMSIS/include/core_cm4_simd.h
os/ports/common/ARMCMx/CMSIS/include/core_cmFunc.h
os/ports/common/ARMCMx/CMSIS/include/core_cmInstr.h
os/ports/common/ARMCMx/CMSIS/readme.txt
os/ports/common/ARMCMx/nvic.c
os/ports/common/ARMCMx/nvic.h
os/ports/GCC/ARMCMx/chcore.c
os/ports/GCC/ARMCMx/chcore.h
os/ports/GCC/ARMCMx/chcore_v7m.c
os/ports/GCC/ARMCMx/chcore_v7m.h
os/ports/GCC/ARMCMx/chtypes.h
os/ports/GCC/ARMCMx/crt0.c
os/ports/GCC/ARMCMx/rules.mk
os/ports/GCC/ARMCMx/STM32F4xx/cmparams.h
os/ports/GCC/ARMCMx/STM32F4xx/port.mk
os/ports/GCC/ARMCMx/STM32F4xx/vectors.c
os/ports/IAR/ARMCMx/chcore.c
os/ports/IAR/ARMCMx/chcore.h
os/ports/IAR/ARMCMx/chcoreasm_v6m.s
os/ports/IAR/ARMCMx/chcoreasm_v7m.s
os/ports/IAR/ARMCMx/chcore_v6m.c
os/ports/IAR/ARMCMx/chcore_v6m.h
os/ports/IAR/ARMCMx/chcore_v7m.c
os/ports/IAR/ARMCMx/chcore_v7m.h
os/ports/IAR/ARMCMx/chtypes.h
os/ports/IAR/ARMCMx/cstartup.s
os/ports/IAR/ARMCMx/STM32F4xx/cmparams.h
os/ports/IAR/ARMCMx/STM32F4xx/vectors.s
os/various/chprintf.c
os/various/chprintf.h
os/various/fatfs_diskio.c
os/various/fatfs_syscall.c
os/various/memstreams.c
os/various/memstreams.h
os/various/various.mk

View File

@ -0,0 +1,216 @@
Index: chibios/os/kernel/include/chdebug.h
===================================================================
--- chibios/os/kernel/include/chdebug.h (revision 1050)
+++ chibios/os/kernel/include/chdebug.h (revision 1051)
@@ -162,7 +162,7 @@
#if !defined(chDbgCheck)
#define chDbgCheck(c, func) { \
if (!(c)) \
- chDbgPanic(__QUOTE_THIS(func)"()"); \
+ chDbgPanic(__QUOTE_THIS(func)"()", __FILE__, __LINE__); \
}
#endif /* !defined(chDbgCheck) */
/** @} */
@@ -201,7 +201,7 @@
#if !defined(chDbgAssert)
#define chDbgAssert(c, m, r) { \
if (!(c)) \
- chDbgPanic(m); \
+ chDbgPanic(m, __FILE__, __LINE__); \
}
#endif /* !defined(chDbgAssert) */
/** @} */
@@ -243,7 +243,7 @@
#endif
#if CH_DBG_ENABLED
extern const char *dbg_panic_msg;
- void chDbgPanic(const char *msg);
+ void chDbgPanic(const char *msg, char * file, int line);
#endif
#ifdef __cplusplus
}
Index: chibios/os/kernel/src/chdebug.c
===================================================================
--- chibios/os/kernel/src/chdebug.c (revision 1050)
+++ chibios/os/kernel/src/chdebug.c (revision 1051)
@@ -81,7 +81,7 @@
void dbg_check_disable(void) {
if ((dbg_isr_cnt != 0) || (dbg_lock_cnt != 0))
- chDbgPanic("SV#1");
+ chDbgPanic("SV#1", __FILE__, __LINE__);
}
/**
@@ -92,7 +92,7 @@
void dbg_check_suspend(void) {
if ((dbg_isr_cnt != 0) || (dbg_lock_cnt != 0))
- chDbgPanic("SV#2");
+ chDbgPanic("SV#2", __FILE__, __LINE__);
}
/**
@@ -103,7 +103,7 @@
void dbg_check_enable(void) {
if ((dbg_isr_cnt != 0) || (dbg_lock_cnt != 0))
- chDbgPanic("SV#3");
+ chDbgPanic("SV#3", __FILE__, __LINE__);
}
/**
@@ -114,7 +114,7 @@
void dbg_check_lock(void) {
if ((dbg_isr_cnt != 0) || (dbg_lock_cnt != 0))
- chDbgPanic("SV#4");
+ chDbgPanic("SV#4 misplaced chSysLock()", __FILE__, __LINE__);
dbg_enter_lock();
}
@@ -126,7 +126,7 @@
void dbg_check_unlock(void) {
if ((dbg_isr_cnt != 0) || (dbg_lock_cnt <= 0))
- chDbgPanic("SV#5");
+ chDbgPanic("SV#5", __FILE__, __LINE__);
dbg_leave_lock();
}
@@ -138,7 +138,7 @@
void dbg_check_lock_from_isr(void) {
if ((dbg_isr_cnt <= 0) || (dbg_lock_cnt != 0))
- chDbgPanic("SV#6");
+ chDbgPanic("SV#6", __FILE__, __LINE__);
dbg_enter_lock();
}
@@ -150,7 +150,7 @@
void dbg_check_unlock_from_isr(void) {
if ((dbg_isr_cnt <= 0) || (dbg_lock_cnt <= 0))
- chDbgPanic("SV#7");
+ chDbgPanic("SV#7", __FILE__, __LINE__);
dbg_leave_lock();
}
@@ -163,7 +163,7 @@
port_lock_from_isr();
if ((dbg_isr_cnt < 0) || (dbg_lock_cnt != 0))
- chDbgPanic("SV#8");
+ chDbgPanic("SV#8", __FILE__, __LINE__);
dbg_isr_cnt++;
port_unlock_from_isr();
}
@@ -177,7 +177,7 @@
port_lock_from_isr();
if ((dbg_isr_cnt <= 0) || (dbg_lock_cnt != 0))
- chDbgPanic("SV#9");
+ chDbgPanic("SV#9", __FILE__, __LINE__);
dbg_isr_cnt--;
port_unlock_from_isr();
}
@@ -193,7 +193,7 @@
void chDbgCheckClassI(void) {
if ((dbg_isr_cnt < 0) || (dbg_lock_cnt <= 0))
- chDbgPanic("SV#10");
+ chDbgPanic("SV#10 misplaced I-class function", __FILE__, __LINE__);
}
/**
@@ -207,7 +207,7 @@
void chDbgCheckClassS(void) {
if ((dbg_isr_cnt != 0) || (dbg_lock_cnt <= 0))
- chDbgPanic("SV#11");
+ chDbgPanic("SV#11", __FILE__, __LINE__);
}
#endif /* CH_DBG_SYSTEM_STATE_CHECK */
@@ -262,16 +262,24 @@
* written once and then the system is halted.
*/
const char *dbg_panic_msg;
+char *dbg_panic_file;
+int dbg_panic_line;
/**
* @brief Prints a panic message on the console and then halts the system.
*
* @param[in] msg the pointer to the panic message string
*/
-void chDbgPanic(const char *msg) {
-
+void chDbgPanic(const char *msg, char * file, int line) {
+#if CH_DBG_ENABLED
+ if(dbg_panic_msg!=NULL)
+ return;
+ dbg_panic_file = file;
+ dbg_panic_line = line;
dbg_panic_msg = msg;
+#else
chSysHalt();
+#endif
}
#endif /* CH_DBG_ENABLED */
Index: chibios/os/ports/GCC/ARMCMx/chcore_v7m.h
===================================================================
--- chibios/os/ports/GCC/ARMCMx/chcore_v7m.h (revision 1050)
+++ chibios/os/ports/GCC/ARMCMx/chcore_v7m.h (revision 1051)
@@ -36,6 +36,8 @@
#ifndef _CHCORE_V7M_H_
#define _CHCORE_V7M_H_
+#include "chdebug.h"
+
/*===========================================================================*/
/* Port constants. */
/*===========================================================================*/
@@ -486,6 +488,8 @@
#define port_wait_for_interrupt()
#endif
+void chDbgStackOverflowPanic(Thread *otp);
+
/**
* @brief Performs a context switch between two threads.
* @details This is the most critical code in any port, this function
@@ -502,7 +506,7 @@
#define port_switch(ntp, otp) { \
register struct intctx *r13 asm ("r13"); \
if ((stkalign_t *)(r13 - 1) < otp->p_stklimit) \
- chDbgPanic("stack overflow"); \
+ chDbgStackOverflowPanic(otp); \
_port_switch(ntp, otp); \
}
#endif
Index: chibios/os/ports/GCC/ARMCMx/chcore.c
===================================================================
--- chibios/os/ports/GCC/ARMCMx/chcore.c (revision 1050)
+++ chibios/os/ports/GCC/ARMCMx/chcore.c (revision 1051)
@@ -34,7 +34,19 @@
*/
#include "ch.h"
+#include "string.h"
+static char panicMessage[200];
+
+void chDbgStackOverflowPanic(Thread *otp) {
+ strcpy(panicMessage, "stack overflow: ");
+#ifdef CH_USE_REGISTRY
+ strcat(panicMessage, otp->p_name);
+#endif
+ chDbgPanic(panicMessage, __FILE__, __LINE__);
+}
+
+
/**
* @brief Halts the system.
* @note The function is declared as a weak symbol, it is possible

2
firmware/clean.bat Normal file
View File

@ -0,0 +1,2 @@
rd /s /q .dep
rd /s /q build

4
firmware/clean_build.bat Normal file
View File

@ -0,0 +1,4 @@
rd /s /q .dep
rd /s /q build
compile.bat

38
firmware/compile.bat Normal file
View File

@ -0,0 +1,38 @@
@echo off
rm -rf .dep/
rm -rf build\rusefi.hex
echo Starting compilation
make
rem cd build
rem if not exist rusefi.hex echo "compilation failed"
rem if not exist rusefi.hex exit -1
rem cd ..
if errorlevel 1 goto error
echo Build complete success.
svn info > ../firmware_binary/version.txt
cp config/features.h ../firmware_binary
cp build/rusefi.hex ../firmware_binary
cp build/rusefi.elf ../firmware_binary
cp tunerstudio/rusefi.ini ../firmware_binary
cd ../firmware_binary
del firmaware_binary.zip
7z a firmaware_binary.zip rusefi.hex rusefi.ini features.h flash.bat
cd ../firmware
cd build
java -jar ../../java_tools/gcc_map_reader.jar > ../../firmware_binary/rusefi_ram_report.txt
cd ..
flash.bat
exit
:error
echo Compilation failed

View File

@ -0,0 +1,333 @@
/**
* @file arro_board.h
*
* This file contents a configuration of default ecu board. Pinout and other.
* TODO: most of the pins should get configurable
*
*
* @date Nov 14, 2013
* @author Andrey Belomutskiy, (c) 2012-2014
* @author frig
*
* This file is part of rusEfi - see http://rusefi.com
*
* rusEfi is free software; you can redistribute it and/or modify it under the terms of
* the GNU General Public License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* rusEfi is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
* even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program.
* If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef ARRO_BOARD_H_
#define ARRO_BOARD_H_
#define STM32_ICU_USE_TIM1 TRUE // wave input
#define STM32_ICU_USE_TIM2 TRUE // primary position sensor
#define STM32_ICU_USE_TIM3 TRUE // secondary position sensor
#define STM32_ICU_USE_TIM4 FALSE
#define STM32_ICU_USE_TIM5 FALSE
#define STM32_ICU_USE_TIM8 FALSE
#define STM32_ICU_USE_TIM9 TRUE // wave input
#define STM32_PWM_USE_TIM1 FALSE
#define STM32_PWM_USE_TIM2 FALSE
#define STM32_PWM_USE_TIM3 FALSE
#define STM32_PWM_USE_TIM4 TRUE // fast adc
#define STM32_PWM_USE_TIM5 TRUE // slow adc
#define STM32_PWM_USE_TIM8 FALSE
#define STM32_PWM_USE_TIM9 FALSE
#define STM32_SPI_USE_SPI1 FALSE
#define STM32_SPI_USE_SPI2 FALSE // external ADC
#define STM32_SPI_USE_SPI3 TRUE // potentiometer
#define STM32_CAN_USE_CAN1 TRUE
#define STM32_CAN_USE_CAN2 TRUE
#define STM32_I2C_I2C1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5)
#define STM32_I2C_I2C1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 6)
#define EFI_INTERNAL_SLOW_ADC_PWM &PWMD5
#define EFI_INTERNAL_FAST_ADC_PWM &PWMD4
#define EFI_CAN_DEVICE CAND2
#define EFI_CAN_RX_PORT GPIOB
#define EFI_CAN_RX_PIN 12
#define EFI_CAN_RX_AF 9
#define EFI_CAN_TX_PORT GPIOB
#define EFI_CAN_TX_PIN 6
#define EFI_CAN_TX_AF 9
//#define EFI_CAN_DEVICE CAND1
//#define EFI_CAN_RX_PORT GPIOB
//#define EFI_CAN_RX_PIN 8
//#define EFI_CAN_RX_AF 9
//#define EFI_CAN_TX_PORT GPIOB
//#define EFI_CAN_TX_PIN 9
//#define EFI_CAN_TX_AF 9
/**
* This section is for bottom-left corner SPI
*/
//#define SPI_CS1_PORT GPIOE
//#define SPI_CS1_PIN 13
//#define SPI_CS2_PORT GPIOE
//#define SPI_CS2_PIN 14
//#define SPI_CS3_PORT GPIOE
//#define SPI_CS3_PIN 15
//#define SPI_CS4_PORT GPIOD
//#define SPI_CS4_PIN 10
//#define SPI_SD_MODULE_PORT GPIOD
//#define SPI_SD_MODULE_PIN 11
#define EFI_SPI2_SCK_PORT GPIOB
#define EFI_SPI2_SCK_PIN 13
#define EFI_SPI2_MISO_PORT GPIOB
#define EFI_SPI2_MISO_PIN 14
#define EFI_SPI2_MOSI_PORT GPIOB
#define EFI_SPI2_MOSI_PIN 15
#define EFI_SPI2_AF 5
/**
* This section is for right-side center SPI
*/
#define SPI_CS1_PORT GPIOD
#define SPI_CS1_PIN 7
// this is pointing into the sky for now - conflict with I2C
#define SPI_CS2_PORT GPIOH
// this is pointing into the sky for now - conflict with I2C
#define SPI_CS2_PIN 0
#define SPI_CS3_PORT GPIOD
#define SPI_CS3_PIN 5
#define SPI_CS4_PORT GPIOD
#define SPI_CS4_PIN 3
#define SPI_SD_MODULE_PORT GPIOD
#define SPI_SD_MODULE_PIN 4
#define EFI_SPI3_SCK_PORT GPIOB
#define EFI_SPI3_SCK_PIN 3
#define EFI_SPI3_MISO_PORT GPIOB
#define EFI_SPI3_MISO_PIN 4
#define EFI_SPI3_MOSI_PORT GPIOB
#define EFI_SPI3_MOSI_PIN 5
#define EFI_SPI3_AF 6
#define MMC_CARD_SPI SPID3
#define EFI_I2C_SCL_PORT GPIOB
#define EFI_I2C_SCL_PIN 6
#define EFI_I2C_SDA_PORT GPIOB
#define EFI_I2C_SDA_PIN 7
#define EFI_I2C_AF 4
#define EFI_ADC_SLOW_CHANNELS_COUNT 10
#define EFI_USE_ADC_CHANNEL_IN0 TRUE
#define EFI_USE_ADC_CHANNEL_IN1 TRUE
#define EFI_USE_ADC_CHANNEL_IN2 TRUE
#define EFI_USE_ADC_CHANNEL_IN3 TRUE
#define EFI_USE_ADC_CHANNEL_IN4 TRUE
#define EFI_USE_ADC_CHANNEL_IN6 TRUE
#define EFI_USE_ADC_CHANNEL_IN7 TRUE
#define EFI_USE_ADC_CHANNEL_IN11 TRUE
#define EFI_USE_ADC_CHANNEL_IN12 TRUE
#define EFI_USE_ADC_CHANNEL_IN13 TRUE
#define EFI_USE_ADC_CHANNEL_IN14 FALSE
#define EFI_USE_ADC_CHANNEL_IN15 FALSE
/**
* Patched version of ChibiOS/RT support extra details in the system error messages
*/
#define EFI_CUSTOM_PANIC_METHOD TRUE
/*
* 10 channel board is (from left to right):
* ADC 15 PC5 TPS
* ADC 14 PC4 MAP
* ADC 7 PA7 IAT
* ADC 6 PA6 CLT
* ADC 5 PA5 TIM2_CH1
* ADC 4 PA4
* ADC 3 PA3
* ADC 2 PA2
* ADC 1 PA1 vBatt
* ADC 0 PA0 MAF
*/
#define ADC_LOGIC_TPS_2 ADC_CHANNEL_IN0
#define ADC_CHANNEL_VREF ADC_CHANNEL_IN14
/**
* currently ChibiOS uses only first and second channels of each timer for input capture
*
* So, our options are:
*
* TIM2_CH1
* PA5
*
* TIM4_CH1
* PB6
* PD12
*
* TIM9_CH1
* PE5
*/
/**
* Primary shaft position input
* TODO: ? rename to PRIMARY_TRIGGER?
*/
#define PRIMARY_SHAFT_POSITION_INPUT_DRIVER ICUD3
#define PRIMARY_SHAFT_POSITION_INPUT_PORT GPIOC
#define PRIMARY_SHAFT_POSITION_INPUT_PIN 6
#define PRIMARY_SHAFT_POSITION_INPUT_CHANNEL ICU_CHANNEL_1
/**
* Secondary shaft position input
* TODO: ? rename to SECONDARY_TRIGGER? *
*/
#define SECONDARY_SHAFT_POSITION_INPUT_DRIVER ICUD2
#define SECONDARY_SHAFT_POSITION_INPUT_PORT GPIOA
#define SECONDARY_SHAFT_POSITION_INPUT_PIN 5
#define SECONDARY_SHAFT_POSITION_INPUT_CHANNEL ICU_CHANNEL_1
#define IDLE_VALVE_PORT GPIOE
#define IDLE_VALVE_PIN 2
// todo: migrate to dynamic pin definition
/* Check Engine light */
#define LED_CHECK_ENGINE_PORT GPIOC
#define LED_CHECK_ENGINE_PIN 9
// todo: migrate to dynamic pin definition
/* Fuel pump */
#define FUEL_PUMP_PORT GPIOC
#define FUEL_PUMP_PIN 13
/* Logic analyzer */
#define LOGIC_ANALYZER_1_DRIVER ICUD1
#define LOGIC_ANALYZER_1_PORT GPIOA
#define LOGIC_ANALYZER_1_PIN 8
#define LOGIC_ANALYZER_2_DRIVER ICUD9
#define LOGIC_ANALYZER_2_PORT GPIOE
#define LOGIC_ANALYZER_2_PIN 7
/* Additional PINs on top of the standard discovery pins */
#define EXTRA_LED_1_PORT GPIOC
#define EXTRA_LED_1_PIN 14
#define EXTRA_LED_2_PORT GPIOE
#define EXTRA_LED_2_PIN 9
#define EXTRA_LED_3_PORT GPIOE
#define EXTRA_LED_3_PIN 11
#define PRIMARY_SHAFT_POSITION_EMULATION_PIN 1
#define PRIMARY_SHAFT_POSITION_EMULATION_PORT GPIOD
#define SECONDARY_SHAFT_POSITION_EMULATION_PORT GPIOD
#define SECONDARY_SHAFT_POSITION_EMULATION_PIN 2
// todo: migrate to dynamic pin definition
#define IDLE_SWITCH_PORT GPIOC
#define IDLE_SWITCH_PIN 8
//#define ETB_CONTROL_LINE_1_PORT GPIOE
//#define ETB_CONTROL_LINE_1_PIN 0
//
//#define ETB_CONTROL_LINE_2_PORT GPIOB
//#define ETB_CONTROL_LINE_2_PIN 8
#define ETB_CONTROL_LINE_3_PORT GPIOC
#define ETB_CONTROL_LINE_3_PIN 9
//#define CONSOLE_PORT GPIOB
//#define CONSOLE_TX_PIN 10
//#define CONSOLE_RX_PIN 11
/**
* Here we define the pinout for the human-readable protocol via UART, TunerStudio pinout is defined separately
*/
//#define EFI_CONSOLE_TX_PORT GPIOD
//#define EFI_CONSOLE_TX_PIN 8
//#define EFI_CONSOLE_RX_PORT GPIOD
//#define EFI_CONSOLE_RX_PIN 9
//#define EFI_CONSOLE_AF 7
#define EFI_CONSOLE_UART_DEVICE (&SD3)
#define EFI_CONSOLE_TX_PORT GPIOC
#define EFI_CONSOLE_TX_PIN 10
#define EFI_CONSOLE_RX_PORT GPIOC
#define EFI_CONSOLE_RX_PIN 11
#define EFI_CONSOLE_AF 7
//#define TS_SERIAL_TX_PORT GPIOD
//#define TS_SERIAL_TX_PIN 8
//#define TS_SERIAL_RX_PORT GPIOD
//#define TS_SERIAL_RX_PIN 9
//#define TS_SERIAL_AF 7
#define TS_SERIAL_TX_PORT GPIOC
#define TS_SERIAL_TX_PIN 10
#define TS_SERIAL_RX_PORT GPIOC
#define TS_SERIAL_RX_PIN 11
#define TS_SERIAL_AF 7
#define LED_CRANKING_STATUS_PORT GPIOD
#define LED_CRANKING_STATUS_PIN GPIOD_LED3
#define LED_RUNNING_STATUS_PORT GPIOD
#define LED_RUNNING_STATUS_PIN GPIOD_LED4
#define LED_ERROR_PORT GPIOD
#define LED_ERROR_PIN GPIOD_LED5
#define LED_COMMUNICATION_PORT GPIOD
#define LED_COMMUNICATION_PIN GPIOD_LED6
#define EFI_SIGNAL_EXECUTOR_SLEEP TRUE
#define EFI_SIGNAL_EXECUTOR_SINGLE_TIMER FALSE
#define EFI_SIGNAL_EXECUTOR_HW_TIMER FALSE
//#define EFI_SIGNAL_EXECUTOR_SLEEP FALSE
//#define EFI_SIGNAL_EXECUTOR_SINGLE_TIMER TRUE
// USART1 -> check defined STM32_SERIAL_USE_USART1
// For GPS we have USART1. We can start with PB7 USART1_RX and PB6 USART1_TX
#define GPS_SERIAL_DEVICE &SD1
#define GPS_SERIAL_SPEED 38400
#define GPS_PORT GPIOB
#define GPS_SERIAL_TX_PIN 6
#define GPS_SERIAL_RX_PIN 7
#define HD44780_PORT_RS GPIOE
#define HD44780_PIN_RS 9
#define HD44780_PORT_E GPIOE
#define HD44780_PIN_E 11
#define HD44780_PORT_DB4 GPIOE
#define HD44780_PIN_DB4 13
#define HD44780_PORT_DB5 GPIOE
#define HD44780_PIN_DB5 15
#define HD44780_PORT_DB6 GPIOB
#define HD44780_PIN_DB6 11
#define HD44780_PORT_DB7 GPIOB
#define HD44780_PIN_DB7 13
// todo: migrate to dynamic pin definition
#define FAN_RELAY_PORT GPIOC
#define FAN_RELAY_PIN 15
#endif /*ARRO_BOARD_H_*/

View File

@ -0,0 +1,31 @@
/**
* @file board.h
* Board configuration. Only general confuration, and including custom configs
*
* @date Nov 14, 2013
* @author Andrey Belomutskiy, (c) 2012-2014
* @author frig
*
* This file is part of rusEfi - see http://rusefi.com
*
* rusEfi is free software; you can redistribute it and/or modify it under the terms of
* the GNU General Public License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* rusEfi is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
* even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program.
* If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef BOARD_H_
#define BOARD_H_
#define EFI_BOARD_ARRO TRUE
#if EFI_BOARD_ARRO
#include "arro_board.h"
#endif
#endif /*BOARD_H_*/

View File

@ -0,0 +1,120 @@
/*
* @file efifeatures.h
*
* @brief In this header we can configure which firmware modules are used.
*
* @date Aug 29, 2013
* @author Andrey Belomutskiy, (c) 2012-2013
*/
#ifndef EFIFEATURES_H_
#define EFIFEATURES_H_
/**
* Build-in logic analyzer support. Logic analyzer viewer is one of the java console panes.
*/
#define EFI_WAVE_ANALYZER TRUE
#define EFI_WAVE_CHART TRUE
//#define SERIAL_SPEED (8 * 115200)
//#define SERIAL_SPEED (2 * 115200)
#define SERIAL_SPEED 115200
/**
* TunerStudio support.
*/
#define EFI_TUNER_STUDIO TRUE
#define EFI_SERIAL_OVER_USB TRUE
#define EFI_SERIAL_OVER_UART FALSE
//#define EFI_TUNER_STUDIO_OVER_USB TRUE
/**
* TunerStudio debug output
*/
#define EFI_TUNER_STUDIO_VERBOSE TRUE
#define EFI_DEFAILED_LOGGING FALSE
/**
* Dev console support.
*/
#define EFI_CLI_SUPPORT TRUE
/**
* Usually you need shaft position input, but maybe you do not need it?
*/
#define EFI_SHAFT_POSITION_INPUT TRUE
/**
* MCP42010 digital potentiometer supporrt. This could be useful if you are stimulating some
* stock ECU
*/
#define EFI_POTENTIOMETER FALSE
#define EFI_INTERNAL_ADC TRUE
#define EFI_DENSO_ADC FALSE
#define EFI_CAN_SUPPORT FALSE
#define EFI_HD44780_LCD TRUE
#define EFI_IDLE_CONTROL FALSE
#define EFI_ENGINE_EMULATOR TRUE
#define EFI_EMULATE_POSITION_SENSORS TRUE
#if EFI_TUNER_STUDIO
#if EFI_SERIAL_OVER_USB
#if EFI_TUNER_STUDIO_OVER_USB
#pragma "Cannot be EFI_SERIAL_OVER_USB and EFI_TUNER_STUDIO_OVER_USB at the same time"
#endif
#else
#if EFI_TUNER_STUDIO_OVER_USB
#else
#pragma "Cannot be serial over USART and TUNER_STUDIO over USART at the same time"
#endif
#endif /* EFI_TUNER_STUDIO */
#endif /* EFI_SERIAL_OVER_USB */
/**
* This macros is used to hide pieces of the code from unit tests, so it only makes sense in folders exposed to the tests project.
* This macros is NOT about taking out logging in general.
*/
#define EFI_PROD_CODE TRUE
/**
* Do we need Malfunction Indicator blinking logic?
*/
#define EFI_MALFUNCTIONAL_INDICATOR TRUE
/**
* Do we need file logging (like SD card) logic?
*/
#define EFI_FILE_LOGGING TRUE
/**
* While we embed multiple PnP configurations into the same firmware binary, these marcoses give us control
* over which configurations go into the binary
*/
#define EFI_SUPPORT_DODGE_NEON TRUE
#define EFI_SUPPORT_FORD_ASPIRE TRUE
#define EFI_SUPPORT_FORD_FIESTA TRUE
#define EFI_SUPPORT_NISSAN_PRIMERA TRUE
#define EFI_SUPPORT_1995_FORD_INLINE_6 TRUE
#define EFI_PERF_METRICS TRUE
/**
* Do we need GPS logic?
*/
#define EFI_UART_GPS TRUE
//#define EFI_UART_GPS FALSE
//#define EFI_IDLE_CONTROL TRUE
#define EFI_IDLE_CONTROL FALSE
#endif /* EFIFEATURES_H_ */

View File

@ -0,0 +1,34 @@
/**
* @file GY6_139QMB.c
* @brief 139qmb default engine configuration
*
* @date Feb 13, 2014
* @author rus084
* @author Andrey Belomutskiy, (c) 2012-2014
*/
#include "GY6_139QMB.h"
void setGy6139qmbDefaultEngineConfiguration(engine_configuration_s *engineConfiguration) {
engineConfiguration->rpmHardLimit = 9000;
engineConfiguration->crankingSettings.crankingRpm = 800;
engineConfiguration->analogInputDividerCoefficient = 1.52;
engineConfiguration->engineLoadMode = LM_MAP;
engineConfiguration->globalTriggerAngleOffset = 15;
engineConfiguration->analogChartMode = AC_MAP;
engineConfiguration->cylindersCount = 1; engineConfiguration->rpmMultiplier = 1;
engineConfiguration->firingOrder = FO_ONE_CYLINDER;
/**
* We treat the trigger as 1/0 toothed wheel
*/
engineConfiguration->triggerConfig.totalToothCount = 1;
engineConfiguration->triggerConfig.skippedToothCount = 0;
engineConfiguration->triggerConfig.isSynchronizationNeeded = FALSE;
engineConfiguration->needSecondTriggerInput = FALSE;
}
void setGy6139qmbengine_configuration2_s(engine_configuration_s *engineConfiguration, engine_configuration2_s *engineConfiguration2) {
}

View File

@ -0,0 +1,17 @@
/*
* @file GY6_139QMB.h
*
* @date 13 feb 2014 y.
* @author rus084
* @author Andrey Belomutskiy, (c) 2012-2014
*/
#ifndef GY6_139QMB_H_
#define GY6_139QMB_H_
#include "engine_configuration.h"
void setGy6139qmbDefaultEngineConfiguration(engine_configuration_s *engineConfiguration);
void setGy6139qmbengine_configuration2_s(engine_configuration_s *engineConfiguration, engine_configuration2_s *engineConfiguration2);
#endif /* GY6_139QMB_H_ */

View File

@ -0,0 +1,52 @@
/**
* @file audi_aan.c
* @brief Audo AAN default engine configuration
*
* @date Nov 24, 2013
* @author Andrey Belomutskiy, (c) 2012-2014
*
* This file is part of rusEfi - see http://rusefi.com
*
* rusEfi is free software; you can redistribute it and/or modify it under the terms of
* the GNU General Public License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* rusEfi is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
* even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program.
* If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "main.h"
#if EFI_ENGINE_AUDI_AAN || defined(__DOXYGEN__)
#include "engine_controller.h"
extern engine_configuration2_s engineConfiguration2;
void configureShaftPositionEmulatorShape(PwmConfig *state) {
/**
* One signal per cam shaft revolution
*/
int pinStates0[] = { 1, 0 };
float switchTimes[] = { 0.8, 1 };
int *pinStates[2] = { pinStates0 };
weComplexInit("distributor", state, 0, 2, switchTimes, 1, pinStates);
}
void configureEngineEventHandler(EventHandlerConfiguration *config) {
registerActuatorEvent(&config->ignitionEvents, 0, 1, 0);
registerActuatorEvent(&config->ignitionEvents, 0, 2, 90);
}
void setDefaultEngineConfiguration(EngineConfiguration *engineConfiguration) {
engineConfiguration2.shaftPositionEventCount = 2;
}
#endif /* EFI_ENGINE_AUDI_AAN */

View File

@ -0,0 +1,16 @@
/**
* @file audi_aan.h
* @brief Audo AAN default engine configuration
*
* @date Nov 24, 2013
* @author Andrey Belomutskiy, (c) 2012-2013
*/
#ifndef AUDI_AAN_H_
#define AUDI_AAN_H_
#if EFI_ENGINE_AUDI_AAN
#endif /* EFI_ENGINE_AUDI_AAN */
#endif /* AUDI_AAN_H_ */

View File

@ -0,0 +1,68 @@
/**
* @file dodge_neon.c
*
* @date Dec 16, 2013
* @author Andrey Belomutskiy, (c) 2012-2014
*/
#include "main.h"
#if EFI_SUPPORT_DODGE_NEON || defined(__DOXYGEN__)
#include "dodge_neon.h"
#include "engine_configuration.h"
#include "thermistors.h"
void setDodgeNeonEngineConfiguration(engine_configuration_s *engineConfiguration) {
engineConfiguration->rpmHardLimit = 7000;
engineConfiguration->ignitionPinMode = OM_OPENDRAIN;
setThermistorConfiguration(&engineConfiguration->cltThermistorConf, 0, 32500, 30, 7550, 100, 700);
engineConfiguration->cltThermistorConf.bias_resistor = 2200;
engineConfiguration->crankingSettings.coolantTempMaxC = 37.7; // 5ms at 37.7C
engineConfiguration->crankingSettings.fuelAtMaxTempMs = 5;
engineConfiguration->crankingSettings.coolantTempMinC = -40; // 26ms at -40C
engineConfiguration->crankingSettings.fuelAtMinTempMs = 26;
engineConfiguration->triggerConfig.syncRatioFrom = 0.72 * 0.8;
engineConfiguration->triggerConfig.syncRatioTo = 0.72 * 1.3;
engineConfiguration->triggerConfig.isSynchronizationNeeded = TRUE;
engineConfiguration->triggerConfig.useRiseEdge = FALSE;
engineConfiguration->triggerConfig.triggerType = TT_DODGE_NEON;
engineConfiguration->ignitionMode = IM_INDIVIDUAL_COILS;
engineConfiguration->firingOrder = FO_1_THEN_3_THEN_4_THEN2;
}
static void configureEngineEventHandler(EventHandlerConfiguration *config) {
float x = 51;
resetEventList(&config->crankingInjectionEvents);
resetEventList(&config->injectionEvents);
registerActuatorEvent(&config->injectionEvents, 0, addOutputSignal(INJECTOR_4_OUTPUT), x);
registerActuatorEvent(&config->injectionEvents, 0, addOutputSignal(INJECTOR_2_OUTPUT), x + 180);
registerActuatorEvent(&config->injectionEvents, 0, addOutputSignal(INJECTOR_1_OUTPUT), x + 360);
registerActuatorEvent(&config->injectionEvents, 0, addOutputSignal(INJECTOR_3_OUTPUT), x + 540);
resetEventList(&config->ignitionEvents);
registerActuatorEvent(&config->ignitionEvents, 0, addOutputSignal(SPARKOUT_1_OUTPUT), x);
registerActuatorEvent(&config->ignitionEvents, 0, addOutputSignal(SPARKOUT_2_OUTPUT), x + 180);
registerActuatorEvent(&config->ignitionEvents, 0, addOutputSignal(SPARKOUT_3_OUTPUT), x + 360);
registerActuatorEvent(&config->ignitionEvents, 0, addOutputSignal(SPARKOUT_4_OUTPUT), x + 540);
}
void setDodgeNeonengine_configuration2_s(engine_configuration_s *engineConfiguration, engine_configuration2_s *engineConfiguration2) {
configureEngineEventHandler(&engineConfiguration2->engineEventConfiguration);
}
#endif /* EFI_SUPPORT_DODGE_NEON */

View File

@ -0,0 +1,21 @@
/**
* @file dodge_neon.h
* @brief 1995 Dodge Neon default engine configuration
*
* @date Dec 16, 2013
* @author Andrey Belomutskiy, (c) 2012-2013
*/
#ifndef DODGE_NEON_H_
#define DODGE_NEON_H_
#if EFI_SUPPORT_DODGE_NEON
#include "engine_configuration.h"
void setDodgeNeonEngineConfiguration(engine_configuration_s *engineConfiguration);
void setDodgeNeonengine_configuration2_s(engine_configuration_s *engineConfiguration, engine_configuration2_s *engineConfiguration2);
#endif /* EFI_SUPPORT_DODGE_NEON */
#endif /* DODGE_NEON_H_ */

View File

@ -0,0 +1,15 @@
/**
* @file engines.h
*
* @date Aug 30, 2013
* @author Andrey Belomutskiy, (c) 2012-2013
*/
#ifndef ENGINE_H_
#define ENGINE_H_
#include "boards.h"
#include "efifeatures.h"
#include "rusefi_enums.h"
#endif /* ENGINE_H_ */

View File

@ -0,0 +1,13 @@
ENGINES_SRC = $(PROJECT_DIR)/config/engines/audi_aan.c \
$(PROJECT_DIR)/config/engines/dodge_neon.c \
$(PROJECT_DIR)/config/engines/ford_fiesta.c \
$(PROJECT_DIR)/config/engines/ford_1995_inline_6.c \
$(PROJECT_DIR)/config/engines/nissan_primera.c \
$(PROJECT_DIR)/config/engines/mazda_miata_nb.c \
$(PROJECT_DIR)/config/engines/honda_accord.c \
$(PROJECT_DIR)/config/engines/snow_blower.c \
$(PROJECT_DIR)/config/engines/GY6_139QMB.c \
$(PROJECT_DIR)/config/engines/mazda_323.c
ENGINES_SRC_CPP = $(PROJECT_DIR)/config/engines/ford_aspire.cpp

View File

@ -0,0 +1,78 @@
/**
* @file ford_1995_inline_6.c
* @brief Default engine configuration for a 1995 Ford inline 6 engine
*
* http://rusefi.com/forum/viewtopic.php?f=3&t=469
*
* FORD_INLINE_6_1995 = 7
*
* @date Feb 12, 2014
* @author Andrey Belomutskiy, (c) 2012-2014
*/
#include "main.h"
#include "ford_1995_inline_6.h"
#include "engine_math.h"
#include "thermistors.h"
#if EFI_SUPPORT_1995_FORD_INLINE_6 || defined(__DOXYGEN__)
/**
* @brief Default values for persistent properties
*/
void setFordInline6(engine_configuration_s *engineConfiguration) {
engineConfiguration->cylindersCount = 6;
/**
* 0.5 means primary position sensor is on a camshaft
*/
engineConfiguration->rpmMultiplier = 0.5;
engineConfiguration->ignitionMode = IM_ONE_COIL;
engineConfiguration->firingOrder = FO_1_THEN_5_THEN_3_THEN_6_THEN_2_THEN_4;
/**
* 0.5ms dweel time just to be sure it would fit within camshaft revolution, dwell is not controlled by us anyway
*/
setConstantDwell(engineConfiguration, 0.5);
/**
* We treat the trigger as 6/0 toothed wheel
*/
engineConfiguration->triggerConfig.totalToothCount = 6;
engineConfiguration->triggerConfig.skippedToothCount = 0;
engineConfiguration->triggerConfig.isSynchronizationNeeded = FALSE;
engineConfiguration->triggerConfig.useRiseEdge = TRUE;
engineConfiguration->needSecondTriggerInput = FALSE;
setThermistorConfiguration(&engineConfiguration->cltThermistorConf, -10, 160310, 60, 7700, 120.00, 1180);
engineConfiguration->cltThermistorConf.bias_resistor = 2700;
setThermistorConfiguration(&engineConfiguration->iatThermistorConf, -10, 160310, 60, 7700, 120.00, 1180);
engineConfiguration->iatThermistorConf.bias_resistor = 2700;
engineConfiguration->tpsAdcChannel = 7; // input channel 3 is PA7, that's ADC7
engineConfiguration->cltAdcChannel = 0; // input channel 9 is PA0, that's ADC0
engineConfiguration->iatAdcChannel = 11; // input channel 12 is PC1, that's ADC11
// divided by 2 because of voltage divider, then converted into 10bit ADC value (TunerStudio format)
engineConfiguration->tpsMin = (1.250 / 2) * 1024 / 3.3;
engineConfiguration->tpsMax = (4.538 / 2) * 1024 / 3.3;
engineConfiguration->map.config.mapType = MT_MPX4250;
engineConfiguration->map.channel = 2; // input channel 8 is ADC2
// engineConfiguration->vBattAdcChannel = 0; //
// engineConfiguration->mafAdcChannel = 1;
}
/**
* @brief These settings are not persistent yet
*/
void setFordInline6_2(engine_configuration_s *engineConfiguration, engine_configuration2_s *engineConfiguration2) {
initializeIgnitionActions(engineConfiguration, engineConfiguration2);
}
#endif /* EFI_SUPPORT_1995_FORD_INLINE_6 */

View File

@ -0,0 +1,16 @@
/*
* @file ford_1995_inline_6.h
*
* @date Feb 12, 2014
* @author Andrey Belomutskiy, (c) 2012-2014
*/
#ifndef FORD_1995_INLINE_6_H_
#define FORD_1995_INLINE_6_H_
#include "engine_configuration.h"
void setFordInline6(engine_configuration_s *engineConfiguration);
void setFordInline6_2(engine_configuration_s *engineConfiguration, engine_configuration2_s *engineConfiguration2);
#endif /* FORD_1995_INLINE_6_H_ */

View File

@ -0,0 +1,293 @@
/**
* @file ford_aspire.c
* @brief 1996 Ford Aspire default engine configuration
*
* @date Sep 9, 2013
* @author Andrey Belomutskiy, (c) 2012-2014
*/
#include "main.h"
#include "ford_aspire.h"
#include "allsensors.h"
#include "engines.h"
#include "engine_math.h"
#include "advance_map.h"
#include "engine_configuration.h"
#if EFI_SUPPORT_FORD_ASPIRE || defined(__DOXYGEN__)
/**
* Just the default RPM bin - with TunerStudio you can adjust even the bins
*/
static float default_fuel_maf_bins[FUEL_LOAD_COUNT] = {/*0*/ 1.200000,
/*1*/ 1.413333,
/*2*/ 1.626667,
/*3*/ 1.840000,
/*4*/ 2.053333,
/*5*/ 2.266667,
/*6*/ 2.480000,
/*7*/ 2.693333,
/*8*/ 2.906667,
/*9*/ 3.120000,
/*10*/ 3.333333,
/*11*/ 3.546667,
/*12*/ 3.760000,
/*13*/ 3.973333,
/*14*/ 4.186667,
/*15*/ 4.400000,
};
static float default_fuel_rpm_bins[FUEL_RPM_COUNT] = {/*0*/ 800.000000,
/*1*/ 1213.333374,
/*2*/ 1626.666748,
/*3*/ 2040.000000,
/*4*/ 2453.333496,
/*5*/ 2866.666748,
/*6*/ 3280.000000,
/*7*/ 3693.333496,
/*8*/ 4106.666992,
/*9*/ 4520.000000,
/*10*/ 4933.333496,
/*11*/ 5346.666992,
/*12*/ 5760.000000,
/*13*/ 6173.333496,
/*14*/ 6586.666992,
/*15*/ 7000.000000,
};
/**
* This is just the default map which is stored into flash memory in case flash is empty
* The convenient way to override these default would be to tune this map using TunerStudio software
* with which rusEfi is integrated
*/
static float default_fuel_table[FUEL_LOAD_COUNT][FUEL_RPM_COUNT] = {
/* RPM 800.000000 1213.333374 1626.666748 2040.000000 2453.333496 2866.666748 3280.000000 3693.333496 4106.666992 4520.000000 4933.333496 5346.666992 5760.000000 6173.333496 6586.666992 7000.000000*/
/* Load 1.200000 */{ 1.542000, 1.547600, 1.551867, 1.570000, 1.550000, 0.908666, 0.794800, 0.775200, 0.791733, 0.800000, 0.798667, 0.805733, 0.810000, 0.810000, 0.810000, 0.810000},
/* Load 1.413333 */{ 1.532133, 1.565325, 1.551244, 1.552773, 1.546018, 0.802089, 0.810000, 0.788507, 0.808898, 0.744987, 0.701378, 0.711404, 0.744667, 0.810000, 0.810000, 0.810000},
/* Load 1.626667 */{ 1.543600, 1.545573, 1.555956, 1.545973, 1.415333, 0.115288, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000},
/* Load 1.840000 */{ 1.538800, 1.741893, 1.558426, 1.591440, 1.228773, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000},
/* Load 2.053333 */{ 2.322933, 3.439928, 2.818523, 2.242266, 2.125839, 1.194041, 0.488959, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000},
/* Load 2.266667 */{ 7.696667, 5.957510, 4.700978, 3.879200, 3.099600, 2.403111, 2.458666, 1.790979, 2.190533, 2.074667, 1.368887, 1.287556, 0.000000, 0.000000, 0.000000, 0.000000},
/* Load 2.480000 */{ 14.330001, 8.710773, 6.558134, 5.491520, 5.117494, 4.308798, 3.185521, 3.339520, 2.883200, 2.840399, 2.643334, 2.505092, 2.296640, 0.000000, 0.000000, 0.000000},
/* Load 2.693333 */{ 21.354004, 15.415981, 10.953371, 8.779520, 5.866481, 5.038577, 5.113254, 4.395565, 4.537200, 3.559386, 3.828622, 3.147404, 3.377706, 2.780000, 2.780000, 2.780000},
/* Load 2.906667 */{ 20.020401, 16.311201, 17.209972, 15.600482, 10.950183, 7.773465, 6.243252, 7.400613, 6.672044, 6.133946, 5.529999, 4.769466, 4.528134, 4.010000, 4.010000, 4.010000},
/* Load 3.120000 */{ 18.264000, 15.464134, 15.595227, 15.395760, 12.987042, 13.339199, 8.897678, 8.927333, 8.032880, 6.769040, 5.823335, 6.413146, 6.089281, 5.730000, 5.730000, 5.730000},
/* Load 3.333333 */{ 17.414667, 15.366401, 15.187378, 15.338401, 15.306623, 15.386889, 14.470800, 11.941733, 10.985557, 9.956400, 9.019111, 8.441555, 7.515199, 6.900000, 6.900000, 6.900000},
/* Load 3.546667 */{ 17.005333, 15.372302, 15.188160, 15.278268, 15.325876, 15.561645, 15.638906, 15.415441, 13.630393, 10.918774, 11.508314, 10.660010, 9.551816, 9.230000, 9.230000, 9.230000},
/* Load 3.760000 */{ 16.978800, 15.360346, 15.170587, 15.301680, 15.331520, 15.684401, 15.810480, 15.702454, 15.828107, 15.114964, 14.666001, 11.908847, 12.046723, 9.230000, 9.230000, 9.230000},
/* Load 3.973333 */{ 16.975599, 15.343084, 15.305715, 15.287172, 15.288801, 15.484089, 15.928854, 15.780366, 15.669041, 15.836693, 16.123335, 15.054674, 14.972587, 14.610000, 14.610000, 14.610000},
/* Load 4.186667 */{ 16.961868, 15.368391, 15.210348, 15.290641, 15.263707, 15.485778, 15.827333, 15.802435, 15.677885, 15.827120, 15.997155, 16.027468, 15.478480, 15.190000, 15.190000, 15.190000},
/* Load 4.400000 */{ 17.010000, 15.250000, 15.680000, 15.440000, 15.270000, 15.470000, 15.800000, 15.730000, 15.600000, 15.790000, 16.120001, 16.110001, 15.630000, 15.150000, 15.150000, 15.150000}
};
static float default_timing_maf_table[AD_LOAD_COUNT] = {/*0*/ 1.200000,
/*1*/ 1.413333,
/*2*/ 1.626667,
/*3*/ 1.840000,
/*4*/ 2.053333,
/*5*/ 2.266667,
/*6*/ 2.480000,
/*7*/ 2.693333,
/*8*/ 2.906667,
/*9*/ 3.120000,
/*10*/ 3.333333,
/*11*/ 3.546667,
/*12*/ 3.760000,
/*13*/ 3.973333,
/*14*/ 4.186667,
/*15*/ 4.400000,
};
static float default_timing_rpm_table[AD_RPM_COUNT] = {/*0*/ 800.000000,
/*1*/ 1213.333374,
/*2*/ 1626.666748,
/*3*/ 2040.000000,
/*4*/ 2453.333496,
/*5*/ 2866.666748,
/*6*/ 3280.000000,
/*7*/ 3693.333496,
/*8*/ 4106.666992,
/*9*/ 4520.000000,
/*10*/ 4933.333496,
/*11*/ 5346.666992,
/*12*/ 5760.000000,
/*13*/ 6173.333496,
/*14*/ 6586.666992,
/*15*/ 7000.000000,
};
static float default_timing_table[AD_LOAD_COUNT][AD_RPM_COUNT] = {
/* RPM 800.000000 1213.333374 1626.666748 2040.000000 2453.333496 2866.666748 3280.000000 3693.333496 4106.666992 4520.000000 4933.333496 5346.666992 5760.000000 6173.333496 6586.666992 7000.000000*/
/* Load 1.200000 */{ 0.662000, -7.730000, -16.722000, -23.139999, -29.398001, -31.268000, -32.108002, -30.436001, -30.896000, -26.656000, -24.704000, -25.108000, -25.132000, -25.459999, -25.459999, -25.459999},
/* Load 1.413333 */{ 0.546000, -7.662000, -16.882000, -23.482000, -29.520000, -31.323999, -32.108002, -30.656000, -30.468000, -26.879999, -24.746000, -24.742001, -29.032000, -25.562000, -25.562000, -25.562000},
/* Load 1.626667 */{ 0.584000, -7.870000, -16.714001, -23.025999, -29.542000, -31.166000, -32.175999, -30.540001, -30.268000, -26.416000, -24.134001, -25.007999, -24.698000, -26.167999, -26.167999, -26.167999},
/* Load 1.840000 */{ 0.584000, -7.658000, -16.714001, -23.254000, -29.351999, -30.978001, -32.141998, -30.874001, -30.896000, -26.507999, -24.558001, -24.389999, -25.761999, -35.492001, -35.492001, -35.492001},
/* Load 2.053333 */{ 0.584000, -7.862000, -16.538000, -23.254000, -29.232000, -31.296000, -32.520000, -30.142000, -30.388000, -25.903999, -24.370001, -24.082001, -24.792000, -24.351999, -24.351999, -24.351999},
/* Load 2.266667 */{ -1.364000, -7.726000, -16.806000, -23.254000, -29.639999, -31.006001, -32.298000, -30.912001, -29.882000, -26.392000, -24.664000, -27.233999, -25.374001, -25.417999, -25.417999, -25.417999},
/* Load 2.480000 */{ 1.364000, -10.490000, -16.705999, -22.441999, -28.101999, -30.238001, -32.363998, -30.719999, -30.896000, -26.608000, -24.664000, -24.431999, -24.500000, -25.510000, -25.510000, -25.510000},
/* Load 2.693333 */{ 9.864000, -10.416000, -11.680000, -19.150000, -25.754000, -27.936001, -32.554001, -30.656000, -30.153999, -27.184000, -25.252001, -22.812000, -24.452000, -25.219999, -25.219999, -25.219999},
/* Load 2.906667 */{ 9.866000, 5.452000, 2.854000, -17.212000, -17.552000, -20.688000, -25.660000, -27.809999, -27.691999, -27.224001, -25.882000, -25.360001, -26.100000, -27.992001, -27.992001, -27.992001},
/* Load 3.120000 */{ 9.864000, 5.452000, 2.854000, -0.342000, -12.526000, -16.218000, -21.364000, -27.590000, -25.780001, -24.170000, -24.664000, -25.584000, -26.490000, -31.968000, -31.968000, -31.968000},
/* Load 3.333333 */{ 9.864000, 5.516000, 2.854000, -0.226000, -2.738000, -3.816000, -11.924000, -18.808001, -21.038000, -21.538000, -21.209999, -22.228001, -25.046000, -25.156000, -25.156000, -25.156000},
/* Load 3.546667 */{ 9.866000, 5.518000, 2.854000, 0.000000, -3.022000, -3.816000, -6.428000, -7.788000, -19.426001, -20.860001, -19.966000, -21.030001, -21.396000, -21.570000, -21.570000, -21.570000},
/* Load 3.760000 */{ 9.864000, 5.516000, 2.772000, -0.226000, -2.732000, -3.500000, -6.798000, -8.102000, -8.660000, -9.500000, -11.788000, -20.132000, -20.072001, -20.510000, -20.510000, -20.510000},
/* Load 3.973333 */{ 9.864000, 5.518000, 2.854000, 0.000000, -2.880000, -3.816000, -6.420000, -8.320000, -8.426000, -8.532000, -11.470000, -11.442000, -13.610000, -12.022000, -12.022000, -12.022000},
/* Load 4.186667 */{ 9.750000, 5.518000, 2.604000, 0.000000, -2.880000, -3.654000, -6.050000, -6.888000, -8.372000, -9.364000, -11.764000, -11.732000, -11.864000, -12.376000, -12.376000, -12.376000},
/* Load 4.400000 */{ 0.350000, 5.590000, 0.502000, 0.910000, 0.864000, 0.954000, 1.324000, -7.436000, 1.170000, 1.054000, 2.058000, 2.098000, 2.636000, -12.352000, -12.352000, -12.352000}
};
static void configureAspireEngineEventHandler(engine_configuration_s *e, trigger_shape_s * s, EventHandlerConfiguration *config) {
resetEventList(&config->crankingInjectionEvents);
// registerActuatorEventExt(e, s, &config->crankingInjectionEvents, addOutputSignal(INJECTOR_1_OUTPUT), x);
// registerActuatorEventExt(e, s, &config->crankingInjectionEvents, addOutputSignal(INJECTOR_2_OUTPUT), x);
// registerActuatorEventExt(e, s, &config->crankingInjectionEvents, addOutputSignal(INJECTOR_3_OUTPUT), x);
// registerActuatorEventExt(e, s, &config->crankingInjectionEvents, addOutputSignal(INJECTOR_4_OUTPUT), x);
// registerActuatorEventExt(e, s, &config->crankingInjectionEvents, addOutputSignal(INJECTOR_1_OUTPUT), x + 180);
// registerActuatorEventExt(e, s, &config->crankingInjectionEvents, addOutputSignal(INJECTOR_2_OUTPUT), x + 180);
// registerActuatorEventExt(e, s, &config->crankingInjectionEvents, addOutputSignal(INJECTOR_3_OUTPUT), x + 180);
// registerActuatorEventExt(e, s, &config->crankingInjectionEvents, addOutputSignal(INJECTOR_4_OUTPUT), x + 180);
// registerActuatorEventExt(e, s, &config->crankingInjectionEvents, addOutputSignal(INJECTOR_1_OUTPUT), x + 360);
// registerActuatorEventExt(e, s, &config->crankingInjectionEvents, addOutputSignal(INJECTOR_2_OUTPUT), x + 360);
// registerActuatorEventExt(e, s, &config->crankingInjectionEvents, addOutputSignal(INJECTOR_3_OUTPUT), x + 360);
// registerActuatorEventExt(e, s, &config->crankingInjectionEvents, addOutputSignal(INJECTOR_4_OUTPUT), x + 360);
// registerActuatorEventExt(e, s, &config->crankingInjectionEvents, addOutputSignal(INJECTOR_1_OUTPUT), x + 540);
// registerActuatorEventExt(e, s, &config->crankingInjectionEvents, addOutputSignal(INJECTOR_2_OUTPUT), x + 540);
// registerActuatorEventExt(e, s, &config->crankingInjectionEvents, addOutputSignal(INJECTOR_3_OUTPUT), x + 540);
// registerActuatorEventExt(e, s, &config->crankingInjectionEvents, addOutputSignal(INJECTOR_4_OUTPUT), x + 540);
registerActuatorEvent(&config->crankingInjectionEvents, 1, addOutputSignal(INJECTOR_1_OUTPUT), 0);
registerActuatorEvent(&config->crankingInjectionEvents, 1, addOutputSignal(INJECTOR_2_OUTPUT), 0);
registerActuatorEvent(&config->crankingInjectionEvents, 1, addOutputSignal(INJECTOR_3_OUTPUT), 0);
registerActuatorEvent(&config->crankingInjectionEvents, 1, addOutputSignal(INJECTOR_4_OUTPUT), 0);
registerActuatorEvent(&config->crankingInjectionEvents, 3, addOutputSignal(INJECTOR_1_OUTPUT), 0);
registerActuatorEvent(&config->crankingInjectionEvents, 3, addOutputSignal(INJECTOR_2_OUTPUT), 0);
registerActuatorEvent(&config->crankingInjectionEvents, 3, addOutputSignal(INJECTOR_3_OUTPUT), 0);
registerActuatorEvent(&config->crankingInjectionEvents, 3, addOutputSignal(INJECTOR_4_OUTPUT), 0);
registerActuatorEvent(&config->crankingInjectionEvents, 6, addOutputSignal(INJECTOR_1_OUTPUT), 0);
registerActuatorEvent(&config->crankingInjectionEvents, 6, addOutputSignal(INJECTOR_2_OUTPUT), 0);
registerActuatorEvent(&config->crankingInjectionEvents, 6, addOutputSignal(INJECTOR_3_OUTPUT), 0);
registerActuatorEvent(&config->crankingInjectionEvents, 6, addOutputSignal(INJECTOR_4_OUTPUT), 0);
registerActuatorEvent(&config->crankingInjectionEvents, 8, addOutputSignal(INJECTOR_1_OUTPUT), 0);
registerActuatorEvent(&config->crankingInjectionEvents, 8, addOutputSignal(INJECTOR_2_OUTPUT), 0);
registerActuatorEvent(&config->crankingInjectionEvents, 8, addOutputSignal(INJECTOR_3_OUTPUT), 0);
registerActuatorEvent(&config->crankingInjectionEvents, 8, addOutputSignal(INJECTOR_4_OUTPUT), 0);
addFuelEvents(e, s, config);
// i = 1;
// registerActuatorEventExt(e, s, &config->injectionEvents, addOutputSignal(INJECTOR_1_OUTPUT + getCylinderId(e->firingOrder,i ) - 1), x + i * 720 / 4);
// registerActuatorEventExt(e, s, &config->injectionEvents, addOutputSignal(INJECTOR_4_OUTPUT), x + 360);
// registerActuatorEventExt(e, s, &config->injectionEvents, addOutputSignal(INJECTOR_2_OUTPUT), x + 540);
// registerActuatorEvent(&config->injectionEvents, 1, addOutputSignal(INJECTOR_4_OUTPUT), 0);
// registerActuatorEvent(&config->injectionEvents, 3, addOutputSignal(INJECTOR_2_OUTPUT), 0);
// registerActuatorEvent(&config->injectionEvents, 6, addOutputSignal(INJECTOR_1_OUTPUT), 0);
// registerActuatorEvent(&config->injectionEvents, 8, addOutputSignal(INJECTOR_3_OUTPUT), 0);
float y = -106 + 360;
float x = 74;
resetEventList(&config->ignitionEvents);
// registerActuatorEvent(&config->ignitionEvents, 1, addOutputSignal(SPARKOUT_1_OUTPUT), 0);
// registerActuatorEvent(&config->ignitionEvents, 3, addOutputSignal(SPARKOUT_1_OUTPUT), 0);
// registerActuatorEvent(&config->ignitionEvents, 6, addOutputSignal(SPARKOUT_1_OUTPUT), 0);
// registerActuatorEvent(&config->ignitionEvents, 8, addOutputSignal(SPARKOUT_1_OUTPUT), 0);
registerActuatorEventExt(e, s, &config->ignitionEvents, addOutputSignal(SPARKOUT_1_OUTPUT), x);
registerActuatorEventExt(e, s, &config->ignitionEvents, addOutputSignal(SPARKOUT_1_OUTPUT), x + 180);
registerActuatorEventExt(e, s, &config->ignitionEvents, addOutputSignal(SPARKOUT_1_OUTPUT), x + 360);
registerActuatorEventExt(e, s, &config->ignitionEvents, addOutputSignal(SPARKOUT_1_OUTPUT), x + 540);
}
static void setDefaultMaps(engine_configuration_s *engineConfiguration) {
for (int i = 0; i < FUEL_LOAD_COUNT; i++)
engineConfiguration->fuelLoadBins[i] = default_fuel_maf_bins[i];
for (int i = 0; i < FUEL_RPM_COUNT; i++)
engineConfiguration->fuelRpmBins[i] = default_fuel_rpm_bins[i];
for (int k = 0; k < FUEL_LOAD_COUNT; k++) {
for (int r = 0; r < FUEL_RPM_COUNT; r++) {
engineConfiguration->fuelTable[k][r] = default_fuel_table[k][r];
}
}
for (int i = 0; i < AD_LOAD_COUNT; i++)
engineConfiguration->ignitionLoadBins[i] = default_timing_maf_table[i];
for (int i = 0; i < AD_RPM_COUNT; i++)
engineConfiguration->ignitionRpmBins[i] = default_timing_rpm_table[i];
for (int k = 0; k < AD_LOAD_COUNT; k++) {
for (int r = 0; r < AD_RPM_COUNT; r++) {
engineConfiguration->ignitionTable[k][r] = default_timing_table[k][r];
}
}
}
void setFordAspireEngineConfiguration(engine_configuration_s *engineConfiguration) {
engineConfiguration->tpsMin = 1;
engineConfiguration->tpsMax = 1000;
engineConfiguration->rpmHardLimit = 7000;
setThermistorConfiguration(&engineConfiguration->cltThermistorConf, -20, 18000, 23.8889, 2100, 48.8889, 1000);
engineConfiguration->cltThermistorConf.bias_resistor = 3300; // that's my custom resistor value!
engineConfiguration->crankingSettings.coolantTempMaxC = 65; // 8ms at 65C
engineConfiguration->crankingSettings.fuelAtMaxTempMs = 8;
engineConfiguration->crankingSettings.coolantTempMinC = 0; // 20ms at 0C
engineConfiguration->crankingSettings.fuelAtMinTempMs = 20;
// engineConfiguration->ignitionPinMode = OM_INVERTED;
engineConfiguration->cylindersCount = 4;
engineConfiguration->firingOrder = FO_1_THEN_3_THEN_4_THEN2;
engineConfiguration->globalTriggerAngleOffset = 175;
engineConfiguration->ignitionOffset = 35;
engineConfiguration->injectionOffset = 254;
setDefaultMaps(engineConfiguration);
engineConfiguration->crankingSettings.crankingRpm = 550;
engineConfiguration->crankingChargeAngle = 65;
for (int i = 0; i < DWELL_CURVE_SIZE; i++) {
engineConfiguration->sparkDwellBins[i] = 0;
engineConfiguration->sparkDwell[i] = -1;
}
engineConfiguration->sparkDwellBins[5] = 1;
engineConfiguration->sparkDwell[5] = 4;
engineConfiguration->sparkDwellBins[6] = 4500;
engineConfiguration->sparkDwell[6] = 4;
engineConfiguration->sparkDwellBins[7] = 12500;
engineConfiguration->sparkDwell[7] = 0;
engineConfiguration->triggerConfig.triggerType = TT_FORD_ASPIRE;
engineConfiguration->triggerConfig.isSynchronizationNeeded = FALSE;
engineConfiguration->HD44780width = 20;
engineConfiguration->HD44780height = 4;
engineConfiguration->tpsAdcChannel = 3; // 15 is the old value
engineConfiguration->vBattAdcChannel = 0; // 1 is the old value
// engineConfiguration->map.channel = 1;
engineConfiguration->mafAdcChannel = 1;
engineConfiguration->cltAdcChannel = 11;
// engineConfiguration->iatAdcChannel =
engineConfiguration->map.config.mapType = MT_DENSO183;
}
void setFordAspireengine_configuration2_s(engine_configuration_s *engineConfiguration, engine_configuration2_s *engineConfiguration2) {
configureAspireEngineEventHandler(engineConfiguration,
&engineConfiguration2->triggerShape,
&engineConfiguration2->engineEventConfiguration);
}
#endif /* EFI_SUPPORT_FORD_ASPIRE */

View File

@ -0,0 +1,29 @@
/**
* @file ford_aspire.h
* @brief 1996 Ford Aspire default engine configuration
*
* @date Aug 30, 2013
* @author Andrey Belomutskiy, (c) 2012-2013
*
* http://rusefi.com/forum/viewtopic.php?t=375
*
*/
#ifndef FORD_ASPIRE_H_
#define FORD_ASPIRE_H_
#include "engine_configuration.h"
#ifdef __cplusplus
extern "C"
{
#endif /* __cplusplus */
void setFordAspireEngineConfiguration(engine_configuration_s *engineConfiguration);
void setFordAspireengine_configuration2_s(engine_configuration_s *engineConfiguration, engine_configuration2_s *engineConfiguration2);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* FORD_ASPIRE_H_ */

View File

@ -0,0 +1,17 @@
/**
* @file ford_escort_gt.h
* @brief 1993 Ford Escort GT engine configuration. The US Escort.
*
* @date Oct 31, 2013
* @author Andrey Belomutskiy, (c) 2012-2013
*
*
* Injectors: Denso 195500-2180, 230-265cc (?), tan, 13.9 ohms
*/
#ifndef FORD_ESCORT_GT_H_
#define FORD_ESCORT_GT_H_
#endif /* FORD_ESCORT_GT_H_ */

View File

@ -0,0 +1,53 @@
/**
* @file ford_fiesta.c
* @brief European 1990 Ford Fiesta
*
* @date Nov 22, 2013
* @author Andrey Belomutskiy, (c) 2012-2014
*/
#include "main.h"
#if EFI_SUPPORT_FORD_FIESTA || defined(__DOXYGEN__)
#include "ford_fiesta.h"
#include "engine_configuration.h"
#include "engine_math.h"
static void configureEngineEventHandler(EventHandlerConfiguration *config) {
// injector 1 activated at the 1st tooth event while cranking
registerActuatorEvent(&config->crankingInjectionEvents, 0, addOutputSignal(INJECTOR_1_OUTPUT), 0);
// injector 2 activated at the 36th st tooth event while cranking (do not forget - there are 70 events overall, 35 ups and 46 downs
registerActuatorEvent(&config->crankingInjectionEvents, 0, addOutputSignal(INJECTOR_2_OUTPUT), 360);
// injector 1 activated at the 1st tooth event while normal running
registerActuatorEvent(&config->injectionEvents, 0, addOutputSignal(INJECTOR_1_OUTPUT), 0);
// injector 2 activated at the 36th tooth event while normal running
registerActuatorEvent(&config->injectionEvents, 0, addOutputSignal(INJECTOR_2_OUTPUT), 180);
// spark 1 activated at the 1st tooth event while cranking & normal running
registerActuatorEvent(&config->ignitionEvents, 0, addOutputSignal(SPARKOUT_2_OUTPUT), 0);
// spark 2 activated at the 36th tooth event while cranking & normal running
registerActuatorEvent(&config->ignitionEvents, 0, addOutputSignal(SPARKOUT_2_OUTPUT), 360);
}
void setFordFiestaDefaultEngineConfiguration(engine_configuration_s *engineConfiguration) {
engineConfiguration->rpmHardLimit = 7000;
// only crankshaft sensor so far
engineConfiguration->rpmMultiplier = 1;
engineConfiguration->triggerConfig.totalToothCount = 36;
engineConfiguration->triggerConfig.skippedToothCount = 1;
engineConfiguration->ignitionMode = IM_WASTED_SPARK;
engineConfiguration->firingOrder = FO_1_THEN_3_THEN_4_THEN2;
}
void setFordFiestaengine_configuration2_s(engine_configuration_s *engineConfiguration, engine_configuration2_s *engineConfiguration2) {
configureEngineEventHandler(&engineConfiguration2->engineEventConfiguration);
initializeIgnitionActions(engineConfiguration, engineConfiguration2);
}
#endif /* EFI_SUPPORT_FORD_FIESTA */

View File

@ -0,0 +1,18 @@
/**
* @file ford_fiesta.h
*
* @date Nov 22, 2013
* @author Andrey Belomutskiy, (c) 2012-2013
*/
#ifndef FORD_FIESTA_H_
#define FORD_FIESTA_H_
#if EFI_SUPPORT_FORD_FIESTA || defined(__DOXYGEN__)
#include "engine_configuration.h"
void setFordFiestaDefaultEngineConfiguration(engine_configuration_s *engineConfiguration);
void setFordFiestaengine_configuration2_s(engine_configuration_s *engineConfiguration, engine_configuration2_s *engineConfiguration2);
#endif /* EFI_SUPPORT_FORD_FIESTA */
#endif /* FORD_FIESTA_H_ */

View File

@ -0,0 +1,30 @@
/**
* @file honda_accord.c
*
* @date Jan 12, 2014
* @author Andrey Belomutskiy, (c) 2012-2014
*/
#include "main.h"
#include "engine_configuration.h"
#include "trigger_decoder.h"
void setHondaAccordConfiguration(engine_configuration_s *engineConfiguration) {
engineConfiguration->triggerConfig.totalToothCount = 24;
engineConfiguration->triggerConfig.skippedToothCount = 2;
}
void setHondaAccordConfiguration2(engine_configuration_s *engineConfiguration, engine_configuration2_s *engineConfiguration2) {
EventHandlerConfiguration *config = &engineConfiguration2->engineEventConfiguration;
float x = 10;
resetEventList(&config->ignitionEvents);
registerActuatorEvent(&config->ignitionEvents, 0, addOutputSignal(SPARKOUT_1_OUTPUT), x);
registerActuatorEvent(&config->ignitionEvents, 0, addOutputSignal(SPARKOUT_1_OUTPUT), x + 180);
registerActuatorEvent(&config->ignitionEvents, 0, addOutputSignal(SPARKOUT_1_OUTPUT), x + 360);
registerActuatorEvent(&config->ignitionEvents, 0, addOutputSignal(SPARKOUT_4_OUTPUT), x + 540);
}

View File

@ -0,0 +1,16 @@
/**
* @file honda_accord.h
*
* @date Jan 12, 2014
* @author Andrey Belomutskiy, (c) 2012-2013
*/
#ifndef HONDA_ACCORD_H_
#define HONDA_ACCORD_H_
#include "engine_configuration.h"
void setHondaAccordConfiguration(engine_configuration_s *engineConfiguration);
void setHondaAccordConfiguration2(engine_configuration_s *engineConfiguration, engine_configuration2_s *engineConfiguration2);
#endif /* HONDA_ACCORD_H_ */

View File

@ -0,0 +1,26 @@
/**
* @file mazda_323.c
*
* @date Mar 8, 2014
* @author Andrey Belomutskiy, (c) 2012-2013
*/
#include "mazda_323.h"
void setMazda323EngineConfiguration(engine_configuration_s *engineConfiguration) {
engineConfiguration->cylindersCount = 6;
engineConfiguration->ignitionMode = IM_ONE_COIL;
/**
* We treat the trigger as 4/0 toothed wheel
*/
engineConfiguration->triggerConfig.totalToothCount = 4;
engineConfiguration->triggerConfig.skippedToothCount = 0;
engineConfiguration->triggerConfig.isSynchronizationNeeded = FALSE;
}
void setMazda323configuration2_s(engine_configuration_s *engineConfiguration, engine_configuration2_s *engineConfiguration2) {
}

View File

@ -0,0 +1,22 @@
/**
* @file mazda_323.h
*
* 90-94 Mazda 323 (1.6l SOHC)
* 90-93 Ford Festiva (1.3l SOHC)
*
* http://rusefi.com/forum/viewtopic.php?f=3&t=498
*
* @date Mar 8, 2014
* @author Andrey Belomutskiy, (c) 2012-2013
*/
#ifndef MAZDA_323_H_
#define MAZDA_323_H_
#include "main.h"
#include "engine_configuration.h"
void setMazda323EngineConfiguration(engine_configuration_s *engineConfiguration);
void setMazda323configuration2_s(engine_configuration_s *engineConfiguration, engine_configuration2_s *engineConfiguration2);
#endif /* MAZDA_323_H_ */

View File

@ -0,0 +1,22 @@
/**
* @file mazda_miata_nb.c
*
* @date Feb 18, 2014
* @author Andrey Belomutskiy, (c) 2012-2014
*/
#include "mazda_miata_nb.h"
void setMazdaMiataNbEngineConfiguration(engine_configuration_s *engineConfiguration) {
engineConfiguration->triggerConfig.triggerType = TT_MAZDA_MIATA_NB;
engineConfiguration->triggerConfig.isSynchronizationNeeded = TRUE;
engineConfiguration->triggerConfig.syncRatioFrom = 0.11 * 0.7;
engineConfiguration->triggerConfig.syncRatioTo = 0.11 * 1.3;
engineConfiguration->triggerConfig.useRiseEdge = FALSE;
engineConfiguration->globalTriggerAngleOffset = 320;
}
void setMazdaMiataNb_configuration2_s(engine_configuration_s *engineConfiguration, engine_configuration2_s *engineConfiguration2) {
}

View File

@ -0,0 +1,17 @@
/**
* @file mazda_miata_nb.h
*
* @date Feb 18, 2014
* @author Andrey Belomutskiy, (c) 2012-2013
*/
#ifndef MAZDA_MIATA_NB_H_
#define MAZDA_MIATA_NB_H_
#include "main.h"
#include "engine_configuration.h"
void setMazdaMiataNbEngineConfiguration(engine_configuration_s *engineConfiguration);
void setMazdaMiataNb_configuration2_s(engine_configuration_s *engineConfiguration, engine_configuration2_s *engineConfiguration2);
#endif /* MAZDA_MIATA_NB_H_ */

View File

@ -0,0 +1,21 @@
/**
* @file nissan_primera.c
*
* @date Oct 14, 2013
* @author Andrey Belomutskiy, (c) 2012-2014
*/
#include "main.h"
#if EFI_SUPPORT_NISSAN_PRIMERA || defined(__DOXYGEN__)
#include "nissan_primera.h"
void setNissanPrimeraEngineConfiguration(engine_configuration_s *engineConfiguration) {
engineConfiguration->triggerConfig.totalToothCount = 60;
engineConfiguration->triggerConfig.skippedToothCount = 2;
}
void setNissanPrimeraengine_configuration2_s(engine_configuration_s *engineConfiguration, engine_configuration2_s *engineConfiguration2) {
}
#endif /* EFI_SUPPORT_NISSAN_PRIMERA */

View File

@ -0,0 +1,22 @@
/**
* @file nissan_primera.h
*
* @date Oct 14, 2013
* @author Andrey Belomutskiy, (c) 2012-2013
*/
#include "efifeatures.h"
#ifndef NISSAN_PRIMERA_H_
#define NISSAN_PRIMERA_H_
#if EFI_SUPPORT_NISSAN_PRIMERA
#include "engine_configuration.h"
void setNissanPrimeraEngineConfiguration(engine_configuration_s *engineConfiguration);
void setNissanPrimeraengine_configuration2_s(engine_configuration_s *engineConfiguration, engine_configuration2_s *engineConfiguration2);
#endif /* EFI_SUPPORT_NISSAN_PRIMERA */
#endif /* NISSAN_PRIMERA_H_ */

View File

@ -0,0 +1,49 @@
/**
* @file snow_blower.c
* @brief Default configuration of a single-cylinder engine
*
* @date Sep 9, 2013
* @author Andrey Belomutskiy, (c) 2012-2014
*/
#include "main.h"
#if EFI_ENGINE_SNOW_BLOWER
extern OutputSignal injectorOut1;
static Logging logger;
float getVRef(void) {
return 12;
}
float getFuelMs() {
return 1;
}
#define STROKE_TIME_CONSTANT2 (1000 * 60 * RPM_MULT * TICKS_IN_MS)
static int convertAngleToSysticks(int rpm, int advance) {
return (int) (advance * STROKE_TIME_CONSTANT2 / 360 / rpm);
}
static void onShaftSignal(int ckpSignalType) {
if (ckpSignalType != CKP_PRIMARY_DOWN)
return;
int offset = convertAngleToSysticks(getCurrentRpm(), 10);
scheduleOutput(&injectorOut1, offset, TICKS_IN_MS);
}
void initMainEventListener() {
initLogging(&logger, "main event handler", logger.DEFAULT_BUFFER, sizeof(logger.DEFAULT_BUFFER));
registerCkpListener(&onShaftSignal, "main loop");
}
#endif

View File

@ -0,0 +1,29 @@
/**
* @file snow_blower.h
* @brief Default configuration of a single-cylinder engine
* @date Sep 8, 2013
* @author Andrey Belomutskiy, (c) 2012-2013
*/
#ifndef SNOW_BLOWER_H_
#define SNOW_BLOWER_H_
#if EFI_ENGINE_SNOW_BLOWER
#define NUMBER_OF_CYLINDERS 1
#define EFI_ENGINE_ID "Snow Blower"
#define RPM_MULT (1)
#define getCoolantTemperature() 0
#define getIntakeAirTemperature() 0
#define getMaf() 0
#define getTPS() 0
#define getAfr() 0
#endif /* EFI_ENGINE_SNOW_BLOWER */
#endif /* SNOW_BLOWER_H_ */

View File

@ -0,0 +1,182 @@
/*
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
2011,2012,2013 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
ChibiOS/RT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
ChibiOS/RT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
---
A special exception to the GPL can be applied should you wish to distribute
a combined work that includes ChibiOS/RT, without being obliged to provide
the source code for any proprietary components. See the file exception.txt
for full details of how and when the exception can be applied.
*/
/*
* ST32F407xG memory setup.
*/
__main_stack_size__ = 0x0400;
__process_stack_size__ = 0x0400;
MEMORY
{
flash : org = 0x08000000, len = 1M
ram : org = 0x20000000, len = 112k
ethram : org = 0x2001C000, len = 16k
ccmram : org = 0x10000000, len = 64k
}
__ram_start__ = ORIGIN(ram);
__ram_size__ = LENGTH(ram);
__ram_end__ = __ram_start__ + __ram_size__;
ENTRY(ResetHandler)
SECTIONS
{
. = 0;
_text = .;
startup : ALIGN(16) SUBALIGN(16)
{
KEEP(*(vectors))
} > flash
constructors : ALIGN(4) SUBALIGN(4)
{
PROVIDE(__init_array_start = .);
KEEP(*(SORT(.init_array.*)))
KEEP(*(.init_array))
PROVIDE(__init_array_end = .);
} > flash
destructors : ALIGN(4) SUBALIGN(4)
{
PROVIDE(__fini_array_start = .);
KEEP(*(.fini_array))
KEEP(*(SORT(.fini_array.*)))
PROVIDE(__fini_array_end = .);
} > flash
.text : ALIGN(16) SUBALIGN(16)
{
*(.text.startup.*)
*(.text)
*(.text.*)
*(.rodata)
*(.rodata.*)
*(.glue_7t)
*(.glue_7)
*(.gcc*)
} > flash
.ARM.extab :
{
*(.ARM.extab* .gnu.linkonce.armextab.*)
} > flash
.ARM.exidx : {
PROVIDE(__exidx_start = .);
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
PROVIDE(__exidx_end = .);
} > flash
.eh_frame_hdr :
{
*(.eh_frame_hdr)
} > flash
.eh_frame : ONLY_IF_RO
{
*(.eh_frame)
} > flash
.textalign : ONLY_IF_RO
{
. = ALIGN(8);
} > flash
_etext = .;
_textdata = _etext;
.stacks :
{
. = ALIGN(8);
__main_stack_base__ = .;
. += __main_stack_size__;
. = ALIGN(8);
__main_stack_end__ = .;
__process_stack_base__ = .;
__main_thread_stack_base__ = .;
. += __process_stack_size__;
. = ALIGN(8);
__process_stack_end__ = .;
__main_thread_stack_end__ = .;
} > ram
.ccm :
{
PROVIDE(_cmm_start = .);
. = ALIGN(4);
*(.bss.mainthread.*)
. = ALIGN(4);
*(.bss._idle_thread_wa)
. = ALIGN(4);
*(.bss.rlist)
. = ALIGN(4);
*(.bss.vtlist)
. = ALIGN(4);
*(.bss.endmem)
. = ALIGN(4);
*(.bss.nextmem)
. = ALIGN(4);
*(.bss.default_heap)
. = ALIGN(4);
PROVIDE(_cmm_end = .);
} > ccmram
.data :
{
. = ALIGN(4);
PROVIDE(_data = .);
*(.data)
. = ALIGN(4);
*(.data.*)
. = ALIGN(4);
*(.ramtext)
. = ALIGN(4);
PROVIDE(_edata = .);
} > ram AT > flash
.bss :
{
. = ALIGN(4);
PROVIDE(_bss_start = .);
*(.bss)
. = ALIGN(4);
*(.bss.*)
. = ALIGN(4);
*(COMMON)
. = ALIGN(4);
PROVIDE(_bss_end = .);
} > ram
}
PROVIDE(end = .);
_end = .;
__heap_base__ = _end;
__heap_end__ = __ram_end__;

View File

@ -0,0 +1,563 @@
/*
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
2011,2012 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
ChibiOS/RT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
ChibiOS/RT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
---
A special exception to the GPL can be applied should you wish to distribute
a combined work that includes ChibiOS/RT, without being obliged to provide
the source code for any proprietary components. See the file exception.txt
for full details of how and when the exception can be applied.
*/
/**
* @file templates/chconf.h
* @brief Configuration file template.
* @details A copy of this file must be placed in each project directory, it
* contains the application specific kernel settings.
*
* @addtogroup config
* @details Kernel related settings and hooks.
* @{
*/
#ifndef _CHCONF_H_
#define _CHCONF_H_
#define CHPRINTF_USE_FLOAT TRUE
/**
* number of ticks per second
*
* 8000 rpm equals 133Hz of crankshaft
* that's 266Hz camshaft
* for timing measures we need 95760 Hz precision
*/
#define CH_FREQUENCY 100000
/*===========================================================================*/
/**
* @name Kernel parameters and options
* @{
*/
/*===========================================================================*/
/**
* @brief System tick frequency.
* @details Frequency of the system timer that drives the system ticks. This
* setting also defines the system tick time unit.
*/
#if !defined(CH_FREQUENCY) || defined(__DOXYGEN__)
#define CH_FREQUENCY 1000
#endif
/**
* @brief Round robin interval.
* @details This constant is the number of system ticks allowed for the
* threads before preemption occurs. Setting this value to zero
* disables the preemption for threads with equal priority and the
* round robin becomes cooperative. Note that higher priority
* threads can still preempt, the kernel is always preemptive.
*
* @note Disabling the round robin preemption makes the kernel more compact
* and generally faster.
*/
#if !defined(CH_TIME_QUANTUM) || defined(__DOXYGEN__)
#define CH_TIME_QUANTUM 20
#endif
/**
* @brief Managed RAM size.
* @details Size of the RAM area to be managed by the OS. If set to zero
* then the whole available RAM is used. The core memory is made
* available to the heap allocator and/or can be used directly through
* the simplified core memory allocator.
*
* @note In order to let the OS manage the whole RAM the linker script must
* provide the @p __heap_base__ and @p __heap_end__ symbols.
* @note Requires @p CH_USE_MEMCORE.
*/
#if !defined(CH_MEMCORE_SIZE) || defined(__DOXYGEN__)
#define CH_MEMCORE_SIZE 0
#endif
/**
* @brief Idle thread automatic spawn suppression.
* @details When this option is activated the function @p chSysInit()
* does not spawn the idle thread automatically. The application has
* then the responsibility to do one of the following:
* - Spawn a custom idle thread at priority @p IDLEPRIO.
* - Change the main() thread priority to @p IDLEPRIO then enter
* an endless loop. In this scenario the @p main() thread acts as
* the idle thread.
* .
* @note Unless an idle thread is spawned the @p main() thread must not
* enter a sleep state.
*/
#if !defined(CH_NO_IDLE_THREAD) || defined(__DOXYGEN__)
#define CH_NO_IDLE_THREAD FALSE
#endif
/** @} */
/*===========================================================================*/
/**
* @name Performance options
* @{
*/
/*===========================================================================*/
/**
* @brief OS optimization.
* @details If enabled then time efficient rather than space efficient code
* is used when two possible implementations exist.
*
* @note This is not related to the compiler optimization options.
* @note The default is @p TRUE.
*/
#if !defined(CH_OPTIMIZE_SPEED) || defined(__DOXYGEN__)
#define CH_OPTIMIZE_SPEED TRUE
#endif
/** @} */
/*===========================================================================*/
/**
* @name Subsystem options
* @{
*/
/*===========================================================================*/
/**
* @brief Threads registry APIs.
* @details If enabled then the registry APIs are included in the kernel.
*
* @note The default is @p TRUE.
*/
#if !defined(CH_USE_REGISTRY) || defined(__DOXYGEN__)
#define CH_USE_REGISTRY TRUE
#endif
/**
* @brief Threads synchronization APIs.
* @details If enabled then the @p chThdWait() function is included in
* the kernel.
*
* @note The default is @p TRUE.
*/
#if !defined(CH_USE_WAITEXIT) || defined(__DOXYGEN__)
#define CH_USE_WAITEXIT TRUE
#endif
/**
* @brief Semaphores APIs.
* @details If enabled then the Semaphores APIs are included in the kernel.
*
* @note The default is @p TRUE.
*/
#if !defined(CH_USE_SEMAPHORES) || defined(__DOXYGEN__)
#define CH_USE_SEMAPHORES TRUE
#endif
/**
* @brief Semaphores queuing mode.
* @details If enabled then the threads are enqueued on semaphores by
* priority rather than in FIFO order.
*
* @note The default is @p FALSE. Enable this if you have special requirements.
* @note Requires @p CH_USE_SEMAPHORES.
*/
#if !defined(CH_USE_SEMAPHORES_PRIORITY) || defined(__DOXYGEN__)
#define CH_USE_SEMAPHORES_PRIORITY FALSE
#endif
/**
* @brief Atomic semaphore API.
* @details If enabled then the semaphores the @p chSemSignalWait() API
* is included in the kernel.
*
* @note The default is @p TRUE.
* @note Requires @p CH_USE_SEMAPHORES.
*/
#if !defined(CH_USE_SEMSW) || defined(__DOXYGEN__)
#define CH_USE_SEMSW TRUE
#endif
/**
* @brief Mutexes APIs.
* @details If enabled then the mutexes APIs are included in the kernel.
*
* @note The default is @p TRUE.
*/
#if !defined(CH_USE_MUTEXES) || defined(__DOXYGEN__)
#define CH_USE_MUTEXES TRUE
#endif
/**
* @brief Conditional Variables APIs.
* @details If enabled then the conditional variables APIs are included
* in the kernel.
*
* @note The default is @p TRUE.
* @note Requires @p CH_USE_MUTEXES.
*/
#if !defined(CH_USE_CONDVARS) || defined(__DOXYGEN__)
#define CH_USE_CONDVARS TRUE
#endif
/**
* @brief Conditional Variables APIs with timeout.
* @details If enabled then the conditional variables APIs with timeout
* specification are included in the kernel.
*
* @note The default is @p TRUE.
* @note Requires @p CH_USE_CONDVARS.
*/
#if !defined(CH_USE_CONDVARS_TIMEOUT) || defined(__DOXYGEN__)
#define CH_USE_CONDVARS_TIMEOUT TRUE
#endif
/**
* @brief Events Flags APIs.
* @details If enabled then the event flags APIs are included in the kernel.
*
* @note The default is @p TRUE.
*/
#if !defined(CH_USE_EVENTS) || defined(__DOXYGEN__)
#define CH_USE_EVENTS TRUE
#endif
/**
* @brief Events Flags APIs with timeout.
* @details If enabled then the events APIs with timeout specification
* are included in the kernel.
*
* @note The default is @p TRUE.
* @note Requires @p CH_USE_EVENTS.
*/
#if !defined(CH_USE_EVENTS_TIMEOUT) || defined(__DOXYGEN__)
#define CH_USE_EVENTS_TIMEOUT TRUE
#endif
/**
* @brief Synchronous Messages APIs.
* @details If enabled then the synchronous messages APIs are included
* in the kernel.
*
* @note The default is @p TRUE.
*/
#if !defined(CH_USE_MESSAGES) || defined(__DOXYGEN__)
#define CH_USE_MESSAGES TRUE
#endif
/**
* @brief Synchronous Messages queuing mode.
* @details If enabled then messages are served by priority rather than in
* FIFO order.
*
* @note The default is @p FALSE. Enable this if you have special requirements.
* @note Requires @p CH_USE_MESSAGES.
*/
#if !defined(CH_USE_MESSAGES_PRIORITY) || defined(__DOXYGEN__)
#define CH_USE_MESSAGES_PRIORITY FALSE
#endif
/**
* @brief Mailboxes APIs.
* @details If enabled then the asynchronous messages (mailboxes) APIs are
* included in the kernel.
*
* @note The default is @p TRUE.
* @note Requires @p CH_USE_SEMAPHORES.
*/
#if !defined(CH_USE_MAILBOXES) || defined(__DOXYGEN__)
#define CH_USE_MAILBOXES TRUE
#endif
/**
* @brief I/O Queues APIs.
* @details If enabled then the I/O queues APIs are included in the kernel.
*
* @note The default is @p TRUE.
*/
#if !defined(CH_USE_QUEUES) || defined(__DOXYGEN__)
#define CH_USE_QUEUES TRUE
#endif
/**
* @brief Core Memory Manager APIs.
* @details If enabled then the core memory manager APIs are included
* in the kernel.
*
* @note The default is @p TRUE.
*/
#if !defined(CH_USE_MEMCORE) || defined(__DOXYGEN__)
#define CH_USE_MEMCORE TRUE
#endif
/**
* @brief Heap Allocator APIs.
* @details If enabled then the memory heap allocator APIs are included
* in the kernel.
*
* @note The default is @p TRUE.
* @note Requires @p CH_USE_MEMCORE and either @p CH_USE_MUTEXES or
* @p CH_USE_SEMAPHORES.
* @note Mutexes are recommended.
*/
#if !defined(CH_USE_HEAP) || defined(__DOXYGEN__)
#define CH_USE_HEAP TRUE
#endif
/**
* @brief C-runtime allocator.
* @details If enabled the the heap allocator APIs just wrap the C-runtime
* @p malloc() and @p free() functions.
*
* @note The default is @p FALSE.
* @note Requires @p CH_USE_HEAP.
* @note The C-runtime may or may not require @p CH_USE_MEMCORE, see the
* appropriate documentation.
*/
#if !defined(CH_USE_MALLOC_HEAP) || defined(__DOXYGEN__)
#define CH_USE_MALLOC_HEAP FALSE
#endif
/**
* @brief Memory Pools Allocator APIs.
* @details If enabled then the memory pools allocator APIs are included
* in the kernel.
*
* @note The default is @p TRUE.
*/
#if !defined(CH_USE_MEMPOOLS) || defined(__DOXYGEN__)
#define CH_USE_MEMPOOLS TRUE
#endif
/**
* @brief Dynamic Threads APIs.
* @details If enabled then the dynamic threads creation APIs are included
* in the kernel.
*
* @note The default is @p TRUE.
* @note Requires @p CH_USE_WAITEXIT.
* @note Requires @p CH_USE_HEAP and/or @p CH_USE_MEMPOOLS.
*/
#if !defined(CH_USE_DYNAMIC) || defined(__DOXYGEN__)
#define CH_USE_DYNAMIC TRUE
#endif
/** @} */
/*===========================================================================*/
/**
* @name Debug options
* @{
*/
/*===========================================================================*/
/**
* @brief Debug option, system state check.
* @details If enabled the correct call protocol for system APIs is checked
* at runtime.
*
* @note The default is @p FALSE.
*/
#if !defined(CH_DBG_SYSTEM_STATE_CHECK) || defined(__DOXYGEN__)
#define CH_DBG_SYSTEM_STATE_CHECK TRUE
#endif
/**
* @brief Debug option, parameters checks.
* @details If enabled then the checks on the API functions input
* parameters are activated.
*
* @note The default is @p FALSE.
*/
#if !defined(CH_DBG_ENABLE_CHECKS) || defined(__DOXYGEN__)
#define CH_DBG_ENABLE_CHECKS TRUE
#endif
/**
* @brief Debug option, consistency checks.
* @details If enabled then all the assertions in the kernel code are
* activated. This includes consistency checks inside the kernel,
* runtime anomalies and port-defined checks.
*
* @note The default is @p FALSE.
*/
#if !defined(CH_DBG_ENABLE_ASSERTS) || defined(__DOXYGEN__)
#define CH_DBG_ENABLE_ASSERTS TRUE
#endif
/**
* @brief Debug option, trace buffer.
* @details If enabled then the context switch circular trace buffer is
* activated.
*
* @note The default is @p FALSE.
*/
#if !defined(CH_DBG_ENABLE_TRACE) || defined(__DOXYGEN__)
#define CH_DBG_ENABLE_TRACE FALSE
#endif
/**
* @brief Debug option, stack checks.
* @details If enabled then a runtime stack check is performed.
*
* @note The default is @p FALSE.
* @note The stack check is performed in a architecture/port dependent way.
* It may not be implemented or some ports.
* @note The default failure mode is to halt the system with the global
* @p panic_msg variable set to @p NULL.
*/
#if !defined(CH_DBG_ENABLE_STACK_CHECK) || defined(__DOXYGEN__)
#define CH_DBG_ENABLE_STACK_CHECK TRUE
#endif
/**
* @brief Debug option, stacks initialization.
* @details If enabled then the threads working area is filled with a byte
* value when a thread is created. This can be useful for the
* runtime measurement of the used stack.
*
* @note The default is @p FALSE.
*/
#if !defined(CH_DBG_FILL_THREADS) || defined(__DOXYGEN__)
#define CH_DBG_FILL_THREADS FALSE
#endif
/**
* @brief Debug option, threads profiling.
* @details If enabled then a field is added to the @p Thread structure that
* counts the system ticks occurred while executing the thread.
*
* @note The default is @p TRUE.
* @note This debug option is defaulted to TRUE because it is required by
* some test cases into the test suite.
*/
#if !defined(CH_DBG_THREADS_PROFILING) || defined(__DOXYGEN__)
#define CH_DBG_THREADS_PROFILING TRUE
#endif
/** @} */
/*===========================================================================*/
/**
* @name Kernel hooks
* @{
*/
/*===========================================================================*/
/**
* @brief Threads descriptor structure extension.
* @details User fields added to the end of the @p Thread structure.
*/
#if !defined(THREAD_EXT_FIELDS) || defined(__DOXYGEN__)
#define THREAD_EXT_FIELDS \
/* Add threads custom fields here.*/
#endif
/**
* @brief Threads initialization hook.
* @details User initialization code added to the @p chThdInit() API.
*
* @note It is invoked from within @p chThdInit() and implicitly from all
* the threads creation APIs.
*/
#if !defined(THREAD_EXT_INIT_HOOK) || defined(__DOXYGEN__)
#define THREAD_EXT_INIT_HOOK(tp) { \
/* Add threads initialization code here.*/ \
}
#endif
/**
* @brief Threads finalization hook.
* @details User finalization code added to the @p chThdExit() API.
*
* @note It is inserted into lock zone.
* @note It is also invoked when the threads simply return in order to
* terminate.
*/
#if !defined(THREAD_EXT_EXIT_HOOK) || defined(__DOXYGEN__)
#define THREAD_EXT_EXIT_HOOK(tp) { \
/* Add threads finalization code here.*/ \
}
#endif
/**
* @brief Context switch hook.
* @details This hook is invoked just before switching between threads.
*/
#if !defined(THREAD_CONTEXT_SWITCH_HOOK) || defined(__DOXYGEN__)
#define THREAD_CONTEXT_SWITCH_HOOK(ntp, otp) { \
/* System halt code here.*/ \
}
#endif
/**
* @brief Idle Loop hook.
* @details This hook is continuously invoked by the idle thread loop.
*/
#if !defined(IDLE_LOOP_HOOK) || defined(__DOXYGEN__)
#define IDLE_LOOP_HOOK() { \
/* Idle loop code here.*/ \
}
#endif
/**
* @brief System tick event hook.
* @details This hook is invoked in the system tick handler immediately
* after processing the virtual timers queue.
*/
#if !defined(SYSTEM_TICK_EVENT_HOOK) || defined(__DOXYGEN__)
#define SYSTEM_TICK_EVENT_HOOK() { \
/* System tick event code here.*/ \
}
#endif
/**
* @brief System halt hook.
* @details This hook is invoked in case to a system halting error before
* the system is halted.
*/
#if !defined(SYSTEM_HALT_HOOK) || defined(__DOXYGEN__)
#if CH_DBG_ENABLED
#define SYSTEM_HALT_HOOK() { \
print("FATAL %s\r\n", dbg_panic_msg); \
chThdSleepMilliseconds(100); \
/* System halt code here.*/ \
}
#endif
#endif
/** @} */
/*===========================================================================*/
/* Port-specific settings (override port settings defaulted in chcore.h). */
/*===========================================================================*/
#define CORTEX_USE_FPU TRUE
#endif /* _CHCONF_H_ */
/** @} */

View File

@ -0,0 +1,349 @@
/*
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
2011,2012 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
ChibiOS/RT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
ChibiOS/RT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
---
A special exception to the GPL can be applied should you wish to distribute
a combined work that includes ChibiOS/RT, without being obliged to provide
the source code for any proprietary components. See the file exception.txt
for full details of how and when the exception can be applied.
*/
/**
* @file templates/halconf.h
* @brief HAL configuration header.
* @details HAL configuration file, this file allows to enable or disable the
* various device drivers from your application. You may also use
* this file in order to override the device drivers default settings.
*
* @addtogroup HAL_CONF
* @{
*/
#ifndef _HALCONF_H_
#define _HALCONF_H_
#include "mcuconf.h"
/**
* @brief Enables the TM subsystem.
*/
#if !defined(HAL_USE_TM) || defined(__DOXYGEN__)
#define HAL_USE_TM FALSE
#endif
/**
* @brief Enables the PAL subsystem.
*/
#if !defined(HAL_USE_PAL) || defined(__DOXYGEN__)
#define HAL_USE_PAL TRUE
#endif
/**
* @brief Enables the ADC subsystem.
*/
#if !defined(HAL_USE_ADC) || defined(__DOXYGEN__)
#define HAL_USE_ADC TRUE
#endif
/**
* @brief Enables the CAN subsystem.
*/
#if !defined(HAL_USE_CAN) || defined(__DOXYGEN__)
#define HAL_USE_CAN TRUE
#endif
/**
* @brief Enables the EXT subsystem.
*/
#if !defined(HAL_USE_EXT) || defined(__DOXYGEN__)
#define HAL_USE_EXT FALSE
#endif
/**
* @brief Enables the GPT subsystem.
*/
#if !defined(HAL_USE_GPT) || defined(__DOXYGEN__)
#define HAL_USE_GPT FALSE
#endif
/**
* @brief Enables the I2C subsystem.
*/
#if !defined(HAL_USE_I2C) || defined(__DOXYGEN__)
#define HAL_USE_I2C TRUE
#endif
/**
* @brief Enables the ICU subsystem.
*/
#if !defined(HAL_USE_ICU) || defined(__DOXYGEN__)
#define HAL_USE_ICU TRUE
#endif
/**
* @brief Enables the MAC subsystem.
*/
#if !defined(HAL_USE_MAC) || defined(__DOXYGEN__)
#define HAL_USE_MAC FALSE
#endif
/**
* @brief Enables the MMC_SPI subsystem.
*/
#if !defined(HAL_USE_MMC_SPI) || defined(__DOXYGEN__)
#define HAL_USE_MMC_SPI TRUE
#endif
/**
* @brief Enables the PWM subsystem.
*/
#if !defined(HAL_USE_PWM) || defined(__DOXYGEN__)
#define HAL_USE_PWM TRUE
#endif
/**
* @brief Enables the RTC subsystem.
*/
#if !defined(HAL_USE_RTC) || defined(__DOXYGEN__)
#define HAL_USE_RTC TRUE
#endif
/**
* @brief Enables the SDC subsystem.
*/
#if !defined(HAL_USE_SDC) || defined(__DOXYGEN__)
#define HAL_USE_SDC FALSE
#endif
/**
* @brief Enables the SERIAL subsystem.
*/
#if !defined(HAL_USE_SERIAL) || defined(__DOXYGEN__)
#define HAL_USE_SERIAL TRUE
#endif
/**
* @brief Enables the SERIAL over USB subsystem.
*/
#if !defined(HAL_USE_SERIAL_USB) || defined(__DOXYGEN__)
#define HAL_USE_SERIAL_USB TRUE
#endif
/**
* @brief Enables the SPI subsystem.
*/
#if !defined(HAL_USE_SPI) || defined(__DOXYGEN__)
#define HAL_USE_SPI TRUE
#endif
/**
* @brief Enables the UART subsystem.
*/
#if !defined(HAL_USE_UART) || defined(__DOXYGEN__)
#define HAL_USE_UART FALSE
#endif
/**
* @brief Enables the USB subsystem.
*/
#if !defined(HAL_USE_USB) || defined(__DOXYGEN__)
#define HAL_USE_USB TRUE
#endif
/*===========================================================================*/
/* ADC driver related settings. */
/*===========================================================================*/
/**
* @brief Enables synchronous APIs.
* @note Disabling this option saves both code and data space.
*/
#if !defined(ADC_USE_WAIT) || defined(__DOXYGEN__)
#define ADC_USE_WAIT TRUE
#endif
/**
* @brief Enables the @p adcAcquireBus() and @p adcReleaseBus() APIs.
* @note Disabling this option saves both code and data space.
*/
#if !defined(ADC_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__)
#define ADC_USE_MUTUAL_EXCLUSION TRUE
#endif
/*===========================================================================*/
/* CAN driver related settings. */
/*===========================================================================*/
/**
* @brief Sleep mode related APIs inclusion switch.
*/
#if !defined(CAN_USE_SLEEP_MODE) || defined(__DOXYGEN__)
#define CAN_USE_SLEEP_MODE TRUE
#endif
/*===========================================================================*/
/* I2C driver related settings. */
/*===========================================================================*/
/**
* @brief Enables the mutual exclusion APIs on the I2C bus.
*/
#if !defined(I2C_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__)
#define I2C_USE_MUTUAL_EXCLUSION TRUE
#endif
/*===========================================================================*/
/* MAC driver related settings. */
/*===========================================================================*/
/**
* @brief Enables an event sources for incoming packets.
*/
#if !defined(MAC_USE_EVENTS) || defined(__DOXYGEN__)
#define MAC_USE_EVENTS TRUE
#endif
/*===========================================================================*/
/* MMC_SPI driver related settings. */
/*===========================================================================*/
/**
* @brief Block size for MMC transfers.
*/
#if !defined(MMC_SECTOR_SIZE) || defined(__DOXYGEN__)
#define MMC_SECTOR_SIZE 512
#endif
/**
* @brief Delays insertions.
* @details If enabled this options inserts delays into the MMC waiting
* routines releasing some extra CPU time for the threads with
* lower priority, this may slow down the driver a bit however.
* This option is recommended also if the SPI driver does not
* use a DMA channel and heavily loads the CPU.
*/
#if !defined(MMC_NICE_WAITING) || defined(__DOXYGEN__)
#define MMC_NICE_WAITING TRUE
#endif
/**
* @brief Number of positive insertion queries before generating the
* insertion event.
*/
#if !defined(MMC_POLLING_INTERVAL) || defined(__DOXYGEN__)
#define MMC_POLLING_INTERVAL 10
#endif
/**
* @brief Interval, in milliseconds, between insertion queries.
*/
#if !defined(MMC_POLLING_DELAY) || defined(__DOXYGEN__)
#define MMC_POLLING_DELAY 10
#endif
/**
* @brief Uses the SPI polled API for small data transfers.
* @details Polled transfers usually improve performance because it
* saves two context switches and interrupt servicing. Note
* that this option has no effect on large transfers which
* are always performed using DMAs/IRQs.
*/
#if !defined(MMC_USE_SPI_POLLING) || defined(__DOXYGEN__)
#define MMC_USE_SPI_POLLING TRUE
#endif
/*===========================================================================*/
/* SDC driver related settings. */
/*===========================================================================*/
/**
* @brief Number of initialization attempts before rejecting the card.
* @note Attempts are performed at 10mS intervals.
*/
#if !defined(SDC_INIT_RETRY) || defined(__DOXYGEN__)
#define SDC_INIT_RETRY 100
#endif
/**
* @brief Include support for MMC cards.
* @note MMC support is not yet implemented so this option must be kept
* at @p FALSE.
*/
#if !defined(SDC_MMC_SUPPORT) || defined(__DOXYGEN__)
#define SDC_MMC_SUPPORT FALSE
#endif
/**
* @brief Delays insertions.
* @details If enabled this options inserts delays into the MMC waiting
* routines releasing some extra CPU time for the threads with
* lower priority, this may slow down the driver a bit however.
*/
#if !defined(SDC_NICE_WAITING) || defined(__DOXYGEN__)
#define SDC_NICE_WAITING TRUE
#endif
/*===========================================================================*/
/* SERIAL driver related settings. */
/*===========================================================================*/
/**
* @brief Default bit rate.
* @details Configuration parameter, this is the baud rate selected for the
* default configuration.
*/
#if !defined(SERIAL_DEFAULT_BITRATE) || defined(__DOXYGEN__)
#define SERIAL_DEFAULT_BITRATE 38400
#endif
/**
* @brief Serial buffers size.
* @details Configuration parameter, you can change the depth of the queue
* buffers depending on the requirements of your application.
* @note The default is 64 bytes for both the transmission and receive
* buffers.
*/
#if !defined(SERIAL_BUFFERS_SIZE) || defined(__DOXYGEN__)
#define SERIAL_BUFFERS_SIZE 16
#endif
/*===========================================================================*/
/* SPI driver related settings. */
/*===========================================================================*/
/**
* @brief Enables synchronous APIs.
* @note Disabling this option saves both code and data space.
*/
#if !defined(SPI_USE_WAIT) || defined(__DOXYGEN__)
#define SPI_USE_WAIT TRUE
#endif
/**
* @brief Enables the @p spiAcquireBus() and @p spiReleaseBus() APIs.
* @note Disabling this option saves both code and data space.
*/
#if !defined(SPI_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__)
#define SPI_USE_MUTUAL_EXCLUSION TRUE
#endif
#endif /* _HALCONF_H_ */
/** @} */

View File

@ -0,0 +1,263 @@
/*
ChibiOS/RT - Copyright (C) 2006-2013 Giovanni Di Sirio
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
* STM32F4xx drivers configuration.
* The following settings override the default settings present in
* the various device driver implementation headers.
* Note that the settings for each driver only have effect if the whole
* driver is enabled in halconf.h.
*
* IRQ priorities:
* 15...0 Lowest...Highest.
*
* DMA priorities:
* 0...3 Lowest...Highest.
*/
#define STM32F4xx_MCUCONF
#include "engines.h"
/*
* HAL driver system settings.
*/
#define STM32_NO_INIT FALSE
#define STM32_HSI_ENABLED TRUE
#define STM32_LSI_ENABLED TRUE
#define STM32_HSE_ENABLED TRUE
#define STM32_LSE_ENABLED FALSE
#define STM32_CLOCK48_REQUIRED TRUE
#define STM32_SW STM32_SW_PLL
#define STM32_PLLSRC STM32_PLLSRC_HSE
#ifdef OLIMEX_STM32_E407
#define STM32_PLLM_VALUE 12
#else
#define STM32_PLLM_VALUE 8
#endif
#define STM32_PLLN_VALUE 336
#define STM32_PLLP_VALUE 2
#define STM32_PLLQ_VALUE 7
#define STM32_HPRE STM32_HPRE_DIV1
#define STM32_PPRE1 STM32_PPRE1_DIV4
#define STM32_PPRE2 STM32_PPRE2_DIV2
#define STM32_RTCSEL STM32_RTCSEL_LSI
#define STM32_RTCPRE_VALUE 8
#define STM32_MCO1SEL STM32_MCO1SEL_HSI
#define STM32_MCO1PRE STM32_MCO1PRE_DIV1
#define STM32_MCO2SEL STM32_MCO2SEL_SYSCLK
#define STM32_MCO2PRE STM32_MCO2PRE_DIV5
#define STM32_I2SSRC STM32_I2SSRC_CKIN
#define STM32_PLLI2SN_VALUE 192
#define STM32_PLLI2SR_VALUE 5
#define STM32_VOS STM32_VOS_HIGH
#define STM32_PVD_ENABLE FALSE
#define STM32_PLS STM32_PLS_LEV0
/*
* ADC driver system settings.
*/
#define STM32_ADC_ADCPRE ADC_CCR_ADCPRE_DIV4
#define STM32_ADC_USE_ADC1 TRUE // slow ADC
#define STM32_ADC_USE_ADC2 TRUE // fast ADC
#define STM32_ADC_USE_ADC3 FALSE
#define STM32_ADC_ADC1_DMA_STREAM STM32_DMA_STREAM_ID(2, 4)
#define STM32_ADC_ADC2_DMA_STREAM STM32_DMA_STREAM_ID(2, 2)
#define STM32_ADC_ADC3_DMA_STREAM STM32_DMA_STREAM_ID(2, 1)
#define STM32_ADC_ADC1_DMA_PRIORITY 2
#define STM32_ADC_ADC2_DMA_PRIORITY 2
#define STM32_ADC_ADC3_DMA_PRIORITY 2
#define STM32_ADC_IRQ_PRIORITY 6
#define STM32_ADC_ADC1_DMA_IRQ_PRIORITY 6
#define STM32_ADC_ADC2_DMA_IRQ_PRIORITY 6
#define STM32_ADC_ADC3_DMA_IRQ_PRIORITY 6
/*
* CAN driver system settings.
*/
#define STM32_CAN_CAN1_IRQ_PRIORITY 11
#define STM32_CAN_CAN2_IRQ_PRIORITY 11
/*
* EXT driver system settings.
*/
#define STM32_EXT_EXTI0_IRQ_PRIORITY 6
#define STM32_EXT_EXTI1_IRQ_PRIORITY 6
#define STM32_EXT_EXTI2_IRQ_PRIORITY 6
#define STM32_EXT_EXTI3_IRQ_PRIORITY 6
#define STM32_EXT_EXTI4_IRQ_PRIORITY 6
#define STM32_EXT_EXTI5_9_IRQ_PRIORITY 6
#define STM32_EXT_EXTI10_15_IRQ_PRIORITY 6
#define STM32_EXT_EXTI16_IRQ_PRIORITY 6
#define STM32_EXT_EXTI17_IRQ_PRIORITY 15
#define STM32_EXT_EXTI18_IRQ_PRIORITY 6
#define STM32_EXT_EXTI19_IRQ_PRIORITY 6
#define STM32_EXT_EXTI20_IRQ_PRIORITY 6
#define STM32_EXT_EXTI21_IRQ_PRIORITY 15
#define STM32_EXT_EXTI22_IRQ_PRIORITY 15
/*
* GPT driver system settings.
*/
#define STM32_GPT_USE_TIM1 FALSE
#define STM32_GPT_USE_TIM2 FALSE
#define STM32_GPT_USE_TIM3 FALSE
#define STM32_GPT_USE_TIM4 FALSE
#define STM32_GPT_USE_TIM5 FALSE
#define STM32_GPT_USE_TIM6 FALSE
#define STM32_GPT_USE_TIM7 FALSE
#define STM32_GPT_USE_TIM8 FALSE
#define STM32_GPT_USE_TIM9 FALSE
#define STM32_GPT_USE_TIM11 FALSE
#define STM32_GPT_USE_TIM12 FALSE
#define STM32_GPT_USE_TIM14 FALSE
#define STM32_GPT_TIM1_IRQ_PRIORITY 7
#define STM32_GPT_TIM2_IRQ_PRIORITY 7
#define STM32_GPT_TIM3_IRQ_PRIORITY 7
#define STM32_GPT_TIM4_IRQ_PRIORITY 7
#define STM32_GPT_TIM5_IRQ_PRIORITY 7
#define STM32_GPT_TIM6_IRQ_PRIORITY 7
#define STM32_GPT_TIM7_IRQ_PRIORITY 7
#define STM32_GPT_TIM8_IRQ_PRIORITY 7
#define STM32_GPT_TIM9_IRQ_PRIORITY 7
#define STM32_GPT_TIM11_IRQ_PRIORITY 7
#define STM32_GPT_TIM12_IRQ_PRIORITY 7
#define STM32_GPT_TIM14_IRQ_PRIORITY 7
/*
* I2C driver system settings.
*/
#define STM32_I2C_USE_I2C1 TRUE
#define STM32_I2C_USE_I2C2 FALSE
#define STM32_I2C_USE_I2C3 FALSE
#define STM32_I2C_I2C2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 2)
#define STM32_I2C_I2C2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 7)
#define STM32_I2C_I2C3_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 2)
#define STM32_I2C_I2C3_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4)
#define STM32_I2C_I2C1_IRQ_PRIORITY 5
#define STM32_I2C_I2C2_IRQ_PRIORITY 5
#define STM32_I2C_I2C3_IRQ_PRIORITY 5
#define STM32_I2C_I2C1_DMA_PRIORITY 3
#define STM32_I2C_I2C2_DMA_PRIORITY 3
#define STM32_I2C_I2C3_DMA_PRIORITY 3
#define STM32_I2C_I2C1_DMA_ERROR_HOOK() chSysHalt()
#define STM32_I2C_I2C2_DMA_ERROR_HOOK() chSysHalt()
#define STM32_I2C_I2C3_DMA_ERROR_HOOK() chSysHalt()
/*
* ICU driver system settings.
*/
#define STM32_ICU_TIM1_IRQ_PRIORITY 7
#define STM32_ICU_TIM2_IRQ_PRIORITY 7
#define STM32_ICU_TIM3_IRQ_PRIORITY 7
#define STM32_ICU_TIM4_IRQ_PRIORITY 7
#define STM32_ICU_TIM5_IRQ_PRIORITY 7
#define STM32_ICU_TIM8_IRQ_PRIORITY 7
#define STM32_ICU_TIM9_IRQ_PRIORITY 7
/*
* MAC driver system settings.
*/
#define STM32_MAC_TRANSMIT_BUFFERS 2
#define STM32_MAC_RECEIVE_BUFFERS 4
#define STM32_MAC_BUFFERS_SIZE 1522
#define STM32_MAC_PHY_TIMEOUT 100
#define STM32_MAC_ETH1_CHANGE_PHY_STATE TRUE
#define STM32_MAC_ETH1_IRQ_PRIORITY 13
#define STM32_MAC_IP_CHECKSUM_OFFLOAD 0
/*
* PWM driver system settings.
*/
#define STM32_PWM_USE_ADVANCED FALSE
#define STM32_PWM_TIM1_IRQ_PRIORITY 7
#define STM32_PWM_TIM2_IRQ_PRIORITY 7
#define STM32_PWM_TIM3_IRQ_PRIORITY 7
#define STM32_PWM_TIM4_IRQ_PRIORITY 7
#define STM32_PWM_TIM5_IRQ_PRIORITY 7
#define STM32_PWM_TIM8_IRQ_PRIORITY 7
#define STM32_PWM_TIM9_IRQ_PRIORITY 7
/*
* SERIAL driver system settings.
*/
#define STM32_SERIAL_USE_USART1 TRUE
#define STM32_SERIAL_USE_USART2 TRUE
#define STM32_SERIAL_USE_USART3 TRUE
#define STM32_SERIAL_USE_UART4 FALSE
#define STM32_SERIAL_USE_UART5 FALSE
#define STM32_SERIAL_USE_USART6 FALSE
#define STM32_SERIAL_USART1_PRIORITY 12
#define STM32_SERIAL_USART2_PRIORITY 12
#define STM32_SERIAL_USART3_PRIORITY 12
#define STM32_SERIAL_UART4_PRIORITY 12
#define STM32_SERIAL_UART5_PRIORITY 12
#define STM32_SERIAL_USART6_PRIORITY 12
/*
* SPI driver system settings.
*/
#define STM32_SPI_SPI1_RX_DMA_STREAM STM32_DMA_STREAM_ID(2, 0)
#define STM32_SPI_SPI1_TX_DMA_STREAM STM32_DMA_STREAM_ID(2, 3)
#define STM32_SPI_SPI2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 3)
#define STM32_SPI_SPI2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4)
#define STM32_SPI_SPI3_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 0)
#define STM32_SPI_SPI3_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 7)
#define STM32_SPI_SPI1_DMA_PRIORITY 1
#define STM32_SPI_SPI2_DMA_PRIORITY 1
#define STM32_SPI_SPI3_DMA_PRIORITY 1
#define STM32_SPI_SPI1_IRQ_PRIORITY 10
#define STM32_SPI_SPI2_IRQ_PRIORITY 10
#define STM32_SPI_SPI3_IRQ_PRIORITY 10
#define STM32_SPI_DMA_ERROR_HOOK(spip) chDbgCheck(TRUE, "STM32_SPI_DMA_ERROR_HOOK")
/*
* UART driver system settings.
*/
#define STM32_UART_USE_USART1 FALSE
#define STM32_UART_USE_USART2 FALSE
#define STM32_UART_USE_USART3 TRUE
#define STM32_UART_USE_USART6 FALSE
#define STM32_UART_USART1_RX_DMA_STREAM STM32_DMA_STREAM_ID(2, 5)
#define STM32_UART_USART1_TX_DMA_STREAM STM32_DMA_STREAM_ID(2, 7)
#define STM32_UART_USART2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5)
#define STM32_UART_USART2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 6)
#define STM32_UART_USART3_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 1)
#define STM32_UART_USART3_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 3)
#define STM32_UART_USART6_RX_DMA_STREAM STM32_DMA_STREAM_ID(2, 2)
#define STM32_UART_USART6_TX_DMA_STREAM STM32_DMA_STREAM_ID(2, 7)
#define STM32_UART_USART1_IRQ_PRIORITY 12
#define STM32_UART_USART2_IRQ_PRIORITY 12
#define STM32_UART_USART3_IRQ_PRIORITY 12
#define STM32_UART_USART6_IRQ_PRIORITY 12
#define STM32_UART_USART1_DMA_PRIORITY 0
#define STM32_UART_USART2_DMA_PRIORITY 0
#define STM32_UART_USART3_DMA_PRIORITY 0
#define STM32_UART_USART6_DMA_PRIORITY 0
#define STM32_UART_DMA_ERROR_HOOK(uartp) chSysHalt()
/*
* USB driver system settings.
*/
#define STM32_USB_USE_OTG1 TRUE
#define STM32_USB_USE_OTG2 FALSE
#define STM32_USB_OTG1_IRQ_PRIORITY 14
#define STM32_USB_OTG2_IRQ_PRIORITY 14
#define STM32_USB_OTG1_RX_FIFO_SIZE 512
#define STM32_USB_OTG2_RX_FIFO_SIZE 1024
#define STM32_USB_OTG_THREAD_PRIO LOWPRIO
#define STM32_USB_OTG_THREAD_STACK_SIZE 1024
#define STM32_USB_OTGFIFO_FILL_BASEPRI 0

View File

@ -0,0 +1,4 @@
CONSOLESRC = $(PROJECT_DIR)/console/eficonsole.c \
$(PROJECT_DIR)/console/console_io.c \
$(PROJECT_DIR)/console/status_loop.c

View File

@ -0,0 +1,172 @@
/**
* @file console_io.c
*
* @date Dec 29, 2012
* @author Andrey Belomutskiy, (c) 2012-2014
*
* This file is part of rusEfi - see http://rusefi.com
*
* rusEfi is free software; you can redistribute it and/or modify it under the terms of
* the GNU General Public License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* rusEfi is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
* even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program.
* If not, see <http://www.gnu.org/licenses/>.
*/
#include "main.h"
#include "console_io.h"
#if EFI_PROD_CODE
#include "usbconsole.h"
#endif
#include "rfiutil.h"
/**
* @brief Reads a whole line from the input channel.
*
* @param[in] chp pointer to a @p BaseChannel object
* @param[in] line pointer to the line buffer
* @param[in] size buffer maximum length
* @return The operation status.
* @retval TRUE the channel was reset or CTRL-D pressed.
* @retval FALSE operation successful.
*/
static bool_t getConsoleLine(BaseSequentialStream *chp, char *line, unsigned size) {
char *p = line;
while (TRUE) {
if (!is_serial_ready()) {
// we better do not read from USB serial before it is ready
chThdSleepMilliseconds(10);
continue;
}
short c = (short) chSequentialStreamGet(chp);
if (c < 0)
return TRUE;
if (c == 4) {
return TRUE;
}
if (c == 8) {
if (p != line) {
// backspace
consolePutChar((uint8_t) c);
consolePutChar(0x20);
consolePutChar((uint8_t) c);
p--;
}
continue;
}
if (c == '\r') {
consolePutChar('\r');
consolePutChar('\n');
*p = 0;
return FALSE;
}
if (c < 0x20)
continue;
if (p < line + size - 1) {
consolePutChar((uint8_t) c);
*p++ = (char) c;
}
}
}
// todo: this is ugly as hell!
static char consoleInput[] = " ";
void (*console_line_callback)(char *);
static WORKING_AREA(consoleThreadStack, 2 * UTILITY_THREAD_STACK_SIZE);
static msg_t consoleThreadThreadEntryPoint(void *arg) {
(void) arg;
chRegSetThreadName("console thread");
while (TRUE) {
bool_t end = getConsoleLine((BaseSequentialStream *) CONSOLE_CHANNEL, consoleInput, sizeof(consoleInput));
if (end) {
// firmware simulator is the only case when this happens
continue;
}
(console_line_callback)(consoleInput);
}
return FALSE;
}
#if EFI_SERIAL_OVER_USB
#else
#if EFI_SERIAL_OVER_UART
static SerialConfig serialConfig = { SERIAL_SPEED, 0, USART_CR2_STOP1_BITS | USART_CR2_LINEN, 0 };
#endif /* EFI_SERIAL_OVER_UART */
#endif /* EFI_SERIAL_OVER_USB */
#if ! defined EFI_SERIAL_OVER_USB && ! EFI_SIMULATOR
int is_serial_ready(void) {
return TRUE;
}
#endif
void consolePutChar(int x) {
chSequentialStreamPut(CONSOLE_CHANNEL, (uint8_t )(x));
}
void consoleOutputBuffer(const int8_t *buf, int size) {
chSequentialStreamWrite(CONSOLE_CHANNEL, buf, size);
}
void startChibiosConsole(void (*console_line_callback_p)(char *)) {
console_line_callback = console_line_callback_p;
#if EFI_SERIAL_OVER_USB
usb_serial_start();
#else
#if EFI_SERIAL_OVER_UART
/*
* Activates the serial using the driver default configuration (that's 38400)
* it is important to set 'NONE' as flow control! in terminal application on the PC
*/
sdStart(CONSOLE_CHANNEL, &serialConfig);
// cannot use pin repository here because pin repository prints to console
palSetPadMode(EFI_CONSOLE_RX_PORT, EFI_CONSOLE_RX_PIN, PAL_MODE_ALTERNATE(EFI_CONSOLE_AF));
palSetPadMode(EFI_CONSOLE_TX_PORT, EFI_CONSOLE_TX_PIN, PAL_MODE_ALTERNATE(EFI_CONSOLE_AF));
#endif /* EFI_SERIAL_OVER_UART */
#endif /* EFI_SERIAL_OVER_USB */
chThdCreateStatic(consoleThreadStack, sizeof(consoleThreadStack), NORMALPRIO, consoleThreadThreadEntryPoint, NULL);
}
extern cnt_t dbg_isr_cnt;
void lockAnyContext(void) {
if (isIsrContext()) {
chSysLockFromIsr()
;
} else {
chSysLock()
;
}
}
void lockOutputBuffer(void) {
lockAnyContext();
}
void unlockAnyContext(void) {
if (isIsrContext()) {
chSysUnlockFromIsr()
;
} else {
chSysUnlock()
;
}
}
void unlockOutputBuffer(void) {
unlockAnyContext();
}

View File

@ -0,0 +1,37 @@
/**
* @file console_io.h
*
* @date Dec 29, 2012
* @author Andrey Belomutskiy, (c) 2012-2013
*/
#pragma once
#ifndef CONSOLE_IO_H_
#define CONSOLE_IO_H_
#include <ch.h>
#include <hal.h>
#ifndef TRUE
#define TRUE 1
#endif
#ifndef FALSE
#define FALSE 0
#endif
#include "efifeatures.h"
#include "boards.h"
#if EFI_SERIAL_OVER_USB
#include "usbcfg.h"
extern SerialUSBDriver SDU1;
#define CONSOLE_CHANNEL (&SDU1)
#else
#define CONSOLE_CHANNEL EFI_CONSOLE_UART_DEVICE
#endif
void consolePutChar(int x);
void consoleOutputBuffer(const int8_t *buf, int size);
void startChibiosConsole(void (*console_line_callback_p)(char *));
int is_serial_ready(void);
#endif /* CONSOLE_IO_H_ */

View File

@ -0,0 +1,163 @@
/**
* @file eficonsole.c
* @brief Console package entry point code
*
*
* @date Nov 15, 2012
* @author Andrey Belomutskiy, (c) 2012-2014
*
*
* This file is part of rusEfi - see http://rusefi.com
*
* rusEfi is free software; you can redistribute it and/or modify it under the terms of
* the GNU General Public License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* rusEfi is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
* even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program.
* If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdarg.h>
#include <stdbool.h>
#include "main.h"
#include <chprintf.h>
#include "eficonsole.h"
#include "console_io.h"
#include "rusefi.h"
static Logging logger;
static char fatalErrorMessage[200];
void fatal3(char *msg, char *file, int line) {
strcpy(fatalErrorMessage, msg);
#if EFI_CUSTOM_PANIC_METHOD
chDbgPanic(fatalErrorMessage, file, line);
#else
chDbgPanic(fatalErrorMessage);
#endif
}
static void myfatal(void) {
chDbgCheck(0, "my fatal");
}
static void sayHello(void) {
print("*** rusEFI (c) Andrey Belomutskiy, 2012-2014. All rights reserved.\r\n");
printMsg(&logger, "rusEFI VERSION=%d", getVersion());
print("*** Chibios Kernel: %s\r\n", CH_KERNEL_VERSION);
print("*** Compiled: " __DATE__ " - " __TIME__ " \r\n");
print("COMPILER=%s\r\n", __VERSION__);
printMsg(&logger, "CH_FREQUENCY=%d", CH_FREQUENCY);
#ifdef SERIAL_SPEED
printMsg(&logger, "SERIAL_SPEED=%d", SERIAL_SPEED);
#endif
#ifdef STM32_ADCCLK
printMsg(&logger, "STM32_ADCCLK=%d", STM32_ADCCLK);
printMsg(&logger, "STM32_TIMCLK1=%d", STM32_TIMCLK1);
printMsg(&logger, "STM32_TIMCLK2=%d", STM32_TIMCLK2);
printMsg(&logger, "STM32_PCLK1=%d", STM32_PCLK1);
printMsg(&logger, "STM32_PCLK2=%d", STM32_PCLK2);
#endif
printMsg(&logger, "CH_DBG_ENABLE_ASSERTS=%d", CH_DBG_ENABLE_ASSERTS);
printMsg(&logger, "CH_DBG_ENABLED=%d", CH_DBG_ENABLED);
printMsg(&logger, "CH_DBG_SYSTEM_STATE_CHECK=%d", CH_DBG_SYSTEM_STATE_CHECK);
printMsg(&logger, "CH_DBG_ENABLE_STACK_CHECK=%d", CH_DBG_ENABLE_STACK_CHECK);
#ifdef EFI_WAVE_ANALYZER
printMsg(&logger, "EFI_WAVE_ANALYZER=%d", EFI_WAVE_ANALYZER);
#endif
#ifdef EFI_TUNER_STUDIO
printMsg(&logger, "EFI_TUNER_STUDIO=%d", EFI_TUNER_STUDIO);
#else
printMsg(&logger, "EFI_TUNER_STUDIO=%d", 0);
#endif
#ifdef EFI_SIGNAL_EXECUTOR_SLEEP
printMsg(&logger, "EFI_SIGNAL_EXECUTOR_SLEEP=%d", EFI_SIGNAL_EXECUTOR_SLEEP);
#endif
#ifdef EFI_SIGNAL_EXECUTOR_HW_TIMER
printMsg(&logger, "EFI_SIGNAL_EXECUTOR_HW_TIMER=%d", EFI_SIGNAL_EXECUTOR_HW_TIMER);
#endif
#ifdef EFI_TUNER_STUDIO_OVER_USB
printMsg(&logger, "EFI_TUNER_STUDIO_OVER_USB=%d", EFI_TUNER_STUDIO_OVER_USB);
#else
printMsg(&logger, "EFI_TUNER_STUDIO_OVER_USB=%d", 0);
#endif
#ifdef EFI_SHAFT_POSITION_INPUT
printMsg(&logger, "EFI_SHAFT_POSITION_INPUT=%d", EFI_SHAFT_POSITION_INPUT);
#endif
#ifdef EFI_INTERNAL_ADC
printMsg(&logger, "EFI_INTERNAL_ADC=%d", EFI_INTERNAL_ADC);
#endif
// printSimpleMsg(&logger, "", );
// printSimpleMsg(&logger, "", );
/**
* Time to finish output. This is needed to avoid mix-up of this methods output and console command confirmation
*/
chThdSleepMilliseconds(5);
}
/**
* This methods prints all threads and their total times
*/
static void cmd_threads(void) {
static const char *states[] = { THD_STATE_NAMES };
Thread *tp;
print(" addr stack prio refs state time\r\n");
tp = chRegFirstThread();
do {
print("%.8lx [%.8lx] %4lu %4lu %9s %lu %s\r\n", (uint32_t) tp, 0,
(uint32_t) tp->p_prio, (uint32_t) (tp->p_refs - 1),
states[tp->p_state], (uint32_t) tp->p_time, tp->p_name);
tp = chRegNextThread(tp);
} while (tp != NULL );
}
void sendOutConfirmation(char *value, int i) {
scheduleMsg(&logger, "%s%d", value, i);
}
/**
* This methods prints the message to whatever is configured as our primary console
*/
void print(const char *format, ...) {
if (!is_serial_ready())
return;
va_list ap;
va_start(ap, format);
chvprintf((BaseSequentialStream *)CONSOLE_CHANNEL, format, ap);
va_end(ap);
}
void initializeConsole() {
initIntermediateLoggingBuffer();
initConsoleLogic();
startChibiosConsole(&handleConsoleLine);
initLogging(&logger, "console");
sayHello();
addConsoleAction("hello", sayHello);
#if EFI_HAS_RESET
addConsoleAction("reset", scheduleReset);
#endif
addConsoleAction("fatal", myfatal);
addConsoleAction("threadsinfo", cmd_threads);
}

View File

@ -0,0 +1,26 @@
/**
* @file eficonsole.h
* @brief Console package entry point header
*
* @date Nov 15, 2012
* @author Andrey Belomutskiy, (c) 2012-2013
*/
#pragma once
#ifndef RFICONSOLE_H_
#define RFICONSOLE_H_
#ifdef __cplusplus
extern "C"
{
#endif /* __cplusplus */
void initializeConsole(void);
void sendOutConfirmation(char *value, int i);
void print(const char *fmt, ...);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* RFICONSOLE_H_ */

View File

@ -0,0 +1,404 @@
/**
* @file status_loop.c
* @brief Human-readable protocol status messages
*
* http://rusefi.com/forum/viewtopic.php?t=263 Dev console overview
* http://rusefi.com/forum/viewtopic.php?t=210 Commands overview
*
*
* @date Mar 15, 2013
* @author Andrey Belomutskiy, (c) 2012-2014
*
* This file is part of rusEfi - see http://rusefi.com
*
* rusEfi is free software; you can redistribute it and/or modify it under the terms of
* the GNU General Public License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* rusEfi is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
* even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program.
* If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "main.h"
#include "status_loop.h"
#include "adc_inputs.h"
#if EFI_WAVE_ANALYZER
#include "wave_analyzer.h"
#endif
#include "trigger_central.h"
#include "engine_state.h"
#include "io_pins.h"
#include "mmc_card.h"
#include "rusefi.h"
#include "console_io.h"
#include "advance_map.h"
#if EFI_TUNER_STUDIO
#include "tunerstudio.h"
#endif /* EFI_TUNER_STUDIO */
#include "wave_math.h"
#include "fuel_math.h"
#include "main_trigger_callback.h"
#include "engine_math.h"
#include "idle_thread.h"
#include "engine_configuration.h"
#include "lcd_2x16.h"
#include "rfiutil.h"
#if EFI_PROD_CODE
// todo: move this logic to algo folder!
#include "rtc_helper.h"
#endif
// this 'true' value is needed for simulator
static volatile int fullLog = TRUE;
extern engine_configuration_s * engineConfiguration;
extern engine_configuration2_s * engineConfiguration2;
#define FULL_LOGGING_KEY "fl"
#if EFI_PROD_CODE || EFI_SIMULATOR
static Logging logger;
#endif /* EFI_PROD_CODE || EFI_SIMULATOR */
#if EFI_FILE_LOGGING
static Logging fileLogger;
#endif /* EFI_FILE_LOGGING */
static void reportSensorF(char *caption, float value, int precision) {
#if EFI_PROD_CODE || EFI_SIMULATOR
debugFloat(&logger, caption, value, precision);
#endif /* EFI_PROD_CODE || EFI_SIMULATOR */
#if EFI_FILE_LOGGING
debugFloat(&fileLogger, caption, value, precision);
#endif /* EFI_FILE_LOGGING */
}
static void reportSensorI(char *caption, int value) {
#if EFI_PROD_CODE || EFI_SIMULATOR
debugInt(&logger, caption, value);
#endif /* EFI_PROD_CODE || EFI_SIMULATOR */
#if EFI_FILE_LOGGING
debugInt(&fileLogger, caption, value);
#endif /* EFI_FILE_LOGGING */
}
static char* boolean2string(int value) {
return value ? "YES" : "NO";
}
void finishStatusLine(void) {
printLine(&logger);
}
void printSensors(void) {
#if EFI_FILE_LOGGING
resetLogging(&fileLogger);
#endif /* EFI_FILE_LOGGING */
// current time, in milliseconds
int nowMs = chTimeNow() / TICKS_IN_MS;
float sec = ((float) nowMs) / 1000;
reportSensorF("time", sec, 3);
reportSensorI("rpm", getRpm());
reportSensorF("maf", getMaf(), 2);
if (engineConfiguration2->hasMapSensor) {
reportSensorF(getCaption(LP_MAP), getMap(), 2);
}
reportSensorF("afr", getAfr(), 2);
reportSensorF("vref", getVRef(), 2);
reportSensorF("vbatt", getVBatt(), 2);
reportSensorF(getCaption(LP_THROTTLE), getTPS(), 2);
if (engineConfiguration2->hasCltSensor) {
reportSensorF(getCaption(LP_ECT), getCoolantTemperature(), 2);
}
reportSensorF(getCaption(LP_IAT), getIntakeAirTemperature(), 2);
// debugFloat(&logger, "tch", getTCharge1(tps), 2);
#if EFI_FILE_LOGGING
appendPrintf(&fileLogger, "\r\n");
appendToLog(fileLogger.buffer);
#endif /* EFI_FILE_LOGGING */
}
#define INITIAL_FULL_LOG TRUE
//#define INITIAL_FULL_LOG FALSE
static char LOGGING_BUFFER[500];
#if EFI_PROD_CODE
volatile int needToReportStatus = FALSE;
static int prevCkpEventCounter = -1;
static Logging logger2;
static time_t timeOfPreviousWarning = (systime_t) -10 * CH_FREQUENCY;
static void printStatus(void) {
needToReportStatus = TRUE;
}
//float getTCharge1(float tps) {
// float cltK = tempCtoKelvin(getCoolantTemperature());
// float iatK = tempCtoKelvin(getIntakeAirTemperature());
// return getTCharge(getCurrentRpm(), tps, cltK, iatK);
//}
#if EFI_CUSTOM_PANIC_METHOD
extern char *dbg_panic_file;
extern int dbg_panic_line;
#endif
void onDbgPanic(void) {
setOutputPinValue(LED_ERROR, 1);
}
int hasFatalError(void) {
return dbg_panic_msg != NULL;
}
static void checkIfShouldHalt(void) {
#if CH_DBG_ENABLED
if (hasFatalError()) {
setOutputPinValue(LED_ERROR, 1);
#if EFI_CUSTOM_PANIC_METHOD
print("my FATAL [%s] at %s:%d\r\n", dbg_panic_msg, dbg_panic_file, dbg_panic_line);
#else
print("my FATAL [%s] at %s:%d\r\n", dbg_panic_msg);
#endif
chThdSleepSeconds(1);
// todo: figure out how we halt exactly
while (TRUE) {
}
chSysHalt();
}
#endif
}
/**
* Time when the firmware version was reported last time, in seconds
* TODO: implement a request/response instead of just constantly sending this out
*/
static systime_t timeOfPreviousPrintVersion = (systime_t) -1;
static void printVersion(systime_t nowSeconds) {
if (overflowDiff(nowSeconds, timeOfPreviousPrintVersion) < 4)
return;
timeOfPreviousPrintVersion = nowSeconds;
appendPrintf(&logger, "rusEfiVersion%s%d %s%s", DELIMETER, getVersion(), getConfigurationName(engineConfiguration),
DELIMETER);
}
static systime_t timeOfPreviousReport = (systime_t) -1;
extern bool hasFirmwareError;
extern char errorMessageBuffer[200];
/**
* @brief Sends all pending data to dev console
*/
void updateDevConsoleState(void) {
if (!is_serial_ready())
return;
checkIfShouldHalt();
printPending();
pokeAdcInputs();
if (hasFirmwareError) {
printMsg(&logger, "firmware error: %s", errorMessageBuffer);
return;
}
if (!fullLog)
return;
systime_t nowSeconds = chTimeNowSeconds();
printVersion(nowSeconds);
int currentCkpEventCounter = getCrankEventCounter();
if (prevCkpEventCounter == currentCkpEventCounter && timeOfPreviousReport == nowSeconds)
return;
timeOfPreviousReport = nowSeconds;
int rpm = getRpm();
prevCkpEventCounter = currentCkpEventCounter;
printSensors();
debugInt(&logger, "ckp_c", currentCkpEventCounter);
// debugInt(&logger, "idl", getIdleSwitch());
// debugFloat(&logger, "table_spark", getAdvance(rpm, getMaf()), 2);
float engineLoad = getMaf();
debugFloat(&logger, "fuel_base", getBaseFuel(rpm, engineLoad), 2);
debugFloat(&logger, "fuel_iat", getIatCorrection(getIntakeAirTemperature()), 2);
debugFloat(&logger, "fuel_clt", getCltCorrection(getCoolantTemperature()), 2);
debugFloat(&logger, "fuel_lag", getInjectorLag(getVBatt()), 2);
debugFloat(&logger, "fuel", getRunningFuel(rpm, engineLoad), 2);
debugFloat(&logger, "timing", getAdvance(rpm, engineLoad), 2);
// float map = getMap();
// float fuel = getDefaultFuel(rpm, map);
// debugFloat(&logger, "d_fuel", fuel, 2);
#if EFI_WAVE_ANALYZER
printWave(&logger);
#endif
finishStatusLine();
}
/*
* command example:
* sfm 3500 400
* that would be 'show fuel for rpm 3500 maf 4.0'
*/
static void showFuelMap(int rpm, int key100) {
float engineLoad = key100 / 100.0;
float baseFuel = getBaseFuel(rpm, engineLoad);
float iatCorrection = getIatCorrection(getIntakeAirTemperature());
float cltCorrection = getCltCorrection(getCoolantTemperature());
float injectorLag = getInjectorLag(getVBatt());
print("baseFuel=%f\r\n", baseFuel);
print("iatCorrection=%f cltCorrection=%f injectorLag=%d\r\n", iatCorrection, cltCorrection,
(int) (100 * injectorLag));
float value = getRunningFuel(rpm, engineLoad);
print("fuel map rpm=%d, key=%f: %d\r\n", rpm, engineLoad, (int) (100 * value));
scheduleMsg(&logger2, "fuel map value = %f", value);
}
/**
* @returns TRUE in case there are too many warnings
*/
// todo: extract to 'error_handling.c'
int warning(const char *fmt, ...) {
time_t now = chTimeNow();
if (overflowDiff(now, timeOfPreviousWarning) < CH_FREQUENCY)
return TRUE; // we just had another warning, let's not spam
timeOfPreviousWarning = now;
resetLogging(&logger); // todo: is 'reset' really needed here?
appendMsgPrefix(&logger);
va_list ap;
va_start(ap, fmt);
vappendPrintf(&logger, fmt, ap);
va_end(ap);
append(&logger, DELIMETER);
scheduleLogging(&logger);
return FALSE;
}
static char buffer[10];
static char dateBuffer[30];
void updateHD44780lcd(void) {
lcd_HD44780_set_position(0, 12);
char * ptr = itoa10(buffer, getRpm());
ptr[0] = 0;
int len = ptr - buffer;
for (int i = 0; i < 6 - len; i++)
lcd_HD44780_print_char('_');
lcd_HD44780_print_string(buffer);
#if EFI_PROD_CODE
dateToString(dateBuffer);
lcd_HD44780_set_position(1, 0);
lcd_HD44780_print_string(dateBuffer);
#endif /* EFI_PROD_CODE */
}
#endif /* EFI_PROD_CODE */
static WORKING_AREA(lcdThreadStack, UTILITY_THREAD_STACK_SIZE);
static void lcdThread(void *arg) {
while (true) {
#if EFI_HD44780_LCD
updateHD44780lcd();
#endif
chThdSleepMilliseconds(50);
}
}
static WORKING_AREA(tsThreadStack, UTILITY_THREAD_STACK_SIZE);
static void tsStatusThread(void *arg) {
while (true) {
#if EFI_TUNER_STUDIO
// sensor state for EFI Analytics Tuner Studio
updateTunerStudioState();
#endif /* EFI_TUNER_STUDIO */
chThdSleepMilliseconds(50);
}
}
void initStatusLoop(void) {
#if EFI_PROD_CODE || EFI_SIMULATOR
initLoggingExt(&logger, "status loop", LOGGING_BUFFER, sizeof(LOGGING_BUFFER));
#endif /* EFI_PROD_CODE || EFI_SIMULATOR */
setFullLog(INITIAL_FULL_LOG);
addConsoleActionI(FULL_LOGGING_KEY, setFullLog);
#if EFI_PROD_CODE
initLogging(&logger2, "main event handler");
addConsoleActionII("sfm", showFuelMap);
addConsoleAction("status", printStatus);
#endif /* EFI_PROD_CODE */
#if EFI_FILE_LOGGING
initLogging(&fileLogger, "file logger");
#endif /* EFI_FILE_LOGGING */
}
void startStatusThreads(void) {
// todo: refactoring needed, this file should probably be split into pieces
chThdCreateStatic(lcdThreadStack, sizeof(lcdThreadStack), NORMALPRIO, (tfunc_t) lcdThread, NULL);
chThdCreateStatic(tsThreadStack, sizeof(tsThreadStack), NORMALPRIO, (tfunc_t) tsStatusThread, NULL);
}
void setFullLog(int value) {
print("Setting full logging: %s\r\n", boolean2string(value));
printMsg(&logger, "%s%d", FULL_LOGGING_KEY, value);
fullLog = value;
}
int getFullLog(void) {
return fullLog;
}

View File

@ -0,0 +1,30 @@
/**
* @file status_loop.h
*
* @date Mar 15, 2013
* @author Andrey Belomutskiy, (c) 2012-2013
*/
#ifndef CONSOLE_LOOP_H_
#define CONSOLE_LOOP_H_
#ifdef __cplusplus
extern "C"
{
#endif /* __cplusplus */
void initStatusLoop(void);
void updateDevConsoleState(void);
int getFullLog(void);
void printSensors(void);
void finishStatusLine(void);
void setFullLog(int value);
void startStatusThreads(void);
void sayOsHello(void);
int hasFatalError(void);
void onDbgPanic(void);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* CONSOLE_LOOP_H_ */

View File

@ -0,0 +1,199 @@
/**
* @file tunerstudio.c
* @brief Integration with EFI Analytics Tuner Studio software
*
* todo: merge this file with tunerstudio_algo.c?
*
* @date Aug 26, 2013
* @author Andrey Belomutskiy, (c) 2012-2014
*
* This file is part of rusEfi - see http://rusefi.com
*
* rusEfi is free software; you can redistribute it and/or modify it under the terms of
* the GNU General Public License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* rusEfi is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
* even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program.
* If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "main.h"
#include "engine_state.h"
#include "tunerstudio.h"
#include "pin_repository.h"
#include "main_trigger_callback.h"
#include "flash_main.h"
#include "usbconsole.h"
#include "map_averaging.h"
#include "tunerstudio_algo.h"
#include "tunerstudio_configuration.h"
#include "malfunction_central.h"
#if EFI_TUNER_STUDIO
static Logging logger;
extern engine_configuration_s *engineConfiguration;
extern SerialUSBDriver SDU1;
#define CONSOLE_DEVICE &SDU1
#if EFI_TUNER_STUDIO_OVER_USB
#define ts_serail_ready() is_usb_serial_ready()
#else
#define ts_serail_ready() TRUE
static SerialConfig tsSerialConfig = { TS_SERIAL_SPEED, 0, USART_CR2_STOP1_BITS | USART_CR2_LINEN, 0 };
#endif /* EFI_TUNER_STUDIO_OVER_USB */
static WORKING_AREA(TS_WORKING_AREA, UTILITY_THREAD_STACK_SIZE);
static int tsCounter = 0;
static int writeCounter = 0;
static TunerStudioWriteRequest writeRequest;
extern TunerStudioOutputChannels tsOutputChannels;
extern engine_configuration_s tsContstants;
char *constantsAsPtr = (char *) &tsContstants;
extern TunerStudioState tsState;
static void printStats(void) {
#if EFI_TUNER_STUDIO_OVER_USB
#else
scheduleMsg(&logger, "TS RX on %s%d", portname(TS_SERIAL_RX_PORT), TS_SERIAL_RX_PIN);
scheduleMsg(&logger, "TS TX on %s%d", portname(TS_SERIAL_TX_PORT), TS_SERIAL_TX_PIN);
#endif /* EFI_TUNER_STUDIO_OVER_USB */
scheduleMsg(&logger, "TunerStudio total/error counter=%d/%d", tsCounter, tsState.errorCounter);
scheduleMsg(&logger, "TunerStudio H counter=%d", tsState.queryCommandCounter);
scheduleMsg(&logger, "TunerStudio O counter=%d size=%d", tsState.outputChannelsCommandCounter, sizeof(tsOutputChannels));
scheduleMsg(&logger, "TunerStudio C counter=%d size=%d", tsState.readPageCommandsCounter, sizeof(tsContstants));
scheduleMsg(&logger, "TunerStudio B counter=%d size=%d", tsState.burnCommandCounter, sizeof(tsContstants));
scheduleMsg(&logger, "TunerStudio W counter=%d", writeCounter);
}
void tunerStudioWriteData(const uint8_t * buffer, int size) {
chSequentialStreamWrite(TS_SERIAL_DEVICE, buffer, size);
}
void tunerStudioDebug(char *msg) {
#if EFI_TUNER_STUDIO_VERBOSE
print("%s\r\n", msg);
printStats();
#endif
}
/**
* 'Write' command receives a single value at a given offset
*/
void handleValueWriteCommand(void) {
writeCounter++;
tunerStudioDebug("got W (Write)");
int size = sizeof(TunerStudioWriteRequest);
print("Reading %d\r\n", size);
int recieved = chSequentialStreamRead(TS_SERIAL_DEVICE, (uint8_t *)&writeRequest, size);
print("got %d\r\n", recieved);
// unsigned char offset = writeBuffer[0];
// unsigned char value = writeBuffer[1];
//
print("offset %d: value=%d\r\n", writeRequest.offset, writeRequest.value);
constantsAsPtr[writeRequest.offset] = writeRequest.value;
}
/**
* 'Burn' command is a command to commit the changes
*/
void handleBurnCommand(void) {
tsState.burnCommandCounter++;
tunerStudioDebug("got B (Burn)");
// todo: how about some multi-threading?
memcpy(engineConfiguration, &tsContstants, sizeof(engine_configuration_s));
writeToFlash();
}
static msg_t tsThreadEntryPoint(void *arg) {
(void) arg;
chRegSetThreadName("tunerstudio thread");
int wasReady = FALSE;
while (true) {
int isReady = ts_serail_ready();
if (!isReady) {
chThdSleepMilliseconds(10);
wasReady = FALSE;
continue;
}
if (!wasReady) {
wasReady = TRUE;
// scheduleSimpleMsg(&logger, "ts channel is now ready ", chTimeNow());
}
short command = (short) chSequentialStreamGet(TS_SERIAL_DEVICE);
int success = tunerStudioHandleCommand(command);
if (!success && command != 0)
print("got unexpected TunerStudio command %c:%d\r\n", command, command);
tsCounter++;
}
#if defined __GNUC__
return 0;
#endif
}
extern engine_configuration_s *engineConfiguration;
void syncTunerStudioCopy(void) {
memcpy(&tsContstants, engineConfiguration, sizeof(engine_configuration_s));
}
void startTunerStudioConnectivity(void) {
initLogging(&logger, "tuner studio");
#if EFI_TUNER_STUDIO_OVER_USB
print("TunerStudio over USB serial");
usb_serial_start();
#else
print("TunerStudio over USART");
mySetPadMode("tunerstudio rx", TS_SERIAL_RX_PORT, TS_SERIAL_RX_PIN, PAL_MODE_ALTERNATE(TS_SERIAL_AF));
mySetPadMode("tunerstudio tx", TS_SERIAL_TX_PORT, TS_SERIAL_TX_PIN, PAL_MODE_ALTERNATE(TS_SERIAL_AF));
sdStart(TS_SERIAL_DEVICE, &tsSerialConfig);
#endif
syncTunerStudioCopy();
addConsoleAction("tsinfo", printStats);
chThdCreateStatic(TS_WORKING_AREA, sizeof(TS_WORKING_AREA), NORMALPRIO, tsThreadEntryPoint, NULL);
}
void updateTunerStudioState() {
tsOutputChannels.rpm = getRpm();
tsOutputChannels.coolant_temperature = getCoolantTemperature();
tsOutputChannels.intake_air_temperature = getIntakeAirTemperature();
tsOutputChannels.throttle_positon = getTPS();
tsOutputChannels.mass_air_flow = getMaf();
tsOutputChannels.air_fuel_ratio = getAfr();
tsOutputChannels.v_batt = getVBatt();
tsOutputChannels.tpsADC = getTPS10bitAdc();
tsOutputChannels.atmospherePressure = getAtmosphericPressure();
tsOutputChannels.manifold_air_pressure = getMap();
tsOutputChannels.checkEngine = hasErrorCodes();
}
#endif /* EFI_TUNER_STUDIO */

View File

@ -0,0 +1,34 @@
/**
* @file tunerstudio.h
*
* @date Aug 26, 2013
* @author Andrey Belomutskiy, (c) 2012-2013
*/
#ifndef TUNERSTUDIO_H_
#define TUNERSTUDIO_H_
#if EFI_TUNER_STUDIO_OVER_USB
#define TS_SERIAL_DEVICE (&SDU1)
#else
#define TS_SERIAL_DEVICE &SD3
#define TS_SERIAL_SPEED 115200
#endif /* EFI_TUNER_STUDIO_OVER_USB */
#if defined __GNUC__
typedef struct
__attribute__((packed)) {
#else
typedef __packed struct {
#endif
short int offset;
unsigned char value;
} TunerStudioWriteRequest;
void startTunerStudioConnectivity(void);
void syncTunerStudioCopy(void);
void updateTunerStudioState(void);
#endif /* TUNERSTUDIO_H_ */

View File

@ -0,0 +1,3 @@
TUNERSTUDIOSRC = console/tunerstudio/tunerstudio_algo.c \
console/tunerstudio/tunerstudio.c

View File

@ -0,0 +1,129 @@
/**
* @file tunerstudio_algo.c
* @brief Tuner Studio plain protocol implementation
*
*
* Tuner Studio has a really simple protocol, a minimal implementation
* capable of displaying current engine state on the gauges would
* require only two commands: queryCommand and ochGetCommand
*
* queryCommand:
* Communication initialization command. TunerStudio sends a single byte H
* ECU response:
* One of the known ECU id strings. We are using "MShift v0.01" id string.
*
* ochGetCommand:
* Request for output channels state.TunerStudio sends a single byte O
* ECU response:
* A snapshot of output channels as described in [OutputChannels] section of the .ini file
* The length of this block is 'ochBlockSize' property of the .ini file
*
* These two commands are enough to get working gauges. In order to start configuring the ECU using
* tuner studio, three more commands should be implemented:
*
* todo: merge this file with tunerstudio.c?
*
*
* @date Oct 22, 2013
* @author Andrey Belomutskiy, (c) 2012-2014
*
* This file is part of rusEfi - see http://rusefi.com
*
* rusEfi is free software; you can redistribute it and/or modify it under the terms of
* the GNU General Public License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* rusEfi is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
* even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program.
* If not, see <http://www.gnu.org/licenses/>.
*/
#include <string.h>
#include "tunerstudio_algo.h"
#include "tunerstudio_configuration.h"
#include "engine_configuration.h"
#ifndef FALSE
#define FALSE 0
#endif
#ifndef TRUE
#define TRUE (!FALSE)
#endif
TunerStudioState tsState;
TunerStudioOutputChannels tsOutputChannels;
/**
* this is a local copy of the configuration. Any changes to this copy
* have no effect until this copy is explicitly propagated to the main working copy
*/
engine_configuration_s tsContstants;
int tunerStudioHandleCommand(short command) {
if (command == 'H') {
handleQueryCommand();
} else if (command == 'O') {
handleOutputChannelsCommand();
} else if (command == 'W') {
handleValueWriteCommand();
} else if (command == 'B') {
handleBurnCommand();
} else if (command == 'C') {
handlePageReadCommand();
} else if (command == 't' || command == 'T') {
handleTestCommand();
} else if (command == 'F') {
tunerStudioDebug("ignoring F");
/**
* http://www.msextra.com/forums/viewtopic.php?f=122&t=48327
* Response from TS support: This is an optional command *
* "The F command is used to find what ini. file needs to be loaded in TunerStudio to match the controller.
* If you are able to just make your firmware ignore the command that would work.
* Currently on some firmware versions the F command is not used and is just ignored by the firmware as a unknown command."
*/
} else {
#if EFI_TUNER_STUDIO_OVER_USB
/**
* With TTL there is a real chance of corrupted messages.
* With serial-over-USB we are not expecting communication errors
*/
// fatal("unexpected TunerStudio command in USB mode");
#endif /* EFI_TUNER_STUDIO_OVER_USB */
tsState.errorCounter++;
return FALSE;
}
return TRUE;
}
void handleQueryCommand(void) {
tsState.queryCommandCounter++;
tunerStudioDebug("got H (queryCommand)");
tunerStudioWriteData((const uint8_t *) TS_SIGNATURE, strlen(TS_SIGNATURE) + 1);
}
/**
* @brief 'Output' command sends out a snapshot of current values
*/
void handleOutputChannelsCommand(void) {
tsState.outputChannelsCommandCounter++;
// this method is invoked too often to print any debug information
tunerStudioWriteData((const uint8_t *) &tsOutputChannels, sizeof(TunerStudioOutputChannels));
}
void handlePageReadCommand(void) {
tsState.readPageCommandsCounter++;
tunerStudioDebug("got C (Constants)");
tunerStudioWriteData((const uint8_t *) &tsContstants, sizeof(engine_configuration_s));
}
void handleTestCommand(void) {
/**
* this is NOT a standard TunerStudio command, this is my own
* extension of the protocol to simplify troubleshooting
*/
tunerStudioDebug("got T (Test)\r\n");
tunerStudioWriteData((const uint8_t *) "alive\r\n", 7);
}

View File

@ -0,0 +1,36 @@
/**
* @file tunerstudio_algo.h
*
* @date Oct 22, 2013
* @author Andrey Belomutskiy, (c) 2012-2013
*/
#ifndef TUNERSTUDIO_ALGO_H_
#define TUNERSTUDIO_ALGO_H_
#define TS_SIGNATURE "MShift v0.01"
#include <stdint.h>
typedef struct {
int queryCommandCounter;
int outputChannelsCommandCounter;
int readPageCommandsCounter;
int burnCommandCounter;
int errorCounter;
} TunerStudioState;
int tunerStudioHandleCommand(short command);
void handleTestCommand(void);
void handleQueryCommand(void);
void handleOutputChannelsCommand(void);
void handleValueWriteCommand(void);
void handlePageReadCommand(void);
void handleBurnCommand(void);
void tunerStudioWriteData(const uint8_t * buffer, int size);
void tunerStudioDebug(char *msg);
#endif /* TUNERSTUDIO_ALGO_H_ */

View File

@ -0,0 +1,34 @@
/*
* @file tunerstudio_configuration.h
* @brief Tuner Studio connectivity configuration
*
* In this file the configuration of TunerStudio is defined
*
* @date Oct 22, 2013
* @author Andrey Belomutskiy, (c) 2012-2013
*/
#ifndef TUNERSTUDIO_CONFIGURATION_H_
#define TUNERSTUDIO_CONFIGURATION_H_
/**
* please be aware that current "stable" version of TunerStudio does not
* support 'float' (F32) type. You would need a beta version to handle floats
*/
typedef struct {
int rpm; // size 4, offset 0
float coolant_temperature; // size 4, offset 4
float intake_air_temperature; // size 4, offset 8
float throttle_positon; // size 4, offset 12
float mass_air_flow; // size 4, offset 16
float air_fuel_ratio; // size 4, offset 20
float fuel_load; // size 4, offset 24
float v_batt; // size 4, offset 28
short int tpsADC; // size 2, offset 32
short int alignment; // size 2, offset 34
float atmospherePressure; // size 4, offset 36
float manifold_air_pressure; // size 4, offset 40
int checkEngine; // size 4, offset 44
} TunerStudioOutputChannels;
#endif /* TUNERSTUDIO_CONFIGURATION_H_ */

View File

@ -0,0 +1,3 @@
CONSOLEUTILSRC = $(PROJECT_DIR)/console_util/datalogging.c \
$(PROJECT_DIR)/console_util/rfiutil.c

View File

@ -0,0 +1,400 @@
/**
* @file datalogging.c
* @brief Buffered console output stream code
*
* Here we have a memory buffer and method related to
* printing messages into this buffer. The purpose of the
* buffer is to allow fast, non-blocking, thread-safe logging.
*
* The idea is that each interrupt handler would have it's own logging buffer. You can add
* stuff into this buffer without any locking since it's you own buffer, and once you get
* the whole message you invoke the scheduleLogging() method which appends your local content
* into the global logging buffer, from which it is later dispatched to the console by our
* main console thread.
*
* @date Feb 25, 2013
* @author Andrey Belomutskiy, (c) 2012-2014
*
* This file is part of rusEfi - see http://rusefi.com
*
* rusEfi is free software; you can redistribute it and/or modify it under the terms of
* the GNU General Public License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* rusEfi is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
* even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program.
* If not, see <http://www.gnu.org/licenses/>.
*
*/
#include <stdbool.h>
#include "main.h"
#include "rfiutil.h"
#include "chprintf.h"
#include "chmtx.h"
#include "memstreams.h"
#include "console_io.h"
#define OUTPUT_BUFFER 9000
/**
* This is the size of the MemoryStream used by chvprintf
*/
#define INTERMEDIATE_LOGGING_BUFFER_SIZE 2000
// we use this magic constant to make sure it's not just a random non-zero int in memory
#define MAGIC_LOGGING_FLAG 45234441
/**
* This is the buffer into which all the data providers write
*/
static char pendingBuffer[OUTPUT_BUFFER];
/**
* We copy all the pending data into this buffer once we are ready to push it out
*/
static char outputBuffer[OUTPUT_BUFFER];
/**
* ... and we need another buffer for to make the message with with control sum
* TODO: if needed we can eliminate this buffer by making some space in the start
* of the 'outputBuffer' into which we would put the control sum when time comes
*/
static char ioBuffer[OUTPUT_BUFFER];
static MemoryStream intermediateLoggingBuffer;
static uint8_t intermediateLoggingBufferData[INTERMEDIATE_LOGGING_BUFFER_SIZE]; //todo define max-printf-buffer
static bool intermediateLoggingBufferInited = FALSE;
static int validateBuffer(Logging *logging, int extraLen, char *text) {
if (logging->buffer == NULL) {
strcpy(logging->SMALL_BUFFER, "Logging not initialized: ");
strcat(logging->SMALL_BUFFER, logging->name);
strcat(logging->SMALL_BUFFER, "/");
strcat(logging->SMALL_BUFFER, text);
fatal(logging->SMALL_BUFFER);
return TRUE;
}
int currentLen = loggingSize(logging);
if (currentLen + extraLen > logging->bufferSize - 1) {
strcpy(logging->SMALL_BUFFER, "Logging buffer overflow: ");
strcat(logging->SMALL_BUFFER, logging->name);
strcat(logging->SMALL_BUFFER, "/");
strcat(logging->SMALL_BUFFER, text);
fatal(logging->SMALL_BUFFER);
// unlockOutputBuffer();
// resetLogging(logging);
return TRUE;
}
return FALSE;
}
void append(Logging *logging, char *text) {
chDbgCheck(text!=NULL, "append NULL");
int extraLen = strlen(text);
int errcode = validateBuffer(logging, extraLen, text);
if (errcode)
return;
strcpy(logging->linePointer, text);
logging->linePointer += extraLen;
}
static void vappendPrintfI(Logging *logging, const char *fmt, va_list arg) {
intermediateLoggingBuffer.eos = 0; // reset
chvprintf((BaseSequentialStream *) &intermediateLoggingBuffer, fmt, arg);
intermediateLoggingBuffer.buffer[intermediateLoggingBuffer.eos] = 0; // need to terminate explicitly
append(logging, (char *) intermediateLoggingBufferData);
}
void vappendPrintf(Logging *logging, const char *fmt, va_list arg) {
if (!intermediateLoggingBufferInited) {
fatal("intermediateLoggingBufferInited not inited!");
return;
}
int isLocked = dbg_lock_cnt != 0;
int icsr_vectactive = dbg_isr_cnt > 0;
if (isLocked) {
vappendPrintfI(logging, fmt, arg);
} else {
if (icsr_vectactive == 0) {
chSysLock()
;
vappendPrintfI(logging, fmt, arg);
chSysUnlock()
;
} else {
chSysLockFromIsr()
;
vappendPrintfI(logging, fmt, arg);
chSysUnlockFromIsr()
;
}
}
}
void appendPrintf(Logging *logging, const char *fmt, ...) {
va_list ap;
va_start(ap, fmt);
vappendPrintf(logging, fmt, ap);
va_end(ap);
}
// todo: this method does not really belong to this file
char* getCaption(LoggingPoints loggingPoint) {
switch (loggingPoint) {
case LP_RPM:
return "RPM";
case LP_THROTTLE:
return "TP";
case LP_IAT:
return "MAT";
case LP_ECT:
return "CLT";
case LP_SECONDS:
return "SecL";
case LP_MAF:
return "MAF";
case LP_MAP:
return "MAP";
case LP_MAP_RAW:
return "MAP_R";
}
fatal("No such loggingPoint");
return NULL;
}
// todo: this method does not really belong to this file
static char* get2ndCaption(int loggingPoint) {
switch (loggingPoint) {
case LP_RPM:
return "RPM";
case LP_THROTTLE:
return "%";
case LP_IAT:
return "°F";
case LP_ECT:
return "°F";
case LP_SECONDS:
return "s";
case LP_MAP:
return "MAP";
case LP_MAF:
return "MAF";
}
fatal("No such loggingPoint");
return NULL;
}
void initLoggingExt(Logging *logging, char *name, char *buffer, int bufferSize) {
print("Init logging\r\n");
logging->name = name;
logging->buffer = buffer;
logging->bufferSize = bufferSize;
resetLogging(logging);
logging->isInitialized = MAGIC_LOGGING_FLAG;
}
int isInitialized(Logging *logging) {
return logging->isInitialized == MAGIC_LOGGING_FLAG;
}
void initLogging(Logging *logging, char *name) {
initLoggingExt(logging, name, logging->DEFAULT_BUFFER, sizeof(logging->DEFAULT_BUFFER));
}
void debugInt(Logging *logging, char *caption, int value) {
append(logging, caption);
append(logging, DELIMETER);
appendPrintf(logging, "%d%s", value, DELIMETER);
}
void appendFloat(Logging *logging, float value, int precision) {
// todo: this implementation is less than perfect
switch (precision) {
case 1:
appendPrintf(logging, "%..10f", value);
break;
case 2:
appendPrintf(logging, "%..100f", value);
break;
case 3:
appendPrintf(logging, "%..1000f", value);
break;
case 4:
appendPrintf(logging, "%..10000f", value);
break;
case 5:
appendPrintf(logging, "%..100000f", value);
break;
case 6:
appendPrintf(logging, "%..1000000f", value);
break;
default:
appendPrintf(logging, "%f", value);
}
}
void debugFloat(Logging *logging, char *caption, float value, int precision) {
append(logging, caption);
append(logging, DELIMETER);
appendFloat(logging, value, precision);
append(logging, DELIMETER);
}
/*
void logInt(Logging *logging, LoggingPoints loggingPoint, int value) {
char *caption = getCaption(loggingPoint);
debugInt(logging, caption, value);
}
void logFloat(Logging *logging, LoggingPoints loggingPoint, float value) {
debugFloat(logging, getCaption(loggingPoint), value, 2);
}
*/
static void commonSimpleMsg(Logging *logging, char *msg, int value) {
resetLogging(logging);
appendMsgPrefix(logging);
appendPrintf(logging, "%s%d", msg, value);
}
/**
* this method should invoked on the main thread only
*/
static void printWithLength(char *line) {
/**
* this is my way to detect serial port transmission errors
* following code is functionally identical to
* print("line:%d:%s\r\n", len, line);
* but it is faster because it outputs the whole buffer, not single characters
* We need this optimization because when we output larger chunks of data like the wave_chart:
* When we work with actual hardware, it is faster to invoke 'chSequentialStreamWrite' for the
* whole buffer then to invoke 'chSequentialStreamPut' once per character.
*/
int len = strlen(line);
strcpy(ioBuffer, "line:");
char *p = ioBuffer + strlen(ioBuffer);
p = itoa10(p, len);
*p++ = ':';
strcpy(p, line);
p += len;
*p++ = '\r';
*p++ = '\n';
if (!is_serial_ready())
return;
consoleOutputBuffer((const int8_t *)ioBuffer, p - ioBuffer);
}
void printLine(Logging *logging) {
printWithLength(logging->buffer);
resetLogging(logging);
}
void appendMsgPrefix(Logging *logging) {
appendPrintf(logging, "msg%s", DELIMETER);
}
void appendMsgPostfix(Logging *logging) {
append(logging, DELIMETER);
}
void resetLogging(Logging *logging) {
char *buffer = logging->buffer;
chDbgCheck(buffer!=NULL, "null buffer");
logging->linePointer = buffer;
}
/**
* This method would output a simple console message immediately.
* This method should only be invoked on main thread because only the main thread can write to the console
*/
void printMsg(Logging *logger, const char *fmt, ...) {
// resetLogging(logging); // I guess 'reset' is not needed here?
appendMsgPrefix(logger);
va_list ap;
va_start(ap, fmt);
vappendPrintf(logger, fmt, ap);
va_end(ap);
append(logger, DELIMETER);
printLine(logger);
}
void scheduleMsg(Logging *logging, const char *fmt, ...) {
resetLogging(logging); // todo: is 'reset' really needed here?
appendMsgPrefix(logging);
va_list ap;
va_start(ap, fmt);
vappendPrintf(logging, fmt, ap);
va_end(ap);
appendMsgPostfix(logging);
scheduleLogging(logging);
}
// todo: remove this method, replace with 'scheduleMsg'
void scheduleIntValue(Logging *logging, char *msg, int value) {
resetLogging(logging);
append(logging, msg);
append(logging, DELIMETER);
appendPrintf(logging, "%d", value);
append(logging, DELIMETER);
scheduleLogging(logging);
}
void scheduleLogging(Logging *logging) {
// this could be done without locking
int newLength = strlen(logging->buffer);
lockOutputBuffer();
// I hope this is fast enough to operate under sys lock
int curLength = strlen(pendingBuffer);
if (curLength + newLength >= OUTPUT_BUFFER) {
/**
* if no one is consuming the data we have to drop it
* this happens in case of serial-over-USB, todo: find a better solution
*
*/
// strcpy(fatalMessage, "datalogging.c: output buffer overflow: ");
// strcat(fatalMessage, logging->name);
// fatal(fatalMessage);
unlockOutputBuffer();
resetLogging(logging);
return;
}
strcat(pendingBuffer, logging->buffer);
unlockOutputBuffer();
resetLogging(logging);
}
uint32_t loggingSize(Logging *logging) {
return (int) logging->linePointer - (int) (logging->buffer);
}
/**
* This method actually sends all the pending data to the communication layer
*/
void printPending() {
lockOutputBuffer();
// we cannot output under syslock, so another buffer
strcpy(outputBuffer, pendingBuffer);
pendingBuffer[0] = 0; // reset pending buffer
unlockOutputBuffer();
if (strlen(outputBuffer) > 0)
printWithLength(outputBuffer);
}
void initIntermediateLoggingBuffer(void) {
msObjectInit(&intermediateLoggingBuffer, intermediateLoggingBufferData, INTERMEDIATE_LOGGING_BUFFER_SIZE, 0);
intermediateLoggingBufferInited = TRUE;
}

View File

@ -0,0 +1,96 @@
/**
* @file datalogging.h
* @brief Buffered console output stream header
*
* @date Feb 25, 2013
* @author Andrey Belomutskiy, (c) 2012-2013
*/
#ifndef DATALOGGING_H_
#define DATALOGGING_H_
#include "global.h"
#include <stdarg.h>
#define DELIMETER ","
typedef enum {
LP_RPM,
LP_ECT,
LP_IAT,
LP_THROTTLE, LP_SECONDS,
LP_MAP,
LP_MAF,
LP_MAP_RAW,
} LoggingPoints;
// todo: migrate to external buffer so that different instances have different
// size of buffers?
typedef struct {
char *name;
char SMALL_BUFFER[40];
// todo: explicitly default buffer externally so that we do not have default_buffer where we do not need it?
char DEFAULT_BUFFER[200];
char *buffer;
char *linePointer;
int bufferSize;
volatile int isInitialized;
} Logging;
#ifdef __cplusplus
extern "C"
{
#endif /* __cplusplus */
void lockOutputBuffer(void);
void unlockOutputBuffer(void);
void initIntermediateLoggingBuffer(void);
uint32_t loggingSize(Logging *logging);
int isInitialized(Logging *logging);
void initLogging(Logging *logging, char *name);
void initLoggingExt(Logging *logging, char *name, char *buffer, int bufferSize);
void debugInt(Logging *logging, char *caption, int value);
void logInt(Logging *logging, LoggingPoints loggingPoint, int value);
void debugFloat(Logging *logging, char *text, float value, int precision);
void logFloat(Logging *logging, LoggingPoints loggingPoint, float value);
void appendFloat(Logging *logging, float value, int precision);
void resetLogging(Logging *logging);
void printLine(Logging *logging);
void appendMsgPrefix(Logging *logging);
void appendMsgPostfix(Logging *logging);
void scheduleMsg(Logging *logging, const char *fmt, ...);
void printMsg(Logging *logging, const char *fmt, ...);
char* getCaption(LoggingPoints loggingPoint);
void appendPrintf(Logging *logging, const char *fmt, ...);
void vappendPrintf(Logging *logging, const char *fmt, va_list arg);
void append(Logging *logging, char *text);
/**
* this method copies the line into the intermediate buffer for later output by
* the main thread
*/
void scheduleLogging(Logging *logging);
void scheduleIntValue(Logging *logging, char *msg, int value);
/**
* this should only be invoked by the 'main' thread in order to keep the console safe
*/
void printPending(void);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* DATALOGGING_H_ */

View File

@ -0,0 +1,139 @@
/**
* @file rfiutil.c
* @brief Number to string conversion code
*
* @date Nov 15, 2012
* @author Andrey Belomutskiy, (c) 2012-2014
*
* This file is part of rusEfi - see http://rusefi.com
*
* rusEfi is free software; you can redistribute it and/or modify it under the terms of
* the GNU General Public License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* rusEfi is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
* even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program.
* If not, see <http://www.gnu.org/licenses/>.
*/
#include <string.h>
#include "rfiutil.h"
int mylog10(int param) {
if (param < 10)
return 0;
if (param < 100)
return 1;
if (param < 1000)
return 2;
if (param < 10000)
return 3;
if (param < 100000)
return 4;
if (param < 1000000)
return 5;
if (param < 10000000)
return 6;
if (param < 100000000)
return 7;
return mylog10(param / 10) + 1;
}
static char *ltoa_internal(char *p, long num, unsigned radix) {
int i;
char *q;
q = p + _MAX_FILLER;
do {
i = (int) (num % radix);
i += '0';
if (i > '9')
i += 'A' - '0' - 10;
*--q = i;
} while ((num /= radix) != 0);
i = (int) (p + _MAX_FILLER - q);
do
*p++ = *q++;
while (--i);
return p;
}
static char* itoa_signed(uint8_t *p, int num, unsigned radix) {
if (num < 0) {
*p++ = '-';
char *end = ltoa_internal(p, -num, radix);
*end = 0;
return end;
}
char *end = ltoa_internal(p, num, radix);
*end = 0;
return end;
}
/**
* Integer to string
*/
char* itoa10(uint8_t *p, int num) {
// todo: unit test
return itoa_signed(p, num, 10);
}
char hexChar(int v) {
v = v & 0xF;
if (v < 10)
return '0' + v;
return 'A' - 10 + v;
}
// todo: why does it not compile if I make this function 'inline'?
int isIsrContext(void) {
/**
* Unfortunately ChibiOS has two versions of methods for different
* contexts.
*/
return dbg_isr_cnt > 0;
}
void chVTSetAny(VirtualTimer *vtp, systime_t time, vtfunc_t vtfunc, void *par) {
if (isIsrContext()) {
chSysLockFromIsr()
;
if (chVTIsArmedI(vtp))
chVTResetI(vtp);
chVTSetI(vtp, time, vtfunc, par);
chSysUnlockFromIsr()
;
} else {
chSysLock()
;
if (chVTIsArmedI(vtp))
chVTResetI(vtp);
chVTSetI(vtp, time, vtfunc, par);
chSysUnlock()
;
}
}
/**
* @brief This function knows how to print a histogram_s summary
*/
void printHistogram(Logging *logging, histogram_s *histogram) {
int report[5];
int len = hsReport(histogram, report);
resetLogging(logging);
appendMsgPrefix(logging);
appendPrintf(logging, "histogram %s *", histogram->name);
for (int i = 0; i < len; i++)
appendPrintf(logging, "%d ", report[i]);
appendPrintf(logging, "*");
appendMsgPostfix(logging);
scheduleLogging(logging);
}

View File

@ -0,0 +1,29 @@
/*
* @file rfiutil.h
* @brief Number to string conversion header
*
* @date Nov 15, 2012
* @author Andrey Belomutskiy, (c) 2012-2013
*/
#ifndef RFIUTIL_H_
#define RFIUTIL_H_
#include "global.h"
#include "histogram.h"
#include "datalogging.h"
#ifndef TRUE
#define TRUE 1
#define FALSE 0
#endif
#define _MAX_FILLER 11
char* itoa10(uint8_t *p, int num);
char hexC(int v);
int isIsrContext(void);
void chVTSetAny(VirtualTimer *vtp, systime_t time, vtfunc_t vtfunc, void *par);
void printHistogram(Logging *logging, histogram_s *histogram);
#endif /* RFIUTIL_H_ */

View File

@ -0,0 +1,43 @@
/**
* @file OutputSignalArray.cpp
*
* @date Mar 20, 2014
* @author Andrey Belomutskiy, (c) 2012-2014
*
* This file is part of rusEfi - see http://rusefi.com
*
* rusEfi is free software; you can redistribute it and/or modify it under the terms of
* the GNU General Public License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* rusEfi is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
* even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program.
* If not, see <http://www.gnu.org/licenses/>.
*/
#include "OutputSignalList.h"
OutputSignalList::OutputSignalList() {
clear();
}
void OutputSignalList::clear() {
size = 0;
}
OutputSignal * OutputSignalList::add(io_pin_e ioPin) {
if(size==OUTPUT_SIGNAL_MAX_SIZE) {
firmwareError("Too many signals, adding %d", ioPin);
return NULL;
}
OutputSignal *signal = &signals[size++];
initOutputSignal(signal, ioPin);
return signal;
}

View File

@ -0,0 +1,42 @@
/*
* @file OutputSignalList.h
*
* @date Mar 20, 2014
* @author Andrey Belomutskiy, (c) 2012-2014
*
* This file is part of rusEfi - see http://rusefi.com
*
* rusEfi is free software; you can redistribute it and/or modify it under the terms of
* the GNU General Public License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* rusEfi is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
* even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program.
* If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef OUTPUTSIGNALLIST_H_
#define OUTPUTSIGNALLIST_H_
#include "signal_executor.h"
#include "io_pins.h"
#define OUTPUT_SIGNAL_MAX_SIZE 40
class OutputSignalList {
public:
OutputSignalList();
void clear();
OutputSignal * add(io_pin_e ioPin);
private:
int size;
OutputSignal signals[OUTPUT_SIGNAL_MAX_SIZE];
};
#endif /* OUTPUTSIGNALLIST_H_ */

View File

@ -0,0 +1,53 @@
/**
* @file advance_map.c
*
* @date Mar 27, 2013
* @author Andrey Belomutskiy, (c) 2012-2014
*
* This file is part of rusEfi - see http://rusefi.com
*
* rusEfi is free software; you can redistribute it and/or modify it under the terms of
* the GNU General Public License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* rusEfi is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
* even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program.
* If not, see <http://www.gnu.org/licenses/>.
*/
#include "advance_map.h"
#include "interpolation.h"
// that's for 'max' function
#include "idle_controller.h"
#include "engine_configuration.h"
#include "engine_math.h"
extern engine_configuration_s *engineConfiguration;
extern engine_configuration2_s *engineConfiguration2;
static float *timing_ptrs[AD_LOAD_COUNT];
static int initialized = FALSE;
float getBaseAdvance(int rpm, float engineLoad) {
chDbgAssert(initialized, "fuel map initialized", NULL);
return interpolate3d(engineLoad, engineConfiguration->ignitionLoadBins, AD_LOAD_COUNT, rpm,
engineConfiguration->ignitionRpmBins,
AD_RPM_COUNT, timing_ptrs);
}
float getAdvance(int rpm, float engineLoad) {
if (isCrankingR(rpm))
return engineConfiguration->crankingChargeAngle;
return getBaseAdvance(rpm, engineLoad) + engineConfiguration->ignitionOffset;
}
void prepareTimingMap(void) {
for (int k = 0; k < FUEL_LOAD_COUNT; k++)
timing_ptrs[k] = engineConfiguration->fuelTable[k];
initialized = TRUE;
}

View File

@ -0,0 +1,17 @@
/*
* advance.h
*
* @date Mar 27, 2013
* @author Andrey Belomutskiy, (c) 2012-2013
*/
#ifndef ADVANCE_H_
#define ADVANCE_H_
#define AD_LOAD_COUNT 16
#define AD_RPM_COUNT 16
float getAdvance(int rpm, float maf);
void prepareTimingMap(void);
#endif /* ADVANCE_H_ */

View File

@ -0,0 +1,46 @@
/*
* @file algo.c
*
* @date Mar 2, 2014
* @author Andrey Belomutskiy, (c) 2012-2014
*
*
* This file is part of rusEfi - see http://rusefi.com
*
* rusEfi is free software; you can redistribute it and/or modify it under the terms of
* the GNU General Public License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* rusEfi is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
* even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program.
* If not, see <http://www.gnu.org/licenses/>.
*/
#include "global.h"
#include "algo.h"
//#include "rpm_calculator.h"
#include "advance_map.h"
#include "fuel_math.h"
#include "wave_chart.h"
#include "settings.h"
WaveChart waveChart;
void initAlgo(void) {
#if EFI_PROD_CODE || EFI_SIMULATOR
initSettings();
#endif
#if EFI_WAVE_CHART
initWaveChart(&waveChart);
#endif
prepareFuelMap();
prepareTimingMap();
}

View File

@ -0,0 +1,22 @@
/*
* @file algo.h
*
* @date Mar 2, 2014
* @author Andrey Belomutskiy, (c) 2012-2014
*/
#ifndef ALGO_H_
#define ALGO_H_
#ifdef __cplusplus
extern "C"
{
#endif /* __cplusplus */
void initAlgo(void);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* ALGO_H_ */

View File

@ -0,0 +1,20 @@
CONTROLLERS_ALGO_SRC = $(PROJECT_DIR)/controllers/algo/map_adjuster.c \
$(PROJECT_DIR)/controllers/algo/fuel_math.c \
$(PROJECT_DIR)/controllers/algo/advance_map.c \
$(PROJECT_DIR)/controllers/algo/engine_configuration.c \
$(PROJECT_DIR)/controllers/algo/signal_executor.c \
$(PROJECT_DIR)/controllers/algo/interpolation.c \
$(PROJECT_DIR)/controllers/algo/malfunction_central.c \
$(PROJECT_DIR)/controllers/algo/event_registry.c \
$(PROJECT_DIR)/controllers/algo/idle_controller.c \
$(PROJECT_DIR)/controllers/algo/trigger_mazda.c \
$(PROJECT_DIR)/controllers/algo/wave_chart.c \
$(PROJECT_DIR)/controllers/algo/trigger_structure.c \
$(PROJECT_DIR)/controllers/algo/nmea.c \
$(PROJECT_DIR)/controllers/algo/algo.c \
$(PROJECT_DIR)/controllers/algo/signal_executor_single_timer_algo.c
CONTROLLERS_ALGO_SRC_CPP = $(PROJECT_DIR)/controllers/algo/trigger_decoder.cpp \
$(PROJECT_DIR)/controllers/algo/OutputSignalArray.cpp

View File

@ -0,0 +1,24 @@
/**
* @file can_header.h
*
* @date Dec 21, 2013
* @author Andrey Belomutskiy, (c) 2012-2013
*/
#ifndef CAN_HEADER_H_
#define CAN_HEADER_H_
#include "rusefi_enums.h"
/**
* Net Body Computer types
*/
typedef enum {
CAN_BUS_NBC_BMW = 0,
CAN_BUS_NBC_FIAT = 1,
CAN_BUS_NBC_VAG = 2,
Internal_ForceMyEnumIntSize_can_nbc = ENUM_SIZE_HACK,
} can_nbc_e;
#endif /* CAN_HEADER_H_ */

View File

@ -0,0 +1,330 @@
/**
* @file engine_controller.c
* @brief Utility method related to the engine configuration data structure.
*
* @date Nov 22, 2013
* @author Andrey Belomutskiy, (c) 2012-2014
*
* This file is part of rusEfi - see http://rusefi.com
*
* rusEfi is free software; you can redistribute it and/or modify it under the terms of
* the GNU General Public License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* rusEfi is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
* even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program.
* If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "main.h"
#include "engine_configuration.h"
#include "allsensors.h"
#include "interpolation.h"
#include "trigger_decoder.h"
#if EFI_PROD_CODE
#include "tunerstudio.h"
#endif
#include "audi_aan.h"
#include "dodge_neon.h"
#include "ford_aspire.h"
#include "ford_fiesta.h"
#include "ford_1995_inline_6.h"
#include "snow_blower.h"
#include "nissan_primera.h"
#include "honda_accord.h"
#include "GY6_139QMB.h"
#include "mazda_miata_nb.h"
#include "mazda_323.h"
#define ADC_CHANNEL_FAST_ADC 256
static volatile int globalConfigurationVersion = 0;
int getGlobalConfigurationVersion(void) {
return globalConfigurationVersion;
}
void incrementGlobalConfigurationVersion(void) {
globalConfigurationVersion++;
}
/**
* @brief Sets the same dwell time across the whole getRpm() range
*/
void setConstantDwell(engine_configuration_s *engineConfiguration, float dwellMs) {
for (int i = 0; i < DWELL_CURVE_SIZE; i++) {
engineConfiguration->sparkDwellBins[i] = 1000 * i;
engineConfiguration->sparkDwell[i] = dwellMs;
}
}
void initBpsxD1Sensor(afr_sensor_s *sensor) {
/**
* This decodes BPSX D1 Wideband Controller analog signal
*/
sensor->v1 = 0;
sensor->value1 = 9;
sensor->v2 = 5;
sensor->value2 = 19;
}
/**
* @brief Global default engine configuration
* This method sets the default global engine configuration. These values are later overridden by engine-specific defaults
* and the settings saves in flash memory.
*/
void setDefaultConfiguration(engine_configuration_s *engineConfiguration) {
engineConfiguration->injectorLag = 0.0;
for (int i = 0; i < IAT_CURVE_SIZE; i++) {
engineConfiguration->iatFuelCorrBins[i] = -40 + i * 10;
engineConfiguration->iatFuelCorr[i] = 1; // this correction is a multiplier
}
for (int i = 0; i < CLT_CURVE_SIZE; i++) {
engineConfiguration->cltFuelCorrBins[i] = -40 + i * 10;
engineConfiguration->cltFuelCorr[i] = 1; // this correction is a multiplier
}
// setTableValue(engineConfiguration->cltFuelCorrBins, engineConfiguration->cltFuelCorr, CLT_CURVE_SIZE, -40, 1.5);
// setTableValue(engineConfiguration->cltFuelCorrBins, engineConfiguration->cltFuelCorr, CLT_CURVE_SIZE, -30, 1.5);
// setTableValue(engineConfiguration->cltFuelCorrBins, engineConfiguration->cltFuelCorr, CLT_CURVE_SIZE, -20, 1.42);
// setTableValue(engineConfiguration->cltFuelCorrBins, engineConfiguration->cltFuelCorr, CLT_CURVE_SIZE, -10, 1.36);
// setTableValue(engineConfiguration->cltFuelCorrBins, engineConfiguration->cltFuelCorr, CLT_CURVE_SIZE, 0, 1.28);
// setTableValue(engineConfiguration->cltFuelCorrBins, engineConfiguration->cltFuelCorr, CLT_CURVE_SIZE, 10, 1.19);
// setTableValue(engineConfiguration->cltFuelCorrBins, engineConfiguration->cltFuelCorr, CLT_CURVE_SIZE, 20, 1.12);
// setTableValue(engineConfiguration->cltFuelCorrBins, engineConfiguration->cltFuelCorr, CLT_CURVE_SIZE, 30, 1.10);
// setTableValue(engineConfiguration->cltFuelCorrBins, engineConfiguration->cltFuelCorr, CLT_CURVE_SIZE, 40, 1.06);
// setTableValue(engineConfiguration->cltFuelCorrBins, engineConfiguration->cltFuelCorr, CLT_CURVE_SIZE, 50, 1.06);
// setTableValue(engineConfiguration->cltFuelCorrBins, engineConfiguration->cltFuelCorr, CLT_CURVE_SIZE, 60, 1.03);
// setTableValue(engineConfiguration->cltFuelCorrBins, engineConfiguration->cltFuelCorr, CLT_CURVE_SIZE, 70, 1.01);
for (int i = 0; i < VBAT_INJECTOR_CURVE_SIZE; i++) {
engineConfiguration->battInjectorLagCorrBins[i] = 12 - VBAT_INJECTOR_CURVE_SIZE / 2 + i;
engineConfiguration->battInjectorLagCorr[i] = 0; // zero extra time by default
}
setConstantDwell(engineConfiguration, 4); // 4ms is global default dwell
for (int k = 0; k < FUEL_LOAD_COUNT; k++) {
for (int r = 0; r < FUEL_RPM_COUNT; r++) {
// 3ms would be the global default
engineConfiguration->fuelTable[k][r] = 3;
}
}
setThermistorConfiguration(&engineConfiguration->cltThermistorConf, 0, 9500, 23.8889, 2100, 48.8889, 1000);
engineConfiguration->cltThermistorConf.bias_resistor = 1500;
setThermistorConfiguration(&engineConfiguration->iatThermistorConf, 32, 9500, 75, 2100, 120, 1000);
// todo: this value is way off! I am pretty sure temp coeffs are off also
engineConfiguration->iatThermistorConf.bias_resistor = 2700;
engineConfiguration->rpmHardLimit = 7000;
engineConfiguration->crankingSettings.crankingRpm = 550;
engineConfiguration->analogInputDividerCoefficient = 2;
engineConfiguration->crankingChargeAngle = 70;
engineConfiguration->timingMode = TM_DYNAMIC;
engineConfiguration->fixedModeTiming = 50;
engineConfiguration->analogChartMode = AC_TRIGGER;
engineConfiguration->map.channel = ADC_CHANNEL_FAST_ADC;
engineConfiguration->injectionPinMode = OM_DEFAULT;
engineConfiguration->ignitionPinMode = OM_DEFAULT;
engineConfiguration->idlePinMode = OM_DEFAULT;
engineConfiguration->fuelPumpPinMode = OM_DEFAULT;
engineConfiguration->malfunctionIndicatorPinMode = OM_DEFAULT;
engineConfiguration->globalTriggerAngleOffset = 0;
engineConfiguration->injectionOffset = 0;
engineConfiguration->ignitionOffset = 0;
engineConfiguration->engineLoadMode = LM_MAF;
engineConfiguration->vbattDividerCoeff = ((float)(15 + 65)) / 15;
engineConfiguration->fanOnTemperature = 75;
engineConfiguration->fanOffTemperature = 70;
engineConfiguration->can_nbc_type = CAN_BUS_NBC_BMW;
engineConfiguration->can_sleep_period = 50;
engineConfiguration->canReadEnabled = TRUE;
engineConfiguration->canWriteEnabled = FALSE;
/**
* 0.5 means primary position sensor is on a camshaft
*/
engineConfiguration->rpmMultiplier = 0.5;
engineConfiguration->cylindersCount = 4;
engineConfiguration->displayMode = DM_HD44780;
engineConfiguration->logFormat = LF_NATIVE;
engineConfiguration->triggerConfig.triggerType = TT_TOOTHED_WHEEL;
engineConfiguration->triggerConfig.syncRatioFrom = 1.5;
engineConfiguration->triggerConfig.syncRatioTo = 3;
engineConfiguration->triggerConfig.isSynchronizationNeeded = TRUE;
engineConfiguration->triggerConfig.useRiseEdge = TRUE;
engineConfiguration->HD44780width = 16;
engineConfiguration->HD44780height = 2;
engineConfiguration->tpsAdcChannel = 3;
engineConfiguration->vBattAdcChannel = 5;
engineConfiguration->cltAdcChannel = 6;
engineConfiguration->iatAdcChannel = 7;
engineConfiguration->mafAdcChannel = 0;
engineConfiguration->afrSensor.afrAdcChannel = 14;
initBpsxD1Sensor(&engineConfiguration->afrSensor);
engineConfiguration->globalFuelCorrection = 1;
engineConfiguration->needSecondTriggerInput = TRUE;
engineConfiguration->injectionPins[0] = GPIOB_9;
engineConfiguration->injectionPins[1] = GPIOB_8;
engineConfiguration->injectionPins[2] = GPIOE_3;
engineConfiguration->injectionPins[3] = GPIOE_5;
engineConfiguration->injectionPins[4] = GPIOE_6;
// engineConfiguration->injectionPins[5] = GPIOE_5;
engineConfiguration->ignitionPins[0] = GPIOC_7;
engineConfiguration->ignitionPins[1] = GPIOE_4; // todo: update this value
engineConfiguration->ignitionPins[2] = GPIOE_0; // todo: update this value
engineConfiguration->ignitionPins[3] = GPIOE_1; // todo: update this value
engineConfiguration->map.config.mapType = MT_CUSTOM;
engineConfiguration->map.config.Min = 0;
engineConfiguration->map.config.Max = 500;
}
void setDefaultNonPersistentConfiguration(engine_configuration2_s *engineConfiguration2) {
/**
* 720 is the range for four stroke
*/
engineConfiguration2->crankAngleRange = 720;
engineConfiguration2->hasMapSensor = TRUE;
engineConfiguration2->hasCltSensor = TRUE;
}
void resetConfigurationExt(engine_type_e engineType, engine_configuration_s *engineConfiguration, engine_configuration2_s *engineConfiguration2) {
/**
* Let's apply global defaults first
*/
setDefaultConfiguration(engineConfiguration);
engineConfiguration->engineType = engineType;
/**
* And override them with engine-specific defaults
*/
switch (engineType) {
#if EFI_SUPPORT_DODGE_NEON || defined(__DOXYGEN__)
case DODGE_NEON_1995:
setDodgeNeonEngineConfiguration(engineConfiguration);
break;
#endif /* EFI_SUPPORT_DODGE_NEON */
#if EFI_SUPPORT_FORD_ASPIRE || defined(__DOXYGEN__)
case FORD_ASPIRE_1996:
setFordAspireEngineConfiguration(engineConfiguration);
break;
#endif /* EFI_SUPPORT_FORD_ASPIRE */
#if EFI_SUPPORT_FORD_FIESTA || defined(__DOXYGEN__)
case FORD_FIESTA:
setFordFiestaDefaultEngineConfiguration(engineConfiguration);
break;
#endif /* EFI_SUPPORT_FORD_FIESTA */
case HONDA_ACCORD:
setHondaAccordConfiguration(engineConfiguration);
break;
#if EFI_SUPPORT_1995_FORD_INLINE_6 || defined(__DOXYGEN__)
case FORD_INLINE_6_1995:
setFordInline6(engineConfiguration);
break;
#endif /* EFI_SUPPORT_1995_FORD_INLINE_6 */
case GY6_139QMB:
setGy6139qmbDefaultEngineConfiguration(engineConfiguration);
break;
case MAZDA_MIATA_NB:
setMazdaMiataNbEngineConfiguration(engineConfiguration);
break;
case MAZDA_323:
setMazda323EngineConfiguration(engineConfiguration);
break;
default:
firmwareError("Unexpected engine type: %d", engineType);
}
applyNonPersistentConfiguration(engineConfiguration, engineConfiguration2, engineType);
#if EFI_TUNER_STUDIO
syncTunerStudioCopy();
#endif
}
void applyNonPersistentConfiguration(engine_configuration_s *engineConfiguration, engine_configuration2_s *engineConfiguration2, engine_type_e engineType) {
initializeTriggerShape(engineConfiguration, engineConfiguration2);
chDbgCheck(engineConfiguration2->triggerShape.size != 0, "size is zero");
chDbgCheck(engineConfiguration2->triggerShape.shaftPositionEventCount, "shaftPositionEventCount is zero");
switch (engineConfiguration->engineType) {
#if EFI_SUPPORT_DODGE_NEON
case DODGE_NEON_1995:
setDodgeNeonengine_configuration2_s(engineConfiguration, engineConfiguration2);
break;
#endif /* EFI_SUPPORT_DODGE_NEON */
#if EFI_SUPPORT_FORD_ASPIRE
case FORD_ASPIRE_1996:
setFordAspireengine_configuration2_s(engineConfiguration, engineConfiguration2);
break;
#endif /* EFI_SUPPORT_FORD_ASPIRE */
#if EFI_SUPPORT_FORD_FIESTA
case FORD_FIESTA:
setFordFiestaengine_configuration2_s(engineConfiguration, engineConfiguration2);
break;
#endif /* EFI_SUPPORT_FORD_FIESTA */
#if EFI_SUPPORT_NISSAN_PRIMERA
case NISSAN_PRIMERA:
setNissanPrimeraengine_configuration2_s(engineConfiguration, engineConfiguration2);
break;
#endif /* EFI_SUPPORT_NISSAN_PRIMERA */
case HONDA_ACCORD:
setHondaAccordConfiguration2(engineConfiguration, engineConfiguration2);
break;
#if EFI_SUPPORT_1995_FORD_INLINE_6 || defined(__DOXYGEN__)
case FORD_INLINE_6_1995:
setFordInline6_2(engineConfiguration, engineConfiguration2);
break;
#endif /* EFI_SUPPORT_1995_FORD_INLINE_6 */
case GY6_139QMB:
setGy6139qmbengine_configuration2_s(engineConfiguration, engineConfiguration2);
break;
case MAZDA_MIATA_NB:
setMazdaMiataNb_configuration2_s(engineConfiguration, engineConfiguration2);
break;
case MAZDA_323:
setMazda323configuration2_s(engineConfiguration, engineConfiguration2);
break;
default:
fatal("Unexpected engine type")
;
}
}

View File

@ -0,0 +1,295 @@
/**
* @file engine_configuration.h
* @brief Main engine configuration data structure.
*
* @date Oct 30, 2013
* @author Andrey Belomutskiy, (c) 2012-2013
*/
#ifndef ENGINE_CONFIGURATION_H_
#define ENGINE_CONFIGURATION_H_
#include "efifeatures.h"
#include "sensor_types.h"
#include "can_header.h"
#include "trigger_structure.h"
#include "event_registry.h"
#include "rusefi_enums.h"
typedef struct {
float coolantTempMinC;
float coolantTempMaxC;
float fuelAtMinTempMs;
float fuelAtMaxTempMs;
/**
* This value controls what RPM values we consider 'cranking' (any RPM below 'crankingRpm')
* Anything above 'crankingRpm' would be 'running'
*/
short int crankingRpm;
} cranking_parameters_s;
/**
* @brief Here we store information about which injector or spark should be fired when.
*/
typedef struct {
ActuatorEventList crankingInjectionEvents;
ActuatorEventList injectionEvents;
ActuatorEventList ignitionEvents;
} EventHandlerConfiguration;
#define FUEL_RPM_COUNT 16
#define FUEL_LOAD_COUNT 16
#define CLT_CURVE_SIZE 16
#define IAT_CURVE_SIZE 16
#define VBAT_INJECTOR_CURVE_SIZE 8
#define IGN_LOAD_COUNT 16
#define IGN_RPM_COUNT 16
#define DWELL_CURVE_SIZE 8
typedef enum {
AC_OFF = 0,
/**
* You would use this value if you want to see a detailed graph of your trigger events
*/
AC_TRIGGER = 1,
AC_MAP = 2,
Internal_ForceMyEnumIntSize_analog_chart_mode = ENUM_SIZE_HACK,
} analog_chart_e;
typedef enum {
/**
* This is the default mode in which ECU controls timing dynamically
*/
TM_DYNAMIC = 0,
/**
* Fixed timing is useful while you are playing with a timing gun - you need to have fixed
* timing if you want to install your distributor at some specific angle
*/
TM_FIXED = 1,
Internal_ForceMyEnumIntSize_timing_mode = ENUM_SIZE_HACK,
} timing_mode_e;
typedef struct {
int afrAdcChannel;
float v1;
float value1;
float v2;
float value2;
} afr_sensor_s;
#define DWELL_COUNT 8
/**
* @brief Engine configuration.
* Values in this data structure are adjustable and persisted in on-board flash RAM.
*
* The offsets are tracked using
* https://docs.google.com/spreadsheet/ccc?key=0AiAmAn6tn3L_dGJXZDZOcVVhaG9SaHZKU1dyMjhEV0E
*
* todo: currently the fields here are simply in the order in which they were implemented
* todo: re-arrange this structure one we have a stable code version
*/
typedef struct {
float injectorLag; // size 4, offset 0
float injectorFlow; // size 4, offset 4
float battInjectorLagCorrBins[VBAT_INJECTOR_CURVE_SIZE]; // size 32, offset 8
float battInjectorLagCorr[VBAT_INJECTOR_CURVE_SIZE]; // size 32, offset 40
float cltFuelCorrBins[CLT_CURVE_SIZE]; // size 64, offset 72
float cltFuelCorr[CLT_CURVE_SIZE]; // size 64, offset 136
float iatFuelCorrBins[IAT_CURVE_SIZE]; // size 64, offset 200
float iatFuelCorr[IAT_CURVE_SIZE]; // size 64, offset 264
short int rpmHardLimit; // size 2, offset 328
// todo: extract these two fields into a structure
// todo: we need two sets of TPS parameters - modern ETBs have to sensors
short int tpsMin; // size 2, offset 330
// tpsMax value as 10 bit ADC value. Not Voltage!
short int tpsMax; // size 2, offset 332
short int analogChartMode;
cranking_parameters_s crankingSettings;
map_s map;
// todo: merge with channel settings, use full-scale Thermistor here!
ThermistorConf cltThermistorConf; // size 40 (10*4), offset 336
ThermistorConf iatThermistorConf; // size 40, offset 376
float sparkDwellBins[DWELL_COUNT]; // offset 580
float sparkDwell[DWELL_COUNT];
float ignitionTable[IGN_LOAD_COUNT][IGN_RPM_COUNT];
float ignitionLoadBins[IGN_LOAD_COUNT]; // offset 3450
float ignitionRpmBins[IGN_RPM_COUNT]; // offset 3542
/**
* this value could be used to offset the whole ignition timing table by a constant
*/
float ignitionOffset;
/**
* While cranking (which causes battery voltage to drop) we can calculate dwell time in shaft
* degrees, not in absolute time as in running mode.
*/
float crankingChargeAngle;
timing_mode_e timingMode;
/**
* This value is used in 'fixed timing' mode, i.e. constant timing
* This mode is useful for instance while adjusting distributor location
*/
float fixedModeTiming;
// WARNING: by default, our small enums are ONE BYTE. but if the are surrounded by non-enums - alignments do the trick
engine_type_e engineType;
float fuelTable[FUEL_LOAD_COUNT][FUEL_RPM_COUNT]; // size 1024, offset 1816
float fuelLoadBins[FUEL_LOAD_COUNT]; // offset 2840
// RPM is float and not integer in order to use unified methods for interpolation
float fuelRpmBins[FUEL_RPM_COUNT]; // offset 3542
// WARNING: by default, our small enums are ONE BYTE. this one is made 4-byte with the 'ENUM_SIZE_HACK' hack
pin_output_mode_e injectionPinMode;
pin_output_mode_e ignitionPinMode;
pin_output_mode_e idlePinMode;
pin_output_mode_e fuelPumpPinMode;
pin_output_mode_e malfunctionIndicatorPinMode;
/**
* This is the angle between Top Dead Center (TDC) and the first trigger event.
* Knows this angle allows us to control timing and other angles in reference to TDC.
*/
float globalTriggerAngleOffset;
/**
* We have 3.3V ADC and most of the analog input signals are 5V, this forces us to use
* voltage dividers on the input circuits. This parameter holds the coefficient of these dividers.
* see also vbattDividerCoeff
*/
float analogInputDividerCoefficient;
/**
* This setting controls which algorithm is used for ENGINE LOAD
*/
engine_load_mode_e engineLoadMode;
/**
* see
*/
float vbattDividerCoeff;
/**
* Cooling fan turn-on temperature threshold, in Celsuis
*/
float fanOnTemperature;
/**
* Cooling fan turn-off temperature threshold, in Celsuis
*/
float fanOffTemperature;
int canReadEnabled;
int canWriteEnabled;
can_nbc_e can_nbc_type;
int can_sleep_period;
int cylindersCount;
ignition_mode_e ignitionMode;
firing_order_e firingOrder;
/**
* This magic constant is about four-stroke engines with camshaft position sensors.
* On any four stroke engine, each revolution of the camshaft is two revolutions
* of the crankshaft. If camshaft position is our primary sensor, we use this multiplier
* to convert from camshaft angles to crankshaft angles. All angels across the system
* should be crankshaft angles.
*/
float rpmMultiplier;
display_mode_e displayMode;
log_format_e logFormat;
int firmwareVersion;
int HD44780width;
int HD44780height;
int tpsAdcChannel;
brain_pin_e ignitionPins[12];
trigger_config_s triggerConfig;
int needSecondTriggerInput;
brain_pin_e injectionPins[12];
brain_pin_e fuelPumpPin;
brain_pin_e idleValvePin;
int vBattAdcChannel;
float globalFuelCorrection;
// todo: merge with channel settings, use full-scale Thermistor!
int cltAdcChannel;
int iatAdcChannel;
int mafAdcChannel;
afr_sensor_s afrSensor;
float injectionOffset;
} engine_configuration_s;
/**
* this part of the structure is separate just because so far
* these fields are not integrated with Tuner Studio. Step by step :)
*/
typedef struct {
int hasMapSensor;
int hasCltSensor;
Thermistor iat;
Thermistor clt;
int crankAngleRange;
trigger_shape_s triggerShape;
cranking_ignition_mode_e crankingIgnitionMode;
EventHandlerConfiguration engineEventConfiguration;
} engine_configuration2_s;
#ifdef __cplusplus
extern "C"
{
#endif /* __cplusplus */
char* getConfigurationName(engine_configuration_s *engineConfiguration);
void setDefaultConfiguration(engine_configuration_s *engineConfiguration);
void setConstantDwell(engine_configuration_s *engineConfiguration, float dwellMs);
void setDefaultNonPersistentConfiguration(engine_configuration2_s *engineConfiguration2);
void printConfiguration(engine_configuration_s *engineConfiguration, engine_configuration2_s *engineConfiguration2);
void printFloatArray(char *prefix, float array[], int size);
void resetConfigurationExt(engine_type_e engineType, engine_configuration_s *engineConfiguration, engine_configuration2_s *engineConfiguration2);
void applyNonPersistentConfiguration(engine_configuration_s *engineConfiguration, engine_configuration2_s *engineConfiguration2, engine_type_e engineType);
void incrementGlobalConfigurationVersion(void);
int getGlobalConfigurationVersion(void);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* ENGINE_CONFIGURATION_H_ */

View File

@ -0,0 +1,15 @@
/**
* @file engine_state.h
* @brief One header which acts as gateway to current engine state
*
* @date Dec 20, 2013
* @author Andrey Belomutskiy, (c) 2012-2013
*/
#ifndef ENGINE_STATE_H_
#define ENGINE_STATE_H_
#include "allsensors.h"
#include "rpm_calculator.h"
#endif /* ENGINE_STATE_H_ */

View File

@ -0,0 +1,28 @@
/**
* @file error_handling.h
*
* @date Mar 6, 2014
* @author Andrey Belomutskiy, (c) 2012-2013
*/
#ifndef ERROR_HANDLING_H_
#define ERROR_HANDLING_H_
#ifdef __cplusplus
extern "C"
{
#endif /* __cplusplus */
int warning(const char *fmt, ...);
void firmwareError(const char *fmt, ...);
int hasFatalError(void);
void fatal3(char *msg, char *file, int line);
#define fatal(x) (fatal3(x, __FILE__, __LINE__));
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* ERROR_HANDLING_H_ */

View File

@ -0,0 +1,61 @@
/**
* @file event_registry.c
* @brief This data structure knows when to do what
*
* @date Nov 27, 2013
* @author Andrey Belomutskiy, (c) 2012-2014
*
*
* This file is part of rusEfi - see http://rusefi.com
*
* rusEfi is free software; you can redistribute it and/or modify it under the terms of
* the GNU General Public License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* rusEfi is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
* even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program.
* If not, see <http://www.gnu.org/licenses/>.
*/
#include "event_registry.h"
#include "main.h"
#include "engine_math.h"
extern engine_configuration_s *engineConfiguration;
extern engine_configuration2_s *engineConfiguration2;
void resetEventList(ActuatorEventList *list) {
list->size = 0;
}
static void copyActuatorEvent(ActuatorEvent *source, ActuatorEvent*target) {
target->eventIndex = source->eventIndex;
target->actuator = source->actuator;
target->angleOffset = source->angleOffset;
}
void registerActuatorEvent(ActuatorEventList *list, int eventIndex, OutputSignal *actuator, float angleOffset) {
if (list->size == MAX_EVENT_COUNT) {
fatal("registerActuatorEvent");
return;
}
ActuatorEvent *e = &list->events[list->size++];
e->eventIndex = eventIndex;
e->actuator = actuator;
e->angleOffset = angleOffset;
}
void findEvents(int eventIndex, ActuatorEventList *source, ActuatorEventList *target) {
resetEventList(target);
// todo: implement something faster
for (int i = 0; i < source->size; i++) {
ActuatorEvent *s = &source->events[i];
if (s->eventIndex != eventIndex)
continue;
// todo: migrate to pointers instead of copying an object?
copyActuatorEvent(s, &target->events[target->size++]);
}
}

View File

@ -0,0 +1,53 @@
/**
* @file event_registry.h
*
* @date Nov 27, 2013
* @author Andrey Belomutskiy, (c) 2012-2013
*/
#ifndef EVENT_REGISTRY_H_
#define EVENT_REGISTRY_H_
#include "global.h"
#include "signal_executor.h"
#include "trigger_structure.h"
#define MAX_EVENT_COUNT 40
typedef struct {
int eventIndex;
OutputSignal *actuator;
float angleOffset;
} ActuatorEvent;
typedef struct {
int size;
ActuatorEvent events[MAX_EVENT_COUNT];
} ActuatorEventList;
#ifdef __cplusplus
extern "C"
{
#endif /* __cplusplus */
void resetEventList(ActuatorEventList *list);
/**
* this is an intermediate implementation of flexible event handling.
*
* In the future implementation we will drop the 'eventIndex' parameter and everything will be
* angle-driven. But that's just a plan for next iteration.
*
* @param actuator injector or coil OutputSignal
*/
void registerActuatorEvent(ActuatorEventList *list, int eventIndex, OutputSignal *actuator, float angleOffset);
void findEvents(int eventIndex, ActuatorEventList *source, ActuatorEventList *target);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* EVENT_REGISTRY_H_ */

View File

@ -0,0 +1,155 @@
/**
* @file fuel_math.c
* @brief Fuel amount calculation logic
*
* While engine running, fuel amount is an interpolated value from the fuel map by getRpm() and getEngineLoad()
* On top of the value from the fuel map we also apply
* <BR>1) getInjectorLag() correction to account for fuel injector lag
* <BR>2) getCltCorrection() for warm-up
* <BR>3) getIatCorrection() to account for cold weather
*
* getCrankingFuel() depents only on getCoolantTemperature()
*
*
* @date May 27, 2013
* @author Andrey Belomutskiy, (c) 2012-2014
*
* This file is part of rusEfi - see http://rusefi.com
*
* rusEfi is free software; you can redistribute it and/or modify it under the terms of
* the GNU General Public License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* rusEfi is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
* even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program.
* If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "main.h"
#include "fuel_math.h"
#include "interpolation.h"
#include "engine_configuration.h"
#include "allsensors.h"
#include "engine_math.h"
static float *fuel_ptrs[FUEL_LOAD_COUNT];
static int initialized = FALSE;
extern engine_configuration_s *engineConfiguration;
/**
* @brief Initialize fuel map data structure
* @note this method has nothing to do with fuel map VALUES - it's job
* is to prepare the fuel map data structure for 3d interpolation
*/
void prepareFuelMap(void) {
for (int k = 0; k < FUEL_LOAD_COUNT; k++)
fuel_ptrs[k] = engineConfiguration->fuelTable[k];
initialized = TRUE;
}
/**
* @brief Engine warm-up fuel correction.
*/
float getCltCorrection(float clt) {
if (cisnan(clt))
return 1; // this error should be already reported somewhere else, let's just handle it
return interpolate2d(clt, engineConfiguration->cltFuelCorrBins, engineConfiguration->cltFuelCorr, CLT_CURVE_SIZE);
}
float getIatCorrection(float iat) {
if (cisnan(iat))
return 1; // this error should be already reported somewhere else, let's just handle it
return interpolate2d(iat, engineConfiguration->iatFuelCorrBins, engineConfiguration->iatFuelCorr, IAT_CURVE_SIZE);
}
/**
* @brief Injector lag correction
* @param vBatt Battery voltage.
* @return Time in ms for injection opening time based on current battery voltage
*/
float getInjectorLag(float vBatt) {
if (cisnan(vBatt)) {
warning("vBatt=%f", vBatt);
return 0;
}
float vBattCorrection = interpolate2d(vBatt, engineConfiguration->battInjectorLagCorrBins,
engineConfiguration->battInjectorLagCorr, VBAT_INJECTOR_CURVE_SIZE);
return engineConfiguration->injectorLag + vBattCorrection;
}
float getBaseFuel(int rpm, float engineLoad) {
chDbgCheck(initialized, "fuel map initialized");
return interpolate3d(engineLoad, engineConfiguration->fuelLoadBins, FUEL_LOAD_COUNT, rpm, engineConfiguration->fuelRpmBins,
FUEL_RPM_COUNT, fuel_ptrs);
}
float getCrankingFuel(void) {
return getStartingFuel(getCoolantTemperature());
}
int isCranking(void);
/**
* @returns Length of fuel injection, in milliseconds
*/
float getFuelMs(int rpm) {
if (isCranking()) {
return getCrankingFuel();
} else {
float fuel = getRunningFuel(rpm, getEngineLoad());
return fuel;
}
}
float getRunningFuel(int rpm, float engineLoad) {
float baseFuel = getBaseFuel(rpm, engineLoad);
float iatCorrection = getIatCorrection(getIntakeAirTemperature());
float cltCorrection = getCltCorrection(getCoolantTemperature());
float injectorLag = getInjectorLag(getVBatt());
return baseFuel * cltCorrection * iatCorrection + injectorLag;
}
float getStartingFuel(float coolantTemperature) {
// these magic constants are in Celsius
if (cisnan(coolantTemperature)
|| coolantTemperature
< engineConfiguration->crankingSettings.coolantTempMinC)
return engineConfiguration->crankingSettings.fuelAtMinTempMs;
if (coolantTemperature
> engineConfiguration->crankingSettings.coolantTempMaxC)
return engineConfiguration->crankingSettings.fuelAtMaxTempMs;
return interpolate(engineConfiguration->crankingSettings.coolantTempMinC,
engineConfiguration->crankingSettings.fuelAtMinTempMs,
engineConfiguration->crankingSettings.coolantTempMaxC,
engineConfiguration->crankingSettings.fuelAtMaxTempMs,
coolantTemperature);
}
/**
* @return 0 for OM_DEFAULT and OM_OPENDRAIN
*/
inline static int getElectricalValue0(pin_output_mode_e mode) {
return mode == OM_INVERTED || mode == OM_OPENDRAIN_INVERTED;
}
/**
* @return 1 for OM_DEFAULT and OM_OPENDRAIN
*/
inline static int getElectricalValue1(pin_output_mode_e mode) {
return mode == OM_DEFAULT || mode == OM_OPENDRAIN;
}
// todo: this method is here for unit test visibility. todo: move to a bette place!
int getElectricalValue(int logicalValue, pin_output_mode_e mode) {
chDbgCheck(mode <= OM_OPENDRAIN_INVERTED, "invalid pin_output_mode_e");
return logicalValue ? getElectricalValue1(mode) : getElectricalValue0(mode);
}

View File

@ -0,0 +1,21 @@
/**
* @file fuel_math.h
*
* @date May 27, 2013
* @author Andrey Belomutskiy, (c) 2012-2013
*/
#ifndef FUEL_MAP_H_
#define FUEL_MAP_H_
void prepareFuelMap(void);
float getBaseFuel(int rpm, float engineLoad);
float getIatCorrection(float iat);
float getInjectorLag(float vBatt);
float getCltCorrection(float clt);
float getRunningFuel(int rpm, float engineLoad);
float getStartingFuel(float coolantTemperature);
float getFuelMs(int rpm);
#endif /* FUEL_MAP_H_ */

View File

@ -0,0 +1,107 @@
/**
* @file idle_controller.c
* @brief Simple Idle Air Valve control algorithm
*
* This algorithm is trying to get current RPM to the desired 'target' value
* by changing Idle Air Valve solenoid duty cycle. Depending on how far current RPM
* is from the target RPM, the incremental change would be smaller or bigger.
*
*
* todo: DEFAULT_IDLE_DUTY should be a field on the IdleValveState, not a constant
*
* @date May 22, 2013
* @author Andrey Belomutskiy, (c) 2012-2014
*/
#include "idle_controller.h"
void idleDebug(char *msg, int value);
int isCranking(void);
static int lastGoodValue = DEFAULT_IDLE_DUTY;
void idleInit(IdleValveState *idle) {
idle->value = DEFAULT_IDLE_DUTY;
setTargetRpm(idle, DEFAULT_TARGET_RPM);
idle->timeOfLastIdleChange = 0;
}
void setTargetRpm(IdleValveState *idle, int targetRpm) {
idle->targetRpmRangeLeft = (int)(targetRpm * 0.93);
idle->targetRpmRangeRight = (int)(targetRpm * 1.07);
}
int min(int i1, int i2) {
return i1 < i2 ? i1 : i2;
}
int max(int i1, int i2) {
return i1 > i2 ? i1 : i2;
}
float maxF(float i1, float i2) {
return i1 > i2 ? i1 : i2;
}
/**
* @brief sets new idle valve duty cycle: checks the bounds and reports new value
*/
static int setNewValue(IdleValveState *idle, int currentRpm, int now, char * msg, int newValue) {
newValue = max(newValue, MIN_IDLE);
newValue = min(newValue, MAX_IDLE);
if (idle->value != newValue) {
idleDebug(msg, currentRpm);
idle->timeOfLastIdleChange = now;
}
idle->value = newValue;
return newValue;
}
static int changeValue(IdleValveState *idle, int currentRpm, int now, char * msg, int delta) {
int newValue = idle->value + delta;
return setNewValue(idle, currentRpm, now, msg, newValue);
}
/**
* now - current time in seconds
*/
int getIdle(IdleValveState *idle, int currentRpm, int now) {
if (currentRpm == 0 || isCranking()) {
return setNewValue(idle, currentRpm, now, "cranking value: ", DEFAULT_IDLE_DUTY);
}
if (currentRpm < 0.7 * idle->targetRpmRangeLeft) {
return setNewValue(idle, currentRpm, now, "RPMs are seriously low: ", lastGoodValue);
}
if (now - idle->timeOfLastIdleChange < IDLE_PERIOD) {
// too soon to adjust anything - exiting
return idle->value;
}
if (currentRpm > idle->targetRpmRangeLeft && currentRpm < idle->targetRpmRangeRight) {
// current RPM is good enough
// todo: need idle signal input
//lastGoodValue = idle->value;
return idle->value;
}
if (currentRpm >= idle->targetRpmRangeRight + 100)
return changeValue(idle, currentRpm, now, "rpm is too high: ", -IDLE_DECREASE_STEP);
if (currentRpm >= idle->targetRpmRangeRight)
return changeValue(idle, currentRpm, now, "rpm is a bit too high: ", -1);
// we are here if RPM is low, let's see how low
// if (currentRpm < 0.7 * idle->targetRpmRangeLeft) {
// // todo: act faster in case of really low RPM?
// return setNewValue(idle, currentRpm, now, "RPMs are seriously low: ", 15 * IDLE_INCREASE_STEP);
// } else
if (currentRpm < idle->targetRpmRangeLeft - 100) {
return changeValue(idle, currentRpm, now, "RPMs are low: ", IDLE_INCREASE_STEP);
}
return changeValue(idle, currentRpm, now, "RPMs are a bit low: ", 1);
}

View File

@ -0,0 +1,44 @@
/**
* @file idle_controller.h
*
* @date May 22, 2013
* @author Andrey Belomutskiy, (c) 2012-2013
*/
#ifndef IDLE_CONTROLLER_H_
#define IDLE_CONTROLLER_H_
// 700‰ duty cycle by default
#define DEFAULT_IDLE_DUTY 600
#define DEFAULT_TARGET_RPM 1000
//#define DEFAULT_TARGET_RPM 2000
#define IDLE_PERIOD 1
// Per mil (1/1000) values
#define MIN_IDLE 100
#define MAX_IDLE 900
#define IDLE_INCREASE_STEP 5
#define IDLE_DECREASE_STEP 5
typedef struct {
int time;
int targetRpmRangeLeft, targetRpmRangeRight;
int value;
int timeOfLastIdleChange;
} IdleValveState;
void idleInit(IdleValveState *idle);
int getIdle(IdleValveState *idle, int currentRpm, int time);
void setTargetRpm(IdleValveState *idle, int targetRpm);
// todo: move these somewhere else!
int max(int i1, int i2);
int min(int i1, int i2);
float maxF(float i1, float i2);
#endif /* IDLE_CONTROLLER_H_ */

View File

@ -0,0 +1,214 @@
/**
* @file interpolation.c
* @brief Linear interpolation algorithms
*
* @date Oct 17, 2013
* @author Andrey Belomutskiy, (c) 2012-2014
*/
#if DEBUG_FUEL
#include <stdio.h>
#endif
#include <math.h>
#include "main.h"
#include "interpolation.h"
#include "engine_math.h"
#define INTERPOLATION_A(x1, y1, x2, y2) ((y1 - y2) / (x1 - x2))
int needInterpolationLogging = TRUE;
/** @brief Linear interpolation by two points
*
* @param x1 key of the first point
* @param y1 value of the first point
* @param x2 key of the second point
* @param y2 value of the second point
* @param X key to be interpolated
*
* @note For example, "interpolate(engineConfiguration.tpsMin, 0, engineConfiguration.tpsMax, 100, adc);"
*/
float interpolate(float x1, float y1, float x2, float y2, float x) {
// a*x1 + b = y1
// a*x2 + b = y2
// chDbgCheck(x1 != x2, "no way we can interpolate");
float a = INTERPOLATION_A(x1, y1, x2, y2);
float b = y1 - a * x1;
float result = a * x + b;
#if DEBUG_FUEL
printf("x1=%f y1=%f x2=%f y2=%f\r\n", x1, y1, x2, y2);
printf("a=%f b=%f result=%f\r\n", a, b, result);
#endif
return result;
}
/** @brief Binary search
* @returns the highest index within sorted array such that array[i] is greater than or equal to the parameter
* @note If the parameter is smaller than the first element of the array, -1 is returned.
*/
int findIndex(float array[], int size, float value) {
if (cisnan(value))
fatal("NaN in findIndex\r\n");
if (value < array[0])
return -1;
int middle;
int left = 0;
int right = size;
while (1) {
if (size-- == 0)
fatal("Unexpected state in binary search.");
middle = (left + right) / 2;
// print("left=%d middle=%d right=%d: %f\r\n", left, middle, right, array[middle]);
if (middle == left)
break;
if (value < array[middle]) {
right = middle;
} else if (value > array[middle]) {
left = middle;
} else {
break;
}
}
return middle;
}
/**
* @brief One-dimensional table lookup with linear interpolation
*/
float interpolate2d(float value, float bin[], float values[], int size) {
int index = findIndex(bin, size, value);
if (index == -1)
return values[0];
if (index == size - 1)
return values[size - 1];
return interpolate(bin[index], values[index], bin[index + 1], values[index + 1], value);
}
/**
* @brief Two-dimensional table lookup with linear interpolation
*/
float interpolate3d(float x, float xBin[], int xBinSize, float y, float yBin[], int yBinSize, float* map[]) {
if (cisnan(y)) {
warning("%f: x is NaN in interpolate3d", x);
return NAN;
}
if (cisnan(y)) {
warning("%f: y is NaN in interpolate3d", y);
return NAN;
}
int xIndex = findIndex(xBin, xBinSize, x);
#if DEBUG_INTERPOLATION
if (needInterpolationLogging)
printf("X index=%d\r\n", xIndex);
#endif
int yIndex = findIndex(yBin, yBinSize, y);
if (xIndex < 0 && yIndex < 0) {
#if DEBUG_INTERPOLATION
if (needInterpolationLogging)
printf("X and Y are smaller than smallest cell in table: %d\r\n", xIndex);
#endif
return map[0][0];
}
if (xIndex < 0) {
#if DEBUG_INTERPOLATION
if (needInterpolationLogging)
printf("X is smaller than smallest cell in table: %dr\n", xIndex);
#endif
// no interpolation should be fine here.
return map[0][yIndex];
}
if (yIndex < 0) {
#if DEBUG_INTERPOLATION
if (needInterpolationLogging)
printf("Y is smaller than smallest cell in table: %d\r\n", yIndex);
#endif
// no interpolation should be fine here.
return map[xIndex][0];
}
if (xIndex == xBinSize - 1 && yIndex == yBinSize - 1) {
#if DEBUG_INTERPOLATION
if (needInterpolationLogging)
printf("X and Y are larger than largest cell in table: %d %d\r\n", xIndex, yIndex);
#endif
return map[xBinSize - 1][yBinSize - 1];
}
if (xIndex == xBinSize - 1) {
#if DEBUG_INTERPOLATION
if (needInterpolationLogging)
printf("TODO BETTER LOGGING x overflow %d\r\n", yIndex);
#endif
// todo: implement better handling - y interpolation
return map[xBinSize - 1][yIndex];
}
if (yIndex == yBinSize - 1) {
#if DEBUG_INTERPOLATION
if (needInterpolationLogging)
printf("Y is larger than largest cell in table: %d\r\n", yIndex);
#endif
// todo: implement better handling - x interpolation
return map[xIndex][yBinSize - 1];
}
/*
* first we find the interpolated value for this RPM
*/
int rpmMaxIndex = xIndex + 1;
float xMin = xBin[xIndex];
float xMax = xBin[xIndex + 1];
float rpmMinKeyMinValue = map[xIndex][yIndex];
float rpmMaxKeyMinValue = map[xIndex + 1][yIndex];
float keyMinValue = interpolate(xMin, rpmMinKeyMinValue, xMax, rpmMaxKeyMinValue, x);
#if DEBUG_INTERPOLATION
if (needInterpolationLogging) {
printf("X=%f:\r\nrange %f - %f\r\n", x, xMin, xMax);
printf("X interpolation range %f %f result %f\r\n", rpmMinKeyMinValue, rpmMaxKeyMinValue, keyMinValue);
}
#endif
int keyMaxIndex = yIndex + 1;
float keyMin = yBin[yIndex];
float keyMax = yBin[keyMaxIndex];
float rpmMinKeyMaxValue = map[xIndex][keyMaxIndex];
float rpmMaxKeyMaxValue = map[rpmMaxIndex][keyMaxIndex];
float keyMaxValue = interpolate(xMin, rpmMinKeyMaxValue, xMax, rpmMaxKeyMaxValue, x);
#if DEBUG_INTERPOLATION
if (needInterpolationLogging) {
printf("key=%f:\r\nrange %f - %f\r\n", y, keyMin, keyMax);
printf("key interpolation range %f %f result %f\r\n", rpmMinKeyMaxValue, rpmMaxKeyMaxValue, keyMaxValue);
}
#endif
float result = interpolate(keyMin, keyMinValue, keyMax, keyMaxValue, y);
return result;
}
void setTableValue(float bins[], float values[], int size, float key, float value) {
int index = findIndex(bins, size, key);
if (index == -1)
index = 0;
values[index] = value;
}

View File

@ -0,0 +1,17 @@
/**
* @file interpolation.h
*
* @date Oct 17, 2013
* @author Andrey Belomutskiy, (c) 2012-2013
*/
#ifndef INTERPOLATION_3D_H_
#define INTERPOLATION_3D_H_
int findIndex(float array[], int size, float value);
float interpolate(float x1, float y1, float x2, float y2, float x);
float interpolate2d(float value, float bin[], float values[], int size);
float interpolate3d(float x, float xBin[], int xBinSize, float y, float yBin[], int yBinSize, float* map[]);
void setTableValue(float bins[], float values[], int size, float key, float value);
#endif /* INTERPOLATION_3D_H_ */

View File

@ -0,0 +1,108 @@
/**
* @file io_pins.h
*
* @date Jan 24, 2013
* @author Andrey Belomutskiy, (c) 2012-2013
*/
#ifndef STATUS_LEDS_H_
#define STATUS_LEDS_H_
#include "main.h"
typedef enum {
LED_CRANKING, // Orange on-board LED
LED_RUNNING, // Green on-board LED
LED_ERROR, // Red on-board LED
LED_COMMUNICATION_1, // Blue on-board LED
LED_EXT_1, // external board LED
LED_EXT_2, // external board LED
LED_EXT_3, // external board LED
LED_DEBUG,
LED_EMULATOR,
IDLE_VALVE,
TRIGGER_EMILATOR_PRIMARY,
TRIGGER_EMILATOR_SECONDARY,
SPARKOUT_1_OUTPUT,
SPARKOUT_2_OUTPUT,
SPARKOUT_3_OUTPUT,
SPARKOUT_4_OUTPUT,
SPARKOUT_5_OUTPUT,
SPARKOUT_6_OUTPUT,
INJECTOR_1_OUTPUT,
INJECTOR_2_OUTPUT,
INJECTOR_3_OUTPUT,
INJECTOR_4_OUTPUT,
INJECTOR_5_OUTPUT,
INJECTOR_6_OUTPUT,
ELECTRONIC_THROTTLE_CONTROL_1,
ELECTRONIC_THROTTLE_CONTROL_2,
ELECTRONIC_THROTTLE_CONTROL_3,
/* digit 1 */
LED_HUGE_0, // B2
LED_HUGE_1,
LED_HUGE_2,
LED_HUGE_3,
LED_HUGE_4,
LED_HUGE_5,
LED_HUGE_6,
/* digit 2 */
LED_HUGE_7,
LED_HUGE_8,
LED_HUGE_9, // E15
LED_HUGE_10,
LED_HUGE_11,
LED_HUGE_12,
LED_HUGE_13,
/* digit 3 */
LED_HUGE_14,
LED_HUGE_15,
LED_HUGE_16,
LED_HUGE_17,
LED_HUGE_18,
LED_HUGE_19,
LED_HUGE_20,
// malfunction LED indicator - CheckEngine
LED_CHECK_ENGINE,
FUEL_PUMP_RELAY,
FAN_RELAY,
SPI_CS_1,
SPI_CS_2,
SPI_CS_3,
SPI_CS_4,
SPI_CS_SD_MODULE,
} io_pin_e;
#define IO_PIN_COUNT 100
#ifdef __cplusplus
extern "C"
{
#endif /* __cplusplus */
void initPrimaryPins(void);
void initOutputPins(void);
char *getPinName(io_pin_e io_pin);
void turnOutputPinOn(io_pin_e pin);
void turnOutputPinOff(io_pin_e pin);
void setOutputPinValue(io_pin_e pin, int logicValue);
int getElectricalValue(int logicalValue, pin_output_mode_e mode);
int getOutputPinValue(io_pin_e pin);
void setDefaultPinState(io_pin_e pin, pin_output_mode_e *defaultState);
void outputPinRegisterExt2(char *msg, io_pin_e ioPin, brain_pin_e brainPin, pin_output_mode_e *outputMode);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* STATUS_LEDS_H_ */

View File

@ -0,0 +1,34 @@
/**
* @file main_trigger_callback.h
* @brief Main logic header
*
*
* @date Feb 9, 2013
* @author Andrey Belomutskiy, (c) 2012-2013
*/
#ifndef MAIN_LOOP_H_
#define MAIN_LOOP_H_
#include "main.h"
#define MAX_INJECTOR_COUNT 12
#define MAX_IGNITER_COUNT 4
#ifdef __cplusplus
extern "C"
{
#endif /* __cplusplus */
#include "event_registry.h"
void initMainEventListener(void);
void showMainHistogram(void);
void onEveryMillisecondTimerSignal(void);
int isIgnitionTimingError(void);
float getFuel(int rpm, float key);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* MAIN_LOOP_H_ */

View File

@ -0,0 +1,60 @@
/**
* @file malfunction_central.c
* @brief This data structure holds current malfunction codes
*
* @date Dec 20, 2013
* @author Andrey Belomutskiy, (c) 2012-2014
*/
#include "malfunction_central.h"
static error_codes_set_s error_codes_set;
/**
* @return -1 if code not found
*/
static int find_position(obd_code_e e_code) // Search if code is present
{
// cycle for searching element equal seaching code
for (int t = 0; t < error_codes_set.count; t++)
if (error_codes_set.error_codes[t] == e_code)
return t; // we found position where this code is present
return -1; // -1 if code not found
}
void initMalfunctionCentral(void) {
error_codes_set.count = 0;
}
void addError(obd_code_e errorCode) {
if (error_codes_set.count < MAX_ERROR_CODES_COUNT && find_position(errorCode) == -1) {
error_codes_set.error_codes[error_codes_set.count] = errorCode;
error_codes_set.count++;
}
}
void removeError(obd_code_e errorCode) {
int pos = find_position(errorCode);
if (pos >= 0) {
for (int t = pos; t < error_codes_set.count; t++) // shift all right elements to one pos left
error_codes_set.error_codes[t] = error_codes_set.error_codes[t + 1];
error_codes_set.error_codes[--error_codes_set.count] = 0; // place 0
}
}
void setError(int flag, obd_code_e errorCode) {
if (flag)
addError(errorCode);
else
removeError(errorCode);
}
void getErrorCodes(error_codes_set_s * copy) {
copy->count = error_codes_set.count;
for (int i = 0; i < copy->count; i++)
copy->error_codes[i] = error_codes_set.error_codes[i];
}
bool_t hasErrorCodes(void) {
return error_codes_set.count > 0;
}

View File

@ -0,0 +1,58 @@
/**
* @file malfunction_central.h
* @brief This data structure holds current malfunction codes
*
* @date Dec 20, 2013
* @author Andrey Belomutskiy, (c) 2012-2013
*/
#ifndef MALFUNCTION_CENTRAL_H_
#define MALFUNCTION_CENTRAL_H_
#ifdef __cplusplus
extern "C"
{
#endif /* __cplusplus */
#include "main.h"
#include "obd_error_codes.h"
#define MAX_ERROR_CODES_COUNT 10
typedef struct {
int count;
obd_code_e error_codes[MAX_ERROR_CODES_COUNT];
} error_codes_set_s;
void initMalfunctionCentral(void);
/**
* @brief Adds an error code into the set of current errors.
* The error code is placed into the fixed-size data structure if it fits into it.
* The error code stays in the data structure till it is removed by 'clearError'
*
*/
void addError(obd_code_e errorCode);
/**
* @brief Removed the error code from the set of current errors.
*
*/
void removeError(obd_code_e errorCode);
void setError(int flag, obd_code_e errorCode);
/**
* @brief Copies the current set of errors into the specified buffer
*/
void getErrorCodes(error_codes_set_s * buffer);
bool_t hasErrorCodes(void);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* MALFUNCTION_CENTRAL_H_ */

View File

@ -0,0 +1,88 @@
/*
* map_adjuster.c
*
* @date Jul 23, 2013
* @author Andrey Belomutskiy, (c) 2012-2014
*
*
* This file is part of rusEfi - see http://rusefi.com
*
* rusEfi is free software; you can redistribute it and/or modify it under the terms of
* the GNU General Public License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* rusEfi is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
* even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program.
* If not, see <http://www.gnu.org/licenses/>.
*/
#include <stddef.h>
#include "map_adjuster.h"
#include "avg_values.h"
#define TARGET_MIN_AFR 11
#define TARGET_MAX_AFR 16
#define HOW_MANY_MEASURMENTS_ARE_NEEDED 5
#define MULT_STEP_DOWN 0.92
#if 0
static AvgTable adjustments;
static AvgTable afrs;
void initMapAdjuster(void) {
avgReset(&afrs);
avgFill(&adjustments, 1, 1);
}
float maxF(float i1, float i2) {
return i1 > i2 ? i1 : i2;
}
static int adjustCell(int i, int j, void (*callback)(int, float, float)) {
int count = afrs.counts[i][j];
if (count < HOW_MANY_MEASURMENTS_ARE_NEEDED)
return 0;
float value = avgGetValueByIndexes(&afrs, i, j);
afrs.counts[i][j] = 0;
afrs.values[i][j] = 0;
if (value < TARGET_MIN_AFR) {
float currentMult = adjustments.values[i][j];
// printf("adj %d %d. cur=%f\r\n", i, j, currentMult);
float newValue = maxF(0.1, MULT_STEP_DOWN * currentMult);
adjustments.values[i][j] = newValue;
// printf("adj %d %d. new=%f\r\n", i, j, adjustments.values[i][j]);
if (callback != NULL)
callback(MAX_RPM * i / AVG_TAB_SIZE, 1.0 * MAX_KEY * j / AVG_TAB_SIZE, newValue);
return 1;
}
return 0;
}
int runMapAdjustments(void (*callback)(int, float, float)) {
int total = 0;
for (int i = 0; i < AVG_TAB_SIZE; i++) {
for (int j = 0; j < AVG_TAB_SIZE; j++) {
total += adjustCell(i, j, callback);
}
}
return total;
}
void addAfr(int rpm, float key, float afr) {
avgAddValue(&afrs, rpm, key, afr);
}
float getMultiplier(int rpm, float key) {
return avgGetValue(&adjustments, rpm, key);
}
#endif /* 0 */

View File

@ -0,0 +1,17 @@
/*
* map_adjuster.h
*
* @date Jul 23, 2013
* @author Andrey Belomutskiy, (c) 2012-2013
*/
#ifndef MAP_ADJUSTER_H_
#define MAP_ADJUSTER_H_
void initMapAdjuster(void);
int runMapAdjustments(void (*callback)(int, float, float));
void addAfr(int rpm, float key, float afr);
float getMultiplier(int rpm, float key);
#endif /* MAP_ADJUSTER_H_ */

View File

@ -0,0 +1,318 @@
/**
* @date Dec 20, 2013
*
* @author Andrey Belomutskiy, (c) 2012-2014
* @author Kot_dnz
*
* This file is part of rusEfi - see http://rusefi.com
*
* rusEfi is free software; you can redistribute it and/or modify it under the terms of
* the GNU General Public License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* rusEfi is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
* even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program.
* If not, see <http://www.gnu.org/licenses/>.
*/
#include <math.h>
#include <time.h>
#include "main.h"
#include "nmea.h"
long hex2int(char *a, int len) {
int i;
long val = 0;
for (i = 0; i < len; i++)
if (a[i] <= 57)
val += (a[i] - 48) * (1 << (4 * (len - 1 - i))); // it's number
else
val += (a[i] - 87) * (1 << (4 * (len - 1 - i))); // it's a-f -> work only with low case hex
return val;
}
int str2int(char *a, int len) {
int i = 0, k = 0;
while (i<len) {
k = (k<<3)+(k<<1)+(*a)-'0';
a++;
i++;
}
return k;
}
float gps_deg_dec(float deg_point) {
double ddeg;
double sec = modf(deg_point, &ddeg) * 60;
int deg = (int) (ddeg / 100);
int min = (int) (deg_point - (deg * 100));
float absdlat = round(deg * 1000000.);
float absmlat = round(min * 1000000.);
float absslat = round(sec * 1000000.);
return round(absdlat + (absmlat / 60) + (absslat / 3600)) / 1000000;
}
// Convert lat e lon to decimals (from deg)
void gps_convert_deg_to_dec(float *latitude, char ns, float *longitude, char we) {
float lat = (ns == 'N') ? *latitude : -1 * (*latitude);
float lon = (we == 'E') ? *longitude : -1 * (*longitude);
*latitude = gps_deg_dec(lat);
*longitude = gps_deg_dec(lon);
}
// in string collect all char till comma and convert to float
int str_till_comma(char *a, char *dStr) {
int i = 0, sLen = strlen(a);
if (sLen > GPS_MAX_STRING)
sLen = GPS_MAX_STRING;
while (a[i] != 44 && i < sLen) { // while not comma or end
dStr[i] = a[i];
i++;
}
dStr[i] = '\0';
return i;
}
/*
GxGGA - name code
Parameter Value Unit Description
UTC hhmmss.sss Universal time coordinated
Lat ddmm.mmmm Latitude
Northing Indicator N=North, S=South
Lon dddmm.mmmm Longitude
Easting Indicator E=East, W=West
Status 0 0=Invalid, 1=2D/3D, 2=DGPS, 6=Dead Reckoning
SVs Used 00 Number of SVs used for Navigation
HDOP 99.99 Horizontal Dilution of Precision
Alt (MSL) m Altitude (above means sea level)
Unit M=Meters
Geoid Sep. m Geoid Separation = Alt(HAE) - Alt(MSL)
Unit M=Meters
Age of DGPS Corr s Age of Differential Corrections
DGPS Ref Station ID of DGPS Reference Station
*/
void nmea_parse_gpgga(char *nmea, loc_t *loc) {
char *p = nmea;
char dStr[GPS_MAX_STRING];
p = strchr(p, ',') + 1; //skip time - we read date&time if Valid in GxRMC
p = strchr(p, ',') + 1; // in p string started with searching address
str_till_comma(p, dStr); // str to float till comma saved modified string
if(strlen(p) == 0) return; // if no data in field - empty data - we return
loc->latitude = atoff(dStr); // fulfil data
p = strchr(p, ',') + 1; // see above
switch (p[0]) {
case 'N':
loc->lat = 'N';
break;
case 'S':
loc->lat = 'S';
break;
case ',':
loc->lat = '\0';
break;
}
p = strchr(p, ',') + 1;
str_till_comma(p, dStr); // str to float till comma saved modified string
loc->longitude = atoff(dStr);
p = strchr(p, ',') + 1;
switch (p[0]) {
case 'W':
loc->lon = 'W';
break;
case 'E':
loc->lon = 'E';
break;
case ',':
loc->lon = '\0';
break;
}
p = strchr(p, ',') + 1;
str_till_comma(p, dStr); // str to float till comma saved modified string
loc->quality = atoi(dStr);
p = strchr(p, ',') + 1;
str_till_comma(p, dStr); // str to float till comma saved modified string
loc->satellites = atoi(dStr);
p = strchr(p, ',') + 1;
p = strchr(p, ',') + 1;
str_till_comma(p, dStr); // str to float till comma saved modified string
loc->altitude = atoff(dStr);
}
/*
GxRMC - nmea code
Parameter Value Unit Description
UTC hhmmss.sss Universal time coordinated
Status V A=Valid, V=Invalid
Lat ddmm.mmmm Latitude
Northing Indicator N=North, S=South
Lon dddmm.mmmm Longitude
Easting Indicator E=East, W=West
SOG nots Speed Over Ground
COG (true) ° Course Over Ground (true)
Date ddmmyy Universal time coordinated
Magnetic Variation ° Magnetic Variation
Magnetic Variation E=East,W=West
Mode Indicator N A=Autonomous, D=Differential, E=Dead Reckoning, N=None
Navigational Status S=Safe C=Caution U=Unsafe V=Not valid
*/
void nmea_parse_gprmc(char *nmea, loc_t *loc) {
char *p = nmea;
char dStr[GPS_MAX_STRING];
struct tm timp;
p = strchr(p, ',') + 1; //read time
str_till_comma(p, dStr);
if(strlen(dStr) > 5){
timp.tm_hour = str2int(dStr,2);
timp.tm_min = str2int(dStr+2,2);
timp.tm_sec = str2int(dStr+4,2);
}
p = strchr(p, ',') + 1; //read field Valid status
str_till_comma(p, dStr);
if(dStr[0] == 'V') { // if field is invalid
loc->quality = 0;
return;
}
loc->quality = 4; // this is declaration that last receive field VALID
p = strchr(p, ',') + 1; // latitude
str_till_comma(p, dStr); // str to float till comma saved modified string
loc->latitude = atoff(dStr);
p = strchr(p, ',') + 1;
switch (p[0]) {
case 'N':
loc->lat = 'N';
break;
case 'S':
loc->lat = 'S';
break;
case ',':
loc->lat = '\0';
break;
}
p = strchr(p, ',') + 1; // longitude
str_till_comma(p, dStr); // str to float till comma saved modified string
loc->longitude = atoff(dStr);
p = strchr(p, ',') + 1;
switch (p[0]) {
case 'W':
loc->lon = 'W';
break;
case 'E':
loc->lon = 'E';
break;
case ',':
loc->lon = '\0';
break;
}
p = strchr(p, ',') + 1;
str_till_comma(p, dStr); // str to float till comma saved modified string
loc->speed = atoff(dStr);
p = strchr(p, ',') + 1;
str_till_comma(p, dStr); // str to float till comma saved modified string
loc->course = atoff(dStr);
p = strchr(p, ',') + 1; //read date
str_till_comma(p, dStr);
if(strlen(dStr) > 5){
timp.tm_mday = str2int(dStr,2);
timp.tm_mon = str2int(dStr+2,2);
timp.tm_year = str2int(dStr+4,2)+100; // we receive -200, but standard wait -1900 = add correction
}
if( timp.tm_year > 0 ) { // check if date field is valid
memcpy(&loc->GPStm, &timp, sizeof(timp));
}
}
/**
* Get the message type (GPGGA, GPRMC, etc..)
*
* This function filters out also wrong packages (invalid checksum)
*
* @param message The NMEA message
* @return The type of message if it is valid
*/
nmea_message_type nmea_get_message_type(const char *message) {
int checksum = nmea_valid_checksum(message);
if (checksum != _EMPTY) {
return checksum;
}
if (strstr(message, NMEA_GPGGA_STR) != NULL) {
return NMEA_GPGGA;
}
if (strstr(message, NMEA_GPRMC_STR) != NULL) {
return NMEA_GPRMC;
}
return NMEA_UNKNOWN;
}
int nmea_valid_checksum(const char *message) {
char p;
int sum = 0;
char *starPtr = strrchr(message, '*');
if (starPtr == NULL)
return NMEA_CHECKSUM_ERR;
char *int_message = starPtr + 1;
long checksum = hex2int(int_message, 2);
++message;
while ((p = *message++) != '*') {
sum ^= p;
}
if (sum != checksum) {
return NMEA_CHECKSUM_ERR;
}
return _EMPTY;
}
// Compute the GPS location using decimal scale
void gps_location(loc_t *coord, char *buffer) {
coord->type = nmea_get_message_type(buffer);
switch (coord->type) {
case NMEA_GPGGA:
nmea_parse_gpgga(buffer, coord);
gps_convert_deg_to_dec(&(coord->latitude), coord->lat, &(coord->longitude), coord->lon);
break;
case NMEA_GPRMC:
nmea_parse_gprmc(buffer, coord);
break;
case NMEA_UNKNOWN:
// unknown message type
break;
}
}

View File

@ -0,0 +1,57 @@
/**
*
* https://github.com/wdalmut/libgps/tree/develop/src
*
*/
#ifndef _NMEA_H_
#define _NMEA_H_
#ifdef __cplusplus
extern "C"
{
#endif /* __cplusplus */
#define GPS_MAX_STRING 256
typedef enum {
NMEA_UNKNOWN = 0x00,
NMEA_GPRMC = 0x01,
NMEA_GPGGA = 0x02
} nmea_message_type;
#define _EMPTY 0x00
#define NMEA_GPRMC_STR "$GPRMC"
#define NMEA_GPGGA_STR "$GPGGA"
#define _COMPLETED 0x03
#define NMEA_CHECKSUM_ERR 0x80
#define NMEA_MESSAGE_ERR 0xC0
struct GPSlocation {
float latitude;
float longitude;
float speed;
float altitude;
float course;
struct tm GPStm;
nmea_message_type type;
int quality;
int satellites;
char lat; // Northing Indicator N=North, S=South
char lon; // Easting Indicator E=East, W=West
};
typedef struct GPSlocation loc_t;
nmea_message_type nmea_get_message_type(const char *);
int nmea_valid_checksum(const char *);
void nmea_parse_gpgga(char *, loc_t *);
void nmea_parse_gprmc(char *, loc_t *);
void gps_location(loc_t *, char *);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,274 @@
/**
* @file rusefi_enums.h
* @brief Fundamental rusEfi enumerable types live here
*
* @note this file should probably not include any other files
*
* @date Jan 14, 2014
* @author Andrey Belomutskiy, (c) 2012-2013
*/
#ifndef RUSEFI_ENUMS_H_
#define RUSEFI_ENUMS_H_
// for now I want all enums to be 32 bit integers. At some point maybe we will make the one-byte
// this is about offsets and sizes in TunerStudio
#define ENUM_SIZE_HACK 2000000000
typedef enum {
AUDI_AAN = 1,
#if EFI_SUPPORT_DODGE_NEON
/**
* 1995 Dodge Neon
* http://rusefi.com/forum/viewtopic.php?t=360
*/
DODGE_NEON_1995 = 2,
#endif /* EFI_SUPPORT_DODGE_NEON */
#if EFI_SUPPORT_FORD_ASPIRE
/**
* 1996 1.3 Ford Aspire
* http://rusefi.com/forum/viewtopic.php?t=375
*/
FORD_ASPIRE_1996 = 3,
#endif /* EFI_SUPPORT_FORD_ASPIRE */
#if EFI_SUPPORT_FORD_FIESTA
/**
* 36-1 toothed wheel engine
* http://rusefi.com/forum/viewtopic.php?t=282
*/
FORD_FIESTA = 4,
#endif /* EFI_SUPPORT_FORD_FIESTA */
#if EFI_SUPPORT_NISSAN_PRIMERA
NISSAN_PRIMERA = 5,
#endif /* EFI_SUPPORT_NISSAN_PRIMERA */
HONDA_ACCORD = 6,
FORD_INLINE_6_1995 = 7,
/**
* one cylinder engine
* 139qmb 50-90cc
* http://rusefi.com/forum/viewtopic.php?f=3&t=332
*/
GY6_139QMB = 8,
MAZDA_MIATA_NB = 9,
ROVER_V8 = 10,
MAZDA_323 = 11,
Internal_ForceMyEnumIntSize_engine_type = ENUM_SIZE_HACK,
} engine_type_e;
typedef enum {
TT_TOOTHED_WHEEL = 0,
TT_FORD_ASPIRE = 1,
TT_DODGE_NEON = 2,
TT_MAZDA_MIATA_NA = 3,
TT_MAZDA_MIATA_NB = 4,
Internal_ForceMyEnumIntSize_trigger_type = ENUM_SIZE_HACK,
} trigger_type_e;
/**
* This enum is used to select your desired Engine Load calculation algorithm
*/
typedef enum {
/**
* raw Mass Air Flow sensor value algorithm. http://en.wikipedia.org/wiki/Mass_flow_sensor
*/
LM_MAF = 0,
/**
* Throttle Position Sensor value is used as engine load. http://en.wikipedia.org/wiki/Throttle_position_sensor
* That's know as Alpha N
*/
LM_TPS = 1,
/**
* raw Manifold Absolute Pressure sensor value is used as engine load http://en.wikipedia.org/wiki/MAP_sensor
*/
LM_MAP = 2,
/**
* Speed Density algorithm - Engile Load is a function of MAP and ... TODO
* http://articles.sae.org/8539/
*/
LM_SPEED_DENSITY = 3,
Internal_ForceMyEnumIntSize_engine_load_mode = ENUM_SIZE_HACK,
} engine_load_mode_e;
typedef enum {
DM_NONE = 0,
DM_HD44780 = 1,
DM_HD44780_OVER_PCF8574 = 2,
Internal_ForceMyEnumIntSize_display_mode = ENUM_SIZE_HACK,
} display_mode_e;
typedef enum {
LF_NATIVE = 0,
/**
* http://www.efianalytics.com/MegaLogViewer/
* log example: http://svn.code.sf.net/p/rusefi/code/trunk/misc/ms_logs/
*/
LM_MLV = 1,
Internal_ForceMyEnumIntSize_log_format = ENUM_SIZE_HACK,
} log_format_e;
typedef enum {
/**
* GND for logical OFF, VCC for logical ON
*/
OM_DEFAULT = 0,
/**
* GND for logical ON, VCC for logical OFF
*/
OM_INVERTED = 1,
OM_OPENDRAIN = 2,
OM_OPENDRAIN_INVERTED = 3,
Internal_ForceMyEnumIntSize_pin_output_mode = ENUM_SIZE_HACK,
} pin_output_mode_e;
typedef enum {
FO_ONE_CYLINDER = 1,
FO_1_THEN_3_THEN_4_THEN2 = 2,
FO_1_THEN_2_THEN_4_THEN3 = 3,
FO_1_THEN_3_THEN_2_THEN4 = 4,
FO_1_THEN_5_THEN_3_THEN_6_THEN_2_THEN_4 = 5,
FO_1_8_4_3_6_5_7_2 = 6,
Internal_ForceMyEnumIntSize_firing_order = ENUM_SIZE_HACK,
} firing_order_e;
/**
* @brief Ignition Mode
*/
typedef enum {
IM_ONE_COIL = 0,
IM_INDIVIDUAL_COILS = 1,
IM_WASTED_SPARK = 2,
Internal_ForceMyEnumIntSize_ignition_mode = ENUM_SIZE_HACK,
} ignition_mode_e;
/**
* @brief Ignition Mode while cranking
*/
typedef enum {
CIM_DEFAULT = 0,
CIM_FIXED_ANGLE = 1,
Internal_ForceMyEnumIntSize_cranking_ignition_mode = ENUM_SIZE_HACK,
} cranking_ignition_mode_e;
typedef enum {
IE_NO_ERROR = 0,
IE_UNEXPECTED_FIRING_ORDER = 1,
Internal_ForceMyEnumIntSize_cranking_internal_error = ENUM_SIZE_HACK,
} internal_error_e;
/**
* Hardware pin
*/
typedef enum {
GPIOA_0 = 0,
GPIOA_1 = 1,
GPIOA_2 = 2,
GPIOA_3 = 3,
GPIOA_4 = 4,
GPIOA_5 = 5,
GPIOA_6 = 6,
GPIOA_7 = 7,
GPIOA_8 = 8,
GPIOA_9 = 9,
GPIOA_10 = 10,
GPIOA_11 = 11,
GPIOA_12 = 12,
GPIOA_13 = 13,
GPIOA_14 = 14,
GPIOA_15 = 15,
GPIOB_0 = 16,
GPIOB_1 = 17,
GPIOB_2 = 18,
GPIOB_3 = 19,
GPIOB_4 = 20,
GPIOB_5 = 21,
GPIOB_6 = 22,
GPIOB_7 = 23,
GPIOB_8 = 24,
GPIOB_9 = 25,
GPIOB_10 = 26,
GPIOB_11 = 27,
GPIOB_12 = 28,
GPIOB_13 = 29,
GPIOB_14 = 30,
GPIOB_15 = 31,
GPIOC_0 = 32,
GPIOC_1 = 33,
GPIOC_2 = 34,
GPIOC_3 = 35,
GPIOC_4 = 36,
GPIOC_5 = 37,
GPIOC_6 = 38,
GPIOC_7 = 39,
GPIOC_8 = 40,
GPIOC_9 = 41,
GPIOC_10 = 42,
GPIOC_11 = 43,
GPIOC_12 = 44,
GPIOC_13 = 45,
GPIOC_14 = 46,
GPIOC_15 = 47,
GPIOD_0 = 48,
GPIOD_1 = 49,
GPIOD_2 = 50,
GPIOD_3 = 51,
GPIOD_4 = 52,
GPIOD_5 = 53,
GPIOD_6 = 54,
GPIOD_7 = 55,
GPIOD_8 = 56,
GPIOD_9 = 57,
GPIOD_10 = 58,
GPIOD_11 = 59,
GPIOD_12 = 60,
GPIOD_13 = 61,
GPIOD_14 = 62,
GPIOD_15 = 63,
GPIOE_0 = 64,
GPIOE_1 = 65,
GPIOE_2 = 66,
GPIOE_3 = 67,
GPIOE_4 = 68,
GPIOE_5 = 69,
GPIOE_6 = 70,
GPIOE_7 = 71,
GPIOE_8 = 72,
GPIOE_9 = 73,
GPIOE_10 = 74,
GPIOE_11 = 75,
GPIOE_12 = 76,
GPIOE_13 = 77,
GPIOE_14 = 78,
GPIOE_15 = 79,
Internal_ForceMyEnumIntSize_cranking_brain_pin = ENUM_SIZE_HACK,
} brain_pin_e;
typedef enum {
MT_CUSTOM = 0,
MT_DENSO183 = 1,
MT_MPX4250 = 2,
Internal_ForceMyEnumIntSize_cranking_map_type = ENUM_SIZE_HACK,
} map_type_e;
#endif /* RUSEFI_ENUMS_H_ */

View File

@ -0,0 +1,148 @@
/**
* @file signal_executor.c
*
* todo: we should split this file into two:
* one for pure scheduling and another one for signal output which would
* use the scheduling
*
* @date Dec 4, 2013
* @author Andrey Belomutskiy, (c) 2012-2014
*
* This file is part of rusEfi - see http://rusefi.com
*
* rusEfi is free software; you can redistribute it and/or modify it under the terms of
* the GNU General Public License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* rusEfi is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
* even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program.
* If not, see <http://www.gnu.org/licenses/>.
*/
#include "main.h"
#include "signal_executor.h"
#if EFI_WAVE_CHART
#include "rpm_calculator.h"
#endif
#if EFI_WAVE_ANALYZER
/**
* Signal executors feed digital events right into WaveChart used by Sniffer tab of Dev Console
*/
#include "wave_analyzer.h"
#endif /* EFI_WAVE_ANALYZER */
#define OUTPUT_SIGNAL_COUNT 40
static OutputSignal signals[OUTPUT_SIGNAL_COUNT];
int outputSignalCount;
void resetOutputSignals(void) {
outputSignalCount = 0;
}
OutputSignal * addOutputSignal(io_pin_e ioPin) {
chDbgCheck(outputSignalCount < OUTPUT_SIGNAL_COUNT, "too many output signals");
OutputSignal *signal = &signals[outputSignalCount++];
initOutputSignal(signal, ioPin);
return signal;
}
void initOutputSignalBase(OutputSignal *signal) {
signal->status = IDLE;
signal->last_scheduling_time = 0;
signal->initialized = TRUE;
}
static void turnHigh(OutputSignal *signal) {
#if EFI_DEFAILED_LOGGING
signal->hi_time = chTimeNow();
#endif /* EFI_DEFAILED_LOGGING */
// turn the output level ACTIVE
// todo: this XOR should go inside the setOutputPinValue method
setOutputPinValue(signal->io_pin, TRUE);
// sleep for the needed duration
#if EFI_WAVE_CHART
addWaveChartEvent(signal->name, "up", "");
#endif /* EFI_WAVE_ANALYZER */
}
static void turnLow(OutputSignal *signal) {
// turn off the output
// todo: this XOR should go inside the setOutputPinValue method
setOutputPinValue(signal->io_pin, FALSE);
#if EFI_DEFAILED_LOGGING
systime_t after = chTimeNow();
debugInt(&signal->logging, "a_time", after - signal->hi_time);
scheduleLogging(&signal->logging);
#endif /* EFI_DEFAILED_LOGGING */
#if EFI_WAVE_CHART
addWaveChartEvent(signal->name, "down", "");
#endif /* EFI_WAVE_ANALYZER */
}
/**
*
* @param delay the number of ticks before the output signal
* immediate output if delay is zero
* @param dwell the number of ticks of output duration
*
*/
void scheduleOutput(OutputSignal *signal, int delay, int dwell, time_t now) {
chDbgCheck(dwell >= 0, "dwell cannot be negative");
scheduleOutputBase(signal, delay, dwell);
scheduleTask(&signal->signalTimerUp, delay, (schfunc_t) &turnHigh, (void *) signal);
scheduleTask(&signal->signalTimerDown, delay + dwell, (schfunc_t) &turnLow, (void*)signal);
signal->last_scheduling_time = now;
}
void scheduleOutputBase(OutputSignal *signal, int offset, int duration) {
/**
* it's better to check for the exact 'TRUE' value since otherwise
* we would accept any memory garbage
*/
chDbgCheck(signal->initialized == TRUE, "Signal not initialized");
// signal->offset = offset;
// signal->duration = duration;
}
char *getPinName(io_pin_e io_pin) {
switch (io_pin) {
case SPARKOUT_1_OUTPUT:
return "Spark 1";
case SPARKOUT_2_OUTPUT:
return "Spark 2";
case SPARKOUT_3_OUTPUT:
return "Spark 3";
case SPARKOUT_4_OUTPUT:
return "Spark 4";
case INJECTOR_1_OUTPUT:
return "Injector 1";
case INJECTOR_2_OUTPUT:
return "Injector 2";
case INJECTOR_3_OUTPUT:
return "Injector 3";
case INJECTOR_4_OUTPUT:
return "Injector 4";
case INJECTOR_5_OUTPUT:
return "Injector 5";
default:
return "No name";
}
}

View File

@ -0,0 +1,101 @@
/**
* @file signal_executor.h
* @brief Asynchronous output signal header
*
* @date Feb 10, 2013
* @author Andrey Belomutskiy, (c) 2012-2013
*/
#ifndef SPARKOUT_H_
#define SPARKOUT_H_
#include "rusefi_enums.h"
#include "global.h"
#include "efifeatures.h"
#include "io_pins.h"
#if EFI_PROD_CODE
#include "datalogging.h"
#endif /* EFI_PROD_CODE */
#if EFI_SIGNAL_EXECUTOR_SLEEP
#include "signal_executor_sleep.h"
#endif /* EFI_SIGNAL_EXECUTOR_SLEEP */
#if EFI_SIGNAL_EXECUTOR_SINGLE_TIMER
#include "signal_executor_single_timer.h"
#endif /* EFI_SIGNAL_EXECUTOR_SINGLE_TIMER */
typedef void (*schfunc_t)(void *);
typedef struct scheduling_struct scheduling_s;
struct scheduling_struct {
//int initialized;
#if EFI_SIGNAL_EXECUTOR_SLEEP
VirtualTimer timer;
#endif /* EFI_SIGNAL_EXECUTOR_SLEEP */
#if EFI_SIGNAL_EXECUTOR_SINGLE_TIMER
volatile time_t moment;
#endif /* EFI_SIGNAL_EXECUTOR_SINGLE_TIMER */
};
typedef enum {
IDLE = 0, ACTIVE
} executor_status_t;
/**
* @brief Asynchronous output signal data structure
*/
typedef struct OutputSignal_struct OutputSignal;
struct OutputSignal_struct {
/**
* name of this signal
*/
char *name;
io_pin_e io_pin;
#if 0 // depricated
// time in system ticks
volatile int offset;
// time in system ticks
volatile int duration;
#endif
int initialized;
time_t last_scheduling_time;
time_t hi_time;
/**
* this timer is used to wait for the time to activate the thread
*/
scheduling_s signalTimerUp;
scheduling_s signalTimerDown;
executor_status_t status;
#if EFI_SIGNAL_EXECUTOR_HW_TIMER
// todo
#endif
OutputSignal *next;
};
#ifdef __cplusplus
extern "C"
{
#endif /* __cplusplus */
void resetOutputSignals(void);
OutputSignal * addOutputSignal(io_pin_e ioPin);
void initOutputSignal(OutputSignal *signal, io_pin_e ioPin);
void scheduleOutput(OutputSignal *signal, int delay, int dwell, time_t now);
void initOutputSignalBase(OutputSignal *signal);
void scheduleOutputBase(OutputSignal *signal, int offset, int duration);
void scheduleTask(scheduling_s *scheduling, int delay, schfunc_t callback, void *param);
void scheduleByAngle(scheduling_s *timer, float angle, schfunc_t callback, void *param);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* SPARKOUT_H_ */

View File

@ -0,0 +1,74 @@
/**
* @file signal_executor_single_timer_algo.c
*
* @date Nov 28, 2013
* @author Andrey Belomutskiy, (c) 2012-2014
*
*
* This file is part of rusEfi - see http://rusefi.com
*
* rusEfi is free software; you can redistribute it and/or modify it under the terms of
* the GNU General Public License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* rusEfi is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
* even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program.
* If not, see <http://www.gnu.org/licenses/>.
*/
#include "signal_executor.h"
#include "signal_executor_single_timer_algo.h"
#include "main.h"
#include "utlist.h"
#include "io_pins.h"
#if EFI_WAVE_ANALYZER
#include "wave_analyzer.h"
#include "wave_chart.h"
extern WaveChart waveChart;
#endif
#if EFI_SIGNAL_EXECUTOR_SINGLE_TIMER
/**
* @brief Output list
*
* List of all active output signals
* This is actually the head of the list.
* When the list is empty (initial state) the head of the list should be NULL.
* This is by design.
*/
OutputSignal *st_output_list = NULL;
inline void registerSignal(OutputSignal *signal) {
LL_APPEND(st_output_list, signal);
}
void setOutputPinValue(io_pin_e pin, int value);
/**
* @return time of next event within for this signal
* @todo Find better name.
*/
inline time_t toggleSignalIfNeeded(OutputSignal *out, time_t now) {
// chDbgCheck(out!=NULL, "out is NULL");
// chDbgCheck(out->io_pin < IO_PIN_COUNT, "pin assertion");
time_t last = out->last_scheduling_time;
//estimated = last + out->timing[out->status];
time_t estimated = last + GET_DURATION(out);
if (now >= estimated) {
out->status ^= 1; /* toggle status */
//setOutputPinValue(out->io_pin, out->status); /* Toggle output */
palWritePad(GPIOE, 5, out->status);
#if EFI_WAVE_ANALYZER
// addWaveChartEvent(out->name, out->status ? "up" : "down", "");
#endif /* EFI_WAVE_ANALYZER */
out->last_scheduling_time = now; /* store last update */
estimated = now + GET_DURATION(out); /* update estimation */
}
return estimated - now;
}
#endif /* EFI_SIGNAL_EXECUTOR_SINGLE_TIMER */

View File

@ -0,0 +1,18 @@
/**
* @file signal_executor_single_timer_algo.h
*
* @date Nov 28, 2013
* @author Andrey Belomutskiy, (c) 2012-2013
*/
#ifndef SIGNAL_EXECUTOR_SINGLE_TIMER_ALGO_H_
#define SIGNAL_EXECUTOR_SINGLE_TIMER_ALGO_H_
#include "signal_executor.h"
#define GET_DURATION(o) ((o)->status ? (o)->signalTimerDown.moment : (o)->signalTimerUp.moment)
inline void registerSignal(OutputSignal *signal);
inline time_t toggleSignalIfNeeded(OutputSignal *out, time_t now);
#endif /* SIGNAL_EXECUTOR_SINGLE_TIMER_ALGO_H_ */

View File

@ -0,0 +1,203 @@
/**
* @file trigger_decoder.c
*
* @date Dec 24, 2013
* @author Andrey Belomutskiy, (c) 2012-2014
*
* This file is part of rusEfi - see http://rusefi.com
*
* rusEfi is free software; you can redistribute it and/or modify it under the terms of
* the GNU General Public License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* rusEfi is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
* even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program.
* If not, see <http://www.gnu.org/licenses/>.
*/
#include "main.h"
#include "trigger_decoder.h"
#include "cyclic_buffer.h"
extern "C"
{
#include "trigger_mazda.h"
}
#if EFI_PROD_CODE || EFI_SIMULATOR
static Logging logger;
#endif
static cyclic_buffer errorDetection;
/**
* @return TRUE is something is wrong with trigger decoding
*/
int isTriggerDecoderError(void) {
return errorDetection.sum(6) > 4;
}
static inline int isSynchronizationGap(trigger_state_s *shaftPositionState, trigger_shape_s *triggerShape,
trigger_config_s *triggerConfig, int currentDuration) {
if (!triggerConfig->isSynchronizationNeeded)
return FALSE;
return currentDuration > shaftPositionState->toothed_previous_duration * triggerConfig->syncRatioFrom
&& currentDuration < shaftPositionState->toothed_previous_duration * triggerConfig->syncRatioTo;
}
static inline int noSynchronizationResetNeeded(trigger_state_s *shaftPositionState, trigger_shape_s *triggerShape,
trigger_config_s *triggerConfig) {
if (triggerConfig->isSynchronizationNeeded)
return FALSE;
if (!shaftPositionState->shaft_is_synchronized)
return TRUE;
/**
* in case of noise the counter could be above the expected number of events
*/
return shaftPositionState->current_index >= triggerShape->shaftPositionEventCount - 1;
}
/**
* @brief This method changes the state of trigger_state_s data structure according to the trigger event
*/
void processTriggerEvent(trigger_state_s *shaftPositionState, trigger_shape_s *triggerShape,
trigger_config_s *triggerConfig, ShaftEvents signal, time_t now) {
int isLessImportant = (triggerConfig->useRiseEdge && signal != SHAFT_PRIMARY_UP)
|| (!triggerConfig->useRiseEdge && signal != SHAFT_PRIMARY_DOWN);
if (isLessImportant) {
/**
* For less important events we simply increment the index.
*/
shaftPositionState->current_index++;
return;
}
int currentDuration = now - shaftPositionState->toothed_previous_time;
// todo: skip a number of signal from the beginning
#if EFI_PROD_CODE
// scheduleMsg(&logger, "from %f to %f %d %d", triggerConfig->syncRatioFrom, triggerConfig->syncRatioTo, currentDuration, shaftPositionState->toothed_previous_duration);
// scheduleMsg(&logger, "ratio %f", 1.0 * currentDuration/ shaftPositionState->toothed_previous_duration);
#else
if (shaftPositionState->toothed_previous_duration != 0) {
// printf("ratio %f: cur=%d pref=%d\r\n", 1.0 * currentDuration / shaftPositionState->toothed_previous_duration,
// currentDuration, shaftPositionState->toothed_previous_duration);
}
#endif
if (noSynchronizationResetNeeded(shaftPositionState, triggerShape, triggerConfig)
|| isSynchronizationGap(shaftPositionState, triggerShape, triggerConfig, currentDuration)) {
/**
* We can check if things are fine by comparing the number of events in a cycle with the expected number of event.
*/
int isDecodingError = shaftPositionState->current_index != triggerShape->shaftPositionEventCount - 1;
errorDetection.add(isDecodingError);
shaftPositionState->shaft_is_synchronized = TRUE;
shaftPositionState->current_index = 0;
} else {
shaftPositionState->current_index++;
}
shaftPositionState->toothed_previous_duration = currentDuration;
shaftPositionState->toothed_previous_time = now;
}
static void initializeSkippedToothTriggerShape(trigger_shape_s *s, int totalTeethCount, int skippedCount) {
triggerShapeInit(s);
float toothWidth = 0.5;
for (int i = 0; i < totalTeethCount - skippedCount - 1; i++) {
float angleDown = 720.0 / totalTeethCount * (i + toothWidth);
float angleUp = 720.0 / totalTeethCount * (i + 1);
triggerAddEvent(s, angleDown, T_PRIMARY, TV_HIGH);
triggerAddEvent(s, angleUp, T_PRIMARY, TV_LOW);
}
float angleDown = 720.0 / totalTeethCount * (totalTeethCount - skippedCount - 1 + toothWidth);
triggerAddEvent(s, angleDown, T_PRIMARY, TV_HIGH);
triggerAddEvent(s, 720, T_PRIMARY, TV_LOW);
}
void initializeSkippedToothTriggerShapeExt(engine_configuration2_s *engineConfiguration2, int totalTeethCount,
int skippedCount) {
trigger_shape_s *s = &engineConfiguration2->triggerShape;
initializeSkippedToothTriggerShape(s, totalTeethCount, skippedCount);
engineConfiguration2->triggerShape.shaftPositionEventCount = ((totalTeethCount - skippedCount) * 2);
checkSwitchTimes(s->size, s->wave.switchTimes);
}
static void configureNeonTriggerShape(trigger_shape_s *s) {
triggerShapeInit(s);
triggerAddEvent(s, 60, T_PRIMARY, TV_HIGH);
triggerAddEvent(s, 210, T_PRIMARY, TV_LOW);
triggerAddEvent(s, 420, T_PRIMARY, TV_HIGH);
triggerAddEvent(s, 630, T_PRIMARY, TV_LOW);
// voodoo magic - we always need 720 at the end
triggerAddEvent(s, 720, T_PRIMARY, TV_LOW);
s->shaftPositionEventCount = 4;
}
static void confgiureFordAspireTriggerShape(trigger_shape_s * s) {
triggerShapeInit(s);
s->shaftPositionEventCount = 10;
triggerAddEvent(s, 53.747, T_SECONDARY, TV_HIGH);
triggerAddEvent(s, 121.90, T_SECONDARY, TV_LOW);
triggerAddEvent(s, 232.76, T_SECONDARY, TV_HIGH);
triggerAddEvent(s, 300.54, T_SECONDARY, TV_LOW);
triggerAddEvent(s, 360, T_PRIMARY, TV_HIGH);
triggerAddEvent(s, 409.8412, T_SECONDARY, TV_HIGH);
triggerAddEvent(s, 478.6505, T_SECONDARY, TV_LOW);
triggerAddEvent(s, 588.045, T_SECONDARY, TV_HIGH);
triggerAddEvent(s, 657.03, T_SECONDARY, TV_LOW);
triggerAddEvent(s, 720, T_PRIMARY, TV_LOW);
}
void initializeTriggerShape(engine_configuration_s *engineConfiguration, engine_configuration2_s *engineConfiguration2) {
trigger_config_s *tt = &engineConfiguration->triggerConfig;
switch (tt->triggerType) {
case TT_TOOTHED_WHEEL:
initializeSkippedToothTriggerShapeExt(engineConfiguration2, tt->totalToothCount, tt->skippedToothCount);
return;
case TT_MAZDA_MIATA_NB:
initializeMazdaMiataNbShape(&engineConfiguration2->triggerShape);
return;
case TT_DODGE_NEON:
configureNeonTriggerShape(&engineConfiguration2->triggerShape);
return;
case TT_FORD_ASPIRE:
confgiureFordAspireTriggerShape(&engineConfiguration2->triggerShape);
return;
default:
fatal("not implemented")
;
}
}
void initTriggerDecoder(void) {
#if EFI_PROD_CODE || EFI_SIMULATOR
initLogging(&logger, "trigger decoder");
#endif
}

View File

@ -0,0 +1,35 @@
/**
* @file trigger_decoder.h
*
* @date Dec 24, 2013
* @author Andrey Belomutskiy, (c) 2012-2013
*/
#ifndef TRIGGER_DECODER_H_
#define TRIGGER_DECODER_H_
#include <time.h>
#ifdef __cplusplus
extern "C"
{
#include "trigger_structure.h"
#include "engine_configuration.h"
#else
#include "trigger_structure.h"
#include "engine_configuration.h"
#endif
int isTriggerDecoderError(void);
void processTriggerEvent(trigger_state_s *shaftPositionState, trigger_shape_s *triggerShape, trigger_config_s *triggerConfig, ShaftEvents signal, time_t now);
void initializeSkippedToothTriggerShapeExt(engine_configuration2_s *engineConfiguration2, int totalTeethCount, int skippedCount);
void initializeTriggerShape(engine_configuration_s *engineConfiguration, engine_configuration2_s *engineConfiguration2);
void initTriggerDecoder(void);
#ifdef __cplusplus
}
#endif
#endif /* TRIGGER_DECODER_H_ */

View File

@ -0,0 +1,58 @@
/**
* @file trigger_mazda.c
*
* @date Feb 18, 2014
* @author Andrey Belomutskiy, (c) 2012-2014
*
* This file is part of rusEfi - see http://rusefi.com
*
* rusEfi is free software; you can redistribute it and/or modify it under the terms of
* the GNU General Public License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* rusEfi is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
* even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program.
* If not, see <http://www.gnu.org/licenses/>.
*/
#include "trigger_mazda.h"
void initializeMazdaMiataNbShape(trigger_shape_s *s) {
triggerShapeInit(s);
/**
* cam sensor is primary, crank sensor is secondary
*/
triggerAddEvent(s, 20, T_PRIMARY, TV_LOW);
triggerAddEvent(s, 66, T_SECONDARY, TV_HIGH);
triggerAddEvent(s, 70, T_SECONDARY, TV_LOW);
triggerAddEvent(s, 136, T_SECONDARY, TV_HIGH);
triggerAddEvent(s, 140, T_SECONDARY, TV_LOW);
triggerAddEvent(s, 246, T_SECONDARY, TV_HIGH);
triggerAddEvent(s, 250, T_SECONDARY, TV_LOW);
triggerAddEvent(s, 316, T_SECONDARY, TV_HIGH);
triggerAddEvent(s, 320, T_SECONDARY, TV_LOW);
triggerAddEvent(s, 340, T_PRIMARY, TV_HIGH);
triggerAddEvent(s, 360, T_PRIMARY, TV_LOW);
triggerAddEvent(s, 380, T_PRIMARY, TV_HIGH);
triggerAddEvent(s, 400, T_PRIMARY, TV_LOW);
triggerAddEvent(s, 426, T_SECONDARY, TV_HIGH);
triggerAddEvent(s, 430, T_SECONDARY, TV_LOW);
triggerAddEvent(s, 496, T_SECONDARY, TV_HIGH);
triggerAddEvent(s, 500, T_SECONDARY, TV_LOW);
triggerAddEvent(s, 606, T_SECONDARY, TV_HIGH);
triggerAddEvent(s, 610, T_SECONDARY, TV_LOW);
triggerAddEvent(s, 676, T_SECONDARY, TV_HIGH);
triggerAddEvent(s, 680, T_SECONDARY, TV_LOW);
triggerAddEvent(s, 720, T_PRIMARY, TV_HIGH);
s->shaftPositionEventCount = 6 + 16;
}

View File

@ -0,0 +1,24 @@
/**
* @file trigger_mazda.h
*
* @date Feb 18, 2014
* @author Andrey Belomutskiy, (c) 2012-2013
*/
#ifndef TRIGGER_MAZDA_H_
#define TRIGGER_MAZDA_H_
#ifdef __cplusplus
extern "C"
{
#endif /* __cplusplus */
#include "trigger_structure.h"
void initializeMazdaMiataNbShape(trigger_shape_s *s);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* TRIGGER_MAZDA_H_ */

View File

@ -0,0 +1,60 @@
/**
* @file trigger_structure.c
*
* @date Jan 20, 2014
* @author Andrey Belomutskiy, (c) 2012-2014
*
* This file is part of rusEfi - see http://rusefi.com
*
* rusEfi is free software; you can redistribute it and/or modify it under the terms of
* the GNU General Public License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* rusEfi is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
* even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program.
* If not, see <http://www.gnu.org/licenses/>.
*/
#include "main.h"
#include "trigger_structure.h"
void clearTriggerState(trigger_state_s *state) {
state->shaft_is_synchronized = FALSE;
state->toothed_previous_time = 0;
state->toothed_previous_duration = 0;
state->current_index = 0;
}
void triggerShapeInit(trigger_shape_s *trigger) {
memset(trigger, 0, sizeof(trigger_shape_s));
}
void triggerAddEvent(trigger_shape_s *trigger, float angle, trigger_wheel_e waveIndex, trigger_value_e state) {
angle /= 720;
if (trigger->size == 0) {
trigger->size = 1;
for (int i = 0; i < PWM_PHASE_MAX_WAVE_PER_PWM; i++)
trigger->wave.waves[i].pinStates[0] = 0;
trigger->wave.switchTimes[0] = angle;
trigger->wave.waves[waveIndex].pinStates[0] = state;
return;
}
// if(angle!=trigger->wave.switchTimes[trigger->currentIndex])
int index = trigger->size++;
for (int i = 0; i < PWM_PHASE_MAX_WAVE_PER_PWM; i++)
trigger->wave.waves[i].pinStates[index] = trigger->wave.waves[i].pinStates[index - 1];
trigger->wave.switchTimes[index] = angle;
trigger->wave.waves[waveIndex].pinStates[index] = state;
}
void checkSwitchTimes(int size, float *switchTimes) {
for (int i = 0; i < size - 1; i++)
chDbgCheck(switchTimes[i] < switchTimes[i + 1], "invalid switchTimes");
}

View File

@ -0,0 +1,106 @@
/**
* @file trigger_structure.h
*
* @date Dec 22, 2013
* @author Andrey Belomutskiy, (c) 2012-2013
*/
#ifndef TRIGGER_STRUCTURE_H_
#define TRIGGER_STRUCTURE_H_
#include "rusefi_enums.h"
#define PWM_PHASE_MAX_COUNT 150
#define PWM_PHASE_MAX_WAVE_PER_PWM 2
typedef enum {
SHAFT_PRIMARY_UP = 0,
SHAFT_PRIMARY_DOWN = 1,
SHAFT_SECONDARY_UP = 2,
SHAFT_SECONDARY_DOWN = 3,
} ShaftEvents;
typedef struct {
/**
* TRUE if we know where we are
*/
unsigned char shaft_is_synchronized;
int current_index;
int toothed_previous_duration;
int toothed_previous_time;
} trigger_state_s;
/**
* @brief PWM configuration for the specific output pin
*/
typedef struct {
int pinStates[PWM_PHASE_MAX_COUNT];
} single_wave_s;
typedef struct {
/**
* Number of events in the cycle
*/
int phaseCount;
/**
* Number of signal wires
*/
int waveCount;
single_wave_s waves[PWM_PHASE_MAX_WAVE_PER_PWM];
/**
* values in the (0..1] range which refer to points within the period at at which pin state should be changed
* So, in the simplest case we turn pin off at 0.3 and turn it on at 1 - that would give us a 70% duty cycle PWM
*/
float switchTimes[PWM_PHASE_MAX_COUNT];
} multi_wave_s;
typedef enum {
TV_LOW = 0,
TV_HIGH = 1
} trigger_value_e;
typedef enum {
T_PRIMARY = 0,
T_SECONDARY = 1
} trigger_wheel_e;
/**
* @brief Trigger wheel(s) configuration
*/
typedef struct {
trigger_type_e triggerType;
int isSynchronizationNeeded;
int totalToothCount;
int skippedToothCount;
float syncRatioFrom;
float syncRatioTo;
int useRiseEdge;
} trigger_config_s;
typedef struct {
multi_wave_s wave;
int size;
/**
* Total count of shaft events per CAM or CRANK shaft revolution.
* TODO this should be migrated to CRANKshaft revolution, this would go together
* TODO with eliminating RPM_MULT magic constant
*/
int shaftPositionEventCount;
} trigger_shape_s;
void clearTriggerState(trigger_state_s *state);
void triggerShapeInit(trigger_shape_s *trigger);
void triggerAddEvent(trigger_shape_s *trigger, float angle, trigger_wheel_e waveIndex, trigger_value_e state);
void checkSwitchTimes(int size, float *switchTimes);
#endif /* TRIGGER_STRUCTURE_H_ */

Some files were not shown because too many files have changed in this diff Show More