manual sync
This commit is contained in:
parent
93b522b2aa
commit
6803af5650
|
@ -140,6 +140,10 @@
|
|||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/chibios/os/ports/common/ARMCMx/CMSIS/include}""/>
|
||||
</option>
|
||||
<option id="org.eclipse.cdt.cross.arm.gnu.cpp.compiler.option.other.otherflags.1439013659" name="Other flags" superClass="org.eclipse.cdt.cross.arm.gnu.cpp.compiler.option.other.otherflags" value="-c -fmessage-length=0 -std=c++11 -Werror=write-strings" valueType="string"/>
|
||||
<option id="org.eclipse.cdt.cross.arm.gnu.cpp.compiler.option.preprocessor.def.1500938905" name="Defined symbols (-D)" superClass="org.eclipse.cdt.cross.arm.gnu.cpp.compiler.option.preprocessor.def" valueType="definedSymbols">
|
||||
<listOptionValue builtIn="false" value="CORTEX_USE_FPU=TRUE"/>
|
||||
</option>
|
||||
<option id="org.eclipse.cdt.cross.arm.gnu.cpp.compiler.option.optimization.flags.1776181591" name="Other optimization flags" superClass="org.eclipse.cdt.cross.arm.gnu.cpp.compiler.option.optimization.flags" value="-mfloat-abi=softfp -mfpu=fpv4-sp-d16 -fsingle-precision-constant" valueType="string"/>
|
||||
<inputType id="org.eclipse.cdt.cross.arm.gnu.sourcery.windows.cpp.compiler.base.input.1939416167" superClass="org.eclipse.cdt.cross.arm.gnu.sourcery.windows.cpp.compiler.base.input"/>
|
||||
</tool>
|
||||
<tool id="org.eclipse.cdt.cross.arm.gnu.sourcery.windows.elf.c.linker.debug.369587711" name="ARM Sourcery Windows GCC C Linker" superClass="org.eclipse.cdt.cross.arm.gnu.sourcery.windows.elf.c.linker.debug"/>
|
||||
|
@ -299,6 +303,10 @@
|
|||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/chibios/os/ports/common/ARMCMx}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/chibios/os/ports/common/ARMCMx/CMSIS/include}""/>
|
||||
</option>
|
||||
<option id="org.eclipse.cdt.cross.arm.gnu.cpp.compiler.option.preprocessor.def.104404165" superClass="org.eclipse.cdt.cross.arm.gnu.cpp.compiler.option.preprocessor.def" valueType="definedSymbols">
|
||||
<listOptionValue builtIn="false" value="CORTEX_USE_FPU=TRUE"/>
|
||||
</option>
|
||||
<option id="org.eclipse.cdt.cross.arm.gnu.cpp.compiler.option.optimization.flags.514837677" superClass="org.eclipse.cdt.cross.arm.gnu.cpp.compiler.option.optimization.flags" value="-mfloat-abi=softfp -mfpu=fpv4-sp-d16 -fsingle-precision-constant" valueType="string"/>
|
||||
<inputType id="org.eclipse.cdt.cross.arm.gnu.sourcery.windows.cpp.compiler.base.input.815685204" superClass="org.eclipse.cdt.cross.arm.gnu.sourcery.windows.cpp.compiler.base.input"/>
|
||||
</tool>
|
||||
<tool id="org.eclipse.cdt.cross.arm.gnu.sourcery.windows.elf.c.linker.release.1692652942" name="ARM Sourcery Windows GCC C Linker" superClass="org.eclipse.cdt.cross.arm.gnu.sourcery.windows.elf.c.linker.release"/>
|
||||
|
|
|
@ -1,2 +0,0 @@
|
|||
.dep
|
||||
build
|
|
@ -294,6 +294,7 @@ ULIBS = -lm
|
|||
|
||||
ifeq ($(USE_FPU),yes)
|
||||
USE_OPT += -mfloat-abi=hard -mfpu=fpv4-sp-d16 -fsingle-precision-constant
|
||||
USE_CPPOPT += -mfloat-abi=hard -mfpu=fpv4-sp-d16 -fsingle-precision-constant
|
||||
DDEFS += -DCORTEX_USE_FPU=TRUE
|
||||
else
|
||||
DDEFS += -DCORTEX_USE_FPU=FALSE
|
||||
|
|
|
@ -60,19 +60,11 @@
|
|||
#define STM32_I2C_I2C1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 6)
|
||||
|
||||
#define EFI_CAN_DEVICE CAND2
|
||||
#define EFI_CAN_RX_PORT GPIOB
|
||||
#define EFI_CAN_RX_PIN 12
|
||||
#define EFI_CAN_RX_AF 9
|
||||
#define EFI_CAN_TX_PORT GPIOB
|
||||
#define EFI_CAN_TX_PIN 6
|
||||
#define EFI_CAN_TX_AF 9
|
||||
|
||||
//#define EFI_CAN_DEVICE CAND1
|
||||
//#define EFI_CAN_RX_PORT GPIOB
|
||||
//#define EFI_CAN_RX_PIN 8
|
||||
//#define EFI_CAN_RX_AF 9
|
||||
//#define EFI_CAN_TX_PORT GPIOB
|
||||
//#define EFI_CAN_TX_PIN 9
|
||||
//#define EFI_CAN_TX_AF 9
|
||||
|
||||
/**
|
||||
|
@ -230,4 +222,10 @@
|
|||
#define GPS_SERIAL_TX_PIN 6
|
||||
#define GPS_SERIAL_RX_PIN 7
|
||||
|
||||
#define CONSOLE_MODE_SWITCH_PORT GPIOB
|
||||
#define CONSOLE_MODE_SWITCH_PIN 1
|
||||
|
||||
#define CONFIG_RESET_SWITCH_PORT GPIOD
|
||||
#define CONFIG_RESET_SWITCH_PIN 6
|
||||
|
||||
#endif /*ARRO_BOARD_H_*/
|
||||
|
|
|
@ -105,17 +105,17 @@
|
|||
#define EFI_SUPPORT_NISSAN_PRIMERA TRUE
|
||||
#define EFI_SUPPORT_1995_FORD_INLINE_6 TRUE
|
||||
|
||||
#define EFI_WAVE_CHART TRUE
|
||||
|
||||
#define EFI_HISTOGRAMS TRUE
|
||||
#define EFI_ANALOG_CHART TRUE
|
||||
|
||||
#if defined __GNUC__
|
||||
#define EFI_PERF_METRICS TRUE
|
||||
#define EFI_ANALOG_CHART TRUE
|
||||
#define EFI_WAVE_CHART TRUE
|
||||
#define DL_OUTPUT_BUFFER 9000
|
||||
#else
|
||||
// todo: CCM usage for IAR?
|
||||
#define EFI_PERF_METRICS FALSE
|
||||
#define EFI_ANALOG_CHART FALSE
|
||||
#define EFI_WAVE_CHART FALSE
|
||||
#define DL_OUTPUT_BUFFER 6000
|
||||
#define DL_OUTPUT_BUFFER 9000
|
||||
#endif
|
||||
|
||||
/**
|
||||
|
|
|
@ -14,7 +14,7 @@ void setGy6139qmbDefaultEngineConfiguration(engine_configuration_s *engineConfig
|
|||
engineConfiguration->rpmHardLimit = 9000;
|
||||
engineConfiguration->crankingSettings.crankingRpm = 800;
|
||||
engineConfiguration->analogInputDividerCoefficient = 1.52;
|
||||
engineConfiguration->engineLoadMode = LM_MAP;
|
||||
engineConfiguration->algorithm = LM_MAP;
|
||||
engineConfiguration->globalTriggerAngleOffset = 15;
|
||||
engineConfiguration->analogChartMode = AC_MAP;
|
||||
engineConfiguration->cylindersCount = 1;
|
||||
|
@ -27,6 +27,6 @@ void setGy6139qmbDefaultEngineConfiguration(engine_configuration_s *engineConfig
|
|||
*/
|
||||
engineConfiguration->triggerConfig.totalToothCount = 1;
|
||||
engineConfiguration->triggerConfig.skippedToothCount = 0;
|
||||
engineConfiguration->triggerConfig.isSynchronizationNeeded = FALSE;
|
||||
engineConfiguration->needSecondTriggerInput = FALSE;
|
||||
engineConfiguration->triggerConfig.isSynchronizationNeeded = false;
|
||||
engineConfiguration->needSecondTriggerInput = false;
|
||||
}
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
|
||||
extern engine_configuration2_s engineConfiguration2;
|
||||
|
||||
void configureShaftPositionEmulatorShape(PwmConfig *state) {
|
||||
static void configureShaftPositionEmulatorShapeWhat(PwmConfig *state) {
|
||||
/**
|
||||
* One signal per cam shaft revolution
|
||||
*/
|
||||
|
@ -40,11 +40,6 @@ void configureShaftPositionEmulatorShape(PwmConfig *state) {
|
|||
weComplexInit("distributor", state, 0, 2, switchTimes, 1, pinStates);
|
||||
}
|
||||
|
||||
void configureEngineEventHandler(EventHandlerConfiguration *config) {
|
||||
registerActuatorEvent(&config->ignitionEvents, 0, 1, 0);
|
||||
registerActuatorEvent(&config->ignitionEvents, 0, 2, 90);
|
||||
}
|
||||
|
||||
void setDefaultEngineConfiguration(EngineConfiguration *engineConfiguration) {
|
||||
engineConfiguration2.shaftPositionEventCount = 2;
|
||||
}
|
||||
|
|
|
@ -1,7 +1,10 @@
|
|||
/**
|
||||
* @file citroenBerlingoTU3JP.cpp
|
||||
*
|
||||
* CITROEN_TU3JP 15
|
||||
* CITROEN_TU3JP: engine_type 15
|
||||
*
|
||||
* This config overrides some values of the default configuration which is set by setDefaultConfiguration() method
|
||||
*
|
||||
*
|
||||
* @date Apr 15, 2014
|
||||
* @author Andrey Belomutskiy, (c) 2012-2014
|
||||
|
@ -12,9 +15,11 @@
|
|||
void setCitroenBerlingoTU3JPConfiguration(engine_configuration_s *engineConfiguration, board_configuration_s *boardConfiguration) {
|
||||
engineConfiguration->engineType = CITROEN_TU3JP;
|
||||
|
||||
engineConfiguration->triggerConfig.triggerType = TT_TOOTHED_WHEEL;
|
||||
engineConfiguration->triggerConfig.totalToothCount = 60;
|
||||
engineConfiguration->triggerConfig.skippedToothCount = 2;
|
||||
//engineConfiguration->triggerConfig.triggerType = todo 60_2
|
||||
|
||||
setToothedWheelConfiguration(engineConfiguration, 60, 2);
|
||||
|
||||
setTriggerSynchronizationGap(&engineConfiguration->triggerConfig, 2.5);
|
||||
|
||||
|
||||
// set_cranking_injection_mode 0
|
||||
|
|
|
@ -3,6 +3,8 @@
|
|||
*
|
||||
* DODGE_NEON_1995 = 2
|
||||
*
|
||||
* This config overrides some values of the default configuration which is set by setDefaultConfiguration() method
|
||||
*
|
||||
* @date Dec 16, 2013
|
||||
* @author Andrey Belomutskiy, (c) 2012-2014
|
||||
*/
|
||||
|
@ -21,7 +23,7 @@ void setDodgeNeonEngineConfiguration(engine_configuration_s *engineConfiguration
|
|||
|
||||
engineConfiguration->triggerConfig.triggerType = TT_DODGE_NEON;
|
||||
|
||||
engineConfiguration->engineLoadMode = LM_TPS;
|
||||
engineConfiguration->algorithm = LM_TPS;
|
||||
|
||||
// set_rpm_hard_limit 4000
|
||||
engineConfiguration->rpmHardLimit = 4000; // yes, 4k. let's play it safe for now
|
||||
|
@ -40,10 +42,10 @@ void setDodgeNeonEngineConfiguration(engine_configuration_s *engineConfiguration
|
|||
// set_whole_fuel_map 3
|
||||
setWholeFuelMap(engineConfiguration, 3);
|
||||
|
||||
setTriggerSynchronizationGap(engineConfiguration, 0.72);
|
||||
setTriggerSynchronizationGap(&engineConfiguration->triggerConfig, 0.72);
|
||||
|
||||
engineConfiguration->triggerConfig.useRiseEdge = FALSE;
|
||||
engineConfiguration->needSecondTriggerInput = TRUE;
|
||||
engineConfiguration->triggerConfig.useRiseEdge = false;
|
||||
engineConfiguration->needSecondTriggerInput = true;
|
||||
|
||||
// set_cranking_injection_mode 0
|
||||
engineConfiguration->crankingInjectionMode = IM_SIMULTANEOUS;
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
*
|
||||
* http://rusefi.com/forum/viewtopic.php?f=3&t=469
|
||||
*
|
||||
* This config overrides some values of the default configuration which is set by setDefaultConfiguration() method
|
||||
*
|
||||
* FORD_INLINE_6_1995 = 7
|
||||
*
|
||||
* @date Feb 12, 2014
|
||||
|
@ -38,12 +40,9 @@ void setFordInline6(engine_configuration_s *engineConfiguration, board_configura
|
|||
/**
|
||||
* We treat the trigger as 6/0 toothed wheel
|
||||
*/
|
||||
engineConfiguration->triggerConfig.triggerType = TT_TOOTHED_WHEEL;
|
||||
engineConfiguration->triggerConfig.totalToothCount = 6;
|
||||
engineConfiguration->triggerConfig.skippedToothCount = 0;
|
||||
engineConfiguration->triggerConfig.isSynchronizationNeeded = FALSE;
|
||||
setToothedWheelConfiguration(engineConfiguration, 6, 0);
|
||||
engineConfiguration->triggerConfig.useRiseEdge = TRUE;
|
||||
engineConfiguration->needSecondTriggerInput = FALSE;
|
||||
engineConfiguration->needSecondTriggerInput = false;
|
||||
|
||||
engineConfiguration->globalTriggerAngleOffset = 0;
|
||||
engineConfiguration->ignitionOffset = 13;
|
||||
|
|
|
@ -119,8 +119,7 @@ void setFordAspireEngineConfiguration(engine_configuration_s *engineConfiguratio
|
|||
setSingleCoilDwell(engineConfiguration);
|
||||
engineConfiguration->ignitionMode = IM_ONE_COIL;
|
||||
engineConfiguration->triggerConfig.triggerType = TT_FORD_ASPIRE;
|
||||
engineConfiguration->triggerConfig.isSynchronizationNeeded = FALSE;
|
||||
|
||||
engineConfiguration->triggerConfig.isSynchronizationNeeded = false;
|
||||
|
||||
boardConfiguration->injectionPins[4] = GPIO_NONE;
|
||||
boardConfiguration->injectionPins[5] = GPIO_NONE;
|
||||
|
|
|
@ -23,8 +23,6 @@ void setFordEscortGt(engine_configuration_s *engineConfiguration, board_configur
|
|||
// set_injection_offset 510
|
||||
engineConfiguration->injectionOffset = 59;
|
||||
|
||||
|
||||
|
||||
setSingleCoilDwell(engineConfiguration);
|
||||
engineConfiguration->ignitionMode = IM_ONE_COIL;
|
||||
|
||||
|
|
|
@ -20,8 +20,7 @@ void setFordFiestaDefaultEngineConfiguration(engine_configuration_s *engineConfi
|
|||
engineConfiguration->rpmHardLimit = 7000;
|
||||
setOperationMode(engineConfiguration, FOUR_STROKE_CRANK_SENSOR);
|
||||
|
||||
engineConfiguration->triggerConfig.totalToothCount = 36;
|
||||
engineConfiguration->triggerConfig.skippedToothCount = 1;
|
||||
setToothedWheelConfiguration(engineConfiguration, 36, 1);
|
||||
|
||||
engineConfiguration->ignitionMode = IM_WASTED_SPARK;
|
||||
engineConfiguration->firingOrder = FO_1_THEN_3_THEN_4_THEN2;
|
||||
|
|
|
@ -16,8 +16,5 @@ void setMazda323EngineConfiguration(engine_configuration_s *engineConfiguration)
|
|||
/**
|
||||
* We treat the trigger as 4/0 toothed wheel
|
||||
*/
|
||||
engineConfiguration->triggerConfig.totalToothCount = 4;
|
||||
engineConfiguration->triggerConfig.skippedToothCount = 0;
|
||||
engineConfiguration->triggerConfig.isSynchronizationNeeded = FALSE;
|
||||
|
||||
setToothedWheelConfiguration(engineConfiguration, 4, 0);
|
||||
}
|
||||
|
|
|
@ -17,8 +17,8 @@ void setMazdaMiataNbEngineConfiguration(engine_configuration_s *engineConfigurat
|
|||
|
||||
engineConfiguration->triggerConfig.triggerType = TT_MAZDA_MIATA_NB;
|
||||
|
||||
setTriggerSynchronizationGap(engineConfiguration, 0.11);
|
||||
engineConfiguration->triggerConfig.useRiseEdge = FALSE;
|
||||
setTriggerSynchronizationGap(&engineConfiguration->triggerConfig, 0.11);
|
||||
engineConfiguration->triggerConfig.useRiseEdge = false;
|
||||
engineConfiguration->globalTriggerAngleOffset = 276;
|
||||
|
||||
// set_cranking_injection_mode 0
|
||||
|
|
|
@ -13,8 +13,7 @@
|
|||
#include "nissan_primera.h"
|
||||
|
||||
void setNissanPrimeraEngineConfiguration(engine_configuration_s *engineConfiguration) {
|
||||
engineConfiguration->triggerConfig.totalToothCount = 60;
|
||||
engineConfiguration->triggerConfig.skippedToothCount = 2;
|
||||
setToothedWheelConfiguration(engineConfiguration, 60, 2);
|
||||
}
|
||||
|
||||
#endif /* EFI_SUPPORT_NISSAN_PRIMERA */
|
||||
|
|
|
@ -3,6 +3,8 @@
|
|||
*
|
||||
* V8, firing order 18436572
|
||||
*
|
||||
* This config overrides some values of the default configuration which is set by setDefaultConfiguration() method
|
||||
*
|
||||
* ROVER_V8 = 10
|
||||
*
|
||||
* @date Jun 27, 2014
|
||||
|
@ -16,11 +18,9 @@ void setRoverv8(engine_configuration_s *engineConfiguration,
|
|||
board_configuration_s *boardConfiguration) {
|
||||
|
||||
setOperationMode(engineConfiguration, FOUR_STROKE_CRANK_SENSOR);
|
||||
engineConfiguration->triggerConfig.totalToothCount = 36;
|
||||
engineConfiguration->triggerConfig.skippedToothCount = 1;
|
||||
setToothedWheelConfiguration(engineConfiguration, 36, 1);
|
||||
|
||||
// todo: displacement? 4 liters?
|
||||
engineConfiguration->displacement = 4;
|
||||
engineConfiguration->displacement = 3.528;
|
||||
engineConfiguration->cylindersCount = 8;
|
||||
engineConfiguration->firingOrder = FO_1_8_4_3_6_5_7_2;
|
||||
|
||||
|
@ -34,7 +34,7 @@ void setRoverv8(engine_configuration_s *engineConfiguration,
|
|||
|
||||
|
||||
// set_cranking_injection_mode 0
|
||||
engineConfiguration->crankingInjectionMode = IM_SEQUENTIAL;
|
||||
engineConfiguration->crankingInjectionMode = IM_SIMULTANEOUS;
|
||||
// set_injection_mode 1
|
||||
engineConfiguration->injectionMode = IM_SEQUENTIAL;
|
||||
|
||||
|
|
|
@ -31,7 +31,7 @@ extern SerialUSBDriver SDU1;
|
|||
int lastWriteSize;
|
||||
int lastWriteActual;
|
||||
|
||||
static bool_t isSerialConsoleStarted = FALSE;
|
||||
static bool isSerialConsoleStarted = false;
|
||||
|
||||
static EventListener consoleEventListener;
|
||||
|
||||
|
@ -99,7 +99,7 @@ static bool getConsoleLine(BaseSequentialStream *chp, char *line, unsigned size)
|
|||
consolePutChar('\r');
|
||||
consolePutChar('\n');
|
||||
*p = 0;
|
||||
return FALSE;
|
||||
return false;
|
||||
}
|
||||
if (c < 0x20)
|
||||
continue;
|
||||
|
@ -136,7 +136,7 @@ static msg_t consoleThreadThreadEntryPoint(void *arg) {
|
|||
(console_line_callback)(consoleInput);
|
||||
}
|
||||
#if defined __GNUC__
|
||||
return FALSE;
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -182,7 +182,10 @@ void startConsole(void (*console_line_callback_p)(char *)) {
|
|||
console_line_callback = console_line_callback_p;
|
||||
|
||||
#if EFI_PROD_CODE
|
||||
is_serial_over_uart = palReadPad(GPIOA, GPIOA_BUTTON) != EFI_USE_UART_FOR_CONSOLE;
|
||||
|
||||
palSetPadMode(CONSOLE_MODE_SWITCH_PORT, CONSOLE_MODE_SWITCH_PIN, PAL_MODE_INPUT_PULLUP);
|
||||
|
||||
is_serial_over_uart = GET_CONSOLE_MODE_VALUE() == EFI_USE_UART_FOR_CONSOLE;
|
||||
|
||||
if (isSerialOverUart()) {
|
||||
/*
|
||||
|
@ -221,10 +224,10 @@ bool lockAnyContext(void) {
|
|||
chSysLock()
|
||||
;
|
||||
}
|
||||
return FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool_t lockOutputBuffer(void) {
|
||||
bool lockOutputBuffer(void) {
|
||||
return lockAnyContext();
|
||||
}
|
||||
|
||||
|
|
|
@ -21,6 +21,9 @@
|
|||
#include "efifeatures.h"
|
||||
#include "boards.h"
|
||||
|
||||
#define GET_CONSOLE_MODE_VALUE() palReadPad(CONSOLE_MODE_SWITCH_PORT, CONSOLE_MODE_SWITCH_PIN)
|
||||
#define SHOULD_INGORE_FLASH() (palReadPad(CONFIG_RESET_SWITCH_PORT, CONFIG_RESET_SWITCH_PIN) == 0)
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
|
|
|
@ -161,7 +161,6 @@ void printState(int currentCkpEventCounter) {
|
|||
|
||||
int rpm = getRpm();
|
||||
debugInt(&logger, "ckp_c", currentCkpEventCounter);
|
||||
debugInt(&logger, "fuel_lag", getRevolutionCounter());
|
||||
|
||||
// debugInt(&logger, "idl", getIdleSwitch());
|
||||
|
||||
|
@ -171,7 +170,7 @@ void printState(int currentCkpEventCounter) {
|
|||
debugFloat(&logger, "fuel_base", getBaseFuel(rpm, engineLoad), 2);
|
||||
// debugFloat(&logger, "fuel_iat", getIatCorrection(getIntakeAirTemperature()), 2);
|
||||
// debugFloat(&logger, "fuel_clt", getCltCorrection(getCoolantTemperature()), 2);
|
||||
// debugFloat(&logger, "fuel_lag", getInjectorLag(getVBatt()), 2);
|
||||
debugFloat(&logger, "fuel_lag", getInjectorLag(getVBatt()), 2);
|
||||
debugFloat(&logger, "fuel", getRunningFuel(rpm, engineLoad), 2);
|
||||
|
||||
debugFloat(&logger, "timing", getAdvance(rpm, engineLoad), 2);
|
||||
|
@ -298,26 +297,27 @@ void updateDevConsoleState(void) {
|
|||
* that would be 'show fuel for rpm 3500 maf 4.0'
|
||||
*/
|
||||
|
||||
static void showFuelMap(int rpm, int key100) {
|
||||
float engineLoad = key100 / 100.0;
|
||||
|
||||
static void showFuelMap2(float rpm, float engineLoad) {
|
||||
float baseFuel = getBaseFuel(rpm, engineLoad);
|
||||
|
||||
float iatCorrection = getIatCorrection(getIntakeAirTemperature());
|
||||
float cltCorrection = getCltCorrection(getCoolantTemperature());
|
||||
float injectorLag = getInjectorLag(getVBatt());
|
||||
print("baseFuel=%f\r\n", baseFuel);
|
||||
scheduleMsg(&logger2, "rpm=%f engineLoad=%f", rpm, engineLoad);
|
||||
scheduleMsg(&logger2, "baseFuel=%f", baseFuel);
|
||||
|
||||
print("iatCorrection=%f cltCorrection=%f injectorLag=%d\r\n", iatCorrection, cltCorrection,
|
||||
(int) (100 * injectorLag));
|
||||
scheduleMsg(&logger2, "iatCorrection=%f cltCorrection=%f injectorLag=%f", iatCorrection, cltCorrection,
|
||||
injectorLag);
|
||||
|
||||
float value = getRunningFuel(rpm, engineLoad);
|
||||
|
||||
print("fuel map rpm=%d, key=%f: %d\r\n", rpm, engineLoad, (int) (100 * value));
|
||||
|
||||
scheduleMsg(&logger2, "fuel map value = %f", value);
|
||||
scheduleMsg(&logger2, "injection pulse width: %f", value);
|
||||
}
|
||||
|
||||
static void showFuelMap(void) {
|
||||
showFuelMap2(getRpm(), getEngineLoad());
|
||||
}
|
||||
|
||||
|
||||
static char buffer[10];
|
||||
static char dateBuffer[30];
|
||||
|
||||
|
@ -415,7 +415,8 @@ void initStatusLoop(void) {
|
|||
#if EFI_PROD_CODE
|
||||
initLogging(&logger2, "main event handler");
|
||||
|
||||
addConsoleActionII("sfm", showFuelMap);
|
||||
addConsoleActionFF("fuelinfo2", showFuelMap2);
|
||||
addConsoleAction("fuelinfo", showFuelMap);
|
||||
|
||||
addConsoleAction("status", printStatus);
|
||||
#endif /* EFI_PROD_CODE */
|
||||
|
|
|
@ -26,12 +26,9 @@
|
|||
|
||||
#include "engine_state.h"
|
||||
#include "tunerstudio.h"
|
||||
#include "pin_repository.h"
|
||||
|
||||
#include "main_trigger_callback.h"
|
||||
#include "flash_main.h"
|
||||
#include "usbconsole.h"
|
||||
#include "map_averaging.h"
|
||||
|
||||
#include "tunerstudio_algo.h"
|
||||
#include "tunerstudio_configuration.h"
|
||||
|
@ -42,27 +39,40 @@
|
|||
|
||||
#if EFI_TUNER_STUDIO
|
||||
|
||||
#define MAX_PAGE_ID 5
|
||||
#define PAGE_0_SIZE 1356
|
||||
|
||||
// in MS, that's 10 seconds
|
||||
#define TS_READ_TIMEOUT 10000
|
||||
#if EFI_PROD_CODE
|
||||
#include "pin_repository.h"
|
||||
#include "usbconsole.h"
|
||||
#include "map_averaging.h"
|
||||
extern SerialUSBDriver SDU1;
|
||||
#define CONSOLE_DEVICE &SDU1
|
||||
|
||||
#define TS_SERIAL_UART_DEVICE &SD3
|
||||
//#define TS_SERIAL_SPEED 115200
|
||||
#define TS_SERIAL_SPEED 38400
|
||||
|
||||
static SerialConfig tsSerialConfig = { TS_SERIAL_SPEED, 0, USART_CR2_STOP1_BITS | USART_CR2_LINEN, 0 };
|
||||
#endif /* EFI_PROD_CODE */
|
||||
|
||||
#define MAX_PAGE_ID 0
|
||||
#define PAGE_0_SIZE 5804
|
||||
|
||||
// in MS, that's 10 seconds
|
||||
#define TS_READ_TIMEOUT 10000
|
||||
|
||||
#define PROTOCOL "001"
|
||||
|
||||
extern SerialUSBDriver SDU1;
|
||||
|
||||
BaseChannel * getTsSerialDevice(void) {
|
||||
#if EFI_PROD_CODE
|
||||
if (isSerialOverUart()) {
|
||||
// if console uses UART then TS uses USB
|
||||
return (BaseChannel *) &SDU1;
|
||||
} else {
|
||||
return (BaseChannel *) TS_SERIAL_UART_DEVICE;
|
||||
}
|
||||
#else
|
||||
return (BaseChannel *) TS_SIMULATOR_PORT;
|
||||
#endif
|
||||
}
|
||||
|
||||
static Logging logger;
|
||||
|
@ -71,12 +81,10 @@ extern engine_configuration_s *engineConfiguration;
|
|||
extern persistent_config_s configWorkingCopy;
|
||||
extern persistent_config_container_s persistentState;
|
||||
|
||||
extern SerialUSBDriver SDU1;
|
||||
#define CONSOLE_DEVICE &SDU1
|
||||
|
||||
static efitimems_t previousWriteReportMs = 0;
|
||||
|
||||
static int ts_serail_ready(void) {
|
||||
#if EFI_PROD_CODE
|
||||
if (isSerialOverUart()) {
|
||||
// TS uses USB when console uses serial
|
||||
return is_usb_serial_ready();
|
||||
|
@ -84,10 +92,11 @@ static int ts_serail_ready(void) {
|
|||
// TS uses serial when console uses USB
|
||||
return TRUE;
|
||||
}
|
||||
#else
|
||||
return TRUE;
|
||||
#endif
|
||||
}
|
||||
|
||||
static SerialConfig tsSerialConfig = { TS_SERIAL_SPEED, 0, USART_CR2_STOP1_BITS | USART_CR2_LINEN, 0 };
|
||||
|
||||
static THD_WORKING_AREA(TS_WORKING_AREA, UTILITY_THREAD_STACK_SIZE);
|
||||
|
||||
static int tsCounter = 0;
|
||||
|
@ -100,10 +109,12 @@ extern TunerStudioOutputChannels tsOutputChannels;
|
|||
extern TunerStudioState tsState;
|
||||
|
||||
static void printStats(void) {
|
||||
#if EFI_PROD_CODE
|
||||
if (!isSerialOverUart()) {
|
||||
scheduleMsg(&logger, "TS RX on %s%d", portname(TS_SERIAL_RX_PORT), TS_SERIAL_RX_PIN);
|
||||
scheduleMsg(&logger, "TS TX on %s%d", portname(TS_SERIAL_TX_PORT), TS_SERIAL_TX_PIN);
|
||||
}
|
||||
#endif /* EFI_PROD_CODE */
|
||||
scheduleMsg(&logger, "TunerStudio total/error counter=%d/%d", tsCounter, tsState.errorCounter);
|
||||
scheduleMsg(&logger, "TunerStudio H counter=%d", tsState.queryCommandCounter);
|
||||
scheduleMsg(&logger, "TunerStudio O counter=%d size=%d", tsState.outputChannelsCommandCounter,
|
||||
|
@ -113,15 +124,34 @@ static void printStats(void) {
|
|||
scheduleMsg(&logger, "TunerStudio W counter=%d", tsState.writeValueCommandCounter);
|
||||
scheduleMsg(&logger, "TunerStudio C counter=%d", tsState.writeChunkCommandCounter);
|
||||
scheduleMsg(&logger, "TunerStudio P counter=%d current page %d", tsState.pageCommandCounter, tsState.currentPageId);
|
||||
scheduleMsg(&logger, "pages total size=%d", sizeof(engine_configuration_s));
|
||||
scheduleMsg(&logger, "page 0 size=%d", getTunerStudioPageSize(0));
|
||||
scheduleMsg(&logger, "page 1 size=%d", getTunerStudioPageSize(1));
|
||||
|
||||
// scheduleMsg(&logger, "timingMode %d", (int)(&engineConfiguration->timingMode) - (int)engineConfiguration);
|
||||
// scheduleMsg(&logger, "cylindersCount %d", (int)(&engineConfiguration->cylindersCount) - (int)engineConfiguration);
|
||||
scheduleMsg(&logger, "analogChartFrequency %d",
|
||||
(int) (&engineConfiguration->analogChartFrequency) - (int) engineConfiguration);
|
||||
|
||||
int fuelMapOffset = (int) (&engineConfiguration->fuelTable) - (int) engineConfiguration;
|
||||
scheduleMsg(&logger, "fuelTable %d", fuelMapOffset);
|
||||
|
||||
int offset = (int) (&engineConfiguration->bc.injectionPinMode) - (int) engineConfiguration;
|
||||
scheduleMsg(&logger, "injectionPinMode %d", offset);
|
||||
|
||||
offset = (int) (&engineConfiguration->bc.idleThreadPeriod) - (int) engineConfiguration;
|
||||
scheduleMsg(&logger, "idleThreadPeriod %d", offset);
|
||||
|
||||
|
||||
if (sizeof(engine_configuration_s) != getTunerStudioPageSize(0))
|
||||
firmwareError("TS page size mismatch");
|
||||
}
|
||||
|
||||
void tunerStudioWriteData(const uint8_t * buffer, int size) {
|
||||
chSequentialStreamWrite(getTsSerialDevice(), buffer, size);
|
||||
}
|
||||
|
||||
void tunerStudioDebug(char *msg) {
|
||||
void tunerStudioDebug(const char *msg) {
|
||||
#if EFI_TUNER_STUDIO_VERBOSE
|
||||
scheduleMsg(&logger, "%s", msg);
|
||||
printStats();
|
||||
|
@ -132,13 +162,13 @@ char *getWorkingPageAddr(int pageIndex) {
|
|||
switch (pageIndex) {
|
||||
case 0:
|
||||
return (char*) &configWorkingCopy.engineConfiguration;
|
||||
case 1:
|
||||
return (char*) &configWorkingCopy.boardConfiguration;
|
||||
case 2: // fuelTable
|
||||
case 3: // ignitionTable
|
||||
case 4: // veTable
|
||||
case 5: // afrTable
|
||||
return (char*) &configWorkingCopy.engineConfiguration + PAGE_0_SIZE + (pageIndex - 2) * 1024;
|
||||
// case 1:
|
||||
// return (char*) &configWorkingCopy.boardConfiguration;
|
||||
// case 2: // fuelTable
|
||||
// case 3: // ignitionTable
|
||||
// case 4: // veTable
|
||||
// case 5: // afrTable
|
||||
// return (char*) &configWorkingCopy.engineConfiguration + PAGE_0_SIZE + (pageIndex - 2) * 1024;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
@ -147,58 +177,56 @@ int getTunerStudioPageSize(int pageIndex) {
|
|||
switch (pageIndex) {
|
||||
case 0:
|
||||
return PAGE_0_SIZE;
|
||||
case 1:
|
||||
return sizeof(configWorkingCopy.boardConfiguration);
|
||||
case 2:
|
||||
case 3:
|
||||
case 4:
|
||||
return 1024;
|
||||
// case 1:
|
||||
// return sizeof(configWorkingCopy.boardConfiguration);
|
||||
// case 2:
|
||||
// case 3:
|
||||
// case 4:
|
||||
// return 1024;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void handlePageSelectCommand(uint16_t pageId) {
|
||||
void handlePageSelectCommand(ts_response_format_e mode, uint16_t pageId) {
|
||||
tsState.pageCommandCounter++;
|
||||
|
||||
tsState.currentPageId = pageId;
|
||||
scheduleMsg(&logger, "page %d selected", tsState.currentPageId);
|
||||
tunerStudioWriteCrcPacket(TS_RESPONSE_OK, NULL, 0);
|
||||
tsSendResponse(mode, NULL, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* This command is needed to make the whole transfer a bit faster
|
||||
* @note See also handleWriteValueCommand
|
||||
*/
|
||||
void handleWriteChunkCommand(short offset, short count, void *content) {
|
||||
void handleWriteChunkCommand(ts_response_format_e mode, short offset, short count, void *content) {
|
||||
tsState.writeChunkCommandCounter++;
|
||||
|
||||
scheduleMsg(&logger, "receiving page %d chunk offset %d size %d", tsState.currentPageId, offset, count);
|
||||
|
||||
if (offset > getTunerStudioPageSize(tsState.currentPageId)) {
|
||||
scheduleMsg(&logger, "ERROR offset %d", offset);
|
||||
// out of range
|
||||
tsState.errorCounter++;
|
||||
tunerStudioError("ERROR: out of range");
|
||||
offset = 0;
|
||||
}
|
||||
|
||||
if (count > getTunerStudioPageSize(tsState.currentPageId)) {
|
||||
tunerStudioError("ERROR: unexpected count");
|
||||
scheduleMsg(&logger, "ERROR count %d", count);
|
||||
// out of range
|
||||
tsState.errorCounter++;
|
||||
count = 0;
|
||||
}
|
||||
|
||||
uint8_t * addr = (uint8_t *) (getWorkingPageAddr(tsState.currentPageId) + offset);
|
||||
// memcpy(addr, content, count);
|
||||
memcpy(addr, content, count);
|
||||
|
||||
tunerStudioWriteCrcPacket(TS_RESPONSE_OK, NULL, 0);
|
||||
tsSendResponse(mode, NULL, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* 'Write' command receives a single value at a given offset
|
||||
* @note Writing values one by one is pretty slow
|
||||
*/
|
||||
void handleWriteValueCommand(uint16_t page, uint16_t offset, uint8_t value) {
|
||||
void handleWriteValueCommand(ts_response_format_e mode, uint16_t page, uint16_t offset, uint8_t value) {
|
||||
tsState.writeValueCommandCounter++;
|
||||
|
||||
tsState.currentPageId = page;
|
||||
|
@ -213,9 +241,8 @@ void handleWriteValueCommand(uint16_t page, uint16_t offset, uint8_t value) {
|
|||
// scheduleMsg(&logger, "Reading %d\r\n", size);
|
||||
|
||||
if (offset > getTunerStudioPageSize(tsState.currentPageId)) {
|
||||
tunerStudioError("ERROR: out of range2");
|
||||
scheduleMsg(&logger, "ERROR offset %d", offset);
|
||||
// out of range
|
||||
tsState.errorCounter++;
|
||||
offset = 0;
|
||||
return;
|
||||
}
|
||||
|
@ -235,7 +262,7 @@ static void sendErrorCode(void) {
|
|||
tunerStudioWriteCrcPacket(TS_RESPONSE_CRC_FAILURE, NULL, 0);
|
||||
}
|
||||
|
||||
void handlePageReadCommand(uint16_t pageId, uint16_t offset, uint16_t count) {
|
||||
void handlePageReadCommand(ts_response_format_e mode, uint16_t pageId, uint16_t offset, uint16_t count) {
|
||||
tsState.readPageCommandsCounter++;
|
||||
tunerStudioDebug("got R (Read page)");
|
||||
tsState.currentPageId = pageId;
|
||||
|
@ -249,7 +276,7 @@ void handlePageReadCommand(uint16_t pageId, uint16_t offset, uint16_t count) {
|
|||
|
||||
// something is not right here
|
||||
tsState.currentPageId = 0;
|
||||
tsState.errorCounter++;
|
||||
tunerStudioError("ERROR: invalid page");
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -262,16 +289,16 @@ void handlePageReadCommand(uint16_t pageId, uint16_t offset, uint16_t count) {
|
|||
}
|
||||
|
||||
const uint8_t *addr = (const uint8_t *) (getWorkingPageAddr(tsState.currentPageId) + offset);
|
||||
tunerStudioWriteCrcPacket(TS_RESPONSE_OK, addr, count);
|
||||
tsSendResponse(mode, addr, count);
|
||||
#if EFI_TUNER_STUDIO_VERBOSE
|
||||
scheduleMsg(&logger, "Sending %d done", size);
|
||||
scheduleMsg(&logger, "Sending %d done", count);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* 'Burn' command is a command to commit the changes
|
||||
*/
|
||||
void handleBurnCommand(uint16_t page) {
|
||||
void handleBurnCommand(ts_response_format_e mode, uint16_t page) {
|
||||
tsState.burnCommandCounter++;
|
||||
|
||||
tunerStudioDebug("got B (Burn)");
|
||||
|
@ -285,14 +312,59 @@ void handleBurnCommand(uint16_t page) {
|
|||
// todo: how about some multi-threading?
|
||||
memcpy(&persistentState.persistentConfiguration, &configWorkingCopy, sizeof(persistent_config_s));
|
||||
|
||||
scheduleMsg(&logger, "va1=%d", configWorkingCopy.boardConfiguration.idleValvePin);
|
||||
scheduleMsg(&logger, "va2=%d", persistentState.persistentConfiguration.boardConfiguration.idleValvePin);
|
||||
scheduleMsg(&logger, "va1=%d", configWorkingCopy.engineConfiguration.bc.idleValvePin);
|
||||
scheduleMsg(&logger, "va2=%d", persistentState.persistentConfiguration.engineConfiguration.bc.idleValvePin);
|
||||
|
||||
#if EFI_INTERNAL_FLASH
|
||||
writeToFlash();
|
||||
#endif
|
||||
incrementGlobalConfigurationVersion();
|
||||
tunerStudioWriteCrcPacket(TS_RESPONSE_BURN_OK, NULL, 0);
|
||||
}
|
||||
|
||||
static TunerStudioReadRequest readRequest;
|
||||
static short int pageIn;
|
||||
|
||||
static bool handlePlainCommand(uint8_t command) {
|
||||
if (command == TS_HELLO_COMMAND) {
|
||||
scheduleMsg(&logger, "Got naked Query command");
|
||||
handleQueryCommand(TS_PLAIN);
|
||||
return true;
|
||||
} else if (command == 't' || command == 'T') {
|
||||
handleTestCommand();
|
||||
return true;
|
||||
} else if (command == TS_PAGE_COMMAND) {
|
||||
int recieved = chSequentialStreamRead(getTsSerialDevice(), (uint8_t *)&pageIn, sizeof(pageIn));
|
||||
handlePageSelectCommand(TS_PLAIN, pageIn);
|
||||
return true;
|
||||
} else if (command == TS_READ_COMMAND) {
|
||||
//scheduleMsg(&logger, "Got naked READ PAGE???");
|
||||
int recieved = chSequentialStreamRead(getTsSerialDevice(), (uint8_t *)&readRequest, sizeof(readRequest));
|
||||
if (recieved != sizeof(readRequest)) {
|
||||
// todo: handler error
|
||||
return true;
|
||||
}
|
||||
handlePageReadCommand(TS_PLAIN, readRequest.page, readRequest.offset, readRequest.count);
|
||||
return true;
|
||||
} else if (command == TS_OUTPUT_COMMAND) {
|
||||
//scheduleMsg(&logger, "Got naked Channels???");
|
||||
handleOutputChannelsCommand(TS_PLAIN);
|
||||
return true;
|
||||
} else if (command == 'F') {
|
||||
tunerStudioDebug("not ignoring F");
|
||||
tunerStudioWriteData((const uint8_t *) PROTOCOL, strlen(PROTOCOL));
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static bool isKnownCommand(char command) {
|
||||
return command == TS_HELLO_COMMAND || command == TS_READ_COMMAND || command == TS_OUTPUT_COMMAND
|
||||
|| command == TS_PAGE_COMMAND || command == TS_BURN_COMMAND || command == TS_SINGLE_WRITE_COMMAND
|
||||
|| command == TS_CHUNK_WRITE_COMMAND;
|
||||
}
|
||||
|
||||
static uint8_t firstByte;
|
||||
static uint8_t secondByte;
|
||||
|
||||
|
@ -303,12 +375,12 @@ static msg_t tsThreadEntryPoint(void *arg) {
|
|||
(void) arg;
|
||||
chRegSetThreadName("tunerstudio thread");
|
||||
|
||||
int wasReady = FALSE;
|
||||
int wasReady = false;
|
||||
while (true) {
|
||||
int isReady = ts_serail_ready();
|
||||
if (!isReady) {
|
||||
chThdSleepMilliseconds(10);
|
||||
wasReady = FALSE;
|
||||
wasReady = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -321,32 +393,16 @@ static msg_t tsThreadEntryPoint(void *arg) {
|
|||
|
||||
int recieved = chSequentialStreamRead(getTsSerialDevice(), &firstByte, 1);
|
||||
if (recieved != 1) {
|
||||
tsState.errorCounter++;
|
||||
tunerStudioError("ERROR: no command");
|
||||
continue;
|
||||
}
|
||||
// scheduleMsg(&logger, "Got first=%x=[%c]", firstByte, firstByte);
|
||||
if (firstByte == TS_HELLO_COMMAND) {
|
||||
scheduleMsg(&logger, "Got naked Query command");
|
||||
handleQueryCommand(FALSE);
|
||||
if (handlePlainCommand(firstByte))
|
||||
continue;
|
||||
} else if (firstByte == 't' || firstByte == 'T') {
|
||||
handleTestCommand();
|
||||
continue;
|
||||
} else if (firstByte == TS_READ_COMMAND) {
|
||||
scheduleMsg(&logger, "Got naked READ PAGE???");
|
||||
continue;
|
||||
} else if (firstByte == TS_OUTPUT_COMMAND) {
|
||||
scheduleMsg(&logger, "Got naked Channels???");
|
||||
continue;
|
||||
} else if (firstByte == 'F') {
|
||||
tunerStudioDebug("not ignoring F");
|
||||
tunerStudioWriteData((const uint8_t *) PROTOCOL, strlen(PROTOCOL));
|
||||
continue;
|
||||
}
|
||||
|
||||
recieved = chSequentialStreamRead(getTsSerialDevice(), &secondByte, 1);
|
||||
if (recieved != 1) {
|
||||
tsState.errorCounter++;
|
||||
tunerStudioError("ERROR: no second");
|
||||
continue;
|
||||
}
|
||||
// scheduleMsg(&logger, "Got secondByte=%x=[%c]", secondByte, secondByte);
|
||||
|
@ -355,22 +411,19 @@ static msg_t tsThreadEntryPoint(void *arg) {
|
|||
|
||||
if (incomingPacketSize == 0 || incomingPacketSize > sizeof(crcIoBuffer)) {
|
||||
scheduleMsg(&logger, "TunerStudio: invalid size: %d", incomingPacketSize);
|
||||
tsState.errorCounter++;
|
||||
tunerStudioError("ERROR: size");
|
||||
sendErrorCode();
|
||||
continue;
|
||||
}
|
||||
|
||||
recieved = chnReadTimeout(getTsSerialDevice(), crcIoBuffer, 1, MS2ST(TS_READ_TIMEOUT));
|
||||
if (recieved != 1) {
|
||||
scheduleMsg(&logger, "did not receive command");
|
||||
tsState.errorCounter++;
|
||||
tunerStudioError("ERROR: did not receive command");
|
||||
continue;
|
||||
}
|
||||
|
||||
char command = crcIoBuffer[0];
|
||||
if (command != TS_HELLO_COMMAND && command != TS_READ_COMMAND && command != TS_OUTPUT_COMMAND
|
||||
&& command != TS_PAGE_COMMAND && command != TS_BURN_COMMAND && command != TS_SINGLE_WRITE_COMMAND
|
||||
&& command != TS_CHUNK_WRITE_COMMAND) {
|
||||
if (!isKnownCommand(command)) {
|
||||
scheduleMsg(&logger, "unexpected command %x", command);
|
||||
sendErrorCode();
|
||||
continue;
|
||||
|
@ -380,9 +433,11 @@ static msg_t tsThreadEntryPoint(void *arg) {
|
|||
|
||||
recieved = chnReadTimeout(getTsSerialDevice(), (void * ) (crcIoBuffer + 1), incomingPacketSize + 4 - 1,
|
||||
MS2ST(TS_READ_TIMEOUT));
|
||||
if (recieved != incomingPacketSize + 4 - 1) {
|
||||
scheduleMsg(&logger, "got ONLY %d", recieved);
|
||||
tsState.errorCounter++;
|
||||
int expectedSize = incomingPacketSize + 4 - 1;
|
||||
if (recieved != expectedSize) {
|
||||
scheduleMsg(&logger, "got ONLY %d for packet size %d/%d for command %c", recieved, incomingPacketSize,
|
||||
expectedSize, command);
|
||||
tunerStudioError("ERROR: not enough");
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -398,14 +453,14 @@ static msg_t tsThreadEntryPoint(void *arg) {
|
|||
|
||||
scheduleMsg(&logger, "TunerStudio: command %c actual CRC %x/expected %x", crcIoBuffer[0], actualCrc,
|
||||
expectedCrc);
|
||||
tsState.errorCounter++;
|
||||
tunerStudioError("ERROR: CRC issue");
|
||||
continue;
|
||||
}
|
||||
|
||||
// scheduleMsg(&logger, "TunerStudio: P00-07 %x %x %x %x %x %x %x %x", crcIoBuffer[0], crcIoBuffer[1],
|
||||
// crcIoBuffer[2], crcIoBuffer[3], crcIoBuffer[4], crcIoBuffer[5], crcIoBuffer[6], crcIoBuffer[7]);
|
||||
|
||||
int success = tunerStudioHandleCommand(crcIoBuffer, incomingPacketSize);
|
||||
int success = tunerStudioHandleCrcCommand(crcIoBuffer, incomingPacketSize);
|
||||
if (!success)
|
||||
print("got unexpected TunerStudio command %x:%c\r\n", command, command);
|
||||
|
||||
|
@ -422,6 +477,7 @@ void syncTunerStudioCopy(void) {
|
|||
void startTunerStudioConnectivity(void) {
|
||||
initLogging(&logger, "tuner studio");
|
||||
memset(&tsState, 0, sizeof(tsState));
|
||||
#if EFI_PROD_CODE
|
||||
if (isSerialOverUart()) {
|
||||
print("TunerStudio over USB serial");
|
||||
usb_serial_start();
|
||||
|
@ -433,7 +489,7 @@ void startTunerStudioConnectivity(void) {
|
|||
|
||||
sdStart(TS_SERIAL_UART_DEVICE, &tsSerialConfig);
|
||||
}
|
||||
|
||||
#endif /* EFI_PROD_CODE */
|
||||
syncTunerStudioCopy();
|
||||
|
||||
addConsoleAction("tsinfo", printStats);
|
||||
|
|
|
@ -10,39 +10,46 @@
|
|||
|
||||
#include "tunerstudio_configuration.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
void startTunerStudioConnectivity(void);
|
||||
void syncTunerStudioCopy(void);
|
||||
void updateTunerStudioState(TunerStudioOutputChannels *tsOutputChannels);
|
||||
void tunerStudioWriteCrcPacket(const uint8_t command, const void *buf, const uint16_t size);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#if defined __GNUC__
|
||||
typedef struct
|
||||
__attribute__((packed)) {
|
||||
// GCC
|
||||
#define pre_packed
|
||||
#define post_packed __attribute__((packed))
|
||||
#else
|
||||
typedef __packed struct {
|
||||
// IAR
|
||||
#define pre_packed __packed
|
||||
#define post_packed
|
||||
#endif
|
||||
|
||||
typedef pre_packed struct
|
||||
post_packed {
|
||||
short int offset;
|
||||
short int count;
|
||||
|
||||
} TunerStudioWriteChunkRequest;
|
||||
|
||||
#if defined __GNUC__
|
||||
typedef struct
|
||||
__attribute__((packed)) {
|
||||
#else
|
||||
typedef __packed struct {
|
||||
#endif
|
||||
typedef pre_packed struct
|
||||
post_packed {
|
||||
short int page;
|
||||
short int offset;
|
||||
short int count;
|
||||
} TunerStudioReadRequest;
|
||||
|
||||
typedef pre_packed struct
|
||||
post_packed {
|
||||
short int offset;
|
||||
unsigned char value;
|
||||
} TunerStudioWriteValueRequest;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
void startTunerStudioConnectivity(void);
|
||||
void syncTunerStudioCopy(void);
|
||||
void updateTunerStudioState(TunerStudioOutputChannels *tsOutputChannels);
|
||||
void tunerStudioWriteCrcPacket(const uint8_t command, const void *buf, const uint16_t size);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* TUNERSTUDIO_H_ */
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
|
||||
TUNERSTUDIOSRC = console/tunerstudio/tunerstudio_algo.c \
|
||||
console/tunerstudio/tunerstudio.c
|
||||
TUNERSTUDIOSRC = $(PROJECT_DIR)/console/tunerstudio/tunerstudio_algo.c \
|
||||
$(PROJECT_DIR)/console/tunerstudio/tunerstudio.c
|
||||
|
|
|
@ -65,34 +65,39 @@ TunerStudioOutputChannels tsOutputChannels;
|
|||
*/
|
||||
persistent_config_s configWorkingCopy;
|
||||
|
||||
int tunerStudioHandleCommand(char *data, int incomingPacketSize) {
|
||||
void tunerStudioError(const char *msg) {
|
||||
tunerStudioDebug(msg);
|
||||
tsState.errorCounter++;
|
||||
}
|
||||
|
||||
int tunerStudioHandleCrcCommand(char *data, int incomingPacketSize) {
|
||||
char command = data[0];
|
||||
data++;
|
||||
if (command == TS_HELLO_COMMAND) {
|
||||
tunerStudioDebug("got CRC Query");
|
||||
handleQueryCommand(TRUE);
|
||||
handleQueryCommand(TS_CRC);
|
||||
} else if (command == TS_OUTPUT_COMMAND) {
|
||||
handleOutputChannelsCommand();
|
||||
handleOutputChannelsCommand(TS_CRC);
|
||||
} else if (command == TS_PAGE_COMMAND) {
|
||||
uint16_t page = *(uint16_t *) data;
|
||||
handlePageSelectCommand(page);
|
||||
handlePageSelectCommand(TS_CRC, page);
|
||||
} else if (command == TS_CHUNK_WRITE_COMMAND) {
|
||||
uint16_t offset = *(uint16_t *) data;
|
||||
uint16_t count = *(uint16_t *) (data + 2);
|
||||
handleWriteChunkCommand(offset, count, data + 4);
|
||||
handleWriteChunkCommand(TS_CRC, offset, count, data + 4);
|
||||
} else if (command == TS_SINGLE_WRITE_COMMAND) {
|
||||
uint16_t page = *(uint16_t *) data;
|
||||
uint16_t offset = *(uint16_t *) (data + 2);
|
||||
uint8_t value = data[4];
|
||||
handleWriteValueCommand(page, offset, value);
|
||||
handleWriteValueCommand(TS_CRC, page, offset, value);
|
||||
} else if (command == TS_BURN_COMMAND) {
|
||||
uint16_t page = *(uint16_t *) data;
|
||||
handleBurnCommand(page);
|
||||
handleBurnCommand(TS_CRC, page);
|
||||
} else if (command == TS_READ_COMMAND) {
|
||||
uint16_t page = *(uint16_t *) data;
|
||||
uint16_t offset = *(uint16_t *) (data + 2);
|
||||
uint16_t count = *(uint16_t *) (data + 4);
|
||||
handlePageReadCommand(page, offset, count);
|
||||
handlePageReadCommand(TS_CRC, page, offset, count);
|
||||
} else if (command == 't' || command == 'T') {
|
||||
handleTestCommand();
|
||||
} else if (command == 'F') {
|
||||
|
@ -105,32 +110,38 @@ int tunerStudioHandleCommand(char *data, int incomingPacketSize) {
|
|||
* Currently on some firmware versions the F command is not used and is just ignored by the firmware as a unknown command."
|
||||
*/
|
||||
} else {
|
||||
tunerStudioDebug("ignoring unexpected");
|
||||
tsState.errorCounter++;
|
||||
tunerStudioError("ERROR: ignoring unexpected command");
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void handleQueryCommand(int needCrc) {
|
||||
void tsSendResponse(ts_response_format_e mode, const uint8_t * buffer, int size) {
|
||||
if (mode == TS_CRC) {
|
||||
tunerStudioWriteCrcPacket(TS_RESPONSE_OK, buffer, size);
|
||||
} else {
|
||||
if (size > 0)
|
||||
tunerStudioWriteData(buffer, size);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Query with CRC takes place while re-establishing connection
|
||||
* Query without CRC takes place on TunerStudio startup
|
||||
*/
|
||||
void handleQueryCommand(ts_response_format_e mode) {
|
||||
tsState.queryCommandCounter++;
|
||||
tunerStudioDebug("got H (queryCommand)");
|
||||
if (needCrc) {
|
||||
// Query with CRC takes place while re-establishing connection
|
||||
tunerStudioWriteCrcPacket(TS_RESPONSE_OK, (const uint8_t *) TS_SIGNATURE, strlen(TS_SIGNATURE) + 1);
|
||||
} else {
|
||||
// Query without CRC takes place on TunerStudio startup
|
||||
tunerStudioWriteData((const uint8_t *) TS_SIGNATURE, strlen(TS_SIGNATURE) + 1);
|
||||
}
|
||||
tsSendResponse(mode, (const uint8_t *) TS_SIGNATURE, strlen(TS_SIGNATURE) + 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 'Output' command sends out a snapshot of current values
|
||||
*/
|
||||
void handleOutputChannelsCommand(void) {
|
||||
void handleOutputChannelsCommand(ts_response_format_e mode) {
|
||||
tsState.outputChannelsCommandCounter++;
|
||||
// this method is invoked too often to print any debug information
|
||||
tunerStudioWriteCrcPacket(TS_RESPONSE_OK, (const uint8_t *) &tsOutputChannels, sizeof(TunerStudioOutputChannels));
|
||||
tsSendResponse(mode, (const uint8_t *) &tsOutputChannels, sizeof(TunerStudioOutputChannels));
|
||||
}
|
||||
|
||||
void handleTestCommand(void) {
|
||||
|
|
|
@ -24,6 +24,11 @@
|
|||
#define TS_RESPONSE_BURN_OK 0x04
|
||||
#define TS_RESPONSE_CRC_FAILURE 0x82
|
||||
|
||||
typedef enum {
|
||||
TS_PLAIN = 0,
|
||||
TS_CRC = 1
|
||||
} ts_response_format_e;
|
||||
|
||||
typedef struct {
|
||||
int queryCommandCounter;
|
||||
int outputChannelsCommandCounter;
|
||||
|
@ -37,22 +42,25 @@ typedef struct {
|
|||
short currentPageId;
|
||||
} TunerStudioState;
|
||||
|
||||
int tunerStudioHandleCommand(char *data, int incomingPacketSize);
|
||||
int tunerStudioHandleCrcCommand(char *data, int incomingPacketSize);
|
||||
|
||||
void handleTestCommand(void);
|
||||
void handleQueryCommand(int needCrc);
|
||||
void handleOutputChannelsCommand(void);
|
||||
void handleQueryCommand(ts_response_format_e mode);
|
||||
void tsSendResponse(ts_response_format_e mode, const uint8_t * buffer, int size);
|
||||
void handleOutputChannelsCommand(ts_response_format_e mode);
|
||||
|
||||
char *getWorkingPageAddr(int pageIndex);
|
||||
int getTunerStudioPageSize(int pageIndex);
|
||||
void handleWriteValueCommand(uint16_t page, uint16_t offset, uint8_t value);
|
||||
void handleWriteChunkCommand(short offset, short count, void *content);
|
||||
void handlePageSelectCommand(uint16_t pageId);
|
||||
void handlePageReadCommand(uint16_t pageId, uint16_t offset, uint16_t count);
|
||||
void handleBurnCommand(uint16_t page);
|
||||
void handleWriteValueCommand(ts_response_format_e mode, uint16_t page, uint16_t offset, uint8_t value);
|
||||
void handleWriteChunkCommand(ts_response_format_e mode, short offset, short count, void *content);
|
||||
void handlePageSelectCommand(ts_response_format_e mode, uint16_t pageId);
|
||||
void handlePageReadCommand(ts_response_format_e mode, uint16_t pageId, uint16_t offset, uint16_t count);
|
||||
void handleBurnCommand(ts_response_format_e mode, uint16_t page);
|
||||
|
||||
void tunerStudioWriteData(const uint8_t * buffer, int size);
|
||||
void tunerStudioDebug(char *msg);
|
||||
void tunerStudioDebug(const char *msg);
|
||||
|
||||
void tunerStudioError(const char *msg);
|
||||
|
||||
#define TS_HELLO_COMMAND 'H'
|
||||
#define TS_OUTPUT_COMMAND 'O'
|
||||
|
|
|
@ -66,8 +66,7 @@ static int validateBuffer(Logging *logging, int extraLen, const char *text) {
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
int currentLen = loggingSize(logging);
|
||||
if (currentLen + extraLen > logging->bufferSize - 1) {
|
||||
if (remainingSize(logging) < extraLen + 1) {
|
||||
strcpy(logging->SMALL_BUFFER, "Logging buffer overflow: ");
|
||||
strcat(logging->SMALL_BUFFER, logging->name);
|
||||
strcat(logging->SMALL_BUFFER, "/");
|
||||
|
@ -90,6 +89,22 @@ void append(Logging *logging, const char *text) {
|
|||
logging->linePointer += extraLen;
|
||||
}
|
||||
|
||||
/**
|
||||
* @note This method if fast because it does not validate much, be sure what you are doing
|
||||
*/
|
||||
void appendFast(Logging *logging, const char *text) {
|
||||
// todo: fix this implementation? this would be a one-pass implementation instead of a two-pass
|
||||
// char c;
|
||||
// char *s = (char *) text;
|
||||
// do {
|
||||
// c = *s++;
|
||||
// *logging->linePointer++ = c;
|
||||
// } while (c != '\0');
|
||||
int extraLen = strlen(text);
|
||||
strcpy(logging->linePointer, text);
|
||||
logging->linePointer += extraLen;
|
||||
}
|
||||
|
||||
static void vappendPrintfI(Logging *logging, const char *fmt, va_list arg) {
|
||||
intermediateLoggingBuffer.eos = 0; // reset
|
||||
chvprintf((BaseSequentialStream *) &intermediateLoggingBuffer, fmt, arg);
|
||||
|
@ -365,8 +380,8 @@ void scheduleLogging(Logging *logging) {
|
|||
resetLogging(logging);
|
||||
}
|
||||
|
||||
uint32_t loggingSize(Logging *logging) {
|
||||
return (int) logging->linePointer - (int) (logging->buffer);
|
||||
uint32_t remainingSize(Logging *logging) {
|
||||
return logging->bufferSize - loggingSize(logging);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -43,11 +43,13 @@ extern "C"
|
|||
{
|
||||
#endif /* __cplusplus */
|
||||
|
||||
bool_t lockOutputBuffer(void);
|
||||
bool lockOutputBuffer(void);
|
||||
void unlockOutputBuffer(void);
|
||||
|
||||
void initIntermediateLoggingBuffer(void);
|
||||
uint32_t loggingSize(Logging *logging);
|
||||
uint32_t remainingSize(Logging *logging);
|
||||
|
||||
#define loggingSize(logging) ((int) (logging)->linePointer - (int) ((logging)->buffer))
|
||||
|
||||
int isInitialized(Logging *logging);
|
||||
|
||||
|
@ -74,6 +76,7 @@ char* getCaption(LoggingPoints loggingPoint);
|
|||
void appendPrintf(Logging *logging, const char *fmt, ...);
|
||||
void vappendPrintf(Logging *logging, const char *fmt, va_list arg);
|
||||
void append(Logging *logging, const char *text);
|
||||
void appendFast(Logging *logging, const char *text);
|
||||
/**
|
||||
* this method copies the line into the intermediate buffer for later output by
|
||||
* the main thread
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
#include "io_pins.h"
|
||||
|
||||
// todo: this value is too low for 6 cyl engine, get it back to 60
|
||||
#define OUTPUT_SIGNAL_MAX_SIZE 60
|
||||
#define OUTPUT_SIGNAL_MAX_SIZE 90
|
||||
|
||||
class OutputSignalList {
|
||||
public:
|
||||
|
|
|
@ -21,16 +21,22 @@
|
|||
|
||||
#include "global.h"
|
||||
#include "algo.h"
|
||||
//#include "rpm_calculator.h"
|
||||
#include "advance_map.h"
|
||||
#include "fuel_math.h"
|
||||
#include "wave_chart.h"
|
||||
#include "settings.h"
|
||||
#include "signal_executor.h"
|
||||
#include "speed_density.h"
|
||||
|
||||
WaveChart waveChart;
|
||||
|
||||
void initAlgo(void) {
|
||||
void initDataStructures(engine_configuration_s *engineConfiguration) {
|
||||
prepareFuelMap();
|
||||
prepareTimingMap();
|
||||
initSpeedDensity(engineConfiguration);
|
||||
}
|
||||
|
||||
void initAlgo(engine_configuration_s *engineConfiguration) {
|
||||
#if EFI_PROD_CODE || EFI_SIMULATOR
|
||||
initSettings();
|
||||
initSignalExecutor();
|
||||
|
@ -39,10 +45,4 @@ void initAlgo(void) {
|
|||
#if EFI_WAVE_CHART
|
||||
initWaveChart(&waveChart);
|
||||
#endif
|
||||
|
||||
|
||||
prepareFuelMap();
|
||||
prepareTimingMap();
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -8,12 +8,15 @@
|
|||
#ifndef ALGO_H_
|
||||
#define ALGO_H_
|
||||
|
||||
#include "engine_configuration.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif /* __cplusplus */
|
||||
|
||||
void initAlgo(void);
|
||||
void initDataStructures(engine_configuration_s *engineConfiguration);
|
||||
void initAlgo(engine_configuration_s *engineConfiguration);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -22,6 +22,10 @@
|
|||
typedef struct {
|
||||
ActuatorEventList crankingInjectionEvents;
|
||||
ActuatorEventList injectionEvents;
|
||||
/**
|
||||
* We are alternating two event lists in order to avoid a potential issue around revolution boundary
|
||||
* when an event is scheduled within the next revolution.
|
||||
*/
|
||||
IgnitionEventList ignitionEvents[2];
|
||||
} EventHandlerConfiguration;
|
||||
|
||||
|
|
|
@ -9,5 +9,15 @@
|
|||
* @author Andrey Belomutskiy, (c) 2012-2014
|
||||
*/
|
||||
|
||||
#include "main.h"
|
||||
#include "engine.h"
|
||||
#include "engine_state.h"
|
||||
|
||||
/**
|
||||
* We are executing these heavy (logarithm) methods from outside the trigger callbacks for performance reasons.
|
||||
*/
|
||||
void Engine::updateSlowSensors() {
|
||||
engineState.iat = getIntakeAirTemperature();
|
||||
engineState.clt = getCoolantTemperature();
|
||||
}
|
||||
|
||||
|
|
|
@ -10,12 +10,26 @@
|
|||
#include "main.h"
|
||||
#include "engine_configuration.h"
|
||||
|
||||
class EngineState {
|
||||
public:
|
||||
/**
|
||||
* Access to these two fields is not synchronized in any way - that should work since float read/write are atomic.
|
||||
*/
|
||||
float iat;
|
||||
float clt;
|
||||
};
|
||||
|
||||
class RpmCalculator;
|
||||
|
||||
class Engine {
|
||||
public:
|
||||
RpmCalculator *rpmCalculator;
|
||||
engine_configuration_s *engineConfiguration;
|
||||
|
||||
|
||||
EngineState engineState;
|
||||
|
||||
void updateSlowSensors();
|
||||
};
|
||||
|
||||
#endif /* ENGINE_H_ */
|
||||
|
|
|
@ -26,8 +26,9 @@
|
|||
#include "interpolation.h"
|
||||
#include "trigger_decoder.h"
|
||||
#include "engine_math.h"
|
||||
#include "speed_density.h"
|
||||
|
||||
#if EFI_PROD_CODE
|
||||
#if EFI_TUNER_STUDIO
|
||||
#include "tunerstudio.h"
|
||||
#endif
|
||||
|
||||
|
@ -94,11 +95,18 @@ void setWholeFuelMap(engine_configuration_s *engineConfiguration, float value) {
|
|||
}
|
||||
}
|
||||
|
||||
void setTriggerSynchronizationGap(engine_configuration_s *engineConfiguration, float synchGap) {
|
||||
engineConfiguration->triggerConfig.isSynchronizationNeeded = TRUE;
|
||||
void setToothedWheelConfiguration(engine_configuration_s *engineConfiguration, int total, int skipped) {
|
||||
engineConfiguration->triggerConfig.triggerType = TT_TOOTHED_WHEEL;
|
||||
engineConfiguration->triggerConfig.isSynchronizationNeeded = (skipped != 0);
|
||||
|
||||
engineConfiguration->triggerConfig.syncRatioFrom = synchGap * 0.75;
|
||||
engineConfiguration->triggerConfig.syncRatioTo = synchGap * 1.25;
|
||||
engineConfiguration->triggerConfig.totalToothCount = total;
|
||||
engineConfiguration->triggerConfig.skippedToothCount = skipped;
|
||||
}
|
||||
|
||||
void setTriggerSynchronizationGap(trigger_config_s *triggerConfig, float synchGap) {
|
||||
triggerConfig->isSynchronizationNeeded = TRUE;
|
||||
triggerConfig->syncRatioFrom = synchGap * 0.75;
|
||||
triggerConfig->syncRatioTo = synchGap * 1.25;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -110,6 +118,8 @@ void setDefaultConfiguration(engine_configuration_s *engineConfiguration, board_
|
|||
memset(engineConfiguration, 0, sizeof(engine_configuration_s));
|
||||
memset(boardConfiguration, 0, sizeof(board_configuration_s));
|
||||
|
||||
setDetaultVETable(engineConfiguration);
|
||||
|
||||
engineConfiguration->injectorLag = 0.0;
|
||||
|
||||
for (int i = 0; i < IAT_CURVE_SIZE; i++) {
|
||||
|
@ -147,8 +157,8 @@ void setDefaultConfiguration(engine_configuration_s *engineConfiguration, board_
|
|||
setTimingLoadBin(engineConfiguration, 1.2, 4.4);
|
||||
setTimingRpmBin(engineConfiguration, 800, 7000);
|
||||
|
||||
setTableBin(engineConfiguration->map.samplingAngleBins, MAP_ANGLE_SIZE, 800, 7000);
|
||||
setTableBin(engineConfiguration->map.samplingWindowBins, MAP_ANGLE_SIZE, 800, 7000);
|
||||
setTableBin2(engineConfiguration->map.samplingAngleBins, MAP_ANGLE_SIZE, 800, 7000, 1);
|
||||
setTableBin2(engineConfiguration->map.samplingWindowBins, MAP_ANGLE_SIZE, 800, 7000, 1);
|
||||
|
||||
// set_whole_timing_map 3
|
||||
setWholeFuelMap(engineConfiguration, 3);
|
||||
|
@ -193,7 +203,7 @@ void setDefaultConfiguration(engine_configuration_s *engineConfiguration, board_
|
|||
engineConfiguration->overrideCrankingIgnition = TRUE;
|
||||
engineConfiguration->analogChartFrequency = 20;
|
||||
|
||||
engineConfiguration->engineLoadMode = LM_MAF;
|
||||
engineConfiguration->algorithm = LM_MAF;
|
||||
|
||||
engineConfiguration->vbattDividerCoeff = ((float) (15 + 65)) / 15;
|
||||
|
||||
|
@ -206,7 +216,7 @@ void setDefaultConfiguration(engine_configuration_s *engineConfiguration, board_
|
|||
engineConfiguration->can_nbc_type = CAN_BUS_NBC_BMW;
|
||||
engineConfiguration->can_sleep_period = 50;
|
||||
engineConfiguration->canReadEnabled = TRUE;
|
||||
engineConfiguration->canWriteEnabled = FALSE;
|
||||
engineConfiguration->canWriteEnabled = false;
|
||||
|
||||
setOperationMode(engineConfiguration, FOUR_STROKE_CAM_SENSOR);
|
||||
engineConfiguration->cylindersCount = 4;
|
||||
|
@ -221,7 +231,7 @@ void setDefaultConfiguration(engine_configuration_s *engineConfiguration, board_
|
|||
engineConfiguration->logFormat = LF_NATIVE;
|
||||
|
||||
engineConfiguration->triggerConfig.triggerType = TT_TOOTHED_WHEEL;
|
||||
setTriggerSynchronizationGap(engineConfiguration, 2);
|
||||
setTriggerSynchronizationGap(&engineConfiguration->triggerConfig, 2);
|
||||
engineConfiguration->triggerConfig.useRiseEdge = TRUE;
|
||||
|
||||
engineConfiguration->HD44780width = 16;
|
||||
|
@ -260,12 +270,26 @@ void setDefaultConfiguration(engine_configuration_s *engineConfiguration, board_
|
|||
boardConfiguration->injectionPins[3] = GPIOE_5;
|
||||
boardConfiguration->injectionPins[4] = GPIOE_6;
|
||||
boardConfiguration->injectionPins[5] = GPIOC_12;
|
||||
boardConfiguration->injectionPins[6] = GPIO_NONE;
|
||||
boardConfiguration->injectionPins[7] = GPIO_NONE;
|
||||
boardConfiguration->injectionPins[8] = GPIO_NONE;
|
||||
boardConfiguration->injectionPins[9] = GPIO_NONE;
|
||||
boardConfiguration->injectionPins[10] = GPIO_NONE;
|
||||
boardConfiguration->injectionPins[11] = GPIO_NONE;
|
||||
boardConfiguration->injectionPinMode = OM_DEFAULT;
|
||||
|
||||
boardConfiguration->ignitionPins[0] = GPIOC_7;
|
||||
boardConfiguration->ignitionPins[1] = GPIOE_4; // todo: update this value
|
||||
boardConfiguration->ignitionPins[2] = GPIOE_0; // todo: update this value
|
||||
boardConfiguration->ignitionPins[3] = GPIOE_1; // todo: update this value
|
||||
boardConfiguration->ignitionPins[4] = GPIO_NONE;
|
||||
boardConfiguration->ignitionPins[5] = GPIO_NONE;
|
||||
boardConfiguration->ignitionPins[6] = GPIO_NONE;
|
||||
boardConfiguration->ignitionPins[7] = GPIO_NONE;
|
||||
boardConfiguration->ignitionPins[8] = GPIO_NONE;
|
||||
boardConfiguration->ignitionPins[9] = GPIO_NONE;
|
||||
boardConfiguration->ignitionPins[10] = GPIO_NONE;
|
||||
boardConfiguration->ignitionPins[11] = GPIO_NONE;
|
||||
boardConfiguration->ignitionPinMode = OM_DEFAULT;
|
||||
|
||||
boardConfiguration->malfunctionIndicatorPin = GPIOC_9;
|
||||
|
@ -314,6 +338,12 @@ void setDefaultConfiguration(engine_configuration_s *engineConfiguration, board_
|
|||
boardConfiguration->generalPeriodicThreadPeriod = 200;
|
||||
|
||||
boardConfiguration->tunerStudioSerialSpeed = 38400;
|
||||
|
||||
boardConfiguration->boardTestModeJumperPin = GPIOB_0;
|
||||
|
||||
boardConfiguration->canDeviceMode = CD_USE_CAN2;
|
||||
boardConfiguration->canTxPin = GPIOB_0;
|
||||
boardConfiguration->canRxPin = GPIOB_12;
|
||||
}
|
||||
|
||||
void setDefaultNonPersistentConfiguration(engine_configuration2_s *engineConfiguration2) {
|
||||
|
@ -438,8 +468,8 @@ void setOperationMode(engine_configuration_s *engineConfiguration, operation_mod
|
|||
}
|
||||
}
|
||||
|
||||
operation_mode_e getOperationMode( engine_configuration_s const *engineConfiguration) {
|
||||
if(engineConfiguration->rpmMultiplier == 1)
|
||||
operation_mode_e getOperationMode(engine_configuration_s const *engineConfiguration) {
|
||||
if (engineConfiguration->rpmMultiplier == 1)
|
||||
return FOUR_STROKE_CRANK_SENSOR;
|
||||
return FOUR_STROKE_CAM_SENSOR;
|
||||
|
||||
|
|
|
@ -68,6 +68,14 @@ typedef enum {
|
|||
Internal_ForceMyEnumIntSize_timing_mode = ENUM_SIZE_HACK,
|
||||
} timing_mode_e;
|
||||
|
||||
typedef enum {
|
||||
CD_OFF = 0,
|
||||
CD_USE_CAN1 = 1,
|
||||
CD_USE_CAN2 = 2,
|
||||
|
||||
Internal_ForceMyEnumIntSize_can_device_mode = ENUM_SIZE_HACK,
|
||||
} can_device_mode_e;
|
||||
|
||||
typedef struct {
|
||||
int afrAdcChannel;
|
||||
float v1;
|
||||
|
@ -97,202 +105,6 @@ typedef struct {
|
|||
} trigger_config_s;
|
||||
|
||||
|
||||
/**
|
||||
* @brief Engine configuration.
|
||||
* Values in this data structure are adjustable and persisted in on-board flash RAM.
|
||||
*
|
||||
* The offsets are tracked using
|
||||
* https://docs.google.com/spreadsheet/ccc?key=0AiAmAn6tn3L_dGJXZDZOcVVhaG9SaHZKU1dyMjhEV0E
|
||||
*
|
||||
* todo: currently the fields here are simply in the order in which they were implemented
|
||||
* todo: re-arrange this structure one we have a stable code version
|
||||
*/
|
||||
typedef struct {
|
||||
float injectorLag; // size 4, offset 0
|
||||
/**
|
||||
* cc/min, cubic centimeter per minute
|
||||
*
|
||||
* By the way, g/s = 0.125997881 * (lb/hr)
|
||||
* g/s = 0.125997881 * (cc/min)/10.5
|
||||
* g/s = 0.0119997981 * cc/min
|
||||
*
|
||||
*/
|
||||
float injectorFlow; // size 4, offset 4
|
||||
float battInjectorLagCorrBins[VBAT_INJECTOR_CURVE_SIZE]; // size 32, offset 8
|
||||
float battInjectorLagCorr[VBAT_INJECTOR_CURVE_SIZE]; // size 32, offset 40
|
||||
|
||||
float cltFuelCorrBins[CLT_CURVE_SIZE]; // size 64, offset 72
|
||||
float cltFuelCorr[CLT_CURVE_SIZE]; // size 64, offset 136
|
||||
|
||||
float iatFuelCorrBins[IAT_CURVE_SIZE]; // size 64, offset 200
|
||||
float iatFuelCorr[IAT_CURVE_SIZE]; // size 64, offset 264
|
||||
|
||||
short int rpmHardLimit; // size 2, offset 328
|
||||
|
||||
// todo: extract these two fields into a structure
|
||||
// todo: we need two sets of TPS parameters - modern ETBs have to sensors
|
||||
short int tpsMin; // size 2, offset 330
|
||||
// tpsMax value as 10 bit ADC value. Not Voltage!
|
||||
short int tpsMax; // size 2, offset 332
|
||||
short int analogChartMode;
|
||||
|
||||
cranking_parameters_s crankingSettings;
|
||||
|
||||
MAP_sensor_config_s map;
|
||||
|
||||
// todo: merge with channel settings, use full-scale Thermistor here!
|
||||
ThermistorConf cltThermistorConf; // size 40 (10*4), offset 336
|
||||
ThermistorConf iatThermistorConf; // size 40, offset 376
|
||||
|
||||
float sparkDwellBins[DWELL_COUNT]; // offset 580
|
||||
float sparkDwell[DWELL_COUNT];
|
||||
|
||||
float ignitionLoadBins[IGN_LOAD_COUNT];
|
||||
float ignitionRpmBins[IGN_RPM_COUNT];
|
||||
|
||||
/**
|
||||
* this value could be used to offset the whole ignition timing table by a constant
|
||||
*/
|
||||
float ignitionOffset;
|
||||
|
||||
/**
|
||||
* While cranking (which causes battery voltage to drop) we can calculate dwell time in shaft
|
||||
* degrees, not in absolute time as in running mode.
|
||||
*/
|
||||
float crankingChargeAngle;
|
||||
|
||||
timing_mode_e timingMode;
|
||||
/**
|
||||
* This value is used in 'fixed timing' mode, i.e. constant timing
|
||||
* This mode is useful for instance while adjusting distributor location
|
||||
*/
|
||||
float fixedModeTiming;
|
||||
|
||||
// WARNING: by default, our small enums are ONE BYTE. but if the are surrounded by non-enums - alignments do the trick
|
||||
engine_type_e engineType;
|
||||
|
||||
float fuelLoadBins[FUEL_LOAD_COUNT]; //
|
||||
// RPM is float and not integer in order to use unified methods for interpolation
|
||||
float fuelRpmBins[FUEL_RPM_COUNT]; //
|
||||
|
||||
/**
|
||||
* Engine displacement, in liters
|
||||
* see also cylindersCount
|
||||
*/
|
||||
float displacement;
|
||||
int unused[2];
|
||||
|
||||
injection_mode_e crankingInjectionMode;
|
||||
injection_mode_e injectionMode;
|
||||
|
||||
|
||||
/**
|
||||
* Inside rusEfi all the angles are handled in relation to the trigger synchronization event
|
||||
* which depends on the trigger shape and has nothing to do wit Top Dead Center (TDC)
|
||||
*
|
||||
* For engine configuration humans need angles from TDC.
|
||||
*
|
||||
* This field is the angle between Top Dead Center (TDC) and the first trigger event.
|
||||
* Knowing this angle allows us to control timing and other angles in reference to TDC.
|
||||
*/
|
||||
float globalTriggerAngleOffset;
|
||||
/**
|
||||
* We have 3.3V ADC and most of the analog input signals are 5V, this forces us to use
|
||||
* voltage dividers on the input circuits. This parameter holds the coefficient of these dividers.
|
||||
* see also vbattDividerCoeff
|
||||
*/
|
||||
float analogInputDividerCoefficient;
|
||||
|
||||
/**
|
||||
* This setting controls which algorithm is used for ENGINE LOAD
|
||||
*/
|
||||
engine_load_mode_e engineLoadMode;
|
||||
|
||||
/**
|
||||
* see
|
||||
*/
|
||||
float vbattDividerCoeff;
|
||||
/**
|
||||
* Cooling fan turn-on temperature threshold, in Celsuis
|
||||
*/
|
||||
float fanOnTemperature;
|
||||
/**
|
||||
* Cooling fan turn-off temperature threshold, in Celsuis
|
||||
*/
|
||||
float fanOffTemperature;
|
||||
|
||||
int canReadEnabled;
|
||||
int canWriteEnabled;
|
||||
can_nbc_e can_nbc_type;
|
||||
int can_sleep_period;
|
||||
|
||||
int cylindersCount;
|
||||
|
||||
ignition_mode_e ignitionMode;
|
||||
firing_order_e firingOrder;
|
||||
|
||||
/**
|
||||
* This magic constant is about four-stroke engines with camshaft position sensors.
|
||||
* On any four stroke engine, each revolution of the camshaft is two revolutions
|
||||
* of the crankshaft. If camshaft position is our primary sensor, we use this multiplier
|
||||
* to convert from camshaft angles to crankshaft angles. All angels across the system
|
||||
* should be crankshaft angles.
|
||||
*/
|
||||
|
||||
float rpmMultiplier;
|
||||
|
||||
display_mode_e displayMode;
|
||||
|
||||
log_format_e logFormat;
|
||||
|
||||
int firmwareVersion;
|
||||
int HD44780width;
|
||||
int HD44780height;
|
||||
|
||||
int tpsAdcChannel;
|
||||
int overrideCrankingIgnition;
|
||||
int analogChartFrequency;
|
||||
int unused5[10];
|
||||
|
||||
trigger_config_s triggerConfig;
|
||||
|
||||
int needSecondTriggerInput;
|
||||
int vBattAdcChannel;
|
||||
|
||||
float globalFuelCorrection;
|
||||
|
||||
// todo: merge with channel settings, use full-scale Thermistor!
|
||||
int cltAdcChannel;
|
||||
int iatAdcChannel;
|
||||
int mafAdcChannel;
|
||||
|
||||
afr_sensor_s afrSensor;
|
||||
|
||||
float injectionOffset;
|
||||
|
||||
float crankingTimingAngle;
|
||||
|
||||
float diffLoadEnrichmentCoef;
|
||||
|
||||
air_pressure_sensor_config_s baroSensor;
|
||||
|
||||
float veLoadBins[VE_LOAD_COUNT];
|
||||
float veRpmBins[VE_RPM_COUNT];
|
||||
float afrLoadBins[AFR_LOAD_COUNT];
|
||||
float afrRpmBins[AFR_RPM_COUNT];
|
||||
|
||||
// the large tables are always in the end - that's related to TunerStudio paging implementation
|
||||
float fuelTable[FUEL_LOAD_COUNT][FUEL_RPM_COUNT]; // size 1024
|
||||
float ignitionTable[IGN_LOAD_COUNT][IGN_RPM_COUNT]; // size 1024
|
||||
|
||||
float veTable[VE_LOAD_COUNT][VE_RPM_COUNT]; // size 1024
|
||||
float afrTable[AFR_LOAD_COUNT][AFR_RPM_COUNT]; // size 1024
|
||||
|
||||
} engine_configuration_s;
|
||||
|
||||
void setOperationMode(engine_configuration_s *engineConfiguration, operation_mode_e mode);
|
||||
operation_mode_e getOperationMode(engine_configuration_s const *engineConfiguration);
|
||||
|
||||
#define HW_MAX_ADC_INDEX 16
|
||||
|
||||
typedef struct {
|
||||
|
@ -355,11 +167,216 @@ typedef struct {
|
|||
|
||||
int tunerStudioSerialSpeed;
|
||||
|
||||
brain_pin_e boardTestModeJumperPin;
|
||||
|
||||
can_device_mode_e canDeviceMode;
|
||||
brain_pin_e canTxPin;
|
||||
brain_pin_e canRxPin;
|
||||
|
||||
} board_configuration_s;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief Engine configuration.
|
||||
* Values in this data structure are adjustable and persisted in on-board flash RAM.
|
||||
*
|
||||
* The offsets are tracked using
|
||||
* https://docs.google.com/spreadsheet/ccc?key=0AiAmAn6tn3L_dGJXZDZOcVVhaG9SaHZKU1dyMjhEV0E
|
||||
*
|
||||
* todo: currently the fields here are simply in the order in which they were implemented
|
||||
* todo: re-arrange this structure one we have a stable code version
|
||||
*/
|
||||
typedef struct {
|
||||
float injectorLag; // size 4, offset 0
|
||||
/**
|
||||
* cc/min, cubic centimeter per minute
|
||||
*
|
||||
* By the way, g/s = 0.125997881 * (lb/hr)
|
||||
* g/s = 0.125997881 * (cc/min)/10.5
|
||||
* g/s = 0.0119997981 * cc/min
|
||||
*
|
||||
*/
|
||||
float injectorFlow; // size 4, offset 4
|
||||
float battInjectorLagCorrBins[VBAT_INJECTOR_CURVE_SIZE]; // size 32, offset 8
|
||||
float battInjectorLagCorr[VBAT_INJECTOR_CURVE_SIZE]; // size 32, offset 40
|
||||
|
||||
float cltFuelCorrBins[CLT_CURVE_SIZE]; // size 64, offset 72
|
||||
float cltFuelCorr[CLT_CURVE_SIZE]; // size 64, offset 136
|
||||
|
||||
float iatFuelCorrBins[IAT_CURVE_SIZE]; // size 64, offset 200
|
||||
float iatFuelCorr[IAT_CURVE_SIZE]; // size 64, offset 264
|
||||
|
||||
short int unused2; // size 2, offset 328
|
||||
|
||||
// todo: extract these two fields into a structure
|
||||
// todo: we need two sets of TPS parameters - modern ETBs have to sensors
|
||||
short int tpsMin; // size 2, offset 330
|
||||
// tpsMax value as 10 bit ADC value. Not Voltage!
|
||||
short int tpsMax; // size 2, offset 332
|
||||
short int analogChartMode;
|
||||
|
||||
cranking_parameters_s crankingSettings;
|
||||
|
||||
MAP_sensor_config_s map;
|
||||
|
||||
// todo: merge with channel settings, use full-scale Thermistor here!
|
||||
ThermistorConf cltThermistorConf; // size 40 (10*4), offset 336
|
||||
ThermistorConf iatThermistorConf; // size 40, offset 376
|
||||
|
||||
float sparkDwellBins[DWELL_COUNT]; // offset 580
|
||||
float sparkDwell[DWELL_COUNT];
|
||||
|
||||
float ignitionLoadBins[IGN_LOAD_COUNT];
|
||||
float ignitionRpmBins[IGN_RPM_COUNT];
|
||||
|
||||
/**
|
||||
* this value could be used to offset the whole ignition timing table by a constant
|
||||
*/
|
||||
float ignitionOffset;
|
||||
|
||||
/**
|
||||
* While cranking (which causes battery voltage to drop) we can calculate dwell time in shaft
|
||||
* degrees, not in absolute time as in running mode.
|
||||
*/
|
||||
float crankingChargeAngle;
|
||||
|
||||
timing_mode_e timingMode;
|
||||
/**
|
||||
* This value is used in 'fixed timing' mode, i.e. constant timing
|
||||
* This mode is useful for instance while adjusting distributor location
|
||||
*/
|
||||
float fixedModeTiming;
|
||||
|
||||
// WARNING: by default, our small enums are ONE BYTE. but if the are surrounded by non-enums - alignments do the trick
|
||||
engine_type_e engineType;
|
||||
|
||||
float fuelLoadBins[FUEL_LOAD_COUNT]; //
|
||||
// RPM is float and not integer in order to use unified methods for interpolation
|
||||
float fuelRpmBins[FUEL_RPM_COUNT]; //
|
||||
|
||||
/**
|
||||
* Engine displacement, in liters
|
||||
* see also cylindersCount
|
||||
*/
|
||||
float displacement;
|
||||
int rpmHardLimit;
|
||||
|
||||
injection_mode_e crankingInjectionMode;
|
||||
injection_mode_e injectionMode;
|
||||
|
||||
|
||||
/**
|
||||
* Inside rusEfi all the angles are handled in relation to the trigger synchronization event
|
||||
* which depends on the trigger shape and has nothing to do wit Top Dead Center (TDC)
|
||||
*
|
||||
* For engine configuration humans need angles from TDC.
|
||||
*
|
||||
* This field is the angle between Top Dead Center (TDC) and the first trigger event.
|
||||
* Knowing this angle allows us to control timing and other angles in reference to TDC.
|
||||
*/
|
||||
float globalTriggerAngleOffset;
|
||||
/**
|
||||
* We have 3.3V ADC and most of the analog input signals are 5V, this forces us to use
|
||||
* voltage dividers on the input circuits. This parameter holds the coefficient of these dividers.
|
||||
* see also vbattDividerCoeff
|
||||
*/
|
||||
float analogInputDividerCoefficient;
|
||||
|
||||
/**
|
||||
* This setting controls which algorithm is used for ENGINE LOAD
|
||||
*/
|
||||
engine_load_mode_e algorithm;
|
||||
|
||||
/**
|
||||
* see
|
||||
*/
|
||||
float vbattDividerCoeff;
|
||||
/**
|
||||
* Cooling fan turn-on temperature threshold, in Celsuis
|
||||
*/
|
||||
float fanOnTemperature;
|
||||
/**
|
||||
* Cooling fan turn-off temperature threshold, in Celsuis
|
||||
*/
|
||||
float fanOffTemperature;
|
||||
|
||||
int canReadEnabled;
|
||||
int canWriteEnabled;
|
||||
can_nbc_e can_nbc_type;
|
||||
int can_sleep_period;
|
||||
|
||||
int cylindersCount;
|
||||
|
||||
ignition_mode_e ignitionMode;
|
||||
firing_order_e firingOrder;
|
||||
|
||||
/**
|
||||
* This magic constant is about four-stroke engines with camshaft position sensors.
|
||||
* On any four stroke engine, each revolution of the camshaft is two revolutions
|
||||
* of the crankshaft. If camshaft position is our primary sensor, we use this multiplier
|
||||
* to convert from camshaft angles to crankshaft angles. All angels across the system
|
||||
* should be crankshaft angles.
|
||||
*/
|
||||
|
||||
float rpmMultiplier;
|
||||
|
||||
display_mode_e displayMode;
|
||||
|
||||
log_format_e logFormat;
|
||||
|
||||
int firmwareVersion;
|
||||
int HD44780width;
|
||||
int HD44780height;
|
||||
|
||||
int tpsAdcChannel;
|
||||
int overrideCrankingIgnition;
|
||||
int analogChartFrequency;
|
||||
|
||||
trigger_config_s triggerConfig;
|
||||
|
||||
int needSecondTriggerInput;
|
||||
int vBattAdcChannel;
|
||||
|
||||
float globalFuelCorrection;
|
||||
|
||||
// todo: merge with channel settings, use full-scale Thermistor!
|
||||
int cltAdcChannel;
|
||||
int iatAdcChannel;
|
||||
int mafAdcChannel;
|
||||
|
||||
afr_sensor_s afrSensor;
|
||||
|
||||
float injectionOffset;
|
||||
|
||||
float crankingTimingAngle;
|
||||
|
||||
float diffLoadEnrichmentCoef;
|
||||
|
||||
air_pressure_sensor_config_s baroSensor;
|
||||
|
||||
float veLoadBins[VE_LOAD_COUNT];
|
||||
float veRpmBins[VE_RPM_COUNT];
|
||||
float afrLoadBins[AFR_LOAD_COUNT];
|
||||
float afrRpmBins[AFR_RPM_COUNT];
|
||||
|
||||
// the large tables are always in the end - that's related to TunerStudio paging implementation
|
||||
float fuelTable[FUEL_LOAD_COUNT][FUEL_RPM_COUNT]; // size 1024
|
||||
float ignitionTable[IGN_LOAD_COUNT][IGN_RPM_COUNT]; // size 1024
|
||||
|
||||
float veTable[VE_LOAD_COUNT][VE_RPM_COUNT]; // size 1024
|
||||
float afrTable[AFR_LOAD_COUNT][AFR_RPM_COUNT]; // size 1024
|
||||
|
||||
|
||||
board_configuration_s bc;
|
||||
|
||||
} engine_configuration_s;
|
||||
|
||||
void setOperationMode(engine_configuration_s *engineConfiguration, operation_mode_e mode);
|
||||
operation_mode_e getOperationMode(engine_configuration_s const *engineConfiguration);
|
||||
|
||||
typedef struct {
|
||||
engine_configuration_s engineConfiguration;
|
||||
board_configuration_s boardConfiguration;
|
||||
} persistent_config_s;
|
||||
|
||||
typedef struct {
|
||||
|
@ -379,7 +396,8 @@ void setWholeFuelMap(engine_configuration_s *engineConfiguration, float value);
|
|||
void setConstantDwell(engine_configuration_s *engineConfiguration, float dwellMs);
|
||||
void printFloatArray(const char *prefix, float array[], int size);
|
||||
|
||||
void setTriggerSynchronizationGap(engine_configuration_s *engineConfiguration, float synchGap);
|
||||
void setTriggerSynchronizationGap(trigger_config_s *triggerConfig, float synchGap);
|
||||
void setToothedWheelConfiguration(engine_configuration_s *engineConfiguration, int total, int skipped);
|
||||
|
||||
void incrementGlobalConfigurationVersion(void);
|
||||
int getGlobalConfigurationVersion(void);
|
||||
|
|
|
@ -55,10 +55,8 @@ int getRusEfiVersion(void);
|
|||
|
||||
#define efiAssertVoid(condition, message) { if (!(condition)) { firmwareError(message); return; } }
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
|
||||
#endif /* ERROR_HANDLING_H_ */
|
||||
|
|
|
@ -24,11 +24,11 @@
|
|||
#include "main.h"
|
||||
#include "engine_math.h"
|
||||
|
||||
void registerActuatorEvent(ActuatorEventList *list, int eventIndex, OutputSignal *actuator, float angleOffset) {
|
||||
ActuatorEvent *e = list->getNextActuatorEvent();
|
||||
if (e == NULL)
|
||||
return; // error already reported
|
||||
e->position.eventIndex = eventIndex;
|
||||
e->actuator = actuator;
|
||||
e->position.angleOffset = angleOffset;
|
||||
}
|
||||
//void registerActuatorEventWhat(ActuatorEventList *list, int eventIndex, OutputSignal *actuator, float angleOffset) {
|
||||
// ActuatorEvent *e = list->getNextActuatorEvent();
|
||||
// if (e == NULL)
|
||||
// return; // error already reported
|
||||
// e->position.eventIndex = eventIndex;
|
||||
// e->actuator = actuator;
|
||||
// e->position.angleOffset = angleOffset;
|
||||
//}
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
#include "global.h"
|
||||
#include "signal_executor.h"
|
||||
|
||||
#define MAX_EVENT_COUNT 40
|
||||
#define MAX_EVENT_COUNT 80
|
||||
|
||||
/**
|
||||
* This structure defines an angle position within the trigger
|
||||
|
@ -31,13 +31,15 @@ typedef struct {
|
|||
typedef struct {
|
||||
event_trigger_position_s position;
|
||||
OutputSignal *actuator;
|
||||
scheduling_s signalTimer;
|
||||
} ActuatorEvent;
|
||||
|
||||
typedef struct IgnitionEvent_struct IgnitionEvent;
|
||||
|
||||
struct IgnitionEvent_struct {
|
||||
ActuatorEvent actuator;
|
||||
io_pin_e io_pin;
|
||||
scheduling_s signalTimerUp;
|
||||
scheduling_s signalTimerDown;
|
||||
event_trigger_position_s dwellPosition;
|
||||
float advance;
|
||||
event_trigger_position_s sparkPosition;
|
||||
IgnitionEvent *next;
|
||||
|
@ -68,14 +70,14 @@ typedef ArrayList<ActuatorEvent, MAX_EVENT_COUNT> ActuatorEventList;
|
|||
|
||||
typedef ArrayList<IgnitionEvent, MAX_EVENT_COUNT> IgnitionEventList;
|
||||
|
||||
/**
|
||||
* this is an intermediate implementation of flexible event handling.
|
||||
*
|
||||
* In the future implementation we will drop the 'eventIndex' parameter and everything will be
|
||||
* angle-driven. But that's just a plan for next iteration.
|
||||
*
|
||||
* @param actuator injector or coil OutputSignal
|
||||
*/
|
||||
void registerActuatorEvent(ActuatorEventList *list, int eventIndex, OutputSignal *actuator, float angleOffset);
|
||||
///**
|
||||
// * this is an intermediate implementation of flexible event handling.
|
||||
// *
|
||||
// * In the future implementation we will drop the 'eventIndex' parameter and everything will be
|
||||
// * angle-driven. But that's just a plan for next iteration.
|
||||
// *
|
||||
// * @param actuator injector or coil OutputSignal
|
||||
// */
|
||||
//void registerActuatorEvent(ActuatorEventList *list, int eventIndex, OutputSignal *actuator, float angleOffset);
|
||||
|
||||
#endif /* EVENT_REGISTRY_H_ */
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* @file fuel_math.c
|
||||
* @file fuel_math.cpp
|
||||
* @brief Fuel amount calculation logic
|
||||
*
|
||||
* While engine running, fuel amount is an interpolated value from the fuel map by getRpm() and getEngineLoad()
|
||||
|
|
|
@ -111,7 +111,7 @@ extern "C"
|
|||
|
||||
void initPrimaryPins(void);
|
||||
void initOutputPins(void);
|
||||
char *getPinName(io_pin_e io_pin);
|
||||
const char *getPinName(io_pin_e io_pin);
|
||||
void turnOutputPinOn(io_pin_e pin);
|
||||
void turnOutputPinOff(io_pin_e pin);
|
||||
void setOutputPinValue(io_pin_e pin, int logicValue);
|
||||
|
|
|
@ -80,6 +80,7 @@ typedef enum {
|
|||
TT_GM_7X = 5,
|
||||
TT_MINI_COOPER_R50 = 6,
|
||||
TT_FORD_ESCORT_GT = 7,
|
||||
TT_TT_TOOTHED_WHEEL_60_2 = 8,
|
||||
|
||||
Internal_ForceMyEnumIntSize_trigger_type = ENUM_SIZE_HACK,
|
||||
} trigger_type_e;
|
||||
|
@ -170,19 +171,20 @@ typedef enum {
|
|||
} pin_input_mode_e;
|
||||
|
||||
typedef enum {
|
||||
FO_ONE_CYLINDER = 1,
|
||||
FO_1_THEN_3_THEN_4_THEN2 = 2,
|
||||
FO_1_THEN_2_THEN_4_THEN3 = 3,
|
||||
FO_1_THEN_3_THEN_2_THEN4 = 4,
|
||||
FO_1_THEN_5_THEN_3_THEN_6_THEN_2_THEN_4 = 5,
|
||||
FO_1_8_4_3_6_5_7_2 = 6,
|
||||
FO_ONE_CYLINDER = 0,
|
||||
FO_1_THEN_3_THEN_4_THEN2 = 1,
|
||||
FO_1_THEN_2_THEN_4_THEN3 = 2,
|
||||
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,
|
||||
} firing_order_e;
|
||||
|
||||
// todo: better enum name
|
||||
typedef enum {
|
||||
FOUR_STROKE_CRANK_SENSOR = 0,
|
||||
FOUR_STROKE_CAM_SENSOR = 1,
|
||||
OM_NONE = 0,
|
||||
FOUR_STROKE_CRANK_SENSOR = 1,
|
||||
FOUR_STROKE_CAM_SENSOR = 2,
|
||||
|
||||
Internal_ForceMyEnumIntSize_operation_mode_e = ENUM_SIZE_HACK,
|
||||
} operation_mode_e;
|
||||
|
@ -191,7 +193,13 @@ typedef enum {
|
|||
* @brief Ignition Mode
|
||||
*/
|
||||
typedef enum {
|
||||
/**
|
||||
* in this mode only SPARKOUT_1_OUTPUT is used
|
||||
*/
|
||||
IM_ONE_COIL = 0,
|
||||
/**
|
||||
* in this mode we use as many coils as we have cylinders
|
||||
*/
|
||||
IM_INDIVIDUAL_COILS = 1,
|
||||
IM_WASTED_SPARK = 2,
|
||||
|
||||
|
|
|
@ -51,19 +51,12 @@ void initSignalExecutor(void) {
|
|||
|
||||
void initOutputSignal(OutputSignal *signal, io_pin_e ioPin) {
|
||||
signal->io_pin = ioPin;
|
||||
signal->name = getPinName(ioPin);
|
||||
initOutputSignalBase(signal);
|
||||
}
|
||||
|
||||
void initOutputSignalBase(OutputSignal *signal) {
|
||||
signal->initialized = TRUE;
|
||||
}
|
||||
|
||||
void turnPinHigh(OutputSignal *signal) {
|
||||
void turnPinHigh(io_pin_e pin) {
|
||||
#if EFI_DEFAILED_LOGGING
|
||||
// signal->hi_time = hTimeNow();
|
||||
#endif /* EFI_DEFAILED_LOGGING */
|
||||
io_pin_e pin = signal->io_pin;
|
||||
// turn the output level ACTIVE
|
||||
// todo: this XOR should go inside the setOutputPinValue method
|
||||
setOutputPinValue(pin, TRUE);
|
||||
|
@ -79,14 +72,14 @@ void turnPinHigh(OutputSignal *signal) {
|
|||
#endif
|
||||
|
||||
#if EFI_WAVE_CHART
|
||||
addWaveChartEvent(signal->name, "up", "");
|
||||
addWaveChartEvent(getPinName(pin), WC_UP, "");
|
||||
#endif /* EFI_WAVE_ANALYZER */
|
||||
}
|
||||
|
||||
void turnPinLow(OutputSignal *signal) {
|
||||
void turnPinLow(io_pin_e pin) {
|
||||
// turn off the output
|
||||
// todo: this XOR should go inside the setOutputPinValue method
|
||||
setOutputPinValue(signal->io_pin, FALSE);
|
||||
setOutputPinValue(pin, false);
|
||||
|
||||
#if EFI_DEFAILED_LOGGING
|
||||
systime_t after = hTimeNow();
|
||||
|
@ -95,7 +88,7 @@ void turnPinLow(OutputSignal *signal) {
|
|||
#endif /* EFI_DEFAILED_LOGGING */
|
||||
|
||||
#if EFI_WAVE_CHART
|
||||
addWaveChartEvent(signal->name, "down", "");
|
||||
addWaveChartEvent(getPinName(pin), WC_DOWN, "");
|
||||
#endif /* EFI_WAVE_ANALYZER */
|
||||
}
|
||||
|
||||
|
@ -118,50 +111,67 @@ void scheduleOutput(OutputSignal *signal, float delayMs, float durationMs) {
|
|||
return;
|
||||
}
|
||||
|
||||
scheduleOutputBase(signal, delayMs, durationMs);
|
||||
|
||||
int index = getRevolutionCounter() % 2;
|
||||
scheduling_s * sUp = &signal->signalTimerUp[index];
|
||||
scheduling_s * sDown = &signal->signalTimerDown[index];
|
||||
|
||||
scheduleTask(sUp, (int)MS2US(delayMs), (schfunc_t) &turnPinHigh, (void *) signal);
|
||||
scheduleTask(sDown, (int)MS2US(delayMs + durationMs), (schfunc_t) &turnPinLow, (void*) signal);
|
||||
|
||||
// signal->last_scheduling_time = now;
|
||||
scheduleTask(sUp, (int)MS2US(delayMs), (schfunc_t) &turnPinHigh, (void *) signal->io_pin);
|
||||
scheduleTask(sDown, (int)MS2US(delayMs + durationMs), (schfunc_t) &turnPinLow, (void*) signal->io_pin);
|
||||
}
|
||||
|
||||
void scheduleOutputBase(OutputSignal *signal, float delayMs, float durationMs) {
|
||||
/**
|
||||
* it's better to check for the exact 'TRUE' value since otherwise
|
||||
* we would accept any memory garbage
|
||||
*/
|
||||
efiAssertVoid(signal->initialized == TRUE, "Signal not initialized");
|
||||
// signal->offset = offset;
|
||||
// signal->duration = duration;
|
||||
}
|
||||
|
||||
char *getPinName(io_pin_e io_pin) {
|
||||
const char *getPinName(io_pin_e io_pin) {
|
||||
switch (io_pin) {
|
||||
// todo: refactor this hell - introduce arrays & checks?
|
||||
case SPARKOUT_1_OUTPUT:
|
||||
return "Spark 1";
|
||||
return "spa1";
|
||||
case SPARKOUT_2_OUTPUT:
|
||||
return "Spark 2";
|
||||
return "spa2";
|
||||
case SPARKOUT_3_OUTPUT:
|
||||
return "Spark 3";
|
||||
return "spa3";
|
||||
case SPARKOUT_4_OUTPUT:
|
||||
return "Spark 4";
|
||||
return "spa4";
|
||||
case SPARKOUT_5_OUTPUT:
|
||||
return "spa5";
|
||||
case SPARKOUT_6_OUTPUT:
|
||||
return "spa6";
|
||||
case SPARKOUT_7_OUTPUT:
|
||||
return "spa7";
|
||||
case SPARKOUT_8_OUTPUT:
|
||||
return "spa8";
|
||||
case SPARKOUT_9_OUTPUT:
|
||||
return "spa9";
|
||||
case SPARKOUT_10_OUTPUT:
|
||||
return "spa10";
|
||||
case SPARKOUT_11_OUTPUT:
|
||||
return "spa11";
|
||||
case SPARKOUT_12_OUTPUT:
|
||||
return "spa12";
|
||||
|
||||
case INJECTOR_1_OUTPUT:
|
||||
return "Injector 1";
|
||||
return "inj1";
|
||||
case INJECTOR_2_OUTPUT:
|
||||
return "Injector 2";
|
||||
return "inj2";
|
||||
case INJECTOR_3_OUTPUT:
|
||||
return "Injector 3";
|
||||
return "inj3";
|
||||
case INJECTOR_4_OUTPUT:
|
||||
return "Injector 4";
|
||||
return "inj4";
|
||||
case INJECTOR_5_OUTPUT:
|
||||
return "Injector 5";
|
||||
return "inj5";
|
||||
case INJECTOR_6_OUTPUT:
|
||||
return "inj6";
|
||||
case INJECTOR_7_OUTPUT:
|
||||
return "inj7";
|
||||
case INJECTOR_8_OUTPUT:
|
||||
return "inj8";
|
||||
case INJECTOR_9_OUTPUT:
|
||||
return "inj9";
|
||||
case INJECTOR_10_OUTPUT:
|
||||
return "inj10";
|
||||
case INJECTOR_11_OUTPUT:
|
||||
return "inj11";
|
||||
case INJECTOR_12_OUTPUT:
|
||||
return "inj12";
|
||||
default:
|
||||
return "No name";
|
||||
return "Pin needs name";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,12 +28,7 @@
|
|||
*/
|
||||
typedef struct OutputSignal_struct OutputSignal;
|
||||
struct OutputSignal_struct {
|
||||
/**
|
||||
* name of this signal
|
||||
*/
|
||||
char *name;
|
||||
io_pin_e io_pin;
|
||||
int initialized;
|
||||
|
||||
/**
|
||||
* We are alternating instances so that events which extend into next revolution are not reused while
|
||||
|
@ -41,9 +36,6 @@ struct OutputSignal_struct {
|
|||
*/
|
||||
scheduling_s signalTimerUp[2];
|
||||
scheduling_s signalTimerDown[2];
|
||||
|
||||
scheduling_s triggerEvent;
|
||||
float angleOffsetParam;
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -56,8 +48,8 @@ void scheduleOutput(OutputSignal *signal, float delayMs, float durationMs);
|
|||
void initOutputSignalBase(OutputSignal *signal);
|
||||
void scheduleOutputBase(OutputSignal *signal, float delayMs, float durationMs);
|
||||
|
||||
void turnPinHigh(OutputSignal *signal);
|
||||
void turnPinLow(OutputSignal *signal);
|
||||
void turnPinHigh(io_pin_e pin);
|
||||
void turnPinLow(io_pin_e pin);
|
||||
|
||||
void initSignalExecutor(void);
|
||||
void initSignalExecutorImpl(void);
|
||||
|
|
|
@ -34,12 +34,19 @@
|
|||
|
||||
#define CHART_DELIMETER "!"
|
||||
|
||||
#if EFI_HISTOGRAMS
|
||||
#include "rfiutil.h"
|
||||
#include "histogram.h"
|
||||
static histogram_s waveChartHisto;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* This is the number of events in the digital chart which would be displayed
|
||||
* on the 'digital sniffer' pane
|
||||
*/
|
||||
#if EFI_PROD_CODE
|
||||
static volatile int chartSize = 100;
|
||||
// todo: does it really need to be a variable? maybe a constant should be enough?
|
||||
static volatile int chartSize = 300;
|
||||
#define WAVE_LOGGING_SIZE 5000
|
||||
#else
|
||||
// need more events for automated test
|
||||
|
@ -47,6 +54,8 @@ static volatile int chartSize = 400;
|
|||
#define WAVE_LOGGING_SIZE 35000
|
||||
#endif
|
||||
|
||||
int waveChartUsedSize;
|
||||
|
||||
static int isChartActive = TRUE;
|
||||
//static int isChartActive = FALSE;
|
||||
|
||||
|
@ -67,7 +76,12 @@ void resetWaveChart(WaveChart *chart) {
|
|||
appendPrintf(&chart->logging, "wave_chart%s", DELIMETER);
|
||||
}
|
||||
|
||||
static char WAVE_LOGGING_BUFFER[WAVE_LOGGING_SIZE] CCM_OPTIONAL;
|
||||
static char WAVE_LOGGING_BUFFER[WAVE_LOGGING_SIZE] CCM_OPTIONAL
|
||||
;
|
||||
|
||||
int isWaveChartFull(WaveChart *chart) {
|
||||
return chart->counter >= chartSize;
|
||||
}
|
||||
|
||||
static void printStatus(void) {
|
||||
scheduleIntValue(&logger, "chart", isChartActive);
|
||||
|
@ -93,12 +107,9 @@ void publishChartIfFull(WaveChart *chart) {
|
|||
}
|
||||
}
|
||||
|
||||
int isWaveChartFull(WaveChart *chart) {
|
||||
return chart->counter >= chartSize;
|
||||
}
|
||||
|
||||
void publishChart(WaveChart *chart) {
|
||||
appendPrintf(&chart->logging, DELIMETER);
|
||||
waveChartUsedSize = loggingSize(&chart->logging);
|
||||
#if DEBUG_WAVE
|
||||
Logging *l = &chart->logging;
|
||||
scheduleSimpleMsg(&debugLogging, "IT'S TIME", strlen(l->buffer));
|
||||
|
@ -107,8 +118,10 @@ void publishChart(WaveChart *chart) {
|
|||
scheduleLogging(&chart->logging);
|
||||
}
|
||||
|
||||
static char timeBuffer[10];
|
||||
|
||||
/**
|
||||
* @brief Register a change in sniffed signal
|
||||
* @brief Register an event for digital sniffer
|
||||
*/
|
||||
void addWaveChartEvent3(WaveChart *chart, const char *name, const char * msg, const char * msg2) {
|
||||
efiAssertVoid(chart->isInitialized, "chart not initialized");
|
||||
|
@ -117,13 +130,52 @@ void addWaveChartEvent3(WaveChart *chart, const char *name, const char * msg, co
|
|||
#endif
|
||||
if (isWaveChartFull(chart))
|
||||
return;
|
||||
bool alreadyLocked = lockOutputBuffer(); // we have multiple threads writing to the same output buffer
|
||||
appendPrintf(&chart->logging, "%s%s%s%s", name, CHART_DELIMETER, msg, CHART_DELIMETER);
|
||||
|
||||
#if EFI_HISTOGRAMS && EFI_PROD_CODE
|
||||
int beforeCallback = hal_lld_get_counter_value();
|
||||
#endif
|
||||
|
||||
|
||||
int time100 = getTimeNowUs() / 10;
|
||||
appendPrintf(&chart->logging, "%d%s%s", time100, msg2, CHART_DELIMETER);
|
||||
|
||||
bool alreadyLocked = lockOutputBuffer(); // we have multiple threads writing to the same output buffer
|
||||
|
||||
if (chart->counter == 0)
|
||||
chart->startTime = time100;
|
||||
chart->counter++;
|
||||
if (remainingSize(&chart->logging) > 30) {
|
||||
/**
|
||||
* printf is a heavy method, append is used here as a performance optimization
|
||||
*/
|
||||
appendFast(&chart->logging, name);
|
||||
appendFast(&chart->logging, CHART_DELIMETER);
|
||||
appendFast(&chart->logging, msg);
|
||||
appendFast(&chart->logging, CHART_DELIMETER);
|
||||
/**
|
||||
* We want smaller times within a chart in order to reduce packet size.
|
||||
*/
|
||||
time100 -= chart->startTime;
|
||||
|
||||
itoa10(timeBuffer, time100);
|
||||
appendFast(&chart->logging, timeBuffer);
|
||||
appendFast(&chart->logging, msg2);
|
||||
appendFast(&chart->logging, CHART_DELIMETER);
|
||||
}
|
||||
if (!alreadyLocked)
|
||||
unlockOutputBuffer();
|
||||
|
||||
#if EFI_HISTOGRAMS && EFI_PROD_CODE
|
||||
int diff = hal_lld_get_counter_value() - beforeCallback;
|
||||
if (diff > 0)
|
||||
hsAdd(&waveChartHisto, diff);
|
||||
#endif /* EFI_HISTOGRAMS */
|
||||
|
||||
}
|
||||
|
||||
void showWaveChartHistogram(void) {
|
||||
#if EFI_PROD_CODE
|
||||
printHistogram(&logger, &waveChartHisto);
|
||||
#endif
|
||||
}
|
||||
|
||||
void initWaveChart(WaveChart *chart) {
|
||||
|
@ -140,6 +192,10 @@ void initWaveChart(WaveChart *chart) {
|
|||
initLoggingExt(&debugLogging, "wave chart debug", &debugLogging.DEFAULT_BUFFER, sizeof(debugLogging.DEFAULT_BUFFER));
|
||||
#endif
|
||||
|
||||
#if EFI_HISTOGRAMS
|
||||
initHistogram(&waveChartHisto, "wave chart");
|
||||
#endif /* EFI_HISTOGRAMS */
|
||||
|
||||
resetWaveChart(chart);
|
||||
addConsoleActionI("chartsize", setChartSize);
|
||||
addConsoleActionI("chart", setChartActive);
|
||||
|
|
|
@ -23,6 +23,7 @@ typedef struct {
|
|||
Logging logging;
|
||||
#endif /* EFI_WAVE_CHART */
|
||||
int counter;
|
||||
int startTime;
|
||||
volatile int isInitialized;
|
||||
} WaveChart;
|
||||
|
||||
|
@ -34,9 +35,10 @@ extern "C"
|
|||
void addWaveChartEvent3(WaveChart *chart, const char *name, const char *msg, const char *msg2);
|
||||
void publishChart(WaveChart *chart);
|
||||
void initWaveChart(WaveChart *chart);
|
||||
void showWaveChartHistogram(void);
|
||||
void resetWaveChart(WaveChart *chart);
|
||||
void setChartSize(int newSize);
|
||||
int isWaveChartFull(WaveChart *chart);
|
||||
//int isWaveChartFull(WaveChart *chart);
|
||||
void publishChartIfFull(WaveChart *chart);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -37,24 +37,6 @@ void multi_wave_s::reset(void) {
|
|||
waveCount = 0;
|
||||
}
|
||||
|
||||
float multi_wave_s::getAngle(int index, engine_configuration_s const *engineConfiguration, trigger_shape_s * s) const {
|
||||
if (getOperationMode(engineConfiguration) == FOUR_STROKE_CAM_SENSOR)
|
||||
return getSwitchTime(index) * 720.0;
|
||||
/**
|
||||
* FOUR_STROKE_CRANK_SENSOR magic:
|
||||
* We have two crank shaft revolutions for each engine cycle
|
||||
* See also trigger_central.cpp
|
||||
* See also getEngineCycleEventCount()
|
||||
*/
|
||||
int triggerEventCounter = s->getSize();
|
||||
|
||||
if (index < triggerEventCounter) {
|
||||
return getSwitchTime(index) * 360.0;
|
||||
} else {
|
||||
return 360 + getSwitchTime(index - triggerEventCounter) * 360.0;
|
||||
}
|
||||
}
|
||||
|
||||
float multi_wave_s::getSwitchTime(int index) const {
|
||||
return switchTimes[index];
|
||||
}
|
||||
|
|
|
@ -32,7 +32,6 @@ public:
|
|||
void init(float *st, single_wave_s *waves);
|
||||
void reset(void);
|
||||
float getSwitchTime(int phaseIndex) const;
|
||||
float getAngle(int phaseIndex, engine_configuration_s const *engineConfiguration, trigger_shape_s * s) const;
|
||||
void setSwitchTime(int phaseIndex, float value);
|
||||
void checkSwitchTimes(int size);
|
||||
int getChannelState(int channelIndex, int phaseIndex) const;
|
||||
|
|
|
@ -2,5 +2,6 @@
|
|||
CONTROLLERS_CORE_SRC = $(PROJECT_DIR)/controllers/core/avg_values.c
|
||||
|
||||
CONTROLLERS_CORE_SRC_CPP = $(PROJECT_DIR)/controllers/core/EfiWave.cpp \
|
||||
$(PROJECT_DIR)/controllers/core/table_helper.cpp \
|
||||
$(PROJECT_DIR)/controllers/core/interpolation.cpp \
|
||||
|
||||
|
|
|
@ -0,0 +1,45 @@
|
|||
/**
|
||||
* @file fl_stack.h
|
||||
* @brief Fixed-length stack
|
||||
*
|
||||
* @date Jul 9, 2014
|
||||
* @author Andrey Belomutskiy, (c) 2012-2014
|
||||
*/
|
||||
|
||||
#ifndef FL_STACK_H_
|
||||
#define FL_STACK_H_
|
||||
|
||||
template<typename T, int MAXSIZE>
|
||||
class FLStack {
|
||||
public:
|
||||
FLStack();
|
||||
void push(T value);
|
||||
T pop();
|
||||
int size();
|
||||
bool isEmpty();
|
||||
private:
|
||||
int index;
|
||||
T values[MAXSIZE];
|
||||
};
|
||||
|
||||
template<typename T, int MAXSIZE>
|
||||
FLStack<T, MAXSIZE>::FLStack() {
|
||||
index = 0;
|
||||
}
|
||||
|
||||
template<typename T, int MAXSIZE>
|
||||
bool FLStack<T, MAXSIZE>::isEmpty() {
|
||||
return index == 0;
|
||||
}
|
||||
|
||||
template<typename T, int MAXSIZE>
|
||||
void FLStack<T, MAXSIZE>::push(T value) {
|
||||
values[index++] = value;
|
||||
}
|
||||
|
||||
template<typename T, int MAXSIZE>
|
||||
int FLStack<T, MAXSIZE>::size() {
|
||||
return index;
|
||||
}
|
||||
|
||||
#endif /* FL_STACK_H_ */
|
|
@ -82,9 +82,13 @@ int findIndex(float array[], int size, float value) {
|
|||
int left = 0;
|
||||
int right = size;
|
||||
|
||||
while (1) {
|
||||
if (size-- == 0)
|
||||
efiAssert(FALSE, "Unexpected state in binary search", 0);
|
||||
// todo: extract binary search as template method?
|
||||
while (true) {
|
||||
#if 0
|
||||
// that's an assertion to make sure we do not loop here
|
||||
size--;
|
||||
efiAssert(size > 0, "Unexpected state in binary search", 0);
|
||||
#endif
|
||||
|
||||
middle = (left + right) / 2;
|
||||
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
/**
|
||||
* @file table_helper.cpp
|
||||
* @brief Helper methods related to 3D & 2D tables manipulation (maps and curves)
|
||||
*
|
||||
* @date Jul 6, 2014
|
||||
* @author Andrey Belomutskiy, (c) 2012-2014
|
||||
*/
|
||||
|
||||
#include "table_helper.h"
|
||||
#include "efilib.h"
|
||||
#include "interpolation.h"
|
||||
|
||||
void setTableBin2(float array[], int size, float l, float r, float precision) {
|
||||
for (int i = 0; i < size; i++) {
|
||||
float value = interpolate(0, l, size - 1, r, i);
|
||||
/**
|
||||
* rounded values look nicer, also we want to avoid precision mismatch with Tuner Studio
|
||||
*/
|
||||
array[i] = efiRound(value, precision);
|
||||
}
|
||||
}
|
||||
|
||||
void setTableBin(float array[], int size, float l, float r) {
|
||||
setTableBin2(array, size, l, r, 0.01);
|
||||
}
|
||||
|
||||
void setRpmTableBin(float array[], int size) {
|
||||
setTableBin2(array, size, 800, 7000, 1);
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
/**
|
||||
* @file table_helper.h
|
||||
*
|
||||
* @date Jul 6, 2014
|
||||
* @author Andrey Belomutskiy, (c) 2012-2014
|
||||
*/
|
||||
#ifndef TABLE_HELPER_H_
|
||||
#define TABLE_HELPER_H_
|
||||
|
||||
#include <math.h>
|
||||
#include "error_handling.h"
|
||||
|
||||
// 'random' value to be sure we are not treating any non-zero trash as TRUE
|
||||
#define MAGIC_TRUE_VALUE 153351512
|
||||
|
||||
template<int RPM_BIN_SIZE, int LOAD_BIN_SIZE>
|
||||
class Map3D {
|
||||
public:
|
||||
void init(float table[RPM_BIN_SIZE][LOAD_BIN_SIZE]);
|
||||
float getValue(float x, float xBin[], float y, float yBin[]);
|
||||
void setAll(float value);
|
||||
private:
|
||||
float *pointers[LOAD_BIN_SIZE];
|
||||
int initialized;
|
||||
};
|
||||
|
||||
template<int RPM_BIN_SIZE, int LOAD_BIN_SIZE>
|
||||
void Map3D<RPM_BIN_SIZE, LOAD_BIN_SIZE>::init(float table[RPM_BIN_SIZE][LOAD_BIN_SIZE]) {
|
||||
for (int k = 0; k < LOAD_BIN_SIZE; k++)
|
||||
pointers[k] = table[k];
|
||||
initialized = MAGIC_TRUE_VALUE;
|
||||
}
|
||||
|
||||
template<int RPM_BIN_SIZE, int LOAD_BIN_SIZE>
|
||||
float Map3D<RPM_BIN_SIZE, LOAD_BIN_SIZE>::getValue(float x, float xBin[], float y, float yBin[]) {
|
||||
efiAssert(initialized == MAGIC_TRUE_VALUE, "map initialized", NAN);
|
||||
return interpolate3d(x, xBin, LOAD_BIN_SIZE, y, yBin, RPM_BIN_SIZE, pointers);
|
||||
}
|
||||
|
||||
template<int RPM_BIN_SIZE, int LOAD_BIN_SIZE>
|
||||
void Map3D<RPM_BIN_SIZE, LOAD_BIN_SIZE>::setAll(float value) {
|
||||
efiAssertVoid(initialized == MAGIC_TRUE_VALUE, "map initialized");
|
||||
for (int l = 0; l < LOAD_BIN_SIZE; l++) {
|
||||
for (int r = 0; r < RPM_BIN_SIZE; r++) {
|
||||
pointers[l][r] = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
typedef Map3D<16, 16> Map3D1616;
|
||||
|
||||
void setTableBin(float array[], int size, float l, float r);
|
||||
void setTableBin2(float array[], int size, float l, float r, float precision);
|
||||
void setRpmTableBin(float array[], int size);
|
||||
|
||||
#endif /* TABLE_HELPER_H_ */
|
|
@ -57,7 +57,7 @@ extern board_configuration_s *boardConfiguration;
|
|||
persistent_config_container_s persistentState CCM_OPTIONAL;
|
||||
|
||||
engine_configuration_s *engineConfiguration = &persistentState.persistentConfiguration.engineConfiguration;
|
||||
board_configuration_s *boardConfiguration = &persistentState.persistentConfiguration.boardConfiguration;
|
||||
board_configuration_s *boardConfiguration = &persistentState.persistentConfiguration.engineConfiguration.bc;
|
||||
|
||||
/**
|
||||
* CH_FREQUENCY is the number of system ticks in a second
|
||||
|
@ -244,7 +244,7 @@ void initEngineContoller(void) {
|
|||
initAnalogChart();
|
||||
#endif /* EFI_ANALOG_CHART */
|
||||
|
||||
initAlgo();
|
||||
initAlgo(engineConfiguration);
|
||||
|
||||
#if EFI_WAVE_ANALYZER
|
||||
initWaveAnalyzer();
|
||||
|
|
|
@ -13,16 +13,7 @@
|
|||
#include "signal_executor.h"
|
||||
#include "engine_configuration.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif /* __cplusplus */
|
||||
|
||||
char * getPinNameByAdcChannel(int hwChannel, char *buffer);
|
||||
void initEngineContoller(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* ENGINE_STATUS_H_ */
|
||||
|
|
|
@ -15,7 +15,6 @@
|
|||
#include "flash.h"
|
||||
#include "rusefi.h"
|
||||
|
||||
//#include "tunerstudio.h"
|
||||
#include "engine_controller.h"
|
||||
|
||||
#include "datalogging.h"
|
||||
|
@ -55,7 +54,7 @@ void writeToFlash(void) {
|
|||
#if EFI_INTERNAL_FLASH
|
||||
persistentState.size = PERSISTENT_SIZE;
|
||||
persistentState.version = FLASH_DATA_VERSION;
|
||||
scheduleMsg(&logger, "FLASH_DATA_VERSION=%d", persistentState.version);
|
||||
scheduleMsg(&logger, "flash compatible with %d", persistentState.version);
|
||||
crc_t result = flashStateCrc(&persistentState);
|
||||
persistentState.value = result;
|
||||
scheduleMsg(&logger, "Reseting flash, size=%d", PERSISTENT_SIZE);
|
||||
|
@ -85,7 +84,7 @@ static void doResetConfiguration(void) {
|
|||
boardConfiguration);
|
||||
}
|
||||
|
||||
static void readFromFlash(void) {
|
||||
void readFromFlash(void) {
|
||||
printMsg(&logger, "readFromFlash()");
|
||||
|
||||
flashRead(FLASH_ADDR, (char *) &persistentState, PERSISTENT_SIZE);
|
||||
|
@ -112,6 +111,4 @@ void initFlash(void) {
|
|||
addConsoleAction("readconfig", readFromFlash);
|
||||
addConsoleAction("writeconfig", writeToFlash);
|
||||
addConsoleAction("resetconfig", doResetConfiguration);
|
||||
|
||||
readFromFlash();
|
||||
}
|
||||
|
|
|
@ -11,13 +11,14 @@
|
|||
|
||||
#include "engine_configuration.h"
|
||||
|
||||
#define FLASH_DATA_VERSION 3601
|
||||
#define FLASH_DATA_VERSION 3880
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif /* __cplusplus */
|
||||
|
||||
void readFromFlash(void);
|
||||
void initFlash(void);
|
||||
void writeToFlash(void);
|
||||
|
||||
|
|
|
@ -34,8 +34,8 @@ extern board_configuration_s *boardConfiguration;
|
|||
void initIgnitionCentral(void) {
|
||||
initLogging(&logger, "IgnitionCentral");
|
||||
|
||||
outputPinRegisterExt2("sparkout1", SPARKOUT_1_OUTPUT, boardConfiguration->ignitionPins[0], &boardConfiguration->ignitionPinMode);
|
||||
outputPinRegisterExt2("sparkout2", SPARKOUT_2_OUTPUT, boardConfiguration->ignitionPins[1], &boardConfiguration->ignitionPinMode);
|
||||
outputPinRegisterExt2("sparkout3", SPARKOUT_3_OUTPUT, boardConfiguration->ignitionPins[2], &boardConfiguration->ignitionPinMode);
|
||||
outputPinRegisterExt2("sparkout4", SPARKOUT_4_OUTPUT, boardConfiguration->ignitionPins[3], &boardConfiguration->ignitionPinMode);
|
||||
for (int i = 0; i < engineConfiguration->cylindersCount; i++) {
|
||||
io_pin_e pin = (io_pin_e)((int)INJECTOR_1_OUTPUT + i);
|
||||
outputPinRegisterExt2(getPinName(pin), pin, boardConfiguration->ignitionPins[i], &boardConfiguration->ignitionPinMode);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -139,24 +139,16 @@ void initInjectorCentral(void) {
|
|||
|
||||
for (int i = 0; i < engineConfiguration->cylindersCount; i++)
|
||||
is_injector_enabled[i] = true;
|
||||
printStatus();
|
||||
|
||||
// todo: should we move this code closer to the injection logic?
|
||||
// todo: dynamic initialization
|
||||
// todo: consider actual cylinders count
|
||||
outputPinRegisterExt2("injector1", INJECTOR_1_OUTPUT, boardConfiguration->injectionPins[0],
|
||||
&boardConfiguration->injectionPinMode);
|
||||
outputPinRegisterExt2("injector2", INJECTOR_2_OUTPUT, boardConfiguration->injectionPins[1],
|
||||
&boardConfiguration->injectionPinMode);
|
||||
outputPinRegisterExt2("injector3", INJECTOR_3_OUTPUT, boardConfiguration->injectionPins[2],
|
||||
&boardConfiguration->injectionPinMode);
|
||||
outputPinRegisterExt2("injector4", INJECTOR_4_OUTPUT, boardConfiguration->injectionPins[3],
|
||||
&boardConfiguration->injectionPinMode);
|
||||
outputPinRegisterExt2("injector5", INJECTOR_5_OUTPUT, boardConfiguration->injectionPins[4],
|
||||
&boardConfiguration->injectionPinMode);
|
||||
outputPinRegisterExt2("injector5", INJECTOR_6_OUTPUT, boardConfiguration->injectionPins[5],
|
||||
&boardConfiguration->injectionPinMode);
|
||||
for (int i = 0; i < engineConfiguration->cylindersCount; i++) {
|
||||
io_pin_e pin = (io_pin_e)((int)INJECTOR_1_OUTPUT + i);
|
||||
|
||||
outputPinRegisterExt2(getPinName(pin), pin,
|
||||
boardConfiguration->injectionPins[i], &boardConfiguration->injectionPinMode);
|
||||
}
|
||||
|
||||
printStatus();
|
||||
addConsoleActionII("injector", setInjectorEnabled);
|
||||
|
||||
addConsoleActionSSS("fuelbench", &fuelbench);
|
||||
|
|
|
@ -42,14 +42,14 @@
|
|||
* @deprecated
|
||||
*/
|
||||
float getOneDegreeTimeMs(int rpm) {
|
||||
return 1000.0 * 60 / 360 / rpm;
|
||||
return 1000.0f * 60 / 360 / rpm;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return time needed to rotate crankshaft by one degree, in microseconds.
|
||||
*/
|
||||
float getOneDegreeTimeUs(int rpm) {
|
||||
return 1000000.0 * 60 / 360 / rpm;
|
||||
return 1000000.0f * 60 / 360 / rpm;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -67,7 +67,7 @@ float fixAngle(float angle) {
|
|||
// I guess this implementation would be faster than 'angle % 720'
|
||||
while (angle < 0)
|
||||
angle += 720;
|
||||
while (angle > 720)
|
||||
while (angle >= 720)
|
||||
angle -= 720;
|
||||
return angle;
|
||||
}
|
||||
|
@ -77,7 +77,7 @@ float fixAngle(float angle) {
|
|||
*
|
||||
*/
|
||||
float getEngineLoadT(engine_configuration_s *engineConfiguration) {
|
||||
switch (engineConfiguration->engineLoadMode) {
|
||||
switch (engineConfiguration->algorithm) {
|
||||
case LM_MAF:
|
||||
return getMaf();
|
||||
case LM_MAP:
|
||||
|
@ -88,7 +88,7 @@ float getEngineLoadT(engine_configuration_s *engineConfiguration) {
|
|||
// TODO: real implementation
|
||||
return getMap();
|
||||
default:
|
||||
firmwareError("Unexpected engine load parameter: %d", engineConfiguration->engineLoadMode);
|
||||
firmwareError("Unexpected engine load parameter: %d", engineConfiguration->algorithm);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
@ -113,26 +113,26 @@ int isCrankingRT(engine_configuration_s *engineConfiguration, int rpm) {
|
|||
return rpm > 0 && rpm < engineConfiguration->crankingSettings.crankingRpm;
|
||||
}
|
||||
|
||||
OutputSignalList ignitionSignals;
|
||||
OutputSignalList injectonSignals;
|
||||
OutputSignalList injectonSignals CCM_OPTIONAL;
|
||||
|
||||
static void registerSparkEvent(engine_configuration_s const *engineConfiguration, trigger_shape_s * s,
|
||||
IgnitionEventList *list, OutputSignal *actuator, float localAdvance, float dwell) {
|
||||
IgnitionEventList *list, io_pin_e pin, float localAdvance, float dwell) {
|
||||
|
||||
IgnitionEvent *event = list->getNextActuatorEvent();
|
||||
if (event == NULL)
|
||||
return; // error already reported
|
||||
|
||||
event->io_pin = pin;
|
||||
|
||||
event->advance = localAdvance;
|
||||
|
||||
registerActuatorEventExt(engineConfiguration, s, &event->actuator, actuator, localAdvance - dwell);
|
||||
findTriggerPosition(engineConfiguration, s, &event->dwellPosition, localAdvance - dwell);
|
||||
}
|
||||
|
||||
void initializeIgnitionActions(float advance, float dwellAngle, engine_configuration_s *engineConfiguration,
|
||||
engine_configuration2_s *engineConfiguration2, IgnitionEventList *list) {
|
||||
|
||||
efiAssertVoid(engineConfiguration->cylindersCount > 0, "cylindersCount");
|
||||
ignitionSignals.clear();
|
||||
|
||||
list->resetEventList();
|
||||
|
||||
|
@ -140,15 +140,15 @@ void initializeIgnitionActions(float advance, float dwellAngle, engine_configura
|
|||
case IM_ONE_COIL:
|
||||
for (int i = 0; i < engineConfiguration->cylindersCount; i++) {
|
||||
// todo: extract method
|
||||
float localAdvance = advance + 720.0 * i / engineConfiguration->cylindersCount;
|
||||
float localAdvance = advance + 720.0f * i / engineConfiguration->cylindersCount;
|
||||
|
||||
registerSparkEvent(engineConfiguration, &engineConfiguration2->triggerShape, list,
|
||||
ignitionSignals.add(SPARKOUT_1_OUTPUT), localAdvance, dwellAngle);
|
||||
SPARKOUT_1_OUTPUT, localAdvance, dwellAngle);
|
||||
}
|
||||
break;
|
||||
case IM_WASTED_SPARK:
|
||||
for (int i = 0; i < engineConfiguration->cylindersCount; i++) {
|
||||
float localAdvance = advance + 720.0 * i / engineConfiguration->cylindersCount;
|
||||
float localAdvance = advance + 720.0f * i / engineConfiguration->cylindersCount;
|
||||
|
||||
int wastedIndex = i % (engineConfiguration->cylindersCount / 2);
|
||||
|
||||
|
@ -156,17 +156,17 @@ void initializeIgnitionActions(float advance, float dwellAngle, engine_configura
|
|||
io_pin_e ioPin = (io_pin_e) (SPARKOUT_1_OUTPUT + id);
|
||||
|
||||
registerSparkEvent(engineConfiguration, &engineConfiguration2->triggerShape, list,
|
||||
ignitionSignals.add(ioPin), localAdvance, dwellAngle);
|
||||
ioPin, localAdvance, dwellAngle);
|
||||
|
||||
}
|
||||
|
||||
break;
|
||||
case IM_INDIVIDUAL_COILS:
|
||||
for (int i = 0; i < engineConfiguration->cylindersCount; i++) {
|
||||
float localAdvance = advance + 720.0 * i / engineConfiguration->cylindersCount;
|
||||
float localAdvance = advance + 720.0f * i / engineConfiguration->cylindersCount;
|
||||
|
||||
io_pin_e pin = (io_pin_e) ((int) SPARKOUT_1_OUTPUT + getCylinderId(engineConfiguration->firingOrder, i) - 1);
|
||||
registerSparkEvent(engineConfiguration, &engineConfiguration2->triggerShape, list, ignitionSignals.add(pin),
|
||||
registerSparkEvent(engineConfiguration, &engineConfiguration2->triggerShape, list, pin,
|
||||
localAdvance, dwellAngle);
|
||||
}
|
||||
break;
|
||||
|
@ -176,6 +176,16 @@ void initializeIgnitionActions(float advance, float dwellAngle, engine_configura
|
|||
}
|
||||
}
|
||||
|
||||
static void registerInjectionEvent(engine_configuration_s const *e,
|
||||
trigger_shape_s *s,
|
||||
ActuatorEventList *list,
|
||||
io_pin_e pin,
|
||||
float angle
|
||||
) {
|
||||
registerActuatorEventExt(e, s, list->getNextActuatorEvent(), injectonSignals.add(pin), angle);
|
||||
|
||||
}
|
||||
|
||||
void addFuelEvents(engine_configuration_s const *e, engine_configuration2_s *engineConfiguration2,
|
||||
ActuatorEventList *list, injection_mode_e mode) {
|
||||
list->resetEventList();
|
||||
|
@ -189,7 +199,7 @@ void addFuelEvents(engine_configuration_s const *e, engine_configuration2_s *eng
|
|||
for (int i = 0; i < e->cylindersCount; i++) {
|
||||
io_pin_e pin = (io_pin_e) ((int) INJECTOR_1_OUTPUT + getCylinderId(e->firingOrder, i) - 1);
|
||||
float angle = baseAngle + i * 720.0 / e->cylindersCount;
|
||||
registerActuatorEventExt(e, s, list->getNextActuatorEvent(), injectonSignals.add(pin), angle);
|
||||
registerInjectionEvent(e, s, list, pin, angle);
|
||||
}
|
||||
break;
|
||||
case IM_SIMULTANEOUS:
|
||||
|
@ -198,7 +208,7 @@ void addFuelEvents(engine_configuration_s const *e, engine_configuration2_s *eng
|
|||
|
||||
for (int j = 0; j < e->cylindersCount; j++) {
|
||||
io_pin_e pin = (io_pin_e) ((int) INJECTOR_1_OUTPUT + j);
|
||||
registerActuatorEventExt(e, s, list->getNextActuatorEvent(), injectonSignals.add(pin), angle);
|
||||
registerInjectionEvent(e, s, list, pin, angle);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -206,7 +216,7 @@ void addFuelEvents(engine_configuration_s const *e, engine_configuration2_s *eng
|
|||
for (int i = 0; i < e->cylindersCount; i++) {
|
||||
io_pin_e pin = (io_pin_e) ((int) INJECTOR_1_OUTPUT + (i % 2));
|
||||
float angle = baseAngle + i * 720.0 / e->cylindersCount;
|
||||
registerActuatorEventExt(e, s, list->getNextActuatorEvent(), injectonSignals.add(pin), angle);
|
||||
registerInjectionEvent(e, s, list, pin, angle);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
@ -228,12 +238,16 @@ float getSparkDwellMsT(engine_configuration_s *engineConfiguration, int rpm) {
|
|||
return interpolate2d(rpm, engineConfiguration->sparkDwellBins, engineConfiguration->sparkDwell, DWELL_CURVE_SIZE);
|
||||
}
|
||||
|
||||
int getEngineCycleEventCount2(operation_mode_e mode, trigger_shape_s * s) {
|
||||
return mode == FOUR_STROKE_CAM_SENSOR ? s->getSize() : 2 * s->getSize();
|
||||
}
|
||||
|
||||
/**
|
||||
* Trigger event count equals engine cycle event count if we have a cam sensor.
|
||||
* Two trigger cycles make one engine cycle in case of a four stroke engine If we only have a cranksensor.
|
||||
*/
|
||||
int getEngineCycleEventCount(engine_configuration_s const *engineConfiguration, trigger_shape_s * s) {
|
||||
return getOperationMode(engineConfiguration) == FOUR_STROKE_CAM_SENSOR ? s->getSize() : 2 * s->getSize();
|
||||
return getEngineCycleEventCount2(getOperationMode(engineConfiguration), s);
|
||||
}
|
||||
|
||||
void findTriggerPosition(engine_configuration_s const *engineConfiguration, trigger_shape_s * s,
|
||||
|
@ -241,37 +255,40 @@ void findTriggerPosition(engine_configuration_s const *engineConfiguration, trig
|
|||
|
||||
angleOffset = fixAngle(angleOffset + engineConfiguration->globalTriggerAngleOffset);
|
||||
|
||||
// todo: migrate to crankAngleRange?
|
||||
float firstAngle = s->wave.getAngle(s->triggerShapeSynchPointIndex, engineConfiguration, s);
|
||||
|
||||
int engineCycleEventCount = getEngineCycleEventCount(engineConfiguration, s);
|
||||
|
||||
// let's find the last trigger angle which is less or equal to the desired angle
|
||||
int i;
|
||||
for (i = 0; i < engineCycleEventCount - 1; i++) {
|
||||
// todo: we need binary search here
|
||||
float angle = fixAngle(
|
||||
s->wave.getAngle((s->triggerShapeSynchPointIndex + i + 1) % engineCycleEventCount, engineConfiguration, s)
|
||||
- firstAngle);
|
||||
if (angle > angleOffset)
|
||||
int middle;
|
||||
int left = 0;
|
||||
int right = engineCycleEventCount - 1;
|
||||
|
||||
/**
|
||||
* Let's find the last trigger angle which is less or equal to the desired angle
|
||||
* todo: extract binary search as template method?
|
||||
*/
|
||||
while (true) {
|
||||
middle = (left + right) / 2;
|
||||
|
||||
if (middle == left)
|
||||
break;
|
||||
|
||||
if (angleOffset < s->eventAngles[middle]) {
|
||||
right = middle;
|
||||
} else if (angleOffset > s->eventAngles[middle]) {
|
||||
left = middle;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
// explicit check for zero to avoid issues where logical zero is not exactly zero due to float nature
|
||||
float eventAngle;
|
||||
if (i == 0) {
|
||||
eventAngle = 0;
|
||||
} else {
|
||||
eventAngle = fixAngle(
|
||||
s->wave.getAngle((s->triggerShapeSynchPointIndex + i) % engineCycleEventCount, engineConfiguration, s)
|
||||
- firstAngle);
|
||||
|
||||
}
|
||||
|
||||
float eventAngle = s->eventAngles[middle];
|
||||
|
||||
if (angleOffset < eventAngle) {
|
||||
firmwareError("angle constraint violation in registerActuatorEventExt(): %f/%f", angleOffset, eventAngle);
|
||||
return;
|
||||
}
|
||||
|
||||
position->eventIndex = i;
|
||||
position->eventIndex = middle;
|
||||
position->eventAngle = eventAngle;
|
||||
position->angleOffset = angleOffset - eventAngle;
|
||||
}
|
||||
|
@ -318,8 +335,8 @@ int getCylinderId(firing_order_e firingOrder, int index) {
|
|||
void prepareOutputSignals(engine_configuration_s *engineConfiguration, engine_configuration2_s *engineConfiguration2) {
|
||||
|
||||
// todo: move this reset into decoder
|
||||
engineConfiguration2->triggerShape.triggerShapeSynchPointIndex = findTriggerZeroEventIndex(
|
||||
&engineConfiguration2->triggerShape, &engineConfiguration->triggerConfig);
|
||||
engineConfiguration2->triggerShape.setTriggerShapeSynchPointIndex(findTriggerZeroEventIndex(
|
||||
&engineConfiguration2->triggerShape, &engineConfiguration->triggerConfig));
|
||||
|
||||
injectonSignals.clear();
|
||||
EventHandlerConfiguration *config = &engineConfiguration2->engineEventConfiguration;
|
||||
|
@ -329,16 +346,6 @@ void prepareOutputSignals(engine_configuration_s *engineConfiguration, engine_co
|
|||
engineConfiguration->injectionMode);
|
||||
}
|
||||
|
||||
void setTableBin(float array[], int size, float l, float r) {
|
||||
for (int i = 0; i < size; i++) {
|
||||
float value = interpolate(0, l, size - 1, r, i);
|
||||
/**
|
||||
* rounded values look nicer, also we want to avoid precision mismatch with Tuner Studio
|
||||
*/
|
||||
array[i] = efiRound(value, 0.01);
|
||||
}
|
||||
}
|
||||
|
||||
void setFuelRpmBin(engine_configuration_s *engineConfiguration, float l, float r) {
|
||||
setTableBin(engineConfiguration->fuelRpmBins, FUEL_RPM_COUNT, l, r);
|
||||
}
|
||||
|
|
|
@ -13,48 +13,14 @@
|
|||
#ifdef __cplusplus
|
||||
#include "ec2.h"
|
||||
#include "trigger_structure.h"
|
||||
#include "table_helper.h"
|
||||
|
||||
void findTriggerPosition(engine_configuration_s const *engineConfiguration, trigger_shape_s * s,
|
||||
event_trigger_position_s *position, float angleOffset);
|
||||
|
||||
int isInjectionEnabled(engine_configuration2_s const *engineConfiguration2);
|
||||
|
||||
// 'random' value to be sure we are not treating any non-zero trash as TRUE
|
||||
#define MAGIC_TRUE_VALUE 153351512
|
||||
|
||||
template<int RPM_BIN_SIZE, int LOAD_BIN_SIZE>
|
||||
class Map3D {
|
||||
public:
|
||||
void init(float table[RPM_BIN_SIZE][LOAD_BIN_SIZE]);
|
||||
float getValue(float x, float xBin[], float y, float yBin[]);
|
||||
void setAll(float value);
|
||||
private:
|
||||
float *pointers[LOAD_BIN_SIZE];
|
||||
int initialized;
|
||||
};
|
||||
|
||||
template<int RPM_BIN_SIZE, int LOAD_BIN_SIZE>
|
||||
void Map3D<RPM_BIN_SIZE, LOAD_BIN_SIZE>::init(float table[RPM_BIN_SIZE][LOAD_BIN_SIZE]) {
|
||||
for (int k = 0; k < LOAD_BIN_SIZE; k++)
|
||||
pointers[k] = table[k];
|
||||
initialized = MAGIC_TRUE_VALUE;
|
||||
}
|
||||
|
||||
template<int RPM_BIN_SIZE, int LOAD_BIN_SIZE>
|
||||
float Map3D<RPM_BIN_SIZE, LOAD_BIN_SIZE>::getValue(float x, float xBin[], float y, float yBin[]) {
|
||||
efiAssert(initialized == MAGIC_TRUE_VALUE, "fuel map initialized", NAN);
|
||||
return interpolate3d(x, xBin, LOAD_BIN_SIZE, y, yBin, RPM_BIN_SIZE, pointers);
|
||||
}
|
||||
|
||||
template<int RPM_BIN_SIZE, int LOAD_BIN_SIZE>
|
||||
void Map3D<RPM_BIN_SIZE, LOAD_BIN_SIZE>::setAll(float value) {
|
||||
for (int l = 0; l < LOAD_BIN_SIZE; l++) {
|
||||
for (int r = 0; r < RPM_BIN_SIZE; r++) {
|
||||
pointers[l][r] = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
typedef Map3D<16, 16> Map3D1616;
|
||||
float fixAngle(float angle);
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -63,8 +29,6 @@ extern "C"
|
|||
{
|
||||
#endif /* __cplusplus */
|
||||
|
||||
//float getDefaultVE(int rpm);
|
||||
|
||||
float getDefaultFuel(int rpm, float map);
|
||||
|
||||
float getOneDegreeTimeMs(int rpm);
|
||||
|
@ -74,19 +38,14 @@ float getCrankshaftRevolutionTimeMs(int rpm);
|
|||
int isCrankingRT(engine_configuration_s *engineConfiguration, int rpm);
|
||||
#define isCrankingR(rpm) isCrankingRT(engineConfiguration, rpm)
|
||||
|
||||
float fixAngle(float angle);
|
||||
float getTriggerEventAngle(int triggerEventIndex);
|
||||
|
||||
float getEngineLoadT(engine_configuration_s *engineConfiguration);
|
||||
#define getEngineLoad() getEngineLoadT(engineConfiguration)
|
||||
|
||||
float getSparkDwellMsT(engine_configuration_s *engineConfiguration, int rpm);
|
||||
#define getSparkDwellMs(rpm) getSparkDwellMsT(engineConfiguration, rpm)
|
||||
|
||||
|
||||
int getCylinderId(firing_order_e firingOrder, int index);
|
||||
|
||||
void setTableBin(float array[], int size, float l, float r);
|
||||
void setFuelRpmBin(engine_configuration_s *engineConfiguration, float l, float r);
|
||||
void setFuelLoadBin(engine_configuration_s *engineConfiguration, float l, float r);
|
||||
void setTimingRpmBin(engine_configuration_s *engineConfiguration, float l, float r);
|
||||
|
|
|
@ -45,34 +45,48 @@ float getTCharge(int rpm, int tps, float coolantTemp, float airTemp) {
|
|||
*/
|
||||
#define GAS_R 0.28705
|
||||
|
||||
/**
|
||||
* @return value in seconds
|
||||
*/
|
||||
float sdMath(engine_configuration_s *engineConfiguration, float VE, float MAP, float AFR, float temp) {
|
||||
float injectorFlowRate = cc_minute_to_gramm_second(engineConfiguration->injectorFlow);
|
||||
float Vol = engineConfiguration->displacement / engineConfiguration->cylindersCount;
|
||||
return (Vol * VE * MAP) / (AFR * injectorFlowRate * GAS_R * temp);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return value in Milliseconds
|
||||
*/
|
||||
float getSpeedDensityFuel(Engine *engine) {
|
||||
int rpm = engine->rpmCalculator->rpm();
|
||||
|
||||
engine_configuration_s *engineConfiguration = engine->engineConfiguration;
|
||||
|
||||
float tps = getTPS();
|
||||
float coolantC = getCoolantTemperature();
|
||||
float intakeC = getIntakeAirTemperature();
|
||||
float tChargeK = convertCelciusToKelvin(getTCharge(rpm, tps, coolantC, intakeC));
|
||||
float MAP = getMap();
|
||||
float VE = 0.8;//veMap.getValue(rpm)
|
||||
float AFR = 14.7;
|
||||
|
||||
return sdMath(engine->engineConfiguration, VE, MAP, AFR, tChargeK);
|
||||
float tChargeK = convertCelsiusToKelvin(getTCharge(rpm, tps, coolantC, intakeC));
|
||||
float map = getMap();
|
||||
float VE = veMap.getValue(map, engineConfiguration->veLoadBins, rpm,
|
||||
engineConfiguration->veRpmBins);
|
||||
float AFR = afrMap.getValue(map, engineConfiguration->afrLoadBins, rpm,
|
||||
engineConfiguration->afrRpmBins);
|
||||
|
||||
return sdMath(engine->engineConfiguration, VE, map, AFR, tChargeK) * 1000;
|
||||
}
|
||||
|
||||
void setDetaultVETable(engine_configuration_s *engineConfiguration) {
|
||||
setTableBin(engineConfiguration->veRpmBins, FUEL_RPM_COUNT, 800, 7000);
|
||||
setRpmTableBin(engineConfiguration->veRpmBins, VE_RPM_COUNT);
|
||||
setTableBin2(engineConfiguration->veLoadBins, VE_LOAD_COUNT, 10, 300, 1);
|
||||
|
||||
setRpmTableBin(engineConfiguration->afrRpmBins, AFR_RPM_COUNT);
|
||||
setTableBin2(engineConfiguration->afrLoadBins, VE_LOAD_COUNT, 10, 300, 1);
|
||||
|
||||
veMap.setAll(0.8);
|
||||
afrMap.setAll(14.7);
|
||||
}
|
||||
|
||||
void initSpeedDensity(configuration_s *config) {
|
||||
veMap.init(config->engineConfiguration->veTable);
|
||||
afrMap.init(config->engineConfiguration->afrTable);
|
||||
void initSpeedDensity(engine_configuration_s *engineConfiguration) {
|
||||
veMap.init(engineConfiguration->veTable);
|
||||
afrMap.init(engineConfiguration->afrTable);
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@ float sdMath(engine_configuration_s *engineConfiguration, float VE, float MAP, f
|
|||
|
||||
#define cc_minute_to_gramm_second(ccm) ((ccm) * 0.0119997981)
|
||||
|
||||
void initSpeedDensity(configuration_s *config);
|
||||
void setDetaultVETable(engine_configuration_s *engineConfiguration);
|
||||
void initSpeedDensity(engine_configuration_s *engineConfiguration);
|
||||
|
||||
#endif /* SPEED_DENSITY_H_ */
|
||||
|
|
|
@ -17,10 +17,14 @@
|
|||
#include "engine_math.h"
|
||||
#include "ec2.h"
|
||||
|
||||
// Celsius
|
||||
#define LIMPING_MODE_IAT_TEMPERATURE 30
|
||||
#define LIMPING_MODE_CLT_TEMPERATURE 70
|
||||
|
||||
extern engine_configuration_s *engineConfiguration;
|
||||
extern engine_configuration2_s *engineConfiguration2;
|
||||
|
||||
static bool_t initialized = FALSE;
|
||||
static bool initialized = false;
|
||||
|
||||
/**
|
||||
* http://en.wikipedia.org/wiki/Voltage_divider
|
||||
|
@ -44,29 +48,21 @@ float convertResistanceToKelvinTemperature(float resistance, ThermistorConf *the
|
|||
//warning("Invalid resistance in convertResistanceToKelvinTemperature=", resistance);
|
||||
return 0;
|
||||
}
|
||||
float logR = log(resistance);
|
||||
float logR = logf(resistance);
|
||||
return 1 / (thermistor->s_h_a + thermistor->s_h_b * logR + thermistor->s_h_c * logR * logR * logR);
|
||||
}
|
||||
|
||||
float convertKelvinToC(float tempK) {
|
||||
return tempK - KELV;
|
||||
}
|
||||
|
||||
float convertCelciusToKelvin(float tempC) {
|
||||
return tempC + KELV;
|
||||
}
|
||||
|
||||
float convertCelciustoF(float tempC) {
|
||||
float convertCelsiustoF(float tempC) {
|
||||
return tempC * 9 / 5 + 32;
|
||||
}
|
||||
|
||||
float convertFtoCelcius(float tempF) {
|
||||
float convertFtoCelsius(float tempF) {
|
||||
return (tempF - 32) / 9 * 5;
|
||||
}
|
||||
|
||||
float convertKelvinToFahrenheit(float kelvin) {
|
||||
float tempC = convertKelvinToC(kelvin);
|
||||
return convertCelciustoF(tempC);
|
||||
float tempC = convertKelvinToCelcius(kelvin);
|
||||
return convertCelsiustoF(tempC);
|
||||
}
|
||||
|
||||
float getKelvinTemperature(float resistance, ThermistorConf *thermistor) {
|
||||
|
@ -94,7 +90,7 @@ float getTemperatureC(Thermistor *thermistor) {
|
|||
float resistance = getResistance(thermistor);
|
||||
|
||||
float kelvinTemperature = getKelvinTemperature(resistance, thermistor->config);
|
||||
return convertKelvinToC(kelvinTemperature);
|
||||
return convertKelvinToCelcius(kelvinTemperature);
|
||||
}
|
||||
|
||||
int isValidCoolantTemperature(float temperature) {
|
||||
|
@ -108,12 +104,14 @@ int isValidIntakeAirTemperature(float temperature) {
|
|||
}
|
||||
|
||||
/**
|
||||
* @return coolant temperature, in Celcius
|
||||
* @return coolant temperature, in Celsius
|
||||
*/
|
||||
float getCoolantTemperature(void) {
|
||||
float temperature = getTemperatureC(&engineConfiguration2->clt);
|
||||
if (!isValidCoolantTemperature(temperature))
|
||||
return NAN;
|
||||
if (!isValidCoolantTemperature(temperature)) {
|
||||
warning(OBD_PCM_Processor_Fault, "unrealistic coolant temperature %f", temperature);
|
||||
return LIMPING_MODE_CLT_TEMPERATURE;
|
||||
}
|
||||
return temperature;
|
||||
}
|
||||
|
||||
|
@ -134,9 +132,9 @@ void prepareThermistorCurve(ThermistorConf * config) {
|
|||
float T2 = config->tempC_2 + KELV;
|
||||
float T3 = config->tempC_3 + KELV;
|
||||
|
||||
float L1 = log(config->resistance_1);
|
||||
float L2 = log(config->resistance_2);
|
||||
float L3 = log(config->resistance_3);
|
||||
float L1 = logf(config->resistance_1);
|
||||
float L2 = logf(config->resistance_2);
|
||||
float L3 = logf(config->resistance_3);
|
||||
|
||||
float Y1 = 1 / T1;
|
||||
float Y2 = 1 / T2;
|
||||
|
@ -150,11 +148,14 @@ void prepareThermistorCurve(ThermistorConf * config) {
|
|||
config->s_h_a = Y1 - (config->s_h_b + L1 * L1 * config->s_h_c) * L1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Celsius value
|
||||
*/
|
||||
float getIntakeAirTemperature(void) {
|
||||
float temperature = getTemperatureC(&engineConfiguration2->iat);
|
||||
if (!isValidIntakeAirTemperature(temperature)) {
|
||||
warning(OBD_PCM_Processor_Fault, "unrealistic intake temperature %f", temperature);
|
||||
return NAN;
|
||||
return LIMPING_MODE_IAT_TEMPERATURE;
|
||||
}
|
||||
return temperature;
|
||||
}
|
||||
|
|
|
@ -26,10 +26,10 @@ float getR1InVoltageDividor(float Vout, float Vin, float r2);
|
|||
float getR2InVoltageDividor(float Vout, float Vin, float r1);
|
||||
float getTempK(float resistance);
|
||||
/**
|
||||
* converts Kelvin temperature into Celcius temperature
|
||||
* converts Kelvin temperature into Celsius temperature
|
||||
*/
|
||||
float convertKelvinToCelcius(float tempK);
|
||||
float convertCelciusToKelvin(float tempC);
|
||||
#define convertKelvinToCelcius(tempK) ((tempK) - KELV)
|
||||
#define convertCelsiusToKelvin(tempC) ((tempC) + KELV)
|
||||
|
||||
float convertCelciustoF(float tempC);
|
||||
float convertFtoCelcius(float tempF);
|
||||
|
|
|
@ -19,10 +19,12 @@
|
|||
#include "ec2.h"
|
||||
#include "map.h"
|
||||
#include "trigger_decoder.h"
|
||||
#include "console_io.h"
|
||||
|
||||
#if EFI_PROD_CODE
|
||||
#include "rusefi.h"
|
||||
#include "pin_repository.h"
|
||||
#include "hardware.h"
|
||||
#endif /* EFI_PROD_CODE */
|
||||
|
||||
#if EFI_INTERNAL_FLASH
|
||||
|
@ -114,7 +116,7 @@ static const char * pinModeToString(pin_output_mode_e mode) {
|
|||
}
|
||||
}
|
||||
|
||||
static const char * boolToString(bool_t value) {
|
||||
static const char * boolToString(bool value) {
|
||||
return value ? "Yes" : "No";
|
||||
}
|
||||
|
||||
|
@ -201,6 +203,7 @@ void printConfiguration(engine_configuration_s *engineConfiguration, engine_conf
|
|||
|
||||
scheduleMsg(&logger, "primary trigger input: %s", hwPortname(boardConfiguration->primaryTriggerInputPin));
|
||||
|
||||
scheduleMsg(&logger, "boardTestModeJumperPin: %s", hwPortname(boardConfiguration->boardTestModeJumperPin));
|
||||
#endif /* EFI_PROD_CODE */
|
||||
|
||||
scheduleMsg(&logger, "isInjectionEnabledFlag %s", boolToString(engineConfiguration2->isInjectionEnabledFlag));
|
||||
|
@ -412,8 +415,8 @@ static void setIgnitionMode(int value) {
|
|||
doPrintConfiguration();
|
||||
}
|
||||
|
||||
static void setTotalToothCount(int value) {
|
||||
engineConfiguration->triggerConfig.totalToothCount = value;
|
||||
static void setToothedWheel(int total, int skipped) {
|
||||
setToothedWheelConfiguration(engineConfiguration, total, skipped);
|
||||
initializeTriggerShape(&logger, engineConfiguration, engineConfiguration2);
|
||||
incrementGlobalConfigurationVersion();
|
||||
doPrintConfiguration();
|
||||
|
@ -484,6 +487,23 @@ static void disableInjection(void) {
|
|||
scheduleMsg(&logger, "injection disabled");
|
||||
}
|
||||
|
||||
#if EFI_WAVE_CHART
|
||||
extern int waveChartUsedSize;
|
||||
#endif
|
||||
|
||||
static void printAllInfo(void) {
|
||||
printTemperatureInfo();
|
||||
printTPSInfo();
|
||||
printMAPInfo();
|
||||
#if EFI_WAVE_CHART
|
||||
scheduleMsg(&logger, "waveChartUsedSize=%d", waveChartUsedSize);
|
||||
#endif
|
||||
#if EFI_PROD_CODE
|
||||
scheduleMsg(&logger, "console mode jumper: %s", boolToString(!GET_CONSOLE_MODE_VALUE()));
|
||||
scheduleMsg(&logger, "board test mode jumper: %s", boolToString(GET_BOARD_TEST_MODE_VALUE()));
|
||||
#endif
|
||||
}
|
||||
|
||||
void initSettings(void) {
|
||||
initLoggingExt(&logger, "settings control", LOGGING_BUFFER, sizeof(LOGGING_BUFFER));
|
||||
|
||||
|
@ -491,6 +511,7 @@ void initSettings(void) {
|
|||
addConsoleAction("tempinfo", printTemperatureInfo);
|
||||
addConsoleAction("tpsinfo", printTPSInfo);
|
||||
addConsoleAction("mapinfo", printMAPInfo);
|
||||
addConsoleAction("info", printAllInfo);
|
||||
|
||||
addConsoleActionI("set_ignition_offset", setIgnitionOffset);
|
||||
addConsoleActionI("set_injection_offset", setInjectionOffset);
|
||||
|
@ -531,6 +552,6 @@ void initSettings(void) {
|
|||
|
||||
addConsoleAction("enable_injection", enableInjection);
|
||||
addConsoleAction("disable_injection", disableInjection);
|
||||
addConsoleActionI("set_total_tooth_count", setTotalToothCount);
|
||||
addConsoleActionII("set_toothed_wheel", setToothedWheel);
|
||||
}
|
||||
|
||||
|
|
|
@ -32,7 +32,7 @@ static void executorCallback(void *arg) {
|
|||
}
|
||||
|
||||
Executor::Executor() {
|
||||
reentrantLock = FALSE;
|
||||
reentrantLock = false;
|
||||
}
|
||||
|
||||
void Executor::lock(void) {
|
||||
|
@ -76,7 +76,7 @@ void Executor::doExecute(uint64_t nowUs) {
|
|||
firmwareError("Someone has stolen my lock");
|
||||
return;
|
||||
}
|
||||
reentrantLock = FALSE;
|
||||
reentrantLock = false;
|
||||
/**
|
||||
* Let's set up the timer for the next execution
|
||||
*/
|
||||
|
|
|
@ -18,7 +18,7 @@ public:
|
|||
void execute(uint64_t nowUs);
|
||||
private:
|
||||
EventQueue queue;
|
||||
bool_t reentrantLock;
|
||||
bool reentrantLock;
|
||||
void doExecute(uint64_t nowUs);
|
||||
void lock(void);
|
||||
void unlock(void);
|
||||
|
|
|
@ -18,7 +18,7 @@ EventQueue::EventQueue() {
|
|||
head = NULL;
|
||||
}
|
||||
|
||||
bool_t EventQueue::checkIfPending(scheduling_s *scheduling) {
|
||||
bool EventQueue::checkIfPending(scheduling_s *scheduling) {
|
||||
return assertNotInList<scheduling_s>(head, scheduling);
|
||||
}
|
||||
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
#define QUEUE_LENGTH_LIMIT 1000
|
||||
|
||||
template<typename T>
|
||||
bool_t assertNotInList(T *head, T*element) {
|
||||
bool assertNotInList(T *head, T*element) {
|
||||
// this code is just to validate state, no functional load
|
||||
T * current;
|
||||
int counter = 0;
|
||||
|
@ -48,7 +48,7 @@ public:
|
|||
int size(void);
|
||||
scheduling_s *getForUnitText(int index);
|
||||
private:
|
||||
bool_t checkIfPending(scheduling_s *scheduling);
|
||||
bool checkIfPending(scheduling_s *scheduling);
|
||||
scheduling_s *head;
|
||||
};
|
||||
|
||||
|
|
|
@ -46,7 +46,7 @@ void SimplePwm::setSimplePwmDutyCycle(float dutyCycle) {
|
|||
static uint64_t getNextSwitchTimeUs(PwmConfig *state) {
|
||||
efiAssert(state->safe.phaseIndex < PWM_PHASE_MAX_COUNT, "phaseIndex range", 0);
|
||||
int iteration = state->safe.iteration;
|
||||
float switchTime = state->multiWave.switchTimes[state->safe.phaseIndex];
|
||||
float switchTime = state->multiWave.getSwitchTime(state->safe.phaseIndex);
|
||||
float periodMs = state->safe.periodMs;
|
||||
#if DEBUG_PWM
|
||||
scheduleMsg(&logger, "iteration=%d switchTime=%f period=%f", iteration, switchTime, period);
|
||||
|
@ -131,7 +131,7 @@ void copyPwmParameters(PwmConfig *state, int phaseCount, float *switchTimes, int
|
|||
state->phaseCount = phaseCount;
|
||||
|
||||
for (int phaseIndex = 0; phaseIndex < phaseCount; phaseIndex++) {
|
||||
state->multiWave.switchTimes[phaseIndex] = switchTimes[phaseIndex];
|
||||
state->multiWave.setSwitchTime(phaseIndex, switchTimes[phaseIndex]);
|
||||
|
||||
for (int waveIndex = 0; waveIndex < waveCount; waveIndex++) {
|
||||
// print("output switch time index (%d/%d) at %f to %d\r\n", phaseIndex,waveIndex,
|
||||
|
|
|
@ -79,10 +79,12 @@ static Logging logger;
|
|||
|
||||
static void handleFuelInjectionEvent(MainTriggerCallback *mainTriggerCallback, ActuatorEvent *event, int rpm) {
|
||||
float fuelMs = getFuelMs(rpm) * mainTriggerCallback->engineConfiguration->globalFuelCorrection;
|
||||
if (cisnan(fuelMs)) {
|
||||
warning(OBD_PCM_Processor_Fault, "NaN injection pulse");
|
||||
return;
|
||||
}
|
||||
if (fuelMs < 0) {
|
||||
#if EFI_PROD_CODE
|
||||
scheduleMsg(&logger, "ERROR: negative injectionPeriod %f", fuelMs);
|
||||
#endif
|
||||
warning(OBD_PCM_Processor_Fault, "Negative injection pulse %f", fuelMs);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -128,8 +130,7 @@ static void handleSparkEvent(MainTriggerCallback *mainTriggerCallback, int event
|
|||
return;
|
||||
}
|
||||
|
||||
ActuatorEvent *event = &iEvent->actuator;
|
||||
float sparkDelay = getOneDegreeTimeMs(rpm) * event->position.angleOffset;
|
||||
float sparkDelay = getOneDegreeTimeMs(rpm) * iEvent->dwellPosition.angleOffset;
|
||||
int isIgnitionError = sparkDelay < 0;
|
||||
ignitionErrorDetection.add(isIgnitionError);
|
||||
if (isIgnitionError) {
|
||||
|
@ -140,9 +141,6 @@ static void handleSparkEvent(MainTriggerCallback *mainTriggerCallback, int event
|
|||
return;
|
||||
}
|
||||
|
||||
OutputSignal *signal = event->actuator;
|
||||
//scheduleOutput(event->actuator, sparkDelay, dwellMs);
|
||||
|
||||
if (cisnan(dwellMs)) {
|
||||
firmwareError("NaN in scheduleOutput", dwellMs);
|
||||
return;
|
||||
|
@ -152,13 +150,13 @@ static void handleSparkEvent(MainTriggerCallback *mainTriggerCallback, int event
|
|||
* We are alternating two event lists in order to avoid a potential issue around revolution boundary
|
||||
* when an event is scheduled within the next revolution.
|
||||
*/
|
||||
scheduling_s * sUp = &signal->signalTimerUp[0];
|
||||
scheduling_s * sDown = &signal->signalTimerDown[0];
|
||||
scheduling_s * sUp = &iEvent->signalTimerUp;
|
||||
scheduling_s * sDown = &iEvent->signalTimerDown;
|
||||
|
||||
/**
|
||||
* The start of charge is always within the current trigger event range, so just plain time-based scheduling
|
||||
*/
|
||||
scheduleTask(sUp, (int) MS2US(sparkDelay), (schfunc_t) &turnPinHigh, (void *) signal);
|
||||
scheduleTask(sUp, (int) MS2US(sparkDelay), (schfunc_t) &turnPinHigh, (void *) iEvent->io_pin);
|
||||
/**
|
||||
* Spark event is often happening during a later trigger event timeframe
|
||||
* TODO: improve precision
|
||||
|
@ -173,7 +171,7 @@ static void handleSparkEvent(MainTriggerCallback *mainTriggerCallback, int event
|
|||
*/
|
||||
float timeTillIgnitionUs = getOneDegreeTimeUs(rpm) * iEvent->sparkPosition.angleOffset;
|
||||
|
||||
scheduleTask(sDown, (int) timeTillIgnitionUs, (schfunc_t) &turnPinLow, (void*) signal);
|
||||
scheduleTask(sDown, (int) timeTillIgnitionUs, (schfunc_t) &turnPinLow, (void*) iEvent->io_pin);
|
||||
} else {
|
||||
/**
|
||||
* Spark should be scheduled in relation to some future trigger event, this way we get better firing precision
|
||||
|
@ -183,8 +181,6 @@ static void handleSparkEvent(MainTriggerCallback *mainTriggerCallback, int event
|
|||
return;
|
||||
|
||||
LL_APPEND(iHead, iEvent);
|
||||
|
||||
//scheduleTask(sDown, (int) MS2US(sparkDelay + dwellMs), (schfunc_t) &turnPinLow, (void*) signal);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -205,19 +201,17 @@ static void handleSpark(MainTriggerCallback *mainTriggerCallback, int eventIndex
|
|||
// time to fire a spark which was scheduled previously
|
||||
LL_DELETE(iHead, current);
|
||||
|
||||
ActuatorEvent *event = ¤t->actuator;
|
||||
OutputSignal *signal = event->actuator;
|
||||
scheduling_s * sDown = &signal->signalTimerDown[0];
|
||||
scheduling_s * sDown = ¤t->signalTimerDown;
|
||||
|
||||
float timeTillIgnitionUs = getOneDegreeTimeUs(rpm) * current->sparkPosition.angleOffset;
|
||||
scheduleTask(sDown, (int) timeTillIgnitionUs, (schfunc_t) &turnPinLow, (void*) signal);
|
||||
scheduleTask(sDown, (int) timeTillIgnitionUs, (schfunc_t) &turnPinLow, (void*) current->io_pin);
|
||||
}
|
||||
}
|
||||
|
||||
// scheduleSimpleMsg(&logger, "eventId spark ", eventIndex);
|
||||
for (int i = 0; i < list->size; i++) {
|
||||
IgnitionEvent *event = &list->events[i];
|
||||
if (event->actuator.position.eventIndex != eventIndex)
|
||||
if (event->dwellPosition.eventIndex != eventIndex)
|
||||
continue;
|
||||
handleSparkEvent(mainTriggerCallback, eventIndex, event, rpm);
|
||||
}
|
||||
|
@ -303,9 +297,14 @@ void onTriggerEvent(trigger_event_e ckpSignalType, int eventIndex, MainTriggerCa
|
|||
#endif /* EFI_HISTOGRAMS */
|
||||
}
|
||||
|
||||
#include "wave_chart.h"
|
||||
|
||||
static void showTriggerHistogram(void) {
|
||||
printAllCallbacksHistogram();
|
||||
showMainHistogram();
|
||||
#if EFI_PROD_CODE
|
||||
showWaveChartHistogram();
|
||||
#endif
|
||||
}
|
||||
|
||||
static void showMainInfo(void) {
|
||||
|
|
|
@ -131,16 +131,16 @@ static char shaft_signal_msg_index[15];
|
|||
* updated here.
|
||||
* This callback is invoked on interrupt thread.
|
||||
*/
|
||||
void shaftPositionCallback(trigger_event_e ckpSignalType, int index, RpmCalculator *rpmState) {
|
||||
void rpmShaftPositionCallback(trigger_event_e ckpSignalType, int index, RpmCalculator *rpmState) {
|
||||
itoa10(&shaft_signal_msg_index[1], index);
|
||||
if (ckpSignalType == SHAFT_PRIMARY_UP) {
|
||||
addWaveChartEvent("crank", "up", (char*) shaft_signal_msg_index);
|
||||
addWaveChartEvent(WC_CRANK1, WC_UP, (char*) shaft_signal_msg_index);
|
||||
} else if (ckpSignalType == SHAFT_PRIMARY_DOWN) {
|
||||
addWaveChartEvent("crank", "down", (char*) shaft_signal_msg_index);
|
||||
addWaveChartEvent(WC_CRANK1, WC_DOWN, (char*) shaft_signal_msg_index);
|
||||
} else if (ckpSignalType == SHAFT_SECONDARY_UP) {
|
||||
addWaveChartEvent("crank2", "up", (char*) shaft_signal_msg_index);
|
||||
addWaveChartEvent(WC_CRANK2, WC_UP, (char*) shaft_signal_msg_index);
|
||||
} else if (ckpSignalType == SHAFT_SECONDARY_DOWN) {
|
||||
addWaveChartEvent("crank2", "down", (char*) shaft_signal_msg_index);
|
||||
addWaveChartEvent(WC_CRANK2, WC_DOWN, (char*) shaft_signal_msg_index);
|
||||
}
|
||||
|
||||
if (index != 0) {
|
||||
|
@ -154,7 +154,7 @@ void shaftPositionCallback(trigger_event_e ckpSignalType, int index, RpmCalculat
|
|||
|
||||
uint64_t nowUs = getTimeNowUs();
|
||||
|
||||
bool_t hadRpmRecently = rpmState->isRunning();
|
||||
bool hadRpmRecently = rpmState->isRunning();
|
||||
|
||||
if (hadRpmRecently) {
|
||||
if (isNoisySignal(rpmState, nowUs)) {
|
||||
|
@ -210,7 +210,7 @@ void initRpmCalculator(void) {
|
|||
|
||||
strcpy((char*) shaft_signal_msg_index, "_");
|
||||
|
||||
addTriggerEventListener((ShaftPositionListener)&shaftPositionCallback, "rpm reporter", &rpmState);
|
||||
addTriggerEventListener((ShaftPositionListener)&rpmShaftPositionCallback, "rpm reporter", &rpmState);
|
||||
}
|
||||
|
||||
#if EFI_PROD_CODE || EFI_SIMULATOR
|
||||
|
|
|
@ -11,6 +11,11 @@
|
|||
|
||||
#include <time.h>
|
||||
|
||||
#define WC_DOWN "d"
|
||||
#define WC_UP "u"
|
||||
#define WC_CRANK1 "c1"
|
||||
#define WC_CRANK2 "c2"
|
||||
|
||||
#define NOISY_RPM -1
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -36,7 +41,7 @@ public:
|
|||
* @brief Current RPM
|
||||
*/
|
||||
int getRpmE(Engine *engine);
|
||||
void shaftPositionCallback(trigger_event_e ckpSignalType, int index, RpmCalculator *rpmState);
|
||||
void rpmShaftPositionCallback(trigger_event_e ckpSignalType, int index, RpmCalculator *rpmState);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -15,11 +15,10 @@ static inline float addPair(trigger_shape_s *s, float a, float w) {
|
|||
return a;
|
||||
}
|
||||
|
||||
void configureMiniCooperTriggerShape(engine_configuration_s *engineConfiguration,
|
||||
engine_configuration2_s *engineConfiguration2) {
|
||||
trigger_shape_s *s = &engineConfiguration2->triggerShape;
|
||||
void configureMiniCooperTriggerShape(trigger_config_s *triggerConfig,
|
||||
trigger_shape_s *s) {
|
||||
|
||||
s->reset();
|
||||
s->reset(FOUR_STROKE_CAM_SENSOR);
|
||||
|
||||
// s->initialState[0] = 1;
|
||||
|
||||
|
@ -68,5 +67,5 @@ void configureMiniCooperTriggerShape(engine_configuration_s *engineConfiguration
|
|||
/**
|
||||
* With just one tooth on camshaft synchronization is not needed
|
||||
*/
|
||||
engineConfiguration->triggerConfig.isSynchronizationNeeded = FALSE;
|
||||
triggerConfig->isSynchronizationNeeded = FALSE;
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
#include "engine_configuration.h"
|
||||
#include "ec2.h"
|
||||
|
||||
void configureMiniCooperTriggerShape(engine_configuration_s *engineConfiguration,
|
||||
engine_configuration2_s *engineConfiguration2);
|
||||
void configureMiniCooperTriggerShape(trigger_config_s *triggerConfig,
|
||||
trigger_shape_s *s);
|
||||
|
||||
#endif /* TRIGGER_BMW_H_ */
|
||||
|
|
|
@ -88,9 +88,9 @@ void TriggerCentral::handleShaftSignal(configuration_s *configuration, trigger_e
|
|||
trigger_shape_s * triggerShape = &configuration->engineConfiguration2->triggerShape;
|
||||
|
||||
/**
|
||||
* This invocation changes the state of
|
||||
* This invocation changes the state of triggerState
|
||||
*/
|
||||
triggerState.processTriggerEvent(triggerShape, &configuration->engineConfiguration->triggerConfig, signal, nowUs);
|
||||
triggerState.decodeTriggerEvent(triggerShape, &configuration->engineConfiguration->triggerConfig, signal, nowUs);
|
||||
|
||||
if (!triggerState.shaft_is_synchronized)
|
||||
return; // we should not propagate event if we do not know where we are
|
||||
|
|
|
@ -30,17 +30,19 @@ private:
|
|||
};
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
void addTriggerEventListener(ShaftPositionListener handler, const char *name, void *arg);
|
||||
uint64_t getCrankEventCounter(void);
|
||||
uint64_t getStartOfRevolutionIndex(void);
|
||||
int isSignalDecoderError(void);
|
||||
void hwHandleShaftSignal(trigger_event_e signal);
|
||||
void initTriggerCentral(void);
|
||||
void printAllCallbacksHistogram(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
void addTriggerEventListener(ShaftPositionListener handler, const char *name, void *arg);
|
||||
int isSignalDecoderError(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
|
|
@ -7,59 +7,59 @@
|
|||
|
||||
#include "trigger_chrysler.h"
|
||||
|
||||
void configureNeonTriggerShape(trigger_shape_s *s) {
|
||||
s->reset();
|
||||
void configureNeonTriggerShape(trigger_config_s *triggerConfig, trigger_shape_s *s) {
|
||||
s->reset(FOUR_STROKE_CAM_SENSOR);
|
||||
|
||||
// voodoo magic - we always need 720 at the end
|
||||
int base = 720 - 560;
|
||||
|
||||
s->initialState[0] = 1;
|
||||
|
||||
triggerAddEvent(s, base - 720 + 600, T_SECONDARY, TV_HIGH);
|
||||
triggerAddEvent(s, base - 720 + 604, T_SECONDARY, TV_LOW);
|
||||
triggerAddEvent(s, base - 720 + 616, T_SECONDARY, TV_HIGH);
|
||||
triggerAddEvent(s, base - 720 + 620, T_SECONDARY, TV_LOW);
|
||||
triggerAddEvent(s, base - 720 + 643, T_SECONDARY, TV_HIGH);
|
||||
triggerAddEvent(s, base - 720 + 648, T_SECONDARY, TV_LOW);
|
||||
triggerAddEvent(s, base - 720 + 671, T_SECONDARY, TV_HIGH);
|
||||
triggerAddEvent(s, base - 720 + 676, T_SECONDARY, TV_LOW);
|
||||
s->addEvent(base - 720 + 600, T_SECONDARY, TV_HIGH);
|
||||
s->addEvent(base - 720 + 604, T_SECONDARY, TV_LOW);
|
||||
s->addEvent(base - 720 + 616, T_SECONDARY, TV_HIGH);
|
||||
s->addEvent(base - 720 + 620, T_SECONDARY, TV_LOW);
|
||||
s->addEvent(base - 720 + 643, T_SECONDARY, TV_HIGH);
|
||||
s->addEvent(base - 720 + 648, T_SECONDARY, TV_LOW);
|
||||
s->addEvent(base - 720 + 671, T_SECONDARY, TV_HIGH);
|
||||
s->addEvent(base - 720 + 676, T_SECONDARY, TV_LOW);
|
||||
|
||||
triggerAddEvent(s, base + 0, T_PRIMARY, TV_LOW);
|
||||
s->addEvent(base + 0, T_PRIMARY, TV_LOW);
|
||||
|
||||
triggerAddEvent(s, base + 20, T_SECONDARY, TV_HIGH);
|
||||
triggerAddEvent(s, base + 60, T_SECONDARY, TV_LOW);
|
||||
triggerAddEvent(s, base + 75, T_SECONDARY, TV_HIGH);
|
||||
triggerAddEvent(s, base + 79, T_SECONDARY, TV_LOW);
|
||||
triggerAddEvent(s, base + 101, T_SECONDARY, TV_HIGH);
|
||||
triggerAddEvent(s, base + 106, T_SECONDARY, TV_LOW);
|
||||
triggerAddEvent(s, base + 130, T_SECONDARY, TV_HIGH);
|
||||
triggerAddEvent(s, base + 135, T_SECONDARY, TV_LOW);
|
||||
s->addEvent(base + 20, T_SECONDARY, TV_HIGH);
|
||||
s->addEvent(base + 60, T_SECONDARY, TV_LOW);
|
||||
s->addEvent(base + 75, T_SECONDARY, TV_HIGH);
|
||||
s->addEvent(base + 79, T_SECONDARY, TV_LOW);
|
||||
s->addEvent(base + 101, T_SECONDARY, TV_HIGH);
|
||||
s->addEvent(base + 106, T_SECONDARY, TV_LOW);
|
||||
s->addEvent(base + 130, T_SECONDARY, TV_HIGH);
|
||||
s->addEvent(base + 135, T_SECONDARY, TV_LOW);
|
||||
|
||||
triggerAddEvent(s, base + 200, T_PRIMARY, TV_HIGH); // width = 150
|
||||
s->addEvent(base + 200, T_PRIMARY, TV_HIGH); // width = 150
|
||||
|
||||
triggerAddEvent(s, base + 236, T_SECONDARY, TV_HIGH);
|
||||
triggerAddEvent(s, base + 239, T_SECONDARY, TV_LOW);
|
||||
triggerAddEvent(s, base + 250, T_SECONDARY, TV_HIGH);
|
||||
triggerAddEvent(s, base + 255, T_SECONDARY, TV_LOW);
|
||||
triggerAddEvent(s, base + 277, T_SECONDARY, TV_HIGH);
|
||||
triggerAddEvent(s, base + 282, T_SECONDARY, TV_LOW);
|
||||
triggerAddEvent(s, base + 305, T_SECONDARY, TV_HIGH);
|
||||
triggerAddEvent(s, base + 310, T_SECONDARY, TV_LOW);
|
||||
s->addEvent(base + 236, T_SECONDARY, TV_HIGH);
|
||||
s->addEvent(base + 239, T_SECONDARY, TV_LOW);
|
||||
s->addEvent(base + 250, T_SECONDARY, TV_HIGH);
|
||||
s->addEvent(base + 255, T_SECONDARY, TV_LOW);
|
||||
s->addEvent(base + 277, T_SECONDARY, TV_HIGH);
|
||||
s->addEvent(base + 282, T_SECONDARY, TV_LOW);
|
||||
s->addEvent(base + 305, T_SECONDARY, TV_HIGH);
|
||||
s->addEvent(base + 310, T_SECONDARY, TV_LOW);
|
||||
|
||||
triggerAddEvent(s, base + 374, T_SECONDARY, TV_HIGH);
|
||||
s->addEvent(base + 374, T_SECONDARY, TV_HIGH);
|
||||
|
||||
triggerAddEvent(s, base + 395, T_PRIMARY, TV_LOW); // width =
|
||||
s->addEvent(base + 395, T_PRIMARY, TV_LOW); // width =
|
||||
|
||||
triggerAddEvent(s, base + 418, T_SECONDARY, TV_LOW);
|
||||
triggerAddEvent(s, base + 436, T_SECONDARY, TV_HIGH);
|
||||
triggerAddEvent(s, base + 441, T_SECONDARY, TV_LOW);
|
||||
triggerAddEvent(s, base + 463, T_SECONDARY, TV_HIGH);
|
||||
triggerAddEvent(s, base + 468, T_SECONDARY, TV_LOW);
|
||||
triggerAddEvent(s, base + 492, T_SECONDARY, TV_HIGH);
|
||||
triggerAddEvent(s, base + 497, T_SECONDARY, TV_LOW);
|
||||
s->addEvent(base + 418, T_SECONDARY, TV_LOW);
|
||||
s->addEvent(base + 436, T_SECONDARY, TV_HIGH);
|
||||
s->addEvent(base + 441, T_SECONDARY, TV_LOW);
|
||||
s->addEvent(base + 463, T_SECONDARY, TV_HIGH);
|
||||
s->addEvent(base + 468, T_SECONDARY, TV_LOW);
|
||||
s->addEvent(base + 492, T_SECONDARY, TV_HIGH);
|
||||
s->addEvent(base + 497, T_SECONDARY, TV_LOW);
|
||||
|
||||
|
||||
triggerAddEvent(s, base + 560, T_PRIMARY, TV_HIGH); // width =
|
||||
s->addEvent(base + 560, T_PRIMARY, TV_HIGH); // width =
|
||||
|
||||
s->shaftPositionEventCount = 4 + 8 + 8 + 8 + 8;
|
||||
}
|
||||
|
|
|
@ -10,6 +10,6 @@
|
|||
|
||||
#include "trigger_structure.h"
|
||||
|
||||
void configureNeonTriggerShape(trigger_shape_s *s);
|
||||
void configureNeonTriggerShape(trigger_config_s *triggerConfig, trigger_shape_s *s);
|
||||
|
||||
#endif /* TRIGGER_CHRYSLER_H_ */
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* @file trigger_decoder.c
|
||||
* @file trigger_decoder.cpp
|
||||
*
|
||||
* @date Dec 24, 2013
|
||||
* @author Andrey Belomutskiy, (c) 2012-2014
|
||||
|
@ -48,7 +48,7 @@ int isTriggerDecoderError(void) {
|
|||
static inline int isSynchronizationGap(TriggerState const *shaftPositionState, trigger_shape_s const *triggerShape,
|
||||
trigger_config_s const *triggerConfig, const int currentDuration) {
|
||||
if (!triggerConfig->isSynchronizationNeeded)
|
||||
return FALSE;
|
||||
return false;
|
||||
|
||||
return currentDuration > shaftPositionState->toothed_previous_duration * triggerConfig->syncRatioFrom
|
||||
&& currentDuration < shaftPositionState->toothed_previous_duration * triggerConfig->syncRatioTo;
|
||||
|
@ -57,7 +57,7 @@ static inline int isSynchronizationGap(TriggerState const *shaftPositionState, t
|
|||
static inline int noSynchronizationResetNeeded(TriggerState *shaftPositionState, trigger_shape_s const *triggerShape,
|
||||
trigger_config_s const*triggerConfig) {
|
||||
if (triggerConfig->isSynchronizationNeeded)
|
||||
return FALSE;
|
||||
return false;
|
||||
if (!shaftPositionState->shaft_is_synchronized)
|
||||
return TRUE;
|
||||
/**
|
||||
|
@ -67,9 +67,10 @@ static inline int noSynchronizationResetNeeded(TriggerState *shaftPositionState,
|
|||
}
|
||||
|
||||
/**
|
||||
* @brief This method changes the state of trigger_state_s data structure according to the trigger event
|
||||
* @brief Trigger decoding happends here
|
||||
* This method changes the state of trigger_state_s data structure according to the trigger event
|
||||
*/
|
||||
void TriggerState::processTriggerEvent(trigger_shape_s const*triggerShape, trigger_config_s const*triggerConfig,
|
||||
void TriggerState::decodeTriggerEvent(trigger_shape_s const*triggerShape, trigger_config_s const*triggerConfig,
|
||||
trigger_event_e signal, uint64_t nowUs) {
|
||||
|
||||
int isLessImportant = (triggerConfig->useRiseEdge && signal != SHAFT_PRIMARY_UP)
|
||||
|
@ -83,7 +84,8 @@ void TriggerState::processTriggerEvent(trigger_shape_s const*triggerShape, trigg
|
|||
return;
|
||||
}
|
||||
|
||||
int64_t currentDuration = nowUs - toothed_previous_time;
|
||||
int64_t currentDuration = isFirstEvent ? 0 : nowUs - toothed_previous_time;
|
||||
isFirstEvent = false;
|
||||
efiAssertVoid(currentDuration >= 0, "negative duration?");
|
||||
|
||||
// todo: skip a number of signal from the beginning
|
||||
|
@ -119,51 +121,51 @@ void TriggerState::processTriggerEvent(trigger_shape_s const*triggerShape, trigg
|
|||
toothed_previous_time = nowUs;
|
||||
}
|
||||
|
||||
static void initializeSkippedToothTriggerShape(trigger_shape_s *s, int totalTeethCount, int skippedCount) {
|
||||
static void initializeSkippedToothTriggerShape(trigger_shape_s *s, int totalTeethCount, int skippedCount, operation_mode_e operationMode) {
|
||||
efiAssertVoid(s != NULL, "trigger_shape_s is NULL");
|
||||
s->reset();
|
||||
s->reset(operationMode);
|
||||
|
||||
float toothWidth = 0.5;
|
||||
|
||||
for (int i = 0; i < totalTeethCount - skippedCount - 1; i++) {
|
||||
float angleDown = 720.0 / totalTeethCount * (i + toothWidth);
|
||||
float angleUp = 720.0 / totalTeethCount * (i + 1);
|
||||
triggerAddEvent(s, angleDown, T_PRIMARY, TV_HIGH);
|
||||
triggerAddEvent(s, angleUp, T_PRIMARY, TV_LOW);
|
||||
s->addEvent(angleDown, T_PRIMARY, TV_HIGH);
|
||||
s->addEvent(angleUp, T_PRIMARY, TV_LOW);
|
||||
}
|
||||
|
||||
float angleDown = 720.0 / totalTeethCount * (totalTeethCount - skippedCount - 1 + toothWidth);
|
||||
triggerAddEvent(s, angleDown, T_PRIMARY, TV_HIGH);
|
||||
triggerAddEvent(s, 720, T_PRIMARY, TV_LOW);
|
||||
s->addEvent(angleDown, T_PRIMARY, TV_HIGH);
|
||||
s->addEvent(720, T_PRIMARY, TV_LOW);
|
||||
}
|
||||
|
||||
void initializeSkippedToothTriggerShapeExt(engine_configuration2_s *engineConfiguration2, int totalTeethCount,
|
||||
int skippedCount) {
|
||||
int skippedCount, operation_mode_e operationMode) {
|
||||
efiAssertVoid(totalTeethCount > 0, "totalTeethCount is zero");
|
||||
|
||||
trigger_shape_s *s = &engineConfiguration2->triggerShape;
|
||||
initializeSkippedToothTriggerShape(s, totalTeethCount, skippedCount);
|
||||
initializeSkippedToothTriggerShape(s, totalTeethCount, skippedCount, operationMode);
|
||||
|
||||
s->shaftPositionEventCount = ((totalTeethCount - skippedCount) * 2);
|
||||
s->wave.checkSwitchTimes(s->getSize());
|
||||
}
|
||||
|
||||
static void configureFordAspireTriggerShape(trigger_shape_s * s) {
|
||||
s->reset();
|
||||
static void configureFordAspireTriggerShape(trigger_config_s *triggerConfig, trigger_shape_s * s) {
|
||||
s->reset(FOUR_STROKE_CAM_SENSOR);
|
||||
|
||||
s->shaftPositionEventCount = 10;
|
||||
|
||||
triggerAddEvent(s, 53.747, T_SECONDARY, TV_HIGH);
|
||||
triggerAddEvent(s, 121.90, T_SECONDARY, TV_LOW); // delta = 68.153
|
||||
triggerAddEvent(s, 232.76, T_SECONDARY, TV_HIGH); // delta = 110.86
|
||||
triggerAddEvent(s, 300.54, T_SECONDARY, TV_LOW); // delta = 67.78
|
||||
triggerAddEvent(s, 360, T_PRIMARY, TV_HIGH);
|
||||
s->addEvent(53.747, T_SECONDARY, TV_HIGH);
|
||||
s->addEvent(121.90, T_SECONDARY, TV_LOW); // delta = 68.153
|
||||
s->addEvent(232.76, T_SECONDARY, TV_HIGH); // delta = 110.86
|
||||
s->addEvent(300.54, T_SECONDARY, TV_LOW); // delta = 67.78
|
||||
s->addEvent(360, T_PRIMARY, TV_HIGH);
|
||||
|
||||
triggerAddEvent(s, 409.8412, T_SECONDARY, TV_HIGH); // delta = 49.8412
|
||||
triggerAddEvent(s, 478.6505, T_SECONDARY, TV_LOW); // delta = 68.8093
|
||||
triggerAddEvent(s, 588.045, T_SECONDARY, TV_HIGH); // delta = 109.3945
|
||||
triggerAddEvent(s, 657.03, T_SECONDARY, TV_LOW);
|
||||
triggerAddEvent(s, 720, T_PRIMARY, TV_LOW);
|
||||
s->addEvent(409.8412, T_SECONDARY, TV_HIGH); // delta = 49.8412
|
||||
s->addEvent(478.6505, T_SECONDARY, TV_LOW); // delta = 68.8093
|
||||
s->addEvent(588.045, T_SECONDARY, TV_HIGH); // delta = 109.3945
|
||||
s->addEvent(657.03, T_SECONDARY, TV_LOW);
|
||||
s->addEvent(720, T_PRIMARY, TV_LOW);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -174,45 +176,75 @@ void initializeTriggerShape(Logging *logger, engine_configuration_s *engineConfi
|
|||
#if EFI_PROD_CODE
|
||||
printMsg(logger, "initializeTriggerShape()");
|
||||
#endif
|
||||
trigger_config_s *tt = &engineConfiguration->triggerConfig;
|
||||
switch (tt->triggerType) {
|
||||
trigger_config_s *triggerConfig = &engineConfiguration->triggerConfig;
|
||||
trigger_shape_s *triggerShape = &engineConfiguration2->triggerShape;
|
||||
switch (triggerConfig->triggerType) {
|
||||
|
||||
case TT_TOOTHED_WHEEL:
|
||||
initializeSkippedToothTriggerShapeExt(engineConfiguration2, tt->totalToothCount, tt->skippedToothCount);
|
||||
initializeSkippedToothTriggerShapeExt(engineConfiguration2, triggerConfig->totalToothCount, triggerConfig->skippedToothCount,
|
||||
getOperationMode(engineConfiguration));
|
||||
return;
|
||||
|
||||
case TT_MAZDA_MIATA_NB:
|
||||
initializeMazdaMiataNbShape(&engineConfiguration2->triggerShape);
|
||||
initializeMazdaMiataNbShape(triggerConfig, triggerShape);
|
||||
return;
|
||||
|
||||
case TT_DODGE_NEON:
|
||||
configureNeonTriggerShape(&engineConfiguration2->triggerShape);
|
||||
configureNeonTriggerShape(triggerConfig, triggerShape);
|
||||
return;
|
||||
|
||||
case TT_FORD_ASPIRE:
|
||||
configureFordAspireTriggerShape(&engineConfiguration2->triggerShape);
|
||||
configureFordAspireTriggerShape(triggerConfig, triggerShape);
|
||||
return;
|
||||
|
||||
case TT_GM_7X:
|
||||
configureGmTriggerShape(&engineConfiguration2->triggerShape);
|
||||
configureGmTriggerShape(triggerConfig, triggerShape);
|
||||
return;
|
||||
|
||||
case TT_FORD_ESCORT_GT:
|
||||
configureMazdaProtegeLx(engineConfiguration, engineConfiguration2);
|
||||
configureMazdaProtegeLx(triggerConfig, triggerShape);
|
||||
return;
|
||||
|
||||
case TT_MINI_COOPER_R50:
|
||||
configureMiniCooperTriggerShape(engineConfiguration, engineConfiguration2);
|
||||
configureMiniCooperTriggerShape(triggerConfig, triggerShape);
|
||||
return;
|
||||
|
||||
default:
|
||||
firmwareError("initializeTriggerShape() not implemented: %d", tt->triggerType);
|
||||
firmwareError("initializeTriggerShape() not implemented: %d", triggerConfig->triggerType);
|
||||
;
|
||||
}
|
||||
if (engineConfiguration2->triggerShape.shaftPositionEventCount != engineConfiguration2->triggerShape.getSize())
|
||||
firmwareError("trigger size or shaftPositionEventCount?");
|
||||
}
|
||||
|
||||
TriggerStimulatorHelper::TriggerStimulatorHelper() {
|
||||
primaryWheelState = false;
|
||||
secondaryWheelState = false;
|
||||
}
|
||||
|
||||
void TriggerStimulatorHelper::nextStep(TriggerState *state, trigger_shape_s * shape, int i, trigger_config_s const*triggerConfig) {
|
||||
int stateIndex = i % shape->getSize();
|
||||
|
||||
int loopIndex = i / shape->getSize();
|
||||
|
||||
int time = (int) (10000 * (loopIndex + shape->wave.getSwitchTime(stateIndex)));
|
||||
|
||||
bool newPrimaryWheelState = shape->wave.getChannelState(0, stateIndex);
|
||||
bool newSecondaryWheelState = shape->wave.getChannelState(1, stateIndex);
|
||||
|
||||
if (primaryWheelState != newPrimaryWheelState) {
|
||||
primaryWheelState = newPrimaryWheelState;
|
||||
trigger_event_e s = primaryWheelState ? SHAFT_PRIMARY_UP : SHAFT_PRIMARY_DOWN;
|
||||
state->decodeTriggerEvent(shape, triggerConfig, s, time);
|
||||
}
|
||||
|
||||
if (secondaryWheelState != newSecondaryWheelState) {
|
||||
secondaryWheelState = newSecondaryWheelState;
|
||||
trigger_event_e s = secondaryWheelState ? SHAFT_SECONDARY_UP : SHAFT_SECONDARY_DOWN;
|
||||
state->decodeTriggerEvent(shape, triggerConfig, s, time);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Trigger shape is defined in a way which is convenient for trigger shape definition
|
||||
* On the other hand, trigger decoder indexing begins from synchronization event.
|
||||
|
@ -224,34 +256,13 @@ int findTriggerZeroEventIndex(trigger_shape_s * shape, trigger_config_s const*tr
|
|||
TriggerState state;
|
||||
errorDetection.clear();
|
||||
|
||||
int primaryWheelState = FALSE;
|
||||
int secondaryWheelState = FALSE;
|
||||
TriggerStimulatorHelper helper;
|
||||
|
||||
for (int i = 0; i < 4 * PWM_PHASE_MAX_COUNT; i++) {
|
||||
|
||||
int stateIndex = i % shape->getSize();
|
||||
|
||||
int loopIndex = i / shape->getSize();
|
||||
|
||||
int time = (int) (10000 * (loopIndex + shape->wave.getSwitchTime(stateIndex)));
|
||||
|
||||
int newPrimaryWheelState = shape->wave.getChannelState(0, stateIndex);
|
||||
int newSecondaryWheelState = shape->wave.getChannelState(1, stateIndex);
|
||||
|
||||
if (primaryWheelState != newPrimaryWheelState) {
|
||||
primaryWheelState = newPrimaryWheelState;
|
||||
trigger_event_e s = primaryWheelState ? SHAFT_PRIMARY_UP : SHAFT_PRIMARY_DOWN;
|
||||
state.processTriggerEvent(shape, triggerConfig, s, time);
|
||||
}
|
||||
|
||||
if (secondaryWheelState != newSecondaryWheelState) {
|
||||
secondaryWheelState = newSecondaryWheelState;
|
||||
trigger_event_e s = secondaryWheelState ? SHAFT_SECONDARY_UP : SHAFT_SECONDARY_DOWN;
|
||||
state.processTriggerEvent(shape, triggerConfig, s, time);
|
||||
}
|
||||
helper.nextStep(&state, shape, i, triggerConfig);
|
||||
|
||||
if (state.shaft_is_synchronized)
|
||||
return stateIndex;
|
||||
return i % shape->getSize();;
|
||||
}
|
||||
firmwareError("findTriggerZeroEventIndex() failed");
|
||||
return -1;
|
||||
|
|
|
@ -14,19 +14,29 @@
|
|||
#include "engine_configuration.h"
|
||||
#include "ec2.h"
|
||||
|
||||
class TriggerStimulatorHelper {
|
||||
public:
|
||||
TriggerStimulatorHelper();
|
||||
void nextStep(TriggerState *state, trigger_shape_s * shape, int i, trigger_config_s const*triggerConfig);
|
||||
private:
|
||||
bool primaryWheelState;
|
||||
bool secondaryWheelState;
|
||||
};
|
||||
|
||||
void initializeSkippedToothTriggerShapeExt(engine_configuration2_s *engineConfiguration2, int totalTeethCount, int skippedCount, operation_mode_e operationMode);
|
||||
int 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);
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
int isTriggerDecoderError(void);
|
||||
void initializeSkippedToothTriggerShapeExt(engine_configuration2_s *engineConfiguration2, int totalTeethCount, int skippedCount);
|
||||
void initializeTriggerShape(Logging *logger, engine_configuration_s *engineConfiguration, engine_configuration2_s *engineConfiguration2);
|
||||
int findTriggerZeroEventIndex(trigger_shape_s * shape, trigger_config_s const*triggerConfig);
|
||||
|
||||
void initTriggerDecoder(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* TRIGGER_DECODER_H_ */
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* @file trigger_emulator_algo.c
|
||||
* @file trigger_emulator_algo.cpp
|
||||
*
|
||||
* @date Mar 3, 2014
|
||||
* @author Andrey Belomutskiy, (c) 2012-2014
|
||||
|
@ -61,7 +61,7 @@ void initTriggerEmulatorLogic(pwm_gen_callback *stateChangeCallback) {
|
|||
|
||||
trigger_shape_s *s = &engineConfiguration2->triggerShape;
|
||||
setTriggerEmulatorRPM(DEFAULT_EMULATION_RPM);
|
||||
int *pinStates[2] = {s->wave.waves[0].pinStates, s->wave.waves[1].pinStates};
|
||||
int *pinStates[2] = { s->wave.waves[0].pinStates, s->wave.waves[1].pinStates};
|
||||
weComplexInit("position sensor", &triggerSignal, s->getSize(), s->wave.switchTimes, 2, pinStates,
|
||||
updateTriggerShapeIfNeeded,
|
||||
stateChangeCallback);
|
||||
|
|
|
@ -7,34 +7,34 @@
|
|||
|
||||
#include "trigger_gm.h"
|
||||
|
||||
void configureGmTriggerShape(trigger_shape_s *s) {
|
||||
s->reset();
|
||||
void configureGmTriggerShape(trigger_config_s *triggerConfig, trigger_shape_s *s) {
|
||||
s->reset(FOUR_STROKE_CAM_SENSOR);
|
||||
|
||||
// all angles are x2 here - so, 5 degree width is 10
|
||||
float w = 10;
|
||||
|
||||
s->shaftPositionEventCount = 14;
|
||||
|
||||
triggerAddEvent(s, 120 - w, T_PRIMARY, TV_HIGH);
|
||||
triggerAddEvent(s, 120, T_PRIMARY, TV_LOW);
|
||||
s->addEvent(120 - w, T_PRIMARY, TV_HIGH);
|
||||
s->addEvent(120, T_PRIMARY, TV_LOW);
|
||||
|
||||
triggerAddEvent(s, 240 - w, T_PRIMARY, TV_HIGH);
|
||||
triggerAddEvent(s, 240, T_PRIMARY, TV_LOW);
|
||||
s->addEvent(240 - w, T_PRIMARY, TV_HIGH);
|
||||
s->addEvent(240, T_PRIMARY, TV_LOW);
|
||||
|
||||
triggerAddEvent(s, 360 - w, T_PRIMARY, TV_HIGH);
|
||||
triggerAddEvent(s, 360, T_PRIMARY, TV_LOW);
|
||||
s->addEvent(360 - w, T_PRIMARY, TV_HIGH);
|
||||
s->addEvent(360, T_PRIMARY, TV_LOW);
|
||||
|
||||
triggerAddEvent(s, 480 - w, T_PRIMARY, TV_HIGH);
|
||||
triggerAddEvent(s, 480, T_PRIMARY, TV_LOW);
|
||||
s->addEvent(480 - w, T_PRIMARY, TV_HIGH);
|
||||
s->addEvent(480, T_PRIMARY, TV_LOW);
|
||||
|
||||
triggerAddEvent(s, 600 - w, T_PRIMARY, TV_HIGH);
|
||||
triggerAddEvent(s, 600, T_PRIMARY, TV_LOW);
|
||||
s->addEvent(600 - w, T_PRIMARY, TV_HIGH);
|
||||
s->addEvent(600, T_PRIMARY, TV_LOW);
|
||||
|
||||
triggerAddEvent(s, 700 - w, T_PRIMARY, TV_HIGH);
|
||||
triggerAddEvent(s, 700, T_PRIMARY, TV_LOW);
|
||||
s->addEvent(700 - w, T_PRIMARY, TV_HIGH);
|
||||
s->addEvent(700, T_PRIMARY, TV_LOW);
|
||||
|
||||
triggerAddEvent(s, 720 - w, T_PRIMARY, TV_HIGH);
|
||||
triggerAddEvent(s, 720, T_PRIMARY, TV_LOW);
|
||||
s->addEvent(720 - w, T_PRIMARY, TV_HIGH);
|
||||
s->addEvent(720, T_PRIMARY, TV_LOW);
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -10,6 +10,6 @@
|
|||
|
||||
#include "trigger_structure.h"
|
||||
|
||||
void configureGmTriggerShape(trigger_shape_s *s);
|
||||
void configureGmTriggerShape(trigger_config_s *triggerConfig, trigger_shape_s *s);
|
||||
|
||||
#endif /* TRIGGER_GM_H_ */
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* @file trigger_mazda.c
|
||||
* @file trigger_mazda.cpp
|
||||
*
|
||||
* @date Feb 18, 2014
|
||||
* @author Andrey Belomutskiy, (c) 2012-2014
|
||||
|
@ -20,78 +20,75 @@
|
|||
|
||||
#include "trigger_mazda.h"
|
||||
|
||||
void initializeMazdaMiataNbShape(trigger_shape_s *s) {
|
||||
s->reset();
|
||||
void initializeMazdaMiataNbShape(trigger_config_s *triggerConfig, trigger_shape_s *s) {
|
||||
s->reset(FOUR_STROKE_CAM_SENSOR);
|
||||
|
||||
/**
|
||||
* cam sensor is primary, crank sensor is secondary
|
||||
*/
|
||||
triggerAddEvent(s, 20, T_PRIMARY, TV_HIGH);
|
||||
s->addEvent(20, T_PRIMARY, TV_HIGH);
|
||||
|
||||
triggerAddEvent(s, 66, T_SECONDARY, TV_LOW);
|
||||
triggerAddEvent(s, 70, T_SECONDARY, TV_HIGH);
|
||||
triggerAddEvent(s, 136, T_SECONDARY, TV_LOW);
|
||||
triggerAddEvent(s, 140, T_SECONDARY, TV_HIGH);
|
||||
triggerAddEvent(s, 246, T_SECONDARY, TV_LOW);
|
||||
triggerAddEvent(s, 250, T_SECONDARY, TV_HIGH);
|
||||
triggerAddEvent(s, 316, T_SECONDARY, TV_LOW);
|
||||
triggerAddEvent(s, 320, T_SECONDARY, TV_HIGH);
|
||||
s->addEvent(66, T_SECONDARY, TV_LOW);
|
||||
s->addEvent(70, T_SECONDARY, TV_HIGH);
|
||||
s->addEvent(136, T_SECONDARY, TV_LOW);
|
||||
s->addEvent(140, T_SECONDARY, TV_HIGH);
|
||||
s->addEvent(246, T_SECONDARY, TV_LOW);
|
||||
s->addEvent(250, T_SECONDARY, TV_HIGH);
|
||||
s->addEvent(316, T_SECONDARY, TV_LOW);
|
||||
s->addEvent(320, T_SECONDARY, TV_HIGH);
|
||||
|
||||
triggerAddEvent(s, 340, T_PRIMARY, TV_LOW);
|
||||
triggerAddEvent(s, 360, T_PRIMARY, TV_HIGH);
|
||||
s->addEvent(340, T_PRIMARY, TV_LOW);
|
||||
s->addEvent(360, T_PRIMARY, TV_HIGH);
|
||||
|
||||
triggerAddEvent(s, 380, T_PRIMARY, TV_LOW);
|
||||
triggerAddEvent(s, 400, T_PRIMARY, TV_HIGH);
|
||||
s->addEvent(380, T_PRIMARY, TV_LOW);
|
||||
s->addEvent(400, T_PRIMARY, TV_HIGH);
|
||||
|
||||
triggerAddEvent(s, 426, T_SECONDARY, TV_LOW);
|
||||
triggerAddEvent(s, 430, T_SECONDARY, TV_HIGH);
|
||||
triggerAddEvent(s, 496, T_SECONDARY, TV_LOW);
|
||||
triggerAddEvent(s, 500, T_SECONDARY, TV_HIGH);
|
||||
triggerAddEvent(s, 606, T_SECONDARY, TV_LOW);
|
||||
triggerAddEvent(s, 610, T_SECONDARY, TV_HIGH);
|
||||
triggerAddEvent(s, 676, T_SECONDARY, TV_LOW);
|
||||
triggerAddEvent(s, 680, T_SECONDARY, TV_HIGH);
|
||||
s->addEvent(426, T_SECONDARY, TV_LOW);
|
||||
s->addEvent(430, T_SECONDARY, TV_HIGH);
|
||||
s->addEvent(496, T_SECONDARY, TV_LOW);
|
||||
s->addEvent(500, T_SECONDARY, TV_HIGH);
|
||||
s->addEvent(606, T_SECONDARY, TV_LOW);
|
||||
s->addEvent(610, T_SECONDARY, TV_HIGH);
|
||||
s->addEvent(676, T_SECONDARY, TV_LOW);
|
||||
s->addEvent(680, T_SECONDARY, TV_HIGH);
|
||||
|
||||
triggerAddEvent(s, 720, T_PRIMARY, TV_LOW);
|
||||
s->addEvent(720, T_PRIMARY, TV_LOW);
|
||||
|
||||
s->shaftPositionEventCount = 6 + 16;
|
||||
}
|
||||
|
||||
void configureMazdaProtegeLx(engine_configuration_s *engineConfiguration,
|
||||
engine_configuration2_s *engineConfiguration2) {
|
||||
void configureMazdaProtegeLx(trigger_config_s *triggerConfig, trigger_shape_s *s) {
|
||||
|
||||
trigger_shape_s *s = &engineConfiguration2->triggerShape;
|
||||
|
||||
s->reset();
|
||||
s->reset(FOUR_STROKE_CAM_SENSOR);
|
||||
// s->initialState[0] = 1;
|
||||
|
||||
float w = 720 / 4 * 0.215;
|
||||
float a = 5;
|
||||
// triggerAddEvent(s, a, T_SECONDARY, TV_LOW);
|
||||
// triggerAddEvent(s, a + w, T_SECONDARY, TV_HIGH);
|
||||
// s->addEvent(a, T_SECONDARY, TV_LOW);
|
||||
// s->addEvent(a + w, T_SECONDARY, TV_HIGH);
|
||||
// a += 180;
|
||||
// triggerAddEvent(s, a, T_SECONDARY, TV_LOW);
|
||||
// triggerAddEvent(s, a + w, T_SECONDARY, TV_HIGH);
|
||||
// s->addEvent(a, T_SECONDARY, TV_LOW);
|
||||
// s->addEvent(a + w, T_SECONDARY, TV_HIGH);
|
||||
// a += 180;
|
||||
// triggerAddEvent(s, a, T_SECONDARY, TV_LOW);
|
||||
// triggerAddEvent(s, a + w, T_SECONDARY, TV_HIGH);
|
||||
// s->addEvent(a, T_SECONDARY, TV_LOW);
|
||||
// s->addEvent(a + w, T_SECONDARY, TV_HIGH);
|
||||
// a += 180;
|
||||
// triggerAddEvent(s, a, T_SECONDARY, TV_LOW);
|
||||
// triggerAddEvent(s, a + w, T_SECONDARY, TV_HIGH);
|
||||
// s->addEvent(a, T_SECONDARY, TV_LOW);
|
||||
// s->addEvent(a + w, T_SECONDARY, TV_HIGH);
|
||||
|
||||
float z = 0.093;
|
||||
|
||||
a = 180;
|
||||
triggerAddEvent(s, a - z * 720, T_PRIMARY, TV_HIGH);
|
||||
triggerAddEvent(s, a, T_PRIMARY, TV_LOW);
|
||||
s->addEvent(a - z * 720, T_PRIMARY, TV_HIGH);
|
||||
s->addEvent(a, T_PRIMARY, TV_LOW);
|
||||
|
||||
a += 180;
|
||||
triggerAddEvent(s, a - z * 720, T_PRIMARY, TV_HIGH);
|
||||
triggerAddEvent(s, a, T_PRIMARY, TV_LOW);
|
||||
s->addEvent(a - z * 720, T_PRIMARY, TV_HIGH);
|
||||
s->addEvent(a, T_PRIMARY, TV_LOW);
|
||||
|
||||
a += 180;
|
||||
triggerAddEvent(s, a - z * 720, T_PRIMARY, TV_HIGH);
|
||||
triggerAddEvent(s, a, T_PRIMARY, TV_LOW);
|
||||
s->addEvent(a - z * 720, T_PRIMARY, TV_HIGH);
|
||||
s->addEvent(a, T_PRIMARY, TV_LOW);
|
||||
|
||||
a += 180;
|
||||
s->addEvent(a - z * 720, T_PRIMARY, TV_HIGH);
|
||||
|
@ -100,5 +97,5 @@ void configureMazdaProtegeLx(engine_configuration_s *engineConfiguration,
|
|||
|
||||
// s->shaftPositionEventCount = 2 + 8;
|
||||
s->shaftPositionEventCount = 8;
|
||||
engineConfiguration->triggerConfig.isSynchronizationNeeded = FALSE;
|
||||
triggerConfig->isSynchronizationNeeded = false;
|
||||
}
|
||||
|
|
|
@ -12,8 +12,7 @@
|
|||
#include "engine_configuration.h"
|
||||
#include "ec2.h"
|
||||
|
||||
void initializeMazdaMiataNbShape(trigger_shape_s *s);
|
||||
void configureMazdaProtegeLx(engine_configuration_s *engineConfiguration,
|
||||
engine_configuration2_s *engineConfiguration2);
|
||||
void initializeMazdaMiataNbShape(trigger_config_s *triggerConfig, trigger_shape_s *s);
|
||||
void configureMazdaProtegeLx(trigger_config_s *triggerConfig, trigger_shape_s *s);
|
||||
|
||||
#endif /* TRIGGER_MAZDA_H_ */
|
||||
|
|
|
@ -29,7 +29,7 @@ trigger_shape_helper::trigger_shape_helper() {
|
|||
|
||||
trigger_shape_s::trigger_shape_s() :
|
||||
wave(switchTimes, NULL) {
|
||||
reset();
|
||||
reset(OM_NONE);
|
||||
wave.waves = h.waves;
|
||||
}
|
||||
|
||||
|
@ -37,7 +37,33 @@ int trigger_shape_s::getSize() {
|
|||
return size;
|
||||
}
|
||||
|
||||
void trigger_shape_s::reset() {
|
||||
int trigger_shape_s::getTriggerShapeSynchPointIndex() {
|
||||
return triggerShapeSynchPointIndex;
|
||||
}
|
||||
|
||||
// todo: clean-up!
|
||||
int getEngineCycleEventCount2(operation_mode_e mode, trigger_shape_s * s);
|
||||
float fixAngle(float angle);
|
||||
|
||||
void trigger_shape_s::setTriggerShapeSynchPointIndex(int triggerShapeSynchPointIndex) {
|
||||
this->triggerShapeSynchPointIndex = triggerShapeSynchPointIndex;
|
||||
|
||||
int engineCycleEventCount = getEngineCycleEventCount2(operationMode, this);
|
||||
|
||||
float firstAngle = getAngle(triggerShapeSynchPointIndex);
|
||||
|
||||
for (int i = 0; i < engineCycleEventCount; i++) {
|
||||
if (i == 0) {
|
||||
// explicit check for zero to avoid issues where logical zero is not exactly zero due to float nature
|
||||
eventAngles[i] = 0;
|
||||
} else {
|
||||
eventAngles[i] = fixAngle(getAngle((triggerShapeSynchPointIndex + i) % engineCycleEventCount) - firstAngle);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void trigger_shape_s::reset(operation_mode_e operationMode) {
|
||||
this->operationMode = operationMode;
|
||||
size = 0;
|
||||
shaftPositionEventCount = 0;
|
||||
triggerShapeSynchPointIndex = 0;
|
||||
|
@ -58,6 +84,7 @@ void multi_wave_s::setSwitchTime(int index, float value) {
|
|||
TriggerState::TriggerState() {
|
||||
clear();
|
||||
totalEventCountBase = 0;
|
||||
isFirstEvent = true;
|
||||
}
|
||||
|
||||
int TriggerState::getCurrentIndex() {
|
||||
|
@ -74,7 +101,7 @@ uint64_t TriggerState::getTotalEventCounter() {
|
|||
|
||||
void TriggerState::nextRevolution(int triggerEventCount) {
|
||||
current_index = 0;
|
||||
totalRevolutionCounter ++;
|
||||
totalRevolutionCounter++;
|
||||
totalEventCountBase += triggerEventCount;
|
||||
}
|
||||
|
||||
|
@ -94,7 +121,30 @@ void TriggerState::clear() {
|
|||
totalRevolutionCounter = 0;
|
||||
}
|
||||
|
||||
float trigger_shape_s::getAngle(int index) const {
|
||||
if (operationMode == FOUR_STROKE_CAM_SENSOR)
|
||||
return switchAngles[index];
|
||||
/**
|
||||
* FOUR_STROKE_CRANK_SENSOR magic:
|
||||
* We have two crank shaft revolutions for each engine cycle
|
||||
* See also trigger_central.cpp
|
||||
* See also getEngineCycleEventCount()
|
||||
*/
|
||||
int triggerEventCounter = size;
|
||||
|
||||
if (index < triggerEventCounter) {
|
||||
return switchAngles[index];
|
||||
} else {
|
||||
return 360 + switchAngles[index - triggerEventCounter];
|
||||
}
|
||||
}
|
||||
|
||||
void trigger_shape_s::addEvent(float angle, trigger_wheel_e waveIndex, trigger_value_e state) {
|
||||
efiAssertVoid(operationMode != OM_NONE, "operationMode not set");
|
||||
/**
|
||||
* While '720' value works perfectly it has not much sense for crank sensor-only scenario.
|
||||
* todo: accept angle as a value in the 0..1 range?
|
||||
*/
|
||||
angle /= 720;
|
||||
efiAssertVoid(angle > previousAngle, "invalid angle order");
|
||||
previousAngle = angle;
|
||||
|
@ -114,7 +164,7 @@ void trigger_shape_s::addEvent(float angle, trigger_wheel_e waveIndex, trigger_v
|
|||
wave->pinStates[0] = initialState[i];
|
||||
}
|
||||
|
||||
wave.setSwitchTime(0, angle);
|
||||
setSwitchTime(0, angle);
|
||||
wave.waves[waveIndex].pinStates[0] = state;
|
||||
return;
|
||||
}
|
||||
|
@ -125,13 +175,14 @@ void trigger_shape_s::addEvent(float angle, trigger_wheel_e waveIndex, trigger_v
|
|||
|
||||
for (int i = 0; i < PWM_PHASE_MAX_WAVE_PER_PWM; i++)
|
||||
wave.waves[i].pinStates[index] = wave.getChannelState(i, index - 1);
|
||||
wave.setSwitchTime(index, angle);
|
||||
setSwitchTime(index, angle);
|
||||
wave.waves[waveIndex].pinStates[index] = state;
|
||||
}
|
||||
|
||||
void triggerAddEvent(trigger_shape_s *trigger, float angle, trigger_wheel_e waveIndex, trigger_value_e state) {
|
||||
// todo: inline this method
|
||||
trigger->addEvent(angle, waveIndex, state);
|
||||
void trigger_shape_s::setSwitchTime(int index, float angle) {
|
||||
int cycleDuration = (operationMode == FOUR_STROKE_CAM_SENSOR) ? 720 : 360;
|
||||
switchAngles[index] = cycleDuration * angle;
|
||||
wave.setSwitchTime(index, angle);
|
||||
}
|
||||
|
||||
void multi_wave_s::checkSwitchTimes(int size) {
|
||||
|
|
|
@ -25,7 +25,7 @@ public:
|
|||
uint64_t getStartOfRevolutionIndex();
|
||||
void nextRevolution(int triggerEventCount);
|
||||
void nextTriggerEvent();
|
||||
void processTriggerEvent(trigger_shape_s const*triggerShape, trigger_config_s const*triggerConfig, trigger_event_e signal, uint64_t nowUs);
|
||||
void decodeTriggerEvent(trigger_shape_s const*triggerShape, trigger_config_s const*triggerConfig, trigger_event_e signal, uint64_t nowUs);
|
||||
|
||||
|
||||
/**
|
||||
|
@ -43,6 +43,7 @@ private:
|
|||
int current_index;
|
||||
uint64_t totalEventCountBase;
|
||||
int totalRevolutionCounter;
|
||||
bool isFirstEvent;
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
|
@ -66,12 +67,14 @@ public:
|
|||
|
||||
class trigger_shape_s {
|
||||
private:
|
||||
void setSwitchTime(int index, float angle);
|
||||
trigger_shape_helper h;
|
||||
int size;
|
||||
public:
|
||||
trigger_shape_s();
|
||||
void addEvent(float angle, trigger_wheel_e waveIndex, trigger_value_e state);
|
||||
void reset();
|
||||
float getAngle(int phaseIndex) const;
|
||||
void reset(operation_mode_e operationMode);
|
||||
int getSize();
|
||||
multi_wave_s wave;
|
||||
|
||||
|
@ -86,25 +89,38 @@ public:
|
|||
// tood: maybe even automate this flag calculation?
|
||||
int initialState[PWM_PHASE_MAX_WAVE_PER_PWM];
|
||||
|
||||
|
||||
int getTriggerShapeSynchPointIndex();
|
||||
|
||||
void setTriggerShapeSynchPointIndex(int triggerShapeSynchPointIndex);
|
||||
/**
|
||||
* These angles are in event coordinates - with synchronization point located at angle zero.
|
||||
*/
|
||||
float eventAngles[PWM_PHASE_MAX_COUNT];
|
||||
|
||||
private:
|
||||
/**
|
||||
* index of synchronization event within trigger_shape_s
|
||||
* See findTriggerZeroEventIndex()
|
||||
*/
|
||||
int triggerShapeSynchPointIndex;
|
||||
private:
|
||||
/**
|
||||
* Values are in the 0..1 range
|
||||
*/
|
||||
float switchTimes[PWM_PHASE_MAX_COUNT];
|
||||
/**
|
||||
* These are the same values as in switchTimes, but these are angles in the 0..360 or 0..720 range.
|
||||
* That's a performance optimization - this should save as one multiplication in a critical spot.
|
||||
*
|
||||
* These angles are in trigger DESCRIPTION coordinates - i.e. the way you add events while declaring trigger shape
|
||||
*/
|
||||
float switchAngles[PWM_PHASE_MAX_COUNT];
|
||||
|
||||
float previousAngle;
|
||||
/**
|
||||
* this is part of performance optimization
|
||||
*/
|
||||
operation_mode_e operationMode;
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif /* __cplusplus */
|
||||
|
||||
void triggerAddEvent(trigger_shape_s *trigger, float angle, trigger_wheel_e waveIndex, trigger_value_e state);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* TRIGGER_STRUCTURE_H_ */
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
arm-none-eabi-objdump -S build/rusefi.elf > build.dump
|
|
@ -48,7 +48,7 @@ void acAddData(float angle, float value) {
|
|||
appendPrintf(&logging, "analog_chart%s", DELIMETER);
|
||||
}
|
||||
|
||||
if (loggingSize(&logging) < sizeof(LOGGING_BUFFER) - 100)
|
||||
if (remainingSize(&logging) > 100)
|
||||
appendPrintf(&logging, "%f|%f|", angle, value);
|
||||
}
|
||||
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#include "gpio_helper.h"
|
||||
#include "efilib2.h"
|
||||
#include "console_io.h"
|
||||
#include "engine.h"
|
||||
|
||||
#if EFI_PERF_METRICS
|
||||
|
||||
|
@ -66,6 +67,8 @@ static void testSystemCalls(const int count) {
|
|||
scheduleMsg(&logger, "Finished %d iterations of 'currentTimeMillis' in %dms", count, time);
|
||||
}
|
||||
|
||||
static Engine testEngine;
|
||||
|
||||
static void testRusefiMethods(const int count) {
|
||||
time_t start, time;
|
||||
int tempi = 1;
|
||||
|
@ -79,12 +82,20 @@ static void testRusefiMethods(const int count) {
|
|||
scheduleMsg(&logger, "Finished %d iterations of getBaseFuel in %dms", count, time);
|
||||
|
||||
start = currentTimeMillis();
|
||||
for (int i = 0; i < count; i++)
|
||||
tempi += getFuelMs(1200);
|
||||
time = currentTimeMillis() - start;
|
||||
if (tempi != 0)
|
||||
scheduleMsg(&logger, "Finished %d iterations of getFuelMs in %dms", count, time);
|
||||
|
||||
// for (int i = 0; i < count; i++)
|
||||
// tempi += getDefaultFuel(4020, 2.21111);
|
||||
// time = currentTimeMillis() - start;
|
||||
// if (tempi == 0)
|
||||
// rint("Finished %d iterations of getDefaultFuel in %dms\r\n", count, time);
|
||||
start = currentTimeMillis();
|
||||
for (int i = 0; i < count; i++) {
|
||||
testEngine.updateSlowSensors();
|
||||
tempi += testEngine.engineState.clt;
|
||||
}
|
||||
time = currentTimeMillis() - start;
|
||||
if (tempi != 0)
|
||||
scheduleMsg(&logger, "Finished %d iterations of updateSlowSensors in %dms", count, time);
|
||||
}
|
||||
|
||||
static void testMath(const int count) {
|
||||
|
@ -165,6 +176,14 @@ static void testMath(const int count) {
|
|||
scheduleMsg(&logger, "Finished %d iterations of float division in %dms", count, time);
|
||||
}
|
||||
|
||||
start = currentTimeMillis();
|
||||
tempf = 1;
|
||||
for (int i = 0; i < count; i++)
|
||||
tempf += logf(tempf);
|
||||
time = currentTimeMillis() - start;
|
||||
if (tempf != 0)
|
||||
scheduleMsg(&logger, "Finished %d iterations of float log in %dms", count, time);
|
||||
|
||||
start = currentTimeMillis();
|
||||
double tempd = 1;
|
||||
for (int i = 0; i < count; i++)
|
||||
|
@ -181,9 +200,17 @@ static void testMath(const int count) {
|
|||
if (tempd != 0)
|
||||
scheduleMsg(&logger, "Finished %d iterations of double division in %dms", count, time);
|
||||
|
||||
start = currentTimeMillis();
|
||||
tempd = 1;
|
||||
for (int i = 0; i < count; i++)
|
||||
tempd += log(tempd);
|
||||
time = currentTimeMillis() - start;
|
||||
if (tempd != 0)
|
||||
scheduleMsg(&logger, "Finished %d iterations of double log in %dms", count, time);
|
||||
}
|
||||
|
||||
static void runTests(const int count) {
|
||||
scheduleMsg(&logger, "Running tests: %d", count);
|
||||
testRusefiMethods(count / 10);
|
||||
testSystemCalls(count);
|
||||
testMath(count);
|
||||
|
|
|
@ -49,7 +49,7 @@ static void waAnaWidthCallback(WaveReader *reader) {
|
|||
uint64_t nowUs = getTimeNowUs();
|
||||
reader->eventCounter++;
|
||||
reader->lastActivityTimeUs = nowUs;
|
||||
addWaveChartEvent(reader->name, "up", "");
|
||||
addWaveChartEvent(reader->name, WC_UP, "");
|
||||
|
||||
uint64_t width = nowUs - reader->periodEventTimeUs;
|
||||
reader->last_wave_low_widthUs = width;
|
||||
|
@ -62,7 +62,7 @@ static void waIcuPeriodCallback(WaveReader *reader) {
|
|||
uint64_t nowUs = getTimeNowUs();
|
||||
reader->eventCounter++;
|
||||
reader->lastActivityTimeUs = nowUs;
|
||||
addWaveChartEvent(reader->name, "down", "");
|
||||
addWaveChartEvent(reader->name, WC_DOWN, "");
|
||||
|
||||
uint64_t width = nowUs - reader->widthEventTimeUs;
|
||||
reader->last_wave_high_widthUs = width;
|
||||
|
|
|
@ -30,7 +30,7 @@
|
|||
#if EFI_USE_CCM && defined __GNUC__
|
||||
#define CCM_OPTIONAL __attribute__((section(".ccm")));
|
||||
#else
|
||||
#define CCM_OPTIONAL
|
||||
#define CCM_OPTIONAL @ ".ccm"
|
||||
#endif
|
||||
|
||||
// this stuff is about ChibiOS 2.6 > Migration
|
||||
|
|
|
@ -261,8 +261,7 @@ GPIO_TypeDef* getAdcChannelPort(int hwChannel) {
|
|||
case ADC_CHANNEL_IN15:
|
||||
return GPIOC;
|
||||
default:
|
||||
firmwareError("Unknown hw channel")
|
||||
;
|
||||
firmwareError("Unknown hw channel");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
@ -303,8 +302,7 @@ int getAdcChannelPin(int hwChannel) {
|
|||
case ADC_CHANNEL_IN15:
|
||||
return 5;
|
||||
default:
|
||||
firmwareError("Unknown hw channel")
|
||||
;
|
||||
firmwareError("Unknown hw channel");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
@ -411,7 +409,7 @@ static void adc_callback_fast(ADCDriver *adcp, adcsample_t *buffer, size_t n) {
|
|||
}
|
||||
}
|
||||
|
||||
void initAdcInputs() {
|
||||
void initAdcInputs(bool isBoardTestMode) {
|
||||
|
||||
initLoggingExt(&logger, "ADC", LOGGING_BUFFER, sizeof(LOGGING_BUFFER));
|
||||
printMsg(&logger, "initAdcInputs()");
|
||||
|
@ -430,7 +428,7 @@ void initAdcInputs() {
|
|||
for (int adc = 0; adc < HW_MAX_ADC_INDEX; adc++) {
|
||||
adc_channel_mode_e mode = boardConfiguration->adcHwChannelEnabled[adc];
|
||||
|
||||
if (mode == ADC_SLOW) {
|
||||
if (mode == ADC_SLOW || (isBoardTestMode && mode == ADC_FAST)) {
|
||||
slowAdc.addChannel(ADC_CHANNEL_IN0 + adc);
|
||||
} else if (mode == ADC_FAST) {
|
||||
fastAdc.addChannel(ADC_CHANNEL_IN0 + adc);
|
||||
|
@ -438,7 +436,14 @@ void initAdcInputs() {
|
|||
}
|
||||
|
||||
slowAdc.init();
|
||||
pwmStart(EFI_INTERNAL_SLOW_ADC_PWM, &pwmcfg_slow);
|
||||
if (!isBoardTestMode) {
|
||||
fastAdc.init();
|
||||
/*
|
||||
* Initializes the PWM driver.
|
||||
*/
|
||||
pwmStart(EFI_INTERNAL_FAST_ADC_PWM, &pwmcfg_fast);
|
||||
}
|
||||
|
||||
// ADC_CHANNEL_IN0 // PA0
|
||||
// ADC_CHANNEL_IN1 // PA1
|
||||
|
@ -459,11 +464,6 @@ void initAdcInputs() {
|
|||
|
||||
//if(slowAdcChannelCount > ADC_MAX_SLOW_CHANNELS_COUNT) // todo: do we need this logic? do we need this check
|
||||
|
||||
/*
|
||||
* Initializes the PWM driver.
|
||||
*/
|
||||
pwmStart(EFI_INTERNAL_SLOW_ADC_PWM, &pwmcfg_slow);
|
||||
pwmStart(EFI_INTERNAL_FAST_ADC_PWM, &pwmcfg_fast);
|
||||
addConsoleActionI("adc", printAdcValue);
|
||||
addConsoleAction("fadc", printFullAdcReport);
|
||||
#else
|
||||
|
|
|
@ -19,7 +19,7 @@ extern "C"
|
|||
|
||||
GPIO_TypeDef* getAdcChannelPort(int hwChannel);
|
||||
int getAdcChannelPin(int hwChannel);
|
||||
void initAdcInputs(void);
|
||||
void initAdcInputs(bool isBoardTestMode);
|
||||
int getAdcHardwareIndexByInternalIndex(int index);
|
||||
int getAdcValueByIndex(int internalIndex);
|
||||
void pokeAdcInputs(void);
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
#include "AdcConfiguration.h"
|
||||
|
||||
static volatile int stepCoutner = 0;
|
||||
static volatile brain_pin_e currentPin;
|
||||
static volatile brain_pin_e currentPin = GPIO_NONE;
|
||||
static volatile int currentIndex = 0;
|
||||
|
||||
extern AdcConfiguration slowAdc;
|
||||
|
@ -93,11 +93,25 @@ static msg_t ivThread(int param) {
|
|||
#endif
|
||||
}
|
||||
|
||||
void initBoardTest(void) {
|
||||
// todo: add a command to go into board test mode after reboot
|
||||
if (1 == 1)
|
||||
return;
|
||||
static bool is_board_test_mode = false;
|
||||
|
||||
bool isBoardTestMode(void) {
|
||||
return is_board_test_mode;
|
||||
}
|
||||
|
||||
void printBoardTestState(void) {
|
||||
print("Current index=%d\r\n", currentIndex);
|
||||
print("'n' for next step and 'set X' to return to step X\r\n");
|
||||
print("ADC count: %d\r\n", slowAdc.size());
|
||||
|
||||
if (currentPin != GPIO_NONE) {
|
||||
print("Blinking %s\r\n", hwPortname(currentPin));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void initBoardTest(void) {
|
||||
is_board_test_mode = true;
|
||||
addConsoleAction("n", nextStep);
|
||||
addConsoleActionI("set", setIndex);
|
||||
|
||||
|
@ -142,8 +156,7 @@ void initBoardTest(void) {
|
|||
GPIO_TypeDef *hwPort = getHwPort(currentPin);
|
||||
uint32_t hwPin = getHwPin(currentPin);
|
||||
|
||||
print("currentIndex=%d\r\n", currentIndex);
|
||||
print("Let's blink %s%d\r\n", portname(hwPort), hwPin);
|
||||
printBoardTestState();
|
||||
mySetPadMode("test", hwPort, hwPin, PAL_STM32_MODE_OUTPUT);
|
||||
|
||||
currentIndex++;
|
||||
|
|
|
@ -28,6 +28,8 @@ extern "C"
|
|||
#endif /* __cplusplus */
|
||||
|
||||
void initBoardTest(void);
|
||||
bool isBoardTestMode(void);
|
||||
void printBoardTestState(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -25,6 +25,7 @@ static THD_WORKING_AREA(canTreadStack, UTILITY_THREAD_STACK_SIZE);
|
|||
|
||||
extern engine_configuration_s *engineConfiguration;
|
||||
extern engine_configuration2_s *engineConfiguration2;
|
||||
extern board_configuration_s *board_configuration;
|
||||
|
||||
/*
|
||||
* 500KBaud
|
||||
|
@ -175,6 +176,10 @@ static void canInfo(void) {
|
|||
scheduleMsg(&logger, "CAN rx count %d", canReadCounter);
|
||||
}
|
||||
|
||||
static CANDriver *getCanDevice() {
|
||||
if(board)
|
||||
}
|
||||
|
||||
void initCan(void) {
|
||||
initLogging(&logger, "CAN driver");
|
||||
|
||||
|
|
|
@ -50,7 +50,7 @@ flashsector_t flashSectorAt(flashaddr_t address) {
|
|||
* @return CH_SUCCESS Unlock was successful.
|
||||
* @return CH_FAILED Unlock failed.
|
||||
*/
|
||||
static bool_t flashUnlock(void) {
|
||||
static bool flashUnlock(void) {
|
||||
/* Check if unlock is really needed */
|
||||
if (!(FLASH->CR & FLASH_CR_LOCK))
|
||||
return CH_SUCCESS;
|
||||
|
@ -141,13 +141,13 @@ bool flashIsErased(flashaddr_t address, size_t size) {
|
|||
* then, fallback to byte per byte comparison. */
|
||||
while (size >= sizeof(flashdata_t)) {
|
||||
if (*(volatile flashdata_t*) address != (flashdata_t) (-1)) // flashdata_t being unsigned, -1 is 0xFF..FF
|
||||
return FALSE;
|
||||
return false;
|
||||
address += sizeof(flashdata_t);
|
||||
size -= sizeof(flashdata_t);
|
||||
}
|
||||
while (size > 0) {
|
||||
if (*(char*) address != 0xff)
|
||||
return FALSE;
|
||||
return false;
|
||||
++address;
|
||||
--size;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* @file hardware.c
|
||||
* @file hardware.cpp
|
||||
* @brief Hardware package entry point
|
||||
*
|
||||
* @date May 27, 2013
|
||||
|
@ -12,6 +12,7 @@
|
|||
#include "io_pins.h"
|
||||
#include "rtc_helper.h"
|
||||
#include "rfiutil.h"
|
||||
#include "console_io.h"
|
||||
|
||||
#include "adc_inputs.h"
|
||||
|
||||
|
@ -27,6 +28,7 @@
|
|||
#include "neo6m.h"
|
||||
#include "lcd_HD44780.h"
|
||||
#include "settings.h"
|
||||
#include "algo.h"
|
||||
|
||||
#if EFI_INTERNAL_FLASH
|
||||
#include "flash_main.h"
|
||||
|
@ -105,7 +107,6 @@ void initHardware(Logging *logger) {
|
|||
initHistogramsModule();
|
||||
#endif /* EFI_HISTOGRAMS */
|
||||
|
||||
|
||||
/**
|
||||
* We need the LED_ERROR pin even before we read configuration
|
||||
*/
|
||||
|
@ -114,12 +115,25 @@ void initHardware(Logging *logger) {
|
|||
if (hasFirmwareError())
|
||||
return;
|
||||
|
||||
initDataStructures(engineConfiguration);
|
||||
|
||||
#if EFI_INTERNAL_FLASH
|
||||
|
||||
palSetPadMode(CONFIG_RESET_SWITCH_PORT, CONFIG_RESET_SWITCH_PIN, PAL_MODE_INPUT_PULLUP);
|
||||
|
||||
initFlash();
|
||||
/**
|
||||
* this call reads configuration from flash memory or sets default configuration
|
||||
* if flash state does not look right.
|
||||
*/
|
||||
initFlash();
|
||||
if (SHOULD_INGORE_FLASH()) {
|
||||
engineConfiguration->engineType = FORD_ASPIRE_1996;
|
||||
resetConfigurationExt(logger, engineConfiguration->engineType, engineConfiguration, engineConfiguration2,
|
||||
boardConfiguration);
|
||||
writeToFlash();
|
||||
} else {
|
||||
readFromFlash();
|
||||
}
|
||||
#else
|
||||
engineConfiguration->engineType = FORD_ASPIRE_1996;
|
||||
resetConfigurationExt(logger, engineConfiguration->engineType, engineConfiguration, engineConfiguration2, boardConfiguration);
|
||||
|
@ -128,10 +142,20 @@ void initHardware(Logging *logger) {
|
|||
if (hasFirmwareError())
|
||||
return;
|
||||
|
||||
mySetPadMode("board test", getHwPort(boardConfiguration->boardTestModeJumperPin),
|
||||
getHwPin(boardConfiguration->boardTestModeJumperPin), PAL_MODE_INPUT_PULLUP);
|
||||
bool isBoardTestMode = GET_BOARD_TEST_MODE_VALUE();
|
||||
|
||||
initAdcInputs(isBoardTestMode);
|
||||
|
||||
if (isBoardTestMode) {
|
||||
initBoardTest();
|
||||
efiAssertVoid(FALSE, "board test done");
|
||||
}
|
||||
|
||||
initRtc();
|
||||
|
||||
initOutputPins();
|
||||
initAdcInputs();
|
||||
|
||||
#if EFI_HIP_9011
|
||||
initHip9011();
|
||||
|
@ -144,7 +168,6 @@ void initHardware(Logging *logger) {
|
|||
// init_adc_mcp3208(&adcState, &SPID2);
|
||||
// requestAdcValue(&adcState, 0);
|
||||
|
||||
|
||||
// todo: figure out better startup logic
|
||||
initTriggerCentral();
|
||||
|
||||
|
@ -195,6 +218,5 @@ void initHardware(Logging *logger) {
|
|||
// }
|
||||
// }
|
||||
|
||||
initBoardTest();
|
||||
printMsg(logger, "initHardware() OK!");
|
||||
}
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue