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/avrdude@78 81a1dc3b-b13d-400b-aceb-764788c761c2
This commit is contained in:
bsd 2001-10-14 02:53:21 +00:00
parent fa67482972
commit 5dc50eb59f
5 changed files with 119 additions and 28 deletions

View File

@ -17,7 +17,7 @@ DIRS = ${BINDIR} ${MANDIR} ${DOCDIR} ${CONFIGDIR}
INSTALL = /usr/bin/install -c -o root -g wheel INSTALL = /usr/bin/install -c -o root -g wheel
CFLAGS += -g -Wall --pedantic -DCONFIG_DIR=\"${CONFIGDIR}\" CFLAGS = -g -Wall --pedantic -DCONFIG_DIR=\"${CONFIGDIR}\"
LDFLAGS = LDFLAGS =

107
avr.c
View File

@ -78,8 +78,8 @@ struct avrpart parts[] = {
{{0, 512, 0, 0, 9000, 20000, {0x00, 0xff }, NULL}, /* eeprom */ {{0, 512, 0, 0, 9000, 20000, {0x00, 0xff }, NULL}, /* eeprom */
{0, 8192, 0, 0, 9000, 20000, {0xff, 0x00 }, NULL}}}, /* flash */ {0, 8192, 0, 0, 9000, 20000, {0xff, 0x00 }, NULL}}}, /* flash */
{"ATMEGA103", "103", 20000, {"ATMEGA103", "103", 56000*2,
{{0, 4096, 0, 0, 9000, 20000, {0x00, 0xff }, NULL}, /* eeprom */ {{0, 4096, 0, 0, 64000, 69000, {0x80, 0x7f }, NULL}, /* eeprom */
{1, 131072, 256, 512, 22000, 56000, {0xff, 0x00 }, NULL}}}, /* flash */ {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 * read a byte of data from the indicated memory region
*/ */
unsigned char avr_read_byte(int fd, struct avrpart * p, unsigned char avr_read_byte(int fd, struct avrpart * p,
int memtype, unsigned short addr) int memtype, unsigned long addr)
{ {
unsigned short offset; unsigned short offset;
unsigned char cmd[4]; 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) int avr_read(int fd, struct avrpart * p, int memtype)
{ {
unsigned char rbyte; unsigned char rbyte;
unsigned short i; unsigned long i;
unsigned char * buf; unsigned char * buf;
int size; int size;
@ -230,7 +230,7 @@ int avr_read(int fd, struct avrpart * p, int memtype)
for (i=0; i<size; i++) { for (i=0; i<size; i++) {
rbyte = avr_read_byte(fd, p, memtype, i); rbyte = avr_read_byte(fd, p, memtype, i);
fprintf(stderr, " \r%4u 0x%02x", i, rbyte); fprintf(stderr, " \r%4lu 0x%02x", i, rbyte);
buf[i] = rbyte; buf[i] = rbyte;
} }
@ -240,11 +240,41 @@ int avr_read(int fd, struct avrpart * p, int memtype)
} }
/*
* write a byte of data to the indicated memory region
*/
int avr_write_bank(int fd, struct avrpart * p, int memtype,
unsigned short bank)
{
unsigned char cmd[4];
unsigned char res[4];
LED_ON(fd, pinno[PIN_LED_PGM]);
LED_OFF(fd, pinno[PIN_LED_ERR]);
cmd[0] = 0x4c;
cmd[1] = bank >> 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 * write a byte of data to the indicated memory region
*/ */
int avr_write_byte(int fd, struct avrpart * p, int memtype, 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 cmd[4];
unsigned char res[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 */ /* order here is very important, AVR_M_EEPROM, AVR_M_FLASH, AVR_M_FLASH+1 */
static unsigned char cmdbyte[3] = { 0xc0, 0x40, 0x48 }; static unsigned char cmdbyte[3] = { 0xc0, 0x40, 0x48 };
/* 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 * 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
b = avr_read_byte(fd, p, memtype, addr); * use this optimization for banked addressing.
if (b == data) { */
return 0; 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]); 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[0] = cmdbyte[memtype + offset];
cmd[1] = caddr >> 8; /* high order bits of address */ cmd[1] = caddr >> 8; /* high order bits of address */
cmd[2] = caddr & 0x0ff; /* low 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); 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; tries = 0;
ready = 0; ready = 0;
while (!ready) { while (!ready) {
@ -298,14 +344,15 @@ int avr_write_byte(int fd, struct avrpart * p, int memtype,
* specified for the chip. * specified for the chip.
*/ */
usleep(p->mem[memtype].max_write_delay); 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; ready = 1;
} }
tries++; tries++;
if (!ready && tries > 10) { if (!ready && tries > 5) {
/* /*
* 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
@ -335,8 +382,7 @@ int avr_write(int fd, struct avrpart * p, int memtype, int size)
{ {
int rc; int rc;
int wsize; int wsize;
unsigned char * buf; unsigned long i;
unsigned short i;
unsigned char data; unsigned char data;
int werror; int werror;
@ -344,7 +390,6 @@ int avr_write(int fd, struct avrpart * p, int memtype, int size)
werror = 0; werror = 0;
buf = p->mem[memtype].buf;
wsize = p->mem[memtype].size; wsize = p->mem[memtype].size;
if (size < wsize) { if (size < wsize) {
wsize = size; wsize = size;
@ -359,15 +404,32 @@ int avr_write(int fd, struct avrpart * p, int memtype, int size)
for (i=0; i<wsize; i++) { for (i=0; i<wsize; i++) {
/* eeprom or low byte of flash */ /* eeprom or low byte of flash */
data = buf[i]; data = p->mem[memtype].buf[i];
rc = avr_write_byte(fd, p, memtype, i, data); 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) { if (rc) {
fprintf(stderr, " ***failed; "); fprintf(stderr, " ***failed; ");
fprintf(stderr, "\n"); fprintf(stderr, "\n");
LED_ON(fd, pinno[PIN_LED_ERR]); LED_ON(fd, pinno[PIN_LED_ERR]);
werror = 1; 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) { if (werror) {
/* /*
* 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
@ -377,6 +439,7 @@ int avr_write(int fd, struct avrpart * p, int memtype, int size)
} }
} }
fprintf(stderr, "\n"); fprintf(stderr, "\n");
return i; return i;

7
avr.h
View File

@ -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]); int avr_cmd(int fd, unsigned char cmd[4], unsigned char res[4]);
unsigned char avr_read_byte(int fd, struct avrpart * p, 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_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, 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); int avr_write(int fd, struct avrpart * p, int memtype, int size);

View File

@ -93,12 +93,12 @@ char * fmtstr(FILEFMT format)
int b2ihex(unsigned char * inbuf, int bufsize, int b2ihex(unsigned char * inbuf, int bufsize,
int recsize, int startaddr, int recsize, int startaddr,
char * outfile, FILE * outf) char * outfile, FILE * outf)
{ {
unsigned char * buf; unsigned char * buf;
unsigned int nextaddr; unsigned int nextaddr;
int n, nbytes; int n, nbytes, n_64k;
int i; int i;
unsigned char cksum; unsigned char cksum;
@ -108,6 +108,7 @@ int b2ihex(unsigned char * inbuf, int bufsize,
return -1; return -1;
} }
n_64k = 0;
nextaddr = startaddr; nextaddr = startaddr;
buf = inbuf; buf = inbuf;
nbytes = 0; nbytes = 0;
@ -117,6 +118,9 @@ int b2ihex(unsigned char * inbuf, int bufsize,
if (n > bufsize) if (n > bufsize)
n = bufsize; n = bufsize;
if ((nextaddr + n) > 0x10000)
n = 0x10000 - nextaddr;
if (n) { if (n) {
cksum = 0; cksum = 0;
fprintf(outf, ":%02X%04X00", n, nextaddr); fprintf(outf, ":%02X%04X00", n, nextaddr);
@ -132,6 +136,20 @@ int b2ihex(unsigned char * inbuf, int bufsize,
nbytes += n; 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 */ /* advance to next 'recsize' bytes */
buf += n; buf += n;
bufsize -= n; bufsize -= n;

7
term.c
View File

@ -283,6 +283,7 @@ int cmd_dump(int fd, struct avrpart * p, int argc, char * argv[])
return 0; return 0;
} }
int cmd_write(int fd, struct avrpart * p, int argc, char * argv[]) int cmd_write(int fd, struct avrpart * p, int argc, char * argv[])
{ {
char * e; char * e;
@ -313,6 +314,12 @@ int cmd_write(int fd, struct avrpart * p, int argc, char * argv[])
return -1; 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; maxsize = p->mem[memtype].size;
addr = strtoul(argv[2], &e, 0); addr = strtoul(argv[2], &e, 0);