rusefi/firmware/controllers/algo/engine_configuration.h

571 lines
14 KiB
C

/**
* @file engine_configuration.h
* @brief Main engine configuration data structure.
*
* @date Oct 30, 2013
* @author Andrey Belomutskiy, (c) 2012-2014
*/
#ifndef ENGINE_CONFIGURATION_H_
#define ENGINE_CONFIGURATION_H_
#include "efifeatures.h"
#include "crc.h"
#include "sensor_types.h"
#include "can_header.h"
#include "rusefi_enums.h"
#include "global.h"
#define MOCK_UNDEFINED -1
typedef struct {
float baseCrankingFuel;
/**
* This value controls what RPM values we consider 'cranking' (any RPM below 'crankingRpm')
* Anything above 'crankingRpm' would be 'running'
*/
short int crankingRpm;
} cranking_parameters_s;
#define INJECTION_PIN_COUNT 12
#define IGNITION_PIN_COUNT 12
#define MAX31855_CS_COUNT 8
#define JOYSTICK_PIN_COUNT 5
#define FUEL_RPM_COUNT 16
#define FUEL_LOAD_COUNT 16
#define LE_COMMAND_LENGTH 200
#define LE_COMMAND_COUNT 16
typedef char le_formula_t[LE_COMMAND_LENGTH];
#define CLT_CURVE_SIZE 16
#define IAT_CURVE_SIZE 16
#define VBAT_INJECTOR_CURVE_SIZE 8
#define IGN_LOAD_COUNT 16
#define IGN_RPM_COUNT 16
typedef float fuel_table_t[FUEL_LOAD_COUNT][FUEL_RPM_COUNT];
typedef float ignition_table_t[IGN_LOAD_COUNT][IGN_RPM_COUNT];
#define DWELL_CURVE_SIZE 8
typedef enum {
AC_OFF = 0,
/**
* You would use this value if you want to see a detailed graph of your trigger events
*/
AC_TRIGGER = 1, AC_MAP = 2,
Internal_ForceMyEnumIntSize_analog_chart_mode = ENUM_SIZE_HACK,
} analog_chart_e;
typedef enum {
/**
* This is the default mode in which ECU controls timing dynamically
*/
TM_DYNAMIC = 0,
/**
* Fixed timing is useful while you are playing with a timing gun - you need to have fixed
* timing if you want to install your distributor at some specific angle
*/
TM_FIXED = 1,
Internal_ForceMyEnumIntSize_timing_mode = ENUM_SIZE_HACK,
} timing_mode_e;
typedef enum {
CD_OFF = 0,
CD_USE_CAN1 = 1,
CD_USE_CAN2 = 2,
Internal_ForceMyEnumIntSize_can_device_mode = ENUM_SIZE_HACK,
} can_device_mode_e;
typedef struct {
adc_channel_e afrAdcChannel;
float v1;
float value1;
float v2;
float value2;
} afr_sensor_s;
#define DWELL_COUNT 8
#define CRANKING_CURVE_SIZE 8
/**
* @brief Trigger wheel(s) configuration
*/
typedef struct {
trigger_type_e triggerType;
int customIsSynchronizationNeeded;
int customTotalToothCount;
int customSkippedToothCount;
float customSyncRatioFrom;
float customSyncRatioTo;
int customUseRiseEdge;
} trigger_config_s;
#define HW_MAX_ADC_INDEX 16
typedef struct {
// WARNING: by default, our small enums are ONE BYTE. this one is made 4-byte with the 'ENUM_SIZE_HACK' hack
brain_pin_e idleValvePin;
pin_output_mode_e idleValvePinMode;
brain_pin_e fuelPumpPin;
pin_output_mode_e fuelPumpPinMode;
brain_pin_e injectionPins[INJECTION_PIN_COUNT];
pin_output_mode_e injectionPinMode;
brain_pin_e ignitionPins[IGNITION_PIN_COUNT];
pin_output_mode_e ignitionPinMode;
brain_pin_e malfunctionIndicatorPin;
pin_output_mode_e malfunctionIndicatorPinMode;
brain_pin_e fanPin;
pin_output_mode_e fanPinMode;
brain_pin_e electronicThrottlePin1;
pin_output_mode_e electronicThrottlePin1Mode;
/**
* Idle switch input signal
*/
brain_pin_e idleSwitchPin;
pin_input_mode_e idleSwitchPinMode;
brain_pin_e alternatorControlPin;
pin_output_mode_e alternatorControlPinMode;
brain_pin_e HD44780_rs;
brain_pin_e HD44780_e;
brain_pin_e HD44780_db4;
brain_pin_e HD44780_db5;
brain_pin_e HD44780_db6;
brain_pin_e HD44780_db7;
brain_pin_e gps_rx_pin;
brain_pin_e gps_tx_pin;
int idleSolenoidFrequency;
int triggerSimulatorFrequency;
/**
* Digital Potentiometer is used by stock ECU stimulation code
*/
spi_device_e digitalPotentiometerSpiDevice;
brain_pin_e digitalPotentiometerChipSelect[DIGIPOT_COUNT];
adc_channel_mode_e adcHwChannelEnabled[HW_MAX_ADC_INDEX];
brain_pin_e triggerInputPins[3];
brain_pin_e mainRelayPin;
int idleThreadPeriod;
int consoleLoopPeriod;
int lcdThreadPeriod;
int tunerStudioThreadPeriod;
int generalPeriodicThreadPeriod;
uint32_t tunerStudioSerialSpeed;
brain_pin_e boardTestModeJumperPin;
can_device_mode_e canDeviceMode;
brain_pin_e canTxPin;
brain_pin_e canRxPin;
brain_pin_e triggerSimulatorPins[TRIGGER_SIMULATOR_PIN_COUNT];
pin_output_mode_e triggerSimulatorPinModes[TRIGGER_SIMULATOR_PIN_COUNT];
brain_pin_e o2heaterPin;
pin_output_mode_e o2heaterPinModeTodO;
unsigned int is_enabled_spi_1 : 1; // bit 0
unsigned int is_enabled_spi_2 : 1; // bit 1
unsigned int is_enabled_spi_3 : 1; // bit 2
unsigned int isSdCardEnabled : 1; // bit 3
unsigned int isFastAdcEnabled : 1; // bit 4
unsigned int isEngineControlEnabled : 1; // bit 5
unsigned int isHip9011Enabled : 1; // bit 6
brain_pin_e logicAnalyzerPins[LOGIC_ANALYZER_CHANNEL_COUNT];
/**
* default or inverted input
*/
uint8_t logicAnalyzerMode[LOGIC_ANALYZER_CHANNEL_COUNT];
int unrealisticRpmThreashold;
pin_output_mode_e mainRelayPinMode;
brain_pin_e max31855_cs[MAX31855_CS_COUNT];
spi_device_e max31855spiDevice;
brain_pin_e gpioPins[LE_COMMAND_COUNT];
pin_output_mode_e gpioPinModes[LE_COMMAND_COUNT];
brain_pin_e joystickPins[JOYSTICK_PIN_COUNT];
/**
* This pin is used for debugging - snap a logic analyzer on it and see if it's ever high
*/
brain_pin_e triggerErrorPin;
pin_output_mode_e triggerErrorPinMode;
/**
* value between 0 and 1
*/
float idleSolenoidPwm;
brain_pin_e acRelayPin;
pin_output_mode_e acRelayPinMode;
short int fsioFrequency[LE_COMMAND_COUNT];
brain_pin_e hip9011CsPin;
brain_pin_e hip9011IntHoldPin;
brain_pin_e hip9011OutPin;
int unusedbs[38];
le_formula_t le_formulas[LE_COMMAND_COUNT];
} board_configuration_s;
// 19010105 decimal
#define HEADER_MAGIC_NUMBER 0x1221239
/**
* @brief Engine configuration.
* Values in this data structure are adjustable and persisted in on-board flash RAM.
*
* The offsets are tracked using
* https://docs.google.com/spreadsheet/ccc?key=0AiAmAn6tn3L_dGJXZDZOcVVhaG9SaHZKU1dyMjhEV0E
*
* todo: currently the fields here are simply in the order in which they were implemented
* todo: re-arrange this structure one we have a stable code version
*/
typedef struct {
// WARNING: by default, our small enums are ONE BYTE. but if the are surrounded by non-enums - alignments do the trick
engine_type_e engineType;
/**
* this magic number is used to make sure that what we read from Flash is in fact some configuration
*/
int headerMagicValue;
float battInjectorLagCorrBins[VBAT_INJECTOR_CURVE_SIZE]; // size 32, offset 8
float battInjectorLagCorr[VBAT_INJECTOR_CURVE_SIZE]; // size 32, offset 40
float cltFuelCorrBins[CLT_CURVE_SIZE]; // size 64, offset 72
float cltFuelCorr[CLT_CURVE_SIZE]; // size 64, offset 136
float iatFuelCorrBins[IAT_CURVE_SIZE]; // size 64, offset 200
float iatFuelCorr[IAT_CURVE_SIZE]; // size 64, offset 264
/**
* Should the trigger emulator push data right into trigger input, eliminating the need for physical jumper wires?
* PS: Funny name, right? :)
* todo: make this a bit on some bit field
*/
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
short int tpsMin; // size 2, offset 330
// tpsMax value as 10 bit ADC value. Not Voltage!
short int tpsMax; // size 2, offset 332
short int analogChartMode;
/**
* todo: finish implementation. These values are used for TPS disconnect detection
*/
short int tpsErrorLowValue;
short int tpsErrorHighValue;
float primingSquirtDurationMs;
/**
* 360 for two-stroke
* 720 for four-stroke
*/
int engineCycle;
cranking_parameters_s crankingSettings;
MAP_sensor_config_s map;
// todo: merge with channel settings, use full-scale Thermistor here!
ThermistorConf cltThermistorConf; // size 40 (10*4), offset 336
ThermistorConf iatThermistorConf; // size 40, offset 376
float sparkDwellBins[DWELL_COUNT]; // offset 580
float sparkDwell[DWELL_COUNT];
float ignitionLoadBins[IGN_LOAD_COUNT];
float ignitionRpmBins[IGN_RPM_COUNT];
/**
* this value could be used to offset the whole ignition timing table by a constant
*/
float ignitionOffset;
/**
* While cranking (which causes battery voltage to drop) we can calculate dwell time in shaft
* degrees, not in absolute time as in running mode.
*/
float crankingChargeAngle;
timing_mode_e timingMode;
/**
* This value is used in 'fixed timing' mode, i.e. constant timing
* This mode is useful for instance while adjusting distributor location
*/
float fixedModeTiming;
float injectorLag; // size 4, offset 0
float fuelLoadBins[FUEL_LOAD_COUNT]; //
// RPM is float and not integer in order to use unified methods for interpolation
float fuelRpmBins[FUEL_RPM_COUNT]; //
/**
* Engine displacement, in liters
* see also cylindersCount
*/
float displacement;
int rpmHardLimit;
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)
*
* For engine configuration humans need angles from TDC.
*
* This field is the angle between Top Dead Center (TDC) and the first trigger event.
* Knowing this angle allows us to control timing and other angles in reference to TDC.
*/
float globalTriggerAngleOffset;
/**
* We have 3.3V ADC and most of the analog input signals are 5V, this forces us to use
* voltage dividers on the input circuits. This parameter holds the coefficient of these dividers.
* see also vbattDividerCoeff
*/
float analogInputDividerCoefficient;
/**
* This setting controls which algorithm is used for ENGINE LOAD
*/
engine_load_mode_e algorithm;
/**
* see
*/
float vbattDividerCoeff;
/**
* Cooling fan turn-on temperature threshold, in Celsuis
*/
float fanOnTemperature;
/**
* Cooling fan turn-off temperature threshold, in Celsuis
*/
float fanOffTemperature;
int canReadEnabled;
int canWriteEnabled;
can_nbc_e can_nbc_type;
int can_sleep_period;
int cylindersCount;
ignition_mode_e ignitionMode;
firing_order_e firingOrder;
/**
* This magic constant is about four-stroke engines with camshaft position sensors.
* On any four stroke engine, each revolution of the camshaft is two revolutions
* of the crankshaft. If camshaft position is our primary sensor, we use this multiplier
* to convert from camshaft angles to crankshaft angles. All angels across the system
* should be crankshaft angles.
*/
float rpmMultiplier;
display_mode_e displayMode;
log_format_e logFormat;
int firmwareVersion;
int HD44780width;
int HD44780height;
adc_channel_e tpsAdcChannel;
int overrideCrankingIgnition;
int analogChartFrequency;
trigger_config_s triggerConfig;
int space;
adc_channel_e vbattAdcChannel;
float globalFuelCorrection;
// todo: merge with channel settings, use full-scale Thermistor!
adc_channel_e cltAdcChannel;
adc_channel_e iatAdcChannel;
adc_channel_e mafAdcChannel;
afr_sensor_s afrSensor;
float injectionOffset;
float crankingTimingAngle;
float diffLoadEnrichmentCoef;
air_pressure_sensor_config_s baroSensor;
float veLoadBins[FUEL_LOAD_COUNT];
float veRpmBins[FUEL_RPM_COUNT];
float afrLoadBins[FUEL_LOAD_COUNT];
float afrRpmBins[FUEL_RPM_COUNT];
// the large tables are always in the end - that's related to TunerStudio paging implementation
fuel_table_t fuelTable; // size 1024
ignition_table_t ignitionTable; // size 1024
fuel_table_t veTable; // size 1024
fuel_table_t afrTable; // size 1024
board_configuration_s bc;
bool_t hasMapSensor : 1; // bit 0
bool_t hasIatSensor : 1; // bit 1
bool_t hasBaroSensor : 1; // bit 1
bool_t hasAfrSensor : 1; // bit 2
bool_t useConstantDwellDuringCranking : 1; // bit 3
bool_t isDigitalChartEnabled : 1; // bit 4
// that's the next 32 bit field
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
bool needSecondTriggerInput : 1; // bit 4
bool isMapAveragingEnabled : 1; // bit 5
bool isMilEnabled : 1; // bit 6
bool isFuelPumpEnabled : 1; // bit 7
bool isTunerStudioEnabled : 1; // bit 8
bool isWaveAnalyzerEnabled : 1; // bit 9
bool isIdleThreadEnabled : 1; // bit 10
/**
* Usually if we have no trigger events that means engine is stopped
* Unless we are troubleshooting and spinning the engine by hand - this case a longer
* delay is needed
*/
bool isManualSpinningMode : 1; // bit 11
uint32_t digitalChartSize;
/**
* cc/min, cubic centimeter per minute
*
* By the way, g/s = 0.125997881 * (lb/hr)
* g/s = 0.125997881 * (cc/min)/10.5
* g/s = 0.0119997981 * cc/min
*
*/
float injectorFlow; // size 4
float crankingFuelCoef[CRANKING_CURVE_SIZE];
float crankingFuelBins[CRANKING_CURVE_SIZE];
float crankingCycleCoef[CRANKING_CURVE_SIZE];
float crankingCycleBins[CRANKING_CURVE_SIZE];
float ignitionDwellForCrankingMs;
int targetIdleRpm;
/**
* A/C button input handled as analog input
*/
adc_channel_e acSwitchAdc;
int ignMathCalculateAtIndex;
short int acCutoffLowRpm;
short int acCutoffHighRpm;
short int acIdleRpmBump;
short int unusedShort;
adc_channel_e vRefAdcChannel;
float knockDetectionWindowStart;
float knockDetectionWindowEnd;
int unused3[85];
} engine_configuration_s;
void setOperationMode(engine_configuration_s *engineConfiguration, operation_mode_e mode);
operation_mode_e getOperationMode(engine_configuration_s const *engineConfiguration);
typedef struct {
engine_configuration_s engineConfiguration;
} persistent_config_s;
typedef struct {
int version;
int size;
persistent_config_s persistentConfiguration;
crc_t value;
} persistent_config_container_s;
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
void setDefaultConfiguration(engine_configuration_s *engineConfiguration, board_configuration_s *boardConfiguration);
void setWholeFuelMap(engine_configuration_s *engineConfiguration, float value);
void setWholeTimingTable(engine_configuration_s *engineConfiguration, float value);
void setConstantDwell(engine_configuration_s *engineConfiguration, float dwellMs);
void printFloatArray(const char *prefix, float array[], int size);
void incrementGlobalConfigurationVersion(void);
int getGlobalConfigurationVersion(void);
void commonFrankensoAnalogInputs(engine_configuration_s *engineConfiguration);
#ifdef __cplusplus
}
#endif /* __cplusplus */
void copyFuelTable(fuel_table_t const source, fuel_table_t destination);
void copyTimingTable(ignition_table_t const source, ignition_table_t destination);
#endif /* ENGINE_CONFIGURATION_H_ */