From c35b4481dc9155cf7a7c9bf8920ad281ac030fdc Mon Sep 17 00:00:00 2001 From: joerg_wunsch Date: Wed, 1 Nov 2006 21:47:25 +0000 Subject: [PATCH] Implement and document HVSP and PP modes for the AVR Dragon. git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk/avrdude@677 81a1dc3b-b13d-400b-aceb-764788c761c2 --- ChangeLog | 12 ++++ NEWS | 2 +- avrdude.1 | 3 +- avrdude.conf.in | 19 +++++- config_gram.y | 14 ++++ doc/avrdude.texi | 10 ++- jtagmkII.c | 4 +- jtagmkII_private.h | 2 +- lexer.l | 2 + stk500v2.c | 165 ++++++++++++++++++++++++++++++++++++++++++++- stk500v2.h | 2 + 11 files changed, 226 insertions(+), 9 deletions(-) diff --git a/ChangeLog b/ChangeLog index 6d357e7d..f0bf1e08 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,15 @@ +2006-11-01 Joerg Wunsch + + * avrdude.conf.in: Implement HVSP and PP modes for the AVR Dragon. + * config_gram.y: (Ditto.) + * jtagmkII.c: (Ditto.) + * jtagmkII_private.h: (Ditto.) + * lexer.l: (Ditto.) + * stk500v2.c: (Ditto.) + * stk500v2.h: (Ditto.) + * avrdude.1: Document the HVSP and PP support for the Dragon. + * doc/avrdude.texi: (Ditto.) + 2006-10-27 Joerg Wunsch * jtagmkI.c: Implement a flags field in struct serdev, and populate it diff --git a/NEWS b/NEWS index 06e154bc..7946ba9c 100644 --- a/NEWS +++ b/NEWS @@ -7,7 +7,7 @@ Approximate change log for AVRDUDE by version. ---------------------------------------------------------------------- Current: - * Add support for the AVR Dragon (JTAG and ISP mode). + * Add support for the AVR Dragon (all modes: ISP, JTAG, HVSP, PP). Version 5.2: diff --git a/avrdude.1 b/avrdude.1 index 3b1e969e..5907e42b 100644 --- a/avrdude.1 +++ b/avrdude.1 @@ -114,8 +114,7 @@ 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.) +The AVR Dragon is supported in all modes (ISP, JTAG, HVSP, PP). 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. diff --git a/avrdude.conf.in b/avrdude.conf.in index e5dba6c6..a6f5f428 100644 --- a/avrdude.conf.in +++ b/avrdude.conf.in @@ -18,7 +18,8 @@ # type = par | stk500 | stk500v2 | stk500pp | stk500hvsp | stk500generic | # avr910 | butterfly | usbasp | # jtagmki | jtagmkii | jtagmkii_isp | -# dragon_jtag | dragon_isp; # programmer type +# dragon_jtag | dragon_isp | dragon_pp | +# dragon_hvsp; # programmer type # baudrate = ; # baudrate for avr910-programmer # vcc = [, ... ] ; # pin number(s) # reset = ; # pin number @@ -458,6 +459,22 @@ programmer type = dragon_isp; ; +# AVR Dragon in PP mode +programmer + id = "dragon_pp"; + desc = "Atmel AVR Dragon in PP mode"; + baudrate = 115200; + type = dragon_pp; +; + +# AVR Dragon in HVSP mode +programmer + id = "dragon_hvsp"; + desc = "Atmel AVR Dragon in HVSP mode"; + baudrate = 115200; + type = dragon_hvsp; +; + programmer id = "pavr"; desc = "Jason Kyle's pAVR Serial Programmer"; diff --git a/config_gram.y b/config_gram.y index b8b8aa1b..ad8978d7 100644 --- a/config_gram.y +++ b/config_gram.y @@ -88,8 +88,10 @@ static int parse_cmdbits(OPCODE * op); %token K_DEFAULT_SERIAL %token K_DESC %token K_DEVICECODE +%token K_DRAGON_HVSP %token K_DRAGON_ISP %token K_DRAGON_JTAG +%token K_DRAGON_PP %token K_STK500_DEVCODE %token K_AVR910_DEVCODE %token K_EEPROM @@ -439,6 +441,12 @@ prog_parm : } } | + K_TYPE TKN_EQUAL K_DRAGON_HVSP { + { + stk500v2_dragon_hvsp_initpgm(current_prog); + } + } | + K_TYPE TKN_EQUAL K_DRAGON_ISP { { stk500v2_dragon_isp_initpgm(current_prog); @@ -451,6 +459,12 @@ prog_parm : } } | + K_TYPE TKN_EQUAL K_DRAGON_PP { + { + stk500v2_dragon_pp_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 f8ca982a..5a81c9e2 100644 --- a/doc/avrdude.texi +++ b/doc/avrdude.texi @@ -184,7 +184,7 @@ 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. +The AVR Dragon is supported in all modes (ISP, JTAG, HVSP, PP). (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 @@ -385,6 +385,14 @@ Brian Dean's Programmer,@* Atmel Butterfly Development Board @item @code{dt006} @tab Dontronics DT006 +@item @code{dragon_hvsp} @tab +AVR Dragon in high-voltage serial programming mode +@item @code{dragon_isp} @tab +AVR Dragon in ISP mode +@item @code{dragon_jtag} @tab +AVR Dragon in JTAG mode +@item @code{dragon_pp} @tab +AVR Dragon in (high-voltage) parallel programming mode @item @code{jtagmkI} @tab Atmel JTAG ICE mkI, running at 115200 Bd @item @code{jtag1} @tab diff --git a/jtagmkII.c b/jtagmkII.c index a4846626..660112b2 100644 --- a/jtagmkII.c +++ b/jtagmkII.c @@ -232,7 +232,7 @@ static void jtagmkII_prmsg(PROGRAMMER * pgm, unsigned char * data, size_t len) switch (data[1]) { case EMULATOR_MODE_DEBUGWIRE: fprintf(stderr, ": DebugWire"); break; case EMULATOR_MODE_JTAG: fprintf(stderr, ": JTAG"); break; - case EMULATOR_MODE_UNKNOWN: fprintf(stderr, ": Unknown"); break; + case EMULATOR_MODE_HV: fprintf(stderr, ": HVSP/PP"); break; case EMULATOR_MODE_SPI: fprintf(stderr, ": SPI"); break; } putc('\n', stderr); @@ -674,7 +674,7 @@ int jtagmkII_getsync(PROGRAMMER * pgm, int mode) { fprintf(stderr, "%s: jtagmkII_getsync(): Using a %zu-byte device descriptor\n", progname, device_descriptor_length); - if (mode == EMULATOR_MODE_SPI) { + if (mode == EMULATOR_MODE_SPI || mode == EMULATOR_MODE_HV) { device_descriptor_length = 0; if (hwver == 0 && fwver < FWVER(4, 14)) { fprintf(stderr, diff --git a/jtagmkII_private.h b/jtagmkII_private.h index b1ebe89e..c7f8ce7f 100644 --- a/jtagmkII_private.h +++ b/jtagmkII_private.h @@ -177,7 +177,7 @@ #define PAR_EMULATOR_MODE 0x03 # define EMULATOR_MODE_DEBUGWIRE 0x00 # define EMULATOR_MODE_JTAG 0x01 -# define EMULATOR_MODE_UNKNOWN 0x02 +# define EMULATOR_MODE_HV 0x02 /* HVSP or PP mode of AVR Dragon */ # define EMULATOR_MODE_SPI 0x03 #define PAR_IREG 0x04 #define PAR_BAUD_RATE 0x05 diff --git a/lexer.l b/lexer.l index 04ba9ad4..a52f914a 100644 --- a/lexer.l +++ b/lexer.l @@ -135,8 +135,10 @@ 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_hvsp { yylval=NULL; return K_DRAGON_HVSP; } dragon_isp { yylval=NULL; return K_DRAGON_ISP; } dragon_jtag { yylval=NULL; return K_DRAGON_JTAG; } +dragon_pp { yylval=NULL; return K_DRAGON_PP; } 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 013504b1..26599165 100644 --- a/stk500v2.c +++ b/stk500v2.c @@ -131,10 +131,12 @@ struct jtagispentry }; static struct jtagispentry jtagispcmds[] = { + /* generic */ { CMD_SET_PARAMETER, 2 }, { CMD_GET_PARAMETER, 3 }, { CMD_OSCCAL, 2 }, { CMD_LOAD_ADDRESS, 2 }, + /* ISP mode */ { CMD_ENTER_PROGMODE_ISP, 2 }, { CMD_LEAVE_PROGMODE_ISP, 2 }, { CMD_CHIP_ERASE_ISP, 2 }, @@ -148,7 +150,37 @@ static struct jtagispentry jtagispcmds[] = { { CMD_READ_LOCK_ISP, 4 }, { CMD_READ_SIGNATURE_ISP, 4 }, { CMD_READ_OSCCAL_ISP, 4 }, - { CMD_SPI_MULTI, SZ_SPI_MULTI } + { CMD_SPI_MULTI, SZ_SPI_MULTI }, + /* all HV modes */ + { CMD_SET_CONTROL_STACK, 2 }, + /* HVSP mode */ + { CMD_ENTER_PROGMODE_HVSP, 2 }, + { CMD_LEAVE_PROGMODE_HVSP, 2 }, + { CMD_CHIP_ERASE_HVSP, 2 }, + { CMD_PROGRAM_FLASH_HVSP, 2 }, + { CMD_READ_FLASH_HVSP, SZ_READ_FLASH_EE }, + { CMD_PROGRAM_EEPROM_HVSP, 2 }, + { CMD_READ_EEPROM_HVSP, SZ_READ_FLASH_EE }, + { CMD_PROGRAM_FUSE_HVSP, 2 }, + { CMD_READ_FUSE_HVSP, 3 }, + { CMD_PROGRAM_LOCK_HVSP, 2 }, + { CMD_READ_LOCK_HVSP, 3 }, + { CMD_READ_SIGNATURE_HVSP, 3 }, + { CMD_READ_OSCCAL_HVSP, 3 }, + /* PP mode */ + { CMD_ENTER_PROGMODE_PP, 2 }, + { CMD_LEAVE_PROGMODE_PP, 2 }, + { CMD_CHIP_ERASE_PP, 2 }, + { CMD_PROGRAM_FLASH_PP, 2 }, + { CMD_READ_FLASH_PP, SZ_READ_FLASH_EE }, + { CMD_PROGRAM_EEPROM_PP, 2 }, + { CMD_READ_EEPROM_PP, SZ_READ_FLASH_EE }, + { CMD_PROGRAM_FUSE_PP, 2 }, + { CMD_READ_FUSE_PP, 3 }, + { CMD_PROGRAM_LOCK_PP, 2 }, + { CMD_READ_LOCK_PP, 3 }, + { CMD_READ_SIGNATURE_PP, 3 }, + { CMD_READ_OSCCAL_PP, 3 }, }; static int stk500v2_getparm(PROGRAMMER * pgm, unsigned char parm, unsigned char * value); @@ -2260,6 +2292,73 @@ static int stk500v2_dragon_isp_open(PROGRAMMER * pgm, char * port) } +/* + * Wrapper functions for the AVR Dragon in HV 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 HV mode (HVSP or parallel). + */ +static int stk500v2_dragon_hv_open(PROGRAMMER * pgm, char * port) +{ + long baud; + + if (verbose >= 2) + fprintf(stderr, "%s: stk500v2_dragon_hv_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_HV) != 0) { + fprintf(stderr, "%s: failed to sync with the JTAG ICE mkII in HV 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"); @@ -2409,3 +2508,67 @@ void stk500v2_dragon_isp_initpgm(PROGRAMMER * pgm) pgm->set_sck_period = stk500v2_set_sck_period_mk2; pgm->page_size = 256; } + +void stk500v2_dragon_pp_initpgm(PROGRAMMER * pgm) +{ + strcpy(pgm->type, "DRAGON_PP"); + + /* + * mandatory functions + */ + pgm->initialize = stk500pp_initialize; + pgm->display = stk500v2_display; + pgm->enable = stk500v2_enable; + pgm->disable = stk500pp_disable; + pgm->program_enable = stk500pp_program_enable; + pgm->chip_erase = stk500pp_chip_erase; + pgm->cmd = stk500hv_cmd; + pgm->open = stk500v2_dragon_hv_open; + pgm->close = jtagmkII_close; + + /* + * optional functions + */ + pgm->read_byte = stk500pp_read_byte; + pgm->write_byte = stk500pp_write_byte; + pgm->paged_write = stk500pp_paged_write; + pgm->paged_load = stk500pp_paged_load; + pgm->print_parms = stk500v2_print_parms; + pgm->set_vtarget = stk500v2_set_vtarget; + pgm->set_varef = stk500v2_set_varef; + pgm->set_fosc = stk500v2_set_fosc; + pgm->set_sck_period = stk500v2_set_sck_period_mk2; + pgm->page_size = 256; +} + +void stk500v2_dragon_hvsp_initpgm(PROGRAMMER * pgm) +{ + strcpy(pgm->type, "DRAGON_HVSP"); + + /* + * mandatory functions + */ + pgm->initialize = stk500hvsp_initialize; + pgm->display = stk500v2_display; + pgm->enable = stk500v2_enable; + pgm->disable = stk500hvsp_disable; + pgm->program_enable = stk500hvsp_program_enable; + pgm->chip_erase = stk500hvsp_chip_erase; + pgm->cmd = stk500hv_cmd; + pgm->open = stk500v2_dragon_hv_open; + pgm->close = jtagmkII_close; + + /* + * optional functions + */ + pgm->read_byte = stk500hvsp_read_byte; + pgm->write_byte = stk500hvsp_write_byte; + pgm->paged_write = stk500hvsp_paged_write; + pgm->paged_load = stk500hvsp_paged_load; + pgm->print_parms = stk500v2_print_parms; + pgm->set_vtarget = stk500v2_set_vtarget; + pgm->set_varef = stk500v2_set_varef; + pgm->set_fosc = stk500v2_set_fosc; + pgm->set_sck_period = stk500v2_set_sck_period_mk2; + pgm->page_size = 256; +} diff --git a/stk500v2.h b/stk500v2.h index 469a07bc..c347b84a 100644 --- a/stk500v2.h +++ b/stk500v2.h @@ -27,7 +27,9 @@ void stk500v2_initpgm (PROGRAMMER * pgm); void stk500hvsp_initpgm (PROGRAMMER * pgm); void stk500pp_initpgm (PROGRAMMER * pgm); void stk500v2_jtagmkII_initpgm(PROGRAMMER * pgm); +void stk500v2_dragon_hvsp_initpgm(PROGRAMMER * pgm); void stk500v2_dragon_isp_initpgm(PROGRAMMER * pgm); +void stk500v2_dragon_pp_initpgm(PROGRAMMER * pgm); #endif