From a2a276a8cc42d85267c1d1733d512975101b799b Mon Sep 17 00:00:00 2001 From: MCUdude Date: Wed, 29 Dec 2021 13:32:56 +0100 Subject: [PATCH] Add support for UPDI devices though jtag2updi 'Hack' borrowed from https://github.com/facchinm/avrdude --- src/jtagmkII.c | 49 ++++++++++++++++++++++++------------------------- 1 file changed, 24 insertions(+), 25 deletions(-) diff --git a/src/jtagmkII.c b/src/jtagmkII.c index 38eba40d..263a1f6b 100644 --- a/src/jtagmkII.c +++ b/src/jtagmkII.c @@ -891,7 +891,7 @@ static int jtagmkII_chip_erase(PROGRAMMER * pgm, AVRPART * p) int status, len; 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[1] = XMEGA_ERASE_CHIP; 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: ", progname, - (p->flags & AVRPART_HAS_PDI)? "Xmega ": ""); + (p->flags & (AVRPART_HAS_PDI | AVRPART_HAS_UPDI))? "Xmega ": ""); jtagmkII_send(pgm, buf, len); status = jtagmkII_recv(pgm, &resp); @@ -928,7 +928,7 @@ static int jtagmkII_chip_erase(PROGRAMMER * pgm, AVRPART * p) return -1; } - if (!(p->flags & AVRPART_HAS_PDI)) + if (!(p->flags & (AVRPART_HAS_PDI | AVRPART_HAS_UPDI))) pgm->initialize(pgm, p); return 0; @@ -986,7 +986,7 @@ static void jtagmkII_set_devdescr(PROGRAMMER * pgm, AVRPART * p) } } 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(): " "Sending set device descriptor command: ", @@ -1312,7 +1312,7 @@ static int jtagmkII_initialize(PROGRAMMER * pgm, AVRPART * p) ok = 1; } else if (pgm->flag & PGM_FL_IS_PDI) { ifname = "PDI"; - if (p->flags & AVRPART_HAS_PDI) + if (p->flags & (AVRPART_HAS_PDI | AVRPART_HAS_UPDI)) ok = 1; } else { ifname = "JTAG"; @@ -1358,20 +1358,20 @@ static int jtagmkII_initialize(PROGRAMMER * pgm, AVRPART * p) * mode from JTAG to JTAG_XMEGA. */ 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) return -1; } /* * 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); else jtagmkII_set_devdescr(pgm, p); 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 * is. @@ -1411,7 +1411,7 @@ static int jtagmkII_initialize(PROGRAMMER * pgm, AVRPART * p) } 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 * https://savannah.nongnu.org/bugs/index.php?37942 @@ -1428,7 +1428,7 @@ static int jtagmkII_initialize(PROGRAMMER * pgm, AVRPART * p) 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"); if (jtagmkII_read_byte(pgm, p, &hfuse, 1, &b) < 0) 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", 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", progname); return -1; @@ -2016,7 +2016,7 @@ static int jtagmkII_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m, if (strcmp(m->desc, "flash") == 0) { PDATA(pgm)->flash_pageaddr = (unsigned long)-1L; 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 */ dynamic_memtype = 1; } else if (strcmp(m->desc, "eeprom") == 0) { @@ -2035,18 +2035,18 @@ static int jtagmkII_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m, free(cmd); 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; } else if ( ( strcmp(m->desc, "usersig") == 0 ) ) { cmd[1] = MTYPE_USERSIG; } else if ( ( strcmp(m->desc, "boot") == 0 ) ) { 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; } else { cmd[1] = MTYPE_SPM; } - serial_recv_timeout = 100; + serial_recv_timeout = 200; for (; addr < maxaddr; addr += page_size) { if ((maxaddr - addr) < page_size) block_size = maxaddr - addr; @@ -2143,11 +2143,11 @@ static int jtagmkII_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m, cmd[0] = CMND_READ_MEMORY; if (strcmp(m->desc, "flash") == 0) { 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 */ dynamic_memtype = 1; } 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) return -1; } 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; } else if ( ( strcmp(m->desc, "boot") == 0 ) ) { 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; } else { cmd[1] = MTYPE_SPM; @@ -2241,7 +2241,7 @@ static int jtagmkII_read_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem, unsupp = 0; 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 || strcmp(mem->desc, "application") == 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; cache_ptr = PDATA(pgm)->flash_pagecache; } 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 */ cmd[1] = MTYPE_EEPROM; } else { @@ -2417,7 +2417,7 @@ static int jtagmkII_write_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem, writedata = data; 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 ((addr & 1) == 1) { /* 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) unsupp = 1; } 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; PDATA(pgm)->eeprom_pageaddr = (unsigned long)-1L; } 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) { - if ( p->flags & AVRPART_HAS_PDI ) { + if ( p->flags & (AVRPART_HAS_PDI | AVRPART_HAS_UPDI) ) { if (addr >= PDATA(pgm)->boot_start) return MTYPE_BOOT_FLASH; 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 * 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) /* * 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->flag = PGM_FL_IS_PDI; } -