package com.dev.fbs9600_mon; import java.io.BufferedReader; import java.io.ByteArrayInputStream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStreamReader; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.util.ArrayList; import java.util.zip.CRC32; import javax.swing.JOptionPane; import javax.swing.JTextArea; import main.page_debug_inf; import sp_comm.CommSerialPort; import sp_comm.SP_COMM; import com.ComFn; import com.Crc16; import com.Ecb_Aes; import com.PlaySound; public class SPCommMon_DFU { public static final short CMD_TYPE_READ = 0x03; public static final short CMD_TYPE_WRITE = 0x05; public static final byte BOOTLOADER_CMD_QUIT = 0; public static final byte BOOTLOADER_CMD_GETINF = 1; public static final byte BOOTLOADER_CMD_WRITE = 2; public static final byte BOOTLOADER_CMD_READ = 3; public static final int BOOTLOADER_BUF_LEN_128 = 128; public static final int BOOTLOADER_BUF_LEN_256 = 256; public static final int BOOTLOADER_BUF_LEN_1024 = 1024; private int BOOTLOADER_BUF_LEN = SPCommMon_DFU.BOOTLOADER_BUF_LEN_256; private ByteBuffer DFUCommRxBuffer = ByteBuffer.allocate(1248); private ByteBuffer DFUCommTxBuffer = ByteBuffer.allocate(1248); 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_read_check_en = false; private int dt_dfu_FirmVersion = 0; private int dt_multy_comm = CommSerialPort.mutycomm_Type_Samd09; private int m_DEV_TYPE = SPCommMon.DEV_TYPE_MON_SAMD09; private JTextArea dfu_inf = null; private page_debug_inf dt_debug_inf = null; //private SPCommMon m_SPComm = null; private SP_COMM m_COMM = null; private boolean dt_update_en = true; private boolean CommThread_EN = true; /* public SPCommMon_DFU(SPCommMon sp_comm) { m_SPComm = sp_comm; m_DEV_TYPE = m_SPComm.m_DEV_TYPE; dt_target_addr = m_SPComm.dt_target_addr; dt_multy_comm = m_SPComm.dt_multy_comm; dt_dfu_read_check_en = m_SPComm.dt_dfu_read_check_en; dfu_inf = m_SPComm.dt_show_dfu_inf; switch(m_DEV_TYPE) { case SPCommMon.DEV_TYPE_MON_SAMD09: BOOTLOADER_BUF_LEN = BOOTLOADER_BUF_LEN_256; break; case SPCommMon.DEV_TYPE_MON_MSP430: BOOTLOADER_BUF_LEN = BOOTLOADER_BUF_LEN_256; break; case SPCommMon.DEV_TYPE_MON_MSP430_RF: BOOTLOADER_BUF_LEN = BOOTLOADER_BUF_LEN_128; break; case SPCommMon.DEV_TYPE_MON_SWM: BOOTLOADER_BUF_LEN = BOOTLOADER_BUF_LEN_256; break; case SPCommMon.DEV_TYPE_NTM: BOOTLOADER_BUF_LEN = BOOTLOADER_BUF_LEN_1024; break; } DFUCommTxBuffer.order(ByteOrder.LITTLE_ENDIAN); DFUCommRxBuffer.order(ByteOrder.LITTLE_ENDIAN); } */ public SPCommMon_DFU(SP_COMM sp_comm, int dev_type, int tar_addr, boolean dfu_ck_en, JTextArea dfu_inf_t, page_debug_inf debug_inf) { m_COMM = sp_comm; m_DEV_TYPE = dev_type; dt_target_addr = tar_addr; dt_multy_comm = CommSerialPort.mutycomm_Type_Samd09; dt_dfu_read_check_en = dfu_ck_en; dfu_inf = dfu_inf_t; dt_debug_inf = debug_inf; switch(m_DEV_TYPE) { case SPCommMon.DEV_TYPE_MON_SAMD09: BOOTLOADER_BUF_LEN = BOOTLOADER_BUF_LEN_256; dt_multy_comm = CommSerialPort.mutycomm_Type_Samd09; break; case SPCommMon.DEV_TYPE_MON_MSP430: { BOOTLOADER_BUF_LEN = BOOTLOADER_BUF_LEN_256; dt_multy_comm = CommSerialPort.mutycomm_Type_Msp430; } break; case SPCommMon.DEV_TYPE_MON_MSP430_RF: { BOOTLOADER_BUF_LEN = BOOTLOADER_BUF_LEN_128; dt_multy_comm = CommSerialPort.mutycomm_Type_Msp430; } break; case SPCommMon.DEV_TYPE_MON_SWM: { BOOTLOADER_BUF_LEN = BOOTLOADER_BUF_LEN_256; dt_multy_comm = CommSerialPort.mutycomm_Type_SWM; } break; case SPCommMon.DEV_TYPE_NTM: BOOTLOADER_BUF_LEN = BOOTLOADER_BUF_LEN_1024; dt_multy_comm = CommSerialPort.mutycomm_Type_Samd09; break; } DFUCommTxBuffer.order(ByteOrder.LITTLE_ENDIAN); DFUCommRxBuffer.order(ByteOrder.LITTLE_ENDIAN); } public void setDFUCommState(boolean comm_en, boolean dfu_en) { CommThread_EN = comm_en; dt_update_en = dfu_en; } private ByteBuffer makeDfuBuf(ByteBuffer buf_t, byte cmd, int prog_addr, byte[] bt_data) { buf_t.order(ByteOrder.LITTLE_ENDIAN); buf_t.clear(); //---------------------------------------------------// //-------------- BOOTLOADER_CMD_GETINF --------------// if((CommSerialPort.mutycomm_Type_Msp430 == dt_multy_comm) || (CommSerialPort.mutycomm_Type_SWM == dt_multy_comm)) { buf_t.put((byte) dt_target_addr); for(int n=0; n<3; n++) { buf_t.put((byte) 0xAA); } } else { for(int n=0; n<3; n++) { buf_t.put((byte) 0xAA); } buf_t.put((byte) dt_target_addr); } buf_t.put(cmd); buf_t.put((byte) 0x00); if((SPCommMon.DEV_TYPE_MON_MSP430==m_DEV_TYPE) || (SPCommMon.DEV_TYPE_MON_MSP430_RF==m_DEV_TYPE)) { buf_t.putShort((short) prog_addr); } else { buf_t.putInt(prog_addr); } buf_t.putShort((short) 0); if(BOOTLOADER_CMD_WRITE == cmd) { //for(int n=0; n 0) { len += 1; } } dfu_text_inf += "DFU File CRC Check OK, File Inf: " + new String(buf_hd_inf, 0, len, "UTF-8") + "\n"; 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, int dfu_file_len) { 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 == dt_update_en) || (false == CommThread_EN)) { dfu_text_inf += "DFU Manual Stop . . .\n"; break; } //====================================// Thread.sleep(250); m_COMM.tr_Msg(makeDfuBuf(DFUCommTxBuffer, BOOTLOADER_CMD_GETINF, dfu_file_len, null), DFUCommRxBuffer, dt_multy_comm, dt_debug_inf, true); int ch_res = checkDfuBuf(DFUCommRxBuffer, BOOTLOADER_CMD_GETINF, 0); if(0 == ch_res) { break; } String text_t = " " + String.valueOf(ch_res); for(int n=0; n= 6) { dot_count = 0; } 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 == dt_update_en) { dfu_text_inf += "DFU_Version: " + Long.toHexString(dt_dfu_FirmVersion).toUpperCase() + "\n"; if(0x10010001<= dt_dfu_FirmVersion) { if(0x10010005 <= dt_dfu_FirmVersion) { if(false == dfu_text_inf.contains("FBS9600-DTS-March-DFU-0x10010005")) { dfu_text_inf += "Error!!!!! Target DFU Is March *.cim AppFile To Write!\n"; dt_update_en = false; } } else { if(true == dfu_text_inf.contains("FBS9600-DTS-March-DFU-0x10010005")) { dfu_text_inf += "Error!!!!! Target DFU Is March *.sam AppFile To Write!\n"; dt_update_en = false; } } if(0x1001000A == dt_dfu_FirmVersion) { BOOTLOADER_BUF_LEN = BOOTLOADER_BUF_LEN_128; } else { // BOOTLOADER_BUF_LEN = BOOTLOADER_BUF_LEN_256; } } } if(true == 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 al_dfu_data, ArrayList 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 == dt_update_en) || (false == CommThread_EN)) { 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++) { m_COMM.tr_Msg(makeDfuBuf(DFUCommTxBuffer, BOOTLOADER_CMD_WRITE, prog_addr, buf_to_flash), DFUCommRxBuffer, dt_multy_comm, dt_debug_inf, false); if(0 == checkDfuBuf(DFUCommRxBuffer, BOOTLOADER_CMD_WRITE, prog_addr)) { 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; } dfu_inf.setText(dfu_text_inf + String.format("DFU Write: %d%% Done.\n", percent)); } } if((true == dt_update_en) || (true == CommThread_EN)) { dfu_text_inf += "DFU Write: 100% Done!\n"; } dfu_inf.setText(dfu_text_inf); } catch (InterruptedException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } //---------------------------------------------------------------------------------// return prog_ok; //---------------------------------------------------------------------------------// } private boolean DFU_Read(ArrayList al_dfu_data, ArrayList al_dfu_addr, String dfu_text_inf_t) { String dfu_text_inf = dfu_text_inf_t; boolean check_res = false; int prog_addr = 0; int percent = 0; int dfu_dat_index = 0; try { while(dfu_dat_index < al_dfu_data.size()) { //====================================// if((false == dt_update_en) || (false == CommThread_EN)) { 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; //====================================// for(int cnt_t=0; cnt_t<3; cnt_t++) { m_COMM.tr_Msg(makeDfuBuf(DFUCommTxBuffer, BOOTLOADER_CMD_READ, prog_addr, null), DFUCommRxBuffer, dt_multy_comm, dt_debug_inf, false); if(0 == checkDfuBuf(DFUCommRxBuffer, BOOTLOADER_CMD_READ, prog_addr)) { check_res = true; break; } else { check_res = false; Thread.sleep(100); } } if(false == check_res) { break; } byte[] rx_data_check = new byte[BOOTLOADER_BUF_LEN]; if((SPCommMon.DEV_TYPE_MON_MSP430==m_DEV_TYPE) || (SPCommMon.DEV_TYPE_MON_MSP430_RF==m_DEV_TYPE)) { DFUCommRxBuffer.position(10); } else { DFUCommRxBuffer.position(12); } DFUCommRxBuffer.get(rx_data_check); for(int n=0; n 100) { percent = 100; } dfu_inf.setText(dfu_text_inf + String.format("DFU Verify: %d%% Done.\n", percent)); } if(false == check_res) { break; } } } catch (InterruptedException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } return check_res; } public boolean runDFU(String dt_update_file, String dfu_text_inf_t) { String dfu_text_inf = dfu_text_inf_t + "BOOTLOADER_BUF_LEN:" + BOOTLOADER_BUF_LEN + "\n"; //-------------------------- FILE CRC CHECK ---------------------------// ByteBuffer bbf_data = check_DFU_File(dt_update_file, dfu_text_inf); if(null == bbf_data) { return false; } dfu_text_inf = dfu_inf.getText(); //-------------------------- BOOTLOADER_CMD_GETINF ---------------------------// int f_len = 0; if(SPCommMon.DEV_TYPE_NTM == m_DEV_TYPE) { f_len = bbf_data.limit()-64; } dfu_text_inf = getAndCheckDFUInf(dfu_text_inf, f_len); //-----------------------------------------------------------------------------// ArrayList al_dfu_data = new ArrayList(); ArrayList al_dfu_addr = new ArrayList(); if((true == dt_update_en) && (true == CommThread_EN)) { if(dt_dfu_FirmVersion < 21410) { bbf_data.position(64); byte[] txt_bytes = new byte[bbf_data.limit()-64]; bbf_data.get(txt_bytes); long file_len = txt_bytes.length/3; dfu_text_inf = getMSP430BinCode(dt_dfu_FirmVersion, txt_bytes, file_len, dfu_text_inf, BOOTLOADER_BUF_LEN, al_dfu_data, al_dfu_addr); } else { 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 = dfu_inf.getText(); //------------------------------ BOOTLOADER_CMD_READ --------------------------// boolean check_res = prog_ok; if(true == check_res) { try { Thread.sleep(100); if(true == dt_dfu_read_check_en) { check_res = DFU_Read(al_dfu_data, al_dfu_addr, dfu_text_inf); } if((true == dt_update_en) && (true == CommThread_EN)) { if(true == check_res) { dfu_text_inf += "DFU Verify 100% Done.\n"; dfu_text_inf += "DFU Completed ~_~\n"; boolean restart_ck = false; for(int cnt_t=0; cnt_t<3; cnt_t++) { m_COMM.tr_Msg(makeDfuBuf(DFUCommTxBuffer, BOOTLOADER_CMD_QUIT, 0, null), DFUCommRxBuffer, dt_multy_comm, dt_debug_inf, false); if(0 == checkDfuBuf(DFUCommRxBuffer, BOOTLOADER_CMD_QUIT, 0)) { restart_ck = true; break; } else { Thread.sleep(100); } } if(true == restart_ck) { dfu_text_inf += "Restart Target Done.\n"; new PlaySound("6133.wav"); } else { dfu_text_inf += "Restart Target Faild...\n"; } } else { dfu_text_inf += "DFU Verify Failed !!!!!!!!!!!\n"; } } } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } al_dfu_data.clear(); al_dfu_addr.clear(); } return check_res; } /*********************************************************************************************/ String getBinCode(int dfu_ver, ByteBuffer bbf_data, long file_len, String dfu_text_inf_t, int dfu_buf_len, ArrayList al_dfu_data, ArrayList al_dfu_addr) { String dfu_text_inf = dfu_text_inf_t; int prog_addr = 0; int percent = 0; bbf_data.position(64); boolean bbf_is_end = false; while(!bbf_is_end) { byte[] buf_to_flash = new byte[dfu_buf_len]; for(int n=0; n 100) { percent = 100; } 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; } /*********************************************************************************************/ String getMSP430BinCode(int dfu_ver, byte[] txt_bytes, long file_len, String dfu_text_inf_t, int dfu_buf_len, ArrayList al_dfu_data, ArrayList al_dfu_addr) { String dfu_text_inf = dfu_text_inf_t; int BOOT_APP_ADDR = 0x9000;//0xD000; int BOOT_APPVECTOR_ADDR = 0xFBDC;//0xFDE0; String BOOT_APPVECTOR_tag = "@fb";//0xFDE0; String BOOT_APPVECTOR_tagfull = "@fbe0";//0xFDE0; try { int prog_addr = 0; int percent = 0; BufferedReader br = new BufferedReader(new InputStreamReader(new ByteArrayInputStream(txt_bytes))); boolean bbf_is_end = false; int data_addr = 0; while(!bbf_is_end) { int data_type = 0; int data_cnt = 0; byte[] buf_to_flash = new byte[dfu_buf_len]; for(int n=0; n= 2040) && ((dfu_ver/10) < 2141)) { BOOT_APPVECTOR_ADDR = 0xFBDC; BOOT_APPVECTOR_tag = "@fb"; BOOT_APPVECTOR_tagfull = "@fbdc"; } else { if(0xD000 == BOOT_APP_ADDR) { BOOT_APPVECTOR_ADDR = 0xFDE0; BOOT_APPVECTOR_tag = "@fd"; BOOT_APPVECTOR_tagfull = "@fde2"; } else { BOOT_APPVECTOR_ADDR = 0xFBDC; BOOT_APPVECTOR_tag = "@fb"; BOOT_APPVECTOR_tagfull = "@fbdc"; } } data_type = 0; data_addr = 0; continue; } if(line.contains(BOOT_APPVECTOR_tag)) { data_type = 1; data_cnt = 0; data_addr = Integer.parseInt(line.substring(1, line.length()), 16) - BOOT_APPVECTOR_ADDR; if(line.contains(BOOT_APPVECTOR_tagfull)) { break; } else { continue; } } byte[] dat = ComFn.hexStr2Byte(line); for(int n=0; n= dfu_buf_len) { break; } } else { prog_addr = BOOT_APPVECTOR_ADDR-BOOT_APP_ADDR; } } //-----------------------------------------------------------------------// al_dfu_data.add(buf_to_flash); al_dfu_addr.add(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; } dfu_inf.setText(dfu_text_inf + String.format("DFU data release: %d%% Done.\n", percent)); } //-----------------------------------------------------------------------// } dfu_text_inf += "DFU data release: 100% Done!\n"; dfu_inf.setText(dfu_text_inf); } catch (IOException e1) { // TODO Auto-generated catch block e1.printStackTrace(); dt_update_en = false; } //---------------------------------------------------------------------------------// return dfu_text_inf; } /*********************************************************************************************/ }