Merge branch 'master' into master_jared

This commit is contained in:
rusefi 2020-04-26 19:56:07 -04:00
commit 37d73c595b
471 changed files with 8632 additions and 7665 deletions

4
.github/ISSUE_TEMPLATE.md vendored Normal file
View File

@ -0,0 +1,4 @@
Thank you for taking the time to report an issue!
To make our work easier, please provide as many details as you can:
* [ ] What hardware did you use while experiencing the issue?

2
.gitignore vendored
View File

@ -17,3 +17,5 @@ java_console_binary
.vscode
*.cmp
*.net
err.txt
log.txt

28
.vscode/launch.json vendored Normal file
View File

@ -0,0 +1,28 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "(gdb) Launch",
"type": "cppdbg",
"request": "launch",
"program": "${workspaceFolder}/unit_tests/build/rusefi_test",
// uncomment args below to only debug a particular test
//"args": ["--gtest_filter=etb.testTargetTpsIsFloatBug945"],
"stopAtEntry": false,
"cwd": "${workspaceFolder}/unit_tests/build/",
"environment": [],
"externalConsole": false,
"MIMode": "gdb",
"setupCommands": [
{
"description": "Enable pretty-printing for gdb",
"text": "-enable-pretty-printing",
"ignoreFailures": true
}
]
}
]
}

32
.vscode/settings.json vendored Normal file
View File

@ -0,0 +1,32 @@
{
"files.associations": {
"xstring": "cpp",
"ios": "cpp",
"xlocale": "cpp",
"xtr1common": "cpp",
"xiosbase": "cpp",
"deque": "cpp",
"forward_list": "cpp",
"list": "cpp",
"system_error": "cpp",
"vector": "cpp",
"xhash": "cpp",
"xtree": "cpp"
},
"editor.detectIndentation": false,
"editor.insertSpaces": false,
"files.exclude": {
"**/.dep": true,
"**/build/lst": true,
"**/build/obj": true,
"hardware/": true,
"misc/": true,
},
"search.exclude": {
"**/.dep": true,
"**/build/lst": true,
"**/build/obj": true,
"hardware/": true,
"misc/": true,
},
}

View File

@ -44,6 +44,10 @@ See https://rusefi.com/forum/viewtopic.php?f=5&t=9
| Release date | Revision | Details |
| ------------ | --------- | ------- |
| 04/18/2020 | r22231 | Renix 44-2-2 trigger support added |
| 04/02/2020 | | Start button feature |
| 03/28/2020 | | Critical error text is now displayed in TunerStudio |
| 03/26/2020 | | Multi-spark feature |
| 09/05/2019 | r19849 | Electronic Throttle Body including idle control seems to work |
| 07/28/2019 | r19612 | improvement #809: software jump to DFU |
| 04/25/2019 | r17317 | bugfix #775: electrical noise reboot during settings change causes with full tune loss |

View File

@ -1,14 +0,0 @@
{
"editor.detectIndentation": false,
"editor.insertSpaces": false,
"files.exclude": {
".dep": true,
"build/lst": true,
"build/obj": true,
},
"search.exclude": {
".dep": true,
"build/lst": true,
"build/obj": true,
},
}

@ -1 +1 @@
Subproject commit 85cf4582a9f6a57cc49759c606af5fda2f52d106
Subproject commit 1a2c5967dc813bdbf1cc7eabfea8377340c8a29e

View File

@ -80,12 +80,6 @@ ifeq ($(USE_VERBOSE_COMPILE),)
USE_VERBOSE_COMPILE = no
endif
# If enabled, this option makes the build process faster by not compiling
# modules not used in the current configuration.
ifeq ($(USE_SMART_BUILD),)
USE_SMART_BUILD = no
endif
ifeq ($(USE_BOOTLOADER),)
USE_BOOTLOADER = no
endif
@ -133,6 +127,20 @@ MAKEFLAGS += ${NUMJOBS}
# Project, sources and paths
#
BOARDS_DIR = $(PROJECT_DIR)/config/boards
include $(PROJECT_DIR)/config/boards/$(PROJECT_BOARD)/board.mk
# If enabled, this option makes the build process faster by not compiling
# modules not used in the current configuration.
# without USE_SMART_BUILD all ChibiOS (including all drivers) are builded. And all drivers includes get included.
ifeq ($(USE_SMART_BUILD),)
USE_SMART_BUILD = yes
endif
ifeq ($(CONFDIR),)
CONFDIR = $(PROJECT_DIR)/config/stm32f4ems
endif
# Startup files.
include $(CPU_STARTUP_DIR)
# HAL-OSAL files (optional).
@ -153,9 +161,6 @@ ifeq ($(USE_FATFS),yes)
include $(PROJECT_DIR)/ext/fatfs.mk
endif
BOARDS_DIR = $(PROJECT_DIR)/config/boards
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/controllers.mk
@ -172,7 +177,6 @@ ifeq ($(BOOTLOADERINC),)
BOOTLOADERINC= $(PROJECT_DIR)/bootloader/
endif
ifeq ($(USE_BOOTLOADER),yes)
include $(PROJECT_DIR)/bootloader/bootloader.mk
endif
@ -189,7 +193,9 @@ CSRC = $(STARTUPSRC) \
$(PORTSRC) \
$(OSALSRC) \
$(HALSRC) \
$(HALSRC_CONTRIB) \
$(PLATFORMSRC) \
$(PLATFORMSRC_CONTRIB) \
$(BOARDSRC) \
$(BOOTLOADERSRC) \
$(CHIBIOS)/os/ex/ST/lis302dl.c \
@ -275,6 +281,7 @@ INCDIR = $(CHIBIOS)/os/license \
$(HALINC) \
$(HALINC_CONTRIB) \
$(PLATFORMINC) \
$(PLATFORMINC_CONTRIB) \
$(BOARDINC) \
$(BOOTLOADERINC) \
$(CHCPPINC) \

View File

@ -1,5 +1,4 @@
#ifndef BOOTLOADER_H_
#define BOOTLOADER_H_
#pragma once
#ifdef __cplusplus
extern "C" {
@ -13,5 +12,3 @@ int initBootloader(void);
#ifdef __cplusplus
}
#endif
#endif /* BOOTLOADER_H_ */

View File

@ -12,8 +12,14 @@ ifeq ($(DEBUG_LEVEL_OPT),)
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
ifeq ($(CONFDIR),)
CONFDIR = $(PROJECT_DIR)/config/stm32f4ems
endif
# disable some modules to shrink bootloader binary
DDEFS += -DHAL_USE_ADC=FALSE -DHAL_USE_CAN=FALSE -DHAL_USE_EXT=FALSE -DHAL_USE_GPT=FALSE -DHAL_USE_I2C=FALSE -DHAL_USE_ICU=FALSE -DHAL_USE_PWM=FALSE -DHAL_USE_RTC=FALSE -DHAL_USE_I2C=FALSE
#disable ChibiOS flsah driver and prevent header from include
DDEFS += -DHAL_USE_FLASH=FALSE
# disable USB (The bootloader has currently UART support only)
DDEFS += -DEFI_USB_SERIAL=FALSE -DHAL_USE_SERIAL_USB=FALSE -DHAL_USE_USB=FALSE -DHAL_USE_USB_MSD=FALSE
@ -71,7 +77,7 @@ endif
# If enabled, this option makes the build process faster by not compiling
# modules not used in the current configuration.
ifeq ($(USE_SMART_BUILD),)
USE_SMART_BUILD = no
USE_SMART_BUILD = yes
endif
#

View File

@ -2,7 +2,7 @@
#include "hardware.h"
#include "efi_gpio.h"
#include "flash.h"
#include "flash_int.h"
#include "dfu.h"
@ -165,7 +165,7 @@ static void dfuHandleRead(void) {
if (isInVirtualPageBuffer(addr))
memcpy(buffer, (uint8_t *)addr, numBytes);
else
flashRead(addr, (char *)buffer, numBytes);
intFlashRead(addr, (char *)buffer, numBytes);
// transmit data
sr5WriteData(&blTsChannel, (uint8_t *)buffer, numBytes);
@ -197,7 +197,7 @@ static void dfuHandleWrite(void) {
if (isInVirtualPageBuffer(addr))
memcpy((uint8_t *)addr, (buffer + 1), numBytes);
else
flashWrite(addr, (const char *)(buffer + 1), numBytes);
intFlashWrite(addr, (const char *)(buffer + 1), numBytes);
// we're done!
sendByte(DFU_ACK_BYTE);
@ -233,7 +233,7 @@ static void dfuHandleErase(void) {
continue;
}
// erase sector
flashSectorErase(sectorIdx);
intFlashSectorErase(sectorIdx);
}
sendByte(DFU_ACK_BYTE);

View File

@ -1,5 +1,4 @@
#ifndef DFU_H_
#define DFU_H_
#pragma once
#include "tunerstudio_io.h"
@ -51,5 +50,3 @@ void dfuJumpToApp(uint32_t addr);
ts_channel_s *getTsChannel();
#endif /* DFU_H_ */

View File

@ -9,8 +9,6 @@
* The whole idea of bootloader is to make it as small as possible. And reasonably independent.
*/
int maxNesting = 0;
void chDbgPanic3(const char */*msg*/, const char * /*file*/, int /*line*/) {
}

View File

@ -10,4 +10,4 @@ set EFI_FATAL_ERROR_PIN=
set BUILDDIR=
set DEBUG_LEVEL_OPT=
set USE_FATFS=
set USE_SMART_BUILD=

View File

@ -13,8 +13,7 @@
#include "engine_configuration.h"
#include "smart_gpio.h"
EXTERN_ENGINE
;
EXTERN_ENGINE;
static void vag_18_Turbo(DECLARE_ENGINE_PARAMETER_SIGNATURE) {
}

View File

@ -0,0 +1,11 @@
cd ../../..
set PROJECT_BOARD=microrusefi
set PROJECT_CPU=ARCH_STM32F4
set DEFAULT_ENGINE_TYPE = -DDEFAULT_ENGINE_TYPE=BMW_M73_MRE_SLAVE
set EXTRA_PARAMS=-DDUMMY -DEFI_CANBUS_SLAVE=TRUE
call config/boards/common_make.bat

View File

@ -14,6 +14,7 @@ ifeq ($(PROJECT_CPU),ARCH_STM32F4)
else
MCU_DEFS = -DSTM32F767xx
BOARDSRC = $(CHIBIOS)/os/hal/boards/ST_NUCLEO144_F767ZI/board.c
CONFDIR=config/stm32f7ems
BOARDINC = $(BOARDS_DIR)/nucleo_f767 # For board.h
BOARDINC += $(PROJECT_DIR)/config/stm32f7ems # efifeatures/halconf/chconf.h
LDSCRIPT= $(BOARDS_DIR)/nucleo_f767/STM32F76xxI.ld

View File

@ -4,6 +4,13 @@
*
* @brief Configuration defaults for the microRusefi board
*
* MICRO_RUS_EFI
* set engine_type 60
*
* MRE_BOARD_TEST
* set engine_type 30
*
*
* See https://github.com/rusefi/rusefi_documentation/wiki/Hardware_microRusEfi_wiring
*
* @author Matthew Kennedy, (c) 2019
@ -18,6 +25,15 @@
EXTERN_ENGINE;
static const ConfigOverrides configOverrides = {
.canTxPin = GPIOB_6,
.canRxPin = GPIOB_12,
};
const ConfigOverrides& getConfigOverrides() {
return configOverrides;
}
static void setInjectorPins() {
engineConfiguration->injectionPins[0] = GPIOE_14;
engineConfiguration->injectionPins[1] = GPIOE_13;
@ -65,12 +81,12 @@ static void setupVbatt() {
engineConfiguration->analogInputDividerCoefficient = 2.5f / 1.5f;
*/
// 6.8k high side/10k low side = 1.6667 ratio divider
// 6.8k high side/10k low side = 1.68 ratio divider
engineConfiguration->analogInputDividerCoefficient = 16.8f / 10.0f;
// set vbatt_divider 8.16
// R139=39k high side/R141=10k low side multiplied by above analogInputDividerCoefficient = 8.166666f
engineConfiguration->vbattDividerCoeff = (49.0f / 10.0f);
// set vbatt_divider 8.23
// R139=39k high side/R141=10k low side multiplied by above analogInputDividerCoefficient = 8.232f
engineConfiguration->vbattDividerCoeff = (49.0f / 10.0f) * engineConfiguration->analogInputDividerCoefficient;
engineConfiguration->vbattAdcChannel = EFI_ADC_11;
engineConfiguration->adcVcc = 3.29f;
@ -103,25 +119,15 @@ static void setupEtb() {
engineConfiguration->etbIo[0].controlPin1 = GPIOC_7;
// DIR pin
engineConfiguration->etbIo[0].directionPin1 = GPIOA_8;
// set_fsio_output_pin 7 PC8
#if EFI_FSIO
// set_rpn_expression 8 "1"
// disable ETB by default
setFsio(7, GPIOC_8, "1" PASS_CONFIG_PARAMETER_SUFFIX);
// enable ETB
// set_rpn_expression 8 "0"
//setFsio(7, GPIOC_8, "0" PASS_CONFIG_PARAMETER_SUFFIX);
#endif /* EFI_FSIO */
// Disable pin
engineConfiguration->etbIo[0].disablePin = GPIOC_8;
// Unused
engineConfiguration->etbIo[0].directionPin2 = GPIO_UNASSIGNED;
// set_analog_input_pin pps PA7
// EFI_ADC_7: "31 - AN volt 3" - PA7
// engineConfiguration->throttlePedalPositionAdcChannel = EFI_ADC_7;
// Unused
engineConfiguration->etbIo[0].directionPin2 = GPIO_UNASSIGNED;
// we only have pwm/dir, no dira/dirb
engineConfiguration->etb_use_two_wires = false;

View File

@ -23,9 +23,9 @@ outputs:
# TLE8888 high current low side: VVT2 TLE8888_IN9 / TLE8888_OUT5
GPIOE_10: "3 - Lowside 2"
# TLE8888 half bridges (pushpull, lowside, or high-low) TLE8888_IN11 / TLE8888_OUT21
# TLE8888 half bridges (pushpull, lowside, or high-low) TLE8888_IN11 / TLE8888_OUT21#91
GPIOE_8: "35 - GP Out 1"
# TLE8888 half bridges (pushpull, lowside, or high-low) IN? / TLE8888_OUT22
# TLE8888 half bridges (pushpull, lowside, or high-low) IN? / TLE8888_OUT22#89
# this should work but it does not GPIOE_7: "34 - GP Out 2"
TLE8888_PIN_22: "34 - GP Out 2"
TLE8888_PIN_23: "33 - GP Out 3"

View File

@ -8,3 +8,6 @@
#define ts_show_etb_pins false
#define ts_show_analog_divider false
#define ts_show_spi false
#define ts_show_sd_card false
#define ts_show_can_pins false
#define ts_show_tunerstudio_port false

View File

@ -0,0 +1,4 @@
https://rusefi.com/forum/viewtopic.php?f=4&t=1538
https://github.com/rusefi/hw_microRusEfi

View File

@ -15,6 +15,7 @@ set EXTRA_PARAMS=-DDUMMY -DSTM32F746xx ^
-DEFI_FATAL_ERROR_PIN=GPIOB_14 ^
-DEFI_TOOTH_LOGGER=FALSE ^
-DRAM_UNUSED_SIZE=10 ^
-DSTATUS_LOGGING_BUFFER_SIZE=1400 ^
-DCCM_UNUSED_SIZE=10
set DEBUG_LEVEL_OPT="-O2"
call config/boards/common_make.bat

View File

@ -4,6 +4,7 @@ BOARDSRC_CPP = $(PROJECT_DIR)/config/boards/NUCLEO_F767/board_configuration.cpp
# Required include directories
BOARDINC = $(PROJECT_DIR)/config/boards/NUCLEO_F746 $(PROJECT_DIR)/config/stm32f7ems
CONFDIR=config/stm32f7ems
LDSCRIPT= $(PROJECT_DIR)/config/boards/NUCLEO_F746/STM32F746xG.ld

View File

@ -12,6 +12,7 @@ set EXTRA_PARAMS=-DDUMMY -DSTM32F767xx ^
-DEFI_INJECTOR_PIN3=GPIO_UNASSIGNED ^
-DFIRMWARE_ID=\"nucleo767\" ^
-DEFI_COMMUNICATION_PIN=GPIOB_7 ^
-DSTATUS_LOGGING_BUFFER_SIZE=1400 ^
-DEFI_FATAL_ERROR_PIN=GPIOB_14 ^
-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

View File

@ -4,6 +4,7 @@ BOARDSRC_CPP = $(PROJECT_DIR)/config/boards/nucleo_f767/board_configuration.cpp
# Required include directories
BOARDINC = $(PROJECT_DIR)/config/boards/nucleo_f767 $(PROJECT_DIR)/config/stm32f7ems
CONFDIR=config/stm32f7ems
LDSCRIPT= $(PROJECT_DIR)/config/boards/nucleo_f767/STM32F76xxI.ld

View File

@ -258,7 +258,6 @@ void setBoardConfigurationOverrides(void) {
//engineConfiguration->isCJ125Enabled = true;
engineConfiguration->isCJ125Enabled = false;
engineConfiguration->canDeviceMode = CD_USE_CAN1;
engineConfiguration->canTxPin = GPIOB_9;
engineConfiguration->canRxPin = GPIOB_8;

View File

@ -9,8 +9,7 @@
#include "../../stm32f4ems/efifeatures.h"
#ifndef EFIFEATURES_PROMETHEUS_H_
#define EFIFEATURES_PROMETHEUS_H_
#pragma once
#undef EFI_RTC
#define EFI_RTC FALSE
@ -68,9 +67,6 @@
#define BOARD_TLE8888_COUNT 0
#endif
// todo: move this outside of efifeatures.h
#define BOARD_EXT_GPIOCHIPS (BOARD_TLE6240_COUNT + BOARD_MC33972_COUNT + BOARD_TLE8888_COUNT)
#undef EFI_CONSOLE_TX_PORT
#define EFI_CONSOLE_TX_PORT GPIOA
@ -115,4 +111,3 @@
#define EFI_NARROW_EGO_AVERAGING TRUE
#endif /* EFIFEATURES_PROMETHEUS_H_ */

View File

@ -1,4 +1,5 @@
Prometheus board.
http://rusefi.com/forum/viewtopic.php?f=4&t=1215
https://github.com/andreika-git/rusefi/
https://github.com/andreika-git/prometheus

View File

@ -17,6 +17,7 @@ else
BOARDINC = $(BOARDS_DIR)/nucleo_f767 # For board.h
BOARDINC += $(PROJECT_DIR)/config/stm32f7ems # efifeatures/halconf/chconf.h
LDSCRIPT= $(BOARDS_DIR)/nucleo_f767/STM32F76xxI.ld
CONFDIR=config/stm32f4ems
endif

View File

@ -43,6 +43,15 @@ static const brain_pin_e ignPins[] = {
GPIOG_2,
};
static const ConfigOverrides configOverrides = {
.canTxPin = GPIOD_1,
.canRxPin = GPIOD_0,
};
const ConfigOverrides& getConfigOverrides() {
return configOverrides;
}
static void setInjectorPins() {
copyArray(engineConfiguration->injectionPins, injPins);
engineConfiguration->injectionPinMode = OM_DEFAULT;
@ -86,6 +95,8 @@ static void setupEtb() {
engineConfiguration->etbIo[0].controlPin1 = GPIOD_12;
// DIR pin
engineConfiguration->etbIo[0].directionPin1 = GPIOD_10;
// Disable pin
engineConfiguration->etbIo[0].disablePin = GPIOD_11;
// Unused
engineConfiguration->etbIo[0].directionPin2 = GPIO_UNASSIGNED;
@ -94,25 +105,16 @@ static void setupEtb() {
engineConfiguration->etbIo[1].controlPin1 = GPIOD_13;
// DIR pin
engineConfiguration->etbIo[1].directionPin1 = GPIOD_9;
// Disable pin
engineConfiguration->etbIo[1].disablePin = GPIOD_8;
// Unused
engineConfiguration->etbIo[1].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 setupCanPins() {
engineConfiguration->canTxPin = GPIOD_1;
engineConfiguration->canRxPin = GPIOD_0;
}
static void setupDefaultSensorInputs() {
// trigger inputs
// Digital channel 1 as default - others not set
@ -164,7 +166,6 @@ void setBoardConfigurationOverrides(void) {
setLedPins();
setupVbatt();
setupEtb();
setupCanPins();
// "required" hardware is done - set some reasonable defaults
setupDefaultSensorInputs();

View File

@ -6,3 +6,7 @@
#define ts_show_egt false
#define ts_show_gps false
#define ts_show_analog_divider false
#define ts_show_spi false
#define ts_show_sd_card false
#define ts_show_can_pins false
#define ts_show_tunerstudio_port false

View File

@ -0,0 +1,4 @@
https://rusefi.com/forum/viewtopic.php?f=4&t=1646
https://github.com/mck1117/proteus

View File

@ -1 +1,4 @@
See [misc/jenkins/compile_other_versions/run.bat](misc/jenkins/compile_other_versions/run.bat) which is executed by build server.
See https://rusefi.com/build_server/

File diff suppressed because it is too large Load Diff

View File

@ -34,9 +34,6 @@
#undef BOARD_TLE8888_COUNT
#define BOARD_TLE8888_COUNT 0
#undef BOARD_EXT_GPIOCHIPS
#define BOARD_EXT_GPIOCHIPS (BOARD_TLE6240_COUNT + BOARD_MC33972_COUNT + BOARD_TLE8888_COUNT)
/*
* Board oscillators-related settings.
* NOTE: LSE not fitted.

View File

@ -221,7 +221,6 @@ void setBoardConfigurationOverrides(void) {
#endif
engineConfiguration->isCJ125Enabled = false;
engineConfiguration->canDeviceMode = CD_USE_CAN1;
engineConfiguration->canTxPin = GPIOD_0;
engineConfiguration->canRxPin = GPIOD_1;

View File

@ -9,8 +9,7 @@
#include "../../stm32f7ems/efifeatures.h"
#ifndef EFIFEATURES_SUBARUEJ20G_H_
#define EFIFEATURES_SUBARUEJ20G_H_
#pragma once
/* debug console */
#undef EFI_USE_UART_FOR_CONSOLE
@ -25,10 +24,6 @@
/* do not use serial device for console */
#undef TS_SERIAL_DEVICE
/* additional space for pins on gpioext */
#undef BOARD_EXT_PINREPOPINS
#define BOARD_EXT_PINREPOPINS (16 + 22)
#undef EFI_RTC
#define EFI_RTC FALSE
@ -113,4 +108,3 @@
#define EFI_NARROW_EGO_AVERAGING TRUE
#endif /* EFIFEATURES_SUBARUEJ20G_H_ */

View File

@ -30,8 +30,8 @@
* ECU pin 6: GND ECU
* 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 21: GND BRN BLK CLT sensor (only on first ECU)
* ECU pin 22: IN RED/BRN GRN CLT sensor (only on first ECU)
* 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
@ -39,7 +39,7 @@
* 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
*
* ECU pin 47: IN IAT sensor (only on second ECU)
*
* Plug #4 40 pin
* ECU pin 6: IN start signal from ignition key
@ -79,6 +79,7 @@ void m73engine(DECLARE_CONFIG_PARAMETER_SIGNATURE) {
engineConfiguration->specs.cylindersCount = 12;
engineConfiguration->specs.displacement = 5.4;
engineConfiguration->specs.firingOrder = FO_1_7_5_11_3_9_6_12_2_8_4_10;
CONFIG(isFasterEngineSpinUpEnabled) = true;
engineConfiguration->vvtMode = VVT_FIRST_HALF;
@ -252,7 +253,7 @@ GPIOA_6
*
* white#9 : orange : +5v
* white#17: green : PPS
* white#18: red
* white#18: red : TPS#2
* white#23: black : Sensor Ground
* white#24: red : TPS#1
*
@ -261,7 +262,7 @@ void setEngineBMW_M73_Proteus(DECLARE_CONFIG_PARAMETER_SIGNATURE) {
m73engine(PASS_CONFIG_PARAMETER_SIGNATURE);
// 12 injectors defined in boards/proteus/board_configuration.cpp
// set_analog_input_pin pps pa4
engineConfiguration->throttlePedalPositionAdcChannel = EFI_ADC_4;
// set vbatt_divider 8.16
@ -270,7 +271,8 @@ void setEngineBMW_M73_Proteus(DECLARE_CONFIG_PARAMETER_SIGNATURE) {
engineConfiguration->vbattDividerCoeff = 7.6;
// TPS#2 = Analog volt
// engineConfiguration->tps2_1AdcChannel = EFI_ADC_;
// set_analog_input_pin tps2 pa6
engineConfiguration->tps2_1AdcChannel = EFI_ADC_6;
}

View File

@ -12,7 +12,9 @@
void m73engine(DECLARE_CONFIG_PARAMETER_SIGNATURE);
void setEngineBMW_M73_Frankenso(DECLARE_CONFIG_PARAMETER_SIGNATURE);
// set engine_type 24
void setEngineBMW_M73_Manhattan(DECLARE_CONFIG_PARAMETER_SIGNATURE);
// set engine_type 63
void setEngineBMW_M73_Proteus(DECLARE_CONFIG_PARAMETER_SIGNATURE);
void setEngineBMW_M73_microRusEfi(DECLARE_CONFIG_PARAMETER_SIGNATURE);

View File

@ -30,12 +30,16 @@
* ECU pin 2: OUT ORG injector #4
* ECU pin 6: GND ECU
* ECU pin 15: OUT ORG injector #2
* ECU pin 21: GND BRN BLK CLT sensor (only on first ECU)
* ECU pin 22: IN RED/BRN BLU CLT sensor (only on first ECU)
* ECU pin 27: OUT GRN injector #6
* ECU pin 28: OUT BLU injector #5
* ECU pin 32: IN WHT VR positive crankshaft sensor
* ECU pin 34: IN IAT sensor (only on second ECU)
* ECU pin 40: OUT BRN/BLK GRN injector #3
* ECU pin 41: OUT BRN/WHT BLU injector #1
* ECU pin 46: IN BLK BLU VR negative crankshaft sensor
* ECU pin 47: GND BRN IAT sensor (only on second ECU)
*
* Plug #4 40 pin
* ECU pin 6: IN ORG start signal from ignition key. Custom wiring: pulled-up thermistor wire on MRE
@ -46,9 +50,13 @@
* Plug #5 9 pin
* ECU pin 3: OUT BLK ORG coil signal
* ECU pin 5: GND BRN ground
* ECU pin 6: OUT BLK ORG coil signal
* ECU pin 9: OUT BLK ORG coil signal
*
* BMW_M73_MRE
* set engine_type 104
* BMW_M73_MRE_SLAVE
* set engine_type 105
*
*/
@ -61,7 +69,9 @@ void setEngineBMW_M73_microRusEfi(DECLARE_CONFIG_PARAMETER_SIGNATURE) {
// 13641435991 injector
engineConfiguration->injector.flow = 180; // cc/min, who knows if this number is real - no good source of info
CONFIG(isFasterEngineSpinUpEnabled) = true;
engineConfiguration->globalTriggerAngleOffset = 90;
engineConfiguration->specs.cylindersCount = 6;
engineConfiguration->specs.displacement = 5.4 / 2;
engineConfiguration->specs.firingOrder = FO_1_5_3_6_2_4;
@ -70,10 +80,6 @@ void setEngineBMW_M73_microRusEfi(DECLARE_CONFIG_PARAMETER_SIGNATURE) {
engineConfiguration->injectionMode = IM_BATCH;
// set_analog_input_pin pps PA7
// EFI_ADC_7: "31 - AN volt 3" - PA7
CONFIG(throttlePedalPositionAdcChannel) = EFI_ADC_7;
// enable ETB
// set_rpn_expression 8 "0"
setFsio(7, GPIOC_8, "0" PASS_CONFIG_PARAMETER_SUFFIX);
@ -83,7 +89,8 @@ void setEngineBMW_M73_microRusEfi(DECLARE_CONFIG_PARAMETER_SIGNATURE) {
engineConfiguration->etb.pFactor = 2.00;
engineConfiguration->etb.iFactor = 0.35;
// AN Temp 4, orange wire
// set debug_mode 37
// 22 - AN Temp 4, orange wire
CONFIG(startStopButtonPin) = GPIOA_3;
#if (BOARD_TLE8888_COUNT > 0)
@ -92,6 +99,35 @@ void setEngineBMW_M73_microRusEfi(DECLARE_CONFIG_PARAMETER_SIGNATURE) {
#endif /* BOARD_TLE8888_COUNT */
engineConfiguration->canNbcType = CAN_BUS_NBC_NONE;
#if EFI_CANBUS_SLAVE
engineConfiguration->canReadEnabled = true;
engineConfiguration->canWriteEnabled = false;
#else /* EFI_CANBUS_SLAVE */
// set_analog_input_pin pps PA7
// EFI_ADC_7: "31 - AN volt 3" - PA7
CONFIG(throttlePedalPositionAdcChannel) = EFI_ADC_7;
engineConfiguration->canReadEnabled = false;
engineConfiguration->canWriteEnabled = true;
CONFIG(enableVerboseCanTx) = true;
#endif /* EFI_CANBUS_SLAVE */
// do I have VR wires flipped?
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;
CONFIG(crankingTimingAngle) = 15;
// I am too lazy to add MAP sensor
engineConfiguration->fuelAlgorithm = LM_ALPHA_N;
// set cranking_fuel 15
engineConfiguration->cranking.baseFuel = 15;
//set tps_min 891
CONFIG(tpsMin) = 891;
//set tps_max 177

View File

@ -196,8 +196,6 @@ void setFrankensoConfiguration(DECLARE_CONFIG_PARAMETER_SIGNATURE) {
void setFrankensoBoardTestConfiguration(DECLARE_CONFIG_PARAMETER_SIGNATURE) {
setFrankensoConfiguration(PASS_CONFIG_PARAMETER_SIGNATURE);
engineConfiguration->directSelfStimulation = true; // this engine type is used for board validation
engineConfiguration->triggerSimulatorFrequency = 300;
engineConfiguration->cranking.rpm = 100;
@ -313,8 +311,6 @@ void setTle8888TestConfiguration(DECLARE_CONFIG_PARAMETER_SIGNATURE) {
engineConfiguration->ignitionMode = IM_INDIVIDUAL_COILS;
engineConfiguration->crankingInjectionMode = IM_SEQUENTIAL;
engineConfiguration->directSelfStimulation = true;
#if defined(STM32_HAS_GPIOG) && STM32_HAS_GPIOG
engineConfiguration->ignitionPins[0] = GPIOG_3;
engineConfiguration->ignitionPins[1] = GPIOG_4;
@ -349,11 +345,11 @@ void setTle8888TestConfiguration(DECLARE_CONFIG_PARAMETER_SIGNATURE) {
// SF PF11
#if defined(STM32_HAS_GPIOF) && STM32_HAS_GPIOF
#if EFI_FSIO
setFsio(12, GPIOF_12, "0" PASS_CONFIG_PARAMETER_SUFFIX);
setFsio(14, GPIOF_13, "1" PASS_CONFIG_PARAMETER_SUFFIX);
#endif /* EFI_FSIO */
CONFIG(etbIo[0].directionPin1) = GPIOF_15;
CONFIG(etbIo[0].directionPin2) = GPIOF_14;
CONFIG(etbIo[0].disablePin) = GPIOF_12;
#endif /* STM32_HAS_GPIOF */
CONFIG(etb_use_two_wires) = true;
engineConfiguration->isHip9011Enabled = false;
@ -365,11 +361,11 @@ void setTle8888TestConfiguration(DECLARE_CONFIG_PARAMETER_SIGNATURE) {
// IN2 PE4
// SF PE3
#if EFI_FSIO
setFsio(13, GPIOE_5, "0" PASS_CONFIG_PARAMETER_SUFFIX);
setFsio(15, GPIOE_6, "1" PASS_CONFIG_PARAMETER_SUFFIX);
#endif
CONFIG(etbIo[0].directionPin1) = GPIOE_2;
CONFIG(etbIo[0].directionPin2) = GPIOE_4;
CONFIG(etbIo[0].disablePin) = GPIOE_5;
engineConfiguration->tps1_1AdcChannel = EFI_ADC_3; // PA3
@ -403,8 +399,6 @@ void setTle8888TestConfiguration(DECLARE_CONFIG_PARAMETER_SIGNATURE) {
*/
void mreBoardTest(DECLARE_CONFIG_PARAMETER_SIGNATURE) {
#if (BOARD_TLE8888_COUNT > 0)
engineConfiguration->directSelfStimulation = true; // this engine type is used for board validation
engineConfiguration->debugMode = DBG_TLE8888;
engineConfiguration->triggerSimulatorFrequency = 60;
@ -528,13 +522,25 @@ void setTest33816EngineConfiguration(DECLARE_CONFIG_PARAMETER_SIGNATURE) {
// default spi3sckPin PB3
CONFIG(triggerSimulatorPins[0]) = GPIO_UNASSIGNED;
CONFIG(triggerSimulatorPins[1]) = GPIO_UNASSIGNED;
CONFIG(triggerSimulatorPins[2]) = GPIO_UNASSIGNED;
engineConfiguration->injectionPins[0] = GPIOB_9; // #1
engineConfiguration->injectionPins[1] = GPIOE_2; // #2
engineConfiguration->injectionPins[2] = GPIOB_8; // #3
engineConfiguration->injectionPins[3] = GPIOB_7; // #4
// blue
CONFIG(mc33816_cs) = GPIOD_7;
// green
CONFIG(mc33816_rstb) = GPIOD_5;
CONFIG(mc33816_rstb) = GPIOD_4;
// yellow
CONFIG(mc33816_driven) = GPIOD_6;
CONFIG(mc33816_flag0) = GPIOD_3;
// enable_spi 3
CONFIG(is_enabled_spi_3) = true;
// Wire up spi3
@ -544,5 +550,7 @@ void setTest33816EngineConfiguration(DECLARE_CONFIG_PARAMETER_SIGNATURE) {
CONFIG(isSdCardEnabled) = false;
CONFIG(mc33_hvolt) = 63;
CONFIG(mc33816spiDevice) = SPI_DEVICE_3;
}

View File

@ -265,12 +265,6 @@ void setDodgeNeonNGCEngineConfiguration(DECLARE_CONFIG_PARAMETER_SIGNATURE) {
engineConfiguration->specs.displacement = 1.996;
engineConfiguration->specs.cylindersCount = 4;
engineConfiguration->biQuad.a0 = 0.0000024635293743901;
engineConfiguration->biQuad.a1 = 0.00000492705874878021;
engineConfiguration->biQuad.a2 = 0.0000024635293743901;
engineConfiguration->biQuad.b1 = -1.9968534854;
engineConfiguration->biQuad.b2 = 0.9968633396;
/**
* 77C
* 1200 rpm

View File

@ -5,15 +5,19 @@
* @author Andrey Belomutskiy, (c) 2012-2020
*/
#ifndef CONFIG_ENGINES_MAZDA_MIATA_1_6_H_
#define CONFIG_ENGINES_MAZDA_MIATA_1_6_H_
#pragma once
#include "engine_configuration.h"
/**
* set engine_type 57
*/
void setMiataNA6_VAF_Frankenso(DECLARE_CONFIG_PARAMETER_SIGNATURE);
/**
* set engine_type 41
*/
void setMiataNA6_MAP_Frankenso(DECLARE_CONFIG_PARAMETER_SIGNATURE);
void miataNAcommon(DECLARE_CONFIG_PARAMETER_SIGNATURE);
void setMiataNA6_VAF_MRE(DECLARE_CONFIG_PARAMETER_SIGNATURE);
#endif /* CONFIG_ENGINES_MAZDA_MIATA_1_6_H_ */

View File

@ -195,8 +195,6 @@ static void setMazdaMiataEngineNB2Defaults(DECLARE_CONFIG_PARAMETER_SIGNATURE) {
setCommonNTCSensor(&engineConfiguration->clt, 2700);
setCommonNTCSensor(&engineConfiguration->iat, 2700);
engineConfiguration->nbVvtIndex = 0;
engineConfiguration->auxPidFrequency[0] = 300; // VVT solenoid control
// set idle_position 35
@ -273,7 +271,11 @@ static void setMazdaMiataEngineNB2Defaults(DECLARE_CONFIG_PARAMETER_SIGNATURE) {
// set_whole_ve_map 80
setMazdaMiataNbInjectorLag(PASS_CONFIG_PARAMETER_SIGNATURE);
engineConfiguration->debugMode = DBG_IDLE_CONTROL;
CONFIG(debugTriggerSync) = GPIOD_3;
// engineConfiguration->debugMode = DBG_IDLE_CONTROL;
engineConfiguration->debugMode = DBG_TRIGGER_COUNTERS;
//set idle_offset 30
engineConfiguration->idleRpmPid.offset = 30;
engineConfiguration->idleRpmPid.pFactor = 0.07;
@ -396,7 +398,10 @@ void setMazdaMiata2003EngineConfiguration(DECLARE_CONFIG_PARAMETER_SIGNATURE) {
// see setDefaultIdleParameters
engineConfiguration->adcVcc = 3.3f;
engineConfiguration->vbattDividerCoeff = 9.70f;
engineConfiguration->vbattDividerCoeff = 8.80f;
engineConfiguration->displayLogicLevelsInEngineSniffer = true;
engineConfiguration->useOnlyRisingEdgeForTrigger = true;
// by the way NB2 MAF internal diameter is about 2.5 inches / 63mm
// 1K pull-down to read current from this MAF
@ -420,7 +425,6 @@ void setMazdaMiata2003EngineConfiguration(DECLARE_CONFIG_PARAMETER_SIGNATURE) {
engineConfiguration->tps1_1AdcChannel = EFI_ADC_13; // PC3 blue
engineConfiguration->idleMode = IM_AUTO;
CONFIG(useETBforIdleControl) = true;
// set_analog_input_pin pps PA2
/* a step back - Frankenso does not use ETB
engineConfiguration->throttlePedalPositionAdcChannel = EFI_ADC_2;
@ -461,8 +465,7 @@ void setMazdaMiata2003EngineConfiguration(DECLARE_CONFIG_PARAMETER_SIGNATURE) {
config->crankingFuelCoef[7] = 10;
config->crankingFuelBins[7] = 90;
// engineConfiguration->crankingIACposition = 65;
engineConfiguration->crankingIACposition = 90;
}
/**
@ -500,7 +503,11 @@ static void setMiataNB2_MRE_common(DECLARE_CONFIG_PARAMETER_SIGNATURE) {
engineConfiguration->camInputs[0] = GPIOA_5;
engineConfiguration->useOnlyRisingEdgeForTrigger = false;
engineConfiguration->useTLE8888_hall_mode = true;
/**
* By default "auto detection mode for VR sensor signals" is used
* We know that for short & strange Hall (?) signals like Miata NB2 crank sensor this does not work well above certain RPM.
*/
engineConfiguration->tle8888mode = TL_MANUAL;
// GPIOD_6: "13 - GP Out 6" - selected to +12v
engineConfiguration->alternatorControlPin = GPIOD_6;
@ -559,6 +566,8 @@ static void setMiataNB2_MRE_common(DECLARE_CONFIG_PARAMETER_SIGNATURE) {
void setMiataNB2_MRE_ETB(DECLARE_CONFIG_PARAMETER_SIGNATURE) {
setMiataNB2_MRE_common(PASS_CONFIG_PARAMETER_SIGNATURE);
CONFIG(useETBforIdleControl) = true;
#if EFI_FSIO
// enable ETB
// set_rpn_expression 8 "0"

View File

@ -14,9 +14,22 @@
void setMazdaMiataNbInjectorLag(DECLARE_CONFIG_PARAMETER_SIGNATURE);
void setMazdaMiataNbTpsTps(DECLARE_CONFIG_PARAMETER_SIGNATURE);
/**
* Primary rusEfi test mule https://rusefi.com/forum/viewtopic.php?f=3&t=1095
* MAZDA_MIATA_2003
* set engine_type 47
*/
void setMazdaMiata2003EngineConfiguration(DECLARE_CONFIG_PARAMETER_SIGNATURE);
/**
* race car - NA body and fuel system with NB2 engine
*/
void setMazdaMiata2003EngineConfigurationNaFuelRail(DECLARE_CONFIG_PARAMETER_SIGNATURE);
void setMazdaMiata2003EngineConfigurationBoardTest(DECLARE_CONFIG_PARAMETER_SIGNATURE);
void setMiataNB2_MRE_ETB(DECLARE_CONFIG_PARAMETER_SIGNATURE);
/**
* OEM mechanical throttle body
* set engine_type 11
*/
void setMiataNB2_MRE_MTB(DECLARE_CONFIG_PARAMETER_SIGNATURE);

View File

@ -7,18 +7,19 @@
#include "me7pnp.h"
#include "global.h"
#include "engine.h"
#include "engine_math.h"
#include "allsensors.h"
#include "fsio_impl.h"
#include "engine_configuration.h"
#include "smart_gpio.h"
#include "cj125.h"
EXTERN_ENGINE
;
EXTERN_ENGINE;
void vag_18_Turbo(DECLARE_ENGINE_PARAMETER_SIGNATURE) {
/**
* set engine_type 102
*/
void vag_18_Turbo(DECLARE_CONFIG_PARAMETER_SIGNATURE) {
//Base Engine Settings
@ -56,8 +57,6 @@ void vag_18_Turbo(DECLARE_ENGINE_PARAMETER_SIGNATURE) {
engineConfiguration->afr.hwChannel = EFI_ADC_NONE;
engineConfiguration->vbattAdcChannel = EFI_ADC_4;
engineConfiguration->vbattDividerCoeff = ((float) (10.0 + 33)) / 10 * 2;
engineConfiguration->cj125ur = EFI_ADC_11;
engineConfiguration->cj125ua = EFI_ADC_12;
engineConfiguration->mafAdcChannel = EFI_ADC_8;
//CAN Settings
@ -65,7 +64,7 @@ void vag_18_Turbo(DECLARE_ENGINE_PARAMETER_SIGNATURE) {
engineConfiguration->canNbcType = CAN_BUS_NBC_VAG;
engineConfiguration->canReadEnabled = true;
engineConfiguration->canWriteEnabled = true;
engineConfiguration->canDeviceMode = CD_USE_CAN1;
engineConfiguration->canTxPin = GPIOB_6;
engineConfiguration->canRxPin = GPIOB_12;
@ -93,9 +92,10 @@ void vag_18_Turbo(DECLARE_ENGINE_PARAMETER_SIGNATURE) {
//SPI Settings
engineConfiguration->is_enabled_spi_1 = true;
engineConfiguration->is_enabled_spi_2 = true;
engineConfiguration->is_enabled_spi_3 = false;
engineConfiguration->cj125SpiDevice = SPI_DEVICE_2;
cj125defaultPinout(PASS_CONFIG_PARAMETER_SIGNATURE);
engineConfiguration->cj125ur = EFI_ADC_11;
engineConfiguration->cj125CsPin = GPIOB_11;
//Digital Inputs/Outputs
@ -114,10 +114,10 @@ void vag_18_Turbo(DECLARE_ENGINE_PARAMETER_SIGNATURE) {
engineConfiguration->brakePedalPin = GPIOE_10;
engineConfiguration->camInputs[0] = GPIOA_2;
#if defined(STM32_HAS_GPIOG) && STM32_HAS_GPIOG
engineConfiguration->triggerInputPins[0] = GPIOG_7;
// engineConfiguration->triggerInputPins[0] = GPIOG_7;
#endif /* STM32_HAS_GPIOF */
#if defined(STM32_HAS_GPIOF) && STM32_HAS_GPIOF
engineConfiguration->vehicleSpeedSensorInputPin = GPIOF_14;
// engineConfiguration->vehicleSpeedSensorInputPin = GPIOF_14;
#endif /* STM32_HAS_GPIOF */
@ -134,7 +134,6 @@ void vag_18_Turbo(DECLARE_ENGINE_PARAMETER_SIGNATURE) {
#if EFI_FSIO
#if defined(STM32_HAS_GPIOF) && STM32_HAS_GPIOF
setFsio (12, GPIOF_12, "0" PASS_CONFIG_PARAMETER_SUFFIX);
setFsio (14, GPIOF_13, "1" PASS_CONFIG_PARAMETER_SUFFIX);
#endif /* STM32_HAS_GPIOF */
setFsioExt (3, GPIOE_0, "0.15 90 coolant 120 min max 90 - 30 / 0.8 * +", 25 PASS_CONFIG_PARAMETER_SUFFIX);
@ -144,15 +143,16 @@ void vag_18_Turbo(DECLARE_ENGINE_PARAMETER_SIGNATURE) {
#if defined(STM32_HAS_GPIOF) && STM32_HAS_GPIOF
CONFIG(etbIo[0].directionPin1) = GPIOF_15;
CONFIG(etbIo[0].directionPin2) = GPIOF_14;
CONFIG(etbIo[0].disablePin) = GPIOF_12;
#endif /* STM32_HAS_GPIOF */
engineConfiguration->isHip9011Enabled = false;
#if EFI_FSIO
setFsio (13, GPIOE_5, "0" PASS_CONFIG_PARAMETER_SUFFIX);
setFsio (15, GPIOE_6, "1" PASS_CONFIG_PARAMETER_SUFFIX);
#endif
CONFIG(etbIo[1].directionPin1) = GPIOE_2;
CONFIG(etbIo[1].directionPin2) = GPIOE_4;
CONFIG(etbIo[1].disablePin) = GPIOE_5;
engineConfiguration->etb.pFactor = 1.07;
engineConfiguration->etb.iFactor = 0.18;

View File

@ -1,15 +1,13 @@
/*
* me7pnp.h
* @file me7pnp.h
*
* Created on: 1. mai 2019
* Author: Ola
*/
#ifndef CONFIG_ENGINES_ME7PNP_H_
#define CONFIG_ENGINES_ME7PNP_H_
#pragma once
#include "engine_configuration.h"
void vag_18_Turbo(DECLARE_CONFIG_PARAMETER_SIGNATURE);
#endif /* CONFIG_ENGINES_ME7PNP_H_ */

View File

@ -4,11 +4,10 @@
* @date Aug 5, 2014
* @author Andrey Belomutskiy, (c) 2012-2020
*/
#ifndef MITSUBISHI_H_
#define MITSUBISHI_H_
#pragma once
#include "engine_configuration.h"
void setMitsubishiConfiguration(DECLARE_CONFIG_PARAMETER_SIGNATURE);
#endif /* MITSUBISHI_H_ */

View File

@ -4,12 +4,9 @@
* @date Jun 27, 2014
* @author Andrey Belomutskiy, (c) 2012-2020
*/
#ifndef ROVER_V8_H_
#define ROVER_V8_H_
#pragma once
#include "engine_configuration.h"
void setFrankenstein_01_LCD(engine_configuration_s *engineConfiguration);
void setRoverv8(DECLARE_CONFIG_PARAMETER_SIGNATURE);
#endif /* ROVER_V8_H_ */

View File

@ -4,11 +4,9 @@
* @date Jan 26, 2015
* @author Andrey Belomutskiy, (c) 2012-2020
*/
#ifndef CONFIG_ENGINES_SACHS_H_
#define CONFIG_ENGINES_SACHS_H_
#pragma once
#include "engine_configuration.h"
void setSachs(DECLARE_CONFIG_PARAMETER_SIGNATURE);
#endif /* CONFIG_ENGINES_SACHS_H_ */

View File

@ -4,12 +4,8 @@
* @date Sep 14, 2014
* @author Andrey Belomutskiy, (c) 2012-2020
*/
#ifndef SUBARU_H_
#define SUBARU_H_
#include "engine_configuration.h"
void setSubaru2003Wrx(DECLARE_CONFIG_PARAMETER_SIGNATURE);
void setSubaruEJ20GDefaults(DECLARE_CONFIG_PARAMETER_SIGNATURE);
#endif /* SUBARU_H_ */

View File

@ -15,6 +15,7 @@
EXTERN_CONFIG;
// VW_ABA
void setVwAba(DECLARE_CONFIG_PARAMETER_SIGNATURE) {
setFrankensoConfiguration(PASS_CONFIG_PARAMETER_SIGNATURE);

View File

@ -762,9 +762,9 @@ void chDbgPanic3(const char *msg, const char * file, int line);
* so that it would not crash the error handler in case of stack issues
*/
#if CH_DBG_SYSTEM_STATE_CHECK
#define hasFatalError() (ch.dbg.panic_msg != NULL)
#define hasOsPanicError() (ch.dbg.panic_msg != NULL)
#else
#define hasFatalError() (FALSE)
#define hasOsPanicError() (FALSE)
#endif

View File

@ -12,6 +12,9 @@
#define EFI_GPIO_HARDWARE TRUE
#define EFI_BOOST_CONTROL TRUE
#define EFI_LAUNCH_CONTROL FALSE
#define EFI_FSIO TRUE
#ifndef EFI_CDM_INTEGRATION
@ -143,12 +146,6 @@
#define BOARD_TLE8888_COUNT 1
#endif
// todo: move this outside of efifeatures.h
#define BOARD_EXT_GPIOCHIPS (BOARD_TLE6240_COUNT + BOARD_MC33972_COUNT + BOARD_TLE8888_COUNT)
// todo: move this outside of efifeatures.h
#define BOARD_EXT_PINREPOPINS 24
#define EFI_ANALOG_SENSORS TRUE
#ifndef EFI_MAX_31855
@ -287,10 +284,8 @@
// todo: most of this should become configurable
// todo: switch to continues ADC conversion for slow ADC?
// https://github.com/rusefi/rusefi/issues/630
// todo: switch to continues ADC conversion for fast ADC?
#define EFI_INTERNAL_FAST_ADC_PWM &PWMD4
#define EFI_INTERNAL_FAST_ADC_GPT &GPTD6
#define EFI_SPI1_AF 5

View File

@ -30,6 +30,20 @@
#include "mcuconf.h"
/* THIS IS HACK: to allow smooth transition to ChibiOS with ELF support we
* need to disable hal_flash.h until we move to ChibiOS EFL driver.
* hal_flash.h in ChibiOS has definitions that conflict with current RusEFI
* flash driver.
* but it is included unconditionaly from hal.h */
#define HAL_FLASH_H
/**
* @brief Enables the FLASH subsystem.
*/
#if !defined(HAL_USE_FLASH) || defined(__DOXYGEN__)
#define HAL_USE_FLASH FALSE
#endif
/**
* @brief Enables the PAL subsystem.
*/
@ -120,7 +134,7 @@
* @brief Enables the PWM subsystem.
*/
#if !defined(HAL_USE_PWM) || defined(__DOXYGEN__)
#define HAL_USE_PWM TRUE
#define HAL_USE_PWM FALSE
#endif
/**

View File

@ -180,7 +180,7 @@
#define STM32_GPT_USE_TIM3 FALSE
#define STM32_GPT_USE_TIM4 FALSE
#define STM32_GPT_USE_TIM5 TRUE
#define STM32_GPT_USE_TIM6 FALSE
#define STM32_GPT_USE_TIM6 TRUE
#define STM32_GPT_USE_TIM7 FALSE
#define STM32_GPT_USE_TIM8 FALSE
#define STM32_GPT_USE_TIM9 FALSE
@ -272,9 +272,7 @@
#define STM32_PWM_USE_TIM1 FALSE
#define STM32_PWM_USE_TIM2 FALSE
#define STM32_PWM_USE_TIM3 FALSE
// maybe even swithc this one to software timer?
// todo: https://github.com/rusefi/rusefi/issues/630 ?
#define STM32_PWM_USE_TIM4 TRUE
#define STM32_PWM_USE_TIM4 FALSE
#define STM32_PWM_USE_TIM5 FALSE
#define STM32_PWM_USE_TIM8 FALSE
#define STM32_PWM_USE_TIM9 FALSE

View File

@ -764,9 +764,9 @@ void chDbgPanic3(const char *msg, const char * file, int line);
* so that it would not crash the error handler in case of stack issues
*/
#if CH_DBG_SYSTEM_STATE_CHECK
#define hasFatalError() (ch.dbg.panic_msg != NULL)
#define hasOsPanicError() (ch.dbg.panic_msg != NULL)
#else
#define hasFatalError() (FALSE)
#define hasOsPanicError() (FALSE)
#endif

View File

@ -50,8 +50,6 @@
#define BOARD_TLE8888_COUNT 1
#endif
// todo: move this outside of efifeatures.h
#define BOARD_EXT_GPIOCHIPS (BOARD_TLE6240_COUNT + BOARD_MC33972_COUNT + BOARD_TLE8888_COUNT)
#undef EFI_CAN_SUPPORT

View File

@ -30,6 +30,20 @@
#include "mcuconf.h"
/* THIS IS HACK: to allow smooth transition to ChibiOS with ELF support we
* need to disable hal_flash.h until we move to ChibiOS EFL driver.
* hal_flash.h in ChibiOS has definitions that conflict with current RusEFI
* flash driver.
* but it is included unconditionaly from hal.h */
#define HAL_FLASH_H
/**
* @brief Enables the FLASH subsystem.
*/
#if !defined(HAL_USE_FLASH) || defined(__DOXYGEN__)
#define HAL_USE_FLASH FALSE
#endif
/**
* @brief Enables the PAL subsystem.
*/
@ -111,7 +125,7 @@
* @brief Enables the PWM subsystem.
*/
#if !defined(HAL_USE_PWM) || defined(__DOXYGEN__)
#define HAL_USE_PWM TRUE
#define HAL_USE_PWM FALSE
#endif
/**

View File

@ -201,7 +201,7 @@
#define STM32_GPT_USE_TIM3 FALSE
#define STM32_GPT_USE_TIM4 FALSE
#define STM32_GPT_USE_TIM5 TRUE
#define STM32_GPT_USE_TIM6 FALSE
#define STM32_GPT_USE_TIM6 TRUE
#define STM32_GPT_USE_TIM7 FALSE
#define STM32_GPT_USE_TIM8 FALSE
#define STM32_GPT_USE_TIM9 FALSE
@ -283,7 +283,7 @@
#define STM32_PWM_USE_TIM1 FALSE
#define STM32_PWM_USE_TIM2 FALSE
#define STM32_PWM_USE_TIM3 FALSE
#define STM32_PWM_USE_TIM4 TRUE
#define STM32_PWM_USE_TIM4 FALSE
#define STM32_PWM_USE_TIM5 FALSE
#define STM32_PWM_USE_TIM8 FALSE
#define STM32_PWM_USE_TIM9 FALSE

View File

@ -34,8 +34,7 @@ static thread_reference_t btThreadRef = nullptr; // used by thread suspend/resum
static LoggingWithStorage btLogger("bluetooth");
EXTERN_ENGINE
;
EXTERN_ENGINE;
// Main communication code

View File

@ -5,9 +5,7 @@
* @author Andrey Belomutskiy, (c) 2012-2020
*/
#ifndef BLUETOOTH_H_
#define BLUETOOTH_H_
#pragma once
#include "global.h"
#include "tunerstudio_io.h"
@ -44,4 +42,3 @@ void bluetoothCancel(void);
*/
void bluetoothSoftwareDisconnectNotify();
#endif /* BLUETOOTH_H_ */

View File

@ -80,7 +80,7 @@
#include <string.h>
#include "engine_configuration.h"
#include "injector_central.h"
#include "bench_test.h"
#include "svnversion.h"
#include "loggingcentral.h"
#include "status_loop.h"
@ -89,7 +89,7 @@
#if EFI_SIMULATOR
#include "rusEfiFunctionalTest.h"
#endif
#endif /* EFI_SIMULATOR */
#if EFI_TUNER_STUDIO
@ -103,8 +103,7 @@
#endif /* EFI_IDLE_CONTROL */
EXTERN_ENGINE
;
EXTERN_ENGINE;
extern persistent_config_container_s persistentState;
@ -469,7 +468,8 @@ static bool isKnownCommand(char command) {
|| command == TS_CRC_CHECK_COMMAND
|| command == TS_GET_FIRMWARE_VERSION
|| command == TS_PERF_TRACE_BEGIN
|| command == TS_PERF_TRACE_GET_BUFFER;
|| command == TS_PERF_TRACE_GET_BUFFER
|| command == TS_GET_CONFIG_ERROR;
}
// this function runs indefinitely
@ -845,6 +845,9 @@ int tunerStudioHandleCrcCommand(ts_channel_s *tsChannel, char *data, int incomin
break;
#endif /* ENABLE_PERF_TRACE */
case TS_GET_CONFIG_ERROR:
sr5SendResponse(tsChannel, TS_CRC, reinterpret_cast<const uint8_t*>(getFirmwareError()), strlen(getFirmwareError()));
break;
default:
tunerStudioError("ERROR: ignoring unexpected command");
return false;

View File

@ -5,9 +5,7 @@
* @author Andrey Belomutskiy, (c) 2012-2020
*/
#ifndef TUNERSTUDIO_H_
#define TUNERSTUDIO_H_
#pragma once
#include "global.h"
#include "tunerstudio_io.h"
@ -106,5 +104,3 @@ typedef pre_packed struct
} TunerStudioWriteValueRequest;
#endif /* EFI_TUNER_STUDIO */
#endif /* TUNERSTUDIO_H_ */

View File

@ -18,6 +18,16 @@ typedef struct {
uint16_t values[EGT_CHANNEL_COUNT];
} egt_values_s;
enum class TsCalMode : uint8_t {
None = 0,
Tps1Max = 1,
Tps1Min = 2,
EtbKp = 3,
EtbKi = 4,
EtbKd = 5,
};
/**
* At the moment rusEfi does NOT have any code generation around TS output channels, three locations have to be changed manually
* 1) this TunerStudioOutputChannels firmware version of the structure
@ -57,10 +67,11 @@ typedef struct {
unsigned int isIatError : 1; // bit 21
unsigned int isAcSwitchEngaged : 1; // bit 22
unsigned int isTriggerError : 1; // bit 23
unsigned int hasFatalError : 1; // bit 24
unsigned int hasCriticalError : 1; // bit 24
unsigned int isWarnNow : 1; // bit 25
unsigned int unused80b8 : 1; // bit 26
unsigned int isPedalError : 1; // bit 26
unsigned int isKnockChipOk : 1; // bit 27
unsigned int launchTriggered : 1; // bit 28
// RPM, vss
scaled_channel<uint16_t> rpm; // 4
@ -151,15 +162,29 @@ typedef struct {
uint32_t firmwareVersion; // 120
uint32_t tsConfigVersion; // 124
// These two fields indicate to TS that we'd like to set a particular field to a particular value
// We use a maintainConstantValue in TS for each field we'd like to set, like this:
// maintainConstantValue = tpsMax, { (calibrationMode == 1 ) ? calibrationValue : tpsMax }
// maintainConstantValue = tpsMin, { (calibrationMode == 2 ) ? calibrationValue : tpsMin }
// When the mode is set to a particular value, TS will copy the calibrationValue in to the specified field.
//
// With this simple construct, the ECU can send any number of internally computed configuration fields
// back to TunerStudio, getting around the problem of setting values on the controller without TS's knowledge.
// The ECU simply has to sequentially set a mode/value, wait briefly, then repeat until all the values
// it wants to send have been sent.
float calibrationValue; // 128
TsCalMode calibrationMode; // 132
uint8_t padding[3]; // 133-135
// Errors
int totalTriggerErrorCounter; // 128
int orderingErrorCounter; // 132
int16_t warningCounter; // 136
int16_t lastErrorCode; // 138
int16_t recentErrorCodes[8]; // 140
int totalTriggerErrorCounter; // 136
int orderingErrorCounter; // 140
int16_t warningCounter; // 144
int16_t lastErrorCode; // 146
int16_t recentErrorCodes[8]; // 148-162
// Debug
float debugFloatField1; // 156
float debugFloatField1; // 164
float debugFloatField2;
float debugFloatField3;
float debugFloatField4;
@ -170,17 +195,24 @@ typedef struct {
int debugIntField2;
int debugIntField3;
int16_t debugIntField4;
int16_t debugIntField5; // 198
int16_t debugIntField5; // 206
// accelerometer
int16_t accelerationX; // 200
int16_t accelerationY; // 202
int16_t accelerationX; // 208
int16_t accelerationY; // 210
// EGT
egt_values_s egtValues; // 204
scaled_percent throttle2Position; // 220
egt_values_s egtValues; // 212
uint8_t unusedAtTheEnd[18]; // we have some unused bytes to allow compatible TS changes
scaled_percent throttle2Position; // 228
scaled_voltage rawTps1Primary; // 230
scaled_voltage rawPpsPrimary; // 232
scaled_voltage rawClt; // 234
scaled_voltage rawIat; // 236
scaled_voltage rawOilPressure; // 238
uint8_t unusedAtTheEnd[4]; // we have some unused bytes to allow compatible TS changes
// Temporary - will remove soon
TsDebugChannels* getDebugChannels() {

View File

@ -5,11 +5,10 @@
* @author Andrey Belomutskiy, (c) 2012-2020
*/
#include "global.h"
#include "engine.h"
#include "os_access.h"
#include "tunerstudio_io.h"
#include "console_io.h"
#include "engine.h"
#if EFI_SIMULATOR
#include "rusEfiFunctionalTest.h"
#endif

View File

@ -4,9 +4,8 @@
* @date Mar 8, 2015
* @author Andrey Belomutskiy, (c) 2012-2020
*/
#ifndef CONSOLE_TUNERSTUDIO_TUNERSTUDIO_IO_H_
#define CONSOLE_TUNERSTUDIO_TUNERSTUDIO_IO_H_
#pragma once
#include "global.h"
#if EFI_PROD_CODE
@ -68,6 +67,7 @@ typedef struct {
#define TS_PAGE_COMMAND 'P' // 0x50
#define TS_COMMAND_F 'F' // 0x46
#define TS_GET_FIRMWARE_VERSION 'V' // versionInfo
#define TS_GET_CONFIG_ERROR 'e' // returns getFirmwareError()
// High speed logger commands
#define TS_SET_LOGGER_MODE 'l'
@ -108,4 +108,3 @@ int sr5ReadData(ts_channel_s *tsChannel, uint8_t * buffer, int size);
int sr5ReadDataTimeout(ts_channel_s *tsChannel, uint8_t * buffer, int size, int timeout);
bool sr5IsReady(ts_channel_s *tsChannel);
#endif /* CONSOLE_TUNERSTUDIO_TUNERSTUDIO_IO_H_ */

View File

@ -18,7 +18,6 @@
* If not, see <http://www.gnu.org/licenses/>.
*/
#include "global.h"
#include "engine.h"
#include "console_io.h"
#include "os_util.h"
@ -39,9 +38,6 @@ extern SerialUSBDriver SDU1;
// 10 seconds
#define CONSOLE_WRITE_TIMEOUT 10000
int lastWriteSize;
int lastWriteActual;
static bool isSerialConsoleStarted = false;
static event_listener_t consoleEventListener;
@ -253,11 +249,8 @@ void consolePutChar(int x) {
}
void consoleOutputBuffer(const uint8_t *buf, int size) {
lastWriteSize = size;
#if !EFI_UART_ECHO_TEST_MODE
lastWriteActual = chnWriteTimeout(getConsoleChannel(), buf, size, CONSOLE_WRITE_TIMEOUT);
// if (r != size)
// firmwareError(OBD_PCM_Processor_Fault, "Partial console write");
chnWriteTimeout(getConsoleChannel(), buf, size, CONSOLE_WRITE_TIMEOUT);
#endif /* EFI_UART_ECHO_TEST_MODE */
}

View File

@ -4,9 +4,8 @@
* @date Dec 29, 2012
* @author Andrey Belomutskiy, (c) 2012-2020
*/
#ifndef CONSOLE_IO_H_
#define CONSOLE_IO_H_
#pragma once
#ifdef __cplusplus
extern "C"
{
@ -42,4 +41,3 @@ bool isCommandLineConsoleReady(void);
#define isCommandLineConsoleReady() true
#endif
#endif /* CONSOLE_IO_H_ */

View File

@ -29,7 +29,7 @@
static LoggingWithStorage logger("console");
static void myfatal(void) {
static void testCritical(void) {
chDbgCheck(0);
}
@ -46,11 +46,18 @@ static void sayNothing(void) {
}
static void sayHello(void) {
scheduleMsg(&logger, "*** rusEFI (c) Andrey Belomutskiy 2012-2019. All rights reserved.");
scheduleMsg(&logger, "*** rusEFI LLC (c) 2012-2020. All rights reserved.");
scheduleMsg(&logger, "rusEFI v%d@%s", getRusEfiVersion(), VCS_VERSION);
scheduleMsg(&logger, "*** Chibios Kernel: %s", CH_KERNEL_VERSION);
scheduleMsg(&logger, "*** Compiled: " __DATE__ " - " __TIME__ "");
scheduleMsg(&logger, "COMPILER=%s", __VERSION__);
#if defined(STM32F4) || defined(STM32F7)
uint32_t *uid = ((uint32_t *)UID_BASE);
scheduleMsg(&logger, "UID=%x %x %x", uid[0], uid[1], uid[2]);
#endif
#ifdef CH_FREQUENCY
scheduleMsg(&logger, "CH_FREQUENCY=%d", CH_FREQUENCY);
#endif
@ -183,7 +190,7 @@ void initializeConsole(Logging *sharedLogger) {
addConsoleAction("reset", scheduleReset);
#endif
addConsoleAction("fatal", myfatal);
addConsoleAction("critical", testCritical);
addConsoleAction("error", myerror);
addConsoleAction("threadsinfo", cmd_threads);
}

View File

@ -6,12 +6,9 @@
* @author Andrey Belomutskiy, (c) 2012-2020
*/
#ifndef RFICONSOLE_H_
#define RFICONSOLE_H_
#pragma once
#include "datalogging.h"
void initializeConsole(Logging *sharedLogger);
void print(const char *fmt, ...);
#endif /* RFICONSOLE_H_ */

View File

@ -102,7 +102,6 @@ extern WaveChart waveChart;
int warningEnabled = true;
extern bool hasFirmwareErrorFlag;
extern int maxTriggerReentraint;
extern uint32_t maxLockedDuration;
@ -172,8 +171,7 @@ static void reportSensorI(Logging *log, const char *caption, const char *units,
#endif /* EFI_FILE_LOGGING */
}
EXTERN_ENGINE
;
EXTERN_ENGINE;
static char buf[6];
@ -206,18 +204,7 @@ static void printSensors(Logging *log) {
#endif
// why do we still send data into console in text mode?
if (hasCltSensor()) {
reportSensorF(log, "CLT", "C", getCoolantTemperature(), 2); // log column #4
}
SensorResult tps = Sensor::get(SensorType::Tps1);
if (tps) {
reportSensorF(log, "TPS", "%", tps.Value, 2); // log column #5
}
if (hasIatSensor()) {
reportSensorF(log, "IAT", "C", getIntakeAirTemperature(), 2); // log column #7
}
Sensor::showAllSensorInfo(log);
if (hasVBatt(PASS_ENGINE_PARAMETER_SIGNATURE)) {
reportSensorF(log, GAUGE_NAME_VBAT, "V", getVBatt(PASS_ENGINE_PARAMETER_SIGNATURE), 2); // log column #6
@ -323,24 +310,20 @@ static void printSensors(Logging *log) {
reportSensorF(log, GAUGE_NAME_TIMING_ADVANCE, "deg", engine->engineState.timingAdvance, 2);
if (hasPedalPositionSensor(PASS_ENGINE_PARAMETER_SIGNATURE)) {
// 136
reportSensorF(log, GAUGE_NAME_THROTTLE_PEDAL, "%", getPedalPosition(PASS_ENGINE_PARAMETER_SIGNATURE), 2);
}
reportSensorF(log, GAUGE_NAME_THROTTLE_PEDAL, "%", Sensor::get(SensorType::AcceleratorPedal).value_or(0), 2);
floatms_t fuelBase = getBaseFuel(rpm PASS_ENGINE_PARAMETER_SUFFIX);
reportSensorF(log, GAUGE_NAME_FUEL_BASE, "ms", fuelBase, 2);
reportSensorF(log, GAUGE_NAME_FUEL_LAST_INJECTION, "ms", ENGINE(actualLastInjection), 2);
reportSensorF(log, GAUGE_NAME_INJECTOR_LAG, "ms", engine->engineState.running.injectorLag, 2);
reportSensorF(log, GAUGE_NAME_FUEL_RUNNING, "ms", ENGINE(engineState.running.fuel), 2);
// 268
reportSensorF(log, GAUGE_NAME_FUEL_PID_CORR, "ms", ENGINE(engineState.running.pidCorrection), 2);
floatms_t fuelBase = getBaseFuel(rpm PASS_ENGINE_PARAMETER_SUFFIX);
reportSensorF(log, GAUGE_NAME_FUEL_BASE, "ms", fuelBase, 2);
reportSensorF(log, GAUGE_NAME_FUEL_LAST_INJECTION, "ms", ENGINE(actualLastInjection), 2);
reportSensorF(log, GAUGE_NAME_INJECTOR_LAG, "ms", engine->engineState.running.injectorLag, 2);
reportSensorF(log, GAUGE_NAME_FUEL_RUNNING, "ms", ENGINE(engineState.running.fuel), 2);
// 268
reportSensorF(log, GAUGE_NAME_FUEL_PID_CORR, "ms", ENGINE(engineState.running.pidCorrection), 2);
reportSensorF(log, GAUGE_NAME_FUEL_WALL_AMOUNT, "v", ENGINE(wallFuel[0]).getWallFuel(), 2);
reportSensorF(log, GAUGE_NAME_FUEL_WALL_CORRECTION, "v", ENGINE(wallFuel[0]).wallFuelCorrection, 2);
reportSensorF(log, GAUGE_NAME_FUEL_WALL_AMOUNT, "v", ENGINE(wallFuel[0]).getWallFuel(), 2);
reportSensorF(log, GAUGE_NAME_FUEL_WALL_CORRECTION, "v", ENGINE(wallFuel[0]).wallFuelCorrection, 2);
reportSensorI(log, GAUGE_NAME_VERSION, "#", getRusEfiVersion());
reportSensorI(log, GAUGE_NAME_VERSION, "#", getRusEfiVersion());
#if EFI_VEHICLE_SPEED
if (hasVehicleSpeedSensor()) {
@ -370,9 +353,6 @@ static void printSensors(Logging *log) {
reportSensorF(log, GAUGE_NAME_DWELL_DUTY, "%", getCoilDutyCycle(rpm PASS_ENGINE_PARAMETER_SUFFIX), 2);
// debugFloat(&logger, "tch", getTCharge1(tps), 2);
for (int i = 0;i<FSIO_ANALOG_INPUT_COUNT;i++) {
if (engineConfiguration->fsioAdc[i] != EFI_ADC_NONE) {
strcpy(buf, "adcX");
@ -498,7 +478,7 @@ void updateDevConsoleState(void) {
#if EFI_PROD_CODE
// todo: unify with simulator!
if (hasFirmwareError()) {
scheduleMsg(&logger, "FATAL error: %s", getFirmwareError());
scheduleMsg(&logger, "%s error: %s", CRITICAL_PREFIX, getFirmwareError());
warningEnabled = false;
scheduleLogging(&logger);
return;
@ -585,14 +565,12 @@ static OutputPin *leds[] = { &enginePins.warningLedPin, &enginePins.runningLedPi
static void initStatusLeds(void) {
enginePins.communicationLedPin.initPin("led: comm status", engineConfiguration->communicationLedPin);
// we initialize this here so that we can blink it on start-up
enginePins.checkEnginePin.initPin("MalfunctionIndicator", CONFIG(malfunctionIndicatorPin), &CONFIG(malfunctionIndicatorPinMode));
enginePins.checkEnginePin.initPin("Check engine light", CONFIG(malfunctionIndicatorPin), &CONFIG(malfunctionIndicatorPinMode));
enginePins.warningLedPin.initPin("led: warning status", engineConfiguration->warningLedPin);
enginePins.runningLedPin.initPin("led: running status", engineConfiguration->runningLedPin);
enginePins.debugTriggerSync.initPin("debug: sync", CONFIG(debugTriggerSync));
enginePins.debugTimerCallback.initPin("debug: timer callback", CONFIG(debugTimerCallback));
enginePins.debugSetTimer.initPin("debug: set timer", CONFIG(debugSetTimer));
}
#define BLINKING_PERIOD_MS 33
@ -617,8 +595,8 @@ class CommunicationBlinkingTask : public PeriodicTimerController {
}
void setAllLeds(int value) {
// make sure we do not turn the fatal LED off if already have
// fatal error by now
// make sure we do not turn the critical LED off if already have
// critical error by now
for (uint32_t i = 0; !hasFirmwareError() && i < sizeof(leds) / sizeof(leds[0]); i++) {
leds[i]->setValue(value);
}
@ -637,9 +615,9 @@ class CommunicationBlinkingTask : public PeriodicTimerController {
enginePins.warningLedPin.setValue(0);
} else {
if (hasFirmwareError()) {
// special behavior in case of fatal error - not equal on/off time
// special behavior in case of critical error - not equal on/off time
// this special behaviour helps to notice that something is not right, also
// differentiates software firmware error from fatal interrupt error with CPU halt.
// differentiates software firmware error from critical interrupt error with CPU halt.
offTimeMs = 50;
onTimeMs = 450;
} else {
@ -709,9 +687,6 @@ void updateTunerStudioState(TunerStudioOutputChannels *tsOutputChannels DECLARE_
executorStatistics();
#endif /* EFI_PROD_CODE */
float coolant = getCoolantTemperature();
float intake = getIntakeAirTemperature();
float engineLoad = getEngineLoadT(PASS_ENGINE_PARAMETER_SIGNATURE);
// header
@ -719,10 +694,20 @@ void updateTunerStudioState(TunerStudioOutputChannels *tsOutputChannels DECLARE_
// offset 0
tsOutputChannels->rpm = rpm;
// offset 4
tsOutputChannels->coolantTemperature = coolant;
// offset 8
tsOutputChannels->intakeAirTemperature = intake;
SensorResult clt = Sensor::get(SensorType::Clt);
tsOutputChannels->coolantTemperature = clt.Value;
tsOutputChannels->isCltError = !clt.Valid;
SensorResult iat = Sensor::get(SensorType::Iat);
tsOutputChannels->intakeAirTemperature = iat.Value;
tsOutputChannels->isIatError = !iat.Valid;
SensorResult auxTemp1 = Sensor::get(SensorType::AuxTemp1);
tsOutputChannels->auxTemp1 = auxTemp1.Value;
SensorResult auxTemp2 = Sensor::get(SensorType::AuxTemp2);
tsOutputChannels->auxTemp2 = auxTemp2.Value;
SensorResult tps1 = Sensor::get(SensorType::Tps1);
tsOutputChannels->throttlePosition = tps1.Value;
@ -732,6 +717,17 @@ void updateTunerStudioState(TunerStudioOutputChannels *tsOutputChannels DECLARE_
SensorResult tps2 = Sensor::get(SensorType::Tps2);
tsOutputChannels->throttle2Position = tps2.Value;
SensorResult pedal = Sensor::get(SensorType::AcceleratorPedal);
tsOutputChannels->pedalPosition = pedal.Value;
// Only report fail if you have one (many people don't)
tsOutputChannels->isPedalError = !pedal.Valid && Sensor::hasSensor(SensorType::AcceleratorPedal);
// Set raw sensors
tsOutputChannels->rawTps1Primary = Sensor::getRaw(SensorType::Tps1);
tsOutputChannels->rawPpsPrimary = Sensor::getRaw(SensorType::AcceleratorPedal);
tsOutputChannels->rawClt = Sensor::getRaw(SensorType::Clt);
tsOutputChannels->rawIat = Sensor::getRaw(SensorType::Iat);
tsOutputChannels->rawOilPressure = Sensor::getRaw(SensorType::OilPressure);
// offset 16
tsOutputChannels->massAirFlowVoltage = hasMafSensor() ? getMafVoltage(PASS_ENGINE_PARAMETER_SIGNATURE) : 0;
@ -742,10 +738,10 @@ void updateTunerStudioState(TunerStudioOutputChannels *tsOutputChannels DECLARE_
}
// offset 24
tsOutputChannels->engineLoad = engineLoad;
if (hasVBatt(PASS_ENGINE_PARAMETER_SIGNATURE)) {
// offset 28
tsOutputChannels->vBatt = getVBatt(PASS_ENGINE_PARAMETER_SIGNATURE);
}
// KLUDGE? we always show VBatt because Proteus board has VBatt input sensor hardcoded
// offset 28
tsOutputChannels->vBatt = getVBatt(PASS_ENGINE_PARAMETER_SIGNATURE);
// offset 36
#if EFI_ANALOG_SENSORS
@ -771,8 +767,6 @@ void updateTunerStudioState(TunerStudioOutputChannels *tsOutputChannels DECLARE_
tsOutputChannels->orderingErrorCounter = engine->triggerCentral.triggerState.orderingErrorCounter;
// 68
tsOutputChannels->baroCorrection = engine->engineState.baroCorrection;
// 136
tsOutputChannels->pedalPosition = hasPedalPositionSensor(PASS_ENGINE_PARAMETER_SIGNATURE) ? getPedalPosition(PASS_ENGINE_PARAMETER_SIGNATURE) : 0;
// 140
#if EFI_ENGINE_CONTROL
tsOutputChannels->injectorDutyCycle = getInjectorDutyCycle(rpm PASS_ENGINE_PARAMETER_SUFFIX);
@ -828,13 +822,16 @@ void updateTunerStudioState(TunerStudioOutputChannels *tsOutputChannels DECLARE_
tsOutputChannels->knockCount = engine->knockCount;
tsOutputChannels->knockLevel = engine->knockVolts;
tsOutputChannels->hasFatalError = hasFirmwareError();
tsOutputChannels->hasCriticalError = hasFirmwareError();
tsOutputChannels->isWarnNow = engine->engineState.warnings.isWarningNow(timeSeconds, true);
#if EFI_HIP_9011
tsOutputChannels->isKnockChipOk = (instance.invalidHip9011ResponsesCount == 0);
#endif /* EFI_HIP_9011 */
#if EFI_LAUNCH_CONTROL
tsOutputChannels->launchTriggered = engine->isLaunchCondition;
#endif
tsOutputChannels->tpsAccelFuel = engine->engineState.tpsAccelEnrich;
// engine load acceleration
@ -885,9 +882,6 @@ void updateTunerStudioState(TunerStudioOutputChannels *tsOutputChannels DECLARE_
#endif /* EFI_VEHICLE_SPEED */
#endif /* EFI_PROD_CODE */
tsOutputChannels->isCltError = !hasCltSensor();
tsOutputChannels->isIatError = !hasIatSensor();
tsOutputChannels->fuelConsumptionPerHour = engine->engineState.fuelConsumption.perSecondConsumption;
tsOutputChannels->warningCounter = engine->engineState.warnings.warningCounter;
@ -918,10 +912,8 @@ void updateTunerStudioState(TunerStudioOutputChannels *tsOutputChannels DECLARE_
#endif // EFI_ENGINE_CONTROL
switch (engineConfiguration->debugMode) {
case DBG_AUX_TEMPERATURE:
// // 68
tsOutputChannels->debugFloatField1 = engine->sensors.auxTemp1;
tsOutputChannels->debugFloatField2 = engine->sensors.auxTemp2;
case DBG_START_STOP:
tsOutputChannels->debugIntField1 = engine->startStopStateToggleCounter;
break;
case DBG_STATUS:
tsOutputChannels->debugFloatField1 = timeSeconds;
@ -950,16 +942,21 @@ void updateTunerStudioState(TunerStudioOutputChannels *tsOutputChannels DECLARE_
case DBG_TRIGGER_COUNTERS:
tsOutputChannels->debugIntField1 = engine->triggerCentral.getHwEventCounter((int)SHAFT_PRIMARY_FALLING);
tsOutputChannels->debugIntField2 = engine->triggerCentral.getHwEventCounter((int)SHAFT_SECONDARY_FALLING);
tsOutputChannels->debugIntField3 = engine->triggerCentral.getHwEventCounter((int)SHAFT_3RD_FALLING);
// no one uses shaft so far tsOutputChannels->debugIntField3 = engine->triggerCentral.getHwEventCounter((int)SHAFT_3RD_FALLING);
#if EFI_PROD_CODE && HAL_USE_ICU == TRUE
tsOutputChannels->debugIntField3 = icuRisingCallbackCounter + icuFallingCallbackCounter;
tsOutputChannels->debugIntField4 = engine->triggerCentral.vvtEventRiseCounter;
tsOutputChannels->debugIntField5 = engine->triggerCentral.vvtEventFallCounter;
tsOutputChannels->debugFloatField5 = icuRisingCallbackCounter + icuFallingCallbackCounter;
#endif /* EFI_PROD_CODE */
tsOutputChannels->debugFloatField1 = engine->triggerCentral.getHwEventCounter((int)SHAFT_PRIMARY_RISING);
tsOutputChannels->debugFloatField2 = engine->triggerCentral.getHwEventCounter((int)SHAFT_SECONDARY_RISING);
tsOutputChannels->debugFloatField3 = engine->triggerCentral.getHwEventCounter((int)SHAFT_3RD_RISING);
tsOutputChannels->debugIntField4 = engine->triggerCentral.triggerState.currentCycle.eventCount[0];
tsOutputChannels->debugIntField5 = engine->triggerCentral.triggerState.currentCycle.eventCount[1];
// debugFloatField6 used
// no one uses shaft so far tsOutputChannels->debugFloatField3 = engine->triggerCentral.getHwEventCounter((int)SHAFT_3RD_RISING);
break;
case DBG_FSIO_ADC:
// todo: implement a proper loop

View File

@ -11,47 +11,116 @@
#if EFI_TOOTH_LOGGER
EXTERN_ENGINE;
#include <cstddef>
#include "efitime.h"
#include "efilib.h"
#include "tunerstudio_configuration.h"
static uint16_t buffer[1000] CCM_OPTIONAL;
typedef struct __attribute__ ((packed)) {
uint16_t timestamp;
} tooth_logger_s;
typedef struct __attribute__ ((packed)) {
// the whole order of all packet bytes is reversed, not just the 'endian-swap' integers
uint32_t timestamp;
// unfortunately all these fields are required by TS...
bool priLevel : 1;
bool secLevel : 1;
bool trigger : 1;
bool sync : 1;
} composite_logger_s;
static composite_logger_s buffer[COMPOSITE_PACKET_COUNT] CCM_OPTIONAL;
static size_t NextIdx = 0;
static volatile bool ToothLoggerEnabled = false;
static uint32_t lastEdgeTimestamp = 0;
void SetNextEntry(uint16_t entry) {
static bool trigger1 = false;
static bool trigger2 = false;
//char (*__kaboom)[sizeof( composite_logger_s )] = 1;
//char (*__kaboom)[sizeof( buffer )] = 1;
//void SetNextToothEntry(uint16_t entry) {
// TS uses big endian, grumble
buffer[NextIdx] = SWAP_UINT16(entry);
// buffer[NextIdx] = SWAP_UINT16(entry);
//NextIdx++;
static void SetNextCompositeEntry(efitick_t timestamp, bool trigger1, bool trigger2,
bool isTDC DECLARE_ENGINE_PARAMETER_SUFFIX) {
uint32_t nowUs = NT2US(timestamp);
// TS uses big endian, grumble
buffer[NextIdx].timestamp = SWAP_UINT32(nowUs);
buffer[NextIdx].priLevel = trigger1;
buffer[NextIdx].secLevel = trigger2;
buffer[NextIdx].trigger = isTDC;
buffer[NextIdx].sync = engine->triggerCentral.triggerState.shaft_is_synchronized;
// todo:
//buffer[NextIdx].sync = isSynced;
//buffer[NextIdx].trigger = wtfIsTriggerIdk;
NextIdx++;
static_assert(sizeof(composite_logger_s) == COMPOSITE_PACKET_SIZE, "composite packet size");
// If we hit the end, loop
if (NextIdx >= sizeof(buffer) / sizeof(buffer[0])) {
NextIdx = 0;
}
}
void LogTriggerTooth(trigger_event_e tooth, efitick_t timestamp) {
void LogTriggerTooth(trigger_event_e tooth, efitick_t timestamp DECLARE_ENGINE_PARAMETER_SUFFIX) {
// bail if we aren't enabled
if (!ToothLoggerEnabled) {
return;
}
// We currently only support the primary trigger falling edge
// (this is the edge that VR sensors are accurate on)
// Since VR sensors are the most useful case here, this is okay for now.
if (tooth != SHAFT_PRIMARY_FALLING) {
return;
/*
// We currently only support the primary trigger falling edge
// (this is the edge that VR sensors are accurate on)
// Since VR sensors are the most useful case here, this is okay for now.
if (tooth != SHAFT_PRIMARY_FALLING) {
return;
}
uint32_t nowUs = NT2US(timestamp);
// 10us per LSB - this gives plenty of accuracy, yet fits 655.35 ms in to a uint16
uint16_t delta = static_cast<uint16_t>((nowUs - lastEdgeTimestamp) / 10);
lastEdgeTimestamp = nowUs;
SetNextEntry(delta);
*/
switch (tooth) {
case SHAFT_PRIMARY_FALLING:
trigger1 = false;
break;
case SHAFT_PRIMARY_RISING:
trigger1 = true;
break;
case SHAFT_SECONDARY_FALLING:
trigger2 = false;
break;
case SHAFT_SECONDARY_RISING:
trigger2 = true;
break;
default:
break;
}
uint32_t nowUs = NT2US(timestamp);
// 10us per LSB - this gives plenty of accuracy, yet fits 655.35 ms in to a uint16
uint16_t delta = static_cast<uint16_t>((nowUs - lastEdgeTimestamp) / 10);
lastEdgeTimestamp = nowUs;
SetNextCompositeEntry(timestamp, trigger1, trigger2, false PASS_ENGINE_PARAMETER_SUFFIX);
}
SetNextEntry(delta);
void LogTriggerTopDeadCenter(efitick_t timestamp DECLARE_ENGINE_PARAMETER_SUFFIX) {
// bail if we aren't enabled
if (!ToothLoggerEnabled) {
return;
}
SetNextCompositeEntry(timestamp, trigger1, trigger2, true PASS_ENGINE_PARAMETER_SUFFIX);
}
void EnableToothLogger() {

View File

@ -11,6 +11,7 @@
#include <cstddef>
#include "efitime.h"
#include "rusefi_enums.h"
#include "engine.h"
// Enable the tooth logger - this clears the buffer starts logging
void EnableToothLogger();
@ -19,7 +20,9 @@ void EnableToothLogger();
void DisableToothLogger();
// A new tooth has arrived! Log to the buffer if enabled.
void LogTriggerTooth(trigger_event_e tooth, efitick_t timestamp);
void LogTriggerTooth(trigger_event_e tooth, efitick_t timestamp DECLARE_ENGINE_PARAMETER_SUFFIX);
void LogTriggerTopDeadCenter(efitick_t timestamp DECLARE_ENGINE_PARAMETER_SUFFIX);
struct ToothLoggerBuffer
{

View File

@ -22,7 +22,7 @@
#include "local_version_holder.h"
#include "periodic_task.h"
#include "pwm_generator.h"
#include "pwm_generator_logic.h"
#include "pin_repository.h"
@ -30,14 +30,12 @@
#error "Unexpected OS ACCESS HERE"
#endif /* HAS_OS_ACCESS */
EXTERN_ENGINE
;
EXTERN_ENGINE;
static Logging *logger;
static SimplePwm alternatorControl("alt");
static pid_s *altPidS = &persistentState.persistentConfiguration.engineConfiguration.alternatorControl;
static PidIndustrial alternatorPid(altPidS);
static PidIndustrial alternatorPid(&persistentState.persistentConfiguration.engineConfiguration.alternatorControl);
static percent_t currentAltDuty;
@ -164,8 +162,7 @@ void initAlternatorCtrl(Logging *sharedLogger DECLARE_ENGINE_PARAMETER_SUFFIX) {
return;
if (CONFIG(onOffAlternatorLogic)) {
enginePins.alternatorPin.initPin("on/off alternator", CONFIG(alternatorControlPin));
enginePins.alternatorPin.initPin("Alternator control", CONFIG(alternatorControlPin));
} else {
startSimplePwmExt(&alternatorControl,
"Alternator control",

View File

@ -7,8 +7,8 @@
* @author Andrey Belomutskiy, (c) 2012-2020
*
*/
#ifndef ALTERNATORCONTROLLER_H_
#define ALTERNATORCONTROLLER_H_
#pragma once
#include "engine.h"
void initAlternatorCtrl(Logging *sharedLogger);
@ -19,5 +19,3 @@ void showAltInfo(void);
void setDefaultAlternatorParameters(DECLARE_CONFIG_PARAMETER_SIGNATURE);
void onConfigurationChangeAlternatorCallback(engine_configuration_s *previousConfiguration);
#endif /* ALTERNATORCONTROLLER_H_ */

View File

@ -12,7 +12,7 @@
#include "allsensors.h"
#if EFI_AUX_PID
#include "pwm_generator.h"
#include "pwm_generator_logic.h"
#include "tunerstudio_configuration.h"
#include "fsio_impl.h"
#include "engine_math.h"
@ -23,10 +23,9 @@
#if defined(HAS_OS_ACCESS)
#error "Unexpected OS ACCESS HERE"
#endif
#endif /* HAS_OS_ACCESS */
EXTERN_ENGINE
;
EXTERN_ENGINE;
extern fsio8_Map3D_f32t fsioTable1;
@ -57,8 +56,7 @@ public:
void init(int index) {
this->index = index;
pid_s *auxPidS = &persistentState.persistentConfiguration.engineConfiguration.auxPid[index];
auxPid.initPidClass(auxPidS);
auxPid.initPidClass(&persistentState.persistentConfiguration.engineConfiguration.auxPid[index]);
table = getFSIOTable(index);
}
@ -124,7 +122,7 @@ static void turnAuxPidOn(int index) {
&engine->executor,
engineConfiguration->auxPidPins[index],
&instances[index].auxOutputPin,
engineConfiguration->auxPidFrequency[index], 0.1, (pwm_gen_callback*)applyPinState);
engineConfiguration->auxPidFrequency[index], 0.1);
}
void startAuxPins(void) {

View File

@ -5,8 +5,7 @@
* @author Andrey Belomutskiy, (c) 2012-2020
*/
#ifndef CONTROLLERS_ALGO_AUX_PID_H_
#define CONTROLLERS_ALGO_AUX_PID_H_
#pragma once
#include "global.h"
@ -14,4 +13,3 @@ void initAuxPid(Logging *sharedLogger);
void startAuxPins(void);
void stopAuxPins(void);
#endif /* CONTROLLERS_ALGO_AUX_PID_H_ */

View File

@ -13,7 +13,7 @@
#endif /* EFI_TUNER_STUDIO */
#include "engine.h"
#include "boost_control.h"
#include "tps.h"
#include "sensor.h"
#include "map.h"
#include "io_pins.h"
#include "engine_configuration.h"
@ -22,7 +22,7 @@
#include "engine_controller.h"
#include "periodic_task.h"
#include "pin_repository.h"
#include "pwm_generator.h"
#include "pwm_generator_logic.h"
#include "pid_auto_tune.h"
#include "local_version_holder.h"
#define NO_PIN_PERIOD 500
@ -37,8 +37,7 @@ static Logging *logger;
static boostOpenLoop_Map3D_t boostMapOpen("boostmapopen", 1);
static boostOpenLoop_Map3D_t boostMapClosed("boostmapclosed", 1);
static SimplePwm boostPwmControl("boost");
static pid_s *boostPidS = &persistentState.persistentConfiguration.engineConfiguration.boostPid;
static Pid boostControlPid(boostPidS);
static Pid boostControlPid;
static bool shouldResetPid = false;
@ -51,6 +50,8 @@ static void pidReset(void) {
}
class BoostControl: public PeriodicTimerController {
DECLARE_ENGINE_PTR;
int getPeriodMs() override {
return GET_PERIOD_LIMITED(&engineConfiguration->boostPid);
}
@ -78,10 +79,13 @@ class BoostControl: public PeriodicTimerController {
percent_t duty = openLoopDuty;
if (engineConfiguration->boostType == CLOSED_LOOP) {
float tps = getTPS(PASS_ENGINE_PARAMETER_SIGNATURE);
float targetBoost = boostMapClosed.getValue(rpm / RPM_1_BYTE_PACKING_MULT, tps / TPS_1_BYTE_PACKING_MULT) * LOAD_1_BYTE_PACKING_MULT;
closedLoopDuty = openLoopDuty + boostControlPid.getOutput(targetBoost, mapValue);
duty += closedLoopDuty;
auto [valid, tps] = Sensor::get(SensorType::DriverThrottleIntent);
if (valid) {
float targetBoost = boostMapClosed.getValue(rpm / RPM_1_BYTE_PACKING_MULT, tps / TPS_1_BYTE_PACKING_MULT) * LOAD_1_BYTE_PACKING_MULT;
closedLoopDuty = openLoopDuty + boostControlPid.getOutput(targetBoost, mapValue);
duty += closedLoopDuty;
}
}
boostControlPid.iTermMin = -50;
@ -95,16 +99,22 @@ class BoostControl: public PeriodicTimerController {
#endif /* EFI_TUNER_STUDIO */
}
#if EFI_LAUNCH_CONTROL
if (engine->setLaunchBoostDuty) {
duty = engineConfiguration->launchBoostDuty;
}
#endif /* EFI_LAUNCH_CONTROL */
boostPwmControl.setSimplePwmDutyCycle(PERCENT_TO_DUTY(duty));
}
};
static BoostControl BoostController;
#if !EFI_UNIT_TEST
void setBoostPFactor(float value) {
engineConfiguration->boostPid.pFactor = value;
boostControlPid.reset();
}
void setBoostIFactor(float value) {
@ -116,6 +126,7 @@ void setBoostDFactor(float value) {
engineConfiguration->boostPid.dFactor = value;
boostControlPid.reset();
}
#endif /* EFI_UNIT_TEST */
void setDefaultBoostParameters(DECLARE_CONFIG_PARAMETER_SIGNATURE) {
engineConfiguration->isBoostControlEnabled = true;
@ -146,6 +157,7 @@ void setDefaultBoostParameters(DECLARE_CONFIG_PARAMETER_SIGNATURE) {
}
static void turnBoostPidOn() {
#if !EFI_UNIT_TEST
if (CONFIG(boostControlPin) == GPIO_UNASSIGNED){
return;
}
@ -157,9 +169,9 @@ static void turnBoostPidOn() {
CONFIG(boostControlPin),
&enginePins.boostPin,
engineConfiguration->boostPwmFrequency,
0.5f,
(pwm_gen_callback*) applyPinState
0.5f
);
#endif /* EFI_UNIT_TEST */
}
void startBoostPin(void) {
@ -167,7 +179,9 @@ void startBoostPin(void) {
}
void stopBoostPin(void) {
#if !EFI_UNIT_TEST
brain_pin_markUnused(activeConfiguration.boostControlPin);
#endif /* EFI_UNIT_TEST */
}
void onConfigurationChangeBoostCallback(engine_configuration_s *previousConfiguration) {
@ -175,16 +189,22 @@ void onConfigurationChangeBoostCallback(engine_configuration_s *previousConfigur
}
void initBoostCtrl(Logging *sharedLogger DECLARE_ENGINE_PARAMETER_SUFFIX) {
#if !EFI_UNIT_TEST
if (CONFIG(boostControlPin) == GPIO_UNASSIGNED){
return;
}
#endif
boostControlPid.initPidClass(&engineConfiguration->boostPid);
logger = sharedLogger;
boostMapOpen.init(config->boostTableOpenLoop, config->boostMapBins, config->boostRpmBins);
boostMapClosed.init(config->boostTableClosedLoop, config->boostTpsBins, config->boostRpmBins);
boostControlPid.reset();
#if !EFI_UNIT_TEST
startBoostPin();
BoostController.Start();
#endif
}
#endif

View File

@ -9,19 +9,12 @@
#include "engine.h"
#include "periodic_task.h"
void startBoostPin(void);
void stopBoostPin(void);
void initBoostCtrl(Logging *sharedLogger);
void initBoostCtrl(Logging *sharedLogger DECLARE_ENGINE_PARAMETER_SUFFIX);
void setBoostPFactor(float p);
void setBoostIFactor(float i);
void setBoostDFactor(float d);
void setDefaultBoostParameters(DECLARE_CONFIG_PARAMETER_SIGNATURE);
void showBoostInfo(void);
void onConfigurationChangeBoostCallback(engine_configuration_s *previousConfiguration);

View File

@ -15,7 +15,7 @@
#include "dc_motor.h"
#include "efi_gpio.h"
#include "pwm_generator.h"
#include "pwm_generator_logic.h"
EXTERN_ENGINE;
@ -24,6 +24,7 @@ private:
OutputPin m_pinEnable;
OutputPin m_pinDir1;
OutputPin m_pinDir2;
OutputPin m_disablePin;
SimplePwm m_pwmEnable;
SimplePwm m_pwmDir1;
@ -32,7 +33,7 @@ private:
SimplePwm etbPwmUp;
public:
EtbHardware() : etbPwmUp("etbUp"), dcMotor(&m_pwmEnable, &m_pwmDir1, &m_pwmDir2) {}
EtbHardware() : etbPwmUp("etbUp"), dcMotor(&m_pwmEnable, &m_pwmDir1, &m_pwmDir2, &m_disablePin) {}
TwoPinDcMotor dcMotor;
@ -45,14 +46,17 @@ public:
void start(bool useTwoWires,
brain_pin_e pinEnable,
// since we have pointer magic here we cannot simply have value parameter
const pin_output_mode_e *pinEnableMode,
brain_pin_e pinDir1,
brain_pin_e pinDir2,
brain_pin_e pinDisable,
ExecutorInterface* executor,
int frequency) {
dcMotor.setType(useTwoWires ? TwoPinDcMotor::ControlType::PwmDirectionPins : TwoPinDcMotor::ControlType::PwmEnablePin);
m_pinEnable.initPin("ETB Enable", pinEnable, pinEnableMode);
// Configure the disable pin first - ensure things are in a safe state
m_disablePin.initPin("ETB Disable", pinDisable);
m_pinEnable.initPin("ETB Enable", pinEnable);
m_pinDir1.initPin("ETB Dir 1", pinDir1);
m_pinDir2.initPin("ETB Dir 2", pinDir2);
@ -65,24 +69,21 @@ public:
executor,
&m_pinEnable,
clampedFrequency,
0,
(pwm_gen_callback*)applyPinState
0
);
startSimplePwm(&m_pwmDir1, "ETB Dir 1",
executor,
&m_pinDir1,
clampedFrequency,
0,
(pwm_gen_callback*)applyPinState
0
);
startSimplePwm(&m_pwmDir2, "ETB Dir 2",
executor,
&m_pinDir2,
clampedFrequency,
0,
(pwm_gen_callback*)applyPinState
0
);
#endif /* EFI_UNIT_TEST */
}
@ -95,13 +96,12 @@ DcMotor* initDcMotor(size_t index DECLARE_ENGINE_PARAMETER_SUFFIX)
const auto& io = engineConfiguration->etbIo[index];
auto& hw = etbHardware[index];
// controlPinMode is a strange feature - it's simply because I am short on 5v I/O on Frankenso with Miata NB2 test mule
hw.start(
CONFIG(etb_use_two_wires),
io.controlPin1,
&io.controlPinMode,
io.directionPin1,
io.directionPin2,
io.disablePin,
&ENGINE(executor),
CONFIG(etbFreq)
);

View File

@ -76,13 +76,7 @@
#include "electronic_throttle.h"
#include "tps.h"
#include "io_pins.h"
#include "engine_configuration.h"
#include "pwm_generator_logic.h"
#include "pid.h"
#include "engine_controller.h"
#include "periodic_task.h"
#include "pin_repository.h"
#include "sensor.h"
#include "dc_motor.h"
#include "dc_motors.h"
#include "pid_auto_tune.h"
@ -95,10 +89,6 @@
#define ETB_MAX_COUNT 2
#endif /* ETB_MAX_COUNT */
static pid_s tuneWorkingPidSettings;
static Pid tuneWorkingPid(&tuneWorkingPidSettings);
static PID_AutoTune autoTune;
static LoggingWithStorage logger("ETB");
static pedal2tps_t pedal2tpsMap("Pedal2Tps", 1);
@ -108,19 +98,25 @@ static bool startupPositionError = false;
#define STARTUP_NEUTRAL_POSITION_ERROR_THRESHOLD 5
extern percent_t mockPedalPosition;
static SensorType indexToTpsSensor(size_t index) {
switch(index) {
case 0: return SensorType::Tps1;
default: return SensorType::Tps2;
}
}
static percent_t directPwmValue = NAN;
static percent_t currentEtbDuty;
#define ETB_DUTY_LIMIT 0.9
// 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))
#define ETB_PERCENT_TO_DUTY(x) (clampF(-ETB_DUTY_LIMIT, 0.01f * (x), ETB_DUTY_LIMIT))
void EtbController::init(DcMotor *motor, int ownIndex, pid_s *pidParameters) {
void EtbController::init(DcMotor *motor, int ownIndex, pid_s *pidParameters, const ValueProvider3D* pedalMap) {
m_motor = motor;
m_myIndex = ownIndex;
m_pid.initPidClass(pidParameters);
m_pedalMap = pedalMap;
}
void EtbController::reset() {
@ -141,6 +137,182 @@ int EtbController::getPeriodMs() {
return GET_PERIOD_LIMITED(&engineConfiguration->etb);
}
expected<percent_t> EtbController::observePlant() const {
return Sensor::get(indexToTpsSensor(m_myIndex));
}
void EtbController::setIdlePosition(percent_t pos) {
m_idlePosition = pos;
}
expected<percent_t> EtbController::getSetpoint() const {
// A few extra preconditions if throttle control is invalid
if (startupPositionError) {
return unexpected;
}
if (engineConfiguration->pauseEtbControl) {
return unexpected;
}
// If the pedal map hasn't been set, we can't provide a setpoint.
if (!m_pedalMap) {
return unexpected;
}
auto pedalPosition = Sensor::get(SensorType::AcceleratorPedal);
if (!pedalPosition.Valid) {
return unexpected;
}
float sanitizedPedal = clampF(0, pedalPosition.Value, 100);
float rpm = GET_RPM();
float targetFromTable = m_pedalMap->getValue(rpm / RPM_1_BYTE_PACKING_MULT, sanitizedPedal);
engine->engineState.targetFromTable = targetFromTable;
percent_t etbIdlePosition = clampF(
0,
CONFIG(useETBforIdleControl) ? m_idlePosition : 0,
100
);
percent_t etbIdleAddition = 0.01f * CONFIG(etbIdleThrottleRange) * etbIdlePosition;
// Interpolate so that the idle adder just "compresses" the throttle's range upward.
// [0, 100] -> [idle, 100]
// 0% target from table -> idle position as target
// 100% target from table -> 100% target position
percent_t targetPosition = interpolateClamped(0, etbIdleAddition, 100, 100, targetFromTable);
#if EFI_TUNER_STUDIO
if (m_myIndex == 0) {
tsOutputChannels.etbTarget = targetPosition;
}
#endif
return targetPosition;
}
expected<percent_t> EtbController::getOpenLoop(percent_t target) const {
float ff = interpolate2d("etbb", target, engineConfiguration->etbBiasBins, engineConfiguration->etbBiasValues);
engine->engineState.etbFeedForward = ff;
return ff;
}
expected<percent_t> EtbController::getClosedLoopAutotune(percent_t actualThrottlePosition) {
// Estimate gain at 60% position - this should be well away from the spring and in the linear region
bool isPositive = actualThrottlePosition > 60.0f;
float autotuneAmplitude = 20;
// End of cycle - record & reset
if (!isPositive && m_lastIsPositive) {
efitick_t now = getTimeNowNt();
// Determine period
float tu = NT2US((float)(now - m_cycleStartTime)) / 1e6;
m_cycleStartTime = now;
// Determine amplitude
float a = m_maxCycleTps - m_minCycleTps;
// Filter - it's pretty noisy since the ultimate period is not very many loop periods
constexpr float alpha = 0.05;
m_a = alpha * a + (1 - alpha) * m_a;
m_tu = alpha * tu + (1 - alpha) * m_tu;
// Reset bounds
m_minCycleTps = 100;
m_maxCycleTps = 0;
// Math is for ÅströmHägglund (relay) auto tuning
// https://warwick.ac.uk/fac/cross_fac/iatl/reinvention/archive/volume5issue2/hornsey
// Publish to TS state
#if EFI_TUNER_STUDIO
if (engineConfiguration->debugMode == DBG_ETB_AUTOTUNE) {
// a - amplitude of output (TPS %)
tsOutputChannels.debugFloatField1 = m_a;
float b = 2 * autotuneAmplitude;
// b - amplitude of input (Duty cycle %)
tsOutputChannels.debugFloatField2 = b;
// Tu - oscillation period (seconds)
tsOutputChannels.debugFloatField3 = m_tu;
// Ultimate gain per A-H relay tuning rule
// Ku
float ku = 4 * b / (3.14159f * m_a);
tsOutputChannels.debugFloatField4 = ku;
// The multipliers below are somewhere near the "no overshoot"
// and "some overshoot" flavors of the Ziegler-Nichols method
// Kp
tsOutputChannels.debugFloatField5 = 0.35f * ku;
// Ki
tsOutputChannels.debugFloatField6 = 0.25f * ku / m_tu;
// Kd
tsOutputChannels.debugFloatField7 = 0.08f * ku * m_tu;
}
#endif
}
m_lastIsPositive = isPositive;
// Find the min/max of each cycle
if (actualThrottlePosition < m_minCycleTps) {
m_minCycleTps = actualThrottlePosition;
}
if (actualThrottlePosition > m_maxCycleTps) {
m_maxCycleTps = actualThrottlePosition;
}
// Bang-bang control the output to induce oscillation
return autotuneAmplitude * (isPositive ? -1 : 1);
}
expected<percent_t> EtbController::getClosedLoop(percent_t target, percent_t actualThrottlePosition) {
if (m_shouldResetPid) {
m_pid.reset();
m_shouldResetPid = false;
}
// Only report the 0th throttle
if (m_myIndex == 0) {
#if EFI_TUNER_STUDIO
// Error is positive if the throttle needs to open further
tsOutputChannels.etb1Error = target - actualThrottlePosition;
#endif /* EFI_TUNER_STUDIO */
}
// Only allow autotune with stopped engine
if (GET_RPM() == 0 && engine->etbAutoTune) {
return getClosedLoopAutotune(actualThrottlePosition);
} else {
// Normal case - use PID to compute closed loop part
return m_pid.getOutput(target, actualThrottlePosition);
}
}
void EtbController::setOutput(expected<percent_t> outputValue) {
#if EFI_TUNER_STUDIO
// Only report first-throttle stats
if (m_myIndex == 0) {
tsOutputChannels.etb1DutyCycle = outputValue.value_or(0);
}
#endif
if (!m_motor) return;
if (outputValue) {
m_motor->enable();
m_motor->set(ETB_PERCENT_TO_DUTY(outputValue.Value));
} else {
m_motor->disable();
}
}
void EtbController::PeriodicTask() {
#if EFI_TUNER_STUDIO
// Only debug throttle #0
@ -156,60 +328,11 @@ void EtbController::PeriodicTask() {
}
#endif /* EFI_TUNER_STUDIO */
if (!m_motor) {
return;
}
if (startupPositionError) {
m_motor->set(0);
return;
}
if (m_shouldResetPid) {
m_pid.reset();
m_shouldResetPid = false;
}
if (!cisnan(directPwmValue)) {
m_motor->set(directPwmValue);
return;
}
if (engineConfiguration->pauseEtbControl) {
m_motor->set(0);
return;
}
percent_t actualThrottlePosition = getTPSWithIndex(m_myIndex 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 = CONFIG(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;
@ -217,27 +340,16 @@ void EtbController::PeriodicTask() {
#endif /* EFI_TUNER_STUDIO */
}
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);
m_pid.iTermMin = engineConfiguration->etb_iTermMin;
m_pid.iTermMax = engineConfiguration->etb_iTermMax;
currentEtbDuty = engine->engineState.etbFeedForward +
m_pid.getOutput(targetPosition, actualThrottlePosition);
m_motor->set(ETB_PERCENT_TO_DUTY(currentEtbDuty));
if (engineConfiguration->isVerboseETB) {
m_pid.showPidStatus(&logger, "ETB");
}
update();
DISPLAY_STATE(Engine)
DISPLAY(DISPLAY_IF(hasEtbPedalPositionSensor))
DISPLAY_TEXT(Electronic_Throttle);
DISPLAY_SENSOR(TPS)
DISPLAY_TEXT(eol);
@ -276,19 +388,6 @@ DISPLAY(DISPLAY_IF(hasEtbPedalPositionSensor))
/* DISPLAY_ELSE */
DISPLAY_TEXT(No_Pedal_Sensor);
/* DISPLAY_ENDIF */
// Only report the 0th throttle
if (m_myIndex == 0) {
#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;
#endif /* EFI_TUNER_STUDIO */
}
}
// real implementation (we mock for some unit tests)
@ -296,8 +395,6 @@ EtbController etbControllers[ETB_COUNT];
static void showEthInfo(void) {
#if EFI_PROD_CODE
static char pinNameBuffer[16];
if (engine->etbActualCount == 0) {
scheduleMsg(&logger, "ETB DISABLED since no PPS");
}
@ -305,13 +402,7 @@ static void showEthInfo(void) {
scheduleMsg(&logger, "etbAutoTune=%d",
engine->etbAutoTune);
scheduleMsg(&logger, "throttlePedal=%.2f %.2f/%.2f @%s",
getPedalPosition(PASS_ENGINE_PARAMETER_SIGNATURE),
engineConfiguration->throttlePedalUpVoltage,
engineConfiguration->throttlePedalWOTVoltage,
getPinNameByAdcChannel("tPedal", engineConfiguration->throttlePedalPositionAdcChannel, pinNameBuffer));
scheduleMsg(&logger, "TPS=%.2f", getTPS(PASS_ENGINE_PARAMETER_SIGNATURE));
scheduleMsg(&logger, "TPS=%.2f", Sensor::get(SensorType::Tps1).value_or(0));
scheduleMsg(&logger, "etbControlPin1=%s duty=%.2f freq=%d",
@ -371,8 +462,6 @@ static void etbReset() {
}
etbPidReset();
mockPedalPosition = MOCK_UNDEFINED;
}
#endif /* EFI_PROD_CODE */
@ -415,34 +504,19 @@ void setEtbOffset(int value) {
#endif /* EFI_UNIT_TEST */
void setBoschVNH2SP30Curve(DECLARE_CONFIG_PARAMETER_SIGNATURE) {
engineConfiguration->etbBiasBins[0] = 0;
engineConfiguration->etbBiasBins[1] = 1;
engineConfiguration->etbBiasBins[2] = 5;
/**
* This specific throttle has default position of about 7% open
*/
engineConfiguration->etbBiasBins[3] = 7;
engineConfiguration->etbBiasBins[4] = 14;
engineConfiguration->etbBiasBins[5] = 65;
engineConfiguration->etbBiasBins[6] = 66;
engineConfiguration->etbBiasBins[7] = 100;
/**
* This specific throttle has default position of about 7% open
*/
static const float boschBiasBins[] = {
0, 1, 5, 7, 14, 65, 66, 100
};
static const float boschBiasValues[] = {
-15, -15, -10, 0, 19, 20, 26, 28
};
/**
* Some negative bias for below-default position
*/
engineConfiguration->etbBiasValues[0] = -15;
engineConfiguration->etbBiasValues[1] = -15;
engineConfiguration->etbBiasValues[2] = -10;
/**
* Zero bias for index which corresponds to default throttle position, when no current is applied
* This specific throttle has default position of about 7% open
*/
engineConfiguration->etbBiasValues[3] = 0;
engineConfiguration->etbBiasValues[4] = 19;
engineConfiguration->etbBiasValues[5] = 20;
engineConfiguration->etbBiasValues[6] = 26;
engineConfiguration->etbBiasValues[7] = 28;
void setBoschVNH2SP30Curve(DECLARE_CONFIG_PARAMETER_SIGNATURE) {
copyArray(CONFIG(etbBiasBins), boschBiasBins);
copyArray(CONFIG(etbBiasValues), boschBiasValues);
}
void setDefaultEtbParameters(DECLARE_CONFIG_PARAMETER_SIGNATURE) {
@ -461,17 +535,17 @@ void setDefaultEtbParameters(DECLARE_CONFIG_PARAMETER_SIGNATURE) {
engineConfiguration->throttlePedalUpVoltage = 0; // that's voltage, not ADC like with TPS
engineConfiguration->throttlePedalWOTVoltage = 6; // that's voltage, not ADC like with TPS
engineConfiguration->etb.pFactor = 1;
engineConfiguration->etb.iFactor = 0.05;
engineConfiguration->etb.dFactor = 0.0;
engineConfiguration->etb.periodMs = (1000 / DEFAULT_ETB_LOOP_FREQUENCY);
engineConfiguration->etbFreq = DEFAULT_ETB_PWM_FREQUENCY;
engineConfiguration->etb = {
1, // Kp
10, // Ki
0.05, // Kd
0, // offset
(1000 / DEFAULT_ETB_LOOP_FREQUENCY),
-100, 100 // min/max
};
engineConfiguration->etb_iTermMin = -300;
engineConfiguration->etb_iTermMax = 300;
// values are above 100% since we have feedforward part of the total summation
engineConfiguration->etb.minValue = -200;
engineConfiguration->etb.maxValue = 200;
}
void onConfigurationChangeElectronicThrottleCallback(engine_configuration_s *previousConfiguration) {
@ -493,58 +567,24 @@ static void setAutoStep(float value) {
autoTune.SetOutputStep(value);
}
static void setAutoPeriod(int period) {
tuneWorkingPidSettings.periodMs = period;
autoTune.reset();
}
static void setAutoOffset(int offset) {
tuneWorkingPidSettings.offset = offset;
autoTune.reset();
}
#endif /* EFI_PROD_CODE */
void setDefaultEtbBiasCurve(DECLARE_CONFIG_PARAMETER_SIGNATURE) {
engineConfiguration->etbBiasBins[0] = 0;
engineConfiguration->etbBiasBins[1] = 1;
engineConfiguration->etbBiasBins[2] = 2;
/**
* This specific throttle has default position of about 4% open
*/
engineConfiguration->etbBiasBins[3] = 4;
engineConfiguration->etbBiasBins[4] = 7;
engineConfiguration->etbBiasBins[5] = 98;
engineConfiguration->etbBiasBins[6] = 99;
engineConfiguration->etbBiasBins[7] = 100;
static const float defaultBiasBins[] = {
0, 1, 2, 4, 7, 98, 99, 100
};
static const float defaultBiasValues[] = {
-20, -18, -17, 0, 20, 21, 22, 25
};
/**
* Some negative bias for below-default position
*/
engineConfiguration->etbBiasValues[0] = -20;
engineConfiguration->etbBiasValues[1] = -18;
engineConfiguration->etbBiasValues[2] = -17;
/**
* Zero bias for index which corresponds to default throttle position, when no current is applied
* This specific throttle has default position of about 4% open
*/
engineConfiguration->etbBiasValues[3] = 0;
engineConfiguration->etbBiasValues[4] = 20;
engineConfiguration->etbBiasValues[5] = 21;
engineConfiguration->etbBiasValues[6] = 22;
engineConfiguration->etbBiasValues[7] = 25;
void setDefaultEtbBiasCurve(DECLARE_CONFIG_PARAMETER_SIGNATURE) {
copyArray(CONFIG(etbBiasBins), defaultBiasBins);
copyArray(CONFIG(etbBiasValues), defaultBiasValues);
}
void unregisterEtbPins() {
// todo: we probably need an implementation here?!
}
void initElectronicThrottle(DECLARE_ENGINE_PARAMETER_SIGNATURE) {
for (int i = 0; i < ETB_COUNT; i++) {
engine->etbControllers[i] = &etbControllers[i];
}
doInitElectronicThrottle(PASS_ENGINE_PARAMETER_SIGNATURE);
}
void doInitElectronicThrottle(DECLARE_ENGINE_PARAMETER_SIGNATURE) {
efiAssertVoid(OBD_PCM_Processor_Fault, engine->etbControllers != NULL, "etbControllers NULL");
#if EFI_PROD_CODE
@ -553,14 +593,14 @@ void doInitElectronicThrottle(DECLARE_ENGINE_PARAMETER_SIGNATURE) {
addConsoleActionI("etb_freq", setEtbFrequency);
#endif /* EFI_PROD_CODE */
engine->engineState.hasEtbPedalPositionSensor = hasPedalPositionSensor(PASS_ENGINE_PARAMETER_SIGNATURE);
if (!engine->engineState.hasEtbPedalPositionSensor) {
#if EFI_PROD_CODE
// TODO: Once switched to new sensor model for pedal, we don't need this to be test-guarded.
// If you don't have a pedal, we have no business here.
if (!Sensor::hasSensor(SensorType::AcceleratorPedal)) {
return;
#endif
}
engine->etbActualCount = hasSecondThrottleBody(PASS_ENGINE_PARAMETER_SIGNATURE) ? 2 : 1;
pedal2tpsMap.init(config->pedalToTpsTable, config->pedalToTpsPedalBins, config->pedalToTpsRpmBins);
engine->etbActualCount = Sensor::hasSensor(SensorType::Tps2) ? 2 : 1;
for (int i = 0 ; i < engine->etbActualCount; i++) {
auto motor = initDcMotor(i PASS_ENGINE_PARAMETER_SUFFIX);
@ -568,23 +608,16 @@ void doInitElectronicThrottle(DECLARE_ENGINE_PARAMETER_SIGNATURE) {
// If this motor is actually set up, init the etb
if (motor)
{
engine->etbControllers[i]->init(motor, i, &engineConfiguration->etb);
engine->etbControllers[i]->init(motor, i, &engineConfiguration->etb, &pedal2tpsMap);
INJECT_ENGINE_REFERENCE(engine->etbControllers[i]);
}
}
pedal2tpsMap.init(config->pedalToTpsTable, config->pedalToTpsPedalBins, config->pedalToTpsRpmBins);
#if 0
// not alive code
autoTune.SetOutputStep(0.1);
#endif
#if 0 && ! EFI_UNIT_TEST
percent_t startupThrottlePosition = getTPS(PASS_ENGINE_PARAMETER_SIGNATURE);
if (absF(startupThrottlePosition - engineConfiguration->etbNeutralPosition) > STARTUP_NEUTRAL_POSITION_ERROR_THRESHOLD) {
/**
* Unexpected electronic throttle start-up position is worth a fatal error
* Unexpected electronic throttle start-up position is worth a critical error
*/
firmwareError(OBD_Throttle_Actuator_Control_Range_Performance_Bank_1, "startup ETB position %.2f not %d",
startupThrottlePosition,
@ -612,24 +645,6 @@ void doInitElectronicThrottle(DECLARE_ENGINE_PARAMETER_SIGNATURE) {
addConsoleActionNANF(CMD_ETB_DUTY, setThrottleDutyCycle);
#endif /* EFI_PROD_CODE */
#if EFI_PROD_CODE && 0
tuneWorkingPidSettings.pFactor = 1;
tuneWorkingPidSettings.iFactor = 0;
tuneWorkingPidSettings.dFactor = 0;
// tuneWorkingPidSettings.offset = 10; // todo: not hard-coded value
//todo tuneWorkingPidSettings.periodMs = 10;
tuneWorkingPidSettings.minValue = 0;
tuneWorkingPidSettings.maxValue = 100;
tuneWorkingPidSettings.periodMs = 100;
// this is useful once you do "enable etb_auto"
addConsoleActionF("set_etbat_output", setTempOutput);
addConsoleActionF("set_etbat_step", setAutoStep);
addConsoleActionI("set_etbat_period", setAutoPeriod);
addConsoleActionI("set_etbat_offset", setAutoOffset);
#endif /* EFI_PROD_CODE */
etbPidReset(PASS_ENGINE_PARAMETER_SIGNATURE);
for (int i = 0 ; i < engine->etbActualCount; i++) {
@ -637,6 +652,26 @@ void doInitElectronicThrottle(DECLARE_ENGINE_PARAMETER_SIGNATURE) {
}
}
void initElectronicThrottle(DECLARE_ENGINE_PARAMETER_SIGNATURE) {
if (hasFirmwareError()) {
return;
}
for (int i = 0; i < ETB_COUNT; i++) {
engine->etbControllers[i] = &etbControllers[i];
}
doInitElectronicThrottle(PASS_ENGINE_PARAMETER_SIGNATURE);
}
void setEtbIdlePosition(percent_t pos DECLARE_ENGINE_PARAMETER_SUFFIX) {
for (int i = 0; i < ETB_COUNT; i++) {
auto etb = engine->etbControllers[i];
if (etb) {
etb->setIdlePosition(pos);
}
}
}
#endif /* EFI_ELECTRONIC_THROTTLE_BODY */

View File

@ -12,21 +12,25 @@
#define DEFAULT_ETB_PWM_FREQUENCY 300
#include "engine.h"
#include "closed_loop_controller.h"
#include "expected.h"
#include "periodic_task.h"
class DcMotor;
class Logging;
class IEtbController : public PeriodicTimerController{
class IEtbController : public PeriodicTimerController, public ClosedLoopController<percent_t, percent_t> {
public:
DECLARE_ENGINE_PTR;
virtual void init(DcMotor *motor, int ownIndex, pid_s *pidParameters) = 0;
virtual void init(DcMotor *motor, int ownIndex, pid_s *pidParameters, const ValueProvider3D* pedalMap) = 0;
virtual void reset() = 0;
virtual void setIdlePosition(percent_t pos) = 0;
};
class EtbController final : public IEtbController {
public:
void init(DcMotor *motor, int ownIndex, pid_s *pidParameters) override;
void init(DcMotor *motor, int ownIndex, pid_s *pidParameters, const ValueProvider3D* pedalMap) override;
void setIdlePosition(percent_t pos) override;
// PeriodicTimerController implementation
int getPeriodMs() override;
@ -40,18 +44,42 @@ public:
// Print this throttle's status.
void showStatus(Logging* logger);
// Helpers for individual parts of throttle control
expected<percent_t> observePlant() const override;
expected<percent_t> getSetpoint() const override;
expected<percent_t> getOpenLoop(percent_t target) const override;
expected<percent_t> getClosedLoop(percent_t setpoint, percent_t target) override;
expected<percent_t> getClosedLoopAutotune(percent_t actualThrottlePosition);
void setOutput(expected<percent_t> outputValue) override;
// Used to inspect the internal PID controller's state
const pid_state_s* getPidState() const { return &m_pid; };
private:
int m_myIndex;
DcMotor *m_motor;
int m_myIndex = 0;
DcMotor *m_motor = nullptr;
Pid m_pid;
bool m_shouldResetPid = false;
// Pedal -> target map
const ValueProvider3D* m_pedalMap = nullptr;
float m_idlePosition = 0;
// Autotune helpers
bool m_lastIsPositive = false;
efitick_t m_cycleStartTime = 0;
float m_minCycleTps = 0;
float m_maxCycleTps = 0;
float m_a = 0;
float m_tu = 0;
};
void initElectronicThrottle(DECLARE_ENGINE_PARAMETER_SIGNATURE);
void doInitElectronicThrottle(DECLARE_ENGINE_PARAMETER_SIGNATURE);
void setEtbIdlePosition(percent_t pos DECLARE_ENGINE_PARAMETER_SUFFIX);
void setDefaultEtbBiasCurve(DECLARE_CONFIG_PARAMETER_SIGNATURE);
void setDefaultEtbParameters(DECLARE_CONFIG_PARAMETER_SIGNATURE);

View File

@ -0,0 +1,54 @@
#include "global.h"
#include "engine.h"
#include "gppwm_channel.h"
#include "pwm_generator_logic.h"
EXTERN_ENGINE;
static GppwmChannel channels[4];
static OutputPin pins[4];
static SimplePwm outputs[4];
static gppwm_Map3D_t table1("GPPWM 1");
static gppwm_Map3D_t table2("GPPWM 2");
static gppwm_Map3D_t table3("GPPWM 3");
static gppwm_Map3D_t table4("GPPWM 4");
static gppwm_Map3D_t* tables[] = {
&table1,
&table2,
&table3,
&table4,
};
void initGpPwm(DECLARE_ENGINE_PARAMETER_SIGNATURE) {
for (size_t i = 0; i < efi::size(channels); i++) {
auto& cfg = CONFIG(gppwm)[i];
// If no pin, don't enable this channel.
if (cfg.pin == GPIO_UNASSIGNED) continue;
// Determine frequency and whether PWM is enabled
float freq = cfg.pwmFrequency;
bool usePwm = freq > 0;
// Setup pin & pwm
pins[i].initPin("gp pwm", cfg.pin);
startSimplePwm(&outputs[i], "gp pwm", &engine->executor, &pins[i], freq, 0);
// Set up this channel's lookup table
tables[i]->init(cfg.table, cfg.loadBins, cfg.rpmBins);
// Finally configure the channel
INJECT_ENGINE_REFERENCE(&channels[i]);
channels[i].init(usePwm, &outputs[i], tables[i], &cfg);
}
}
void updateGppwm() {
for (size_t i = 0; i < efi::size(channels); i++) {
channels[i].update();
}
}

View File

@ -0,0 +1,6 @@
#pragma once
#include "engine.h"
void initGpPwm(DECLARE_ENGINE_PARAMETER_SIGNATURE);
void updateGppwm();

View File

@ -0,0 +1,89 @@
#include "gppwm_channel.h"
#include "engine.h"
#include "pwm_generator_logic.h"
#include "table_helper.h"
#include "expected.h"
#include "sensor.h"
#include "map.h"
EXTERN_ENGINE;
expected<float> readGppwmChannel(gppwm_channel_e channel DECLARE_ENGINE_PARAMETER_SUFFIX) {
switch (channel) {
case GPPWM_Tps:
return Sensor::get(SensorType::Tps1);
case GPPWM_Map: {
float map = getMap(PASS_ENGINE_PARAMETER_SIGNATURE);
if (cisnan(map)) {
return unexpected;
}
return map;
}
case GPPWM_Clt:
return Sensor::get(SensorType::Clt);
case GPPWM_Iat:
return Sensor::get(SensorType::Iat);
default:
return unexpected;
}
}
void GppwmChannel::setOutput(float result) {
// Not init yet, nothing to do.
if (!m_pwm || !m_config) {
return;
}
if (!m_usePwm) {
// Apply hysteresis with provided values
if (m_state && result < m_config->offBelowDuty) {
m_state = false;
} else if (!m_state && result > m_config->onAboveDuty) {
m_state = true;
}
result = m_state ? 100 : 0;
}
m_pwm->setSimplePwmDutyCycle(clampF(0, result / 100.0f, 1));
}
void GppwmChannel::init(bool usePwm, SimplePwm* pwm, const ValueProvider3D* table, const gppwm_channel* config) {
m_usePwm = usePwm;
m_pwm = pwm;
m_table = table;
m_config = config;
}
float GppwmChannel::getOutput() const {
expected<float> loadAxisValue = readGppwmChannel(m_config->loadAxis PASS_ENGINE_PARAMETER_SUFFIX);
// If we couldn't get load axis value, fall back on error value
if (!loadAxisValue) {
return m_config->dutyIfError;
}
float rpm = GET_RPM();
float result = m_table->getValue(rpm / RPM_1_BYTE_PACKING_MULT, loadAxisValue.Value);
if (cisnan(result)) {
return m_config->dutyIfError;
}
return result;
}
void GppwmChannel::update() {
// Without a config, nothing to do.
if (!m_config) {
return;
}
float output = getOutput();
setOutput(output);
}

View File

@ -0,0 +1,28 @@
#pragma once
#include "gppwm.h"
class OutputPin;
class SimplePwm;
class ValueProvider3D;
class GppwmChannel {
public:
DECLARE_ENGINE_PTR;
void init(bool usePwm, SimplePwm* pwm, const ValueProvider3D* table, const gppwm_channel* config);
void update();
private:
float getOutput() const;
void setOutput(float result);
// Store the current state so we can apply hysteresis
bool m_state = false;
// Configuration fields
const gppwm_channel* m_config = nullptr;
bool m_usePwm = false;
SimplePwm* m_pwm = nullptr;
const ValueProvider3D* m_table = nullptr;
};

View File

@ -32,13 +32,15 @@
#if EFI_IDLE_CONTROL
#include "engine_configuration.h"
#include "rpm_calculator.h"
#include "pwm_generator.h"
#include "pwm_generator_logic.h"
#include "idle_thread.h"
#include "engine_math.h"
#include "engine.h"
#include "periodic_task.h"
#include "allsensors.h"
#include "sensor.h"
#include "electronic_throttle.h"
#if ! EFI_UNIT_TEST
#include "stepper.h"
@ -52,8 +54,7 @@ static StepperMotor iacMotor;
static Logging *logger;
EXTERN_ENGINE
;
EXTERN_ENGINE;
static bool shouldResetPid = false;
// The idea of 'mightResetPid' is to reset PID only once - each time when TPS > idlePidDeactivationTpsThreshold.
@ -92,7 +93,8 @@ PidWithOverrides idlePid;
#endif /* EFI_IDLE_PID_CIC */
// todo: extract interface for idle valve hardware, with solenoid and stepper implementations?
static SimplePwm idleSolenoid("idle");
static SimplePwm idleSolenoidOpen("idle open");
static SimplePwm idleSolenoidClose("idle close");
static uint32_t lastCrankingCyclesCounter = 0;
static float lastCrankingIacPosition;
@ -125,11 +127,16 @@ static void showIdleInfo(void) {
scheduleMsg(logger, "enablePin=%s/%d", hwPortname(engineConfiguration->stepperEnablePin),
engineConfiguration->stepperEnablePinMode);
} else {
scheduleMsg(logger, "idle valve freq=%d on %s", CONFIG(idle).solenoidFrequency,
hwPortname(CONFIG(idle).solenoidPin));
if (!CONFIG(isDoubleSolenoidIdle)) {
scheduleMsg(logger, "idle valve freq=%d on %s", CONFIG(idle).solenoidFrequency,
hwPortname(CONFIG(idle).solenoidPin));
} else {
scheduleMsg(logger, "idle valve freq=%d on %s", CONFIG(idle).solenoidFrequency,
hwPortname(CONFIG(idle).solenoidPin));
scheduleMsg(logger, " and %s", hwPortname(CONFIG(secondSolenoidPin)));
}
}
if (engineConfiguration->idleMode == IM_AUTO) {
idlePid.showPidStatus(logger, "idle");
}
@ -141,18 +148,39 @@ void setIdleMode(idle_mode_e value) {
}
static void applyIACposition(percent_t position) {
/**
* currently idle level is an percent value (0-100 range), and PWM takes a float in the 0..1 range
* todo: unify?
*/
float duty = PERCENT_TO_DUTY(position);
if (CONFIG(useETBforIdleControl)) {
engine->engineState.idle.etbIdleAddition = position / 100 * CONFIG(etbIdleThrottleRange);
if (!Sensor::hasSensor(SensorType::AcceleratorPedal)) {
firmwareError(CUSTOM_NO_ETB_FOR_IDLE, "No ETB to use for idle");
return;
}
#if EFI_ELECTRONIC_THROTTLE_BODY
setEtbIdlePosition(position);
#endif
#if ! EFI_UNIT_TEST
} if (CONFIG(useStepperIdle)) {
iacMotor.setTargetPosition(position / 100 * engineConfiguration->idleStepperTotalSteps);
iacMotor.setTargetPosition(duty * engineConfiguration->idleStepperTotalSteps);
#endif /* EFI_UNIT_TEST */
} else {
/**
* currently idle level is an percent value (0-100 range), and PWM takes a float in the 0..1 range
* todo: unify?
*/
idleSolenoid.setSimplePwmDutyCycle(PERCENT_TO_DUTY(position));
if (!CONFIG(isDoubleSolenoidIdle)) {
idleSolenoidOpen.setSimplePwmDutyCycle(duty);
} else {
/* use 0.01..0.99 range */
float idle_range = 0.98; /* move to config? */
float idle_open, idle_close;
idle_open = 0.01 + idle_range * duty;
idle_close = 0.01 + idle_range * (1.0 - duty);
idleSolenoidOpen.setSimplePwmDutyCycle(idle_open);
idleSolenoidClose.setSimplePwmDutyCycle(idle_close);
}
}
}
@ -177,10 +205,6 @@ static percent_t manualIdleController(float cltCorrection DECLARE_ENGINE_PARAMET
percent_t correctedPosition = cltCorrection * CONFIG(manIdlePosition);
// let's put the value into the right range
correctedPosition = maxF(correctedPosition, 0.01);
correctedPosition = minF(correctedPosition, 99.9);
return correctedPosition;
}
@ -218,21 +242,20 @@ static bool isOutOfAutomaticIdleCondition(DECLARE_ENGINE_PARAMETER_SIGNATURE) {
return !engine->engineState.idle.throttlePedalUpState;
}
percent_t inputPosition;
const auto [valid, pos] = Sensor::get(SensorType::DriverThrottleIntent);
if (hasPedalPositionSensor(PASS_ENGINE_PARAMETER_SIGNATURE)) {
inputPosition = getPedalPosition(PASS_ENGINE_PARAMETER_SIGNATURE);
} else {
inputPosition = getTPS(PASS_ENGINE_PARAMETER_SIGNATURE);
// Disable auto idle in case of TPS/Pedal failure
if (!valid) {
return true;
}
return inputPosition > CONFIG(idlePidDeactivationTpsThreshold);
return pos > CONFIG(idlePidDeactivationTpsThreshold);
}
/**
* @return idle valve position percentage for automatic closed loop mode
*/
static percent_t automaticIdleController(DECLARE_ENGINE_PARAMETER_SIGNATURE) {
static percent_t automaticIdleController(float tpsPos DECLARE_ENGINE_PARAMETER_SUFFIX) {
if (isOutOfAutomaticIdleCondition(PASS_ENGINE_PARAMETER_SIGNATURE)) {
// Don't store old I and D terms if PID doesn't work anymore.
// Otherwise they will affect the idle position much later, when the throttle is closed.
@ -288,7 +311,6 @@ static percent_t automaticIdleController(DECLARE_ENGINE_PARAMETER_SIGNATURE) {
}
// Apply PID Deactivation Threshold as a smooth taper for TPS transients.
percent_t tpsPos = getTPS(PASS_ENGINE_PARAMETER_SIGNATURE);
// if tps==0 then PID just works as usual, or we completely disable it if tps>=threshold
newValue = interpolateClamped(0.0f, newValue, CONFIG(idlePidDeactivationTpsThreshold), engine->engineState.idle.baseIdlePosition, tpsPos);
@ -300,8 +322,9 @@ static percent_t automaticIdleController(DECLARE_ENGINE_PARAMETER_SIGNATURE) {
int idlePidLowerRpm = targetRpm + CONFIG(idlePidRpmDeadZone);
if (CONFIG(idlePidRpmUpperLimit) > 0) {
engine->engineState.idle.idleState = PID_UPPER;
if (CONFIG(useIacTableForCoasting) && hasCltSensor()) {
percent_t iacPosForCoasting = interpolate2d("iacCoasting", getCoolantTemperature(), CONFIG(iacCoastingBins), CONFIG(iacCoasting));
const auto [cltValid, clt] = Sensor::get(SensorType::Clt);
if (CONFIG(useIacTableForCoasting) && cltValid) {
percent_t iacPosForCoasting = interpolate2d("iacCoasting", clt, CONFIG(iacCoastingBins), CONFIG(iacCoasting));
newValue = interpolateClamped(idlePidLowerRpm, newValue, idlePidLowerRpm + CONFIG(idlePidRpmUpperLimit), iacPosForCoasting, rpm);
} else {
// Well, just leave it as is, without PID regulation...
@ -327,7 +350,9 @@ static percent_t automaticIdleController(DECLARE_ENGINE_PARAMETER_SIGNATURE) {
idlePid.iTermMin = engineConfiguration->idlerpmpid_iTermMin;
idlePid.iTermMax = engineConfiguration->idlerpmpid_iTermMax;
engine->engineState.isAutomaticIdle = engineConfiguration->idleMode == IM_AUTO;
SensorResult tps = Sensor::get(SensorType::DriverThrottleIntent);
engine->engineState.isAutomaticIdle = tps.Valid && engineConfiguration->idleMode == IM_AUTO;
if (engineConfiguration->isVerboseIAC && engine->engineState.isAutomaticIdle) {
// todo: print each bit using 'getIdle_state_e' method
@ -370,7 +395,7 @@ static percent_t automaticIdleController(DECLARE_ENGINE_PARAMETER_SIGNATURE) {
finishIdleTestIfNeeded();
undoIdleBlipIfNeeded();
float clt = getCoolantTemperature();
const auto [cltValid, clt] = Sensor::get(SensorType::Clt);
#if EFI_SHAFT_POSITION_INPUT
bool isRunning = engine->rpmCalculator.isRunning(PASS_ENGINE_PARAMETER_SIGNATURE);
#else
@ -378,7 +403,7 @@ static percent_t automaticIdleController(DECLARE_ENGINE_PARAMETER_SIGNATURE) {
#endif /* EFI_SHAFT_POSITION_INPUT */
// cltCorrection is used only for cranking or running in manual mode
float cltCorrection;
if (!hasCltSensor())
if (!cltValid)
cltCorrection = 1.0f;
// Use separate CLT correction table for cranking
else if (engineConfiguration->overrideCrankingIacSetting && !isRunning) {
@ -397,25 +422,29 @@ static percent_t automaticIdleController(DECLARE_ENGINE_PARAMETER_SIGNATURE) {
engine->engineState.idle.idleState = BLIP;
} else if (!isRunning) {
// during cranking it's always manual mode, PID would make no sense during cranking
iacPosition = cltCorrection * engineConfiguration->crankingIACposition;
iacPosition = clampPercentValue(cltCorrection * engineConfiguration->crankingIACposition);
// save cranking position & cycles counter for taper transition
lastCrankingIacPosition = iacPosition;
lastCrankingCyclesCounter = engine->rpmCalculator.getRevolutionCounterSinceStart();
engine->engineState.idle.baseIdlePosition = iacPosition;
} else {
if (engineConfiguration->idleMode == IM_MANUAL) {
if (!tps.Valid || engineConfiguration->idleMode == IM_MANUAL) {
// let's re-apply CLT correction
iacPosition = manualIdleController(cltCorrection PASS_ENGINE_PARAMETER_SUFFIX);
} else {
iacPosition = automaticIdleController(PASS_ENGINE_PARAMETER_SIGNATURE);
iacPosition = automaticIdleController(tps.Value PASS_ENGINE_PARAMETER_SUFFIX);
}
iacPosition = clampPercentValue(iacPosition);
// store 'base' iacPosition without adjustments
engine->engineState.idle.baseIdlePosition = iacPosition;
percent_t tpsPos = getTPS(PASS_ENGINE_PARAMETER_SIGNATURE);
float additionalAir = (float)engineConfiguration->iacByTpsTaper;
iacPosition += interpolateClamped(0.0f, 0.0f, CONFIG(idlePidDeactivationTpsThreshold), additionalAir, tpsPos);
if (tps.Valid) {
iacPosition += interpolateClamped(0.0f, 0.0f, CONFIG(idlePidDeactivationTpsThreshold), additionalAir, tps.Value);
}
// taper transition from cranking to running (uint32_t to float conversion is safe here)
if (engineConfiguration->afterCrankingIACtaperDuration > 0)
@ -475,7 +504,8 @@ void setDefaultIdleParameters(DECLARE_CONFIG_PARAMETER_SIGNATURE) {
void onConfigurationChangeIdleCallback(engine_configuration_s *previousConfiguration) {
shouldResetPid = !idlePid.isSame(&previousConfiguration->idleRpmPid);
idleSolenoid.setFrequency(CONFIG(idle).solenoidFrequency);
idleSolenoidOpen.setFrequency(CONFIG(idle).solenoidFrequency);
idleSolenoidClose.setFrequency(CONFIG(idle).solenoidFrequency);
}
void setTargetIdleRpm(int value) {
@ -542,7 +572,8 @@ bool isIdleHardwareRestartNeeded() {
isConfigurationChanged(useStepperIdle) ||
// isConfigurationChanged() ||
isConfigurationChanged(useETBforIdleControl) ||
isConfigurationChanged(idle.solenoidPin);
isConfigurationChanged(idle.solenoidPin) ||
isConfigurationChanged(secondSolenoidPin);
}
@ -551,6 +582,7 @@ void stopIdleHardware(DECLARE_ENGINE_PARAMETER_SIGNATURE) {
brain_pin_markUnused(activeConfiguration.stepperEnablePin);
brain_pin_markUnused(activeConfiguration.idle.stepperStepPin);
brain_pin_markUnused(activeConfiguration.idle.solenoidPin);
brain_pin_markUnused(activeConfiguration.secondSolenoidPin);
// brain_pin_markUnused(activeConfiguration.idle.);
// brain_pin_markUnused(activeConfiguration.idle.);
// brain_pin_markUnused(activeConfiguration.idle.);
@ -598,11 +630,25 @@ void initIdleHardware(DECLARE_ENGINE_PARAMETER_SIGNATURE) {
*/
// todo: even for double-solenoid mode we can probably use same single SimplePWM
// todo: open question why do we pass 'OutputPin' into 'startSimplePwmExt' if we have custom applyIdleSolenoidPinState listener anyway?
startSimplePwmExt(&idleSolenoid, "Idle Valve",
&engine->executor,
CONFIG(idle).solenoidPin, &enginePins.idleSolenoidPin,
CONFIG(idle).solenoidFrequency, CONFIG(manIdlePosition) / 100,
(pwm_gen_callback*)applyIdleSolenoidPinState);
if (!CONFIG(isDoubleSolenoidIdle)) {
startSimplePwmExt(&idleSolenoidOpen, "Idle Valve",
&engine->executor,
CONFIG(idle).solenoidPin, &enginePins.idleSolenoidPin,
CONFIG(idle).solenoidFrequency, PERCENT_TO_DUTY(CONFIG(manIdlePosition)),
(pwm_gen_callback*)applyIdleSolenoidPinState);
} else {
startSimplePwmExt(&idleSolenoidOpen, "Idle Valve Open",
&engine->executor,
CONFIG(idle).solenoidPin, &enginePins.idleSolenoidPin,
CONFIG(idle).solenoidFrequency, PERCENT_TO_DUTY(CONFIG(manIdlePosition)),
(pwm_gen_callback*)applyIdleSolenoidPinState);
startSimplePwmExt(&idleSolenoidClose, "Idle Valve Close",
&engine->executor,
CONFIG(secondSolenoidPin), &enginePins.secondIdleSolenoidPin,
CONFIG(idle).solenoidFrequency, PERCENT_TO_DUTY(CONFIG(manIdlePosition)),
(pwm_gen_callback*)applyIdleSolenoidPinState);
}
idlePositionSensitivityThreshold = 0.0f;
}
}

View File

@ -14,14 +14,12 @@
#include "state_requence.h"
#include "pwm_generator_logic.h"
#include "engine.h"
#include "pwm_generator.h"
static LoggingWithStorage logger;
static SimplePwm pwmTest[5];
extern OutputPin warningLedPin;
extern EnginePins enginePins;
EXTERN_ENGINE;
@ -31,18 +29,18 @@ static void startPwmTest(int freq) {
engine->isRunningPwmTest = true;
// PD13 pin is initialized elsewhere already
startSimplePwm(&pwmTest[0], "tester", &warningLedPin, 10, 0.5f, applyPinState);
startSimplePwm(&pwmTest[0], "tester", &warningLedPin, 10, 0.5f);
/**
* See custom_engine.cpp for pinout
*/
// currently this is PB9 by default - see CONFIG(injectionPins)
startSimplePwm(&pwmTest[1], "tester", &enginePins.injectors[0], freq / 1.3333333333, 0.5f, applyPinState);
startSimplePwm(&pwmTest[1], "tester", &enginePins.injectors[0], freq / 1.3333333333, 0.5f);
// currently this is PE2 by default
startSimplePwm(&pwmTest[2], "tester", &enginePins.injectors[1], freq / 1000, 0.5f, applyPinState);
startSimplePwm(&pwmTest[2], "tester", &enginePins.injectors[1], freq / 1000, 0.5f);
// currently this is PB8 by default
startSimplePwm(&pwmTest[3], "tester", &enginePins.injectors[2], freq, 0.5, applyPinState);
startSimplePwm(&pwmTest[3], "tester", &enginePins.injectors[2], freq, 0.5);
// currently this is PB7 by default
startSimplePwm(&pwmTest[4], "tester", &enginePins.injectors[3], freq / 33.33333333333, 0.5, applyPinState);
startSimplePwm(&pwmTest[4], "tester", &enginePins.injectors[3], freq / 33.33333333333, 0.5);
}

View File

@ -4,9 +4,7 @@
* @date Apr 29, 2014
* @author Andrey Belomutskiy, (c) 2012-2020
*/
#ifndef PWMTESTER_H_
#define PWMTESTER_H_
#pragma once
void initPwmTester(void);
#endif /* PWMTESTER_H_ */

View File

@ -32,8 +32,7 @@
#include "tunerstudio_configuration.h"
#endif /* EFI_TUNER_STUDIO */
EXTERN_ENGINE
;
EXTERN_ENGINE;
tps_tps_Map3D_t tpsTpsMap("tpsTps");
@ -286,8 +285,7 @@ void AccelEnrichment::onNewValue(float currentValue DECLARE_ENGINE_PARAMETER_SUF
}
void TpsAccelEnrichment::onEngineCycleTps(DECLARE_ENGINE_PARAMETER_SIGNATURE) {
// we update values in handleFuel() directly
//onNewValue(getTPS(PASS_ENGINE_PARAMETER_SIGNATURE) PASS_ENGINE_PARAMETER_SUFFIX);
// we update values in handleFuel() directly by calling onNewValue()
onUpdateInvocationCounter++;

View File

@ -24,14 +24,14 @@
#include "advance_map.h"
#include "interpolation.h"
#include "engine_math.h"
#include "tps.h"
#include "sensor.h"
#include "idle_thread.h"
#include "allsensors.h"
#include "launch_control.h"
#if EFI_ENGINE_CONTROL
EXTERN_ENGINE
;
EXTERN_ENGINE;
static ign_Map3D_t advanceMap("advance");
// This coeff in ctor parameter is sufficient for int16<->float conversion!
@ -69,37 +69,26 @@ static const ignition_table_t defaultIatTiming = {
#endif /* IGN_LOAD_COUNT == DEFAULT_IGN_LOAD_COUNT */
//Todo: There are some more conditions that needs to be true, and RPM range must be added to launchrpm?
//bool isLaunchCondition(int rpm DECLARE_ENGINE_PARAMETER_SUFFIX) {
// return CONFIG(launchControlEnabled) && rpm >= engineConfiguration->launchRpm;
//}
/**
* @return ignition timing angle advance before TDC
*/
static angle_t getRunningAdvance(int rpm, float engineLoad DECLARE_ENGINE_PARAMETER_SUFFIX) {
if (CONFIG(timingMode) == TM_FIXED)
if (CONFIG(timingMode) == TM_FIXED) {
return engineConfiguration->fixedTiming;
}
engine->m.beforeAdvance = getTimeNowLowerNt();
if (cisnan(engineLoad)) {
warning(CUSTOM_NAN_ENGINE_LOAD, "NaN engine load");
return NAN;
}
efiAssert(CUSTOM_ERR_ASSERT, !cisnan(engineLoad), "invalid el", NAN);
engine->m.beforeZeroTest = getTimeNowLowerNt();
engine->m.zeroTestTime = getTimeNowLowerNt() - engine->m.beforeZeroTest;
//See comment at line 70
// if (isLaunchCondition(rpm PASS_ENGINE_PARAMETER_SUFFIX)) {
// return engineConfiguration->launchTimingRetard;
// }
efiAssert(CUSTOM_ERR_ASSERT, !cisnan(engineLoad), "invalid el", NAN);
float advanceAngle;
if (CONFIG(useTPSAdvanceTable)) {
float tps = getTPS(PASS_ENGINE_PARAMETER_SIGNATURE);
advanceAngle = advanceTpsMap.getValue((float) rpm, tps);
// TODO: what do we do about multi-TPS?
float tps = Sensor::get(SensorType::Tps1).value_or(0);
advanceAngle = advanceTpsMap.getValue(rpm, tps);
} else {
advanceAngle = advanceMap.getValue((float) rpm, engineLoad);
}
@ -107,29 +96,53 @@ static angle_t getRunningAdvance(int rpm, float engineLoad DECLARE_ENGINE_PARAME
// get advance from the separate table for Idle
if (CONFIG(useSeparateAdvanceForIdle)) {
float idleAdvance = interpolate2d("idleAdvance", rpm, config->idleAdvanceBins, config->idleAdvance);
// interpolate between idle table and normal (running) table using TPS threshold
float tps = getTPS(PASS_ENGINE_PARAMETER_SIGNATURE);
advanceAngle = interpolateClamped(0.0f, idleAdvance, CONFIG(idlePidDeactivationTpsThreshold), advanceAngle, tps);
auto [valid, tps] = Sensor::get(SensorType::DriverThrottleIntent);
if (valid) {
// interpolate between idle table and normal (running) table using TPS threshold
advanceAngle = interpolateClamped(0.0f, idleAdvance, CONFIG(idlePidDeactivationTpsThreshold), advanceAngle, tps);
}
}
engine->m.advanceLookupTime = getTimeNowLowerNt() - engine->m.beforeAdvance;
#if EFI_LAUNCH_CONTROL
if (engine->isLaunchCondition && CONFIG(enableLaunchRetard)) {
if (CONFIG(launchSmoothRetard)) {
float launchAngle = CONFIG(launchTimingRetard);
int launchAdvanceRpmRange = CONFIG(launchTimingRpmRange);
int launchRpm = CONFIG(launchRpm);
// interpolate timing from rpm at launch triggered to full retard at launch launchRpm + launchTimingRpmRange
return interpolateClamped(launchRpm, advanceAngle, (launchRpm + launchAdvanceRpmRange), launchAngle, rpm);
} else {
return engineConfiguration->launchTimingRetard;
}
}
#endif /* EFI_LAUNCH_CONTROL */
return advanceAngle;
}
angle_t getAdvanceCorrections(int rpm DECLARE_ENGINE_PARAMETER_SUFFIX) {
float iatCorrection;
if (!hasIatSensor()) {
const auto [iatValid, iat] = Sensor::get(SensorType::Iat);
if (!iatValid) {
iatCorrection = 0;
} else {
iatCorrection = iatAdvanceCorrectionMap.getValue((float) rpm, getIntakeAirTemperature());
iatCorrection = iatAdvanceCorrectionMap.getValue((float) rpm, iat);
}
// PID Ignition Advance angle correction
float pidTimingCorrection = 0.0f;
if (CONFIG(useIdleTimingPidControl)) {
int targetRpm = getTargetRpmForIdleCorrection(PASS_ENGINE_PARAMETER_SIGNATURE);
int rpmDelta = absI(rpm - targetRpm);
float tps = getTPS(PASS_ENGINE_PARAMETER_SIGNATURE);
if (tps >= CONFIG(idlePidDeactivationTpsThreshold)) {
auto [valid, tps] = Sensor::get(SensorType::Tps1);
// If TPS is invalid, or we aren't in the region, so reset state and don't apply PID
if (!valid || tps >= CONFIG(idlePidDeactivationTpsThreshold)) {
// we are not in the idle mode anymore, so the 'reset' flag will help us when we return to the idle.
shouldResetTimingPid = true;
}
@ -160,6 +173,7 @@ angle_t getAdvanceCorrections(int rpm DECLARE_ENGINE_PARAMETER_SUFFIX) {
tsOutputChannels.debugFloatField2 = engine->engineState.cltTimingCorrection;
tsOutputChannels.debugFloatField3 = engine->fsioState.fsioTimingAdjustment;
tsOutputChannels.debugFloatField4 = pidTimingCorrection;
tsOutputChannels.debugIntField1 = engine->engineState.multispark.count;
#endif /* EFI_TUNER_STUDIO */
}
@ -194,31 +208,35 @@ angle_t getAdvance(int rpm, float engineLoad DECLARE_ENGINE_PARAMETER_SUFFIX) {
if (cisnan(engineLoad)) {
return 0; // any error should already be reported
}
angle_t angle;
if (ENGINE(rpmCalculator).isCranking(PASS_ENGINE_PARAMETER_SIGNATURE)) {
bool isCranking = ENGINE(rpmCalculator).isCranking(PASS_ENGINE_PARAMETER_SIGNATURE);
if (isCranking) {
angle = getCrankingAdvance(rpm, engineLoad PASS_ENGINE_PARAMETER_SUFFIX);
assertAngleRange(angle, "crAngle", CUSTOM_ERR_6680);
efiAssert(CUSTOM_ERR_ASSERT, !cisnan(angle), "cr_AngleN", 0);
if (CONFIG(useAdvanceCorrectionsForCranking)) {
angle_t correction = getAdvanceCorrections(rpm PASS_ENGINE_PARAMETER_SUFFIX);
if (!cisnan(correction)) { // correction could be NaN during settings update
angle += correction;
}
}
efiAssert(CUSTOM_ERR_ASSERT, !cisnan(angle), "cr_AngleN2", 0);
} else {
angle = getRunningAdvance(rpm, engineLoad PASS_ENGINE_PARAMETER_SUFFIX);
if (cisnan(angle)) {
warning(CUSTOM_ERR_6610, "NaN angle from table");
return 0;
}
}
// Allow correction only if set to dynamic
// AND we're either not cranking OR allowed to correct in cranking
bool allowCorrections = CONFIG(timingMode) == TM_DYNAMIC
&& (!isCranking || CONFIG(useAdvanceCorrectionsForCranking));
if (allowCorrections) {
angle_t correction = getAdvanceCorrections(rpm PASS_ENGINE_PARAMETER_SUFFIX);
if (!cisnan(correction)) { // correction could be NaN during settings update
angle += correction;
}
efiAssert(CUSTOM_ERR_ASSERT, !cisnan(angle), "AngleN3", 0);
}
efiAssert(CUSTOM_ERR_ASSERT, !cisnan(angle), "_AngleN4", 0);
angle -= engineConfiguration->ignitionOffset;
efiAssert(CUSTOM_ERR_ASSERT, !cisnan(angle), "_AngleN5", 0);
fixAngle(angle, "getAdvance", CUSTOM_ERR_ADCANCE_CALC_ANGLE);
@ -228,6 +246,43 @@ angle_t getAdvance(int rpm, float engineLoad DECLARE_ENGINE_PARAMETER_SUFFIX) {
#endif
}
size_t getMultiSparkCount(int rpm DECLARE_ENGINE_PARAMETER_SUFFIX) {
// Compute multispark (if enabled)
if (CONFIG(multisparkEnable)
&& rpm <= CONFIG(multisparkMaxRpm)
&& CONFIG(multisparkMaxExtraSparkCount) > 0) {
// For zero RPM, disable multispark. We don't yet know the engine speed, so multispark may not be safe.
if (rpm == 0) {
return 0;
}
floatus_t multiDelay = CONFIG(multisparkSparkDuration);
floatus_t multiDwell = CONFIG(multisparkDwell);
ENGINE(engineState.multispark.delay) = US2NT(multiDelay);
ENGINE(engineState.multispark.dwell) = US2NT(multiDwell);
constexpr float usPerDegreeAt1Rpm = 60e6 / 360;
floatus_t usPerDegree = usPerDegreeAt1Rpm / rpm;
// How long is there for sparks? The user configured an angle, convert to time.
floatus_t additionalSparksUs = usPerDegree * CONFIG(multisparkMaxSparkingAngle);
// How long does one spark take?
floatus_t oneSparkTime = multiDelay + multiDwell;
// How many sparks can we fit in the alloted time?
float sparksFitInTime = additionalSparksUs / oneSparkTime;
// Take the floor (convert to uint8_t) - we want to undershoot, not overshoot
uint32_t floored = sparksFitInTime;
// Allow no more than the maximum number of extra sparks
return minI(floored, CONFIG(multisparkMaxExtraSparkCount));
} else {
return 0;
}
}
void setDefaultIatTimingCorrection(DECLARE_ENGINE_PARAMETER_SIGNATURE) {
setLinearCurve(config->ignitionIatCorrLoadBins, /*from*/CLT_CURVE_RANGE_FROM, 110, 1);
#if IGN_LOAD_COUNT == DEFAULT_IGN_LOAD_COUNT

View File

@ -16,3 +16,4 @@ float getTopAdvanceForBore(chamber_style_e style, int octane, double compression
float getInitialAdvance(int rpm, float map, float advanceMax);
void buildTimingMap(float advanceMax DECLARE_CONFIG_PARAMETER_SUFFIX);
angle_t getAdvanceCorrections(int rpm DECLARE_ENGINE_PARAMETER_SUFFIX);
size_t getMultiSparkCount(int rpm DECLARE_ENGINE_PARAMETER_SUFFIX);

View File

@ -5,6 +5,7 @@ CONTROLLERS_ALGO_SRC_CPP = $(PROJECT_DIR)/controllers/algo/advance_map.cpp \
$(GENERATED_ENUMS_DIR)/auto_generated_enums.cpp \
$(PROJECT_DIR)/controllers/algo/fuel_math.cpp \
$(PROJECT_DIR)/controllers/algo/accel_enrichment.cpp \
$(PROJECT_DIR)/controllers/algo/launch_control.cpp \
$(PROJECT_DIR)/controllers/algo/engine_configuration.cpp \
$(PROJECT_DIR)/controllers/algo/engine.cpp \
$(PROJECT_DIR)/controllers/algo/engine2.cpp \

View File

@ -485,21 +485,11 @@ case TLE8888_PIN_9:
}
return NULL;
}
const char *getCan_device_mode_e(can_device_mode_e value){
switch(value) {
case CD_OFF:
return "CD_OFF";
case CD_USE_CAN1:
return "CD_USE_CAN1";
case CD_USE_CAN2:
return "CD_USE_CAN2";
case Internal_ForceMyEnumIntSize_can_device_mode:
return "Internal_ForceMyEnumIntSize_can_device_mode";
}
return NULL;
}
const char *getCan_nbc_e(can_nbc_e value){
switch(value) {
case CAN_BUS_NBC_NONE:
return "CAN_BUS_NBC_NONE";
case CAN_BUS_MAZDA_RX8:
return "CAN_BUS_MAZDA_RX8";
case CAN_BUS_NBC_BMW:
@ -508,6 +498,8 @@ case CAN_BUS_NBC_FIAT:
return "CAN_BUS_NBC_FIAT";
case CAN_BUS_NBC_VAG:
return "CAN_BUS_NBC_VAG";
case CAN_BUS_W202_C180:
return "CAN_BUS_W202_C180";
case Internal_ForceMyEnumIntSize_can_nbc:
return "Internal_ForceMyEnumIntSize_can_nbc";
}
@ -541,8 +533,14 @@ const char *getDebug_mode_e(debug_mode_e value){
switch(value) {
case DBG_BOOST:
return "DBG_BOOST";
case DBG_37:
return "DBG_37";
case DBG_START_STOP:
return "DBG_START_STOP";
case DBG_LAUNCH:
return "DBG_LAUNCH";
case DBG_ETB_AUTOTUNE:
return "DBG_ETB_AUTOTUNE";
case DBG_40:
return "DBG_40";
case DBG_ALTERNATOR_PID:
return "DBG_ALTERNATOR_PID";
case DBG_ANALOG_INPUTS:
@ -551,8 +549,8 @@ case DBG_ANALOG_INPUTS2:
return "DBG_ANALOG_INPUTS2";
case DBG_AUX_PID_1:
return "DBG_AUX_PID_1";
case DBG_AUX_TEMPERATURE:
return "DBG_AUX_TEMPERATURE";
case DBG_34:
return "DBG_34";
case DBG_AUX_VALVES:
return "DBG_AUX_VALVES";
case DBG_BENCH_TEST:
@ -607,8 +605,8 @@ case DBG_TPS_ACCEL:
return "DBG_TPS_ACCEL";
case DBG_TRIGGER_COUNTERS:
return "DBG_TRIGGER_COUNTERS";
case DBG_TRIGGER_SYNC:
return "DBG_TRIGGER_SYNC";
case DBG_16:
return "DBG_16";
case DBG_VEHICLE_SPEED_SENSOR:
return "DBG_VEHICLE_SPEED_SENSOR";
case DBG_VVT:
@ -719,6 +717,8 @@ case BMW_M73_M:
return "BMW_M73_M";
case BMW_M73_MRE:
return "BMW_M73_MRE";
case BMW_M73_MRE_SLAVE:
return "BMW_M73_MRE_SLAVE";
case BMW_M73_PROTEUS:
return "BMW_M73_P";
case MRE_BOARD_TEST:
@ -959,6 +959,8 @@ case FOUR_STROKE_CAM_SENSOR:
return "FOUR_STROKE_CAM_SENSOR";
case FOUR_STROKE_CRANK_SENSOR:
return "FOUR_STROKE_CRANK_SENSOR";
case FOUR_STROKE_THREE_TIMES_CRANK_SENSOR:
return "FOUR_STROKE_THREE_TIMES_CRANK_SENSOR";
case FOUR_STROKE_SYMMETRICAL_CRANK_SENSOR:
return "FOUR_STROKE_SYMMETRICAL_CRANK_SENSOR";
case Force_4_bytes_size_operation_mode_e:
@ -1155,6 +1157,14 @@ case TT_MAZDA_MIATA_VVT_TEST:
return "TT_MAZDA_MIATA_VVT_TEST";
case TT_MAZDA_SOHC_4:
return "TT_MAZDA_SOHC_4";
case TT_BOSCH_QUICK_START:
return "TT_BOSCH_QUICK_START";
case TT_HONDA_K_12_1:
return "TT_HONDA_K_12_1";
case TT_RENIX_66_2_2_2:
return "TT_RENIX_66_2_2_2";
case TT_RENIX_44_2_2:
return "TT_RENIX_44_2_2";
case TT_MIATA_NB2_VVT_CAM:
return "TT_MIATA_NB2_VVT_CAM";
case TT_MAZDA_Z5:

View File

@ -16,7 +16,7 @@ const char *getAdc_channel_e(adc_channel_e value);
const char *getAdc_channel_mode_e(adc_channel_mode_e value);
const char *getAir_pressure_sensor_type_e(air_pressure_sensor_type_e value);
const char *getBrain_pin_e(brain_pin_e value);
const char *getCan_device_mode_e(can_device_mode_e value);
const char *getCan_nbc_e(can_nbc_e value);
const char *getChamber_style_e(chamber_style_e value);
const char *getCranking_ignition_mode_e(cranking_ignition_mode_e value);

View File

@ -9,7 +9,6 @@
* @author Andrey Belomutskiy, (c) 2012-2020
*/
#include "global.h"
#include "engine.h"
#include "allsensors.h"
#include "efi_gpio.h"
@ -25,9 +24,11 @@
#include "map_averaging.h"
#include "fsio_impl.h"
#include "perf_trace.h"
#include "sensor.h"
#include "gppwm.h"
#if EFI_PROD_CODE
#include "injector_central.h"
#include "bench_test.h"
#else
#define isRunningBenchTest() true
#endif /* EFI_PROD_CODE */
@ -40,8 +41,7 @@ static TriggerState initState CCM_OPTIONAL;
LoggingWithStorage engineLogger("engine");
EXTERN_ENGINE
;
EXTERN_ENGINE;
#if EFI_ENGINE_SNIFFER
#include "engine_sniffer.h"
@ -79,9 +79,9 @@ void Engine::initializeTriggerWaveform(Logging *logger DECLARE_ENGINE_PARAMETER_
if (TRIGGER_WAVEFORM(bothFrontsRequired) && engineConfiguration->useOnlyRisingEdgeForTrigger) {
#if EFI_PROD_CODE || EFI_SIMULATOR
firmwareError(CUSTOM_ERR_BOTH_FRONTS_REQUIRED, "Inconsistent trigger setup");
firmwareError(CUSTOM_ERR_BOTH_FRONTS_REQUIRED, "trigger: both fronts required");
#else
warning(CUSTOM_ERR_BOTH_FRONTS_REQUIRED, "Inconsistent trigger setup");
warning(CUSTOM_ERR_BOTH_FRONTS_REQUIRED, "trigger: both fronts required");
#endif
}
@ -115,7 +115,7 @@ static void cylinderCleanupControl(DECLARE_ENGINE_PARAMETER_SIGNATURE) {
#if EFI_ENGINE_CONTROL
bool newValue;
if (engineConfiguration->isCylinderCleanupEnabled) {
newValue = !engine->rpmCalculator.isRunning(PASS_ENGINE_PARAMETER_SIGNATURE) && getTPS(PASS_ENGINE_PARAMETER_SIGNATURE) > CLEANUP_MODE_TPS;
newValue = !engine->rpmCalculator.isRunning(PASS_ENGINE_PARAMETER_SIGNATURE) && Sensor::get(SensorType::DriverThrottleIntent).value_or(0) > CLEANUP_MODE_TPS;
} else {
newValue = false;
}
@ -141,6 +141,8 @@ void Engine::periodicSlowCallback(DECLARE_ENGINE_PARAMETER_SIGNATURE) {
runHardcodedFsio(PASS_ENGINE_PARAMETER_SIGNATURE);
#endif /* EFI_FSIO */
updateGppwm();
cylinderCleanupControl(PASS_ENGINE_PARAMETER_SIGNATURE);
#if (BOARD_TLE8888_COUNT > 0)
@ -226,8 +228,6 @@ void Engine::reset() {
*/
engineCycle = getEngineCycle(FOUR_STROKE_CRANK_SENSOR);
memset(&ignitionPin, 0, sizeof(ignitionPin));
memset(&m, 0, sizeof(m));
}
@ -247,13 +247,6 @@ void Engine::preCalculate(DECLARE_ENGINE_PARAMETER_SIGNATURE) {
void Engine::OnTriggerStateDecodingError() {
Engine *engine = this;
EXPAND_Engine;
if (engineConfiguration->debugMode == DBG_TRIGGER_SYNC) {
#if EFI_TUNER_STUDIO
tsOutputChannels.debugIntField1 = triggerCentral.triggerState.currentCycle.eventCount[0];
tsOutputChannels.debugIntField2 = triggerCentral.triggerState.currentCycle.eventCount[1];
tsOutputChannels.debugIntField3 = triggerCentral.triggerState.currentCycle.eventCount[2];
#endif /* EFI_TUNER_STUDIO */
}
warning(CUSTOM_SYNC_COUNT_MISMATCH, "trigger not happy current %d/%d/%d expected %d/%d/%d",
triggerCentral.triggerState.currentCycle.eventCount[0],
@ -489,11 +482,9 @@ void Engine::periodicFastCallback(DECLARE_ENGINE_PARAMETER_SIGNATURE) {
engineState.periodicFastCallback(PASS_ENGINE_PARAMETER_SIGNATURE);
#if EFI_ENGINE_CONTROL
engine->m.beforeFuelCalc = getTimeNowLowerNt();
int rpm = GET_RPM();
ENGINE(injectionDuration) = getInjectionDuration(rpm PASS_ENGINE_PARAMETER_SUFFIX);
engine->m.fuelCalcTime = getTimeNowLowerNt() - engine->m.beforeFuelCalc;
#endif
}

View File

@ -54,7 +54,7 @@ public:
explicit Engine(persistent_config_s *config);
Engine();
IEtbController *etbControllers[ETB_COUNT];
IEtbController *etbControllers[ETB_COUNT] = {nullptr};
cyclic_buffer<int> triggerErrorDetection;
@ -79,6 +79,16 @@ public:
bool needTdcCallback = true;
#endif /* EFI_UNIT_TEST */
#if EFI_LAUNCH_CONTROL
bool launchActivatePinState = false;
bool isLaunchCondition = false;
bool applyLaunchExtraFuel = false;
bool setLaunchBoostDuty = false;
bool applyLaunchControlRetard = false;
bool rpmHardCut = false;
#endif /* EFI_LAUNCH_CONTROL */
/**
* if 2nd TPS is not configured we do not run 2nd ETB
*/
@ -96,9 +106,6 @@ public:
#if !EFI_PROD_CODE
float mockMapValue = 0;
// for historical reasons we have options to mock TPS on different layers :(
int mockTpsAdcValue = 0;
float mockTpsValue = NAN;
#endif
int getGlobalConfigurationVersion(void) const;
@ -176,6 +183,11 @@ public:
*/
efitick_t stopEngineRequestTimeNt = 0;
bool startStopState = false;
efitick_t startStopStateLastPushTime = 0;
int startStopStateToggleCounter = 0;
/**
* This counter is incremented every time user adjusts ECU parameters online (either via rusEfi console or other
* tuning software)
@ -248,6 +260,8 @@ public:
*/
bool isTestMode = false;
bool directSelfStimulation = false;
void resetEngineSnifferIfInTestMode();
/**
@ -307,8 +321,6 @@ public:
*/
bool isInShutdownMode() const;
monitoring_timestamps_s m;
void knockLogic(float knockVolts DECLARE_ENGINE_PARAMETER_SUFFIX);
void printKnockState(void);

View File

@ -16,6 +16,7 @@
#include "advance_map.h"
#include "aux_valves.h"
#include "perf_trace.h"
#include "sensor.h"
#if EFI_PROD_CODE
#include "svnversion.h"
@ -28,8 +29,7 @@
extern fuel_Map3D_t veMap;
extern afr_Map3D_t afrMap;
EXTERN_ENGINE
;
EXTERN_ENGINE;
// this does not look exactly right
extern LoggingWithStorage engineLogger;
@ -119,19 +119,9 @@ void EngineState::updateSlowSensors(DECLARE_ENGINE_PARAMETER_SIGNATURE) {
engine->sensors.iat = getIntakeAirTemperatureM(PASS_ENGINE_PARAMETER_SIGNATURE);
#if !EFI_CANBUS_SLAVE
engine->sensors.clt = getCoolantTemperatureM(PASS_ENGINE_PARAMETER_SIGNATURE);
// todo: reduce code duplication with 'getCoolantTemperature'
if (engineConfiguration->auxTempSensor1.adcChannel != EFI_ADC_NONE) {
engine->sensors.auxTemp1 = getTemperatureC(&engineConfiguration->auxTempSensor1,
&engine->engineState.auxTemp1Curve,
false PASS_ENGINE_PARAMETER_SUFFIX);
}
if (engineConfiguration->auxTempSensor2.adcChannel != EFI_ADC_NONE) {
engine->sensors.auxTemp2 = getTemperatureC(&engineConfiguration->auxTempSensor2,
&engine->engineState.auxTemp2Curve,
false PASS_ENGINE_PARAMETER_SUFFIX);
}
#endif /* EFI_CANBUS_SLAVE */
#if EFI_UNIT_TEST
if (!cisnan(engine->sensors.mockClt)) {
@ -164,7 +154,7 @@ void EngineState::periodicFastCallback(DECLARE_ENGINE_PARAMETER_SIGNATURE) {
}
// todo: move this into slow callback, no reason for IAT corr to be here
running.intakeTemperatureCoefficient = getIatFuelCorrection(getIntakeAirTemperature() PASS_ENGINE_PARAMETER_SUFFIX);
running.intakeTemperatureCoefficient = getIatFuelCorrection(PASS_ENGINE_PARAMETER_SIGNATURE);
// todo: move this into slow callback, no reason for CLT corr to be here
running.coolantTemperatureCoefficient = getCltFuelCorrection(PASS_ENGINE_PARAMETER_SIGNATURE);
@ -197,9 +187,11 @@ void EngineState::periodicFastCallback(DECLARE_ENGINE_PARAMETER_SIGNATURE) {
float engineLoad = getEngineLoadT(PASS_ENGINE_PARAMETER_SIGNATURE);
timingAdvance = getAdvance(rpm, engineLoad PASS_ENGINE_PARAMETER_SUFFIX);
multispark.count = getMultiSparkCount(rpm PASS_ENGINE_PARAMETER_SUFFIX);
if (engineConfiguration->fuelAlgorithm == LM_SPEED_DENSITY) {
float tps = getTPS(PASS_ENGINE_PARAMETER_SIGNATURE);
updateTChargeK(rpm, tps PASS_ENGINE_PARAMETER_SUFFIX);
auto tps = Sensor::get(SensorType::Tps1);
updateTChargeK(rpm, tps.value_or(0) PASS_ENGINE_PARAMETER_SUFFIX);
float map = getMap(PASS_ENGINE_PARAMETER_SIGNATURE);
/**
@ -207,15 +199,16 @@ void EngineState::periodicFastCallback(DECLARE_ENGINE_PARAMETER_SIGNATURE) {
*/
if (CONFIG(useTPSBasedVeTable)) {
// todo: should we have 'veTpsMap' fuel_Map3D_t variable here?
currentRawVE = interpolate3d<float, float>(tps, CONFIG(ignitionTpsBins), IGN_TPS_COUNT, rpm, config->veRpmBins, FUEL_RPM_COUNT, veMap.pointers);
currentRawVE = interpolate3d<float, float>(tps.value_or(50), CONFIG(ignitionTpsBins), IGN_TPS_COUNT, rpm, config->veRpmBins, FUEL_RPM_COUNT, veMap.pointers);
} else {
currentRawVE = veMap.getValue(rpm, map);
}
// get VE from the separate table for Idle
if (CONFIG(useSeparateVeForIdle)) {
if (tps.Valid && CONFIG(useSeparateVeForIdle)) {
float idleVe = interpolate2d("idleVe", rpm, config->idleVeBins, config->idleVe);
// interpolate between idle table and normal (running) table using TPS threshold
currentRawVE = interpolateClamped(0.0f, idleVe, CONFIG(idlePidDeactivationTpsThreshold), currentRawVE, tps);
currentRawVE = interpolateClamped(0.0f, idleVe, CONFIG(idlePidDeactivationTpsThreshold), currentRawVE, tps.Value);
}
currentBaroCorrectedVE = baroCorrection * currentRawVE * PERCENT_DIV;
targetAFR = afrMap.getValue(rpm, map);
@ -227,7 +220,7 @@ void EngineState::periodicFastCallback(DECLARE_ENGINE_PARAMETER_SIGNATURE) {
void EngineState::updateTChargeK(int rpm, float tps DECLARE_ENGINE_PARAMETER_SUFFIX) {
#if EFI_ENGINE_CONTROL
float newTCharge = getTCharge(rpm, tps, getCoolantTemperature(), getIntakeAirTemperature() PASS_ENGINE_PARAMETER_SUFFIX);
float newTCharge = getTCharge(rpm, tps PASS_ENGINE_PARAMETER_SUFFIX);
// convert to microsecs and then to seconds
efitick_t curTime = getTimeNowNt();
float secsPassed = (float)NT2US(curTime - timeSinceLastTChargeK) / 1000000.0f;
@ -268,7 +261,7 @@ void StartupFuelPumping::setPumpsCounter(int newValue) {
void StartupFuelPumping::update(DECLARE_ENGINE_PARAMETER_SIGNATURE) {
if (GET_RPM() == 0) {
bool isTpsAbove50 = getTPS(PASS_ENGINE_PARAMETER_SIGNATURE) >= 50;
bool isTpsAbove50 = Sensor::get(SensorType::DriverThrottleIntent).value_or(0) >= 50;
if (this->isTpsAbove50 != isTpsAbove50) {
setPumpsCounter(pumpsCounter + 1);

View File

@ -29,6 +29,7 @@
#include "engine_math.h"
#include "speed_density.h"
#include "advance_map.h"
#include "sensor.h"
#include "hip9011_lookup.h"
#if EFI_MEMS
@ -66,6 +67,7 @@
#include "test_engine.h"
#include "sachs.h"
#include "vw.h"
#include "me7pnp.h"
#include "vw_b6.h"
#include "daihatsu.h"
#include "chevrolet_camaro_4.h"
@ -100,7 +102,7 @@
#endif /* EFI_PROD_CODE */
#if EFI_EMULATE_POSITION_SENSORS
#include "trigger_emulator.h"
#include "trigger_emulator_algo.h"
#endif /* EFI_EMULATE_POSITION_SENSORS */
#if EFI_TUNER_STUDIO
@ -143,7 +145,7 @@ static fuel_table_t alphaNfuel = {
* todo: place this field next to 'engineConfiguration'?
*/
#ifdef EFI_ACTIVE_CONFIGURATION_IN_FLASH
#include "flash.h"
#include "flash_int.h"
engine_configuration_s & activeConfiguration = reinterpret_cast<persistent_config_container_s*>(getFlashAddrFirstCopy())->persistentConfiguration.engineConfiguration;
// we cannot use this activeConfiguration until we call rememberCurrentConfiguration()
bool isActiveConfigurationVoid = true;
@ -595,7 +597,6 @@ static void setDefaultStepperIdleParameters(DECLARE_ENGINE_PARAMETER_SIGNATURE)
}
static void setCanFrankensoDefaults(DECLARE_CONFIG_PARAMETER_SIGNATURE) {
engineConfiguration->canDeviceMode = CD_USE_CAN2;
engineConfiguration->canTxPin = GPIOB_6;
engineConfiguration->canRxPin = GPIOB_12;
}
@ -609,17 +610,53 @@ void setTargetRpmCurve(int rpm DECLARE_CONFIG_PARAMETER_SUFFIX) {
}
int getTargetRpmForIdleCorrection(DECLARE_ENGINE_PARAMETER_SIGNATURE) {
float clt = getCoolantTemperature();
int targetRpm;
if (!hasCltSensor()) {
// error is already reported, let's take first value from the table should be good enough error handing solution
targetRpm = CONFIG(cltIdleRpm)[0];
} else {
targetRpm = interpolate2d("cltRpm", clt, CONFIG(cltIdleRpmBins), CONFIG(cltIdleRpm));
}
// error is already reported, let's take the value at 0C since that should be a nice high idle
float clt = Sensor::get(SensorType::Clt).value_or(0);
int targetRpm = interpolate2d("cltRpm", clt, CONFIG(cltIdleRpmBins), CONFIG(cltIdleRpm));
return targetRpm + engine->fsioState.fsioIdleTargetRPMAdjustment;
}
void setDefaultMultisparkParameters(DECLARE_ENGINE_PARAMETER_SIGNATURE) {
// 1ms spark + 2ms dwell
engineConfiguration->multisparkSparkDuration = 1000;
engineConfiguration->multisparkDwell = 2000;
// Conservative defaults - probably won't blow up coils
engineConfiguration->multisparkMaxRpm = 1500;
engineConfiguration->multisparkMaxExtraSparkCount = 2;
engineConfiguration->multisparkMaxSparkingAngle = 30;
}
void setDefaultGppwmParameters(DECLARE_ENGINE_PARAMETER_SIGNATURE) {
// Same config for all channels
for (size_t i = 0; i < efi::size(CONFIG(gppwm)); i++) {
auto& cfg = CONFIG(gppwm)[i];
cfg.pin = GPIO_UNASSIGNED;
cfg.dutyIfError = 0;
cfg.onAboveDuty = 60;
cfg.offBelowDuty = 50;
cfg.pwmFrequency = 250;
for (size_t j = 0; j < efi::size(cfg.loadBins); j++) {
uint8_t z = j * 100 / (efi::size(cfg.loadBins) - 1);
cfg.loadBins[j] = z;
// Fill some values in the table
for (size_t k = 0; k < efi::size(cfg.rpmBins); k++) {
cfg.table[j][k] = z;
}
}
for (size_t j = 0; j < efi::size(cfg.rpmBins); j++) {
cfg.rpmBins[j] = 1000 * j / RPM_1_BYTE_PACKING_MULT;
}
}
}
/**
* @brief Global default engine configuration
* This method sets the global engine configuration defaults. These default values are then
@ -670,7 +707,7 @@ static void setDefaultEngineConfiguration(DECLARE_ENGINE_PARAMETER_SIGNATURE) {
engineConfiguration->canNbcType = CAN_BUS_MAZDA_RX8;
// Don't enable, but set default address
engineConfiguration->verboseCanBaseAddress = 0x200;
engineConfiguration->verboseCanBaseAddress = CAN_DEFAULT_BASE;
engineConfiguration->sdCardPeriodMs = 50;
@ -678,16 +715,16 @@ static void setDefaultEngineConfiguration(DECLARE_ENGINE_PARAMETER_SIGNATURE) {
config->fsioFormulas[i][0] = 0;
}
CONFIG(mapMinBufferLength) = 1;
CONFIG(startCrankingDuration) = 7;
engineConfiguration->idlePidRpmDeadZone = 50;
engineConfiguration->startOfCrankingPrimingPulse = 0;
engineConfiguration->acCutoffLowRpm = 700;
engineConfiguration->acCutoffHighRpm = 5000;
engineConfiguration->postCrankingTargetClt = 25;
engineConfiguration->postCrankingDurationSec = 2;
initTemperatureCurve(IAT_FUEL_CORRECTION_CURVE, 1);
@ -860,6 +897,10 @@ static void setDefaultEngineConfiguration(DECLARE_ENGINE_PARAMETER_SIGNATURE) {
engineConfiguration->timingMode = TM_DYNAMIC;
engineConfiguration->fixedModeTiming = 50;
setDefaultMultisparkParameters(PASS_ENGINE_PARAMETER_SIGNATURE);
setDefaultGppwmParameters(PASS_ENGINE_PARAMETER_SIGNATURE);
#if !EFI_UNIT_TEST
engineConfiguration->analogInputDividerCoefficient = 2;
#endif
@ -910,7 +951,6 @@ static void setDefaultEngineConfiguration(DECLARE_ENGINE_PARAMETER_SIGNATURE) {
engineConfiguration->mapHighValueVoltage = 5;
engineConfiguration->logFormat = LF_NATIVE;
engineConfiguration->directSelfStimulation = false;
engineConfiguration->trigger.type = TT_TOOTHED_WHEEL_60_2;
@ -1103,9 +1143,6 @@ void resetConfigurationExt(Logging * logger, configuration_callback_t boardCallb
setBoardConfigurationOverrides();
#endif
#if EFI_SIMULATOR
engineConfiguration->directSelfStimulation = true;
#endif /* */
engineConfiguration->engineType = engineType;
/**
@ -1151,6 +1188,7 @@ void resetConfigurationExt(Logging * logger, configuration_callback_t boardCallb
setEngineBMW_M73_Manhattan(PASS_CONFIG_PARAMETER_SIGNATURE);
break;
case BMW_M73_MRE:
case BMW_M73_MRE_SLAVE:
setEngineBMW_M73_microRusEfi(PASS_CONFIG_PARAMETER_SIGNATURE);
break;
case BMW_M73_PROTEUS:
@ -1307,6 +1345,9 @@ void resetConfigurationExt(Logging * logger, configuration_callback_t boardCallb
case TOYOTA_JZS147:
setToyota_jzs147EngineConfiguration(PASS_CONFIG_PARAMETER_SIGNATURE);
break;
case VAG_18_TURBO:
vag_18_Turbo(PASS_CONFIG_PARAMETER_SIGNATURE);
break;
case TEST_33816:
setTest33816EngineConfiguration(PASS_CONFIG_PARAMETER_SIGNATURE);
break;
@ -1418,3 +1459,8 @@ void copyTimingTable(ignition_table_t const source, ignition_table_t destination
}
}
static const ConfigOverrides defaultConfigOverrides{};
// This symbol is weak so that a board_configuration.cpp file can override it
__attribute__((weak)) const ConfigOverrides& getConfigOverrides() {
return defaultConfigOverrides;
}

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