Merge remote-tracking branch 'origin/master' into master
This commit is contained in:
commit
4be62ab521
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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"(
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -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<uint16_t, 1000, 1> 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
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#pragma once
|
||||
#define VCS_DATE 20211204
|
||||
#define VCS_DATE 20211206
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="Launcher elm327_connector" type="Application" factoryName="Application">
|
||||
<option name="MAIN_CLASS_NAME" value="com.rusefi.Launcher" />
|
||||
<module name="ui" />
|
||||
<option name="PROGRAM_PARAMETERS" value="elm327_connector" />
|
||||
<option name="VM_PARAMETERS" value="-Dini_file_path=../firmware/tunerstudio -Dshow_etb_pane=true -Dhigh_speed_logger_rpm=10000" />
|
||||
<method v="2">
|
||||
<option name="Make" enabled="true" />
|
||||
</method>
|
||||
</configuration>
|
||||
</component>
|
|
@ -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);
|
||||
|
|
|
@ -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<StreamFile> compositeLogs = new ArrayList<>();
|
||||
private final List<StreamFile> 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);
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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<String> 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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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<String> firmwareVersion = new AtomicReference<>("N/A");
|
||||
|
||||
public static long classBuildTimeMillis() {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
|
||||
STM32_Programmer_CLI.exe -c port=usb1 -r 0x08000000 0x0020000 dump_f0.hex
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue