📄 xmodem.c
字号:
#include "Xmodem.h"
#include "Buffer.h"
static enum {
ST_HEAD,
ST_SEQ,
ST_SEQC,
ST_DATA,
ST_CHKSUM,
ST_STORE
} CurState;
static u32 RecvBuf[PACKET_1K_SIZE >> 2];
static unsigned PackLen, RecvLen;
static unsigned TimeCount;
static u8 FirstWait, Chksum;
static u8 CurSeq, SeqNum, SeqComp;
unsigned Xmodem_RecvSize;
static void Xmodem_Send(u8 c)
{
UART_ByteSend(UARTX, &c);
}
void Xmodem_Reset(void)
{
CurSeq = 0;
CurState = ST_HEAD;
TimeCount = NAK_TIMEOUT_WAIT;
FirstWait = 1;
Xmodem_RecvSize = 0;
}
int Xmodem_Action(void)
{
u8 c;
if(CurState == ST_STORE)
{
if(Buf_Put(RecvBuf, PackLen >> 2))
return 0;
CurSeq = SeqNum;
c = ACK;
goto Restart;
}
if(TimeCount)
{
if(UART_FlagStatus(UARTX) & (UART_RxHalfFull | UART_RxBufFull))
{
UART_ByteReceive(UARTX, &c, 0xFF);
switch(CurState)
{
case ST_HEAD:
switch(c)
{
case SOH:
PackLen = PACKET_SIZE;
break;
case STX:
PackLen = PACKET_1K_SIZE;
break;
case EOT:
Xmodem_Send(ACK);
return 1;
default:
c = NAK;
goto Restart;
}
FirstWait = 0;
CurState = ST_SEQ;
break;
case ST_SEQ:
SeqNum = c;
CurState = ST_SEQC;
break;
case ST_SEQC:
SeqComp = c;
RecvLen = 0;
Chksum = 0;
CurState = ST_DATA;
break;
case ST_DATA:
((u8 *)RecvBuf)[RecvLen++] = c;
Chksum += c;
if(RecvLen >= PackLen)
CurState = ST_CHKSUM;
break;
case ST_CHKSUM:
if(SeqNum + SeqComp == 255 && Chksum == c)
{
if(SeqNum == CurSeq)
{
c = ACK;
goto Restart;
}
else if(SeqNum == (CurSeq + 1 & 255))
{
Xmodem_RecvSize += PackLen;
CurState = ST_STORE;
break;
}
}
c = NAK;
goto Restart;
}
TimeCount = NAK_TIMEOUT_RECV;
}
else
TimeCount--;
return 0;
}
c = NAK;
Restart:
Xmodem_Send(c);
CurState = ST_HEAD;
TimeCount = NAK_TIMEOUT_WAIT;
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -