fresh version
This commit is contained in:
parent
fa6f88dc03
commit
34f2334652
|
@ -78,7 +78,7 @@
|
|||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/chibios/os/ports/common/ARMCMx}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/chibios/os/ports/common/ARMCMx/CMSIS/include}""/>
|
||||
</option>
|
||||
<option id="org.eclipse.cdt.cross.arm.gnu.c.compiler.option.other.otherflags.720321025" name="Other flags" superClass="org.eclipse.cdt.cross.arm.gnu.c.compiler.option.other.otherflags" value="-fgnu89-inline -c -fmessage-length=0 -Werror=type-limits -Werror-implicit-function-declaration -Werror -Wno-error=pointer-sign -Wno-error=unused-function -Wno-error=unused-variable" valueType="string"/>
|
||||
<option id="org.eclipse.cdt.cross.arm.gnu.c.compiler.option.other.otherflags.720321025" name="Other flags" superClass="org.eclipse.cdt.cross.arm.gnu.c.compiler.option.other.otherflags" value="-fgnu89-inline -c -fmessage-length=0 -Werror=switch -Werror=type-limits -Werror-implicit-function-declaration -Werror -Wno-error=pointer-sign -Wno-error=unused-function -Wno-error=unused-variable" valueType="string"/>
|
||||
<option id="org.eclipse.cdt.cross.arm.gnu.c.compiler.option.misc.std.32943169" name="Language Standard" superClass="org.eclipse.cdt.cross.arm.gnu.c.compiler.option.misc.std" value="org.eclipse.cdt.cross.arm.gnu.c.compiler.option.misc.std.gnu99" valueType="enumerated"/>
|
||||
<option id="org.eclipse.cdt.cross.arm.gnu.c.compiler.option.preprocessor.def.1323722868" name="Defined symbols (-D)" superClass="org.eclipse.cdt.cross.arm.gnu.c.compiler.option.preprocessor.def" valueType="definedSymbols">
|
||||
<listOptionValue builtIn="false" value="CORTEX_USE_FPU=TRUE"/>
|
||||
|
@ -115,6 +115,7 @@
|
|||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/emulation/hw_layer}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/hw_layer}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/hw_layer/flash}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/hw_layer/stm32f4}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/russianefi}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/russianefi/algo}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/russianefi/ckp}""/>
|
||||
|
@ -139,7 +140,7 @@
|
|||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/chibios/os/ports/common/ARMCMx}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/chibios/os/ports/common/ARMCMx/CMSIS/include}""/>
|
||||
</option>
|
||||
<option id="org.eclipse.cdt.cross.arm.gnu.cpp.compiler.option.other.otherflags.1439013659" name="Other flags" superClass="org.eclipse.cdt.cross.arm.gnu.cpp.compiler.option.other.otherflags" value="-c -fmessage-length=0 -std=c++11 -Werror=write-strings" valueType="string"/>
|
||||
<option id="org.eclipse.cdt.cross.arm.gnu.cpp.compiler.option.other.otherflags.1439013659" name="Other flags" superClass="org.eclipse.cdt.cross.arm.gnu.cpp.compiler.option.other.otherflags" value="-c -fmessage-length=0 -std=c++11 -Werror=write-strings -Werror=switch" valueType="string"/>
|
||||
<option id="org.eclipse.cdt.cross.arm.gnu.cpp.compiler.option.preprocessor.def.1500938905" name="Defined symbols (-D)" superClass="org.eclipse.cdt.cross.arm.gnu.cpp.compiler.option.preprocessor.def" valueType="definedSymbols">
|
||||
<listOptionValue builtIn="false" value="CORTEX_USE_FPU=TRUE"/>
|
||||
</option>
|
||||
|
@ -303,10 +304,10 @@
|
|||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/chibios/os/ports/common/ARMCMx}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/chibios/os/ports/common/ARMCMx/CMSIS/include}""/>
|
||||
</option>
|
||||
<option id="org.eclipse.cdt.cross.arm.gnu.cpp.compiler.option.preprocessor.def.104404165" superClass="org.eclipse.cdt.cross.arm.gnu.cpp.compiler.option.preprocessor.def" valueType="definedSymbols">
|
||||
<option id="org.eclipse.cdt.cross.arm.gnu.cpp.compiler.option.preprocessor.def.104404165" name="Defined symbols (-D)" superClass="org.eclipse.cdt.cross.arm.gnu.cpp.compiler.option.preprocessor.def" valueType="definedSymbols">
|
||||
<listOptionValue builtIn="false" value="CORTEX_USE_FPU=TRUE"/>
|
||||
</option>
|
||||
<option id="org.eclipse.cdt.cross.arm.gnu.cpp.compiler.option.optimization.flags.514837677" superClass="org.eclipse.cdt.cross.arm.gnu.cpp.compiler.option.optimization.flags" value="-mfloat-abi=softfp -mfpu=fpv4-sp-d16 -fsingle-precision-constant" valueType="string"/>
|
||||
<option id="org.eclipse.cdt.cross.arm.gnu.cpp.compiler.option.optimization.flags.514837677" name="Other optimization flags" superClass="org.eclipse.cdt.cross.arm.gnu.cpp.compiler.option.optimization.flags" value="-mfloat-abi=softfp -mfpu=fpv4-sp-d16 -fsingle-precision-constant" valueType="string"/>
|
||||
<inputType id="org.eclipse.cdt.cross.arm.gnu.sourcery.windows.cpp.compiler.base.input.815685204" superClass="org.eclipse.cdt.cross.arm.gnu.sourcery.windows.cpp.compiler.base.input"/>
|
||||
</tool>
|
||||
<tool id="org.eclipse.cdt.cross.arm.gnu.sourcery.windows.elf.c.linker.release.1692652942" name="ARM Sourcery Windows GCC C Linker" superClass="org.eclipse.cdt.cross.arm.gnu.sourcery.windows.elf.c.linker.release"/>
|
||||
|
|
|
@ -196,6 +196,7 @@ INCDIR = $(PORTINC) $(KERNINC) $(TESTINC) \
|
|||
hw_layer/serial_over_usb \
|
||||
hw_layer/algo \
|
||||
hw_layer/lcd \
|
||||
hw_layer/stm32f4 \
|
||||
emulation \
|
||||
emulation/hw_layer \
|
||||
emulation/test \
|
||||
|
|
|
@ -220,14 +220,10 @@
|
|||
#define EFI_SIGNAL_EXECUTOR_ONE_TIMER TRUE
|
||||
#define EFI_SIGNAL_EXECUTOR_HW_TIMER FALSE
|
||||
|
||||
|
||||
// USART1 -> check defined STM32_SERIAL_USE_USART1
|
||||
// For GPS we have USART1. We can start with PB7 USART1_RX and PB6 USART1_TX
|
||||
#define GPS_SERIAL_DEVICE &SD1
|
||||
#define GPS_SERIAL_SPEED 38400
|
||||
#define GPS_PORT GPIOB
|
||||
#define GPS_SERIAL_TX_PIN 6
|
||||
#define GPS_SERIAL_RX_PIN 7
|
||||
|
||||
#define CONSOLE_MODE_SWITCH_PORT GPIOB
|
||||
#define CONSOLE_MODE_SWITCH_PIN 1
|
||||
|
|
|
@ -73,7 +73,7 @@
|
|||
|
||||
#define EFI_HD44780_LCD TRUE
|
||||
|
||||
#define EFI_IDLE_CONTROL FALSE
|
||||
#define EFI_IDLE_CONTROL TRUE
|
||||
|
||||
#define EFI_FUEL_PUMP TRUE
|
||||
|
||||
|
@ -124,9 +124,6 @@
|
|||
#define EFI_UART_GPS TRUE
|
||||
//#define EFI_UART_GPS FALSE
|
||||
|
||||
//#define EFI_IDLE_CONTROL TRUE
|
||||
#define EFI_IDLE_CONTROL FALSE
|
||||
|
||||
//#define EFI_ELECTRONIC_THROTTLE_BODY TRUE
|
||||
#define EFI_ELECTRONIC_THROTTLE_BODY FALSE
|
||||
|
||||
|
|
|
@ -16,4 +16,5 @@ ENGINES_SRC_CPP = $(PROJECT_DIR)/config/engines/ford_aspire.cpp \
|
|||
$(PROJECT_DIR)/config/engines/GY6_139QMB.cpp \
|
||||
$(PROJECT_DIR)/config/engines/rover_v8.cpp \
|
||||
$(PROJECT_DIR)/config/engines/mazda_323.cpp \
|
||||
$(PROJECT_DIR)/config/engines/saturn_ion.cpp
|
||||
$(PROJECT_DIR)/config/engines/saturn_ion.cpp \
|
||||
$(PROJECT_DIR)/config/engines/mitsubishi.cpp
|
|
@ -48,10 +48,10 @@ void setFordInline6(engine_configuration_s *engineConfiguration, board_configura
|
|||
engineConfiguration->globalTriggerAngleOffset = 0;
|
||||
engineConfiguration->ignitionOffset = 13;
|
||||
|
||||
setThermistorConfiguration(&engineConfiguration->cltThermistorConf, -10, 160310, 60, 7700, 120.00, 1180);
|
||||
setThermistorConfiguration(&engineConfiguration->cltThermistorConf, -10.0, 160310.0, 60.0, 7700.0, 120.0, 1180.0);
|
||||
engineConfiguration->cltThermistorConf.bias_resistor = 2700;
|
||||
|
||||
setThermistorConfiguration(&engineConfiguration->iatThermistorConf, -10, 160310, 60, 7700, 120.00, 1180);
|
||||
setThermistorConfiguration(&engineConfiguration->iatThermistorConf, -10.0, 160310.0, 60.0, 7700.0, 120.0, 1180.0);
|
||||
engineConfiguration->iatThermistorConf.bias_resistor = 2700;
|
||||
|
||||
// 12ch analog board pinout:
|
||||
|
@ -75,15 +75,15 @@ void setFordInline6(engine_configuration_s *engineConfiguration, board_configura
|
|||
boardConfiguration->adcHwChannelEnabled[15] = ADC_FAST;
|
||||
|
||||
|
||||
engineConfiguration->tpsAdcChannel = 4;
|
||||
engineConfiguration->iatAdcChannel = 2;
|
||||
engineConfiguration->cltAdcChannel = 1;
|
||||
engineConfiguration->afrSensor.afrAdcChannel = 11;
|
||||
engineConfiguration->tpsAdcChannel = EFI_ADC_4;
|
||||
engineConfiguration->iatAdcChannel = EFI_ADC_2;
|
||||
engineConfiguration->cltAdcChannel = EFI_ADC_1;
|
||||
engineConfiguration->afrSensor.afrAdcChannel = EFI_ADC_11;
|
||||
|
||||
engineConfiguration->map.sensor.sensorType = MT_MPX4250;
|
||||
engineConfiguration->map.sensor.hwChannel = 15;
|
||||
engineConfiguration->map.sensor.hwChannel = EFI_ADC_15;
|
||||
engineConfiguration->baroSensor.sensorType = MT_MPX4250;
|
||||
engineConfiguration->baroSensor.hwChannel = 7;
|
||||
engineConfiguration->baroSensor.hwChannel = EFI_ADC_7;
|
||||
|
||||
// 6 channel output board
|
||||
// output 1 is PB9
|
||||
|
@ -105,10 +105,10 @@ void setFordInline6(engine_configuration_s *engineConfiguration, board_configura
|
|||
// engineConfiguration->vBattAdcChannel = 0; //
|
||||
// engineConfiguration->mafAdcChannel = 1;
|
||||
|
||||
boardConfiguration->primaryTriggerInputPin = GPIOA_8;
|
||||
boardConfiguration->secondaryTriggerInputPin = GPIOA_5;
|
||||
boardConfiguration->primaryLogicAnalyzerPin = GPIOC_6;
|
||||
boardConfiguration->secondaryLogicAnalyzerPin = GPIOE_7;
|
||||
boardConfiguration->triggerInputPins[0] = GPIOA_8;
|
||||
boardConfiguration->triggerInputPins[1] = GPIOA_5;
|
||||
boardConfiguration->logicAnalyzerPins[0] = GPIOC_6;
|
||||
boardConfiguration->logicAnalyzerPins[1] = GPIOE_7;
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -90,6 +90,11 @@ void setFordAspireEngineConfiguration(engine_configuration_s *engineConfiguratio
|
|||
|
||||
engineConfiguration->rpmHardLimit = 7000;
|
||||
|
||||
/**
|
||||
* 18K Ohm @ -20C
|
||||
* 2.1K Ohm @ 24C
|
||||
* 1K Ohm @ 49C
|
||||
*/
|
||||
setThermistorConfiguration(&engineConfiguration->cltThermistorConf, -20, 18000, 23.8889, 2100, 48.8889, 1000);
|
||||
engineConfiguration->cltThermistorConf.bias_resistor = 3300; // that's my custom resistor value!
|
||||
|
||||
|
@ -112,9 +117,12 @@ void setFordAspireEngineConfiguration(engine_configuration_s *engineConfiguratio
|
|||
engineConfiguration->injectionOffset = 59;
|
||||
|
||||
setDefaultMaps(engineConfiguration);
|
||||
// set_cranking_rpm 550
|
||||
engineConfiguration->crankingSettings.crankingRpm = 550;
|
||||
// set_cranking_charge_angle 70
|
||||
engineConfiguration->crankingChargeAngle = 70;
|
||||
engineConfiguration->crankingTimingAngle = 26 + 11;
|
||||
// set_cranking_timing_angle 37
|
||||
engineConfiguration->crankingTimingAngle = 37;
|
||||
|
||||
setSingleCoilDwell(engineConfiguration);
|
||||
engineConfiguration->ignitionMode = IM_ONE_COIL;
|
||||
|
@ -140,11 +148,11 @@ void setFordAspireEngineConfiguration(engine_configuration_s *engineConfiguratio
|
|||
// Frankenstein analog input #12: adc
|
||||
|
||||
|
||||
engineConfiguration->tpsAdcChannel = 3;
|
||||
engineConfiguration->vBattAdcChannel = 0;
|
||||
engineConfiguration->map.sensor.hwChannel = 4;
|
||||
engineConfiguration->mafAdcChannel = 1;
|
||||
engineConfiguration->cltAdcChannel = 11;
|
||||
engineConfiguration->tpsAdcChannel = EFI_ADC_3;
|
||||
engineConfiguration->vBattAdcChannel = EFI_ADC_0;
|
||||
engineConfiguration->map.sensor.hwChannel = EFI_ADC_4;
|
||||
engineConfiguration->mafAdcChannel = EFI_ADC_1;
|
||||
engineConfiguration->cltAdcChannel = EFI_ADC_11;
|
||||
// engineConfiguration->iatAdcChannel =
|
||||
|
||||
engineConfiguration->map.sensor.sensorType = MT_DENSO183;
|
||||
|
|
|
@ -40,9 +40,9 @@ void setFordEscortGt(engine_configuration_s *engineConfiguration, board_configur
|
|||
// Frankenstein analog input #10: adc
|
||||
// Frankenstein analog input #11: adc
|
||||
// Frankenstein analog input #12: adc
|
||||
engineConfiguration->mafAdcChannel = 1;
|
||||
engineConfiguration->tpsAdcChannel = 3;
|
||||
engineConfiguration->cltAdcChannel = 11;
|
||||
engineConfiguration->mafAdcChannel = EFI_ADC_1;
|
||||
engineConfiguration->tpsAdcChannel = EFI_ADC_3;
|
||||
engineConfiguration->cltAdcChannel = EFI_ADC_11;
|
||||
|
||||
|
||||
// Frankenstein: high side #1 is PE8
|
||||
|
|
|
@ -6,19 +6,26 @@
|
|||
* http://rusefi.com/forum/viewtopic.php?f=3&t=621
|
||||
*
|
||||
* engine_type 6
|
||||
* engine_type 17
|
||||
*
|
||||
* @date Jan 12, 2014
|
||||
* @author Andrey Belomutskiy, (c) 2012-2014
|
||||
*/
|
||||
|
||||
#include "main.h"
|
||||
#include "engine_configuration.h"
|
||||
#include "trigger_decoder.h"
|
||||
#include "thermistors.h"
|
||||
#include "honda_accord.h"
|
||||
|
||||
void setHondaAccordConfiguration(engine_configuration_s *engineConfiguration, board_configuration_s *boardConfiguration) {
|
||||
engineConfiguration->engineType = HONDA_ACCORD;
|
||||
static void setHondaAccordConfigurationCommon(engine_configuration_s *engineConfiguration, board_configuration_s *boardConfiguration) {
|
||||
engineConfiguration->map.sensor.sensorType = MT_DENSO183;
|
||||
|
||||
engineConfiguration->map.sensor.sensorType = MT_HONDA3BAR;
|
||||
engineConfiguration->ignitionMode = IM_ONE_COIL;
|
||||
engineConfiguration->injectionMode = IM_BATCH;
|
||||
|
||||
engineConfiguration->idleMode = IM_MANUAL;
|
||||
|
||||
engineConfiguration->HD44780height = 4;
|
||||
|
||||
engineConfiguration->cylindersCount = 4;
|
||||
engineConfiguration->displacement = 2.156;
|
||||
|
@ -26,9 +33,9 @@ void setHondaAccordConfiguration(engine_configuration_s *engineConfiguration, bo
|
|||
// Keihin 06164-P0A-A00
|
||||
engineConfiguration->injectorFlow = 248;
|
||||
|
||||
|
||||
engineConfiguration->algorithm = LM_SPEED_DENSITY;
|
||||
|
||||
// engineConfiguration->algorithm = LM_SPEED_DENSITY;
|
||||
// I want to start with a simple Alpha-N
|
||||
engineConfiguration->algorithm = LM_TPS;
|
||||
|
||||
engineConfiguration->crankingSettings.coolantTempMaxC = 65; // 8ms at 65C
|
||||
engineConfiguration->crankingSettings.fuelAtMaxTempMs = 8;
|
||||
|
@ -36,24 +43,158 @@ void setHondaAccordConfiguration(engine_configuration_s *engineConfiguration, bo
|
|||
engineConfiguration->crankingSettings.coolantTempMinC = 0; // 20ms at 0C
|
||||
engineConfiguration->crankingSettings.fuelAtMinTempMs = 15;
|
||||
|
||||
/**
|
||||
* 18K Ohm @ -20C
|
||||
* 2.1K Ohm @ 24C
|
||||
* 100 Ohm @ 120C
|
||||
*/
|
||||
setThermistorConfiguration(&engineConfiguration->cltThermistorConf, -20.0, 18000.0, 23.8889, 2100.0, 120.0, 100.0);
|
||||
engineConfiguration->cltThermistorConf.bias_resistor = 1500; // same as OEM ECU
|
||||
|
||||
setThermistorConfiguration(&engineConfiguration->iatThermistorConf, -20.0, 18000.0, 23.8889, 2100.0, 120.0, 100.0);
|
||||
engineConfiguration->iatThermistorConf.bias_resistor = 1500; // same as OEM ECU
|
||||
|
||||
// set_cranking_charge_angle 35
|
||||
engineConfiguration->crankingChargeAngle = 35;
|
||||
// set_cranking_timing_angle 0
|
||||
engineConfiguration->crankingTimingAngle = 0;
|
||||
|
||||
// set_global_trigger_offset_angle 34
|
||||
engineConfiguration->globalTriggerAngleOffset = 34;
|
||||
|
||||
// set_rpm_hard_limit 4000
|
||||
engineConfiguration->rpmHardLimit = 4000; // yes, 4k. let's play it safe for now
|
||||
// set_cranking_rpm 2000
|
||||
engineConfiguration->crankingSettings.crankingRpm = 600;
|
||||
|
||||
|
||||
// set_ignition_offset 350
|
||||
// engineConfiguration->ignitionOffset = 350;
|
||||
// set_injection_offset 510
|
||||
// engineConfiguration->injectionOffset = 510;
|
||||
|
||||
|
||||
/**
|
||||
* ADC inputs:
|
||||
*
|
||||
* Inp1/ADC12 PC2: CLT
|
||||
* Inp2/ADC11 PC1: AIT/IAT
|
||||
* Inp3/ADC0 PA0: MAP
|
||||
* Inp4/ADC13 PC3: AFR
|
||||
* Inp6/ADC1 PA1: TPS
|
||||
* Inp12/ADC14 PC4: VBatt
|
||||
*/
|
||||
memset(boardConfiguration->adcHwChannelEnabled, 0, sizeof(boardConfiguration->adcHwChannelEnabled));
|
||||
boardConfiguration->adcHwChannelEnabled[0] = ADC_FAST; // ADC0 - PA0 - MAP
|
||||
boardConfiguration->adcHwChannelEnabled[1] = ADC_SLOW;
|
||||
boardConfiguration->adcHwChannelEnabled[1] = ADC_SLOW; // TPS
|
||||
boardConfiguration->adcHwChannelEnabled[2] = ADC_SLOW;
|
||||
boardConfiguration->adcHwChannelEnabled[3] = ADC_SLOW;
|
||||
boardConfiguration->adcHwChannelEnabled[4] = ADC_SLOW;
|
||||
|
||||
boardConfiguration->adcHwChannelEnabled[6] = ADC_SLOW;
|
||||
boardConfiguration->adcHwChannelEnabled[7] = ADC_SLOW;
|
||||
boardConfiguration->adcHwChannelEnabled[11] = ADC_SLOW;
|
||||
boardConfiguration->adcHwChannelEnabled[12] = ADC_SLOW;
|
||||
boardConfiguration->adcHwChannelEnabled[13] = ADC_SLOW;
|
||||
boardConfiguration->adcHwChannelEnabled[11] = ADC_SLOW; // IAT
|
||||
boardConfiguration->adcHwChannelEnabled[12] = ADC_SLOW; // CLT
|
||||
boardConfiguration->adcHwChannelEnabled[13] = ADC_SLOW; // AFR
|
||||
boardConfiguration->adcHwChannelEnabled[14] = ADC_SLOW; // VBatt
|
||||
|
||||
/**
|
||||
* D14/W10 O2 Sensor
|
||||
*/
|
||||
engineConfiguration->afrSensor.afrAdcChannel = EFI_ADC_13;
|
||||
|
||||
/**
|
||||
* VBatt
|
||||
*/
|
||||
engineConfiguration->vBattAdcChannel = EFI_ADC_14;
|
||||
engineConfiguration->vbattDividerCoeff = ((float) (8.2 + 33)) / 8.2 * 2;
|
||||
|
||||
// todo engineConfiguration->afrSensor.afrAdcChannel = 14;
|
||||
|
||||
|
||||
engineConfiguration->map.sensor.sensorType = MT_MPX4250;
|
||||
engineConfiguration->map.sensor.hwChannel = 0;
|
||||
/**
|
||||
* MAP D17/W5
|
||||
*/
|
||||
engineConfiguration->map.sensor.hwChannel = EFI_ADC_0;
|
||||
|
||||
|
||||
/**
|
||||
* TPS D11/W11
|
||||
*/
|
||||
engineConfiguration->tpsAdcChannel = EFI_ADC_1;
|
||||
|
||||
/**
|
||||
* IAT D15/W7
|
||||
*/
|
||||
engineConfiguration->iatAdcChannel = EFI_ADC_11;
|
||||
|
||||
/**
|
||||
* CLT D13/W9
|
||||
*/
|
||||
engineConfiguration->cltAdcChannel = EFI_ADC_12;
|
||||
|
||||
|
||||
/**
|
||||
* Outputs
|
||||
*/
|
||||
// Frankenso low out #:
|
||||
// Frankenso low out #:
|
||||
// Frankenso low out #:
|
||||
// Frankenso low out #:
|
||||
// Frankenso low out #5: PE3
|
||||
// Frankenso low out #6: PE4
|
||||
// Frankenso low out #7: PE1 (do not use with discovery!)
|
||||
// Frankenso low out #:
|
||||
// Frankenso low out #9: PB9
|
||||
// Frankenso low out #10: PE0 (do not use with discovery!)
|
||||
// Frankenso low out #11: PB8
|
||||
// Frankenso low out #12: PB7
|
||||
|
||||
boardConfiguration->idleValvePin = GPIOE_5;
|
||||
boardConfiguration->o2heaterPin = GPIOC_13;
|
||||
|
||||
boardConfiguration->injectionPins[0] = GPIOB_8;
|
||||
boardConfiguration->injectionPins[1] = GPIOB_9;
|
||||
boardConfiguration->injectionPins[2] = GPIOE_1;
|
||||
boardConfiguration->injectionPins[3] = GPIOB_7;
|
||||
|
||||
boardConfiguration->ignitionPins[0] = GPIOE_4;
|
||||
boardConfiguration->ignitionPins[1] = GPIO_NONE;
|
||||
boardConfiguration->ignitionPins[2] = GPIO_NONE;
|
||||
boardConfiguration->ignitionPins[3] = GPIO_NONE;
|
||||
|
||||
boardConfiguration->fuelPumpPin = GPIOE_3;
|
||||
boardConfiguration->fuelPumpPinMode = OM_DEFAULT;
|
||||
|
||||
boardConfiguration->gps_rx_pin = GPIO_NONE;
|
||||
boardConfiguration->gps_tx_pin = GPIO_NONE;
|
||||
|
||||
boardConfiguration->HD44780_rs = GPIOE_7;
|
||||
boardConfiguration->HD44780_e = GPIOE_9;
|
||||
boardConfiguration->HD44780_db4 = GPIOE_11;
|
||||
boardConfiguration->HD44780_db5 = GPIOE_13;
|
||||
boardConfiguration->HD44780_db6 = GPIOE_15;
|
||||
boardConfiguration->HD44780_db7 = GPIOB_10;
|
||||
|
||||
boardConfiguration->logicAnalyzerPins[1] = GPIO_NONE;
|
||||
|
||||
|
||||
boardConfiguration->idleSolenoidFrequency = 500;
|
||||
}
|
||||
|
||||
void setHondaAccordConfigurationTwoWires(engine_configuration_s *engineConfiguration, board_configuration_s *boardConfiguration) {
|
||||
engineConfiguration->engineType = HONDA_ACCORD_CD_TWO_WIRES;
|
||||
engineConfiguration->triggerConfig.triggerType = TT_HONDA_ACCORD_CD_TWO_WIRES;
|
||||
setHondaAccordConfigurationCommon(engineConfiguration, boardConfiguration);
|
||||
}
|
||||
|
||||
void setHondaAccordConfigurationThreeWires(engine_configuration_s *engineConfiguration, board_configuration_s *boardConfiguration) {
|
||||
engineConfiguration->engineType = HONDA_ACCORD_CD;
|
||||
engineConfiguration->triggerConfig.triggerType = TT_HONDA_ACCORD_CD;
|
||||
setHondaAccordConfigurationCommon(engineConfiguration, boardConfiguration);
|
||||
}
|
||||
|
||||
void setHondaAccordConfigurationDip(engine_configuration_s *engineConfiguration, board_configuration_s *boardConfiguration) {
|
||||
engineConfiguration->engineType = HONDA_ACCORD_CD_DIP;
|
||||
engineConfiguration->triggerConfig.triggerType = TT_HONDA_ACCORD_CD_DIP;
|
||||
setHondaAccordConfigurationCommon(engineConfiguration, boardConfiguration);
|
||||
}
|
||||
|
|
|
@ -10,6 +10,8 @@
|
|||
|
||||
#include "engine_configuration.h"
|
||||
|
||||
void setHondaAccordConfiguration(engine_configuration_s *engineConfiguration, board_configuration_s *boardConfiguration);
|
||||
void setHondaAccordConfigurationTwoWires(engine_configuration_s *engineConfiguration, board_configuration_s *boardConfiguration);
|
||||
void setHondaAccordConfigurationThreeWires(engine_configuration_s *engineConfiguration, board_configuration_s *boardConfiguration);
|
||||
void setHondaAccordConfigurationDip(engine_configuration_s *engineConfiguration, board_configuration_s *boardConfiguration);
|
||||
|
||||
#endif /* HONDA_ACCORD_H_ */
|
||||
|
|
|
@ -34,13 +34,13 @@ void setMazdaMiataNbEngineConfiguration(engine_configuration_s *engineConfigurat
|
|||
setThermistorConfiguration(&engineConfiguration->iatThermistorConf, -10, 160310, 60, 7700, 120.00, 1180);
|
||||
engineConfiguration->iatThermistorConf.bias_resistor = 2700;
|
||||
|
||||
engineConfiguration->tpsAdcChannel = 3; // 15 is the old value
|
||||
engineConfiguration->vBattAdcChannel = 0; // 1 is the old value
|
||||
engineConfiguration->tpsAdcChannel = EFI_ADC_3; // 15 is the old value
|
||||
engineConfiguration->vBattAdcChannel = EFI_ADC_0; // 1 is the old value
|
||||
// engineConfiguration->map.channel = 1;
|
||||
engineConfiguration->mafAdcChannel = 1;
|
||||
engineConfiguration->cltAdcChannel = 11;
|
||||
engineConfiguration->iatAdcChannel = 13;
|
||||
engineConfiguration->afrSensor.afrAdcChannel = 2;
|
||||
engineConfiguration->mafAdcChannel = EFI_ADC_1;
|
||||
engineConfiguration->cltAdcChannel = EFI_ADC_11;
|
||||
engineConfiguration->iatAdcChannel = EFI_ADC_13;
|
||||
engineConfiguration->afrSensor.afrAdcChannel = EFI_ADC_2;
|
||||
|
||||
boardConfiguration->idleValvePin = GPIOE_0;
|
||||
boardConfiguration->idleValvePinMode = OM_DEFAULT;
|
||||
|
|
|
@ -0,0 +1,95 @@
|
|||
/**
|
||||
* @file mitsubishi.cpp
|
||||
*
|
||||
* MITSU_4G93 16
|
||||
*
|
||||
* @date Aug 5, 2014
|
||||
* @author Andrey Belomutskiy, (c) 2012-2014
|
||||
*/
|
||||
|
||||
#include "mitsubishi.h"
|
||||
#include "thermistors.h"
|
||||
|
||||
void setMitsubishiConfiguration(engine_configuration_s *engineConfiguration, board_configuration_s *boardConfiguration) {
|
||||
engineConfiguration->engineType = MITSU_4G93;
|
||||
|
||||
engineConfiguration->triggerConfig.triggerType = TT_MITSU;
|
||||
|
||||
engineConfiguration->cylindersCount = 4;
|
||||
engineConfiguration->displacement = 1.800;
|
||||
|
||||
// set_ignition_mode 2
|
||||
engineConfiguration->ignitionMode = IM_WASTED_SPARK;
|
||||
engineConfiguration->firingOrder = FO_1_THEN_3_THEN_4_THEN2;
|
||||
|
||||
// set_global_trigger_offset_angle 671
|
||||
engineConfiguration->globalTriggerAngleOffset = 671;
|
||||
|
||||
// set_cranking_rpm 550
|
||||
engineConfiguration->crankingSettings.crankingRpm = 550;
|
||||
// set_cranking_charge_angle 70
|
||||
engineConfiguration->crankingChargeAngle = 70;
|
||||
// set_cranking_timing_angle 715
|
||||
engineConfiguration->crankingTimingAngle = 715;
|
||||
|
||||
// set_whole_fuel_map 3
|
||||
setWholeFuelMap(engineConfiguration, 3);
|
||||
|
||||
// since CLT is not wired up yet let's just use same value for min and max
|
||||
// set_cranking_fuel_max 6 40
|
||||
engineConfiguration->crankingSettings.coolantTempMaxC = 37.7; // 6ms at 37.7C
|
||||
engineConfiguration->crankingSettings.fuelAtMaxTempMs = 6;
|
||||
|
||||
// set_cranking_fuel_min 6 -40
|
||||
engineConfiguration->crankingSettings.coolantTempMinC = -40; // 6ms at -40C
|
||||
engineConfiguration->crankingSettings.fuelAtMinTempMs = 6;
|
||||
|
||||
// /**
|
||||
// * 29150 Ohm @ 40C
|
||||
// * 10160 Ohm @ 70C
|
||||
// * 1270 Ohm @ 150C
|
||||
// */
|
||||
// setThermistorConfiguration(&engineConfiguration->cltThermistorConf, 40, 29150, 70, 10160, 150, 1270);
|
||||
|
||||
/**
|
||||
* 18K Ohm @ -20C
|
||||
* 2.1K Ohm @ 24C
|
||||
* 294 Ohm @ 80C
|
||||
* http://www.rexbo.eu/hella/coolant-temperature-sensor-6pt009107121?c=100334&at=3130
|
||||
*/
|
||||
setThermistorConfiguration(&engineConfiguration->cltThermistorConf, -20, 18000, 23.8889, 2100, 80, 294);
|
||||
|
||||
engineConfiguration->cltThermistorConf.bias_resistor = 2700;
|
||||
|
||||
// Frankenstein: low side - inj #1: PC14
|
||||
// Frankenstein: low side - inj #2: PC15
|
||||
// Frankenstein: low side - inj #3: PE6
|
||||
// Frankenstein: low side - inj #4: PC13
|
||||
// Frankenstein: low side - inj #5: PE4
|
||||
// Frankenstein: low side - inj #6: PE5
|
||||
// Frankenstein: low side - inj #7: PE2
|
||||
// Frankenstein: low side - inj #8: PE3
|
||||
// Frankenstein: low side - inj #9: PE0
|
||||
// Frankenstein: low side - inj #10: PE1
|
||||
// Frankenstein: low side - inj #11: PB8
|
||||
// Frankenstein: low side - inj #12: PB9
|
||||
|
||||
boardConfiguration->injectionPins[0] = GPIOB_9; // Frankenstein: low side - inj #12
|
||||
boardConfiguration->injectionPins[1] = GPIOB_8; // Frankenstein: low side - inj #11
|
||||
boardConfiguration->injectionPins[2] = GPIOE_3; // Frankenstein: low side - inj #8
|
||||
boardConfiguration->injectionPins[3] = GPIOE_5; // Frankenstein: low side - inj #6
|
||||
|
||||
|
||||
// Frankenstein: high side #1: PE8
|
||||
// Frankenstein: high side #2: PE10
|
||||
|
||||
boardConfiguration->ignitionPins[0] = GPIOE_8; // Frankenstein: high side #1
|
||||
boardConfiguration->ignitionPins[1] = GPIO_NONE;
|
||||
boardConfiguration->ignitionPins[2] = GPIOE_10; // // Frankenstein: high side #2
|
||||
boardConfiguration->ignitionPins[3] = GPIO_NONE;
|
||||
|
||||
engineConfiguration->HD44780width = 20;
|
||||
engineConfiguration->HD44780height = 4;
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
/**
|
||||
* @file mitsubishi.h
|
||||
*
|
||||
* @date Aug 5, 2014
|
||||
* @author Andrey Belomutskiy, (c) 2012-2014
|
||||
*/
|
||||
#ifndef MITSUBISHI_H_
|
||||
#define MITSUBISHI_H_
|
||||
|
||||
#include "main.h"
|
||||
|
||||
#include "engine_configuration.h"
|
||||
|
||||
void setMitsubishiConfiguration(engine_configuration_s *engineConfiguration, board_configuration_s *boardConfiguration);
|
||||
|
||||
#endif /* MITSUBISHI_H_ */
|
|
@ -80,11 +80,9 @@ static bool getConsoleLine(BaseSequentialStream *chp, char *line, unsigned size)
|
|||
continue;
|
||||
#endif
|
||||
|
||||
if (c < 0)
|
||||
if (c < 0 || c == 4) {
|
||||
return TRUE;
|
||||
if (c == 4) {
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
if (c == 8) {
|
||||
if (p != line) {
|
||||
// backspace
|
||||
|
@ -101,8 +99,9 @@ static bool getConsoleLine(BaseSequentialStream *chp, char *line, unsigned size)
|
|||
*p = 0;
|
||||
return false;
|
||||
}
|
||||
if (c < 0x20)
|
||||
if (c < 0x20) {
|
||||
continue;
|
||||
}
|
||||
if (p < line + size - 1) {
|
||||
consolePutChar((uint8_t) c);
|
||||
*p++ = (char) c;
|
||||
|
@ -152,7 +151,7 @@ SerialDriver * getConsoleChannel(void) {
|
|||
}
|
||||
}
|
||||
|
||||
int isConsoleReady(void) {
|
||||
bool isConsoleReady(void) {
|
||||
if (isSerialOverUart()) {
|
||||
return isSerialConsoleStarted;
|
||||
} else {
|
||||
|
@ -169,7 +168,7 @@ void consolePutChar(int x) {
|
|||
// 10 seconds
|
||||
#define CONSOLE_WRITE_TIMEOUT 10000
|
||||
|
||||
void consoleOutputBuffer(const int8_t *buf, int size) {
|
||||
void consoleOutputBuffer(const uint8_t *buf, int size) {
|
||||
lastWriteSize = size;
|
||||
#if !EFI_UART_ECHO_TEST_MODE
|
||||
lastWriteActual = chnWriteTimeout(getConsoleChannel(), buf, size, CONSOLE_WRITE_TIMEOUT);
|
||||
|
|
|
@ -32,9 +32,9 @@ extern "C"
|
|||
SerialDriver * getConsoleChannel(void);
|
||||
|
||||
void consolePutChar(int x);
|
||||
void consoleOutputBuffer(const int8_t *buf, int size);
|
||||
void consoleOutputBuffer(const uint8_t *buf, int size);
|
||||
void startConsole(void (*console_line_callback_p)(char *));
|
||||
int isConsoleReady(void);
|
||||
bool isConsoleReady(void);
|
||||
bool isSerialOverUart(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -130,17 +130,14 @@ static void cmd_threads(void) {
|
|||
#endif
|
||||
}
|
||||
|
||||
void sendOutConfirmation(char *value, int i) {
|
||||
scheduleMsg(&logger, "%s%d", value, i);
|
||||
}
|
||||
|
||||
/**
|
||||
* This methods prints the message to whatever is configured as our primary console
|
||||
*/
|
||||
void print(const char *format, ...) {
|
||||
#if !EFI_UART_ECHO_TEST_MODE
|
||||
if (!isConsoleReady())
|
||||
if (!isConsoleReady()) {
|
||||
return;
|
||||
}
|
||||
va_list ap;
|
||||
va_start(ap, format);
|
||||
chvprintf((BaseSequentialStream*)getConsoleChannel(), format, ap);
|
||||
|
@ -148,7 +145,7 @@ void print(const char *format, ...) {
|
|||
#endif /* EFI_UART_ECHO_TEST_MODE */
|
||||
}
|
||||
|
||||
void initializeConsole() {
|
||||
void initializeConsole(void) {
|
||||
initIntermediateLoggingBuffer();
|
||||
initConsoleLogic();
|
||||
|
||||
|
|
|
@ -16,7 +16,6 @@ extern "C"
|
|||
#endif /* __cplusplus */
|
||||
|
||||
void initializeConsole(void);
|
||||
void sendOutConfirmation(char *value, int i);
|
||||
void print(const char *fmt, ...);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* @file status_loop.c
|
||||
* @file status_loop.cpp
|
||||
* @brief Human-readable protocol status messages
|
||||
*
|
||||
* http://rusefi.com/forum/viewtopic.php?t=263 Dev console overview
|
||||
|
@ -46,8 +46,6 @@
|
|||
#include "tunerstudio.h"
|
||||
#endif /* EFI_TUNER_STUDIO */
|
||||
|
||||
#include "wave_math.h"
|
||||
|
||||
#include "fuel_math.h"
|
||||
#include "main_trigger_callback.h"
|
||||
#include "engine_math.h"
|
||||
|
@ -56,18 +54,22 @@
|
|||
#include "rfiutil.h"
|
||||
#include "svnversion.h"
|
||||
#include "engine.h"
|
||||
#include "lcd_controller.h"
|
||||
#include "fuel_math.h"
|
||||
|
||||
#if EFI_PROD_CODE
|
||||
// todo: move this logic to algo folder!
|
||||
#include "rtc_helper.h"
|
||||
#include "lcd_HD44780.h"
|
||||
#include "rusefi.h"
|
||||
#include "pin_repository.h"
|
||||
#include "flash_main.h"
|
||||
#endif
|
||||
|
||||
extern Engine engine;
|
||||
|
||||
// this 'true' value is needed for simulator
|
||||
static volatile int fullLog = TRUE;
|
||||
static volatile bool fullLog = true;
|
||||
int warningEnabled = TRUE;
|
||||
//int warningEnabled = FALSE;
|
||||
|
||||
|
@ -112,10 +114,6 @@ static const char* boolean2string(int value) {
|
|||
return value ? "YES" : "NO";
|
||||
}
|
||||
|
||||
void finishStatusLine(void) {
|
||||
printLine(&logger);
|
||||
}
|
||||
|
||||
void printSensors(void) {
|
||||
#if EFI_FILE_LOGGING
|
||||
resetLogging(&fileLogger);
|
||||
|
@ -186,7 +184,7 @@ void printState(int currentCkpEventCounter) {
|
|||
#define INITIAL_FULL_LOG TRUE
|
||||
//#define INITIAL_FULL_LOG FALSE
|
||||
|
||||
static char LOGGING_BUFFER[500];
|
||||
static char LOGGING_BUFFER[700];
|
||||
|
||||
volatile int needToReportStatus = FALSE;
|
||||
static int prevCkpEventCounter = -1;
|
||||
|
@ -203,13 +201,42 @@ static void printStatus(void) {
|
|||
*/
|
||||
static systime_t timeOfPreviousPrintVersion = (systime_t) -1;
|
||||
|
||||
static void printVersion(systime_t nowSeconds) {
|
||||
if (overflowDiff(nowSeconds, timeOfPreviousPrintVersion) < 4)
|
||||
#if EFI_PROD_CODE
|
||||
static void printOutPin(const char *pinName, brain_pin_e hwPin) {
|
||||
appendPrintf(&logger, "outpin%s%s@%s%s", DELIMETER, pinName,
|
||||
hwPortname(hwPin), DELIMETER);
|
||||
}
|
||||
#endif /* EFI_PROD_CODE */
|
||||
|
||||
static void printInfo(systime_t nowSeconds) {
|
||||
/**
|
||||
* we report the version every 4 seconds - this way the console does not need to
|
||||
* request it and we will display it pretty soon
|
||||
*/
|
||||
if (overflowDiff(nowSeconds, timeOfPreviousPrintVersion) < 4) {
|
||||
return;
|
||||
}
|
||||
timeOfPreviousPrintVersion = nowSeconds;
|
||||
appendPrintf(&logger, "rusEfiVersion%s%d@%s %s%s", DELIMETER, getRusEfiVersion(), VCS_VERSION,
|
||||
getConfigurationName(engineConfiguration),
|
||||
DELIMETER);
|
||||
#if EFI_PROD_CODE
|
||||
printOutPin(WC_CRANK1, boardConfiguration->triggerInputPins[0]);
|
||||
printOutPin(WC_CRANK2, boardConfiguration->triggerInputPins[1]);
|
||||
printOutPin(WA_CHANNEL_1, boardConfiguration->logicAnalyzerPins[0]);
|
||||
printOutPin(WA_CHANNEL_2, boardConfiguration->logicAnalyzerPins[1]);
|
||||
|
||||
for (int i = 0; i < engineConfiguration->cylindersCount; i++) {
|
||||
// todo: extract method?
|
||||
io_pin_e pin = (io_pin_e) ((int) SPARKOUT_1_OUTPUT + i);
|
||||
|
||||
printOutPin(getPinName(pin), boardConfiguration->ignitionPins[i]);
|
||||
|
||||
pin = (io_pin_e) ((int) INJECTOR_1_OUTPUT + i);
|
||||
printOutPin(getPinName(pin), boardConfiguration->injectionPins[i]);
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
static systime_t timeOfPreviousReport = (systime_t) -1;
|
||||
|
@ -220,8 +247,9 @@ extern char errorMessageBuffer[200];
|
|||
* @brief Sends all pending data to dev console
|
||||
*/
|
||||
void updateDevConsoleState(void) {
|
||||
if (!isConsoleReady())
|
||||
if (!isConsoleReady()) {
|
||||
return;
|
||||
}
|
||||
// looks like this is not needed anymore
|
||||
// checkIfShouldHalt();
|
||||
printPending();
|
||||
|
@ -240,15 +268,17 @@ void updateDevConsoleState(void) {
|
|||
pokeAdcInputs();
|
||||
#endif
|
||||
|
||||
if (!fullLog)
|
||||
if (!fullLog) {
|
||||
return;
|
||||
}
|
||||
|
||||
systime_t nowSeconds = getTimeNowSeconds();
|
||||
printVersion(nowSeconds);
|
||||
printInfo(nowSeconds);
|
||||
|
||||
int currentCkpEventCounter = getCrankEventCounter();
|
||||
if (prevCkpEventCounter == currentCkpEventCounter && timeOfPreviousReport == nowSeconds)
|
||||
if (prevCkpEventCounter == currentCkpEventCounter && timeOfPreviousReport == nowSeconds) {
|
||||
return;
|
||||
}
|
||||
|
||||
timeOfPreviousReport = nowSeconds;
|
||||
|
||||
|
@ -257,10 +287,10 @@ void updateDevConsoleState(void) {
|
|||
printState(currentCkpEventCounter);
|
||||
|
||||
#if EFI_WAVE_ANALYZER
|
||||
// printWave(&logger);
|
||||
printWave(&logger);
|
||||
#endif
|
||||
|
||||
finishStatusLine();
|
||||
printLine(&logger);
|
||||
}
|
||||
|
||||
#if EFI_PROD_CODE
|
||||
|
@ -272,7 +302,7 @@ void updateDevConsoleState(void) {
|
|||
*/
|
||||
|
||||
static void showFuelMap2(float rpm, float engineLoad) {
|
||||
float baseFuel = getBaseTableFuel(rpm, engineLoad);
|
||||
float baseFuel = getBaseTableFuel((int) rpm, engineLoad);
|
||||
|
||||
float iatCorrection = getIatCorrection(getIntakeAirTemperature());
|
||||
float cltCorrection = getCltCorrection(getCoolantTemperature());
|
||||
|
@ -283,49 +313,19 @@ static void showFuelMap2(float rpm, float engineLoad) {
|
|||
scheduleMsg(&logger2, "iatCorrection=%f cltCorrection=%f injectorLag=%f", iatCorrection, cltCorrection,
|
||||
injectorLag);
|
||||
|
||||
float value = getRunningFuel(baseFuel, &engine, rpm);
|
||||
float value = getRunningFuel(baseFuel, &engine, (int) rpm);
|
||||
scheduleMsg(&logger2, "injection pulse width: %f", value);
|
||||
}
|
||||
|
||||
static void showFuelMap(void) {
|
||||
showFuelMap2(getRpm(), getEngineLoad());
|
||||
showFuelMap2((float) getRpm(), getEngineLoad());
|
||||
}
|
||||
|
||||
|
||||
static char buffer[10];
|
||||
static char dateBuffer[30];
|
||||
|
||||
void updateHD44780lcd(void) {
|
||||
|
||||
lcd_HD44780_set_position(0, 9);
|
||||
lcd_HD44780_print_char('R');
|
||||
lcd_HD44780_set_position(0, 10);
|
||||
|
||||
char * ptr = itoa10(buffer, getRpm());
|
||||
ptr[0] = 0;
|
||||
int len = ptr - buffer;
|
||||
for (int i = 0; i < 6 - len; i++)
|
||||
lcd_HD44780_print_char(' ');
|
||||
|
||||
lcd_HD44780_print_string(buffer);
|
||||
|
||||
lcd_HD44780_set_position(2, 0);
|
||||
lcd_HD44780_print_char('C');
|
||||
|
||||
ftoa(buffer, getCoolantTemperature(), 100);
|
||||
lcd_HD44780_print_string(buffer);
|
||||
|
||||
#if EFI_PROD_CODE
|
||||
dateToString(dateBuffer);
|
||||
lcd_HD44780_set_position(1, 0);
|
||||
lcd_HD44780_print_string(dateBuffer);
|
||||
#endif /* EFI_PROD_CODE */
|
||||
}
|
||||
#endif /* EFI_PROD_CODE */
|
||||
|
||||
static THD_WORKING_AREA(lcdThreadStack, UTILITY_THREAD_STACK_SIZE);
|
||||
|
||||
static void lcdThread(void *arg) {
|
||||
static void lcdThread(void) {
|
||||
chRegSetThreadName("lcd");
|
||||
while (true) {
|
||||
#if EFI_HD44780_LCD
|
||||
|
@ -338,7 +338,6 @@ static void lcdThread(void *arg) {
|
|||
static THD_WORKING_AREA(tsThreadStack, UTILITY_THREAD_STACK_SIZE);
|
||||
|
||||
#if EFI_TUNER_STUDIO
|
||||
extern TunerStudioOutputChannels tsOutputChannels;
|
||||
|
||||
void updateTunerStudioState(TunerStudioOutputChannels *tsOutputChannels) {
|
||||
#if EFI_SHAFT_POSITION_INPUT
|
||||
|
@ -351,6 +350,9 @@ void updateTunerStudioState(TunerStudioOutputChannels *tsOutputChannels) {
|
|||
float coolant = getCoolantTemperature();
|
||||
float intake = getIntakeAirTemperature();
|
||||
|
||||
float engineLoad = getEngineLoad();
|
||||
float baseFuel = getBaseTableFuel((int) rpm, engineLoad);
|
||||
|
||||
tsOutputChannels->rpm = rpm;
|
||||
tsOutputChannels->coolant_temperature = coolant;
|
||||
tsOutputChannels->intake_air_temperature = intake;
|
||||
|
@ -362,8 +364,24 @@ void updateTunerStudioState(TunerStudioOutputChannels *tsOutputChannels) {
|
|||
tsOutputChannels->atmospherePressure = getBaroPressure();
|
||||
tsOutputChannels->manifold_air_pressure = getMap();
|
||||
tsOutputChannels->checkEngine = hasErrorCodes();
|
||||
#if EFI_PROD_CODE
|
||||
tsOutputChannels->needBurn = getNeedToWriteConfiguration();
|
||||
tsOutputChannels->hasSdCard = isSdCardAlive();
|
||||
tsOutputChannels->isFuelPumpOn = getOutputPinValue(FUEL_PUMP_RELAY);
|
||||
tsOutputChannels->isFanOn = getOutputPinValue(FAN_RELAY);
|
||||
tsOutputChannels->isO2HeaterOn = getOutputPinValue(O2_HEATER);
|
||||
tsOutputChannels->ignition_enabled = engineConfiguration->isIgnitionEnabled;
|
||||
tsOutputChannels->injection_enabled = engineConfiguration->isInjectionEnabled;
|
||||
tsOutputChannels->cylinder_cleanup_enabled = engineConfiguration->isCylinderCleanupEnabled;
|
||||
tsOutputChannels->secondTriggerChannelEnabled = engineConfiguration->secondTriggerChannelEnabled;
|
||||
#endif
|
||||
tsOutputChannels->tCharge = getTCharge(rpm, tps, coolant, intake);
|
||||
tsOutputChannels->sparkDwell = getSparkDwellMs(rpm);
|
||||
tsOutputChannels->pulseWidth = getRunningFuel(baseFuel, &engine, rpm);
|
||||
tsOutputChannels->crankingFuel = getCrankingFuel();
|
||||
}
|
||||
|
||||
extern TunerStudioOutputChannels tsOutputChannels;
|
||||
#endif /* EFI_TUNER_STUDIO */
|
||||
|
||||
static void tsStatusThread(void *arg) {
|
||||
|
@ -403,8 +421,8 @@ void initStatusLoop(void) {
|
|||
|
||||
void startStatusThreads(void) {
|
||||
// todo: refactoring needed, this file should probably be split into pieces
|
||||
chThdCreateStatic(lcdThreadStack, sizeof(lcdThreadStack), NORMALPRIO, (tfunc_t) lcdThread, NULL);
|
||||
chThdCreateStatic(tsThreadStack, sizeof(tsThreadStack), NORMALPRIO, (tfunc_t) tsStatusThread, NULL);
|
||||
chThdCreateStatic(lcdThreadStack, sizeof(lcdThreadStack), NORMALPRIO, (tfunc_t) lcdThread, (void*) NULL);
|
||||
chThdCreateStatic(tsThreadStack, sizeof(tsThreadStack), NORMALPRIO, (tfunc_t) tsStatusThread, (void*) NULL);
|
||||
}
|
||||
|
||||
void setFullLog(int value) {
|
||||
|
@ -413,6 +431,6 @@ void setFullLog(int value) {
|
|||
fullLog = value;
|
||||
}
|
||||
|
||||
int getFullLog(void) {
|
||||
bool getFullLog(void) {
|
||||
return fullLog;
|
||||
}
|
||||
|
|
|
@ -17,7 +17,7 @@ void printState(int currentCkpEventCounter);
|
|||
|
||||
void initStatusLoop(void);
|
||||
void updateDevConsoleState(void);
|
||||
int getFullLog(void);
|
||||
bool getFullLog(void);
|
||||
void printSensors(void);
|
||||
void setFullLog(int value);
|
||||
void startStatusThreads(void);
|
||||
|
|
|
@ -33,7 +33,6 @@
|
|||
#include "tunerstudio_algo.h"
|
||||
#include "tunerstudio_configuration.h"
|
||||
#include "malfunction_central.h"
|
||||
#include "wave_math.h"
|
||||
#include "console_io.h"
|
||||
#include "crc.h"
|
||||
|
||||
|
@ -54,14 +53,14 @@ static SerialConfig tsSerialConfig = { TS_SERIAL_SPEED, 0, USART_CR2_STOP1_BITS
|
|||
#endif /* EFI_PROD_CODE */
|
||||
|
||||
#define MAX_PAGE_ID 0
|
||||
#define PAGE_0_SIZE 5824
|
||||
#define PAGE_0_SIZE 5928
|
||||
#define TS_OUTPUT_SIZE 116
|
||||
|
||||
// in MS, that's 10 seconds
|
||||
#define TS_READ_TIMEOUT 10000
|
||||
|
||||
#define PROTOCOL "001"
|
||||
|
||||
|
||||
BaseChannel * getTsSerialDevice(void) {
|
||||
#if EFI_PROD_CODE
|
||||
if (isSerialOverUart()) {
|
||||
|
@ -77,7 +76,6 @@ BaseChannel * getTsSerialDevice(void) {
|
|||
|
||||
static Logging logger;
|
||||
|
||||
extern engine_configuration_s *engineConfiguration;
|
||||
extern persistent_config_s configWorkingCopy;
|
||||
extern persistent_config_container_s persistentState;
|
||||
|
||||
|
@ -108,6 +106,10 @@ extern TunerStudioOutputChannels tsOutputChannels;
|
|||
|
||||
extern TunerStudioState tsState;
|
||||
|
||||
extern engine_configuration_s *engineConfiguration;
|
||||
extern board_configuration_s *boardConfiguration;
|
||||
|
||||
|
||||
static void printStats(void) {
|
||||
#if EFI_PROD_CODE
|
||||
if (!isSerialOverUart()) {
|
||||
|
@ -127,14 +129,11 @@ static void printStats(void) {
|
|||
// int fuelMapOffset = (int) (&engineConfiguration->fuelTable) - (int) engineConfiguration;
|
||||
// scheduleMsg(&logger, "fuelTable %d", fuelMapOffset);
|
||||
//
|
||||
// int offset = (int) (&engineConfiguration->bc.injectionPinMode) - (int) engineConfiguration;
|
||||
// scheduleMsg(&logger, "injectionPinMode %d", offset);
|
||||
// int offset = (int) (&boardConfiguration->o2heaterPin) - (int) engineConfiguration;
|
||||
// scheduleMsg(&logger, "o2heaterPin %d", offset);
|
||||
//
|
||||
// offset = (int) (&engineConfiguration->bc.idleThreadPeriod) - (int) engineConfiguration;
|
||||
// scheduleMsg(&logger, "idleThreadPeriod %d", offset);
|
||||
|
||||
if (sizeof(engine_configuration_s) != getTunerStudioPageSize(0))
|
||||
firmwareError("TS page size mismatch");
|
||||
// offset = (int) (&boardConfiguration->idleSolenoidFrequency) - (int) engineConfiguration;
|
||||
// scheduleMsg(&logger, "idleSolenoidFrequency %d", offset);
|
||||
}
|
||||
|
||||
void tunerStudioWriteData(const uint8_t * buffer, int size) {
|
||||
|
@ -227,7 +226,7 @@ void handleWriteValueCommand(ts_response_format_e mode, uint16_t page, uint16_t
|
|||
// scheduleMsg(&logger, "Page number %d\r\n", pageId); // we can get a lot of these
|
||||
#endif
|
||||
|
||||
int size = sizeof(TunerStudioWriteValueRequest);
|
||||
// int size = sizeof(TunerStudioWriteValueRequest);
|
||||
// scheduleMsg(&logger, "Reading %d\r\n", size);
|
||||
|
||||
if (offset > getTunerStudioPageSize(tsState.currentPageId)) {
|
||||
|
@ -258,7 +257,7 @@ void handlePageReadCommand(ts_response_format_e mode, uint16_t pageId, uint16_t
|
|||
tsState.currentPageId = pageId;
|
||||
|
||||
#if EFI_TUNER_STUDIO_VERBOSE
|
||||
scheduleMsg(&logger, "Page requested: page %d offset=%d count=%d", tsState.currentPageId, offset, count);
|
||||
scheduleMsg(&logger, "Page requested: page %d offset=%d count=%d", (int)tsState.currentPageId, offset, count);
|
||||
#endif
|
||||
|
||||
if (tsState.currentPageId > MAX_PAGE_ID) {
|
||||
|
@ -305,7 +304,7 @@ void handleBurnCommand(ts_response_format_e mode, uint16_t page) {
|
|||
memcpy(&persistentState.persistentConfiguration, &configWorkingCopy, sizeof(persistent_config_s));
|
||||
|
||||
#if EFI_INTERNAL_FLASH
|
||||
writeToFlash();
|
||||
setNeedToWriteConfiguration();
|
||||
#endif
|
||||
incrementGlobalConfigurationVersion();
|
||||
tunerStudioWriteCrcPacket(TS_RESPONSE_BURN_OK, NULL, 0);
|
||||
|
@ -397,7 +396,7 @@ static msg_t tsThreadEntryPoint(void *arg) {
|
|||
}
|
||||
// scheduleMsg(&logger, "Got secondByte=%x=[%c]", secondByte, secondByte);
|
||||
|
||||
int incomingPacketSize = firstByte * 256 + secondByte;
|
||||
uint32_t incomingPacketSize = firstByte * 256 + secondByte;
|
||||
|
||||
if (incomingPacketSize == 0 || incomingPacketSize > sizeof(crcIoBuffer)) {
|
||||
scheduleMsg(&logger, "TunerStudio: invalid size: %d", incomingPacketSize);
|
||||
|
@ -435,7 +434,7 @@ static msg_t tsThreadEntryPoint(void *arg) {
|
|||
|
||||
expectedCrc = SWAP_UINT32(expectedCrc);
|
||||
|
||||
int actualCrc = crc32(crcIoBuffer, incomingPacketSize);
|
||||
uint32_t actualCrc = crc32(crcIoBuffer, incomingPacketSize);
|
||||
if (actualCrc != expectedCrc) {
|
||||
scheduleMsg(&logger, "TunerStudio: CRC %x %x %x %x", crcIoBuffer[incomingPacketSize + 0],
|
||||
crcIoBuffer[incomingPacketSize + 1], crcIoBuffer[incomingPacketSize + 2],
|
||||
|
@ -466,6 +465,13 @@ void syncTunerStudioCopy(void) {
|
|||
|
||||
void startTunerStudioConnectivity(void) {
|
||||
initLogging(&logger, "tuner studio");
|
||||
|
||||
if (sizeof(engine_configuration_s) != getTunerStudioPageSize(0))
|
||||
firmwareError("TS page size mismatch: %d/%d", sizeof(engine_configuration_s), getTunerStudioPageSize(0));
|
||||
|
||||
if (sizeof(TunerStudioOutputChannels) != TS_OUTPUT_SIZE)
|
||||
firmwareError("TS outputs size mismatch: %d/%d", sizeof(TunerStudioOutputChannels), TS_OUTPUT_SIZE);
|
||||
|
||||
memset(&tsState, 0, sizeof(tsState));
|
||||
#if EFI_PROD_CODE
|
||||
if (isSerialOverUart()) {
|
||||
|
|
|
@ -48,6 +48,7 @@
|
|||
#include "tunerstudio_configuration.h"
|
||||
#include "engine_configuration.h"
|
||||
#include "tunerstudio.h"
|
||||
#include "svnversion.h"
|
||||
|
||||
#ifndef FALSE
|
||||
#define FALSE 0
|
||||
|
@ -150,5 +151,6 @@ void handleTestCommand(void) {
|
|||
* extension of the protocol to simplify troubleshooting
|
||||
*/
|
||||
tunerStudioDebug("got T (Test)");
|
||||
tunerStudioWriteData((const uint8_t *) "alive\r\n", 7);
|
||||
tunerStudioWriteData((const uint8_t *)VCS_VERSION, sizeof(VCS_VERSION));
|
||||
tunerStudioWriteData((const uint8_t *) " alive\r\n", 8);
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
* support 'float' (F32) type. You would need a beta version to handle floats
|
||||
*/
|
||||
typedef struct {
|
||||
// primary instrument cluster gauges
|
||||
int rpm; // size 4, offset 0
|
||||
float coolant_temperature; // size 4, offset 4
|
||||
float intake_air_temperature; // size 4, offset 8
|
||||
|
@ -28,8 +29,29 @@ typedef struct {
|
|||
short int alignment; // size 2, offset 34
|
||||
float atmospherePressure; // size 4, offset 36
|
||||
float manifold_air_pressure; // size 4, offset 40
|
||||
int checkEngine; // size 4, offset 44
|
||||
float tCharge;
|
||||
float crankingFuel;
|
||||
int tpsVolrage;
|
||||
float tCharge; // 52
|
||||
float inj_adv; // 56
|
||||
float sparkDwell; // 60
|
||||
float pulseWidth; // 64
|
||||
float warmUpEnrich; // 68
|
||||
/**
|
||||
* Yes, I do not really enjoy packing bits into integers but we simply have too many boolean flags and I cannot
|
||||
* water 4 bytes per trafic - I want gauges to work as fast as possible
|
||||
*/
|
||||
unsigned int hasSdCard : 1; // bit 0
|
||||
unsigned int ignition_enabled : 1; // bit 1
|
||||
unsigned int injection_enabled : 1; // bit 2
|
||||
unsigned int cylinder_cleanup_enabled : 1; // bit 3
|
||||
unsigned int cylinder_cleanup : 1; // bit 4
|
||||
unsigned int isFuelPumpOn : 1; // bit 5
|
||||
unsigned int isFanOn : 1; // bit 6
|
||||
unsigned int isO2HeaterOn : 1; // bit 7
|
||||
unsigned int checkEngine : 1; // bit 8
|
||||
unsigned int needBurn : 1; // bit 9
|
||||
unsigned int secondTriggerChannelEnabled : 1; // bit 10
|
||||
int unused[10];
|
||||
} TunerStudioOutputChannels;
|
||||
|
||||
#endif /* TUNERSTUDIO_CONFIGURATION_H_ */
|
||||
|
|
|
@ -49,7 +49,8 @@
|
|||
/**
|
||||
* This is the buffer into which all the data providers write
|
||||
*/
|
||||
static char pendingBuffer[DL_OUTPUT_BUFFER] CCM_OPTIONAL;
|
||||
static char pendingBuffer[DL_OUTPUT_BUFFER] CCM_OPTIONAL
|
||||
;
|
||||
|
||||
/**
|
||||
* We copy all the pending data into this buffer once we are ready to push it out
|
||||
|
@ -57,10 +58,12 @@ static char pendingBuffer[DL_OUTPUT_BUFFER] CCM_OPTIONAL;
|
|||
static char outputBuffer[DL_OUTPUT_BUFFER];
|
||||
|
||||
static MemoryStream intermediateLoggingBuffer;
|
||||
static uint8_t intermediateLoggingBufferData[INTERMEDIATE_LOGGING_BUFFER_SIZE] CCM_OPTIONAL; //todo define max-printf-buffer
|
||||
static uint8_t intermediateLoggingBufferData[INTERMEDIATE_LOGGING_BUFFER_SIZE] CCM_OPTIONAL
|
||||
;
|
||||
//todo define max-printf-buffer
|
||||
static bool intermediateLoggingBufferInited = FALSE;
|
||||
|
||||
static int validateBuffer(Logging *logging, int extraLen, const char *text) {
|
||||
static int validateBuffer(Logging *logging, uint32_t extraLen, const char *text) {
|
||||
if (logging->buffer == NULL) {
|
||||
firmwareError("Logging not initialized: %s", logging->name);
|
||||
return TRUE;
|
||||
|
@ -81,10 +84,11 @@ static int validateBuffer(Logging *logging, int extraLen, const char *text) {
|
|||
|
||||
void append(Logging *logging, const char *text) {
|
||||
efiAssertVoid(text != NULL, "append NULL");
|
||||
int extraLen = strlen(text);
|
||||
uint32_t extraLen = strlen(text);
|
||||
int errcode = validateBuffer(logging, extraLen, text);
|
||||
if (errcode)
|
||||
if (errcode) {
|
||||
return;
|
||||
}
|
||||
strcpy(logging->linePointer, text);
|
||||
logging->linePointer += extraLen;
|
||||
}
|
||||
|
@ -171,6 +175,7 @@ char* getCaption(LoggingPoints loggingPoint) {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
// todo: this method does not really belong to this file
|
||||
static char* get2ndCaption(int loggingPoint) {
|
||||
switch (loggingPoint) {
|
||||
|
@ -192,6 +197,7 @@ static char* get2ndCaption(int loggingPoint) {
|
|||
firmwareError("No such loggingPoint");
|
||||
return NULL;
|
||||
}
|
||||
*/
|
||||
|
||||
void initLoggingExt(Logging *logging, const char *name, char *buffer, int bufferSize) {
|
||||
print("Init logging %s\r\n", name);
|
||||
|
@ -284,8 +290,8 @@ static void printWithLength(char *line) {
|
|||
|
||||
if (!isConsoleReady())
|
||||
return;
|
||||
consoleOutputBuffer((const int8_t *) header, strlen(header));
|
||||
consoleOutputBuffer((const int8_t *) line, p - line);
|
||||
consoleOutputBuffer((const uint8_t *) header, strlen(header));
|
||||
consoleOutputBuffer((const uint8_t *) line, p - line);
|
||||
}
|
||||
|
||||
void printLine(Logging *logging) {
|
||||
|
@ -368,15 +374,17 @@ void scheduleLogging(Logging *logging) {
|
|||
// strcpy(fatalMessage, "datalogging.c: output buffer overflow: ");
|
||||
// strcat(fatalMessage, logging->name);
|
||||
// fatal(fatalMessage);
|
||||
if (!alreadyLocked)
|
||||
if (!alreadyLocked) {
|
||||
unlockOutputBuffer();
|
||||
}
|
||||
resetLogging(logging);
|
||||
return;
|
||||
}
|
||||
|
||||
strcat(pendingBuffer, logging->buffer);
|
||||
if (!alreadyLocked)
|
||||
if (!alreadyLocked) {
|
||||
unlockOutputBuffer();
|
||||
}
|
||||
resetLogging(logging);
|
||||
}
|
||||
|
||||
|
@ -387,15 +395,16 @@ uint32_t remainingSize(Logging *logging) {
|
|||
/**
|
||||
* This method actually sends all the pending data to the communication layer
|
||||
*/
|
||||
void printPending() {
|
||||
void printPending(void) {
|
||||
lockOutputBuffer();
|
||||
// we cannot output under syslock, so another buffer
|
||||
strcpy(outputBuffer, pendingBuffer);
|
||||
pendingBuffer[0] = 0; // reset pending buffer
|
||||
unlockOutputBuffer();
|
||||
|
||||
if (strlen(outputBuffer) > 0)
|
||||
if (strlen(outputBuffer) > 0) {
|
||||
printWithLength(outputBuffer);
|
||||
}
|
||||
}
|
||||
|
||||
void initIntermediateLoggingBuffer(void) {
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include "main.h"
|
||||
#include "rfiutil.h"
|
||||
|
||||
/*
|
||||
|
@ -49,7 +50,7 @@ int mylog10(int param) {
|
|||
char hexChar(int v) {
|
||||
v = v & 0xF;
|
||||
if (v < 10)
|
||||
return '0' + v;
|
||||
return (char)('0' + v);
|
||||
return 'A' - 10 + v;
|
||||
}
|
||||
|
||||
|
@ -68,8 +69,7 @@ int isLocked(void) {
|
|||
|
||||
void chVTSetAny(virtual_timer_t *vtp, systime_t time, vtfunc_t vtfunc, void *par) {
|
||||
if (isIsrContext()) {
|
||||
chSysLockFromIsr()
|
||||
;
|
||||
bool wasLocked = lockAnyContext();
|
||||
|
||||
/**
|
||||
* todo: this could be simplified once we migrate to ChibiOS 3.0
|
||||
|
@ -79,7 +79,8 @@ void chVTSetAny(virtual_timer_t *vtp, systime_t time, vtfunc_t vtfunc, void *par
|
|||
chVTResetI(vtp);
|
||||
|
||||
chVTSetI(vtp, time, vtfunc, par);
|
||||
chSysUnlockFromIsr()
|
||||
if (!wasLocked)
|
||||
chSysUnlockFromIsr()
|
||||
;
|
||||
} else {
|
||||
chSysLock()
|
||||
|
|
|
@ -23,11 +23,11 @@ static void startPwmTest(int freq) {
|
|||
scheduleMsg(&logger, "running pwm test @%d", freq);
|
||||
|
||||
// PD13, GPIO_NONE because pin is initialized elsewhere already
|
||||
startSimplePwm(&pwmTest[0], "tester", LED_WARNING, 10, 0.5);
|
||||
startSimplePwm(&pwmTest[0], "tester", LED_WARNING, 10, 0.5f);
|
||||
// currently this is PB9 by default - see boardConfiguration->injectionPins
|
||||
startSimplePwm(&pwmTest[1], "tester", INJECTOR_1_OUTPUT, freq / 1.3333333333, 0.5);
|
||||
startSimplePwm(&pwmTest[1], "tester", INJECTOR_1_OUTPUT, freq / 1.3333333333, 0.5f);
|
||||
// currently this is PB8 by default
|
||||
startSimplePwm(&pwmTest[2], "tester", INJECTOR_2_OUTPUT, freq / 1000, 0.5);
|
||||
startSimplePwm(&pwmTest[2], "tester", INJECTOR_2_OUTPUT, freq / 1000, 0.5f);
|
||||
// currently this is PE3 by default
|
||||
startSimplePwm(&pwmTest[3], "tester", INJECTOR_3_OUTPUT, freq, 0.5);
|
||||
// currently this is PE5 by default
|
||||
|
|
|
@ -35,7 +35,7 @@ static Map3D1616 advanceMap;
|
|||
float getBaseAdvance(int rpm, float engineLoad) {
|
||||
efiAssert(!cisnan(engineLoad), "invalid el", NAN);
|
||||
efiAssert(!cisnan(engineLoad), "invalid rpm", NAN);
|
||||
return advanceMap.getValue(engineLoad, engineConfiguration->ignitionLoadBins, rpm,
|
||||
return advanceMap.getValue(engineLoad, engineConfiguration->ignitionLoadBins, (float)rpm,
|
||||
engineConfiguration->ignitionRpmBins);
|
||||
}
|
||||
|
||||
|
|
|
@ -40,25 +40,20 @@ extern "C"
|
|||
* these fields are not integrated with Tuner Studio. Step by step :)
|
||||
*/
|
||||
class engine_configuration2_s {
|
||||
// todo: move these fields into Engine class, eliminate this class
|
||||
public:
|
||||
engine_configuration2_s();
|
||||
|
||||
Thermistor iat;
|
||||
Thermistor clt;
|
||||
|
||||
// int crankAngleRange;
|
||||
|
||||
trigger_shape_s triggerShape;
|
||||
|
||||
cranking_ignition_mode_e crankingIgnitionMode;
|
||||
|
||||
EventHandlerConfiguration engineEventConfiguration;
|
||||
|
||||
int isInjectionEnabledFlag;
|
||||
|
||||
/**
|
||||
* This coefficient translates ADC value directly into voltage adjusted according to
|
||||
* voltage divider configuration.
|
||||
* voltage divider configuration. This is a future (?) performance optimization.
|
||||
*/
|
||||
float adcToVoltageInputDividerCoefficient;
|
||||
};
|
||||
|
@ -72,6 +67,7 @@ void prepareOutputSignals(engine_configuration_s *engineConfiguration,
|
|||
engine_configuration2_s *engineConfiguration2);
|
||||
|
||||
void initializeIgnitionActions(float advance, float dwellAngle, engine_configuration_s *engineConfiguration, engine_configuration2_s *engineConfiguration2, IgnitionEventList *list);
|
||||
float getFuelMultiplier(engine_configuration_s const *e, injection_mode_e mode);
|
||||
void addFuelEvents(engine_configuration_s const *e, engine_configuration2_s *engineConfiguration2, ActuatorEventList *list, injection_mode_e mode);
|
||||
|
||||
void registerActuatorEventExt(engine_configuration_s const *engineConfiguration, trigger_shape_s * s, ActuatorEvent *e, OutputSignal *actuator, float angleOffset);
|
||||
|
@ -83,7 +79,6 @@ void resetConfigurationExt(Logging * logger, engine_type_e engineType,
|
|||
void applyNonPersistentConfiguration(Logging * logger, engine_configuration_s *engineConfiguration,
|
||||
engine_configuration2_s *engineConfiguration2);
|
||||
|
||||
|
||||
void setDefaultNonPersistentConfiguration(engine_configuration2_s *engineConfiguration2);
|
||||
void printConfiguration(engine_configuration_s *engineConfiguration, engine_configuration2_s *engineConfiguration2);
|
||||
|
||||
|
|
|
@ -48,6 +48,7 @@
|
|||
#include "ford_escort_gt.h"
|
||||
#include "citroenBerlingoTU3JP.h"
|
||||
#include "rover_v8.h"
|
||||
#include "mitsubishi.h"
|
||||
|
||||
static volatile int globalConfigurationVersion = 0;
|
||||
|
||||
|
@ -179,8 +180,8 @@ void setDefaultConfiguration(engine_configuration_s *engineConfiguration, board_
|
|||
|
||||
engineConfiguration->analogChartMode = AC_TRIGGER;
|
||||
|
||||
engineConfiguration->map.sensor.hwChannel = 4;
|
||||
engineConfiguration->baroSensor.hwChannel = 4;
|
||||
engineConfiguration->map.sensor.hwChannel = EFI_ADC_4;
|
||||
engineConfiguration->baroSensor.hwChannel = EFI_ADC_4;
|
||||
|
||||
engineConfiguration->firingOrder = FO_1_THEN_3_THEN_4_THEN2;
|
||||
engineConfiguration->crankingInjectionMode = IM_SIMULTANEOUS;
|
||||
|
@ -219,18 +220,19 @@ void setDefaultConfiguration(engine_configuration_s *engineConfiguration, board_
|
|||
engineConfiguration->displayMode = DM_HD44780;
|
||||
|
||||
engineConfiguration->logFormat = LF_NATIVE;
|
||||
engineConfiguration->directSelfStimulation = false;
|
||||
|
||||
engineConfiguration->triggerConfig.triggerType = TT_TOOTHED_WHEEL_60_2;
|
||||
|
||||
engineConfiguration->HD44780width = 16;
|
||||
engineConfiguration->HD44780height = 2;
|
||||
engineConfiguration->HD44780width = 20;
|
||||
engineConfiguration->HD44780height = 4;
|
||||
|
||||
engineConfiguration->tpsAdcChannel = 3;
|
||||
engineConfiguration->vBattAdcChannel = 5;
|
||||
engineConfiguration->cltAdcChannel = 6;
|
||||
engineConfiguration->iatAdcChannel = 7;
|
||||
engineConfiguration->mafAdcChannel = 0;
|
||||
engineConfiguration->afrSensor.afrAdcChannel = 14;
|
||||
engineConfiguration->tpsAdcChannel = EFI_ADC_3;
|
||||
engineConfiguration->vBattAdcChannel = EFI_ADC_5;
|
||||
engineConfiguration->cltAdcChannel = EFI_ADC_6;
|
||||
engineConfiguration->iatAdcChannel = EFI_ADC_7;
|
||||
engineConfiguration->mafAdcChannel = EFI_ADC_0;
|
||||
engineConfiguration->afrSensor.afrAdcChannel = EFI_ADC_14;
|
||||
|
||||
initBpsxD1Sensor(&engineConfiguration->afrSensor);
|
||||
|
||||
|
@ -247,12 +249,21 @@ void setDefaultConfiguration(engine_configuration_s *engineConfiguration, board_
|
|||
engineConfiguration->hasMapSensor = TRUE;
|
||||
engineConfiguration->hasCltSensor = TRUE;
|
||||
|
||||
boardConfiguration->idleSolenoidFrequency = 200;
|
||||
// engineConfiguration->idleMode = IM_AUTO;
|
||||
engineConfiguration->idleMode = IM_MANUAL;
|
||||
|
||||
engineConfiguration->isInjectionEnabled = true;
|
||||
engineConfiguration->isIgnitionEnabled = true;
|
||||
engineConfiguration->isCylinderCleanupEnabled = true;
|
||||
engineConfiguration->secondTriggerChannelEnabled = true;
|
||||
|
||||
boardConfiguration->idleValvePin = GPIOE_2;
|
||||
boardConfiguration->idleValvePinMode = OM_DEFAULT;
|
||||
boardConfiguration->fuelPumpPin = GPIOC_13;
|
||||
boardConfiguration->fuelPumpPinMode = OM_DEFAULT;
|
||||
boardConfiguration->electronicThrottlePin1 = GPIOC_9;
|
||||
boardConfiguration->o2heaterPin = GPIO_NONE;
|
||||
|
||||
boardConfiguration->injectionPins[0] = GPIOB_9;
|
||||
boardConfiguration->injectionPins[1] = GPIOB_8;
|
||||
|
@ -292,9 +303,11 @@ void setDefaultConfiguration(engine_configuration_s *engineConfiguration, board_
|
|||
|
||||
boardConfiguration->triggerSimulatorPins[0] = GPIOD_1;
|
||||
boardConfiguration->triggerSimulatorPins[1] = GPIOD_2;
|
||||
boardConfiguration->triggerSimulatorPins[2] = GPIOD_3;
|
||||
|
||||
boardConfiguration->triggerSimulatorPinModes[0] = OM_DEFAULT;
|
||||
boardConfiguration->triggerSimulatorPinModes[1] = OM_DEFAULT;
|
||||
boardConfiguration->triggerSimulatorPinModes[2] = OM_DEFAULT;
|
||||
|
||||
boardConfiguration->HD44780_rs = GPIOE_9;
|
||||
boardConfiguration->HD44780_e = GPIOE_11;
|
||||
|
@ -303,6 +316,9 @@ void setDefaultConfiguration(engine_configuration_s *engineConfiguration, board_
|
|||
boardConfiguration->HD44780_db6 = GPIOB_11;
|
||||
boardConfiguration->HD44780_db7 = GPIOB_13;
|
||||
|
||||
boardConfiguration->gps_rx_pin = GPIOB_7;
|
||||
boardConfiguration->gps_tx_pin = GPIOB_6;
|
||||
|
||||
memset(boardConfiguration->adcHwChannelEnabled, 0, sizeof(boardConfiguration->adcHwChannelEnabled));
|
||||
boardConfiguration->adcHwChannelEnabled[0] = ADC_SLOW;
|
||||
boardConfiguration->adcHwChannelEnabled[1] = ADC_SLOW;
|
||||
|
@ -316,10 +332,10 @@ void setDefaultConfiguration(engine_configuration_s *engineConfiguration, board_
|
|||
boardConfiguration->adcHwChannelEnabled[12] = ADC_SLOW;
|
||||
boardConfiguration->adcHwChannelEnabled[13] = ADC_SLOW;
|
||||
|
||||
boardConfiguration->primaryTriggerInputPin = GPIOC_6;
|
||||
boardConfiguration->secondaryTriggerInputPin = GPIOA_5;
|
||||
boardConfiguration->primaryLogicAnalyzerPin = GPIOA_8;
|
||||
boardConfiguration->secondaryLogicAnalyzerPin = GPIOE_7;
|
||||
boardConfiguration->triggerInputPins[0] = GPIOC_6;
|
||||
boardConfiguration->triggerInputPins[1] = GPIOA_5;
|
||||
boardConfiguration->logicAnalyzerPins[0] = GPIOA_8;
|
||||
boardConfiguration->logicAnalyzerPins[1] = GPIOE_7;
|
||||
|
||||
boardConfiguration->idleThreadPeriod = 100;
|
||||
boardConfiguration->consoleLoopPeriod = 200;
|
||||
|
@ -342,13 +358,8 @@ void setDefaultConfiguration(engine_configuration_s *engineConfiguration, board_
|
|||
boardConfiguration->digitalPotentiometerChipSelect[3] = GPIO_NONE;
|
||||
}
|
||||
|
||||
void setDefaultNonPersistentConfiguration(engine_configuration2_s *engineConfiguration2) {
|
||||
/**
|
||||
* 720 is the range for four stroke
|
||||
*/
|
||||
// engineConfiguration2->crankAngleRange = 720;
|
||||
|
||||
}
|
||||
//void setDefaultNonPersistentConfiguration(engine_configuration2_s *engineConfiguration2) {
|
||||
//}
|
||||
|
||||
void resetConfigurationExt(Logging * logger, engine_type_e engineType, engine_configuration_s *engineConfiguration,
|
||||
engine_configuration2_s *engineConfiguration2, board_configuration_s *boardConfiguration) {
|
||||
|
@ -381,8 +392,17 @@ void resetConfigurationExt(Logging * logger, engine_type_e engineType, engine_co
|
|||
setNissanPrimeraEngineConfiguration(engineConfiguration);
|
||||
break;
|
||||
#endif
|
||||
case HONDA_ACCORD:
|
||||
setHondaAccordConfiguration(engineConfiguration, boardConfiguration);
|
||||
case HONDA_ACCORD_CD:
|
||||
setHondaAccordConfigurationThreeWires(engineConfiguration, boardConfiguration);
|
||||
break;
|
||||
case HONDA_ACCORD_CD_TWO_WIRES:
|
||||
setHondaAccordConfigurationTwoWires(engineConfiguration, boardConfiguration);
|
||||
break;
|
||||
case HONDA_ACCORD_CD_DIP:
|
||||
setHondaAccordConfigurationDip(engineConfiguration, boardConfiguration);
|
||||
break;
|
||||
case MITSU_4G93:
|
||||
setMitsubishiConfiguration(engineConfiguration, boardConfiguration);
|
||||
break;
|
||||
#if EFI_SUPPORT_1995_FORD_INLINE_6 || defined(__DOXYGEN__)
|
||||
case FORD_INLINE_6_1995:
|
||||
|
@ -435,8 +455,6 @@ void applyNonPersistentConfiguration(Logging * logger, engine_configuration_s *e
|
|||
#if EFI_PROD_CODE
|
||||
scheduleMsg(logger, "applyNonPersistentConfiguration()");
|
||||
#endif
|
||||
engineConfiguration2->isInjectionEnabledFlag = TRUE;
|
||||
|
||||
initializeTriggerShape(logger, engineConfiguration, engineConfiguration2);
|
||||
if (engineConfiguration2->triggerShape.getSize() == 0) {
|
||||
firmwareError("triggerShape size is zero");
|
||||
|
|
|
@ -77,7 +77,7 @@ typedef enum {
|
|||
} can_device_mode_e;
|
||||
|
||||
typedef struct {
|
||||
int afrAdcChannel;
|
||||
adc_channel_e afrAdcChannel;
|
||||
float v1;
|
||||
float value1;
|
||||
float v2;
|
||||
|
@ -143,8 +143,13 @@ typedef struct {
|
|||
brain_pin_e HD44780_db6;
|
||||
brain_pin_e HD44780_db7;
|
||||
|
||||
brain_pin_e triggerSimulatorPins[2];
|
||||
pin_output_mode_e triggerSimulatorPinModes[2];
|
||||
brain_pin_e gps_rx_pin;
|
||||
brain_pin_e gps_tx_pin;
|
||||
|
||||
int idleSolenoidFrequency;
|
||||
|
||||
int unused;
|
||||
|
||||
|
||||
/**
|
||||
* Digital Potentiometer is used by stock ECU stimulation code
|
||||
|
@ -154,10 +159,8 @@ typedef struct {
|
|||
|
||||
adc_channel_mode_e adcHwChannelEnabled[HW_MAX_ADC_INDEX];
|
||||
|
||||
brain_pin_e primaryTriggerInputPin;
|
||||
brain_pin_e secondaryTriggerInputPin;
|
||||
brain_pin_e primaryLogicAnalyzerPin;
|
||||
brain_pin_e secondaryLogicAnalyzerPin;
|
||||
brain_pin_e triggerInputPins[2];
|
||||
brain_pin_e logicAnalyzerPins[2];
|
||||
|
||||
int idleThreadPeriod;
|
||||
int consoleLoopPeriod;
|
||||
|
@ -173,6 +176,15 @@ typedef struct {
|
|||
brain_pin_e canTxPin;
|
||||
brain_pin_e canRxPin;
|
||||
|
||||
brain_pin_e triggerSimulatorPins[3];
|
||||
pin_output_mode_e triggerSimulatorPinModes[3];
|
||||
|
||||
brain_pin_e o2heaterPin;
|
||||
pin_output_mode_e o2heaterPinModeTodO;
|
||||
|
||||
int unused2[8];
|
||||
|
||||
|
||||
} board_configuration_s;
|
||||
|
||||
|
||||
|
@ -207,7 +219,11 @@ typedef struct {
|
|||
float iatFuelCorrBins[IAT_CURVE_SIZE]; // size 64, offset 200
|
||||
float iatFuelCorr[IAT_CURVE_SIZE]; // size 64, offset 264
|
||||
|
||||
short int unused2; // size 2, offset 328
|
||||
/**
|
||||
* Should the trigger emulator push data right into trigger input, eliminating the need for physical jumper wires?
|
||||
* PS: Funny name, right? :)
|
||||
*/
|
||||
short int directSelfStimulation; // size 2, offset 328
|
||||
|
||||
// todo: extract these two fields into a structure
|
||||
// todo: we need two sets of TPS parameters - modern ETBs have to sensors
|
||||
|
@ -265,7 +281,6 @@ typedef struct {
|
|||
injection_mode_e crankingInjectionMode;
|
||||
injection_mode_e injectionMode;
|
||||
|
||||
|
||||
/**
|
||||
* Inside rusEfi all the angles are handled in relation to the trigger synchronization event
|
||||
* which depends on the trigger shape and has nothing to do wit Top Dead Center (TDC)
|
||||
|
@ -329,21 +344,21 @@ typedef struct {
|
|||
int HD44780width;
|
||||
int HD44780height;
|
||||
|
||||
int tpsAdcChannel;
|
||||
adc_channel_e tpsAdcChannel;
|
||||
int overrideCrankingIgnition;
|
||||
int analogChartFrequency;
|
||||
|
||||
trigger_config_s triggerConfig;
|
||||
|
||||
int space;
|
||||
int vBattAdcChannel;
|
||||
adc_channel_e vBattAdcChannel;
|
||||
|
||||
float globalFuelCorrection;
|
||||
|
||||
// todo: merge with channel settings, use full-scale Thermistor!
|
||||
int cltAdcChannel;
|
||||
int iatAdcChannel;
|
||||
int mafAdcChannel;
|
||||
adc_channel_e cltAdcChannel;
|
||||
adc_channel_e iatAdcChannel;
|
||||
adc_channel_e mafAdcChannel;
|
||||
|
||||
afr_sensor_s afrSensor;
|
||||
|
||||
|
@ -367,12 +382,20 @@ typedef struct {
|
|||
float veTable[VE_LOAD_COUNT][VE_RPM_COUNT]; // size 1024
|
||||
float afrTable[AFR_LOAD_COUNT][AFR_RPM_COUNT]; // size 1024
|
||||
|
||||
|
||||
board_configuration_s bc;
|
||||
|
||||
int hasMapSensor;
|
||||
int hasCltSensor;
|
||||
|
||||
idle_mode_e idleMode;
|
||||
|
||||
bool isInjectionEnabled : 1; // bit 0
|
||||
bool isIgnitionEnabled : 1; // bit 1
|
||||
bool isCylinderCleanupEnabled : 1; // bit 2
|
||||
bool secondTriggerChannelEnabled : 1; // bit 3
|
||||
|
||||
|
||||
int unused3[8];
|
||||
|
||||
} engine_configuration_s;
|
||||
|
||||
|
|
|
@ -29,6 +29,7 @@ int warning(obd_code_e code, const char *fmt, ...);
|
|||
*/
|
||||
void firmwareError(const char *fmt, ...);
|
||||
bool hasFirmwareError(void);
|
||||
char *getFirmwareError(void);
|
||||
|
||||
/**
|
||||
* declared as a macro so that this code does not use stack
|
||||
|
@ -43,6 +44,7 @@ bool hasFirmwareError(void);
|
|||
void chDbgPanic3(const char *msg, const char * file, int line);
|
||||
|
||||
void initErrorHandling(void);
|
||||
char *getWarninig(void);
|
||||
|
||||
// todo: better place for this shared declaration?
|
||||
int getRusEfiVersion(void);
|
||||
|
|
|
@ -62,7 +62,7 @@ void ArrayList< Type, Dimention>::resetEventList(void) {
|
|||
|
||||
template <class Type, int Dimention>
|
||||
Type * ArrayList< Type, Dimention>::getNextActuatorEvent(void) {
|
||||
efiAssert(size < Dimention, "registerActuatorEvent() too many events", NULL);
|
||||
efiAssert(size < Dimention, "registerActuatorEvent() too many events", (Type *)NULL);
|
||||
return &events[size++];
|
||||
}
|
||||
|
||||
|
|
|
@ -23,6 +23,7 @@ float getIatCorrection(float iat);
|
|||
float getInjectorLag(float vBatt);
|
||||
float getCltCorrection(float clt);
|
||||
float getRunningFuel(float baseFuel, Engine *engine, int rpm);
|
||||
float getCrankingFuel(void);
|
||||
float getStartingFuel(float coolantTemperature);
|
||||
float getFuelMs(int rpm, Engine *engine);
|
||||
|
||||
|
|
|
@ -78,10 +78,10 @@ int getIdle(IdleValveState *idle, int currentRpm, int now) {
|
|||
}
|
||||
|
||||
if (currentRpm >= idle->targetRpmRangeRight + 100)
|
||||
return changeValue(idle, currentRpm, now, "rpm is too high: ", -IDLE_DECREASE_STEP);
|
||||
return changeValue(idle, currentRpm, now, "idle control: rpm is too high: ", -IDLE_DECREASE_STEP);
|
||||
|
||||
if (currentRpm >= idle->targetRpmRangeRight)
|
||||
return changeValue(idle, currentRpm, now, "rpm is a bit too high: ", -1);
|
||||
return changeValue(idle, currentRpm, now, "idle control: rpm is a bit too high: ", -1);
|
||||
|
||||
// we are here if RPM is low, let's see how low
|
||||
// if (currentRpm < 0.7 * idle->targetRpmRangeLeft) {
|
||||
|
@ -89,7 +89,7 @@ int getIdle(IdleValveState *idle, int currentRpm, int now) {
|
|||
// return setNewValue(idle, currentRpm, now, "RPMs are seriously low: ", 15 * IDLE_INCREASE_STEP);
|
||||
// } else
|
||||
if (currentRpm < idle->targetRpmRangeLeft - 100) {
|
||||
return changeValue(idle, currentRpm, now, "RPMs are low: ", IDLE_INCREASE_STEP);
|
||||
return changeValue(idle, currentRpm, now, "idle control: RPMs are low: ", IDLE_INCREASE_STEP);
|
||||
}
|
||||
return changeValue(idle, currentRpm, now, "RPMs are a bit low: ", 1);
|
||||
return changeValue(idle, currentRpm, now, "idle control: RPMs are a bit low: ", 1);
|
||||
}
|
||||
|
|
|
@ -12,6 +12,9 @@
|
|||
|
||||
#define GPIO_NULL NULL
|
||||
|
||||
/**
|
||||
* Logical pins. See brain_pin_e for physical pins.
|
||||
*/
|
||||
typedef enum {
|
||||
LED_WARNING, // Orange on-board LED
|
||||
LED_RUNNING, // Green on-board LED
|
||||
|
@ -23,9 +26,13 @@ typedef enum {
|
|||
LED_DEBUG,
|
||||
LED_EMULATOR,
|
||||
|
||||
/**
|
||||
* see board_configuration_s->idleValvePin
|
||||
*/
|
||||
IDLE_VALVE,
|
||||
TRIGGER_EMULATOR_PRIMARY,
|
||||
TRIGGER_EMULATOR_SECONDARY,
|
||||
TRIGGER_EMULATOR_3RD,
|
||||
|
||||
SPARKOUT_1_OUTPUT,
|
||||
SPARKOUT_2_OUTPUT,
|
||||
|
@ -57,6 +64,12 @@ typedef enum {
|
|||
ELECTRONIC_THROTTLE_CONTROL_2,
|
||||
ELECTRONIC_THROTTLE_CONTROL_3,
|
||||
|
||||
/**
|
||||
* these seven segment display pins are related to unused external tachometer code
|
||||
* I still have the hardware so maybe one day I will fix it, but for now it's just dead code
|
||||
* See https://www.youtube.com/watch?v=YYiHoN6MBqE
|
||||
* todo: this should be re-implemented in a smarter way with some sort of multiplexing anyway
|
||||
*/
|
||||
/* digit 1 */
|
||||
LED_HUGE_0, // B2
|
||||
LED_HUGE_1,
|
||||
|
@ -87,6 +100,7 @@ typedef enum {
|
|||
|
||||
FUEL_PUMP_RELAY,
|
||||
FAN_RELAY,
|
||||
O2_HEATER,
|
||||
|
||||
SPI_CS_1,
|
||||
SPI_CS_2,
|
||||
|
|
|
@ -46,7 +46,7 @@ typedef enum {
|
|||
NISSAN_PRIMERA = 5,
|
||||
#endif /* EFI_SUPPORT_NISSAN_PRIMERA */
|
||||
|
||||
HONDA_ACCORD = 6,
|
||||
HONDA_ACCORD_CD = 6,
|
||||
|
||||
FORD_INLINE_6_1995 = 7,
|
||||
/**
|
||||
|
@ -70,6 +70,15 @@ typedef enum {
|
|||
|
||||
CITROEN_TU3JP = 15,
|
||||
|
||||
MITSU_4G93 = 16,
|
||||
|
||||
/**
|
||||
* a version of HONDA_ACCORD_CD which only uses two of three trigger input sensors
|
||||
*/
|
||||
HONDA_ACCORD_CD_TWO_WIRES = 17,
|
||||
|
||||
HONDA_ACCORD_CD_DIP = 18,
|
||||
|
||||
Internal_ForceMyEnumIntSize_engine_type = ENUM_SIZE_HACK,
|
||||
} engine_type_e;
|
||||
|
||||
|
@ -85,6 +94,14 @@ typedef enum {
|
|||
TT_TOOTHED_WHEEL_60_2 = 8,
|
||||
TT_TOOTHED_WHEEL_36_1 = 9,
|
||||
|
||||
TT_HONDA_ACCORD_CD = 10,
|
||||
|
||||
TT_MITSU = 11,
|
||||
|
||||
TT_HONDA_ACCORD_CD_TWO_WIRES = 12,
|
||||
|
||||
TT_HONDA_ACCORD_CD_DIP = 13,
|
||||
|
||||
Internal_ForceMyEnumIntSize_trigger_type = ENUM_SIZE_HACK,
|
||||
} trigger_type_e;
|
||||
|
||||
|
@ -96,11 +113,28 @@ typedef enum {
|
|||
Internal_ForceMyEnumIntSize_adc_channel_mode = ENUM_SIZE_HACK,
|
||||
} adc_channel_mode_e;
|
||||
|
||||
// todo: better names?
|
||||
typedef enum {
|
||||
SHAFT_PRIMARY_UP = 0,
|
||||
SHAFT_PRIMARY_DOWN = 1,
|
||||
SHAFT_SECONDARY_UP = 2,
|
||||
SHAFT_SECONDARY_DOWN = 3,
|
||||
TV_LOW = 0,
|
||||
TV_HIGH = 1
|
||||
} trigger_value_e;
|
||||
|
||||
// todo: better names?
|
||||
typedef enum {
|
||||
T_PRIMARY = 0,
|
||||
T_SECONDARY = 1,
|
||||
// todo: I really do not want to call this 'tertiary'. maybe we should rename all of these?
|
||||
T_CHANNEL_3 = 2
|
||||
} trigger_wheel_e;
|
||||
|
||||
// todo: better names?
|
||||
typedef enum {
|
||||
SHAFT_PRIMARY_DOWN = 0,
|
||||
SHAFT_PRIMARY_UP = 1,
|
||||
SHAFT_SECONDARY_DOWN = 2,
|
||||
SHAFT_SECONDARY_UP = 3,
|
||||
SHAFT_3RD_DOWN = 4,
|
||||
SHAFT_3RD_UP = 5,
|
||||
} trigger_event_e;
|
||||
|
||||
/**
|
||||
|
@ -149,6 +183,13 @@ typedef enum {
|
|||
Internal_ForceMyEnumIntSize_log_format = ENUM_SIZE_HACK,
|
||||
} log_format_e;
|
||||
|
||||
|
||||
typedef enum {
|
||||
IM_AUTO = 0,
|
||||
IM_MANUAL = 1,
|
||||
Internal_ForceMyEnumIntSize_idle_mode = ENUM_SIZE_HACK,
|
||||
} idle_mode_e;
|
||||
|
||||
typedef enum {
|
||||
/**
|
||||
* GND for logical OFF, VCC for logical ON
|
||||
|
@ -244,6 +285,29 @@ typedef enum {
|
|||
Internal_ForceMyEnumIntSize_cranking_internal_error = ENUM_SIZE_HACK,
|
||||
} internal_error_e;
|
||||
|
||||
typedef enum {
|
||||
EFI_ADC_0 = 0,
|
||||
EFI_ADC_1 = 1,
|
||||
EFI_ADC_2 = 2,
|
||||
EFI_ADC_3 = 3,
|
||||
EFI_ADC_4 = 4,
|
||||
EFI_ADC_5 = 5,
|
||||
EFI_ADC_6 = 6,
|
||||
EFI_ADC_7 = 7,
|
||||
EFI_ADC_8 = 8,
|
||||
EFI_ADC_9 = 9,
|
||||
EFI_ADC_10 = 10,
|
||||
EFI_ADC_11 = 11,
|
||||
EFI_ADC_12 = 12,
|
||||
EFI_ADC_13 = 13,
|
||||
EFI_ADC_14 = 14,
|
||||
EFI_ADC_15 = 15,
|
||||
|
||||
EFI_ADC_ERROR = 999,
|
||||
|
||||
Internal_ForceMyEnumIntSize_cranking_adc_channel = ENUM_SIZE_HACK,
|
||||
} adc_channel_e;
|
||||
|
||||
/**
|
||||
* Hardware pin. This enum is platform-specific.
|
||||
*/
|
||||
|
@ -334,6 +398,7 @@ typedef enum {
|
|||
GPIOE_15 = 79,
|
||||
|
||||
GPIO_NONE = 80,
|
||||
GPIO_INVALID = 81,
|
||||
|
||||
Internal_ForceMyEnumIntSize_cranking_brain_pin = ENUM_SIZE_HACK,
|
||||
} brain_pin_e;
|
||||
|
|
|
@ -79,7 +79,7 @@ void resetWaveChart(WaveChart *chart) {
|
|||
static char WAVE_LOGGING_BUFFER[WAVE_LOGGING_SIZE] CCM_OPTIONAL
|
||||
;
|
||||
|
||||
int isWaveChartFull(WaveChart *chart) {
|
||||
static int isWaveChartFull(WaveChart *chart) {
|
||||
return chart->counter >= chartSize;
|
||||
}
|
||||
|
||||
|
@ -94,8 +94,9 @@ static void setChartActive(int value) {
|
|||
}
|
||||
|
||||
void setChartSize(int newSize) {
|
||||
if (newSize < 5)
|
||||
if (newSize < 5) {
|
||||
return;
|
||||
}
|
||||
chartSize = newSize;
|
||||
printStatus();
|
||||
}
|
||||
|
@ -114,8 +115,10 @@ void publishChart(WaveChart *chart) {
|
|||
Logging *l = &chart->logging;
|
||||
scheduleSimpleMsg(&debugLogging, "IT'S TIME", strlen(l->buffer));
|
||||
#endif
|
||||
if (isChartActive && getFullLog())
|
||||
bool isFullLog = getFullLog();
|
||||
if (isChartActive && isFullLog) {
|
||||
scheduleLogging(&chart->logging);
|
||||
}
|
||||
}
|
||||
|
||||
static char timeBuffer[10];
|
||||
|
@ -128,8 +131,9 @@ void addWaveChartEvent3(WaveChart *chart, const char *name, const char * msg, co
|
|||
#if DEBUG_WAVE
|
||||
scheduleSimpleMsg(&debugLogging, "current", chart->counter);
|
||||
#endif
|
||||
if (isWaveChartFull(chart))
|
||||
if (isWaveChartFull(chart)) {
|
||||
return;
|
||||
}
|
||||
|
||||
#if EFI_HISTOGRAMS && EFI_PROD_CODE
|
||||
int beforeCallback = hal_lld_get_counter_value();
|
||||
|
@ -140,8 +144,9 @@ void addWaveChartEvent3(WaveChart *chart, const char *name, const char * msg, co
|
|||
|
||||
bool alreadyLocked = lockOutputBuffer(); // we have multiple threads writing to the same output buffer
|
||||
|
||||
if (chart->counter == 0)
|
||||
if (chart->counter == 0) {
|
||||
chart->startTime = time100;
|
||||
}
|
||||
chart->counter++;
|
||||
if (remainingSize(&chart->logging) > 30) {
|
||||
/**
|
||||
|
@ -161,13 +166,15 @@ void addWaveChartEvent3(WaveChart *chart, const char *name, const char * msg, co
|
|||
appendFast(&chart->logging, msg2);
|
||||
appendFast(&chart->logging, CHART_DELIMETER);
|
||||
}
|
||||
if (!alreadyLocked)
|
||||
if (!alreadyLocked) {
|
||||
unlockOutputBuffer();
|
||||
}
|
||||
|
||||
#if EFI_HISTOGRAMS && EFI_PROD_CODE
|
||||
int diff = hal_lld_get_counter_value() - beforeCallback;
|
||||
if (diff > 0)
|
||||
int64_t diff = hal_lld_get_counter_value() - beforeCallback;
|
||||
if (diff > 0) {
|
||||
hsAdd(&waveChartHisto, diff);
|
||||
}
|
||||
#endif /* EFI_HISTOGRAMS */
|
||||
|
||||
}
|
||||
|
@ -181,8 +188,9 @@ void showWaveChartHistogram(void) {
|
|||
void initWaveChart(WaveChart *chart) {
|
||||
initLogging(&logger, "wave info");
|
||||
|
||||
if (!isChartActive)
|
||||
if (!isChartActive) {
|
||||
printMsg(&logger, "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! chart disabled");
|
||||
}
|
||||
|
||||
printStatus();
|
||||
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
#include "main.h"
|
||||
#include "rpm_calculator.h"
|
||||
#include "pwm_generator.h"
|
||||
#include "wave_math.h"
|
||||
#include "alternatorController.h"
|
||||
#include "pin_repository.h"
|
||||
#include "engine_configuration.h"
|
||||
|
|
|
@ -13,4 +13,5 @@ CONTROLLERS_SRC_CPP = $(PROJECT_DIR)/controllers/settings.cpp \
|
|||
controllers/idle_thread.cpp \
|
||||
controllers/PwmTester.cpp \
|
||||
$(PROJECT_DIR)/controllers/alternatorController.cpp \
|
||||
$(PROJECT_DIR)/controllers/lcd_controller.cpp \
|
||||
$(PROJECT_DIR)/controllers/engine_controller.cpp
|
||||
|
|
|
@ -44,7 +44,7 @@ float multi_wave_s::getSwitchTime(int index) const {
|
|||
void checkSwitchTimes2(int size, float *switchTimes) {
|
||||
for (int i = 0; i < size - 1; i++) {
|
||||
if (switchTimes[i] >= switchTimes[i + 1]) {
|
||||
firmwareError("invalid switchTimes");
|
||||
firmwareError("invalid switchTimes @%d: %f/%f", i, switchTimes[i], switchTimes[i + 1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
#include "engine_configuration.h"
|
||||
|
||||
#define PWM_PHASE_MAX_COUNT 250
|
||||
#define PWM_PHASE_MAX_WAVE_PER_PWM 2
|
||||
#define PWM_PHASE_MAX_WAVE_PER_PWM 3
|
||||
|
||||
/**
|
||||
* @brief PWM configuration for the specific output pin
|
||||
|
@ -35,6 +35,10 @@ public:
|
|||
void setSwitchTime(int phaseIndex, float value);
|
||||
void checkSwitchTimes(int size);
|
||||
int getChannelState(int channelIndex, int phaseIndex) const;
|
||||
|
||||
int findAngleMatch(float angle, int size) const;
|
||||
int waveIndertionAngle(float angle, int size) const;
|
||||
|
||||
/**
|
||||
* Number of signal wires
|
||||
*/
|
||||
|
@ -49,5 +53,7 @@ public:
|
|||
};
|
||||
|
||||
void checkSwitchTimes2(int size, float *switchTimes);
|
||||
void configureHondaAccordCD(trigger_shape_s *s, bool with3rdSignal);
|
||||
void configureHondaAccordCDDip(trigger_shape_s *s);
|
||||
|
||||
#endif /* EFI_WAVE_H_ */
|
||||
|
|
|
@ -22,10 +22,9 @@ void avgReset(AvgTable *table) {
|
|||
}
|
||||
|
||||
void avgAddValue(AvgTable *table, int rpm, float key, float value) {
|
||||
if (rpm >= MAX_RPM)
|
||||
return;
|
||||
if (key >= MAX_KEY)
|
||||
if (rpm >= MAX_RPM || key >= MAX_KEY) {
|
||||
return;
|
||||
}
|
||||
int i = (int)(AVG_TAB_SIZE * rpm / MAX_RPM);
|
||||
int j = (int)(AVG_TAB_SIZE * key / MAX_KEY);
|
||||
|
||||
|
@ -35,26 +34,25 @@ void avgAddValue(AvgTable *table, int rpm, float key, float value) {
|
|||
|
||||
float avgGetValueByIndexes(AvgTable *table, int i, int j) {
|
||||
int count = table->counts[i][j];
|
||||
if (count == 0)
|
||||
if (count == 0) {
|
||||
return NAN;
|
||||
}
|
||||
return table->values[i][j] / count;
|
||||
}
|
||||
|
||||
float avgGetValue(AvgTable *table, int rpm, float key) {
|
||||
if (rpm >= MAX_RPM)
|
||||
return NAN;
|
||||
if (key >= MAX_KEY)
|
||||
if (rpm >= MAX_RPM || key >= MAX_KEY) {
|
||||
return NAN;
|
||||
}
|
||||
int i = (int)(AVG_TAB_SIZE * rpm / MAX_RPM);
|
||||
int j = (int)(AVG_TAB_SIZE * key / MAX_KEY);
|
||||
return avgGetValueByIndexes(table, i, j);
|
||||
}
|
||||
|
||||
int avgGetValuesCount(AvgTable *table, int rpm, float key) {
|
||||
if (rpm >= MAX_RPM)
|
||||
return 0;
|
||||
if (key >= MAX_KEY)
|
||||
if (rpm >= MAX_RPM || key >= MAX_KEY) {
|
||||
return 0;
|
||||
}
|
||||
int i = (int)(AVG_TAB_SIZE * rpm / MAX_RPM);
|
||||
int j = (int)(AVG_TAB_SIZE * key / MAX_KEY);
|
||||
|
||||
|
|
|
@ -26,8 +26,9 @@ private:
|
|||
|
||||
template<int RPM_BIN_SIZE, int LOAD_BIN_SIZE>
|
||||
void Map3D<RPM_BIN_SIZE, LOAD_BIN_SIZE>::init(float table[RPM_BIN_SIZE][LOAD_BIN_SIZE]) {
|
||||
for (int k = 0; k < LOAD_BIN_SIZE; k++)
|
||||
for (int k = 0; k < LOAD_BIN_SIZE; k++) {
|
||||
pointers[k] = table[k];
|
||||
}
|
||||
initialized = MAGIC_TRUE_VALUE;
|
||||
}
|
||||
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
#include "main_trigger_callback.h"
|
||||
#include "map_multiplier_thread.h"
|
||||
#include "io_pins.h"
|
||||
#include "flash_main.h"
|
||||
#include "tunerstudio.h"
|
||||
#include "injector_central.h"
|
||||
#include "ignition_central.h"
|
||||
|
@ -54,7 +55,8 @@
|
|||
|
||||
extern board_configuration_s *boardConfiguration;
|
||||
|
||||
persistent_config_container_s persistentState CCM_OPTIONAL;
|
||||
persistent_config_container_s persistentState CCM_OPTIONAL
|
||||
;
|
||||
|
||||
engine_configuration_s *engineConfiguration = &persistentState.persistentConfiguration.engineConfiguration;
|
||||
board_configuration_s *boardConfiguration = &persistentState.persistentConfiguration.engineConfiguration.bc;
|
||||
|
@ -69,10 +71,11 @@ static VirtualTimer fuelPumpTimer;
|
|||
|
||||
static Logging logger;
|
||||
|
||||
static engine_configuration2_s ec2 CCM_OPTIONAL;
|
||||
static engine_configuration2_s ec2 CCM_OPTIONAL
|
||||
;
|
||||
engine_configuration2_s * engineConfiguration2 = &ec2;
|
||||
|
||||
static configuration_s cfg = {&persistentState.persistentConfiguration.engineConfiguration, &ec2};
|
||||
static configuration_s cfg = { &persistentState.persistentConfiguration.engineConfiguration, &ec2 };
|
||||
|
||||
configuration_s * configuration = &cfg;
|
||||
|
||||
|
@ -104,10 +107,8 @@ static void updateErrorCodes(void) {
|
|||
/**
|
||||
* technically we can set error codes right inside the getMethods, but I a bit on a fence about it
|
||||
*/
|
||||
setError(isValidIntakeAirTemperature(getIntakeAirTemperature()),
|
||||
OBD_Intake_Air_Temperature_Circuit_Malfunction);
|
||||
setError(isValidCoolantTemperature(getCoolantTemperature()),
|
||||
OBD_Engine_Coolant_Temperature_Circuit_Malfunction);
|
||||
setError(isValidIntakeAirTemperature(getIntakeAirTemperature()), OBD_Intake_Air_Temperature_Circuit_Malfunction);
|
||||
setError(isValidCoolantTemperature(getCoolantTemperature()), OBD_Engine_Coolant_Temperature_Circuit_Malfunction);
|
||||
}
|
||||
|
||||
static void fanRelayControl(void) {
|
||||
|
@ -118,11 +119,9 @@ static void fanRelayControl(void) {
|
|||
int newValue;
|
||||
if (isCurrentlyOn) {
|
||||
// if the fan is already on, we keep it on till the 'fanOff' temperature
|
||||
newValue = getCoolantTemperature()
|
||||
> engineConfiguration->fanOffTemperature;
|
||||
newValue = getCoolantTemperature() > engineConfiguration->fanOffTemperature;
|
||||
} else {
|
||||
newValue = getCoolantTemperature()
|
||||
> engineConfiguration->fanOnTemperature;
|
||||
newValue = getCoolantTemperature() > engineConfiguration->fanOnTemperature;
|
||||
}
|
||||
|
||||
if (isCurrentlyOn != newValue) {
|
||||
|
@ -156,25 +155,31 @@ static void onEvenyGeneralMilliseconds(void *arg) {
|
|||
*/
|
||||
halTime.get(hal_lld_get_counter_value(), true);
|
||||
|
||||
if (!engine.rpmCalculator->isRunning())
|
||||
writeToFlashIfPending();
|
||||
|
||||
engine.updateSlowSensors();
|
||||
|
||||
updateErrorCodes();
|
||||
|
||||
fanRelayControl();
|
||||
|
||||
setOutputPinValue(O2_HEATER, engine.rpmCalculator->isRunning());
|
||||
|
||||
// schedule next invocation
|
||||
chVTSetAny(&everyMsTimer, boardConfiguration->generalPeriodicThreadPeriod * TICKS_IN_MS, &onEvenyGeneralMilliseconds, 0);
|
||||
chVTSetAny(&everyMsTimer, boardConfiguration->generalPeriodicThreadPeriod * TICKS_IN_MS,
|
||||
&onEvenyGeneralMilliseconds, 0);
|
||||
}
|
||||
|
||||
static void initPeriodicEvents(void) {
|
||||
// schedule first invocation
|
||||
chVTSetAny(&everyMsTimer, boardConfiguration->generalPeriodicThreadPeriod * TICKS_IN_MS, &onEvenyGeneralMilliseconds, 0);
|
||||
chVTSetAny(&everyMsTimer, boardConfiguration->generalPeriodicThreadPeriod * TICKS_IN_MS,
|
||||
&onEvenyGeneralMilliseconds, 0);
|
||||
}
|
||||
|
||||
static void fuelPumpOff(void *arg) {
|
||||
if (getOutputPinValue(FUEL_PUMP_RELAY))
|
||||
scheduleMsg(&logger, "fuelPump OFF at %s%d",
|
||||
hwPortname(boardConfiguration->fuelPumpPin));
|
||||
scheduleMsg(&logger, "fuelPump OFF at %s%d", hwPortname(boardConfiguration->fuelPumpPin));
|
||||
turnOutputPinOff(FUEL_PUMP_RELAY);
|
||||
}
|
||||
|
||||
|
@ -182,10 +187,8 @@ static void fuelPumpOn(trigger_event_e signal, int index, void *arg) {
|
|||
if (index != 0)
|
||||
return; // let's not abuse the timer - one time per revolution would be enough
|
||||
// todo: the check about GPIO_NONE should be somewhere else!
|
||||
if (!getOutputPinValue(FUEL_PUMP_RELAY)
|
||||
&& boardConfiguration->fuelPumpPin != GPIO_NONE)
|
||||
scheduleMsg(&logger, "fuelPump ON at %s",
|
||||
hwPortname(boardConfiguration->fuelPumpPin));
|
||||
if (!getOutputPinValue(FUEL_PUMP_RELAY) && boardConfiguration->fuelPumpPin != GPIO_NONE)
|
||||
scheduleMsg(&logger, "fuelPump ON at %s", hwPortname(boardConfiguration->fuelPumpPin));
|
||||
turnOutputPinOn(FUEL_PUMP_RELAY);
|
||||
/**
|
||||
* the idea of this implementation is that we turn the pump when the ECU turns on or
|
||||
|
@ -200,7 +203,7 @@ static void initFuelPump(void) {
|
|||
fuelPumpOn(SHAFT_PRIMARY_UP, 0, NULL);
|
||||
}
|
||||
|
||||
char * getPinNameByAdcChannel(int hwChannel, char *buffer) {
|
||||
char * getPinNameByAdcChannel(adc_channel_e hwChannel, char *buffer) {
|
||||
strcpy((char*) buffer, portname(getAdcChannelPort(hwChannel)));
|
||||
itoa10(&buffer[2], getAdcChannelPin(hwChannel));
|
||||
return (char*) buffer;
|
||||
|
@ -208,14 +211,14 @@ char * getPinNameByAdcChannel(int hwChannel, char *buffer) {
|
|||
|
||||
static char pinNameBuffer[16];
|
||||
|
||||
static void printAnalogChannelInfoExt(const char *name, int hwChannel,
|
||||
float adcVoltage) {
|
||||
static void printAnalogChannelInfoExt(const char *name, adc_channel_e hwChannel, float adcVoltage) {
|
||||
float voltage = adcVoltage * engineConfiguration->analogInputDividerCoefficient;
|
||||
scheduleMsg(&logger, "%s ADC%d %s rawValue=%f/divided=%fv", name, hwChannel,
|
||||
scheduleMsg(&logger, "%s ADC%d %s %s rawValue=%f/divided=%fv", name, hwChannel,
|
||||
getAdcMode(hwChannel),
|
||||
getPinNameByAdcChannel(hwChannel, pinNameBuffer), adcVoltage, voltage);
|
||||
}
|
||||
|
||||
static void printAnalogChannelInfo(const char *name, int hwChannel) {
|
||||
static void printAnalogChannelInfo(const char *name, adc_channel_e hwChannel) {
|
||||
printAnalogChannelInfoExt(name, hwChannel, getVoltage(hwChannel));
|
||||
}
|
||||
|
||||
|
@ -227,11 +230,10 @@ static void printAnalogInfo(void) {
|
|||
printAnalogChannelInfo("AFR", engineConfiguration->afrSensor.afrAdcChannel);
|
||||
printAnalogChannelInfo("MAP", engineConfiguration->map.sensor.hwChannel);
|
||||
printAnalogChannelInfo("BARO", engineConfiguration->baroSensor.hwChannel);
|
||||
printAnalogChannelInfoExt("Vbatt", engineConfiguration->vBattAdcChannel,
|
||||
getVBatt());
|
||||
printAnalogChannelInfoExt("Vbatt", engineConfiguration->vBattAdcChannel, getVBatt());
|
||||
}
|
||||
|
||||
static THD_WORKING_AREA(csThreadStack, UTILITY_THREAD_STACK_SIZE);// declare thread stack
|
||||
static THD_WORKING_AREA(csThreadStack, UTILITY_THREAD_STACK_SIZE); // declare thread stack
|
||||
|
||||
void initEngineContoller(void) {
|
||||
if (hasFirmwareError())
|
||||
|
@ -269,8 +271,7 @@ void initEngineContoller(void) {
|
|||
// multiple issues with this initMapAdjusterThread();
|
||||
initPeriodicEvents();
|
||||
|
||||
chThdCreateStatic(csThreadStack, sizeof(csThreadStack), LOWPRIO,
|
||||
(tfunc_t) csThread, NULL);
|
||||
chThdCreateStatic(csThreadStack, sizeof(csThreadStack), LOWPRIO, (tfunc_t) csThread, NULL);
|
||||
|
||||
initInjectorCentral();
|
||||
initPwmTester();
|
||||
|
@ -306,6 +307,5 @@ void initEngineContoller(void) {
|
|||
initFuelPump();
|
||||
#endif
|
||||
|
||||
|
||||
addConsoleAction("analoginfo", printAnalogInfo);
|
||||
}
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
#include "signal_executor.h"
|
||||
#include "engine_configuration.h"
|
||||
|
||||
char * getPinNameByAdcChannel(int hwChannel, char *buffer);
|
||||
char * getPinNameByAdcChannel(adc_channel_e hwChannel, char *buffer);
|
||||
void initEngineContoller(void);
|
||||
|
||||
#endif /* ENGINE_STATUS_H_ */
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include "main.h"
|
||||
#include "error_handling.h"
|
||||
#include "io_pins.h"
|
||||
#include "memstreams.h"
|
||||
|
||||
#if EFI_HD44780_LCD
|
||||
#include "lcd_HD44780.h"
|
||||
|
@ -16,6 +17,8 @@
|
|||
static time_t timeOfPreviousWarning = -10;
|
||||
static Logging logger;
|
||||
|
||||
#define WARNING_PREFIX "WARNING: "
|
||||
|
||||
extern int warningEnabled;
|
||||
extern int main_loop_started;
|
||||
|
||||
|
@ -45,6 +48,10 @@ void chDbgPanic3(const char *msg, const char * file, int line) {
|
|||
}
|
||||
}
|
||||
|
||||
#define WARNING_BUFFER_SIZE 80
|
||||
static char warningBuffer[WARNING_BUFFER_SIZE];
|
||||
static MemoryStream warningStream;
|
||||
|
||||
/**
|
||||
* @returns TRUE in case there are too many warnings
|
||||
*/
|
||||
|
@ -56,16 +63,27 @@ int warning(obd_code_e code, const char *fmt, ...) {
|
|||
|
||||
resetLogging(&logger); // todo: is 'reset' really needed here?
|
||||
appendMsgPrefix(&logger);
|
||||
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
vappendPrintf(&logger, fmt, ap);
|
||||
append(&logger, WARNING_PREFIX);
|
||||
warningStream.eos = 0; // reset
|
||||
chvprintf((BaseSequentialStream *) &warningStream, fmt, ap);
|
||||
warningStream.buffer[warningStream.eos] = 0;
|
||||
va_end(ap);
|
||||
|
||||
append(&logger, warningBuffer);
|
||||
append(&logger, DELIMETER);
|
||||
scheduleLogging(&logger);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
char *getWarninig(void) {
|
||||
return warningBuffer;
|
||||
}
|
||||
|
||||
void initErrorHandling(void) {
|
||||
initLogging(&logger, "error handling");
|
||||
msObjectInit(&warningStream, (uint8_t *)warningBuffer, WARNING_BUFFER_SIZE, 0);
|
||||
}
|
||||
|
|
|
@ -19,20 +19,12 @@
|
|||
|
||||
#include "datalogging.h"
|
||||
|
||||
#include "audi_aan.h"
|
||||
#include "dodge_neon.h"
|
||||
#include "ford_aspire.h"
|
||||
#include "ford_fiesta.h"
|
||||
#include "ford_1995_inline_6.h"
|
||||
#include "snow_blower.h"
|
||||
#include "nissan_primera.h"
|
||||
#include "honda_accord.h"
|
||||
#include "GY6_139QMB.h"
|
||||
|
||||
#include "ec2.h"
|
||||
|
||||
static engine_type_e defaultEngineType = FORD_ASPIRE_1996;
|
||||
|
||||
static bool needToWriteConfiguration = false;
|
||||
|
||||
static Logging logger;
|
||||
|
||||
extern persistent_config_container_s persistentState;
|
||||
|
@ -50,6 +42,24 @@ crc_t flashStateCrc(persistent_config_container_s *state) {
|
|||
return calc_crc((const crc_t*) &state->persistentConfiguration, sizeof(persistent_config_s));
|
||||
}
|
||||
|
||||
void setNeedToWriteConfiguration(void) {
|
||||
scheduleMsg(&logger, "Scheduling configuration write");
|
||||
needToWriteConfiguration = true;
|
||||
}
|
||||
|
||||
bool getNeedToWriteConfiguration(void) {
|
||||
return needToWriteConfiguration;
|
||||
}
|
||||
|
||||
void writeToFlashIfPending() {
|
||||
if(!getNeedToWriteConfiguration())
|
||||
return;
|
||||
// todo: technically we need a lock here, realistically we should be fine.
|
||||
needToWriteConfiguration = false;
|
||||
scheduleMsg(&logger, "Writing pending configuration");
|
||||
writeToFlash();
|
||||
}
|
||||
|
||||
void writeToFlash(void) {
|
||||
#if EFI_INTERNAL_FLASH
|
||||
persistentState.size = PERSISTENT_SIZE;
|
||||
|
@ -89,7 +99,7 @@ void readFromFlash(void) {
|
|||
|
||||
flashRead(FLASH_ADDR, (char *) &persistentState, PERSISTENT_SIZE);
|
||||
|
||||
setDefaultNonPersistentConfiguration(engineConfiguration2);
|
||||
//setDefaultNonPersistentConfiguration(engineConfiguration2);
|
||||
|
||||
if (!isValidCrc(&persistentState) || persistentState.size != PERSISTENT_SIZE) {
|
||||
printMsg(&logger, "Need to reset flash to default");
|
||||
|
@ -104,7 +114,6 @@ void readFromFlash(void) {
|
|||
}
|
||||
|
||||
void initFlash(void) {
|
||||
print("initFlash()\r\n");
|
||||
initLogging(&logger, "Flash memory");
|
||||
|
||||
addConsoleAction("readconfig", readFromFlash);
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
|
||||
#include "engine_configuration.h"
|
||||
|
||||
#define FLASH_DATA_VERSION 3975
|
||||
#define FLASH_DATA_VERSION 4320
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
|
@ -20,7 +20,19 @@ extern "C"
|
|||
|
||||
void readFromFlash(void);
|
||||
void initFlash(void);
|
||||
/**
|
||||
* Because of hardware-related issues, stm32f4 chip is totally
|
||||
* frozen while we are writing to internal flash. Writing the configuration takes
|
||||
* about 1-2 seconds, we cannot afford to do that while the engine is
|
||||
* running so we postpone the write until the engine is stopped.
|
||||
*/
|
||||
void writeToFlash(void);
|
||||
void setNeedToWriteConfiguration(void);
|
||||
/**
|
||||
* @return true if an flash write is pending
|
||||
*/
|
||||
bool getNeedToWriteConfiguration(void);
|
||||
void writeToFlashIfPending(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -27,18 +27,15 @@
|
|||
#include "idle_controller.h"
|
||||
#include "rpm_calculator.h"
|
||||
#include "pwm_generator.h"
|
||||
#include "wave_math.h"
|
||||
#include "idle_thread.h"
|
||||
#include "pin_repository.h"
|
||||
#include "engine_configuration.h"
|
||||
#include "engine.h"
|
||||
|
||||
#define IDLE_AIR_CONTROL_VALVE_PWM_FREQUENCY 200
|
||||
|
||||
static THD_WORKING_AREA(ivThreadStack, UTILITY_THREAD_STACK_SIZE);
|
||||
|
||||
static volatile int isIdleControlActive = EFI_IDLE_CONTROL;
|
||||
extern board_configuration_s *boardConfiguration;
|
||||
extern engine_configuration_s *engineConfiguration;
|
||||
|
||||
/**
|
||||
* here we keep the value we got from IDLE SWITCH input
|
||||
|
@ -48,7 +45,7 @@ static volatile int idleSwitchState;
|
|||
static Logging logger;
|
||||
extern Engine engine;
|
||||
|
||||
static SimplePwm idleValve;
|
||||
static SimplePwm idleValvePwm;
|
||||
|
||||
/**
|
||||
* Idle level calculation algorithm lives in idle_controller.c
|
||||
|
@ -65,20 +62,21 @@ void idleDebug(char *msg, int value) {
|
|||
}
|
||||
|
||||
static void setIdleControlEnabled(int value) {
|
||||
isIdleControlActive = value;
|
||||
scheduleMsg(&logger, "isIdleControlActive=%d", isIdleControlActive);
|
||||
engineConfiguration->idleMode = value ? IM_MANUAL : IM_AUTO;
|
||||
scheduleMsg(&logger, "isIdleControlActive=%d", engineConfiguration->idleMode);
|
||||
}
|
||||
|
||||
static void setIdleValvePwm(int value) {
|
||||
// todo: change parameter type, maybe change parameter validation?
|
||||
if (value < 1 || value > 999)
|
||||
return;
|
||||
scheduleMsg(&logger, "setting idle valve PWM %d", value);
|
||||
scheduleMsg(&logger, "setting idle valve PWM %d @%d on %s", value, boardConfiguration->idleSolenoidFrequency,
|
||||
hwPortname(boardConfiguration->idleValvePin));
|
||||
/**
|
||||
* currently idle level is an integer per mil (0-1000 range), and PWM takes a float in the 0..1 range
|
||||
* todo: unify?
|
||||
*/
|
||||
idleValve.setSimplePwmDutyCycle(0.001 * value);
|
||||
idleValvePwm.setSimplePwmDutyCycle(0.001 * value);
|
||||
}
|
||||
|
||||
static msg_t ivThread(int param) {
|
||||
|
@ -91,7 +89,7 @@ static msg_t ivThread(int param) {
|
|||
// this value is not used yet
|
||||
idleSwitchState = palReadPad(getHwPort(boardConfiguration->idleSwitchPin), getHwPin(boardConfiguration->idleSwitchPin));
|
||||
|
||||
if (!isIdleControlActive)
|
||||
if (engineConfiguration->idleMode != IM_AUTO)
|
||||
continue;
|
||||
|
||||
int nowSec = getTimeNowSeconds();
|
||||
|
@ -117,10 +115,13 @@ static void setIdleRpmAction(int value) {
|
|||
void startIdleThread() {
|
||||
initLogging(&logger, "Idle Valve Control");
|
||||
|
||||
startSimplePwmExt(&idleValve, "Idle Valve",
|
||||
/**
|
||||
* Start PWM for IDLE_VALVE logical / idleValvePin physical
|
||||
*/
|
||||
startSimplePwmExt(&idleValvePwm, "Idle Valve",
|
||||
boardConfiguration->idleValvePin,
|
||||
IDLE_VALVE,
|
||||
IDLE_AIR_CONTROL_VALVE_PWM_FREQUENCY,
|
||||
boardConfiguration->idleSolenoidFrequency,
|
||||
0.5);
|
||||
|
||||
idleInit(&idle);
|
||||
|
|
|
@ -32,7 +32,6 @@
|
|||
static Logging logger;
|
||||
|
||||
extern engine_configuration_s *engineConfiguration;
|
||||
extern engine_configuration2_s *engineConfiguration2;
|
||||
extern board_configuration_s *boardConfiguration;
|
||||
|
||||
static int is_injector_enabled[MAX_INJECTOR_COUNT];
|
||||
|
@ -76,46 +75,83 @@ static void setInjectorEnabled(int id, int value) {
|
|||
printStatus();
|
||||
}
|
||||
|
||||
void runBench(brain_pin_e brainPin, io_pin_e pin, float onTime, float offTime, int count) {
|
||||
scheduleMsg(&logger, "Running bench: ON_TIME=%f ms OFF_TIME=%fms Counter=%d", onTime, offTime, count);
|
||||
static void runBench(brain_pin_e brainPin, io_pin_e pin, float delayMs, float onTimeMs, float offTimeMs, int count) {
|
||||
scheduleMsg(&logger, "Running bench: ON_TIME=%f ms OFF_TIME=%fms Counter=%d", onTimeMs, offTimeMs, count);
|
||||
scheduleMsg(&logger, "output on %s", hwPortname(brainPin));
|
||||
|
||||
int delaySt = (int) (delayMs * CH_FREQUENCY / 1000);
|
||||
if (delaySt != 0) {
|
||||
chThdSleep(delaySt);
|
||||
}
|
||||
|
||||
for (int i = 0; i < count; i++) {
|
||||
setOutputPinValue(pin, TRUE);
|
||||
chThdSleep((int) (onTime * CH_FREQUENCY / 1000));
|
||||
chThdSleep((int) (onTimeMs * CH_FREQUENCY / 1000));
|
||||
setOutputPinValue(pin, FALSE);
|
||||
chThdSleep((int) (offTime * CH_FREQUENCY / 1000));
|
||||
int offTimeSt = (int) (offTimeMs * CH_FREQUENCY / 1000);
|
||||
if (offTimeSt > 0) {
|
||||
chThdSleep(offTimeSt);
|
||||
}
|
||||
}
|
||||
scheduleMsg(&logger, "Done!");
|
||||
}
|
||||
|
||||
static volatile int needToRunBench = FALSE;
|
||||
float onTime;
|
||||
float offTime;
|
||||
int count;
|
||||
brain_pin_e brainPin;
|
||||
io_pin_e pin;
|
||||
static float onTime;
|
||||
static float offTime;
|
||||
static float delayMs;
|
||||
static int count;
|
||||
static brain_pin_e brainPin;
|
||||
static io_pin_e pin;
|
||||
|
||||
static void fuelbench(char * onStr, char *offStr, char *countStr) {
|
||||
onTime = atoff(onStr);
|
||||
offTime = atoff(offStr);
|
||||
static void pinbench(const char *delayStr, const char *onTimeStr, const char *offTimeStr, const char *countStr,
|
||||
io_pin_e pinParam, brain_pin_e brainPinParam) {
|
||||
delayMs = atoff(delayStr);
|
||||
onTime = atoff(onTimeStr);
|
||||
offTime = atoff(offTimeStr);
|
||||
count = atoi(countStr);
|
||||
|
||||
brainPin = boardConfiguration->injectionPins[0];
|
||||
pin = INJECTOR_1_OUTPUT;
|
||||
brainPin = brainPinParam;
|
||||
pin = pinParam;
|
||||
needToRunBench = TRUE;
|
||||
}
|
||||
|
||||
static void sparkbench(char * onStr, char *offStr, char *countStr) {
|
||||
onTime = atoff(onStr);
|
||||
offTime = atoff(offStr);
|
||||
count = atoi(countStr);
|
||||
static void fuelbench2(const char *delayStr, const char *indexStr, const char * onTimeStr, const char *offTimeStr,
|
||||
const char *countStr) {
|
||||
int index = atoi(indexStr);
|
||||
brain_pin_e b = boardConfiguration->injectionPins[index - 1];
|
||||
io_pin_e p = (io_pin_e) ((int) INJECTOR_1_OUTPUT - 1 + index);
|
||||
pinbench(delayStr, onTimeStr, offTimeStr, countStr, p, b);
|
||||
}
|
||||
|
||||
static void fuelpumpbench(int delayParam, int onTimeParam) {
|
||||
brainPin = boardConfiguration->fuelPumpPin;
|
||||
pin = FUEL_PUMP_RELAY;
|
||||
|
||||
delayMs = delayParam;
|
||||
onTime = onTimeParam;
|
||||
offTime = 0;
|
||||
count = 1;
|
||||
|
||||
brainPin = boardConfiguration->ignitionPins[0];
|
||||
pin = SPARKOUT_1_OUTPUT;
|
||||
needToRunBench = TRUE;
|
||||
}
|
||||
|
||||
static void fuelbench(const char * onTimeStr, const char *offTimeStr, const char *countStr) {
|
||||
fuelbench2("0", "1", onTimeStr, offTimeStr, countStr);
|
||||
}
|
||||
|
||||
static void sparkbench2(const char *delayStr, const char *indexStr, const char * onTimeStr, const char *offTimeStr,
|
||||
const char *countStr) {
|
||||
int index = atoi(indexStr);
|
||||
brain_pin_e b = boardConfiguration->ignitionPins[index - 1];
|
||||
io_pin_e p = (io_pin_e) ((int) SPARKOUT_1_OUTPUT - 1 + index);
|
||||
pinbench(delayStr, onTimeStr, offTimeStr, countStr, p, b);
|
||||
}
|
||||
|
||||
static void sparkbench(const char * onTimeStr, const char *offTimeStr, const char *countStr) {
|
||||
sparkbench2("0", "1", onTimeStr, offTimeStr, countStr);
|
||||
}
|
||||
|
||||
static THD_WORKING_AREA(benchThreadStack, UTILITY_THREAD_STACK_SIZE);
|
||||
|
||||
static msg_t benchThread(int param) {
|
||||
|
@ -126,7 +162,7 @@ static msg_t benchThread(int param) {
|
|||
chThdSleepMilliseconds(200);
|
||||
}
|
||||
needToRunBench = FALSE;
|
||||
runBench(brainPin, pin, onTime, offTime, count);
|
||||
runBench(brainPin, pin, delayMs, onTime, offTime, count);
|
||||
}
|
||||
#if defined __GNUC__
|
||||
return 0;
|
||||
|
@ -142,15 +178,20 @@ void initInjectorCentral(void) {
|
|||
|
||||
// todo: should we move this code closer to the injection logic?
|
||||
for (int i = 0; i < engineConfiguration->cylindersCount; i++) {
|
||||
io_pin_e pin = (io_pin_e)((int)INJECTOR_1_OUTPUT + i);
|
||||
io_pin_e pin = (io_pin_e) ((int) INJECTOR_1_OUTPUT + i);
|
||||
|
||||
outputPinRegisterExt2(getPinName(pin), pin,
|
||||
boardConfiguration->injectionPins[i], &boardConfiguration->injectionPinMode);
|
||||
outputPinRegisterExt2(getPinName(pin), pin, boardConfiguration->injectionPins[i],
|
||||
&boardConfiguration->injectionPinMode);
|
||||
}
|
||||
|
||||
printStatus();
|
||||
addConsoleActionII("injector", setInjectorEnabled);
|
||||
|
||||
addConsoleActionII("fuelpumpbench", &fuelpumpbench);
|
||||
|
||||
addConsoleActionSSS("fuelbench", &fuelbench);
|
||||
addConsoleActionSSS("sparkbench", &sparkbench);
|
||||
|
||||
addConsoleActionSSSSS("fuelbench2", &fuelbench2);
|
||||
addConsoleActionSSSSS("sparkbench2", &sparkbench2);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,193 @@
|
|||
/**
|
||||
* @file lcd_controller.cpp
|
||||
*
|
||||
* @date Aug 14, 2014
|
||||
* @author Andrey Belomutskiy, (c) 2012-2014
|
||||
*/
|
||||
|
||||
#include "main.h"
|
||||
#include "lcd_controller.h"
|
||||
#include "lcd_HD44780.h"
|
||||
#include "efilib.h"
|
||||
#include "rpm_calculator.h"
|
||||
#include "allsensors.h"
|
||||
#include "engine.h"
|
||||
#include "rtc_helper.h"
|
||||
#include "io_pins.h"
|
||||
|
||||
extern Engine engine;
|
||||
extern engine_configuration_s *engineConfiguration;
|
||||
|
||||
#define LCD_WIDTH 20
|
||||
// this value should be even
|
||||
#define NUMBER_OF_DIFFERENT_LINES 4
|
||||
|
||||
char * appendStr(char *ptr, const char *suffix) {
|
||||
for (uint32_t i = 0; i < strlen(suffix); i++) {
|
||||
*ptr++ = suffix[i];
|
||||
}
|
||||
return ptr;
|
||||
}
|
||||
|
||||
static char * prepareVBattMapLine(char *buffer) {
|
||||
char *ptr = buffer;
|
||||
*ptr++ = 'V';
|
||||
ptr = ftoa(ptr, getVBatt(), 10.0f);
|
||||
|
||||
ptr = appendStr(ptr, " M");
|
||||
ptr = ftoa(ptr, getRawMap(), 10.0f);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
static char * prepareCltIatTpsLine(char *buffer) {
|
||||
char *ptr = buffer;
|
||||
*ptr++ = 'C';
|
||||
ptr = ftoa(ptr, getCoolantTemperature(), 10.0f);
|
||||
|
||||
ptr = appendStr(ptr, " C");
|
||||
ptr = ftoa(ptr, getIntakeAirTemperature(), 10.0f);
|
||||
|
||||
ptr = appendStr(ptr, " TP");
|
||||
ptr = itoa10(ptr, (int) getTPS());
|
||||
return ptr;
|
||||
}
|
||||
|
||||
static const char* algorithmStr[] = { "MAF", "TPS", "MAP", "SD" };
|
||||
static const char* ignitionModeStr[] = { "1C", "IND", "WS" };
|
||||
static const char* injectionModeStr[] = { "Sim", "Seq", "Bch" };
|
||||
static const char* idleModeStr[] = { "I:A", "I:M" };
|
||||
|
||||
static const char *getPinShortName(io_pin_e pin) {
|
||||
switch (pin) {
|
||||
case ALTERNATOR_SWITCH:
|
||||
return "AL";
|
||||
case FUEL_PUMP_RELAY:
|
||||
return "FP";
|
||||
case FAN_RELAY:
|
||||
return "FN";
|
||||
case O2_HEATER:
|
||||
return "O2H";
|
||||
default:
|
||||
firmwareError("No short name for %d", (int) pin);
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
char * appendPinStatus(char *buffer, io_pin_e pin) {
|
||||
char *ptr = appendStr(buffer, getPinShortName(pin));
|
||||
int state = getOutputPinValue(pin);
|
||||
// todo: should we handle INITIAL_PIN_STATE?
|
||||
if (state) {
|
||||
return appendStr(ptr, ":Y ");
|
||||
} else {
|
||||
return appendStr(ptr, ":n ");
|
||||
}
|
||||
}
|
||||
|
||||
static char * prepareInfoLine(char *buffer) {
|
||||
char *ptr = buffer;
|
||||
|
||||
ptr = appendStr(ptr, algorithmStr[engineConfiguration->algorithm]);
|
||||
|
||||
ptr = appendStr(ptr, " ");
|
||||
ptr = appendStr(ptr, ignitionModeStr[engineConfiguration->ignitionMode]);
|
||||
|
||||
ptr = appendStr(ptr, " ");
|
||||
ptr = appendStr(ptr, injectionModeStr[engineConfiguration->injectionMode]);
|
||||
|
||||
ptr = appendStr(ptr, " ");
|
||||
ptr = appendStr(ptr, idleModeStr[engineConfiguration->idleMode]);
|
||||
|
||||
ptr = appendStr(ptr, " ");
|
||||
return ptr;
|
||||
}
|
||||
|
||||
static char * prepareStatusLine(char *buffer) {
|
||||
char *ptr = buffer;
|
||||
|
||||
ptr = appendPinStatus(ptr, FUEL_PUMP_RELAY);
|
||||
ptr = appendPinStatus(ptr, FAN_RELAY);
|
||||
ptr = appendPinStatus(ptr, O2_HEATER);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
static char buffer[LCD_WIDTH + 4];
|
||||
static char dateBuffer[30];
|
||||
|
||||
static void prepareCurrentSecondLine(int index) {
|
||||
memset(buffer, ' ', LCD_WIDTH);
|
||||
char *ptr;
|
||||
switch (index) {
|
||||
case 0:
|
||||
ptr = prepareCltIatTpsLine(buffer);
|
||||
break;
|
||||
case 1:
|
||||
ptr = prepareInfoLine(buffer);
|
||||
break;
|
||||
case 2:
|
||||
ptr = prepareVBattMapLine(buffer);
|
||||
break;
|
||||
case 3:
|
||||
ptr = prepareStatusLine(buffer);
|
||||
break;
|
||||
}
|
||||
*ptr = ' ';
|
||||
}
|
||||
|
||||
void updateHD44780lcd(void) {
|
||||
|
||||
lcd_HD44780_set_position(0, 9);
|
||||
/**
|
||||
* this would blink so that we know the LCD is alive
|
||||
*/
|
||||
if (getTimeNowSeconds() % 2 == 0) {
|
||||
lcd_HD44780_print_char('R');
|
||||
} else {
|
||||
lcd_HD44780_print_char(' ');
|
||||
}
|
||||
lcd_HD44780_set_position(0, 10);
|
||||
|
||||
char * ptr = itoa10(buffer, getRpm());
|
||||
ptr[0] = 0;
|
||||
int len = ptr - buffer;
|
||||
for (int i = 0; i < 6 - len; i++) {
|
||||
lcd_HD44780_print_char(' ');
|
||||
}
|
||||
lcd_HD44780_print_string(buffer);
|
||||
|
||||
if (hasFirmwareError()) {
|
||||
memcpy(buffer, getFirmwareError(), LCD_WIDTH);
|
||||
buffer[LCD_WIDTH] = 0;
|
||||
lcd_HD44780_set_position(1, 0);
|
||||
lcd_HD44780_print_string(buffer);
|
||||
return;
|
||||
}
|
||||
|
||||
lcd_HD44780_set_position(1, 0);
|
||||
memset(buffer, ' ', LCD_WIDTH);
|
||||
memcpy(buffer, getWarninig(), LCD_WIDTH);
|
||||
buffer[LCD_WIDTH] = 0;
|
||||
lcd_HD44780_print_string(buffer);
|
||||
|
||||
if (engineConfiguration->HD44780height < 3) {
|
||||
return;
|
||||
}
|
||||
|
||||
int index = (getTimeNowSeconds() / 2) % (NUMBER_OF_DIFFERENT_LINES / 2);
|
||||
|
||||
prepareCurrentSecondLine(index);
|
||||
buffer[LCD_WIDTH] = 0;
|
||||
lcd_HD44780_set_position(2, 0);
|
||||
lcd_HD44780_print_string(buffer);
|
||||
|
||||
prepareCurrentSecondLine(index + NUMBER_OF_DIFFERENT_LINES / 2);
|
||||
buffer[LCD_WIDTH] = 0;
|
||||
lcd_HD44780_set_position(3, 0);
|
||||
lcd_HD44780_print_string(buffer);
|
||||
|
||||
#if EFI_PROD_CODE
|
||||
dateToString(dateBuffer);
|
||||
lcd_HD44780_set_position(1, 0);
|
||||
lcd_HD44780_print_string(dateBuffer);
|
||||
#endif /* EFI_PROD_CODE */
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
/**
|
||||
* @file lcd_controller.h
|
||||
*
|
||||
* @date Aug 14, 2014
|
||||
* @author Andrey Belomutskiy, (c) 2012-2014
|
||||
*/
|
||||
|
||||
#ifndef LCD_CONTROLLER_H_
|
||||
#define LCD_CONTROLLER_H_
|
||||
|
||||
void updateHD44780lcd(void);
|
||||
|
||||
#endif /* LCD_CONTROLLER_H_ */
|
|
@ -22,7 +22,7 @@
|
|||
|
||||
#include "map.h"
|
||||
|
||||
#if EFI_MAP_AVERAGING
|
||||
#if EFI_MAP_AVERAGING || defined(__DOXYGEN__)
|
||||
|
||||
#include "map_averaging.h"
|
||||
#include "trigger_central.h"
|
||||
|
|
|
@ -13,7 +13,6 @@
|
|||
#include "map_adjuster.h"
|
||||
#include "rpm_calculator.h"
|
||||
#include "main_trigger_callback.h"
|
||||
#include "wave_math.h"
|
||||
#include "allsensors.h"
|
||||
#include "engine_math.h"
|
||||
#include "engine.h"
|
||||
|
|
|
@ -188,6 +188,21 @@ static void registerInjectionEvent(engine_configuration_s const *e,
|
|||
|
||||
}
|
||||
|
||||
float getFuelMultiplier(engine_configuration_s const *e, injection_mode_e mode) {
|
||||
switch(mode) {
|
||||
case IM_SEQUENTIAL:
|
||||
return 1;
|
||||
case IM_SIMULTANEOUS:
|
||||
// todo: pre-calculate and save into ec2?
|
||||
return 1.0 / e->cylindersCount;
|
||||
case IM_BATCH:
|
||||
return 2.0 / e->cylindersCount;
|
||||
default:
|
||||
firmwareError("Unexpected getFuelMultiplier %d", mode);
|
||||
return NAN;
|
||||
}
|
||||
}
|
||||
|
||||
void addFuelEvents(engine_configuration_s const *e, engine_configuration2_s *engineConfiguration2,
|
||||
ActuatorEventList *list, injection_mode_e mode) {
|
||||
list->resetEventList();
|
||||
|
@ -216,9 +231,16 @@ void addFuelEvents(engine_configuration_s const *e, engine_configuration2_s *eng
|
|||
break;
|
||||
case IM_BATCH:
|
||||
for (int i = 0; i < e->cylindersCount; i++) {
|
||||
io_pin_e pin = (io_pin_e) ((int) INJECTOR_1_OUTPUT + (i % 2));
|
||||
int index = i % (e->cylindersCount / 2);
|
||||
io_pin_e pin = (io_pin_e) ((int) INJECTOR_1_OUTPUT + index);
|
||||
float angle = baseAngle + i * 720.0 / e->cylindersCount;
|
||||
registerInjectionEvent(e, s, list, pin, angle);
|
||||
|
||||
/**
|
||||
* also fire the 2nd half of the injectors so that we can implement a batch mode on individual wires
|
||||
*/
|
||||
pin = (io_pin_e) ((int) INJECTOR_1_OUTPUT + index + (e->cylindersCount / 2));
|
||||
registerInjectionEvent(e, s, list, pin, angle);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
@ -270,8 +292,9 @@ void findTriggerPosition(engine_configuration_s const *engineConfiguration, trig
|
|||
while (true) {
|
||||
middle = (left + right) / 2;
|
||||
|
||||
if (middle == left)
|
||||
if (middle == left) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (angleOffset < s->eventAngles[middle]) {
|
||||
right = middle;
|
||||
|
@ -299,8 +322,10 @@ void registerActuatorEventExt(engine_configuration_s const *engineConfiguration,
|
|||
OutputSignal *actuator, float angleOffset) {
|
||||
efiAssertVoid(s->getSize() > 0, "uninitialized trigger_shape_s");
|
||||
|
||||
if (e == NULL)
|
||||
return; // error already reported
|
||||
if (e == NULL) {
|
||||
// error already reported
|
||||
return;
|
||||
}
|
||||
e->actuator = actuator;
|
||||
|
||||
findTriggerPosition(engineConfiguration, s, &e->position, angleOffset);
|
||||
|
@ -337,8 +362,7 @@ int getCylinderId(firing_order_e firingOrder, int index) {
|
|||
void prepareOutputSignals(engine_configuration_s *engineConfiguration, engine_configuration2_s *engineConfiguration2) {
|
||||
|
||||
// todo: move this reset into decoder
|
||||
engineConfiguration2->triggerShape.setTriggerShapeSynchPointIndex(findTriggerZeroEventIndex(
|
||||
&engineConfiguration2->triggerShape, &engineConfiguration->triggerConfig));
|
||||
engineConfiguration2->triggerShape.calculateTriggerSynchPoint(&engineConfiguration->triggerConfig);
|
||||
|
||||
injectonSignals.clear();
|
||||
EventHandlerConfiguration *config = &engineConfiguration2->engineEventConfiguration;
|
||||
|
@ -364,6 +388,7 @@ void setTimingLoadBin(engine_configuration_s *engineConfiguration, float l, floa
|
|||
setTableBin(engineConfiguration->ignitionLoadBins, IGN_LOAD_COUNT, l, r);
|
||||
}
|
||||
|
||||
int isInjectionEnabled(engine_configuration2_s const *engineConfiguration2) {
|
||||
return engineConfiguration2->isInjectionEnabledFlag;
|
||||
int isInjectionEnabled(engine_configuration_s *engineConfiguration) {
|
||||
// todo: is this worth a method? should this be inlined?
|
||||
return engineConfiguration->isInjectionEnabled;
|
||||
}
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
void findTriggerPosition(engine_configuration_s const *engineConfiguration, trigger_shape_s * s,
|
||||
event_trigger_position_s *position, float angleOffset);
|
||||
|
||||
int isInjectionEnabled(engine_configuration2_s const *engineConfiguration2);
|
||||
int isInjectionEnabled(engine_configuration_s *engineConfiguration);
|
||||
|
||||
float fixAngle(float angle);
|
||||
|
||||
|
|
|
@ -26,7 +26,7 @@ static Map3D1616 afrMap;
|
|||
#define tpMin 0
|
||||
#define tpMax 100
|
||||
// http://rusefi.com/math/t_charge.html
|
||||
float getTCharge(int rpm, int tps, float coolantTemp, float airTemp) {
|
||||
float getTCharge(int rpm, float tps, float coolantTemp, float airTemp) {
|
||||
float minRpmKcurrentTPS = interpolate(tpMin, K_AT_MIN_RPM_MIN_TPS, tpMax,
|
||||
K_AT_MIN_RPM_MAX_TPS, tps);
|
||||
float maxRpmKcurrentTPS = interpolate(tpMin, K_AT_MAX_RPM_MIN_TPS, tpMax,
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
#include "ec2.h"
|
||||
#include "engine.h"
|
||||
|
||||
float getTCharge(int rpm, int tps, float coolantTemp, float airTemp);
|
||||
float getTCharge(int rpm, float tps, float coolantTemp, float airTemp);
|
||||
void setDetaultVETable(engine_configuration_s *engineConfiguration);
|
||||
float sdMath(engine_configuration_s *engineConfiguration, float VE, float MAP, float AFR, float temp);
|
||||
|
||||
|
|
|
@ -18,8 +18,11 @@ extern engine_configuration_s * engineConfiguration;
|
|||
*/
|
||||
static FastInterpolation denso183(0, -6.64, 5, 182.78);
|
||||
|
||||
// todo: figure out real values
|
||||
static FastInterpolation honda3bar(0.32, -95.8371264, 4.84, 300);
|
||||
/**
|
||||
* MAP sensor output voltage of 3.0v = a gauge reading of 0 in. Hg
|
||||
* MAP sensor output voltage of 0.5v = a gauge reading of 27 in. Hg
|
||||
*/
|
||||
static FastInterpolation honda3bar(0.5, 91.422, 3.0, 0);
|
||||
|
||||
static FastInterpolation mpx4250(0, 8, 5, 260);
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@ typedef struct {
|
|||
float Min;
|
||||
float Max;
|
||||
air_pressure_sensor_type_e sensorType;
|
||||
int hwChannel;
|
||||
adc_channel_e hwChannel;
|
||||
} air_pressure_sensor_config_s;
|
||||
|
||||
/**
|
||||
|
@ -65,7 +65,7 @@ typedef struct {
|
|||
|
||||
typedef struct {
|
||||
ThermistorConf *config;
|
||||
int channel;
|
||||
adc_channel_e channel;
|
||||
} Thermistor;
|
||||
|
||||
#endif /* THERMISTOR_TYPES_H_ */
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* @file thermistors.c
|
||||
* @file thermistors.cpp
|
||||
*
|
||||
* @date Feb 17, 2013
|
||||
* @author Andrey Belomutskiy, (c) 2012-2014
|
||||
|
@ -18,8 +18,8 @@
|
|||
#include "ec2.h"
|
||||
|
||||
// Celsius
|
||||
#define LIMPING_MODE_IAT_TEMPERATURE 30
|
||||
#define LIMPING_MODE_CLT_TEMPERATURE 70
|
||||
#define LIMPING_MODE_IAT_TEMPERATURE 30.0f
|
||||
#define LIMPING_MODE_CLT_TEMPERATURE 70.0f
|
||||
|
||||
extern engine_configuration_s *engineConfiguration;
|
||||
extern engine_configuration2_s *engineConfiguration2;
|
||||
|
@ -34,8 +34,9 @@ float getR1InVoltageDividor(float Vout, float Vin, float r2) {
|
|||
}
|
||||
|
||||
float getR2InVoltageDividor(float Vout, float Vin, float r1) {
|
||||
if (Vout == 0)
|
||||
if (Vout == 0) {
|
||||
return NAN;
|
||||
}
|
||||
return r1 / (Vin / Vout - 1);
|
||||
}
|
||||
|
||||
|
@ -46,7 +47,7 @@ float getVoutInVoltageDividor(float Vin, float r1, float r2) {
|
|||
float convertResistanceToKelvinTemperature(float resistance, ThermistorConf *thermistor) {
|
||||
if (resistance <= 0) {
|
||||
//warning("Invalid resistance in convertResistanceToKelvinTemperature=", resistance);
|
||||
return 0;
|
||||
return 0.0f;
|
||||
}
|
||||
float logR = logf(resistance);
|
||||
return 1 / (thermistor->s_h_a + thermistor->s_h_b * logR + thermistor->s_h_c * logR * logR * logR);
|
||||
|
@ -93,12 +94,12 @@ float getTemperatureC(Thermistor *thermistor) {
|
|||
return convertKelvinToCelcius(kelvinTemperature);
|
||||
}
|
||||
|
||||
int isValidCoolantTemperature(float temperature) {
|
||||
bool isValidCoolantTemperature(float temperature) {
|
||||
// I hope magic constants are appropriate here
|
||||
return !cisnan(temperature) && temperature > -50 && temperature < 250;
|
||||
}
|
||||
|
||||
int isValidIntakeAirTemperature(float temperature) {
|
||||
bool isValidIntakeAirTemperature(float temperature) {
|
||||
// I hope magic constants are appropriate here
|
||||
return !cisnan(temperature) && temperature > -50 && temperature < 100;
|
||||
}
|
||||
|
@ -109,7 +110,7 @@ int isValidIntakeAirTemperature(float temperature) {
|
|||
float getCoolantTemperature(void) {
|
||||
float temperature = getTemperatureC(&engineConfiguration2->clt);
|
||||
if (!isValidCoolantTemperature(temperature)) {
|
||||
warning(OBD_PCM_Processor_Fault, "unrealistic coolant temperature %f", temperature);
|
||||
warning(OBD_PCM_Processor_Fault, "unrealistic CLT %f", temperature);
|
||||
return LIMPING_MODE_CLT_TEMPERATURE;
|
||||
}
|
||||
return temperature;
|
||||
|
@ -154,13 +155,13 @@ void prepareThermistorCurve(ThermistorConf * config) {
|
|||
float getIntakeAirTemperature(void) {
|
||||
float temperature = getTemperatureC(&engineConfiguration2->iat);
|
||||
if (!isValidIntakeAirTemperature(temperature)) {
|
||||
warning(OBD_PCM_Processor_Fault, "unrealistic intake temperature %f", temperature);
|
||||
warning(OBD_PCM_Processor_Fault, "unrealistic IAT %f", temperature);
|
||||
return LIMPING_MODE_IAT_TEMPERATURE;
|
||||
}
|
||||
return temperature;
|
||||
}
|
||||
|
||||
static void initThermistorCurve(Thermistor * t, ThermistorConf *config, int channel) {
|
||||
static void initThermistorCurve(Thermistor * t, ThermistorConf *config, adc_channel_e channel) {
|
||||
prepareThermistorCurve(config);
|
||||
t->config = config;
|
||||
t->channel = channel;
|
||||
|
|
|
@ -38,9 +38,9 @@ float getKelvinTemperature(float resistance, ThermistorConf *thermistor);
|
|||
float getResistance(Thermistor *thermistor);
|
||||
float getTemperatureC(Thermistor *thermistor);
|
||||
float getCoolantTemperature(void);
|
||||
int isValidCoolantTemperature(float temperature);
|
||||
bool isValidCoolantTemperature(float temperature);
|
||||
float getIntakeAirTemperature(void);
|
||||
int isValidIntakeAirTemperature(float temperature);
|
||||
bool isValidIntakeAirTemperature(float temperature);
|
||||
|
||||
float convertResistanceToKelvinTemperature(float resistance,
|
||||
ThermistorConf *thermistor);
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
#include "engine_configuration.h"
|
||||
#include "interpolation.h"
|
||||
#include "adc_inputs.h"
|
||||
#include "wave_math.h"
|
||||
|
||||
extern engine_configuration_s *engineConfiguration;
|
||||
|
||||
|
@ -49,14 +48,16 @@ float getTpsRateOfChange(void) {
|
|||
*
|
||||
* */
|
||||
float getTpsValue(int adc) {
|
||||
if (adc < engineConfiguration->tpsMin)
|
||||
return 0;
|
||||
if (adc > engineConfiguration->tpsMax)
|
||||
return 100;
|
||||
if (adc < engineConfiguration->tpsMin) {
|
||||
return 0.0f;
|
||||
}
|
||||
if (adc > engineConfiguration->tpsMax) {
|
||||
return 100.0f;
|
||||
}
|
||||
// todo: double comparison using EPS
|
||||
if (engineConfiguration->tpsMin == engineConfiguration->tpsMax) {
|
||||
firmwareError("Invalid TPS configuration: same value");
|
||||
return 0;
|
||||
return 0.0f;
|
||||
}
|
||||
return interpolate(engineConfiguration->tpsMin, 0, engineConfiguration->tpsMax, 100, adc);
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include "boards.h"
|
||||
#include "engine_configuration.h"
|
||||
#include "adc_inputs.h"
|
||||
#include "voltage.h"
|
||||
|
||||
extern engine_configuration_s *engineConfiguration;
|
||||
|
||||
|
|
|
@ -43,17 +43,21 @@ static void doPrintConfiguration(void) {
|
|||
printConfiguration(engineConfiguration, engineConfiguration2);
|
||||
}
|
||||
|
||||
static void printIntArray(int array[], int size) {
|
||||
for (int j = 0; j < size; j++)
|
||||
print("%d ", array[j]);
|
||||
print("\r\n");
|
||||
}
|
||||
/*
|
||||
static void printIntArray(int array[], int size) {
|
||||
for (int j = 0; j < size; j++) {
|
||||
print("%d ", array[j]);
|
||||
}
|
||||
print("\r\n");
|
||||
}
|
||||
*/
|
||||
|
||||
void printFloatArray(const char *prefix, float array[], int size) {
|
||||
appendMsgPrefix(&logger);
|
||||
appendPrintf(&logger, prefix);
|
||||
for (int j = 0; j < size; j++)
|
||||
for (int j = 0; j < size; j++) {
|
||||
appendPrintf(&logger, "%f ", array[j]);
|
||||
}
|
||||
appendMsgPostfix(&logger);
|
||||
scheduleLogging(&logger);
|
||||
}
|
||||
|
@ -76,8 +80,12 @@ const char* getConfigurationName(engine_configuration_s *engineConfiguration) {
|
|||
case NISSAN_PRIMERA:
|
||||
return "Nissan Primera";
|
||||
#endif /* EFI_SUPPORT_NISSAN_PRIMERA */
|
||||
case HONDA_ACCORD:
|
||||
return "Honda Accord";
|
||||
case HONDA_ACCORD_CD:
|
||||
return "Honda Accord 3w";
|
||||
case HONDA_ACCORD_CD_TWO_WIRES:
|
||||
return "Honda Accord 2w";
|
||||
case HONDA_ACCORD_CD_DIP:
|
||||
return "Honda Dip";
|
||||
case FORD_INLINE_6_1995:
|
||||
return "Ford 1995 inline 6";
|
||||
case GY6_139QMB:
|
||||
|
@ -96,7 +104,10 @@ const char* getConfigurationName(engine_configuration_s *engineConfiguration) {
|
|||
return "Citroen TU3JP";
|
||||
case ROVER_V8:
|
||||
return "Rover v8";
|
||||
case MITSU_4G93:
|
||||
return "Mitsu 4G93";
|
||||
default:
|
||||
firmwareError("Unexpected: engineType %d", engineConfiguration->engineType);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
@ -125,7 +136,8 @@ static const char * boolToString(bool value) {
|
|||
*/
|
||||
void printConfiguration(engine_configuration_s *engineConfiguration, engine_configuration2_s *engineConfiguration2) {
|
||||
|
||||
scheduleMsg(&logger, "Template %s trigger %d", getConfigurationName(engineConfiguration), engineConfiguration->triggerConfig.triggerType);
|
||||
scheduleMsg(&logger, "Template %s/%d trigger %d", getConfigurationName(engineConfiguration),
|
||||
engineConfiguration->engineType, engineConfiguration->triggerConfig.triggerType);
|
||||
|
||||
scheduleMsg(&logger, "configurationVersion=%d", getGlobalConfigurationVersion());
|
||||
|
||||
|
@ -152,16 +164,18 @@ void printConfiguration(engine_configuration_s *engineConfiguration, engine_conf
|
|||
|
||||
// appendMsgPrefix(&logger);
|
||||
|
||||
scheduleMsg(&logger, "rpmHardLimit: %d", engineConfiguration->rpmHardLimit);
|
||||
scheduleMsg(&logger, "rpmMultiplier=%f", engineConfiguration->rpmMultiplier);
|
||||
scheduleMsg(&logger, "rpmHardLimit: %d/rpmMultiplier=%f", engineConfiguration->rpmHardLimit,
|
||||
engineConfiguration->rpmMultiplier);
|
||||
|
||||
scheduleMsg(&logger, "tpsMin: %d", engineConfiguration->tpsMin);
|
||||
scheduleMsg(&logger, "tpsMax: %d", engineConfiguration->tpsMax);
|
||||
scheduleMsg(&logger, "tpsMin: %d/tpsMax: %d", engineConfiguration->tpsMin, engineConfiguration->tpsMax);
|
||||
|
||||
scheduleMsg(&logger, "ignitionMode: %d/enabled=%s", engineConfiguration->ignitionMode,
|
||||
boolToString(engineConfiguration->isIgnitionEnabled));
|
||||
scheduleMsg(&logger, "timingMode: %d", engineConfiguration->timingMode);
|
||||
scheduleMsg(&logger, "fixedModeTiming: %d", (int) engineConfiguration->fixedModeTiming);
|
||||
scheduleMsg(&logger, "ignitionOffset=%f", engineConfiguration->ignitionOffset);
|
||||
scheduleMsg(&logger, "injectionOffset=%f", engineConfiguration->injectionOffset);
|
||||
scheduleMsg(&logger, "injectionOffset=%f/enabled=%s", (double) engineConfiguration->injectionOffset,
|
||||
boolToString(engineConfiguration->isInjectionEnabled));
|
||||
|
||||
scheduleMsg(&logger, "crankingChargeAngle=%f", engineConfiguration->crankingChargeAngle);
|
||||
scheduleMsg(&logger, "crankingTimingAngle=%f", engineConfiguration->crankingTimingAngle);
|
||||
|
@ -176,7 +190,8 @@ void printConfiguration(engine_configuration_s *engineConfiguration, engine_conf
|
|||
pinModeToString(boardConfiguration->malfunctionIndicatorPinMode));
|
||||
scheduleMsg(&logger, "analogInputDividerCoefficient: %f", engineConfiguration->analogInputDividerCoefficient);
|
||||
|
||||
scheduleMsg(&logger, "needSecondTriggerInput: %s", boolToString(engineConfiguration2->triggerShape.needSecondTriggerInput));
|
||||
scheduleMsg(&logger, "needSecondTriggerInput: %s",
|
||||
boolToString(engineConfiguration2->triggerShape.needSecondTriggerInput));
|
||||
|
||||
#if EFI_PROD_CODE
|
||||
scheduleMsg(&logger, "idleValvePin: %s", hwPortname(boardConfiguration->idleValvePin));
|
||||
|
@ -201,19 +216,23 @@ void printConfiguration(engine_configuration_s *engineConfiguration, engine_conf
|
|||
pinModeToString(boardConfiguration->triggerSimulatorPinModes[0]));
|
||||
scheduleMsg(&logger, "secondary trigger simulator: %s %s", hwPortname(boardConfiguration->triggerSimulatorPins[1]),
|
||||
pinModeToString(boardConfiguration->triggerSimulatorPinModes[1]));
|
||||
scheduleMsg(&logger, "3rd trigger simulator: %s %s", hwPortname(boardConfiguration->triggerSimulatorPins[2]),
|
||||
pinModeToString(boardConfiguration->triggerSimulatorPinModes[2]));
|
||||
|
||||
scheduleMsg(&logger, "primary trigger input: %s", hwPortname(boardConfiguration->primaryTriggerInputPin));
|
||||
scheduleMsg(&logger, "primary trigger input: %s", hwPortname(boardConfiguration->triggerInputPins[0]));
|
||||
scheduleMsg(&logger, "secondary trigger input: %s", hwPortname(boardConfiguration->triggerInputPins[1]));
|
||||
scheduleMsg(&logger, "primary logic input: %s", hwPortname(boardConfiguration->logicAnalyzerPins[0]));
|
||||
scheduleMsg(&logger, "secondary logic input: %s", hwPortname(boardConfiguration->logicAnalyzerPins[1]));
|
||||
|
||||
scheduleMsg(&logger, "boardTestModeJumperPin: %s", hwPortname(boardConfiguration->boardTestModeJumperPin));
|
||||
|
||||
scheduleMsg(&logger, "digitalPotentiometerSpiDevice %d", boardConfiguration->digitalPotentiometerSpiDevice);
|
||||
|
||||
for (int i = 0; i < DIGIPOT_COUNT; i++) {
|
||||
scheduleMsg(&logger, "digitalPotentiometer CS%d %s", i, hwPortname(boardConfiguration->digitalPotentiometerChipSelect[i]));
|
||||
scheduleMsg(&logger, "digitalPotentiometer CS%d %s", i,
|
||||
hwPortname(boardConfiguration->digitalPotentiometerChipSelect[i]));
|
||||
}
|
||||
#endif /* EFI_PROD_CODE */
|
||||
|
||||
scheduleMsg(&logger, "isInjectionEnabledFlag %s", boolToString(engineConfiguration2->isInjectionEnabledFlag));
|
||||
}
|
||||
|
||||
static void setFixedModeTiming(int value) {
|
||||
|
@ -228,6 +247,10 @@ static void setTimingMode(int value) {
|
|||
incrementGlobalConfigurationVersion();
|
||||
}
|
||||
|
||||
static void setIdleMode(int mode) {
|
||||
engineConfiguration->idleMode = (idle_mode_e) mode;
|
||||
}
|
||||
|
||||
void setEngineType(int value) {
|
||||
engineConfiguration->engineType = (engine_type_e) value;
|
||||
resetConfigurationExt(&logger, (engine_type_e) value, engineConfiguration, engineConfiguration2,
|
||||
|
@ -295,7 +318,7 @@ static void setRpmMultiplier(int value) {
|
|||
static char pinNameBuffer[16];
|
||||
|
||||
static void printThermistor(const char *msg, Thermistor *thermistor) {
|
||||
int adcChannel = thermistor->channel;
|
||||
adc_channel_e adcChannel = thermistor->channel;
|
||||
float voltage = getVoltageDivided(adcChannel);
|
||||
float r = getResistance(thermistor);
|
||||
|
||||
|
@ -309,8 +332,8 @@ static void printThermistor(const char *msg, Thermistor *thermistor) {
|
|||
#endif
|
||||
}
|
||||
|
||||
static void printMAPInfo(void) {
|
||||
#if EFI_PROD_CODE
|
||||
static void printMAPInfo(void) {
|
||||
scheduleMsg(&logger, "map type=%d raw=%f MAP=%f", engineConfiguration->map.sensor.sensorType, getRawMap(),
|
||||
getMap());
|
||||
if (engineConfiguration->map.sensor.sensorType == MT_CUSTOM) {
|
||||
|
@ -321,8 +344,8 @@ static void printMAPInfo(void) {
|
|||
if (engineConfiguration->baroSensor.sensorType == MT_CUSTOM) {
|
||||
scheduleMsg(&logger, "min=%f max=%f", engineConfiguration->baroSensor.Min, engineConfiguration->baroSensor.Max);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
static void printTPSInfo(void) {
|
||||
#if EFI_PROD_CODE
|
||||
|
@ -337,16 +360,22 @@ static void printTPSInfo(void) {
|
|||
|
||||
static void printTemperatureInfo(void) {
|
||||
printThermistor("CLT", &engineConfiguration2->clt);
|
||||
if (!isValidCoolantTemperature(getCoolantTemperature())) {
|
||||
scheduleMsg(&logger, "CLT sensing error");
|
||||
}
|
||||
printThermistor("IAT", &engineConfiguration2->iat);
|
||||
if (!isValidIntakeAirTemperature(getIntakeAirTemperature())) {
|
||||
scheduleMsg(&logger, "IAT sensing error");
|
||||
}
|
||||
|
||||
float rClt = getResistance(&engineConfiguration2->clt);
|
||||
float rIat = getResistance(&engineConfiguration2->iat);
|
||||
|
||||
#if EFI_ANALOG_INPUTS
|
||||
int cltChannel = engineConfiguration2->clt.channel;
|
||||
adc_channel_e cltChannel = engineConfiguration2->clt.channel;
|
||||
scheduleMsg(&logger, "CLT R=%f on channel %d@%s", rClt, cltChannel,
|
||||
getPinNameByAdcChannel(cltChannel, pinNameBuffer));
|
||||
int iatChannel = engineConfiguration2->iat.channel;
|
||||
adc_channel_e iatChannel = engineConfiguration2->iat.channel;
|
||||
scheduleMsg(&logger, "IAT R=%f on channel %d@%s", rIat, iatChannel,
|
||||
getPinNameByAdcChannel(iatChannel, pinNameBuffer));
|
||||
|
||||
|
@ -425,7 +454,7 @@ static void setIgnitionMode(int value) {
|
|||
}
|
||||
|
||||
static void setTriggerType(int value) {
|
||||
engineConfiguration->triggerConfig.triggerType = (trigger_type_e)value;
|
||||
engineConfiguration->triggerConfig.triggerType = (trigger_type_e) value;
|
||||
incrementGlobalConfigurationVersion();
|
||||
doPrintConfiguration();
|
||||
}
|
||||
|
@ -450,6 +479,10 @@ static void setGlobalFuelCorrection(float value) {
|
|||
engineConfiguration->globalFuelCorrection = value;
|
||||
}
|
||||
|
||||
static void setVBattDivider(float value) {
|
||||
engineConfiguration->vbattDividerCoeff = value;
|
||||
}
|
||||
|
||||
static void setWholeTimingMap(float value) {
|
||||
// todo: table helper?
|
||||
scheduleMsg(&logger, "Setting whole timing map to %f", value);
|
||||
|
@ -465,7 +498,72 @@ static void setWholeFuelMapCmd(float value) {
|
|||
setWholeFuelMap(engineConfiguration, value);
|
||||
}
|
||||
|
||||
static void setTimingMap(char * rpmStr, char *loadStr, char *valueStr) {
|
||||
static void setTriggerInputPin(const char *indexStr, const char *pinName) {
|
||||
#if EFI_PROD_CODE
|
||||
int index = atoi(indexStr);
|
||||
if (index < 0 || index > 2)
|
||||
return;
|
||||
brain_pin_e pin = parseBrainPin(pinName);
|
||||
scheduleMsg(&logger, "setting trigger pin[%d] to %s please save&restart", index, hwPortname(pin));
|
||||
boardConfiguration->triggerInputPins[index] = pin;
|
||||
#endif
|
||||
}
|
||||
|
||||
#if EFI_PROD_CODE
|
||||
static void setTriggerSimulatorMode(const char *indexStr, const char *modeCode) {
|
||||
int index = atoi(indexStr);
|
||||
if (index < 0 || index > 2 || absI(index) == ERROR_CODE) {
|
||||
return;
|
||||
}
|
||||
int mode = atoi(modeCode);
|
||||
if (absI(mode) == ERROR_CODE) {
|
||||
return;
|
||||
}
|
||||
boardConfiguration->triggerSimulatorPinModes[index] = (pin_output_mode_e) mode;
|
||||
}
|
||||
|
||||
static void setTriggerSimulatorPin(const char *indexStr, const char *pinName) {
|
||||
int index = atoi(indexStr);
|
||||
if (index < 0 || index > 2)
|
||||
return;
|
||||
brain_pin_e pin = parseBrainPin(pinName);
|
||||
scheduleMsg(&logger, "setting trigger simulator pin[%d] to %s please save&restart", index, hwPortname(pin));
|
||||
boardConfiguration->triggerSimulatorPins[index] = pin;
|
||||
}
|
||||
|
||||
static void setAnalogInputPin(const char *sensorStr, const char *pinName) {
|
||||
brain_pin_e pin = parseBrainPin(pinName);
|
||||
adc_channel_e channel = getAdcChannel(pin);
|
||||
if (channel == EFI_ADC_ERROR) {
|
||||
scheduleMsg(&logger, "Error with [%s]", pinName);
|
||||
return;
|
||||
}
|
||||
if (strEqual("map", sensorStr)) {
|
||||
engineConfiguration->map.sensor.hwChannel = channel;
|
||||
scheduleMsg(&logger, "setting MAP to %s/%d", pinName, channel);
|
||||
} else if (strEqual("clt", sensorStr)) {
|
||||
engineConfiguration->cltAdcChannel = channel;
|
||||
scheduleMsg(&logger, "setting CLT to %s/%d", pinName, channel);
|
||||
} else if (strEqual("iat", sensorStr)) {
|
||||
engineConfiguration->iatAdcChannel = channel;
|
||||
scheduleMsg(&logger, "setting IAT to %s/%d", pinName, channel);
|
||||
} else if (strEqual("tps", sensorStr)) {
|
||||
engineConfiguration->tpsAdcChannel = channel;
|
||||
scheduleMsg(&logger, "setting TPS to %s/%d", pinName, channel);
|
||||
}
|
||||
}
|
||||
|
||||
static void setLogicInputPin(const char *indexStr, const char *pinName) {
|
||||
int index = atoi(indexStr);
|
||||
if (index < 0 || index > 2)
|
||||
return;
|
||||
brain_pin_e pin = parseBrainPin(pinName);
|
||||
scheduleMsg(&logger, "setting logic input pin[%d] to %s please save&restart", index, hwPortname(pin));
|
||||
boardConfiguration->logicAnalyzerPins[index] = pin;
|
||||
}
|
||||
#endif /* EFI_PROD_CODE */
|
||||
|
||||
static void setTimingMap(const char * rpmStr, const char *loadStr, const char *valueStr) {
|
||||
float rpm = atoff(rpmStr);
|
||||
float engineLoad = atoff(loadStr);
|
||||
float value = atoff(valueStr);
|
||||
|
@ -479,7 +577,7 @@ static void setTimingMap(char * rpmStr, char *loadStr, char *valueStr) {
|
|||
scheduleMsg(&logger, "Setting timing map entry %d:%d to %f", rpmIndex, loadIndex, value);
|
||||
}
|
||||
|
||||
static void setFuelMap(char * rpmStr, char *loadStr, char *valueStr) {
|
||||
static void setFuelMap(const char * rpmStr, const char *loadStr, const char *valueStr) {
|
||||
float rpm = atoff(rpmStr);
|
||||
float engineLoad = atoff(loadStr);
|
||||
float value = atoff(valueStr);
|
||||
|
@ -494,15 +592,35 @@ static void setFuelMap(char * rpmStr, char *loadStr, char *valueStr) {
|
|||
}
|
||||
|
||||
static void enableInjection(void) {
|
||||
engineConfiguration2->isInjectionEnabledFlag = TRUE;
|
||||
engineConfiguration->isInjectionEnabled = true;
|
||||
scheduleMsg(&logger, "injection enabled");
|
||||
}
|
||||
|
||||
static void disableInjection(void) {
|
||||
engineConfiguration2->isInjectionEnabledFlag = FALSE;
|
||||
engineConfiguration->isInjectionEnabled = false;
|
||||
scheduleMsg(&logger, "injection disabled");
|
||||
}
|
||||
|
||||
static void enableIgnition(void) {
|
||||
engineConfiguration->isIgnitionEnabled = true;
|
||||
scheduleMsg(&logger, "ignition enabled");
|
||||
}
|
||||
|
||||
static void disableIgnition(void) {
|
||||
engineConfiguration->isIgnitionEnabled = false;
|
||||
scheduleMsg(&logger, "ignition disabled");
|
||||
}
|
||||
|
||||
static void enableSelfStimulation(void) {
|
||||
engineConfiguration->directSelfStimulation = true;
|
||||
scheduleMsg(&logger, "self stimulation enabled");
|
||||
}
|
||||
|
||||
static void disableSelfStimulation(void) {
|
||||
engineConfiguration->directSelfStimulation = false;
|
||||
scheduleMsg(&logger, "self stimulation disabled");
|
||||
}
|
||||
|
||||
#if EFI_WAVE_CHART
|
||||
extern int waveChartUsedSize;
|
||||
#endif
|
||||
|
@ -510,11 +628,11 @@ extern int waveChartUsedSize;
|
|||
static void printAllInfo(void) {
|
||||
printTemperatureInfo();
|
||||
printTPSInfo();
|
||||
printMAPInfo();
|
||||
#if EFI_WAVE_CHART
|
||||
scheduleMsg(&logger, "waveChartUsedSize=%d", waveChartUsedSize);
|
||||
#endif
|
||||
#if EFI_PROD_CODE
|
||||
printMAPInfo();
|
||||
scheduleMsg(&logger, "console mode jumper: %s", boolToString(!GET_CONSOLE_MODE_VALUE()));
|
||||
scheduleMsg(&logger, "board test mode jumper: %s", boolToString(GET_BOARD_TEST_MODE_VALUE()));
|
||||
#endif
|
||||
|
@ -526,7 +644,6 @@ void initSettings(void) {
|
|||
addConsoleAction("showconfig", doPrintConfiguration);
|
||||
addConsoleAction("tempinfo", printTemperatureInfo);
|
||||
addConsoleAction("tpsinfo", printTPSInfo);
|
||||
addConsoleAction("mapinfo", printMAPInfo);
|
||||
addConsoleAction("info", printAllInfo);
|
||||
|
||||
addConsoleActionI("set_ignition_offset", setIgnitionOffset);
|
||||
|
@ -536,6 +653,7 @@ void initSettings(void) {
|
|||
addConsoleActionI("set_fixed_mode_timing", setFixedModeTiming);
|
||||
addConsoleActionI("set_timing_mode", setTimingMode);
|
||||
addConsoleActionI("set_engine_type", setEngineType);
|
||||
addConsoleActionI("set_idle_mode", setIdleMode);
|
||||
|
||||
addConsoleActionI("set_injection_pin_mode", setInjectionPinMode);
|
||||
addConsoleActionI("set_ignition_pin_mode", setIgnitionPinMode);
|
||||
|
@ -567,9 +685,28 @@ void initSettings(void) {
|
|||
addConsoleActionI("set_firing_order", setFiringOrder);
|
||||
addConsoleActionI("set_algorithm", setAlgorithm);
|
||||
|
||||
// todo: refactor this - looks like all boolean flags should be controlled with less code duplication
|
||||
addConsoleAction("enable_injection", enableInjection);
|
||||
addConsoleAction("disable_injection", disableInjection);
|
||||
addConsoleAction("enable_ignition", enableIgnition);
|
||||
addConsoleAction("disable_ignition", disableIgnition);
|
||||
addConsoleAction("enable_self_stimulation", enableSelfStimulation);
|
||||
addConsoleAction("disable_self_stimulation", disableSelfStimulation);
|
||||
|
||||
addConsoleActionII("set_toothed_wheel", setToothedWheel);
|
||||
addConsoleActionI("set_trigger_type", setTriggerType);
|
||||
|
||||
addConsoleActionSS("set_trigger_input_pin", setTriggerInputPin);
|
||||
|
||||
addConsoleActionF("set_vbatt_divider", setVBattDivider);
|
||||
|
||||
#if EFI_PROD_CODE
|
||||
addConsoleActionSS("set_trigger_simulator_pin", setTriggerSimulatorPin);
|
||||
addConsoleActionSS("set_trigger_simulator_mode", setTriggerSimulatorMode);
|
||||
|
||||
addConsoleAction("mapinfo", printMAPInfo);
|
||||
addConsoleActionSS("set_analog_input_pin", setAnalogInputPin);
|
||||
addConsoleActionSS("set_logic_input_pin", setLogicInputPin);
|
||||
#endif /* EFI_PROD_CODE */
|
||||
}
|
||||
|
||||
|
|
|
@ -56,7 +56,7 @@ static uint64_t getNextSwitchTimeUs(PwmConfig *state) {
|
|||
* Once 'iteration' gets relatively high, we might lose calculation precision here.
|
||||
* This is addressed by ITERATION_LIMIT
|
||||
*/
|
||||
uint64_t timeToSwitchUs = (iteration + switchTime) * periodUs;
|
||||
uint64_t timeToSwitchUs = (uint64_t)((iteration + switchTime) * periodUs);
|
||||
|
||||
#if DEBUG_PWM
|
||||
scheduleMsg(&logger, "start=%d timeToSwitch=%d", state->safe.start, timeToSwitch);
|
||||
|
@ -66,8 +66,9 @@ static uint64_t getNextSwitchTimeUs(PwmConfig *state) {
|
|||
|
||||
void PwmConfig::handleCycleStart() {
|
||||
if (safe.phaseIndex == 0) {
|
||||
if (cycleCallback != NULL)
|
||||
if (cycleCallback != NULL) {
|
||||
cycleCallback(this);
|
||||
}
|
||||
efiAssertVoid(periodUs != 0, "period not initialized");
|
||||
if (safe.periodUs != periodUs || safe.iteration == ITERATION_LIMIT) {
|
||||
/**
|
||||
|
@ -119,6 +120,9 @@ static uint64_t togglePwmState(PwmConfig *state) {
|
|||
* We are here if we are late for a state transition.
|
||||
* At 12000RPM=200Hz with a 60 toothed wheel we need to change state every
|
||||
* 1000000 / 200 / 120 = ~41 uS. We are kind of OK.
|
||||
*
|
||||
* We are also here after a flash write. Flash write freezes the whole chip for a couple of seconds,
|
||||
* so PWM generation and trigger simulation generation would have to recover from this time lag.
|
||||
*/
|
||||
//todo: introduce error and test this error handling warning(OBD_PCM_Processor_Fault, "PWM: negative switch time");
|
||||
timeToSwitch = 10;
|
||||
|
|
|
@ -30,7 +30,7 @@
|
|||
|
||||
#endif
|
||||
|
||||
#if EFI_ENGINE_CONTROL
|
||||
#if EFI_ENGINE_CONTROL || defined(__DOXYGEN__)
|
||||
|
||||
#include "main_trigger_callback.h"
|
||||
#include "ec2.h"
|
||||
|
@ -97,7 +97,7 @@ static void handleFuelInjectionEvent(MainTriggerCallback *mainTriggerCallback, A
|
|||
}
|
||||
|
||||
static void handleFuel(MainTriggerCallback *mainTriggerCallback, int eventIndex, int rpm) {
|
||||
if (!isInjectionEnabled(mainTriggerCallback->engineConfiguration2))
|
||||
if (!isInjectionEnabled(mainTriggerCallback->engineConfiguration))
|
||||
return;
|
||||
efiAssertVoid(getRemainingStack(chThdSelf()) > 16, "stack#3");
|
||||
efiAssertVoid(eventIndex < 2 * mainTriggerCallback->engineConfiguration2->triggerShape.shaftPositionEventCount,
|
||||
|
@ -185,7 +185,7 @@ static void handleSparkEvent(MainTriggerCallback *mainTriggerCallback, int event
|
|||
}
|
||||
|
||||
static void handleSpark(MainTriggerCallback *mainTriggerCallback, int eventIndex, int rpm, IgnitionEventList *list) {
|
||||
if (!isValidRpm(rpm))
|
||||
if (!isValidRpm(rpm) || !mainTriggerCallback->engineConfiguration->isIgnitionEnabled)
|
||||
return; // this might happen for instance in case of a single trigger event after a pause
|
||||
|
||||
/**
|
||||
|
@ -326,17 +326,16 @@ void MainTriggerCallback::init(Engine *engine, engine_configuration2_s *engineCo
|
|||
|
||||
void initMainEventListener(Engine *engine, engine_configuration2_s *engineConfiguration2) {
|
||||
efiAssertVoid(engine!=NULL, "null engine");
|
||||
engine_configuration_s *engineConfiguration = engine->engineConfiguration;
|
||||
|
||||
mainTriggerCallbackInstance.init(engine, engineConfiguration2);
|
||||
|
||||
#if EFI_PROD_CODE
|
||||
#if EFI_PROD_CODE || defined(__DOXYGEN__)
|
||||
addConsoleAction("performanceinfo", showTriggerHistogram);
|
||||
addConsoleAction("maininfo", showMainInfo);
|
||||
|
||||
initLogging(&logger, "main event handler");
|
||||
printMsg(&logger, "initMainLoop: %d", currentTimeMillis());
|
||||
if (!isInjectionEnabled(mainTriggerCallbackInstance.engineConfiguration2))
|
||||
if (!isInjectionEnabled(mainTriggerCallbackInstance.engineConfiguration))
|
||||
printMsg(&logger, "!!!!!!!!!!!!!!!!!!! injection disabled");
|
||||
#endif
|
||||
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
extern WaveChart waveChart;
|
||||
#endif /* EFI_WAVE_CHART */
|
||||
|
||||
#if EFI_SHAFT_POSITION_INPUT
|
||||
#if EFI_SHAFT_POSITION_INPUT || defined(__DOXYGEN__)
|
||||
|
||||
#include "trigger_central.h"
|
||||
#include "engine_configuration.h"
|
||||
|
@ -77,7 +77,7 @@ uint64_t getLastRpmEventTime(void) {
|
|||
return rpmState.lastRpmEventTimeUs;
|
||||
}
|
||||
|
||||
#if EFI_PROD_CODE || EFI_SIMULATOR
|
||||
#if (EFI_PROD_CODE || EFI_SIMULATOR) || defined(__DOXYGEN__)
|
||||
bool isCranking(void) {
|
||||
int rpm = getRpm();
|
||||
return isCrankingR(rpm);
|
||||
|
@ -141,10 +141,14 @@ void rpmShaftPositionCallback(trigger_event_e ckpSignalType, int index, RpmCalcu
|
|||
addWaveChartEvent(WC_CRANK2, WC_UP, (char*) shaft_signal_msg_index);
|
||||
} else if (ckpSignalType == SHAFT_SECONDARY_DOWN) {
|
||||
addWaveChartEvent(WC_CRANK2, WC_DOWN, (char*) shaft_signal_msg_index);
|
||||
} else if (ckpSignalType == SHAFT_3RD_UP) {
|
||||
addWaveChartEvent(WC_CRANK3, WC_UP, (char*) shaft_signal_msg_index);
|
||||
} else if (ckpSignalType == SHAFT_3RD_DOWN) {
|
||||
addWaveChartEvent(WC_CRANK3, WC_DOWN, (char*) shaft_signal_msg_index);
|
||||
}
|
||||
|
||||
if (index != 0) {
|
||||
#if EFI_ANALOG_CHART
|
||||
#if EFI_ANALOG_CHART || defined(__DOXYGEN__)
|
||||
if (engineConfiguration->analogChartMode == AC_TRIGGER)
|
||||
acAddData(getCrankshaftAngle(getTimeNowUs()), 1000 * ckpSignalType + index);
|
||||
#endif
|
||||
|
@ -174,7 +178,7 @@ void rpmShaftPositionCallback(trigger_event_e ckpSignalType, int index, RpmCalcu
|
|||
}
|
||||
}
|
||||
rpmState->lastRpmEventTimeUs = nowUs;
|
||||
#if EFI_ANALOG_CHART
|
||||
#if EFI_ANALOG_CHART || defined(__DOXYGEN__)
|
||||
if (engineConfiguration->analogChartMode == AC_TRIGGER)
|
||||
acAddData(getCrankshaftAngle(nowUs), index);
|
||||
#endif
|
||||
|
@ -184,22 +188,31 @@ static scheduling_s tdcScheduler[2];
|
|||
|
||||
static char rpmBuffer[10];
|
||||
|
||||
#if EFI_PROD_CODE || EFI_SIMULATOR
|
||||
#if (EFI_PROD_CODE || EFI_SIMULATOR) || defined(__DOXYGEN__)
|
||||
/**
|
||||
* This callback has nothing to do with actual engine control, it just sends a Top Dead Center mark to the dev console
|
||||
* digital sniffer.
|
||||
*/
|
||||
static void onTdcCallback(void) {
|
||||
itoa10(rpmBuffer, getRpm());
|
||||
addWaveChartEvent(TOP_DEAD_CENTER_MESSAGE, (char*) rpmBuffer, "");
|
||||
}
|
||||
|
||||
/**
|
||||
* This trigger callback schedules the actual physical TDC callback in relation to trigger synchronization point.
|
||||
*/
|
||||
static void tdcMarkCallback(trigger_event_e ckpSignalType, int index, void *arg) {
|
||||
if (index == 0) {
|
||||
bool isTriggerSynchronizationPoint = index == 0;
|
||||
if (isTriggerSynchronizationPoint) {
|
||||
int index = getRevolutionCounter() % 2;
|
||||
// todo: use event-based scheduling, not just time-based scheduling
|
||||
scheduleByAngle(&tdcScheduler[index], engineConfiguration->globalTriggerAngleOffset, (schfunc_t) onTdcCallback, NULL);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void initRpmCalculator(void) {
|
||||
#if EFI_PROD_CODE || EFI_SIMULATOR
|
||||
#if (EFI_PROD_CODE || EFI_SIMULATOR) || defined(__DOXYGEN__)
|
||||
initLogging(&logger, "rpm calc");
|
||||
engine.rpmCalculator = &rpmState;
|
||||
|
||||
|
@ -213,7 +226,7 @@ void initRpmCalculator(void) {
|
|||
addTriggerEventListener((ShaftPositionListener)&rpmShaftPositionCallback, "rpm reporter", &rpmState);
|
||||
}
|
||||
|
||||
#if EFI_PROD_CODE || EFI_SIMULATOR
|
||||
#if (EFI_PROD_CODE || EFI_SIMULATOR) || defined(__DOXYGEN__)
|
||||
/**
|
||||
* Schedules a callback 'angle' degree of crankshaft from now.
|
||||
* The callback would be executed once after the duration of time which
|
||||
|
|
|
@ -9,12 +9,13 @@
|
|||
#ifndef RPM_REPORTER_H_
|
||||
#define RPM_REPORTER_H_
|
||||
|
||||
#include <time.h>
|
||||
#include <global.h>
|
||||
|
||||
#define WC_DOWN "d"
|
||||
#define WC_UP "u"
|
||||
#define WC_CRANK1 "c1"
|
||||
#define WC_CRANK2 "c2"
|
||||
#define WC_CRANK3 "c3"
|
||||
|
||||
#define NOISY_RPM -1
|
||||
|
||||
|
@ -58,6 +59,9 @@ uint64_t getLastRpmEventTime(void);
|
|||
|
||||
int getRevolutionCounter(void);
|
||||
float getCrankshaftAngle(uint64_t timeUs);
|
||||
/**
|
||||
* @return true if engine is running
|
||||
*/
|
||||
bool isRunning(void);
|
||||
bool isValidRpm(int rpm);
|
||||
void addWaveChartEvent(const char *name, const char *msg, const char *msg2);
|
||||
|
|
|
@ -7,6 +7,7 @@ TRIGGER_DECODERS_SRC_CPP = \
|
|||
$(PROJECT_DIR)/controllers/trigger/trigger_chrysler.cpp \
|
||||
$(PROJECT_DIR)/controllers/trigger/trigger_structure.cpp \
|
||||
$(PROJECT_DIR)/controllers/trigger/trigger_decoder.cpp \
|
||||
$(PROJECT_DIR)/controllers/trigger/trigger_mitsubishi.cpp \
|
||||
$(PROJECT_DIR)/controllers/trigger/trigger_gm.cpp
|
||||
|
||||
TRIGGER_SRC_CPP = \
|
||||
|
|
|
@ -26,8 +26,9 @@ void configureMiniCooperTriggerShape(trigger_shape_s *s) {
|
|||
s->addEvent(a, T_SECONDARY, TV_LOW);
|
||||
a += w;
|
||||
|
||||
for (int i = 0; i <= 22; i++)
|
||||
for (int i = 0; i <= 22; i++) {
|
||||
a = addPair(s, a, w);
|
||||
}
|
||||
|
||||
a += 3 * w;
|
||||
|
||||
|
@ -38,13 +39,15 @@ void configureMiniCooperTriggerShape(trigger_shape_s *s) {
|
|||
s->addEvent(a, T_SECONDARY, TV_LOW);
|
||||
a += w;
|
||||
|
||||
for (int i = 0; i < 36; i++)
|
||||
for (int i = 0; i < 36; i++) {
|
||||
a = addPair(s, a, w);
|
||||
}
|
||||
|
||||
s->addEvent(376, T_PRIMARY, TV_HIGH);
|
||||
|
||||
for (int i = 0; i < 21; i++)
|
||||
for (int i = 0; i < 21; i++) {
|
||||
a = addPair(s, a, w);
|
||||
}
|
||||
a += 3 * w;
|
||||
|
||||
efiAssertVoid(absF(firstGapAngle + 360 - a) < 0.1, "shape constraint");
|
||||
|
@ -54,13 +57,14 @@ void configureMiniCooperTriggerShape(trigger_shape_s *s) {
|
|||
s->addEvent(a, T_SECONDARY, TV_LOW);
|
||||
a += w;
|
||||
|
||||
for (int i = 0; i < 33; i++)
|
||||
for (int i = 0; i < 33; i++) {
|
||||
a = addPair(s, a, w);
|
||||
}
|
||||
|
||||
efiAssertVoid(absF(720 - w / 2 - a) < 0.1, "shape constraint");
|
||||
s->addEvent(a, T_SECONDARY, TV_HIGH);
|
||||
|
||||
s->addEvent(720, T_PRIMARY, TV_LOW);
|
||||
s->addEvent(720.0, T_PRIMARY, TV_LOW);
|
||||
|
||||
s->shaftPositionEventCount = s->getSize();
|
||||
/**
|
||||
|
|
|
@ -11,7 +11,6 @@
|
|||
#include "main_trigger_callback.h"
|
||||
#include "engine_configuration.h"
|
||||
#include "listener_array.h"
|
||||
#include "wave_math.h"
|
||||
#include "data_buffer.h"
|
||||
#include "histogram.h"
|
||||
#if EFI_PROD_CODE
|
||||
|
@ -63,6 +62,10 @@ TriggerCentral::TriggerCentral() {
|
|||
clearCallbacks(&triggerListeneres);
|
||||
}
|
||||
|
||||
int TriggerCentral::getHwEventCounter(int index) {
|
||||
return hwEventCounters[index];
|
||||
}
|
||||
|
||||
void TriggerCentral::handleShaftSignal(configuration_s *configuration, trigger_event_e signal, uint64_t nowUs) {
|
||||
efiAssertVoid(configuration!=NULL, "configuration");
|
||||
|
||||
|
@ -81,7 +84,7 @@ void TriggerCentral::handleShaftSignal(configuration_s *configuration, trigger_e
|
|||
* We are here if there is a time gap between now and previous shaft event - that means the engine is not runnig.
|
||||
* That means we have lost synchronization since the engine is not running :)
|
||||
*/
|
||||
triggerState.shaft_is_synchronized = FALSE;
|
||||
triggerState.shaft_is_synchronized = false;
|
||||
}
|
||||
previousShaftEventTime = nowUs;
|
||||
|
||||
|
@ -92,16 +95,19 @@ void TriggerCentral::handleShaftSignal(configuration_s *configuration, trigger_e
|
|||
*/
|
||||
triggerState.decodeTriggerEvent(triggerShape, &configuration->engineConfiguration->triggerConfig, signal, nowUs);
|
||||
|
||||
if (!triggerState.shaft_is_synchronized)
|
||||
return; // we should not propagate event if we do not know where we are
|
||||
if (!triggerState.shaft_is_synchronized) {
|
||||
// we should not propagate event if we do not know where we are
|
||||
return;
|
||||
}
|
||||
|
||||
if (triggerState.getCurrentIndex() >= configuration->engineConfiguration2->triggerShape.shaftPositionEventCount) {
|
||||
int f = warning(OBD_PCM_Processor_Fault, "unexpected eventIndex=%d", triggerState.getCurrentIndex());
|
||||
if (!f) {
|
||||
#if EFI_PROD_CODE
|
||||
// this temporary code is about trigger noise debugging
|
||||
for (int i = 0; i < HW_EVENT_TYPES; i++)
|
||||
for (int i = 0; i < HW_EVENT_TYPES; i++) {
|
||||
scheduleMsg(&logging, "event type: %d count=%d", i, hwEventCounters[i]);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
} else {
|
||||
|
@ -110,7 +116,7 @@ void TriggerCentral::handleShaftSignal(configuration_s *configuration, trigger_e
|
|||
* cycle into a four stroke, 720 degrees cycle. TODO
|
||||
*/
|
||||
int triggerIndexForListeners;
|
||||
if( getOperationMode(configuration->engineConfiguration) == FOUR_STROKE_CAM_SENSOR) {
|
||||
if (getOperationMode(configuration->engineConfiguration) == FOUR_STROKE_CAM_SENSOR) {
|
||||
// That's easy - trigger cycle matches engine cycle
|
||||
triggerIndexForListeners = triggerState.getCurrentIndex();
|
||||
} else {
|
||||
|
@ -119,7 +125,6 @@ void TriggerCentral::handleShaftSignal(configuration_s *configuration, trigger_e
|
|||
triggerIndexForListeners = triggerState.getCurrentIndex() + (isEven ? 0 : triggerShape->getSize());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Here we invoke all the listeners - the main engine control logic is inside these listeners
|
||||
*/
|
||||
|
@ -130,7 +135,7 @@ void TriggerCentral::handleShaftSignal(configuration_s *configuration, trigger_e
|
|||
int diff = afterCallback - beforeCallback;
|
||||
// this counter is only 32 bits so it overflows every minute, let's ignore the value in case of the overflow for simplicity
|
||||
if (diff > 0)
|
||||
hsAdd(&triggerCallback, diff);
|
||||
hsAdd(&triggerCallback, diff);
|
||||
#endif /* EFI_HISTOGRAMS */
|
||||
}
|
||||
|
||||
|
@ -140,9 +145,18 @@ void printAllCallbacksHistogram(void) {
|
|||
#endif
|
||||
}
|
||||
|
||||
static void triggerInfo() {
|
||||
#if EFI_PROD_CODE
|
||||
scheduleMsg(&logging, "trigger %d/%d/%d/%d", triggerCentral.getHwEventCounter(0),
|
||||
triggerCentral.getHwEventCounter(1), triggerCentral.getHwEventCounter(2),
|
||||
triggerCentral.getHwEventCounter(3));
|
||||
#endif
|
||||
}
|
||||
|
||||
void initTriggerCentral(void) {
|
||||
#if EFI_PROD_CODE
|
||||
initLogging(&logging, "ShaftPosition");
|
||||
addConsoleAction("triggerinfo", triggerInfo);
|
||||
#endif
|
||||
|
||||
#if EFI_HISTOGRAMS
|
||||
|
|
|
@ -10,19 +10,21 @@
|
|||
|
||||
#include "rusefi_enums.h"
|
||||
#include "listener_array.h"
|
||||
#include "trigger_decoder.h"
|
||||
|
||||
typedef void (*ShaftPositionListener)(trigger_event_e signal, int index, void *arg);
|
||||
|
||||
#ifdef __cplusplus
|
||||
#include "ec2.h"
|
||||
|
||||
#define HW_EVENT_TYPES 4
|
||||
#define HW_EVENT_TYPES 6
|
||||
|
||||
class TriggerCentral {
|
||||
public:
|
||||
TriggerCentral();
|
||||
void addEventListener(ShaftPositionListener handler, const char *name, void *arg);
|
||||
void handleShaftSignal(configuration_s *configuration, trigger_event_e signal, uint64_t nowUs);
|
||||
int getHwEventCounter(int index);
|
||||
TriggerState triggerState;
|
||||
private:
|
||||
IntListenerArray triggerListeneres;
|
||||
|
|
|
@ -19,7 +19,7 @@ void configureNeonTriggerShape(trigger_shape_s *s) {
|
|||
// voodoo magic - we always need 720 at the end
|
||||
int base = 720 - 560;
|
||||
|
||||
s->initialState[0] = 1;
|
||||
s->initialState[T_PRIMARY] = 1;
|
||||
|
||||
s->addEvent(base - 720 + 600, T_SECONDARY, TV_HIGH);
|
||||
s->addEvent(base - 720 + 604, T_SECONDARY, TV_LOW);
|
||||
|
|
|
@ -26,13 +26,11 @@
|
|||
#include "trigger_chrysler.h"
|
||||
#include "trigger_gm.h"
|
||||
#include "trigger_bmw.h"
|
||||
#include "trigger_mitsubishi.h"
|
||||
|
||||
extern "C" {
|
||||
#include "trigger_structure.h"
|
||||
#include "wave_math.h"
|
||||
}
|
||||
|
||||
#if EFI_PROD_CODE || EFI_SIMULATOR
|
||||
#if (EFI_PROD_CODE || EFI_SIMULATOR) || defined(__DOXYGEN__)
|
||||
static Logging logger;
|
||||
#endif
|
||||
|
||||
|
@ -45,33 +43,43 @@ int isTriggerDecoderError(void) {
|
|||
return errorDetection.sum(6) > 4;
|
||||
}
|
||||
|
||||
static inline int isSynchronizationGap(TriggerState const *shaftPositionState, trigger_shape_s const *triggerShape,
|
||||
trigger_config_s const *triggerConfig, const int currentDuration) {
|
||||
if (!triggerShape->isSynchronizationNeeded)
|
||||
static inline bool isSynchronizationGap(TriggerState const *shaftPositionState, trigger_shape_s const *triggerShape,
|
||||
const int currentDuration) {
|
||||
if (!triggerShape->isSynchronizationNeeded) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return currentDuration > shaftPositionState->toothed_previous_duration * triggerShape->syncRatioFrom
|
||||
&& currentDuration < shaftPositionState->toothed_previous_duration * triggerShape->syncRatioTo;
|
||||
}
|
||||
|
||||
static inline int noSynchronizationResetNeeded(TriggerState *shaftPositionState, trigger_shape_s const *triggerShape,
|
||||
trigger_config_s const*triggerConfig) {
|
||||
if (triggerShape->isSynchronizationNeeded)
|
||||
static inline bool noSynchronizationResetNeeded(TriggerState *shaftPositionState, trigger_shape_s const *triggerShape) {
|
||||
if (triggerShape->isSynchronizationNeeded) {
|
||||
return false;
|
||||
if (!shaftPositionState->shaft_is_synchronized)
|
||||
return TRUE;
|
||||
}
|
||||
if (!shaftPositionState->shaft_is_synchronized) {
|
||||
return true;
|
||||
}
|
||||
/**
|
||||
* in case of noise the counter could be above the expected number of events
|
||||
*/
|
||||
return shaftPositionState->getCurrentIndex() >= triggerShape->shaftPositionEventCount - 1;
|
||||
}
|
||||
|
||||
static trigger_wheel_e eventIndex[6] = { T_PRIMARY, T_PRIMARY, T_SECONDARY, T_SECONDARY, T_CHANNEL_3, T_CHANNEL_3 };
|
||||
static trigger_value_e eventType[6] = { TV_LOW, TV_HIGH, TV_LOW, TV_HIGH, TV_LOW, TV_HIGH };
|
||||
|
||||
/**
|
||||
* @brief Trigger decoding happends here
|
||||
* @brief Trigger decoding happens here
|
||||
* This method changes the state of trigger_state_s data structure according to the trigger event
|
||||
*/
|
||||
void TriggerState::decodeTriggerEvent(trigger_shape_s const*triggerShape, trigger_config_s const*triggerConfig,
|
||||
trigger_event_e signal, uint64_t nowUs) {
|
||||
trigger_event_e const signal, uint64_t nowUs) {
|
||||
efiAssertVoid(signal <= SHAFT_3RD_UP, "unexpected signal");
|
||||
|
||||
trigger_wheel_e triggerWheel = eventIndex[signal];
|
||||
|
||||
eventCount[triggerWheel]++;
|
||||
|
||||
int isLessImportant = (triggerShape->useRiseEdge && signal != SHAFT_PRIMARY_UP)
|
||||
|| (!triggerShape->useRiseEdge && signal != SHAFT_PRIMARY_DOWN);
|
||||
|
@ -80,7 +88,7 @@ void TriggerState::decodeTriggerEvent(trigger_shape_s const*triggerShape, trigge
|
|||
/**
|
||||
* For less important events we simply increment the index.
|
||||
*/
|
||||
nextTriggerEvent();
|
||||
nextTriggerEvent(triggerWheel, nowUs);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -100,28 +108,37 @@ void TriggerState::decodeTriggerEvent(trigger_shape_s const*triggerShape, trigge
|
|||
}
|
||||
#endif
|
||||
|
||||
if (noSynchronizationResetNeeded(this, triggerShape, triggerConfig)
|
||||
|| isSynchronizationGap(this, triggerShape, triggerConfig, currentDuration)) {
|
||||
if (noSynchronizationResetNeeded(this, triggerShape) || isSynchronizationGap(this, triggerShape, currentDuration)) {
|
||||
/**
|
||||
* We can check if things are fine by comparing the number of events in a cycle with the expected number of event.
|
||||
*/
|
||||
int isDecodingError = getCurrentIndex() != triggerShape->shaftPositionEventCount - 1;
|
||||
bool isDecodingError = eventCount[0] != triggerShape->expectedEventCount[0]
|
||||
|| eventCount[1] != triggerShape->expectedEventCount[1]
|
||||
|| eventCount[2] != triggerShape->expectedEventCount[2];
|
||||
|
||||
errorDetection.add(isDecodingError);
|
||||
|
||||
if (isTriggerDecoderError())
|
||||
warning(OBD_PCM_Processor_Fault, "trigger decoding issue");
|
||||
if (isTriggerDecoderError()) {
|
||||
warning(OBD_PCM_Processor_Fault, "trigger decoding issue. expected %d/%d/%d got %d/%d/%d",
|
||||
triggerShape->expectedEventCount[0], triggerShape->expectedEventCount[1],
|
||||
triggerShape->expectedEventCount[2], eventCount[0], eventCount[1], eventCount[2]);
|
||||
}
|
||||
|
||||
shaft_is_synchronized = TRUE;
|
||||
nextRevolution(triggerShape->shaftPositionEventCount);
|
||||
shaft_is_synchronized = true;
|
||||
// this call would update duty cycle values
|
||||
// nextTriggerEvent(triggerWheel, nowUs);
|
||||
|
||||
nextRevolution(triggerShape->shaftPositionEventCount, nowUs);
|
||||
} else {
|
||||
nextTriggerEvent();
|
||||
nextTriggerEvent(triggerWheel, nowUs);
|
||||
}
|
||||
|
||||
toothed_previous_duration = currentDuration;
|
||||
toothed_previous_time = nowUs;
|
||||
}
|
||||
|
||||
static void initializeSkippedToothTriggerShape(trigger_shape_s *s, int totalTeethCount, int skippedCount, operation_mode_e operationMode) {
|
||||
static void initializeSkippedToothTriggerShape(trigger_shape_s *s, int totalTeethCount, int skippedCount,
|
||||
operation_mode_e operationMode) {
|
||||
efiAssertVoid(s != NULL, "trigger_shape_s is NULL");
|
||||
s->reset(operationMode);
|
||||
|
||||
|
@ -139,8 +156,8 @@ static void initializeSkippedToothTriggerShape(trigger_shape_s *s, int totalTeet
|
|||
s->addEvent(720, T_PRIMARY, TV_LOW);
|
||||
}
|
||||
|
||||
void initializeSkippedToothTriggerShapeExt(trigger_shape_s *s, int totalTeethCount,
|
||||
int skippedCount, operation_mode_e operationMode) {
|
||||
void initializeSkippedToothTriggerShapeExt(trigger_shape_s *s, int totalTeethCount, int skippedCount,
|
||||
operation_mode_e operationMode) {
|
||||
efiAssertVoid(totalTeethCount > 0, "totalTeethCount is zero");
|
||||
|
||||
s->totalToothCount = totalTeethCount;
|
||||
|
@ -185,17 +202,16 @@ void initializeTriggerShape(Logging *logger, engine_configuration_s *engineConfi
|
|||
triggerShape->useRiseEdge = TRUE;
|
||||
triggerShape->needSecondTriggerInput = TRUE;
|
||||
|
||||
|
||||
switch (triggerConfig->triggerType) {
|
||||
|
||||
case TT_TOOTHED_WHEEL:
|
||||
engineConfiguration2->triggerShape.needSecondTriggerInput = false;
|
||||
|
||||
engineConfiguration2->triggerShape.isSynchronizationNeeded = engineConfiguration->triggerConfig.customIsSynchronizationNeeded;
|
||||
engineConfiguration2->triggerShape.isSynchronizationNeeded =
|
||||
engineConfiguration->triggerConfig.customIsSynchronizationNeeded;
|
||||
|
||||
initializeSkippedToothTriggerShapeExt(triggerShape, triggerConfig->customTotalToothCount,
|
||||
triggerConfig->customSkippedToothCount,
|
||||
getOperationMode(engineConfiguration));
|
||||
triggerConfig->customSkippedToothCount, getOperationMode(engineConfiguration));
|
||||
return;
|
||||
|
||||
case TT_MAZDA_MIATA_NB:
|
||||
|
@ -231,6 +247,22 @@ void initializeTriggerShape(Logging *logger, engine_configuration_s *engineConfi
|
|||
setToothedWheelConfiguration(triggerShape, 36, 1, engineConfiguration);
|
||||
return;
|
||||
|
||||
case TT_HONDA_ACCORD_CD_TWO_WIRES:
|
||||
configureHondaAccordCD(triggerShape, false);
|
||||
return;
|
||||
|
||||
case TT_HONDA_ACCORD_CD:
|
||||
configureHondaAccordCD(triggerShape, true);
|
||||
return;
|
||||
|
||||
case TT_HONDA_ACCORD_CD_DIP:
|
||||
configureHondaAccordCDDip(triggerShape);
|
||||
return;
|
||||
|
||||
case TT_MITSU:
|
||||
initializeMitsubishi4g18(triggerShape);
|
||||
return;
|
||||
|
||||
default:
|
||||
firmwareError("initializeTriggerShape() not implemented: %d", triggerConfig->triggerType);
|
||||
;
|
||||
|
@ -244,7 +276,8 @@ TriggerStimulatorHelper::TriggerStimulatorHelper() {
|
|||
secondaryWheelState = false;
|
||||
}
|
||||
|
||||
void TriggerStimulatorHelper::nextStep(TriggerState *state, trigger_shape_s * shape, int i, trigger_config_s const*triggerConfig) {
|
||||
void TriggerStimulatorHelper::nextStep(TriggerState *state, trigger_shape_s * shape, int i,
|
||||
trigger_config_s const*triggerConfig) {
|
||||
int stateIndex = i % shape->getSize();
|
||||
|
||||
int loopIndex = i / shape->getSize();
|
||||
|
@ -267,6 +300,22 @@ void TriggerStimulatorHelper::nextStep(TriggerState *state, trigger_shape_s * sh
|
|||
}
|
||||
}
|
||||
|
||||
static void onFindIndex(TriggerState *state) {
|
||||
|
||||
}
|
||||
|
||||
static int doFindTrigger(TriggerStimulatorHelper *helper, trigger_shape_s * shape, trigger_config_s const*triggerConfig,
|
||||
TriggerState *state) {
|
||||
for (int i = 0; i < 4 * PWM_PHASE_MAX_COUNT; i++) {
|
||||
helper->nextStep(state, shape, i, triggerConfig);
|
||||
|
||||
if (state->shaft_is_synchronized)
|
||||
return i % shape->getSize();;
|
||||
}
|
||||
firmwareError("findTriggerZeroEventIndex() failed");
|
||||
return EFI_ERROR_CODE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Trigger shape is defined in a way which is convenient for trigger shape definition
|
||||
* On the other hand, trigger decoder indexing begins from synchronization event.
|
||||
|
@ -278,16 +327,23 @@ int findTriggerZeroEventIndex(trigger_shape_s * shape, trigger_config_s const*tr
|
|||
TriggerState state;
|
||||
errorDetection.clear();
|
||||
|
||||
|
||||
TriggerStimulatorHelper helper;
|
||||
|
||||
for (int i = 0; i < 4 * PWM_PHASE_MAX_COUNT; i++) {
|
||||
helper.nextStep(&state, shape, i, triggerConfig);
|
||||
|
||||
if (state.shaft_is_synchronized)
|
||||
return i % shape->getSize();;
|
||||
int index = doFindTrigger(&helper, shape, triggerConfig, &state);
|
||||
if (index == EFI_ERROR_CODE) {
|
||||
return index;
|
||||
}
|
||||
firmwareError("findTriggerZeroEventIndex() failed");
|
||||
return -1;
|
||||
/**
|
||||
* Now that we have just located the synch point, we can simulate the whole cycle
|
||||
* in order to calculate expected duty cycle
|
||||
*/
|
||||
|
||||
|
||||
state.cycleCallback = onFindIndex;
|
||||
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
void initTriggerDecoder(void) {
|
||||
|
|
|
@ -8,12 +8,52 @@
|
|||
#ifndef TRIGGER_DECODER_H_
|
||||
#define TRIGGER_DECODER_H_
|
||||
|
||||
#include <time.h>
|
||||
|
||||
#include "trigger_structure.h"
|
||||
#include "engine_configuration.h"
|
||||
#include "ec2.h"
|
||||
|
||||
class TriggerState;
|
||||
|
||||
typedef void (*TriggerStateCallback)(TriggerState *);
|
||||
|
||||
class TriggerState {
|
||||
public:
|
||||
TriggerState();
|
||||
int getCurrentIndex();
|
||||
int getTotalRevolutionCounter();
|
||||
uint64_t getTotalEventCounter();
|
||||
uint64_t getStartOfRevolutionIndex();
|
||||
void nextRevolution(int triggerEventCount, uint64_t nowUs);
|
||||
void nextTriggerEvent(trigger_wheel_e triggerWheel, uint64_t nowUs);
|
||||
void decodeTriggerEvent(trigger_shape_s const*triggerShape, trigger_config_s const*triggerConfig, trigger_event_e const signal, uint64_t nowUs);
|
||||
|
||||
TriggerStateCallback cycleCallback;
|
||||
|
||||
/**
|
||||
* TRUE if we know where we are
|
||||
*/
|
||||
unsigned char shaft_is_synchronized;
|
||||
|
||||
uint64_t toothed_previous_duration;
|
||||
uint64_t toothed_previous_time;
|
||||
private:
|
||||
void clear();
|
||||
/**
|
||||
* index within trigger revolution, from 0 to trigger event count
|
||||
*/
|
||||
int current_index;
|
||||
/**
|
||||
* Number of actual events within current trigger cycle
|
||||
* see trigger_shape_s
|
||||
*/
|
||||
int eventCount[PWM_PHASE_MAX_WAVE_PER_PWM];
|
||||
uint64_t timeOfPreviousEvent[PWM_PHASE_MAX_WAVE_PER_PWM];
|
||||
int totalTime[PWM_PHASE_MAX_WAVE_PER_PWM];
|
||||
uint64_t totalEventCountBase;
|
||||
int totalRevolutionCounter;
|
||||
bool isFirstEvent;
|
||||
};
|
||||
|
||||
class TriggerStimulatorHelper {
|
||||
public:
|
||||
TriggerStimulatorHelper();
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
#include "main.h"
|
||||
#include "trigger_emulator_algo.h"
|
||||
#include "engine_configuration.h"
|
||||
#include "wave_math.h"
|
||||
#include "LocalVersionHolder.h"
|
||||
#include "ec2.h"
|
||||
|
||||
|
@ -20,8 +19,9 @@ extern engine_configuration2_s *engineConfiguration2;
|
|||
*/
|
||||
static int pinStates1[PWM_PHASE_MAX_COUNT];
|
||||
static int pinStates2[PWM_PHASE_MAX_COUNT];
|
||||
static single_wave_s waves[2] = {single_wave_s(pinStates1), single_wave_s(pinStates2)};
|
||||
static single_wave_s sr[2] = {waves[0], waves[1]};
|
||||
static int pinStates3[PWM_PHASE_MAX_COUNT];
|
||||
static single_wave_s waves[PWM_PHASE_MAX_WAVE_PER_PWM] = {single_wave_s(pinStates1), single_wave_s(pinStates2), single_wave_s(pinStates3)};
|
||||
static single_wave_s sr[PWM_PHASE_MAX_WAVE_PER_PWM] = {waves[0], waves[1], waves[2]};
|
||||
|
||||
static float swtchTms[PWM_PHASE_MAX_COUNT];
|
||||
|
||||
|
@ -52,8 +52,8 @@ static void updateTriggerShapeIfNeeded(PwmConfig *state) {
|
|||
applyNonPersistentConfiguration(&logger, engineConfiguration, engineConfiguration2);
|
||||
|
||||
trigger_shape_s *s = &engineConfiguration2->triggerShape;
|
||||
int *pinStates[2] = {s->wave.waves[0].pinStates, s->wave.waves[1].pinStates};
|
||||
copyPwmParameters(state, s->getSize(), s->wave.switchTimes, 2, pinStates);
|
||||
int *pinStates[PWM_PHASE_MAX_WAVE_PER_PWM] = {s->wave.waves[0].pinStates, s->wave.waves[1].pinStates, s->wave.waves[2].pinStates};
|
||||
copyPwmParameters(state, s->getSize(), s->wave.switchTimes, PWM_PHASE_MAX_WAVE_PER_PWM, pinStates);
|
||||
state->safe.periodUs = -1; // this would cause loop re-initialization
|
||||
}
|
||||
}
|
||||
|
@ -64,10 +64,9 @@ void initTriggerEmulatorLogic(pwm_gen_callback *stateChangeCallback) {
|
|||
|
||||
trigger_shape_s *s = &engineConfiguration2->triggerShape;
|
||||
setTriggerEmulatorRPM(DEFAULT_EMULATION_RPM);
|
||||
int *pinStates[2] = { s->wave.waves[0].pinStates, s->wave.waves[1].pinStates};
|
||||
weComplexInit("position sensor", &triggerSignal, s->getSize(), s->wave.switchTimes, 2, pinStates,
|
||||
updateTriggerShapeIfNeeded,
|
||||
stateChangeCallback);
|
||||
int *pinStates[PWM_PHASE_MAX_WAVE_PER_PWM] = { s->wave.waves[0].pinStates, s->wave.waves[1].pinStates, s->wave.waves[2].pinStates};
|
||||
weComplexInit("position sensor", &triggerSignal, s->getSize(), s->wave.switchTimes, PWM_PHASE_MAX_WAVE_PER_PWM, pinStates,
|
||||
updateTriggerShapeIfNeeded, stateChangeCallback);
|
||||
|
||||
addConsoleActionI("rpm", &setTriggerEmulatorRPM);
|
||||
|
||||
|
|
|
@ -16,25 +16,25 @@ void configureGmTriggerShape(trigger_config_s *triggerConfig, trigger_shape_s *s
|
|||
s->shaftPositionEventCount = 14;
|
||||
|
||||
s->addEvent(120 - w, T_PRIMARY, TV_HIGH);
|
||||
s->addEvent(120, T_PRIMARY, TV_LOW);
|
||||
s->addEvent(120.0, T_PRIMARY, TV_LOW);
|
||||
|
||||
s->addEvent(240 - w, T_PRIMARY, TV_HIGH);
|
||||
s->addEvent(240, T_PRIMARY, TV_LOW);
|
||||
s->addEvent(240.0, T_PRIMARY, TV_LOW);
|
||||
|
||||
s->addEvent(360 - w, T_PRIMARY, TV_HIGH);
|
||||
s->addEvent(360, T_PRIMARY, TV_LOW);
|
||||
s->addEvent(360.0, T_PRIMARY, TV_LOW);
|
||||
|
||||
s->addEvent(480 - w, T_PRIMARY, TV_HIGH);
|
||||
s->addEvent(480, T_PRIMARY, TV_LOW);
|
||||
s->addEvent(480.0, T_PRIMARY, TV_LOW);
|
||||
|
||||
s->addEvent(600 - w, T_PRIMARY, TV_HIGH);
|
||||
s->addEvent(600, T_PRIMARY, TV_LOW);
|
||||
s->addEvent(600.0, T_PRIMARY, TV_LOW);
|
||||
|
||||
s->addEvent(700 - w, T_PRIMARY, TV_HIGH);
|
||||
s->addEvent(700, T_PRIMARY, TV_LOW);
|
||||
s->addEvent(700.0, T_PRIMARY, TV_LOW);
|
||||
|
||||
s->addEvent(720 - w, T_PRIMARY, TV_HIGH);
|
||||
s->addEvent(720, T_PRIMARY, TV_LOW);
|
||||
s->addEvent(720.0, T_PRIMARY, TV_LOW);
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
#include "trigger_mazda.h"
|
||||
|
||||
void initializeMazdaMiataNbShape(trigger_shape_s *s) {
|
||||
setTriggerSynchronizationGap(s, 0.11);
|
||||
setTriggerSynchronizationGap(s, 0.11f);
|
||||
s->useRiseEdge = false;
|
||||
|
||||
s->reset(FOUR_STROKE_CAM_SENSOR);
|
||||
|
@ -29,33 +29,33 @@ void initializeMazdaMiataNbShape(trigger_shape_s *s) {
|
|||
/**
|
||||
* cam sensor is primary, crank sensor is secondary
|
||||
*/
|
||||
s->addEvent(20, T_PRIMARY, TV_HIGH);
|
||||
s->addEvent(20.0f, T_PRIMARY, TV_HIGH);
|
||||
|
||||
s->addEvent(66, T_SECONDARY, TV_LOW);
|
||||
s->addEvent(70, T_SECONDARY, TV_HIGH);
|
||||
s->addEvent(136, T_SECONDARY, TV_LOW);
|
||||
s->addEvent(140, T_SECONDARY, TV_HIGH);
|
||||
s->addEvent(246, T_SECONDARY, TV_LOW);
|
||||
s->addEvent(250, T_SECONDARY, TV_HIGH);
|
||||
s->addEvent(316, T_SECONDARY, TV_LOW);
|
||||
s->addEvent(320, T_SECONDARY, TV_HIGH);
|
||||
s->addEvent(66.0f, T_SECONDARY, TV_LOW);
|
||||
s->addEvent(70.0f, T_SECONDARY, TV_HIGH);
|
||||
s->addEvent(136.0f, T_SECONDARY, TV_LOW);
|
||||
s->addEvent(140.0f, T_SECONDARY, TV_HIGH);
|
||||
s->addEvent(246.0f, T_SECONDARY, TV_LOW);
|
||||
s->addEvent(250.0f, T_SECONDARY, TV_HIGH);
|
||||
s->addEvent(316.0f, T_SECONDARY, TV_LOW);
|
||||
s->addEvent(320.0f, T_SECONDARY, TV_HIGH);
|
||||
|
||||
s->addEvent(340, T_PRIMARY, TV_LOW);
|
||||
s->addEvent(360, T_PRIMARY, TV_HIGH);
|
||||
s->addEvent(340.0f, T_PRIMARY, TV_LOW);
|
||||
s->addEvent(360.0f, T_PRIMARY, TV_HIGH);
|
||||
|
||||
s->addEvent(380, T_PRIMARY, TV_LOW);
|
||||
s->addEvent(400, T_PRIMARY, TV_HIGH);
|
||||
s->addEvent(380.0f, T_PRIMARY, TV_LOW);
|
||||
s->addEvent(400.0f, T_PRIMARY, TV_HIGH);
|
||||
|
||||
s->addEvent(426, T_SECONDARY, TV_LOW);
|
||||
s->addEvent(430, T_SECONDARY, TV_HIGH);
|
||||
s->addEvent(496, T_SECONDARY, TV_LOW);
|
||||
s->addEvent(500, T_SECONDARY, TV_HIGH);
|
||||
s->addEvent(606, T_SECONDARY, TV_LOW);
|
||||
s->addEvent(610, T_SECONDARY, TV_HIGH);
|
||||
s->addEvent(676, T_SECONDARY, TV_LOW);
|
||||
s->addEvent(680, T_SECONDARY, TV_HIGH);
|
||||
s->addEvent(426.0f, T_SECONDARY, TV_LOW);
|
||||
s->addEvent(430.0f, T_SECONDARY, TV_HIGH);
|
||||
s->addEvent(496.0f, T_SECONDARY, TV_LOW);
|
||||
s->addEvent(500.0f, T_SECONDARY, TV_HIGH);
|
||||
s->addEvent(606.0f, T_SECONDARY, TV_LOW);
|
||||
s->addEvent(610.0f, T_SECONDARY, TV_HIGH);
|
||||
s->addEvent(676.0f, T_SECONDARY, TV_LOW);
|
||||
s->addEvent(680.0f, T_SECONDARY, TV_HIGH);
|
||||
|
||||
s->addEvent(720, T_PRIMARY, TV_LOW);
|
||||
s->addEvent(720.0f, T_PRIMARY, TV_LOW);
|
||||
|
||||
s->shaftPositionEventCount = 6 + 16;
|
||||
}
|
||||
|
@ -68,7 +68,7 @@ void configureMazdaProtegeLx(trigger_shape_s *s) {
|
|||
s->reset(FOUR_STROKE_CAM_SENSOR);
|
||||
// s->initialState[0] = 1;
|
||||
|
||||
float w = 720 / 4 * 0.215;
|
||||
// float w = 720 / 4 * 0.215;
|
||||
float a = 5;
|
||||
// s->addEvent(a, T_SECONDARY, TV_LOW);
|
||||
// s->addEvent(a + w, T_SECONDARY, TV_HIGH);
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
/**
|
||||
* @file trigger_mitsubishi.cpp
|
||||
*
|
||||
* @date Aug 5, 2014
|
||||
* @author Andrey Belomutskiy, (c) 2012-2014
|
||||
*/
|
||||
|
||||
#include "trigger_mitsubishi.h"
|
||||
|
||||
void initializeMitsubishi4g18(trigger_shape_s *s) {
|
||||
s->reset(FOUR_STROKE_CAM_SENSOR);
|
||||
s->useRiseEdge = false;
|
||||
|
||||
setTriggerSynchronizationGap(s, 1.6666);
|
||||
|
||||
int secondaryWidth = 70;
|
||||
|
||||
s->addEvent(180.0 - 131 + 5, T_PRIMARY, TV_HIGH);
|
||||
s->addEvent(180.0 - secondaryWidth, T_SECONDARY, TV_HIGH);
|
||||
s->addEvent(180.0, T_SECONDARY, TV_LOW);
|
||||
s->addEvent(180.0 + 49 + 5, T_PRIMARY, TV_LOW);
|
||||
|
||||
s->addEvent(360.0 - secondaryWidth, T_SECONDARY, TV_HIGH);
|
||||
s->addEvent(360.0, T_SECONDARY, TV_LOW);
|
||||
|
||||
s->addEvent(540.0 - 131 + 5, T_PRIMARY, TV_HIGH);
|
||||
s->addEvent(540.0 - secondaryWidth, T_SECONDARY, TV_HIGH);
|
||||
s->addEvent(540.0 - 131 + 5 + 90, T_PRIMARY, TV_LOW);
|
||||
s->addEvent(540.0, T_SECONDARY, TV_LOW);
|
||||
|
||||
s->addEvent(720.0 - secondaryWidth, T_SECONDARY, TV_HIGH);
|
||||
s->addEvent(720.0, T_SECONDARY, TV_LOW);
|
||||
|
||||
s->shaftPositionEventCount = s->getSize();
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
/**
|
||||
* @file trigger_mitsubishi.h
|
||||
*
|
||||
* @date Aug 5, 2014
|
||||
* @author Andrey Belomutskiy, (c) 2012-2014
|
||||
*/
|
||||
#ifndef TRIGGER_MITSUBISHI_H_
|
||||
#define TRIGGER_MITSUBISHI_H_
|
||||
|
||||
#include "trigger_structure.h"
|
||||
|
||||
void initializeMitsubishi4g18(trigger_shape_s *s);
|
||||
|
||||
#endif /* TRIGGER_MITSUBISHI_H_ */
|
|
@ -24,17 +24,18 @@
|
|||
#include "trigger_decoder.h"
|
||||
|
||||
trigger_shape_helper::trigger_shape_helper() {
|
||||
waves[0].init(pinStates0);
|
||||
waves[1].init(pinStates1);
|
||||
for (int i = 0; i < TRIGGER_CHANNEL_COUNT; i++) {
|
||||
waves[i].init(pinStates[i]);
|
||||
}
|
||||
}
|
||||
|
||||
trigger_shape_s::trigger_shape_s() :
|
||||
wave(switchTimes, NULL) {
|
||||
wave(switchTimesBuffer, NULL) {
|
||||
reset(OM_NONE);
|
||||
wave.waves = h.waves;
|
||||
}
|
||||
|
||||
int trigger_shape_s::getSize() {
|
||||
int trigger_shape_s::getSize() const {
|
||||
return size;
|
||||
}
|
||||
|
||||
|
@ -46,6 +47,10 @@ int trigger_shape_s::getTriggerShapeSynchPointIndex() {
|
|||
int getEngineCycleEventCount2(operation_mode_e mode, trigger_shape_s * s);
|
||||
float fixAngle(float angle);
|
||||
|
||||
void trigger_shape_s::calculateTriggerSynchPoint(trigger_config_s const*triggerConfig) {
|
||||
setTriggerShapeSynchPointIndex(findTriggerZeroEventIndex(this, triggerConfig));
|
||||
}
|
||||
|
||||
void trigger_shape_s::setTriggerShapeSynchPointIndex(int triggerShapeSynchPointIndex) {
|
||||
this->triggerShapeSynchPointIndex = triggerShapeSynchPointIndex;
|
||||
|
||||
|
@ -69,7 +74,8 @@ void trigger_shape_s::reset(operation_mode_e operationMode) {
|
|||
shaftPositionEventCount = 0;
|
||||
triggerShapeSynchPointIndex = 0;
|
||||
memset(initialState, 0, sizeof(initialState));
|
||||
memset(switchTimes, 0, sizeof(switchTimes));
|
||||
memset(switchTimesBuffer, 0, sizeof(switchTimesBuffer));
|
||||
memset(expectedEventCount, 0, sizeof(expectedEventCount));
|
||||
wave.reset();
|
||||
previousAngle = 0;
|
||||
}
|
||||
|
@ -78,11 +84,32 @@ int multi_wave_s::getChannelState(int channelIndex, int phaseIndex) const {
|
|||
return waves[channelIndex].pinStates[phaseIndex];
|
||||
}
|
||||
|
||||
int multi_wave_s::waveIndertionAngle(float angle, int size) const {
|
||||
for (int i = size - 1; i >= 0; i--) {
|
||||
if (angle > switchTimes[i])
|
||||
return i + 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int multi_wave_s::findAngleMatch(float angle, int size) const {
|
||||
for (int i = 0; i < size; i++) {
|
||||
if (isSameF(switchTimes[i], angle))
|
||||
return i;
|
||||
}
|
||||
return EFI_ERROR_CODE;
|
||||
}
|
||||
|
||||
void multi_wave_s::setSwitchTime(int index, float value) {
|
||||
switchTimes[index] = value;
|
||||
}
|
||||
|
||||
TriggerState::TriggerState() {
|
||||
cycleCallback = NULL;
|
||||
shaft_is_synchronized = FALSE;
|
||||
toothed_previous_time = 0;
|
||||
toothed_previous_duration = 0;
|
||||
totalRevolutionCounter = 0;
|
||||
clear();
|
||||
totalEventCountBase = 0;
|
||||
isFirstEvent = true;
|
||||
|
@ -100,8 +127,11 @@ uint64_t TriggerState::getTotalEventCounter() {
|
|||
return totalEventCountBase + current_index;
|
||||
}
|
||||
|
||||
void TriggerState::nextRevolution(int triggerEventCount) {
|
||||
current_index = 0;
|
||||
void TriggerState::nextRevolution(int triggerEventCount, uint64_t nowUs) {
|
||||
if (cycleCallback != NULL) {
|
||||
cycleCallback(this);
|
||||
}
|
||||
clear();
|
||||
totalRevolutionCounter++;
|
||||
totalEventCountBase += triggerEventCount;
|
||||
}
|
||||
|
@ -110,21 +140,29 @@ int TriggerState::getTotalRevolutionCounter() {
|
|||
return totalRevolutionCounter;
|
||||
}
|
||||
|
||||
void TriggerState::nextTriggerEvent() {
|
||||
void TriggerState::nextTriggerEvent(trigger_wheel_e triggerWheel, uint64_t nowUs) {
|
||||
uint64_t prevTime = timeOfPreviousEvent[triggerWheel];
|
||||
if (prevTime != 0) {
|
||||
totalTime[triggerWheel] += (nowUs - prevTime);
|
||||
timeOfPreviousEvent[triggerWheel] = 0;
|
||||
} else {
|
||||
timeOfPreviousEvent[triggerWheel] = nowUs;
|
||||
}
|
||||
|
||||
current_index++;
|
||||
}
|
||||
|
||||
void TriggerState::clear() {
|
||||
shaft_is_synchronized = FALSE;
|
||||
toothed_previous_time = 0;
|
||||
toothed_previous_duration = 0;
|
||||
memset(eventCount, 0, sizeof(eventCount));
|
||||
memset(timeOfPreviousEvent, 0, sizeof(timeOfPreviousEvent));
|
||||
memset(totalTime, 0, sizeof(totalTime));
|
||||
current_index = 0;
|
||||
totalRevolutionCounter = 0;
|
||||
}
|
||||
|
||||
float trigger_shape_s::getAngle(int index) const {
|
||||
if (operationMode == FOUR_STROKE_CAM_SENSOR)
|
||||
return switchAngles[index];
|
||||
if (operationMode == FOUR_STROKE_CAM_SENSOR) {
|
||||
return getSwitchAngle(index);
|
||||
}
|
||||
/**
|
||||
* FOUR_STROKE_CRANK_SENSOR magic:
|
||||
* We have two crank shaft revolutions for each engine cycle
|
||||
|
@ -134,20 +172,29 @@ float trigger_shape_s::getAngle(int index) const {
|
|||
int triggerEventCounter = size;
|
||||
|
||||
if (index < triggerEventCounter) {
|
||||
return switchAngles[index];
|
||||
return getSwitchAngle(index);
|
||||
} else {
|
||||
return 360 + switchAngles[index - triggerEventCounter];
|
||||
return 360 + getSwitchAngle(index - triggerEventCounter);
|
||||
}
|
||||
}
|
||||
|
||||
void trigger_shape_s::addEvent(float angle, trigger_wheel_e waveIndex, trigger_value_e state) {
|
||||
void trigger_shape_s::addEvent(float angle, trigger_wheel_e const waveIndex, trigger_value_e const state) {
|
||||
efiAssertVoid(operationMode != OM_NONE, "operationMode not set");
|
||||
/**
|
||||
* While '720' value works perfectly it has not much sense for crank sensor-only scenario.
|
||||
* todo: accept angle as a value in the 0..1 range?
|
||||
*/
|
||||
angle /= 720;
|
||||
efiAssertVoid(angle > previousAngle, "invalid angle order");
|
||||
|
||||
expectedEventCount[waveIndex]++;
|
||||
|
||||
efiAssertVoid(angle > 0, "angle should be positive");
|
||||
if (size > 0) {
|
||||
if (angle <= previousAngle) {
|
||||
firmwareError("invalid angle order: %f and %f", angle, previousAngle);
|
||||
return;
|
||||
}
|
||||
}
|
||||
previousAngle = angle;
|
||||
if (size == 0) {
|
||||
size = 1;
|
||||
|
@ -165,46 +212,203 @@ void trigger_shape_s::addEvent(float angle, trigger_wheel_e waveIndex, trigger_v
|
|||
wave->pinStates[0] = initialState[i];
|
||||
}
|
||||
|
||||
setSwitchTime(0, angle);
|
||||
wave.setSwitchTime(0, angle);
|
||||
wave.waves[waveIndex].pinStates[0] = state;
|
||||
return;
|
||||
}
|
||||
|
||||
// if(angle!=trigger->wave.switchTimes[trigger->currentIndex])
|
||||
int exactMatch = wave.findAngleMatch(angle, size);
|
||||
if (exactMatch != EFI_ERROR_CODE) {
|
||||
firmwareError("same angle: not supported");
|
||||
return;
|
||||
}
|
||||
|
||||
int index = size++;
|
||||
int index = wave.waveIndertionAngle(angle, size);
|
||||
|
||||
for (int i = 0; i < PWM_PHASE_MAX_WAVE_PER_PWM; i++)
|
||||
// shifting existing data
|
||||
for (int i = size - 1; i >= index; i--) {
|
||||
for (int j = 0; j < PWM_PHASE_MAX_WAVE_PER_PWM; j++) {
|
||||
wave.waves[j].pinStates[i + 1] = wave.getChannelState(j, index);
|
||||
}
|
||||
wave.setSwitchTime(i + 1, wave.getSwitchTime(i));
|
||||
}
|
||||
|
||||
// int index = size;
|
||||
size++;
|
||||
|
||||
for (int i = 0; i < PWM_PHASE_MAX_WAVE_PER_PWM; i++) {
|
||||
wave.waves[i].pinStates[index] = wave.getChannelState(i, index - 1);
|
||||
setSwitchTime(index, angle);
|
||||
}
|
||||
wave.setSwitchTime(index, angle);
|
||||
wave.waves[waveIndex].pinStates[index] = state;
|
||||
}
|
||||
|
||||
void trigger_shape_s::setSwitchTime(int index, float angle) {
|
||||
int cycleDuration = (operationMode == FOUR_STROKE_CAM_SENSOR) ? 720 : 360;
|
||||
switchAngles[index] = cycleDuration * angle;
|
||||
wave.setSwitchTime(index, angle);
|
||||
int trigger_shape_s::getCycleDuration() const {
|
||||
return (operationMode == FOUR_STROKE_CAM_SENSOR) ? 720 : 360;
|
||||
}
|
||||
|
||||
float trigger_shape_s::getSwitchAngle(int index) const {
|
||||
return getCycleDuration() * wave.getSwitchTime(index);
|
||||
}
|
||||
|
||||
void multi_wave_s::checkSwitchTimes(int size) {
|
||||
checkSwitchTimes2(size, switchTimes);
|
||||
}
|
||||
|
||||
void setToothedWheelConfiguration(trigger_shape_s *s, int total, int skipped, engine_configuration_s const *engineConfiguration) {
|
||||
void setToothedWheelConfiguration(trigger_shape_s *s, int total, int skipped,
|
||||
engine_configuration_s const *engineConfiguration) {
|
||||
s->isSynchronizationNeeded = (skipped != 0);
|
||||
|
||||
s->totalToothCount = total;
|
||||
s->skippedToothCount = skipped;
|
||||
s->needSecondTriggerInput = false;
|
||||
s->useRiseEdge = TRUE;
|
||||
s->useRiseEdge = true;
|
||||
|
||||
initializeSkippedToothTriggerShapeExt(s, s->totalToothCount,
|
||||
s->skippedToothCount,
|
||||
initializeSkippedToothTriggerShapeExt(s, s->totalToothCount, s->skippedToothCount,
|
||||
getOperationMode(engineConfiguration));
|
||||
}
|
||||
|
||||
void setTriggerSynchronizationGap(trigger_shape_s *s, float synchGap) {
|
||||
s->isSynchronizationNeeded = TRUE;
|
||||
s->isSynchronizationNeeded = true;
|
||||
s->syncRatioFrom = synchGap * 0.75;
|
||||
s->syncRatioTo = synchGap * 1.25;
|
||||
}
|
||||
|
||||
#define S24 (720.0f / 24 / 2)
|
||||
|
||||
static float addAccordPair(trigger_shape_s *s, float sb) {
|
||||
s->addEvent(sb, T_SECONDARY, TV_HIGH);
|
||||
sb += S24;
|
||||
s->addEvent(sb, T_SECONDARY, TV_LOW);
|
||||
sb += S24;
|
||||
|
||||
return sb;
|
||||
}
|
||||
|
||||
#define DIP 7.5f
|
||||
static float addAccordPair3(trigger_shape_s *s, float sb) {
|
||||
sb += DIP;
|
||||
s->addEvent(sb, T_CHANNEL_3, TV_HIGH);
|
||||
sb += DIP;
|
||||
s->addEvent(sb, T_CHANNEL_3, TV_LOW);
|
||||
sb += 2 * DIP;
|
||||
return sb;
|
||||
}
|
||||
|
||||
/**
|
||||
* Thank you Dip!
|
||||
* http://forum.pgmfi.org/viewtopic.php?f=2&t=15570start=210#p139007
|
||||
*/
|
||||
void configureHondaAccordCDDip(trigger_shape_s *s) {
|
||||
s->reset(FOUR_STROKE_CAM_SENSOR);
|
||||
|
||||
s->initialState[T_SECONDARY] = TV_HIGH;
|
||||
float sb = 0;
|
||||
sb = addAccordPair3(s, sb);
|
||||
sb = addAccordPair3(s, sb);
|
||||
sb = addAccordPair3(s, sb);
|
||||
|
||||
s->addEvent(90, T_SECONDARY, TV_LOW);
|
||||
sb = 90;
|
||||
sb = addAccordPair3(s, sb);
|
||||
sb = addAccordPair3(s, sb);
|
||||
sb = addAccordPair3(s, sb);
|
||||
|
||||
s->addEvent(180, T_SECONDARY, TV_HIGH);
|
||||
sb = 180;
|
||||
sb = addAccordPair3(s, sb);
|
||||
sb = addAccordPair3(s, sb);
|
||||
sb = addAccordPair3(s, sb);
|
||||
|
||||
s->addEvent(270, T_SECONDARY, TV_LOW);
|
||||
sb = 270;
|
||||
sb = addAccordPair3(s, sb);
|
||||
sb = addAccordPair3(s, sb);
|
||||
sb = addAccordPair3(s, sb);
|
||||
|
||||
|
||||
s->addEvent(360.0f - DIP, T_PRIMARY, TV_HIGH);
|
||||
s->addEvent(360, T_SECONDARY, TV_HIGH);
|
||||
sb = 360;
|
||||
sb = addAccordPair3(s, sb);
|
||||
sb = addAccordPair3(s, sb);
|
||||
sb = addAccordPair3(s, sb);
|
||||
|
||||
s->addEvent(450, T_SECONDARY, TV_LOW);
|
||||
sb = 450;
|
||||
sb = addAccordPair3(s, sb);
|
||||
sb = addAccordPair3(s, sb);
|
||||
sb = addAccordPair3(s, sb);
|
||||
|
||||
s->addEvent(540, T_SECONDARY, TV_HIGH);
|
||||
sb = 540;
|
||||
sb = addAccordPair3(s, sb);
|
||||
sb = addAccordPair3(s, sb);
|
||||
sb = addAccordPair3(s, sb);
|
||||
|
||||
s->addEvent(630, T_SECONDARY, TV_LOW);
|
||||
sb = 630;
|
||||
sb = addAccordPair3(s, sb);
|
||||
sb = addAccordPair3(s, sb);
|
||||
sb = addAccordPair3(s, sb);
|
||||
|
||||
s->addEvent(720.0f - DIP, T_PRIMARY, TV_LOW);
|
||||
|
||||
// s->addEvent(720.0f - 12 * sb, T_SECONDARY, TV_LOW);
|
||||
// s->addEvent(720.0f, T_SECONDARY, TV_LOW);
|
||||
|
||||
s->addEvent(720.0f, T_SECONDARY, TV_HIGH);
|
||||
|
||||
s->isSynchronizationNeeded = false;
|
||||
|
||||
s->shaftPositionEventCount = s->getSize();
|
||||
}
|
||||
|
||||
void configureHondaAccordCD(trigger_shape_s *s, bool with3rdSignal) {
|
||||
s->reset(FOUR_STROKE_CAM_SENSOR);
|
||||
|
||||
float sb = 5.0f;
|
||||
|
||||
float tdcWidth = 0.1854 * 720 / 4;
|
||||
|
||||
s->isSynchronizationNeeded = false;
|
||||
|
||||
sb = addAccordPair(s, sb);
|
||||
|
||||
if (with3rdSignal)
|
||||
s->addEvent(sb - S24 / 2, T_CHANNEL_3, TV_HIGH);
|
||||
|
||||
sb = addAccordPair(s, sb);
|
||||
sb = addAccordPair(s, sb);
|
||||
if (with3rdSignal)
|
||||
s->addEvent(sb - S24 / 2, T_CHANNEL_3, TV_LOW);
|
||||
sb = addAccordPair(s, sb);
|
||||
sb = addAccordPair(s, sb);
|
||||
s->addEvent(1 * 180.0f - tdcWidth, T_PRIMARY, TV_HIGH);
|
||||
sb = addAccordPair(s, sb);
|
||||
s->addEvent(1 * 180.0f, T_PRIMARY, TV_LOW);
|
||||
|
||||
sb = addAccordPair(s, sb);
|
||||
sb = addAccordPair(s, sb);
|
||||
sb = addAccordPair(s, sb);
|
||||
sb = addAccordPair(s, sb);
|
||||
sb = addAccordPair(s, sb);
|
||||
|
||||
s->addEvent(2 * 180.0f - tdcWidth, T_PRIMARY, TV_HIGH);
|
||||
sb = addAccordPair(s, sb);
|
||||
s->addEvent(2 * 180.0f, T_PRIMARY, TV_LOW);
|
||||
|
||||
for (int i = 3; i <= 4; i++) {
|
||||
sb = addAccordPair(s, sb);
|
||||
sb = addAccordPair(s, sb);
|
||||
sb = addAccordPair(s, sb);
|
||||
sb = addAccordPair(s, sb);
|
||||
sb = addAccordPair(s, sb);
|
||||
|
||||
s->addEvent(i * 180.0f - tdcWidth, T_PRIMARY, TV_HIGH);
|
||||
sb = addAccordPair(s, sb);
|
||||
s->addEvent(i * 180.0f, T_PRIMARY, TV_LOW);
|
||||
}
|
||||
|
||||
s->shaftPositionEventCount = s->getSize();
|
||||
}
|
||||
|
|
|
@ -16,61 +16,19 @@
|
|||
|
||||
class trigger_shape_s;
|
||||
|
||||
class TriggerState {
|
||||
public:
|
||||
TriggerState();
|
||||
int getCurrentIndex();
|
||||
int getTotalRevolutionCounter();
|
||||
uint64_t getTotalEventCounter();
|
||||
uint64_t getStartOfRevolutionIndex();
|
||||
void nextRevolution(int triggerEventCount);
|
||||
void nextTriggerEvent();
|
||||
void decodeTriggerEvent(trigger_shape_s const*triggerShape, trigger_config_s const*triggerConfig, trigger_event_e signal, uint64_t nowUs);
|
||||
|
||||
|
||||
/**
|
||||
* TRUE if we know where we are
|
||||
*/
|
||||
unsigned char shaft_is_synchronized;
|
||||
|
||||
uint64_t toothed_previous_duration;
|
||||
uint64_t toothed_previous_time;
|
||||
private:
|
||||
void clear();
|
||||
/**
|
||||
* index within trigger revolution, from 0 to trigger event count
|
||||
*/
|
||||
int current_index;
|
||||
uint64_t totalEventCountBase;
|
||||
int totalRevolutionCounter;
|
||||
bool isFirstEvent;
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
TV_LOW = 0,
|
||||
TV_HIGH = 1
|
||||
} trigger_value_e;
|
||||
|
||||
typedef enum {
|
||||
T_PRIMARY = 0,
|
||||
T_SECONDARY = 1
|
||||
} trigger_wheel_e;
|
||||
#define TRIGGER_CHANNEL_COUNT 3
|
||||
|
||||
class trigger_shape_helper {
|
||||
int pinStates0[PWM_PHASE_MAX_COUNT];
|
||||
int pinStates1[PWM_PHASE_MAX_COUNT];
|
||||
int pinStates[TRIGGER_CHANNEL_COUNT][PWM_PHASE_MAX_COUNT];
|
||||
public:
|
||||
trigger_shape_helper();
|
||||
|
||||
single_wave_s waves[2];
|
||||
single_wave_s waves[TRIGGER_CHANNEL_COUNT];
|
||||
};
|
||||
|
||||
class trigger_shape_s {
|
||||
private:
|
||||
void setSwitchTime(int index, float angle);
|
||||
trigger_shape_helper h;
|
||||
int size;
|
||||
public:
|
||||
trigger_shape_s();
|
||||
int isSynchronizationNeeded;
|
||||
|
||||
int totalToothCount;
|
||||
|
@ -81,14 +39,15 @@ public:
|
|||
|
||||
int useRiseEdge;
|
||||
|
||||
/**
|
||||
* This is used for signal validation
|
||||
*/
|
||||
int expectedEventCount[PWM_PHASE_MAX_WAVE_PER_PWM];
|
||||
|
||||
bool needSecondTriggerInput;
|
||||
|
||||
|
||||
trigger_shape_s();
|
||||
void addEvent(float angle, trigger_wheel_e waveIndex, trigger_value_e state);
|
||||
float getAngle(int phaseIndex) const;
|
||||
void addEvent(float angle, trigger_wheel_e const waveIndex, trigger_value_e const state);
|
||||
void reset(operation_mode_e operationMode);
|
||||
int getSize();
|
||||
int getSize() const;
|
||||
multi_wave_s wave;
|
||||
|
||||
/**
|
||||
|
@ -102,16 +61,20 @@ public:
|
|||
// tood: maybe even automate this flag calculation?
|
||||
int initialState[PWM_PHASE_MAX_WAVE_PER_PWM];
|
||||
|
||||
|
||||
int getTriggerShapeSynchPointIndex();
|
||||
|
||||
void calculateTriggerSynchPoint(trigger_config_s const*triggerConfig);
|
||||
|
||||
void setTriggerShapeSynchPointIndex(int triggerShapeSynchPointIndex);
|
||||
/**
|
||||
* These angles are in event coordinates - with synchronization point located at angle zero.
|
||||
* These values are pre-calculated for performance reasons.
|
||||
*/
|
||||
float eventAngles[PWM_PHASE_MAX_COUNT];
|
||||
|
||||
private:
|
||||
trigger_shape_helper h;
|
||||
int size;
|
||||
/**
|
||||
* index of synchronization event within trigger_shape_s
|
||||
* See findTriggerZeroEventIndex()
|
||||
|
@ -120,20 +83,25 @@ private:
|
|||
/**
|
||||
* Values are in the 0..1 range
|
||||
*/
|
||||
float switchTimes[PWM_PHASE_MAX_COUNT];
|
||||
float switchTimesBuffer[PWM_PHASE_MAX_COUNT];
|
||||
/**
|
||||
* These are the same values as in switchTimes, but these are angles in the 0..360 or 0..720 range.
|
||||
* That's a performance optimization - this should save as one multiplication in a critical spot.
|
||||
*
|
||||
* These angles are in trigger DESCRIPTION coordinates - i.e. the way you add events while declaring trigger shape
|
||||
*/
|
||||
float switchAngles[PWM_PHASE_MAX_COUNT];
|
||||
float getSwitchAngle(int index) const;
|
||||
|
||||
float previousAngle;
|
||||
/**
|
||||
* this is part of performance optimization
|
||||
*/
|
||||
operation_mode_e operationMode;
|
||||
|
||||
/**
|
||||
* This private method should only be used to prepare the array of pre-calculated values
|
||||
* See eventAngles array
|
||||
*/
|
||||
float getAngle(int phaseIndex) const;
|
||||
|
||||
int getCycleDuration() const;
|
||||
};
|
||||
|
||||
void setTriggerSynchronizationGap(trigger_shape_s *s, float synchGap);
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
#include "status_loop.h"
|
||||
#include "engine_configuration.h"
|
||||
|
||||
#if EFI_ANALOG_CHART
|
||||
#if EFI_ANALOG_CHART || defined(__DOXYGEN__)
|
||||
|
||||
static char LOGGING_BUFFER[5000];
|
||||
static Logging logging;
|
||||
|
@ -22,8 +22,9 @@ static int initialized = FALSE;
|
|||
extern engine_configuration_s *engineConfiguration;
|
||||
|
||||
void acAddData(float angle, float value) {
|
||||
if (!initialized)
|
||||
if (!initialized) {
|
||||
return; // this is possible because of initialization sequence
|
||||
}
|
||||
|
||||
if( engineConfiguration->analogChartFrequency < 1) {
|
||||
//todofirmwareError()
|
||||
|
@ -35,8 +36,9 @@ void acAddData(float angle, float value) {
|
|||
// message terminator
|
||||
appendPrintf(&logging, DELIMETER);
|
||||
// output pending data
|
||||
if (getFullLog())
|
||||
if (getFullLog()) {
|
||||
scheduleLogging(&logging);
|
||||
}
|
||||
pendingData = FALSE;
|
||||
}
|
||||
return;
|
||||
|
@ -48,8 +50,9 @@ void acAddData(float angle, float value) {
|
|||
appendPrintf(&logging, "analog_chart%s", DELIMETER);
|
||||
}
|
||||
|
||||
if (remainingSize(&logging) > 100)
|
||||
if (remainingSize(&logging) > 100) {
|
||||
appendPrintf(&logging, "%f|%f|", angle, value);
|
||||
}
|
||||
}
|
||||
|
||||
void initAnalogChart(void) {
|
||||
|
|
|
@ -2,10 +2,10 @@
|
|||
EMULATIONSRC = emulation/hw_layer/poten.c \
|
||||
emulation/analog_chart.c \
|
||||
emulation/test/test.c \
|
||||
emulation/test/testbmk.c \
|
||||
emulation/wave_analyzer.c
|
||||
emulation/test/testbmk.c
|
||||
|
||||
EMULATIONSRC_CPP = emulation/trigger_emulator.cpp \
|
||||
emulation/rfi_perftest.cpp \
|
||||
emulation/engine_emulator.cpp
|
||||
emulation/engine_emulator.cpp \
|
||||
emulation/wave_analyzer.cpp
|
||||
|
||||
|
|
|
@ -38,16 +38,19 @@
|
|||
|
||||
SPIDriver * getDigiralPotDevice(spi_device_e spiDevice) {
|
||||
#if STM32_SPI_USE_SPI1 || defined(__DOXYGEN__)
|
||||
if (spiDevice == SPI_DEVICE_1)
|
||||
if (spiDevice == SPI_DEVICE_1) {
|
||||
return &SPID1;
|
||||
}
|
||||
#endif
|
||||
#if STM32_SPI_USE_SPI2 || defined(__DOXYGEN__)
|
||||
if (spiDevic e== SPI_DEVICE_2)
|
||||
if (spiDevic e== SPI_DEVICE_2) {
|
||||
return &SPID2;
|
||||
}
|
||||
#endif
|
||||
#if STM32_SPI_USE_SPI3 || defined(__DOXYGEN__)
|
||||
if (spiDevice == SPI_DEVICE_3)
|
||||
if (spiDevice == SPI_DEVICE_3) {
|
||||
return &SPID3;
|
||||
}
|
||||
#endif
|
||||
firmwareError("Unexpected SPI device: %d", spiDevice);
|
||||
return NULL;
|
||||
|
@ -58,7 +61,7 @@ SPIDriver * getDigiralPotDevice(spi_device_e spiDevice) {
|
|||
|
||||
static Logging logger;
|
||||
|
||||
#if EFI_POTENTIOMETER
|
||||
#if EFI_POTENTIOMETER || defined(__DOXYGEN__)
|
||||
Mcp42010Driver config[DIGIPOT_COUNT];
|
||||
|
||||
void initPotentiometer(Mcp42010Driver *driver, SPIDriver *spi, ioportid_t port, ioportmask_t pin) {
|
||||
|
@ -102,12 +105,8 @@ void setPotResistance(Mcp42010Driver *driver, int channel, int resistance) {
|
|||
sendToPot(driver, channel, value);
|
||||
}
|
||||
|
||||
static void setPotResistance0(int value) {
|
||||
setPotResistance(&config[0], 0, value);
|
||||
}
|
||||
|
||||
static void setPotResistance1(int value) {
|
||||
setPotResistance(&config[0], 1, value);
|
||||
static void setPotResistanceCommand(int index, int value) {
|
||||
setPotResistance(&config[index / 2], index % 2, value);
|
||||
}
|
||||
|
||||
static void setPotValue1(int value) {
|
||||
|
@ -127,20 +126,20 @@ void initPotentiometers(board_configuration_s *boardConfiguration) {
|
|||
|
||||
for (int i = 0; i < DIGIPOT_COUNT; i++) {
|
||||
brain_pin_e csPin = boardConfiguration->digitalPotentiometerChipSelect[i];
|
||||
if (csPin == GPIO_NONE)
|
||||
if (csPin == GPIO_NONE) {
|
||||
continue;
|
||||
}
|
||||
|
||||
initPotentiometer(&config[i], getDigiralPotDevice(boardConfiguration->digitalPotentiometerSpiDevice),
|
||||
getHwPort(csPin), getHwPin(csPin));
|
||||
}
|
||||
|
||||
addConsoleActionI("pot0", setPotResistance0);
|
||||
addConsoleActionI("pot1", setPotResistance1);
|
||||
addConsoleActionII("pot", setPotResistanceCommand);
|
||||
|
||||
addConsoleActionI("potd1", setPotValue1);
|
||||
|
||||
setPotResistance0(3000);
|
||||
setPotResistance1(7000);
|
||||
setPotResistance(&config[0], 0, 3000);
|
||||
setPotResistance(&config[0], 1, 7000);
|
||||
#else
|
||||
print("digiPot logic disabled\r\n");
|
||||
#endif
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
#include "console_io.h"
|
||||
#include "engine.h"
|
||||
|
||||
#if EFI_PERF_METRICS
|
||||
#if EFI_PERF_METRICS || defined(__DOXYGEN__)
|
||||
|
||||
static Logging logger;
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* @file trigger_emulator.c
|
||||
* @file trigger_emulator.cpp
|
||||
* @brief Position sensor(s) emulation code
|
||||
*
|
||||
* This file is mostly about initialization, the configuration is
|
||||
|
@ -14,30 +14,81 @@
|
|||
#include "main_trigger_callback.h"
|
||||
#include "datalogging.h"
|
||||
#include "engine_configuration.h"
|
||||
#if EFI_PROD_CODE
|
||||
#include "pwm_generator.h"
|
||||
#include "io_pins.h"
|
||||
#include "pin_repository.h"
|
||||
#endif
|
||||
#include "io_pins.h"
|
||||
#include "trigger_emulator_algo.h"
|
||||
#include "trigger_central.h"
|
||||
|
||||
extern engine_configuration_s *engineConfiguration;
|
||||
extern board_configuration_s *boardConfiguration;
|
||||
|
||||
extern PwmConfig triggerSignal;
|
||||
|
||||
TriggerEmulatorHelper::TriggerEmulatorHelper() {
|
||||
primaryWheelState = false;
|
||||
secondaryWheelState = false;
|
||||
thirdWheelState = false;
|
||||
}
|
||||
|
||||
void TriggerEmulatorHelper::handleEmulatorCallback(PwmConfig *state, int stateIndex) {
|
||||
int newPrimaryWheelState = state->multiWave.waves[0].pinStates[stateIndex];
|
||||
int newSecondaryWheelState = state->multiWave.waves[1].pinStates[stateIndex];
|
||||
int new3rdWheelState = state->multiWave.waves[2].pinStates[stateIndex];
|
||||
|
||||
if (primaryWheelState != newPrimaryWheelState) {
|
||||
primaryWheelState = newPrimaryWheelState;
|
||||
hwHandleShaftSignal(primaryWheelState ? SHAFT_PRIMARY_UP : SHAFT_PRIMARY_DOWN);
|
||||
}
|
||||
|
||||
if (secondaryWheelState != newSecondaryWheelState) {
|
||||
secondaryWheelState = newSecondaryWheelState;
|
||||
hwHandleShaftSignal(secondaryWheelState ? SHAFT_SECONDARY_UP : SHAFT_SECONDARY_DOWN);
|
||||
}
|
||||
|
||||
if (thirdWheelState != new3rdWheelState) {
|
||||
thirdWheelState = new3rdWheelState;
|
||||
hwHandleShaftSignal(thirdWheelState ? SHAFT_3RD_UP : SHAFT_3RD_DOWN);
|
||||
}
|
||||
|
||||
// print("hello %d\r\n", chTimeNow());
|
||||
}
|
||||
|
||||
static TriggerEmulatorHelper helper;
|
||||
|
||||
#if EFI_EMULATE_POSITION_SENSORS || defined(__DOXYGEN__)
|
||||
|
||||
static void emulatorApplyPinState(PwmConfig *state, int stateIndex) {
|
||||
if (engineConfiguration->directSelfStimulation) {
|
||||
helper.handleEmulatorCallback(state, stateIndex);
|
||||
}
|
||||
|
||||
applyPinState(state, stateIndex);
|
||||
}
|
||||
#endif /* EFI_EMULATE_POSITION_SENSORS */
|
||||
|
||||
void initTriggerEmulator(void) {
|
||||
#if EFI_EMULATE_POSITION_SENSORS
|
||||
#if EFI_EMULATE_POSITION_SENSORS || defined(__DOXYGEN__)
|
||||
print("Emulating %s\r\n", getConfigurationName(engineConfiguration));
|
||||
|
||||
triggerSignal.outputPins[0] = TRIGGER_EMULATOR_PRIMARY;
|
||||
triggerSignal.outputPins[1] = TRIGGER_EMULATOR_SECONDARY;
|
||||
triggerSignal.outputPins[2] = TRIGGER_EMULATOR_3RD;
|
||||
|
||||
// todo: refactor, make this a loop
|
||||
outputPinRegisterExt2("distributor ch1", triggerSignal.outputPins[0], boardConfiguration->triggerSimulatorPins[0],
|
||||
&boardConfiguration->triggerSimulatorPinModes[0]);
|
||||
|
||||
outputPinRegisterExt2("distributor ch2", triggerSignal.outputPins[1], boardConfiguration->triggerSimulatorPins[1],
|
||||
&boardConfiguration->triggerSimulatorPinModes[1]);
|
||||
|
||||
initTriggerEmulatorLogic(applyPinState);
|
||||
outputPinRegisterExt2("distributor ch3", triggerSignal.outputPins[2], boardConfiguration->triggerSimulatorPins[2],
|
||||
&boardConfiguration->triggerSimulatorPinModes[2]);
|
||||
|
||||
|
||||
initTriggerEmulatorLogic(emulatorApplyPinState);
|
||||
#else
|
||||
print("No position sensor(s) emulation\r\n");
|
||||
#endif /* EFI_EMULATE_POSITION_SENSORS */
|
||||
|
|
|
@ -10,23 +10,25 @@
|
|||
#define DIST_EMULATOR_H_
|
||||
|
||||
#include "main.h"
|
||||
#include "wave_math.h"
|
||||
|
||||
#include "trigger_structure.h"
|
||||
#include "engine_configuration.h"
|
||||
#include "pwm_generator_logic.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif /* __cplusplus */
|
||||
class TriggerEmulatorHelper {
|
||||
public:
|
||||
bool primaryWheelState;
|
||||
bool secondaryWheelState;
|
||||
bool thirdWheelState;
|
||||
|
||||
TriggerEmulatorHelper();
|
||||
|
||||
void handleEmulatorCallback(PwmConfig *state, int stateIndex);
|
||||
|
||||
};
|
||||
|
||||
|
||||
void initTriggerEmulator(void);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
void setTriggerEmulatorRPM(int value);
|
||||
|
||||
|
||||
#endif /* DIST_EMULATOR_H_ */
|
||||
|
|
|
@ -1,256 +1,262 @@
|
|||
/**
|
||||
* @file wave_analyzer.c
|
||||
* @brief Initialization of Input Capture pins used for dev console sniffer
|
||||
*
|
||||
* This file is responsible for sniffing of external digital signals and registering
|
||||
* these digital events in WaveChart used by the Sniffer tab of Dev Console.
|
||||
*
|
||||
*
|
||||
* @date Jan 7, 2013
|
||||
* @author Andrey Belomutskiy, (c) 2012-2014
|
||||
*/
|
||||
|
||||
#include "main.h"
|
||||
#include "wave_analyzer.h"
|
||||
#include "eficonsole.h"
|
||||
#include "data_buffer.h"
|
||||
#include "pin_repository.h"
|
||||
#include "engine_state.h"
|
||||
#include "signal_executor.h"
|
||||
#include "engine_configuration.h"
|
||||
#include "trigger_central.h"
|
||||
#include "rfiutil.h"
|
||||
|
||||
|
||||
#define CHART_RESET_DELAY 1
|
||||
|
||||
extern board_configuration_s *boardConfiguration;
|
||||
|
||||
extern engine_configuration_s *engineConfiguration;
|
||||
|
||||
static volatile uint32_t ckpPeriodUs; // difference between current crank signal and previous crank signal
|
||||
static volatile uint64_t previousCrankSignalStart = 0;
|
||||
|
||||
#define MAX_ICU_COUNT 5
|
||||
|
||||
static int waveReaderCount = 0;
|
||||
static WaveReader readers[MAX_ICU_COUNT];
|
||||
extern WaveChart waveChart;
|
||||
|
||||
static Logging logger;
|
||||
|
||||
static void ensureInitialized(WaveReader *reader) {
|
||||
efiAssertVoid(reader->hw.started, "wave analyzer NOT INITIALIZED");
|
||||
}
|
||||
|
||||
#ifdef EFI_WAVE_ANALYZER
|
||||
|
||||
static void waAnaWidthCallback(WaveReader *reader) {
|
||||
uint64_t nowUs = getTimeNowUs();
|
||||
reader->eventCounter++;
|
||||
reader->lastActivityTimeUs = nowUs;
|
||||
addWaveChartEvent(reader->name, WC_UP, "");
|
||||
|
||||
uint64_t width = nowUs - reader->periodEventTimeUs;
|
||||
reader->last_wave_low_widthUs = width;
|
||||
|
||||
reader->signalPeriodUs = nowUs - reader->widthEventTimeUs;
|
||||
reader->widthEventTimeUs = nowUs;
|
||||
}
|
||||
|
||||
static void waIcuPeriodCallback(WaveReader *reader) {
|
||||
uint64_t nowUs = getTimeNowUs();
|
||||
reader->eventCounter++;
|
||||
reader->lastActivityTimeUs = nowUs;
|
||||
addWaveChartEvent(reader->name, WC_DOWN, "");
|
||||
|
||||
uint64_t width = nowUs - reader->widthEventTimeUs;
|
||||
reader->last_wave_high_widthUs = width;
|
||||
|
||||
reader->periodEventTimeUs = nowUs;
|
||||
|
||||
//scheduleSimpleMsg(&irqLogging, "co", reader->chart.counter);
|
||||
|
||||
// dbAdd(&wavePeriodTime, now);
|
||||
|
||||
int period = ckpPeriodUs; // local copy of volatile variable
|
||||
|
||||
uint64_t offset = nowUs - previousCrankSignalStart;
|
||||
|
||||
if (offset > period / 2) {
|
||||
/**
|
||||
* here we calculate the offset in relation to future cranking signal
|
||||
*/
|
||||
offset -= period;
|
||||
}
|
||||
reader->waveOffsetUs = offset;
|
||||
|
||||
// we want only the low phase length, so we subsctract high width from period
|
||||
// processSignal(1, &dataPinReader, last_period - last_adc_response_width);
|
||||
}
|
||||
|
||||
static void setWaveModeSilent(int index, int mode) {
|
||||
WaveReader *reader = &readers[index];
|
||||
|
||||
setWaveReaderMode(&reader->hw, mode);
|
||||
}
|
||||
|
||||
void setWaveMode(int index, int mode) {
|
||||
setWaveModeSilent(index, mode);
|
||||
print("wavemode%d:%d\r\n", index, mode);
|
||||
}
|
||||
|
||||
int getWaveMode(int index) {
|
||||
WaveReader *reader = &readers[index];
|
||||
ensureInitialized(reader);
|
||||
return reader->hw.activeMode;
|
||||
}
|
||||
|
||||
int getEventCounter(int index) {
|
||||
WaveReader *reader = &readers[index];
|
||||
ensureInitialized(reader);
|
||||
return reader->eventCounter;
|
||||
}
|
||||
|
||||
static void initWave(char *name, int index, ICUDriver *driver, ioportid_t port, int pin, int mode) {
|
||||
waveReaderCount++;
|
||||
efiAssertVoid(index < MAX_ICU_COUNT, "too many ICUs");
|
||||
WaveReader *reader = &readers[index];
|
||||
WaveReaderHw *hw = &reader->hw;
|
||||
|
||||
reader->name = name;
|
||||
|
||||
registerCallback(&hw->widthListeners, (IntListener) waAnaWidthCallback, reader);
|
||||
|
||||
registerCallback(&hw->periodListeners, (IntListener) waIcuPeriodCallback, reader);
|
||||
|
||||
initWaveAnalyzerDriver(hw, driver, port, pin);
|
||||
|
||||
print("wave%d input on %s%d\r\n", index, portname(reader->hw.port), reader->hw.pin);
|
||||
setWaveReaderMode(hw, mode);
|
||||
}
|
||||
#endif
|
||||
|
||||
//int getCrankStart() {
|
||||
// return previousCrankSignalStart;
|
||||
//}
|
||||
|
||||
//static int getCrankPeriod(void) {
|
||||
// return ckpPeriod;
|
||||
//}
|
||||
|
||||
static void onWaveShaftSignal(trigger_event_e ckpSignalType, int index, void *arg) {
|
||||
if (index != 0)
|
||||
return;
|
||||
uint64_t nowUs = getTimeNowUs();
|
||||
ckpPeriodUs = nowUs - previousCrankSignalStart;
|
||||
previousCrankSignalStart = nowUs;
|
||||
}
|
||||
|
||||
static THD_WORKING_AREA(waThreadStack, UTILITY_THREAD_STACK_SIZE);
|
||||
|
||||
//static Logging logger;
|
||||
|
||||
static msg_t waThread(void *arg) {
|
||||
chRegSetThreadName("Wave Analyzer");
|
||||
#if EFI_WAVE_CHART
|
||||
while (TRUE) {
|
||||
chThdSleepSeconds(CHART_RESET_DELAY);
|
||||
|
||||
publishChartIfFull(&waveChart);
|
||||
}
|
||||
#endif /* EFI_WAVE_CHART */
|
||||
#if defined __GNUC__
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
int getWaveLowWidth(int index) {
|
||||
WaveReader *reader = &readers[index];
|
||||
ensureInitialized(reader);
|
||||
return reader->last_wave_low_widthUs;
|
||||
}
|
||||
|
||||
float getWaveHighWidthMs(int index) {
|
||||
WaveReader *reader = &readers[index];
|
||||
ensureInitialized(reader);
|
||||
if (getTimeNowUs() - reader->lastActivityTimeUs > 4 * US_PER_SECOND)
|
||||
return 0; // dwell time has expired
|
||||
return reader->last_wave_high_widthUs / 1000.0;
|
||||
}
|
||||
|
||||
uint64_t getWaveOffset(int index) {
|
||||
WaveReader *reader = &readers[index];
|
||||
ensureInitialized(reader);
|
||||
return reader->waveOffsetUs;
|
||||
}
|
||||
|
||||
float getSignalPeriodMs(int index) {
|
||||
WaveReader *reader = &readers[index];
|
||||
ensureInitialized(reader);
|
||||
return reader->signalPeriodUs / 1000.0;
|
||||
}
|
||||
|
||||
int getWidthEventTime(int index) {
|
||||
WaveReader *reader = &readers[index];
|
||||
ensureInitialized(reader);
|
||||
return reader->widthEventTimeUs;
|
||||
}
|
||||
|
||||
uint64_t getPeriodEventTime(int index) {
|
||||
WaveReader *reader = &readers[index];
|
||||
ensureInitialized(reader);
|
||||
return reader->periodEventTimeUs;
|
||||
}
|
||||
|
||||
int waveBufferReported = 0;
|
||||
|
||||
static void reportWave(Logging *logging, int index) {
|
||||
// int counter = getEventCounter(index);
|
||||
// debugInt2(logging, "ev", index, counter);
|
||||
|
||||
float dwellMs = getWaveHighWidthMs(index);
|
||||
float periodMs = getSignalPeriodMs(index);
|
||||
|
||||
appendPrintf(logging, "duty%d%s", index, DELIMETER);
|
||||
appendFloat(logging, 100.0 * dwellMs / periodMs, 2);
|
||||
appendPrintf(logging, "%s", DELIMETER);
|
||||
|
||||
appendPrintf(logging, "dwell%d%s", index, DELIMETER);
|
||||
appendFloat(logging, dwellMs, 2);
|
||||
appendPrintf(logging, "%s", DELIMETER);
|
||||
|
||||
appendPrintf(logging, "period%d%s", index, DELIMETER);
|
||||
appendFloat(logging, periodMs, 2);
|
||||
appendPrintf(logging, "%s", DELIMETER);
|
||||
|
||||
// int crank = getCrankPeriod();
|
||||
|
||||
// int offset = getWaveOffset(index);
|
||||
// debugFloat2(logging, "advance", index, 90.0 * offset / crank, 3);
|
||||
// debugInt2(logging, "offset", index, offset);
|
||||
}
|
||||
|
||||
void printWave(Logging *logging) {
|
||||
reportWave(logging, 0);
|
||||
reportWave(logging, 1);
|
||||
}
|
||||
|
||||
void initWaveAnalyzer(void) {
|
||||
#ifdef EFI_WAVE_ANALYZER
|
||||
initLogging(&logger, "wave");
|
||||
|
||||
initWave("input1 A8", 0, getInputCaptureDriver(boardConfiguration->primaryLogicAnalyzerPin), getHwPort(boardConfiguration->primaryLogicAnalyzerPin), getHwPin(boardConfiguration->primaryLogicAnalyzerPin), 1);
|
||||
initWave("input2 E5", 1, getInputCaptureDriver(boardConfiguration->secondaryLogicAnalyzerPin), getHwPort(boardConfiguration->secondaryLogicAnalyzerPin), getHwPin(boardConfiguration->secondaryLogicAnalyzerPin), 1);
|
||||
// initWave("input0 C6", 2, &WAVE_TIMER, WAVE_INPUT_PORT, WAVE_INPUT_PIN, 0);
|
||||
|
||||
addTriggerEventListener(&onWaveShaftSignal, "wave analyzer", NULL);
|
||||
|
||||
addConsoleActionII("wm", setWaveModeSilent);
|
||||
|
||||
chThdCreateStatic(waThreadStack, sizeof(waThreadStack), NORMALPRIO, waThread, NULL);
|
||||
|
||||
#else
|
||||
print("wave disabled\r\n");
|
||||
#endif
|
||||
}
|
||||
/**
|
||||
* @file wave_analyzer.cpp
|
||||
* @brief Initialization of Input Capture pins used for dev console sniffer
|
||||
*
|
||||
* This file is responsible for sniffing of external digital signals and registering
|
||||
* these digital events in WaveChart used by the Sniffer tab of Dev Console.
|
||||
*
|
||||
*
|
||||
* @date Jan 7, 2013
|
||||
* @author Andrey Belomutskiy, (c) 2012-2014
|
||||
*/
|
||||
|
||||
#include "main.h"
|
||||
#include "wave_analyzer.h"
|
||||
#include "eficonsole.h"
|
||||
#include "data_buffer.h"
|
||||
#include "pin_repository.h"
|
||||
#include "engine_state.h"
|
||||
#include "signal_executor.h"
|
||||
#include "engine_configuration.h"
|
||||
#include "trigger_central.h"
|
||||
#include "rfiutil.h"
|
||||
#include "engine_math.h"
|
||||
#include "engine.h"
|
||||
|
||||
extern Engine engine;
|
||||
|
||||
#define CHART_RESET_DELAY 1
|
||||
|
||||
extern board_configuration_s *boardConfiguration;
|
||||
|
||||
extern engine_configuration_s *engineConfiguration;
|
||||
|
||||
static volatile uint32_t ckpPeriodUs; // difference between current crank signal and previous crank signal
|
||||
static volatile uint64_t previousCrankSignalStart = 0;
|
||||
|
||||
#define MAX_ICU_COUNT 5
|
||||
|
||||
static int waveReaderCount = 0;
|
||||
static WaveReader readers[MAX_ICU_COUNT];
|
||||
extern WaveChart waveChart;
|
||||
|
||||
static Logging logger;
|
||||
|
||||
static void ensureInitialized(WaveReader *reader) {
|
||||
efiAssertVoid(reader->hw.started, "wave analyzer NOT INITIALIZED");
|
||||
}
|
||||
|
||||
#if EFI_WAVE_ANALYZER || defined(__DOXYGEN__)
|
||||
|
||||
static void waAnaWidthCallback(WaveReader *reader) {
|
||||
uint64_t nowUs = getTimeNowUs();
|
||||
reader->eventCounter++;
|
||||
reader->lastActivityTimeUs = nowUs;
|
||||
addWaveChartEvent(reader->name, WC_UP, "");
|
||||
|
||||
uint32_t width = nowUs - reader->periodEventTimeUs;
|
||||
reader->last_wave_low_widthUs = width;
|
||||
|
||||
reader->signalPeriodUs = nowUs - reader->widthEventTimeUs;
|
||||
reader->widthEventTimeUs = nowUs;
|
||||
}
|
||||
|
||||
static void waIcuPeriodCallback(WaveReader *reader) {
|
||||
uint64_t nowUs = getTimeNowUs();
|
||||
reader->eventCounter++;
|
||||
reader->lastActivityTimeUs = nowUs;
|
||||
addWaveChartEvent(reader->name, WC_DOWN, "");
|
||||
|
||||
uint64_t width = nowUs - reader->widthEventTimeUs;
|
||||
reader->last_wave_high_widthUs = width;
|
||||
|
||||
reader->periodEventTimeUs = nowUs;
|
||||
|
||||
//scheduleSimpleMsg(&irqLogging, "co", reader->chart.counter);
|
||||
|
||||
// dbAdd(&wavePeriodTime, now);
|
||||
|
||||
uint32_t period = ckpPeriodUs; // local copy of volatile variable
|
||||
|
||||
uint32_t offset = nowUs - previousCrankSignalStart;
|
||||
|
||||
if (offset > period / 2) {
|
||||
/**
|
||||
* here we calculate the offset in relation to future cranking signal
|
||||
*/
|
||||
offset -= period;
|
||||
}
|
||||
reader->waveOffsetUs = offset;
|
||||
|
||||
// we want only the low phase length, so we subsctract high width from period
|
||||
// processSignal(1, &dataPinReader, last_period - last_adc_response_width);
|
||||
}
|
||||
|
||||
static void setWaveModeSilent(int index, int mode) {
|
||||
WaveReader *reader = &readers[index];
|
||||
|
||||
setWaveReaderMode(&reader->hw, mode);
|
||||
}
|
||||
|
||||
//void setWaveMode(int index, int mode) {
|
||||
// setWaveModeSilent(index, mode);
|
||||
// print("wavemode%d:%d\r\n", index, mode);
|
||||
//}
|
||||
|
||||
int getWaveMode(int index) {
|
||||
WaveReader *reader = &readers[index];
|
||||
ensureInitialized(reader);
|
||||
return reader->hw.activeMode;
|
||||
}
|
||||
|
||||
int getEventCounter(int index) {
|
||||
WaveReader *reader = &readers[index];
|
||||
ensureInitialized(reader);
|
||||
return reader->eventCounter;
|
||||
}
|
||||
|
||||
static void initWave(const char *name, int index, ICUDriver *driver, ioportid_t port, ioportmask_t pin, int mode) {
|
||||
waveReaderCount++;
|
||||
efiAssertVoid(index < MAX_ICU_COUNT, "too many ICUs");
|
||||
WaveReader *reader = &readers[index];
|
||||
WaveReaderHw *hw = &reader->hw;
|
||||
|
||||
reader->name = name;
|
||||
|
||||
registerCallback(&hw->widthListeners, (IntListener) waAnaWidthCallback, (void*)reader);
|
||||
|
||||
registerCallback(&hw->periodListeners, (IntListener) waIcuPeriodCallback, (void*)reader);
|
||||
|
||||
initWaveAnalyzerDriver(hw, driver, port, pin);
|
||||
|
||||
print("wave%d input on %s%d\r\n", index, portname(reader->hw.port), reader->hw.pin);
|
||||
setWaveReaderMode(hw, mode);
|
||||
}
|
||||
#endif
|
||||
|
||||
//int getCrankStart() {
|
||||
// return previousCrankSignalStart;
|
||||
//}
|
||||
|
||||
//static int getCrankPeriod(void) {
|
||||
// return ckpPeriod;
|
||||
//}
|
||||
|
||||
static void onWaveShaftSignal(trigger_event_e ckpSignalType, int index, void *arg) {
|
||||
if (index != 0) {
|
||||
return;
|
||||
}
|
||||
uint64_t nowUs = getTimeNowUs();
|
||||
ckpPeriodUs = nowUs - previousCrankSignalStart;
|
||||
previousCrankSignalStart = nowUs;
|
||||
}
|
||||
|
||||
static THD_WORKING_AREA(waThreadStack, UTILITY_THREAD_STACK_SIZE);
|
||||
|
||||
//static Logging logger;
|
||||
|
||||
static msg_t waThread(void *arg) {
|
||||
chRegSetThreadName("Wave Analyzer");
|
||||
#if EFI_WAVE_CHART
|
||||
while (TRUE) {
|
||||
chThdSleepSeconds(CHART_RESET_DELAY);
|
||||
|
||||
publishChartIfFull(&waveChart);
|
||||
}
|
||||
#endif /* EFI_WAVE_CHART */
|
||||
#if defined __GNUC__
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
uint32_t getWaveLowWidth(int index) {
|
||||
WaveReader *reader = &readers[index];
|
||||
ensureInitialized(reader);
|
||||
return reader->last_wave_low_widthUs;
|
||||
}
|
||||
|
||||
float getWaveHighWidthMs(int index) {
|
||||
WaveReader *reader = &readers[index];
|
||||
ensureInitialized(reader);
|
||||
if (getTimeNowUs() - reader->lastActivityTimeUs > 4 * US_PER_SECOND) {
|
||||
return 0.0f; // dwell time has expired
|
||||
}
|
||||
return reader->last_wave_high_widthUs / 1000.0f;
|
||||
}
|
||||
|
||||
uint64_t getWaveOffset(int index) {
|
||||
WaveReader *reader = &readers[index];
|
||||
ensureInitialized(reader);
|
||||
return reader->waveOffsetUs;
|
||||
}
|
||||
|
||||
float getSignalPeriodMs(int index) {
|
||||
WaveReader *reader = &readers[index];
|
||||
ensureInitialized(reader);
|
||||
return reader->signalPeriodUs / 1000.0f;
|
||||
}
|
||||
|
||||
uint64_t getWidthEventTime(int index) {
|
||||
WaveReader *reader = &readers[index];
|
||||
ensureInitialized(reader);
|
||||
return reader->widthEventTimeUs;
|
||||
}
|
||||
|
||||
uint64_t getPeriodEventTime(int index) {
|
||||
WaveReader *reader = &readers[index];
|
||||
ensureInitialized(reader);
|
||||
return reader->periodEventTimeUs;
|
||||
}
|
||||
|
||||
int waveBufferReported = 0;
|
||||
|
||||
static void reportWave(Logging *logging, int index) {
|
||||
// int counter = getEventCounter(index);
|
||||
// debugInt2(logging, "ev", index, counter);
|
||||
|
||||
float dwellMs = getWaveHighWidthMs(index);
|
||||
float periodMs = getSignalPeriodMs(index);
|
||||
|
||||
appendPrintf(logging, "duty%d%s", index, DELIMETER);
|
||||
appendFloat(logging, 100.0f * dwellMs / periodMs, 2);
|
||||
appendPrintf(logging, "%s", DELIMETER);
|
||||
|
||||
appendPrintf(logging, "dwell%d%s", index, DELIMETER);
|
||||
appendFloat(logging, dwellMs, 2);
|
||||
appendPrintf(logging, "%s", DELIMETER);
|
||||
|
||||
appendPrintf(logging, "period%d%s", index, DELIMETER);
|
||||
appendFloat(logging, periodMs, 2);
|
||||
appendPrintf(logging, "%s", DELIMETER);
|
||||
|
||||
int offset = getWaveOffset(index);
|
||||
int crank = getOneDegreeTimeMs(getRpm()) * 360;
|
||||
|
||||
appendPrintf(logging, "advance%d%s", index, DELIMETER);
|
||||
appendFloat(logging, 90.0 * offset / crank, 3);
|
||||
appendPrintf(logging, "%s", DELIMETER);
|
||||
}
|
||||
|
||||
void printWave(Logging *logging) {
|
||||
reportWave(logging, 0);
|
||||
reportWave(logging, 1);
|
||||
}
|
||||
|
||||
void initWaveAnalyzer(void) {
|
||||
#if EFI_WAVE_ANALYZER || defined(__DOXYGEN__)
|
||||
initLogging(&logger, "wave");
|
||||
|
||||
initWave(WA_CHANNEL_1, 0, getInputCaptureDriver(boardConfiguration->logicAnalyzerPins[0]), getHwPort(boardConfiguration->logicAnalyzerPins[0]), getHwPin(boardConfiguration->logicAnalyzerPins[0]), 1);
|
||||
initWave(WA_CHANNEL_2, 1, getInputCaptureDriver(boardConfiguration->logicAnalyzerPins[1]), getHwPort(boardConfiguration->logicAnalyzerPins[1]), getHwPin(boardConfiguration->logicAnalyzerPins[1]), 1);
|
||||
// initWave("input0 C6", 2, &WAVE_TIMER, WAVE_INPUT_PORT, WAVE_INPUT_PIN, 0);
|
||||
|
||||
addTriggerEventListener(&onWaveShaftSignal, "wave analyzer", (void*)NULL);
|
||||
|
||||
addConsoleActionII("wm", setWaveModeSilent);
|
||||
|
||||
chThdCreateStatic(waThreadStack, sizeof(waThreadStack), NORMALPRIO, waThread, (void*)NULL);
|
||||
|
||||
#else
|
||||
print("wave disabled\r\n");
|
||||
#endif
|
||||
}
|
|
@ -15,19 +15,22 @@
|
|||
#include "wave_analyzer_hw.h"
|
||||
#include "wave_chart.h"
|
||||
|
||||
#define WA_CHANNEL_1 "input1"
|
||||
#define WA_CHANNEL_2 "input2"
|
||||
|
||||
typedef struct {
|
||||
WaveReaderHw hw;
|
||||
char *name;
|
||||
const char *name;
|
||||
volatile int eventCounter;
|
||||
|
||||
volatile uint64_t lastActivityTimeUs; // timestamp in microseconds ticks
|
||||
volatile uint64_t periodEventTimeUs; // time of signal fall in microseconds
|
||||
volatile uint64_t widthEventTimeUs; // time of signal rise in microseconds
|
||||
|
||||
volatile uint64_t signalPeriodUs; // period between two signal rises in microseconds
|
||||
volatile uint32_t signalPeriodUs; // period between two signal rises in microseconds
|
||||
|
||||
volatile uint64_t waveOffsetUs; // offset from CKP signal in systimer ticks
|
||||
volatile uint64_t last_wave_low_widthUs; // time period in systimer ticks
|
||||
volatile uint32_t last_wave_low_widthUs; // time period in systimer ticks
|
||||
volatile uint64_t last_wave_high_widthUs; // time period in systimer ticks
|
||||
} WaveReader;
|
||||
|
||||
|
@ -39,7 +42,7 @@ extern "C"
|
|||
void initWaveAnalyzer(void);
|
||||
void pokeWaveInfo(void);
|
||||
void reportWaveInfo(void);
|
||||
int getWaveLowWidth(int index);
|
||||
uint32_t getWaveLowWidth(int index);
|
||||
float getWaveHighWidthMs(int index);
|
||||
uint64_t getWaveOffset(int index);
|
||||
|
||||
|
@ -48,7 +51,7 @@ int getWaveMode(int index);
|
|||
int getEventCounter(int index);
|
||||
|
||||
float getSignalPeriodMs(int index);
|
||||
int getWidthEventTime(int index);
|
||||
uint64_t getWidthEventTime(int index);
|
||||
uint64_t getPeriodEventTime(int index);
|
||||
|
||||
//int getCrankStart();
|
||||
|
|
|
@ -10,9 +10,15 @@
|
|||
|
||||
#include <ch.h>
|
||||
#include <hal.h>
|
||||
#include <time.h>
|
||||
#include <string.h>
|
||||
|
||||
// this is about MISRA not liking 'time.h'. todo: figure out something
|
||||
#if defined __GNUC__
|
||||
#include <sys/types.h>
|
||||
#else
|
||||
typedef unsigned int time_t;
|
||||
#endif
|
||||
|
||||
#include "efifeatures.h"
|
||||
#include "rusefi_enums.h"
|
||||
#include "obd_error_codes.h"
|
||||
|
@ -27,6 +33,8 @@
|
|||
// see also PORT_INT_REQUIRED_STACK
|
||||
#define UTILITY_THREAD_STACK_SIZE 128
|
||||
|
||||
#define EFI_ERROR_CODE 0xffffffff
|
||||
|
||||
#if EFI_USE_CCM && defined __GNUC__
|
||||
#define CCM_OPTIONAL __attribute__((section(".ccm")));
|
||||
#else
|
||||
|
|
|
@ -10,13 +10,17 @@
|
|||
class AdcConfiguration {
|
||||
public:
|
||||
AdcConfiguration(ADCConversionGroup* hwConfig);
|
||||
void addChannel(int hwChannelIndex);
|
||||
int getAdcHardwareIndexByInternalIndex(int index);
|
||||
void addChannel(adc_channel_e hwChannelIndex);
|
||||
adc_channel_e getAdcHardwareIndexByInternalIndex(int index);
|
||||
int internalAdcIndexByHardwareIndex[20];
|
||||
bool isHwUsed(adc_channel_e hwChannel);
|
||||
int size();
|
||||
void init(void);
|
||||
int conversionCount;
|
||||
int errorsCount;
|
||||
int getAdcValueByIndex(int internalIndex);
|
||||
|
||||
adc_state values;
|
||||
private:
|
||||
ADCConversionGroup* hwConfig;
|
||||
/**
|
||||
|
@ -24,7 +28,7 @@ private:
|
|||
*/
|
||||
int channelCount;
|
||||
|
||||
int hardwareIndexByIndernalAdcIndex[20];
|
||||
adc_channel_e hardwareIndexByIndernalAdcIndex[20];
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -26,6 +26,7 @@ AdcConfiguration::AdcConfiguration(ADCConversionGroup* hwConfig) {
|
|||
hwConfig->sqr1 = 0;
|
||||
hwConfig->sqr2 = 0;
|
||||
hwConfig->sqr3 = 0;
|
||||
memset(internalAdcIndexByHardwareIndex, 0xFFFFFFFF, sizeof(internalAdcIndexByHardwareIndex));
|
||||
}
|
||||
|
||||
#define ADC_GRP1_BUF_DEPTH_FAST 1
|
||||
|
@ -80,8 +81,6 @@ static adcsample_t getAvgAdcValue(int index, adcsample_t *samples, int bufDepth,
|
|||
return result / bufDepth;
|
||||
}
|
||||
|
||||
static adc_state newState;
|
||||
|
||||
static void adc_callback_slow(ADCDriver *adcp, adcsample_t *buffer, size_t n);
|
||||
static void adc_callback_fast(ADCDriver *adcp, adcsample_t *buffer, size_t n);
|
||||
|
||||
|
@ -147,7 +146,7 @@ ADC_TwoSamplingDelay_5Cycles, // cr1
|
|||
// Conversion group sequence 1...6
|
||||
};
|
||||
|
||||
static AdcConfiguration fastAdc(&adcgrpcfg_fast);
|
||||
AdcConfiguration fastAdc(&adcgrpcfg_fast);
|
||||
|
||||
static void pwmpcb_slow(PWMDriver *pwmp) {
|
||||
#if EFI_INTERNAL_ADC
|
||||
|
@ -202,36 +201,71 @@ static void pwmpcb_fast(PWMDriver *pwmp) {
|
|||
#endif
|
||||
}
|
||||
|
||||
int getAdcValueByIndex(int internalIndex) {
|
||||
return newState.adc_data[internalIndex];
|
||||
}
|
||||
|
||||
int getInternalAdcValue(int hwChannel) {
|
||||
int getInternalAdcValue(adc_channel_e hwChannel) {
|
||||
if (boardConfiguration->adcHwChannelEnabled[hwChannel] == ADC_FAST)
|
||||
return fastAdcValue;
|
||||
|
||||
int internalIndex = slowAdc.internalAdcIndexByHardwareIndex[hwChannel];
|
||||
return getAdcValueByIndex(internalIndex);
|
||||
return slowAdc.getAdcValueByIndex(internalIndex);
|
||||
}
|
||||
|
||||
static PWMConfig pwmcfg_slow = { PWM_FREQ_SLOW, PWM_PERIOD_SLOW, pwmpcb_slow, { {
|
||||
PWM_OUTPUT_DISABLED, NULL }, { PWM_OUTPUT_DISABLED, NULL }, {
|
||||
PWM_OUTPUT_DISABLED, NULL }, { PWM_OUTPUT_DISABLED, NULL } },
|
||||
/* HW dependent part.*/
|
||||
0 };
|
||||
0, 0 };
|
||||
|
||||
static PWMConfig pwmcfg_fast = { PWM_FREQ_FAST, PWM_PERIOD_FAST, pwmpcb_fast, { {
|
||||
PWM_OUTPUT_DISABLED, NULL }, { PWM_OUTPUT_DISABLED, NULL }, {
|
||||
PWM_OUTPUT_DISABLED, NULL }, { PWM_OUTPUT_DISABLED, NULL } },
|
||||
/* HW dependent part.*/
|
||||
0 };
|
||||
0, 0 };
|
||||
|
||||
static void initAdcPin(ioportid_t port, int pin, const char *msg) {
|
||||
print("adc %s\r\n", msg);
|
||||
mySetPadMode("adc input", port, pin, PAL_MODE_INPUT_ANALOG);
|
||||
}
|
||||
|
||||
GPIO_TypeDef* getAdcChannelPort(int hwChannel) {
|
||||
adc_channel_e getAdcChannel(brain_pin_e pin) {
|
||||
switch(pin) {
|
||||
case GPIOA_0:
|
||||
return EFI_ADC_0;
|
||||
case GPIOA_1:
|
||||
return EFI_ADC_1;
|
||||
case GPIOA_2:
|
||||
return EFI_ADC_2;
|
||||
case GPIOA_3:
|
||||
return EFI_ADC_3;
|
||||
case GPIOA_4:
|
||||
return EFI_ADC_4;
|
||||
case GPIOA_5:
|
||||
return EFI_ADC_5;
|
||||
case GPIOA_6:
|
||||
return EFI_ADC_6;
|
||||
case GPIOA_7:
|
||||
return EFI_ADC_7;
|
||||
case GPIOB_0:
|
||||
return EFI_ADC_8;
|
||||
case GPIOB_1:
|
||||
return EFI_ADC_9;
|
||||
case GPIOC_0:
|
||||
return EFI_ADC_10;
|
||||
case GPIOC_1:
|
||||
return EFI_ADC_11;
|
||||
case GPIOC_2:
|
||||
return EFI_ADC_12;
|
||||
case GPIOC_3:
|
||||
return EFI_ADC_13;
|
||||
case GPIOC_4:
|
||||
return EFI_ADC_14;
|
||||
case GPIOC_5:
|
||||
return EFI_ADC_15;
|
||||
default:
|
||||
return EFI_ADC_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
GPIO_TypeDef* getAdcChannelPort(adc_channel_e hwChannel) {
|
||||
// todo: replace this with an array :)
|
||||
switch (hwChannel) {
|
||||
case ADC_CHANNEL_IN0:
|
||||
|
@ -272,7 +306,17 @@ GPIO_TypeDef* getAdcChannelPort(int hwChannel) {
|
|||
}
|
||||
}
|
||||
|
||||
int getAdcChannelPin(int hwChannel) {
|
||||
const char * getAdcMode(adc_channel_e hwChannel) {
|
||||
if (slowAdc.isHwUsed(hwChannel)) {
|
||||
return "slow";
|
||||
}
|
||||
if (fastAdc.isHwUsed(hwChannel)) {
|
||||
return "fast";
|
||||
}
|
||||
return "INACTIVE";
|
||||
}
|
||||
|
||||
int getAdcChannelPin(adc_channel_e hwChannel) {
|
||||
// todo: replace this with an array :)
|
||||
switch (hwChannel) {
|
||||
case ADC_CHANNEL_IN0:
|
||||
|
@ -313,7 +357,7 @@ int getAdcChannelPin(int hwChannel) {
|
|||
}
|
||||
}
|
||||
|
||||
static void initAdcHwChannel(int hwChannel) {
|
||||
static void initAdcHwChannel(adc_channel_e hwChannel) {
|
||||
GPIO_TypeDef* port = getAdcChannelPort(hwChannel);
|
||||
int pin = getAdcChannelPin(hwChannel);
|
||||
|
||||
|
@ -324,12 +368,25 @@ int AdcConfiguration::size() {
|
|||
return channelCount;
|
||||
}
|
||||
|
||||
int AdcConfiguration::getAdcValueByIndex(int internalIndex) {
|
||||
return values.adc_data[internalIndex];
|
||||
}
|
||||
|
||||
void AdcConfiguration::init(void) {
|
||||
hwConfig->num_channels = size();
|
||||
hwConfig->sqr1 += ADC_SQR1_NUM_CH(size());
|
||||
}
|
||||
|
||||
void AdcConfiguration::addChannel(int hwChannel) {
|
||||
bool AdcConfiguration::isHwUsed(adc_channel_e hwChannelIndex) {
|
||||
for (int i = 0; i < channelCount; i++) {
|
||||
if (hardwareIndexByIndernalAdcIndex[i] == hwChannelIndex) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void AdcConfiguration::addChannel(adc_channel_e hwChannel) {
|
||||
int logicChannel = channelCount++;
|
||||
|
||||
internalAdcIndexByHardwareIndex[hwChannel] = logicChannel;
|
||||
|
@ -344,13 +401,13 @@ void AdcConfiguration::addChannel(int hwChannel) {
|
|||
initAdcHwChannel(hwChannel);
|
||||
}
|
||||
|
||||
static void printAdcValue(int channel) {
|
||||
static void printAdcValue(adc_channel_e channel) {
|
||||
int value = getAdcValue(channel);
|
||||
float volts = adcToVoltsDivided(value);
|
||||
scheduleMsg(&logger, "adc voltage : %f", volts);
|
||||
}
|
||||
|
||||
int AdcConfiguration::getAdcHardwareIndexByInternalIndex(int index) {
|
||||
adc_channel_e AdcConfiguration::getAdcHardwareIndexByInternalIndex(int index) {
|
||||
return hardwareIndexByIndernalAdcIndex[index];
|
||||
}
|
||||
|
||||
|
@ -360,11 +417,11 @@ static void printFullAdcReport(void) {
|
|||
for (int index = 0; index < slowAdc.size(); index++) {
|
||||
appendMsgPrefix(&logger);
|
||||
|
||||
int hwIndex = slowAdc.getAdcHardwareIndexByInternalIndex(index);
|
||||
adc_channel_e hwIndex = slowAdc.getAdcHardwareIndexByInternalIndex(index);
|
||||
GPIO_TypeDef* port = getAdcChannelPort(hwIndex);
|
||||
int pin = getAdcChannelPin(hwIndex);
|
||||
|
||||
int adcValue = getAdcValueByIndex(index);
|
||||
int adcValue = slowAdc.getAdcValueByIndex(index);
|
||||
appendPrintf(&logger, " ch%d %s%d", index, portname(port), pin);
|
||||
appendPrintf(&logger, " ADC%d 12bit=%d", hwIndex, adcValue);
|
||||
float volts = adcToVolts(adcValue);
|
||||
|
@ -397,7 +454,7 @@ static void adc_callback_slow(ADCDriver *adcp, adcsample_t *buffer, size_t n) {
|
|||
// newState.time = chimeNow();
|
||||
for (int i = 0; i < slowAdc.size(); i++) {
|
||||
int value = getAvgAdcValue(i, slowAdcState.samples, ADC_GRP1_BUF_DEPTH_SLOW, slowAdc.size());
|
||||
newState.adc_data[i] = value;
|
||||
slowAdc.values.adc_data[i] = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -409,13 +466,16 @@ static void adc_callback_fast(ADCDriver *adcp, adcsample_t *buffer, size_t n) {
|
|||
// intermediate callback when the buffer is half full.*/
|
||||
if (adcp->state == ADC_COMPLETE) {
|
||||
fastAdcValue = getAvgAdcValue(0, samples_fast, ADC_GRP1_BUF_DEPTH_FAST, fastAdc.size());
|
||||
|
||||
fastAdc.values.adc_data[0] = fastAdcValue;
|
||||
|
||||
#if EFI_MAP_AVERAGING
|
||||
mapAveragingCallback(fastAdcValue);
|
||||
#endif /* EFI_MAP_AVERAGING */
|
||||
}
|
||||
}
|
||||
|
||||
void initAdcInputs(bool isBoardTestMode) {
|
||||
void initAdcInputs(void) {
|
||||
|
||||
initLoggingExt(&logger, "ADC", LOGGING_BUFFER, sizeof(LOGGING_BUFFER));
|
||||
printMsg(&logger, "initAdcInputs()");
|
||||
|
@ -434,22 +494,20 @@ void initAdcInputs(bool isBoardTestMode) {
|
|||
for (int adc = 0; adc < HW_MAX_ADC_INDEX; adc++) {
|
||||
adc_channel_mode_e mode = boardConfiguration->adcHwChannelEnabled[adc];
|
||||
|
||||
if (mode == ADC_SLOW || (isBoardTestMode && mode == ADC_FAST)) {
|
||||
slowAdc.addChannel(ADC_CHANNEL_IN0 + adc);
|
||||
if (mode == ADC_SLOW) {
|
||||
slowAdc.addChannel((adc_channel_e) (ADC_CHANNEL_IN0 + adc));
|
||||
} else if (mode == ADC_FAST) {
|
||||
fastAdc.addChannel(ADC_CHANNEL_IN0 + adc);
|
||||
fastAdc.addChannel((adc_channel_e) (ADC_CHANNEL_IN0 + adc));
|
||||
}
|
||||
}
|
||||
|
||||
slowAdc.init();
|
||||
pwmStart(EFI_INTERNAL_SLOW_ADC_PWM, &pwmcfg_slow);
|
||||
if (!isBoardTestMode) {
|
||||
fastAdc.init();
|
||||
fastAdc.init();
|
||||
/*
|
||||
* Initializes the PWM driver.
|
||||
*/
|
||||
pwmStart(EFI_INTERNAL_FAST_ADC_PWM, &pwmcfg_fast);
|
||||
}
|
||||
|
||||
// ADC_CHANNEL_IN0 // PA0
|
||||
// ADC_CHANNEL_IN1 // PA1
|
||||
|
@ -470,7 +528,7 @@ void initAdcInputs(bool isBoardTestMode) {
|
|||
|
||||
//if(slowAdcChannelCount > ADC_MAX_SLOW_CHANNELS_COUNT) // todo: do we need this logic? do we need this check
|
||||
|
||||
addConsoleActionI("adc", printAdcValue);
|
||||
addConsoleActionI("adc", (VoidInt) printAdcValue);
|
||||
addConsoleAction("fadc", printFullAdcReport);
|
||||
#else
|
||||
printMsg(&logger, "ADC disabled");
|
||||
|
|
|
@ -12,24 +12,25 @@
|
|||
#include "main.h"
|
||||
#include "adc_math.h"
|
||||
|
||||
const char * getAdcMode(adc_channel_e hwChannel);
|
||||
int getAdcChannelPin(adc_channel_e hwChannel);
|
||||
void initAdcInputs(void);
|
||||
GPIO_TypeDef* getAdcChannelPort(adc_channel_e hwChannel);
|
||||
adc_channel_e getAdcChannel(brain_pin_e pin);
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif /* __cplusplus */
|
||||
|
||||
GPIO_TypeDef* getAdcChannelPort(int hwChannel);
|
||||
int getAdcChannelPin(int hwChannel);
|
||||
void initAdcInputs(bool isBoardTestMode);
|
||||
int getAdcHardwareIndexByInternalIndex(int index);
|
||||
int getAdcValueByIndex(int internalIndex);
|
||||
void pokeAdcInputs(void);
|
||||
int getInternalAdcValue(int index);
|
||||
int getInternalAdcValue(adc_channel_e index);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
|
||||
/* Depth of the conversion buffer, channels are sampled X times each.*/
|
||||
#define ADC_GRP1_BUF_DEPTH_SLOW 1
|
||||
#define ADC_MAX_CHANNELS_COUNT 16
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
* @file board_test.cpp
|
||||
* @brief This is a simple board testing utility
|
||||
*
|
||||
* By default this is enabled by grounding PB0
|
||||
*
|
||||
* @date Mar 12, 2014
|
||||
* @author Andrey Belomutskiy, (c) 2012-2014
|
||||
*
|
||||
|
@ -29,19 +31,44 @@
|
|||
|
||||
static volatile int stepCoutner = 0;
|
||||
static volatile brain_pin_e currentPin = GPIO_NONE;
|
||||
static volatile int currentIndex = 0;
|
||||
|
||||
extern AdcConfiguration slowAdc;
|
||||
extern AdcConfiguration fastAdc;
|
||||
|
||||
static int isTimeForNextStep(int copy) {
|
||||
static bool isTimeForNextStep(int copy) {
|
||||
return copy != stepCoutner;
|
||||
}
|
||||
|
||||
static void processAdcPin(AdcConfiguration *adc, int index, const char *prefix) {
|
||||
adc_channel_e hwIndex = adc->getAdcHardwareIndexByInternalIndex(index);
|
||||
GPIO_TypeDef* port = getAdcChannelPort(hwIndex);
|
||||
int pin = getAdcChannelPin(hwIndex);
|
||||
|
||||
int copy = stepCoutner;
|
||||
|
||||
int c = 0;
|
||||
|
||||
while (!isTimeForNextStep(copy)) {
|
||||
print("%s ch%d hwIndex=%d %s%d\r\n", prefix, index, hwIndex, portname(port), pin);
|
||||
int adcValue = adc->getAdcValueByIndex(index);
|
||||
|
||||
// print("ADC%d val= %d%s", hwIndex, value, DELIMETER);
|
||||
float volts = adcToVolts(adcValue) * 2;
|
||||
print("v=%f adc=%d c=%d (hit 'n'<ENTER> for next step\r\n", volts, adcValue, c++);
|
||||
|
||||
chThdSleepMilliseconds(300);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
static volatile int currentIndex = 0;
|
||||
|
||||
static void waitForKey(void) {
|
||||
print("Please hit N<ENTER> to continue\r\n");
|
||||
int copy = stepCoutner;
|
||||
while (!isTimeForNextStep(copy))
|
||||
while (!isTimeForNextStep(copy)) {
|
||||
chThdSleepMilliseconds(200);
|
||||
}
|
||||
}
|
||||
|
||||
static void nextStep(void) {
|
||||
|
@ -102,12 +129,11 @@ bool isBoardTestMode(void) {
|
|||
void printBoardTestState(void) {
|
||||
print("Current index=%d\r\n", currentIndex);
|
||||
print("'n' for next step and 'set X' to return to step X\r\n");
|
||||
print("ADC count: %d\r\n", slowAdc.size());
|
||||
print("ADC count: slow %d/fast %d\r\n", slowAdc.size(), fastAdc.size());
|
||||
|
||||
if (currentPin != GPIO_NONE) {
|
||||
print("Blinking %s\r\n", hwPortname(currentPin));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void initBoardTest(void) {
|
||||
|
@ -119,37 +145,15 @@ void initBoardTest(void) {
|
|||
|
||||
// this code is ugly as hell, I had no time to think. Todo: refactor
|
||||
|
||||
int pinsCount = sizeof(BLINK_PINS) / sizeof(brain_pin_e);
|
||||
|
||||
processAdcPin(&fastAdc, 0, "fast");
|
||||
while (currentIndex < slowAdc.size()) {
|
||||
int hwIndex = slowAdc.getAdcHardwareIndexByInternalIndex(currentIndex);
|
||||
GPIO_TypeDef* port = getAdcChannelPort(hwIndex);
|
||||
int pin = getAdcChannelPin(hwIndex);
|
||||
|
||||
int value = getAdcValueByIndex(currentIndex);
|
||||
|
||||
int copy = stepCoutner;
|
||||
|
||||
int c = 0;
|
||||
|
||||
while (!isTimeForNextStep(copy)) {
|
||||
|
||||
print("ch%d hwIndex=%d %s%d\r\n", currentIndex, hwIndex, portname(port), pin);
|
||||
|
||||
int adcValue = getAdcValueByIndex(currentIndex);
|
||||
|
||||
// print("ADC%d val= %d%s", hwIndex, value, DELIMETER);
|
||||
float volts = adcToVolts(adcValue) * 2;
|
||||
print("v=%f adc=%d c=%d (hit 'n'<ENTER> for next step\r\n", volts, adcValue, c++);
|
||||
|
||||
chThdSleepMilliseconds(300);
|
||||
|
||||
}
|
||||
processAdcPin(&slowAdc, currentIndex, "slow");
|
||||
currentIndex++;
|
||||
}
|
||||
|
||||
currentIndex = 0;
|
||||
|
||||
int pinsCount = sizeof(BLINK_PINS) / sizeof(brain_pin_e);
|
||||
while (currentIndex < pinsCount) {
|
||||
currentPin = BLINK_PINS[currentIndex];
|
||||
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
#include "can_header.h"
|
||||
#include "engine_configuration.h"
|
||||
|
||||
#if EFI_CAN_SUPPORT
|
||||
#if EFI_CAN_SUPPORT || defined(__DOXYGEN__)
|
||||
|
||||
static int canReadCounter = 0;
|
||||
static Logging logger;
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
#include "main.h"
|
||||
|
||||
#if EFI_INTERNAL_FLASH
|
||||
#if EFI_INTERNAL_FLASH || defined(__DOXYGEN__)
|
||||
|
||||
#include "flash.h"
|
||||
#include <string.h>
|
||||
|
|
|
@ -36,7 +36,7 @@ void initOutputPinExt(const char *msg, OutputPin *outputPin, GPIO_TypeDef *port,
|
|||
// firmwareError("outputPin already assigned to %x%d", outputPin->port, outputPin->pin);
|
||||
// return;
|
||||
// }
|
||||
outputPin->currentLogicValue = -1;
|
||||
outputPin->currentLogicValue = INITIAL_PIN_STATE;
|
||||
outputPin->port = port;
|
||||
outputPin->pin = pinNumber;
|
||||
|
||||
|
|
|
@ -9,6 +9,9 @@
|
|||
#ifndef GPIO_HELPER_H_
|
||||
#define GPIO_HELPER_H_
|
||||
|
||||
#define INITIAL_PIN_STATE -1
|
||||
|
||||
|
||||
/**
|
||||
* @brief Single output pin reference and state
|
||||
*/
|
||||
|
|
|
@ -185,7 +185,7 @@ void initHardware(Logging *logger) {
|
|||
getHwPin(boardConfiguration->boardTestModeJumperPin), PAL_MODE_INPUT_PULLUP);
|
||||
bool isBoardTestMode = GET_BOARD_TEST_MODE_VALUE();
|
||||
|
||||
initAdcInputs(isBoardTestMode);
|
||||
initAdcInputs();
|
||||
|
||||
if (isBoardTestMode) {
|
||||
initBoardTest();
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue