package com.example.administrator.wingcool_gt9_apk;

import android.Manifest;
import android.app.Activity;
import android.app.PendingIntent;
import android.content.ContentUris;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.database.Cursor;
import android.hardware.usb.UsbConstants;
import android.hardware.usb.UsbDevice;
import android.hardware.usb.UsbDeviceConnection;
import android.hardware.usb.UsbEndpoint;
import android.hardware.usb.UsbInterface;
import android.hardware.usb.UsbManager;
import android.hardware.usb.UsbRequest;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.os.SystemClock;
import android.provider.DocumentsContract;
import android.provider.MediaStore;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.DisplayMetrics;
import android.view.Gravity;
import android.view.View;
import android.widget.Button;
import android.widget.CompoundButton;
import android.widget.EditText;
//import android.widget.RadioButton;
//import android.widget.RadioGroup;
import android.widget.TextView;
import android.widget.Toast;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.Reader;
import java.net.DatagramPacket;
import java.nio.ByteBuffer;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.Locale;
import java.util.Timer;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class FirmwareUpdate extends AppCompatActivity
        implements  OpenDevicesReceiver.OpenDevicesListener, View.OnClickListener{//,CompoundButton.OnCheckedChangeListener{

    private static final int CONNECTED_SUCCESS = 0;
    private static final int RECEIVER_MESSAGE_SUCCESS = 1;
    private static final int SEND_MESSAGE_SUCCESS = 2;
    private static final int DEBUG_MESSAGE_SUCCESS = 3;
    private static final int DEBUG_MESSAGE_ERROR = 4;
    private static final int UPDATE_FW= 5;

    private static final String USB_ACTION = "com.host2device";
    private static final String ACTION_USB_PERMISSION = "com.host2device.USB_PERMISSION";
    private ExecutorService mThreadPool;
    private UsbManager mUsbManager;
    private OpenDevicesReceiver fwOpenDevicesReceiver;
    private EditText mError;
    private UsbDeviceConnection mUsbDeviceConnection;

    private UsbEndpoint mUsbEndpointOut;
    private UsbEndpoint mUsbEndpointIn;
    private byte[] mBytes = new byte[1024];
    private byte[] mSendData = new byte[1024];
    private byte[] mConfigData = new byte[1024];
    private String[] mVersionShow = new String[16];
    byte[] mGt293xFirmwareData = new byte[400 * 1024];

    private boolean isReceiverMessage = true;
    private boolean isSendMessage = true;

    private boolean isNeedFindDevice  = true;

    private int bottonMode = 0;

    private UsbInterface mUsbInterface;
    private StringBuffer mStringBuffer = new StringBuffer();
    private Context mContext;
    private Button btnReadVersion;
    private TextView tvS8xxxxShow;
    private TextView tvGtxxxxShow;
    private TextView tvCfgVersionShow;
    private TextView tvUpDataResult;
    private int iProductId;
    private byte byProductType = 0;
    private static final byte GT9 = 0x01;
    private static final byte GT7 = 0x02;
    private static final byte GT29336 = 0x03;
    private static final byte GT2931 = 0x04;
    
    int FW_HEAD_LENGTH	=		14;
    int FW_SECTION_LENGTH	=	0x2000; 	/** 8K */
    int FW_DSP_ISP_LENGTH	=	0x1000;	/**  4K */
    int FW_DSP_LENGTH	=		0x1000;	/** 4K */
    int FW_BOOT_LENGTH	=		0x800;	/**  2K */
    int FW_SS51_LENGTH	=		(4 * FW_SECTION_LENGTH);	/**  32K */
    int FW_BOOT_ISP_LENGTH	=	0x800;	/**  2k */
    int FW_GLINK_LENGTH	=		0x3000;	/**  12k */
    int FW_GWAKE_LENGTH		=	(4 * FW_SECTION_LENGTH) ; /**  32k */

    int FW_HEAD_OFFSET   =       0;
    int FW_SS51_OFFSET	 =		(FW_HEAD_OFFSET + FW_HEAD_LENGTH);  //14
    int FW_DSP_OFFSET	=		(FW_SS51_OFFSET + FW_SS51_LENGTH);  //
    int FW_BOOT_OFFSET	=		(FW_DSP_OFFSET + FW_DSP_LENGTH);
    int FW_BOOT_ISP_OFFSET	=	(FW_BOOT_OFFSET + FW_BOOT_LENGTH);
    int FW_GLINK_OFFSET		=	(FW_BOOT_ISP_OFFSET + FW_BOOT_ISP_LENGTH);
    int FW_GWAKE_OFFSET		=	(FW_GLINK_OFFSET + FW_GLINK_LENGTH);
    int FW_DSP_ISP_OFFSET	=	(FW_GWAKE_OFFSET + FW_GWAKE_LENGTH);

    private byte mSendGetGt9VersionData[]={
        0x03,0x00,0x0f,(byte)0x81,0x40,0x00,0x06,0x00,
        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
    };

    //-------------------------------------------------------------------------------------------------------------------------------//
    byte TYPE_BERLIN_B = (byte)0x97;
    byte TYPE_BERLIN_D = (byte)0x98;  // 兼容GT9916 BerlinD
    byte SS51_ISP_CODE = 0x01;
    byte	SS51_PATCH_CODE = 0x02;//Const Code for Berlin
    byte	SS51_PATCH_OVERLAY = 0x03;
    byte	DSP_CODE = 0x04;
    byte	HOTKNOT_CODE = 0x05;
    byte	GESTURE_CODE =	0x06;
    byte	GSETURE_OVERLAY_CODE = 0x07;
    byte	FLASHLESS_CODE = 0x08;

    int MAX_SEND_BYTES = 4096;

    //-------------------------------------------------------------------------------------------------------------------------------//

    private Button btn_update;
    private Button btn_AutoUpdate;

    private Button btn_search_bin_button;
    private TextView tv_edit_search_bin;

    private Button btn_search_cfg_button;
    private TextView tv_edit_search_cfg;

    private Context mAlertContext;

    private AlertDialog alert = null;
    private AlertDialog.Builder builder = null;
	
	public String Update_log;
    public String Update_log1;
    public String Update_log2;
    String updateLogShow= "";

    String StrConfigDateString = "";

    Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {

            StringBuilder stringBuilder = new StringBuilder("");
            // for (int i = 1; i < mBytes.length; i++) {
            int checksum = 0 ;
            switch (msg.what) {
                case CONNECTED_SUCCESS://车机和手机连接成功
                    btnReadVersion.setEnabled(true);
                    //btn_update.setEnabled(true);
                    //btn_AutoUpdate.setEnabled(true);
                    //loopReceiverMessage();
                    break;

                case RECEIVER_MESSAGE_SUCCESS://成功接受到数据

                    //String hv = null;

                    for (int i = 0; i < 189; i++) {

                        if (i == 0 || i == 64 || i == 128)
                        {
                            continue;
                        }
                        int v = mBytes[i] & 0xFF;
                        checksum =checksum+ v;
                        String hv = Integer.toHexString(v);
                        stringBuilder.append(hv);
                        stringBuilder.append(",");
                    }

                    //String d_value =Arrays.toString(mBytes[);
                    //String d_value =Arrays.hv.toString();
                    //mShow.setText( stringBuilder.toString() );//输出显示
                    //tv_edit_search_bin.setText(uri.getPath().toString());
                    // mLog.setText(mStringBuffer.toString());

                    break;

                case SEND_MESSAGE_SUCCESS://成功发送数据
                    tvS8xxxxShow.setText("");
                    break;

                case DEBUG_MESSAGE_SUCCESS://成功发送数据
                    //StringBuilder stringBuilder = new StringBuilder("");

                    checksum = 0 ;
                    for (int i = 0; i < 216; i++) {

                        int v = mSendData[i] & 0xFF;
                        checksum =checksum+ v;
                        //byte v = mSendData[i];
                        String hv = Integer.toHexString(v);
                        //String hv = Byte.toString(v);
                        stringBuilder.append(hv);
                        stringBuilder.append(",");
                    }
                    tvS8xxxxShow.setText(stringBuilder.toString());
                    //mShow.setText(value);
                    break;
                case DEBUG_MESSAGE_ERROR://成功发送数据
                    //mShow.setText("ERROR");

                    updateLogShow = updateLogShow.concat(Update_log);
                    updateLogShow = updateLogShow.concat("\n");
                    updateLogShow = updateLogShow.concat(Update_log2);
                    mError.setText(updateLogShow);
                    mError.setSelection(mError.getText().length());
                    Update_log2 = "";
                    Update_log = "";
                    break;

                case UPDATE_FW:
                    tvUpDataResult.setText(Update_log1);
                    break;
            }
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_firmware_update);
        mAlertContext = FirmwareUpdate.this;
        ConstantsActivity.activityList.add(this);
        //switchLanguage(ConstantsActivity.langae);
        bindView();
        initData();
        openDevices();
    }

    //核心设置的代码
    protected void switchLanguage(String language) {
        Resources resources = getResources();
        Configuration config = resources.getConfiguration();
        DisplayMetrics dm = resources.getDisplayMetrics();
        switch (language) {
            case "zh":
                config.locale = Locale.CHINESE;
                resources.updateConfiguration(config, dm);
                break;
            case "en":
                config.locale = Locale.ENGLISH;
                resources.updateConfiguration(config, dm);
                break;
            default:
                config.locale = Locale.US;
                resources.updateConfiguration(config, dm);
                break;
        }
    }

    private void updateProcHandle() {

        mThreadPool.execute(new Runnable() {
            @Override
            public void run() {
                 SystemClock.sleep(100);
                 Update_log1 =  "";  //升级成功
                 updateLogShow =  "";
                 Update_log2 =  "";
                 mHandler.sendEmptyMessage(UPDATE_FW);
                 if(GT29xxupdateProc() == true)
                 {
                    // mHandler.sendEmptyMessage(UPDATE_FW);
                     Update_log1 =  "UPDATE SUCCESS!!!";  //升级成功
                     mHandler.sendEmptyMessage(UPDATE_FW);
                 }
                 else {
                     Update_log1 = "UPDATE FAILED!";   //升级失败
                     mHandler.sendEmptyMessage(UPDATE_FW);
                 }
            }   //ThreadPool
        });   //ThreadPool
    }

    private void bindView() {
        //mLog = (TextView) findViewById(R.id.log);
        btnReadVersion = (Button) findViewById(R.id.version);
        mError = (EditText) findViewById(R.id.error);
        tvS8xxxxShow = (TextView) findViewById(R.id.s8xxxxshow);
        tvGtxxxxShow = (TextView) findViewById(R.id.gtxxxxshow);
        tvCfgVersionShow = (TextView) findViewById(R.id.cfgversionshow);
        //mSendMessage = (Button) findViewById(R.id.sendmessage);
        //mlog1 = (Button) findViewById(R.id.log1);
        //mSendCfg = (Button) findViewById(R.id.btn1);
        btn_update = (Button) findViewById(R.id.btnUpdate);
        btn_AutoUpdate = (Button) findViewById(R.id.btnAutoUpdate);
        // mShow = (EditText) findViewById(R.id.show);

        btn_search_bin_button = (Button) findViewById(R.id.searchbinbutton);
        tv_edit_search_bin = (TextView) findViewById(R.id.editsearchbin);

        btn_search_cfg_button = (Button) findViewById(R.id.searchcfgbutton);
        tv_edit_search_cfg = (TextView) findViewById(R.id.editsearchcfg);

        tvUpDataResult = (TextView) findViewById(R.id.updataresult);

        mError.setKeyListener(null);

        btnReadVersion.setOnClickListener(this);
        btn_update.setOnClickListener(this);
        btn_AutoUpdate.setOnClickListener(this);

        btn_search_bin_button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
                intent.setType("*/*");//设置类型
                intent.addCategory(Intent.CATEGORY_OPENABLE);
                startActivityForResult(intent, 1);
            }
        });

        btn_search_cfg_button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //ActivityCompat.requestPermissions(  Config.this, new String[]{android
                //        .Manifest.permission.READ_EXTERNAL_STORAGE}, 2);
                Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
                intent.setType("*/*");//设置类型，我这里是任意类型，任意后缀的可以这样写。
                intent.addCategory(Intent.CATEGORY_OPENABLE);
                startActivityForResult(intent, 2);
            }
        });
    }
    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        switch (requestCode) {
            case 1:
                if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    //创建文件夹
                    if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
                        //Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
                        //intent.setType("*/*");//设置类型，我这里是任意类型，任意后缀的可以这样写。
                        //intent.addCategory(Intent.CATEGORY_OPENABLE);
                        //startActivityForResult(intent, 1);
                    }
                }
                break;
            case 3:
                if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED){
                    //权限已成功申请
                    //readFile();
                }else{
                    //用户拒绝授权
                    Toast.makeText(this,getResources().getString(R.string.nopermission), Toast.LENGTH_SHORT).show();
                    finish();
                }
                break;
            default:
                super.onRequestPermissionsResult(requestCode, permissions, grantResults);
                break;
        }
    }

    private void initData() {
        mContext = getApplicationContext();
        btnReadVersion.setEnabled(false);    //
        btn_update.setEnabled(false);
        btn_AutoUpdate.setEnabled(false);

        mThreadPool = Executors.newFixedThreadPool(5);

        mUsbManager = (UsbManager) getSystemService(Context.USB_SERVICE);

    }

    /**
     * 打开设备 , 让车机和手机端连起来
     */
    private void openDevices() {

        //列举设备(手机)
        fwOpenDevicesReceiver = new OpenDevicesReceiver(this);
        mThreadPool.execute(new Runnable() {
            @Override
            public void run() {
            SystemClock.sleep(1000);
            PendingIntent pendingIntent = PendingIntent.getBroadcast(mContext, 0, new Intent(ACTION_USB_PERMISSION), 0);
            IntentFilter intentFilter = new IntentFilter(USB_ACTION);

            registerReceiver(fwOpenDevicesReceiver, intentFilter);
            while(isNeedFindDevice) {
                SystemClock.sleep(100);
                HashMap<String, UsbDevice> deviceList = mUsbManager.getDeviceList();
                if (deviceList != null) {
                    for (UsbDevice usbDevice : deviceList.values()) {
                        //int productId = usbDevice.getProductId();
                        int vendorId = usbDevice.getVendorId();
                        if ((vendorId == 0x27C0)          //之前VID错误了，做兼容
                            ||(vendorId == 0x27C6)    //汇顶的VID
                            ||(vendorId == 0x222A)    //奕力的VID
                            ||(vendorId == 0x056A))   //8191主动笔和Wacom主动笔
                        {
                            if (mUsbManager.hasPermission(usbDevice)) {
                                initDevice();

                            } else {

                                //String avalue = "S818 IS NOT PERMISSION";
                                //mShow.setText(avalue);//输出显示
                                mUsbManager.requestPermission(usbDevice, pendingIntent);
                                break;
                            }
                            break;
                        }
                    }
                }
            }
        }   //ThreadPool
    });   //ThreadPool
    }

    /**
     * 初始化设备(手机) , 当手机进入Accessory模式后 , 手机的PID会变为Google定义的2个常量值其中的一个 ,
     */
    private void initDevice() {

        HashMap<String, UsbDevice> deviceList = mUsbManager.getDeviceList();
        Collection<UsbDevice> values = deviceList.values();
        if (!values.isEmpty()) {
            for (UsbDevice usbDevice : values) {
                int vendorId = usbDevice.getVendorId();
                //if (productId == 0x0818 || productId == 0x0001 )
                if ((vendorId == 0x27C0)          //之前VID错误了，做兼容
                    ||(vendorId == 0x27C6)    //汇顶的VID
                    ||(vendorId == 0x222A)    //奕力的VID
                    ||(vendorId == 0x056A))   //8191主动笔和Wacom主动笔
                {

                    if (mUsbManager.hasPermission(usbDevice)) {

                        UsbInterface usbInterface = usbDevice.getInterface(1);

                        for (int i = 0; i < usbInterface.getEndpointCount(); i++) {
                            UsbEndpoint ep = usbInterface.getEndpoint(i);

                            if (ep.getDirection() == UsbConstants.USB_DIR_OUT) {
                                //mUsbEndpointIn = ep;
                                mUsbEndpointOut = ep;
                            } else {
                                //mUsbEndpointOut = ep;
                                mUsbEndpointIn = ep;
                            }
                        }

                        if ((null == mUsbEndpointIn) || (null == mUsbEndpointOut)) {
                            mUsbDeviceConnection = mUsbManager.openDevice(usbDevice);
                            if (mUsbDeviceConnection!=null) {
                                int i = mUsbDeviceConnection.controlTransfer(0x00, 0x09,
                                        0x002, 0, null, 0, 100);
                                SystemClock.sleep(1000);
                                if (i >= 0) {
                                    //mHandler.sendEmptyMessage(DEBUG_MESSAGE_SUCCESS);
                                } else {
                                    //mHandler.sendEmptyMessage(DEBUG_MESSAGE_ERROR);
                                }
                            }
                        } else {

                            isNeedFindDevice = false;
                            mUsbInterface = usbInterface;
                            mUsbDeviceConnection = mUsbManager.openDevice(usbDevice);
                            mUsbDeviceConnection.claimInterface(mUsbInterface, true);
                            if(null != mUsbEndpointIn){
                                iProductId = usbDevice.getProductId();
                                //if ((iProductId == 0x0819) || (iProductId == 0x8191)||(iProductId == 0x0528))
                                //{
                                //    byProductType = GT7;
                                //}else{
                                //    byProductType = GT9;
                                //}

                                if ((iProductId == 0x0829) || (iProductId == 0x0528) || (iProductId == 0x0928))
                                {
                                    byProductType = GT29336;
                                }
                                else{
                                    byProductType = GT2931;
                                }
                                mHandler.sendEmptyMessage(CONNECTED_SUCCESS);
                            }
                        }
                    } else {
                        mUsbManager.requestPermission(usbDevice, PendingIntent.getBroadcast(mContext, 0, new Intent(""), 0));
                    }
                }
            }
        }
    }

    @Override
    public void onClick(final View view) {
        int j = 0;
        int sendLoop = 1;
        byte addressH,addressL;
        byte addrfirstbyte, addrsecondbyte, addrthirdbyte;
        String hv = "";
        String strpidversion = "GT";
        switch(view.getId()) {
            case R.id.version:     //read version
                bottonMode = 0;
                mSendData = mSendGetGt9VersionData;
                isSendMessage = false;

                /*
                if (byProductType == GT7)  //GT7
                {
                    addressH = (byte)0x82;
                    addressL = (byte)0x40;
                    iicRead(addressH,addressL,mBytes,16);

                    for (int i = 0; i < 8; i++)
                    {
                        int v = mBytes[i] & 0xFF;
                        mVersionShow[i] = Integer.toHexString(v);
                    }

                    if (mBytes[0] == 0x37 && mBytes[1] == 0x33 && mBytes[2] == 0x38 && mBytes[3] == 0x37){
                        mShow.setText( "GT7387_" + mVersionShow[4] + "." + mVersionShow[5] + "." + mVersionShow[6] + "." + mVersionShow[7]);//输出显示
                    }
                    else if (mBytes[0] == 0x37 && mBytes[1] == 0x33 && mBytes[2] == 0x38 && mBytes[3] == 0x38){
                        mShow.setText( "GT7387P_" + mVersionShow[4] + "." + mVersionShow[5] + "." + mVersionShow[6] + "." + mVersionShow[7]);//输出显示
                    }
                    else if (mBytes[0] == 0x37 && mBytes[1] == 0x33 && mBytes[2] == 0x38 && mBytes[3] == 0x32){
                        mShow.setText( "GT7382H_" + mVersionShow[4] + "." + mVersionShow[5] + "." + mVersionShow[6] + "." + mVersionShow[7]);//输出显示
                    }
                    else
                        mShow.setText( "Null" );//输出显示
                    }
                }
                else  //GT9
                */
                {

                    for (int i = 0; i < 23; i++)  //Get version
                    {
                        mBytes[i] = 0;
                    }

                    iicRead32Bits((byte)0x01, (byte)0x00, (byte)0x14, (byte)0x03,mBytes, 24);

                    strpidversion = new String(mBytes,0,24);

                    tvS8xxxxShow.setText(strpidversion);

                    strpidversion = "GT";

                    iicRead32Bits((byte)0x01, (byte)0x00, (byte)0x14, (byte)0x0f,mBytes, 23);

                    for (int i = 10; i < 15; i++)  //Get PID
                    {
                        if (mBytes[i] == 0)
                            break;

                        int v = (mBytes[i] - 48) & 0xFF;  //ASCII码减去48
                        hv = Integer.toHexString(v);
                        strpidversion += hv;
                    }

                    if (strpidversion.length() < 6)
                    {
                        tvGtxxxxShow.setText( "Null" );//输出显示
                    } else{

                        strpidversion += "_";

                        for (int i = 18; i < 22; i++)  //Get version
                        {
                            int v = mBytes[i] & 0xFF;
                            hv = Integer.toHexString(v);
                            if (hv.length() < 2){
                                hv = "0" + hv;
                            }

                            strpidversion += hv;

                            if (i < 21)
                            {
                                strpidversion += ".";
                            }
                        }

                        tvGtxxxxShow.setText(strpidversion);//输出显示
                    }

                    //send 0x00 0x00 0x04 0x07 0x0B 0x00 to [0x10174]，通知GT29XX,要读cfg
                    mBytes[0] = 0x00;
                    mBytes[1] = 0x00;
                    mBytes[2] = 0x04;
                    mBytes[3] = 0x07;
                    mBytes[4] = 0x0B;
                    mBytes[5] = 0x00;
                    iicWrite32Bits((byte)0x01, (byte)0x01, (byte)0x74, (byte)0x0f, mBytes,0,6);


                    //read [0x10175] = 0x80,config is ready
                    //do {
                    //    SystemClock.sleep(30);
                    //    iicRead32Bits((byte)0x01, (byte)0x01, (byte)0x75, mBytes, 1);
                    //}while(mBytes[0] != (byte)0x80);

                    //read [0x10174] = 0x80,config is ready
                    do {
                        SystemClock.sleep(30);
                        iicRead32Bits((byte)0x01, (byte)0x01, (byte)0x74, (byte)0x0f, mBytes, 1);
                    }while(mBytes[0] != (byte)0x80);

                    //SystemClock.sleep(2);

                    if (byProductType == GT29336) {
                        addrfirstbyte = (byte)0x01;
                        addrsecondbyte = (byte)0x3B;
                        addrthirdbyte = (byte)0x74;
                    }else {
                        addrfirstbyte = (byte)0x01;
                        addrsecondbyte = (byte)0x21;
                        addrthirdbyte = (byte)0x8C;
                    }

                    //read buffer [0x13B74]/[0X1218C]
                    iicRead32Bits(addrfirstbyte, addrsecondbyte, addrthirdbyte, (byte)0x0f, mBytes, 63);  //read config head

                    strpidversion = "Config Version: " + Integer.toString(mBytes[34]);

                    SystemClock.sleep(5);

                    //send 0x00 0x00 0x04 0x08 0x0C 0x00 to [0x10174]，通知GT29XX,通信结束
                    mBytes[0] = 0x00;
                    mBytes[1] = 0x00;
                    mBytes[2] = 0x04;
                    mBytes[3] = 0x08;
                    mBytes[4] = 0x0C;
                    mBytes[5] = 0x00;
                    iicWrite32Bits((byte)0x01, (byte)0x01, (byte)0x74, (byte)0x0f, mBytes, 0, 6);

                    //read [0x10175] = 0x80,config is ready
                    //do {
                    //    SystemClock.sleep(30);
                    //    iicRead32Bits((byte)0x01, (byte)0x01, (byte)0x75, mBytes, 1);
                    //}while(mBytes[0] != (byte)0x80);

                    //read [0x10175] = 0x80,read config is over
                    do {
                        SystemClock.sleep(30);
                        iicRead32Bits((byte)0x01, (byte)0x01, (byte)0x74, (byte)0x0f, mBytes, 1);
                    }while(mBytes[0] != (byte)0x80);

                    //SystemClock.sleep(2);

                    //stMessageLog = "Read config finish!! Config Version:0x" + mConfigShow[34];

                    tvCfgVersionShow.setText(strpidversion);

                    /*
                    addressH = (byte)0x81;
                    addressL = (byte)0x40;
                    iicRead(addressH,addressL,mBytes,16);

                    int v = mBytes[4] & 0xFF;
                    hv = Integer.toHexString(v);
                    if (hv.length() < 2){
                        hv = "0" + hv;
                    }
                    mVersionShow[0] = hv;

                    v = mBytes[5] & 0xFF;
                    hv = Integer.toHexString(v);
                    if (hv.length() < 2){
                        hv = "0" + hv;
                    }
                    mVersionShow[1] = hv;

                    if (mBytes[0] == 0x39 && mBytes[1] == 0x31 && mBytes[2] == 0x31 && mBytes[3] == 0x32){
                        mShow.setText( "GT9110H_" + mVersionShow[1].toString() + mVersionShow[0].toString() );//输出显示
                    }
                    else if (mBytes[0] == 0x36 && mBytes[1] == 0x31 && mBytes[2] == 0x30 && mBytes[3] == 0x39){
                        mShow.setText( "GT6108H_" + mVersionShow[1].toString() + mVersionShow[0].toString() );//输出显示
                    }
                    else{
                        mShow.setText( "Null" );//输出显示
                    }
                     */
                }

                break;

            case R.id.btnAutoUpdate:  //自动下载固件和配置
                bottonMode = 3;
                isReceiverMessage = false;  //升级关闭循环接收信息
                //mSendData = mSendGetGt9VersionData;
                isSendMessage = false;
                //updateProcHandle();   //暂时不开放
                //mHandler.sendEmptyMessage(UPDATE_FW);
                break;
            case R.id.btnUpdate:
                bottonMode = 4;
                isReceiverMessage = false;  //升级关闭循环接收信息
                //mSendData = mSendGetGt9VersionData;
                isSendMessage = false;
                //mHandler.sendEmptyMessage(UPDATE_FW);
                //if (byProductType == GT9)
                {
                    updateProcHandle();
                }
                break;

            default:
                break;
        }


        while (isSendMessage) {
            /**
             * 发送数据的地方 , 只接受byte数据类型的数据
             */
            SystemClock.sleep(1);
            // int i = mUsbDeviceConnection.bulkTransfer(mUsbEndpointOut, messageContent.getBytes(), messageContent.getBytes().length, 3000);
            //String c_value = "SENDING";
            // mShow.setText(c_value);//输出显示

            j = j +1;
            if(1000 == j) {
                j = 0;
                isSendMessage = false;
            }
            //int i = mUsbDeviceConnection.bulkTransfer(mUsbEndpointOut, mSendData, mSendData.length, 3000);
            // UsbPipe
            // UsbEndpoint
            //int i = mUsbDeviceConnection.controlTransfer(0x21, 0x09, 0x301, 0, mSendGetGt9VersionData, mSendGetGt9VersionData.length, 100);
            //
            if (null != mUsbEndpointOut) {
              //  if ((null != mUsbEndpointOut) && (bottonMode != 1)) {
                //mSendGetGt9ConfigData  mSendGetGt9VersionData
                int i = -1;
                int count = 0;
                for (int k = 0; k < sendLoop; k++) {
                    int offset1 = k*64;
                    if(k==3)
                    i = mUsbDeviceConnection.bulkTransfer(mUsbEndpointOut, mSendData, offset1, 0x40, 100);
                    else
                        i = mUsbDeviceConnection.bulkTransfer(mUsbEndpointOut, mSendData, offset1, 0x40, 100);
                    SystemClock.sleep(10);

                    if (i == 0x0f || i == 0x40) {

                        //   String b_value = "SEND MESSAGE SUCCESS";
                        //  mShow.setText(b_
                        // value);//输出显示
                        count++;
                        //mHandler.sendEmptyMessage(SEND_MESSAGE_SUCCESS);
                        // mlog1.setEnabled(true);
                       // isSendMessage = false;

                    } else {
                        //  mlog1.setEnabled(true);
                        if(sendLoop == 4)
                        mHandler.sendEmptyMessage(DEBUG_MESSAGE_ERROR);
                    }

                    if(count == 4)
                        mHandler.sendEmptyMessage(DEBUG_MESSAGE_SUCCESS);
                }
                if (i == 0x0f ||i == 0x40 )
                isSendMessage = false;
                //int i = mUsbDeviceConnection.bulkTransfer(mUsbEndpointIn, mBytes, mBytes.length, 3000);
                //int i =0;


            }

        }
    }

    protected void onActivityResult ( int requestCode, int resultCode, Intent resultData){
        if (resultCode == Activity.RESULT_OK) {

            int permission_write = ContextCompat.checkSelfPermission(FirmwareUpdate.this, Manifest.permission.WRITE_EXTERNAL_STORAGE);
            int permission_read = ContextCompat.checkSelfPermission(FirmwareUpdate.this, Manifest.permission.READ_EXTERNAL_STORAGE);

            if ((permission_write != PackageManager.PERMISSION_GRANTED)
                    ||(permission_read != PackageManager.PERMISSION_GRANTED))
            {

                ActivityCompat.requestPermissions(FirmwareUpdate.this, new String[]{android.Manifest.permission.WRITE_EXTERNAL_STORAGE,
                        android.Manifest.permission.READ_EXTERNAL_STORAGE}, 3);
            }

            StringBuffer buffer = new StringBuffer();
            if (requestCode == 1) {

                if (resultData != null) {
                    Uri uri = resultData.getData();
                    String filePath = getFilePathFromUri(uri);
                    //String fileName = getFileNameFromUri(uri);
                    tv_edit_search_bin.setText(filePath);

                    btn_update.setEnabled(true);
                }

            }//end of if (requestCode == 1)
            else if (requestCode == 2) {  //CFG 文 件
                StrConfigDateString = "";

                Uri uri = null;
                if (resultData != null){
                    uri = resultData.getData();
                }

                try {
                    InputStream inputStream = getContentResolver().openInputStream(uri);
                    BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
                    String line;
                    StringBuilder stringBuilder = new StringBuilder();

                    while ((line = reader.readLine()) != null){
                        stringBuilder.append(line);
                    }

                    reader.close();

                    StrConfigDateString = stringBuilder.toString();


                    //edit_search.setText(fileData);
                    tv_edit_search_cfg.setText(uri.getPath());

                    btn_update.setEnabled(true);

                } catch (IOException c) {
                    tv_edit_search_cfg.setText(uri.getPath() + "——" + getResources().getString(R.string.invalidfile));
                    return;
                }
            }  //end of else if (requestCode == 2)
        }

    }

    private String getFilePathFromUri(Uri uri) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT && DocumentsContract.isDocumentUri(this, uri)) {
            if (isExternalStorageDocument(uri)) {
                String docId = DocumentsContract.getDocumentId(uri);
                String[] split = docId.split(":");
                String type = split[0];
                if ("primary".equalsIgnoreCase(type)) {
                    return Environment.getExternalStorageDirectory() + "/" + split[1];
                }
            } else if (isDownloadsDocument(uri)) {
                String id = DocumentsContract.getDocumentId(uri);
                Uri contentUri = ContentUris.withAppendedId(
                        Uri.parse("content://downloads/public_downloads"), Long.parseLong(id));
                return getDataColumn(this, contentUri, null, null);
            } else if (isMediaDocument(uri)) {
                String docId = DocumentsContract.getDocumentId(uri);
                String[] split = docId.split(":");
                String type = split[0];
                Uri contentUri = null;
                if ("image".equals(type)) {
                    contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
                } else if ("video".equals(type)) {
                    contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
                } else if ("audio".equals(type)) {
                    contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
                }
                String selection = "_id=?";
                String[] selectionArgs = new String[]{split[1]};
                return getDataColumn(this, contentUri, selection, selectionArgs);
            }
        } else if ("content".equalsIgnoreCase(uri.getScheme())) {
            return getDataColumn(this, uri, null, null);
        } else if ("file".equalsIgnoreCase(uri.getScheme())) {
            return uri.getPath();
        }
        return null;
    }

    private String getFileNameFromUri(Uri uri) {
        String result = null;
        if (uri.getScheme().equals("content")) {
            Cursor cursor = getContentResolver().query(uri, null, null, null, null);
            try {
                if (cursor != null && cursor.moveToFirst()) {
                    result = cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.DISPLAY_NAME));
                }
            } finally {
                if (cursor != null) {
                    cursor.close();
                }
            }
        }
        if (result == null) {
            result = uri.getPath();
            int cut = result.lastIndexOf('/');
            if (cut != -1) {
                result = result.substring(cut + 1);
            }
        }
        return result;
    }

    private String getDataColumn(FirmwareUpdate mainActivity, Uri uri, String selection, String[] selectionArgs) {
        Cursor cursor = null;
        String column = MediaStore.Images.Media.DATA;
        String[] projection = {column};
        try {
            cursor = mainActivity.getContentResolver().query(uri, projection, selection, selectionArgs, null);
            if (cursor != null && cursor.moveToFirst()) {
                int index = cursor.getColumnIndexOrThrow(column);
                return cursor.getString(index);
            }
        } finally {
            if (cursor != null) {
                cursor.close();
            }
        }
        return null;
    }



    private boolean isExternalStorageDocument(Uri uri) {
        return "com.android.externalstorage.documents".equals(uri.getAuthority());
    }

    private boolean isDownloadsDocument(Uri uri) {
        return "com.android.providers.downloads.documents".equals(uri.getAuthority());
    }

    private boolean isMediaDocument(Uri uri) {
        return "com.android.providers.media.documents".equals(uri.getAuthority());
    }


    private byte iicByteData[]={
        //0    1   2     3    4    5    6
        0x03,0x00,0x0f,0x00,0x00,0x00,0x01,0x00,
        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,

    };
    private byte iicWriteData[]={
        //0    1   2     3    4    5    6
        0x03,0x00,0x0f,0x00,0x00,0x00,0x39,0x00,
        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,

    };

    //发送命令，使得S818可以通过IIC向GT9的固定地址读取任意bytes的数据
    private boolean iicRead(byte addressHigh,byte addressLow,byte[] wBuffer,int length) {

        int i;

        iicByteData[1] = 0x00; //read GT9 command
        iicByteData[2] = 0x0f; //no command
        iicByteData[3] = addressHigh;
        iicByteData[4] = addressLow;
        iicByteData[5] = 0x00;
        iicByteData[6] = 63;  //length 一次接收63个数据

        for (int j = 7; j < 64; j++) {
            iicWriteData[j] = 0x00;
        }

        int address1 = ((addressHigh&0xff)<<8);
        int address2 = addressLow&0xff;
        int address = address1|address2;

        int sendTimes = length/63 + 1;  //预计是向下取整，所以+1

        iicByteData[5] = (byte)(length>>8);
        iicByteData[6] = (byte)length;  //length 一次接收63个数据

        //发送读取命令
        i = mUsbDeviceConnection.bulkTransfer(mUsbEndpointOut, iicByteData, 0, 0x40, 100);
        if (i != 0x40)
            return false;  //传输失败

        for (int k = 0; k < sendTimes; k++) {
            //int finalOffset = k*63; //每次只能发57bytes数据
            int offset = k*64;

          //  if(length - (finalOffset ) < 63) {

               // iicByteData[6] = (byte) (length - (finalOffset));  //length
           // }
         //   else
         //   {
              //  iicByteData[6] = 63;
          //  }


           // SystemClock.sleep(1);

            isReceiverMessage = false;  //先关闭循环接收信息

           //接收数据
           // i = mUsbDeviceConnection.bulkTransfer(mUsbEndpointIn, wBuffer, offset, 0x40, 100);
            i = mUsbDeviceConnection.bulkTransfer(mUsbEndpointIn, wBuffer, offset, 0x40, 100);

            //if (i != 0x40) {
            if (i != 0x40) {
               // mError.setText("iicWrite Failed");
                Update_log = "iicRead Failed";
                mHandler.sendEmptyMessage(DEBUG_MESSAGE_ERROR);
                return false;

            }

           // address = address + 63;
          //  iicByteData[3] = (byte)(address>>8);
          //  iicByteData[4] = (byte)address;
        }

        //将report id从数组中去除
        //byte[] temperBuffer =new byte[length];
        if(true) {
            int count1 = 0;
            for (int k = 0; k < length; k++) {
                if (k % 63 == 0) {
                    count1++;
                }

                wBuffer[k] = wBuffer[k + count1];

            }
        }
        return true;
    }

    //发送命令，使得S818可以通过IIC向GT9的固定地址写任意bytes的数据
    private  boolean iicWrite(byte addressHigh,byte addressLow,byte[] wBuffer,int offset,int length) {
        int i;

        iicWriteData[1] = 0x01; //write GT9 command
        iicWriteData[2] = 0x0f; //no command
        iicWriteData[3] = addressHigh;
        iicWriteData[4] = addressLow;
        iicWriteData[5] = 0x00;
        iicWriteData[6] = 0x39;  //length

        int address1 = ((addressHigh&0xff)<<8);
        int address2 = addressLow&0xff;
        int address = address1|address2;

        int sendTimes = length/57 + 1;  //预计是向下取整，所以+1

        for (int k = 0; k < sendTimes; k++) {
            int finalOffset = offset + k*57; //每次只能发57bytes数据

            if(length - (finalOffset -offset) < 57) {

                iicWriteData[6] = (byte) (length - (finalOffset -offset));  //length
            }
            else
            {
                iicWriteData[6] = 0x39;
            }

            for (int j = 7; j < 64; j++) {
                iicWriteData[j] = wBuffer[finalOffset + j -7];
            }
            i = mUsbDeviceConnection.bulkTransfer(mUsbEndpointOut, iicWriteData, 0, 0x40, 100);

            if (i != 0x40) {
              //  mError.setText("iicWrite Failed");
                Update_log = "iicWrite Failed";
                mHandler.sendEmptyMessage(DEBUG_MESSAGE_ERROR);
                return false;

            }

            address = address + 57;
            iicWriteData[3] = (byte)(address>>8);
            iicWriteData[4] = (byte)address;
        }

        return true;
    }

    //发送命令，使得S818可以通过IIC向GT9的固定地址写1byte数据
    private  boolean iicByteWrite(byte addressHigh,byte addressLow,byte subCommand,byte data) {
        int i;

        iicByteData[1] = 0x01; //write GT9 command
        iicByteData[2] = subCommand;
        iicByteData[3] = addressHigh;
        iicByteData[4] = addressLow;
        iicByteData[5] = 0x00;
        iicByteData[6] = 0x01;  //length

        iicByteData[7] = data;
        if ((null == mUsbEndpointIn) || (null == mUsbEndpointOut)){
            i = 0;
            //mUsbManager = (UsbManager) getSystemService(Context.USB_SERVICE);
           // initDevice();
            i = mUsbDeviceConnection.bulkTransfer(mUsbEndpointOut, iicByteData, 0, 0x40, 100);
        }
        else {
            i = mUsbDeviceConnection.bulkTransfer(mUsbEndpointOut, iicByteData, 0, 0x40, 100);
        }
       // i = 0;
        if(i == 0x40)
            return true;
        else
            return false;
    }

    //发送命令，使得S818可以通过IIC向GT9的固定地址读取1byte数据
    private byte iicByteRead(byte addressHigh,byte addressLow) {
        iicByteData[1] = 0x00; //read GT9 command
        iicByteData[2] = 0x0f;  //no command
        iicByteData[3] = addressHigh;
        iicByteData[4] = addressLow;
        iicByteData[5] = 0x00;   //length
        iicByteData[6] = 0x01;   //lengthlow

        iicByteData[7] = 0x00;
        //  mThreadPool.execute(new Runnable() {
        //     @Override
        //     public void run() {
        int i;
        boolean byteReceiverLoop = true;
        i = mUsbDeviceConnection.bulkTransfer(mUsbEndpointOut, iicByteData, 0, 0x40, 100);
        if (i != 0x40)
            return 0x77;  //用0x77来表示传输失败
        //SystemClock.sleep(5);

        isReceiverMessage = false;  //先关闭循环接收信息


        i = mUsbDeviceConnection.bulkTransfer(mUsbEndpointIn, mBytes, 0, 0x40, 3000);
        //SystemClock.sleep(5);
        if (i == 0x40)
            return mBytes[1];
        else
            return 0x77;  //用0x77来表示传输失败
        // }
    }

    //发送命令，使得S8xx可以通过IIC向GT29xx的固定地址读取任意bytes的数据
    private boolean iicRead32Bits(byte addrfirstbyte,byte addrsecondbyte,byte addrthirdbyte,byte subCommand,byte[] wBuffer,int length) {

        int i;

        iicByteData[1] = (byte)(0 | subCommand);//0x0f; //7bit:0-read,1-write;other:command
        //iicByteData[2] = 0x0f; //no command
        iicByteData[2] = addrfirstbyte;
        iicByteData[3] = addrsecondbyte;
        iicByteData[4] = addrthirdbyte;
        iicByteData[5] = 0x00;
        iicByteData[6] = 63;  //length 一次接收63个数据

        for (int j = 7; j < 64; j++) {
            iicByteData[j] = 0x00;
        }

        int address1 = ((addrsecondbyte & 0xff) << 8);
        int address2 = addrthirdbyte & 0xff;
        int address = address1 | address2;

        int sendTimes = length / 63;  //预计是向下取整，所以+1

        if ((length % 63) != 0)
        {
            sendTimes += 1;   //预计是向下取整，所以+1
        }
        //iicByteData[5] = (byte)(length>>8);
        //iicByteData[6] = (byte)length;  //length 一次接收63个数据

        for (int k = 0; k < sendTimes; k++)
        {
            int finalOffset = k*63; //每次只能发57bytes数据
            int offset = k * 64;

            if(length - (finalOffset ) < 63) {

                iicByteData[6] = (byte) (length - (finalOffset));  //length
            }
            else
            {
                iicByteData[6] = 63;
            }

            //发送读取命令
            i = mUsbDeviceConnection.bulkTransfer(mUsbEndpointOut, iicByteData, 0, 0x40, 100);
            if (i != 0x40)
                return false;  //传输失败

            // SystemClock.sleep(1);

            //接收数据
            // i = mUsbDeviceConnection.bulkTransfer(mUsbEndpointIn, wBuffer, offset, 0x40, 100);
            i = mUsbDeviceConnection.bulkTransfer(mUsbEndpointIn, wBuffer, offset, 0x40, 100);

            //if (i != 0x40) {
            if (i != 0x40) {
                //editname.setText("IIC Read Failed!!");
                return false;

            }

            address = address + 63;
            iicByteData[3] = (byte)(address>>8);
            iicByteData[4] = (byte)address;
        }

        //将report id从数组中去除
        //byte[] temperBuffer =new byte[length];
        if(true) {
            int count1 = 0;
            for (int k = 0; k < length; k++) {
                if (k % 63 == 0) {
                    count1++;
                }

                wBuffer[k] = wBuffer[k + count1];

            }
        }
        return true;
    }

    //发送命令，使得S8xx可以通过IIC向GT79xx的固定地址写任意bytes的数据
    private  boolean iicWrite32Bits(byte addrfirstbyte,byte addrsecondbyte,byte addrthirdbyte,byte subCommand,byte[] wBuffer,int offset, int length) {

        int i;

        iicWriteData[1] = (byte)(0x80 | subCommand);//0x0f; //7bit:0-read,1-write;other:command
        //iicWriteData[2] = 0x0f; //no command
        iicWriteData[2] = addrfirstbyte;
        iicWriteData[3] = addrsecondbyte;
        iicWriteData[4] = addrthirdbyte;
        iicWriteData[5] = 0x00;
        iicWriteData[6] = 63;  //length 一次接收63个数据

        for (int j = 7; j < 64; j++) {
            iicWriteData[j] = 0x00;
        }

        int address1 = ((addrsecondbyte&0xff)<<8);
        int address2 = addrthirdbyte&0xff;
        int address = address1|address2;

        int sendTimes = length/57 + 1;  //预计是向下取整，所以+1

        //iicByteData[5] = (byte)(length>>8);
        //iicByteData[6] = (byte)length;  //length 一次接收63个数据

        for (int k = 0; k < sendTimes; k++) {
            int finalOffset = offset + k*57; //每次只能发57bytes数据

            if(length - (finalOffset -offset) < 57) {

                iicWriteData[6] = (byte) (length - (finalOffset -offset));  //length
            }
            else
            {
                iicWriteData[6] = 0x39;
            }

            for (int j = 7; j < 64; j++) {
                iicWriteData[j] = wBuffer[finalOffset + j -7];
            }
            i = mUsbDeviceConnection.bulkTransfer(mUsbEndpointOut, iicWriteData, 0, 0x40, 100);

            if (i != 0x40) {
                //mShow.setText("iicWrite Failed");
                return false;

            }

            address = address + 57;
            //iicWriteData[2] = (byte)((address & 0xFF0000) >> 16);
            iicWriteData[3] = (byte)(address >> 8);
            iicWriteData[4] = (byte)address;
        }

        return true;
    }

    //发送命令，使得S818可以通过IIC向GT9的固定地址写1byte数据
    private  boolean IicWriteOneByte(byte addrfirstbyte,byte addrsecondbyte,byte addrthirdbyte,byte subCommand,byte data) {
        int i;

        iicByteData[1] = (byte)(0x80 | subCommand); //write GT9 command
        iicByteData[2] = addrfirstbyte;
        iicByteData[3] = addrsecondbyte;
        iicByteData[4] = addrthirdbyte;
        iicByteData[5] = 0x00;
        iicByteData[6] = 0x01;  //length

        iicByteData[7] = data;
        if ((null == mUsbEndpointIn) || (null == mUsbEndpointOut)){
            i=0;
        }
        else {
            i = mUsbDeviceConnection.bulkTransfer(mUsbEndpointOut, iicByteData, 0, 0x40, 100);
        }
        // i = 0;
        if(i == 0x40)
            return true;
        else
            return false;
    }

    private boolean enterUpdateMode() {
        // if ( == false)
        {
            //FwUpdateMessage(L"[FW update]Touch IC reset failed", MSG_ERR);
            byte maddressHigh = (byte)0x80;
            byte maddressLow = (byte)0x40;
            byte msubcommand =0x04 ;  //rst IC
            byte mdata = (byte)0x00;

            if(!iicByteWrite(maddressHigh,maddressLow,msubcommand,mdata)) {
               // mError.setText("[FW update]Touch IC reset failed");
                Update_log = "[FW update]Touch IC reset failed";
                mHandler.sendEmptyMessage(DEBUG_MESSAGE_ERROR);
                return false;
            }
        }

        for (int k = 0; k < 5; k++)
        {
            //nTryTimes--;
            byte maddressHigh = (byte)0x41;
            byte maddressLow = (byte)0x80;  //_rRW_MISCTL__SWRST_B0_
            byte msubcommand =0x0f ;  //no command
            byte mdata = (byte)0x0C;

            if(!iicByteWrite(maddressHigh,maddressLow,msubcommand,mdata))
                return false;

            maddressHigh = (byte)0x40;
            maddressLow = (byte)0xB0;  //_bRW_MISCTL__TMR0_EN
            mdata = (byte)0x00;

            if(!iicByteWrite(maddressHigh,maddressLow,msubcommand,mdata))
                return false;
        }

        byte maddressHigh = (byte)0x41;
        byte maddressLow = (byte)0x80;  //_rRW_MISCTL__SWRST_B0_

        if (0x0C ==iicByteRead(maddressHigh,maddressLow))
        {
           // FwUpdateMessage(L"[FW update]Hold IC successfully", MSG_NOR);
           // mError.setText("[FW update]Hold IC successfully");
            Update_log = "[FW update]Hold IC successfully";
            mHandler.sendEmptyMessage(DEBUG_MESSAGE_ERROR);

        }
        else
        {
           // FwUpdateMessage(L"[FW update]Hold IC failed", MSG_ERR);
           // mError.setText("[FW update]Hold IC failed");
            Update_log = "[FW update]Hold IC failed";
            mHandler.sendEmptyMessage(DEBUG_MESSAGE_ERROR);
            return false;
        }

        maddressHigh = (byte)0x40;
        maddressLow = (byte)0xB0;  //_rRW_MISCTL__SWRST_B0_
        if (0x00 == iicByteRead(maddressHigh,maddressLow))
        {
            //FwUpdateMessage(L"[FW update]Disable watch dog", MSG_NOR);
          //  mError.setText("[FW update]Disable watch dog");
            Update_log = "[FW update]Disable watch dog";
            mHandler.sendEmptyMessage(DEBUG_MESSAGE_ERROR);
        }
        else
        {
          //  FwUpdateMessage(L"[FW update]Disable watch dog failed", MSG_ERR);
           // mError.setText("[FW update]Disable watch dog failed");
            Update_log = "[FW update]Disable watch dog failed";
            mHandler.sendEmptyMessage(DEBUG_MESSAGE_ERROR);
            return false;
        }


        maddressHigh = (byte)0x40;
        maddressLow = (byte)0x4B;  //_bRW_MISCTL__CACHE_EN
        byte mdata = (byte)0x00;
        byte msubcommand =0x0f ;  //no command
        if (!iicByteWrite(maddressHigh,maddressLow,msubcommand,mdata))
        {
          //  FwUpdateMessage(L"[FW update]Clear cache enable failed", MSG_ERR);
          //  mError.setText("[FW update]Clear cache enable failed");
            Update_log = "[FW update]Clear cache enable failed";
            mHandler.sendEmptyMessage(DEBUG_MESSAGE_ERROR);
            return false;
        }
        // FwUpdateMessage(L"[FW update]Clear cache enable", MSG_NOR);

        maddressHigh = (byte)0x50;
        maddressLow = (byte)0x94;  //_rRW_MISCTL__BOOT_CTL_
        mdata = (byte)0x00;
        if (!iicByteWrite(maddressHigh,maddressLow,msubcommand,mdata))
        {
            //FwUpdateMessage(L"[FW update]Clear update ctrlflag failed", MSG_ERR);
           // mError.setText("[FW update]Clear update ctrlflag failed");
            Update_log = "[FW update]Clear update ctrlflag failed";
            mHandler.sendEmptyMessage(DEBUG_MESSAGE_ERROR);
            return false;
        }
       // FwUpdateMessage(L"[FW update]Clear update ctrlflag", MSG_NOR);
       // mError.setText("[FW update]Clear update ctrlflag");
        Update_log = "[FW update]Clear update ctrlflag";
        mHandler.sendEmptyMessage(DEBUG_MESSAGE_ERROR);

        return true;
    }

    boolean memCmp(byte[] sBuffer,byte[] deBuffer,int offset,int length) {

         {
            try {

                for (int i = 0; i < length; i++) {
                    if (sBuffer[i] != deBuffer[offset + i]) {
                        // FwUpdateMessage(L"Recall frame data fail,not equal.", MSG_ERR);
                        // mError.setText("Recall frame data fail,not equal.");
                        StringBuilder stringBuilder = new StringBuilder("sBuffer[i]=");
                        int v = sBuffer[i] & 0xFF;
                        String hv = Integer.toHexString(v);
                        stringBuilder.append(hv);
                        stringBuilder.append(",dBuffer[offset + i]=");

                        v = deBuffer[offset + i]& 0xFF;
                        hv = Integer.toHexString(v);
                        stringBuilder.append(hv);
                        stringBuilder.append(",i=");

                        stringBuilder.append(i);
                        stringBuilder.append(",offset=");
                        stringBuilder.append(offset);
                        stringBuilder.append(".\n");


                        for (int j = 0; j < 129; i++) {

                             v = sBuffer[i+j] & 0xFF;
                            hv = Integer.toHexString(v);
                            stringBuilder.append(hv);
                            stringBuilder.append(",");
                        }

                        Update_log2 = Update_log2.concat(stringBuilder.toString()) ;
                        Update_log2 = Update_log2.concat("\n");
                       // mHandler.sendEmptyMessage(DEBUG_MESSAGE_ERROR);
                        return false;
                    }
                }
            } catch (ArithmeticException e) {
                Update_log2 = Update_log2.concat("ArithmeticException");
                Update_log2 = Update_log2.concat("\n");
                e.printStackTrace();
            } catch (ArrayIndexOutOfBoundsException e) {
                Update_log2 = Update_log2.concat("Recall check success");
                Update_log2 = Update_log2.concat("\n");
                e.printStackTrace();
            }
        }
        return true;
    }


    boolean recallCheck(byte addressHigh,byte addressLow,byte[] dBuffer,int offset,int length)
    {
        //BYTE* pbBuf = new BYTE[wLen];
        byte[] recallBuf =new byte[length+0x3000];

        //if(false)
        {
            if (!iicRead(addressHigh, addressLow, recallBuf, length)) {
                //FwUpdateMessage(L"recall i2c error failed", MSG_ERR);
               // mShow.setText("recall i2c error failed");
                Update_log2 =Update_log2.concat("recall i2c error failed!") ;
                Update_log2 = Update_log2.concat("\n");
               // mHandler.sendEmptyMessage(DEBUG_MESSAGE_ERROR);
                return false;
            }
            if (!memCmp(recallBuf, dBuffer, offset, length)) {  //recallBuf为回读的数据,dBuffer为源数据

                // FwUpdateMessage(L"Recall frame data fail,not equal.", MSG_ERR);
               // mMessage.setText("Recall frame data fail,not equal.");
               // Update_log = "recall frame data fail,not equal";
                Update_log2 =Update_log2.concat("recall frame data fail,not equal") ;
                Update_log2 = Update_log2.concat("\n");
               // mHandler.sendEmptyMessage(DEBUG_MESSAGE_ERROR);
                return false;
            }
        }
        return true;

    }

    boolean recallCheck32Bits(byte addrfirstbyte,byte addrsecondbyte, byte addrthirdbyte, byte[] wBuffer,int offset,int length)
    {
        //BYTE* pbBuf = new BYTE[wLen];
        byte[] pbBuf =new byte[length+0x3000];

        //if(false)
        {
            if (!iicRead32Bits(addrfirstbyte, addrsecondbyte, addrthirdbyte, (byte)0x0f, pbBuf, length))
            //if (!iicRead(addressHigh, addressLow, pbBuf, length))
            {
                //FwUpdateMessage(L"recall i2c error failed", MSG_ERR);
                Update_log2 =Update_log2.concat("recall i2c error failed!") ;
                Update_log2 = Update_log2.concat("\n");
                return false;
            }
            if (!memCmp(pbBuf, wBuffer, offset, length)) {

                // FwUpdateMessage(L"Recall frame data fail,not equal.", MSG_ERR);
                //mMessage.setText("Recall frame data fail,not equal.");
                Update_log2 =Update_log2.concat("recall frame data fail,not equal") ;
                Update_log2 = Update_log2.concat("\n");
                return false;
            }
        }
        return true;

    }

    byte[] mGt9FirmwareData = new byte[88 * 1024 + 512];
    /**
    public void readFile() throws IOException {
        //打开文件输入流
        String filename = "///storage/emulated/0/Download/GT9110H_2002(A2E3).BIN";
        FileInputStream input = mContext.openFileInput(filename);
        //读取文件内容:
        input.read(mGt9FirmwareData);
        //关闭输入流
        input.close();
    }*/
    private boolean burnDspIsp() {

        // FwUpdateMessage(L"Set boot from sram", MSG_NOR);
        byte maddressHigh = (byte)0x41;
        byte maddressLow = (byte)0x90;   //_rRW_MISCTL__BOOTCTL_B0_  1
        byte msubcommand =0x0f ;  //no command
        byte mdata = (byte)0x02;

        if(!iicByteWrite(maddressHigh,maddressLow,msubcommand,mdata)) {

           // FwUpdateMessage(L"Set boot from sram failed", MSG_ERR);
            //mError.setText("Set boot from sram failed");
            Update_log = "Set boot from sram failed";
            mHandler.sendEmptyMessage(DEBUG_MESSAGE_ERROR);
            return false;
        }

        maddressHigh = (byte)0x41;
        maddressLow = (byte)0x84;   //_bWO_MISCTL__CPU_SWRST_PULSE  2
        msubcommand =0x0f ;  //no command
        mdata = (byte)0x01;

        if(!iicByteWrite(maddressHigh,maddressLow,msubcommand,mdata)) {
                    // FwUpdateMessage(L"Set boot from sram failed", MSG_ERR);
            //mError.setText("Software reboot failed");
            Update_log = "Software reboot failed";
            mHandler.sendEmptyMessage(DEBUG_MESSAGE_ERROR);
            return false;
        }

        maddressHigh = (byte)0x40;
        maddressLow = (byte)0x48;   //_bRW_MISCTL__SRAM_BANK   3
        msubcommand =0x0f ;  //no command
        mdata = (byte)0x02;

        if(!iicByteWrite(maddressHigh,maddressLow,msubcommand,mdata)) {
                        // FwUpdateMessage(L"Set boot from sram failed", MSG_ERR);
          //  mError.setText("select bank2 failed");
            Update_log = "select bank2 failed";
            mHandler.sendEmptyMessage(DEBUG_MESSAGE_ERROR);
            return false;
        }


        maddressHigh = (byte)0x40;
        maddressLow = (byte)0x49;   //_bRW_MISCTL__MEM_CD_EN   4
        msubcommand =0x0f ;  //no command
        mdata = (byte)0x01;

        if(!iicByteWrite(maddressHigh,maddressLow,msubcommand,mdata))
        {
                            // FwUpdateMessage(L"Set boot from sram failed", MSG_ERR);
           // mError.setText("enable accessing failed");
            Update_log = "enable accessing failed";
            mHandler.sendEmptyMessage(DEBUG_MESSAGE_ERROR);
            return false;
        }


        maddressHigh = (byte)0xC0;
        maddressLow = (byte)0x00;   //_bRW_MISCTL__SRAM_BANK   3
        //int mDspIsplength = 0x1000;

        //FileInputStream input = mContext.openFileInput("Gt9Firmware");
        // byte[] mGt9FirmwareData = new byte[88*1024+512];
        // StringBuilder sb = new StringBuilder("");
        // byte[] temp ;


        //读取文件内容:
        /**
         try {
         readFile();
         } catch (IOException e) {
         mMessage.setText("文件不存在!");
         // e.printStackTrace();
         }
         */

        ActivityCompat.requestPermissions(  FirmwareUpdate.this, new String[]{android
                .Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);   //申请权限，android6.0以上系统首次使用必须添加

        StringBuffer buffer = new StringBuffer();
        StringBuilder stringBuilder = new StringBuilder("");
        if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {

            try {

                //String filename = Environment.getExternalStorageDirectory() + "/Download/GT9110H_2002(A2E3).BIN";
                String filename = "GT9110H_2002(A2E3).BIN";
                //mError.setText(filename);
                //FileInputStream fis = new FileInputStream(filename);
                if(bottonMode == 4)
                {
                    filename = tv_edit_search_bin.getText().toString();
                    FileInputStream fw = new FileInputStream(filename);
                    //fw.read(mGt9FirmwareData);
                    fw.read(mGt293xFirmwareData);
                    fw.close();
                }
                else {

                    if(bottonMode == 3) {
                        InputStream config = getResources().openRawResource(R.raw.gt9110h_config_2018110802);
                        //InputStream config = getResources().openRawResource(R.raw.xinjian);\
                        config.read(mConfigData);

                        InputStream fis = getResources().openRawResource(R.raw.gt9110h_2002);
                        //gt9110h_config_20181108
                        fis.read(mGt9FirmwareData);

                        config.close();
                        fis.close();
                    }
                }
            } catch (FileNotFoundException e) {
                e.printStackTrace();
                Update_log = getResources().getString(R.string.invalidfile);
                mHandler.sendEmptyMessage(DEBUG_MESSAGE_ERROR);

                return false;
            }
            catch (IOException e) {
                e.printStackTrace();
                Update_log = "IOException";
                mHandler.sendEmptyMessage(DEBUG_MESSAGE_ERROR);

                return false;
            }

        }
        else{
            Update_log = getResources().getString(R.string.nopermission);
            mHandler.sendEmptyMessage(DEBUG_MESSAGE_ERROR);

            return false;
        }

        if (mGt9FirmwareData[1] == 0x01 && mGt9FirmwareData[2] == 0x60) {
            if (!iicWrite(maddressHigh, maddressLow, mGt9FirmwareData, FW_DSP_ISP_OFFSET, FW_DSP_ISP_LENGTH)) {
                // FwUpdateMessage(L"Set boot from sram failed", MSG_ERR);
               // mError.setText("burn 4k dsp_isp failed");
                Update_log = "burn 4k dsp_isp failed";
                mHandler.sendEmptyMessage(DEBUG_MESSAGE_ERROR);

                return false;

            } else {
                //mError.setText("burn 4k dsp_isp successed");
                Update_log = "burn 4k dsp_isp successed";
                mHandler.sendEmptyMessage(DEBUG_MESSAGE_ERROR);
            }
        } else {
           // mError.setText("get FW data error, burn 4k dsp_isp failed");
            Update_log = "get FW data error, burn 4k dsp_isp failed";
            mHandler.sendEmptyMessage(DEBUG_MESSAGE_ERROR);

            return false;
        }

        // if (!recallCheck(maddressHigh, maddressLow, mGt9FirmwareData, FW_DSP_ISP_OFFSET, FW_DSP_ISP_LENGTH)) {
        maddressHigh = (byte) 0xC0;
        maddressLow = (byte) 0x00;
        //if (!recallCheck(maddressHigh, maddressLow, mGt9FirmwareData, FW_DSP_ISP_OFFSET, 2500))
        //    {
        //    mError.setText("recall check error,burn 4k dsp_isp failed");
        //    return false;
        //}
        //else
        {
            //if (!recallCheck(maddressHigh, maddressLow, mGt9FirmwareData, FW_DSP_ISP_OFFSET+2500, 100))
            if (!recallCheck(maddressHigh, maddressLow, mGt9FirmwareData, FW_DSP_ISP_OFFSET, FW_DSP_ISP_LENGTH)) {
                //mError.setText("recall check error,burn 4k dsp_isp failed");
                Update_log = "recall check error,burn 4k dsp_isp failed";
                mHandler.sendEmptyMessage(DEBUG_MESSAGE_ERROR);
                return false;
            } else {
                //mError.setText("recall check success,burn 4k dsp_isp failed");
                Update_log = "recall check success,burn 4k dsp_isp success";
                mHandler.sendEmptyMessage(DEBUG_MESSAGE_ERROR);
                //return false;

            }
        }

        maddressHigh = (byte) 0x42;
        maddressLow = (byte) 0x18;   //_rRW_MISCTL__BOOT_OPT_B0_   4
        msubcommand = 0x0f;  //no command
        mdata = (byte) 0x00;

        if (!iicByteWrite(maddressHigh, maddressLow, msubcommand, mdata)) {
            //mError.setText("set scramble failed");
            Update_log = "set scramble failed";
            mHandler.sendEmptyMessage(DEBUG_MESSAGE_ERROR);
            return false;
        }

        maddressHigh = (byte) 0x40;
        maddressLow = (byte) 0x48;   //_bRW_MISCTL__SRAM_BANK   5
        msubcommand = 0x0f;  //no command
        mdata = (byte) 0x03;

        if (!iicByteWrite(maddressHigh, maddressLow, msubcommand, mdata)) {
            //mError.setText("select bank3 failed");
            Update_log = "select bank3 failed";
            mHandler.sendEmptyMessage(DEBUG_MESSAGE_ERROR);
            return false;
        }

        return true;

    }

    byte[] eraseBuf = new byte[0x800+0x1000];
    private boolean eraseBootLoader() {

        //memset(pBuf, 0xFF, 0x800);
        for (int i = 0; i < 0x1800; i++)
        {
            eraseBuf[i] = (byte)0xFF;
        }

        byte maddressHigh = (byte)0x41;
        byte maddressLow = (byte)0x80;  //_rRW_MISCTL__SWRST_B0_
        byte msubcommand =0x0f ;  //no command
        byte mdata = (byte)0x0C;

        if(!iicByteWrite(maddressHigh,maddressLow,msubcommand,mdata))
            return false;

        maddressHigh = (byte)0x42;
        maddressLow = (byte)0x18;  //_rRW_MISCTL__BOOT_OPT_B0_
        //byte msubcommand =0x0f ;  //no command
        mdata = (byte)0x00;

        if(!iicByteWrite(maddressHigh,maddressLow,msubcommand,mdata))
            return false;

        maddressHigh = (byte)0x41;
        maddressLow = (byte)0x80;  //_rRW_MISCTL__SWRST_B0_
        //byte msubcommand =0x0f ;  //no command
        mdata = (byte)0x04;

        if(!iicByteWrite(maddressHigh,maddressLow,msubcommand,mdata))
            return false;

        maddressHigh = (byte)0x40;
        maddressLow = (byte)0x48;  //_bRW_MISCTL__SRAM_BANK
        //byte msubcommand =0x0f ;  //no command
        mdata = (byte)0x03;

        if(!iicByteWrite(maddressHigh,maddressLow,msubcommand,mdata))
            return false;

        maddressHigh = (byte)0x90;
        maddressLow = (byte)0x00;
        //int mOffset = 0;
        // int mBootlength = 0x800;


       // iicWrite(maddressHigh,maddressLow,pBuf,0,0x800);
       if(! iicWrite(maddressHigh,maddressLow,eraseBuf,0,0x800))
        {
            // FwUpdateMessage(L"Set boot from sram failed", MSG_ERR);
         //   mError.setText("burn fw_boot failed");
            Update_log = "burn fw_boot failed";
            mHandler.sendEmptyMessage(DEBUG_MESSAGE_ERROR);
            return false;

        }
        else
        {
          //  mError.setText("burn fw_boot successed");
            Update_log = "burn fw_boot successed";
            mHandler.sendEmptyMessage(DEBUG_MESSAGE_ERROR);

        }
        SystemClock.sleep(1);

        maddressHigh = (byte)0x50;
        maddressLow = (byte)0x94;  //_rRW_MISCTL__BOOT_CTL_
        //byte msubcommand =0x0f ;  //no command
        mdata = (byte)0x06;

        if(!iicByteWrite(maddressHigh,maddressLow,msubcommand,mdata))
            return false;

        int nTryTimes = 1000;
        byte  bRet;
        maddressHigh = (byte)0x50;
        maddressLow = (byte)0x94;
        do
        {
            bRet = iicByteRead(maddressHigh,maddressLow);
            if (bRet == 0)
            {
                break;
            }
        }
        while ((--nTryTimes) != 0);

        if (nTryTimes == 0)
        {
            // FwUpdateMessage(L"move data to flash failed", MSG_ERR);
          //  mError.setText("[eraseBoot]move data to flash failed");
            Update_log = "[eraseBoot]move data to flash failed";
            mHandler.sendEmptyMessage(DEBUG_MESSAGE_ERROR);

            return false;
        }


        maddressHigh = (byte)0x90;
        maddressLow = (byte)0x00;
        if (!recallCheck(maddressHigh, maddressLow, eraseBuf, 0, 0x800)) {
                // mError.setText("recall check error,erase bootloader ");
                Update_log = "recall check error,erase bootloader ";
                mHandler.sendEmptyMessage(DEBUG_MESSAGE_ERROR);
                return false;
        } else {
                // mError.setText("recall check success,erase bootloader");
                Update_log = "recall check success,erase bootloader ";
                mHandler.sendEmptyMessage(DEBUG_MESSAGE_ERROR);
                //return false;

        }

        return true;
    }

    private boolean burnFwGwakeSection(int offSet, byte wAddresshigh,byte wAddresslow, int wLen, byte bBankCmd)
    {
        byte maddressHigh = (byte)0x41;
        byte maddressLow = (byte)0x80;  //_rRW_MISCTL__SWRST_B0_  hold dsp
        byte msubcommand =0x0f ;  //no command
        byte mdata = (byte)0x0c;

        if(!iicByteWrite(maddressHigh,maddressLow,msubcommand,mdata))
            return false;

        maddressHigh = (byte)0x42;
        maddressLow = (byte)0x18;  //_rRW_MISCTL__BOOT_OPT_B0_
        //byte msubcommand =0x0f ;  //no command
        mdata = (byte)0x00;

        if(!iicByteWrite(maddressHigh,maddressLow,msubcommand,mdata))
            return false;

        maddressHigh = (byte)0x41;
        maddressLow = (byte)0x80;  //_rRW_MISCTL__SWRST_B0_  release dsp
        //byte msubcommand =0x0f ;  //no command
        mdata = (byte)0x04;

        if(!iicByteWrite(maddressHigh,maddressLow,msubcommand,mdata))
            return false;

        SystemClock.sleep(1);

        byte bank =  (byte)((bBankCmd >> 4) & 0x0F);
        maddressHigh = (byte)0x40;
        maddressLow = (byte)0x48;  //_rRW_MISCTL__SWRST_B0_  release dsp
        //byte msubcommand =0x0f ;  //no command
        mdata = bank;

        if(!iicByteWrite(maddressHigh,maddressLow,msubcommand,mdata))
            return false;

       // int mOffset = 0x00;
        Update_log2="";
        if(! iicWrite(wAddresshigh,wAddresslow,mGt9FirmwareData,offSet,wLen))
        {
            // FwUpdateMessage(L"Set boot from sram failed", MSG_ERR);
          //  mError.setText("burn [fwGwOrLink] section failed");
            Update_log2 = "burn [fwGwOrLink] section failed\n";
           // mHandler.sendEmptyMessage(DEBUG_MESSAGE_ERROR);
            return false;

        }
        else
        {
           // mError.setText("burn [fwGwOrLink] section successed");
            Update_log2 =Update_log2.concat("burn [fwGwOrLink] section successed\n") ;
         //   mHandler.sendEmptyMessage(DEBUG_MESSAGE_ERROR);

        }

        maddressHigh = (byte)0x50;
        maddressLow = (byte)0x94;  //_rRW_MISCTL__SWRST_B0_  release dsp
        //byte msubcommand =0x0f ;  //no command
        mdata = (byte)(bBankCmd & 0x0f);

        if(!iicByteWrite(maddressHigh,maddressLow,msubcommand,mdata))
            return false;


        int nTryTimes = 1000;
        byte  bRet;
        maddressHigh = (byte)0x50;
        maddressLow = (byte)0x94;
        do
        {
            bRet = iicByteRead(maddressHigh,maddressLow);
            if (bRet == 0)
            {
                break;
            }
        }
        while ((--nTryTimes) != 0);

        if (nTryTimes == 0)
        {
           // FwUpdateMessage(L"move data to flash failed", MSG_ERR);
           // mError.setText("[fwGwOrLink]move data to flash failed");
            //Update_log = "[fwGwOrLink]move data to flash failed";
            Update_log2 =Update_log2.concat("[fwGwOrLink]move data to flash failed\n") ;
            //mHandler.sendEmptyMessage(DEBUG_MESSAGE_ERROR);
            return false;
        }
        if (!recallCheck(wAddresshigh,wAddresslow,mGt9FirmwareData,offSet,wLen)) {
            //mError.setText("recall check error[fwGwOrLink] ");
            Update_log2 =Update_log2.concat("recall check error[fwGwOrLink]\n") ;
            //mHandler.sendEmptyMessage(DEBUG_MESSAGE_ERROR);
            return false;
        } else {
           // mError.setText("recall check success[fwGwOrLink]");
           // Update_log = "recall check success[fwGwOrLink]";
            Update_log2 =Update_log2.concat("recall check success[fwGwOrLink]\n") ;
           // mHandler.sendEmptyMessage(DEBUG_MESSAGE_ERROR);
            //return false;
        }
       // FwUpdateMessage(L"move data to flash complete......", MSG_NOR);
     //   mError.setText("[fwGwOrLink]move data to flash complete");
       // Update_log = "[fwGwOrLink]move data to flash complete";
       // mHandler.sendEmptyMessage(DEBUG_MESSAGE_ERROR);

        Update_log2 =Update_log2.concat("[fwGwOrLink]move data to flash complete\n") ;

        return true;
    }
    private boolean burnFwGwake() {


        byte maddressHigh = (byte)0x50;
        byte maddressLow = (byte)0x94;  //_rRW_MISCTL__SWRST_B0_
        byte msubcommand =0x0f ;  //no command
        byte mdata = (byte)0x00;

        if(!iicByteWrite(maddressHigh,maddressLow,msubcommand,mdata))
            return false;

        //burnFwGwakeSection(mGt9FirmwareData,FW_GWAKE_OFFSET, 0x90,0x00, FW_SECTION_LENGTH,0x3A);
        maddressHigh = (byte)0x90;
        maddressLow = (byte)0x00;
        mdata = (byte)0x3A;
        if (!burnFwGwakeSection(FW_GWAKE_OFFSET, maddressHigh,maddressLow, FW_SECTION_LENGTH,mdata))
        {
           // FwUpdateMessage(L"[update gwake]Begin burn seciton1 failed", MSG_ERR);
         //   mError.setText("[fwGw]Begin burn seciton1 failed");
            Update_log = "[fwGw]Begin burn seciton1 failed";
            mHandler.sendEmptyMessage(DEBUG_MESSAGE_ERROR);
            return false;
        }
        else
        {
           // FwUpdateMessage(L"[update gwake]Begin burn seciton1 seccessfully", MSG_NOR);
           // mError.setText("[fwGw]Begin burn seciton1 seccessfully");
            Update_log = "[fwGw]Begin burn seciton1 seccessfully";
            mHandler.sendEmptyMessage(DEBUG_MESSAGE_ERROR);
        }

        // FwUpdateMessage(L"[update gwake]Begin burn seciton2", MSG_NOR);
        mdata = (byte)0x3B;
        if (!burnFwGwakeSection(FW_GWAKE_OFFSET+FW_SECTION_LENGTH, maddressHigh,maddressLow, FW_SECTION_LENGTH,mdata))
        {
           // FwUpdateMessage(L"[update gwake]Begin burn seciton2 failed", MSG_ERR);
           // mError.setText("[update gwake]Begin burn seciton2 failed");
            Update_log = "[update gwake]Begin burn seciton2 failed";
            mHandler.sendEmptyMessage(DEBUG_MESSAGE_ERROR);
            return false;
        }
        else
        {
           // FwUpdateMessage(L"[update gwake]Begin burn seciton2 seccessfully", MSG_NOR);
          //  mError.setText("[update gwake]Begin burn seciton2 seccessfully");
            Update_log = "[update gwake]Begin burn seciton2 seccessfully";
            mHandler.sendEmptyMessage(DEBUG_MESSAGE_ERROR);
        }

        //FwUpdateMessage(L"[update gwake]Begin burn seciton3", MSG_NOR);
        mdata = (byte)0x3C;
        if (!burnFwGwakeSection(FW_GWAKE_OFFSET+FW_SECTION_LENGTH*2, maddressHigh,maddressLow, FW_SECTION_LENGTH,mdata))
        {
           // FwUpdateMessage(L"[update gwake]Begin burn seciton3 failed", MSG_ERR);
          //  mError.setText("[update gwake]Begin burn seciton3 failed");
            Update_log = "[update gwake]Begin burn seciton3 failed";
            mHandler.sendEmptyMessage(DEBUG_MESSAGE_ERROR);
            return false;
        }
        else
        {
            //FwUpdateMessage(L"[update gwake]Begin burn seciton3 seccessfully", MSG_NOR);
           // mError.setText("[update gwake]Begin burn seciton3 seccessfully");
            Update_log = "[update gwake]Begin burn seciton3 seccessfully";
            mHandler.sendEmptyMessage(DEBUG_MESSAGE_ERROR);
        }

        //FwUpdateMessage(L"[update gwake]Begin burn seciton4", MSG_NOR);
        mdata = (byte)0x3D;
        if (!burnFwGwakeSection(FW_GWAKE_OFFSET+FW_SECTION_LENGTH*3, maddressHigh,maddressLow, FW_SECTION_LENGTH,mdata))
        {
           // FwUpdateMessage(L"[update gwake]Begin burn seciton4 failed", MSG_ERR);
            //mError.setText("[update gwake]Begin burn seciton4 failed");
            Update_log = "[update gwake]Begin burn seciton4 failed";
            mHandler.sendEmptyMessage(DEBUG_MESSAGE_ERROR);
            return false;
        }
        else
        {
            //FwUpdateMessage(L"[update gwake]Begin burn seciton4 seccessfully", MSG_NOR);
            //mError.setText("[update gwake]Begin burn seciton4 seccessfully");
            Update_log = "[update gwake]Begin burn seciton4 seccessfully";
            mHandler.sendEmptyMessage(DEBUG_MESSAGE_ERROR);

        }

        //FwUpdateMessage(L"[update gwake]burn gwake firmware seccessfully----<<", MSG_NOR);
       // mError.setText("[update gwake]burn gwake firmware seccessfully----<<");
        Update_log = "[update gwake]burn gwake firmware seccessfully----<<";
        mHandler.sendEmptyMessage(DEBUG_MESSAGE_ERROR);

        return true;
    }

    private boolean burnFwSection(byte[] wBuffer,int offSet, byte wAddresshigh,byte wAddresslow, int wLen, byte bBankCmd)
    {
        byte maddressHigh = (byte)0x41;
        byte maddressLow = (byte)0x80;  //_rRW_MISCTL__SWRST_B0_  hold dsp
        byte msubcommand =0x0f ;  //no command
        byte mdata = (byte)0x0c;

        if(!iicByteWrite(maddressHigh,maddressLow,msubcommand,mdata))
            return false;

        maddressHigh = (byte)0x42;
        maddressLow = (byte)0x18;  //_rRW_MISCTL__BOOT_OPT_B0_
        //byte msubcommand =0x0f ;  //no command
        mdata = (byte)0x00;

        if(!iicByteWrite(maddressHigh,maddressLow,msubcommand,mdata))
            return false;
/**
        maddressHigh = (byte)0x41;
        maddressLow = (byte)0x80;  //_rRW_MISCTL__SWRST_B0_  release dsp
        //byte msubcommand =0x0f ;  //no command
        mdata = (byte)0x04;

        if(!iicByteWrite(maddressHigh,maddressLow,msubcommand,mdata))
            return false;
 */

        byte bank =  (byte)((bBankCmd >> 4) & 0x0F);
        maddressHigh = (byte)0x40;
        maddressLow = (byte)0x48;  //_rRW_
        mdata = bank;

        if(!iicByteWrite(maddressHigh,maddressLow,msubcommand,mdata))
            return false;

        maddressHigh = (byte)0x40;
        maddressLow = (byte)0x49;  //_rRW_
        mdata =(byte)0x01;

        if(!iicByteWrite(maddressHigh,maddressLow,msubcommand,mdata))
            return false;

        // int mOffset = 0x00;
        Update_log2= "";
        if(! iicWrite(wAddresshigh,wAddresslow,wBuffer,offSet,wLen))
        {
            // FwUpdateMessage(L"Set boot from sram failed", MSG_ERR);
           // mError.setText("burn fw51 section failed");
            Update_log2 = "burn fw51 section failed\n";
            //mHandler.sendEmptyMessage(DEBUG_MESSAGE_ERROR);
            return false;

        }
        else
        {
          //  mError.setText("burn fw51 section successed");
            Update_log2 = "burn fw51 section successed\n";
           // mHandler.sendEmptyMessage(DEBUG_MESSAGE_ERROR);
        }

        maddressHigh = (byte)0x41;
        maddressLow = (byte)0x80;  //_rRW_MISCTL__SWRST_B0_  release dsp
        mdata = (byte)(0x04);

        if(!iicByteWrite(maddressHigh,maddressLow,msubcommand,mdata))
            return false;

        SystemClock.sleep(1);

        maddressHigh = (byte)0x50;
        maddressLow = (byte)0x94;  //_rRW_MISCTL__SWRST_B0_  release dsp
        //byte msubcommand =0x0f ;  //no command
        mdata = (byte)(bBankCmd & 0x0f);

        if(!iicByteWrite(maddressHigh,maddressLow,msubcommand,mdata))
            return false;


        int nTryTimes = 1000;
        byte  bRet;
        maddressHigh = (byte)0x50;
        maddressLow = (byte)0x94;
        do
        {
            bRet = iicByteRead(maddressHigh,maddressLow);
            if (bRet == 0)
            {
                break;
            }
        }
        while ((--nTryTimes) != 0);

        if (nTryTimes == 0)
        {
            // FwUpdateMessage(L"move data to flash failed", MSG_ERR);
           // mError.setText("[fw51]move data to flash failed");
           // Update_log = "[fw51]move data to flash failed";
           // mHandler.sendEmptyMessage(DEBUG_MESSAGE_ERROR);
            Update_log2 =Update_log2.concat("[fw51]move data to flash failed\n") ;
            return false;
        }


        maddressHigh = (byte)0x40;
        maddressLow = (byte)0x48;  //_rRW_
        mdata = (byte)((bBankCmd >> 4) & 0x0F);
        if(!iicByteWrite(maddressHigh,maddressLow,msubcommand,mdata))
            return false;

        maddressHigh = (byte)0x40;
        maddressLow = (byte)0x49;  //_rRW_
        mdata = (byte)(0x01);
        if(!iicByteWrite(maddressHigh,maddressLow,msubcommand,mdata))
            return false;

        if (!recallCheck(wAddresshigh,wAddresslow,wBuffer,offSet,wLen)) {
           // mError.setText("recall check error[fw51] ");
           // Update_log = "recall check error[fw51] ";
           // mHandler.sendEmptyMessage(DEBUG_MESSAGE_ERROR);

            Update_log2 =Update_log2.concat("[fw51]move data to flash failed\n") ;
            return false;
        } else {
          //  mError.setText("recall check success[fw51]");
           // Update_log = "recall check success[fw51] ";
           // mHandler.sendEmptyMessage(DEBUG_MESSAGE_ERROR);

            Update_log2 =Update_log2.concat("recall check success[fw51]\n") ;
            //return false;
        }
        // FwUpdateMessage(L"move data to flash complete......", MSG_NOR);

        maddressHigh = (byte)0x40;
        maddressLow = (byte)0x49;  //_rRW_
        mdata = (byte)(0x00);
        if(!iicByteWrite(maddressHigh,maddressLow,msubcommand,mdata))
            return false;

      //  mError.setText("[fw51]move data to flash complete");
       // Update_log = "[fw51]move data to flash complete ";
       // mHandler.sendEmptyMessage(DEBUG_MESSAGE_ERROR);
        Update_log2 =Update_log2.concat("[fw51]move data to flash complete\n") ;

        return true;
    }

    private boolean burnFwSS51() {

       // FwUpdateMessage(L"[update SS51]Begin burn ss51 firmware---->>", MSG_NOR);

       // FwUpdateMessage(L"[update SS51]Clear burn flag", MSG_NOR);

        byte maddressHigh = (byte)0x50;
        byte maddressLow = (byte)0x94;  //_rRW_MISCTL__SWRST_B0_
        byte msubcommand =0x0f ;  //no command
        byte mdata = (byte)0x00;

        if(!iicByteWrite(maddressHigh,maddressLow,msubcommand,mdata))
            return false;

        maddressHigh = (byte)0xC0;
        maddressLow = (byte)0x00;
        mdata = (byte)0x01;
        // FwUpdateMessage(L"[update SS51]Begin burn seciton1", MSG_NOR);
        if (!burnFwSection(mGt9FirmwareData,FW_SS51_OFFSET, maddressHigh,maddressLow, FW_SECTION_LENGTH,mdata))
        {
           // FwUpdateMessage(L"[update SS51]Begin burn seciton1 failed", MSG_ERR);
            //mShow.setText("[update SS51]Begin burn seciton1 failed");
            Update_log = "[update SS51]Begin burn seciton1 failed ";
            mHandler.sendEmptyMessage(DEBUG_MESSAGE_ERROR);
            return false;
        }
        else
        {
            //FwUpdateMessage(L"[update SS51]Begin burn seciton1 seccessfully", MSG_NOR);
           // mShow.setText("[update SS51]Begin burn seciton1 seccessfully");
            Update_log = "[update SS51]Begin burn seciton1 seccessfully ";
            mHandler.sendEmptyMessage(DEBUG_MESSAGE_ERROR);
        }

        maddressHigh = (byte)0xE0;
        maddressLow = (byte)0x00;
        mdata = (byte)0x02;
        // FwUpdateMessage(L"[update SS51]Begin burn seciton2", MSG_NOR);
        if (!burnFwSection(mGt9FirmwareData,FW_SS51_OFFSET+FW_SECTION_LENGTH, maddressHigh,maddressLow, FW_SECTION_LENGTH,mdata))
        {
            // FwUpdateMessage(L"[update SS51]Begin burn seciton1 failed", MSG_ERR);
          //  mShow.setText("[update SS51]Begin burn seciton2 failed");
            return false;
        }
        else
        {
            //FwUpdateMessage(L"[update SS51]Begin burn seciton1 seccessfully", MSG_NOR);
          //  mShow.setText("[update SS51]Begin burn seciton2 seccessfully");
        }

        maddressHigh = (byte)0xC0;
        maddressLow = (byte)0x00;
        mdata = (byte)0x13;
        // FwUpdateMessage(L"[update SS51]Begin burn seciton2", MSG_NOR);
        if (!burnFwSection(mGt9FirmwareData,FW_SS51_OFFSET+FW_SECTION_LENGTH*2, maddressHigh,maddressLow, FW_SECTION_LENGTH,mdata))
        {
            // FwUpdateMessage(L"[update SS51]Begin burn seciton1 failed", MSG_ERR);
           // mShow.setText("[update SS51]Begin burn seciton3 failed");
            return false;
        }
        else
        {
            //FwUpdateMessage(L"[update SS51]Begin burn seciton1 seccessfully", MSG_NOR);
           // mShow.setText("[update SS51]Begin burn seciton3 seccessfully");
        }

        maddressHigh = (byte)0xE0;
        maddressLow = (byte)0x00;
        mdata = (byte)0x14;
        // FwUpdateMessage(L"[update SS51]Begin burn seciton2", MSG_NOR);
        if (!burnFwSection(mGt9FirmwareData,FW_SS51_OFFSET+FW_SECTION_LENGTH*3, maddressHigh,maddressLow, FW_SECTION_LENGTH,mdata))
        {
            // FwUpdateMessage(L"[update SS51]Begin burn seciton1 failed", MSG_ERR);
           // mShow.setText("[update SS51]Begin burn seciton4 failed");
            return false;
        }
        else
        {
            //FwUpdateMessage(L"[update SS51]Begin burn seciton1 seccessfully", MSG_NOR);
          //  mShow.setText("[update SS51]Begin burn seciton4 seccessfully");
        }

       // FwUpdateMessage(L"[update SS51]burn ss51 firmware seccessfully----<<", MSG_NOR);
        //mShow.setText("[update SS51]burn ss51 firmware seccessfully----<<");
        return true;
    }

    private boolean burnFwDSP() {
       // FwUpdateMessage(L"[update DSP]Begin burn dsp firmware---->>", MSG_NOR);

       // FwUpdateMessage(L"[update DSP]hold ss51 & dsp", MSG_NOR);
        byte maddressHigh = (byte)0x41;
        byte maddressLow = (byte)0x80;  //_rRW_MISCTL__SWRST_B0_
        byte msubcommand =0x0f ;  //no command
        byte mdata = (byte)0x0c;

        if(!iicByteWrite(maddressHigh,maddressLow,msubcommand,mdata))
            return false;


        // FwUpdateMessage(L"[update DSP]set scramble", MSG_NOR);
        maddressHigh = (byte)0x42;
        maddressLow = (byte)0x18;  //_rRW_MISCTL__SWRST_B0_
        //byte msubcommand =0x0f ;  //no command
        mdata = (byte)0x00;

        if(!iicByteWrite(maddressHigh,maddressLow,msubcommand,mdata))
            return false;


        // FwUpdateMessage(L"[update DSP]hold ss51 & release dsp", MSG_NOR);

         maddressHigh = (byte)0x41;
         maddressLow = (byte)0x80;  //_rRW_MISCTL__SWRST_B0_
       // byte msubcommand =0x0f ;  //no command
         mdata = (byte)0x04;

        if(!iicByteWrite(maddressHigh,maddressLow,msubcommand,mdata))
            return false;


        // FwUpdateMessage(L"[update DSP]select bank3", MSG_NOR);
        maddressHigh = (byte)0x40;
        maddressLow = (byte)0x48;  //_rRW_MISCTL__SWRST_B0_
        // byte msubcommand =0x0f ;  //no command
        mdata = (byte)0x03;

        if(!iicByteWrite(maddressHigh,maddressLow,msubcommand,mdata))
            return false;

        maddressHigh = (byte)0x90;
        maddressLow = (byte)0x00;  //_rRW_MISCTL__SWRST_B0_
        // byte msubcommand =0x0f ;  //no command
        mdata = (byte)0x03;
        // FwUpdateMessage(L"[update DSP]burn 4k dsp firmware", MSG_NOR);
        //if (!m_pI2CDevice->I2CWrite(0x9000, m_pbBuf + FW_DSP_OFFSET, FW_DSP_LENGTH))
        if(!iicWrite(maddressHigh,maddressLow,mGt9FirmwareData,FW_DSP_OFFSET,FW_DSP_LENGTH))
        {
           // FwUpdateMessage(L"[update DSP]burn 4k dsp firmware failed", MSG_ERR);
          //  mError.setText("[update DSP]burn 4k dsp firmware failed");
            Update_log = "[update DSP]burn 4k dsp firmware failed";
            mHandler.sendEmptyMessage(DEBUG_MESSAGE_ERROR);
            return false;
        }

        //Sleep(1);
        SystemClock.sleep(1);
        //FwUpdateMessage(L"[update DSP]send burn cmd to move data to flash from sram", MSG_NOR);
        maddressHigh = (byte)0x50;
        maddressLow = (byte)0x94;  //_rRW_MISCTL__SWRST_B0_
        // byte msubcommand =0x0f ;  //no command
        mdata = (byte)0x05;

        if(!iicByteWrite(maddressHigh,maddressLow,msubcommand,mdata)) {
            return false;
        }

        // FwUpdateMessage(L"[update DSP]Wait for the burn is complete......", MSG_NOR);

        int nTryTimes = 1000;
        maddressHigh = (byte)0x50;
        maddressLow = (byte)0x94;  //_rRW_MISCTL__SWRST_B0_
        do
        {
            if (iicByteRead(maddressHigh,maddressLow)== 0)
            {
                break;
            }
        }
        while (nTryTimes-- != 0);

        if (nTryTimes == 0)
        {
           // FwUpdateMessage(L"[update DSP]move data to flash failed", MSG_ERR);
           // mError.setText("[update DSP]move data to flash failed");
            Update_log = "[update DSP]move data to flash failed";
            mHandler.sendEmptyMessage(DEBUG_MESSAGE_ERROR);
            return false;
        }
        else{
            Update_log = "[update DSP]move data to flash success";
            mHandler.sendEmptyMessage(DEBUG_MESSAGE_ERROR);
        }

        //FwUpdateMessage(L"[update DSP]recall check 4k dsp firmware", MSG_NOR);
        // if (!RecallCheck(m_pbBuf + FW_DSP_OFFSET, 0x9000, FW_DSP_LENGTH))
        {
            // FwUpdateMessage(L"[update DSP]recall check 4k dsp firmware failed", MSG_ERR);
            // return false;
        }
        maddressHigh = (byte)0x90;
        maddressLow = (byte)0x00;  //_rRW_MISCTL__SWRST_B0_
        if (!recallCheck(maddressHigh,maddressLow,mGt9FirmwareData,FW_DSP_OFFSET,FW_DSP_LENGTH)) {
            //mError.setText("recall check error[fwDSP] ");
            Update_log = "recall check error[fwDSP] ";
            mHandler.sendEmptyMessage(DEBUG_MESSAGE_ERROR);
            return false;
        } else {
        //    mError.setText("recall check success[fwDSP]");
            Update_log = "recall check success[fwDSP]";
            mHandler.sendEmptyMessage(DEBUG_MESSAGE_ERROR);
            //return false;
        }
       // FwUpdateMessage(L"[update DSP]burn DSP firmware seccessfully----<<", MSG_NOR);
        //mError.setText("[update DSP]burn DSP firmware seccessfully----<<");
        Update_log = "[update DSP]burn DSP firmware seccessfully----<<";
        mHandler.sendEmptyMessage(DEBUG_MESSAGE_ERROR);

        return true;
    }

    private boolean burnFwLink() {


        // if (FW_GLINK_OFFSET > m_nBinFileLen)
        {
            //  FwUpdateMessage(L"[update Link]needn`t burn Link", MSG_NOR);
            //   return true;
        }

        // FwUpdateMessage(L"[update Link]Begin burn link firmware---->>", MSG_NOR);

        // FwUpdateMessage(L"[update Link]Clear burn flag", MSG_NOR);
        byte maddressHigh = (byte)0x50;
        byte maddressLow = (byte)0x94;  //_rRW_MISCTL__SWRST_B0_
        byte msubcommand =0x0f ;  //no command
        byte mdata = (byte)0x00;

        if(!iicByteWrite(maddressHigh,maddressLow,msubcommand,mdata))
            return false;


        // FwUpdateMessage(L"[update Link]Begin burn seciton1", MSG_NOR);
        maddressHigh = (byte)0x90;
        maddressLow = (byte)0x00;
        mdata = (byte)0x38;
       // if (!BurnFwGwakeSection(m_pbBuf + FW_GLINK_OFFSET, 0x9000, FW_SECTION_LENGTH, 0x38))
        if(!burnFwGwakeSection(FW_GLINK_OFFSET,maddressHigh,maddressLow,FW_SECTION_LENGTH,mdata))
        {
           // FwUpdateMessage(L"[update Link]Begin burn seciton1 failed", MSG_ERR);
           // mError.setText("[update Link]Begin burn seciton1 failed");
            Update_log = "[update Link]Begin burn seciton1 failed";
            mHandler.sendEmptyMessage(DEBUG_MESSAGE_ERROR);
            return false;
        }
        else
        {
           // FwUpdateMessage(L"[update Link]Begin burn seciton1 seccessfully", MSG_NOR);
           // mError.setText("[update Link]Begin burn seciton1 seccessfully");
            Update_log = "[update Link]Begin burn seciton1 seccessfully";
            mHandler.sendEmptyMessage(DEBUG_MESSAGE_ERROR);
        }

        //  FwUpdateMessage(L"[update Link]Begin burn seciton2", MSG_NOR);

        maddressHigh = (byte)0x90;
        maddressLow = (byte)0x00;
        mdata = (byte)0x39;
        // if (!BurnFwGwakeSection(m_pbBuf + FW_GLINK_OFFSET, 0x9000, FW_SECTION_LENGTH, 0x38))
        if(!burnFwGwakeSection(FW_GLINK_OFFSET+FW_SECTION_LENGTH,maddressHigh,maddressLow,FW_GLINK_LENGTH -FW_SECTION_LENGTH,mdata))
        {
            // FwUpdateMessage(L"[update Link]Begin burn seciton1 failed", MSG_ERR);
           // mError.setText("[update Link]Begin burn seciton2 failed");
            Update_log = "[update Link]Begin burn seciton2 failed";
            mHandler.sendEmptyMessage(DEBUG_MESSAGE_ERROR);
            return false;
        }
        else
        {
            // FwUpdateMessage(L"[update Link]Begin burn seciton1 seccessfully", MSG_NOR);
           // mError.setText("[update Link]Begin burn seciton2 seccessfully");
            Update_log = "[update Link]Begin burn seciton2 seccessfully";
            mHandler.sendEmptyMessage(DEBUG_MESSAGE_ERROR);
        }

       // FwUpdateMessage(L"[update Link]burn link firmware seccessfully----<<", MSG_NOR);
       // mError.setText("[update Link]burn link firmware seccessfully----<<");
        Update_log = "[update Link]burn link firmware seccessfully----<<";
        mHandler.sendEmptyMessage(DEBUG_MESSAGE_ERROR);
        return true;
    }

    private boolean burnFwBoot() {
        //  FwUpdateMessage(L"[update bootloader]Begin burn bootloader firmware---->>.", MSG_NOR);

        // FwUpdateMessage(L"[update bootloader]hold ss51 & dsp", MSG_NOR);
        byte maddressHigh = (byte)0x41;
        byte maddressLow = (byte)0x80;  //_rRW_MISCTL__SWRST_B0_
        byte msubcommand =0x0f ;  //no command
        byte mdata = (byte)0x0c;

        if(!iicByteWrite(maddressHigh,maddressLow,msubcommand,mdata))
            return false;

        // FwUpdateMessage(L"[update bootloader]set scramble", MSG_NOR);

        maddressHigh = (byte)0x42;
        maddressLow = (byte)0x18;  //_rRW_MISCTL__SWRST_B0_
        //byte msubcommand =0x0f ;  //no command
        mdata = (byte)0x00;

        if(!iicByteWrite(maddressHigh,maddressLow,msubcommand,mdata))
            return false;

        //FwUpdateMessage(L"[update bootloader]hold ss51 & release dsp", MSG_NOR);
        maddressHigh = (byte)0x41;
        maddressLow = (byte)0x80;  //_rRW_MISCTL__SWRST_B0_
        //byte msubcommand =0x0f ;  //no command
        mdata = (byte)0x04;

        if(!iicByteWrite(maddressHigh,maddressLow,msubcommand,mdata))
            return false;


        // FwUpdateMessage(L"[update bootloader]select bank3", MSG_NOR);
        maddressHigh = (byte)0x40;
        maddressLow = (byte)0x48;  //_rRW_MISCTL__SWRST_B0_
        //byte msubcommand =0x0f ;  //no command
        mdata = (byte)0x03;

        if(!iicByteWrite(maddressHigh,maddressLow,msubcommand,mdata))
            return false;

        maddressHigh = (byte)0x90;
        maddressLow = (byte)0x00;  //_rRW_MISCTL__SWRST_B0_
        // FwUpdateMessage(L"[update bootloader]burn 2k bootloader firmware", MSG_NOR);
        // if (!m_pI2CDevice->I2CWrite(0x9000, m_pbBuf + FW_BOOT_OFFSET, FW_BOOT_LENGTH))
        if(!iicWrite(maddressHigh,maddressLow,mGt9FirmwareData,FW_BOOT_OFFSET,FW_BOOT_LENGTH))
        {
            //  FwUpdateMessage(L"[update bootloader]burn fw_boot failed", MSG_ERR);
            return false;
        }
        // Sleep(1);
        SystemClock.sleep(1);
        // FwUpdateMessage(L"[update bootloader]send burn cmd to move data to flash from sram", MSG_NOR);
        maddressHigh = (byte)0x50;
        maddressLow = (byte)0x94;  //_rRW_MISCTL__SWRST_B0_
        //byte msubcommand =0x0f ;  //no command
        mdata = (byte)0x06;

        if(!iicByteWrite(maddressHigh,maddressLow,msubcommand,mdata))
            return false;


        // FwUpdateMessage(L"[update bootloader]Wait for the burn is complete......", MSG_NOR);
        maddressHigh = (byte)0x50;
        maddressLow = (byte)0x94;
        int nTryTimes = 1000;
        do
        {
            //if (m_pI2CDevice->I2CByteRead(_rRW_MISCTL__BOOT_CTL_) == 0)
            if(iicByteRead(maddressHigh,maddressLow) == 0)
            {
                break;
            }
        }
        while ((--nTryTimes) != 0);

        if (nTryTimes == 0)
        {
           // FwUpdateMessage(L"[update bootloader]move data to flash failed", MSG_ERR);
            //mError.setText("[update bootloader]move data to flash failed");
            Update_log = "[update bootloader]move data to flash failed";
            mHandler.sendEmptyMessage(DEBUG_MESSAGE_ERROR);
            return false;
        }

        maddressHigh = (byte)0x90;
        maddressLow = (byte)0x00;  //_rRW_MISCTL__SWRST_B0_
        if (!recallCheck(maddressHigh,maddressLow,mGt9FirmwareData,FW_BOOT_OFFSET,FW_BOOT_LENGTH)) {
            //mError.setText("recall check error[fwBoot] ");
            //mError.setText("[update bootloader]move data to flash failed");
            Update_log = "recall check error[fwBoot] ";
            mHandler.sendEmptyMessage(DEBUG_MESSAGE_ERROR);
            return false;
        } else {
           // mError.setText("recall check success[fwBoot]");
            Update_log = "recall check success[fwBoot] ";
            mHandler.sendEmptyMessage(DEBUG_MESSAGE_ERROR);
            //return false;
        }
        // FwUpdateMessage(L"[update bootloader]recall check 2k bootloader firmware", MSG_NOR);
        //if (!RecallCheck(m_pbBuf + FW_BOOT_OFFSET, 0x9000, FW_BOOT_LENGTH))
        {
            //  FwUpdateMessage(L"[update bootloader]recall check 2k bootloader firmware failed", MSG_ERR);
            // return false;
        }

       // FwUpdateMessage(L"[update bootloader]burn bootloader firmware seccessfully----<<", MSG_NOR);
       // mError.setText("[[update bootloader]burn bootloader firmware seccessfully----<<");
        Update_log = "[update bootloader]burn bootloader firmware seccessfully----<< ";
        mHandler.sendEmptyMessage(DEBUG_MESSAGE_ERROR);

        return true;
    }

    private boolean burnFwBootIsp() {
        // if (FW_BOOT_ISP_OFFSET > m_nBinFileLen)
        {
            //   FwUpdateMessage(L"[update boot_isp]needn`t burn boot_isp", MSG_NOR);
            //   return true;
        }

        // FwUpdateMessage(L"[update bootisp]Begin burn boot_isp firmware---->>", MSG_NOR);

        // FwUpdateMessage(L"[update bootisp]hold ss51 & dsp", MSG_NOR);
        byte maddressHigh = (byte)0x41;
        byte maddressLow = (byte)0x80;  //_rRW_MISCTL__SWRST_B0_
        byte msubcommand =0x0f ;  //no command
        byte mdata = (byte)0x0c;

        if(!iicByteWrite(maddressHigh,maddressLow,msubcommand,mdata))
            return false;


        //FwUpdateMessage(L"[update bootisp]set scramble", MSG_NOR);
        maddressHigh = (byte)0x42;
        maddressLow = (byte)0x18;  //_rRW_MISCTL__SWRST_B0_
        //byte msubcommand =0x0f ;  //no command
        mdata = (byte)0x00;

        if(!iicByteWrite(maddressHigh,maddressLow,msubcommand,mdata))
            return false;


        //  FwUpdateMessage(L"[update bootisp]hold ss51 & release dsp", MSG_NOR);
        maddressHigh = (byte)0x41;
        maddressLow = (byte)0x80;  //_rRW_MISCTL__SWRST_B0_
        //byte msubcommand =0x0f ;  //no command
        mdata = (byte)0x04;

        if(!iicByteWrite(maddressHigh,maddressLow,msubcommand,mdata))
            return false;

        // FwUpdateMessage(L"[update bootisp]select bank3", MSG_NOR);
        maddressHigh = (byte)0x40;
        maddressLow = (byte)0x48;  //_rRW_MISCTL__SWRST_B0_
        //byte msubcommand =0x0f ;  //no command
        mdata = (byte)0x03;

        if(!iicByteWrite(maddressHigh,maddressLow,msubcommand,mdata))
            return false;


        // FwUpdateMessage(L"[update bootisp]burn 2k bootloader firmware", MSG_NOR);
        //if (!m_pI2CDevice->I2CWrite(0x9000, m_pbBuf + FW_BOOT_ISP_OFFSET, FW_BOOT_ISP_LENGTH))
        maddressHigh = (byte)0x90;
        maddressLow = (byte)0x00;
        if(!iicWrite(maddressHigh,maddressLow,mGt9FirmwareData,FW_BOOT_ISP_OFFSET,FW_BOOT_ISP_LENGTH))
        {
            //FwUpdateMessage(L"[update bootisp]burn fw_boot failed", MSG_ERR);
            //mError.setText("[update bootisp]burn fw_boot failed");
            Update_log = "[update bootisp]burn fw_boot failed";
            mHandler.sendEmptyMessage(DEBUG_MESSAGE_ERROR);
            return false;
        }

        // Sleep(1);  //1ms
        SystemClock.sleep(1);
        //  FwUpdateMessage(L"[update bootisp]send burn cmd to move data to flash from sram", MSG_NOR);
        maddressHigh = (byte)0x50;
        maddressLow = (byte)0x94;  //
        //byte msubcommand =0x0f ;  //no command
        mdata = (byte)0x07;

        if(!iicByteWrite(maddressHigh,maddressLow,msubcommand,mdata))
            return false;

       // FwUpdateMessage(L"[update bootisp]Wait for the burn is complete......", MSG_NOR);
       // mError.setText("[update bootisp]Wait for the burn is complete......");
        Update_log = "[update bootisp]Wait for the burn is complete.....";
        mHandler.sendEmptyMessage(DEBUG_MESSAGE_ERROR);

        int nTryTimes = 1000;
        maddressHigh = (byte)0x50;
        maddressLow = (byte)0x94;
        do
        {
            //if (m_pI2CDevice->I2CByteRead(_rRW_MISCTL__BOOT_CTL_) == 0)
            if(iicByteRead(maddressHigh,maddressLow)==0)
            {
                break;
            }
        }
        while ((--nTryTimes) != 0);

        if (nTryTimes == 0)
        {
           // FwUpdateMessage(L"[update bootisp]move data to flash failed", MSG_ERR);
           // mError.setText("[update bootisp]move data to flash failed");
            Update_log = "[update bootisp]move data to flash failed";
            mHandler.sendEmptyMessage(DEBUG_MESSAGE_ERROR);

            return false;
        }

        maddressHigh = (byte)0x90;
        maddressLow = (byte)0x00;  //_rRW_MISCTL__SWRST_B0_
        if (!recallCheck(maddressHigh,maddressLow,mGt9FirmwareData,FW_BOOT_ISP_OFFSET,FW_BOOT_ISP_LENGTH)) {
            //mError.setText("recall check error[fwBootISP] ");
            Update_log = "recall check error[fwBootISP] ";
            mHandler.sendEmptyMessage(DEBUG_MESSAGE_ERROR);
            return false;
        } else {
            //mError.setText("recall check success[fwBootISP]");
            Update_log = "recall check success[fwBootISP] ";
            mHandler.sendEmptyMessage(DEBUG_MESSAGE_ERROR);
            //return false;
        }
        //FwUpdateMessage(L"[update bootisp]recall check 2k bootloader firmware", MSG_NOR);
        // if (!RecallCheck(m_pbBuf + FW_BOOT_ISP_OFFSET, 0x9000, FW_BOOT_ISP_LENGTH))
        {
            // FwUpdateMessage(L"[update bootisp]recall check 2k bootloader firmware failed", MSG_ERR);
            //  return false;
        }

       // FwUpdateMessage(L"[update bootisp]burn bootloader firmware seccessfully----<<", MSG_NOR);
      //  mError.setText("[update bootisp]burn bootloader firmware seccessfully----<<");
        Update_log = "[update bootisp]burn bootloader firmware seccessfully----<< ";
        mHandler.sendEmptyMessage(DEBUG_MESSAGE_ERROR);
        return true;

    }

    private boolean burnFinish() {

        // FwUpdateMessage(L"[FW update]send burn finish flag", MSG_NOR);
        byte maddressHigh = (byte)0x50;
        byte maddressLow = (byte)0x94;  //_rRW_MISCTL__SWRST_B0_
        byte msubcommand =0x0f ;  //no command
        byte mdata = (byte)0x99;

        if(!iicByteWrite(maddressHigh,maddressLow,msubcommand,mdata)) {
           // mError.setText("[FW update]send burn finish flag failed");
            Update_log = "[FW update]send burn finish flag failed ";
            mHandler.sendEmptyMessage(DEBUG_MESSAGE_ERROR);
            return false;
        }

        //RebootFromSram
        maddressHigh = (byte)0x41;
        maddressLow = (byte)0x80;  //_rRW_MISCTL__SWRST_B0_
        msubcommand =0x05 ;  //RebootFromSram command
        mdata = (byte)0x80;

        if(!iicByteWrite(maddressHigh,maddressLow,msubcommand,mdata)) {

            maddressHigh = (byte)0x80;
            maddressLow = (byte)0x40;
            msubcommand =0x04 ;  //Reset IC command
            mdata = (byte)0x00;
            if (!iicByteWrite(maddressHigh,maddressLow,msubcommand,mdata))
            {
               // FwUpdateMessage(L"[FW update]Touch IC reset failed", MSG_ERR);
               // mError.setText("[FW update]Touch IC reset failed");
                Update_log = "[FW update]Touch IC reset failed ";
                mHandler.sendEmptyMessage(DEBUG_MESSAGE_ERROR);
                return false;
            }
            //FwUpdateMessage(L"[FW update]ResetTouch IC ", MSG_NOR);
           // mError.setText("[FW update]ResetTouch IC ");
            Update_log = "[FW update]ResetTouch IC, UPDATE SUCCESS!!! ";
            mHandler.sendEmptyMessage(DEBUG_MESSAGE_ERROR);
        }

        //自动发送配置
        if(bottonMode == 3) {
            maddressHigh = (byte) 0x80;
            maddressLow = (byte) 0x47;
            //iicWrite(maddressHigh,maddressLow,mConfigData,0,186);
            if (!iicWrite(maddressHigh, maddressLow, mConfigData, 0, 186)) {

                Update_log = "[FW auto-update]Send Config failed ";
                mHandler.sendEmptyMessage(DEBUG_MESSAGE_ERROR);
                return false;
            }
            Update_log = "[FW auto-update]Send Config  SUCCESS!!! ";
            mHandler.sendEmptyMessage(DEBUG_MESSAGE_ERROR);
        }

        return true;
    }

    private boolean updateProc() {

        if (!enterUpdateMode())  //NO1
        {
            //FwUpdateMessage(L"[FW update]Enter update mode failed", MSG_ERR);
            return false;
        }

        if (!burnDspIsp()) {   //NO2
                // FwUpdateMessage(L"[FW update]Burn DSP isp failed", MSG_ERR);
                return false;
        }

        if (!eraseBootLoader()) {  //NO3
                return false;
        }

        if (!burnFwGwake()) {  //NO8
            //FwUpdateMessage(L"[FW update]Burn Gwake failed", MSG_ERR);
            return false;
        }

        if (!burnFwSS51()) {  //NO5
            //FwUpdateMessage(L"[FW update]Burn SS51 failed", MSG_ERR);
            return false;
        }

        if (!burnFwDSP()) {  //NO9
            //FwUpdateMessage(L"[FW update]Burn DSP failed", MSG_ERR);
            return false;
        }

        if (!burnFwLink()) {  //NO7
            // FwUpdateMessage(L"[FW update]Burn link failed", MSG_ERR);
            return false;
        }

        if (!burnFwBoot()) {  //NO4
            // FwUpdateMessage(L"[FW update]Burn boot failed", MSG_ERR);
            return false;
        }

        if (!burnFwBootIsp()) {  //NO6
            // FwUpdateMessage(L"[FW update]Burn boot isp failed", MSG_ERR);
            return false;
        }


        burnFinish();

        return true;
    }

    //---------------------------------------------------------------------------------------------------------------------------//
    private byte iChipType;
    private byte iFwCnt;

    int BERLINB_MAX_FW_NUM =  47;

    private byte[] p_fw_info_fw_type = new byte[BERLINB_MAX_FW_NUM];
    private int[] p_fw_info_fw_len = new int[BERLINB_MAX_FW_NUM];
    private int[] p_fw_info_fw_flash_addr = new int[BERLINB_MAX_FW_NUM];
    private int[] p_fw_info_fw_data_index = new int[BERLINB_MAX_FW_NUM];
    /*
    private boolean CheckBinFileValid()
    {
        int nValidLen = (mGt293xFirmwareData[0]) + (mGt293xFirmwareData[1] << 8)
                + (mGt293xFirmwareData[2] << 16) + (mGt293xFirmwareData[3] << 24);

        if(nValidLen + 8 > m_nBinFileLen)
        {
            return false;
        }

        INT32 nCheckSum = mGt293xFirmwareData[4] + (mGt293xFirmwareData[5] << 8)
                + (mGt293xFirmwareData[6] << 16) + (mGt293xFirmwareData[7] << 24);

        if (nCheckSum != GetCheckSum((WORD*)(m_pbBinBuf + 8), nValidLen>>1))
        {
            return false;
        }

        return true;
    }
    */
    private boolean UpdateInit(){
        //if (!CheckBinFileValid())
        //    return false;

        iChipType = mGt293xFirmwareData[30];
        iFwCnt = mGt293xFirmwareData[29];
        //增加GT9916支持，chiptype=0x98
        if (iChipType != TYPE_BERLIN_B && iChipType != TYPE_BERLIN_D)
        {
            Update_log = "[FW update]Chip_type error!";
            mHandler.sendEmptyMessage(DEBUG_MESSAGE_ERROR);
            return false;
        }

        if (iFwCnt == 0 || iFwCnt > (byte)BERLINB_MAX_FW_NUM)
        {
            Update_log = "[FW update]Fw_cnt error!";
            mHandler.sendEmptyMessage(DEBUG_MESSAGE_ERROR);
            return false;
        }

        int nInfoOffset = 42;
        int nDataOffset = 512;
        int nInfoStepSize = 10;

        for (int i = 0; i < iFwCnt; i++)
        {
            int index = nInfoOffset + i * nInfoStepSize;
            p_fw_info_fw_type[i] = mGt293xFirmwareData[index];
            p_fw_info_fw_len[i] = (mGt293xFirmwareData[index + 1] & 0xff) + ((mGt293xFirmwareData[index + 2] & 0xff) << 8) + ((mGt293xFirmwareData[index + 3] & 0xff) << 16) + ((mGt293xFirmwareData[index + 4] & 0xff) << 24);
            //p_fw_info_fw_len[i] = p_fw_info_fw_len[i] & 0xffff;

            p_fw_info_fw_flash_addr[i] = (mGt293xFirmwareData[index + 5] & 0xff) + ((mGt293xFirmwareData[index + 6] & 0xff) << 8) + ((mGt293xFirmwareData[index + 7] & 0xff) << 16) + ((mGt293xFirmwareData[index + 8] & 0xff) << 24);
            p_fw_info_fw_data_index[i] = nDataOffset;  //存储固件起始位置的下标
            nDataOffset += p_fw_info_fw_len[i];
        }

        Update_log = "[FW update]UpdateInit Success";
        mHandler.sendEmptyMessage(DEBUG_MESSAGE_ERROR);
        return true;
    }

    private boolean EnterUpdateMode(){

        boolean ret = false;

        byte addrfirstbyte = (byte)0x01;
        byte addrsecondbyte = (byte)0x01;
        byte addrthirdbyte = (byte)0x74;
        byte msubcommand = (byte)0x12;  //最高位置1,写命令18 DISABLE_DIGITER_INTERFACE
        byte mdata = (byte)0x00;

        if(!IicWriteOneByte(addrfirstbyte, addrsecondbyte, addrthirdbyte, msubcommand, mdata)) {
            return false;
        }

        SystemClock.sleep(10);

        msubcommand = (byte)0x2B;  //最高位置1,写命令43 DISABLE_ESD_CHECK
        //mdata = (byte)0x00;

        if(!IicWriteOneByte(addrfirstbyte, addrsecondbyte, addrthirdbyte, msubcommand, mdata)) {
            return false;
        }

        SystemClock.sleep(10);

        msubcommand = (byte)0x24;  //最高位置1,写命令36 GTXXX_ENTER_UPDATE_MODE

        for (int i = 0; i < 10; i++)
        {
            ret = iicRead32Bits(addrfirstbyte, addrsecondbyte, addrthirdbyte, msubcommand,mBytes, 1);  //用read命令才能进入update mode，固件里面这样写的
            if (ret) break;
        }

        if (!ret) {
            Update_log = "[FW update]Enter Update Mode Fail!";
            mHandler.sendEmptyMessage(DEBUG_MESSAGE_ERROR);
            return false;
        }
        else
        {
            for (int i = 0; i < 150; i++)
            {
                //gpI2C1->I2CByteWrite(0xD807, 0xFF);
                //iicByteWrite((byte)0xD8, (byte)0x07, (byte)0, (byte)0xFF);
                addrfirstbyte = (byte)0x00;
                addrsecondbyte = (byte)0xD8;
                addrthirdbyte = (byte)0x07;
                msubcommand = (byte)0x0f;
                mdata = (byte)0xFF;

                IicWriteOneByte(addrfirstbyte, addrsecondbyte, addrthirdbyte, msubcommand, mdata);
                //iicWrite32Bits(addrfirstbyte, addrsecondbyte, addrthirdbyte,(byte)0x0f, byte[] wBuffer, 0, 1);
                SystemClock.sleep(20);
                //if (0xFF == gpI2C1->I2CByteRead(0xD807))
                iicRead32Bits(addrfirstbyte, addrsecondbyte, addrthirdbyte,msubcommand,mBytes, 1);
                if ((byte)0xFF == mBytes[0])
                {
                    addrfirstbyte = (byte)0x00;
                    addrsecondbyte = (byte)0xD0;
                    addrthirdbyte = (byte)0x54;
                    msubcommand = (byte)0x0f;
                    mdata = (byte)0;

                    //gpI2C1->I2CByteWrite(0xD054, 0);
                    //iicByteWrite((byte)0xD0, (byte)0x54, (byte)0, (byte)0);
                    IicWriteOneByte(addrfirstbyte, addrsecondbyte, addrthirdbyte, msubcommand, mdata);

                    SystemClock.sleep(10);

                    Update_log = "[FW update]Enter Update Mode Success";
                    mHandler.sendEmptyMessage(DEBUG_MESSAGE_ERROR);
                    return true;
                }
                SystemClock.sleep(10);
            }

        }

        Update_log = "[FW update]Enter Update Mode Fail!";
        mHandler.sendEmptyMessage(DEBUG_MESSAGE_ERROR);
        return false;
    }

    private boolean UpdateIsp(){

        int fw_len = 0;
        int fw_type = 0;
        int fw_data_index = 0;

        byte addrfirstbyte, addrsecondbyte, addrthirdbyte;

        // ISP fw data get
        for (int i = 0; i < iFwCnt; i++)
        {
            if (SS51_ISP_CODE == p_fw_info_fw_type[i])
            {
                fw_data_index = p_fw_info_fw_data_index[i];
                fw_len = p_fw_info_fw_len[i];
                fw_type = SS51_ISP_CODE;
                break;
            }
        }

        if (fw_type != SS51_ISP_CODE)
        {
            Update_log = "[FW update]Update ISP Code Fail!";
            mHandler.sendEmptyMessage(DEBUG_MESSAGE_ERROR);
            return false;
        }


        if (iChipType == TYPE_BERLIN_B)//默认 Berlin B
        {   //download isp to chip sram buffer addr
            addrfirstbyte = 0x05;
            addrsecondbyte = 0x70;
            addrthirdbyte = 0x00;

            //if (!gpI2C1->I2CWrite(BLB_ISP_RAM_ADDR, tmp_fw_info.p_fw_data, tmp_fw_info.fw_len))
            if (!iicWrite32Bits(addrfirstbyte, addrsecondbyte, addrthirdbyte, (byte)0x0f, mGt293xFirmwareData,fw_data_index, fw_len))
            {
                Update_log = "[FW update]Update ISP Code Fail!";
                mHandler.sendEmptyMessage(DEBUG_MESSAGE_ERROR);
                return false;
            }

            //todo
            //BYTE* CheckIsp = new BYTE[tmp_fw_info.fw_len];
            //if (!gpI2C1->I2CRead(BLB_ISP_RAM_ADDR, CheckIsp, tmp_fw_info.fw_len))
            //{
            //    return false;
            //}
            //if (memcmp(tmp_fw_info.p_fw_data, CheckIsp, tmp_fw_info.fw_len) != 0)
            //{
            //    return false;
            //}
        }
        else if (iChipType == TYPE_BERLIN_D)
        {
            addrfirstbyte = 0x02;
            addrsecondbyte = 0x38;
            addrthirdbyte = 0x00;

            //if (!gpI2C1->I2CWrite(BLD_ISP_RAM_ADDR, tmp_fw_info.p_fw_data, tmp_fw_info.fw_len))
            if (!iicWrite32Bits(addrfirstbyte, addrsecondbyte, addrthirdbyte, (byte)0x0f, mGt293xFirmwareData,fw_data_index, fw_len))
            {
                return false;
            }
            SystemClock.sleep(20);
            if (!recallCheck32Bits(addrfirstbyte,addrsecondbyte, addrthirdbyte, mGt293xFirmwareData,fw_data_index,fw_len))
            {
                return false;
            }
            /* todo
            BYTE* CheckIsp = new BYTE[tmp_fw_info.fw_len];
            if (!gpI2C1->I2CRead(BLD_ISP_RAM_ADDR, CheckIsp, tmp_fw_info.fw_len))
            {
                return false;
            }
            if (memcmp(tmp_fw_info.p_fw_data, CheckIsp, tmp_fw_info.fw_len) != 0)
            {
                return false;
            }
            */
        }

        //SystemClock.sleep(100);
        //BYTE cmdClearBackDoor[10];
        //BYTE ReadBackCheck[10];
        //

        for (int i = 0; i < 10; i++) {
            mBytes[i] = (byte) 0x55;
        }

        //clear back door
        //if (!gpI2C1->I2CWrite(BOOT_OPT_ADDR, cmdClearBackDoor, 8))
        addrfirstbyte = 0x01;
        addrsecondbyte = 0x00;
        addrthirdbyte = 0x00;
        if (!iicWrite32Bits(addrfirstbyte, addrsecondbyte, addrthirdbyte, (byte)0x0f, mBytes, 0, 8)) {
            return false;
        }
        SystemClock.sleep(20);

        if (!iicRead32Bits(addrfirstbyte, addrsecondbyte, addrthirdbyte, (byte)0x0f, mBytes, 8))
        //if (!gpI2C1->I2CRead(BOOT_OPT_ADDR, ReadBackCheck, 8))  //todo
        {
            //Update_log = "[FW update]Clear Back Door Fail!";
            //mHandler.sendEmptyMessage(DEBUG_MESSAGE_ERROR);
            return false;
        }
        //SystemClock.sleep(40);
        int count;
        for (count = 0; count < 8; count++) {
            if (mBytes[count] != (byte) 0x55) {
                Update_log = "[FW update]Clear Back Door Fail!";
                mHandler.sendEmptyMessage(DEBUG_MESSAGE_ERROR);
                return false;
                //break;
            }
        }

        addrfirstbyte = (byte)0x00;
        addrsecondbyte = (byte)0xD8;
        addrthirdbyte = (byte)0x08;
        //msubcommand = (byte)0x0f;
        //mdata = (byte)0;

        if (!IicWriteOneByte(addrfirstbyte, addrsecondbyte, addrthirdbyte, (byte)0x0f, (byte)0))
        //if (!gpI2C1->I2CByteWrite(0xD808, 0))//？sea
        {
            return false;
        }

        SystemClock.sleep(20);

        boolean ret = false;
        for (int i = 0; i < 200; i++)
        {
            //read buffer [0x01001E]
            if (!iicRead32Bits((byte)0x01, (byte)0x00, (byte)0x1E, (byte)0x0f, mBytes, 6))
            {
                continue;
            }

            if ((mBytes[3] == 'I') && (mBytes[4] == 'S') && (mBytes[5] == 'P'))
            {
                ret = true;
                break;
            }

            SystemClock.sleep(5);
        }

        if (!ret)
        {
            Update_log = "[FW update]Update ISP Code Fail!";
            mHandler.sendEmptyMessage(DEBUG_MESSAGE_ERROR);
            return false;
        }

        Update_log = "[FW update]Update ISP Code Success";
        //mHandler.sendEmptyMessage(DEBUG_MESSAGE_ERROR);
        return true;
    }

    private boolean DownloadSection(int index)
    {
        boolean ret = true;
        int nOffset = 0;
        int nLen;
        byte[] pbSendBuf = new byte[MAX_SEND_BYTES + 10];
        //BYTE* pbReadBuf = new BYTE[MAX_SEND_BYTES + 10];
        //BYTE cmd[16];
        //INT nCmdLen;
        int nFlashAddr = p_fw_info_fw_flash_addr[index];

        byte addrfirstbyte, addrsecondbyte, addrthirdbyte;

        int ichecksum;

        do
        {
            nLen = p_fw_info_fw_len[index] - nOffset > MAX_SEND_BYTES ? MAX_SEND_BYTES : p_fw_info_fw_len[index] - nOffset;

            //memcpy(pbSendBuf, pFwInfo->p_fw_data + nOffset, nLen);
            for (int i = 0; i < nLen; i++) {
                pbSendBuf[i] = mGt293xFirmwareData[p_fw_info_fw_data_index[index] + nOffset + i];
            }
            //(*(DWORD*)(pbSendBuf + nLen)) = GetCheckSum((WORD*)pbSendBuf, nLen>>1);  //todo
            ichecksum = 0;
            for (int i = 0; i < nLen; i += 2) {
                int vb = ((pbSendBuf[i + 1] & 0xFF) << 8) + (pbSendBuf[i] & 0xFF);
                ichecksum = ichecksum + vb;
            }

            pbSendBuf[nLen] = (byte)(ichecksum & 0x000000ff);
            pbSendBuf[nLen + 1] = (byte)((ichecksum & 0x0000ff00) >> 8);
            pbSendBuf[nLen + 2] = (byte)((ichecksum & 0x00ff0000) >> 16);
            pbSendBuf[nLen + 3] = (byte)((ichecksum & 0xff000000) >> 24);

            //for (INT i = 0; i < 3; i++)
            {
                if (iChipType == TYPE_BERLIN_B)
                {
                    addrfirstbyte = 0x01;
                    addrsecondbyte = 0x34;
                    addrthirdbyte = 0x10;
                    if (!iicWrite32Bits(addrfirstbyte, addrsecondbyte, addrthirdbyte,(byte)0x0f, pbSendBuf,0, nLen + 4))
                    //if (!gpI2C1->I2CWrite(BLB_CMD_DATA_ADDR, pbSendBuf, nLen + 4))
                    {
                        ret = false;
                        break;
                    }
                }
                else if (iChipType == TYPE_BERLIN_D)
                {
                    addrfirstbyte = 0x01;
                    addrsecondbyte = 0x24;
                    addrthirdbyte = 0x10;
                    if (!iicWrite32Bits(addrfirstbyte, addrsecondbyte, addrthirdbyte,(byte)0x0f, pbSendBuf,0, nLen + 4))
                    //if (!gpI2C1->I2CWrite(BLD_CMD_DATA_ADDR, pbSendBuf, nLen + 4))
                    {
                        ret = false;
                        break;
                    }
                }
		/*	if (!gpI2C1->I2CRead(BLB_CMD_DATA_ADDR, pbReadBuf, nLen + 4))
			{
				ret = false;
				break;
			}

			if (memcmp(pbReadBuf, pbSendBuf, nLen + 4) == 0)
			{
				ret = true;

				break;;
			}*/
            }

            if (!ret) {
                return false;
            }

            mBytes[0] = 0x00;
            mBytes[1] = 0x00;
            mBytes[2] = 0x0B;//cmd len
            mBytes[3] = (byte)0xBB;//FLASH_CMD_MASTER_W;//0xAA,0xBB,0xCC,0xDD
            mBytes[4] = p_fw_info_fw_type[index];
            mBytes[5] = (byte)((nLen + 4) & 0xFF);
            mBytes[6] = (byte)(((nLen + 4) & 0xFF00) >> 8) ;
            mBytes[7] = (byte)(nFlashAddr & 0xFF);
            mBytes[8] = (byte)((nFlashAddr & 0xFF00) >> 8);
            mBytes[9] = (byte)((nFlashAddr & 0xFF0000) >> 16);
            mBytes[10] = (byte)((nFlashAddr & 0xFF000000) >> 24);

            ichecksum = 0;
            for (int i = 0; i < 11; i++)
            {
                ichecksum += (mBytes[i] & 0xFF);
            }

            mBytes[11] = (byte)(ichecksum & 0xFF);
            mBytes[12] = (byte)((ichecksum & 0xFF00) >> 8) ;

            //(*(WORD*)&cmd[11]) = GetCheckSum(cmd, 11);

            if (iChipType == TYPE_BERLIN_B)
            {
                addrfirstbyte = 0x01;
                addrsecondbyte = 0x34;
                addrthirdbyte = 0x00;
                if (!iicWrite32Bits(addrfirstbyte, addrsecondbyte, addrthirdbyte,(byte)0x0f, mBytes,0, 13))
                //if (!gpI2C1->I2CWrite(BLB_CMD_ADDR, cmd, 13))
                {
                    ret = false;
                    break;
                }

                int i;
                for (i = 0; i < 50; i++)  //check 50 times
                {

                    SystemClock.sleep(30);

                    iicRead32Bits(addrfirstbyte, addrsecondbyte, addrthirdbyte, (byte)0x0f, mBytes, 1);
                    //if (!gpI2C1->I2CCheckRegister(BLB_CMD_STATUS_ADDR, FLASH_CMD_W_STATUS_WRITE_OK))
                    if (mBytes[0] == (byte) 0xEE)
                    {
                        break;
                    }
                }
                if (i == 50){
                    ret = false;
                    break;
                }
            }
            else if (iChipType == TYPE_BERLIN_D)
            {
                addrfirstbyte = 0x01;
                addrsecondbyte = 0x24;
                addrthirdbyte = 0x00;
                if (!iicWrite32Bits(addrfirstbyte, addrsecondbyte, addrthirdbyte,(byte)0x0f, mBytes,0, 13))
                //if (!gpI2C1->I2CWrite(BLD_CMD_ADDR, cmd, 13))
                {
                    ret = false;
                    break;
                }

                int i;
                for (i = 0; i < 50; i++)  //check 50 times
                {
                    SystemClock.sleep(30);

                    iicRead32Bits(addrfirstbyte, addrsecondbyte, addrthirdbyte, (byte)0x0f, mBytes, 1);
                    //if (!gpI2C1->I2CCheckRegister(BLD_CMD_STATUS_ADDR, FLASH_CMD_W_STATUS_WRITE_OK))
                    if (mBytes[0] == (byte) 0xEE)
                    {
                        break;
                    }
                }
                if (i == 50){
                    ret = false;
                    break;
                }
            }
            nOffset += nLen;
            nFlashAddr += nLen;

            //m_bHaveDownloadLength += nLen;
            //CString str = LS(IDC_GTXXX_DOWNLOAD_BIN) + ":%d%%";
            //str.Format(str, m_bHaveDownloadLength * 100 / (m_nBinFileLen-8));
            //FwUpdateMessage(str, MSG_FRESH);
        } while (nOffset < p_fw_info_fw_len[index]);

        if (!ret)
        {
            return false;
        }

        return true;
    }

    private boolean DownloadBinFile() {
        //m_bHaveDownloadLength = 0;

        Update_log2 = "[FW update]Download Bin File start......\n";
        mHandler.sendEmptyMessage(DEBUG_MESSAGE_ERROR);

        for (int i = 0; i < iFwCnt; i++)
        {
            if (p_fw_info_fw_type[i] == SS51_ISP_CODE)
            {
                continue;
            }
            if (p_fw_info_fw_type[i] == SS51_PATCH_CODE)
            {
                continue;
            }

            if (!DownloadSection(i))
            {
                Update_log = "[FW update]Download Bin File Fail!";
                mHandler.sendEmptyMessage(DEBUG_MESSAGE_ERROR);
                return false;
            }
        }
        for (int i = 0; i < iFwCnt; i++)
        {
            if (p_fw_info_fw_type[i] == SS51_PATCH_CODE)
            {
                if (!DownloadSection(i))
                {
                    Update_log = "[FW update]Download Patch Code Fail!";
                    mHandler.sendEmptyMessage(DEBUG_MESSAGE_ERROR);
                    return false;
                }
            }
        }

        Update_log = "[FW update]Download Bin File Success";
        mHandler.sendEmptyMessage(DEBUG_MESSAGE_ERROR);
        return true;
    }

    private boolean UpdateFinish() {

        byte addrfirstbyte = (byte)0x01;
        byte addrsecondbyte = (byte)0x01;
        byte addrthirdbyte = (byte)0x74;
        byte msubcommand = (byte)0x04 ;  //最高位置1。写命令4 rst IC
        byte mdata = (byte)0x00;

        msubcommand = (byte)0x11 ;  //最高位置1，写命令17 ENABLE_DIGITER_INTERFACE
        IicWriteOneByte(addrfirstbyte, addrsecondbyte, addrthirdbyte, msubcommand, mdata);

        SystemClock.sleep(10);

        msubcommand = (byte)0x2A ;  //最高位置1，写命令42 ENABLE_ESD_CHECK
        IicWriteOneByte(addrfirstbyte, addrsecondbyte, addrthirdbyte, msubcommand, mdata);

        SystemClock.sleep(10);

        msubcommand = (byte)0x04 ;  //最高位置1。写命令4 rst IC
        if(!IicWriteOneByte(addrfirstbyte, addrsecondbyte, addrthirdbyte, msubcommand, mdata)) {
            Update_log = "[FW update]Reset touch IC failed!";
            mHandler.sendEmptyMessage(DEBUG_MESSAGE_ERROR);
            return false;
        }

        Update_log = "[FW update]Update Bin Finish!!";
        mHandler.sendEmptyMessage(DEBUG_MESSAGE_ERROR);
        return true;
    }

    private boolean UpdateConfigProc() {

        Update_log = "[Config update]Update Config Start......";
        mHandler.sendEmptyMessage(DEBUG_MESSAGE_ERROR);

        String[] stringArr;
        String value;

        byte addrfirstbyte, addrsecondbyte, addrthirdbyte;

        //send 0x00 to [0x10174]，清除标志
        mBytes[0] = 0x00;
        iicWrite32Bits((byte)0x01, (byte)0x01, (byte)0x74, (byte)0x0f, mBytes,0,1);
        SystemClock.sleep(15);

        //send 0x00 0x00 0x04 0x04 0x08 0x00 to [0x10174]，通知GT29XX,send cfg
        mBytes[0] = 0x00;
        mBytes[1] = 0x00;
        mBytes[2] = 0x04;
        mBytes[3] = 0x04;
        mBytes[4] = 0x08;
        mBytes[5] = 0x00;
        iicWrite32Bits((byte)0x01, (byte)0x01, (byte)0x74, (byte)0x0f, mBytes,0,6);

        //30ms一次轮询[0x10174]，如果是0x80，说明GT29XX已准备好，可以send cfg
        do {
            SystemClock.sleep(30);
            iicRead32Bits((byte)0x01, (byte)0x01, (byte)0x74, (byte)0x0f, mBytes, 1);
        }while(mBytes[0] != (byte)0x80);

        //value = configBuilder.toString();
        value = StrConfigDateString;
        value = value.replaceAll("0x", ""); //0x转换为没有
        stringArr = value.split(",");

        //value = value.replace(',', ' '); //逗号转换为空格

        //value = value.trim();  //去除空格
        //value = value.replaceAll(" ", ""); //逗号转换为空格
        //char mTextData[] = value.toCharArray();
        byte[] mBufferData = new byte[2048];

        for (int b = 0; b < stringArr.length; b++) {
            byte aByte = (byte) Integer.parseInt(stringArr[b], 16);
            mBufferData[b] = aByte;
        }
        //mBufferData = value.getBytes();
        //mSendData = new byte[2048];

        //重新计算checksum

        //head buffer长度为64字节，最后两个字节是checksum，低位在前存放
            /*
            ichecksumhead = 0;
            for (int i = 0; i < 62; i++) {
                int vb = mBufferData[i] & 0xFF;
                ichecksumhead = ichecksumhead + vb;
            }

            mBufferData[62] = (byte)(ichecksumhead & 0x00ff);
            mBufferData[63] = (byte)((ichecksumhead & 0xff00) >> 8);
            */

        //配置长度（不含head buffer长度）
        int iconfiglen = (int)(mBufferData[60] & 0xFF) * 256 + (mBufferData[59] & 0xFF);

        //计算配置的checksum，不含64字节的head buffer
            /*
            lchecksum = 0;
            for (int i = 64; i < (iconfiglen + 64 - 4); i += 2) {
                int vb = ((mBufferData[i + 1] & 0xFF) << 8) + (mBufferData[i] & 0xFF);
                lchecksum = lchecksum + vb;
            }

            mBufferData[iconfiglen + 64 - 4] = (byte)(lchecksum & 0x000000ff);
            mBufferData[iconfiglen + 64 - 3] = (byte)((lchecksum & 0x0000ff00) >> 8);
            mBufferData[iconfiglen + 64 - 2] = (byte)((lchecksum & 0x00ff0000) >> 16);
            mBufferData[iconfiglen + 64 - 1] = (byte)((lchecksum & 0xff000000) >> 24);
            */

        if (byProductType == GT29336) {
            addrfirstbyte = (byte)0x01;
            addrsecondbyte = (byte)0x3B;
            addrthirdbyte = (byte)0x74;
        }
        else
        {
            addrfirstbyte = (byte)0x01;
            addrsecondbyte = (byte)0x21;
            addrthirdbyte = (byte)0x8C;
        }

        iicWrite32Bits(addrfirstbyte, addrsecondbyte, addrthirdbyte, (byte)0x0f, mBufferData,0,iconfiglen + 64);

        SystemClock.sleep(30);

        if (!recallCheck32Bits(addrfirstbyte, addrsecondbyte, addrthirdbyte, mBufferData, 0, iconfiglen + 64)) {
            Update_log = "[Config update]Recall check config error!!";
            mHandler.sendEmptyMessage(DEBUG_MESSAGE_ERROR);
            return false;
        } else {
            Update_log = "[Config update]Recall check config success!!";
            mHandler.sendEmptyMessage(DEBUG_MESSAGE_ERROR);
        }

        SystemClock.sleep(8);

        //send 0x00 0x00 0x04 0x05 0x09 0x00 to [0x10174]，通知GT29XX,cfg发送完毕
        mBytes[0] = 0x00;
        mBytes[1] = 0x00;
        mBytes[2] = 0x04;
        mBytes[3] = 0x05;
        mBytes[4] = 0x09;
        mBytes[5] = 0x00;
        iicWrite32Bits((byte)0x01, (byte)0x01, (byte)0x74, (byte)0x0f, mBytes,0,6);

        //30ms一次轮询[0x10174]，如果是0x80，说明GT29XX已接收配置
        do {
            SystemClock.sleep(30);
            iicRead32Bits((byte)0x01, (byte)0x01, (byte)0x74, (byte)0x0f, mBytes, 1);
            if (mBytes[0] == (byte)0x03)
            {
                Update_log = "[Config update]Config checksum is error!!";
                mHandler.sendEmptyMessage(DEBUG_MESSAGE_ERROR);
                return false;
            }
            else if (mBytes[0] == (byte)0x01)
            {
                Update_log = "[Config update]receive finish!!";
                mHandler.sendEmptyMessage(DEBUG_MESSAGE_ERROR);
                break;
            }

        }while(mBytes[0] != (byte)0x80);

        SystemClock.sleep(15);

        //send 0x00 0x00 0x04 0x06 0x0A 0x00 to [0x10174]，通知GT29XX,流程完成
        mBytes[0] = 0x00;
        mBytes[1] = 0x00;
        mBytes[2] = 0x04;
        mBytes[3] = 0x06;
        mBytes[4] = 0x0A;
        mBytes[5] = 0x00;
        iicWrite32Bits((byte)0x01, (byte)0x01, (byte)0x74, (byte)0x0f, mBytes,0,6);

        //30ms一次轮询[0x10174]，如果是0x80，说明GT29XX已完成
        do {
            SystemClock.sleep(30);
            iicRead32Bits((byte)0x01, (byte)0x01, (byte)0x74, (byte)0x0f, mBytes, 1);
            if (mBytes[0] == (byte)0x01)
            {
                Update_log = "[Config update]receive finish!!";
                mHandler.sendEmptyMessage(DEBUG_MESSAGE_ERROR);
                break;
            }
        }while(mBytes[0] != (byte)0x80);

        SystemClock.sleep(100);

        if (stringArr.length > iconfiglen + 64)  //有USB配置
        {
            SystemClock.sleep(500);
            //strtemplog= "[Cfg update]Update cfg of S8xxx...\n";
            //strUpdateCfgInfoLog = strUpdateCfgInfoLog.concat(strtemplog);

            iicWrite32Bits((byte)0x01, (byte)0x01, (byte)0x74, (byte)49, mBufferData, iconfiglen + 64,24);

            SystemClock.sleep(150);

            IicWriteOneByte((byte)0x01, (byte)0x01, (byte)0x74, (byte)35,(byte)0);

            SystemClock.sleep(150);

            isNeedFindDevice = true;

            openDevices();
        }

        //mShow.setText("Send cfg finish!!");
        Update_log = "[Config update]Send config finish!! Config Version:0x" + Integer.toHexString(mBufferData[34]);
        mHandler.sendEmptyMessage(DEBUG_MESSAGE_ERROR);

        return true;
    }

    private boolean GT29xxupdateProc() {

        if (tv_edit_search_bin.getText().length() != 0)  //下载固件
        {
            //读取文件内容:
            /**
             try {
             readFile();
             } catch (IOException e) {
             mMessage.setText("文件不存在!");
             // e.printStackTrace();
             }
             */

            ActivityCompat.requestPermissions(FirmwareUpdate.this, new String[]{android
                    .Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);   //申请权限，android6.0以上系统首次使用必须添加

            StringBuffer buffer = new StringBuffer();
            StringBuilder stringBuilder = new StringBuilder("");
            if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {

                try {

                    //String filename = Environment.getExternalStorageDirectory() + "/Download/GT9110H_2002(A2E3).BIN";
                    String filename = "GT9110H_2002(A2E3).BIN";
                    //mError.setText(filename);
                    //FileInputStream fis = new FileInputStream(filename);
                    if (bottonMode == 4) {
                        filename = tv_edit_search_bin.getText().toString();
                        FileInputStream fw = new FileInputStream(filename);
                        //fw.read(mGt9FirmwareData);
                        fw.read(mGt293xFirmwareData);
                        fw.close();
                    } else {

                        if (bottonMode == 3) {
                            InputStream config = getResources().openRawResource(R.raw.gt9110h_config_2018110802);
                            //InputStream config = getResources().openRawResource(R.raw.xinjian);\
                            config.read(mConfigData);

                            InputStream fis = getResources().openRawResource(R.raw.gt9110h_2002);
                            //gt9110h_config_20181108
                            fis.read(mGt9FirmwareData);

                            config.close();
                            fis.close();
                        }
                    }
                } catch (FileNotFoundException e) {
                    e.printStackTrace();
                    Update_log = getResources().getString(R.string.invalidfile);
                    mHandler.sendEmptyMessage(DEBUG_MESSAGE_ERROR);

                    return false;
                } catch (IOException e) {
                    e.printStackTrace();
                    Update_log = "IOException";
                    mHandler.sendEmptyMessage(DEBUG_MESSAGE_ERROR);

                    return false;
                }

            } else {
                Update_log = getResources().getString(R.string.nopermission);
                mHandler.sendEmptyMessage(DEBUG_MESSAGE_ERROR);

                return false;
            }

        /*
        byte addrfirstbyte = (byte)0x01;
        byte addrsecondbyte = (byte)0x01;
        byte addrthirdbyte = (byte)0x74;
        byte msubcommand = (byte)0x04 ;  //最高位置1。写命令4 rst IC
        byte mdata = (byte)0x00;

        //msubcommand = (byte)0x04 ;  //最高位置1。写命令4 rst IC
        if(!IicWriteOneByte(addrfirstbyte, addrsecondbyte, addrthirdbyte, msubcommand, mdata)) {
            Update_log = "[FW update]Reset touch IC failed!";
            mHandler.sendEmptyMessage(DEBUG_MESSAGE_ERROR);
            return false;
        }

        SystemClock.sleep(80);
        */

            if (!UpdateInit())  //NO1
            {
                //FwUpdateMessage(L"[FW update]Enter update mode failed", MSG_ERR);
                UpdateFinish();
                return false;
            }

            if (!EnterUpdateMode())  //NO2
            {
                //FwUpdateMessage(L"[FW update]Enter update mode failed", MSG_ERR);
                UpdateFinish();
                return false;
            }

            if (!UpdateIsp())  //NO3
            {
                //FwUpdateMessage(L"[FW update]Enter update mode failed", MSG_ERR);
                UpdateFinish();
                return false;
            }

        /*
        if (m_nConfigLen > 0 && m_nConfigLen < 4096 &&  m_pbConfigBuf != NULL)
        {
            FwUpdateMessage(LS(IDS_UPGRADE_CONFIG_BY_ISP), MSG_PROC);
            if (!UpdateConfigByIsp())
            {
                FwUpdateMessage(LS(IDS_UPGRADE_CONFIG_BY_ISP_FAILE), MSG_ERR);
				goto FAILED_EIXT;
            }
        }
        */

            if (!DownloadBinFile()) {
                //FwUpdateMessage(LS(IDS_GTXXX_DOWNLOAD_BIN_FAILED), MSG_ERR);
                UpdateFinish();
                return false;
            }

            if (!UpdateFinish()) {
                //FwUpdateMessage(LS(IDS_GTXXX_RESET_FAILED), MSG_ERR);
                return false;
            }
        }

        if (tv_edit_search_cfg.getText().length() != 0)  //下发配置
        {
            SystemClock.sleep(100);

            if (!UpdateConfigProc())
            {
                return false;
            }

        }

        return true;
    }

    //---------------------------------------------------------------------------------------------------------------------------//

    @Override
    protected void onDestroy() {
        super.onDestroy();

        if (mUsbDeviceConnection != null) {
            mUsbDeviceConnection.releaseInterface(mUsbInterface);
            mUsbDeviceConnection.close();
            mUsbDeviceConnection = null;
        }
        mUsbEndpointIn = null;
        mUsbEndpointOut = null;
        isReceiverMessage = false;
        isNeedFindDevice = false;
        mThreadPool.shutdownNow();
        // unregisterReceiver(mUsbDetachedReceiver);
        unregisterReceiver(fwOpenDevicesReceiver);
    }
}
