#include #include #include #include #include unsigned char memory[512]; unsigned long sendbyte=0,abs_adr=0; int error=0; int comport=0; /* application specific functions */ void usage(void); void detect(void); void preloader(void); void loader(void); void eraser(void); void apploader(char *strg); void readhex(unsigned int start_addr,char *c); void readhex2(char *c); void transmit(unsigned long adr,unsigned char dat); /* common functions */ unsigned long hex2long(char *c); unsigned long pot(unsigned long a,unsigned long b); void strred(char *c1,char *c2,int a,int b); void setbaud(unsigned long baudrate); void send(unsigned char bte); int receive(unsigned int timeout_ms); /****************************************************************************/ /* MAIN */ /* Checks parameter format */ /* Initalizes MC in Boot Strap Mode */ /* Reads preloader hex file and sends it (32 Bytes) to MC */ /* Reads loader hex file and sends it (256 Bytes) to MC */ /* Reads application hex file (given as parameter) and sends it to MC */ /****************************************************************************/ void main(int argc,char **argv) { if (argc==2 || argc==4) { if (argc==4) { if (strcmp(argv[2],"-p")==0) { if (strcmp(argv[3],"COM1")==0) comport=0x3f8; if (strcmp(argv[3],"COM2")==0) comport=0x2f8; if (strcmp(argv[3],"COM3")==0) comport=0x3e8; if (strcmp(argv[3],"COM4")==0) comport=0x2e8; } else usage(); } else { comport=0x3f8; } if (comport==0) usage(); clrscr(); setbaud(38400); printf("HEXLOAD - (c) 1998 by christian perschl & wilhelm brezovits\n"); printf("Edition for starter kit C167 in Flash mode\n"); detect(); /* initializes mc and receives id byte */ preloader(); /* loads preload.h86 and sends it (32 Byte) to mc */ loader(); /* loads load.h86 and sends it (256 Byte) to mc */ eraser(); /* erases the external flash */ apploader(argv[1]); /* loads application file and sends it to mc */ } else usage(); } /****************************************************************************/ /* USAGE */ /* writes usage message and exits */ /****************************************************************************/ void usage() { /* wrong parameters */ printf("usage: hexload [-p ]\n"); printf(" standard or extended intel hex format \n"); printf(" serial port, COM1 (default), COM2, ...\n"); exit(10); } /****************************************************************************/ /* DETECT */ /* sends initialization byte to mc and determines mc-derivate/step */ /****************************************************************************/ void detect() { int i; /* look for incoming data */ if ((inportb(comport+5) & 0x01)==1) i=inportb(comport+5); /* send byte 0 , MC calculates Baudrate */ outportb(comport,0); /* receive and interpret id byte */ delay(10); if ((i=receive(100))==-1) { printf("ERROR: id byte not received\n"); exit(1); } switch (i) { case 0xb5: printf("%x: C165 detected\n",i);break; case 0x55: printf("%x: 80C166 detected\n",i);break; case 0xa5: printf("%x: C167 Step AD detected\n",i);break; case 0xc5: printf("%x: C167 Step BA / C167CR detected\n",i);break; default:printf("%x: Unknown C16x Type recognized\n",i); } } /****************************************************************************/ /* PRELOADER */ /* sends preloader hex file to mc */ /****************************************************************************/ void preloader() { FILE *FIN; char lin[256]; int i; /* reset array memory */ for (i=0;i<32;i++) memory[i]=0; /* read preloader - hex file and write to array mem */ FIN=fopen("preload.h86","rt"); while (!feof(FIN)) { fscanf(FIN,"%s",lin); readhex(0xFA40,lin); } fclose(FIN); if (error==0) printf("preloader: conversion of HEX-File OK\n"); else { printf("ERROR: preloader hex file not valid\n");exit(2); } /* send preloader from array memory to comport */ printf("sending preloader\n"); for (i=0;i<32;i++) { while ((inportb(comport+5) & 0x20)==0); outportb(comport,memory[i]); } printf("preloader successfully loaded\n"); } /****************************************************************************/ /* LOADER */ /* sends loader hex file to mc */ /****************************************************************************/ void loader() { FILE *FIN; char lin[256]; int i; /* reset array memory */ for (i=0;i<512;i++) memory[i]=0; /* read loader to array memory */ FIN=fopen("load.h86","rt"); while (!feof(FIN)) { fscanf(FIN,"%s",lin); readhex(0xF600,lin); } fclose(FIN); if (error==0) printf("loader: conversion of HEX-File OK\n"); else { printf("ERROR: loader hex file not valid\n");exit(3); } /* send loader to MC */ printf("sending loader\n"); for (i=0;i<512;i++) { while ((inportb(comport+5) & 0x20)==0); // wait for transition outportb(comport,memory[i]);} if (receive(100)==1) printf("loader successfully loaded\n"); else { printf("ERROR: loader not loaded !!!\n"); exit(4); } } /****************************************************************************/ /* ERASER */ /* sends loader hex file to mc */ /****************************************************************************/ void eraser() { printf("erasing flash\n"); send('l'); /* while(!kbhit()) { printf("%d ",receive(1)); } */ if (receive(10000)==4) printf("flash successfully erased\n"); else { printf("ERROR: flash not erased !!!\n"); exit(5); } } /****************************************************************************/ /* APPLOADER */ /* sends given application hex file to mc */ /****************************************************************************/ void apploader(char *strg) { FILE *FIN; char lin[256]; /* load and transmit application file */ printf("loading application file\n"); abs_adr=0; error=0; FIN=fopen(strg,"rt"); printf("Bytes transfered: \n"); while (!feof(FIN)) { fscanf(FIN,"%s",lin); readhex2(lin); printf("\r%ld",sendbyte); } fclose(FIN); if (error==0) printf("\napplication:conversion of HEX-File OK"); else { printf("ERROR: application hex file not valid\n");exit(5); } send('e'); if (receive(100)==2) printf("\napplication successfully loaded"); else { printf("\nERROR: application not loaded !!!\n"); exit(6); } } /****************************************************************************/ /* READHEX */ /* read hex file and write into array memory: used for preloader and loader */ /****************************************************************************/ void readhex(unsigned int start_addr,char *c) { char hc1[256],hc2[3]; unsigned char content[256]; unsigned long offset=0,sum=0; unsigned int length=0,type=0; int i; /* read recorde header: length, offset, type */ if (c[0]!=':') { fprintf(stdout,"Record header error\n"); error=1;} strred(c,hc1,2,2); length=hex2long(hc1); strred(c,hc1,4,4); offset=hex2long(hc1); strred(c,hc1,8,2); type=hex2long(hc1); strred(c,hc1,strlen(c)-1,2);/* checksum=hex2long(hc1);*/ /* read whole record into array content */ for (i=0;i> 24; send(w); w=(adr & 0x00FF0000) >> 16; send(w); w=(adr & 0x0000FF00) >> 8; send(w); w=adr & 0x000000FF; send(w); send(dat); } /****************************************************************************/ /* SEND */ /* Sends given data to serial port */ /****************************************************************************/ void send(unsigned char bte) { while ((inportb(comport+5) & 0x20)==0); outportb(comport,bte); } /****************************************************************************/ /* RECEIVE */ /* Receives byte from serial port via polling */ /****************************************************************************/ int receive(unsigned int timeout_ms) { unsigned int i=0; while (((inportb(comport+5) & 0x01)==0) && i++=0;i--) { err=1; if (c[i]>='0' && c[i]<='9') { add=pot(16,strlen(c)-i-1)*(c[i]-48);err=0;} if (c[i]>='A' && c[i]<='F') { add=pot(16,strlen(c)-i-1)*(c[i]-55);err=0;} if (c[i]>='a' && c[i]<='f') { add=pot(16,strlen(c)-i-1)*(c[i]-87);err=0;} if (err==1) { fprintf(stderr,"no hexadecimal character\n");error=1; } res=res+add; } return res; } /****************************************************************************/ /* POT */ /* calculate a^b , long */ /****************************************************************************/ unsigned long pot(unsigned long a,unsigned long b) { if (b==0) return 1; else return a*pot(a,b-1); } /****************************************************************************/ /* SETBAUD */ /* set given baud rate of serial port */ /****************************************************************************/ void setbaud(unsigned long baud) { unsigned int w; outport(comport+3,0x83); /* LCR: Line control register, Register Address = 3 */ /* LCR = 1000 0011 B = 0x83 */ /* 1: DLAB: Divisor latch access bit */ /* DLAB: It must be set high to access the divisor latches of the baud */ /* generator. It must be set low to access the receiver buffer or */ /* the transmitter holding register. */ switch (baud) { case 150: w=768;break; case 300: w=384;break; case 600: w=192;break; case 1200:w=96;break; case 2400:w=48;break; case 3600:w=32;break; case 4800:w=24;break; case 7200:w=16;break; case 9600:w=12;break; case 19200:w=6;break; case 38400:w=3;break; case 56000:w=2;break; default: w=12; } outport(comport,w); outport(comport+1,0); /* DLM: Divisor latch (Bit 8-15), Register Address = 1, (DLAB=1) */ outport(comport+3,0x03); /* LCR: Line control register, Register Address = 3 */ /* LCR = 0000 0011 B = 0x07 */ /* |||| ||11: WLS1+WLS0: Character length = 8 bits */ /* |||| |0: STB: Number of stop bits = 1 */ /* |||| 0: PEN: Parity enable = nein */ /* |||0: EPS: Even parity select = nein */ /* ||0: Stick parity = nein */ /* |0: Set break = nein */ /* 0: DLAB: Divisor latch access bit */ }