📄 ldrom4k.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 + -