/************************************************************************/ /* Atmel 89C2051 Parallel Port Programmer */ /* */ /* Author: */ /* Steven J. Merrifield */ /* sjm@ee.latrobe.edu.au */ /* http://livewire.ee.latrobe.edu.au/~sjm */ /* */ /* THIS IS AN UNSUPPORTED ALPHA VERSION - USE AT YOUR OWN RISK !!!!! */ /* There is no guarantee that this program will work correctly. It may */ /* fry your controller - USE AT YOUR OWN RISK. I offer absolutely no */ /* guarantee that this software will work at all !!! */ /* */ /* I DO NOT want to receive any mail about this program. If you want */ /* to make changes, then go ahead. You do not need my permission. If */ /* you distribute modified versions, then please give me credit as */ /* the original author. Likewise, if you modify the hardware, then */ /* give me credit as the original designer. */ /* */ /* I will NOT be releasing further versions or updates because I do not */ /* have the time. This source is made available in the hope that */ /* somebody will adopt the basic framework and make a decent program */ /* out of it. Any mail concerning this program will be ruthlessly */ /* redirected to /dev/null. I do NOT have the time to offer support */ /* or answer questions. Please do NOT ask as a refusal may offend. */ /* */ /* This program was written for Borland C for DOS, which is a major */ /* headache because its delay() function will not go lower than 1ms. */ /* The hardware requires a programming pulse of between 1us to 110us. */ /* Because of this, I've included a for(;;) loop which YOU will have */ /* to adjust according to your machine. Just hang a CRO off pin 6 of */ /* the controller, and adjust the delay for about 50us. */ /* */ /* To do: Autodetect host processor speed? */ /* Verify data as it's being programmed? */ /* Allow user to select LPT base address? */ /* Option to dump ROM to a user-selectable file? */ /* Add ASCII values to ROM dump on right hand side? */ /* Add options for setting Lock Bits? */ /* */ /* This code is full of bugs - there is no guarantee that any of it */ /* will work !!! */ /************************************************************************/ #include #include #include #include #include #define TIMING_LOOP 4500 /* See comment above */ #define DATA 0x378 /* Base address for parallel port */ #define STAT DATA+1 #define CTRL DATA+2 /************************************************************************/ /* Reset the internal address counter to zero. It would be nice if this */ /* could be done in software, but I'm already using all 18 lines - if */ /* only there were 19... */ /************************************************************************/ void zero_addr() { int ch=0; fprintf(stdout,"Press the RESET button now. Then press 'C' to continue... "); do { ch = fgetc(stdin); } while (toupper(ch) !='C'); fprintf(stdout,"\n"); } /************************************************************************/ /* Erase the internal memory */ /************************************************************************/ void erase_dev() { zero_addr(); fprintf(stdout,"Erasing...\n"); outportb(CTRL,0x09); /* RST= +5 */ outportb(DATA,0x06); /* Setup P3.X pins */ outportb(CTRL,0x0B); /* RST = +12 */ outportb(DATA,0x04); /* Strobe P3.2 low */ delay(10); /* Wait 10ms */ outportb(DATA,0x06); /* Take P3.2 high again */ outportb(CTRL,0x09); /* RST = +5 */ fprintf(stdout,"Done!\n"); } /************************************************************************/ /* Read a binary file, store it into an array, then write the contents */ /* of that array to the controller. Note that the timing loop WILL NEED */ /* to be adjusted depending on the speed of your machine. */ /************************************************************************/ void program_dev() { int result; FILE *infile; unsigned char data_arr[2048]; char f[80]; char s[80]; char temp[80]; int arr_index = 0; int i; long int c; for (i=0;i<2048;i++) /* clear array before reading file */ data_arr[i] = 0xFF; fprintf(stdout,"Enter filename: "); fscanf(stdin,"%s",f); if ((infile=fopen(f,"rt")) == NULL) { fprintf(stderr,"\nError opening file.\n"); exit(1); } while (!(feof(infile))) /* load data into array */ { fscanf(infile,"%2x",&data_arr[arr_index]); arr_index++; } zero_addr(); fprintf(stdout,"Programming... (please wait)\n"); for (i=0;i<2048;i++) { outportb(CTRL,0x08); /* OE = low, LE = high, RST = +5 */ outportb(DATA,data_arr[i]); /* Send data */ outportb(CTRL,0x09); /* LE = low */ outportb(DATA,0x3A); /* Setup P3.X */ outportb(CTRL,0x0B); /* RST = +12 */ outportb(DATA,0x38); /* Pulse P3.2 low */ for (c=0;c> 4)^0x08; /* get low nibble */ outportb(CTRL,0x04); /* A/B = B */ hidat=(inportb(STAT) & 0xF0)^0x80; /* get high nibble */ return(hidat | lodat); } /************************************************************************/ /* Read the signature bytes */ /************************************************************************/ void read_sig() { int i; unsigned char sig[3]; zero_addr(); outportb(DATA,0x02); /* Setup P3.X */ for (i=0;i<3;i++) { sig[i]=read_port(); fprintf(stdout,"%03X: %02X\n",i,sig[i]); outportb(DATA,0x03); /* Pulse xtal high */ outportb(DATA,0x02); /* Bring xtal low */ } } /************************************************************************/ /* Read entire memory into an array, then display that array */ /************************************************************************/ void read_dev() { int i; int addr=0; int cnt; int ch=0; int line_cnt; unsigned char data_arr[2048]; zero_addr(); outportb(DATA,0x32); /* Setup P3.X */ for (i=0;i<2048;i++) { data_arr[i] = read_port(); outportb(DATA,0x33); /* Pulse xtal high */ outportb(DATA,0x32); /* Bring xtal low */ } i=0; while (i<2048) { for (line_cnt=0;line_cnt<16;line_cnt++) { fprintf(stdout,"%03X: ",addr); for (cnt=0;cnt<16;cnt++) { fprintf(stdout,"%02X ",data_arr[i]); i++; } fprintf(stdout,"\n"); addr+=16; } do { ch = fgetc(stdin); } while (toupper(ch) !='C'); fprintf(stdout,"\n"); } } /************************************************************************/ /* Main program */ /************************************************************************/ int main() { int QUIT = 0; char choice; outportb(CTRL,0x09); while (QUIT != 1) { fprintf(stdout,"\n\n\n"); fprintf(stdout,"+--------------------------+\n"); fprintf(stdout,"| 1. Program device |\n"); fprintf(stdout,"| 2. Read device |\n"); fprintf(stdout,"| 3. Erase device |\n"); fprintf(stdout,"| 4. Read signature bytes |\n"); fprintf(stdout,"| 5. QUIT |\n"); fprintf(stdout,"+--------------------------+\n"); fprintf(stdout," Enter choice (1-5) "); choice = '\0'; while ((choice < '1') || (choice > '5')) choice = fgetc(stdin); switch (choice) { case '1': program_dev(); break; case '2': read_dev(); break; case '3': erase_dev(); break; case '4': read_sig(); break; case '5': QUIT = 1; break; } } return(0); }