tune via CAN #3361

only trivial refactoring
This commit is contained in:
rusefillc 2021-12-04 20:10:30 -05:00
parent 399888f795
commit d186e4153e
4 changed files with 66 additions and 72 deletions

View File

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

View File

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

View File

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

View File

@ -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);
}
}