/* * Copyright 2000 Brian S. Dean * All Rights Reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY BRIAN S. DEAN ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BRIAN S. DEAN BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH * DAMAGE. * */ /* $Id$ */ /* * Code to program an Atmel AVR AT90S device using the parallel port. * * Make the following connections: * * Parallel Port Atmel AVR * ------------- ---------------------------- * Pin 2 -> Vcc (see NOTE below) * Pin 3 -> SCK CLOCK IN * Pin 4 -> MOSI Instruction input * Pin 5 -> /RESET * Pin 6,7,8,9 -> Vcc (Can be tied together with Schottky diodes) * Pin 10 <- MISO Data out * Pin 18 <- GND * * NOTE on Vcc connection: make sure your parallel port can supply an * adequate amount of current to power your device. 6-10 mA is * common for parallel port signal lines, but is not guaranteed, * especially for notebook computers. Optionally, you can tie pins * 6, 7, 8, and 9 also to Vcc with Schottky diodes to supply * additional current. If in doubt, don't risk damaging your * parallel port, use an external power supply. */ #include #include #include #include #include #include #include "avr.h" #include "fileio.h" #include "ppi.h" #include "term.h" #define DEFAULT_PARALLEL "/dev/ppi0" char * version = "1.1"; char * progname; char progbuf[PATH_MAX]; /* temporary buffer of spaces the same length as progname; used for lining up multiline messages */ char * usage_text = "\n" "Usage: avrprog [options]\n" "\n" " Available Options:\n" "\n" " -m MemType : select memory type for reading or writing\n" " \"e\", \"eeprom\" = EEPROM\n" " \"f\", \"flash\" = FLASH (default)\n" "\n" " -i Filename : select input file, \"-\" = stdin\n" "\n" " -o Filename : select output file, \"-\" = stdout\n" "\n" " -f Format : select input / output file format\n" " \"i\" = Intel Hex\n" " \"s\" = Motorola S-Record\n" " \"r\" = Raw binary (default for output)\n" " \"a\" = Auto detect (default for input)\n" " (valid for input only)\n" " \n" "\n" " -p Part : select Atmel part number (see below for valid parts)\n" "\n" " -P Parallel : select parallel port device name (default = /dev/ppi0)\n" "\n" " -F : override invalid device signature check\n" "\n" " -t : enter terminal mode (or read commands from stdin)\n" "\n" " -E exitspec[,...]: specify which bits to set/reset on exit\n" " \"[no]reset\" = [don't] activate /RESET\n" " \"[no]vcc\" = [don't] activate Vcc\n" "\n" " -e : perform a chip erase (required before programming)\n" "\n"; /* * usage message */ void usage ( void ) { fprintf ( stderr, "%s", usage_text ); fprintf(stderr, " Valid Parts for the -p option are:\n"); avr_list_parts(stderr, " "); fprintf(stderr, "\n"); } /* * parse the -E string */ int getexitspecs ( char *s, int *set, int *clr ) { char *cp; while ((cp = strtok(s, ","))) { if (strcmp(cp, "reset") == 0) { *clr |= AVR_RESET; } else if (strcmp(cp, "noreset") == 0) { *set |= AVR_RESET; } else if (strcmp(cp, "vcc") == 0) { *set |= AVR_POWER; } else if (strcmp(cp, "novcc") == 0) { *clr |= AVR_POWER; } else { return -1; } s = 0; /* strtok() should be called with the actual string only once */ } return 0; } /* * main routine */ int main ( int argc, char * argv [] ) { int fd; /* file descriptor for parallel port */ int rc; /* general return code checking */ int exitrc; /* exit code for main() */ int i; /* general loop counter */ int ch; /* options flag */ int size; /* size of memory region */ int len; /* length for various strings */ unsigned char sig[4]; /* AVR signature bytes */ unsigned char nulldev[4]; /* 0xff signature bytes for comparison */ struct avrpart * p, ap1; /* which avr part we are programming */ struct avrpart * v, ap2; /* used for verify */ int readorwrite; /* true if a chip read/write op was selected */ int ppidata; /* cached value of the ppi data register */ /* options / operating mode variables */ int memtype; /* AVR_FLASH or AVR_EEPROM */ int doread; /* 0=reading, 1=writing */ int erase; /* 1=erase chip, 0=don't */ char * outputf; /* output file name */ char * inputf; /* input file name */ int ovsigck; /* 1=override sig check, 0=don't */ char * parallel; /* parallel port device */ int terminal; /* 1=enter terminal mode, 0=don't */ FILEFMT filefmt; /* FMT_AUTO, FMT_IHEX, FMT_SREC, FMT_RBIN */ int nowrite; /* don't actually write anything to the chip */ int verify; /* perform a verify operation */ int ppisetbits; /* bits to set in ppi data register at exit */ int ppiclrbits; /* bits to clear in ppi data register at exit */ readorwrite = 0; parallel = DEFAULT_PARALLEL; outputf = NULL; inputf = NULL; doread = 1; memtype = AVR_FLASH; erase = 0; p = NULL; ovsigck = 0; terminal = 0; filefmt = FMT_AUTO; nowrite = 0; verify = 1; /* on by default; XXX can't turn it off */ ppisetbits = ppiclrbits = 0; progname = rindex(argv[0],'/'); if (progname) progname++; else progname = argv[0]; len = strlen(progname) + 2; for (i=0; iflash or p->eeprom) is the * same as what is on the chip */ fprintf(stderr, "%s: verifying %s memory against %s:\n", progname, avr_memtstr(memtype), inputf); fprintf(stderr, "%s: reading on-chip %s data:\n", progname, avr_memtstr(memtype)); rc = avr_read ( fd, v, memtype ); if (rc) { fprintf(stderr, "%s: failed to read all of %s memory, rc=%d\n", progname, avr_memtstr(memtype), rc); exitrc = 1; goto main_exit; } fprintf(stderr, "%s: verifying\n", progname); rc = avr_verify(p, v, memtype); if (rc) { fprintf(stderr, "%s: verification error; content mismatch\n", progname); exitrc = 1; goto main_exit; } fprintf(stderr, "%s: data verified\n", progname); } main_exit: /* * program complete */ avr_powerdown(fd); ppi_setall(fd, PPIDATA, ppidata); close(fd); fprintf(stderr, "\n%s done. Thank you.\n\n", progname); return exitrc; }