Make the pin definitions configurable based on entries in a config

file.  This makes supporting other programmers much easier.

Rename AVRprog.pdf to avrprog.pdf.


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@67 81a1dc3b-b13d-400b-aceb-764788c761c2
This commit is contained in:
Brian S. Dean 2001-09-19 17:04:25 +00:00
parent e87b062769
commit 6981b65d59
10 changed files with 533 additions and 62 deletions

View File

@ -11,12 +11,13 @@ BINDIR = ${PREFIX}/bin
MANDIR = ${PREFIX}/man/man1 MANDIR = ${PREFIX}/man/man1
MANUAL = avrprog.1 MANUAL = avrprog.1
DOCDIR = ${PREFIX}/share/doc/avrprog DOCDIR = ${PREFIX}/share/doc/avrprog
CONFIGDIR = ${PREFIX}/etc
DIRS = ${BINDIR} ${MANDIR} ${DOCDIR} DIRS = ${BINDIR} ${MANDIR} ${DOCDIR} ${CONFIGDIR}
INSTALL = /usr/bin/install -c -o root -g wheel INSTALL = /usr/bin/install -c -o root -g wheel
CFLAGS += -Wall --pedantic CFLAGS = -g -Wall --pedantic -DCONFIG_DIR=\"${CONFIGDIR}\"
LDFLAGS = LDFLAGS =
@ -39,7 +40,11 @@ ${TARGET} : ${OBJS}
clean : clean :
rm -f *~ *.core ${TARGET} *.o rm -f *~ *.core ${TARGET} *.o
install : dirs ${BINDIR}/${TARGET} ${MANDIR}/${MANUAL} ${DOCDIR}/AVRprog.pdf install : dirs \
${BINDIR}/${TARGET} \
${MANDIR}/${MANUAL} \
${DOCDIR}/avrprog.pdf \
${CONFIGDIR}/avrprog.conf.sample
dirs : dirs :
@ -51,11 +56,14 @@ dirs :
done done
${BINDIR}/${TARGET} : ${TARGET} ${BINDIR}/${TARGET} : ${TARGET}
${INSTALL_PROGRAM} ${TARGET} ${BINDIR} ${INSTALL_PROGRAM} ${TARGET} $@
${MANDIR}/${MANUAL} : ${MANUAL} ${MANDIR}/${MANUAL} : ${MANUAL}
${INSTALL_MANUAL} ${MANUAL} ${MANDIR} ${INSTALL_MANUAL} ${MANUAL} $@
${DOCDIR}/AVRprog.pdf : AVRprog.pdf ${DOCDIR}/avrprog.pdf : avrprog.pdf
${INSTALL_DATA} AVRprog.pdf ${DOCDIR}/AVRprog.pdf ${INSTALL_DATA} avrprog.pdf $@
${CONFIGDIR}/avrprog.conf.sample : avrprog.conf.sample
${INSTALL_DATA} avrprog.conf.sample $@

View File

@ -114,16 +114,16 @@ int avr_txrx_bit ( int fd, int bit )
* read the result bit (it is either valid from a previous clock * read the result bit (it is either valid from a previous clock
* pulse or it is ignored in the current context) * pulse or it is ignored in the current context)
*/ */
r = ppi_getpin(fd, PIN_AVR_MISO); r = ppi_getpin(fd, pinno[PIN_AVR_MISO]);
/* set the data input line as desired */ /* set the data input line as desired */
ppi_setpin(fd, PIN_AVR_MOSI, bit); ppi_setpin(fd, pinno[PIN_AVR_MOSI], bit);
/* /*
* pulse the clock line, clocking in the MOSI data, and clocking out * pulse the clock line, clocking in the MOSI data, and clocking out
* the next result bit * the next result bit
*/ */
ppi_pulsepin(fd, PIN_AVR_SCK); ppi_pulsepin(fd, pinno[PIN_AVR_SCK]);
return r; return r;
} }
@ -176,8 +176,8 @@ unsigned char avr_read_byte ( int fd, struct avrpart * p,
/* order here is very important, AVR_EEPROM, AVR_FLASH, AVR_FLASH+1 */ /* order here is very important, AVR_EEPROM, AVR_FLASH, AVR_FLASH+1 */
static unsigned char cmdbyte[3] = { 0xa0, 0x20, 0x28 }; static unsigned char cmdbyte[3] = { 0xa0, 0x20, 0x28 };
LED_ON(fd, PIN_LED_PGM); LED_ON(fd, pinno[PIN_LED_PGM]);
LED_OFF(fd, PIN_LED_ERR); LED_OFF(fd, pinno[PIN_LED_ERR]);
offset = 0; offset = 0;
@ -193,7 +193,7 @@ unsigned char avr_read_byte ( int fd, struct avrpart * p,
avr_cmd(fd, cmd, res); avr_cmd(fd, cmd, res);
LED_OFF(fd, PIN_LED_PGM); LED_OFF(fd, pinno[PIN_LED_PGM]);
return res[3]; return res[3];
} }
@ -253,8 +253,8 @@ int avr_write_byte ( int fd, struct avrpart * p, AVRMEM memtype,
return 0; return 0;
} }
LED_ON(fd, PIN_LED_PGM); LED_ON(fd, pinno[PIN_LED_PGM]);
LED_OFF(fd, PIN_LED_ERR); LED_OFF(fd, pinno[PIN_LED_ERR]);
offset = 0; offset = 0;
@ -297,13 +297,14 @@ int avr_write_byte ( int fd, struct avrpart * p, AVRMEM memtype,
* we couldn't write the data, indicate our displeasure by * we couldn't write the data, indicate our displeasure by
* returning an error code * returning an error code
*/ */
LED_OFF(fd, PIN_LED_PGM); LED_OFF(fd, pinno[PIN_LED_PGM]);
LED_ON(fd, PIN_LED_ERR); LED_ON(fd, pinno[PIN_LED_ERR]);
return -1; return -1;
} }
} }
LED_OFF(fd, PIN_LED_PGM); LED_OFF(fd, pinno[PIN_LED_PGM]);
return 0; return 0;
} }
@ -326,7 +327,7 @@ int avr_write ( int fd, struct avrpart * p, AVRMEM memtype, int size )
unsigned char data; unsigned char data;
int werror; int werror;
LED_OFF(fd, PIN_LED_ERR); LED_OFF(fd, pinno[PIN_LED_ERR]);
werror = 0; werror = 0;
@ -351,7 +352,7 @@ int avr_write ( int fd, struct avrpart * p, AVRMEM memtype, int size )
if (rc) { if (rc) {
fprintf(stderr, " ***failed; "); fprintf(stderr, " ***failed; ");
fprintf(stderr, "\n"); fprintf(stderr, "\n");
LED_ON(fd, PIN_LED_ERR); LED_ON(fd, pinno[PIN_LED_ERR]);
werror = 1; werror = 1;
} }
if (werror) { if (werror) {
@ -359,7 +360,7 @@ int avr_write ( int fd, struct avrpart * p, AVRMEM memtype, int size )
* make sure the error led stay on if there was a previous write * make sure the error led stay on if there was a previous write
* error, otherwise it gets cleared in avr_write_byte() * error, otherwise it gets cleared in avr_write_byte()
*/ */
LED_ON(fd, PIN_LED_ERR); LED_ON(fd, pinno[PIN_LED_ERR]);
} }
} }
@ -394,13 +395,13 @@ int avr_chip_erase ( int fd, struct avrpart * p )
unsigned char data[4] = {0xac, 0x80, 0x00, 0x00}; unsigned char data[4] = {0xac, 0x80, 0x00, 0x00};
unsigned char res[4]; unsigned char res[4];
LED_ON(fd, PIN_LED_PGM); LED_ON(fd, pinno[PIN_LED_PGM]);
avr_cmd(fd, data, res); avr_cmd(fd, data, res);
usleep(p->chip_erase_delay); usleep(p->chip_erase_delay);
avr_initialize(fd, p); avr_initialize(fd, p);
LED_OFF(fd, PIN_LED_PGM); LED_OFF(fd, pinno[PIN_LED_PGM]);
return 0; return 0;
} }
@ -455,9 +456,9 @@ int avr_initialize ( int fd, struct avrpart * p )
avr_powerup(fd); avr_powerup(fd);
ppi_setpin(fd, PIN_AVR_SCK, 0); ppi_setpin(fd, pinno[PIN_AVR_SCK], 0);
ppi_setpin(fd, PIN_AVR_RESET, 0); ppi_setpin(fd, pinno[PIN_AVR_RESET], 0);
ppi_pulsepin(fd, PIN_AVR_RESET); ppi_pulsepin(fd, pinno[PIN_AVR_RESET]);
usleep(20000); /* 20 ms XXX should be a per-chip parameter */ usleep(20000); /* 20 ms XXX should be a per-chip parameter */
@ -478,7 +479,7 @@ int avr_initialize ( int fd, struct avrpart * p )
rc = avr_program_enable ( fd ); rc = avr_program_enable ( fd );
if (rc == 0) if (rc == 0)
break; break;
ppi_pulsepin(fd, PIN_AVR_SCK); ppi_pulsepin(fd, pinno[PIN_AVR_SCK]);
tries++; tries++;
} while (tries < 32); } while (tries < 32);

View File

@ -113,6 +113,31 @@ ll.
8515 AT90S8515 8515 AT90S8515
8535 AT90S8535 8535 AT90S8535
.TE .TE
.It Fl c Ar Pin-Configuration
Use the pin configuration specified by the argument. Pin
configurations are read from the config file (see the
.Fl C
option). New pin configurations can be easily added or modified
through the use of a config file to make
.Nm avrprog
work with different programmers as long as the programmer supports the
Atmel AVR serial program method.
.It Fl C Ar Config-File
Use the specified config file to locate the desired pin configuration.
Pin configurations are specified in the config file using a colon
seperated field format. The configuration name is the first field,
the remaining fields are of the form:
.Ar PIN=VALUE ,
where
.Ar PIN
can be
.Ar VCC , RESET , SCK , MOSI , MISO , BUFF , PGMLED , RDYLED , VFYLED , ERRLED .
The value is the pin number of the PC parallel port assigned to that
function. The
.Ar VCC
pin can take multible values seperated by a comma. It's value(s) must
come from pins 2 through 9. The default configuration file is
.Pa /usr/local/etc/avrprog.conf .
.It Fl e .It Fl e
Causes a chip erase to be executed. This will reset the contents of the Causes a chip erase to be executed. This will reset the contents of the
flash ROM and EEPROM to the value flash ROM and EEPROM to the value
@ -300,6 +325,8 @@ ll.
.It Pa /dev/ppi0 .It Pa /dev/ppi0
default device to be used for communication with the programming default device to be used for communication with the programming
hardware hardware
.It Pa /usr/local/etc/avrprog.conf
default pin configuration file
.It Pa ~/.inputrc .It Pa ~/.inputrc
Initialization file for the Initialization file for the
.Xr readline 3 .Xr readline 3

View File

@ -0,0 +1,27 @@
# $Id$
#
# Programmer Pin Configurations
#
# The format of these entries is as follows:
# name:[desc=<description>:][[<pin>=<value>:]...]
#
# Example: for a programmer called PGM-1 that uses pin 2 and 3 for
# power, pins 4, 5, and 6 for RESET, SCK, and MOSI, and pin 10 for
# MISO, we could use the following entry:
#
# pgm-1 : desc=Programmer 1:vcc=2,3:reset=4:sck=5:mosi=6:miso=10
#
# Continuation lines are supported, use a backslash (\) as the last
# character of the line and the next line will included as part of the
# configuration data.
#
bsd : desc=Brian Dean's programmer:vcc=2,3,4,5:reset=7:sck=8:\
mosi=9:miso=10
dt006 : desc=Dontronics DT006:reset=4:sck=5:mosi=2:miso=11
alf : desc=Tony Freibel's programmer:vcc=2,3,4,5:buff=6:\
reset=7:sck=8:mosi=9:miso=10:errled=1:rdyled=14:pgmled=16:\
vfyled=17

View File

@ -42,6 +42,9 @@
#define IHEX_MAXDATA 256 #define IHEX_MAXDATA 256
#define MAX_LINE_LEN 256 /* max line length for ASCII format input files */
struct ihexrec { struct ihexrec {
unsigned char reclen; unsigned char reclen;
unsigned short loadofs; unsigned short loadofs;

View File

@ -52,8 +52,6 @@ enum {
FIO_WRITE FIO_WRITE
}; };
#define MAX_LINE_LEN 256 /* max line length for ASCII format input files */
char * fmtstr ( FILEFMT format ); char * fmtstr ( FILEFMT format );
int fileio_setparms ( int op, struct fioparms * fp ); int fileio_setparms ( int op, struct fioparms * fp );

View File

@ -73,12 +73,14 @@
*/ */
#include <stdio.h> #include <stdio.h>
#include <stdlib.h>
#include <errno.h> #include <errno.h>
#include <fcntl.h> #include <fcntl.h>
#include <limits.h> #include <limits.h>
#include <string.h> #include <string.h>
#include <time.h> #include <time.h>
#include <unistd.h> #include <unistd.h>
#include <ctype.h>
#include "avr.h" #include "avr.h"
#include "fileio.h" #include "fileio.h"
@ -114,6 +116,8 @@ char progbuf[PATH_MAX]; /* temporary buffer of spaces the same
length as progname; used for lining up length as progname; used for lining up
multiline messages */ multiline messages */
unsigned int pinno[N_PINS];
/* /*
* usage message * usage message
*/ */
@ -138,16 +142,18 @@ int getexitspecs ( char *s, int *set, int *clr )
while ((cp = strtok(s, ","))) { while ((cp = strtok(s, ","))) {
if (strcmp(cp, "reset") == 0) { if (strcmp(cp, "reset") == 0) {
*clr |= ppi_getpinmask(PIN_AVR_RESET); *clr |= ppi_getpinmask(pinno[PIN_AVR_RESET]);
} }
else if (strcmp(cp, "noreset") == 0) { else if (strcmp(cp, "noreset") == 0) {
*set |= ppi_getpinmask(PIN_AVR_RESET); *set |= ppi_getpinmask(pinno[PIN_AVR_RESET]);
} }
else if (strcmp(cp, "vcc") == 0) { else if (strcmp(cp, "vcc") == 0) {
*set |= PPI_AVR_VCC; if (pinno[PPI_AVR_VCC])
*set |= pinno[PPI_AVR_VCC];
} }
else if (strcmp(cp, "novcc") == 0) { else if (strcmp(cp, "novcc") == 0) {
*clr |= PPI_AVR_VCC; if (pinno[PPI_AVR_VCC])
*clr |= pinno[PPI_AVR_VCC];
} }
else { else {
return -1; return -1;
@ -259,6 +265,329 @@ int print_module_versions ( FILE * outf, char * timestamp )
#define MAX_LINE_LEN 1024
#define MAX_PIN_NAME 64
int parse_config(int lineno, char * infile, char * config, char * s,
unsigned int * pinno, char * desc, int desclen)
{
char pin_name[MAX_PIN_NAME];
char * p;
int i;
int pins;
unsigned int value;
unsigned int v;
char * e;
pins = 0;
p = s;
while (1) {
while (*p && isspace(*p))
p++;
if (*p == 0) {
if (pins == 0) {
fprintf(stderr,
"%s: warning: no pins configured using config entry \"%s\" "
"at line %d of %s\n",
progname, config, lineno, infile);
}
return 0;
}
/*
* parse the pin name
*/
pin_name[0] = 0;
i = 0;
while (*p && (i<MAX_PIN_NAME) && !((*p == '=')||isspace(*p))) {
pin_name[i++] = *p;
p++;
}
if (i == MAX_PIN_NAME) {
fprintf(stderr, "%s: pin name too long at line %d of \"%s\"\n",
progname, lineno, infile);
return -1;
}
pin_name[i] = 0;
/* skip over spaces and equals sign */
while (*p && (isspace(*p)||(*p == '=')))
p++;
if (strcasecmp(pin_name, "desc") == 0) {
i = 0;
while (*p && (i<desclen) && (*p != ':')) {
desc[i++] = *p;
p++;
}
if (i == desclen) {
fprintf(stderr,
"%s: error at line %d of %s: description is too "
"long (max = %d chars)\n",
progname, lineno, infile, desclen);
return -1;
}
desc[i] = 0;
}
else {
/*
* parse pin value
*/
value = 0;
while (*p && (*p != ':')) {
if (strcasecmp(pin_name, "desc") == 0) {
i = 0;
while (*p && (i<desclen) && (*p != ':')) {
desc[i++] = *p;
p++;
}
if (i == desclen) {
fprintf(stderr,
"%s: error at line %d of %s: description is too "
"long (max = %d chars)\n",
progname, lineno, infile, desclen);
return -1;
}
desc[i] = 0;
}
else {
v = strtoul(p, &e, 0);
if (e == p) {
fprintf(stderr,
"%s: can't parse pin value at line %d of \"%s\" "
"starting with \"%s\"\n",
progname, lineno, infile, p);
return -1;
}
if (strcasecmp(pin_name, "VCC")==0) {
/*
* VCC is a bit mask of pins for the data register, pins 2-9
*/
if ((v < 2) || (v > 9)) {
fprintf(stderr,
"%s: error at line %d of %s: VCC must be one or more "
"pins from the range 2-9\n",
progname, lineno, infile);
return -1;
}
value |= (1 << (v-2));
}
else {
if ((v <= 0) || (v >= 18)) {
fprintf(stderr,
"%s: error at line %d of %s: pin must be in the "
"range 1-17\n",
progname, lineno, infile);
return -1;
}
value = v;
}
p = e;
while (*p && (isspace(*p)||(*p == ',')))
p++;
}
if (strcasecmp(pin_name, "VCC")==0)
pinno[PPI_AVR_VCC] = value;
else if (strcasecmp(pin_name, "BUFF")==0)
pinno[PIN_AVR_BUFF] = value;
else if (strcasecmp(pin_name, "RESET")==0)
pinno[PIN_AVR_RESET] = value;
else if (strcasecmp(pin_name, "SCK")==0)
pinno[PIN_AVR_SCK] = value;
else if (strcasecmp(pin_name, "MOSI")==0)
pinno[PIN_AVR_MOSI] = value;
else if (strcasecmp(pin_name, "MISO")==0)
pinno[PIN_AVR_MISO] = value;
else if (strcasecmp(pin_name, "ERRLED")==0)
pinno[PIN_LED_ERR] = value;
else if (strcasecmp(pin_name, "RDYLED")==0)
pinno[PIN_LED_RDY] = value;
else if (strcasecmp(pin_name, "PGMLED")==0)
pinno[PIN_LED_PGM] = value;
else if (strcasecmp(pin_name, "VFYLED")==0)
pinno[PIN_LED_VFY] = value;
else {
fprintf(stderr,
"%s: error at line %d of %s: invalid pin name \"%s\"\n",
progname, lineno, infile, pin_name);
return -1;
}
pins++;
}
}
while (*p && (*p == ':'))
p++;
}
return 0;
}
int read_config(char * infile, char * config, unsigned int * pinno,
char * desc, int desclen)
{
FILE * f;
char line[MAX_LINE_LEN];
char buf[MAX_LINE_LEN];
char configname[MAX_PIN_NAME];
int len, lineno, rc, cont;
char * p, * q;
int i;
for (i=0; i<N_PINS; i++)
pinno[i] = 0;
f = fopen(infile, "r");
if (f == NULL) {
fprintf(stderr, "%s: can't open config file \"%s\": %s\n",
progname, infile, strerror(errno));
return -1;
}
lineno = 0;
buf[0] = 0;
while (fgets(line, MAX_LINE_LEN, f) != NULL) {
lineno++;
p = line;
while (isspace(*p))
p++;
if ((*p == '#')||(*p == '\n')||(*p == 0))
continue;
len = strlen(p);
if (p[len-1] == '\n') {
p[len-1] = 0;
len--;
}
cont = 0;
if (p[len-1] == '\\') {
cont = 1; /* flag that this is a continuation line */
/* trim trailing white space before continuation character */
q = &p[len-2];
while (isspace(*q))
q--;
q++;
*q = 0;
}
rc = strlcat(buf, p, MAX_LINE_LEN);
if (rc >= MAX_LINE_LEN) {
fprintf(stderr,
"%s: buffer length of %d exceed at line %d of \"%s\"\n",
progname, MAX_LINE_LEN, lineno, infile);
return -2;
}
if (cont)
continue; /* continuation line, keep going */
/*
* read the configuration name from the beginning of the line
*/
p = buf;
i = 0;
while (*p && (i < MAX_PIN_NAME) && (!(isspace(*p)||(*p == ':')))) {
configname[i++] = *p;
p++;
}
if (i == MAX_PIN_NAME) {
fprintf(stderr, "%s: configuration name too long at line %d of \"%s\"\n",
progname, lineno, infile);
return -3;
}
configname[i] = 0;
/*
* position 'p' to the beginning of the pin information
*/
while (*p && (isspace(*p) || (*p == ':')))
p++;
if (strcasecmp(configname, config) == 0) {
rc = parse_config(lineno, infile, config, p, pinno, desc, desclen);
if (rc) {
fprintf(stderr, "%s: error parsing config file \"%s\" at line %d\n",
progname, infile, lineno);
return -3;
}
return 0;
}
buf[0] = 0;
}
/*
* config entry not found
*/
fprintf(stderr, "%s: config entry \"%s\" not found in file \"%s\"\n",
progname, config, infile);
return -5;
}
void pinconfig_display(char * p, char * config, char * desc)
{
fprintf(stderr, "%sProgrammer Pin Configuration: %s (%s)\n", p,
config ? config : "DEFAULT", desc);
fprintf(stderr,
"%s VCC = 0x%02x\n"
"%s BUFF = %d\n"
"%s RESET = %d\n"
"%s SCK = %d\n"
"%s MOSI = %d\n"
"%s MISO = %d\n"
"%s ERR LED = %d\n"
"%s RDY LED = %d\n"
"%s PGM LED = %d\n"
"%s VFY LED = %d\n",
p, pinno[PPI_AVR_VCC],
p, pinno[PIN_AVR_BUFF],
p, pinno[PIN_AVR_RESET],
p, pinno[PIN_AVR_SCK],
p, pinno[PIN_AVR_MOSI],
p, pinno[PIN_AVR_MISO],
p, pinno[PIN_LED_ERR],
p, pinno[PIN_LED_RDY],
p, pinno[PIN_LED_PGM],
p, pinno[PIN_LED_VFY]);
}
void verify_pin_assigned(int pin, char * desc)
{
if (pinno[pin] == 0) {
fprintf(stderr, "%s: error: no pin has been assigned for %s\n",
progname, desc);
exit(1);
}
}
#define MAX_DESC_LEN 80
/* /*
* main routine * main routine
*/ */
@ -279,6 +608,9 @@ int main ( int argc, char * argv [] )
int ppidata; /* cached value of the ppi data register */ int ppidata; /* cached value of the ppi data register */
int vsize=-1; /* number of bytes to verify */ int vsize=-1; /* number of bytes to verify */
char timestamp[64]; char timestamp[64];
char configfile[PATH_MAX]; /* pin configuration file */
char * pinconfig;
char desc[MAX_DESC_LEN];
/* options / operating mode variables */ /* options / operating mode variables */
int memtype; /* AVR_FLASH or AVR_EEPROM */ int memtype; /* AVR_FLASH or AVR_EEPROM */
@ -309,6 +641,32 @@ int main ( int argc, char * argv [] )
nowrite = 0; nowrite = 0;
verify = 1; /* on by default; XXX can't turn it off */ verify = 1; /* on by default; XXX can't turn it off */
ppisetbits = ppiclrbits = 0; ppisetbits = ppiclrbits = 0;
pinconfig = NULL;
strcpy(configfile, CONFIG_DIR);
i = strlen(configfile);
if (i && (configfile[i-1] != '/'))
strcat(configfile, "/");
strcat(configfile, "avrprog.conf");
for (i=0; i<N_PINS; i++)
pinno[i] = 0;
/*
* default pin configuration
*/
pinno[PPI_AVR_VCC] = 0x0f; /* ppi pins 2-5, data reg bits 0-3 */
pinno[PIN_AVR_BUFF] = 0;
pinno[PIN_AVR_RESET] = 7;
pinno[PIN_AVR_SCK] = 8;
pinno[PIN_AVR_MOSI] = 9;
pinno[PIN_AVR_MISO] = 10;
pinno[PIN_LED_ERR] = 0;
pinno[PIN_LED_RDY] = 0;
pinno[PIN_LED_PGM] = 0;
pinno[PIN_LED_VFY] = 0;
strcpy(desc, "compiled in default");
progname = rindex(argv[0],'/'); progname = rindex(argv[0],'/');
if (progname) if (progname)
@ -343,9 +701,18 @@ int main ( int argc, char * argv [] )
/* /*
* process command line arguments * process command line arguments
*/ */
while ((ch = getopt(argc,argv,"?eE:f:Fi:m:no:p:P:tV")) != -1) { while ((ch = getopt(argc,argv,"?c:C:eE:f:Fi:m:no:p:P:tV")) != -1) {
switch (ch) { switch (ch) {
case 'c': /* pin configuration */
pinconfig = optarg;
break;
case 'C': /* pin configuration file */
strncpy(configfile, optarg, PATH_MAX);
configfile[PATH_MAX-1] = 0;
break;
case 'm': /* select memory type to operate on */ case 'm': /* select memory type to operate on */
if ((strcasecmp(optarg,"e")==0)||(strcasecmp(optarg,"eeprom")==0)) { if ((strcasecmp(optarg,"e")==0)||(strcasecmp(optarg,"eeprom")==0)) {
memtype = AVR_EEPROM; memtype = AVR_EEPROM;
@ -482,6 +849,19 @@ int main ( int argc, char * argv [] )
return 1; return 1;
} }
/*
* read the parallel port pin configuration to use if requested
*/
if (pinconfig != NULL) {
rc = read_config(configfile, pinconfig, pinno, desc, MAX_DESC_LEN);
if (rc) {
fprintf(stderr, "%s: error reading \"%s\" configuration from \"%s\"\n",
progname, pinconfig, configfile);
exit(1);
}
}
/* /*
* set up seperate instances of the avr part, one for use in * set up seperate instances of the avr part, one for use in
* programming, one for use in verifying. These are separate * programming, one for use in verifying. These are separate
@ -497,9 +877,17 @@ int main ( int argc, char * argv [] )
avr_initmem(v); avr_initmem(v);
avr_display(stderr, p, progbuf); avr_display(stderr, p, progbuf);
#if 1
pinconfig_display(progbuf, pinconfig, desc);
#endif
fprintf(stderr, "\n"); fprintf(stderr, "\n");
verify_pin_assigned(PIN_AVR_RESET, "AVR RESET");
verify_pin_assigned(PIN_AVR_SCK, "AVR SCK");
verify_pin_assigned(PIN_AVR_MISO, "AVR MISO");
verify_pin_assigned(PIN_AVR_MOSI, "AVR MOSI");
/* /*
* open the parallel port * open the parallel port
*/ */
@ -529,15 +917,15 @@ int main ( int argc, char * argv [] )
/* /*
* turn off all the status leds * turn off all the status leds
*/ */
LED_OFF(fd, PIN_LED_RDY); LED_OFF(fd, pinno[PIN_LED_RDY]);
LED_OFF(fd, PIN_LED_ERR); LED_OFF(fd, pinno[PIN_LED_ERR]);
LED_OFF(fd, PIN_LED_PGM); LED_OFF(fd, pinno[PIN_LED_PGM]);
LED_OFF(fd, PIN_LED_VFY); LED_OFF(fd, pinno[PIN_LED_VFY]);
/* /*
* enable the 74367 buffer, if connected; this signal is active low * enable the 74367 buffer, if connected; this signal is active low
*/ */
ppi_setpin(fd, PIN_AVR_BUFF, 0); ppi_setpin(fd, pinno[PIN_AVR_BUFF], 0);
/* /*
* initialize the chip in preperation for accepting commands * initialize the chip in preperation for accepting commands
@ -550,7 +938,7 @@ int main ( int argc, char * argv [] )
} }
/* indicate ready */ /* indicate ready */
LED_ON(fd, PIN_LED_RDY); LED_ON(fd, pinno[PIN_LED_RDY]);
fprintf ( stderr, fprintf ( stderr,
"%s: AVR device initialized and ready to accept instructions\n", "%s: AVR device initialized and ready to accept instructions\n",
@ -692,7 +1080,7 @@ int main ( int argc, char * argv [] )
* verify that the in memory file (p->mem[AVR_FLASH|AVR_EEPROM]) * verify that the in memory file (p->mem[AVR_FLASH|AVR_EEPROM])
* is the same as what is on the chip * is the same as what is on the chip
*/ */
LED_ON(fd, PIN_LED_VFY); LED_ON(fd, pinno[PIN_LED_VFY]);
fprintf(stderr, "%s: verifying %s memory against %s:\n", fprintf(stderr, "%s: verifying %s memory against %s:\n",
progname, avr_memtstr(memtype), inputf); progname, avr_memtstr(memtype), inputf);
@ -702,7 +1090,7 @@ int main ( int argc, char * argv [] )
if (rc < 0) { if (rc < 0) {
fprintf(stderr, "%s: failed to read all of %s memory, rc=%d\n", fprintf(stderr, "%s: failed to read all of %s memory, rc=%d\n",
progname, avr_memtstr(memtype), rc); progname, avr_memtstr(memtype), rc);
LED_ON(fd, PIN_LED_ERR); LED_ON(fd, pinno[PIN_LED_ERR]);
exitrc = 1; exitrc = 1;
goto main_exit; goto main_exit;
} }
@ -712,7 +1100,7 @@ int main ( int argc, char * argv [] )
if (rc < 0) { if (rc < 0) {
fprintf(stderr, "%s: verification error; content mismatch\n", fprintf(stderr, "%s: verification error; content mismatch\n",
progname); progname);
LED_ON(fd, PIN_LED_ERR); LED_ON(fd, pinno[PIN_LED_ERR]);
exitrc = 1; exitrc = 1;
goto main_exit; goto main_exit;
} }
@ -720,7 +1108,7 @@ int main ( int argc, char * argv [] )
fprintf(stderr, "%s: %d bytes of %s verified\n", fprintf(stderr, "%s: %d bytes of %s verified\n",
progname, rc, avr_memtstr(memtype)); progname, rc, avr_memtstr(memtype));
LED_OFF(fd, PIN_LED_VFY); LED_OFF(fd, pinno[PIN_LED_VFY]);
} }
@ -737,9 +1125,9 @@ int main ( int argc, char * argv [] )
/* /*
* disable the 74367 buffer, if connected; this signal is active low * disable the 74367 buffer, if connected; this signal is active low
*/ */
ppi_setpin(fd, PIN_AVR_BUFF, 1); ppi_setpin(fd, pinno[PIN_AVR_BUFF], 1);
LED_OFF(fd, PIN_LED_RDY); LED_OFF(fd, pinno[PIN_LED_RDY]);
close(fd); close(fd);

View File

@ -32,6 +32,24 @@
#ifndef __pindefs_h__ #ifndef __pindefs_h__
#define __pindefs_h__ #define __pindefs_h__
#if 1
enum {
PPI_AVR_VCC=1,
PIN_AVR_BUFF,
PIN_AVR_RESET,
PIN_AVR_SCK,
PIN_AVR_MOSI,
PIN_AVR_MISO,
PIN_LED_ERR,
PIN_LED_RDY,
PIN_LED_PGM,
PIN_LED_VFY,
N_PINS
};
extern unsigned int pinno[N_PINS];
#else
#define PPI_AVR_VCC 0x0f /* ppi pins 2-5, data reg bits 0-3 */ #define PPI_AVR_VCC 0x0f /* ppi pins 2-5, data reg bits 0-3 */
#define PIN_AVR_BUFF 6 #define PIN_AVR_BUFF 6
#define PIN_AVR_RESET 7 #define PIN_AVR_RESET 7
@ -42,6 +60,7 @@
#define PIN_LED_RDY 14 #define PIN_LED_RDY 14
#define PIN_LED_PGM 16 #define PIN_LED_PGM 16
#define PIN_LED_VFY 17 #define PIN_LED_VFY 17
#endif
#define LED_ON(fd,pin) ppi_setpin(fd,pin,0) #define LED_ON(fd,pin) ppi_setpin(fd,pin,0)
#define LED_OFF(fd,pin) ppi_setpin(fd,pin,1) #define LED_OFF(fd,pin) ppi_setpin(fd,pin,1)

View File

@ -355,7 +355,7 @@ int cmd_write ( int fd, struct avrpart * p, int argc, char * argv[] )
} }
} }
LED_OFF(fd, PIN_LED_ERR); LED_OFF(fd, pinno[PIN_LED_ERR]);
for (werror=0, i=0; i<len; i++) { for (werror=0, i=0; i<len; i++) {
rc = avr_write_byte(fd, p, memtype, addr+i, buf[i]); rc = avr_write_byte(fd, p, memtype, addr+i, buf[i]);
if (rc) { if (rc) {
@ -364,7 +364,7 @@ int cmd_write ( int fd, struct avrpart * p, int argc, char * argv[] )
werror = 1; werror = 1;
} }
if (werror) { if (werror) {
LED_ON(fd, PIN_LED_ERR); LED_ON(fd, pinno[PIN_LED_ERR]);
} }
} }