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 @@