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

📄 ldrom4k.c

📁 W78E516B在线升级的下位机源代码
💻 C
字号:
//////////////////////////////////////////////////////////////////////////////////
//  																			//
// File Name :	W78E516ISP.C													//
//  																			//
// Function  :	in-system program for W78E516   								//
//  			Download file (*.hex|*.bin) to uC  using RS232  				//
//  																			//
// MCU  	 :	winbond W78E516B												//
//  																			//
// ROM & RAM :  64Kx8Bit(APROM) 4Kx8Bit(LDROM)  512x8Bit						//
//  																			//
// Crystal   :  40MHz(Max)  													//
//  																			//
// Date(Star):  2003/12/01  													//
//  																			//
// Author    :	Kong Quan   													//
//  																			//
//////////////////////////////////////////////////////////////////////////////////

/*
** Structure
**  -------------------------------------------------------------
** | STX | #BYTE | CMD | ADR_High | ADR_Low | #DATA | DATA | LRC |
** |-----|-------|-----|----------|---------|-------|------|-----|
** |	 |  	 |     |	1)    |   1)	|   2)  |  2)  |	 |
**  -------------------------------------------------------------
**  	1) optional fields(1 byte)
**  	2) optional fields(variable length)
*/

/* 使用方法
** 1. 根据实际需要设置波特率
** 2. 编译后,把文件烧录到W78E516的LDROM(10000H--10FFFH)
** 3. 在F4KBOOT Mode 下, 使用上位机软件W78E516ISP.EXE可以擦除,烧录,读出APROM的代码
*/


//#pragma SRC

//define compiler condition
//#define BRG1
//#define BOARD_1

#define uchar	unsigned char
#define uint	unsigned int
#define TRUE	1
#define FALSE	0

//define constant
#ifdef BOARD_1
#define FOSC	11059200
#else
#define FOSC	24000000
#endif

#include "W78E516B.H"
#include "LDROM4K.H"

#include <intrins.h>
#include <string.h>

//project information
uchar code	Project[] = "W78E516ISP V1.0";
uchar code	Copyright[] = "KongQuan 2003 XiongDi.,LTD.";
uchar code	ReleaseDate[] = __DATE__;

//configure baud rate
#define BAUDRATE	B57600

/****************************************************************************
**  																		*
* Function: 	main program												*
**  																		*
****************************************************************************/
void main(void)
{
	InitSys();

	// write enable
	CHPENR = 0x87;
	CHPENR = 0x59;

	if (CHPCON & 0x80)		//  check F04KBOOT mode
	{
		CHPCON = 0x03;		// enable ISP mode
		CHPENR = 0x00;		// disable CHPCON write attribute

		TR0 = 0;			// timer0 stop
		//TL0 = TM0L = 0xF0;
		//TH0 = TM0H = 0xFF;
		TL0 = TM0L = (-(uint) D1p5us) % 256;	// set timer0 for read operation, about 1.5us
		TH0 = TM0H = (-(uint) D1p5us) / 256;	// depending on user's system clock rate
		TF0 = 0;
		TR0 = 1;			// timer0 start
		PCON |= 0x01;		// enter idle mode
	}
	CHPENR = 0x00;			// disable CHPCON write attribute

	RevData = 0;
	t_empty = 1;

	SendByte(ACK);			//ASK when JMP TO LDROM FROM APROM

	RedLed = 0;
	GreenLed = 0;

	while (1)
	{
		if (RevData)
		{
			RevData = 0;
			if (r_in == STX)
			{
				RevRS232();
				if (!RevErr)
				{
					CommandExe();
				}
				else
				{
					SendByte(RERR);
				}
			}
		}
	}
}

/****************************************************************************
**  																		*
* Function: 	initialization system   									*
**  																		*
****************************************************************************/
void InitSys(void)
{
	//initialize port
	P0 = 0xFF;
	P1 = 0xFF;
	P2 = 0xFF;
	P3 = 0xFF;
	//enable on-chip XRAM
	CHPENR = 0x87;
	CHPENR = 0x59;
	CHPCON |= 0x10;
	CHPENR = 0x00;
	//set timer 0&1
	TMOD = 0x11;		//16bit timer
	//set timer2
	T2MOD = 0x00;
	T2CON = 0x30;		//baud rate generator
	//set serial port
	RCAP2L = BAUDRATE % 256;
	RCAP2H = BAUDRATE / 256;
	PCON = 0x00;		//not double baud rate
	SCON = 0x50;		//UART: mode1, enable receive
	//initialize parameter
	r_in = 0;
	RevData = 0;
	t_empty = 0;
	t_done = 1;
	//set interrupt
	TCON = 0x00;
	IP = 0x00;
	IE = 0x92;			//UART & TIMER0 interrupt enable
	TR2 = 1;			//start timer2
}

/****************************************************************************
**  																		*
* Function: 	erase 64K APROM 											*
**  																		*
****************************************************************************/
uchar EraseAprom(void)
{
	TR0 = 0;
	TL0 = TM0L = (-(uint) D15ms) % 256;	// set wake-up timer for erase operation, about 15ms
	TH0 = TM0H = (-(uint) D15ms) / 256;	// depending on user's system clock rate
	SFRCN = 0x22;						// erase 64K
	TF0 = 0;
	TR0 = 1;							// timer0 start
	PCON |= 0x01;						// enter idle mode

	return ACK;

	// blank check
	return BlankCheck();
}

/****************************************************************************
**  																		*
* Function: 	 64K APROM blank check  									*
**  																		*
****************************************************************************/
uchar BlankCheck(void)
{
	t_buf[0] = STX;
	t_buf[1] = 0x05;
	t_buf[2] = BLANKCHK;
	t_buf[3] = 0x00;
	t_buf[4] = 0x00;
	t_buf[5] = ACK;
	t_buf[7] = ETX;
	t_in = 8;

	TR0 = 0;
	SFRCN = 0x00;						// read 64KB APROM mode
	SFRAH = 0x00;						// start address = 0000H
	SFRAL = 0x00;
	TL0 = TM0L = (-(uint) D1p5us) % 256;	// set timer0 for read operation, about 1.5us
	TH0 = TM0H = (-(uint) D1p5us) / 256;	// depending on user's system clock rate

	while (1)
	{
		TR0 = 1;
		PCON |= 0x01;
		if (SFRFD != 0xFF)
		{
			t_buf[3] = SFRAH;
			t_buf[4] = SFRAL;
			t_buf[5] = NACK;
			t_buf[6] = CalBCC(t_buf + 1);
			SendMsg();
			return NACK;
		}

		if (++SFRAL == 0)
		{
			t_buf[3] = SFRAH;
			t_buf[4] = SFRAL - 1;
			t_buf[6] = CalBCC(t_buf + 1);
			SendMsg();
			if (++SFRAH == 0)
			{
				break;
			}
		}
	}

	return	ACK;
}

/****************************************************************************
**  																		*
* Function: 	Program 64K APROM   										*
**  																		*
****************************************************************************/
uchar PrgAprom(void)
{
	uchar			counter_err;
	uchar idata	   *p1;
	uchar			i,length;

	TR0 = 0;							//stop TM0

	length = r_buf[0] - 4;

	for (counter_err = 0; counter_err < 3; counter_err++)
	{
		SFRCN = 0x21;						// program 64KB APROM mode
		SFRAH = r_buf[2];					// get start address
		SFRAL = r_buf[3];
		TL0 = TM0L = (-(uint) D50us) % 256;	// set timer0 for program operation, about 50us
		TH0 = TM0H = (-(uint) D50us) / 256;	// depending on user's system clock rate
		p1 = &r_buf[4];
		for (i = 0; i < length; i++)		//program start
		{
			SFRFD = *p1++;
			TR0 = 1;
			PCON |= 0x01;

			if (++SFRAL == 0)
			{
				SFRAH++;
			}
		}

		SFRCN = 0x00;						// read 64KB APROM mode
		SFRAH = r_buf[2];					// get start address
		SFRAL = r_buf[3];
		TL0 = TM0L = (-(uint) D1p5us) % 256;	// set timer0 for read operation, about 1.5us
		TH0 = TM0H = (-(uint) D1p5us) / 256;	// depending on user's system clock rate
		p1 = t_buf;
		for (i = 0; i < length; i++)
		{
			TR0 = 1;
			PCON |= 0x01;
			*p1++ = SFRFD;

			if (++SFRAL == 0)
			{
				SFRAH++;
			}
		}
		if (memcmp(&r_buf[4], t_buf, length) == 0)
		{
			return ACK;
		}
	}
	return NACK;
}

/*------------------------------------------------
receive data from UART
------------------------------------------------*/
void RevRS232(void)
{
	uchar	i;
	RevErr = 0;
	r_end = 0;
	r_cnt = 0;
	ET0 = 0;
	TL0 = 0;
	TH0 = 0;
	TR0 = 1;
	for (i = 0; i < 3; i++)
	{
		TF0 = 0;
		while (!TF0)
		{
			if (RevData)
			{
				RevData = 0;
				r_buf[r_cnt++] = r_in;
				if ((r_buf[0] == 0) || (r_buf[0] > 39))
				{
					RevErr = 1;
					break;
				}
				if (r_buf[0] == r_cnt - 1)
				{
					TR0 = 0;
					TL0 = 0;
					TH0 = 0x80;
					TF0 = 0;
					TR0 = 1;		//reset timer0
					RevErr = 0;
					r_end = 1;
					break;
				}
			}
		}
		if (RevErr || r_end)
		{
			break;
		}
	}
	if (r_end)
	{
		while (!TF0)
		{
			if (RevData)
			{
				if (r_in != ETX)
				{
					RevErr = 1;
				}
				break;
			}
		}
	}
	//stop timer
	TR0 = 0;
	ET0 = 1;
	RevData = 0;
	if (!RevErr)
	{
		if (CalBCC(r_buf) != r_buf[r_buf[0]])
		{
			RevErr = 1;
		}
	}
}

/*------------------------------------------------
calculate BCC
------------------------------------------------*/
uchar CalBCC(uchar idata *s1)
{
	uchar	len = *s1;
	uchar	BCC = 0x00;
	uchar	i;
	for (i = 0; i < len; i++)
	{
		BCC ^= *s1++;
	}

	return ~BCC;
}

/*------------------------------------------------
send message
------------------------------------------------*/
void SendMsg(void)
{
	t_out = 0;
	t_empty = 0;
	t_done = 0;
	TI = 1;				//start send
	while (!t_done);		// wait send complete
}

/*------------------------------------------------
execute command
------------------------------------------------*/
uchar CommandExe(void)
{
	uchar	status = ACK;
	switch (command)
	{
			//check connect
		case CONNECT:
			{
				if (memcmp(&object, Copyright, sizeof(Copyright) - 1) == 0)
				{
					m_bConnect = TRUE;
					status = ACK;
				}
				else
				{
					m_bConnect = FALSE;
					status = NACK;
				}
				break;
			}
			//bland check
		case BLANKCHK:
			{
				status = BlankCheck();
				break;
			}
			//erase 64K APROM
		case ERASE:
			{
				status = EraseAprom();
				break;
			}
			//in-system program
		case PROGRAM:
			{
				status = PrgAprom();
				break;
			}
		case EPV:
			{
				break;
			}
			//exit ISP mode
		case EXIT:
			{
				SendByte(ACK);		// send ACK to HOST

				CHPENR = 0x87;
				CHPENR = 0x59;
				CHPCON = 0x83;
				CHPENR = 0x00;

				TR0 = 0;			// timer0 stop
				//TL0 = TM0L = 0xF0;
				//TH0 = TM0H = 0xFF;
				TL0 = TM0L = (-(uint) D1p5us) % 256;	// set timer0 for read operation, about 1.5us
				TH0 = TM0H = (-(uint) D1p5us) / 256;	// depending on user's system clock rate
				TF0 = 0;
				TR0 = 1;			// timer0 start
				PCON |= 0x01;		// enter idle mode for launching APROM
				break;
			}
			//get system information
		case GETVERSION:
			{
				t_buf[0] = STX;
				t_buf[1] = sizeof(Project) + 1;
				t_buf[2] = GETVERSION;
				t_in = sizeof(Project) + 4;
				memcpy(t_buf + 3, Project, sizeof(Project));
				t_buf[sizeof(Project) + 2] = CalBCC(t_buf + 1);
				t_buf[sizeof(Project) + 3] = ETX;
				SendMsg();
				break;
			}
		case READ:
			{
				ReadAPROM();
				break;
			}
		default:
			{
				SendByte(NACK);
				status = NACK;
				break;
			}
	}

	SendByte(status);
	return status;
}

/****************************************************************************
**  																		*
* Function: 	ask data function register  								*
**  																		*
****************************************************************************/
void SendByte(uchar ch)
{
	t_buf[0] = ch;
	t_in = 1;
	SendMsg();
}

/****************************************************************************
**  																		*
* Function: 	read APROM  												*
**  																		*
****************************************************************************/
void ReadAPROM(void)
{
	uchar idata	   *p1;
	uchar			counter_err;

	TR0 = 0;							//stop TM0
	SFRCN = 0x00;						// read 64KB APROM mode
	SFRAH = 0x00;						// start address = 0000H
	SFRAL = 0x00;
	TL0 = TM0L = (-(uint) D1p5us) % 256;	// set timer0 for read operation, about 1.5us
	TH0 = TM0H = (-(uint) D1p5us) / 256;	// depending on user's system clock rate

	t_buf[0] = STX;
	t_buf[1] = 36;						//cmd(1)+ADDR(2)+DATA(32)+LRC(1)
	t_buf[2] = READ;
	t_buf[38] = ETX;
	t_in = 39;

	p1 = t_buf + 3;
	*p1++ = SFRAH;
	*p1++ = SFRAL;

	while (1)
	{
		TR0 = 1;
		PCON |= 0x01;
		*p1++ = SFRFD;

		if (++SFRAL == 0)
		{
			SFRAH++;
		}

		if ((SFRAL & 0x1F) == 0)
		{
			*p1 = CalBCC(t_buf + 1);
			for (counter_err = 0; counter_err < 3; counter_err++)
			{
				RevData = 0;
				SendMsg();
				TM1_Delay10ms(100);
				while (!TM1_TimeUp)		//wait ACK
				{
					if (RevData)
					{
						break;
					}
				}
				if (RevData && (r_in == ACK))
				{
					break;
				}
			}//end for

			if (!RevData)
			{
				break;
			}		//lose connect
			p1 = t_buf + 3;
			*p1++ = SFRAH;
			*p1++ = SFRAL;
		}

		if ((SFRAL | SFRAH) == 0)
		{
			break;
		}
	}//end while
	RevData = 0;
}

/****************************************************************************
**  																		*
* Function: 	set special function register   							*
**  																		*
****************************************************************************/
void TM1_Delay10ms(uchar _10ms)
{
	DelayWait = _10ms;
	TR1 = 0;
	TL1 = TM1L = (-(uint) D_10ms) % 256;
	TH1 = TM1H = (-(uint) D_10ms) / 256;
	TM1_TimeUp = 0;
	TF1 = 0;
	TR1 = 1;			//start timer2
	ET1 = 1;			//timer2 interrupt enable
}

/*------------------------------------------------
Extral0 interrupt
------------------------------------------------*/
void ext_int0(void) interrupt 0
{
}

/*------------------------------------------------
Timer0 interrupt
------------------------------------------------*/
void timer0(void) interrupt 1
{
	TR0 = 0;
	TL0 = TM0L;
	TH0 = TM0H;
}

/*------------------------------------------------
Extral1 interrupt
------------------------------------------------*/
void ext_int1(void) interrupt 2
{
}

/*------------------------------------------------
Timer1 interrupt
------------------------------------------------*/
void timer1(void) interrupt 3
{
	TL1 = TM1L;
	TH1 = TM1H;		//reload value
	if (DelayWait != 0)
	{
		if (--DelayWait == 0)
		{
			TR1 = 0;
			ET1 = 0;
			TM1_TimeUp = 1;
		}
	}
}

/*------------------------------------------------
Serial interrupt
------------------------------------------------*/
void serial(void) interrupt 4
{
	if (RI)
	{
		r_in = SBUF;
		RI = 0;
		RevData = 1;
	}
	else
	{
		TI = 0;
		if (!t_empty)
		{
			SBUF = t_buf[t_out++];
			if (t_out >= t_in)
			{
				t_empty = 1;
			}
		}
		else
		{
			t_done = 1;
		}
	}
}

/*------------------------------------------------
Timer2 interrupt
------------------------------------------------*/
void timer2(void) interrupt 5
{
	TF2 = 0;			//must clear by soft
}

/*------------------------------------------------
Extral2 interrupt
------------------------------------------------*/
void ext_int2(void) interrupt 6
{
}

/*------------------------------------------------
Extral3 interrupt
------------------------------------------------*/
void ext_int3(void) interrupt 7
{
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -