manual sync with SF
This commit is contained in:
parent
102ee997cb
commit
0d87be6add
|
@ -50,6 +50,7 @@
|
||||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/controllers/math}""/>
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/controllers/math}""/>
|
||||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/console_util}""/>
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/console_util}""/>
|
||||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/emulation}""/>
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/emulation}""/>
|
||||||
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/emulation/test}""/>
|
||||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/emulation/hw_layer}""/>
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/emulation/hw_layer}""/>
|
||||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/hw_layer}""/>
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/hw_layer}""/>
|
||||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/hw_layer/flash}""/>
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/hw_layer/flash}""/>
|
||||||
|
@ -59,7 +60,10 @@
|
||||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/russianefi/adc}""/>
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/russianefi/adc}""/>
|
||||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/config/system}""/>
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/config/system}""/>
|
||||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/splib}""/>
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/splib}""/>
|
||||||
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/chibios/os/kernel/include}""/>
|
||||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/chibios/boards/ST_STM32F4_DISCOVERY}""/>
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/chibios/boards/ST_STM32F4_DISCOVERY}""/>
|
||||||
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/chibios/os/hal/src}""/>
|
||||||
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/chibios/os/hal/include}""/>
|
||||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/chibios/os/hal/platforms/STM32/TIMv1}""/>
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/chibios/os/hal/platforms/STM32/TIMv1}""/>
|
||||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/chibios/os/hal/platforms/STM32/I2Cv1}""/>
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/chibios/os/hal/platforms/STM32/I2Cv1}""/>
|
||||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/chibios/os/hal/platforms/STM32}""/>
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/chibios/os/hal/platforms/STM32}""/>
|
||||||
|
@ -67,14 +71,11 @@
|
||||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/chibios/os/hal/platforms/STM32/OTGv1}""/>
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/chibios/os/hal/platforms/STM32/OTGv1}""/>
|
||||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/chibios/os/hal/platforms/STM32/GPIOv2}""/>
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/chibios/os/hal/platforms/STM32/GPIOv2}""/>
|
||||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/chibios/os/hal/platforms/STM32F4xx}""/>
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/chibios/os/hal/platforms/STM32F4xx}""/>
|
||||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/chibios/os/hal/src}""/>
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/chibios/os/hal/platforms/STM32/SPIv1}""/>
|
||||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/chibios/os/hal/include}""/>
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/chibios/os/hal/platforms/STM32/USARTv1}""/>
|
||||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/chibios/os/kernel/include}""/>
|
|
||||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/chibios/os/ports/GCC/ARMCMx}""/>
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/chibios/os/ports/GCC/ARMCMx}""/>
|
||||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/chibios/os/ports/GCC/ARMCMx/STM32F4xx}""/>
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/chibios/os/ports/GCC/ARMCMx/STM32F4xx}""/>
|
||||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/chibios/os/ports/common/ARMCMx}""/>
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/chibios/os/ports/common/ARMCMx}""/>
|
||||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/chibios/os/hal/platforms/STM32/SPIv1}""/>
|
|
||||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/chibios/os/hal/platforms/STM32/USARTv1}""/>
|
|
||||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/chibios/os/ports/common/ARMCMx/CMSIS/include}""/>
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/chibios/os/ports/common/ARMCMx/CMSIS/include}""/>
|
||||||
</option>
|
</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.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"/>
|
||||||
|
@ -110,6 +111,7 @@
|
||||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/controllers/math}""/>
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/controllers/math}""/>
|
||||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/console_util}""/>
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/console_util}""/>
|
||||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/emulation}""/>
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/emulation}""/>
|
||||||
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/emulation/test}""/>
|
||||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/emulation/hw_layer}""/>
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/emulation/hw_layer}""/>
|
||||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/hw_layer}""/>
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/hw_layer}""/>
|
||||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/hw_layer/flash}""/>
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/hw_layer/flash}""/>
|
||||||
|
@ -119,7 +121,10 @@
|
||||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/russianefi/adc}""/>
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/russianefi/adc}""/>
|
||||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/config/system}""/>
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/config/system}""/>
|
||||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/splib}""/>
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/splib}""/>
|
||||||
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/chibios/os/kernel/include}""/>
|
||||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/chibios/boards/ST_STM32F4_DISCOVERY}""/>
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/chibios/boards/ST_STM32F4_DISCOVERY}""/>
|
||||||
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/chibios/os/hal/src}""/>
|
||||||
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/chibios/os/hal/include}""/>
|
||||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/chibios/os/hal/platforms/STM32/TIMv1}""/>
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/chibios/os/hal/platforms/STM32/TIMv1}""/>
|
||||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/chibios/os/hal/platforms/STM32/I2Cv1}""/>
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/chibios/os/hal/platforms/STM32/I2Cv1}""/>
|
||||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/chibios/os/hal/platforms/STM32}""/>
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/chibios/os/hal/platforms/STM32}""/>
|
||||||
|
@ -127,17 +132,14 @@
|
||||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/chibios/os/hal/platforms/STM32/OTGv1}""/>
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/chibios/os/hal/platforms/STM32/OTGv1}""/>
|
||||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/chibios/os/hal/platforms/STM32/GPIOv2}""/>
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/chibios/os/hal/platforms/STM32/GPIOv2}""/>
|
||||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/chibios/os/hal/platforms/STM32F4xx}""/>
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/chibios/os/hal/platforms/STM32F4xx}""/>
|
||||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/chibios/os/hal/src}""/>
|
|
||||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/chibios/os/hal/include}""/>
|
|
||||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/chibios/os/kernel/include}""/>
|
|
||||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/chibios/os/ports/GCC/ARMCMx}""/>
|
|
||||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/chibios/os/ports/GCC/ARMCMx/STM32F4xx}""/>
|
|
||||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/chibios/os/ports/common/ARMCMx}""/>
|
|
||||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/chibios/os/hal/platforms/STM32/SPIv1}""/>
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/chibios/os/hal/platforms/STM32/SPIv1}""/>
|
||||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/chibios/os/hal/platforms/STM32/USARTv1}""/>
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/chibios/os/hal/platforms/STM32/USARTv1}""/>
|
||||||
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/chibios/os/ports/GCC/ARMCMx/STM32F4xx}""/>
|
||||||
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/chibios/os/ports/GCC/ARMCMx}""/>
|
||||||
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/chibios/os/ports/common/ARMCMx}""/>
|
||||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/chibios/os/ports/common/ARMCMx/CMSIS/include}""/>
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/chibios/os/ports/common/ARMCMx/CMSIS/include}""/>
|
||||||
</option>
|
</option>
|
||||||
<option id="org.eclipse.cdt.cross.arm.gnu.cpp.compiler.option.other.otherflags.1439013659" superClass="org.eclipse.cdt.cross.arm.gnu.cpp.compiler.option.other.otherflags" value="-c -fmessage-length=0 -std=c++11" valueType="string"/>
|
<option id="org.eclipse.cdt.cross.arm.gnu.cpp.compiler.option.other.otherflags.1439013659" name="Other flags" superClass="org.eclipse.cdt.cross.arm.gnu.cpp.compiler.option.other.otherflags" value="-c -fmessage-length=0 -std=c++11 -Werror=write-strings" valueType="string"/>
|
||||||
<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"/>
|
<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>
|
||||||
<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.c.linker.debug.369587711" name="ARM Sourcery Windows GCC C Linker" superClass="org.eclipse.cdt.cross.arm.gnu.sourcery.windows.elf.c.linker.debug"/>
|
||||||
|
@ -188,13 +190,14 @@
|
||||||
<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"/>
|
<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>
|
||||||
<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">
|
<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.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.optimize" 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">
|
<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=""${workspace_loc:/${ProjName}}""/>
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}}""/>
|
||||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/controllers/system}""/>
|
|
||||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/console/algo}""/>
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/console/algo}""/>
|
||||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/hw_layer/algo}""/>
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/hw_layer/algo}""/>
|
||||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/controllers/algo}""/>
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/controllers/algo}""/>
|
||||||
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/ext}""/>
|
||||||
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/ext_algo}""/>
|
||||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/util}""/>
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/util}""/>
|
||||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/config}""/>
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/config}""/>
|
||||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/config/engines}""/>
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/config/engines}""/>
|
||||||
|
@ -205,24 +208,25 @@
|
||||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/controllers}""/>
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/controllers}""/>
|
||||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/controllers/math}""/>
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/controllers/math}""/>
|
||||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/controllers/sensors}""/>
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/controllers/sensors}""/>
|
||||||
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/controllers/core}""/>
|
||||||
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/controllers/system}""/>
|
||||||
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/controllers/trigger}""/>
|
||||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/emulation}""/>
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/emulation}""/>
|
||||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/emulation/hw_layer}""/>
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/emulation/hw_layer}""/>
|
||||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/hw_layer}""/>
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/hw_layer}""/>
|
||||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/linked/controllers}""/>
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/hw_layer/algo}""/>
|
||||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/linked/controllers/math}""/>
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/hw_layer/lcd}""/>
|
||||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/russianefi}""/>
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/hw_layer/serial_over_usb}""/>
|
||||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/russianefi/algo}""/>
|
|
||||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/russianefi/ckp}""/>
|
|
||||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/russianefi/adc}""/>
|
|
||||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/splib}""/>
|
|
||||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/chibios/boards/ST_STM32F4_DISCOVERY}""/>
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/chibios/boards/ST_STM32F4_DISCOVERY}""/>
|
||||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/chibios/os/hal/platforms/STM32}""/>
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/chibios/os/kernel/include}""/>
|
||||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/chibios/os/various}""/>
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/chibios/os/various}""/>
|
||||||
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/chibios/os/hal/platforms/STM32}""/>
|
||||||
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/chibios/os/hal/platforms/STM32/RTCv2}""/>
|
||||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/chibios/os/hal/platforms/STM32/OTGv1}""/>
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/chibios/os/hal/platforms/STM32/OTGv1}""/>
|
||||||
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/chibios/os/hal/platforms/STM32/I2Cv1}""/>
|
||||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/chibios/os/hal/platforms/STM32/GPIOv2}""/>
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/chibios/os/hal/platforms/STM32/GPIOv2}""/>
|
||||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/chibios/os/hal/platforms/STM32F4xx}""/>
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/chibios/os/hal/platforms/STM32F4xx}""/>
|
||||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/chibios/os/hal/src}""/>
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/chibios/os/hal/src}""/>
|
||||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/chibios/os/kernel/include}""/>
|
|
||||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/chibios/os/hal/include}""/>
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/chibios/os/hal/include}""/>
|
||||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/chibios/os/hal/platforms/STM32/SPIv1}""/>
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/chibios/os/hal/platforms/STM32/SPIv1}""/>
|
||||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/chibios/os/hal/platforms/STM32/TIMv1}""/>
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/chibios/os/hal/platforms/STM32/TIMv1}""/>
|
||||||
|
@ -242,8 +246,59 @@
|
||||||
<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"/>
|
<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>
|
||||||
<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">
|
<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.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.optimize" 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"/>
|
<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"/>
|
||||||
|
<option id="org.eclipse.cdt.cross.arm.gnu.cpp.compiler.option.include.paths.346409971" name="Include paths (-I)" superClass="org.eclipse.cdt.cross.arm.gnu.cpp.compiler.option.include.paths" valueType="includePath">
|
||||||
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}}""/>
|
||||||
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/hw_layer/serial_over_usb}""/>
|
||||||
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/hw_layer/lcd}""/>
|
||||||
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/ext}""/>
|
||||||
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/ext_algo}""/>
|
||||||
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/chibios/os/various}""/>
|
||||||
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/hw_layer/algo}""/>
|
||||||
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/util}""/>
|
||||||
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/console}""/>
|
||||||
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/console/tunerstudio}""/>
|
||||||
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/config}""/>
|
||||||
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/config/engines}""/>
|
||||||
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/config/boards}""/>
|
||||||
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/controllers}""/>
|
||||||
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/controllers/algo}""/>
|
||||||
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/controllers/core}""/>
|
||||||
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/controllers/trigger}""/>
|
||||||
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/controllers/sensors}""/>
|
||||||
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/controllers/system}""/>
|
||||||
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/controllers/math}""/>
|
||||||
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/console_util}""/>
|
||||||
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/emulation}""/>
|
||||||
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/emulation/test}""/>
|
||||||
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/emulation/hw_layer}""/>
|
||||||
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/hw_layer}""/>
|
||||||
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/hw_layer/flash}""/>
|
||||||
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/russianefi}""/>
|
||||||
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/russianefi/algo}""/>
|
||||||
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/russianefi/ckp}""/>
|
||||||
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/russianefi/adc}""/>
|
||||||
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/config/system}""/>
|
||||||
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/splib}""/>
|
||||||
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/chibios/os/kernel/include}""/>
|
||||||
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/chibios/boards/ST_STM32F4_DISCOVERY}""/>
|
||||||
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/chibios/os/hal/src}""/>
|
||||||
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/chibios/os/hal/include}""/>
|
||||||
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/chibios/os/hal/platforms/STM32/TIMv1}""/>
|
||||||
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/chibios/os/hal/platforms/STM32/I2Cv1}""/>
|
||||||
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/chibios/os/hal/platforms/STM32}""/>
|
||||||
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/chibios/os/hal/platforms/STM32/RTCv2}""/>
|
||||||
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/chibios/os/hal/platforms/STM32/OTGv1}""/>
|
||||||
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/chibios/os/hal/platforms/STM32/GPIOv2}""/>
|
||||||
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/chibios/os/hal/platforms/STM32F4xx}""/>
|
||||||
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/chibios/os/hal/platforms/STM32/SPIv1}""/>
|
||||||
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/chibios/os/hal/platforms/STM32/USARTv1}""/>
|
||||||
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/chibios/os/ports/GCC/ARMCMx}""/>
|
||||||
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/chibios/os/ports/GCC/ARMCMx/STM32F4xx}""/>
|
||||||
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/chibios/os/ports/common/ARMCMx}""/>
|
||||||
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/chibios/os/ports/common/ARMCMx/CMSIS/include}""/>
|
||||||
|
</option>
|
||||||
<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"/>
|
<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>
|
||||||
<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.c.linker.release.1692652942" name="ARM Sourcery Windows GCC C Linker" superClass="org.eclipse.cdt.cross.arm.gnu.sourcery.windows.elf.c.linker.release"/>
|
||||||
|
|
|
@ -18,7 +18,7 @@ endif
|
||||||
|
|
||||||
# C++ specific options here (added to USE_OPT).
|
# C++ specific options here (added to USE_OPT).
|
||||||
ifeq ($(USE_CPPOPT),)
|
ifeq ($(USE_CPPOPT),)
|
||||||
USE_CPPOPT = -std=c++11 -fno-rtti -fno-exceptions -fno-use-cxa-atexit
|
USE_CPPOPT = -std=c++11 -fno-rtti -fno-exceptions -fno-use-cxa-atexit -Werror=write-strings
|
||||||
endif
|
endif
|
||||||
|
|
||||||
# Enable this if you want the linker to remove unused code and data
|
# Enable this if you want the linker to remove unused code and data
|
||||||
|
@ -196,8 +196,9 @@ INCDIR = $(PORTINC) $(KERNINC) $(TESTINC) \
|
||||||
hw_layer/serial_over_usb \
|
hw_layer/serial_over_usb \
|
||||||
hw_layer/algo \
|
hw_layer/algo \
|
||||||
hw_layer/lcd \
|
hw_layer/lcd \
|
||||||
emulation/hw_layer \
|
|
||||||
emulation \
|
emulation \
|
||||||
|
emulation/hw_layer \
|
||||||
|
emulation/test \
|
||||||
controllers \
|
controllers \
|
||||||
controllers/sensors \
|
controllers/sensors \
|
||||||
controllers/system \
|
controllers/system \
|
||||||
|
@ -292,7 +293,7 @@ ULIBS = -lm
|
||||||
##############################################################################
|
##############################################################################
|
||||||
|
|
||||||
ifeq ($(USE_FPU),yes)
|
ifeq ($(USE_FPU),yes)
|
||||||
USE_OPT += -mfloat-abi=softfp -mfpu=fpv4-sp-d16 -fsingle-precision-constant
|
USE_OPT += -mfloat-abi=hard -mfpu=fpv4-sp-d16 -fsingle-precision-constant
|
||||||
DDEFS += -DCORTEX_USE_FPU=TRUE
|
DDEFS += -DCORTEX_USE_FPU=TRUE
|
||||||
else
|
else
|
||||||
DDEFS += -DCORTEX_USE_FPU=FALSE
|
DDEFS += -DCORTEX_USE_FPU=FALSE
|
||||||
|
|
|
@ -192,10 +192,11 @@ static void serve_interrupt(SerialDriver *sdp) {
|
||||||
/* Physical transmission end.*/
|
/* Physical transmission end.*/
|
||||||
if (sr & USART_SR_TC) {
|
if (sr & USART_SR_TC) {
|
||||||
chSysLockFromIsr();
|
chSysLockFromIsr();
|
||||||
chnAddFlagsI(sdp, CHN_TRANSMISSION_END);
|
if (chOQIsEmptyI(&sdp->oqueue))
|
||||||
chSysUnlockFromIsr();
|
chnAddFlagsI(sdp, CHN_TRANSMISSION_END);
|
||||||
u->CR1 = cr1 & ~(USART_CR1_TXEIE | USART_CR1_TCIE);
|
u->CR1 = cr1 & ~USART_CR1_TCIE;
|
||||||
u->SR = ~USART_SR_TC;
|
u->SR = ~USART_SR_TC;
|
||||||
|
chSysUnlockFromIsr();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -35,6 +35,28 @@
|
||||||
|
|
||||||
#include "ch.h"
|
#include "ch.h"
|
||||||
|
|
||||||
|
extern stkalign_t __main_stack_base__;
|
||||||
|
|
||||||
|
int getRemainingStack(Thread *otp) {
|
||||||
|
#if CH_DBG_ENABLE_STACK_CHECK
|
||||||
|
register struct intctx *r13 asm ("r13");
|
||||||
|
otp->activeStack = r13;
|
||||||
|
|
||||||
|
int rs;
|
||||||
|
if (dbg_isr_cnt > 0) {
|
||||||
|
// ISR context
|
||||||
|
rs = (stkalign_t *) (r13 - 1) - &__main_stack_base__;
|
||||||
|
} else {
|
||||||
|
|
||||||
|
rs = (stkalign_t *) (r13 - 1) - otp->p_stklimit;
|
||||||
|
}
|
||||||
|
otp->remainingStack = rs;
|
||||||
|
return rs;
|
||||||
|
#else
|
||||||
|
return 99999;
|
||||||
|
#endif /* CH_DBG_ENABLE_STACK_CHECK */
|
||||||
|
}
|
||||||
|
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
/* Port interrupt handlers. */
|
/* Port interrupt handlers. */
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
|
|
|
@ -490,6 +490,8 @@ struct context {
|
||||||
|
|
||||||
void chDbgStackOverflowPanic(Thread *otp);
|
void chDbgStackOverflowPanic(Thread *otp);
|
||||||
|
|
||||||
|
int getRemainingStack(Thread *otp);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Performs a context switch between two threads.
|
* @brief Performs a context switch between two threads.
|
||||||
* @details This is the most critical code in any port, this function
|
* @details This is the most critical code in any port, this function
|
||||||
|
@ -504,8 +506,7 @@ void chDbgStackOverflowPanic(Thread *otp);
|
||||||
#define port_switch(ntp, otp) _port_switch(ntp, otp)
|
#define port_switch(ntp, otp) _port_switch(ntp, otp)
|
||||||
#else
|
#else
|
||||||
#define port_switch(ntp, otp) { \
|
#define port_switch(ntp, otp) { \
|
||||||
register struct intctx *r13 asm ("r13"); \
|
if (getRemainingStack(otp) < 0) \
|
||||||
if ((stkalign_t *)(r13 - 1) < otp->p_stklimit) \
|
|
||||||
chDbgStackOverflowPanic(otp); \
|
chDbgStackOverflowPanic(otp); \
|
||||||
_port_switch(ntp, otp); \
|
_port_switch(ntp, otp); \
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,6 +39,21 @@
|
||||||
/* Port interrupt handlers. */
|
/* Port interrupt handlers. */
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
int getRemainingStack(Thread *otp) {
|
||||||
|
#if CH_DBG_ENABLE_STACK_CHECK || defined(__DOXYGEN__)
|
||||||
|
int remainingStack;
|
||||||
|
if (dbg_isr_cnt > 0) {
|
||||||
|
remainingStack = 999; // todo
|
||||||
|
} else {
|
||||||
|
remainingStack = (stkalign_t *)(__get_SP() - sizeof(struct intctx)) - otp->p_stklimit;
|
||||||
|
}
|
||||||
|
otp->remainingStack = remainingStack;
|
||||||
|
return remainingStack;
|
||||||
|
#else
|
||||||
|
return 999999;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief System Timer vector.
|
* @brief System Timer vector.
|
||||||
* @details This interrupt is used as system tick.
|
* @details This interrupt is used as system tick.
|
||||||
|
|
|
@ -470,6 +470,8 @@ struct context {
|
||||||
#define port_wait_for_interrupt()
|
#define port_wait_for_interrupt()
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
int getRemainingStack(Thread *otp);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Performs a context switch between two threads.
|
* @brief Performs a context switch between two threads.
|
||||||
* @details This is the most critical code in any port, this function
|
* @details This is the most critical code in any port, this function
|
||||||
|
@ -484,7 +486,7 @@ struct context {
|
||||||
#define port_switch(ntp, otp) _port_switch(ntp, otp)
|
#define port_switch(ntp, otp) _port_switch(ntp, otp)
|
||||||
#else
|
#else
|
||||||
#define port_switch(ntp, otp) { \
|
#define port_switch(ntp, otp) { \
|
||||||
if ((stkalign_t *)(__get_SP() - sizeof(struct intctx)) < otp->p_stklimit) \
|
if (getRemainingStack(otp) < 0) \
|
||||||
chDbgPanic("stack overflow"); \
|
chDbgPanic("stack overflow"); \
|
||||||
_port_switch(ntp, otp); \
|
_port_switch(ntp, otp); \
|
||||||
}
|
}
|
||||||
|
|
|
@ -205,8 +205,8 @@
|
||||||
#define TS_SERIAL_RX_PIN 11
|
#define TS_SERIAL_RX_PIN 11
|
||||||
#define TS_SERIAL_AF 7
|
#define TS_SERIAL_AF 7
|
||||||
|
|
||||||
#define LED_CRANKING_STATUS_PORT GPIOD
|
#define LED_WARNING_PORT GPIOD
|
||||||
#define LED_CRANKING_STATUS_PIN GPIOD_LED3
|
#define LED_WARNING_PIN GPIOD_LED3
|
||||||
|
|
||||||
#define LED_RUNNING_STATUS_PORT GPIOD
|
#define LED_RUNNING_STATUS_PORT GPIOD
|
||||||
#define LED_RUNNING_STATUS_PIN GPIOD_LED4
|
#define LED_RUNNING_STATUS_PIN GPIOD_LED4
|
||||||
|
|
|
@ -10,15 +10,17 @@
|
||||||
#ifndef EFIFEATURES_H_
|
#ifndef EFIFEATURES_H_
|
||||||
#define EFIFEATURES_H_
|
#define EFIFEATURES_H_
|
||||||
|
|
||||||
|
#define EFI_USE_CCM TRUE
|
||||||
|
|
||||||
|
//#define EFI_UART_ECHO_TEST_MODE TRUE
|
||||||
|
|
||||||
|
#define EFI_USE_UART_FOR_CONSOLE FALSE
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Build-in logic analyzer support. Logic analyzer viewer is one of the java console panes.
|
* Build-in logic analyzer support. Logic analyzer viewer is one of the java console panes.
|
||||||
*/
|
*/
|
||||||
#define EFI_WAVE_ANALYZER TRUE
|
#define EFI_WAVE_ANALYZER TRUE
|
||||||
|
|
||||||
|
|
||||||
#define EFI_WAVE_CHART TRUE
|
|
||||||
#define EFI_ANALOG_CHART TRUE
|
|
||||||
|
|
||||||
//#define SERIAL_SPEED (8 * 115200)
|
//#define SERIAL_SPEED (8 * 115200)
|
||||||
//#define SERIAL_SPEED (2 * 115200)
|
//#define SERIAL_SPEED (2 * 115200)
|
||||||
#define SERIAL_SPEED 115200
|
#define SERIAL_SPEED 115200
|
||||||
|
@ -28,10 +30,6 @@
|
||||||
*/
|
*/
|
||||||
#define EFI_TUNER_STUDIO TRUE
|
#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
|
* TunerStudio debug output
|
||||||
*/
|
*/
|
||||||
|
@ -82,19 +80,6 @@
|
||||||
#define EFI_ENGINE_EMULATOR TRUE
|
#define EFI_ENGINE_EMULATOR TRUE
|
||||||
#define EFI_EMULATE_POSITION_SENSORS 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 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.
|
* This macros is NOT about taking out logging in general.
|
||||||
|
@ -120,7 +105,18 @@
|
||||||
#define EFI_SUPPORT_NISSAN_PRIMERA TRUE
|
#define EFI_SUPPORT_NISSAN_PRIMERA TRUE
|
||||||
#define EFI_SUPPORT_1995_FORD_INLINE_6 TRUE
|
#define EFI_SUPPORT_1995_FORD_INLINE_6 TRUE
|
||||||
|
|
||||||
|
#if defined __GNUC__
|
||||||
#define EFI_PERF_METRICS TRUE
|
#define EFI_PERF_METRICS TRUE
|
||||||
|
#define EFI_ANALOG_CHART TRUE
|
||||||
|
#define EFI_WAVE_CHART TRUE
|
||||||
|
#define DL_OUTPUT_BUFFER 9000
|
||||||
|
#else
|
||||||
|
// todo: CCM usage for IAR?
|
||||||
|
#define EFI_PERF_METRICS FALSE
|
||||||
|
#define EFI_ANALOG_CHART FALSE
|
||||||
|
#define EFI_WAVE_CHART FALSE
|
||||||
|
#define DL_OUTPUT_BUFFER 6000
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Do we need GPS logic?
|
* Do we need GPS logic?
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/**
|
/**
|
||||||
* @file GY6_139QMB.c
|
* @file GY6_139QMB.cpp
|
||||||
* @brief 139qmb default engine configuration
|
* @brief 139qmb default engine configuration
|
||||||
*
|
*
|
||||||
* @date Feb 13, 2014
|
* @date Feb 13, 2014
|
||||||
|
@ -7,6 +7,7 @@
|
||||||
* @author Andrey Belomutskiy, (c) 2012-2014
|
* @author Andrey Belomutskiy, (c) 2012-2014
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "main.h"
|
||||||
#include "GY6_139QMB.h"
|
#include "GY6_139QMB.h"
|
||||||
|
|
||||||
void setGy6139qmbDefaultEngineConfiguration(engine_configuration_s *engineConfiguration) {
|
void setGy6139qmbDefaultEngineConfiguration(engine_configuration_s *engineConfiguration) {
|
||||||
|
@ -17,7 +18,7 @@ void setGy6139qmbDefaultEngineConfiguration(engine_configuration_s *engineConfig
|
||||||
engineConfiguration->globalTriggerAngleOffset = 15;
|
engineConfiguration->globalTriggerAngleOffset = 15;
|
||||||
engineConfiguration->analogChartMode = AC_MAP;
|
engineConfiguration->analogChartMode = AC_MAP;
|
||||||
engineConfiguration->cylindersCount = 1;
|
engineConfiguration->cylindersCount = 1;
|
||||||
engineConfiguration->rpmMultiplier = 1;
|
setOperationMode(engineConfiguration, FOUR_STROKE_CRANK_SENSOR);
|
||||||
|
|
||||||
engineConfiguration->firingOrder = FO_ONE_CYLINDER;
|
engineConfiguration->firingOrder = FO_ONE_CYLINDER;
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/**
|
/**
|
||||||
* @file audi_aan.c
|
* @file audi_aan.cpp
|
||||||
* @brief Audo AAN default engine configuration
|
* @brief Audo AAN default engine configuration
|
||||||
*
|
*
|
||||||
* @date Nov 24, 2013
|
* @date Nov 24, 2013
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/**
|
/**
|
||||||
* @file dodge_neon.c
|
* @file dodge_neon.cpp
|
||||||
*
|
*
|
||||||
* DODGE_NEON_1995 = 2
|
* DODGE_NEON_1995 = 2
|
||||||
*
|
*
|
||||||
|
@ -18,6 +18,7 @@
|
||||||
|
|
||||||
void setDodgeNeonEngineConfiguration(engine_configuration_s *engineConfiguration,
|
void setDodgeNeonEngineConfiguration(engine_configuration_s *engineConfiguration,
|
||||||
board_configuration_s *boardConfiguration) {
|
board_configuration_s *boardConfiguration) {
|
||||||
|
|
||||||
engineConfiguration->triggerConfig.triggerType = TT_DODGE_NEON;
|
engineConfiguration->triggerConfig.triggerType = TT_DODGE_NEON;
|
||||||
|
|
||||||
engineConfiguration->engineLoadMode = LM_TPS;
|
engineConfiguration->engineLoadMode = LM_TPS;
|
||||||
|
@ -39,10 +40,8 @@ void setDodgeNeonEngineConfiguration(engine_configuration_s *engineConfiguration
|
||||||
// set_whole_fuel_map 3
|
// set_whole_fuel_map 3
|
||||||
setWholeFuelMap(engineConfiguration, 3);
|
setWholeFuelMap(engineConfiguration, 3);
|
||||||
|
|
||||||
engineConfiguration->triggerConfig.syncRatioFrom = 0.72 * 0.8;
|
setTriggerSynchronizationGap(engineConfiguration, 0.72);
|
||||||
engineConfiguration->triggerConfig.syncRatioTo = 0.72 * 1.3;
|
|
||||||
|
|
||||||
engineConfiguration->triggerConfig.isSynchronizationNeeded = TRUE;
|
|
||||||
engineConfiguration->triggerConfig.useRiseEdge = FALSE;
|
engineConfiguration->triggerConfig.useRiseEdge = FALSE;
|
||||||
engineConfiguration->needSecondTriggerInput = TRUE;
|
engineConfiguration->needSecondTriggerInput = TRUE;
|
||||||
|
|
||||||
|
|
|
@ -1,15 +0,0 @@
|
||||||
/**
|
|
||||||
* @file engines.h
|
|
||||||
*
|
|
||||||
* @date Aug 30, 2013
|
|
||||||
* @author Andrey Belomutskiy, (c) 2012-2014
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef ENGINE_H_
|
|
||||||
#define ENGINE_H_
|
|
||||||
|
|
||||||
#include "boards.h"
|
|
||||||
#include "efifeatures.h"
|
|
||||||
#include "rusefi_enums.h"
|
|
||||||
|
|
||||||
#endif /* ENGINE_H_ */
|
|
|
@ -14,5 +14,6 @@ ENGINES_SRC_CPP = $(PROJECT_DIR)/config/engines/ford_aspire.cpp \
|
||||||
$(PROJECT_DIR)/config/engines/honda_accord.cpp \
|
$(PROJECT_DIR)/config/engines/honda_accord.cpp \
|
||||||
$(PROJECT_DIR)/config/engines/snow_blower.cpp \
|
$(PROJECT_DIR)/config/engines/snow_blower.cpp \
|
||||||
$(PROJECT_DIR)/config/engines/GY6_139QMB.cpp \
|
$(PROJECT_DIR)/config/engines/GY6_139QMB.cpp \
|
||||||
|
$(PROJECT_DIR)/config/engines/rover_v8.cpp \
|
||||||
$(PROJECT_DIR)/config/engines/mazda_323.cpp \
|
$(PROJECT_DIR)/config/engines/mazda_323.cpp \
|
||||||
$(PROJECT_DIR)/config/engines/saturn_ion.cpp
|
$(PROJECT_DIR)/config/engines/saturn_ion.cpp
|
|
@ -1,5 +1,5 @@
|
||||||
/**
|
/**
|
||||||
* @file ford_1995_inline_6.c
|
* @file ford_1995_inline_6.cpp
|
||||||
* @brief Default engine configuration for a 1995 Ford inline 6 engine
|
* @brief Default engine configuration for a 1995 Ford inline 6 engine
|
||||||
*
|
*
|
||||||
* http://rusefi.com/forum/viewtopic.php?f=3&t=469
|
* http://rusefi.com/forum/viewtopic.php?f=3&t=469
|
||||||
|
@ -23,10 +23,7 @@
|
||||||
void setFordInline6(engine_configuration_s *engineConfiguration, board_configuration_s *boardConfiguration) {
|
void setFordInline6(engine_configuration_s *engineConfiguration, board_configuration_s *boardConfiguration) {
|
||||||
engineConfiguration->cylindersCount = 6;
|
engineConfiguration->cylindersCount = 6;
|
||||||
|
|
||||||
/**
|
setOperationMode(engineConfiguration, FOUR_STROKE_CAM_SENSOR);
|
||||||
* 0.5 means primary position sensor is on a camshaft
|
|
||||||
*/
|
|
||||||
engineConfiguration->rpmMultiplier = 0.5;
|
|
||||||
|
|
||||||
engineConfiguration->ignitionMode = IM_ONE_COIL;
|
engineConfiguration->ignitionMode = IM_ONE_COIL;
|
||||||
engineConfiguration->firingOrder = FO_1_THEN_5_THEN_3_THEN_6_THEN_2_THEN_4;
|
engineConfiguration->firingOrder = FO_1_THEN_5_THEN_3_THEN_6_THEN_2_THEN_4;
|
||||||
|
@ -41,6 +38,7 @@ void setFordInline6(engine_configuration_s *engineConfiguration, board_configura
|
||||||
/**
|
/**
|
||||||
* We treat the trigger as 6/0 toothed wheel
|
* We treat the trigger as 6/0 toothed wheel
|
||||||
*/
|
*/
|
||||||
|
engineConfiguration->triggerConfig.triggerType = TT_TOOTHED_WHEEL;
|
||||||
engineConfiguration->triggerConfig.totalToothCount = 6;
|
engineConfiguration->triggerConfig.totalToothCount = 6;
|
||||||
engineConfiguration->triggerConfig.skippedToothCount = 0;
|
engineConfiguration->triggerConfig.skippedToothCount = 0;
|
||||||
engineConfiguration->triggerConfig.isSynchronizationNeeded = FALSE;
|
engineConfiguration->triggerConfig.isSynchronizationNeeded = FALSE;
|
||||||
|
|
|
@ -13,7 +13,6 @@
|
||||||
#include "ford_aspire.h"
|
#include "ford_aspire.h"
|
||||||
|
|
||||||
#include "allsensors.h"
|
#include "allsensors.h"
|
||||||
#include "engines.h"
|
|
||||||
#include "engine_math.h"
|
#include "engine_math.h"
|
||||||
#include "advance_map.h"
|
#include "advance_map.h"
|
||||||
#include "engine_configuration.h"
|
#include "engine_configuration.h"
|
||||||
|
@ -103,6 +102,10 @@ void setFordAspireEngineConfiguration(engine_configuration_s *engineConfiguratio
|
||||||
// engineConfiguration->ignitionPinMode = OM_INVERTED;
|
// engineConfiguration->ignitionPinMode = OM_INVERTED;
|
||||||
|
|
||||||
engineConfiguration->cylindersCount = 4;
|
engineConfiguration->cylindersCount = 4;
|
||||||
|
engineConfiguration->displacement = 1.3;
|
||||||
|
// Denso 195500-2110
|
||||||
|
engineConfiguration->injectorFlow = 119.8;
|
||||||
|
|
||||||
engineConfiguration->firingOrder = FO_1_THEN_3_THEN_4_THEN2;
|
engineConfiguration->firingOrder = FO_1_THEN_3_THEN_4_THEN2;
|
||||||
engineConfiguration->globalTriggerAngleOffset = 175;
|
engineConfiguration->globalTriggerAngleOffset = 175;
|
||||||
engineConfiguration->ignitionOffset = 98 - 11;
|
engineConfiguration->ignitionOffset = 98 - 11;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/**
|
/**
|
||||||
* @file ford_fiesta.c
|
* @file ford_fiesta.cpp
|
||||||
* @brief European 1990 Ford Fiesta
|
* @brief European 1990 Ford Fiesta
|
||||||
*
|
*
|
||||||
* FORD_FIESTA = 4
|
* FORD_FIESTA = 4
|
||||||
|
@ -18,8 +18,7 @@
|
||||||
|
|
||||||
void setFordFiestaDefaultEngineConfiguration(engine_configuration_s *engineConfiguration) {
|
void setFordFiestaDefaultEngineConfiguration(engine_configuration_s *engineConfiguration) {
|
||||||
engineConfiguration->rpmHardLimit = 7000;
|
engineConfiguration->rpmHardLimit = 7000;
|
||||||
// only crankshaft sensor so far
|
setOperationMode(engineConfiguration, FOUR_STROKE_CRANK_SENSOR);
|
||||||
engineConfiguration->rpmMultiplier = 1;
|
|
||||||
|
|
||||||
engineConfiguration->triggerConfig.totalToothCount = 36;
|
engineConfiguration->triggerConfig.totalToothCount = 36;
|
||||||
engineConfiguration->triggerConfig.skippedToothCount = 1;
|
engineConfiguration->triggerConfig.skippedToothCount = 1;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/**
|
/**
|
||||||
* @file honda_accord.c
|
* @file honda_accord.cpp
|
||||||
*
|
*
|
||||||
* @date Jan 12, 2014
|
* @date Jan 12, 2014
|
||||||
* @author Andrey Belomutskiy, (c) 2012-2014
|
* @author Andrey Belomutskiy, (c) 2012-2014
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/**
|
/**
|
||||||
* @file mazda_323.c
|
* @file mazda_323.cpp
|
||||||
*
|
*
|
||||||
* @date Mar 8, 2014
|
* @date Mar 8, 2014
|
||||||
* @author Andrey Belomutskiy, (c) 2012-2014
|
* @author Andrey Belomutskiy, (c) 2012-2014
|
||||||
|
@ -8,7 +8,8 @@
|
||||||
#include "mazda_323.h"
|
#include "mazda_323.h"
|
||||||
|
|
||||||
void setMazda323EngineConfiguration(engine_configuration_s *engineConfiguration) {
|
void setMazda323EngineConfiguration(engine_configuration_s *engineConfiguration) {
|
||||||
engineConfiguration->cylindersCount = 6;
|
engineConfiguration->cylindersCount = 4;
|
||||||
|
engineConfiguration->displacement = 1.6;
|
||||||
|
|
||||||
engineConfiguration->ignitionMode = IM_ONE_COIL;
|
engineConfiguration->ignitionMode = IM_ONE_COIL;
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/**
|
/**
|
||||||
* @file mazda_miata_nb.c
|
* @file mazda_miata_nb.cpp
|
||||||
*
|
*
|
||||||
* MAZDA_MIATA_NB = 9
|
* MAZDA_MIATA_NB = 9
|
||||||
*
|
*
|
||||||
|
@ -16,10 +16,8 @@ void setMazdaMiataNbEngineConfiguration(engine_configuration_s *engineConfigurat
|
||||||
engineConfiguration->rpmHardLimit = 3000; // yes, 3k. let's play it safe for now
|
engineConfiguration->rpmHardLimit = 3000; // yes, 3k. let's play it safe for now
|
||||||
|
|
||||||
engineConfiguration->triggerConfig.triggerType = TT_MAZDA_MIATA_NB;
|
engineConfiguration->triggerConfig.triggerType = TT_MAZDA_MIATA_NB;
|
||||||
engineConfiguration->triggerConfig.isSynchronizationNeeded = TRUE;
|
|
||||||
|
|
||||||
engineConfiguration->triggerConfig.syncRatioFrom = 0.11 * 0.7;
|
setTriggerSynchronizationGap(engineConfiguration, 0.11);
|
||||||
engineConfiguration->triggerConfig.syncRatioTo = 0.11 * 1.3;
|
|
||||||
engineConfiguration->triggerConfig.useRiseEdge = FALSE;
|
engineConfiguration->triggerConfig.useRiseEdge = FALSE;
|
||||||
engineConfiguration->globalTriggerAngleOffset = 276;
|
engineConfiguration->globalTriggerAngleOffset = 276;
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
/**
|
/**
|
||||||
* @file nissan_primera.c
|
* @file nissan_primera.cpp
|
||||||
|
*
|
||||||
|
* engine_type 5
|
||||||
*
|
*
|
||||||
* @date Oct 14, 2013
|
* @date Oct 14, 2013
|
||||||
* @author Andrey Belomutskiy, (c) 2012-2014
|
* @author Andrey Belomutskiy, (c) 2012-2014
|
||||||
|
|
|
@ -0,0 +1,70 @@
|
||||||
|
/**
|
||||||
|
* @file rover_v8.cpp
|
||||||
|
*
|
||||||
|
* V8, firing order 18436572
|
||||||
|
*
|
||||||
|
* ROVER_V8 = 10
|
||||||
|
*
|
||||||
|
* @date Jun 27, 2014
|
||||||
|
* @author Andrey Belomutskiy, (c) 2012-2014
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "main.h"
|
||||||
|
#include "rover_v8.h"
|
||||||
|
|
||||||
|
void setRoverv8(engine_configuration_s *engineConfiguration,
|
||||||
|
board_configuration_s *boardConfiguration) {
|
||||||
|
|
||||||
|
setOperationMode(engineConfiguration, FOUR_STROKE_CRANK_SENSOR);
|
||||||
|
engineConfiguration->triggerConfig.totalToothCount = 36;
|
||||||
|
engineConfiguration->triggerConfig.skippedToothCount = 1;
|
||||||
|
|
||||||
|
// todo: displacement? 4 liters?
|
||||||
|
engineConfiguration->displacement = 4;
|
||||||
|
engineConfiguration->cylindersCount = 8;
|
||||||
|
engineConfiguration->firingOrder = FO_1_8_4_3_6_5_7_2;
|
||||||
|
|
||||||
|
// set_rpm_hard_limit 4000
|
||||||
|
engineConfiguration->rpmHardLimit = 4000; // yes, 4k. let's play it safe for now
|
||||||
|
// set_cranking_rpm 550
|
||||||
|
engineConfiguration->crankingSettings.crankingRpm = 550;
|
||||||
|
|
||||||
|
// set_whole_fuel_map 3
|
||||||
|
setWholeFuelMap(engineConfiguration, 3);
|
||||||
|
|
||||||
|
|
||||||
|
// set_cranking_injection_mode 0
|
||||||
|
engineConfiguration->crankingInjectionMode = IM_SEQUENTIAL;
|
||||||
|
// set_injection_mode 1
|
||||||
|
engineConfiguration->injectionMode = IM_SEQUENTIAL;
|
||||||
|
|
||||||
|
// set_ignition_mode 2
|
||||||
|
engineConfiguration->ignitionMode = IM_WASTED_SPARK;
|
||||||
|
|
||||||
|
|
||||||
|
// Frankenstein: low side - inj #1: PC14
|
||||||
|
// Frankenstein: low side - inj #2: PC15
|
||||||
|
// Frankenstein: low side - inj #3: PE6
|
||||||
|
// Frankenstein: low side - inj #4: PC13
|
||||||
|
// Frankenstein: low side - inj #5: PE4
|
||||||
|
// Frankenstein: low side - inj #6: PE5
|
||||||
|
// Frankenstein: low side - inj #7: PE2
|
||||||
|
// Frankenstein: low side - inj #8: PE3
|
||||||
|
// Frankenstein: low side - inj #9: PE0
|
||||||
|
// Frankenstein: low side - inj #10: PE1
|
||||||
|
// Frankenstein: low side - inj #11: PB8
|
||||||
|
// Frankenstein: low side - inj #12: PB9
|
||||||
|
|
||||||
|
boardConfiguration->injectionPins[0] = GPIOB_9; // Frankenstein: low side - inj #12
|
||||||
|
boardConfiguration->injectionPins[1] = GPIOB_8; // Frankenstein: low side - inj #11
|
||||||
|
boardConfiguration->injectionPins[2] = GPIOE_3; // Frankenstein: low side - inj #8
|
||||||
|
boardConfiguration->injectionPins[3] = GPIOE_5; // Frankenstein: low side - inj #6
|
||||||
|
|
||||||
|
boardConfiguration->fuelPumpPin = GPIOC_13; // Frankenstein: low side - inj #4
|
||||||
|
boardConfiguration->fuelPumpPinMode = OM_DEFAULT;
|
||||||
|
|
||||||
|
// set_injection_pin_mode 0
|
||||||
|
boardConfiguration->injectionPinMode = OM_DEFAULT;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,15 @@
|
||||||
|
/**
|
||||||
|
* @file rover_v8.h
|
||||||
|
*
|
||||||
|
* @date Jun 27, 2014
|
||||||
|
* @author Andrey Belomutskiy, (c) 2012-2014
|
||||||
|
*/
|
||||||
|
#ifndef ROVER_V8_H_
|
||||||
|
#define ROVER_V8_H_
|
||||||
|
|
||||||
|
#include "engine_configuration.h"
|
||||||
|
|
||||||
|
void setRoverv8(engine_configuration_s *engineConfiguration,
|
||||||
|
board_configuration_s *boardConfiguration);
|
||||||
|
|
||||||
|
#endif /* ROVER_V8_H_ */
|
|
@ -1,5 +1,5 @@
|
||||||
/**
|
/**
|
||||||
* @file snow_blower.c
|
* @file snow_blower.cpp
|
||||||
* @brief Default configuration of a single-cylinder engine
|
* @brief Default configuration of a single-cylinder engine
|
||||||
*
|
*
|
||||||
* @date Sep 9, 2013
|
* @date Sep 9, 2013
|
||||||
|
@ -7,8 +7,3 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
|
|
||||||
#if EFI_ENGINE_SNOW_BLOWER
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
|
@ -28,8 +28,8 @@
|
||||||
/*
|
/*
|
||||||
* ST32F407xG memory setup.
|
* ST32F407xG memory setup.
|
||||||
*/
|
*/
|
||||||
__main_stack_size__ = 0x0400;
|
__main_stack_size__ = 0x0600;
|
||||||
__process_stack_size__ = 0x0400;
|
__process_stack_size__ = 0x0600;
|
||||||
|
|
||||||
MEMORY
|
MEMORY
|
||||||
{
|
{
|
||||||
|
@ -127,7 +127,7 @@ SECTIONS
|
||||||
__main_thread_stack_end__ = .;
|
__main_thread_stack_end__ = .;
|
||||||
} > ram
|
} > ram
|
||||||
|
|
||||||
.ccm :
|
.ccm (NOLOAD) :
|
||||||
{
|
{
|
||||||
PROVIDE(_cmm_start = .);
|
PROVIDE(_cmm_start = .);
|
||||||
. = ALIGN(4);
|
. = ALIGN(4);
|
||||||
|
|
|
@ -45,11 +45,11 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#define PORT_IDLE_THREAD_STACK_SIZE 256
|
#define PORT_IDLE_THREAD_STACK_SIZE 1024
|
||||||
|
|
||||||
#define PORT_INT_REQUIRED_STACK 128
|
#define PORT_INT_REQUIRED_STACK 768
|
||||||
|
|
||||||
#define CHPRINTF_USE_FLOAT TRUE
|
#define CHPRINTF_USE_FLOAT TRUE
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* number of ticks per second
|
* number of ticks per second
|
||||||
|
@ -480,6 +480,8 @@
|
||||||
*/
|
*/
|
||||||
#if !defined(THREAD_EXT_FIELDS) || defined(__DOXYGEN__)
|
#if !defined(THREAD_EXT_FIELDS) || defined(__DOXYGEN__)
|
||||||
#define THREAD_EXT_FIELDS \
|
#define THREAD_EXT_FIELDS \
|
||||||
|
void *activeStack; \
|
||||||
|
int remainingStack; \
|
||||||
/* Add threads custom fields here.*/
|
/* Add threads custom fields here.*/
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -30,7 +30,9 @@
|
||||||
|
|
||||||
#define STM32F4xx_MCUCONF
|
#define STM32F4xx_MCUCONF
|
||||||
|
|
||||||
#include "engines.h"
|
#include "boards.h"
|
||||||
|
#include "efifeatures.h"
|
||||||
|
#include "rusefi_enums.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* HAL driver system settings.
|
* HAL driver system settings.
|
||||||
|
|
|
@ -22,12 +22,19 @@
|
||||||
#include "console_io.h"
|
#include "console_io.h"
|
||||||
|
|
||||||
#if EFI_PROD_CODE
|
#if EFI_PROD_CODE
|
||||||
|
extern SerialUSBDriver SDU1;
|
||||||
|
#include "usbcfg.h"
|
||||||
#include "usbconsole.h"
|
#include "usbconsole.h"
|
||||||
#endif
|
#endif
|
||||||
#include "rfiutil.h"
|
#include "rfiutil.h"
|
||||||
|
|
||||||
|
int lastWriteSize;
|
||||||
|
int lastWriteActual;
|
||||||
|
|
||||||
static bool_t isSerialConsoleStarted = FALSE;
|
static bool_t isSerialConsoleStarted = FALSE;
|
||||||
|
|
||||||
|
static EventListener consoleEventListener;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Reads a whole line from the input channel.
|
* @brief Reads a whole line from the input channel.
|
||||||
*
|
*
|
||||||
|
@ -38,7 +45,7 @@ static bool_t isSerialConsoleStarted = FALSE;
|
||||||
* @retval TRUE the channel was reset or CTRL-D pressed.
|
* @retval TRUE the channel was reset or CTRL-D pressed.
|
||||||
* @retval FALSE operation successful.
|
* @retval FALSE operation successful.
|
||||||
*/
|
*/
|
||||||
static bool_t getConsoleLine(BaseSequentialStream *chp, char *line, unsigned size) {
|
static bool getConsoleLine(BaseSequentialStream *chp, char *line, unsigned size) {
|
||||||
char *p = line;
|
char *p = line;
|
||||||
|
|
||||||
while (TRUE) {
|
while (TRUE) {
|
||||||
|
@ -49,6 +56,30 @@ static bool_t getConsoleLine(BaseSequentialStream *chp, char *line, unsigned siz
|
||||||
}
|
}
|
||||||
|
|
||||||
short c = (short) chSequentialStreamGet(chp);
|
short c = (short) chSequentialStreamGet(chp);
|
||||||
|
|
||||||
|
if (isSerialOverUart()) {
|
||||||
|
uint32_t flags;
|
||||||
|
chSysLock()
|
||||||
|
;
|
||||||
|
|
||||||
|
flags = chEvtGetAndClearFlagsI(&consoleEventListener);
|
||||||
|
chSysUnlock()
|
||||||
|
;
|
||||||
|
|
||||||
|
if (flags & SD_OVERRUN_ERROR) {
|
||||||
|
// firmwareError("serial overrun");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#if EFI_UART_ECHO_TEST_MODE
|
||||||
|
/**
|
||||||
|
* That's test code - let's test connectivity
|
||||||
|
*/
|
||||||
|
consolePutChar((uint8_t) c);
|
||||||
|
continue;
|
||||||
|
#endif
|
||||||
|
|
||||||
if (c < 0)
|
if (c < 0)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
if (c == 4) {
|
if (c == 4) {
|
||||||
|
@ -84,13 +115,19 @@ static char consoleInput[] = "
|
||||||
|
|
||||||
void (*console_line_callback)(char *);
|
void (*console_line_callback)(char *);
|
||||||
|
|
||||||
static WORKING_AREA(consoleThreadStack, 2 * UTILITY_THREAD_STACK_SIZE);
|
static bool is_serial_over_uart;
|
||||||
|
|
||||||
|
bool isSerialOverUart(void) {
|
||||||
|
return is_serial_over_uart;
|
||||||
|
}
|
||||||
|
|
||||||
|
static THD_WORKING_AREA(consoleThreadStack, 2 * UTILITY_THREAD_STACK_SIZE);
|
||||||
static msg_t consoleThreadThreadEntryPoint(void *arg) {
|
static msg_t consoleThreadThreadEntryPoint(void *arg) {
|
||||||
(void) arg;
|
(void) arg;
|
||||||
chRegSetThreadName("console thread");
|
chRegSetThreadName("console thread");
|
||||||
|
|
||||||
while (TRUE) {
|
while (TRUE) {
|
||||||
bool_t end = getConsoleLine((BaseSequentialStream *) CONSOLE_CHANNEL, consoleInput, sizeof(consoleInput));
|
bool end = getConsoleLine((BaseSequentialStream*) getConsoleChannel(), consoleInput, sizeof(consoleInput));
|
||||||
if (end) {
|
if (end) {
|
||||||
// firmware simulator is the only case when this happens
|
// firmware simulator is the only case when this happens
|
||||||
continue;
|
continue;
|
||||||
|
@ -103,47 +140,68 @@ static msg_t consoleThreadThreadEntryPoint(void *arg) {
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#if EFI_SERIAL_OVER_USB
|
#if EFI_PROD_CODE
|
||||||
#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 ! EFI_SERIAL_OVER_USB && ! EFI_SIMULATOR
|
static SerialConfig serialConfig = { SERIAL_SPEED, 0, USART_CR2_STOP1_BITS | USART_CR2_LINEN, 0 };
|
||||||
int isConsoleReady(void) {
|
|
||||||
return isSerialConsoleStarted;
|
SerialDriver * getConsoleChannel(void) {
|
||||||
|
if (isSerialOverUart()) {
|
||||||
|
return (SerialDriver *) EFI_CONSOLE_UART_DEVICE;
|
||||||
|
} else {
|
||||||
|
return (SerialDriver *) &SDU1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
int isConsoleReady(void) {
|
||||||
|
if (isSerialOverUart()) {
|
||||||
|
return isSerialConsoleStarted;
|
||||||
|
} else {
|
||||||
|
return is_usb_serial_ready();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* EFI_PROD_CODE */
|
||||||
|
|
||||||
void consolePutChar(int x) {
|
void consolePutChar(int x) {
|
||||||
chSequentialStreamPut(CONSOLE_CHANNEL, (uint8_t )(x));
|
chSequentialStreamPut(getConsoleChannel(), (uint8_t )(x));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 10 seconds
|
||||||
|
#define CONSOLE_WRITE_TIMEOUT 10000
|
||||||
|
|
||||||
void consoleOutputBuffer(const int8_t *buf, int size) {
|
void consoleOutputBuffer(const int8_t *buf, int size) {
|
||||||
chSequentialStreamWrite(CONSOLE_CHANNEL, buf, size);
|
lastWriteSize = size;
|
||||||
|
#if !EFI_UART_ECHO_TEST_MODE
|
||||||
|
lastWriteActual = chnWriteTimeout(getConsoleChannel(), buf, size, CONSOLE_WRITE_TIMEOUT);
|
||||||
|
// if (r != size)
|
||||||
|
// firmwareError("Partial console write");
|
||||||
|
#endif /* EFI_UART_ECHO_TEST_MODE */
|
||||||
}
|
}
|
||||||
|
|
||||||
void startConsole(void (*console_line_callback_p)(char *)) {
|
void startConsole(void (*console_line_callback_p)(char *)) {
|
||||||
console_line_callback = console_line_callback_p;
|
console_line_callback = console_line_callback_p;
|
||||||
#if EFI_SERIAL_OVER_USB
|
|
||||||
usb_serial_start();
|
|
||||||
|
|
||||||
#else
|
#if EFI_PROD_CODE
|
||||||
#if EFI_SERIAL_OVER_UART
|
is_serial_over_uart = palReadPad(GPIOA, GPIOA_BUTTON) != EFI_USE_UART_FOR_CONSOLE;
|
||||||
/*
|
|
||||||
* 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
|
if (isSerialOverUart()) {
|
||||||
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));
|
* 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(EFI_CONSOLE_UART_DEVICE, &serialConfig);
|
||||||
|
|
||||||
isSerialConsoleStarted = TRUE;
|
// cannot use pin repository here because pin repository prints to console
|
||||||
#endif /* EFI_SERIAL_OVER_UART */
|
palSetPadMode(EFI_CONSOLE_RX_PORT, EFI_CONSOLE_RX_PIN, PAL_MODE_ALTERNATE(EFI_CONSOLE_AF));
|
||||||
#endif /* EFI_SERIAL_OVER_USB */
|
palSetPadMode(EFI_CONSOLE_TX_PORT, EFI_CONSOLE_TX_PIN, PAL_MODE_ALTERNATE(EFI_CONSOLE_AF));
|
||||||
|
|
||||||
|
isSerialConsoleStarted = TRUE;
|
||||||
|
|
||||||
|
chEvtRegisterMask((EventSource *) chnGetEventSource(EFI_CONSOLE_UART_DEVICE), &consoleEventListener, 1);
|
||||||
|
} else {
|
||||||
|
usb_serial_start();
|
||||||
|
}
|
||||||
|
#endif /* EFI_PROD_CODE */
|
||||||
chThdCreateStatic(consoleThreadStack, sizeof(consoleThreadStack), NORMALPRIO, consoleThreadThreadEntryPoint, NULL);
|
chThdCreateStatic(consoleThreadStack, sizeof(consoleThreadStack), NORMALPRIO, consoleThreadThreadEntryPoint, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -152,7 +210,7 @@ extern cnt_t dbg_isr_cnt;
|
||||||
/**
|
/**
|
||||||
* @return TRUE if already in locked context
|
* @return TRUE if already in locked context
|
||||||
*/
|
*/
|
||||||
bool_t lockAnyContext(void) {
|
bool lockAnyContext(void) {
|
||||||
int alreadyLocked = isLocked();
|
int alreadyLocked = isLocked();
|
||||||
if (alreadyLocked)
|
if (alreadyLocked)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
|
@ -21,23 +21,18 @@
|
||||||
#include "efifeatures.h"
|
#include "efifeatures.h"
|
||||||
#include "boards.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
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C"
|
extern "C"
|
||||||
{
|
{
|
||||||
#endif /* __cplusplus */
|
#endif /* __cplusplus */
|
||||||
|
|
||||||
|
SerialDriver * getConsoleChannel(void);
|
||||||
|
|
||||||
void consolePutChar(int x);
|
void consolePutChar(int x);
|
||||||
void consoleOutputBuffer(const int8_t *buf, int size);
|
void consoleOutputBuffer(const int8_t *buf, int size);
|
||||||
void startConsole(void (*console_line_callback_p)(char *));
|
void startConsole(void (*console_line_callback_p)(char *));
|
||||||
int isConsoleReady(void);
|
int isConsoleReady(void);
|
||||||
|
bool isSerialOverUart(void);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,6 +46,10 @@ static void myfatal(void) {
|
||||||
chDbgCheck(0, "my fatal");
|
chDbgCheck(0, "my fatal");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void myerror(void) {
|
||||||
|
firmwareError("firmwareError: %d", getRusEfiVersion());
|
||||||
|
}
|
||||||
|
|
||||||
static void sayHello(void) {
|
static void sayHello(void) {
|
||||||
printMsg(&logger, "*** rusEFI (c) Andrey Belomutskiy, 2012-2014. All rights reserved.");
|
printMsg(&logger, "*** rusEFI (c) Andrey Belomutskiy, 2012-2014. All rights reserved.");
|
||||||
printMsg(&logger, "rusEFI v%d@%d", getRusEfiVersion(), SVN_VERSION);
|
printMsg(&logger, "rusEFI v%d@%d", getRusEfiVersion(), SVN_VERSION);
|
||||||
|
@ -69,6 +73,9 @@ static void sayHello(void) {
|
||||||
printMsg(&logger, "STM32_PCLK2=%d", STM32_PCLK2);
|
printMsg(&logger, "STM32_PCLK2=%d", STM32_PCLK2);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
printMsg(&logger, "PORT_IDLE_THREAD_STACK_SIZE=%d", PORT_IDLE_THREAD_STACK_SIZE);
|
||||||
|
|
||||||
printMsg(&logger, "CH_DBG_ENABLE_ASSERTS=%d", CH_DBG_ENABLE_ASSERTS);
|
printMsg(&logger, "CH_DBG_ENABLE_ASSERTS=%d", CH_DBG_ENABLE_ASSERTS);
|
||||||
printMsg(&logger, "CH_DBG_ENABLED=%d", CH_DBG_ENABLED);
|
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_SYSTEM_STATE_CHECK=%d", CH_DBG_SYSTEM_STATE_CHECK);
|
||||||
|
@ -91,19 +98,8 @@ static void sayHello(void) {
|
||||||
printMsg(&logger, "EFI_SIGNAL_EXECUTOR_HW_TIMER=%d", EFI_SIGNAL_EXECUTOR_HW_TIMER);
|
printMsg(&logger, "EFI_SIGNAL_EXECUTOR_HW_TIMER=%d", EFI_SIGNAL_EXECUTOR_HW_TIMER);
|
||||||
#endif
|
#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);
|
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);
|
printMsg(&logger, "EFI_INTERNAL_ADC=%d", EFI_INTERNAL_ADC);
|
||||||
#endif
|
|
||||||
|
|
||||||
// printSimpleMsg(&logger, "", );
|
// printSimpleMsg(&logger, "", );
|
||||||
// printSimpleMsg(&logger, "", );
|
// printSimpleMsg(&logger, "", );
|
||||||
|
@ -119,6 +115,7 @@ static void sayHello(void) {
|
||||||
* This methods prints all threads and their total times
|
* This methods prints all threads and their total times
|
||||||
*/
|
*/
|
||||||
static void cmd_threads(void) {
|
static void cmd_threads(void) {
|
||||||
|
#if CH_DBG_THREADS_PROFILING || defined(__DOXYGEN__)
|
||||||
static const char *states[] = { THD_STATE_NAMES };
|
static const char *states[] = { THD_STATE_NAMES };
|
||||||
Thread *tp;
|
Thread *tp;
|
||||||
|
|
||||||
|
@ -130,6 +127,7 @@ static void cmd_threads(void) {
|
||||||
states[tp->p_state], (uint32_t) tp->p_time, tp->p_name);
|
states[tp->p_state], (uint32_t) tp->p_time, tp->p_name);
|
||||||
tp = chRegNextThread(tp);
|
tp = chRegNextThread(tp);
|
||||||
} while (tp != NULL );
|
} while (tp != NULL );
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void sendOutConfirmation(char *value, int i) {
|
void sendOutConfirmation(char *value, int i) {
|
||||||
|
@ -140,12 +138,14 @@ void sendOutConfirmation(char *value, int i) {
|
||||||
* This methods prints the message to whatever is configured as our primary console
|
* This methods prints the message to whatever is configured as our primary console
|
||||||
*/
|
*/
|
||||||
void print(const char *format, ...) {
|
void print(const char *format, ...) {
|
||||||
|
#if !EFI_UART_ECHO_TEST_MODE
|
||||||
if (!isConsoleReady())
|
if (!isConsoleReady())
|
||||||
return;
|
return;
|
||||||
va_list ap;
|
va_list ap;
|
||||||
va_start(ap, format);
|
va_start(ap, format);
|
||||||
chvprintf((BaseSequentialStream *)CONSOLE_CHANNEL, format, ap);
|
chvprintf((BaseSequentialStream*)getConsoleChannel(), format, ap);
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
|
#endif /* EFI_UART_ECHO_TEST_MODE */
|
||||||
}
|
}
|
||||||
|
|
||||||
void initializeConsole() {
|
void initializeConsole() {
|
||||||
|
@ -163,5 +163,6 @@ void initializeConsole() {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
addConsoleAction("fatal", myfatal);
|
addConsoleAction("fatal", myfatal);
|
||||||
|
addConsoleAction("error", myerror);
|
||||||
addConsoleAction("threadsinfo", cmd_threads);
|
addConsoleAction("threadsinfo", cmd_threads);
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,10 +38,8 @@
|
||||||
#include "io_pins.h"
|
#include "io_pins.h"
|
||||||
#include "mmc_card.h"
|
#include "mmc_card.h"
|
||||||
#include "console_io.h"
|
#include "console_io.h"
|
||||||
|
#include "malfunction_central.h"
|
||||||
#define PRINT_FIRMWARE_ONCE TRUE
|
#include "speed_density.h"
|
||||||
|
|
||||||
static bool_t firmwareErrorReported = FALSE;
|
|
||||||
|
|
||||||
#include "advance_map.h"
|
#include "advance_map.h"
|
||||||
#if EFI_TUNER_STUDIO
|
#if EFI_TUNER_STUDIO
|
||||||
|
@ -57,6 +55,7 @@ static bool_t firmwareErrorReported = FALSE;
|
||||||
#include "engine_configuration.h"
|
#include "engine_configuration.h"
|
||||||
#include "rfiutil.h"
|
#include "rfiutil.h"
|
||||||
#include "svnversion.h"
|
#include "svnversion.h"
|
||||||
|
#include "engine.h"
|
||||||
|
|
||||||
#if EFI_PROD_CODE
|
#if EFI_PROD_CODE
|
||||||
// todo: move this logic to algo folder!
|
// todo: move this logic to algo folder!
|
||||||
|
@ -65,6 +64,8 @@ static bool_t firmwareErrorReported = FALSE;
|
||||||
#include "rusefi.h"
|
#include "rusefi.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
extern Engine engine;
|
||||||
|
|
||||||
// this 'true' value is needed for simulator
|
// this 'true' value is needed for simulator
|
||||||
static volatile int fullLog = TRUE;
|
static volatile int fullLog = TRUE;
|
||||||
int warningEnabled = TRUE;
|
int warningEnabled = TRUE;
|
||||||
|
@ -72,6 +73,7 @@ int warningEnabled = TRUE;
|
||||||
|
|
||||||
extern engine_configuration_s * engineConfiguration;
|
extern engine_configuration_s * engineConfiguration;
|
||||||
extern engine_configuration2_s * engineConfiguration2;
|
extern engine_configuration2_s * engineConfiguration2;
|
||||||
|
extern board_configuration_s *boardConfiguration;
|
||||||
#define FULL_LOGGING_KEY "fl"
|
#define FULL_LOGGING_KEY "fl"
|
||||||
|
|
||||||
#if EFI_PROD_CODE || EFI_SIMULATOR
|
#if EFI_PROD_CODE || EFI_SIMULATOR
|
||||||
|
@ -97,7 +99,7 @@ static void reportSensorF(const char *caption, float value, int precision) {
|
||||||
#endif /* EFI_FILE_LOGGING */
|
#endif /* EFI_FILE_LOGGING */
|
||||||
}
|
}
|
||||||
|
|
||||||
static void reportSensorI(char *caption, int value) {
|
static void reportSensorI(const char *caption, int value) {
|
||||||
#if EFI_PROD_CODE || EFI_SIMULATOR
|
#if EFI_PROD_CODE || EFI_SIMULATOR
|
||||||
debugInt(&logger, caption, value);
|
debugInt(&logger, caption, value);
|
||||||
#endif /* EFI_PROD_CODE || EFI_SIMULATOR */
|
#endif /* EFI_PROD_CODE || EFI_SIMULATOR */
|
||||||
|
@ -154,6 +156,7 @@ void printSensors(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void printState(int currentCkpEventCounter) {
|
void printState(int currentCkpEventCounter) {
|
||||||
|
#if EFI_SHAFT_POSITION_INPUT
|
||||||
printSensors();
|
printSensors();
|
||||||
|
|
||||||
int rpm = getRpm();
|
int rpm = getRpm();
|
||||||
|
@ -177,6 +180,7 @@ void printState(int currentCkpEventCounter) {
|
||||||
// float fuel = getDefaultFuel(rpm, map);
|
// float fuel = getDefaultFuel(rpm, map);
|
||||||
// debugFloat(&logger, "d_fuel", fuel, 2);
|
// debugFloat(&logger, "d_fuel", fuel, 2);
|
||||||
|
|
||||||
|
#endif /* EFI_SHAFT_POSITION_INPUT */
|
||||||
}
|
}
|
||||||
|
|
||||||
#define INITIAL_FULL_LOG TRUE
|
#define INITIAL_FULL_LOG TRUE
|
||||||
|
@ -201,32 +205,31 @@ static void printStatus(void) {
|
||||||
// return getTCharge(getCurrentRpm(), tps, cltK, iatK);
|
// return getTCharge(getCurrentRpm(), tps, cltK, iatK);
|
||||||
//}
|
//}
|
||||||
|
|
||||||
#if EFI_CUSTOM_PANIC_METHOD
|
//#if EFI_CUSTOM_PANIC_METHOD
|
||||||
extern char *dbg_panic_file;
|
//extern char *dbg_panic_file;
|
||||||
extern int dbg_panic_line;
|
//extern int dbg_panic_line;
|
||||||
#endif
|
//#endif
|
||||||
|
|
||||||
bool_t hasFatalError(void) {
|
//static void checkIfShouldHalt(void) {
|
||||||
return dbg_panic_msg != NULL;
|
//#if CH_DBG_ENABLED
|
||||||
}
|
// if (hasFatalError()) {
|
||||||
|
// /**
|
||||||
static void checkIfShouldHalt(void) {
|
// * low-level function is used here to reduce stack usage
|
||||||
#if CH_DBG_ENABLED
|
// */
|
||||||
if (hasFatalError()) {
|
// palWritePad(LED_ERROR_PORT, LED_ERROR_PIN, 1);
|
||||||
setOutputPinValue(LED_ERROR, 1);
|
//#if EFI_CUSTOM_PANIC_METHOD
|
||||||
#if EFI_CUSTOM_PANIC_METHOD
|
// print("my FATAL [%s] at %s:%d\r\n", dbg_panic_msg, dbg_panic_file, dbg_panic_line);
|
||||||
print("my FATAL [%s] at %s:%d\r\n", dbg_panic_msg, dbg_panic_file, dbg_panic_line);
|
//#else
|
||||||
#else
|
// print("my FATAL [%s] at %s:%d\r\n", dbg_panic_msg);
|
||||||
print("my FATAL [%s] at %s:%d\r\n", dbg_panic_msg);
|
//#endif
|
||||||
#endif
|
// chThdSleepSeconds(1);
|
||||||
chThdSleepSeconds(1);
|
// // todo: figure out how we halt exactly
|
||||||
// todo: figure out how we halt exactly
|
// while (TRUE) {
|
||||||
while (TRUE) {
|
// }
|
||||||
}
|
// chSysHalt();
|
||||||
chSysHalt();
|
// }
|
||||||
}
|
//#endif
|
||||||
#endif
|
//}
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Time when the firmware version was reported last time, in seconds
|
* Time when the firmware version was reported last time, in seconds
|
||||||
|
@ -253,14 +256,14 @@ extern char errorMessageBuffer[200];
|
||||||
void updateDevConsoleState(void) {
|
void updateDevConsoleState(void) {
|
||||||
if (!isConsoleReady())
|
if (!isConsoleReady())
|
||||||
return;
|
return;
|
||||||
checkIfShouldHalt();
|
// looks like this is not needed anymore
|
||||||
|
// checkIfShouldHalt();
|
||||||
printPending();
|
printPending();
|
||||||
|
|
||||||
if (hasFirmwareError()) {
|
if (hasFirmwareError()) {
|
||||||
if (!firmwareErrorReported || !PRINT_FIRMWARE_ONCE)
|
printMsg(&logger, "firmware error: %s", errorMessageBuffer);
|
||||||
printMsg(&logger, "firmware error: %s", errorMessageBuffer);
|
|
||||||
firmwareErrorReported = TRUE;
|
|
||||||
warningEnabled = FALSE;
|
warningEnabled = FALSE;
|
||||||
|
chThdSleepMilliseconds(200);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -324,7 +327,7 @@ void updateHD44780lcd(void) {
|
||||||
lcd_HD44780_print_char('R');
|
lcd_HD44780_print_char('R');
|
||||||
lcd_HD44780_set_position(0, 10);
|
lcd_HD44780_set_position(0, 10);
|
||||||
|
|
||||||
char * ptr = itoa10((uint8_t*) buffer, getRpm());
|
char * ptr = itoa10(buffer, getRpm());
|
||||||
ptr[0] = 0;
|
ptr[0] = 0;
|
||||||
int len = ptr - buffer;
|
int len = ptr - buffer;
|
||||||
for (int i = 0; i < 6 - len; i++)
|
for (int i = 0; i < 6 - len; i++)
|
||||||
|
@ -346,7 +349,7 @@ void updateHD44780lcd(void) {
|
||||||
}
|
}
|
||||||
#endif /* EFI_PROD_CODE */
|
#endif /* EFI_PROD_CODE */
|
||||||
|
|
||||||
static WORKING_AREA(lcdThreadStack, UTILITY_THREAD_STACK_SIZE);
|
static THD_WORKING_AREA(lcdThreadStack, UTILITY_THREAD_STACK_SIZE);
|
||||||
|
|
||||||
static void lcdThread(void *arg) {
|
static void lcdThread(void *arg) {
|
||||||
chRegSetThreadName("lcd");
|
chRegSetThreadName("lcd");
|
||||||
|
@ -354,20 +357,49 @@ static void lcdThread(void *arg) {
|
||||||
#if EFI_HD44780_LCD
|
#if EFI_HD44780_LCD
|
||||||
updateHD44780lcd();
|
updateHD44780lcd();
|
||||||
#endif
|
#endif
|
||||||
chThdSleepMilliseconds(50);
|
chThdSleepMilliseconds(boardConfiguration->lcdThreadPeriod);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static WORKING_AREA(tsThreadStack, UTILITY_THREAD_STACK_SIZE);
|
static THD_WORKING_AREA(tsThreadStack, UTILITY_THREAD_STACK_SIZE);
|
||||||
|
|
||||||
|
#if EFI_TUNER_STUDIO
|
||||||
|
extern TunerStudioOutputChannels tsOutputChannels;
|
||||||
|
|
||||||
|
void updateTunerStudioState(TunerStudioOutputChannels *tsOutputChannels) {
|
||||||
|
#if EFI_SHAFT_POSITION_INPUT
|
||||||
|
int rpm = getRpm();
|
||||||
|
#else
|
||||||
|
int rpm = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
float tps = getTPS();
|
||||||
|
float coolant = getCoolantTemperature();
|
||||||
|
float intake = getIntakeAirTemperature();
|
||||||
|
|
||||||
|
tsOutputChannels->rpm = rpm;
|
||||||
|
tsOutputChannels->coolant_temperature = coolant;
|
||||||
|
tsOutputChannels->intake_air_temperature = intake;
|
||||||
|
tsOutputChannels->throttle_positon = tps;
|
||||||
|
tsOutputChannels->mass_air_flow = getMaf();
|
||||||
|
tsOutputChannels->air_fuel_ratio = getAfr();
|
||||||
|
tsOutputChannels->v_batt = getVBatt();
|
||||||
|
tsOutputChannels->tpsADC = getTPS10bitAdc();
|
||||||
|
tsOutputChannels->atmospherePressure = getBaroPressure();
|
||||||
|
tsOutputChannels->manifold_air_pressure = getMap();
|
||||||
|
tsOutputChannels->checkEngine = hasErrorCodes();
|
||||||
|
tsOutputChannels->tCharge = getTCharge(rpm, tps, coolant, intake);
|
||||||
|
}
|
||||||
|
#endif /* EFI_TUNER_STUDIO */
|
||||||
|
|
||||||
static void tsStatusThread(void *arg) {
|
static void tsStatusThread(void *arg) {
|
||||||
chRegSetThreadName("tuner s");
|
chRegSetThreadName("tuner s");
|
||||||
while (true) {
|
while (true) {
|
||||||
#if EFI_TUNER_STUDIO
|
#if EFI_TUNER_STUDIO
|
||||||
// sensor state for EFI Analytics Tuner Studio
|
// sensor state for EFI Analytics Tuner Studio
|
||||||
updateTunerStudioState();
|
updateTunerStudioState(&tsOutputChannels);
|
||||||
#endif /* EFI_TUNER_STUDIO */
|
#endif /* EFI_TUNER_STUDIO */
|
||||||
chThdSleepMilliseconds(50);
|
chThdSleepMilliseconds(boardConfiguration->tunerStudioThreadPeriod);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -37,13 +37,37 @@
|
||||||
#include "tunerstudio_configuration.h"
|
#include "tunerstudio_configuration.h"
|
||||||
#include "malfunction_central.h"
|
#include "malfunction_central.h"
|
||||||
#include "wave_math.h"
|
#include "wave_math.h"
|
||||||
|
#include "console_io.h"
|
||||||
|
#include "crc.h"
|
||||||
|
|
||||||
#if EFI_TUNER_STUDIO
|
#if EFI_TUNER_STUDIO
|
||||||
|
|
||||||
|
#define MAX_PAGE_ID 5
|
||||||
|
#define PAGE_0_SIZE 1356
|
||||||
|
|
||||||
|
// in MS, that's 10 seconds
|
||||||
|
#define TS_READ_TIMEOUT 10000
|
||||||
|
|
||||||
|
#define TS_SERIAL_UART_DEVICE &SD3
|
||||||
|
//#define TS_SERIAL_SPEED 115200
|
||||||
|
#define TS_SERIAL_SPEED 38400
|
||||||
|
|
||||||
|
#define PROTOCOL "001"
|
||||||
|
|
||||||
|
extern SerialUSBDriver SDU1;
|
||||||
|
|
||||||
|
BaseChannel * getTsSerialDevice(void) {
|
||||||
|
if (isSerialOverUart()) {
|
||||||
|
// if console uses UART then TS uses USB
|
||||||
|
return (BaseChannel *) &SDU1;
|
||||||
|
} else {
|
||||||
|
return (BaseChannel *) TS_SERIAL_UART_DEVICE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static Logging logger;
|
static Logging logger;
|
||||||
|
|
||||||
extern engine_configuration_s *engineConfiguration;
|
extern engine_configuration_s *engineConfiguration;
|
||||||
extern board_configuration_s *boardConfiguration;
|
|
||||||
extern persistent_config_s configWorkingCopy;
|
extern persistent_config_s configWorkingCopy;
|
||||||
extern persistent_config_container_s persistentState;
|
extern persistent_config_container_s persistentState;
|
||||||
|
|
||||||
|
@ -52,47 +76,49 @@ extern SerialUSBDriver SDU1;
|
||||||
|
|
||||||
static efitimems_t previousWriteReportMs = 0;
|
static efitimems_t previousWriteReportMs = 0;
|
||||||
|
|
||||||
#if EFI_TUNER_STUDIO_OVER_USB
|
static int ts_serail_ready(void) {
|
||||||
#define ts_serail_ready() is_usb_serial_ready()
|
if (isSerialOverUart()) {
|
||||||
#else
|
// TS uses USB when console uses serial
|
||||||
#define ts_serail_ready() TRUE
|
return is_usb_serial_ready();
|
||||||
static SerialConfig tsSerialConfig = { TS_SERIAL_SPEED, 0, USART_CR2_STOP1_BITS | USART_CR2_LINEN, 0 };
|
} else {
|
||||||
#endif /* EFI_TUNER_STUDIO_OVER_USB */
|
// TS uses serial when console uses USB
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static WORKING_AREA(TS_WORKING_AREA, UTILITY_THREAD_STACK_SIZE);
|
static SerialConfig tsSerialConfig = { TS_SERIAL_SPEED, 0, USART_CR2_STOP1_BITS | USART_CR2_LINEN, 0 };
|
||||||
|
|
||||||
|
static THD_WORKING_AREA(TS_WORKING_AREA, UTILITY_THREAD_STACK_SIZE);
|
||||||
|
|
||||||
static int tsCounter = 0;
|
static int tsCounter = 0;
|
||||||
static int writeCounter = 0;
|
|
||||||
|
|
||||||
static short pageId;
|
//static TunerStudioWriteValueRequest writeValueRequest;
|
||||||
|
//static TunerStudioWriteChunkRequest writeChunkRequest;
|
||||||
static TunerStudioWriteRequest writeRequest;
|
|
||||||
|
|
||||||
extern TunerStudioOutputChannels tsOutputChannels;
|
extern TunerStudioOutputChannels tsOutputChannels;
|
||||||
|
|
||||||
//char *constantsAsPtr = (char *) &configWorkingCopy;
|
|
||||||
|
|
||||||
extern TunerStudioState tsState;
|
extern TunerStudioState tsState;
|
||||||
|
|
||||||
static void printStats(void) {
|
static void printStats(void) {
|
||||||
#if EFI_TUNER_STUDIO_OVER_USB
|
if (!isSerialOverUart()) {
|
||||||
#else
|
scheduleMsg(&logger, "TS RX on %s%d", portname(TS_SERIAL_RX_PORT), TS_SERIAL_RX_PIN);
|
||||||
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);
|
||||||
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 total/error counter=%d/%d", tsCounter, tsState.errorCounter);
|
||||||
scheduleMsg(&logger, "TunerStudio H counter=%d", tsState.queryCommandCounter);
|
scheduleMsg(&logger, "TunerStudio H counter=%d", tsState.queryCommandCounter);
|
||||||
scheduleMsg(&logger, "TunerStudio O counter=%d size=%d", tsState.outputChannelsCommandCounter,
|
scheduleMsg(&logger, "TunerStudio O counter=%d size=%d", tsState.outputChannelsCommandCounter,
|
||||||
sizeof(tsOutputChannels));
|
sizeof(tsOutputChannels));
|
||||||
scheduleMsg(&logger, "TunerStudio C counter=%d", tsState.readPageCommandsCounter);
|
scheduleMsg(&logger, "TunerStudio P counter=%d", tsState.readPageCommandsCounter);
|
||||||
scheduleMsg(&logger, "TunerStudio B counter=%d", tsState.burnCommandCounter);
|
scheduleMsg(&logger, "TunerStudio B counter=%d", tsState.burnCommandCounter);
|
||||||
scheduleMsg(&logger, "TunerStudio W counter=%d", writeCounter);
|
scheduleMsg(&logger, "TunerStudio W counter=%d", tsState.writeValueCommandCounter);
|
||||||
|
scheduleMsg(&logger, "TunerStudio C counter=%d", tsState.writeChunkCommandCounter);
|
||||||
|
scheduleMsg(&logger, "TunerStudio P counter=%d current page %d", tsState.pageCommandCounter, tsState.currentPageId);
|
||||||
scheduleMsg(&logger, "page 0 size=%d", getTunerStudioPageSize(0));
|
scheduleMsg(&logger, "page 0 size=%d", getTunerStudioPageSize(0));
|
||||||
scheduleMsg(&logger, "page 1 size=%d", getTunerStudioPageSize(1));
|
scheduleMsg(&logger, "page 1 size=%d", getTunerStudioPageSize(1));
|
||||||
}
|
}
|
||||||
|
|
||||||
void tunerStudioWriteData(const uint8_t * buffer, int size) {
|
void tunerStudioWriteData(const uint8_t * buffer, int size) {
|
||||||
chSequentialStreamWrite(TS_SERIAL_DEVICE, buffer, size);
|
chSequentialStreamWrite(getTsSerialDevice(), buffer, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
void tunerStudioDebug(char *msg) {
|
void tunerStudioDebug(char *msg) {
|
||||||
|
@ -108,6 +134,11 @@ char *getWorkingPageAddr(int pageIndex) {
|
||||||
return (char*) &configWorkingCopy.engineConfiguration;
|
return (char*) &configWorkingCopy.engineConfiguration;
|
||||||
case 1:
|
case 1:
|
||||||
return (char*) &configWorkingCopy.boardConfiguration;
|
return (char*) &configWorkingCopy.boardConfiguration;
|
||||||
|
case 2: // fuelTable
|
||||||
|
case 3: // ignitionTable
|
||||||
|
case 4: // veTable
|
||||||
|
case 5: // afrTable
|
||||||
|
return (char*) &configWorkingCopy.engineConfiguration + PAGE_0_SIZE + (pageIndex - 2) * 1024;
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -115,86 +146,143 @@ char *getWorkingPageAddr(int pageIndex) {
|
||||||
int getTunerStudioPageSize(int pageIndex) {
|
int getTunerStudioPageSize(int pageIndex) {
|
||||||
switch (pageIndex) {
|
switch (pageIndex) {
|
||||||
case 0:
|
case 0:
|
||||||
return sizeof(configWorkingCopy.engineConfiguration);
|
return PAGE_0_SIZE;
|
||||||
case 1:
|
case 1:
|
||||||
return sizeof(configWorkingCopy.boardConfiguration);
|
return sizeof(configWorkingCopy.boardConfiguration);
|
||||||
|
case 2:
|
||||||
|
case 3:
|
||||||
|
case 4:
|
||||||
|
return 1024;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void handlePageSelectCommand(uint16_t pageId) {
|
||||||
|
tsState.pageCommandCounter++;
|
||||||
|
|
||||||
|
tsState.currentPageId = pageId;
|
||||||
|
scheduleMsg(&logger, "page %d selected", tsState.currentPageId);
|
||||||
|
tunerStudioWriteCrcPacket(TS_RESPONSE_OK, NULL, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This command is needed to make the whole transfer a bit faster
|
||||||
|
* @note See also handleWriteValueCommand
|
||||||
|
*/
|
||||||
|
void handleWriteChunkCommand(short offset, short count, void *content) {
|
||||||
|
tsState.writeChunkCommandCounter++;
|
||||||
|
|
||||||
|
scheduleMsg(&logger, "receiving page %d chunk offset %d size %d", tsState.currentPageId, offset, count);
|
||||||
|
|
||||||
|
if (offset > getTunerStudioPageSize(tsState.currentPageId)) {
|
||||||
|
scheduleMsg(&logger, "ERROR offset %d", offset);
|
||||||
|
// out of range
|
||||||
|
tsState.errorCounter++;
|
||||||
|
offset = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (count > getTunerStudioPageSize(tsState.currentPageId)) {
|
||||||
|
scheduleMsg(&logger, "ERROR count %d", count);
|
||||||
|
// out of range
|
||||||
|
tsState.errorCounter++;
|
||||||
|
count = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t * addr = (uint8_t *) (getWorkingPageAddr(tsState.currentPageId) + offset);
|
||||||
|
// memcpy(addr, content, count);
|
||||||
|
|
||||||
|
tunerStudioWriteCrcPacket(TS_RESPONSE_OK, NULL, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 'Write' command receives a single value at a given offset
|
* 'Write' command receives a single value at a given offset
|
||||||
|
* @note Writing values one by one is pretty slow
|
||||||
*/
|
*/
|
||||||
void handleValueWriteCommand(void) {
|
void handleWriteValueCommand(uint16_t page, uint16_t offset, uint8_t value) {
|
||||||
writeCounter++;
|
tsState.writeValueCommandCounter++;
|
||||||
|
|
||||||
//tunerStudioDebug("got W (Write)"); // we can get a lot of these
|
tsState.currentPageId = page;
|
||||||
|
|
||||||
|
//tunerStudioDebug("got W (Write)"); // we can get a lot of these
|
||||||
|
|
||||||
int recieved = chSequentialStreamRead(TS_SERIAL_DEVICE, (uint8_t *)&pageId, 2);
|
|
||||||
if (recieved != 2) {
|
|
||||||
tsState.errorCounter++;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
#if EFI_TUNER_STUDIO_VERBOSE
|
#if EFI_TUNER_STUDIO_VERBOSE
|
||||||
// scheduleMsg(&logger, "Page number %d\r\n", pageId); // we can get a lot of these
|
// scheduleMsg(&logger, "Page number %d\r\n", pageId); // we can get a lot of these
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int size = sizeof(TunerStudioWriteRequest);
|
int size = sizeof(TunerStudioWriteValueRequest);
|
||||||
// scheduleMsg(&logger, "Reading %d\r\n", size);
|
// scheduleMsg(&logger, "Reading %d\r\n", size);
|
||||||
|
|
||||||
recieved = chSequentialStreamRead(TS_SERIAL_DEVICE, (uint8_t *)&writeRequest, size);
|
if (offset > getTunerStudioPageSize(tsState.currentPageId)) {
|
||||||
// scheduleMsg(&logger, "got %d", recieved);
|
scheduleMsg(&logger, "ERROR offset %d", offset);
|
||||||
|
// out of range
|
||||||
// unsigned char offset = writeBuffer[0];
|
tsState.errorCounter++;
|
||||||
// unsigned char value = writeBuffer[1];
|
offset = 0;
|
||||||
//
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
efitimems_t nowMs = currentTimeMillis();
|
efitimems_t nowMs = currentTimeMillis();
|
||||||
if (nowMs - previousWriteReportMs > 5) {
|
if (nowMs - previousWriteReportMs > 5) {
|
||||||
previousWriteReportMs = nowMs;
|
previousWriteReportMs = nowMs;
|
||||||
// scheduleMsg(&logger, "page %d offset %d: value=%d", pageId, writeRequest.offset, writeRequest.value);
|
scheduleMsg(&logger, "page %d offset %d: value=%d", tsState.currentPageId, offset, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
getWorkingPageAddr(pageId)[writeRequest.offset] = writeRequest.value;
|
getWorkingPageAddr(tsState.currentPageId)[offset] = value;
|
||||||
|
|
||||||
// scheduleMsg(&logger, "va=%d", configWorkingCopy.boardConfiguration.idleValvePin);
|
// scheduleMsg(&logger, "va=%d", configWorkingCopy.boardConfiguration.idleValvePin);
|
||||||
}
|
}
|
||||||
|
|
||||||
void handlePageReadCommand(void) {
|
static void sendErrorCode(void) {
|
||||||
|
tunerStudioWriteCrcPacket(TS_RESPONSE_CRC_FAILURE, NULL, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void handlePageReadCommand(uint16_t pageId, uint16_t offset, uint16_t count) {
|
||||||
tsState.readPageCommandsCounter++;
|
tsState.readPageCommandsCounter++;
|
||||||
tunerStudioDebug("got C (Constants)");
|
tunerStudioDebug("got R (Read page)");
|
||||||
int recieved = chSequentialStreamRead(TS_SERIAL_DEVICE, (uint8_t *)&pageId, 2);
|
tsState.currentPageId = pageId;
|
||||||
if (recieved != 2) {
|
|
||||||
|
#if EFI_TUNER_STUDIO_VERBOSE
|
||||||
|
scheduleMsg(&logger, "Page requested: page %d offset=%d count=%d", tsState.currentPageId, offset, count);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (tsState.currentPageId > MAX_PAGE_ID) {
|
||||||
|
scheduleMsg(&logger, "invalid Page number %x", tsState.currentPageId);
|
||||||
|
|
||||||
|
// something is not right here
|
||||||
|
tsState.currentPageId = 0;
|
||||||
tsState.errorCounter++;
|
tsState.errorCounter++;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int size = getTunerStudioPageSize(tsState.currentPageId);
|
||||||
|
|
||||||
|
if (size < offset + count) {
|
||||||
|
scheduleMsg(&logger, "invalid offset/count %d/%d", offset, count);
|
||||||
|
sendErrorCode();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const uint8_t *addr = (const uint8_t *) (getWorkingPageAddr(tsState.currentPageId) + offset);
|
||||||
|
tunerStudioWriteCrcPacket(TS_RESPONSE_OK, addr, count);
|
||||||
#if EFI_TUNER_STUDIO_VERBOSE
|
#if EFI_TUNER_STUDIO_VERBOSE
|
||||||
scheduleMsg(&logger, "Page number %d", pageId);
|
scheduleMsg(&logger, "Sending %d done", size);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
tunerStudioWriteData((const uint8_t *) getWorkingPageAddr(pageId), getTunerStudioPageSize(pageId));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 'Burn' command is a command to commit the changes
|
* 'Burn' command is a command to commit the changes
|
||||||
*/
|
*/
|
||||||
void handleBurnCommand(void) {
|
void handleBurnCommand(uint16_t page) {
|
||||||
tsState.burnCommandCounter++;
|
tsState.burnCommandCounter++;
|
||||||
|
|
||||||
tunerStudioDebug("got B (Burn)");
|
tunerStudioDebug("got B (Burn)");
|
||||||
|
|
||||||
int recieved = chSequentialStreamRead(TS_SERIAL_DEVICE, (uint8_t *)&pageId, 2);
|
tsState.currentPageId = page;
|
||||||
if (recieved != 2) {
|
|
||||||
tsState.errorCounter++;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
#if EFI_TUNER_STUDIO_VERBOSE
|
#if EFI_TUNER_STUDIO_VERBOSE
|
||||||
scheduleMsg(&logger, "Page number %d\r\n", pageId);
|
scheduleMsg(&logger, "Page number %d\r\n", tsState.currentPageId);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// todo: how about some multi-threading?
|
// todo: how about some multi-threading?
|
||||||
memcpy(&persistentState.persistentConfiguration, &configWorkingCopy, sizeof(persistent_config_s));
|
memcpy(&persistentState.persistentConfiguration, &configWorkingCopy, sizeof(persistent_config_s));
|
||||||
|
|
||||||
scheduleMsg(&logger, "va1=%d", configWorkingCopy.boardConfiguration.idleValvePin);
|
scheduleMsg(&logger, "va1=%d", configWorkingCopy.boardConfiguration.idleValvePin);
|
||||||
|
@ -202,8 +290,15 @@ void handleBurnCommand(void) {
|
||||||
|
|
||||||
writeToFlash();
|
writeToFlash();
|
||||||
incrementGlobalConfigurationVersion();
|
incrementGlobalConfigurationVersion();
|
||||||
|
tunerStudioWriteCrcPacket(TS_RESPONSE_BURN_OK, NULL, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static uint8_t firstByte;
|
||||||
|
static uint8_t secondByte;
|
||||||
|
|
||||||
|
// todo: reduce TS page size so that we can reduce buffer size
|
||||||
|
static char crcIoBuffer[4096];
|
||||||
|
|
||||||
static msg_t tsThreadEntryPoint(void *arg) {
|
static msg_t tsThreadEntryPoint(void *arg) {
|
||||||
(void) arg;
|
(void) arg;
|
||||||
chRegSetThreadName("tunerstudio thread");
|
chRegSetThreadName("tunerstudio thread");
|
||||||
|
@ -216,41 +311,128 @@ static msg_t tsThreadEntryPoint(void *arg) {
|
||||||
wasReady = FALSE;
|
wasReady = FALSE;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!wasReady) {
|
if (!wasReady) {
|
||||||
wasReady = TRUE;
|
wasReady = TRUE;
|
||||||
// scheduleSimpleMsg(&logger, "ts channel is now ready ", hTimeNow());
|
// scheduleSimpleMsg(&logger, "ts channel is now ready ", hTimeNow());
|
||||||
}
|
}
|
||||||
|
|
||||||
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++;
|
tsCounter++;
|
||||||
|
|
||||||
|
int recieved = chSequentialStreamRead(getTsSerialDevice(), &firstByte, 1);
|
||||||
|
if (recieved != 1) {
|
||||||
|
tsState.errorCounter++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// scheduleMsg(&logger, "Got first=%x=[%c]", firstByte, firstByte);
|
||||||
|
if (firstByte == TS_HELLO_COMMAND) {
|
||||||
|
scheduleMsg(&logger, "Got naked Query command");
|
||||||
|
handleQueryCommand(FALSE);
|
||||||
|
continue;
|
||||||
|
} else if (firstByte == 't' || firstByte == 'T') {
|
||||||
|
handleTestCommand();
|
||||||
|
continue;
|
||||||
|
} else if (firstByte == TS_READ_COMMAND) {
|
||||||
|
scheduleMsg(&logger, "Got naked READ PAGE???");
|
||||||
|
continue;
|
||||||
|
} else if (firstByte == TS_OUTPUT_COMMAND) {
|
||||||
|
scheduleMsg(&logger, "Got naked Channels???");
|
||||||
|
continue;
|
||||||
|
} else if (firstByte == 'F') {
|
||||||
|
tunerStudioDebug("not ignoring F");
|
||||||
|
tunerStudioWriteData((const uint8_t *) PROTOCOL, strlen(PROTOCOL));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
recieved = chSequentialStreamRead(getTsSerialDevice(), &secondByte, 1);
|
||||||
|
if (recieved != 1) {
|
||||||
|
tsState.errorCounter++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// scheduleMsg(&logger, "Got secondByte=%x=[%c]", secondByte, secondByte);
|
||||||
|
|
||||||
|
int incomingPacketSize = firstByte * 256 + secondByte;
|
||||||
|
|
||||||
|
if (incomingPacketSize == 0 || incomingPacketSize > sizeof(crcIoBuffer)) {
|
||||||
|
scheduleMsg(&logger, "TunerStudio: invalid size: %d", incomingPacketSize);
|
||||||
|
tsState.errorCounter++;
|
||||||
|
sendErrorCode();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
recieved = chnReadTimeout(getTsSerialDevice(), crcIoBuffer, 1, MS2ST(TS_READ_TIMEOUT));
|
||||||
|
if (recieved != 1) {
|
||||||
|
scheduleMsg(&logger, "did not receive command");
|
||||||
|
tsState.errorCounter++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
char command = crcIoBuffer[0];
|
||||||
|
if (command != TS_HELLO_COMMAND && command != TS_READ_COMMAND && command != TS_OUTPUT_COMMAND
|
||||||
|
&& command != TS_PAGE_COMMAND && command != TS_BURN_COMMAND && command != TS_SINGLE_WRITE_COMMAND
|
||||||
|
&& command != TS_CHUNK_WRITE_COMMAND) {
|
||||||
|
scheduleMsg(&logger, "unexpected command %x", command);
|
||||||
|
sendErrorCode();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// scheduleMsg(&logger, "TunerStudio: reading %d+4 bytes(s)", incomingPacketSize);
|
||||||
|
|
||||||
|
recieved = chnReadTimeout(getTsSerialDevice(), (void * ) (crcIoBuffer + 1), incomingPacketSize + 4 - 1,
|
||||||
|
MS2ST(TS_READ_TIMEOUT));
|
||||||
|
if (recieved != incomingPacketSize + 4 - 1) {
|
||||||
|
scheduleMsg(&logger, "got ONLY %d", recieved);
|
||||||
|
tsState.errorCounter++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t expectedCrc = *(uint32_t*) (crcIoBuffer + incomingPacketSize);
|
||||||
|
|
||||||
|
expectedCrc = SWAP_UINT32(expectedCrc);
|
||||||
|
|
||||||
|
int actualCrc = crc32(crcIoBuffer, incomingPacketSize);
|
||||||
|
if (actualCrc != expectedCrc) {
|
||||||
|
scheduleMsg(&logger, "TunerStudio: CRC %x %x %x %x", crcIoBuffer[incomingPacketSize + 0],
|
||||||
|
crcIoBuffer[incomingPacketSize + 1], crcIoBuffer[incomingPacketSize + 2],
|
||||||
|
crcIoBuffer[incomingPacketSize + 3]);
|
||||||
|
|
||||||
|
scheduleMsg(&logger, "TunerStudio: command %c actual CRC %x/expected %x", crcIoBuffer[0], actualCrc,
|
||||||
|
expectedCrc);
|
||||||
|
tsState.errorCounter++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// scheduleMsg(&logger, "TunerStudio: P00-07 %x %x %x %x %x %x %x %x", crcIoBuffer[0], crcIoBuffer[1],
|
||||||
|
// crcIoBuffer[2], crcIoBuffer[3], crcIoBuffer[4], crcIoBuffer[5], crcIoBuffer[6], crcIoBuffer[7]);
|
||||||
|
|
||||||
|
int success = tunerStudioHandleCommand(crcIoBuffer, incomingPacketSize);
|
||||||
|
if (!success)
|
||||||
|
print("got unexpected TunerStudio command %x:%c\r\n", command, command);
|
||||||
|
|
||||||
}
|
}
|
||||||
#if defined __GNUC__
|
#if defined __GNUC__
|
||||||
return 0;
|
return 0;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
extern engine_configuration_s *engineConfiguration;
|
|
||||||
|
|
||||||
void syncTunerStudioCopy(void) {
|
void syncTunerStudioCopy(void) {
|
||||||
memcpy(&configWorkingCopy, &persistentState.persistentConfiguration, sizeof(persistent_config_s));
|
memcpy(&configWorkingCopy, &persistentState.persistentConfiguration, sizeof(persistent_config_s));
|
||||||
}
|
}
|
||||||
|
|
||||||
void startTunerStudioConnectivity(void) {
|
void startTunerStudioConnectivity(void) {
|
||||||
initLogging(&logger, "tuner studio");
|
initLogging(&logger, "tuner studio");
|
||||||
#if EFI_TUNER_STUDIO_OVER_USB
|
memset(&tsState, 0, sizeof(tsState));
|
||||||
print("TunerStudio over USB serial");
|
if (isSerialOverUart()) {
|
||||||
usb_serial_start();
|
print("TunerStudio over USB serial");
|
||||||
#else
|
usb_serial_start();
|
||||||
print("TunerStudio over USART");
|
} else {
|
||||||
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);
|
print("TunerStudio over USART");
|
||||||
#endif
|
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_UART_DEVICE, &tsSerialConfig);
|
||||||
|
}
|
||||||
|
|
||||||
syncTunerStudioCopy();
|
syncTunerStudioCopy();
|
||||||
|
|
||||||
|
@ -259,18 +441,22 @@ void startTunerStudioConnectivity(void) {
|
||||||
chThdCreateStatic(TS_WORKING_AREA, sizeof(TS_WORKING_AREA), NORMALPRIO, tsThreadEntryPoint, NULL);
|
chThdCreateStatic(TS_WORKING_AREA, sizeof(TS_WORKING_AREA), NORMALPRIO, tsThreadEntryPoint, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void updateTunerStudioState() {
|
/**
|
||||||
tsOutputChannels.rpm = getRpm();
|
* Adds size to the beginning of a packet and a crc32 at the end. Then send the packet.
|
||||||
tsOutputChannels.coolant_temperature = getCoolantTemperature();
|
*/
|
||||||
tsOutputChannels.intake_air_temperature = getIntakeAirTemperature();
|
void tunerStudioWriteCrcPacket(const uint8_t command, const void *buf, const uint16_t size) {
|
||||||
tsOutputChannels.throttle_positon = getTPS();
|
// todo: max size validation
|
||||||
tsOutputChannels.mass_air_flow = getMaf();
|
*(uint16_t *) crcIoBuffer = SWAP_UINT16(size + 1); // packet size including command
|
||||||
tsOutputChannels.air_fuel_ratio = getAfr();
|
*(uint8_t *) (crcIoBuffer + 2) = command;
|
||||||
tsOutputChannels.v_batt = getVBatt();
|
if (size != 0)
|
||||||
tsOutputChannels.tpsADC = getTPS10bitAdc();
|
memcpy(crcIoBuffer + 3, buf, size);
|
||||||
tsOutputChannels.atmospherePressure = getBaroPressure();
|
// CRC on whole packet
|
||||||
tsOutputChannels.manifold_air_pressure = getMap();
|
uint32_t crc = crc32((void *) (crcIoBuffer + 2), (uint32_t) (size + 1));
|
||||||
tsOutputChannels.checkEngine = hasErrorCodes();
|
*(uint32_t *) (crcIoBuffer + 2 + 1 + size) = SWAP_UINT32(crc);
|
||||||
|
|
||||||
|
// scheduleMsg(&logger, "TunerStudio: CRC command %x size %d", command, size);
|
||||||
|
|
||||||
|
tunerStudioWriteData(crcIoBuffer, size + 2 + 1 + 4); // with size, command and CRC
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* EFI_TUNER_STUDIO */
|
#endif /* EFI_TUNER_STUDIO */
|
||||||
|
|
|
@ -8,13 +8,18 @@
|
||||||
#ifndef TUNERSTUDIO_H_
|
#ifndef TUNERSTUDIO_H_
|
||||||
#define TUNERSTUDIO_H_
|
#define TUNERSTUDIO_H_
|
||||||
|
|
||||||
#if EFI_TUNER_STUDIO_OVER_USB
|
#include "tunerstudio_configuration.h"
|
||||||
#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;
|
||||||
|
short int count;
|
||||||
|
|
||||||
|
} TunerStudioWriteChunkRequest;
|
||||||
|
|
||||||
#if defined __GNUC__
|
#if defined __GNUC__
|
||||||
typedef struct
|
typedef struct
|
||||||
|
@ -25,19 +30,19 @@ typedef struct
|
||||||
|
|
||||||
short int offset;
|
short int offset;
|
||||||
unsigned char value;
|
unsigned char value;
|
||||||
} TunerStudioWriteRequest;
|
} TunerStudioWriteValueRequest;
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C"
|
extern "C" {
|
||||||
{
|
|
||||||
#endif /* __cplusplus */
|
#endif /* __cplusplus */
|
||||||
|
|
||||||
void startTunerStudioConnectivity(void);
|
void startTunerStudioConnectivity(void);
|
||||||
void syncTunerStudioCopy(void);
|
void syncTunerStudioCopy(void);
|
||||||
void updateTunerStudioState(void);
|
void updateTunerStudioState(TunerStudioOutputChannels *tsOutputChannels);
|
||||||
|
void tunerStudioWriteCrcPacket(const uint8_t command, const void *buf, const uint16_t size);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif /* __cplusplus */
|
#endif /* __cplusplus */
|
||||||
|
|
||||||
#endif /* TUNERSTUDIO_H_ */
|
#endif /* TUNERSTUDIO_H_ */
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
* @file tunerstudio_algo.c
|
* @file tunerstudio_algo.c
|
||||||
* @brief Tuner Studio plain protocol implementation
|
* @brief Tuner Studio plain protocol implementation
|
||||||
*
|
*
|
||||||
|
* This implementation would not happen without the documentation
|
||||||
|
* provided by Jon Zeeff (jon@zeeff.com)
|
||||||
*
|
*
|
||||||
* Tuner Studio has a really simple protocol, a minimal implementation
|
* Tuner Studio has a really simple protocol, a minimal implementation
|
||||||
* capable of displaying current engine state on the gauges would
|
* capable of displaying current engine state on the gauges would
|
||||||
|
@ -63,17 +65,34 @@ TunerStudioOutputChannels tsOutputChannels;
|
||||||
*/
|
*/
|
||||||
persistent_config_s configWorkingCopy;
|
persistent_config_s configWorkingCopy;
|
||||||
|
|
||||||
int tunerStudioHandleCommand(short command) {
|
int tunerStudioHandleCommand(char *data, int incomingPacketSize) {
|
||||||
if (command == 'H') {
|
char command = data[0];
|
||||||
handleQueryCommand();
|
data++;
|
||||||
} else if (command == 'O') {
|
if (command == TS_HELLO_COMMAND) {
|
||||||
|
tunerStudioDebug("got CRC Query");
|
||||||
|
handleQueryCommand(TRUE);
|
||||||
|
} else if (command == TS_OUTPUT_COMMAND) {
|
||||||
handleOutputChannelsCommand();
|
handleOutputChannelsCommand();
|
||||||
} else if (command == 'W') {
|
} else if (command == TS_PAGE_COMMAND) {
|
||||||
handleValueWriteCommand();
|
uint16_t page = *(uint16_t *) data;
|
||||||
} else if (command == 'B') {
|
handlePageSelectCommand(page);
|
||||||
handleBurnCommand();
|
} else if (command == TS_CHUNK_WRITE_COMMAND) {
|
||||||
} else if (command == 'C') {
|
uint16_t offset = *(uint16_t *) data;
|
||||||
handlePageReadCommand();
|
uint16_t count = *(uint16_t *) (data + 2);
|
||||||
|
handleWriteChunkCommand(offset, count, data + 4);
|
||||||
|
} else if (command == TS_SINGLE_WRITE_COMMAND) {
|
||||||
|
uint16_t page = *(uint16_t *) data;
|
||||||
|
uint16_t offset = *(uint16_t *) (data + 2);
|
||||||
|
uint8_t value = data[4];
|
||||||
|
handleWriteValueCommand(page, offset, value);
|
||||||
|
} else if (command == TS_BURN_COMMAND) {
|
||||||
|
uint16_t page = *(uint16_t *) data;
|
||||||
|
handleBurnCommand(page);
|
||||||
|
} else if (command == TS_READ_COMMAND) {
|
||||||
|
uint16_t page = *(uint16_t *) data;
|
||||||
|
uint16_t offset = *(uint16_t *) (data + 2);
|
||||||
|
uint16_t count = *(uint16_t *) (data + 4);
|
||||||
|
handlePageReadCommand(page, offset, count);
|
||||||
} else if (command == 't' || command == 'T') {
|
} else if (command == 't' || command == 'T') {
|
||||||
handleTestCommand();
|
handleTestCommand();
|
||||||
} else if (command == 'F') {
|
} else if (command == 'F') {
|
||||||
|
@ -86,23 +105,23 @@ int tunerStudioHandleCommand(short command) {
|
||||||
* Currently on some firmware versions the F command is not used and is just ignored by the firmware as a unknown command."
|
* Currently on some firmware versions the F command is not used and is just ignored by the firmware as a unknown command."
|
||||||
*/
|
*/
|
||||||
} else {
|
} else {
|
||||||
#if EFI_TUNER_STUDIO_OVER_USB
|
tunerStudioDebug("ignoring unexpected");
|
||||||
/**
|
|
||||||
* 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++;
|
tsState.errorCounter++;
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void handleQueryCommand(void) {
|
void handleQueryCommand(int needCrc) {
|
||||||
tsState.queryCommandCounter++;
|
tsState.queryCommandCounter++;
|
||||||
tunerStudioDebug("got H (queryCommand)");
|
tunerStudioDebug("got H (queryCommand)");
|
||||||
tunerStudioWriteData((const uint8_t *) TS_SIGNATURE, strlen(TS_SIGNATURE) + 1);
|
if (needCrc) {
|
||||||
|
// Query with CRC takes place while re-establishing connection
|
||||||
|
tunerStudioWriteCrcPacket(TS_RESPONSE_OK, (const uint8_t *) TS_SIGNATURE, strlen(TS_SIGNATURE) + 1);
|
||||||
|
} else {
|
||||||
|
// Query without CRC takes place on TunerStudio startup
|
||||||
|
tunerStudioWriteData((const uint8_t *) TS_SIGNATURE, strlen(TS_SIGNATURE) + 1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -111,7 +130,7 @@ void handleQueryCommand(void) {
|
||||||
void handleOutputChannelsCommand(void) {
|
void handleOutputChannelsCommand(void) {
|
||||||
tsState.outputChannelsCommandCounter++;
|
tsState.outputChannelsCommandCounter++;
|
||||||
// this method is invoked too often to print any debug information
|
// this method is invoked too often to print any debug information
|
||||||
tunerStudioWriteData((const uint8_t *) &tsOutputChannels, sizeof(TunerStudioOutputChannels));
|
tunerStudioWriteCrcPacket(TS_RESPONSE_OK, (const uint8_t *) &tsOutputChannels, sizeof(TunerStudioOutputChannels));
|
||||||
}
|
}
|
||||||
|
|
||||||
void handleTestCommand(void) {
|
void handleTestCommand(void) {
|
||||||
|
@ -119,6 +138,6 @@ void handleTestCommand(void) {
|
||||||
* this is NOT a standard TunerStudio command, this is my own
|
* this is NOT a standard TunerStudio command, this is my own
|
||||||
* extension of the protocol to simplify troubleshooting
|
* extension of the protocol to simplify troubleshooting
|
||||||
*/
|
*/
|
||||||
tunerStudioDebug("got T (Test)\r\n");
|
tunerStudioDebug("got T (Test)");
|
||||||
tunerStudioWriteData((const uint8_t *) "alive\r\n", 7);
|
tunerStudioWriteData((const uint8_t *) "alive\r\n", 7);
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,27 +12,55 @@
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
|
// http://en.wikipedia.org/wiki/Endianness
|
||||||
|
|
||||||
|
#define SWAP_UINT16(x) ((x) << 8) | ((x) >> 8)
|
||||||
|
|
||||||
|
#define SWAP_UINT32(x) (((x) >> 24) & 0xff) | (((x) << 8) & 0xff0000) | (((x) >> 8) & 0xff00) | (((x) << 24) & 0xff000000)
|
||||||
|
|
||||||
|
// response codes
|
||||||
|
|
||||||
|
#define TS_RESPONSE_OK 0x00
|
||||||
|
#define TS_RESPONSE_BURN_OK 0x04
|
||||||
|
#define TS_RESPONSE_CRC_FAILURE 0x82
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int queryCommandCounter;
|
int queryCommandCounter;
|
||||||
int outputChannelsCommandCounter;
|
int outputChannelsCommandCounter;
|
||||||
int readPageCommandsCounter;
|
int readPageCommandsCounter;
|
||||||
int burnCommandCounter;
|
int burnCommandCounter;
|
||||||
|
int pageCommandCounter;
|
||||||
|
int writeValueCommandCounter;
|
||||||
|
int writeChunkCommandCounter;
|
||||||
int errorCounter;
|
int errorCounter;
|
||||||
|
// this field is in the end to simply aligning situation
|
||||||
|
short currentPageId;
|
||||||
} TunerStudioState;
|
} TunerStudioState;
|
||||||
|
|
||||||
int tunerStudioHandleCommand(short command);
|
int tunerStudioHandleCommand(char *data, int incomingPacketSize);
|
||||||
|
|
||||||
void handleTestCommand(void);
|
void handleTestCommand(void);
|
||||||
void handleQueryCommand(void);
|
void handleQueryCommand(int needCrc);
|
||||||
void handleOutputChannelsCommand(void);
|
void handleOutputChannelsCommand(void);
|
||||||
|
|
||||||
char *getWorkingPageAddr(int pageIndex);
|
char *getWorkingPageAddr(int pageIndex);
|
||||||
int getTunerStudioPageSize(int pageIndex);
|
int getTunerStudioPageSize(int pageIndex);
|
||||||
void handleValueWriteCommand(void);
|
void handleWriteValueCommand(uint16_t page, uint16_t offset, uint8_t value);
|
||||||
void handlePageReadCommand(void);
|
void handleWriteChunkCommand(short offset, short count, void *content);
|
||||||
void handleBurnCommand(void);
|
void handlePageSelectCommand(uint16_t pageId);
|
||||||
|
void handlePageReadCommand(uint16_t pageId, uint16_t offset, uint16_t count);
|
||||||
|
void handleBurnCommand(uint16_t page);
|
||||||
|
|
||||||
void tunerStudioWriteData(const uint8_t * buffer, int size);
|
void tunerStudioWriteData(const uint8_t * buffer, int size);
|
||||||
void tunerStudioDebug(char *msg);
|
void tunerStudioDebug(char *msg);
|
||||||
|
|
||||||
|
#define TS_HELLO_COMMAND 'H'
|
||||||
|
#define TS_OUTPUT_COMMAND 'O'
|
||||||
|
#define TS_READ_COMMAND 'R'
|
||||||
|
#define TS_PAGE_COMMAND 'P'
|
||||||
|
|
||||||
|
#define TS_SINGLE_WRITE_COMMAND 'W'
|
||||||
|
#define TS_CHUNK_WRITE_COMMAND 'C'
|
||||||
|
#define TS_BURN_COMMAND 'B'
|
||||||
|
|
||||||
#endif /* TUNERSTUDIO_ALGO_H_ */
|
#endif /* TUNERSTUDIO_ALGO_H_ */
|
||||||
|
|
|
@ -29,6 +29,7 @@ typedef struct {
|
||||||
float atmospherePressure; // size 4, offset 36
|
float atmospherePressure; // size 4, offset 36
|
||||||
float manifold_air_pressure; // size 4, offset 40
|
float manifold_air_pressure; // size 4, offset 40
|
||||||
int checkEngine; // size 4, offset 44
|
int checkEngine; // size 4, offset 44
|
||||||
|
float tCharge;
|
||||||
} TunerStudioOutputChannels;
|
} TunerStudioOutputChannels;
|
||||||
|
|
||||||
#endif /* TUNERSTUDIO_CONFIGURATION_H_ */
|
#endif /* TUNERSTUDIO_CONFIGURATION_H_ */
|
||||||
|
|
|
@ -38,7 +38,6 @@
|
||||||
#include "memstreams.h"
|
#include "memstreams.h"
|
||||||
#include "console_io.h"
|
#include "console_io.h"
|
||||||
|
|
||||||
#define OUTPUT_BUFFER 9000
|
|
||||||
/**
|
/**
|
||||||
* This is the size of the MemoryStream used by chvprintf
|
* This is the size of the MemoryStream used by chvprintf
|
||||||
*/
|
*/
|
||||||
|
@ -50,18 +49,15 @@
|
||||||
/**
|
/**
|
||||||
* This is the buffer into which all the data providers write
|
* This is the buffer into which all the data providers write
|
||||||
*/
|
*/
|
||||||
#if defined __GNUC__
|
static char pendingBuffer[DL_OUTPUT_BUFFER] CCM_OPTIONAL;
|
||||||
static char pendingBuffer[OUTPUT_BUFFER] __attribute__((section(".ccm")));
|
|
||||||
#else
|
|
||||||
static char pendingBuffer[OUTPUT_BUFFER];
|
|
||||||
#endif
|
|
||||||
/**
|
/**
|
||||||
* We copy all the pending data into this buffer once we are ready to push it out
|
* We copy all the pending data into this buffer once we are ready to push it out
|
||||||
*/
|
*/
|
||||||
static char outputBuffer[OUTPUT_BUFFER];
|
static char outputBuffer[DL_OUTPUT_BUFFER];
|
||||||
|
|
||||||
static MemoryStream intermediateLoggingBuffer;
|
static MemoryStream intermediateLoggingBuffer;
|
||||||
static uint8_t intermediateLoggingBufferData[INTERMEDIATE_LOGGING_BUFFER_SIZE]; //todo define max-printf-buffer
|
static uint8_t intermediateLoggingBufferData[INTERMEDIATE_LOGGING_BUFFER_SIZE] CCM_OPTIONAL; //todo define max-printf-buffer
|
||||||
static bool intermediateLoggingBufferInited = FALSE;
|
static bool intermediateLoggingBufferInited = FALSE;
|
||||||
|
|
||||||
static int validateBuffer(Logging *logging, int extraLen, const char *text) {
|
static int validateBuffer(Logging *logging, int extraLen, const char *text) {
|
||||||
|
@ -76,7 +72,7 @@ static int validateBuffer(Logging *logging, int extraLen, const char *text) {
|
||||||
strcat(logging->SMALL_BUFFER, logging->name);
|
strcat(logging->SMALL_BUFFER, logging->name);
|
||||||
strcat(logging->SMALL_BUFFER, "/");
|
strcat(logging->SMALL_BUFFER, "/");
|
||||||
strcat(logging->SMALL_BUFFER, text);
|
strcat(logging->SMALL_BUFFER, text);
|
||||||
fatal(logging->SMALL_BUFFER);
|
firmwareError(logging->SMALL_BUFFER);
|
||||||
// unlockOutputBuffer();
|
// unlockOutputBuffer();
|
||||||
// resetLogging(logging);
|
// resetLogging(logging);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
@ -85,7 +81,7 @@ static int validateBuffer(Logging *logging, int extraLen, const char *text) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void append(Logging *logging, const char *text) {
|
void append(Logging *logging, const char *text) {
|
||||||
chDbgCheck(text!=NULL, "append NULL");
|
efiAssertVoid(text != NULL, "append NULL");
|
||||||
int extraLen = strlen(text);
|
int extraLen = strlen(text);
|
||||||
int errcode = validateBuffer(logging, extraLen, text);
|
int errcode = validateBuffer(logging, extraLen, text);
|
||||||
if (errcode)
|
if (errcode)
|
||||||
|
@ -102,8 +98,9 @@ static void vappendPrintfI(Logging *logging, const char *fmt, va_list arg) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void vappendPrintf(Logging *logging, const char *fmt, va_list arg) {
|
void vappendPrintf(Logging *logging, const char *fmt, va_list arg) {
|
||||||
|
efiAssertVoid(getRemainingStack(chThdSelf()) > 16, "stack#5b");
|
||||||
if (!intermediateLoggingBufferInited) {
|
if (!intermediateLoggingBufferInited) {
|
||||||
fatal("intermediateLoggingBufferInited not inited!");
|
firmwareError("intermediateLoggingBufferInited not inited!");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
int is_locked = isLocked();
|
int is_locked = isLocked();
|
||||||
|
@ -128,6 +125,7 @@ void vappendPrintf(Logging *logging, const char *fmt, va_list arg) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void appendPrintf(Logging *logging, const char *fmt, ...) {
|
void appendPrintf(Logging *logging, const char *fmt, ...) {
|
||||||
|
efiAssertVoid(getRemainingStack(chThdSelf()) > 16, "stack#4");
|
||||||
va_list ap;
|
va_list ap;
|
||||||
va_start(ap, fmt);
|
va_start(ap, fmt);
|
||||||
vappendPrintf(logging, fmt, ap);
|
vappendPrintf(logging, fmt, ap);
|
||||||
|
@ -154,7 +152,7 @@ char* getCaption(LoggingPoints loggingPoint) {
|
||||||
case LP_MAP_RAW:
|
case LP_MAP_RAW:
|
||||||
return "MAP_R";
|
return "MAP_R";
|
||||||
}
|
}
|
||||||
fatal("No such loggingPoint");
|
firmwareError("No such loggingPoint");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -176,7 +174,7 @@ static char* get2ndCaption(int loggingPoint) {
|
||||||
case LP_MAF:
|
case LP_MAF:
|
||||||
return "MAF";
|
return "MAF";
|
||||||
}
|
}
|
||||||
fatal("No such loggingPoint");
|
firmwareError("No such loggingPoint");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -204,7 +202,11 @@ void debugInt(Logging *logging, const char *caption, int value) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void appendFloat(Logging *logging, float value, int precision) {
|
void appendFloat(Logging *logging, float value, int precision) {
|
||||||
// todo: this implementation is less than perfect
|
/**
|
||||||
|
* todo: #1 this implementation is less than perfect
|
||||||
|
* todo: #2 The only way to avoid double promotion would probably be using *float instead of float
|
||||||
|
* See also http://stackoverflow.com/questions/5522051/printing-a-float-in-c-while-avoiding-variadic-parameter-promotion-to-double
|
||||||
|
*/
|
||||||
switch (precision) {
|
switch (precision) {
|
||||||
case 1:
|
case 1:
|
||||||
appendPrintf(logging, "%..10f", value);
|
appendPrintf(logging, "%..10f", value);
|
||||||
|
@ -324,7 +326,7 @@ void scheduleMsg(Logging *logging, const char *fmt, ...) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// todo: remove this method, replace with 'scheduleMsg'
|
// todo: remove this method, replace with 'scheduleMsg'
|
||||||
void scheduleIntValue(Logging *logging, char *msg, int value) {
|
void scheduleIntValue(Logging *logging, const char *msg, int value) {
|
||||||
resetLogging(logging);
|
resetLogging(logging);
|
||||||
|
|
||||||
append(logging, msg);
|
append(logging, msg);
|
||||||
|
@ -339,10 +341,10 @@ void scheduleLogging(Logging *logging) {
|
||||||
// this could be done without locking
|
// this could be done without locking
|
||||||
int newLength = strlen(logging->buffer);
|
int newLength = strlen(logging->buffer);
|
||||||
|
|
||||||
bool_t alreadyLocked = lockOutputBuffer();
|
bool alreadyLocked = lockOutputBuffer();
|
||||||
// I hope this is fast enough to operate under sys lock
|
// I hope this is fast enough to operate under sys lock
|
||||||
int curLength = strlen(pendingBuffer);
|
int curLength = strlen(pendingBuffer);
|
||||||
if (curLength + newLength >= OUTPUT_BUFFER) {
|
if (curLength + newLength >= DL_OUTPUT_BUFFER) {
|
||||||
/**
|
/**
|
||||||
* if no one is consuming the data we have to drop it
|
* 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
|
* this happens in case of serial-over-USB, todo: find a better solution
|
||||||
|
|
|
@ -81,7 +81,7 @@ void append(Logging *logging, const char *text);
|
||||||
|
|
||||||
void scheduleLogging(Logging *logging);
|
void scheduleLogging(Logging *logging);
|
||||||
|
|
||||||
void scheduleIntValue(Logging *logging, char *msg, int value);
|
void scheduleIntValue(Logging *logging, const char *msg, int value);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* this should only be invoked by the 'main' thread in order to keep the console safe
|
* this should only be invoked by the 'main' thread in order to keep the console safe
|
||||||
|
|
|
@ -22,6 +22,8 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "rfiutil.h"
|
#include "rfiutil.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
not used, not sure if we still need it. I guess we will remove it in 2015
|
||||||
int mylog10(int param) {
|
int mylog10(int param) {
|
||||||
if (param < 10)
|
if (param < 10)
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -39,49 +41,10 @@ int mylog10(int param) {
|
||||||
return 6;
|
return 6;
|
||||||
if (param < 100000000)
|
if (param < 100000000)
|
||||||
return 7;
|
return 7;
|
||||||
|
#warning This would be better without recursion
|
||||||
return mylog10(param / 10) + 1;
|
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) {
|
char hexChar(int v) {
|
||||||
v = v & 0xF;
|
v = v & 0xF;
|
||||||
|
@ -103,11 +66,15 @@ int isLocked(void) {
|
||||||
return dbg_lock_cnt > 0;
|
return dbg_lock_cnt > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void chVTSetAny(VirtualTimer *vtp, systime_t time, vtfunc_t vtfunc, void *par) {
|
void chVTSetAny(virtual_timer_t *vtp, systime_t time, vtfunc_t vtfunc, void *par) {
|
||||||
if (isIsrContext()) {
|
if (isIsrContext()) {
|
||||||
chSysLockFromIsr()
|
chSysLockFromIsr()
|
||||||
;
|
;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* todo: this could be simplified once we migrate to ChibiOS 3.0
|
||||||
|
* See http://www.chibios.org/dokuwiki/doku.php?id=chibios:howtos:porting_from_2_to_3
|
||||||
|
*/
|
||||||
if (chVTIsArmedI(vtp))
|
if (chVTIsArmedI(vtp))
|
||||||
chVTResetI(vtp);
|
chVTResetI(vtp);
|
||||||
|
|
||||||
|
|
|
@ -13,23 +13,15 @@
|
||||||
#include "histogram.h"
|
#include "histogram.h"
|
||||||
#include "datalogging.h"
|
#include "datalogging.h"
|
||||||
|
|
||||||
#ifndef TRUE
|
|
||||||
#define TRUE 1
|
|
||||||
#define FALSE 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define _MAX_FILLER 11
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C"
|
extern "C"
|
||||||
{
|
{
|
||||||
#endif /* __cplusplus */
|
#endif /* __cplusplus */
|
||||||
|
|
||||||
char* itoa10(uint8_t *p, int num);
|
|
||||||
char hexC(int v);
|
char hexC(int v);
|
||||||
int isIsrContext(void);
|
int isIsrContext(void);
|
||||||
int isLocked(void);
|
int isLocked(void);
|
||||||
void chVTSetAny(VirtualTimer *vtp, systime_t time, vtfunc_t vtfunc, void *par);
|
void chVTSetAny(virtual_timer_t *vtp, systime_t time, vtfunc_t vtfunc, void *par);
|
||||||
void printHistogram(Logging *logging, histogram_s *histogram);
|
void printHistogram(Logging *logging, histogram_s *histogram);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
|
@ -15,18 +15,7 @@
|
||||||
|
|
||||||
static Logging logger;
|
static Logging logger;
|
||||||
|
|
||||||
static float _switchTimes[2];
|
static SimplePwm pwmTest[5];
|
||||||
|
|
||||||
// todo: extract helper for simple PWM?
|
|
||||||
static int pinStates[2];
|
|
||||||
static single_wave_s wave(pinStates);
|
|
||||||
static single_wave_s sr[1] = { wave };
|
|
||||||
|
|
||||||
static PwmConfig pwmTest[5] = { PwmConfig(_switchTimes, sr),
|
|
||||||
PwmConfig(_switchTimes, sr),
|
|
||||||
PwmConfig(_switchTimes, sr),
|
|
||||||
PwmConfig(_switchTimes, sr),
|
|
||||||
PwmConfig(_switchTimes, sr)};
|
|
||||||
|
|
||||||
extern board_configuration_s *boardConfiguration;
|
extern board_configuration_s *boardConfiguration;
|
||||||
|
|
||||||
|
@ -34,20 +23,15 @@ static void startPwmTest(int freq) {
|
||||||
scheduleMsg(&logger, "running pwm test @%d", freq);
|
scheduleMsg(&logger, "running pwm test @%d", freq);
|
||||||
|
|
||||||
// PD13, GPIO_NONE because pin is initialized elsewhere already
|
// PD13, GPIO_NONE because pin is initialized elsewhere already
|
||||||
startSimplePwm(&pwmTest[0], "tester", GPIO_NONE,
|
startSimplePwm(&pwmTest[0], "tester", LED_WARNING, 10, 0.5);
|
||||||
LED_CRANKING, 0.5, 10, FALSE);
|
// currently this is PB9 by default - see boardConfiguration->injectionPins
|
||||||
// currently this is PB9 by default
|
startSimplePwm(&pwmTest[1], "tester", INJECTOR_1_OUTPUT, freq / 1.3333333333, 0.5);
|
||||||
startSimplePwm(&pwmTest[1], "tester", boardConfiguration->injectionPins[0],
|
|
||||||
INJECTOR_1_OUTPUT, 0.5, freq / 1.3333333333, FALSE);
|
|
||||||
// currently this is PB8 by default
|
// currently this is PB8 by default
|
||||||
startSimplePwm(&pwmTest[2], "tester", GPIO_NONE,
|
startSimplePwm(&pwmTest[2], "tester", INJECTOR_2_OUTPUT, freq / 1000, 0.5);
|
||||||
INJECTOR_2_OUTPUT, 0.5, freq / 1000, FALSE);
|
|
||||||
// currently this is PE3 by default
|
// currently this is PE3 by default
|
||||||
startSimplePwm(&pwmTest[3], "tester", GPIO_NONE,
|
startSimplePwm(&pwmTest[3], "tester", INJECTOR_3_OUTPUT, freq, 0.5);
|
||||||
INJECTOR_3_OUTPUT, 0.5, freq, FALSE);
|
|
||||||
// currently this is PE5 by default
|
// currently this is PE5 by default
|
||||||
startSimplePwm(&pwmTest[4], "tester", GPIO_NONE,
|
startSimplePwm(&pwmTest[4], "tester", INJECTOR_4_OUTPUT, freq / 33.33333333333, 0.5);
|
||||||
INJECTOR_4_OUTPUT, 0.5, freq / 33.33333333333, FALSE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void initPwmTester(void) {
|
void initPwmTester(void) {
|
||||||
|
|
|
@ -18,25 +18,30 @@ extern engine_configuration_s *engineConfiguration;
|
||||||
static AccelEnrichmemnt instance;
|
static AccelEnrichmemnt instance;
|
||||||
|
|
||||||
void AccelEnrichmemnt::updateDiffEnrichment(engine_configuration_s *engineConfiguration, float engineLoad) {
|
void AccelEnrichmemnt::updateDiffEnrichment(engine_configuration_s *engineConfiguration, float engineLoad) {
|
||||||
for (int i = 1; i < 4; i++) {
|
for (int i = 3; i == 1; i--)
|
||||||
engineLoadD[i] = engineLoadD[i - 1];
|
engineLoadD[i] = engineLoadD[i - 1];
|
||||||
}
|
|
||||||
engineLoadD[0] = engineLoad;
|
engineLoadD[0] = engineLoad;
|
||||||
float Dcurr = engineLoadD[0] - engineLoadD[1];
|
|
||||||
float Dold = engineLoadD[2] - engineLoadD[3];
|
diffEnrichment = ((3 * (engineLoadD[0] - engineLoadD[1]) + (engineLoadD[2] - engineLoadD[3])) / 4)
|
||||||
diffEnrichment = ((3 * Dcurr + Dold) / 4) * (engineConfiguration->diffLoadEnrichmentCoef);
|
* (engineConfiguration->diffLoadEnrichmentCoef);
|
||||||
}
|
}
|
||||||
|
|
||||||
float AccelEnrichmemnt::getDiffEnrichment() {
|
float AccelEnrichmemnt::getDiffEnrichment() {
|
||||||
return diffEnrichment;
|
return diffEnrichment;
|
||||||
}
|
}
|
||||||
|
AccelEnrichmemnt::AccelEnrichmemnt() {
|
||||||
|
for (int i = 0; i < 4; i++)
|
||||||
|
engineLoadD[i] = 0;
|
||||||
|
diffEnrichment = 0;
|
||||||
|
}
|
||||||
|
|
||||||
float getAccelEnrichment(void) {
|
float getAccelEnrichment(void) {
|
||||||
return instance.getDiffEnrichment();
|
return instance.getDiffEnrichment();
|
||||||
}
|
}
|
||||||
|
|
||||||
#if EFI_PROD_CODE
|
#if EFI_PROD_CODE
|
||||||
static WORKING_AREA(aeThreadStack, UTILITY_THREAD_STACK_SIZE);
|
static THD_WORKING_AREA(aeThreadStack, UTILITY_THREAD_STACK_SIZE);
|
||||||
|
|
||||||
static msg_t DiffEnrichmentThread(int param) {
|
static msg_t DiffEnrichmentThread(int param) {
|
||||||
chRegSetThreadName("Diff Enrichment");
|
chRegSetThreadName("Diff Enrichment");
|
||||||
|
@ -54,3 +59,4 @@ void initDiffEnrichment(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -14,14 +14,18 @@
|
||||||
|
|
||||||
class AccelEnrichmemnt {
|
class AccelEnrichmemnt {
|
||||||
public:
|
public:
|
||||||
void updateDiffEnrichment(engine_configuration_s *engineConfiguration, float engineLoad);
|
AccelEnrichmemnt();
|
||||||
|
void updateDiffEnrichment(engine_configuration_s *engineConfiguration,
|
||||||
|
float engineLoad);
|
||||||
float getDiffEnrichment(void);
|
float getDiffEnrichment(void);
|
||||||
private:
|
private:
|
||||||
float engineLoadD[5];
|
float engineLoadD[4];
|
||||||
float diffEnrichment;
|
float diffEnrichment;
|
||||||
};
|
};
|
||||||
|
|
||||||
void initDiffEnrichment(void);
|
void initDiffEnrichment(void);
|
||||||
float getAccelEnrichment(void);
|
float getAccelEnrichment(void);
|
||||||
|
|
||||||
|
|
||||||
#endif /* ACC_ENRICHMENT_H_ */
|
#endif /* ACC_ENRICHMENT_H_ */
|
||||||
|
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
* If not, see <http://www.gnu.org/licenses/>.
|
* If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "main.h"
|
||||||
#include "advance_map.h"
|
#include "advance_map.h"
|
||||||
#include "interpolation.h"
|
#include "interpolation.h"
|
||||||
// that's for 'max' function
|
// that's for 'max' function
|
||||||
|
@ -29,16 +30,13 @@
|
||||||
extern engine_configuration_s *engineConfiguration;
|
extern engine_configuration_s *engineConfiguration;
|
||||||
//extern engine_configuration2_s *engineConfiguration2;
|
//extern engine_configuration2_s *engineConfiguration2;
|
||||||
|
|
||||||
static float *timing_ptrs[AD_LOAD_COUNT];
|
static Map3D1616 advanceMap;
|
||||||
static int initialized = FALSE;
|
|
||||||
|
|
||||||
float getBaseAdvance(int rpm, float engineLoad) {
|
float getBaseAdvance(int rpm, float engineLoad) {
|
||||||
chDbgAssert(initialized, "fuel map initialized", NULL);
|
efiAssert(!cisnan(engineLoad), "invalid el", NAN);
|
||||||
efiAssert(!cisnan(engineLoad), "invalid el");
|
efiAssert(!cisnan(engineLoad), "invalid rpm", NAN);
|
||||||
efiAssert(!cisnan(engineLoad), "invalid rpm");
|
return advanceMap.getValue(engineLoad, engineConfiguration->ignitionLoadBins, rpm,
|
||||||
return interpolate3d(engineLoad, engineConfiguration->ignitionLoadBins, AD_LOAD_COUNT, rpm,
|
engineConfiguration->ignitionRpmBins);
|
||||||
engineConfiguration->ignitionRpmBins,
|
|
||||||
AD_RPM_COUNT, timing_ptrs);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
float getAdvance(int rpm, float engineLoad) {
|
float getAdvance(int rpm, float engineLoad) {
|
||||||
|
@ -52,7 +50,5 @@ float getAdvance(int rpm, float engineLoad) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void prepareTimingMap(void) {
|
void prepareTimingMap(void) {
|
||||||
for (int k = 0; k < AD_LOAD_COUNT; k++)
|
advanceMap.init(engineConfiguration->ignitionTable);
|
||||||
timing_ptrs[k] = engineConfiguration->ignitionTable[k];
|
|
||||||
initialized = TRUE;
|
|
||||||
}
|
}
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* advance.h
|
* @file advance_map.h
|
||||||
*
|
*
|
||||||
* @date Mar 27, 2013
|
* @date Mar 27, 2013
|
||||||
* @author Andrey Belomutskiy, (c) 2012-2014
|
* @author Andrey Belomutskiy, (c) 2012-2014
|
||||||
|
|
|
@ -1,16 +1,17 @@
|
||||||
|
|
||||||
CONTROLLERS_ALGO_SRC = $(PROJECT_DIR)/controllers/algo/map_adjuster.c \
|
CONTROLLERS_ALGO_SRC = $(PROJECT_DIR)/controllers/algo/map_adjuster.c \
|
||||||
$(PROJECT_DIR)/controllers/algo/advance_map.c \
|
|
||||||
$(PROJECT_DIR)/controllers/algo/signal_executor.c \
|
$(PROJECT_DIR)/controllers/algo/signal_executor.c \
|
||||||
$(PROJECT_DIR)/controllers/algo/malfunction_central.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/idle_controller.c \
|
||||||
$(PROJECT_DIR)/controllers/algo/wave_chart.c \
|
$(PROJECT_DIR)/controllers/algo/wave_chart.c \
|
||||||
$(PROJECT_DIR)/controllers/algo/nmea.c
|
$(PROJECT_DIR)/controllers/algo/nmea.c
|
||||||
|
|
||||||
CONTROLLERS_ALGO_SRC_CPP = $(PROJECT_DIR)/controllers/algo/OutputSignalArray.cpp \
|
CONTROLLERS_ALGO_SRC_CPP = $(PROJECT_DIR)/controllers/algo/OutputSignalArray.cpp \
|
||||||
|
$(PROJECT_DIR)/controllers/algo/advance_map.cpp \
|
||||||
$(PROJECT_DIR)/controllers/algo/fuel_math.cpp \
|
$(PROJECT_DIR)/controllers/algo/fuel_math.cpp \
|
||||||
$(PROJECT_DIR)/controllers/algo/accel_enrichment.cpp \
|
$(PROJECT_DIR)/controllers/algo/accel_enrichment.cpp \
|
||||||
$(PROJECT_DIR)/controllers/algo/engine_configuration.cpp \
|
$(PROJECT_DIR)/controllers/algo/engine_configuration.cpp \
|
||||||
|
$(PROJECT_DIR)/controllers/algo/engine.cpp \
|
||||||
|
$(PROJECT_DIR)/controllers/algo/event_registry.cpp \
|
||||||
$(PROJECT_DIR)/controllers/algo/algo.cpp
|
$(PROJECT_DIR)/controllers/algo/algo.cpp
|
||||||
|
|
||||||
|
|
|
@ -13,8 +13,19 @@
|
||||||
#define EC2_H_
|
#define EC2_H_
|
||||||
|
|
||||||
#include "engine_configuration.h"
|
#include "engine_configuration.h"
|
||||||
|
#include "event_registry.h"
|
||||||
#include "trigger_structure.h"
|
#include "trigger_structure.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Here we store information about which injector or spark should be fired when.
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
ActuatorEventList crankingInjectionEvents;
|
||||||
|
ActuatorEventList injectionEvents;
|
||||||
|
IgnitionEventList ignitionEvents[2];
|
||||||
|
} EventHandlerConfiguration;
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C"
|
extern "C"
|
||||||
{
|
{
|
||||||
|
@ -42,15 +53,26 @@ public:
|
||||||
EventHandlerConfiguration engineEventConfiguration;
|
EventHandlerConfiguration engineEventConfiguration;
|
||||||
|
|
||||||
int isInjectionEnabledFlag;
|
int isInjectionEnabledFlag;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This coefficient translates ADC value directly into voltage adjusted according to
|
||||||
|
* voltage divider configuration.
|
||||||
|
*/
|
||||||
|
float adcToVoltageInputDividerCoefficient;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
engine_configuration_s *engineConfiguration;
|
||||||
|
engine_configuration2_s *engineConfiguration2;
|
||||||
|
} configuration_s;
|
||||||
|
|
||||||
void prepareOutputSignals(engine_configuration_s *engineConfiguration,
|
void prepareOutputSignals(engine_configuration_s *engineConfiguration,
|
||||||
engine_configuration2_s *engineConfiguration2);
|
engine_configuration2_s *engineConfiguration2);
|
||||||
|
|
||||||
void initializeIgnitionActions(float baseAngle, engine_configuration_s *engineConfiguration, engine_configuration2_s *engineConfiguration2, float dwellMs, ActuatorEventList *list);
|
void initializeIgnitionActions(float advance, float dwellAngle, engine_configuration_s *engineConfiguration, engine_configuration2_s *engineConfiguration2, IgnitionEventList *list);
|
||||||
void addFuelEvents(engine_configuration_s const *e, engine_configuration2_s *engineConfiguration2, ActuatorEventList *list, injection_mode_e mode);
|
void addFuelEvents(engine_configuration_s const *e, engine_configuration2_s *engineConfiguration2, ActuatorEventList *list, injection_mode_e mode);
|
||||||
|
|
||||||
void registerActuatorEventExt(engine_configuration_s const *engineConfiguration, trigger_shape_s * s, ActuatorEventList *list, OutputSignal *actuator, float angleOffset);
|
void registerActuatorEventExt(engine_configuration_s const *engineConfiguration, trigger_shape_s * s, ActuatorEvent *e, OutputSignal *actuator, float angleOffset);
|
||||||
|
|
||||||
void resetConfigurationExt(Logging * logger, engine_type_e engineType,
|
void resetConfigurationExt(Logging * logger, engine_type_e engineType,
|
||||||
engine_configuration_s *engineConfiguration,
|
engine_configuration_s *engineConfiguration,
|
||||||
|
|
|
@ -0,0 +1,13 @@
|
||||||
|
/**
|
||||||
|
* @file engine.cpp
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* This might be a http://en.wikipedia.org/wiki/God_object but that's best way I can
|
||||||
|
* express myself in C/C++. I am open for suggestions :)
|
||||||
|
*
|
||||||
|
* @date May 21, 2014
|
||||||
|
* @author Andrey Belomutskiy, (c) 2012-2014
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,21 @@
|
||||||
|
/**
|
||||||
|
* @file engine.h
|
||||||
|
*
|
||||||
|
* @date May 21, 2014
|
||||||
|
* @author Andrey Belomutskiy, (c) 2012-2014
|
||||||
|
*/
|
||||||
|
#ifndef ENGINE_H_
|
||||||
|
#define ENGINE_H_
|
||||||
|
|
||||||
|
#include "main.h"
|
||||||
|
#include "engine_configuration.h"
|
||||||
|
|
||||||
|
class RpmCalculator;
|
||||||
|
|
||||||
|
class Engine {
|
||||||
|
public:
|
||||||
|
RpmCalculator *rpmCalculator;
|
||||||
|
engine_configuration_s *engineConfiguration;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* ENGINE_H_ */
|
|
@ -1,5 +1,5 @@
|
||||||
/**
|
/**
|
||||||
* @file engine_controller.c
|
* @file engine_configuration.cpp
|
||||||
* @brief Utility method related to the engine configuration data structure.
|
* @brief Utility method related to the engine configuration data structure.
|
||||||
*
|
*
|
||||||
* @date Nov 22, 2013
|
* @date Nov 22, 2013
|
||||||
|
@ -46,6 +46,7 @@
|
||||||
#include "MiniCooperR50.h"
|
#include "MiniCooperR50.h"
|
||||||
#include "ford_escort_gt.h"
|
#include "ford_escort_gt.h"
|
||||||
#include "citroenBerlingoTU3JP.h"
|
#include "citroenBerlingoTU3JP.h"
|
||||||
|
#include "rover_v8.h"
|
||||||
|
|
||||||
static volatile int globalConfigurationVersion = 0;
|
static volatile int globalConfigurationVersion = 0;
|
||||||
|
|
||||||
|
@ -77,6 +78,14 @@ void initBpsxD1Sensor(afr_sensor_s *sensor) {
|
||||||
sensor->value2 = 19;
|
sensor->value2 = 19;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void setWholeVEMap(engine_configuration_s *engineConfiguration, float value) {
|
||||||
|
// for (int l = 0; l < VE_LOAD_COUNT; l++) {
|
||||||
|
// for (int r = 0; r < VE_RPM_COUNT; r++) {
|
||||||
|
// engineConfiguration->veTable[l][r] = value;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
void setWholeFuelMap(engine_configuration_s *engineConfiguration, float value) {
|
void setWholeFuelMap(engine_configuration_s *engineConfiguration, float value) {
|
||||||
for (int l = 0; l < FUEL_LOAD_COUNT; l++) {
|
for (int l = 0; l < FUEL_LOAD_COUNT; l++) {
|
||||||
for (int r = 0; r < FUEL_RPM_COUNT; r++) {
|
for (int r = 0; r < FUEL_RPM_COUNT; r++) {
|
||||||
|
@ -85,6 +94,13 @@ void setWholeFuelMap(engine_configuration_s *engineConfiguration, float value) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void setTriggerSynchronizationGap(engine_configuration_s *engineConfiguration, float synchGap) {
|
||||||
|
engineConfiguration->triggerConfig.isSynchronizationNeeded = TRUE;
|
||||||
|
|
||||||
|
engineConfiguration->triggerConfig.syncRatioFrom = synchGap * 0.75;
|
||||||
|
engineConfiguration->triggerConfig.syncRatioTo = synchGap * 1.25;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Global default engine configuration
|
* @brief Global default engine configuration
|
||||||
* This method sets the default global engine configuration. These values are later overridden by engine-specific defaults
|
* This method sets the default global engine configuration. These values are later overridden by engine-specific defaults
|
||||||
|
@ -192,20 +208,20 @@ void setDefaultConfiguration(engine_configuration_s *engineConfiguration, board_
|
||||||
engineConfiguration->canReadEnabled = TRUE;
|
engineConfiguration->canReadEnabled = TRUE;
|
||||||
engineConfiguration->canWriteEnabled = FALSE;
|
engineConfiguration->canWriteEnabled = FALSE;
|
||||||
|
|
||||||
/**
|
setOperationMode(engineConfiguration, FOUR_STROKE_CAM_SENSOR);
|
||||||
* 0.5 means primary position sensor is on a camshaft
|
|
||||||
*/
|
|
||||||
engineConfiguration->rpmMultiplier = 0.5;
|
|
||||||
engineConfiguration->cylindersCount = 4;
|
engineConfiguration->cylindersCount = 4;
|
||||||
|
engineConfiguration->displacement = 2;
|
||||||
|
/**
|
||||||
|
* By the way http://users.erols.com/srweiss/tableifc.htm has a LOT of data
|
||||||
|
*/
|
||||||
|
engineConfiguration->injectorFlow = 200;
|
||||||
|
|
||||||
engineConfiguration->displayMode = DM_HD44780;
|
engineConfiguration->displayMode = DM_HD44780;
|
||||||
|
|
||||||
engineConfiguration->logFormat = LF_NATIVE;
|
engineConfiguration->logFormat = LF_NATIVE;
|
||||||
|
|
||||||
engineConfiguration->triggerConfig.triggerType = TT_TOOTHED_WHEEL;
|
engineConfiguration->triggerConfig.triggerType = TT_TOOTHED_WHEEL;
|
||||||
engineConfiguration->triggerConfig.syncRatioFrom = 1.5;
|
setTriggerSynchronizationGap(engineConfiguration, 2);
|
||||||
engineConfiguration->triggerConfig.syncRatioTo = 3;
|
|
||||||
engineConfiguration->triggerConfig.isSynchronizationNeeded = TRUE;
|
|
||||||
engineConfiguration->triggerConfig.useRiseEdge = TRUE;
|
engineConfiguration->triggerConfig.useRiseEdge = TRUE;
|
||||||
|
|
||||||
engineConfiguration->HD44780width = 16;
|
engineConfiguration->HD44780width = 16;
|
||||||
|
@ -291,6 +307,13 @@ void setDefaultConfiguration(engine_configuration_s *engineConfiguration, board_
|
||||||
boardConfiguration->primaryLogicAnalyzerPin = GPIOA_8;
|
boardConfiguration->primaryLogicAnalyzerPin = GPIOA_8;
|
||||||
boardConfiguration->secondaryLogicAnalyzerPin = GPIOE_7;
|
boardConfiguration->secondaryLogicAnalyzerPin = GPIOE_7;
|
||||||
|
|
||||||
|
boardConfiguration->idleThreadPeriod = 100;
|
||||||
|
boardConfiguration->consoleLoopPeriod = 200;
|
||||||
|
boardConfiguration->lcdThreadPeriod = 300;
|
||||||
|
boardConfiguration->tunerStudioThreadPeriod = 300;
|
||||||
|
boardConfiguration->generalPeriodicThreadPeriod = 200;
|
||||||
|
|
||||||
|
boardConfiguration->tunerStudioSerialSpeed = 38400;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setDefaultNonPersistentConfiguration(engine_configuration2_s *engineConfiguration2) {
|
void setDefaultNonPersistentConfiguration(engine_configuration2_s *engineConfiguration2) {
|
||||||
|
@ -363,6 +386,10 @@ void resetConfigurationExt(Logging * logger, engine_type_e engineType, engine_co
|
||||||
case CITROEN_TU3JP:
|
case CITROEN_TU3JP:
|
||||||
setCitroenBerlingoTU3JPConfiguration(engineConfiguration, boardConfiguration);
|
setCitroenBerlingoTU3JPConfiguration(engineConfiguration, boardConfiguration);
|
||||||
break;
|
break;
|
||||||
|
case ROVER_V8:
|
||||||
|
setRoverv8(engineConfiguration, boardConfiguration);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
firmwareError("Unexpected engine type: %d", engineType);
|
firmwareError("Unexpected engine type: %d", engineType);
|
||||||
|
|
||||||
|
@ -398,6 +425,22 @@ void applyNonPersistentConfiguration(Logging * logger, engine_configuration_s *e
|
||||||
|
|
||||||
prepareOutputSignals(engineConfiguration, engineConfiguration2);
|
prepareOutputSignals(engineConfiguration, engineConfiguration2);
|
||||||
// todo: looks like this is here only for unit tests. todo: remove
|
// todo: looks like this is here only for unit tests. todo: remove
|
||||||
initializeIgnitionActions(0, engineConfiguration, engineConfiguration2, 0, &engineConfiguration2->engineEventConfiguration.ignitionEvents[0]);
|
initializeIgnitionActions(0, 0, engineConfiguration, engineConfiguration2,
|
||||||
|
&engineConfiguration2->engineEventConfiguration.ignitionEvents[0]);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void setOperationMode(engine_configuration_s *engineConfiguration, operation_mode_e mode) {
|
||||||
|
if (mode == FOUR_STROKE_CAM_SENSOR) {
|
||||||
|
engineConfiguration->rpmMultiplier = 0.5;
|
||||||
|
} else if (mode == FOUR_STROKE_CRANK_SENSOR) {
|
||||||
|
engineConfiguration->rpmMultiplier = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
operation_mode_e getOperationMode( engine_configuration_s const *engineConfiguration) {
|
||||||
|
if(engineConfiguration->rpmMultiplier == 1)
|
||||||
|
return FOUR_STROKE_CRANK_SENSOR;
|
||||||
|
return FOUR_STROKE_CAM_SENSOR;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,6 @@
|
||||||
#include "crc.h"
|
#include "crc.h"
|
||||||
#include "sensor_types.h"
|
#include "sensor_types.h"
|
||||||
#include "can_header.h"
|
#include "can_header.h"
|
||||||
#include "event_registry.h"
|
|
||||||
#include "rusefi_enums.h"
|
#include "rusefi_enums.h"
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
@ -29,17 +28,12 @@ typedef struct {
|
||||||
short int crankingRpm;
|
short int crankingRpm;
|
||||||
} cranking_parameters_s;
|
} 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[2];
|
|
||||||
} EventHandlerConfiguration;
|
|
||||||
|
|
||||||
#define FUEL_RPM_COUNT 16
|
#define FUEL_RPM_COUNT 16
|
||||||
#define FUEL_LOAD_COUNT 16
|
#define FUEL_LOAD_COUNT 16
|
||||||
|
#define VE_RPM_COUNT 16
|
||||||
|
#define VE_LOAD_COUNT 16
|
||||||
|
#define AFR_RPM_COUNT 16
|
||||||
|
#define AFR_LOAD_COUNT 16
|
||||||
|
|
||||||
#define CLT_CURVE_SIZE 16
|
#define CLT_CURVE_SIZE 16
|
||||||
#define IAT_CURVE_SIZE 16
|
#define IAT_CURVE_SIZE 16
|
||||||
|
@ -115,6 +109,14 @@ typedef struct {
|
||||||
*/
|
*/
|
||||||
typedef struct {
|
typedef struct {
|
||||||
float injectorLag; // size 4, offset 0
|
float injectorLag; // size 4, offset 0
|
||||||
|
/**
|
||||||
|
* cc/min, cubic centimeter per minute
|
||||||
|
*
|
||||||
|
* By the way, g/s = 0.125997881 * (lb/hr)
|
||||||
|
* g/s = 0.125997881 * (cc/min)/10.5
|
||||||
|
* g/s = 0.0119997981 * cc/min
|
||||||
|
*
|
||||||
|
*/
|
||||||
float injectorFlow; // size 4, offset 4
|
float injectorFlow; // size 4, offset 4
|
||||||
float battInjectorLagCorrBins[VBAT_INJECTOR_CURVE_SIZE]; // size 32, offset 8
|
float battInjectorLagCorrBins[VBAT_INJECTOR_CURVE_SIZE]; // size 32, offset 8
|
||||||
float battInjectorLagCorr[VBAT_INJECTOR_CURVE_SIZE]; // size 32, offset 40
|
float battInjectorLagCorr[VBAT_INJECTOR_CURVE_SIZE]; // size 32, offset 40
|
||||||
|
@ -145,9 +147,8 @@ typedef struct {
|
||||||
float sparkDwellBins[DWELL_COUNT]; // offset 580
|
float sparkDwellBins[DWELL_COUNT]; // offset 580
|
||||||
float sparkDwell[DWELL_COUNT];
|
float sparkDwell[DWELL_COUNT];
|
||||||
|
|
||||||
float ignitionTable[IGN_LOAD_COUNT][IGN_RPM_COUNT];
|
float ignitionLoadBins[IGN_LOAD_COUNT];
|
||||||
float ignitionLoadBins[IGN_LOAD_COUNT]; // offset 3450
|
float ignitionRpmBins[IGN_RPM_COUNT];
|
||||||
float ignitionRpmBins[IGN_RPM_COUNT]; // offset 3542
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* this value could be used to offset the whole ignition timing table by a constant
|
* this value could be used to offset the whole ignition timing table by a constant
|
||||||
|
@ -170,12 +171,16 @@ typedef struct {
|
||||||
// WARNING: by default, our small enums are ONE BYTE. but if the are surrounded by non-enums - alignments do the trick
|
// 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;
|
engine_type_e engineType;
|
||||||
|
|
||||||
float fuelTable[FUEL_LOAD_COUNT][FUEL_RPM_COUNT]; // size 1024, offset 1816
|
float fuelLoadBins[FUEL_LOAD_COUNT]; //
|
||||||
float fuelLoadBins[FUEL_LOAD_COUNT]; // offset 2840
|
|
||||||
// RPM is float and not integer in order to use unified methods for interpolation
|
// RPM is float and not integer in order to use unified methods for interpolation
|
||||||
float fuelRpmBins[FUEL_RPM_COUNT]; // offset 3542
|
float fuelRpmBins[FUEL_RPM_COUNT]; //
|
||||||
|
|
||||||
int unused[3];
|
/**
|
||||||
|
* Engine displacement, in liters
|
||||||
|
* see also cylindersCount
|
||||||
|
*/
|
||||||
|
float displacement;
|
||||||
|
int unused[2];
|
||||||
|
|
||||||
injection_mode_e crankingInjectionMode;
|
injection_mode_e crankingInjectionMode;
|
||||||
injection_mode_e injectionMode;
|
injection_mode_e injectionMode;
|
||||||
|
@ -270,8 +275,24 @@ typedef struct {
|
||||||
float diffLoadEnrichmentCoef;
|
float diffLoadEnrichmentCoef;
|
||||||
|
|
||||||
air_pressure_sensor_config_s baroSensor;
|
air_pressure_sensor_config_s baroSensor;
|
||||||
|
|
||||||
|
float veLoadBins[VE_LOAD_COUNT];
|
||||||
|
float veRpmBins[VE_RPM_COUNT];
|
||||||
|
float afrLoadBins[AFR_LOAD_COUNT];
|
||||||
|
float afrRpmBins[AFR_RPM_COUNT];
|
||||||
|
|
||||||
|
// the large tables are always in the end - that's related to TunerStudio paging implementation
|
||||||
|
float fuelTable[FUEL_LOAD_COUNT][FUEL_RPM_COUNT]; // size 1024
|
||||||
|
float ignitionTable[IGN_LOAD_COUNT][IGN_RPM_COUNT]; // size 1024
|
||||||
|
|
||||||
|
float veTable[VE_LOAD_COUNT][VE_RPM_COUNT]; // size 1024
|
||||||
|
float afrTable[AFR_LOAD_COUNT][AFR_RPM_COUNT]; // size 1024
|
||||||
|
|
||||||
} engine_configuration_s;
|
} engine_configuration_s;
|
||||||
|
|
||||||
|
void setOperationMode(engine_configuration_s *engineConfiguration, operation_mode_e mode);
|
||||||
|
operation_mode_e getOperationMode(engine_configuration_s const *engineConfiguration);
|
||||||
|
|
||||||
#define HW_MAX_ADC_INDEX 16
|
#define HW_MAX_ADC_INDEX 16
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
@ -326,6 +347,14 @@ typedef struct {
|
||||||
brain_pin_e primaryLogicAnalyzerPin;
|
brain_pin_e primaryLogicAnalyzerPin;
|
||||||
brain_pin_e secondaryLogicAnalyzerPin;
|
brain_pin_e secondaryLogicAnalyzerPin;
|
||||||
|
|
||||||
|
int idleThreadPeriod;
|
||||||
|
int consoleLoopPeriod;
|
||||||
|
int lcdThreadPeriod;
|
||||||
|
int tunerStudioThreadPeriod;
|
||||||
|
int generalPeriodicThreadPeriod;
|
||||||
|
|
||||||
|
int tunerStudioSerialSpeed;
|
||||||
|
|
||||||
} board_configuration_s;
|
} board_configuration_s;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
@ -350,6 +379,7 @@ void setWholeFuelMap(engine_configuration_s *engineConfiguration, float value);
|
||||||
void setConstantDwell(engine_configuration_s *engineConfiguration, float dwellMs);
|
void setConstantDwell(engine_configuration_s *engineConfiguration, float dwellMs);
|
||||||
void printFloatArray(const char *prefix, float array[], int size);
|
void printFloatArray(const char *prefix, float array[], int size);
|
||||||
|
|
||||||
|
void setTriggerSynchronizationGap(engine_configuration_s *engineConfiguration, float synchGap);
|
||||||
|
|
||||||
void incrementGlobalConfigurationVersion(void);
|
void incrementGlobalConfigurationVersion(void);
|
||||||
int getGlobalConfigurationVersion(void);
|
int getGlobalConfigurationVersion(void);
|
||||||
|
|
|
@ -28,11 +28,17 @@ int warning(obd_code_e code, const char *fmt, ...);
|
||||||
* todo: better method name?
|
* todo: better method name?
|
||||||
*/
|
*/
|
||||||
void firmwareError(const char *fmt, ...);
|
void firmwareError(const char *fmt, ...);
|
||||||
bool_t hasFirmwareError(void);
|
bool hasFirmwareError(void);
|
||||||
|
|
||||||
bool_t hasFatalError(void);
|
/**
|
||||||
void fatal3(char *msg, char *file, int line);
|
* declared as a macro so that this code does not use stack
|
||||||
#define fatal(x) (fatal3(x, __FILE__, __LINE__));
|
* so that it would not crash the error handler in case of stack issues
|
||||||
|
*/
|
||||||
|
#if CH_DBG_SYSTEM_STATE_CHECK
|
||||||
|
#define hasFatalError() (dbg_panic_msg != NULL)
|
||||||
|
#else
|
||||||
|
#define hasFatalError() (FALSE)
|
||||||
|
#endif
|
||||||
|
|
||||||
void chDbgPanic3(const char *msg, const char * file, int line);
|
void chDbgPanic3(const char *msg, const char * file, int line);
|
||||||
|
|
||||||
|
@ -45,7 +51,10 @@ int getRusEfiVersion(void);
|
||||||
* @deprecated Global panic is inconvenient because it's hard to deliver the error message while whole instance
|
* @deprecated Global panic is inconvenient because it's hard to deliver the error message while whole instance
|
||||||
* is stopped. Please use firmwareWarning() instead
|
* is stopped. Please use firmwareWarning() instead
|
||||||
*/
|
*/
|
||||||
#define efiAssert(x, y) chDbgAssert(x, y, NULL)
|
#define efiAssert(condition, message, result) { if (!(condition)) { firmwareError(message); return result; } }
|
||||||
|
|
||||||
|
#define efiAssertVoid(condition, message) { if (!(condition)) { firmwareError(message); return; } }
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,61 +0,0 @@
|
||||||
/**
|
|
||||||
* @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() too many events");
|
|
||||||
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++]);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,34 @@
|
||||||
|
/**
|
||||||
|
* @file event_registry.cpp
|
||||||
|
* @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"
|
||||||
|
|
||||||
|
void registerActuatorEvent(ActuatorEventList *list, int eventIndex, OutputSignal *actuator, float angleOffset) {
|
||||||
|
ActuatorEvent *e = list->getNextActuatorEvent();
|
||||||
|
if (e == NULL)
|
||||||
|
return; // error already reported
|
||||||
|
e->position.eventIndex = eventIndex;
|
||||||
|
e->actuator = actuator;
|
||||||
|
e->position.angleOffset = angleOffset;
|
||||||
|
}
|
|
@ -13,24 +13,60 @@
|
||||||
|
|
||||||
#define MAX_EVENT_COUNT 40
|
#define MAX_EVENT_COUNT 40
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This structure defines an angle position within the trigger
|
||||||
|
*/
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
/**
|
||||||
|
* That's trigger event index
|
||||||
|
*/
|
||||||
int eventIndex;
|
int eventIndex;
|
||||||
OutputSignal *actuator;
|
float eventAngle;
|
||||||
|
/**
|
||||||
|
* Angle offset from the trigger event
|
||||||
|
*/
|
||||||
float angleOffset;
|
float angleOffset;
|
||||||
|
} event_trigger_position_s;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
event_trigger_position_s position;
|
||||||
|
OutputSignal *actuator;
|
||||||
|
scheduling_s signalTimer;
|
||||||
} ActuatorEvent;
|
} ActuatorEvent;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct IgnitionEvent_struct IgnitionEvent;
|
||||||
|
|
||||||
|
struct IgnitionEvent_struct {
|
||||||
|
ActuatorEvent actuator;
|
||||||
|
float advance;
|
||||||
|
event_trigger_position_s sparkPosition;
|
||||||
|
IgnitionEvent *next;
|
||||||
|
char *name;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class Type, int Dimention>
|
||||||
|
class ArrayList {
|
||||||
|
public:
|
||||||
int size;
|
int size;
|
||||||
ActuatorEvent events[MAX_EVENT_COUNT];
|
Type events[Dimention];
|
||||||
} ActuatorEventList;
|
void resetEventList(void);
|
||||||
|
Type *getNextActuatorEvent(void);
|
||||||
|
};
|
||||||
|
|
||||||
#ifdef __cplusplus
|
template <class Type, int Dimention>
|
||||||
extern "C"
|
void ArrayList< Type, Dimention>::resetEventList(void) {
|
||||||
{
|
size = 0;
|
||||||
#endif /* __cplusplus */
|
}
|
||||||
|
|
||||||
|
template <class Type, int Dimention>
|
||||||
|
Type * ArrayList< Type, Dimention>::getNextActuatorEvent(void) {
|
||||||
|
efiAssert(size < Dimention, "registerActuatorEvent() too many events", NULL);
|
||||||
|
return &events[size++];
|
||||||
|
}
|
||||||
|
|
||||||
void resetEventList(ActuatorEventList *list);
|
typedef ArrayList<ActuatorEvent, MAX_EVENT_COUNT> ActuatorEventList;
|
||||||
|
|
||||||
|
typedef ArrayList<IgnitionEvent, MAX_EVENT_COUNT> IgnitionEventList;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* this is an intermediate implementation of flexible event handling.
|
* this is an intermediate implementation of flexible event handling.
|
||||||
|
@ -42,11 +78,4 @@ void resetEventList(ActuatorEventList *list);
|
||||||
*/
|
*/
|
||||||
void registerActuatorEvent(ActuatorEventList *list, int eventIndex, OutputSignal *actuator, float angleOffset);
|
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_ */
|
#endif /* EVENT_REGISTRY_H_ */
|
||||||
|
|
|
@ -40,19 +40,17 @@
|
||||||
#include "accel_enrichment.h"
|
#include "accel_enrichment.h"
|
||||||
#endif /* EFI_ACCEL_ENRICHMENT */
|
#endif /* EFI_ACCEL_ENRICHMENT */
|
||||||
|
|
||||||
static float *fuel_ptrs[FUEL_LOAD_COUNT];
|
|
||||||
static int initialized = FALSE;
|
|
||||||
extern engine_configuration_s *engineConfiguration;
|
extern engine_configuration_s *engineConfiguration;
|
||||||
|
|
||||||
|
static Map3D1616 fuelMap;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Initialize fuel map data structure
|
* @brief Initialize fuel map data structure
|
||||||
* @note this method has nothing to do with fuel map VALUES - it's job
|
* @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
|
* is to prepare the fuel map data structure for 3d interpolation
|
||||||
*/
|
*/
|
||||||
void prepareFuelMap(void) {
|
void prepareFuelMap(void) {
|
||||||
for (int k = 0; k < FUEL_LOAD_COUNT; k++)
|
fuelMap.init(engineConfiguration->fuelTable);
|
||||||
fuel_ptrs[k] = engineConfiguration->fuelTable[k];
|
|
||||||
initialized = TRUE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -86,11 +84,9 @@ float getInjectorLag(float vBatt) {
|
||||||
}
|
}
|
||||||
|
|
||||||
float getBaseFuel(int rpm, float engineLoad) {
|
float getBaseFuel(int rpm, float engineLoad) {
|
||||||
chDbgCheck(initialized, "fuel map initialized");
|
efiAssert(!cisnan(engineLoad), "invalid el", NAN);
|
||||||
efiAssert(!cisnan(engineLoad), "invalid el");
|
return fuelMap.getValue(engineLoad, engineConfiguration->fuelLoadBins, rpm,
|
||||||
efiAssert(!cisnan(engineLoad), "invalid rpm");
|
engineConfiguration->fuelRpmBins);
|
||||||
return interpolate3d(engineLoad, engineConfiguration->fuelLoadBins, FUEL_LOAD_COUNT, rpm,
|
|
||||||
engineConfiguration->fuelRpmBins, FUEL_RPM_COUNT, fuel_ptrs);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
float getCrankingFuel(void) {
|
float getCrankingFuel(void) {
|
||||||
|
@ -157,7 +153,7 @@ inline static int getElectricalValue1(pin_output_mode_e mode) {
|
||||||
|
|
||||||
// todo: this method is here for unit test visibility. todo: move to a bette place!
|
// todo: this method is here for unit test visibility. todo: move to a bette place!
|
||||||
int getElectricalValue(int logicalValue, pin_output_mode_e mode) {
|
int getElectricalValue(int logicalValue, pin_output_mode_e mode) {
|
||||||
chDbgCheck(mode <= OM_OPENDRAIN_INVERTED, "invalid pin_output_mode_e");
|
efiAssert(mode <= OM_OPENDRAIN_INVERTED, "invalid pin_output_mode_e", -1);
|
||||||
|
|
||||||
return logicalValue ? getElectricalValue1(mode) : getElectricalValue0(mode);
|
return logicalValue ? getElectricalValue1(mode) : getElectricalValue0(mode);
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
#define GPIO_NULL NULL
|
#define GPIO_NULL NULL
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
LED_CRANKING, // Orange on-board LED
|
LED_WARNING, // Orange on-board LED
|
||||||
LED_RUNNING, // Green on-board LED
|
LED_RUNNING, // Green on-board LED
|
||||||
LED_ERROR, // Red on-board LED
|
LED_ERROR, // Red on-board LED
|
||||||
LED_COMMUNICATION_1, // Blue on-board LED
|
LED_COMMUNICATION_1, // Blue on-board LED
|
||||||
|
|
|
@ -15,14 +15,31 @@
|
||||||
#define MAX_INJECTOR_COUNT 12
|
#define MAX_INJECTOR_COUNT 12
|
||||||
#define MAX_IGNITER_COUNT 4
|
#define MAX_IGNITER_COUNT 4
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
#include "engine_configuration.h"
|
||||||
|
#include "ec2.h"
|
||||||
|
#include "event_registry.h"
|
||||||
|
class MainTriggerCallback {
|
||||||
|
public:
|
||||||
|
// MainTriggerCallback();
|
||||||
|
void init(engine_configuration_s *engineConfiguration, engine_configuration2_s *engineConfiguration2);
|
||||||
|
|
||||||
|
engine_configuration_s *engineConfiguration;
|
||||||
|
engine_configuration2_s *engineConfiguration2;
|
||||||
|
|
||||||
|
};
|
||||||
|
void initMainEventListener(engine_configuration_s *engineConfiguration, engine_configuration2_s *engineConfiguration2);
|
||||||
|
void onTriggerEvent(trigger_event_e ckpSignalType, int eventIndex, MainTriggerCallback *mainTriggerCallback);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C"
|
extern "C"
|
||||||
{
|
{
|
||||||
#endif /* __cplusplus */
|
#endif /* __cplusplus */
|
||||||
|
|
||||||
#include "event_registry.h"
|
|
||||||
|
|
||||||
void initMainEventListener(void);
|
|
||||||
void showMainHistogram(void);
|
void showMainHistogram(void);
|
||||||
void onEveryMillisecondTimerSignal(void);
|
void onEveryMillisecondTimerSignal(void);
|
||||||
int isIgnitionTimingError(void);
|
int isIgnitionTimingError(void);
|
||||||
|
|
|
@ -55,6 +55,6 @@ void getErrorCodes(error_codes_set_s * copy) {
|
||||||
copy->error_codes[i] = error_codes_set.error_codes[i];
|
copy->error_codes[i] = error_codes_set.error_codes[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
bool_t hasErrorCodes(void) {
|
bool hasErrorCodes(void) {
|
||||||
return error_codes_set.count > 0;
|
return error_codes_set.count > 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,11 +48,10 @@ void setError(int flag, obd_code_e errorCode);
|
||||||
*/
|
*/
|
||||||
void getErrorCodes(error_codes_set_s * buffer);
|
void getErrorCodes(error_codes_set_s * buffer);
|
||||||
|
|
||||||
bool_t hasErrorCodes(void);
|
bool hasErrorCodes(void);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif /* __cplusplus */
|
#endif /* __cplusplus */
|
||||||
|
|
||||||
|
|
||||||
#endif /* MALFUNCTION_CENTRAL_H_ */
|
#endif /* MALFUNCTION_CENTRAL_H_ */
|
||||||
|
|
|
@ -97,7 +97,7 @@ typedef enum {
|
||||||
SHAFT_PRIMARY_DOWN = 1,
|
SHAFT_PRIMARY_DOWN = 1,
|
||||||
SHAFT_SECONDARY_UP = 2,
|
SHAFT_SECONDARY_UP = 2,
|
||||||
SHAFT_SECONDARY_DOWN = 3,
|
SHAFT_SECONDARY_DOWN = 3,
|
||||||
} ShaftEvents;
|
} trigger_event_e;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This enum is used to select your desired Engine Load calculation algorithm
|
* This enum is used to select your desired Engine Load calculation algorithm
|
||||||
|
@ -179,6 +179,14 @@ typedef enum {
|
||||||
Internal_ForceMyEnumIntSize_firing_order = ENUM_SIZE_HACK,
|
Internal_ForceMyEnumIntSize_firing_order = ENUM_SIZE_HACK,
|
||||||
} firing_order_e;
|
} firing_order_e;
|
||||||
|
|
||||||
|
// todo: better enum name
|
||||||
|
typedef enum {
|
||||||
|
FOUR_STROKE_CRANK_SENSOR = 0,
|
||||||
|
FOUR_STROKE_CAM_SENSOR = 1,
|
||||||
|
|
||||||
|
Internal_ForceMyEnumIntSize_operation_mode_e = ENUM_SIZE_HACK,
|
||||||
|
} operation_mode_e;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Ignition Mode
|
* @brief Ignition Mode
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -56,12 +56,10 @@ void initOutputSignal(OutputSignal *signal, io_pin_e ioPin) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void initOutputSignalBase(OutputSignal *signal) {
|
void initOutputSignalBase(OutputSignal *signal) {
|
||||||
signal->status = IDLE;
|
|
||||||
// signal->last_scheduling_time = 0;
|
|
||||||
signal->initialized = TRUE;
|
signal->initialized = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void turnHigh(OutputSignal *signal) {
|
void turnPinHigh(OutputSignal *signal) {
|
||||||
#if EFI_DEFAILED_LOGGING
|
#if EFI_DEFAILED_LOGGING
|
||||||
// signal->hi_time = hTimeNow();
|
// signal->hi_time = hTimeNow();
|
||||||
#endif /* EFI_DEFAILED_LOGGING */
|
#endif /* EFI_DEFAILED_LOGGING */
|
||||||
|
@ -85,7 +83,7 @@ static void turnHigh(OutputSignal *signal) {
|
||||||
#endif /* EFI_WAVE_ANALYZER */
|
#endif /* EFI_WAVE_ANALYZER */
|
||||||
}
|
}
|
||||||
|
|
||||||
static void turnLow(OutputSignal *signal) {
|
void turnPinLow(OutputSignal *signal) {
|
||||||
// turn off the output
|
// turn off the output
|
||||||
// todo: this XOR should go inside the setOutputPinValue method
|
// todo: this XOR should go inside the setOutputPinValue method
|
||||||
setOutputPinValue(signal->io_pin, FALSE);
|
setOutputPinValue(signal->io_pin, FALSE);
|
||||||
|
@ -126,8 +124,8 @@ void scheduleOutput(OutputSignal *signal, float delayMs, float durationMs) {
|
||||||
scheduling_s * sUp = &signal->signalTimerUp[index];
|
scheduling_s * sUp = &signal->signalTimerUp[index];
|
||||||
scheduling_s * sDown = &signal->signalTimerDown[index];
|
scheduling_s * sDown = &signal->signalTimerDown[index];
|
||||||
|
|
||||||
scheduleTask(sUp, (int)MS2US(delayMs), (schfunc_t) &turnHigh, (void *) signal);
|
scheduleTask(sUp, (int)MS2US(delayMs), (schfunc_t) &turnPinHigh, (void *) signal);
|
||||||
scheduleTask(sDown, (int)MS2US(delayMs + durationMs), (schfunc_t) &turnLow, (void*) signal);
|
scheduleTask(sDown, (int)MS2US(delayMs + durationMs), (schfunc_t) &turnPinLow, (void*) signal);
|
||||||
|
|
||||||
// signal->last_scheduling_time = now;
|
// signal->last_scheduling_time = now;
|
||||||
}
|
}
|
||||||
|
@ -137,7 +135,7 @@ void scheduleOutputBase(OutputSignal *signal, float delayMs, float durationMs) {
|
||||||
* it's better to check for the exact 'TRUE' value since otherwise
|
* it's better to check for the exact 'TRUE' value since otherwise
|
||||||
* we would accept any memory garbage
|
* we would accept any memory garbage
|
||||||
*/
|
*/
|
||||||
chDbgCheck(signal->initialized == TRUE, "Signal not initialized");
|
efiAssertVoid(signal->initialized == TRUE, "Signal not initialized");
|
||||||
// signal->offset = offset;
|
// signal->offset = offset;
|
||||||
// signal->duration = duration;
|
// signal->duration = duration;
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,10 +23,6 @@
|
||||||
#include "signal_executor_sleep.h"
|
#include "signal_executor_sleep.h"
|
||||||
#endif /* EFI_SIGNAL_EXECUTOR_SLEEP */
|
#endif /* EFI_SIGNAL_EXECUTOR_SLEEP */
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
IDLE = 0, ACTIVE
|
|
||||||
} executor_status_t;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Asynchronous output signal data structure
|
* @brief Asynchronous output signal data structure
|
||||||
*/
|
*/
|
||||||
|
@ -40,19 +36,14 @@ struct OutputSignal_struct {
|
||||||
int initialized;
|
int initialized;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* We are alternating instances so that events which extend into next revolution are not overriden while
|
* We are alternating instances so that events which extend into next revolution are not reused while
|
||||||
* scheduling next revolution events
|
* scheduling next revolution events
|
||||||
*/
|
*/
|
||||||
scheduling_s signalTimerUp[2];
|
scheduling_s signalTimerUp[2];
|
||||||
scheduling_s signalTimerDown[2];
|
scheduling_s signalTimerDown[2];
|
||||||
|
|
||||||
executor_status_t status;
|
scheduling_s triggerEvent;
|
||||||
|
float angleOffsetParam;
|
||||||
#if EFI_SIGNAL_EXECUTOR_HW_TIMER
|
|
||||||
// todo
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// OutputSignal *next;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
@ -65,6 +56,9 @@ void scheduleOutput(OutputSignal *signal, float delayMs, float durationMs);
|
||||||
void initOutputSignalBase(OutputSignal *signal);
|
void initOutputSignalBase(OutputSignal *signal);
|
||||||
void scheduleOutputBase(OutputSignal *signal, float delayMs, float durationMs);
|
void scheduleOutputBase(OutputSignal *signal, float delayMs, float durationMs);
|
||||||
|
|
||||||
|
void turnPinHigh(OutputSignal *signal);
|
||||||
|
void turnPinLow(OutputSignal *signal);
|
||||||
|
|
||||||
void initSignalExecutor(void);
|
void initSignalExecutor(void);
|
||||||
void initSignalExecutorImpl(void);
|
void initSignalExecutorImpl(void);
|
||||||
void scheduleByAngle(scheduling_s *timer, float angle, schfunc_t callback, void *param);
|
void scheduleByAngle(scheduling_s *timer, float angle, schfunc_t callback, void *param);
|
||||||
|
|
|
@ -40,9 +40,11 @@
|
||||||
*/
|
*/
|
||||||
#if EFI_PROD_CODE
|
#if EFI_PROD_CODE
|
||||||
static volatile int chartSize = 100;
|
static volatile int chartSize = 100;
|
||||||
|
#define WAVE_LOGGING_SIZE 5000
|
||||||
#else
|
#else
|
||||||
// need more events for automated test
|
// need more events for automated test
|
||||||
static volatile int chartSize = 200;
|
static volatile int chartSize = 400;
|
||||||
|
#define WAVE_LOGGING_SIZE 35000
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static int isChartActive = TRUE;
|
static int isChartActive = TRUE;
|
||||||
|
@ -65,11 +67,7 @@ void resetWaveChart(WaveChart *chart) {
|
||||||
appendPrintf(&chart->logging, "wave_chart%s", DELIMETER);
|
appendPrintf(&chart->logging, "wave_chart%s", DELIMETER);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined __GNUC__
|
static char WAVE_LOGGING_BUFFER[WAVE_LOGGING_SIZE] CCM_OPTIONAL;
|
||||||
static char WAVE_LOGGING_BUFFER[5000] __attribute__((section(".ccm")));
|
|
||||||
#else
|
|
||||||
static char WAVE_LOGGING_BUFFER[5000];
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static void printStatus(void) {
|
static void printStatus(void) {
|
||||||
scheduleIntValue(&logger, "chart", isChartActive);
|
scheduleIntValue(&logger, "chart", isChartActive);
|
||||||
|
@ -113,13 +111,13 @@ void publishChart(WaveChart *chart) {
|
||||||
* @brief Register a change in sniffed signal
|
* @brief Register a change in sniffed signal
|
||||||
*/
|
*/
|
||||||
void addWaveChartEvent3(WaveChart *chart, const char *name, const char * msg, const char * msg2) {
|
void addWaveChartEvent3(WaveChart *chart, const char *name, const char * msg, const char * msg2) {
|
||||||
chDbgCheck(chart->isInitialized, "chart not initialized");
|
efiAssertVoid(chart->isInitialized, "chart not initialized");
|
||||||
#if DEBUG_WAVE
|
#if DEBUG_WAVE
|
||||||
scheduleSimpleMsg(&debugLogging, "current", chart->counter);
|
scheduleSimpleMsg(&debugLogging, "current", chart->counter);
|
||||||
#endif
|
#endif
|
||||||
if (isWaveChartFull(chart))
|
if (isWaveChartFull(chart))
|
||||||
return;
|
return;
|
||||||
bool_t alreadyLocked = lockOutputBuffer(); // we have multiple threads writing to the same output buffer
|
bool alreadyLocked = lockOutputBuffer(); // we have multiple threads writing to the same output buffer
|
||||||
appendPrintf(&chart->logging, "%s%s%s%s", name, CHART_DELIMETER, msg, CHART_DELIMETER);
|
appendPrintf(&chart->logging, "%s%s%s%s", name, CHART_DELIMETER, msg, CHART_DELIMETER);
|
||||||
int time100 = getTimeNowUs() / 10;
|
int time100 = getTimeNowUs() / 10;
|
||||||
appendPrintf(&chart->logging, "%d%s%s", time100, msg2, CHART_DELIMETER);
|
appendPrintf(&chart->logging, "%d%s%s", time100, msg2, CHART_DELIMETER);
|
||||||
|
|
|
@ -24,7 +24,7 @@ extern board_configuration_s *boardConfiguration;
|
||||||
|
|
||||||
static PwmConfig alternatorControl;
|
static PwmConfig alternatorControl;
|
||||||
|
|
||||||
static WORKING_AREA(ivThreadStack, UTILITY_THREAD_STACK_SIZE);
|
static THD_WORKING_AREA(ivThreadStack, UTILITY_THREAD_STACK_SIZE);
|
||||||
|
|
||||||
static msg_t AltCtrlThread(int param) {
|
static msg_t AltCtrlThread(int param) {
|
||||||
chRegSetThreadName("AlternatorController");
|
chRegSetThreadName("AlternatorController");
|
||||||
|
|
|
@ -2,12 +2,12 @@
|
||||||
CONTROLLERSSRC = \
|
CONTROLLERSSRC = \
|
||||||
controllers/ignition_central.c \
|
controllers/ignition_central.c \
|
||||||
$(PROJECT_DIR)/controllers/malfunction_indicator.c \
|
$(PROJECT_DIR)/controllers/malfunction_indicator.c \
|
||||||
$(PROJECT_DIR)/controllers/error_handling.c \
|
$(PROJECT_DIR)/controllers/error_handling.c
|
||||||
controllers/map_averaging.c \
|
|
||||||
controllers/map_multiplier_thread.c
|
|
||||||
|
|
||||||
CONTROLLERS_SRC_CPP = $(PROJECT_DIR)/controllers/settings.cpp \
|
CONTROLLERS_SRC_CPP = $(PROJECT_DIR)/controllers/settings.cpp \
|
||||||
controllers/electronic_throttle.cpp \
|
controllers/electronic_throttle.cpp \
|
||||||
|
controllers/map_averaging.cpp \
|
||||||
|
controllers/map_multiplier_thread.cpp \
|
||||||
controllers/flash_main.cpp \
|
controllers/flash_main.cpp \
|
||||||
controllers/injector_central.cpp \
|
controllers/injector_central.cpp \
|
||||||
controllers/idle_thread.cpp \
|
controllers/idle_thread.cpp \
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
|
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
#include "EfiWave.h"
|
#include "EfiWave.h"
|
||||||
|
#include "trigger_structure.h"
|
||||||
|
|
||||||
single_wave_s::single_wave_s() {
|
single_wave_s::single_wave_s() {
|
||||||
init(NULL);
|
init(NULL);
|
||||||
|
@ -20,16 +21,40 @@ void single_wave_s::init(int *pinStates) {
|
||||||
this->pinStates = pinStates;
|
this->pinStates = pinStates;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
multi_wave_s::multi_wave_s() {
|
||||||
|
}
|
||||||
|
|
||||||
multi_wave_s::multi_wave_s(float *switchTimes, single_wave_s *waves) {
|
multi_wave_s::multi_wave_s(float *switchTimes, single_wave_s *waves) {
|
||||||
|
init(switchTimes, waves);
|
||||||
|
}
|
||||||
|
|
||||||
|
void multi_wave_s::init(float *switchTimes, single_wave_s *waves) {
|
||||||
this->switchTimes = switchTimes;
|
this->switchTimes = switchTimes;
|
||||||
this->waves = waves;
|
this->waves = waves;
|
||||||
}
|
}
|
||||||
|
|
||||||
void multi_wave_s::reset(void) {
|
void multi_wave_s::reset(void) {
|
||||||
phaseCount = 0;
|
|
||||||
waveCount = 0;
|
waveCount = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float multi_wave_s::getAngle(int index, engine_configuration_s const *engineConfiguration, trigger_shape_s * s) const {
|
||||||
|
if (getOperationMode(engineConfiguration) == FOUR_STROKE_CAM_SENSOR)
|
||||||
|
return getSwitchTime(index) * 720.0;
|
||||||
|
/**
|
||||||
|
* FOUR_STROKE_CRANK_SENSOR magic:
|
||||||
|
* We have two crank shaft revolutions for each engine cycle
|
||||||
|
* See also trigger_central.cpp
|
||||||
|
* See also getEngineCycleEventCount()
|
||||||
|
*/
|
||||||
|
int triggerEventCounter = s->getSize();
|
||||||
|
|
||||||
|
if (index < triggerEventCounter) {
|
||||||
|
return getSwitchTime(index) * 360.0;
|
||||||
|
} else {
|
||||||
|
return 360 + getSwitchTime(index - triggerEventCounter) * 360.0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
float multi_wave_s::getSwitchTime(int index) const {
|
float multi_wave_s::getSwitchTime(int index) const {
|
||||||
return switchTimes[index];
|
return switchTimes[index];
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,9 @@
|
||||||
#ifndef EFI_WAVE_H_
|
#ifndef EFI_WAVE_H_
|
||||||
#define EFI_WAVE_H_
|
#define EFI_WAVE_H_
|
||||||
|
|
||||||
#define PWM_PHASE_MAX_COUNT 150
|
#include "engine_configuration.h"
|
||||||
|
|
||||||
|
#define PWM_PHASE_MAX_COUNT 250
|
||||||
#define PWM_PHASE_MAX_WAVE_PER_PWM 2
|
#define PWM_PHASE_MAX_WAVE_PER_PWM 2
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -21,18 +23,19 @@ public:
|
||||||
int *pinStates;
|
int *pinStates;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class trigger_shape_s;
|
||||||
|
|
||||||
class multi_wave_s {
|
class multi_wave_s {
|
||||||
public:
|
public:
|
||||||
|
multi_wave_s();
|
||||||
multi_wave_s(float *st, single_wave_s *waves);
|
multi_wave_s(float *st, single_wave_s *waves);
|
||||||
|
void init(float *st, single_wave_s *waves);
|
||||||
void reset(void);
|
void reset(void);
|
||||||
float getSwitchTime(int phaseIndex) const;
|
float getSwitchTime(int phaseIndex) const;
|
||||||
|
float getAngle(int phaseIndex, engine_configuration_s const *engineConfiguration, trigger_shape_s * s) const;
|
||||||
void setSwitchTime(int phaseIndex, float value);
|
void setSwitchTime(int phaseIndex, float value);
|
||||||
void checkSwitchTimes(int size);
|
void checkSwitchTimes(int size);
|
||||||
int getChannelState(int channelIndex, int phaseIndex) const;
|
int getChannelState(int channelIndex, int phaseIndex) const;
|
||||||
/**
|
|
||||||
* Number of events in the cycle
|
|
||||||
*/
|
|
||||||
int phaseCount;
|
|
||||||
/**
|
/**
|
||||||
* Number of signal wires
|
* Number of signal wires
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
|
|
||||||
CONTROLLERS_CORE_SRC = $(PROJECT_DIR)/controllers/core/interpolation.c \
|
CONTROLLERS_CORE_SRC = $(PROJECT_DIR)/controllers/core/avg_values.c
|
||||||
$(PROJECT_DIR)/controllers/core/avg_values.c
|
|
||||||
|
|
||||||
CONTROLLERS_CORE_SRC_CPP = $(PROJECT_DIR)/controllers/core/EfiWave.cpp
|
CONTROLLERS_CORE_SRC_CPP = $(PROJECT_DIR)/controllers/core/EfiWave.cpp \
|
||||||
|
$(PROJECT_DIR)/controllers/core/interpolation.cpp \
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/**
|
/**
|
||||||
* @file interpolation.c
|
* @file interpolation.cpp
|
||||||
* @brief Linear interpolation algorithms
|
* @brief Linear interpolation algorithms
|
||||||
*
|
*
|
||||||
* @date Oct 17, 2013
|
* @date Oct 17, 2013
|
||||||
|
@ -14,12 +14,30 @@
|
||||||
|
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
#include "interpolation.h"
|
#include "interpolation.h"
|
||||||
//#include "engine_math.h"
|
|
||||||
|
|
||||||
#define INTERPOLATION_A(x1, y1, x2, y2) ((y1 - y2) / (x1 - x2))
|
#define INTERPOLATION_A(x1, y1, x2, y2) ((y1 - y2) / (x1 - x2))
|
||||||
|
|
||||||
int needInterpolationLogging = TRUE;
|
int needInterpolationLogging = TRUE;
|
||||||
|
|
||||||
|
|
||||||
|
FastInterpolation::FastInterpolation(float x1, float y1, float x2, float y2) {
|
||||||
|
init(x1, y1, x2, y2);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FastInterpolation::init(float x1, float y1, float x2, float y2) {
|
||||||
|
if (x1 == x2) {
|
||||||
|
firmwareError("Same x1 and x2 in interpolate: %f/%f", x1, x2);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
a = INTERPOLATION_A(x1, y1, x2, y2);
|
||||||
|
b = y1 - a * x1;
|
||||||
|
}
|
||||||
|
|
||||||
|
float FastInterpolation::getValue(float x) {
|
||||||
|
return a * x + b;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/** @brief Linear interpolation by two points
|
/** @brief Linear interpolation by two points
|
||||||
*
|
*
|
||||||
* @param x1 key of the first point
|
* @param x1 key of the first point
|
||||||
|
@ -39,7 +57,7 @@ float interpolate(float x1, float y1, float x2, float y2, float x) {
|
||||||
|
|
||||||
// a*x1 + b = y1
|
// a*x1 + b = y1
|
||||||
// a*x2 + b = y2
|
// a*x2 + b = y2
|
||||||
// chDbgCheck(x1 != x2, "no way we can interpolate");
|
// efiAssertVoid(x1 != x2, "no way we can interpolate");
|
||||||
float a = INTERPOLATION_A(x1, y1, x2, y2);
|
float a = INTERPOLATION_A(x1, y1, x2, y2);
|
||||||
float b = y1 - a * x1;
|
float b = y1 - a * x1;
|
||||||
float result = a * x + b;
|
float result = a * x + b;
|
||||||
|
@ -55,8 +73,7 @@ float interpolate(float x1, float y1, float x2, float y2, float x) {
|
||||||
* @note If the parameter is smaller than the first element of the array, -1 is returned.
|
* @note If the parameter is smaller than the first element of the array, -1 is returned.
|
||||||
*/
|
*/
|
||||||
int findIndex(float array[], int size, float value) {
|
int findIndex(float array[], int size, float value) {
|
||||||
if (cisnan(value))
|
efiAssert(!cisnan(value), "NaN in findIndex", 0);
|
||||||
fatal("NaN in findIndex\r\n");
|
|
||||||
|
|
||||||
if (value < array[0])
|
if (value < array[0])
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -67,7 +84,7 @@ int findIndex(float array[], int size, float value) {
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
if (size-- == 0)
|
if (size-- == 0)
|
||||||
fatal("Unexpected state in binary search.");
|
efiAssert(FALSE, "Unexpected state in binary search", 0);
|
||||||
|
|
||||||
middle = (left + right) / 2;
|
middle = (left + right) / 2;
|
||||||
|
|
|
@ -8,19 +8,19 @@
|
||||||
#ifndef INTERPOLATION_3D_H_
|
#ifndef INTERPOLATION_3D_H_
|
||||||
#define INTERPOLATION_3D_H_
|
#define INTERPOLATION_3D_H_
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C"
|
|
||||||
{
|
|
||||||
#endif /* __cplusplus */
|
|
||||||
|
|
||||||
int findIndex(float array[], int size, float value);
|
int findIndex(float array[], int size, float value);
|
||||||
float interpolate(float x1, float y1, float x2, float y2, float x);
|
float interpolate(float x1, float y1, float x2, float y2, float x);
|
||||||
float interpolate2d(float value, float bin[], float values[], int size);
|
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[]);
|
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);
|
void setTableValue(float bins[], float values[], int size, float key, float value);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
class FastInterpolation {
|
||||||
}
|
public:
|
||||||
#endif /* __cplusplus */
|
FastInterpolation(float x1, float y1, float x2, float y2);
|
||||||
|
void init(float x1, float y1, float x2, float y2);
|
||||||
|
float getValue(float x);
|
||||||
|
private:
|
||||||
|
float a, b;
|
||||||
|
};
|
||||||
|
|
||||||
#endif /* INTERPOLATION_3D_H_ */
|
#endif /* INTERPOLATION_3D_H_ */
|
||||||
|
|
|
@ -38,11 +38,11 @@ static Logging logger;
|
||||||
/**
|
/**
|
||||||
* @brief Control Thread stack
|
* @brief Control Thread stack
|
||||||
*/
|
*/
|
||||||
static WORKING_AREA(etbTreadStack, UTILITY_THREAD_STACK_SIZE);
|
static THD_WORKING_AREA(etbTreadStack, UTILITY_THREAD_STACK_SIZE);
|
||||||
/**
|
/**
|
||||||
* @brief Pulse-Width Modulation state
|
* @brief Pulse-Width Modulation state
|
||||||
*/
|
*/
|
||||||
static PwmConfig etbPwm;
|
static SimplePwm etbPwm;
|
||||||
|
|
||||||
static float prevTps;
|
static float prevTps;
|
||||||
|
|
||||||
|
@ -69,7 +69,7 @@ static msg_t etbThread(void *arg) {
|
||||||
static void setThrottleConsole(int level) {
|
static void setThrottleConsole(int level) {
|
||||||
scheduleMsg(&logger, "setting throttle=%d", level);
|
scheduleMsg(&logger, "setting throttle=%d", level);
|
||||||
|
|
||||||
etbPwm.multiWave.switchTimes[0] = 0.01 + (min(level, 98)) / 100.0;
|
etbPwm.multiWave.switchTimes[0] = 0.01 + (minI(level, 98)) / 100.0;
|
||||||
print("st = %f\r\n", etbPwm.multiWave.switchTimes[0]);
|
print("st = %f\r\n", etbPwm.multiWave.switchTimes[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -84,11 +84,11 @@ void initElectronicThrottle(void) {
|
||||||
// outputPinRegister("etb2", ELECTRONIC_THROTTLE_CONTROL_2, ETB_CONTROL_LINE_2_PORT, ETB_CONTROL_LINE_2_PIN);
|
// outputPinRegister("etb2", ELECTRONIC_THROTTLE_CONTROL_2, ETB_CONTROL_LINE_2_PORT, ETB_CONTROL_LINE_2_PIN);
|
||||||
|
|
||||||
// this line used for PWM
|
// this line used for PWM
|
||||||
startSimplePwm(&etbPwm, "etb",
|
startSimplePwmExt(&etbPwm, "etb",
|
||||||
boardConfiguration->electronicThrottlePin1,
|
boardConfiguration->electronicThrottlePin1,
|
||||||
ELECTRONIC_THROTTLE_CONTROL_1,
|
ELECTRONIC_THROTTLE_CONTROL_1,
|
||||||
0.80,
|
500,
|
||||||
500);
|
0.80);
|
||||||
|
|
||||||
addConsoleActionI("e", setThrottleConsole);
|
addConsoleActionI("e", setThrottleConsole);
|
||||||
chThdCreateStatic(etbTreadStack, sizeof(etbTreadStack), NORMALPRIO, (tfunc_t) etbThread, NULL);
|
chThdCreateStatic(etbTreadStack, sizeof(etbTreadStack), NORMALPRIO, (tfunc_t) etbThread, NULL);
|
||||||
|
|
|
@ -50,15 +50,11 @@
|
||||||
#include "efilib2.h"
|
#include "efilib2.h"
|
||||||
#include "ec2.h"
|
#include "ec2.h"
|
||||||
#include "PwmTester.h"
|
#include "PwmTester.h"
|
||||||
|
#include "engine.h"
|
||||||
|
|
||||||
|
extern board_configuration_s *boardConfiguration;
|
||||||
|
|
||||||
#define _10_MILLISECONDS (10 * TICKS_IN_MS)
|
persistent_config_container_s persistentState CCM_OPTIONAL;
|
||||||
|
|
||||||
#if defined __GNUC__
|
|
||||||
persistent_config_container_s persistentState __attribute__((section(".ccm")));
|
|
||||||
#else
|
|
||||||
persistent_config_container_s persistentState;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
engine_configuration_s *engineConfiguration = &persistentState.persistentConfiguration.engineConfiguration;
|
engine_configuration_s *engineConfiguration = &persistentState.persistentConfiguration.engineConfiguration;
|
||||||
board_configuration_s *boardConfiguration = &persistentState.persistentConfiguration.boardConfiguration;
|
board_configuration_s *boardConfiguration = &persistentState.persistentConfiguration.boardConfiguration;
|
||||||
|
@ -73,11 +69,18 @@ static VirtualTimer fuelPumpTimer;
|
||||||
|
|
||||||
static Logging logger;
|
static Logging logger;
|
||||||
|
|
||||||
static engine_configuration2_s ec2;
|
static engine_configuration2_s ec2 CCM_OPTIONAL;
|
||||||
engine_configuration2_s * engineConfiguration2 = &ec2;
|
engine_configuration2_s * engineConfiguration2 = &ec2;
|
||||||
|
|
||||||
|
static configuration_s cfg = {&persistentState.persistentConfiguration.engineConfiguration, &ec2};
|
||||||
|
|
||||||
|
configuration_s * configuration = &cfg;
|
||||||
|
|
||||||
|
Engine engine;
|
||||||
|
|
||||||
static msg_t csThread(void) {
|
static msg_t csThread(void) {
|
||||||
chRegSetThreadName("status");
|
chRegSetThreadName("status");
|
||||||
|
#if EFI_SHAFT_POSITION_INPUT
|
||||||
while (TRUE) {
|
while (TRUE) {
|
||||||
int is_cranking = isCranking();
|
int is_cranking = isCranking();
|
||||||
int is_running = getRpm() > 0 && !is_cranking;
|
int is_running = getRpm() > 0 && !is_cranking;
|
||||||
|
@ -93,6 +96,8 @@ static msg_t csThread(void) {
|
||||||
chThdSleepMilliseconds(100);
|
chThdSleepMilliseconds(100);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif /* EFI_SHAFT_POSITION_INPUT */
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void updateErrorCodes(void) {
|
static void updateErrorCodes(void) {
|
||||||
|
@ -129,14 +134,12 @@ static void fanRelayControl(void) {
|
||||||
Overflow64Counter halTime;
|
Overflow64Counter halTime;
|
||||||
|
|
||||||
uint64_t getTimeNowUs(void) {
|
uint64_t getTimeNowUs(void) {
|
||||||
// todo: synchronization? multi-threading?
|
return halTime.get(hal_lld_get_counter_value(), false) / (CORE_CLOCK / 1000000);
|
||||||
halTime.offer(hal_lld_get_counter_value());
|
|
||||||
return halTime.get() / (CORE_CLOCK / 1000000);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t getHalTimer(void) {
|
//uint64_t getHalTimer(void) {
|
||||||
return halTime.get();
|
// return halTime.get();
|
||||||
}
|
//}
|
||||||
|
|
||||||
efitimems_t currentTimeMillis(void) {
|
efitimems_t currentTimeMillis(void) {
|
||||||
// todo: migrate to getTimeNowUs? or not?
|
// todo: migrate to getTimeNowUs? or not?
|
||||||
|
@ -147,23 +150,23 @@ int getTimeNowSeconds(void) {
|
||||||
return chTimeNow() / CH_FREQUENCY;
|
return chTimeNow() / CH_FREQUENCY;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void onEveny10Milliseconds(void *arg) {
|
static void onEvenyGeneralMilliseconds(void *arg) {
|
||||||
/**
|
/**
|
||||||
* We need to push current value into the 64 bit counter often enough so that we do not miss an overflow
|
* We need to push current value into the 64 bit counter often enough so that we do not miss an overflow
|
||||||
*/
|
*/
|
||||||
halTime.offer(hal_lld_get_counter_value());
|
halTime.get(hal_lld_get_counter_value(), true);
|
||||||
|
|
||||||
updateErrorCodes();
|
updateErrorCodes();
|
||||||
|
|
||||||
fanRelayControl();
|
fanRelayControl();
|
||||||
|
|
||||||
// schedule next invocation
|
// schedule next invocation
|
||||||
chVTSetAny(&everyMsTimer, _10_MILLISECONDS, &onEveny10Milliseconds, 0);
|
chVTSetAny(&everyMsTimer, boardConfiguration->generalPeriodicThreadPeriod * TICKS_IN_MS, &onEvenyGeneralMilliseconds, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void initPeriodicEvents(void) {
|
static void initPeriodicEvents(void) {
|
||||||
// schedule first invocation
|
// schedule first invocation
|
||||||
chVTSetAny(&everyMsTimer, _10_MILLISECONDS, &onEveny10Milliseconds, 0);
|
chVTSetAny(&everyMsTimer, boardConfiguration->generalPeriodicThreadPeriod * TICKS_IN_MS, &onEvenyGeneralMilliseconds, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void fuelPumpOff(void *arg) {
|
static void fuelPumpOff(void *arg) {
|
||||||
|
@ -173,7 +176,7 @@ static void fuelPumpOff(void *arg) {
|
||||||
turnOutputPinOff(FUEL_PUMP_RELAY);
|
turnOutputPinOff(FUEL_PUMP_RELAY);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void fuelPumpOn(ShaftEvents signal, int index) {
|
static void fuelPumpOn(trigger_event_e signal, int index, void *arg) {
|
||||||
if (index != 0)
|
if (index != 0)
|
||||||
return; // let's not abuse the timer - one time per revolution would be enough
|
return; // let's not abuse the timer - one time per revolution would be enough
|
||||||
// todo: the check about GPIO_NONE should be somewhere else!
|
// todo: the check about GPIO_NONE should be somewhere else!
|
||||||
|
@ -191,26 +194,27 @@ static void fuelPumpOn(ShaftEvents signal, int index) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static void initFuelPump(void) {
|
static void initFuelPump(void) {
|
||||||
addTriggerEventListener(&fuelPumpOn, "fuel pump");
|
addTriggerEventListener(&fuelPumpOn, "fuel pump", NULL);
|
||||||
fuelPumpOn(SHAFT_PRIMARY_UP, 0);
|
fuelPumpOn(SHAFT_PRIMARY_UP, 0, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
char * getPinNameByAdcChannel(int hwChannel, uint8_t *buffer) {
|
char * getPinNameByAdcChannel(int hwChannel, char *buffer) {
|
||||||
strcpy((char*) buffer, portname(getAdcChannelPort(hwChannel)));
|
strcpy((char*) buffer, portname(getAdcChannelPort(hwChannel)));
|
||||||
itoa10(&buffer[2], getAdcChannelPin(hwChannel));
|
itoa10(&buffer[2], getAdcChannelPin(hwChannel));
|
||||||
return (char*) buffer;
|
return (char*) buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint8_t pinNameBuffer[16];
|
static char pinNameBuffer[16];
|
||||||
|
|
||||||
static void printAnalogChannelInfoExt(const char *name, int hwChannel,
|
static void printAnalogChannelInfoExt(const char *name, int hwChannel,
|
||||||
float voltage) {
|
float adcVoltage) {
|
||||||
scheduleMsg(&logger, "%s ADC%d %s value=%fv", name, hwChannel,
|
float voltage = adcVoltage * engineConfiguration->analogInputDividerCoefficient;
|
||||||
getPinNameByAdcChannel(hwChannel, pinNameBuffer), voltage);
|
scheduleMsg(&logger, "%s ADC%d %s rawValue=%f/divided=%fv", name, hwChannel,
|
||||||
|
getPinNameByAdcChannel(hwChannel, pinNameBuffer), adcVoltage, voltage);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void printAnalogChannelInfo(const char *name, int hwChannel) {
|
static void printAnalogChannelInfo(const char *name, int hwChannel) {
|
||||||
printAnalogChannelInfoExt(name, hwChannel, getVoltageDivided(hwChannel));
|
printAnalogChannelInfoExt(name, hwChannel, getVoltage(hwChannel));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void printAnalogInfo(void) {
|
static void printAnalogInfo(void) {
|
||||||
|
@ -225,7 +229,7 @@ static void printAnalogInfo(void) {
|
||||||
getVBatt());
|
getVBatt());
|
||||||
}
|
}
|
||||||
|
|
||||||
static WORKING_AREA(csThreadStack, UTILITY_THREAD_STACK_SIZE);// declare thread stack
|
static THD_WORKING_AREA(csThreadStack, UTILITY_THREAD_STACK_SIZE);// declare thread stack
|
||||||
|
|
||||||
void initEngineContoller(void) {
|
void initEngineContoller(void) {
|
||||||
if (hasFirmwareError())
|
if (hasFirmwareError())
|
||||||
|
@ -246,11 +250,13 @@ void initEngineContoller(void) {
|
||||||
initWaveAnalyzer();
|
initWaveAnalyzer();
|
||||||
#endif /* EFI_WAVE_ANALYZER */
|
#endif /* EFI_WAVE_ANALYZER */
|
||||||
|
|
||||||
|
#if EFI_SHAFT_POSITION_INPUT
|
||||||
/**
|
/**
|
||||||
* there is an implicit dependency on the fact that 'tachometer' listener is the 1st listener - this case
|
* there is an implicit dependency on the fact that 'tachometer' listener is the 1st listener - this case
|
||||||
* other listeners can access current RPM value
|
* other listeners can access current RPM value
|
||||||
*/
|
*/
|
||||||
initRpmCalculator();
|
initRpmCalculator();
|
||||||
|
#endif /* EFI_SHAFT_POSITION_INPUT */
|
||||||
|
|
||||||
#if EFI_TUNER_STUDIO
|
#if EFI_TUNER_STUDIO
|
||||||
startTunerStudioConnectivity();
|
startTunerStudioConnectivity();
|
||||||
|
@ -283,7 +289,7 @@ void initEngineContoller(void) {
|
||||||
/**
|
/**
|
||||||
* This method initialized the main listener which actually runs injectors & ignition
|
* This method initialized the main listener which actually runs injectors & ignition
|
||||||
*/
|
*/
|
||||||
initMainEventListener();
|
initMainEventListener(engineConfiguration, engineConfiguration2);
|
||||||
#endif /* EFI_ENGINE_CONTROL */
|
#endif /* EFI_ENGINE_CONTROL */
|
||||||
|
|
||||||
#if EFI_IDLE_CONTROL
|
#if EFI_IDLE_CONTROL
|
||||||
|
|
|
@ -18,7 +18,7 @@ extern "C"
|
||||||
{
|
{
|
||||||
#endif /* __cplusplus */
|
#endif /* __cplusplus */
|
||||||
|
|
||||||
char * getPinNameByAdcChannel(int hwChannel, uint8_t *buffer);
|
char * getPinNameByAdcChannel(int hwChannel, char *buffer);
|
||||||
void initEngineContoller(void);
|
void initEngineContoller(void);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
|
@ -27,10 +27,14 @@ void chDbgPanic3(const char *msg, const char * file, int line) {
|
||||||
return;
|
return;
|
||||||
dbg_panic_file = file;
|
dbg_panic_file = file;
|
||||||
dbg_panic_line = line;
|
dbg_panic_line = line;
|
||||||
|
#if CH_DBG_SYSTEM_STATE_CHECK
|
||||||
dbg_panic_msg = msg;
|
dbg_panic_msg = msg;
|
||||||
|
#endif /* CH_DBG_SYSTEM_STATE_CHECK */
|
||||||
|
|
||||||
|
/**
|
||||||
setOutputPinValue(LED_ERROR, 1);
|
* low-level function is used here to reduce stack usage
|
||||||
|
*/
|
||||||
|
palWritePad(LED_ERROR_PORT, LED_ERROR_PIN, 1);
|
||||||
#if EFI_HD44780_LCD
|
#if EFI_HD44780_LCD
|
||||||
lcdShowFatalMessage((char *) msg);
|
lcdShowFatalMessage((char *) msg);
|
||||||
#endif /* EFI_HD44780_LCD */
|
#endif /* EFI_HD44780_LCD */
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/**
|
/**
|
||||||
* @file flash_main.c
|
* @file flash_main.cpp
|
||||||
* @brief Higher-level logic of saving data into internal flash memory
|
* @brief Higher-level logic of saving data into internal flash memory
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
|
@ -52,6 +52,7 @@ crc_t flashStateCrc(persistent_config_container_s *state) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void writeToFlash(void) {
|
void writeToFlash(void) {
|
||||||
|
#if EFI_INTERNAL_FLASH
|
||||||
persistentState.size = PERSISTENT_SIZE;
|
persistentState.size = PERSISTENT_SIZE;
|
||||||
persistentState.version = FLASH_DATA_VERSION;
|
persistentState.version = FLASH_DATA_VERSION;
|
||||||
scheduleMsg(&logger, "FLASH_DATA_VERSION=%d", persistentState.version);
|
scheduleMsg(&logger, "FLASH_DATA_VERSION=%d", persistentState.version);
|
||||||
|
@ -64,6 +65,7 @@ void writeToFlash(void) {
|
||||||
result = flashWrite(FLASH_ADDR, (const char *) &persistentState, PERSISTENT_SIZE);
|
result = flashWrite(FLASH_ADDR, (const char *) &persistentState, PERSISTENT_SIZE);
|
||||||
scheduleMsg(&logger, "Flash programmed in (ms): %d", currentTimeMillis() - nowMs);
|
scheduleMsg(&logger, "Flash programmed in (ms): %d", currentTimeMillis() - nowMs);
|
||||||
scheduleMsg(&logger, "Flashed: %d", result);
|
scheduleMsg(&logger, "Flashed: %d", result);
|
||||||
|
#endif /* EFI_INTERNAL_FLASH */
|
||||||
}
|
}
|
||||||
|
|
||||||
static int isValidCrc(persistent_config_container_s *state) {
|
static int isValidCrc(persistent_config_container_s *state) {
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
|
|
||||||
#include "engine_configuration.h"
|
#include "engine_configuration.h"
|
||||||
|
|
||||||
#define FLASH_DATA_VERSION 3002
|
#define FLASH_DATA_VERSION 3601
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C"
|
extern "C"
|
||||||
|
|
|
@ -31,10 +31,11 @@
|
||||||
#include "idle_thread.h"
|
#include "idle_thread.h"
|
||||||
#include "pin_repository.h"
|
#include "pin_repository.h"
|
||||||
#include "engine_configuration.h"
|
#include "engine_configuration.h"
|
||||||
|
#include "engine.h"
|
||||||
|
|
||||||
#define IDLE_AIR_CONTROL_VALVE_PWM_FREQUENCY 200
|
#define IDLE_AIR_CONTROL_VALVE_PWM_FREQUENCY 200
|
||||||
|
|
||||||
static WORKING_AREA(ivThreadStack, UTILITY_THREAD_STACK_SIZE);
|
static THD_WORKING_AREA(ivThreadStack, UTILITY_THREAD_STACK_SIZE);
|
||||||
|
|
||||||
static volatile int isIdleControlActive = EFI_IDLE_CONTROL;
|
static volatile int isIdleControlActive = EFI_IDLE_CONTROL;
|
||||||
extern board_configuration_s *boardConfiguration;
|
extern board_configuration_s *boardConfiguration;
|
||||||
|
@ -45,15 +46,9 @@ extern board_configuration_s *boardConfiguration;
|
||||||
static volatile int idleSwitchState;
|
static volatile int idleSwitchState;
|
||||||
|
|
||||||
static Logging logger;
|
static Logging logger;
|
||||||
|
extern Engine engine;
|
||||||
|
|
||||||
static float _switchTimes[PWM_PHASE_MAX_COUNT];
|
static SimplePwm idleValve;
|
||||||
|
|
||||||
// todo: extract helper for simple PWM?
|
|
||||||
static int pinStates[2];
|
|
||||||
static single_wave_s wave(pinStates);
|
|
||||||
static single_wave_s sr[1] = {wave};
|
|
||||||
|
|
||||||
static PwmConfig idleValve(_switchTimes, sr);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Idle level calculation algorithm lives in idle_controller.c
|
* Idle level calculation algorithm lives in idle_controller.c
|
||||||
|
@ -80,10 +75,10 @@ static void setIdleValvePwm(int value) {
|
||||||
return;
|
return;
|
||||||
scheduleMsg(&logger, "setting idle valve PWM %d", value);
|
scheduleMsg(&logger, "setting idle valve PWM %d", value);
|
||||||
/**
|
/**
|
||||||
* currently IDEL level is an integer per mil (0-1000 range), and PWM takes a fioat in the 0..1 range
|
* currently idle level is an integer per mil (0-1000 range), and PWM takes a float in the 0..1 range
|
||||||
* todo: unify?
|
* todo: unify?
|
||||||
*/
|
*/
|
||||||
setSimplePwmDutyCycle(&idleValve, 0.001 * value);
|
idleValve.setSimplePwmDutyCycle(0.001 * value);
|
||||||
}
|
}
|
||||||
|
|
||||||
static msg_t ivThread(int param) {
|
static msg_t ivThread(int param) {
|
||||||
|
@ -91,7 +86,7 @@ static msg_t ivThread(int param) {
|
||||||
|
|
||||||
int currentIdleValve = -1;
|
int currentIdleValve = -1;
|
||||||
while (TRUE) {
|
while (TRUE) {
|
||||||
chThdSleepMilliseconds(100);
|
chThdSleepMilliseconds(boardConfiguration->idleThreadPeriod);
|
||||||
|
|
||||||
// this value is not used yet
|
// this value is not used yet
|
||||||
idleSwitchState = palReadPad(getHwPort(boardConfiguration->idleSwitchPin), getHwPin(boardConfiguration->idleSwitchPin));
|
idleSwitchState = palReadPad(getHwPort(boardConfiguration->idleSwitchPin), getHwPin(boardConfiguration->idleSwitchPin));
|
||||||
|
@ -122,12 +117,11 @@ static void setIdleRpmAction(int value) {
|
||||||
void startIdleThread() {
|
void startIdleThread() {
|
||||||
initLogging(&logger, "Idle Valve Control");
|
initLogging(&logger, "Idle Valve Control");
|
||||||
|
|
||||||
startSimplePwm(&idleValve, "Idle Valve",
|
startSimplePwmExt(&idleValve, "Idle Valve",
|
||||||
boardConfiguration->idleValvePin,
|
boardConfiguration->idleValvePin,
|
||||||
IDLE_VALVE,
|
IDLE_VALVE,
|
||||||
0.5,
|
|
||||||
IDLE_AIR_CONTROL_VALVE_PWM_FREQUENCY,
|
IDLE_AIR_CONTROL_VALVE_PWM_FREQUENCY,
|
||||||
TRUE);
|
0.5);
|
||||||
|
|
||||||
idleInit(&idle);
|
idleInit(&idle);
|
||||||
scheduleMsg(&logger, "initial idle %d", idle.value);
|
scheduleMsg(&logger, "initial idle %d", idle.value);
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/**
|
/**
|
||||||
* @file injector_central.c
|
* @file injector_central.cpp
|
||||||
* @brief Utility methods related to fuel injection.
|
* @brief Utility methods related to fuel injection.
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
|
@ -22,7 +22,6 @@
|
||||||
|
|
||||||
#include "injector_central.h"
|
#include "injector_central.h"
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
#include "engines.h"
|
|
||||||
#include "io_pins.h"
|
#include "io_pins.h"
|
||||||
#include "signal_executor.h"
|
#include "signal_executor.h"
|
||||||
#include "main_trigger_callback.h"
|
#include "main_trigger_callback.h"
|
||||||
|
@ -38,17 +37,13 @@ extern board_configuration_s *boardConfiguration;
|
||||||
|
|
||||||
static int is_injector_enabled[MAX_INJECTOR_COUNT];
|
static int is_injector_enabled[MAX_INJECTOR_COUNT];
|
||||||
|
|
||||||
int isInjectionEnabled(void) {
|
void assertCylinderId(int cylinderId, const char *msg) {
|
||||||
return engineConfiguration2->isInjectionEnabledFlag;
|
|
||||||
}
|
|
||||||
|
|
||||||
void assertCylinderId(int cylinderId, char *msg) {
|
|
||||||
int isValid = cylinderId >= 1 && cylinderId <= engineConfiguration->cylindersCount;
|
int isValid = cylinderId >= 1 && cylinderId <= engineConfiguration->cylindersCount;
|
||||||
if (!isValid) {
|
if (!isValid) {
|
||||||
// we are here only in case of a fatal issue - at this point it is fine to make some blocking i-o
|
// we are here only in case of a fatal issue - at this point it is fine to make some blocking i-o
|
||||||
//scheduleSimpleMsg(&logger, "cid=", cylinderId);
|
//scheduleSimpleMsg(&logger, "cid=", cylinderId);
|
||||||
print("ERROR [%s] cid=%d\r\n", msg, cylinderId);
|
print("ERROR [%s] cid=%d\r\n", msg, cylinderId);
|
||||||
chDbgAssert(TRUE, "Cylinder ID", null);
|
efiAssertVoid(FALSE, "Cylinder ID");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -76,7 +71,7 @@ static void printStatus(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static void setInjectorEnabled(int id, int value) {
|
static void setInjectorEnabled(int id, int value) {
|
||||||
chDbgCheck(id >= 0 && id < engineConfiguration->cylindersCount, "injector id");
|
efiAssertVoid(id >= 0 && id < engineConfiguration->cylindersCount, "injector id");
|
||||||
is_injector_enabled[id] = value;
|
is_injector_enabled[id] = value;
|
||||||
printStatus();
|
printStatus();
|
||||||
}
|
}
|
||||||
|
@ -121,14 +116,14 @@ static void sparkbench(char * onStr, char *offStr, char *countStr) {
|
||||||
needToRunBench = TRUE;
|
needToRunBench = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static WORKING_AREA(benchThreadStack, UTILITY_THREAD_STACK_SIZE);
|
static THD_WORKING_AREA(benchThreadStack, UTILITY_THREAD_STACK_SIZE);
|
||||||
|
|
||||||
static msg_t benchThread(int param) {
|
static msg_t benchThread(int param) {
|
||||||
chRegSetThreadName("BenchThread");
|
chRegSetThreadName("BenchThread");
|
||||||
|
|
||||||
while (TRUE) {
|
while (TRUE) {
|
||||||
while (!needToRunBench) {
|
while (!needToRunBench) {
|
||||||
chThdSleepMilliseconds(50);
|
chThdSleepMilliseconds(200);
|
||||||
}
|
}
|
||||||
needToRunBench = FALSE;
|
needToRunBench = FALSE;
|
||||||
runBench(brainPin, pin, onTime, offTime, count);
|
runBench(brainPin, pin, onTime, offTime, count);
|
||||||
|
|
|
@ -19,9 +19,8 @@ extern "C"
|
||||||
#endif /* __cplusplus */
|
#endif /* __cplusplus */
|
||||||
|
|
||||||
void initInjectorCentral(void);
|
void initInjectorCentral(void);
|
||||||
int isInjectionEnabled(void);
|
|
||||||
int isInjectorEnabled(int cylinderId);
|
int isInjectorEnabled(int cylinderId);
|
||||||
void assertCylinderId(int cylinderId, char *msg);
|
void assertCylinderId(int cylinderId, const char *msg);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,7 +37,7 @@
|
||||||
#define MFI_BLINK_SEPARATOR 400
|
#define MFI_BLINK_SEPARATOR 400
|
||||||
#define MFI_CHECKENGINE_LIGHT 10000
|
#define MFI_CHECKENGINE_LIGHT 10000
|
||||||
|
|
||||||
static WORKING_AREA(mfiThreadStack, UTILITY_THREAD_STACK_SIZE); // declare thread
|
static THD_WORKING_AREA(mfiThreadStack, UTILITY_THREAD_STACK_SIZE); // declare thread
|
||||||
|
|
||||||
static void blink_digits(int digit, int duration) {
|
static void blink_digits(int digit, int duration) {
|
||||||
for (int iter = 0; iter < digit; iter++) {
|
for (int iter = 0; iter < digit; iter++) {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/**
|
/**
|
||||||
* @file map_averaging.c
|
* @file map_averaging.cpp
|
||||||
*
|
*
|
||||||
* @date Dec 11, 2013
|
* @date Dec 11, 2013
|
||||||
* @author Andrey Belomutskiy, (c) 2012-2014
|
* @author Andrey Belomutskiy, (c) 2012-2014
|
||||||
|
@ -20,16 +20,18 @@
|
||||||
|
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
|
|
||||||
|
#include "map.h"
|
||||||
|
|
||||||
#if EFI_MAP_AVERAGING
|
#if EFI_MAP_AVERAGING
|
||||||
|
|
||||||
#include "map_averaging.h"
|
#include "map_averaging.h"
|
||||||
#include "trigger_central.h"
|
#include "trigger_central.h"
|
||||||
#include "adc_inputs.h"
|
#include "adc_inputs.h"
|
||||||
#include "map.h"
|
|
||||||
#include "engine_state.h"
|
#include "engine_state.h"
|
||||||
#include "engine_configuration.h"
|
#include "engine_configuration.h"
|
||||||
#include "interpolation.h"
|
#include "interpolation.h"
|
||||||
#include "signal_executor.h"
|
#include "signal_executor.h"
|
||||||
|
#include "engine.h"
|
||||||
|
|
||||||
#if EFI_ANALOG_CHART
|
#if EFI_ANALOG_CHART
|
||||||
#include "analog_chart.h"
|
#include "analog_chart.h"
|
||||||
|
@ -58,13 +60,13 @@ static volatile float v_mapAccumulator = 0;
|
||||||
*/
|
*/
|
||||||
static volatile int mapMeasurementsCounter = 0;
|
static volatile int mapMeasurementsCounter = 0;
|
||||||
|
|
||||||
static float currentMaxPressure;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* v_ for Voltage
|
* v_ for Voltage
|
||||||
*/
|
*/
|
||||||
static float v_averagedMapValue;
|
static float v_averagedMapValue;
|
||||||
|
|
||||||
|
extern Engine engine;
|
||||||
|
|
||||||
extern engine_configuration_s *engineConfiguration;
|
extern engine_configuration_s *engineConfiguration;
|
||||||
|
|
||||||
static scheduling_s startTimer[2];
|
static scheduling_s startTimer[2];
|
||||||
|
@ -81,7 +83,9 @@ static void startAveraging(void*arg) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method is invoked from ADC callback
|
* This method is invoked from ADC callback.
|
||||||
|
* @note This method is invoked OFTEN, this method is a potential bottle-next - the implementation should be
|
||||||
|
* as fast as possible
|
||||||
*/
|
*/
|
||||||
void mapAveragingCallback(adcsample_t value) {
|
void mapAveragingCallback(adcsample_t value) {
|
||||||
/* Calculates the average values from the ADC samples.*/
|
/* Calculates the average values from the ADC samples.*/
|
||||||
|
@ -90,11 +94,11 @@ void mapAveragingCallback(adcsample_t value) {
|
||||||
float voltage = adcToVoltsDivided(value);
|
float voltage = adcToVoltsDivided(value);
|
||||||
float currentPressure = getMapByVoltage(voltage);
|
float currentPressure = getMapByVoltage(voltage);
|
||||||
|
|
||||||
|
#if EFI_ANALOG_CHART
|
||||||
if (engineConfiguration->analogChartMode == AC_MAP)
|
if (engineConfiguration->analogChartMode == AC_MAP)
|
||||||
if (perRevolutionCounter % FAST_MAP_CHART_SKIP_FACTOR == 0)
|
if (perRevolutionCounter % FAST_MAP_CHART_SKIP_FACTOR == 0)
|
||||||
acAddData(getCrankshaftAngle(getTimeNowUs()), currentPressure);
|
acAddData(getCrankshaftAngle(getTimeNowUs()), currentPressure);
|
||||||
|
#endif /* EFI_ANALOG_CHART */
|
||||||
currentMaxPressure = maxF(currentMaxPressure, currentPressure);
|
|
||||||
|
|
||||||
chSysLockFromIsr()
|
chSysLockFromIsr()
|
||||||
;
|
;
|
||||||
|
@ -118,7 +122,7 @@ static void endAveraging(void *arg) {
|
||||||
/**
|
/**
|
||||||
* Shaft Position callback used to schedule start and end of MAP averaging
|
* Shaft Position callback used to schedule start and end of MAP averaging
|
||||||
*/
|
*/
|
||||||
static void shaftPositionCallback(ShaftEvents ckpEventType, int index) {
|
static void shaftPositionCallback(trigger_event_e ckpEventType, int index, void *arg) {
|
||||||
// this callback is invoked on interrupt thread
|
// this callback is invoked on interrupt thread
|
||||||
|
|
||||||
if (index != 0)
|
if (index != 0)
|
||||||
|
@ -131,8 +135,6 @@ static void shaftPositionCallback(ShaftEvents ckpEventType, int index) {
|
||||||
perRevolution = perRevolutionCounter;
|
perRevolution = perRevolutionCounter;
|
||||||
perRevolutionCounter = 0;
|
perRevolutionCounter = 0;
|
||||||
|
|
||||||
currentMaxPressure = 0;
|
|
||||||
|
|
||||||
MAP_sensor_config_s * config = &engineConfiguration->map;
|
MAP_sensor_config_s * config = &engineConfiguration->map;
|
||||||
|
|
||||||
float startAngle = interpolate2d(rpm, config->samplingAngleBins, config->samplingAngle, MAP_ANGLE_SIZE);
|
float startAngle = interpolate2d(rpm, config->samplingAngleBins, config->samplingAngle, MAP_ANGLE_SIZE);
|
||||||
|
@ -153,11 +155,12 @@ float getMapVoltage(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* because of MAP window averaging, MAP is only available while engine is spinning
|
* Because of MAP window averaging, MAP is only available while engine is spinning
|
||||||
|
* @return Manifold Absolute Pressure, in kPa
|
||||||
*/
|
*/
|
||||||
float getMap(void) {
|
float getMap(void) {
|
||||||
if (getRpm() == 0)
|
if (getRpm() == 0)
|
||||||
return getRawMap(); // maybe return NaN and have a
|
return getRawMap(); // maybe return NaN in case of stopped engine?
|
||||||
return getMapByVoltage(v_averagedMapValue);
|
return getMapByVoltage(v_averagedMapValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -170,7 +173,7 @@ void initMapAveraging(void) {
|
||||||
endTimer[1].name = "map end1";
|
endTimer[1].name = "map end1";
|
||||||
|
|
||||||
|
|
||||||
addTriggerEventListener(&shaftPositionCallback, "rpm reporter");
|
addTriggerEventListener(&shaftPositionCallback, "rpm reporter", NULL);
|
||||||
addConsoleAction("faststat", showMapStats);
|
addConsoleAction("faststat", showMapStats);
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
* @brief dead code
|
* @brief dead code
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* map_multiplier.c
|
* map_multiplier.cpp
|
||||||
*
|
*
|
||||||
* @date Jul 23, 2013
|
* @date Jul 23, 2013
|
||||||
* @author Andrey Belomutskiy, (c) 2012-2014
|
* @author Andrey Belomutskiy, (c) 2012-2014
|
||||||
|
@ -16,12 +16,15 @@
|
||||||
#include "wave_math.h"
|
#include "wave_math.h"
|
||||||
#include "allsensors.h"
|
#include "allsensors.h"
|
||||||
#include "engine_math.h"
|
#include "engine_math.h"
|
||||||
|
#include "engine.h"
|
||||||
|
|
||||||
extern engine_configuration_s *engineConfiguration;
|
extern engine_configuration_s *engineConfiguration;
|
||||||
|
|
||||||
static Logging logger;
|
static Logging logger;
|
||||||
|
|
||||||
static WORKING_AREA(maThreadStack, UTILITY_THREAD_STACK_SIZE);
|
extern Engine engine;
|
||||||
|
|
||||||
|
static THD_WORKING_AREA(maThreadStack, UTILITY_THREAD_STACK_SIZE);
|
||||||
|
|
||||||
static void mapCallback(int rpm, float key, float value) {
|
static void mapCallback(int rpm, float key, float value) {
|
||||||
Logging *logging = &logger;
|
Logging *logging = &logger;
|
|
@ -19,14 +19,15 @@
|
||||||
* If not, see <http://www.gnu.org/licenses/>.
|
* If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "engine_math.h"
|
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
|
#include "engine_math.h"
|
||||||
#include "engine_configuration.h"
|
#include "engine_configuration.h"
|
||||||
#include "interpolation.h"
|
#include "interpolation.h"
|
||||||
#include "allsensors.h"
|
#include "allsensors.h"
|
||||||
#include "io_pins.h"
|
#include "io_pins.h"
|
||||||
#include "OutputSignalList.h"
|
#include "OutputSignalList.h"
|
||||||
#include "trigger_decoder.h"
|
#include "trigger_decoder.h"
|
||||||
|
#include "event_registry.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* default Volumetric Efficiency
|
* default Volumetric Efficiency
|
||||||
|
@ -36,42 +37,21 @@
|
||||||
// return interpolate(5000, 1.1, 8000, 1, rpm);
|
// return interpolate(5000, 1.1, 8000, 1, rpm);
|
||||||
// return interpolate(500, 0.5, 5000, 1.1, rpm);
|
// return interpolate(500, 0.5, 5000, 1.1, rpm);
|
||||||
//}
|
//}
|
||||||
//#define K_AT_MIN_RPM_MIN_TPS 0.25
|
|
||||||
//#define K_AT_MIN_RPM_MAX_TPS 0.25
|
|
||||||
//#define K_AT_MAX_RPM_MIN_TPS 0.25
|
|
||||||
//#define K_AT_MAX_RPM_MAX_TPS 0.9
|
|
||||||
//
|
|
||||||
//#define rpmMin 500
|
|
||||||
//#define rpmMax 8000
|
|
||||||
//
|
|
||||||
//#define tpMin 0
|
|
||||||
//#define tpMax 100
|
|
||||||
//
|
|
||||||
// http://rusefi.com/math/t_charge.html
|
|
||||||
// /
|
|
||||||
//float getTCharge(int rpm, int tps, float coolantTemp, float airTemp) {
|
|
||||||
// float minRpmKcurrentTPS = interpolate(tpMin, K_AT_MIN_RPM_MIN_TPS, tpMax,
|
|
||||||
// K_AT_MIN_RPM_MAX_TPS, tps);
|
|
||||||
// float maxRpmKcurrentTPS = interpolate(tpMin, K_AT_MAX_RPM_MIN_TPS, tpMax,
|
|
||||||
// K_AT_MAX_RPM_MAX_TPS, tps);
|
|
||||||
//
|
|
||||||
// float Tcharge_coff = interpolate(rpmMin, minRpmKcurrentTPS, rpmMax,
|
|
||||||
// maxRpmKcurrentTPS, rpm);
|
|
||||||
//
|
|
||||||
// float Tcharge = coolantTemp * (1 - Tcharge_coff) + airTemp * Tcharge_coff;
|
|
||||||
//
|
|
||||||
// return Tcharge;
|
|
||||||
//}
|
|
||||||
#define MAX_STARTING_FUEL 15
|
|
||||||
#define MIN_STARTING_FUEL 8
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return time needed to rotate crankshaft by one degree, in milliseconds.
|
* @return time needed to rotate crankshaft by one degree, in milliseconds.
|
||||||
|
* @deprecated
|
||||||
*/
|
*/
|
||||||
float getOneDegreeTimeMs(int rpm) {
|
float getOneDegreeTimeMs(int rpm) {
|
||||||
return 1000.0 * 60 / 360 / rpm;
|
return 1000.0 * 60 / 360 / rpm;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return time needed to rotate crankshaft by one degree, in microseconds.
|
||||||
|
*/
|
||||||
|
float getOneDegreeTimeUs(int rpm) {
|
||||||
|
return 1000000.0 * 60 / 360 / rpm;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return number of milliseconds in one crankshaft revolution
|
* @return number of milliseconds in one crankshaft revolution
|
||||||
*/
|
*/
|
||||||
|
@ -136,34 +116,39 @@ int isCrankingRT(engine_configuration_s *engineConfiguration, int rpm) {
|
||||||
OutputSignalList ignitionSignals;
|
OutputSignalList ignitionSignals;
|
||||||
OutputSignalList injectonSignals;
|
OutputSignalList injectonSignals;
|
||||||
|
|
||||||
|
|
||||||
static void registerSparkEvent(engine_configuration_s const *engineConfiguration, trigger_shape_s * s,
|
static void registerSparkEvent(engine_configuration_s const *engineConfiguration, trigger_shape_s * s,
|
||||||
ActuatorEventList *list, OutputSignal *actuator, float angleOffset) {
|
IgnitionEventList *list, OutputSignal *actuator, float localAdvance, float dwell) {
|
||||||
|
|
||||||
registerActuatorEventExt(engineConfiguration, s, list,
|
IgnitionEvent *event = list->getNextActuatorEvent();
|
||||||
actuator, angleOffset);
|
if (event == NULL)
|
||||||
|
return; // error already reported
|
||||||
|
|
||||||
|
event->advance = localAdvance;
|
||||||
|
|
||||||
|
registerActuatorEventExt(engineConfiguration, s, &event->actuator, actuator, localAdvance - dwell);
|
||||||
}
|
}
|
||||||
|
|
||||||
void initializeIgnitionActions(float baseAngle, engine_configuration_s *engineConfiguration,
|
void initializeIgnitionActions(float advance, float dwellAngle, engine_configuration_s *engineConfiguration,
|
||||||
engine_configuration2_s *engineConfiguration2, float dwellMs, ActuatorEventList *list) {
|
engine_configuration2_s *engineConfiguration2, IgnitionEventList *list) {
|
||||||
chDbgCheck(engineConfiguration->cylindersCount > 0, "cylindersCount");
|
|
||||||
|
efiAssertVoid(engineConfiguration->cylindersCount > 0, "cylindersCount");
|
||||||
ignitionSignals.clear();
|
ignitionSignals.clear();
|
||||||
|
|
||||||
resetEventList(list);
|
list->resetEventList();
|
||||||
|
|
||||||
switch (engineConfiguration->ignitionMode) {
|
switch (engineConfiguration->ignitionMode) {
|
||||||
case IM_ONE_COIL:
|
case IM_ONE_COIL:
|
||||||
for (int i = 0; i < engineConfiguration->cylindersCount; i++) {
|
for (int i = 0; i < engineConfiguration->cylindersCount; i++) {
|
||||||
// todo: extract method
|
// todo: extract method
|
||||||
float angle = baseAngle + 720.0 * i / engineConfiguration->cylindersCount;
|
float localAdvance = advance + 720.0 * i / engineConfiguration->cylindersCount;
|
||||||
|
|
||||||
registerSparkEvent(engineConfiguration, &engineConfiguration2->triggerShape, list,
|
registerSparkEvent(engineConfiguration, &engineConfiguration2->triggerShape, list,
|
||||||
ignitionSignals.add(SPARKOUT_1_OUTPUT), angle);
|
ignitionSignals.add(SPARKOUT_1_OUTPUT), localAdvance, dwellAngle);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case IM_WASTED_SPARK:
|
case IM_WASTED_SPARK:
|
||||||
for (int i = 0; i < engineConfiguration->cylindersCount; i++) {
|
for (int i = 0; i < engineConfiguration->cylindersCount; i++) {
|
||||||
float angle = baseAngle + 720.0 * i / engineConfiguration->cylindersCount;
|
float localAdvance = advance + 720.0 * i / engineConfiguration->cylindersCount;
|
||||||
|
|
||||||
int wastedIndex = i % (engineConfiguration->cylindersCount / 2);
|
int wastedIndex = i % (engineConfiguration->cylindersCount / 2);
|
||||||
|
|
||||||
|
@ -171,18 +156,18 @@ void initializeIgnitionActions(float baseAngle, engine_configuration_s *engineCo
|
||||||
io_pin_e ioPin = (io_pin_e) (SPARKOUT_1_OUTPUT + id);
|
io_pin_e ioPin = (io_pin_e) (SPARKOUT_1_OUTPUT + id);
|
||||||
|
|
||||||
registerSparkEvent(engineConfiguration, &engineConfiguration2->triggerShape, list,
|
registerSparkEvent(engineConfiguration, &engineConfiguration2->triggerShape, list,
|
||||||
ignitionSignals.add(ioPin), angle);
|
ignitionSignals.add(ioPin), localAdvance, dwellAngle);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case IM_INDIVIDUAL_COILS:
|
case IM_INDIVIDUAL_COILS:
|
||||||
for (int i = 0; i < engineConfiguration->cylindersCount; i++) {
|
for (int i = 0; i < engineConfiguration->cylindersCount; i++) {
|
||||||
float angle = baseAngle + 720.0 * i / engineConfiguration->cylindersCount;
|
float localAdvance = advance + 720.0 * i / engineConfiguration->cylindersCount;
|
||||||
|
|
||||||
io_pin_e pin = (io_pin_e) ((int) SPARKOUT_1_OUTPUT + getCylinderId(engineConfiguration->firingOrder, i) - 1);
|
io_pin_e pin = (io_pin_e) ((int) SPARKOUT_1_OUTPUT + getCylinderId(engineConfiguration->firingOrder, i) - 1);
|
||||||
registerSparkEvent(engineConfiguration, &engineConfiguration2->triggerShape, list,
|
registerSparkEvent(engineConfiguration, &engineConfiguration2->triggerShape, list, ignitionSignals.add(pin),
|
||||||
ignitionSignals.add(pin), angle);
|
localAdvance, dwellAngle);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -193,7 +178,7 @@ void initializeIgnitionActions(float baseAngle, engine_configuration_s *engineCo
|
||||||
|
|
||||||
void addFuelEvents(engine_configuration_s const *e, engine_configuration2_s *engineConfiguration2,
|
void addFuelEvents(engine_configuration_s const *e, engine_configuration2_s *engineConfiguration2,
|
||||||
ActuatorEventList *list, injection_mode_e mode) {
|
ActuatorEventList *list, injection_mode_e mode) {
|
||||||
resetEventList(list);
|
list->resetEventList();
|
||||||
|
|
||||||
trigger_shape_s *s = &engineConfiguration2->triggerShape;
|
trigger_shape_s *s = &engineConfiguration2->triggerShape;
|
||||||
|
|
||||||
|
@ -204,7 +189,7 @@ void addFuelEvents(engine_configuration_s const *e, engine_configuration2_s *eng
|
||||||
for (int i = 0; i < e->cylindersCount; i++) {
|
for (int i = 0; i < e->cylindersCount; i++) {
|
||||||
io_pin_e pin = (io_pin_e) ((int) INJECTOR_1_OUTPUT + getCylinderId(e->firingOrder, i) - 1);
|
io_pin_e pin = (io_pin_e) ((int) INJECTOR_1_OUTPUT + getCylinderId(e->firingOrder, i) - 1);
|
||||||
float angle = baseAngle + i * 720.0 / e->cylindersCount;
|
float angle = baseAngle + i * 720.0 / e->cylindersCount;
|
||||||
registerActuatorEventExt(e, s, list, injectonSignals.add(pin), angle);
|
registerActuatorEventExt(e, s, list->getNextActuatorEvent(), injectonSignals.add(pin), angle);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case IM_SIMULTANEOUS:
|
case IM_SIMULTANEOUS:
|
||||||
|
@ -213,7 +198,7 @@ void addFuelEvents(engine_configuration_s const *e, engine_configuration2_s *eng
|
||||||
|
|
||||||
for (int j = 0; j < e->cylindersCount; j++) {
|
for (int j = 0; j < e->cylindersCount; j++) {
|
||||||
io_pin_e pin = (io_pin_e) ((int) INJECTOR_1_OUTPUT + j);
|
io_pin_e pin = (io_pin_e) ((int) INJECTOR_1_OUTPUT + j);
|
||||||
registerActuatorEventExt(e, s, list, injectonSignals.add(pin), angle);
|
registerActuatorEventExt(e, s, list->getNextActuatorEvent(), injectonSignals.add(pin), angle);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -221,7 +206,7 @@ void addFuelEvents(engine_configuration_s const *e, engine_configuration2_s *eng
|
||||||
for (int i = 0; i < e->cylindersCount; i++) {
|
for (int i = 0; i < e->cylindersCount; i++) {
|
||||||
io_pin_e pin = (io_pin_e) ((int) INJECTOR_1_OUTPUT + (i % 2));
|
io_pin_e pin = (io_pin_e) ((int) INJECTOR_1_OUTPUT + (i % 2));
|
||||||
float angle = baseAngle + i * 720.0 / e->cylindersCount;
|
float angle = baseAngle + i * 720.0 / e->cylindersCount;
|
||||||
registerActuatorEventExt(e, s, list, injectonSignals.add(pin), angle);
|
registerActuatorEventExt(e, s, list->getNextActuatorEvent(), injectonSignals.add(pin), angle);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -238,53 +223,76 @@ float getSparkDwellMsT(engine_configuration_s *engineConfiguration, int rpm) {
|
||||||
float angle = engineConfiguration->crankingChargeAngle;
|
float angle = engineConfiguration->crankingChargeAngle;
|
||||||
return getOneDegreeTimeMs(rpm) * angle;
|
return getOneDegreeTimeMs(rpm) * angle;
|
||||||
}
|
}
|
||||||
efiAssert(!cisnan(rpm), "invalid rpm");
|
efiAssert(!cisnan(rpm), "invalid rpm", NAN);
|
||||||
|
|
||||||
return interpolate2d(rpm, engineConfiguration->sparkDwellBins, engineConfiguration->sparkDwell, DWELL_CURVE_SIZE);
|
return interpolate2d(rpm, engineConfiguration->sparkDwellBins, engineConfiguration->sparkDwell, DWELL_CURVE_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
void registerActuatorEventExt(engine_configuration_s const *engineConfiguration, trigger_shape_s * s,
|
/**
|
||||||
ActuatorEventList *list, OutputSignal *actuator, float angleOffset) {
|
* Trigger event count equals engine cycle event count if we have a cam sensor.
|
||||||
chDbgCheck(s->getSize() > 0, "uninitialized trigger_shape_s");
|
* Two trigger cycles make one engine cycle in case of a four stroke engine If we only have a cranksensor.
|
||||||
|
*/
|
||||||
|
int getEngineCycleEventCount(engine_configuration_s const *engineConfiguration, trigger_shape_s * s) {
|
||||||
|
return getOperationMode(engineConfiguration) == FOUR_STROKE_CAM_SENSOR ? s->getSize() : 2 * s->getSize();
|
||||||
|
}
|
||||||
|
|
||||||
|
void findTriggerPosition(engine_configuration_s const *engineConfiguration, trigger_shape_s * s,
|
||||||
|
event_trigger_position_s *position, float angleOffset) {
|
||||||
|
|
||||||
angleOffset = fixAngle(angleOffset + engineConfiguration->globalTriggerAngleOffset);
|
angleOffset = fixAngle(angleOffset + engineConfiguration->globalTriggerAngleOffset);
|
||||||
|
|
||||||
int triggerIndexOfZeroEvent = s->triggerShapeSynchPointIndex;
|
|
||||||
|
|
||||||
// todo: migrate to crankAngleRange?
|
// todo: migrate to crankAngleRange?
|
||||||
float firstAngle = s->wave.getSwitchTime(triggerIndexOfZeroEvent) * 720;
|
float firstAngle = s->wave.getAngle(s->triggerShapeSynchPointIndex, engineConfiguration, s);
|
||||||
|
|
||||||
|
int engineCycleEventCount = getEngineCycleEventCount(engineConfiguration, s);
|
||||||
|
|
||||||
// let's find the last trigger angle which is less or equal to the desired angle
|
// let's find the last trigger angle which is less or equal to the desired angle
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < s->getSize() - 1; i++) {
|
for (i = 0; i < engineCycleEventCount - 1; i++) {
|
||||||
// todo: we need binary search here
|
// todo: we need binary search here
|
||||||
float angle = fixAngle(
|
float angle = fixAngle(
|
||||||
s->wave.getSwitchTime((triggerIndexOfZeroEvent + i + 1) % s->getSize()) * 720 - firstAngle);
|
s->wave.getAngle((s->triggerShapeSynchPointIndex + i + 1) % engineCycleEventCount, engineConfiguration, s)
|
||||||
|
- firstAngle);
|
||||||
if (angle > angleOffset)
|
if (angle > angleOffset)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// explicit check for zero to avoid issues where logical zero is not exactly zero due to float nature
|
// explicit check for zero to avoid issues where logical zero is not exactly zero due to float nature
|
||||||
float angle =
|
float eventAngle;
|
||||||
i == 0 ?
|
if (i == 0) {
|
||||||
0 :
|
eventAngle = 0;
|
||||||
fixAngle(s->wave.getSwitchTime((triggerIndexOfZeroEvent + i) % s->getSize()) * 720 - firstAngle);
|
} else {
|
||||||
|
eventAngle = fixAngle(
|
||||||
|
s->wave.getAngle((s->triggerShapeSynchPointIndex + i) % engineCycleEventCount, engineConfiguration, s)
|
||||||
|
- firstAngle);
|
||||||
|
}
|
||||||
|
|
||||||
if (angleOffset < angle) {
|
if (angleOffset < eventAngle) {
|
||||||
firmwareError("angle constraint violation in registerActuatorEventExt(): %f/%f", angleOffset, angle);
|
firmwareError("angle constraint violation in registerActuatorEventExt(): %f/%f", angleOffset, eventAngle);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
registerActuatorEvent(list, i, actuator, angleOffset - angle);
|
position->eventIndex = i;
|
||||||
|
position->eventAngle = eventAngle;
|
||||||
|
position->angleOffset = angleOffset - eventAngle;
|
||||||
}
|
}
|
||||||
|
|
||||||
//float getTriggerEventAngle(int triggerEventIndex) {
|
void registerActuatorEventExt(engine_configuration_s const *engineConfiguration, trigger_shape_s * s, ActuatorEvent *e,
|
||||||
// return 0;
|
OutputSignal *actuator, float angleOffset) {
|
||||||
//}
|
efiAssertVoid(s->getSize() > 0, "uninitialized trigger_shape_s");
|
||||||
|
|
||||||
|
if (e == NULL)
|
||||||
|
return; // error already reported
|
||||||
|
e->actuator = actuator;
|
||||||
|
|
||||||
|
findTriggerPosition(engineConfiguration, s, &e->position, angleOffset);
|
||||||
|
}
|
||||||
|
|
||||||
static int order_1_THEN_3_THEN_4_THEN2[] = { 1, 3, 4, 2 };
|
static int order_1_THEN_3_THEN_4_THEN2[] = { 1, 3, 4, 2 };
|
||||||
|
|
||||||
static int order_1_THEN_5_THEN_3_THEN_6_THEN_2_THEN_4[] = { 1, 5, 3, 6, 2, 4 };
|
static int order_1_THEN_5_THEN_3_THEN_6_THEN_2_THEN_4[] = { 1, 5, 3, 6, 2, 4 };
|
||||||
|
|
||||||
|
static int order_1_8_4_3_6_5_7_2[] = {1, 8, 4, 3, 6, 5, 7, 2};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param index from zero to cylindersCount - 1
|
* @param index from zero to cylindersCount - 1
|
||||||
* @return cylinderId from one to cylindersCount
|
* @return cylinderId from one to cylindersCount
|
||||||
|
@ -298,6 +306,8 @@ int getCylinderId(firing_order_e firingOrder, int index) {
|
||||||
return order_1_THEN_3_THEN_4_THEN2[index];
|
return order_1_THEN_3_THEN_4_THEN2[index];
|
||||||
case FO_1_THEN_5_THEN_3_THEN_6_THEN_2_THEN_4:
|
case FO_1_THEN_5_THEN_3_THEN_6_THEN_2_THEN_4:
|
||||||
return order_1_THEN_5_THEN_3_THEN_6_THEN_2_THEN_4[index];
|
return order_1_THEN_5_THEN_3_THEN_6_THEN_2_THEN_4[index];
|
||||||
|
case FO_1_8_4_3_6_5_7_2:
|
||||||
|
return order_1_8_4_3_6_5_7_2[index];
|
||||||
|
|
||||||
default:
|
default:
|
||||||
firmwareError("getCylinderId not supported for %d", firingOrder);
|
firmwareError("getCylinderId not supported for %d", firingOrder);
|
||||||
|
@ -320,8 +330,13 @@ void prepareOutputSignals(engine_configuration_s *engineConfiguration, engine_co
|
||||||
}
|
}
|
||||||
|
|
||||||
void setTableBin(float array[], int size, float l, float r) {
|
void setTableBin(float array[], int size, float l, float r) {
|
||||||
for (int i = 0; i < size; i++)
|
for (int i = 0; i < size; i++) {
|
||||||
array[i] = interpolate(0, l, size - 1, r, i);
|
float value = interpolate(0, l, size - 1, r, i);
|
||||||
|
/**
|
||||||
|
* rounded values look nicer, also we want to avoid precision mismatch with Tuner Studio
|
||||||
|
*/
|
||||||
|
array[i] = efiRound(value, 0.01);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void setFuelRpmBin(engine_configuration_s *engineConfiguration, float l, float r) {
|
void setFuelRpmBin(engine_configuration_s *engineConfiguration, float l, float r) {
|
||||||
|
@ -339,3 +354,7 @@ void setTimingRpmBin(engine_configuration_s *engineConfiguration, float l, float
|
||||||
void setTimingLoadBin(engine_configuration_s *engineConfiguration, float l, float r) {
|
void setTimingLoadBin(engine_configuration_s *engineConfiguration, float l, float r) {
|
||||||
setTableBin(engineConfiguration->ignitionLoadBins, IGN_LOAD_COUNT, l, r);
|
setTableBin(engineConfiguration->ignitionLoadBins, IGN_LOAD_COUNT, l, r);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int isInjectionEnabled(engine_configuration2_s const *engineConfiguration2) {
|
||||||
|
return engineConfiguration2->isInjectionEnabledFlag;
|
||||||
|
}
|
||||||
|
|
|
@ -10,6 +10,54 @@
|
||||||
|
|
||||||
#include "engine_configuration.h"
|
#include "engine_configuration.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
#include "ec2.h"
|
||||||
|
#include "trigger_structure.h"
|
||||||
|
void findTriggerPosition(engine_configuration_s const *engineConfiguration, trigger_shape_s * s,
|
||||||
|
event_trigger_position_s *position, float angleOffset);
|
||||||
|
|
||||||
|
int isInjectionEnabled(engine_configuration2_s const *engineConfiguration2);
|
||||||
|
|
||||||
|
// 'random' value to be sure we are not treating any non-zero trash as TRUE
|
||||||
|
#define MAGIC_TRUE_VALUE 153351512
|
||||||
|
|
||||||
|
template<int RPM_BIN_SIZE, int LOAD_BIN_SIZE>
|
||||||
|
class Map3D {
|
||||||
|
public:
|
||||||
|
void init(float table[RPM_BIN_SIZE][LOAD_BIN_SIZE]);
|
||||||
|
float getValue(float x, float xBin[], float y, float yBin[]);
|
||||||
|
void setAll(float value);
|
||||||
|
private:
|
||||||
|
float *pointers[LOAD_BIN_SIZE];
|
||||||
|
int initialized;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<int RPM_BIN_SIZE, int LOAD_BIN_SIZE>
|
||||||
|
void Map3D<RPM_BIN_SIZE, LOAD_BIN_SIZE>::init(float table[RPM_BIN_SIZE][LOAD_BIN_SIZE]) {
|
||||||
|
for (int k = 0; k < LOAD_BIN_SIZE; k++)
|
||||||
|
pointers[k] = table[k];
|
||||||
|
initialized = MAGIC_TRUE_VALUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<int RPM_BIN_SIZE, int LOAD_BIN_SIZE>
|
||||||
|
float Map3D<RPM_BIN_SIZE, LOAD_BIN_SIZE>::getValue(float x, float xBin[], float y, float yBin[]) {
|
||||||
|
efiAssert(initialized == MAGIC_TRUE_VALUE, "fuel map initialized", NAN);
|
||||||
|
return interpolate3d(x, xBin, LOAD_BIN_SIZE, y, yBin, RPM_BIN_SIZE, pointers);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<int RPM_BIN_SIZE, int LOAD_BIN_SIZE>
|
||||||
|
void Map3D<RPM_BIN_SIZE, LOAD_BIN_SIZE>::setAll(float value) {
|
||||||
|
for (int l = 0; l < LOAD_BIN_SIZE; l++) {
|
||||||
|
for (int r = 0; r < RPM_BIN_SIZE; r++) {
|
||||||
|
pointers[l][r] = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef Map3D<16, 16> Map3D1616;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C"
|
extern "C"
|
||||||
{
|
{
|
||||||
|
@ -18,9 +66,9 @@ extern "C"
|
||||||
//float getDefaultVE(int rpm);
|
//float getDefaultVE(int rpm);
|
||||||
|
|
||||||
float getDefaultFuel(int rpm, float map);
|
float getDefaultFuel(int rpm, float map);
|
||||||
//float getTCharge(int rpm, int tps, float coolantTemp, float airTemp);
|
|
||||||
|
|
||||||
float getOneDegreeTimeMs(int rpm);
|
float getOneDegreeTimeMs(int rpm);
|
||||||
|
float getOneDegreeTimeUs(int rpm);
|
||||||
float getCrankshaftRevolutionTimeMs(int rpm);
|
float getCrankshaftRevolutionTimeMs(int rpm);
|
||||||
|
|
||||||
int isCrankingRT(engine_configuration_s *engineConfiguration, int rpm);
|
int isCrankingRT(engine_configuration_s *engineConfiguration, int rpm);
|
||||||
|
@ -35,6 +83,7 @@ float getEngineLoadT(engine_configuration_s *engineConfiguration);
|
||||||
float getSparkDwellMsT(engine_configuration_s *engineConfiguration, int rpm);
|
float getSparkDwellMsT(engine_configuration_s *engineConfiguration, int rpm);
|
||||||
#define getSparkDwellMs(rpm) getSparkDwellMsT(engineConfiguration, rpm)
|
#define getSparkDwellMs(rpm) getSparkDwellMsT(engineConfiguration, rpm)
|
||||||
|
|
||||||
|
|
||||||
int getCylinderId(firing_order_e firingOrder, int index);
|
int getCylinderId(firing_order_e firingOrder, int index);
|
||||||
|
|
||||||
void setTableBin(float array[], int size, float l, float r);
|
void setTableBin(float array[], int size, float l, float r);
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
|
|
||||||
CONTROLLERS_MATH_SRC =
|
CONTROLLERS_MATH_SRC =
|
||||||
|
|
||||||
CONTROLLERS_MATH_SRC_CPP = $(PROJECT_DIR)/controllers/math/engine_math.cpp
|
CONTROLLERS_MATH_SRC_CPP = $(PROJECT_DIR)/controllers/math/engine_math.cpp \
|
||||||
|
$(PROJECT_DIR)/controllers/math/speed_density.cpp
|
||||||
|
|
|
@ -0,0 +1,78 @@
|
||||||
|
/**
|
||||||
|
* @file speed_density.cpp
|
||||||
|
*
|
||||||
|
* @date May 29, 2014
|
||||||
|
* @author Andrey Belomutskiy, (c) 2012-2014
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "main.h"
|
||||||
|
#include "speed_density.h"
|
||||||
|
#include "interpolation.h"
|
||||||
|
#include "engine.h"
|
||||||
|
#include "rpm_calculator.h"
|
||||||
|
#include "engine_math.h"
|
||||||
|
#include "engine_state.h"
|
||||||
|
|
||||||
|
#define K_AT_MIN_RPM_MIN_TPS 0.25
|
||||||
|
#define K_AT_MIN_RPM_MAX_TPS 0.25
|
||||||
|
#define K_AT_MAX_RPM_MIN_TPS 0.25
|
||||||
|
#define K_AT_MAX_RPM_MAX_TPS 0.9
|
||||||
|
|
||||||
|
#define rpmMin 500
|
||||||
|
#define rpmMax 8000
|
||||||
|
|
||||||
|
static Map3D1616 veMap;
|
||||||
|
static Map3D1616 afrMap;
|
||||||
|
|
||||||
|
#define tpMin 0
|
||||||
|
#define tpMax 100
|
||||||
|
// http://rusefi.com/math/t_charge.html
|
||||||
|
float getTCharge(int rpm, int tps, float coolantTemp, float airTemp) {
|
||||||
|
float minRpmKcurrentTPS = interpolate(tpMin, K_AT_MIN_RPM_MIN_TPS, tpMax,
|
||||||
|
K_AT_MIN_RPM_MAX_TPS, tps);
|
||||||
|
float maxRpmKcurrentTPS = interpolate(tpMin, K_AT_MAX_RPM_MIN_TPS, tpMax,
|
||||||
|
K_AT_MAX_RPM_MAX_TPS, tps);
|
||||||
|
|
||||||
|
float Tcharge_coff = interpolate(rpmMin, minRpmKcurrentTPS, rpmMax, maxRpmKcurrentTPS, rpm);
|
||||||
|
|
||||||
|
float Tcharge = coolantTemp * (1 - Tcharge_coff) + airTemp * Tcharge_coff;
|
||||||
|
|
||||||
|
return Tcharge;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* is J/g*K
|
||||||
|
*/
|
||||||
|
#define GAS_R 0.28705
|
||||||
|
|
||||||
|
float sdMath(engine_configuration_s *engineConfiguration, float VE, float MAP, float AFR, float temp) {
|
||||||
|
float injectorFlowRate = cc_minute_to_gramm_second(engineConfiguration->injectorFlow);
|
||||||
|
float Vol = engineConfiguration->displacement / engineConfiguration->cylindersCount;
|
||||||
|
return (Vol * VE * MAP) / (AFR * injectorFlowRate * GAS_R * temp);
|
||||||
|
}
|
||||||
|
|
||||||
|
float getSpeedDensityFuel(Engine *engine) {
|
||||||
|
int rpm = engine->rpmCalculator->rpm();
|
||||||
|
|
||||||
|
float tps = getTPS();
|
||||||
|
float coolantC = getCoolantTemperature();
|
||||||
|
float intakeC = getIntakeAirTemperature();
|
||||||
|
float tChargeK = convertCelciusToKelvin(getTCharge(rpm, tps, coolantC, intakeC));
|
||||||
|
float MAP = getMap();
|
||||||
|
float VE = 0.8;//veMap.getValue(rpm)
|
||||||
|
float AFR = 14.7;
|
||||||
|
|
||||||
|
return sdMath(engine->engineConfiguration, VE, MAP, AFR, tChargeK);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void setDetaultVETable(engine_configuration_s *engineConfiguration) {
|
||||||
|
setTableBin(engineConfiguration->veRpmBins, FUEL_RPM_COUNT, 800, 7000);
|
||||||
|
|
||||||
|
veMap.setAll(0.8);
|
||||||
|
}
|
||||||
|
|
||||||
|
void initSpeedDensity(configuration_s *config) {
|
||||||
|
veMap.init(config->engineConfiguration->veTable);
|
||||||
|
afrMap.init(config->engineConfiguration->afrTable);
|
||||||
|
}
|
|
@ -0,0 +1,23 @@
|
||||||
|
/**
|
||||||
|
* @file speed_density.h
|
||||||
|
*
|
||||||
|
* @date May 29, 2014
|
||||||
|
* @author Andrey Belomutskiy, (c) 2012-2014
|
||||||
|
*/
|
||||||
|
#ifndef SPEED_DENSITY_H_
|
||||||
|
#define SPEED_DENSITY_H_
|
||||||
|
|
||||||
|
#include "engine_configuration.h"
|
||||||
|
#include "ec2.h"
|
||||||
|
|
||||||
|
float getTCharge(int rpm, int tps, float coolantTemp, float airTemp);
|
||||||
|
void setDetaultVETable(engine_configuration_s *engineConfiguration);
|
||||||
|
float sdMath(engine_configuration_s *engineConfiguration, float VE, float MAP, float AFR, float temp);
|
||||||
|
|
||||||
|
#define gramm_second_to_cc_minute(gs) ((gs) / 0.0119997981)
|
||||||
|
|
||||||
|
#define cc_minute_to_gramm_second(ccm) ((ccm) * 0.0119997981)
|
||||||
|
|
||||||
|
void initSpeedDensity(configuration_s *config);
|
||||||
|
|
||||||
|
#endif /* SPEED_DENSITY_H_ */
|
|
@ -12,15 +12,6 @@
|
||||||
|
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C"
|
|
||||||
{
|
|
||||||
#endif /* __cplusplus */
|
|
||||||
|
|
||||||
float getAfr(void);
|
float getAfr(void);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif /* __cplusplus */
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -16,22 +16,19 @@ extern engine_configuration_s * engineConfiguration;
|
||||||
*
|
*
|
||||||
* @returns kPa value
|
* @returns kPa value
|
||||||
*/
|
*/
|
||||||
float getMAPValueHonda_Denso183(float voltage) {
|
static FastInterpolation denso183(0, -6.64, 5, 182.78);
|
||||||
return interpolate(0, -6.64, 5, 182.78, voltage);
|
|
||||||
}
|
|
||||||
|
|
||||||
float getMAPValueMPX_4250(float voltage) {
|
static FastInterpolation mpx4250(0, 8, 5, 260);
|
||||||
return interpolate(0, 8, 5, 260, voltage);
|
|
||||||
}
|
|
||||||
|
|
||||||
float decodePressure(float voltage, air_pressure_sensor_config_s * config) {
|
float decodePressure(float voltage, air_pressure_sensor_config_s * config) {
|
||||||
switch (config->sensorType) {
|
switch (config->sensorType) {
|
||||||
case MT_CUSTOM:
|
case MT_CUSTOM:
|
||||||
|
// todo: introduce 'FastInterpolation customMap'
|
||||||
return interpolate(0, config->Min, 5, config->Max, voltage);
|
return interpolate(0, config->Min, 5, config->Max, voltage);
|
||||||
case MT_DENSO183:
|
case MT_DENSO183:
|
||||||
return getMAPValueHonda_Denso183(voltage);
|
return denso183.getValue(voltage);
|
||||||
case MT_MPX4250:
|
case MT_MPX4250:
|
||||||
return getMAPValueMPX_4250(voltage);
|
return mpx4250.getValue(voltage);
|
||||||
default:
|
default:
|
||||||
firmwareError("Unknown MAP type: %d", config->sensorType);
|
firmwareError("Unknown MAP type: %d", config->sensorType);
|
||||||
return NAN;
|
return NAN;
|
||||||
|
@ -47,6 +44,9 @@ float getMapByVoltage(float voltage) {
|
||||||
return decodePressure(voltage, config);
|
return decodePressure(voltage, config);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Manifold Absolute Pressure, in kPa
|
||||||
|
*/
|
||||||
float getRawMap(void) {
|
float getRawMap(void) {
|
||||||
float voltage = getVoltageDivided(engineConfiguration->map.sensor.hwChannel);
|
float voltage = getVoltageDivided(engineConfiguration->map.sensor.hwChannel);
|
||||||
return getMapByVoltage(voltage);
|
return getMapByVoltage(voltage);
|
|
@ -6,6 +6,8 @@ extern "C"
|
||||||
{
|
{
|
||||||
#endif /* __cplusplus */
|
#endif /* __cplusplus */
|
||||||
|
|
||||||
|
#include "sensor_types.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return Raw MAP sensor value right now
|
* @return Raw MAP sensor value right now
|
||||||
*/
|
*/
|
||||||
|
@ -17,8 +19,7 @@ float getBaroPressure(void);
|
||||||
float getMap(void);
|
float getMap(void);
|
||||||
float getMapVoltage(void);
|
float getMapVoltage(void);
|
||||||
float getMapByVoltage(float voltage);
|
float getMapByVoltage(float voltage);
|
||||||
float getMAPValueHonda_Denso183(float volts);
|
float decodePressure(float voltage, air_pressure_sensor_config_s * config);
|
||||||
float getMAPValueMPX_4250(float volts);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,6 +14,9 @@
|
||||||
#include "rusefi_enums.h"
|
#include "rusefi_enums.h"
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
/**
|
||||||
|
* kPa value at zero volts
|
||||||
|
*/
|
||||||
float Min;
|
float Min;
|
||||||
float Max;
|
float Max;
|
||||||
air_pressure_sensor_type_e sensorType;
|
air_pressure_sensor_type_e sensorType;
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
|
|
||||||
CONTROLLERS_SENSORS_SRC = $(PROJECT_DIR)/controllers/sensors/tps.c \
|
CONTROLLERS_SENSORS_SRC = $(PROJECT_DIR)/controllers/sensors/allsensors.c \
|
||||||
$(PROJECT_DIR)/controllers/sensors/allsensors.c \
|
|
||||||
$(PROJECT_DIR)/controllers/sensors/maf.c \
|
$(PROJECT_DIR)/controllers/sensors/maf.c \
|
||||||
$(PROJECT_DIR)/controllers/sensors/map.c \
|
|
||||||
$(PROJECT_DIR)/controllers/sensors/ego.c \
|
|
||||||
$(PROJECT_DIR)/controllers/sensors/voltage.c
|
$(PROJECT_DIR)/controllers/sensors/voltage.c
|
||||||
|
|
||||||
CONTROLLERS_SENSORS_SRC_CPP = $(PROJECT_DIR)/controllers/sensors/thermistors.cpp
|
CONTROLLERS_SENSORS_SRC_CPP = $(PROJECT_DIR)/controllers/sensors/thermistors.cpp \
|
||||||
|
$(PROJECT_DIR)/controllers/sensors/map.cpp \
|
||||||
|
$(PROJECT_DIR)/controllers/sensors/tps.cpp \
|
||||||
|
$(PROJECT_DIR)/controllers/sensors/ego.cpp
|
||||||
|
|
|
@ -52,7 +52,7 @@ float convertKelvinToC(float tempK) {
|
||||||
return tempK - KELV;
|
return tempK - KELV;
|
||||||
}
|
}
|
||||||
|
|
||||||
float convertCelciustoKelvin(float tempC) {
|
float convertCelciusToKelvin(float tempC) {
|
||||||
return tempC + KELV;
|
return tempC + KELV;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -81,7 +81,7 @@ float getKelvinTemperature(float resistance, ThermistorConf *thermistor) {
|
||||||
|
|
||||||
float getResistance(Thermistor *thermistor) {
|
float getResistance(Thermistor *thermistor) {
|
||||||
float voltage = getVoltageDivided(thermistor->channel);
|
float voltage = getVoltageDivided(thermistor->channel);
|
||||||
chDbgCheck(thermistor->config != NULL, "config is null");
|
efiAssert(thermistor->config != NULL, "config is null", NAN);
|
||||||
float resistance = getR2InVoltageDividor(voltage, _5_VOLTS, thermistor->config->bias_resistor);
|
float resistance = getR2InVoltageDividor(voltage, _5_VOLTS, thermistor->config->bias_resistor);
|
||||||
return resistance;
|
return resistance;
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,7 +29,7 @@ float getTempK(float resistance);
|
||||||
* converts Kelvin temperature into Celcius temperature
|
* converts Kelvin temperature into Celcius temperature
|
||||||
*/
|
*/
|
||||||
float convertKelvinToCelcius(float tempK);
|
float convertKelvinToCelcius(float tempK);
|
||||||
float convertCelciustoKelvin(float tempC);
|
float convertCelciusToKelvin(float tempC);
|
||||||
|
|
||||||
float convertCelciustoF(float tempC);
|
float convertCelciustoF(float tempC);
|
||||||
float convertFtoCelcius(float tempF);
|
float convertFtoCelcius(float tempF);
|
||||||
|
|
|
@ -93,7 +93,7 @@ static float getPrimatyRawTPS(void) {
|
||||||
/*
|
/*
|
||||||
* In case of dual TPS this function would return logical TPS position
|
* In case of dual TPS this function would return logical TPS position
|
||||||
*
|
*
|
||||||
* @return Current TPS position. 0 means idle and 100 means Wide Open Throttle
|
* @return Current TPS position, percent of WOT. 0 means idle and 100 means Wide Open Throttle
|
||||||
*/
|
*/
|
||||||
float getTPS(void) {
|
float getTPS(void) {
|
||||||
// todo: if (config->isDualTps)
|
// todo: if (config->isDualTps)
|
|
@ -12,11 +12,6 @@
|
||||||
|
|
||||||
#include "global.h"
|
#include "global.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C"
|
|
||||||
{
|
|
||||||
#endif /* __cplusplus */
|
|
||||||
|
|
||||||
float getTPS(void);
|
float getTPS(void);
|
||||||
int convertVoltageTo10bitADC(float voltage);
|
int convertVoltageTo10bitADC(float voltage);
|
||||||
int getTPS10bitAdc(void);
|
int getTPS10bitAdc(void);
|
||||||
|
@ -39,8 +34,4 @@ typedef struct {
|
||||||
void saveTpsState(time_t now, float curValue);
|
void saveTpsState(time_t now, float curValue);
|
||||||
float getTpsRateOfChange(void);
|
float getTpsRateOfChange(void);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif /* __cplusplus */
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/**
|
/**
|
||||||
* @file settings.c
|
* @file settings.cpp
|
||||||
* @brief This file is about configuring engine via the human-readable protocol
|
* @brief This file is about configuring engine via the human-readable protocol
|
||||||
*
|
*
|
||||||
* @date Dec 30, 2012
|
* @date Dec 30, 2012
|
||||||
|
@ -18,6 +18,7 @@
|
||||||
#include "tps.h"
|
#include "tps.h"
|
||||||
#include "ec2.h"
|
#include "ec2.h"
|
||||||
#include "map.h"
|
#include "map.h"
|
||||||
|
#include "trigger_decoder.h"
|
||||||
|
|
||||||
#if EFI_PROD_CODE
|
#if EFI_PROD_CODE
|
||||||
#include "rusefi.h"
|
#include "rusefi.h"
|
||||||
|
@ -91,11 +92,32 @@ const char* getConfigurationName(engine_configuration_s *engineConfiguration) {
|
||||||
return "Ford Escort GT";
|
return "Ford Escort GT";
|
||||||
case CITROEN_TU3JP:
|
case CITROEN_TU3JP:
|
||||||
return "Citroen TU3JP";
|
return "Citroen TU3JP";
|
||||||
|
case ROVER_V8:
|
||||||
|
return "Rover v8";
|
||||||
default:
|
default:
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const char * pinModeToString(pin_output_mode_e mode) {
|
||||||
|
switch (mode) {
|
||||||
|
case OM_DEFAULT:
|
||||||
|
return "default";
|
||||||
|
case OM_INVERTED:
|
||||||
|
return "inverted";
|
||||||
|
case OM_OPENDRAIN:
|
||||||
|
return "open drain";
|
||||||
|
case OM_OPENDRAIN_INVERTED:
|
||||||
|
return "open drain inverted";
|
||||||
|
default:
|
||||||
|
return "unexpected";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char * boolToString(bool_t value) {
|
||||||
|
return value ? "Yes" : "No";
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Prints current engine configuration to human-readable console.
|
* @brief Prints current engine configuration to human-readable console.
|
||||||
*/
|
*/
|
||||||
|
@ -147,38 +169,41 @@ void printConfiguration(engine_configuration_s *engineConfiguration, engine_conf
|
||||||
|
|
||||||
// scheduleMsg(&logger, "crankingRpm: %d", engineConfiguration->crankingSettings.crankingRpm);
|
// scheduleMsg(&logger, "crankingRpm: %d", engineConfiguration->crankingSettings.crankingRpm);
|
||||||
|
|
||||||
scheduleMsg(&logger, "idlePinMode: %d", boardConfiguration->idleValvePinMode);
|
scheduleMsg(&logger, "idlePinMode: %s", pinModeToString(boardConfiguration->idleValvePinMode));
|
||||||
scheduleMsg(&logger, "malfunctionIndicatorPinMode: %d", boardConfiguration->malfunctionIndicatorPinMode);
|
scheduleMsg(&logger, "malfunctionIndicatorPinMode: %s", pinModeToString(boardConfiguration->malfunctionIndicatorPinMode));
|
||||||
scheduleMsg(&logger, "analogInputDividerCoefficient: %f", engineConfiguration->analogInputDividerCoefficient);
|
scheduleMsg(&logger, "analogInputDividerCoefficient: %f", engineConfiguration->analogInputDividerCoefficient);
|
||||||
|
|
||||||
scheduleMsg(&logger, "needSecondTriggerInput: %d", engineConfiguration->needSecondTriggerInput);
|
scheduleMsg(&logger, "needSecondTriggerInput: %s", boolToString(engineConfiguration->needSecondTriggerInput));
|
||||||
|
|
||||||
#if EFI_PROD_CODE
|
#if EFI_PROD_CODE
|
||||||
scheduleMsg(&logger, "idleValvePin: %s", hwPortname(boardConfiguration->idleValvePin));
|
scheduleMsg(&logger, "idleValvePin: %s", hwPortname(boardConfiguration->idleValvePin));
|
||||||
scheduleMsg(&logger, "fuelPumpPin: mode %d @ %s", boardConfiguration->fuelPumpPinMode,
|
scheduleMsg(&logger, "fuelPumpPin: mode %s @ %s", pinModeToString(boardConfiguration->fuelPumpPinMode),
|
||||||
hwPortname(boardConfiguration->fuelPumpPin));
|
hwPortname(boardConfiguration->fuelPumpPin));
|
||||||
|
|
||||||
scheduleMsg(&logger, "injectionPins: mode %d", boardConfiguration->injectionPinMode);
|
scheduleMsg(&logger, "injectionPins: mode %s", pinModeToString(boardConfiguration->injectionPinMode));
|
||||||
for (int i = 0; i < engineConfiguration->cylindersCount; i++) {
|
for (int i = 0; i < engineConfiguration->cylindersCount; i++) {
|
||||||
brain_pin_e brainPin = boardConfiguration->injectionPins[i];
|
brain_pin_e brainPin = boardConfiguration->injectionPins[i];
|
||||||
|
|
||||||
scheduleMsg(&logger, "injection %d @ %s", i, hwPortname(brainPin));
|
scheduleMsg(&logger, "injection %d @ %s", i, hwPortname(brainPin));
|
||||||
}
|
}
|
||||||
|
|
||||||
scheduleMsg(&logger, "ignitionPins: mode %d", boardConfiguration->ignitionPinMode);
|
scheduleMsg(&logger, "ignitionPins: mode %s", pinModeToString(boardConfiguration->ignitionPinMode));
|
||||||
// todo: calculate coils count based on ignition mode
|
// todo: calculate coils count based on ignition mode
|
||||||
for (int i = 0; i < 4; i++) {
|
for (int i = 0; i < 4; i++) {
|
||||||
brain_pin_e brainPin = boardConfiguration->ignitionPins[i];
|
brain_pin_e brainPin = boardConfiguration->ignitionPins[i];
|
||||||
scheduleMsg(&logger, "ignition %d @ %s", i, hwPortname(brainPin));
|
scheduleMsg(&logger, "ignition %d @ %s", i, hwPortname(brainPin));
|
||||||
}
|
}
|
||||||
|
|
||||||
scheduleMsg(&logger, "primary trigger simulator: %s %d", hwPortname(boardConfiguration->triggerSimulatorPins[0]),
|
scheduleMsg(&logger, "primary trigger simulator: %s %s", hwPortname(boardConfiguration->triggerSimulatorPins[0]),
|
||||||
boardConfiguration->triggerSimulatorPinModes[0]);
|
pinModeToString(boardConfiguration->triggerSimulatorPinModes[0]));
|
||||||
scheduleMsg(&logger, "secondary trigger simulator: %s %d", hwPortname(boardConfiguration->triggerSimulatorPins[1]),
|
scheduleMsg(&logger, "secondary trigger simulator: %s %s", hwPortname(boardConfiguration->triggerSimulatorPins[1]),
|
||||||
boardConfiguration->triggerSimulatorPinModes[1]);
|
pinModeToString(boardConfiguration->triggerSimulatorPinModes[1]));
|
||||||
|
|
||||||
|
scheduleMsg(&logger, "primary trigger input: %s", hwPortname(boardConfiguration->primaryTriggerInputPin));
|
||||||
|
|
||||||
#endif /* EFI_PROD_CODE */
|
#endif /* EFI_PROD_CODE */
|
||||||
|
|
||||||
scheduleMsg(&logger, "isInjectionEnabledFlag %d", engineConfiguration2->isInjectionEnabledFlag);
|
scheduleMsg(&logger, "isInjectionEnabledFlag %s", boolToString(engineConfiguration2->isInjectionEnabledFlag));
|
||||||
|
|
||||||
// appendPrintf(&logger, DELIMETER);
|
// appendPrintf(&logger, DELIMETER);
|
||||||
// scheduleLogging(&logger);
|
// scheduleLogging(&logger);
|
||||||
|
@ -197,8 +222,9 @@ static void setTimingMode(int value) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void setEngineType(int value) {
|
void setEngineType(int value) {
|
||||||
engineConfiguration->engineType = (engine_type_e)value;
|
engineConfiguration->engineType = (engine_type_e) value;
|
||||||
resetConfigurationExt(&logger, (engine_type_e) value, engineConfiguration, engineConfiguration2, boardConfiguration);
|
resetConfigurationExt(&logger, (engine_type_e) value, engineConfiguration, engineConfiguration2,
|
||||||
|
boardConfiguration);
|
||||||
#if EFI_INTERNAL_FLASH
|
#if EFI_INTERNAL_FLASH
|
||||||
writeToFlash();
|
writeToFlash();
|
||||||
// scheduleReset();
|
// scheduleReset();
|
||||||
|
@ -259,9 +285,9 @@ static void setRpmMultiplier(int value) {
|
||||||
doPrintConfiguration();
|
doPrintConfiguration();
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint8_t pinNameBuffer[16];
|
static char pinNameBuffer[16];
|
||||||
|
|
||||||
static void printThermistor(char *msg, Thermistor *thermistor) {
|
static void printThermistor(const char *msg, Thermistor *thermistor) {
|
||||||
int adcChannel = thermistor->channel;
|
int adcChannel = thermistor->channel;
|
||||||
float voltage = getVoltageDivided(adcChannel);
|
float voltage = getVoltageDivided(adcChannel);
|
||||||
float r = getResistance(thermistor);
|
float r = getResistance(thermistor);
|
||||||
|
@ -278,17 +304,15 @@ static void printThermistor(char *msg, Thermistor *thermistor) {
|
||||||
|
|
||||||
static void printMAPInfo(void) {
|
static void printMAPInfo(void) {
|
||||||
#if EFI_PROD_CODE
|
#if EFI_PROD_CODE
|
||||||
scheduleMsg(&logger, "map type=%d raw=%f MAP=%f", engineConfiguration->map.sensor.sensorType, getRawMap(), getMap());
|
scheduleMsg(&logger, "map type=%d raw=%f MAP=%f", engineConfiguration->map.sensor.sensorType, getRawMap(),
|
||||||
|
getMap());
|
||||||
if (engineConfiguration->map.sensor.sensorType == MT_CUSTOM) {
|
if (engineConfiguration->map.sensor.sensorType == MT_CUSTOM) {
|
||||||
scheduleMsg(&logger, "min=%f max=%f", engineConfiguration->map.sensor.Min,
|
scheduleMsg(&logger, "min=%f max=%f", engineConfiguration->map.sensor.Min, engineConfiguration->map.sensor.Max);
|
||||||
engineConfiguration->map.sensor.Max);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
scheduleMsg(&logger, "baro type=%d value=%f", engineConfiguration->baroSensor.sensorType, getBaroPressure());
|
scheduleMsg(&logger, "baro type=%d value=%f", engineConfiguration->baroSensor.sensorType, getBaroPressure());
|
||||||
if (engineConfiguration->baroSensor.sensorType == MT_CUSTOM) {
|
if (engineConfiguration->baroSensor.sensorType == MT_CUSTOM) {
|
||||||
scheduleMsg(&logger, "min=%f max=%f", engineConfiguration->baroSensor.Min,
|
scheduleMsg(&logger, "min=%f max=%f", engineConfiguration->baroSensor.Min, engineConfiguration->baroSensor.Max);
|
||||||
engineConfiguration->baroSensor.Max);
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -388,6 +412,13 @@ static void setIgnitionMode(int value) {
|
||||||
doPrintConfiguration();
|
doPrintConfiguration();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void setTotalToothCount(int value) {
|
||||||
|
engineConfiguration->triggerConfig.totalToothCount = value;
|
||||||
|
initializeTriggerShape(&logger, engineConfiguration, engineConfiguration2);
|
||||||
|
incrementGlobalConfigurationVersion();
|
||||||
|
doPrintConfiguration();
|
||||||
|
}
|
||||||
|
|
||||||
static void setCrankingChargeAngle(float value) {
|
static void setCrankingChargeAngle(float value) {
|
||||||
engineConfiguration->crankingChargeAngle = value;
|
engineConfiguration->crankingChargeAngle = value;
|
||||||
incrementGlobalConfigurationVersion();
|
incrementGlobalConfigurationVersion();
|
||||||
|
@ -500,5 +531,6 @@ void initSettings(void) {
|
||||||
|
|
||||||
addConsoleAction("enable_injection", enableInjection);
|
addConsoleAction("enable_injection", enableInjection);
|
||||||
addConsoleAction("disable_injection", disableInjection);
|
addConsoleAction("disable_injection", disableInjection);
|
||||||
|
addConsoleActionI("set_total_tooth_count", setTotalToothCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,9 +17,6 @@ extern "C"
|
||||||
void initSettings(void);
|
void initSettings(void);
|
||||||
void pokeControl(void);
|
void pokeControl(void);
|
||||||
void setEngineType(int value);
|
void setEngineType(int value);
|
||||||
int getInjectionPeriod(void);
|
|
||||||
int getInjectionOffset(void);
|
|
||||||
int getInjectionDivider(void);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue