Easy-Downloader V2.0 for ATMEL 89C51/52/55 (sdcc version)
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2, or (at your option) any
later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
#include
#include
#define xon 0x11
#define xoff 0x13
int i;
unsigned char ACCU,temp,blank,chip,VPP;
char command;
unsigned int address,chksum;
char code title[] = "\n\r Easy-Downloader V2.0 for ATMEL 89C51/52/55 (sdcc version)";
char code prompt[] = "\n\r >";
char code ok[] = "\n\r ok";
unsigned int count,bytes,nonblank;
#define LM317 P3_5
#define LE P3_7
#define prog P2_7
#define Vpp P3_3
#define rdy P3_2
#define xtal P3_1
#define p26 P3_4
#define p27 P3_5
#define p36 P3_6
#define p37 P3_7
#define p10 P1_0
#define p11 P1_1
#define p12 P1_2
#define p13 P1_3
#define p14 P1_4
pulseProg()
{
prog = 0;
prog = 0;
prog = 0;
prog = 1;
}
time1ms() /* 1 ms delay with XTAL 11.0592MHz */
{
int i;
for (i = 0; i<50; i++) // the value shown in this line, 50 was calibrated for 1ms
; // you may change it!
}
delay(int n) /* do nothing n*1ms */
{
int i;
for (i=0; i< n ; i++)
time1ms();
}
delay10us()
{
int i;
for (i=0;i<1;i++);
}
char getchar(void)
{
char c;
while(!RI);
RI =0;
c = SBUF;
putchar(c); // echo to terminal
return SBUF;
}
char getchr(void)
{
while(!RI);
RI =0;
return SBUF; // no echo for command write
}
// external function for sending character through serial port
void putchar(char c)
{
while(!TI);
TI=0;
SBUF = c;
}
// send ASCII string to screen, the string must be stored in code memory
putstr(char *s)
{
char i=0;
char c;
while((c=*(s+(i++)))!= 0) putchar(c); // while byte is not terminator, keep sending
}
sendprompt()
{
putstr(prompt);
}
prompting()
{
if (command == 0x0d) // send title and prompt when get ENTER key
{
putstr(title);
sendprompt();
}
}
// need flow control with host pc
unsigned int getnum()
{
char s[6];
char c;
char i;
unsigned int temp16;
c = 0;
i=0;
for (i = 0; c != 0xa; i++) // loop until CR has entered
{
putchar(xon); // send xon to signal host to send byte
c = getchar(); // get character from serial port
if(c == 0xd) c=0xa; // convert CR to LF to make it compatible with ez31 and ez41
s[i] = c; // save character to array
}
s[i-1] = 0; // put terminator at the end of string
// convert ascii to integer (atoi(s))
temp16 = 0;
for(i=0; s[i] != 0; i++) temp16 = 10*temp16 + s[i]-'0';
return temp16; // return 16-bit for number of byte counting
}
getcommand()
{
if (RI) command = getchar(); //
else command = -1; /* no cammand has entered */
}
putok()
{
putstr(ok);
sendprompt();
}
send_hex(unsigned char n)
{
if(n<=9) putchar(n+'0'); // send 0-9
else putchar(n+55); // send A-F
}
puthex(unsigned char n)
{
unsigned char temp;
temp = n&0xf0;
temp >>=4;
send_hex(temp);
temp = n&0xf;
send_hex(temp);
}
puthex16(unsigned int n)
{
puthex(n>>8);
puthex(n);
}
putnum(unsigned int n)
{
unsigned int k;
char s[6];
s[0] = n/10000+'0';
k = n%10000;
s[1] = k/1000+'0';
k = k%1000;
s[2] = k/100+'0';
k = k%100;
s[3] = k/10+'0';
k = k%10;
s[4] = k%10+'0';
for(k = 0; s[k] == '0' && k<5; k++);
if (k==5) k--; // if all bytes are '0', get back one position
do putchar(s[k++]);
while (k<5);
}
getconsole()
{
if (RI) command = getchr();
else command = -1;
}
chkXOFF() /* use XON and XOFF for controlling flow with host */
{
if(getconsole() == xoff)
{
do;
while(getconsole() != xon);
}
}
erase()
{
if (command == 'e')
{
Vpp = 1;
p26 = 1;
p27 = 0;
p36 = 0;
p37 = 0;
delay10us();
Vpp = 0;
delay(100);
for (i=0; i < 1; i++) /* erase entire PEROM array (2kB) */
{
prog = 0;
delay(10); /* 10 ms prog pulse */
prog = 1;
delay(10);
}
Vpp = 1;
delay(100);
putok();
}
}
write() /* call sequence before write: 's', 't','e','w' */
{
if (command == 'w')
{
Vpp = 1;
p26 = 0;
p27 = 1;
p36 = 1;
p37 = 1;
prog = 1;
delay10us();
if (VPP == 0xff) /* skip if VPP != 0xff,i.e., need 5Vpp for programming */
Vpp = 0;
delay(100); /* raise programming voltage to 12V */
chksum = 0;
for (i = 0; i < count; i++)
{ /* use XON & XOFF flow control */
putchar(xon); /* send XON */
address = i;
P1 = address;
P2 = (address>>8)
0x80;
delay10us();
P0 = getchr(); /* read raw bytes from console */
putchar(xoff); /* send XOFF */
chksum += P0; /* summing chksum */
pulseProg();
while(!rdy)
; // wait until ready
}
Vpp = 1; /* bring Vpp back to 5V */
delay(100);
putok();
}
}
read() /* read ACCUording to number of bytes by 'c' command */
{
unsigned int i;
if (command=='r')
{
chksum = 0; /* reset check sum word */
Vpp = 1;
prog = 1;
p26 = 0;
p27 = 1;
p36 = 1;
p37 = 1;
blank = '1';
for(i = 0; i < count; i++)
{
address = i;
P1 = address;
P2 = (address>>8)
0x80;
p27 = 0;
delay10us();
P0 = 0xff;
chksum += P0;
puthex(P0); /* read in HEX */
p27 = 1;
chkXOFF();
}
putok();
}
}
blanktest() /* if all bytes are 0FFH then blank =FF, else blank = 0 */
{
if (P0 != 0xff)
{ blank = '0'; /* full */
nonblank++;
}
}
lock() /* only protection mode 4 can be programmed,i.e., disabled further
program, verify, and external execution */
{
if (command == 'l')
{
Vpp = 0;
prog = 1;
p26 = p27 = p36 = p37 = 1;
delay(100);
pulseProg();
delay(5);
p36 = p37 = 0;
delay10us();
pulseProg();
delay(5);
p27 = 0;
p36 = 1;
p37 = 0;
delay10us();
pulseProg();
delay(5);
putok();
}
}
printchksum()
{
if (command == 'c')
{
putstr("\n\r CHKSUM = "); puthex16(~chksum+1);
putok();
}
}
signature() /* read signature ATMEL chip 51/52/55 12V or 5V Vpp */
{
Vpp = prog = 1;
p26 = 0;
p27 = 1;
p36 = p37 = 0;
address = 0x31;
P1 = address;
P2 = (address>>8)
0x80;
p27 = 0;
delay10us();
P0 = 0xff;
chip = P0;
p27 = 1;
address++;
P1 = address;
P2 = (address>>8)
0x80;
p27 = 0;
delay10us();
P0 = 0xff; /* put FF before read back */
VPP = P0; /* save Vpp 12V (FF) or 5V (5) into VPP */
}
testblank() /* need to call signature function pior calling testblank */
{
unsigned int i;
signature();
switch(chip){
case (0x51): /* 89C51 */
bytes = 4096; /* if chip == 0x51 or 0x61 then bytes = 4kB */
break;
case (0x61): /* 89LV51 */
bytes = 4096;
break;
case (0x52): /* 89C52 */
bytes = 8192; /* if chip == 0x52 or 0x62 then bytes = 8kB */
break;
case (0x62): /* 89LV52 */
bytes = 8192;
break;
case (0x55): /* 89C55 */
bytes = 20480; /* if chip == 0x55 or 0x65 then bytes = 20kB */
break;
case (0x65): /* 89LV55 */
bytes = 20480;
break;
case 0xff:
bytes = 0;
}
chksum = 0; /* reset check sum word */
nonblank = 0; /* reset nonblank bytes counter */
Vpp = prog = 1;
p26 = 0;
p27 = p36 = p37 =1;
blank = '1';
for(i = 0; i < bytes; i++)
{
address = i;
P1 = address;
P2 = (address>>8)
0x80;
p27 = 0;
delay10us();
P0 = 0xff; /* put FF before read back */
chksum += P0;
blanktest();
p27 = 1; /* next address */
}
}
setcounter()
{
if (command == 's')
{
count = getnum();
putok();
}
}
getinfo()
{
if (command =='g')
{
testblank();
if(chip!=0xff)
{
putstr("\n\r found 89C");
puthex(chip);
if (VPP==0xff)
putstr("-12V");
if (VPP==5)
putstr("-5V");
putstr("\n\r nonblank ");
putnum(nonblank);
putstr(" bytes");
putstr("\n\r bytes counter ");
putnum(count);
}
else(putstr("\n\r Not found 89Cxx"));
putok();
}
}
PGMparameters() /* for simple host interfacing */
{
if (command=='p')
{
testblank();
puthex(chip);
putchar(',');
putnum(nonblank);
putchar(',');
putnum(count); // use getnum instead of printf_fast to reduce size
//printf_fast("%x,%u,%u",chip,nonblank,count);
putok();
}
}
void main(void)
{
i=0;
count =0;
SCON = 0x52; // 8-bit UART mode
TMOD = 0x20; // timer 1 mode 2 auto reload
TH1= 0xfd; // 9600 8n1
TR1 = 1; // run timer1
getchar();
putstr(title);
sendprompt();
while(1)
{
getcommand();
prompting();
setcounter();
erase();
write();
read();
lock();
printchksum();
getinfo();
PGMparameters();
}
}
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2, or (at your option) any
later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
#include
#include
#define xon 0x11
#define xoff 0x13
int i;
unsigned char ACCU,temp,blank,chip,VPP;
char command;
unsigned int address,chksum;
char code title[] = "\n\r Easy-Downloader V2.0 for ATMEL 89C51/52/55 (sdcc version)";
char code prompt[] = "\n\r >";
char code ok[] = "\n\r ok";
unsigned int count,bytes,nonblank;
#define LM317 P3_5
#define LE P3_7
#define prog P2_7
#define Vpp P3_3
#define rdy P3_2
#define xtal P3_1
#define p26 P3_4
#define p27 P3_5
#define p36 P3_6
#define p37 P3_7
#define p10 P1_0
#define p11 P1_1
#define p12 P1_2
#define p13 P1_3
#define p14 P1_4
pulseProg()
{
prog = 0;
prog = 0;
prog = 0;
prog = 1;
}
time1ms() /* 1 ms delay with XTAL 11.0592MHz */
{
int i;
for (i = 0; i<50; i++) // the value shown in this line, 50 was calibrated for 1ms
; // you may change it!
}
delay(int n) /* do nothing n*1ms */
{
int i;
for (i=0; i< n ; i++)
time1ms();
}
delay10us()
{
int i;
for (i=0;i<1;i++);
}
char getchar(void)
{
char c;
while(!RI);
RI =0;
c = SBUF;
putchar(c); // echo to terminal
return SBUF;
}
char getchr(void)
{
while(!RI);
RI =0;
return SBUF; // no echo for command write
}
// external function for sending character through serial port
void putchar(char c)
{
while(!TI);
TI=0;
SBUF = c;
}
// send ASCII string to screen, the string must be stored in code memory
putstr(char *s)
{
char i=0;
char c;
while((c=*(s+(i++)))!= 0) putchar(c); // while byte is not terminator, keep sending
}
sendprompt()
{
putstr(prompt);
}
prompting()
{
if (command == 0x0d) // send title and prompt when get ENTER key
{
putstr(title);
sendprompt();
}
}
// need flow control with host pc
unsigned int getnum()
{
char s[6];
char c;
char i;
unsigned int temp16;
c = 0;
i=0;
for (i = 0; c != 0xa; i++) // loop until CR has entered
{
putchar(xon); // send xon to signal host to send byte
c = getchar(); // get character from serial port
if(c == 0xd) c=0xa; // convert CR to LF to make it compatible with ez31 and ez41
s[i] = c; // save character to array
}
s[i-1] = 0; // put terminator at the end of string
// convert ascii to integer (atoi(s))
temp16 = 0;
for(i=0; s[i] != 0; i++) temp16 = 10*temp16 + s[i]-'0';
return temp16; // return 16-bit for number of byte counting
}
getcommand()
{
if (RI) command = getchar(); //
else command = -1; /* no cammand has entered */
}
putok()
{
putstr(ok);
sendprompt();
}
send_hex(unsigned char n)
{
if(n<=9) putchar(n+'0'); // send 0-9
else putchar(n+55); // send A-F
}
puthex(unsigned char n)
{
unsigned char temp;
temp = n&0xf0;
temp >>=4;
send_hex(temp);
temp = n&0xf;
send_hex(temp);
}
puthex16(unsigned int n)
{
puthex(n>>8);
puthex(n);
}
putnum(unsigned int n)
{
unsigned int k;
char s[6];
s[0] = n/10000+'0';
k = n%10000;
s[1] = k/1000+'0';
k = k%1000;
s[2] = k/100+'0';
k = k%100;
s[3] = k/10+'0';
k = k%10;
s[4] = k%10+'0';
for(k = 0; s[k] == '0' && k<5; k++);
if (k==5) k--; // if all bytes are '0', get back one position
do putchar(s[k++]);
while (k<5);
}
getconsole()
{
if (RI) command = getchr();
else command = -1;
}
chkXOFF() /* use XON and XOFF for controlling flow with host */
{
if(getconsole() == xoff)
{
do;
while(getconsole() != xon);
}
}
erase()
{
if (command == 'e')
{
Vpp = 1;
p26 = 1;
p27 = 0;
p36 = 0;
p37 = 0;
delay10us();
Vpp = 0;
delay(100);
for (i=0; i < 1; i++) /* erase entire PEROM array (2kB) */
{
prog = 0;
delay(10); /* 10 ms prog pulse */
prog = 1;
delay(10);
}
Vpp = 1;
delay(100);
putok();
}
}
write() /* call sequence before write: 's', 't','e','w' */
{
if (command == 'w')
{
Vpp = 1;
p26 = 0;
p27 = 1;
p36 = 1;
p37 = 1;
prog = 1;
delay10us();
if (VPP == 0xff) /* skip if VPP != 0xff,i.e., need 5Vpp for programming */
Vpp = 0;
delay(100); /* raise programming voltage to 12V */
chksum = 0;
for (i = 0; i < count; i++)
{ /* use XON & XOFF flow control */
putchar(xon); /* send XON */
address = i;
P1 = address;
P2 = (address>>8)
0x80;
delay10us();
P0 = getchr(); /* read raw bytes from console */
putchar(xoff); /* send XOFF */
chksum += P0; /* summing chksum */
pulseProg();
while(!rdy)
; // wait until ready
}
Vpp = 1; /* bring Vpp back to 5V */
delay(100);
putok();
}
}
read() /* read ACCUording to number of bytes by 'c' command */
{
unsigned int i;
if (command=='r')
{
chksum = 0; /* reset check sum word */
Vpp = 1;
prog = 1;
p26 = 0;
p27 = 1;
p36 = 1;
p37 = 1;
blank = '1';
for(i = 0; i < count; i++)
{
address = i;
P1 = address;
P2 = (address>>8)
0x80;
p27 = 0;
delay10us();
P0 = 0xff;
chksum += P0;
puthex(P0); /* read in HEX */
p27 = 1;
chkXOFF();
}
putok();
}
}
blanktest() /* if all bytes are 0FFH then blank =FF, else blank = 0 */
{
if (P0 != 0xff)
{ blank = '0'; /* full */
nonblank++;
}
}
lock() /* only protection mode 4 can be programmed,i.e., disabled further
program, verify, and external execution */
{
if (command == 'l')
{
Vpp = 0;
prog = 1;
p26 = p27 = p36 = p37 = 1;
delay(100);
pulseProg();
delay(5);
p36 = p37 = 0;
delay10us();
pulseProg();
delay(5);
p27 = 0;
p36 = 1;
p37 = 0;
delay10us();
pulseProg();
delay(5);
putok();
}
}
printchksum()
{
if (command == 'c')
{
putstr("\n\r CHKSUM = "); puthex16(~chksum+1);
putok();
}
}
signature() /* read signature ATMEL chip 51/52/55 12V or 5V Vpp */
{
Vpp = prog = 1;
p26 = 0;
p27 = 1;
p36 = p37 = 0;
address = 0x31;
P1 = address;
P2 = (address>>8)
0x80;
p27 = 0;
delay10us();
P0 = 0xff;
chip = P0;
p27 = 1;
address++;
P1 = address;
P2 = (address>>8)
0x80;
p27 = 0;
delay10us();
P0 = 0xff; /* put FF before read back */
VPP = P0; /* save Vpp 12V (FF) or 5V (5) into VPP */
}
testblank() /* need to call signature function pior calling testblank */
{
unsigned int i;
signature();
switch(chip){
case (0x51): /* 89C51 */
bytes = 4096; /* if chip == 0x51 or 0x61 then bytes = 4kB */
break;
case (0x61): /* 89LV51 */
bytes = 4096;
break;
case (0x52): /* 89C52 */
bytes = 8192; /* if chip == 0x52 or 0x62 then bytes = 8kB */
break;
case (0x62): /* 89LV52 */
bytes = 8192;
break;
case (0x55): /* 89C55 */
bytes = 20480; /* if chip == 0x55 or 0x65 then bytes = 20kB */
break;
case (0x65): /* 89LV55 */
bytes = 20480;
break;
case 0xff:
bytes = 0;
}
chksum = 0; /* reset check sum word */
nonblank = 0; /* reset nonblank bytes counter */
Vpp = prog = 1;
p26 = 0;
p27 = p36 = p37 =1;
blank = '1';
for(i = 0; i < bytes; i++)
{
address = i;
P1 = address;
P2 = (address>>8)
0x80;
p27 = 0;
delay10us();
P0 = 0xff; /* put FF before read back */
chksum += P0;
blanktest();
p27 = 1; /* next address */
}
}
setcounter()
{
if (command == 's')
{
count = getnum();
putok();
}
}
getinfo()
{
if (command =='g')
{
testblank();
if(chip!=0xff)
{
putstr("\n\r found 89C");
puthex(chip);
if (VPP==0xff)
putstr("-12V");
if (VPP==5)
putstr("-5V");
putstr("\n\r nonblank ");
putnum(nonblank);
putstr(" bytes");
putstr("\n\r bytes counter ");
putnum(count);
}
else(putstr("\n\r Not found 89Cxx"));
putok();
}
}
PGMparameters() /* for simple host interfacing */
{
if (command=='p')
{
testblank();
puthex(chip);
putchar(',');
putnum(nonblank);
putchar(',');
putnum(count); // use getnum instead of printf_fast to reduce size
//printf_fast("%x,%u,%u",chip,nonblank,count);
putok();
}
}
void main(void)
{
i=0;
count =0;
SCON = 0x52; // 8-bit UART mode
TMOD = 0x20; // timer 1 mode 2 auto reload
TH1= 0xfd; // 9600 8n1
TR1 = 1; // run timer1
getchar();
putstr(title);
sendprompt();
while(1)
{
getcommand();
prompting();
setcounter();
erase();
write();
read();
lock();
printchksum();
getinfo();
PGMparameters();
}
}
Komentar
Posting Komentar