⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xmodem.c

📁 脱机ISP编程器
💻 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 + -