now with transfer rate

This commit is contained in:
rusefi 2020-06-27 14:15:32 -04:00
parent 4e4ee82a80
commit 991e83c506
8 changed files with 150 additions and 27 deletions

2
.gitignore vendored
View File

@ -1,3 +1,3 @@
.gradle
build
sample.hex
*.hex

View File

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

View File

@ -16,4 +16,12 @@ public class FlashRange {
public int getTotalLength() {
return totalLength;
}
@Override
public String toString() {
return "FlashRange{" +
"baseAddress=" + baseAddress +
", totalLength=" + totalLength +
'}';
}
}

View File

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

View File

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

View File

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

View File

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

View File

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