diff --git a/firmware/config/engines/MiniCooperR50.h b/firmware/config/engines/MiniCooperR50.h index b801492958..165313343a 100644 --- a/firmware/config/engines/MiniCooperR50.h +++ b/firmware/config/engines/MiniCooperR50.h @@ -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_ */ diff --git a/firmware/config/engines/citroenBerlingoTU3JP.h b/firmware/config/engines/citroenBerlingoTU3JP.h index 09f2d42736..586bc6d892 100644 --- a/firmware/config/engines/citroenBerlingoTU3JP.h +++ b/firmware/config/engines/citroenBerlingoTU3JP.h @@ -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_ */ diff --git a/firmware/config/engines/ford_aspire.h b/firmware/config/engines/ford_aspire.h index 87d19a9fdf..9a16a8d8c5 100644 --- a/firmware/config/engines/ford_aspire.h +++ b/firmware/config/engines/ford_aspire.h @@ -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_ */ diff --git a/firmware/config/engines/ford_escort_gt.cpp b/firmware/config/engines/ford_escort_gt.cpp index a3ac21f6bf..c8e91bfa30 100644 --- a/firmware/config/engines/ford_escort_gt.cpp +++ b/firmware/config/engines/ford_escort_gt.cpp @@ -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); +} diff --git a/firmware/config/engines/ford_escort_gt.h b/firmware/config/engines/ford_escort_gt.h index 2f701034b7..34c8bef6e7 100644 --- a/firmware/config/engines/ford_escort_gt.h +++ b/firmware/config/engines/ford_escort_gt.h @@ -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_ */ diff --git a/firmware/config/engines/honda_accord.cpp b/firmware/config/engines/honda_accord.cpp index 2869caadab..9c3127f828 100644 --- a/firmware/config/engines/honda_accord.cpp +++ b/firmware/config/engines/honda_accord.cpp @@ -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 diff --git a/firmware/config/engines/mitsubishi.cpp b/firmware/config/engines/mitsubishi.cpp index d6f6a2fe40..ca3b4bfcad 100644 --- a/firmware/config/engines/mitsubishi.cpp +++ b/firmware/config/engines/mitsubishi.cpp @@ -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); } diff --git a/firmware/console/eficonsole.c b/firmware/console/eficonsole.c index 4c94e6dbfb..f6d00edef5 100644 --- a/firmware/console/eficonsole.c +++ b/firmware/console/eficonsole.c @@ -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); diff --git a/firmware/console/status_loop.cpp b/firmware/console/status_loop.cpp index bcf43b923f..5a0fc8b88e 100644 --- a/firmware/console/status_loop.cpp +++ b/firmware/console/status_loop.cpp @@ -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); diff --git a/firmware/console/tunerstudio/tunerstudio.cpp b/firmware/console/tunerstudio/tunerstudio.cpp index 38c49a0d23..b0920a7d62 100644 --- a/firmware/console/tunerstudio/tunerstudio.cpp +++ b/firmware/console/tunerstudio/tunerstudio.cpp @@ -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); diff --git a/firmware/console/tunerstudio/tunerstudio_algo.cpp b/firmware/console/tunerstudio/tunerstudio_algo.cpp index c4475ad9d4..a9769b84d4 100644 --- a/firmware/console/tunerstudio/tunerstudio_algo.cpp +++ b/firmware/console/tunerstudio/tunerstudio_algo.cpp @@ -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); } diff --git a/firmware/console/tunerstudio/tunerstudio_configuration.h b/firmware/console/tunerstudio/tunerstudio_configuration.h index 84bef28ef2..0c5d56c1e4 100644 --- a/firmware/console/tunerstudio/tunerstudio_configuration.h +++ b/firmware/console/tunerstudio/tunerstudio_configuration.h @@ -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_ */ diff --git a/firmware/console_util/datalogging.c b/firmware/console_util/datalogging.c index 173711f299..35a4162f70 100644 --- a/firmware/console_util/datalogging.c +++ b/firmware/console_util/datalogging.c @@ -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; } /* diff --git a/firmware/console_util/datalogging.h b/firmware/console_util/datalogging.h index 3246ca0a63..d395c1f3b8 100644 --- a/firmware/console_util/datalogging.h +++ b/firmware/console_util/datalogging.h @@ -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; diff --git a/firmware/controllers/algo/accel_enrichment.cpp b/firmware/controllers/algo/accel_enrichment.cpp index 1d28d5c578..585942ed99 100644 --- a/firmware/controllers/algo/accel_enrichment.cpp +++ b/firmware/controllers/algo/accel_enrichment.cpp @@ -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) { diff --git a/firmware/controllers/algo/engine_configuration.cpp b/firmware/controllers/algo/engine_configuration.cpp index fdcf10e191..ebf4de1a91 100644 --- a/firmware/controllers/algo/engine_configuration.cpp +++ b/firmware/controllers/algo/engine_configuration.cpp @@ -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; diff --git a/firmware/controllers/algo/engine_configuration.h b/firmware/controllers/algo/engine_configuration.h index b13693ef77..19fec92927 100644 --- a/firmware/controllers/algo/engine_configuration.h +++ b/firmware/controllers/algo/engine_configuration.h @@ -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]; diff --git a/firmware/controllers/algo/fuel_math.cpp b/firmware/controllers/algo/fuel_math.cpp index 33270acb93..d47e7a02f7 100644 --- a/firmware/controllers/algo/fuel_math.cpp +++ b/firmware/controllers/algo/fuel_math.cpp @@ -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) diff --git a/firmware/controllers/algo/rusefi_enums.h b/firmware/controllers/algo/rusefi_enums.h index c2b89176fe..599453761d 100644 --- a/firmware/controllers/algo/rusefi_enums.h +++ b/firmware/controllers/algo/rusefi_enums.h @@ -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_ */ diff --git a/firmware/controllers/flash_main.cpp b/firmware/controllers/flash_main.cpp index 42a6d72be3..a679360d21 100644 --- a/firmware/controllers/flash_main.cpp +++ b/firmware/controllers/flash_main.cpp @@ -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) { diff --git a/firmware/controllers/injector_central.cpp b/firmware/controllers/injector_central.cpp index a71747e2d5..8afafe746b 100644 --- a/firmware/controllers/injector_central.cpp +++ b/firmware/controllers/injector_central.cpp @@ -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++) { diff --git a/firmware/controllers/lcd_controller.cpp b/firmware/controllers/lcd_controller.cpp index eb06fd77f0..ec47891070 100644 --- a/firmware/controllers/lcd_controller.cpp +++ b/firmware/controllers/lcd_controller.cpp @@ -130,6 +130,9 @@ static void prepareCurrentSecondLine(int index) { case 3: ptr = prepareStatusLine(buffer); break; + default: + firmwareError("unexpected case"); + return; } *ptr = ' '; } diff --git a/firmware/controllers/sensors/ego.cpp b/firmware/controllers/sensors/ego.cpp index 224d01a421..d15bfd83a8 100644 --- a/firmware/controllers/sensors/ego.cpp +++ b/firmware/controllers/sensors/ego.cpp @@ -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; + } +} diff --git a/firmware/controllers/sensors/ego.h b/firmware/controllers/sensors/ego.h index a49b45986e..3970ff5f99 100644 --- a/firmware/controllers/sensors/ego.h +++ b/firmware/controllers/sensors/ego.h @@ -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 diff --git a/firmware/controllers/settings.cpp b/firmware/controllers/settings.cpp index 68eee0185f..831daedb84 100644 --- a/firmware/controllers/settings.cpp +++ b/firmware/controllers/settings.cpp @@ -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); diff --git a/firmware/controllers/trigger/main_trigger_callback.cpp b/firmware/controllers/trigger/main_trigger_callback.cpp index 17b0d44236..1ba583985c 100644 --- a/firmware/controllers/trigger/main_trigger_callback.cpp +++ b/firmware/controllers/trigger/main_trigger_callback.cpp @@ -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 */ diff --git a/firmware/controllers/trigger/rpm_calculator.cpp b/firmware/controllers/trigger/rpm_calculator.cpp index cc7eb4b48e..f44ad0e1f0 100644 --- a/firmware/controllers/trigger/rpm_calculator.cpp +++ b/firmware/controllers/trigger/rpm_calculator.cpp @@ -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"); diff --git a/firmware/controllers/trigger/trigger_central.cpp b/firmware/controllers/trigger/trigger_central.cpp index 8c546ea296..71d21281a7 100644 --- a/firmware/controllers/trigger/trigger_central.cpp +++ b/firmware/controllers/trigger/trigger_central.cpp @@ -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 diff --git a/firmware/controllers/trigger/trigger_central.h b/firmware/controllers/trigger/trigger_central.h index 69a7406472..2481ae4d05 100644 --- a/firmware/controllers/trigger/trigger_central.h +++ b/firmware/controllers/trigger/trigger_central.h @@ -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); diff --git a/firmware/controllers/trigger/trigger_chrysler.cpp b/firmware/controllers/trigger/trigger_chrysler.cpp index 5ebd5b8736..4d77a85057 100644 --- a/firmware/controllers/trigger/trigger_chrysler.cpp +++ b/firmware/controllers/trigger/trigger_chrysler.cpp @@ -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 diff --git a/firmware/controllers/trigger/trigger_decoder.cpp b/firmware/controllers/trigger/trigger_decoder.cpp index 6b3ea12942..0e87d4ad44 100644 --- a/firmware/controllers/trigger/trigger_decoder.cpp +++ b/firmware/controllers/trigger/trigger_decoder.cpp @@ -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 } diff --git a/firmware/controllers/trigger/trigger_decoder.h b/firmware/controllers/trigger/trigger_decoder.h index cbe6ccf00a..56dd4ecfca 100644 --- a/firmware/controllers/trigger/trigger_decoder.h +++ b/firmware/controllers/trigger/trigger_decoder.h @@ -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); diff --git a/firmware/controllers/trigger/trigger_mazda.cpp b/firmware/controllers/trigger/trigger_mazda.cpp index a5c29a536b..5b06885ba6 100644 --- a/firmware/controllers/trigger/trigger_mazda.cpp +++ b/firmware/controllers/trigger/trigger_mazda.cpp @@ -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); diff --git a/firmware/controllers/trigger/trigger_mazda.h b/firmware/controllers/trigger/trigger_mazda.h index 87e1b2b6da..fec32b727e 100644 --- a/firmware/controllers/trigger/trigger_mazda.h +++ b/firmware/controllers/trigger/trigger_mazda.h @@ -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); diff --git a/firmware/controllers/trigger/trigger_structure.cpp b/firmware/controllers/trigger/trigger_structure.cpp index 8b00593baa..0441272ca8 100644 --- a/firmware/controllers/trigger/trigger_structure.cpp +++ b/firmware/controllers/trigger/trigger_structure.cpp @@ -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, diff --git a/firmware/controllers/trigger/trigger_structure.h b/firmware/controllers/trigger/trigger_structure.h index ee8b02e0d0..3ff005f484 100644 --- a/firmware/controllers/trigger/trigger_structure.h +++ b/firmware/controllers/trigger/trigger_structure.h @@ -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]; diff --git a/firmware/hw_layer/hardware.cpp b/firmware/hw_layer/hardware.cpp index 83d76b3977..691011a22b 100644 --- a/firmware/hw_layer/hardware.cpp +++ b/firmware/hw_layer/hardware.cpp @@ -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"); } diff --git a/firmware/hw_layer/trigger_input.cpp b/firmware/hw_layer/trigger_input.cpp index 8779f90ed8..0a732fdce4 100644 --- a/firmware/hw_layer/trigger_input.cpp +++ b/firmware/hw_layer/trigger_input.cpp @@ -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; } diff --git a/firmware/iar/ch.ewp b/firmware/iar/ch.ewp index d3db72e841..1496e099bc 100644 --- a/firmware/iar/ch.ewp +++ b/firmware/iar/ch.ewp @@ -91,7 +91,7 @@