diff --git a/Makefile b/Makefile index fabd1ac1..76ba5b20 100644 --- a/Makefile +++ b/Makefile @@ -4,6 +4,8 @@ TARGET = avrprog +DEST = ${HOME}/bin/0.${ARCH} + all : ${TARGET} CFLAGS = -Wall @@ -14,3 +16,8 @@ ${TARGET} : avrprog.c clean : rm -f *.o ${TARGET} *~ +install : ${DEST}/${TARGET} + +${DEST}/${TARGET} : ${TARGET} + cp -p ${TARGET} $@ + diff --git a/avrprog.c b/avrprog.c index 9cd3cf2a..da13a96a 100644 --- a/avrprog.c +++ b/avrprog.c @@ -1,19 +1,46 @@ /* - * Copyright 2000, Brian Dean + * 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 device using the parallel port. + * Code to program an Atmel AVR AT90S device using the parallel port. * * Make the following connections: * - * Pin 2 -> PB7(SCK) CLOCK IN (data bit 0) - * Pin 3 -> PB5(MOSI) Instruction input (data bit 1) - * Pin 4 -> /RESET (data bit 2) - * Pin 10 <- PB6(MISO) Data out (status bit 6) + * Parallel Port Atmel AVR + * ------------- ---------------------------- + * Pin 2 -> Vcc + * Pin 3 -> PB7(SCK) CLOCK IN + * Pin 4 -> PB5(MOSI) Instruction input + * Pin 5 -> /RESET + * Pin 10 <- PB6(MISO) Data out * */ @@ -33,9 +60,10 @@ char * progname; -#define AVR_CLOCK 0x01 /* bit 0 of data register */ -#define AVR_INSTR 0x02 /* bit 1 of data register */ -#define AVR_RESET 0x04 /* bit 2 of data register */ +#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 */ +#define AVR_RESET 0x08 /* bit 3 of data register */ #define AVR_DATA 0x40 /* bit 6 of status register */ @@ -54,23 +82,6 @@ enum { }; -int dprintf ( FILE * f, char * format, ... ) -{ -#if DEBUG - va_list ap; - int rc; - - va_start(ap,format); - rc = vfprintf(f,format,ap); - va_end(ap); - - return rc; -#else - return 0; -#endif -} - - int ppi_getops ( int reg, unsigned long * get, unsigned long * set ) { switch (reg) { @@ -207,19 +218,32 @@ unsigned char avr_txrx ( int fd, unsigned char byte ) } -unsigned char avr_read_byte ( int fd, unsigned short addr, int memtype ) +int avr_cmd ( int fd, unsigned char * cmd, unsigned char * res ) { - unsigned char r; + int i; + + for (i=0; i<4; i++) { + res[i] = avr_txrx(fd, cmd[i]); + } + + return 0; +} + + +unsigned char avr_read_byte ( int fd, int memtype, unsigned short addr ) +{ + unsigned char cmd[4]; + unsigned char res[4]; switch (memtype) { case AVR_FLASH_LO: - avr_txrx(fd, 0x20); + cmd[0] = 0x20; break; case AVR_FLASH_HI: - avr_txrx(fd, 0x28); + cmd[0] = 0x28; break; case AVR_EEPROM: - avr_txrx(fd, 0xa0); + cmd[0] = 0xa0; addr &= 0x7f; break; default: @@ -229,24 +253,28 @@ unsigned char avr_read_byte ( int fd, unsigned short addr, int memtype ) break; } - avr_txrx(fd, addr >> 8); /* high order bits of address */ - avr_txrx(fd, addr & 0x0ff); /* low order bits of address */ - r = avr_txrx(fd, 0); /* don't care */ + cmd[1] = addr >> 8; /* high order bits of address */ + cmd[2] = addr & 0x0ff; /* low order bits of address */ + cmd[3] = 0; /* don't care */ - return r; + avr_cmd(fd, cmd, res); + + return res[3]; } int avr_read ( int fd, int memtype, unsigned start, unsigned n, unsigned char * buf, int bufsize ) { - unsigned char rbyte; - unsigned short data; + unsigned char rbyte, memt; unsigned short end, i, bi; switch (memtype) { - case AVR_FLASH : + case AVR_FLASH : + memt = AVR_FLASH_LO; + break; case AVR_EEPROM : + memt = memtype; break; default: fprintf(stderr, "%s: avr_read(); internal error: invalid memtype=%d\n", @@ -260,29 +288,21 @@ int avr_read ( int fd, int memtype, unsigned start, unsigned n, bi = 0; for (i=start; i> 8); /* high order bits of address */ - avr_txrx(fd, addr & 0x0ff); /* low order bits of address */ - avr_txrx(fd, data); /* data */ + cmd[1] = addr >> 8; /* high order bits of address */ + cmd[2] = addr & 0x0ff; /* low order bits of address */ + cmd[3] = data; /* data */ + + avr_cmd(fd, cmd, res); tries = 0; ready = 0; while (!ready) { usleep(5000); /* flash write delay */ - r = avr_read_byte ( fd, addr, memtype ); + r = avr_read_byte(fd, memtype, addr); if (data == 0x7f) { - usleep(20000); + usleep(20000); /* long delay for 0x7f since polling doesn't work */ ready = 1; } else if (r == data) { ready = 1; } + tries++; if (!ready && tries > 10) { - fprintf(stderr, "**" ); - ready = 1; + /* + * we couldn't write the data, indicate our displeasure by + * returning an error code + */ + return -1; } } @@ -343,17 +370,21 @@ int avr_write_byte ( int fd, int memtype, unsigned short addr, unsigned char dat int avr_write ( int fd, int memtype, unsigned start, - unsigned char * buf, int size ) + unsigned char * buf, int bufsize ) { - unsigned char data; + unsigned char data, memt; unsigned short end, i, bi; + int nl; + int rc; switch (memtype) { case AVR_FLASH : - end = start+size/2; + end = start+bufsize/2; + memt = AVR_FLASH_LO; break; case AVR_EEPROM : - end = start+size; + end = start+bufsize; + memt = memtype; break; default: fprintf(stderr, "%s: avr_write(); internal error: invalid memtype=%d\n", @@ -365,23 +396,28 @@ int avr_write ( int fd, int memtype, unsigned start, bi = 0; for (i=start; i