diff --git a/.github/workflows/build-firmware.yaml b/.github/workflows/build-firmware.yaml new file mode 100644 index 0000000000..2bcff4963f --- /dev/null +++ b/.github/workflows/build-firmware.yaml @@ -0,0 +1,101 @@ +name: Firmware CI + +on: [push,pull_request] + +jobs: + build: + runs-on: ubuntu-latest + + strategy: + # Let all builds finish even if one fails early + fail-fast: false + matrix: + # What boards should we build for? In the 'include' section below, + # set up what each of these boards needs to build. + build-target: [frankenso, frankenso-pal, mre-f4, mre-f7, prometheus-405, prometheus-469, proteus, kinetis] + build-type: [debug, release] + + include: + # Board configurations + - build-target: frankenso + efi-cpu: ARCH_STM32F4 + efi-board: st_stm32f4 + + - build-target: frankenso-pal + efi-cpu: ARCH_STM32F4 + efi-board: st_stm32f4 + target-extra-params: -DHAL_TRIGGER_USE_PAL=TRUE -DHAL_USE_ICU=FALSE -DEFI_VEHICLE_SPEED=FALSE -DEFI_LOGIC_ANALYZER=FALSE + + - build-target: mre-f4 + efi-cpu: ARCH_STM32F4 + efi-board: microrusefi + + - build-target: mre-f7 + efi-cpu: ARCH_STM32F7 + efi-board: microrusefi + + - build-target: prometheus-405 + efi-cpu: ARCH_STM32F4 + efi-board: prometheus/f405 + + - build-target: prometheus-469 + efi-cpu: ARCH_STM32F4 + efi-board: prometheus/f469 + + - build-target: proteus + efi-cpu: ARCH_STM32F7 + efi-board: proteus + + - build-target: kinetis + efi-cpu: kinetis + efi-board: kinetis + target-extra-params: -DCPU_MKE16F512VLH16 -DCPU_MKE16F512VLH16_cm4 -D__USE_CMSI -DDEFAULT_ENGINE_TYPE=MINIMAL_PINS + extra-options: USE_FATFS=no USE_BOOTLOADER=no + + # Debug vs. release configuration + - build-type: debug + type-extra-params: -DDUMMY + build-debug-level-opt: -O0 -ggdb -g3 + + - build-type: release + type-extra-params: -DEFI_ENABLE_ASSERTS=FALSE -DCH_DBG_ENABLE_TRACE=FALSE -DCH_DBG_ENABLE_ASSERTS=FALSE -DCH_DBG_ENABLE_STACK_CHECK=FALSE -DCH_DBG_FILL_THREADS=FALSE -DCH_DBG_THREADS_PROFILING=FALSE + build-debug-level-opt: -O2 -ggdb -g3 + + exclude: + - build-target: kinetis + build-type: debug + + steps: + - uses: actions/checkout@v1 + with: + fetch-depth: 1 + submodules: recursive + + # Build machines don't have arm-none-eabi gcc, so let's download it and put it on the path + - name: Download & Install GCC + run: | + wget 'https://developer.arm.com/-/media/Files/downloads/gnu-rm/9-2019q4/RC2.1/gcc-arm-none-eabi-9-2019-q4-major-x86_64-linux.tar.bz2?revision=6e63531f-8cb1-40b9-bbfc-8a57cdfc01b4&la=en&hash=F761343D43A0587E8AC0925B723C04DBFB848339' -O compiler.tar.bz2 + tar -xvf compiler.tar.bz2 + echo "::add-path::`pwd`/gcc-arm-none-eabi-9-2019-q4-major/bin" + + # Make sure the compiler we just downloaded works - just print out the version + - name: Test Compiler + run: arm-none-eabi-gcc -v + + # Build the firmware! + - name: Build Firmware + working-directory: ./firmware/ + run: make -j4 PROJECT_BOARD=${{matrix.efi-board}} PROJECT_CPU=${{matrix.efi-cpu}} EXTRA_PARAMS="${{matrix.type-extra-params}} ${{matrix.target-extra-params}}" DEBUG_LEVEL_OPT='${{matrix.build-debug-level-opt}}' ${{matrix.extra-options}} + + # The next two steps upload the bin and elf as build artifacts + - name: Upload elf + uses: actions/upload-artifact@v1 + with: + name: firmware-${{matrix.build-target}}-${{matrix.build-type}}-elf + path: ./firmware/build/rusefi.elf + + - name: Upload bin + uses: actions/upload-artifact@v1 + with: + name: firmware-${{matrix.build-target}}-${{matrix.build-type}}-bin + path: ./firmware/build/rusefi.bin diff --git a/.github/workflows/build-simulator.yaml b/.github/workflows/build-simulator.yaml new file mode 100644 index 0000000000..1399b05af4 --- /dev/null +++ b/.github/workflows/build-simulator.yaml @@ -0,0 +1,21 @@ +name: Simulator CI + +on: [push,pull_request] + +jobs: + build: + + runs-on: ubuntu-latest + + steps: + - name: Install Simulator Deps + run: sudo apt-get update && sudo apt-get install -y gcc-multilib g++-multilib + + - uses: actions/checkout@v1 + with: + fetch-depth: 1 + submodules: recursive + + - name: Build Simulator + working-directory: ./simulator/ + run: make -j4 diff --git a/.github/workflows/build-unit-tests.yaml b/.github/workflows/build-unit-tests.yaml index fe82baca21..98d6dfea7c 100644 --- a/.github/workflows/build-unit-tests.yaml +++ b/.github/workflows/build-unit-tests.yaml @@ -1,6 +1,6 @@ -name: unit test ci +name: Unit Test CI -on: [push] +on: [push,pull_request] jobs: build: diff --git a/firmware/Makefile b/firmware/Makefile index c3b183e1fb..d4b4afdcba 100644 --- a/firmware/Makefile +++ b/firmware/Makefile @@ -7,6 +7,8 @@ CHIBIOS = ChibiOS RULESPATH = $(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC RULESFILE = $(RULESPATH)/rules.mk +include rusefi_rules.mk + # Define project name here PROJECT = rusefi PROJECT_DIR = . @@ -35,9 +37,12 @@ endif # Compiler options here. ifeq ($(USE_OPT),) - USE_OPT = $(EXTRA_PARAMS) $(DEBUG_LEVEL_OPT) $(RFLAGS) -Wno-error=implicit-fallthrough -Wno-error=bool-operation -fomit-frame-pointer -falign-functions=16 -Werror -Wno-error=pointer-sign -Wno-error=unused-function -Wno-error=unused-variable -Wno-error=sign-compare -Wno-error=unused-parameter -Werror=missing-field-initializers -Werror=type-limits -Wno-error=strict-aliasing -Wno-error=attributes + USE_OPT = $(EXTRA_PARAMS) $(DEBUG_LEVEL_OPT) $(RFLAGS) -Wno-error=implicit-fallthrough -Wno-error=bool-operation -fomit-frame-pointer -falign-functions=16 -Werror=type-limits -Wno-error=strict-aliasing -Wno-error=attributes endif + +USE_OPT += $(RUSEFI_OPT) + # C specific options here (added to USE_OPT). ifeq ($(USE_COPT),) USE_COPT = -fgnu89-inline -std=gnu99 -Werror-implicit-function-declaration @@ -150,13 +155,7 @@ endif include $(PROJECT_DIR)/config/boards/$(PROJECT_BOARD)/board.mk include $(PROJECT_DIR)/config/engines/engines.mk include $(PROJECT_DIR)/console/console.mk -include $(PROJECT_DIR)/controllers/algo/algo.mk include $(PROJECT_DIR)/controllers/controllers.mk -include $(PROJECT_DIR)/controllers/core/core.mk -include $(PROJECT_DIR)/controllers/math/math.mk -include $(PROJECT_DIR)/controllers/sensors/sensors.mk -include $(PROJECT_DIR)/controllers/system/system.mk -include $(PROJECT_DIR)/controllers/trigger/trigger.mk include $(PROJECT_DIR)/development/development.mk include $(PROJECT_DIR)/hw_layer/hw_layer.mk include $(PROJECT_DIR)/hw_layer/drivers/drivers.mk @@ -303,9 +302,7 @@ INCDIR = $(CHIBIOS)/os/license \ $(DEVELOPMENT_DIR) \ development/hw_layer \ development/test \ - $(CONTROLLERS_INC) \ - controllers/sensors \ - controllers/sensors/converters + $(CONTROLLERS_INC) # # Project, sources and paths diff --git a/firmware/bootloader/!compile_bootloader_405.bat b/firmware/bootloader/!compile_bootloader_405.bat index 954452daae..22ce79292f 100644 --- a/firmware/bootloader/!compile_bootloader_405.bat +++ b/firmware/bootloader/!compile_bootloader_405.bat @@ -4,7 +4,7 @@ echo Starting compilation for Prometheus-405 set PROJECT_BOARD=Prometheus set PROMETHEUS_BOARD=405 -set EXTRA_PARAMS=-DDUMMY -DEFI_BOOTLOADER -DSTM32F405xx -DEFI_ENABLE_ASSERTS=FALSE -DCH_DBG_ENABLE_CHECKS=FALSE -DCH_DBG_ENABLE_TRACE=FALSE -DCH_DBG_ENABLE_ASSERTS=FALSE -DCH_DBG_ENABLE_STACK_CHECK=FALSE -DCH_DBG_FILL_THREADS=FALSE ^ +set EXTRA_PARAMS=-DDUMMY -DEFI_BOOTLOADER -DSTM32F405xx -DEFI_ENABLE_ASSERTS=FALSE -DCH_DBG_ENABLE_CHECKS=FALSE -DCH_DBG_ENABLE_ASSERTS=FALSE -DCH_DBG_ENABLE_STACK_CHECK=FALSE -DCH_DBG_FILL_THREADS=FALSE ^ -DBOARD_TLE8888_COUNT=0 ^ -DBOARD_TLE6240_COUNT=0 ^ -DBOARD_MC33972_COUNT=0 ^ diff --git a/firmware/bootloader/!compile_bootloader_469.bat b/firmware/bootloader/!compile_bootloader_469.bat index 2d23879dc4..c4c08cb06e 100644 --- a/firmware/bootloader/!compile_bootloader_469.bat +++ b/firmware/bootloader/!compile_bootloader_469.bat @@ -4,7 +4,7 @@ echo Starting compilation for Prometheus-469 set PROJECT_BOARD=Prometheus set PROMETHEUS_BOARD=469 -set EXTRA_PARAMS=-DDUMMY -DEFI_BOOTLOADER -DSTM32F469xx -DEFI_ENABLE_ASSERTS=FALSE -DCH_DBG_ENABLE_CHECKS=FALSE -DCH_DBG_ENABLE_TRACE=FALSE -DCH_DBG_ENABLE_ASSERTS=FALSE -DCH_DBG_ENABLE_STACK_CHECK=FALSE -DCH_DBG_FILL_THREADS=FALSE ^ +set EXTRA_PARAMS=-DDUMMY -DEFI_BOOTLOADER -DSTM32F469xx -DEFI_ENABLE_ASSERTS=FALSE -DCH_DBG_ENABLE_CHECKS=FALSE -DCH_DBG_ENABLE_ASSERTS=FALSE -DCH_DBG_ENABLE_STACK_CHECK=FALSE -DCH_DBG_FILL_THREADS=FALSE ^ -DBOARD_TLE8888_COUNT=0 ^ -DBOARD_TLE6240_COUNT=0 ^ -DBOARD_MC33972_COUNT=0 ^ diff --git a/firmware/bootloader/!compile_bootloader_discovery407.bat b/firmware/bootloader/!compile_bootloader_discovery407.bat index 9f26200296..036c988e62 100644 --- a/firmware/bootloader/!compile_bootloader_discovery407.bat +++ b/firmware/bootloader/!compile_bootloader_discovery407.bat @@ -4,7 +4,7 @@ echo Starting compilation for Discovery-407 rem set PROJECT_BOARD=Prometheus rem set PROMETHEUS_BOARD=405 -rem set EXTRA_PARAMS=-DDUMMY -DSTM32F405xx -DEFI_ENABLE_ASSERTS=FALSE -DCH_DBG_ENABLE_CHECKS=FALSE -DCH_DBG_ENABLE_TRACE=FALSE -DCH_DBG_ENABLE_ASSERTS=FALSE -DCH_DBG_ENABLE_STACK_CHECK=FALSE -DCH_DBG_FILL_THREADS=FALSE -DCH_DBG_THREADS_PROFILING=FALSE +rem set EXTRA_PARAMS=-DDUMMY -DSTM32F405xx -DEFI_ENABLE_ASSERTS=FALSE -DCH_DBG_ENABLE_CHECKS=FALSE -DCH_DBG_ENABLE_ASSERTS=FALSE -DCH_DBG_ENABLE_STACK_CHECK=FALSE -DCH_DBG_FILL_THREADS=FALSE -DCH_DBG_THREADS_PROFILING=FALSE set EXTRA_PARAMS=-DDUMMY -DEFI_BOOTLOADER ^ -DCH_DBG_ENABLE_STACK_CHECK=FALSE ^ -DBOARD_TLE8888_COUNT=0 ^ diff --git a/firmware/bootloader/src/Makefile b/firmware/bootloader/src/Makefile index e14e79c18c..3d26e4a3ca 100644 --- a/firmware/bootloader/src/Makefile +++ b/firmware/bootloader/src/Makefile @@ -9,7 +9,7 @@ ifeq ($(DEBUG_LEVEL_OPT),) # this value would be used by default. For 'debug' configuration override with '-O0 -ggdb -g3' or something along these lines DEBUG_LEVEL_OPT = -O2 - DDEFS += -DEFI_ENABLE_ASSERTS=FALSE -DCH_DBG_ENABLE_TRACE=FALSE -DCH_DBG_ENABLE_ASSERTS=FALSE -DCH_DBG_ENABLE_STACK_CHECK=FALSE -DCH_DBG_FILL_THREADS=FALSE -DCH_DBG_THREADS_PROFILING=FALSE + DDEFS += -DEFI_ENABLE_ASSERTS=FALSE -DCH_DBG_ENABLE_ASSERTS=FALSE -DCH_DBG_ENABLE_STACK_CHECK=FALSE -DCH_DBG_FILL_THREADS=FALSE -DCH_DBG_THREADS_PROFILING=FALSE endif # disable some modules to shrink bootloader binary @@ -156,34 +156,22 @@ CSRC = $(STARTUPSRC) \ $(CHIBIOS)/os/various/syscalls.c \ $(CHIBIOS)/os/hal/lib/streams/memstreams.c \ $(CHIBIOS)/os/hal/lib/streams/chprintf.c \ - $(ENGINES_SRC) \ $(CONSOLESRC) \ $(DEV_SRC) \ $(HW_LAYER_EMS) \ $(HW_LAYER_DRIVERS_CORE) \ - $(CONTROLLERS_ALGO_SRC) \ - $(CONTROLLERS_CORE_SRC) \ - $(CONTROLLERS_SENSORS_SRC) \ $(FATFSSRC) \ $(SYSTEMSRC) \ # C++ sources that can be compiled in ARM or THUMB mode depending on the global # setting. CPPSRC = $(CHCPPSRC) \ - $(TRIGGER_SRC_CPP) \ - $(TRIGGER_DECODERS_SRC_CPP) \ $(DEV_SRC_CPP) \ - $(CONTROLLERS_ALGO_SRC_CPP) \ - $(SYSTEMSRC_CPP) \ $(BOARDSRC_CPP) \ - $(ENGINES_SRC_CPP) \ $(HW_LAYER_EMS_CPP) \ $(HW_SENSORS_SRC) \ $(TUNERSTUDIO_SRC_CPP) \ $(CONSOLE_SRC_CPP) \ - $(CONTROLLERS_SENSORS_SRC_CPP) \ - $(CONTROLLERS_CORE_SRC_CPP) \ - $(CONTROLLERS_MATH_SRC_CPP) \ $(PROJECT_DIR)/console/binary/tunerstudio_io.cpp \ $(PROJECT_DIR)/controllers/system/efi_gpio.cpp \ $(PROJECT_DIR)/controllers/algo/engine_configuration.cpp \ diff --git a/firmware/bootloader/src/rusefi_stubs.cpp b/firmware/bootloader/src/rusefi_stubs.cpp index f62657d8b9..5c455eacea 100644 --- a/firmware/bootloader/src/rusefi_stubs.cpp +++ b/firmware/bootloader/src/rusefi_stubs.cpp @@ -31,8 +31,8 @@ LoggingWithStorage::LoggingWithStorage(const char *name) : Logging(name, DEFAULT // this is supposed to be taken from chconf_common.h but it does not work? I am not sure why :( // TODO: make this be defined by chconf_common.h? -#if ! ENABLE_PERF_TRACE -//void irqEnterHook() {} -//void irqExitHook() {} -//void contextSwitchHook() {} -#endif /* ENABLE_PERF_TRACE */ \ No newline at end of file +//#if ! ENABLE_PERF_TRACE +void irqEnterHook() {} +void irqExitHook() {} +void contextSwitchHook() {} +//#endif /* ENABLE_PERF_TRACE */ \ No newline at end of file diff --git a/firmware/clean_compile_two_versions.bat b/firmware/clean_compile_two_versions.bat index f4842d4017..82753651af 100644 --- a/firmware/clean_compile_two_versions.bat +++ b/firmware/clean_compile_two_versions.bat @@ -7,7 +7,7 @@ mkdir deliver call clean.bat echo "TIMESTAMP %date% %time%" -set EXTRA_PARAMS=-DDUMMY -DFIRMWARE_ID=\"default_no_assert\" -DEFI_ENABLE_ASSERTS=FALSE -DCH_DBG_ENABLE_TRACE=FALSE -DCH_DBG_ENABLE_ASSERTS=FALSE -DCH_DBG_ENABLE_STACK_CHECK=FALSE -DCH_DBG_FILL_THREADS=FALSE -DCH_DBG_THREADS_PROFILING=FALSE +set EXTRA_PARAMS=-DDUMMY -DFIRMWARE_ID=\"default_no_assert\" -DEFI_ENABLE_ASSERTS=FALSE -DCH_DBG_ENABLE_ASSERTS=FALSE -DCH_DBG_ENABLE_STACK_CHECK=FALSE -DCH_DBG_FILL_THREADS=FALSE -DCH_DBG_THREADS_PROFILING=FALSE make -j4 DEBUG_LEVEL_OPT='-O2' set EXTRA_PARAMS= diff --git a/firmware/config/boards/clean_env_variables.bat b/firmware/config/boards/clean_env_variables.bat index ff18965ae7..d0dba99e47 100644 --- a/firmware/config/boards/clean_env_variables.bat +++ b/firmware/config/boards/clean_env_variables.bat @@ -7,3 +7,7 @@ set PROJECT_CPU= set USE_BOOTLOADER= set DEFAULT_ENGINE_TYPE= set EFI_FATAL_ERROR_PIN= +set BUILDDIR= +set DEBUG_LEVEL_OPT= +set USE_FATFS= + diff --git a/firmware/config/boards/common_make.bat b/firmware/config/boards/common_make.bat index 6e0a947eaf..3af123cbb1 100644 --- a/firmware/config/boards/common_make.bat +++ b/firmware/config/boards/common_make.bat @@ -15,4 +15,6 @@ echo %script_name%: invoking hex2dfu.exe cp build/rusefi.bin deliver/ echo %script_name%: deliver folder -ls -l deliver \ No newline at end of file +ls -l deliver + +call config/boards/clean_env_variables.bat \ No newline at end of file diff --git a/firmware/config/boards/frankenso/!compile-frankenso-pal.bat b/firmware/config/boards/frankenso/!compile-frankenso-pal.bat new file mode 100644 index 0000000000..d8d08c6178 --- /dev/null +++ b/firmware/config/boards/frankenso/!compile-frankenso-pal.bat @@ -0,0 +1,13 @@ + +cd ../../.. + +set EXTRA_PARAMS=-DDUMMY ^ + -DHAL_TRIGGER_USE_PAL=TRUE ^ + -DEFI_VEHICLE_SPEED=FALSE ^ + -DHAL_USE_ICU=FALSE ^ + -DEFI_LOGIC_ANALYZER=FALSE ^ + -DDEFAULT_ENGINE_TYPE=MIATA_NA6_VAF ^ + -DFIRMWARE_ID=\"frankensoNA6\" + +call config/boards/common_make.bat + diff --git a/firmware/config/boards/frankenso/!compile-frankenso_na6.bat b/firmware/config/boards/frankenso/!compile-frankenso_na6.bat index 78b9086d01..61820cca1e 100644 --- a/firmware/config/boards/frankenso/!compile-frankenso_na6.bat +++ b/firmware/config/boards/frankenso/!compile-frankenso_na6.bat @@ -7,4 +7,3 @@ set EXTRA_PARAMS=-DDUMMY ^ call config/boards/common_make.bat -call config/boards/clean_env_variables.bat diff --git a/firmware/config/boards/me7_pnp/!compile-me7_pnp.bat b/firmware/config/boards/me7_pnp/!compile-me7_pnp.bat index c58b5302b1..f184b60334 100644 --- a/firmware/config/boards/me7_pnp/!compile-me7_pnp.bat +++ b/firmware/config/boards/me7_pnp/!compile-me7_pnp.bat @@ -8,9 +8,7 @@ set PROJECT_CPU=ARCH_STM32F7 set EXTRA_PARAMS=-DDUMMY -DSTM32F767xx ^ -DEFI_ENABLE_ASSERTS=FALSE ^ -DEFI_USE_OSC=TRUE ^ - -DCH_DBG_ENABLE_CHECKS=FALSE -DCH_DBG_ENABLE_TRACE=FALSE -DCH_DBG_ENABLE_ASSERTS=FALSE -DCH_DBG_ENABLE_STACK_CHECK=FALSE -DCH_DBG_FILL_THREADS=FALSE -DCH_DBG_THREADS_PROFILING=FALSE + -DCH_DBG_ENABLE_CHECKS=FALSE -DCH_DBG_ENABLE_ASSERTS=FALSE -DCH_DBG_ENABLE_STACK_CHECK=FALSE -DCH_DBG_FILL_THREADS=FALSE -DCH_DBG_THREADS_PROFILING=FALSE set DEBUG_LEVEL_OPT="-O2" call config/boards/common_make.bat - -call config/boards/clean_env_variables.bat \ No newline at end of file diff --git a/firmware/config/boards/microrusefi/!compile-mre-f4-test.bat b/firmware/config/boards/microrusefi/!compile-mre-f4-test.bat index 6dcb87b573..21a6079dcb 100644 --- a/firmware/config/boards/microrusefi/!compile-mre-f4-test.bat +++ b/firmware/config/boards/microrusefi/!compile-mre-f4-test.bat @@ -7,4 +7,4 @@ set DEFAULT_ENGINE_TYPE = -DDEFAULT_ENGINE_TYPE=MRE_BOARD_TEST call config/boards/common_make.bat -call config/boards/clean_env_variables.bat + diff --git a/firmware/config/boards/microrusefi/!compile-mre-f4.bat b/firmware/config/boards/microrusefi/!compile-mre-f4.bat index 0f778d3f46..27d3a78e02 100644 --- a/firmware/config/boards/microrusefi/!compile-mre-f4.bat +++ b/firmware/config/boards/microrusefi/!compile-mre-f4.bat @@ -6,4 +6,4 @@ set PROJECT_CPU=ARCH_STM32F4 call config/boards/common_make.bat -call config/boards/clean_env_variables.bat + diff --git a/firmware/config/boards/microrusefi/!compile-mre-f7-test.bat b/firmware/config/boards/microrusefi/!compile-mre-f7-test.bat index 94333f48d4..bb742d4f97 100644 --- a/firmware/config/boards/microrusefi/!compile-mre-f7-test.bat +++ b/firmware/config/boards/microrusefi/!compile-mre-f7-test.bat @@ -9,4 +9,3 @@ set DEFAULT_ENGINE_TYPE = -DDEFAULT_ENGINE_TYPE=MRE_BOARD_TEST call config/boards/common_make.bat -call config/boards/clean_env_variables.bat diff --git a/firmware/config/boards/microrusefi/!compile-mre-f7.bat b/firmware/config/boards/microrusefi/!compile-mre-f7.bat index 9fa152962f..36752bb27d 100644 --- a/firmware/config/boards/microrusefi/!compile-mre-f7.bat +++ b/firmware/config/boards/microrusefi/!compile-mre-f7.bat @@ -8,4 +8,3 @@ set PROJECT_CPU=ARCH_STM32F7 call config/boards/common_make.bat -call config/boards/clean_env_variables.bat diff --git a/firmware/config/boards/microrusefi/!compile-nucleo-Manhattan.bat b/firmware/config/boards/microrusefi/!compile-nucleo-Manhattan.bat index b8e0a6b99e..8e972665dd 100644 --- a/firmware/config/boards/microrusefi/!compile-nucleo-Manhattan.bat +++ b/firmware/config/boards/microrusefi/!compile-nucleo-Manhattan.bat @@ -16,4 +16,3 @@ rem -DDEFAULT_ENGINE_TYPE=MRE_BOARD_TEST call config/boards/common_make.bat -call config/boards/clean_env_variables.bat diff --git a/firmware/config/boards/microrusefi/board_configuration.cpp b/firmware/config/boards/microrusefi/board_configuration.cpp index 877c9f2c81..c23f373100 100644 --- a/firmware/config/boards/microrusefi/board_configuration.cpp +++ b/firmware/config/boards/microrusefi/board_configuration.cpp @@ -93,9 +93,9 @@ static void setupEtb() { // DIS - disables motor (enable low) // PWM pin - boardConfiguration->etb1.controlPin1 = GPIOC_7; + engineConfiguration->etbIo[0].controlPin1 = GPIOC_7; // DIR pin - boardConfiguration->etb1.directionPin1 = GPIOA_8; + engineConfiguration->etbIo[0].directionPin1 = GPIOA_8; // set_fsio_output_pin 7 PC8 #if EFI_FSIO @@ -113,10 +113,10 @@ static void setupEtb() { // engineConfiguration->throttlePedalPositionAdcChannel = EFI_ADC_7; // Unused - boardConfiguration->etb1.directionPin2 = GPIO_UNASSIGNED; + engineConfiguration->etbIo[0].directionPin2 = GPIO_UNASSIGNED; // we only have pwm/dir, no dira/dirb - engineConfiguration->etb1_use_two_wires = false; + engineConfiguration->etb_use_two_wires = false; engineConfiguration->etbFreq = 800; } diff --git a/firmware/config/boards/nucleo_f746/!compile-stm32f746_nucleo.bat b/firmware/config/boards/nucleo_f746/!compile-stm32f746_nucleo.bat index 446d586c97..cdc807cf5b 100644 --- a/firmware/config/boards/nucleo_f746/!compile-stm32f746_nucleo.bat +++ b/firmware/config/boards/nucleo_f746/!compile-stm32f746_nucleo.bat @@ -19,4 +19,3 @@ set EXTRA_PARAMS=-DDUMMY -DSTM32F746xx ^ set DEBUG_LEVEL_OPT="-O2" call config/boards/common_make.bat -call config/boards/clean_env_variables.bat \ No newline at end of file diff --git a/firmware/config/boards/nucleo_f767/!compile-stm32f767_nucleo.bat b/firmware/config/boards/nucleo_f767/!compile-stm32f767_nucleo.bat index 1397faaecc..df9b87c88f 100644 --- a/firmware/config/boards/nucleo_f767/!compile-stm32f767_nucleo.bat +++ b/firmware/config/boards/nucleo_f767/!compile-stm32f767_nucleo.bat @@ -14,9 +14,8 @@ set EXTRA_PARAMS=-DDUMMY -DSTM32F767xx ^ -DEFI_COMMUNICATION_PIN=GPIOB_7 ^ -DEFI_FATAL_ERROR_PIN=GPIOB_14 ^ -DEFI_ENABLE_ASSERTS=FALSE ^ - -DCH_DBG_ENABLE_CHECKS=FALSE -DCH_DBG_ENABLE_TRACE=FALSE -DCH_DBG_ENABLE_ASSERTS=FALSE -DCH_DBG_ENABLE_STACK_CHECK=FALSE -DCH_DBG_FILL_THREADS=FALSE -DCH_DBG_THREADS_PROFILING=FALSE + -DCH_DBG_ENABLE_CHECKS=FALSE -DCH_DBG_ENABLE_ASSERTS=FALSE -DCH_DBG_ENABLE_STACK_CHECK=FALSE -DCH_DBG_FILL_THREADS=FALSE -DCH_DBG_THREADS_PROFILING=FALSE set DEBUG_LEVEL_OPT="-O2" call config/boards/common_make.bat -call config/boards/clean_env_variables.bat diff --git a/firmware/config/boards/nucleo_f767/!compile-stm32f767_osc.bat b/firmware/config/boards/nucleo_f767/!compile-stm32f767_osc.bat index 7ced41d213..cbf1f791ce 100644 --- a/firmware/config/boards/nucleo_f767/!compile-stm32f767_osc.bat +++ b/firmware/config/boards/nucleo_f767/!compile-stm32f767_osc.bat @@ -12,11 +12,10 @@ set EXTRA_PARAMS=-DDUMMY -DSTM32F767xx ^ -DEFI_FATAL_ERROR_PIN=GPIOB_14 ^ -DEFI_ENABLE_ASSERTS=FALSE ^ -DEFI_USE_OSC=TRUE ^ - -DCH_DBG_ENABLE_CHECKS=FALSE -DCH_DBG_ENABLE_TRACE=FALSE -DCH_DBG_ENABLE_ASSERTS=FALSE -DCH_DBG_ENABLE_STACK_CHECK=FALSE -DCH_DBG_FILL_THREADS=FALSE -DCH_DBG_THREADS_PROFILING=FALSE + -DCH_DBG_ENABLE_CHECKS=FALSE -DCH_DBG_ENABLE_ASSERTS=FALSE -DCH_DBG_ENABLE_STACK_CHECK=FALSE -DCH_DBG_FILL_THREADS=FALSE -DCH_DBG_THREADS_PROFILING=FALSE rem Do not forget to comment out following line if looking to debug! set DEBUG_LEVEL_OPT="-O2" call config/boards/common_make.bat -call config/boards/clean_env_variables.bat diff --git a/firmware/config/boards/nucleo_f767/board_configuration.cpp b/firmware/config/boards/nucleo_f767/board_configuration.cpp index 014e9ef372..c4bbf9ae07 100644 --- a/firmware/config/boards/nucleo_f767/board_configuration.cpp +++ b/firmware/config/boards/nucleo_f767/board_configuration.cpp @@ -69,7 +69,7 @@ void setBoardConfigurationOverrides(void) { boardConfiguration->triggerSimulatorPins[2] = GPIO_UNASSIGNED; boardConfiguration->triggerSimulatorPinModes[1] = OM_DEFAULT; boardConfiguration->triggerSimulatorPinModes[2] = OM_DEFAULT; - boardConfiguration->vehicleSpeedSensorInputPin = GPIO_UNASSIGNED; + engineConfiguration->vehicleSpeedSensorInputPin = GPIO_UNASSIGNED; boardConfiguration->digitalPotentiometerSpiDevice = SPI_NONE; boardConfiguration->max31855spiDevice = SPI_NONE; diff --git a/firmware/config/boards/prometheus/!compile-prometheus_405.bat b/firmware/config/boards/prometheus/!compile-prometheus_405.bat index a2bb40c09a..1502021057 100644 --- a/firmware/config/boards/prometheus/!compile-prometheus_405.bat +++ b/firmware/config/boards/prometheus/!compile-prometheus_405.bat @@ -3,14 +3,7 @@ rem STM32F405 version of the firmware for https://rusefi.com/forum/viewtopic.php rem cd ../../.. -set PROJECT_BOARD=prometheus -set PROMETHEUS_BOARD=405 -set EXTRA_PARAMS=-DDUMMY -DSTM32F405xx -DEFI_ENABLE_ASSERTS=FALSE ^ - -DFIRMWARE_ID=\"prometheus405\" ^ - -DCH_DBG_ENABLE_TRACE=FALSE -DCH_DBG_ENABLE_ASSERTS=FALSE -DCH_DBG_ENABLE_STACK_CHECK=FALSE -DCH_DBG_FILL_THREADS=FALSE -DCH_DBG_THREADS_PROFILING=FALSE -set DEBUG_LEVEL_OPT="-O2" -set USE_BOOTLOADER=yes +set PROJECT_BOARD=prometheus/f405 call config/boards/common_make.bat -call config/boards/clean_env_variables.bat \ No newline at end of file diff --git a/firmware/config/boards/prometheus/!compile-prometheus_469.bat b/firmware/config/boards/prometheus/!compile-prometheus_469.bat index 6dd85fac4d..040f7f8daf 100644 --- a/firmware/config/boards/prometheus/!compile-prometheus_469.bat +++ b/firmware/config/boards/prometheus/!compile-prometheus_469.bat @@ -3,14 +3,8 @@ rem STM32F469 version of the firmware for https://rusefi.com/forum/viewtopic.php rem cd ../../.. -set PROJECT_BOARD=prometheus -set PROMETHEUS_BOARD=469 -set EXTRA_PARAMS=-DDUMMY -DSTM32F469xx -DEFI_ENABLE_ASSERTS=FALSE ^ - -DFIRMWARE_ID=\"prometeus469\" ^ - -DCH_DBG_ENABLE_TRACE=FALSE -DCH_DBG_ENABLE_ASSERTS=FALSE -DCH_DBG_ENABLE_STACK_CHECK=FALSE -DCH_DBG_FILL_THREADS=FALSE -DCH_DBG_THREADS_PROFILING=FALSE -set DEBUG_LEVEL_OPT="-O2" +set PROJECT_BOARD=prometheus/f469 set USE_BOOTLOADER=yes call config/boards/common_make.bat -call config/boards/clean_env_variables.bat diff --git a/firmware/config/boards/prometheus/board_configuration.cpp b/firmware/config/boards/prometheus/board_configuration.cpp index 662a3c6ba7..2faf3efe50 100644 --- a/firmware/config/boards/prometheus/board_configuration.cpp +++ b/firmware/config/boards/prometheus/board_configuration.cpp @@ -191,7 +191,7 @@ void setBoardConfigurationOverrides(void) { boardConfiguration->malfunctionIndicatorPinMode = OM_DEFAULT; // starter block - setFsio(0, (is469 ? GPIOB_10 : GPIOB_1), STARTER_BLOCK PASS_CONFIG_PARAMETER_SUFFIX); + setFsio(0, (is469 ? GPIOB_10 : GPIOB_1), STARTER_RELAY_LOGIC PASS_CONFIG_PARAMETER_SUFFIX); // debug pad @@ -215,7 +215,7 @@ void setBoardConfigurationOverrides(void) { boardConfiguration->triggerSimulatorPins[2] = GPIO_UNASSIGNED; boardConfiguration->triggerSimulatorPinModes[1] = OM_DEFAULT; boardConfiguration->triggerSimulatorPinModes[2] = OM_DEFAULT; - boardConfiguration->vehicleSpeedSensorInputPin = GPIO_UNASSIGNED; + engineConfiguration->vehicleSpeedSensorInputPin = GPIO_UNASSIGNED; boardConfiguration->digitalPotentiometerSpiDevice = SPI_NONE; boardConfiguration->max31855spiDevice = SPI_NONE; diff --git a/firmware/config/boards/prometheus/efifeatures.h b/firmware/config/boards/prometheus/efifeatures.h index 3d39906559..ecf7eba807 100644 --- a/firmware/config/boards/prometheus/efifeatures.h +++ b/firmware/config/boards/prometheus/efifeatures.h @@ -105,8 +105,8 @@ #undef EFI_MEMS #define EFI_MEMS FALSE -#undef EFI_IDLE_INCREMENTAL_PID_CIC -#define EFI_IDLE_INCREMENTAL_PID_CIC TRUE +#undef EFI_IDLE_PID_CIC +#define EFI_IDLE_PID_CIC TRUE #define RPM_LOW_THRESHOLD 8 // RPM=8 is an empirical lower sensitivity threshold of MAX9926 for 60-2 #define NO_RPM_EVENTS_TIMEOUT_SECS 5 // (RPM < 12) diff --git a/firmware/config/boards/prometheus/f405/board.mk b/firmware/config/boards/prometheus/f405/board.mk new file mode 100644 index 0000000000..8a4c92e35d --- /dev/null +++ b/firmware/config/boards/prometheus/f405/board.mk @@ -0,0 +1,3 @@ +PROMETHEUS_BOARD = 405 + +include $(PROJECT_DIR)/config/boards/prometheus/prometheus-common.mk \ No newline at end of file diff --git a/firmware/config/boards/prometheus/f469/board.mk b/firmware/config/boards/prometheus/f469/board.mk new file mode 100644 index 0000000000..6c2fe59e51 --- /dev/null +++ b/firmware/config/boards/prometheus/f469/board.mk @@ -0,0 +1,3 @@ +PROMETHEUS_BOARD = 469 + +include $(PROJECT_DIR)/config/boards/prometheus/prometheus-common.mk diff --git a/firmware/config/boards/prometheus/board.mk b/firmware/config/boards/prometheus/prometheus-common.mk similarity index 55% rename from firmware/config/boards/prometheus/board.mk rename to firmware/config/boards/prometheus/prometheus-common.mk index 8e59572dff..c53f0c82b5 100644 --- a/firmware/config/boards/prometheus/board.mk +++ b/firmware/config/boards/prometheus/prometheus-common.mk @@ -7,17 +7,25 @@ BOARDSRC_CPP = $(PROJECT_DIR)/config/boards/Prometheus/board_configuration.cpp # Required include directories BOARDINC = $(PROJECT_DIR)/config/boards/prometheus -# Override LD script -ifeq ($(USE_BOOTLOADER),yes) - # include Prometheus bootloader code - BOOTLOADERINC= $(PROJECT_DIR)/bootloader/prometheus/$(PROMETHEUS_BOARD) +# This board uses bootloader +USE_BOOTLOADER=yes + +# include Prometheus bootloader code +BOOTLOADERINC= $(PROJECT_DIR)/bootloader/prometheus/$(PROMETHEUS_BOARD) + +# Default to a release build - clear EXTRA_PARAMS from cmdline to build debug +ifeq ($(EXTRA_PARAMS),) + EXTRA_PARAMS=-DEFI_ENABLE_ASSERTS=FALSE -DCH_DBG_ENABLE_ASSERTS=FALSE -DCH_DBG_ENABLE_STACK_CHECK=FALSE -DCH_DBG_FILL_THREADS=FALSE -DCH_DBG_THREADS_PROFILING=FALSE +endif +ifeq ($(DEBUG_LEVEL_OPT),) + DEBUG_LEVEL_OPT = -O2 endif ifeq ($(PROMETHEUS_BOARD),405) LDSCRIPT= $(PROJECT_DIR)/config/boards/prometheus/STM32F405xG.ld -DDEFS += -DDEFAULT_ENGINE_TYPE=PROMETHEUS_DEFAULTS -DSTM32F405xx +DDEFS += -DDEFAULT_ENGINE_TYPE=PROMETHEUS_DEFAULTS -DSTM32F405xx -DFIRMWARE_ID=\"prometeus405\" else # Override DEFAULT_ENGINE_TYPE LDSCRIPT= $(PROJECT_DIR)/config/boards/prometheus/STM32F469xI.ld -DDEFS += -DDEFAULT_ENGINE_TYPE=PROMETHEUS_DEFAULTS -DSTM32F469xx +DDEFS += -DDEFAULT_ENGINE_TYPE=PROMETHEUS_DEFAULTS -DSTM32F469xx -DFIRMWARE_ID=\"prometeus469\" endif diff --git a/firmware/config/boards/proteus/board.mk b/firmware/config/boards/proteus/board.mk new file mode 100644 index 0000000000..eb50754451 --- /dev/null +++ b/firmware/config/boards/proteus/board.mk @@ -0,0 +1,11 @@ +# List of all the board related files. +BOARDSRC = $(CHIBIOS)/os/hal/boards/ST_NUCLEO144_F767ZI/board.c +BOARDSRC_CPP = $(PROJECT_DIR)/config/boards/proteus/board_configuration.cpp + +# Required include directories +BOARDINC = $(PROJECT_DIR)/config/boards/nucleo_f767 $(PROJECT_DIR)/config/stm32f7ems + +LDSCRIPT= $(PROJECT_DIR)/config/boards/nucleo_f767/STM32F76xxI.ld + +# Override DEFAULT_ENGINE_TYPE +DDEFS += -DSTM32F767xx -DEFI_USE_OSC=TRUE -DEFI_FATAL_ERROR_PIN=GPIOE_3 -DFIRMWARE_ID=\"proteus\" -DDEFAULT_ENGINE_TYPE=PROTEUS diff --git a/firmware/config/boards/proteus/board_configuration.cpp b/firmware/config/boards/proteus/board_configuration.cpp new file mode 100644 index 0000000000..0554f34496 --- /dev/null +++ b/firmware/config/boards/proteus/board_configuration.cpp @@ -0,0 +1,166 @@ +/** + * @file boards/proteus/board_configuration.cpp + * + * @brief Configuration defaults for the Proteus board + * + * @author Matthew Kennedy, (c) 2019 + */ + +#include "global.h" +#include "engine.h" +#include "engine_math.h" +#include "allsensors.h" +#include "fsio_impl.h" +#include "engine_configuration.h" + +EXTERN_ENGINE; + +static void setInjectorPins() { + boardConfiguration->injectionPins[0] = GPIOD_7; + boardConfiguration->injectionPins[1] = GPIOG_9; + boardConfiguration->injectionPins[2] = GPIOG_10; + boardConfiguration->injectionPins[3] = GPIOG_11; + boardConfiguration->injectionPins[4] = GPIOG_12; + boardConfiguration->injectionPins[5] = GPIOG_13; + boardConfiguration->injectionPins[6] = GPIOG_14; + boardConfiguration->injectionPins[7] = GPIOB_4; + boardConfiguration->injectionPins[8] = GPIOB_5; + boardConfiguration->injectionPins[9] = GPIOB_6; + boardConfiguration->injectionPins[10] = GPIOB_7; + boardConfiguration->injectionPins[11] = GPIOB_8; + + boardConfiguration->injectionPinMode = OM_DEFAULT; +} + +static void setIgnitionPins() { + boardConfiguration->ignitionPins[0] = GPIOD_4; + boardConfiguration->ignitionPins[1] = GPIOD_3; + boardConfiguration->ignitionPins[2] = GPIOC_9; + boardConfiguration->ignitionPins[3] = GPIOC_8; + boardConfiguration->ignitionPins[4] = GPIOC_7; + boardConfiguration->ignitionPins[5] = GPIOG_8; + boardConfiguration->ignitionPins[6] = GPIOG_7; + boardConfiguration->ignitionPins[7] = GPIOG_6; + boardConfiguration->ignitionPins[8] = GPIOG_5; + boardConfiguration->ignitionPins[9] = GPIOG_4; + boardConfiguration->ignitionPins[10] = GPIOG_3; + boardConfiguration->ignitionPins[11] = GPIOG_2; + + boardConfiguration->ignitionPinMode = OM_DEFAULT; +} + +static void setLedPins() { + engineConfiguration->communicationLedPin = GPIOE_4; + engineConfiguration->runningLedPin = GPIOE_5; + boardConfiguration->triggerErrorPin = GPIOE_6; +} + +static void setupVbatt() { + // 6.8k high side/10k low side = 1.6667 ratio divider + engineConfiguration->analogInputDividerCoefficient = 2.5f / 1.5f; + + // 47k high side/10k low side = 4.7 + engineConfiguration->vbattDividerCoeff = (57.0f / 10.0f); + //engineConfiguration->vbattAdcChannel = TODO; + + engineConfiguration->adcVcc = 3.3f; +} + +static void setupEtb() { + // TLE9201 driver + // This chip has three control pins: + // DIR - sets direction of the motor + // PWM - pwm control (enable high, coast low) + // DIS - disables motor (enable low) + + // Throttle #1 + // PWM pin + engineConfiguration->etbIo[0].controlPin1 = GPIOD_12; + // DIR pin + engineConfiguration->etbIo[0].directionPin1 = GPIOD_10; + // Unused + engineConfiguration->etbIo[0].directionPin2 = GPIO_UNASSIGNED; + + // Throttle #2 + // PWM pin + engineConfiguration->etbIo[0].controlPin1 = GPIOD_13; + // DIR pin + engineConfiguration->etbIo[0].directionPin1 = GPIOD_9; + // Unused + engineConfiguration->etbIo[0].directionPin2 = GPIO_UNASSIGNED; + +#if EFI_FSIO + // disable ETB by default + setFsio(7, GPIOD_8, "1" PASS_CONFIG_PARAMETER_SUFFIX); + setFsio(8, GPIOD_11, "1" PASS_CONFIG_PARAMETER_SUFFIX); +#endif /* EFI_FSIO */ + + // we only have pwm/dir, no dira/dirb + engineConfiguration->etb_use_two_wires = false; + engineConfiguration->etbFreq = 800; +} + +static void setupDefaultSensorInputs() { + // trigger inputs + // VR channel 1 as default - others not set + boardConfiguration->triggerInputPins[0] = GPIOC_6; + boardConfiguration->triggerInputPins[1] = GPIO_UNASSIGNED; + boardConfiguration->triggerInputPins[2] = GPIO_UNASSIGNED; + engineConfiguration->camInputs[0] = GPIO_UNASSIGNED; + + // clt = Analog Temp 1 = PC4 + engineConfiguration->clt.adcChannel = EFI_ADC_14; + engineConfiguration->clt.config.bias_resistor = 2700; + + // iat = Analog Temp 2 = PC5 + engineConfiguration->iat.adcChannel = EFI_ADC_15; + engineConfiguration->iat.config.bias_resistor = 2700; + + // TODO: more sensors +} + +void setPinConfigurationOverrides(void) { +} + +void setSerialConfigurationOverrides(void) { + boardConfiguration->useSerialPort = false; + engineConfiguration->binarySerialTxPin = GPIO_UNASSIGNED; + engineConfiguration->binarySerialRxPin = GPIO_UNASSIGNED; + engineConfiguration->consoleSerialTxPin = GPIO_UNASSIGNED; + engineConfiguration->consoleSerialRxPin = GPIO_UNASSIGNED; +} + + +/** + * @brief Board-specific configuration code overrides. + * + * See also setDefaultEngineConfiguration + * + * @todo Add your board-specific code, if any. + */ +void setBoardConfigurationOverrides(void) { + setInjectorPins(); + setIgnitionPins(); + setLedPins(); + setupVbatt(); + setupEtb(); + + // "required" hardware is done - set some reasonable defaults + setupDefaultSensorInputs(); + + // Some sensible defaults for other options + setOperationMode(engineConfiguration, FOUR_STROKE_CRANK_SENSOR); + engineConfiguration->trigger.type = TT_TOOTHED_WHEEL_60_2; + engineConfiguration->useOnlyRisingEdgeForTrigger = true; + setAlgorithm(LM_SPEED_DENSITY PASS_CONFIG_PARAMETER_SUFFIX); + + engineConfiguration->specs.cylindersCount = 8; + engineConfiguration->specs.firingOrder = FO_1_8_7_2_6_5_4_3; + + engineConfiguration->ignitionMode = IM_INDIVIDUAL_COILS; + engineConfiguration->crankingInjectionMode = IM_SIMULTANEOUS; + engineConfiguration->injectionMode = IM_SIMULTANEOUS; +} + +void setAdcChannelOverrides(void) { +} diff --git a/firmware/config/boards/proteus/mapping.yaml b/firmware/config/boards/proteus/mapping.yaml new file mode 100644 index 0000000000..2f3b8711ec --- /dev/null +++ b/firmware/config/boards/proteus/mapping.yaml @@ -0,0 +1,73 @@ +outputs: + GPIOD_7: "Lowside 1" + GPIOG_9: "Lowside 2" + GPIOG_10: "Lowside 3" + GPIOG_11: "Lowside 4" + GPIOG_12: "Lowside 5" + GPIOG_13: "Lowside 6" + GPIOG_14: "Lowside 7" + GPIOB_4: "Lowside 8" + GPIOB_5: "Lowside 9" + GPIOB_6: "Lowside 10" + GPIOB_7: "Lowside 11" + GPIOB_8: "Lowside 12" + GPIOB_9: "Lowside 13" + GPIOE_0: "Lowside 14" + GPIOE_1: "Lowside 15" + GPIOE_2: "Lowside 16" + + GPIOD_4: "Ign 1" + GPIOD_3: "Ign 2" + GPIOC_9: "Ign 3" + GPIOC_8: "Ign 4" + GPIOC_7: "Ign 5" + GPIOG_8: "Ign 6" + GPIOG_7: "Ign 7" + GPIOG_6: "Ign 8" + GPIOG_5: "Ign 9" + GPIOG_4: "Ign 10" + GPIOG_3: "Ign 11" + GPIOG_2: "Ign 12" + + GPIOA_9: "Highside 1" + GPIOA_8: "Highside 2" + GPIOD_15: "Highside 3" + GPIOD_14: "Highside 4" + +event_inputs: + GPIOC_6: "Digital 1" + GPIOE_11: "Digital 2" + GPIOE_12: "Digital 3" + GPIOE_13: "Digital 4" + GPIOE_14: "Digital 5" + GPIOE_15: "Digital 6" + GPIOE_7: "Digital 7" + GPIOE_8: "Digital 8" + +switch_inputs: + GPIOC_6: "Digital 1" + GPIOE_11: "Digital 2" + GPIOE_12: "Digital 3" + GPIOE_13: "Digital 4" + GPIOE_14: "Digital 5" + GPIOE_15: "Digital 6" + GPIOE_7: "Digital 7" + GPIOE_8: "Digital 8" + +analog_inputs: + EFI_ADC_0: "Analog Volt 5" + EFI_ADC_1: "Analog Volt 6" + EFI_ADC_2: "Analog Volt 7" + EFI_ADC_3: "Analog Volt 8" + EFI_ADC_4: "Analog Volt 9" + EFI_ADC_5: "Analog Volt 10" + EFI_ADC_6: "Analog Volt 11" + EFI_ADC_7: "Analog Volt 12" + EFI_ADC_8: "Analog Temp 3" + EFI_ADC_9: "Analog Temp 4" + EFI_ADC_10: "Analog Volt 1" + EFI_ADC_11: "Analog Volt 2" + EFI_ADC_12: "Analog Volt 3" + EFI_ADC_13: "Analog Volt 4" + EFI_ADC_14: "Analog Temp 1" + EFI_ADC_15: "Analog Temp 2" diff --git a/firmware/config/boards/subaru-ej20gn/board_configuration.cpp b/firmware/config/boards/subaru-ej20gn/board_configuration.cpp index 6b107ee431..03a9dcf8f0 100644 --- a/firmware/config/boards/subaru-ej20gn/board_configuration.cpp +++ b/firmware/config/boards/subaru-ej20gn/board_configuration.cpp @@ -160,7 +160,7 @@ void setBoardConfigurationOverrides(void) { // starter block /* Starter signal connected through MC33972 - SG11 */ - //setFsio(0, (GPIOB_1), STARTER_BLOCK PASS_CONFIG_PARAMETER_SUFFIX); + //setFsio(0, (GPIOB_1), STARTER_RELAY_LOGIC PASS_CONFIG_PARAMETER_SUFFIX); // not used @@ -177,7 +177,7 @@ void setBoardConfigurationOverrides(void) { boardConfiguration->digitalPotentiometerChipSelect[1] = GPIO_UNASSIGNED; boardConfiguration->digitalPotentiometerChipSelect[2] = GPIO_UNASSIGNED; boardConfiguration->digitalPotentiometerChipSelect[3] = GPIO_UNASSIGNED; - boardConfiguration->vehicleSpeedSensorInputPin = GPIO_UNASSIGNED; + engineConfiguration->vehicleSpeedSensorInputPin = GPIO_UNASSIGNED; boardConfiguration->digitalPotentiometerSpiDevice = SPI_NONE; boardConfiguration->max31855spiDevice = SPI_NONE; diff --git a/firmware/config/boards/subaru-ej20gn/efifeatures.h b/firmware/config/boards/subaru-ej20gn/efifeatures.h index d92dd2db2e..93e09ab7cc 100644 --- a/firmware/config/boards/subaru-ej20gn/efifeatures.h +++ b/firmware/config/boards/subaru-ej20gn/efifeatures.h @@ -103,8 +103,8 @@ #undef EFI_MEMS #define EFI_MEMS FALSE -#undef EFI_IDLE_INCREMENTAL_PID_CIC -#define EFI_IDLE_INCREMENTAL_PID_CIC TRUE +#undef EFI_IDLE_PID_CIC +#define EFI_IDLE_PID_CIC TRUE #define RPM_LOW_THRESHOLD 8 // RPM=8 is an empirical lower sensitivity threshold of MAX9926 for 60-2 #define NO_RPM_EVENTS_TIMEOUT_SECS 5 // (RPM < 12) diff --git a/firmware/config/boards/subaru-ej20gn/make.sh b/firmware/config/boards/subaru-ej20gn/make.sh index add57a5ab5..19152e6e61 100755 --- a/firmware/config/boards/subaru-ej20gn/make.sh +++ b/firmware/config/boards/subaru-ej20gn/make.sh @@ -3,7 +3,7 @@ export PROJECT_BOARD=subaru-ej20gn export PROJECT_CPU=ARCH_STM32F7 export PROJECT_CORE=cortex-m7 -export EXTRA_PARAMS="-DDUMMY -DEFI_ENABLE_ASSERTS=FALSE -DCH_DBG_ENABLE_TRACE=FALSE -DCH_DBG_ENABLE_ASSERTS=FALSE -DCH_DBG_ENABLE_STACK_CHECK=FALSE -DCH_DBG_FILL_THREADS=FALSE -DCH_DBG_THREADS_PROFILING=FALSE" +export EXTRA_PARAMS="-DDUMMY -DEFI_ENABLE_ASSERTS=FALSE -DCH_DBG_ENABLE_ASSERTS=FALSE -DCH_DBG_ENABLE_STACK_CHECK=FALSE -DCH_DBG_FILL_THREADS=FALSE -DCH_DBG_THREADS_PROFILING=FALSE" #echo $EXTRA_PARAMS #export DEBUG_LEVEL_OPT="-O0" #export USE_BOOTLOADER=yes diff --git a/firmware/config/engines/bmw_e34.cpp b/firmware/config/engines/bmw_e34.cpp index 4fcd22b18f..72bcb1d5e3 100644 --- a/firmware/config/engines/bmw_e34.cpp +++ b/firmware/config/engines/bmw_e34.cpp @@ -119,8 +119,8 @@ void setBmwE34(DECLARE_CONFIG_PARAMETER_SIGNATURE) { boardConfiguration->triggerErrorPin = GPIO_UNASSIGNED; // clutch up - boardConfiguration->clutchUpPin = GPIOD_3; - boardConfiguration->clutchUpPinMode = PI_PULLUP; + engineConfiguration->clutchUpPin = GPIOD_3; + engineConfiguration->clutchUpPinMode = PI_PULLUP; // fuel pump boardConfiguration->fuelPumpPin = GPIOD_4; diff --git a/firmware/config/engines/bmw_m73.cpp b/firmware/config/engines/bmw_m73.cpp index 399bcb5238..96058e04da 100644 --- a/firmware/config/engines/bmw_m73.cpp +++ b/firmware/config/engines/bmw_m73.cpp @@ -24,17 +24,17 @@ * ECU pin 23: OUT BRN/BLK BLK ECU relay control, low-side * * Plug #3 52 pin - * ECU pin 2: OUT injector #4 + * ECU pin 2: OUT WHT injector #4 * ECU pin 6: GND ECU - * ECU pin 15: OUT injector #2 + * ECU pin 15: OUT BLK injector #2 * ECU pin 20: IN WHT hall effect camshaft sensor signal * ECU pin 21: GND BRN BLK CLT sensor * ECU pin 22: IN RED/BRN GRN CLT sensor - * ECU pin 27: OUT injector #6 - * ECU pin 28: OUT injector #5 + * ECU pin 27: OUT ORG injector #6 + * ECU pin 28: OUT RED injector #5 * ECU pin 32: IN ORG VR positive crankshaft sensor - only 2x 5k per channel, R111 not installed, W1002 not installed - * ECU pin 40: OUT BRN/BLK injector #3 - * ECU pin 41: OUT BRN/WHT injector #1 + * ECU pin 40: OUT BRN/BLK GRN injector #3 + * ECU pin 41: OUT BRN/WHT BLU injector #1 * ECU pin 45: GND crankshaft shield * ECU pin 46: IN BLK BLU VR negative crankshaft sensor * @@ -50,13 +50,15 @@ * ECU pic 3: OUT BLK coil signal, low-side * ECU pic 5: GND BRN ground * ECU pic 6: OUT BLK coil signal, low-side - * ECU pic 9: OUT BLK coil signal, low-side + * ECU pic 9: OUT BLK RED coil signal, low-side * * Frankenso * set engine_type 40 * Manhattan * set engine_type 24 * + * https://raw.githubusercontent.com/wiki/rusefi/rusefi_documentation/oem_docs/VAG/Bosch_0280750009_pinout.jpg + * * @date Nov 1, 2019 * @author Andrey Belomutskiy, (c) 2012-2019 */ @@ -78,9 +80,16 @@ static void m73engine(DECLARE_CONFIG_PARAMETER_SIGNATURE) { engineConfiguration->globalTriggerAngleOffset = 90; setOperationMode(engineConfiguration, FOUR_STROKE_CRANK_SENSOR); + // todo: that's not right, should be 60/2 without VW engineConfiguration->trigger.type = TT_60_2_VW; + // this large engine seems to crank at around only 150 RPM? And happily idle at 400RPM? + engineConfiguration->cranking.rpm = 280; + engineConfiguration->ignitionMode = IM_TWO_COILS; + + // set cranking_fuel 15 + engineConfiguration->cranking.baseFuel = 15; } @@ -99,31 +108,106 @@ void setEngineBMW_M73_Frankenso(DECLARE_CONFIG_PARAMETER_SIGNATURE) { CONFIGB(fuelPumpPin) = GPIO_UNASSIGNED; - boardConfiguration->ignitionPins[ID2INDEX(1)] = GPIOE_14; // Frankenso high side - pin 1G + boardConfiguration->ignitionPins[ID2INDEX(1)] = GPIOE_14; // Frankenso high side - pin 1G - GREEN wire boardConfiguration->ignitionPins[ID2INDEX(2)] = GPIO_UNASSIGNED; boardConfiguration->ignitionPins[ID2INDEX(3)] = GPIO_UNASSIGNED; boardConfiguration->ignitionPins[ID2INDEX(4)] = GPIO_UNASSIGNED; - boardConfiguration->ignitionPins[ID2INDEX(7)] = GPIOC_7; // Frankenso high side - pin 1H + boardConfiguration->ignitionPins[ID2INDEX(7)] = GPIOC_7; // Frankenso high side - pin 1H - ORANGE wire - boardConfiguration->injectionPins[0] = GPIOB_8; - boardConfiguration->injectionPins[1] = GPIOB_7; - boardConfiguration->injectionPins[2] = GPIOB_9; - boardConfiguration->injectionPins[3] = GPIOD_5; - boardConfiguration->injectionPins[4] = GPIOD_3; - boardConfiguration->injectionPins[5] = GPIOE_2; + boardConfiguration->injectionPins[0] = GPIOB_8; // BLU + boardConfiguration->injectionPins[1] = GPIOB_7; // BLK + boardConfiguration->injectionPins[2] = GPIOB_9; // GRN + boardConfiguration->injectionPins[3] = GPIOD_5; // WHT + boardConfiguration->injectionPins[4] = GPIOD_3; // RED + boardConfiguration->injectionPins[5] = GPIOE_2; // ORG - boardConfiguration->injectionPins[6] = GPIOE_3; - boardConfiguration->injectionPins[7] = GPIOE_4; - boardConfiguration->injectionPins[8] = GPIOE_5; - boardConfiguration->injectionPins[9] = GPIOE_6; - boardConfiguration->injectionPins[10] = GPIOC_13; - boardConfiguration->injectionPins[11] = GPIOD_7; + boardConfiguration->injectionPins[6] = GPIOE_3; // BLU + boardConfiguration->injectionPins[7] = GPIOE_4; // BLK + boardConfiguration->injectionPins[8] = GPIOE_5; // GRN + boardConfiguration->injectionPins[9] = GPIOE_6; // WHT + boardConfiguration->injectionPins[10] = GPIOC_13;//RED + boardConfiguration->injectionPins[11] = GPIOD_7;// ORG } // BMW_M73_M void setEngineBMW_M73_Manhattan(DECLARE_CONFIG_PARAMETER_SIGNATURE) { m73engine(PASS_CONFIG_PARAMETER_SIGNATURE); + /** +Nucleo boards - first step is to confirm that I can blink via each pin +going clockwise from top-right corner + +GPIOA_10 USD ID +GPIOA_11 USD DM +GPIOA_12 USD DP + +E_4: running + +Good GPIO: +GPIOC_9 ETB#1 +GPIOC_8 ETB#1 +GPIOB_8 ETB#2 +GPIOB_9 ETB#2 +GPIOC_5 +GPIOA_7 +GPIOA_6 + */ + + + CONFIGB(fsioOutputPins)[7] = GPIO_UNASSIGNED; + boardConfiguration->fuelPumpPin = GPIO_UNASSIGNED; + boardConfiguration->idle.solenoidPin = GPIO_UNASSIGNED; + boardConfiguration->fanPin = GPIO_UNASSIGNED; + + /** + * Yellow op-amp board + * + * AN5 tested pull-down 1M PA3 TPS1 orange wire + * AN6 tested pull-down 1M PA4 TPS2 + * AN7 tested pull-down 1M PA6 PPS + * AN8 tested no pull-down / no pull-up + */ + + + // For example TLE7209 - two control wires: + // PWM on both wires - one to open, another to close + // ETB motor NEG pin # - white wire - OUT 1 + + engineConfiguration->throttlePedalPositionAdcChannel = EFI_ADC_6; + // set_analog_input_pin tps PA3 + engineConfiguration->tps1_1AdcChannel = EFI_ADC_3; // PA3 + // set_analog_input_pin tps2 PA4 + engineConfiguration->tps2_1AdcChannel = EFI_ADC_4; // PA4 + + // PWM pin + engineConfiguration->etbIo[0].controlPin1 = GPIO_UNASSIGNED; + // DIR pin + engineConfiguration->etbIo[0].directionPin1 = GPIOC_9; + engineConfiguration->etbIo[0].directionPin2 = GPIOC_8; + CONFIG(etb_use_two_wires) = true; + + // PWM pin + engineConfiguration->etbIo[1].controlPin1 = GPIO_UNASSIGNED; + // DIR pin + engineConfiguration->etbIo[1].directionPin1 = GPIOB_8; + engineConfiguration->etbIo[1].directionPin2 = GPIOB_9; + + + boardConfiguration->injectionPins[0] = GPIO_UNASSIGNED; + boardConfiguration->injectionPins[1] = GPIO_UNASSIGNED; + boardConfiguration->injectionPins[2] = GPIO_UNASSIGNED; + boardConfiguration->injectionPins[3] = GPIO_UNASSIGNED; + boardConfiguration->injectionPins[4] = GPIO_UNASSIGNED; + boardConfiguration->injectionPins[5] = GPIO_UNASSIGNED; + + boardConfiguration->injectionPins[6] = GPIO_UNASSIGNED; + boardConfiguration->injectionPins[7] = GPIO_UNASSIGNED; + boardConfiguration->injectionPins[8] = GPIO_UNASSIGNED; + boardConfiguration->injectionPins[9] = GPIO_UNASSIGNED; + boardConfiguration->injectionPins[10] = GPIO_UNASSIGNED; + boardConfiguration->injectionPins[11] = GPIO_UNASSIGNED; + + } diff --git a/firmware/config/engines/citroenBerlingoTU3JP.cpp b/firmware/config/engines/citroenBerlingoTU3JP.cpp index eb403f8887..301d99210c 100644 --- a/firmware/config/engines/citroenBerlingoTU3JP.cpp +++ b/firmware/config/engines/citroenBerlingoTU3JP.cpp @@ -201,7 +201,7 @@ void setCitroenBerlingoTU3JPConfiguration(DECLARE_CONFIG_PARAMETER_SIGNATURE) { /** * Speed Sensor */ - boardConfiguration->vehicleSpeedSensorInputPin = GPIOA_8; + engineConfiguration->vehicleSpeedSensorInputPin = GPIOA_8; /** * Other */ diff --git a/firmware/config/engines/custom_engine.cpp b/firmware/config/engines/custom_engine.cpp index 4715f5d276..8686d24dc9 100644 --- a/firmware/config/engines/custom_engine.cpp +++ b/firmware/config/engines/custom_engine.cpp @@ -253,6 +253,13 @@ void setEtbTestConfiguration(DECLARE_CONFIG_PARAMETER_SIGNATURE) { // set tps_max 540 engineConfiguration->tpsMax = 540; + // yes, 30K - that's a test configuration + engineConfiguration->rpmHardLimit = 30000; + + setOperationMode(engineConfiguration, FOUR_STROKE_CRANK_SENSOR); + engineConfiguration->trigger.type = TT_TOOTHED_WHEEL_60_2; + + boardConfiguration->ignitionPins[0] = GPIO_UNASSIGNED; boardConfiguration->ignitionPins[1] = GPIO_UNASSIGNED; boardConfiguration->ignitionPins[2] = GPIO_UNASSIGNED; @@ -260,9 +267,9 @@ void setEtbTestConfiguration(DECLARE_CONFIG_PARAMETER_SIGNATURE) { /** * remember that some H-bridges require 5v control lines, not just 3v logic outputs we have on stm32 */ - CONFIGB(etb1.directionPin1) = GPIOC_7; // Frankenso high-side in order to get 5v control - CONFIGB(etb1.directionPin2) = GPIOC_9; - CONFIGB(etb1.controlPin1) = GPIOE_14; + CONFIG(etbIo[0].directionPin1) = GPIOC_7; // Frankenso high-side in order to get 5v control + CONFIG(etbIo[0].directionPin2) = GPIOC_9; + CONFIG(etbIo[0].controlPin1) = GPIOE_14; #if EFI_ELECTRONIC_THROTTLE_BODY setBoschVNH2SP30Curve(PASS_CONFIG_PARAMETER_SIGNATURE); @@ -342,10 +349,10 @@ void setTle8888TestConfiguration(DECLARE_CONFIG_PARAMETER_SIGNATURE) { setFsio(12, GPIOF_12, "0" PASS_CONFIG_PARAMETER_SUFFIX); setFsio(14, GPIOF_13, "1" PASS_CONFIG_PARAMETER_SUFFIX); #endif /* EFI_FSIO */ - CONFIGB(etb1.directionPin1) = GPIOF_15; - CONFIGB(etb1.directionPin2) = GPIOF_14; + CONFIG(etbIo[0].directionPin1) = GPIOF_15; + CONFIG(etbIo[0].directionPin2) = GPIOF_14; #endif /* STM32_HAS_GPIOF */ - CONFIG(etb1_use_two_wires) = true; + CONFIG(etb_use_two_wires) = true; boardConfiguration->isHip9011Enabled = false; // ETB #2 @@ -358,9 +365,8 @@ void setTle8888TestConfiguration(DECLARE_CONFIG_PARAMETER_SIGNATURE) { setFsio(13, GPIOE_5, "0" PASS_CONFIG_PARAMETER_SUFFIX); setFsio(15, GPIOE_6, "1" PASS_CONFIG_PARAMETER_SUFFIX); #endif - CONFIG(etb2_use_two_wires) = true; - CONFIG(etb2.directionPin1) = GPIOE_2; - CONFIG(etb2.directionPin2) = GPIOE_4; + CONFIG(etbIo[0].directionPin1) = GPIOE_2; + CONFIG(etbIo[0].directionPin2) = GPIOE_4; engineConfiguration->tps1_1AdcChannel = EFI_ADC_3; // PA3 diff --git a/firmware/config/engines/dodge_neon.cpp b/firmware/config/engines/dodge_neon.cpp index 6615b9c8d5..c07d5b80f7 100644 --- a/firmware/config/engines/dodge_neon.cpp +++ b/firmware/config/engines/dodge_neon.cpp @@ -310,7 +310,7 @@ void setDodgeNeonNGCEngineConfiguration(DECLARE_CONFIG_PARAMETER_SIGNATURE) { //engineConfiguration->fuelAlgorithm = LM_ALPHA_N; // I want to start with a simple Alpha-N setFuelLoadBin(0, 100 PASS_CONFIG_PARAMETER_SUFFIX); - setLinearCurve(config->ignitionLoadBins, IGN_LOAD_COUNT, 20, 120, 1); + setLinearCurve(config->ignitionLoadBins, 20, 120, 1); setAlgorithm(LM_SPEED_DENSITY PASS_CONFIG_PARAMETER_SUFFIX); @@ -434,8 +434,8 @@ void setDodgeNeonNGCEngineConfiguration(DECLARE_CONFIG_PARAMETER_SIGNATURE) { boardConfiguration->clutchDownPin = GPIOC_12; boardConfiguration->clutchDownPinMode = PI_PULLUP; -// boardConfiguration->clutchUpPin = GPIOA_14; // note SWCLK - conflict with SWD - boardConfiguration->clutchUpPinMode = PI_PULLUP; +// engineConfiguration->clutchUpPin = GPIOA_14; // note SWCLK - conflict with SWD + engineConfiguration->clutchUpPinMode = PI_PULLUP; engineConfiguration->activateAuxPid1 = 1; engineConfiguration->auxPidPins[0] = GPIOD_5; // playing with AUX PID for alternator @@ -456,7 +456,7 @@ void setDodgeNeonNGCEngineConfiguration(DECLARE_CONFIG_PARAMETER_SIGNATURE) { // setFsioExt(0, GPIOE_5, "0 fsio_setting", 400 PASS_CONFIG_PARAMETER_SUFFIX); #endif - boardConfiguration->vehicleSpeedSensorInputPin = GPIOA_8; + engineConfiguration->vehicleSpeedSensorInputPin = GPIOA_8; engineConfiguration->fanOnTemperature = 92; engineConfiguration->fanOffTemperature = 89; diff --git a/firmware/config/engines/ford_festiva.cpp b/firmware/config/engines/ford_festiva.cpp index d2fb46d52f..1ebc26f6b8 100644 --- a/firmware/config/engines/ford_festiva.cpp +++ b/firmware/config/engines/ford_festiva.cpp @@ -149,7 +149,7 @@ void setFordEscortGt(DECLARE_CONFIG_PARAMETER_SIGNATURE) { engineConfiguration->crankingTimingAngle = 3; engineConfiguration->crankingChargeAngle = 70; - setLinearCurve(config->ignitionLoadBins, IGN_LOAD_COUNT, 20, 105, 5); + setLinearCurve(config->ignitionLoadBins, 20, 105, 5); setWholeTimingTable_d(10 PASS_CONFIG_PARAMETER_SUFFIX); // set_whole_fuel_map 5 setWholeFuelMap(5 PASS_CONFIG_PARAMETER_SUFFIX); diff --git a/firmware/config/engines/mazda_323.cpp b/firmware/config/engines/mazda_323.cpp index 0f95cc1bcd..08056574d5 100644 --- a/firmware/config/engines/mazda_323.cpp +++ b/firmware/config/engines/mazda_323.cpp @@ -7,7 +7,9 @@ #include "mazda_323.h" -void setMazda323EngineConfiguration(engine_configuration_s *engineConfiguration) { +EXTERN_CONFIG; + +void setMazda323EngineConfiguration(DECLARE_CONFIG_PARAMETER_SIGNATURE) { engineConfiguration->specs.cylindersCount = 4; engineConfiguration->specs.displacement = 1.6; diff --git a/firmware/config/engines/mazda_323.h b/firmware/config/engines/mazda_323.h index e0a95883e2..ff614afc87 100644 --- a/firmware/config/engines/mazda_323.h +++ b/firmware/config/engines/mazda_323.h @@ -10,11 +10,8 @@ * @author Andrey Belomutskiy, (c) 2012-2017 */ -#ifndef MAZDA_323_H_ -#define MAZDA_323_H_ +#pragma once #include "engine_configuration.h" -void setMazda323EngineConfiguration(engine_configuration_s *engineConfiguration); - -#endif /* MAZDA_323_H_ */ +void setMazda323EngineConfiguration(DECLARE_CONFIG_PARAMETER_SIGNATURE); diff --git a/firmware/config/engines/mazda_miata_vvt.cpp b/firmware/config/engines/mazda_miata_vvt.cpp index a0145039e7..cb87c96203 100644 --- a/firmware/config/engines/mazda_miata_vvt.cpp +++ b/firmware/config/engines/mazda_miata_vvt.cpp @@ -304,7 +304,7 @@ void setMazdaMiata2003EngineConfiguration(DECLARE_CONFIG_PARAMETER_SIGNATURE) { boardConfiguration->alternatorControlPin = GPIOE_10; boardConfiguration->alternatorControlPinMode = OM_OPENDRAIN; -// boardConfiguration->vehicleSpeedSensorInputPin = GPIOA_8; +// engineConfiguration->vehicleSpeedSensorInputPin = GPIOA_8; boardConfiguration->vvtCamSensorUseRise = true; @@ -411,12 +411,12 @@ void setMazdaMiata2003EngineConfiguration(DECLARE_CONFIG_PARAMETER_SIGNATURE) { // VNH2SP30 three-wire ETB control // PWM - boardConfiguration->etb1.controlPin1 = GPIOE_6; - boardConfiguration->etb1.controlPinMode = OM_INVERTED; + engineConfiguration->etbIo[0].controlPin1 = GPIOE_6; + engineConfiguration->etbIo[0].controlPinMode = OM_INVERTED; // - boardConfiguration->etb1.directionPin1 = GPIOE_12; + engineConfiguration->etbIo[0].directionPin1 = GPIOE_12; // - boardConfiguration->etb1.directionPin2 = GPIOC_7; + engineConfiguration->etbIo[0].directionPin2 = GPIOC_7; // set_analog_input_pin tps PC3 engineConfiguration->tps1_1AdcChannel = EFI_ADC_13; // PC3 diff --git a/firmware/config/engines/me7pnp.cpp b/firmware/config/engines/me7pnp.cpp index 6b35eaa562..4f9f1721f2 100644 --- a/firmware/config/engines/me7pnp.cpp +++ b/firmware/config/engines/me7pnp.cpp @@ -117,7 +117,7 @@ void vag_18_Turbo(DECLARE_ENGINE_PARAMETER_SIGNATURE) { boardConfiguration->triggerInputPins[0] = GPIOG_7; #endif /* STM32_HAS_GPIOF */ #if defined(STM32_HAS_GPIOF) && STM32_HAS_GPIOF - boardConfiguration->vehicleSpeedSensorInputPin = GPIOF_14; + engineConfiguration->vehicleSpeedSensorInputPin = GPIOF_14; #endif /* STM32_HAS_GPIOF */ @@ -140,10 +140,10 @@ void vag_18_Turbo(DECLARE_ENGINE_PARAMETER_SIGNATURE) { setFsioExt (3, GPIOE_0, "0.15 90 coolant 120 min max 90 - 30 / 0.8 * +", 25 PASS_CONFIG_PARAMETER_SUFFIX); #endif engineConfiguration->auxPidFrequency[3] = 25; - CONFIG(etb1_use_two_wires) = true; + CONFIG(etb_use_two_wires) = true; #if defined(STM32_HAS_GPIOF) && STM32_HAS_GPIOF - CONFIGB(etb1.directionPin1) = GPIOF_15; - CONFIGB(etb1.directionPin2) = GPIOF_14; + CONFIG(etbIo[0].directionPin1) = GPIOF_15; + CONFIG(etbIo[0].directionPin2) = GPIOF_14; #endif /* STM32_HAS_GPIOF */ boardConfiguration->isHip9011Enabled = false; @@ -151,9 +151,8 @@ void vag_18_Turbo(DECLARE_ENGINE_PARAMETER_SIGNATURE) { setFsio (13, GPIOE_5, "0" PASS_CONFIG_PARAMETER_SUFFIX); setFsio (15, GPIOE_6, "1" PASS_CONFIG_PARAMETER_SUFFIX); #endif - CONFIG(etb2_use_two_wires) = true; - CONFIG(etb2.directionPin1) = GPIOE_2; - CONFIG(etb2.directionPin2) = GPIOE_4; + CONFIG(etbIo[1].directionPin1) = GPIOE_2; + CONFIG(etbIo[1].directionPin2) = GPIOE_4; engineConfiguration->etb.pFactor = 1.07; engineConfiguration->etb.iFactor = 0.18; diff --git a/firmware/config/engines/nissan_primera.cpp b/firmware/config/engines/nissan_primera.cpp index ea54528650..5e319d17e9 100644 --- a/firmware/config/engines/nissan_primera.cpp +++ b/firmware/config/engines/nissan_primera.cpp @@ -1,10 +1,11 @@ /** * @file nissan_primera.cpp * - * engine_type 5 + * NISSAN_PRIMERA + * set engine_type 5 * * @date Oct 14, 2013 - * @author Andrey Belomutskiy, (c) 2012-2018 + * @author Andrey Belomutskiy, (c) 2012-2019 */ #include "global.h" @@ -12,11 +13,23 @@ #if EFI_SUPPORT_NISSAN_PRIMERA #include "nissan_primera.h" -void setNissanPrimeraEngineConfiguration(engine_configuration_s *engineConfiguration) { +EXTERN_CONFIG; + +void setNissanPrimeraEngineConfiguration(DECLARE_CONFIG_PARAMETER_SIGNATURE) { + setDefaultFrankensoConfiguration(PASS_CONFIG_PARAMETER_SIGNATURE); + engineConfiguration->trigger.type = TT_NISSAN_SR20VE; + + boardConfiguration->ignitionPins[0] = GPIOD_7; + boardConfiguration->ignitionPins[1] = GPIO_UNASSIGNED; + boardConfiguration->ignitionPins[2] = GPIOD_6; + + + engineConfiguration->auxValves[0] = GPIOE_14; + engineConfiguration->auxValves[1] = GPIOE_12; } -void setNissanPrimeraEngineConfiguration_360(engine_configuration_s *engineConfiguration) { +void setNissanPrimeraEngineConfiguration_360(DECLARE_CONFIG_PARAMETER_SIGNATURE) { engineConfiguration->trigger.type = TT_NISSAN_SR20VE_360; } diff --git a/firmware/config/engines/nissan_primera.h b/firmware/config/engines/nissan_primera.h index 4d5d316e7a..17daf37936 100644 --- a/firmware/config/engines/nissan_primera.h +++ b/firmware/config/engines/nissan_primera.h @@ -2,19 +2,16 @@ * @file nissan_primera.h * * @date Oct 14, 2013 - * @author Andrey Belomutskiy, (c) 2012-2017 + * @author Andrey Belomutskiy, (c) 2012-2019 */ -#ifndef NISSAN_PRIMERA_H_ -#define NISSAN_PRIMERA_H_ +#pragma once #if EFI_SUPPORT_NISSAN_PRIMERA #include "engine_configuration.h" -void setNissanPrimeraEngineConfiguration(engine_configuration_s *engineConfiguration); -void setNissanPrimeraEngineConfiguration_360(engine_configuration_s *engineConfiguration); +void setNissanPrimeraEngineConfiguration(DECLARE_CONFIG_PARAMETER_SIGNATURE); +void setNissanPrimeraEngineConfiguration_360(DECLARE_CONFIG_PARAMETER_SIGNATURE); #endif /* EFI_SUPPORT_NISSAN_PRIMERA */ - -#endif /* NISSAN_PRIMERA_H_ */ diff --git a/firmware/config/engines/rover_v8.cpp b/firmware/config/engines/rover_v8.cpp index 883592e5d9..417fa006a2 100644 --- a/firmware/config/engines/rover_v8.cpp +++ b/firmware/config/engines/rover_v8.cpp @@ -88,7 +88,7 @@ void setRoverv8(DECLARE_CONFIG_PARAMETER_SIGNATURE) { boardConfiguration->injectionPins[6] = GPIOE_2; // Frankenstein: low side - out #7 boardConfiguration->injectionPins[7] = GPIOE_3; // Frankenstein: low side - out #8 -// not valid ICU pin boardConfiguration->vehicleSpeedSensorInputPin = GPIOC_2; +// not valid ICU pin engineConfiguration->vehicleSpeedSensorInputPin = GPIOC_2; //GPIOE_0 AND GPIOE_1 are bad pins since they conflict with accelerometer //no malfunction indicator pin needed, since we use CAN_BUS_MAZDA_RX8 diff --git a/firmware/config/engines/sachs.cpp b/firmware/config/engines/sachs.cpp index a9cc428be2..f811931d64 100644 --- a/firmware/config/engines/sachs.cpp +++ b/firmware/config/engines/sachs.cpp @@ -85,11 +85,11 @@ void setSachs(DECLARE_CONFIG_PARAMETER_SIGNATURE) { // todo: extract a method? figure out something smarter setFuelRpmBin(800, 15000 PASS_CONFIG_PARAMETER_SUFFIX); setTimingRpmBin(800, 15000 PASS_CONFIG_PARAMETER_SUFFIX); - setLinearCurve(config->veRpmBins, FUEL_RPM_COUNT, 15000, 7000, 1); - setLinearCurve(config->afrRpmBins, FUEL_RPM_COUNT, 15000, 7000, 1); + setLinearCurve(config->veRpmBins, 15000, 7000, 1); + setLinearCurve(config->afrRpmBins, 15000, 7000, 1); engineConfiguration->hasFrequencyReportingMapSensor = true; - boardConfiguration->frequencyReportingMapInputPin = GPIOC_6; + engineConfiguration->frequencyReportingMapInputPin = GPIOC_6; boardConfiguration->mapFrequency100Kpa = 159; boardConfiguration->mapFrequency0Kpa = 80; } diff --git a/firmware/config/stm32f4ems/chconf.h b/firmware/config/stm32f4ems/chconf.h index ce3817b05a..ac805a917b 100644 --- a/firmware/config/stm32f4ems/chconf.h +++ b/firmware/config/stm32f4ems/chconf.h @@ -52,7 +52,7 @@ #if !defined(ENABLE_PERF_TRACE) || defined(__DOXYGEN__) // looks like this value could not be defined in efifeatures.h - please define either externally or just change the value here - #define ENABLE_PERF_TRACE FALSE + #define ENABLE_PERF_TRACE TRUE #endif /* ENABLE_PERF_TRACE */ #include "chconf_common.h" @@ -132,7 +132,7 @@ * must be set to zero in that case. */ #if !defined(CH_CFG_TIME_QUANTUM) -#define CH_CFG_TIME_QUANTUM 20 +#define CH_CFG_TIME_QUANTUM 0 #endif /** @@ -147,7 +147,7 @@ * @note Requires @p CH_CFG_USE_MEMCORE. */ #if !defined(CH_CFG_MEMCORE_SIZE) -#define CH_CFG_MEMCORE_SIZE 2048 +#define CH_CFG_MEMCORE_SIZE 0 #endif /** @@ -346,7 +346,7 @@ * @note The default is @p TRUE. * @note Requires @p CH_CFG_USE_SEMAPHORES. */ -#define CH_CFG_USE_MAILBOXES TRUE +#define CH_CFG_USE_MAILBOXES FALSE /** * @brief I/O Queues APIs. @@ -354,7 +354,7 @@ * * @note The default is @p TRUE. */ -#define CH_CFG_USE_QUEUES TRUE +#define CH_CFG_USE_QUEUES FALSE /** * @brief Core Memory Manager APIs. @@ -364,7 +364,7 @@ * @note The default is @p TRUE. */ #if !defined(CH_CFG_USE_MEMCORE) -#define CH_CFG_USE_MEMCORE TRUE +#define CH_CFG_USE_MEMCORE FALSE #endif /** @@ -378,7 +378,7 @@ * @note Mutexes are recommended. */ #if !defined(CH_CFG_USE_HEAP) -#define CH_CFG_USE_HEAP TRUE +#define CH_CFG_USE_HEAP FALSE #endif /** @@ -389,7 +389,7 @@ * @note The default is @p TRUE. */ #if !defined(CH_CFG_USE_MEMPOOLS) -#define CH_CFG_USE_MEMPOOLS TRUE +#define CH_CFG_USE_MEMPOOLS FALSE #endif /** diff --git a/firmware/config/stm32f4ems/efifeatures.h b/firmware/config/stm32f4ems/efifeatures.h index 4ee9074219..f232636b48 100644 --- a/firmware/config/stm32f4ems/efifeatures.h +++ b/firmware/config/stm32f4ems/efifeatures.h @@ -57,8 +57,8 @@ /** * Build-in logic analyzer support. Logic analyzer viewer is one of the java console panes. */ -#ifndef EFI_WAVE_ANALYZER -#define EFI_WAVE_ANALYZER TRUE +#ifndef EFI_LOGIC_ANALYZER +#define EFI_LOGIC_ANALYZER TRUE #endif #ifndef EFI_ICU_INPUTS @@ -194,7 +194,7 @@ #define EFI_IDLE_CONTROL TRUE #endif -#define EFI_IDLE_INCREMENTAL_PID_CIC FALSE +#define EFI_IDLE_PID_CIC FALSE /** * Control the main power relay based on measured ignition voltage (Vbatt) diff --git a/firmware/config/stm32f7ems/chconf.h b/firmware/config/stm32f7ems/chconf.h index bf11a66bc5..6adecfefcb 100644 --- a/firmware/config/stm32f7ems/chconf.h +++ b/firmware/config/stm32f7ems/chconf.h @@ -31,11 +31,24 @@ #define _CHIBIOS_RT_CONF_ #define _CHIBIOS_RT_CONF_VER_5_1_ -#define CHPRINTF_USE_FLOAT TRUE +/* + * __process_stack_size__ and __process_stack_size__ defaults are each hard-coded as 0x400 in ChibiOS rules.mk files + * rusEfi do not override these defaults. + * + * http://www.chibios.com/forum/viewtopic.php?t=309 + * "__main_stack_size__ is the size of INTERRUPTS stack" + * "__process_stack_size__ is the stack of the C-runtime, in ChibiOS the "main" thread uses the C-runtime stack." + * + */ -#if !defined(EFI_CLOCK_LOCKS) || defined(__DOXYGEN__) - #define EFI_CLOCK_LOCKS FALSE -#endif /* EFI_CLOCK_LOCKS */ +#define PORT_IDLE_THREAD_STACK_SIZE 1024 + +// rusEfi main processing happens on IRQ so PORT_INT_REQUIRED_STACK has to be pretty large. +// see also a strange comment about PORT_INT_REQUIRED_STACK in global_shared.h +// see also http://www.chibios.org/dokuwiki/doku.php?id=chibios:kb:stacks +#define PORT_INT_REQUIRED_STACK 768 + +#define CHPRINTF_USE_FLOAT TRUE #if !defined(ENABLE_PERF_TRACE) || defined(__DOXYGEN__) // looks like this value could not be defined in efifeatures.h - please define either externally or just change the value here @@ -44,7 +57,6 @@ #include "chconf_common.h" - /*===========================================================================*/ /** * @name System timers settings @@ -56,18 +68,14 @@ * @brief System time counter resolution. * @note Allowed values are 16 or 32 bits. */ -#if !defined(CH_CFG_ST_RESOLUTION) #define CH_CFG_ST_RESOLUTION 32 -#endif /** * @brief System tick frequency. * @details Frequency of the system timer that drives the system ticks. This * setting also defines the system tick time unit. */ -#if !defined(CH_CFG_ST_FREQUENCY) #define CH_CFG_ST_FREQUENCY 1000 -#endif /** * @brief Time intervals data size. @@ -338,9 +346,15 @@ * @note The default is @p TRUE. * @note Requires @p CH_CFG_USE_SEMAPHORES. */ -#if !defined(CH_CFG_USE_MAILBOXES) -#define CH_CFG_USE_MAILBOXES TRUE -#endif +#define CH_CFG_USE_MAILBOXES FALSE + +/** + * @brief I/O Queues APIs. + * @details If enabled then the I/O queues APIs are included in the kernel. + * + * @note The default is @p TRUE. + */ +#define CH_CFG_USE_QUEUES FALSE /** * @brief Core Memory Manager APIs. @@ -350,7 +364,7 @@ * @note The default is @p TRUE. */ #if !defined(CH_CFG_USE_MEMCORE) -#define CH_CFG_USE_MEMCORE TRUE +#define CH_CFG_USE_MEMCORE FALSE #endif /** @@ -378,17 +392,6 @@ #define CH_CFG_USE_MEMPOOLS FALSE #endif -/** - * @brief Objects FIFOs APIs. - * @details If enabled then the objects FIFOs APIs are included - * in the kernel. - * - * @note The default is @p TRUE. - */ -#if !defined(CH_CFG_USE_OBJ_FIFOS) -#define CH_CFG_USE_OBJ_FIFOS FALSE -#endif - /** * @brief Dynamic Threads APIs. * @details If enabled then the dynamic threads creation APIs are included @@ -402,6 +405,17 @@ #define CH_CFG_USE_DYNAMIC FALSE #endif +/** + * @brief Objects FIFOs APIs. + * @details If enabled then the objects FIFOs APIs are included + * in the kernel. + * + * @note The default is @p TRUE. + */ +#if !defined(CH_CFG_USE_OBJ_FIFOS) +#define CH_CFG_USE_OBJ_FIFOS FALSE +#endif + /** @} */ /*===========================================================================*/ @@ -456,7 +470,7 @@ * @brief Enables factory for mailboxes. */ #if !defined(CH_CFG_FACTORY_MAILBOXES) -#define CH_CFG_FACTORY_MAILBOXES TRUE +#define CH_CFG_FACTORY_MAILBOXES FALSE #endif /** @@ -495,6 +509,12 @@ #define CH_DBG_SYSTEM_STATE_CHECK TRUE #endif +/** + * micro-optimization: use same (lower-level) api for lock/unlock regardless on context + * this saves us one branching + */ +#define USE_PORT_LOCK FALSE + /** * @brief Debug option, parameters checks. * @details If enabled then the checks on the API functions input @@ -503,7 +523,7 @@ * @note The default is @p FALSE. */ #if !defined(CH_DBG_ENABLE_CHECKS) -#define CH_DBG_ENABLE_CHECKS FALSE +#define CH_DBG_ENABLE_CHECKS TRUE #endif /** @@ -515,7 +535,7 @@ * @note The default is @p FALSE. */ #if !defined(CH_DBG_ENABLE_ASSERTS) -#define CH_DBG_ENABLE_ASSERTS FALSE +#define CH_DBG_ENABLE_ASSERTS TRUE #endif /** @@ -537,6 +557,17 @@ #define CH_DBG_TRACE_BUFFER_SIZE 128 #endif +/** + * @brief Debug option, trace buffer. + * @details If enabled then the context switch circular trace buffer is + * activated. + * + * @note The default is @p FALSE. + */ +#ifndef CH_DBG_ENABLE_TRACE +#define CH_DBG_ENABLE_TRACE FALSE +#endif + /** * @brief Debug option, stack checks. * @details If enabled then a runtime stack check is performed. @@ -548,7 +579,7 @@ * @p panic_msg variable set to @p NULL. */ #if !defined(CH_DBG_ENABLE_STACK_CHECK) -#define CH_DBG_ENABLE_STACK_CHECK FALSE +#define CH_DBG_ENABLE_STACK_CHECK TRUE #endif /** @@ -559,8 +590,9 @@ * * @note The default is @p FALSE. */ +// see also CH_DBG_STACK_FILL_VALUE #if !defined(CH_DBG_FILL_THREADS) -#define CH_DBG_FILL_THREADS FALSE +#define CH_DBG_FILL_THREADS TRUE #endif /** @@ -606,13 +638,15 @@ * @details User fields added to the end of the @p thread_t structure. */ #define CH_CFG_THREAD_EXTRA_FIELDS \ + void *activeStack; \ + int remainingStack; \ /* Add threads custom fields here.*/ /** * @brief Threads initialization hook. - * @details User initialization code added to the @p _thread_init() function. + * @details User initialization code added to the @p chThdInit() API. * - * @note It is invoked from within @p _thread_init() and implicitly from all + * @note It is invoked from within @p chThdInit() and implicitly from all * the threads creation APIs. */ #define CH_CFG_THREAD_INIT_HOOK(tp) { \ @@ -622,6 +656,10 @@ /** * @brief Threads finalization hook. * @details User finalization code added to the @p chThdExit() API. + * + * @note It is inserted into lock zone. + * @note It is also invoked when the threads simply return in order to + * terminate. */ #define CH_CFG_THREAD_EXIT_HOOK(tp) { \ /* Add threads finalization code here.*/ \ @@ -632,7 +670,7 @@ * @details This hook is invoked just before switching between threads. */ #define CH_CFG_CONTEXT_SWITCH_HOOK(ntp, otp) { \ - /* Context switch code here.*/ \ + contextSwitchHook(); \ } /** @@ -640,6 +678,7 @@ */ #define CH_CFG_IRQ_PROLOGUE_HOOK() { \ /* IRQ prologue code here.*/ \ + irqEnterHook(); \ } /** @@ -647,6 +686,7 @@ */ #define CH_CFG_IRQ_EPILOGUE_HOOK() { \ /* IRQ epilogue code here.*/ \ + irqExitHook(); \ } /** @@ -656,7 +696,6 @@ * @note This macro can be used to activate a power saving mode. */ #define CH_CFG_IDLE_ENTER_HOOK() { \ - /* Idle-enter code here.*/ \ } /** @@ -666,7 +705,6 @@ * @note This macro can be used to deactivate a power saving mode. */ #define CH_CFG_IDLE_LEAVE_HOOK() { \ - /* Idle-leave code here.*/ \ } /** @@ -693,7 +731,7 @@ */ #define CH_CFG_SYSTEM_HALT_HOOK(reason) { \ /* System halt code here.*/ \ - chDbgPanic3(reason, __FILE__, __LINE__); \ + chDbgPanic3(reason, __FILE__, __LINE__); \ } /** @@ -705,6 +743,7 @@ /* Trace code here.*/ \ } + /** @} */ /*===========================================================================*/ diff --git a/firmware/config/stm32f7ems/mcuconf.h b/firmware/config/stm32f7ems/mcuconf.h index 8b4d1269a4..4059ae77d7 100644 --- a/firmware/config/stm32f7ems/mcuconf.h +++ b/firmware/config/stm32f7ems/mcuconf.h @@ -38,6 +38,11 @@ */ #define UART_DMA_IRQ_PRIORITY (PRECISE_SCHEDULING_TIMER_PRIORITY + 2) +/* + * SysTick driver system settings. + */ +#define STM32_ST_IRQ_PRIORITY 8 +#define STM32_ST_USE_TIMER 2 /* * STM32F7xx drivers configuration. @@ -162,8 +167,8 @@ #define STM32_DAC_DUAL_MODE FALSE #define STM32_DAC_USE_DAC1_CH1 FALSE #define STM32_DAC_USE_DAC1_CH2 FALSE -#define STM32_DAC_DAC1_CH1_IRQ_PRIORITY 10 -#define STM32_DAC_DAC1_CH2_IRQ_PRIORITY 10 +#define STM32_DAC_DAC1_CH1_IRQ_PRIORITY PRECISE_SCHEDULING_TIMER_PRIORITY + 6 +#define STM32_DAC_DAC1_CH2_IRQ_PRIORITY PRECISE_SCHEDULING_TIMER_PRIORITY + 6 #define STM32_DAC_DAC1_CH1_DMA_PRIORITY 2 #define STM32_DAC_DAC1_CH2_DMA_PRIORITY 2 #define STM32_DAC_DAC1_CH1_DMA_STREAM STM32_DMA_STREAM_ID(1, 5) @@ -172,18 +177,19 @@ /* * EXT driver system settings. */ -#define STM32_EXT_EXTI0_IRQ_PRIORITY PRECISE_SCHEDULING_TIMER_PRIORITY + 2 -#define STM32_EXT_EXTI1_IRQ_PRIORITY PRECISE_SCHEDULING_TIMER_PRIORITY + 2 -#define STM32_EXT_EXTI2_IRQ_PRIORITY PRECISE_SCHEDULING_TIMER_PRIORITY + 2 -#define STM32_EXT_EXTI3_IRQ_PRIORITY PRECISE_SCHEDULING_TIMER_PRIORITY + 2 -#define STM32_EXT_EXTI4_IRQ_PRIORITY PRECISE_SCHEDULING_TIMER_PRIORITY + 2 -#define STM32_EXT_EXTI5_9_IRQ_PRIORITY PRECISE_SCHEDULING_TIMER_PRIORITY + 2 -#define STM32_EXT_EXTI10_15_IRQ_PRIORITY PRECISE_SCHEDULING_TIMER_PRIORITY + 2 -#define STM32_EXT_EXTI16_IRQ_PRIORITY PRECISE_SCHEDULING_TIMER_PRIORITY + 2 +#define STM32_EXT_EXT_IRQ_PRIORITY ICU_PRIORITY +#define STM32_EXT_EXTI0_IRQ_PRIORITY STM32_EXT_EXT_IRQ_PRIORITY +#define STM32_EXT_EXTI1_IRQ_PRIORITY STM32_EXT_EXT_IRQ_PRIORITY +#define STM32_EXT_EXTI2_IRQ_PRIORITY STM32_EXT_EXT_IRQ_PRIORITY +#define STM32_EXT_EXTI3_IRQ_PRIORITY STM32_EXT_EXT_IRQ_PRIORITY +#define STM32_EXT_EXTI4_IRQ_PRIORITY STM32_EXT_EXT_IRQ_PRIORITY +#define STM32_EXT_EXTI5_9_IRQ_PRIORITY STM32_EXT_EXT_IRQ_PRIORITY +#define STM32_EXT_EXTI10_15_IRQ_PRIORITY STM32_EXT_EXT_IRQ_PRIORITY +#define STM32_EXT_EXTI16_IRQ_PRIORITY STM32_EXT_EXT_IRQ_PRIORITY #define STM32_EXT_EXTI17_IRQ_PRIORITY 15 -#define STM32_EXT_EXTI18_IRQ_PRIORITY PRECISE_SCHEDULING_TIMER_PRIORITY + 2 -#define STM32_EXT_EXTI19_IRQ_PRIORITY PRECISE_SCHEDULING_TIMER_PRIORITY + 2 -#define STM32_EXT_EXTI20_IRQ_PRIORITY PRECISE_SCHEDULING_TIMER_PRIORITY + 2 +#define STM32_EXT_EXTI18_IRQ_PRIORITY STM32_EXT_EXT_IRQ_PRIORITY +#define STM32_EXT_EXTI19_IRQ_PRIORITY STM32_EXT_EXT_IRQ_PRIORITY +#define STM32_EXT_EXTI20_IRQ_PRIORITY STM32_EXT_EXT_IRQ_PRIORITY #define STM32_EXT_EXTI21_IRQ_PRIORITY 15 #define STM32_EXT_EXTI22_IRQ_PRIORITY 15 @@ -356,11 +362,6 @@ #define STM32_SPI_SPI6_IRQ_PRIORITY 10 #define STM32_SPI_DMA_ERROR_HOOK(spip) osalSysHalt("DMA failure") -/* - * ST driver system settings. - */ -#define STM32_ST_IRQ_PRIORITY 8 -#define STM32_ST_USE_TIMER 2 /* * UART driver system settings. diff --git a/firmware/console/binary/tunerstudio.cpp b/firmware/console/binary/tunerstudio.cpp index be7ff45cb5..8dc37b6138 100644 --- a/firmware/console/binary/tunerstudio.cpp +++ b/firmware/console/binary/tunerstudio.cpp @@ -76,6 +76,7 @@ #include "bluetooth.h" #include "tunerstudio_io.h" #include "tooth_logger.h" +#include "electronic_throttle.h" #include #include "engine_configuration.h" @@ -94,11 +95,11 @@ #ifndef EFI_IDLE_CONTROL - #if EFI_IDLE_INCREMENTAL_PID_CIC + #if EFI_IDLE_PID_CIC extern PidCic idlePid; #else extern Pid idlePid; - #endif /* EFI_IDLE_INCREMENTAL_PID_CIC */ + #endif /* EFI_IDLE_PID_CIC */ #endif /* EFI_IDLE_CONTROL */ @@ -256,7 +257,7 @@ static void onlineApplyWorkingCopyBytes(int currentPageId, uint32_t offset, int } } -extern Pid etbPid; +extern EtbController etbController[ETB_COUNT]; static const void * getStructAddr(int structId) { switch (structId) { @@ -274,7 +275,7 @@ static const void * getStructAddr(int structId) { return static_cast(&engine->triggerCentral.triggerState); #if EFI_ELECTRONIC_THROTTLE_BODY case LDS_ETB_PID_STATE_INDEX: - return static_cast(&etbPid); + return static_cast(&etbController[0].etbPid); #endif /* EFI_ELECTRONIC_THROTTLE_BODY */ #ifndef EFI_IDLE_CONTROL @@ -487,7 +488,9 @@ static bool isKnownCommand(char command) { || command == TS_GET_LOGGER_BUFFER || command == TS_GET_TEXT || command == TS_CRC_CHECK_COMMAND - || command == TS_GET_FIRMWARE_VERSION; + || command == TS_GET_FIRMWARE_VERSION + || command == TS_PERF_TRACE_BEGIN + || command == TS_PERF_TRACE_GET_BUFFER; } // this function runs indefinitely @@ -852,20 +855,20 @@ int tunerStudioHandleCrcCommand(ts_channel_s *tsChannel, char *data, int incomin } break; - case TS_PERF_TRACE_BEGIN: +#endif /* EFI_TOOTH_LOGGER */ #if ENABLE_PERF_TRACE + case TS_PERF_TRACE_BEGIN: perfTraceEnable(); -#endif /* ENABLE_PERF_TRACE */ + sendOkResponse(tsChannel, TS_CRC); break; case TS_PERF_TRACE_GET_BUFFER: { -#if ENABLE_PERF_TRACE auto trace = perfTraceGetBuffer(); sr5SendResponse(tsChannel, TS_CRC, trace.Buffer, trace.Size); -#endif /* ENABLE_PERF_TRACE */ } -#endif /* EFI_TOOTH_LOGGER */ + break; +#endif /* ENABLE_PERF_TRACE */ default: tunerStudioError("ERROR: ignoring unexpected command"); return false; diff --git a/firmware/console/binary/tunerstudio_io.cpp b/firmware/console/binary/tunerstudio_io.cpp index f56a5318d4..9a6111ea5a 100644 --- a/firmware/console/binary/tunerstudio_io.cpp +++ b/firmware/console/binary/tunerstudio_io.cpp @@ -102,6 +102,10 @@ void startTsPort(ts_channel_s *tsChannel) { if (CONFIGB(useSerialPort)) { print("TunerStudio over USART"); + /** + * We have hard-coded USB serial console so that it would be clear how to connect to each specific board, + * but for UART serial we allow users to change settings. + */ efiSetPadMode("tunerstudio rx", engineConfiguration->binarySerialRxPin, PAL_MODE_ALTERNATE(TS_SERIAL_AF)); efiSetPadMode("tunerstudio tx", engineConfiguration->binarySerialTxPin, PAL_MODE_ALTERNATE(TS_SERIAL_AF)); diff --git a/firmware/console/eficonsole.cpp b/firmware/console/eficonsole.cpp index a002a4363b..120bd0e87e 100644 --- a/firmware/console/eficonsole.cpp +++ b/firmware/console/eficonsole.cpp @@ -78,8 +78,8 @@ static void sayHello(void) { scheduleMsg(&logger, "CH_DBG_SYSTEM_STATE_CHECK=%d", CH_DBG_SYSTEM_STATE_CHECK); scheduleMsg(&logger, "CH_DBG_ENABLE_STACK_CHECK=%d", CH_DBG_ENABLE_STACK_CHECK); -#ifdef EFI_WAVE_ANALYZER - scheduleMsg(&logger, "EFI_WAVE_ANALYZER=%d", EFI_WAVE_ANALYZER); +#ifdef EFI_LOGIC_ANALYZER + scheduleMsg(&logger, "EFI_LOGIC_ANALYZER=%d", EFI_LOGIC_ANALYZER); #endif #ifdef EFI_TUNER_STUDIO scheduleMsg(&logger, "EFI_TUNER_STUDIO=%d", EFI_TUNER_STUDIO); diff --git a/firmware/console/status_loop.cpp b/firmware/console/status_loop.cpp index 920c0c916a..9f0b9ee948 100644 --- a/firmware/console/status_loop.cpp +++ b/firmware/console/status_loop.cpp @@ -30,9 +30,9 @@ #include "engine_controller.h" #include "adc_inputs.h" -#if EFI_WAVE_ANALYZER -#include "wave_analyzer.h" -#endif /* EFI_WAVE_ANALYZER */ +#if EFI_LOGIC_ANALYZER +#include "logic_analyzer.h" +#endif /* EFI_LOGIC_ANALYZER */ #include "trigger_central.h" #include "allsensors.h" @@ -458,10 +458,10 @@ void printOverallStatus(systime_t nowSeconds) { printOutPin(PROTOCOL_HIP_NAME, CONFIGB(hip9011IntHoldPin)); printOutPin(PROTOCOL_TACH_NAME, CONFIGB(tachOutputPin)); printOutPin(PROTOCOL_DIZZY_NAME, engineConfiguration->dizzySparkOutputPin); -#if EFI_WAVE_ANALYZER +#if EFI_LOGIC_ANALYZER printOutPin(PROTOCOL_WA_CHANNEL_1, CONFIGB(logicAnalyzerPins)[0]); printOutPin(PROTOCOL_WA_CHANNEL_2, CONFIGB(logicAnalyzerPins)[1]); -#endif /* EFI_WAVE_ANALYZER */ +#endif /* EFI_LOGIC_ANALYZER */ for (int i = 0; i < engineConfiguration->specs.cylindersCount; i++) { printOutPin(enginePins.coils[i].getShortName(), CONFIGB(ignitionPins)[i]); @@ -524,9 +524,9 @@ void updateDevConsoleState(void) { chThdSleepMilliseconds(200); #endif -#if EFI_WAVE_ANALYZER +#if EFI_LOGIC_ANALYZER printWave(&logger); -#endif /* EFI_WAVE_ANALYZER */ +#endif /* EFI_LOGIC_ANALYZER */ scheduleLogging(&logger); } @@ -741,7 +741,7 @@ void updateTunerStudioState(TunerStudioOutputChannels *tsOutputChannels DECLARE_ tsOutputChannels->vBatt = getVBatt(PASS_ENGINE_PARAMETER_SIGNATURE); } // offset 32 - tsOutputChannels->tpsADC = getTPS12bitAdc(PASS_ENGINE_PARAMETER_SIGNATURE) / TPS_TS_CONVERSION; + tsOutputChannels->tpsADC = getTPS12bitAdc(0 PASS_ENGINE_PARAMETER_SUFFIX) / TPS_TS_CONVERSION; // offset 36 #if EFI_ANALOG_SENSORS tsOutputChannels->baroPressure = hasBaroSensor() ? getBaroPressure() : 0; diff --git a/firmware/controllers/actuators/alternator_controller.cpp b/firmware/controllers/actuators/alternator_controller.cpp index a904422368..44ac40ff64 100644 --- a/firmware/controllers/actuators/alternator_controller.cpp +++ b/firmware/controllers/actuators/alternator_controller.cpp @@ -133,9 +133,9 @@ void setAltPFactor(float p) { static void applyAlternatorPinState(int stateIndex, PwmConfig *state) /* pwm_gen_callback */ { efiAssertVoid(CUSTOM_ERR_6643, stateIndex < PWM_PHASE_MAX_COUNT, "invalid stateIndex"); - efiAssertVoid(CUSTOM_IDLE_WAVE_CNT, state->multiWave.waveCount == 1, "invalid idle waveCount"); + efiAssertVoid(CUSTOM_IDLE_WAVE_CNT, state->multiChannelStateSequence.waveCount == 1, "invalid idle waveCount"); OutputPin *output = state->outputPins[0]; - int value = state->multiWave.getChannelState(/*channelIndex*/0, stateIndex); + int value = state->multiChannelStateSequence.getChannelState(/*channelIndex*/0, stateIndex); /** * 'engine->isAlternatorControlEnabled' would be false is RPM is too low */ diff --git a/firmware/controllers/actuators/aux_pid.cpp b/firmware/controllers/actuators/aux_pid.cpp index 1b45c5f6da..9937b935ce 100644 --- a/firmware/controllers/actuators/aux_pid.cpp +++ b/firmware/controllers/actuators/aux_pid.cpp @@ -134,9 +134,11 @@ void startAuxPins(void) { } void stopAuxPins(void) { +#if EFI_PROD_CODE for (int i = 0;i < AUX_PID_COUNT;i++) { brain_pin_markUnused(activeConfiguration.auxPidPins[i]); } +#endif /* EFI_PROD_CODE */ } void initAuxPid(Logging *sharedLogger) { diff --git a/firmware/controllers/actuators/electronic_throttle.cpp b/firmware/controllers/actuators/electronic_throttle.cpp index b30c829ed6..51dacd6f75 100644 --- a/firmware/controllers/actuators/electronic_throttle.cpp +++ b/firmware/controllers/actuators/electronic_throttle.cpp @@ -86,9 +86,9 @@ #error "Unexpected OS ACCESS HERE" #endif +#ifndef ETB_MAX_COUNT #define ETB_MAX_COUNT 2 - -static bool shouldResetPid = false; +#endif /* ETB_MAX_COUNT */ static pid_s tuneWorkingPidSettings; static Pid tuneWorkingPid(&tuneWorkingPidSettings); @@ -103,7 +103,7 @@ static bool startupPositionError = false; #define STARTUP_NEUTRAL_POSITION_ERROR_THRESHOLD 5 -class EtbControl { +class EtbHardware { private: OutputPin m_pinEnable; OutputPin m_pinDir1; @@ -116,9 +116,7 @@ private: SimplePwm etbPwmUp; public: - DECLARE_ENGINE_PTR; - - EtbControl() : etbPwmUp("etbUp"), dcMotor(&m_pwmEnable, &m_pwmDir1, &m_pwmDir2) {} + EtbHardware() : etbPwmUp("etbUp"), dcMotor(&m_pwmEnable, &m_pwmDir1, &m_pwmDir2) {} TwoPinDcMotor dcMotor; @@ -133,49 +131,48 @@ public: // since we have pointer magic here we cannot simply have value parameter pin_output_mode_e *pinEnableMode, brain_pin_e pinDir1, - brain_pin_e pinDir2) { - dcMotor.SetType(useTwoWires ? TwoPinDcMotor::ControlType::PwmDirectionPins : TwoPinDcMotor::ControlType::PwmEnablePin); + brain_pin_e pinDir2, + ExecutorInterface* executor, + int frequency) { + dcMotor.setType(useTwoWires ? TwoPinDcMotor::ControlType::PwmDirectionPins : TwoPinDcMotor::ControlType::PwmEnablePin); m_pinEnable.initPin("ETB Enable", pinEnable, pinEnableMode); m_pinDir1.initPin("ETB Dir 1", pinDir1); m_pinDir2.initPin("ETB Dir 2", pinDir2); // Clamp to >100hz - int freq = maxI(100, engineConfiguration->etbFreq); + int clampedFrequency = maxI(100, frequency); // no need to complicate event queue with ETB PWM in unit tests #if ! EFI_UNIT_TEST startSimplePwm(&m_pwmEnable, "ETB Enable", - &engine->executor, + executor, &m_pinEnable, - freq, + clampedFrequency, 0, (pwm_gen_callback*)applyPinState); startSimplePwm(&m_pwmDir1, "ETB Dir 1", - &engine->executor, + executor, &m_pinDir1, - freq, + clampedFrequency, 0, (pwm_gen_callback*)applyPinState); startSimplePwm(&m_pwmDir2, "ETB Dir 2", - &engine->executor, + executor, &m_pinDir2, - freq, + clampedFrequency, 0, (pwm_gen_callback*)applyPinState); #endif /* EFI_UNIT_TEST */ } }; -static EtbControl etb1; extern percent_t mockPedalPosition; -Pid etbPid; - static percent_t directPwmValue = NAN; static percent_t currentEtbDuty; @@ -183,151 +180,167 @@ static percent_t currentEtbDuty; // this macro clamps both positive and negative percentages from about -100% to 100% #define ETB_PERCENT_TO_DUTY(X) (maxF(minF((X * 0.01), ETB_DUTY_LIMIT - 0.01), 0.01 - ETB_DUTY_LIMIT)) +void EtbController::init(DcMotor *motor, int ownIndex) { + this->m_motor = motor; + this->ownIndex = ownIndex; +} - int EtbController::getPeriodMs() { - return GET_PERIOD_LIMITED(&engineConfiguration->etb); +int EtbController::getPeriodMs() { + return GET_PERIOD_LIMITED(&engineConfiguration->etb); +} + +void EtbController::PeriodicTask() { + // set debug_mode 17 + if (engineConfiguration->debugMode == DBG_ELECTRONIC_THROTTLE_PID) { +#if EFI_TUNER_STUDIO + etbPid.postState(&tsOutputChannels); + tsOutputChannels.debugIntField5 = engine->engineState.etbFeedForward; +#endif /* EFI_TUNER_STUDIO */ + } else if (engineConfiguration->debugMode == DBG_ELECTRONIC_THROTTLE_EXTRA) { +#if EFI_TUNER_STUDIO + // set debug_mode 29 + tsOutputChannels.debugFloatField1 = directPwmValue; +#endif /* EFI_TUNER_STUDIO */ } - void EtbController::PeriodicTask() { - // set debug_mode 17 - if (engineConfiguration->debugMode == DBG_ELECTRONIC_THROTTLE_PID) { + if (!m_motor) { + return; + } + + if (startupPositionError) { + m_motor->set(0); + return; + } + + if (shouldResetPid) { + etbPid.reset(); + shouldResetPid = false; + } + + if (!cisnan(directPwmValue)) { + m_motor->set(directPwmValue); + return; + } + + if (boardConfiguration->pauseEtbControl) { + m_motor->set(0); + return; + } + + percent_t actualThrottlePosition = getTPSWithIndex(ownIndex PASS_ENGINE_PARAMETER_SUFFIX); + + if (engine->etbAutoTune) { + autoTune.input = actualThrottlePosition; + bool result = autoTune.Runtime(&logger); + + tuneWorkingPid.updateFactors(autoTune.output, 0, 0); + + float value = tuneWorkingPid.getOutput(50, actualThrottlePosition); + scheduleMsg(&logger, "AT input=%f output=%f PID=%f", autoTune.input, + autoTune.output, + value); + scheduleMsg(&logger, "AT PID=%f", value); + m_motor->set(ETB_PERCENT_TO_DUTY(value)); + + if (result) { + scheduleMsg(&logger, "GREAT NEWS! %f/%f/%f", autoTune.GetKp(), autoTune.GetKi(), autoTune.GetKd()); + } + + return; + } + + + percent_t pedalPosition = getPedalPosition(PASS_ENGINE_PARAMETER_SIGNATURE); + + int rpm = GET_RPM(); + engine->engineState.targetFromTable = pedal2tpsMap.getValue(rpm / RPM_1_BYTE_PACKING_MULT, pedalPosition); + percent_t etbIdleAddition = CONFIGB(useETBforIdleControl) ? engine->engineState.idle.etbIdleAddition : 0; + percent_t targetPosition = engine->engineState.targetFromTable + etbIdleAddition; + + if (engineConfiguration->debugMode == DBG_ETB_LOGIC) { #if EFI_TUNER_STUDIO - etbPid.postState(&tsOutputChannels); - tsOutputChannels.debugIntField5 = engine->engineState.etbFeedForward; + tsOutputChannels.debugFloatField1 = engine->engineState.targetFromTable; + tsOutputChannels.debugFloatField2 = engine->engineState.idle.etbIdleAddition; #endif /* EFI_TUNER_STUDIO */ - } else if (engineConfiguration->debugMode == DBG_ELECTRONIC_THROTTLE_EXTRA) { -#if EFI_TUNER_STUDIO - // set debug_mode 29 - tsOutputChannels.debugFloatField1 = directPwmValue; -#endif /* EFI_TUNER_STUDIO */ - } + } - if (startupPositionError) { - etb1.dcMotor.Set(0); - return; - } + if (cisnan(targetPosition)) { + // this could happen while changing settings + warning(CUSTOM_ERR_ETB_TARGET, "target"); + return; + } + engine->engineState.etbFeedForward = interpolate2d("etbb", targetPosition, engineConfiguration->etbBiasBins, engineConfiguration->etbBiasValues); - if (shouldResetPid) { - etbPid.reset(); - shouldResetPid = false; - } + etbPid.iTermMin = engineConfiguration->etb_iTermMin; + etbPid.iTermMax = engineConfiguration->etb_iTermMax; - if (!cisnan(directPwmValue)) { - etb1.dcMotor.Set(directPwmValue); - return; - } + currentEtbDuty = engine->engineState.etbFeedForward + + etbPid.getOutput(targetPosition, actualThrottlePosition); - if (boardConfiguration->pauseEtbControl) { - etb1.dcMotor.Set(0); - return; - } + m_motor->set(ETB_PERCENT_TO_DUTY(currentEtbDuty)); - percent_t actualThrottlePosition = getTPS(PASS_ENGINE_PARAMETER_SIGNATURE); + if (engineConfiguration->isVerboseETB) { + etbPid.showPidStatus(&logger, "ETB"); + } - if (engine->etbAutoTune) { - autoTune.input = actualThrottlePosition; - bool result = autoTune.Runtime(&logger); - - tuneWorkingPid.updateFactors(autoTune.output, 0, 0); - - float value = tuneWorkingPid.getOutput(50, actualThrottlePosition); - scheduleMsg(&logger, "AT input=%f output=%f PID=%f", autoTune.input, - autoTune.output, - value); - scheduleMsg(&logger, "AT PID=%f", value); - etb1.dcMotor.Set(ETB_PERCENT_TO_DUTY(value)); - - if (result) { - scheduleMsg(&logger, "GREAT NEWS! %f/%f/%f", autoTune.GetKp(), autoTune.GetKi(), autoTune.GetKd()); - } - - return; - } - - - percent_t pedalPosition = getPedalPosition(PASS_ENGINE_PARAMETER_SIGNATURE); - - int rpm = GET_RPM(); - engine->engineState.targetFromTable = pedal2tpsMap.getValue(rpm / RPM_1_BYTE_PACKING_MULT, pedalPosition); - percent_t etbIdleAddition = CONFIGB(useETBforIdleControl) ? engine->engineState.idle.etbIdleAddition : 0; - percent_t targetPosition = engine->engineState.targetFromTable + etbIdleAddition; - - if (engineConfiguration->debugMode == DBG_ETB_LOGIC) { -#if EFI_TUNER_STUDIO - tsOutputChannels.debugFloatField1 = engine->engineState.targetFromTable; - tsOutputChannels.debugFloatField2 = engine->engineState.idle.etbIdleAddition; -#endif /* EFI_TUNER_STUDIO */ - } - - engine->engineState.etbFeedForward = interpolate2d("etbb", targetPosition, engineConfiguration->etbBiasBins, engineConfiguration->etbBiasValues); - - etbPid.iTermMin = engineConfiguration->etb_iTermMin; - etbPid.iTermMax = engineConfiguration->etb_iTermMax; - - currentEtbDuty = engine->engineState.etbFeedForward + - etbPid.getOutput(targetPosition, actualThrottlePosition); - - etb1.dcMotor.Set(ETB_PERCENT_TO_DUTY(currentEtbDuty)); - - if (engineConfiguration->isVerboseETB) { - etbPid.showPidStatus(&logger, "ETB"); - } - - DISPLAY_STATE(Engine) + DISPLAY_STATE(Engine) DISPLAY(DISPLAY_IF(hasEtbPedalPositionSensor)) - DISPLAY_TEXT(Electronic_Throttle); - DISPLAY_SENSOR(TPS) - DISPLAY_TEXT(eol); + DISPLAY_TEXT(Electronic_Throttle); + DISPLAY_SENSOR(TPS) + DISPLAY_TEXT(eol); - DISPLAY_TEXT(Pedal); - DISPLAY_SENSOR(PPS); - DISPLAY(DISPLAY_CONFIG(throttlePedalPositionAdcChannel)); - DISPLAY_TEXT(eol); + DISPLAY_TEXT(Pedal); + DISPLAY_SENSOR(PPS); + DISPLAY(DISPLAY_CONFIG(throttlePedalPositionAdcChannel)); + DISPLAY_TEXT(eol); - DISPLAY_TEXT(Feed_forward); - DISPLAY(DISPLAY_FIELD(etbFeedForward)); - DISPLAY_TEXT(eol); + DISPLAY_TEXT(Feed_forward); + DISPLAY(DISPLAY_FIELD(etbFeedForward)); + DISPLAY_TEXT(eol); - DISPLAY_STATE(ETB_pid) - DISPLAY_TEXT(input); - DISPLAY(DISPLAY_FIELD(input)); - DISPLAY_TEXT(Output); - DISPLAY(DISPLAY_FIELD(output)); - DISPLAY_TEXT(iTerm); - DISPLAY(DISPLAY_FIELD(iTerm)); - DISPLAY_TEXT(eol); - DISPLAY(DISPLAY_FIELD(errorAmplificationCoef)); - DISPLAY(DISPLAY_FIELD(previousError)); - DISPLAY_TEXT(eol); + DISPLAY_STATE(ETB_pid) + DISPLAY_TEXT(input); + DISPLAY(DISPLAY_FIELD(input)); + DISPLAY_TEXT(Output); + DISPLAY(DISPLAY_FIELD(output)); + DISPLAY_TEXT(iTerm); + DISPLAY(DISPLAY_FIELD(iTerm)); + DISPLAY_TEXT(eol); + DISPLAY(DISPLAY_FIELD(errorAmplificationCoef)); + DISPLAY(DISPLAY_FIELD(previousError)); + DISPLAY_TEXT(eol); - DISPLAY_TEXT(Settings); - DISPLAY(DISPLAY_CONFIG(ETB_PFACTOR)); - DISPLAY(DISPLAY_CONFIG(ETB_IFACTOR)); - DISPLAY(DISPLAY_CONFIG(ETB_DFACTOR)); - DISPLAY_TEXT(eol); - DISPLAY(DISPLAY_CONFIG(ETB_OFFSET)); - DISPLAY(DISPLAY_CONFIG(ETB_PERIODMS)); - DISPLAY_TEXT(eol); - DISPLAY(DISPLAY_CONFIG(ETB_MINVALUE)); - DISPLAY(DISPLAY_CONFIG(ETB_MAXVALUE)); + DISPLAY_TEXT(Settings); + DISPLAY(DISPLAY_CONFIG(ETB_PFACTOR)); + DISPLAY(DISPLAY_CONFIG(ETB_IFACTOR)); + DISPLAY(DISPLAY_CONFIG(ETB_DFACTOR)); + DISPLAY_TEXT(eol); + DISPLAY(DISPLAY_CONFIG(ETB_OFFSET)); + DISPLAY(DISPLAY_CONFIG(ETB_PERIODMS)); + DISPLAY_TEXT(eol); + DISPLAY(DISPLAY_CONFIG(ETB_MINVALUE)); + DISPLAY(DISPLAY_CONFIG(ETB_MAXVALUE)); /* DISPLAY_ELSE */ - DISPLAY_TEXT(No_Pedal_Sensor); + DISPLAY_TEXT(No_Pedal_Sensor); /* DISPLAY_ENDIF */ #if EFI_TUNER_STUDIO - // 312 - tsOutputChannels.etbTarget = targetPosition; - // 316 - tsOutputChannels.etb1DutyCycle = currentEtbDuty; - // 320 - // Error is positive if the throttle needs to open further - tsOutputChannels.etb1Error = targetPosition - actualThrottlePosition; + // 312 + tsOutputChannels.etbTarget = targetPosition; + // 316 + tsOutputChannels.etb1DutyCycle = currentEtbDuty; + // 320 + // Error is positive if the throttle needs to open further + tsOutputChannels.etb1Error = targetPosition - actualThrottlePosition; #endif /* EFI_TUNER_STUDIO */ - } +} -EtbController etbController; +static EtbHardware etbHardware[ETB_COUNT]; +EtbController etbController[ETB_COUNT]; /** + * At the moment there are TWO ways to use this * set_etb_duty X + * set etb X * manual duty cycle control without PID. Percent value from 0 to 100 */ void setThrottleDutyCycle(percent_t level) { @@ -339,14 +352,22 @@ void setThrottleDutyCycle(percent_t level) { float dc = ETB_PERCENT_TO_DUTY(level); directPwmValue = dc; - etb1.dcMotor.Set(dc); + for (int i = 0 ; i < ETB_COUNT; i++) { + etbHardware[i].dcMotor.set(dc); + } scheduleMsg(&logger, "duty ETB duty=%f", dc); } +static bool etbOperational = false; + static void showEthInfo(void) { #if EFI_PROD_CODE static char pinNameBuffer[16]; + if (!etbOperational) { + scheduleMsg(&logger, "ETB DISABLED since no PPS"); + } + scheduleMsg(&logger, "etbAutoTune=%d", engine->etbAutoTune); @@ -357,31 +378,48 @@ static void showEthInfo(void) { getPinNameByAdcChannel("tPedal", engineConfiguration->throttlePedalPositionAdcChannel, pinNameBuffer)); scheduleMsg(&logger, "TPS=%.2f", getTPS(PASS_ENGINE_PARAMETER_SIGNATURE)); - scheduleMsg(&logger, "dir=%d DC=%f", etb1.dcMotor.isOpenDirection(), etb1.dcMotor.Get()); + scheduleMsg(&logger, "etbControlPin1=%s duty=%.2f freq=%d", - hwPortname(CONFIGB(etb1.controlPin1)), + hwPortname(CONFIG(etbIo[0].controlPin1)), currentEtbDuty, engineConfiguration->etbFreq); - scheduleMsg(&logger, "dir1=%s", hwPortname(CONFIGB(etb1.directionPin1))); - scheduleMsg(&logger, "dir2=%s", hwPortname(CONFIGB(etb1.directionPin2))); - etbPid.showPidStatus(&logger, "ETB"); + scheduleMsg(&logger, "dir1=%s", hwPortname(CONFIG(etbIo[0].directionPin1))); + scheduleMsg(&logger, "dir2=%s", hwPortname(CONFIG(etbIo[0].directionPin2))); + + for (int i = 0 ; i < ETB_COUNT; i++) { + EtbHardware *etb = &etbHardware[i]; + + scheduleMsg(&logger, "%d: dir=%d DC=%f", i, etb->dcMotor.isOpenDirection(), etb->dcMotor.get()); + } + + etbController[0].etbPid.showPidStatus(&logger, "ETB"); #endif /* EFI_PROD_CODE */ } +static void etbPidReset() { + for (int i = 0 ; i < ETB_COUNT; i++) { + etbController[i].etbPid.reset(); + } +} + #if EFI_PROD_CODE static void setEtbFrequency(int frequency) { engineConfiguration->etbFreq = frequency; - etb1.setFrequency(frequency); + for (int i = 0 ; i < ETB_COUNT; i++) { + etbHardware[i].setFrequency(frequency); + } } static void etbReset() { scheduleMsg(&logger, "etbReset"); - etb1.dcMotor.Set(0); - etbPid.reset(); + for (int i = 0 ; i < ETB_COUNT; i++) { + etbHardware[i].dcMotor.set(0); + } + etbPidReset(); mockPedalPosition = MOCK_UNDEFINED; } @@ -393,7 +431,7 @@ static void etbReset() { */ void setEtbPFactor(float value) { engineConfiguration->etb.pFactor = value; - etbPid.reset(); + etbPidReset(); showEthInfo(); } @@ -402,7 +440,7 @@ void setEtbPFactor(float value) { */ void setEtbIFactor(float value) { engineConfiguration->etb.iFactor = value; - etbPid.reset(); + etbPidReset(); showEthInfo(); } @@ -411,7 +449,7 @@ void setEtbIFactor(float value) { */ void setEtbDFactor(float value) { engineConfiguration->etb.dFactor = value; - etbPid.reset(); + etbPidReset(); showEthInfo(); } @@ -420,7 +458,7 @@ void setEtbDFactor(float value) { */ void setEtbOffset(int value) { engineConfiguration->etb.offset = value; - etbPid.reset(); + etbPidReset(); showEthInfo(); } @@ -459,8 +497,8 @@ void setBoschVNH2SP30Curve(DECLARE_CONFIG_PARAMETER_SIGNATURE) { void setDefaultEtbParameters(DECLARE_CONFIG_PARAMETER_SIGNATURE) { CONFIG(etbIdleThrottleRange) = 5; - setLinearCurveAny(config->pedalToTpsPedalBins, PEDAL_TO_TPS_SIZE, /*from*/0, /*to*/100, 1); - setLinearCurveAny(config->pedalToTpsRpmBins, PEDAL_TO_TPS_SIZE, /*from*/0, /*to*/8000 / RPM_1_BYTE_PACKING_MULT, 1); + setLinearCurve(config->pedalToTpsPedalBins, /*from*/0, /*to*/100, 1); + setLinearCurve(config->pedalToTpsRpmBins, /*from*/0, /*to*/8000 / RPM_1_BYTE_PACKING_MULT, 1); for (int pedalIndex = 0;pedalIndexbc.etb1, &activeConfiguration.bc.etb1); + for (int i = 0 ; i < ETB_COUNT; i++) { + /** + * We do not want any interruption in HW pin while adjusting other properties + */ + bool changed = isEtbPinsChanged(&engineConfiguration->etbIo[i], &activeConfiguration.etbIo[i]); + if (changed) { + return changed; + } + } + return false; } void stopETBPins(void) { - brain_pin_markUnused(activeConfiguration.bc.etb1.controlPin1); - brain_pin_markUnused(activeConfiguration.bc.etb1.directionPin1); - brain_pin_markUnused(activeConfiguration.bc.etb1.directionPin2); + for (int i = 0 ; i < ETB_COUNT; i++) { + etb_io *activeIo = &activeConfiguration.etbIo[i]; + brain_pin_markUnused(activeIo->controlPin1); + brain_pin_markUnused(activeIo->directionPin1); + brain_pin_markUnused(activeIo->directionPin2); + } } #endif /* EFI_PROD_CODE */ void onConfigurationChangeElectronicThrottleCallback(engine_configuration_s *previousConfiguration) { - shouldResetPid = !etbPid.isSame(&previousConfiguration->etb); + bool shouldResetPid = !etbController[0].etbPid.isSame(&previousConfiguration->etb); + for (int i = 0 ; i < ETB_COUNT; i++) { + etbController[i].shouldResetPid = shouldResetPid; + } } void startETBPins(DECLARE_ENGINE_PARAMETER_SIGNATURE) { - // controlPinMode is a strange feature - it's simply because I am short on 5v I/O on Frankenso with Miata NB2 test mule - etb1.start( - CONFIG(etb1_use_two_wires), - CONFIGB(etb1.controlPin1), - &CONFIGB(etb1.controlPinMode), - CONFIGB(etb1.directionPin1), - CONFIGB(etb1.directionPin2) - ); + for (int i = 0 ; i < ETB_COUNT; i++) { + etb_io *io = &engineConfiguration->etbIo[i]; + // controlPinMode is a strange feature - it's simply because I am short on 5v I/O on Frankenso with Miata NB2 test mule + etbHardware[i].start( + CONFIG(etb_use_two_wires), + io->controlPin1, + &io->controlPinMode, + io->directionPin1, + io->directionPin2, + &ENGINE(executor), + CONFIG(etbFreq) + ); + } } #if EFI_PROD_CODE && 0 @@ -588,10 +643,12 @@ void initElectronicThrottle(DECLARE_ENGINE_PARAMETER_SIGNATURE) { addConsoleActionI("etb_freq", setEtbFrequency); #endif /* EFI_PROD_CODE */ - etbPid.initPidClass(&engineConfiguration->etb); + for (int i = 0 ; i < ETB_COUNT; i++) { + etbController[i].init(&etbHardware[i].dcMotor, i); + etbController[i].etbPid.initPidClass(&engineConfiguration->etb); + INJECT_ENGINE_REFERENCE(&etbController[i]); + } - INJECT_ENGINE_REFERENCE(etb1); - INJECT_ENGINE_REFERENCE(etbController); pedal2tpsMap.init(config->pedalToTpsTable, config->pedalToTpsPedalBins, config->pedalToTpsRpmBins); @@ -599,6 +656,7 @@ void initElectronicThrottle(DECLARE_ENGINE_PARAMETER_SIGNATURE) { if (!engine->engineState.hasEtbPedalPositionSensor) { return; } + etbOperational = true; #if 0 // not alive code autoTune.SetOutputStep(0.1); @@ -621,12 +679,20 @@ void initElectronicThrottle(DECLARE_ENGINE_PARAMETER_SIGNATURE) { #if EFI_PROD_CODE if (engineConfiguration->etbCalibrationOnStart) { - etb1.dcMotor.Set(70); - chThdSleep(600); - grabTPSIsWideOpen(); - etb1.dcMotor.Set(-70); - chThdSleep(600); - grabTPSIsClosed(); + + for (int i = 0 ; i < ETB_COUNT; i++) { + EtbHardware *etb = &etbHardware[i]; + + etb->dcMotor.set(70); + chThdSleep(600); + // todo: grab with proper index + grabTPSIsWideOpen(); + etb->dcMotor.set(-70); + chThdSleep(600); + // todo: grab with proper index + grabTPSIsClosed(); + } + } // manual duty cycle control without PID. Percent value from 0 to 100 @@ -651,9 +717,11 @@ void initElectronicThrottle(DECLARE_ENGINE_PARAMETER_SIGNATURE) { #endif /* EFI_PROD_CODE */ - etbPid.reset(); + etbPidReset(); - etbController.Start(); + for (int i = 0 ; i < ETB_COUNT; i++) { + etbController[i].Start(); + } } #endif /* EFI_ELECTRONIC_THROTTLE_BODY */ diff --git a/firmware/controllers/actuators/electronic_throttle.h b/firmware/controllers/actuators/electronic_throttle.h index 2e0587120b..c2dc136aa5 100644 --- a/firmware/controllers/actuators/electronic_throttle.h +++ b/firmware/controllers/actuators/electronic_throttle.h @@ -14,12 +14,21 @@ #include "engine.h" #include "periodic_task.h" -class EtbController : public PeriodicTimerController { +class DcMotor; + +class EtbController final : public PeriodicTimerController { public: DECLARE_ENGINE_PTR; + void init(DcMotor *motor, int ownIndex); int getPeriodMs() override; void PeriodicTask() override; + Pid etbPid; + bool shouldResetPid = false; + +private: + int ownIndex; + DcMotor *m_motor; }; void initElectronicThrottle(DECLARE_ENGINE_PARAMETER_SIGNATURE); diff --git a/firmware/controllers/actuators/idle_thread.cpp b/firmware/controllers/actuators/idle_thread.cpp index 4fcd9d0e5f..8ee03533a8 100644 --- a/firmware/controllers/actuators/idle_thread.cpp +++ b/firmware/controllers/actuators/idle_thread.cpp @@ -34,6 +34,7 @@ #include "rpm_calculator.h" #include "pwm_generator.h" #include "idle_thread.h" +#include "engine_math.h" #include "engine.h" #include "periodic_task.h" @@ -58,7 +59,7 @@ static bool shouldResetPid = false; // See automaticIdleController(). static bool mightResetPid = false; -#if EFI_IDLE_INCREMENTAL_PID_CIC +#if EFI_IDLE_PID_CIC // Use new PID with CIC integrator PidCic idlePid; #else @@ -85,7 +86,7 @@ public: }; PidWithOverrides idlePid; -#endif /* EFI_IDLE_INCREMENTAL_PID_CIC */ +#endif /* EFI_IDLE_PID_CIC */ // todo: extract interface for idle valve hardware, with solenoid and stepper implementations? static SimplePwm idleSolenoid("idle"); @@ -93,6 +94,8 @@ static SimplePwm idleSolenoid("idle"); static uint32_t lastCrankingCyclesCounter = 0; static float lastCrankingIacPosition; +static iacPidMultiplier_t iacPidMultMap("iacPidMultiplier"); + /** * When the IAC position value change is insignificant (lower than this threshold), leave the poor valve alone * todo: why do we have this logic? is this ever useful? @@ -273,17 +276,18 @@ static percent_t automaticIdleController(DECLARE_ENGINE_PARAMETER_SIGNATURE) { // the state of PID has been changed, so we might reset it now, but only when needed (see idlePidDeactivationTpsThreshold) mightResetPid = true; -#if EFI_IDLE_INCREMENTAL_PID_CIC + // Apply PID Multiplier if used + if (CONFIG(useIacPidMultTable)) { + float engineLoad = getEngineLoadT(PASS_ENGINE_PARAMETER_SIGNATURE); + float multCoef = iacPidMultMap.getValue(rpm / RPM_1_BYTE_PACKING_MULT, engineLoad); + // PID can be completely disabled of multCoef==0, or it just works as usual if multCoef==1 + newValue = interpolateClamped(0.0f, engine->engineState.idle.baseIdlePosition, 1.0f, newValue, multCoef); + } + + // Apply PID Deactivation Threshold as a smooth taper for TPS transients. percent_t tpsPos = getTPS(PASS_ENGINE_PARAMETER_SIGNATURE); - - // Treat the 'newValue' as if it contains not an actual IAC position, but an incremental delta. - // So we add this delta to the base IAC position, with a smooth taper for TPS transients. - newValue = engine->engineState.idle.baseIdlePosition + interpolateClamped(0.0f, newValue, CONFIGB(idlePidDeactivationTpsThreshold), 0.0f, tpsPos); - - // apply the PID limits - newValue = maxF(newValue, CONFIG(idleRpmPid.minValue)); - newValue = minF(newValue, CONFIG(idleRpmPid.maxValue)); -#endif /* EFI_IDLE_INCREMENTAL_PID_CIC */ + // if tps==0 then PID just works as usual, or we completely disable it if tps>=threshold + newValue = interpolateClamped(0.0f, newValue, CONFIGB(idlePidDeactivationTpsThreshold), engine->engineState.idle.baseIdlePosition, tpsPos); // Interpolate to the manual position when RPM is close to the upper RPM limit (if idlePidRpmUpperLimit is set). // If RPM increases and the throttle is closed, then we're in coasting mode, and we should smoothly disable auto-pid. @@ -348,8 +352,8 @@ static percent_t automaticIdleController(DECLARE_ENGINE_PARAMETER_SIGNATURE) { } engine->acSwitchState = result; } - if (CONFIGB(clutchUpPin) != GPIO_UNASSIGNED) { - engine->clutchUpState = efiReadPin(CONFIGB(clutchUpPin)); + if (CONFIG(clutchUpPin) != GPIO_UNASSIGNED) { + engine->clutchUpState = efiReadPin(CONFIG(clutchUpPin)); } if (CONFIG(throttlePedalUpPin) != GPIO_UNASSIGNED) { engine->engineState.idle.throttlePedalUpState = efiReadPin(CONFIG(throttlePedalUpPin)); @@ -451,6 +455,7 @@ IdleController idleControllerInstance; static void applyPidSettings(DECLARE_ENGINE_PARAMETER_SIGNATURE) { idlePid.updateFactors(engineConfiguration->idleRpmPid.pFactor, engineConfiguration->idleRpmPid.iFactor, engineConfiguration->idleRpmPid.dFactor); + iacPidMultMap.init(CONFIG(iacPidMultTable), CONFIG(iacPidMultLoadBins), CONFIG(iacPidMultRpmBins)); } void setDefaultIdleParameters(DECLARE_CONFIG_PARAMETER_SIGNATURE) { @@ -516,9 +521,9 @@ void startIdleBench(void) { static void applyIdleSolenoidPinState(int stateIndex, PwmConfig *state) /* pwm_gen_callback */ { efiAssertVoid(CUSTOM_ERR_6645, stateIndex < PWM_PHASE_MAX_COUNT, "invalid stateIndex"); - efiAssertVoid(CUSTOM_ERR_6646, state->multiWave.waveCount == 1, "invalid idle waveCount"); + efiAssertVoid(CUSTOM_ERR_6646, state->multiChannelStateSequence.waveCount == 1, "invalid idle waveCount"); OutputPin *output = state->outputPins[0]; - int value = state->multiWave.getChannelState(/*channelIndex*/0, stateIndex); + int value = state->multiChannelStateSequence.getChannelState(/*channelIndex*/0, stateIndex); if (!value /* always allow turning solenoid off */ || (GET_RPM_VALUE != 0 || timeToStopIdleTest != 0) /* do not run solenoid unless engine is spinning or bench testing in progress */ ) { @@ -539,6 +544,7 @@ bool isIdleHardwareRestartNeeded() { } void stopIdleHardware(DECLARE_ENGINE_PARAMETER_SIGNATURE) { +#if EFI_PROD_CODE brain_pin_markUnused(activeConfiguration.stepperEnablePin); brain_pin_markUnused(activeConfiguration.bc.idle.stepperStepPin); brain_pin_markUnused(activeConfiguration.bc.idle.solenoidPin); @@ -546,7 +552,7 @@ void stopIdleHardware(DECLARE_ENGINE_PARAMETER_SIGNATURE) { // brain_pin_markUnused(activeConfiguration.bc.idle.); // brain_pin_markUnused(activeConfiguration.bc.idle.); // brain_pin_markUnused(activeConfiguration.bc.idle.); - +#endif /* EFI_PROD_CODE */ } void initIdleHardware(DECLARE_ENGINE_PARAMETER_SIGNATURE) { @@ -577,7 +583,7 @@ void initIdleHardware(DECLARE_ENGINE_PARAMETER_SIGNATURE) { void startIdleThread(Logging*sharedLogger DECLARE_ENGINE_PARAMETER_SUFFIX) { logger = sharedLogger; - INJECT_ENGINE_REFERENCE(idleControllerInstance); + INJECT_ENGINE_REFERENCE(&idleControllerInstance); idlePid.initPidClass(&engineConfiguration->idleRpmPid); @@ -641,9 +647,9 @@ void startIdleThread(Logging*sharedLogger DECLARE_ENGINE_PARAMETER_SUFFIX) { getInputMode(CONFIGB(clutchDownPinMode))); } - if (CONFIGB(clutchUpPin) != GPIO_UNASSIGNED) { - efiSetPadMode("clutch up switch", CONFIGB(clutchUpPin), - getInputMode(CONFIGB(clutchUpPinMode))); + if (CONFIG(clutchUpPin) != GPIO_UNASSIGNED) { + efiSetPadMode("clutch up switch", CONFIG(clutchUpPin), + getInputMode(CONFIG(clutchUpPinMode))); } if (CONFIG(throttlePedalUpPin) != GPIO_UNASSIGNED) { diff --git a/firmware/controllers/actuators/pwm_tester.cpp b/firmware/controllers/actuators/pwm_tester.cpp index 463ba917de..c257bf7f74 100644 --- a/firmware/controllers/actuators/pwm_tester.cpp +++ b/firmware/controllers/actuators/pwm_tester.cpp @@ -11,7 +11,7 @@ #if EFI_PWM_TESTER #include "pwm_tester.h" -#include "efi_wave.h" +#include "state_requence.h" #include "pwm_generator_logic.h" #include "engine.h" #include "pwm_generator.h" diff --git a/firmware/controllers/algo/advance_map.cpp b/firmware/controllers/algo/advance_map.cpp index 67e97992e2..8da18d85c9 100644 --- a/firmware/controllers/algo/advance_map.cpp +++ b/firmware/controllers/algo/advance_map.cpp @@ -224,12 +224,12 @@ angle_t getAdvance(int rpm, float engineLoad DECLARE_ENGINE_PARAMETER_SUFFIX) { } void setDefaultIatTimingCorrection(DECLARE_ENGINE_PARAMETER_SIGNATURE) { - setLinearCurve(config->ignitionIatCorrLoadBins, IGN_LOAD_COUNT, /*from*/CLT_CURVE_RANGE_FROM, 110, 1); + setLinearCurve(config->ignitionIatCorrLoadBins, /*from*/CLT_CURVE_RANGE_FROM, 110, 1); #if IGN_LOAD_COUNT == DEFAULT_IGN_LOAD_COUNT memcpy(config->ignitionIatCorrRpmBins, iatTimingRpmBins, sizeof(iatTimingRpmBins)); copyTimingTable(defaultIatTiming, config->ignitionIatCorrTable); #else - setLinearCurve(config->ignitionIatCorrLoadBins, IGN_RPM_COUNT, /*from*/0, 6000, 1); + setLinearCurve(config->ignitionIatCorrLoadBins, /*from*/0, 6000, 1); #endif /* IGN_LOAD_COUNT == DEFAULT_IGN_LOAD_COUNT */ } diff --git a/firmware/controllers/algo/algo.mk b/firmware/controllers/algo/algo.mk index 5646200dda..e150fdcf32 100644 --- a/firmware/controllers/algo/algo.mk +++ b/firmware/controllers/algo/algo.mk @@ -8,6 +8,6 @@ CONTROLLERS_ALGO_SRC_CPP = $(PROJECT_DIR)/controllers/algo/advance_map.cpp \ $(PROJECT_DIR)/controllers/algo/engine_configuration.cpp \ $(PROJECT_DIR)/controllers/algo/engine.cpp \ $(PROJECT_DIR)/controllers/algo/engine2.cpp \ - $(PROJECT_DIR)/controllers/algo/lcd_menu_tree.cpp \ + $(PROJECT_DIR)/controllers/gauges/lcd_menu_tree.cpp \ $(PROJECT_DIR)/controllers/algo/event_registry.cpp \ $(PROJECT_DIR)/controllers/algo/algo.cpp \ diff --git a/firmware/controllers/algo/auto_generated_enums.cpp b/firmware/controllers/algo/auto_generated_enums.cpp index d923bd1e0d..9612068455 100644 --- a/firmware/controllers/algo/auto_generated_enums.cpp +++ b/firmware/controllers/algo/auto_generated_enums.cpp @@ -77,6 +77,12 @@ case EFI_ADC_ERROR: return "EFI_ADC_ERROR"; case EFI_ADC_NONE: return "EFI_ADC_NONE"; +#if EFI_UNIT_TEST +case TEST_MAF_CHANNEL: +case TEST_CLT_CHANNEL: +case TEST_IAT_CHANNEL: + return "EFI_TEST"; +#endif /* EFI_UNIT_TEST */ } return NULL; } @@ -769,6 +775,8 @@ case SACHS: return "SACHS"; case MRE_MIATA_NA6: return "MRE_MIATA_NA6"; +case PROTEUS: + return "PROTEUS"; case SUBARUEJ20G_DEFAULTS: return "SUBARUEJ20G_DEFAULTS"; case SUBARU_2003_WRX: @@ -999,6 +1007,8 @@ case SC_DETAILED_RPM: return "SC_DETAILED_RPM"; case SC_MAP: return "SC_MAP"; +case SC_AUX_FAST1: + return "SC_AUX_FAST1"; case SC_OFF: return "SC_OFF"; case SC_RPM_ACCEL: diff --git a/firmware/controllers/algo/engine.cpp b/firmware/controllers/algo/engine.cpp index 2f0e2c2c57..98c1ab7b2c 100644 --- a/firmware/controllers/algo/engine.cpp +++ b/firmware/controllers/algo/engine.cpp @@ -52,16 +52,16 @@ FsioState::FsioState() { #endif } -void Engine::eInitializeTriggerShape(Logging *logger DECLARE_ENGINE_PARAMETER_SUFFIX) { +void Engine::initializeTriggerWaveform(Logging *logger DECLARE_ENGINE_PARAMETER_SUFFIX) { #if EFI_ENGINE_CONTROL && EFI_SHAFT_POSITION_INPUT // we have a confusing threading model so some synchronization would not hurt bool alreadyLocked = lockAnyContext(); - TRIGGER_SHAPE(initializeTriggerShape(logger, + TRIGGER_WAVEFORM(initializeTriggerWaveform(logger, engineConfiguration->ambiguousOperationMode, engineConfiguration->useOnlyRisingEdgeForTrigger, &engineConfiguration->trigger)); - if (TRIGGER_SHAPE(bothFrontsRequired) && engineConfiguration->useOnlyRisingEdgeForTrigger) { + if (TRIGGER_WAVEFORM(bothFrontsRequired) && engineConfiguration->useOnlyRisingEdgeForTrigger) { #if EFI_PROD_CODE || EFI_SIMULATOR firmwareError(CUSTOM_ERR_BOTH_FRONTS_REQUIRED, "Inconsistent trigger setup"); #else @@ -70,9 +70,9 @@ void Engine::eInitializeTriggerShape(Logging *logger DECLARE_ENGINE_PARAMETER_SU } - if (!TRIGGER_SHAPE(shapeDefinitionError)) { + if (!TRIGGER_WAVEFORM(shapeDefinitionError)) { /** - * this instance is used only to initialize 'this' TriggerShape instance + * this instance is used only to initialize 'this' TriggerWaveform instance * #192 BUG real hardware trigger events could be coming even while we are initializing trigger */ initState.resetTriggerState(); @@ -82,14 +82,14 @@ void Engine::eInitializeTriggerShape(Logging *logger DECLARE_ENGINE_PARAMETER_SU if (engine->triggerCentral.triggerShape.getSize() == 0) { firmwareError(CUSTOM_ERR_TRIGGER_ZERO, "triggerShape size is zero"); } - engine->engineCycleEventCount = TRIGGER_SHAPE(getLength()); + engine->engineCycleEventCount = TRIGGER_WAVEFORM(getLength()); } if (!alreadyLocked) { unlockAnyContext(); } - if (!TRIGGER_SHAPE(shapeDefinitionError)) { + if (!TRIGGER_WAVEFORM(shapeDefinitionError)) { prepareOutputSignals(PASS_ENGINE_PARAMETER_SIGNATURE); } #endif /* EFI_ENGINE_CONTROL && EFI_SHAFT_POSITION_INPUT */ @@ -121,7 +121,9 @@ void Engine::periodicSlowCallback(DECLARE_ENGINE_PARAMETER_SIGNATURE) { #if EFI_FSIO runFsio(PASS_ENGINE_PARAMETER_SIGNATURE); -#endif /* EFI_PROD_CODE && EFI_FSIO */ +#else + runHardcodedFsio(PASS_ENGINE_PARAMETER_SIGNATURE); +#endif /* EFI_FSIO */ cylinderCleanupControl(PASS_ENGINE_PARAMETER_SIGNATURE); @@ -225,6 +227,19 @@ void Engine::preCalculate(DECLARE_ENGINE_PARAMETER_SIGNATURE) { #endif } +void Engine::OnTriggerStateDecodingError() { + Engine *engine = this; + EXPAND_Engine; + triggerCentral.triggerState.handleTriggerError(PASS_ENGINE_PARAMETER_SIGNATURE); +} + +void Engine::OnTriggerStateProperState(efitick_t nowNt) { + Engine *engine = this; + EXPAND_Engine; + rpmCalculator.setSpinningUp(nowNt PASS_ENGINE_PARAMETER_SUFFIX); +} + + void Engine::setConfig(persistent_config_s *config) { this->config = config; engineConfigurationPtr = &config->engineConfiguration; @@ -382,3 +397,22 @@ void doScheduleStopEngine(DECLARE_ENGINE_PARAMETER_SIGNATURE) { // let's close injectors or else if these happen to be open right now enginePins.stopPins(); } + +void action_s::setAction(schfunc_t callback, void *param) { + this->callback = callback; + this->param = param; +} + +void action_s::execute() { + efiAssertVoid(CUSTOM_ERR_ASSERT, callback != NULL, "callback==null1"); + callback(param); +} + +schfunc_t action_s::getCallback() const { + return callback; +} + +void * action_s::getArgument() const { + return param; +} + diff --git a/firmware/controllers/algo/engine.h b/firmware/controllers/algo/engine.h index c4ff7f42bf..0c4c26ff3e 100644 --- a/firmware/controllers/algo/engine.h +++ b/firmware/controllers/algo/engine.h @@ -45,10 +45,16 @@ class RpmCalculator; #define CLEANUP_MODE_TPS 90 #define STEPPER_PARKING_TPS CLEANUP_MODE_TPS -class Engine { +#define CYCLE_ALTERNATION 2 + +class Engine : public TriggerStateListener { public: explicit Engine(persistent_config_s *config); Engine(); + + void OnTriggerStateDecodingError() override; + void OnTriggerStateProperState(efitick_t nowNt) override; + void setConfig(persistent_config_s *config); injection_mode_e getCurrentInjectionMode(DECLARE_ENGINE_PARAMETER_SIGNATURE); @@ -56,6 +62,10 @@ public: LocalVersionHolder auxParametersVersion; operation_mode_e getOperationMode(DECLARE_ENGINE_PARAMETER_SIGNATURE); + AuxActor auxValves[AUX_DIGITAL_VALVE_COUNT][2]; + + bool needTdcCallback = true; + /** * By the way 32-bit value should hold at least 400 hours of events at 6K RPM x 12 events per revolution */ @@ -102,9 +112,11 @@ public: bool needToStopEngine(efitick_t nowNt) const; bool etbAutoTune = false; /** - * That's the linked list of pending spark firing events + * That's the linked list of pending events scheduled in relation to trigger + * At the moment we iterate over the whole list while looking for events for specific trigger index + * We can make it an array of lists per trigger index, but that would take some RAM and probably not needed yet. */ - IgnitionEvent *ignitionEventsHead = nullptr; + AngleBasedEvent *angleBasedEventsHead = nullptr; /** * this is based on isEngineChartEnabled and engineSnifferRpmThreshold settings */ @@ -132,9 +144,6 @@ public: // timestamp of most recent time RPM hard limit was triggered efitime_t rpmHardLimitTimestamp = 0; - // todo: should be a field on some other class, not Engine? - bool isInitializingTrigger = false; - /** * This flag indicated a big enough problem that engine control would be * prohibited if this flag is set to true. @@ -185,7 +194,7 @@ public: void periodicFastCallback(DECLARE_ENGINE_PARAMETER_SIGNATURE); void periodicSlowCallback(DECLARE_ENGINE_PARAMETER_SIGNATURE); void updateSlowSensors(DECLARE_ENGINE_PARAMETER_SIGNATURE); - void eInitializeTriggerShape(Logging *logger DECLARE_ENGINE_PARAMETER_SUFFIX); + void initializeTriggerWaveform(Logging *logger DECLARE_ENGINE_PARAMETER_SUFFIX); bool clutchUpState = false; bool clutchDownState = false; diff --git a/firmware/controllers/algo/engine2.cpp b/firmware/controllers/algo/engine2.cpp index 3e9bf728a9..8ef3bcd6bf 100644 --- a/firmware/controllers/algo/engine2.cpp +++ b/firmware/controllers/algo/engine2.cpp @@ -145,7 +145,7 @@ void EngineState::periodicFastCallback(DECLARE_ENGINE_PARAMETER_SIGNATURE) { #if EFI_ENGINE_CONTROL if (!engine->slowCallBackWasInvoked) { - warning(CUSTOM_ERR_6696, "Slow not invoked yet"); + warning(CUSTOM_SLOW_NOT_INVOKED, "Slow not invoked yet"); } efitick_t nowNt = getTimeNowNt(); if (ENGINE(rpmCalculator).isCranking(PASS_ENGINE_PARAMETER_SIGNATURE)) { diff --git a/firmware/controllers/algo/engine_configuration.cpp b/firmware/controllers/algo/engine_configuration.cpp index 5d15bf81ce..6269268700 100644 --- a/firmware/controllers/algo/engine_configuration.cpp +++ b/firmware/controllers/algo/engine_configuration.cpp @@ -143,6 +143,8 @@ static fuel_table_t alphaNfuel = { */ #ifdef EFI_ACTIVE_CONFIGURATION_IN_FLASH engine_configuration_s & activeConfiguration = *(engine_configuration_s *)EFI_ACTIVE_CONFIGURATION_IN_FLASH; +// we cannot use this activeConfiguration until we call rememberCurrentConfiguration() +bool isActiveConfigurationVoid = true; #else static engine_configuration_s activeConfigurationLocalStorage; engine_configuration_s & activeConfiguration = activeConfigurationLocalStorage; @@ -153,6 +155,8 @@ extern engine_configuration_s *engineConfiguration; void rememberCurrentConfiguration(DECLARE_ENGINE_PARAMETER_SIGNATURE) { #ifndef EFI_ACTIVE_CONFIGURATION_IN_FLASH memcpy(&activeConfiguration, engineConfiguration, sizeof(engine_configuration_s)); +#else + isActiveConfigurationVoid = false; #endif /* EFI_ACTIVE_CONFIGURATION_IN_FLASH */ } @@ -208,7 +212,7 @@ void setConstantDwell(floatms_t dwellMs DECLARE_CONFIG_PARAMETER_SUFFIX) { for (int i = 0; i < DWELL_CURVE_SIZE; i++) { engineConfiguration->sparkDwellRpmBins[i] = 1000 * i; } - setLinearCurve(engineConfiguration->sparkDwellValues, DWELL_CURVE_SIZE, dwellMs, dwellMs, 0.01); + setLinearCurve(engineConfiguration->sparkDwellValues, dwellMs, dwellMs, 0.01); } void setAfrMap(afr_table_t table, float value) { @@ -248,9 +252,9 @@ void setWholeIgnitionIatCorr(float value DECLARE_CONFIG_PARAMETER_SUFFIX) { } void setFuelTablesLoadBin(float minValue, float maxValue DECLARE_CONFIG_PARAMETER_SUFFIX) { - setLinearCurve(config->injPhaseLoadBins, FUEL_LOAD_COUNT, minValue, maxValue, 1); - setLinearCurve(config->veLoadBins, FUEL_LOAD_COUNT, minValue, maxValue, 1); - setLinearCurve(config->afrLoadBins, FUEL_LOAD_COUNT, minValue, maxValue, 1); + setLinearCurve(config->injPhaseLoadBins, minValue, maxValue, 1); + setLinearCurve(config->veLoadBins, minValue, maxValue, 1); + setLinearCurve(config->afrLoadBins, minValue, maxValue, 1); } void setTimingMap(ignition_table_t map, float value) { @@ -304,6 +308,11 @@ void prepareVoidConfiguration(engine_configuration_s *engineConfiguration) { engineConfiguration->vbattAdcChannel = EFI_ADC_NONE; engineConfiguration->map.sensor.hwChannel = EFI_ADC_NONE; engineConfiguration->mafAdcChannel = EFI_ADC_NONE; +/* this breaks unit tests lovely TODO: fix this? + engineConfiguration->tps1_1AdcChannel = EFI_ADC_NONE; +*/ + engineConfiguration->tps2_1AdcChannel = EFI_ADC_NONE; + engineConfiguration->bc.auxFastSensor1_adcChannel = EFI_ADC_NONE; engineConfiguration->acSwitchAdc = EFI_ADC_NONE; engineConfiguration->externalKnockSenseAdc = EFI_ADC_NONE; engineConfiguration->fuelLevelSensor = EFI_ADC_NONE; @@ -313,7 +322,7 @@ void prepareVoidConfiguration(engine_configuration_s *engineConfiguration) { engineConfiguration->high_fuel_pressure_sensor_2 = EFI_ADC_NONE; boardConfiguration->clutchDownPinMode = PI_PULLUP; - boardConfiguration->clutchUpPinMode = PI_PULLUP; + engineConfiguration->clutchUpPinMode = PI_PULLUP; engineConfiguration->brakePedalPinMode = PI_PULLUP; } @@ -450,11 +459,11 @@ static void setDefaultFuelCutParameters(DECLARE_ENGINE_PARAMETER_SIGNATURE) { static void setDefaultCrankingSettings(DECLARE_ENGINE_PARAMETER_SIGNATURE) { CONFIG(useTLE8888_cranking_hack) = true; - setLinearCurve(engineConfiguration->crankingTpsCoef, CRANKING_CURVE_SIZE, /*from*/1, /*to*/1, 1); - setLinearCurve(engineConfiguration->crankingTpsBins, CRANKING_CURVE_SIZE, 0, 100, 1); + setLinearCurve(engineConfiguration->crankingTpsCoef, /*from*/1, /*to*/1, 1); + setLinearCurve(engineConfiguration->crankingTpsBins, 0, 100, 1); - setLinearCurve(config->cltCrankingCorrBins, CLT_CRANKING_CURVE_SIZE, CLT_CURVE_RANGE_FROM, 100, 1); - setLinearCurve(config->cltCrankingCorr, CLT_CRANKING_CURVE_SIZE, 1.0, 1.0, 1); + setLinearCurve(config->cltCrankingCorrBins, CLT_CURVE_RANGE_FROM, 100, 1); + setLinearCurve(config->cltCrankingCorr, 1.0, 1.0, 1); config->crankingFuelCoef[0] = 2.8; // base cranking fuel adjustment coefficient config->crankingFuelBins[0] = -20; // temperature in C @@ -510,7 +519,7 @@ static void setDefaultCrankingSettings(DECLARE_ENGINE_PARAMETER_SIGNATURE) { * see also setTargetRpmCurve() */ static void setDefaultIdleSpeedTarget(DECLARE_ENGINE_PARAMETER_SIGNATURE) { - setLinearCurve(engineConfiguration->cltIdleRpmBins, CLT_CURVE_SIZE, CLT_CURVE_RANGE_FROM, 140, 10); + setLinearCurve(engineConfiguration->cltIdleRpmBins, CLT_CURVE_RANGE_FROM, 140, 10); setCurveValue(engineConfiguration->cltIdleRpmBins, engineConfiguration->cltIdleRpm, CLT_CURVE_SIZE, -30, 1350); setCurveValue(engineConfiguration->cltIdleRpmBins, engineConfiguration->cltIdleRpm, CLT_CURVE_SIZE, -20, 1300); @@ -548,8 +557,8 @@ static void setCanFrankensoDefaults(DECLARE_CONFIG_PARAMETER_SIGNATURE) { * see also setDefaultIdleSpeedTarget() */ void setTargetRpmCurve(int rpm DECLARE_CONFIG_PARAMETER_SUFFIX) { - setLinearCurve(engineConfiguration->cltIdleRpmBins, CLT_CURVE_SIZE, CLT_CURVE_RANGE_FROM, 90, 10); - setLinearCurve(engineConfiguration->cltIdleRpm, CLT_CURVE_SIZE, rpm, rpm, 10); + setLinearCurve(engineConfiguration->cltIdleRpmBins, CLT_CURVE_RANGE_FROM, 90, 10); + setLinearCurve(engineConfiguration->cltIdleRpm, rpm, rpm, 10); } int getTargetRpmForIdleCorrection(DECLARE_ENGINE_PARAMETER_SIGNATURE) { @@ -600,7 +609,7 @@ static void setDefaultEngineConfiguration(DECLARE_ENGINE_PARAMETER_SIGNATURE) { setDefaultEtbBiasCurve(PASS_CONFIG_PARAMETER_SIGNATURE); #endif /* EFI_ELECTRONIC_THROTTLE_BODY */ - CONFIGB(mafSensorType) = Bosch0280218037; + CONFIG(mafSensorType) = Bosch0280218037; setBosch0280218037(config); setBosch02880155868(PASS_ENGINE_PARAMETER_SIGNATURE); @@ -639,17 +648,17 @@ static void setDefaultEngineConfiguration(DECLARE_ENGINE_PARAMETER_SIGNATURE) { engineConfiguration->alternatorControl.minValue = 10; engineConfiguration->alternatorControl.maxValue = 90; - setLinearCurve(engineConfiguration->cltTimingBins, CLT_TIMING_CURVE_SIZE, CLT_CURVE_RANGE_FROM, 120, 1); - setLinearCurve(engineConfiguration->cltTimingExtra, CLT_TIMING_CURVE_SIZE, 0, 0, 1); + setLinearCurve(engineConfiguration->cltTimingBins, CLT_CURVE_RANGE_FROM, 120, 1); + setLinearCurve(engineConfiguration->cltTimingExtra, 0, 0, 1); - setLinearCurve(engineConfiguration->fsioCurve1Bins, FSIO_CURVE_16, 0, 100, 1); - setLinearCurve(engineConfiguration->fsioCurve1, FSIO_CURVE_16, 0, 100, 1); + setLinearCurve(engineConfiguration->fsioCurve1Bins, 0, 100, 1); + setLinearCurve(engineConfiguration->fsioCurve1, 0, 100, 1); - setLinearCurve(engineConfiguration->fsioCurve2Bins, FSIO_CURVE_16, 0, 100, 1); - setLinearCurve(engineConfiguration->fsioCurve2, FSIO_CURVE_16, 30, 170, 1); + setLinearCurve(engineConfiguration->fsioCurve2Bins, 0, 100, 1); + setLinearCurve(engineConfiguration->fsioCurve2, 30, 170, 1); - setLinearCurve(engineConfiguration->fsioCurve3Bins, FSIO_CURVE_8, 0, 100, 1); - setLinearCurve(engineConfiguration->fsioCurve4Bins, FSIO_CURVE_8, 0, 100, 1); + setLinearCurve(engineConfiguration->fsioCurve3Bins, 0, 100, 1); + setLinearCurve(engineConfiguration->fsioCurve4Bins, 0, 100, 1); setDefaultWarmupIdleCorrection(PASS_CONFIG_PARAMETER_SIGNATURE); @@ -677,10 +686,10 @@ static void setDefaultEngineConfiguration(DECLARE_ENGINE_PARAMETER_SIGNATURE) { setTimingLoadBin(1.2, 4.4 PASS_CONFIG_PARAMETER_SUFFIX); setTimingRpmBin(800, 7000 PASS_CONFIG_PARAMETER_SUFFIX); - setLinearCurve(engineConfiguration->map.samplingAngleBins, MAP_ANGLE_SIZE, 800, 7000, 1); - setLinearCurve(engineConfiguration->map.samplingAngle, MAP_ANGLE_SIZE, 100, 130, 1); - setLinearCurve(engineConfiguration->map.samplingWindowBins, MAP_ANGLE_SIZE, 800, 7000, 1); - setLinearCurve(engineConfiguration->map.samplingWindow, MAP_ANGLE_SIZE, 50, 50, 1); + setLinearCurve(engineConfiguration->map.samplingAngleBins, 800, 7000, 1); + setLinearCurve(engineConfiguration->map.samplingAngle, 100, 130, 1); + setLinearCurve(engineConfiguration->map.samplingWindowBins, 800, 7000, 1); + setLinearCurve(engineConfiguration->map.samplingWindow, 50, 50, 1); // set_whole_timing_map 3 setWholeFuelMap(3 PASS_CONFIG_PARAMETER_SUFFIX); @@ -696,19 +705,19 @@ static void setDefaultEngineConfiguration(DECLARE_ENGINE_PARAMETER_SIGNATURE) { setFuelTablesLoadBin(10, 160 PASS_CONFIG_PARAMETER_SUFFIX); setDefaultIatTimingCorrection(PASS_ENGINE_PARAMETER_SIGNATURE); - setLinearCurve(engineConfiguration->mapAccelTaperBins, FSIO_TABLE_8, 0, 32, 4); - setLinearCurve(engineConfiguration->mapAccelTaperMult, FSIO_TABLE_8, 1, 1, 1); + setLinearCurve(engineConfiguration->mapAccelTaperBins, 0, 32, 4); + setLinearCurve(engineConfiguration->mapAccelTaperMult, 1, 1, 1); - setLinearCurve(config->tpsTpsAccelFromRpmBins, FSIO_TABLE_8, 0, 100, 10); - setLinearCurve(config->tpsTpsAccelToRpmBins, FSIO_TABLE_8, 0, 100, 10); + setLinearCurve(config->tpsTpsAccelFromRpmBins, 0, 100, 10); + setLinearCurve(config->tpsTpsAccelToRpmBins, 0, 100, 10); - setLinearCurve(config->fsioTable1LoadBins, FSIO_TABLE_8, 20, 120, 10); + setLinearCurve(config->fsioTable1LoadBins, 20, 120, 10); setRpmTableBin(config->fsioTable1RpmBins, FSIO_TABLE_8); - setLinearCurve(config->fsioTable2LoadBins, FSIO_TABLE_8, 20, 120, 10); + setLinearCurve(config->fsioTable2LoadBins, 20, 120, 10); setRpmTableBin(config->fsioTable2RpmBins, FSIO_TABLE_8); - setLinearCurve(config->fsioTable3LoadBins, FSIO_TABLE_8, 20, 120, 10); + setLinearCurve(config->fsioTable3LoadBins, 20, 120, 10); setRpmTableBin(config->fsioTable3RpmBins, FSIO_TABLE_8); - setLinearCurve(config->fsioTable4LoadBins, FSIO_TABLE_8, 20, 120, 10); + setLinearCurve(config->fsioTable4LoadBins, 20, 120, 10); setRpmTableBin(config->fsioTable4RpmBins, FSIO_TABLE_8); initEngineNoiseTable(PASS_ENGINE_PARAMETER_SIGNATURE); @@ -1103,7 +1112,7 @@ void resetConfigurationExt(Logging * logger, configuration_callback_t boardCallb #endif /* EFI_SUPPORT_FORD_FIESTA */ #if EFI_SUPPORT_NISSAN_PRIMERA case NISSAN_PRIMERA: - setNissanPrimeraEngineConfiguration(engineConfiguration); + setNissanPrimeraEngineConfiguration(PASS_CONFIG_PARAMETER_SIGNATURE); break; #endif case HONDA_ACCORD_CD: @@ -1122,6 +1131,7 @@ void resetConfigurationExt(Logging * logger, configuration_callback_t boardCallb setEtbTestConfiguration(PASS_CONFIG_PARAMETER_SIGNATURE); break; case MICRO_RUS_EFI: + case PROTEUS: // nothing to do - we do it all in setBoardConfigurationOverrides break; case TLE8888_BENCH_ENGINE: @@ -1163,7 +1173,7 @@ void resetConfigurationExt(Logging * logger, configuration_callback_t boardCallb setMazdaMiataNb1EngineConfiguration(PASS_CONFIG_PARAMETER_SIGNATURE); break; case MAZDA_323: - setMazda323EngineConfiguration(engineConfiguration); + setMazda323EngineConfiguration(PASS_CONFIG_PARAMETER_SIGNATURE); break; case MAZDA_626: setMazda626EngineConfiguration(PASS_CONFIG_PARAMETER_SIGNATURE); @@ -1286,7 +1296,7 @@ void applyNonPersistentConfiguration(Logging * logger DECLARE_ENGINE_PARAMETER_S assertEngineReference(); #if EFI_ENGINE_CONTROL - ENGINE(eInitializeTriggerShape(logger PASS_ENGINE_PARAMETER_SUFFIX)); + ENGINE(initializeTriggerWaveform(logger PASS_ENGINE_PARAMETER_SUFFIX)); #endif #if EFI_FSIO diff --git a/firmware/controllers/algo/engine_state.h b/firmware/controllers/algo/engine_state.h index aa6af6ceac..13082dacdd 100644 --- a/firmware/controllers/algo/engine_state.h +++ b/firmware/controllers/algo/engine_state.h @@ -55,6 +55,9 @@ public: angle_t mapAveragingStart[INJECTION_PIN_COUNT]; angle_t mapAveragingDuration = 0; + /** + * timing advance is angle distance before Top Dead Center (TDP), i.e. "10 degree timing advance" means "happens 10 degrees before TDC" + */ angle_t timingAdvance = 0; // fuel-related; float fuelCutoffCorrection = 0; diff --git a/firmware/controllers/algo/event_registry.cpp b/firmware/controllers/algo/event_registry.cpp index c9887a78b2..a1ca5d3a40 100644 --- a/firmware/controllers/algo/event_registry.cpp +++ b/firmware/controllers/algo/event_registry.cpp @@ -38,12 +38,3 @@ IgnitionOutputPin * IgnitionEvent::getOutputForLoggins() { return outputs[0]; } - -//void registerActuatorEventWhat(InjectionEventList *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; -//} diff --git a/firmware/controllers/algo/event_registry.h b/firmware/controllers/algo/event_registry.h index bf8640f167..78987c5607 100644 --- a/firmware/controllers/algo/event_registry.h +++ b/firmware/controllers/algo/event_registry.h @@ -28,9 +28,7 @@ public: bool isSimultanious; InjectorOutputPin *outputs[MAX_WIRES_COUNT]; int ownIndex; -#if EFI_UNIT_TEST - Engine *engine; -#endif + DECLARE_ENGINE_PTR; event_trigger_position_s injectionStart; scheduling_s signalTimerUp; @@ -69,6 +67,17 @@ private: void clear(); }; +class AngleBasedEvent { +public: + scheduling_s scheduling; + event_trigger_position_s position; + action_s action; + /** + * Trigger-based scheduler maintains a linked list of all pending tooth-based events. + */ + AngleBasedEvent *nextToothEvent = nullptr; +}; + #define MAX_OUTPUTS_FOR_IGNITION 2 class IgnitionEvent { @@ -76,22 +85,17 @@ public: IgnitionEvent(); IgnitionOutputPin *outputs[MAX_OUTPUTS_FOR_IGNITION]; scheduling_s dwellStartTimer; - scheduling_s signalTimerDown; + AngleBasedEvent sparkEvent; /** * Desired timing advance */ - angle_t advance = NAN; + angle_t sparkAngle = NAN; floatms_t sparkDwell; /** * this timestamp allows us to measure actual dwell time */ uint32_t actualStartOfDwellNt; event_trigger_position_s dwellPosition; - event_trigger_position_s sparkPosition; - /** - * Ignition scheduler maintains a linked list of all pending ignition events. - */ - IgnitionEvent *next = nullptr; /** * Sequential number of currently processed spark event * @see globalSparkIdCounter @@ -102,9 +106,7 @@ public: */ int cylinderIndex = 0; char *name = nullptr; -#if EFI_UNIT_TEST - Engine *engine; -#endif + DECLARE_ENGINE_PTR; IgnitionOutputPin *getOutputForLoggins(); }; @@ -118,3 +120,14 @@ public: IgnitionEvent elements[MAX_IGNITION_EVENT_COUNT]; bool isReady = false; }; + +class AuxActor { +public: + int phaseIndex; + int valveIndex; + angle_t extra; + + AngleBasedEvent open; + AngleBasedEvent close; + DECLARE_ENGINE_PTR; +}; diff --git a/firmware/controllers/algo/firing_order.h b/firmware/controllers/algo/firing_order.h index 70c0771ab0..9c7cbba3a9 100644 --- a/firmware/controllers/algo/firing_order.h +++ b/firmware/controllers/algo/firing_order.h @@ -1,15 +1,15 @@ /* * @file firing_order.h * + * See also FiringOrderTSLogic.java + * * @date Jul 20, 2016 - * @author Andrey Belomutskiy, (c) 2012-2017 + * @author Andrey Belomutskiy, (c) 2012-2019 */ #include "rusefi_enums.h" - -#ifndef CONTROLLERS_ALGO_FIRING_ORDER_H_ -#define CONTROLLERS_ALGO_FIRING_ORDER_H_ +#pragma once typedef enum { FO_1 = 0, @@ -53,6 +53,3 @@ typedef enum { Force_4b_firing_order = ENUM_32_BITS, } firing_order_e; - - -#endif /* CONTROLLERS_ALGO_FIRING_ORDER_H_ */ diff --git a/firmware/controllers/algo/obd_error_codes.h b/firmware/controllers/algo/obd_error_codes.h index 5c76927fab..a74417f997 100644 --- a/firmware/controllers/algo/obd_error_codes.h +++ b/firmware/controllers/algo/obd_error_codes.h @@ -1831,7 +1831,7 @@ typedef enum { CUSTOM_ERR_PIN_ALREADY_USED_2 = 6134, CUSTOM_ERR_ICU_STATE = 6135, CUSTOM_ERR_TCHARGE_NOT_READY = 6136, - CUSTOM_ERR_TRIGGER_SHAPE_TOO_LONG = 6137, + CUSTOM_ERR_TRIGGER_WAVEFORM_TOO_LONG = 6137, CUSTOM_ERR_FUEL_TABLE_NOT_READY = 6138, CUSTOM_ERR_TCHARGE_NOT_READY2 = 6139, @@ -1938,8 +1938,8 @@ typedef enum { CUSTOM_ERR_6585 = 6585, CUSTOM_ERR_6586 = 6586, CUSTOM_ERR_6587 = 6587, - CUSTOM_ERR_6588 = 6588, - CUSTOM_ERR_6589 = 6589, + CUSTOM_NULL_SHAPE = 6588, + CUSTOM_SPARK_ANGLE_1 = 6589, CUSTOM_ERR_6590 = 6590, CUSTOM_ERR_6591 = 6591, @@ -2026,14 +2026,14 @@ typedef enum { CUSTOM_ERR_6665 = 6665, CUSTOM_ERR_6666 = 6666, CUSTOM_ERR_ADCANCE_CALC_ANGLE = 6667, - CUSTOM_ERR_6668 = 6668, + CUSTOM_ERR_ETB_TARGET = 6668, CUSTOM_ERR_6669 = 6669, CUSTOM_ERR_6670 = 6670, - CUSTOM_ERR_6671 = 6671, - CUSTOM_ERR_6672 = 6672, - CUSTOM_ERR_6673 = 6673, - CUSTOM_ERR_6674 = 6674, + CUSTOM_STACK_ADC_6671 = 6671, + CUSTOM_ICU_DRIVER = 6672, + CUSTOM_ICU_DRIVER_STATE = 6673, + CUSTOM_STACK_SPI = 6674, CUSTOM_ERR_6675 = 6675, CUSTOM_ERR_6676 = 6676, CUSTOM_IH_STACK = 6677, @@ -2049,16 +2049,16 @@ typedef enum { CUSTOM_ERR_6686 = 6686, CUSTOM_ERR_6687 = 6687, CUSTOM_ERR_6688 = 6688, - CUSTOM_ERR_6689 = 6689, + CUSTOM_SPARK_ANGLE_9 = 6689, CUSTOM_ERR_MAP_START_ASSERT = 6690, CUSTOM_ERR_MAP_AVG_OFFSET = 6691, CUSTOM_ERR_MAP_CYL_OFFSET = 6692, CUSTOM_ERR_PWM_DUTY_ASSERT = 6693, CUSTOM_ERR_ZERO_CRANKING_FUEL = 6694, - CUSTOM_ERR_6695 = 6695, - CUSTOM_ERR_6696 = 6696, - CUSTOM_ERR_6697 = 6697, + CUSTOM_NULL_EXECUTOR = 6695, + CUSTOM_SLOW_NOT_INVOKED = 6696, + CUSTOM_PWM_CYCLE_START = 6697, CUSTOM_ERR_ARRAY_IS_FULL = 6698, CUSTOM_ERR_ARRAY_REMOVE_ERROR = 6699, CUSTOM_ERR_INVALID_INPUT_ICU_PIN = 6700, @@ -2069,7 +2069,7 @@ typedef enum { CUSTOM_ERR_6703 = 6703, CUSTOM_ERR_BOTH_FRONTS_REQUIRED = 6704, CUSTOM_TLE8888 = 6705, - CUSTOM_ERR_6706 = 6706, + CUSTOM_KNOCK_WINDOW = 6706, CUSTOM_ERR_TIMER_TEST_CALLBACK_NOT_HAPPENED = 6707, CUSTOM_ERR_TIMER_TEST_CALLBACK_WRONG_TIME = 6708, CUSTOM_ERR_6709 = 6709, @@ -2080,8 +2080,20 @@ typedef enum { CUSTOM_ERR_PWM_SWITCH_ASSERT = 6714, + CUSTOM_INVALID_ADC = 6720, + CUSTOM_ERR_6721 = 6721, + CUSTOM_ERR_6722 = 6722, + CUSTOM_ERR_6723 = 6723, + CUSTOM_ERR_6724 = 6724, + CUSTOM_ERR_6725 = 6725, + CUSTOM_ERR_6726 = 6726, + CUSTOM_ERR_6727 = 6727, + CUSTOM_ERR_6728 = 6728, + CUSTOM_ERR_6729 = 6729, + + CUSTOM_ERR_TRIGGER_SYNC = 9000, - CUSTOM_OBD_TRIGGER_SHAPE = 9001, + CUSTOM_OBD_TRIGGER_WAVEFORM = 9001, /** * This is not engine miss detection - this is only internal scheduler state validation * Should not happen diff --git a/firmware/controllers/algo/rusefi_enums.h b/firmware/controllers/algo/rusefi_enums.h index 8f071f8f09..8d913fa55e 100644 --- a/firmware/controllers/algo/rusefi_enums.h +++ b/firmware/controllers/algo/rusefi_enums.h @@ -103,7 +103,7 @@ typedef enum { // used by unit test // see https://github.com/rusefi/rusefi/issues/898 - // see TriggerShape::bothFrontsRequired + // see TriggerWaveform::bothFrontsRequired ISSUE_898 = 27, MAZDA_626 = 28, @@ -187,6 +187,8 @@ typedef enum { MICRO_RUS_EFI = 60, + PROTEUS = 61, + /** * this configuration has as few pins configured as possible */ @@ -719,6 +721,7 @@ typedef enum { SC_MAP = 2, SC_RPM_ACCEL = 3, SC_DETAILED_RPM = 4, + SC_AUX_FAST1 = 5, Internal_ForceMyEnumIntSize_sensor_chart = ENUM_32_BITS, } sensor_chart_e; diff --git a/firmware/controllers/algo/rusefi_types.h b/firmware/controllers/algo/rusefi_types.h index 0bb964ff28..41c23f8693 100644 --- a/firmware/controllers/algo/rusefi_types.h +++ b/firmware/controllers/algo/rusefi_types.h @@ -4,8 +4,8 @@ * @date Jan 12, 2015 * @author Andrey Belomutskiy, (c) 2012-2017 */ -#ifndef CONTROLLERS_ALGO_RUSEFI_TYPES_H_ -#define CONTROLLERS_ALGO_RUSEFI_TYPES_H_ + +#pragma once #include #include @@ -90,7 +90,6 @@ typedef uint8_t iac_pid_mult_t[IAC_PID_MULT_SIZE][IAC_PID_MULT_SIZE]; typedef float baro_corr_table_t[BARO_CORR_SIZE][BARO_CORR_SIZE]; typedef float fsio_table_8x8_f32t[FSIO_TABLE_8][FSIO_TABLE_8]; -typedef uint8_t fsio_table_8x8_u8t[FSIO_TABLE_8][FSIO_TABLE_8]; typedef float tps_tps_table_t[TPS_TPS_ACCEL_TABLE][TPS_TPS_ACCEL_TABLE]; typedef uint8_t fsio_table_8x8_u8t[FSIO_TABLE_8][FSIO_TABLE_8]; @@ -131,5 +130,3 @@ typedef void (*VoidCharPtrCharPtrVoidPtr)(const char *, const char *, void*); typedef void (*VoidCharPtrCharPtrCharPtr)(const char *, const char *, const char *); typedef void (*VoidCharPtrCharPtrCharPtrCharPtrCharPtr)(const char *, const char *, const char *, const char *, const char *); - -#endif /* CONTROLLERS_ALGO_RUSEFI_TYPES_H_ */ diff --git a/firmware/controllers/controllers.mk b/firmware/controllers/controllers.mk index 8a3c4688b4..56783f376a 100644 --- a/firmware/controllers/controllers.mk +++ b/firmware/controllers/controllers.mk @@ -1,3 +1,11 @@ +include $(PROJECT_DIR)/controllers/algo/algo.mk +include $(PROJECT_DIR)/controllers/core/core.mk +include $(PROJECT_DIR)/controllers/math/math.mk +include $(PROJECT_DIR)/controllers/trigger/trigger.mk +include $(PROJECT_DIR)/controllers/sensors/sensors.mk +include $(PROJECT_DIR)/controllers/system/system.mk +#include $(PROJECT_DIR)/controllers/gauges/gauges.mk + CONTROLLERS_DIR=$(PROJECT_DIR)/controllers CONTROLLERSSRC = @@ -5,34 +13,42 @@ CONTROLLERSSRC = CONTROLLERS_SRC_CPP = \ $(CONTROLLERS_DIR)/actuators/electronic_throttle.cpp \ $(CONTROLLERS_DIR)/actuators/alternator_controller.cpp \ - $(CONTROLLERS_DIR)/actuators/malfunction_indicator.cpp \ - $(CONTROLLERS_DIR)/actuators/tachometer.cpp \ $(CONTROLLERS_DIR)/actuators/idle_thread.cpp \ $(CONTROLLERS_DIR)/actuators/pwm_tester.cpp \ $(CONTROLLERS_DIR)/actuators/algo/aux_pid.cpp \ - $(CONTROLLERS_DIR)/actuators/lcd_controller.cpp \ - $(CONTROLLERS_DIR)/scheduling/signal_executor_sleep.cpp \ - $(CONTROLLERS_DIR)/scheduling/single_timer_executor.cpp \ - $(CONTROLLERS_DIR)/scheduling/pwm_generator_logic.cpp \ - $(CONTROLLERS_DIR)/scheduling/event_queue.cpp \ - $(PROJECT_DIR)/controllers/settings.cpp \ - $(PROJECT_DIR)/controllers/core/error_handling.cpp \ - $(PROJECT_DIR)/controllers/map_averaging.cpp \ - $(PROJECT_DIR)/controllers/flash_main.cpp \ - $(PROJECT_DIR)/controllers/injector_central.cpp \ - $(PROJECT_DIR)/controllers/obd2.cpp \ - $(PROJECT_DIR)/controllers/engine_controller.cpp \ - $(PROJECT_DIR)/controllers/persistent_store.cpp \ + $(CONTROLLERS_DIR)/gauges/tachometer.cpp \ + $(CONTROLLERS_DIR)/gauges/malfunction_indicator.cpp \ + $(CONTROLLERS_DIR)/gauges/lcd_controller.cpp \ + $(CONTROLLERS_DIR)/system/timer/signal_executor_sleep.cpp \ + $(CONTROLLERS_DIR)/system/timer/single_timer_executor.cpp \ + $(CONTROLLERS_DIR)/system/timer/pwm_generator_logic.cpp \ + $(CONTROLLERS_DIR)/system/timer/event_queue.cpp \ + $(CONTROLLERS_DIR)/settings.cpp \ + $(CONTROLLERS_DIR)/core/error_handling.cpp \ + $(CONTROLLERS_DIR)/engine_cycle/map_averaging.cpp \ + $(CONTROLLERS_DIR)/engine_cycle/rpm_calculator.cpp \ + $(CONTROLLERS_DIR)/engine_cycle/spark_logic.cpp \ + $(CONTROLLERS_DIR)/engine_cycle/main_trigger_callback.cpp \ + $(CONTROLLERS_DIR)/engine_cycle/aux_valves.cpp \ + $(CONTROLLERS_DIR)/flash_main.cpp \ + $(CONTROLLERS_DIR)/injector_central.cpp \ + $(CONTROLLERS_DIR)/obd2.cpp \ + $(CONTROLLERS_DIR)/engine_controller.cpp \ + $(CONTROLLERS_DIR)/persistent_store.cpp \ CONTROLLERS_INC=\ $(CONTROLLERS_DIR) \ - $(CONTROLLERS_DIR)/scheduling \ $(CONTROLLERS_DIR)/system \ + $(CONTROLLERS_DIR)/system/timer \ $(CONTROLLERS_DIR)/algo \ + $(CONTROLLERS_DIR)/engine_cycle \ $(CONTROLLERS_DIR)/trigger/decoders \ $(CONTROLLERS_DIR)/trigger \ + $(CONTROLLERS_DIR)/sensors \ + $(CONTROLLERS_DIR)/sensors/converters \ $(CONTROLLERS_DIR)/core \ + $(CONTROLLERS_DIR)/gauges \ $(CONTROLLERS_DIR)/math \ $(CONTROLLERS_DIR)/generated \ $(CONTROLLERS_DIR)/actuators \ diff --git a/firmware/controllers/core/common_headers.h b/firmware/controllers/core/common_headers.h index aa1b846cb0..aa0056ac64 100644 --- a/firmware/controllers/core/common_headers.h +++ b/firmware/controllers/core/common_headers.h @@ -72,17 +72,28 @@ board_configuration_s *boardConfiguration = nullptr; -#define INJECT_ENGINE_REFERENCE(x) \ - x.engine = engine; \ - x.engineConfiguration = engineConfiguration; \ - x.config = config; \ - x.boardConfiguration = boardConfiguration; +#define INJECT_ENGINE_REFERENCE(x) \ + (x)->engine = engine; \ + (x)->engineConfiguration = engineConfiguration; \ + (x)->config = config; \ + (x)->boardConfiguration = boardConfiguration; #define EXPAND_Engine \ engine_configuration_s *engineConfiguration = engine->engineConfigurationPtr; \ persistent_config_s *config = engine->config; \ board_configuration_s *boardConfiguration = &engineConfiguration->bc; +#ifndef EFI_ACTIVE_CONFIGURATION_IN_FLASH +// We store a special changeable copy of configuration is RAM, so we can just compare them #define isConfigurationChanged(x) (engineConfiguration->x != activeConfiguration.x) +#else +// We cannot call prepareVoidConfiguration() for activeConfiguration if it's stored in flash, +// so we need to tell the firmware that it's "void" (i.e. zeroed, invalid) by setting a special flag variable, +// and then we consider 'x' as changed if it's just non-zero. +extern bool isActiveConfigurationVoid; +#define isConfigurationChanged(x) ((engineConfiguration->x != activeConfiguration.x) || (isActiveConfigurationVoid && engineConfiguration->x != 0)) +#endif /* EFI_ACTIVE_CONFIGURATION_IN_FLASH */ + +#define isPinOrModeChanged(pin, mode) (isConfigurationChanged(pin) || isConfigurationChanged(mode)) #endif /* CONTROLLERS_CORE_COMMON_HEADERS_H_ */ diff --git a/firmware/controllers/core/core.mk b/firmware/controllers/core/core.mk index 1d3a00902c..e80f249eb7 100644 --- a/firmware/controllers/core/core.mk +++ b/firmware/controllers/core/core.mk @@ -1,6 +1,6 @@ CONTROLLERS_CORE_SRC_CPP = \ - $(PROJECT_DIR)/controllers/core/efi_wave.cpp \ + $(PROJECT_DIR)/controllers/core/state_sequence.cpp \ $(PROJECT_DIR)/controllers/core/fsio_core.cpp \ $(PROJECT_DIR)/controllers/core/fsio_impl.cpp \ diff --git a/firmware/controllers/core/error_handling.cpp b/firmware/controllers/core/error_handling.cpp index 9cf415bfd4..75feeea2b1 100644 --- a/firmware/controllers/core/error_handling.cpp +++ b/firmware/controllers/core/error_handling.cpp @@ -92,7 +92,10 @@ void chDbgPanic3(const char *msg, const char * file, int line) { static void printToStream(MemoryStream *stream, const char *fmt, va_list ap) { stream->eos = 0; // reset chvprintf((BaseSequentialStream *) stream, fmt, ap); - stream->buffer[stream->eos] = 0; + + // Terminate, but don't write past the end of the buffer + int terminatorLocation = minI(stream->eos, stream->size - 1); + stream->buffer[terminatorLocation] = '\0'; } static void printWarning(const char *fmt, va_list ap) { diff --git a/firmware/controllers/core/fsio_impl.cpp b/firmware/controllers/core/fsio_impl.cpp index d651b152dc..8b358f3a9c 100644 --- a/firmware/controllers/core/fsio_impl.cpp +++ b/firmware/controllers/core/fsio_impl.cpp @@ -12,13 +12,13 @@ */ #include "global.h" +#include "fsio_impl.h" +#include "allsensors.h" #if EFI_FSIO #include "os_access.h" -#include "fsio_impl.h" #include "settings.h" -#include "allsensors.h" #include "rpm_calculator.h" #include "efi_gpio.h" #include "pwm_generator_logic.h" @@ -102,6 +102,7 @@ static LEElement * acRelayLogic; static LEElement * fuelPumpLogic; static LEElement * radiatorFanLogic; static LEElement * alternatorLogic; +static LEElement * starterRelayLogic; #if EFI_MAIN_RELAY_CONTROL static LEElement * mainRelayLogic; @@ -194,7 +195,7 @@ static void setFsioDigitalInputPin(const char *indexStr, const char *pinName) { scheduleMsg(logger, "invalid pin name [%s]", pinName); return; } - CONFIGB(fsioDigitalInputs)[index] = pin; + CONFIG(fsioDigitalInputs)[index] = pin; scheduleMsg(logger, "FSIO digital input pin #%d [%s]", (index + 1), hwPortname(pin)); } @@ -464,6 +465,9 @@ void runFsio(DECLARE_ENGINE_PARAMETER_SIGNATURE) { enginePins.mainRelay.setValue(true); #endif /* EFI_MAIN_RELAY_CONTROL */ + if (CONFIGB(starterRelayPin) != GPIO_UNASSIGNED) + setPinState("starter_relay", &enginePins.starterRelay, starterRelayLogic PASS_ENGINE_PARAMETER_SUFFIX); + /** * o2 heater is off during cranking * todo: convert to FSIO? @@ -582,7 +586,7 @@ static void showFsioInfo(void) { } } for (int i = 0; i < FSIO_COMMAND_COUNT; i++) { - brain_pin_e inputPin = CONFIGB(fsioDigitalInputs)[i]; + brain_pin_e inputPin = CONFIG(fsioDigitalInputs)[i]; if (inputPin != GPIO_UNASSIGNED) { scheduleMsg(logger, "FSIO digital input #%d: %s", i, hwPortname(inputPin)); } @@ -673,6 +677,8 @@ void initFsioImpl(Logging *sharedLogger DECLARE_ENGINE_PARAMETER_SUFFIX) { if (CONFIGB(mainRelayPin) != GPIO_UNASSIGNED) mainRelayLogic = sysPool.parseExpression(MAIN_RELAY_LOGIC); #endif /* EFI_MAIN_RELAY_CONTROL */ + if (CONFIGB(starterRelayPin) != GPIO_UNASSIGNED) + starterRelayLogic = sysPool.parseExpression(STARTER_RELAY_LOGIC); #if EFI_PROD_CODE for (int i = 0; i < FSIO_COMMAND_COUNT; i++) { @@ -691,7 +697,7 @@ void initFsioImpl(Logging *sharedLogger DECLARE_ENGINE_PARAMETER_SUFFIX) { } for (int i = 0; i < FSIO_COMMAND_COUNT; i++) { - brain_pin_e inputPin = CONFIGB(fsioDigitalInputs)[i]; + brain_pin_e inputPin = CONFIG(fsioDigitalInputs)[i]; if (inputPin != GPIO_UNASSIGNED) { efiSetPadMode("FSIO input", inputPin, getInputMode(engineConfiguration->fsioInputModes[i])); @@ -724,5 +730,37 @@ void initFsioImpl(Logging *sharedLogger DECLARE_ENGINE_PARAMETER_SUFFIX) { } +#else /* !EFI_FSIO */ + +EXTERN_ENGINE +; +extern EnginePins enginePins; + +// "Limp-mode" implementation for some RAM-limited configs without FSIO +void runHardcodedFsio(DECLARE_ENGINE_PARAMETER_SIGNATURE) { + // see MAIN_RELAY_LOGIC + if (CONFIGB(mainRelayPin) != GPIO_UNASSIGNED) { + enginePins.mainRelay.setValue((getTimeNowSeconds() < 2) || (getVBatt(PASS_ENGINE_PARAMETER_SIGNATURE) > 5) || engine->isInShutdownMode()); + } + // see STARTER_RELAY_LOGIC + if (CONFIGB(starterRelayPin) != GPIO_UNASSIGNED) { + enginePins.starterRelay.setValue(engine->rpmCalculator.getRpm() < engineConfiguration->cranking.rpm); + } + // see FAN_CONTROL_LOGIC + if (CONFIGB(fanPin) != GPIO_UNASSIGNED) { + enginePins.fanRelay.setValue((enginePins.fanRelay.getLogicValue() && (getCoolantTemperature() > engineConfiguration->fanOffTemperature)) || + (getCoolantTemperature() > engineConfiguration->fanOnTemperature) || engine->isCltBroken); + } + // see AC_RELAY_LOGIC + if (CONFIGB(acRelayPin) != GPIO_UNASSIGNED) { + enginePins.acRelay.setValue(getAcToggle(PASS_ENGINE_PARAMETER_SIGNATURE) && engine->rpmCalculator.getRpm() > 850); + } + // see FUEL_PUMP_LOGIC + if (CONFIGB(fuelPumpPin) != GPIO_UNASSIGNED) { + enginePins.fuelPumpRelay.setValue((getTimeNowSeconds() < engineConfiguration->startUpFuelPumpDuration) || (engine->rpmCalculator.getRpm() > 0)); + } + + enginePins.o2heater.setValue(engine->rpmCalculator.isRunning(PASS_ENGINE_PARAMETER_SIGNATURE)); +} #endif /* EFI_FSIO */ diff --git a/firmware/controllers/core/fsio_impl.h b/firmware/controllers/core/fsio_impl.h index f9f728dadc..37fd5d3153 100644 --- a/firmware/controllers/core/fsio_impl.h +++ b/firmware/controllers/core/fsio_impl.h @@ -39,6 +39,7 @@ void setFsioExpression(const char *indexStr, const char *quotedLine DECLARE_ENGI float getFsioOutputValue(int index DECLARE_ENGINE_PARAMETER_SUFFIX); void applyFsioConfiguration(DECLARE_ENGINE_PARAMETER_SIGNATURE); void onConfigurationChangeFsioCallback(engine_configuration_s *previousConfiguration DECLARE_ENGINE_PARAMETER_SUFFIX); +void runHardcodedFsio(DECLARE_ENGINE_PARAMETER_SIGNATURE); ValueProvider3D *getFSIOTable(int index); diff --git a/firmware/controllers/core/efi_wave.cpp b/firmware/controllers/core/state_sequence.cpp similarity index 56% rename from firmware/controllers/core/efi_wave.cpp rename to firmware/controllers/core/state_sequence.cpp index 037402ff22..bb67dc25bd 100644 --- a/firmware/controllers/core/efi_wave.cpp +++ b/firmware/controllers/core/state_sequence.cpp @@ -1,59 +1,59 @@ /** - * @file EfiWave.cpp + * @file state_sequence.cpp * * @date May 18, 2014 * @author Andrey Belomutskiy, (c) 2012-2018 */ #include "global.h" -#include "efi_wave.h" +#include "state_sequence.h" #include "trigger_structure.h" -SingleWave::SingleWave() { +SingleChannelStateSequence::SingleChannelStateSequence() { init(NULL); } -SingleWave::SingleWave(pin_state_t *ps) { +SingleChannelStateSequence::SingleChannelStateSequence(pin_state_t *ps) { init(ps); } -void SingleWave::init(pin_state_t *pinStates) { +void SingleChannelStateSequence::init(pin_state_t *pinStates) { this->pinStates = pinStates; } -pin_state_t SingleWave::getState(int switchIndex) const { +pin_state_t SingleChannelStateSequence::getState(int switchIndex) const { pin_state_t state = pinStates[switchIndex]; efiAssert(OBD_PCM_Processor_Fault, state == 0 || state == 1, "wave state get", TV_FALL); return state; } -void SingleWave::setState(int switchIndex, pin_state_t state) { +void SingleChannelStateSequence::setState(int switchIndex, pin_state_t state) { efiAssertVoid(OBD_PCM_Processor_Fault, state == 0 || state == 1, "wave state set"); pinStates[switchIndex] = state; } -MultiWave::MultiWave() { +MultiChannelStateSequence::MultiChannelStateSequence() { reset(); } -MultiWave::MultiWave(float *switchTimes, SingleWave *waves) : MultiWave() { +MultiChannelStateSequence::MultiChannelStateSequence(float *switchTimes, SingleChannelStateSequence *waves) : MultiChannelStateSequence() { init(switchTimes, waves); } -void MultiWave::init(float *switchTimes, SingleWave *channels) { +void MultiChannelStateSequence::init(float *switchTimes, SingleChannelStateSequence *channels) { this->switchTimes = switchTimes; this->channels = channels; } -void MultiWave::reset(void) { +void MultiChannelStateSequence::reset(void) { waveCount = 0; } -float MultiWave::getSwitchTime(const int index) const { +float MultiChannelStateSequence::getSwitchTime(const int index) const { return switchTimes[index]; } -void MultiWave::checkSwitchTimes(const int size) { +void MultiChannelStateSequence::checkSwitchTimes(const int size) { if (switchTimes[size - 1] != 1) { firmwareError(CUSTOM_ERR_WAVE_1, "last switch time has to be 1 not %.2f", switchTimes[size - 1]); return; @@ -65,7 +65,7 @@ void MultiWave::checkSwitchTimes(const int size) { } } -pin_state_t MultiWave::getChannelState(const int channelIndex, const int phaseIndex) const { +pin_state_t MultiChannelStateSequence::getChannelState(const int channelIndex, const int phaseIndex) const { if (channelIndex >= waveCount) { // todo: would be nice to get this asserting working //firmwareError(OBD_PCM_Processor_Fault, "channel index %d/%d", channelIndex, waveCount); @@ -76,7 +76,7 @@ pin_state_t MultiWave::getChannelState(const int channelIndex, const int phaseIn /** * returns the index at which given value would need to be inserted into sorted array */ -int MultiWave::findInsertionAngle(const float angle, const int size) const { +int MultiChannelStateSequence::findInsertionAngle(const float angle, const int size) const { for (int i = size - 1; i >= 0; i--) { if (angle > switchTimes[i]) return i + 1; @@ -84,7 +84,7 @@ int MultiWave::findInsertionAngle(const float angle, const int size) const { return 0; } -int MultiWave::findAngleMatch(const float angle, const int size) const { +int MultiChannelStateSequence::findAngleMatch(const float angle, const int size) const { for (int i = 0; i < size; i++) { if (isSameF(switchTimes[i], angle)) return i; @@ -92,7 +92,7 @@ int MultiWave::findAngleMatch(const float angle, const int size) const { return EFI_ERROR_CODE; } -void MultiWave::setSwitchTime(const int index, const float value) { +void MultiChannelStateSequence::setSwitchTime(const int index, const float value) { efiAssertVoid(CUSTOM_ERR_PWM_SWITCH_ASSERT, switchTimes != NULL, "switchTimes"); switchTimes[index] = value; } diff --git a/firmware/controllers/core/efi_wave.h b/firmware/controllers/core/state_sequence.h similarity index 80% rename from firmware/controllers/core/efi_wave.h rename to firmware/controllers/core/state_sequence.h index 55d055a2ab..b549d9affc 100644 --- a/firmware/controllers/core/efi_wave.h +++ b/firmware/controllers/core/state_sequence.h @@ -1,11 +1,11 @@ /** - * @file efi_wave.h + * @file state_sequence.h * * @date May 18, 2014 - * @author Andrey Belomutskiy, (c) 2012-2017 + * @author Andrey Belomutskiy, (c) 2012-2019 */ -#ifndef EFI_WAVE_H_ -#define EFI_WAVE_H_ + +#pragma once #include "global.h" @@ -36,13 +36,14 @@ typedef trigger_value_e pin_state_t; * is not implemented using a bit array, it could absolutely be a bit array * * This sequence does not know anything about signal lengths - only signal state at a given index + * This sequence can have consecutive zeros and ones since these sequences work as a group within MultiChannelStateSequence * * @brief PWM configuration for the specific output pin */ -class SingleWave { +class SingleChannelStateSequence { public: - SingleWave(); - explicit SingleWave(pin_state_t *pinStates); + SingleChannelStateSequence(); + explicit SingleChannelStateSequence(pin_state_t *pinStates); void init(pin_state_t *pinStates); /** * todo: confirm that we only deal with two states here, no magic '-1'? @@ -59,11 +60,11 @@ public: * This class represents multi-channel logical signals with shared time axis * */ -class MultiWave { +class MultiChannelStateSequence { public: - MultiWave(); - MultiWave(float *switchTimes, SingleWave *waves); - void init(float *switchTimes, SingleWave *waves); + MultiChannelStateSequence(); + MultiChannelStateSequence(float *switchTimes, SingleChannelStateSequence *waves); + void init(float *switchTimes, SingleChannelStateSequence *waves); void reset(void); float getSwitchTime(const int phaseIndex) const; void setSwitchTime(const int phaseIndex, const float value); @@ -77,7 +78,7 @@ public: * Number of signal channels */ int waveCount; - SingleWave *channels = nullptr; + SingleChannelStateSequence *channels = nullptr; //private: /** * values in the (0..1] range which refer to points within the period at at which pin state should be changed @@ -86,4 +87,4 @@ public: float *switchTimes = nullptr; }; -#endif /* EFI_WAVE_H_ */ + diff --git a/firmware/controllers/engine_controller.cpp b/firmware/controllers/engine_controller.cpp index 778fb15646..202abfe541 100644 --- a/firmware/controllers/engine_controller.cpp +++ b/firmware/controllers/engine_controller.cpp @@ -42,8 +42,8 @@ #include "injector_central.h" #include "os_util.h" #include "engine_math.h" -#if EFI_WAVE_ANALYZER -#include "wave_analyzer.h" +#if EFI_LOGIC_ANALYZER +#include "logic_analyzer.h" #endif #include "allsensors.h" #include "electronic_throttle.h" @@ -207,6 +207,7 @@ static Overflow64Counter halTime; */ //todo: macro to save method invocation efitimeus_t getTimeNowUs(void) { + ScopePerf perf(PE::ScheduleByAngle); return getTimeNowNt() / (CORE_CLOCK / 1000000); } @@ -703,11 +704,11 @@ void initEngineContoller(Logging *sharedLogger DECLARE_ENGINE_PARAMETER_SUFFIX) initAlgo(sharedLogger); -#if EFI_WAVE_ANALYZER +#if EFI_LOGIC_ANALYZER if (engineConfiguration->isWaveAnalyzerEnabled) { initWaveAnalyzer(sharedLogger); } -#endif /* EFI_WAVE_ANALYZER */ +#endif /* EFI_LOGIC_ANALYZER */ #if EFI_CJ125 /** @@ -797,7 +798,7 @@ void initEngineContoller(Logging *sharedLogger DECLARE_ENGINE_PARAMETER_SUFFIX) // help to notice when RAM usage goes up - if a code change adds to RAM usage these variables would fail // linking process which is the way to raise the alarm #ifndef RAM_UNUSED_SIZE -#define RAM_UNUSED_SIZE 3000 +#define RAM_UNUSED_SIZE 2500 #endif #ifndef CCM_UNUSED_SIZE #define CCM_UNUSED_SIZE 4600 @@ -818,6 +819,6 @@ int getRusEfiVersion(void) { if (initBootloader() != 0) return 123; #endif /* EFI_BOOTLOADER_INCLUDE_CODE */ - return 20191117; + return 20191206; } #endif /* EFI_UNIT_TEST */ diff --git a/firmware/controllers/engine_cycle/aux_valves.cpp b/firmware/controllers/engine_cycle/aux_valves.cpp new file mode 100644 index 0000000000..9634e341e3 --- /dev/null +++ b/firmware/controllers/engine_cycle/aux_valves.cpp @@ -0,0 +1,189 @@ +/* + * aux_valves.cpp + * + * + * Here we have two auxilary digital on/off outputs which would open once per each 360 degrees of engine crank revolution. + * The second valve is 180 degrees after the first one. + * + * Valve open and close angles are taken from fsioCurve1 and fsioCurve2 tables respectively, the position depend on TPS input. + * + * https://github.com/rusefi/rusefi/issues/490 + * + * @date Nov 25, 2017 + * @author Andrey Belomutskiy, (c) 2012-2019 + */ + +#include "engine_math.h" +#include "aux_valves.h" +#include "allsensors.h" +#include "trigger_central.h" +#include "spark_logic.h" + +EXTERN_ENGINE +; + +void plainPinTurnOn(AuxActor *current) { + NamedOutputPin *output = &enginePins.auxValve[current->valveIndex]; + output->setHigh(); + +#if EFI_UNIT_TEST + Engine *engine = current->engine; + EXPAND_Engine; +#endif /* EFI_UNIT_TEST */ + + scheduleOrQueue(¤t->open, + TRIGGER_EVENT_UNDEFINED, + current->extra + engine->engineState.auxValveStart, + (schfunc_t)plainPinTurnOn, + current + PASS_ENGINE_PARAMETER_SUFFIX + ); + + angle_t duration = engine->engineState.auxValveEnd - engine->engineState.auxValveStart; + + fixAngle(duration, "duration", CUSTOM_ERR_6557); + + scheduleOrQueue(¤t->close, + TRIGGER_EVENT_UNDEFINED, + current->extra + engine->engineState.auxValveEnd, + (schfunc_t)plainPinTurnOff, + output + PASS_ENGINE_PARAMETER_SUFFIX + ); + } + +void plainPinTurnOff(NamedOutputPin *output) { + output->setLow(); +} + +/* +static void auxValveTriggerCallback(trigger_event_e ckpSignalType, + uint32_t index DECLARE_ENGINE_PARAMETER_SUFFIX) { + UNUSED(ckpSignalType); + + if (index != engine->auxSchedulingIndex) { + return; + } + int rpm = GET_RPM_VALUE; + if (!isValidRpm(rpm)) { + return; + } +*/ + /** + * Sometimes previous event has not yet been executed by the time we are scheduling new events. + * We use this array alternation in order to bring events that are scheled and waiting to be executed from + * events which are already being scheduled + */ +/* + int engineCycleAlternation = engine->triggerCentral.triggerState.getTotalRevolutionCounter() % CYCLE_ALTERNATION; + + for (int valveIndex = 0; valveIndex < AUX_DIGITAL_VALVE_COUNT; valveIndex++) { + + NamedOutputPin *output = &enginePins.auxValve[valveIndex]; + + for (int phaseIndex = 0; phaseIndex < 2; phaseIndex++) { +*/ +/* I believe a more correct implementation is the following: + * here we properly account for trigger angle position in engine cycle coordinates + // todo: at the moment this logic is assuming four-stroke 720-degree engine cycle + angle_t extra = phaseIndex * 360 // cycle opens twice per 720 engine cycle + + valveIndex * 180 // 2nd valve is operating at 180 offset to first + + tdcPosition() // engine cycle position to trigger cycle position conversion + - ENGINE(triggerCentral.triggerShape.eventAngles[SCHEDULING_TRIGGER_INDEX]) + ; +*/ +/* + angle_t extra = phaseIndex * 360 + valveIndex * 180; + angle_t onTime = extra + engine->engineState.auxValveStart; + scheduling_s *onEvent = &engine->auxTurnOnEvent[valveIndex][phaseIndex][engineCycleAlternation]; + scheduling_s *offEvent = &engine->auxTurnOffEvent[valveIndex][phaseIndex][engineCycleAlternation]; + bool isOverlap = onEvent->isScheduled || offEvent->isScheduled; + if (isOverlap) { + enginePins.debugTriggerSync.setValue(1); + } + + fixAngle(onTime, "onTime", CUSTOM_ERR_6556); + scheduleByAngle(onEvent, + onTime, + (schfunc_t) &plainPinTurnOn, output PASS_ENGINE_PARAMETER_SUFFIX); + angle_t offTime = extra + engine->engineState.auxValveEnd; + fixAngle(offTime, "offTime", CUSTOM_ERR_6557); + scheduleByAngle(offEvent, + offTime, + (schfunc_t) &plainPinTurnOff, output PASS_ENGINE_PARAMETER_SUFFIX); + if (isOverlap) { + enginePins.debugTriggerSync.setValue(0); + } + } + } +} +*/ + +void initAuxValves(Logging *sharedLogger DECLARE_ENGINE_PARAMETER_SUFFIX) { + UNUSED(sharedLogger); + if (engineConfiguration->auxValves[0] == GPIO_UNASSIGNED) { + return; + } + +#if !EFI_UNIT_TEST + // let's give it time to grab TPS value + chThdSleepMilliseconds(50); +#endif /* EFI_UNIT_TESTS */ + + float tps = getTPS(PASS_ENGINE_PARAMETER_SIGNATURE); + if (cisnan(tps)) { + firmwareError(CUSTOM_OBD_91, "No TPS for Aux Valves"); + return; + } + + updateAuxValves(PASS_ENGINE_PARAMETER_SIGNATURE); + + for (int valveIndex = 0; valveIndex < AUX_DIGITAL_VALVE_COUNT; valveIndex++) { + + for (int phaseIndex = 0; phaseIndex < 2; phaseIndex++) { + AuxActor *actor = &engine->auxValves[valveIndex][phaseIndex]; + actor->phaseIndex = phaseIndex; + actor->valveIndex = valveIndex; + actor->extra = phaseIndex * 360 + valveIndex * 180; + + INJECT_ENGINE_REFERENCE(actor); + + scheduleOrQueue(&actor->open, + TRIGGER_EVENT_UNDEFINED, + actor->extra + engine->engineState.auxValveStart, + (schfunc_t)plainPinTurnOn, + actor + PASS_ENGINE_PARAMETER_SUFFIX + ); + } + } + + +// addTriggerEventListener(auxValveTriggerCallback, "AuxV", engine); +} + +void updateAuxValves(DECLARE_ENGINE_PARAMETER_SIGNATURE) { + if (engineConfiguration->auxValves[0] == GPIO_UNASSIGNED) { + return; + } + + float tps = getTPS(PASS_ENGINE_PARAMETER_SIGNATURE); + if (cisnan(tps)) { + // error should be already reported by now + return; + } + engine->engineState.auxValveStart = interpolate2d("aux", tps, + engineConfiguration->fsioCurve1Bins, + engineConfiguration->fsioCurve1); + + engine->engineState.auxValveEnd = interpolate2d("aux", tps, + engineConfiguration->fsioCurve2Bins, + engineConfiguration->fsioCurve2); + + if (engine->engineState.auxValveStart >= engine->engineState.auxValveEnd) { + // this is a fatal error to make this really visible + firmwareError(CUSTOM_AUX_OUT_OF_ORDER, "out of order at %.2f %.2f %.2f", tps, + engine->engineState.auxValveStart, + engine->engineState.auxValveEnd); + } +} diff --git a/firmware/controllers/engine_cycle/aux_valves.h b/firmware/controllers/engine_cycle/aux_valves.h new file mode 100644 index 0000000000..3f28d16e8f --- /dev/null +++ b/firmware/controllers/engine_cycle/aux_valves.h @@ -0,0 +1,15 @@ +/* + * @file aux_valves.h + * + * @date Nov 25, 2017 + * @author Andrey Belomutskiy, (c) 2012-2019 + */ + +#pragma once + +#include "engine.h" + +void initAuxValves(Logging *sharedLogger DECLARE_ENGINE_PARAMETER_SUFFIX); +void updateAuxValves(DECLARE_ENGINE_PARAMETER_SIGNATURE); +void plainPinTurnOn(AuxActor *current); +void plainPinTurnOff(NamedOutputPin *output); diff --git a/firmware/controllers/trigger/main_trigger_callback.cpp b/firmware/controllers/engine_cycle/main_trigger_callback.cpp similarity index 99% rename from firmware/controllers/trigger/main_trigger_callback.cpp rename to firmware/controllers/engine_cycle/main_trigger_callback.cpp index 6bac5d4551..647a3ee6c1 100644 --- a/firmware/controllers/trigger/main_trigger_callback.cpp +++ b/firmware/controllers/engine_cycle/main_trigger_callback.cpp @@ -494,10 +494,10 @@ void mainTriggerCallback(trigger_event_e ckpSignalType, uint32_t trgEventIndex D } if (checkIfTriggerConfigChanged(PASS_ENGINE_PARAMETER_SIGNATURE)) { - engine->ignitionEvents.isReady = false; // we need to rebuild ignition schedule + engine->ignitionEvents.isReady = false; // we need to rebuild complete ignition schedule engine->injectionEvents.isReady = false; // moved 'triggerIndexByAngle' into trigger initialization (why was it invoked from here if it's only about trigger shape & optimization?) - // see initializeTriggerShape() -> prepareOutputSignals(PASS_ENGINE_PARAMETER_SIGNATURE) + // see initializeTriggerWaveform() -> prepareOutputSignals(PASS_ENGINE_PARAMETER_SIGNATURE) // we need this to apply new 'triggerIndexByAngle' values engine->periodicFastCallback(PASS_ENGINE_PARAMETER_SIGNATURE); diff --git a/firmware/controllers/trigger/main_trigger_callback.h b/firmware/controllers/engine_cycle/main_trigger_callback.h similarity index 100% rename from firmware/controllers/trigger/main_trigger_callback.h rename to firmware/controllers/engine_cycle/main_trigger_callback.h diff --git a/firmware/controllers/map_averaging.cpp b/firmware/controllers/engine_cycle/map_averaging.cpp similarity index 98% rename from firmware/controllers/map_averaging.cpp rename to firmware/controllers/engine_cycle/map_averaging.cpp index 90caf93845..070408753a 100644 --- a/firmware/controllers/map_averaging.cpp +++ b/firmware/controllers/engine_cycle/map_averaging.cpp @@ -236,7 +236,7 @@ void refreshMapAveragingPreCalc(DECLARE_ENGINE_PARAMETER_SIGNATURE) { angle_t start = interpolate2d("mapa", rpm, c->samplingAngleBins, c->samplingAngle); efiAssertVoid(CUSTOM_ERR_MAP_START_ASSERT, !cisnan(start), "start"); - angle_t offsetAngle = TRIGGER_SHAPE(eventAngles[CONFIG(mapAveragingSchedulingAtIndex)]); + angle_t offsetAngle = TRIGGER_WAVEFORM(eventAngles[CONFIG(mapAveragingSchedulingAtIndex)]); efiAssertVoid(CUSTOM_ERR_MAP_AVG_OFFSET, !cisnan(offsetAngle), "offsetAngle"); for (int i = 0; i < engineConfiguration->specs.cylindersCount; i++) { @@ -313,9 +313,9 @@ static void mapAveragingTriggerCallback(trigger_event_e ckpEventType, // at the moment we schedule based on time prediction based on current RPM and angle // we are loosing precision in case of changing RPM - the further away is the event the worse is precision // todo: schedule this based on closest trigger event, same as ignition works - scheduleByAngle(rpm, &startTimer[i][structIndex], samplingStart, + scheduleByAngle(&startTimer[i][structIndex], samplingStart, startAveraging, NULL PASS_ENGINE_PARAMETER_SUFFIX); - scheduleByAngle(rpm, &endTimer[i][structIndex], samplingEnd, + scheduleByAngle(&endTimer[i][structIndex], samplingEnd, endAveraging, NULL PASS_ENGINE_PARAMETER_SUFFIX); engine->m.mapAveragingCbTime = getTimeNowLowerNt() - engine->m.beforeMapAveragingCb; diff --git a/firmware/controllers/map_averaging.h b/firmware/controllers/engine_cycle/map_averaging.h similarity index 100% rename from firmware/controllers/map_averaging.h rename to firmware/controllers/engine_cycle/map_averaging.h diff --git a/firmware/controllers/engine_cycle/readme.md b/firmware/controllers/engine_cycle/readme.md new file mode 100644 index 0000000000..111595326d --- /dev/null +++ b/firmware/controllers/engine_cycle/readme.md @@ -0,0 +1 @@ +Here we have logic related to engine contol activitied within each engine cycle: coils & injectors mostly. \ No newline at end of file diff --git a/firmware/controllers/trigger/rpm_calculator.cpp b/firmware/controllers/engine_cycle/rpm_calculator.cpp similarity index 96% rename from firmware/controllers/trigger/rpm_calculator.cpp rename to firmware/controllers/engine_cycle/rpm_calculator.cpp index 107f47f7d8..980e3eb3ba 100644 --- a/firmware/controllers/trigger/rpm_calculator.cpp +++ b/firmware/controllers/engine_cycle/rpm_calculator.cpp @@ -269,7 +269,7 @@ void rpmShaftPositionCallback(trigger_event_e ckpSignalType, int signal = 1000 * ckpSignalType + index; scAddData(crankAngle, signal); } -#endif +#endif /* EFI_SENSOR_CHART */ if (rpmState->isSpinningUp(PASS_ENGINE_PARAMETER_SIGNATURE)) { // we are here only once trigger is synchronized for the first time @@ -296,6 +296,9 @@ static char rpmBuffer[_MAX_FILLER]; * digital sniffer. */ static void onTdcCallback(Engine *engine) { + if (!engine->needTdcCallback) { + return; + } EXPAND_Engine; itoa10(rpmBuffer, GET_RPM()); #if EFI_ENGINE_SNIFFER @@ -316,7 +319,7 @@ static void tdcMarkCallback(trigger_event_e ckpSignalType, int rpm = GET_RPM(); // todo: use tooth event-based scheduling, not just time-based scheduling if (isValidRpm(rpm)) { - scheduleByAngle(rpm, &tdcScheduler[revIndex2], tdcPosition(), + scheduleByAngle(&tdcScheduler[revIndex2], tdcPosition(), (schfunc_t) onTdcCallback, engine PASS_ENGINE_PARAMETER_SUFFIX); } } @@ -355,14 +358,9 @@ void initRpmCalculator(Logging *sharedLogger DECLARE_ENGINE_PARAMETER_SUFFIX) { * The callback would be executed once after the duration of time which * it takes the crankshaft to rotate to the specified angle. */ -void scheduleByAngle(float rpm, scheduling_s *timer, angle_t angle, +void scheduleByAngle(scheduling_s *timer, angle_t angle, schfunc_t callback, void *param DECLARE_ENGINE_PARAMETER_SUFFIX) { - ScopePerf perf(PE::ScheduleByAngle); - - efiAssertVoid(CUSTOM_ANGLE_NAN, !cisnan(angle), "NaN angle?"); - efiAssertVoid(CUSTOM_ERR_6634, isValidRpm(rpm), "RPM check expected"); float delayUs = ENGINE(rpmCalculator.oneDegreeUs) * angle; - efiAssertVoid(CUSTOM_ERR_6635, !cisnan(delayUs), "NaN delay?"); ENGINE(executor.scheduleForLater(timer, (int) delayUs, callback, param)); } diff --git a/firmware/controllers/trigger/rpm_calculator.h b/firmware/controllers/engine_cycle/rpm_calculator.h similarity index 97% rename from firmware/controllers/trigger/rpm_calculator.h rename to firmware/controllers/engine_cycle/rpm_calculator.h index 6df6cc0c9d..e7be215c06 100644 --- a/firmware/controllers/trigger/rpm_calculator.h +++ b/firmware/controllers/engine_cycle/rpm_calculator.h @@ -166,6 +166,6 @@ float getCrankshaftAngleNt(efitime_t timeNt DECLARE_ENGINE_PARAMETER_SUFFIX); #define addEngineSnifferEvent(n, msg) {} #endif /* EFI_ENGINE_SNIFFER */ -void scheduleByAngle(float rpm, scheduling_s *timer, angle_t angle, schfunc_t callback, void *param DECLARE_ENGINE_PARAMETER_SUFFIX); +void scheduleByAngle(scheduling_s *timer, angle_t angle, schfunc_t callback, void *param DECLARE_ENGINE_PARAMETER_SUFFIX); #endif /* RPM_REPORTER_H_ */ diff --git a/firmware/controllers/trigger/spark_logic.cpp b/firmware/controllers/engine_cycle/spark_logic.cpp similarity index 79% rename from firmware/controllers/trigger/spark_logic.cpp rename to firmware/controllers/engine_cycle/spark_logic.cpp index 82cc763f46..e28543373d 100644 --- a/firmware/controllers/trigger/spark_logic.cpp +++ b/firmware/controllers/engine_cycle/spark_logic.cpp @@ -5,7 +5,7 @@ * @author Andrey Belomutskiy, (c) 2012-2019 */ -#include "global.h" +#include "spark_logic.h" #include "os_access.h" #include "engine_math.h" @@ -75,7 +75,7 @@ static void fireSparkBySettingPinLow(IgnitionEvent *event, IgnitionOutputPin *ou } \ } -static void prepareCylinderIgnitionSchedule(angle_t dwellAngle, floatms_t sparkDwell, IgnitionEvent *event DECLARE_ENGINE_PARAMETER_SUFFIX) { +static void prepareCylinderIgnitionSchedule(angle_t dwellAngleDuration, floatms_t sparkDwell, IgnitionEvent *event DECLARE_ENGINE_PARAMETER_SUFFIX) { // todo: clean up this implementation? does not look too nice as is. // let's save planned duration so that we can later compare it with reality @@ -84,11 +84,12 @@ static void prepareCylinderIgnitionSchedule(angle_t dwellAngle, floatms_t sparkD // change of sign here from 'before TDC' to 'after TDC' angle_t ignitionPositionWithinEngineCycle = ENGINE(ignitionPositionWithinEngineCycle[event->cylinderIndex]); assertAngleRange(ignitionPositionWithinEngineCycle, "aPWEC", CUSTOM_ERR_6566); - cfg_float_t_1f timing_offset_cylinder = CONFIG(timing_offset_cylinder[event->cylinderIndex]); - const angle_t localAdvance = -ENGINE(engineState.timingAdvance) + ignitionPositionWithinEngineCycle + timing_offset_cylinder; - efiAssertVoid(CUSTOM_ERR_6689, !cisnan(localAdvance), "findAngle#9"); + // this correction is usually zero (not used) + cfg_float_t_1f perCylinderCorrection = CONFIG(timing_offset_cylinder[event->cylinderIndex]); + const angle_t sparkAngle = -ENGINE(engineState.timingAdvance) + ignitionPositionWithinEngineCycle + perCylinderCorrection; + efiAssertVoid(CUSTOM_SPARK_ANGLE_9, !cisnan(sparkAngle), "findAngle#9"); - efiAssertVoid(CUSTOM_ERR_6589, !cisnan(localAdvance), "localAdvance#1"); + efiAssertVoid(CUSTOM_SPARK_ANGLE_1, !cisnan(sparkAngle), "sparkAngle#1"); const int index = ENGINE(ignitionPin[event->cylinderIndex]); const int coilIndex = ID2INDEX(getCylinderId(index PASS_ENGINE_PARAMETER_SUFFIX)); IgnitionOutputPin *output = &enginePins.coils[coilIndex]; @@ -107,12 +108,12 @@ static void prepareCylinderIgnitionSchedule(angle_t dwellAngle, floatms_t sparkD event->outputs[0] = output; event->outputs[1] = secondOutput; - event->advance = localAdvance; + event->sparkAngle = sparkAngle; - angle_t a = localAdvance - dwellAngle; - efiAssertVoid(CUSTOM_ERR_6590, !cisnan(a), "findAngle#5"); - assertAngleRange(a, "findAngle#a6", CUSTOM_ERR_6550); - TRIGGER_SHAPE(findTriggerPosition(&event->dwellPosition, a PASS_CONFIG_PARAM(engineConfiguration->globalTriggerAngleOffset))); + angle_t dwellStartAngle = sparkAngle - dwellAngleDuration; + efiAssertVoid(CUSTOM_ERR_6590, !cisnan(dwellStartAngle), "findAngle#5"); + assertAngleRange(dwellStartAngle, "findAngle#a6", CUSTOM_ERR_6550); + event->dwellPosition.setAngle(dwellStartAngle PASS_ENGINE_PARAMETER_SUFFIX); #if FUEL_MATH_EXTREME_LOGGING printf("addIgnitionEvent %s ind=%d\n", output->name, event->dwellPosition.triggerEventIndex); @@ -156,13 +157,13 @@ if (engineConfiguration->debugMode == DBG_DWELL_METRIC) { #endif /* EFI_UNIT_TEST */ // now that we've just fired a coil let's prepare the new schedule for the next engine revolution - angle_t dwellAngle = ENGINE(engineState.dwellAngle); + angle_t dwellAngleDuration = ENGINE(engineState.dwellAngle); floatms_t sparkDwell = ENGINE(engineState.sparkDwell); - if (cisnan(dwellAngle) || cisnan(sparkDwell)) { + if (cisnan(dwellAngleDuration) || cisnan(sparkDwell)) { // we are here if engine has just stopped return; } - prepareCylinderIgnitionSchedule(dwellAngle, sparkDwell, event PASS_ENGINE_PARAMETER_SUFFIX); + prepareCylinderIgnitionSchedule(dwellAngleDuration, sparkDwell, event PASS_ENGINE_PARAMETER_SUFFIX); } static void startDwellByTurningSparkPinHigh(IgnitionEvent *event, IgnitionOutputPin *output) { @@ -215,16 +216,72 @@ void turnSparkPinHigh(IgnitionEvent *event) { } } +static bool assertNotInIgnitionList(AngleBasedEvent *head, AngleBasedEvent *element) { + assertNotInListMethodBody(AngleBasedEvent, head, element, nextToothEvent) +} + +/** + * @return true if event corresponds to current tooth and was time-based scheduler + * false if event was put into queue for scheduling at a later tooth + */ +bool scheduleOrQueue(AngleBasedEvent *event, + uint32_t trgEventIndex, + angle_t angle, + schfunc_t callback, + void *param DECLARE_ENGINE_PARAMETER_SUFFIX) { + event->position.setAngle(angle PASS_ENGINE_PARAMETER_SUFFIX); + + /** + * todo: extract a "scheduleForAngle" method with best implementation into a separate utility method + * + * Here's the status as of Nov 2018: + * "scheduleForLater" uses time only and for best precision it's best to use "scheduleForLater" only + * once we hit the last trigger tooth prior to needed event. This case we use as much trigger position angle as possible + * and only use less precise RPM-based time calculation for the last portion of the angle, the one between two teeth closest to the + * desired angle moment. + * + * At the moment we only have time-based scheduler. I believe what needs to be added is a trigger-event based scheduler on top of the + * time-based schedule. This case we would be firing events with best possible angle precision. + * + */ + if (trgEventIndex != TRIGGER_EVENT_UNDEFINED && event->position.triggerEventIndex == trgEventIndex) { + /** + * Spark should be fired before the next trigger event - time-based delay is best precision possible + */ + float timeTillIgnitionUs = ENGINE(rpmCalculator.oneDegreeUs) * event->position.angleOffsetFromTriggerEvent; + + + scheduling_s * sDown = &event->scheduling; + + engine->executor.scheduleForLater(sDown, (int) timeTillIgnitionUs, callback, param); + return true; + } else { + event->action.setAction(callback, param); + /** + * Spark should be scheduled in relation to some future trigger event, this way we get better firing precision + */ + bool isPending = assertNotInIgnitionList(ENGINE(angleBasedEventsHead), event); + if (isPending) { +#if SPARK_EXTREME_LOGGING + scheduleMsg(logger, "isPending thus not adding to queue index=%d rev=%d now=%d", trgEventIndex, getRevolutionCounter(), (int)getTimeNowUs()); +#endif /* FUEL_MATH_EXTREME_LOGGING */ + } else { + LL_APPEND2(ENGINE(angleBasedEventsHead), event, nextToothEvent); + } + return false; + } +} + static ALWAYS_INLINE void handleSparkEvent(bool limitedSpark, uint32_t trgEventIndex, IgnitionEvent *iEvent, int rpm DECLARE_ENGINE_PARAMETER_SUFFIX) { - angle_t advance = iEvent->advance; + angle_t sparkAngle = iEvent->sparkAngle; const floatms_t dwellMs = ENGINE(engineState.sparkDwell); if (cisnan(dwellMs) || dwellMs <= 0) { warning(CUSTOM_DWELL, "invalid dwell to handle: %.2f at %d", dwellMs, rpm); return; } - if (cisnan(advance)) { + if (cisnan(sparkAngle)) { warning(CUSTOM_ERR_6688, "NaN advance"); return; } @@ -247,7 +304,6 @@ static ALWAYS_INLINE void handleSparkEvent(bool limitedSpark, uint32_t trgEventI * when an event is scheduled within the next revolution. */ scheduling_s * sUp = &iEvent->dwellStartTimer; - scheduling_s * sDown = &iEvent->signalTimerDown; /** @@ -272,59 +328,31 @@ static ALWAYS_INLINE void handleSparkEvent(bool limitedSpark, uint32_t trgEventI * TODO: improve precision */ - efiAssertVoid(CUSTOM_ERR_6591, !cisnan(advance), "findAngle#4"); - assertAngleRange(advance, "findAngle#a5", CUSTOM_ERR_6549); - TRIGGER_SHAPE(findTriggerPosition(&iEvent->sparkPosition, advance PASS_CONFIG_PARAM(engineConfiguration->globalTriggerAngleOffset))); + efiAssertVoid(CUSTOM_ERR_6591, !cisnan(sparkAngle), "findAngle#4"); + assertAngleRange(sparkAngle, "findAngle#a5", CUSTOM_ERR_6549); + + + bool scheduled = scheduleOrQueue(&iEvent->sparkEvent, trgEventIndex, sparkAngle, (schfunc_t)fireSparkAndPrepareNextSchedule, iEvent PASS_ENGINE_PARAMETER_SUFFIX); + + if (scheduled) { +#if SPARK_EXTREME_LOGGING + scheduleMsg(logger, "scheduling sparkDown ind=%d %d %s now=%d later id=%d", trgEventIndex, getRevolutionCounter(), iEvent->getOutputForLoggins()->name, (int)getTimeNowUs(), iEvent->sparkId); +#endif /* FUEL_MATH_EXTREME_LOGGING */ + } else { +#if SPARK_EXTREME_LOGGING + scheduleMsg(logger, "to queue sparkDown ind=%d %d %s now=%d for id=%d", trgEventIndex, getRevolutionCounter(), iEvent->getOutputForLoggins()->name, (int)getTimeNowUs(), iEvent->sparkEvent.position.triggerEventIndex); +#endif /* FUEL_MATH_EXTREME_LOGGING */ + } + + #if EFI_UNIT_TEST if (verboseMode) { printf("spark dwell@ %d/%d spark@ %d/%d id=%d\r\n", iEvent->dwellPosition.triggerEventIndex, (int)iEvent->dwellPosition.angleOffsetFromTriggerEvent, - iEvent->sparkPosition.triggerEventAngle, (int)iEvent->sparkPosition.angleOffsetFromTriggerEvent, + iEvent->sparkEvent.position.triggerEventIndex, (int)iEvent->sparkEvent.position.angleOffsetFromTriggerEvent, iEvent->sparkId); } #endif - - /** - * todo: extract a "scheduleForAngle" method with best implementation into a separate utility method - * - * Here's the status as of Nov 2018: - * "scheduleForLater" uses time only and for best precision it's best to use "scheduleForLater" only - * once we hit the last trigger tooth prior to needed event. This case we use as much trigger position angle as possible - * and only use less precise RPM-based time calculation for the last portion of the angle, the one between two teeth closest to the - * desired angle moment. - * - * At the moment we only have time-based scheduler. I believe what needs to be added is a trigger-event based scheduler on top of the - * time-based schedule. This case we would be firing events with best possible angle precision. - * - */ - if (iEvent->sparkPosition.triggerEventIndex == trgEventIndex) { - /** - * Spark should be fired before the next trigger event - time-based delay is best precision possible - */ - float timeTillIgnitionUs = ENGINE(rpmCalculator.oneDegreeUs) * iEvent->sparkPosition.angleOffsetFromTriggerEvent; - -#if SPARK_EXTREME_LOGGING - scheduleMsg(logger, "scheduling sparkDown ind=%d %d %s now=%d %d later id=%d", trgEventIndex, getRevolutionCounter(), iEvent->getOutputForLoggins()->name, (int)getTimeNowUs(), (int)timeTillIgnitionUs, iEvent->sparkId); -#endif /* FUEL_MATH_EXTREME_LOGGING */ - - engine->executor.scheduleForLater(sDown, (int) timeTillIgnitionUs, (schfunc_t) &fireSparkAndPrepareNextSchedule, iEvent); - } else { -#if SPARK_EXTREME_LOGGING - scheduleMsg(logger, "to queue sparkDown ind=%d %d %s %d for %d", trgEventIndex, getRevolutionCounter(), iEvent->getOutputForLoggins()->name, (int)getTimeNowUs(), iEvent->sparkPosition.triggerEventIndex); -#endif /* FUEL_MATH_EXTREME_LOGGING */ - /** - * Spark should be scheduled in relation to some future trigger event, this way we get better firing precision - */ - bool isPending = assertNotInList(ENGINE(ignitionEventsHead), iEvent); - if (isPending) { -#if SPARK_EXTREME_LOGGING - scheduleMsg(logger, "not adding to queue sparkDown ind=%d %d %s %d", trgEventIndex, getRevolutionCounter(), iEvent->getOutputForLoggins()->name, (int)getTimeNowUs()); -#endif /* FUEL_MATH_EXTREME_LOGGING */ - return; - } - - LL_APPEND(ENGINE(ignitionEventsHead), iEvent); - } } void initializeIgnitionActions(DECLARE_ENGINE_PARAMETER_SIGNATURE) { @@ -381,23 +409,23 @@ static ALWAYS_INLINE void prepareIgnitionSchedule(DECLARE_ENGINE_PARAMETER_SIGNA static void scheduleAllSparkEventsUntilNextTriggerTooth(uint32_t trgEventIndex DECLARE_ENGINE_PARAMETER_SUFFIX) { - IgnitionEvent *current, *tmp; + AngleBasedEvent *current, *tmp; - LL_FOREACH_SAFE(ENGINE(ignitionEventsHead), current, tmp) + LL_FOREACH_SAFE2(ENGINE(angleBasedEventsHead), current, tmp, nextToothEvent) { - if (current->sparkPosition.triggerEventIndex == trgEventIndex) { + if (current->position.triggerEventIndex == trgEventIndex) { // time to fire a spark which was scheduled previously - LL_DELETE(ENGINE(ignitionEventsHead), current); + LL_DELETE2(ENGINE(angleBasedEventsHead), current, nextToothEvent); - scheduling_s * sDown = ¤t->signalTimerDown; + scheduling_s * sDown = ¤t->scheduling; #if SPARK_EXTREME_LOGGING - scheduleMsg(logger, "time to sparkDown ind=%d %d %s %d", trgEventIndex, getRevolutionCounter(), current->getOutputForLoggins()->name, (int)getTimeNowUs()); + scheduleMsg(logger, "time to invoke ind=%d %d %d", trgEventIndex, getRevolutionCounter(), (int)getTimeNowUs()); #endif /* FUEL_MATH_EXTREME_LOGGING */ - float timeTillIgnitionUs = ENGINE(rpmCalculator.oneDegreeUs) * current->sparkPosition.angleOffsetFromTriggerEvent; - engine->executor.scheduleForLater(sDown, (int) timeTillIgnitionUs, (schfunc_t) &fireSparkAndPrepareNextSchedule, current); + float timeTillIgnitionUs = ENGINE(rpmCalculator.oneDegreeUs) * current->position.angleOffsetFromTriggerEvent; + engine->executor.scheduleForLater(sDown, (int) timeTillIgnitionUs, (schfunc_t) current->action.getCallback(), current->action.getArgument()); } } } diff --git a/firmware/controllers/trigger/spark_logic.h b/firmware/controllers/engine_cycle/spark_logic.h similarity index 76% rename from firmware/controllers/trigger/spark_logic.h rename to firmware/controllers/engine_cycle/spark_logic.h index 818855aee9..914bf332ae 100644 --- a/firmware/controllers/trigger/spark_logic.h +++ b/firmware/controllers/engine_cycle/spark_logic.h @@ -5,8 +5,7 @@ * @author Andrey Belomutskiy, (c) 2012-2017 */ -#ifndef CONTROLLERS_TRIGGER_SPARK_LOGIC_H_ -#define CONTROLLERS_TRIGGER_SPARK_LOGIC_H_ +#pragma once #include "engine.h" @@ -19,4 +18,9 @@ int getNumberOfSparks(ignition_mode_e mode DECLARE_ENGINE_PARAMETER_SUFFIX); percent_t getCoilDutyCycle(int rpm DECLARE_ENGINE_PARAMETER_SUFFIX); void initializeIgnitionActions(DECLARE_ENGINE_PARAMETER_SIGNATURE); -#endif /* CONTROLLERS_TRIGGER_SPARK_LOGIC_H_ */ +#define TRIGGER_EVENT_UNDEFINED -1 +bool scheduleOrQueue(AngleBasedEvent *event, + uint32_t trgEventIndex, + angle_t angle, + schfunc_t callback, + void *param DECLARE_ENGINE_PARAMETER_SUFFIX); diff --git a/firmware/controllers/actuators/lcd_controller.cpp b/firmware/controllers/gauges/lcd_controller.cpp similarity index 100% rename from firmware/controllers/actuators/lcd_controller.cpp rename to firmware/controllers/gauges/lcd_controller.cpp diff --git a/firmware/controllers/actuators/lcd_controller.h b/firmware/controllers/gauges/lcd_controller.h similarity index 100% rename from firmware/controllers/actuators/lcd_controller.h rename to firmware/controllers/gauges/lcd_controller.h diff --git a/firmware/controllers/algo/lcd_menu_tree.cpp b/firmware/controllers/gauges/lcd_menu_tree.cpp similarity index 100% rename from firmware/controllers/algo/lcd_menu_tree.cpp rename to firmware/controllers/gauges/lcd_menu_tree.cpp diff --git a/firmware/controllers/algo/lcd_menu_tree.h b/firmware/controllers/gauges/lcd_menu_tree.h similarity index 100% rename from firmware/controllers/algo/lcd_menu_tree.h rename to firmware/controllers/gauges/lcd_menu_tree.h diff --git a/firmware/controllers/algo/malfunction_central.cpp b/firmware/controllers/gauges/malfunction_central.cpp similarity index 100% rename from firmware/controllers/algo/malfunction_central.cpp rename to firmware/controllers/gauges/malfunction_central.cpp diff --git a/firmware/controllers/algo/malfunction_central.h b/firmware/controllers/gauges/malfunction_central.h similarity index 100% rename from firmware/controllers/algo/malfunction_central.h rename to firmware/controllers/gauges/malfunction_central.h diff --git a/firmware/controllers/actuators/malfunction_indicator.cpp b/firmware/controllers/gauges/malfunction_indicator.cpp similarity index 100% rename from firmware/controllers/actuators/malfunction_indicator.cpp rename to firmware/controllers/gauges/malfunction_indicator.cpp diff --git a/firmware/controllers/actuators/malfunction_indicator.h b/firmware/controllers/gauges/malfunction_indicator.h similarity index 100% rename from firmware/controllers/actuators/malfunction_indicator.h rename to firmware/controllers/gauges/malfunction_indicator.h diff --git a/firmware/controllers/gauges/readme.md b/firmware/controllers/gauges/readme.md new file mode 100644 index 0000000000..e4952d8b09 --- /dev/null +++ b/firmware/controllers/gauges/readme.md @@ -0,0 +1 @@ +This folder has code related to communication with the human behind the steering wheel: tachometer, check engine light, LCD etc etc. \ No newline at end of file diff --git a/firmware/controllers/actuators/tachometer.cpp b/firmware/controllers/gauges/tachometer.cpp similarity index 100% rename from firmware/controllers/actuators/tachometer.cpp rename to firmware/controllers/gauges/tachometer.cpp diff --git a/firmware/controllers/actuators/tachometer.h b/firmware/controllers/gauges/tachometer.h similarity index 100% rename from firmware/controllers/actuators/tachometer.h rename to firmware/controllers/gauges/tachometer.h diff --git a/firmware/controllers/injector_central.cpp b/firmware/controllers/injector_central.cpp index 74bc56ecc9..5effd8280f 100644 --- a/firmware/controllers/injector_central.cpp +++ b/firmware/controllers/injector_central.cpp @@ -250,16 +250,6 @@ private: static BenchController instance; -void OutputPin::unregisterOutput(brain_pin_e oldPin, brain_pin_e newPin) { - if (oldPin != GPIO_UNASSIGNED && oldPin != newPin) { - scheduleMsg(logger, "unregistering %s", hwPortname(oldPin)); -#if EFI_GPIO_HARDWARE - brain_pin_markUnused(oldPin); - port = nullptr; -#endif /* EFI_GPIO_HARDWARE */ - } -} - static void handleCommandX14(uint16_t index) { switch (index) { case 1: diff --git a/firmware/controllers/math/engine_math.cpp b/firmware/controllers/math/engine_math.cpp index 83ce346b97..cca8c622ae 100644 --- a/firmware/controllers/math/engine_math.cpp +++ b/firmware/controllers/math/engine_math.cpp @@ -196,9 +196,7 @@ bool FuelSchedule::addFuelEventsForCylinder(int i DECLARE_ENGINE_PARAMETER_SUFF InjectionEvent *ev = &elements[i]; ev->ownIndex = i; -#if EFI_UNIT_TEST - ev->engine = engine; -#endif + INJECT_ENGINE_REFERENCE(ev); fixAngle(angle, "addFuel#1", CUSTOM_ERR_6554); ev->outputs[0] = output; @@ -206,14 +204,14 @@ bool FuelSchedule::addFuelEventsForCylinder(int i DECLARE_ENGINE_PARAMETER_SUFF ev->isSimultanious = isSimultanious; - if (TRIGGER_SHAPE(getSize()) < 1) { - warning(CUSTOM_ERR_NOT_INITIALIZED_TRIGGER, "uninitialized TriggerShape"); + if (TRIGGER_WAVEFORM(getSize()) < 1) { + warning(CUSTOM_ERR_NOT_INITIALIZED_TRIGGER, "uninitialized TriggerWaveform"); return false; } efiAssert(CUSTOM_ERR_ASSERT, !cisnan(angle), "findAngle#3", false); assertAngleRange(angle, "findAngle#a33", CUSTOM_ERR_6544); - TRIGGER_SHAPE(findTriggerPosition(&ev->injectionStart, angle PASS_CONFIG_PARAM(engineConfiguration->globalTriggerAngleOffset))); + ev->injectionStart.setAngle(angle PASS_ENGINE_PARAMETER_SUFFIX); #if EFI_UNIT_TEST printf("registerInjectionEvent angle=%.2f trgIndex=%d inj %d\r\n", angle, ev->injectionStart.triggerEventIndex, injectorIndex); #endif @@ -519,17 +517,17 @@ void prepareOutputSignals(DECLARE_ENGINE_PARAMETER_SIGNATURE) { prepareIgnitionPinIndices(CONFIG(ignitionMode) PASS_ENGINE_PARAMETER_SUFFIX); - TRIGGER_SHAPE(prepareShape()); + TRIGGER_WAVEFORM(prepareShape()); } #endif /* EFI_ENGINE_CONTROL */ void setFuelRpmBin(float from, float to DECLARE_CONFIG_PARAMETER_SUFFIX) { - setTableBin(config->fuelRpmBins, FUEL_RPM_COUNT, from, to); + setLinearCurve(config->fuelRpmBins, from, to); } void setFuelLoadBin(float from, float to DECLARE_CONFIG_PARAMETER_SUFFIX) { - setTableBin(config->fuelLoadBins, FUEL_LOAD_COUNT, from, to); + setLinearCurve(config->fuelLoadBins, from, to); } void setTimingRpmBin(float from, float to DECLARE_CONFIG_PARAMETER_SUFFIX) { @@ -537,7 +535,7 @@ void setTimingRpmBin(float from, float to DECLARE_CONFIG_PARAMETER_SUFFIX) { } void setTimingLoadBin(float from, float to DECLARE_CONFIG_PARAMETER_SUFFIX) { - setTableBin(config->ignitionLoadBins, IGN_LOAD_COUNT, from, to); + setLinearCurve(config->ignitionLoadBins, from, to); } /** @@ -548,11 +546,11 @@ void setAlgorithm(engine_load_mode_e algo DECLARE_CONFIG_PARAMETER_SUFFIX) { if (algo == LM_ALPHA_N) { setTimingLoadBin(20, 120 PASS_CONFIG_PARAMETER_SUFFIX); } else if (algo == LM_SPEED_DENSITY) { - setLinearCurve(config->ignitionLoadBins, IGN_LOAD_COUNT, 20, 120, 3); + setLinearCurve(config->ignitionLoadBins, 20, 120, 3); buildTimingMap(35 PASS_CONFIG_PARAMETER_SUFFIX); } } void setFlatInjectorLag(float value DECLARE_CONFIG_PARAMETER_SUFFIX) { - setArrayValues(engineConfiguration->injector.battLagCorr, VBAT_INJECTOR_CURVE_SIZE, value); + setArrayValues(engineConfiguration->injector.battLagCorr, value); } diff --git a/firmware/controllers/math/engine_math.h b/firmware/controllers/math/engine_math.h index e66f7521ea..36e8b6081d 100644 --- a/firmware/controllers/math/engine_math.h +++ b/firmware/controllers/math/engine_math.h @@ -67,4 +67,4 @@ void setSingleCoilDwell(DECLARE_CONFIG_PARAMETER_SIGNATURE); // expectation is that for well-known triggers CONFIG(globalTriggerAngleOffset) would usually be zero // while for toothed wheels user would have to provide a value #define tdcPosition() \ - (TRIGGER_SHAPE(tdcPosition) + CONFIG(globalTriggerAngleOffset)) + (TRIGGER_WAVEFORM(tdcPosition) + CONFIG(globalTriggerAngleOffset)) diff --git a/firmware/controllers/math/speed_density.cpp b/firmware/controllers/math/speed_density.cpp index 6c84f32bb6..4d51d99229 100644 --- a/firmware/controllers/math/speed_density.cpp +++ b/firmware/controllers/math/speed_density.cpp @@ -174,14 +174,14 @@ void setDefaultVETable(DECLARE_ENGINE_PARAMETER_SIGNATURE) { veMap.setAll(80); // setRpmTableBin(engineConfiguration->ve2RpmBins, FUEL_RPM_COUNT); -// setLinearCurve(engineConfiguration->ve2LoadBins, FUEL_LOAD_COUNT, 10, 300, 1); +// setLinearCurve(engineConfiguration->ve2LoadBins, 10, 300, 1); // ve2Map.setAll(0.81); setRpmTableBin(config->afrRpmBins, FUEL_RPM_COUNT); afrMap.setAll(14.7); setRpmTableBin(engineConfiguration->baroCorrRpmBins, BARO_CORR_SIZE); - setLinearCurve(engineConfiguration->baroCorrPressureBins, BARO_CORR_SIZE, 75, 105, 1); + setLinearCurve(engineConfiguration->baroCorrPressureBins, 75, 105, 1); for (int i = 0; i < BARO_CORR_SIZE;i++) { for (int j = 0; j < BARO_CORR_SIZE;j++) { // Default baro table is all 1.0, we can't recommend a reasonable default here diff --git a/firmware/controllers/sensors/map.cpp b/firmware/controllers/sensors/map.cpp index d32af37c33..22e4deb748 100644 --- a/firmware/controllers/sensors/map.cpp +++ b/firmware/controllers/sensors/map.cpp @@ -225,7 +225,7 @@ static void printMAPInfo(void) { if (engineConfiguration->hasFrequencyReportingMapSensor) { - scheduleMsg(logger, "instant value=%.2fHz @ %s", mapFreq, hwPortname(CONFIGB(frequencyReportingMapInputPin))); + scheduleMsg(logger, "instant value=%.2fHz @ %s", mapFreq, hwPortname(CONFIG(frequencyReportingMapInputPin))); } else { scheduleMsg(logger, "map type=%d/%s MAP=%.2fkPa mapMinBufferLength=%d", engineConfiguration->map.sensor.type, getAir_pressure_sensor_type_e(engineConfiguration->map.sensor.type), @@ -268,14 +268,14 @@ void initMapDecoder(Logging *sharedLogger DECLARE_ENGINE_PARAMETER_SUFFIX) { if (engineConfiguration->hasFrequencyReportingMapSensor) { #if HAL_USE_ICU - digital_input_s* digitalMapInput = startDigitalCapture("MAP freq", CONFIGB(frequencyReportingMapInputPin), true); + digital_input_s* digitalMapInput = startDigitalCapture("MAP freq", CONFIG(frequencyReportingMapInputPin), true); digitalMapInput->setWidthCallback((VoidInt) digitalMapWidthCallback, NULL); #else #if EFI_PROD_CODE efiExtiEnablePin( "Frequency MAP", - CONFIGB(frequencyReportingMapInputPin), + CONFIG(frequencyReportingMapInputPin), PAL_EVENT_MODE_RISING_EDGE, (palcallback_t)digitalMapWidthCallback, nullptr diff --git a/firmware/controllers/sensors/map.h b/firmware/controllers/sensors/map.h index 17515981b7..8c9c6ab283 100644 --- a/firmware/controllers/sensors/map.h +++ b/firmware/controllers/sensors/map.h @@ -26,10 +26,10 @@ float getMapByVoltage(float voltage DECLARE_ENGINE_PARAMETER_SUFFIX); float decodePressure(float voltage, air_pressure_sensor_config_s * mapConfig DECLARE_ENGINE_PARAMETER_SUFFIX); float validateMap(float mapKPa DECLARE_ENGINE_PARAMETER_SUFFIX); -#define KPA_PER_PSI 6.89475728 +#define KPA_PER_PSI 6.89475728f // PSI (relative to atmosphere) to kPa (relative to vacuum) -#define PSI2KPA(psi) (101.32500411216164 + KPA_PER_PSI * (psi)) +#define PSI2KPA(psi) (101.32500411216164f + KPA_PER_PSI * (psi)) #define INHG2KPA(inhg) ((inhg) * 3.386375) #define KPA2INHG(kpa) ((kpa) / 3.386375) diff --git a/firmware/controllers/sensors/tps.cpp b/firmware/controllers/sensors/tps.cpp index 96878731e4..4ded0610bc 100644 --- a/firmware/controllers/sensors/tps.cpp +++ b/firmware/controllers/sensors/tps.cpp @@ -141,7 +141,7 @@ float getTPSVoltage(DECLARE_ENGINE_PARAMETER_SIGNATURE) { * We need ADC value because TunerStudio has a nice TPS configuration wizard, and this wizard * wants a TPS value. */ -int getTPS12bitAdc(DECLARE_ENGINE_PARAMETER_SIGNATURE) { +int getTPS12bitAdc(int index DECLARE_ENGINE_PARAMETER_SUFFIX) { #if !EFI_PROD_CODE if (engine->mockTpsAdcValue != MOCK_UNDEFINED) { return engine->mockTpsAdcValue; @@ -151,7 +151,11 @@ int getTPS12bitAdc(DECLARE_ENGINE_PARAMETER_SIGNATURE) { return -1; #if EFI_PROD_CODE - return getAdcValue("tps10", engineConfiguration->tps1_1AdcChannel); + if (index == 0) { + return getAdcValue("tps10", engineConfiguration->tps1_1AdcChannel); + } else { + return getAdcValue("tps20", engineConfiguration->tps2_1AdcChannel); + } // return tpsFastAdc / 4; #else return 0; @@ -193,8 +197,8 @@ void grabPedalIsWideOpen() { /** * @brief Position on physical primary TPS */ -static percent_t getPrimatyRawTPS(DECLARE_ENGINE_PARAMETER_SIGNATURE) { - percent_t tpsValue = getTpsValue(getTPS12bitAdc(PASS_ENGINE_PARAMETER_SIGNATURE) PASS_ENGINE_PARAMETER_SUFFIX); +static percent_t getPrimatyRawTPS(int index DECLARE_ENGINE_PARAMETER_SUFFIX) { + percent_t tpsValue = getTpsValue(getTPS12bitAdc(index PASS_ENGINE_PARAMETER_SUFFIX) PASS_ENGINE_PARAMETER_SUFFIX); return tpsValue; } @@ -222,7 +226,7 @@ bool hasTpsSensor(DECLARE_ENGINE_PARAMETER_SIGNATURE) { return engineConfiguration->tps1_1AdcChannel != EFI_ADC_NONE; } -percent_t getTPS(DECLARE_ENGINE_PARAMETER_SIGNATURE) { +percent_t getTPSWithIndex(int index DECLARE_ENGINE_PARAMETER_SUFFIX) { #if !EFI_PROD_CODE if (!cisnan(engine->mockTpsValue)) { return engine->mockTpsValue; @@ -234,7 +238,11 @@ percent_t getTPS(DECLARE_ENGINE_PARAMETER_SIGNATURE) { // todo: blah blah // todo: if two TPS do not match - show OBD code via malfunction_central.c - return getPrimatyRawTPS(PASS_ENGINE_PARAMETER_SIGNATURE); + return getPrimatyRawTPS(index PASS_ENGINE_PARAMETER_SUFFIX); +} + +percent_t getTPS(DECLARE_ENGINE_PARAMETER_SIGNATURE) { + return getTPSWithIndex(0 PASS_ENGINE_PARAMETER_SUFFIX); } void setBosch0280750009(DECLARE_ENGINE_PARAMETER_SIGNATURE) { diff --git a/firmware/controllers/sensors/tps.h b/firmware/controllers/sensors/tps.h index 3e4503aa9f..cd12176012 100644 --- a/firmware/controllers/sensors/tps.h +++ b/firmware/controllers/sensors/tps.h @@ -24,10 +24,11 @@ percent_t getPedalPosition(DECLARE_ENGINE_PARAMETER_SIGNATURE); * @return Current TPS position, percent of WOT. 0 means idle and 100 means Wide Open Throttle */ percent_t getTPS(DECLARE_ENGINE_PARAMETER_SIGNATURE); +percent_t getTPSWithIndex(int index DECLARE_ENGINE_PARAMETER_SUFFIX); bool hasTpsSensor(DECLARE_ENGINE_PARAMETER_SIGNATURE); int convertVoltageTo10bitADC(float voltage); -int getTPS12bitAdc(DECLARE_ENGINE_PARAMETER_SIGNATURE); -#define getTPS10bitAdc() (getTPS12bitAdc() / TPS_TS_CONVERSION) +int getTPS12bitAdc(int index DECLARE_ENGINE_PARAMETER_SUFFIX); +#define getTPS10bitAdc() (getTPS12bitAdc(0 PASS_ENGINE_PARAMETER_SUFFIX) / TPS_TS_CONVERSION) float getTPSVoltage(DECLARE_ENGINE_PARAMETER_SIGNATURE); percent_t getTpsValue(int adc DECLARE_ENGINE_PARAMETER_SUFFIX); void setBosch0280750009(DECLARE_ENGINE_PARAMETER_SIGNATURE); diff --git a/firmware/controllers/settings.cpp b/firmware/controllers/settings.cpp index 964bc8727b..bf82370028 100644 --- a/firmware/controllers/settings.cpp +++ b/firmware/controllers/settings.cpp @@ -115,6 +115,9 @@ static void printOutputs(const engine_configuration_s *engineConfiguration) { scheduleMsg(&logger, "mainRelay: mode %s @ %s", getPin_output_mode_e(boardConfiguration->mainRelayPinMode), hwPortname(boardConfiguration->mainRelayPin)); + scheduleMsg(&logger, "starterRelay: mode %s @ %s", getPin_output_mode_e(boardConfiguration->starterRelayPinMode), + hwPortname(boardConfiguration->starterRelayPin)); + scheduleMsg(&logger, "alternator field: mode %s @ %s", getPin_output_mode_e(boardConfiguration->alternatorControlPinMode), hwPortname(boardConfiguration->alternatorControlPin)); @@ -278,7 +281,7 @@ void printConfiguration(const engine_configuration_s *engineConfiguration) { boolToString(engineConfiguration->isManualSpinningMode), boolToString(engineConfiguration->isCylinderCleanupEnabled)); - scheduleMsg(&logger, "clutchUp@%s: %s", hwPortname(boardConfiguration->clutchUpPin), + scheduleMsg(&logger, "clutchUp@%s: %s", hwPortname(engineConfiguration->clutchUpPin), boolToString(engine->clutchUpState)); scheduleMsg(&logger, "clutchDown@%s: %s", hwPortname(boardConfiguration->clutchDownPin), boolToString(engine->clutchDownState)); @@ -568,7 +571,7 @@ static void setToothedWheel(int total, int skipped DECLARE_ENGINE_PARAMETER_SUFF scheduleMsg(&logger, "toothed: total=%d/skipped=%d", total, skipped); setToothedWheelConfiguration(&engine->triggerCentral.triggerShape, total, skipped, engineConfiguration->ambiguousOperationMode); -// initializeTriggerShape(&logger, engineConfiguration, engineConfiguration2); +// initializeTriggerWaveform(&logger, engineConfiguration, engineConfiguration2); incrementGlobalConfigurationVersion(PASS_ENGINE_PARAMETER_SIGNATURE); doPrintConfiguration(); } @@ -696,6 +699,10 @@ static void setMainRelayPin(const char *pinName) { setIndividualPin(pinName, &boardConfiguration->mainRelayPin, "main relay"); } +static void setStarterRelayPin(const char *pinName) { + setIndividualPin(pinName, &boardConfiguration->starterRelayPin, "starter relay"); +} + static void setAlternatorPin(const char *pinName) { setIndividualPin(pinName, &boardConfiguration->alternatorControlPin, "alternator"); } @@ -811,7 +818,10 @@ static void setAnalogInputPin(const char *sensorStr, const char *pinName) { scheduleMsg(&logger, "setting IAT to %s/%d", pinName, channel); } else if (strEqual("tps", sensorStr)) { engineConfiguration->tps1_1AdcChannel = channel; - scheduleMsg(&logger, "setting TPS to %s/%d", pinName, channel); + scheduleMsg(&logger, "setting TPS1 to %s/%d", pinName, channel); + } else if (strEqual("tps2", sensorStr)) { + engineConfiguration->tps2_1AdcChannel = channel; + scheduleMsg(&logger, "setting TPS2 to %s/%d", pinName, channel); } incrementGlobalConfigurationVersion(PASS_ENGINE_PARAMETER_SIGNATURE); } @@ -969,7 +979,7 @@ static void enableOrDisable(const char *param, bool isEnabled) { engineConfiguration->isMapAveragingEnabled = isEnabled; } else if (strEqualCaseInsensitive(param, "tunerstudio")) { engineConfiguration->isTunerStudioEnabled = isEnabled; - } else if (strEqualCaseInsensitive(param, "wave_analyzer")) { + } else if (strEqualCaseInsensitive(param, "logic_analyzer")) { engineConfiguration->isWaveAnalyzerEnabled = isEnabled; } else if (strEqualCaseInsensitive(param, "manual_spinning")) { engineConfiguration->isManualSpinningMode = isEnabled; @@ -1146,11 +1156,11 @@ static void getValue(const char *paramStr) { } static void setFsioCurve1Value(float value) { - setLinearCurve(engineConfiguration->fsioCurve1, FSIO_CURVE_16, value, value, 1); + setLinearCurve(engineConfiguration->fsioCurve1, value, value, 1); } static void setFsioCurve2Value(float value) { - setLinearCurve(engineConfiguration->fsioCurve2, FSIO_CURVE_16, value, value, 1); + setLinearCurve(engineConfiguration->fsioCurve2, value, value, 1); } typedef struct { @@ -1242,7 +1252,7 @@ const command_i_s commandsI[] = {{"ignition_mode", setIgnitionMode}, {"tpsErrorDetectionTooHigh", setTpsErrorDetectionTooHigh}, {"fixed_mode_timing", setFixedModeTiming}, {"timing_mode", setTimingMode}, - {"engine_type", setEngineType}, + {CMD_ENGINE_TYPE, setEngineType}, {"rpm_hard_limit", setRpmHardLimit}, {"firing_order", setFiringOrder}, {"algorithm", setAlgorithmInt}, @@ -1431,6 +1441,7 @@ void initSettings(void) { addConsoleActionS("set_alternator_pin", setAlternatorPin); addConsoleActionS("set_idle_pin", setIdlePin); addConsoleActionS("set_main_relay_pin", setMainRelayPin); + addConsoleActionS("set_starter_relay_pin", setStarterRelayPin); #if HAL_USE_ADC addConsoleActionSS("set_analog_input_pin", setAnalogInputPin); diff --git a/firmware/controllers/system/dc_motor.cpp b/firmware/controllers/system/dc_motor.cpp index 4dbc6959c7..2b3db71ef8 100644 --- a/firmware/controllers/system/dc_motor.cpp +++ b/firmware/controllers/system/dc_motor.cpp @@ -7,6 +7,7 @@ */ #include "dc_motor.h" +#include "pwm_generator_logic.h" TwoPinDcMotor::TwoPinDcMotor(SimplePwm* enable, SimplePwm* dir1, SimplePwm* dir2) : m_enable(enable) @@ -19,14 +20,14 @@ bool TwoPinDcMotor::isOpenDirection() const { return m_value >= 0; } -float TwoPinDcMotor::Get() const { +float TwoPinDcMotor::get() const { return m_value; } /** * @param duty value between -1.0 and 1.0 */ -bool TwoPinDcMotor::Set(float duty) +bool TwoPinDcMotor::set(float duty) { m_value = duty; diff --git a/firmware/controllers/system/dc_motor.h b/firmware/controllers/system/dc_motor.h index 8c6722b123..4bcf221b54 100644 --- a/firmware/controllers/system/dc_motor.h +++ b/firmware/controllers/system/dc_motor.h @@ -7,8 +7,6 @@ #pragma once -#include "pwm_generator_logic.h" - /** * @brief Brushed or brushless DC motor interface * @@ -23,9 +21,19 @@ public: * @param duty +1.0f represents full power forward, and -1.0f represents full power backward. * @return True if any fault was detected driving the motor, and false if successful. */ - virtual bool Set(float duty) = 0; + virtual bool set(float duty) = 0; + + /** + * @brief Get the current motor duty cycle. + * @return The current duty cycle setting. +1.0f represents full power forward, and -1.0f represents full power backward. + */ + virtual float get() const = 0; + + virtual bool isOpenDirection() const = 0; }; +class SimplePwm; + /** * @brief Represents a DC motor controller (H bridge) with one pin for enable (PWM), * and two pins for direction control. @@ -70,9 +78,9 @@ public: */ TwoPinDcMotor(SimplePwm* enable, SimplePwm* dir1, SimplePwm* dir2); - virtual bool Set(float duty) override; - float Get() const; - bool isOpenDirection() const; + virtual bool set(float duty) override; + float get() const override; + bool isOpenDirection() const override; - void SetType(ControlType type) { m_type = type; } + void setType(ControlType type) { m_type = type; } }; diff --git a/firmware/controllers/system/efi_gpio.cpp b/firmware/controllers/system/efi_gpio.cpp index ff31a5afbe..3616753985 100644 --- a/firmware/controllers/system/efi_gpio.cpp +++ b/firmware/controllers/system/efi_gpio.cpp @@ -30,7 +30,7 @@ extern WaveChart waveChart; // todo: clean this mess, this should become 'static'/private EnginePins enginePins; -extern LoggingWithStorage sharedLogger; +static Logging* logger; pin_output_mode_e DEFAULT_OUTPUT = OM_DEFAULT; @@ -85,6 +85,18 @@ EnginePins::EnginePins() { } \ } +#define unregisterOutputIfPinChanged(output, pin) { \ + if (isConfigurationChanged(pin)) { \ + (output).unregisterOutput(activeConfiguration.pin); \ + } \ +} + +#define unregisterOutputIfPinOrModeChanged(output, pin, mode) { \ + if (isPinOrModeChanged(pin, mode)) { \ + (output).unregisterOutput(activeConfiguration.pin); \ + } \ +} + #else /* EFI_PROD_CODE */ #define setPinValue(outputPin, electricalValue, logicValue) \ @@ -114,37 +126,25 @@ void EnginePins::unregisterPins() { unregisterEtbPins(); #endif /* EFI_ELECTRONIC_THROTTLE_BODY */ #if EFI_PROD_CODE - fuelPumpRelay.unregisterOutput(activeConfiguration.bc.fuelPumpPin, engineConfiguration->bc.fuelPumpPin); - fanRelay.unregisterOutput(activeConfiguration.bc.fanPin, engineConfiguration->bc.fanPin); - acRelay.unregisterOutput(activeConfiguration.bc.acRelayPin, engineConfiguration->bc.acRelayPin); - hipCs.unregisterOutput(activeConfiguration.bc.hip9011CsPin, engineConfiguration->bc.hip9011CsPin); - triggerDecoderErrorPin.unregisterOutput(activeConfiguration.bc.triggerErrorPin, - engineConfiguration->bc.triggerErrorPin); - - sdCsPin.unregisterOutput(activeConfiguration.bc.sdCardCsPin, engineConfiguration->bc.sdCardCsPin); - accelerometerCs.unregisterOutput(activeConfiguration.LIS302DLCsPin, engineConfiguration->LIS302DLCsPin); -// etbOutput1.unregisterOutput(activeConfiguration.bc.etb1.directionPin1, -// engineConfiguration->bc.etb1.directionPin1); -// etbOutput2.unregisterOutput(activeConfiguration.bc.etb1.directionPin2, -// engineConfiguration->bc.etb1.directionPin2); - checkEnginePin.unregisterOutput(activeConfiguration.bc.malfunctionIndicatorPin, - engineConfiguration->bc.malfunctionIndicatorPin); - dizzyOutput.unregisterOutput(activeConfiguration.dizzySparkOutputPin, - engineConfiguration->dizzySparkOutputPin); - tachOut.unregisterOutput(activeConfiguration.bc.tachOutputPin, - engineConfiguration->bc.tachOutputPin); - idleSolenoidPin.unregisterOutput(activeConfiguration.bc.idle.solenoidPin, - engineConfiguration->bc.idle.solenoidPin); + unregisterOutputIfPinOrModeChanged(fuelPumpRelay, bc.fuelPumpPin, bc.fuelPumpPinMode); + unregisterOutputIfPinOrModeChanged(fanRelay, bc.fanPin, bc.fanPinMode); + unregisterOutputIfPinOrModeChanged(acRelay, bc.acRelayPin, bc.acRelayPinMode); + unregisterOutputIfPinOrModeChanged(hipCs, bc.hip9011CsPin, bc.hip9011CsPinMode); + unregisterOutputIfPinOrModeChanged(triggerDecoderErrorPin, bc.triggerErrorPin, bc.triggerErrorPinMode); + unregisterOutputIfPinOrModeChanged(checkEnginePin, bc.malfunctionIndicatorPin, bc.malfunctionIndicatorPinMode); + unregisterOutputIfPinOrModeChanged(dizzyOutput, dizzySparkOutputPin, dizzySparkOutputPinMode); + unregisterOutputIfPinOrModeChanged(tachOut, bc.tachOutputPin, bc.tachOutputPinMode); + unregisterOutputIfPinOrModeChanged(idleSolenoidPin, bc.idle.solenoidPin, bc.idle.solenoidPinMode); + unregisterOutputIfPinChanged(sdCsPin, bc.sdCardCsPin); + unregisterOutputIfPinChanged(accelerometerCs, LIS302DLCsPin); for (int i = 0;i < FSIO_COMMAND_COUNT;i++) { - fsioOutputs[i].unregisterOutput(activeConfiguration.bc.fsioOutputPins[i], - engineConfiguration->bc.fsioOutputPins[i]); + unregisterOutputIfPinChanged(fsioOutputs[i], bc.fsioOutputPins[i]); } - alternatorPin.unregisterOutput(activeConfiguration.bc.alternatorControlPin, - engineConfiguration->bc.alternatorControlPin); - mainRelay.unregisterOutput(activeConfiguration.bc.mainRelayPin, - engineConfiguration->bc.mainRelayPin); + unregisterOutputIfPinOrModeChanged(alternatorPin, bc.alternatorControlPin, bc.alternatorControlPinMode); + unregisterOutputIfPinOrModeChanged(mainRelay, bc.mainRelayPin, bc.mainRelayPinMode); + unregisterOutputIfPinOrModeChanged(starterRelay, bc.starterRelayPin, bc.starterRelayPinMode); #endif /* EFI_PROD_CODE */ } @@ -161,9 +161,7 @@ void EnginePins::reset() { void EnginePins::stopIgnitionPins(void) { #if EFI_PROD_CODE for (int i = 0; i < IGNITION_PIN_COUNT; i++) { - NamedOutputPin *output = &enginePins.coils[i]; - output->unregisterOutput(activeConfiguration.bc.ignitionPins[i], - engineConfiguration->bc.ignitionPins[i]); + unregisterOutputIfPinOrModeChanged(enginePins.coils[i], bc.ignitionPins[i], bc.ignitionPinMode); } #endif /* EFI_PROD_CODE */ } @@ -171,9 +169,7 @@ void EnginePins::stopIgnitionPins(void) { void EnginePins::stopInjectionPins(void) { #if EFI_PROD_CODE for (int i = 0; i < INJECTION_PIN_COUNT; i++) { - NamedOutputPin *output = &enginePins.injectors[i]; - output->unregisterOutput(activeConfiguration.bc.injectionPins[i], - engineConfiguration->bc.injectionPins[i]); + unregisterOutputIfPinOrModeChanged(enginePins.injectors[i], bc.injectionPins[i], bc.injectionPinMode); } #endif /* EFI_PROD_CODE */ } @@ -191,13 +187,11 @@ void EnginePins::startIgnitionPins(void) { #if EFI_PROD_CODE for (int i = 0; i < engineConfiguration->specs.cylindersCount; i++) { NamedOutputPin *output = &enginePins.coils[i]; - // todo: we need to check if mode has changed - if (isConfigurationChanged(bc.ignitionPins[i])) { + if (isPinOrModeChanged(bc.ignitionPins[i], bc.ignitionPinMode)) { output->initPin(output->name, CONFIGB(ignitionPins)[i], &CONFIGB(ignitionPinMode)); } } - // todo: we need to check if mode has changed - if (isConfigurationChanged(dizzySparkOutputPin)) { + if (isPinOrModeChanged(dizzySparkOutputPin, dizzySparkOutputPinMode)) { enginePins.dizzyOutput.initPin("dizzy tach", engineConfiguration->dizzySparkOutputPin, &engineConfiguration->dizzySparkOutputPinMode); @@ -210,9 +204,7 @@ void EnginePins::startInjectionPins(void) { // todo: should we move this code closer to the injection logic? for (int i = 0; i < engineConfiguration->specs.cylindersCount; i++) { NamedOutputPin *output = &enginePins.injectors[i]; - // todo: we need to check if mode has changed - if (engineConfiguration->bc.injectionPins[i] != activeConfiguration.bc.injectionPins[i]) { - + if (isPinOrModeChanged(bc.injectionPins[i], bc.injectionPinMode)) { output->initPin(output->name, CONFIGB(injectionPins)[i], &CONFIGB(injectionPinMode)); } @@ -273,7 +265,7 @@ bool NamedOutputPin::stop() { #if EFI_GPIO_HARDWARE if (isInitialized() && getLogicValue()) { setValue(false); - scheduleMsg(&sharedLogger, "turning off %s", name); + scheduleMsg(logger, "turning off %s", name); return true; } #endif /* EFI_GPIO_HARDWARE */ @@ -383,6 +375,7 @@ void initOutputPins(DECLARE_ENGINE_PARAMETER_SIGNATURE) { enginePins.fuelPumpRelay.initPin("fuel pump relay", CONFIGB(fuelPumpPin), &CONFIGB(fuelPumpPinMode)); enginePins.mainRelay.initPin("main relay", CONFIGB(mainRelayPin), &CONFIGB(mainRelayPinMode)); + enginePins.starterRelay.initPin("starter relay", CONFIGB(starterRelayPin), &CONFIGB(starterRelayPinMode)); enginePins.fanRelay.initPin("fan relay", CONFIGB(fanPin), &CONFIGB(fanPinMode)); enginePins.o2heater.initPin("o2 heater", CONFIGB(o2heaterPin)); @@ -481,6 +474,16 @@ void OutputPin::initPin(const char *msg, brain_pin_e brainPin, const pin_output_ #endif /* EFI_GPIO_HARDWARE */ } +void OutputPin::unregisterOutput(brain_pin_e oldPin) { + if (oldPin != GPIO_UNASSIGNED) { + scheduleMsg(logger, "unregistering %s", hwPortname(oldPin)); +#if EFI_GPIO_HARDWARE && EFI_PROD_CODE + brain_pin_markUnused(oldPin); + port = nullptr; +#endif /* EFI_GPIO_HARDWARE */ + } +} + #if EFI_GPIO_HARDWARE // questionable trick: we avoid using 'getHwPort' and 'getHwPin' in case of errors in order to increase the changes of turning the LED @@ -488,7 +491,8 @@ void OutputPin::initPin(const char *msg, brain_pin_e brainPin, const pin_output_ ioportid_t errorLedPort; ioportmask_t errorLedPin; -void initPrimaryPins(void) { +void initPrimaryPins(Logging *sharedLogger) { + logger = sharedLogger; #if EFI_PROD_CODE enginePins.errorLedPin.initPin("led: ERROR status", LED_ERROR_BRAIN_PIN); errorLedPort = getHwPort("primary", LED_ERROR_BRAIN_PIN); diff --git a/firmware/controllers/system/efi_gpio.h b/firmware/controllers/system/efi_gpio.h index fd919abd0c..e1b60f3c12 100644 --- a/firmware/controllers/system/efi_gpio.h +++ b/firmware/controllers/system/efi_gpio.h @@ -13,7 +13,7 @@ #include "io_pins.h" #include "engine_configuration.h" -void initPrimaryPins(void); +void initPrimaryPins(Logging *sharedLogger); void initOutputPins(DECLARE_ENGINE_PARAMETER_SIGNATURE); #if EFI_GPIO_HARDWARE @@ -41,7 +41,7 @@ public: /** * dissociates pin from this output and un-registers it in pin repository */ - void unregisterOutput(brain_pin_e oldPin, brain_pin_e newPin); + void unregisterOutput(brain_pin_e oldPin); bool isInitialized(); @@ -124,6 +124,7 @@ public: void stopInjectionPins(); void stopIgnitionPins(); OutputPin mainRelay; + OutputPin starterRelay; OutputPin fanRelay; // see acRelayPin OutputPin acRelay; diff --git a/firmware/controllers/scheduling/event_queue.cpp b/firmware/controllers/system/timer/event_queue.cpp similarity index 82% rename from firmware/controllers/scheduling/event_queue.cpp rename to firmware/controllers/system/timer/event_queue.cpp index d39cba69b5..47260cb044 100644 --- a/firmware/controllers/scheduling/event_queue.cpp +++ b/firmware/controllers/system/timer/event_queue.cpp @@ -30,7 +30,7 @@ EventQueue::EventQueue() { } bool EventQueue::checkIfPending(scheduling_s *scheduling) { - return assertNotInList(head, scheduling); + assertNotInListMethodBody(scheduling_s, head, scheduling, nextScheduling_s); } /** @@ -57,13 +57,12 @@ bool EventQueue::insertTask(scheduling_s *scheduling, efitime_t timeX, schfunc_t } scheduling->momentX = timeX; - scheduling->callback = callback; - scheduling->param = param; + scheduling->action.setAction(callback, param); scheduling->isScheduled = true; if (head == NULL || timeX < head->momentX) { // here we insert into head of the linked list - LL_PREPEND(head, scheduling); + LL_PREPEND2(head, scheduling, nextScheduling_s); #if EFI_UNIT_TEST assertListIsSorted(); #endif /* EFI_UNIT_TEST */ @@ -71,12 +70,12 @@ bool EventQueue::insertTask(scheduling_s *scheduling, efitime_t timeX, schfunc_t } else { // here we know we are not in the head of the list, let's find the position - linear search scheduling_s *insertPosition = head; - while (insertPosition->next != NULL && insertPosition->next->momentX < timeX) { - insertPosition = insertPosition->next; + while (insertPosition->nextScheduling_s != NULL && insertPosition->nextScheduling_s->momentX < timeX) { + insertPosition = insertPosition->nextScheduling_s; } - scheduling->next = insertPosition->next; - insertPosition->next = scheduling; + scheduling->nextScheduling_s = insertPosition->nextScheduling_s; + insertPosition->nextScheduling_s = scheduling; #if EFI_UNIT_TEST assertListIsSorted(); #endif /* EFI_UNIT_TEST */ @@ -132,9 +131,8 @@ int EventQueue::executeAll(efitime_t now) { int listIterationCounter = 0; int executionCounter = 0; // we need safe iteration because we are removing elements inside the loop - LL_FOREACH_SAFE(head, current, tmp) + LL_FOREACH_SAFE2(head, current, tmp, nextScheduling_s) { - efiAssert(CUSTOM_ERR_ASSERT, current->callback != NULL, "callback==null1", 0); if (++listIterationCounter > QUEUE_LENGTH_LIMIT) { firmwareError(CUSTOM_LIST_LOOP, "Is this list looped?"); return false; @@ -143,14 +141,14 @@ int EventQueue::executeAll(efitime_t now) { executionCounter++; efiAssert(CUSTOM_ERR_ASSERT, head == current, "removing from head", -1); //LL_DELETE(head, current); - head = head->next; + head = head->nextScheduling_s; if (executionList == NULL) { lastInExecutionList = executionList = current; } else { - lastInExecutionList->next = current; + lastInExecutionList->nextScheduling_s = current; lastInExecutionList = current; } - current->next = nullptr; + current->nextScheduling_s = nullptr; } else { /** * The list is sorted. Once we find one action in the future, all the remaining ones @@ -167,20 +165,18 @@ int EventQueue::executeAll(efitime_t now) { * we need safe iteration here because 'callback' might change change 'current->next' * while re-inserting it into the queue from within the callback */ - LL_FOREACH_SAFE(executionList, current, tmp) - { - efiAssert(CUSTOM_ERR_ASSERT, current->callback != NULL, "callback==null2", 0); + LL_FOREACH_SAFE2(executionList, current, tmp, nextScheduling_s) { uint32_t before = getTimeNowLowerNt(); current->isScheduled = false; uint32_t howFarOff = now - current->momentX; maxSchedulingPrecisionLoss = maxI(maxSchedulingPrecisionLoss, howFarOff); #if EFI_UNIT_TEST - printf("QUEUE: execute current=%d param=%d\r\n", (long)current, (long)current->param); + printf("QUEUE: execute current=%d param=%d\r\n", (long)current, (long)current->action.getArgument()); #endif { ScopePerf perf2(PE::EventQueueExecuteCallback); - current->callback(current->param); + current->action.execute(); } // even with overflow it's safe to subtract here @@ -198,16 +194,16 @@ int EventQueue::executeAll(efitime_t now) { int EventQueue::size(void) const { scheduling_s *tmp; int result; - LL_COUNT(head, tmp, result); + LL_COUNT2(head, tmp, result, nextScheduling_s); return result; } #if EFI_UNIT_TEST void EventQueue::assertListIsSorted() const { scheduling_s *current = head; - while (current != NULL && current->next != NULL) { - efiAssertVoid(CUSTOM_ERR_6623, current->momentX <= current->next->momentX, "list order"); - current = current->next; + while (current != NULL && current->nextScheduling_s != NULL) { + efiAssertVoid(CUSTOM_ERR_6623, current->momentX <= current->nextScheduling_s->momentX, "list order"); + current = current->nextScheduling_s; } } #endif @@ -220,10 +216,11 @@ scheduling_s * EventQueue::getHead() { return head; } -scheduling_s *EventQueue::getForUnitText(int index) { +// todo: reduce code duplication with another 'getElementAtIndexForUnitText' +scheduling_s *EventQueue::getElementAtIndexForUnitText(int index) { scheduling_s * current; - LL_FOREACH(head, current) + LL_FOREACH2(head, current, nextScheduling_s) { if (index == 0) return current; diff --git a/firmware/controllers/scheduling/event_queue.h b/firmware/controllers/system/timer/event_queue.h similarity index 50% rename from firmware/controllers/scheduling/event_queue.h rename to firmware/controllers/system/timer/event_queue.h index ba8a56cf07..d1789feb0a 100644 --- a/firmware/controllers/scheduling/event_queue.h +++ b/firmware/controllers/system/timer/event_queue.h @@ -18,29 +18,28 @@ #define QUEUE_LENGTH_LIMIT 1000 -template -bool assertNotInList(T *head, T*element) { - // this code is just to validate state, no functional load - T * current; - int counter = 0; - LL_FOREACH(head, current) - { - if (++counter > QUEUE_LENGTH_LIMIT) { - firmwareError(CUSTOM_ERR_LOOPED_QUEUE, "Looped queue?"); - return false; - } - if (current == element) { - /** - * for example, this might happen in case of sudden RPM change if event - * was not scheduled by angle but was scheduled by time. In case of scheduling - * by time with slow RPM the whole next fast revolution might be within the wait period - */ - warning(CUSTOM_RE_ADDING_INTO_EXECUTION_QUEUE, "re-adding element into event_queue"); - return true; - } - } +// templates do not accept field names so we use a macro here +#define assertNotInListMethodBody(T, head, element, field) \ + /* this code is just to validate state, no functional load*/ \ + T * current; \ + int counter = 0; \ + LL_FOREACH2(head, current, field) { \ + if (++counter > QUEUE_LENGTH_LIMIT) { \ + firmwareError(CUSTOM_ERR_LOOPED_QUEUE, "Looped queue?"); \ + return false; \ + } \ + if (current == element) { \ + /** \ + * for example, this might happen in case of sudden RPM change if event \ + * was not scheduled by angle but was scheduled by time. In case of scheduling \ + * by time with slow RPM the whole next fast revolution might be within the wait period \ + */ \ + warning(CUSTOM_RE_ADDING_INTO_EXECUTION_QUEUE, "re-adding element into event_queue"); \ + return true; \ + } \ + } \ return false; -} + /** * Execution sorted linked list @@ -59,7 +58,7 @@ public: efitime_t getNextEventTime(efitime_t nowUs) const; void clear(void); int size(void) const; - scheduling_s *getForUnitText(int index); + scheduling_s *getElementAtIndexForUnitText(int index); void setLateDelay(int value); scheduling_s * getHead(); void assertListIsSorted() const; diff --git a/firmware/controllers/scheduling/pwm_generator_logic.cpp b/firmware/controllers/system/timer/pwm_generator_logic.cpp similarity index 88% rename from firmware/controllers/scheduling/pwm_generator_logic.cpp rename to firmware/controllers/system/timer/pwm_generator_logic.cpp index eb4a07187a..c56e38d566 100644 --- a/firmware/controllers/scheduling/pwm_generator_logic.cpp +++ b/firmware/controllers/system/timer/pwm_generator_logic.cpp @@ -12,7 +12,6 @@ #include "os_access.h" #include "pwm_generator_logic.h" #include "pwm_generator.h" -#include "error_handling.h" #include "perf_trace.h" /** @@ -49,12 +48,12 @@ PwmConfig::PwmConfig() { arg = this; } -PwmConfig::PwmConfig(float *st, SingleWave *waves) : PwmConfig() { - multiWave.init(st, waves); +PwmConfig::PwmConfig(float *st, SingleChannelStateSequence *waves) : PwmConfig() { + multiChannelStateSequence.init(st, waves); } -void PwmConfig::init(float *st, SingleWave *waves) { - multiWave.init(st, waves); +void PwmConfig::init(float *st, SingleChannelStateSequence *waves) { + multiChannelStateSequence.init(st, waves); } /** @@ -92,7 +91,7 @@ void SimplePwm::setSimplePwmDutyCycle(float dutyCycle) { mode = PM_FULL; } else { mode = PM_NORMAL; - multiWave.setSwitchTime(0, dutyCycle); + multiChannelStateSequence.setSwitchTime(0, dutyCycle); } } @@ -103,7 +102,7 @@ static efitimeus_t getNextSwitchTimeUs(PwmConfig *state) { efiAssert(CUSTOM_ERR_ASSERT, state->safe.phaseIndex < PWM_PHASE_MAX_COUNT, "phaseIndex range", 0); int iteration = state->safe.iteration; // we handle PM_ZERO and PM_FULL separately - float switchTime = state->mode == PM_NORMAL ? state->multiWave.getSwitchTime(state->safe.phaseIndex) : 1; + float switchTime = state->mode == PM_NORMAL ? state->multiChannelStateSequence.getSwitchTime(state->safe.phaseIndex) : 1; float periodNt = state->safe.periodNt; #if DEBUG_PWM scheduleMsg(&logger, "iteration=%d switchTime=%.2f period=%.2f", iteration, switchTime, period); @@ -138,10 +137,15 @@ void PwmConfig::stop() { } void PwmConfig::handleCycleStart() { - efiAssertVoid(CUSTOM_ERR_6697, safe.phaseIndex == 0, "handleCycleStart"); - if (pwmCycleCallback != NULL) { - pwmCycleCallback(this); - } + if (safe.phaseIndex != 0) { + // https://github.com/rusefi/rusefi/issues/1030 + firmwareError(CUSTOM_PWM_CYCLE_START, "handleCycleStart %d", safe.phaseIndex); + return; + } + + if (pwmCycleCallback != NULL) { + pwmCycleCallback(this); + } efiAssertVoid(CUSTOM_ERR_6580, periodNt != 0, "period not initialized"); if (safe.periodNt != periodNt || safe.iteration == ITERATION_LIMIT) { /** @@ -254,7 +258,7 @@ static void timerCallback(PwmConfig *state) { return; } if (state->executor == NULL) { - firmwareError(CUSTOM_ERR_6695, "exec on %s", state->name); + firmwareError(CUSTOM_NULL_EXECUTOR, "exec on %s", state->name); return; } @@ -270,17 +274,17 @@ void copyPwmParameters(PwmConfig *state, int phaseCount, float const *switchTime state->phaseCount = phaseCount; for (int phaseIndex = 0; phaseIndex < phaseCount; phaseIndex++) { - state->multiWave.setSwitchTime(phaseIndex, switchTimes[phaseIndex]); + state->multiChannelStateSequence.setSwitchTime(phaseIndex, switchTimes[phaseIndex]); for (int channelIndex = 0; channelIndex < waveCount; channelIndex++) { // print("output switch time index (%d/%d) at %.2f to %d\r\n", phaseIndex, channelIndex, // switchTimes[phaseIndex], pinStates[waveIndex][phaseIndex]); pin_state_t value = pinStates[channelIndex][phaseIndex]; - state->multiWave.channels[channelIndex].setState(phaseIndex, value); + state->multiChannelStateSequence.channels[channelIndex].setState(phaseIndex, value); } } if (state->mode == PM_NORMAL) { - state->multiWave.checkSwitchTimes(phaseCount); + state->multiChannelStateSequence.checkSwitchTimes(phaseCount); } } @@ -311,7 +315,7 @@ void PwmConfig::weComplexInit(const char *msg, ExecutorInterface *executor, this->pwmCycleCallback = pwmCycleCallback; this->stateChangeCallback = stateChangeCallback; - multiWave.waveCount = waveCount; + multiChannelStateSequence.waveCount = waveCount; copyPwmParameters(this, phaseCount, switchTimes, waveCount, pinStates); @@ -362,10 +366,10 @@ void startSimplePwmExt(SimplePwm *state, const char *msg, */ void applyPinState(int stateIndex, PwmConfig *state) /* pwm_gen_callback */ { efiAssertVoid(CUSTOM_ERR_6663, stateIndex < PWM_PHASE_MAX_COUNT, "invalid stateIndex"); - efiAssertVoid(CUSTOM_ERR_6664, state->multiWave.waveCount <= PWM_PHASE_MAX_WAVE_PER_PWM, "invalid waveCount"); - for (int channelIndex = 0; channelIndex < state->multiWave.waveCount; channelIndex++) { + efiAssertVoid(CUSTOM_ERR_6664, state->multiChannelStateSequence.waveCount <= PWM_PHASE_MAX_WAVE_PER_PWM, "invalid waveCount"); + for (int channelIndex = 0; channelIndex < state->multiChannelStateSequence.waveCount; channelIndex++) { OutputPin *output = state->outputPins[channelIndex]; - int value = state->multiWave.getChannelState(channelIndex, stateIndex); + int value = state->multiChannelStateSequence.getChannelState(channelIndex, stateIndex); output->setValue(value); } } diff --git a/firmware/controllers/scheduling/pwm_generator_logic.h b/firmware/controllers/system/timer/pwm_generator_logic.h similarity index 92% rename from firmware/controllers/scheduling/pwm_generator_logic.h rename to firmware/controllers/system/timer/pwm_generator_logic.h index ab13b6ac12..f0f9e055fa 100644 --- a/firmware/controllers/scheduling/pwm_generator_logic.h +++ b/firmware/controllers/system/timer/pwm_generator_logic.h @@ -8,8 +8,8 @@ #ifndef PWM_GENERATOR_LOGIC_H_ #define PWM_GENERATOR_LOGIC_H_ +#include "state_sequence.h" #include "global.h" -#include "efi_wave.h" #include "scheduler.h" #include "efi_gpio.h" @@ -54,8 +54,8 @@ typedef enum { class PwmConfig { public: PwmConfig(); - PwmConfig(float *switchTimes, SingleWave *waves); - void init(float *switchTimes, SingleWave *waves); + PwmConfig(float *switchTimes, SingleChannelStateSequence *waves); + void init(float *switchTimes, SingleChannelStateSequence *waves); void *arg = nullptr; void weComplexInit(const char *msg, @@ -82,7 +82,7 @@ public: // todo: 'outputPins' should be extracted away from here since technically one can want PWM scheduler without actual pin output OutputPin *outputPins[PWM_PHASE_MAX_WAVE_PER_PWM]; - MultiWave multiWave; + MultiChannelStateSequence multiChannelStateSequence; efitimeus_t togglePwmState(); void stop(); @@ -120,10 +120,10 @@ public: explicit SimplePwm(const char *name); void setSimplePwmDutyCycle(float dutyCycle); pin_state_t pinStates[2]; - SingleWave sr[1]; + SingleChannelStateSequence sr[1]; float _switchTimes[2]; private: - SingleWave waveInstance; + SingleChannelStateSequence waveInstance; }; /** diff --git a/firmware/controllers/system/timer/readme.md b/firmware/controllers/system/timer/readme.md new file mode 100644 index 0000000000..6a21cb6bbc --- /dev/null +++ b/firmware/controllers/system/timer/readme.md @@ -0,0 +1 @@ +In this folder we have files related to hubrid hardware/software timer, including PWM generation. \ No newline at end of file diff --git a/firmware/controllers/scheduling/scheduler.h b/firmware/controllers/system/timer/scheduler.h similarity index 71% rename from firmware/controllers/scheduling/scheduler.h rename to firmware/controllers/system/timer/scheduler.h index 44e5f7adf9..17935acf9e 100644 --- a/firmware/controllers/scheduling/scheduler.h +++ b/firmware/controllers/system/timer/scheduler.h @@ -2,7 +2,7 @@ * @file scheduler.h * * @date May 18, 2014 - * @author Andrey Belomutskiy, (c) 2012-2017 + * @author Andrey Belomutskiy, (c) 2012-2019 */ #pragma once @@ -10,6 +10,18 @@ typedef void (*schfunc_t)(void *); +class action_s { +public: + void setAction(schfunc_t callback, void *param); + void execute(); + schfunc_t getCallback() const; + void * getArgument() const; + +private: + schfunc_t callback = nullptr; + void *param = nullptr; +}; + /** * This structure holds information about an event scheduled in the future: when to execute what callback with what parameters */ @@ -26,12 +38,11 @@ public: bool isScheduled = false; /** - * Scheduler implementation has a linked list of these scheduling records. + * Scheduler implementation uses a sorted linked list of these scheduling records. */ - scheduling_s *next = nullptr; + scheduling_s *nextScheduling_s = nullptr; - schfunc_t callback = nullptr; - void *param = nullptr; + action_s action; }; class ExecutorInterface { diff --git a/firmware/controllers/scheduling/signal_executor_sleep.cpp b/firmware/controllers/system/timer/signal_executor_sleep.cpp similarity index 93% rename from firmware/controllers/scheduling/signal_executor_sleep.cpp rename to firmware/controllers/system/timer/signal_executor_sleep.cpp index be5af50a9c..f08d30a608 100644 --- a/firmware/controllers/scheduling/signal_executor_sleep.cpp +++ b/firmware/controllers/system/timer/signal_executor_sleep.cpp @@ -39,16 +39,15 @@ void SleepExecutor::scheduleByTimestamp(scheduling_s *scheduling, efitimeus_t ti static void timerCallback(scheduling_s *scheduling) { #if EFI_PRINTF_FUEL_DETAILS - if (scheduling->callback == (schfunc_t)&seTurnPinLow) { - printf("executing cb=seTurnPinLow p=%d sch=%d now=%d\r\n", (int)scheduling->param, (int)scheduling, + if (scheduling->action.getCallback() == (schfunc_t)&seTurnPinLow) { + printf("executing cb=seTurnPinLow p=%d sch=%d now=%d\r\n", (int)scheduling->action.getArgument(), (int)scheduling, (int)getTimeNowUs()); } else { // printf("exec cb=%d p=%d\r\n", (int)scheduling->callback, (int)scheduling->param); } #endif /* EFI_SIMULATOR */ - scheduling->callback(scheduling->param); - + scheduling->action.execute(); } static void doScheduleForLater(scheduling_s *scheduling, int delayUs, schfunc_t callback, void *param) { @@ -62,8 +61,7 @@ static void doScheduleForLater(scheduling_s *scheduling, int delayUs, schfunc_t } bool alreadyLocked = lockAnyContext(); - scheduling->callback = callback; - scheduling->param = param; + scheduling->action.setAction(callback, param); int isArmed = chVTIsArmedI(&scheduling->timer); if (isArmed) { /** diff --git a/firmware/controllers/scheduling/signal_executor_sleep.h b/firmware/controllers/system/timer/signal_executor_sleep.h similarity index 100% rename from firmware/controllers/scheduling/signal_executor_sleep.h rename to firmware/controllers/system/timer/signal_executor_sleep.h diff --git a/firmware/controllers/scheduling/single_timer_executor.cpp b/firmware/controllers/system/timer/single_timer_executor.cpp similarity index 100% rename from firmware/controllers/scheduling/single_timer_executor.cpp rename to firmware/controllers/system/timer/single_timer_executor.cpp diff --git a/firmware/controllers/scheduling/single_timer_executor.h b/firmware/controllers/system/timer/single_timer_executor.h similarity index 89% rename from firmware/controllers/scheduling/single_timer_executor.h rename to firmware/controllers/system/timer/single_timer_executor.h index 49461ab8d8..cb844c3d76 100644 --- a/firmware/controllers/scheduling/single_timer_executor.h +++ b/firmware/controllers/system/timer/single_timer_executor.h @@ -14,8 +14,8 @@ class SingleTimerExecutor : public ExecutorInterface { public: SingleTimerExecutor(); - void scheduleByTimestamp(scheduling_s *scheduling, efitimeus_t timeUs, schfunc_t callback, void *param); - void scheduleForLater(scheduling_s *scheduling, int delayUs, schfunc_t callback, void *param); + void scheduleByTimestamp(scheduling_s *scheduling, efitimeus_t timeUs, schfunc_t callback, void *param) override; + void scheduleForLater(scheduling_s *scheduling, int delayUs, schfunc_t callback, void *param) override; void onTimerCallback(); int timerCallbackCounter; int scheduleCounter; diff --git a/firmware/controllers/system_fsio.h b/firmware/controllers/system_fsio.h index 4b808a71b9..d316277fc0 100644 --- a/firmware/controllers/system_fsio.h +++ b/firmware/controllers/system_fsio.h @@ -68,7 +68,7 @@ // starter block using configurable parameter // Human-readable: rpm < cranking_rpm -#define STARTER_BLOCK "rpm cranking_rpm <" +#define STARTER_RELAY_LOGIC "rpm cranking_rpm <" // Human-readable: fsio_table (3, rpm, map) / 100 #define BOOST_CONTROLLER "3 rpm map fsio_table 100 /" diff --git a/firmware/controllers/system_fsio.txt b/firmware/controllers/system_fsio.txt index fc2761e3ff..8a6148ca9f 100644 --- a/firmware/controllers/system_fsio.txt +++ b/firmware/controllers/system_fsio.txt @@ -46,7 +46,7 @@ RPM_ABOVE_6000_SOLENOID_80_DUTY=(rpm > 6000) * 0.8 RPM_BELOW_USER_SETTING_1=rpm < fsio_setting(1) # starter block using configurable parameter -STARTER_BLOCK=rpm < cranking_rpm +STARTER_RELAY_LOGIC=rpm < cranking_rpm BOOST_CONTROLLER=fsio_table (3, rpm, map) / 100 diff --git a/firmware/controllers/trigger/aux_valves.cpp b/firmware/controllers/trigger/aux_valves.cpp deleted file mode 100644 index 5efcbff995..0000000000 --- a/firmware/controllers/trigger/aux_valves.cpp +++ /dev/null @@ -1,111 +0,0 @@ -/* - * aux_valves.cpp - * - * - * Here we have two auxilary digital on/off outputs which would open once per each 360 degrees of engine crank revolution. - * The second valve is 180 degrees after the first one. - * - * Valve open and close angles are taken from fsioCurve1 and fsioCurve2 tables respectively, the position depend on TPS input. - * - * https://github.com/rusefi/rusefi/issues/490 - * - * @date Nov 25, 2017 - * @author Andrey Belomutskiy, (c) 2012-2018 - */ - -#include "engine_math.h" -#include "aux_valves.h" -#include "allsensors.h" -#include "trigger_central.h" - -EXTERN_ENGINE -; - -static scheduling_s turnOnEvent[AUX_DIGITAL_VALVE_COUNT][2]; -static scheduling_s turnOffEvent[AUX_DIGITAL_VALVE_COUNT][2]; - -static void turnOn(NamedOutputPin *output) { - output->setHigh(); -} - -static void turnOff(NamedOutputPin *output) { - output->setLow(); -} - -#define SCHEDULING_TRIGGER_INDEX 2 - -static void auxValveTriggerCallback(trigger_event_e ckpSignalType, - uint32_t index DECLARE_ENGINE_PARAMETER_SUFFIX) { - UNUSED(ckpSignalType); - - if (index != SCHEDULING_TRIGGER_INDEX) { - return; - } - int rpm = GET_RPM_VALUE; - if (!isValidRpm(rpm)) { - return; - } - - for (int valveIndex = 0; valveIndex < AUX_DIGITAL_VALVE_COUNT; valveIndex++) { - - NamedOutputPin *output = &enginePins.auxValve[valveIndex]; - - for (int phaseIndex = 0; phaseIndex < 2; phaseIndex++) { -/* I believe a more correct implementation is the following: - * here we properly account for trigger angle position in engine cycle coordinates - // todo: at the moment this logic is assuming four-stroke 720-degree engine cycle - angle_t extra = phaseIndex * 360 // cycle opens twice per 720 engine cycle - + valveIndex * 180 // 2nd valve is operating at 180 offset to first - + tdcPosition() // engine cycle position to trigger cycle position conversion - - ENGINE(triggerCentral.triggerShape.eventAngles[SCHEDULING_TRIGGER_INDEX]) - ; -*/ - angle_t extra = phaseIndex * 360 + valveIndex * 180; - angle_t onTime = extra + engine->engineState.auxValveStart; - fixAngle(onTime, "onTime", CUSTOM_ERR_6556); - scheduleByAngle(rpm, &turnOnEvent[valveIndex][phaseIndex], - onTime, - (schfunc_t) &turnOn, output PASS_ENGINE_PARAMETER_SUFFIX); - angle_t offTime = extra + engine->engineState.auxValveEnd; - fixAngle(offTime, "offTime", CUSTOM_ERR_6557); - scheduleByAngle(rpm, &turnOffEvent[valveIndex][phaseIndex], - offTime, - (schfunc_t) &turnOff, output PASS_ENGINE_PARAMETER_SUFFIX); - } - } -} - -void initAuxValves(Logging *sharedLogger DECLARE_ENGINE_PARAMETER_SUFFIX) { - UNUSED(sharedLogger); - if (engineConfiguration->auxValves[0] == GPIO_UNASSIGNED) { - return; - } - addTriggerEventListener(auxValveTriggerCallback, "tach", engine); -} - -void updateAuxValves(DECLARE_ENGINE_PARAMETER_SIGNATURE) { - if (engineConfiguration->auxValves[0] == GPIO_UNASSIGNED) { - return; - } - - float x = getTPS(PASS_ENGINE_PARAMETER_SIGNATURE); - if (cisnan(x)) { - // error should be already reported by now - return; - } - engine->engineState.auxValveStart = interpolate2d("aux", x, - engineConfiguration->fsioCurve1Bins, - engineConfiguration->fsioCurve1); - - engine->engineState.auxValveEnd = interpolate2d("aux", x, - engineConfiguration->fsioCurve2Bins, - engineConfiguration->fsioCurve2); - - if (engine->engineState.auxValveStart >= engine->engineState.auxValveEnd) { - // this is a fatal error to make this really visible - firmwareError(CUSTOM_AUX_OUT_OF_ORDER, "out of order at %.2f %.2f %.2f", x, - engine->engineState.auxValveStart, - engine->engineState.auxValveEnd); - } -} - diff --git a/firmware/controllers/trigger/aux_valves.h b/firmware/controllers/trigger/aux_valves.h deleted file mode 100644 index 172b488cff..0000000000 --- a/firmware/controllers/trigger/aux_valves.h +++ /dev/null @@ -1,16 +0,0 @@ -/* - * aux_valves.h - * - * @date Nov 25, 2017 - * @author Andrey Belomutskiy, (c) 2012-2017 - */ - -#ifndef CONTROLLERS_TRIGGER_AUX_VALVES_H_ -#define CONTROLLERS_TRIGGER_AUX_VALVES_H_ - -#include "engine.h" - -void initAuxValves(Logging *sharedLogger DECLARE_ENGINE_PARAMETER_SUFFIX); -void updateAuxValves(DECLARE_ENGINE_PARAMETER_SIGNATURE); - -#endif /* CONTROLLERS_TRIGGER_AUX_VALVES_H_ */ diff --git a/firmware/controllers/trigger/decoders/trigger_bmw.cpp b/firmware/controllers/trigger/decoders/trigger_bmw.cpp index 1e22772f9d..60e10ef343 100644 --- a/firmware/controllers/trigger/decoders/trigger_bmw.cpp +++ b/firmware/controllers/trigger/decoders/trigger_bmw.cpp @@ -7,7 +7,7 @@ #include "trigger_bmw.h" -static inline float addPair(TriggerShape *s, float a, float w) { +static inline float addPair(TriggerWaveform *s, float a, float w) { s->addEvent720(a, T_SECONDARY, TV_RISE); a += w; s->addEvent720(a, T_SECONDARY, TV_FALL); @@ -15,7 +15,7 @@ static inline float addPair(TriggerShape *s, float a, float w) { return a; } -void configureMiniCooperTriggerShape(TriggerShape *s) { +void configureMiniCooperTriggerWaveform(TriggerWaveform *s) { s->initialize(FOUR_STROKE_CAM_SENSOR, true); // s->initialState[0] = 1; diff --git a/firmware/controllers/trigger/decoders/trigger_bmw.h b/firmware/controllers/trigger/decoders/trigger_bmw.h index ae6ef6a3c1..9c75b8f002 100644 --- a/firmware/controllers/trigger/decoders/trigger_bmw.h +++ b/firmware/controllers/trigger/decoders/trigger_bmw.h @@ -9,5 +9,5 @@ #include "trigger_structure.h" -void configureMiniCooperTriggerShape(TriggerShape *s); +void configureMiniCooperTriggerWaveform(TriggerWaveform *s); diff --git a/firmware/controllers/trigger/decoders/trigger_chrysler.cpp b/firmware/controllers/trigger/decoders/trigger_chrysler.cpp index 3decbd5294..61c4f035e5 100644 --- a/firmware/controllers/trigger/decoders/trigger_chrysler.cpp +++ b/firmware/controllers/trigger/decoders/trigger_chrysler.cpp @@ -8,7 +8,7 @@ #include "trigger_chrysler.h" #include "trigger_universal.h" -void initDodgeRam(TriggerShape *s) { +void initDodgeRam(TriggerWaveform *s) { s->initialize(FOUR_STROKE_CAM_SENSOR, true); s->useRiseEdge = true; @@ -25,7 +25,7 @@ void initDodgeRam(TriggerShape *s) { s->useOnlyPrimaryForSync = true; } -void configureNeon2003TriggerShapeCrank(TriggerShape *s DECLARE_ENGINE_PARAMETER_SUFFIX) { +void configureNeon2003TriggerWaveformCrank(TriggerWaveform *s DECLARE_ENGINE_PARAMETER_SUFFIX) { s->initialize(FOUR_STROKE_CRANK_SENSOR, false); s->useRiseEdge = true; @@ -99,7 +99,7 @@ void configureNeon2003TriggerShapeCrank(TriggerShape *s DECLARE_ENGINE_PARAMETER s->addEvent720(m * 360, T_PRIMARY, TV_RISE); } -void configureNeon2003TriggerShapeCam(TriggerShape *s) { +void configureNeon2003TriggerWaveformCam(TriggerWaveform *s) { // todo: move sync point so that two channel does not have false trigger issues bool useOnlyPrimary = true; @@ -322,7 +322,7 @@ gap=1.43/0.71 } } -void configureDodgeStratusTriggerShape(TriggerShape *s) { +void configureDodgeStratusTriggerWaveform(TriggerWaveform *s) { s->initialize(FOUR_STROKE_CAM_SENSOR, false); s->isSynchronizationNeeded = true; @@ -388,7 +388,7 @@ void configureDodgeStratusTriggerShape(TriggerShape *s) { s->addEvent720(angle + w, T_PRIMARY, TV_FALL); } -static void configureNeon1995TriggerShapeCommon(bool withCam, TriggerShape *s) { +static void configureNeon1995TriggerWaveformCommon(bool withCam, TriggerWaveform *s) { trigger_wheel_e crank = withCam ? T_SECONDARY : T_PRIMARY; // voodoo magic - we always need 720 at the end @@ -448,17 +448,17 @@ static void configureNeon1995TriggerShapeCommon(bool withCam, TriggerShape *s) { } } -void configureNeon1995TriggerShapeOnlyCrank(TriggerShape *s) { +void configureNeon1995TriggerWaveformOnlyCrank(TriggerWaveform *s) { s->initialize(FOUR_STROKE_CRANK_SENSOR, false); s->setTriggerSynchronizationGap(3.79); s->tdcPosition = 279; - configureNeon1995TriggerShapeCommon(false, s); + configureNeon1995TriggerWaveformCommon(false, s); } -void configureNeon1995TriggerShape(TriggerShape *s) { +void configureNeon1995TriggerWaveform(TriggerWaveform *s) { s->initialize(FOUR_STROKE_CAM_SENSOR, true); s->setTriggerSynchronizationGap(0.8227); @@ -468,12 +468,12 @@ void configureNeon1995TriggerShape(TriggerShape *s) { s->initialState[T_PRIMARY] = TV_RISE; - configureNeon1995TriggerShapeCommon(true, s); + configureNeon1995TriggerWaveformCommon(true, s); s->useOnlyPrimaryForSync = true; } -void initJeep18_2_2_2(TriggerShape *s) { +void initJeep18_2_2_2(TriggerWaveform *s) { s->initialize(FOUR_STROKE_CAM_SENSOR, true); s->isSynchronizationNeeded = true; s->setTriggerSynchronizationGap(1); @@ -543,7 +543,7 @@ void initJeep18_2_2_2(TriggerShape *s) { } -static void add4cylblock(int off, TriggerShape *s) { +static void add4cylblock(int off, TriggerWaveform *s) { s->addEvent720(114 + off, T_SECONDARY, TV_RISE); s->addEvent720(114 + off + 2, T_SECONDARY, TV_FALL); @@ -558,7 +558,7 @@ static void add4cylblock(int off, TriggerShape *s) { } // TT_JEEP_4_CYL -void initJeep_XJ_4cyl_2500(TriggerShape *s) { +void initJeep_XJ_4cyl_2500(TriggerWaveform *s) { s->initialize(FOUR_STROKE_CAM_SENSOR, true); s->isSynchronizationNeeded = true; s->setTriggerSynchronizationGap(1); diff --git a/firmware/controllers/trigger/decoders/trigger_chrysler.h b/firmware/controllers/trigger/decoders/trigger_chrysler.h index c766487ad5..1ebcb1f35e 100644 --- a/firmware/controllers/trigger/decoders/trigger_chrysler.h +++ b/firmware/controllers/trigger/decoders/trigger_chrysler.h @@ -13,16 +13,16 @@ #define CHRYSLER_NGC4_GAP 1 #define CHRYSLER_NGC6_GAP 1.5 -void configureNeon1995TriggerShape(TriggerShape *s); -void configureNeon1995TriggerShapeOnlyCrank(TriggerShape *s); +void configureNeon1995TriggerWaveform(TriggerWaveform *s); +void configureNeon1995TriggerWaveformOnlyCrank(TriggerWaveform *s); -void configureNeon2003TriggerShapeCam(TriggerShape *s); -void configureNeon2003TriggerShapeCrank(TriggerShape *s); -void initDodgeRam(TriggerShape *s); +void configureNeon2003TriggerWaveformCam(TriggerWaveform *s); +void configureNeon2003TriggerWaveformCrank(TriggerWaveform *s); +void initDodgeRam(TriggerWaveform *s); -void configureDodgeStratusTriggerShape(TriggerShape *s); +void configureDodgeStratusTriggerWaveform(TriggerWaveform *s); -void initJeep18_2_2_2(TriggerShape *s); -void initJeep_XJ_4cyl_2500(TriggerShape *s); +void initJeep18_2_2_2(TriggerWaveform *s); +void initJeep_XJ_4cyl_2500(TriggerWaveform *s); #endif /* TRIGGER_CHRYSLER_H_ */ diff --git a/firmware/controllers/trigger/decoders/trigger_gm.cpp b/firmware/controllers/trigger/decoders/trigger_gm.cpp index ac381740f4..5f47bba6d6 100644 --- a/firmware/controllers/trigger/decoders/trigger_gm.cpp +++ b/firmware/controllers/trigger/decoders/trigger_gm.cpp @@ -7,7 +7,7 @@ #include "trigger_gm.h" -void configureGmTriggerShape(TriggerShape *s) { +void configureGmTriggerWaveform(TriggerWaveform *s) { s->initialize(FOUR_STROKE_CRANK_SENSOR, false); // all angles are x2 here - so, 5 degree width is 10 @@ -39,7 +39,7 @@ void configureGmTriggerShape(TriggerShape *s) { s->setTriggerSynchronizationGap(6); } -static int gm_tooth_pair(float startAngle, bool isShortLong, TriggerShape* s, int mult) +static int gm_tooth_pair(float startAngle, bool isShortLong, TriggerWaveform* s, int mult) { int window = (isShortLong ? 5 : 10) * mult; int end = startAngle + mult * 15; @@ -59,7 +59,7 @@ static int gm_tooth_pair(float startAngle, bool isShortLong, TriggerShape* s, in * * based on data in https://rusefi.com/forum/viewtopic.php?f=3&t=936&p=30303#p30285 */ -void initGmLS24(TriggerShape *s) { +void initGmLS24(TriggerWaveform *s) { s->initialize(FOUR_STROKE_CRANK_SENSOR, false); /* diff --git a/firmware/controllers/trigger/decoders/trigger_gm.h b/firmware/controllers/trigger/decoders/trigger_gm.h index 53cca74206..895f3526b9 100644 --- a/firmware/controllers/trigger/decoders/trigger_gm.h +++ b/firmware/controllers/trigger/decoders/trigger_gm.h @@ -10,7 +10,7 @@ #include "trigger_structure.h" -void configureGmTriggerShape(TriggerShape *s); -void initGmLS24(TriggerShape *s); +void configureGmTriggerWaveform(TriggerWaveform *s); +void initGmLS24(TriggerWaveform *s); #endif /* TRIGGER_GM_H_ */ diff --git a/firmware/controllers/trigger/decoders/trigger_honda.cpp b/firmware/controllers/trigger/decoders/trigger_honda.cpp index 8841417cd9..a2b926e8f5 100644 --- a/firmware/controllers/trigger/decoders/trigger_honda.cpp +++ b/firmware/controllers/trigger/decoders/trigger_honda.cpp @@ -10,7 +10,7 @@ #define S24 (720.0f / 24 / 2) -static float addAccordPair(TriggerShape *s, float sb, trigger_wheel_e const channelIndex) { +static float addAccordPair(TriggerWaveform *s, float sb, trigger_wheel_e const channelIndex) { s->addEvent720(sb, channelIndex, TV_RISE); sb += S24; s->addEvent720(sb, channelIndex, TV_FALL); @@ -20,7 +20,7 @@ static float addAccordPair(TriggerShape *s, float sb, trigger_wheel_e const chan } #define DIP 7.5f -static float addAccordPair3(TriggerShape *s, float sb) { +static float addAccordPair3(TriggerWaveform *s, float sb) { sb += DIP; s->addEvent720(sb, T_CHANNEL_3, TV_RISE); sb += DIP; @@ -33,7 +33,7 @@ static float addAccordPair3(TriggerShape *s, float sb) { * Thank you Dip! * http://forum.pgmfi.org/viewtopic.php?f=2&t=15570start=210#p139007 */ -void configureHondaAccordCDDip(TriggerShape *s) { +void configureHondaAccordCDDip(TriggerWaveform *s) { s->initialize(FOUR_STROKE_CAM_SENSOR, true); s->initialState[T_SECONDARY] = TV_RISE; @@ -102,7 +102,7 @@ void configureHondaAccordCDDip(TriggerShape *s) { * '4' is conditional * '24' is always secondary channel */ -void configureHonda_1_4_24(TriggerShape *s, bool withOneEventSignal, bool withFourEventSignal, +void configureHonda_1_4_24(TriggerWaveform *s, bool withOneEventSignal, bool withFourEventSignal, trigger_wheel_e const oneEventWave, trigger_wheel_e const fourEventWave, float prefix) { @@ -166,7 +166,7 @@ void configureHonda_1_4_24(TriggerShape *s, bool withOneEventSignal, bool withFo s->useOnlyPrimaryForSync = true; } -void configureHondaCbr600(TriggerShape *s) { +void configureHondaCbr600(TriggerWaveform *s) { s->initialize(FOUR_STROKE_CAM_SENSOR, true); s->useOnlyPrimaryForSync = true; s->isSynchronizationNeeded = true; @@ -209,7 +209,7 @@ void configureHondaCbr600(TriggerShape *s) { s->addEvent720(720.0f, T_PRIMARY, TV_RISE); } -void configureHondaCbr600custom(TriggerShape *s) { +void configureHondaCbr600custom(TriggerWaveform *s) { // w = 15 float w = 720 / 2 / 24; @@ -283,7 +283,7 @@ void configureHondaCbr600custom(TriggerShape *s) { } -void configureHondaAccordShifted(TriggerShape *s) { +void configureHondaAccordShifted(TriggerWaveform *s) { s->initialize(FOUR_STROKE_CAM_SENSOR, true); float sb = S24; @@ -314,7 +314,7 @@ void configureHondaAccordShifted(TriggerShape *s) { s->isSynchronizationNeeded = false; } -void configureOnePlus16(TriggerShape *s, operation_mode_e operationMode) { +void configureOnePlus16(TriggerWaveform *s, operation_mode_e operationMode) { UNUSED(operationMode); s->initialize(FOUR_STROKE_CAM_SENSOR, true); diff --git a/firmware/controllers/trigger/decoders/trigger_honda.h b/firmware/controllers/trigger/decoders/trigger_honda.h index 365a46b9d8..a469d95661 100644 --- a/firmware/controllers/trigger/decoders/trigger_honda.h +++ b/firmware/controllers/trigger/decoders/trigger_honda.h @@ -10,17 +10,17 @@ #include "trigger_structure.h" -void configureHondaAccordCDDip(TriggerShape *s); -void configureHondaAccordShifted(TriggerShape *s); +void configureHondaAccordCDDip(TriggerWaveform *s); +void configureHondaAccordShifted(TriggerWaveform *s); -void configureHonda_1_4_24(TriggerShape *s, bool withOneEventSignal, bool withFourEventSignal, +void configureHonda_1_4_24(TriggerWaveform *s, bool withOneEventSignal, bool withFourEventSignal, trigger_wheel_e const oneEventWave, trigger_wheel_e const fourEventWave, float d); -void configureOnePlus16(TriggerShape *s, operation_mode_e operationMode); +void configureOnePlus16(TriggerWaveform *s, operation_mode_e operationMode); -void configureHondaCbr600(TriggerShape *s); -void configureHondaCbr600custom(TriggerShape *s); +void configureHondaCbr600(TriggerWaveform *s); +void configureHondaCbr600custom(TriggerWaveform *s); #endif /* CONTROLLERS_TRIGGER_TRIGGER_HONDA_H_ */ diff --git a/firmware/controllers/trigger/decoders/trigger_mazda.cpp b/firmware/controllers/trigger/decoders/trigger_mazda.cpp index cb15e7d0c2..9a4f48dfa6 100644 --- a/firmware/controllers/trigger/decoders/trigger_mazda.cpp +++ b/firmware/controllers/trigger/decoders/trigger_mazda.cpp @@ -20,7 +20,7 @@ #include "trigger_mazda.h" -void initializeMazdaMiataNaShape(TriggerShape *s) { +void initializeMazdaMiataNaShape(TriggerWaveform *s) { s->initialize(FOUR_STROKE_CAM_SENSOR, true); s->setTriggerSynchronizationGap2(1.4930 * 0.6f, 1.4930 * 1.3f); s->useRiseEdge = false; @@ -56,7 +56,7 @@ void initializeMazdaMiataNaShape(TriggerShape *s) { * by alexander-n8hgeg5e * See https://rusefi.com/forum/viewtopic.php?f=5&t=1447 */ -void initialize_Mazda_Engine_z5_Shape(TriggerShape *s) { +void initialize_Mazda_Engine_z5_Shape(TriggerWaveform *s) { s->initialize(FOUR_STROKE_CAM_SENSOR, false); /** * My Signal is: 60, 60, 102, 60 @@ -87,7 +87,7 @@ void initialize_Mazda_Engine_z5_Shape(TriggerShape *s) { } // TT_MIATA_VVT -void initializeMazdaMiataNb2Crank(TriggerShape *s) { +void initializeMazdaMiataNb2Crank(TriggerWaveform *s) { s->initialize(FOUR_STROKE_SYMMETRICAL_CRANK_SENSOR, false); float o = 160; @@ -101,7 +101,7 @@ void initializeMazdaMiataNb2Crank(TriggerShape *s) { s->addEvent720(o + 4 * 140.0f, T_PRIMARY, TV_RISE); } -static void initializeMazdaMiataNb1ShapeWithOffset(TriggerShape *s, float offset) { +static void initializeMazdaMiataNb1ShapeWithOffset(TriggerWaveform *s, float offset) { s->initialize(FOUR_STROKE_CAM_SENSOR, true); s->setTriggerSynchronizationGap3(0, 0.065, 0.17f); s->useRiseEdge = false; @@ -143,15 +143,15 @@ static void initializeMazdaMiataNb1ShapeWithOffset(TriggerShape *s, float offset s->addEvent720(720.0f, T_PRIMARY, TV_RISE); } -void initializeMazdaMiataNb1Shape(TriggerShape *s) { +void initializeMazdaMiataNb1Shape(TriggerWaveform *s) { initializeMazdaMiataNb1ShapeWithOffset(s, 0); } -void initializeMazdaMiataVVtTestShape(TriggerShape *s) { +void initializeMazdaMiataVVtTestShape(TriggerWaveform *s) { initializeMazdaMiataNb1ShapeWithOffset(s, -22); } -void configureMazdaProtegeSOHC(TriggerShape *s) { +void configureMazdaProtegeSOHC(TriggerWaveform *s) { // todo: move to into configuration definition s->needSecondTriggerInput = FALSE; @@ -181,7 +181,7 @@ void configureMazdaProtegeSOHC(TriggerShape *s) { s->isSynchronizationNeeded = false; } -void configureMazdaProtegeLx(TriggerShape *s) { +void configureMazdaProtegeLx(TriggerWaveform *s) { // todo: move to into configuration definition s->needSecondTriggerInput = FALSE; s->initialize(FOUR_STROKE_CAM_SENSOR, true); s->useOnlyPrimaryForSync = true; diff --git a/firmware/controllers/trigger/decoders/trigger_mazda.h b/firmware/controllers/trigger/decoders/trigger_mazda.h index 4f630cac35..3523bbb725 100644 --- a/firmware/controllers/trigger/decoders/trigger_mazda.h +++ b/firmware/controllers/trigger/decoders/trigger_mazda.h @@ -12,12 +12,12 @@ #define MIATA_NA_GAP 1.4930f -void initializeMazdaMiataNaShape(TriggerShape *s); -void initializeMazdaMiataNb1Shape(TriggerShape *s); -void initializeMazdaMiataNb2Crank(TriggerShape *s); -void initializeMazdaMiataVVtTestShape(TriggerShape *s); -void configureMazdaProtegeSOHC(TriggerShape *s); -void configureMazdaProtegeLx(TriggerShape *s); -void initialize_Mazda_Engine_z5_Shape(TriggerShape *s); +void initializeMazdaMiataNaShape(TriggerWaveform *s); +void initializeMazdaMiataNb1Shape(TriggerWaveform *s); +void initializeMazdaMiataNb2Crank(TriggerWaveform *s); +void initializeMazdaMiataVVtTestShape(TriggerWaveform *s); +void configureMazdaProtegeSOHC(TriggerWaveform *s); +void configureMazdaProtegeLx(TriggerWaveform *s); +void initialize_Mazda_Engine_z5_Shape(TriggerWaveform *s); #endif /* TRIGGER_MAZDA_H_ */ diff --git a/firmware/controllers/trigger/decoders/trigger_misc.cpp b/firmware/controllers/trigger/decoders/trigger_misc.cpp index 2dbea44a5f..dc9b792f38 100644 --- a/firmware/controllers/trigger/decoders/trigger_misc.cpp +++ b/firmware/controllers/trigger/decoders/trigger_misc.cpp @@ -8,7 +8,7 @@ #include "trigger_misc.h" // TT_FIAT_IAW_P8 -void configureFiatIAQ_P8(TriggerShape * s) { +void configureFiatIAQ_P8(TriggerWaveform * s) { s->initialize(FOUR_STROKE_CAM_SENSOR, false); s->isSynchronizationNeeded = true; diff --git a/firmware/controllers/trigger/decoders/trigger_misc.h b/firmware/controllers/trigger/decoders/trigger_misc.h index e56b7f6e9c..c2c4ec0ef0 100644 --- a/firmware/controllers/trigger/decoders/trigger_misc.h +++ b/firmware/controllers/trigger/decoders/trigger_misc.h @@ -10,6 +10,6 @@ #include "trigger_structure.h" -void configureFiatIAQ_P8(TriggerShape * s); +void configureFiatIAQ_P8(TriggerWaveform * s); #endif /* CONTROLLERS_TRIGGER_DECODERS_TRIGGER_MISC_H_ */ diff --git a/firmware/controllers/trigger/decoders/trigger_mitsubishi.cpp b/firmware/controllers/trigger/decoders/trigger_mitsubishi.cpp index cc6a26fb21..aa1c824b9d 100644 --- a/firmware/controllers/trigger/decoders/trigger_mitsubishi.cpp +++ b/firmware/controllers/trigger/decoders/trigger_mitsubishi.cpp @@ -7,7 +7,7 @@ #include "trigger_mitsubishi.h" -void configureFordAspireTriggerShape(TriggerShape * s) { +void configureFordAspireTriggerWaveform(TriggerWaveform * s) { s->initialize(FOUR_STROKE_CAM_SENSOR, true); s->isSynchronizationNeeded = false; @@ -31,7 +31,7 @@ void configureFordAspireTriggerShape(TriggerShape * s) { /** * TT_MITSUBISHI = 11 */ -void initializeMitsubishi4g18(TriggerShape *s) { +void initializeMitsubishi4g18(TriggerWaveform *s) { s->initialize(FOUR_STROKE_CAM_SENSOR, true); s->useRiseEdge = false; diff --git a/firmware/controllers/trigger/decoders/trigger_mitsubishi.h b/firmware/controllers/trigger/decoders/trigger_mitsubishi.h index 0df0b7b33d..984e9d154e 100644 --- a/firmware/controllers/trigger/decoders/trigger_mitsubishi.h +++ b/firmware/controllers/trigger/decoders/trigger_mitsubishi.h @@ -9,7 +9,7 @@ #include "trigger_structure.h" -void initializeMitsubishi4g18(TriggerShape *s); -void configureFordAspireTriggerShape(TriggerShape * s); +void initializeMitsubishi4g18(TriggerWaveform *s); +void configureFordAspireTriggerWaveform(TriggerWaveform * s); #endif /* TRIGGER_MITSUBISHI_H_ */ diff --git a/firmware/controllers/trigger/decoders/trigger_nissan.cpp b/firmware/controllers/trigger/decoders/trigger_nissan.cpp index 9c177b780d..827ac7a47a 100644 --- a/firmware/controllers/trigger/decoders/trigger_nissan.cpp +++ b/firmware/controllers/trigger/decoders/trigger_nissan.cpp @@ -13,7 +13,7 @@ /** * 8,2,2,2 Nissan pattern */ -static void initializeNissanSR20VE_4_optional_360(TriggerShape *s, bool with2nd) { +static void initializeNissanSR20VE_4_optional_360(TriggerWaveform *s, bool with2nd) { s->initialize(FOUR_STROKE_CAM_SENSOR, with2nd); s->isSynchronizationNeeded = true; s->gapBothDirections = true; @@ -99,10 +99,10 @@ static void initializeNissanSR20VE_4_optional_360(TriggerShape *s, bool with2nd) * Nissan Primera p11 year 1995-2002 */ -void initializeNissanSR20VE_4(TriggerShape *s) { +void initializeNissanSR20VE_4(TriggerWaveform *s) { initializeNissanSR20VE_4_optional_360(s, false); } -void initializeNissanSR20VE_4_360(TriggerShape *s) { +void initializeNissanSR20VE_4_360(TriggerWaveform *s) { initializeNissanSR20VE_4_optional_360(s, true); } diff --git a/firmware/controllers/trigger/decoders/trigger_nissan.h b/firmware/controllers/trigger/decoders/trigger_nissan.h index bc5d76bb90..dcfdf85f3b 100644 --- a/firmware/controllers/trigger/decoders/trigger_nissan.h +++ b/firmware/controllers/trigger/decoders/trigger_nissan.h @@ -10,7 +10,7 @@ #include "trigger_structure.h" -void initializeNissanSR20VE_4(TriggerShape *s); -void initializeNissanSR20VE_4_360(TriggerShape *s); +void initializeNissanSR20VE_4(TriggerWaveform *s); +void initializeNissanSR20VE_4_360(TriggerWaveform *s); #endif /* CONTROLLERS_TRIGGER_TRIGGER_NISSAN_H_ */ diff --git a/firmware/controllers/trigger/decoders/trigger_rover.cpp b/firmware/controllers/trigger/decoders/trigger_rover.cpp index 8974cadad4..8535653fc4 100644 --- a/firmware/controllers/trigger/decoders/trigger_rover.cpp +++ b/firmware/controllers/trigger/decoders/trigger_rover.cpp @@ -11,7 +11,7 @@ /** * https://en.wikipedia.org/wiki/Rover_K-series_engine */ -void initializeRoverK(TriggerShape *s) { +void initializeRoverK(TriggerWaveform *s) { s->initialize(FOUR_STROKE_CRANK_SENSOR, false); float tooth = 20; diff --git a/firmware/controllers/trigger/decoders/trigger_rover.h b/firmware/controllers/trigger/decoders/trigger_rover.h index b057770229..5fc9f92dff 100644 --- a/firmware/controllers/trigger/decoders/trigger_rover.h +++ b/firmware/controllers/trigger/decoders/trigger_rover.h @@ -11,6 +11,6 @@ #include "trigger_structure.h" -void initializeRoverK(TriggerShape *s); +void initializeRoverK(TriggerWaveform *s); #endif /* CONTROLLERS_TRIGGER_TRIGGER_ROVER_H_ */ diff --git a/firmware/controllers/trigger/decoders/trigger_structure.cpp b/firmware/controllers/trigger/decoders/trigger_structure.cpp index 62824046bc..2a885c3ff5 100644 --- a/firmware/controllers/trigger/decoders/trigger_structure.cpp +++ b/firmware/controllers/trigger/decoders/trigger_structure.cpp @@ -44,6 +44,11 @@ #include "engine_configuration.h" extern persistent_config_container_s persistentState; +EXTERN_ENGINE; + +void event_trigger_position_s::setAngle(angle_t angle DECLARE_ENGINE_PARAMETER_SUFFIX) { + TRIGGER_WAVEFORM(findTriggerPosition(this, angle PASS_CONFIG_PARAM(engineConfiguration->globalTriggerAngleOffset))); +} trigger_shape_helper::trigger_shape_helper() { memset(&pinStates, 0, sizeof(pinStates)); @@ -52,7 +57,7 @@ trigger_shape_helper::trigger_shape_helper() { } } -TriggerShape::TriggerShape() : +TriggerWaveform::TriggerWaveform() : wave(switchTimesBuffer, NULL) { initialize(OM_NONE, false); wave.channels = h.channels; @@ -60,7 +65,7 @@ TriggerShape::TriggerShape() : memset(triggerIndexByAngle, 0, sizeof(triggerIndexByAngle)); } -void TriggerShape::initialize(operation_mode_e operationMode, bool needSecondTriggerInput) { +void TriggerWaveform::initialize(operation_mode_e operationMode, bool needSecondTriggerInput) { isSynchronizationNeeded = true; // that's default value bothFrontsRequired = false; this->needSecondTriggerInput = needSecondTriggerInput; @@ -96,18 +101,18 @@ void TriggerShape::initialize(operation_mode_e operationMode, bool needSecondTri #endif } -int TriggerShape::getSize() const { +int TriggerWaveform::getSize() const { return privateTriggerDefinitionSize; } -int TriggerShape::getTriggerShapeSynchPointIndex() const { +int TriggerWaveform::getTriggerWaveformSynchPointIndex() const { return triggerShapeSynchPointIndex; } /** * physical primary trigger duration */ -angle_t TriggerShape::getCycleDuration() const { +angle_t TriggerWaveform::getCycleDuration() const { switch (operationMode) { case FOUR_STROKE_SYMMETRICAL_CRANK_SENSOR: return 180; @@ -123,7 +128,7 @@ angle_t TriggerShape::getCycleDuration() const { * Trigger event count equals engine cycle event count if we have a cam sensor. * Two trigger cycles make one engine cycle in case of a four stroke engine If we only have a cranksensor. */ -uint32_t TriggerShape::getLength() const { +uint32_t TriggerWaveform::getLength() const { /** * 4 for FOUR_STROKE_SYMMETRICAL_CRANK_SENSOR * 2 for FOUR_STROKE_CRANK_SENSOR @@ -133,7 +138,7 @@ uint32_t TriggerShape::getLength() const { return multiplier * getSize(); } -angle_t TriggerShape::getAngle(int index) const { +angle_t TriggerWaveform::getAngle(int index) const { // todo: why is this check here? looks like the code below could be used universally if (operationMode == FOUR_STROKE_CAM_SENSOR) { return getSwitchAngle(index); @@ -151,7 +156,7 @@ angle_t TriggerShape::getAngle(int index) const { return getCycleDuration() * crankCycle + getSwitchAngle(remainder); } -void TriggerShape::addEventClamped(angle_t angle, trigger_wheel_e const channelIndex, trigger_value_e const stateParam, float filterLeft, float filterRight) { +void TriggerWaveform::addEventClamped(angle_t angle, trigger_wheel_e const channelIndex, trigger_value_e const stateParam, float filterLeft, float filterRight) { if (angle > filterLeft && angle < filterRight) { #if EFI_UNIT_TEST // printf("addEventClamped %f %s\r\n", angle, getTrigger_value_e(stateParam)); @@ -160,7 +165,7 @@ void TriggerShape::addEventClamped(angle_t angle, trigger_wheel_e const channelI } } -operation_mode_e TriggerShape::getOperationMode() const { +operation_mode_e TriggerWaveform::getOperationMode() const { return operationMode; } @@ -168,7 +173,7 @@ operation_mode_e TriggerShape::getOperationMode() const { extern bool printTriggerDebug; #endif -void TriggerShape::calculateExpectedEventCounts(bool useOnlyRisingEdgeForTrigger) { +void TriggerWaveform::calculateExpectedEventCounts(bool useOnlyRisingEdgeForTrigger) { UNUSED(useOnlyRisingEdgeForTrigger); // todo: move the following logic from below here // if (!useOnlyRisingEdgeForTrigger || stateParam == TV_RISE) { @@ -177,11 +182,11 @@ void TriggerShape::calculateExpectedEventCounts(bool useOnlyRisingEdgeForTrigger } -void TriggerShape::addEvent720(angle_t angle, trigger_wheel_e const channelIndex, trigger_value_e const stateParam) { +void TriggerWaveform::addEvent720(angle_t angle, trigger_wheel_e const channelIndex, trigger_value_e const stateParam) { addEvent(angle / 720, channelIndex, stateParam); } -void TriggerShape::addEvent(angle_t angle, trigger_wheel_e const channelIndex, trigger_value_e const stateParam) { +void TriggerWaveform::addEvent(angle_t angle, trigger_wheel_e const channelIndex, trigger_value_e const stateParam) { efiAssertVoid(CUSTOM_OMODE_UNDEF, operationMode != OM_NONE, "operationMode not set"); efiAssertVoid(CUSTOM_ERR_6598, channelIndex!= T_SECONDARY || needSecondTriggerInput, "secondary needed or not?"); @@ -224,7 +229,7 @@ void TriggerShape::addEvent(angle_t angle, trigger_wheel_e const channelIndex, t if (privateTriggerDefinitionSize == 0) { privateTriggerDefinitionSize = 1; for (int i = 0; i < PWM_PHASE_MAX_WAVE_PER_PWM; i++) { - SingleWave *wave = &this->wave.channels[i]; + SingleChannelStateSequence *wave = &this->wave.channels[i]; if (wave->pinStates == NULL) { warning(CUSTOM_ERR_STATE_NULL, "wave pinStates is NULL"); @@ -278,26 +283,26 @@ void TriggerShape::addEvent(angle_t angle, trigger_wheel_e const channelIndex, t wave.channels[channelIndex].setState(index, state); } -angle_t TriggerShape::getSwitchAngle(int index) const { +angle_t TriggerWaveform::getSwitchAngle(int index) const { return getCycleDuration() * wave.getSwitchTime(index); } -void setToothedWheelConfiguration(TriggerShape *s, int total, int skipped, +void setToothedWheelConfiguration(TriggerWaveform *s, int total, int skipped, operation_mode_e operationMode) { #if EFI_ENGINE_CONTROL s->useRiseEdge = true; - initializeSkippedToothTriggerShapeExt(s, total, skipped, + initializeSkippedToothTriggerWaveformExt(s, total, skipped, operationMode); #endif } -void TriggerShape::setTriggerSynchronizationGap2(float syncRatioFrom, float syncRatioTo) { +void TriggerWaveform::setTriggerSynchronizationGap2(float syncRatioFrom, float syncRatioTo) { setTriggerSynchronizationGap3(/*gapIndex*/0, syncRatioFrom, syncRatioTo); } -void TriggerShape::setTriggerSynchronizationGap3(int gapIndex, float syncRatioFrom, float syncRatioTo) { +void TriggerWaveform::setTriggerSynchronizationGap3(int gapIndex, float syncRatioFrom, float syncRatioTo) { isSynchronizationNeeded = true; this->syncronizationRatioFrom[gapIndex] = syncRatioFrom; this->syncronizationRatioTo[gapIndex] = syncRatioTo; @@ -317,7 +322,7 @@ void TriggerShape::setTriggerSynchronizationGap3(int gapIndex, float syncRatioFr /** * this method is only used on initialization */ -int TriggerShape::findAngleIndex(float target) const { +int TriggerWaveform::findAngleIndex(float target) const { int engineCycleEventCount = getLength(); efiAssert(CUSTOM_ERR_ASSERT, engineCycleEventCount > 0, "engineCycleEventCount", 0); @@ -345,11 +350,11 @@ int TriggerShape::findAngleIndex(float target) const { return left - 1; } -void TriggerShape::setShapeDefinitionError(bool value) { +void TriggerWaveform::setShapeDefinitionError(bool value) { shapeDefinitionError = value; } -void TriggerShape::findTriggerPosition(event_trigger_position_s *position, +void TriggerWaveform::findTriggerPosition(event_trigger_position_s *position, angle_t angle DEFINE_CONFIG_PARAM(angle_t, globalTriggerAngleOffset)) { efiAssertVoid(CUSTOM_ERR_6574, !cisnan(angle), "findAngle#1"); assertAngleRange(angle, "findAngle#a1", CUSTOM_ERR_6545); @@ -373,11 +378,10 @@ void TriggerShape::findTriggerPosition(event_trigger_position_s *position, } position->triggerEventIndex = triggerEventIndex; - position->triggerEventAngle = triggerEventAngle; position->angleOffsetFromTriggerEvent = angle - triggerEventAngle; } -void TriggerShape::prepareShape() { +void TriggerWaveform::prepareShape() { #if EFI_ENGINE_CONTROL && EFI_SHAFT_POSITION_INPUT int engineCycleInt = (int) getEngineCycle(operationMode); for (int angle = 0; angle < engineCycleInt; angle++) { @@ -391,19 +395,19 @@ void TriggerShape::prepareShape() { #endif } -void TriggerShape::setTriggerSynchronizationGap(float syncRatio) { +void TriggerWaveform::setTriggerSynchronizationGap(float syncRatio) { setTriggerSynchronizationGap3(/*gapIndex*/0, syncRatio * 0.75f, syncRatio * 1.25f); } -void TriggerShape::setSecondTriggerSynchronizationGap2(float syncRatioFrom, float syncRatioTo) { +void TriggerWaveform::setSecondTriggerSynchronizationGap2(float syncRatioFrom, float syncRatioTo) { setTriggerSynchronizationGap3(/*gapIndex*/1, syncRatioFrom, syncRatioTo); } -void TriggerShape::setThirdTriggerSynchronizationGap(float syncRatio) { +void TriggerWaveform::setThirdTriggerSynchronizationGap(float syncRatio) { setTriggerSynchronizationGap3(/*gapIndex*/2, syncRatio * 0.75f, syncRatio * 1.25f); } -void TriggerShape::setSecondTriggerSynchronizationGap(float syncRatio) { +void TriggerWaveform::setSecondTriggerSynchronizationGap(float syncRatio) { setTriggerSynchronizationGap3(/*gapIndex*/1, syncRatio * 0.75f, syncRatio * 1.25f); } @@ -411,11 +415,11 @@ void TriggerShape::setSecondTriggerSynchronizationGap(float syncRatio) { /** * External logger is needed because at this point our logger is not yet initialized */ -void TriggerShape::initializeTriggerShape(Logging *logger, operation_mode_e ambiguousOperationMode, bool useOnlyRisingEdgeForTrigger, const trigger_config_s *triggerConfig) { +void TriggerWaveform::initializeTriggerWaveform(Logging *logger, operation_mode_e ambiguousOperationMode, bool useOnlyRisingEdgeForTrigger, const trigger_config_s *triggerConfig) { #if EFI_PROD_CODE efiAssertVoid(CUSTOM_ERR_6641, getCurrentRemainingStack() > 256, "init t"); - scheduleMsg(logger, "initializeTriggerShape(%s/%d)", getTrigger_type_e(triggerConfig->type), (int) triggerConfig->type); + scheduleMsg(logger, "initializeTriggerWaveform(%s/%d)", getTrigger_type_e(triggerConfig->type), (int) triggerConfig->type); #endif shapeDefinitionError = false; @@ -425,7 +429,7 @@ void TriggerShape::initializeTriggerShape(Logging *logger, operation_mode_e ambi switch (triggerConfig->type) { case TT_TOOTHED_WHEEL: - initializeSkippedToothTriggerShapeExt(this, triggerConfig->customTotalToothCount, + initializeSkippedToothTriggerWaveformExt(this, triggerConfig->customTotalToothCount, triggerConfig->customSkippedToothCount, ambiguousOperationMode); break; @@ -450,32 +454,32 @@ void TriggerShape::initializeTriggerShape(Logging *logger, operation_mode_e ambi break; case TT_DODGE_NEON_1995: - configureNeon1995TriggerShape(this); + configureNeon1995TriggerWaveform(this); break; case TT_DODGE_NEON_1995_ONLY_CRANK: - configureNeon1995TriggerShapeOnlyCrank(this); + configureNeon1995TriggerWaveformOnlyCrank(this); break; case TT_DODGE_STRATUS: - configureDodgeStratusTriggerShape(this); + configureDodgeStratusTriggerWaveform(this); break; case TT_DODGE_NEON_2003_CAM: - configureNeon2003TriggerShapeCam(this); + configureNeon2003TriggerWaveformCam(this); break; case TT_DODGE_NEON_2003_CRANK: - configureNeon2003TriggerShapeCam(this); -// configureNeon2003TriggerShapeCrank(triggerShape); + configureNeon2003TriggerWaveformCam(this); +// configureNeon2003TriggerWaveformCrank(triggerShape); break; case TT_FORD_ASPIRE: - configureFordAspireTriggerShape(this); + configureFordAspireTriggerWaveform(this); break; case TT_GM_7X: - configureGmTriggerShape(this); + configureGmTriggerWaveform(this); break; case TT_MAZDA_DOHC_1_4: @@ -503,7 +507,7 @@ void TriggerShape::initializeTriggerShape(Logging *logger, operation_mode_e ambi break; case TT_MINI_COOPER_R50: - configureMiniCooperTriggerShape(this); + configureMiniCooperTriggerWaveform(this); break; case TT_TOOTHED_WHEEL_60_2: @@ -600,7 +604,7 @@ void TriggerShape::initializeTriggerShape(Logging *logger, operation_mode_e ambi default: setShapeDefinitionError(true); - warning(CUSTOM_ERR_NO_SHAPE, "initializeTriggerShape() not implemented: %d", triggerConfig->type); + warning(CUSTOM_ERR_NO_SHAPE, "initializeTriggerWaveform() not implemented: %d", triggerConfig->type); } /** * Feb 2019 suggestion: it would be an improvement to remove 'expectedEventCount' logic from 'addEvent' diff --git a/firmware/controllers/trigger/decoders/trigger_structure.h b/firmware/controllers/trigger/decoders/trigger_structure.h index b83f126406..6176e011d8 100644 --- a/firmware/controllers/trigger/decoders/trigger_structure.h +++ b/firmware/controllers/trigger/decoders/trigger_structure.h @@ -2,15 +2,14 @@ * @file trigger_structure.h * * @date Dec 22, 2013 - * @author Andrey Belomutskiy, (c) 2012-2018 + * @author Andrey Belomutskiy, (c) 2012-2019 */ -#ifndef TRIGGER_STRUCTURE_H_ -#define TRIGGER_STRUCTURE_H_ +#pragma once +#include "state_sequence.h" #include "globalaccess.h" #include "engine_configuration_generated_structures.h" -#include "efi_wave.h" #define FOUR_STROKE_ENGINE_CYCLE 720 @@ -47,13 +46,10 @@ class event_trigger_position_s { public: uint32_t triggerEventIndex = 0; - /** - * angle of that 'triggerEventIndex' event - * todo: Technically we can simply take angle of trigger event from trigger shape by 'triggerEventIndex'? - */ - angle_t triggerEventAngle = 0; angle_t angleOffsetFromTriggerEvent = 0; + + void setAngle(angle_t angle DECLARE_ENGINE_PARAMETER_SUFFIX); }; #define TRIGGER_CHANNEL_COUNT 3 @@ -62,7 +58,7 @@ class trigger_shape_helper { public: trigger_shape_helper(); - SingleWave channels[TRIGGER_CHANNEL_COUNT]; + SingleChannelStateSequence channels[TRIGGER_CHANNEL_COUNT]; private: pin_state_t pinStates[TRIGGER_CHANNEL_COUNT][PWM_PHASE_MAX_COUNT]; }; @@ -76,10 +72,10 @@ class TriggerState; * @brief Trigger shape has all the fields needed to describe and decode trigger signal. * @see TriggerState for trigger decoder state which works based on this trigger shape model */ -class TriggerShape { +class TriggerWaveform { public: - TriggerShape(); - void initializeTriggerShape(Logging *logger, operation_mode_e ambiguousOperationMode, + TriggerWaveform(); + void initializeTriggerWaveform(Logging *logger, operation_mode_e ambiguousOperationMode, bool useOnlyRisingEdgeForTrigger, const trigger_config_s *triggerConfig); void findTriggerPosition(event_trigger_position_s *position, angle_t angle DEFINE_CONFIG_PARAM(angle_t, globalTriggerAngleOffset)); @@ -190,7 +186,7 @@ public: int triggerSignals[PWM_PHASE_MAX_COUNT]; #endif - MultiWave wave; + MultiChannelStateSequence wave; // todo: add a runtime validation which would verify that this field was set properly // todo: maybe even automate this flag calculation? @@ -244,7 +240,7 @@ public: uint32_t getLength() const; int getSize() const; - int getTriggerShapeSynchPointIndex() const; + int getTriggerWaveformSynchPointIndex() const; void prepareShape(); /** @@ -254,7 +250,7 @@ public: angle_t getAngle(int phaseIndex) const; /** - * index of synchronization event within TriggerShape + * index of synchronization event within TriggerWaveform * See findTriggerZeroEventIndex() */ int triggerShapeSynchPointIndex; @@ -287,10 +283,8 @@ private: angle_t getCycleDuration() const; }; -void setToothedWheelConfiguration(TriggerShape *s, int total, int skipped, operation_mode_e operationMode); +void setToothedWheelConfiguration(TriggerWaveform *s, int total, int skipped, operation_mode_e operationMode); -#define TRIGGER_SHAPE(x) ENGINE(triggerCentral.triggerShape.x) +#define TRIGGER_WAVEFORM(x) ENGINE(triggerCentral.triggerShape.x) -#define getTriggerSize() TRIGGER_SHAPE(privateTriggerDefinitionSize) - -#endif /* TRIGGER_STRUCTURE_H_ */ +#define getTriggerSize() TRIGGER_WAVEFORM(privateTriggerDefinitionSize) diff --git a/firmware/controllers/trigger/decoders/trigger_subaru.cpp b/firmware/controllers/trigger/decoders/trigger_subaru.cpp index 9286d2885e..08f25fdb07 100644 --- a/firmware/controllers/trigger/decoders/trigger_subaru.cpp +++ b/firmware/controllers/trigger/decoders/trigger_subaru.cpp @@ -10,7 +10,7 @@ /** * This trigger is also used by Nissan and Mazda */ -void initialize36_2_2_2(TriggerShape *s) { +void initialize36_2_2_2(TriggerWaveform *s) { s->initialize(FOUR_STROKE_CAM_SENSOR, true); float wide = 30 * 2; @@ -46,7 +46,7 @@ void initialize36_2_2_2(TriggerShape *s) { s->useOnlyPrimaryForSync = true; } -void initializeSubaru7_6(TriggerShape *s) { +void initializeSubaru7_6(TriggerWaveform *s) { s->initialize(FOUR_STROKE_CAM_SENSOR, true); float magic = 333; diff --git a/firmware/controllers/trigger/decoders/trigger_subaru.h b/firmware/controllers/trigger/decoders/trigger_subaru.h index 12adf5da55..f82b1fce6c 100644 --- a/firmware/controllers/trigger/decoders/trigger_subaru.h +++ b/firmware/controllers/trigger/decoders/trigger_subaru.h @@ -10,7 +10,7 @@ #include "trigger_structure.h" -void initialize36_2_2_2(TriggerShape *s); -void initializeSubaru7_6(TriggerShape *s); +void initialize36_2_2_2(TriggerWaveform *s); +void initializeSubaru7_6(TriggerWaveform *s); #endif /* CONTROLLERS_TRIGGER_TRIGGER_SUBARU_H_ */ diff --git a/firmware/controllers/trigger/decoders/trigger_toyota.cpp b/firmware/controllers/trigger/decoders/trigger_toyota.cpp index 68e44d47b1..37e36ffbd9 100644 --- a/firmware/controllers/trigger/decoders/trigger_toyota.cpp +++ b/firmware/controllers/trigger/decoders/trigger_toyota.cpp @@ -9,7 +9,7 @@ #include "trigger_toyota.h" -void initialize2jzGE1_12(TriggerShape *s) { +void initialize2jzGE1_12(TriggerWaveform *s) { s->initialize(FOUR_STROKE_CAM_SENSOR, true); float crankD = 360 / 12 / 2; // 15 @@ -43,7 +43,7 @@ void initialize2jzGE1_12(TriggerShape *s) { s->isSynchronizationNeeded = false; } -void initialize2jzGE3_34(TriggerShape *s) { +void initialize2jzGE3_34(TriggerWaveform *s) { setToothedWheelConfiguration(s, 36, 2, FOUR_STROKE_CRANK_SENSOR); // s->initialize(FOUR_STROKE_CAM_SENSOR, true); diff --git a/firmware/controllers/trigger/decoders/trigger_toyota.h b/firmware/controllers/trigger/decoders/trigger_toyota.h index 8b29734398..90fc7cd347 100644 --- a/firmware/controllers/trigger/decoders/trigger_toyota.h +++ b/firmware/controllers/trigger/decoders/trigger_toyota.h @@ -10,7 +10,7 @@ #include "trigger_structure.h" -void initialize2jzGE1_12(TriggerShape *s); -void initialize2jzGE3_34(TriggerShape *s); +void initialize2jzGE1_12(TriggerWaveform *s); +void initialize2jzGE3_34(TriggerWaveform *s); #endif /* CONTROLLERS_TRIGGER_TRIGGER_TOYOTA_H_ */ diff --git a/firmware/controllers/trigger/decoders/trigger_universal.cpp b/firmware/controllers/trigger/decoders/trigger_universal.cpp index 4459eb2d72..3cf56f5957 100644 --- a/firmware/controllers/trigger/decoders/trigger_universal.cpp +++ b/firmware/controllers/trigger/decoders/trigger_universal.cpp @@ -11,7 +11,7 @@ angle_t getEngineCycle(operation_mode_e operationMode) { return operationMode == TWO_STROKE ? 360 : FOUR_STROKE_ENGINE_CYCLE; } -void addSkippedToothTriggerEvents(trigger_wheel_e wheel, TriggerShape *s, int totalTeethCount, int skippedCount, +void addSkippedToothTriggerEvents(trigger_wheel_e wheel, TriggerWaveform *s, int totalTeethCount, int skippedCount, float toothWidth, float offset, float engineCycle, float filterLeft, float filterRight) { efiAssertVoid(CUSTOM_ERR_6586, totalTeethCount > 0, "total count"); efiAssertVoid(CUSTOM_ERR_6587, skippedCount >= 0, "skipped count"); @@ -28,14 +28,14 @@ void addSkippedToothTriggerEvents(trigger_wheel_e wheel, TriggerShape *s, int to s->addEventClamped(offset + engineCycle, wheel, TV_FALL, filterLeft, filterRight); } -void initializeSkippedToothTriggerShapeExt(TriggerShape *s, int totalTeethCount, int skippedCount, +void initializeSkippedToothTriggerWaveformExt(TriggerWaveform *s, int totalTeethCount, int skippedCount, operation_mode_e operationMode) { if (totalTeethCount <= 0) { - warning(CUSTOM_OBD_TRIGGER_SHAPE, "totalTeethCount is zero or less: %d", totalTeethCount); + warning(CUSTOM_OBD_TRIGGER_WAVEFORM, "totalTeethCount is zero or less: %d", totalTeethCount); s->setShapeDefinitionError(true); return; } - efiAssertVoid(CUSTOM_ERR_6588, s != NULL, "TriggerShape is NULL"); + efiAssertVoid(CUSTOM_NULL_SHAPE, s != NULL, "TriggerWaveform is NULL"); s->initialize(operationMode, false); s->setTriggerSynchronizationGap(skippedCount + 1); @@ -46,7 +46,7 @@ void initializeSkippedToothTriggerShapeExt(TriggerShape *s, int totalTeethCount, } -void configureOnePlusOne(TriggerShape *s, operation_mode_e operationMode) { +void configureOnePlusOne(TriggerWaveform *s, operation_mode_e operationMode) { UNUSED(operationMode); s->initialize(FOUR_STROKE_CAM_SENSOR, true); @@ -60,7 +60,7 @@ void configureOnePlusOne(TriggerShape *s, operation_mode_e operationMode) { s->useOnlyPrimaryForSync = true; } -void configureOnePlus60_2(TriggerShape *s, operation_mode_e operationMode) { +void configureOnePlus60_2(TriggerWaveform *s, operation_mode_e operationMode) { UNUSED(operationMode); s->initialize(FOUR_STROKE_CAM_SENSOR, true); @@ -79,7 +79,7 @@ void configureOnePlus60_2(TriggerShape *s, operation_mode_e operationMode) { s->useOnlyPrimaryForSync = true; } -void configure3_1_cam(TriggerShape *s, operation_mode_e operationMode) { +void configure3_1_cam(TriggerWaveform *s, operation_mode_e operationMode) { UNUSED(operationMode); s->initialize(FOUR_STROKE_CAM_SENSOR, true); diff --git a/firmware/controllers/trigger/decoders/trigger_universal.h b/firmware/controllers/trigger/decoders/trigger_universal.h index b5ffd92a92..c40db80179 100644 --- a/firmware/controllers/trigger/decoders/trigger_universal.h +++ b/firmware/controllers/trigger/decoders/trigger_universal.h @@ -14,17 +14,17 @@ #define NO_LEFT_FILTER -1 #define NO_RIGHT_FILTER 1000 -void addSkippedToothTriggerEvents(trigger_wheel_e wheel, TriggerShape *s, +void addSkippedToothTriggerEvents(trigger_wheel_e wheel, TriggerWaveform *s, int totalTeethCount, int skippedCount, float toothWidth, float offset, float engineCycle, float filterLeft, float filterRight); -void initializeSkippedToothTriggerShapeExt(TriggerShape *s, int totalTeethCount, int skippedCount, operation_mode_e operationMode);; +void initializeSkippedToothTriggerWaveformExt(TriggerWaveform *s, int totalTeethCount, int skippedCount, operation_mode_e operationMode);; -void configureOnePlus60_2(TriggerShape *s, operation_mode_e operationMode); +void configureOnePlus60_2(TriggerWaveform *s, operation_mode_e operationMode); -void configure3_1_cam(TriggerShape *s, operation_mode_e operationMode); +void configure3_1_cam(TriggerWaveform *s, operation_mode_e operationMode); -void configureOnePlusOne(TriggerShape *s, operation_mode_e operationMode); +void configureOnePlusOne(TriggerWaveform *s, operation_mode_e operationMode); #endif /* CONTROLLERS_TRIGGER_DECODERS_TRIGGER_UNIVERSAL_H_ */ diff --git a/firmware/controllers/trigger/decoders/trigger_vw.cpp b/firmware/controllers/trigger/decoders/trigger_vw.cpp index ef92ce973b..53d0db2cb7 100644 --- a/firmware/controllers/trigger/decoders/trigger_vw.cpp +++ b/firmware/controllers/trigger/decoders/trigger_vw.cpp @@ -8,8 +8,8 @@ #include "trigger_vw.h" #include "trigger_universal.h" -void setVwConfiguration(TriggerShape *s) { - efiAssertVoid(CUSTOM_ERR_6660, s != NULL, "TriggerShape is NULL"); +void setVwConfiguration(TriggerWaveform *s) { + efiAssertVoid(CUSTOM_ERR_6660, s != NULL, "TriggerWaveform is NULL"); s->initialize(FOUR_STROKE_CRANK_SENSOR, false); diff --git a/firmware/controllers/trigger/decoders/trigger_vw.h b/firmware/controllers/trigger/decoders/trigger_vw.h index 7ae70a39fd..3dcbb2ed23 100644 --- a/firmware/controllers/trigger/decoders/trigger_vw.h +++ b/firmware/controllers/trigger/decoders/trigger_vw.h @@ -10,6 +10,6 @@ #include "trigger_structure.h" -void setVwConfiguration(TriggerShape *s); +void setVwConfiguration(TriggerWaveform *s); #endif /* CONTROLLERS_TRIGGER_DECODERS_TRIGGER_VW_H_ */ diff --git a/firmware/controllers/trigger/trigger.mk b/firmware/controllers/trigger/trigger.mk index f3bf94da84..9aaa261b2d 100644 --- a/firmware/controllers/trigger/trigger.mk +++ b/firmware/controllers/trigger/trigger.mk @@ -1,26 +1,22 @@ TRIGGER_DECODERS_SRC_CPP = \ - $(PROJECT_DIR)/controllers/trigger/decoders/trigger_bmw.cpp \ - $(PROJECT_DIR)/controllers/trigger/decoders/trigger_mazda.cpp \ - $(PROJECT_DIR)/controllers/trigger/decoders/trigger_chrysler.cpp \ - $(PROJECT_DIR)/controllers/trigger/decoders/trigger_structure.cpp \ - $(PROJECT_DIR)/controllers/trigger/trigger_decoder.cpp \ - $(PROJECT_DIR)/controllers/trigger/trigger_simulator.cpp \ - $(PROJECT_DIR)/controllers/trigger/decoders/trigger_mitsubishi.cpp \ - $(PROJECT_DIR)/controllers/trigger/decoders/trigger_nissan.cpp \ - $(PROJECT_DIR)/controllers/trigger/decoders/trigger_subaru.cpp \ - $(PROJECT_DIR)/controllers/trigger/decoders/trigger_toyota.cpp \ - $(PROJECT_DIR)/controllers/trigger/decoders/trigger_gm.cpp \ - $(PROJECT_DIR)/controllers/trigger/decoders/trigger_honda.cpp \ - $(PROJECT_DIR)/controllers/trigger/decoders/trigger_rover.cpp \ - $(PROJECT_DIR)/controllers/trigger/decoders/trigger_vw.cpp \ - $(PROJECT_DIR)/controllers/trigger/decoders/trigger_misc.cpp \ - $(PROJECT_DIR)/controllers/trigger/decoders/trigger_universal.cpp + $(CONTROLLERS_DIR)/trigger/decoders/trigger_bmw.cpp \ + $(CONTROLLERS_DIR)/trigger/decoders/trigger_mazda.cpp \ + $(CONTROLLERS_DIR)/trigger/decoders/trigger_chrysler.cpp \ + $(CONTROLLERS_DIR)/trigger/decoders/trigger_structure.cpp \ + $(CONTROLLERS_DIR)/trigger/trigger_decoder.cpp \ + $(CONTROLLERS_DIR)/trigger/trigger_simulator.cpp \ + $(CONTROLLERS_DIR)/trigger/decoders/trigger_mitsubishi.cpp \ + $(CONTROLLERS_DIR)/trigger/decoders/trigger_nissan.cpp \ + $(CONTROLLERS_DIR)/trigger/decoders/trigger_subaru.cpp \ + $(CONTROLLERS_DIR)/trigger/decoders/trigger_toyota.cpp \ + $(CONTROLLERS_DIR)/trigger/decoders/trigger_gm.cpp \ + $(CONTROLLERS_DIR)/trigger/decoders/trigger_honda.cpp \ + $(CONTROLLERS_DIR)/trigger/decoders/trigger_rover.cpp \ + $(CONTROLLERS_DIR)/trigger/decoders/trigger_vw.cpp \ + $(CONTROLLERS_DIR)/trigger/decoders/trigger_misc.cpp \ + $(CONTROLLERS_DIR)/trigger/decoders/trigger_universal.cpp TRIGGER_SRC_CPP = \ - $(PROJECT_DIR)/controllers/trigger/trigger_emulator_algo.cpp \ - $(PROJECT_DIR)/controllers/trigger/rpm_calculator.cpp \ - $(PROJECT_DIR)/controllers/trigger/trigger_central.cpp \ - $(PROJECT_DIR)/controllers/trigger/spark_logic.cpp \ - $(PROJECT_DIR)/controllers/trigger/main_trigger_callback.cpp \ - $(PROJECT_DIR)/controllers/trigger/aux_valves.cpp + $(CONTROLLERS_DIR)/trigger/trigger_emulator_algo.cpp \ + $(CONTROLLERS_DIR)/trigger/trigger_central.cpp diff --git a/firmware/controllers/trigger/trigger_central.cpp b/firmware/controllers/trigger/trigger_central.cpp index 4aebbc2a19..71ab35c636 100644 --- a/firmware/controllers/trigger/trigger_central.cpp +++ b/firmware/controllers/trigger/trigger_central.cpp @@ -290,12 +290,12 @@ bool TriggerCentral::noiseFilter(efitick_t nowNt, trigger_event_e signal DECLARE efitick_t allowedPeriod = accumSignalPrevPeriods[os]; // but first check if we're expecting a gap - bool isGapExpected = TRIGGER_SHAPE(isSynchronizationNeeded) && triggerState.shaft_is_synchronized && - (triggerState.currentCycle.eventCount[ti] + 1) == TRIGGER_SHAPE(expectedEventCount[ti]); + bool isGapExpected = TRIGGER_WAVEFORM(isSynchronizationNeeded) && triggerState.shaft_is_synchronized && + (triggerState.currentCycle.eventCount[ti] + 1) == TRIGGER_WAVEFORM(expectedEventCount[ti]); if (isGapExpected) { // usually we need to extend the period for gaps, based on the trigger info - allowedPeriod *= TRIGGER_SHAPE(syncRatioAvg); + allowedPeriod *= TRIGGER_WAVEFORM(syncRatioAvg); } // also we need some margin for rapidly changing trigger-wheel speed, @@ -364,7 +364,7 @@ void TriggerCentral::handleShaftSignal(trigger_event_e signal DECLARE_ENGINE_PAR /** * This invocation changes the state of triggerState */ - triggerState.decodeTriggerEvent(signal, nowNt PASS_ENGINE_PARAMETER_SUFFIX); + triggerState.decodeTriggerEvent(nullptr, engine, signal, nowNt PASS_ENGINE_PARAMETER_SUFFIX); /** * If we only have a crank position sensor with four stroke, here we are extending crank revolutions with a 360 degree @@ -430,9 +430,9 @@ EXTERN_ENGINE static void triggerShapeInfo(void) { #if EFI_PROD_CODE || EFI_SIMULATOR - TriggerShape *s = &engine->triggerCentral.triggerShape; - scheduleMsg(logger, "useRise=%s", boolToString(TRIGGER_SHAPE(useRiseEdge))); - scheduleMsg(logger, "gap from %.2f to %.2f", TRIGGER_SHAPE(syncronizationRatioFrom[0]), TRIGGER_SHAPE(syncronizationRatioTo[0])); + TriggerWaveform *s = &engine->triggerCentral.triggerShape; + scheduleMsg(logger, "useRise=%s", boolToString(TRIGGER_WAVEFORM(useRiseEdge))); + scheduleMsg(logger, "gap from %.2f to %.2f", TRIGGER_WAVEFORM(syncronizationRatioFrom[0]), TRIGGER_WAVEFORM(syncronizationRatioTo[0])); for (int i = 0; i < s->getSize(); i++) { scheduleMsg(logger, "event %d %.2f", i, s->eventAngles[i]); @@ -474,8 +474,8 @@ void printAllTriggers() { engineConfiguration->trigger.type = tt; engineConfiguration->ambiguousOperationMode = FOUR_STROKE_CAM_SENSOR; - TriggerShape *s = &engine->triggerCentral.triggerShape; - engine->eInitializeTriggerShape(NULL PASS_ENGINE_PARAMETER_SUFFIX); + TriggerWaveform *s = &engine->triggerCentral.triggerShape; + engine->initializeTriggerWaveform(NULL PASS_ENGINE_PARAMETER_SUFFIX); if (s->shapeDefinitionError) { printf("Trigger error %d\r\n", triggerId); @@ -488,7 +488,7 @@ void printAllTriggers() { for (int i = 0; i < s->getLength(); i++) { - int triggerDefinitionCoordinate = (s->getTriggerShapeSynchPointIndex() + i) % s->getSize(); + int triggerDefinitionCoordinate = (s->getTriggerWaveformSynchPointIndex() + i) % s->getSize(); fprintf(fp, "event %d %d %.2f\n", i, s->triggerSignals[triggerDefinitionCoordinate], s->eventAngles[i]); @@ -546,7 +546,7 @@ extern int icuWidthPeriodCounter; void triggerInfo(void) { #if EFI_PROD_CODE || EFI_SIMULATOR - TriggerShape *ts = &engine->triggerCentral.triggerShape; + TriggerWaveform *ts = &engine->triggerCentral.triggerShape; #if (HAL_TRIGGER_USE_PAL == TRUE) && (PAL_USE_CALLBACKS == TRUE) @@ -562,8 +562,8 @@ void triggerInfo(void) { scheduleMsg(logger, "Template %s (%d) trigger %s (%d) useRiseEdge=%s onlyFront=%s useOnlyFirstChannel=%s tdcOffset=%.2f", getConfigurationName(engineConfiguration->engineType), engineConfiguration->engineType, getTrigger_type_e(engineConfiguration->trigger.type), engineConfiguration->trigger.type, - boolToString(TRIGGER_SHAPE(useRiseEdge)), boolToString(engineConfiguration->useOnlyRisingEdgeForTrigger), - boolToString(engineConfiguration->trigger.useOnlyFirstChannel), TRIGGER_SHAPE(tdcPosition)); + boolToString(TRIGGER_WAVEFORM(useRiseEdge)), boolToString(engineConfiguration->useOnlyRisingEdgeForTrigger), + boolToString(engineConfiguration->trigger.useOnlyFirstChannel), TRIGGER_WAVEFORM(tdcPosition)); if (engineConfiguration->trigger.type == TT_TOOTHED_WHEEL) { scheduleMsg(logger, "total %d/skipped %d", engineConfiguration->trigger.customTotalToothCount, @@ -577,12 +577,12 @@ void triggerInfo(void) { scheduleMsg(logger, "trigger#2 event counters up=%d/down=%d", engine->triggerCentral.getHwEventCounter(2), engine->triggerCentral.getHwEventCounter(3)); } - scheduleMsg(logger, "expected cycle events %d/%d/%d", TRIGGER_SHAPE(expectedEventCount[0]), - TRIGGER_SHAPE(expectedEventCount[1]), TRIGGER_SHAPE(expectedEventCount[2])); + scheduleMsg(logger, "expected cycle events %d/%d/%d", TRIGGER_WAVEFORM(expectedEventCount[0]), + TRIGGER_WAVEFORM(expectedEventCount[1]), TRIGGER_WAVEFORM(expectedEventCount[2])); scheduleMsg(logger, "trigger type=%d/need2ndChannel=%s", engineConfiguration->trigger.type, - boolToString(TRIGGER_SHAPE(needSecondTriggerInput))); - scheduleMsg(logger, "expected duty #0=%.2f/#1=%.2f", TRIGGER_SHAPE(expectedDutyCycle[0]), TRIGGER_SHAPE(expectedDutyCycle[1])); + boolToString(TRIGGER_WAVEFORM(needSecondTriggerInput))); + scheduleMsg(logger, "expected duty #0=%.2f/#1=%.2f", TRIGGER_WAVEFORM(expectedDutyCycle[0]), TRIGGER_WAVEFORM(expectedDutyCycle[1])); scheduleMsg(logger, "synchronizationNeeded=%s/isError=%s/total errors=%d ord_err=%d/total revolutions=%d/self=%s", boolToString(ts->isSynchronizationNeeded), @@ -590,8 +590,8 @@ void triggerInfo(void) { engine->triggerCentral.triggerState.orderingErrorCounter, engine->triggerCentral.triggerState.getTotalRevolutionCounter(), boolToString(engineConfiguration->directSelfStimulation)); - if (TRIGGER_SHAPE(isSynchronizationNeeded)) { - scheduleMsg(logger, "gap from %.2f to %.2f", TRIGGER_SHAPE(syncronizationRatioFrom[0]), TRIGGER_SHAPE(syncronizationRatioTo[0])); + if (TRIGGER_WAVEFORM(isSynchronizationNeeded)) { + scheduleMsg(logger, "gap from %.2f to %.2f", TRIGGER_WAVEFORM(syncronizationRatioFrom[0]), TRIGGER_WAVEFORM(syncronizationRatioTo[0])); } #endif /* EFI_PROD_CODE || EFI_SIMULATOR */ @@ -699,7 +699,7 @@ void onConfigurationChangeTriggerCallback(DECLARE_ENGINE_PARAMETER_SIGNATURE) { assertEngineReference(); #if EFI_ENGINE_CONTROL - ENGINE(eInitializeTriggerShape(logger PASS_ENGINE_PARAMETER_SUFFIX)); + ENGINE(initializeTriggerWaveform(logger PASS_ENGINE_PARAMETER_SUFFIX)); engine->triggerCentral.resetAccumSignalData(); #endif } diff --git a/firmware/controllers/trigger/trigger_central.h b/firmware/controllers/trigger/trigger_central.h index 375336da81..792feb997c 100644 --- a/firmware/controllers/trigger/trigger_central.h +++ b/firmware/controllers/trigger/trigger_central.h @@ -41,7 +41,7 @@ public: */ efitick_t timeAtVirtualZeroNt = 0; - TriggerShape triggerShape; + TriggerWaveform triggerShape; efitick_t previousVvtCamTime = 0; efitick_t previousVvtCamDuration = 0; diff --git a/firmware/controllers/trigger/trigger_decoder.cpp b/firmware/controllers/trigger/trigger_decoder.cpp index ebeaeff561..da07d6816b 100644 --- a/firmware/controllers/trigger/trigger_decoder.cpp +++ b/firmware/controllers/trigger/trigger_decoder.cpp @@ -59,7 +59,6 @@ void TriggerState::setShaftSynchronized(bool value) { } void TriggerState::resetTriggerState() { - triggerCycleCallback = nullptr; setShaftSynchronized(false); toothed_previous_time = 0; @@ -121,7 +120,7 @@ bool isTriggerDecoderError(void) { return errorDetection.sum(6) > 4; } -void calculateTriggerSynchPoint(TriggerShape *shape, TriggerState *state DECLARE_ENGINE_PARAMETER_SUFFIX) { +void calculateTriggerSynchPoint(TriggerWaveform *shape, TriggerState *state DECLARE_ENGINE_PARAMETER_SUFFIX) { #if EFI_PROD_CODE efiAssertVoid(CUSTOM_ERR_6642, getCurrentRemainingStack() > 256, "calc s"); #endif @@ -133,7 +132,7 @@ void calculateTriggerSynchPoint(TriggerShape *shape, TriggerState *state DECLARE engine->engineCycleEventCount = length; efiAssertVoid(CUSTOM_SHAPE_LEN_ZERO, length > 0, "shapeLength=0"); if (length >= PWM_PHASE_MAX_COUNT) { - warning(CUSTOM_ERR_TRIGGER_SHAPE_TOO_LONG, "Count above %d", length); + warning(CUSTOM_ERR_TRIGGER_WAVEFORM_TOO_LONG, "Count above %d", length); shape->setShapeDefinitionError(true); return; } @@ -195,7 +194,7 @@ float TriggerStateWithRunningStatistics::calculateInstantRpm(int *prevIndexOut, /** * Here we calculate RPM based on last 90 degrees */ - angle_t currentAngle = TRIGGER_SHAPE(eventAngles[current_index]); + angle_t currentAngle = TRIGGER_WAVEFORM(eventAngles[current_index]); // todo: make this '90' depend on cylinder count or trigger shape? if (cisnan(currentAngle)) { return NOISY_RPM; @@ -203,14 +202,14 @@ float TriggerStateWithRunningStatistics::calculateInstantRpm(int *prevIndexOut, angle_t previousAngle = currentAngle - 90; fixAngle(previousAngle, "prevAngle", CUSTOM_ERR_TRIGGER_ANGLE_RANGE); // todo: prevIndex should be pre-calculated - int prevIndex = TRIGGER_SHAPE(triggerIndexByAngle[(int)previousAngle]); + int prevIndex = TRIGGER_WAVEFORM(triggerIndexByAngle[(int)previousAngle]); if (prevIndexOut != NULL) { *prevIndexOut = prevIndex; } // now let's get precise angle for that event - angle_t prevIndexAngle = TRIGGER_SHAPE(eventAngles[prevIndex]); + angle_t prevIndexAngle = TRIGGER_WAVEFORM(eventAngles[prevIndex]); efitick_t time90ago = timeOfLastEvent[prevIndex]; if (time90ago == 0) { return prevInstantRpmValue; @@ -260,7 +259,7 @@ void TriggerStateWithRunningStatistics::runtimeStatistics(efitime_t nowNt DECLAR instantRpm = calculateInstantRpm(&prevIndex, nowNt PASS_ENGINE_PARAMETER_SUFFIX); #if EFI_SENSOR_CHART - angle_t currentAngle = TRIGGER_SHAPE(eventAngles[currentCycle.current_index]); + angle_t currentAngle = TRIGGER_WAVEFORM(eventAngles[currentCycle.current_index]); if (CONFIGB(sensorChartMode) == SC_DETAILED_RPM) { scAddData(currentAngle, instantRpm); } else { @@ -304,10 +303,10 @@ static trigger_value_e eventType[6] = { TV_FALL, TV_RISE, TV_FALL, TV_RISE, TV_F PRINT_INC_INDEX; \ } -#define considerEventForGap() (!TRIGGER_SHAPE(useOnlyPrimaryForSync) || isPrimary) +#define considerEventForGap() (!TRIGGER_WAVEFORM(useOnlyPrimaryForSync) || isPrimary) -#define needToSkipFall(type) ((!TRIGGER_SHAPE(gapBothDirections)) && (( TRIGGER_SHAPE(useRiseEdge)) && (type != TV_RISE))) -#define needToSkipRise(type) ((!TRIGGER_SHAPE(gapBothDirections)) && ((!TRIGGER_SHAPE(useRiseEdge)) && (type != TV_FALL))) +#define needToSkipFall(type) ((!TRIGGER_WAVEFORM(gapBothDirections)) && (( TRIGGER_WAVEFORM(useRiseEdge)) && (type != TV_RISE))) +#define needToSkipRise(type) ((!TRIGGER_WAVEFORM(gapBothDirections)) && ((!TRIGGER_WAVEFORM(useRiseEdge)) && (type != TV_FALL))) int TriggerState::getCurrentIndex() const { return currentCycle.current_index; @@ -339,16 +338,16 @@ void TriggerState::onSynchronizationLost(DECLARE_ENGINE_PARAMETER_SIGNATURE) { } bool TriggerState::validateEventCounters(DECLARE_ENGINE_PARAMETER_SIGNATURE) const { - bool isDecodingError = currentCycle.eventCount[0] != TRIGGER_SHAPE(expectedEventCount[0]) - || currentCycle.eventCount[1] != TRIGGER_SHAPE(expectedEventCount[1]) - || currentCycle.eventCount[2] != TRIGGER_SHAPE(expectedEventCount[2]); + bool isDecodingError = currentCycle.eventCount[0] != TRIGGER_WAVEFORM(expectedEventCount[0]) + || currentCycle.eventCount[1] != TRIGGER_WAVEFORM(expectedEventCount[1]) + || currentCycle.eventCount[2] != TRIGGER_WAVEFORM(expectedEventCount[2]); #if EFI_UNIT_TEST - printf("sync point: isDecodingError=%d isInit=%d\r\n", isDecodingError, engine->isInitializingTrigger); + printf("sync point: isDecodingError=%d\r\n", isDecodingError); if (isDecodingError) { - printf("count: cur=%d exp=%d\r\n", currentCycle.eventCount[0], TRIGGER_SHAPE(expectedEventCount[0])); - printf("count: cur=%d exp=%d\r\n", currentCycle.eventCount[1], TRIGGER_SHAPE(expectedEventCount[1])); - printf("count: cur=%d exp=%d\r\n", currentCycle.eventCount[2], TRIGGER_SHAPE(expectedEventCount[2])); + printf("count: cur=%d exp=%d\r\n", currentCycle.eventCount[0], TRIGGER_WAVEFORM(expectedEventCount[0])); + printf("count: cur=%d exp=%d\r\n", currentCycle.eventCount[1], TRIGGER_WAVEFORM(expectedEventCount[1])); + printf("count: cur=%d exp=%d\r\n", currentCycle.eventCount[2], TRIGGER_WAVEFORM(expectedEventCount[2])); } #endif /* EFI_UNIT_TEST */ @@ -368,9 +367,9 @@ void TriggerState::handleTriggerError(DECLARE_ENGINE_PARAMETER_SIGNATURE) { currentCycle.eventCount[0], currentCycle.eventCount[1], currentCycle.eventCount[2], - TRIGGER_SHAPE(expectedEventCount[0]), - TRIGGER_SHAPE(expectedEventCount[1]), - TRIGGER_SHAPE(expectedEventCount[2])); + TRIGGER_WAVEFORM(expectedEventCount[0]), + TRIGGER_WAVEFORM(expectedEventCount[1]), + TRIGGER_WAVEFORM(expectedEventCount[2])); lastDecodingErrorTime = getTimeNowNt(); someSortOfTriggerError = true; @@ -378,14 +377,15 @@ void TriggerState::handleTriggerError(DECLARE_ENGINE_PARAMETER_SIGNATURE) { if (CONFIG(verboseTriggerSynchDetails) || (someSortOfTriggerError && !CONFIG(silentTriggerError))) { #if EFI_PROD_CODE scheduleMsg(logger, "error: synchronizationPoint @ index %d expected %d/%d/%d got %d/%d/%d", - currentCycle.current_index, TRIGGER_SHAPE(expectedEventCount[0]), - TRIGGER_SHAPE(expectedEventCount[1]), TRIGGER_SHAPE(expectedEventCount[2]), + currentCycle.current_index, TRIGGER_WAVEFORM(expectedEventCount[0]), + TRIGGER_WAVEFORM(expectedEventCount[1]), TRIGGER_WAVEFORM(expectedEventCount[2]), currentCycle.eventCount[0], currentCycle.eventCount[1], currentCycle.eventCount[2]); #endif /* EFI_PROD_CODE */ } } -void TriggerState::onShaftSynchronization(efitime_t nowNt, trigger_wheel_e triggerWheel DECLARE_ENGINE_PARAMETER_SUFFIX) { +void TriggerState::onShaftSynchronization(const TriggerStateCallback triggerCycleCallback, + efitime_t nowNt, trigger_wheel_e triggerWheel DECLARE_ENGINE_PARAMETER_SUFFIX) { setShaftSynchronized(true); // this call would update duty cycle values nextTriggerEvent() @@ -416,12 +416,14 @@ void TriggerState::onShaftSynchronization(efitime_t nowNt, trigger_wheel_e trigg * @param signal type of event which just happened * @param nowNt current time */ -void TriggerState::decodeTriggerEvent(trigger_event_e const signal, efitime_t nowNt DECLARE_ENGINE_PARAMETER_SUFFIX) { +void TriggerState::decodeTriggerEvent(const TriggerStateCallback triggerCycleCallback, + TriggerStateListener * triggerStateListener, + trigger_event_e const signal, efitime_t nowNt DECLARE_ENGINE_PARAMETER_SUFFIX) { ScopePerf perf(PE::DecodeTriggerEvent, static_cast(signal)); bool useOnlyRisingEdgeForTrigger = CONFIG(useOnlyRisingEdgeForTrigger); - // todo: use 'triggerShape' instead of TRIGGER_SHAPE in order to decouple this method from engine #635 - TriggerShape *triggerShape = &ENGINE(triggerCentral.triggerShape); + // todo: use 'triggerShape' instead of TRIGGER_WAVEFORM in order to decouple this method from engine #635 + TriggerWaveform *triggerShape = &ENGINE(triggerCentral.triggerShape); efiAssertVoid(CUSTOM_ERR_6640, signal <= SHAFT_3RD_RISING, "unexpected signal"); @@ -448,15 +450,16 @@ void TriggerState::decodeTriggerEvent(trigger_event_e const signal, efitime_t no toothDurations[0] = currentDurationLong > 10 * US2NT(US_PER_SECOND_LL) ? 10 * US2NT(US_PER_SECOND_LL) : currentDurationLong; + bool haveListener = triggerStateListener != NULL; bool isPrimary = triggerWheel == T_PRIMARY; if (needToSkipFall(type) || needToSkipRise(type) || (!considerEventForGap())) { #if EFI_UNIT_TEST if (printTriggerDebug) { - printf("%s isLessImportant %s now=%lld index=%d\r\n", + printf("%s isLessImportant %s now=%d index=%d\r\n", getTrigger_type_e(engineConfiguration->trigger.type), getTrigger_event_e(signal), - nowNt, + (int)nowNt, currentCycle.current_index); } #endif /* EFI_UNIT_TEST */ @@ -533,7 +536,7 @@ void TriggerState::decodeTriggerEvent(trigger_event_e const signal, efitime_t no bool isSync = true; for (int i = 0;isyncronizationRatioFrom[i]) || (toothDurations[i] > toothDurations[i + 1] * TRIGGER_SHAPE(syncronizationRatioFrom[i]) + bool isGapCondition = cisnan(triggerShape->syncronizationRatioFrom[i]) || (toothDurations[i] > toothDurations[i + 1] * TRIGGER_WAVEFORM(syncronizationRatioFrom[i]) && toothDurations[i] < toothDurations[i + 1] * triggerShape->syncronizationRatioTo[i]); isSync &= isGapCondition; @@ -568,8 +571,8 @@ void TriggerState::decodeTriggerEvent(trigger_event_e const signal, efitime_t no /* cast is needed to make sure we do not put 64 bit value to stack*/ (int)getTimeNowSeconds(), i, gap, - TRIGGER_SHAPE(syncronizationRatioFrom[i]), - TRIGGER_SHAPE(syncronizationRatioTo[i]), + TRIGGER_WAVEFORM(syncronizationRatioFrom[i]), + TRIGGER_WAVEFORM(syncronizationRatioTo[i]), boolToString(someSortOfTriggerError)); } } @@ -582,8 +585,8 @@ void TriggerState::decodeTriggerEvent(trigger_event_e const signal, efitime_t no print("index=%d: gap=%.2f expected from %.2f to %.2f error=%s\r\n", i, gap, - TRIGGER_SHAPE(syncronizationRatioFrom[i]), - TRIGGER_SHAPE(syncronizationRatioTo[i]), + TRIGGER_WAVEFORM(syncronizationRatioFrom[i]), + TRIGGER_WAVEFORM(syncronizationRatioTo[i]), boolToString(someSortOfTriggerError)); } } @@ -646,21 +649,23 @@ void TriggerState::decodeTriggerEvent(trigger_event_e const signal, efitime_t no enginePins.triggerDecoderErrorPin.setValue(isDecodingError); - if (isDecodingError && !engine->isInitializingTrigger) { - handleTriggerError(PASS_ENGINE_PARAMETER_SIGNATURE); + // 'haveListener' means we are running a real engine and now just preparing trigger shape + // that's a bit of a hack, a sweet OOP solution would be a real callback or at least 'needDecodingErrorLogic' method? + if (isDecodingError && haveListener) { + triggerStateListener->OnTriggerStateDecodingError(); } errorDetection.add(isDecodingError); if (isTriggerDecoderError()) { warning(CUSTOM_OBD_TRG_DECODING, "trigger decoding issue. expected %d/%d/%d got %d/%d/%d", - TRIGGER_SHAPE(expectedEventCount[0]), TRIGGER_SHAPE(expectedEventCount[1]), - TRIGGER_SHAPE(expectedEventCount[2]), currentCycle.eventCount[0], currentCycle.eventCount[1], + TRIGGER_WAVEFORM(expectedEventCount[0]), TRIGGER_WAVEFORM(expectedEventCount[1]), + TRIGGER_WAVEFORM(expectedEventCount[2]), currentCycle.eventCount[0], currentCycle.eventCount[1], currentCycle.eventCount[2]); } } - onShaftSynchronization(nowNt, triggerWheel PASS_ENGINE_PARAMETER_SUFFIX); + onShaftSynchronization(triggerCycleCallback, nowNt, triggerWheel PASS_ENGINE_PARAMETER_SUFFIX); } else { /* if (!isSynchronizationPoint) */ nextTriggerEvent() @@ -673,7 +678,7 @@ void TriggerState::decodeTriggerEvent(trigger_event_e const signal, efitime_t no toothed_previous_time = nowNt; } - if (!isValidIndex(PASS_ENGINE_PARAMETER_SIGNATURE) && !engine->isInitializingTrigger) { + if (!isValidIndex(PASS_ENGINE_PARAMETER_SIGNATURE) && haveListener) { // let's not show a warning if we are just starting to spin if (GET_RPM_VALUE != 0) { warning(CUSTOM_SYNC_ERROR, "sync error: index #%d above total size %d", currentCycle.current_index, getTriggerSize()); @@ -690,8 +695,8 @@ void TriggerState::decodeTriggerEvent(trigger_event_e const signal, efitime_t no runtimeStatistics(nowNt PASS_ENGINE_PARAMETER_SUFFIX); // Needed for early instant-RPM detection - if (!engine->isInitializingTrigger) { - engine->rpmCalculator.setSpinningUp(nowNt PASS_ENGINE_PARAMETER_SUFFIX); + if (haveListener) { + triggerStateListener->OnTriggerStateProperState(nowNt); } } @@ -706,9 +711,9 @@ static void onFindIndexCallback(TriggerState *state) { * Trigger shape is defined in a way which is convenient for trigger shape definition * On the other hand, trigger decoder indexing begins from synchronization event. * - * This function finds the index of synchronization event within TriggerShape + * This function finds the index of synchronization event within TriggerWaveform */ -uint32_t findTriggerZeroEventIndex(TriggerState *state, TriggerShape * shape, +uint32_t findTriggerZeroEventIndex(TriggerState *state, TriggerWaveform * shape, trigger_config_s const*triggerConfig DECLARE_ENGINE_PARAMETER_SUFFIX) { UNUSED(triggerConfig); #if EFI_PROD_CODE @@ -723,14 +728,12 @@ uint32_t findTriggerZeroEventIndex(TriggerState *state, TriggerShape * shape, return 0; } - engine->isInitializingTrigger = true; // todo: should this variable be declared 'static' to reduce stack usage? TriggerStimulatorHelper helper; uint32_t syncIndex = helper.findTriggerSyncPoint(shape, state PASS_ENGINE_PARAMETER_SUFFIX); if (syncIndex == EFI_ERROR_CODE) { - engine->isInitializingTrigger = false; return syncIndex; } efiAssert(CUSTOM_ERR_ASSERT, state->getTotalRevolutionCounter() == 1, "findZero_revCounter", EFI_ERROR_CODE); @@ -747,11 +750,9 @@ uint32_t findTriggerZeroEventIndex(TriggerState *state, TriggerShape * shape, * * todo: add a comment why are we doing '2 * shape->getSize()' here? */ - state->triggerCycleCallback = onFindIndexCallback; - helper.assertSyncPositionAndSetDutyCycle(syncIndex, state, shape PASS_ENGINE_PARAMETER_SUFFIX); + helper.assertSyncPositionAndSetDutyCycle(onFindIndexCallback, syncIndex, state, shape PASS_ENGINE_PARAMETER_SUFFIX); - engine->isInitializingTrigger = false; return syncIndex % shape->getSize(); } diff --git a/firmware/controllers/trigger/trigger_decoder.h b/firmware/controllers/trigger/trigger_decoder.h index c9f69c52d1..53b1a8dc04 100644 --- a/firmware/controllers/trigger/trigger_decoder.h +++ b/firmware/controllers/trigger/trigger_decoder.h @@ -2,11 +2,10 @@ * @file trigger_decoder.h * * @date Dec 24, 2013 - * @author Andrey Belomutskiy, (c) 2012-2017 + * @author Andrey Belomutskiy, (c) 2012-2019 */ -#ifndef TRIGGER_DECODER_H_ -#define TRIGGER_DECODER_H_ +#pragma once #include "global.h" #include "trigger_structure.h" @@ -15,6 +14,12 @@ class TriggerState; +class TriggerStateListener { + public: + virtual void OnTriggerStateDecodingError() = 0; + virtual void OnTriggerStateProperState(efitick_t nowNt) = 0; +}; + typedef void (*TriggerStateCallback)(TriggerState *); typedef struct { @@ -25,7 +30,7 @@ typedef struct { /** * Number of actual events of each channel within current trigger cycle, these * values are used to detect trigger signal errors. - * see TriggerShape + * see TriggerWaveform */ uint32_t eventCount[PWM_PHASE_MAX_WAVE_PER_PWM]; /** @@ -43,7 +48,7 @@ typedef struct { } current_cycle_state_s; /** - * @see TriggerShape for trigger wheel shape definition + * @see TriggerWaveform for trigger wheel shape definition */ class TriggerState : public trigger_state_s { public: @@ -59,10 +64,15 @@ public: bool isEvenRevolution() const; void incrementTotalEventCounter(); efitime_t getTotalEventCounter() const; - void decodeTriggerEvent(trigger_event_e const signal, efitime_t nowUs DECLARE_ENGINE_PARAMETER_SUFFIX); + + void decodeTriggerEvent(const TriggerStateCallback triggerCycleCallback, + TriggerStateListener * triggerStateListener, + trigger_event_e const signal, efitime_t nowUs DECLARE_ENGINE_PARAMETER_SUFFIX); + bool validateEventCounters(DECLARE_ENGINE_PARAMETER_SIGNATURE) const; void handleTriggerError(DECLARE_ENGINE_PARAMETER_SIGNATURE); - void onShaftSynchronization(efitime_t nowNt, trigger_wheel_e triggerWheel DECLARE_ENGINE_PARAMETER_SUFFIX); + void onShaftSynchronization(const TriggerStateCallback triggerCycleCallback, + efitime_t nowNt, trigger_wheel_e triggerWheel DECLARE_ENGINE_PARAMETER_SUFFIX); /** * Resets synchronization flag and alerts rpm_calculator to reset engine spinning flag. */ @@ -70,7 +80,6 @@ public: bool isValidIndex(DECLARE_ENGINE_PARAMETER_SIGNATURE) const; float getTriggerDutyCycle(int index); - TriggerStateCallback triggerCycleCallback; /** * TRUE if we know where we are @@ -126,7 +135,7 @@ private: /** - * the reason for sub-class is simply to save RAM but not having statisics in the trigger initialization instance + * the reason for sub-class is simply to save RAM but not having statistics in the trigger initialization instance */ class TriggerStateWithRunningStatistics : public TriggerState { public: @@ -161,7 +170,7 @@ public: }; angle_t getEngineCycle(operation_mode_e operationMode); -uint32_t findTriggerZeroEventIndex(TriggerState *state, TriggerShape * shape, trigger_config_s const*triggerConfig DECLARE_ENGINE_PARAMETER_SUFFIX); +uint32_t findTriggerZeroEventIndex(TriggerState *state, TriggerWaveform * shape, trigger_config_s const*triggerConfig DECLARE_ENGINE_PARAMETER_SUFFIX); class Engine; @@ -170,7 +179,5 @@ void initTriggerDecoderLogger(Logging *sharedLogger); bool isTriggerDecoderError(void); -void calculateTriggerSynchPoint(TriggerShape *shape, TriggerState *state DECLARE_ENGINE_PARAMETER_SUFFIX); +void calculateTriggerSynchPoint(TriggerWaveform *shape, TriggerState *state DECLARE_ENGINE_PARAMETER_SUFFIX); - -#endif /* TRIGGER_DECODER_H_ */ diff --git a/firmware/controllers/trigger/trigger_emulator_algo.cpp b/firmware/controllers/trigger/trigger_emulator_algo.cpp index c1d99c845a..c022a79f66 100644 --- a/firmware/controllers/trigger/trigger_emulator_algo.cpp +++ b/firmware/controllers/trigger/trigger_emulator_algo.cpp @@ -2,7 +2,7 @@ * @file trigger_emulator_algo.cpp * * This file is about producing real electrical signals which emulate trigger signal based on - * a known TriggerShape. + * a known TriggerWaveform. * * Historically this implementation was implemented based on PwmConfig which is maybe not the * best way to implement it. (todo: why is not the best way?) @@ -13,18 +13,18 @@ * @date Mar 3, 2014 * @author Andrey Belomutskiy, (c) 2012-2018 */ +#include "state_sequence.h" #include "global.h" #include "efi_gpio.h" -#include "efi_wave.h" int getPreviousIndex(const int currentIndex, const int size) { return (currentIndex + size - 1) % size; } -bool needEvent(const int currentIndex, const int size, MultiWave *multiWave, int channelIndex) { +bool needEvent(const int currentIndex, const int size, MultiChannelStateSequence *multiChannelStateSequence, int channelIndex) { int prevIndex = getPreviousIndex(currentIndex, size); - pin_state_t previousValue = multiWave->getChannelState(channelIndex, /*phaseIndex*/prevIndex); - pin_state_t currentValue = multiWave->getChannelState(channelIndex, /*phaseIndex*/currentIndex); + pin_state_t previousValue = multiChannelStateSequence->getChannelState(channelIndex, /*phaseIndex*/prevIndex); + pin_state_t currentValue = multiChannelStateSequence->getChannelState(channelIndex, /*phaseIndex*/currentIndex); return previousValue != currentValue; } @@ -46,20 +46,20 @@ EXTERN_ENGINE void TriggerEmulatorHelper::handleEmulatorCallback(PwmConfig *state, int stateIndex) { // todo: code duplication with TriggerStimulatorHelper::feedSimulatedEvent? - MultiWave *multiWave = &state->multiWave; + MultiChannelStateSequence *multiChannelStateSequence = &state->multiChannelStateSequence; - if (needEvent(stateIndex, state->phaseCount, &state->multiWave, 0)) { - pin_state_t currentValue = multiWave->getChannelState(/*phaseIndex*/0, stateIndex); + if (needEvent(stateIndex, state->phaseCount, &state->multiChannelStateSequence, 0)) { + pin_state_t currentValue = multiChannelStateSequence->getChannelState(/*phaseIndex*/0, stateIndex); hwHandleShaftSignal(currentValue ? SHAFT_PRIMARY_RISING : SHAFT_PRIMARY_FALLING); } - if (needEvent(stateIndex, state->phaseCount, &state->multiWave, 1)) { - pin_state_t currentValue = multiWave->getChannelState(/*phaseIndex*/1, stateIndex); + if (needEvent(stateIndex, state->phaseCount, &state->multiChannelStateSequence, 1)) { + pin_state_t currentValue = multiChannelStateSequence->getChannelState(/*phaseIndex*/1, stateIndex); hwHandleShaftSignal(currentValue ? SHAFT_SECONDARY_RISING : SHAFT_SECONDARY_FALLING); } - if (needEvent(stateIndex, state->phaseCount, &state->multiWave, 2)) { - pin_state_t currentValue = multiWave->getChannelState(/*phaseIndex*/2, stateIndex); + if (needEvent(stateIndex, state->phaseCount, &state->multiChannelStateSequence, 2)) { + pin_state_t currentValue = multiChannelStateSequence->getChannelState(/*phaseIndex*/2, stateIndex); hwHandleShaftSignal(currentValue ? SHAFT_3RD_RISING : SHAFT_3RD_FALLING); } @@ -73,9 +73,9 @@ void TriggerEmulatorHelper::handleEmulatorCallback(PwmConfig *state, int stateIn static pin_state_t pinStates1[PWM_PHASE_MAX_COUNT]; static pin_state_t pinStates2[PWM_PHASE_MAX_COUNT]; static pin_state_t pinStates3[PWM_PHASE_MAX_COUNT]; -static SingleWave waves[PWM_PHASE_MAX_WAVE_PER_PWM] = { SingleWave(pinStates1), SingleWave(pinStates2), - SingleWave(pinStates3) }; -static SingleWave sr[PWM_PHASE_MAX_WAVE_PER_PWM] = { waves[0], waves[1], waves[2] }; +static SingleChannelStateSequence waves[PWM_PHASE_MAX_WAVE_PER_PWM] = { SingleChannelStateSequence(pinStates1), SingleChannelStateSequence(pinStates2), + SingleChannelStateSequence(pinStates3) }; +static SingleChannelStateSequence sr[PWM_PHASE_MAX_WAVE_PER_PWM] = { waves[0], waves[1], waves[2] }; static float switchTimesBuffer[PWM_PHASE_MAX_COUNT]; @@ -115,14 +115,14 @@ void setTriggerEmulatorRPM(int rpm DECLARE_ENGINE_PARAMETER_SUFFIX) { scheduleMsg(logger, "Emulating position sensor(s). RPM=%d", rpm); } -static void updateTriggerShapeIfNeeded(PwmConfig *state) { +static void updateTriggerWaveformIfNeeded(PwmConfig *state) { if (atTriggerVersion < engine->triggerCentral.triggerShape.version) { atTriggerVersion = engine->triggerCentral.triggerShape.version; scheduleMsg(logger, "Stimulator: updating trigger shape: %d/%d %d", atTriggerVersion, engine->getGlobalConfigurationVersion(), currentTimeMillis()); - TriggerShape *s = &engine->triggerCentral.triggerShape; + TriggerWaveform *s = &engine->triggerCentral.triggerShape; pin_state_t *pinStates[PWM_PHASE_MAX_WAVE_PER_PWM] = { s->wave.channels[0].pinStates, s->wave.channels[1].pinStates, @@ -164,7 +164,7 @@ static void resumeStimulator() { void initTriggerEmulatorLogic(Logging *sharedLogger DECLARE_ENGINE_PARAMETER_SUFFIX) { logger = sharedLogger; - TriggerShape *s = &engine->triggerCentral.triggerShape; + TriggerWaveform *s = &engine->triggerCentral.triggerShape; setTriggerEmulatorRPM(engineConfiguration->bc.triggerSimulatorFrequency PASS_ENGINE_PARAMETER_SUFFIX); pin_state_t *pinStates[PWM_PHASE_MAX_WAVE_PER_PWM] = { s->wave.channels[0].pinStates, @@ -173,7 +173,7 @@ void initTriggerEmulatorLogic(Logging *sharedLogger DECLARE_ENGINE_PARAMETER_SUF triggerSignal.weComplexInit("position sensor", &engine->executor, s->getSize(), s->wave.switchTimes, PWM_PHASE_MAX_WAVE_PER_PWM, - pinStates, updateTriggerShapeIfNeeded, (pwm_gen_callback*)emulatorApplyPinState); + pinStates, updateTriggerWaveformIfNeeded, (pwm_gen_callback*)emulatorApplyPinState); addConsoleActionI("rpm", setTriggerEmulatorRPM); addConsoleActionI("stop_stimulator_at_index", setEmulatorAtIndex); diff --git a/firmware/controllers/trigger/trigger_emulator_algo.h b/firmware/controllers/trigger/trigger_emulator_algo.h index edba7e98e7..8cfe0fa118 100644 --- a/firmware/controllers/trigger/trigger_emulator_algo.h +++ b/firmware/controllers/trigger/trigger_emulator_algo.h @@ -20,6 +20,6 @@ public: void initTriggerEmulatorLogic(Logging *sharedLogger DECLARE_ENGINE_PARAMETER_SUFFIX); int getPreviousIndex(const int currentIndex, const int size); -bool needEvent(const int currentIndex, const int size, MultiWave *multiWave, int channelIndex); +bool needEvent(const int currentIndex, const int size, MultiChannelStateSequence *multiChannelStateSequence, int channelIndex); #endif /* TRIGGER_EMULATOR_ALGO_H_ */ diff --git a/firmware/controllers/trigger/trigger_simulator.cpp b/firmware/controllers/trigger/trigger_simulator.cpp index 963bfee0b8..2596e9846b 100644 --- a/firmware/controllers/trigger/trigger_simulator.cpp +++ b/firmware/controllers/trigger/trigger_simulator.cpp @@ -14,9 +14,6 @@ EXTERN_ENGINE; -TriggerStimulatorHelper::TriggerStimulatorHelper() { -} - // this is not the only place where we have 'isUpEvent'. todo: reuse static const bool isRisingEdge[6] = { false, true, false, true, false, true }; @@ -29,7 +26,8 @@ bool isUsefulSignal(trigger_event_e signal DECLARE_ENGINE_PARAMETER_SUFFIX) { extern bool printTriggerDebug; #endif /* ! EFI_UNIT_TEST */ -void TriggerStimulatorHelper::feedSimulatedEvent(TriggerState *state, TriggerShape * shape, int i +void TriggerStimulatorHelper::feedSimulatedEvent(const TriggerStateCallback triggerCycleCallback, + TriggerState *state, TriggerWaveform * shape, int i DECLARE_ENGINE_PARAMETER_SUFFIX) { efiAssertVoid(CUSTOM_ERR_6593, shape->getSize() > 0, "size not zero"); int stateIndex = i % shape->getSize(); @@ -39,19 +37,19 @@ void TriggerStimulatorHelper::feedSimulatedEvent(TriggerState *state, TriggerSha int time = (int) (SIMULATION_CYCLE_PERIOD * (loopIndex + shape->wave.getSwitchTime(stateIndex))); - MultiWave *multiWave = &shape->wave; + MultiChannelStateSequence *multiChannelStateSequence = &shape->wave; #if EFI_UNIT_TEST int prevIndex = getPreviousIndex(stateIndex, shape->getSize()); - pin_state_t primaryWheelState = multiWave->getChannelState(0, prevIndex); - pin_state_t newPrimaryWheelState = multiWave->getChannelState(0, stateIndex); + pin_state_t primaryWheelState = multiChannelStateSequence->getChannelState(0, prevIndex); + pin_state_t newPrimaryWheelState = multiChannelStateSequence->getChannelState(0, stateIndex); - pin_state_t secondaryWheelState = multiWave->getChannelState(1, prevIndex); - pin_state_t newSecondaryWheelState = multiWave->getChannelState(1, stateIndex); + pin_state_t secondaryWheelState = multiChannelStateSequence->getChannelState(1, prevIndex); + pin_state_t newSecondaryWheelState = multiChannelStateSequence->getChannelState(1, stateIndex); -// pin_state_t thirdWheelState = multiWave->getChannelState(2, prevIndex); -// pin_state_t new3rdWheelState = multiWave->getChannelState(2, stateIndex); +// pin_state_t thirdWheelState = multiChannelStateSequence->getChannelState(2, prevIndex); +// pin_state_t new3rdWheelState = multiChannelStateSequence->getChannelState(2, stateIndex); if (printTriggerDebug) { printf("feedSimulatedEvent: %d>%d primary %d>%d secondary %d>%d\r\n", prevIndex, stateIndex, primaryWheelState, newPrimaryWheelState, @@ -62,40 +60,50 @@ void TriggerStimulatorHelper::feedSimulatedEvent(TriggerState *state, TriggerSha // todo: code duplication with TriggerEmulatorHelper::handleEmulatorCallback? - if (needEvent(stateIndex, size, multiWave, 0)) { - pin_state_t currentValue = multiWave->getChannelState(/*phaseIndex*/0, stateIndex); + if (needEvent(stateIndex, size, multiChannelStateSequence, 0)) { + pin_state_t currentValue = multiChannelStateSequence->getChannelState(/*phaseIndex*/0, stateIndex); trigger_event_e s = currentValue ? SHAFT_PRIMARY_RISING : SHAFT_PRIMARY_FALLING; - if (isUsefulSignal(s PASS_ENGINE_PARAMETER_SUFFIX)) - state->decodeTriggerEvent(s, time PASS_ENGINE_PARAMETER_SUFFIX); + if (isUsefulSignal(s PASS_ENGINE_PARAMETER_SUFFIX)) { + state->decodeTriggerEvent(triggerCycleCallback, + /* override */ nullptr, + s, time PASS_ENGINE_PARAMETER_SUFFIX); + } } - if (needEvent(stateIndex, size, multiWave, 1)) { - pin_state_t currentValue = multiWave->getChannelState(/*phaseIndex*/1, stateIndex); + if (needEvent(stateIndex, size, multiChannelStateSequence, 1)) { + pin_state_t currentValue = multiChannelStateSequence->getChannelState(/*phaseIndex*/1, stateIndex); trigger_event_e s = currentValue ? SHAFT_SECONDARY_RISING : SHAFT_SECONDARY_FALLING; - if (isUsefulSignal(s PASS_ENGINE_PARAMETER_SUFFIX)) - state->decodeTriggerEvent(s, time PASS_ENGINE_PARAMETER_SUFFIX); + if (isUsefulSignal(s PASS_ENGINE_PARAMETER_SUFFIX)) { + state->decodeTriggerEvent(triggerCycleCallback, + /* override */ nullptr, + s, time PASS_ENGINE_PARAMETER_SUFFIX); + } } - if (needEvent(stateIndex, size, multiWave, 2)) { - pin_state_t currentValue = multiWave->getChannelState(/*phaseIndex*/2, stateIndex); + if (needEvent(stateIndex, size, multiChannelStateSequence, 2)) { + pin_state_t currentValue = multiChannelStateSequence->getChannelState(/*phaseIndex*/2, stateIndex); trigger_event_e s = currentValue ? SHAFT_3RD_RISING : SHAFT_3RD_FALLING; - if (isUsefulSignal(s PASS_ENGINE_PARAMETER_SUFFIX)) - state->decodeTriggerEvent(s, time PASS_ENGINE_PARAMETER_SUFFIX); + if (isUsefulSignal(s PASS_ENGINE_PARAMETER_SUFFIX)) { + state->decodeTriggerEvent(triggerCycleCallback, + /* override */ nullptr, + s, time PASS_ENGINE_PARAMETER_SUFFIX); + } } } -void TriggerStimulatorHelper::assertSyncPositionAndSetDutyCycle(const uint32_t syncIndex, TriggerState *state, TriggerShape * shape +void TriggerStimulatorHelper::assertSyncPositionAndSetDutyCycle(const TriggerStateCallback triggerCycleCallback, + const uint32_t syncIndex, TriggerState *state, TriggerWaveform * shape DECLARE_ENGINE_PARAMETER_SUFFIX) { /** * let's feed two more cycles to validate shape definition */ for (uint32_t i = syncIndex + 1; i <= syncIndex + GAP_TRACKING_LENGTH * shape->getSize(); i++) { - feedSimulatedEvent(state, shape, i PASS_ENGINE_PARAMETER_SUFFIX); + feedSimulatedEvent(triggerCycleCallback, state, shape, i PASS_ENGINE_PARAMETER_SUFFIX); } int revolutionCounter = state->getTotalRevolutionCounter(); if (revolutionCounter != GAP_TRACKING_LENGTH + 1) { - warning(CUSTOM_OBD_TRIGGER_SHAPE, "sync failed/wrong gap parameters trigger=%s rc=%d", getTrigger_type_e(engineConfiguration->trigger.type), revolutionCounter); + warning(CUSTOM_OBD_TRIGGER_WAVEFORM, "sync failed/wrong gap parameters trigger=%s rc=%d", getTrigger_type_e(engineConfiguration->trigger.type), revolutionCounter); shape->setShapeDefinitionError(true); return; } @@ -109,10 +117,10 @@ void TriggerStimulatorHelper::assertSyncPositionAndSetDutyCycle(const uint32_t s /** * @return trigger synchronization point index, or error code if not found */ -uint32_t TriggerStimulatorHelper::findTriggerSyncPoint(TriggerShape * shape, +uint32_t TriggerStimulatorHelper::findTriggerSyncPoint(TriggerWaveform * shape, TriggerState *state DECLARE_ENGINE_PARAMETER_SUFFIX) { for (int i = 0; i < 4 * PWM_PHASE_MAX_COUNT; i++) { - feedSimulatedEvent(state, shape, i PASS_ENGINE_PARAMETER_SUFFIX); + feedSimulatedEvent(nullptr, state, shape, i PASS_ENGINE_PARAMETER_SUFFIX); if (state->shaft_is_synchronized) return i; diff --git a/firmware/controllers/trigger/trigger_simulator.h b/firmware/controllers/trigger/trigger_simulator.h index 5453e93c13..44fa8c0d01 100644 --- a/firmware/controllers/trigger/trigger_simulator.h +++ b/firmware/controllers/trigger/trigger_simulator.h @@ -3,29 +3,26 @@ * @brief This class knows how to produce synthetic shaft signals based on triggerShape * * @date Sep 23, 2015 - * @author Andrey Belomutskiy, (c) 2012-2017 + * @author Andrey Belomutskiy, (c) 2012-2019 */ -#ifndef CONTROLLERS_TRIGGER_TRIGGER_SIMULATOR_H_ -#define CONTROLLERS_TRIGGER_TRIGGER_SIMULATOR_H_ +#pragma once #include "trigger_decoder.h" class TriggerStimulatorHelper { public: - TriggerStimulatorHelper(); - uint32_t findTriggerSyncPoint(TriggerShape * shape, + uint32_t findTriggerSyncPoint(TriggerWaveform * shape, TriggerState *state DECLARE_ENGINE_PARAMETER_SUFFIX); - void assertSyncPositionAndSetDutyCycle(const uint32_t index, TriggerState *state, TriggerShape * shape + void assertSyncPositionAndSetDutyCycle(const TriggerStateCallback triggerCycleCallback, + const uint32_t index, TriggerState *state, TriggerWaveform * shape DECLARE_ENGINE_PARAMETER_SUFFIX); private: // send next event so that we can see how state reacts - void feedSimulatedEvent(TriggerState *state, TriggerShape * shape, int i DECLARE_ENGINE_PARAMETER_SUFFIX); + void feedSimulatedEvent(const TriggerStateCallback triggerCycleCallback, TriggerState *state, TriggerWaveform * shape, int i DECLARE_ENGINE_PARAMETER_SUFFIX); }; bool isUsefulSignal(trigger_event_e signal DECLARE_ENGINE_PARAMETER_SUFFIX); - -#endif /* CONTROLLERS_TRIGGER_TRIGGER_SIMULATOR_H_ */ diff --git a/firmware/development/development.mk b/firmware/development/development.mk index 7b4624017e..4ccc15e29a 100644 --- a/firmware/development/development.mk +++ b/firmware/development/development.mk @@ -9,7 +9,7 @@ DEV_SRC_CPP = $(DEVELOPMENT_DIR)/trigger_emulator.cpp \ $(DEVELOPMENT_DIR)/rfi_perftest.cpp \ $(DEVELOPMENT_DIR)/engine_emulator.cpp \ $(DEVELOPMENT_DIR)/engine_sniffer.cpp \ - $(DEVELOPMENT_DIR)/wave_analyzer.cpp \ + $(DEVELOPMENT_DIR)/logic_analyzer.cpp \ $(DEVELOPMENT_DIR)/development/perf_trace.cpp DEV_SIMULATOR_SRC_CPP = $(DEVELOPMENT_DIR)/engine_sniffer.cpp \ No newline at end of file diff --git a/firmware/development/engine_emulator.cpp b/firmware/development/engine_emulator.cpp index 17cb871f3e..bbd28ac21a 100644 --- a/firmware/development/engine_emulator.cpp +++ b/firmware/development/engine_emulator.cpp @@ -15,7 +15,7 @@ #include "fuel_math.h" #include "status_loop.h" -#include "wave_analyzer.h" +#include "logic_analyzer.h" #include "pin_repository.h" #include "pwm_generator_logic.h" diff --git a/firmware/development/engine_sniffer.cpp b/firmware/development/engine_sniffer.cpp index 66fa82edef..6be646565a 100644 --- a/firmware/development/engine_sniffer.cpp +++ b/firmware/development/engine_sniffer.cpp @@ -5,7 +5,7 @@ * Here we have our own build-in logic analyzer. The data we aggregate here is sent to the * java UI rusEfi Console so that it can be displayed nicely in the Sniffer tab. * - * Both external events (see wave_analyzer.c) and internal (see signal executors) are supported + * Both external events (see logic_analyzer.cpp) and internal (see signal executors) are supported * * @date Jun 23, 2013 * @author Andrey Belomutskiy, (c) 2012-2019 diff --git a/firmware/development/wave_analyzer.cpp b/firmware/development/logic_analyzer.cpp similarity index 98% rename from firmware/development/wave_analyzer.cpp rename to firmware/development/logic_analyzer.cpp index bb74ebdccb..b9e0317bcd 100644 --- a/firmware/development/wave_analyzer.cpp +++ b/firmware/development/logic_analyzer.cpp @@ -1,5 +1,5 @@ /** - * @file wave_analyzer.cpp + * @file logic_analyzer.cpp * @brief Initialization of Input Capture pins used for rusEfi console sniffer * * This file is responsible for sniffing of external digital signals and registering @@ -11,9 +11,10 @@ * @author Andrey Belomutskiy, (c) 2012-2019 */ +#include "logic_analyzer.h" + #include "global.h" #include "os_access.h" -#include "wave_analyzer.h" #include "eficonsole.h" #include "data_buffer.h" #include "pin_repository.h" @@ -26,7 +27,7 @@ #include "rpm_calculator.h" #include "engine_sniffer.h" -#if EFI_WAVE_ANALYZER +#if EFI_LOGIC_ANALYZER EXTERN_ENGINE; @@ -231,4 +232,4 @@ void initWaveAnalyzer(Logging *sharedLogger) { } -#endif /* EFI_WAVE_ANALYZER */ +#endif /* EFI_LOGIC_ANALYZER */ diff --git a/firmware/development/wave_analyzer.h b/firmware/development/logic_analyzer.h similarity index 82% rename from firmware/development/wave_analyzer.h rename to firmware/development/logic_analyzer.h index 115d6e902a..3be7f561af 100644 --- a/firmware/development/wave_analyzer.h +++ b/firmware/development/logic_analyzer.h @@ -1,18 +1,15 @@ /** - * @file wave_analyzer.h - * - * todo: rename all this 'logic analyzer' is probably much more appropriate + * @file logic_analyzer.h * * @date Jan 7, 2013 - * @author Andrey Belomutskiy, (c) 2012-2017 + * @author Andrey Belomutskiy, (c) 2012-2019 */ -#ifndef WAVE_ANALYZER_H_ -#define WAVE_ANALYZER_H_ +#pragma once #include "global.h" -#if EFI_WAVE_ANALYZER +#if EFI_LOGIC_ANALYZER #include "digital_input_icu.h" #include "engine_sniffer.h" @@ -57,7 +54,5 @@ void initWaveAnalyzer(Logging *sharedLogger); void printWave(Logging *logging); void showWaveInfo(void); -#endif - -#endif /* WAVE_ANALYZER_H_ */ +#endif /* EFI_LOGIC_ANALYZER */ diff --git a/firmware/development/perf_trace.cpp b/firmware/development/perf_trace.cpp index 3e1f328cda..66c570e590 100644 --- a/firmware/development/perf_trace.cpp +++ b/firmware/development/perf_trace.cpp @@ -1,3 +1,9 @@ +/** + * @file perf_trace.cpp + * + * See JsonOutput.java in rusEfi console + */ + #include "efifeatures.h" #include "perf_trace.h" @@ -26,30 +32,40 @@ struct TraceEntry uint32_t Timestamp; }; +// Ensure that the struct is the size we think it is - the binary layout is important static_assert(sizeof(TraceEntry) == 8); +// This buffer stores a trace - we write the full buffer once, then disable tracing static TraceEntry s_traceBuffer[TRACE_BUFFER_LENGTH]; static size_t s_nextIdx = 0; -static bool s_isTracing = true; +static bool s_isTracing = false; void perfEventImpl(PE event, EPhase phase, uint8_t data) { + // Bail if we aren't allowed to trace if constexpr (!ENABLE_PERF_TRACE) { return; } + // Bail if we aren't tracing if (!s_isTracing) { return; } - uint32_t timestamp = getTimeNowLowerNt(); + // todo: why doesn't getTimeNowLowerNt() work here? + // It returns 0 like we're in a unit test + uint32_t timestamp = port_rt_get_counter_value(); size_t idx; - // Critical section: reserve index under lock + // Critical section: disable interrupts to reserve an index. + // We could lock, but this gets called a LOT - so locks could + // significantly alter the results of the measurement. + // In addition, if we want to trace lock/unlock events, we can't + // be locking ourselves from the trace functionality. { - bool wasLocked = lockAnyContext(); + __disable_irq(); idx = s_nextIdx++; if (s_nextIdx >= TRACE_BUFFER_LENGTH) { @@ -57,9 +73,7 @@ void perfEventImpl(PE event, EPhase phase, uint8_t data) s_isTracing = false; } - if (!wasLocked) { - unlockAnyContext(); - } + __enable_irq(); } // We can safely write data out of the lock, our spot is reserved @@ -67,6 +81,7 @@ void perfEventImpl(PE event, EPhase phase, uint8_t data) entry.Event = event; entry.Phase = phase; + // Get the current active interrupt - this is the "thread ID" entry.ThreadId = static_cast(SCB->ICSR & SCB_ICSR_VECTACTIVE_Msk); entry.Timestamp = timestamp; entry.Data = data; diff --git a/firmware/development/perf_trace.h b/firmware/development/perf_trace.h index 9572fe2188..a45120480b 100644 --- a/firmware/development/perf_trace.h +++ b/firmware/development/perf_trace.h @@ -1,4 +1,7 @@ - +/** + * @file perf_trace.h + * + */ #pragma once #include @@ -7,8 +10,10 @@ // Defines different events we want to trace. These can be an interval (begin -> end), or an // instant. Instants can be global, or specific to one thread. You probably don't want to use // each element in PE more than once, as they should each indicate that a specific thing began, -// ended, or occured. +// ended, or occurred. enum class PE : uint8_t { + // The tag below is consumed by PerfTraceTool.java + // enum_start_tag INVALID, ISR, ContextSwitch, @@ -48,23 +53,14 @@ enum class PE : uint8_t { TunerStudioHandleCrcCommand, PwmConfigTogglePwmState, PwmConfigStateChangeCallback, + // enum_end_tag + // The tag above is consumed by PerfTraceTool.java + // please note that the tool requires a comma at the end of last value }; -void perfEventBegin(PE event, uint8_t data); -void perfEventEnd(PE event, uint8_t data); -void perfEventInstantGlobal(PE event, uint8_t data); - -inline void perfEventBegin(PE event) { - perfEventBegin(event, 0); -} - -inline void perfEventEnd(PE event) { - perfEventEnd(event, 0); -} - -inline void perfEventInstantGlobal(PE event) { - perfEventInstantGlobal(event, 0); -} +void perfEventBegin(PE event, uint8_t data = 0); +void perfEventEnd(PE event, uint8_t data = 0); +void perfEventInstantGlobal(PE event, uint8_t data = 0); // Enable one buffer's worth of perf tracing, and retrieve the buffer size in bytes void perfTraceEnable(); @@ -78,6 +74,7 @@ struct TraceBufferResult // Retrieve the trace buffer const TraceBufferResult perfTraceGetBuffer(); +#if ENABLE_PERF_TRACE class ScopePerf { public: @@ -85,19 +82,24 @@ public: ScopePerf(PE event, uint8_t data) : m_event(event), m_data(data) { -#if ENABLE_PERF_TRACE perfEventBegin(event, data); -#endif /* ENABLE_PERF_TRACE */ } ~ScopePerf() { -#if ENABLE_PERF_TRACE perfEventEnd(m_event, m_data); -#endif /* ENABLE_PERF_TRACE */ } private: const PE m_event; const uint8_t m_data; }; + +#else /* if ENABLE_PERF_TRACE */ + +struct ScopePerf { + ScopePerf(PE event) { (void)event; } + ScopePerf(PE event, uint8_t data) { (void)event; (void)data; } +}; + +#endif /* ENABLE_PERF_TRACE */ diff --git a/firmware/development/rfi_perftest.cpp b/firmware/development/rfi_perftest.cpp index 4cdcadcc98..5cdfe07dcd 100644 --- a/firmware/development/rfi_perftest.cpp +++ b/firmware/development/rfi_perftest.cpp @@ -284,7 +284,7 @@ static void runChibioTest(void) { print("EFI_INTERNAL_ADC=%d\r\n", EFI_INTERNAL_ADC); print("EFI_HD44780_LCD=%d\r\n", EFI_HD44780_LCD); print("EFI_MAP_AVERAGING=%d\r\n", EFI_MAP_AVERAGING); - print("EFI_WAVE_ANALYZER=%d\r\n", EFI_WAVE_ANALYZER); + print("EFI_LOGIC_ANALYZER=%d\r\n", EFI_LOGIC_ANALYZER); print("EFI_ENGINE_SNIFFER=%d\r\n", EFI_ENGINE_SNIFFER); print("EFI_SENSOR_CHART=%d\r\n", EFI_SENSOR_CHART); print("EFI_SHAFT_POSITION_INPUT=%d\r\n", EFI_SHAFT_POSITION_INPUT); diff --git a/firmware/development/sensor_chart.h b/firmware/development/sensor_chart.h index 79237ab2c0..91a02390ef 100644 --- a/firmware/development/sensor_chart.h +++ b/firmware/development/sensor_chart.h @@ -2,15 +2,12 @@ * @file sensor_chart.h * * @date Dec 20, 2013 - * @author Andrey Belomutskiy, (c) 2012-2017 + * @author Andrey Belomutskiy, (c) 2012-2019 */ -#ifndef SENSOR_CHART_H_ -#define SENSOR_CHART_H_ +#pragma once #include "global.h" void scAddData(float angle, float value); void initSensorChart(void); - -#endif /* SENSOR_CHART_H_ */ diff --git a/firmware/gen_firing_order.bat b/firmware/gen_firing_order.bat new file mode 100644 index 0000000000..3bbf59ed92 --- /dev/null +++ b/firmware/gen_firing_order.bat @@ -0,0 +1 @@ +java -jar ../java_console_binary/rusefi_console.jar firing_order controllers/algo/firing_order.h diff --git a/firmware/gen_ptrace_enums.bat b/firmware/gen_ptrace_enums.bat new file mode 100644 index 0000000000..f8c1eead0c --- /dev/null +++ b/firmware/gen_ptrace_enums.bat @@ -0,0 +1,5 @@ +# +# this tool might have enough flexibility to generate both C# and java class depending on specified "top line" and "stringClassName" parameters? +# +java -jar ../java_console_binary/rusefi_console.jar ptrace_enums development/perf_trace.h ../java_console/models/src/com/rusefi/tracing/EnumNames.java "package com.rusefi.tracing;" "public static final String" + diff --git a/firmware/hw_layer/adc_inputs.cpp b/firmware/hw_layer/adc_inputs.cpp index d8e50c490c..70ba7f5104 100644 --- a/firmware/hw_layer/adc_inputs.cpp +++ b/firmware/hw_layer/adc_inputs.cpp @@ -468,7 +468,7 @@ static void adc_callback_slow(ADCDriver *adcp, adcsample_t *buffer, size_t n) { if (adcp->state == ADC_COMPLETE) { slowAdc.invalidateSamplesCache(); - efiAssertVoid(CUSTOM_ERR_6671, getCurrentRemainingStack() > 128, "lowstck#9c"); + efiAssertVoid(CUSTOM_STACK_ADC_6671, getCurrentRemainingStack() > 128, "lowstck#9c"); /* Calculates the average values from the ADC samples.*/ for (int i = 0; i < slowAdc.size(); i++) { @@ -491,6 +491,11 @@ void addChannel(const char *name, adc_channel_e setting, adc_channel_mode_e mode if (setting == EFI_ADC_NONE) { return; } + if (/*type-limited (int)setting < 0 || */(int)setting>=HW_MAX_ADC_INDEX) { + firmwareError(CUSTOM_INVALID_ADC, "Invalid ADC setting %s", name); + return; + } + if (adcHwChannelEnabled[setting] != ADC_OFF) { getPinNameByAdcChannel(name, setting, errorMsgBuff); firmwareError(CUSTOM_ERR_ADC_USED, "ADC mapping error: input %s for %s already used by %s?", errorMsgBuff, name, adcHwChannelUsage[setting]); @@ -512,6 +517,12 @@ static void configureInputs(void) { memset(adcHwChannelEnabled, 0, sizeof(adcHwChannelEnabled)); memset(adcHwChannelUsage, 0, sizeof(adcHwChannelUsage)); + /** + * order of analog channels here is totally random and has no meaning + * we also have some weird implementation with internal indices - that all has no meaning, it's just a random implementation + * which does not mean anything. + */ + addChannel("MAP", engineConfiguration->map.sensor.hwChannel, ADC_FAST); if (hasMafSensor()) { addChannel("MAF", engineConfiguration->mafAdcChannel, ADC_FAST); @@ -520,14 +531,22 @@ static void configureInputs(void) { addChannel("baro", engineConfiguration->baroSensor.hwChannel, ADC_SLOW); addChannel("TPS", engineConfiguration->tps1_1AdcChannel, ADC_SLOW); + if (engineConfiguration->tps2_1AdcChannel != EFI_ADC_0) { + // allow EFI_ADC_0 next time we have an incompatible configuration change + addChannel("TPS2", engineConfiguration->tps2_1AdcChannel, ADC_SLOW); + } addChannel("fuel", engineConfiguration->fuelLevelSensor, ADC_SLOW); addChannel("pPS", engineConfiguration->throttlePedalPositionAdcChannel, ADC_SLOW); addChannel("VBatt", engineConfiguration->vbattAdcChannel, ADC_SLOW); // not currently used addChannel("Vref", engineConfiguration->vRefAdcChannel, ADC_SLOW); addChannel("CLT", engineConfiguration->clt.adcChannel, ADC_SLOW); addChannel("IAT", engineConfiguration->iat.adcChannel, ADC_SLOW); - addChannel("AUX#1", engineConfiguration->auxTempSensor1.adcChannel, ADC_SLOW); - addChannel("AUX#2", engineConfiguration->auxTempSensor2.adcChannel, ADC_SLOW); + addChannel("AUXT#1", engineConfiguration->auxTempSensor1.adcChannel, ADC_SLOW); + addChannel("AUXT#2", engineConfiguration->auxTempSensor2.adcChannel, ADC_SLOW); + if (engineConfiguration->bc.auxFastSensor1_adcChannel != EFI_ADC_0) { + // allow EFI_ADC_0 next time we have an incompatible configuration change + addChannel("AUXF#1", engineConfiguration->bc.auxFastSensor1_adcChannel, ADC_FAST); + } addChannel("AFR", engineConfiguration->afr.hwChannel, ADC_SLOW); addChannel("OilP", engineConfiguration->oilPressure.hwChannel, ADC_SLOW); addChannel("AC", engineConfiguration->acSwitchAdc, ADC_SLOW); diff --git a/firmware/hw_layer/digital_input_icu.cpp b/firmware/hw_layer/digital_input_icu.cpp index 81b8b33bdb..028c8929ba 100644 --- a/firmware/hw_layer/digital_input_icu.cpp +++ b/firmware/hw_layer/digital_input_icu.cpp @@ -28,7 +28,7 @@ #include "fl_stack.h" -#if EFI_ICU_INPUTS +#if EFI_ICU_INPUTS && HAL_USE_ICU #include "mpu_util.h" #include "eficonsole.h" @@ -281,8 +281,8 @@ void startInputDriver(const char *msg, /*nullable*/digital_input_s *hw, bool isA } wave_icucfg.channel = getInputCaptureChannel(hw->brainPin); efiIcuStart(msg, driver, &wave_icucfg); - efiAssertVoid(CUSTOM_ERR_6672, driver != NULL, "di: driver is NULL"); - efiAssertVoid(CUSTOM_ERR_6673, driver->state == ICU_READY, "di: driver not ready"); + efiAssertVoid(CUSTOM_ICU_DRIVER, driver != NULL, "di: driver is NULL"); + efiAssertVoid(CUSTOM_ICU_DRIVER_STATE, driver->state == ICU_READY, "di: driver not ready"); icuStartCapture(driver); // this would change state from READY to WAITING icuEnableNotifications(driver); } diff --git a/firmware/hw_layer/hardware.cpp b/firmware/hw_layer/hardware.cpp index f9e3828930..c58a37d134 100644 --- a/firmware/hw_layer/hardware.cpp +++ b/firmware/hw_layer/hardware.cpp @@ -27,6 +27,7 @@ #include "accelerometer.h" #include "eficonsole.h" #include "console_io.h" +#include "sensor_chart.h" #include "mpu_util.h" //#include "usb_msd.h" @@ -93,7 +94,7 @@ bool rtcWorks = true; */ void lockSpi(spi_device_e device) { UNUSED(device); - efiAssertVoid(CUSTOM_ERR_6674, getCurrentRemainingStack() > 128, "lockSpi"); + efiAssertVoid(CUSTOM_STACK_SPI, getCurrentRemainingStack() > 128, "lockSpi"); // todo: different locks for different SPI devices! chMtxLock(&spiMtx); } @@ -188,8 +189,6 @@ static int fastMapSampleIndex; static int hipSampleIndex; static int tpsSampleIndex; -extern int tpsFastAdc; - #if HAL_USE_ADC extern AdcDevice fastAdc; @@ -216,6 +215,13 @@ void adc_callback_fast(ADCDriver *adcp, adcsample_t *buffer, size_t n) { */ efiAssertVoid(CUSTOM_ERR_6676, getCurrentRemainingStack() > 128, "lowstck#9b"); +#if EFI_SENSOR_CHART + if (ENGINE(sensorChartMode) == SC_AUX_FAST1) { + float voltage = getAdcValue("fAux1", engineConfiguration->bc.auxFastSensor1_adcChannel); + scAddData(getCrankshaftAngleNt(getTimeNowNt() PASS_ENGINE_PARAMETER_SUFFIX), voltage); + } +#endif /* EFI_SENSOR_CHART */ + #if EFI_MAP_AVERAGING mapAveragingAdcCallback(fastAdc.samples[fastMapSampleIndex]); #endif /* EFI_MAP_AVERAGING */ @@ -223,7 +229,7 @@ void adc_callback_fast(ADCDriver *adcp, adcsample_t *buffer, size_t n) { if (CONFIGB(isHip9011Enabled)) { hipAdcCallback(fastAdc.samples[hipSampleIndex]); } -#endif +#endif /* EFI_HIP_9011 */ // if (tpsSampleIndex != TPS_IS_SLOW) { // tpsFastAdc = fastAdc.samples[tpsSampleIndex]; // } @@ -242,6 +248,7 @@ static void calcFastAdcIndexes(void) { } else { tpsSampleIndex = TPS_IS_SLOW; } + #endif/* HAL_USE_ADC */ } @@ -257,12 +264,6 @@ void turnOnHardware(Logging *sharedLogger) { #endif /* EFI_SHAFT_POSITION_INPUT */ } -static void unregisterPin(brain_pin_e currentPin, brain_pin_e prevPin) { - if (currentPin != prevPin) { - brain_pin_markUnused(prevPin); - } -} - void stopSpi(spi_device_e device) { #if HAL_USE_SPI if (!isSpiInitialized[device]) @@ -339,7 +340,8 @@ void applyNewHardwareSettings(void) { stopHD44780_pins(); #endif /* #if EFI_HD44780_LCD */ - unregisterPin(engineConfiguration->bc.clutchUpPin, activeConfiguration.bc.clutchUpPin); + if (isPinOrModeChanged(clutchUpPin, clutchUpPinMode)) + brain_pin_markUnused(activeConfiguration.clutchUpPin); enginePins.unregisterPins(); @@ -424,7 +426,7 @@ void initHardware(Logging *l) { /** * We need the LED_ERROR pin even before we read configuration */ - initPrimaryPins(); + initPrimaryPins(sharedLogger); if (hasFirmwareError()) { return; diff --git a/firmware/hw_layer/hip9011.cpp b/firmware/hw_layer/hip9011.cpp index bbedf7ad85..f0dde59bde 100644 --- a/firmware/hw_layer/hip9011.cpp +++ b/firmware/hw_layer/hip9011.cpp @@ -254,14 +254,14 @@ static void intHoldCallback(trigger_event_e ckpEventType, uint32_t index DECLARE int structIndex = getRevolutionCounter() % 2; // todo: schedule this based on closest trigger event, same as ignition works - scheduleByAngle(rpm, &startTimer[structIndex], engineConfiguration->knockDetectionWindowStart, - (schfunc_t) &startIntegration, NULL PASS_ENGINE_PARAMETER_SUFFIX); + scheduleByAngle(&startTimer[structIndex], engineConfiguration->knockDetectionWindowStart, + (schfunc_t) &startIntegration, NULL); #if EFI_PROD_CODE hipLastExecutionCount = lastExecutionCount; #endif /* EFI_PROD_CODE */ - scheduleByAngle(rpm, &endTimer[structIndex], engineConfiguration->knockDetectionWindowEnd, + scheduleByAngle(&endTimer[structIndex], engineConfiguration->knockDetectionWindowEnd, (schfunc_t) &endIntegration, - NULL PASS_ENGINE_PARAMETER_SUFFIX); + NULL); engine->m.hipCbTime = getTimeNowLowerNt() - engine->m.beforeHipCb; } diff --git a/firmware/hw_layer/hip9011_logic.cpp b/firmware/hw_layer/hip9011_logic.cpp index c210c84a9b..68c315c06a 100644 --- a/firmware/hw_layer/hip9011_logic.cpp +++ b/firmware/hw_layer/hip9011_logic.cpp @@ -68,7 +68,7 @@ void HIP9011::setAngleWindowWidth(DEFINE_HIP_PARAMS) { float angleWindowWidth = GET_CONFIG_VALUE(knockDetectionWindowEnd) - GET_CONFIG_VALUE(knockDetectionWindowStart); if (angleWindowWidth < 0) { #if EFI_PROD_CODE - warning(CUSTOM_ERR_6697, "invalid knock window"); + warning(CUSTOM_KNOCK_WINDOW, "invalid knock window"); #endif angleWindowWidth = 0; } diff --git a/firmware/hw_layer/pin_repository.cpp b/firmware/hw_layer/pin_repository.cpp index 473047b9fa..7d18ff32f9 100644 --- a/firmware/hw_layer/pin_repository.cpp +++ b/firmware/hw_layer/pin_repository.cpp @@ -21,7 +21,7 @@ #define BOARD_EXT_PINREPOPINS 0 #endif -static int initialized = FALSE; +static bool initialized = false; static LoggingWithStorage logger("pin repos"); static int totalPinsUsed = 0; @@ -139,7 +139,7 @@ void initPinRepository(void) { initialized = true; - addConsoleAction("pins", reportPins); + addConsoleAction(CMD_PINS, reportPins); } bool brain_pin_is_onchip(brain_pin_e brainPin) @@ -197,8 +197,7 @@ bool brain_pin_markUsed(brain_pin_e brainPin, const char *msg) { * See also brain_pin_markUsed() */ -void brain_pin_markUnused(brain_pin_e brainPin) -{ +void brain_pin_markUnused(brain_pin_e brainPin) { int index; if (!initialized) { diff --git a/firmware/hw_layer/ports/kinetis/hw_ports.mk b/firmware/hw_layer/ports/kinetis/hw_ports.mk index 29245349f7..7438697eef 100644 --- a/firmware/hw_layer/ports/kinetis/hw_ports.mk +++ b/firmware/hw_layer/ports/kinetis/hw_ports.mk @@ -8,4 +8,5 @@ HW_LAYER_EMS += $(PROJECT_DIR)/hw_layer/ports/kinetis/flash.c \ HW_LAYER_EMS_CPP += $(PROJECT_DIR)/hw_layer/ports/kinetis/mpu_util.cpp \ $(PROJECT_DIR)/hw_layer/ports/kinetis/kinetis_pins.cpp \ - $(PROJECT_DIR)/hw_layer/ports/kinetis/kinetis_common.cpp + $(PROJECT_DIR)/hw_layer/ports/kinetis/kinetis_common.cpp \ + $(PROJECT_DIR)/hw_layer/trigger_input_comp.cpp diff --git a/firmware/hw_layer/ports/kinetis/mpu_util.cpp b/firmware/hw_layer/ports/kinetis/mpu_util.cpp index 78e351df9b..78475108f3 100644 --- a/firmware/hw_layer/ports/kinetis/mpu_util.cpp +++ b/firmware/hw_layer/ports/kinetis/mpu_util.cpp @@ -12,7 +12,6 @@ #include "mpu_util.h" #include "flash.h" -#include "error_handling.h" #include "engine.h" #include "pin_repository.h" #include "os_util.h" diff --git a/firmware/hw_layer/ports/stm32/stm32f4/mpu_util.cpp b/firmware/hw_layer/ports/stm32/stm32f4/mpu_util.cpp index 8249294693..3585257993 100644 --- a/firmware/hw_layer/ports/stm32/stm32f4/mpu_util.cpp +++ b/firmware/hw_layer/ports/stm32/stm32f4/mpu_util.cpp @@ -11,7 +11,6 @@ #include "mpu_util.h" #include "flash.h" -#include "error_handling.h" #include "engine.h" #include "pin_repository.h" #include "stm32f4xx_hal_flash.h" diff --git a/firmware/hw_layer/ports/stm32/stm32f7/mpu_util.cpp b/firmware/hw_layer/ports/stm32/stm32f7/mpu_util.cpp index e2e11c76a3..bce4e43da2 100644 --- a/firmware/hw_layer/ports/stm32/stm32f7/mpu_util.cpp +++ b/firmware/hw_layer/ports/stm32/stm32f7/mpu_util.cpp @@ -8,7 +8,6 @@ #include "global.h" #include "mpu_util.h" #include "flash.h" -#include "error_handling.h" #include "engine.h" #include "pin_repository.h" #include "stm32f7xx_hal_flash.h" diff --git a/firmware/hw_layer/sensors/cj125.cpp b/firmware/hw_layer/sensors/cj125.cpp index 53290706ad..d24f6c08d4 100644 --- a/firmware/hw_layer/sensors/cj125.cpp +++ b/firmware/hw_layer/sensors/cj125.cpp @@ -164,7 +164,7 @@ static void cjPrintErrorCode(cj125_error_e errCode) { case CJ125_ERROR_OVERHEAT: errString = "Sensor overheating"; break; - case CJ125_ERROR_NONE: + case CJ125_NO_ERROR: errString = "N/A"; break; case CJ125_ERROR_WRONG_IDENT: @@ -173,6 +173,9 @@ static void cjPrintErrorCode(cj125_error_e errCode) { case CJ125_ERROR_WRONG_INIT: errString = "W_INIT"; break; + case CJ125_ERROR_DISABLED: + errString = "DISABLED"; + break; } scheduleMsg(logger, "cj125 ERROR: %s.", errString); } @@ -540,18 +543,22 @@ void initCJ125(Logging *sharedLogger DECLARE_ENGINE_PARAMETER_SUFFIX) { globalInstance.spi = &spi; globalInstance.logger = sharedLogger; - if (!CONFIGB(isCJ125Enabled)) + if (!CONFIGB(isCJ125Enabled)) { + globalInstance.errorCode = CJ125_ERROR_DISABLED; return; + } if (CONFIG(cj125ur) == EFI_ADC_NONE || CONFIG(cj125ua) == EFI_ADC_NONE) { scheduleMsg(logger, "cj125 init error! cj125ur and cj125ua are required."); warning(CUSTOM_CJ125_0, "cj ur ua"); + globalInstance.errorCode = CJ125_ERROR_DISABLED; return; } if (CONFIGB(wboHeaterPin) == GPIO_UNASSIGNED) { scheduleMsg(logger, "cj125 init error! wboHeaterPin is required."); warning(CUSTOM_CJ125_1, "cj heater"); + globalInstance.errorCode = CJ125_ERROR_DISABLED; return; } diff --git a/firmware/hw_layer/sensors/cj125_logic.cpp b/firmware/hw_layer/sensors/cj125_logic.cpp index 22ee2198d4..e8b017da1e 100644 --- a/firmware/hw_layer/sensors/cj125_logic.cpp +++ b/firmware/hw_layer/sensors/cj125_logic.cpp @@ -7,6 +7,7 @@ #include "cj125_logic.h" #include "engine.h" +#include "error_handling.h" EXTERN_ENGINE; @@ -47,7 +48,12 @@ void CJ125::StartHeaterControl(pwm_gen_callback *stateChangeCallback DECLARE_ENG SetIdleHeater(PASS_ENGINE_PARAMETER_SIGNATURE); } -void CJ125::cjIdentify(void) { +/** + * @return true in case of positive SPI identification + * false in case of unexpected SPI response + */ +bool CJ125::cjIdentify(void) { + efiAssert(OBD_PCM_Processor_Fault, spi!= NULL, "No SPI pointer", false); // read Ident register int ident = spi->ReadRegister(IDENT_REG_RD) & CJ125_IDENT_MASK; @@ -62,15 +68,22 @@ void CJ125::cjIdentify(void) { scheduleMsg(logger, "cj125: Check ident=0x%x diag=0x%x init1=0x%x init2=0x%x", ident, diag, init1, init2); if (ident != CJ125_IDENT) { scheduleMsg(logger, "cj125: Error! Wrong ident! Cannot communicate with CJ125!"); + errorCode = CJ125_ERROR_WRONG_IDENT; + state = CJ125_ERROR; + return false; } if (init1 != CJ125_INIT1_NORMAL_17 || init2 != CJ125_INIT2_DIAG) { scheduleMsg(logger, "cj125: Error! Cannot set init registers! Cannot communicate with CJ125!"); + errorCode = CJ125_ERROR_WRONG_INIT; + state = CJ125_ERROR; + return false; } #if 0 if (diag != CJ125_DIAG_NORM) { scheduleMsg(logger, "cj125: Diag error!"); } #endif + return true; } void CJ125::cjSetMode(cj125_mode_e m) { diff --git a/firmware/hw_layer/sensors/cj125_logic.h b/firmware/hw_layer/sensors/cj125_logic.h index 208aeda0a2..e2b326fff2 100644 --- a/firmware/hw_layer/sensors/cj125_logic.h +++ b/firmware/hw_layer/sensors/cj125_logic.h @@ -31,11 +31,12 @@ typedef enum { } cj125_state_e; typedef enum { - CJ125_ERROR_NONE = 0, + CJ125_NO_ERROR = 0, CJ125_ERROR_HEATER_MALFUNCTION = 1, CJ125_ERROR_OVERHEAT = 2, CJ125_ERROR_WRONG_IDENT = 3, CJ125_ERROR_WRONG_INIT = 4, + CJ125_ERROR_DISABLED = 5, } cj125_error_e; typedef enum { @@ -90,14 +91,14 @@ public: // Used by CJ125 driver state machine volatile cj125_state_e state = CJ125_INIT; // Last Error code - volatile cj125_error_e errorCode = CJ125_ERROR_NONE; + volatile cj125_error_e errorCode = CJ125_NO_ERROR; void setError(cj125_error_e errCode DECLARE_ENGINE_PARAMETER_SUFFIX); bool isWorkingState(void) const; void SetHeater(float value DECLARE_ENGINE_PARAMETER_SUFFIX); void SetIdleHeater(DECLARE_ENGINE_PARAMETER_SIGNATURE); void StartHeaterControl(pwm_gen_callback *stateChangeCallback DECLARE_ENGINE_PARAMETER_SUFFIX); - void cjIdentify(void); + bool cjIdentify(void); void cjSetMode(cj125_mode_e m); bool isValidState() const; void cjInitPid(DECLARE_ENGINE_PARAMETER_SIGNATURE); diff --git a/firmware/hw_layer/sensors/joystick.h b/firmware/hw_layer/sensors/joystick.h index 3360c969f4..cb88f46ac9 100644 --- a/firmware/hw_layer/sensors/joystick.h +++ b/firmware/hw_layer/sensors/joystick.h @@ -2,10 +2,10 @@ * @file joystick.h * * @date Jan 2, 2015 - * @author Andrey Belomutskiy, (c) 2012-2017 + * @author Andrey Belomutskiy, (c) 2012-2019 */ -#ifndef CONTROLLERS_JOYSTICK_H_ -#define CONTROLLERS_JOYSTICK_H_ + +#pragma once #include "global.h" @@ -21,5 +21,3 @@ void onJoystick(joystick_button_e button); void initJoystick(Logging *shared); void startJoystickPins(); void stopJoystickPins(); - -#endif /* CONTROLLERS_JOYSTICK_H_ */ diff --git a/firmware/hw_layer/sensors/yaw_rate_sensor.h b/firmware/hw_layer/sensors/yaw_rate_sensor.h index 09355b0019..58aee052b1 100644 --- a/firmware/hw_layer/sensors/yaw_rate_sensor.h +++ b/firmware/hw_layer/sensors/yaw_rate_sensor.h @@ -1,16 +1,12 @@ /* - * yaw_rate_sensor.h + * @file yaw_rate_sensor.h * - * Created on: Oct 16, 2018 - * @author Andrey Belomutskiy, (c) 2012-2018 + * @date Oct 16, 2018 + * @author Andrey Belomutskiy, (c) 2012-2019 */ -#ifndef HW_LAYER_SENSORS_YAW_RATE_SENSOR_H_ -#define HW_LAYER_SENSORS_YAW_RATE_SENSOR_H_ +#pragma once #include "global.h" -#include "engine.h" void initBoschYawRateSensor(); - -#endif /* HW_LAYER_SENSORS_YAW_RATE_SENSOR_H_ */ diff --git a/firmware/hw_layer/stepper.cpp b/firmware/hw_layer/stepper.cpp index cceb0daa9c..663804a243 100644 --- a/firmware/hw_layer/stepper.cpp +++ b/firmware/hw_layer/stepper.cpp @@ -112,13 +112,6 @@ StepperMotor::StepperMotor() { currentPosition = 0; targetPosition = 0; -#if EFI_PROD_CODE - enablePort = NULL; - enablePin = 0; - stepPort = NULL; - stepPin = 0; -#endif - reactionTime = 0; totalSteps = 0; } @@ -142,22 +135,20 @@ void StepperMotor::setDirection(bool isIncrementing) { } void StepperMotor::pulse() { -#if EFI_PROD_CODE - palWritePad(enablePort, enablePin, 0); // enable stepper - palWritePad(stepPort, stepPin, 1); + enablePin.setValue(false); // enable stepper + + stepPin.setValue(true); chThdSleepMilliseconds(reactionTime); - palWritePad(stepPort, stepPin, 0); + stepPin.setValue(false); chThdSleepMilliseconds(reactionTime); - palWritePad(enablePort, enablePin, 1); // disable stepper -#endif /* EFI_PROD_CODE */ + enablePin.setValue(true); // disable stepper } void StepperMotor::initialize(brain_pin_e stepPin, brain_pin_e directionPin, pin_output_mode_e directionPinMode, float reactionTime, int totalSteps, brain_pin_e enablePin, pin_output_mode_e enablePinMode, Logging *sharedLogger) { - UNUSED(enablePinMode); this->reactionTime = maxF(1, reactionTime); this->totalSteps = maxI(3, totalSteps); @@ -167,30 +158,18 @@ void StepperMotor::initialize(brain_pin_e stepPin, brain_pin_e directionPin, pin return; } -#if EFI_PROD_CODE - stepPort = getHwPort("step", stepPin); - this->stepPin = getHwPin("step", stepPin); -#endif /* EFI_PROD_CODE */ - this->directionPinMode = directionPinMode; this->directionPin.initPin("stepper dir", directionPin, &this->directionPinMode); -#if EFI_PROD_CODE - enablePort = getHwPort("enable", enablePin); - this->enablePin = getHwPin("enable", enablePin); -#endif /* EFI_PROD_CODE */ + this->stepPinMode = OM_DEFAULT; // todo: do we need configurable stepPinMode? + this->stepPin.initPin("stepper step", stepPin, &this->stepPinMode); - efiSetPadMode("stepper step", stepPin, PAL_MODE_OUTPUT_PUSHPULL); - // todo: start using enablePinMode parameter here #718 - efiSetPadMode("stepper enable", enablePin, PAL_MODE_OUTPUT_PUSHPULL); - -#if EFI_PROD_CODE - palWritePad(this->enablePort, enablePin, 1); // disable stepper + this->enablePinMode = enablePinMode; + this->enablePin.initPin("stepper enable", enablePin, &this->enablePinMode); // All pins must be 0 for correct hardware startup (e.g. stepper auto-disabling circuit etc.). - palWritePad(this->stepPort, this->stepPin, 0); -#endif - + this->enablePin.setValue(true); // disable stepper + this->stepPin.setValue(false); this->directionPin.setValue(false); this->currentDirection = false; diff --git a/firmware/hw_layer/stepper.h b/firmware/hw_layer/stepper.h index 168e2cebf1..c951add875 100644 --- a/firmware/hw_layer/stepper.h +++ b/firmware/hw_layer/stepper.h @@ -21,7 +21,7 @@ public: int getTargetPosition() const; void setDirection(bool isIncrementing); - OutputPin directionPin; + OutputPin directionPin, stepPin, enablePin; int currentPosition; bool currentDirection; float reactionTime; @@ -29,15 +29,7 @@ public: private: int targetPosition; -#if EFI_PROD_CODE - ioportid_t stepPort; - ioportmask_t stepPin; - - ioportid_t enablePort; - ioportmask_t enablePin; -#endif - - pin_output_mode_e directionPinMode; + pin_output_mode_e directionPinMode, stepPinMode, enablePinMode; THD_WORKING_AREA(stThreadStack, UTILITY_THREAD_STACK_SIZE); }; diff --git a/firmware/hw_layer/trigger_input_comp.cpp b/firmware/hw_layer/trigger_input_comp.cpp index 307485ce5e..c854db0f4f 100644 --- a/firmware/hw_layer/trigger_input_comp.cpp +++ b/firmware/hw_layer/trigger_input_comp.cpp @@ -23,25 +23,59 @@ EXTERN_ENGINE ; static Logging *logger; +static volatile int centeredDacValue = 127; +static volatile int toothCnt = 0; +static volatile int dacHysteresisMin = 1; // = 5V * 1/256 (8-bit DAC) = ~20mV +static volatile int dacHysteresisMax = 15; // = ~300mV +static volatile int dacHysteresisDelta = dacHysteresisMin; +static volatile int hystUpdatePeriodNumEvents = 116; // every ~1 turn of 60-2 wheel +static volatile efitick_t prevNt = 0; +// VR-sensor saturation stuff +static volatile float curVrFreqNt = 0, saturatedVrFreqNt = 0; + +// We want to interpolate between min and max depending on the signal level (adaptive hysteresis). +// But we don't want to measure the signal amplitude directly, so we estimate it by measuring the signal frequency: +// for VR sensors, the amplitude is inversely proportional to the tooth's 'time-width'. +// We find it by dividing the total time by the teeth count, and use the reciprocal value as signal frequency! +static void setHysteresis(COMPDriver *comp, int sign) { + // update the hysteresis threshold, but not for every tooth +#ifdef EFI_TRIGGER_COMP_ADAPTIVE_HYSTERESIS + if (toothCnt++ > hystUpdatePeriodNumEvents) { + efitick_t nowNt = getTimeNowNt(); + curVrFreqNt = (float)toothCnt / (float)(nowNt - prevNt); + dacHysteresisDelta = (int)efiRound(interpolateClamped(0.0f, dacHysteresisMin, saturatedVrFreqNt, dacHysteresisMax, curVrFreqNt), 1.0f); + toothCnt = 0; + prevNt = nowNt; +#ifdef TRIGGER_COMP_EXTREME_LOGGING + scheduleMsg(logger, "* f=%f d=%d", curVrFreqNt * 1000.0f, dacHysteresisDelta); +#endif /* TRIGGER_COMP_EXTREME_LOGGING */ + } +#endif /* EFI_TRIGGER_COMP_ADAPTIVE_HYSTERESIS */ + comp_lld_set_dac_value(comp, centeredDacValue + dacHysteresisDelta * sign); +} + static void comp_shaft_callback(COMPDriver *comp) { - bool isRising = (comp_lld_get_status(comp) & COMP_IRQ_RISING) != 0; + uint32_t status = comp_lld_get_status(comp); int isPrimary = (comp == EFI_COMP_PRIMARY_DEVICE); - if (!isPrimary && !TRIGGER_SHAPE(needSecondTriggerInput)) { + if (!isPrimary && !TRIGGER_WAVEFORM(needSecondTriggerInput)) { return; } trigger_event_e signal; - if (isRising) { + if (status & COMP_IRQ_RISING) { signal = isPrimary ? (engineConfiguration->invertPrimaryTriggerSignal ? SHAFT_PRIMARY_FALLING : SHAFT_PRIMARY_RISING) : (engineConfiguration->invertSecondaryTriggerSignal ? SHAFT_SECONDARY_FALLING : SHAFT_SECONDARY_RISING); - } else { + hwHandleShaftSignal(signal); + // shift the threshold down a little bit to avoid false-triggering (threshold hysteresis) + setHysteresis(comp, -1); + } + + if (status & COMP_IRQ_FALLING) { signal = isPrimary ? (engineConfiguration->invertPrimaryTriggerSignal ? SHAFT_PRIMARY_RISING : SHAFT_PRIMARY_FALLING) : (engineConfiguration->invertSecondaryTriggerSignal ? SHAFT_SECONDARY_RISING : SHAFT_SECONDARY_FALLING); + hwHandleShaftSignal(signal); + // shift the threshold up a little bit to avoid false-triggering (threshold hysteresis) + setHysteresis(comp, 1); } - hwHandleShaftSignal(signal); - -#ifdef EFI_TRIGGER_DEBUG_BLINK - __blink(1); -#endif } // todo: add cam support? @@ -71,17 +105,36 @@ void turnOnTriggerInputPins(Logging *sharedLogger) { applyNewTriggerInputPins(); } +static int getDacValue(uint8_t voltage DECLARE_ENGINE_PARAMETER_SUFFIX) { + constexpr float maxDacValue = 255.0f; // 8-bit DAC + return (int)efiRound(maxDacValue * (float)voltage * VOLTAGE_1_BYTE_PACKING_DIV / CONFIG(adcVcc), 1.0f); +} + void startTriggerInputPins(void) { //efiAssertVoid(CUSTOM_ERR_, !isCompEnabled, "isCompEnabled"); + if (isCompEnabled) { + scheduleMsg(logger, "startTIPins(): already enabled!"); + return; + } - const float vRef = 5.0f; - const float vSensorRef = 2.5f; // 2.5V resistor divider - // when VR sensor is silent, there's still some noise around vRef, so we need a small threshold to avoid false triggering - const float noSignalThreshold = 0.05f; + centeredDacValue = getDacValue(CONFIG(triggerCompCenterVolt) PASS_ENGINE_PARAMETER_SUFFIX); // usually 2.5V resistor divider - const int maxDacValue = 255; - const int vDac = (int)(int)efiRound(maxDacValue * (vSensorRef - noSignalThreshold) / vRef, 1.0f); + dacHysteresisMin = getDacValue(CONFIG(triggerCompHystMin) PASS_ENGINE_PARAMETER_SUFFIX); // usually ~20mV + dacHysteresisMax = getDacValue(CONFIG(triggerCompHystMax) PASS_ENGINE_PARAMETER_SUFFIX); // usually ~300mV + dacHysteresisDelta = dacHysteresisMin; + // 20 rpm (60_2) = 1000*60/((2*60)*20) = 25 ms for 1 tooth event + float satRpm = CONFIG(triggerCompSensorSatRpm) * RPM_1_BYTE_PACKING_MULT; + hystUpdatePeriodNumEvents = getTriggerSize(); // = 116 for "60-2" trigger wheel + float saturatedToothDurationUs = 60.0f * US_PER_SECOND_F / satRpm / hystUpdatePeriodNumEvents; + saturatedVrFreqNt = 1.0f / US2NT(saturatedToothDurationUs); + + scheduleMsg(logger, "startTIPins(): cDac=%d hystMin=%d hystMax=%d satRpm=%.0f satFreq*1k=%f period=%d", + centeredDacValue, dacHysteresisMin, dacHysteresisMax, satRpm, saturatedVrFreqNt * 1000.0f, hystUpdatePeriodNumEvents); +#ifdef EFI_TRIGGER_COMP_ADAPTIVE_HYSTERESIS + scheduleMsg(logger, "startTIPins(): ADAPTIVE_HYSTERESIS enabled!"); +#endif /* EFI_TRIGGER_COMP_ADAPTIVE_HYSTERESIS */ + int channel = EFI_COMP_TRIGGER_CHANNEL; // todo: use getInputCaptureChannel(hwPin); // todo: set pin mode to default (analog/comparator) @@ -89,7 +142,7 @@ void startTriggerInputPins(void) { // no generic hal support for extended COMP configuration, so we use hal_lld layer... osalSysLock(); - comp_lld_set_dac_value(EFI_COMP_PRIMARY_DEVICE, vDac); + comp_lld_set_dac_value(EFI_COMP_PRIMARY_DEVICE, centeredDacValue); comp_lld_channel_enable(EFI_COMP_PRIMARY_DEVICE, channel); osalSysUnlock(); @@ -98,8 +151,13 @@ void startTriggerInputPins(void) { } void stopTriggerInputPins(void) { - if (!isCompEnabled) + if (!isCompEnabled) { + scheduleMsg(logger, "stopTIPins(): already disabled!"); return; + } + + scheduleMsg(logger, "stopTIPins();"); + compDisable(EFI_COMP_PRIMARY_DEVICE); isCompEnabled = false; #if 0 diff --git a/firmware/hw_layer/trigger_input_exti.cpp b/firmware/hw_layer/trigger_input_exti.cpp index c6beacbb6b..ac136bbdf1 100644 --- a/firmware/hw_layer/trigger_input_exti.cpp +++ b/firmware/hw_layer/trigger_input_exti.cpp @@ -32,7 +32,7 @@ static void shaft_callback(void *arg) { return; bool isPrimary = pal_line == primary_line; - if (!isPrimary && !TRIGGER_SHAPE(needSecondTriggerInput)) { + if (!isPrimary && !TRIGGER_WAVEFORM(needSecondTriggerInput)) { return; } @@ -73,11 +73,11 @@ void turnOnTriggerInputPin(const char *msg, int index, bool isTriggerShaft) { * * do not set to both edges if we need only one * * simplify callback in case of one edge */ ioline_t pal_line = PAL_LINE(getHwPort("trg", brainPin), getHwPin("trg", brainPin)); - efiExtiEnablePin(msg, brainPin, PAL_EVENT_MODE_BOTH_EDGES, isVvtShaft ? shaft_callback : cam_callback, (void *)pal_line); + efiExtiEnablePin(msg, brainPin, PAL_EVENT_MODE_BOTH_EDGES, isTriggerShaft ? shaft_callback : cam_callback, (void *)pal_line); } void turnOffTriggerInputPin(brain_pin_e brainPin) { - stopDigitalCapture("trigger", brainPin); + efiExtiDisablePin(brainPin); } void setPrimaryChannel(brain_pin_e brainPin) { diff --git a/firmware/hw_layer/trigger_input_icu.cpp b/firmware/hw_layer/trigger_input_icu.cpp index 1c06d11374..f3f0eb2260 100644 --- a/firmware/hw_layer/trigger_input_icu.cpp +++ b/firmware/hw_layer/trigger_input_icu.cpp @@ -51,7 +51,7 @@ static void shaftWidthCallback(bool isPrimary) { // todo: start using real event time from HW event, not just software timer? if (hasFirmwareErrorFlag) return; - if (!isPrimary && !TRIGGER_SHAPE(needSecondTriggerInput)) { + if (!isPrimary && !TRIGGER_WAVEFORM(needSecondTriggerInput)) { return; } // icucnt_t last_width = icuGetWidth(icup); so far we are fine with system time @@ -68,7 +68,7 @@ static void shaftPeriodCallback(bool isPrimary) { icuWidthPeriodCounter++; if (hasFirmwareErrorFlag) return; - if (!isPrimary && !TRIGGER_SHAPE(needSecondTriggerInput)) { + if (!isPrimary && !TRIGGER_WAVEFORM(needSecondTriggerInput)) { return; } diff --git a/firmware/hw_layer/vehicle_speed.cpp b/firmware/hw_layer/vehicle_speed.cpp index 79b02bc53a..fda3a57af5 100644 --- a/firmware/hw_layer/vehicle_speed.cpp +++ b/firmware/hw_layer/vehicle_speed.cpp @@ -52,7 +52,7 @@ static void vsAnaWidthCallback(void) { static void speedInfo(void) { scheduleMsg(logger, "VSS input at %s", - hwPortname(CONFIGB(vehicleSpeedSensorInputPin))); + hwPortname(CONFIG(vehicleSpeedSensorInputPin))); scheduleMsg(logger, "c=%.2f eventCounter=%d speed=%.2f", engineConfiguration->vehicleSpeedCoef, @@ -63,17 +63,17 @@ static void speedInfo(void) { } bool hasVehicleSpeedSensor() { - return CONFIGB(vehicleSpeedSensorInputPin) != GPIO_UNASSIGNED; + return CONFIG(vehicleSpeedSensorInputPin) != GPIO_UNASSIGNED; } void stopVSSPins(void) { - stopDigitalCapture("VSS", activeConfiguration.bc.vehicleSpeedSensorInputPin); + stopDigitalCapture("VSS", activeConfiguration.vehicleSpeedSensorInputPin); } void startVSSPins(void) { if (!hasVehicleSpeedSensor()) return; - digital_input_s* vehicleSpeedInput = addWaveAnalyzerDriver("VSS", CONFIGB(vehicleSpeedSensorInputPin)); + digital_input_s* vehicleSpeedInput = addWaveAnalyzerDriver("VSS", CONFIG(vehicleSpeedSensorInputPin)); startInputDriver("VSS", vehicleSpeedInput, true); vehicleSpeedInput->widthListeners.registerCallback((VoidInt) vsAnaWidthCallback, NULL); } diff --git a/firmware/integration/rusefi_config.txt b/firmware/integration/rusefi_config.txt index 543fade4c2..f94af55680 100644 --- a/firmware/integration/rusefi_config.txt +++ b/firmware/integration/rusefi_config.txt @@ -87,6 +87,8 @@ struct_no_prefix engine_configuration_s #define CLT_TIMING_CURVE_SIZE 8 #define IDLE_VE_CURVE_SIZE 8 +#define ETB_COUNT 2 + #define AUX_DIGITAL_VALVE_COUNT 2 #define IAT_CURVE_SIZE 16 @@ -116,7 +118,15 @@ struct_no_prefix engine_configuration_s #define FUEL_LOAD_COUNT 16 #define PEDAL_TO_TPS_SIZE 8 + + +! +! all the xxx_PACKING_xxx constants are about persisting tables in compact for, for example packing RPM with 50 increment in a byte +! or packing numeric voltage inside an integer byte +! See usages of '@@RPM_1_BYTE_PACKING_MULT@@' where we apply the TS part of the magic +! #define RPM_1_BYTE_PACKING_MULT 50 +#define VOLTAGE_1_BYTE_PACKING_DIV 0.02 #define FSIO_TABLE_8 8 @@ -166,16 +176,16 @@ int16_t rpm;+This sets the RPM limit below which the ECU will use cranking fuel end_struct #define debug_mode_e_enum "Alternator PID", "TPS acceleration enrichment", "INVALID", "Idle Control", "Engine Load accl enrich", "Trigger Counters", "FSIO_ADC", "AUX_PID_1", "VVT input", "Cranking", "Timing", "Closed-loop fuel corr PID", "VSS", "SD card", "sr5", "Knock", "Trigger Sync", "Electronic Throttle", "Executor", "Bench Test / TS commands", "Aux Valves", "Analog inputs #1", "INSTANT_RPM", "FSIO_EXPRESSION", "Status", "CJ125", "CAN", "MAP", "Metrics", "ETB#2", "Ion Sense", "TLE8888", "Analog inputs #2", "Dwell Metric", "Aux Temperature", "ETB Logic" -custom debug_mode_e 4 bits, U32, @OFFSET@, [0:5], @@debug_mode_e_enum@@ +custom debug_mode_e 4 bits, U32, @OFFSET@, [0:7], @@debug_mode_e_enum@@ #define vvt_mode_e_enum "First half", "Second half", "2GZ", "Miata NB2", "mode4", "mode5", "mode6", "mode7" -custom vvt_mode_e 4 bits, U32, @OFFSET@, [0:2], @@vvt_mode_e_enum@@ +custom vvt_mode_e 4 bits, U32, @OFFSET@, [0:7], @@vvt_mode_e_enum@@ #define can_device_mode_e_enum "v0", "v1" -custom can_device_mode_e 4 bits, U32, @OFFSET@, [0:2], @@can_device_mode_e_enum@@ +custom can_device_mode_e 4 bits, U32, @OFFSET@, [0:7], @@can_device_mode_e_enum@@ #define mass_storage_e_enum "Auto", "Always", "Never" -custom mass_storage_e 4 bits, U32, @OFFSET@, [0:1], @@mass_storage_e_enum@@ +custom mass_storage_e 4 bits, U32, @OFFSET@, [0:7], @@mass_storage_e_enum@@ ! At the moment TIM1, TIM2, TIM3 and TIM9 are configured as ICU ! todo: as of ChibiOS3, only channels 1 & 2 are allowed to capture input, that's a ChibiOS driver limitation @@ -200,7 +210,7 @@ custom output_pin_e 1 bits, U08, @OFFSET@, [0:7], @@output_pin_e_enum@@ #define pin_output_mode_e_enum "default", "default inverted", "open collector", "open collector inverted" -custom pin_output_mode_e 1 bits, U08, @OFFSET@, [0:1], @@pin_output_mode_e_enum@@ +custom pin_output_mode_e 1 bits, U08, @OFFSET@, [0:7], @@pin_output_mode_e_enum@@ custom pin_input_mode_e 1 scalar, U08, @OFFSET@, "todo", 1, 0, 0, 20, 1 @@ -211,12 +221,12 @@ struct spi_pins end_struct -custom air_pressure_sensor_type_e 4 bits, U32, @OFFSET@, [0:3] "Custom", "DENSO183", "MPX4250", "HONDA3BAR", "NEON_2003", "22012AA090", "3 Bar", "MPX4100", "Toyota 89420-02010", "MPX4250A", "INVALID" +custom air_pressure_sensor_type_e 4 bits, U32, @OFFSET@, [0:7] "Custom", "DENSO183", "MPX4250", "HONDA3BAR", "NEON_2003", "22012AA090", "3 Bar", "MPX4100", "Toyota 89420-02010", "MPX4250A", "INVALID" ! ! lower 16 values are used on stm32 rusEfi, values above 16 are related to Kinetis work in progress ! #define adc_channel_e_enum "PA0", "PA1", "PA2", "PA3", "PA4", "PA5", "PA6", "PA7", "PB0", "PB1", "PC0", "PC1", "PC2", "PC3", "PC4", "PC5", "Disabled", "PB12", "PB13", "PC14", "PC15", "PC16", "PC17", "PD3", "PD4", "PE2", "PE6", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID" -custom adc_channel_e 1 bits, U08, @OFFSET@, [0:4] @@adc_channel_e_enum@@ +custom adc_channel_e 1 bits, U08, @OFFSET@, [0:7] @@adc_channel_e_enum@@ struct air_pressure_sensor_config_s float lowValue;kPa value at low volts;"kpa", 1, 0, -400, 800, 2 @@ -260,7 +270,7 @@ struct ThermistorConf @brief Thermistor curve parameters adc_channel_e adcChannel; end_struct -custom engine_type_e 4 bits, S32, @OFFSET@, [0:2], "AUDI_AAN", "DODGE_NEON_1995", "FORD_ASPIRE_1996", "FORD_FIESTA", "NISSAN_PRIMERA", "HONDA_ACCORD", "FORD_INLINE_6_1995", "GY6_139QMB" +custom engine_type_e 4 bits, S32, @OFFSET@, [0:7], "AUDI_AAN", "DODGE_NEON_1995", "FORD_ASPIRE_1996", "FORD_FIESTA", "NISSAN_PRIMERA", "HONDA_ACCORD", "FORD_INLINE_6_1995", "GY6_139QMB" engine_type_e engineType;http://rusefi.com/wiki/index.php?title=Manual:Engine_Type\nset engine_type X int engineSnifferRpmThreshold;Engine sniffer would be disabled above this rpm\nset engineSnifferRpmThreshold X;"RPM", 1, 0, 0,30000, 0 @@ -297,8 +307,8 @@ bit isVerboseAuxPid4; bit useBiQuadAnalogFiltering; bit cj125isUaDivided; bit cj125isLsu49; -bit etb1_use_two_wires; -bit etb2_use_two_wires; +bit etb_use_two_wires; +bit unusedHereo_wires; bit showSdCardWarning; bit cj125isUrDivided;looks like 3v range should be enough, divider not needed bit useTLE8888_hall_mode; @@ -318,7 +328,7 @@ bit issue_294_30; bit issue_294_31; -int16_t tpsMin;Closed throttle. todo: extract these two fields into a structure\ntodo: we need two sets of TPS parameters - modern ETBs have two sensors\nSee also tps1_1AdcChannel\nset tps_min X;"ADC", 1, 0, 0, 1023, 0 +int16_t tpsMin;Closed throttle. todo: extract these two fields into a structure\nSee also tps1_1AdcChannel\nset tps_min X;"ADC", 1, 0, 0, 1023, 0 int16_t tpsMax;Full throttle. tpsMax value as 10 bit ADC value. Not Voltage!\nSee also tps1_1AdcChannel\nset tps_max X;"ADC", 1, 0, 0, 1023, 0 int16_t tpsErrorDetectionTooLow;+TPS error detection, what TPS % value is unrealistically low;"%", 1, 0, -40, 200, 0 @@ -348,7 +358,7 @@ float[DWELL_CURVE_SIZE] sparkDwellRpmBins;On single-coil or wasted spark setups struct_no_prefix specs_s float displacement;Engine displacement, in litres\nsee also cylindersCount;"L", 1, 0, 0, 1000.0, 2 -custom cylinders_count_t 4 bits, U32, @OFFSET@, [0:3], "INVALID", 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, "INVALID", "INVALID", "INVALID" +custom cylinders_count_t 4 bits, U32, @OFFSET@, [0:7], "INVALID", 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, "INVALID", "INVALID", "INVALID" cylinders_count_t cylindersCount; ! see firing_order.h @@ -357,7 +367,7 @@ cylinders_count_t cylindersCount; ! FO_1_8_4_3_6_5_7_2 = 5 ! FO_1_2_4_5_3 = 6 -custom firing_order_e 4 bits, U32, @OFFSET@, [0:4], "One Cylinder", "1-3-4-2", "1-2-4-3", "1-3-2-4", "1-5-3-6-2-4", "1-8-4-3-6-5-7-2", "1-2-4-5-3", "1-4-2-5-3-6", "1-2", "1_2_3_4_5_6", "1-2-3", "1-8-7-2-6-5-4-3", "1-5-4-2-6-3-7-8", "1-6-3-2-5-4", "1-10-9-4-3-6-5-8-7_2", "1-7-5-11-3-9-6-12-2-8-4-10", "1-7-4-10-2-8-6-12-3-9-5-11", "1-4-3-2", "1-12-5-8-3-10-6-7-2-11-4-9", "1-2-7-8-4-5-6-3", "fo20", "fo21", "fo22", "INVALID" +custom firing_order_e 4 bits, U32, @OFFSET@, [0:7], "One Cylinder", "1-3-4-2", "1-2-4-3", "1-3-2-4", "1-5-3-6-2-4", "1-8-4-3-6-5-7-2", "1-2-4-5-3", "1-4-2-5-3-6", "1-2", "1_2_3_4_5_6", "1-2-3", "1-8-7-2-6-5-4-3", "1-5-4-2-6-3-7-8", "1-6-3-2-5-4", "1-10-9-4-3-6-5-8-7_2", "1-7-5-11-3-9-6-12-2-8-4-10", "1-7-4-10-2-8-6-12-3-9-5-11", "1-4-3-2", "1-12-5-8-3-10-6-7-2-11-4-9", "1-2-7-8-4-5-6-3", "fo20", "fo21", "fo22", "INVALID" firing_order_e firingOrder; end_struct @@ -370,17 +380,17 @@ int sensorSnifferRpmThreshold;+Disable sensor sniffer above this rpm;"RPM", #define engine_load_mode_e_enum "MAF", "Alpha-N/TPS", "MAP", "SPEED DENSITY", "MAF Air Charge" -custom engine_load_mode_e 4 bits, U32, @OFFSET@, [0:2], @@engine_load_mode_e_enum@@ +custom engine_load_mode_e 4 bits, U32, @OFFSET@, [0:7], @@engine_load_mode_e_enum@@ engine_load_mode_e fuelAlgorithm;+This setting controls which fuel quantity control algorithm is used.\nSee also useTPSAdvanceTable\nset algorithm X -custom injection_mode_e 4 bits, U32, @OFFSET@, [0:1], "Simultaneous", "Sequential", "Batch", "Single Point" +custom injection_mode_e 4 bits, U32, @OFFSET@, [0:7], "Simultaneous", "Sequential", "Batch", "Single Point" injection_mode_e crankingInjectionMode;+This is the injection strategy during engine start. See Fuel/Injection settings for more detail. It is suggested to use "Simultaneous". injection_mode_e injectionMode;+This is where the fuel injection type is defined: "Simultaneous" means all injectors will fire together at once. "Sequential" fires the injectors on a per cylinder basis, which requires individually wired injectors. "Batched" will fire the injectors in groups. If your injectors are individually wired you will also need to enable "Two wire batch emulation". \nset injection_mode X\nSee also twoWireBatchInjection angle_t extraInjectionOffset;+this is about deciding when the injector starts it's squirt\nSee also injectionPhase map\ntodo: do we need even need this since we have the map anyway?;"deg", 1, 0.0, -720, 720, 2 angle_t crankingTimingAngle;+Ignition advance angle used during engine cranking, 5-10 degrees will work as a base setting for most engines.\nset cranking_timing_angle X; "deg", 1, 0.0, -360, 360, 2 -custom ignition_mode_e 4 bits, U32, @OFFSET@, [0:1], "One coil", "Individual Coils", "Wasted", "Two distributors" +custom ignition_mode_e 4 bits, U32, @OFFSET@, [0:7], "One coil", "Individual Coils", "Wasted", "Two distributors" ignition_mode_e ignitionMode;+"One Coil" is for use on distributed ignition system. "Individual Coils" is to be used when you have one coil per cylinder (COP or similar). "Wasted" means one coil is driving two spark plugs in two cylinders, with one of the sparks not doing anything since it's happening on the exhaust cycle\nset ignition_mode X angle_t ignitionOffset;+this value could be used to offset the whole ignition timing table by a constant;"RPM", 1, 0, 0, 3000.0, 0 @@ -403,16 +413,16 @@ float fsio_visible fanOffTemperature;+Cooling fan turn-off temperature threshold float vehicleSpeedCoef;+This coefficient translates vehicle speed input frequency (in Hz) into vehicle speed, km/h;"coef", 1, 0, 0.01, 2000.0, 2 -custom can_nbc_e 4 bits, U32, @OFFSET@, [0:1], "BMW", "FIAT", "VAG" , "MAZDA RX8" +custom can_nbc_e 4 bits, U32, @OFFSET@, [0:7], "BMW", "FIAT", "VAG" , "MAZDA RX8" can_nbc_e canNbcType;set can_mode X int canSleepPeriodMs;CANbus thread period, ms;"ms", 1, 0, 0, 1000.0, 2 -custom operation_mode_e 4 bits, U32, @OFFSET@, [0:2], "INVALID", "4 stroke without cam sensor", "4 stroke with cam sensor", "2 stroke", "4 stroke with symmetrical crank (requires VVT input)", "INVALID", "INVALID", "INVALID" +custom operation_mode_e 4 bits, U32, @OFFSET@, [0:7], "INVALID", "4 stroke without cam sensor", "4 stroke with cam sensor", "2 stroke", "4 stroke with symmetrical crank (requires VVT input)", "INVALID", "INVALID", "INVALID" operation_mode_e ambiguousOperationMode;+'Some triggers could be mounted differently. Most well-known triggers imply specific sensor setup. 4 stroke with symmetrical crank' is a pretty special case for example on Miata NB2\nSee engineCycle\nset operation_mode X -custom display_mode_e 4 bits, U32, @OFFSET@, [0:1], "none", "hd44780", "hd44780 over pcf8574", "INVALID" +custom display_mode_e 4 bits, U32, @OFFSET@, [0:7], "none", "hd44780", "hd44780 over pcf8574", "INVALID" display_mode_e displayMode; custom log_format_e 4 bits, U32, @OFFSET@, [0:0], "native", "Mega Log Viewer" @@ -436,7 +446,7 @@ custom bool32_t 4 bits, U32, @OFFSET@, [0:0], "false", "true" #define trigger_type_e_enum "custom toothed wheel", "Ford Aspire", "Dodge Neon 1995", "Miata NA", "Miata NB", "GM_7X", "Cooper R50", "Mazda SOHC 4", "60/2", "36/1", "Honda 4+24+1", "Mitsubishi", "Honda 4+24", "Honda 1+4+24", "Dodge Neon 2003", "Mazda DOHC 1+4", "1+1", "1+60/2", "Single Tooth", "Dodge Ram 1+16", "60/2 VW", "Honda 1+24", "Dodge Stratus", "36_2_2_2", "Nissan Primera", "2JZ", "Rover K", "GM LS 24", "Honda CBR 600", "2JZ_1_12", "Honda CBR 600 custom", "3/1 skipped" , "Dodge Neon 2003 crank", "Miata VVT", "trg34", "trg35", "Subaru 7+6", "Jeep 18-2-2-2", "WIP", "Dodge Neon 1995 crank only", "Jeep XJ 4 cyl", "FiatIAQ_P8", "Mazda Z5", "trg43", "trg44", "trg45", "INVALID" -custom trigger_type_e 4 bits, U32, @OFFSET@, [0:5], @@trigger_type_e_enum@@ +custom trigger_type_e 4 bits, U32, @OFFSET@, [0:7], @@trigger_type_e_enum@@ trigger_type_e type;set trigger_type X bit unusedCustomIsSynchronizationNeeded; @@ -449,7 +459,7 @@ end_struct trigger_config_s trigger; -custom spi_device_e 1 bits,U32, @OFFSET@, [0:2], "Off", "SPI1", "SPI2", "SPI3", "SPI4" +custom spi_device_e 1 bits,U32, @OFFSET@, [0:7], "Off", "SPI1", "SPI2", "SPI3", "SPI4" spi_device_e hip9011SpiDevice; adc_channel_e high_fuel_pressure_sensor_1; adc_channel_e high_fuel_pressure_sensor_2; @@ -458,7 +468,7 @@ custom spi_device_e 1 bits,U32, @OFFSET@, [0:2], "Off", "SPI1", "SPI2", "SPI3" float globalFuelCorrection;set global_fuel_correction X;"coef", 1, 0.0, 0, 1000.0, 2 - float adcVcc;; "volts", 1, 0.0, 0, 4.0, 3 + float adcVcc;; "volts", 1, 0.0, 0, 6.0, 3 float maxKnockSubDeg;maximum total number of degrees to subtract from ignition advance\nwhen knocking brain_input_pin_e[CAM_INPUTS_COUNT iterate] camInputs;+Camshaft input could be used either just for engine phase detection if your trigger shape does not include cam sensor as 'primary' channel, or it could be used for Variable Valve timing on one of the camshafts.\nTODO #660 @@ -549,9 +559,11 @@ spi_device_e digitalPotentiometerSpiDevice;Digital Potentiometer is used by stoc pin_output_mode_e mc33972_csPinMode; -custom adc_channel_mode_e 4 bits, U32, @OFFSET@, [0:1], "Off", "Slow", "Fast", "INVALID" +custom adc_channel_mode_e 4 bits, U32, @OFFSET@, [0:7], "Off", "Slow", "Fast", "INVALID" - etb_io etb1 + adc_channel_e auxFastSensor1_adcChannel;Useful in Research&Development phase + uint8_t[3] unused556; + float fuelLevelEmptyTankVoltage;;"V", 1, 0, 0,10, 2 float fuelLevelFullTankVoltage;;"V", 1, 0, 0,10, 2 @@ -639,11 +651,13 @@ pin_output_mode_e hip9011IntHoldPinMode; -custom uart_device_e 1 bits,U32, @OFFSET@, [0:1], "Off", "UART1", "UART2", "UART3" +custom uart_device_e 1 bits,U32, @OFFSET@, [0:7], "Off", "UART1", "UART2", "UART3" int16_t sdCardPeriodMs;+SD card logging period, in milliseconds;"ms", 1, 0, 0, 30000, 0 brain_pin_e debugSetTimer - uint8_t[1] unusedSpiPadding2; - uint8_t[4] unuseduartPadding1; + brain_pin_e debugMapAveraging; + brain_pin_e starterRelayPin; + pin_output_mode_e starterRelayPinMode; + uint8_t[2] unuseduartPadding1; int mapMinBufferLength;;"count", 1, 0, 0, 24, 0 int16_t idlePidDeactivationTpsThreshold;;"%", 1, 0, 0, 100.0, 0 @@ -686,33 +700,39 @@ custom fsio_setting_t 4 scalar, F32, @OFFSET@, "Val", 1, 0, 0, uart_device_e consoleUartDevice; -#define sensor_chart_e_enum "none", "trigger", "MAP", "RPM ACCEL", "DETAILED RPM", "INVALID" -custom sensor_chart_e 4 bits, S32, @OFFSET@, [0:2], @@sensor_chart_e_enum@@ +#define sensor_chart_e_enum "none", "trigger", "MAP", "RPM ACCEL", "DETAILED RPM", "Fast Aux1", "INVALID", "INVALID" +custom sensor_chart_e 4 bits, S32, @OFFSET@, [0:7], @@sensor_chart_e_enum@@ sensor_chart_e sensorChartMode;+rusEfi console Sensor Sniffer mode #define ego_sensor_e_enum "BPSX", "Innovate", "14Point7", "Narrow", "PLX", "Custom" -custom ego_sensor_e 4 bits, S32, @OFFSET@, [0:2], @@ego_sensor_e_enum@@ +custom ego_sensor_e 4 bits, S32, @OFFSET@, [0:7], @@ego_sensor_e_enum@@ #define maf_sensor_type_e_enum "v0", "v1", "v2", "v3" -custom maf_sensor_type_e 4 bits, S32, @OFFSET@, [0:2], @@maf_sensor_type_e_enum@@ +custom maf_sensor_type_e 4 bits, S32, @OFFSET@, [0:7], @@maf_sensor_type_e_enum@@ -maf_sensor_type_e mafSensorType; +! todo: keep moving all these fields at the end of board_configuration_s below 'board_configuration_s bc' +! end of board_configuration_s +end_struct + +board_configuration_s bc; + maf_sensor_type_e mafSensorType; + + custom le_formula_t 200 string, ASCII, @OFFSET@, 200 brain_pin_e[FSIO_COMMAND_COUNT iterate] fsioDigitalInputs;todo:not finished\nThese input pins allow us to pull toggle buttons state; brain_input_pin_e vehicleSpeedSensorInputPin; switch_input_pin_e clutchUpPin;Some vehicles have a switch to indicate that clutch pedal is all the way up brain_input_pin_e frequencyReportingMapInputPin; pin_input_mode_e clutchUpPinMode; - float etbIdleRange;;"angle", 1, 0, -100, 100, 2 - bit clutchUpPinInverted - bit clutchDownPinInverted - int[121] unusedAtBoardConfigurationEnd; -end_struct -custom le_formula_t 200 string, ASCII, @OFFSET@, 200 - -board_configuration_s bc; -bit vvtDisplayInverted + float unused + bit todoClutchUpPinInverted + bit todoClutchDownPinInverted + etb_io[ETB_COUNT iterate] etbIo +! our strategy is to get rid of "boardConfiguration" and make everything just "engineConfiguration". Please do not add new fields into legacy "bc" area. + int[119] unusedAtOldBoardConfigurationEnd; + + bit vvtDisplayInverted bit fuelClosedLoopCorrectionEnabled;+Enables lambda sensor closed loop feedback for fuelling. bit isVerboseIAC;+Print details into rusEfi console bit isVerboseETB;+Prints ETB details to rusEFI console @@ -775,7 +795,7 @@ bit useSeparateAdvanceForCranking;+This activates a separate advance table for c bit useAdvanceCorrectionsForCranking;+This enables the various ignition corrections during cranking (IAT, CLT, FSIO and PID idle). bit useTPSAdvanceTable;+This flag allows to use TPS for ignition lookup while in Speed Density Fuel Mode bit etbCalibrationOnStart -bit unused_1484_bit_21 +bit useIacPidMultTable;+This flag allows to use a special 'PID Multiplier' table (0.0-1.0) to compensate for nonlinear nature of IAC-RPM controller bit unused_1484_bit_22 bit unused_1484_bit_23 bit unused_1484_bit_24 @@ -824,7 +844,7 @@ float[BARO_CORR_SIZE] baroCorrRpmBins;;"RPM", 1, 0, 0.0, 18000, baro_corr_table_t baroCorrTable; #define pin_mode_e_enum "default", "INVALID", "INVALID", "INVALID", "opendrain", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "PULLUP", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "PULLDOWN" -custom pin_mode_e 1 bits, U08, @OFFSET@, [0:6], @@pin_mode_e_enum@@ +custom pin_mode_e 1 bits, U08, @OFFSET@, [0:7], @@pin_mode_e_enum@@ float[CRANKING_CURVE_SIZE] crankingTpsCoef;Cranking fuel correction coefficient based on TPS;"Ratio", 1, 0, 0.0, 700.0, 2 @@ -839,7 +859,9 @@ custom pin_mode_e 1 bits, U08, @OFFSET@, [0:6], @@pin_mode_e_enum@@ float fuelRailPressure;; "kPa", 1, 0.0, 0, 1000.0, 2 float alternator_derivativeFilterLoss;; "x", 1, 0.0, -1000000, 1000000, 4 float alternator_antiwindupFreq;; "x", 1, 0.0, -1000000, 1000000, 4 - uint8_t[8] unusedFormerWarmupAfrPid; +int16_t tps2Min;Closed throttle#2. todo: extract these two fields into a structure\nSee also tps2_1AdcChannel\nset tps2_min X;"ADC", 1, 0, 0, 1023, 0 +int16_t tps2Max;Full throttle#2. tpsMax value as 10 bit ADC value. Not Voltage!\nSee also tps1_1AdcChannel\nset tps2_max X;"ADC", 1, 0, 0, 1023, 0 + uint8_t[4] unusedFormerWarmupAfrPid; ! todo: mapErrorDetectionIdleTooLow? 30kPa is usually lowest on idle float mapErrorDetectionTooLow;kPa value which is too low to be true;"kPa", 1, 0, -100.0, 100.0, 2 @@ -1047,7 +1069,7 @@ tChargeMode_e tChargeMode; int16_t etb_iTermMin;iTerm min value;"", 1, 0, -30000, 30000.0, 0 int16_t etb_iTermMax;iTerm max value;"", 1, 0, -30000, 30000.0, 0 float etbDeadband;;"", 1, 0, 0, 100.0, 2 - etb_io etb2 + uint8_t[4] unused1059; pid_s idleTimingPid;See useIdleTimingPidControl int16_t idleTimingPidWorkZone;+When the current RPM is closer than this value to the target, closed-loop idle timing control is enabled.;"RPM", 1, 0, 0, 1000, 0 @@ -1074,7 +1096,12 @@ tChargeMode_e tChargeMode; uint8_t[4] unusuedvref; uint8_t[4] unusuedsw; int[3] alFIn; - uint8_t[4] unusedSpiPadding3; + + uint8_t triggerCompCenterVolt;+Trigger comparator center point voltage;"V", @@VOLTAGE_1_BYTE_PACKING_DIV@@, 0, 0.0, 5.1, 2 + uint8_t triggerCompHystMin;+Trigger comparator hysteresis voltage (Min);"V", @@VOLTAGE_1_BYTE_PACKING_DIV@@, 0, 0.0, 5.1, 2 + uint8_t triggerCompHystMax;+Trigger comparator hysteresis voltage (Max);"V", @@VOLTAGE_1_BYTE_PACKING_DIV@@, 0, 0.0, 5.1, 2 + uint8_t triggerCompSensorSatRpm;+VR-sensor saturation RPM;"RPM", @@RPM_1_BYTE_PACKING_MULT@@, 0, 0.0, 12000.0, 0 + pid_s idleRpmPid2 iac_pid_mult_t iacPidMultTable; @@ -1083,6 +1110,7 @@ uint8_t[4] unusuedsw; int[565] mainUnusedEnd; +! end of engine_configuration_s end_struct engine_configuration_s engineConfiguration; @@ -1272,10 +1300,12 @@ end_struct #define GAUGE_NAME_DEBUG_I5 "debug i5" +#define CMD_PINS "pins" #define CMD_CALIBRATE_PEDAL_UP "calibrate_pedal_up" #define CMD_CALIBRATE_PEDAL_DOWN "calibrate_pedal_down" #define CMD_ETB_DUTY "set_etb_duty" +#define CMD_ENGINE_TYPE "engine_type" #define CMD_TRIGGERINFO "triggerinfo" #define CMD_WRITECONFIG "writeconfig" #define CMD_DATE "date" diff --git a/firmware/rusefi_rules.mk b/firmware/rusefi_rules.mk new file mode 100644 index 0000000000..4232098583 --- /dev/null +++ b/firmware/rusefi_rules.mk @@ -0,0 +1,5 @@ +RUSEFI_OPT=-Werror -Wno-error=pointer-sign -Wno-error=unused-function -Wno-error=unused-variable -Wno-error=sign-compare -Wno-error=unused-parameter -Werror=missing-field-initializers + +RUSEFI_OPT+=-Wno-error=missing-prototypes + +RUSEFI_OPT+=-Werror=switch \ No newline at end of file diff --git a/firmware/tunerstudio/rusefi.input b/firmware/tunerstudio/rusefi.input index 89f09d181e..db5f327758 100644 --- a/firmware/tunerstudio/rusefi.input +++ b/firmware/tunerstudio/rusefi.input @@ -737,6 +737,15 @@ fileVersion = { 20190701 } gridOrient = 250, 0, 340 ; Space 123 rotation of grid in degrees. upDownLabel = "(RICHER)", "(LEANER)" + table = iacPidMultTbl, iacPidMultMap, "IAC PID Multiplier Table", 1 + ; constant, variable + xBins = iacPidMultRpmBins, RPMValue + yBins = iacPidMultLoadBins, engineLoad + zBins = iacPidMultTable +; gridHeight = 2.0 + gridOrient = 250, 0, 340 ; Space 123 rotation of grid in degrees. + upDownLabel = "(Later)", "(Sooner)" + [GaugeConfigurations] gaugeCategory = Sensors - Extra 2 @@ -1084,6 +1093,7 @@ menuDialog = main # Digital outputs subMenu = mainRelay, "Main relay" + subMenu = starterRelay, "Starter relay" subMenu = fuelPump, "Fuel rail" subMenu = fanSetting, "Fan" subMenu = tachSettings, "Tachometer" @@ -1156,6 +1166,8 @@ menuDialog = main subMenu = idlehw, "Idle hardware" subMenu = std_separator subMenu = cltIdleRPMCurve, "Target RPM", 0, {idleMode == 0} + subMenu = iacPidMultTbl, "IAC PID Multiplier", 0, {idleMode == 0 && useIacPidMultTable == 1} + subMenu = std_separator subMenu = idleVeCurve, "VE", 0, {useSeparateVeForIdle == 1} subMenu = idleAdvanceCurve, "Ignition advance", 0, {useSeparateAdvanceForIdle == 1} subMenu = std_separator @@ -1574,6 +1586,12 @@ cmd_set_engine_type_default = "w\x00\x31\x00\x00" field = "Brake pedal switch", brakePedalPin field = "A/C switch", acSwitchAdc + dialog = triggerInputComparator, "Built-in Comparator Settings (Kinetis-only)" + field = "Comparator Center Point Voltage", triggerCompCenterVolt + field = "Comparator hysteresis voltage (Min)", triggerCompHystMin + field = "Comparator hysteresis voltage (Max)", triggerCompHystMax + field = "VR-sensor saturation RPM", triggerCompSensorSatRpm + dialog = triggerInputs, "Trigger Inputs" field = "!ECU reboot needed to apply these settings" field = "#Cam is primary if you have cam sensor" @@ -1582,6 +1600,7 @@ cmd_set_engine_type_default = "w\x00\x31\x00\x00" field = "Secondary channel", triggerInputPins2, { trigger_type != 0 && trigger_type != 8 && trigger_type != 9 && trigger_type != 18 && trigger_type != 20} field = "Invert Secondary", invertSecondaryTriggerSignal, { trigger_type != 0 && trigger_type != 8 && trigger_type != 9 && trigger_type != 18 && trigger_type != 20} field = "Cam Sync/VVT input", camInputs1 + panel = triggerInputComparator dialog = allPinsSensors, "Sensors" field = "CLT ADC input", clt_adcChannel @@ -1652,6 +1671,8 @@ cmd_set_engine_type_default = "w\x00\x31\x00\x00" field = "Fan Pin Mode", fanPinMode field = "Main Relay Pin", mainRelayPin field = "Main Relay Mode", mainRelayPinMode + field = "Starter Relay Pin", starterRelayPin + field = "Starter Relay Mode", starterRelayPinMode field = "aux valve #1", auxValves1 field = "aux valve #2", auxValves2 @@ -1720,6 +1741,7 @@ cmd_set_engine_type_default = "w\x00\x31\x00\x00" field = "Debug Trigger Sync", debugTriggerSync field = "Debug Timer Callback", debugTimerCallback field = "Debug Set Timer", debugSetTimer + field = "Aux Fast Analog", auxFastSensor1_adcChannel dialog = allPins1_3 field = "FSIO ADC #1", fsioAdc1 @@ -1942,6 +1964,7 @@ cmd_set_engine_type_default = "w\x00\x31\x00\x00" field = "RPM dead zone to deactivate IAC pid", idlePidRpmDeadZone field = "RPM upper limit to deactivate IAC pid",idlePidRpmUpperLimit field = "PID Extra for low RPM", pidExtraForLowRpm + field = "Use IAC PID Multiplier Table", useIacPidMultTable dialog = idleSettings, "", yAxis @@ -1995,6 +2018,10 @@ cmd_set_engine_type_default = "w\x00\x31\x00\x00" field = "Pin", mainRelayPin field = "Pin mode", mainRelayPinMode + dialog = starterRelay, "Starter relay output" + field = "Pin", starterRelayPin + field = "Pin mode", starterRelayPinMode + dialog = statusLeds, "Status LEDs" field = "Running status LED", runningLedPin field = "TS communication status LED", communicationLedPin @@ -2164,7 +2191,9 @@ cmd_set_engine_type_default = "w\x00\x31\x00\x00" ; Board->Connection dialog = tsPort, "TunerStudio Port" field = "tunerStudioSerialSpeed", tunerStudioSerialSpeed - field = "Use PC10/PC11 serial?", useSerialPort + field = "Use UART/TTL serial?", useSerialPort + field = "RX pin", binarySerialRxPin, {useSerialPort == 1} + field = "TX pin", binarySerialTxPin, {useSerialPort == 1} field = "uartConsoleSerialSpeed", uartConsoleSerialSpeed dialog = canBus, "CAN Bus" @@ -2207,7 +2236,7 @@ cmd_set_engine_type_default = "w\x00\x31\x00\x00" commandButton = "Reinit", cmd_tle8888_init dialog = connection, "", yAxis - field = "STM32 vRef voltage", adcVcc + field = "ADC vRef voltage", adcVcc panel = tsPort panel = canBus panel = sdCard @@ -2468,16 +2497,17 @@ cmd_set_engine_type_default = "w\x00\x31\x00\x00" field = "Pause ETB control", pauseEtbControl field = "Throttle Pedal Up", throttlePedalUpVoltage field = "Throttle Pedal Wide Open", throttlePedalWOTVoltage + field = "Two-wire mode", etb_use_two_wires, {throttlePedalPositionAdcChannel != 16} field = "PWM Frequency", etbFreq, {throttlePedalPositionAdcChannel != 16} field = etbCalibrationOnStart, etbCalibrationOnStart - field = "No1 Direction #1", etb1_directionPin1, {throttlePedalPositionAdcChannel != 16} - field = "No1 Direction #2", etb1_directionPin2, {throttlePedalPositionAdcChannel != 16} - field = "Two-wire mode", etb1_use_two_wires, {throttlePedalPositionAdcChannel != 16} - field = "No1 Control #1", etb1_controlPin1, {throttlePedalPositionAdcChannel != 16 && etb1_use_two_wires == 0} - field = "No2 Direction #1", etb2_directionPin1, {throttlePedalPositionAdcChannel != 16} - field = "No2 Direction #2", etb2_directionPin2, {throttlePedalPositionAdcChannel != 16} - field = "Two-wire mode", etb2_use_two_wires, {throttlePedalPositionAdcChannel != 16} - field = "No2 Control #1", etb2_controlPin1, {throttlePedalPositionAdcChannel != 16 && etb2_use_two_wires == 0} + field = "No1 Direction #1", etbIo1_directionPin1, {throttlePedalPositionAdcChannel != 16} + field = "No1 Direction #2", etbIo1_directionPin2, {throttlePedalPositionAdcChannel != 16} + field = "No1 Control #1", etbIo1_controlPin1, {throttlePedalPositionAdcChannel != 16 && etb_use_two_wires == 0} + field = "No2 Direction #1", etbIo2_directionPin1, {throttlePedalPositionAdcChannel != 16} + field = "No2 Direction #2", etbIo2_directionPin2, {throttlePedalPositionAdcChannel != 16} + field = "No2 Control #1", etb2_controlPin1, {throttlePedalPositionAdcChannel != 16 && etb_use_two_wires == 0} + field = "TPS#2 min", tps2Min, {etbIo2_directionPin1 != 0} + field = "TPS#2 max", tps2Max, {etbIo2_directionPin1 != 0} panel = etbPidDialog dialog = etbDialogRight diff --git a/firmware/util/containers/fl_stack.h b/firmware/util/containers/fl_stack.h index 273c0828d1..a85a45fa5f 100644 --- a/firmware/util/containers/fl_stack.h +++ b/firmware/util/containers/fl_stack.h @@ -10,7 +10,6 @@ #define FL_STACK_H_ #include "global.h" -#include "error_handling.h" template class FLStack { diff --git a/firmware/util/containers/table_helper.cpp b/firmware/util/containers/table_helper.cpp index 1dcfec6aaa..845bdb5869 100644 --- a/firmware/util/containers/table_helper.cpp +++ b/firmware/util/containers/table_helper.cpp @@ -18,10 +18,6 @@ void setRpmBin(float array[], int size, float idleRpm, float topRpm) { array[size - 1] = topRpm; } -void setTableBin(float array[], int size, float from, float to) { - setLinearCurve(array, size, from, to, 0.01); -} - /** * initialize RPM table axis using default RPM range */ diff --git a/firmware/util/containers/table_helper.h b/firmware/util/containers/table_helper.h index d61b1b3a39..d3f29a82d1 100644 --- a/firmware/util/containers/table_helper.h +++ b/firmware/util/containers/table_helper.h @@ -158,20 +158,18 @@ typedef Map3D ign_tps_Map3D_t; typedef Map3D fuel_Map3D_t; typedef Map3D baroCorr_Map3D_t; typedef Map3D pedal2tps_t; +typedef Map3D iacPidMultiplier_t; void setRpmBin(float array[], int size, float idleRpm, float topRpm); -void setTableBin(float array[], int size, float from, float to); - -#define setArrayValues(array, size, value) setTableBin(array, size, value, value) - /** - * @param precision for example '0.1' for one digit fractional part + * @param precision for example '0.1' for one digit fractional part. Default to 0.01, two digits. */ -template -void setLinearCurveAny(vType array[], int size, float from, float to, float precision) { - for (int i = 0; i < size; i++) { - float value = interpolateMsg("setLinearCurve", 0, from, size - 1, to, i); +template +void setLinearCurve(TValue (&array)[TSize], float from, float to, float precision = 0.01f) { + for (int i = 0; i < TSize; i++) { + float value = interpolateMsg("setLinearCurve", 0, from, TSize - 1, to, i); + /** * rounded values look nicer, also we want to avoid precision mismatch with Tuner Studio */ @@ -179,7 +177,13 @@ void setLinearCurveAny(vType array[], int size, float from, float to, float prec } } -#define setLinearCurve setLinearCurveAny +template +void setArrayValues(TValue (&array)[TSize], TValue value) { + for (int i = 0; i < TSize; i++) { + array[i] = value; + } +} + void setRpmTableBin(float array[], int size); #endif /* TABLE_HELPER_H_ */ diff --git a/firmware/util/math/pid.cpp b/firmware/util/math/pid.cpp index 1cd09b0ba7..8546df9aa4 100644 --- a/firmware/util/math/pid.cpp +++ b/firmware/util/math/pid.cpp @@ -12,6 +12,7 @@ #include "os_access.h" #include "pid.h" #include "math.h" +#include "engine_configuration_generated_structures.h" Pid::Pid() { initPidClass(NULL); @@ -28,7 +29,7 @@ void Pid::initPidClass(pid_s *parameters) { reset(); } -bool Pid::isSame(pid_s *parameters) const { +bool Pid::isSame(const pid_s *parameters) const { efiAssert(OBD_PCM_Processor_Fault, this->parameters != NULL, "PID::isSame invalid", false); efiAssert(OBD_PCM_Processor_Fault, parameters != NULL, "PID::isSame NULL", false); return this->parameters->pFactor == parameters->pFactor @@ -153,7 +154,7 @@ void Pid::sleep() { #endif /* EFI_UNIT_TEST */ } -void Pid::showPidStatus(Logging *logging, const char*msg) { +void Pid::showPidStatus(Logging *logging, const char*msg) const { scheduleMsg(logging, "%s settings: offset=%f P=%.5f I=%.5f D=%.5f period=%dms", msg, getOffset(), diff --git a/firmware/util/math/pid.h b/firmware/util/math/pid.h index becd8be186..1374894317 100644 --- a/firmware/util/math/pid.h +++ b/firmware/util/math/pid.h @@ -8,8 +8,6 @@ #ifndef PID_H_ #define PID_H_ -#include "global.h" -#include "engine_configuration_generated_structures.h" #include "engine_state_generated.h" #include "pid_state_generated.h" @@ -30,13 +28,16 @@ #define MS2SEC(x) (x * 0.001) +struct pid_s; +class Logging; + class Pid : public pid_state_s { public: Pid(); explicit Pid(pid_s *parameters); void initPidClass(pid_s *parameters); - bool isSame(pid_s *parameters) const; + bool isSame(const pid_s *parameters) const; /** * This version of the method takes dTime from pid_s @@ -62,7 +63,7 @@ public: void postState(TunerStudioOutputChannels *tsOutputChannels); void postState(TunerStudioOutputChannels *tsOutputChannels, int pMult); #endif /* EFI_TUNER_STUDIO */ - void showPidStatus(Logging *logging, const char*msg); + void showPidStatus(Logging *logging, const char*msg) const; void sleep(); int resetCounter; // todo: move this to pid_s one day diff --git a/java_console/autotest/src/com/rusefi/AutoTest.java b/java_console/autotest/src/com/rusefi/AutoTest.java index ed48aaca6c..99eae07a0a 100644 --- a/java_console/autotest/src/com/rusefi/AutoTest.java +++ b/java_console/autotest/src/com/rusefi/AutoTest.java @@ -15,6 +15,7 @@ import com.rusefi.waves.EngineReport; import static com.rusefi.IoUtil.sleep; import static com.rusefi.TestingUtils.*; +import static com.rusefi.config.generated.Fields.CMD_PINS; import static com.rusefi.config.generated.Fields.MOCK_MAF_COMMAND; import static com.rusefi.io.CommandQueue.disableCommand; import static com.rusefi.waves.EngineReport.isCloseEnough; @@ -135,8 +136,9 @@ public class AutoTest { } static void setEngineType(int type) { + sendCommand(CMD_PINS); currentEngineType = type; - sendCommand("set engine_type " + type, COMPLEX_COMMAND_RETRY, 30); + sendCommand("set " + Fields.CMD_ENGINE_TYPE + " " + type, COMPLEX_COMMAND_RETRY, 30); sleep(10); sendCommand("enable self_stimulation"); } diff --git a/java_console/autotest/src/com/rusefi/EnduranceTest.java b/java_console/autotest/src/com/rusefi/EnduranceTest.java index 28e6e17e61..cb6ec4cfff 100644 --- a/java_console/autotest/src/com/rusefi/EnduranceTest.java +++ b/java_console/autotest/src/com/rusefi/EnduranceTest.java @@ -1,5 +1,7 @@ package com.rusefi; +import com.rusefi.config.generated.Fields; + import static com.rusefi.IoUtil.sendCommand; import static com.rusefi.IoUtil.sleep; import static com.rusefi.RealHwTest.startRealHardwareTest; @@ -24,12 +26,12 @@ public class EnduranceTest { IoUtil.realHardwareConnect(port); for (int i = 0; i < count; i++) { AutoTest.currentEngineType = 3; - sendCommand("set_engine_type " + 3, AutoTest.COMPLEX_COMMAND_RETRY, 60); + sendCommand("set " + Fields.CMD_ENGINE_TYPE + " " + 3, AutoTest.COMPLEX_COMMAND_RETRY, 60); sleep(2); sendCommand("enable self_stimulation"); // IoUtil.changeRpm(1200); AutoTest.currentEngineType = 28; - sendCommand("set_engine_type " + 28, AutoTest.COMPLEX_COMMAND_RETRY, 60); + sendCommand("set " + Fields.CMD_ENGINE_TYPE + " " + 28, AutoTest.COMPLEX_COMMAND_RETRY, 60); sleep(2); FileLog.MAIN.logLine("++++++++++++++++++++++++++++++++++++ " + i + " +++++++++++++++"); } diff --git a/java_console/io/src/com/rusefi/io/CommandQueue.java b/java_console/io/src/com/rusefi/io/CommandQueue.java index 56d64f4ef9..11bb5c393e 100644 --- a/java_console/io/src/com/rusefi/io/CommandQueue.java +++ b/java_console/io/src/com/rusefi/io/CommandQueue.java @@ -53,7 +53,7 @@ public class CommandQueue { private static boolean isSlowCommand(String cmd) { String lc = cmd.toLowerCase(); - return lc.startsWith("set_engine_type") || lc.startsWith("writeconfig") || lc.startsWith("rewriteconfig"); + return lc.startsWith("set " + Fields.CMD_ENGINE_TYPE) || lc.startsWith("writeconfig") || lc.startsWith("rewriteconfig"); } public static int getTimeout(String cmd) { diff --git a/java_console/models/src/com/rusefi/FiringOrderTSLogic.java b/java_console/models/src/com/rusefi/FiringOrderTSLogic.java index 05693ba11b..5ed9766ab5 100644 --- a/java_console/models/src/com/rusefi/FiringOrderTSLogic.java +++ b/java_console/models/src/com/rusefi/FiringOrderTSLogic.java @@ -15,17 +15,21 @@ public class FiringOrderTSLogic { private static final String FIRING_ORDER_PREFIX = "FO_"; private static final Map ordinal2order = new HashMap<>(); + private static int maxOrdinal; public static void main(String[] args) throws IOException { - readFiringOrders(); - - for (int i = 2; i <= 12; i++) - processId(i); - + invoke("../firmware/controllers/algo/firing_order.h"); } - private static void readFiringOrders() throws IOException { - BufferedReader br = new BufferedReader(new FileReader("../firmware/controllers/algo/firing_order.h")); + public static void invoke(String fileName) throws IOException { + readFiringOrders(fileName); + + for (int i = 2; i <= maxOrdinal; i++) + processId(i); + } + + private static void readFiringOrders(String fileName) throws IOException { + BufferedReader br = new BufferedReader(new FileReader(fileName)); String line; while ((line = br.readLine()) != null) { @@ -50,6 +54,7 @@ public class FiringOrderTSLogic { System.out.println("order " + Arrays.toString(order) + ": " + ordinal); + maxOrdinal = Math.max(ordinal, maxOrdinal); ordinal2order.put(ordinal, order); } diff --git a/java_console/models/src/com/rusefi/PerfTraceTool.java b/java_console/models/src/com/rusefi/PerfTraceTool.java new file mode 100644 index 0000000000..37590f3e05 --- /dev/null +++ b/java_console/models/src/com/rusefi/PerfTraceTool.java @@ -0,0 +1,90 @@ +package com.rusefi; + +import com.rusefi.tracing.Entry; +import com.rusefi.tracing.EnumNames; +import com.rusefi.tracing.JsonOutput; + +import java.io.*; +import java.util.ArrayList; +import java.util.List; + +/** + * This tool generates C# or Java class based on enum values from C/C++ header related to rusEfi own Perf Trace + * + * This allows developers to only edit C/C++ header yet see proper names in chrome://tracing JSON file + * + * This is not used in runtime while profiling actual firmware + * @see JsonOutput + * @see EnumNames + * + * @see EnumNames + * @see Entry + * + */ +public class PerfTraceTool { + private static final String ENUM_START_TAG = "enum_start_tag"; + private static final String ENUM_END_TAG = "enum_end_tag"; + private static final String EOL = "\r\n"; + + public static void readPerfTrace(String inputFileName, String outputFileName, String topClassLine, String stringType) throws IOException { + List enumNames = readEnums(inputFileName); + System.out.println("Got enums: " + enumNames); + + + writeClass(outputFileName, enumNames, topClassLine, stringType); + } + + private static void writeClass(String outputFileName, List enumNames, String topClassLine, String stringType) throws IOException { + BufferedWriter writer = new BufferedWriter(new FileWriter(outputFileName)); + + + writer.write(topClassLine + EOL + EOL); + + writer.write("public class EnumNames {" + EOL); + writer.write("\t" + + stringType + + "[] TypeNames = {" + EOL); + + for (String enumValue : enumNames) + writer.write("\t\"" + enumValue + "\"," + EOL); + + + writer.write("\t};" + EOL); + writer.write("}" + EOL); + writer.close(); + + System.out.println("Done writing to " + outputFileName); + } + + private static List readEnums(String inputFileName) throws IOException { + BufferedReader br = new BufferedReader(new FileReader(inputFileName)); + + boolean weAreInBusiness = false; + List result = new ArrayList<>(); + + String line; + while ((line = br.readLine()) != null) { + if (line.contains(ENUM_START_TAG)) { + weAreInBusiness = true; + continue; + } + + if (line.contains(ENUM_END_TAG)) { + // we are done here + break; + } + + if (!weAreInBusiness) + continue; + + line = line.trim().replaceAll("\\s", ""); + + if (line.endsWith(",")) { + result.add(line.substring(0, line.length() - 1)); + } + + + } + return result; + } +} diff --git a/java_console/models/src/com/rusefi/config/generated/Fields.java b/java_console/models/src/com/rusefi/config/generated/Fields.java index 59298eaacf..793263ad05 100644 --- a/java_console/models/src/com/rusefi/config/generated/Fields.java +++ b/java_console/models/src/com/rusefi/config/generated/Fields.java @@ -1,6 +1,6 @@ package com.rusefi.config.generated; -// this file was generated automatically by rusEfi tool ConfigDefinition.jar based on integration\rusefi_config.txt Mon Nov 18 19:05:30 EST 2019 +// this file was generated automatically by rusEfi tool ConfigDefinition.jar based on integration\rusefi_config.txt Sun Dec 08 00:20:37 EST 2019 // by class com.rusefi.output.FileJavaFieldsConsumer import com.rusefi.config.*; @@ -64,6 +64,7 @@ public class Fields { public static final int autoTuneTpsRocThreshold_offset_hex = 978; public static final int AUX_DIGITAL_VALVE_COUNT = 2; public static final int AUX_PID_COUNT = 4; + public static final int auxFastSensor1_adcChannel_offset = 680; public static final int auxPid1_dFactor_offset = 2620; public static final int auxPid1_iFactor_offset = 2616; public static final int auxPid1_maxValue_offset = 2630; @@ -233,17 +234,17 @@ public class Fields { public static final int cltTimingExtra_offset_hex = 950; public static final int clutchDownPin_offset = 664; public static final int clutchDownPin_offset_hex = 298; - public static final int clutchDownPinInverted_offset = 976; public static final int clutchDownPinMode_offset = 667; public static final int clutchUpPin_offset = 969; - public static final int clutchUpPinInverted_offset = 976; public static final int clutchUpPinMode_offset = 971; public static final String CMD_CALIBRATE_PEDAL_DOWN = "calibrate_pedal_down"; public static final String CMD_CALIBRATE_PEDAL_UP = "calibrate_pedal_up"; public static final String CMD_DATE = "date"; public static final String CMD_DISABLE = "disable"; public static final String CMD_ENABLE = "enable"; + public static final String CMD_ENGINE_TYPE = "engine_type"; public static final String CMD_ETB_DUTY = "set_etb_duty"; + public static final String CMD_PINS = "pins"; public static final String CMD_REBOOT = "reboot"; public static final String CMD_REBOOT_DFU = "reboot_dfu"; public static final String CMD_TRIGGER_HW_INPUT = "trigger_hw_input"; @@ -296,6 +297,8 @@ public class Fields { public static final int cylinderBore_offset_hex = 198; public static final int cylindersCount_offset = 400; public static final int cylindersCount_offset_hex = 190; + public static final int debugMapAveraging_offset = 807; + public static final int debugMapAveraging_offset_hex = 327; public static final int debugMode_offset = 2092; public static final int debugSetTimer_offset = 806; public static final int debugSetTimer_offset_hex = 326; @@ -334,19 +337,8 @@ public class Fields { public static final int engineSnifferRpmThreshold_offset_hex = 4; public static final int engineType_offset = 0; public static final int engineType_offset_hex = 0; - public static final int etb1_controlPin1_offset = 682; - public static final int etb1_controlPinMode_offset = 683; - public static final int etb1_directionPin1_offset = 680; - public static final int etb1_directionPin2_offset = 681; - public static final int etb1_offset = 680; - public static final int etb1_use_two_wires_offset = 76; - public static final int etb2_controlPin1_offset = 3966; - public static final int etb2_controlPinMode_offset = 3967; - public static final int etb2_directionPin1_offset = 3964; - public static final int etb2_directionPin2_offset = 3965; - public static final int etb2_offset = 3964; - public static final int etb2_use_two_wires_offset = 76; public static final int ETB_BIAS_CURVE_LENGTH = 8; + public static final int ETB_COUNT = 2; public static final int etb_dFactor_offset = 1744; public static final int etb_iFactor_offset = 1740; public static final int etb_iTermMax_offset = 3958; @@ -357,13 +349,23 @@ public class Fields { public static final int etb_offset_offset = 1748; public static final int etb_periodMs_offset = 1750; public static final int etb_pFactor_offset = 1736; + public static final int etb_use_two_wires_offset = 76; public static final int etbBiasBins_offset = 3888; public static final int etbBiasValues_offset = 3920; public static final int etbCalibrationOnStart_offset = 1476; public static final int etbDeadband_offset = 3960; public static final int etbFreq_offset = 2514; - public static final int etbIdleRange_offset = 972; public static final int etbIdleThrottleRange_offset = 4012; + public static final int etbIo1_controlPin1_offset = 982; + public static final int etbIo1_controlPinMode_offset = 983; + public static final int etbIo1_directionPin1_offset = 980; + public static final int etbIo1_directionPin2_offset = 981; + public static final int etbIo1_offset = 980; + public static final int etbIo2_controlPin1_offset = 986; + public static final int etbIo2_controlPinMode_offset = 987; + public static final int etbIo2_directionPin1_offset = 984; + public static final int etbIo2_directionPin2_offset = 985; + public static final int etbIo2_offset = 984; public static final int etbNeutralPosition_offset = 1471; public static final int externalKnockSenseAdc_offset = 3103; public static final int extraInjectionOffset_offset = 432; @@ -1107,6 +1109,10 @@ public class Fields { public static final int spi3mosiPin_offset = 934; public static final int spi3SckMode_offset = 2602; public static final int spi3sckPin_offset = 936; + public static final int starterRelayPin_offset = 808; + public static final int starterRelayPin_offset_hex = 328; + public static final int starterRelayPinMode_offset = 809; + public static final int starterRelayPinMode_offset_hex = 329; public static final int startOfCrankingPrimingPulse_offset = 2032; public static final int startUpFuelPumpDuration_offset = 1892; public static final int startUpFuelPumpDuration_offset_hex = 764; @@ -1173,12 +1179,16 @@ public class Fields { public static final int tle8888_cs_offset = 3105; public static final int tle8888_csPinMode_offset = 3106; public static final int tle8888spiDevice_offset = 4000; + public static final int todoClutchDownPinInverted_offset = 976; + public static final int todoClutchUpPinInverted_offset = 976; public static final String TOP_DEAD_CENTER_MESSAGE = "r"; public static final int TOTAL_CONFIG_SIZE = 20000; public static final int tps1_1AdcChannel_offset = 512; public static final int tps1_1AdcChannel_offset_hex = 200; public static final int tps2_1AdcChannel_offset = 515; public static final int tps2_1AdcChannel_offset_hex = 203; + public static final int tps2Max_offset = 1770; + public static final int tps2Min_offset = 1768; public static final int TPS_TPS_ACCEL_TABLE = 8; public static final int tpsAccelEnrichmentThreshold_offset = 2048; public static final int tpsAccelEnrichmentThreshold_offset_hex = 800; @@ -1214,6 +1224,10 @@ public class Fields { public static final int trigger_unusedCustomNeedSecondTriggerInput_offset_hex = 210; public static final int trigger_useOnlyFirstChannel_offset = 528; public static final int trigger_useOnlyFirstChannel_offset_hex = 210; + public static final int triggerCompCenterVolt_offset = 4036; + public static final int triggerCompHystMax_offset = 4038; + public static final int triggerCompHystMin_offset = 4037; + public static final int triggerCompSensorSatRpm_offset = 4039; public static final int triggerErrorPin_offset = 828; public static final int triggerErrorPinMode_offset = 829; public static final int triggerInputPins1_offset = 700; @@ -1234,8 +1248,9 @@ public class Fields { public static final int twoWireBatchInjection_offset = 1476; public static final int uartConsoleSerialSpeed_offset = 2076; public static final int unrealisticRpmThreashold_offset = 760; + public static final int unused1059_offset = 3964; public static final int unused1234234_offset = 2042; - public static final int unused_1484_bit_21_offset = 1476; + public static final int unused556_offset = 681; public static final int unused_1484_bit_22_offset = 1476; public static final int unused_1484_bit_23_offset = 1476; public static final int unused_1484_bit_24_offset = 1476; @@ -1249,21 +1264,19 @@ public class Fields { public static final int unused_board_984_31_offset = 744; public static final int unused_former_warmup_target_afr_offset = 2096; public static final int unused_former_warmup_target_afr_offset_hex = 830; + public static final int unused_offset = 972; public static final int unusedAnotherOne_offset = 744; - public static final int unusedAtBoardConfigurationEnd_offset = 980; + public static final int unusedAtOldBoardConfigurationEnd_offset = 988; public static final int unusedErrorPin_offset = 2040; public static final int unusedFlexFuelSensor_offset = 3100; - public static final int unusedFormerWarmupAfrPid_offset = 1768; + public static final int unusedFormerWarmupAfrPid_offset = 1772; + public static final int unusedHereo_wires_offset = 76; public static final int unusedOldWarmupAfr_offset = 744; - public static final int unusedSpiPadding2_offset = 807; - public static final int unusedSpiPadding2_offset_hex = 327; - public static final int unusedSpiPadding3_offset = 4036; public static final int unusedSpiPadding4_offset = 2593; public static final int unusedSpiPadding5_offset = 2713; public static final int unusedSpiPadding7_offset = 4005; public static final int unusedSpiPadding8_offset = 4009; - public static final int unuseduartPadding1_offset = 808; - public static final int unuseduartPadding1_offset_hex = 328; + public static final int unuseduartPadding1_offset = 810; public static final int unusuedsw_offset = 4020; public static final int unusuedvref_offset = 4016; public static final int useAdvanceCorrectionsForCranking_offset = 1476; @@ -1283,6 +1296,7 @@ public class Fields { public static final int useFSIO6ForRevLimiter_offset = 1464; public static final int useFSIO8ForServo1_offset = 1464; public static final int useFSIO9ForServo2_offset = 1464; + public static final int useIacPidMultTable_offset = 1476; public static final int useIacTableForCoasting_offset = 744; public static final int useIdleTimingPidControl_offset = 744; public static final int useInstantRpmForIdle_offset = 76; @@ -1342,8 +1356,8 @@ public class Fields { public static final Field USEBIQUADANALOGFILTERING = Field.create("USEBIQUADANALOGFILTERING", 76, FieldType.BIT, 9); public static final Field CJ125ISUADIVIDED = Field.create("CJ125ISUADIVIDED", 76, FieldType.BIT, 10); public static final Field CJ125ISLSU49 = Field.create("CJ125ISLSU49", 76, FieldType.BIT, 11); - public static final Field ETB1_USE_TWO_WIRES = Field.create("ETB1_USE_TWO_WIRES", 76, FieldType.BIT, 12); - public static final Field ETB2_USE_TWO_WIRES = Field.create("ETB2_USE_TWO_WIRES", 76, FieldType.BIT, 13); + public static final Field ETB_USE_TWO_WIRES = Field.create("ETB_USE_TWO_WIRES", 76, FieldType.BIT, 12); + public static final Field UNUSEDHEREO_WIRES = Field.create("UNUSEDHEREO_WIRES", 76, FieldType.BIT, 13); public static final Field SHOWSDCARDWARNING = Field.create("SHOWSDCARDWARNING", 76, FieldType.BIT, 14); public static final Field CJ125ISURDIVIDED = Field.create("CJ125ISURDIVIDED", 76, FieldType.BIT, 15); public static final Field USETLE8888_HALL_MODE = Field.create("USETLE8888_HALL_MODE", 76, FieldType.BIT, 16); @@ -1532,10 +1546,7 @@ public class Fields { public static final Field DIGITALPOTENTIOMETERSPIDEVICE = Field.create("DIGITALPOTENTIOMETERSPIDEVICE", 677, FieldType.INT8); public static final Field MC33972_CS = Field.create("MC33972_CS", 678, FieldType.INT8, brain_pin_e); public static final Field MC33972_CSPINMODE = Field.create("MC33972_CSPINMODE", 679, FieldType.INT8, pin_output_mode_e); - public static final Field ETB1_DIRECTIONPIN1 = Field.create("ETB1_DIRECTIONPIN1", 680, FieldType.INT8, brain_pin_e); - public static final Field ETB1_DIRECTIONPIN2 = Field.create("ETB1_DIRECTIONPIN2", 681, FieldType.INT8, brain_pin_e); - public static final Field ETB1_CONTROLPIN1 = Field.create("ETB1_CONTROLPIN1", 682, FieldType.INT8, brain_pin_e); - public static final Field ETB1_CONTROLPINMODE = Field.create("ETB1_CONTROLPINMODE", 683, FieldType.INT8, pin_output_mode_e); + public static final Field AUXFASTSENSOR1_ADCCHANNEL = Field.create("AUXFASTSENSOR1_ADCCHANNEL", 680, FieldType.INT8, adc_channel_e); public static final Field FUELLEVELEMPTYTANKVOLTAGE = Field.create("FUELLEVELEMPTYTANKVOLTAGE", 684, FieldType.FLOAT); public static final Field FUELLEVELFULLTANKVOLTAGE = Field.create("FUELLEVELFULLTANKVOLTAGE", 688, FieldType.FLOAT); public static final String[] ego_sensor_e = {"BPSX", "Innovate", "14Point7", "Narrow", "PLX", "Custom"}; @@ -1651,7 +1662,9 @@ public class Fields { public static final Field MAX31855_CS8 = Field.create("MAX31855_CS8", 803, FieldType.INT8, brain_pin_e); public static final Field SDCARDPERIODMS = Field.create("SDCARDPERIODMS", 804, FieldType.INT16); public static final Field DEBUGSETTIMER = Field.create("DEBUGSETTIMER", 806, FieldType.INT8, brain_pin_e); - public static final Field UNUSEDSPIPADDING2 = Field.create("UNUSEDSPIPADDING2", 807, FieldType.INT8); + public static final Field DEBUGMAPAVERAGING = Field.create("DEBUGMAPAVERAGING", 807, FieldType.INT8, brain_pin_e); + public static final Field STARTERRELAYPIN = Field.create("STARTERRELAYPIN", 808, FieldType.INT8, brain_pin_e); + public static final Field STARTERRELAYPINMODE = Field.create("STARTERRELAYPINMODE", 809, FieldType.INT8, pin_output_mode_e); public static final Field MAPMINBUFFERLENGTH = Field.create("MAPMINBUFFERLENGTH", 812, FieldType.INT); public static final Field IDLEPIDDEACTIVATIONTPSTHRESHOLD = Field.create("IDLEPIDDEACTIVATIONTPSTHRESHOLD", 816, FieldType.INT16); public static final Field STEPPERPARKINGEXTRASTEPS = Field.create("STEPPERPARKINGEXTRASTEPS", 818, FieldType.INT16); @@ -1709,7 +1722,7 @@ public class Fields { public static final Field JOYSTICKCPIN = Field.create("JOYSTICKCPIN", 941, FieldType.INT8, brain_pin_e); public static final Field JOYSTICKDPIN = Field.create("JOYSTICKDPIN", 942, FieldType.INT8, brain_pin_e); public static final Field CONSOLEUARTDEVICE = Field.create("CONSOLEUARTDEVICE", 943, FieldType.INT8); - public static final String[] sensor_chart_e = {"none", "trigger", "MAP", "RPM ACCEL", "DETAILED RPM", "INVALID"}; + public static final String[] sensor_chart_e = {"none", "trigger", "MAP", "RPM ACCEL", "DETAILED RPM", "Fast Aux1", "INVALID", "INVALID"}; public static final Field SENSORCHARTMODE = Field.create("SENSORCHARTMODE", 944, FieldType.INT, sensor_chart_e); public static final String[] maf_sensor_type_e = {"v0", "v1", "v2", "v3"}; public static final Field MAFSENSORTYPE = Field.create("MAFSENSORTYPE", 948, FieldType.INT, maf_sensor_type_e); @@ -1733,9 +1746,17 @@ public class Fields { public static final Field CLUTCHUPPIN = Field.create("CLUTCHUPPIN", 969, FieldType.INT8, switch_input_pin_e); public static final Field FREQUENCYREPORTINGMAPINPUTPIN = Field.create("FREQUENCYREPORTINGMAPINPUTPIN", 970, FieldType.INT8, brain_input_pin_e); public static final Field CLUTCHUPPINMODE = Field.create("CLUTCHUPPINMODE", 971, FieldType.INT8); - public static final Field ETBIDLERANGE = Field.create("ETBIDLERANGE", 972, FieldType.FLOAT); - public static final Field CLUTCHUPPININVERTED = Field.create("CLUTCHUPPININVERTED", 976, FieldType.BIT, 0); - public static final Field CLUTCHDOWNPININVERTED = Field.create("CLUTCHDOWNPININVERTED", 976, FieldType.BIT, 1); + public static final Field UNUSED = Field.create("UNUSED", 972, FieldType.FLOAT); + public static final Field TODOCLUTCHUPPININVERTED = Field.create("TODOCLUTCHUPPININVERTED", 976, FieldType.BIT, 0); + public static final Field TODOCLUTCHDOWNPININVERTED = Field.create("TODOCLUTCHDOWNPININVERTED", 976, FieldType.BIT, 1); + public static final Field ETBIO1_DIRECTIONPIN1 = Field.create("ETBIO1_DIRECTIONPIN1", 980, FieldType.INT8, brain_pin_e); + public static final Field ETBIO1_DIRECTIONPIN2 = Field.create("ETBIO1_DIRECTIONPIN2", 981, FieldType.INT8, brain_pin_e); + public static final Field ETBIO1_CONTROLPIN1 = Field.create("ETBIO1_CONTROLPIN1", 982, FieldType.INT8, brain_pin_e); + public static final Field ETBIO1_CONTROLPINMODE = Field.create("ETBIO1_CONTROLPINMODE", 983, FieldType.INT8, pin_output_mode_e); + public static final Field ETBIO2_DIRECTIONPIN1 = Field.create("ETBIO2_DIRECTIONPIN1", 984, FieldType.INT8, brain_pin_e); + public static final Field ETBIO2_DIRECTIONPIN2 = Field.create("ETBIO2_DIRECTIONPIN2", 985, FieldType.INT8, brain_pin_e); + public static final Field ETBIO2_CONTROLPIN1 = Field.create("ETBIO2_CONTROLPIN1", 986, FieldType.INT8, brain_pin_e); + public static final Field ETBIO2_CONTROLPINMODE = Field.create("ETBIO2_CONTROLPINMODE", 987, FieldType.INT8, pin_output_mode_e); public static final Field VVTDISPLAYINVERTED = Field.create("VVTDISPLAYINVERTED", 1464, FieldType.BIT, 0); public static final Field FUELCLOSEDLOOPCORRECTIONENABLED = Field.create("FUELCLOSEDLOOPCORRECTIONENABLED", 1464, FieldType.BIT, 1); public static final Field ISVERBOSEIAC = Field.create("ISVERBOSEIAC", 1464, FieldType.BIT, 2); @@ -1794,7 +1815,7 @@ public class Fields { public static final Field USEADVANCECORRECTIONSFORCRANKING = Field.create("USEADVANCECORRECTIONSFORCRANKING", 1476, FieldType.BIT, 18); public static final Field USETPSADVANCETABLE = Field.create("USETPSADVANCETABLE", 1476, FieldType.BIT, 19); public static final Field ETBCALIBRATIONONSTART = Field.create("ETBCALIBRATIONONSTART", 1476, FieldType.BIT, 20); - public static final Field UNUSED_1484_BIT_21 = Field.create("UNUSED_1484_BIT_21", 1476, FieldType.BIT, 21); + public static final Field USEIACPIDMULTTABLE = Field.create("USEIACPIDMULTTABLE", 1476, FieldType.BIT, 21); public static final Field UNUSED_1484_BIT_22 = Field.create("UNUSED_1484_BIT_22", 1476, FieldType.BIT, 22); public static final Field UNUSED_1484_BIT_23 = Field.create("UNUSED_1484_BIT_23", 1476, FieldType.BIT, 23); public static final Field UNUSED_1484_BIT_24 = Field.create("UNUSED_1484_BIT_24", 1476, FieldType.BIT, 24); @@ -1857,6 +1878,8 @@ public class Fields { public static final Field FUELRAILPRESSURE = Field.create("FUELRAILPRESSURE", 1756, FieldType.FLOAT); public static final Field ALTERNATOR_DERIVATIVEFILTERLOSS = Field.create("ALTERNATOR_DERIVATIVEFILTERLOSS", 1760, FieldType.FLOAT); public static final Field ALTERNATOR_ANTIWINDUPFREQ = Field.create("ALTERNATOR_ANTIWINDUPFREQ", 1764, FieldType.FLOAT); + public static final Field TPS2MIN = Field.create("TPS2MIN", 1768, FieldType.INT16); + public static final Field TPS2MAX = Field.create("TPS2MAX", 1770, FieldType.INT16); public static final Field MAPERRORDETECTIONTOOLOW = Field.create("MAPERRORDETECTIONTOOLOW", 1776, FieldType.FLOAT); public static final Field MAPERRORDETECTIONTOOHIGH = Field.create("MAPERRORDETECTIONTOOHIGH", 1780, FieldType.FLOAT); public static final Field STEP1RPMWINDOW = Field.create("STEP1RPMWINDOW", 1784, FieldType.INT); @@ -2073,10 +2096,6 @@ public class Fields { public static final Field ETB_ITERMMIN = Field.create("ETB_ITERMMIN", 3956, FieldType.INT16); public static final Field ETB_ITERMMAX = Field.create("ETB_ITERMMAX", 3958, FieldType.INT16); public static final Field ETBDEADBAND = Field.create("ETBDEADBAND", 3960, FieldType.FLOAT); - public static final Field ETB2_DIRECTIONPIN1 = Field.create("ETB2_DIRECTIONPIN1", 3964, FieldType.INT8, brain_pin_e); - public static final Field ETB2_DIRECTIONPIN2 = Field.create("ETB2_DIRECTIONPIN2", 3965, FieldType.INT8, brain_pin_e); - public static final Field ETB2_CONTROLPIN1 = Field.create("ETB2_CONTROLPIN1", 3966, FieldType.INT8, brain_pin_e); - public static final Field ETB2_CONTROLPINMODE = Field.create("ETB2_CONTROLPINMODE", 3967, FieldType.INT8, pin_output_mode_e); public static final Field IDLETIMINGPID_PFACTOR = Field.create("IDLETIMINGPID_PFACTOR", 3968, FieldType.FLOAT); public static final Field IDLETIMINGPID_IFACTOR = Field.create("IDLETIMINGPID_IFACTOR", 3972, FieldType.FLOAT); public static final Field IDLETIMINGPID_DFACTOR = Field.create("IDLETIMINGPID_DFACTOR", 3976, FieldType.FLOAT); @@ -2097,6 +2116,10 @@ public class Fields { public static final Field IDLERPMPID_ITERMMAX = Field.create("IDLERPMPID_ITERMMAX", 4006, FieldType.INT16); public static final Field MC33972SPIDEVICE = Field.create("MC33972SPIDEVICE", 4008, FieldType.INT8); public static final Field ETBIDLETHROTTLERANGE = Field.create("ETBIDLETHROTTLERANGE", 4012, FieldType.FLOAT); + public static final Field TRIGGERCOMPCENTERVOLT = Field.create("TRIGGERCOMPCENTERVOLT", 4036, FieldType.INT8); + public static final Field TRIGGERCOMPHYSTMIN = Field.create("TRIGGERCOMPHYSTMIN", 4037, FieldType.INT8); + public static final Field TRIGGERCOMPHYSTMAX = Field.create("TRIGGERCOMPHYSTMAX", 4038, FieldType.INT8); + public static final Field TRIGGERCOMPSENSORSATRPM = Field.create("TRIGGERCOMPSENSORSATRPM", 4039, FieldType.INT8); public static final Field IDLERPMPID2_PFACTOR = Field.create("IDLERPMPID2_PFACTOR", 4040, FieldType.FLOAT); public static final Field IDLERPMPID2_IFACTOR = Field.create("IDLERPMPID2_IFACTOR", 4044, FieldType.FLOAT); public static final Field IDLERPMPID2_DFACTOR = Field.create("IDLERPMPID2_DFACTOR", 4048, FieldType.FLOAT); @@ -2151,8 +2174,8 @@ public class Fields { USEBIQUADANALOGFILTERING, CJ125ISUADIVIDED, CJ125ISLSU49, - ETB1_USE_TWO_WIRES, - ETB2_USE_TWO_WIRES, + ETB_USE_TWO_WIRES, + UNUSEDHEREO_WIRES, SHOWSDCARDWARNING, CJ125ISURDIVIDED, USETLE8888_HALL_MODE, @@ -2333,10 +2356,7 @@ public class Fields { DIGITALPOTENTIOMETERSPIDEVICE, MC33972_CS, MC33972_CSPINMODE, - ETB1_DIRECTIONPIN1, - ETB1_DIRECTIONPIN2, - ETB1_CONTROLPIN1, - ETB1_CONTROLPINMODE, + AUXFASTSENSOR1_ADCCHANNEL, FUELLEVELEMPTYTANKVOLTAGE, FUELLEVELFULLTANKVOLTAGE, AFR_TYPE, @@ -2450,7 +2470,9 @@ public class Fields { MAX31855_CS8, SDCARDPERIODMS, DEBUGSETTIMER, - UNUSEDSPIPADDING2, + DEBUGMAPAVERAGING, + STARTERRELAYPIN, + STARTERRELAYPINMODE, MAPMINBUFFERLENGTH, IDLEPIDDEACTIVATIONTPSTHRESHOLD, STEPPERPARKINGEXTRASTEPS, @@ -2530,9 +2552,17 @@ public class Fields { CLUTCHUPPIN, FREQUENCYREPORTINGMAPINPUTPIN, CLUTCHUPPINMODE, - ETBIDLERANGE, - CLUTCHUPPININVERTED, - CLUTCHDOWNPININVERTED, + UNUSED, + TODOCLUTCHUPPININVERTED, + TODOCLUTCHDOWNPININVERTED, + ETBIO1_DIRECTIONPIN1, + ETBIO1_DIRECTIONPIN2, + ETBIO1_CONTROLPIN1, + ETBIO1_CONTROLPINMODE, + ETBIO2_DIRECTIONPIN1, + ETBIO2_DIRECTIONPIN2, + ETBIO2_CONTROLPIN1, + ETBIO2_CONTROLPINMODE, VVTDISPLAYINVERTED, FUELCLOSEDLOOPCORRECTIONENABLED, ISVERBOSEIAC, @@ -2591,7 +2621,7 @@ public class Fields { USEADVANCECORRECTIONSFORCRANKING, USETPSADVANCETABLE, ETBCALIBRATIONONSTART, - UNUSED_1484_BIT_21, + USEIACPIDMULTTABLE, UNUSED_1484_BIT_22, UNUSED_1484_BIT_23, UNUSED_1484_BIT_24, @@ -2654,6 +2684,8 @@ public class Fields { FUELRAILPRESSURE, ALTERNATOR_DERIVATIVEFILTERLOSS, ALTERNATOR_ANTIWINDUPFREQ, + TPS2MIN, + TPS2MAX, MAPERRORDETECTIONTOOLOW, MAPERRORDETECTIONTOOHIGH, STEP1RPMWINDOW, @@ -2865,10 +2897,6 @@ public class Fields { ETB_ITERMMIN, ETB_ITERMMAX, ETBDEADBAND, - ETB2_DIRECTIONPIN1, - ETB2_DIRECTIONPIN2, - ETB2_CONTROLPIN1, - ETB2_CONTROLPINMODE, IDLETIMINGPID_PFACTOR, IDLETIMINGPID_IFACTOR, IDLETIMINGPID_DFACTOR, @@ -2889,6 +2917,10 @@ public class Fields { IDLERPMPID_ITERMMAX, MC33972SPIDEVICE, ETBIDLETHROTTLERANGE, + TRIGGERCOMPCENTERVOLT, + TRIGGERCOMPHYSTMIN, + TRIGGERCOMPHYSTMAX, + TRIGGERCOMPSENSORSATRPM, IDLERPMPID2_PFACTOR, IDLERPMPID2_IFACTOR, IDLERPMPID2_DFACTOR, diff --git a/java_console/models/src/com/rusefi/test/ParserTest.java b/java_console/models/src/com/rusefi/test/ReversePolishNotationParserTest.java similarity index 99% rename from java_console/models/src/com/rusefi/test/ParserTest.java rename to java_console/models/src/com/rusefi/test/ReversePolishNotationParserTest.java index 74be6244d7..d2b6653cc5 100644 --- a/java_console/models/src/com/rusefi/test/ParserTest.java +++ b/java_console/models/src/com/rusefi/test/ReversePolishNotationParserTest.java @@ -14,7 +14,7 @@ import static org.junit.Assert.fail; * @see DoubleEvaluator * @see Operator */ -public class ParserTest { +public class ReversePolishNotationParserTest { @Test public void testFunctionParameters() { assertParseB("3 log", "log(3)"); diff --git a/java_console/models/src/com/rusefi/tracing/Entry.java b/java_console/models/src/com/rusefi/tracing/Entry.java new file mode 100644 index 0000000000..535f71a211 --- /dev/null +++ b/java_console/models/src/com/rusefi/tracing/Entry.java @@ -0,0 +1,132 @@ +package com.rusefi.tracing; + +import java.io.ByteArrayInputStream; +import java.io.DataInputStream; +import java.io.EOFException; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +import static com.rusefi.tracing.EnumNames.TypeNames; + +public class Entry { + // todo: maybe convert on firmware side so that CPU MHz are not accounted for on the java side? + private static final double MAGIC_NT = 168.0; + private final String name; + private final Phase phase; + private double timestampSeconds; + + public Entry(String name, Phase phase, double timestampSeconds) { + this.name = name; + this.phase = phase; + this.timestampSeconds = timestampSeconds; + } + + private static void AppendKeyValuePair(StringBuilder sb, String x, String y) { + sb.append('"'); + sb.append(x); + sb.append("\":\""); + sb.append(y); + sb.append('"'); + } + + private static void AppendKeyValuePair(StringBuilder sb, String x, int y) { + sb.append('"'); + sb.append(x); + sb.append("\":"); + sb.append(y); + } + + private static void AppendKeyValuePair(StringBuilder sb, String x, double y) { + sb.append('"'); + sb.append(x); + sb.append("\":"); + sb.append(y); + } + + public static int readInt(DataInputStream in) throws IOException { + int ch1 = in.read(); + int ch2 = in.read(); + int ch3 = in.read(); + int ch4 = in.read(); + if ((ch1 | ch2 | ch3 | ch4) < 0) + throw new EOFException(); + return ((ch4 << 24) + (ch3 << 16) + (ch2 << 8) + (ch1 << 0)); + } + + + public static List parseBuffer(byte[] packet) { + List result = new ArrayList<>(); + double minValue = Double.MAX_VALUE; + try { + DataInputStream is = new DataInputStream(new ByteArrayInputStream(packet)); + is.readByte(); // skip TS result code + int firstTimeStamp = 0; + for (int i = 0; i < packet.length - 1; i += 8) { + byte type = is.readByte(); + byte phase = is.readByte(); + byte data = is.readByte(); + byte thread = is.readByte(); + + int timestampNt = readInt(is); + if (i == 0) { + firstTimeStamp = timestampNt; + } else { + if (timestampNt < firstTimeStamp) { + System.out.println("Dropping the remainder of the packet at " + i + " due to " + + timestampNt + " below " + firstTimeStamp); + break; + } + } + + + double timestampSeconds = timestampNt / MAGIC_NT; + minValue = Math.min(minValue, timestampSeconds); + String name; + if (type == 1) { + name = "ISR: " + thread; + } + else + { + name = TypeNames[type]; + } + + Entry e = new Entry(name, Phase.decode(phase), timestampSeconds); + result.add(e); + } + + for (Entry e : result) + e.adjustTimestamp(minValue); + + + } catch (IOException e) { + throw new IllegalStateException(e); + } + return result; + } + + private void adjustTimestamp(double minValue) { + timestampSeconds -= minValue; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + + sb.append("{"); + AppendKeyValuePair(sb, "name", name); + + sb.append(","); + AppendKeyValuePair(sb, "ph", phase.toString()); + sb.append(","); + AppendKeyValuePair(sb, "tid", 0); + sb.append(","); + + AppendKeyValuePair(sb, "pid", 0); + sb.append(","); + AppendKeyValuePair(sb, "ts", timestampSeconds); + sb.append("}"); + + return sb.toString(); + } +} diff --git a/java_console/models/src/com/rusefi/tracing/EnumNames.java b/java_console/models/src/com/rusefi/tracing/EnumNames.java new file mode 100644 index 0000000000..7d7ce009e9 --- /dev/null +++ b/java_console/models/src/com/rusefi/tracing/EnumNames.java @@ -0,0 +1,45 @@ +package com.rusefi.tracing; + +public class EnumNames { + public static final String[] TypeNames = { + "INVALID", + "ISR", + "ContextSwitch", + "OutputPinSetValue", + "DecodeTriggerEvent", + "EnginePeriodicFastCallback", + "EnginePeriodicSlowCallback", + "EngineStatePeriodicFastCallback", + "HandleShaftSignal", + "EventQueueInsertTask", + "EventQueueExecuteAll", + "SingleTimerExecutorDoExecute", + "SingleTimerExecutorScheduleTimerCallback", + "PeriodicControllerPeriodicTask", + "PeriodicTimerControllerPeriodicTask", + "AdcCallbackFast", + "AdcCallbackSlow", + "AdcConversionSlow", + "AdcConversionFast", + "AdcSubscriptionUpdateSubscribers", + "GetRunningFuel", + "GetInjectionDuration", + "HandleFuel", + "MainTriggerCallback", + "OnTriggerEventSparkLogic", + "ShaftPositionListeners", + "GetBaseFuel", + "GetTpsEnrichment", + "GetSpeedDensityFuel", + "WallFuelAdjust", + "MapAveragingTriggerCallback", + "AdcCallbackFastComplete", + "SingleTimerExecutorScheduleByTimestamp", + "ScheduleByAngle", + "EventQueueExecuteCallback", + "PwmGeneratorCallback", + "TunerStudioHandleCrcCommand", + "PwmConfigTogglePwmState", + "PwmConfigStateChangeCallback", + }; +} diff --git a/java_console/models/src/com/rusefi/tracing/JsonOutput.java b/java_console/models/src/com/rusefi/tracing/JsonOutput.java new file mode 100644 index 0000000000..1858a9b9ad --- /dev/null +++ b/java_console/models/src/com/rusefi/tracing/JsonOutput.java @@ -0,0 +1,66 @@ +package com.rusefi.tracing; + +import java.io.*; +import java.util.Arrays; +import java.util.List; + +/** + * This class helps to write JSON files readable by chrome://tracing/ + *

+ * See https://github.com/catapult-project/catapult/blob/master/tracing/README.md + * @see PerfTraceTool + */ +public class JsonOutput { + + /** + * those are special entries that change display settings + * those set thread names and sort index based on those thread IDs + * (those thread IDs are interrupt numbers, and the name is the name of the interrupt handler) + */ + private static final String FORMATTING_SETTINGS + = "{\"name\":\"thread_name\",\"ph\":\"M\",\"tid\":18,\"pid\":0,\"args\":{\"name\":\"ADC\"}}," + + "{\"name\":\"thread_name\",\"ph\":\"M\",\"tid\":29,\"pid\":0,\"args\":{\"name\":\"TIM3\"}}," + + "{\"name\":\"thread_name\",\"ph\":\"M\",\"tid\":30,\"pid\":0,\"args\":{\"name\":\"TIM4\"}}," + + "{\"name\":\"thread_name\",\"ph\":\"M\",\"tid\":44,\"pid\":0,\"args\":{\"name\":\"TIM8/13\"}}," + + "{\"name\":\"thread_name\",\"ph\":\"M\",\"tid\":50,\"pid\":0,\"args\":{\"name\":\"TIM5\"}}," + + "{\"name\":\"thread_name\",\"ph\":\"M\",\"tid\":58,\"pid\":0,\"args\":{\"name\":\"DMA2s2\"}}," + + "{\"name\":\"thread_name\",\"ph\":\"M\",\"tid\":60,\"pid\":0,\"args\":{\"name\":\"DMA2s4\"}}," + + "{\"name\":\"thread_name\",\"ph\":\"M\",\"tid\":67,\"pid\":0,\"args\":{\"name\":\"USB\"}}," + + "{\"name\":\"thread_sort_index\",\"ph\":\"M\",\"tid\":18,\"pid\":0,\"args\":{\"sort_index\":4}}," + + "{\"name\":\"thread_sort_index\",\"ph\":\"M\",\"tid\":29,\"pid\":0,\"args\":{\"sort_index\":2}}," + + "{\"name\":\"thread_sort_index\",\"ph\":\"M\",\"tid\":30,\"pid\":0,\"args\":{\"sort_index\":5}}," + + "{\"name\":\"thread_sort_index\",\"ph\":\"M\",\"tid\":44,\"pid\":0,\"args\":{\"sort_index\":7}}," + + "{\"name\":\"thread_sort_index\",\"ph\":\"M\",\"tid\":50,\"pid\":0,\"args\":{\"sort_index\":3}}," + + "{\"name\":\"thread_sort_index\",\"ph\":\"M\",\"tid\":58,\"pid\":0,\"args\":{\"sort_index\":6}}," + + "{\"name\":\"thread_sort_index\",\"ph\":\"M\",\"tid\":60,\"pid\":0,\"args\":{\"sort_index\":8}}," + + "{\"name\":\"thread_sort_index\",\"ph\":\"M\",\"tid\":67,\"pid\":0,\"args\":{\"sort_index\":9}}" + ; + private static final String EOL = "\r\n"; + + public static void main(String[] args) throws IOException { + List testEntries = Arrays.asList( + new Entry("hello", Phase.B, 0.1), + new Entry("hello2", Phase.B, 0.2), + new Entry("hello2", Phase.E, 0.3), + new Entry("hello", Phase.E, 0.4) + ); + + writeToStream(testEntries, new FileOutputStream("hello_trace.json")); + } + + public static void writeToStream(List testEntries, OutputStream outputStream) throws IOException { + + Writer out = new OutputStreamWriter(outputStream); + out.write("{\"traceEvents\": [" + EOL); + + out.write(FORMATTING_SETTINGS + EOL); + + for (Entry e : testEntries) { + out.write(","); + out.write(e.toString() + EOL); + } + + out.write("]}"); + out.close(); + } +} diff --git a/java_console/models/src/com/rusefi/tracing/Phase.java b/java_console/models/src/com/rusefi/tracing/Phase.java new file mode 100644 index 0000000000..e98febf992 --- /dev/null +++ b/java_console/models/src/com/rusefi/tracing/Phase.java @@ -0,0 +1,24 @@ +package com.rusefi.tracing; + +public enum Phase { + // Begin + B, + // End + E, + i, + ; + + public static Phase decode(byte phase) { + switch (phase) { + case 0: + return B; + case 1: + return E; + case 2: + case 3: + return i; + default: + throw new IllegalStateException("Unexpected " + phase); + } + } +} diff --git a/java_console/models/src/com/rusefi/tracing/test/EntryTest.java b/java_console/models/src/com/rusefi/tracing/test/EntryTest.java new file mode 100644 index 0000000000..9f826f1343 --- /dev/null +++ b/java_console/models/src/com/rusefi/tracing/test/EntryTest.java @@ -0,0 +1,17 @@ +package com.rusefi.tracing.test; + +import com.rusefi.tracing.Entry; +import com.rusefi.tracing.Phase; +import org.junit.Test; + +import static org.junit.Assert.assertEquals; + +public class EntryTest { + @Test + public void testToString() { + Entry e = new Entry("hello", Phase.E, 0.1); + + assertEquals("{\"name\":\"hello\",\"ph\":\"E\",\"tid\":0,\"pid\":0,\"ts\":0.1}", e.toString()); + + } +} diff --git a/java_console/ui/src/com/rusefi/BenchTestPane.java b/java_console/ui/src/com/rusefi/BenchTestPane.java index 66180e53d1..325c0eba5b 100644 --- a/java_console/ui/src/com/rusefi/BenchTestPane.java +++ b/java_console/ui/src/com/rusefi/BenchTestPane.java @@ -1,13 +1,26 @@ package com.rusefi; +import com.rusefi.binaryprotocol.BinaryProtocol; +import com.rusefi.binaryprotocol.BinaryProtocolHolder; import com.rusefi.config.generated.Fields; +import com.rusefi.tracing.Entry; +import com.rusefi.tracing.JsonOutput; import com.rusefi.ui.MessagesView; +import com.rusefi.ui.RpmModel; +import com.rusefi.ui.util.UiUtils; import org.jetbrains.annotations.NotNull; import javax.swing.*; import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.io.FileOutputStream; +import java.io.IOException; +import java.util.List; import static com.rusefi.CommandControl.TEST; +import static com.rusefi.binaryprotocol.BinaryProtocolCommands.RESPONSE_OK; +import static com.rusefi.binaryprotocol.IoHelper.checkResponseCode; public class BenchTestPane { private final JPanel content = new JPanel(new GridLayout(2, 5)); @@ -15,6 +28,7 @@ public class BenchTestPane { public BenchTestPane() { content.setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20)); + content.add(grabPerformanceTrace()); content.add(createFanTest()); content.add(createAcRelayTest()); content.add(createFuelPumpTest()); @@ -38,6 +52,36 @@ public class BenchTestPane { content.add(new MessagesView().messagesScroll); } + private Component grabPerformanceTrace() { + JButton button = new JButton("Grab PTrace"); + button.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + BinaryProtocol bp = BinaryProtocolHolder.INSTANCE.get(); + bp.executeCommand(new byte[]{'r'}, "begin trace", false); + + try { + Thread.sleep(500); + + byte[] packet = bp.executeCommand(new byte[]{'b'}, "get trace", true); + if (!checkResponseCode(packet, RESPONSE_OK) || ((packet.length - 1) % 8) != 0) + throw new IllegalStateException("Unexpected packet"); + + List data = Entry.parseBuffer(packet); + + int rpm = RpmModel.getInstance().getValue(); + String fileName = FileLog.getDate() + "_rpm_" + rpm + "_rusEfi_trace" + ".json"; + + + JsonOutput.writeToStream(data, new FileOutputStream(fileName)); + } catch (IOException | InterruptedException e1) { + throw new IllegalStateException(e1); + } + } + }); + return UiUtils.wrap(button); + } + private Component createMILTest() { CommandControl panel = new CommandControl("MIL", "check_engine.jpg", TEST) { @NotNull diff --git a/java_console/ui/src/com/rusefi/Launcher.java b/java_console/ui/src/com/rusefi/Launcher.java index 28bcf4aff5..f15db788ad 100644 --- a/java_console/ui/src/com/rusefi/Launcher.java +++ b/java_console/ui/src/com/rusefi/Launcher.java @@ -29,6 +29,7 @@ import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; import java.awt.*; import java.awt.event.ActionListener; +import java.io.IOException; import java.util.Arrays; import java.util.HashMap; import java.util.Map; @@ -48,17 +49,21 @@ import static com.rusefi.ui.storage.PersistentConfiguration.getConfig; * @see EngineSnifferPanel */ public class Launcher { - public static final int CONSOLE_VERSION = 20191105; + public static final int CONSOLE_VERSION = 20191201; public static final String INI_FILE_PATH = System.getProperty("ini_file_path", ".."); public static final String INPUT_FILES_PATH = System.getProperty("input_files_path", ".."); public static final String TOOLS_PATH = System.getProperty("tools_path", "."); private static final String TAB_INDEX = "main_tab"; protected static final String PORT_KEY = "port"; protected static final String SPEED_KEY = "speed"; + private static final String TOOL_NAME_COMPILE_FSIO_FILE = "compile_fsio_file"; private static final String TOOL_NAME_REBOOT_ECU = "reboot_ecu"; + private static final String TOOL_NAME_FIRING_ORDER = "firing_order"; + private static final String TOOL_NAME_PERF_ENUMS = "ptrace_enums"; // todo: rename to something more FSIO-specific? would need to update documentation somewhere private static final String TOOL_NAME_COMPILE = "compile"; + private final String port; // todo: the logic around 'fatalError' could be implemented nicer private String fatalError; @@ -316,43 +321,37 @@ public class Launcher { */ public static void main(final String[] args) throws Exception { String toolName = args.length == 0 ? null : args[0]; + if (TOOL_NAME_COMPILE_FSIO_FILE.equalsIgnoreCase(toolName)) { - /** - * re-packaging array which contains input and output file names - */ - int returnCode = CompileTool.run(Arrays.asList(args).subList(1, args.length)); + int returnCode = invokeCompileFileTool(args); System.exit(returnCode); - return; } if (TOOL_NAME_COMPILE.equals(toolName)) { - if (args.length != 2) { - System.err.println("input expression parameter expected"); - System.exit(-1); - return; - } - String input = args[1]; - System.out.println(DoubleEvaluator.process(input).getPosftfixExpression()); + invokeCompileExpressionTool(args); System.exit(0); } - System.out.println("Optional tools: " + Arrays.asList(TOOL_NAME_COMPILE_FSIO_FILE, TOOL_NAME_COMPILE, TOOL_NAME_REBOOT_ECU)); + + if (TOOL_NAME_FIRING_ORDER.equals(toolName)) { + FiringOrderTSLogic.invoke(args[1]); + System.exit(0); + } + + if (TOOL_NAME_PERF_ENUMS.equals(toolName)) { + PerfTraceTool.readPerfTrace(args[1], args[2], args[3], args[4]); + System.exit(0); + } + + System.out.println("Optional tools: " + Arrays.asList(TOOL_NAME_COMPILE_FSIO_FILE, + TOOL_NAME_COMPILE, + TOOL_NAME_REBOOT_ECU, + TOOL_NAME_FIRING_ORDER)); System.out.println("Starting rusEfi UI console " + CONSOLE_VERSION); FileLog.MAIN.start(); if (TOOL_NAME_REBOOT_ECU.equalsIgnoreCase(toolName)) { - String autoDetectedPort = PortDetector.autoDetectPort(null); - if (autoDetectedPort == null) { - System.err.println("rusEfi not detected"); - return; - } - PortHolder.EstablishConnection establishConnection = new PortHolder.EstablishConnection(autoDetectedPort).invoke(); - if (!establishConnection.isConnected()) - return; - IoStream stream = establishConnection.getStream(); - byte[] commandBytes = BinaryProtocol.getTextCommandBytes(Fields.CMD_REBOOT); - stream.sendPacket(commandBytes, FileLog.LOGGER); - + invokeRebootTool(); return; } @@ -368,6 +367,36 @@ public class Launcher { }); } + private static int invokeCompileFileTool(String[] args) throws IOException { + /** + * re-packaging array which contains input and output file names + */ + return CompileTool.run(Arrays.asList(args).subList(1, args.length)); + } + + private static void invokeRebootTool() throws IOException { + String autoDetectedPort = PortDetector.autoDetectPort(null); + if (autoDetectedPort == null) { + System.err.println("rusEfi not detected"); + return; + } + PortHolder.EstablishConnection establishConnection = new PortHolder.EstablishConnection(autoDetectedPort).invoke(); + if (!establishConnection.isConnected()) + return; + IoStream stream = establishConnection.getStream(); + byte[] commandBytes = BinaryProtocol.getTextCommandBytes(Fields.CMD_REBOOT); + stream.sendPacket(commandBytes, FileLog.LOGGER); + } + + private static void invokeCompileExpressionTool(String[] args) { + if (args.length != 2) { + System.err.println("input expression parameter expected"); + System.exit(-1); + } + String expression = args[1]; + System.out.println(DoubleEvaluator.process(expression).getPosftfixExpression()); + } + private static void awtCode(String[] args) { if (JustOneInstance.isAlreadyRunning()) { int result = JOptionPane.showConfirmDialog(null, "Looks like another instance is already running. Do you really want to start another instance?", diff --git a/java_console/ui/src/com/rusefi/PresetsPane.java b/java_console/ui/src/com/rusefi/PresetsPane.java index 69899b994c..5d583410ec 100644 --- a/java_console/ui/src/com/rusefi/PresetsPane.java +++ b/java_console/ui/src/com/rusefi/PresetsPane.java @@ -1,5 +1,6 @@ package com.rusefi; +import com.rusefi.config.generated.Fields; import com.rusefi.io.CommandQueue; import org.jetbrains.annotations.NotNull; @@ -40,7 +41,7 @@ public class PresetsPane { private final String labelTest; public SetEngineTypeCommandControl(String labelTest, String imageFileName, int engineType) { - super(labelTest, imageFileName, CommandControl.SET, "set engine_type " + engineType); + super(labelTest, imageFileName, CommandControl.SET, "set " + Fields.CMD_ENGINE_TYPE + " " + engineType); this.labelTest = labelTest; } diff --git a/java_console/ui/src/com/rusefi/ui/GaugesPanel.java b/java_console/ui/src/com/rusefi/ui/GaugesPanel.java index 61adf3cb8a..1ee27430aa 100644 --- a/java_console/ui/src/com/rusefi/ui/GaugesPanel.java +++ b/java_console/ui/src/com/rusefi/ui/GaugesPanel.java @@ -244,7 +244,9 @@ public class GaugesPanel { gauges.setLayout(rows, columns); for (int i = 0; i < rows * columns; i++) { - Component element = GaugesGridElement.read(config.getChild("element_" + i), DEFAULT_LAYOUT[i]); + // sometimes grid is quite large so we shall be careful with default sensor index + Sensor defaultSensor = DEFAULT_LAYOUT[Math.min(i, DEFAULT_LAYOUT.length - 1)]; + Component element = GaugesGridElement.read(config.getChild("element_" + i), defaultSensor); gauges.panel.add(element); } diff --git a/java_console/ui/src/com/rusefi/ui/storage/Node.java b/java_console/ui/src/com/rusefi/ui/storage/Node.java index 64eaeb1de2..2c8a9a7512 100644 --- a/java_console/ui/src/com/rusefi/ui/storage/Node.java +++ b/java_console/ui/src/com/rusefi/ui/storage/Node.java @@ -36,6 +36,7 @@ public class Node { return true; } + @NotNull public Node getChild(String name) { Node child = (Node) config.get(name); if (child == null) { diff --git a/misc/jenkins/compile_other_versions/prepare_bundle.bat b/misc/jenkins/compile_other_versions/prepare_bundle.bat index c6fee5afe0..621ac9211b 100644 --- a/misc/jenkins/compile_other_versions/prepare_bundle.bat +++ b/misc/jenkins/compile_other_versions/prepare_bundle.bat @@ -1,5 +1,6 @@ set script_name=build_version.bat echo Entering %script_name% with %bundle_name% +echo "RUSEFI_BUILD_FTP_USER=%RUSEFI_BUILD_FTP_USER%" if %RUSEFI_BUILD_FTP_USER%.==. ( echo RUSEFI_BUILD_FTP_USER not set - not packaging @@ -18,8 +19,6 @@ set folder=temp\%folder% echo Packaging temp\rusefi_bundle.zip file call misc\jenkins\build_working_folder.bat -rem TODO: extract FTP duplication with 407 build - cd temp set bundle_file=rusefi_bundle_%bundle_name%.zip mv rusefi_bundle.zip %bundle_file% diff --git a/misc/jenkins/compile_other_versions/run.bat b/misc/jenkins/compile_other_versions/run.bat index d0fc64e535..5aa0c82a1a 100644 --- a/misc/jenkins/compile_other_versions/run.bat +++ b/misc/jenkins/compile_other_versions/run.bat @@ -1,5 +1,6 @@ set script_name=run.bat echo Entering %script_name% +echo "RUSEFI_BUILD_FTP_USER=%RUSEFI_BUILD_FTP_USER%" pwd @@ -9,6 +10,10 @@ if not exist java_console_binary/rusefi_console.jar exit -1 call misc\jenkins\build_simulator.bat if not exist simulator/build/rusefi_simulator.exe exit -1 +call misc\jenkins\compile_other_versions\compile_and_upload.bat kinetis kinetis +IF NOT ERRORLEVEL 0 echo ERROR invoking compile_and_upload.bat +IF NOT ERRORLEVEL 0 EXIT /B 1 + call misc\jenkins\compile_other_versions\compile_and_upload.bat frankenso frankenso_na6 IF NOT ERRORLEVEL 0 echo ERROR invoking compile_and_upload.bat IF NOT ERRORLEVEL 0 EXIT /B 1 diff --git a/simulator/Makefile b/simulator/Makefile index b221a477a8..50a11c8764 100644 --- a/simulator/Makefile +++ b/simulator/Makefile @@ -18,6 +18,8 @@ RULESPATH = $(CHIBIOS)/os/common/startup/SIMIA32/compilers/GCC RULESFILE = $(RULESPATH)/rules.mk include ../firmware/rusefi.mk +RULESFILE = ../firmware/rusefi_rules.mk + # Compiler options here. @@ -28,7 +30,7 @@ ifeq ($(USE_OPT),) # this config producec a smaller binary file # 7.3 compiler would want -Wno-error=implicit-fallthrough while 6.4 does not know about it # see https://github.com/rusefi/rusefi/issues/517 - USE_OPT = -Wall -O2 -Wno-error=implicit-fallthrough -Werror-implicit-function-declaration -Werror -Wno-error=pointer-sign -Wno-error=unused-function -Wno-error=unused-variable -Wno-error=sign-compare -Wno-error=unused-parameter -Werror=missing-field-initializers -Wno-error=write-strings -Wno-error=strict-aliasing + USE_OPT = -Wall -O2 -Wno-error=implicit-fallthrough -Wno-error=write-strings -Wno-error=strict-aliasing ifeq ($(OS),Windows_NT) else @@ -36,6 +38,8 @@ ifeq ($(USE_OPT),) endif endif +USE_OPT += $(RUSEFI_OPT) + ifeq ($(CCACHE_DIR),) $(info No CCACHE_DIR) else @@ -121,12 +125,6 @@ include $(PROJECT_DIR)/console/binary/tunerstudio.mk include $(PROJECT_DIR)/console/console.mk include $(PROJECT_DIR)/config/engines/engines.mk include $(PROJECT_DIR)/controllers/controllers.mk -include $(PROJECT_DIR)/controllers/algo/algo.mk -include $(PROJECT_DIR)/controllers/core/core.mk -include $(PROJECT_DIR)/controllers/math/math.mk -include $(PROJECT_DIR)/controllers/sensors/sensors.mk -include $(PROJECT_DIR)/controllers/trigger/trigger.mk -include $(PROJECT_DIR)/controllers/system/system.mk include $(PROJECT_DIR)/development/development.mk include $(PROJECT_DIR)/hw_layer/hw_layer.mk include $(PROJECT_DIR)/hw_layer/sensors/sensors.mk @@ -160,7 +158,7 @@ CPPSRC = $(UTILSRC_CPP) \ $(PROJECT_DIR)/development/sensor_chart.cpp \ $(PROJECT_DIR)/development/trigger_emulator.cpp \ $(HW_LAYER_EMS_CPP) \ - $(PROJECT_DIR)/hw_layer/sensors/cj125.cpp \ + $(HW_SENSORS_SRC) \ $(TRIGGER_SRC_CPP) \ $(TRIGGER_DECODERS_SRC_CPP) \ $(SYSTEMSRC_CPP) \ @@ -196,15 +194,12 @@ INCDIR = . \ $(PROJECT_DIR)/console/fl_binary \ $(PROJECT_DIR)/config/engines \ $(PROJECT_DIR)/ext_algo \ - $(PROJECT_DIR)/controllers \ - $(HW_LAYER_DRIVERS_INC) \ + $(HW_LAYER_DRIVERS_INC) \ $(PROJECT_DIR)/hw_layer \ $(PROJECT_DIR)/hw_layer/algo \ $(HW_SENSORS_INC) \ - $(CONTROLLERS_INC) \ $(DEVELOPMENT_DIR) \ - $(PROJECT_DIR)/controllers/sensors \ - $(PROJECT_DIR)/controllers/sensors/converters \ + $(CONTROLLERS_INC) \ ${CHIBIOS}/os/various \ $(CHIBIOS)/os/hal/lib/streams \ simulator diff --git a/simulator/simulator/efifeatures.h b/simulator/simulator/efifeatures.h index fe40bc75ec..94f57ab33d 100644 --- a/simulator/simulator/efifeatures.h +++ b/simulator/simulator/efifeatures.h @@ -87,7 +87,7 @@ #define EFI_ENGINE_CONTROL TRUE #define EFI_IDLE_CONTROL TRUE -#define EFI_IDLE_INCREMENTAL_PID_CIC FALSE +#define EFI_IDLE_PID_CIC FALSE #define EFI_MAIN_RELAY_CONTROL FALSE #define EFI_HIP_9011 TRUE #define EFI_CJ125 FALSE @@ -122,7 +122,7 @@ #define EFI_RTC FALSE #define EFI_MALFUNCTION_INDICATOR FALSE #define EFI_HD44780_LCD FALSE -#define EFI_WAVE_ANALYZER FALSE +#define EFI_LOGIC_ANALYZER FALSE #define EFI_PWM_TESTER FALSE #define TRIGGER_EXTREME_LOGGING FALSE #define SPARK_EXTREME_LOGGING FALSE diff --git a/unit_tests/Makefile b/unit_tests/Makefile index 96b9d5b552..54857e6cf7 100644 --- a/unit_tests/Makefile +++ b/unit_tests/Makefile @@ -14,6 +14,7 @@ endif PROJECT_DIR = ../firmware +include $(PROJECT_DIR)/rusefi_rules.mk # Compiler options here. ifeq ($(USE_OPT),) @@ -27,6 +28,11 @@ ifeq ($(USE_OPT),) USE_OPT += -Werror=missing-field-initializers endif + +#TODO! this is a nice goal +#USE_OPT += $(RUSEFI_OPT) +#USE_OPT += -Wno-error=format= -Wno-error=register -Wno-error=write-strings + ifeq ($(CCACHE_DIR),) $(info No CCACHE_DIR) else @@ -91,12 +97,6 @@ PROJECT = rusefi_test # Imported source files and paths include $(PROJECT_DIR)/config/engines/engines.mk include $(PROJECT_DIR)/controllers/controllers.mk -include $(PROJECT_DIR)/controllers/algo/algo.mk -include $(PROJECT_DIR)/controllers/core/core.mk -include $(PROJECT_DIR)/controllers/math/math.mk -include $(PROJECT_DIR)/controllers/system/system.mk -include $(PROJECT_DIR)/controllers/sensors/sensors.mk -include $(PROJECT_DIR)/controllers/trigger/trigger.mk include $(PROJECT_DIR)/development/development.mk include $(PROJECT_DIR)/hw_layer/hw_layer.mk include $(PROJECT_DIR)/hw_layer/drivers/drivers.mk @@ -170,8 +170,6 @@ INCDIR = . \ $(PROJECT_DIR)/config/engines \ $(CONTROLLERS_INC) \ $(PROJECT_DIR)/console \ - $(PROJECT_DIR)/controllers/sensors \ - $(PROJECT_DIR)/controllers/sensors/converters \ $(DEVELOPMENT_DIR) \ $(PROJECT_DIR)/ext_algo \ $(PROJECT_DIR)/hw_layer \ diff --git a/unit_tests/afm2mapConverter.cpp b/unit_tests/afm2mapConverter.cpp index 5777326f63..8e87c20316 100644 --- a/unit_tests/afm2mapConverter.cpp +++ b/unit_tests/afm2mapConverter.cpp @@ -57,7 +57,7 @@ void printConvertedTable() { printf("\n"); - setLinearCurve(PSI_BINS, ASIZE, PSI2KPA(18), PSI2KPA(-14.5), 0.1); // we invert PSI scale since voltage is inverted below + setLinearCurve(PSI_BINS, PSI2KPA(18), PSI2KPA(-14.5f), 0.1f); // we invert PSI scale since voltage is inverted below for (int i = 0; i< ASIZE;i++) { printf("%f, ", PSI_BINS[i]); } diff --git a/unit_tests/boards.cpp b/unit_tests/boards.cpp index 5350c8e223..9ce0f88998 100644 --- a/unit_tests/boards.cpp +++ b/unit_tests/boards.cpp @@ -24,8 +24,9 @@ float getVoltageDivided(const char *msg, adc_channel_e hwChannel DECLARE_ENGINE_ case TEST_IAT_CHANNEL: return testIatValue; //return adcToVolts(engine->engineState.mockAdcState.getMockAdcValue(hwChannel)); + default: + return adcToVolts(engine->engineState.mockAdcState.getMockAdcValue(hwChannel));; } - return adcToVolts(engine->engineState.mockAdcState.getMockAdcValue(hwChannel));; } float getVoltage(const char *msg, adc_channel_e hwChannel DECLARE_ENGINE_PARAMETER_SUFFIX) { diff --git a/unit_tests/engine_test_helper.cpp b/unit_tests/engine_test_helper.cpp index 609655eaf7..ae3e57da27 100644 --- a/unit_tests/engine_test_helper.cpp +++ b/unit_tests/engine_test_helper.cpp @@ -75,7 +75,7 @@ EngineTestHelper::EngineTestHelper(engine_type_e engineType, configuration_callb //todo: reuse initPeriodicEvents(PASS_ENGINE_PARAMETER_SIGNATURE) method engine->periodicSlowCallback(PASS_ENGINE_PARAMETER_SIGNATURE); - engine->eInitializeTriggerShape(NULL PASS_ENGINE_PARAMETER_SUFFIX); + engine->initializeTriggerWaveform(NULL PASS_ENGINE_PARAMETER_SUFFIX); initRpmCalculator(NULL PASS_ENGINE_PARAMETER_SUFFIX); initMainEventListener(NULL PASS_ENGINE_PARAMETER_SUFFIX); } @@ -128,7 +128,6 @@ void EngineTestHelper::fireTriggerEvents2(int count, float durationMs) { void EngineTestHelper::clearQueue() { engine.executor.executeAll(99999999); // this is needed to clear 'isScheduled' flag ASSERT_EQ( 0, engine.executor.size()) << "Failed to clearQueue"; - engine.ignitionEventsHead = nullptr; // let's drop whatever was scheduled just to start from a clean state } int EngineTestHelper::executeActions() { @@ -163,29 +162,63 @@ void EngineTestHelper::assertInjectorDownEvent(const char *msg, int eventIndex, scheduling_s * EngineTestHelper::assertEvent5(const char *msg, int index, void *callback, efitime_t expectedTimestamp) { TestExecutor *executor = &engine.executor; - EXPECT_TRUE(executor->size() > index) << msg; + EXPECT_TRUE(executor->size() > index) << msg << " valid index"; scheduling_s *event = executor->getForUnitTest(index); - assertEqualsM4(msg, " up/down", (void*)event->callback == (void*) callback, 1); + assertEqualsM4(msg, " callback up/down", (void*)event->action.getCallback() == (void*) callback, 1); efitime_t start = getTimeNowUs(); - assertEqualsM(msg, expectedTimestamp, event->momentX - start); + assertEqualsM4(msg, " timestamp", expectedTimestamp, event->momentX - start); return event; } +// todo: reduce code duplication with another 'getElementAtIndexForUnitText' +static AngleBasedEvent * getElementAtIndexForUnitText(int index, Engine *engine) { + AngleBasedEvent * current; + + LL_FOREACH2(engine->angleBasedEventsHead, current, nextToothEvent) + { + if (index == 0) + return current; + index--; + } +#if EFI_UNIT_TEST + firmwareError(OBD_PCM_Processor_Fault, "getForUnitText: null"); +#endif /* EFI_UNIT_TEST */ + return NULL; +} + +AngleBasedEvent * EngineTestHelper::assertTriggerEvent(const char *msg, + int index, AngleBasedEvent *expected, + void *callback, + int triggerEventIndex, angle_t angleOffsetFromTriggerEvent) { + AngleBasedEvent * event = getElementAtIndexForUnitText(index, &engine); + + assertEqualsM4(msg, " callback up/down", (void*)event->action.getCallback() == (void*) callback, 1); + + assertEqualsM4(msg, " trigger", triggerEventIndex, event->position.triggerEventIndex); + assertEqualsM4(msg, " angle", angleOffsetFromTriggerEvent, event->position.angleOffsetFromTriggerEvent); + return event; +} + +scheduling_s * EngineTestHelper::assertScheduling(const char *msg, int index, scheduling_s *expected, void *callback, efitime_t expectedTimestamp) { + scheduling_s * actual = assertEvent5(msg, index, callback, expectedTimestamp); + return actual; +} + void EngineTestHelper::assertEvent(const char *msg, int index, void *callback, efitime_t momentX, InjectionEvent *expectedEvent) { scheduling_s *event = assertEvent5(msg, index, callback, momentX); - InjectionEvent *actualEvent = (InjectionEvent *)event->param; + InjectionEvent *actualEvent = (InjectionEvent *)event->action.getArgument(); - assertEqualsLM(msg, expectedEvent->outputs[0], (long)actualEvent->outputs[0]); + assertEqualsLM(msg, (long)expectedEvent->outputs[0], (long)actualEvent->outputs[0]); // but this would not work assertEqualsLM(msg, expectedPair, (long)eventPair); } -void EngineTestHelper::applyTriggerShape() { +void EngineTestHelper::applyTriggerWaveform() { Engine *engine = &this->engine; EXPAND_Engine - ENGINE(eInitializeTriggerShape(NULL PASS_ENGINE_PARAMETER_SUFFIX)); + ENGINE(initializeTriggerWaveform(NULL PASS_ENGINE_PARAMETER_SUFFIX)); incrementGlobalConfigurationVersion(PASS_ENGINE_PARAMETER_SIGNATURE); } @@ -212,8 +245,8 @@ void setupSimpleTestEngineWithMaf(EngineTestHelper *eth, injection_mode_e inject // set cranking mode (it's used by getCurrentInjectionMode()) engineConfiguration->crankingInjectionMode = IM_SIMULTANEOUS; - setArrayValues(config->cltFuelCorrBins, CLT_CURVE_SIZE, 1); - setArrayValues(engineConfiguration->injector.battLagCorr, VBAT_INJECTOR_CURVE_SIZE, 0); + setArrayValues(config->cltFuelCorrBins, 1.0f); + setArrayValues(engineConfiguration->injector.battLagCorr, 0.0f); // this is needed to update injectorLag engine->updateSlowSensors(PASS_ENGINE_PARAMETER_SIGNATURE); @@ -228,7 +261,7 @@ void EngineTestHelper::setTriggerType(trigger_type_e trigger DECLARE_ENGINE_PARA engineConfiguration->trigger.type = trigger; incrementGlobalConfigurationVersion(PASS_ENGINE_PARAMETER_SIGNATURE); ASSERT_EQ( 1, isTriggerConfigChanged(PASS_ENGINE_PARAMETER_SIGNATURE)) << "trigger #2"; - applyTriggerShape(); + applyTriggerWaveform(); } void setupSimpleTestEngineWithMafAndTT_ONE_trigger(EngineTestHelper *eth, injection_mode_e injectionMode) { diff --git a/unit_tests/engine_test_helper.h b/unit_tests/engine_test_helper.h index 265b660c18..7522aea166 100644 --- a/unit_tests/engine_test_helper.h +++ b/unit_tests/engine_test_helper.h @@ -2,10 +2,10 @@ * @file engine_test_helper.h * * @date Jun 26, 2014 - * @author Andrey Belomutskiy, (c) 2012-2014 + * @author Andrey Belomutskiy, (c) 2012-2019 */ -#ifndef ENGINE_TEST_HELPER_H_ -#define ENGINE_TEST_HELPER_H_ + +#pragma once #include "engine.h" #include "trigger_central.h" @@ -28,7 +28,7 @@ class EngineTestHelper : public EngineTestHelperBase { public: EngineTestHelper(engine_type_e engineType); EngineTestHelper(engine_type_e engineType, configuration_callback_t boardCallback); - void applyTriggerShape(); + void applyTriggerWaveform(); void setTriggerType(trigger_type_e trigger DECLARE_ENGINE_PARAMETER_SUFFIX); void fireRise(float delayMs); void fireFall(float delayMs); @@ -47,6 +47,10 @@ public: void clearQueue(); scheduling_s * assertEvent5(const char *msg, int index, void *callback, efitime_t expectedTimestamp); + scheduling_s * assertScheduling(const char *msg, int index, scheduling_s *expected, void *callback, efitime_t expectedTimestamp); + + AngleBasedEvent * assertTriggerEvent(const char *msg, int index, AngleBasedEvent *expected, void *callback, int triggerEventIndex, angle_t angleOffsetFromTriggerEvent); + void assertEvent(const char *msg, int index, void *callback, efitime_t momentX, InjectionEvent *event); void assertInjectorUpEvent(const char *msg, int eventIndex, efitime_t momentX, long injectorIndex); void assertInjectorDownEvent(const char *msg, int eventIndex, efitime_t momentX, long injectorIndex); @@ -62,9 +66,5 @@ public: persistent_config_s persistentConfig; }; - void setupSimpleTestEngineWithMafAndTT_ONE_trigger(EngineTestHelper *eth, injection_mode_e injMode = IM_BATCH); -void setupSimpleTestEngineWithMaf(EngineTestHelper *eth, injection_mode_e injectionMode, - trigger_type_e trigger); - -#endif /* ENGINE_TEST_HELPER_H_ */ +void setupSimpleTestEngineWithMaf(EngineTestHelper *eth, injection_mode_e injectionMode, trigger_type_e trigger); diff --git a/unit_tests/global_execution_queue.cpp b/unit_tests/global_execution_queue.cpp index 4048bb00aa..7002988abc 100644 --- a/unit_tests/global_execution_queue.cpp +++ b/unit_tests/global_execution_queue.cpp @@ -30,7 +30,7 @@ int TestExecutor::size() { } scheduling_s* TestExecutor::getForUnitTest(int index) { - return schedulingQueue.getForUnitText(index); + return schedulingQueue.getElementAtIndexForUnitText(index); } void TestExecutor::scheduleByTimestamp(scheduling_s *scheduling, efitimeus_t timeUs, schfunc_t callback, void *param) { diff --git a/unit_tests/global_execution_queue.h b/unit_tests/global_execution_queue.h index 43d39da3d8..c8a605c021 100644 --- a/unit_tests/global_execution_queue.h +++ b/unit_tests/global_execution_queue.h @@ -13,8 +13,8 @@ class TestExecutor : public ExecutorInterface { public: - void scheduleByTimestamp(scheduling_s *scheduling, efitimeus_t timeUs, schfunc_t callback, void *param); - void scheduleForLater(scheduling_s *scheduling, int delayUs, schfunc_t callback, void *param); + void scheduleByTimestamp(scheduling_s *scheduling, efitimeus_t timeUs, schfunc_t callback, void *param) override; + void scheduleForLater(scheduling_s *scheduling, int delayUs, schfunc_t callback, void *param) override; void clear(); int executeAll(efitime_t now); int size(); diff --git a/unit_tests/tests/test_accel_enrichment.cpp b/unit_tests/tests/test_accel_enrichment.cpp index 00f51cfbfe..b61e1c1e7f 100644 --- a/unit_tests/tests/test_accel_enrichment.cpp +++ b/unit_tests/tests/test_accel_enrichment.cpp @@ -5,13 +5,11 @@ * * @date Apr 29, 2014 * Author: Dmitry Sidin - * Author: Andrey Belomutskiy, (c) 2012-2018 + * Author: Andrey Belomutskiy, (c) 2012-2019 */ -#include "global.h" -#include "engine_configuration.h" -#include "accel_enrichment.h" #include "engine_test_helper.h" +#include "accel_enrichment.h" #include "tps.h" TEST(fuel, testTpsAccelEnrichmentMath) { diff --git a/unit_tests/tests/test_aux_valves.cpp b/unit_tests/tests/test_aux_valves.cpp new file mode 100644 index 0000000000..3871e00ddc --- /dev/null +++ b/unit_tests/tests/test_aux_valves.cpp @@ -0,0 +1,26 @@ +/* + * @file test_aux_valves.cpp + * + * @date: Nov 23, 2019 + * @Author: Andrey Belomutskiy, (c) 2012-2019 + */ + +#include "engine_test_helper.h" +#include "aux_valves.h" + +TEST(misc, testAuxValves) { + WITH_ENGINE_TEST_HELPER(NISSAN_PRIMERA); + + engine->needTdcCallback = false; + + setupSimpleTestEngineWithMafAndTT_ONE_trigger(ð, IM_SEQUENTIAL); + engineConfiguration->isInjectionEnabled = false; + + eth.fireTriggerEvents2(2 /* count */ , 600 /* ms */); + ASSERT_EQ( 100, GET_RPM()) << "spinning-RPM#1"; + + eth.assertTriggerEvent("a0", 0, &engine->auxValves[0][0].open, (void*)&plainPinTurnOn, 7, 86); + eth.assertTriggerEvent("a1", 1, &engine->auxValves[0][1].open, (void*)&plainPinTurnOn, 3, 86); + eth.assertTriggerEvent("a2", 2, &engine->auxValves[1][0].open, (void*)&plainPinTurnOn, 1, 86); + +} diff --git a/unit_tests/tests/test_cj125.cpp b/unit_tests/tests/test_cj125.cpp index df083359a3..bfad9fe863 100644 --- a/unit_tests/tests/test_cj125.cpp +++ b/unit_tests/tests/test_cj125.cpp @@ -1,11 +1,10 @@ /* - * test_cj125.cpp + * @file test_cj125.cpp * * Created on: Jan 3, 2019 * @author Andrey Belomutskiy, (c) 2012-2019 */ -#include "gtest/gtest.h" #include "cj125_logic.h" #include "engine_test_helper.h" @@ -29,19 +28,38 @@ TEST(testCJ125, testInitialState) { WITH_ENGINE_TEST_HELPER(FORD_ASPIRE_1996); ASSERT_EQ(engine->sensors.vBatt, 0); - cj.StartHeaterControl(&applyHeaterPinState PASS_ENGINE_PARAMETER_SUFFIX); + cj.StartHeaterControl((pwm_gen_callback*)&applyHeaterPinState PASS_ENGINE_PARAMETER_SUFFIX); ASSERT_EQ(cj.heaterDuty, CJ125_HEATER_IDLE_RATE); TestSpi mock; cj.spi = &mock; - EXPECT_CALL(mock, ReadRegister(IDENT_REG_RD)).Times(1); - EXPECT_CALL(mock, ReadRegister(INIT_REG1_RD)).Times(1); - EXPECT_CALL(mock, ReadRegister(INIT_REG2_RD)).Times(1); + EXPECT_CALL(mock, ReadRegister(IDENT_REG_RD)).Times(1).WillOnce(Return(CJ125_IDENT)); + EXPECT_CALL(mock, ReadRegister(INIT_REG1_RD)).Times(1).WillOnce(Return(CJ125_INIT1_NORMAL_17)); + EXPECT_CALL(mock, ReadRegister(INIT_REG2_RD)).Times(1).WillOnce(Return(CJ125_INIT2_DIAG)); EXPECT_CALL(mock, ReadRegister(DIAG_REG_RD)).Times(1); cj.cjIdentify(); - + // validate that error state was not set + ASSERT_EQ(cj.state, CJ125_INIT); } +TEST(testCJ125, testFailedIdentify) { + CJ125 cj; + + ASSERT_EQ(cj.state, CJ125_INIT); + + TestSpi mock; + cj.spi = &mock; + + cj.cjIdentify(); + ASSERT_EQ(cj.errorCode, CJ125_ERROR_WRONG_IDENT); + ASSERT_EQ(cj.state, CJ125_ERROR); +} + +TEST(testCJ125, testMode) { + + + +} diff --git a/unit_tests/tests/test_engine_math.cpp b/unit_tests/tests/test_engine_math.cpp index 9a2d13eb57..3e35d2a9f5 100644 --- a/unit_tests/tests/test_engine_math.cpp +++ b/unit_tests/tests/test_engine_math.cpp @@ -5,9 +5,7 @@ * @author Andrey Belomutskiy, (c) 2012-2019 */ -#include "global.h" #include "engine_math.h" -#include "engine.h" #include "map.h" #include "speed_density.h" #include "engine_test_helper.h" diff --git a/unit_tests/tests/test_fasterEngineSpinningUp.cpp b/unit_tests/tests/test_fasterEngineSpinningUp.cpp index e88dad2181..fc92e1928d 100644 --- a/unit_tests/tests/test_fasterEngineSpinningUp.cpp +++ b/unit_tests/tests/test_fasterEngineSpinningUp.cpp @@ -36,7 +36,6 @@ TEST(cranking, testFasterEngineSpinningUp) { ASSERT_EQ(0, engine->executor.size()) << "plain#1"; // check all events starting from now - int timeStartUs = eth.getTimeNowUs(); // advance 1 revolution // because we have trivial TT_ONE trigger here synchronization would happen with just one rise front eth.fireRise(200); @@ -81,7 +80,6 @@ TEST(cranking, testFasterEngineSpinningUp) { eth.fireFall(60); eth.clearQueue(); - timeStartUs = eth.getTimeNowUs(); eth.fireTriggerEventsWithDuration(60); // check if the mode is now changed to 'running' at higher RPM diff --git a/unit_tests/tests/test_fuel_map.cpp b/unit_tests/tests/test_fuel_map.cpp index 43b7c72c53..4360bc4d5f 100644 --- a/unit_tests/tests/test_fuel_map.cpp +++ b/unit_tests/tests/test_fuel_map.cpp @@ -5,8 +5,6 @@ * @author Andrey Belomutskiy, (c) 2012-2019 */ -#include "global.h" -#include "engine_configuration.h" #include "fuel_math.h" #include "trigger_structure.h" #include "allsensors.h" @@ -116,7 +114,7 @@ TEST(misc, testFuelMap) { } -static void confgiureFordAspireTriggerShape(TriggerShape * s) { +static void confgiureFordAspireTriggerWaveform(TriggerWaveform * s) { s->initialize(FOUR_STROKE_CAM_SENSOR, true); s->addEvent720(53.747, T_SECONDARY, TV_RISE); @@ -165,52 +163,52 @@ TEST(misc, testAngleResolver) { engineConfiguration->globalTriggerAngleOffset = 175; - TriggerShape * ts = &engine->triggerCentral.triggerShape; - engine->eInitializeTriggerShape(NULL PASS_ENGINE_PARAMETER_SUFFIX); + TriggerWaveform * ts = &engine->triggerCentral.triggerShape; + engine->initializeTriggerWaveform(NULL PASS_ENGINE_PARAMETER_SUFFIX); assertEqualsM("index 2", 52.76, ts->eventAngles[3]); // this angle is relation to synch point assertEqualsM("time 2", 0.3233, ts->wave.getSwitchTime(2)); assertEqualsM("index 5", 412.76, ts->eventAngles[6]); assertEqualsM("time 5", 0.5733, ts->wave.getSwitchTime(5)); - ASSERT_EQ(4, ts->getTriggerShapeSynchPointIndex()); + ASSERT_EQ(4, ts->getTriggerWaveformSynchPointIndex()); ASSERT_EQ( 10, ts->getSize()) << "shape size"; event_trigger_position_s injectionStart; printf("*************************************************** testAngleResolver 0\r\n"); - TRIGGER_SHAPE(findTriggerPosition(&injectionStart, -122, engineConfiguration->globalTriggerAngleOffset)); + TRIGGER_WAVEFORM(findTriggerPosition(&injectionStart, -122, engineConfiguration->globalTriggerAngleOffset)); ASSERT_EQ( 2, injectionStart.triggerEventIndex) << "eventIndex@0"; ASSERT_NEAR(0.24, injectionStart.angleOffsetFromTriggerEvent, EPS5D); printf("*************************************************** testAngleResolver 0.1\r\n"); - TRIGGER_SHAPE(findTriggerPosition(&injectionStart, -80, engineConfiguration->globalTriggerAngleOffset)); + TRIGGER_WAVEFORM(findTriggerPosition(&injectionStart, -80, engineConfiguration->globalTriggerAngleOffset)); ASSERT_EQ( 2, injectionStart.triggerEventIndex) << "eventIndex@0"; ASSERT_FLOAT_EQ(42.24, injectionStart.angleOffsetFromTriggerEvent); printf("*************************************************** testAngleResolver 0.2\r\n"); - TRIGGER_SHAPE(findTriggerPosition(&injectionStart, -54, engineConfiguration->globalTriggerAngleOffset)); + TRIGGER_WAVEFORM(findTriggerPosition(&injectionStart, -54, engineConfiguration->globalTriggerAngleOffset)); ASSERT_EQ( 2, injectionStart.triggerEventIndex) << "eventIndex@0"; ASSERT_FLOAT_EQ(68.2400, injectionStart.angleOffsetFromTriggerEvent); printf("*************************************************** testAngleResolver 0.3\r\n"); - TRIGGER_SHAPE(findTriggerPosition(&injectionStart, -53, engineConfiguration->globalTriggerAngleOffset)); + TRIGGER_WAVEFORM(findTriggerPosition(&injectionStart, -53, engineConfiguration->globalTriggerAngleOffset)); ASSERT_EQ(2, injectionStart.triggerEventIndex); ASSERT_FLOAT_EQ(69.24, injectionStart.angleOffsetFromTriggerEvent); printf("*************************************************** testAngleResolver 1\r\n"); - TRIGGER_SHAPE(findTriggerPosition(&injectionStart, 0, engineConfiguration->globalTriggerAngleOffset)); + TRIGGER_WAVEFORM(findTriggerPosition(&injectionStart, 0, engineConfiguration->globalTriggerAngleOffset)); ASSERT_EQ(2, injectionStart.triggerEventIndex); ASSERT_FLOAT_EQ(122.24, injectionStart.angleOffsetFromTriggerEvent); printf("*************************************************** testAngleResolver 2\r\n"); - TRIGGER_SHAPE(findTriggerPosition(&injectionStart, 56, engineConfiguration->globalTriggerAngleOffset)); + TRIGGER_WAVEFORM(findTriggerPosition(&injectionStart, 56, engineConfiguration->globalTriggerAngleOffset)); ASSERT_EQ(2, injectionStart.triggerEventIndex); ASSERT_FLOAT_EQ(178.24, injectionStart.angleOffsetFromTriggerEvent); - TriggerShape t; - confgiureFordAspireTriggerShape(&t); + TriggerWaveform t; + confgiureFordAspireTriggerWaveform(&t); } TEST(misc, testPinHelper) { @@ -233,7 +231,7 @@ TEST(fuel, testTpsBasedVeDefect799) { int mapFrom = 100; // set MAP axis range - setLinearCurve(config->veLoadBins, FUEL_LOAD_COUNT, mapFrom, mapFrom + FUEL_LOAD_COUNT - 1, 1); + setLinearCurve(config->veLoadBins, mapFrom, mapFrom + FUEL_LOAD_COUNT - 1, 1); // RPM does not matter - set table values to match load axis for (int load = 0; load < FUEL_LOAD_COUNT;load++) { @@ -246,7 +244,7 @@ TEST(fuel, testTpsBasedVeDefect799) { ASSERT_EQ(107, veMap.getValue(2000, 107)); // set TPS axis range which does not overlap MAP range for this test - setLinearCurve(CONFIG(ignitionTpsBins), IGN_TPS_COUNT, 0, 15, 1); + setLinearCurve(CONFIG(ignitionTpsBins), 0, 15, 1); engine->mockMapValue = 107; diff --git a/unit_tests/tests/test_gpiochip.cpp b/unit_tests/tests/test_gpiochip.cpp index 98172d2909..eaa00411fc 100644 --- a/unit_tests/tests/test_gpiochip.cpp +++ b/unit_tests/tests/test_gpiochip.cpp @@ -42,6 +42,7 @@ static int calls_to_failed_chip = 0; static int testchip_failed_writePad(void *data, brain_pin_e pin, int value) { calls_to_failed_chip++; + return 0; } static int testchip_failed_init(void *data) @@ -123,24 +124,24 @@ TEST(gpioext, testGpioExt) { EXPECT_EQ(2, initcalls); /* gpio reads */ - EXPECT_TRUE(gpiochips_readPad(chip1_base + 0) == 0); - EXPECT_TRUE(gpiochips_readPad(chip1_base + 1) != 0); + EXPECT_TRUE(gpiochips_readPad((brain_pin_e)(chip1_base + 0)) == 0); + EXPECT_TRUE(gpiochips_readPad((brain_pin_e)(chip1_base + 1)) != 0); /* gpio write */ - gpiochips_writePad(chip2_base + 0, 0); - gpiochips_writePad(chip2_base + 1, 1); + gpiochips_writePad((brain_pin_e)(chip2_base + 0), 0); + gpiochips_writePad((brain_pin_e)(chip2_base + 1), 1); EXPECT_EQ(0x02, io_state); /* try to access failed chip */ - EXPECT_FALSE(gpiochips_writePad(chip3_base + 0, 0) >= 0); - EXPECT_FALSE(gpiochips_writePad(chip3_base + 1, 1) >= 0); + EXPECT_FALSE(gpiochips_writePad((brain_pin_e)(chip3_base + 0), 0) >= 0); + EXPECT_FALSE(gpiochips_writePad((brain_pin_e)(chip3_base + 1), 1) >= 0); EXPECT_EQ(0, calls_to_failed_chip); /* read/write outside range */ - EXPECT_TRUE(gpiochips_readPad(chip1_base - 1) < 0); - EXPECT_TRUE(gpiochips_writePad(chip1_base - 1, 1) < 0); + EXPECT_TRUE(gpiochips_readPad((brain_pin_e)(chip1_base - 1)) < 0); + EXPECT_TRUE(gpiochips_writePad((brain_pin_e)(chip1_base - 1), 1) < 0); - EXPECT_TRUE(gpiochips_readPad(chip3_base + 16) < 0); - EXPECT_TRUE(gpiochips_writePad(chip3_base + 16, 1) < 0); + EXPECT_TRUE(gpiochips_readPad((brain_pin_e)(chip3_base + 16)) < 0); + EXPECT_TRUE(gpiochips_writePad((brain_pin_e)(chip3_base + 16), 1) < 0); } diff --git a/unit_tests/tests/test_ignition_scheduling.cpp b/unit_tests/tests/test_ignition_scheduling.cpp index 500c8297de..f2a9535f4f 100644 --- a/unit_tests/tests/test_ignition_scheduling.cpp +++ b/unit_tests/tests/test_ignition_scheduling.cpp @@ -26,14 +26,14 @@ TEST(ignition, twoCoils) { engine->engineState.timingAdvance = 0; initializeIgnitionActions(PASS_ENGINE_PARAMETER_SIGNATURE); - ASSERT_EQ(engine->ignitionEvents.elements[0].advance, 0); + ASSERT_EQ(engine->ignitionEvents.elements[0].sparkAngle, 0); ASSERT_EQ((void*)engine->ignitionEvents.elements[0].outputs[0], (void*)&enginePins.coils[0]); - ASSERT_EQ(engine->ignitionEvents.elements[1].advance, 720 / 12); + ASSERT_EQ(engine->ignitionEvents.elements[1].sparkAngle, 720 / 12); ASSERT_EQ((void*)engine->ignitionEvents.elements[1].outputs[0], (void*)&enginePins.coils[6]); - ASSERT_EQ(engine->ignitionEvents.elements[3].advance, 3 * 720 / 12); + ASSERT_EQ(engine->ignitionEvents.elements[3].sparkAngle, 3 * 720 / 12); ASSERT_EQ((void*)engine->ignitionEvents.elements[3].outputs[0], (void*)&enginePins.coils[6]); diff --git a/unit_tests/tests/test_logic_expression.cpp b/unit_tests/tests/test_logic_expression.cpp index 59003b9fac..96c024528e 100644 --- a/unit_tests/tests/test_logic_expression.cpp +++ b/unit_tests/tests/test_logic_expression.cpp @@ -7,7 +7,6 @@ * @author Andrey Belomutskiy, (c) 2012-2018 */ -#include "global.h" #include "fsio_impl.h" #include "cli_registry.h" #include "engine_test_helper.h" @@ -229,7 +228,7 @@ TEST(fsio, testLogicExpressions) { engine->fsioState.mockCrankingRpm = 200; testExpression2(0, "rpm", 900, engine); testExpression2(0, "cranking_rpm", 200, engine); - testExpression2(0, STARTER_BLOCK, 0, engine); + testExpression2(0, STARTER_RELAY_LOGIC, 0, engine); testExpression2(0, "rpm cranking_rpm > ", 1, engine); } } diff --git a/unit_tests/tests/test_on_demand_parameters.cpp b/unit_tests/tests/test_on_demand_parameters.cpp index 0c8f95420b..a6372a7d65 100644 --- a/unit_tests/tests/test_on_demand_parameters.cpp +++ b/unit_tests/tests/test_on_demand_parameters.cpp @@ -47,8 +47,9 @@ TEST(util, checkForMissingParameterHandling) { FAIL() << "Expected 'missing key3' exception"; } catch(string message) { // exception about missing value is expected - ASSERT_TRUE(message.find("No value for this key") >= 0); - ASSERT_TRUE(message.find("key3") >= 0); + // type limits this to always be not negative + // todo? do we need this? ASSERT_TRUE(message.find("No value for this key") >= 0); + // todo? do we need this? ASSERT_TRUE(message.find("key3") >= 0); } } diff --git a/unit_tests/tests/test_pwm_generator.cpp b/unit_tests/tests/test_pwm_generator.cpp index c866968185..7d48e4aac1 100644 --- a/unit_tests/tests/test_pwm_generator.cpp +++ b/unit_tests/tests/test_pwm_generator.cpp @@ -18,7 +18,7 @@ static int expectedTimeOfNextEvent; static int pinValue = -1; static void testApplyPinState(int stateIndex, PwmConfig *state) /* pwm_gen_callback */ { - pinValue = state->multiWave.getChannelState(/*channelIndex*/0, stateIndex); + pinValue = state->multiChannelStateSequence.getChannelState(/*channelIndex*/0, stateIndex); printf("PWM_test: setPinValue=%d @ timeNow=%d\r\n", pinValue, timeNowUs); } @@ -52,7 +52,7 @@ static void test100dutyCycle() { &pin, 1000 /* frequency */, 1.0 /* duty cycle */, - &testApplyPinState); + (pwm_gen_callback*)&testApplyPinState); expectedTimeOfNextEvent += 1000; assertEqualsM2("1@1000/100", expectedTimeOfNextEvent, executor.getForUnitTest(0)->momentX, 0); @@ -79,7 +79,7 @@ static void testSwitchToNanPeriod() { &pin, 1000 /* frequency */, 0.60 /* duty cycle */, - &testApplyPinState); + (pwm_gen_callback*)&testApplyPinState); expectedTimeOfNextEvent += 600; assertEqualsM2("1@1000/70", expectedTimeOfNextEvent, executor.getForUnitTest(0)->momentX, 0); @@ -118,7 +118,7 @@ TEST(misc, testPwmGenerator) { &pin, 1000 /* frequency */, 0.80 /* duty cycle */, - &testApplyPinState); + (pwm_gen_callback*)&testApplyPinState); expectedTimeOfNextEvent += 800; diff --git a/unit_tests/tests/test_signal_executor.cpp b/unit_tests/tests/test_signal_executor.cpp index f40e49b051..3c35b17759 100644 --- a/unit_tests/tests/test_signal_executor.cpp +++ b/unit_tests/tests/test_signal_executor.cpp @@ -108,9 +108,9 @@ TEST(misc, testSignalExecutor) { ASSERT_EQ(4, eq.size()); ASSERT_EQ(10, eq.getHead()->momentX); - ASSERT_EQ(10, eq.getHead()->next->momentX); - ASSERT_EQ(11, eq.getHead()->next->next->momentX); - ASSERT_EQ(12, eq.getHead()->next->next->next->momentX); + ASSERT_EQ(10, eq.getHead()->nextScheduling_s->momentX); + ASSERT_EQ(11, eq.getHead()->nextScheduling_s->nextScheduling_s->momentX); + ASSERT_EQ(12, eq.getHead()->nextScheduling_s->nextScheduling_s->nextScheduling_s->momentX); callbackCounter = 0; eq.executeAll(10); diff --git a/unit_tests/tests/test_speed_density.cpp b/unit_tests/tests/test_speed_density.cpp index 683ad7b743..d91a39348d 100644 --- a/unit_tests/tests/test_speed_density.cpp +++ b/unit_tests/tests/test_speed_density.cpp @@ -5,7 +5,6 @@ * @author Andrey Belomutskiy, (c) 2012-2018 */ -#include "global.h" #include "engine_test_helper.h" #include "speed_density.h" @@ -14,7 +13,7 @@ TEST(big, testSpeedDensity) { WITH_ENGINE_TEST_HELPER(FORD_INLINE_6_1995); engineConfiguration->trigger.customTotalToothCount = 8; - eth.applyTriggerShape(); + eth.applyTriggerWaveform(); eth.fireTriggerEvents(36); ASSERT_EQ( 1500, GET_RPM()) << "RPM"; diff --git a/unit_tests/tests/test_trigger_decoder.cpp b/unit_tests/tests/test_trigger_decoder.cpp index 214478e4f9..7908947e6c 100644 --- a/unit_tests/tests/test_trigger_decoder.cpp +++ b/unit_tests/tests/test_trigger_decoder.cpp @@ -49,7 +49,7 @@ static int getTriggerZeroEventIndex(engine_type_e engineType) { initDataStructures(PASS_ENGINE_PARAMETER_SIGNATURE); - TriggerShape * shape = ð.engine.triggerCentral.triggerShape; + TriggerWaveform * shape = ð.engine.triggerCentral.triggerShape; return findTriggerZeroEventIndex(ð.engine.triggerCentral.triggerState, shape, &engineConfiguration->trigger PASS_ENGINE_PARAMETER_SUFFIX); } @@ -60,8 +60,8 @@ static void testDodgeNeonDecoder(void) { WITH_ENGINE_TEST_HELPER(DODGE_NEON_1995); - TriggerShape * shape = ð.engine.triggerCentral.triggerShape; - ASSERT_EQ(8, shape->getTriggerShapeSynchPointIndex()); + TriggerWaveform * shape = ð.engine.triggerCentral.triggerShape; + ASSERT_EQ(8, shape->getTriggerWaveformSynchPointIndex()); TriggerState state; @@ -118,28 +118,28 @@ TEST(misc, testSomethingWeird) { ASSERT_FALSE(sta->shaft_is_synchronized) << "shaft_is_synchronized"; int r = 10; - sta->decodeTriggerEvent(SHAFT_PRIMARY_FALLING, r PASS_ENGINE_PARAMETER_SUFFIX); + sta->decodeTriggerEvent(nullptr, /* override */ nullptr,SHAFT_PRIMARY_FALLING, r PASS_ENGINE_PARAMETER_SUFFIX); ASSERT_FALSE(sta->shaft_is_synchronized) << "shaft_is_synchronized"; // still no synchronization - sta->decodeTriggerEvent(SHAFT_PRIMARY_RISING, ++r PASS_ENGINE_PARAMETER_SUFFIX); + sta->decodeTriggerEvent(nullptr, /* override */ nullptr,SHAFT_PRIMARY_RISING, ++r PASS_ENGINE_PARAMETER_SUFFIX); ASSERT_TRUE(sta->shaft_is_synchronized); // first signal rise synchronize ASSERT_EQ(0, sta->getCurrentIndex()); - sta->decodeTriggerEvent(SHAFT_PRIMARY_FALLING, r++ PASS_ENGINE_PARAMETER_SUFFIX); + sta->decodeTriggerEvent(nullptr, /* override */ nullptr,SHAFT_PRIMARY_FALLING, r++ PASS_ENGINE_PARAMETER_SUFFIX); ASSERT_EQ(1, sta->getCurrentIndex()); for (int i = 2; i < 10;) { - sta->decodeTriggerEvent(SHAFT_PRIMARY_RISING, r++ PASS_ENGINE_PARAMETER_SUFFIX); + sta->decodeTriggerEvent(nullptr, /* override */ nullptr,SHAFT_PRIMARY_RISING, r++ PASS_ENGINE_PARAMETER_SUFFIX); assertEqualsM("even", i++, sta->getCurrentIndex()); - sta->decodeTriggerEvent(SHAFT_PRIMARY_FALLING, r++ PASS_ENGINE_PARAMETER_SUFFIX); + sta->decodeTriggerEvent(nullptr, /* override */ nullptr,SHAFT_PRIMARY_FALLING, r++ PASS_ENGINE_PARAMETER_SUFFIX); assertEqualsM("odd", i++, sta->getCurrentIndex()); } - sta->decodeTriggerEvent(SHAFT_PRIMARY_RISING, r++ PASS_ENGINE_PARAMETER_SUFFIX); + sta->decodeTriggerEvent(nullptr, /* override */ nullptr,SHAFT_PRIMARY_RISING, r++ PASS_ENGINE_PARAMETER_SUFFIX); ASSERT_EQ(10, sta->getCurrentIndex()); - sta->decodeTriggerEvent(SHAFT_PRIMARY_FALLING, r++ PASS_ENGINE_PARAMETER_SUFFIX); + sta->decodeTriggerEvent(nullptr, /* override */ nullptr,SHAFT_PRIMARY_FALLING, r++ PASS_ENGINE_PARAMETER_SUFFIX); ASSERT_EQ(11, sta->getCurrentIndex()); - sta->decodeTriggerEvent(SHAFT_PRIMARY_RISING, r++ PASS_ENGINE_PARAMETER_SUFFIX); + sta->decodeTriggerEvent(nullptr, /* override */ nullptr,SHAFT_PRIMARY_RISING, r++ PASS_ENGINE_PARAMETER_SUFFIX); ASSERT_EQ(0, sta->getCurrentIndex()); // new revolution } @@ -151,22 +151,22 @@ TEST(misc, test1995FordInline6TriggerDecoder) { WITH_ENGINE_TEST_HELPER(FORD_INLINE_6_1995); - TriggerShape * shape = &engine->triggerCentral.triggerShape; + TriggerWaveform * shape = &engine->triggerCentral.triggerShape; - ASSERT_EQ( 0, shape->getTriggerShapeSynchPointIndex()) << "triggerShapeSynchPointIndex"; + ASSERT_EQ( 0, shape->getTriggerWaveformSynchPointIndex()) << "triggerShapeSynchPointIndex"; event_trigger_position_s position; ASSERT_EQ( 0, engineConfiguration->globalTriggerAngleOffset) << "globalTriggerAngleOffset"; - TRIGGER_SHAPE(findTriggerPosition(&position, 0, engineConfiguration->globalTriggerAngleOffset)); + TRIGGER_WAVEFORM(findTriggerPosition(&position, 0, engineConfiguration->globalTriggerAngleOffset)); assertTriggerPosition(&position, 0, 0); - TRIGGER_SHAPE(findTriggerPosition(&position, 200, engineConfiguration->globalTriggerAngleOffset)); + TRIGGER_WAVEFORM(findTriggerPosition(&position, 200, engineConfiguration->globalTriggerAngleOffset)); assertTriggerPosition(&position, 3, 20); - TRIGGER_SHAPE(findTriggerPosition(&position, 360, engineConfiguration->globalTriggerAngleOffset)); + TRIGGER_WAVEFORM(findTriggerPosition(&position, 360, engineConfiguration->globalTriggerAngleOffset)); assertTriggerPosition(&position, 6, 0); - eth.applyTriggerShape(); + eth.applyTriggerWaveform(); engine->periodicFastCallback(PASS_ENGINE_PARAMETER_SIGNATURE); eth.fireTriggerEvents(48); @@ -203,7 +203,7 @@ TEST(misc, testFordAspire) { WITH_ENGINE_TEST_HELPER(FORD_ASPIRE_1996); - ASSERT_EQ( 4, TRIGGER_SHAPE(getTriggerShapeSynchPointIndex())) << "getTriggerShapeSynchPointIndex"; + ASSERT_EQ( 4, TRIGGER_WAVEFORM(getTriggerWaveformSynchPointIndex())) << "getTriggerWaveformSynchPointIndex"; ASSERT_EQ(800, config->fuelRpmBins[0]); ASSERT_EQ(7000, config->fuelRpmBins[15]); @@ -228,11 +228,11 @@ static void testTriggerDecoder2(const char *msg, engine_type_e type, int synchPo WITH_ENGINE_TEST_HELPER(type); - TriggerShape *t = &ENGINE(triggerCentral.triggerShape); + TriggerWaveform *t = &ENGINE(triggerCentral.triggerShape); ASSERT_FALSE(t->shapeDefinitionError) << "isError"; - assertEqualsM("synchPointIndex", synchPointIndex, t->getTriggerShapeSynchPointIndex()); + assertEqualsM("synchPointIndex", synchPointIndex, t->getTriggerWaveformSynchPointIndex()); ASSERT_NEAR(channel1duty, t->expectedDutyCycle[0], 0.0001) << msg << " channel1duty"; ASSERT_NEAR(channel2duty, t->expectedDutyCycle[1], 0.0001) << msg << " channel2duty"; @@ -307,7 +307,7 @@ TEST(misc, testRpmCalculator) { engineConfiguration->trigger.customTotalToothCount = 8; engineConfiguration->globalFuelCorrection = 3; - eth.applyTriggerShape(); + eth.applyTriggerWaveform(); setFlatInjectorLag(0 PASS_CONFIG_PARAMETER_SUFFIX); @@ -318,8 +318,8 @@ TEST(misc, testRpmCalculator) { ASSERT_EQ(0, GET_RPM()); // triggerIndexByAngle update is now fixed! prepareOutputSignals() wasn't reliably called - ASSERT_EQ(5, TRIGGER_SHAPE(triggerIndexByAngle[240])); - ASSERT_EQ(5, TRIGGER_SHAPE(triggerIndexByAngle[241])); + ASSERT_EQ(5, TRIGGER_WAVEFORM(triggerIndexByAngle[240])); + ASSERT_EQ(5, TRIGGER_WAVEFORM(triggerIndexByAngle[241])); eth.fireTriggerEvents(/* count */ 48); @@ -351,7 +351,7 @@ TEST(misc, testRpmCalculator) { assertEqualsM("fuel #2", 4.5450, engine->injectionDuration); assertEqualsM("one degree", 111.1111, engine->rpmCalculator.oneDegreeUs); ASSERT_EQ( 1, ilist->isReady) << "size #2"; - ASSERT_EQ( 0, ilist->elements[0].dwellPosition.triggerEventAngle) << "dwell angle"; + ASSERT_EQ( 0, ilist->elements[0].dwellPosition.triggerEventIndex) << "dwell @ index"; assertEqualsM("dwell offset", 8.5, ilist->elements[0].dwellPosition.angleOffsetFromTriggerEvent); ASSERT_EQ( 0, eth.engine.triggerCentral.triggerState.getCurrentIndex()) << "index #2"; @@ -359,14 +359,14 @@ TEST(misc, testRpmCalculator) { { scheduling_s *ev0 = engine->executor.getForUnitTest(0); - assertREqualsM("Call@0", (void*)ev0->callback, (void*)turnSparkPinHigh); + assertREqualsM("Call@0", (void*)ev0->action.getCallback(), (void*)turnSparkPinHigh); assertEqualsM("ev 0", start + 944, ev0->momentX); - assertEqualsLM("coil 0", (long)&enginePins.coils[0], (long)((IgnitionEvent*)ev0->param)->outputs[0]); + assertEqualsLM("coil 0", (long)&enginePins.coils[0], (long)((IgnitionEvent*)ev0->action.getArgument())->outputs[0]); scheduling_s *ev1 = engine->executor.getForUnitTest(1); - assertREqualsM("Call@1", (void*)ev1->callback, (void*)fireSparkAndPrepareNextSchedule); + assertREqualsM("Call@1", (void*)ev1->action.getCallback(), (void*)fireSparkAndPrepareNextSchedule); assertEqualsM("ev 1", start + 1444, ev1->momentX); - assertEqualsLM("coil 1", (long)&enginePins.coils[0], (long)((IgnitionEvent*)ev1->param)->outputs[0]); + assertEqualsLM("coil 1", (long)&enginePins.coils[0], (long)((IgnitionEvent*)ev1->action.getArgument())->outputs[0]); } @@ -382,8 +382,8 @@ TEST(misc, testRpmCalculator) { assertEqualsM("3/3", start + 14777, engine->executor.getForUnitTest(2)->momentX); engine->executor.clear(); - ASSERT_EQ(5, TRIGGER_SHAPE(triggerIndexByAngle[240])); - ASSERT_EQ(5, TRIGGER_SHAPE(triggerIndexByAngle[241])); + ASSERT_EQ(5, TRIGGER_WAVEFORM(triggerIndexByAngle[240])); + ASSERT_EQ(5, TRIGGER_WAVEFORM(triggerIndexByAngle[241])); eth.fireFall(5); @@ -448,7 +448,7 @@ TEST(misc, testTriggerDecoder) { persistent_config_s c; Engine e(&c); - TriggerShape * s = &e.triggerCentral.triggerShape; + TriggerWaveform * s = &e.triggerCentral.triggerShape; persistent_config_s *config = &c; @@ -457,7 +457,7 @@ TEST(misc, testTriggerDecoder) { engine_configuration_s *engineConfiguration = &c.engineConfiguration; board_configuration_s *boardConfiguration = &c.engineConfiguration.bc; - initializeSkippedToothTriggerShapeExt(s, 2, 0, FOUR_STROKE_CAM_SENSOR); + initializeSkippedToothTriggerWaveformExt(s, 2, 0, FOUR_STROKE_CAM_SENSOR); assertEqualsM("shape size", s->getSize(), 4); ASSERT_EQ(s->wave.switchTimes[0], 0.25); ASSERT_EQ(s->wave.switchTimes[1], 0.5); @@ -507,7 +507,7 @@ TEST(misc, testTriggerDecoder) { WITH_ENGINE_TEST_HELPER(MITSU_4G93); -// TriggerShape *t = ð.engine.triggerShape; +// TriggerWaveform *t = ð.engine.triggerShape; // ASSERT_EQ(1, t->eventAngles[1]); // ASSERT_EQ( 0, t->triggerIndexByAngle[56]) << "index at 0"; // ASSERT_EQ( 1, t->triggerIndexByAngle[57]) << "index at 1"; @@ -691,6 +691,12 @@ static void assertInjectors(const char *msg, int value0, int value1) { assertEqualsM4(msg, "inj#1", value1, enginePins.injectors[1].currentLogicValue); } +static void setArray(float* p, size_t count, float value) { + while (count--) { + *p++ = value; + } +} + void doTestFuelSchedulerBug299smallAndMedium(int startUpDelayMs) { printf("*************************************************** testFuelSchedulerBug299 small to medium\r\n"); @@ -705,8 +711,9 @@ void doTestFuelSchedulerBug299smallAndMedium(int startUpDelayMs) { int engineLoadIndex = findIndex(config->fuelLoadBins, FUEL_LOAD_COUNT, testMafValue); ASSERT_EQ(8, engineLoadIndex); - setArrayValues(fuelMap.pointers[engineLoadIndex], FUEL_RPM_COUNT, 25); - setArrayValues(fuelMap.pointers[engineLoadIndex + 1], FUEL_RPM_COUNT, 25); + setArray(fuelMap.pointers[engineLoadIndex], FUEL_RPM_COUNT, 25); + setArray(fuelMap.pointers[engineLoadIndex + 1], FUEL_RPM_COUNT, 25); + engine->periodicFastCallback(PASS_ENGINE_PARAMETER_SIGNATURE); ASSERT_FLOAT_EQ(12.5, engine->injectionDuration) << "fuel#2_0"; @@ -866,8 +873,8 @@ void doTestFuelSchedulerBug299smallAndMedium(int startUpDelayMs) { assertInjectionEvent("#2#", &t->elements[2], 0, 1, 315); assertInjectionEvent("#3#", &t->elements[3], 1, 0, 45 + 90); - setArrayValues(fuelMap.pointers[engineLoadIndex], FUEL_RPM_COUNT, 35); - setArrayValues(fuelMap.pointers[engineLoadIndex + 1], FUEL_RPM_COUNT, 35); + setArray(fuelMap.pointers[engineLoadIndex], FUEL_RPM_COUNT, 35); + setArray(fuelMap.pointers[engineLoadIndex + 1], FUEL_RPM_COUNT, 35); engine->periodicFastCallback(PASS_ENGINE_PARAMETER_SIGNATURE); assertEqualsM("fuel#3", 17.5, engine->injectionDuration); // duty cycle above 75% is a special use-case because 'special' fuel event overlappes the next normal event in batch mode @@ -957,8 +964,8 @@ TEST(big, testDifferentInjectionModes) { // set fuel map values - extract method? int engineLoadIndex = findIndex(config->fuelLoadBins, FUEL_LOAD_COUNT, testMafValue); ASSERT_EQ(8, engineLoadIndex); - setArrayValues(fuelMap.pointers[engineLoadIndex], FUEL_RPM_COUNT, 40); - setArrayValues(fuelMap.pointers[engineLoadIndex + 1], FUEL_RPM_COUNT, 40); + setArray(fuelMap.pointers[engineLoadIndex], FUEL_RPM_COUNT, 40); + setArray(fuelMap.pointers[engineLoadIndex + 1], FUEL_RPM_COUNT, 40); engine->periodicFastCallback(PASS_ENGINE_PARAMETER_SIGNATURE); assertEqualsM("injectionMode IM_BATCH", (int)IM_BATCH, (int)engineConfiguration->injectionMode); @@ -988,8 +995,8 @@ TEST(big, testFuelSchedulerBug299smallAndLarge) { // set fuel map values - extract method? int engineLoadIndex = findIndex(config->fuelLoadBins, FUEL_LOAD_COUNT, testMafValue); ASSERT_EQ(8, engineLoadIndex); - setArrayValues(fuelMap.pointers[engineLoadIndex], FUEL_RPM_COUNT, 35); - setArrayValues(fuelMap.pointers[engineLoadIndex + 1], FUEL_RPM_COUNT, 35); + setArray(fuelMap.pointers[engineLoadIndex], FUEL_RPM_COUNT, 35); + setArray(fuelMap.pointers[engineLoadIndex + 1], FUEL_RPM_COUNT, 35); engine->periodicFastCallback(PASS_ENGINE_PARAMETER_SIGNATURE); ASSERT_FLOAT_EQ(17.5, engine->injectionDuration) << "Lfuel#2_1"; @@ -1052,8 +1059,8 @@ TEST(big, testFuelSchedulerBug299smallAndLarge) { eth.executeActions(); ASSERT_EQ( 0, engine->executor.size()) << "Lqs#04"; - setArrayValues(fuelMap.pointers[engineLoadIndex], FUEL_RPM_COUNT, 4); - setArrayValues(fuelMap.pointers[engineLoadIndex + 1], FUEL_RPM_COUNT, 4); + setArray(fuelMap.pointers[engineLoadIndex], FUEL_RPM_COUNT, 4); + setArray(fuelMap.pointers[engineLoadIndex + 1], FUEL_RPM_COUNT, 4); engine->periodicFastCallback(PASS_ENGINE_PARAMETER_SIGNATURE); ASSERT_EQ( 2, engine->injectionDuration) << "Lfuel#4"; diff --git a/unit_tests/tests/test_trigger_multi_sync.cpp b/unit_tests/tests/test_trigger_multi_sync.cpp index 87542c8a8a..1d8ad39258 100644 --- a/unit_tests/tests/test_trigger_multi_sync.cpp +++ b/unit_tests/tests/test_trigger_multi_sync.cpp @@ -9,7 +9,7 @@ #include "trigger_mazda.h" TEST(trigger, miataNA) { - TriggerShape naShape; + TriggerWaveform naShape; initializeMazdaMiataNaShape(&naShape); diff --git a/unit_tests/tests/test_trigger_noiseless.cpp b/unit_tests/tests/test_trigger_noiseless.cpp index f206cf3bf7..285394492b 100644 --- a/unit_tests/tests/test_trigger_noiseless.cpp +++ b/unit_tests/tests/test_trigger_noiseless.cpp @@ -84,7 +84,7 @@ static void fireNoisyCycle60_2(EngineTestHelper *eth, int numCycles, int duratio } static void resetTrigger(EngineTestHelper ð) { - eth.applyTriggerShape(); + eth.applyTriggerWaveform(); eth.engine.triggerCentral.resetAccumSignalData(); // reset error counter eth.engine.triggerCentral.triggerState.totalTriggerErrorCounter = 0; diff --git a/unit_tests/tests/tests.mk b/unit_tests/tests/tests.mk index c7b3e3866d..dc6e721b4f 100644 --- a/unit_tests/tests/tests.mk +++ b/unit_tests/tests/tests.mk @@ -1,6 +1,7 @@ TESTS_SRC_CPP = \ tests/test_util.cpp \ tests/test_ion.cpp \ + tests/test_aux_valves.cpp \ tests/test_on_demand_parameters.cpp \ tests/test_hip9011.cpp \ tests/test_cj125.cpp \ diff --git a/unit_tests/unit_test_framework.h b/unit_tests/unit_test_framework.h index fd380ef299..5c0f3788fe 100644 --- a/unit_tests/unit_test_framework.h +++ b/unit_tests/unit_test_framework.h @@ -11,6 +11,7 @@ #include "engine.h" #include "gtest/gtest.h" #include "gmock/gmock.h" +using ::testing::Return; // This lets us inspect private state from unit tests #define private public