Makefile: add --pedantic compiler option

avrprog.c:

	Add lots of comments, move getop() variable declarations to
	the top of the program.

	Add a typedef name to the AVR memory type and use it for
	function declarations.

	Add a usleep() delay in the sense loop to avoid becoming a cpu
	hog.

	Print out a version string so that folks know what version of
	the software they are running.

	Be sure and close the parallel device and the i/o file when
	terminating abnormally.


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk/avrdude@8 81a1dc3b-b13d-400b-aceb-764788c761c2
This commit is contained in:
Brian S. Dean 2000-08-06 19:47:03 +00:00
parent 0cd28888ba
commit 825a13d702
2 changed files with 214 additions and 35 deletions

View File

@ -8,7 +8,7 @@ DEST = ${HOME}/bin/0.${ARCH}
all : ${TARGET}
CFLAGS = -Wall
CFLAGS = -Wall --pedantic
${TARGET} : avrprog.c
${CC} ${CFLAGS} -o ${TARGET} avrprog.c

247
avrprog.c
View File

@ -62,6 +62,9 @@ char * version = "$Id$";
char * progname;
/*
* bit definitions for AVR device connections
*/
#define AVR_POWER 0x01 /* bit 0 of data register */
#define AVR_CLOCK 0x02 /* bit 1 of data register */
#define AVR_INSTR 0x04 /* bit 2 of data register */
@ -69,6 +72,9 @@ char * progname;
#define AVR_DATA 0x40 /* bit 6 of status register */
/*
* PPI registers
*/
enum {
PPIDATA,
PPICTRL,
@ -76,14 +82,31 @@ enum {
};
enum {
/*
* AVR memory designations
*/
typedef enum {
AVR_EEPROM,
AVR_FLASH,
AVR_FLASH_LO,
AVR_FLASH_HI
};
} AVRMEM;
/*
* variable declarations required for getopt()
*/
char *optarg;
int optind;
int optopt;
int opterr;
int optreset;
/*
* set 'get' and 'set' appropriately for subsequent passage to ioctl()
* to get/set the specified PPI registers.
*/
int ppi_getops ( int reg, unsigned long * get, unsigned long * set )
{
switch (reg) {
@ -110,6 +133,9 @@ int ppi_getops ( int reg, unsigned long * get, unsigned long * set )
}
/*
* set the indicated bit of the specified register.
*/
int ppi_set ( int fd, int reg, int bit )
{
unsigned char v;
@ -128,6 +154,9 @@ int ppi_set ( int fd, int reg, int bit )
}
/*
* clear the indicated bit of the specified register.
*/
int ppi_clr ( int fd, int reg, int bit )
{
unsigned char v;
@ -146,6 +175,9 @@ int ppi_clr ( int fd, int reg, int bit )
}
/*
* get the indicated bit of the specified register.
*/
int ppi_get ( int fd, int reg, int bit )
{
unsigned char v;
@ -163,6 +195,9 @@ int ppi_get ( int fd, int reg, int bit )
}
/*
* toggle the indicated bit of the specified register.
*/
int ppi_toggle ( int fd, int reg, int bit )
{
unsigned char v;
@ -184,6 +219,9 @@ int ppi_toggle ( int fd, int reg, int bit )
}
/*
* transmit and receive a bit of data to/from the AVR device
*/
int avr_txrx_bit ( int fd, int bit )
{
unsigned char d;
@ -204,6 +242,9 @@ int avr_txrx_bit ( int fd, int bit )
}
/*
* transmit and receive a byte of data to/from the AVR device
*/
unsigned char avr_txrx ( int fd, unsigned char byte )
{
int i;
@ -220,7 +261,11 @@ unsigned char avr_txrx ( int fd, unsigned char byte )
}
int avr_cmd ( int fd, unsigned char * cmd, unsigned char * res )
/*
* transmit an AVR device command and return the results; 'cmd' and
* 'res' must point to at least a 4 byte data buffer
*/
int avr_cmd ( int fd, unsigned char cmd[4], unsigned char res[4] )
{
int i;
@ -232,7 +277,10 @@ int avr_cmd ( int fd, unsigned char * cmd, unsigned char * res )
}
unsigned char avr_read_byte ( int fd, int memtype, unsigned short addr )
/*
* read a byte of data from the indicated memory region
*/
unsigned char avr_read_byte ( int fd, AVRMEM memtype, unsigned short addr )
{
unsigned char cmd[4];
unsigned char res[4];
@ -265,7 +313,12 @@ unsigned char avr_read_byte ( int fd, int memtype, unsigned short addr )
}
int avr_read ( int fd, int memtype, unsigned start, unsigned n,
/*
* read 'n' words of data from the indicated memory region. If the
* flash memory is being read, n*2 bytes will be read into 'buf'; if
* the eeprom is being read, 'n' bytes will be read into 'buf'.
*/
int avr_read ( int fd, AVRMEM memtype, unsigned start, unsigned n,
unsigned char * buf, int bufsize )
{
unsigned char rbyte, memt;
@ -313,7 +366,10 @@ int avr_read ( int fd, int memtype, unsigned start, unsigned n,
}
int avr_write_byte ( int fd, int memtype, unsigned short addr, unsigned char data )
/*
* write a byte of data to the indicated memory region
*/
int avr_write_byte ( int fd, AVRMEM memtype, unsigned short addr, unsigned char data )
{
unsigned char cmd[4], res[4];
unsigned char r;
@ -371,7 +427,10 @@ int avr_write_byte ( int fd, int memtype, unsigned short addr, unsigned char dat
}
int avr_write ( int fd, int memtype, unsigned start,
/*
* write 'bufsize' bytes of data to the indicated memory region.
*/
int avr_write ( int fd, AVRMEM memtype, unsigned start,
unsigned char * buf, int bufsize )
{
unsigned char data, memt;
@ -427,7 +486,9 @@ int avr_write ( int fd, int memtype, unsigned start,
return 0;
}
/*
* issue the 'program enable' command to the AVR device
*/
int avr_program_enable ( int fd )
{
unsigned char cmd[4] = {0xac, 0x53, 0x00, 0x00};
@ -442,6 +503,9 @@ int avr_program_enable ( int fd )
}
/*
* issue the 'chip erase' command to the AVR device
*/
int avr_chip_erase ( int fd )
{
unsigned char data[4] = {0xac, 0x80, 0x00, 0x00};
@ -455,7 +519,10 @@ int avr_chip_erase ( int fd )
}
int avr_signature ( int fd, char sig[4] )
/*
* read the AVR device's signature bytes
*/
int avr_signature ( int fd, unsigned char sig[4] )
{
unsigned char cmd[4] = {0x30, 0x00, 0x00, 0x00};
unsigned char res[4];
@ -471,6 +538,9 @@ int avr_signature ( int fd, char sig[4] )
}
/*
* apply power to the AVR processor
*/
void avr_powerup ( int fd )
{
ppi_set(fd, PPIDATA, AVR_POWER); /* power up */
@ -478,12 +548,18 @@ void avr_powerup ( int fd )
}
/*
* remove power from the AVR processor
*/
void avr_powerdown ( int fd )
{
ppi_clr(fd, PPIDATA, AVR_POWER); /* power down */
}
/*
* initialize the AVR device and prepare it to accept commands
*/
int avr_initialize ( int fd )
{
int rc;
@ -497,6 +573,10 @@ int avr_initialize ( int fd )
usleep(20000); /* 20 ms */
/*
* enable programming mode, try up to 32 times in order to possibly
* get back into sync with the chip if we are out of sync.
*/
tries = 0;
do {
rc = avr_program_enable ( fd );
@ -505,23 +585,36 @@ int avr_initialize ( int fd )
ppi_toggle(fd, PPIDATA, AVR_CLOCK);
tries++;
} while (tries < 32);
/*
* can't sync with the device, maybe it's not attached?
*/
if (tries == 32) {
fprintf ( stderr, "%s: AVR device not responding\n", progname );
return -1;
}
return 0;
}
/*
* infinite loop, sensing on the pin that we use to read data out of
* the device; this is a debugging aid, you can insert a call to this
* function in 'main()' and can use it to determine whether your sense
* pin is actually sensing.
*/
int ppi_sense_test ( int fd )
{
unsigned char v, pv;
pv = 1;
do {
usleep(100000); /* check every 100 ms */
v = ppi_get(fd, PPISTATUS, AVR_DATA);
if (v != pv) {
fprintf ( stderr, "PPISTATUS bit = %d\n", v );
fprintf ( stderr, "sense bit = %d\n", v );
}
pv = v;
} while(1);
@ -530,15 +623,9 @@ int ppi_sense_test ( int fd )
}
/* vars for getopt() */
char *optarg;
int optind;
int optopt;
int opterr;
int optreset;
/*
* usage message
*/
void usage ( void )
{
fprintf ( stderr,
@ -555,10 +642,14 @@ void usage ( void )
}
/*
* main routine
*/
int main ( int argc, char * argv [] )
{
int fd;
int rc;
int i;
unsigned char buf[2048];
unsigned char sig[4];
int ch;
@ -567,6 +658,7 @@ int main ( int argc, char * argv [] )
int size;
char * outputf;
char * inputf;
char * p1, * p2;
iofd = -1;
outputf = NULL;
@ -583,36 +675,69 @@ int main ( int argc, char * argv [] )
else
progname = argv[0];
fprintf(stderr, "%s, Version Information: %s\n", progname, version);
/*
* Print out an identifying string so folks can tell what version
* they are running
*/
fprintf(stderr, "\n");
p1 = strchr(version,',');
if (p1 == NULL)
p1 = version;
else
p1 += 3;
p2 = strrchr(p1,':');
if (p2 == NULL)
p2 = &p1[strlen(p1)];
else
p2 += 3;
fprintf(stderr, "%s, Revision ", progname );
for (i=0; i<p2-p1; i++)
fprintf(stderr, "%c", p1[i]);
fprintf(stderr, "\n");
rc = strlen(progname);
for (i=0; i<rc+2; i++)
fprintf(stderr, "%c", ' ');
fprintf(stderr, "Author: Brian Dean, bsd@bsdhome.com\n");
/*
* check for no arguments
*/
if (argc == 1) {
usage();
return 0;
}
/*
* process command line arguments
*/
while ((ch = getopt(argc,argv,"?efo:rsu:")) != -1) {
switch (ch) {
case 'e':
case 'e': /* select eeprom memory */
if (flash) {
fprintf(stderr,"%s: -e and -f are incompatible\n", progname);
return 1;
}
eeprom = 1;
break;
case 'r':
case 'r': /* perform a chip erase */
erase = 1;
break;
case 's':
case 's': /* read out the signature bytes */
dosig = 1;
break;
case 'f':
case 'f': /* select flash memory */
if (eeprom) {
fprintf(stderr,"%s: -e and -f are incompatible\n", progname);
return 1;
}
flash = 1;
break;
case 'o':
case 'o': /* specify output file */
if (inputf) {
fprintf(stderr,"%s: -o and -u are incompatible\n", progname);
return 1;
@ -632,7 +757,7 @@ int main ( int argc, char * argv [] )
}
}
break;
case 'u':
case 'u': /* specify input (upload) file */
if (outputf) {
fprintf(stderr,"%s: -o and -u are incompatible\n", progname);
return 1;
@ -646,7 +771,7 @@ int main ( int argc, char * argv [] )
return 1;
}
break;
case '?':
case '?': /* help */
usage();
return 1;
break;
@ -658,6 +783,10 @@ int main ( int argc, char * argv [] )
}
}
/*
* open the parallel port
*/
fd = open ( PARALLEL, O_RDWR );
if (fd < 0) {
fprintf ( stderr, "%s: can't open device \"%s\": %s\n",
@ -665,7 +794,10 @@ int main ( int argc, char * argv [] )
return 1;
}
fprintf ( stderr, "%s: initializing\n", progname );
/*
* initialize the chip in preperation for accepting commands
*/
rc = avr_initialize(fd);
if (rc < 0) {
fprintf ( stderr, "%s: initialization failed, rc=%d\n", progname, rc );
@ -676,15 +808,23 @@ int main ( int argc, char * argv [] )
fprintf ( stderr, "%s: AVR device initialized and ready to accept instructions\n",
progname );
if (erase) {
/*
* erase the chip's flash and eeprom memories, this is required
* before the chip can accept new programming
*/
fprintf(stderr, "%s: erasing chip\n", progname );
avr_chip_erase(fd);
avr_initialize(fd);
fprintf(stderr, "%s: done.\n", progname );
}
if (dosig) {
int i;
/*
* read out the on-chip signature bytes
*/
fprintf(stderr, "%s: reading signature bytes: ", progname );
avr_signature(fd, sig);
for (i=0; i<4; i++)
@ -692,7 +832,14 @@ int main ( int argc, char * argv [] )
fprintf(stderr, "\n");
}
if (iofd < 0) {
/*
* Check here to see if any other operations were selected and
* generate an error message because if they were, we need either
* an input or and output file, but one was not selected.
* Otherwise, we just shut down.
*/
if (eeprom||flash) {
fprintf(stderr, "%s: you must specify an input or an output file\n",
progname);
@ -702,17 +849,25 @@ int main ( int argc, char * argv [] )
return 1;
}
if (!(eeprom||flash)) {
/*
* an input file or an output file was specified, but the memory
* type (eeprom or flash) was not specified.
*/
fprintf(stderr,
"%s: please specify either the eeprom (-e) or the flash (-f) memory\n",
progname);
avr_powerdown(fd);
close(fd);
close(iofd);
return 1;
}
if (doread) {
/*
* read device memory
* read out the specified device memory and write it to a file
*/
if (flash) {
size = 2048;
@ -722,6 +877,8 @@ int main ( int argc, char * argv [] )
fprintf ( stderr, "%s: failed to read all of flash memory, rc=%d\n",
progname, rc );
avr_powerdown(fd);
close(fd);
close(iofd);
return 1;
}
}
@ -733,26 +890,35 @@ int main ( int argc, char * argv [] )
fprintf ( stderr, "%s: failed to read all of eeprom memory, rc=%d\n",
progname, rc );
avr_powerdown(fd);
close(fd);
close(iofd);
return 1;
}
}
/*
* write it out to the specified file
*/
rc = write ( iofd, buf, size );
if (rc < 0) {
fprintf(stderr, "%s: write error: %s\n", progname, strerror(errno));
avr_powerdown(fd);
close(fd);
close(iofd);
return 1;
}
else if (rc != size) {
fprintf(stderr, "%s: wrote only %d bytes of the expected %d\n",
progname, rc, size);
avr_powerdown(fd);
close(fd);
close(iofd);
return 1;
}
}
else {
/*
* write device memory
* write the selected device memory using data from a file
*/
if (flash) {
size = 2048;
@ -761,17 +927,24 @@ int main ( int argc, char * argv [] )
size = 128;
}
/* read in the data file */
/*
* read in the data file that will be used to write into the chip
*/
rc = read(iofd, buf, size);
if (rc < 0) {
fprintf(stderr, "%s: read error from \"%s\": %s\n",
progname, inputf, strerror(errno));
avr_powerdown(fd);
close(fd);
close(iofd);
return 1;
}
size = rc;
/*
* write the buffer contents to the selected memory type
*/
if (flash) {
fprintf(stderr, "%s: writing %d bytes into flash memory:\n",
progname, size);
@ -780,6 +953,8 @@ int main ( int argc, char * argv [] )
fprintf ( stderr, "%s: failed to write flash memory, rc=%d\n",
progname, rc );
avr_powerdown(fd);
close(fd);
close(iofd);
return 1;
}
}
@ -791,17 +966,21 @@ int main ( int argc, char * argv [] )
fprintf ( stderr, "%s: failed to write eeprom memory, rc=%d\n",
progname, rc );
avr_powerdown(fd);
close(fd);
close(iofd);
return 1;
}
}
}
avr_powerdown(fd);
/*
* normal program completion
*/
avr_powerdown(fd);
close(fd);
close(iofd);
return 0;
}