|
|
|
@ -1,54 +1,77 @@ |
|
|
|
|
package fr.mobdev.lpcprog.managers; |
|
|
|
|
|
|
|
|
|
import android.content.Context; |
|
|
|
|
|
|
|
|
|
import com.ftdi.j2xx.D2xxManager; |
|
|
|
|
import com.ftdi.j2xx.FT_Device; |
|
|
|
|
|
|
|
|
|
import java.io.File; |
|
|
|
|
import java.io.FileInputStream; |
|
|
|
|
import java.nio.ByteBuffer; |
|
|
|
|
import java.util.Locale; |
|
|
|
|
|
|
|
|
|
import fr.mobdev.lpcprog.R; |
|
|
|
|
import fr.mobdev.lpcprog.listener.FlashListener; |
|
|
|
|
import fr.mobdev.lpcprog.objects.Binary; |
|
|
|
|
import fr.mobdev.lpcprog.objects.Parts; |
|
|
|
|
import fr.mobdev.lpcprog.objects.Server; |
|
|
|
|
import fr.mobdev.lpcprog.objects.USBDevice; |
|
|
|
|
|
|
|
|
|
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 int SERIAL_BUF_SIZE = 1300; |
|
|
|
|
private static final int LINE_DATA_LENGTH = 45; |
|
|
|
|
private static final int LINES_PER_BLOCK = 20; |
|
|
|
|
private static final int MAX_DATA_BLOCK_SIZE = LINES_PER_BLOCK * LINE_DATA_LENGTH; |
|
|
|
|
private static final int UUENCODE_ADDED_VAL = 32; |
|
|
|
|
private static final int LINE_DATA_LENGTH_MAX = 45; |
|
|
|
|
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 = "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(); |
|
|
|
|
private static final byte[] UNLOCK = "U 23130\r\n".getBytes(); |
|
|
|
|
|
|
|
|
|
//members
|
|
|
|
|
private static IspManager instance = null; |
|
|
|
|
private FT_Device serialPort = null; |
|
|
|
|
private Context context; |
|
|
|
|
private long part_id = 0; |
|
|
|
|
|
|
|
|
|
private IspManager(){ |
|
|
|
|
|
|
|
|
|
private IspManager(Context context) { |
|
|
|
|
this.context = context; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
public static IspManager getInstance(){ |
|
|
|
|
if(instance == null) |
|
|
|
|
instance = new IspManager(); |
|
|
|
|
public static IspManager getInstance(Context context) { |
|
|
|
|
if (instance == null) |
|
|
|
|
instance = new IspManager(context); |
|
|
|
|
return instance; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
public boolean setupDevice(USBDevice device, int baudRate){ |
|
|
|
|
public void setPartId(long part){ |
|
|
|
|
part_id = part; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
public boolean setupDevice(USBDevice device, int baudRate) { |
|
|
|
|
serialPort = device.device; |
|
|
|
|
if(serialPort != null) |
|
|
|
|
if (serialPort != null) |
|
|
|
|
serialPort.resetDevice(); |
|
|
|
|
else |
|
|
|
|
System.out.println("device is null fuck"); |
|
|
|
|
|
|
|
|
|
if(serialPort!=null && serialPort.isOpen()){ |
|
|
|
|
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 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; |
|
|
|
@ -56,174 +79,164 @@ public class IspManager { |
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
public boolean synchronize(int crystal_freq){ |
|
|
|
|
if(serialPort == null) |
|
|
|
|
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){ |
|
|
|
|
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); |
|
|
|
|
serialPort.read(buf, buf.length, 500); |
|
|
|
|
String result = new String(buf); |
|
|
|
|
String expected = new String(SYNC); |
|
|
|
|
if(result.compareTo(expected) != 0) { |
|
|
|
|
printbuffer(buf); |
|
|
|
|
if (result.compareTo(expected) != 0) { |
|
|
|
|
serialPort.write("\r\n".getBytes()); |
|
|
|
|
System.out.println("Start answer "+result); |
|
|
|
|
System.out.println("Start answer " + result); |
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
if(serialPort.write(SYNC) != SYNC.length) { |
|
|
|
|
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); |
|
|
|
|
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); |
|
|
|
|
if (result.compareTo(expected) != 0) { |
|
|
|
|
System.out.println("SYNC OK " + result); |
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
String freq = String.valueOf(crystal_freq)+"\r\n"; |
|
|
|
|
if(serialPort.write(freq.getBytes()) != freq.length()) { |
|
|
|
|
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); |
|
|
|
|
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); |
|
|
|
|
if (result.compareTo(expected) != 0) { |
|
|
|
|
System.out.println("freq answer " + result); |
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if(serialPort.write(SYNC_ECHO_OFF) != SYNC_ECHO_OFF.length) { |
|
|
|
|
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])); |
|
|
|
|
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) |
|
|
|
|
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)); |
|
|
|
|
int readed = read(buf, size, 500); |
|
|
|
|
System.out.println("end " + (size - readed)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
public String[] readUid(){ |
|
|
|
|
if(serialPort == null) |
|
|
|
|
public String[] readUid() { |
|
|
|
|
if (serialPort == null) |
|
|
|
|
return null; |
|
|
|
|
int ret = sendCommand(READ_UID,null); |
|
|
|
|
int ret = sendCommand(READ_UID, null); |
|
|
|
|
|
|
|
|
|
if(ret != 0){ |
|
|
|
|
System.out.println("Send Command "+ret); |
|
|
|
|
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++){ |
|
|
|
|
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); |
|
|
|
|
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"); |
|
|
|
|
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")) { |
|
|
|
|
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); |
|
|
|
|
buffer = buffer.substring(buffer.indexOf("\r") + 1); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
System.out.println("uids ok"); |
|
|
|
|
return uids; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
public String readPartId(){ |
|
|
|
|
if(serialPort == null) |
|
|
|
|
public String readPartId() { |
|
|
|
|
if (serialPort == null) |
|
|
|
|
return null; |
|
|
|
|
int ret = sendCommand(READ_PART_ID,null); |
|
|
|
|
if(ret != 0) |
|
|
|
|
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) |
|
|
|
|
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",""); |
|
|
|
|
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) |
|
|
|
|
public String[] readBootVersion() { |
|
|
|
|
if (serialPort == null) |
|
|
|
|
return null; |
|
|
|
|
int ret = sendCommand(READ_BOOT_VERSION,null); |
|
|
|
|
if(ret != 0){ |
|
|
|
|
System.out.println("Send Command "+ret); |
|
|
|
|
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); |
|
|
|
|
int size = read(buf, 50, 500); |
|
|
|
|
|
|
|
|
|
if(size <= 0){ |
|
|
|
|
System.out.println("Receive "+size); |
|
|
|
|
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"); |
|
|
|
|
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")) { |
|
|
|
|
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); |
|
|
|
|
buffer = buffer.substring(buffer.indexOf("\r") + 1); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -231,33 +244,58 @@ public class IspManager { |
|
|
|
|
return version; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
public int sendCommand(byte[] cmd, String[] args){ |
|
|
|
|
private int sendCommand(byte[] cmd, String[] args) { |
|
|
|
|
if(args != null)//FIXME
|
|
|
|
|
return -1; |
|
|
|
|
byte[] buf = new byte[3]; |
|
|
|
|
if(serialPort.write(cmd) != cmd.length) |
|
|
|
|
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++){ |
|
|
|
|
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) |
|
|
|
|
if (len <= 0) |
|
|
|
|
return -4; |
|
|
|
|
return parseRetCode(buf); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
public int read(byte[] buffer, int size, int timeout){ |
|
|
|
|
private int sendCommand(byte[] cmd, char c, int addr, int count) { |
|
|
|
|
int ret = 0; |
|
|
|
|
int len = 0; |
|
|
|
|
|
|
|
|
|
byte[] buf = String.format(Locale.getDefault(),"%c %d %d\r\n",c,addr,count).getBytes(); |
|
|
|
|
len = buf.length; |
|
|
|
|
if(len > REP_BUF) { |
|
|
|
|
len = REP_BUF; |
|
|
|
|
} |
|
|
|
|
int sent = serialPort.write(buf,len); |
|
|
|
|
if(len != sent) { |
|
|
|
|
return -5; |
|
|
|
|
} |
|
|
|
|
buf = new byte[3]; |
|
|
|
|
len = read(buf,3,500); |
|
|
|
|
if(len <= 0) { |
|
|
|
|
return -4; |
|
|
|
|
} |
|
|
|
|
ret = parseRetCode(buf); |
|
|
|
|
|
|
|
|
|
return ret; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private 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); |
|
|
|
|
ByteBuffer output = ByteBuffer.wrap(buffer, 0, size); |
|
|
|
|
|
|
|
|
|
while(sizeRead < size){ |
|
|
|
|
while (sizeRead < size) { |
|
|
|
|
int sizeToRead = serialPort.getQueueStatus(); |
|
|
|
|
if(sizeRead + sizeToRead > size) |
|
|
|
|
if (sizeRead + sizeToRead > size) |
|
|
|
|
sizeToRead = size - sizeRead; |
|
|
|
|
byte[] buf = new byte[sizeToRead]; |
|
|
|
|
if(sizeToRead > 0) { |
|
|
|
|
if (sizeToRead > 0) { |
|
|
|
|
int sizeReceived = serialPort.read(buf, sizeToRead, 50); |
|
|
|
|
if (sizeReceived < 0) |
|
|
|
|
return sizeReceived; |
|
|
|
@ -266,21 +304,22 @@ public class IspManager { |
|
|
|
|
output.put(buf, 0, sizeReceived); |
|
|
|
|
} |
|
|
|
|
long time = System.nanoTime(); |
|
|
|
|
if(time - startTime >= timeoutNano) |
|
|
|
|
if (time - startTime >= timeoutNano) |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
return sizeRead; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private int parseRetCode(byte[] data){ |
|
|
|
|
private int parseRetCode(byte[] data) { |
|
|
|
|
String str = new String(data); |
|
|
|
|
str = str.replace("\r\n",""); |
|
|
|
|
|
|
|
|
|
str = str.replace("\r\n", ""); |
|
|
|
|
if (!str.matches("[0-9 -+]*")) |
|
|
|
|
return -1; |
|
|
|
|
return Integer.parseInt(str); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
public boolean synchronizeIfPossible(int crystal_freq) { |
|
|
|
|
if(!synchronize(crystal_freq)) { |
|
|
|
|
if (!synchronize(crystal_freq)) { |
|
|
|
|
serialPort.purge(D2xxManager.FT_PURGE_TX); |
|
|
|
|
serialPort.purge(D2xxManager.FT_PURGE_RX); |
|
|
|
|
String[] uids = readUid(); |
|
|
|
@ -293,26 +332,413 @@ public class IspManager { |
|
|
|
|
return true; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/*private int byteArrayToInt(byte[] array, int offset){ |
|
|
|
|
private int eraseFlash(Parts parts) { |
|
|
|
|
int ret = unlock(); |
|
|
|
|
if (ret != 0) { |
|
|
|
|
System.out.println("unlock fail"); |
|
|
|
|
return -1; |
|
|
|
|
} |
|
|
|
|
for (int i = 0; i < parts.flash_nb_sectors; i++) { |
|
|
|
|
//blank-check
|
|
|
|
|
ret = send_cmd_sectors('I', i, i); |
|
|
|
|
if (ret == 0) { |
|
|
|
|
continue; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (ret < 0) { |
|
|
|
|
System.out.println("blank "+i+" fail"); |
|
|
|
|
return ret; |
|
|
|
|
} else { |
|
|
|
|
byte buf[] = new byte[REP_BUF]; |
|
|
|
|
read(buf, 40, 500); |
|
|
|
|
} |
|
|
|
|
//prepare-for-write
|
|
|
|
|
ret = send_cmd_sectors('P', i, i); |
|
|
|
|
if (ret != 0) { |
|
|
|
|
System.out.println("prepare-for-write "+i+" fail"); |
|
|
|
|
return ret; |
|
|
|
|
} |
|
|
|
|
//erase
|
|
|
|
|
ret = send_cmd_sectors('E', i, i); |
|
|
|
|
if (ret != 0) { |
|
|
|
|
System.out.println("erase "+i+" fail"); |
|
|
|
|
return ret; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private int send_cmd_sectors(char cmd, int first_sector, int last_sector) { |
|
|
|
|
byte[] buf = new byte[3]; |
|
|
|
|
int ret; |
|
|
|
|
int len; |
|
|
|
|
|
|
|
|
|
if(last_sector < first_sector){ |
|
|
|
|
return -6; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
String request = String.format(Locale.getDefault(),"%c %d %d\r\n",cmd, first_sector, last_sector); |
|
|
|
|
len = serialPort.write(request.getBytes()); |
|
|
|
|
if(len != request.getBytes().length){ |
|
|
|
|
return -5; |
|
|
|
|
} |
|
|
|
|
len = read(buf,3,500); |
|
|
|
|
if(len <= 0){ |
|
|
|
|
return -4; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
ret = parseRetCode(buf); |
|
|
|
|
|
|
|
|
|
return ret; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private int unlock() { |
|
|
|
|
int ret = sendCommand(UNLOCK,null); |
|
|
|
|
if(ret != 0) |
|
|
|
|
return -1; |
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
public void flash(final Server server, final Binary binary, final FlashListener listener) { |
|
|
|
|
new Thread(new Runnable() { |
|
|
|
|
@Override |
|
|
|
|
public void run() { |
|
|
|
|
flashBinary(server,binary,listener); |
|
|
|
|
} |
|
|
|
|
}).start(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private int flashBinary(Server server, Binary binary, FlashListener listener) { |
|
|
|
|
Parts parts = DatabaseManager.getInstance(context).getParts(part_id); |
|
|
|
|
if(parts == null) { |
|
|
|
|
listener.onError(context.getString(R.string.parts_missing)); |
|
|
|
|
return -1; |
|
|
|
|
} |
|
|
|
|
int sector_size = parts.flash_size / parts.flash_nb_sectors; |
|
|
|
|
long ram_addr = parts.ram_base_addr + parts.ram_buffer_offset; |
|
|
|
|
boolean uuencode = parts.uuencode; |
|
|
|
|
byte data[]; |
|
|
|
|
|
|
|
|
|
//Sanity Checks
|
|
|
|
|
if (ram_addr > parts.ram_base_addr + parts.ram_size) { |
|
|
|
|
listener.onError(context.getString(R.string.buffer_out_ram)); |
|
|
|
|
return -2; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
long write_size = calcWriteSize(sector_size, parts.ram_buffer_size); |
|
|
|
|
if (write_size == 0) { |
|
|
|
|
listener.onError(context.getString(R.string.block_size_null)); |
|
|
|
|
return -3; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
int ret = eraseFlash(parts); |
|
|
|
|
if (ret != 0) { |
|
|
|
|
listener.onError(context.getString(R.string.cant_erase_flash)); |
|
|
|
|
return -4; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
data = new byte[parts.flash_size]; |
|
|
|
|
//copy file buffer to data array
|
|
|
|
|
File file = new File(context.getApplicationInfo().dataDir + "/" + server.id + "/" + binary.path + binary.filename); |
|
|
|
|
int size = copy_buffer(file, data, parts.flash_size); |
|
|
|
|
if (size <= 0) { |
|
|
|
|
System.out.println("Size " + size); |
|
|
|
|
listener.onError(context.getString(R.string.copy_file)); |
|
|
|
|
return -5; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
fill_data_with_0(data, size, parts.flash_size); |
|
|
|
|
int cksum = calc_binary_checksum(data); |
|
|
|
|
setChecksum(data, 28, cksum); |
|
|
|
|
if(!verifyChecksum(data,cksum)) { |
|
|
|
|
listener.onError(context.getString(R.string.checksum_failed)); |
|
|
|
|
return -6; |
|
|
|
|
} |
|
|
|
|
long blocks = (size / write_size) + ((size % write_size == 0) ? 0 : 1); |
|
|
|
|
if (blocks * write_size > parts.flash_size) { |
|
|
|
|
listener.onError(context.getString(R.string.flash_outside_end)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
for(int i = 0; i < blocks; i++){ |
|
|
|
|
int current_sector = (int)(i*write_size)/sector_size; |
|
|
|
|
int flash_addr = (int)(parts.flash_base_addr + (i*write_size)); |
|
|
|
|
//prepare-for-write
|
|
|
|
|
ret = send_cmd_sectors('P',current_sector,current_sector); |
|
|
|
|
if(ret != 0){ |
|
|
|
|
listener.onError(context.getString(R.string.prepare_write_error)+" "+i); |
|
|
|
|
return ret; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
ret = send_buf_to_ram(data,(int)(i*write_size),(int)ram_addr,(int)write_size, uuencode); |
|
|
|
|
if(ret != 0) { |
|
|
|
|
listener.onError(context.getString(R.string.write_ram_error)+" "+i); |
|
|
|
|
return ret; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
//write-to-ram
|
|
|
|
|
ret = send_cmd_address('C', flash_addr, (int)ram_addr, (int) write_size); |
|
|
|
|
if(ret != 0){ |
|
|
|
|
listener.onError(context.getString(R.string.copy_to_flash_error)+" "+i); |
|
|
|
|
return ret; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return ret; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private int send_cmd_address(char c, int flash_addr, int ram_addr, int write_size) { |
|
|
|
|
int ret; |
|
|
|
|
int len; |
|
|
|
|
byte[] buf = new byte[3]; |
|
|
|
|
String request = String.format(Locale.getDefault(),"%c %d %d %d\r\n",c,flash_addr,ram_addr,write_size); |
|
|
|
|
len = serialPort.write(request.getBytes()); |
|
|
|
|
if(len != request.getBytes().length){ |
|
|
|
|
System.out.println("cmd addr write"); |
|
|
|
|
return -5; |
|
|
|
|
} |
|
|
|
|
len = read(buf,3,500); |
|
|
|
|
if (len <= 0) { |
|
|
|
|
System.out.println("cmd addr read"); |
|
|
|
|
return -4; |
|
|
|
|
} |
|
|
|
|
ret = parseRetCode(buf); |
|
|
|
|
|
|
|
|
|
System.out.println("cmd addr ret "+ret); |
|
|
|
|
return ret; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private int send_buf_to_ram(byte[] data, int offset, int ram_addr, int write_size, boolean uuencode) { |
|
|
|
|
int ret; |
|
|
|
|
int len; |
|
|
|
|
int blocks; |
|
|
|
|
int total_sent =0; |
|
|
|
|
|
|
|
|
|
byte[] dataToSend = new byte[write_size]; |
|
|
|
|
System.arraycopy(data,offset,dataToSend,0,write_size); |
|
|
|
|
|
|
|
|
|
ret = sendCommand("write-to-ram".getBytes(),'W',ram_addr,write_size); |
|
|
|
|
if(ret != 0){ |
|
|
|
|
System.out.println("ask for write to ram"); |
|
|
|
|
return -8; |
|
|
|
|
} |
|
|
|
|
if(!uuencode) { |
|
|
|
|
len = serialPort.write(dataToSend); |
|
|
|
|
if(len != write_size){ |
|
|
|
|
return -7; |
|
|
|
|
} |
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
blocks = get_nb_blocks(write_size); |
|
|
|
|
|
|
|
|
|
int resend_requested_for_block = 0; |
|
|
|
|
for(int i = 0; i < blocks; i++){ |
|
|
|
|
byte[] buf = new byte[SERIAL_BUF_SIZE]; |
|
|
|
|
byte[] repbuf = new byte[REP_BUF]; |
|
|
|
|
int data_size; |
|
|
|
|
int encoded_size; |
|
|
|
|
int computed_checksum; |
|
|
|
|
data_size = (write_size - total_sent); |
|
|
|
|
if( data_size >= MAX_DATA_BLOCK_SIZE) |
|
|