mirror of https://github.com/rusefi/dfu_java.git
now with transfer rate
This commit is contained in:
parent
4e4ee82a80
commit
991e83c506
|
@ -1,3 +1,3 @@
|
|||
.gradle
|
||||
build
|
||||
sample.hex
|
||||
*.hex
|
||||
|
|
|
@ -6,6 +6,10 @@ public interface DfuConnection {
|
|||
int SECOND = 1000;
|
||||
int DFU_TIMEOUT = 10 * DfuConnection.SECOND;
|
||||
|
||||
FlashRange getFlashRange();
|
||||
|
||||
int getTransferSize();
|
||||
|
||||
int receiveData(DfuCommmand command, short value, ByteBuffer data);
|
||||
|
||||
int sendData(DfuCommmand command, short value, ByteBuffer data);
|
||||
|
|
|
@ -16,4 +16,12 @@ public class FlashRange {
|
|||
public int getTotalLength() {
|
||||
return totalLength;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "FlashRange{" +
|
||||
"baseAddress=" + baseAddress +
|
||||
", totalLength=" + totalLength +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,16 +1,21 @@
|
|||
package com.rusefi.dfu.usb4java;
|
||||
|
||||
import com.rusefi.dfu.DfuSeFlashDescriptor;
|
||||
import com.rusefi.dfu.FlashRange;
|
||||
import com.rusefi.dfu.commands.DfuCommandClearStatus;
|
||||
import com.rusefi.dfu.commands.DfuCommandGetStatus;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.usb4java.*;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
public class DfuDeviceLocator {
|
||||
private static final short ST_VENDOR = 0x0483;
|
||||
private static final short ST_DFU_PRODUCT = (short) 0xdf11;
|
||||
|
||||
private static final byte USB_CLASS_APP_SPECIFIC = (byte) 0xfe;
|
||||
private static final byte DFU_SUBCLASS = 0x01;
|
||||
private static final byte USB_DT_DFU = 0x21;
|
||||
|
||||
private static final Log log = LogUtil.getLog(DfuDeviceLocator.class);
|
||||
|
||||
|
@ -56,9 +61,18 @@ public class DfuDeviceLocator {
|
|||
return null;
|
||||
}
|
||||
|
||||
public static int swap16(int x) {
|
||||
return (((x & 0xff) << 8) | ((x >> 8) & 0xff));
|
||||
}
|
||||
|
||||
public static USBDfuConnection findDfuInterface(Device device, DeviceDescriptor deviceDescriptor) {
|
||||
byte numConfigurations = deviceDescriptor.bNumConfigurations();
|
||||
log.info(numConfigurations + " configuration(s)");
|
||||
|
||||
DeviceHandle deviceHandle = open(device);
|
||||
int transferSize = 0;
|
||||
FlashRange flashRange = null;
|
||||
|
||||
for (int configurationIndex = 0; configurationIndex < numConfigurations; configurationIndex++) {
|
||||
ConfigDescriptor config = new ConfigDescriptor();
|
||||
int result = LibUsb.getConfigDescriptor(device, (byte) configurationIndex, config);
|
||||
|
@ -66,6 +80,9 @@ public class DfuDeviceLocator {
|
|||
throw new LibUsbException("getConfigDescriptor", result);
|
||||
}
|
||||
|
||||
System.out.println("Config " + config);
|
||||
System.out.println("Config Done");
|
||||
|
||||
byte numInterfaces = config.bNumInterfaces();
|
||||
log.info(numInterfaces + " interface(s)");
|
||||
|
||||
|
@ -74,7 +91,32 @@ public class DfuDeviceLocator {
|
|||
|
||||
for (int s = 0; s < iface.numAltsetting(); s++) {
|
||||
InterfaceDescriptor setting = iface.altsetting()[s];
|
||||
log.info("Set " + setting);
|
||||
System.out.println("setting " + setting);
|
||||
|
||||
ByteBuffer extra = setting.extra();
|
||||
|
||||
if (extra.limit() > 2) {
|
||||
int len = extra.get();
|
||||
byte type = extra.get();
|
||||
if (type == USB_DT_DFU) {
|
||||
System.out.println(len + " " + type);
|
||||
extra.get(); // bmAttributes
|
||||
extra.get(); // wDetachTimeOut
|
||||
extra.get();
|
||||
transferSize = swap16(extra.getShort());
|
||||
System.out.println("transferSize " + transferSize);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int interfaceIndex = 0; interfaceIndex < numInterfaces; interfaceIndex++) {
|
||||
Interface iface = config.iface()[interfaceIndex];
|
||||
|
||||
for (int s = 0; s < iface.numAltsetting(); s++) {
|
||||
InterfaceDescriptor setting = iface.altsetting()[s];
|
||||
|
||||
log.info("Settings " + setting);
|
||||
byte interfaceNumber = setting.bInterfaceNumber();
|
||||
log.info(String.format("Setting %d: %x %x class %x, subclass %x, protocol: %x", s,
|
||||
interfaceNumber,
|
||||
|
@ -83,23 +125,21 @@ public class DfuDeviceLocator {
|
|||
setting.bInterfaceProtocol()
|
||||
));
|
||||
|
||||
|
||||
|
||||
if (setting.bInterfaceClass() == USB_CLASS_APP_SPECIFIC &&
|
||||
setting.bInterfaceSubClass() == DFU_SUBCLASS) {
|
||||
log.debug(String.format("Found DFU interface: %d", interfaceNumber));
|
||||
|
||||
DeviceHandle deviceHandle = open(device);
|
||||
|
||||
String stringDescriptor = LibUsb.getStringDescriptor(deviceHandle, setting.iInterface());
|
||||
log.info("StringDescriptor: " + stringDescriptor);
|
||||
if (stringDescriptor.contains("Flash"))
|
||||
flashRange = DfuSeFlashDescriptor.parse(stringDescriptor);
|
||||
|
||||
result = LibUsb.claimInterface(deviceHandle, interfaceNumber);
|
||||
if (result != LibUsb.SUCCESS) {
|
||||
throw new LibUsbException("claimInterface", result);
|
||||
}
|
||||
|
||||
USBDfuConnection session = new USBDfuConnection(deviceHandle, interfaceNumber);
|
||||
USBDfuConnection session = new USBDfuConnection(deviceHandle, interfaceNumber, transferSize, flashRange);
|
||||
|
||||
DfuCommandGetStatus.State state = DfuCommandGetStatus.read(session);
|
||||
log.info("DFU state: " + state);
|
||||
|
|
|
@ -2,6 +2,7 @@ package com.rusefi.dfu.usb4java;
|
|||
|
||||
import com.rusefi.dfu.DfuCommmand;
|
||||
import com.rusefi.dfu.DfuConnection;
|
||||
import com.rusefi.dfu.FlashRange;
|
||||
import org.usb4java.DeviceHandle;
|
||||
import org.usb4java.LibUsb;
|
||||
|
||||
|
@ -10,10 +11,24 @@ import java.nio.ByteBuffer;
|
|||
public class USBDfuConnection implements DfuConnection {
|
||||
private final DeviceHandle deviceHandle;
|
||||
private final byte interfaceNumber;
|
||||
private final int transferSize;
|
||||
private final FlashRange flashRange;
|
||||
|
||||
public USBDfuConnection(DeviceHandle deviceHandle, byte interfaceNumber) {
|
||||
public USBDfuConnection(DeviceHandle deviceHandle, byte interfaceNumber, int transferSize, FlashRange flashRange) {
|
||||
this.deviceHandle = deviceHandle;
|
||||
this.interfaceNumber = interfaceNumber;
|
||||
this.transferSize = transferSize;
|
||||
this.flashRange = flashRange;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FlashRange getFlashRange() {
|
||||
return flashRange;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getTransferSize() {
|
||||
return transferSize;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -0,0 +1,59 @@
|
|||
package com.rusefi.dfu;
|
||||
|
||||
import cz.jaybee.intelhex.DataListener;
|
||||
import cz.jaybee.intelhex.IntelHexException;
|
||||
import cz.jaybee.intelhex.Parser;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
public class HexImage extends AtomicInteger {
|
||||
private final byte[] image;
|
||||
private final int totalBytes;
|
||||
|
||||
public HexImage(byte[] image, int totalBytes) {
|
||||
this.image = image;
|
||||
this.totalBytes = totalBytes;
|
||||
}
|
||||
|
||||
static HexImage loadHexToBuffer(InputStream is, FlashRange range) throws IntelHexException, IOException {
|
||||
byte[] image = new byte[range.getTotalLength()];
|
||||
|
||||
// create IntelHexParserObject
|
||||
Parser ihp = new Parser(is);
|
||||
|
||||
AtomicInteger totalBytesReceived = new AtomicInteger();
|
||||
// register parser listener
|
||||
ihp.setDataListener(new DataListener() {
|
||||
@Override
|
||||
public void data(long address, byte[] data) {
|
||||
// System.out.printf("Address %x size %x\n", address, data.length);
|
||||
totalBytesReceived.addAndGet(data.length);
|
||||
|
||||
if (address < range.getBaseAddress() || address + data.length > range.getBaseAddress() + range.getTotalLength())
|
||||
throw new IllegalStateException(String.format("Image data out of range: %x@%x not withiin %s",
|
||||
data.length,
|
||||
address,
|
||||
range.toString()));
|
||||
System.arraycopy(data, 0, image, (int) (address - range.getBaseAddress()), data.length);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void eof() {
|
||||
// do some action
|
||||
}
|
||||
});
|
||||
ihp.parse();
|
||||
|
||||
return new HexImage(image, totalBytesReceived.get());
|
||||
}
|
||||
|
||||
public byte[] getImage() {
|
||||
return image;
|
||||
}
|
||||
|
||||
public int getTotalBytes() {
|
||||
return totalBytes;
|
||||
}
|
||||
}
|
|
@ -1,32 +1,18 @@
|
|||
package com.rusefi.dfu;
|
||||
|
||||
import cz.jaybee.intelhex.DataListener;
|
||||
import cz.jaybee.intelhex.IntelHexException;
|
||||
import cz.jaybee.intelhex.Parser;
|
||||
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
public class HexReaderSandbox {
|
||||
public static void main(String[] args) throws IOException, IntelHexException {
|
||||
InputStream is = new FileInputStream("sample.hex");
|
||||
|
||||
// create IntelHexParserObject
|
||||
Parser ihp = new Parser(is);
|
||||
FlashRange range = new FlashRange(0x8000000, 0x100000);
|
||||
|
||||
// register parser listener
|
||||
ihp.setDataListener(new DataListener() {
|
||||
@Override
|
||||
public void data(long address, byte[] data) {
|
||||
System.out.printf("Address %x size %x\n", address, data.length);
|
||||
}
|
||||
HexImage image = HexImage.loadHexToBuffer(new FileInputStream("rusefi.hex"), range);
|
||||
|
||||
@Override
|
||||
public void eof() {
|
||||
// do some action
|
||||
}
|
||||
});
|
||||
ihp.parse();
|
||||
System.out.println("Total received " + image.getTotalBytes());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -3,15 +3,26 @@ package com.rusefi.dfu;
|
|||
import com.rusefi.dfu.usb4java.DfuDeviceLocator;
|
||||
import com.rusefi.dfu.usb4java.LogUtil;
|
||||
import com.rusefi.dfu.usb4java.USBDfuConnection;
|
||||
import cz.jaybee.intelhex.IntelHexException;
|
||||
import org.apache.commons.logging.Log;
|
||||
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
public class Sandbox {
|
||||
private static final Log log = LogUtil.getLog(Sandbox.class);
|
||||
|
||||
public static void main(String[] args) {
|
||||
public static void main(String[] args) throws IOException, IntelHexException {
|
||||
log.info("Hello sandbox");
|
||||
|
||||
USBDfuConnection device = DfuDeviceLocator.findDevice();
|
||||
if (device == null) {
|
||||
System.err.println("No DFU devices found");
|
||||
return;
|
||||
}
|
||||
|
||||
HexImage image = HexImage.loadHexToBuffer(new FileInputStream("rusefi.hex"), device.getFlashRange());
|
||||
|
||||
|
||||
log.info("STM32 DFU " + device);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue