Merge pull request #1194 from stefanrueger/exitrc

Fix shell exit value when chip erase is delayed to next flash write
This commit is contained in:
Stefan Rueger 2022-11-25 17:50:01 +00:00 committed by GitHub
commit d2a2ec1d1b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 75 additions and 63 deletions

124
src/avr.c
View File

@ -49,7 +49,7 @@ int avr_tpi_poll_nvmbsy(const PROGRAMMER *pgm) {
/* TPI chip erase sequence */
int avr_tpi_chip_erase(const PROGRAMMER *pgm, const AVRPART *p) {
int err;
int err;
AVRMEM *mem;
if (p->prog_modes & PM_TPI) {
@ -62,27 +62,27 @@ int avr_tpi_chip_erase(const PROGRAMMER *pgm, const AVRPART *p) {
return -1;
}
unsigned char cmd[] = {
/* write pointer register high byte */
(TPI_CMD_SSTPR | 0),
((mem->offset & 0xFF) | 1),
/* and low byte */
(TPI_CMD_SSTPR | 1),
((mem->offset >> 8) & 0xFF),
/* write CHIP_ERASE command to NVMCMD register */
(TPI_CMD_SOUT | TPI_SIO_ADDR(TPI_IOREG_NVMCMD)),
TPI_NVMCMD_CHIP_ERASE,
/* write dummy value to start erase */
TPI_CMD_SST,
0xFF
};
unsigned char cmd[] = {
/* write pointer register high byte */
(TPI_CMD_SSTPR | 0),
((mem->offset & 0xFF) | 1),
/* and low byte */
(TPI_CMD_SSTPR | 1),
((mem->offset >> 8) & 0xFF),
/* write CHIP_ERASE command to NVMCMD register */
(TPI_CMD_SOUT | TPI_SIO_ADDR(TPI_IOREG_NVMCMD)),
TPI_NVMCMD_CHIP_ERASE,
/* write dummy value to start erase */
TPI_CMD_SST,
0xFF
};
while (avr_tpi_poll_nvmbsy(pgm))
;
err = pgm->cmd_tpi(pgm, cmd, sizeof(cmd), NULL, 0);
if(err)
return err;
return err;
while (avr_tpi_poll_nvmbsy(pgm));
@ -97,56 +97,56 @@ int avr_tpi_chip_erase(const PROGRAMMER *pgm, const AVRPART *p) {
/* TPI program enable sequence */
int avr_tpi_program_enable(const PROGRAMMER *pgm, const AVRPART *p, unsigned char guard_time) {
int err, retry;
unsigned char cmd[2];
unsigned char response;
int err, retry;
unsigned char cmd[2];
unsigned char response;
if(p->prog_modes & PM_TPI) {
/* set guard time */
cmd[0] = (TPI_CMD_SSTCS | TPI_REG_TPIPCR);
cmd[1] = guard_time;
if(p->prog_modes & PM_TPI) {
/* set guard time */
cmd[0] = (TPI_CMD_SSTCS | TPI_REG_TPIPCR);
cmd[1] = guard_time;
err = pgm->cmd_tpi(pgm, cmd, sizeof(cmd), NULL, 0);
err = pgm->cmd_tpi(pgm, cmd, sizeof(cmd), NULL, 0);
if(err)
return err;
return err;
/* read TPI ident reg */
/* read TPI ident reg */
cmd[0] = (TPI_CMD_SLDCS | TPI_REG_TPIIR);
err = pgm->cmd_tpi(pgm, cmd, 1, &response, sizeof(response));
err = pgm->cmd_tpi(pgm, cmd, 1, &response, sizeof(response));
if (err || response != TPI_IDENT_CODE) {
pmsg_error("TPIIR not correct\n");
return -1;
}
/* send SKEY command + SKEY */
err = pgm->cmd_tpi(pgm, tpi_skey_cmd, sizeof(tpi_skey_cmd), NULL, 0);
if(err)
return err;
/* send SKEY command + SKEY */
err = pgm->cmd_tpi(pgm, tpi_skey_cmd, sizeof(tpi_skey_cmd), NULL, 0);
if(err)
return err;
/* check if device is ready */
for(retry = 0; retry < 10; retry++)
{
cmd[0] = (TPI_CMD_SLDCS | TPI_REG_TPISR);
err = pgm->cmd_tpi(pgm, cmd, 1, &response, sizeof(response));
if(err || !(response & TPI_REG_TPISR_NVMEN))
continue;
/* check if device is ready */
for(retry = 0; retry < 10; retry++)
{
cmd[0] = (TPI_CMD_SLDCS | TPI_REG_TPISR);
err = pgm->cmd_tpi(pgm, cmd, 1, &response, sizeof(response));
if(err || !(response & TPI_REG_TPISR_NVMEN))
continue;
return 0;
}
return 0;
}
pmsg_error("target does not reply when enabling TPI external programming mode\n");
return -1;
pmsg_error("target does not reply when enabling TPI external programming mode\n");
return -1;
} else {
pmsg_error("part has no TPI\n");
return -1;
}
} else {
pmsg_error("part has no TPI\n");
return -1;
}
}
/* TPI: setup NVMCMD register and pointer register (PR) for read/write/erase */
static int avr_tpi_setup_rw(const PROGRAMMER *pgm, const AVRMEM *mem,
unsigned long addr, unsigned char nvmcmd)
{
unsigned long addr, unsigned char nvmcmd) {
unsigned char cmd[4];
int rc;
@ -448,9 +448,7 @@ int avr_read_mem(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem, con
}
for (i=0; i < (unsigned long) mem->size; i++) {
if (vmem == NULL ||
(vmem->tags[i] & TAG_ALLOCATED) != 0)
{
if (vmem == NULL || (vmem->tags[i] & TAG_ALLOCATED) != 0) {
rc = pgm->read_byte(pgm, p, mem, i, mem->buf + i);
if (rc != LIBAVRDUDE_SUCCESS) {
pmsg_error("unable to read byte at address 0x%04lx\n", i);
@ -711,9 +709,7 @@ int avr_write_byte_default(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM
gettimeofday (&tv, NULL);
start_time = (tv.tv_sec * 1000000) + tv.tv_usec;
do {
/*
* Do polling, but timeout after max_write_delay.
*/
// Do polling, but timeout after max_write_delay
rc = pgm->read_byte(pgm, p, mem, addr, &r);
if (rc != 0) {
pgm->pgm_led(pgm, OFF);
@ -1326,16 +1322,24 @@ void avr_add_mem_order(const char *str) {
exit(1);
}
int avr_memtype_is_flash_type(const char *memtype) {
return memtype && (
strcmp(memtype, "flash") == 0 ||
strcmp(memtype, "application") == 0 ||
strcmp(memtype, "apptable") == 0 ||
strcmp(memtype, "boot") == 0);
}
int avr_mem_is_flash_type(const AVRMEM *mem) {
return
strcmp(mem->desc, "flash") == 0 ||
strcmp(mem->desc, "application") == 0 ||
strcmp(mem->desc, "apptable") == 0 ||
strcmp(mem->desc, "boot") == 0;
return avr_memtype_is_flash_type(mem->desc);
}
int avr_memtype_is_eeprom_type(const char *memtype) {
return memtype && strcmp(memtype, "eeprom") == 0;
}
int avr_mem_is_eeprom_type(const AVRMEM *mem) {
return strcmp(mem->desc, "eeprom") == 0;
return avr_memtype_is_eeprom_type(mem->desc);
}
int avr_mem_is_known(const char *str) {

View File

@ -899,8 +899,12 @@ int avr_put_cycle_count(const PROGRAMMER *pgm, const AVRPART *p, int cycles);
void avr_add_mem_order(const char *str);
int avr_memtype_is_flash_type(const char *mem);
int avr_mem_is_flash_type(const AVRMEM *mem);
int avr_memtype_is_eeprom_type(const char *mem);
int avr_mem_is_eeprom_type(const AVRMEM *mem);
int avr_mem_is_known(const char *str);

View File

@ -495,6 +495,7 @@ int main(int argc, char * argv [])
int ispdelay; /* Specify the delay for ISP clock */
int init_ok; /* Device initialization worked well */
int is_open; /* Device open succeeded */
int ce_delayed; /* Chip erase delayed */
char * logfile; /* Use logfile rather than stderr for diagnostics */
enum updateflags uflags = UF_AUTO_ERASE | UF_VERIFY; /* Flags for do_op() */
@ -574,6 +575,7 @@ int main(int argc, char * argv [])
bitclock = 0.0;
ispdelay = 0;
is_open = 0;
ce_delayed = 0;
logfile = NULL;
len = strlen(progname) + 2;
@ -1400,7 +1402,8 @@ int main(int argc, char * argv [])
exitrc = avr_chip_erase(pgm, p);
if(exitrc == LIBAVRDUDE_SOFTFAIL) {
imsg_info("delaying chip erase until first -U upload to flash\n");
exitrc = 1;
ce_delayed = 1;
exitrc = 0;
} else if(exitrc)
goto main_exit;
}
@ -1428,7 +1431,8 @@ int main(int argc, char * argv [])
if (rc && rc != LIBAVRDUDE_SOFTFAIL) {
exitrc = 1;
break;
}
} else if(rc == 0 && upd->op == DEVICE_WRITE && avr_memtype_is_flash_type(upd->memtype))
ce_delayed = 0; // Redeemed chip erase promise
}
main_exit:
@ -1449,5 +1453,5 @@ main_exit:
msg_info("\n%s done. Thank you.\n\n", progname);
return exitrc;
return ce_delayed? 1: exitrc;
}