From 975d7b786a4c6ad27693c5e53e04e23906bb0b18 Mon Sep 17 00:00:00 2001 From: Joerg Wunsch Date: Thu, 28 Jul 2005 16:06:35 +0000 Subject: [PATCH] Extend the butterfly code to fully support AVR109 boot loaders. Notable changes to butterfly.c include: . do not exit for unsupported devices but return -1 from the init function instead; that way the -F option can be used to continue anyway . honor the -b option as arbitrary bootloaders could be implemented with any baud rate, not just the fixed 19200 Bd used by the butterfly . implement functionality to read the fuse and lock bits, and write the (boot) lock bits, resp. . fix the signature byte order The remaining files document the new functionality. git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk/avrdude@486 81a1dc3b-b13d-400b-aceb-764788c761c2 --- ChangeLog | 10 ++++- avrdude.1 | 15 ++++++- avrdude.conf.in | 12 ++++++ butterfly.c | 104 ++++++++++++++++++++++++++++++++++------------- doc/avrdude.texi | 58 ++++++++++++++++++++++---- 5 files changed, 160 insertions(+), 39 deletions(-) diff --git a/ChangeLog b/ChangeLog index 6b640eb7..272ce9eb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,4 +1,12 @@ -2005/07/26 Brian S. Dean +2005-07-27 Joerg Wunsch + + (This work has been done as part of a contract with Atmel, Dresden.) + * butterfly.c: Implement full support for AVR109 boot loaders. + * avrdude.conf.in: add avr109 and avr911 as alias for butterfly. + * avrdude.1: Document the AVR109 addition. + * doc/avrdude.texi: (Ditto.) + +2005-07-26 Brian S. Dean * main.c: Don't call exit() directly here - set the exit value and jump to the diff --git a/avrdude.1 b/avrdude.1 index ba7f6e78..68688fb8 100644 --- a/avrdude.1 +++ b/avrdude.1 @@ -19,7 +19,7 @@ .\" .\" $Id$ .\" -.Dd DATE May 10, 2005 +.Dd DATE July 28, 2005 .Os .Dt AVRDUDE 1 .Sh NAME @@ -55,6 +55,7 @@ microcontrollers. .Nm Avrdude supports Atmel's STK500 programmer, Atmel's JTAG ICE mkII, +programmers complying to AppNote AVR910 and AVR109 (including the Butterfly), as well as a simple hard-wired programmer connected directly to a .Xr ppi 4 @@ -87,6 +88,11 @@ port. Both, firmware versions 1.x and 2.x can be handled, but require a different programmer type specification (by now). .Pp +The simple serial programmer described in Atmel's application note +AVR910, and the bootloader described in Atmel's application note +AVR109 (which is also used by the AVR Butterfly evaluation board), are +supported on a serial port. +.Pp Atmel's JTAG ICE mkII is supported as well to up- or download memory areas from/to an AVR target (no support for on-chip debugging). .Pp @@ -567,3 +573,10 @@ The JTAGICE mkII programmer currently cannot write to the flash ROM one byte at a time. For that reason, updating the flash ROM from terminal mode does not work. +.Pp +The device IDs used by AVR910 and AVR109 do not match, so the +avr109 (aka. butterfly) programmer might report +.Dl "selected device is not supported by programmer" . +Use the -F option to force +.Nm +to contiue anway. diff --git a/avrdude.conf.in b/avrdude.conf.in index 9a5e62c1..1251ec81 100644 --- a/avrdude.conf.in +++ b/avrdude.conf.in @@ -267,6 +267,18 @@ programmer type = butterfly; ; +programmer + id = "avr109"; + desc = "Atmel AppNote AVR109 Boot Loader"; + type = butterfly; +; + +programmer + id = "avr911"; + desc = "Atmel AppNote AVR911 AVROSP"; + type = butterfly; +; + programmer id = "jtagmkII"; desc = "Atmel JTAG ICE mkII"; diff --git a/butterfly.c b/butterfly.c index 0108ab62..97f99c14 100644 --- a/butterfly.c +++ b/butterfly.c @@ -1,6 +1,7 @@ /* * avrdude - A Downloader/Uploader for AVR device programmers * Copyright (C) 2003-2004 Theodore A. Roth + * Copyright (C) 2005 Joerg Wunsch * * 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 @@ -24,6 +25,14 @@ * evaluation board. This board features a bootloader which uses a protocol * very similar, but not identical, to the one described in application note * avr910. + * + * Actually, the butterfly uses a predecessor of the avr910 protocol + * which is described in application notes avr109 (generic AVR + * bootloader) and avr911 (opensource programmer). This file now + * fully handles the features present in avr109. It should probably + * be renamed to avr109, but we rather stick with the old name inside + * the file. We'll provide aliases for "avr109" and "avr911" in + * avrdude.conf so users could call it by these name as well. */ @@ -222,7 +231,10 @@ static int butterfly_initialize(PROGRAMMER * pgm, AVRPART * p) no_show_func_info(); - /* send some ESC to activate butterfly bootloader */ + /* + * Send some ESC to activate butterfly bootloader. This is not needed + * for plain avr109 bootloaders but does not harm there either. + */ butterfly_send(pgm, "\033\033\033\033", 4); butterfly_drain(pgm, 0); @@ -271,7 +283,7 @@ static int butterfly_initialize(PROGRAMMER * pgm, AVRPART * p) if (c != 'Y') { fprintf(stderr, "%s: error: buffered memory access not supported. Maybe it isn't\n"\ - "a butterfly but a AVR910 device?\n", progname); + "a butterfly/AVR109 but a AVR910 device?\n", progname); exit(1); }; butterfly_recv(pgm, &c, 1); @@ -300,10 +312,11 @@ static int butterfly_initialize(PROGRAMMER * pgm, AVRPART * p) fprintf(stderr,"\n"); if (!dev_supported) { + /* FIXME: if nothing matched, we should rather compare the device + signatures. */ fprintf(stderr, "%s: error: selected device is not supported by programmer: %s\n", progname, p->id); - exit(1); } /* Tell the programmer which part we selected. */ @@ -314,9 +327,7 @@ static int butterfly_initialize(PROGRAMMER * pgm, AVRPART * p) butterfly_send(pgm, buf, 2); butterfly_vfy_cmd_sent(pgm, "select device"); - butterfly_enter_prog_mode(pgm); - - return 0; + return dev_supported? 0: -1; } @@ -325,7 +336,7 @@ static void butterfly_disable(PROGRAMMER * pgm) { no_show_func_info(); - /* Do nothing. */ + butterfly_leave_prog_mode(pgm); return; } @@ -335,7 +346,7 @@ static void butterfly_enable(PROGRAMMER * pgm) { no_show_func_info(); - /* Do nothing. */ + butterfly_enter_prog_mode(pgm); return; } @@ -346,7 +357,13 @@ static int butterfly_open(PROGRAMMER * pgm, char * port) no_show_func_info(); strcpy(pgm->port, port); - pgm->fd = serial_open(port, 19200); + /* + * If baudrate was not specified use 19200 Baud + */ + if(pgm->baudrate == 0) { + pgm->baudrate = 19200; + } + pgm->fd = serial_open(port, pgm->baudrate); /* * drain any extraneous input @@ -361,8 +378,6 @@ static void butterfly_close(PROGRAMMER * pgm) { no_show_func_info(); - butterfly_leave_prog_mode(pgm); - /* "exit programmer" added by Martin Thomas 2/2004 */ butterfly_send(pgm, "E", 1); @@ -401,24 +416,31 @@ static int butterfly_write_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m, no_show_func_info(); - if ((strcmp(m->desc, "flash") != 0) && (strcmp(m->desc, "eeprom") != 0)) + if ((strcmp(m->desc, "flash") == 0) || (strcmp(m->desc, "eeprom") == 0)) + { + cmd[0] = 'B'; + cmd[1] = 0; + if ((cmd[3] = toupper(m->desc[0])) == 'E') { /* write to eeprom */ + cmd[2] = 1; + cmd[4] = value; + size = 5; + } else { /* write to flash */ + /* @@@ not yet implemented */ + cmd[2] = 2; + size = 6; + return -1; + } + butterfly_set_addr(pgm, addr); + } + else if (strcmp(m->desc, "lock") == 0) + { + cmd[0] = 'l'; + cmd[1] = value; + size = 2; + } + else return -1; - cmd[0] = 'B'; - cmd[1] = 0; - if ((cmd[3] = toupper(m->desc[0])) == 'E') { /* write to eeprom */ - cmd[2] = 1; - cmd[4] = value; - size = 5; - } else { /* write to flash */ - /* @@@ not yet implemented */ - cmd[2] = 2; - size = 6; - return -1; - }; - - butterfly_set_addr(pgm, addr); - butterfly_send(pgm, cmd, size); butterfly_vfy_cmd_sent(pgm, "write byte"); @@ -475,6 +497,8 @@ static int butterfly_read_byte_eeprom(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m, static int butterfly_read_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m, unsigned long addr, unsigned char * value) { + unsigned char cmd; + no_show_func_info(); if (strcmp(m->desc, "flash") == 0) { @@ -485,7 +509,25 @@ static int butterfly_read_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m, return butterfly_read_byte_eeprom(pgm, p, m, addr, value); } - return -1; + if (strcmp(m->desc, "lfuse") == 0) { + cmd = 'F'; + } + else if (strcmp(m->desc, "hfuse") == 0) { + cmd = 'N'; + } + else if (strcmp(m->desc, "efuse") == 0) { + cmd = 'Q'; + } + else if (strcmp(m->desc, "lock") == 0) { + cmd = 'r'; + } + else + return -1; + + butterfly_send(pgm, &cmd, 1); + butterfly_recv(pgm, value, 1); + + return *value == '?'? -1: 0; } @@ -581,6 +623,8 @@ static int butterfly_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m, /* Signature byte reads are always 3 bytes. */ static int butterfly_read_sig_bytes(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m) { + unsigned char tmp; + no_show_func_info(); if (m->size < 3) { @@ -590,6 +634,10 @@ static int butterfly_read_sig_bytes(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m) butterfly_send(pgm, "s", 1); butterfly_recv(pgm, m->buf, 3); + /* Returned signature has wrong order. */ + tmp = m->buf[2]; + m->buf[2] = m->buf[0]; + m->buf[0] = tmp; return 3; } diff --git a/doc/avrdude.texi b/doc/avrdude.texi index 375ebe87..12ae8def 100644 --- a/doc/avrdude.texi +++ b/doc/avrdude.texi @@ -129,9 +129,10 @@ from the contents of a file, while interactive mode is useful for exploring memory contents, modifing individual bytes of eeprom, programming fuse/lock bits, etc. -AVRDUDE supports four basic programmer types: Atmel's STK500, +AVRDUDE supports five basic programmer types: Atmel's STK500, Atmel's JTAG ICE mkII, appnote -avr910 and the PPI (parallel port interface). PPI represents a class +avr910, appnote avr109 (including the AVR Butterfly), +and the PPI (parallel port interface). PPI represents a class of simple programmers where the programming lines are directly connected to the PC parallel port. Several pin configurations exist for several variations of the PPI programmers, and AVRDUDE can be be @@ -140,9 +141,13 @@ programmer on the command line or by creating a new entry in its configuration file. All that's usually required for a new entry is to tell AVRDUDE which pins to use for each programming function. -The STK500, JTAG ICE and avr910 use the serial port to communicate with the PC -and contains on-board logic to control the programming of the target -device. The fundamental difference between the two types lies in the +The STK500, JTAG ICE, avr910, and avr109/butterfly use the serial port to communicate with the PC. +The STK500, JTAG ICE, and avr910 contain on-board logic to control the programming of the target +device. +The avr109 bootloader implements a protocol similar to avr910, but is +actually implemented in the boot area of the target's flash ROM, as +opposed to being an external device. +The fundamental difference between the two types lies in the protocol used to control the programmer. The avr910 protocol is very simplistic and can easily be used as the basis for a simple, home made programer since the firmware is available online. On the other hand, @@ -152,8 +157,7 @@ The JTAG ICE also uses a serial communication protocol which is similar to the STK500 firmware version 2 one. However, as the JTAG ICE is intented to allow on-chip debugging as well as memory programming, the protocol is more sophisticated. -(This protocol can also be run on top of USB, but AVRDUDE by now only -supports the RS-232-based option.) +(This protocol can also be run on top of USB.) Only the memory programming functionality of the JTAG ICE is supported by AVRDUDE. @@ -356,9 +360,15 @@ ABCmini Board, aka Dick Smith HOTCHIP @itemx alf Nightshade ALF-PgmAVR, http://nightshade.homeip.net/ +@itemx avr109 +Atmel AppNote AVR109 Boot Loader + @itemx avr910 Atmel Low Cost Serial Programmer +@itemx avr911 +Atmel AppNote AVR911 AVROSP (an alias for avr109) + @itemx avrisp Atmel AVR ISP @@ -507,7 +517,7 @@ programming, then verifying at the end of programming that the fuses have not changed. If you want to change fuses you will need to specify this option, as avrdude will see the fuses have changed (even though you wanted to) and will change them back for your "saftey". This option was designed to -prevent cases of fuse bits magically changing. +prevent cases of fuse bits magically changing (usually called @emph{safemode}). @item -t Tells AVRDUDE to enter the interactive ``terminal'' mode instead of up- @@ -1037,7 +1047,7 @@ programmer id = [, [, ] ...] ; # are quoted strings desc = ; # quoted string type = par | stk500 ; # programmer type - baudrate = ; # baudrate for avr910 + baudrate = ; # baudrate for serial ports vcc = [, ... ] ; # pin number(s) reset = ; # pin number sck = ; # pin number @@ -1190,6 +1200,24 @@ problem with the at90s4433/2333's; see the at90s4433 errata at: @url{http://www.atmel.com/atmel/acrobat/doc1280.pdf} +@item +The boot loader from application note AVR109 (and thus also the AVR +Butterfly) does not support writing of fuse bits. Writing lock bits +is supported, but is restricted to the boot lock bits (BLBxx). These +are restrictions imposed by the underlying SPM instruction that is used +to program the device from inside the boot loader. Note that programming +the boot lock bits can result in a ``shoot-into-your-foot'' scenario as +the only way to unprogram these bits is a chip erase, which will also +erase the boot loader code. + +The boot loader implements the ``chip erase'' function by erasing the +flash pages of the application section. + +Reading fuse and lock bits is fully supported. + +Note that due to the unability to write the fuse bits, the safemode +functionality does not make sense for these boot loaders. + @end itemize @@ -1696,6 +1724,18 @@ response to a number of occasions when an AVR had stopped responding because the by an error caused by the programmer. Programmer of course meaning both the physical device, and the person sitting at the keyboard. +@item +Problem: AVRDUDE says my device is not supported when using the AVR109 boot loader + +Solution: Currently, AVRDUDE uses the AVR910 device codes given in the +@code{avrdude.conf} file, and matches them against the list of supported +devices reported by the programmer. Unfortunately, there are no device +codes at all for some of the newer AVR devices, and even worse, the +device codes listed in @code{preprocessor.xls} of appnote AVR109 do not +match those once specified in AVR910. + +Use the -F option to force AVRDUDE to continue anyway. + @item Problem: Updating the flash ROM from terminal mode does not work with the JTAG ICE mkII.