* pgm_type.c: Add "jtagice3_isp" programmer hook

* avrdude.conf.in: Add "jtag3isp" programmer
* jtag3.c: jtag3_setparm() is now public
* jtag3.h: (Dito)
* stk500v2_private.h: Command 0x1D is CMD_SPI_MULTI only
for STK500v2, AVRISPmkII, and JTAGICEmkII; for JTAGICE3,
it's CMD_SET_SCK now; also add CMD_GET_SCK
* avrpart.c (avr_get_output_index): New function
* avrpart.h: (Dito)
* stk500v2.c: Implement the pasthrough programmer glue logic
for JTAGICE3 in ISP mode
* stk500v2.h: (Dito)
* avrdude.1: Document the JTAGICE3 support.



git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk/avrdude@1119 81a1dc3b-b13d-400b-aceb-764788c761c2
This commit is contained in:
joerg_wunsch
2012-12-03 15:52:38 +00:00
parent de55b22e86
commit 97357595b6
12 changed files with 707 additions and 22 deletions

View File

@@ -67,6 +67,10 @@
#define JTAGMKII_PRIVATE_EXPORTED
#include "jtagmkII_private.h"
#include "jtag3.h" // public interfaces from jtagmkII.c
#define JTAG3_PRIVATE_EXPORTED
#include "jtag3_private.h"
#define STK500V2_XTAL 7372800U
// Timeout (in seconds) for waiting for serial response
@@ -113,6 +117,7 @@ static const char *pgmname[] =
"AVRISP mkII",
"JTAG ICE mkII",
"STK600",
"JTAGICE3",
};
struct jtagispentry
@@ -267,6 +272,12 @@ static int stk500v2_getparm2(PROGRAMMER * pgm, unsigned char parm, unsigned int
static int stk500v2_setparm2(PROGRAMMER * pgm, unsigned char parm, unsigned int value);
static int stk500v2_setparm_real(PROGRAMMER * pgm, unsigned char parm, unsigned char value);
static void stk500v2_print_parms1(PROGRAMMER * pgm, const char * p);
static int stk500v2_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
unsigned int page_size,
unsigned int addr, unsigned int n_bytes);
static int stk500v2_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
unsigned int page_size,
unsigned int addr, unsigned int n_bytes);
static unsigned int stk500v2_mode_for_pagesize(unsigned int pagesize);
@@ -315,6 +326,30 @@ static void stk500v2_jtagmkII_setup(PROGRAMMER * pgm)
PDATA(pgm)->chained_pdata = theircookie;
}
static void stk500v2_jtag3_setup(PROGRAMMER * pgm)
{
void *mycookie, *theircookie;
if ((pgm->cookie = malloc(sizeof(struct pdata))) == 0) {
fprintf(stderr,
"%s: stk500v2_setup(): Out of memory allocating private data\n",
progname);
exit(1);
}
memset(pgm->cookie, 0, sizeof(struct pdata));
PDATA(pgm)->command_sequence = 1;
/*
* Now, have the JTAGICE3 backend allocate its own private
* data. Store our own cookie in a safe place for the time being.
*/
mycookie = pgm->cookie;
jtag3_setup(pgm);
theircookie = pgm->cookie;
pgm->cookie = mycookie;
PDATA(pgm)->chained_pdata = theircookie;
}
void stk500v2_teardown(PROGRAMMER * pgm)
{
free(pgm->cookie);
@@ -331,6 +366,17 @@ static void stk500v2_jtagmkII_teardown(PROGRAMMER * pgm)
free(mycookie);
}
static void stk500v2_jtag3_teardown(PROGRAMMER * pgm)
{
void *mycookie;
mycookie = pgm->cookie;
pgm->cookie = PDATA(pgm)->chained_pdata;
jtag3_teardown(pgm);
free(mycookie);
}
static unsigned short
b2_to_u16(unsigned char *b)
@@ -415,6 +461,31 @@ static int stk500v2_jtagmkII_send(PROGRAMMER * pgm, unsigned char * data, size_t
return rv;
}
/*
* Send the data as a JTAGICE3 encapsulated ISP packet.
*/
static int stk500v2_jtag3_send(PROGRAMMER * pgm, unsigned char * data, size_t len)
{
unsigned char *cmdbuf;
int rv;
void *mycookie;
if ((cmdbuf = malloc(len + 1)) == NULL) {
fprintf(stderr, "%s: out of memory for command packet\n",
progname);
exit(1);
}
mycookie = pgm->cookie;
pgm->cookie = PDATA(pgm)->chained_pdata;
cmdbuf[0] = SCOPE_AVR_ISP;
memcpy(cmdbuf + 1, data, len);
rv = jtag3_send(pgm, cmdbuf, len + 1);
free(cmdbuf);
pgm->cookie = mycookie;
return rv;
}
static int stk500v2_send(PROGRAMMER * pgm, unsigned char * data, size_t len)
{
unsigned char buf[275 + 6]; // max MESSAGE_BODY of 275 bytes, 6 bytes overhead
@@ -425,6 +496,8 @@ static int stk500v2_send(PROGRAMMER * pgm, unsigned char * data, size_t len)
return stk500v2_send_mk2(pgm, data, len);
else if (PDATA(pgm)->pgmtype == PGMTYPE_JTAGICE_MKII)
return stk500v2_jtagmkII_send(pgm, data, len);
else if (PDATA(pgm)->pgmtype == PGMTYPE_JTAGICE3)
return stk500v2_jtag3_send(pgm, data, len);
buf[0] = MESSAGE_START;
buf[1] = PDATA(pgm)->command_sequence;
@@ -512,6 +585,40 @@ static int stk500v2_jtagmkII_recv(PROGRAMMER * pgm, unsigned char msg[],
return rv;
}
static int stk500v2_jtag3_recv(PROGRAMMER * pgm, unsigned char msg[],
size_t maxsize)
{
int rv;
unsigned char *jtagmsg;
void *mycookie;
mycookie = pgm->cookie;
pgm->cookie = PDATA(pgm)->chained_pdata;
rv = jtag3_recv(pgm, &jtagmsg);
pgm->cookie = mycookie;
if (rv <= 0) {
fprintf(stderr, "%s: stk500v2_jtag3_recv(): error in jtagmkII_recv()\n",
progname);
return -1;
}
if (rv - 1 > maxsize) {
fprintf(stderr,
"%s: stk500v2_jtag3_recv(): got %u bytes, have only room for %u bytes\n",
progname, (unsigned)rv - 1, (unsigned)maxsize);
rv = maxsize;
}
if (jtagmsg[0] != SCOPE_AVR_ISP) {
fprintf(stderr,
"%s: stk500v2_jtag3_recv(): message is not AVR ISP: 0x%02x\n",
progname, jtagmsg[0]);
free(jtagmsg);
return -1;
}
memcpy(msg, jtagmsg + 1, rv - 1);
free(jtagmsg);
return rv;
}
static int stk500v2_recv(PROGRAMMER * pgm, unsigned char msg[], size_t maxsize) {
enum states { sINIT, sSTART, sSEQNUM, sSIZE1, sSIZE2, sTOKEN, sDATA, sCSUM, sDONE } state = sSTART;
unsigned int msglen = 0;
@@ -528,6 +635,8 @@ static int stk500v2_recv(PROGRAMMER * pgm, unsigned char msg[], size_t maxsize)
return stk500v2_recv_mk2(pgm, msg, maxsize);
else if (PDATA(pgm)->pgmtype == PGMTYPE_JTAGICE_MKII)
return stk500v2_jtagmkII_recv(pgm, msg, maxsize);
else if (PDATA(pgm)->pgmtype == PGMTYPE_JTAGICE3)
return stk500v2_jtag3_recv(pgm, msg, maxsize);
DEBUG("STK500V2: stk500v2_recv(): ");
@@ -632,7 +741,8 @@ int stk500v2_getsync(PROGRAMMER * pgm) {
DEBUG("STK500V2: stk500v2_getsync()\n");
if (PDATA(pgm)->pgmtype == PGMTYPE_JTAGICE_MKII)
if (PDATA(pgm)->pgmtype == PGMTYPE_JTAGICE_MKII ||
PDATA(pgm)->pgmtype == PGMTYPE_JTAGICE3)
return 0;
retry:
@@ -796,6 +906,10 @@ retry:
fprintf(stderr,
"%s: stk500v2_command(): command failed\n",
progname);
} else if (buf[1] == STATUS_CMD_UNKNOWN) {
fprintf(stderr,
"%s: stk500v2_command(): unknown command\n",
progname);
} else {
fprintf(stderr, "%s: stk500v2_command(): unknown status 0x%02x\n",
progname, buf[1]);
@@ -856,6 +970,17 @@ static int stk500v2_cmd(PROGRAMMER * pgm, unsigned char cmd[4],
}
static int stk500v2_jtag3_cmd(PROGRAMMER * pgm, unsigned char cmd[4],
unsigned char res[4])
{
fprintf(stderr,
"%s: stk500v2_jtag3_cmd(): Not available in JTAGICE3\n",
progname);
return -1;
}
/*
* issue the 'chip erase' command to the AVR device
*/
@@ -1080,7 +1205,6 @@ static int stk500hvsp_program_enable(PROGRAMMER * pgm, AVRPART * p)
}
/*
* initialize the AVR device and prepare it to accept commands
*/
@@ -1127,6 +1251,97 @@ static int stk500v2_initialize(PROGRAMMER * pgm, AVRPART * p)
}
/*
* initialize the AVR device and prepare it to accept commands
*/
static int stk500v2_jtag3_initialize(PROGRAMMER * pgm, AVRPART * p)
{
unsigned char parm[4], *resp;
LNODEID ln;
AVRMEM * m;
void *mycookie;
if ((p->flags & AVRPART_HAS_PDI) ||
(p->flags & AVRPART_HAS_TPI)) {
fprintf(stderr, "%s: jtag3_initialize(): part %s has no ISP interface\n",
progname, p->desc);
return -1;
}
mycookie = pgm->cookie;
pgm->cookie = PDATA(pgm)->chained_pdata;
if (p->flags & AVRPART_HAS_DW)
parm[0] = PARM3_ARCH_TINY;
else
parm[0] = PARM3_ARCH_MEGA;
if (jtag3_setparm(pgm, SCOPE_AVR, 0, PARM3_ARCH, parm, 1) < 0) {
pgm->cookie = mycookie;
return -1;
}
parm[0] = PARM3_SESS_PROGRAMMING;
if (jtag3_setparm(pgm, SCOPE_AVR, 0, PARM3_SESS_PURPOSE, parm, 1) < 0) {
pgm->cookie = mycookie;
return -1;
}
parm[0] = PARM3_CONN_ISP;
if (jtag3_setparm(pgm, SCOPE_AVR, 1, PARM3_CONNECTION, parm, 1) < 0) {
pgm->cookie = mycookie;
return -1;
}
parm[0] = SCOPE_AVR_ISP;
parm[1] = 0x1e;
jtag3_send(pgm, parm, 2);
if (jtag3_recv(pgm, &resp) > 0)
free(resp);
pgm->cookie = mycookie;
/*
* Examine the avrpart's memory definitions, and initialize the page
* caches. For devices/memory that are not page oriented, treat
* them as page size 1 for EEPROM, and 2 for flash.
*/
PDATA(pgm)->flash_pagesize = 2;
PDATA(pgm)->eeprom_pagesize = 1;
for (ln = lfirst(p->mem); ln; ln = lnext(ln)) {
m = ldata(ln);
if (strcmp(m->desc, "flash") == 0) {
if (m->page_size > 0) {
if (m->page_size > 256)
PDATA(pgm)->flash_pagesize = 256;
else
PDATA(pgm)->flash_pagesize = m->page_size;
}
} else if (strcmp(m->desc, "eeprom") == 0) {
if (m->page_size > 0)
PDATA(pgm)->eeprom_pagesize = m->page_size;
}
}
free(PDATA(pgm)->flash_pagecache);
free(PDATA(pgm)->eeprom_pagecache);
if ((PDATA(pgm)->flash_pagecache = malloc(PDATA(pgm)->flash_pagesize)) == NULL) {
fprintf(stderr, "%s: stk500hv_initialize(): Out of memory\n",
progname);
return -1;
}
if ((PDATA(pgm)->eeprom_pagecache = malloc(PDATA(pgm)->eeprom_pagesize)) == NULL) {
fprintf(stderr, "%s: stk500hv_initialize(): Out of memory\n",
progname);
free(PDATA(pgm)->flash_pagecache);
return -1;
}
PDATA(pgm)->flash_pageaddr = PDATA(pgm)->eeprom_pageaddr = (unsigned long)-1L;
return pgm->program_enable(pgm, p);
}
/*
* initialize the AVR device and prepare it to accept commands, generic HV mode
*/
@@ -1154,7 +1369,7 @@ static int stk500hv_initialize(PROGRAMMER * pgm, AVRPART * p, enum hvmode mode)
if (result < 0) {
fprintf(stderr,
"%s: stk500pp_initalize(): "
"%s: stk500hv_initalize(): "
"failed to set control stack\n",
progname);
return -1;
@@ -1184,12 +1399,12 @@ static int stk500hv_initialize(PROGRAMMER * pgm, AVRPART * p, enum hvmode mode)
free(PDATA(pgm)->flash_pagecache);
free(PDATA(pgm)->eeprom_pagecache);
if ((PDATA(pgm)->flash_pagecache = malloc(PDATA(pgm)->flash_pagesize)) == NULL) {
fprintf(stderr, "%s: stk500pp_initialize(): Out of memory\n",
fprintf(stderr, "%s: stk500hv_initialize(): Out of memory\n",
progname);
return -1;
}
if ((PDATA(pgm)->eeprom_pagecache = malloc(PDATA(pgm)->eeprom_pagesize)) == NULL) {
fprintf(stderr, "%s: stk500pp_initialize(): Out of memory\n",
fprintf(stderr, "%s: stk500hv_initialize(): Out of memory\n",
progname);
free(PDATA(pgm)->flash_pagecache);
return -1;
@@ -1215,6 +1430,31 @@ static int stk500hvsp_initialize(PROGRAMMER * pgm, AVRPART * p)
return stk500hv_initialize(pgm, p, HVSPMODE);
}
static void stk500v2_jtag3_disable(PROGRAMMER * pgm)
{
unsigned char buf[16];
int result;
free(PDATA(pgm)->flash_pagecache);
PDATA(pgm)->flash_pagecache = NULL;
free(PDATA(pgm)->eeprom_pagecache);
PDATA(pgm)->eeprom_pagecache = NULL;
buf[0] = CMD_LEAVE_PROGMODE_ISP;
buf[1] = 1; // preDelay;
buf[2] = 1; // postDelay;
result = stk500v2_command(pgm, buf, 3, sizeof(buf));
if (result < 0) {
fprintf(stderr,
"%s: stk500v2_disable(): failed to leave programming mode\n",
progname);
}
return;
}
static void stk500v2_disable(PROGRAMMER * pgm)
{
unsigned char buf[16];
@@ -1577,6 +1817,112 @@ static int stk500hvsp_read_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
return stk500hv_read_byte(pgm, p, mem, addr, value, HVSPMODE);
}
/*
* Read a single byte, ISP mode
*
* By now, only used on the JTAGICE3 which does not implement the
* CMD_SPI_MULTI SPI passthrough command.
*/
static int stk500isp_read_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
unsigned long addr, unsigned char * value)
{
int result, pollidx;
unsigned char buf[6];
unsigned long paddr = 0UL, *paddr_ptr = NULL;
unsigned int pagesize = 0;
unsigned char *cache_ptr = NULL;
OPCODE *op;
if (verbose >= 2)
fprintf(stderr, "%s: stk500isp_read_byte(.., %s, 0x%lx, ...)\n",
progname, mem->desc, addr);
if (strcmp(mem->desc, "flash") == 0 ||
strcmp(mem->desc, "eeprom") == 0) {
// use paged access, and cache result
if (strcmp(mem->desc, "flash") == 0) {
pagesize = PDATA(pgm)->flash_pagesize;
paddr = addr & ~(pagesize - 1);
paddr_ptr = &PDATA(pgm)->flash_pageaddr;
cache_ptr = PDATA(pgm)->flash_pagecache;
} else {
pagesize = mem->page_size;
if (pagesize == 0)
pagesize = 1;
paddr = addr & ~(pagesize - 1);
paddr_ptr = &PDATA(pgm)->eeprom_pageaddr;
cache_ptr = PDATA(pgm)->eeprom_pagecache;
}
if (paddr == *paddr_ptr) {
*value = cache_ptr[addr & (pagesize - 1)];
return 0;
}
if (stk500v2_paged_load(pgm, p, mem, pagesize, paddr, pagesize) < 0)
return -1;
*paddr_ptr = paddr;
memcpy(cache_ptr, &mem->buf[paddr], pagesize);
*value = cache_ptr[addr & (pagesize - 1)];
return 0;
}
if (strcmp(mem->desc, "lfuse") == 0 ||
strcmp(mem->desc, "fuse") == 0) {
buf[0] = CMD_READ_FUSE_ISP;
addr = 0;
} else if (strcmp(mem->desc, "hfuse") == 0) {
buf[0] = CMD_READ_FUSE_ISP;
addr = 1;
} else if (strcmp(mem->desc, "efuse") == 0) {
buf[0] = CMD_READ_FUSE_ISP;
addr = 2;
} else if (strcmp(mem->desc, "lock") == 0) {
buf[0] = CMD_READ_LOCK_ISP;
} else if (strcmp(mem->desc, "calibration") == 0) {
buf[0] = CMD_READ_OSCCAL_ISP;
} else if (strcmp(mem->desc, "signature") == 0) {
buf[0] = CMD_READ_SIGNATURE_ISP;
}
memset(buf + 1, 0, 5);
if ((op = mem->op[AVR_OP_READ]) == NULL) {
fprintf(stderr,
"%s: stk500isp_read_byte(): invalid operation AVR_OP_READ on %s memory\n",
progname, mem->desc);
return -1;
}
avr_set_bits(op, buf + 2);
if ((pollidx = avr_get_output_index(op)) == -1) {
fprintf(stderr,
"%s: stk500isp_read_byte(): cannot determine pollidx to read %s memory\n",
progname, mem->desc);
pollidx = 3;
}
buf[1] = pollidx + 1;
avr_set_addr(op, buf + 2, addr);
if (verbose >= 2)
fprintf(stderr, "%s: stk500isp_read_byte(): Sending read memory command: ",
progname);
result = stk500v2_command(pgm, buf, 6, sizeof(buf));
if (result < 0) {
fprintf(stderr,
"%s: stk500isp_read_byte(): "
"timeout/error communicating with programmer\n",
progname);
return -1;
}
*value = buf[2];
return 0;
}
/*
* Write one byte, generic HV mode
*/
@@ -1738,6 +2084,122 @@ static int stk500hvsp_write_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
}
/*
* Write one byte, ISP mode
*/
static int stk500isp_write_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
unsigned long addr, unsigned char data)
{
int result;
unsigned char buf[5];
unsigned long paddr = 0UL, *paddr_ptr = NULL;
unsigned int pagesize = 0;
unsigned char *cache_ptr = NULL;
OPCODE *op;
if (verbose >= 2)
fprintf(stderr, "%s: stk500isp_write_byte(.., %s, 0x%lx, ...)\n",
progname, mem->desc, addr);
if (strcmp(mem->desc, "flash") == 0 ||
strcmp(mem->desc, "eeprom") == 0) {
if (strcmp(mem->desc, "flash") == 0) {
pagesize = PDATA(pgm)->flash_pagesize;
paddr = addr & ~(pagesize - 1);
paddr_ptr = &PDATA(pgm)->flash_pageaddr;
cache_ptr = PDATA(pgm)->flash_pagecache;
} else {
pagesize = mem->page_size;
if (pagesize == 0)
pagesize = 1;
paddr = addr & ~(pagesize - 1);
paddr_ptr = &PDATA(pgm)->eeprom_pageaddr;
cache_ptr = PDATA(pgm)->eeprom_pagecache;
}
/*
* We use paged writes for flash and EEPROM. As both, flash and
* EEPROM cells can only be programmed from `1' to `0' bits (even
* EEPROM does not support auto-erase in parallel mode), we just
* pre-fill the page cache with 0xff, so all those cells that are
* outside our current address will remain unaffected.
*/
memset(cache_ptr, 0xff, pagesize);
cache_ptr[addr & (pagesize - 1)] = data;
memcpy(mem->buf + paddr, cache_ptr, pagesize);
stk500v2_paged_write(pgm, p, mem, pagesize, addr, pagesize);
/* Invalidate the page cache. */
*paddr_ptr = (unsigned long)-1L;
return 0;
}
memset(buf, 0, sizeof buf);
if (strcmp(mem->desc, "lfuse") == 0 ||
strcmp(mem->desc, "fuse") == 0) {
buf[0] = CMD_PROGRAM_FUSE_ISP;
addr = 0;
} else if (strcmp(mem->desc, "hfuse") == 0) {
buf[0] = CMD_PROGRAM_FUSE_ISP;
addr = 1;
} else if (strcmp(mem->desc, "efuse") == 0) {
buf[0] = CMD_PROGRAM_FUSE_ISP;
addr = 2;
} else if (strcmp(mem->desc, "lock") == 0) {
buf[0] = CMD_PROGRAM_LOCK_ISP;
} else {
fprintf(stderr,
"%s: stk500isp_write_byte(): "
"unsupported memory type: %s\n",
progname, mem->desc);
return -1;
}
if ((op = mem->op[AVR_OP_WRITE]) == NULL) {
fprintf(stderr,
"%s: stk500isp_write_byte(): "
"no AVR_OP_WRITE for %s memory\n",
progname, mem->desc);
return -1;
}
avr_set_bits(op, buf + 1);
avr_set_addr(op, buf + 1, addr);
avr_set_input(op, buf + 1, data);
if (verbose >= 2)
fprintf(stderr, "%s: stk500isp_write_byte(): Sending write memory command: ",
progname);
result = stk500v2_command(pgm, buf, 5, sizeof(buf));
if (result < 0) {
fprintf(stderr,
"%s: stk500isp_write_byte(): "
"timeout/error communicating with programmer\n",
progname);
return -1;
}
if (buf[0] == CMD_PROGRAM_FUSE_ISP) {
/*
* The JTAGICE3 needs one leave progmode / enter progmode cycle
* after writing fuses, before being able to read them back.
*/
buf[0] = CMD_LEAVE_PROGMODE_ISP;
buf[1] = 1; // preDelay;
buf[2] = 1; // postDelay;
stk500v2_command(pgm, buf, 3, sizeof(buf));
pgm->program_enable(pgm, p);
}
return 0;
}
static int stk500v2_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
unsigned int page_size,
unsigned int addr, unsigned int n_bytes)
@@ -2495,6 +2957,28 @@ static int stk600_set_sck_period(PROGRAMMER * pgm, double v)
return stk500v2_setparm2(pgm, PARAM2_SCK_DURATION, sck);
}
static int stk500v2_jtag3_set_sck_period(PROGRAMMER * pgm, double v)
{
unsigned char value[3];
unsigned int sck;
if (v < 1E-6)
sck = 0x400;
else if (v > 1E-3)
sck = 1;
else
sck = 1.0 / (1000.0 * v);
value[0] = CMD_SET_SCK;
value[1] = sck & 0xff;
value[2] = (sck >> 8) & 0xff;
if (stk500v2_jtag3_send(pgm, value, 3) < 0)
return -1;
if (stk500v2_jtag3_recv(pgm, value, 3) < 0)
return -1;
return 0;
}
static int stk500v2_getparm(PROGRAMMER * pgm, unsigned char parm, unsigned char * value)
{
@@ -2616,7 +3100,8 @@ static void stk500v2_display(PROGRAMMER * pgm, const char * p)
case PGMTYPE_STK600: pgmname = "STK600"; break;
default: pgmname = "None";
}
if (PDATA(pgm)->pgmtype != PGMTYPE_JTAGICE_MKII) {
if (PDATA(pgm)->pgmtype != PGMTYPE_JTAGICE_MKII &&
PDATA(pgm)->pgmtype != PGMTYPE_JTAGICE3) {
fprintf(stderr, "%sProgrammer Model: %s\n", p, pgmname);
stk500v2_getparm(pgm, PARAM_HW_VER, &hdw);
stk500v2_getparm(pgm, PARAM_SW_MAJOR, &maj);
@@ -2698,6 +3183,14 @@ static void stk500v2_print_parms1(PROGRAMMER * pgm, const char * p)
pgm->cookie = mycookie;
fprintf(stderr, "%sVtarget : %.1f V\n", p,
b2_to_u16(vtarget_jtag) / 1000.0);
} else if (PDATA(pgm)->pgmtype == PGMTYPE_JTAGICE3) {
mycookie = pgm->cookie;
pgm->cookie = PDATA(pgm)->chained_pdata;
jtag3_getparm(pgm, SCOPE_GENERAL, 1, PARM3_VTARGET, vtarget_jtag, 2);
pgm->cookie = mycookie;
fprintf(stderr, "%sVtarget : %.1f V\n", p,
b2_to_u16(vtarget_jtag) / 1000.0);
} else {
stk500v2_getparm(pgm, PARAM_VTARGET, &vtarget);
fprintf(stderr, "%sVtarget : %.1f V\n", p, vtarget / 10.0);
@@ -2741,6 +3234,20 @@ static void stk500v2_print_parms1(PROGRAMMER * pgm, const char * p)
(float) 1000000 / avrispmkIIfreqs[sck_duration]);
break;
case PGMTYPE_JTAGICE3:
{
unsigned char cmd[4];
cmd[0] = CMD_GET_SCK;
if (stk500v2_jtag3_send(pgm, cmd, 1) >= 0 &&
stk500v2_jtag3_recv(pgm, cmd, 4) >= 2) {
unsigned int sck = cmd[1] | (cmd[2] << 8);
fprintf(stderr, "%sSCK period : %.2f us\n", p,
(float)(1E6 / (1000.0 * sck)));
}
}
break;
case PGMTYPE_STK600:
stk500v2_getparm2(pgm, PARAM2_AREF0, &varef);
fprintf(stderr, "%sVaref 0 : %.2f V\n", p, varef / 100.0);
@@ -2887,6 +3394,23 @@ static void stk500v2_jtagmkII_close(PROGRAMMER * pgm)
}
/*
* Close JTAGICE3.
*/
static void stk500v2_jtag3_close(PROGRAMMER * pgm)
{
void *mycookie;
if (verbose >= 2)
fprintf(stderr, "%s: stk500v2_jtag3_close()\n", progname);
mycookie = pgm->cookie;
pgm->cookie = PDATA(pgm)->chained_pdata;
jtag3_close(pgm);
pgm->cookie = mycookie;
}
/*
* Wrapper functions for the AVR Dragon in ISP mode. This mode
* uses the normal JTAG ICE mkII packet stream to communicate with the
@@ -3040,6 +3564,77 @@ static int stk500v2_dragon_hv_open(PROGRAMMER * pgm, char * port)
return 0;
}
/*
* Wrapper functions for the JTAGICE3 in ISP mode. This mode
* uses the normal JTAGICE3 packet stream to communicate with the
* ICE, but then encapsulates AVRISP mkII commands using
* scope AVRISP.
*/
/*
* Open a JTAGICE3 in ISP mode.
*/
static int stk500v2_jtag3_open(PROGRAMMER * pgm, char * port)
{
long baud;
void *mycookie;
int rv;
if (verbose >= 2)
fprintf(stderr, "%s: stk500v2_jtag3_open()\n", progname);
/*
* The serial_open() function for USB overrides
* the meaning of the "baud" parameter to be the USB device ID to
* search for.
*/
if (strncmp(port, "usb", 3) == 0) {
#if defined(HAVE_LIBUSB)
serdev = &usb_serdev_frame;
baud = USB_DEVICE_JTAGICE3;
pgm->fd.usb.max_xfer = USBDEV_MAX_XFER_3;
pgm->fd.usb.rep = USBDEV_BULK_EP_READ_3;
pgm->fd.usb.wep = USBDEV_BULK_EP_WRITE_3;
pgm->fd.usb.eep = USBDEV_EVT_EP_READ_3;
#else
fprintf(stderr, "avrdude was compiled without usb support.\n");
return -1;
#endif
}
strcpy(pgm->port, port);
if (serial_open(port, baud, &pgm->fd)==-1) {
return -1;
}
/*
* drain any extraneous input
*/
stk500v2_drain(pgm, 0);
mycookie = pgm->cookie;
pgm->cookie = PDATA(pgm)->chained_pdata;
if ((rv = jtag3_getsync(pgm, 42)) != 0) {
if (rv != JTAGII_GETSYNC_FAIL_GRACEFUL)
fprintf(stderr,
"%s: failed to sync with the JTAGICE3 in ISP mode\n",
progname);
pgm->cookie = mycookie;
return -1;
}
pgm->cookie = mycookie;
PDATA(pgm)->pgmtype = PGMTYPE_JTAGICE3;
if (pgm->bitclock != 0.0) {
if (pgm->set_sck_period(pgm, pgm->bitclock) != 0)
return -1;
}
return 0;
}
/*
* XPROG wrapper
*/
@@ -4080,3 +4675,38 @@ void stk600hvsp_initpgm(PROGRAMMER * pgm)
pgm->page_size = 256;
}
const char stk500v2_jtag3_desc[] = "Atmel JTAGICE3 in ISP mode";
void stk500v2_jtag3_initpgm(PROGRAMMER * pgm)
{
strcpy(pgm->type, "JTAG3_ISP");
/*
* mandatory functions
*/
pgm->initialize = stk500v2_jtag3_initialize;
pgm->display = stk500v2_display;
pgm->enable = stk500v2_enable;
pgm->disable = stk500v2_jtag3_disable;
pgm->program_enable = stk500v2_program_enable;
pgm->chip_erase = stk500v2_chip_erase;
pgm->cmd = stk500v2_jtag3_cmd;
pgm->open = stk500v2_jtag3_open;
pgm->close = stk500v2_jtag3_close;
pgm->read_byte = stk500isp_read_byte;
pgm->write_byte = stk500isp_write_byte;
/*
* optional functions
*/
pgm->paged_write = stk500v2_paged_write;
pgm->paged_load = stk500v2_paged_load;
pgm->page_erase = stk500v2_page_erase;
pgm->print_parms = stk500v2_print_parms;
pgm->set_sck_period = stk500v2_jtag3_set_sck_period;
pgm->perform_osccal = stk500v2_perform_osccal;
pgm->setup = stk500v2_jtag3_setup;
pgm->teardown = stk500v2_jtag3_teardown;
pgm->page_size = 256;
}