yuanchaost

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

#ifndef __GLOBAL_DEFINE_H__
#define __GLOBAL_DEFINE_H__

#define EDIT_INPUT_NOTICE  L"选择字库文件..."

 

#define ACK_TIME_OUT    (10)
#define ERASE_FLASH_ACK_TIME_OUT    (60)

// 每次发送的数据长度
#define SEND_DATA_LEN_ONE_TIME                  (256)

//字库在SPI Flash中的起始地址
#define FONT_BASE_ADDR_IN_SPI_FLASH                 (0X00)

//IC卡数据的起始地址
#define IC_CARD_DATA_BASE_ADDR                      (0X00)

//IC卡数据长度
#define IC_CARD_DATA_LEN                            (128)

#define IC_CARD_DRIVER_NAME_LEN                     (12)
#define IC_CARD_GENDER_LEN                          (2)
#define IC_CARD_IDENTIYT_NUMBER_LEN                 (18)
#define IC_CARD_DRIVER_LICENSE_LEN                  (18)
#define IC_CARD_DRIVER_LICENSE_LMT_LEN              (3)
#define IC_CARD_DRIVER_LEGAL_CODE_LEN               (18)
#define IC_CARD_RESERVED_STD_EXTEND_LEN             (56)
#define IC_CARD_CHECKSUM_LEN                        (4)

#define RESEND_TIMER                                (1)


#define CMD_READ_24C01_CARD       "#RIC"
#define CMD_READ_SL4442_CARD      "#RSL"
#define CMD_WRITE_24C01_CARD      "#WIC"
#define CMD_WRITE_SL4442_CARD     "#WSL"
#define CMD_CLEAR_SPI_FLASH       "#CLR"
#define CMD_WRITE_SPI_FLASH       "#WW"

 

extern CSerialPort *pCtrlComm;

extern bool bIsComPortOpen;       /* 串口状态指示    */
extern bool bIsFontLibInSending;     /* 字库发送状态    */
extern bool bIsFlashErase;       /* Flash 擦除状态    */
extern bool bIsWritingICCard;            /* IC卡写卡状态    */
extern bool bIsReadingICCard;            /* IC卡读卡状态    */
extern unsigned char *m_pBuffer;     /* 字库缓存地址程序中动态分配  */
extern unsigned long int m_CurSndPos;    /* 当前写的字库地址    */
extern unsigned long int m_CurSPI_Flash_Addr;  /* 当前写SPI_Flash的位置地址  */
extern unsigned long int m_LastSndLen;    /* 上一次发送的数据长度   */
extern unsigned long int m_FontLibFileLen;      /* 字库缓存的长度    */

extern DWORD m_TimeOut;
extern CTime m_StartUpdFontTime;
extern CTime m_EndUpdFontTime;

extern void SetStauesText(const char *pText);
extern unsigned char Hex2BCD(unsigned char  Val);
extern unsigned char  BCD2Hex(unsigned char Val);
extern unsigned char XorCheckSum(const unsigned char *pBuff, unsigned int Len);
extern unsigned char AndCheckSum(const unsigned char *pBuff, unsigned int Len);
extern void SendFontDataToCom(const unsigned long int WriteAddr, const unsigned char *pSndBuf, unsigned int SndBufLen);
extern void Send24C01DataToCom(const unsigned long int WriteAddr, const unsigned char *pSndBuf, unsigned int SndBufLen);
extern void SendSL4442DataToCom(const unsigned long int WriteAddr, const unsigned char *pSndBuf, unsigned int SndBufLen);

extern void SendWriteDataToCom(char *pCmd, const unsigned long int WriteAddr, const unsigned char *pSndBuf, unsigned int SndBufLen);
extern void SendReadICCardCMDToCom(char *pCmd, const unsigned long int ReadStartAddr, unsign

// CFontUpdate 消息处理程序

int PortNumber    = 1;

bool bIsComPortOpen = false;    /* 串口状态指示    */
bool bIsFontLibInSending = false;   /* 字库发送状态    */
bool bIsFlashErase = false;     /* Flash 擦除状态    */
bool bIsWritingICCard = false;    /* IC卡写卡状态    */
bool bIsReadingICCard = false;    /* IC卡读卡状态    */
unsigned char *m_pBuffer = NULL;   /* 字库缓存地址程序中动态分配  */
unsigned long int m_CurSndPos          = 0; /* 当前写的字库地址    */
unsigned long int m_CurSPI_Flash_Addr  = 0; /* 当前写SPI_Flash的位置地址  */
unsigned long int m_LastSndLen         = 0; /* 上一次发送的数据长度   */
unsigned long int m_FontLibFileLen     = 0; /* 字库缓存的长度    */
DWORD m_TimeOut = 0;

CTime m_StartUpdFontTime;
CTime m_EndUpdFontTime;
CProgressCtrl *pProgressCtrl = NULL;

BEGIN_EVENTSINK_MAP(CFontUpdate, CDialog)
// ON_EVENT(CFontUpdate, IDC_MSCOMM1, 1, CFontUpdate::OnCommMscomm1, VTS_NONE)
END_EVENTSINK_MAP()


void CFontUpdate::FontUpdateInitial(void)
{
  // TODO: Add extra initialization here 
 //参数添加 
 m_Port.AddString(L"COM1"); 
 m_Port.AddString(L"COM2"); 
 m_Port.AddString(L"COM3"); 
 m_Port.AddString(L"COM4");
 m_Port.AddString(L"COM5");
 m_Port.AddString(L"COM6");
 m_Port.AddString(L"COM7");
 m_Port.AddString(L"COM8"); 
 m_Port.AddString(L"COM9"); 
 m_Port.AddString(L"COM10"); 

 

m_Bote.AddString(L"300");
 m_Bote.AddString(L"600");
 m_Bote.AddString(L"1200");
 m_Bote.AddString(L"2400");
 m_Bote.AddString(L"4800");
 m_Bote.AddString(L"9600");
 m_Bote.AddString(L"19200");
 m_Bote.AddString(L"38400");
 m_Bote.AddString(L"43000");
 m_Bote.AddString(L"56000");
 m_Bote.AddString(L"57600");
 m_Bote.AddString(L"115200");

 m_Adjust.AddString(L"无校验");
 m_Adjust.AddString(L"奇校验");
 m_Adjust.AddString(L"偶校验");

 

m_Data.AddString(L"4");
 m_Data.AddString(L"5");
 m_Data.AddString(L"6");
 m_Data.AddString(L"7");
 m_Data.AddString(L"8");

 m_Stop.AddString(L"1");
 m_Stop.AddString(L"2");

 m_Port.SetCurSel(0);
 m_Bote.SetCurSel(11);
 m_Adjust.SetCurSel(0);
 m_Data.SetCurSel(4);
 m_Stop.SetCurSel(0);
 //m_bAutoSend=FALSE;// 初始化自动发送不允许
 bIsComPortOpen = false;
 //UpdateData(FALSE);
 m_CurSndPos    = 0;  /* 当前写的字库地址    */
 m_CurSPI_Flash_Addr  = 0;  /* 当前写SPI_Flash的位置地址 从 0 开始写字库*/
 m_pBuffer    = NULL;
 m_FontLibFileLen  = 0;
 m_TimeOut            = 0;

}

 

int CFontUpdate::CheckFilePath()
{
 GetDlgItemText(IDC_EDIT_PATH_INPUT, m_strInputFilePathName);

    if(   !m_strInputFilePathName.Compare(EDIT_INPUT_NOTICE)
       || m_strInputFilePathName.IsEmpty())
    {
        return -1;
    }

    return 0;
}

void CFontUpdate::SendEraseFlashToCom( DWORD ClearAddr, DWORD ClearLen)
{
 if( true == bIsFlashErase  )
 {
        SetStauesText("正在擦除Flash...");
        return;
    }

    SetStauesText("正在擦除Flash...");
    bIsFlashErase = true;

 /* 发送:#WW + 地址(4字节) + 长度(4字节) ... 数据(长度不超过256) ... 校验和(#W,参与校验,共1字节) + OO# */
 unsigned char *pTmpBuf   = NULL;
 unsigned char *pCalcAddr = NULL;
 unsigned int CalcBufLen  = 0;

 pTmpBuf = new unsigned char[512];
 if(NULL == pTmpBuf)
 {
  SetStauesText("发送数据到串口时, 分配内存失败!");
  return;
 }

 pCalcAddr = pTmpBuf; /* 计算校验和的起始地址 */

/* 命令头 */
 *(pTmpBuf + CalcBufLen++) = '#';
 *(pTmpBuf + CalcBufLen++) = 'C';
 *(pTmpBuf + CalcBufLen++) = 'L';
 *(pTmpBuf + CalcBufLen++) = 'R';

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

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

    BYTE XorSum = XorCheckSum(pCalcAddr, CalcBufLen);
 *(pTmpBuf + CalcBufLen++) = XorSum;
 *(pTmpBuf + CalcBufLen++) = 'O';
 *(pTmpBuf + CalcBufLen++) = 'O';
 *(pTmpBuf + CalcBufLen++) = '#';

DWORD Written = pCtrlComm->Write(pTmpBuf , CalcBufLen);
 if(Written <= 0)
 {
  SetStauesText("发送擦除Flash指令失败!");
  return;
 }

 if(pTmpBuf != NULL)
 {
  delete pTmpBuf;
  pTmpBuf = NULL;
 }
}

HBRUSH CFontUpdate::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
 HBRUSH   hbr   =   CDialog::OnCtlColor(pDC, pWnd, nCtlColor);  

  if((pWnd->GetDlgCtrlID() == IDC_Light))
  {  
   if(bIsComPortOpen == false)
   {
//   ::DeleteObject(hbr);  
   hbr   =   ::CreateSolidBrush(RGB(255,0,0));//控件底色  
   pDC->SetBkMode(TRANSPARENT);
   pDC->SetTextColor(RGB(255,0,0));
   }
   else
   {
//   ::DeleteObject(hbr);  
   hbr   =   ::CreateSolidBrush(RGB(0, 255, 0));//控件底色
   pDC->SetBkMode(TRANSPARENT);  
   pDC->SetTextColor(RGB(0, 255, 0));  
   }
  }
 
  return   hbr;  
}

void CFontUpdate::OnBnClickedButtonOpenComPort()
{
 // TODO: 在此添加控件通知处理程序代码
    if(bIsComPortOpen)  /* 关闭 */
    {
  pCtrlComm->Close();  /* 关闭串口 */
  bIsComPortOpen = false;
  SetDlgItemText(IDC_BUTTON_OPEN_COM_PORT, L"打开");
  Invalidate();
    }
    else    /* 打开 */
    {
        int nPortNumber;
        int nBuardRate = 115200;
        Parity eParity = NoParity;
        unsigned char DataBits = 8;
        StopBits eStopBits = OneStopBit;

        //参数设定部分
     //设定端口
     nPortNumber = m_Port.GetCurSel() + 1;

        //设定波特率
     if(m_Bote.GetCurSel()==0)
      nBuardRate = 300;
     else if(m_Bote.GetCurSel()==1)
      nBuardRate = 600;
        else if(m_Bote.GetCurSel()==2)
      nBuardRate = 1200;
     else if(m_Bote.GetCurSel()==3)
      nBuardRate = 2400;
        else if(m_Bote.GetCurSel()==4)
         nBuardRate = 4800;
        else if(m_Bote.GetCurSel()==5)
      nBuardRate = 9600;
     else if(m_Bote.GetCurSel()==6)
     

nBuardRate = 19200;
        else if(m_Bote.GetCurSel()==7)
      nBuardRate = 38400;
        else if(m_Bote.GetCurSel()==8)
      nBuardRate = 43000;
     else if(m_Bote.GetCurSel()==9)
         nBuardRate = 56000;
        else if(m_Bote.GetCurSel()==10)
      nBuardRate = 57600;
     else nBuardRate = 115200;

        //设定奇偶校验
     if(m_Adjust.GetCurSel()==0)
      eParity = NoParity;
     else if(m_Adjust.GetCurSel()==1)
            eParity = OddParity;
        else
            eParity = EvenParity;

 

 try
        {
            pCtrlComm->Open(nPortNumber, nBuardRate, eParity, DataBits, eStopBits);
        }
        catch(CSerialException e)
        {
            bIsComPortOpen = false;
            SetDlgItemText(IDC_BUTTON_OPEN_COM_PORT, L"打开");
            Invalidate();
            AfxMessageBox(e.GetErrorMessage());
            return;
        }

  bIsComPortOpen = true;    //指示灯亮
  SetDlgItemText(IDC_BUTTON_OPEN_COM_PORT, L"关闭");
        Invalidate();
    }
}

void CFontUpdate::OnCbnSelchangeComboPort()
{
 // TODO: 在此添加控件通知处理程序代码
    int nPortNumber= 8;
    int nBuardRate = 115200;
    Parity eParity = NoParity;
    unsigned char DataBits = 8;
    StopBits eStopBits = OneStopBit;

    if( !bIsComPortOpen )   /* 未打开,直接返回 */
  {
        return;
    }

//参数设定部分
    //设定端口
    nPortNumber = m_Port.GetCurSel() + 1;

    //设定波特率
    if(m_Bote.GetCurSel()==0)
        nBuardRate = 300;
    else if(m_Bote.GetCurSel()==1)
        nBuardRate = 600;
    else if(m_Bote.GetCurSel()==2)
        nBuardRate = 1200;
    else if(m_Bote.GetCurSel()==3)
        nBuardRate = 2400;
    else if(m_Bote.GetCurSel()==4)
        nBuardRate = 4800;
    else if(m_Bote.GetCurSel()==5)
        nBuardRate = 9600;
    else if(m_Bote.GetCurSel()==6)
        nBuardRate = 19200;
    else if(m_Bote.GetCurSel()==7)
        nBuardRate = 38400;
    else if(m_Bote.GetCurSel()==8)
        nBuardRate = 43000;
    else if(m_Bote.GetCurSel()==9)
        nBuardRate = 56000;
    else if(m_Bote.GetCurSel()==10)
        nBuardRate = 57600;
    else nBuardRate = 115200;

 //设定奇偶校验
    if(m_Adjust.GetCurSel()==0)
        eParity = NoParity;
    else if(m_Adjust.GetCurSel()==1)
        eParity = OddParity;
    else
        eParity = EvenParity;

    //设定数据位
    if(m_Data.GetCurSel()==0)
        DataBits = 4;
    else if(m_Data.GetCurSel()==1)
        DataBits = 5;
    else if(m_Data.GetCurSel()==2)
        DataBits = 6;
    else if(m_Data.GetCurSel()==3)
        DataBits = 7;
    else if(m_Data.GetCurSel()==4)
        DataBits = 8;

    //设定停止位
    if(m_Stop.GetCurSel()==0)
        eStopBits = OneStopBit;
    else if(m_Stop.GetCurSel()==1)
        eStopBits = TwoStopBits;

// UpdateData(TRUE); //读取编辑框内容
// UpdateData(FALSE);//显示编辑框中的内容,并将延时时间传给计时器

 if( bIsComPortOpen )
  {
        /* 关闭串口 */
        pCtrlComm->Close();
        bIsComPortOpen = false;
        SetDlgItemText(IDC_BUTTON_OPEN_COM_PORT, L"打开");
        Invalidate();
 }

    /* 打开选择的串口 */
    try
    {
        pCtrlComm->Open(nPortNumber, nBuardRate, eParity, DataBits, eStopBits);
    }
    catch(CSerialException e)
    {
        bIsComPortOpen = false;
        SetDlgItemText(IDC_BUTTON_OPEN_COM_PORT, L"打开");
        Invalidate();
        AfxMessageBox(e.GetErrorMessage());
        return;
    }

if(pCtrlComm->IsOpen())
 {
  bIsComPortOpen = true;    //指示灯亮
  SetDlgItemText(IDC_BUTTON_OPEN_COM_PORT, L"关闭");
        Invalidate();
 }
 else
 {
  bIsComPortOpen = false;    //指示关
  SetDlgItemText(IDC_BUTTON_OPEN_COM_PORT, L"打开");
        Invalidate();
 }
}

bool CFontUpdate::DoEvents()
{
 MSG  msg;
 while (::PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
 {
  if (msg.message == WM_QUIT)//关闭窗口
  {
   return false;
        }
  ::TranslateMessage(&msg);
  ::DispatchMessage(&msg);
 }

 return true;
}

void CFontUpdate::OnBnClickedButtonBrowseFontLib()
{
 // TODO: 在此添加控件通知处理程序代码
#if 1
 CFileDialog Filedlg( TRUE,    // TRUE则显示打开对话框,为FALSE则显示保存对话文件对话框。
      _T("DZK"),   // 指定默认的文件扩展名。
      _T("*.DZK"),  // 指定默认的文件名。
      OFN_NOCHANGEDIR, // 指明一些特定风格。一定注意这里选择这个,可能会造成数据库连接失败
      _T("FilePath(*.DZK)|*.DZK|"));
#endif

    CString FilePathName;
    if(Filedlg.DoModal() == IDOK)
 {
  FilePathName=Filedlg.GetPathName(); 
  SetDlgItemText(IDC_EDIT_PATH_INPUT, FilePathName);
 }

 m_CurSndPos = 0;
 m_LastSndLen = 0;
 bIsFontLibInSending = false;
}

void CFontUpdate::OnBnClickedButtonUpdateFontLib()
{
 // TODO: 在此添加控件通知处理程序代码

 if(( bIsComPortOpen == false))
  {
  SetStauesText("串口尚未打开!");
  return;
 }

 if(true == bIsFlashErase)
 {
  SetStauesText("还在擦除Flash...");
  return;
 }

 if(true == bIsFontLibInSending)
 {
  SetStauesText("已经在字库升级中...");
  return;
 }

if(0 != CheckFilePath())
 {
  SetStauesText("字库文件路径无效!");
  return;
 }

 CFile  FontLibFile;
 if ( !FontLibFile.Open( m_strInputFilePathName, CFile::modeRead) )
 {
  SetStauesText("打开字库文件失败!");
  return;
 }

 m_FontLibFileLen = (unsigned long)(FontLibFile.GetLength());
 if(m_FontLibFileLen == 0)
 {
  SetStauesText("字库文件大小为:0!");
  return;
 }

 /* 假如上次未释放该指针  */
    if(NULL != m_pBuffer)
    {
        delete m_pBuffer;
        m_pBuffer = NULL;
    }
 m_pBuffer = new unsigned char[m_FontLibFileLen];
 if(m_pBuffer == NULL)
 {
  SetStauesText("分配内存失败!");
  return; 
 }

/* 读取 Bin File */
 FontLibFile.Read(m_pBuffer, m_FontLibFileLen); //
 FontLibFile.Close();

    /* 关闭按钮无效 */
    CButton *pBtn = (CButton *)GetDlgItem(IDC_BUTTON_OPEN_COM_PORT);
    if(pBtn != NULL)
    {
        pBtn->EnableWindow(false);
    }

    m_StartUpdFontTime = CTime::GetCurrentTime();

 /* 首次发送 128个, 等待应答之后再发送剩余的 */
 if( m_FontLibFileLen < SEND_DATA_LEN_ONE_TIME)
 {
  m_CurSndPos  = 0; // 发送的位置在m_pBuffer中的偏移
  m_LastSndLen = m_FontLibFileLen;
  SendFontDataToCom(m_CurSPI_Flash_Addr, m_pBuffer + m_CurSndPos, m_LastSndLen);
  bIsFontLibInSending = true;
 }
 else
 {
  m_CurSndPos = 0;
  m_LastSndLen = SEND_DATA_LEN_ONE_TIME;
  SendFontDataToCom(m_CurSPI_Flash_Addr, m_pBuffer + m_CurSndPos, m_LastSndLen);
  bIsFontLibInSending = true;
 }

#if 1
 /******************* progress ****************************** */
    pProgressCtrl = (CProgressCtrl *)GetDlgItem(IDC_PROGRESS_UPDATE);
 if(NULL != pProgressCtrl)
 {
  pProgressCtrl->SetPos(0);                           /* 设置位置 */
  pProgressCtrl->SetStep(1);
 }

    unsigned long int Range = m_FontLibFileLen / (SEND_DATA_LEN_ONE_TIME); /* 文件长度 */
    if (Range == 0)    // 说明只需一步即可达到100%
    {
  Range = 1;
    }
    else if (Range > 0 && (m_FontLibFileLen % (SEND_DATA_LEN_ONE_TIME)) != 0) // 说明不是整除, 需要加上 1 (这是为什么呢? 因为如果一个数字是9.5 , 而每当3时进度条进1, 那么需要4次能把进度条推到100%, 而9.5/3 = 3, 所以给它加1变为4, 然后设置进度条范围为0到4)
    {
  Range += 1;
    }
    else // 刚好整除, 则步数刚好为整除结果
    {
    }
 pProgressCtrl->SetRange(0, Range);     /* 设置范围 */
 pProgressCtrl->ShowWindow(SW_SHOW);
 /******************* progress ****************************** */
#endif

 

/ SetTimer(RESEND_TIMER, 100, NULL); /* 设置定时器 超时重发 10 * 100ms */


    CTime StartTime = CTime::GetCurrentTime();
    CTime EndTime   = CTime::GetCurrentTime();
    int AckCmdLen = 1;

    unsigned char AckCmdBuf[256] = {0};
    while( bIsFontLibInSending )   /* 字库升级中 */
    {

#if 1
  if (!DoEvents())
  {
   break;
        }
  Sleep(1);
#endif

  AckCmdLen = GetAckCmdBuf(AckCmdBuf, 256);

        /* 一直接收不到单片机回复,超时10秒退出 */
        if(AckCmdLen != 0)
        {
            ParaseFontUpdateAck(AckCmdBuf, AckCmdLen);
            StartTime = CTime::GetCurrentTime();
        }
        else
        {
            EndTime   = CTime::GetCurrentTime();
            CTimeSpan timeSpan = EndTime - StartTime;     // 两个CTime相减得到CTimeSpan
            LONGLONG nTSeconds = timeSpan.GetTotalSeconds();                // 得到总的秒数
            if( nTSeconds > ACK_TIME_OUT )
            {
//                KillTimer(RESEND_TIMER);
                bIsFontLibInSending = false;
                m_CurSndPos     = 0;
                m_LastSndLen    = 0;
                m_CurSPI_Flash_Addr = 0;
                SetStauesText("字库升级超时失败!");
            }
        }
    }

  // CDialog::OnOK();
}

void CFontUpdate::OnTimer(UINT nIDEvent)
{
 // TODO: Add your message handler code here and/or call default
 char Tmp123[128];
 static int ReSendTime = 0;

    switch(nIDEvent)
    {
        case RESEND_TIMER:
        {
            if(bIsFontLibInSending == false || ReSendTime >= 10)
            {
                bIsFontLibInSending = false;
                m_CurSndPos = 0;
                m_LastSndLen = 0;
                m_CurSPI_Flash_Addr = 0;
                m_LastSndLen = 0;
                sprintf(Tmp123, "重发超过:%d Addr:%x, Len:%d 退出!",\
                                ReSendTime, m_CurSPI_Flash_Addr, m_LastSndLen);
                SetStauesText(Tmp123);

                if(NULL != m_pBuffer)
                {
                    delete m_pBuffer;
                    m_pBuffer = NULL;
                }

             

 /* 关闭按钮无效 */
                CButton *pBtn = (CButton *)GetDlgItem(IDC_BUTTON_OPEN_COM_PORT);
                if(pBtn != NULL)
                {
                    pBtn->EnableWindow(true);
                }

//                KillTimer(RESEND_TIMER);
                return;
            }

            if((m_TimeOut++) >= 25)
            {
                sprintf(Tmp123, "超时重发:%d Addr:%x, Len:%d", ReSendTime++, m_CurSPI_Flash_Addr, m_LastSndLen);
                SetStauesText(Tmp123);
                SendFontDataToCom(m_CurSPI_Flash_Addr, m_pBuffer + m_CurSndPos, m_LastSndLen);
                m_TimeOut = 0;
            }
        }
  break;
    }

 

CDialog::OnTimer(nIDEvent);
}


void CFontUpdate::OnBnClickedButtonEraseFlash()
{
 // TODO: 在此添加控件通知处理程序代码

    if(( bIsComPortOpen == false))
  {
  SetStauesText("串口尚未打开!");
  return;
 }

    /* 关闭按钮无效 */
    CButton *pBtn = (CButton *)GetDlgItem(IDC_BUTTON_OPEN_COM_PORT);
    if(pBtn != NULL)
    {
        pBtn->EnableWindow(false);
    }

    SendEraseFlashToCom(FONT_BASE_ADDR_IN_SPI_FLASH, 0);

    CTime StartTime = CTime::GetCurrentTime();
    CTime EndTime   = CTime::GetCurrentTime();
    int AckCmdLen = 1;

unsigned char AckCmdBuf[256] = {0};
    while(bIsFlashErase)   /* 擦除Flash */
    {
#if 1
        if (!DoEvents())
        {
            break;
        }
        Sleep(1);
#endif
       
        AckCmdLen = GetAckCmdBuf(AckCmdBuf, 256);

        /* 一直接收不到单片机回复,超时10秒退出 */
        if(AckCmdLen != 0)
        {
            ParaseEraseFlashAck(AckCmdBuf, AckCmdLen);
            StartTime = CTime::GetCurrentTime();
        }

 

 else
        {
            EndTime   = CTime::GetCurrentTime();
            CTimeSpan timeSpan = EndTime - StartTime;     // 两个CTime相减得到CTimeSpan
            LONGLONG nTSeconds = timeSpan.GetTotalSeconds();                // 得到总的秒数
            if( nTSeconds > ERASE_FLASH_ACK_TIME_OUT)
            {
                bIsFlashErase = false;
                SetStauesText("擦除Flash超时失败!");
            }
        }
    }
}

BOOL CFontUpdate::OnInitDialog()
{
 CDialog::OnInitDialog();

 // TODO:  在此添加额外的初始化
 FontUpdateInitial();
 return TRUE;  // return TRUE unless you set the focus to a control
 // 异常: OCX 属性页应返回 FALSE
}

int CFontUpdate::GetAckCmdBuf(unsigned char *PAckCmdBuf, int Len)
{
    LONG len, Idx;
 static BYTE RxDataBuf[1024] = {0}; // 设置BYTE数组 An 8-bit integer that is not signed.
 static LONG TotalRcvLen     = 0; // 保存当前缓存的个数
 DWORD AckCmdLen             = 0; // 单片机返回的应答个数

 /* 以下你可以根据自己的通信协议加入处理代码 */
    len = pCtrlComm->Read(RxDataBuf + TotalRcvLen, 1024 - TotalRcvLen);
 if(len > 0)
 {
        TotalRcvLen += len; // 长度累加

 }

 for( Idx = 0; Idx < TotalRcvLen; Idx++ )
    {
        if(   ('O' == RxDataBuf[Idx])
            &&('O' == RxDataBuf[Idx+1])
            &&('#' == RxDataBuf[Idx+2]))
        {
            AckCmdLen = Idx + 3;
            TotalRcvLen -= AckCmdLen;    /* 数据向前移动 */
            BYTE *pTmpBuf = RxDataBuf + AckCmdLen;
            if( Len >= AckCmdLen )
            {
                memcpy(PAckCmdBuf, RxDataBuf, AckCmdLen);
            }
            else
            {
                SetStauesText("超出缓存限制!");
                AckCmdLen = 0;
            }
   
            for(LONG TmpIdx = 0; TmpIdx < TotalRcvLen; TmpIdx++)
            {
                RxDataBuf[TmpIdx] = *(pTmpBuf + TmpIdx);
            }
            break;
        }
    }

    return AckCmdLen;
}

void CFontUpdate::ParaseEraseFlashAck(unsigned char *PAckCmdBuf, int Len)
{
    char TmpStatues[128];
    if(NULL != strstr((char *)PAckCmdBuf, CMD_CLEAR_SPI_FLASH))
    {
        bIsFlashErase = false;
        SetStauesText("擦除Flash成功");

        /* 关闭按钮无效 */
        CButton *pBtn = (CButton *)GetDlgItem(IDC_BUTTON_OPEN_COM_PORT);
        if(pBtn != NULL)
        {
            pBtn->EnableWindow(true);
        }
    }
}

void CFontUpdate::ParaseFontUpdateAck(unsigned char *PAckCmdBuf, int Len)
{
    char TmpStatues[128];

    if(NULL != strstr((char *)PAckCmdBuf, CMD_WRITE_SPI_FLASH))
    {
        DWORD AckComWriteSPI_Flash_Addr = 0;
        DWORD AckComWriteSPI_Flash_Len  = 0;

        /* 写入SPI Flash的地址 */
        AckComWriteSPI_Flash_Addr |= (*(PAckCmdBuf + 3) << 24);
        AckComWriteSPI_Flash_Addr |= (*(PAckCmdBuf + 4) << 16);
        AckComWriteSPI_Flash_Addr |= (*(PAckCmdBuf + 5) << 8 );
        AckComWriteSPI_Flash_Addr |= (*(PAckCmdBuf + 6) << 0 );

        AckComWriteSPI_Flash_Len  |= (*(PAckCmdBuf + 7) << 24);
        AckComWriteSPI_Flash_Len  |= (*(PAckCmdBuf + 8) << 16);
        AckComWriteSPI_Flash_Len  |= (*(PAckCmdBuf + 9) << 8 );
        AckComWriteSPI_Flash_Len  |= (*(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, m_pBuffer + m_CurSndPos, m_LastSndLen);
                    bIsFontLibInSending = true;
                }

 

  else
                {
                    m_LastSndLen = SEND_DATA_LEN_ONE_TIME;
                    SendFontDataToCom(m_CurSPI_Flash_Addr, m_pBuffer + m_CurSndPos, m_LastSndLen);
                    bIsFontLibInSending = true;
                }
                m_TimeOut = 0;

                sprintf(TmpStatues, "写入进度: %d / %d", m_CurSndPos, m_FontLibFileLen);
                SetStauesText(TmpStatues);
            }

 else if(m_CurSndPos == m_FontLibFileLen)    /* 写完成 */
            {
//                KillTimer(RESEND_TIMER);
                bIsFontLibInSending = false;
                m_CurSndPos  = 0;
                m_LastSndLen = 0;
                m_CurSPI_Flash_Addr = 0;
                m_EndUpdFontTime = CTime::GetCurrentTime();

                CTimeSpan timeSpan = m_EndUpdFontTime - m_StartUpdFontTime;     // 两个CTime相减得到CTimeSpan
                LONGLONG nTSeconds = timeSpan.GetTotalSeconds();                // 得到总的秒数
                sprintf(TmpStatues, "字库升级成功,共耗时: %d 秒", nTSeconds);
                SetStauesText(TmpStatues);
                if(NULL != m_pBuffer)
                {
                    delete m_pBuffer;
                    m_pBuffer = NULL;
                }

            

  /* 关闭按钮无效 */
                CButton *pBtn = (CButton *)GetDlgItem(IDC_BUTTON_OPEN_COM_PORT);
                if(pBtn != NULL)
                {
                    pBtn->EnableWindow(true);
                }
            }

            //CProgressCtrl *pProgressCtrl = (CProgressCtrl *)GetDlgItem(IDC_PROGRESS_UPDATE);
            if(NULL != pProgressCtrl)
            {
                pProgressCtrl->StepIt();
            }
        }
        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;
        }


          

    }
}

 

posted on 2020-07-27 15:20  yuanchaost  阅读(197)  评论(0编辑  收藏  举报