package com.xixun.communicate;

import android.util.Log;

import com.google.gson.Gson;
import com.xixun.communicate.PointCheck.PointCheck;
import com.xixun.communicate.PointCheck.ReceiverCard;
import com.xixun.communicate.Protocol.NET_COMMU_TYPE;
import com.xixun.communicate.Protocol.StreamPort;
import com.xixun.communicate.LedCardCommunication;
import com.xixun.communicate.Task.PollingWorker;
import com.xixun.communicate.Task.Worker;
import com.xixun.display.MyLog;

import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.ArrayList;
import java.util.List;
import java.util.zip.CRC32;

import static android.system.OsConstants.O_RDWR;
import static com.friendlyarm.AndroidSDK.HardwareControler.I2CReadByte;
import static com.friendlyarm.AndroidSDK.HardwareControler.I2CReadByteData;
import static com.friendlyarm.AndroidSDK.HardwareControler.I2CWriteByteData;
import static com.friendlyarm.AndroidSDK.HardwareControler.close;
import static com.friendlyarm.AndroidSDK.HardwareControler.exportGPIOPin;
import static com.friendlyarm.AndroidSDK.HardwareControler.readByteFromI2C;
import static com.friendlyarm.AndroidSDK.HardwareControler.setGPIODirection;
import static com.friendlyarm.AndroidSDK.HardwareControler.setGPIOValue;
import static com.friendlyarm.AndroidSDK.HardwareControler.setI2CSlave;
import static com.xixun.communicate.Protocol.StreamPort.STREAM_SYNC_HEAD;
import static com.xixun.communicate.Protocol.StreamPort.STREAM_SYNC_HEAD2;
import static java.lang.Thread.currentThread;
import static java.lang.Thread.sleep;


public class MooncellFpga {

    public static final String SPI_DEVICE_0 = "/dev/spidev0.0";
    public static final String SPI_DEVICE_1 = "/dev/spidev1.0";
    public static final String SPI_DEVICE_2 = "/dev/spidev2.0";

    public static final int REG_PAGE_SIZE = 4 * 1024;
    public static final int REG_SIZE = REG_PAGE_SIZE * 256;

    public static final byte MOONCELL_FPGA_WRITE_FLAG = (byte) 0xE5;
    public static final byte MOONCELL_FPGA_READ_FLAG = (byte) 0xAA;

    public static final int MOONCELL_FPGA_PORT_NUMBER = 8;

    public static final int MOONCELL_FPGA_FLASH_ADDRESS_GPORT_NUM_PARAMS = 0x80 * Define.FLASH_PAGE_SIZE;
    public static final int MOONCELL_FPGA_FLASH_ADDRESS_GPORT_PARAMS = 0x8C * Define.FLASH_PAGE_SIZE;
    public static final int MOONCELL_FPGA_FLASH_ADDRESS_PICTURE_CONTROL = 0x8E * Define.FLASH_PAGE_SIZE;

    public static final int MOONCELL_FPGA_REG_ADDRESS_BASIC_STEP = 0x10000;
    public static final int MOONCELL_FPGA_REG_ADDRESS_BASIC_SEND = 0x600000;
    public static final int MOONCELL_FPGA_REG_ADDRESS_SEND_P0 = MOONCELL_FPGA_REG_ADDRESS_BASIC_SEND + MOONCELL_FPGA_REG_ADDRESS_BASIC_STEP * 0;
    public static final int MOONCELL_FPGA_REG_ADDRESS_SEND_P1 = MOONCELL_FPGA_REG_ADDRESS_BASIC_SEND + MOONCELL_FPGA_REG_ADDRESS_BASIC_STEP * 1;
    public static final int MOONCELL_FPGA_REG_ADDRESS_SEND_P2 = MOONCELL_FPGA_REG_ADDRESS_BASIC_SEND + MOONCELL_FPGA_REG_ADDRESS_BASIC_STEP * 2;
    public static final int MOONCELL_FPGA_REG_ADDRESS_SEND_P3 = MOONCELL_FPGA_REG_ADDRESS_BASIC_SEND + MOONCELL_FPGA_REG_ADDRESS_BASIC_STEP * 3;
    public static final int MOONCELL_FPGA_REG_ADDRESS_SEND_P4 = MOONCELL_FPGA_REG_ADDRESS_BASIC_SEND + MOONCELL_FPGA_REG_ADDRESS_BASIC_STEP * 4;
    public static final int MOONCELL_FPGA_REG_ADDRESS_SEND_P5 = MOONCELL_FPGA_REG_ADDRESS_BASIC_SEND + MOONCELL_FPGA_REG_ADDRESS_BASIC_STEP * 5;
    public static final int MOONCELL_FPGA_REG_ADDRESS_SEND_P6 = MOONCELL_FPGA_REG_ADDRESS_BASIC_SEND + MOONCELL_FPGA_REG_ADDRESS_BASIC_STEP * 6;
    public static final int MOONCELL_FPGA_REG_ADDRESS_SEND_P7 = MOONCELL_FPGA_REG_ADDRESS_BASIC_SEND + MOONCELL_FPGA_REG_ADDRESS_BASIC_STEP * 7;

    public static final int MOONCELL_FPGA_REG_ADDRESS_BASIC_RECV = 0x680000;
    public static final int MOONCELL_FPGA_REG_ADDRESS_RECV_P0 = MOONCELL_FPGA_REG_ADDRESS_BASIC_RECV + MOONCELL_FPGA_REG_ADDRESS_BASIC_STEP * 0;
    public static final int MOONCELL_FPGA_REG_ADDRESS_RECV_P1 = MOONCELL_FPGA_REG_ADDRESS_BASIC_RECV + MOONCELL_FPGA_REG_ADDRESS_BASIC_STEP * 1;
    public static final int MOONCELL_FPGA_REG_ADDRESS_RECV_P2 = MOONCELL_FPGA_REG_ADDRESS_BASIC_RECV + MOONCELL_FPGA_REG_ADDRESS_BASIC_STEP * 2;
    public static final int MOONCELL_FPGA_REG_ADDRESS_RECV_P3 = MOONCELL_FPGA_REG_ADDRESS_BASIC_RECV + MOONCELL_FPGA_REG_ADDRESS_BASIC_STEP * 3;
    public static final int MOONCELL_FPGA_REG_ADDRESS_RECV_P4 = MOONCELL_FPGA_REG_ADDRESS_BASIC_RECV + MOONCELL_FPGA_REG_ADDRESS_BASIC_STEP * 4;
    public static final int MOONCELL_FPGA_REG_ADDRESS_RECV_P5 = MOONCELL_FPGA_REG_ADDRESS_BASIC_RECV + MOONCELL_FPGA_REG_ADDRESS_BASIC_STEP * 5;
    public static final int MOONCELL_FPGA_REG_ADDRESS_RECV_P6 = MOONCELL_FPGA_REG_ADDRESS_BASIC_RECV + MOONCELL_FPGA_REG_ADDRESS_BASIC_STEP * 6;
    public static final int MOONCELL_FPGA_REG_ADDRESS_RECV_P7 = MOONCELL_FPGA_REG_ADDRESS_BASIC_RECV + MOONCELL_FPGA_REG_ADDRESS_BASIC_STEP * 7;

    public static final int MOONCELL_FPGA_REG_ADDRESS_VGA_PARAMS = 0x700000;
    public static final int MOONCELL_FPGA_REG_ADDRESS_MULTI_PORT_STATUS = 0x710000;


    public static final int MOONCELL_FPGA_MIRROR_ADDRESS_BASIC_STEP = 0x100 * 4;
    public static final int MOONCELL_FPGA_MIRROR_ADDRESS_BASIC = 0xA70000;
    public static final int MOONCELL_FPGA_MIRROR_ADDRESS_PICTURE_SEND_P0 = MOONCELL_FPGA_MIRROR_ADDRESS_BASIC + MOONCELL_FPGA_MIRROR_ADDRESS_BASIC_STEP * 0;
    public static final int MOONCELL_FPGA_MIRROR_ADDRESS_PICTURE_SEND_P1 = MOONCELL_FPGA_MIRROR_ADDRESS_BASIC + MOONCELL_FPGA_MIRROR_ADDRESS_BASIC_STEP * 1;
    public static final int MOONCELL_FPGA_MIRROR_ADDRESS_PICTURE_SEND_P2 = MOONCELL_FPGA_MIRROR_ADDRESS_BASIC + MOONCELL_FPGA_MIRROR_ADDRESS_BASIC_STEP * 2;
    public static final int MOONCELL_FPGA_MIRROR_ADDRESS_PICTURE_SEND_P3 = MOONCELL_FPGA_MIRROR_ADDRESS_BASIC + MOONCELL_FPGA_MIRROR_ADDRESS_BASIC_STEP * 3;
    public static final int MOONCELL_FPGA_MIRROR_ADDRESS_PICTURE_SEND_P4 = MOONCELL_FPGA_MIRROR_ADDRESS_BASIC + MOONCELL_FPGA_MIRROR_ADDRESS_BASIC_STEP * 4;
    public static final int MOONCELL_FPGA_MIRROR_ADDRESS_PICTURE_SEND_P5 = MOONCELL_FPGA_MIRROR_ADDRESS_BASIC + MOONCELL_FPGA_MIRROR_ADDRESS_BASIC_STEP * 5;
    public static final int MOONCELL_FPGA_MIRROR_ADDRESS_PICTURE_SEND_P6 = MOONCELL_FPGA_MIRROR_ADDRESS_BASIC + MOONCELL_FPGA_MIRROR_ADDRESS_BASIC_STEP * 6;
    public static final int MOONCELL_FPGA_MIRROR_ADDRESS_PICTURE_SEND_P7 = MOONCELL_FPGA_MIRROR_ADDRESS_BASIC + MOONCELL_FPGA_MIRROR_ADDRESS_BASIC_STEP * 7;

    public static final int MOONCELL_FPGA_MIRROR_ADDRESS_PICTURE_CONTROL = MOONCELL_FPGA_MIRROR_ADDRESS_BASIC + MOONCELL_FPGA_MIRROR_ADDRESS_BASIC_STEP * 8; // 0xA70000 0x100*4 * 8 = A72000
    public static final int MOONCELL_FPGA_MIRROR_ADDRESS_PICTURE_CONTROL_LIGHT_OFFSET = 0x0D * 4;      // 0X34
    public static final int MOONCELL_FPGA_MIRROR_ADDRESS_PICTURE_CONTROL_LIGHT_ENABLE_OFFSET = 0x0E * 4;  // 0X38

    public static final int MOONCELL_FPGA_MIRROR_ADDRESS_AUDIO_CONTROL = MOONCELL_FPGA_MIRROR_ADDRESS_PICTURE_CONTROL + 0x20 * 4;  // A72000 + 0X20*4 = A72080
    public static final int MOONCELL_FPGA_MIRROR_ADDRESS_3D_CONTROL = MOONCELL_FPGA_MIRROR_ADDRESS_AUDIO_CONTROL + 0x30 * 4; // A72080 + C0 = A72140

    public static final int MOONCELL_FPGA_MIRROR_ADDRESS_ANALOG_PICTURE_CONTROL = MOONCELL_FPGA_MIRROR_ADDRESS_BASIC + MOONCELL_FPGA_MIRROR_ADDRESS_BASIC_STEP * 9;
    public static final int MOONCELL_FPGA_MIRROR_ADDRESS_SYSTEM_CONFIG = 0xA80000;

    public LedCardCommunication ledCardCommunication = null;

    public Object objFpgaReadOrWrite = new Object();

    public String strStoragePath = null;

    public RandomAccessFile fpgaParamsFile = null;
    public RandomAccessFile fpgaRegFile = null;

    public SpiDevice spiDevice = null;
    //  HardwareControler hardwarecontroler = null;
    public boolean Whether_E30card = false;

    public MooncellFpga(LedCardCommunication ledCardCommunication) {
        this.ledCardCommunication = ledCardCommunication;
        if (ledCardCommunication.bTestInNewFpga == false) {
            if (ledCardCommunication != null)
                if (ledCardCommunication.clientsManage != null)
                    strStoragePath = ledCardCommunication.clientsManage.ms.strStoragePath;  // strStoragePath = /mnt/sdcard
            if (strStoragePath == null) return;
        }
        new Thread() {
            public void run() {
                Process();
            }
        }.start();
    }

    static {
        System.loadLibrary("SpiDevice");// 在java代码中引入libs目录下的库函数，文件名为【libhello.so】。注意，引入时的文件名要去掉前面的lib和后面的.so
    }

