📄 xmodem.c
字号:
/*-------------------------------------------------------
Function: Offline Downloader Main Program
File: OfflineDown.c
Version: 1.0
Author: 1.Shao Ziyang
2.avenbbs(8785116@qq.com)
Date: 2008-9-20~2008-10-1
--------------------------------------------------------*/
#include <avr/io.h>
#include "xmodem.h"
#include <util/delay.h>
#include <avr/eeprom.h>
//#include <avr/interrupt.h>
#include "common.h"
#include "usart.h"
//#include "AT45DB041D.h"
#include "AT45.h"
//Bootloader触发模式 0:串口 1:电平
#define LEVELMODE 0
#define LEVELPORT D
#define LEVELPIN PD7
//触发电平 1:高 0:低
#define PINLEVEL 0
//等待密码的超时时间 = TimeOutCnt * timeclk
//超时次数
#define TimeOutCnt 10
//同步时间间隔(ms)
#define timeclk 300
//等待文件的超时时间 = TimeOutCntC * timeclk
//发送'C'的最大次数
#define TimeOutCntC 100
//同步密码长度
#define CONNECTCNT 1
//同步密码
unsigned char ConnectKey[] = {0x66};
//使用定时器1:1024分频,CTC模式4,产生以毫秒为单位的时间
#define TimerInit() \
{ \
OCR1A = (unsigned int)(timeclk * (F_CPU / (1024 * 1000.0f))); \
TCCR1A = 0; \
TCCR1B = (1 << WGM12)|(1 << CS12)|(1 << CS10); \
}
//Xmoden控制字符
#define XMODEM_NUL 0x00
#define XMODEM_SOH 0x01
#define XMODEM_STX 0x02
#define XMODEM_EOT 0x04
#define XMODEM_ACK 0x06
#define XMODEM_NAK 0x15
#define XMODEM_CAN 0x18
#define XMODEM_EOF 0x1A
#define XMODEM_RWC 'C'
extern volatile unsigned char error_flag;
extern unsigned char section;
extern unsigned char keylock;
volatile unsigned char xmodem_rcv;
char msg_timeout[]="Timeout!";
//接收缓冲区
#define BUFFERSIZE 128
#define BUFSIZE 512
unsigned char buf[BUFSIZE];
unsigned int bufptr, pagptr;
//当前Flash地址指针
//#if (FLASHEND > 0xFFFFUL)
//unsigned long int FlashAddr;
//#else
//unsigned int FlashAddr;
//#endif
unsigned char ch, cl;
//校验方法 0:CRC16 1:累加和
#define CRCMODE 0
void crc16(unsigned char *buf)
{
#if (BUFSIZE > 255)
unsigned int j;
#else
unsigned char j;
#endif
#if (CRCMODE == 0)
unsigned char i;
unsigned int t;
#endif
unsigned int crc;
crc = 0;
for (j = BUFFERSIZE; j > 0; j--)
{
#if (CRCMODE == 0)
//标准CRC校验
crc = (crc ^(((unsigned int) *buf) << 8));
for (i = 8; i > 0; i--)
{
t = crc << 1;
if (crc & 0x8000)
t = t ^ 0x1021;
crc = t;
}
#elif (CRCMODE == 1)
//累加和校验
crc += (unsigned int)(*buf);
#elif
#endif
buf++;
}
ch = crc / 256;
cl = crc % 256;
}
int xmodem2df(unsigned int begin_address)
{
// unsigned int i;
unsigned int page_cnt=begin_address;
unsigned char cnt;
unsigned char packNO;
unsigned char crch, crcl;
#if (BUFFERSIZE > 255)
unsigned int li;
#else
unsigned char li;
#endif
TimerInit();
//usart_init(BAUD);
//spi_init();
//spi_init_s();
/*
while (0)
{
usart_tsmt(DF_read_reg());
//usart_tsmt(DF_read_reg_sspi());
//ispTransmit_sw(0x01);
_delay_ms(500);
static unsigned char flag=0;
if (flag)
{
flag=0;
DF_write_page(0);
for (i=0;i<256;i++)
{
buf[i]=0xaa;
}
//DF_write_page(0);
//DF_read_page(0);
for (i=0;i<256;i++)
{
usart_tsmt(buf[i]);
//_delay_ms(2);
}
}
}*/
// sendstr("");
// sendstr("等待联机密码...");
cnt = TimeOutCnt;
cl = 0;
while (1)
{
if (TIFR1 & (1<<OCF1A)) //T1溢出
{
TIFR1 |= (1 << OCF1A);
if (1)//cl == CONNECTCNT) //判断连接密码
break;
cnt--;
if (cnt == 0) //连接超时
{
sendstr(msg_timeout); //提示超时
//__asm__ __volatile__ ("nop");
_delay_ms(1);
(*((void(*)(void))(0x0000UL)))();//软件重启
}
}
if (UCSR0A & (1<<RXC0)) //接收到连接密码
{
if (UDR0 == ConnectKey[cl]) //比较密码
cl++;
else
cl = 0;
}
//usart_tsmt(usart_rcv());
//_delay_ms(1000);
}
sendstr("Connected...");
sendstr("Wait to receive...");
cnt = TimeOutCntC;
LED_2_OFF();
while (1)
{
if (TIFR1 & (1 << OCF1A)) //T1溢出
{
TIFR1 |= (1 << OCF1A);
usart_tsmt(XMODEM_RWC) ; //发送 "C"
/*
#if LED_En
LEDAlt(); //LED指示状态
#endif
*/
cnt--;
if (cnt == 0) //超时
{
sendstr("");
sendstr(msg_timeout); //提示超时
_delay_ms(1);
(*((void(*)(void))(0x0000UL)))();//软件重启
//quit(); //退出 bootloader
}
}
/*
#if WDG_En
wdt_reset(); //清除看门狗
#endif*/
if (UCSR0A & (1<<RXC0))
{
if (UDR0 == XMODEM_SOH) //XMODEM命令开始
break;
}
}
TCCR1B = 0; //关闭定时器1
//开始接受数据
packNO = 0;
bufptr = 0;
cnt = 0;
// FlashAddr = 0;
//-----------------------
do
{
static unsigned char led_flag=1;
if (led_flag)LED_1_ON();//点亮LED
else LED_1_OFF();
led_flag=!led_flag;
packNO++;
ch = usart_rcv(); //获取包序号
cl = ~usart_rcv();
if ((packNO == ch) && (packNO == cl))
{
for (li = BUFFERSIZE; li > 0; li--) //接收完整一帧数据
{
buf[bufptr++] = usart_rcv();
}
crch = usart_rcv(); //获取校验字节
crcl = usart_rcv();
crc16(&buf[bufptr - BUFFERSIZE]); //计算校验
if ((crch == ch) && (crcl == cl))
{
if (bufptr >= BUFSIZE) //缓冲区满,写入数据;否则继续接收
{ //接收多个帧,写入一页
//write_one_page(buf); //写入缓冲区内容到Flash中
DF_write_page(page_cnt++);
// FlashAddr += BUFSIZE; //修改Flash页地址
bufptr = 0;
for(int i2=0;i2<512;i2++)buf[i2]=0xff;
}
usart_tsmt(XMODEM_ACK); //不校验,直接发送正确响应
//usart_tsmt(XMODEM_NAK);
cnt = 0;
}
else //CRC
{
usart_tsmt(XMODEM_NAK); //要求重发数据
cnt++;
}
}
else //PackNo
{
usart_tsmt(XMODEM_NAK); //要求重发数据
cnt++;
}
if (cnt > 3) //连续出错次数太多,中止升级
break;
}
while (usart_rcv() != XMODEM_EOT);
if(bufptr>0&&bufptr<BUFSIZE)DF_write_page(page_cnt);//继续写未满DataFlash一页的数据
usart_tsmt(XMODEM_ACK);
page_cnt=0;//重置DataFlash页计数
sendstr("");
if (cnt==0)
{
sendstr("Done.");
LED_2_ON();
LED_1_OFF();
}
else
{
sendstr("Fail!");
LED_2_OFF();
LED_1_ON();
}
/* while (1)
{
if (usart_rcv()==0x64)
{
DF_read_page(0);
for (i=0;i<256;i++)
usart_tsmt(buf[i]);
}
}
*/
//------------------------
return 0;
}
/*
void xmodem_transmit(void)
{
eeprom_busy_wait();
unsigned char tmp=eeprom_read_byte(SIZE_ADDRESS+section*2);
unsigned char avr_page_size=2;
if (tmp<=5)avr_page_size=1;
if (tmp<=3)avr_page_size=0;
unsigned int flash_size=1;
for (unsigned char t1=0;t1<tmp+2;t1++)flash_size*=2;
//xmodem发送
unsigned char s1;
for(s1=0;s1<50;s1++)
{
usart_tsmt('c');
usart_tsmt('h');
usart_tsmt('e');
usart_tsmt('m');
usart_tsmt('y');
usart_tsmt('x');
_delay_ms(200);
if(xmodem_rcv==XMODEM_RWC||xmodem_rcv==XMODEM_NAK)break;
}
if(s1>=50)return;
keylock=1;
//cli();
LED_2_OFF();
UCSR0B&=~(1<<RXCIE0);
while(1)
{
tmp=usart_rcv();
if(tmp==XMODEM_RWC||tmp==XMODEM_NAK)break;
}
//usart_tsmt('C');
unsigned char packNo=0;
for (unsigned int i=0;i<flash_size;i++)
{
static unsigned char led_flag=1;
if (led_flag)
LED_1_ON();
else
LED_1_OFF();
led_flag=!led_flag;
//unsigned char ctrl_sign[5];
DF_read_page(i+section*512,0);
for (unsigned char part=0;part<2;)
{
crc16(&buf[part*128]);
usart_tsmt(XMODEM_SOH);
usart_tsmt(packNo);
usart_tsmt((unsigned char)~packNo);
for (unsigned char s1=0;s1<128;s1++)
{
usart_tsmt(buf[s1+part*128]);
//_delay_ms(10);
}
usart_tsmt(ch);
usart_tsmt(cl);
for(;;)
{
tmp=usart_rcv();
if (tmp==XMODEM_ACK)
{
packNo++;
part++;
break;
}
else if(tmp==XMODEM_NAK)
break;
else if(tmp==XMODEM_RWC)
{
packNo=0;
part=0;
break;
}
}
}
}
usart_tsmt(XMODEM_EOT);
LED_1_OFF();
error_flag=0;
LED_2_ON();
//sei();
keylock=0;
UCSR0B|=(1<<RXCIE0);
}
*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -