OMG it works!

This commit is contained in:
rusefi 2020-06-27 20:55:57 -04:00
parent 00ff85c536
commit e7a9ef5653
7 changed files with 44 additions and 27 deletions

View File

@ -1,6 +1,10 @@
# dfu_java
stm32 java DFU implementation (DfuSe)
This java code can upload a .hex file into stm32f47.
On Windows that means using a libusb-compatible driver like the one included in windows_driver folder.
ST AN3156 Application note
USB DFU protocol used in the STM32 bootloader

View File

@ -0,0 +1,32 @@
package com.rusefi.dfu;
import com.rusefi.dfu.commands.DfuSeCommandErasePage;
import com.rusefi.dfu.commands.DfuSeCommandSetAddress;
import com.rusefi.dfu.usb4java.USBDfuConnection;
import java.nio.ByteBuffer;
public class DfuLogic {
static void uploadImage(USBDfuConnection device, HexImage image) {
// todo: smarter erase handling!
DfuSeCommandErasePage.execute(device, 0x08000000);
DfuSeCommandErasePage.execute(device, 0x08004000);
DfuSeCommandErasePage.execute(device, 0x08008000);
DfuSeCommandErasePage.execute(device, 0x0800C000);
DfuSeCommandErasePage.execute(device, 0x08010000);
DfuSeCommandErasePage.execute(device, 0x08020000);
DfuSeCommandErasePage.execute(device, 0x08040000);
for (int offset = 0; offset < image.getMaxOffset() - image.getRange().getBaseAddress(); offset += device.getTransferSize()) {
DfuSeCommandSetAddress.execute(device, device.getFlashRange().getBaseAddress() + offset);
DfuConnection.waitStatus(device);
ByteBuffer buffer = ByteBuffer.allocateDirect(device.getTransferSize());
buffer.put(image.getImage(), offset, device.getTransferSize());
device.sendData(DfuCommmand.DNLOAD, DfuSeCommand.W_DNLOAD, buffer);
// AN3156 USB DFU protocol used in the STM32 bootloader
// "The Write memory operation is effectively executed only when a DFU_GETSTATUS request is issued by the host. "
DfuConnection.waitStatus(device);
}
}
}

View File

@ -2,6 +2,10 @@ package com.rusefi.dfu;
import java.util.Arrays;
/**
* ST chips send their memory layout in USB description string
* This class knows how to unpack those descriptions
*/
public class DfuSeFlashDescriptor {
private static final String HEX_PREFIX = "0x";
private static final String K_SUFFIX = "Kg";

View File

@ -54,8 +54,6 @@ public class HexImage extends AtomicInteger {
});
ihp.parse();
maxOffset.set(range.getBaseAddress() + 16 * 1024);
return new HexImage(image, range, totalBytesReceived.get(), maxOffset.get());
}

View File

@ -15,7 +15,6 @@ public class DfuSeCommandSetAddress {
public static void execute(USBDfuConnection session, int address) {
log.info(String.format("SetAddress %x", address));
ByteBuffer buffer = createSpecialCommandBuffer(DfuSeCommand.SE_SET_ADDRESS, address);
buffer.putInt(address);
session.sendData(DfuCommmand.DNLOAD, DfuSeCommand.W_SPECIAL, buffer);
}

View File

@ -5,6 +5,9 @@ import cz.jaybee.intelhex.IntelHexException;
import java.io.FileInputStream;
import java.io.IOException;
/**
* A test tool focused only on HEX file input
*/
public class HexReaderSandbox {
public static void main(String[] args) throws IOException, IntelHexException {
@ -14,5 +17,4 @@ public class HexReaderSandbox {
System.out.println("Total received " + image);
}
}

View File

@ -1,7 +1,5 @@
package com.rusefi.dfu;
import com.rusefi.dfu.commands.DfuSeCommandErasePage;
import com.rusefi.dfu.commands.DfuSeCommandSetAddress;
import com.rusefi.dfu.usb4java.DfuDeviceLocator;
import com.rusefi.dfu.usb4java.LogUtil;
import com.rusefi.dfu.usb4java.USBDfuConnection;
@ -10,7 +8,6 @@ import org.apache.commons.logging.Log;
import java.io.FileInputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
public class Sandbox {
private static final Log log = LogUtil.getLog(Sandbox.class);
@ -27,26 +24,7 @@ public class Sandbox {
HexImage image = HexImage.loadHexToBuffer(new FileInputStream("rusefi.hex"), device.getFlashRange());
DfuSeCommandErasePage.execute(device, 0x08000000);
DfuSeCommandErasePage.execute(device, 0x08004000);
DfuSeCommandErasePage.execute(device, 0x08008000);
DfuSeCommandErasePage.execute(device, 0x0800C000);
DfuSeCommandErasePage.execute(device, 0x08010000);
DfuSeCommandErasePage.execute(device, 0x08020000);
DfuSeCommandErasePage.execute(device, 0x08040000);
for (int offset = 0; offset < image.getMaxOffset() - image.getRange().getBaseAddress(); offset += device.getTransferSize()) {
System.out.println("Handling offset " + offset);
DfuSeCommandSetAddress.execute(device, device.getFlashRange().getBaseAddress() + offset);
DfuConnection.waitStatus(device);
ByteBuffer buffer = ByteBuffer.allocateDirect(device.getTransferSize());
buffer.put(image.getImage(), offset, device.getTransferSize());
device.sendData(DfuCommmand.DNLOAD, DfuSeCommand.W_DNLOAD, buffer);
// AN3156 USB DFU protocol used in the STM32 bootloader
// "The Write memory operation is effectively executed only when a DFU_GETSTATUS request is issued by the host. "
DfuConnection.waitStatus(device);
}
DfuLogic.uploadImage(device, image);
log.info("STM32 DFU " + device);
}