diff --git a/firmware/config/boards/hellen/hellen81/board.mk b/firmware/config/boards/hellen/hellen81/board.mk index f1d4339b82..7480c9c49e 100644 --- a/firmware/config/boards/hellen/hellen81/board.mk +++ b/firmware/config/boards/hellen/hellen81/board.mk @@ -26,7 +26,7 @@ DDEFS += -DLED_COMMUNICATION_BRAIN_PIN_MODE=INVERTED_OUTPUT # Disable serial ports on this board as UART3 causes a DMA conflict with the SD card DDEFS += -DTS_NO_PRIMARY -DTS_NO_SECONDARY -DDEFS += -DEFI_CAN_SERIAL=TRUE -DTS_CAN_DEVICE_SHORT_PACKETS_IN_ONE_FRAME=TRUE +DDEFS += -DEFI_CAN_SERIAL=TRUE # todo debug: DDEFS += -DDISABLE_CAN_UPDATE_DASH=TRUE diff --git a/firmware/config/boards/microrusefi/board.mk b/firmware/config/boards/microrusefi/board.mk index e3aaafbe9a..036e750a93 100644 --- a/firmware/config/boards/microrusefi/board.mk +++ b/firmware/config/boards/microrusefi/board.mk @@ -26,7 +26,7 @@ endif # *TODO* need to give people the horrible choice between Bluetooth via TTL or SD card via SPI :( horrible choice EFI_CONSOLE_TTL_PINS = -DEFI_CONSOLE_TX_BRAIN_PIN=GPIOB_10 -DEFI_CONSOLE_RX_BRAIN_PIN=GPIOB_11 -DDEFS += -DEFI_CAN_SERIAL=TRUE -DTS_CAN_DEVICE_SHORT_PACKETS_IN_ONE_FRAME=TRUE +DDEFS += -DEFI_CAN_SERIAL=TRUE # Add them all together diff --git a/firmware/config/engines/custom_engine.cpp b/firmware/config/engines/custom_engine.cpp index 425552ef64..40908e1f3e 100644 --- a/firmware/config/engines/custom_engine.cpp +++ b/firmware/config/engines/custom_engine.cpp @@ -811,6 +811,10 @@ void proteusHarley() { engineConfiguration->camInputs[0] = PROTEUS_DIGITAL_6; engineConfiguration->vvtMode[0] = VVT_MAP_V_TWIN; + engineConfiguration->mapCamAveragingLength = 16; + engineConfiguration->mapCamSkipFactor = 50; + engineConfiguration->mapCamLookForLowPeaks = true; + engineConfiguration->luaOutputPins[0] = PROTEUS_LS_12; #if HW_PROTEUS strncpy(config->luaScript, R"( diff --git a/firmware/console/binary/output_channels.txt b/firmware/console/binary/output_channels.txt index 6f2254b65b..37a0769ac9 100644 --- a/firmware/console/binary/output_channels.txt +++ b/firmware/console/binary/output_channels.txt @@ -234,7 +234,7 @@ uint16_t rpmAcceleration;dRPM;"RPM/s",1, 0, 0, 0, 0 uint16_t autoscale rawTps2Primary;;"V",{1/@@PACK_MULT_VOLTAGE@@}, 0, 0, 0, 0 uint16_t autoscale rawTps2Secondary;;"V",{1/@@PACK_MULT_VOLTAGE@@}, 0, 0, 0, 0 - uint16_t knockCount;@@GAUGE_NAME_KNOCK_LEVEL@@;"",1, 0, 0, 0, 0 + uint16_t knockCount;"knock: count";"",1, 0, 0, 0, 0 uint16_t autoscale accelerationZ;@@GAUGE_NAME_ACCEL_Z@@;"G",{1/@@PACK_MULT_PERCENT@@}, 0, 0, 0, 0 uint16_t autoscale accelerationRoll;@@GAUGE_NAME_ACCEL_ROLL@@;"",{1/@@PACK_MULT_PERCENT@@}, 0, 0, 0, 0 diff --git a/firmware/console/binary/serial_can.cpp b/firmware/console/binary/serial_can.cpp index d7117b5dc9..7ace7c632d 100644 --- a/firmware/console/binary/serial_can.cpp +++ b/firmware/console/binary/serial_can.cpp @@ -26,7 +26,7 @@ static CanTsListener listener; int CanStreamerState::sendFrame(const IsoTpFrameHeader & header, const uint8_t *data, int num, can_sysinterval_t timeout) { int dlc = 8; // standard 8 bytes - CanTxMessage txmsg(CAN_SERIAL_TX_ID, dlc, false); + CanTxMessage txmsg(CAN_ECU_SERIAL_TX_ID, dlc, false); // fill the frame data according to the CAN-TP protocol (ISO 15765-2) txmsg[0] = (uint8_t)((header.frameType & 0xf) << 4); @@ -76,6 +76,7 @@ int CanStreamerState::sendFrame(const IsoTpFrameHeader & header, const uint8_t * int CanStreamerState::receiveFrame(CANRxFrame *rxmsg, uint8_t *buf, int num, can_sysinterval_t timeout) { if (rxmsg == nullptr || rxmsg->DLC < 1) return 0; + engine->pauseCANdueToSerial = true; int frameType = (rxmsg->data8[0] >> 4) & 0xf; int numBytesAvailable, frameIdx; uint8_t *srcBuf = rxmsg->data8; diff --git a/firmware/console/binary/serial_can.h b/firmware/console/binary/serial_can.h index 0cc70cc41d..e4adcb0bad 100644 --- a/firmware/console/binary/serial_can.h +++ b/firmware/console/binary/serial_can.h @@ -27,10 +27,6 @@ #define CAN_FIFO_BUF_SIZE 64 #define CAN_FIFO_FRAME_SIZE 8 -// todo: find a better place for these defs -#define CAN_SERIAL_RX_ID 0x100 -#define CAN_SERIAL_TX_ID 0x102 - #define CAN_FLOW_STATUS_OK 0 #define CAN_FLOW_STATUS_WAIT_MORE 1 #define CAN_FLOW_STATUS_ABORT 2 @@ -114,7 +110,7 @@ public: class CanTsListener : public CanListener { public: CanTsListener() - : CanListener(CAN_SERIAL_RX_ID) + : CanListener(CAN_ECU_SERIAL_RX_ID) { } diff --git a/firmware/console/binary/ts_outputs_generated.h b/firmware/console/binary/ts_outputs_generated.h index f0d48ac145..0ee306485d 100644 --- a/firmware/console/binary/ts_outputs_generated.h +++ b/firmware/console/binary/ts_outputs_generated.h @@ -1,4 +1,4 @@ -// this section was generated automatically by rusEFI tool ConfigDefinition.jar based on (unknown script) console/binary/output_channels.txt Sat Dec 04 23:26:00 UTC 2021 +// this section was generated automatically by rusEFI tool ConfigDefinition.jar based on (unknown script) console/binary/output_channels.txt Sun Dec 05 04:34:28 UTC 2021 // by class com.rusefi.output.CHeaderConsumer // begin #pragma once @@ -790,7 +790,7 @@ struct ts_outputs_s { */ scaled_channel rawTps2Secondary = (uint16_t)0; /** - * @@GAUGE_NAME_KNOCK_LEVEL@@ + * "knock: count" * offset 306 */ uint16_t knockCount = (uint16_t)0; @@ -970,4 +970,4 @@ struct ts_outputs_s { }; // end -// this section was generated automatically by rusEFI tool ConfigDefinition.jar based on (unknown script) console/binary/output_channels.txt Sat Dec 04 23:26:00 UTC 2021 +// this section was generated automatically by rusEFI tool ConfigDefinition.jar based on (unknown script) console/binary/output_channels.txt Sun Dec 05 04:34:28 UTC 2021 diff --git a/firmware/controllers/actuators/alternator_controller.cpp b/firmware/controllers/actuators/alternator_controller.cpp index 436bee734b..ae393f0edf 100644 --- a/firmware/controllers/actuators/alternator_controller.cpp +++ b/firmware/controllers/actuators/alternator_controller.cpp @@ -31,76 +31,72 @@ static void pidReset() { alternatorPid.reset(); } -class AlternatorController : public PeriodicTimerController { - int getPeriodMs() override { - return GET_PERIOD_LIMITED(&engineConfiguration->alternatorControl); +void AlternatorController::onFastCallback() { + if (!isBrainPinValid(engineConfiguration->alternatorControlPin)) { + return; } - void PeriodicTask() override { #if ! EFI_UNIT_TEST - if (shouldResetPid) { - pidReset(); - shouldResetPid = false; - } + if (shouldResetPid) { + pidReset(); + shouldResetPid = false; + } #endif - // this block could be executed even in on/off alternator control mode - // but at least we would reflect latest state + // this block could be executed even in on/off alternator control mode + // but at least we would reflect latest state #if EFI_TUNER_STUDIO - alternatorPid.postState(&tsOutputChannels.alternatorStatus); + alternatorPid.postState(&tsOutputChannels.alternatorStatus); #endif /* EFI_TUNER_STUDIO */ - // todo: migrate this to FSIO - bool alternatorShouldBeEnabledAtCurrentRpm = GET_RPM() > engineConfiguration->cranking.rpm; + // todo: migrate this to FSIO + bool alternatorShouldBeEnabledAtCurrentRpm = GET_RPM() > engineConfiguration->cranking.rpm; - if (!engineConfiguration->isAlternatorControlEnabled || !alternatorShouldBeEnabledAtCurrentRpm) { - // we need to avoid accumulating iTerm while engine is not running - pidReset(); + if (!engineConfiguration->isAlternatorControlEnabled || !alternatorShouldBeEnabledAtCurrentRpm) { + // we need to avoid accumulating iTerm while engine is not running + pidReset(); - // Shut off output if not needed - alternatorControl.setSimplePwmDutyCycle(0); + // Shut off output if not needed + alternatorControl.setSimplePwmDutyCycle(0); - return; - } + return; + } - auto vBatt = Sensor::get(SensorType::BatteryVoltage); - float targetVoltage = engineConfiguration->targetVBatt; - - // todo: I am not aware of a SINGLE person to use this onOffAlternatorLogic - if (engineConfiguration->onOffAlternatorLogic) { - if (!vBatt) { - // Somehow battery voltage isn't valid, disable alternator control - enginePins.alternatorPin.setValue(false); - } - - float h = 0.1; - bool newState = (vBatt.Value < targetVoltage - h) || (currentPlainOnOffState && vBatt.Value < targetVoltage); - enginePins.alternatorPin.setValue(newState); - currentPlainOnOffState = newState; -#if EFI_TUNER_STUDIO - tsOutputChannels.alternatorOnOff = newState; -#endif /* EFI_TUNER_STUDIO */ - - return; - } + auto vBatt = Sensor::get(SensorType::BatteryVoltage); + float targetVoltage = engineConfiguration->targetVBatt; + // todo: I am not aware of a SINGLE person to use this onOffAlternatorLogic + if (engineConfiguration->onOffAlternatorLogic) { if (!vBatt) { // Somehow battery voltage isn't valid, disable alternator control - alternatorPid.reset(); - alternatorControl.setSimplePwmDutyCycle(0); - } else { - currentAltDuty = alternatorPid.getOutput(targetVoltage, vBatt.Value); - if (engineConfiguration->isVerboseAlternator) { - efiPrintf("alt duty: %.2f/vbatt=%.2f/p=%.2f/i=%.2f/d=%.2f int=%.2f", currentAltDuty, vBatt.Value, - alternatorPid.getP(), alternatorPid.getI(), alternatorPid.getD(), alternatorPid.getIntegration()); - } - - alternatorControl.setSimplePwmDutyCycle(PERCENT_TO_DUTY(currentAltDuty)); + enginePins.alternatorPin.setValue(false); } - } -}; -static AlternatorController instance; + float h = 0.1; + bool newState = (vBatt.Value < targetVoltage - h) || (currentPlainOnOffState && vBatt.Value < targetVoltage); + enginePins.alternatorPin.setValue(newState); + currentPlainOnOffState = newState; +#if EFI_TUNER_STUDIO + tsOutputChannels.alternatorOnOff = newState; +#endif /* EFI_TUNER_STUDIO */ + + return; + } + + if (!vBatt) { + // Somehow battery voltage isn't valid, disable alternator control + alternatorPid.reset(); + alternatorControl.setSimplePwmDutyCycle(0); + } else { + currentAltDuty = alternatorPid.getOutput(targetVoltage, vBatt.Value, FAST_CALLBACK_PERIOD_MS / 1000.0f); + if (engineConfiguration->isVerboseAlternator) { + efiPrintf("alt duty: %.2f/vbatt=%.2f/p=%.2f/i=%.2f/d=%.2f int=%.2f", currentAltDuty, vBatt.Value, + alternatorPid.getP(), alternatorPid.getI(), alternatorPid.getD(), alternatorPid.getIntegration()); + } + + alternatorControl.setSimplePwmDutyCycle(PERCENT_TO_DUTY(currentAltDuty)); + } +} void showAltInfo(void) { efiPrintf("alt=%s @%s t=%dms", boolToString(engineConfiguration->isAlternatorControlEnabled), @@ -135,7 +131,6 @@ void initAlternatorCtrl() { &enginePins.alternatorPin, engineConfiguration->alternatorPwmFrequency, 0); } - instance.Start(); } // todo: start invoking this method like 'startVvtControlPins' @@ -147,5 +142,4 @@ void stopAlternatorPin(void) { // todo: implementation! } - #endif /* EFI_ALTERNATOR_CONTROL */ diff --git a/firmware/controllers/actuators/alternator_controller.h b/firmware/controllers/actuators/alternator_controller.h index c13e7231c1..69d5fed545 100644 --- a/firmware/controllers/actuators/alternator_controller.h +++ b/firmware/controllers/actuators/alternator_controller.h @@ -18,4 +18,9 @@ void setAltIFactor(float p); void setAltDFactor(float p); void showAltInfo(void); +class AlternatorController : public EngineModule { +public: + void onFastCallback() override; +}; + void onConfigurationChangeAlternatorCallback(engine_configuration_s *previousConfiguration); diff --git a/firmware/controllers/algo/engine.h b/firmware/controllers/algo/engine.h index 69f5935cb9..d2e4770c7c 100644 --- a/firmware/controllers/algo/engine.h +++ b/firmware/controllers/algo/engine.h @@ -34,6 +34,7 @@ #include "ac_control.h" #include "type_list.h" #include "boost_control.h" +#include "alternator_controller.h" #ifndef EFI_UNIT_TEST #error EFI_UNIT_TEST must be defined! @@ -119,6 +120,11 @@ public: bool isPwmEnabled = true; const char *prevOutputName = nullptr; + /** + * ELM327 cannot handle both RX and TX at the same time, we have to stay quite once first ISO/TP packet was detected + * this is a pretty temporary hack only while we are trying ELM327, long term ISO/TP and rusEFI broadcast should find a way to coexists + */ + bool pauseCANdueToSerial = false; PinRepository pinRepository; @@ -136,7 +142,9 @@ public: #if EFI_HPFP && EFI_ENGINE_CONTROL HpfpController, #endif // EFI_HPFP && EFI_ENGINE_CONTROL - +#if EFI_ALTERNATOR_CONTROL + AlternatorController, +#endif /* EFI_ALTERNATOR_CONTROL */ FuelPumpController, MainRelayController, AcController, @@ -330,11 +338,6 @@ public: void resetEngineSnifferIfInTestMode(); - /** - * pre-calculated offset for given sequence index within engine cycle - * (not cylinder ID) - */ - angle_t ignitionPositionWithinEngineCycle[MAX_CYLINDER_COUNT]; /** * pre-calculated reference to which output pin should be used for * given sequence index within engine cycle diff --git a/firmware/controllers/can/can_tx.cpp b/firmware/controllers/can/can_tx.cpp index 071d491a0f..c967d853db 100644 --- a/firmware/controllers/can/can_tx.cpp +++ b/firmware/controllers/can/can_tx.cpp @@ -31,7 +31,7 @@ void CanWrite::PeriodicTask(efitime_t nowNt) { CanCycle cycle(cycleCount); //in case we have Verbose Can enabled, we should keep user configured period - if (engineConfiguration->enableVerboseCanTx) { + if (engineConfiguration->enableVerboseCanTx && !engine->pauseCANdueToSerial) { uint16_t cycleCountsPeriodMs = cycleCount * CAN_CYCLE_PERIOD; if (0 != engineConfiguration->canSleepPeriodMs) { if (cycleCountsPeriodMs % engineConfiguration->canSleepPeriodMs) { diff --git a/firmware/controllers/date_stamp.h b/firmware/controllers/date_stamp.h index 7687d58723..7e13406267 100644 --- a/firmware/controllers/date_stamp.h +++ b/firmware/controllers/date_stamp.h @@ -1,2 +1,2 @@ #pragma once -#define VCS_DATE 20211204 +#define VCS_DATE 20211206 diff --git a/firmware/controllers/engine_controller.cpp b/firmware/controllers/engine_controller.cpp index 6f46898cd5..f3df8c892d 100644 --- a/firmware/controllers/engine_controller.cpp +++ b/firmware/controllers/engine_controller.cpp @@ -741,7 +741,7 @@ void initEngineContoller() { * UNUSED_SIZE constants. */ #ifndef RAM_UNUSED_SIZE -#define RAM_UNUSED_SIZE 18000 +#define RAM_UNUSED_SIZE 13000 #endif #ifndef CCM_UNUSED_SIZE #define CCM_UNUSED_SIZE 16 diff --git a/firmware/controllers/engine_cycle/fuel_schedule.cpp b/firmware/controllers/engine_cycle/fuel_schedule.cpp index 5388f71f4f..ab9b8ba2a2 100644 --- a/firmware/controllers/engine_cycle/fuel_schedule.cpp +++ b/firmware/controllers/engine_cycle/fuel_schedule.cpp @@ -107,9 +107,7 @@ bool FuelSchedule::addFuelEventsForCylinder(int i ) { warning(CUSTOM_OBD_INJECTION_NO_PIN_ASSIGNED, "no_pin_inj #%s", output->name); } - angle_t ignitionPositionWithinEngineCycle = engine->ignitionPositionWithinEngineCycle[i]; - - float angle = baseAngle + ignitionPositionWithinEngineCycle; + float angle = baseAngle + getCylinderAngle(i, ev->cylinderNumber); if (TRIGGER_WAVEFORM(getSize()) < 1) { warning(CUSTOM_ERR_NOT_INITIALIZED_TRIGGER, "uninitialized TriggerWaveform"); diff --git a/firmware/controllers/engine_cycle/map_averaging.cpp b/firmware/controllers/engine_cycle/map_averaging.cpp index 048de73ee6..b5f98931d4 100644 --- a/firmware/controllers/engine_cycle/map_averaging.cpp +++ b/firmware/controllers/engine_cycle/map_averaging.cpp @@ -111,7 +111,7 @@ void mapAveragingAdcCallback(adcsample_t adcValue) { if (engineConfiguration->vvtMode[0] == VVT_MAP_V_TWIN && ((fastMapCounter++ % engineConfiguration->mapCamSkipFactor) == 0)) { engine->triggerCentral.mapState.add(instantMap); - bool isPeak = engine->triggerCentral.mapState.isPeak(); + bool isPeak = engine->triggerCentral.mapState.isPeak(engineConfiguration->mapCamLookForLowPeaks); #if EFI_TUNER_STUDIO tsOutputChannels.TEMPLOG_map_length = MAP_CAM_BUFFER; tsOutputChannels.TEMPLOG_MAP_INSTANT_AVERAGE = engine->triggerCentral.mapState.current; diff --git a/firmware/controllers/engine_cycle/spark_logic.cpp b/firmware/controllers/engine_cycle/spark_logic.cpp index 3934dab9a2..c153c8bcea 100644 --- a/firmware/controllers/engine_cycle/spark_logic.cpp +++ b/firmware/controllers/engine_cycle/spark_logic.cpp @@ -73,12 +73,14 @@ static void prepareCylinderIgnitionSchedule(angle_t dwellAngleDuration, floatms_ // let's save planned duration so that we can later compare it with reality event->sparkDwell = sparkDwell; - // change of sign here from 'before TDC' to 'after TDC' - angle_t ignitionPositionWithinEngineCycle = engine->ignitionPositionWithinEngineCycle[event->cylinderIndex]; - assertAngleRange(ignitionPositionWithinEngineCycle, "aPWEC", CUSTOM_ERR_6566); - // this correction is usually zero (not used) - float perCylinderCorrection = engineConfiguration->timing_offset_cylinder[event->cylinderIndex]; - const angle_t sparkAngle = -engine->engineState.timingAdvance + engine->knockController.getKnockRetard() + ignitionPositionWithinEngineCycle + perCylinderCorrection; + const angle_t sparkAngle = + // Negate because timing *before* TDC, and we schedule *after* TDC + - engine->engineState.timingAdvance + // Offset by this cylinder's position in the cycle + + getCylinderAngle(event->cylinderIndex, event->cylinderNumber) + // Pull any extra timing for knock retard + + engine->knockController.getKnockRetard(); + efiAssertVoid(CUSTOM_SPARK_ANGLE_9, !cisnan(sparkAngle), "findAngle#9"); efiAssertVoid(CUSTOM_SPARK_ANGLE_1, !cisnan(sparkAngle), "sparkAngle#1"); diff --git a/firmware/controllers/generated/signature_all.h b/firmware/controllers/generated/signature_all.h index 52bbd1a58e..0df6318312 100644 --- a/firmware/controllers/generated/signature_all.h +++ b/firmware/controllers/generated/signature_all.h @@ -2,5 +2,5 @@ // was generated automatically by rusEFI tool ConfigDefinition.jar based on gen_config.sh integration/rusefi_config.txt // -#define SIGNATURE_HASH 3197887637 -#define TS_SIGNATURE "rusEFI 2021.12.05.all.3197887637" +#define SIGNATURE_HASH 3288789643 +#define TS_SIGNATURE "rusEFI 2021.12.06.all.3288789643" diff --git a/firmware/controllers/generated/signature_atlas.h b/firmware/controllers/generated/signature_atlas.h index bfbcc6198b..9070a385e0 100644 --- a/firmware/controllers/generated/signature_atlas.h +++ b/firmware/controllers/generated/signature_atlas.h @@ -2,5 +2,5 @@ // was generated automatically by rusEFI tool ConfigDefinition.jar based on gen_config.sh integration/rusefi_config.txt // -#define SIGNATURE_HASH 2723221938 -#define TS_SIGNATURE "rusEFI 2021.12.05.atlas.2723221938" +#define SIGNATURE_HASH 3637249964 +#define TS_SIGNATURE "rusEFI 2021.12.06.atlas.3637249964" diff --git a/firmware/controllers/generated/signature_f429-discovery.h b/firmware/controllers/generated/signature_f429-discovery.h index 65dc1cf9d0..49a855a707 100644 --- a/firmware/controllers/generated/signature_f429-discovery.h +++ b/firmware/controllers/generated/signature_f429-discovery.h @@ -2,5 +2,5 @@ // was generated automatically by rusEFI tool ConfigDefinition.jar based on gen_config.sh integration/rusefi_config.txt // -#define SIGNATURE_HASH 3197887637 -#define TS_SIGNATURE "rusEFI 2021.12.05.f429-discovery.3197887637" +#define SIGNATURE_HASH 3288789643 +#define TS_SIGNATURE "rusEFI 2021.12.06.f429-discovery.3288789643" diff --git a/firmware/controllers/generated/signature_frankenso_na6.h b/firmware/controllers/generated/signature_frankenso_na6.h index deebbabc89..41cc89d71e 100644 --- a/firmware/controllers/generated/signature_frankenso_na6.h +++ b/firmware/controllers/generated/signature_frankenso_na6.h @@ -2,5 +2,5 @@ // was generated automatically by rusEFI tool ConfigDefinition.jar based on gen_config.sh integration/rusefi_config.txt // -#define SIGNATURE_HASH 3299455356 -#define TS_SIGNATURE "rusEFI 2021.12.05.frankenso_na6.3299455356" +#define SIGNATURE_HASH 3191121762 +#define TS_SIGNATURE "rusEFI 2021.12.06.frankenso_na6.3191121762" diff --git a/firmware/controllers/generated/signature_hellen-nb1.h b/firmware/controllers/generated/signature_hellen-nb1.h index e13306ad7e..5aab790917 100644 --- a/firmware/controllers/generated/signature_hellen-nb1.h +++ b/firmware/controllers/generated/signature_hellen-nb1.h @@ -2,5 +2,5 @@ // was generated automatically by rusEFI tool ConfigDefinition.jar based on gen_config.sh integration/rusefi_config.txt // -#define SIGNATURE_HASH 457823260 -#define TS_SIGNATURE "rusEFI 2021.12.05.hellen-nb1.457823260" +#define SIGNATURE_HASH 1641333250 +#define TS_SIGNATURE "rusEFI 2021.12.06.hellen-nb1.1641333250" diff --git a/firmware/controllers/generated/signature_hellen121nissan.h b/firmware/controllers/generated/signature_hellen121nissan.h index dc6f583d91..67f1b7cf37 100644 --- a/firmware/controllers/generated/signature_hellen121nissan.h +++ b/firmware/controllers/generated/signature_hellen121nissan.h @@ -2,5 +2,5 @@ // was generated automatically by rusEFI tool ConfigDefinition.jar based on gen_config.sh integration/rusefi_config.txt // -#define SIGNATURE_HASH 85952052 -#define TS_SIGNATURE "rusEFI 2021.12.05.hellen121nissan.85952052" +#define SIGNATURE_HASH 2139263018 +#define TS_SIGNATURE "rusEFI 2021.12.06.hellen121nissan.2139263018" diff --git a/firmware/controllers/generated/signature_hellen121vag.h b/firmware/controllers/generated/signature_hellen121vag.h index e84f82f502..52d5fec320 100644 --- a/firmware/controllers/generated/signature_hellen121vag.h +++ b/firmware/controllers/generated/signature_hellen121vag.h @@ -2,5 +2,5 @@ // was generated automatically by rusEFI tool ConfigDefinition.jar based on gen_config.sh integration/rusefi_config.txt // -#define SIGNATURE_HASH 3778592927 -#define TS_SIGNATURE "rusEFI 2021.12.05.hellen121vag.3778592927" +#define SIGNATURE_HASH 2611336833 +#define TS_SIGNATURE "rusEFI 2021.12.06.hellen121vag.2611336833" diff --git a/firmware/controllers/generated/signature_hellen128.h b/firmware/controllers/generated/signature_hellen128.h index f6f5b06cd9..7ba8bc4ae8 100644 --- a/firmware/controllers/generated/signature_hellen128.h +++ b/firmware/controllers/generated/signature_hellen128.h @@ -2,5 +2,5 @@ // was generated automatically by rusEFI tool ConfigDefinition.jar based on gen_config.sh integration/rusefi_config.txt // -#define SIGNATURE_HASH 610111282 -#define TS_SIGNATURE "rusEFI 2021.12.05.hellen128.610111282" +#define SIGNATURE_HASH 1589680428 +#define TS_SIGNATURE "rusEFI 2021.12.06.hellen128.1589680428" diff --git a/firmware/controllers/generated/signature_hellen154hyundai.h b/firmware/controllers/generated/signature_hellen154hyundai.h index 7c0b83aa82..21721405e1 100644 --- a/firmware/controllers/generated/signature_hellen154hyundai.h +++ b/firmware/controllers/generated/signature_hellen154hyundai.h @@ -2,5 +2,5 @@ // was generated automatically by rusEFI tool ConfigDefinition.jar based on gen_config.sh integration/rusefi_config.txt // -#define SIGNATURE_HASH 2622481971 -#define TS_SIGNATURE "rusEFI 2021.12.05.hellen154hyundai.2622481971" +#define SIGNATURE_HASH 3872583725 +#define TS_SIGNATURE "rusEFI 2021.12.06.hellen154hyundai.3872583725" diff --git a/firmware/controllers/generated/signature_hellen72.h b/firmware/controllers/generated/signature_hellen72.h index 223c7647ca..5fc9d01830 100644 --- a/firmware/controllers/generated/signature_hellen72.h +++ b/firmware/controllers/generated/signature_hellen72.h @@ -2,5 +2,5 @@ // was generated automatically by rusEFI tool ConfigDefinition.jar based on gen_config.sh integration/rusefi_config.txt // -#define SIGNATURE_HASH 1244029733 -#define TS_SIGNATURE "rusEFI 2021.12.05.hellen72.1244029733" +#define SIGNATURE_HASH 817591611 +#define TS_SIGNATURE "rusEFI 2021.12.06.hellen72.817591611" diff --git a/firmware/controllers/generated/signature_hellen81.h b/firmware/controllers/generated/signature_hellen81.h index d04005c4d3..724d48ec82 100644 --- a/firmware/controllers/generated/signature_hellen81.h +++ b/firmware/controllers/generated/signature_hellen81.h @@ -2,5 +2,5 @@ // was generated automatically by rusEFI tool ConfigDefinition.jar based on gen_config.sh integration/rusefi_config.txt // -#define SIGNATURE_HASH 4264296150 -#define TS_SIGNATURE "rusEFI 2021.12.05.hellen81.4264296150" +#define SIGNATURE_HASH 2226579656 +#define TS_SIGNATURE "rusEFI 2021.12.06.hellen81.2226579656" diff --git a/firmware/controllers/generated/signature_hellen88bmw.h b/firmware/controllers/generated/signature_hellen88bmw.h index 94d0c348fd..25a10c7c35 100644 --- a/firmware/controllers/generated/signature_hellen88bmw.h +++ b/firmware/controllers/generated/signature_hellen88bmw.h @@ -2,5 +2,5 @@ // was generated automatically by rusEFI tool ConfigDefinition.jar based on gen_config.sh integration/rusefi_config.txt // -#define SIGNATURE_HASH 526087626 -#define TS_SIGNATURE "rusEFI 2021.12.05.hellen88bmw.526087626" +#define SIGNATURE_HASH 1707500500 +#define TS_SIGNATURE "rusEFI 2021.12.06.hellen88bmw.1707500500" diff --git a/firmware/controllers/generated/signature_hellenNA6.h b/firmware/controllers/generated/signature_hellenNA6.h index 87b42d85c6..84c5baca11 100644 --- a/firmware/controllers/generated/signature_hellenNA6.h +++ b/firmware/controllers/generated/signature_hellenNA6.h @@ -2,5 +2,5 @@ // was generated automatically by rusEFI tool ConfigDefinition.jar based on gen_config.sh integration/rusefi_config.txt // -#define SIGNATURE_HASH 3366363709 -#define TS_SIGNATURE "rusEFI 2021.12.05.hellenNA6.3366363709" +#define SIGNATURE_HASH 2990257187 +#define TS_SIGNATURE "rusEFI 2021.12.06.hellenNA6.2990257187" diff --git a/firmware/controllers/generated/signature_hellen_cypress.h b/firmware/controllers/generated/signature_hellen_cypress.h index 2929ceaa36..7da007ffd2 100644 --- a/firmware/controllers/generated/signature_hellen_cypress.h +++ b/firmware/controllers/generated/signature_hellen_cypress.h @@ -2,5 +2,5 @@ // was generated automatically by rusEFI tool ConfigDefinition.jar based on hellen_cypress_gen_config.bat integration/rusefi_config.txt // -#define SIGNATURE_HASH 2221802281 -#define TS_SIGNATURE "rusEFI 2021.12.05.hellen_cypress.2221802281" +#define SIGNATURE_HASH 4277343543 +#define TS_SIGNATURE "rusEFI 2021.12.06.hellen_cypress.4277343543" diff --git a/firmware/controllers/generated/signature_kin.h b/firmware/controllers/generated/signature_kin.h index b0108e4ba2..735ee6c996 100644 --- a/firmware/controllers/generated/signature_kin.h +++ b/firmware/controllers/generated/signature_kin.h @@ -2,5 +2,5 @@ // was generated automatically by rusEFI tool ConfigDefinition.jar based on kinetis_gen_config.bat integration/rusefi_config.txt // -#define SIGNATURE_HASH 2076954581 -#define TS_SIGNATURE "rusEFI 2021.12.05.kin.2076954581" +#define SIGNATURE_HASH 22469067 +#define TS_SIGNATURE "rusEFI 2021.12.06.kin.22469067" diff --git a/firmware/controllers/generated/signature_mre_f4.h b/firmware/controllers/generated/signature_mre_f4.h index 64ddfbe9d7..c6cb167091 100644 --- a/firmware/controllers/generated/signature_mre_f4.h +++ b/firmware/controllers/generated/signature_mre_f4.h @@ -2,5 +2,5 @@ // was generated automatically by rusEFI tool ConfigDefinition.jar based on gen_config.sh integration/rusefi_config.txt // -#define SIGNATURE_HASH 230465057 -#define TS_SIGNATURE "rusEFI 2021.12.05.mre_f4.230465057" +#define SIGNATURE_HASH 1998686271 +#define TS_SIGNATURE "rusEFI 2021.12.06.mre_f4.1998686271" diff --git a/firmware/controllers/generated/signature_mre_f7.h b/firmware/controllers/generated/signature_mre_f7.h index b93b987dfb..cdca9f2598 100644 --- a/firmware/controllers/generated/signature_mre_f7.h +++ b/firmware/controllers/generated/signature_mre_f7.h @@ -2,5 +2,5 @@ // was generated automatically by rusEFI tool ConfigDefinition.jar based on gen_config.sh integration/rusefi_config.txt // -#define SIGNATURE_HASH 230465057 -#define TS_SIGNATURE "rusEFI 2021.12.05.mre_f7.230465057" +#define SIGNATURE_HASH 1998686271 +#define TS_SIGNATURE "rusEFI 2021.12.06.mre_f7.1998686271" diff --git a/firmware/controllers/generated/signature_prometheus_405.h b/firmware/controllers/generated/signature_prometheus_405.h index 15dc6295a0..118c201df6 100644 --- a/firmware/controllers/generated/signature_prometheus_405.h +++ b/firmware/controllers/generated/signature_prometheus_405.h @@ -2,5 +2,5 @@ // was generated automatically by rusEFI tool ConfigDefinition.jar based on gen_config.sh integration/rusefi_config.txt // -#define SIGNATURE_HASH 4000398707 -#define TS_SIGNATURE "rusEFI 2021.12.05.prometheus_405.4000398707" +#define SIGNATURE_HASH 2498505581 +#define TS_SIGNATURE "rusEFI 2021.12.06.prometheus_405.2498505581" diff --git a/firmware/controllers/generated/signature_prometheus_469.h b/firmware/controllers/generated/signature_prometheus_469.h index 0b7d26e092..24ebbb87ab 100644 --- a/firmware/controllers/generated/signature_prometheus_469.h +++ b/firmware/controllers/generated/signature_prometheus_469.h @@ -2,5 +2,5 @@ // was generated automatically by rusEFI tool ConfigDefinition.jar based on gen_config.sh integration/rusefi_config.txt // -#define SIGNATURE_HASH 4000398707 -#define TS_SIGNATURE "rusEFI 2021.12.05.prometheus_469.4000398707" +#define SIGNATURE_HASH 2498505581 +#define TS_SIGNATURE "rusEFI 2021.12.06.prometheus_469.2498505581" diff --git a/firmware/controllers/generated/signature_proteus_f4.h b/firmware/controllers/generated/signature_proteus_f4.h index 4947fd3c24..f69677fb8d 100644 --- a/firmware/controllers/generated/signature_proteus_f4.h +++ b/firmware/controllers/generated/signature_proteus_f4.h @@ -2,5 +2,5 @@ // was generated automatically by rusEFI tool ConfigDefinition.jar based on gen_config.sh integration/rusefi_config.txt // -#define SIGNATURE_HASH 44703546 -#define TS_SIGNATURE "rusEFI 2021.12.05.proteus_f4.44703546" +#define SIGNATURE_HASH 2016872740 +#define TS_SIGNATURE "rusEFI 2021.12.06.proteus_f4.2016872740" diff --git a/firmware/controllers/generated/signature_proteus_f7.h b/firmware/controllers/generated/signature_proteus_f7.h index c1f501e70d..28f8cfcd54 100644 --- a/firmware/controllers/generated/signature_proteus_f7.h +++ b/firmware/controllers/generated/signature_proteus_f7.h @@ -2,5 +2,5 @@ // was generated automatically by rusEFI tool ConfigDefinition.jar based on gen_config.sh integration/rusefi_config.txt // -#define SIGNATURE_HASH 44703546 -#define TS_SIGNATURE "rusEFI 2021.12.05.proteus_f7.44703546" +#define SIGNATURE_HASH 2016872740 +#define TS_SIGNATURE "rusEFI 2021.12.06.proteus_f7.2016872740" diff --git a/firmware/controllers/generated/signature_subaru_eg33_f7.h b/firmware/controllers/generated/signature_subaru_eg33_f7.h index b20787c485..ce9aaa70b4 100644 --- a/firmware/controllers/generated/signature_subaru_eg33_f7.h +++ b/firmware/controllers/generated/signature_subaru_eg33_f7.h @@ -2,5 +2,5 @@ // was generated automatically by rusEFI tool ConfigDefinition.jar based on config/boards/subaru_eg33/config/gen_config.sh integration/rusefi_config.txt // -#define SIGNATURE_HASH 2099376837 -#define TS_SIGNATURE "rusEFI 2021.12.05.subaru_eg33_f7.2099376837" +#define SIGNATURE_HASH 129819867 +#define TS_SIGNATURE "rusEFI 2021.12.06.subaru_eg33_f7.129819867" diff --git a/firmware/controllers/math/engine_math.cpp b/firmware/controllers/math/engine_math.cpp index b82dd422d4..d41447323b 100644 --- a/firmware/controllers/math/engine_math.cpp +++ b/firmware/controllers/math/engine_math.cpp @@ -440,10 +440,6 @@ void prepareOutputSignals() { } #endif /* EFI_UNIT_TEST */ - for (size_t i = 0; i < engineConfiguration->specs.cylindersCount; i++) { - engine->ignitionPositionWithinEngineCycle[i] = engine->engineCycle * i / engineConfiguration->specs.cylindersCount; - } - prepareIgnitionPinIndices(engineConfiguration->ignitionMode); TRIGGER_WAVEFORM(prepareShape(&engine->triggerCentral.triggerFormDetails)); @@ -452,6 +448,21 @@ void prepareOutputSignals() { engine->injectionEvents.invalidate(); } +angle_t getCylinderAngle(uint8_t cylinderIndex, uint8_t cylinderNumber) { + // base = position of this cylinder in the firing order. + // We get a cylinder every n-th of an engine cycle where N is the number of cylinders + auto base = engine->engineCycle * cylinderIndex / engineConfiguration->specs.cylindersCount; + + // Plus or minus any adjustment if this is an odd-fire engine + auto adjustment = engineConfiguration->timing_offset_cylinder[cylinderNumber]; + + auto result = base + adjustment; + + assertAngleRange(result, "getCylinderAngle", CUSTOM_ERR_6566); + + return result; +} + void setTimingRpmBin(float from, float to) { setRpmBin(config->ignitionRpmBins, IGN_RPM_COUNT, from, to); } diff --git a/firmware/controllers/math/engine_math.h b/firmware/controllers/math/engine_math.h index 2a8207439d..565a300731 100644 --- a/firmware/controllers/math/engine_math.h +++ b/firmware/controllers/math/engine_math.h @@ -62,3 +62,11 @@ void setSingleCoilDwell(); // while for toothed wheels user would have to provide a value #define tdcPosition() \ (TRIGGER_WAVEFORM(tdcPosition) + engineConfiguration->globalTriggerAngleOffset) + +/** Gets phase offset for a particular cylinder's ID and number + * For example on 4 cylinder engine with firing order 1-3-4-2, this + * returns 0-180-360-540 for index 0-1-2-3 + * Cylinder number is used for per-cylinder adjustment, if you have + * an odd-fire engine (v-twin, V10, some v6, etc) + */ +angle_t getCylinderAngle(uint8_t cylinderIndex, uint8_t cylinderNumber); diff --git a/firmware/controllers/trigger/trigger_central.h b/firmware/controllers/trigger/trigger_central.h index 1f1ff9f24f..fdf79ee995 100644 --- a/firmware/controllers/trigger/trigger_central.h +++ b/firmware/controllers/trigger/trigger_central.h @@ -48,8 +48,12 @@ struct MapState { current = mapBuffer.sum(engineConfiguration->mapCamAveragingLength); } - bool isPeak() { - return previous > prevPrevious && previous >= current; + bool isPeak(bool lookForLowPeak) { + if (lookForLowPeak) { + return previous < prevPrevious && previous <= current; + } else { + return previous > prevPrevious && previous >= current; + } } }; diff --git a/firmware/integration/rusefi_config.txt b/firmware/integration/rusefi_config.txt index 098ac33476..634b15f1f1 100644 --- a/firmware/integration/rusefi_config.txt +++ b/firmware/integration/rusefi_config.txt @@ -70,7 +70,7 @@ ! Any time an incompatible change is made to the configuration format stored in flash, ! update this string to the current date! It is required to also update TS_SIGNATURE above ! when this happens. -#define FLASH_DATA_VERSION 10003 +#define FLASH_DATA_VERSION 10004 #define LOG_DELIMITER "`" @@ -893,7 +893,7 @@ custom maf_sensor_type_e 4 bits, S32, @OFFSET@, [0:1], @@maf_sensor_type_e_enum@ bit enableInnovateLC2 bit showHumanReadableWarning bit stftIgnoreErrorMagnitude;+If enabled, adjust at a constant rate instead of a rate proportional to the current lambda error. This mode may be easier to tune, and more tolerant of sensor noise. Use of this mode is required if you have a narrowband O2 sensor. - bit unused976b11 + bit mapCamLookForLowPeaks bit enableSoftwareKnock bit verboseVVTDecoding;enable vvt_details bit invertCamVVTSignal;get invertCamVVTSignal @@ -1548,7 +1548,7 @@ float[IDLE_ADVANCE_CURVE_SIZE] idleAdvance ;Optional timing advance table for float[IDLE_VE_CURVE_SIZE] idleVeBins;Optional VE table for Idle (see useSeparateVEForIdle);"RPM", 1, 0, 0, 18000, 2 float[IDLE_VE_CURVE_SIZE] idleVe; Optional VE table for Idle (see useSeparateVEForIdle);"%", 1, 0, 0, 999, 2 -#define LUA_SCRIPT_SIZE 3600 +#define LUA_SCRIPT_SIZE 8000 custom lua_script_t @@LUA_SCRIPT_SIZE@@ string, ASCII, @OFFSET@, @@LUA_SCRIPT_SIZE@@ lua_script_t luaScript; @@ -1991,5 +1991,5 @@ end_struct #define show_test_presets true #define show_Frankenso_presets true -#define CAN_SERIAL_RX_ID 0x100 -#define CAN_SERIAL_TX_ID 0x102 +#define CAN_ECU_SERIAL_RX_ID 0x100 +#define CAN_ECU_SERIAL_TX_ID 0x102 diff --git a/firmware/tunerstudio/rusefi.input b/firmware/tunerstudio/rusefi.input index 477e0b3134..f2463185b2 100644 --- a/firmware/tunerstudio/rusefi.input +++ b/firmware/tunerstudio/rusefi.input @@ -2773,7 +2773,6 @@ cmd_set_engine_type_default = "@@TS_IO_TEST_COMMAND_char@@\x00\x31\x00\x00" field = "PWM frequency", alternatorPwmFrequency, {isAlternatorControlEnabled == 1 && onOffAlternatorLogic == 0} field = "Off Above TPS", alternatorOffAboveTps, {isAlternatorControlEnabled == 1} field = "Detailed status in console", isVerboseAlternator, {isAlternatorControlEnabled == 1} - field = "control period", alternatorControl_periodMs, {isAlternatorControlEnabled == 1} field = "#PID control" field = "offset", alternatorControl_offset, {isAlternatorControlEnabled == 1 && onOffAlternatorLogic == 0} field = "P factor", alternatorControl_pFactor, {isAlternatorControlEnabled == 1 && onOffAlternatorLogic == 0} @@ -3401,6 +3400,7 @@ cmd_set_engine_type_default = "@@TS_IO_TEST_COMMAND_char@@\x00\x31\x00\x00" field = "mapCamDetectionThreshold", mapCamDetectionThreshold field = "mapCamAveragingLength", mapCamAveragingLength field = "mapCamSkipFactor", mapCamSkipFactor + field = "mapCamLookForLowPeaks", mapCamLookForLowPeaks field = "#System hacks" field = "Global fuel correction", globalFuelCorrection field = "MAP Averaging Logic @", mapAveragingSchedulingAtIndex diff --git a/java_console/.idea/runConfigurations/Launcher_elm327_connector.xml b/java_console/.idea/runConfigurations/Launcher_elm327_connector.xml new file mode 100644 index 0000000000..0cf9e8c954 --- /dev/null +++ b/java_console/.idea/runConfigurations/Launcher_elm327_connector.xml @@ -0,0 +1,11 @@ + + + + \ No newline at end of file diff --git a/java_console/autotest/src/main/java/com/rusefi/autotest/ControllerConnectorState.java b/java_console/autotest/src/main/java/com/rusefi/autotest/ControllerConnectorState.java index b9ddcd1831..eb8401cf55 100644 --- a/java_console/autotest/src/main/java/com/rusefi/autotest/ControllerConnectorState.java +++ b/java_console/autotest/src/main/java/com/rusefi/autotest/ControllerConnectorState.java @@ -40,6 +40,7 @@ public class ControllerConnectorState { port = PortDetector.autoDetectSerial(null).getSerialPort(); if (port == null) throw new IllegalStateException("ECU serial not detected"); + System.out.println("Auto-connected to " + port); } IoUtil.realHardwareConnect(linkManager, port); diff --git a/java_console/io/src/main/java/com/rusefi/binaryprotocol/BinaryProtocol.java b/java_console/io/src/main/java/com/rusefi/binaryprotocol/BinaryProtocol.java index bd7c74728f..b93305b3c3 100644 --- a/java_console/io/src/main/java/com/rusefi/binaryprotocol/BinaryProtocol.java +++ b/java_console/io/src/main/java/com/rusefi/binaryprotocol/BinaryProtocol.java @@ -12,7 +12,6 @@ import com.rusefi.Timeouts; import com.rusefi.composite.CompositeEvent; import com.rusefi.composite.CompositeParser; import com.rusefi.config.generated.Fields; -import com.rusefi.core.MessagesCentral; import com.rusefi.core.Pair; import com.rusefi.core.Sensor; import com.rusefi.core.SensorCentral; @@ -28,7 +27,6 @@ import com.rusefi.ui.livedocs.LiveDocsRegistry; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.io.EOFException; import java.io.IOException; import java.nio.ByteBuffer; import java.nio.ByteOrder; @@ -84,7 +82,7 @@ public class BinaryProtocol { private boolean isCompositeLoggerEnabled; private long lastLowRpmTime = System.currentTimeMillis(); - private List compositeLogs = new ArrayList<>(); + private final List compositeLogs = new ArrayList<>(); public static boolean DISABLE_LOCAL_CACHE; public static String findCommand(byte command) { @@ -220,9 +218,9 @@ public class BinaryProtocol { linkManager.getCommandQueue().handleConfirmationMessage(CommandQueue.CONFIRMATION_PREFIX + command); } - public String getSignature() throws IOException { + public static String getSignature(IoStream stream) throws IOException { HelloCommand.send(stream); - return HelloCommand.getHelloResponse(incomingData); + return HelloCommand.getHelloResponse(stream.getDataBuffer()); } /** @@ -232,7 +230,7 @@ public class BinaryProtocol { */ public boolean connectAndReadConfiguration(DataListener listener) { try { - signature = getSignature(); + signature = getSignature(stream); System.out.println("BinaryProtocol: Got " + signature + " signature"); SignatureHelper.downloadIfNotAvailable(SignatureHelper.getUrl(signature)); } catch (IOException e) { @@ -432,10 +430,7 @@ public class BinaryProtocol { int crcOfLocallyCachedConfiguration = IoHelper.getCrc32(localCached.getContent()); log.info(String.format(CONFIGURATION_RUSEFI_BINARY + " Local cache CRC %x\n", crcOfLocallyCachedConfiguration)); - byte packet[] = new byte[5]; - packet[0] = Fields.TS_CRC_CHECK_COMMAND; - putShort(packet, 1, swap16(/*offset = */ 0)); - putShort(packet, 3, swap16(localCached.getSize())); + byte[] packet = createCrcCommand(localCached.getSize()); byte[] response = executeCommand(packet, "get CRC32"); if (checkResponseCode(response, (byte) Fields.TS_RESPONSE_OK) && response.length == 5) { @@ -454,6 +449,14 @@ public class BinaryProtocol { return null; } + public static byte[] createCrcCommand(int size) { + byte[] packet = new byte[5]; + packet[0] = Fields.TS_CRC_CHECK_COMMAND; + putShort(packet, 1, swap16(/*offset = */ 0)); + putShort(packet, 3, swap16(size)); + return packet; + } + public byte[] executeCommand(byte[] packet, String msg) { return executeCommand(packet, msg, false); } diff --git a/java_console/io/src/main/java/com/rusefi/binaryprotocol/IncomingDataBuffer.java b/java_console/io/src/main/java/com/rusefi/binaryprotocol/IncomingDataBuffer.java index 5b9931e39d..863fc0fdb3 100644 --- a/java_console/io/src/main/java/com/rusefi/binaryprotocol/IncomingDataBuffer.java +++ b/java_console/io/src/main/java/com/rusefi/binaryprotocol/IncomingDataBuffer.java @@ -140,6 +140,12 @@ public class IncomingDataBuffer { return false; // looks good! } + public int getPendingCount() { + synchronized (cbb) { + return cbb.length(); + } + } + public void dropPending() { // todo: when exactly do we need this logic? synchronized (cbb) { diff --git a/java_console/io/src/main/java/com/rusefi/io/can/Elm327Connector.java b/java_console/io/src/main/java/com/rusefi/io/can/Elm327Connector.java index 280b9fa0e6..cadfe60a58 100644 --- a/java_console/io/src/main/java/com/rusefi/io/can/Elm327Connector.java +++ b/java_console/io/src/main/java/com/rusefi/io/can/Elm327Connector.java @@ -2,15 +2,12 @@ package com.rusefi.io.can; import com.devexperts.logging.Logging; import com.opensr5.io.DataListener; +import com.rusefi.config.generated.Fields; import com.rusefi.io.IoStream; -import com.rusefi.io.serial.SerialIoStream; -import com.rusefi.io.tcp.BinaryProtocolProxy; -import com.rusefi.io.tcp.TcpConnector; import java.io.Closeable; import java.io.IOException; import java.util.ArrayList; -import java.util.Arrays; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -21,81 +18,55 @@ public class Elm327Connector implements Closeable { private final static Logging log = Logging.getLogging(Elm327Connector.class); private static final byte[] HEX_ARRAY = "0123456789ABCDEF".getBytes(); +// public final static int ELM327_DEFAULT_BAUDRATE = 115200; // OBDlink SX, 1.3a public final static int ELM327_DEFAULT_BAUDRATE = 38400; private final static int BIG_TIMEOUT = 2 * SECOND; private final static int TIMEOUT = 70; public static final String HELLO = "ATZ"; public static final String ELM_EOL = "\r"; + // those are inverted between ECU side and PC side + private static final int CAN_PC_SERIAL_RX_ID = Fields.CAN_ECU_SERIAL_TX_ID; + private static final int CAN_PC_SERIAL_TX_ID = Fields.CAN_ECU_SERIAL_RX_ID; private final Object lock = new Object(); - // these should match the defines in the firmware - private final static int CAN_SERIAL_TX_ID = 0x100; - private final static int CAN_SERIAL_RX_ID = 0x102; - - private final static int ISO_TP_FRAME_SINGLE = 0; - private final static int ISO_TP_FRAME_FIRST = 1; - private final static int ISO_TP_FRAME_CONSECUTIVE = 2; - private final static int ISO_TP_FRAME_FLOW_CONTROL = 3; - - private IoStream stream = null; + /** + * Connection to ELM327 device where text based ELM protocol happens + */ + private final IoStream underlyingStream; + /** + * Binary serial stream for TS traffic + */ + private final Elm327IoStream tsStream; private String partialLine = ""; private final List completeLines = new ArrayList<>(); private boolean isCommandMode = false; - private Elm327IoStream elmStream; - - // CAN multiframe decoder state - static class CanDecoder { - public int waitingForNumBytes = 0; - public int waitingForFrameIndex = 0; - - public byte [] decodePacket(byte [] data) throws Exception { - int frameType = (data[0] >> 4) & 0xf; - int numBytesAvailable, frameIdx; - int dataOffset; - switch (frameType) { - case ISO_TP_FRAME_SINGLE: - numBytesAvailable = data[0] & 0xf; - dataOffset = 1; - this.waitingForNumBytes = 0; - break; - case ISO_TP_FRAME_FIRST: - this.waitingForNumBytes = ((data[0] & 0xf) << 8) | data[1]; - this.waitingForFrameIndex = 1; - numBytesAvailable = Math.min(this.waitingForNumBytes, 6); - dataOffset = 2; - break; - case ISO_TP_FRAME_CONSECUTIVE: - frameIdx = data[0] & 0xf; - if (this.waitingForNumBytes < 0 || this.waitingForFrameIndex != frameIdx) { - throw new Exception("ISO_TP_FRAME_CONSECUTIVE: That's an abnormal situation, and we probably should react?"); - } - this.waitingForFrameIndex = (this.waitingForFrameIndex + 1) & 0xf; - numBytesAvailable = Math.min(this.waitingForNumBytes, 7); - dataOffset = 1; - break; - case ISO_TP_FRAME_FLOW_CONTROL: - throw new Exception("ISO_TP_FRAME_FLOW_CONTROL: should we just ignore the FC frame?"); - default: - throw new Exception("Unknown frame type"); - } - - return Arrays.copyOfRange(data, dataOffset, dataOffset + numBytesAvailable); - } + public Elm327Connector(IoStream underlyingStream) { + this.underlyingStream = underlyingStream; + underlyingStream.setInputListener(listener); + tsStream = new Elm327IoStream(this, "elm327Stream"); } - public static boolean checkConnection(String serialPort, IoStream stream) { - Elm327Connector con = new Elm327Connector(); - boolean found = con.initConnection(serialPort, stream); - con.close(); - return found; + /** + * TODO: HUH? what's that about?! + */ + public static void whyDoWeNeedToSleepBetweenCommands() { + try { + Thread.sleep(100); + } catch (InterruptedException e) { + throw new IllegalStateException(e); + } } - public void start(String serialPort) { + public Elm327IoStream getTsStream() { + return tsStream; + } + + public void start(String msg) { log.info("* Elm327.start()"); - if (initConnection(serialPort, SerialIoStream.openPort(serialPort))) { + if (initConnection(msg)) { // reset to defaults sendCommand("ATD", "OK"); @@ -107,16 +78,16 @@ public class Elm327Connector implements Closeable { sendCommand("ATSP6", "OK"); // set rx ID - sendCommand("ATCF " + Integer.toHexString(CAN_SERIAL_RX_ID), "OK"); + sendCommand("ATCF " + Integer.toHexString(CAN_PC_SERIAL_RX_ID), "OK"); // rx ID mask = "all bits set" sendCommand("ATCM FFF", "OK"); // set tx ID - sendCommand("ATSH " + Integer.toHexString(CAN_SERIAL_TX_ID), "OK"); + sendCommand("ATSH " + Integer.toHexString(CAN_PC_SERIAL_TX_ID), "OK"); // set FC tx ID (should match our tx ID) - sendCommand("ATFCSH " + Integer.toHexString(CAN_SERIAL_TX_ID), "OK"); + sendCommand("ATFCSH " + Integer.toHexString(CAN_PC_SERIAL_TX_ID), "OK"); // set FC data sendCommand("ATFCSD 30 00 00", "OK"); // use custom FC ID & data @@ -139,16 +110,13 @@ public class Elm327Connector implements Closeable { log.info("* Ignition voltage = " + voltage); } - startNetworkConnector(TcpConnector.DEFAULT_PORT); - //sendBytesToSerial(new byte[] { 0, 1, 83, 32, 96, (byte)239, (byte)195 }); - //sendBytesToSerial(new byte[] { (byte)'V' }); } @Override public void close() { log.info("* Elm327.close()"); - if (stream != null) - stream.close(); + if (underlyingStream != null) + underlyingStream.close(); } private final DataListener listener = freshData -> { @@ -175,21 +143,21 @@ public class Elm327Connector implements Closeable { }; public void sendBytesToSerial(byte [] bytes) { - log.info("-------sendBytesToSerial "+bytes.length+" bytes:"); + log.info("-------sendBytesToSerial " + bytes.length + " byte(s):"); - for (int i = 0; i < bytes.length; i++) { - log.info("["+i+"] " + ((int)bytes[i] & 0xff)); - } + for (int i = 0; i < bytes.length; i++) { + log.info("[index=" + i + "] " + ((int) bytes[i] & 0xff)); + } // 1 frame if (bytes.length <= 7) { - sendFrame((ISO_TP_FRAME_SINGLE << 4) | bytes.length, bytes, 0, bytes.length); + sendCanFrame((IsoTpCanDecoder.ISO_TP_FRAME_SINGLE << 4) | bytes.length, bytes, 0, bytes.length); return; } // multiple frames // send the first header frame - sendFrame((ISO_TP_FRAME_FIRST << 4) | ((bytes.length >> 8) & 0x0f), bytes.length & 0xff, bytes, 0, 6); + sendCanFrame((IsoTpCanDecoder.ISO_TP_FRAME_FIRST << 4) | ((bytes.length >> 8) & 0x0f), bytes.length & 0xff, bytes, 0, 6); // get a flow control frame receiveData(); @@ -199,7 +167,7 @@ public class Elm327Connector implements Closeable { while (remaining > 0) { int len = Math.min(remaining, 7); // send the consecutive frames - sendFrame((ISO_TP_FRAME_CONSECUTIVE << 4) | ((idx++) & 0x0f), bytes, offset, len); + sendCanFrame((IsoTpCanDecoder.ISO_TP_FRAME_CONSECUTIVE << 4) | ((idx++) & 0x0f), bytes, offset, len); offset += len; remaining -= len; } @@ -207,15 +175,12 @@ public class Elm327Connector implements Closeable { /////////////////////////////////////////////////////// - private boolean initConnection(String msg, IoStream stream) { - this.stream = stream; - - this.stream.setInputListener(listener); + private boolean initConnection(String msg) { if (sendCommand(HELLO, "ELM327 v[0-9]+\\.[0-9]+", BIG_TIMEOUT) != null) { - log.info("ELM DETECTED on " + msg + "!"); + log.info("ELM DETECTED on " + msg + "! " + ELM327_DEFAULT_BAUDRATE); return true; } - log.info("ELM NOT FOUND on " + msg + "!"); + log.info("ELM NOT FOUND on " + msg + "! " + ELM327_DEFAULT_BAUDRATE); return false; } @@ -228,7 +193,7 @@ public class Elm327Connector implements Closeable { isCommandMode = true; this.completeLines.clear(); try { - this.stream.write((command + ELM_EOL).getBytes()); + underlyingStream.write((command + ELM_EOL).getBytes()); waitForResponse(timeout); } catch (IOException | InterruptedException ignore) { return null; @@ -259,15 +224,15 @@ public class Elm327Connector implements Closeable { return null; } - private void sendFrame(int hdr0, byte [] data, int offset, int len) { - sendData(new byte[] { (byte)hdr0 }, data, offset, len); + private void sendCanFrame(int hdr0, byte [] data, int offset, int len) { + sendCanData(new byte[] { (byte)hdr0 }, data, offset, len); } - private void sendFrame(int hdr0, int hdr1, byte [] data, int offset, int len) { - sendData(new byte[] { (byte)hdr0, (byte)hdr1 }, data, offset, len); + private void sendCanFrame(int hdr0, int hdr1, byte [] data, int offset, int len) { + sendCanData(new byte[] { (byte)hdr0, (byte)hdr1 }, data, offset, len); } - private void sendData(byte [] hdr, byte [] data, int offset, int len) { + private void sendCanData(byte [] hdr, byte [] data, int offset, int len) { //log.info("--------sendData offset="+Integer.toString(offset) + " len=" + Integer.toString(len) + "hdr.len=" + Integer.toString(hdr.length)); len += hdr.length; @@ -282,7 +247,7 @@ public class Elm327Connector implements Closeable { //log.info("* Elm327.data: " + (new String(hexData))); try { - this.stream.write(hexData); + underlyingStream.write(hexData); } catch (IOException ignore) { // ignore } @@ -334,25 +299,13 @@ public class Elm327Connector implements Closeable { private void sendDataBack(String line) { byte [] canPacket = HexUtil.asBytes(line); - try { - elmStream.processCanPacket(canPacket); - } catch (Exception ignore) { - // todo: ? - } + tsStream.processCanPacket(canPacket); } - private boolean startNetworkConnector(int controllerPort) { - try { - elmStream = new Elm327IoStream(this, "elm327Stream"); - BinaryProtocolProxy.createProxy(elmStream, controllerPort, new BinaryProtocolProxy.ClientApplicationActivityListener() { - @Override - public void onActivity() { - } - }); - } catch (IOException ignore) { - return false; - } - - return true; + public static boolean checkConnection(String serialPort, IoStream stream) { + Elm327Connector con = new Elm327Connector(stream); + boolean found = con.initConnection(serialPort); + con.close(); + return found; } } diff --git a/java_console/io/src/main/java/com/rusefi/io/can/Elm327IoStream.java b/java_console/io/src/main/java/com/rusefi/io/can/Elm327IoStream.java index b4b7c6c4c1..0273eb236c 100644 --- a/java_console/io/src/main/java/com/rusefi/io/can/Elm327IoStream.java +++ b/java_console/io/src/main/java/com/rusefi/io/can/Elm327IoStream.java @@ -3,15 +3,16 @@ package com.rusefi.io.can; import com.opensr5.io.DataListener; import com.rusefi.binaryprotocol.IncomingDataBuffer; import com.rusefi.binaryprotocol.IoHelper; -import com.rusefi.io.ByteReader; import com.rusefi.io.serial.AbstractIoStream; -import com.rusefi.shared.FileUtil; import org.jetbrains.annotations.NotNull; import java.io.*; import java.nio.ByteBuffer; import java.util.Arrays; +/** + * + */ public class Elm327IoStream extends AbstractIoStream { private final String loggingPrefix; private final Elm327Connector con; @@ -22,27 +23,28 @@ public class Elm327IoStream extends AbstractIoStream { // the buffer size is limited by CAN-TP protocol private final static int OUT_BUFFER_SIZE = 4095; - private ByteBuffer inBuf; - private ByteBuffer outBuf; + private final ByteBuffer outBuf; // this should match the TS_CAN_DEVICE_SHORT_PACKETS_IN_ONE_FRAME in the firmware - private final static boolean sendShortPacketsInOneFrame = true; + // todo: move this to rusefi_config.txt / prepend.txt? + private final static boolean sendShortPacketsInOneFrame = false; + //private final static boolean receiveShortPacketsInOneFrame = sendShortPacketsInOneFrame; private final static boolean receiveShortPacketsInOneFrame = false; - private Elm327Connector.CanDecoder canDecoder = new Elm327Connector.CanDecoder(); + private final IsoTpCanDecoder canDecoder = new IsoTpCanDecoder(); - public Elm327IoStream(Elm327Connector con, String loggingPrefix) throws IOException { + public Elm327IoStream(Elm327Connector con, String loggingPrefix) { this(con, loggingPrefix, DisconnectListener.VOID); } - public Elm327IoStream(Elm327Connector con, String loggingPrefix, DisconnectListener disconnectListener) throws IOException { + private Elm327IoStream(Elm327Connector con, String loggingPrefix, DisconnectListener disconnectListener) { this.con = con; this.loggingPrefix = loggingPrefix; this.disconnectListener = disconnectListener; this.dataBuffer = IncomingDataBuffer.createDataBuffer(loggingPrefix, this); - inBuf = ByteBuffer.allocate(OUT_BUFFER_SIZE); +// ByteBuffer inBuf = ByteBuffer.allocate(OUT_BUFFER_SIZE); outBuf = ByteBuffer.allocate(OUT_BUFFER_SIZE); } @@ -62,6 +64,7 @@ public class Elm327IoStream extends AbstractIoStream { return loggingPrefix; } + @NotNull @Override public IncomingDataBuffer getDataBuffer() { return dataBuffer; @@ -91,6 +94,7 @@ public class Elm327IoStream extends AbstractIoStream { super.flush(); byte [] bytes; // for smaller packets, send them in one 'simple' frame by stripping the header+footer off + // i.e. un-pack CRC32 TS protocol // (2 = 16-bit length, 4 = 32-bit crc) if (sendShortPacketsInOneFrame && outBuf.position() >= 2 + 1 + 4 && outBuf.position() <= 2 + 7 + 4) { bytes = Arrays.copyOfRange(outBuf.array(), 2, outBuf.position() - 4); @@ -114,9 +118,7 @@ public class Elm327IoStream extends AbstractIoStream { packet = new byte [2 + data.length + 4]; IoHelper.putShort(packet, 0, data.length); - for (int i = 0; i < data.length; i++) { - packet[i + 2] = data[i]; - } + System.arraycopy(data, 0, packet, 2, data.length); int crc = IoHelper.getCrc32(data); IoHelper.putInt(packet, 2 + data.length, crc); } else { @@ -127,9 +129,10 @@ public class Elm327IoStream extends AbstractIoStream { dataListener.onDataArrived(packet); } - public void processCanPacket(byte [] data) throws Exception { + public void processCanPacket(byte [] data) { byte [] rawData = canDecoder.decodePacket(data); - sendDataToClient(rawData); + if (rawData.length != 0) + sendDataToClient(rawData); } public interface DisconnectListener { diff --git a/java_console/io/src/main/java/com/rusefi/io/can/IsoTpCanDecoder.java b/java_console/io/src/main/java/com/rusefi/io/can/IsoTpCanDecoder.java new file mode 100644 index 0000000000..dab300c5a8 --- /dev/null +++ b/java_console/io/src/main/java/com/rusefi/io/can/IsoTpCanDecoder.java @@ -0,0 +1,75 @@ +package com.rusefi.io.can; + +import com.devexperts.logging.Logging; +import com.rusefi.io.IoStream; + +import java.util.Arrays; + +// CAN multiframe decoder state +class IsoTpCanDecoder { + private static Logging log = Logging.getLogging(IsoTpCanDecoder.class); + + static { + log.configureDebugEnabled(false); + } + + private final static int ISO_TP_FRAME_FLOW_CONTROL = 3; + final static int ISO_TP_FRAME_SINGLE = 0; + final static int ISO_TP_FRAME_FIRST = 1; + final static int ISO_TP_FRAME_CONSECUTIVE = 2; + + private final static int FC_ContinueToSend = 0; + + public int waitingForNumBytes = 0; + public int waitingForFrameIndex = 0; + + public byte[] decodePacket(byte[] data) { + int frameType = (data[0] >> 4) & 0xf; + int numBytesAvailable; + int frameIdx; + int dataOffset; + switch (frameType) { + case ISO_TP_FRAME_SINGLE: + numBytesAvailable = data[0] & 0xf; + dataOffset = 1; + this.waitingForNumBytes = 0; + if (log.debugEnabled()) + log.debug("ISO_TP_FRAME_SINGLE " + numBytesAvailable); + break; + case ISO_TP_FRAME_FIRST: + this.waitingForNumBytes = ((data[0] & 0xf) << 8) | data[1]; + if (log.debugEnabled()) + log.debug("Total expected: " + waitingForNumBytes); + this.waitingForFrameIndex = 1; + numBytesAvailable = Math.min(this.waitingForNumBytes, 6); + waitingForNumBytes -= numBytesAvailable; + dataOffset = 2; + break; + case ISO_TP_FRAME_CONSECUTIVE: + frameIdx = data[0] & 0xf; + if (this.waitingForNumBytes < 0 || this.waitingForFrameIndex != frameIdx) { + throw new IllegalStateException("ISO_TP_FRAME_CONSECUTIVE: That's an abnormal situation, and we probably should react? " + waitingForNumBytes + " " + waitingForFrameIndex + " " + frameIdx); + } + this.waitingForFrameIndex = (this.waitingForFrameIndex + 1) & 0xf; + numBytesAvailable = Math.min(this.waitingForNumBytes, 7); + dataOffset = 1; + waitingForNumBytes -= numBytesAvailable; + if (log.debugEnabled()) + log.debug("ISO_TP_FRAME_CONSECUTIVE Got " + numBytesAvailable + ", still expecting: " + waitingForNumBytes); + break; + case ISO_TP_FRAME_FLOW_CONTROL: + int flowStatus = data[0] & 0xf; + int blockSize = data[1]; + int separationTime = data[2]; + if (flowStatus == FC_ContinueToSend && blockSize == 0 && separationTime == 0) + return new byte[0]; + throw new IllegalStateException("ISO_TP_FRAME_FLOW_CONTROL: should we just ignore the FC frame? " + flowStatus + " " + blockSize + " " + separationTime); + default: + throw new IllegalStateException("Unknown frame type"); + } + byte[] bytes = Arrays.copyOfRange(data, dataOffset, dataOffset + numBytesAvailable); + if (log.debugEnabled()) + log.debug(numBytesAvailable + " bytes(s) arrived in this packet: " + IoStream.printHexBinary(bytes)); + return bytes; + } +} diff --git a/java_console/io/src/test/java/com/rusefi/binaryprotocol/test/Elm327Sandbox.java b/java_console/io/src/test/java/com/rusefi/binaryprotocol/test/Elm327Sandbox.java index 11d147a59f..91b8eaa0b2 100644 --- a/java_console/io/src/test/java/com/rusefi/binaryprotocol/test/Elm327Sandbox.java +++ b/java_console/io/src/test/java/com/rusefi/binaryprotocol/test/Elm327Sandbox.java @@ -1,25 +1,100 @@ package com.rusefi.binaryprotocol.test; +import com.rusefi.binaryprotocol.BinaryProtocol; +import com.rusefi.binaryprotocol.IncomingDataBuffer; +import com.rusefi.config.generated.Fields; +import com.rusefi.io.ConnectionStateListener; import com.rusefi.io.IoStream; +import com.rusefi.io.LinkManager; import com.rusefi.io.can.Elm327Connector; import com.rusefi.io.serial.BaudRateHolder; -import com.rusefi.io.serial.BufferedSerialIoStream; +import com.rusefi.io.serial.SerialIoStream; +import com.rusefi.io.serial.StreamConnector; import java.io.IOException; -import static com.rusefi.Timeouts.SECOND; +import static com.rusefi.binaryprotocol.IoHelper.checkResponseCode; import static com.rusefi.io.can.Elm327Connector.ELM327_DEFAULT_BAUDRATE; -import static com.rusefi.io.can.Elm327Connector.ELM_EOL; public class Elm327Sandbox { public static void main(String[] args) throws InterruptedException, IOException { BaudRateHolder.INSTANCE.baudRate = ELM327_DEFAULT_BAUDRATE; - String serialPort = "COM5"; + String serialPort = "COM7"; + Elm327Connector connector = new Elm327Connector(SerialIoStream.openPort(serialPort)); + connector.start(serialPort); - IoStream stream = BufferedSerialIoStream.openPort(serialPort); - stream.setInputListener(freshData -> System.out.println("onDataArrived")); + IoStream tsStream = connector.getTsStream(); + + IncomingDataBuffer dataBuffer = tsStream.getDataBuffer(); + System.out.println("Hello new ELM327 connection, pending=" + dataBuffer.getPendingCount()); + + runFcommand("First time", tsStream); + Elm327Connector.whyDoWeNeedToSleepBetweenCommands(); + + runFcommand("Second time", tsStream); + Elm327Connector.whyDoWeNeedToSleepBetweenCommands(); + + { + String signature = BinaryProtocol.getSignature(tsStream); + System.out.println("Got " + signature + " signature via CAN/ELM327"); + if (signature == null) + return; + } + + Elm327Connector.whyDoWeNeedToSleepBetweenCommands(); + + { + String signature = BinaryProtocol.getSignature(tsStream); + System.out.println("Let's do it again! Got " + signature + " signature via CAN/ELM327"); + if (signature == null) + return; + } + + Elm327Connector.whyDoWeNeedToSleepBetweenCommands(); + + { + tsStream.sendPacket(new byte[]{Fields.TS_HELLO_COMMAND}); + byte[] response = dataBuffer.getPacket("[hello command]"); + if (!checkResponseCode(response, (byte) Fields.TS_RESPONSE_OK)) + return; + String signature = new String(response, 1, response.length - 1); + System.out.println(Fields.TS_HELLO_COMMAND + " returned " + signature); + } + + Elm327Connector.whyDoWeNeedToSleepBetweenCommands(); + + { + tsStream.sendPacket(BinaryProtocol.createCrcCommand(1000)); + byte[] fResponse = new byte[3]; + dataBuffer.waitForBytes("CRC", System.currentTimeMillis(), fResponse.length); + dataBuffer.getData(fResponse); + System.out.println(" Got CRC response " + IoStream.printHexBinary(fResponse)); + } + + LinkManager linkManager = new LinkManager(); + StreamConnector streamConnector = new StreamConnector(linkManager, () -> tsStream); + linkManager.setConnector(streamConnector); + streamConnector.connectAndReadConfiguration(new ConnectionStateListener() { + @Override + public void onConnectionEstablished() { + System.out.println("onConnectionEstablished"); + } + + @Override + public void onConnectionFailed() { + System.out.println("onConnectionFailed"); + } + }); - stream.write((Elm327Connector.HELLO + ELM_EOL).getBytes()); - Thread.sleep(6 * SECOND); } + + private static void runFcommand(String prefix, IoStream tsStream) throws IOException { + IncomingDataBuffer dataBuffer = tsStream.getDataBuffer(); + tsStream.sendPacket(new byte[]{Fields.TS_COMMAND_F}); + byte[] fResponse = new byte[3]; + dataBuffer.waitForBytes("hello", System.currentTimeMillis(), fResponse.length); + dataBuffer.getData(fResponse); + System.out.println(prefix + " Got F response " + IoStream.printHexBinary(fResponse)); + } + } diff --git a/java_console/shared_io/src/main/java/com/rusefi/rusEFIVersion.java b/java_console/shared_io/src/main/java/com/rusefi/rusEFIVersion.java index abd21a14e3..292133b772 100644 --- a/java_console/shared_io/src/main/java/com/rusefi/rusEFIVersion.java +++ b/java_console/shared_io/src/main/java/com/rusefi/rusEFIVersion.java @@ -6,7 +6,7 @@ import java.net.URL; import java.util.concurrent.atomic.AtomicReference; public class rusEFIVersion { - public static final int CONSOLE_VERSION = 20211130; + public static final int CONSOLE_VERSION = 20211206; public static AtomicReference firmwareVersion = new AtomicReference<>("N/A"); public static long classBuildTimeMillis() { diff --git a/java_console/ui/src/main/java/com/rusefi/tools/Elm327ConnectorStartup.java b/java_console/ui/src/main/java/com/rusefi/tools/Elm327ConnectorStartup.java index 5b37a0c205..c6f6f123a7 100644 --- a/java_console/ui/src/main/java/com/rusefi/tools/Elm327ConnectorStartup.java +++ b/java_console/ui/src/main/java/com/rusefi/tools/Elm327ConnectorStartup.java @@ -4,11 +4,16 @@ import com.devexperts.logging.Logging; import com.rusefi.autodetect.PortDetector; import com.rusefi.autodetect.SerialAutoChecker; import com.rusefi.io.can.Elm327Connector; +import com.rusefi.io.serial.SerialIoStream; +import com.rusefi.io.tcp.BinaryProtocolProxy; +import com.rusefi.io.tcp.TcpConnector; + +import java.io.IOException; public class Elm327ConnectorStartup { private final static Logging log = Logging.getLogging(Elm327ConnectorStartup.class); - public static void start() { + public static void start() throws IOException { SerialAutoChecker.AutoDetectResult detectResult = PortDetector.autoDetectSerial(null, PortDetector.DetectorMode.DETECT_ELM327); String autoDetectedPort = detectResult.getSerialPort(); //String autoDetectedPort = "COM73"; @@ -17,7 +22,17 @@ public class Elm327ConnectorStartup { return; } - new Elm327Connector().start(autoDetectedPort); + Elm327Connector elm327Connector = new Elm327Connector(SerialIoStream.openPort(autoDetectedPort)); + elm327Connector.start(autoDetectedPort); + + BinaryProtocolProxy.createProxy(elm327Connector.getTsStream(), TcpConnector.DEFAULT_PORT, new BinaryProtocolProxy.ClientApplicationActivityListener() { + @Override + public void onActivity() { + System.out.println("onActivity"); + Elm327Connector.whyDoWeNeedToSleepBetweenCommands(); + } + }); + log.info("Running Elm327 connector for " + autoDetectedPort); } } diff --git a/java_console/ui/src/main/java/com/rusefi/ui/engine/EngineSnifferPanel.java b/java_console/ui/src/main/java/com/rusefi/ui/engine/EngineSnifferPanel.java index c631383dc5..74710e90a3 100644 --- a/java_console/ui/src/main/java/com/rusefi/ui/engine/EngineSnifferPanel.java +++ b/java_console/ui/src/main/java/com/rusefi/ui/engine/EngineSnifferPanel.java @@ -131,6 +131,7 @@ public class EngineSnifferPanel { JPanel lowerButtons = new JPanel(new FlowLayout(FlowLayout.RIGHT, 5, 0)); lowerButtons.add(new ConfigField(uiContext, Fields.GLOBALTRIGGERANGLEOFFSET, "Trigger Offset").getContent()); lowerButtons.add(new BitConfigField(uiContext, Fields.VERBOSETRIGGERSYNCHDETAILS, "Verbose trigger Sync").getContent()); + lowerButtons.add(new BitConfigField(uiContext, Fields.VERBOSEVVTDECODING, "Verbose VVT Sync").getContent()); lowerButtons.add(new BitConfigField(uiContext, Fields.ISENGINECHARTENABLED, "Collect Engine Data").getContent()); lowerButtons.add(new ConfigField(uiContext, Fields.ENGINECHARTSIZE, "Engine Sniffer size").getContent()); lowerButtons.add(new ConfigField(uiContext, Fields.ENGINESNIFFERRPMTHRESHOLD, "RPM threshold").getContent()); diff --git a/misc/install/STM32_Programmer_CLI/bin/stm32-read-dfu-f0-128k.bat b/misc/install/STM32_Programmer_CLI/bin/stm32-read-dfu-f0-128k.bat new file mode 100644 index 0000000000..871a05eba6 --- /dev/null +++ b/misc/install/STM32_Programmer_CLI/bin/stm32-read-dfu-f0-128k.bat @@ -0,0 +1,2 @@ + +STM32_Programmer_CLI.exe -c port=usb1 -r 0x08000000 0x0020000 dump_f0.hex \ No newline at end of file diff --git a/unit_tests/tests/trigger/test_map_cam.cpp b/unit_tests/tests/trigger/test_map_cam.cpp index 476abd4fce..15d3e9c4d8 100644 --- a/unit_tests/tests/trigger/test_map_cam.cpp +++ b/unit_tests/tests/trigger/test_map_cam.cpp @@ -29,22 +29,43 @@ TEST(trigger, map_cam) { MapState state; int i = 0; - for (;i<404;i++) { + for (;i<403;i++) { state.add(getZigZag(i)); if (state.mapBuffer.getCount() > engineConfiguration->mapCamAveragingLength) { - ASSERT_FALSE(state.isPeak()) << "At " << i; + ASSERT_FALSE(state.isPeak(false)) << "high At " << i; + ASSERT_FALSE(state.isPeak(true)) << "low At " << i; } } state.add(getZigZag(i)); - ASSERT_TRUE(state.isPeak()) << "At " << i; + ASSERT_FALSE(state.isPeak(false)) << "high At " << i; + ASSERT_FALSE(state.isPeak(true)) << "low At " << i; + i++; - for (;i<604;i++) { + + state.add(getZigZag(i)); + ASSERT_TRUE(state.isPeak(false)) << "high At " << i; + ASSERT_FALSE(state.isPeak(true)) << "low At " << i; + + for (;i<504;i++) { state.add(getZigZag(i)); - ASSERT_FALSE(state.isPeak()) << "At " << i; + ASSERT_FALSE(state.isPeak(false)) << "high At " << i; + ASSERT_FALSE(state.isPeak(true)) << "low At " << i; } state.add(getZigZag(i)); - ASSERT_TRUE(state.isPeak()) << "At " << i; + ASSERT_FALSE(state.isPeak(false)) << "high At " << i; + ASSERT_TRUE(state.isPeak(true)) << "low At " << i; + i++; + + for (;i<604;i++) { + state.add(getZigZag(i)); + ASSERT_FALSE(state.isPeak(false)) << "high At " << i; + ASSERT_FALSE(state.isPeak(true)) << "low At " << i; + } + + state.add(getZigZag(i)); + ASSERT_TRUE(state.isPeak(false)) << "high At " << i; + ASSERT_TRUE(state.isPeak(false)) << "low At " << i; }