commit 89a614a6cd4ffdccb9dbe38a82fdc53a52b36f4b Author: Schoumi Date: Wed Mar 16 12:24:49 2016 +0100 list ftdi device and get lpc ids diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ecc4083 --- /dev/null +++ b/.gitignore @@ -0,0 +1,24 @@ +*.apk + +# Generated files +bin/ +gen/ + +# Gradle files +.gradle/ +build/ +/*/build/ +gradlew* + +# Local configuration file (sdk path, etc) +local.properties + +# Proguard folder generated by Eclipse +proguard/ + +# Log Files +*.log + +#android-studio file +.idea +*.iml diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..4cd354c --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,31 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion 23 + buildToolsVersion "23.0.2" + + defaultConfig { + applicationId "fr.mobdev.lpcprog" + minSdkVersion 12 + targetSdkVersion 23 + versionCode 1 + versionName "1.0" + } + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' + } + } +} + +repositories{ + maven { url "https://jitpack.io" } +} + +dependencies { + compile 'com.android.support:appcompat-v7:23.1.1' + compile 'com.android.support:design:23.1.1' + //compile 'com.github.felHR85:UsbSerial:4.1.1' + compile files('src/main/libs/d2xx.jar') +} diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..2494fe9 --- /dev/null +++ b/app/proguard-rules.pro @@ -0,0 +1,17 @@ +# Add project specific ProGuard rules here. +# By default, the flags in this file are appended to flags specified +# in /home/schoumi/projet/sdk/android-sdk/tools/proguard/proguard-android.txt +# You can edit the include path and order by changing the proguardFiles +# directive in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# Add any project specific keep options here: + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} diff --git a/app/src/DeviceAdapter.java b/app/src/DeviceAdapter.java new file mode 100644 index 0000000..7b12618 --- /dev/null +++ b/app/src/DeviceAdapter.java @@ -0,0 +1,57 @@ +package fr.mobdev.lpcprog; + +import android.hardware.usb.UsbDevice; +import android.hardware.usb.UsbDeviceConnection; +import android.os.Build; +import android.support.v7.widget.RecyclerView; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.TextView; + +import java.util.List; + +public class DeviceAdapter extends RecyclerView.Adapter { + + private List devices; + public DeviceAdapter(List devices){ + this.devices = devices; + } + + @Override + public DeviceHolder onCreateViewHolder(ViewGroup parent, int viewType) { + View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.device_item,parent,false); + return new DeviceHolder(view); + } + + @Override + public void onBindViewHolder(DeviceHolder holder, int position) { + holder.setupDevice(devices.get(position)); + } + + @Override + public int getItemCount() { + return devices.size(); + } +} + +class DeviceHolder extends RecyclerView.ViewHolder { + + + public DeviceHolder(View itemView) { + super(itemView); + } + + public void setupDevice(UsbDevice device){ + if(Build.VERSION.SDK_INT >= 21) { + TextView name = (TextView) itemView.findViewById(R.id.device_name); + name.setText("Name: " + device.getProductName()); + } + TextView vendor = (TextView) itemView.findViewById(R.id.device_vendor_id); + vendor.setText("Vendor Id: "+device.getVendorId()); + TextView product = (TextView) itemView.findViewById(R.id.device_id); + product.setText("Product id: " + device.getProductId()); + + } + +} diff --git a/app/src/IspManager.java b/app/src/IspManager.java new file mode 100644 index 0000000..67eb8de --- /dev/null +++ b/app/src/IspManager.java @@ -0,0 +1,227 @@ +package fr.mobdev.lpcprog; + +import android.hardware.usb.UsbDevice; +import android.hardware.usb.UsbDeviceConnection; +import android.provider.Settings; + +import com.felhr.usbserial.UsbSerialDevice; +import com.felhr.usbserial.UsbSerialInterface; + +public class IspManager { + + //defines + private static final int REP_BUF = 100; + private static final byte[] SYNC_START = "?".getBytes(); + private static final byte[] SYNC = "Synchronized\r\n".getBytes(); + private static final byte[] SYNC_OK = "OK\r\n".getBytes(); + private static final byte[] DATA_BLOCK = "OK\r\n".getBytes(); + private static final byte[] DATA_BLOCK_RESEND = "RESEND\r\n".getBytes(); + private static final byte[] SYNC_ECHO_OFF = "A 0\r\n".getBytes(); + private static final byte[] READ_UID = "N\r\n".getBytes(); + private static final byte[] READ_PART_ID = "J\r\n".getBytes(); + private static final byte[] READ_BOOT_VERSION = "K\r\n".getBytes(); + + //members + private static IspManager instance = null; + private UsbSerialDevice serialPort = null; + + private IspManager(){ + + } + + public static IspManager getInstance(){ + if(instance == null) + instance = new IspManager(); + return instance; + } + + public boolean setupDevice(UsbDevice device, UsbDeviceConnection connection, int baudRate, int data, int stops, int parity, int flow){ + serialPort = UsbSerialDevice.createUsbSerialDevice(device, connection); + if(serialPort.syncOpen()) { + serialPort.setBaudRate(baudRate); + serialPort.setDataBits(data); + serialPort.setStopBits(stops); + serialPort.setParity(parity); + serialPort.setFlowControl(flow); + return true; + } + return false; + } + + public boolean synchronize(int crystal_freq){ + if(serialPort == null) + return false; + byte[] buf; + if(serialPort.syncWrite(SYNC_START,500) != SYNC_START.length){ + System.out.println("Start"); + return false; + } + + buf = new byte[SYNC.length]; + serialPort.syncRead(buf,500); + String result = new String(buf); + String expected = new String(SYNC); + if(result.compareTo(expected) != 0) { + printbuffer(buf); + System.out.println("Start answer "+result); + return false; + } + if(serialPort.syncWrite(SYNC,500) != SYNC.length) { + System.out.println("SYNC write"); + return false; + } + clearBuffer(SYNC.length); + buf = new byte[SYNC_OK.length]; + serialPort.syncRead(buf,500); + result = new String(buf); + expected = new String(SYNC_OK); + if(result.compareTo(expected) != 0) { + printbuffer(buf); + System.out.println("SYNC OK "+result); + return false; + } + + String freq = String.valueOf(crystal_freq)+"\r\n"; + if(serialPort.syncWrite(freq.getBytes(),500) != freq.length()) { + System.out.println("freq write"); + return false; + } + + clearBuffer(freq.length()); + buf = new byte[SYNC_OK.length]; + serialPort.syncRead(buf,500); + result = new String(buf); + expected = new String(SYNC_OK); + if(result.compareTo(expected) != 0) { + System.out.println("freq answer "+result); + printbuffer(buf); + return false; + } + + if(serialPort.syncWrite(SYNC_ECHO_OFF,500) != SYNC_ECHO_OFF.length) { + System.out.println("Sync Echo Off write"); + return false; + } + + clearBuffer(SYNC_ECHO_OFF.length); + buf = new byte[3]; + serialPort.syncRead(buf,500); + + return true; + + + + } + + private void printbuffer(byte[] buffer){ + for(int i = 0; i < buffer.length; i++){ + System.out.println(String.format("%02x",buffer[i])); + } + } + + private void clearBuffer(int size){ + if(serialPort == null) + return; + + byte[] buf = new byte[size]; + int cpt=0; + do{ + int nb = serialPort.syncRead(buf,500); + System.out.println(String.format("%02x",buf[0])); + break;/* + if(nb < 0){ + cpt++; + if(cpt >=100) { + System.out.println("timeout"); + break; + } + } else if( nb == 0){ + System.out.println("nb = 0"); + return; + }*/ + }while(buf[0] == '\r' && buf[0] != '\n'); + + if(buf[0] == '\r') { + serialPort.syncRead(buf, 5); + System.out.println(String.format("%02x", buf[0])); + } + System.out.println("end"); + } + + public String[] readUid(){ + if(serialPort == null) + return null; + byte[] buf = new byte[REP_BUF]; + int ret = sendCommand(READ_UID,null); + if(ret != 0){ + System.out.println("Send Command "+ret); + return null; + } + int size = serialPort.syncRead(buf,1); + if(size<=0){ + System.out.println("Send size "+size); + return null; + } + String[] uids = new String[4]; + for(int i = 0; i < 4; i++){ + uids[0] = Long.toHexString(byteArrayToLong(buf,8*i+i*2)); + } + System.out.println("uids ok"); + return uids; + } + + public String readPartId(){ + return null; + } + + public String[] readBootVersion(){ + return null; + } + + public int sendCommand(byte[] cmd, String[] args){ + byte[] buf = new byte[3]; + if(serialPort.syncWrite(cmd,15) != cmd.length) + return -5; + int len = serialPort.syncRead(buf, 15); + System.out.println("Len "+len); + for(int i = 0; i < 3; i++){ + System.out.println(String.format("%02x", buf[i])); + } + if(len <= 0) + return -4; + int ret = parseRetCode(buf); + return ret; + } + + private int parseRetCode(byte[] data){ + String str = new String(data); + str = str.replace("\r\n",""); + + int ret = Integer.parseInt(str); + //int ret = byteArrayToInt(data,0); + return ret; + } + + private int byteArrayToInt(byte[] array, int offset){ + int value = 0; + value |= (array[offset] & 0xff) << 24; + value |= (array[offset+1] & 0xff) << 16; + value |= (array[offset+2] & 0xff) << 8; + value |= (array[offset+3] & 0xff); + return value; + } + + private long byteArrayToLong(byte[] array, int offset){ + long value = 0; + value |= (array[offset] & 0xff) << 56; + value |= (array[offset+1] & 0xff) << 48; + value |= (array[offset+2] & 0xff) << 40; + value |= (array[offset+3] & 0xff) << 32; + value |= (array[offset+4] & 0xff) << 24; + value |= (array[offset+5] & 0xff) << 16; + value |= (array[offset+6] & 0xff) << 8; + value |= (array[offset+7] & 0xff); + return value; + } +} + diff --git a/app/src/UsbComm.java b/app/src/UsbComm.java new file mode 100644 index 0000000..83068a7 --- /dev/null +++ b/app/src/UsbComm.java @@ -0,0 +1,80 @@ +package fr.mobdev.lpcprog; + +import android.app.Activity; +import android.app.PendingIntent; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.hardware.usb.UsbDevice; +import android.hardware.usb.UsbDeviceConnection; +import android.hardware.usb.UsbManager; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class UsbComm { + private static final String ACTION_USB_PERMISSION = "fr.mobdev.usb_perm"; + private UsbManager manager = null; + private UsbDeviceConnection connection = null; + private static int val = 0; + private UsbDevice device = null; + + public UsbComm(Context context){ + manager = (UsbManager) context.getSystemService(Context.USB_SERVICE); + } + + public boolean searchForDevice(){ + HashMap usbDevices = manager.getDeviceList(); + if(!usbDevices.isEmpty()) { + for (Map.Entry entry : usbDevices.entrySet()) { + UsbDevice device = entry.getValue(); + int deviceVID = device.getVendorId(); + int devicePID = device.getProductId(); + if (deviceVID != 0x1d6b && devicePID != 0x0001 && devicePID != 0x0002 && devicePID != 0x0003) { + return true; + } + } + } + return false; + } + + public List getDevices(){ + List devices = new ArrayList<>(); + HashMap usbDevices = manager.getDeviceList(); + if(!usbDevices.isEmpty()) { + for (Map.Entry entry : usbDevices.entrySet()) { + UsbDevice device = entry.getValue(); + int deviceVID = device.getVendorId(); + int devicePID = device.getProductId(); + if (deviceVID != 0x1d6b && devicePID != 0x0001 && devicePID != 0x0002 && devicePID != 0x0003) { + devices.add(device); + } + } + } + return devices; + } + + public boolean askForPermission(UsbDevice device, Activity activity){ + if(!manager.hasPermission(device)) { + PendingIntent intent = PendingIntent.getBroadcast(activity, 0, new Intent(ACTION_USB_PERMISSION), 0); + manager.requestPermission(device, intent); + return false; + } + return true; + } + + public UsbDeviceConnection openConnection(UsbDevice device, Activity activity){ + if(!manager.hasPermission(device)) { + askForPermission(device, activity); + return null; + } + if(connection == null || this.device != device) { + connection = manager.openDevice(device); + this.device = device; + } + return connection; + } +} + diff --git a/app/src/androidTest/java/fr/mobdev/lpcprog/ApplicationTest.java b/app/src/androidTest/java/fr/mobdev/lpcprog/ApplicationTest.java new file mode 100644 index 0000000..724b8dd --- /dev/null +++ b/app/src/androidTest/java/fr/mobdev/lpcprog/ApplicationTest.java @@ -0,0 +1,13 @@ +package fr.mobdev.lpcprog; + +import android.app.Application; +import android.test.ApplicationTestCase; + +/** + * Testing Fundamentals + */ +public class ApplicationTest extends ApplicationTestCase { + public ApplicationTest() { + super(Application.class); + } +} \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..6905d37 --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/fr/mobdev/lpcprog/DeviceActivity.java b/app/src/main/java/fr/mobdev/lpcprog/DeviceActivity.java new file mode 100644 index 0000000..3813356 --- /dev/null +++ b/app/src/main/java/fr/mobdev/lpcprog/DeviceActivity.java @@ -0,0 +1,92 @@ +package fr.mobdev.lpcprog; + +import android.support.v7.app.AppCompatActivity; +import android.os.Bundle; +import android.widget.TextView; + +import java.util.List; + +public class DeviceActivity extends AppCompatActivity { + + private UsbComm comm; + private USBDevice dev; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.device); + comm = UsbComm.getInstance(this); + List devices = comm.getDevices(); + int pid = getIntent().getIntExtra("PID",-1); + int vid = getIntent().getIntExtra("VID",-1); + for(USBDevice device : devices){ + if(device.PID == pid && device.VID == vid){ + dev = device; + System.out.println("device found"); + break; + } + } + if(dev != null) { + TextView name = (TextView) findViewById(R.id.name); + name.setText("Name: " + dev.description); + TextView vendor = (TextView) findViewById(R.id.vendor_id); + vendor.setText(String.format("Vendor Id: %04x", dev.VID)); + TextView product = (TextView) findViewById(R.id.id); + product.setText(String.format("Product id: %04x", dev.PID)); + } + doUsb(); + } + + private void doUsb(){ + System.out.println("doUsb"); + new Thread(new Runnable() { + @Override + public void run() { + boolean conn = comm.openConnection(dev); + IspManager manager = IspManager.getInstance(); + String uidStr = "No UID Found or error"; + String bootStr = "No Boot Version Found or error"; + String partidStr = "No Part ID Found or error"; + if(conn && manager.setupDevice(dev, 115200)) { + if(!manager.synchronizeIfPossible(10000)) { + System.out.println("Sync failed :("); + return; + } + String[] version = manager.readBootVersion(); + String partid = manager.readPartId(); + String[] uids = manager.readUid(); + if (uids != null) { + uidStr = String.format("UID: %08x - %08x - %08x - %08x",Long.parseLong(uids[0]), + Long.parseLong(uids[1]), + Long.parseLong(uids[2]), + Long.parseLong(uids[3])); + } + if (version != null) { + bootStr = "Boot Version: " + version[0] + "." + version[1]; + } + if(partid != null){ + partidStr = String.format("Part Id %08x",Long.parseLong(partid)); + } + } + updateIDS(uidStr,partidStr,bootStr); + + } + }).start(); + } + + private void updateIDS(final String uid, final String partid, final String boot) { + runOnUiThread(new Runnable() { + @Override + public void run() { + TextView view = (TextView) findViewById(R.id.uids); + view.setText(uid); + + view = (TextView) findViewById(R.id.part_id); + view.setText(partid); + + view = (TextView) findViewById(R.id.boot_version); + view.setText(boot); + } + }); + } +} diff --git a/app/src/main/java/fr/mobdev/lpcprog/DeviceAdapter.java b/app/src/main/java/fr/mobdev/lpcprog/DeviceAdapter.java new file mode 100644 index 0000000..6bc08d8 --- /dev/null +++ b/app/src/main/java/fr/mobdev/lpcprog/DeviceAdapter.java @@ -0,0 +1,55 @@ +package fr.mobdev.lpcprog; + +import android.hardware.usb.UsbDevice; +import android.hardware.usb.UsbDeviceConnection; +import android.os.Build; +import android.support.v7.widget.RecyclerView; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.TextView; + +import java.util.List; + +public class DeviceAdapter extends RecyclerView.Adapter { + + private List devices; + public DeviceAdapter(List devices){ + this.devices = devices; + } + + @Override + public DeviceHolder onCreateViewHolder(ViewGroup parent, int viewType) { + View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.device_item,parent,false); + return new DeviceHolder(view); + } + + @Override + public void onBindViewHolder(DeviceHolder holder, int position) { + holder.setupDevice(devices.get(position)); + } + + @Override + public int getItemCount() { + return devices.size(); + } +} + +class DeviceHolder extends RecyclerView.ViewHolder { + + + public DeviceHolder(View itemView) { + super(itemView); + } + + public void setupDevice(USBDevice device){ + TextView name = (TextView) itemView.findViewById(R.id.device_name); + name.setText("Name: " + device.description); + TextView vendor = (TextView) itemView.findViewById(R.id.device_vendor_id); + vendor.setText(String.format("Vendor Id: %04x",device.VID)); + TextView product = (TextView) itemView.findViewById(R.id.device_id); + product.setText(String.format("Product id: %04x", device.PID)); + + } + +} diff --git a/app/src/main/java/fr/mobdev/lpcprog/IspManager.java b/app/src/main/java/fr/mobdev/lpcprog/IspManager.java new file mode 100644 index 0000000..dbf2bb9 --- /dev/null +++ b/app/src/main/java/fr/mobdev/lpcprog/IspManager.java @@ -0,0 +1,316 @@ +package fr.mobdev.lpcprog; + +import com.ftdi.j2xx.D2xxManager; +import com.ftdi.j2xx.FT_Device; + +import java.nio.ByteBuffer; +import java.util.Locale; + +public class IspManager { + + //defines + private static final int REP_BUF = 100; + private static final byte[] SYNC_START = "?".getBytes(); + private static final byte[] SYNC = "Synchronized\r\n".getBytes(); + private static final byte[] SYNC_OK = "OK\r\n".getBytes(); + private static final byte[] DATA_BLOCK = "OK\r\n".getBytes(); + private static final byte[] DATA_BLOCK_RESEND = "RESEND\r\n".getBytes(); + private static final byte[] SYNC_ECHO_OFF = "A 0\r\n".getBytes(); + private static final byte[] READ_UID = "N\r\n".getBytes(); + private static final byte[] READ_PART_ID = "J\r\n".getBytes(); + private static final byte[] READ_BOOT_VERSION = "K\r\n".getBytes(); + + //members + private static IspManager instance = null; + private FT_Device serialPort = null; + + private IspManager(){ + + } + + public static IspManager getInstance(){ + if(instance == null) + instance = new IspManager(); + return instance; + } + + public boolean setupDevice(USBDevice device, int baudRate){ + serialPort = device.device; + if(serialPort != null) + serialPort.resetDevice(); + else + System.out.println("device is null fuck"); + + if(serialPort!=null && serialPort.isOpen()){ + serialPort.setBaudRate(baudRate); + byte dc1=0x11; + byte dc3=0x13; + serialPort.setFlowControl(D2xxManager.FT_FLOW_XON_XOFF,dc1,dc3); + serialPort.setDataCharacteristics(D2xxManager.FT_DATA_BITS_8,D2xxManager.FT_STOP_BITS_1,D2xxManager.FT_PARITY_NONE); + byte l = 0x2; + serialPort.setLatencyTimer(l); + return true; + } + return false; + } + + public boolean synchronize(int crystal_freq){ + if(serialPort == null) + return false; + serialPort.purge(D2xxManager.FT_PURGE_RX); + serialPort.purge(D2xxManager.FT_PURGE_TX); + byte[] buf; + if(serialPort.write(SYNC_START) != SYNC_START.length){ + System.out.println("Start"); + return false; + } + + buf = new byte[SYNC.length]; + serialPort.read(buf,buf.length,500); + String result = new String(buf); + String expected = new String(SYNC); + if(result.compareTo(expected) != 0) { + printbuffer(buf); + serialPort.write("\r\n".getBytes()); + System.out.println("Start answer "+result); + return false; + } + if(serialPort.write(SYNC) != SYNC.length) { + System.out.println("SYNC write"); + return false; + } + clearBuffer(SYNC.length); + buf = new byte[SYNC_OK.length]; + serialPort.read(buf,buf.length,500); + result = new String(buf); + expected = new String(SYNC_OK); + if(result.compareTo(expected) != 0) { + printbuffer(buf); + System.out.println("SYNC OK "+result); + return false; + } + + String freq = String.valueOf(crystal_freq)+"\r\n"; + if(serialPort.write(freq.getBytes()) != freq.length()) { + System.out.println("freq write"); + return false; + } + + clearBuffer(freq.length()); + buf = new byte[SYNC_OK.length]; + serialPort.read(buf,buf.length,500); + result = new String(buf); + expected = new String(SYNC_OK); + if(result.compareTo(expected) != 0) { + System.out.println("freq answer "+result); + printbuffer(buf); + return false; + } + + if(serialPort.write(SYNC_ECHO_OFF) != SYNC_ECHO_OFF.length) { + System.out.println("Sync Echo Off write"); + return false; + } + + clearBuffer(SYNC_ECHO_OFF.length); + buf = new byte[3]; + int ret = serialPort.read(buf,buf.length,500); + System.out.println(String.format(Locale.getDefault(),"%d %02x %02x %02x",ret,buf[0],buf[1],buf[2])); + return true; + + + + } + + private void printbuffer(byte[] buffer){ + for(byte b : buffer){ + System.out.println(String.format("%02x",b)); + } + } + + private void clearBuffer(int size){ + if(serialPort == null) + return; + + byte[] buf = new byte[size]; + int readed = read(buf,size,500); + System.out.println("end "+(size-readed)); + } + + public String[] readUid(){ + if(serialPort == null) + return null; + int ret = sendCommand(READ_UID,null); + + if(ret != 0){ + System.out.println("Send Command "+ret); + return null; + } + + byte[] buf = new byte[REP_BUF]; + + int size = read(buf,50,500); + for(int i = 0; i < size; i++){ + System.out.println(String.format("%02x", buf[i])); + } + if(size<=0){ + System.out.println("Send size "+size); + return null; + } + String[] uids = new String[4]; + String buffer = new String(buf); + + if(buffer.contains("\r") && buffer.contains("\n")) + buffer = buffer.replace("\n",""); + else if(!buffer.contains("\r") && buffer.contains("\n")) + buffer = buffer.replace("\n","\r"); + + for(int i = 0; i < 4; i++){ + if(buffer.contains("\r")) { + uids[i] = buffer.substring(0, buffer.indexOf("\r")); + buffer = buffer.substring(buffer.indexOf("\r")+1); + } + } + System.out.println("uids ok"); + return uids; + } + + public String readPartId(){ + if(serialPort == null) + return null; + int ret = sendCommand(READ_PART_ID,null); + if(ret != 0) + return null; + byte[] buf = new byte[REP_BUF]; + int size = read(buf,20,500); + if(size <= 0) + return null; + String partId = new String(buf); + partId = partId.substring(0,partId.indexOf("\r\n")); + if(partId.contains("\r")) + partId = partId.replace("\r",""); + if(partId.contains("\n")) + partId = partId.replace("\n",""); + return partId; + } + + public String[] readBootVersion(){ + if(serialPort == null) + return null; + int ret = sendCommand(READ_BOOT_VERSION,null); + if(ret != 0){ + System.out.println("Send Command "+ret); + return null; + } + byte[] buf = new byte[REP_BUF]; + + int size = read(buf,50,500); + + if(size <= 0){ + System.out.println("Receive "+size); + return null; + } + String[] version = new String[2]; + String buffer = new String(buf); + + if(buffer.contains("\r") && buffer.contains("\n")) + buffer = buffer.replace("\n",""); + else if(!buffer.contains("\r") && buffer.contains("\n")) + buffer = buffer.replace("\n","\r"); + + for(int i = 0; i < 2; i++){ + if(buffer.contains("\r")) { + version[i] = buffer.substring(0, buffer.indexOf("\r")); + buffer = buffer.substring(buffer.indexOf("\r")+1); + } + } + + + return version; + } + + public int sendCommand(byte[] cmd, String[] args){ + byte[] buf = new byte[3]; + if(serialPort.write(cmd) != cmd.length) + return -5; + int len = read(buf, buf.length,500); + System.out.println("Len "+len); + for(int i = 0; i < 3; i++){ + System.out.println(String.format("%02x", buf[i])); + } + if(len <= 0) + return -4; + return parseRetCode(buf); + } + + public int read(byte[] buffer, int size, int timeout){ + long startTime = System.nanoTime(); + long timeoutNano = timeout * 1000000; + int sizeRead = 0; + + ByteBuffer output = ByteBuffer.wrap(buffer,0,size); + + while(sizeRead < size){ + int sizeToRead = serialPort.getQueueStatus(); + if(sizeRead + sizeToRead > size) + sizeToRead = size - sizeRead; + byte[] buf = new byte[sizeToRead]; + if(sizeToRead > 0) { + int sizeReceived = serialPort.read(buf, sizeToRead, 50); + if (sizeReceived < 0) + return sizeReceived; + sizeRead += sizeReceived; + if (sizeReceived != 0) + output.put(buf, 0, sizeReceived); + } + long time = System.nanoTime(); + if(time - startTime >= timeoutNano) + break; + } + return sizeRead; + } + + private int parseRetCode(byte[] data){ + String str = new String(data); + str = str.replace("\r\n",""); + + return Integer.parseInt(str); + } + + public boolean synchronizeIfPossible(int crystal_freq) { + if(!synchronize(crystal_freq)) { + serialPort.purge(D2xxManager.FT_PURGE_TX); + serialPort.purge(D2xxManager.FT_PURGE_RX); + String[] uids = readUid(); + if (uids == null) { + System.out.println("uids null fuck"); + return false; + } + } + + return true; + } + + /*private int byteArrayToInt(byte[] array, int offset){ + int value = 0; + value |= (array[offset] & 0xff) << 24; + value |= (array[offset+1] & 0xff) << 16; + value |= (array[offset+2] & 0xff) << 8; + value |= (array[offset+3] & 0xff); + return value; + } + + private long byteArrayToLong(byte[] array, int offset){ + long value = 0; + value |= (array[offset] & 0xff) << 56; + value |= (array[offset+1] & 0xff) << 48; + value |= (array[offset+2] & 0xff) << 40; + value |= (array[offset+3] & 0xff) << 32; + value |= (array[offset+4] & 0xff) << 24; + value |= (array[offset+5] & 0xff) << 16; + value |= (array[offset+6] & 0xff) << 8; + value |= (array[offset+7] & 0xff); + return value; + }*/ +} + diff --git a/app/src/main/java/fr/mobdev/lpcprog/MainActivity.java b/app/src/main/java/fr/mobdev/lpcprog/MainActivity.java new file mode 100644 index 0000000..046c6f3 --- /dev/null +++ b/app/src/main/java/fr/mobdev/lpcprog/MainActivity.java @@ -0,0 +1,94 @@ +package fr.mobdev.lpcprog; + +import android.content.Intent; +import android.os.Bundle; +import android.support.v7.app.AppCompatActivity; +import android.support.v7.widget.LinearLayoutManager; +import android.support.v7.widget.RecyclerView; +import android.support.v7.widget.Toolbar; +import android.view.GestureDetector; +import android.view.Menu; +import android.view.MenuItem; +import android.view.MotionEvent; +import android.view.View; +import android.widget.Toast; + +import java.util.List; + +public class MainActivity extends AppCompatActivity { + + private UsbComm comm; + private List devices; + private int value = 0; + + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.main_activity); + Toolbar toolbar = (Toolbar) findViewById(R.id.main_toolbar); + setSupportActionBar(toolbar); + comm = UsbComm.getInstance(this); + + final GestureDetector gestureDetector = new GestureDetector(MainActivity.this, new GestureDetector.SimpleOnGestureListener(){ + @Override + public boolean onSingleTapUp(MotionEvent e){ + return true; + } + }); + + RecyclerView view = (RecyclerView) findViewById(R.id.device_list); + view.setLayoutManager(new LinearLayoutManager(this)); + view.addOnItemTouchListener(new RecyclerView.SimpleOnItemTouchListener() { + + @Override + public boolean onInterceptTouchEvent(RecyclerView view, MotionEvent e){ + View v = view.findChildViewUnder(e.getX(), e.getY()); + + if(v != null && gestureDetector.onTouchEvent(e)){ + int pos = view.getChildAdapterPosition(v); + System.out.println("touch "+ ++value); + onItemClick(pos); + return true; + } + return false; + } + }); + updateList(); + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + getMenuInflater().inflate(R.menu.menu_main, menu); + return true; + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + int id = item.getItemId(); + if (id == R.id.action_refresh) { + updateList(); + return true; + } + + return super.onOptionsItemSelected(item); + } + + private void updateList(){ + devices = comm.getDevices(); + DeviceAdapter adapter = new DeviceAdapter(devices); + RecyclerView view = (RecyclerView) findViewById(R.id.device_list); + view.setAdapter(adapter); + } + + + + private void onItemClick(final int pos){ + if(devices.size()>pos){ + Intent intent = new Intent(this,DeviceActivity.class); + intent.putExtra("PID",devices.get(pos).PID); + intent.putExtra("VID",devices.get(pos).VID); + startActivity(intent); + } + } +} diff --git a/app/src/main/java/fr/mobdev/lpcprog/USBDevice.java b/app/src/main/java/fr/mobdev/lpcprog/USBDevice.java new file mode 100644 index 0000000..6a7627b --- /dev/null +++ b/app/src/main/java/fr/mobdev/lpcprog/USBDevice.java @@ -0,0 +1,10 @@ +package fr.mobdev.lpcprog; + +import com.ftdi.j2xx.FT_Device; + +public class USBDevice { + public int PID; + public int VID; + public String description; + public FT_Device device; +} diff --git a/app/src/main/java/fr/mobdev/lpcprog/UsbComm.java b/app/src/main/java/fr/mobdev/lpcprog/UsbComm.java new file mode 100644 index 0000000..84e1b75 --- /dev/null +++ b/app/src/main/java/fr/mobdev/lpcprog/UsbComm.java @@ -0,0 +1,89 @@ +package fr.mobdev.lpcprog; + +import android.content.Context; + +import com.ftdi.j2xx.D2xxManager; + +import java.util.ArrayList; +import java.util.List; + +public class UsbComm { + + private static UsbComm instance = null; + + private D2xxManager manager = null; + private Context context; + List openedDevices; + + + private UsbComm(Context context){ + openedDevices = new ArrayList<>(); + try { + manager = D2xxManager.getInstance(context); + this.context = context; + } catch (D2xxManager.D2xxException e) { + e.printStackTrace(); + } + } + + public static UsbComm getInstance(Context context){ + if(instance == null) + instance = new UsbComm(context); + return instance; + } + + public List getDevices(){ + if(manager == null) + return null; + + List devicesList = new ArrayList<>(); + int deviceCount = manager.createDeviceInfoList(context); + if(deviceCount > 0) { + D2xxManager.FtDeviceInfoListNode[] devices = new D2xxManager.FtDeviceInfoListNode[deviceCount]; + manager.getDeviceInfoList(deviceCount, devices); + for (int i = 0; i < deviceCount; i++) { + int deviceVID = devices[i].id >> 16; + int devicePID = devices[i].id & 0xFFFF; + if (deviceVID != 0x1d6b && devicePID != 0x0001 && devicePID != 0x0002 && devicePID != 0x0003) { + USBDevice device = new USBDevice(); + device.VID = deviceVID; + device.PID = devicePID; + device.description = devices[i].description; + devicesList.add(device); + } + } + } + return devicesList; + } + + public boolean openConnection(USBDevice device) { + if(manager == null) + return false; + int deviceCount = manager.createDeviceInfoList(context); + if (deviceCount > 0) { + D2xxManager.FtDeviceInfoListNode[] devices = new D2xxManager.FtDeviceInfoListNode[deviceCount]; + manager.getDeviceInfoList(deviceCount,devices); + for (USBDevice dev : openedDevices) { + if(dev.PID == device.PID && dev.VID == device.VID && dev.device.isOpen()){ + device.device = dev.device; + return true; + } + else if(dev.PID == device.PID && dev.VID == device.VID && !dev.device.isOpen()){ + openedDevices.remove(dev); + } + } + for (int i = 0; i < deviceCount; i++) { + int deviceVID = devices[i].id >> 16; + int devicePID = devices[i].id & 0xFFFF; + if (deviceVID == device.VID && devicePID == device.PID) { + device.device = manager.openByIndex(context,i); + if(device.device != null) + openedDevices.add(device); + return true; + } + } + } + return false; + } +} + diff --git a/app/src/main/libs/d2xx.jar b/app/src/main/libs/d2xx.jar new file mode 100644 index 0000000..760233d Binary files /dev/null and b/app/src/main/libs/d2xx.jar differ diff --git a/app/src/main/res/drawable-hdpi/ic_refresh.png b/app/src/main/res/drawable-hdpi/ic_refresh.png new file mode 100644 index 0000000..42d5b05 Binary files /dev/null and b/app/src/main/res/drawable-hdpi/ic_refresh.png differ diff --git a/app/src/main/res/drawable-mdpi/ic_refresh.png b/app/src/main/res/drawable-mdpi/ic_refresh.png new file mode 100644 index 0000000..91dc808 Binary files /dev/null and b/app/src/main/res/drawable-mdpi/ic_refresh.png differ diff --git a/app/src/main/res/drawable-xhdpi/ic_refresh.png b/app/src/main/res/drawable-xhdpi/ic_refresh.png new file mode 100644 index 0000000..6c7e08e Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/ic_refresh.png differ diff --git a/app/src/main/res/drawable-xxhdpi/ic_refresh.png b/app/src/main/res/drawable-xxhdpi/ic_refresh.png new file mode 100644 index 0000000..6765923 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_refresh.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/ic_refresh.png b/app/src/main/res/drawable-xxxhdpi/ic_refresh.png new file mode 100644 index 0000000..55a0899 Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/ic_refresh.png differ diff --git a/app/src/main/res/ic_cached_white_24dp/android/drawable-hdpi/ic_cached_white_24dp.png b/app/src/main/res/ic_cached_white_24dp/android/drawable-hdpi/ic_cached_white_24dp.png new file mode 100644 index 0000000..42d5b05 Binary files /dev/null and b/app/src/main/res/ic_cached_white_24dp/android/drawable-hdpi/ic_cached_white_24dp.png differ diff --git a/app/src/main/res/ic_cached_white_24dp/android/drawable-mdpi/ic_cached_white_24dp.png b/app/src/main/res/ic_cached_white_24dp/android/drawable-mdpi/ic_cached_white_24dp.png new file mode 100644 index 0000000..91dc808 Binary files /dev/null and b/app/src/main/res/ic_cached_white_24dp/android/drawable-mdpi/ic_cached_white_24dp.png differ diff --git a/app/src/main/res/ic_cached_white_24dp/android/drawable-xhdpi/ic_cached_white_24dp.png b/app/src/main/res/ic_cached_white_24dp/android/drawable-xhdpi/ic_cached_white_24dp.png new file mode 100644 index 0000000..6c7e08e Binary files /dev/null and b/app/src/main/res/ic_cached_white_24dp/android/drawable-xhdpi/ic_cached_white_24dp.png differ diff --git a/app/src/main/res/ic_cached_white_24dp/android/drawable-xxhdpi/ic_cached_white_24dp.png b/app/src/main/res/ic_cached_white_24dp/android/drawable-xxhdpi/ic_cached_white_24dp.png new file mode 100644 index 0000000..6765923 Binary files /dev/null and b/app/src/main/res/ic_cached_white_24dp/android/drawable-xxhdpi/ic_cached_white_24dp.png differ diff --git a/app/src/main/res/ic_cached_white_24dp/android/drawable-xxxhdpi/ic_cached_white_24dp.png b/app/src/main/res/ic_cached_white_24dp/android/drawable-xxxhdpi/ic_cached_white_24dp.png new file mode 100644 index 0000000..55a0899 Binary files /dev/null and b/app/src/main/res/ic_cached_white_24dp/android/drawable-xxxhdpi/ic_cached_white_24dp.png differ diff --git a/app/src/main/res/ic_cached_white_24dp/ios/ic_cached_white.imageset/Contents.json b/app/src/main/res/ic_cached_white_24dp/ios/ic_cached_white.imageset/Contents.json new file mode 100644 index 0000000..191d08f --- /dev/null +++ b/app/src/main/res/ic_cached_white_24dp/ios/ic_cached_white.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images": [ + { + "filename": "ic_cached_white.png", + "idiom": "universal", + "scale": "1x" + }, + { + "filename": "ic_cached_white_2x.png", + "idiom": "universal", + "scale": "2x" + }, + { + "filename": "ic_cached_white_3x.png", + "idiom": "universal", + "scale": "3x" + } + ], + "info": { + "author": "xcode", + "version": 1 + } +} diff --git a/app/src/main/res/ic_cached_white_24dp/ios/ic_cached_white.imageset/ic_cached_white.png b/app/src/main/res/ic_cached_white_24dp/ios/ic_cached_white.imageset/ic_cached_white.png new file mode 100644 index 0000000..91dc808 Binary files /dev/null and b/app/src/main/res/ic_cached_white_24dp/ios/ic_cached_white.imageset/ic_cached_white.png differ diff --git a/app/src/main/res/ic_cached_white_24dp/ios/ic_cached_white.imageset/ic_cached_white_2x.png b/app/src/main/res/ic_cached_white_24dp/ios/ic_cached_white.imageset/ic_cached_white_2x.png new file mode 100644 index 0000000..6c7e08e Binary files /dev/null and b/app/src/main/res/ic_cached_white_24dp/ios/ic_cached_white.imageset/ic_cached_white_2x.png differ diff --git a/app/src/main/res/ic_cached_white_24dp/ios/ic_cached_white.imageset/ic_cached_white_3x.png b/app/src/main/res/ic_cached_white_24dp/ios/ic_cached_white.imageset/ic_cached_white_3x.png new file mode 100644 index 0000000..6765923 Binary files /dev/null and b/app/src/main/res/ic_cached_white_24dp/ios/ic_cached_white.imageset/ic_cached_white_3x.png differ diff --git a/app/src/main/res/ic_cached_white_24dp/web/ic_cached_white_24dp_1x.png b/app/src/main/res/ic_cached_white_24dp/web/ic_cached_white_24dp_1x.png new file mode 100644 index 0000000..91dc808 Binary files /dev/null and b/app/src/main/res/ic_cached_white_24dp/web/ic_cached_white_24dp_1x.png differ diff --git a/app/src/main/res/ic_cached_white_24dp/web/ic_cached_white_24dp_2x.png b/app/src/main/res/ic_cached_white_24dp/web/ic_cached_white_24dp_2x.png new file mode 100644 index 0000000..6c7e08e Binary files /dev/null and b/app/src/main/res/ic_cached_white_24dp/web/ic_cached_white_24dp_2x.png differ diff --git a/app/src/main/res/layout/device.xml b/app/src/main/res/layout/device.xml new file mode 100644 index 0000000..d2b46ea --- /dev/null +++ b/app/src/main/res/layout/device.xml @@ -0,0 +1,55 @@ + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/device_item.xml b/app/src/main/res/layout/device_item.xml new file mode 100644 index 0000000..2be5fe7 --- /dev/null +++ b/app/src/main/res/layout/device_item.xml @@ -0,0 +1,23 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/main_activity.xml b/app/src/main/res/layout/main_activity.xml new file mode 100644 index 0000000..398fecd --- /dev/null +++ b/app/src/main/res/layout/main_activity.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + + diff --git a/app/src/main/res/menu/menu_main.xml b/app/src/main/res/menu/menu_main.xml new file mode 100644 index 0000000..a477c7c --- /dev/null +++ b/app/src/main/res/menu/menu_main.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher.png b/app/src/main/res/mipmap-hdpi/ic_launcher.png new file mode 100644 index 0000000..cde69bc Binary files /dev/null and b/app/src/main/res/mipmap-hdpi/ic_launcher.png differ diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher.png b/app/src/main/res/mipmap-mdpi/ic_launcher.png new file mode 100644 index 0000000..c133a0c Binary files /dev/null and b/app/src/main/res/mipmap-mdpi/ic_launcher.png differ diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/app/src/main/res/mipmap-xhdpi/ic_launcher.png new file mode 100644 index 0000000..bfa42f0 Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/app/src/main/res/mipmap-xxhdpi/ic_launcher.png new file mode 100644 index 0000000..324e72c Binary files /dev/null and b/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ diff --git a/app/src/main/res/values-w820dp/dimens.xml b/app/src/main/res/values-w820dp/dimens.xml new file mode 100644 index 0000000..63fc816 --- /dev/null +++ b/app/src/main/res/values-w820dp/dimens.xml @@ -0,0 +1,6 @@ + + + 64dp + diff --git a/app/src/main/res/values/color.xml b/app/src/main/res/values/color.xml new file mode 100644 index 0000000..ba55cb6 --- /dev/null +++ b/app/src/main/res/values/color.xml @@ -0,0 +1,6 @@ + + + #000000 + #000000 + #FFFFFF + \ No newline at end of file diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml new file mode 100644 index 0000000..47c8224 --- /dev/null +++ b/app/src/main/res/values/dimens.xml @@ -0,0 +1,5 @@ + + + 16dp + 16dp + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml new file mode 100644 index 0000000..1447dd3 --- /dev/null +++ b/app/src/main/res/values/strings.xml @@ -0,0 +1,6 @@ + + LPCProg + + Hello world! + Refresh + diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml new file mode 100644 index 0000000..4409a68 --- /dev/null +++ b/app/src/main/res/values/styles.xml @@ -0,0 +1,18 @@ + + + + + + +