Add support for UPDI devices though jtag2updi

'Hack' borrowed from https://github.com/facchinm/avrdude
This commit is contained in:
MCUdude 2021-12-29 13:32:56 +01:00
parent 71d5dbec48
commit a2a276a8cc
1 changed files with 24 additions and 25 deletions

View File

@ -891,7 +891,7 @@ static int jtagmkII_chip_erase(PROGRAMMER * pgm, AVRPART * p)
int status, len; int status, len;
unsigned char buf[6], *resp, c; unsigned char buf[6], *resp, c;
if (p->flags & AVRPART_HAS_PDI) { if (p->flags & (AVRPART_HAS_PDI | AVRPART_HAS_UPDI)) {
buf[0] = CMND_XMEGA_ERASE; buf[0] = CMND_XMEGA_ERASE;
buf[1] = XMEGA_ERASE_CHIP; buf[1] = XMEGA_ERASE_CHIP;
memset(buf + 2, 0, 4); /* address of area to be erased */ memset(buf + 2, 0, 4); /* address of area to be erased */
@ -902,7 +902,7 @@ static int jtagmkII_chip_erase(PROGRAMMER * pgm, AVRPART * p)
} }
avrdude_message(MSG_NOTICE2, "%s: jtagmkII_chip_erase(): Sending %schip erase command: ", avrdude_message(MSG_NOTICE2, "%s: jtagmkII_chip_erase(): Sending %schip erase command: ",
progname, progname,
(p->flags & AVRPART_HAS_PDI)? "Xmega ": ""); (p->flags & (AVRPART_HAS_PDI | AVRPART_HAS_UPDI))? "Xmega ": "");
jtagmkII_send(pgm, buf, len); jtagmkII_send(pgm, buf, len);
status = jtagmkII_recv(pgm, &resp); status = jtagmkII_recv(pgm, &resp);
@ -928,7 +928,7 @@ static int jtagmkII_chip_erase(PROGRAMMER * pgm, AVRPART * p)
return -1; return -1;
} }
if (!(p->flags & AVRPART_HAS_PDI)) if (!(p->flags & (AVRPART_HAS_PDI | AVRPART_HAS_UPDI)))
pgm->initialize(pgm, p); pgm->initialize(pgm, p);
return 0; return 0;
@ -986,7 +986,7 @@ static void jtagmkII_set_devdescr(PROGRAMMER * pgm, AVRPART * p)
} }
} }
sendbuf.dd.ucCacheType = sendbuf.dd.ucCacheType =
(p->flags & AVRPART_HAS_PDI)? 0x02 /* ATxmega */: 0x00; (p->flags & (AVRPART_HAS_PDI | AVRPART_HAS_UPDI))? 0x02 /* ATxmega */: 0x00;
avrdude_message(MSG_NOTICE2, "%s: jtagmkII_set_devdescr(): " avrdude_message(MSG_NOTICE2, "%s: jtagmkII_set_devdescr(): "
"Sending set device descriptor command: ", "Sending set device descriptor command: ",
@ -1312,7 +1312,7 @@ static int jtagmkII_initialize(PROGRAMMER * pgm, AVRPART * p)
ok = 1; ok = 1;
} else if (pgm->flag & PGM_FL_IS_PDI) { } else if (pgm->flag & PGM_FL_IS_PDI) {
ifname = "PDI"; ifname = "PDI";
if (p->flags & AVRPART_HAS_PDI) if (p->flags & (AVRPART_HAS_PDI | AVRPART_HAS_UPDI))
ok = 1; ok = 1;
} else { } else {
ifname = "JTAG"; ifname = "JTAG";
@ -1358,20 +1358,20 @@ static int jtagmkII_initialize(PROGRAMMER * pgm, AVRPART * p)
* mode from JTAG to JTAG_XMEGA. * mode from JTAG to JTAG_XMEGA.
*/ */
if ((pgm->flag & PGM_FL_IS_JTAG) && if ((pgm->flag & PGM_FL_IS_JTAG) &&
(p->flags & AVRPART_HAS_PDI)) { (p->flags & (AVRPART_HAS_PDI | AVRPART_HAS_UPDI))) {
if (jtagmkII_getsync(pgm, EMULATOR_MODE_JTAG_XMEGA) < 0) if (jtagmkII_getsync(pgm, EMULATOR_MODE_JTAG_XMEGA) < 0)
return -1; return -1;
} }
/* /*
* Must set the device descriptor before entering programming mode. * Must set the device descriptor before entering programming mode.
*/ */
if (PDATA(pgm)->fwver >= 0x700 && (p->flags & AVRPART_HAS_PDI) != 0) if (PDATA(pgm)->fwver >= 0x700 && (p->flags & (AVRPART_HAS_PDI | AVRPART_HAS_UPDI)) != 0)
jtagmkII_set_xmega_params(pgm, p); jtagmkII_set_xmega_params(pgm, p);
else else
jtagmkII_set_devdescr(pgm, p); jtagmkII_set_devdescr(pgm, p);
PDATA(pgm)->boot_start = ULONG_MAX; PDATA(pgm)->boot_start = ULONG_MAX;
if ((p->flags & AVRPART_HAS_PDI)) { if ((p->flags & (AVRPART_HAS_PDI | AVRPART_HAS_UPDI))) {
/* /*
* Find out where the border between application and boot area * Find out where the border between application and boot area
* is. * is.
@ -1411,7 +1411,7 @@ static int jtagmkII_initialize(PROGRAMMER * pgm, AVRPART * p)
} }
PDATA(pgm)->flash_pageaddr = PDATA(pgm)->eeprom_pageaddr = (unsigned long)-1L; PDATA(pgm)->flash_pageaddr = PDATA(pgm)->eeprom_pageaddr = (unsigned long)-1L;
if (PDATA(pgm)->fwver >= 0x700 && (p->flags & AVRPART_HAS_PDI)) { if (PDATA(pgm)->fwver >= 0x700 && (p->flags & (AVRPART_HAS_PDI | AVRPART_HAS_UPDI))) {
/* /*
* Work around for * Work around for
* https://savannah.nongnu.org/bugs/index.php?37942 * https://savannah.nongnu.org/bugs/index.php?37942
@ -1428,7 +1428,7 @@ static int jtagmkII_initialize(PROGRAMMER * pgm, AVRPART * p)
return -1; return -1;
} }
if ((pgm->flag & PGM_FL_IS_JTAG) && !(p->flags & AVRPART_HAS_PDI)) { if ((pgm->flag & PGM_FL_IS_JTAG) && !(p->flags & (AVRPART_HAS_PDI | AVRPART_HAS_UPDI))) {
strcpy(hfuse.desc, "hfuse"); strcpy(hfuse.desc, "hfuse");
if (jtagmkII_read_byte(pgm, p, &hfuse, 1, &b) < 0) if (jtagmkII_read_byte(pgm, p, &hfuse, 1, &b) < 0)
return -1; return -1;
@ -1902,7 +1902,7 @@ static int jtagmkII_page_erase(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
avrdude_message(MSG_NOTICE2, "%s: jtagmkII_page_erase(.., %s, 0x%x)\n", avrdude_message(MSG_NOTICE2, "%s: jtagmkII_page_erase(.., %s, 0x%x)\n",
progname, m->desc, addr); progname, m->desc, addr);
if (!(p->flags & AVRPART_HAS_PDI)) { if (!(p->flags & (AVRPART_HAS_PDI | AVRPART_HAS_UPDI))) {
avrdude_message(MSG_INFO, "%s: jtagmkII_page_erase: not an Xmega device\n", avrdude_message(MSG_INFO, "%s: jtagmkII_page_erase: not an Xmega device\n",
progname); progname);
return -1; return -1;
@ -2016,7 +2016,7 @@ static int jtagmkII_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
if (strcmp(m->desc, "flash") == 0) { if (strcmp(m->desc, "flash") == 0) {
PDATA(pgm)->flash_pageaddr = (unsigned long)-1L; PDATA(pgm)->flash_pageaddr = (unsigned long)-1L;
cmd[1] = jtagmkII_memtype(pgm, p, addr); cmd[1] = jtagmkII_memtype(pgm, p, addr);
if (p->flags & AVRPART_HAS_PDI) if (p->flags & (AVRPART_HAS_PDI | AVRPART_HAS_UPDI))
/* dynamically decide between flash/boot memtype */ /* dynamically decide between flash/boot memtype */
dynamic_memtype = 1; dynamic_memtype = 1;
} else if (strcmp(m->desc, "eeprom") == 0) { } else if (strcmp(m->desc, "eeprom") == 0) {
@ -2035,18 +2035,18 @@ static int jtagmkII_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
free(cmd); free(cmd);
return n_bytes; return n_bytes;
} }
cmd[1] = ( p->flags & AVRPART_HAS_PDI ) ? MTYPE_EEPROM : MTYPE_EEPROM_PAGE; cmd[1] = ( p->flags & (AVRPART_HAS_PDI | AVRPART_HAS_UPDI) ) ? MTYPE_EEPROM : MTYPE_EEPROM_PAGE;
PDATA(pgm)->eeprom_pageaddr = (unsigned long)-1L; PDATA(pgm)->eeprom_pageaddr = (unsigned long)-1L;
} else if ( ( strcmp(m->desc, "usersig") == 0 ) ) { } else if ( ( strcmp(m->desc, "usersig") == 0 ) ) {
cmd[1] = MTYPE_USERSIG; cmd[1] = MTYPE_USERSIG;
} else if ( ( strcmp(m->desc, "boot") == 0 ) ) { } else if ( ( strcmp(m->desc, "boot") == 0 ) ) {
cmd[1] = MTYPE_BOOT_FLASH; cmd[1] = MTYPE_BOOT_FLASH;
} else if ( p->flags & AVRPART_HAS_PDI ) { } else if ( p->flags & (AVRPART_HAS_PDI | AVRPART_HAS_UPDI) ) {
cmd[1] = MTYPE_FLASH; cmd[1] = MTYPE_FLASH;
} else { } else {
cmd[1] = MTYPE_SPM; cmd[1] = MTYPE_SPM;
} }
serial_recv_timeout = 100; serial_recv_timeout = 200;
for (; addr < maxaddr; addr += page_size) { for (; addr < maxaddr; addr += page_size) {
if ((maxaddr - addr) < page_size) if ((maxaddr - addr) < page_size)
block_size = maxaddr - addr; block_size = maxaddr - addr;
@ -2143,11 +2143,11 @@ static int jtagmkII_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
cmd[0] = CMND_READ_MEMORY; cmd[0] = CMND_READ_MEMORY;
if (strcmp(m->desc, "flash") == 0) { if (strcmp(m->desc, "flash") == 0) {
cmd[1] = jtagmkII_memtype(pgm, p, addr); cmd[1] = jtagmkII_memtype(pgm, p, addr);
if (p->flags & AVRPART_HAS_PDI) if (p->flags & (AVRPART_HAS_PDI | AVRPART_HAS_UPDI))
/* dynamically decide between flash/boot memtype */ /* dynamically decide between flash/boot memtype */
dynamic_memtype = 1; dynamic_memtype = 1;
} else if (strcmp(m->desc, "eeprom") == 0) { } else if (strcmp(m->desc, "eeprom") == 0) {
cmd[1] = ( p->flags & AVRPART_HAS_PDI ) ? MTYPE_EEPROM : MTYPE_EEPROM_PAGE; cmd[1] = ( p->flags & (AVRPART_HAS_PDI | AVRPART_HAS_UPDI) ) ? MTYPE_EEPROM : MTYPE_EEPROM_PAGE;
if (pgm->flag & PGM_FL_IS_DW) if (pgm->flag & PGM_FL_IS_DW)
return -1; return -1;
} else if ( ( strcmp(m->desc, "prodsig") == 0 ) ) { } else if ( ( strcmp(m->desc, "prodsig") == 0 ) ) {
@ -2156,7 +2156,7 @@ static int jtagmkII_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
cmd[1] = MTYPE_USERSIG; cmd[1] = MTYPE_USERSIG;
} else if ( ( strcmp(m->desc, "boot") == 0 ) ) { } else if ( ( strcmp(m->desc, "boot") == 0 ) ) {
cmd[1] = MTYPE_BOOT_FLASH; cmd[1] = MTYPE_BOOT_FLASH;
} else if ( p->flags & AVRPART_HAS_PDI ) { } else if ( p->flags & (AVRPART_HAS_PDI | AVRPART_HAS_UPDI) ) {
cmd[1] = MTYPE_FLASH; cmd[1] = MTYPE_FLASH;
} else { } else {
cmd[1] = MTYPE_SPM; cmd[1] = MTYPE_SPM;
@ -2241,7 +2241,7 @@ static int jtagmkII_read_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
unsupp = 0; unsupp = 0;
addr += mem->offset; addr += mem->offset;
cmd[1] = ( p->flags & AVRPART_HAS_PDI ) ? MTYPE_FLASH : MTYPE_FLASH_PAGE; cmd[1] = ( p->flags & (AVRPART_HAS_PDI | AVRPART_HAS_UPDI) ) ? MTYPE_FLASH : MTYPE_FLASH_PAGE;
if (strcmp(mem->desc, "flash") == 0 || if (strcmp(mem->desc, "flash") == 0 ||
strcmp(mem->desc, "application") == 0 || strcmp(mem->desc, "application") == 0 ||
strcmp(mem->desc, "apptable") == 0 || strcmp(mem->desc, "apptable") == 0 ||
@ -2251,7 +2251,7 @@ static int jtagmkII_read_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
paddr_ptr = &PDATA(pgm)->flash_pageaddr; paddr_ptr = &PDATA(pgm)->flash_pageaddr;
cache_ptr = PDATA(pgm)->flash_pagecache; cache_ptr = PDATA(pgm)->flash_pagecache;
} else if (strcmp(mem->desc, "eeprom") == 0) { } else if (strcmp(mem->desc, "eeprom") == 0) {
if ( (pgm->flag & PGM_FL_IS_DW) || ( p->flags & AVRPART_HAS_PDI ) ) { if ( (pgm->flag & PGM_FL_IS_DW) || ( p->flags & (AVRPART_HAS_PDI | AVRPART_HAS_UPDI) ) ) {
/* debugWire cannot use page access for EEPROM */ /* debugWire cannot use page access for EEPROM */
cmd[1] = MTYPE_EEPROM; cmd[1] = MTYPE_EEPROM;
} else { } else {
@ -2417,7 +2417,7 @@ static int jtagmkII_write_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
writedata = data; writedata = data;
cmd[0] = CMND_WRITE_MEMORY; cmd[0] = CMND_WRITE_MEMORY;
cmd[1] = ( p->flags & AVRPART_HAS_PDI ) ? MTYPE_FLASH : MTYPE_SPM; cmd[1] = ( p->flags & (AVRPART_HAS_PDI | AVRPART_HAS_UPDI) ) ? MTYPE_FLASH : MTYPE_SPM;
if (strcmp(mem->desc, "flash") == 0) { if (strcmp(mem->desc, "flash") == 0) {
if ((addr & 1) == 1) { if ((addr & 1) == 1) {
/* odd address = high byte */ /* odd address = high byte */
@ -2431,7 +2431,7 @@ static int jtagmkII_write_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
if (pgm->flag & PGM_FL_IS_DW) if (pgm->flag & PGM_FL_IS_DW)
unsupp = 1; unsupp = 1;
} else if (strcmp(mem->desc, "eeprom") == 0) { } else if (strcmp(mem->desc, "eeprom") == 0) {
cmd[1] = ( p->flags & AVRPART_HAS_PDI ) ? MTYPE_EEPROM_XMEGA: MTYPE_EEPROM; cmd[1] = ( p->flags & (AVRPART_HAS_PDI | AVRPART_HAS_UPDI) ) ? MTYPE_EEPROM_XMEGA: MTYPE_EEPROM;
need_progmode = 0; need_progmode = 0;
PDATA(pgm)->eeprom_pageaddr = (unsigned long)-1L; PDATA(pgm)->eeprom_pageaddr = (unsigned long)-1L;
} else if (strcmp(mem->desc, "lfuse") == 0) { } else if (strcmp(mem->desc, "lfuse") == 0) {
@ -2736,7 +2736,7 @@ static void jtagmkII_print_parms(PROGRAMMER * pgm)
static unsigned char jtagmkII_memtype(PROGRAMMER * pgm, AVRPART * p, unsigned long addr) static unsigned char jtagmkII_memtype(PROGRAMMER * pgm, AVRPART * p, unsigned long addr)
{ {
if ( p->flags & AVRPART_HAS_PDI ) { if ( p->flags & (AVRPART_HAS_PDI | AVRPART_HAS_UPDI) ) {
if (addr >= PDATA(pgm)->boot_start) if (addr >= PDATA(pgm)->boot_start)
return MTYPE_BOOT_FLASH; return MTYPE_BOOT_FLASH;
else else
@ -2752,7 +2752,7 @@ static unsigned int jtagmkII_memaddr(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
* Xmega devices handled by V7+ firmware don't want to be told their * Xmega devices handled by V7+ firmware don't want to be told their
* m->offset within the write memory command. * m->offset within the write memory command.
*/ */
if (PDATA(pgm)->fwver >= 0x700 && (p->flags & AVRPART_HAS_PDI) != 0) { if (PDATA(pgm)->fwver >= 0x700 && (p->flags & (AVRPART_HAS_PDI | AVRPART_HAS_UPDI)) != 0) {
if (addr >= PDATA(pgm)->boot_start) if (addr >= PDATA(pgm)->boot_start)
/* /*
* all memories but "flash" are smaller than boot_start anyway, so * all memories but "flash" are smaller than boot_start anyway, so
@ -4047,4 +4047,3 @@ void jtagmkII_dragon_pdi_initpgm(PROGRAMMER * pgm)
pgm->page_size = 256; pgm->page_size = 256;
pgm->flag = PGM_FL_IS_PDI; pgm->flag = PGM_FL_IS_PDI;
} }