    public void Process() {
        try {
            if ((ledCardCommunication.bTestInNewFpga == false))//&&(Define.bRunOnDebug418==false))  bTestInNewFpga = false
            {
                //if (Define.bRunOnDebug418==false)
                ControllorCardInitial();
                //  MyLog.i("--5"+strStoragePath);
                fpgaRegFile = new RandomAccessFile(strStoragePath + Define.MOONCELL_FPGA_REG_FILE_NAME, "rws");
                fpgaParamsFile = new RandomAccessFile(strStoragePath + Define.MOONCELL_FPGA_PARAMS_FILE_NAME, "rws");
                if (fpgaParamsFile == null || fpgaRegFile == null) {
                    Exit(true);
                }
            }
            if (ledCardCommunication.bTestInNewFpga) {
                MyLog.i("----------------------------------------ledCardCommunication ok");
                spiDevice = new SpiDevice(this, "/sys/class/spi_master/spi0/spi0.1/spi");
            } else {
                MyLog.i("----------------------------------------" + GetDeviceName());
                spiDevice = new SpiDevice(this, GetDeviceName());
                // hardwarecontroler=new HardwareControler( );
            }
            if (spiDevice == null) Exit(true);
            VirtuleRegsFileInitial();
            VirtuleFpgaParamsFileInitial();
            FpgaInitial();
            bReady = true;
            Read_Mooncell_Fpga_Version();
            check_fpga_enable();
            getFpgaVersion();
        } catch (Exception e) {
            String strErrorInfo = e.getMessage();
            MyLog.i(" " + Thread.currentThread().getStackTrace()[2].getFileName() + "-->"
                    + "Function: " + Thread.currentThread().getStackTrace()[2].getMethodName() + "-->"
                    + "Line" + Thread.currentThread().getStackTrace()[2].getLineNumber() + ":\r\n"
                    + "    Error:" + e.getMessage() + "\r\n\r\n"
            );
            if (strErrorInfo.indexOf("(Permission denied)") > 0) {   // Error:/Sysolution/WorkFiles/MC_RegsParams: open failed: EACCES (Permission denied)
                FileOperator.deleteFile(new File(strStoragePath));
                ledCardCommunication.Request_Exit();
            }
            if (bNeedExitRequest)
                ledCardCommunication.Request_Exit();
        }
    }

    public void Read_Mooncell_Fpga_Version() {
        // int version;
        //  version = FpgaRead_Enable(null, 0x710000, 4);
        //   LedCardCommunication Led = new LedCardCommunication( ledCardCommunication.clientsManage,null,0);
        boolean bit_version;
        int result;
        int cnt;
        byte[] Fpga_Version = new byte[32];
        cnt = 0;
        do {
            try {
                sleep(600);
            } catch (Exception e) {
            }
            synchronized (objFpgaReadOrWrite) {
                result = Spi_ReceData_Byte(Fpga_Version, 0x700020, 32);
                cnt++;
            }
            //  MyLog.i("------------result = "+result+" cnt = "+cnt);
        } while ((result < 0) && (cnt < 50));
        Define.PrintBuffer("----------------------Read_Mooncell_Fpga_Version", Fpga_Version, 16);

        if ((Fpga_Version[4] == 0x54) && (Fpga_Version[5] == 0x41) && (Fpga_Version[6] == 0x32) && (Fpga_Version[7] == 0x30)) {
            bit_version = true;
        } else {
            bit_version = false;
        }
        if (ledCardCommunication != null) {
            ledCardCommunication.Send_Version_to_CardSystem(bit_version);
        } else {
            MyLog.i("------------ledCardCommunication = null ");
        }
    }

    int Receive_Card_N = 0;

    public String check_bad_led() {
        byte[] DataBuffer = new byte[8];
        int len;
        int bad_led_totalize;
        int valid_port;
        int d90_cardid = 0; // rcv num
        int i;
        int w = 0, h = 0;
        List<ReceiverCard> c = new ArrayList<>();
        if ((Receive_Card_N == 0) || (Receive_Card_N > 12))
            Receive_Card_N = ReceivedCard_GetNumber(0, RECEIVED_CARD_TYPE_T6);  // 获得接收卡数量
        MyLog.i("------------Receive_Card_N =  " + Receive_Card_N);

        for (i = 0; i < Receive_Card_N; i++) {
            d90_cardid = i;
            ReceivedCard_Read(RECEIVED_CARD_TYPE_T6, d90_cardid, RECEIVED_CARD_INTERNAL_ADDRESS_SDRAM + 0x30000, DataBuffer);
            // Define.PrintBuffer("Module_Num---------------",DataBuffer,DataBuffer.length);

            valid_port = ((DataBuffer[4] << 8) | DataBuffer[5]);
            len = (DataBuffer[0] << 24) | (DataBuffer[1] << 16) | (DataBuffer[2] << 8) | DataBuffer[3];
            //  bad_led_totalize = ((DataBuffer[6] & 0x7f) << 8) | DataBuffer[7];
            bad_led_totalize = ((DataBuffer[6] & 0x7f) << 8) | (DataBuffer[7] & 0xff);
            //  MyLog.i("------------len =  " + len + "  ---bad_led_totalize = " + bad_led_totalize + "     valid_port = " + valid_port);
            if (len < 0 || bad_led_totalize < 0) {
                len = 1;
                bad_led_totalize = 1;
            }
            ReceiverCard r = new ReceiverCard(d90_cardid, len, bad_led_totalize);
            c.add(r);

            Log.i("check_bad_led", "Receive_Card_N = " + i + "bad_led_totalize = " + bad_led_totalize + " len = " + len);

        }

        byte[] Buffer_param = new byte[4];
        if (ReceivedCard_Read(RECEIVED_CARD_TYPE_T6, d90_cardid, 0xd0000000 + 0x400 + 0x9, Buffer_param) == 0) {
            w = make_word(Buffer_param[1], Buffer_param[0]);
            h = make_word(Buffer_param[3], Buffer_param[2]);
            // module_cnt = w / l_module_w;
            MyLog.i(" ----------------------ReceivedCardTest w = " + w + " h = " + h);
            // MyLog.i(" ----------------------module_cnt = "+module_cnt);
        }
        PointCheck pointCheck = new PointCheck(w, h, Receive_Card_N, c);
        Gson gson = new Gson();
        String data = gson.toJson(pointCheck);
        return data;
    }

    void check_fpga_enable() {
        new Thread() {
            public void run() {
                check_fpga();
            }
        }.start();

    }

    public void check_fpga() {
        byte result;
        for (; ; ) {
            try {
                Thread.sleep(60 * 1000);
                result = FpgaRead_Enable(null, MOONCELL_FPGA_MIRROR_ADDRESS_SYSTEM_CONFIG + 63, 1);
                //  System.out.printf("--------result  =  " + result);
                if (result == -1)
                    MyLog.i("---- FpgaRead_Enable -- spi transfer fail  ");
                else if (result != -91) {
                    FpgaInitial();
                    MyLog.i("---- nFpgaSystemConfig again now !");
                } else if (result == -91)
                    MyLog.i("---- FpgaRead_Enable ok !");

            } catch (Exception e) {

            }
        }
    }


    public byte FpgaRead_Enable(StreamPort streamPort, int iAddress, int iLength) {
        byte[] DataBuffer = new byte[1];
        synchronized (objFpgaReadOrWrite) {
            if (Spi_ReceData_Byte(DataBuffer, iAddress, iLength) <= 0)
                return -1;
        }
        return DataBuffer[0];
    }

    String strDeviceName = SPI_DEVICE_2;
    int iPortNumber = 2;

    int GetDisplayNetPortNum() {
        return iPortNumber;
    }

    String GetDeviceName() {
        return strDeviceName;
    }

    public boolean bXixunSuCommand = true;

    public void ControllorCardInitial() {
        if (ledCardCommunication == null) return;
        int iCounter = 0;
        while (ledCardCommunication.Get_DisplayID() == null) {  // Get_DisplayID != null
            try {
                sleep(ClientsManage.HEART_INTERVAL);
            } catch (Exception e) {
                MyLog.i(" " + Thread.currentThread().getStackTrace()[2].getFileName() + "-->"
                        + "Function: " + Thread.currentThread().getStackTrace()[2].getMethodName() + "-->"
                        + "Line" + Thread.currentThread().getStackTrace()[2].getLineNumber() + ":\r\n"
                        + "    Error:" + e.getMessage() + "\r\n\r\n"
                );
                MyLog.i("Wait Get Card ID...");
                iCounter += ClientsManage.HEART_INTERVAL;
                if (iCounter > 10 * 1000) {
                    MyLog.i("Cann't Get Card ID!!!");
                    break;
                }
            }
        }
        if (ledCardCommunication.CardType("L")) {
            strDeviceName = "/dev/spidev-lynq";
            //strDeviceName=SPI_DEVICE_0;
            //bXixunSuCommand=true;

//            Define.SetFileAuthority(true,strDeviceName);
            //           Define.SetFileAuthority(true,strStoragePath+Define.MOONCELL_FPGA_REG_FILE_NAME);
            //           Define.SetFileAuthority(true,strStoragePath+Define.MOONCELL_FPGA_PARAMS_FILE_NAME);
        } else if (ledCardCommunication.CardType("Y")) {
            if (ledCardCommunication.CardType("Y3")) {
                strDeviceName = SPI_DEVICE_0;
            } else {
                strDeviceName = SPI_DEVICE_0;
                bXixunSuCommand = true;
                Define.SetFileAuthority(true, strDeviceName);
                Define.SetFileAuthority(true, strStoragePath + Define.MOONCELL_FPGA_REG_FILE_NAME);
                Define.SetFileAuthority(true, strStoragePath + Define.MOONCELL_FPGA_PARAMS_FILE_NAME);
            }
        } else if (ledCardCommunication.CardType("E")) {
            //bXixunSuCommand=true;//????
            Whether_E30card = true;
            strDeviceName = "/dev/spidev-lynq";
        } else if (ledCardCommunication.CardType("M")) {
            if (ledCardCommunication.CardType("M9")) {
                iPortNumber = 4;
                strDeviceName = SPI_DEVICE_0;
                bXixunSuCommand = false;
            } else {
                iPortNumber = 2;
                strDeviceName = SPI_DEVICE_2;
                bXixunSuCommand = false;
            }
        } else if (ledCardCommunication.CardType("X")) {
            if (ledCardCommunication.CardType("X2"))
                iPortNumber = 2;
            else if (ledCardCommunication.CardType("X4"))
                iPortNumber = 4;
            else if (ledCardCommunication.CardType("X6"))
                iPortNumber = 6;
            else if (ledCardCommunication.CardType("X8"))
                iPortNumber = 8;
            strDeviceName = SPI_DEVICE_0;
            bXixunSuCommand = false;
        } else {
            strDeviceName = "/dev/spidev-lynq";
//            strDeviceName = SPI_DEVICE_0;
//            bXixunSuCommand = true;
//            Define.SetFileAuthority(true, strDeviceName);
//            Define.SetFileAuthority(true, strStoragePath + Define.MOONCELL_FPGA_REG_FILE_NAME);
//            Define.SetFileAuthority(true, strStoragePath + Define.MOONCELL_FPGA_PARAMS_FILE_NAME);
        }
        MyLog.i("Spi Device:" + strDeviceName);
        MyLog.i("Whether_E30card = " + Whether_E30card);
    }

    int iLastValue = Define.UINT_SPECTIAL_FLAG, iCounter = 0;

    public void CheckFpgaWorking() {
        int iCurrentValue = 0;
        byte[] DataBuffer = new byte[64];
        synchronized (objFpgaReadOrWrite) {
            Spi_ReceData_Byte(DataBuffer, MOONCELL_FPGA_REG_ADDRESS_VGA_PARAMS, DataBuffer.length);
        }
        Define.PrintBuffer("VGA Staus:", DataBuffer);
        iCurrentValue = Define.GetIntFromByte(DataBuffer, 0);
        MyLog.i("iCurrentValue:" + Integer.toHexString(iCurrentValue).toUpperCase());
        if (iLastValue == Define.UINT_SPECTIAL_FLAG)
            if (iCurrentValue != 0) iLastValue = iCurrentValue;
        if (iLastValue == iCurrentValue){
            iCounter = 0;
        } else {
            //iCounter++;
            if (iCounter > 10) {
                MyLog.i(" " + Thread.currentThread().getStackTrace()[2].getFileName() + "-->"
                        + "Function: " + Thread.currentThread().getStackTrace()[2].getMethodName() + "-->"
                        + "Line" + Thread.currentThread().getStackTrace()[2].getLineNumber() + ":\r\n"
                        + "\t Fpga isn't working,need,restart: iLastValue=" + iLastValue + " iCurrentValue=" + iCurrentValue
                );
                ledCardCommunication.Request_Exit();
            }
        }
    }

    int FlashWrite(StreamPort streamPort, byte[] DataBuffer, int iAddress, int iLength) {
        return WriteLocalFile(fpgaParamsFile, streamPort, DataBuffer, iAddress, iLength);
    }

    int FlashRead(StreamPort streamPort, int iAddress, int iLength) {
        return ReadLocalFile(fpgaParamsFile, streamPort, iAddress, iLength);
    }

    int RegWrite(StreamPort streamPort, byte[] DataBuffer, int iAddress, int iLength) {
        return WriteLocalFile(fpgaRegFile, streamPort, DataBuffer, iAddress, iLength);
    }

