368 lines
6.3 KiB
C
368 lines
6.3 KiB
C
|
|
|
|||
|
|
#include "xmodem.h"
|
|||
|
|
#include "serial.h"
|
|||
|
|
#include "trigger.h"
|
|||
|
|
#include "shell.h"
|
|||
|
|
#include "delay.h"
|
|||
|
|
|
|||
|
|
//---------------------------------------------------------
|
|||
|
|
|
|||
|
|
#define DEBUG_OK 0
|
|||
|
|
|
|||
|
|
#if (DEBUG_OK == 1)
|
|||
|
|
|
|||
|
|
#define DEBUG_OUT(...) do \
|
|||
|
|
{\
|
|||
|
|
printf(__VA_ARGS__); \
|
|||
|
|
}while(0)
|
|||
|
|
|
|||
|
|
void OutDebugBufInfo(void){};
|
|||
|
|
|
|||
|
|
#elif (DEBUG_OK == 2)
|
|||
|
|
|
|||
|
|
char g_debugbuf[200][50];
|
|||
|
|
int g_debugidx = 0;
|
|||
|
|
|
|||
|
|
#define DEBUG_OUT(...) do \
|
|||
|
|
{\
|
|||
|
|
if (g_debugidx < 200) \
|
|||
|
|
{ \
|
|||
|
|
sprintf((char*)&(g_debugbuf[g_debugidx][0]), __VA_ARGS__); \
|
|||
|
|
g_debugidx++; \
|
|||
|
|
} \
|
|||
|
|
}while(0)
|
|||
|
|
|
|||
|
|
|
|||
|
|
#if (DEBUG_OK == 2)
|
|||
|
|
void OutDebugBufInfo(void)
|
|||
|
|
{
|
|||
|
|
printf("\r\nDebug buff info (%d):\r\n", g_debugidx);
|
|||
|
|
for (int i = 0; i < g_debugidx; i++)
|
|||
|
|
{
|
|||
|
|
printf("%s", (char*)(&g_debugbuf[i][0]));
|
|||
|
|
DelayMs(10);
|
|||
|
|
}
|
|||
|
|
printf("\r\nDebug buff info end\r\n");
|
|||
|
|
|
|||
|
|
g_debugidx = 0;
|
|||
|
|
}
|
|||
|
|
#endif
|
|||
|
|
|
|||
|
|
|
|||
|
|
#else
|
|||
|
|
|
|||
|
|
#define DEBUG_OUT(...) do {}while(0)
|
|||
|
|
|
|||
|
|
void OutDebugBufInfo(void){};
|
|||
|
|
|
|||
|
|
#endif
|
|||
|
|
|
|||
|
|
//---------------------------------------------------------
|
|||
|
|
|
|||
|
|
// <20><><EFBFBD><EFBFBD>xmodem<65><6D>crcֵ
|
|||
|
|
u16 CalcXModemCrc(u8 * pDat, int count)
|
|||
|
|
{
|
|||
|
|
u16 crc;
|
|||
|
|
int i;
|
|||
|
|
|
|||
|
|
crc = 0;
|
|||
|
|
while (--count >= 0)
|
|||
|
|
{
|
|||
|
|
crc = crc ^ (u16) (*pDat++ << 8);
|
|||
|
|
i = 8;
|
|||
|
|
do
|
|||
|
|
{
|
|||
|
|
if (crc & 0x8000)
|
|||
|
|
{
|
|||
|
|
crc = crc << 1 ^ 0x1021; // X16+X12+X5+X0
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
crc = crc << 1;
|
|||
|
|
}
|
|||
|
|
} while (--i);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return (crc);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// <20><><EFBFBD><EFBFBD>xmodem<65><6D><EFBFBD>ݰ<EFBFBD><DDB0><EFBFBD><EFBFBD><EFBFBD>ȷ<EFBFBD><C8B7>
|
|||
|
|
int CheckXModemDat(int crcflag, u8 * pBuf, int size)
|
|||
|
|
{
|
|||
|
|
if(crcflag != 0)
|
|||
|
|
{
|
|||
|
|
u16 crc = CalcXModemCrc(pBuf, size);
|
|||
|
|
u16 tcrc = ((u16)(pBuf[size])<<8) + pBuf[size+1];
|
|||
|
|
|
|||
|
|
if (crc == tcrc)
|
|||
|
|
{
|
|||
|
|
return 1;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
int i = 0;
|
|||
|
|
u8 cks = 0;
|
|||
|
|
|
|||
|
|
for(i = 0; i < size; i++)
|
|||
|
|
{
|
|||
|
|
cks += pBuf[i];
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (cks == pBuf[size])
|
|||
|
|
{
|
|||
|
|
return 1;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// <20><><EFBFBD><EFBFBD>xmodem<65><6D><EFBFBD><EFBFBD>
|
|||
|
|
int XmodemReceive(XmodemCtrl * pCtrl)
|
|||
|
|
{
|
|||
|
|
int rslt, err, retry, recvsize, exsize;
|
|||
|
|
int timer;
|
|||
|
|
u8 packid, tmpid, temp;
|
|||
|
|
u8 trychar, svchar;
|
|||
|
|
u8 xbuff[XMODEM1K_FRAME_C];
|
|||
|
|
u8 ch;
|
|||
|
|
int crcflag;
|
|||
|
|
int datidx;
|
|||
|
|
|
|||
|
|
trychar = 'C'; // <20><><EFBFBD><EFBFBD>crcУ<63>鷽ʽ
|
|||
|
|
svchar = trychar;
|
|||
|
|
recvsize = 0;
|
|||
|
|
packid = 1;
|
|||
|
|
err = 0;
|
|||
|
|
datidx = 0;
|
|||
|
|
|
|||
|
|
pCtrl->InitSave();
|
|||
|
|
|
|||
|
|
DEBUG_OUT("Start XmodemReceive\r\n");
|
|||
|
|
|
|||
|
|
#define MAX_RETRY 32
|
|||
|
|
|
|||
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
for (retry = 0; retry < MAX_RETRY; retry++) // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
{
|
|||
|
|
// 1. <20><><EFBFBD><EFBFBD><EFBFBD>ͷ<EFBFBD><CDB7><EFBFBD><EFBFBD><EFBFBD>ͬ<EFBFBD><CDAC><EFBFBD>ֽ<EFBFBD>
|
|||
|
|
if(trychar != 0)
|
|||
|
|
{
|
|||
|
|
xbuff[0] = trychar;
|
|||
|
|
pCtrl->XmodemOutBuff(xbuff, 1);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 2. <20>ȴ<EFBFBD><C8B4>ظ<EFBFBD><D8B8><EFBFBD><EFBFBD>ݰ<EFBFBD>
|
|||
|
|
timer = GetMsSoftTimer(); // <20><>¼ʱ<C2BC><CAB1>
|
|||
|
|
recvsize = 0;
|
|||
|
|
do
|
|||
|
|
{
|
|||
|
|
rslt = pCtrl->XmodemInBuff(xbuff, 1);
|
|||
|
|
if (rslt != 1) // <20>ȵ<EFBFBD><C8B5>ַ<EFBFBD>
|
|||
|
|
{
|
|||
|
|
if (GetMsSoftTimer() - timer > 1000) // <20>ж<EFBFBD><D0B6>Ƿ<EFBFBD><C7B7><EFBFBD>ʱ
|
|||
|
|
{
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
continue;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
ch = xbuff[0];
|
|||
|
|
switch(ch)
|
|||
|
|
{
|
|||
|
|
case XMODEM_SOH: // Xmodem<65><6D><EFBFBD>ݰ<EFBFBD>ͷ
|
|||
|
|
{
|
|||
|
|
DEBUG_OUT("get soh\r\n");
|
|||
|
|
recvsize = XMODEM_F_SIZE;
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
case XMODEM_STX: // 1K-Xmodem<65><6D><EFBFBD>ݰ<EFBFBD>ͷ
|
|||
|
|
{
|
|||
|
|
DEBUG_OUT("get stx\r\n");
|
|||
|
|
recvsize = XMODEM1K_F_SIZE;
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
case XMODEM_EOT: // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
{
|
|||
|
|
DEBUG_OUT("get eot\r\n");
|
|||
|
|
|
|||
|
|
pCtrl->XmodemCleanBuff(); // <20><><EFBFBD><EFBFBD><EFBFBD>Ѿ<EFBFBD><D1BE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
xbuff[0] = XMODEM_ACK; // ȷ<>ϻظ<CFBB>
|
|||
|
|
pCtrl->XmodemOutBuff(xbuff, 1);
|
|||
|
|
err = 1;
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
case XMODEM_CAN: // ȡ<><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
{
|
|||
|
|
DEBUG_OUT("get can\r\n");
|
|||
|
|
|
|||
|
|
pCtrl->XmodemCleanBuff(); // <20><><EFBFBD><EFBFBD><EFBFBD>Ѿ<EFBFBD><D1BE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
xbuff[0] = XMODEM_ACK; // ȷ<>ϻظ<CFBB>
|
|||
|
|
pCtrl->XmodemOutBuff(xbuff, 1);
|
|||
|
|
err = -2;
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
default:
|
|||
|
|
{
|
|||
|
|
DEBUG_OUT("get others\r\n");
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
break;
|
|||
|
|
}while(1);
|
|||
|
|
|
|||
|
|
if (err == 0)
|
|||
|
|
{
|
|||
|
|
// 3. <20>жϻظ<CFBB><D8B8>Ƿ<EFBFBD><C7B7><EFBFBD>ȷ
|
|||
|
|
if (recvsize == 0) // ͬ<><CDAC><EFBFBD>ֳ<EFBFBD>ʱ
|
|||
|
|
{
|
|||
|
|
if (trychar == 'C')
|
|||
|
|
{
|
|||
|
|
if (retry >= MAX_RETRY-1)
|
|||
|
|
{
|
|||
|
|
trychar = XMODEM_NAK; // <20><>Ϊʹ<CEAA>ú<EFBFBD>У<EFBFBD>鷽ʽ
|
|||
|
|
retry = 0;
|
|||
|
|
}
|
|||
|
|
continue; // <20><><EFBFBD>¿<EFBFBD>ʼ
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
if (retry >= MAX_RETRY-1)
|
|||
|
|
{
|
|||
|
|
err = -1; // <20>泬ʱ<E6B3AC><CAB1><EFBFBD>˳<EFBFBD>
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
continue;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
if (trychar != 0)
|
|||
|
|
{
|
|||
|
|
DEBUG_OUT("save trychar\r\n");
|
|||
|
|
svchar = trychar;
|
|||
|
|
}
|
|||
|
|
trychar = 0; // <20>Ѿ<EFBFBD><D1BE><EFBFBD><EFBFBD><EFBFBD><EFBFBD>˴<EFBFBD><CBB4><EFBFBD>
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><C4BC><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
if (err == 0 && recvsize != 0)
|
|||
|
|
{
|
|||
|
|
if (svchar == 'C')
|
|||
|
|
{
|
|||
|
|
DEBUG_OUT("exsize = 4\r\n");
|
|||
|
|
exsize = XMODEM_HEAD_SIZE+XMODEM_CRC_SIZE-1;
|
|||
|
|
crcflag = 1;
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
DEBUG_OUT("exsize = 3\r\n");
|
|||
|
|
exsize = XMODEM_HEAD_SIZE+XMODEM_CHECK_SIZE-1;
|
|||
|
|
crcflag = 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݰ<EFBFBD>
|
|||
|
|
timer = GetMsSoftTimer(); // <20><>¼ʱ<C2BC><CAB1>
|
|||
|
|
DEBUG_OUT("timer=%d\r\n", timer);
|
|||
|
|
|
|||
|
|
do
|
|||
|
|
{
|
|||
|
|
rslt = pCtrl->XmodemInBuff(&(xbuff[1]), recvsize+exsize);
|
|||
|
|
if (rslt == recvsize+exsize) // <20>ȵ<EFBFBD><C8B5>ַ<EFBFBD>
|
|||
|
|
{
|
|||
|
|
DEBUG_OUT("get exsize+recvsize=%d+%d\r\n", exsize, recvsize);
|
|||
|
|
|
|||
|
|
tmpid = xbuff[1];
|
|||
|
|
temp = ~(xbuff[2]);
|
|||
|
|
|
|||
|
|
if ((tmpid == temp) &&
|
|||
|
|
(CheckXModemDat(crcflag, &(xbuff[3]), recvsize) != 0))
|
|||
|
|
{
|
|||
|
|
xbuff[0] = XMODEM_ACK; // <20>ظ<EFBFBD>ACK<43><4B>ȷ<EFBFBD>Ͻ<EFBFBD><CFBD>յ<EFBFBD><D5B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD>ݰ<EFBFBD>
|
|||
|
|
pCtrl->XmodemOutBuff(xbuff, 1);
|
|||
|
|
|
|||
|
|
DEBUG_OUT("check ok, send ack\r\n");
|
|||
|
|
|
|||
|
|
if (tmpid == packid) // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
{
|
|||
|
|
int svlen;
|
|||
|
|
int svflag = (datidx == 0 ? 0:1);
|
|||
|
|
svlen = pCtrl->SaveData(svflag, &(xbuff[3]), recvsize, pCtrl->savedsize); // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
if (svlen > 0)
|
|||
|
|
{
|
|||
|
|
pCtrl->savedsize += svlen;
|
|||
|
|
}
|
|||
|
|
datidx++;
|
|||
|
|
packid++;
|
|||
|
|
}
|
|||
|
|
retry = 0;
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
xbuff[0] = XMODEM_NAK; // <20>ظ<EFBFBD> NAK<41><4B><EFBFBD><EFBFBD>Ҫ<EFBFBD><D2AA><EFBFBD>´<EFBFBD><C2B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݰ<EFBFBD>
|
|||
|
|
pCtrl->XmodemOutBuff(xbuff, 1);
|
|||
|
|
|
|||
|
|
DEBUG_OUT("crc err, send NAK\r\n");
|
|||
|
|
}
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
int tptimer;
|
|||
|
|
|
|||
|
|
// <20><><EFBFBD><EFBFBD>
|
|||
|
|
tptimer = GetMsSoftTimer();
|
|||
|
|
if (tptimer - timer > recvsize*1) // <20>ж<EFBFBD><D0B6>Ƿ<EFBFBD><C7B7><EFBFBD>ʱ
|
|||
|
|
{
|
|||
|
|
DEBUG_OUT("tptimer=%d, timer=%d, gap=%d\r\n", tptimer, timer, tptimer - timer);
|
|||
|
|
|
|||
|
|
rslt = pCtrl->XmodemGetInBuffLen();
|
|||
|
|
if (rslt > 0)
|
|||
|
|
{
|
|||
|
|
pCtrl->XmodemCleanBuff(); // <20><><EFBFBD><EFBFBD><EFBFBD>Ѿ<EFBFBD><D1BE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
xbuff[0] = XMODEM_NAK; // <20>ظ<EFBFBD> NAK<41><4B><EFBFBD><EFBFBD>Ҫ<EFBFBD><D2AA><EFBFBD>´<EFBFBD><C2B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݰ<EFBFBD>
|
|||
|
|
pCtrl->XmodemOutBuff(xbuff, 1);
|
|||
|
|
DEBUG_OUT("resvlen = %d, send NAK\r\n", rslt);
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
DEBUG_OUT("not data, error\r\n");
|
|||
|
|
err = -1; // <20><><EFBFBD>ճ<EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD>˳<EFBFBD>
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
DEBUG_OUT("wait timeout\r\n");
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD>ȴ<EFBFBD>
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}while(1);
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
DEBUG_OUT("err != 0 || recvsize == 0\r\n");
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (err < 0)
|
|||
|
|
{
|
|||
|
|
DEBUG_OUT("err < 0 sanc cancel\r\n");
|
|||
|
|
|
|||
|
|
xbuff[0] = XMODEM_CAN; // ȡ<><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
pCtrl->XmodemOutBuff(xbuff, 1);
|
|||
|
|
pCtrl->XmodemOutBuff(xbuff, 1);
|
|||
|
|
pCtrl->XmodemOutBuff(xbuff, 1);
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
} // end of for
|
|||
|
|
|
|||
|
|
return err;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|