diff --git a/avr.c b/avr.c index 0bf18a0f..0ee7285d 100644 --- a/avr.c +++ b/avr.c @@ -352,6 +352,33 @@ int avr_read_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem, } +/* + * Return the number of "interesting" bytes in a memory buffer, + * "interesting" being defined as up to the last non-0xff data + * value. This is useful for determining where to stop when dealing + * with "flash" memory, since writing 0xff to flash is typically a + * no-op. Always return an even number since flash is word addressed. + */ +int avr_mem_hiaddr(AVRMEM * mem) +{ + int i, n; + + /* return the highest non-0xff address regardless of how much + memory was read */ + for (i=mem->size-1; i>0; i--) { + if (mem->buf[i] != 0xff) { + n = i+1; + if (n & 0x01) + return n+1; + else + return n; + } + } + + return 0; +} + + /* * Read the entirety of the specified memory type into the * corresponding buffer of the avrpart pointed to by 'p'. If size = @@ -381,6 +408,11 @@ int avr_read(PROGRAMMER * pgm, AVRPART * p, char * memtype, int size, size = mem->size; } + /* + * start with all 0xff + */ + memset(buf, 0xff, size); + if ((strcmp(mem->desc, "flash")==0) || (strcmp(mem->desc, "eeprom")==0)) { if (pgm->paged_load != NULL) { /* @@ -389,11 +421,19 @@ int avr_read(PROGRAMMER * pgm, AVRPART * p, char * memtype, int size, * instead */ if (mem->paged) { - return pgm->paged_load(pgm, p, mem, mem->page_size, size); + rc = pgm->paged_load(pgm, p, mem, mem->page_size, size); + if (rc < 0) + return rc; } else { - return pgm->paged_load(pgm, p, mem, pgm->page_size, size); + rc = pgm->paged_load(pgm, p, mem, pgm->page_size, size); + if (rc < 0) + return rc; } + if (strcasecmp(mem->desc, "flash") == 0) + return avr_mem_hiaddr(mem); + else + return rc; } } @@ -428,7 +468,10 @@ int avr_read(PROGRAMMER * pgm, AVRPART * p, char * memtype, int size, fprintf(stderr, "\n"); } - return i; + if (strcasecmp(mem->desc, "flash") == 0) + return avr_mem_hiaddr(mem); + else + return i; } diff --git a/avr.h b/avr.h index ecd39e64..c1c00ae3 100644 --- a/avr.h +++ b/avr.h @@ -84,4 +84,6 @@ int avr_get_cycle_count(PROGRAMMER * pgm, AVRPART * p, int * cycles); int avr_put_cycle_count(PROGRAMMER * pgm, AVRPART * p, int cycles);; +int avr_mem_hiaddr(AVRMEM * mem); + #endif diff --git a/fileio.c b/fileio.c index 19591747..d40e757b 100644 --- a/fileio.c +++ b/fileio.c @@ -933,9 +933,7 @@ int fileio(int op, char * filename, FILEFMT format, if (fio.op == FIO_READ) { /* 0xff fill unspecified memory */ - for (i=0; i 0) { + if ((op == FIO_READ) && (strcasecmp(mem->desc, "flash") == 0)) { + /* + * if we are reading flash, just mark the size as being the + * highest non-0xff byte + */ + rc = avr_mem_hiaddr(mem); + } + } + return rc; }