package com.dev.ntm.kw8;
|
import java.io.File;
|
import java.io.FileInputStream;
|
import java.io.IOException;
|
import java.nio.ByteBuffer;
|
import java.nio.ByteOrder;
|
import java.util.ArrayList;
|
|
import com.Crc16;
|
import com.dev.ntm.SPCommNTM;
|
|
public class SPComm8KW_DFU {
|
public static final byte CMD_TYPE_READ_03H = 0x03;
|
public static final byte CMD_TYPE_WRITE_10H = 0x10;
|
|
private static final short DFU_Data_REG_ADDR_8KW = (short) 0xF000;
|
private static final short DFU_Stat_REG_ADDR_8KW = (short) 0xFE00;
|
|
private static final short Stat_8KW_APP = (short) 0xAAAA;
|
//private static final short Stat_8KW_DFU = (short) 0xBBBB;
|
|
private static final int APP_START_ADDR_8KW = 0x08004000;
|
|
public static final int BOOTLOADER_BUF_LEN_128 = 128;
|
private int BOOTLOADER_BUF_LEN = SPComm8KW_DFU.BOOTLOADER_BUF_LEN_128;
|
|
private ByteBuffer DFUCommRxBuffer = ByteBuffer.allocate(1048);
|
private ByteBuffer DFUCommTxBuffer = ByteBuffer.allocate(1048);
|
|
public short comm_tx_cnt = 0;
|
public short comm_rx_cnt = 0;
|
|
public int dt_target_addr = 0;
|
public short dt_dfu_addr_start = 0;
|
public short dt_dfu_addr_end = 0;
|
private boolean dt_dfu_stat = false;
|
|
private int dt_dfu_FirmVersion = 0;
|
private SPCommNTM m_SPComm = null;
|
|
public SPComm8KW_DFU(SPCommNTM sp_comm) {
|
m_SPComm = sp_comm;
|
dt_target_addr = m_SPComm.dt_target_addr;
|
DFUCommTxBuffer.order(ByteOrder.LITTLE_ENDIAN);
|
DFUCommRxBuffer.order(ByteOrder.LITTLE_ENDIAN);
|
}
|
|
private ByteBuffer makeDfuBuf(ByteBuffer buf_t, byte dt_cmd, Short reg_addr, int prog_addr, byte[] bt_data) {
|
buf_t.order(ByteOrder.BIG_ENDIAN);
|
buf_t.clear();
|
//---------------------------------------------------//
|
if(CMD_TYPE_READ_03H == dt_cmd) {
|
buf_t.put((byte) dt_target_addr);
|
buf_t.put((byte) dt_cmd);
|
buf_t.putShort(reg_addr);;
|
buf_t.putShort((short) 1);
|
} else if(CMD_TYPE_WRITE_10H == dt_cmd){
|
buf_t.put((byte) dt_target_addr);
|
buf_t.put((byte) dt_cmd);
|
buf_t.putShort(reg_addr);
|
|
if(DFU_Data_REG_ADDR_8KW == reg_addr) {
|
int dat_len = bt_data.length + 4;
|
buf_t.putShort((short) (dat_len/2));
|
buf_t.put((byte) dat_len);
|
buf_t.putInt(prog_addr);
|
buf_t.put(bt_data);
|
} else {
|
buf_t.putShort((short) 1);
|
buf_t.put((byte) 2);
|
buf_t.putShort((short) prog_addr);
|
}
|
|
dt_cmd = CMD_TYPE_READ_03H;
|
}
|
|
int crc = Crc16.CalCRC16(buf_t, buf_t.position()) & 0xFFFF;
|
buf_t.putShort((short) (crc>>8 | crc<<8));
|
buf_t.flip();
|
|
return buf_t;
|
}
|
|
private boolean checkDfuBuf(ByteBuffer buf_t, short reg_addr) {
|
boolean res = false;
|
if(buf_t.limit() > 5) {
|
buf_t.position(buf_t.limit()-2);
|
int crc = buf_t.getShort() & 0xFFFF;
|
crc = ((crc>>8) | (crc<<8)) & 0xFFFF;
|
int crc_cal = Crc16.CalCRC16(buf_t, buf_t.limit()-2) & 0xFFFF;
|
/*************************************************/
|
if(crc_cal == crc) {
|
if(DFU_Stat_REG_ADDR_8KW == reg_addr) {
|
dt_dfu_stat = (0xBBBB == buf_t.getShort(4));
|
}
|
|
res = true;
|
}
|
/*************************************************/
|
} else {
|
res = false;
|
}
|
|
return res;
|
}
|
|
private ByteBuffer check_DFU_File(String dfufile, String dfu_text_inf_t) {
|
String dfu_text_inf = dfu_text_inf_t;
|
File f = new File(dfufile);
|
long file_len_hd = f.length();
|
ByteBuffer bbf_data = ByteBuffer.allocate((int) file_len_hd);
|
try {
|
FileInputStream fis_hd = new FileInputStream(f);
|
byte[] buf_hd = new byte[(int) (file_len_hd)];
|
fis_hd.read(buf_hd);
|
fis_hd.close();
|
bbf_data.put(buf_hd);
|
|
dfu_text_inf += "DFU File CRC Check OK, File len: " + file_len_hd + "\n";
|
m_SPComm.dt_show_dfu_inf.setText(dfu_text_inf);
|
} catch (IOException e1) {
|
bbf_data.clear();
|
// TODO Auto-generated catch block
|
e1.printStackTrace();
|
return null;
|
}
|
|
return bbf_data;
|
}
|
|
private String getAndCheckDFUInf(String dfu_text_inf_t) {
|
String dfu_text_inf = dfu_text_inf_t;
|
//-------------------------- BOOTLOADER_CMD_GETINF ---------------------------//
|
try {
|
//System.out.println("dt_dfu_bitrate:" + dt_dfu_bitrate);
|
int dot_count = 0;
|
while(true) {
|
//====================================//
|
if((false == m_SPComm.dt_update_en) || (false == m_SPComm.CommThreadRunning)) {
|
dfu_text_inf += "DFU Manual Stop . . .\n";
|
break;
|
}
|
//====================================//
|
Thread.sleep(250);
|
makeDfuBuf(DFUCommTxBuffer, CMD_TYPE_READ_03H, DFU_Stat_REG_ADDR_8KW, 0, null);
|
m_SPComm.tr_Msg(DFUCommTxBuffer, DFUCommRxBuffer, true);
|
if(true == checkDfuBuf(DFUCommRxBuffer, DFU_Stat_REG_ADDR_8KW)) {
|
if(dt_dfu_stat == true) {
|
break;
|
}
|
}
|
String text_t = "";
|
for(int n=0; n<dot_count; n++) {
|
text_t += " .";
|
}
|
if(++dot_count >= 6) {
|
dot_count = 0;
|
}
|
|
m_SPComm.dt_show_dfu_inf.setText(dfu_text_inf + "Wait For Target DFU Ready" + text_t + "\n");
|
//System.out.println("DFURX:" + ComFn.bytesToHexString(DFUCommRxBuffer.array(), DFUCommRxBuffer.limit()) + "\n");
|
}
|
|
if(true == m_SPComm.dt_update_en) {
|
dfu_text_inf += "Target DFU Ready OK!\n";
|
}
|
} catch (InterruptedException e) {
|
// TODO Auto-generated catch block
|
e.printStackTrace();
|
}
|
//-----------------------------------------------------------------------------//
|
|
return dfu_text_inf;
|
}
|
|
private boolean DFU_Write(ArrayList<byte[]> al_dfu_data, ArrayList<Integer> al_dfu_addr, String dfu_text_inf_t) {
|
String dfu_text_inf = dfu_text_inf_t;
|
//--------------------------- BOOTLOADER_CMD_WRITE-----------------------------//
|
boolean prog_ok = false;
|
try {
|
Thread.sleep(100);
|
int prog_addr = 0;
|
int percent = 0;
|
int dfu_dat_index = 0;
|
while(dfu_dat_index < al_dfu_data.size()) {
|
//====================================//
|
if((false == m_SPComm.dt_update_en) || (false == m_SPComm.CommThreadRunning)) {
|
dfu_text_inf += "DFU Manual Stop . . .\n";
|
break;
|
}
|
//====================================//
|
byte[] buf_to_flash = al_dfu_data.get(dfu_dat_index);
|
prog_addr = al_dfu_addr.get(dfu_dat_index);
|
dfu_dat_index += 1;
|
//====================================//
|
//System.out.println(ComFn.bytesToHexString(buf_to_flash, BOOTLOADER_BUF_LEN) + "\n");
|
for(int cnt_t=0; cnt_t<5; cnt_t++) {
|
makeDfuBuf(DFUCommTxBuffer, CMD_TYPE_WRITE_10H, DFU_Data_REG_ADDR_8KW, prog_addr, buf_to_flash);
|
m_SPComm.tr_Msg(DFUCommTxBuffer, DFUCommRxBuffer, true);
|
if(true == checkDfuBuf(DFUCommRxBuffer, DFU_Data_REG_ADDR_8KW)) {
|
prog_ok = true;
|
break;
|
} else {
|
prog_ok = false;
|
Thread.sleep(100);
|
}
|
}
|
if(false == prog_ok) {
|
dfu_text_inf += "DFU Write Error!\n";
|
break;
|
}
|
|
if(percent < (dfu_dat_index*100)/al_dfu_data.size()) {
|
percent = (int) ((dfu_dat_index*100)/al_dfu_data.size());
|
if(percent > 100) {
|
percent = 100;
|
}
|
m_SPComm.dt_show_dfu_inf.setText(dfu_text_inf + String.format("DFU Write: %d%% Done.\n", percent));
|
}
|
}
|
dfu_text_inf += "DFU Write: 100% Done!\n";
|
m_SPComm.dt_show_dfu_inf.setText(dfu_text_inf);
|
|
dfu_text_inf += "Start App...\n";
|
m_SPComm.dt_show_dfu_inf.setText(dfu_text_inf);
|
makeDfuBuf(DFUCommTxBuffer, CMD_TYPE_WRITE_10H, DFU_Stat_REG_ADDR_8KW, Stat_8KW_APP, null);
|
m_SPComm.tr_Msg(DFUCommTxBuffer, DFUCommRxBuffer, true);
|
} catch (InterruptedException e1) {
|
// TODO Auto-generated catch block
|
e1.printStackTrace();
|
}
|
//---------------------------------------------------------------------------------//
|
return prog_ok;
|
//---------------------------------------------------------------------------------//
|
}
|
|
public boolean runDFU(String dt_update_file, String dfu_text_inf_t) {
|
String dfu_text_inf = dfu_text_inf_t;
|
//-------------------------- FILE CRC CHECK ---------------------------//
|
ByteBuffer bbf_data = check_DFU_File(dt_update_file, dfu_text_inf);
|
if(null == bbf_data) {
|
return false;
|
}
|
dfu_text_inf = m_SPComm.dt_show_dfu_inf.getText();
|
//-------------------------- BOOTLOADER_CMD_GETINF ---------------------------//
|
dfu_text_inf = getAndCheckDFUInf(dfu_text_inf);
|
//-----------------------------------------------------------------------------//
|
ArrayList<byte[]> al_dfu_data = new ArrayList<byte[]>();
|
ArrayList<Integer> al_dfu_addr = new ArrayList<Integer>();
|
if((true == m_SPComm.dt_update_en) && (true == m_SPComm.CommThreadRunning)) {
|
dfu_text_inf = getBinCode(dt_dfu_FirmVersion, bbf_data, bbf_data.capacity(), dfu_text_inf,
|
BOOTLOADER_BUF_LEN, al_dfu_data, al_dfu_addr);
|
}
|
//-----------------------------------------------------------------------------//
|
//--------------------------- BOOTLOADER_CMD_WRITE-----------------------------//
|
boolean prog_ok = DFU_Write(al_dfu_data, al_dfu_addr, dfu_text_inf);
|
dfu_text_inf = m_SPComm.dt_show_dfu_inf.getText();
|
//------------------------------ BOOTLOADER_CMD_READ --------------------------//
|
boolean check_res = prog_ok;
|
{
|
al_dfu_data.clear();
|
al_dfu_addr.clear();
|
}
|
|
m_SPComm.dt_update_en = false;
|
|
return check_res;
|
}
|
/*********************************************************************************************/
|
String getBinCode(int dfu_ver, ByteBuffer bbf_data, long file_len, String dfu_text_inf_t,
|
int dfu_buf_len, ArrayList<byte[]> al_dfu_data, ArrayList<Integer> al_dfu_addr) {
|
String dfu_text_inf = dfu_text_inf_t;
|
|
int prog_addr = 0;
|
int percent = 0;
|
bbf_data.position(0);
|
boolean bbf_is_end = false;
|
|
while(!bbf_is_end) {
|
byte[] buf_to_flash = new byte[BOOTLOADER_BUF_LEN];
|
|
for(int n=0; n<buf_to_flash.length; n++) {
|
buf_to_flash[n] = (byte) 0xFF;
|
if(bbf_data.hasRemaining()) {
|
buf_to_flash[n] = bbf_data.get();
|
} else {
|
bbf_is_end = true;
|
}
|
}
|
|
//System.out.println( ComFn.bytesToHexString(buf_to_flash, buf_to_flash.length) );
|
|
al_dfu_data.add(buf_to_flash);
|
al_dfu_addr.add(APP_START_ADDR_8KW + prog_addr);
|
prog_addr += dfu_buf_len;
|
|
if(percent < (prog_addr*100)/file_len) {
|
percent = (int) ((prog_addr*100)/file_len);
|
if(percent > 100) {
|
percent = 100;
|
}
|
m_SPComm.dt_show_dfu_inf.setText(dfu_text_inf + String.format("DFU data release: %d%% Done.\n", percent));
|
}
|
}
|
dfu_text_inf += "DFU data release: 100% Done!\n";
|
|
return dfu_text_inf;
|
}
|
/*********************************************************************************************/
|
/*********************************************************************************************/
|
}
|