alchitry / Alchitry-Labs

https://alchitry.com/
GNU General Public License v3.0
28 stars 12 forks source link

Writing to flash on OSX for Mojo v3 #23

Open hussainak opened 4 years ago

hussainak commented 4 years ago

Hi AlChirty,

I am on a mac with OSX mojave installed and I installed ubuntu on virtualbox to work with Alchitry labs. However there is an issue with VirtualBox which quits unexpectedly when I connect Mojo v3 through the USB. So, I wanted to write a small utility that could transfer .bin files on OSX itself. I made an attempt but I am unable to write anything to it. Is there special signalling requred through the microcontroller to get it to work? Please advise based on the code below:

` /*

import java.io.File; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.nio.IntBuffer; import java.nio.file.Files; import org.usb4java.BufferUtils; import org.usb4java.Context; import org.usb4java.Device; import org.usb4java.DeviceDescriptor; import org.usb4java.DeviceHandle; import org.usb4java.DeviceList; import org.usb4java.LibUsb; import org.usb4java.LibUsbException;

/*

// byte[] buff = new byte[100]; // // for (int i = 0; i < 100; i++) { // buff[i] = (byte) (length >> (i * 8) & 0xff); // } // Write // this.write(handle, fileContent); // this.restartMojo(handle); byte b = (byte) 'R'; byte[] buf = new byte[1]; buf[0] = b;

        this.write(handle, buf);

        this.writeData(handle, fileContent);

// DTRRTS(handle, true, false); // Receive the header of the ADB answer (Most likely an AUTH message) // ByteBuffer header = read(handle, 24); // header.position(12); // int dataSize = header.asIntBuffer().get(); // // // Receive the body of the ADB answer // @SuppressWarnings("unused") // ByteBuffer data = read(handle, dataSize); // Release the ADB interface result = LibUsb.releaseInterface(handle, INTERFACE); if (result != LibUsb.SUCCESS) { throw new LibUsbException("Unable to release interface", result); }

        // Close the device
        LibUsb.close(handle);

        // Deinitialize the libusb context
        LibUsb.exit(context);
    } catch (Exception e) {
        System.out.println("Exception: " + e.getMessage());
    }

}

public Device findDevice(short vendorId, short productId) {
    int result1 = LibUsb.init(context);
    if (result1 != LibUsb.SUCCESS) {
        throw new LibUsbException("Unable to initialize libusb.", result1);
    }
    // Read the USB device list
    DeviceList list = new DeviceList();
    int result = LibUsb.getDeviceList(context, list);
    if (result < 0) {
        throw new LibUsbException("Unable to get device list", result);
    }

    try {
        // Iterate over all devices and scan for the right one
        for (Device device : list) {
            DeviceDescriptor descriptor = new DeviceDescriptor();
            result = LibUsb.getDeviceDescriptor(device, descriptor);
            if (result != LibUsb.SUCCESS) {
                throw new LibUsbException("Unable to read device descriptor", result);
            }

            if (descriptor.idVendor() == vendorId && descriptor.idProduct() == productId) {
                return device;
            }
        }
    } finally {
        // Ensure the allocated device list is freed
        LibUsb.freeDeviceList(list, true);
    }

    // Device not found
    return null;
}

public int writeData(DeviceHandle device, byte[] data) {
    int offset = 0;
    ByteBuffer buf = ByteBuffer.allocateDirect(data.length);
    buf.put(data);
    IntBuffer transferred = IntBuffer.allocate(1);

    if (device == null) {
        throw new LibUsbException("USB device unavailable", -666);
    }

    while (offset < data.length) {
        int writeSize = writeBufferChunksize;

        if (offset + writeSize > data.length) {
            writeSize = data.length - offset;
        }

        buf.position(offset);
        int code;
        if ((code = LibUsb.bulkTransfer(device, inEndPoint, buf, transferred, writeTimeout)) < 0) {
            throw new LibUsbException("usb bulk write failed", code);
        }

        offset += transferred.get();
    }

    return offset;
}

public void listDevices() {
    int result1 = LibUsb.init(context);
    if (result1 != LibUsb.SUCCESS) {
        throw new LibUsbException("Unable to initialize libusb.", result1);
    }
    // Read the USB device list
    DeviceList list = new DeviceList();
    int result = LibUsb.getDeviceList(context, list);
    if (result < 0) {
        throw new LibUsbException("Unable to get device list", result);
    }

    try {
        // Iterate over all devices and scan for the right one
        for (Device device : list) {
            DeviceDescriptor descriptor = new DeviceDescriptor();
            result = LibUsb.getDeviceDescriptor(device, descriptor);

            DeviceHandle handle = new DeviceHandle();
            int result2 = LibUsb.open(device, handle);
            if (result2 < 0) {
                System.out.println(String.format("Unable to open device: %s. "
                        + "Continuing without device handle.",
                        LibUsb.strError(result2)));
                handle = null;
            }

            System.out.println("Device: " + device + " Dump: " + descriptor.dump(handle));

// System.out.println("Device: " + descriptor.dump(handle)); // System.out.println("VendorID: " + descriptor.idVendor()); // System.out.println("ProductID: " + descriptor.idProduct()); if (result != LibUsb.SUCCESS) { throw new LibUsbException("Unable to read device descriptor", result); } } } finally { // Ensure the allocated device list is freed LibUsb.freeDeviceList(list, true); LibUsb.exit(context); }

    // Device not found

// return null; }

public ByteBuffer read(DeviceHandle handle, int size) {
    ByteBuffer buffer = BufferUtils.allocateByteBuffer(size).order(
            ByteOrder.LITTLE_ENDIAN);
    IntBuffer transferred = BufferUtils.allocateIntBuffer();
    int result = LibUsb.bulkTransfer(handle, IN_ENDPOINT, buffer,
            transferred, TIMEOUT);
    if (result != LibUsb.SUCCESS) {
        throw new LibUsbException("Unable to read data", result);
    }
    System.out.println(transferred.get() + " bytes read from device");
    return buffer;
}

public static void write(DeviceHandle handle, byte[] data) {
    ByteBuffer buffer = BufferUtils.allocateByteBuffer(data.length);
    buffer.put(data);
    IntBuffer transferred = BufferUtils.allocateIntBuffer();
    int result = LibUsb.bulkTransfer(handle, OUT_ENDPOINT, buffer,
            transferred, TIMEOUT);
    if (result != LibUsb.SUCCESS) {
        throw new LibUsbException("Unable to send data", result);
    }
    System.out.println(transferred.get() + " bytes sent to device");
}

private void restartMojo(DeviceHandle handle) {
    this.DTRRTS(handle, false, true);
    this.sleep(5);
    for (int i = 0; i < 5; i++) {
        this.DTRRTS(handle, false, true);
        this.sleep(5);
        this.DTRRTS(handle, true, true);
        this.sleep(5);
    }
}

public static void sleep(long millis) {
    try {
        Thread.sleep(millis);
    } catch (InterruptedException e) {
        System.out.println(e + " Sleep interrupted but not important!");
    }
}

public static void DTRRTS(DeviceHandle handle, boolean dtr, boolean rts) {
    short value = (short) ((dtr ? ACM_CTRL_DTR : 0x00) | (rts ? ACM_CTRL_RTS : 0x00));
    LibUsb.controlTransfer(handle, DEVICE_OUT_REQUEST, CDC_SET_CONTROL_LINE_STATE, value, (short) 0, EMPTY_BUF, TIMEOUT);

}

}

`

hussainak commented 4 years ago

This will also help me program in VHDL and then transfer the bit file