Add support for the JTAG ICE mkII in ISP mode.

* avrdude.conf.in (jtag2isp): New programmer entry.
* config_gram.y: Add K_JTAG_MKII_ISP.
* jtagmkII.c: Restructure and export some more functions.
* jtagmkII.h: Declare exported functions.
* jtagmkII_private.h: Prepare file to be included in stk500v2.c.
* lexer.l: Add jtagmkii_isp token.
* stk500v2.c: Implement glue to jtagmkII.c.
* stk500v2.h: Declare stk500v2_jtagmkII_initpgm().
* avrdude.1: Document the new programmer support.
* doc/avrdude.texi: (Ditto.)


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk/avrdude@643 81a1dc3b-b13d-400b-aceb-764788c761c2
This commit is contained in:
joerg_wunsch 2006-09-06 20:06:07 +00:00
parent 26952bf8f0
commit f8796c29cc
12 changed files with 391 additions and 68 deletions

View File

@ -1,3 +1,17 @@
2006-09-06 Joerg Wunsch <j@uriah.heep.sax.de>
Add support for the JTAG ICE mkII in ISP mode.
* avrdude.conf.in (jtag2isp): New programmer entry.
* config_gram.y: Add K_JTAG_MKII_ISP.
* jtagmkII.c: Restructure and export some more functions.
* jtagmkII.h: Declare exported functions.
* jtagmkII_private.h: Prepare file to be included in stk500v2.c.
* lexer.l: Add jtagmkii_isp token.
* stk500v2.c: Implement glue to jtagmkII.c.
* stk500v2.h: Declare stk500v2_jtagmkII_initpgm().
* avrdude.1: Document the new programmer support.
* doc/avrdude.texi: (Ditto.)
2006-09-01 Joerg Wunsch <j@uriah.heep.sax.de>
* main.c: Add date and time of compilation to the verbose

3
NEWS
View File

@ -23,6 +23,9 @@ Current:
* Add high-voltage mode programming for the STK500 (both,
parallel, and high-voltage serial programming).
* Add support for using the JTAG ICE mkII as a generic ISP
programmer.
* Allow for specifying the ISP clock delay as an option for
bit-bang programming adapters.

View File

@ -19,7 +19,7 @@
.\"
.\" $Id$
.\"
.Dd DATE August 16, 2006
.Dd DATE September 6, 2006
.Os
.Dt AVRDUDE 1
.Sh NAME
@ -57,7 +57,7 @@ microcontrollers.
.Nm Avrdude
supports Atmel's STK500 programmer,
Atmel's AVRISP and AVRISP mkII devices,
Atmel's JTAG ICE (both mkI and mkII),
Atmel's JTAG ICE (both mkI and mkII, the latter also in ISP mode),
programmers complying to AppNote AVR910 and AVR109 (including the Butterfly),
as well as a simple hard-wired
programmer connected directly to a
@ -111,6 +111,7 @@ supported on a serial port.
.Pp
Atmel's JTAG ICE (both mkI and mkII) is supported as well to up- or download memory
areas from/to an AVR target (no support for on-chip debugging).
For the JTAG ICE mkII, both JTAG and ISP mode are supported.
.Pp
Input files can be provided, and output files can be written in
different file formats, such as raw binary files containing the data
@ -219,7 +220,7 @@ and bit-bang programmers.
Override the RS-232 connection baud rate specified in the respective
programmer's entry of the configuration file.
.It Fl B Ar bitclock
Specify the bit clock period for the JTAG interface (JTAG ICE only).
Specify the bit clock period for the JTAG interface or the ISP clock (JTAG ICE only).
The value is a floating-point number in microseconds.
The default value of the JTAG ICE results in about 1 microsecond bit
clock period, suitable for target MCUs running at 4 MHz clock and
@ -629,6 +630,8 @@ microseconds.
Note that unlike STK500 settings, this setting will be reverted to
its default value (approximately 1 microsecond) when the programming
software signs off from the JTAG ICE.
This parameter can also be used on the JTAG ICE mkII to specify the
ISP clock period when operating the ICE in ISP mode.
.It Ar parms
.Em STK500 programmer only:
Display the current voltage and master oscillator parameters.

View File

@ -16,7 +16,7 @@
# id = <id1> [, <id2> [, <id3>] ...] ; # <idN> are quoted strings
# desc = <description> ; # quoted string
# type = par | stk500 | stk500v2 | stk500pp | stk500hvsp |
# avr910 | jtagmki | jtagmkii; # programmer type
# avr910 | jtagmki | jtagmkii | jtagmkii_isp; # programmer type
# baudrate = <num> ; # baudrate for avr910-programmer
# vcc = <num1> [, <num2> ... ] ; # pin number(s)
# reset = <num> ; # pin number
@ -425,6 +425,14 @@ programmer
type = jtagmkii;
;
# JTAG ICE mkII in ISP mode
programmer
id = "jtag2isp";
desc = "Atmel JTAG ICE mkII in ISP mode";
baudrate = 115200;
type = jtagmkii_isp;
;
programmer
id = "pavr";
desc = "Jason Kyle's pAVR Serial Programmer";

View File

@ -95,6 +95,7 @@ static int parse_cmdbits(OPCODE * op);
%token K_IO
%token K_JTAG_MKI
%token K_JTAG_MKII
%token K_JTAG_MKII_ISP
%token K_LOADPAGE
%token K_MAX_WRITE_DELAY
%token K_MIN_WRITE_DELAY
@ -414,6 +415,12 @@ prog_parm :
}
} |
K_TYPE TKN_EQUAL K_JTAG_MKII_ISP {
{
stk500v2_jtagmkII_initpgm(current_prog);
}
} |
K_DESC TKN_EQUAL TKN_STRING {
strncpy(current_prog->desc, $3->value.string, PGM_DESCLEN);
current_prog->desc[PGM_DESCLEN-1] = 0;

View File

@ -143,7 +143,7 @@ programming fuse/lock bits, etc.
AVRDUDE supports the following basic programmer types: Atmel's STK500,
Atmel's AVRISP and AVRISP mkII devices,
Atmel's JTAG ICE (both mkI and mkII), appnote
Atmel's JTAG ICE (both mkI and mkII, the latter also in ISP mode), appnote
avr910, appnote avr109 (including the AVR Butterfly),
serial bit-bang adapters,
and the PPI (parallel port interface). PPI represents a class
@ -182,6 +182,8 @@ protocol is more sophisticated.
(The JTAG ICE mkII protocol can also be run on top of USB.)
Only the memory programming functionality of the JTAG ICE is supported
by AVRDUDE.
For the JTAG ICE mkII, both JTAG and ISP mode are supported.
@menu
* History::
@ -407,7 +409,7 @@ Override the RS-232 connection baud rate specified in the respective
programmer's entry of the configuration file.
@item -B @var{bitclock}
Specify the bit clock period for the JTAG interface (JTAG ICE only).
Specify the bit clock period for the JTAG interface or the ISP clock (JTAG ICE only).
The value is a floating-point number in microseconds.
The default value of the JTAG ICE results in about 1 microsecond bit
clock period, suitable for target MCUs running at 4 MHz clock and
@ -487,6 +489,9 @@ Atmel JTAG ICE mkII, running at 115200 Bd
@itemx jtag2
Same as before.
@itemx jtag2isp
Atmel JTAG ICE mkII in ISP mode.
@itemx pavr
Jason Kyle's pAVR Serial Programmer
@ -1052,6 +1057,8 @@ Set the JTAG ICE bit clock period to @var{period} microseconds.
Note that unlike STK500 settings, this setting will be reverted to
its default value (approximately 1 microsecond) when the programming
software signs off from the JTAG ICE.
This parameter can also be used on the JTAG ICE mkII to specify the
ISP clock period when operating the ICE in ISP mode.
@item parms
@emph{STK500 only:}

View File

@ -89,8 +89,6 @@ static int jtagmkII_read_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
static int jtagmkII_write_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
unsigned long addr, unsigned char data);
static int jtagmkII_set_sck_period(PROGRAMMER * pgm, double v);
static int jtagmkII_getparm(PROGRAMMER * pgm, unsigned char parm,
unsigned char * value);
static int jtagmkII_setparm(PROGRAMMER * pgm, unsigned char parm,
unsigned char * value);
static void jtagmkII_print_parms1(PROGRAMMER * pgm, char * p);
@ -291,7 +289,7 @@ static void jtagmkII_prmsg(PROGRAMMER * pgm, unsigned char * data, size_t len)
}
static int jtagmkII_send(PROGRAMMER * pgm, unsigned char * data, size_t len)
int jtagmkII_send(PROGRAMMER * pgm, unsigned char * data, size_t len)
{
unsigned char *buf;
@ -493,7 +491,7 @@ fprintf(stderr, "\n");
return msglen;
}
static int jtagmkII_recv(PROGRAMMER * pgm, unsigned char **msg) {
int jtagmkII_recv(PROGRAMMER * pgm, unsigned char **msg) {
unsigned short r_seqno;
int rv;
@ -531,7 +529,7 @@ static int jtagmkII_recv(PROGRAMMER * pgm, unsigned char **msg) {
}
static int jtagmkII_getsync(PROGRAMMER * pgm) {
int jtagmkII_getsync(PROGRAMMER * pgm, int mode) {
int tries;
#define MAXTRIES 33
unsigned char buf[3], *resp, c = 0xff;
@ -625,14 +623,24 @@ static int jtagmkII_getsync(PROGRAMMER * pgm) {
} else if (fwver < FWVER(4, 0)) {
device_descriptor_length -= 2;
}
#undef FWVER
if (verbose >= 2)
if (verbose >= 2 && mode != EMULATOR_MODE_SPI)
fprintf(stderr,
"%s: jtagmkII_getsync(): Using a %zu-byte device descriptor\n",
progname, device_descriptor_length);
if (mode == EMULATOR_MODE_SPI) {
device_descriptor_length = 0;
if (fwver < FWVER(4, 14)) {
fprintf(stderr,
"%s: jtagmkII_getsync(): ISP functionality requires firmware "
"version >= 4.14\n",
progname);
return -1;
}
}
#undef FWVER
/* Turn the ICE into JTAG mode */
buf[0] = EMULATOR_MODE_JTAG;
/* Turn the ICE into JTAG or ISP mode as requested. */
buf[0] = mode;
if (jtagmkII_setparm(pgm, PAR_EMULATOR_MODE, buf) < 0)
return -1;
@ -1058,7 +1066,6 @@ static int jtagmkII_open(PROGRAMMER * pgm, char * port)
*/
baud = 19200;
#if defined(HAVE_LIBUSB)
/*
* If the port name starts with "usb", divert the serial routines
* to the USB ones. The serial_open() function for USB overrides
@ -1066,10 +1073,14 @@ static int jtagmkII_open(PROGRAMMER * pgm, char * port)
* search for.
*/
if (strncmp(port, "usb", 3) == 0) {
#if defined(HAVE_LIBUSB)
serdev = &usb_serdev;
baud = USB_DEVICE_JTAGICEMKII;
}
#else
fprintf(stderr, "avrdude was compiled without usb support.\n");
return -1;
#endif
}
strcpy(pgm->port, port);
pgm->fd = serial_open(port, baud);
@ -1079,13 +1090,13 @@ static int jtagmkII_open(PROGRAMMER * pgm, char * port)
*/
jtagmkII_drain(pgm, 0);
jtagmkII_getsync(pgm);
jtagmkII_getsync(pgm, EMULATOR_MODE_JTAG);
return 0;
}
static void jtagmkII_close(PROGRAMMER * pgm)
void jtagmkII_close(PROGRAMMER * pgm)
{
int status;
unsigned char buf[1], *resp, c;
@ -1093,33 +1104,36 @@ static void jtagmkII_close(PROGRAMMER * pgm)
if (verbose >= 2)
fprintf(stderr, "%s: jtagmkII_close()\n", progname);
buf[0] = CMND_GO;
if (verbose >= 2)
fprintf(stderr, "%s: jtagmkII_close(): Sending GO command: ",
progname);
jtagmkII_send(pgm, buf, 1);
status = jtagmkII_recv(pgm, &resp);
if (status <= 0) {
if (device_descriptor_length) {
/* When in JTAG mode, restart target. */
buf[0] = CMND_GO;
if (verbose >= 2)
putc('\n', stderr);
fprintf(stderr,
"%s: jtagmkII_close(): "
"timeout/error communicating with programmer (status %d)\n",
progname, status);
} else {
if (verbose >= 3) {
putc('\n', stderr);
jtagmkII_prmsg(pgm, resp, status);
} else if (verbose == 2)
fprintf(stderr, "0x%02x (%d bytes msg)\n", resp[0], status);
c = resp[0];
free(resp);
if (c != RSP_OK) {
fprintf(stderr, "%s: jtagmkII_close(): Sending GO command: ",
progname);
jtagmkII_send(pgm, buf, 1);
status = jtagmkII_recv(pgm, &resp);
if (status <= 0) {
if (verbose >= 2)
putc('\n', stderr);
fprintf(stderr,
"%s: jtagmkII_close(): "
"bad response to GO command: 0x%02x\n",
progname, c);
"timeout/error communicating with programmer (status %d)\n",
progname, status);
} else {
if (verbose >= 3) {
putc('\n', stderr);
jtagmkII_prmsg(pgm, resp, status);
} else if (verbose == 2)
fprintf(stderr, "0x%02x (%d bytes msg)\n", resp[0], status);
c = resp[0];
free(resp);
if (c != RSP_OK) {
fprintf(stderr,
"%s: jtagmkII_close(): "
"bad response to GO command: 0x%02x\n",
progname, c);
}
}
}
@ -1624,8 +1638,8 @@ static int jtagmkII_set_sck_period(PROGRAMMER * pgm, double v)
* bytes by now, we always copy out 4 bytes to *value, so the caller
* must have allocated sufficient space.
*/
static int jtagmkII_getparm(PROGRAMMER * pgm, unsigned char parm,
unsigned char * value)
int jtagmkII_getparm(PROGRAMMER * pgm, unsigned char parm,
unsigned char * value)
{
int status;
unsigned char buf[2], *resp, c;

View File

@ -1,6 +1,6 @@
/*
* avrdude - A Downloader/Uploader for AVR device programmers
* Copyright (C) 2002-2004 Brian S. Dean <bsd@bsdhome.com>
* Copyright (C) 2002-2004, 2006 Brian S. Dean <bsd@bsdhome.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -22,6 +22,14 @@
#ifndef jtagmkII_h
#define jtagmkII_h
int jtagmkII_send(PROGRAMMER * pgm, unsigned char * data, size_t len);
int jtagmkII_recv(PROGRAMMER * pgm, unsigned char **msg);
int jtagmkII_open(PROGRAMMER * pgm, char * port);
void jtagmkII_close(PROGRAMMER * pgm);
int jtagmkII_getsync(PROGRAMMER * pgm, int mode);
int jtagmkII_getparm(PROGRAMMER * pgm, unsigned char parm,
unsigned char * value);
void jtagmkII_initpgm (PROGRAMMER * pgm);
#endif

View File

@ -1,6 +1,6 @@
/*
* avrdude - A Downloader/Uploader for AVR device programmers
* Copyright (C) 2005 Joerg Wunsch <j@uriah.heep.sax.de>
* Copyright (C) 2005, 2006 Joerg Wunsch <j@uriah.heep.sax.de>
*
*
* This program is free software; you can redistribute it and/or modify
@ -26,6 +26,7 @@
* Taken from Appnote AVR067
*/
#if !defined(JTAGMKII_PRIVATE_EXPORTED)
/*
* Communication with the JTAG ICE works in frames. The protocol
* somewhat resembles the STK500v2 protocol, yet it is sufficiently
@ -71,6 +72,8 @@
*/
#define MAX_MESSAGE 100000
#endif /* JTAGMKII_PRIVATE_EXPORTED */
/* ICE command codes */
#define CMND_CHIP_ERASE 0x13
#define CMND_CLEAR_EVENTS 0x22
@ -83,6 +86,7 @@
#define CMND_GET_SIGN_ON 0x01
#define CMND_GET_SYNC 0x0f
#define CMND_GO 0x08
#define CMND_ISP_PACKET 0x2F
#define CMND_LEAVE_PROGMODE 0x15
#define CMND_READ_MEMORY 0x05
#define CMND_READ_PC 0x07
@ -232,6 +236,7 @@
# define PAGEPROG_NOT_ALLOWED 0x00
# define PAGEPROG_ALLOWED 0x01
#if !defined(JTAGMKII_PRIVATE_EXPORTED)
/*
* In appnote AVR067, struct device_descriptor is written with
* int/long field types. We cannot use them directly, as they were
@ -288,3 +293,4 @@ struct device_descriptor
/* new as of early 2005, firmware 4.x */
unsigned char EECRAddress[2]; /* EECR memory-mapped IO address */
};
#endif /* JTAGMKII_PRIVATE_EXPORTED */

View File

@ -144,6 +144,7 @@ id { yylval=NULL; return K_ID; }
idr { yylval=NULL; return K_IDR; }
jtagmki { yylval=NULL; return K_JTAG_MKI; }
jtagmkii { yylval=NULL; return K_JTAG_MKII; }
jtagmkii_isp { yylval=NULL; return K_JTAG_MKII_ISP; }
max_write_delay { yylval=NULL; return K_MAX_WRITE_DELAY; }
memory { yylval=NULL; return K_MEMORY; }
min_write_delay { yylval=NULL; return K_MIN_WRITE_DELAY; }

View File

@ -54,6 +54,17 @@
#include "serial.h"
#include "usbdevs.h"
/*
* We need to import enough from the JTAG ICE mkII definitions to be
* able to talk to the ICE, query some parameters etc. The macro
* JTAGMKII_PRIVATE_EXPORTED limits the amount of definitions that
* jtagmkII_private.h will export, so to avoid conflicts with those
* names that are identical to the STK500v2 ones.
*/
#include "jtagmkII.h" // public interfaces from jtagmkII.c
#define JTAGMKII_PRIVATE_EXPORTED
#include "jtagmkII_private.h"
#define STK500V2_XTAL 7372800U
#if 0
@ -91,7 +102,6 @@ static unsigned long eeprom_pageaddr;
static unsigned int eeprom_pagesize;
static unsigned char command_sequence = 1;
static int is_mk2; /* Is the device an AVRISP mkII? */
static enum
{
@ -99,6 +109,7 @@ static enum
PGMTYPE_STK500,
PGMTYPE_AVRISP,
PGMTYPE_AVRISP_MKII,
PGMTYPE_JTAGICE_MKII,
}
pgmtype;
@ -108,6 +119,36 @@ static const char *pgmname[] =
"STK500",
"AVRISP",
"AVRISP mkII",
"JTAG ICE mkII",
};
struct jtagispentry
{
unsigned char cmd;
unsigned short size;
#define SZ_READ_FLASH_EE USHRT_MAX
#define SZ_SPI_MULTI (USHRT_MAX - 1)
};
static struct jtagispentry jtagispcmds[] = {
{ CMD_SET_PARAMETER, 2 },
{ CMD_GET_PARAMETER, 3 },
{ CMD_OSCCAL, 2 },
{ CMD_LOAD_ADDRESS, 2 },
{ CMD_ENTER_PROGMODE_ISP, 2 },
{ CMD_LEAVE_PROGMODE_ISP, 2 },
{ CMD_CHIP_ERASE_ISP, 2 },
{ CMD_PROGRAM_FLASH_ISP, 2 },
{ CMD_READ_FLASH_ISP, SZ_READ_FLASH_EE },
{ CMD_PROGRAM_EEPROM_ISP, 2 },
{ CMD_READ_EEPROM_ISP, SZ_READ_FLASH_EE },
{ CMD_PROGRAM_FUSE_ISP, 3 },
{ CMD_READ_FUSE_ISP, 4 },
{ CMD_PROGRAM_LOCK_ISP, 3 },
{ CMD_READ_LOCK_ISP, 4 },
{ CMD_READ_SIGNATURE_ISP, 4 },
{ CMD_READ_OSCCAL_ISP, 4 },
{ CMD_SPI_MULTI, SZ_SPI_MULTI }
};
static int stk500v2_getparm(PROGRAMMER * pgm, unsigned char parm, unsigned char * value);
@ -118,9 +159,17 @@ static int stk500v2_is_page_empty(unsigned int address, int page_size,
static unsigned int stk500v2_mode_for_pagesize(unsigned int pagesize);
#if defined(HAVE_LIBUSB)
static int stk500v2_set_sck_period_mk2(PROGRAMMER * pgm, double v);
#endif
static unsigned short
b2_to_u16(unsigned char *b)
{
unsigned short l;
l = b[0];
l += (unsigned)b[1] << 8;
return l;
}
static int stk500v2_send_mk2(PROGRAMMER * pgm, unsigned char * data, size_t len)
{
@ -132,13 +181,74 @@ static int stk500v2_send_mk2(PROGRAMMER * pgm, unsigned char * data, size_t len)
return 0;
}
static unsigned short get_jtagisp_return_size(unsigned char cmd)
{
int i;
for (i = 0; i < sizeof jtagispcmds / sizeof jtagispcmds[0]; i++)
if (jtagispcmds[i].cmd == cmd)
return jtagispcmds[i].size;
return 0;
}
/*
* Send the data as a JTAG ICE mkII encapsulated ISP packet.
* Unlike what AVR067 says, the packet gets a length of our
* response buffer prepended, and replies with RSP_SPI_DATA
* if successful.
*/
static int stk500v2_jtagmkII_send(PROGRAMMER * pgm, unsigned char * data, size_t len)
{
unsigned char *cmdbuf;
int rv;
unsigned short sz;
sz = get_jtagisp_return_size(data[0]);
if (sz == 0) {
fprintf(stderr, "%s: unsupported encapsulated ISP command: %#x\n",
progname, data[0]);
return -1;
}
if (sz == SZ_READ_FLASH_EE) {
/*
* For CMND_READ_FLASH_ISP and CMND_READ_EEPROM_ISP, extract the
* size of the return data from the request. Note that the
* request itself has the size in big endian format, while we are
* supposed to deliver it in little endian.
*/
sz = 3 + (data[1] << 8) + data[2];
} else if (sz == SZ_SPI_MULTI) {
/*
* CMND_SPI_MULTI has the Rx size encoded in its 3rd byte.
*/
sz = 3 + data[2];
}
if ((cmdbuf = malloc(len + 3)) == NULL) {
fprintf(stderr, "%s: out of memory for command packet\n",
progname);
exit(1);
}
cmdbuf[0] = CMND_ISP_PACKET;
cmdbuf[1] = sz & 0xff;
cmdbuf[2] = (sz >> 8) & 0xff;
memcpy(cmdbuf + 3, data, len);
rv = jtagmkII_send(pgm, cmdbuf, len + 3);
free(cmdbuf);
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
int i;
if (is_mk2)
if (pgmtype == PGMTYPE_AVRISP_MKII)
return stk500v2_send_mk2(pgm, data, len);
else if (pgmtype == PGMTYPE_JTAGICE_MKII)
return stk500v2_jtagmkII_send(pgm, data, len);
buf[0] = MESSAGE_START;
buf[1] = command_sequence;
@ -184,6 +294,44 @@ static int stk500v2_recv_mk2(PROGRAMMER * pgm, unsigned char msg[],
return rv;
}
static int stk500v2_jtagmkII_recv(PROGRAMMER * pgm, unsigned char msg[],
size_t maxsize)
{
int rv;
unsigned char *jtagmsg;
rv = jtagmkII_recv(pgm, &jtagmsg);
if (rv <= 0) {
fprintf(stderr, "%s: stk500v2_jtagmkII_recv(): error in jtagmkII_recv()\n",
progname);
return -1;
}
if (rv > maxsize) {
fprintf(stderr,
"%s: stk500v2_jtagmkII_recv(): got %u bytes, have only room for %u bytes\n",
progname, (unsigned)rv, maxsize);
rv = maxsize;
}
switch (jtagmsg[0]) {
case RSP_SPI_DATA:
break;
case RSP_FAILED:
fprintf(stderr, "%s: stk500v2_jtagmkII_recv(): failed\n",
progname);
return -1;
case RSP_ILLEGAL_MCU_STATE:
fprintf(stderr, "%s: stk500v2_jtagmkII_recv(): illegal MCU state\n",
progname);
return -1;
default:
fprintf(stderr, "%s: stk500v2_jtagmkII_recv(): unknown status %d\n",
progname, jtagmsg[0]);
return -1;
}
memcpy(msg, jtagmsg + 1, rv - 1);
return 0;
}
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;
int msglen = 0;
@ -195,8 +343,10 @@ static int stk500v2_recv(PROGRAMMER * pgm, unsigned char msg[], size_t maxsize)
struct timeval tv;
double tstart, tnow;
if (is_mk2)
if (pgmtype == PGMTYPE_AVRISP_MKII)
return stk500v2_recv_mk2(pgm, msg, maxsize);
else if (pgmtype == PGMTYPE_JTAGICE_MKII)
return stk500v2_jtagmkII_recv(pgm, msg, maxsize);
DEBUG("STK500V2: stk500v2_recv(): ");
@ -301,6 +451,9 @@ static int stk500v2_getsync(PROGRAMMER * pgm) {
DEBUG("STK500V2: stk500v2_getsync()\n");
if (pgmtype == PGMTYPE_JTAGICE_MKII)
return 0;
retry:
tries++;
@ -702,7 +855,6 @@ static void stk500v2_disable(PROGRAMMER * pgm)
if (buf[1] != STATUS_CMD_OK) {
fprintf(stderr, "%s: stk500v2_disable(): failed to leave programming mode, got 0x%02x\n",
progname,buf[1]);
exit(1);
}
return;
@ -769,6 +921,8 @@ static int stk500v2_open(PROGRAMMER * pgm, char * port)
if (pgm->baudrate)
baud = pgm->baudrate;
pgmtype = PGMTYPE_UNKNOWN;
/*
* If the port name starts with "usb", divert the serial routines
* to the USB ones. The serial_open() function for USB overrides
@ -779,7 +933,7 @@ static int stk500v2_open(PROGRAMMER * pgm, char * port)
#if defined(HAVE_LIBUSB)
serdev = &usb_serdev_frame;
baud = USB_DEVICE_AVRISPMKII;
is_mk2 = 1;
pgmtype = PGMTYPE_AVRISP_MKII;
pgm->set_sck_period = stk500v2_set_sck_period_mk2;
#else
fprintf(stderr, "avrdude was compiled without usb support.\n");
@ -795,8 +949,6 @@ static int stk500v2_open(PROGRAMMER * pgm, char * port)
*/
stk500v2_drain(pgm, 0);
pgmtype = PGMTYPE_UNKNOWN;
stk500v2_getsync(pgm);
stk500v2_drain(pgm, 0);
@ -1707,7 +1859,6 @@ double avrispmkIIfreqs[] = {
65.0, 61.9, 59.0, 56.3, 53.6, 51.1
};
#if defined(HAVE_LIBUSB)
static int stk500v2_set_sck_period_mk2(PROGRAMMER * pgm, double v)
{
int i;
@ -1722,7 +1873,6 @@ static int stk500v2_set_sck_period_mk2(PROGRAMMER * pgm, double v)
return stk500v2_setparm(pgm, PARAM_SCK_DURATION, i);
}
#endif /* HAVE_LIBUSB */
/*
* Return the "mode" value for the parallel and HVSP modes that
@ -1837,10 +1987,6 @@ static void stk500v2_display(PROGRAMMER * pgm, char * p)
unsigned char maj, min, hdw, topcard;
const char *topcard_name, *pgmname;
stk500v2_getparm(pgm, PARAM_HW_VER, &hdw);
stk500v2_getparm(pgm, PARAM_SW_MAJOR, &maj);
stk500v2_getparm(pgm, PARAM_SW_MINOR, &min);
switch (pgmtype) {
case PGMTYPE_UNKNOWN: pgmname = "Unknown"; break;
case PGMTYPE_STK500: pgmname = "STK500"; break;
@ -1848,9 +1994,14 @@ static void stk500v2_display(PROGRAMMER * pgm, char * p)
case PGMTYPE_AVRISP_MKII: pgmname = "AVRISP mkII"; break;
default: pgmname = "None";
}
fprintf(stderr, "%sProgrammer Model: %s\n", p, pgmname);
fprintf(stderr, "%sHardware Version: %d\n", p, hdw);
fprintf(stderr, "%sFirmware Version: %d.%02d\n", p, maj, min);
if (pgmtype != PGMTYPE_JTAGICE_MKII) {
fprintf(stderr, "%sProgrammer Model: %s\n", p, pgmname);
stk500v2_getparm(pgm, PARAM_HW_VER, &hdw);
stk500v2_getparm(pgm, PARAM_SW_MAJOR, &maj);
stk500v2_getparm(pgm, PARAM_SW_MINOR, &min);
fprintf(stderr, "%sHardware Version: %d\n", p, hdw);
fprintf(stderr, "%sFirmware Version: %d.%02d\n", p, maj, min);
}
if (pgmtype == PGMTYPE_STK500) {
stk500v2_getparm(pgm, PARAM_TOPCARD_DETECT, &topcard);
@ -1874,10 +2025,17 @@ static void stk500v2_display(PROGRAMMER * pgm, char * p)
static void stk500v2_print_parms1(PROGRAMMER * pgm, char * p)
{
unsigned char vtarget, vadjust, osc_pscale, osc_cmatch, sck_duration;
unsigned char vtarget_jtag[4];
stk500v2_getparm(pgm, PARAM_VTARGET, &vtarget);
if (pgmtype == PGMTYPE_JTAGICE_MKII) {
jtagmkII_getparm(pgm, PAR_OCD_VTARGET, vtarget_jtag);
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);
}
stk500v2_getparm(pgm, PARAM_SCK_DURATION, &sck_duration);
fprintf(stderr, "%sVtarget : %.1f V\n", p, vtarget / 10.0);
if (pgmtype == PGMTYPE_STK500) {
stk500v2_getparm(pgm, PARAM_VADJUST, &vadjust);
@ -1913,7 +2071,7 @@ static void stk500v2_print_parms1(PROGRAMMER * pgm, char * p)
fprintf(stderr, "%.3f %s\n", f, unit);
}
}
if (is_mk2)
if (pgmtype == PGMTYPE_AVRISP_MKII || pgmtype == PGMTYPE_JTAGICE_MKII)
fprintf(stderr, "%sSCK period : %.2f us\n", p,
(float) 1000000 / avrispmkIIfreqs[sck_duration]);
else
@ -1930,6 +2088,72 @@ static void stk500v2_print_parms(PROGRAMMER * pgm)
}
/*
* Wrapper functions for the JTAG ICE mkII in ISP mode. This mode
* uses the normal JTAG ICE mkII packet stream to communicate with the
* ICE, but then encapsulates AVRISP mkII commands using
* CMND_ISP_PACKET.
*/
/*
* Open a JTAG ICE mkII in ISP mode.
*/
static int stk500v2_jtagmkII_open(PROGRAMMER * pgm, char * port)
{
long baud;
if (verbose >= 2)
fprintf(stderr, "%s: stk500v2_jtagmkII_open()\n", progname);
/*
* The JTAG ICE mkII always starts with a baud rate of 19200 Bd upon
* attaching. If the config file or command-line parameters specify
* a higher baud rate, we switch to it later on, after establishing
* the connection with the ICE.
*/
baud = 19200;
/*
* If the port name starts with "usb", divert the serial routines
* to the USB ones. 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;
baud = USB_DEVICE_JTAGICEMKII;
#else
fprintf(stderr, "avrdude was compiled without usb support.\n");
return -1;
#endif
}
strcpy(pgm->port, port);
pgm->fd = serial_open(port, baud);
/*
* drain any extraneous input
*/
stk500v2_drain(pgm, 0);
if (jtagmkII_getsync(pgm, EMULATOR_MODE_SPI) != 0) {
fprintf(stderr, "%s: failed to sync with the JTAG ICE mkII in ISP mode\n",
progname);
exit(1);
}
pgmtype = PGMTYPE_JTAGICE_MKII;
if (pgm->bitclock != 0.0) {
if (pgm->set_sck_period(pgm, pgm->bitclock) != 0)
return -1;
}
return 0;
}
void stk500v2_initpgm(PROGRAMMER * pgm)
{
strcpy(pgm->type, "STK500V2");
@ -2023,3 +2247,30 @@ void stk500hvsp_initpgm(PROGRAMMER * pgm)
pgm->set_sck_period = stk500v2_set_sck_period;
pgm->page_size = 256;
}
void stk500v2_jtagmkII_initpgm(PROGRAMMER * pgm)
{
strcpy(pgm->type, "JTAGMKII_ISP");
/*
* mandatory functions
*/
pgm->initialize = stk500v2_initialize;
pgm->display = stk500v2_display;
pgm->enable = stk500v2_enable;
pgm->disable = stk500v2_disable;
pgm->program_enable = stk500v2_program_enable;
pgm->chip_erase = stk500v2_chip_erase;
pgm->cmd = stk500v2_cmd;
pgm->open = stk500v2_jtagmkII_open;
pgm->close = jtagmkII_close;
/*
* optional functions
*/
pgm->paged_write = stk500v2_paged_write;
pgm->paged_load = stk500v2_paged_load;
pgm->print_parms = stk500v2_print_parms;
pgm->set_sck_period = stk500v2_set_sck_period_mk2;
pgm->page_size = 256;
}

View File

@ -26,6 +26,7 @@
void stk500v2_initpgm (PROGRAMMER * pgm);
void stk500hvsp_initpgm (PROGRAMMER * pgm);
void stk500pp_initpgm (PROGRAMMER * pgm);
void stk500v2_jtagmkII_initpgm(PROGRAMMER * pgm);
#endif