From ce9ac815ec4d7e0eb61b7f8b2a82be5ef8b90cef Mon Sep 17 00:00:00 2001 From: rusefi Date: Sun, 5 Jul 2020 16:10:53 -0400 Subject: [PATCH] Android progress --- build.gradle | 1 + src/main/java/com/rusefi/dfu/DfuLogic.java | 6 ++- .../dfu/android/AndroidDfuConnection.java | 16 ++++-- .../java/com/rusefi/dfu/DfuLogicTest.java | 54 +++++++++++++++++++ 4 files changed, 72 insertions(+), 5 deletions(-) create mode 100644 src/test/java/com/rusefi/dfu/DfuLogicTest.java diff --git a/build.gradle b/build.gradle index dd61582..943a3f5 100644 --- a/build.gradle +++ b/build.gradle @@ -16,4 +16,5 @@ dependencies { testImplementation group: 'junit', name: 'junit', version: '4.13' + testCompile group: 'org.mockito', name: 'mockito-all', version: '1.10.19' } diff --git a/src/main/java/com/rusefi/dfu/DfuLogic.java b/src/main/java/com/rusefi/dfu/DfuLogic.java index a6e73ff..a20647f 100644 --- a/src/main/java/com/rusefi/dfu/DfuLogic.java +++ b/src/main/java/com/rusefi/dfu/DfuLogic.java @@ -14,7 +14,7 @@ public class DfuLogic { public static final byte USB_DT_DFU = 0x21; public static final String FLASH_TAG = "Flash"; - static void uploadImage(DfuConnection device, HexImage image, FlashRange range) { + public static void uploadImage(DfuConnection device, BinaryImage image, FlashRange range) { List erasePages = range.pagesForSize(image.getImageSize()); // todo: smarted start address logic int eraseAddress = 0x08000000; @@ -29,7 +29,9 @@ public class DfuLogic { DfuConnectionUtil.waitStatus(device); ByteBuffer buffer = ByteBuffer.allocateDirect(device.getTransferSize()); - buffer.put(image.getImage(), offset, device.getTransferSize()); + // last transfer would usually be smaller than transfer size + int size = Math.min(device.getTransferSize(), image.getImage().length - offset); + buffer.put(image.getImage(), offset, size); 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. " diff --git a/src/main/java/com/rusefi/dfu/android/AndroidDfuConnection.java b/src/main/java/com/rusefi/dfu/android/AndroidDfuConnection.java index bb29b26..4c62da6 100644 --- a/src/main/java/com/rusefi/dfu/android/AndroidDfuConnection.java +++ b/src/main/java/com/rusefi/dfu/android/AndroidDfuConnection.java @@ -7,10 +7,16 @@ import com.rusefi.dfu.FlashRange; import java.nio.ByteBuffer; +import static android.hardware.usb.UsbConstants.USB_DIR_IN; +import static android.hardware.usb.UsbConstants.USB_DIR_OUT; + public class AndroidDfuConnection implements DfuConnection { private final UsbDeviceConnection usbDeviceConnection; private final FlashRange flashRange; + private static final byte REQUEST_TYPE_CLASS = 32; + private static final byte RECIPIENT_INTERFACE = 0x01; + public AndroidDfuConnection(UsbDeviceConnection usbDeviceConnection, FlashRange flashRange) { this.usbDeviceConnection = usbDeviceConnection; this.flashRange = flashRange; @@ -28,12 +34,16 @@ public class AndroidDfuConnection implements DfuConnection { @Override public int receiveData(DfuCommmand command, short wValue, ByteBuffer data) { - //return usbDeviceConnection.controlTransfer(); - return 0; + return transfer(usbDeviceConnection, USB_DIR_IN, command.getValue(), wValue, data); } @Override public int sendData(DfuCommmand command, short wValue, ByteBuffer data) { - return 0; + return transfer(usbDeviceConnection, USB_DIR_OUT, command.getValue(), wValue, data); + } + + private static int transfer(UsbDeviceConnection connection, int direction, int request, short wValue, ByteBuffer byteBuffer) { + return connection.controlTransfer(REQUEST_TYPE_CLASS | RECIPIENT_INTERFACE | direction, request, + wValue, 0, byteBuffer.array(), byteBuffer.limit(), 500); } } diff --git a/src/test/java/com/rusefi/dfu/DfuLogicTest.java b/src/test/java/com/rusefi/dfu/DfuLogicTest.java new file mode 100644 index 0000000..21316dc --- /dev/null +++ b/src/test/java/com/rusefi/dfu/DfuLogicTest.java @@ -0,0 +1,54 @@ +package com.rusefi.dfu; + +import org.junit.Test; + +import java.nio.ByteBuffer; +import java.util.Arrays; + +public class DfuLogicTest { + @Test + public void test() { + FlashRange range = new FlashRange(0, Arrays.asList(20, 40, 80, 800)); + + // todo: migrate to mockito? + DfuConnection device = new DfuConnection() { + @Override + public FlashRange getFlashRange() { + return range; + } + + @Override + public int getTransferSize() { + return 100; + } + + @Override + public int receiveData(DfuCommmand command, short wValue, ByteBuffer data) { + return data.limit(); + } + + @Override + public int sendData(DfuCommmand command, short wValue, ByteBuffer data) { + return data.limit(); + } + }; + + BinaryImage image = new BinaryImage() { + @Override + public byte[] getImage() { + return new byte[150]; + } + + @Override + public int getImageSize() { + return getImage().length; + } + }; + + + + + DfuLogic.uploadImage(device, image, range); + + } +}