diff --git a/firmware/config/engines/custom_engine.cpp b/firmware/config/engines/custom_engine.cpp index 8920076e1e..faaee7fcae 100644 --- a/firmware/config/engines/custom_engine.cpp +++ b/firmware/config/engines/custom_engine.cpp @@ -41,7 +41,7 @@ void setCustomEngineConfiguration(engine_configuration_s *engineConfiguration) { // Frankenso low out #3: PD7 Main Relay // Frankenso low out #4: PC13 Idle valve solenoid // Frankenso low out #5: PE3 - // Frankenso low out #6: PE4 + // Frankenso low out #6: PE4 fuel pump relay // Frankenso low out #7: PE1 (do not use with discovery!) // Frankenso low out #8: PE2 injector #2 // Frankenso low out #9: PB9 injector #1 @@ -49,6 +49,7 @@ void setCustomEngineConfiguration(engine_configuration_s *engineConfiguration) { // Frankenso low out #11: PB8 injector #3 // Frankenso low out #12: PB7 injector #4 + boardConfiguration->fuelPumpPin = GPIOE_4; boardConfiguration->mainRelayPin = GPIOD_7; boardConfiguration->idleValvePin = GPIOC_13; diff --git a/firmware/config/engines/mazda_626.cpp b/firmware/config/engines/mazda_626.cpp index f754897eb0..f548a622c2 100644 --- a/firmware/config/engines/mazda_626.cpp +++ b/firmware/config/engines/mazda_626.cpp @@ -11,65 +11,11 @@ #include "mazda_626.h" #include "engine_math.h" #include "honda_accord.h" +#include "custom_engine.h" void setMazda626EngineConfiguration(engine_configuration_s *engineConfiguration) { + setCustomEngineConfiguration(engineConfiguration); + board_configuration_s *boardConfiguration = &engineConfiguration->bc; engineConfiguration->trigger.type = TT_MAZDA_DOHC_1_4; - - setFrankenso_01_LCD(boardConfiguration); - setFrankenso0_1_joystick(engineConfiguration); - - setSingleCoilDwell(engineConfiguration); - engineConfiguration->ignitionMode = IM_ONE_COIL; - - /** - * I-O mapping is a copy of Custom engine type - */ - - /** - * Frankenso analog #1 PC2 ADC12 - * Frankenso analog #2 PC1 ADC11 - * Frankenso analog #3 - * Frankenso analog #4 PC3 ADC13 - * Frankenso analog #5 - * Frankenso analog #6 - * Frankenso analog #7 PA4 ADC4 - * Frankenso analog #8 - * Frankenso analog #9 - * Frankenso analog #10 PA6 ADC6 - * Frankenso analog #11 PC5 ADC15 - * Frankenso analog #12 VBatt - */ - - - /** - * http://rusefi.com/wiki/index.php?title=Manual:Hardware_Frankenso_board - */ - // Frankenso low out #1: PE6 - // Frankenso low out #2: PE5 - // Frankenso low out #3: PD7 Main Relay - // Frankenso low out #4: PC13 Idle valve solenoid - // Frankenso low out #5: PE3 - // Frankenso low out #6: PE4 - // Frankenso low out #7: PE1 (do not use with discovery!) - // Frankenso low out #8: PE2 injector #2 - // Frankenso low out #9: PB9 injector #1 - // Frankenso low out #10: PE0 (do not use with discovery!) - // Frankenso low out #11: PB8 injector #3 - // Frankenso low out #12: PB7 injector #4 - - boardConfiguration->mainRelayPin = GPIOD_7; - boardConfiguration->idleValvePin = GPIOC_13; - - boardConfiguration->fanPin = GPIOE_5; - - boardConfiguration->injectionPins[0] = GPIOB_9; // #1 - boardConfiguration->injectionPins[1] = GPIOE_2; // #2 - boardConfiguration->injectionPins[2] = GPIOB_8; // #3 - boardConfiguration->injectionPins[3] = GPIOB_7; // #4 - - boardConfiguration->ignitionPins[0] = GPIOC_7; - - // todo: 8.2 or 10k? - engineConfiguration->vbattDividerCoeff = ((float) (10 + 33)) / 10 * 2; } diff --git a/firmware/console_util/rfiutil.c b/firmware/console_util/rfiutil.c index 0c676f7cb5..6730e49a45 100644 --- a/firmware/console_util/rfiutil.c +++ b/firmware/console_util/rfiutil.c @@ -54,19 +54,6 @@ char hexChar(int v) { return 'A' - 10 + v; } */ -// todo: make this a macro? -int isIsrContext(void) { - /** - * Unfortunately ChibiOS has two versions of methods for different - * contexts. - */ - return dbg_isr_cnt > 0; -} - -// todo: make this a macro? -int isLocked(void) { - return dbg_lock_cnt > 0; -} void chVTSetAny(virtual_timer_t *vtp, systime_t time, vtfunc_t vtfunc, void *par) { if (isIsrContext()) { diff --git a/firmware/console_util/rfiutil.h b/firmware/console_util/rfiutil.h index b6676ec32d..60e1952918 100644 --- a/firmware/console_util/rfiutil.h +++ b/firmware/console_util/rfiutil.h @@ -12,14 +12,21 @@ #include "global.h" #include "histogram.h" +#define isLocked() (dbg_lock_cnt > 0) + + /** + * Unfortunately ChibiOS has two versions of methods for different + * contexts. + */ + +#define isIsrContext() (dbg_isr_cnt > 0) + #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ -char hexC(int v); -int isIsrContext(void); -int isLocked(void); +//char hexC(int v); void chVTSetAny(virtual_timer_t *vtp, systime_t time, vtfunc_t vtfunc, void *par); #ifdef __cplusplus diff --git a/firmware/controllers/core/interpolation.cpp b/firmware/controllers/core/interpolation.cpp index 9720c62d8e..425b4f8599 100644 --- a/firmware/controllers/core/interpolation.cpp +++ b/firmware/controllers/core/interpolation.cpp @@ -17,6 +17,10 @@ int needInterpolationLogging = TRUE; +FastInterpolation::FastInterpolation() { + init(0, 0, 1, 1); +} + FastInterpolation::FastInterpolation(float x1, float y1, float x2, float y2) { init(x1, y1, x2, y2); } diff --git a/firmware/controllers/core/interpolation.h b/firmware/controllers/core/interpolation.h index dbe4ac44f2..91c14e6324 100644 --- a/firmware/controllers/core/interpolation.h +++ b/firmware/controllers/core/interpolation.h @@ -18,6 +18,7 @@ void setTableValue(float bins[], float values[], int size, float key, float valu class FastInterpolation { public: + FastInterpolation(); FastInterpolation(float x1, float y1, float x2, float y2); void init(float x1, float y1, float x2, float y2); float getValue(float x); diff --git a/firmware/controllers/engine_controller.cpp b/firmware/controllers/engine_controller.cpp index fdfa7c3791..5c676577a0 100644 --- a/firmware/controllers/engine_controller.cpp +++ b/firmware/controllers/engine_controller.cpp @@ -338,7 +338,7 @@ void initEngineContoller(Logging *sharedLogger, Engine *engine) { return; } - initSensors(engine); + initSensors(PASS_ENGINE_PARAMETER_F); initPwmGenerator(); diff --git a/firmware/controllers/map_averaging.cpp b/firmware/controllers/map_averaging.cpp index c07ebdb59b..4fdd0e4be4 100644 --- a/firmware/controllers/map_averaging.cpp +++ b/firmware/controllers/map_averaging.cpp @@ -49,11 +49,19 @@ static volatile int perRevolutionCounter = 0; * Number of measurements in previous shaft revolution */ static volatile int perRevolution = 0; + +/** + * In this lock-free imlementation 'readIndex' + */ +static int readIndex = 0; +static float accumulators[2]; +static int counters[2]; + + /** * Running MAP accumulator - * v_ for Voltage */ -static volatile float v_mapAccumulator = 0; +static volatile float mapAccumulator = 0; /** * Running counter of measurements to consider for averaging */ @@ -69,14 +77,21 @@ EXTERN_ENGINE; static scheduling_s startTimer[2]; static scheduling_s endTimer[2]; +/** + * that's a performance optimization: let's not bother averaging + * if we are outside of of the window + */ +static bool_t isAveraging = false; + static void startAveraging(void *arg) { (void) arg; efiAssertVoid(getRemainingStack(chThdSelf()) > 128, "lowstck#9"); bool wasLocked = lockAnyContext(); ; // with locking we would have a consistent state - v_mapAccumulator = 0; + mapAccumulator = 0; mapMeasurementsCounter = 0; + isAveraging = true; if (!wasLocked) chSysUnlockFromIsr() ; @@ -87,25 +102,30 @@ static void startAveraging(void *arg) { * @note This method is invoked OFTEN, this method is a potential bottle-next - the implementation should be * as fast as possible */ -void mapAveragingCallback(adcsample_t value) { +void mapAveragingCallback(adcsample_t adcValue) { + if(!isAveraging && boardConfiguration->analogChartMode != AC_MAP) { + return; + } + /* Calculates the average values from the ADC samples.*/ perRevolutionCounter++; efiAssertVoid(getRemainingStack(chThdSelf()) > 128, "lowstck#9a"); - float voltage = adcToVoltsDivided(value); - float currentPressure = getMapByVoltage(voltage); #if EFI_ANALOG_CHART if (boardConfiguration->analogChartMode == AC_MAP) - if (perRevolutionCounter % FAST_MAP_CHART_SKIP_FACTOR == 0) + if (perRevolutionCounter % FAST_MAP_CHART_SKIP_FACTOR == 0) { + float voltage = adcToVoltsDivided(adcValue); + float currentPressure = getMapByVoltage(voltage); acAddData(getCrankshaftAngleNt(getTimeNowNt() PASS_ENGINE_PARAMETER), currentPressure); + } #endif /* EFI_ANALOG_CHART */ chSysLockFromIsr() ; // with locking we would have a consistent state - v_mapAccumulator += voltage; + mapAccumulator += adcValue; mapMeasurementsCounter++; chSysUnlockFromIsr() ; @@ -114,8 +134,9 @@ void mapAveragingCallback(adcsample_t value) { static void endAveraging(void *arg) { (void) arg; bool wasLocked = lockAnyContext(); + isAveraging = false; // with locking we would have a consistent state - v_averagedMapValue = v_mapAccumulator / mapMeasurementsCounter; + v_averagedMapValue = adcToVoltsDivided(mapAccumulator / mapMeasurementsCounter); if (!wasLocked) chSysUnlockFromIsr() ; diff --git a/firmware/controllers/sensors/allsensors.cpp b/firmware/controllers/sensors/allsensors.cpp index 976379fa48..e7b320915f 100644 --- a/firmware/controllers/sensors/allsensors.cpp +++ b/firmware/controllers/sensors/allsensors.cpp @@ -7,10 +7,12 @@ * @author Andrey Belomutskiy, (c) 2012-2015 */ +#include "engine.h" #include "allsensors.h" -void initSensors(Engine *engine) { - initThermistors(engine); +void initSensors(DECLARE_ENGINE_PARAMETER_F) { + initThermistors(PASS_ENGINE_PARAMETER_F); + initMapDecoder(PASS_ENGINE_PARAMETER_F); } // todo: move this somewhere else? maybe. diff --git a/firmware/controllers/sensors/allsensors.h b/firmware/controllers/sensors/allsensors.h index 783b12876f..c12a09c8f3 100644 --- a/firmware/controllers/sensors/allsensors.h +++ b/firmware/controllers/sensors/allsensors.h @@ -25,7 +25,7 @@ #include "adc_math.h" #endif -void initSensors(Engine *engine); +void initSensors(DECLARE_ENGINE_PARAMETER_F); bool getAcToggle(Engine *engine); diff --git a/firmware/controllers/sensors/map.cpp b/firmware/controllers/sensors/map.cpp index 931691fa07..b1dec421b5 100644 --- a/firmware/controllers/sensors/map.cpp +++ b/firmware/controllers/sensors/map.cpp @@ -8,7 +8,9 @@ #if EFI_ANALOG_SENSORS || defined(__DOXYGEN__) -extern engine_configuration_s * engineConfiguration; +EXTERN_ENGINE; + +static FastInterpolation customMap; /** * @brief MAP value decoded for a 1.83 Honda sensor @@ -31,10 +33,16 @@ static FastInterpolation mpx4250(0, 8, 5, 260); static FastInterpolation dodgeNeon2003(0.5, 0, 4.5, 100); +/** + * We hold a reference to current decoder to reduce code branching + * to lookup decoder each time we need to decode + */ +static FastInterpolation *mapDecoder; + float decodePressure(float voltage, air_pressure_sensor_config_s * config) { switch (config->type) { case MT_CUSTOM: - // todo: introduce 'FastInterpolation customMap' + // todo: migrate to 'FastInterpolation customMap' return interpolate(0, config->valueAt0, 5, config->valueAt5, voltage); case MT_DENSO183: return denso183.getValue(voltage); @@ -54,7 +62,8 @@ float decodePressure(float voltage, air_pressure_sensor_config_s * config) { * @brief MAP value decoded according to current settings * @returns kPa value */ -float getMapByVoltage(float voltage) { +float getMapByVoltage(float voltage DECLARE_ENGINE_PARAMETER_S) { + // todo: migrate to mapDecoder once parameter listeners are ready air_pressure_sensor_config_s * config = &engineConfiguration->map.sensor; return decodePressure(voltage, config); } @@ -62,14 +71,43 @@ float getMapByVoltage(float voltage) { /** * @return Manifold Absolute Pressure, in kPa */ -float getRawMap(void) { +float getRawMap(DECLARE_ENGINE_PARAMETER_F) { float voltage = getVoltageDivided(engineConfiguration->map.sensor.hwChannel); - return getMapByVoltage(voltage); + return getMapByVoltage(voltage PASS_ENGINE_PARAMETER); } -float getBaroPressure(void) { +float getBaroPressure(DECLARE_ENGINE_PARAMETER_F) { float voltage = getVoltageDivided(engineConfiguration->baroSensor.hwChannel); return decodePressure(voltage, &engineConfiguration->baroSensor); } +static FastInterpolation *getDecoder(air_pressure_sensor_type_e type) { + switch (type) { + case MT_CUSTOM: + return &customMap; + case MT_DENSO183: + return &denso183; + case MT_MPX4250: + return &mpx4250; + case MT_HONDA3BAR: + return &honda3bar; + case MT_DODGE_NEON_2003: + return &dodgeNeon2003; + default: + firmwareError("Unknown MAP type: %d", type); + return &customMap; + } +} + +static void applyConfiguration(DECLARE_ENGINE_PARAMETER_F) { + air_pressure_sensor_config_s * config = &engineConfiguration->map.sensor; + customMap.init(0, config->valueAt0, 5, config->valueAt5); + mapDecoder = getDecoder(engineConfiguration->map.sensor.type); +} + +void initMapDecoder(DECLARE_ENGINE_PARAMETER_F) { + applyConfiguration(PASS_ENGINE_PARAMETER_F); + //engine->configurationListeners.registerCallback(applyConfiguration); +} + #endif diff --git a/firmware/controllers/sensors/map.h b/firmware/controllers/sensors/map.h index f1af533c12..1ca32c424f 100644 --- a/firmware/controllers/sensors/map.h +++ b/firmware/controllers/sensors/map.h @@ -2,29 +2,21 @@ #define MAP_H_ #include "engine_configuration.h" - -#ifdef __cplusplus -extern "C" -{ -#endif /* __cplusplus */ - #include "sensor_types.h" +void initMapDecoder(DECLARE_ENGINE_PARAMETER_F); + /** * @return Raw MAP sensor value right now */ -float getRawMap(void); -float getBaroPressure(void); +float getRawMap(DECLARE_ENGINE_PARAMETER_F); +float getBaroPressure(DECLARE_ENGINE_PARAMETER_F); /** * @return MAP value averaged within a window of measurement */ float getMap(void); float getMapVoltage(void); -float getMapByVoltage(float voltage); +float getMapByVoltage(float voltage DECLARE_ENGINE_PARAMETER_S); float decodePressure(float voltage, air_pressure_sensor_config_s * config); -#ifdef __cplusplus -} -#endif /* __cplusplus */ - #endif diff --git a/firmware/controllers/sensors/thermistors.cpp b/firmware/controllers/sensors/thermistors.cpp index f14286a9d8..812359655b 100644 --- a/firmware/controllers/sensors/thermistors.cpp +++ b/firmware/controllers/sensors/thermistors.cpp @@ -182,7 +182,7 @@ void setCommonNTCSensor(ThermistorConf *thermistorConf) { setThermistorConfiguration(thermistorConf, -20, 18000, 23.8889, 2100, 120.0, 100.0); } -void initThermistors(Engine *engine) { +void initThermistors(DECLARE_ENGINE_PARAMETER_F) { efiAssertVoid(engine!=NULL, "e NULL initThermistors"); efiAssertVoid(engine->engineConfiguration2!=NULL, "e2 NULL initThermistors"); initThermistorCurve(&engine->clt, &engine->engineConfiguration->clt, diff --git a/firmware/controllers/sensors/thermistors.h b/firmware/controllers/sensors/thermistors.h index b74dce5c26..d46c830153 100644 --- a/firmware/controllers/sensors/thermistors.h +++ b/firmware/controllers/sensors/thermistors.h @@ -16,10 +16,6 @@ #include "sensor_types.h" #include "engine.h" -#ifdef __cplusplus -extern "C" -{ -#endif /* __cplusplus */ /** * Vout=r2/(r1+r2)*Vin */ @@ -51,10 +47,15 @@ void prepareThermistorCurve(ThermistorConf * config); class Engine; -void initThermistors(Engine *engine); +void initThermistors(DECLARE_ENGINE_PARAMETER_F); void setCommonNTCSensor(ThermistorConf *thermistorConf); +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + #ifdef __cplusplus } #endif /* __cplusplus */ diff --git a/firmware/rusefi.cpp b/firmware/rusefi.cpp index df55a669ac..fd755a9f9d 100644 --- a/firmware/rusefi.cpp +++ b/firmware/rusefi.cpp @@ -258,5 +258,5 @@ int getRusEfiVersion(void) { return 1; // this is here to make the compiler happy about the unused array if (UNUSED_CCM_SIZE == 0) return 1; // this is here to make the compiler happy about the unused array - return 20150209; + return 20150210; } diff --git a/unit_tests/test_fuel_map.cpp b/unit_tests/test_fuel_map.cpp index da540d7a6c..80427e4359 100644 --- a/unit_tests/test_fuel_map.cpp +++ b/unit_tests/test_fuel_map.cpp @@ -42,7 +42,7 @@ void testFuelMap(void) { Engine *engine = ð.engine; engine_configuration_s *engineConfiguration = engine->engineConfiguration; - initThermistors(engine); + initThermistors(PASS_ENGINE_PARAMETER_F); printf("*** getInjectorLag\r\n"); diff --git a/unit_tests/test_trigger_decoder.cpp b/unit_tests/test_trigger_decoder.cpp index cf6fc89eef..0d7ed1bf1d 100644 --- a/unit_tests/test_trigger_decoder.cpp +++ b/unit_tests/test_trigger_decoder.cpp @@ -369,11 +369,11 @@ static void testRpmCalculator(void) { efiAssertVoid(eth.engine.engineConfiguration!=NULL, "null config in engine"); - initThermistors(ð.engine); - Engine *engine = ð.engine; engine_configuration_s *engineConfiguration = ð.persistentConfig.engineConfiguration; + initThermistors(PASS_ENGINE_PARAMETER_F); + engineConfiguration->trigger.customTotalToothCount = 8; engineConfiguration->globalFuelCorrection = 3; eth.initTriggerShapeAndRpmCalculator(); diff --git a/win32_functional_tests/simulator/rusEfiFunctionalTest.cpp b/win32_functional_tests/simulator/rusEfiFunctionalTest.cpp index e19c1d7bc4..f50e21a22d 100644 --- a/win32_functional_tests/simulator/rusEfiFunctionalTest.cpp +++ b/win32_functional_tests/simulator/rusEfiFunctionalTest.cpp @@ -80,7 +80,7 @@ void rusEfiFunctionalTest(void) { resetConfigurationExt(NULL, FORD_ASPIRE_1996, engine); prepareShapes(engine); - initThermistors(engine); + initThermistors(PASS_ENGINE_PARAMETER_F); initAlgo(engineConfiguration); initRpmCalculator(engine);