auto-sync

This commit is contained in:
rusefi 2014-08-29 10:40:11 -04:00
parent 34f2334652
commit 2329cff5b1
44 changed files with 613 additions and 301 deletions

View File

@ -8,18 +8,9 @@
#ifndef MINICOOPERR50_H_
#define MINICOOPERR50_H_
#ifdef __cplusplus
extern "C"
{
#endif /* __cplusplus */
#include "main.h"
#include "engine_configuration.h"
void setMiniCooperR50(engine_configuration_s *engineConfiguration, board_configuration_s *boardConfiguration);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* MINICOOPERR50_H_ */

View File

@ -10,15 +10,6 @@
#include "engine_configuration.h"
#ifdef __cplusplus
extern "C"
{
#endif /* __cplusplus */
void setCitroenBerlingoTU3JPConfiguration(engine_configuration_s *engineConfiguration, board_configuration_s *boardConfiguration);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* CITROENBERLINGOTU3JP_H_ */

View File

@ -14,15 +14,6 @@
#include "engine_configuration.h"
#ifdef __cplusplus
extern "C"
{
#endif /* __cplusplus */
void setFordAspireEngineConfiguration(engine_configuration_s *engineConfiguration, board_configuration_s *boardConfiguration);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* FORD_ASPIRE_H_ */

View File

@ -10,23 +10,30 @@
#include "ford_escort_gt.h"
#include "engine_math.h"
void setFordEscortGt(engine_configuration_s *engineConfiguration, board_configuration_s *boardConfiguration) {
engineConfiguration->triggerConfig.triggerType = TT_FORD_ESCORT_GT;
static void setDefaultCrankingFuel(engine_configuration_s *engineConfiguration) {
// todo: set cranking parameters method based on injectors and displacement?
// 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;
}
static void common079721_2351(engine_configuration_s *engineConfiguration, board_configuration_s *boardConfiguration) {
engineConfiguration->cylindersCount = 4;
engineConfiguration->firingOrder = FO_1_THEN_3_THEN_4_THEN2;
// set_global_trigger_offset_angle 256
engineConfiguration->globalTriggerAngleOffset = 256;
// set_ignition_offset 170
engineConfiguration->ignitionOffset = 170;
// set_injection_offset 510
engineConfiguration->injectionOffset = 59;
setSingleCoilDwell(engineConfiguration);
engineConfiguration->ignitionMode = IM_ONE_COIL;
boardConfiguration->fuelPumpPin = GPIO_NONE; // fuel pump is not controlled by ECU on this engine
boardConfiguration->triggerSimulatorPinModes[0] = OM_OPENDRAIN;
boardConfiguration->triggerSimulatorPinModes[1] = OM_OPENDRAIN;
// set_cranking_injection_mode 0
engineConfiguration->crankingInjectionMode = IM_SIMULTANEOUS;
// set_injection_mode 2
engineConfiguration->injectionMode = IM_BATCH;
// Frankenstein analog input #1: adc1
// Frankenstein analog input #2: adc3
@ -43,6 +50,12 @@ void setFordEscortGt(engine_configuration_s *engineConfiguration, board_configur
engineConfiguration->mafAdcChannel = EFI_ADC_1;
engineConfiguration->tpsAdcChannel = EFI_ADC_3;
engineConfiguration->cltAdcChannel = EFI_ADC_11;
}
void setMiata1990(engine_configuration_s *engineConfiguration, board_configuration_s *boardConfiguration) {
engineConfiguration->triggerConfig.triggerType = TT_FORD_ESCORT_GT;
common079721_2351(engineConfiguration, boardConfiguration);
// Frankenstein: high side #1 is PE8
@ -53,12 +66,11 @@ void setFordEscortGt(engine_configuration_s *engineConfiguration, board_configur
// Frankenstein: high side #6 is PC7
boardConfiguration->ignitionPins[0] = GPIOE_12; // Frankenstein: high side #3
boardConfiguration->ignitionPins[1] = GPIO_NONE;
boardConfiguration->ignitionPins[1] = GPIOE_14; // Frankenstein: high side #4
boardConfiguration->ignitionPins[2] = GPIO_NONE;
boardConfiguration->ignitionPins[3] = GPIO_NONE;
boardConfiguration->ignitionPinMode = OM_DEFAULT;
// Frankenstein: low side - inj #1: PC14
// Frankenstein: low side - inj #2: PC15
// Frankenstein: low side - inj #3: PE6
@ -80,26 +92,71 @@ void setFordEscortGt(engine_configuration_s *engineConfiguration, board_configur
boardConfiguration->injectionPins[5] = GPIO_NONE;
boardConfiguration->injectionPinMode = OM_DEFAULT;
// todo: idleValvePin
}
void setFordEscortGt(engine_configuration_s *engineConfiguration, board_configuration_s *boardConfiguration) {
engineConfiguration->triggerConfig.triggerType = TT_FORD_ESCORT_GT;
common079721_2351(engineConfiguration, boardConfiguration);
// set_global_trigger_offset_angle 256
engineConfiguration->globalTriggerAngleOffset = 256;
// set_ignition_offset 170
engineConfiguration->ignitionOffset = 170;
// set_injection_offset 510
engineConfiguration->injectionOffset = 59;
setSingleCoilDwell(engineConfiguration);
engineConfiguration->ignitionMode = IM_ONE_COIL;
boardConfiguration->triggerSimulatorPinModes[0] = OM_OPENDRAIN;
boardConfiguration->triggerSimulatorPinModes[1] = OM_OPENDRAIN;
// Frankenstein: high side #1 is PE8
// Frankenstein: high side #2 is PE10
// Frankenstein: high side #3 is PE12
// Frankenstein: high side #4 is PE14
// Frankenstein: high side #5 is PC9
// Frankenstein: high side #6 is PC7
boardConfiguration->ignitionPins[0] = GPIOE_12; // Frankenstein: high side #3
boardConfiguration->ignitionPins[1] = GPIO_NONE;
boardConfiguration->ignitionPins[2] = GPIO_NONE;
boardConfiguration->ignitionPins[3] = GPIO_NONE;
boardConfiguration->ignitionPinMode = OM_DEFAULT;
// 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;
boardConfiguration->fuelPumpPin = GPIO_NONE; // fuel pump is not controlled by ECU on this engine
// set_cranking_injection_mode 0
engineConfiguration->crankingInjectionMode = IM_SIMULTANEOUS;
// set_injection_mode 2
engineConfiguration->injectionMode = IM_BATCH;
setDefaultCrankingFuel(engineConfiguration);
}
/**
* set_engine_type 20
*/
void setMiata1994(engine_configuration_s *engineConfiguration, board_configuration_s *boardConfiguration) {
engineConfiguration->triggerConfig.triggerType = TT_MAZDA_MIATA_NA;
engineConfiguration->displacement = 1.839;
boardConfiguration->triggerSimulatorPins[0] = GPIOD_2; // 2G - YEL/BLU
boardConfiguration->triggerSimulatorPins[1] = GPIOB_3; // 2E - WHT - four times
boardConfiguration->triggerSimulatorPinModes[0] = OM_OPENDRAIN;
boardConfiguration->triggerSimulatorPinModes[1] = OM_OPENDRAIN;
boardConfiguration->triggerInputPins[0] = GPIO_NONE;
boardConfiguration->triggerInputPins[1] = GPIO_NONE;
boardConfiguration->is_enabled_spi_1 = false;
boardConfiguration->is_enabled_spi_2 = false;
boardConfiguration->is_enabled_spi_3 = false;
setDefaultCrankingFuel(engineConfiguration);
}
void setMiata1996(engine_configuration_s *engineConfiguration, board_configuration_s *boardConfiguration) {
setDefaultCrankingFuel(engineConfiguration);
}

View File

@ -14,15 +14,10 @@
#include "engine_configuration.h"
#ifdef __cplusplus
extern "C"
{
#endif /* __cplusplus */
void setFordEscortGt(engine_configuration_s *engineConfiguration, board_configuration_s *boardConfiguration);
#ifdef __cplusplus
}
#endif /* __cplusplus */
// todo: maybe it's time to rename this file to Miata NA? Miata? Mazda?
void setMiata1990(engine_configuration_s *engineConfiguration, board_configuration_s *boardConfiguration);
void setMiata1994(engine_configuration_s *engineConfiguration, board_configuration_s *boardConfiguration);
void setMiata1996(engine_configuration_s *engineConfiguration, board_configuration_s *boardConfiguration);
#endif /* FORD_ESCORT_GT_H_ */

View File

@ -16,6 +16,7 @@
#include "trigger_decoder.h"
#include "thermistors.h"
#include "honda_accord.h"
#include "engine_math.h"
static void setHondaAccordConfigurationCommon(engine_configuration_s *engineConfiguration, board_configuration_s *boardConfiguration) {
engineConfiguration->map.sensor.sensorType = MT_DENSO183;
@ -36,6 +37,8 @@ static void setHondaAccordConfigurationCommon(engine_configuration_s *engineConf
// engineConfiguration->algorithm = LM_SPEED_DENSITY;
// I want to start with a simple Alpha-N
engineConfiguration->algorithm = LM_TPS;
setFuelLoadBin(engineConfiguration, 0, 100);
setTimingLoadBin(engineConfiguration, 0, 100);
engineConfiguration->crankingSettings.coolantTempMaxC = 65; // 8ms at 65C
engineConfiguration->crankingSettings.fuelAtMaxTempMs = 8;
@ -55,9 +58,9 @@ static void setHondaAccordConfigurationCommon(engine_configuration_s *engineConf
engineConfiguration->iatThermistorConf.bias_resistor = 1500; // same as OEM ECU
// set_cranking_charge_angle 35
engineConfiguration->crankingChargeAngle = 35;
engineConfiguration->crankingChargeAngle = 70;
// set_cranking_timing_angle 0
engineConfiguration->crankingTimingAngle = 0;
engineConfiguration->crankingTimingAngle = 45;
// set_global_trigger_offset_angle 34
engineConfiguration->globalTriggerAngleOffset = 34;
@ -65,7 +68,7 @@ static void setHondaAccordConfigurationCommon(engine_configuration_s *engineConf
// 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;
engineConfiguration->crankingSettings.crankingRpm = 500;
// set_ignition_offset 350

View File

@ -8,7 +8,7 @@
*/
#include "mitsubishi.h"
#include "thermistors.h"
#include "allsensors.h"
void setMitsubishiConfiguration(engine_configuration_s *engineConfiguration, board_configuration_s *boardConfiguration) {
engineConfiguration->engineType = MITSU_4G93;
@ -90,6 +90,8 @@ void setMitsubishiConfiguration(engine_configuration_s *engineConfiguration, boa
engineConfiguration->HD44780width = 20;
engineConfiguration->HD44780height = 4;
initEgoSensor(&engineConfiguration->afrSensor, ES_Innovate_MTX_L);
}

View File

@ -50,6 +50,14 @@ static void myerror(void) {
firmwareError("firmwareError: %d", getRusEfiVersion());
}
static void sayNothing(void) {
/**
* @see EngineState#TS_PROTOCOL_TAG
* this empty response is part of protocol check
* todo: make this logic smarter?
*/
}
static void sayHello(void) {
printMsg(&logger, "*** rusEFI (c) Andrey Belomutskiy, 2012-2014. All rights reserved.");
printMsg(&logger, "rusEFI v%d@%s", getRusEfiVersion(), VCS_VERSION);
@ -154,6 +162,7 @@ void initializeConsole(void) {
initLogging(&logger, "console");
sayHello();
addConsoleAction("test", sayNothing);
addConsoleAction("hello", sayHello);
#if EFI_HAS_RESET
addConsoleAction("reset", scheduleReset);

View File

@ -137,6 +137,9 @@ void printSensors(void) {
reportSensorF("vref", getVRef(), 2);
reportSensorF("vbatt", getVBatt(), 2);
reportSensorF("TRG_0_DUTY", getTriggerDutyCycle(0), 2);
reportSensorF("TRG_1_DUTY", getTriggerDutyCycle(1), 2);
reportSensorF(getCaption(LP_THROTTLE), getTPS(), 2);
if (engineConfiguration->hasCltSensor) {
@ -374,6 +377,9 @@ void updateTunerStudioState(TunerStudioOutputChannels *tsOutputChannels) {
tsOutputChannels->injection_enabled = engineConfiguration->isInjectionEnabled;
tsOutputChannels->cylinder_cleanup_enabled = engineConfiguration->isCylinderCleanupEnabled;
tsOutputChannels->secondTriggerChannelEnabled = engineConfiguration->secondTriggerChannelEnabled;
tsOutputChannels->isCltError = !isValidCoolantTemperature(getCoolantTemperature());
tsOutputChannels->isIatError = !isValidIntakeAirTemperature(getIntakeAirTemperature());
#endif
tsOutputChannels->tCharge = getTCharge(rpm, tps, coolant, intake);
tsOutputChannels->sparkDwell = getSparkDwellMs(rpm);

View File

@ -324,6 +324,7 @@ static bool handlePlainCommand(uint8_t command) {
return true;
} else if (command == TS_PAGE_COMMAND) {
int recieved = chSequentialStreamRead(getTsSerialDevice(), (uint8_t *)&pageIn, sizeof(pageIn));
// todo: validate 'recieved' value
handlePageSelectCommand(TS_PLAIN, pageIn);
return true;
} else if (command == TS_READ_COMMAND) {
@ -357,8 +358,19 @@ static bool isKnownCommand(char command) {
static uint8_t firstByte;
static uint8_t secondByte;
// todo: reduce TS page size so that we can reduce buffer size
static uint8_t crcIoBuffer[4096];
#define CRC_VALUE_SIZE 4
// todo: double-check this
#define CRC_WRAPPING_SIZE 7
/**
* we use 'blockingFactor = 256' in rusefi.ini
* todo: should we just do (256 + CRC_WRAPPING_SIZE) ?
*/
static uint8_t crcIoBuffer[300];
static msg_t tsThreadEntryPoint(void *arg) {
(void) arg;
@ -398,7 +410,7 @@ static msg_t tsThreadEntryPoint(void *arg) {
uint32_t incomingPacketSize = firstByte * 256 + secondByte;
if (incomingPacketSize == 0 || incomingPacketSize > sizeof(crcIoBuffer)) {
if (incomingPacketSize == 0 || incomingPacketSize > (sizeof(crcIoBuffer) - CRC_WRAPPING_SIZE)) {
scheduleMsg(&logger, "TunerStudio: invalid size: %d", incomingPacketSize);
tunerStudioError("ERROR: size");
sendErrorCode();
@ -420,9 +432,9 @@ static msg_t tsThreadEntryPoint(void *arg) {
// scheduleMsg(&logger, "TunerStudio: reading %d+4 bytes(s)", incomingPacketSize);
recieved = chnReadTimeout(getTsSerialDevice(), (uint8_t * ) (crcIoBuffer + 1), incomingPacketSize + 4 - 1,
recieved = chnReadTimeout(getTsSerialDevice(), (uint8_t * ) (crcIoBuffer + 1), incomingPacketSize + CRC_VALUE_SIZE - 1,
MS2ST(TS_READ_TIMEOUT));
int expectedSize = incomingPacketSize + 4 - 1;
int expectedSize = incomingPacketSize + CRC_VALUE_SIZE - 1;
if (recieved != expectedSize) {
scheduleMsg(&logger, "got ONLY %d for packet size %d/%d for command %c", recieved, incomingPacketSize,
expectedSize, command);

View File

@ -152,5 +152,9 @@ void handleTestCommand(void) {
*/
tunerStudioDebug("got T (Test)");
tunerStudioWriteData((const uint8_t *)VCS_VERSION, sizeof(VCS_VERSION));
tunerStudioWriteData((const uint8_t *) " alive\r\n", 8);
/**
* Please note that this response is a magic constant used by dev console for protocol detection
* @see EngineState#TS_PROTOCOL_TAG
*/
tunerStudioWriteData((const uint8_t *) " ts_p_alive\r\n", 8);
}

View File

@ -51,7 +51,12 @@ typedef struct {
unsigned int checkEngine : 1; // bit 8
unsigned int needBurn : 1; // bit 9
unsigned int secondTriggerChannelEnabled : 1; // bit 10
int unused[10];
int unused2;
unsigned int isTpsError : 1; // bit 0
unsigned int isCltError : 1; // bit 1
unsigned int isMapError : 1; // bit 2
unsigned int isIatError : 1; // bit 3
int unused[8];
} TunerStudioOutputChannels;
#endif /* TUNERSTUDIO_CONFIGURATION_H_ */

View File

@ -162,17 +162,18 @@ char* getCaption(LoggingPoints loggingPoint) {
return "MAT";
case LP_ECT:
return "CLT";
case LP_SECONDS:
return "SecL";
// case LP_SECONDS:
// return "SecL";
case LP_MAF:
return "MAF";
case LP_MAP:
return "MAP";
case LP_MAP_RAW:
return "MAP_R";
default:
firmwareError("No such loggingPoint");
return NULL;
}
firmwareError("No such loggingPoint");
return NULL;
}
/*

View File

@ -15,13 +15,23 @@
#define DELIMETER ","
typedef enum {
LP_RPM,
LP_ECT,
LP_IAT,
LP_THROTTLE, LP_SECONDS,
LP_MAP,
LP_MAF,
LP_MAP_RAW,
LP_RPM = 0,
LP_ECT = 1,
LP_IAT = 2,
LP_THROTTLE = 3,
LP_THROTTLE_ADC = 4,
LP_MAP = 5,
LP_MAP_RAW = 6,
LP_MAF = 7,
LP_TRG_CH0_DUTY = 8,
LP_TRG_CH1_DUTY = 9,
// LP_SECONDS,
LP_COUNT = 9
} LoggingPoints;

View File

@ -15,7 +15,6 @@
#include "signal_executor.h"
extern Engine engine;
extern engine_configuration_s *engineConfiguration;
static AccelEnrichmemnt instance;
void AccelEnrichmemnt::updateDiffEnrichment(engine_configuration_s *engineConfiguration, float engineLoad) {
@ -44,6 +43,8 @@ float getAccelEnrichment(void) {
#if EFI_PROD_CODE
static THD_WORKING_AREA(aeThreadStack, UTILITY_THREAD_STACK_SIZE);
extern engine_configuration_s *engineConfiguration;
static msg_t DiffEnrichmentThread(int param) {
chRegSetThreadName("Diff Enrichment");
while (TRUE) {

View File

@ -70,16 +70,6 @@ void setConstantDwell(engine_configuration_s *engineConfiguration, float dwellMs
}
}
void initBpsxD1Sensor(afr_sensor_s *sensor) {
/**
* This decodes BPSX D1 Wideband Controller analog signal
*/
sensor->v1 = 0;
sensor->value1 = 9;
sensor->v2 = 5;
sensor->value2 = 19;
}
void setWholeVEMap(engine_configuration_s *engineConfiguration, float value) {
// todo: table helper?
// for (int l = 0; l < VE_LOAD_COUNT; l++) {
@ -222,6 +212,7 @@ void setDefaultConfiguration(engine_configuration_s *engineConfiguration, board_
engineConfiguration->logFormat = LF_NATIVE;
engineConfiguration->directSelfStimulation = false;
engineConfiguration->needSecondTriggerInput = true;
engineConfiguration->triggerConfig.triggerType = TT_TOOTHED_WHEEL_60_2;
engineConfiguration->HD44780width = 20;
@ -234,7 +225,7 @@ void setDefaultConfiguration(engine_configuration_s *engineConfiguration, board_
engineConfiguration->mafAdcChannel = EFI_ADC_0;
engineConfiguration->afrSensor.afrAdcChannel = EFI_ADC_14;
initBpsxD1Sensor(&engineConfiguration->afrSensor);
initEgoSensor(&engineConfiguration->afrSensor, ES_BPSX_D1);
engineConfiguration->globalFuelCorrection = 1;
@ -356,6 +347,10 @@ void setDefaultConfiguration(engine_configuration_s *engineConfiguration, board_
boardConfiguration->digitalPotentiometerChipSelect[1] = GPIO_NONE;
boardConfiguration->digitalPotentiometerChipSelect[2] = GPIOD_5;
boardConfiguration->digitalPotentiometerChipSelect[3] = GPIO_NONE;
boardConfiguration->is_enabled_spi_1 = false;
boardConfiguration->is_enabled_spi_2 = true;
boardConfiguration->is_enabled_spi_3 = true;
}
//void setDefaultNonPersistentConfiguration(engine_configuration2_s *engineConfiguration2) {
@ -427,6 +422,15 @@ void resetConfigurationExt(Logging * logger, engine_type_e engineType, engine_co
case FORD_ESCORT_GT:
setFordEscortGt(engineConfiguration, boardConfiguration);
break;
case MIATA_1990:
setMiata1990(engineConfiguration, boardConfiguration);
break;
case MIATA_1994:
setMiata1994(engineConfiguration, boardConfiguration);
break;
case MIATA_1996:
setMiata1996(engineConfiguration, boardConfiguration);
break;
case CITROEN_TU3JP:
setCitroenBerlingoTU3JPConfiguration(engineConfiguration, boardConfiguration);
break;

View File

@ -182,7 +182,11 @@ typedef struct {
brain_pin_e o2heaterPin;
pin_output_mode_e o2heaterPinModeTodO;
int unused2[8];
unsigned int is_enabled_spi_1 : 1;
unsigned int is_enabled_spi_2 : 1;
unsigned int is_enabled_spi_3 : 1;
int unused2[7];
} board_configuration_s;
@ -393,7 +397,7 @@ typedef struct {
bool isIgnitionEnabled : 1; // bit 1
bool isCylinderCleanupEnabled : 1; // bit 2
bool secondTriggerChannelEnabled : 1; // bit 3
bool needSecondTriggerInput : 1; // bit 4
int unused3[8];

View File

@ -41,50 +41,6 @@
#include "accel_enrichment.h"
#endif /* EFI_ACCEL_ENRICHMENT */
extern Engine engine;
extern engine_configuration_s *engineConfiguration;
static Map3D1616 fuelMap;
/**
* @brief Initialize fuel map data structure
* @note this method has nothing to do with fuel map VALUES - it's job
* is to prepare the fuel map data structure for 3d interpolation
*/
void prepareFuelMap(void) {
fuelMap.init(engineConfiguration->fuelTable);
}
/**
* @brief Engine warm-up fuel correction.
*/
float getCltCorrection(float clt) {
if (cisnan(clt))
return 1; // this error should be already reported somewhere else, let's just handle it
return interpolate2d(clt, engineConfiguration->cltFuelCorrBins, engineConfiguration->cltFuelCorr, CLT_CURVE_SIZE);
}
float getIatCorrection(float iat) {
if (cisnan(iat))
return 1; // this error should be already reported somewhere else, let's just handle it
return interpolate2d(iat, engineConfiguration->iatFuelCorrBins, engineConfiguration->iatFuelCorr, IAT_CURVE_SIZE);
}
/**
* @brief Injector lag correction
* @param vBatt Battery voltage.
* @return Time in ms for injection opening time based on current battery voltage
*/
float getInjectorLag(float vBatt) {
if (cisnan(vBatt)) {
warning(OBD_System_Voltage_Malfunction, "vBatt=%f", vBatt);
return 0;
}
float vBattCorrection = interpolate2d(vBatt, engineConfiguration->battInjectorLagCorrBins,
engineConfiguration->battInjectorLagCorr, VBAT_INJECTOR_CURVE_SIZE);
return engineConfiguration->injectorLag + vBattCorrection;
}
float getBaseFuel(Engine *engine, int rpm) {
if (engine->engineConfiguration->algorithm == LM_SPEED_DENSITY) {
return getSpeedDensityFuel(engine, rpm);
@ -94,16 +50,6 @@ float getBaseFuel(Engine *engine, int rpm) {
}
}
float getBaseTableFuel(int rpm, float engineLoad) {
efiAssert(!cisnan(engineLoad), "invalid el", NAN);
return fuelMap.getValue(engineLoad, engineConfiguration->fuelLoadBins, rpm,
engineConfiguration->fuelRpmBins);
}
float getCrankingFuel(void) {
return getStartingFuel(getCoolantTemperature());
}
/**
* @returns Length of fuel injection, in milliseconds
*/
@ -130,6 +76,60 @@ float getRunningFuel(float baseFuel, Engine *engine, int rpm) {
return baseFuel * cltCorrection * iatCorrection + injectorLag;
}
extern Engine engine;
extern engine_configuration_s *engineConfiguration;
static Map3D1616 fuelMap;
/**
* @brief Injector lag correction
* @param vBatt Battery voltage.
* @return Time in ms for injection opening time based on current battery voltage
*/
float getInjectorLag(float vBatt) {
if (cisnan(vBatt)) {
warning(OBD_System_Voltage_Malfunction, "vBatt=%f", vBatt);
return 0;
}
float vBattCorrection = interpolate2d(vBatt, engineConfiguration->battInjectorLagCorrBins,
engineConfiguration->battInjectorLagCorr, VBAT_INJECTOR_CURVE_SIZE);
return engineConfiguration->injectorLag + vBattCorrection;
}
/**
* @brief Initialize fuel map data structure
* @note this method has nothing to do with fuel map VALUES - it's job
* is to prepare the fuel map data structure for 3d interpolation
*/
void prepareFuelMap(void) {
fuelMap.init(engineConfiguration->fuelTable);
}
/**
* @brief Engine warm-up fuel correction.
*/
float getCltCorrection(float clt) {
if (cisnan(clt))
return 1; // this error should be already reported somewhere else, let's just handle it
return interpolate2d(clt, engineConfiguration->cltFuelCorrBins, engineConfiguration->cltFuelCorr, CLT_CURVE_SIZE);
}
float getIatCorrection(float iat) {
if (cisnan(iat))
return 1; // this error should be already reported somewhere else, let's just handle it
return interpolate2d(iat, engineConfiguration->iatFuelCorrBins, engineConfiguration->iatFuelCorr, IAT_CURVE_SIZE);
}
float getBaseTableFuel(int rpm, float engineLoad) {
efiAssert(!cisnan(engineLoad), "invalid el", NAN);
return fuelMap.getValue(engineLoad, engineConfiguration->fuelLoadBins, rpm,
engineConfiguration->fuelRpmBins);
}
float getCrankingFuel(void) {
return getStartingFuel(getCoolantTemperature());
}
float getStartingFuel(float coolantTemperature) {
// these magic constants are in Celsius
if (cisnan(coolantTemperature) || coolantTemperature < engineConfiguration->crankingSettings.coolantTempMinC)

View File

@ -79,7 +79,11 @@ typedef enum {
HONDA_ACCORD_CD_DIP = 18,
Internal_ForceMyEnumIntSize_engine_type = ENUM_SIZE_HACK,
MIATA_1990 = 19,
MIATA_1994 = 20,
MIATA_1996 = 21,
Force_4b_engine_type = ENUM_SIZE_HACK,
} engine_type_e;
typedef enum {
@ -102,7 +106,7 @@ typedef enum {
TT_HONDA_ACCORD_CD_DIP = 13,
Internal_ForceMyEnumIntSize_trigger_type = ENUM_SIZE_HACK,
Force_4b_trigger_type = ENUM_SIZE_HACK,
} trigger_type_e;
typedef enum {
@ -110,7 +114,7 @@ typedef enum {
ADC_SLOW = 1,
ADC_FAST = 2,
Internal_ForceMyEnumIntSize_adc_channel_mode = ENUM_SIZE_HACK,
Force_4b_adc_channel_mode = ENUM_SIZE_HACK,
} adc_channel_mode_e;
// todo: better names?
@ -160,7 +164,7 @@ typedef enum {
*/
LM_SPEED_DENSITY = 3,
Internal_ForceMyEnumIntSize_engine_load_mode = ENUM_SIZE_HACK,
Force_4b_engine_load_mode = ENUM_SIZE_HACK,
} engine_load_mode_e;
typedef enum {
@ -168,7 +172,7 @@ typedef enum {
DM_HD44780 = 1,
DM_HD44780_OVER_PCF8574 = 2,
Internal_ForceMyEnumIntSize_display_mode = ENUM_SIZE_HACK,
Force_4b_display_mode = ENUM_SIZE_HACK,
} display_mode_e;
@ -180,14 +184,14 @@ typedef enum {
*/
LM_MLV = 1,
Internal_ForceMyEnumIntSize_log_format = ENUM_SIZE_HACK,
Force_4b_log_format = ENUM_SIZE_HACK,
} log_format_e;
typedef enum {
IM_AUTO = 0,
IM_MANUAL = 1,
Internal_ForceMyEnumIntSize_idle_mode = ENUM_SIZE_HACK,
Force_4b_idle_mode = ENUM_SIZE_HACK,
} idle_mode_e;
typedef enum {
@ -205,13 +209,13 @@ typedef enum {
OM_OPENDRAIN = 2,
OM_OPENDRAIN_INVERTED = 3,
Internal_ForceMyEnumIntSize_pin_output_mode = ENUM_SIZE_HACK,
Force_4b_pin_output_mode = ENUM_SIZE_HACK,
} pin_output_mode_e;
typedef enum {
PI_DEFAULT = 0,
Internal_ForceMyEnumIntSize_pin_input_mode = ENUM_SIZE_HACK,
Force_4b_pin_input_mode = ENUM_SIZE_HACK,
} pin_input_mode_e;
typedef enum {
@ -221,7 +225,7 @@ typedef enum {
FO_1_THEN_3_THEN_2_THEN4 = 3,
FO_1_THEN_5_THEN_3_THEN_6_THEN_2_THEN_4 = 4,
FO_1_8_4_3_6_5_7_2 = 5,
Internal_ForceMyEnumIntSize_firing_order = ENUM_SIZE_HACK,
Force_4b_firing_order = ENUM_SIZE_HACK,
} firing_order_e;
// todo: better enum name
@ -230,7 +234,7 @@ typedef enum {
FOUR_STROKE_CRANK_SENSOR = 1,
FOUR_STROKE_CAM_SENSOR = 2,
Internal_ForceMyEnumIntSize_operation_mode_e = ENUM_SIZE_HACK,
Force_4b_operation_mode_e = ENUM_SIZE_HACK,
} operation_mode_e;
/**
@ -247,7 +251,7 @@ typedef enum {
IM_INDIVIDUAL_COILS = 1,
IM_WASTED_SPARK = 2,
Internal_ForceMyEnumIntSize_ignition_mode = ENUM_SIZE_HACK,
Force_4b_ignition_mode = ENUM_SIZE_HACK,
} ignition_mode_e;
typedef enum {
@ -255,7 +259,7 @@ typedef enum {
IM_SEQUENTIAL = 1,
IM_BATCH = 2,
Internal_ForceMyEnumIntSize_injection_mode = ENUM_SIZE_HACK,
Force_4b_injection_mode = ENUM_SIZE_HACK,
} injection_mode_e;
/**
@ -265,7 +269,7 @@ typedef enum {
CIM_DEFAULT = 0,
CIM_FIXED_ANGLE = 1,
Internal_ForceMyEnumIntSize_cranking_ignition_mode = ENUM_SIZE_HACK,
Force_4b_cranking_ignition_mode = ENUM_SIZE_HACK,
} cranking_ignition_mode_e;
typedef enum {
@ -275,14 +279,14 @@ typedef enum {
SPI_DEVICE_3 = 3,
SPI_DEVICE_4 = 4,
Internal_ForceMyEnumIntSize_spi_device = ENUM_SIZE_HACK,
Force_4b_spi_device = ENUM_SIZE_HACK,
} spi_device_e;
typedef enum {
IE_NO_ERROR = 0,
IE_UNEXPECTED_FIRING_ORDER = 1,
Internal_ForceMyEnumIntSize_cranking_internal_error = ENUM_SIZE_HACK,
Force_4b_cranking_internal_error = ENUM_SIZE_HACK,
} internal_error_e;
typedef enum {
@ -305,9 +309,19 @@ typedef enum {
EFI_ADC_ERROR = 999,
Internal_ForceMyEnumIntSize_cranking_adc_channel = ENUM_SIZE_HACK,
Force_4b_cranking_adc_channel = ENUM_SIZE_HACK,
} adc_channel_e;
typedef enum {
ES_BPSX_D1 = 0,
ES_Innovate_MTX_L = 1,
Force_4b_ego_sensor = ENUM_SIZE_HACK,
} ego_sensor_e;
/**
* Hardware pin. This enum is platform-specific.
*/
@ -400,7 +414,7 @@ typedef enum {
GPIO_NONE = 80,
GPIO_INVALID = 81,
Internal_ForceMyEnumIntSize_cranking_brain_pin = ENUM_SIZE_HACK,
Force_4b_cranking_brain_pin = ENUM_SIZE_HACK,
} brain_pin_e;
typedef enum {
@ -409,7 +423,7 @@ typedef enum {
MT_MPX4250 = 2,
MT_HONDA3BAR = 3,
Internal_ForceMyEnumIntSize_cranking_map_type = ENUM_SIZE_HACK,
Force_4b_cranking_map_type = ENUM_SIZE_HACK,
} air_pressure_sensor_type_e;
#endif /* RUSEFI_ENUMS_H_ */

View File

@ -52,8 +52,9 @@ bool getNeedToWriteConfiguration(void) {
}
void writeToFlashIfPending() {
if(!getNeedToWriteConfiguration())
if (!getNeedToWriteConfiguration()) {
return;
}
// todo: technically we need a lock here, realistically we should be fine.
needToWriteConfiguration = false;
scheduleMsg(&logger, "Writing pending configuration");
@ -83,10 +84,11 @@ static int isValidCrc(persistent_config_container_s *state) {
return FALSE;
}
crc_t result = flashStateCrc(state);
int isValidCrc = result == state->value;
if (!isValidCrc)
int isValidCrc_b = result == state->value;
if (!isValidCrc_b) {
scheduleMsg(&logger, "CRC got %d while %d expected", result, state->value);
return isValidCrc;
}
return isValidCrc_b;
}
static void doResetConfiguration(void) {

View File

@ -102,7 +102,7 @@ static float offTime;
static float delayMs;
static int count;
static brain_pin_e brainPin;
static io_pin_e pin;
static io_pin_e pinX;
static void pinbench(const char *delayStr, const char *onTimeStr, const char *offTimeStr, const char *countStr,
io_pin_e pinParam, brain_pin_e brainPinParam) {
@ -112,7 +112,7 @@ static void pinbench(const char *delayStr, const char *onTimeStr, const char *of
count = atoi(countStr);
brainPin = brainPinParam;
pin = pinParam;
pinX = pinParam;
needToRunBench = TRUE;
}
@ -126,7 +126,7 @@ static void fuelbench2(const char *delayStr, const char *indexStr, const char *
static void fuelpumpbench(int delayParam, int onTimeParam) {
brainPin = boardConfiguration->fuelPumpPin;
pin = FUEL_PUMP_RELAY;
pinX = FUEL_PUMP_RELAY;
delayMs = delayParam;
onTime = onTimeParam;
@ -162,7 +162,7 @@ static msg_t benchThread(int param) {
chThdSleepMilliseconds(200);
}
needToRunBench = FALSE;
runBench(brainPin, pin, delayMs, onTime, offTime, count);
runBench(brainPin, pinX, delayMs, onTime, offTime, count);
}
#if defined __GNUC__
return 0;
@ -173,8 +173,9 @@ void initInjectorCentral(void) {
initLogging(&logger, "InjectorCentral");
chThdCreateStatic(benchThreadStack, sizeof(benchThreadStack), NORMALPRIO, (tfunc_t) benchThread, NULL);
for (int i = 0; i < engineConfiguration->cylindersCount; i++)
for (int i = 0; i < engineConfiguration->cylindersCount; i++) {
is_injector_enabled[i] = true;
}
// todo: should we move this code closer to the injection logic?
for (int i = 0; i < engineConfiguration->cylindersCount; i++) {

View File

@ -130,6 +130,9 @@ static void prepareCurrentSecondLine(int index) {
case 3:
ptr = prepareStatusLine(buffer);
break;
default:
firmwareError("unexpected case");
return;
}
*ptr = ' ';
}

View File

@ -13,3 +13,28 @@ float getAfr(void) {
return interpolate(sensor->v1, sensor->value1, sensor->v2, sensor->value2, volts);
}
void initEgoSensor(afr_sensor_s *sensor, ego_sensor_e type) {
switch (type) {
case ES_BPSX_D1:
/**
* This decodes BPSX D1 Wideband Controller analog signal
*/
sensor->v1 = 0;
sensor->value1 = 9;
sensor->v2 = 5;
sensor->value2 = 19;
break;
case ES_Innovate_MTX_L:
sensor->v1 = 0;
sensor->value1 = 7.35;
sensor->v2 = 5;
sensor->value2 = 22.39;
break;
default:
firmwareError("Unexpected EGO %d", type);
break;
}
}

View File

@ -11,7 +11,10 @@
#define EGO_H_
#include "main.h"
#include "rusefi_enums.h"
#include "engine_configuration.h"
float getAfr(void);
void initEgoSensor(afr_sensor_s *sensor, ego_sensor_e type);
#endif

View File

@ -35,14 +35,6 @@ static Logging logger;
static char LOGGING_BUFFER[1000];
extern engine_configuration_s *engineConfiguration;
extern engine_configuration2_s *engineConfiguration2;
extern board_configuration_s *boardConfiguration;
static void doPrintConfiguration(void) {
printConfiguration(engineConfiguration, engineConfiguration2);
}
/*
static void printIntArray(int array[], int size) {
for (int j = 0; j < size; j++) {
@ -106,6 +98,12 @@ const char* getConfigurationName(engine_configuration_s *engineConfiguration) {
return "Rover v8";
case MITSU_4G93:
return "Mitsu 4G93";
case MIATA_1990:
return "Miata 1990";
case MIATA_1994:
return "Miata 1994";
case MIATA_1996:
return "Miata 1996";
default:
firmwareError("Unexpected: engineType %d", engineConfiguration->engineType);
return NULL;
@ -131,6 +129,8 @@ static const char * boolToString(bool value) {
return value ? "Yes" : "No";
}
extern board_configuration_s *boardConfiguration;
/**
* @brief Prints current engine configuration to human-readable console.
*/
@ -183,7 +183,7 @@ void printConfiguration(engine_configuration_s *engineConfiguration, engine_conf
// scheduleMsg(&logger, "analogChartMode: %d", engineConfiguration->analogChartMode);
// scheduleMsg(&logger, "crankingRpm: %d", engineConfiguration->crankingSettings.crankingRpm);
scheduleMsg(&logger, "crankingRpm: %d", engineConfiguration->crankingSettings.crankingRpm);
scheduleMsg(&logger, "idlePinMode: %s", pinModeToString(boardConfiguration->idleValvePinMode));
scheduleMsg(&logger, "malfunctionIndicatorPinMode: %s",
@ -191,7 +191,7 @@ void printConfiguration(engine_configuration_s *engineConfiguration, engine_conf
scheduleMsg(&logger, "analogInputDividerCoefficient: %f", engineConfiguration->analogInputDividerCoefficient);
scheduleMsg(&logger, "needSecondTriggerInput: %s",
boolToString(engineConfiguration2->triggerShape.needSecondTriggerInput));
boolToString(engineConfiguration->needSecondTriggerInput));
#if EFI_PROD_CODE
scheduleMsg(&logger, "idleValvePin: %s", hwPortname(boardConfiguration->idleValvePin));
@ -232,9 +232,20 @@ void printConfiguration(engine_configuration_s *engineConfiguration, engine_conf
scheduleMsg(&logger, "digitalPotentiometer CS%d %s", i,
hwPortname(boardConfiguration->digitalPotentiometerChipSelect[i]));
}
scheduleMsg(&logger, "spi 1=%s/2=%s/3=%s", boolToString(boardConfiguration->is_enabled_spi_1),
boolToString(boardConfiguration->is_enabled_spi_2), boolToString(boardConfiguration->is_enabled_spi_3));
#endif /* EFI_PROD_CODE */
}
extern engine_configuration_s *engineConfiguration;
extern engine_configuration2_s *engineConfiguration2;
static void doPrintConfiguration(void) {
printConfiguration(engineConfiguration, engineConfiguration2);
}
static void setFixedModeTiming(int value) {
engineConfiguration->fixedModeTiming = value;
doPrintConfiguration();
@ -495,21 +506,22 @@ static void setWholeTimingMap(float value) {
static void setWholeFuelMapCmd(float value) {
scheduleMsg(&logger, "Setting whole fuel map to %f", value);
if (engineConfiguration->algorithm == LM_SPEED_DENSITY) {
scheduleMsg(&logger, "WARNING: setting fuel map in SD mode is pointless");
}
setWholeFuelMap(engineConfiguration, value);
}
static void setTriggerInputPin(const char *indexStr, const char *pinName) {
#if EFI_PROD_CODE
static void setTriggerInputPin(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 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) {
@ -591,6 +603,32 @@ static void setFuelMap(const char * rpmStr, const char *loadStr, const char *val
scheduleMsg(&logger, "Setting fuel map entry %d:%d to %f", rpmIndex, loadIndex, value);
}
static void setSpiMode(int index, bool mode) {
switch(index) {
case 1:
boardConfiguration->is_enabled_spi_1 = mode;
break;
case 2:
boardConfiguration->is_enabled_spi_2 = mode;
break;
case 3:
boardConfiguration->is_enabled_spi_3 = mode;
break;
default:
scheduleMsg(&logger, "invalid spi index %d", index);
return;
}
scheduleMsg(&logger, "spi %d mode: %s", index, boolToString(mode));
}
static void enableSpi(int index) {
setSpiMode(index, true);
}
static void disableSpi(int index) {
setSpiMode(index, false);
}
static void enableInjection(void) {
engineConfiguration->isInjectionEnabled = true;
scheduleMsg(&logger, "injection enabled");
@ -693,14 +731,17 @@ void initSettings(void) {
addConsoleAction("enable_self_stimulation", enableSelfStimulation);
addConsoleAction("disable_self_stimulation", disableSelfStimulation);
addConsoleActionI("enable_spi", enableSpi);
addConsoleActionI("disable_spi", disableSpi);
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_input_pin", setTriggerInputPin);
addConsoleActionSS("set_trigger_simulator_pin", setTriggerSimulatorPin);
addConsoleActionSS("set_trigger_simulator_mode", setTriggerSimulatorMode);

View File

@ -56,7 +56,6 @@
static LocalVersionHolder localVersion;
extern Engine engine;
static MainTriggerCallback mainTriggerCallbackInstance;
@ -96,11 +95,11 @@ static void handleFuelInjectionEvent(MainTriggerCallback *mainTriggerCallback, A
scheduleOutput(event->actuator, delay, fuelMs);
}
static void handleFuel(MainTriggerCallback *mainTriggerCallback, int eventIndex, int rpm) {
static void handleFuel(Engine *engine, MainTriggerCallback *mainTriggerCallback, int eventIndex, int rpm) {
if (!isInjectionEnabled(mainTriggerCallback->engineConfiguration))
return;
efiAssertVoid(getRemainingStack(chThdSelf()) > 16, "stack#3");
efiAssertVoid(eventIndex < 2 * mainTriggerCallback->engineConfiguration2->triggerShape.shaftPositionEventCount,
efiAssertVoid(eventIndex < mainTriggerCallback->engineConfiguration2->triggerShape.getLength(),
"event index");
/**
@ -225,6 +224,8 @@ void showMainHistogram(void) {
#endif
}
extern Engine engine;
/**
* This is the main trigger event handler.
* Both injection and ignition are controlled from this method.
@ -234,7 +235,8 @@ void onTriggerEvent(trigger_event_e ckpSignalType, int eventIndex, MainTriggerCa
"event index");
efiAssertVoid(getRemainingStack(chThdSelf()) > 16, "stack#3");
int rpm = getRpm();
// todo int rpm = getRpmE(mainTriggerCallback->engine);
int rpm = getRpmE(&engine);
if (rpm == 0) {
// this happens while we just start cranking
// todo: check for 'trigger->is_synchnonized?'
@ -287,7 +289,8 @@ void onTriggerEvent(trigger_event_e ckpSignalType, int eventIndex, MainTriggerCa
triggerEventsQueue.executeAll(getCrankEventCounter());
handleFuel(mainTriggerCallback, eventIndex, rpm);
//todo handleFuel(mainTriggerCallback->engine, mainTriggerCallback, eventIndex, rpm);
handleFuel(&engine, mainTriggerCallback, eventIndex, rpm);
handleSpark(mainTriggerCallback, eventIndex, rpm,
&mainTriggerCallback->engineConfiguration2->engineEventConfiguration.ignitionEvents[revolutionIndex]);
#if EFI_HISTOGRAMS && EFI_PROD_CODE
@ -307,6 +310,15 @@ static void showTriggerHistogram(void) {
#endif
}
void MainTriggerCallback::init(Engine *engine, engine_configuration2_s *engineConfiguration2) {
efiAssertVoid(engine!=NULL, "engine NULL");
this->engine = engine;
this->engineConfiguration = engine->engineConfiguration;
efiAssertVoid(engineConfiguration!=NULL, "engineConfiguration NULL");
this->engineConfiguration2 = engineConfiguration2;
}
static void showMainInfo(void) {
int rpm = getRpm();
float el = getEngineLoadT(mainTriggerCallbackInstance.engine);
@ -316,14 +328,6 @@ static void showMainInfo(void) {
#endif
}
void MainTriggerCallback::init(Engine *engine, engine_configuration2_s *engineConfiguration2) {
efiAssertVoid(engine!=NULL, "engine NULL");
this->engine = engine;
this->engineConfiguration = engine->engineConfiguration;
efiAssertVoid(engineConfiguration!=NULL, "engineConfiguration NULL");
this->engineConfiguration2 = engineConfiguration2;
}
void initMainEventListener(Engine *engine, engine_configuration2_s *engineConfiguration2) {
efiAssertVoid(engine!=NULL, "null engine");
@ -350,4 +354,6 @@ int isIgnitionTimingError(void) {
return ignitionErrorDetection.sum(6) > 4;
}
#endif /* EFI_ENGINE_CONTROL */

View File

@ -34,12 +34,19 @@ extern WaveChart waveChart;
#include "analog_chart.h"
#endif /* EFI_PROD_CODE */
static RpmCalculator rpmState;
#define UNREALISTIC_RPM 30000
#define TOP_DEAD_CENTER_MESSAGE "r"
/**
* @return -1 in case of isNoisySignal(), current RPM otherwise
*/
int getRpmE(Engine *engine) {
efiAssert(engine->rpmCalculator!=NULL, "rpmCalculator not assigned", -1);
return engine->rpmCalculator->rpm();
}
extern engine_configuration_s *engineConfiguration;
extern engine_configuration2_s *engineConfiguration2;
@ -73,10 +80,6 @@ bool isValidRpm(int rpm) {
return rpm > 0 && rpm < UNREALISTIC_RPM;
}
uint64_t getLastRpmEventTime(void) {
return rpmState.lastRpmEventTimeUs;
}
#if (EFI_PROD_CODE || EFI_SIMULATOR) || defined(__DOXYGEN__)
bool isCranking(void) {
int rpm = getRpm();
@ -84,29 +87,6 @@ bool isCranking(void) {
}
#endif
/**
* @return -1 in case of isNoisySignal(), current RPM otherwise
*/
int getRpmE(Engine *engine) {
efiAssert(engine->rpmCalculator!=NULL, "rpmCalculator not assigned", -1);
return engine->rpmCalculator->rpm();
}
/**
* @return Current crankshaft angle, 0 to 720 for four-stroke
*/
float getCrankshaftAngle(uint64_t timeUs) {
uint64_t timeSinceZeroAngle = timeUs - rpmState.lastRpmEventTimeUs;
float cRevolutionTimeMs = getCrankshaftRevolutionTimeMs(rpmState.rpm());
return 360.0 * timeSinceZeroAngle / cRevolutionTimeMs / 1000;
}
int getRevolutionCounter(void) {
return rpmState.revolutionCounter;
}
/**
* Checks for noise on the trigger input line. Noise is detected by an unexpectedly small time gap between
* current and previous trigger input events.
@ -201,16 +181,37 @@ static void onTdcCallback(void) {
/**
* 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) {
bool isTriggerSynchronizationPoint = index == 0;
static void tdcMarkCallback(trigger_event_e ckpSignalType, int index0, void *arg) {
bool isTriggerSynchronizationPoint = index0 == 0;
if (isTriggerSynchronizationPoint) {
int index = getRevolutionCounter() % 2;
int revIndex2 = getRevolutionCounter() % 2;
// todo: use event-based scheduling, not just time-based scheduling
scheduleByAngle(&tdcScheduler[index], engineConfiguration->globalTriggerAngleOffset, (schfunc_t) onTdcCallback, NULL);
scheduleByAngle(&tdcScheduler[revIndex2], engineConfiguration->globalTriggerAngleOffset, (schfunc_t) onTdcCallback, NULL);
}
}
#endif
static RpmCalculator rpmState;
uint64_t getLastRpmEventTime(void) {
return rpmState.lastRpmEventTimeUs;
}
int getRevolutionCounter(void) {
return rpmState.revolutionCounter;
}
/**
* @return Current crankshaft angle, 0 to 720 for four-stroke
*/
float getCrankshaftAngle(uint64_t timeUs) {
uint64_t timeSinceZeroAngle = timeUs - rpmState.lastRpmEventTimeUs;
float cRevolutionTimeMs = getCrankshaftRevolutionTimeMs(rpmState.rpm());
return 360.0 * timeSinceZeroAngle / cRevolutionTimeMs / 1000;
}
void initRpmCalculator(void) {
#if (EFI_PROD_CODE || EFI_SIMULATOR) || defined(__DOXYGEN__)
initLogging(&logger, "rpm calc");

View File

@ -145,16 +145,31 @@ void printAllCallbacksHistogram(void) {
#endif
}
#if EFI_PROD_CODE || EFI_SIMULATOR
// todo: eliminate this extern which is needed by 'triggerInfo'
extern engine_configuration_s *engineConfiguration;
extern engine_configuration2_s * engineConfiguration2;
#endif
static void triggerInfo() {
#if EFI_PROD_CODE
scheduleMsg(&logging, "trigger %d/%d/%d/%d", triggerCentral.getHwEventCounter(0),
#if EFI_PROD_CODE || EFI_SIMULATOR
scheduleMsg(&logging, "trigger event counters %d/%d/%d/%d", triggerCentral.getHwEventCounter(0),
triggerCentral.getHwEventCounter(1), triggerCentral.getHwEventCounter(2),
triggerCentral.getHwEventCounter(3));
scheduleMsg(&logging, "trigger type=%d/need2ndChannel=%d",
engineConfiguration->triggerConfig.triggerType,
engineConfiguration->needSecondTriggerInput);
scheduleMsg(&logging, "expected duty #0=%f/#1=%f", engineConfiguration2->triggerShape.dutyCycle[0],
engineConfiguration2->triggerShape.dutyCycle[1]);
#endif
}
float getTriggerDutyCycle(int index) {
return triggerCentral.triggerState.getTriggerDutyCycle(index);
}
void initTriggerCentral(void) {
#if EFI_PROD_CODE
#if EFI_PROD_CODE || EFI_SIMULATOR
initLogging(&logging, "ShaftPosition");
addConsoleAction("triggerinfo", triggerInfo);
#endif

View File

@ -35,6 +35,7 @@ private:
uint64_t getCrankEventCounter(void);
uint64_t getStartOfRevolutionIndex(void);
void hwHandleShaftSignal(trigger_event_e signal);
float getTriggerDutyCycle(int index);
void initTriggerCentral(void);
void printAllCallbacksHistogram(void);

View File

@ -13,7 +13,6 @@ void configureNeonTriggerShape(trigger_shape_s *s) {
setTriggerSynchronizationGap(s, 0.72);
s->useRiseEdge = false;
s->needSecondTriggerInput = true;
// voodoo magic - we always need 720 at the end

View File

@ -30,9 +30,8 @@
#include "trigger_structure.h"
#if (EFI_PROD_CODE || EFI_SIMULATOR) || defined(__DOXYGEN__)
static Logging logger;
#endif
// todo: better name for this constant
#define HELPER_PERIOD 100000
static cyclic_buffer errorDetection;
@ -66,6 +65,12 @@ static inline bool noSynchronizationResetNeeded(TriggerState *shaftPositionState
return shaftPositionState->getCurrentIndex() >= triggerShape->shaftPositionEventCount - 1;
}
float TriggerState::getTriggerDutyCycle(int index) {
float time = prevTotalTime[index];
return 100 * time / prevCycleDuration;
}
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 };
@ -94,7 +99,7 @@ void TriggerState::decodeTriggerEvent(trigger_shape_s const*triggerShape, trigge
int64_t currentDuration = isFirstEvent ? 0 : nowUs - toothed_previous_time;
isFirstEvent = false;
efiAssertVoid(currentDuration >= 0, "negative duration?");
efiAssertVoid(currentDuration >= 0, "decode: negative duration?");
// todo: skip a number of signal from the beginning
@ -126,7 +131,7 @@ void TriggerState::decodeTriggerEvent(trigger_shape_s const*triggerShape, trigge
shaft_is_synchronized = true;
// this call would update duty cycle values
// nextTriggerEvent(triggerWheel, nowUs);
nextTriggerEvent(triggerWheel, nowUs);
nextRevolution(triggerShape->shaftPositionEventCount, nowUs);
} else {
@ -200,12 +205,11 @@ void initializeTriggerShape(Logging *logger, engine_configuration_s *engineConfi
setTriggerSynchronizationGap(triggerShape, 2);
triggerShape->useRiseEdge = TRUE;
triggerShape->needSecondTriggerInput = TRUE;
switch (triggerConfig->triggerType) {
case TT_TOOTHED_WHEEL:
engineConfiguration2->triggerShape.needSecondTriggerInput = false;
// todo: move to into configuration definition engineConfiguration2->triggerShape.needSecondTriggerInput = false;
engineConfiguration2->triggerShape.isSynchronizationNeeded =
engineConfiguration->triggerConfig.customIsSynchronizationNeeded;
@ -214,6 +218,10 @@ void initializeTriggerShape(Logging *logger, engine_configuration_s *engineConfi
triggerConfig->customSkippedToothCount, getOperationMode(engineConfiguration));
return;
case TT_MAZDA_MIATA_NA:
initializeMazdaMiataNaShape(triggerShape);
return;
case TT_MAZDA_MIATA_NB:
initializeMazdaMiataNbShape(triggerShape);
return;
@ -274,6 +282,7 @@ void initializeTriggerShape(Logging *logger, engine_configuration_s *engineConfi
TriggerStimulatorHelper::TriggerStimulatorHelper() {
primaryWheelState = false;
secondaryWheelState = false;
thirdWheelState = false;
}
void TriggerStimulatorHelper::nextStep(TriggerState *state, trigger_shape_s * shape, int i,
@ -282,10 +291,11 @@ void TriggerStimulatorHelper::nextStep(TriggerState *state, trigger_shape_s * sh
int loopIndex = i / shape->getSize();
int time = (int) (10000 * (loopIndex + shape->wave.getSwitchTime(stateIndex)));
int time = (int) (HELPER_PERIOD * (loopIndex + shape->wave.getSwitchTime(stateIndex)));
bool newPrimaryWheelState = shape->wave.getChannelState(0, stateIndex);
bool newSecondaryWheelState = shape->wave.getChannelState(1, stateIndex);
bool new3rdWheelState = shape->wave.getChannelState(2, stateIndex);
if (primaryWheelState != newPrimaryWheelState) {
primaryWheelState = newPrimaryWheelState;
@ -298,19 +308,28 @@ void TriggerStimulatorHelper::nextStep(TriggerState *state, trigger_shape_s * sh
trigger_event_e s = secondaryWheelState ? SHAFT_SECONDARY_UP : SHAFT_SECONDARY_DOWN;
state->decodeTriggerEvent(shape, triggerConfig, s, time);
}
if (thirdWheelState != new3rdWheelState) {
thirdWheelState = new3rdWheelState;
trigger_event_e s = thirdWheelState ? SHAFT_3RD_UP : SHAFT_3RD_DOWN;
state->decodeTriggerEvent(shape, triggerConfig, s, time);
}
}
static void onFindIndex(TriggerState *state) {
for (int i = 0; i < PWM_PHASE_MAX_WAVE_PER_PWM; i++) {
// todo: that's not the best place for this intermediate data storage, fix it!
state->expectedTotalTime[i] = state->totalTime[i];
}
}
static int doFindTrigger(TriggerStimulatorHelper *helper, trigger_shape_s * shape, trigger_config_s const*triggerConfig,
TriggerState *state) {
static uint32_t 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();;
return i;
}
firmwareError("findTriggerZeroEventIndex() failed");
return EFI_ERROR_CODE;
@ -322,33 +341,44 @@ static int doFindTrigger(TriggerStimulatorHelper *helper, trigger_shape_s * shap
*
* This function finds the index of synchronization event within trigger_shape_s
*/
int findTriggerZeroEventIndex(trigger_shape_s * shape, trigger_config_s const*triggerConfig) {
uint32_t findTriggerZeroEventIndex(trigger_shape_s * shape, trigger_config_s const*triggerConfig) {
TriggerState state;
errorDetection.clear();
TriggerStimulatorHelper helper;
int index = doFindTrigger(&helper, shape, triggerConfig, &state);
uint32_t index = doFindTrigger(&helper, shape, triggerConfig, &state);
if (index == EFI_ERROR_CODE) {
return index;
}
efiAssert(state.getTotalRevolutionCounter() == 1, "totalRevolutionCounter", EFI_ERROR_CODE);
/**
* 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;
for (uint32_t i = index + 1; i <= index + 2 * shape->getSize(); i++) {
helper.nextStep(&state, shape, i, triggerConfig);
}
efiAssert(state.getTotalRevolutionCounter() > 1, "totalRevolutionCounter2", EFI_ERROR_CODE);
for (int i = 0; i < PWM_PHASE_MAX_WAVE_PER_PWM; i++) {
shape->dutyCycle[i] = 1.0 * state.expectedTotalTime[i] / HELPER_PERIOD;
}
return index;
return index % shape->getSize();
}
#if (EFI_PROD_CODE || EFI_SIMULATOR) || defined(__DOXYGEN__)
//static Logging logger;
#endif
void initTriggerDecoder(void) {
#if EFI_PROD_CODE || EFI_SIMULATOR
initLogging(&logger, "trigger decoder");
// initLogging(&logger, "trigger decoder");
#endif
}

View File

@ -27,15 +27,27 @@ public:
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);
float getTriggerDutyCycle(int index);
TriggerStateCallback cycleCallback;
/**
* TRUE if we know where we are
*/
unsigned char shaft_is_synchronized;
bool shaft_is_synchronized;
uint64_t toothed_previous_duration;
uint64_t toothed_previous_time;
/**
* Here we accumulate the amount of time this signal was ON within current trigger cycle
*/
int totalTime[PWM_PHASE_MAX_WAVE_PER_PWM];
/**
* Total time result for previous trigger cycle
*/
int prevTotalTime[PWM_PHASE_MAX_WAVE_PER_PWM];
int expectedTotalTime[PWM_PHASE_MAX_WAVE_PER_PWM];
private:
void clear();
/**
@ -48,10 +60,11 @@ private:
*/
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;
uint64_t prevCycleDuration;
uint64_t startOfCycle;
};
class TriggerStimulatorHelper {
@ -61,10 +74,11 @@ public:
private:
bool primaryWheelState;
bool secondaryWheelState;
bool thirdWheelState;
};
void initializeSkippedToothTriggerShapeExt(trigger_shape_s *s, int totalTeethCount, int skippedCount, operation_mode_e operationMode);
int findTriggerZeroEventIndex(trigger_shape_s * shape, trigger_config_s const*triggerConfig);
uint32_t findTriggerZeroEventIndex(trigger_shape_s * shape, trigger_config_s const*triggerConfig);
void initializeTriggerShape(Logging *logger, engine_configuration_s *engineConfiguration, engine_configuration2_s *engineConfiguration2);
void initTriggerDecoder(void);

View File

@ -20,6 +20,35 @@
#include "trigger_mazda.h"
void initializeMazdaMiataNaShape(trigger_shape_s *s) {
s->reset(FOUR_STROKE_CAM_SENSOR);
setTriggerSynchronizationGap(s, 1.68f);
float z = 0.093;
s->useRiseEdge = false;
s->isSynchronizationNeeded = true;
s->addEvent(180.0f - 1.75 * z * 720, T_SECONDARY, TV_HIGH);
s->addEvent(180.0f - 0.75 * z * 720, T_SECONDARY, TV_LOW);
s->addEvent(360.0f - 2 * z * 720, T_PRIMARY, TV_HIGH);
s->addEvent(360.0f - 1.75 * z * 720, T_SECONDARY, TV_HIGH);
s->addEvent(360.0f - z * 720, T_PRIMARY, TV_LOW);
s->addEvent(360.0f - 0.75 * z * 720, T_SECONDARY, TV_LOW);
s->addEvent(540.0f - 1.75 * z * 720, T_SECONDARY, TV_HIGH);
s->addEvent(540.0f - 0.75 * z * 720, T_SECONDARY, TV_LOW);
s->addEvent(720.0f - 2 * z * 720, T_PRIMARY, TV_HIGH);
s->addEvent(720.0f - 1.75 * z * 720, T_SECONDARY, TV_HIGH);
s->addEvent(720.0f - 0.75 * z * 720, T_SECONDARY, TV_LOW);
s->addEvent(720.0f, T_PRIMARY, TV_LOW);
s->shaftPositionEventCount = s->getSize();
}
void initializeMazdaMiataNbShape(trigger_shape_s *s) {
setTriggerSynchronizationGap(s, 0.11f);
s->useRiseEdge = false;
@ -62,7 +91,7 @@ void initializeMazdaMiataNbShape(trigger_shape_s *s) {
void configureMazdaProtegeLx(trigger_shape_s *s) {
s->needSecondTriggerInput = FALSE;
// todo: move to into configuration definition s->needSecondTriggerInput = FALSE;
s->reset(FOUR_STROKE_CAM_SENSOR);

View File

@ -12,6 +12,7 @@
#include "engine_configuration.h"
#include "ec2.h"
void initializeMazdaMiataNaShape(trigger_shape_s *s);
void initializeMazdaMiataNbShape(trigger_shape_s *s);
void configureMazdaProtegeLx(trigger_shape_s *s);

View File

@ -106,11 +106,12 @@ void multi_wave_s::setSwitchTime(int index, float value) {
TriggerState::TriggerState() {
cycleCallback = NULL;
shaft_is_synchronized = FALSE;
shaft_is_synchronized = false;
toothed_previous_time = 0;
toothed_previous_duration = 0;
totalRevolutionCounter = 0;
clear();
memset(expectedTotalTime, 0, sizeof(expectedTotalTime));
totalEventCountBase = 0;
isFirstEvent = true;
}
@ -131,6 +132,9 @@ void TriggerState::nextRevolution(int triggerEventCount, uint64_t nowUs) {
if (cycleCallback != NULL) {
cycleCallback(this);
}
memcpy(prevTotalTime, totalTime, sizeof(prevTotalTime));
prevCycleDuration = nowUs - startOfCycle;
startOfCycle = nowUs;
clear();
totalRevolutionCounter++;
totalEventCountBase += triggerEventCount;
@ -143,9 +147,11 @@ int TriggerState::getTotalRevolutionCounter() {
void TriggerState::nextTriggerEvent(trigger_wheel_e triggerWheel, uint64_t nowUs) {
uint64_t prevTime = timeOfPreviousEvent[triggerWheel];
if (prevTime != 0) {
// even event - apply the value
totalTime[triggerWheel] += (nowUs - prevTime);
timeOfPreviousEvent[triggerWheel] = 0;
} else {
// odd event - start accumulation
timeOfPreviousEvent[triggerWheel] = nowUs;
}
@ -159,6 +165,10 @@ void TriggerState::clear() {
current_index = 0;
}
uint32_t trigger_shape_s::getLength() const {
return operationMode == FOUR_STROKE_CAM_SENSOR ? shaftPositionEventCount : 2 * shaftPositionEventCount;
}
float trigger_shape_s::getAngle(int index) const {
if (operationMode == FOUR_STROKE_CAM_SENSOR) {
return getSwitchAngle(index);
@ -261,7 +271,7 @@ void setToothedWheelConfiguration(trigger_shape_s *s, int total, int skipped,
s->totalToothCount = total;
s->skippedToothCount = skipped;
s->needSecondTriggerInput = false;
// todo: move to into configuration definition s->needSecondTriggerInput = false;
s->useRiseEdge = true;
initializeSkippedToothTriggerShapeExt(s, s->totalToothCount, s->skippedToothCount,

View File

@ -34,6 +34,8 @@ public:
int totalToothCount;
int skippedToothCount;
float dutyCycle[PWM_PHASE_MAX_WAVE_PER_PWM];
float syncRatioFrom;
float syncRatioTo;
@ -44,7 +46,6 @@ public:
*/
int expectedEventCount[PWM_PHASE_MAX_WAVE_PER_PWM];
bool needSecondTriggerInput;
void addEvent(float angle, trigger_wheel_e const waveIndex, trigger_value_e const state);
void reset(operation_mode_e operationMode);
int getSize() const;
@ -57,6 +58,11 @@ public:
*/
int shaftPositionEventCount;
/**
* this one is per CRANKshaft revolution
*/
uint32_t getLength() const;
// todo: add a runtime validation which would verify that this field was set properly
// tood: maybe even automate this flag calculation?
int initialState[PWM_PHASE_MAX_WAVE_PER_PWM];

View File

@ -104,8 +104,12 @@ void turnOnSpi(spi_device_e device) {
}
void initSpiModules(void) {
turnOnSpi(SPI_DEVICE_2);
turnOnSpi(SPI_DEVICE_3);
if (boardConfiguration->is_enabled_spi_2) {
turnOnSpi(SPI_DEVICE_2);
}
if (boardConfiguration->is_enabled_spi_3) {
turnOnSpi(SPI_DEVICE_3);
}
}
static I2CConfig i2cfg = { OPMODE_I2C, 100000, STD_DUTY_CYCLE, };
@ -138,7 +142,6 @@ void initHardware(Logging *logger) {
chMtxInit(&spiMtx);
#if EFI_HISTOGRAMS
/**
* histograms is a data structure for CPU monitor, it does not depend on configuration
@ -183,11 +186,11 @@ void initHardware(Logging *logger) {
mySetPadMode("board test", getHwPort(boardConfiguration->boardTestModeJumperPin),
getHwPin(boardConfiguration->boardTestModeJumperPin), PAL_MODE_INPUT_PULLUP);
bool isBoardTestMode = GET_BOARD_TEST_MODE_VALUE();
bool isBoardTestMode_b = GET_BOARD_TEST_MODE_VALUE();
initAdcInputs();
if (isBoardTestMode) {
if (isBoardTestMode_b) {
initBoardTest();
efiAssertVoid(FALSE, "board test done");
}

View File

@ -1,5 +1,5 @@
/**
* @file trigger_input.c
* @file trigger_input.cpp
* @brief Position sensor hardware layer
*
* @date Dec 30, 2012
@ -38,8 +38,10 @@ static inline ICUDriver *getSecondaryInputCaptureDriver(void) {
* 'width' events happens before the 'period' event
*/
static void shaft_icu_width_callback(ICUDriver *icup) {
// todo: support for 3rd trigger input channel
// todo: start using real event time from HW event, not just software timer?
int isPrimary = icup == getPrimaryInputCaptureDriver();
if (!isPrimary && !engineConfiguration2->triggerShape.needSecondTriggerInput) {
if (!isPrimary && !engineConfiguration->needSecondTriggerInput) {
return;
}
// icucnt_t last_width = icuGetWidth(icup); so far we are fine with system time
@ -51,7 +53,7 @@ static void shaft_icu_width_callback(ICUDriver *icup) {
static void shaft_icu_period_callback(ICUDriver *icup) {
int isPrimary = icup == getPrimaryInputCaptureDriver();
if (!isPrimary && !engineConfiguration2->triggerShape.needSecondTriggerInput) {
if (!isPrimary && !engineConfiguration->needSecondTriggerInput) {
return;
}

View File

@ -91,7 +91,7 @@
</option>
<option>
<name>GeneralEnableMisra</name>
<state>0</state>
<state>1</state>
</option>
<option>
<name>GeneralMisraVerbose</name>
@ -120,16 +120,16 @@
<option>
<name>GeneralMisraRules98</name>
<version>0</version>
<state>0000111110010001101110011100111100101110011001000101000111101101100001111111011100110001111001100111001101110101011111111111111</state>
<state>0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000</state>
</option>
<option>
<name>GeneralMisraVer</name>
<state>1</state>
<state>0</state>
</option>
<option>
<name>GeneralMisraRules04</name>
<version>0</version>
<state>111101110010111111111000110111111111111111111111111110010111101111010101111111111111111111111111101111111011111001111011111011111111111111111</state>
<state>011100010000100010000000000011011000000000001000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000</state>
</option>
<option>
<name>RTConfigPath2</name>

View File

@ -5,7 +5,7 @@
define symbol __ICFEDIT_intvec_start__ = 0x08000000;
/*-Memory Regions-*/
define symbol __ICFEDIT_region_ROM_start__ = 0x08000000;
define symbol __ICFEDIT_region_ROM_end__ = 0x0801FFFF;
define symbol __ICFEDIT_region_ROM_end__ = 0x0803FFFF;
define symbol __ICFEDIT_region_RAM_start__ = 0x20000000;
define symbol __ICFEDIT_region_RAM_end__ = 0x2001FFFF;
define symbol __ICFEDIT_region_CCMRAM_start__ = 0x10000000;

View File

@ -229,5 +229,5 @@ void firmwareError(const char *fmt, ...) {
}
int getRusEfiVersion(void) {
return 20140822;
return 20140829;
}

View File

@ -1,6 +1,6 @@
; this is TunerStudio project for www.rusefi.com DIY engine management system
; version 20140823
; version 20140828
; this should stop TS from looking for the CAN ID in the 2nd byte location and allow the page reads to work correctly.
enable2ndByteCanID = false
@ -115,9 +115,9 @@ enable2ndByteCanID = false
crankingInjectionMode = scalar, U32, 928, "°C", 1, 0, 0, 1000.0, 2 ; size 4
injectionMode = scalar, U32, 932, "°C", 1, 0, 0, 1000.0, 2 ; size 4
globalTriggerOffsetAngle = scalar, F32, 936, "RPM", 1, 0, 0, 720, 0 ; size 4
analogInputDividerCoefficient=scalar, F32, 940, "RPM", 1, 0, 1, 10.0, 2 ; size 4
analogInputDividerCoefficient=scalar, F32, 940, "RPM", 1, 0, 0.01, 10.0, 2 ; size 4
fuelAlgorithm = bits, U32, 944, [0:1], "MAF", "Alpha-N", "MAP", "SPEED DENSITY"
VBattDividerCoefficient = scalar, F32, 948, "RPM", 1, 0, 1, 10.0, 2 ; size 4
VBattDividerCoefficient = scalar, F32, 948, "RPM", 1, 0, 0.01, 10.0, 2 ; size 4
FanONTemperature = scalar, F32, 952, "°C", 1, 0, 0, 1000.0, 2 ; size 4
FanOffTemperature = scalar, F32, 956, "°C", 1, 0, 0, 1000.0, 2 ; size 4
CanReadEnabled = bits, U32, 960, [0:0], "false", "true"
@ -150,10 +150,10 @@ enable2ndByteCanID = false
iatAdcInput = bits, U32, 1068, [0:3] "PA0", "PA1", "PA2", "PA3", "PA4", "PA5", "PA6", "PA7", "PB0", "PB1", "PC0", "PC1", "PC2", "PC3", "PC4", "PC5"
mafAdcInput = bits, U32, 1072, [0:3] "PA0", "PA1", "PA2", "PA3", "PA4", "PA5", "PA6", "PA7", "PB0", "PB1", "PC0", "PC1", "PC2", "PC3", "PC4", "PC5"
afrAdcInput = bits, U32, 1076, [0:3] "PA0", "PA1", "PA2", "PA3", "PA4", "PA5", "PA6", "PA7", "PB0", "PB1", "PC0", "PC1", "PC2", "PC3", "PC4", "PC5"
afr_v1 = scalar, F32, 1080, "RPM", 1, 0.0, 0, 1000.0, 2 ; size 4
afr_value1 = scalar, F32, 1084, "RPM", 1, 0.0, 0, 1000.0, 2 ; size 4
afr_v2 = scalar, F32, 1088, "RPM", 1, 0.0, 0, 1000.0, 2 ; size 4
afr_value2 = scalar, F32, 1092, "RPM", 1, 0.0, 0, 1000.0, 2 ; size 4
afr_v1 = scalar, F32, 1080, "volts", 1, 0.0, 0, 10.0, 2 ; size 4
afr_value1 = scalar, F32, 1084, "AFR", 1, 0.0, 0, 1000.0, 2 ; size 4
afr_v2 = scalar, F32, 1088, "volts", 1, 0.0, 0, 10.0, 2 ; size 4
afr_value2 = scalar, F32, 1092, "AFR", 1, 0.0, 0, 1000.0, 2 ; size 4
injectionOffset = scalar, F32, 1096, "RPM", 1, 0.0, 0, 1000.0, 2 ; size 4
crankingTimingAngle = scalar, F32, 1100, "RPM", 1, 0.0, 0, 1000.0, 2 ; size 4
baroSensorType = scalar, U32, 1104, "index", 1, 0, 0, 300, 0 ; size 4
@ -167,10 +167,11 @@ enable2ndByteCanID = false
afrKeyBins = array, F32, 1252, [16], "Load", 1, 0.0, 0, 300.0, 2; size 64
afrRpmBins = array, F32, 1316, [16], "RPM", 1, 0.0, 0, 18000.0, 2; size 64
fuelTable = array, F32, 1380, [16x16],"ms", 1, 0, 0.0, 300.0, 2; size 1024
ignitionTable = array, F32, 2404, [16x16],"deg", 1, 0.0, -360, 360, 2; size 1024
veTable = array, F32, 3428, [16x16],"deg", 1, 0.0, 0, 100.0, 2; size 1024
afrTable = array, F32, 4452, [16x16],"deg", 1, 0.0, 0, 25.0, 2; size 1024
; name = array, type, offset, shape, units, scale, translate, lo, hi, digits
fuelTable = array, F32, 1380, [16x16],"ms", 0.1, 0, 0.0, 300.0, 2; size 1024
ignitionTable = array, F32, 2404, [16x16],"deg", 1, 0, -360, 360, 2; size 1024
veTable = array, F32, 3428, [16x16],"deg", 0.05, 0, 0, 100.0, 2; size 1024
afrTable = array, F32, 4452, [16x16],"deg", 0.1, 0, 0, 25.0, 2; size 1024
idleValvePin = bits, U32, 5476, [0:6], "GPIOA_0", "GPIOA_1", "GPIOA_2", "GPIOA_3", "GPIOA_4", "GPIOA_5", "GPIOA_6", "GPIOA_7", "GPIOA_8", "GPIOA_9", "GPIOA_10", "GPIOA_11", "GPIOA_12", "GPIOA_13", "GPIOA_14", "GPIOA_15", "GPIOB_0", "GPIOB_1", "GPIOB_2", "GPIOB_3", "GPIOB_4", "GPIOB_5", "GPIOB_6", "GPIOB_7", "GPIOB_8", "GPIOB_9", "GPIOB_10", "GPIOB_11", "GPIOB_12", "GPIOB_13", "GPIOB_14", "GPIOB_15", "GPIOC_0", "GPIOC_1", "GPIOC_2", "GPIOC_3", "GPIOC_4", "GPIOC_5", "GPIOC_6", "GPIOC_7", "GPIOC_8", "GPIOC_9", "GPIOC_10", "GPIOC_11", "GPIOC_12", "GPIOC_13", "GPIOC_14", "GPIOC_15", "GPIOD_0", "GPIOD_1", "GPIOD_2", "GPIOD_3", "GPIOD_4", "GPIOD_5", "GPIOD_6", "GPIOD_7", "GPIOD_8", "GPIOD_9", "GPIOD_10", "GPIOD_11", "GPIOD_12", "GPIOD_13", "GPIOD_14", "GPIOD_15", "GPIOE_0", "GPIOE_1", "GPIOE_2", "GPIOE_3", "GPIOE_4", "GPIOE_5", "GPIOE_6", "GPIOE_7", "GPIOE_8", "GPIOE_9", "GPIOE_10", "GPIOE_11", "GPIOE_12", "GPIOE_13", "GPIOE_14", "GPIOE_15", "NONE", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID"
idleValvePinMode = bits, U32, 5480, [0:1], "default", "default inverted", "open", "open inverted"
@ -323,6 +324,11 @@ enable2ndByteCanID = false
ind_need_burn = bits, U32, 72, [9:9], "true", "false";
ind_2nd_trigger_en=bits, U32, 72, [10:10], "true", "false";
ind_tps_error = bits, U32, 80, [0:0], "true", "false";
ind_clt_error = bits, U32, 80, [1:1], "true", "false";
ind_map_error = bits, U32, 80, [2:2], "true", "false";
ind_iat_error = bits, U32, 80, [3:3], "true", "false";
time = { timeNow }
[CurveEditor]
@ -463,6 +469,12 @@ enable2ndByteCanID = false
indicator = { ind_need_burn}, "no Burn", "Need Burn", white, black, red, black
indicator = { ind_has_sd}, "no SD", "with SD", white, black, green, black
indicator = { ind_fuel_pump}, "no pump", "pump", white, black, green, black
; error codes
indicator = { ind_tps_error}, "tps", "tps error", white, black, red, black
indicator = { ind_clt_error}, "clt", "clt error", white, black, red, black
indicator = { ind_iat_error}, "iat", "iat error", white, black, red, black
indicator = { ind_map_error}, "map", "map error", white, black, red, black
[Datalog]
@ -490,6 +502,7 @@ enable2ndByteCanID = false
subMenu = mapSamplingAngleCurve, "Map sampling angle"
subMenu = mapSamplingWindowCurve, "Map sampling window"
subMenu = triggerConfiguration, "&Trigger configuration"
subMenu = egoSettings, "EGO sensor settings"
menu = "&Settings"
subMenu = generalSettings, "General"
subMenu = fuelTableTbl, "&Fuel Table", {fuelAlgorithm != 3}
@ -565,6 +578,7 @@ enable2ndByteCanID = false
field = "MAP ADC input", mapAdcInput
field = "Baro ADC input", baroAdcInput
field = "vBatt ADC input", vBattAdcInput
field = "AFR ADC input", afrAdcInput
dialog = boardInputMode, "Board inputs Mode"
field = "ADC on PA0", adcModePA0
@ -668,6 +682,12 @@ enable2ndByteCanID = false
field = "MAP at minimum voltage", mapMin, { mapSensorType == 0}
field = "MAP at maximum voltage", mapMax, { mapSensorType == 0}
dialog = egoSettings, "EGO Sensor Settings"
field = "low voltage", afr_v1
field = "low value", afr_value1
field = "high voltage", afr_v2
field = "high value", afr_value2
dialog = crankingFuel, "Cranking Fuel"
field = "Minimum temp point", CrankingCoolantTempMin
field = "Pulse Width at Minimum temp point", CrankingMinTempPW

View File

@ -25,7 +25,7 @@ int minI(int i1, int i2) {
}
float efiRound(float value, float precision) {
int a = value / precision;
int a = (int)(value / precision);
return a * precision;
}

View File

@ -148,7 +148,7 @@ int hsReport(histogram_s *h, int* report) {
float d = bounds[minIndex];
if (acc != k)
d += (bounds[minIndex + 1] - 1 - bounds[minIndex]) * (k - acc) / h->values[minIndex];
report[index++] = d;
report[index++] = (int)d;
}
int maxIndex = BOUND_LENGTH - 1;