diff --git a/ChangeLog b/ChangeLog index 0cb1e4f1..00c5ec59 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,16 @@ +2006-10-26 Joerg Wunsch + + * 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 Released AVRDUDE 5.2. diff --git a/avrdude.1 b/avrdude.1 index 0b424356..3b1e969e 100644 --- a/avrdude.1 +++ b/avrdude.1 @@ -19,7 +19,7 @@ .\" .\" $Id$ .\" -.Dd DATE October 9, 2006 +.Dd DATE October 26, 2006 .Os .Dt AVRDUDE 1 .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). For the JTAG ICE mkII, both JTAG and ISP mode are supported. .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 .Nm avrdude has been compiled with libusb support. diff --git a/avrdude.conf.in b/avrdude.conf.in index 6b1ff2c2..e5dba6c6 100644 --- a/avrdude.conf.in +++ b/avrdude.conf.in @@ -17,7 +17,8 @@ # desc = ; # quoted string # type = par | stk500 | stk500v2 | stk500pp | stk500hvsp | stk500generic | # avr910 | butterfly | usbasp | -# jtagmki | jtagmkii | jtagmkii_isp; # programmer type +# jtagmki | jtagmkii | jtagmkii_isp | +# dragon_jtag | dragon_isp; # programmer type # baudrate = ; # baudrate for avr910-programmer # vcc = [, ... ] ; # pin number(s) # reset = ; # pin number @@ -441,6 +442,22 @@ programmer 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 id = "pavr"; desc = "Jason Kyle's pAVR Serial Programmer"; diff --git a/config_gram.y b/config_gram.y index 10dc23f2..b8b8aa1b 100644 --- a/config_gram.y +++ b/config_gram.y @@ -88,6 +88,8 @@ static int parse_cmdbits(OPCODE * op); %token K_DEFAULT_SERIAL %token K_DESC %token K_DEVICECODE +%token K_DRAGON_ISP +%token K_DRAGON_JTAG %token K_STK500_DEVCODE %token K_AVR910_DEVCODE %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 { strncpy(current_prog->desc, $3->value.string, PGM_DESCLEN); current_prog->desc[PGM_DESCLEN-1] = 0; diff --git a/doc/avrdude.texi b/doc/avrdude.texi index 9e3dafb8..f8ca982a 100644 --- a/doc/avrdude.texi +++ b/doc/avrdude.texi @@ -184,6 +184,18 @@ 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. +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 has been compiled with libusb support. It features a simple firwmare-only USB implementation, running on diff --git a/jtagmkII.c b/jtagmkII.c index cfb4e62a..f43a0a6a 100644 --- a/jtagmkII.c +++ b/jtagmkII.c @@ -26,6 +26,9 @@ /* * 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" @@ -573,7 +576,7 @@ int jtagmkII_getsync(PROGRAMMER * pgm, int mode) { #define MAXTRIES 33 unsigned char buf[3], *resp, c = 0xff; int status; - unsigned int fwver; + unsigned int fwver, hwver; if (verbose >= 3) fprintf(stderr, "%s: jtagmkII_getsync()\n", progname); @@ -601,6 +604,7 @@ int jtagmkII_getsync(PROGRAMMER * pgm, int mode) { if (status > 0) { if ((c = resp[0]) == RSP_SIGN_ON) { fwver = ((unsigned)resp[8] << 8) | (unsigned)resp[7]; + hwver = (unsigned)resp[9]; memcpy(serno, resp + 10, 6); if (verbose >= 1 && status > 17) { 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 * revision matches what device descriptor length. The algorithm * 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)) - if (fwver < FWVER(3, 16)) { + if (hwver == 0 && fwver < FWVER(3, 16)) { device_descriptor_length -= 2; fprintf(stderr, "%s: jtagmkII_getsync(): " "S_MCU firmware version might be too old to work correctly\n", progname); - } else if (fwver < FWVER(4, 0)) { + } else if (hwver == 0 && fwver < FWVER(4, 0)) { device_descriptor_length -= 2; } if (verbose >= 2 && mode != EMULATOR_MODE_SPI) @@ -668,7 +676,7 @@ int jtagmkII_getsync(PROGRAMMER * pgm, int mode) { progname, device_descriptor_length); if (mode == EMULATOR_MODE_SPI) { device_descriptor_length = 0; - if (fwver < FWVER(4, 14)) { + if (hwver == 0 && fwver < FWVER(4, 14)) { fprintf(stderr, "%s: jtagmkII_getsync(): ISP functionality requires firmware " "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) { int status; @@ -1913,3 +1966,33 @@ void jtagmkII_initpgm(PROGRAMMER * pgm) pgm->set_sck_period = jtagmkII_set_sck_period; 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; +} diff --git a/jtagmkII.h b/jtagmkII.h index 9a0ea2f7..39eea580 100644 --- a/jtagmkII.h +++ b/jtagmkII.h @@ -30,6 +30,7 @@ int jtagmkII_getparm(PROGRAMMER * pgm, unsigned char parm, unsigned char * value); void jtagmkII_initpgm (PROGRAMMER * pgm); +void jtagmkII_dragon_initpgm (PROGRAMMER * pgm); #endif diff --git a/lexer.l b/lexer.l index 32ccc928..04ba9ad4 100644 --- a/lexer.l +++ b/lexer.l @@ -135,6 +135,8 @@ default_parallel { yylval=NULL; return K_DEFAULT_PARALLEL; } default_programmer { yylval=NULL; return K_DEFAULT_PROGRAMMER; } default_serial { yylval=NULL; return K_DEFAULT_SERIAL; } 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; } eeprom { yylval=NULL; return K_EEPROM; } enablepageprogramming { yylval=NULL; return K_ENABLEPAGEPROGRAMMING; } diff --git a/stk500v2.c b/stk500v2.c index 2087ae26..013504b1 100644 --- a/stk500v2.c +++ b/stk500v2.c @@ -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) { strcpy(pgm->type, "STK500V2"); @@ -2315,3 +2382,30 @@ void stk500v2_jtagmkII_initpgm(PROGRAMMER * pgm) pgm->perform_osccal = stk500v2_perform_osccal; 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; +} diff --git a/stk500v2.h b/stk500v2.h index 97cdf6a2..469a07bc 100644 --- a/stk500v2.h +++ b/stk500v2.h @@ -27,6 +27,7 @@ void stk500v2_initpgm (PROGRAMMER * pgm); void stk500hvsp_initpgm (PROGRAMMER * pgm); void stk500pp_initpgm (PROGRAMMER * pgm); void stk500v2_jtagmkII_initpgm(PROGRAMMER * pgm); +void stk500v2_dragon_isp_initpgm(PROGRAMMER * pgm); #endif diff --git a/usbdevs.h b/usbdevs.h index 608f9d70..1b390ffb 100644 --- a/usbdevs.h +++ b/usbdevs.h @@ -29,6 +29,8 @@ #define USB_VENDOR_ATMEL 1003 #define USB_DEVICE_JTAGICEMKII 0x2103 #define USB_DEVICE_AVRISPMKII 0x2104 +#define USB_DEVICE_AVRDRAGON 0x2107 + /* * Should we query the endpoint number and max transfer size from USB? * After all, the JTAG ICE mkII docs document these values.