From ee25a62df6df4bd268f469acaba2a832c28611dd Mon Sep 17 00:00:00 2001 From: Stefan Rueger Date: Sat, 19 Nov 2022 23:09:18 +0000 Subject: [PATCH] Emulate chip erase in terminal when pgm->chip_erase() soft fails --- src/main.c | 5 ++++- src/term.c | 41 ++++++++++++++++++++++++++++++++++++++++- src/urclock.c | 3 +-- 3 files changed, 45 insertions(+), 4 deletions(-) diff --git a/src/main.c b/src/main.c index 40f40c36..3e87019f 100644 --- a/src/main.c +++ b/src/main.c @@ -1395,7 +1395,10 @@ int main(int argc, char * argv []) } else { pmsg_info("erasing chip\n"); exitrc = avr_chip_erase(pgm, p); - if(exitrc) + if(exitrc == LIBAVRDUDE_SOFTFAIL) { + imsg_info("delaying chip erase until first -U upload to flash\n"); + exitrc = 1; + } else if(exitrc) goto main_exit; } } diff --git a/src/term.c b/src/term.c index edd6c8e3..78f37216 100644 --- a/src/term.c +++ b/src/term.c @@ -755,8 +755,47 @@ static int cmd_send(PROGRAMMER *pgm, AVRPART *p, int argc, char *argv[]) { static int cmd_erase(PROGRAMMER *pgm, AVRPART *p, int argc, char *argv[]) { term_out("erasing chip ...\n"); + // Erase chip and clear cache - pgm->chip_erase_cached(pgm, p); + int rc = pgm->chip_erase_cached(pgm, p); + + if(rc == LIBAVRDUDE_SOFTFAIL) { + pmsg_info("(erase) emulating chip erase by writing 0xff to flash "); + AVRMEM *flm = avr_locate_mem(p, "flash"); + if(!flm) { + msg_error("but flash not defined for part %s?\n", p->desc); + return -1; + } + int addr, beg = 0, end = flm->size-1; + if(pgm->readonly) { + for(addr=beg; addr < flm->size; addr++) + if(!pgm->readonly(pgm, p, flm, addr)) { + beg = addr; + break; + } + if(addr >= flm->size) { + msg_info("but all flash is write protected\n"); + return 0; + } + for(addr=end; addr >= 0; addr--) + if(!pgm->readonly(pgm, p, flm, addr)) { + end = addr; + break; + } + } + + msg_info("[0x%04x, 0x%04x]; undo with abort\n", beg, end); + for(int addr=beg; addr <= end; addr++) + if(!pgm->readonly || !pgm->readonly(pgm, p, flm, addr)) + if(pgm->write_byte_cached(pgm, p, flm, addr, 0xff) == -1) + return -1; + return 0; + } + + if(rc) { + pmsg_error("(erase) programmer %s failed erasing the chip\n", (char *) ldata(lfirst(pgm->id))); + return -1; + } return 0; } diff --git a/src/urclock.c b/src/urclock.c index c2e6ef70..d828c24f 100644 --- a/src/urclock.c +++ b/src/urclock.c @@ -1898,7 +1898,6 @@ static int urclock_chip_erase(const PROGRAMMER *pgm, const AVRPART *p) { (ur.urprotocol && !(ur.urfeatures & UB_CHIP_ERASE)) || ur.bloptiversion || (ur.blurversion && ur.blurversion < 076)) { - pmsg_info("delaying chip erase to first -U upload to flash\n"); // Bootloader does not implement chip erase: don't send command to bootloader ur.emulate_ce = 1; emulated = 1; @@ -1953,7 +1952,7 @@ static int urclock_chip_erase(const PROGRAMMER *pgm, const AVRPART *p) { } } - return 0; + return emulated? LIBAVRDUDE_SOFTFAIL: 0; }