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:
parent
e87b062769
commit
6981b65d59
|
@ -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 $@
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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 );
|
||||||
|
|
422
avrdude/main.c
422
avrdude/main.c
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue