From 799081f34cdd45301f714a88cefcc47c19fd9d1c Mon Sep 17 00:00:00 2001 From: "Brian S. Dean" Date: Sun, 14 Oct 2001 02:53:21 +0000 Subject: [PATCH] First cut at supporting the ATmega 103 which uses bank addressing and has a 128K flash. Due to the bank addressing required, interactive update of the flash is not supported, though the eeprom can be updated interactively. Both memories can be programmed via non-interactive mode. Intel Hex Record type '04' is now generated as required for outputing memory contents that go beyond 64K. git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@78 81a1dc3b-b13d-400b-aceb-764788c761c2 --- avrdude/Makefile | 2 +- avrdude/avr.c | 107 +++++++++++++++++++++++++++++++++++++---------- avrdude/avr.h | 7 +++- avrdude/fileio.c | 24 +++++++++-- avrdude/term.c | 7 ++++ 5 files changed, 119 insertions(+), 28 deletions(-) diff --git a/avrdude/Makefile b/avrdude/Makefile index e5530e20..6c919665 100644 --- a/avrdude/Makefile +++ b/avrdude/Makefile @@ -17,7 +17,7 @@ DIRS = ${BINDIR} ${MANDIR} ${DOCDIR} ${CONFIGDIR} INSTALL = /usr/bin/install -c -o root -g wheel -CFLAGS += -g -Wall --pedantic -DCONFIG_DIR=\"${CONFIGDIR}\" +CFLAGS = -g -Wall --pedantic -DCONFIG_DIR=\"${CONFIGDIR}\" LDFLAGS = diff --git a/avrdude/avr.c b/avrdude/avr.c index ac944834..381dbbec 100644 --- a/avrdude/avr.c +++ b/avrdude/avr.c @@ -78,8 +78,8 @@ struct avrpart parts[] = { {{0, 512, 0, 0, 9000, 20000, {0x00, 0xff }, NULL}, /* eeprom */ {0, 8192, 0, 0, 9000, 20000, {0xff, 0x00 }, NULL}}}, /* flash */ - {"ATMEGA103", "103", 20000, - {{0, 4096, 0, 0, 9000, 20000, {0x00, 0xff }, NULL}, /* eeprom */ + {"ATMEGA103", "103", 56000*2, + {{0, 4096, 0, 0, 64000, 69000, {0x80, 0x7f }, NULL}, /* eeprom */ {1, 131072, 256, 512, 22000, 56000, {0xff, 0x00 }, NULL}}}, /* flash */ }; @@ -181,7 +181,7 @@ int avr_cmd(int fd, unsigned char cmd[4], unsigned char res[4]) * read a byte of data from the indicated memory region */ unsigned char avr_read_byte(int fd, struct avrpart * p, - int memtype, unsigned short addr) + int memtype, unsigned long addr) { unsigned short offset; unsigned char cmd[4]; @@ -221,7 +221,7 @@ unsigned char avr_read_byte(int fd, struct avrpart * p, int avr_read(int fd, struct avrpart * p, int memtype) { unsigned char rbyte; - unsigned short i; + unsigned long i; unsigned char * buf; int size; @@ -230,7 +230,7 @@ int avr_read(int fd, struct avrpart * p, int memtype) for (i=0; i> 8; /* high order bits of address */ + cmd[2] = bank & 0x0ff; /* low order bits of address */ + cmd[3] = 0; /* these bits are ignored */ + + avr_cmd(fd, cmd, res); + + /* + * since we don't know what voltage the target AVR is powered by, be + * conservative and delay the max amount the spec says to wait + */ + usleep(p->mem[memtype].max_write_delay); + + LED_OFF(fd, pinno[PIN_LED_PGM]); + return 0; +} + + /* * write a byte of data to the indicated memory region */ int avr_write_byte(int fd, struct avrpart * p, int memtype, - unsigned short addr, unsigned char data) + unsigned long addr, unsigned char data) { unsigned char cmd[4]; unsigned char res[4]; @@ -257,13 +287,19 @@ int avr_write_byte(int fd, struct avrpart * p, int memtype, /* order here is very important, AVR_M_EEPROM, AVR_M_FLASH, AVR_M_FLASH+1 */ static unsigned char cmdbyte[3] = { 0xc0, 0x40, 0x48 }; - /* - * check to see if the write is necessary by reading the existing - * value and only write if we are changing the value - */ - b = avr_read_byte(fd, p, memtype, addr); - if (b == data) { - return 0; + if (!p->mem[memtype].banked) { + /* + * check to see if the write is necessary by reading the existing + * value and only write if we are changing the value; we can't + * use this optimization for banked addressing. + */ + b = avr_read_byte(fd, p, memtype, addr); + if (b == data) { + return 0; + } + } + else { + addr = addr % p->mem[memtype].bank_size; } LED_ON(fd, pinno[PIN_LED_PGM]); @@ -280,10 +316,20 @@ int avr_write_byte(int fd, struct avrpart * p, int memtype, cmd[0] = cmdbyte[memtype + offset]; cmd[1] = caddr >> 8; /* high order bits of address */ cmd[2] = caddr & 0x0ff; /* low order bits of address */ - cmd[3] = data; /* data */ + cmd[3] = data; /* data */ avr_cmd(fd, cmd, res); + if (p->mem[memtype].banked) { + /* + * in banked addressing, single bytes to written to the memory + * page complete immediately, we only need to delay when we commit + * the whole page via the avr_write_bank() routine. + */ + LED_OFF(fd, pinno[PIN_LED_PGM]); + return 0; + } + tries = 0; ready = 0; while (!ready) { @@ -298,14 +344,15 @@ int avr_write_byte(int fd, struct avrpart * p, int memtype, * specified for the chip. */ usleep(p->mem[memtype].max_write_delay); - ready = 1; + r = avr_read_byte(fd, p, memtype, addr); } - else if (r == data) { + + if (r == data) { ready = 1; } tries++; - if (!ready && tries > 10) { + if (!ready && tries > 5) { /* * we couldn't write the data, indicate our displeasure by * returning an error code @@ -335,8 +382,7 @@ int avr_write(int fd, struct avrpart * p, int memtype, int size) { int rc; int wsize; - unsigned char * buf; - unsigned short i; + unsigned long i; unsigned char data; int werror; @@ -344,7 +390,6 @@ int avr_write(int fd, struct avrpart * p, int memtype, int size) werror = 0; - buf = p->mem[memtype].buf; wsize = p->mem[memtype].size; if (size < wsize) { wsize = size; @@ -359,15 +404,32 @@ int avr_write(int fd, struct avrpart * p, int memtype, int size) for (i=0; imem[memtype].buf[i]; rc = avr_write_byte(fd, p, memtype, i, data); - fprintf(stderr, " \r%4u 0x%02x", i, data); + fprintf(stderr, " \r%4lu 0x%02x", i, data); if (rc) { fprintf(stderr, " ***failed; "); fprintf(stderr, "\n"); LED_ON(fd, pinno[PIN_LED_ERR]); werror = 1; } + + if (p->mem[memtype].banked) { + if (((i % p->mem[memtype].bank_size) == p->mem[memtype].bank_size-1) || + (i == wsize-1)) { + rc = avr_write_bank(fd, p, memtype, i/p->mem[memtype].bank_size); + if (rc) { + fprintf(stderr, + " *** bank %ld (addresses 0x%04lx - 0x%04lx) failed to write\n", + i % p->mem[memtype].bank_size, + i-p->mem[memtype].bank_size+1, i); + fprintf(stderr, "\n"); + LED_ON(fd, pinno[PIN_LED_ERR]); + werror = 1; + } + } + } + if (werror) { /* * make sure the error led stay on if there was a previous write @@ -377,6 +439,7 @@ int avr_write(int fd, struct avrpart * p, int memtype, int size) } } + fprintf(stderr, "\n"); return i; diff --git a/avrdude/avr.h b/avrdude/avr.h index 963f9057..c4b04d0a 100644 --- a/avrdude/avr.h +++ b/avrdude/avr.h @@ -110,12 +110,15 @@ unsigned char avr_txrx(int fd, unsigned char byte); int avr_cmd(int fd, unsigned char cmd[4], unsigned char res[4]); unsigned char avr_read_byte(int fd, struct avrpart * p, - int memtype, unsigned short addr); + int memtype, unsigned long addr); int avr_read(int fd, struct avrpart * p, int memtype); +int avr_write_bank(int fd, struct avrpart * p, int memtype, + unsigned short bank); + int avr_write_byte(int fd, struct avrpart * p, int memtype, - unsigned short addr, unsigned char data); + unsigned long addr, unsigned char data); int avr_write(int fd, struct avrpart * p, int memtype, int size); diff --git a/avrdude/fileio.c b/avrdude/fileio.c index f6d13c88..cf28033e 100644 --- a/avrdude/fileio.c +++ b/avrdude/fileio.c @@ -93,12 +93,12 @@ char * fmtstr(FILEFMT format) int b2ihex(unsigned char * inbuf, int bufsize, - int recsize, int startaddr, - char * outfile, FILE * outf) + int recsize, int startaddr, + char * outfile, FILE * outf) { unsigned char * buf; unsigned int nextaddr; - int n, nbytes; + int n, nbytes, n_64k; int i; unsigned char cksum; @@ -108,6 +108,7 @@ int b2ihex(unsigned char * inbuf, int bufsize, return -1; } + n_64k = 0; nextaddr = startaddr; buf = inbuf; nbytes = 0; @@ -117,6 +118,9 @@ int b2ihex(unsigned char * inbuf, int bufsize, if (n > bufsize) n = bufsize; + if ((nextaddr + n) > 0x10000) + n = 0x10000 - nextaddr; + if (n) { cksum = 0; fprintf(outf, ":%02X%04X00", n, nextaddr); @@ -132,6 +136,20 @@ int b2ihex(unsigned char * inbuf, int bufsize, nbytes += n; } + if (nextaddr >= 0x10000) { + int lo, hi; + /* output an extended address record */ + n_64k++; + lo = n_64k & 0xff; + hi = (n_64k >> 8) & 0xff; + cksum = 0; + fprintf(outf, ":02000004%02X%02X", hi, lo); + cksum += 2 + 0 + 4 + hi + lo; + cksum = -cksum; + fprintf(outf, "%02X\n", cksum); + nextaddr = 0; + } + /* advance to next 'recsize' bytes */ buf += n; bufsize -= n; diff --git a/avrdude/term.c b/avrdude/term.c index ea993ce5..b258ff3f 100644 --- a/avrdude/term.c +++ b/avrdude/term.c @@ -283,6 +283,7 @@ int cmd_dump(int fd, struct avrpart * p, int argc, char * argv[]) return 0; } + int cmd_write(int fd, struct avrpart * p, int argc, char * argv[]) { char * e; @@ -313,6 +314,12 @@ int cmd_write(int fd, struct avrpart * p, int argc, char * argv[]) return -1; } + if (p->mem[memtype].banked) { + fprintf(stderr, "%s (write): sorry, interactive write of bank addressed " + "memory is not supported\n", progname); + return -1; + } + maxsize = p->mem[memtype].size; addr = strtoul(argv[2], &e, 0);