📄 loadpgm.c
字号:
#include <time.h>
#include <stdio.h>
#include <dos.h>
#include <conio.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <math.h>
#define RETRIES 64
#define BLOCK_NUM 9 // (32 * 1024) / 4096
#define BUF_SIZE 4096
#define BAUD2400 24
#define BAUD9600 12
#define BAUD19200 6
#define BAUD28800 2
#define PIC_EOI1 0x20 /* 8259 pic assignments */
#define PIC_MSK1 0x21
#define PIC_EOI2 0xA0
#define PIC_MSK2 0xA1
#define COM1_ADR 0x03f8 /* COM1 port base address */
#define COM1_MSK 0x10 /* COM1 8259 pic interrupt mask */
#define COM1_INT 0x0c /* COM1 interrupt number */
#define COM2_ADR 0x02f8 /* COM2 port base address */
#define COM2_MSK 0x08 /* COM2 8259 pic interrupt mask */
#define COM2_INT 0x0b /* COM2 interrupt number */
#define COM3_ADR 0x03e8 /* COM3 port base address */
#define COM3_MSK 0x04 /* COM3 8259 pic interrupt mask */
#define COM3_INT 0x72 /* COM3 interrupt number */
#define COM4_ADR 0x0270 /* COM4 port base address */
#define COM4_MSK 0x08 /* COM4 8259 pic interrupt mask */
#define COM4_INT 0x73 /* COM4 interrupt number */
unsigned int com_DATA; /* data register */
unsigned int com_IER; /* interrupt enable register */
unsigned int com_LCR; /* line control register */
unsigned int com_MCR; /* mode control register */
unsigned int com_LSR; /* status register */
unsigned int com_MSR; /* modem status register */
unsigned int com_MSK; /* interupt mask */
unsigned int com_INT; /* interrupt number */
void (interrupt far *oldvector)(); /* save old intr vector addr */
void interrupt far handler(); /* declaration for intr handler */
unsigned int oldlcr;
unsigned int olddll;
unsigned int olddlm;
#define BUFSIZE 0x3ff /* input buffer size */
volatile unsigned char Buffer[BUFSIZE+1]; /* rx in buffer for COM1 */
volatile unsigned int AscIn, AscOut; /* buffer in,out ptr offsets */
int debug, skip;
FILE *fp;
//***************************************************
char filename[40];
char cmd_erase[6] = { 0x1B, '%', '1', 'E', 0, 0 };
char cmd[10];
char cmd_response[256];
unsigned char xmit_buffer[BUF_SIZE];
//***************************************************
void dlysec( unsigned int sec )
{
time_t tstart, tend;
time( &tstart );
do
{
time( &tend );
} while( difftime( tend, tstart ) < sec );
}
void dlymsec( unsigned int msec )
{
clock_t cstart;
cstart = clock();
while( (clock() - cstart) < msec );
}
error_exit( int code )
{
//** debug
int i;
for( i=0; i<100; i++ )
{
outp( com_MCR, 0x02 );
outp( com_MCR, 0 );
}
//** debug
async_dis();
exit(code);
}
/*===================================================*/
/* setup addressing for both com ports */
/*===================================================*/
void com_init( int addr, int mask, int intr )
{
com_MSK = mask;
com_INT = intr;
com_DATA = addr; /* data register */
com_IER = addr + 1; /* interrupt enable register */
com_LCR = addr + 3; /* line control register */
com_MCR = addr + 4; /* modem control register */
com_LSR = addr + 5; /* status register */
com_MSR = addr + 6; /* modem status register */
oldlcr = inp(com_LCR); /* save original com port setup */
olddll = inp(com_DATA);
olddlm = inp(com_IER);
}
void set_baud( int baud )
{
unsigned int divisor;
int lcr;
divisor = baud;
outp(com_LCR, 0x80);
outp(com_IER, divisor >> 8);
outp(com_DATA, divisor); /* set baud rate */
outp(com_LCR, 0x0b); /* set length,stop bits, etc. */
}
/*=====================================================*/
/* set up interrupt vector, and initialize serial port */
/*=====================================================*/
async_en()
{
int data,msk;
oldvector = _dos_getvect(com_INT); /* store old interupt vector */
_dos_setvect(com_INT, handler); /* init interrupt vector table */
_disable(); /* cli */
data = 0x0b;
outp(com_MCR, data); /* setup mode control */
inp(com_DATA); /* clear potential pending intr */
if( com_INT == 0x0c || com_INT == 0x0b )
msk = PIC_MSK1;
else
msk = PIC_MSK2;
data = inp(msk); /* unmask com interupt */
data &= ~(com_MSK);
outp(msk, data);
_enable(); /* sti */
outp(com_IER, 1); /* enable interrupt */
outp(PIC_EOI2, 0x20); /* issue eoi to 8259 */
outp(PIC_EOI1, 0x20); /* issue eoi to 8259 */
}
/*======================================================*/
/* disable com interrupts, restore old interrupt vector */
/*======================================================*/
async_dis()
{
int data,msk;
if(debug)
printf("\nRestore interrupt vector");
if( com_INT == 0x0c || com_INT == 0x0b )
msk = PIC_MSK1;
else
msk = PIC_MSK2;
outp(com_MCR, 0); /* clear mode control reg */
data = inp(msk); /* set mask bit for com port */
data |= com_MSK;
outp(msk, data);
_dos_setvect(com_INT, oldvector); /* init interrupt vector table */
outp(com_LCR, oldlcr | 0x80); /* restore com setup */
outp(com_DATA, olddll);
outp(com_IER, olddlm);
outp(com_LCR, oldlcr);
}
void clrbuf()
{
AscIn=AscOut=0;
}
void rts_on()
{
outp( com_MCR, 0x02 );
}
void rts_off()
{
outp( com_MCR, 0 );
}
/*===========================*/
/* read char from COM port */
/*===========================*/
int com_in( int len, int msec )
{
int ch, i;
clock_t cstart;
cstart = clock();
if( debug )
printf("\nrcvd: ");
i = 0;
do
{
if( AscIn != AscOut )
{
cmd_response[i++] = *(Buffer + AscOut);
AscOut++;
AscOut &= BUFSIZE;
if( debug)
printf("%c", cmd_response[i-1]);
cstart = clock();
msec = 100;
}
} while( ( (clock()-cstart) < msec ) && ( i < len ) );
cmd_response[i] = 0;
return(i);
}
/*=================================*/
/* transmit specified char to COM */
/*=================================*/
com_out(char ch)
{
while ((inp(com_LSR) & 0x20) == 0); // wait for transmitted buffer empty
while ((inp(com_MSR) & 0x10) == 0); // wait fot CTS
outp(com_DATA, ch);
if( debug )
putchar( ch );
}
com_outs( char *str )
{
char chr;
if( debug )
printf("\nsend: ");
while( chr = *str++ )
com_out( chr );
}
void send_char( unsigned char chr )
{
_asm
{
mov dx, com_LSR
wait2send:
in al, dx
test al, 0x20
jz wait2send
mov dx, com_MSR
waitCTS:
in al, dx
test al, 0x10
jz waitCTS
mov dx, com_DATA
mov al, chr
out dx, al
}
}
int send_block( unsigned char *pbuf, int len )
{
int i;
unsigned char chr;
unsigned int sum = 0;
for( i=len; i; i-- )
{
send_char( chr = *pbuf++ );
sum += chr;
}
send_char((unsigned char)(sum >> 8));
send_char((unsigned char)(sum & 0xff));
}
/*=======================*/
/* interrupt handler... */
/*=======================*/
void interrupt far
handler(es, ds, di, si, bp, sp, bx, dx, cx, ax, ip, cs, flags)
int es, ds, di, si, bp, sp, bx, dx, cx, ax, ip, cs, flags;
{
*(Buffer + AscIn) = inp(com_DATA); /* read ch from serial port */
AscIn++; /* incr ptr */
AscIn = AscIn & BUFSIZE;
_enable(); /* issue sti */
outp(PIC_EOI2, 0x20); /* 8259 #1 eoi */
outp(PIC_EOI1, 0x20); /* 8259 #1 eoi */
}
int to_off(char *hexds)
{
int i;
int off = 0;
char chr;
for (i = 0; i < 3; i++) {
chr = *hexds++;
if (isdigit(chr))
chr -= '0';
else if (isxdigit(chr))
chr = (chr | ('a' - 'A')) - 'a' + 10;
else
return -1;
off = (off << 4) | chr;
}
return off;
}
void device_info()
{
printf("\n\tType of Display = %c", cmd_response[3] );
printf("\n\tFirmware version = %c%c", cmd_response[5], cmd_response[6] );
printf("\n\tCharacter set = %c", cmd_response[8] );
printf("\n\tNumber of lines = %c", cmd_response[10] );
printf("\n\tCharacters/line = %c%c", cmd_response[12], cmd_response[13] );
}
main( int argc, char *argv[] )
{
unsigned char cc;
int addr, mask, intr, baud;
int p1, p2;
int blk_no;
int len;
int i;
int remain, offset;
char *ptr;
skip = debug = 0;
addr = COM3_ADR;
mask = COM3_MSK;
intr = COM3_INT;
baud = BAUD9600;
strcpy( filename, "LCD52.BIN" );
for( i=1; i<argc; i++ )
{
if( argv[i][0] != '/' )
continue;
switch( argv[i][1] )
{
case 'C':
case 'c':
p1 = atoi( argv[i] + 3 );
switch(p1)
{
case 1:
addr = COM1_ADR;
mask = COM1_MSK;
intr = COM1_INT;
break;
case 2:
addr = COM2_ADR;
mask = COM2_MSK;
intr = COM2_INT;
break;
case 3:
addr = COM3_ADR;
mask = COM3_MSK;
intr = COM3_INT;
break;
case 4:
addr = COM4_ADR;
mask = COM4_MSK;
intr = COM4_INT;
break;
default:
printf("\nInvalid port number\n");
exit(0);
}
break;
case 'B':
case 'b':
p1 = atoi( argv[i] + 3 );
switch(p1)
{
case 2400:
baud = BAUD2400;
break;
case 9600:
baud = BAUD9600;
break;
case 19200:
baud = BAUD19200;
break;
default:
printf("\nInvalid baud rate\n");
exit(0);
}
case 'F':
case 'f':
strcpy( filename, argv[i] + 3 );
break;
case 'D':
case 'd':
debug = 1;
break;
case 'X':
case 'x':
skip = 1;
break;
case '?':
printf("\nUsage: Loadpgm /C=com /B=baud /F=filename /Debug \n\n");
exit(0);
}
}
printf("\nLOADPGM ver 1.0");
if( (fp = fopen( filename, "rb" )) == NULL )
{
printf("\nCannot open %s", filename );
exit( 1 );
}
clrbuf();
com_init( addr, mask, intr );
set_baud( BAUD9600 );
async_en();
dlysec(1);
clrbuf();
printf("\n\n> Get Device ID: ");
com_outs("[0c"); // Get device ID
rts_on();
if( com_in( 15, 5000 ) == 0 )
{
rts_off();
error_exit( 1 );
}
device_info();
clrbuf();
if( (cmd_response[5] != '0' || cmd_response[6] != '0') && skip == 0 )
{
printf("\n\n> Go to EPROM mode");
com_outs("#0P");
com_outs("#4P");
com_outs("#7P");
com_outs("#2P");
com_outs("%0G"); // Go to EPROM mode
dlysec(1);
printf("\n\n> Waiting for device initialisation ");
for( i=0; i<15; i++ )
{
if( AscIn != AscOut )
break;
dlysec(1);
putchar('.');
}
if( i == 15 )
{
printf("\n## Timeout waiting for device initialization");
//error_exit(1);
}
else
{
com_in(15,1000);
device_info();
}
}
rts_off();
clrbuf();
for( blk_no = 0; blk_no < BLOCK_NUM; blk_no++ )
{
len = fread( xmit_buffer, 1, BUF_SIZE, fp );
if( len == 0 )
break;
dlysec(1);
printf("\n\n> BLOCK #%d", blk_no);
set_baud( BAUD9600 );
com_outs("#0P");
com_outs("#4P");
com_outs("#7P");
com_outs("#2P");
if( blk_no % 16 == 0 )
{
printf("\n>> Erasing ...");
cmd_erase[2] = (blk_no / 16) + '0';
if(cmd_erase[2] > '9')
cmd_erase[2] += 'A' - '0';
clrbuf();
rts_on();
com_outs( cmd_erase );
if( com_in( 6, 5000 ) != 6 )
{
printf("\n## received timeout: %s", cmd_response);
error_exit(1);
}
else if( !strcmp(cmd_response, "&E-OK") )
printf(" OK" );
else
{
printf("\n## erase FAIL: %s\n", cmd_response);
error_exit(1);
}
}
rts_off();
printf("\n>> Programming blk %d ... ", blk_no);
sprintf(cmd, "$A%05lX", blk_no * 0x1000L);
com_outs(cmd); // Program Address
sprintf(cmd, "$L%03X", len-1);
com_outs(cmd); // Program range
dlymsec( 20 );
set_baud( BAUD28800 );
offset = 0;
rts_off();
for( i=0; i<RETRIES; i++ )
{
clrbuf();
rts_on();
if( com_in( 6, 5000 ) == 0 )
{
printf("\n## Receive timeout: Data Req Cmd: previous offset=%04X", offset);
error_exit(1);
}
rts_off();
if( isxdigit( cmd_response[2] ) )
{
offset = to_off( cmd_response + 2 );
if( offset == -1 )
{
printf("\n## Transmit error: %s", cmd_response );
break;
}
}
else if( strcmp(cmd_response, "&R-OK") == 0 )
break;
else if( strcmp(cmd_response, "&FAIL") == 0 )
break;
remain = len - offset;
send_block( xmit_buffer + offset, (remain > 256) ? 256 : remain );
}
if( i == RETRIES )
{
printf("\n## Too more errors, program aborted\n");
break;
}
if( strcmp(cmd_response, "&R-OK") )
{
printf("\n## Without expected receive OK (%s)\n", cmd_response);
break;
}
clrbuf();
rts_on();
if( com_in( 6, 5000 ) != 6 )
{
printf("\n## Receive time out: expect program OK!\n");
error_exit(2);
}
rts_off();
if( strcmp(cmd_response, "&P-OK") == 0 )
printf( " OK" );
else
{
printf("\n## Program FAIL (%s)\n", cmd_response);
error_exit(2);
}
}
rts_off();
set_baud( BAUD9600 );
// dlysec( 1 );
rts_on();
clrbuf();
printf("\n\n> Execute from Flash.");
com_outs("#0P");
com_outs("#4P");
com_outs("#7P");
com_outs("#2P");
com_outs("%1G"); // Go to FLASH mode
dlysec(1);
printf("\n\n> Waiting for device initialisation ");
for( i=0; i<15; i++ )
{
if( AscIn != AscOut )
break;
dlysec(1);
putchar('.');
}
if( i == 15 )
{
printf("\n## Timeout waiting for device initialization");
//error_exit(1);
}
com_in(11000);
rts_off();
device_info();
printf("\n\n");
async_dis();
fclose(fp);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -