auto-sync

This commit is contained in:
rusEfi 2015-03-08 13:04:49 -05:00
parent ff79cdda55
commit a15738f42c
7 changed files with 176 additions and 130 deletions

View File

@ -15,6 +15,7 @@
<flashmethod>sti04</flashmethod> <flashmethod>sti04</flashmethod>
<filesize>14008</filesize> <filesize>14008</filesize>
</romid> </romid>
<table type="3D" name="Ignition Advance" storageaddress="24B8" sizex="16" sizey="16" storagetype="float" endian="big"> <table type="3D" name="Ignition Advance" storageaddress="24B8" sizex="16" sizey="16" storagetype="float" endian="big">
<scaling units="Engine Load" expression="x" to_byte="x" format="0.00" fineincrement=".1" coarseincrement="1" /> <scaling units="Engine Load" expression="x" to_byte="x" format="0.00" fineincrement=".1" coarseincrement="1" />
<table type="X Axis" storageaddress="28B8" storagetype="float" endian="big"> <table type="X Axis" storageaddress="28B8" storagetype="float" endian="big">
@ -24,9 +25,31 @@
<scaling units="RPM" expression="x" to_byte="x" format="0.00" fineincrement=".1" coarseincrement="1" /> <scaling units="RPM" expression="x" to_byte="x" format="0.00" fineincrement=".1" coarseincrement="1" />
</table> </table>
</table> </table>
<table type="2D" name="CL to OL Delay" storageaddress="40" sizex="4" sizey="6" storagetype="float">
<table type="3D" name="Fuel Table" storageaddress="2038" sizex="16" sizey="16" storagetype="float" endian="big">
<scaling units="Engine Load" expression="x" to_byte="x" format="0.00" fineincrement=".1" coarseincrement="1" />
<table type="X Axis" storageaddress="2438" storagetype="float" endian="big">
<scaling units="degree" expression="x" to_byte="x" format="0.00" fineincrement=".1" coarseincrement="1" />
</table>
<table type="Y Axis" storageaddress="2478" storagetype="float" endian="big">
<scaling units="RPM" expression="x" to_byte="x" format="0.00" fineincrement=".1" coarseincrement="1" />
</table>
</table>
<table type="3D" name="Target AFR" storageaddress="2DB8" sizex="16" sizey="16" storagetype="float" endian="big">
<scaling units="Engine Load" expression="x" to_byte="x" format="0.00" fineincrement=".1" coarseincrement="1" />
<table type="X Axis" storageaddress="31B8" storagetype="float" endian="big">
<scaling units="degree" expression="x" to_byte="x" format="0.00" fineincrement=".1" coarseincrement="1" />
</table>
<table type="Y Axis" storageaddress="31F8" storagetype="float" endian="big">
<scaling units="RPM" expression="x" to_byte="x" format="0.00" fineincrement=".1" coarseincrement="1" />
</table>
</table>
<table type="2D" name="Coolant-based Warnup Enrichment" storageaddress="90" sizex="16" storagetype="float" endian="big">
<scaling units="Target Boost (psia) Compensation (%)" expression="x" to_byte="x" format="0.00" fineincrement=".1" coarseincrement="1" /> <scaling units="Target Boost (psia) Compensation (%)" expression="x" to_byte="x" format="0.00" fineincrement=".1" coarseincrement="1" />
<table type="X Axis" storageaddress="6" storagetype="float"> <table type="X Axis" storageaddress="50" storagetype="float" endian="big">
<scaling units="uni" expression="x" to_byte="x" format="0.00" fineincrement=".1" coarseincrement="1" /> <scaling units="uni" expression="x" to_byte="x" format="0.00" fineincrement=".1" coarseincrement="1" />
</table> </table>
</table> </table>

View File

@ -19,22 +19,18 @@ public class ConfigurationImage {
this.content = content; this.content = content;
} }
public int getSize() { public int getSize() {
return content.length; return content.length;
} }
public byte[] getFileContent() throws IOException { public byte[] getFileContent() throws IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream(); try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
try {
byte[] bytes = BIN_HEADER.getBytes(); byte[] bytes = BIN_HEADER.getBytes();
if (bytes.length != BIN_HEADER.length()) if (bytes.length != BIN_HEADER.length())
throw new IllegalStateException("Encoding issue"); throw new IllegalStateException("Encoding issue");
baos.write(bytes); baos.write(bytes);
baos.write(content); baos.write(content);
return baos.toByteArray(); return baos.toByteArray();
} finally {
baos.close();
} }
} }
@ -63,7 +59,22 @@ public class ConfigurationImage {
return result == image.getContent().length ? image : null; return result == image.getContent().length ? image : null;
} }
public static byte[] extractContent(byte[] rom) {
if (rom.length < BIN_HEADER.length())
return null;
byte[] result = new byte[rom.length - BIN_HEADER.length()];
System.arraycopy(rom, BIN_HEADER.length(), result, 0, result.length);
return result;
}
public byte[] getContent() { public byte[] getContent() {
return content; return content;
} }
@SuppressWarnings("CloneDoesntCallSuperClone")
@Override
public ConfigurationImage clone() {
byte[] copy = content.clone();
return new ConfigurationImage(copy);
}
} }

View File

@ -1,7 +1,9 @@
package com.rusefi.binaryprotocol; package com.rusefi.binaryprotocol;
import com.rusefi.ConfigurationImage; import com.rusefi.ConfigurationImage;
import com.rusefi.ConfigurationImageDiff;
import com.rusefi.Logger; import com.rusefi.Logger;
import com.rusefi.core.Pair;
import com.rusefi.io.DataListener; import com.rusefi.io.DataListener;
import com.rusefi.io.serial.SerialPortReader; import com.rusefi.io.serial.SerialPortReader;
import etch.util.CircularByteBuffer; import etch.util.CircularByteBuffer;
@ -25,6 +27,9 @@ public class BinaryProtocol {
private final CircularByteBuffer cbb; private final CircularByteBuffer cbb;
private boolean isBurnPending; private boolean isBurnPending;
private final Object lock = new Object();
private ConfigurationImage controller;
public BinaryProtocol(final Logger logger, SerialPort serialPort) throws SerialPortException { public BinaryProtocol(final Logger logger, SerialPort serialPort) throws SerialPortException {
this.logger = logger; this.logger = logger;
this.serialPort = serialPort; this.serialPort = serialPort;
@ -47,12 +52,22 @@ public class BinaryProtocol {
serialPort.addEventListener(new SerialPortReader(serialPort, listener)); serialPort.addEventListener(new SerialPortReader(serialPort, listener));
} }
private void waitForBytes(int count) throws InterruptedException { public void burnChanges(ConfigurationImage newVersion, Logger logger) throws InterruptedException, EOFException, SerialPortException {
logger.info("Waiting for " + count + " byte(s)"); ConfigurationImage current = getController();
synchronized (cbb) { // let's have our own copy which no one would be able to change
while (cbb.length() < count) newVersion = newVersion.clone();
cbb.wait(); int offset = 0;
while (offset < current.getSize()) {
Pair<Integer, Integer> range = ConfigurationImageDiff.findDifferences(current, newVersion, offset);
if (range == null)
break;
logger.info("Need to patch: " + range);
writeData(newVersion.getContent(), range.first, range.second - range.first, logger);
offset = range.second;
} }
burn();
setController(newVersion);
} }
/** /**
@ -71,29 +86,6 @@ public class BinaryProtocol {
return packet; return packet;
} }
private static void putInt(byte[] packet, int offset, int value) {
int index = offset + 3;
for (int i = 0; i < 4; i++) {
packet[index--] = (byte) value;
value >>= 8;
}
}
private static void putShort(byte[] packet, int offset, int value) {
int index = offset + 1;
for (int i = 0; i < 2; i++) {
packet[index--] = (byte) value;
value >>= 8;
}
}
private void sendCrcPacket(byte[] command) throws SerialPortException {
byte[] packet = makePacket(command);
logger.info("Sending " + Arrays.toString(packet));
serialPort.writeBytes(packet);
}
public static int swap16(int x) { public static int swap16(int x) {
return (((x & 0xFF) << 8) | ((x) >> 8)); return (((x & 0xFF) << 8) | ((x) >> 8));
} }
@ -133,7 +125,9 @@ public class BinaryProtocol {
} }
} }
public void readImage(ConfigurationImage image) throws SerialPortException, EOFException, InterruptedException { public void readImage(int size) throws SerialPortException, EOFException, InterruptedException {
ConfigurationImage image = new ConfigurationImage(size);
int offset = 0; int offset = 0;
while (offset < image.getSize()) { while (offset < image.getSize()) {
@ -159,6 +153,7 @@ public class BinaryProtocol {
offset += requestSize; offset += requestSize;
} }
logger.info("Got image!"); logger.info("Got image!");
setController(image);
} }
public byte[] exchange(byte[] packet) throws SerialPortException, InterruptedException, EOFException { public byte[] exchange(byte[] packet) throws SerialPortException, InterruptedException, EOFException {
@ -166,10 +161,6 @@ public class BinaryProtocol {
return receivePacket(); return receivePacket();
} }
private boolean checkResponseCode(byte[] response, byte code) {
return response != null && response.length > 0 && response[0] == code;
}
public void writeData(byte[] content, Integer offset, int size, Logger logger) throws SerialPortException, EOFException, InterruptedException { public void writeData(byte[] content, Integer offset, int size, Logger logger) throws SerialPortException, EOFException, InterruptedException {
if (size > BLOCKING_FACTOR) { if (size > BLOCKING_FACTOR) {
writeData(content, offset, BLOCKING_FACTOR, logger); writeData(content, offset, BLOCKING_FACTOR, logger);
@ -195,7 +186,6 @@ public class BinaryProtocol {
} }
break; break;
} }
} }
public void burn() throws InterruptedException, EOFException, SerialPortException { public void burn() throws InterruptedException, EOFException, SerialPortException {
@ -211,4 +201,50 @@ public class BinaryProtocol {
} }
isBurnPending = false; isBurnPending = false;
} }
public void setController(ConfigurationImage controller) {
synchronized (lock) {
this.controller = controller.clone();
}
}
public ConfigurationImage getController() {
synchronized (lock) {
return controller.clone();
}
}
private void waitForBytes(int count) throws InterruptedException {
logger.info("Waiting for " + count + " byte(s)");
synchronized (cbb) {
while (cbb.length() < count)
cbb.wait();
}
}
private boolean checkResponseCode(byte[] response, byte code) {
return response != null && response.length > 0 && response[0] == code;
}
private static void putInt(byte[] packet, int offset, int value) {
int index = offset + 3;
for (int i = 0; i < 4; i++) {
packet[index--] = (byte) value;
value >>= 8;
}
}
private static void putShort(byte[] packet, int offset, int value) {
int index = offset + 1;
for (int i = 0; i < 2; i++) {
packet[index--] = (byte) value;
value >>= 8;
}
}
private void sendCrcPacket(byte[] command) throws SerialPortException {
byte[] packet = makePacket(command);
logger.info("Sending " + Arrays.toString(packet));
serialPort.writeBytes(packet);
}
} }

View File

@ -11,5 +11,7 @@
<orderEntry type="library" name="log4j" level="project" /> <orderEntry type="library" name="log4j" level="project" />
<orderEntry type="library" name="jep" level="project" /> <orderEntry type="library" name="jep" level="project" />
<orderEntry type="library" name="swing-layout-1.0" level="project" /> <orderEntry type="library" name="swing-layout-1.0" level="project" />
<orderEntry type="module" module-name="ui" />
<orderEntry type="module" module-name="io" />
</component> </component>
</module> </module>

View File

@ -36,14 +36,17 @@ import javax.swing.JToolBar;
import com.romraider.Settings; import com.romraider.Settings;
import com.romraider.editor.ecu.ECUEditor; import com.romraider.editor.ecu.ECUEditor;
import com.romraider.editor.ecu.ECUEditorManager; import com.romraider.editor.ecu.ECUEditorManager;
import com.romraider.maps.Rom;
import com.romraider.util.SettingsManager; import com.romraider.util.SettingsManager;
import com.rusefi.ConfigurationImage;
import com.rusefi.binaryprotocol.BinaryProtocolCmd;
public class ECUEditorToolBar extends JToolBar implements ActionListener { public class ECUEditorToolBar extends JToolBar {
private static final long serialVersionUID = 7778170684606193919L; private static final long serialVersionUID = 7778170684606193919L;
private final JButton saveImage = new JButton(); // private final JButton saveImage = new JButton();
private final JButton refreshImage = new JButton(); private final JButton refreshImage = new JButton();
private final JButton closeImage = new JButton(); // private final JButton closeImage = new JButton();
public ECUEditorToolBar(String name) { public ECUEditorToolBar(String name) {
super(name); super(name);
@ -55,29 +58,40 @@ public class ECUEditorToolBar extends JToolBar implements ActionListener {
this.updateIcons(); this.updateIcons();
this.add(saveImage); // this.add(saveImage);
this.add(closeImage); // this.add(closeImage);
this.add(refreshImage); this.add(refreshImage);
saveImage.setMaximumSize(new Dimension(50, 50)); refreshImage.setToolTipText("Burn changes into controller");
saveImage.setBorder(createLineBorder(new Color(150, 150, 150), 0));
closeImage.setMaximumSize(new Dimension(50, 50));
closeImage.setBorder(createLineBorder(new Color(150, 150, 150), 0)); // saveImage.setMaximumSize(new Dimension(50, 50));
// saveImage.setBorder(createLineBorder(new Color(150, 150, 150), 0));
// closeImage.setMaximumSize(new Dimension(50, 50));
// closeImage.setBorder(createLineBorder(new Color(150, 150, 150), 0));
refreshImage.setMaximumSize(new Dimension(50, 50)); refreshImage.setMaximumSize(new Dimension(50, 50));
refreshImage.setBorder(createLineBorder(new Color(150, 150, 150), 0)); refreshImage.setBorder(createLineBorder(new Color(150, 150, 150), 0));
this.updateButtons(); this.updateButtons();
saveImage.addActionListener(this); // saveImage.addActionListener(this);
closeImage.addActionListener(this); // closeImage.addActionListener(this);
refreshImage.addActionListener(this); refreshImage.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
Rom lastSelectedRom = ECUEditorManager.getECUEditor().getLastSelectedRom();
byte[] newVersion = ConfigurationImage.extractContent(lastSelectedRom.saveFile());
System.out.println(newVersion.length);
BinaryProtocolCmd.scheduleBurn(new ConfigurationImage(newVersion));
}
});
} }
public void updateIcons() { public void updateIcons() {
int iconScale = getSettings().getEditorIconScale(); int iconScale = getSettings().getEditorIconScale();
saveImage.setIcon(rescaleImageIcon(new ImageIcon(getClass().getResource("/graphics/icon-save.png")), iconScale)); // saveImage.setIcon(rescaleImageIcon(new ImageIcon(getClass().getResource("/graphics/icon-save.png")), iconScale));
refreshImage.setIcon(rescaleImageIcon(new ImageIcon(getClass().getResource("/graphics/icon-refresh.png")), iconScale)); refreshImage.setIcon(rescaleImageIcon(new ImageIcon(getClass().getResource("/graphics/icon-refresh.png")), iconScale));
closeImage.setIcon(rescaleImageIcon(new ImageIcon( getClass().getResource("/graphics/icon-close.png")), iconScale)); // closeImage.setIcon(rescaleImageIcon(new ImageIcon( getClass().getResource("/graphics/icon-close.png")), iconScale));
repaint(); repaint();
} }
@ -85,46 +99,28 @@ public class ECUEditorToolBar extends JToolBar implements ActionListener {
int newHeight = (int) (imageIcon.getImage().getHeight(this) * (percentOfOriginal * .01)); int newHeight = (int) (imageIcon.getImage().getHeight(this) * (percentOfOriginal * .01));
int newWidth = (int) (imageIcon.getImage().getWidth(this) * (percentOfOriginal * .01)); int newWidth = (int) (imageIcon.getImage().getWidth(this) * (percentOfOriginal * .01));
if(newHeight > 0 && newWidth > 0) if (newHeight > 0 && newWidth > 0) {
{
imageIcon.setImage(imageIcon.getImage().getScaledInstance(newWidth, newHeight, Image.SCALE_SMOOTH)); imageIcon.setImage(imageIcon.getImage().getScaledInstance(newWidth, newHeight, Image.SCALE_SMOOTH));
} }
return imageIcon; return imageIcon;
} }
public void updateButtons() { public void updateButtons() {
String file = getEditor().getLastSelectedRomFileName(); // String file = getEditor().getLastSelectedRomFileName();
//
saveImage.setToolTipText("Save " + file + " As New Image..."); //// saveImage.setToolTipText("Save " + file + " As New Image...");
refreshImage.setToolTipText("Refresh " + file + " from saved copy"); //// closeImage.setToolTipText("Close " + file);
closeImage.setToolTipText("Close " + file); //
// if ("".equals(file)) {
if ("".equals(file)) { //// saveImage.setEnabled(false);
saveImage.setEnabled(false); // refreshImage.setEnabled(false);
refreshImage.setEnabled(false); // closeImage.setEnabled(false);
closeImage.setEnabled(false); // } else {
} else { // saveImage.setEnabled(true);
saveImage.setEnabled(true); // refreshImage.setEnabled(true);
refreshImage.setEnabled(true); // closeImage.setEnabled(true);
closeImage.setEnabled(true); // }
} // revalidate();
revalidate();
}
@Override
public void actionPerformed(ActionEvent e) {
if (e.getSource() == saveImage) {
try {
((ECUEditorMenuBar) getEditor().getJMenuBar()).saveImage();
getEditor().refreshUI();
} catch (Exception ex) {
JOptionPane.showMessageDialog(getEditor(), new DebugPanel(ex,
getSettings().getSupportURL()), "Exception", JOptionPane.ERROR_MESSAGE);
}
} else if (e.getSource() == closeImage) {
getEditor().closeImage();
} else if (e.getSource() == refreshImage) {
}
} }
private Settings getSettings() { private Settings getSettings() {

View File

@ -1,7 +1,6 @@
package com.rusefi; package com.rusefi;
import com.rusefi.binaryprotocol.BinaryProtocol; import com.rusefi.binaryprotocol.BinaryProtocol;
import com.rusefi.core.Pair;
import com.rusefi.io.serial.PortHolder; import com.rusefi.io.serial.PortHolder;
import com.rusefi.ui.StatusWindow; import com.rusefi.ui.StatusWindow;
import jssc.SerialPort; import jssc.SerialPort;
@ -19,6 +18,7 @@ import java.util.concurrent.Executors;
* 3/7/2015 * 3/7/2015
*/ */
public class UploadChanges { public class UploadChanges {
public static final Logger logger = createUiLogger();
private static final Executor EXEC = Executors.newSingleThreadExecutor(); private static final Executor EXEC = Executors.newSingleThreadExecutor();
public static void main(String[] args) throws SerialPortException, InvocationTargetException, InterruptedException { public static void main(String[] args) throws SerialPortException, InvocationTargetException, InterruptedException {
@ -33,11 +33,7 @@ public class UploadChanges {
public void run() { public void run() {
try { try {
showUi(port); showUi(port);
} catch (SerialPortException e) { } catch (SerialPortException | IOException | InterruptedException e) {
throw new IllegalStateException(e);
} catch (IOException e) {
throw new IllegalStateException(e);
} catch (InterruptedException e) {
throw new IllegalStateException(e); throw new IllegalStateException(e);
} }
} }
@ -45,8 +41,6 @@ public class UploadChanges {
} }
private static void showUi(String port) throws SerialPortException, IOException, InterruptedException { private static void showUi(String port) throws SerialPortException, IOException, InterruptedException {
final Logger logger = createUiLogger();
SerialPort serialPort; SerialPort serialPort;
serialPort = new SerialPort(port); serialPort = new SerialPort(port);
@ -58,29 +52,27 @@ public class UploadChanges {
logger.info("Looks good"); logger.info("Looks good");
final ConfigurationImage ci1 = ConfigurationImage.readFromFile("rus_saved.bin", logger); final ConfigurationImage ci1 = ConfigurationImage.readFromFile("rus_saved.bin", logger);
final ConfigurationImage ci2 = ConfigurationImage.readFromFile("rusefi_configuration.bin", logger); final ConfigurationImage ci2 = ConfigurationImage.readFromFile("rusefi_configuration.bin", logger);
final BinaryProtocol bp = new BinaryProtocol(logger, serialPort); final BinaryProtocol bp = new BinaryProtocol(logger, serialPort);
bp.setController(ci1);
scheduleBurn(ci2, bp);
}
public static void scheduleBurn(final ConfigurationImage newVersion, final BinaryProtocol bp) {
EXEC.execute(new Runnable() { EXEC.execute(new Runnable() {
@Override @Override
public void run() { public void run() {
try { try {
patch(ci1, ci2, bp, logger); bp.burnChanges(newVersion, logger);
} catch (InterruptedException e) { } catch (InterruptedException | EOFException | SerialPortException e) {
logger.error("Error: " + e);
throw new IllegalStateException(e);
} catch (EOFException e) {
logger.error("Error: " + e);
throw new IllegalStateException(e);
} catch (SerialPortException e) {
logger.error("Error: " + e); logger.error("Error: " + e);
throw new IllegalStateException(e); throw new IllegalStateException(e);
} }
} }
}); });
} }
private static Logger createUiLogger() { private static Logger createUiLogger() {
@ -123,18 +115,4 @@ public class UploadChanges {
}; };
} }
private static void patch(ConfigurationImage ci1, ConfigurationImage ci2, BinaryProtocol bp, Logger logger) throws InterruptedException, EOFException, SerialPortException {
int offset = 0;
while (offset < ci1.getSize()) {
Pair<Integer, Integer> range = ConfigurationImageDiff.findDifferences(ci1, ci2, offset);
if (range == null)
break;
logger.info("Need to patch: " + range);
bp.writeData(ci2.getContent(), range.first, range.second - range.first, logger);
offset = range.second;
}
bp.burn();
}
} }

View File

@ -1,22 +1,20 @@
package com.rusefi.binaryprotocol; package com.rusefi.binaryprotocol;
import com.romraider.Settings;
import com.romraider.editor.ecu.ECUEditor; import com.romraider.editor.ecu.ECUEditor;
import com.romraider.util.SettingsManager; import com.romraider.util.SettingsManager;
import com.rusefi.ConfigurationImage; import com.rusefi.ConfigurationImage;
import com.rusefi.Logger; import com.rusefi.Logger;
import com.rusefi.RomRaiderWrapper; import com.rusefi.RomRaiderWrapper;
import com.rusefi.UploadChanges;
import com.rusefi.io.serial.PortHolder; import com.rusefi.io.serial.PortHolder;
import jssc.SerialPort; import jssc.SerialPort;
import jssc.SerialPortException;
import java.io.IOException;
/** /**
* (c) Andrey Belomutskiy * (c) Andrey Belomutskiy
* 3/6/2015 * 3/6/2015
*/ */
public class BinaryProtocolCmd { public class BinaryProtocolCmd {
static BinaryProtocol bp;
public static void main(String[] args) throws Exception { public static void main(String[] args) throws Exception {
if (args.length != 1) { if (args.length != 1) {
@ -26,7 +24,7 @@ public class BinaryProtocolCmd {
String port = args[0]; String port = args[0];
Logger logger = Logger.STDOUT; Logger logger = UploadChanges.logger;
SerialPort serialPort; SerialPort serialPort;
serialPort = new SerialPort(port); serialPort = new SerialPort(port);
@ -34,15 +32,14 @@ public class BinaryProtocolCmd {
if (!opened) { if (!opened) {
logger.error("failed to open " + port); logger.error("failed to open " + port);
} }
BinaryProtocol bp = new BinaryProtocol(logger, serialPort); bp = new BinaryProtocol(logger, serialPort);
PortHolder.setupPort(serialPort, 38400); PortHolder.setupPort(serialPort, 38400);
logger.info("Looks good"); logger.info("Looks good");
bp.exchange(new byte[]{'S'}); bp.exchange(new byte[]{'S'});
ConfigurationImage image = new ConfigurationImage(14008); bp.readImage(14008);
ConfigurationImage image = bp.getController();
bp.readImage(image);
image.saveToFile("rusefi_configuration.bin"); image.saveToFile("rusefi_configuration.bin");
@ -53,4 +50,7 @@ public class BinaryProtocolCmd {
} }
public static void scheduleBurn(ConfigurationImage newVersion) {
UploadChanges.scheduleBurn(newVersion, bp);
}
} }