From 0dcbfc38daddf9bb5413b346f2482d287fae7d6d Mon Sep 17 00:00:00 2001 From: rusefillc Date: Sat, 4 Dec 2021 20:10:30 -0500 Subject: [PATCH] tune via CAN #3361 only trivial refactoring --- .../autotest/ControllerConnectorState.java | 1 + .../com/rusefi/io/can/Elm327Connector.java | 85 ++++--------------- .../com/rusefi/io/can/Elm327IoStream.java | 4 +- .../com/rusefi/io/can/IsoTpCanDecoder.java | 48 +++++++++++ 4 files changed, 66 insertions(+), 72 deletions(-) create mode 100644 java_console/io/src/main/java/com/rusefi/io/can/IsoTpCanDecoder.java 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/io/can/Elm327Connector.java b/java_console/io/src/main/java/com/rusefi/io/can/Elm327Connector.java index 280b9fa0e6..b7175ded42 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,6 +2,7 @@ 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; @@ -10,7 +11,6 @@ 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; @@ -29,62 +29,13 @@ public class Elm327Connector implements Closeable { 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; + private IoStream stream = null; 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 static boolean checkConnection(String serialPort, IoStream stream) { Elm327Connector con = new Elm327Connector(); boolean found = con.initConnection(serialPort, stream); @@ -107,16 +58,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(Fields.CAN_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(Fields.CAN_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(Fields.CAN_SERIAL_TX_ID), "OK"); // set FC data sendCommand("ATFCSD 30 00 00", "OK"); // use custom FC ID & data @@ -183,13 +134,13 @@ public class Elm327Connector implements Closeable { // 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 +150,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; } @@ -259,15 +210,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; @@ -336,19 +287,15 @@ public class Elm327Connector implements Closeable { byte [] canPacket = HexUtil.asBytes(line); try { elmStream.processCanPacket(canPacket); - } catch (Exception ignore) { - // todo: ? + } catch (Exception e) { + System.out.println("ELM327: Error processing " + line); } } private boolean startNetworkConnector(int controllerPort) { try { elmStream = new Elm327IoStream(this, "elm327Stream"); - BinaryProtocolProxy.createProxy(elmStream, controllerPort, new BinaryProtocolProxy.ClientApplicationActivityListener() { - @Override - public void onActivity() { - } - }); + BinaryProtocolProxy.createProxy(elmStream, controllerPort, BinaryProtocolProxy.ClientApplicationActivityListener.VOID); } catch (IOException ignore) { return false; } 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..d901a262d8 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,9 +3,7 @@ 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.*; @@ -29,7 +27,7 @@ public class Elm327IoStream extends AbstractIoStream { private final static boolean sendShortPacketsInOneFrame = true; private final static boolean receiveShortPacketsInOneFrame = false; - private Elm327Connector.CanDecoder canDecoder = new Elm327Connector.CanDecoder(); + private IsoTpCanDecoder canDecoder = new IsoTpCanDecoder(); public Elm327IoStream(Elm327Connector con, String loggingPrefix) throws IOException { 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..b23ef4d0be --- /dev/null +++ b/java_console/io/src/main/java/com/rusefi/io/can/IsoTpCanDecoder.java @@ -0,0 +1,48 @@ +package com.rusefi.io.can; + +import java.util.Arrays; + +// CAN multiframe decoder state +class IsoTpCanDecoder { + 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; + + 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); + } +}