    int RegRead(StreamPort streamPort, int iAddress, int iLength) {
        return ReadLocalFile(fpgaRegFile, streamPort, iAddress, iLength);
    }
    public int FpgaWrite(StreamPort streamPort, byte[] DataBuffer, int iAddress, int iLength) {
        int result = 0;
        byte bitStatus = 0;
        int iTimeLength = 0, iTimeStep = 20;
        GiGData_DataBuffer[0] = 0x00;

        synchronized (objFpgaReadOrWrite) {
            while ((bitStatus = GetMultiPortBusyStatus()) != 0) {
                try {
                    Thread.sleep(iTimeStep);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                iTimeLength += iTimeStep;
                if ((iTimeLength) > (Define.iTimeOut_CommandAck / 2)) {
                    MyLog.i("===============Busy Wait=============GetMultiPortBusyStatus=" + bitStatus + "  TimeOut=" + iTimeLength + "ms;");
                    break;
                }
            }
            if ((iAddress == 0xA72000) && (iLength > 128))
                iLength = 128;

            if (streamPort == null) {
                // Define.PrintBuffer("spi write",DataBuffer,(iLength>64)?64:iLength);
                //  MyLog.i("-------fw 1");
                result = SpiOperator(true, iAddress, DataBuffer, iLength, false);
                if (result < 0) {
                    MyLog.i("FpgaWrite SpiOperateor failed");
                }
            } else {
                if (streamPort.m_bAck) {//如果命令有应答
//                    Define.PrintBuffer("spi write",DataBuffer,(iLength>64)?64:iLength);
                    //  MyLog.i("-------fw 2");
                    result = SpiOperator(true, iAddress, DataBuffer, iLength, streamPort.m_bAck);
                    if (result >= 0) {
                        if (streamPort != null)
                            if (ledCardCommunication != null)
                                if (ledCardCommunication.clientsManage != null)
                                    ledCardCommunication.clientsManage.
                                            TransData_Byte(streamPort.clientIpAddress, NET_COMMU_TYPE.FPGA_MOONCELL.getValue(), (byte) 0, streamPort.ucPipeId, DataBuffer, DataBuffer.length);
//                                Define.PrintBuffer("spi ack",DataBuffer,(iLength>64)?64:iLength);
                    } else {
                        MyLog.i("FpgaWrite SpiOperateor failed");
                    }
                    //FpgaRead(streamPort, iAddress, iLength);
                } else {
//                     Define.PrintBuffer("spi write",DataBuffer,(iLength>64)?64:iLength);
                    //   MyLog.i("-------fw 3");
                    result = SpiOperator(true, iAddress, DataBuffer, iLength, streamPort.m_bAck);
                    if (result < 0) {
                        MyLog.i("FpgaWrite SpiOperateor failed");
                    }
                }
            }
        }
        return result;
    }

    //20190402 modified by alahover -end
    public int FpgaRead(StreamPort streamPort, int iAddress, int iLength) {
        int result;
        byte[] DataBuffer = new byte[iLength];
        synchronized (objFpgaReadOrWrite) {
//            Define.PrintBuffer("spi read",DataBuffer,(iLength>64)?64:iLength);
            //        MyLog.i("-------fw 41");
            result = Spi_ReceData_Byte(DataBuffer, iAddress, iLength);
            if (result >= 0 && streamPort != null && ledCardCommunication.clientsManage != null){
                            ledCardCommunication.clientsManage.TransData_Byte(streamPort.clientIpAddress, NET_COMMU_TYPE.FPGA_MOONCELL.getValue(), (byte) 0, streamPort.ucPipeId, DataBuffer, DataBuffer.length);
            }
        }
        return result;
    }

    public int Spi_ReceData_Byte(byte[] DataBuffer, int iAddress, int iLength) {
        //modified by alahover 20190413 -start
        // MyLog.i("-------fw 4");
        return SpiOperator(false, iAddress, DataBuffer, iLength, true);
        //return SpiOperator(false, iAddress, DataBuffer, iLength,true);
        //modified by alahover 20190413 -end
    }

    public void WriteAck(StreamPort streamPort, byte[] DataBuffer) {
        if (streamPort == null) return;
        if (DataBuffer == null) return;
        int iLength = (DataBuffer.length > Define.iDetectBytes) ? Define.iDetectBytes : DataBuffer.length;
        for (int i = 0; i < iLength; i++)
            DataBuffer[i] = (byte) Define.UCHAR_SPECTIAL_FLAG;// 发送应答标志，接收方会检测到缓存所有数据变化才认为收到应答。

        if (ledCardCommunication != null)
            if (ledCardCommunication.clientsManage != null)
                ledCardCommunication.clientsManage.
                        TransData_Byte(streamPort.clientIpAddress, NET_COMMU_TYPE.FPGA_MOONCELL.getValue(), (byte) 0, streamPort.ucPipeId, DataBuffer, iLength);
    }

    public int SpiOperator(boolean bWrite, int iAddress, byte[] DataBuffer, int iLength, boolean bAck) {
        if (spiDevice == null || DataBuffer == null || iLength == 0)
            return -1;
        //=========================================================================================================  //add byfw
        int iProtocalAddBytes = 8;
        int iOffset = 0;
        int len = 0;
        // MyLog.i("---iLength = "+iLength);

        if (Whether_E30card) {
            if (iLength >= 2048)
                len = 3072;
            else if ((iLength >= 1024) && (iLength < 2048))
                len = 2048;
            else if (iLength < 1024)
                len = iLength + iProtocalAddBytes;
        } else
            len = iLength + iProtocalAddBytes;
        byte[] dataBuffer = new byte[len];//  new byte[iLength + iProtocalAddBytes];//[iLength + iProtocalAddBytes]
        // ==============================================================================================================================
        for (int i = 0; i < dataBuffer.length; i++)
            dataBuffer[i] = 0;
        // e5                         aa
        dataBuffer[iOffset++] = (byte) ((bWrite) ? MOONCELL_FPGA_WRITE_FLAG : MOONCELL_FPGA_READ_FLAG);                      // 读写标志。
        dataBuffer[iOffset++] = (byte) (iAddress >> 16);                        // 地址。
        dataBuffer[iOffset++] = (byte) (iAddress >> 8);
        dataBuffer[iOffset++] = (byte) (iAddress >> 0);
        dataBuffer[iOffset++] = (byte) (iLength >> 8);                         // 长度。
        dataBuffer[iOffset++] = (byte) (iLength >> 0);
        dataBuffer[iOffset++] = 0x00;                                           // 空白。
        dataBuffer[iOffset++] = 0x00;                                           // 空白。

        if (bWrite) //写操作，把用户传进来的写的正文内容，拷贝到spi数据包的正文段
            System.arraycopy(DataBuffer, 0, dataBuffer, iOffset, iLength);    // 正文内容。
        iOffset += iLength;
        if (false) {
            Define.PrintBuffer("Trans Len", dataBuffer, (iLength > 64) ? 64 : iLength);
        }
        //=========================================================================================================  //  add byfw
        if (Whether_E30card) {
            if (iOffset >= 2056) {
                iOffset = 3072;
            } else if ((iOffset > 1024) && (iOffset < 2048)) {
                iOffset = 2048;
            }
        }
        //===================================================================================================================
        int res = spiDevice.Operator(dataBuffer, iOffset);
        //  MyLog.i("write dataBuffer  = "+res);
        if (res > 0) {
            if (bWrite == false || bAck == true) {//读操作则，把收到的缓存应答拷贝到用户缓存
                System.arraycopy(dataBuffer, iProtocalAddBytes, DataBuffer, 0, iLength);
            }
//            MyLog.showBytes("read",DataBuffer,0);
        } else {
            MyLog.i("-------------------Operator send faild");
        }
        return res;
    }
//modified by alahover 20190413 -end


    public static final int FGPA_UPDATE_PACKET_INTERVAL = (10);
    public static final int FGPA_UPDATE_EMPTY_VERSION = (0x0101);
    public static final int FGPA_UPDATE_ADD_BYTES = (100);

    public void FpgaUpgrade(String strFileName) throws InterruptedException, IOException {
        int iTryCounter = 0, iOldVersion = 0;
        int cnt;
        int iNewVersion = 0;
        if (strFileName == null) return;
        if (strFileName.length() < 3) return;

        StreamPort streamPort = new StreamPort();
        if (streamPort == null) return;

        MyLog.i("FpgaUpgrade Step 00: strFileName: " + strFileName);

        RandomAccessFile fpgaUpgradeFile = new RandomAccessFile(strFileName, "r");
        if (fpgaUpgradeFile == null) return;
        //MyLog.i("FpgaUpgrade Step 001: Open success strFileName: "+strFileName);
        int iOffset = 0;
        byte[] DataBuffer = new byte[0x400];
        byte[] dataBuffer = new byte[DataBuffer.length + 0x0C + FGPA_UPDATE_ADD_BYTES];
        // 获取旧版本FPGA。
        //while(true)
        {
            FpgaUpgrade_GetVersion(streamPort); // 第一次不正确。
            iOldVersion = FpgaUpgrade_GetVersion(streamPort);
            MyLog.i("FpgaUpgrade_GetVersion Step 01: Ready...");
            for (cnt = 0; cnt < 10; cnt++) {
                sleep(100);
                iOldVersion = FpgaUpgrade_GetVersion(streamPort);
                if (iOldVersion != -1)
                    break;

            }
            //   if( iOldVersion != -1 )
            //   {
            //      MyLog.i("FpgaUpgrade fail from reset fpga into update mode.");
            //      return;
            //  }
            MyLog.i("FpgaUpgrade Step 01: Old Fpga Version= " + Define.PrintIntToHex(iOldVersion));

            //if (iCounter>10) break;
            //sleep(FGPA_UPDATE_PACKET_INTERVAL*300);
        }

        // 开始命令。
        MyLog.i("FpgaUpgrade Step : Ready into update mode...");
        iTryCounter = 0;
        while (true) {
            iOffset = 0;
            Define.SetIntToByte(0x0C, dataBuffer, iOffset);         // 固定的命令识别符。
            iOffset += 4;
            Define.SetIntToByte(0x00000000, dataBuffer, iOffset);   // 板卡号,主卡为0。
            iOffset += 4;
            Define.SetIntToByte(0x00080400, dataBuffer, iOffset);   // 包号。
            iOffset += 4;
            FpgaUpgrade_TransData_Byte(true, NET_COMMU_TYPE.FGPA_UPDATE.getValue(), dataBuffer, iOffset);
            //sleep(FGPA_UPDATE_PACKET_INTERVAL);
            //FpgaUpgrade_TransData_Byte(true, NET_COMMU_TYPE.FGPA_UPDATE.getValue(), dataBuffer, iOffset);

            sleep(FGPA_UPDATE_PACKET_INTERVAL * 30);
            if (FpgaUpgrade_EnterUpgradeMode(streamPort)) break;

            iTryCounter++;
            if (iTryCounter > 10) {
                MyLog.i("FpgaUpgrade fail from reset fpga into update mode.");
                return;
            }
        }
        MyLog.i("FpgaUpgrade Step 02: Enter into update mode ok.");

        // 发送FPGA文件数据。
        int iTransCounter = 0, iTransLength = 0, iPacketNum = 1;
        MyLog.i("FpgaUpgrade Step 03: Ready send data...");
        while (iTransCounter < fpgaUpgradeFile.length()) {
            //MyLog.i("FpgaUpgrade Step 031: iPacketNum="+iPacketNum + " iTransCounter="+Define.PrintIntToHex(iTransCounter));
            fpgaUpgradeFile.seek(iTransCounter);
            //MyLog.i("FpgaUpgrade Step 032");
            if ((iTransLength = fpgaUpgradeFile.read(DataBuffer)) < 0) {
                MyLog.i("FpgaUpgrade fail from read file offset at " + Define.PrintIntToHex(iTransCounter));
                return;
            }
            //MyLog.i("FpgaUpgrade Step 033");
            //Define.PrintBuffer("File",DataBuffer,48);

            iOffset = 0;
            Define.SetIntToByte(0x0C, dataBuffer, iOffset);                 // 固定的命令识别符。
            iOffset += 4;
            Define.SetIntToByte(0x00000000, dataBuffer, iOffset);           // 板卡号,主卡为0。
            iOffset += 4;
            Define.SetIntToByte(iTransCounter, dataBuffer, iOffset);                // 包号。
            iOffset += 4;
            System.arraycopy(DataBuffer, 0, dataBuffer, iOffset, iTransLength);  // 正文内容。
            iOffset += iTransLength;

            //MyLog.i("FpgaUpgrade Step 035");
            //Define.PrintBuffer("File Trans",dataBuffer,48);
            FpgaUpgrade_TransData_Byte(true, NET_COMMU_TYPE.FGPA_UPDATE.getValue(), dataBuffer, iOffset);

            //MyLog.i("FpgaUpgrade Step 036");
            //Define.PrintBuffer("Ack",dataBuffer,dataBuffer.length);
            //sleep(FGPA_UPDATE_PACKET_INTERVAL);
            int iRetValue = FpgaUpgrade_GetIntData(streamPort, dataBuffer, NET_COMMU_TYPE.FGPA_UPDATE_ACK, 4); // FPGA收完正确的数据。
            //MyLog.i("iRetValue =" + iRetValue);
            if (iRetValue == 0x00000001) // 发送命令正确。
            {
                iTransCounter += iTransLength;
                iPacketNum++;
            }
            //MyLog.i("FpgaUpgrade Step 037");
            //sleep(FGPA_UPDATE_PACKET_INTERVAL);
        }
        MyLog.i("FpgaUpgrade Step 03: Send data ok.");
        // 发送完毕命令。
        {
            MyLog.i("FpgaUpgrade Step 04: Send finish command.");
            iOffset = 0;
            Define.SetIntToByte(0x0C, dataBuffer, iOffset);         // 固定的命令识别符。
            iOffset += 4;
            Define.SetIntToByte(0x00000000, dataBuffer, iOffset);   // 板卡号,主卡为0。
            iOffset += 4;
            Define.SetIntToByte(0x00080000, dataBuffer, iOffset);   // 包号。
            iOffset += 4;
            FpgaUpgrade_TransData_Byte(true, NET_COMMU_TYPE.FGPA_UPDATE.getValue(), dataBuffer, iOffset);
            //sleep(FGPA_UPDATE_PACKET_INTERVAL);
            MyLog.i("FpgaUpgrade Step 04: Send finish ok.");
        }
        // 获取新版本FPGA。
        iTryCounter = 0;
        while (true) {
            sleep(300);
            if (FpgaUpgrade_EnterUpgradeMode(streamPort) == false) {

                for (cnt = 0; cnt < 10; cnt++) {
                    sleep(100);
                    iNewVersion = FpgaUpgrade_GetVersion(streamPort);
                    if (iNewVersion != -1)
                        break;
                }
                MyLog.i("FpgaUpgrade Step 05: iNewVersion=" + Integer.toHexString(iNewVersion));
                break;
            }
            iTryCounter++;
            if (iTryCounter > 50) break;
        }
    }

    /**
     * 获取当前FPGA版本
     *
     * @return
     */
    public int getFpgaVersion() {
        StreamPort streamPort = new StreamPort();
        FpgaUpgrade_GetVersion(streamPort); // 第一次不正确。
        int iOldVersion = FpgaUpgrade_GetVersion(streamPort);
        for (int cnt = 0; cnt < 10; cnt++) {
            MyLog.sleepForMillisecond(100);
            iOldVersion = FpgaUpgrade_GetVersion(streamPort);
            if (iOldVersion != -1)
                break;
        }
        MyLog.i("FpgaUpgrade Step 01: Old Fpga Version= " + Define.PrintIntToHex(iOldVersion));
//        return Define.PrintIntToHex(iOldVersion);
        return iOldVersion;
    }

    boolean FpgaUpgrade_EnterUpgradeMode(StreamPort streamPort) {
        // return FpgaUpgrade_GetVersion(streamPort)==FGPA_UPDATE_EMPTY_VERSION;
        // modified byfw 2019-4-18 -----start 修正了fpga升级问题  在m60上实现可用
        return FpgaUpgrade_GetVersion(streamPort) == 256;
        // modified byfw 2019-4-18 -----end
    }

    int FpgaUpgrade_GetVersion(StreamPort streamPort) {
        byte[] DataBuffer = new byte[13 + 6 + 1 + 4 + FGPA_UPDATE_ADD_BYTES];
        // byte[] DataBuffer = new byte[8];
        int RetValue;

        //MyLog.i("FpgaUpgrade_GetVersion Step 01: Ready...");
        FpgaUpgrade_TransData_Byte(true, NET_COMMU_TYPE.FGPA_VERSION.getValue()/*0x7c*/, DataBuffer, DataBuffer.length);

        int iRetValue = FpgaUpgrade_GetIntData(streamPort, DataBuffer, NET_COMMU_TYPE.FGPA_VERSION_ACK, 0);
        //  MyLog.i("FpgaUpgrade_GetVersion Step 04: iRetValue= "+iRetValue);
        if (iRetValue == 0x00000001) // 发送命令正确。
        {
            RetValue = Define.GetBtyeToInt(streamPort.ReceBuffer, 4) & 0xFFFF;
            //    MyLog.i("FpgaUpgrade_GetVersion Step 04: iRetValue= "+Define.PrintIntToHex(iRetValue));
            MyLog.i("----Define.GetBtyeToInt = " + RetValue);
            //   MyLog.i("FpgaUpgrade_GetVersion Step 05: iRetValue= "+streamPort.ReceBuffer);
            return RetValue;
        }
        return -1;
    }

    int FpgaUpgrade_GetIntData(StreamPort streamPort, NET_COMMU_TYPE ucCommandType, int iTextOffset) {
        byte[] DataBuffer = new byte[FGPA_UPDATE_ADD_BYTES];
        int iCounter = 0;
        while (iCounter < 10) {   //MyLog.i("FpgaUpgrade_GetData Step 00");
            if (FpgaUpgrade_ReceData_Byte(DataBuffer, DataBuffer.length) < 0) break;
            //MyLog.i("FpgaUpgrade_GetData Step 001");
            for (int i = 0; i < DataBuffer.length; i++) {   //MyLog.i("FpgaUpgrade_GetData Step 002 DataBuffer[i]="+DataBuffer[i]);
                if (streamPort.ReceFrame(DataBuffer[i])) {
                    MyLog.i("FpgaUpgrade_GetData Step 01");
                    if ((ucCommandType == NET_COMMU_TYPE.NONE) || (streamPort.ucCommandType == ucCommandType)) {
                        MyLog.i("FpgaUpgrade_GetData Step 02: ucCommandType=" + Define.PrintIntToHex(ucCommandType.getValue()));
                        return Define.GetBtyeToInt(streamPort.ReceBuffer, 12 + iTextOffset); // 12：Frame Head.
                    }
                }
            }

            iCounter++;
        }
        return -1;
    }

    int FpgaUpgrade_GetIntData(StreamPort streamPort, byte[] DataBuffer, NET_COMMU_TYPE ucCommandType, int iTextOffset) {
        if (DataBuffer == null) return -1;

        for (int i = 0; i < DataBuffer.length; i++) {
            if (streamPort.ReceFrame(DataBuffer[i])) {   //MyLog.i("FpgaUpgrade_GetIntData Step 00 ucCommandType="+ucCommandType);
                if ((ucCommandType == NET_COMMU_TYPE.NONE) || (streamPort.ucCommandType == ucCommandType)) {
                    return Define.GetBtyeToInt(streamPort.ReceBuffer, iTextOffset);
                }
            }
        }
        return -1;
    }

    int FpgaUpgrade_ReceData_Byte(byte[] DataBuffer, int iLength) {   //MyLog.i("FpgaUpgrade_ReceData_Byte Step 00");
        return FpgaUpgrade_TransData_Byte(false, (byte) 0, DataBuffer, iLength);
    }

    public boolean Reboot_LightSet() {
        int result = 0;
        //  while(GetReady() == false);
        while (GetReady() == false) {
            try {
                Thread.sleep(100);
                MyLog.i("------------------------GetReady() = false");
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            continue;
        }
        MyLog.i("------------------------GetReady() = true");
        int iOffset = 0;
        byte[] DataBuffer = new byte[8];
        DataBuffer[iOffset++] = (byte) (0);  // 亮度调节
        DataBuffer[iOffset++] = (byte) (0);
        DataBuffer[iOffset++] = (byte) (0);
        DataBuffer[iOffset++] = (byte) (0);
        DataBuffer[iOffset++] = (byte) (0);          // 亮度使能。
        DataBuffer[iOffset++] = (byte) (0);
        DataBuffer[iOffset++] = (byte) (0);
        DataBuffer[iOffset++] = (byte) (0xA5);
        // A72000                                   0X34 = A72034
        result = FpgaWrite(null, DataBuffer, MOONCELL_FPGA_MIRROR_ADDRESS_PICTURE_CONTROL + MOONCELL_FPGA_MIRROR_ADDRESS_PICTURE_CONTROL_LIGHT_OFFSET, iOffset);

        //MyLog.i(iOffset+"====================================================iValue:"+iValue);
        //    FpgaRead(null, MOONCELL_FPGA_MIRROR_ADDRESS_PICTURE_CONTROL+MOONCELL_FPGA_MIRROR_ADDRESS_PICTURE_CONTROL_LIGHT_OFFSET,iOffset);
        return (result > 0) ? true : false;

    }

    boolean bFirst = true;

    int FpgaUpgrade_TransData_Byte(boolean bWrite, byte ucCommand, byte[] DataBuffer, int iLength) {
        synchronized (objFpgaReadOrWrite) {
            int iProtocalReceAddBytes = 200;
            int iProtocalAddBytes = 13;
            int iOffset = 0;
            byte[] dataBuffer = new byte[iLength + iProtocalAddBytes + iProtocalReceAddBytes];

            for (int i = 0; i < dataBuffer.length; i++) dataBuffer[i] = 0;

            if (bWrite) {
                dataBuffer[iOffset++] = STREAM_SYNC_HEAD;                       // 0x7E，同步头。
                dataBuffer[iOffset++] = STREAM_SYNC_HEAD;                       // 0x7E。
                dataBuffer[iOffset++] = STREAM_SYNC_HEAD2;                      // 0x55。
                dataBuffer[iOffset++] = ucCommand;

                Define.SetIntToByte(0, dataBuffer, iOffset);            // 保留字。
                iOffset += 4;

                Define.SetIntToByte(iLength, dataBuffer, iOffset);              // 正文长度。
                iOffset += 4;

                if (DataBuffer != null && iLength > 0) {

                    System.arraycopy(DataBuffer, 0, dataBuffer, iOffset, iLength);        // 正文内容。
                    iOffset += iLength;
                }

                dataBuffer[iOffset] = Define.GetCheckCodeIn8(dataBuffer, 3, iOffset);  // 校验码，累加和取反。
                iOffset++;
            } else iOffset = iLength;

            //  mask by feng 2019-11-6
            if (bFirst) {
                spiDevice.Operator(dataBuffer, dataBuffer.length); // 第一次运行不正确。
                try {
                    sleep(10);
                } catch (Exception e) {
                }
            }

            // if(ucCommand==0x7c || ucCommand==0x49)
            //    Define.PrintBuffer("2 dataBuffer",dataBuffer,dataBuffer.length);


//            MyLog.showBytes("dataBuffer:",dataBuffer,0);
            if (spiDevice.Operator(dataBuffer, dataBuffer.length) > 0) {
                // MyLog.i("FpgaUpgrade_TransData_Byte Step 02");
                System.arraycopy(dataBuffer, iOffset, DataBuffer, 0, FGPA_UPDATE_ADD_BYTES);
                //MyLog.i("FpgaUpgrade_TransData_Byte Step 03: iLength="+iLength);
                // MyLog.i("FpgaUpgrade_TransData_Byte Step 03");

                //  Define.PrintBuffer("-------- DataBuffer",DataBuffer,DataBuffer.length);

                if (false) {
                    Define.PrintBuffer("Read Rece", DataBuffer, (iLength > 32) ? 32 : iLength);
                }

                bFirst = false;
                return 0;
            }
        }
        return -1;
    }


    public int Operation(StreamPort streamPort) {
//        MyLog.showBytes("ReceBuffer",streamPort.ReceBuffer,0);
        if (NeedExit()) return -1;
        String receDataBuffer = new String(streamPort.ReceBuffer, 0, streamPort.iReceLength);

        //MyLog.i("Received Command: " + receDataBuffer + "\r\n iReceLength= "+ streamPort.iReceLength);

        int iWorkResault = 0, iOffset = 0, iReceLenth = receDataBuffer.length();

        String strFunc = null;
        int iAddress = -1, iLength = -1, iStringLength = -1;
        byte[] DataBuffer = null;

        if (iReceLenth <= 0) return -1;

        while (iOffset < iReceLenth) {
            if (NeedExit()) break;
            String receToatlCommand = receDataBuffer.substring(iOffset);

            //MyLog.i("-------------receToatlCommand:" + receToatlCommand);
            int iCommandSize = receToatlCommand.indexOf(Define.strParamsSeg); // 发送方有可能没有发送时间信息，也就没有分号。

            if (iCommandSize > 0) iOffset++;
            else iCommandSize = iReceLenth - iOffset; // 无命令结束符，只有一条命令，或最后一条命令。
            iOffset += iCommandSize;

            {
                String receSubCommand = receToatlCommand.substring(0, iCommandSize);

                int iCommandParamsStart = receSubCommand.indexOf('=');
                String strValue = receSubCommand.substring(iCommandParamsStart + 1);
                //MyLog.i("strValue:" + strValue);

                try {

                    if (receSubCommand.indexOf(Define.strFunc) == 0) {
                        strFunc = receSubCommand.substring(iCommandParamsStart + 1);
                        //MyLog.i(Define.strFunc + strFunc);
                        continue;
                    }

                    int iValue = Integer.parseInt(strValue);
                    if (iValue < 0) continue;
                    //MyLog.i("iValue:" + iValue);

                    if (receSubCommand.indexOf(Define.strAddress) == 0)
                        iAddress = iValue;  //  上位机data
                    else if (receSubCommand.indexOf(Define.strLength) == 0) iLength = iValue;

                    else if (receSubCommand.indexOf(Define.strStringLength) == 0) {
                        iStringLength = iValue; // 正文总字符的长度，随后是其命令的数据内容。

                        if (iStringLength < streamPort.iReceLength) {
                            int iLen = streamPort.iReceLength - iStringLength; // 正文数据的长度，
                            if (iLen == iLength) { // 正文数据的长度与字符串标识的长度一致。
                                DataBuffer = new byte[iLen];
                                System.arraycopy(streamPort.ReceBuffer, iStringLength, DataBuffer, 0, DataBuffer.length);
                                break;// 此Define.strStringLength字符串为最后一个，跳出处理。
                            }
                        }
                    }
                } catch (Exception e) {
                    MyLog.i(Thread.currentThread().getStackTrace()[2].getFileName() + "-->"
                            + "Function: " + Thread.currentThread().getStackTrace()[2].getMethodName() + "-->"
                            + "Line" + Thread.currentThread().getStackTrace()[2].getLineNumber() + ":\r\n"
                            + "    Error:" + e.getMessage() + "\r\n\r\n"
                    );
                }
            }
        }
        if (strFunc != null) {
            if (true) {
                //  if (strFunc.equals(Define.strGetGiGData)==false)
                //     MyLog.i(Thread.currentThread().getStackTrace()[2].getFileName() + "-->"
                //         + "Function: " + strFunc +" iAddress: 0x" + Long.toHexString(iAddress).toUpperCase()+" iLength: 0x" + Long.toHexString(iLength).toUpperCase());
                switch (strFunc) {
                    case Define.strFlashRead:
                        return FlashRead(streamPort, iAddress, iLength);
                    case Define.strFlashWrite:
                        return FlashWrite(streamPort, DataBuffer, iAddress, iLength);
                    case Define.strFpgaRead:
                        return FpgaRead(streamPort, iAddress, iLength);
                    case Define.strFpgaWrite:
                        /*if (iAddress ==10952704){
                            MyLog.i("iAddress==="+iAddress);
                            MyLog.i("iLength==="+iLength);
                            MyLog.i("strFunc==="+strFunc);
                            MyLog.i("streamPort="+streamPort.toString());
                            MyLog.showBytes("DataBuffer===",DataBuffer,0);
                        }*/
                        return FpgaWrite(streamPort, DataBuffer, iAddress, iLength);
                    case Define.strRegRead:
                        return RegRead(streamPort, iAddress, iLength);
                    case Define.strRegWrite:
                        return RegWrite(streamPort, DataBuffer, iAddress, iLength);
                    case Define.strGetGiGData:
                        synchronized (objFpgaReadOrWrite) {
                            iWorkResault = GetGiGData(streamPort, iLength);
                        }
                        break;
                    case Define.strReset:
                        ledCardCommunication.Request_Exit();
                        break;
                }
            }
        }
        //MyLog.i("---------------------------------------Rece:" + receDataBuffer);
        return iWorkResault;
    }

    /**
     * 设置偏移
     *
     * @param screenX
     * @param screenY
     * @param cutW
     * @param cutH
     * @param so1X
     * @param so1Y
     * @param so2X
     * @param so2Y
     * @return 索引0-1:大屏左;2-3大屏上;4-5:截取宽;6-7:截取高;12-13:网口1Y;14-15:网口1X;16-17:网口2Y;18-19:网口2X
     */
    public int setOffset(int screenX, int screenY, int cutW, int cutH, int so1X, int so1Y, int so2X, int so2Y) {
        byte[] bs = OffsetData.data;
        byte[] screenXs = OffsetData.intToByteArray(screenX);
        byte[] screenYs = OffsetData.intToByteArray(screenY);
        byte[] cutWs = OffsetData.intToByteArray(cutW);
        byte[] cutHs = OffsetData.intToByteArray(cutH);
        byte[] so1Xs = OffsetData.intToByteArray(so1X);
        byte[] so1Ys = OffsetData.intToByteArray(so1Y);
        byte[] so2Xs = OffsetData.intToByteArray(so2X);
        byte[] so2Ys = OffsetData.intToByteArray(so2Y);
        bs[0] = screenXs[0];
        bs[1] = screenXs[1];
        bs[2] = screenYs[0];
        bs[3] = screenYs[1];
        bs[4] = cutWs[0];
        bs[5] = cutWs[1];
        bs[6] = cutHs[0];
        bs[7] = cutHs[1];
        bs[12] = so1Ys[0];
        bs[13] = so1Ys[1];
        bs[14] = so1Xs[0];
        bs[15] = so1Xs[1];
        bs[16] = so2Ys[0];
        bs[17] = so2Ys[1];
        bs[18] = so2Xs[0];
        bs[19] = so2Xs[1];
        return FpgaWrite(new StreamPort(), bs, 10952704, 256);
    }


    int ReadLocalFile(RandomAccessFile randomAccessFile, StreamPort streamPort, int iAddress, int iLength) {
        //MyLog.i("ReadLocalFile : iAddress: 0x" + Long.toHexString(iAddress).toUpperCase() + "; iLength=" + iLength);
        if (NeedExit()) return -1;
        if (randomAccessFile == null) return -1;
        if (iAddress < 0) return -1;
        if (iLength <= 0) return -1;
        if ((iAddress + iLength) > Define.FLASH_SIZE) return -1;

        synchronized (this) {
            byte[] DataBuffer = new byte[iLength];
            try {
                int iReadLength = 0;
                randomAccessFile.seek(iAddress);
                if ((iReadLength = randomAccessFile.read(DataBuffer)) < 0) {
                    return -1;
                }
                if (ledCardCommunication != null)
                    if (ledCardCommunication.clientsManage != null)
                        if (streamPort != null) ledCardCommunication.clientsManage.
                                TransData_Byte(streamPort.clientIpAddress, NET_COMMU_TYPE.FPGA_MOONCELL.getValue(), (byte) 0, streamPort.ucPipeId, DataBuffer, iReadLength);
            } catch (Exception e) {
                MyLog.i(Thread.currentThread().getStackTrace()[2].getFileName() + "-->"
                        + Thread.currentThread().getStackTrace()[2].getMethodName() + "()-->"
                        + "L" + Thread.currentThread().getStackTrace()[2].getLineNumber() + ":\r\n"
                        + "    Error:" + e.getMessage() + "\r\n\r\n"
                );
                if (bNeedExitRequest)
                    ledCardCommunication.Request_Exit();
            }
        }
        return 0;
    }

    int WriteLocalFile(RandomAccessFile randomAccessFile, StreamPort streamPort, byte[] DataBuffer, int iAddress, int iLength) {
        //MyLog.i("WriteLocalFile : iAddress=" + iAddress + "; iLength=" + iLength + " [0]="+DataBuffer[0]);
        if (NeedExit()) return -1;
        if (randomAccessFile == null) return -1;
        if (iAddress < 0) return -1;
        if (iLength <= 0) return -1;
        if (streamPort == null) return -1;
        if ((iAddress + iLength) > Define.FLASH_SIZE) return -1;
        synchronized (this) {
            try {
                randomAccessFile.seek(iAddress);
                randomAccessFile.write(DataBuffer, 0, iLength);
                //modified by alahover 20190413 -start
                if (streamPort.m_bAck)
                    WriteAck(streamPort, DataBuffer);
                //WriteAck(streamPort,DataBuffer);
                //modified by alahover 20190413 -end
            } catch (Exception e) {
                MyLog.i(Thread.currentThread().getStackTrace()[2].getFileName() + "-->"
                        + "Function: " + Thread.currentThread().getStackTrace()[2].getMethodName() + "-->"
                        + "Line" + Thread.currentThread().getStackTrace()[2].getLineNumber() + ":\r\n"
                        + "    Error:" + e.getMessage() + "\r\n\r\n"
                );
                if (bNeedExitRequest)
                    ledCardCommunication.Request_Exit();
            }
        }
        return 0;
    }

    /**/
    int LightMidify(int iLightValue){ // 0~0x100.
        if (iLightValue < 0) return -1;
        if (iLightValue > 0x100) return -1;
        iLightValue *= 2; // 0~0x200.    //4// 十位。
        //     if (iLightValue<10) iLightValue=10; // 小于10会黑屏，禁止黑屏。
        //     MyLog.i("====================================================iLightValue:"+iLightValue);
        return (iLightValue << 20 | iLightValue << 10 | iLightValue);// RGB同样的颜色。

    }

    public boolean LightSet(int iLightValue) {// 0~0x100.
        int result = 0;
        int iValue;
        //  if (iLightValue<0) return false;
        if (GetReady() == false) return false;
        iValue = LightMidify(iLightValue);
//        MyLog.i("iValue=========="+iValue);
        if (iValue < 0) return false;
        int iOffset = 0;
        byte[] DataBuffer = new byte[8];
        DataBuffer[iOffset++] = (byte) (iValue >> 24);  // 亮度调节
        DataBuffer[iOffset++] = (byte) (iValue >> 16);
        DataBuffer[iOffset++] = (byte) (iValue >> 8);
        DataBuffer[iOffset++] = (byte) (iValue >> 0);
        DataBuffer[iOffset++] = (byte) (0);          // 亮度使能。
        DataBuffer[iOffset++] = (byte) (0);
        DataBuffer[iOffset++] = (byte) (0);
        DataBuffer[iOffset++] = (byte) (0xA5);
        //  A72000
        result = FpgaWrite(null, DataBuffer, MOONCELL_FPGA_MIRROR_ADDRESS_PICTURE_CONTROL + MOONCELL_FPGA_MIRROR_ADDRESS_PICTURE_CONTROL_LIGHT_OFFSET, iOffset);
//        MyLog.showBytes("DataBuffer=========",DataBuffer,0);
        //MyLog.i(iOffset+"====================================================iValue:"+iValue);
        //    FpgaRead(null, MOONCELL_FPGA_MIRROR_ADDRESS_PICTURE_CONTROL+MOONCELL_FPGA_MIRROR_ADDRESS_PICTURE_CONTROL_LIGHT_OFFSET,iOffset);
//        MyLog.i("LightSetresult======================"+result);
        return (result >= 0) ? true : false;
    }

    /**
     * 查询亮度
     *
     * @return
     */
    public int getBrightness() {
        int iOffset = 0;
        int iValue;
        byte[] DataBuffer = new byte[8];
        int result = SpiOperator(false, MOONCELL_FPGA_MIRROR_ADDRESS_PICTURE_CONTROL + MOONCELL_FPGA_MIRROR_ADDRESS_PICTURE_CONTROL_LIGHT_OFFSET, DataBuffer, DataBuffer.length, true);
//        MyLog.i("reada=========="+result);
        iValue = ((DataBuffer[0] & 0xFF) << 24) + ((DataBuffer[1] & 0xFF) << 16) + ((DataBuffer[2] & 0xFF) << 8) + ((DataBuffer[3] & 0xFF) << 0);
//        MyLog.i("iValue=========="+iValue);
        return LightMidifyOff(iValue);
    }

    public int LightMidifyOff(int iValue) // 0~0x100.
    {
        return (iValue >> 20 & iValue >> 10 & iValue) / 2;// RGB同样的颜色。
    }

    public void DispalyOff() {
        LightSet(999);
    }


    public byte GetMultiPortBusyStatus() {
        byte bitStatus = (byte) 0xFF;
        byte[] DataBuffer = new byte[GetDisplayNetPortNum() * 2];
        if (Spi_ReceData_Byte(DataBuffer, MOONCELL_FPGA_REG_ADDRESS_MULTI_PORT_STATUS, DataBuffer.length) >= 0) {
            bitStatus = 0;
            for (int i = 0; i < GetDisplayNetPortNum(); i++) {
                if ((DataBuffer[(i * 2) + 1] & (0x01 << 1)) != 0)
                    bitStatus |= (1 << i);
            }
        }
        return bitStatus;
    }

    public byte GetMultiPortHaveData() {
        byte bitStatus = 0;
        byte gigNums = 8;// GetDisplayNetPortNum() ;       // Px口状态标志
        byte[] DataBuffer = new byte[gigNums * 2];            // Bit2：Px口接收VCS数据包状态：0表示空闲，1表示接收到一个VCS数据包
        // MyLog.i("-------fw 43");
        if (Spi_ReceData_Byte(DataBuffer, MOONCELL_FPGA_REG_ADDRESS_MULTI_PORT_STATUS, DataBuffer.length) >= 0) {
            for (int i = 0; i < gigNums; i++) {
                if ((DataBuffer[(i * 2) + 1] & (0x01 << 2)) != 0)
                    bitStatus |= (1 << i);
            }
        }
        return bitStatus;
    }
    byte[] GiGData_DataBuffer = new byte[2048]; // FpgaWrite 要清除GiGData_DataBuffer[0]
    public int GetGiGData(StreamPort streamPort, int iLength) {
        int iWorkResault = -1;
        for (int i = 0; i < GiGData_DataBuffer.length; i++)
            GiGData_DataBuffer[i] = (byte) 0; // 无数据返回空。

        byte bitStatus = GetMultiPortHaveData();
        if (bitStatus != 0) {         // 表示px port 接收一个VCS数据包ing
            for (int i = 0; i < MOONCELL_FPGA_PORT_NUMBER; i++) {
                if ((bitStatus & (1 << i)) != 0) {
                    byte[] DataBuffer = new byte[2048];
                    // MyLog.i("-------fw 44");
                    if (Spi_ReceData_Byte(DataBuffer, (MOONCELL_FPGA_REG_ADDRESS_BASIC_RECV + i * MOONCELL_FPGA_REG_ADDRESS_BASIC_STEP), DataBuffer.length) >= 0) {
                        int iAliableLength = (int) ((DataBuffer[DataBuffer.length - 2] & 0xff) << 8 | (DataBuffer[DataBuffer.length - 1] & 0xff));
                        if (iAliableLength > 16)
                            if (iAliableLength <= 1460)
                                if (DataBuffer[0] == (byte) 0x55)
                                    if (DataBuffer[1] == (byte) 0x55)
                                    // if (DataBuffer[16]!=(byte) 0xA5)
                                    //    if (DataBuffer[17]!=(byte) 0xA5)
                                    {
                                        synchronized (GiGData_DataBuffer) {
                                            GiGData_DataBuffer[0] = 0x04;
                                            GiGData_DataBuffer[1] = (byte) ((iAliableLength >> 8) & 0xff);
                                            GiGData_DataBuffer[2] = (byte) ((iAliableLength >> 0) & 0xff);
                                            GiGData_DataBuffer[3] = (byte) i;
                                            System.arraycopy(DataBuffer, 0, GiGData_DataBuffer, 16, iAliableLength);//+4); // 4:For CRC Code.
                                        }
                                        iWorkResault = 0;
                                    }
                    }
                }
            }

        }
        if (streamPort != null)
            if (ledCardCommunication != null)
                if (ledCardCommunication.clientsManage != null) {
                    ledCardCommunication.clientsManage.
                            TransData_Byte(streamPort.clientIpAddress, NET_COMMU_TYPE.FPGA_MOONCELL.getValue(), (byte) 0, streamPort.ucPipeId, GiGData_DataBuffer, iLength);
//                    Define.PrintBuffer("spi gig date back to net ", GiGData_DataBuffer, (iLength > 64) ? 64 : iLength);
                }
        return iWorkResault;
    }

    void VirtuleFpgaParamsFileInitial() {
        if (Define.FileExist(strStoragePath + Define.MOONCELL_FPGA_PARAMS_FILE_NAME, Define.FLASH_SIZE))
            return;
        byte[] dataBuffer = new byte[Define.FLASH_SIZE];
        for (int i = 0; i < dataBuffer.length; i++) dataBuffer[i] = (byte) 0;
        synchronized (this) {
            try {
                fpgaParamsFile.seek(0);
                fpgaParamsFile.write(dataBuffer);
            } catch (Exception e) {
                MyLog.i(Thread.currentThread().getStackTrace()[2].getFileName() + "-->"
                        + "Function: " + Thread.currentThread().getStackTrace()[2].getMethodName() + "-->"
                        + "Line" + Thread.currentThread().getStackTrace()[2].getLineNumber() + ":\r\n"
                        + "    Error:" + e.getMessage() + "\r\n\r\n"
                );
            }
        }
    }

    void VirtuleRegsFileInitial() {
        if (Define.FileExist(strStoragePath + Define.MOONCELL_FPGA_REG_FILE_NAME, REG_SIZE)) return;
        byte[] DataBuffer = new byte[REG_SIZE];     // REG_SIZE = 4k * 256
        for (int i = 0; i < DataBuffer.length; i++) DataBuffer[i] = (byte) 0;   // DataBuffer 清 0
        {
            int iOffset = 0;
            DataBuffer[iOffset++] = (byte) 0x93;
            DataBuffer[iOffset++] = (byte) 0x00;
            DataBuffer[iOffset++] = (byte) 0x00;
            DataBuffer[iOffset++] = (byte) 0x00;

            DataBuffer[iOffset++] = (byte) 0x00;
            DataBuffer[iOffset++] = (byte) 0x18;
            DataBuffer[iOffset++] = (byte) 0x04;
            DataBuffer[iOffset++] = (byte) 0x21;

            for (; iOffset < 16; ) DataBuffer[iOffset++] = (byte) iOffset;
        }
        synchronized (this) {
            try {
                fpgaRegFile.seek(0);
                fpgaRegFile.write(DataBuffer);
            } catch (Exception e) {
                MyLog.i(Thread.currentThread().getStackTrace()[2].getFileName() + "-->"
                        + "Function: " + Thread.currentThread().getStackTrace()[2].getMethodName() + "-->"
                        + "Line" + Thread.currentThread().getStackTrace()[2].getLineNumber() + ":\r\n"
                        + "    Error:" + e.getMessage() + "\r\n\r\n"
                );
            }
        }
    }


    void FpgaInitial() {
        try {
            {
                byte[] DataBuffer = new byte[MOONCELL_FPGA_MIRROR_ADDRESS_BASIC_STEP];
                for (int i = 0; i < MOONCELL_FPGA_PORT_NUMBER; i++) {  // MOONCELL_FPGA_PORT_NUMBER = 8
                    fpgaParamsFile.seek(MOONCELL_FPGA_FLASH_ADDRESS_GPORT_PARAMS + i * MOONCELL_FPGA_MIRROR_ADDRESS_BASIC_STEP);
                    if (fpgaParamsFile.read(DataBuffer) >= 0) {
                        // A70000           +   0X400 * i
                        FpgaWrite(null, DataBuffer, MOONCELL_FPGA_MIRROR_ADDRESS_BASIC + i * MOONCELL_FPGA_MIRROR_ADDRESS_BASIC_STEP, DataBuffer.length); // length = 1k
                    } else {
                        MyLog.i(Thread.currentThread().getStackTrace()[2].getFileName() + "-->"
                                + Thread.currentThread().getStackTrace()[2].getMethodName() + "()-->"
                                + "L" + Thread.currentThread().getStackTrace()[2].getLineNumber() + ":\r\n"
                                + "    Error:" + "Can't Read data from fpgaParamsFile MOONCELL_FPGA_FLASH_ADDRESS_GPORT_PARAMS + i * MOONCELL_FPGA_MIRROR_ADDRESS_BASIC_STEP @ 0x" +
                                Long.toHexString(MOONCELL_FPGA_FLASH_ADDRESS_GPORT_PARAMS + i * MOONCELL_FPGA_MIRROR_ADDRESS_BASIC_STEP).toUpperCase()
                                + "\r\n\r\n"
                        );
                    }
                }
            }
            {
                byte[] DataBuffer = new byte[256];
                fpgaParamsFile.seek(MOONCELL_FPGA_FLASH_ADDRESS_PICTURE_CONTROL);
                if (fpgaParamsFile.read(DataBuffer) >= 0) {
                    int iRealLight = -1, iOffset = 0;

                    //if (ledCardCommunication != null)
                    //    iRealLight = ledCardCommunication.Get_Light();

//                int iValue = LightMidify(ledCardCommunication.clientsManage.ms.workParams.iLightValue); // 获取到非法的亮度会设置为0，黑屏。
                    int iValue = LightMidify(1);
                    if (iValue > 0) {
                        iOffset = MOONCELL_FPGA_MIRROR_ADDRESS_PICTURE_CONTROL_LIGHT_OFFSET;
                        MyLog.i("初始化亮度............." + iValue);
                        DataBuffer[iOffset++] = (byte) (iValue >> 24);
                        DataBuffer[iOffset++] = (byte) (iValue >> 16);
                        DataBuffer[iOffset++] = (byte) (iValue >> 8);
                        DataBuffer[iOffset++] = (byte) (iValue >> 0);
                        DataBuffer[iOffset++] = (byte) 0; // 亮度使能。
                        DataBuffer[iOffset++] = (byte) 0;
                        DataBuffer[iOffset++] = (byte) 0;
                        DataBuffer[iOffset++] = (byte) 0xA5;
                    } else {
                        iOffset = MOONCELL_FPGA_MIRROR_ADDRESS_PICTURE_CONTROL_LIGHT_ENABLE_OFFSET;   // 0X38
                        DataBuffer[iOffset++] = (byte) 0; // 亮度禁止。
                        DataBuffer[iOffset++] = (byte) 0;
                        DataBuffer[iOffset++] = (byte) 0;
                        DataBuffer[iOffset++] = (byte) 0;
                    }
                    //    A72000
                    FpgaWrite(null, DataBuffer, MOONCELL_FPGA_MIRROR_ADDRESS_PICTURE_CONTROL, DataBuffer.length);
                } else {
                    MyLog.i(Thread.currentThread().getStackTrace()[2].getFileName() + "-->"
                            + Thread.currentThread().getStackTrace()[2].getMethodName() + "()-->"
                            + "L" + Thread.currentThread().getStackTrace()[2].getLineNumber() + ":\r\n"
                            + "    Error:" + "Can't Read data from fpgaParamsFile MOONCELL_FPGA_FLASH_ADDRESS_PICTURE_CONTROL @ 0x" +
                            Long.toHexString(MOONCELL_FPGA_FLASH_ADDRESS_PICTURE_CONTROL).toUpperCase()
                            + "\r\n\r\n"
                    );
                }
            }
            //if (false)
            {
                boolean bNeedSetPortNum = true;
                byte[] DataBuffer = new byte[16];
                fpgaParamsFile.seek(MOONCELL_FPGA_FLASH_ADDRESS_GPORT_NUM_PARAMS);
                if (fpgaParamsFile.read(DataBuffer) >= 0) {
                    if (DataBuffer[0] == (byte) 0xAA)
                        if (DataBuffer[1] == (byte) 0xAA)
                            if (DataBuffer[2] == (byte) 0xAA)
                                if (DataBuffer[3] == (byte) 0xAA)
                                    if (DataBuffer[7] == (byte) GetDisplayNetPortNum())
                                        if (DataBuffer[8] == (byte) 0x55)
                                            if (DataBuffer[9] == (byte) 0x55)
                                                if (DataBuffer[10] == (byte) 0x55)
                                                    if (DataBuffer[11] == (byte) 0x55)
                                                        bNeedSetPortNum = false;


                } else {
                    MyLog.i(Thread.currentThread().getStackTrace()[2].getFileName() + "-->"
                            + Thread.currentThread().getStackTrace()[2].getMethodName() + "()-->"
                            + "L" + Thread.currentThread().getStackTrace()[2].getLineNumber() + ":\r\n"
                            + "    Error:" + "Can't Read data from fpgaParamsFile MOONCELL_FPGA_FLASH_ADDRESS_GPORT_NUM_PARAMS @ 0x" +
                            Long.toHexString(MOONCELL_FPGA_FLASH_ADDRESS_GPORT_NUM_PARAMS).toUpperCase()
                            + "\r\n\r\n"
                    );
                }
                if (bNeedSetPortNum) {
                    int iOffset = 0;
                    DataBuffer[iOffset++] = (byte) 0xAA;
                    DataBuffer[iOffset++] = (byte) 0xAA;
                    DataBuffer[iOffset++] = (byte) 0xAA;
                    DataBuffer[iOffset++] = (byte) 0xAA;

                    DataBuffer[iOffset++] = (byte) 0x00;
                    DataBuffer[iOffset++] = (byte) 0x00;
                    DataBuffer[iOffset++] = (byte) 0x00;
                    DataBuffer[iOffset++] = (byte) GetDisplayNetPortNum(); // 千兆网口端口数量.

                    DataBuffer[iOffset++] = (byte) 0x55;
                    DataBuffer[iOffset++] = (byte) 0x55;
                    DataBuffer[iOffset++] = (byte) 0x55;
                    DataBuffer[iOffset++] = (byte) 0x55;

                    fpgaParamsFile.seek(MOONCELL_FPGA_FLASH_ADDRESS_GPORT_NUM_PARAMS);
                    fpgaParamsFile.write(DataBuffer);
                }
                //
            }
            /*
             */
            //MyLog.i(Thread.currentThread().getStackTrace()[2].getMethodName() + " L" + Thread.currentThread().getStackTrace()[2].getLineNumber() + " curAddr=");
            //GigeInial();
            FpgaSystemConfig();
        } catch (Exception e) {
            MyLog.i(Thread.currentThread().getStackTrace()[2].getFileName() + "-->"
                    + Thread.currentThread().getStackTrace()[2].getMethodName() + "()-->"
                    + "L" + Thread.currentThread().getStackTrace()[2].getLineNumber() + ":\r\n"
                    + "    Error:" + e.getMessage() + "\r\n\r\n"
            );
        }
    }


    void FpgaSystemConfig() {
        int iOffset = 0;
        byte[] DataBuffer = new byte[16 * 4];
        DataBuffer[3] = 0;

        iOffset = 4;
        DataBuffer[iOffset++] = (byte) 0x6F;
        DataBuffer[iOffset++] = (byte) 0x60;
        DataBuffer[iOffset++] = (byte) 0x33;
        DataBuffer[iOffset++] = (byte) 0x9A;

        iOffset = 63;
        DataBuffer[iOffset++] = (byte) 0xA5;

        FpgaWrite(null, DataBuffer, MOONCELL_FPGA_MIRROR_ADDRESS_SYSTEM_CONFIG, DataBuffer.length);
    }

    boolean bReady = false;

    public boolean GetReady() {
        return bReady;
    }

    Boolean bNeedExit = false;

    boolean NeedExit() {
        return bNeedExit;
    }

    boolean bNeedExitRequest = true; // 用于重新加载FPGA新参数退出时（优盘加载等），其他模块异常返回时，不要申请退出。

    void Exit(boolean bNeedExitRequest) {
        if (NeedExit()) return;
        bNeedExit = true;
        bReady = false;
        bNeedExitRequest = false;

        try {
            if (fpgaParamsFile != null) {
                fpgaParamsFile.close();
                fpgaParamsFile = null;
            }
            if (fpgaRegFile != null) {
                fpgaRegFile.close();
                fpgaRegFile = null;
            }
            if (spiDevice != null) {
                // JNI ERROR (app bug): accessed stale local reference 0x1d50000d (index 3 in a table of size 1)
                // JNI WARNING: 0x1d50000d is not a valid JNI reference
                spiDevice.Exit();
                spiDevice = null;
            }
        } catch (Exception e) {
        }
        MyLog.i(" " + Thread.currentThread().getStackTrace()[2].getFileName() + "-->"
                + "Function: " + Thread.currentThread().getStackTrace()[2].getMethodName() + "-->"
                + "Line" + Thread.currentThread().getStackTrace()[2].getLineNumber() + ":\r\n"
        );
    }

    int PX_BROARDCAST = 0xFF; // 0：第一个网口，。。。
    int BROARDCAST_SEND_REG_ADDR = 0xFF0000;

    int PX_ADDR(int n) {
        return (n == PX_BROARDCAST) ? BROARDCAST_SEND_REG_ADDR : (MOONCELL_FPGA_REG_ADDRESS_BASIC_SEND + n * MOONCELL_FPGA_REG_ADDRESS_BASIC_STEP);
    }

    int PX_N(int addr) {
        return ((addr - MOONCELL_FPGA_REG_ADDRESS_BASIC_SEND) / MOONCELL_FPGA_REG_ADDRESS_BASIC_STEP);
    }


    int RECEIVED_CARD_INTERNAL_ADDRESS_SDRAM = 0xD0000000;
    int RECEIVED_CARD_INTERNAL_ADDRESS_REG = 0xDA000000;
    int RECEIVED_CARD_INTERNAL_ADDRESS_FLASH = 0xDF000000;
    int HUB_BOARDCAST_ADDRESS = 0x10FF;
    int RECEIVED_CARD_BOARDCAST_ADDRESS = 0xFFF; // 0：第一个接收卡，。。


    public static int RECEIVED_CARD_TYPE_T6 = 0;
    public static int iReceivedCardType_Function = 1;
    public static int RECEIVED_CARD_TYPE_BOARDCASE = 0xF;

    public static int iReceivedCard_BaseAddress = 0xDF800;
    public static int iReceivedCard_BaseSize = 0x400;

    public static int iReceivedCard_WriteAddress = iReceivedCard_BaseAddress;
    public static int iReceivedCard_ReadAddress = iReceivedCard_BaseAddress + iReceivedCard_BaseSize;  //0xDF800 + 0x400


    int make_word(int a, int b) {
        return (a & 0xff) | (b << 8);
    }

    int make_long(int a, int b) {
        return (a & 0xffff) | (b << 16);
    }

    short loword(int w) {
        return ((short) ((w >> 0) & 0xffff));
    }

    short hiword(int w) {
        return ((short) ((w >> 16) & 0xffff));
    }

    byte lobyte(int w) {
        return ((byte) ((w >> 0) & 0xff));
    }

    byte hibyte(int w) {
        return ((byte) ((w >> 8) & 0xff));
    }

    int make_vcs_io_address(int io_type, int addr) {
        return (io_type + addr);
    }

    int make_device_address(int ha, int type, int la) {
        return ((ha << 16) | (type << 12) | la);
    }

    int vcx_io_address(int ha, int type, int la) {
        return make_long((type << 12) | la, ha);
    }

    int ReceivedCard_Operator(boolean bWrite, boolean bNeedWriteAck, int iPortID, int iHight16Address, int iCardType, int iCardID, int iDataAddress, byte[] Databuffer, int iLength) {
        int iWorkResault = 0;
        if (iLength > 0)
            if (Databuffer == null) return -1;

        byte[] TransBuffer = new byte[MOONCELL_FPGA_REG_ADDRESS_BASIC_STEP];     //0x10000 = 65536

        int iOffset = 0;
        // Head:
        {
            TransBuffer[iOffset++] = (byte) 0x9A;
            TransBuffer[iOffset++] = (byte) (bWrite ? ((bNeedWriteAck) ? 0xAD : 0x3D) : 0x0D);


            Define.SetShortToByte(Define.htons((iLength / 4)), TransBuffer, iOffset);
            iOffset += 2;

            Define.SetIntToByte(Define.hton_l(vcx_io_address(iHight16Address, iCardType, iCardID & RECEIVED_CARD_BOARDCAST_ADDRESS)), TransBuffer, iOffset);  // TA
            iOffset += 4;                                                                             // 0xFFF

            Define.SetIntToByte(Define.hton_l(vcx_io_address(0xf0, 0, 0x55)), TransBuffer, iOffset);  // SA
            iOffset += 4;

            Define.SetIntToByte(Define.hton_l(iDataAddress), TransBuffer, iOffset);  // PIO   iDataAddress = 0XD00DFC00
            iOffset += 4;

            Define.SetShortToByte(0, TransBuffer, iOffset);                 // ANS
            iOffset += 2;

            CRC32 crc32 = new CRC32();
            crc32.update(TransBuffer, 0, iOffset);
            Define.SetIntToByte(Define.hton_l((int) crc32.getValue()), TransBuffer, iOffset);
            iOffset += 4;
        }
        // Text:
        if (bWrite) {
            System.arraycopy(Databuffer, 0, TransBuffer, iOffset, iLength);
            iOffset += iLength;
            // Check:
            CRC32 crc32 = new CRC32();
            crc32.update(Databuffer, 0, iLength);
            Define.SetIntToByte(Define.hton_l((int) crc32.getValue()), TransBuffer, iOffset);
            iOffset += 4;
        }
        synchronized (objFpgaReadOrWrite) {
            // Trans:
            //modified by alahover 20190413 -start
            //SpiOperator(true, PX_ADDR(iPortID), TransBuffer, iOffset);
            //  MyLog.i("-------fw 6");
            SpiOperator(true, PX_ADDR(iPortID), TransBuffer, iOffset, false);
            //modified by alahover 20190413 -end
            if (bWrite) {
                if (bNeedWriteAck) {
                    if ((iCardID & RECEIVED_CARD_BOARDCAST_ADDRESS) < RECEIVED_CARD_BOARDCAST_ADDRESS)  // 增加对HUB设备的判断.
                    {
                        if (ReceivedCard_WaitAck(Databuffer, iLength) == 0)
                            if (Databuffer[0] != 0) iWorkResault = 0;
                    }
                }
            } else {
                iWorkResault = ReceivedCard_WaitAck(Databuffer, iLength);
            }
        }
        return iWorkResault;
    }

    int ReceivedCard_WaitAck(byte[] Databuffer, int iLength) {
        int iWorkResault = -1;

        if (iLength > 0)
            if (Databuffer == null) return iWorkResault;

        CRC32 crc32 = new CRC32();
        int iTimes = 100;

        do {
            while (iTimes > 0) {
                iTimes--;
                try {
                    sleep(5);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                if (GetGiGData(null, 0) == 0)
                    if (GiGData_DataBuffer[0] == 0x04) {
                        MyLog.i("Rece Data");
                        break;
                    }
            }
            if (GiGData_DataBuffer[0] != 0x04) {
                MyLog.i("No Data");
                break;
            }
            crc32.update(GiGData_DataBuffer, 16 + 2 + 22, iLength);
            int iReceCrc32 = Define.hton_l(Define.GetIntFromByte(GiGData_DataBuffer, 16 + 2 + 22 + iLength));
            if (iReceCrc32 != (int) (crc32.getValue())) // 接收过来的CRC低16位数据为0。
            {
                MyLog.i("Crc Error: iReceCrc32=" + Integer.toHexString(iReceCrc32).toUpperCase());
                MyLog.i("crc32.getValue()=" + Integer.toHexString((int) crc32.getValue()).toUpperCase());
                break;
            }

            System.arraycopy(GiGData_DataBuffer, 16 + 2 + 22, Databuffer, 0, iLength);
            iWorkResault = 0;
        } while (false);
        return iWorkResault;
    }

    /**
     * @MethodName:
     * @Description:    获取接收卡数量
     * @author: Lay
     * @date:   2020/12/7 15:52
    */
    public int ReceivedCard_GetNumber(int iPortNumber, int iReceCardType) // type:0~F,各种接收卡类型，F通播。
    {
        int iReceivedCardNumber = 0;
        byte[] DataBuffer = new byte[64];


        if (ReceivedCard_Operator(true, false, iPortNumber,
                HUB_BOARDCAST_ADDRESS, RECEIVED_CARD_TYPE_BOARDCASE, RECEIVED_CARD_BOARDCAST_ADDRESS,
                0x35000CDD, DataBuffer, DataBuffer.length) == 0) {

            if (ReceivedCard_WaitAck(DataBuffer, DataBuffer.length) == 0) {
                //Define.PrintBuffer("Read Rece Len",DataBuffer,DataBuffer.length);
                iReceivedCardNumber = Define.hton_l(Define.GetIntFromByte(DataBuffer, iReceCardType * 4));
            }
        }
        MyLog.i("iReceivedCardNumber=" + iReceivedCardNumber);

        return iReceivedCardNumber;
    }

    int iCounterPacket = 0;

    void ReceivedCardTest() {
        byte[] DataBuffer = new byte[528];

        //ReceivedCard_GetNumber(0,0);

        //       iCounterPacket++;
        //       for (int i=0;i<DataBuffer.length;i++) DataBuffer[i]=(byte)(iCounterPacket%255);
        //Define.PrintBuffer("Write Trans T6",DataBuffer,12);
        //     ReceivedCard_Write(RECEIVED_CARD_TYPE_T6,0,DataBuffer);// PX_BROARDCAST

        byte[] BufferHead = new byte[16];
        if (ReceivedCard_Read(RECEIVED_CARD_TYPE_T6, 0, RECEIVED_CARD_INTERNAL_ADDRESS_SDRAM + 0x30000, BufferHead) == 0) {
            Define.PrintBuffer("Read Rece T6 BufferHead --------------------", BufferHead, BufferHead.length);
        }
        if (BufferHead[0] != 0 && BufferHead[1] != 0 && BufferHead[2] != 0 && BufferHead[3] != 0) {
            byte[] DataBuffer2 = new byte[512];
            if (ReceivedCard_Read(RECEIVED_CARD_TYPE_T6, 0, RECEIVED_CARD_INTERNAL_ADDRESS_SDRAM + 0x30010, DataBuffer2) == 0) {
                Define.PrintBuffer("Read Rece T6", DataBuffer2, DataBuffer2.length);
            }
        }


    }

    int ReceivedCard_Write(int iReceivedCardType, int iCardID, int addr, byte[] DataBuffer) {
        int iOffset = 0;
        byte[] TransBuffer = new byte[4 * 3 + DataBuffer.length];

        Define.SetIntToByte(Define.UINT_SPECTIAL_FLAG, TransBuffer, iOffset);
        iOffset += 4;
        Define.SetIntToByte(0, TransBuffer, iOffset);
        iOffset += 4;
        Define.SetIntToByte(DataBuffer.length, TransBuffer, iOffset);
        iOffset += 4;
        System.arraycopy(DataBuffer, 0, TransBuffer, iOffset, DataBuffer.length);
        iOffset += DataBuffer.length;

        return ReceivedCard_Operator(true, false, 0, 0, iReceivedCardType, iCardID,
                addr, TransBuffer, TransBuffer.length);  //RECEIVED_CARD_INTERNAL_ADDRESS_SDRAM+iReceivedCard_WriteAddress
    }

    int ReceivedCard_Read(int iReceivedCardType, int iCardID, int addr, byte[] DataBuffer) {
        return ReceivedCard_Operator(false, false, 0, 0, iReceivedCardType, iCardID,
                addr, DataBuffer, DataBuffer.length);  //iReceivedCard_ReadAddress
    }                       // 0xD0000000 + 0xDF800 + 0x400 = 0XD00DFC00

    // RECEIVED_CARD_INTERNAL_ADDRESS_SDRAM+0x30000
    int GetFpagGigPortNum() {

        return 1;
    }
/*

    void GigeInial()
    {   giginfo  pgigdat =new giginfo();
        for (int i=0;i<8;i++)
            init_fpga_gige_config(i,pgigdat);
     }

    int init_fpga_gige_config(int px,giginfo  pgigdat)
    {
        byte [] g_commIoBuffer1=new byte[MOONCELL_FPGA_MIRROR_ADDRESS_BASIC_STEP];
        // 配置GIG图像发送指令存储器
        byte []  header =new byte[18];
        byte []  tempcalcval =new byte[4];;
        int curAddr=0;
        byte devid[] = {0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x78};
        CRC32 crc32 = new CRC32();

        boolean _m_img_sel = (pgigdat.imgsel == 0) ? true : false ;

        curAddr = 0 ;

        // 系统连接包(包长度:32BYTES == 前导(2) + 包头(22) + 后缀(2) + 空值(6))
        g_commIoBuffer1[curAddr++] =(byte) 0x55 ;
        g_commIoBuffer1[curAddr++] = (byte)0x55 ;

        {   int iOffset=0;
            header[iOffset++]=(byte)0x9A;
            header[iOffset++]=(byte)0x3D;
            Define.SetShortToByte(0,header,iOffset); iOffset+=2;

            Define.SetIntToByte(Define.hton_l(make_device_address(0x10ff,0,0)),header,iOffset); iOffset+=4;
            Define.SetIntToByte(Define.hton_l((0x00<<24)| (px<<16) | (_m_img_sel ? 0 : (1<<15)) | (Define.chksum_crc16(devid,0,devid.length) & 0x7fff)  ),header,iOffset); iOffset+=4;
            Define.SetIntToByte(Define.hton_l(0x35000CAA),header,iOffset); iOffset+=4;

            Define.SetShortToByte(0,header,iOffset); iOffset+=2;
            crc32.update(header);
            System.arraycopy(header, 0, g_commIoBuffer1, curAddr, header.length); curAddr+=header.length;
            Define.SetIntToByte(Define.hton_l((int)crc32.getValue()),g_commIoBuffer1,curAddr); curAddr+=4;


            //MyLog.i(" crc16 :       0x" + Long.toHexString(crc16(devid)).toUpperCase());
            //MyLog.i(" chksum_crc16: 0x" + Long.toHexString(chksum_crc16(devid,0,devid.length)).toUpperCase());
            //MyLog.i(" chksum_crc32 (header,18): 0x" + Long.toHexString(chksum_crc32 (header,18)).toUpperCase());
            //MyLog.i(" (int)crc32.getValue(): 0x" + Long.toHexString((int)crc32.getValue()).toUpperCase());
        }
        // 后缀
        g_commIoBuffer1[curAddr++] = 0x00 ;
        g_commIoBuffer1[curAddr++] = 0x00 ;
        // 空值
        curAddr += 6 ;

        // 图像开始(包长度:32BYTES == 前导(2) + 包头(22) + 后缀(2) + 空值(6))
        g_commIoBuffer1[curAddr++] = 0x55 ;
        g_commIoBuffer1[curAddr++] = 0x55 ;
        {   int iOffset=0;
            header[iOffset++]=(byte)0x9A;
            header[iOffset++]=(byte)0x3D;
            Define.SetShortToByte(0,header,iOffset); iOffset+=2;

            Define.SetIntToByte(Define.hton_l(make_device_address(0x10ff,0,0)),header,iOffset); iOffset+=4;
            Define.SetIntToByte(Define.hton_l((0x00<<24)| (px<<16) | (_m_img_sel ? 0 : (1<<15)) ),header,iOffset); iOffset+=4;
            Define.SetIntToByte(Define.hton_l(0x35000CBB),header,iOffset); iOffset+=4;

            Define.SetShortToByte(0,header,iOffset); iOffset+=2;
            crc32.update(header);
            System.arraycopy(header, 0, g_commIoBuffer1, curAddr, header.length); curAddr+=header.length;
            Define.SetIntToByte(Define.hton_l((int)crc32.getValue()),g_commIoBuffer1,curAddr); curAddr+=4;
        }
        // 后缀
        g_commIoBuffer1[curAddr++] = 0x00 ;
        g_commIoBuffer1[curAddr++] = 0x00 ;
        // 空值
        curAddr += 6 ;

        // 图像结束(包长度:32BYTES == 前导(2) + 包头(22) + 后缀(2) + 空值(6))
        g_commIoBuffer1[curAddr++] = 0x55 ;
        g_commIoBuffer1[curAddr++] = 0x55 ;
        {   int iOffset=0;
            header[iOffset++]=(byte)0x9A;
            header[iOffset++]=(byte)0x3D;
            Define.SetShortToByte(0,header,iOffset); iOffset+=2;

            Define.SetIntToByte(Define.hton_l(make_device_address(0x10ff,0,0)),header,iOffset); iOffset+=4;
            Define.SetIntToByte(Define.hton_l((0x00<<24)| (px<<16) | (_m_img_sel ? 0 : (1<<15)) ),header,iOffset); iOffset+=4;
            Define.SetIntToByte(Define.hton_l(0x35000CCC),header,iOffset); iOffset+=4;

            Define.SetShortToByte(0,header,iOffset); iOffset+=2;
            crc32.update(header);
            System.arraycopy(header, 0, g_commIoBuffer1, curAddr, header.length); curAddr+=header.length;
            Define.SetIntToByte(Define.hton_l((int)crc32.getValue()),g_commIoBuffer1,curAddr); curAddr+=4;
        }
        // 后缀
        g_commIoBuffer1[curAddr++] = 0x00 ;
        g_commIoBuffer1[curAddr++] = 0x00 ;
        // 空值
        curAddr += 6 ;

        // 时隙包(包长度:40BYTES == 前导(2) + 包头(22) + 数据(4) + 数据校验(4) + 后缀(2) + 空值(6))
        g_commIoBuffer1[curAddr++] = 0x55 ;
        g_commIoBuffer1[curAddr++] = 0x55 ;
        {   int iOffset=0;
            header[iOffset++]=(byte)0x9A;
            header[iOffset++]=(byte)0x3D;
            Define.SetShortToByte(0x0100,header,iOffset); iOffset+=2;

            Define.SetIntToByte(Define.hton_l(make_device_address(0x10ff,0,0)),header,iOffset); iOffset+=4;
            Define.SetIntToByte(Define.hton_l((0x00<<24)| (px<<16) | (_m_img_sel ? 0 : (1<<15)) ),header,iOffset); iOffset+=4;
            Define.SetIntToByte(Define.hton_l(0x35000C11),header,iOffset); iOffset+=4;

            Define.SetShortToByte(0,header,iOffset); iOffset+=2;
            crc32.update(header);
            System.arraycopy(header, 0, g_commIoBuffer1, curAddr, header.length); curAddr+=header.length;
            Define.SetIntToByte(Define.hton_l((int)crc32.getValue()),g_commIoBuffer1,curAddr); curAddr+=4;
        }
        // 数据
        {   Define.SetIntToByte(Define.hton_l(1536),tempcalcval,0);
            System.arraycopy(tempcalcval, 0, g_commIoBuffer1, curAddr, tempcalcval.length);curAddr+=4;
            crc32.update(tempcalcval);
            Define.SetIntToByte(Define.hton_l((int)crc32.getValue()),g_commIoBuffer1,curAddr); curAddr+=4;
        }
        // 后缀
        g_commIoBuffer1[curAddr++] = 0x00 ;
        g_commIoBuffer1[curAddr++] = 0x00 ;
        // 空值
        curAddr += 6 ;

        // 音频包头(包长度:24BYTES == 前导(2) + 包头(22)
        g_commIoBuffer1[curAddr++] = 0x55 ;
        g_commIoBuffer1[curAddr++] = 0x55 ;
        {   int iOffset=0;
            header[iOffset++]=(byte)0x9A;
            header[iOffset++]=(byte)0x3D;
            Define.SetShortToByte(0x6000,header,iOffset); iOffset+=2;

            Define.SetIntToByte(Define.hton_l(make_device_address(0x10ff,0,0)),header,iOffset); iOffset+=4;
            Define.SetIntToByte(Define.hton_l((0x00<<24)| (px<<16) | (_m_img_sel ? 0 : (1<<15)) ),header,iOffset); iOffset+=4;
            Define.SetIntToByte(Define.hton_l(0x10FF1FFF),header,iOffset); iOffset+=4;

            Define.SetShortToByte(0,header,iOffset); iOffset+=2;
            crc32.update(header);
            System.arraycopy(header, 0, g_commIoBuffer1, curAddr, header.length); curAddr+=header.length;
            Define.SetIntToByte(Define.hton_l((int)crc32.getValue()),g_commIoBuffer1,curAddr); curAddr+=4;
        }

        // 图像窗口个数(包长度:4BYTES
        curAddr = 0x200 ;
        g_commIoBuffer1[curAddr++] = (byte)((pgigdat.negative_y>>4) & 0xff);
        g_commIoBuffer1[curAddr] = (byte) ((pgigdat.negative_y<<4) & 0xf0);
        g_commIoBuffer1[curAddr++] |=  (byte)((pgigdat.negative_x>>8) & 0x0f);
        g_commIoBuffer1[curAddr++] =  (byte)(pgigdat.negative_x & 0xff);
        g_commIoBuffer1[curAddr++] =  1 ;

        Define.SetIntToByte(Define.hton_l(make_device_address(0x10ff,0xff,0xfff)),g_commIoBuffer1,curAddr); curAddr+=4;
        Define.SetIntToByte(Define.hton_l(make_device_address(0x10f0,0x00,0x0)),g_commIoBuffer1,curAddr); curAddr+=4;

        // 第00个图像窗口指令(长度:8)
        curAddr = 0x220 ;
        g_commIoBuffer1[curAddr++] = (byte)((pgigdat.img_y >> 8) & 0xff);
        g_commIoBuffer1[curAddr++] = (byte)((pgigdat.img_y >> 0) & 0xff);
        g_commIoBuffer1[curAddr++] = (byte)((pgigdat.img_x >> 8) & 0xff);
        g_commIoBuffer1[curAddr++] = (byte)((pgigdat.img_x >> 0) & 0xff);
        g_commIoBuffer1[curAddr++] = (byte)((pgigdat.img_h >> 8) & 0xff);
        g_commIoBuffer1[curAddr++] = (byte)((pgigdat.img_h >> 0) & 0xff);
        g_commIoBuffer1[curAddr++] = (byte)((pgigdat.img_w >> 8) & 0xff);
        g_commIoBuffer1[curAddr++] = (byte)((pgigdat.img_w >> 0) & 0xff);

        //GIG图像发送指令存储器数据CRC32校验
        curAddr = g_commIoBuffer1.length-4 ;
        crc32.update(g_commIoBuffer1,0,curAddr);
        Define.SetIntToByte(Define.hton_l((int)crc32.getValue()),g_commIoBuffer1,curAddr); curAddr+=4;
    //MyLog.i(Thread.currentThread().getStackTrace()[2].getMethodName() + " L" + Thread.currentThread().getStackTrace()[2].getLineNumber());

        return FpgaWrite(null,g_commIoBuffer1,MOONCELL_FPGA_MIRROR_ADDRESS_BASIC+g_commIoBuffer1.length * px,g_commIoBuffer1.length) ;
    }


if (false)
                    if (ledCardCommunication!=null)
                    if (ledCardCommunication.clientsManage!=null)
                        if (ledCardCommunication.clientsManage.Clients_GetConnectNumber()>0)
                            GiGDataPrepare();

void ReceiveCardSend()
{
    byte [] g_commIoBuffer1=new byte[MOONCELL_FPGA_MIRROR_ADDRESS_BASIC_STEP];
    // 配置GIG图像发送指令存储器
    byte []  header =new byte[18];
    int curAddr=0;
    CRC32 crc32 = new CRC32();


    {   int iOffset=0;
        header[iOffset++]=(byte)0x9A;
        header[iOffset++]=(byte)0x3D;
        Define.SetShortToByte(0,header,iOffset); iOffset+=2;

        Define.SetIntToByte(hton_l(make_device_address(0x10ff,0,0)),header,iOffset); iOffset+=4;
        Define.SetIntToByte(hton_l((0x00<<24)| (px<<16) | (_m_img_sel ? 0 : (1<<15)) ),header,iOffset); iOffset+=4;
        Define.SetIntToByte(hton_l(0x35000CBB),header,iOffset); iOffset+=4;

        Define.SetShortToByte(0,header,iOffset); iOffset+=2;
        crc32.update(header);
        System.arraycopy(header, 0, g_commIoBuffer1, curAddr, header.length); curAddr+=header.length;
        Define.SetIntToByte(hton_l((int)crc32.getValue()),g_commIoBuffer1,curAddr); curAddr+=4;
    }
    crc32.update(g_commIoBuffer1,0,curAddr);
    Define.SetIntToByte(hton_l((int)crc32.getValue()),g_commIoBuffer1,curAddr); curAddr+=4;

    return FpgaWrite(null,g_commIoBuffer1,0xFF0000,curAddr) ;

}
*/


}
