Submitted by Jan Egil Ruud <janegil.ruud@microchip.com>

patch #9482: Add support for UPDI and AVR8X
* avrdude.conf.in (xplainedpro_updi): New programmer
* avrdude.conf.in (.avr8x, ATtiny1617, ATtiny817): New device
family and devices
* config_gram.y: add K_OCD_BASE and K_HAS_UPDI
* lexer.l: (Ditto.)
* doc/avrdude.texi: Document "has_updi" flag
* jtag3.c: Implement UPDI
* jtag3.h: (Ditto.)
* jtag3_private.h: (Ditto.)
* libavrdude.h: Add ocd_base value and AVRPART_HAS_UPDI flag
* pgm_type.c: Add jtagice3_updi




git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk/avrdude@1398 81a1dc3b-b13d-400b-aceb-764788c761c2
This commit is contained in:
Joerg Wunsch 2017-11-29 23:09:51 +00:00
parent 492a7b6709
commit 186656b855
12 changed files with 335 additions and 10 deletions

View File

@ -23,6 +23,7 @@ Contributors:
Brett Hagman <bhagman@roguerobotics.com> Brett Hagman <bhagman@roguerobotics.com>
Rene Liebscher <r.liebscher@gmx.de> Rene Liebscher <r.liebscher@gmx.de>
Jim Paris <jim@jtan.com> Jim Paris <jim@jtan.com>
Jan Egil Ruud <janegil.ruud@microchip.com>
For minor contributions, please see the ChangeLog files. For minor contributions, please see the ChangeLog files.

View File

@ -1,3 +1,19 @@
2017-11-29 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
Submitted by Jan Egil Ruud <janegil.ruud@microchip.com>
patch #9482: Add support for UPDI and AVR8X
* avrdude.conf.in (xplainedpro_updi): New programmer
* avrdude.conf.in (.avr8x, ATtiny1617, ATtiny817): New device
family and devices
* config_gram.y: add K_OCD_BASE and K_HAS_UPDI
* lexer.l: (Ditto.)
* doc/avrdude.texi: Document "has_updi" flag
* jtag3.c: Implement UPDI
* jtag3.h: (Ditto.)
* jtag3_private.h: (Ditto.)
* libavrdude.h: Add ocd_base value and AVRPART_HAS_UPDI flag
* pgm_type.c: Add jtagice3_updi
2017-11-29 Joerg Wunsch <j.gnu@uriah.heep.sax.de> 2017-11-29 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
Submitted by Jan Egil Ruud <janegil.ruud@microchip.com> Submitted by Jan Egil Ruud <janegil.ruud@microchip.com>

6
NEWS
View File

@ -12,20 +12,26 @@ Current:
- libhidapi support (part of patch #8717) - libhidapi support (part of patch #8717)
- use libhidapi as (optional) transport for CMSIS-DAP compliant - use libhidapi as (optional) transport for CMSIS-DAP compliant
debuggers (JTAGICE3 with firmware 3+, AtmelICE, EDBG, mEDBG) debuggers (JTAGICE3 with firmware 3+, AtmelICE, EDBG, mEDBG)
- UPDI support added (AVR8X family)
* New devices supported: * New devices supported:
- ATmega328PB - ATmega328PB
- AVR8X family, ATtiny1617, ATtiny817
* New programmers supported: * New programmers supported:
- ehajo-isp (commercial version of USBtiny) - ehajo-isp (commercial version of USBtiny)
- XplainedPro in UPDI mode
* Bugfixes: * Bugfixes:
bug #47550: Linux GPIO broken bug #47550: Linux GPIO broken
bug #47718: "lfuse reads as" not displayed in verbose mode - SOLUTION bug #47718: "lfuse reads as" not displayed in verbose mode - SOLUTION
bug #48084: Avoid compiled-in timestamp for reproducible release builds bug #48084: Avoid compiled-in timestamp for reproducible release builds
* Patches:
patch #9482: Add support for UPDI and AVR8X
* Internals: * Internals:

View File

@ -55,6 +55,7 @@
# has_jtag = <yes/no> ; # part has JTAG i/f # has_jtag = <yes/no> ; # part has JTAG i/f
# has_debugwire = <yes/no> ; # part has debugWire i/f # has_debugwire = <yes/no> ; # part has debugWire i/f
# has_pdi = <yes/no> ; # part has PDI i/f # has_pdi = <yes/no> ; # part has PDI i/f
# has_updi = <yes/no> ; # part has UPDI i/f
# has_tpi = <yes/no> ; # part has TPI i/f # has_tpi = <yes/no> ; # part has TPI i/f
# devicecode = <num> ; # deprecated, use stk500_devcode # devicecode = <num> ; # deprecated, use stk500_devcode
# stk500_devcode = <num> ; # numeric # stk500_devcode = <num> ; # numeric
@ -1104,6 +1105,14 @@ programmer
usbpid = 0x2111; usbpid = 0x2111;
; ;
programmer
id = "xplainedpro_updi";
desc = "Atmel AVR XplainedPro in UPDI mode";
type = "jtagice3_updi";
connection_type = usb;
usbpid = 0x2111;
;
programmer programmer
id = "xplainedmini"; id = "xplainedmini";
desc = "Atmel AVR XplainedMini in ISP mode"; desc = "Atmel AVR XplainedMini in ISP mode";
@ -1136,6 +1145,14 @@ programmer
usbpid = 0x2141; usbpid = 0x2141;
; ;
programmer
id = "atmelice_updi";
desc = "Atmel-ICE (ARM/AVR) in UPDI mode";
type = "jtagice3_updi";
connection_type = usb;
usbpid = 0x2141;
;
programmer programmer
id = "atmelice_dw"; id = "atmelice_dw";
desc = "Atmel-ICE (ARM/AVR) in debugWIRE mode"; desc = "Atmel-ICE (ARM/AVR) in debugWIRE mode";
@ -14989,4 +15006,136 @@ part
; ;
; ;
#------------------------------------------------------------
# AVR8X family common values
#------------------------------------------------------------
part
id = ".avr8x";
desc = "AVR8X family common values";
has_updi = yes;
nvm_base = 0x1000;
ocd_base = 0x0F80;
memory "signature"
size = 3;
offset = 0x1100;
;
memory "userrow"
size = 0x20;
offset = 0x1300;
page_size = 0x20;
readsize = 0x100;
;
memory "prodsig"
size = 0x3D;
offset = 0x1103;
page_size = 0x3D;
readsize = 0x3D;
;
memory "fuses"
size = 9;
offset = 0x1280;
;
memory "fuse0"
size = 1;
offset = 0x1280;
;
memory "fuse1"
size = 1;
offset = 0x1281;
;
memory "fuse2"
size = 1;
offset = 0x1282;
;
memory "fuse4"
size = 1;
offset = 0x1284;
;
memory "fuse5"
size = 1;
offset = 0x1285;
;
memory "fuse6"
size = 1;
offset = 0x1286;
;
memory "fuse7"
size = 1;
offset = 0x1287;
;
memory "fuse8"
size = 1;
offset = 0x1288;
;
memory "lock"
size = 1;
offset = 0x128a;
;
memory "data"
# SRAM, only used to supply the offset
offset = 0x1000000;
;
;
#------------------------------------------------------------
# ATtiny1617
#------------------------------------------------------------
part parent ".avr8x"
id = "tn1617";
desc = "ATtiny1617";
signature = 0x1e 0x94 0x20;
memory "eeprom"
size = 0x0100;
offset = 0x1400;
page_size = 0x20;
readsize = 0x100;
;
memory "flash"
size = 0x4000;
offset = 0x8000;
page_size = 0x40;
readsize = 0x100;
;
;
#------------------------------------------------------------
# ATtiny817
#------------------------------------------------------------
part parent ".avr8x"
id = "tn817";
desc = "ATtiny817";
signature = 0x1e 0x93 0x20;
memory "eeprom"
size = 0x0100;
offset = 0x1400;
page_size = 0x20;
readsize = 0x100;
;
memory "flash"
size = 0x2000;
offset = 0x8000;
page_size = 0x40;
readsize = 0x100;
;
;

View File

@ -96,6 +96,7 @@ static int pin_name;
%token K_MOSI %token K_MOSI
%token K_NUM_PAGES %token K_NUM_PAGES
%token K_NVM_BASE %token K_NVM_BASE
%token K_OCD_BASE
%token K_OCDREV %token K_OCDREV
%token K_OFFSET %token K_OFFSET
%token K_PAGEL %token K_PAGEL
@ -183,6 +184,7 @@ static int pin_name;
%token K_HAS_JTAG /* MCU has JTAG i/f. */ %token K_HAS_JTAG /* MCU has JTAG i/f. */
%token K_HAS_DW /* MCU has debugWire i/f. */ %token K_HAS_DW /* MCU has debugWire i/f. */
%token K_HAS_PDI /* MCU has PDI i/f rather than ISP (ATxmega). */ %token K_HAS_PDI /* MCU has PDI i/f rather than ISP (ATxmega). */
%token K_HAS_UPDI /* MCU has UPDI i/f (AVR8X). */
%token K_HAS_TPI /* MCU has TPI i/f rather than ISP (ATtiny4/5/9/10). */ %token K_HAS_TPI /* MCU has TPI i/f rather than ISP (ATtiny4/5/9/10). */
%token K_IDR /* address of OCD register in IO space */ %token K_IDR /* address of OCD register in IO space */
%token K_IS_AT90S1200 /* chip is an AT90S1200 (needs special treatment) */ %token K_IS_AT90S1200 /* chip is an AT90S1200 (needs special treatment) */
@ -1062,6 +1064,16 @@ part_parm :
free_token($3); free_token($3);
} | } |
K_HAS_UPDI TKN_EQUAL yesno
{
if ($3->primary == K_YES)
current_part->flags |= AVRPART_HAS_UPDI;
else if ($3->primary == K_NO)
current_part->flags &= ~AVRPART_HAS_UPDI;
free_token($3);
} |
K_HAS_TPI TKN_EQUAL yesno K_HAS_TPI TKN_EQUAL yesno
{ {
if ($3->primary == K_YES) if ($3->primary == K_YES)
@ -1148,6 +1160,12 @@ part_parm :
free_token($3); free_token($3);
} | } |
K_OCD_BASE TKN_EQUAL TKN_NUMBER
{
current_part->ocd_base = $3->value.number;
free_token($3);
} |
K_OCDREV TKN_EQUAL TKN_NUMBER K_OCDREV TKN_EQUAL TKN_NUMBER
{ {
current_part->ocdrev = $3->value.number; current_part->ocdrev = $3->value.number;

View File

@ -1440,6 +1440,7 @@ part
has_jtag = <yes/no> ; # part has JTAG i/f has_jtag = <yes/no> ; # part has JTAG i/f
has_debugwire = <yes/no> ; # part has debugWire i/f has_debugwire = <yes/no> ; # part has debugWire i/f
has_pdi = <yes/no> ; # part has PDI i/f has_pdi = <yes/no> ; # part has PDI i/f
has_updi = <yes/no> ; # part has UPDI i/f
has_tpi = <yes/no> ; # part has TPI i/f has_tpi = <yes/no> ; # part has TPI i/f
devicecode = <num> ; # numeric devicecode = <num> ; # numeric
stk500_devcode = <num> ; # numeric stk500_devcode = <num> ; # numeric

130
jtag3.c
View File

@ -84,6 +84,7 @@ struct pdata
#define PGM_FL_IS_PDI (0x0002) #define PGM_FL_IS_PDI (0x0002)
#define PGM_FL_IS_JTAG (0x0004) #define PGM_FL_IS_JTAG (0x0004)
#define PGM_FL_IS_EDBG (0x0008) #define PGM_FL_IS_EDBG (0x0008)
#define PGM_FL_IS_UPDI (0x0010)
static int jtag3_open(PROGRAMMER * pgm, char * port); static int jtag3_open(PROGRAMMER * pgm, char * port);
static int jtag3_edbg_prepare(PROGRAMMER * pgm); static int jtag3_edbg_prepare(PROGRAMMER * pgm);
@ -1014,6 +1015,10 @@ static int jtag3_initialize(PROGRAMMER * pgm, AVRPART * p)
ifname = "PDI"; ifname = "PDI";
if (p->flags & AVRPART_HAS_PDI) if (p->flags & AVRPART_HAS_PDI)
conn = PARM3_CONN_PDI; conn = PARM3_CONN_PDI;
} else if (pgm->flag & PGM_FL_IS_UPDI) {
ifname = "UPDI";
if (p->flags & AVRPART_HAS_UPDI)
conn = PARM3_CONN_UPDI;
} else { } else {
ifname = "JTAG"; ifname = "JTAG";
if (p->flags & AVRPART_HAS_JTAG) if (p->flags & AVRPART_HAS_JTAG)
@ -1028,6 +1033,8 @@ static int jtag3_initialize(PROGRAMMER * pgm, AVRPART * p)
if (p->flags & AVRPART_HAS_PDI) if (p->flags & AVRPART_HAS_PDI)
parm[0] = PARM3_ARCH_XMEGA; parm[0] = PARM3_ARCH_XMEGA;
else if (p->flags & AVRPART_HAS_UPDI)
parm[0] = PARM3_ARCH_UPDI;
else if (p->flags & AVRPART_HAS_DW) else if (p->flags & AVRPART_HAS_DW)
parm[0] = PARM3_ARCH_TINY; parm[0] = PARM3_ARCH_TINY;
else else
@ -1043,7 +1050,7 @@ static int jtag3_initialize(PROGRAMMER * pgm, AVRPART * p)
if (jtag3_setparm(pgm, SCOPE_AVR, 1, PARM3_CONNECTION, parm, 1) < 0) if (jtag3_setparm(pgm, SCOPE_AVR, 1, PARM3_CONNECTION, parm, 1) < 0)
return -1; return -1;
if (conn == PARM3_CONN_PDI) if (conn == PARM3_CONN_PDI || conn == PARM3_CONN_UPDI)
PDATA(pgm)->set_sck = jtag3_set_sck_xmega_pdi; PDATA(pgm)->set_sck = jtag3_set_sck_xmega_pdi;
else if (conn == PARM3_CONN_JTAG) { else if (conn == PARM3_CONN_JTAG) {
if (p->flags & AVRPART_HAS_PDI) if (p->flags & AVRPART_HAS_PDI)
@ -1119,6 +1126,50 @@ static int jtag3_initialize(PROGRAMMER * pgm, AVRPART * p)
if (jtag3_setparm(pgm, SCOPE_AVR, 2, PARM3_DEVICEDESC, (unsigned char *)&xd, sizeof xd) < 0) if (jtag3_setparm(pgm, SCOPE_AVR, 2, PARM3_DEVICEDESC, (unsigned char *)&xd, sizeof xd) < 0)
return -1; return -1;
} }
else if ((p->flags & AVRPART_HAS_UPDI))
{
struct updi_device_desc xd;
LNODEID ln;
AVRMEM *m;
u16_to_b2(xd.nvm_base_addr, p->nvm_base);
u16_to_b2(xd.ocd_base_addr, p->ocd_base);
for (ln = lfirst(p->mem); ln; ln = lnext(ln))
{
m = ldata(ln);
if (strcmp(m->desc, "flash") == 0)
{
u16_to_b2(xd.prog_base, m->offset);
if (m->readsize != 0 && m->readsize < m->page_size)
PDATA(pgm)->flash_pagesize = m->readsize;
else
PDATA(pgm)->flash_pagesize = m->page_size;
xd.flash_page_size = m->page_size;
}
else if (strcmp(m->desc, "eeprom") == 0)
{
PDATA(pgm)->eeprom_pagesize = m->page_size;
xd.eeprom_page_size = m->page_size;
}
}
avrdude_message(MSG_NOTICE2, "UPDI SET: \n\t"
"xd->prog_base=%x %x\n\t"
"xd->flash_page_size=%x\n\t"
"xd->eeprom_page_size=%x\n\t"
"xd->nvmctrl=%x %x\n\t"
"xd->ocd=%x %x\n",
xd.prog_base[0], xd.prog_base[1],
xd.flash_page_size,
xd.eeprom_page_size,
xd.nvm_base_addr[0], xd.nvm_base_addr[1],
xd.ocd_base_addr[0], xd.ocd_base_addr[1]);
if (jtag3_setparm(pgm, SCOPE_AVR, 2, PARM3_DEVICEDESC, (unsigned char *)&xd, sizeof xd) < 0)
return -1;
}
else else
{ {
struct mega_device_desc md; struct mega_device_desc md;
@ -1443,6 +1494,18 @@ static int jtag3_open_pdi(PROGRAMMER * pgm, char * port)
return 0; return 0;
} }
static int jtag3_open_updi(PROGRAMMER * pgm, char * port)
{
avrdude_message(MSG_NOTICE2, "%s: jtag3_open_updi()\n", progname);
if (jtag3_open_common(pgm, port) < 0)
return -1;
if (jtag3_getsync(pgm, PARM3_CONN_UPDI) < 0)
return -1;
return 0;
}
void jtag3_close(PROGRAMMER * pgm) void jtag3_close(PROGRAMMER * pgm)
{ {
@ -1571,7 +1634,7 @@ static int jtag3_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
cmd[3] = MTYPE_USERSIG; cmd[3] = MTYPE_USERSIG;
} else if ( ( strcmp(m->desc, "boot") == 0 ) ) { } else if ( ( strcmp(m->desc, "boot") == 0 ) ) {
cmd[3] = MTYPE_BOOT_FLASH; cmd[3] = MTYPE_BOOT_FLASH;
} else if ( p->flags & AVRPART_HAS_PDI ) { } else if ( p->flags & AVRPART_HAS_PDI || p->flags & AVRPART_HAS_UPDI ) {
cmd[3] = MTYPE_FLASH; cmd[3] = MTYPE_FLASH;
} else { } else {
cmd[3] = MTYPE_SPM; cmd[3] = MTYPE_SPM;
@ -1648,7 +1711,7 @@ static int jtag3_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
/* 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[3] = ( p->flags & AVRPART_HAS_PDI ) ? MTYPE_EEPROM : MTYPE_EEPROM_PAGE; cmd[3] = ( p->flags & AVRPART_HAS_PDI || p->flags & 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 ) ) {
@ -1657,7 +1720,7 @@ static int jtag3_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
cmd[3] = MTYPE_USERSIG; cmd[3] = MTYPE_USERSIG;
} else if ( ( strcmp(m->desc, "boot") == 0 ) ) { } else if ( ( strcmp(m->desc, "boot") == 0 ) ) {
cmd[3] = MTYPE_BOOT_FLASH; cmd[3] = MTYPE_BOOT_FLASH;
} else if ( p->flags & AVRPART_HAS_PDI ) { } else if ( p->flags & AVRPART_HAS_PDI || p->flags & AVRPART_HAS_UPDI ) {
cmd[3] = MTYPE_FLASH; cmd[3] = MTYPE_FLASH;
} else { } else {
cmd[3] = MTYPE_SPM; cmd[3] = MTYPE_SPM;
@ -1716,7 +1779,9 @@ static int jtag3_read_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
cmd[1] = CMD3_READ_MEMORY; cmd[1] = CMD3_READ_MEMORY;
cmd[2] = 0; cmd[2] = 0;
cmd[3] = ( p->flags & AVRPART_HAS_PDI ) ? MTYPE_FLASH : MTYPE_FLASH_PAGE; cmd[3] = ( p->flags & AVRPART_HAS_PDI || p->flags & AVRPART_HAS_UPDI ) ? MTYPE_FLASH : MTYPE_FLASH_PAGE;
if (p->flags & AVRPART_HAS_UPDI)
addr += mem->offset;
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 ||
@ -1727,7 +1792,7 @@ static int jtag3_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 ) || ( p->flags & AVRPART_HAS_UPDI ) ) {
cmd[3] = MTYPE_EEPROM; cmd[3] = MTYPE_EEPROM;
} else { } else {
cmd[3] = MTYPE_EEPROM_PAGE; cmd[3] = MTYPE_EEPROM_PAGE;
@ -1757,6 +1822,7 @@ static int jtag3_read_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
unsupp = 1; unsupp = 1;
} else if (strncmp(mem->desc, "fuse", strlen("fuse")) == 0) { } else if (strncmp(mem->desc, "fuse", strlen("fuse")) == 0) {
cmd[3] = MTYPE_FUSE_BITS; cmd[3] = MTYPE_FUSE_BITS;
if (!(p->flags & AVRPART_HAS_UPDI))
addr = mem->offset & 7; addr = mem->offset & 7;
} else if (strcmp(mem->desc, "usersig") == 0) { } else if (strcmp(mem->desc, "usersig") == 0) {
cmd[3] = MTYPE_USERSIG; cmd[3] = MTYPE_USERSIG;
@ -1778,7 +1844,11 @@ static int jtag3_read_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
* harm for other connection types either. * harm for other connection types either.
*/ */
u32_to_b4(cmd + 8, 3); u32_to_b4(cmd + 8, 3);
u32_to_b4(cmd + 4, 0); u32_to_b4(cmd + 4, mem->offset);
if (p->flags & AVRPART_HAS_UPDI){
addr -= mem->offset;
}
if (addr == 0) { if (addr == 0) {
if ((status = jtag3_command(pgm, cmd, 12, &resp, "read memory")) < 0) if ((status = jtag3_command(pgm, cmd, 12, &resp, "read memory")) < 0)
@ -1867,7 +1937,9 @@ static int jtag3_write_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
cmd[0] = SCOPE_AVR; cmd[0] = SCOPE_AVR;
cmd[1] = CMD3_WRITE_MEMORY; cmd[1] = CMD3_WRITE_MEMORY;
cmd[2] = 0; cmd[2] = 0;
cmd[3] = ( p->flags & AVRPART_HAS_PDI ) ? MTYPE_FLASH : MTYPE_SPM; cmd[3] = ( p->flags & AVRPART_HAS_PDI || p->flags & AVRPART_HAS_UPDI ) ? MTYPE_FLASH : MTYPE_SPM;
if (p->flags & AVRPART_HAS_UPDI)
addr += mem->offset;
if (strcmp(mem->desc, "flash") == 0) { if (strcmp(mem->desc, "flash") == 0) {
cache_ptr = PDATA(pgm)->flash_pagecache; cache_ptr = PDATA(pgm)->flash_pagecache;
pagesize = PDATA(pgm)->flash_pagesize; pagesize = PDATA(pgm)->flash_pagesize;
@ -1899,9 +1971,12 @@ static int jtag3_write_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
unsupp = 1; unsupp = 1;
} else if (strncmp(mem->desc, "fuse", strlen("fuse")) == 0) { } else if (strncmp(mem->desc, "fuse", strlen("fuse")) == 0) {
cmd[3] = MTYPE_FUSE_BITS; cmd[3] = MTYPE_FUSE_BITS;
if (!(p->flags & AVRPART_HAS_UPDI))
addr = mem->offset & 7; addr = mem->offset & 7;
} else if (strcmp(mem->desc, "usersig") == 0) { } else if (strcmp(mem->desc, "usersig") == 0) {
cmd[3] = MTYPE_USERSIG; cmd[3] = MTYPE_USERSIG;
} else if (strcmp(mem->desc, "userrow") == 0) {
cmd[3] = MTYPE_USERSIG;
} else if (strcmp(mem->desc, "prodsig") == 0) { } else if (strcmp(mem->desc, "prodsig") == 0) {
cmd[3] = MTYPE_PRODSIG; cmd[3] = MTYPE_PRODSIG;
} else if (strncmp(mem->desc, "lock", 4) == 0) { } else if (strncmp(mem->desc, "lock", 4) == 0) {
@ -2179,6 +2254,11 @@ static unsigned int jtag3_memaddr(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m, uns
/* /*
* Non-Xmega device. * Non-Xmega device.
*/ */
if (p->flags & AVRPART_HAS_UPDI) {
if (strcmp(m->desc, "flash") != 0) {
addr += m->offset;
}
}
return addr; return addr;
} }
@ -2284,3 +2364,37 @@ void jtag3_pdi_initpgm(PROGRAMMER * pgm)
pgm->flag = PGM_FL_IS_PDI; pgm->flag = PGM_FL_IS_PDI;
} }
const char jtag3_updi_desc[] = "Atmel JTAGICE3 in UPDI mode";
void jtag3_updi_initpgm(PROGRAMMER * pgm)
{
strcpy(pgm->type, "JTAGICE3_UPDI");
/*
* mandatory functions
*/
pgm->initialize = jtag3_initialize;
pgm->display = jtag3_display;
pgm->enable = jtag3_enable;
pgm->disable = jtag3_disable;
pgm->program_enable = jtag3_program_enable_dummy;
pgm->chip_erase = jtag3_chip_erase;
pgm->open = jtag3_open_updi;
pgm->close = jtag3_close;
pgm->read_byte = jtag3_read_byte;
pgm->write_byte = jtag3_write_byte;
/*
* optional functions
*/
pgm->paged_write = jtag3_paged_write;
pgm->paged_load = jtag3_paged_load;
pgm->page_erase = jtag3_page_erase;
pgm->print_parms = jtag3_print_parms;
pgm->set_sck_period = jtag3_set_sck_period;
pgm->setup = jtag3_setup;
pgm->teardown = jtag3_teardown;
pgm->page_size = 256;
pgm->flag = PGM_FL_IS_UPDI;
}

View File

@ -41,9 +41,11 @@ int jtag3_command(PROGRAMMER *pgm, unsigned char *cmd, unsigned int cmdlen,
extern const char jtag3_desc[]; extern const char jtag3_desc[];
extern const char jtag3_dw_desc[]; extern const char jtag3_dw_desc[];
extern const char jtag3_pdi_desc[]; extern const char jtag3_pdi_desc[];
extern const char jtag3_updi_desc[];
void jtag3_initpgm (PROGRAMMER * pgm); void jtag3_initpgm (PROGRAMMER * pgm);
void jtag3_dw_initpgm (PROGRAMMER * pgm); void jtag3_dw_initpgm (PROGRAMMER * pgm);
void jtag3_pdi_initpgm (PROGRAMMER * pgm); void jtag3_pdi_initpgm (PROGRAMMER * pgm);
void jtag3_updi_initpgm (PROGRAMMER * pgm);
/* /*
* These functions are referenced from stk500v2.c for JTAGICE3 in * These functions are referenced from stk500v2.c for JTAGICE3 in

View File

@ -109,6 +109,7 @@
#define CMD3_GET_PARAMETER 0x02 #define CMD3_GET_PARAMETER 0x02
#define CMD3_SIGN_ON 0x10 #define CMD3_SIGN_ON 0x10
#define CMD3_SIGN_OFF 0x11 /* takes one parameter? */ #define CMD3_SIGN_OFF 0x11 /* takes one parameter? */
#define CMD3_GET_ID 0x12
#define CMD3_START_DW_DEBUG 0x13 #define CMD3_START_DW_DEBUG 0x13
#define CMD3_MONCON_DISABLE 0x17 #define CMD3_MONCON_DISABLE 0x17
@ -165,6 +166,7 @@
#define MTYPE_EEPROM_XMEGA 0xc4 /* xmega EEPROM in debug mode - undocumented in AVR067 */ #define MTYPE_EEPROM_XMEGA 0xc4 /* xmega EEPROM in debug mode - undocumented in AVR067 */
#define MTYPE_USERSIG 0xc5 /* xmega user signature - undocumented in AVR067 */ #define MTYPE_USERSIG 0xc5 /* xmega user signature - undocumented in AVR067 */
#define MTYPE_PRODSIG 0xc6 /* xmega production signature - undocumented in AVR067 */ #define MTYPE_PRODSIG 0xc6 /* xmega production signature - undocumented in AVR067 */
#define MTYPE_SIB 0xD3 /* AVR8X System Information Block */
/* /*
* Parameters are divided into sections, where the section number * Parameters are divided into sections, where the section number
@ -189,6 +191,7 @@
# define PARM3_ARCH_TINY 1 /* also small megaAVR with ISP/DW only */ # define PARM3_ARCH_TINY 1 /* also small megaAVR with ISP/DW only */
# define PARM3_ARCH_MEGA 2 # define PARM3_ARCH_MEGA 2
# define PARM3_ARCH_XMEGA 3 # define PARM3_ARCH_XMEGA 3
# define PARM3_ARCH_UPDI 5 /* AVR devices with UPDI i/f */
#define PARM3_SESS_PURPOSE 0x01 /* section 0, AVR scope, 1 byte */ #define PARM3_SESS_PURPOSE 0x01 /* section 0, AVR scope, 1 byte */
# define PARM3_SESS_PROGRAMMING 1 # define PARM3_SESS_PROGRAMMING 1
@ -199,6 +202,7 @@
# define PARM3_CONN_JTAG 4 # define PARM3_CONN_JTAG 4
# define PARM3_CONN_DW 5 # define PARM3_CONN_DW 5
# define PARM3_CONN_PDI 6 # define PARM3_CONN_PDI 6
# define PARM3_CONN_UPDI 8
#define PARM3_JTAGCHAIN 0x01 /* JTAG chain info, AVR scope (units #define PARM3_JTAGCHAIN 0x01 /* JTAG chain info, AVR scope (units
@ -316,4 +320,13 @@ struct xmega_device_desc {
unsigned char nvm_base_addr[2]; // IO space base address of NVM controller unsigned char nvm_base_addr[2]; // IO space base address of NVM controller
unsigned char mcu_base_addr[2]; // IO space base address of MCU control unsigned char mcu_base_addr[2]; // IO space base address of MCU control
}; };
/* UPDI device descriptor */
struct updi_device_desc {
unsigned char prog_base[2];
unsigned char flash_page_size;
unsigned char eeprom_page_size;
unsigned char nvm_base_addr[2];
unsigned char ocd_base_addr[2];
};
#endif /* JTAG3_PRIVATE_EXPORTED */ #endif /* JTAG3_PRIVATE_EXPORTED */

View File

@ -152,6 +152,7 @@ has_debugwire { yylval=NULL; return K_HAS_DW; }
has_jtag { yylval=NULL; return K_HAS_JTAG; } has_jtag { yylval=NULL; return K_HAS_JTAG; }
has_pdi { yylval=NULL; return K_HAS_PDI; } has_pdi { yylval=NULL; return K_HAS_PDI; }
has_tpi { yylval=NULL; return K_HAS_TPI; } has_tpi { yylval=NULL; return K_HAS_TPI; }
has_updi { yylval=NULL; return K_HAS_UPDI; }
hventerstabdelay { yylval=NULL; return K_HVENTERSTABDELAY; } hventerstabdelay { yylval=NULL; return K_HVENTERSTABDELAY; }
hvleavestabdelay { yylval=NULL; return K_HVLEAVESTABDELAY; } hvleavestabdelay { yylval=NULL; return K_HVLEAVESTABDELAY; }
hvsp_controlstack { yylval=NULL; return K_HVSP_CONTROLSTACK; } hvsp_controlstack { yylval=NULL; return K_HVSP_CONTROLSTACK; }
@ -176,6 +177,7 @@ no { yylval=new_token(K_NO); return K_NO; }
num_banks { yylval=NULL; return K_NUM_PAGES; } num_banks { yylval=NULL; return K_NUM_PAGES; }
num_pages { yylval=NULL; return K_NUM_PAGES; } num_pages { yylval=NULL; return K_NUM_PAGES; }
nvm_base { yylval=NULL; return K_NVM_BASE; } nvm_base { yylval=NULL; return K_NVM_BASE; }
ocd_base { yylval=NULL; return K_OCD_BASE; }
ocdrev { yylval=NULL; return K_OCDREV; } ocdrev { yylval=NULL; return K_OCDREV; }
offset { yylval=NULL; return K_OFFSET; } offset { yylval=NULL; return K_OFFSET; }
page_size { yylval=NULL; return K_PAGE_SIZE; } page_size { yylval=NULL; return K_PAGE_SIZE; }

View File

@ -199,6 +199,7 @@ typedef struct opcode {
#define AVRPART_WRITE 0x0400 /* at least one write operation specified */ #define AVRPART_WRITE 0x0400 /* at least one write operation specified */
#define AVRPART_HAS_TPI 0x0800 /* part has TPI i/f rather than ISP (ATtiny4/5/9/10) */ #define AVRPART_HAS_TPI 0x0800 /* part has TPI i/f rather than ISP (ATtiny4/5/9/10) */
#define AVRPART_IS_AT90S1200 0x1000 /* part is an AT90S1200 (needs special treatment) */ #define AVRPART_IS_AT90S1200 0x1000 /* part is an AT90S1200 (needs special treatment) */
#define AVRPART_HAS_UPDI 0x2000 /* part has UPDI i/f (AVR8X) */
#define AVR_DESCLEN 64 #define AVR_DESCLEN 64
#define AVR_IDLEN 32 #define AVR_IDLEN 32
@ -264,6 +265,7 @@ typedef struct avrpart {
unsigned short eecr; /* JTAC ICE mkII XML file parameter */ unsigned short eecr; /* JTAC ICE mkII XML file parameter */
unsigned int mcu_base; /* Base address of MCU control block in ATxmega devices */ unsigned int mcu_base; /* Base address of MCU control block in ATxmega devices */
unsigned int nvm_base; /* Base address of NVM controller in ATxmega devices */ unsigned int nvm_base; /* Base address of NVM controller in ATxmega devices */
unsigned int ocd_base; /* Base address of OCD module in AVR8X/UPDI devices */
int ocdrev; /* OCD revision (JTAGICE3 parameter, from AS6 XML files) */ int ocdrev; /* OCD revision (JTAGICE3 parameter, from AS6 XML files) */
OPCODE * op[AVR_OP_MAX]; /* opcodes */ OPCODE * op[AVR_OP_MAX]; /* opcodes */

View File

@ -77,6 +77,7 @@ const PROGRAMMER_TYPE programmers_types[] = {
{"jtagmkii_pdi", jtagmkII_pdi_initpgm, jtagmkII_pdi_desc}, {"jtagmkii_pdi", jtagmkII_pdi_initpgm, jtagmkII_pdi_desc},
{"jtagice3", jtag3_initpgm, jtag3_desc}, {"jtagice3", jtag3_initpgm, jtag3_desc},
{"jtagice3_pdi", jtag3_pdi_initpgm, jtag3_pdi_desc}, {"jtagice3_pdi", jtag3_pdi_initpgm, jtag3_pdi_desc},
{"jtagice3_updi", jtag3_updi_initpgm, jtag3_updi_desc},
{"jtagice3_dw", jtag3_dw_initpgm, jtag3_dw_desc}, {"jtagice3_dw", jtag3_dw_initpgm, jtag3_dw_desc},
{"jtagice3_isp", stk500v2_jtag3_initpgm, stk500v2_jtag3_desc}, {"jtagice3_isp", stk500v2_jtag3_initpgm, stk500v2_jtag3_desc},
{"linuxgpio", linuxgpio_initpgm, linuxgpio_desc}, {"linuxgpio", linuxgpio_initpgm, linuxgpio_desc},