/*
Easy-Downloader V1.3 for ATMEL 89C2051/4051 (sdcc version)
Copyright(c) 2004 Wichit Sirichote, kswichit@kmitl.ac.th, January 02, 2004
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
#define LM317 P3_5
#define LE P3_7
#define prog P3_2
#define rdy P3_3
#define xtal P3_4
#define p10 P1_0
#define p11 P1_1
#define p12 P1_2
#define p13 P1_3
#define p14 P1_4
int i;
unsigned char ACCU,temp;
char command;
char code title[] = "\n\r Easy-Downloader V1.3 for ATMEL 89C2051/4051 (sdcc version)";
char code prompt[] = "\n\r >";
char code ok[] = "\n\r ok";
int count;
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();
}
pulseLE()
{
delay(1);
LE =1;
delay(1);
LE=0;
delay(1);
}
initpowerup()
{
prog = 0;
xtal = 0;
LM317 = 1;
p14 = 1;
rdy = 1;
pulseLE();
delay(100);
prog = 1;
p14 = 0;
LM317 = 1;
pulseLE();
delay(100);
}
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();
}
putHEX(unsigned char ACCU)
{
if (ACCU > 9) putchar(ACCU+55); // convert to ASCII for A-F
else putchar(ACCU+48); // and for ASCII 0-9
}
printA()
{
ACCU = P1; // read byte from target
ACCU >>= 4; // shift right 4 bits
putHEX(ACCU); // send 4-bit high nibble
ACCU = P1&0xf; // get low nibble
putHEX(ACCU); // send low nibble
}
erase()
{
if (command == 'e')
{
p12 =1;
p11=p10=0;
pulseLE();
p14 = 0;
LM317 = 0;
pulseLE();
delay(100); // raise program supply up to 12V
for (i=0; i < 10; i++) // erase entire PEROM array (2kB)
{
prog = 0;
delay(10); /* 10 ms prog pulse */
prog=1;
delay(1);
}
initpowerup(); /* reset internal address counter to 000h */
putok();
}
}
write()
{
if (command == 'w')
{
p12=0;
p11=1;
p10=1;
pulseLE();
p14 =0;
LM317 = 0;
pulseLE();
delay(100); /* rise supply up 12V */
for (i = 0; i < count; i++)
{ /* use XON & XOFF flow control */
putchar(xon); /* send XON */
P1 = getchr();
putchar(xoff); /* send XOFF */
pulseProg();
while(!rdy) // wait until ready pin = '1'
;
xtal = 1; // next address
delay(1);
xtal = 0;
}
LM317 = 1;
p14 = 1;
pulseLE();
putok();
}
}
read() /* read code with the number of bytes set by 's' command */
{
if (command=='r')
{
initpowerup();
prog =0;
p12 =0;
p11 = 0;
p10 =1;
pulseLE();
for(i = 0; i < count; i++)
{
prog =1;
P1 = 0xff;
delay(1);
printA(); /* read in HEX */
xtal = 1;
delay(1);
xtal = 0;
}
putok();
}
}
lock() /* only protection mode 3,i.e., disabled further
program and verify, can be programmed */
{
if (command == 'l')
{
P1 = 0x07;
pulseLE();
LM317 = 0;
delay(100);
pulseProg();
P1 = 0x06;
pulseLE();
pulseProg();
p14 = 1;
LM317 = 1;
pulseLE();
putok();
}
}
setcounter()
{
if (command == 's')
{
count = getnum();
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);
LE = 0;
initpowerup();
sendprompt();
while(1)
{
getcommand();
prompting();
erase();
write();
read();
lock();
setcounter();
}
}