Add support for the AVR Dragon (JTAG and ISP mode).

git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk/avrdude@675 81a1dc3b-b13d-400b-aceb-764788c761c2
This commit is contained in:
Joerg Wunsch 2006-10-26 21:14:10 +00:00
parent 08fc2b8a81
commit 90d6100d88
11 changed files with 258 additions and 6 deletions

View File

@ -1,3 +1,16 @@
2006-10-26 Joerg Wunsch <j@uriah.heep.sax.de>
* avrdude.conf.in: Add support for the AVR Dragon (JTAG and ISP mode).
* config_gram.y: (Ditto.)
* jtagmkII.c: (Ditto.)
* jtagmkII.h: (Ditto.)
* lexer.l: (Ditto.)
* stk500v2.c: (Ditto.)
* stk500v2.h: (Ditto.)
* usbdevs.h: (Ditto.)
* avrdude.1: Document the AVR Dragon support.
* doc/avrdude.texi: (Ditto.)
2006-10-09 Joerg Wunsch <j@uriah.heep.sax.de> 2006-10-09 Joerg Wunsch <j@uriah.heep.sax.de>
Released AVRDUDE 5.2. Released AVRDUDE 5.2.

View File

@ -19,7 +19,7 @@
.\" .\"
.\" $Id$ .\" $Id$
.\" .\"
.Dd DATE October 9, 2006 .Dd DATE October 26, 2006
.Os .Os
.Dt AVRDUDE 1 .Dt AVRDUDE 1
.Sh NAME .Sh NAME
@ -114,6 +114,19 @@ Atmel's JTAG ICE (both mkI and mkII) is supported as well to up- or download mem
areas from/to an AVR target (no support for on-chip debugging). areas from/to an AVR target (no support for on-chip debugging).
For the JTAG ICE mkII, both JTAG and ISP mode are supported. For the JTAG ICE mkII, both JTAG and ISP mode are supported.
.Pp .Pp
The AVR Dragon is supported in JTAG and ISP mode.
(High-voltage programming is not yet supported.)
When used in JTAG mode, the AVR Dragon behaves similar to a
JTAG ICE mkII, so all device-specific comments for that device
will apply as well.
When used in ISP mode, the AVR Dragon behaves similar to an
AVRISP mkII (or JTAG ICE mkII in ISP mode), so all device-specific
comments will apply there.
In particular, the Dragon starts out with a rather fast ISP clock
frequency, so the
.Fl B Ar bitclock
option might be required to achieve a stable ISP communication.
.Pp
The USBasp ISP adapter is also supported, provided The USBasp ISP adapter is also supported, provided
.Nm avrdude .Nm avrdude
has been compiled with libusb support. has been compiled with libusb support.

View File

@ -17,7 +17,8 @@
# desc = <description> ; # quoted string # desc = <description> ; # quoted string
# type = par | stk500 | stk500v2 | stk500pp | stk500hvsp | stk500generic | # type = par | stk500 | stk500v2 | stk500pp | stk500hvsp | stk500generic |
# avr910 | butterfly | usbasp | # avr910 | butterfly | usbasp |
# jtagmki | jtagmkii | jtagmkii_isp; # programmer type # jtagmki | jtagmkii | jtagmkii_isp |
# dragon_jtag | dragon_isp; # programmer type
# baudrate = <num> ; # baudrate for avr910-programmer # baudrate = <num> ; # baudrate for avr910-programmer
# vcc = <num1> [, <num2> ... ] ; # pin number(s) # vcc = <num1> [, <num2> ... ] ; # pin number(s)
# reset = <num> ; # pin number # reset = <num> ; # pin number
@ -441,6 +442,22 @@ programmer
type = jtagmkii_isp; type = jtagmkii_isp;
; ;
# AVR Dragon in JTAG mode
programmer
id = "dragon_jtag";
desc = "Atmel AVR Dragon in JTAG mode";
baudrate = 115200;
type = dragon_jtag;
;
# AVR Dragon in ISP mode
programmer
id = "dragon_isp";
desc = "Atmel AVR Dragon in ISP mode";
baudrate = 115200;
type = dragon_isp;
;
programmer programmer
id = "pavr"; id = "pavr";
desc = "Jason Kyle's pAVR Serial Programmer"; desc = "Jason Kyle's pAVR Serial Programmer";

View File

@ -88,6 +88,8 @@ static int parse_cmdbits(OPCODE * op);
%token K_DEFAULT_SERIAL %token K_DEFAULT_SERIAL
%token K_DESC %token K_DESC
%token K_DEVICECODE %token K_DEVICECODE
%token K_DRAGON_ISP
%token K_DRAGON_JTAG
%token K_STK500_DEVCODE %token K_STK500_DEVCODE
%token K_AVR910_DEVCODE %token K_AVR910_DEVCODE
%token K_EEPROM %token K_EEPROM
@ -437,6 +439,18 @@ prog_parm :
} }
} | } |
K_TYPE TKN_EQUAL K_DRAGON_ISP {
{
stk500v2_dragon_isp_initpgm(current_prog);
}
} |
K_TYPE TKN_EQUAL K_DRAGON_JTAG {
{
jtagmkII_dragon_initpgm(current_prog);
}
} |
K_DESC TKN_EQUAL TKN_STRING { K_DESC TKN_EQUAL TKN_STRING {
strncpy(current_prog->desc, $3->value.string, PGM_DESCLEN); strncpy(current_prog->desc, $3->value.string, PGM_DESCLEN);
current_prog->desc[PGM_DESCLEN-1] = 0; current_prog->desc[PGM_DESCLEN-1] = 0;

View File

@ -184,6 +184,18 @@ Only the memory programming functionality of the JTAG ICE is supported
by AVRDUDE. by AVRDUDE.
For the JTAG ICE mkII, both JTAG and ISP mode are supported. For the JTAG ICE mkII, both JTAG and ISP mode are supported.
The AVR Dragon is supported in JTAG and ISP mode.
(High-voltage programming is not yet supported.)
When used in JTAG mode, the AVR Dragon behaves similar to a
JTAG ICE mkII, so all device-specific comments for that device
will apply as well.
When used in ISP mode, the AVR Dragon behaves similar to an
AVRISP mkII (or JTAG ICE mkII in ISP mode), so all device-specific
comments will apply there.
In particular, the Dragon starts out with a rather fast ISP clock
frequency, so the @code{-B @var{bitclock}}
option might be required to achieve a stable ISP communication.
The USBasp ISP adapter is also supported, provided AVRDUDE The USBasp ISP adapter is also supported, provided AVRDUDE
has been compiled with libusb support. has been compiled with libusb support.
It features a simple firwmare-only USB implementation, running on It features a simple firwmare-only USB implementation, running on

View File

@ -26,6 +26,9 @@
/* /*
* avrdude interface for Atmel JTAG ICE mkII programmer * avrdude interface for Atmel JTAG ICE mkII programmer
*
* The AVR Dragon also uses the same protocol, so it is handled here
* as well.
*/ */
#include "ac_cfg.h" #include "ac_cfg.h"
@ -573,7 +576,7 @@ int jtagmkII_getsync(PROGRAMMER * pgm, int mode) {
#define MAXTRIES 33 #define MAXTRIES 33
unsigned char buf[3], *resp, c = 0xff; unsigned char buf[3], *resp, c = 0xff;
int status; int status;
unsigned int fwver; unsigned int fwver, hwver;
if (verbose >= 3) if (verbose >= 3)
fprintf(stderr, "%s: jtagmkII_getsync()\n", progname); fprintf(stderr, "%s: jtagmkII_getsync()\n", progname);
@ -601,6 +604,7 @@ int jtagmkII_getsync(PROGRAMMER * pgm, int mode) {
if (status > 0) { if (status > 0) {
if ((c = resp[0]) == RSP_SIGN_ON) { if ((c = resp[0]) == RSP_SIGN_ON) {
fwver = ((unsigned)resp[8] << 8) | (unsigned)resp[7]; fwver = ((unsigned)resp[8] << 8) | (unsigned)resp[7];
hwver = (unsigned)resp[9];
memcpy(serno, resp + 10, 6); memcpy(serno, resp + 10, 6);
if (verbose >= 1 && status > 17) { if (verbose >= 1 && status > 17) {
fprintf(stderr, "JTAG ICE mkII sign-on message:\n"); fprintf(stderr, "JTAG ICE mkII sign-on message:\n");
@ -651,15 +655,19 @@ int jtagmkII_getsync(PROGRAMMER * pgm, int mode) {
* There's no official documentation from Atmel about what firmware * There's no official documentation from Atmel about what firmware
* revision matches what device descriptor length. The algorithm * revision matches what device descriptor length. The algorithm
* below has been found empirically. * below has been found empirically.
*
* The original JTAG ICE mkII has hardware version 0, the AVR Dragon
* has hardware version 2 (on the slave MCU) and doesn't need the
* firmware version checks (by now).
*/ */
#define FWVER(maj, min) ((maj << 8) | (min)) #define FWVER(maj, min) ((maj << 8) | (min))
if (fwver < FWVER(3, 16)) { if (hwver == 0 && fwver < FWVER(3, 16)) {
device_descriptor_length -= 2; device_descriptor_length -= 2;
fprintf(stderr, fprintf(stderr,
"%s: jtagmkII_getsync(): " "%s: jtagmkII_getsync(): "
"S_MCU firmware version might be too old to work correctly\n", "S_MCU firmware version might be too old to work correctly\n",
progname); progname);
} else if (fwver < FWVER(4, 0)) { } else if (hwver == 0 && fwver < FWVER(4, 0)) {
device_descriptor_length -= 2; device_descriptor_length -= 2;
} }
if (verbose >= 2 && mode != EMULATOR_MODE_SPI) if (verbose >= 2 && mode != EMULATOR_MODE_SPI)
@ -668,7 +676,7 @@ int jtagmkII_getsync(PROGRAMMER * pgm, int mode) {
progname, device_descriptor_length); progname, device_descriptor_length);
if (mode == EMULATOR_MODE_SPI) { if (mode == EMULATOR_MODE_SPI) {
device_descriptor_length = 0; device_descriptor_length = 0;
if (fwver < FWVER(4, 14)) { if (hwver == 0 && fwver < FWVER(4, 14)) {
fprintf(stderr, fprintf(stderr,
"%s: jtagmkII_getsync(): ISP functionality requires firmware " "%s: jtagmkII_getsync(): ISP functionality requires firmware "
"version >= 4.14\n", "version >= 4.14\n",
@ -1167,6 +1175,51 @@ static int jtagmkII_open(PROGRAMMER * pgm, char * port)
} }
static int jtagmkII_dragon_open(PROGRAMMER * pgm, char * port)
{
long baud;
if (verbose >= 2)
fprintf(stderr, "%s: jtagmkII_dragon_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_AVRDRAGON;
#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
*/
jtagmkII_drain(pgm, 0);
jtagmkII_getsync(pgm, EMULATOR_MODE_JTAG);
return 0;
}
void jtagmkII_close(PROGRAMMER * pgm) void jtagmkII_close(PROGRAMMER * pgm)
{ {
int status; int status;
@ -1913,3 +1966,33 @@ void jtagmkII_initpgm(PROGRAMMER * pgm)
pgm->set_sck_period = jtagmkII_set_sck_period; pgm->set_sck_period = jtagmkII_set_sck_period;
pgm->page_size = 256; pgm->page_size = 256;
} }
void jtagmkII_dragon_initpgm(PROGRAMMER * pgm)
{
strcpy(pgm->type, "DRAGON_JTAG");
/*
* mandatory functions
*/
pgm->initialize = jtagmkII_initialize;
pgm->display = jtagmkII_display;
pgm->enable = jtagmkII_enable;
pgm->disable = jtagmkII_disable;
pgm->program_enable = jtagmkII_program_enable_dummy;
pgm->chip_erase = jtagmkII_chip_erase;
pgm->cmd = jtagmkII_cmd;
pgm->open = jtagmkII_dragon_open;
pgm->close = jtagmkII_close;
/*
* optional functions
*/
pgm->paged_write = jtagmkII_paged_write;
pgm->paged_load = jtagmkII_paged_load;
pgm->read_byte = jtagmkII_read_byte;
pgm->write_byte = jtagmkII_write_byte;
pgm->print_parms = jtagmkII_print_parms;
pgm->set_sck_period = jtagmkII_set_sck_period;
pgm->page_size = 256;
}

View File

@ -30,6 +30,7 @@ int jtagmkII_getparm(PROGRAMMER * pgm, unsigned char parm,
unsigned char * value); unsigned char * value);
void jtagmkII_initpgm (PROGRAMMER * pgm); void jtagmkII_initpgm (PROGRAMMER * pgm);
void jtagmkII_dragon_initpgm (PROGRAMMER * pgm);
#endif #endif

View File

@ -135,6 +135,8 @@ default_parallel { yylval=NULL; return K_DEFAULT_PARALLEL; }
default_programmer { yylval=NULL; return K_DEFAULT_PROGRAMMER; } default_programmer { yylval=NULL; return K_DEFAULT_PROGRAMMER; }
default_serial { yylval=NULL; return K_DEFAULT_SERIAL; } default_serial { yylval=NULL; return K_DEFAULT_SERIAL; }
devicecode { yylval=NULL; return K_DEVICECODE; } devicecode { yylval=NULL; return K_DEVICECODE; }
dragon_isp { yylval=NULL; return K_DRAGON_ISP; }
dragon_jtag { yylval=NULL; return K_DRAGON_JTAG; }
eecr { yylval=NULL; return K_EECR; } eecr { yylval=NULL; return K_EECR; }
eeprom { yylval=NULL; return K_EEPROM; } eeprom { yylval=NULL; return K_EEPROM; }
enablepageprogramming { yylval=NULL; return K_ENABLEPAGEPROGRAMMING; } enablepageprogramming { yylval=NULL; return K_ENABLEPAGEPROGRAMMING; }

View File

@ -2193,6 +2193,73 @@ static int stk500v2_jtagmkII_open(PROGRAMMER * pgm, char * port)
} }
/*
* Wrapper functions for the AVR Dragon 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 an AVR Dragon in ISP mode.
*/
static int stk500v2_dragon_isp_open(PROGRAMMER * pgm, char * port)
{
long baud;
if (verbose >= 2)
fprintf(stderr, "%s: stk500v2_dragon_isp_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_AVRDRAGON;
#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);
pgm->close(pgm); /* sign off correctly */
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) void stk500v2_initpgm(PROGRAMMER * pgm)
{ {
strcpy(pgm->type, "STK500V2"); strcpy(pgm->type, "STK500V2");
@ -2315,3 +2382,30 @@ void stk500v2_jtagmkII_initpgm(PROGRAMMER * pgm)
pgm->perform_osccal = stk500v2_perform_osccal; pgm->perform_osccal = stk500v2_perform_osccal;
pgm->page_size = 256; pgm->page_size = 256;
} }
void stk500v2_dragon_isp_initpgm(PROGRAMMER * pgm)
{
strcpy(pgm->type, "DRAGON_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_dragon_isp_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

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

View File

@ -29,6 +29,8 @@
#define USB_VENDOR_ATMEL 1003 #define USB_VENDOR_ATMEL 1003
#define USB_DEVICE_JTAGICEMKII 0x2103 #define USB_DEVICE_JTAGICEMKII 0x2103
#define USB_DEVICE_AVRISPMKII 0x2104 #define USB_DEVICE_AVRISPMKII 0x2104
#define USB_DEVICE_AVRDRAGON 0x2107
/* /*
* Should we query the endpoint number and max transfer size from USB? * Should we query the endpoint number and max transfer size from USB?
* After all, the JTAG ICE mkII docs document these values. * After all, the JTAG ICE mkII docs document these values.