Commit e5d313a7 authored by Vincent van Beveren's avatar Vincent van Beveren

added binary export

parent abaed11f
......@@ -185,6 +185,8 @@ public class DDMILoader {
private int _pageSelect = -1;
private String _id;
private String _condition;
private int _start = 0;
private int _end = 255;
private List<ChecksumProxy> _checksumProxy = new ArrayList<ChecksumProxy>();
......@@ -210,6 +212,17 @@ public class DDMILoader {
_page = XOL.parseInt(val);
return true;
}
if (name.equals("start")) {
_start = XOL.parseInt(val);
return true;
}
if (name.equals("end")) {
_end = XOL.parseInt(val);
return true;
}
if (name.equals("parent-id")) {
XOLProxy<?> proxy = getXol().getProxyById(val);
......@@ -244,9 +257,9 @@ public class DDMILoader {
DataSource ds = null;
if (_i2cAddress >= 0) {
ds = new I2CDataSource(_i2cAddress);
ds = new I2CDataSource(_i2cAddress, _start, _end);
} else if (_page != -1) {
ds = new PageDataSource(_parent, _page);
ds = new PageDataSource(_parent, _page, _start, _end);
}
if (ds == null) throw new RuntimeException("DataSource element not correctly attributted");
......
......@@ -12,7 +12,9 @@ import org.luaj.vm2.LuaValue;
public abstract class DataSource {
private String _condition;
private static final Logger LOG = Logger.getLogger(DataSource.class.getSimpleName());
private static final Logger LOG = Logger.getLogger(DataSource.class.getSimpleName());
public final int start;
public final int end;
private class Checksum
......@@ -130,8 +132,10 @@ public abstract class DataSource {
private List<Cache> _caches;
private String _id;
protected DataSource()
protected DataSource(int start, int end)
{
this.start = start;
this.end = end;
}
public void setId(String id) {
......@@ -280,4 +284,10 @@ public abstract class DataSource {
c.clear(ctx);
}
}
public int size() {
return end - start + 1;
}
public abstract String getPath();
}
\ No newline at end of file
......@@ -8,7 +8,8 @@ public class I2CDataSource extends DataSource {
private final int _addr;
public I2CDataSource(int addr) {
public I2CDataSource(int addr, int start, int end) {
super(start, end);
this._addr = addr;
}
......@@ -72,4 +73,9 @@ public class I2CDataSource extends DataSource {
public String toString() {
return String.format("I2CDataSource(addr=%02x)", _addr);
}
@Override
public String getPath() {
return Integer.toHexString(_addr);
}
}
......@@ -13,8 +13,9 @@ public class PageDataSource extends DataSource {
private final DataSource _parent;
private final int _pageNo;
public PageDataSource(DataSource parent, int pageNo)
public PageDataSource(DataSource parent, int pageNo, int start, int end)
{
super(start, end);
assert(parent != null);
_parent = parent;
_pageNo = pageNo;
......@@ -57,4 +58,9 @@ public class PageDataSource extends DataSource {
_parent.writeMedia(ctx, off, data);
}
@Override
public String getPath() {
return _parent.getPath() + "_page" + _pageNo;
}
}
......@@ -4,20 +4,19 @@
<ddmi id="root">
<source i2c-addr="x50" id="eeprom">
<source i2c-addr="x50" id="eeprom" start="0" end="255">
<checksum offset="63" start="0" end="62"/>
<checksum offset="95" start="64" end="94"/>
<cache start="0" end="255"/>
</source>
<source i2c-addr="x51" id="diag" page-select="127" valid-if="isset(id.montype, 6)">
<source i2c-addr="x51" id="diag" page-select="127" valid-if="isset(id.montype, 6)" start="0" end="127">
<checksum offset="95" start="0" end="94"/>
<cache start="0" end="95"/>
</source>
<source page="0" parent-id="diag" id="diag_p0" />
<source page="1" parent-id="diag" id="diag_p1" />
<source page="2" parent-id="diag" id="diag_p2" />
<source page="3" parent-id="diag" id="diag_p3" />
<source page="0" parent-id="diag" id="diag_p0" start="128" end="255" />
<source page="1" parent-id="diag" id="diag_p1" start="128" end="255" />
<source page="2" parent-id="diag" id="diag_p2" start="128" end="255" />
<source page="3" parent-id="diag" id="diag_p3" start="128" end="255" />
<group source-id="eeprom">
<group label="Base ID fields" source-id="eeprom" name="base_id">
......
......@@ -98,8 +98,18 @@ public class SimI2CLink implements I2CLink {
0x00, 0x00, 0x00,
// page select
0x00
0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 128
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 144
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 160
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 176
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 192
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 208
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 224
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 240
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 // 256
};
......@@ -129,13 +139,13 @@ public class SimI2CLink implements I2CLink {
public void i2cWrite(int addr, byte[] data) throws IOException
{
if (addr != 0x50 && addr != 0x51) throw new IOException("I2C No Ack");
/*
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
*/
if (addr == 0x50) {
_eepromPtr = 0xFF & data[0];
......@@ -164,12 +174,14 @@ public class SimI2CLink implements I2CLink {
public byte[] i2cRead(int addr, int len) throws IOException {
if (addr != 0x50 && addr != 0x51) throw new IOException("I2C No Ack");
/*
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
*/
byte[] d = new byte[len];
for (int i = 0; i < len; i++)
......
package nl.nikhef.tools;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;
......@@ -69,6 +70,45 @@ public final class Utils {
return result;
}
public static void dumpHex(PrintWriter pw, byte[] data, boolean extended) {
StringBuilder sbC = new StringBuilder();
StringBuilder sbH = new StringBuilder();
for (int i = 0; i < data.length; i++) {
if (i % 16 == 0 && extended) {
pw.printf("%04x: ", i);
}
char c = (char)data[i];
if (extended) sbC.append(c >= ' ' && c <= '~' ? c : '.');
sbH.append(String.format(" %02x", data[i]));
if (i % 16 == 15) {
if (extended) {
pw.printf("%-16s %s\n", sbC, sbH);
sbC.setLength(0);
} else {
pw.printf("%s\n", sbH);
}
sbH.setLength(0);
}
}
if (sbC.length() > 0) {
if (extended) {
pw.printf("%-16s %s\n", sbC, sbH);
sbC.setLength(0);
} else {
pw.printf("%s\n", sbH);
}
}
}
public static void dumpHex(String title, byte[] data)
{
StringBuilder sbC = new StringBuilder();
......@@ -163,5 +203,6 @@ public final class Utils {
}
}
package nl.nikhef.safaripark;
import java.awt.Component;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import javax.swing.Action;
import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.ButtonGroup;
import javax.swing.JFileChooser;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import nl.nikhef.safaripark.devmgr.BaySelectionListener;
import nl.nikhef.sfp.SFPDevice;
import nl.nikhef.sfp.ddmi.DDMI;
import nl.nikhef.sfp.ddmi.DDMIContext;
import nl.nikhef.sfp.ddmi.DDMILoader;
import nl.nikhef.sfp.ddmi.DataSource;
import nl.nikhef.tools.Utils;
public class ModuleManager implements BaySelectionListener
{
private Action _binExport;
private JFileChooser _dirChooser;
private JRadioButton _binary;
private JRadioButton _plainhex;
private JRadioButton _extendedhex;
private DDMI _ddmi;
private ContextCache _ctxCache;
private DDMIContext _ctx;
private String _moduleName;
private DateFormat _fileDateFormat = new SimpleDateFormat("yyMMdd_HHmmss");
public ModuleManager(Action binExport, DDMILoader ddmiLoader, ContextCache cc)
{
_ctxCache = cc;
_binExport = binExport;
_binExport.setEnabled(false);
_dirChooser = new JFileChooser();
_ddmi = ddmiLoader.getDDMI();
ButtonGroup bg = new ButtonGroup();
_binary = new JRadioButton("Binary");
_plainhex = new JRadioButton("Plain Hex");
_extendedhex = new JRadioButton("Extended Hex");
bg.add(_plainhex);
bg.add(_extendedhex);
bg.add(_binary);
_extendedhex.setSelected(true);
JPanel pnl = new JPanel();
pnl.setBorder(BorderFactory.createEmptyBorder(4, 4, 4, 4));
pnl.setLayout(new BoxLayout(pnl, BoxLayout.PAGE_AXIS));
pnl.add(new JLabel("Export format"));
pnl.add(_extendedhex);
pnl.add(_plainhex);
pnl.add(_binary);
_dirChooser.setAccessory(pnl);
_dirChooser.setDialogTitle("Select directoy to export module contents to");
_dirChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
}
@Override
public void baySelected(SFPDevice dev, int bay) {
try {
if (dev.isModulePresent(bay))
{
_ctx = _ctxCache.getContextFor(dev, bay);
_moduleName = dev.getModuleSerial(bay);
_binExport.setEnabled(true);
} else {
_ctx = null;
_binExport.setEnabled(false);
}
} catch (IOException e) {
_ctx = null;
_binExport.setEnabled(false);
}
}
public void exportBinary(Component parent)
{
if ((_dirChooser.showDialog(parent, "Select") != JFileChooser.APPROVE_OPTION))
{
return;
}
File f = _dirChooser.getSelectedFile();
for (DataSource ds : _ddmi.getSources())
{
if (!ds.isValid(_ctx)) continue;
System.out.println("Exporting datasource " + ds);
try {
byte[] data = ds.read(_ctx, ds.start, ds.size());
String filebase = String.format("sfp_%s_%s_%s",
_fileDateFormat.format(new Date()),
_moduleName,
ds.getPath());
if (_plainhex.isSelected()) {
exportHex(f, filebase, data, false);
}
if (_binary.isSelected()) {
exportBinary(f, filebase, data);
}
if (_extendedhex.isSelected()) {
exportHex(f, filebase, data, true);
}
} catch (IOException e) {
e.printStackTrace();
continue;
}
}
}
private void exportHex(File f, String filebase, byte[] content, boolean extended) throws IOException
{
PrintWriter pw = new PrintWriter(new FileWriter(new File(f, filebase + (extended ? ".txt" : ".hex"))));
try {
Utils.dumpHex(pw, content, extended);
} finally {
pw.close();
}
}
private void exportBinary(File f, String filebase, byte[] content) throws IOException
{
FileOutputStream fos = new FileOutputStream(new File(f, filebase + ".bin"));
try {
fos.write(content);
} finally {
fos.close();
}
}
@Override
public boolean canSelectBay(SFPDevice dev, int bay) {
return true;
}
}
......@@ -66,6 +66,7 @@ public class SaFariPark extends JFrame implements BaySelectionListener, WindowLi
private DDMILoader _loader;
private ContextCache _ctxCache;
private OverlayManager _ovlMgr;
private ModuleManager _modMgr;
private Action _selectOverlays = new ExtendedAbstractAction("Select overlays", Resources.getIcon("books"), "Select which SFP+ overlays to load") {
......@@ -77,6 +78,19 @@ public class SaFariPark extends JFrame implements BaySelectionListener, WindowLi
}
};
private Action _saveBinary = new ExtendedAbstractAction("Save module contents", Resources.getIcon("document-export-4"), "Save a binary export") {
@Override
public void actionPerformed(ActionEvent e)
{
_modMgr.exportBinary(SaFariPark.this);
}
};
@Inject
......@@ -97,10 +111,13 @@ public class SaFariPark extends JFrame implements BaySelectionListener, WindowLi
_devMgr = new DeviceManager(_sfpManager);
_devMgr.addDeviceSelectedListener(this);
_tabEdit = new EditPane(_ctxCache);
_logOut = new ActiveLogArea();
_monitor = new Monitor(_loader, _ctxCache, _sfpManager);
_status = new StatusBar();
_modMgr = new ModuleManager(_saveBinary, _loader, _ctxCache);
_devMgr.addDeviceSelectedListener(_modMgr);
makeToolbar();
JSplitPane split = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);
split.setLeftComponent(_devMgr);
......@@ -144,6 +161,8 @@ public class SaFariPark extends JFrame implements BaySelectionListener, WindowLi
{
JToolBar tb = new JToolBar();
tb.add(_selectOverlays);
tb.add(_saveBinary);
GuiUtils.toolbarTextButtions(tb);
add(tb, BorderLayout.NORTH);
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment