yuanchaost

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

   DispatcherTimer timer;
        DispatcherTimer fontTimer;
        public int Port = 0;
        TestItemsModel ConfigModel = new TestItemsModel();
        bool isFirstLoad = true;
        string IP = string.Empty;
        SocketServer server = null;
        // 每次发送的数据长度
        const int SEND_DATA_LEN_ONE_TIME = 256;
        //字库在SPI Flash中的起始地址
        const int FONT_BASE_ADDR_IN_SPI_FLASH = 0X00;
        //IC卡数据长度
        const int IC_CARD_DATA_LEN = 128;
        const int IC_CARD_DRIVER_NAME_LEN = 12;
        const int IC_CARD_GENDER_LEN = 2;
        const int IC_CARD_IDENTIYT_NUMBER_LEN = 18;
        const int IC_CARD_DRIVER_LICENSE_LEN = 18;
        const int IC_CARD_DRIVER_LICENSE_LMT_LEN = 3;
        const int IC_CARD_DRIVER_LEGAL_CODE_LEN = 18;
        const int IC_CARD_RESERVED_STD_EXTEND_LEN = 56;
        const int IC_CARD_CHECKSUM_LEN = 4;
        const int ACK_TIME_OUT = 10;
        const int ERASE_FLASH_ACK_TIME_OUT = 60; 

 //IC卡数据的起始地址
        const int IC_CARD_DATA_BASE_ADDR = 0X00;
        const int COM_READ_BUF_LEN = 1024;
        const string CMD_READ_24C01_CARD = "#RIC";
        const string CMD_READ_SL4442_CARD = "#RSL";
        const string CMD_WRITE_24C01_CARD = "#WIC";
        const string CMD_WRITE_SL4442_CARD = "#WSL";
        const string CMD_CLEAR_SPI_FLASH = "#CLR";
        const string CMD_WRITE_SPI_FLASH = "#WW";
        bool bIsFontLibInSending = false; //正在发送字库
        bool bIsComPortOpen = false;//串口是否打开
        bool bIsFlashErase = false; //正在擦除
        bool bIsReadingICCard = false;
        bool bIsWritingICCard = false;
        private static FileStream fs = null;
        private static long index = 0;
        private static long blockCount;
        private static DateTime dt;

  int cardType = 0; //diskType" : int   , 0--4  分别SD1 -- 镜像盘
        int rsType = 0;  //RS485 0  MCU 串口 1
        DateTime startTime;
        DateTime endTime;

        byte[] m_pBuffer = null;            /* 字库缓存地址程序中动态分配  */
        uint m_CurSndPos = 0;  /* 当前写的字库地址    */
        uint m_CurSPI_Flash_Addr = 0; /* 当前写SPI_Flash的位置地址  */
        uint m_LastSndLen = 0; /* 上一次发送的数据长度   */
        uint m_FontLibFileLen = 0; /* 字库缓存的长度    */
        bool isStopTest = false;

private void OpenPort(object model)
        {
            if (!bIsComPortOpen)
            {
                SerialHelper.OpenSerialPort(SelectSerialPort.Name, Convert.ToInt32(SelectBaudRate.Name), Convert.ToInt32(SelectDataBits.Name),
                  Convert.ToInt32(SelectStopBit.Name), Convert.ToInt32(SelectCheckBit.Value));
            }
            else
            {
                if (SerialHelper.serialP.IsOpen)
                {
                    SerialHelper.serialP.Close();
                    OnOpen(false);
                }
            }
        }

private void OnReceiveMsg(string msg)
        {

        }
        private void OnOpen(bool result)
        {
            if (result)
            {
                IndicatorLightColor = Brushes.Green;
                BtnDes = "关闭";
            }
            else
            {
                IndicatorLightColor = Brushes.Red;
                BtnDes = "打开";
            }
            bIsComPortOpen = result;
        }


        long fileLen = 0;
        int sendLen = 0;
        Thread T;
        private void UpgradeFont(object o)
        {
            if (CheckUpdate())
            {
                dt = DateTime.Now;
                if (string.IsNullOrEmpty(FilePath) || !File.Exists(FilePath))
                {
                    ShowTip("文件路径为空");
                    return;
                }
                fs = new FileStream(FilePath, FileMode.Open, FileAccess.Read);
                long m_FontLibFileLen = fs.Length;
                fileLen = m_FontLibFileLen;
                if (m_FontLibFileLen == 0)
                {
                    ShowTip("字库文件大小为:0");
                    return;
                }
                byte[] byteArray = new byte[m_FontLibFileLen];
                fs.Read(byteArray, 0, (int)m_FontLibFileLen);
                int m_CurSndPos = 0;
                int m_CurSPI_Flash_Addr = 0;
                int m_LastSndLen = 0;
               if (m_FontLibFileLen < SEND_DATA_LEN_ONE_TIME)
                {
                    m_CurSndPos = 0; // 发送的位置在m_pBuffer中的偏移
                    m_LastSndLen = (int)m_FontLibFileLen;
                    SendFontDataToCom((uint)m_CurSPI_Flash_Addr, byteArray, (uint)m_LastSndLen);
                    sendLen += m_LastSndLen;
                    bIsFontLibInSending = true;
                }
                else
                {
                    m_CurSndPos = 0;
                    m_LastSndLen = SEND_DATA_LEN_ONE_TIME;
                    SendFontDataToCom((uint)m_CurSPI_Flash_Addr, byteArray, (uint)m_LastSndLen);
                    bIsFontLibInSending = true;
                    sendLen += m_LastSndLen;
                }
                int Range = (int)m_FontLibFileLen / (SEND_DATA_LEN_ONE_TIME); /* 文件长度 */
                if (Range == 0)    // 说明只需一步即可达到100%
                {
                    Range = 1;
                    TxtMsg = "上传完成";

       return;
                }
                else if (Range > 0 && (m_FontLibFileLen % (SEND_DATA_LEN_ONE_TIME)) != 0)
                {
                    Range += 1;
                }
                TxtMsg = string.Empty;
                startTime = DateTime.Now;
                endTime = DateTime.Now;
                byte[] AckCmdBuf = new byte[256];

 T = new Thread(new ThreadStart(() =>
                {
                    for (int i = 1; i < Range; i++)
                    {
                        if (i != (Range - 1))
                        {
                            sendLen += m_LastSndLen;
                            SendFontDataToCom((uint)i * 256, byteArray, (uint)m_LastSndLen);
                            Application.Current.Dispatcher.Invoke(() =>
                            {
                                TxtMsg = $"{sendLen}/{fileLen}";
                                ProMax = (int)fileLen;
                                ProVal = (int)sendLen;
                                ProVisual = Visibility.Visible;
                            });
                        }

 else
                        {
                            int lastLen = (int)(m_FontLibFileLen % 256);
                            if (lastLen == 0)
                                lastLen = 256;
                            sendLen += lastLen;
                            SendFontDataToCom((uint)i * 256, byteArray, (uint)lastLen);
                            endTime = DateTime.Now;
                            TimeSpan timeSpan = endTime - startTime;     // 两个CTime相减得到CTimeSpan
                            double nTSeconds = timeSpan.TotalSeconds;
                            Application.Current.Dispatcher.Invoke(() =>
                            {
                                TxtMsg = $"上传完成耗时:{ Math.Round(nTSeconds, 0)}秒 ({sendLen}/{fileLen})";
                                ProVal = Math.Min((int)sendLen, (int)fileLen);
                                ProVisual = Visibility.Hidden;
                                bIsFontLibInSending = false;

     sendLen = 0;
                            });
                        }
                    }
                }));
                T.Start();
            }
        }

 

 private void ParaseFontUpdateAck(byte[] PAckCmdBuf, int Len)
        {
            byte[] TmpStatues = new byte[128];
            string str = GetStrByArray(PAckCmdBuf);
            if (str.Contains(CMD_WRITE_SPI_FLASH))
            {
                uint AckComWriteSPI_Flash_Addr = 0;
                uint AckComWriteSPI_Flash_Len = 0;
                /* 写入SPI Flash的地址 */
                AckComWriteSPI_Flash_Addr |= (uint)(PAckCmdBuf[3] << 24);
                AckComWriteSPI_Flash_Addr |= (uint)(PAckCmdBuf[4] << 16);
                AckComWriteSPI_Flash_Addr |= (uint)(PAckCmdBuf[5] << 8);
                AckComWriteSPI_Flash_Addr |= (uint)(PAckCmdBuf[6] << 0);

                AckComWriteSPI_Flash_Len |= (uint)(PAckCmdBuf[7] << 24);
                AckComWriteSPI_Flash_Len |= (uint)(PAckCmdBuf[8] << 16);
                AckComWriteSPI_Flash_Len |= (uint)(PAckCmdBuf[9] << 8);
                AckComWriteSPI_Flash_Len |= (uint)(PAckCmdBuf[10] << 0);

   if ((AckComWriteSPI_Flash_Len == m_LastSndLen) && (AckComWriteSPI_Flash_Addr == m_CurSPI_Flash_Addr))
                {
                    m_CurSndPos += m_LastSndLen;    /* 已经发送的长度累增 */
                    m_CurSPI_Flash_Addr += m_LastSndLen;    /* 当前写文件地址累增 */
                    if (m_CurSndPos < m_FontLibFileLen)
                    {
                        /* 发送剩余的 */
                        if (m_FontLibFileLen - m_CurSndPos <= SEND_DATA_LEN_ONE_TIME)
                        {
                            m_LastSndLen = m_FontLibFileLen - m_CurSndPos;
                            SendFontDataToCom(m_CurSPI_Flash_Addr, PAckCmdBuf, m_LastSndLen);
                            bIsFontLibInSending = true;
                        }
                        else
                        {
                            m_LastSndLen = SEND_DATA_LEN_ONE_TIME;
                            SendFontDataToCom(m_CurSPI_Flash_Addr, m_pBuffer, m_LastSndLen);
                             bIsFontLibInSending = true;
                        }
                        TxtMsg = $"写入进度:{m_CurSndPos}/{m_FontLibFileLen}";
                        ProVisual = Visibility.Visible;
                        ProMax = (int)m_FontLibFileLen;
                        ProVal = (int)m_CurSndPos;
                    }
                    else if (m_CurSndPos == m_FontLibFileLen)    /* 写完成 */
                    {
                        ProVal = (int)m_CurSndPos;
                        ProVisual = Visibility.Collapsed;
                        fontTimer.Stop();
                        bIsFontLibInSending = false;

 m_CurSndPos = 0;
                        m_LastSndLen = 0;
                        m_CurSPI_Flash_Addr = 0;
                        endTime = System.DateTime.Now;
                        TimeSpan timeSpan = endTime - startTime;     // 两个CTime相减得到CTimeSpan
                        double nTSeconds = timeSpan.TotalSeconds;                // 得到总的秒数
                        TxtMsg = $"字库升级成功,共耗时:{nTSeconds}秒";
                        if (m_pBuffer != null)
                        {
                            m_pBuffer = null;
                        }
                    }
                    //CProgressCtrl *pProgressCtrl = (CProgressCtrl *)GetDlgItem(IDC_PROGRESS_UPDATE);
                }

   else    /* 写Flash 出错 !*/
                {
                    //sprintf(TmpStatues, "MCU写地址出错:AckAddr:%x, AckLen:%d, Addr:%x, Len:%d Pos:%d",\
                    //                AckComWriteSPI_Flash_Addr, AckComWriteSPI_Flash_Len, \
                    //                m_CurSPI_Flash_Addr, m_LastSndLen, m_CurSndPos);
                    //SetStauesText(TmpStatues);
                    //SendFontDataToCom(m_CurSPI_Flash_Addr, m_pBuffer + m_CurSndPos, m_LastSndLen);
                    //bIsFontLibInSending = true;
                }
            }
        }

 private void CleaningMemory(object o)
        {
            if (CheckPortOpen())
            {
                if (true == bIsFlashErase)
                {
                    ShowTip("正在清除");
                    return;
                }
                SendEraseFlashToCom(FONT_BASE_ADDR_IN_SPI_FLASH, 0);
            }
        }

 void SendFontDataToCom(uint WriteAddr, byte[] pSndBuf, uint SndBufLen)
        {
            /* 发送:#WW + 地址(4字节) + 长度(4字节) ... 数据(长度不超过256) ... 校验和(#W,参与校验,共1字节) + OO# */
            byte[] pTmpBuf = null;
            uint CalcBufLen = 0;
            byte[] pCalcAddr = new byte[512];// [512] = { 0 };
            pTmpBuf = pCalcAddr;    /* 计算校验和的起始地址 */

            /* 命令头 */
            pTmpBuf[CalcBufLen++] = (byte)'#';
            pTmpBuf[CalcBufLen++] = (byte)'W';
            pTmpBuf[CalcBufLen++] = (byte)'W';

            /* 写入SPI Flash的地址 */
            pTmpBuf[CalcBufLen++] = (byte)((WriteAddr >> 0) & 0xff);
            pTmpBuf[CalcBufLen++] = (byte)((WriteAddr >> 8) & 0xff);
            pTmpBuf[CalcBufLen++] = (byte)((WriteAddr >> 16) & 0xff);
            pTmpBuf[CalcBufLen++] = (byte)((WriteAddr >> 24) & 0xff);

          

  /* 写入数据的长度 */
            pTmpBuf[CalcBufLen++] = (byte)((SndBufLen >> 0) & 0xff);
            pTmpBuf[CalcBufLen++] = (byte)((SndBufLen >> 8) & 0xff);
            pTmpBuf[CalcBufLen++] = (byte)((SndBufLen >> 16) & 0xff);
            pTmpBuf[CalcBufLen++] = (byte)((SndBufLen >> 24) & 0xff);

            //真正发送的数据
            Array.Copy(pSndBuf, 0, pTmpBuf, CalcBufLen, SndBufLen);
            CalcBufLen += SndBufLen;
            byte XorSum = XorCheckSum(pCalcAddr, CalcBufLen);
            pTmpBuf[CalcBufLen++] = XorSum;
            pTmpBuf[CalcBufLen++] = (byte)'O';
            pTmpBuf[CalcBufLen++] = (byte)'O';
            pTmpBuf[CalcBufLen++] = (byte)'#';
            try
            {
                SerialHelper.serialP.Write(pTmpBuf, 0, (int)CalcBufLen);
            }

 catch (Exception ex)
            {
                LogService.Instance.Debug("SendFontDataToCom:" + ex.Message);
                TxtMsg = "写字库数据失败!";
            }
        }
        void FontPath(object o)
        {
            Microsoft.Win32.OpenFileDialog ofd = new Microsoft.Win32.OpenFileDialog();
            ofd.DefaultExt = ".*";
            ofd.Filter = "字库文件|*.DZK";
            if (ofd.ShowDialog() == true)
            {
                FilePath = ofd.FileName;
            }
        }
                       //清除
        void SendEraseFlashToCom(UInt32 ClearAddr, UInt32 ClearLen)
        {
            string msg = "正在擦除Flash...";
            if (bIsFlashErase)
            {
                ShowTip(msg);
                return;
            }
            TxtMsg = msg;
            bIsFlashErase = true;
            /* 发送:#WW + 地址(4字节) + 长度(4字节) ... 数据(长度不超过256) ... 校验和(#W,参与校验,共1字节) + OO# */
            byte[] pTmpBuf = null;
            byte[] pCalcAddr = null;
            uint CalcBufLen = 0;
            pTmpBuf = new byte[512];
            pCalcAddr = pTmpBuf;    /* 计算校验和的起始地址 */
            /* 命令头 */
            pTmpBuf[CalcBufLen++] = (byte)'#';
            pTmpBuf[CalcBufLen++] = (byte)'C';
            pTmpBuf[CalcBufLen++] = (byte)'L';
            pTmpBuf[CalcBufLen++] = (byte)'R';
            /* 写入SPI Flash的地址 */
            pTmpBuf[CalcBufLen++] = (byte)((ClearAddr >> 0) & 0xff);
            pTmpBuf[CalcBufLen++] = (byte)((ClearAddr >> 8) & 0xff);

  pTmpBuf[CalcBufLen++] = (byte)((ClearAddr >> 16) & 0xff);
            pTmpBuf[CalcBufLen++] = (byte)((ClearAddr >> 24) & 0xff);
            /* 写入数据的长度 */
            pTmpBuf[CalcBufLen++] = (byte)((ClearLen >> 0) & 0xff);
            pTmpBuf[CalcBufLen++] = (byte)((ClearLen >> 8) & 0xff);
            pTmpBuf[CalcBufLen++] = (byte)((ClearLen >> 16) & 0xff);
            pTmpBuf[CalcBufLen++] = (byte)((ClearLen >> 24) & 0xff);
            byte XorSum = XorCheckSum(pCalcAddr, CalcBufLen);
            pTmpBuf[CalcBufLen++] = XorSum;
            pTmpBuf[CalcBufLen++] = (byte)'O';
            pTmpBuf[CalcBufLen++] = (byte)'O';
            pTmpBuf[CalcBufLen++] = (byte)'#';
           SerialHelper.serialP.Write(pTmpBuf, 0, (int)CalcBufLen);
            Console.WriteLine("SerialHelper.serialP.Write:" + CalcBufLen);
            startTime = DateTime.Now;
            endTime = DateTime.Now;
            SerialHelper.serialP.Write(pTmpBuf, 0, (int)CalcBufLen);
            int AckCmdLen = 1;
            byte[] AckCmdBuf = new byte[256];// [256] = { 0 };

  Task.Factory.StartNew(() =>
            {
                while (bIsFlashErase)   /* 擦除Flash */
                {
                    Thread.Sleep(10);
                    AckCmdLen = GetAckCmdBuf(ref AckCmdBuf, 256);
                    if (AckCmdLen != 0)
                    {
                        ParaseEraseFlashAck(AckCmdBuf, AckCmdLen);
                        startTime = DateTime.Now;
                    }

 else
                    {
                        endTime = DateTime.Now;
                        TimeSpan timeSpan = endTime - startTime;     // 两个CTime相减得到CTimeSpan
                        double nTSeconds = timeSpan.TotalSeconds;                // 得到总的秒数
                        if (nTSeconds > ERASE_FLASH_ACK_TIME_OUT)
                        {
                            bIsFlashErase = false;
                            Application.Current.Dispatcher.Invoke(() =>
                            {
                                TxtMsg = "擦除Flash超时失败!";
                            });
                        }
                    }
                }
            });
        }

 void ParaseEraseFlashAck(byte[] PAckCmdBuf, int Len)
        {
            string str = GetStrByArray(PAckCmdBuf);
            if (str.Contains(CMD_CLEAR_SPI_FLASH))
            {
                Application.Current.Dispatcher.Invoke(() =>
                {
                    bIsFlashErase = false;
                    TxtMsg = "擦除Flash成功";
                });
            }
        }

  byte XorCheckSum(byte[] pBuff, uint Len)
        {
            byte CheckSum = 0;
            if (null == pBuff)
            {
                return CheckSum;
            }
            for (uint i = 0; i < Len; i++)
            {
                CheckSum ^= pBuff[i]; //*(pBuff + i);
            }
            return CheckSum;
        }

 

 int GetAckCmdBuf(ref byte[] PAckCmdBuf, int Len)
        {
            int len, Idx;
            int AckCmdLen = 0;    // 单片机返回的应答个数
            byte[] RxDataBuf = new byte[COM_READ_BUF_LEN];// [COM_READ_BUF_LEN] = { 0 };    // 串口读取的缓存
            int TotalRcvLen = 0;
            System.Threading.Thread.Sleep(10);
            byte[] ReDatas = new byte[SerialHelper.serialP.BytesToRead];
            //从串口读取数据
            len = SerialHelper.serialP.Read(ReDatas, 0, ReDatas.Length);
            Array.Copy(ReDatas, 0, PAckCmdBuf, 0, Math.Min(ReDatas.Length, PAckCmdBuf.Length));
            if (len > 0)
            {
                TotalRcvLen += len; // 长度累加
                Console.WriteLine("TotalRcvLen:" + TotalRcvLen);
            }

 for (Idx = 0; Idx < TotalRcvLen; Idx++)
            {
                if (((byte)'O' == ReDatas[Idx]) && ((byte)'O' == ReDatas[Idx + 1]) && ((byte)'#' == ReDatas[Idx + 2]))
                {
                    AckCmdLen = (int)Idx + 3;
                    TotalRcvLen -= (int)AckCmdLen;    /* 数据向前移动 */
                    byte[] pTmpBuf = new byte[ReDatas.Length + AckCmdLen];
                    if (Len >= AckCmdLen)
                    {
                        Array.Copy(ReDatas, 0, PAckCmdBuf, 0, AckCmdLen);
                    }
                    else
                    {
                        Console.WriteLine("超出缓存限制");
                        AckCmdLen = 0;
                    }
                    for (int TmpIdx = 0; TmpIdx < TotalRcvLen; TmpIdx++)
                    {
                        RxDataBuf[TmpIdx] = pTmpBuf[TmpIdx];
                    }
                    break;
                }
            }
            return AckCmdLen;
       }


                

posted on 2020-07-31 16:20  yuanchaost  阅读(171)  评论(0编辑  收藏  举报