/***************************** Communication Protocol ***************************************************
         *
         *              |-------------------- Packet Length of File (for erase flash )----------------------|
         *	Position:   |   0	|     1     |     2		|     3		|     4     |     5     |     6		    |
         *              |-----------------------------------------------------------------------------------|
         *  Value:		| '*'	| NData[2]  | NData[1]	| NData[0]	| !NData[2] | !NData[1]	| !NData[0]	    |
         *              |-----------------------------------------------------------------------------------|
         *	Position:   |   7		|     8     |     9     |    10		|    11     |    12     |    13	    |
         *              |-----------------------------------------------------------------------------------|
         *  Value:		| CRC32[3]	| CRC32[2]  | CRC32[1]	| CRC32[0]	| !CRC32[3] | !CRC32[2]	| !CRC32[1]	|
         *              |-----------------------------------------------------------------------------------|
         *	Position:   |   14		|
         *              |-----------|
         *  Value:		| !CRC32[0]	|
         *              |-----------|
         *
         *
         *              |------------------ Packet Data (max data length = 2048 bytes) ---------------------|
         *	Position:   |   0	|     1     |     2		|     3		|     4     |     5     |      ...	    |
         *              |-----------------------------------------------------------------------------------|
         *  Value:		| '!'	| NData[1]  | NData[0]	| !NData[1]	| !NData[0] |  Data[0]	|      ...      |
         *              |-----------------------------------------------------------------------------------|
         *	Position:   |   n+5		|   n+6     |   n+7     |   n+8		|   n+9     |   n+10    |   n+11    |
         *              |-----------------------------------------------------------------------------------|
         *  Value:		| Data[n]	| CRC32[3]  | CRC32[2]	| CRC32[1]	|  CRC32[0] | !CRC32[3]	| !CRC32[2]	|
         *              |-----------------------------------------------------------------------------------|
         *	Position:   |  n+12		|	n+13	|
         *              |-----------------------|
         *  Value:		| !CRC32[1]	| !CRC32[0]	|
         *              |-----------|-----------|
         */

        private void btnFire_Click(object sender, EventArgs e)
        {
            if (serialPortManager.isConnected)
            {
                time            = DateTime.Now;
                txtstatus.Text += String.Format("\r\n{0}:- Start program, waiting ACK from Boot Loader", time.ToLongTimeString());

                btnFire.Enabled    = false;
                btnbrown.Enabled   = false;
                countSendData      = 0;
                progressBar1.Value = 0;

                SendPacketLengthThread = new Thread(SendPacketLength);
                SendDataThread         = new Thread(SendData);

                /* Start Send Ping */
                bootLoaderStatus      = BootLoaderStatus.SendPing;
                timerSendPing.Enabled = true;
            }
        }
        public void SerialPortDataEventHandler_CallBack(object sender, byte[] data)
        {
            /* Receive ACK-PING from MCU */
            if ((data[0] == ACK_VALUE) && (bootLoaderStatus == BootLoaderStatus.SendPing))
            {
                timerSendPing.Enabled = false;
                bootLoaderStatus      = BootLoaderStatus.SendLength;

                time = DateTime.Now;
                txtstatus.Invoke(new MethodInvoker(delegate()
                {
                    txtstatus.Text += String.Format("\r\n{0}:- Receive ACK-PING From MCU", time.ToLongTimeString());
                }));

                Thread.Sleep(400);//Critical code

                SendPacketLengthThread.Start();
            }
            /* Receive ACK-DATA-LENGTH from MCU */
            else if ((data[0] == ACK_VALUE) && (bootLoaderStatus == BootLoaderStatus.SendLength))
            {
                bootLoaderStatus = BootLoaderStatus.SendData;

                txtstatus.Invoke(new MethodInvoker(delegate()
                {
                    time            = DateTime.Now;
                    txtstatus.Text += String.Format("\r\n{0}:- Receive ACK-DATA-LENGTH From MCU", time.ToLongTimeString());
                }));

                SendDataThread.Start();
            }
            /* Receive NACK-DATA-LENGTH from MCU */
            else if ((data[0] == NACK_VALUE) && (bootLoaderStatus == BootLoaderStatus.SendLength))
            {
                txtstatus.Invoke(new MethodInvoker(delegate()
                {
                    time            = DateTime.Now;
                    txtstatus.Text += String.Format("\r\n{0}:- Receive NOT-ACK-DATA-LENGTH From MCU", time.ToLongTimeString());
                }));

                if (!SendPacketLengthThread.IsAlive)
                {
                    SendPacketLengthThread = new Thread(SendPacketLength);
                    SendPacketLengthThread.Start();
                }
            }
            /* Receive ACK-DATA from MCU */
            else if ((data[0] == ACK_VALUE) && (bootLoaderStatus == BootLoaderStatus.SendData))
            {
                time = DateTime.Now;
                progressBar1.Invoke(new MethodInvoker(delegate()
                {
                    progressBar1.Value = Convert.ToInt32(((float)countSendData / (float)lengthOfFile) * 100);
                }));

                if (countSendData == lengthOfFile)
                {
                    bootLoaderStatus = BootLoaderStatus.Ending;

                    txtstatus.Invoke(new MethodInvoker(delegate()
                    {
                        txtstatus.Text += String.Format("\r\n{0}:- Program Success", time.ToLongTimeString());
                    }));

                    btnFire.Invoke(new MethodInvoker(delegate()
                    {
                        btnFire.Enabled = true;
                    }));

                    btnbrown.Invoke(new MethodInvoker(delegate()
                    {
                        btnbrown.Enabled = true;
                    }));
                }
                else
                {
                    txtstatus.Invoke(new MethodInvoker(delegate()
                    {
                        txtstatus.Text += String.Format("\r\n{0}:- Receive ACK-DATA From MCU", time.ToLongTimeString());
                    }));

                    if (!SendDataThread.IsAlive)
                    {
                        SendDataThread = new Thread(SendData);
                        SendDataThread.Start();
                    }
                }
            }
        }