📄 lpc2xxisp.cpp
字号:
#include "stdafx.h"
#include "SCOMM.h"
#include "resource.h"
#include "FlashISPDlg.h"
#include "hexreader.h"
#include "math.h"
#include "time.h"
//#include "..\\FrameData.h"
//#include "..\\Option.h"
#define ENCODE_BYTE(b) (((b) == 0) ? 0x60 : ((b) + 0x20))
#define MAX_LINELEN 45
#define UU_LINE 20
#define SYSTEMCLK 8000
#define BUFF_SIZE 4096
#define DOWN_SIZE 1024
#define ID_DWN_EXIT -1
#define ID_DWN_ACTIVERUN 2
#define ID_DWN_DOWNPROGRAM 8
#define ID_IAP_ACTIVE 9
#define ID_IAP_ERASE 10
#define ID_IAP_PROGRAM 11
#define ID_IAP_BAUD 12
#define MAX_RANDNUM 10
BOOL m_ExitThreadNo,m_bEraseAll;
extern UINT m_DownloadTimerId,m_iDownloadTimer;
int randEx(int MAX,int NUM)
{
int k=0;
int j=0;
time_t t;
int RAND[MAX_RANDNUM];
//设置rand函数所用的启始种子值,以期每次产生的随机数序列均不相同。
srand((unsigned) time(&t));
for (k=1;k<=NUM;k++)//定制随机数数量。
{
RAND[k]=rand()%MAX;//定制随机数在0至最大值之间
do
{
for (j=1;j<k;j++) if (RAND[j]==RAND[k]) //一次随机数序列中有相同随机数则再
//产生一个,直至一次随机数序列中随机数全不相同。
{
RAND[k]=rand()%MAX;
break;
}
}while(j<k);
j += RAND[k];
}
j = j/MAX_RANDNUM;
return j;
}
DWORD PacketCommand(BYTE *cmdstr,BYTE cmd,BYTE *str,DWORD len)
{
BYTE chksum = 0;
DWORD pos = 0;
cmdstr[pos++] = 0x55;
cmdstr[pos++] = 0xAA;
cmdstr[pos++] = (BYTE)(len + 6)/0x100 &0xff;
cmdstr[pos++] = (BYTE)(len + 6)&0xff;
cmdstr[pos++] = (BYTE)~(len + 6)/0x100 &0xff;
cmdstr[pos++] = (BYTE)~(len + 6)&0xff;
cmdstr[pos++] = (BYTE)cmd;
chksum ^= cmd;
while(len --)
{
cmdstr[pos++] = *str;
chksum ^= *(str++);
}
cmdstr[pos++] = chksum;
return pos;
}
DWORD PacketData(BYTE *cmdstr,BYTE cmd,DWORD address,BYTE *str,DWORD len)
{
BYTE chksum = 0;
DWORD pos = 0;
cmdstr[pos++] = 0x55;
cmdstr[pos++] = 0xAA;
cmdstr[pos++] = (BYTE)((len + 6 + 8)/0x100 &0xff);
cmdstr[pos++] = (BYTE)((len + 6 + 8)&0xff);
cmdstr[pos++] = (BYTE)(~(len + 6 + 8)/0x100 &0xff);
cmdstr[pos++] = (BYTE)(~(len + 6 + 8)&0xff);
cmdstr[pos++] = cmd;
chksum ^= cmd;
cmdstr[pos] = (BYTE)(address/0x1000000 & 0xff);
chksum ^= cmdstr[pos++];
cmdstr[pos] = (BYTE)(address/0x10000 & 0xff);
chksum ^= cmdstr[pos++];
cmdstr[pos] = (BYTE)(address/0x100 & 0xff);
chksum ^= cmdstr[pos++];
cmdstr[pos] = (BYTE)(address/0x1 & 0xff);
chksum ^= cmdstr[pos++];
cmdstr[pos] = (BYTE)(len/0x1000000 & 0xff);
chksum ^= cmdstr[pos++];
cmdstr[pos] = (BYTE)(len/0x10000 & 0xff);
chksum ^= cmdstr[pos++];
cmdstr[pos] = (BYTE)(len/0x100 & 0xff);
chksum ^= cmdstr[pos++];
cmdstr[pos] = (BYTE)(len/0x1 & 0xff);
chksum ^= cmdstr[pos++];
while(len --)
{
cmdstr[pos++] = *str;
chksum ^= *(str++);
}
cmdstr[pos++] = chksum;
return pos;
}
BYTE ReadOneFrame(CSerial *pComm,BYTE *buff,DWORD *length)
{
DWORD acklen,size;
BYTE ack[10],func_code,tPos=0;
m_iDownloadTimer = 1000;
do {
do{
pComm->ReadData((BYTE*)ack,1,&acklen);
if(acklen) break;
else
{
Sleep(1);
if(m_iDownloadTimer) m_iDownloadTimer --;
}
if(m_iDownloadTimer == 0) return 0;
} while(1);
m_iDownloadTimer = 50;
switch(tPos)
{
case 0:
if(ack[0]==0x55) tPos++;
break;
case 1:
if((BYTE)ack[0]==0xAA) tPos++;
break;
case 2:
size = ack[0]*0x100;
tPos++;
break;
case 3:
size += ack[0];
tPos ++;
break;
case 4:
case 5:
tPos ++;
break;
case 6:
func_code = ack[0];
tPos ++;
size -= 5;
break;
default:
buff[tPos-7] = ack[0];
tPos ++;
size --;
if(size == 0)
{
m_iDownloadTimer = 0;
return func_code;
}
}
}while(m_iDownloadTimer != 0);
return 0;
}
// 发送命令,并校验返回命令是否正确
// cmd, 发送命令
// cmdlen, 发送命令长度
// ack, 接收响应
// acklen, 接收响应长度
// 返回结果:
// 0 -- 没有收到信息
// >0 -- 接收信息长度并校验正确,
// <0 -- 接收信息长度并校验错误.
long SendIspCommand(CSerial *pComm,char *cmd,DWORD cmdlen,char *ack,DWORD acklen,int timeout,LPVOID pParam)
{
CFlashISPDlg *pDlg = (CFlashISPDlg *)pParam;
DWORD rcvlen=0,rec_len,error_cnt=25;
long result;
char rcvbuff[100]={0};
pComm->ClearBuffer();
pComm->SendData((BYTE*)cmd,cmdlen);
m_DownloadTimerId = pDlg->SetTimer(24,timeout,NULL);
m_iDownloadTimer = timeout;
while((rcvlen < acklen)&&(m_iDownloadTimer))
{
pComm->ReadData((BYTE *)rcvbuff,acklen,&rec_len);
rcvlen+=rec_len;
if(rec_len == 0) Sleep(30);
}
pDlg->KillTimer(24);
if(m_iDownloadTimer == 0) return 0;
if(memcmp(rcvbuff,ack,acklen)==0) return rcvlen;
result = rcvlen;
return -result;
}
long IspReadData(CSerial *pComm,char *cmd,DWORD cmdlen,char *ack,DWORD acklen,int timeout,LPVOID pParam)
{
CFlashISPDlg *pDlg = (CFlashISPDlg *)pParam;
DWORD rcvlen=0,rec_len,error_cnt=25;
pComm->ClearBuffer();
pComm->SendData((BYTE*)cmd,cmdlen);
m_DownloadTimerId = pDlg->SetTimer(24,timeout,NULL);
m_iDownloadTimer = timeout;
while((rcvlen < acklen)&&(m_iDownloadTimer))
{
pComm->ReadData((BYTE *)ack,acklen,&rec_len);
rcvlen+=rec_len;
if(rec_len == 0) Sleep(30);
}
pDlg->KillTimer(24);
return rcvlen;
}
//int NxpIspCommand()
//{
//}
// 根据地址计算获得该地址属于第几扇区
char szMcuAck[]={"Synchronized\r\n"};
char szMcuAckOK[]={"OK\r\n"};
char szSynchronizeOK[]={"Synchronized\rOK\r\n"};
char szDeviceSignature[20];
void ExitIspFlash(int exitcode)
{
if(m_ExitThreadNo == 0) m_ExitThreadNo = exitcode;
}
UINT ThreadNxpIspFlash(LPVOID pParam)
{
CFlashISPDlg *pDlg = (CFlashISPDlg *)pParam;
CWnd *pnd = pDlg->GetDlgItem(IDOK);
CProgressCtrl *pDownProgress = (CProgressCtrl*)pDlg->GetDlgItem(IDC_UPDATEPROGRESS);
BYTE errorcount;
int iBackupStep,iDownProgress,iDownFileStep=0,iDownStep;
char cmd[10240];
char ack[100]="Synchronized\r\n";
int iSect=0;
// DWORD xLen;
DWORD size,acklen;//,rLen;
CFile file;
DWORD tPos=0;
DWORD rCnt=0;
DWORD iPos=0;
DWORD xCrc=0;
int oPos=0;
// DWORD ixx;
// BYTE *sBuf;
UINT iStartAddress,iCurrentAddress,iEndAddress;
CString filename;
BYTE ProgramBuff[512*1024];
m_ExitThreadNo = FALSE;
iDownFileStep = 0;
srand( (unsigned)time( NULL ) );
switch(pDlg->m_iFunc)
{
case 0x01:
iDownStep = ID_DWN_DOWNPROGRAM;
iDownFileStep = 0;
break;
case 0x02:
// iDownStep = ID_DWN_ERASE;
// iDownFileStep = 0;
// break;
default:
return 0;
}
do
{
switch(iDownStep)
{
case ID_IAP_ACTIVE:
pDlg->m_ComPort.SetBaudRate(19200);
pDlg->m_ComPort.ClearBuffer();
Sleep(20);
errorcount = 3;
memset(ack,0,sizeof(ack));
pDlg->m_ComPort.SendData((BYTE*)("\x55\xAA\x00\x00\x00\x00\xC0\x05\x68\x7f\x4f\x5D"),12);
m_DownloadTimerId = pDlg->SetTimer(24,1000,NULL);
m_iDownloadTimer = 1000;
do{
pDlg->m_ComPort.ReadData((BYTE *)ack,1,(DWORD*)&acklen);
} while((acklen==0)&&(m_iDownloadTimer));
pDlg->KillTimer(24);
if((ack[0]=='?')&&(acklen!=0))
{
sprintf(cmd,"UPDATE!");
pDlg->m_ComPort.ClearBuffer();
memset(ack,0,sizeof(ack));
Sleep(20);
pDlg->m_ComPort.SendData((BYTE*)cmd,strlen(cmd));
m_DownloadTimerId = pDlg->SetTimer(24,200,NULL);
m_iDownloadTimer = 200;
do{
pDlg->m_ComPort.ReadData((BYTE *)ack,3,(DWORD*)&acklen);
} while((acklen<2)&&(m_iDownloadTimer));
//pDlg->KillTimer(24);
if(strstr(ack,"OK!")!=NULL)
{
iDownStep = ID_IAP_BAUD;
break;
}
}
if(errorcount > 0)
{
errorcount --;
break;
}
ExitIspFlash(iDownStep);
break;
case ID_IAP_BAUD:
Sleep(200);
pDlg->m_ComPort.ClearBuffer();
memset(cmd,0,sizeof(cmd));
size = PacketData((BYTE*)cmd,0x63,pDlg->m_iBaudRate,(BYTE*)ack,0);
pDlg->m_ComPort.SendData((BYTE*)cmd,size);
memset(cmd,0,sizeof(cmd));
if(ReadOneFrame(&pDlg->m_ComPort,(BYTE*)cmd,(DWORD*)&size)==0x63)
{
if(cmd[0] == 0)
{
iDownStep = ID_IAP_ERASE;
pDlg->m_ComPort.SetBaudRate(pDlg->m_iBaudRate);
break;
}
else if(errorcount > 0)
{
errorcount --;
iDownStep = ID_IAP_ACTIVE;
break;
}
if(m_ExitThreadNo != 0) break;
}
ExitIspFlash(iDownStep);
break;
case ID_IAP_ERASE:
// pDlg->m_ComPort.SetBaudRate(9600);
pDlg->m_ComPort.ClearBuffer();
ack[0] = 0x00;
ack[1] = 0x01;
ack[2] = 0x00;
ack[3] = 0x00;
ack[4] = 0x00;
ack[5] = 0x06;
ack[6] = 0x80;
ack[7] = 0x00;
memset(cmd,0,sizeof(cmd));
tPos = 0;
size = PacketCommand((BYTE*)cmd,0x62,(BYTE*)ack,8);
memset(ack,0,sizeof(ack));
pDlg->m_ComPort.SendData((BYTE*)cmd,size);
memset(cmd,0,sizeof(cmd));
if(ReadOneFrame(&pDlg->m_ComPort,(BYTE*)cmd,(DWORD*)&size)==0x62)
{
if(cmd[0] == 0)
{
iDownStep = ID_IAP_PROGRAM;
break;
}
if(m_ExitThreadNo != 0) break;
}
ExitIspFlash(iDownStep);
break;
case ID_IAP_PROGRAM:
iStartAddress = 0x10000;
iCurrentAddress = 0x10000;
errorcount = 3;
do {
pDlg->m_ComPort.ClearBuffer();
memset(cmd,0,sizeof(cmd));
tPos = 0;
size = PacketData((BYTE*)cmd,0x61,iCurrentAddress,(BYTE*)&ProgramBuff[iCurrentAddress],DOWN_SIZE);
memset(ack,0,sizeof(ack));
pDlg->m_ComPort.SendData((BYTE*)cmd,size);
memset(cmd,0,sizeof(cmd));
if(ReadOneFrame(&pDlg->m_ComPort,(BYTE*)cmd,(DWORD*)&size)==0x61)
{
if(cmd[0] == 0)
{
iCurrentAddress += DOWN_SIZE;
pDownProgress->SetPos((iCurrentAddress-iStartAddress)*100/(iEndAddress-iStartAddress));
errorcount = 10;
}
else
{
if(errorcount > 0) errorcount --;
else
break;
}
}
if(m_ExitThreadNo != 0) break;
}while(iCurrentAddress<iEndAddress);
if(iCurrentAddress == iEndAddress)
{
iDownStep = iBackupStep;
}
else
{
ExitIspFlash(iDownStep);
}
break;
case ID_DWN_DOWNPROGRAM:
iBackupStep = ID_DWN_DOWNPROGRAM;
switch(iDownFileStep)
{
case 0: // open boxinfo file
filename = pDlg->m_DownLoadFileName;
memset(ProgramBuff,0,sizeof(ProgramBuff));
if(ReadHexFile(ProgramBuff,filename,&iStartAddress,&iEndAddress)==FALSE)
{
AfxMessageBox("打开文件失败!");
ExitIspFlash(iDownStep);
break;
}
iCurrentAddress = iStartAddress;
if((iEndAddress - iStartAddress) < DOWN_SIZE)
{
iEndAddress = iStartAddress + DOWN_SIZE;
}
else if((iEndAddress - iStartAddress)%DOWN_SIZE!=0)
{
iEndAddress += (DOWN_SIZE - ((iEndAddress - iStartAddress)%DOWN_SIZE));
}
m_bEraseAll = FALSE;
iDownFileStep ++;
iDownStep = ID_IAP_ACTIVE;
// iDownStep = ID_IAP_ERASE;
errorcount = 3;
iDownProgress = 0;
break;
case 1: // erase flash room
// pDlg->m_ComPort.Close();
pnd->SetWindowText("开始");
iDownStep = ID_DWN_ACTIVERUN;
iDownProgress = 0;
// pDlg->m_ComPort.Open();
pDlg->m_ComPort.ClearBuffer();
pDlg->m_ComPort.SetBaudRate(19200);
pDlg->m_ComPort.ClearBuffer();
Sleep(20);
pDlg->m_ComPort.SendData((BYTE*)("\x55\xAA\x00\x00\x00\x00\xC0\x05\x68\x7f\x4f\x5D"),12);
pDlg->m_ComPort.Close();
break;
}
break;
case ID_DWN_ACTIVERUN:
pDlg->m_ComPort.SetBaudRate(19200);
pDlg->m_ComPort.ClearBuffer();
pDlg->m_ComPort.SendData((BYTE*)("\x55\xAA\x00\x00\x00\x00\xC0\x05\x68\x7f\x4f\x5D"),12);
Sleep(500);
iDownStep = ID_DWN_EXIT;
break;
}
if(iDownStep == -1) break;
}while(m_ExitThreadNo == 0);
pDlg->m_ComPort.Close();
switch(m_ExitThreadNo)
{
case ID_IAP_ACTIVE:
case ID_IAP_BAUD:
case ID_IAP_ERASE:
AfxMessageBox("下载程序失败!");
break;
case ID_IAP_PROGRAM:
if(errorcount == 0) AfxMessageBox("下载程序失败!");
else AfxMessageBox("下载程序完成!");
break;
}
pnd->SetWindowText("编程");
pDlg->SendMessage(WM_MYUPDATEDATA,false);
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -