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
This commit is contained in:
joerg_wunsch 2005-07-28 16:06:35 +00:00
parent 6773b66a8d
commit eed121e91f
5 changed files with 160 additions and 39 deletions

View File

@ -1,4 +1,12 @@
2005/07/26 Brian S. Dean <bsd@bsdhome.com> 2005-07-27 Joerg Wunsch <j@uriah.heep.sax.de>
(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 <bsd@bsdhome.com>
* main.c: * main.c:
Don't call exit() directly here - set the exit value and jump to the Don't call exit() directly here - set the exit value and jump to the

View File

@ -19,7 +19,7 @@
.\" .\"
.\" $Id$ .\" $Id$
.\" .\"
.Dd DATE May 10, 2005 .Dd DATE July 28, 2005
.Os .Os
.Dt AVRDUDE 1 .Dt AVRDUDE 1
.Sh NAME .Sh NAME
@ -55,6 +55,7 @@ microcontrollers.
.Nm Avrdude .Nm Avrdude
supports Atmel's STK500 programmer, supports Atmel's STK500 programmer,
Atmel's JTAG ICE mkII, Atmel's JTAG ICE mkII,
programmers complying to AppNote AVR910 and AVR109 (including the Butterfly),
as well as a simple hard-wired as well as a simple hard-wired
programmer connected directly to a programmer connected directly to a
.Xr ppi 4 .Xr ppi 4
@ -87,6 +88,11 @@ port.
Both, firmware versions 1.x and 2.x can be handled, but require a Both, firmware versions 1.x and 2.x can be handled, but require a
different programmer type specification (by now). different programmer type specification (by now).
.Pp .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 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). areas from/to an AVR target (no support for on-chip debugging).
.Pp .Pp
@ -567,3 +573,10 @@ The JTAGICE mkII programmer currently cannot write to the flash ROM
one byte at a time. one byte at a time.
For that reason, updating the flash ROM from terminal mode does not For that reason, updating the flash ROM from terminal mode does not
work. 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.

View File

@ -267,6 +267,18 @@ programmer
type = butterfly; type = butterfly;
; ;
programmer
id = "avr109";
desc = "Atmel AppNote AVR109 Boot Loader";
type = butterfly;
;
programmer
id = "avr911";
desc = "Atmel AppNote AVR911 AVROSP";
type = butterfly;
;
programmer programmer
id = "jtagmkII"; id = "jtagmkII";
desc = "Atmel JTAG ICE mkII"; desc = "Atmel JTAG ICE mkII";

View File

@ -1,6 +1,7 @@
/* /*
* avrdude - A Downloader/Uploader for AVR device programmers * avrdude - A Downloader/Uploader for AVR device programmers
* Copyright (C) 2003-2004 Theodore A. Roth <troth@openavr.org> * Copyright (C) 2003-2004 Theodore A. Roth <troth@openavr.org>
* Copyright (C) 2005 Joerg Wunsch <j@uriah.heep.sax.de>
* *
* This program is free software; you can redistribute it and/or modify * 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 * 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 * evaluation board. This board features a bootloader which uses a protocol
* very similar, but not identical, to the one described in application note * very similar, but not identical, to the one described in application note
* avr910. * 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(); 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_send(pgm, "\033\033\033\033", 4);
butterfly_drain(pgm, 0); butterfly_drain(pgm, 0);
@ -271,7 +283,7 @@ static int butterfly_initialize(PROGRAMMER * pgm, AVRPART * p)
if (c != 'Y') { if (c != 'Y') {
fprintf(stderr, fprintf(stderr,
"%s: error: buffered memory access not supported. Maybe it isn't\n"\ "%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); exit(1);
}; };
butterfly_recv(pgm, &c, 1); butterfly_recv(pgm, &c, 1);
@ -300,10 +312,11 @@ static int butterfly_initialize(PROGRAMMER * pgm, AVRPART * p)
fprintf(stderr,"\n"); fprintf(stderr,"\n");
if (!dev_supported) { if (!dev_supported) {
/* FIXME: if nothing matched, we should rather compare the device
signatures. */
fprintf(stderr, fprintf(stderr,
"%s: error: selected device is not supported by programmer: %s\n", "%s: error: selected device is not supported by programmer: %s\n",
progname, p->id); progname, p->id);
exit(1);
} }
/* Tell the programmer which part we selected. */ /* 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_send(pgm, buf, 2);
butterfly_vfy_cmd_sent(pgm, "select device"); butterfly_vfy_cmd_sent(pgm, "select device");
butterfly_enter_prog_mode(pgm); return dev_supported? 0: -1;
return 0;
} }
@ -325,7 +336,7 @@ static void butterfly_disable(PROGRAMMER * pgm)
{ {
no_show_func_info(); no_show_func_info();
/* Do nothing. */ butterfly_leave_prog_mode(pgm);
return; return;
} }
@ -335,7 +346,7 @@ static void butterfly_enable(PROGRAMMER * pgm)
{ {
no_show_func_info(); no_show_func_info();
/* Do nothing. */ butterfly_enter_prog_mode(pgm);
return; return;
} }
@ -346,7 +357,13 @@ static int butterfly_open(PROGRAMMER * pgm, char * port)
no_show_func_info(); no_show_func_info();
strcpy(pgm->port, port); 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 * drain any extraneous input
@ -361,8 +378,6 @@ static void butterfly_close(PROGRAMMER * pgm)
{ {
no_show_func_info(); no_show_func_info();
butterfly_leave_prog_mode(pgm);
/* "exit programmer" added by Martin Thomas 2/2004 */ /* "exit programmer" added by Martin Thomas 2/2004 */
butterfly_send(pgm, "E", 1); butterfly_send(pgm, "E", 1);
@ -401,24 +416,31 @@ static int butterfly_write_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
no_show_func_info(); 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; 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_send(pgm, cmd, size);
butterfly_vfy_cmd_sent(pgm, "write byte"); 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, static int butterfly_read_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
unsigned long addr, unsigned char * value) unsigned long addr, unsigned char * value)
{ {
unsigned char cmd;
no_show_func_info(); no_show_func_info();
if (strcmp(m->desc, "flash") == 0) { 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 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. */ /* Signature byte reads are always 3 bytes. */
static int butterfly_read_sig_bytes(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m) static int butterfly_read_sig_bytes(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m)
{ {
unsigned char tmp;
no_show_func_info(); no_show_func_info();
if (m->size < 3) { 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_send(pgm, "s", 1);
butterfly_recv(pgm, m->buf, 3); 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; return 3;
} }

View File

@ -129,9 +129,10 @@ from the contents of a file, while interactive mode is useful for
exploring memory contents, modifing individual bytes of eeprom, exploring memory contents, modifing individual bytes of eeprom,
programming fuse/lock bits, etc. 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 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 of simple programmers where the programming lines are directly
connected to the PC parallel port. Several pin configurations exist connected to the PC parallel port. Several pin configurations exist
for several variations of the PPI programmers, and AVRDUDE can be be 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 configuration file. All that's usually required for a new entry is to
tell AVRDUDE which pins to use for each programming function. 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 The STK500, JTAG ICE, avr910, and avr109/butterfly use the serial port to communicate with the PC.
and contains on-board logic to control the programming of the target The STK500, JTAG ICE, and avr910 contain on-board logic to control the programming of the target
device. The fundamental difference between the two types lies in the 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 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 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, 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 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 intented to allow on-chip debugging as well as memory programming, the
protocol is more sophisticated. protocol is more sophisticated.
(This protocol can also be run on top of USB, but AVRDUDE by now only (This protocol can also be run on top of USB.)
supports the RS-232-based option.)
Only the memory programming functionality of the JTAG ICE is supported Only the memory programming functionality of the JTAG ICE is supported
by AVRDUDE. by AVRDUDE.
@ -356,9 +360,15 @@ ABCmini Board, aka Dick Smith HOTCHIP
@itemx alf @itemx alf
Nightshade ALF-PgmAVR, http://nightshade.homeip.net/ Nightshade ALF-PgmAVR, http://nightshade.homeip.net/
@itemx avr109
Atmel AppNote AVR109 Boot Loader
@itemx avr910 @itemx avr910
Atmel Low Cost Serial Programmer Atmel Low Cost Serial Programmer
@itemx avr911
Atmel AppNote AVR911 AVROSP (an alias for avr109)
@itemx avrisp @itemx avrisp
Atmel AVR ISP 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, 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 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 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 @item -t
Tells AVRDUDE to enter the interactive ``terminal'' mode instead of up- Tells AVRDUDE to enter the interactive ``terminal'' mode instead of up-
@ -1037,7 +1047,7 @@ programmer
id = <id1> [, <id2> [, <id3>] ...] ; # <idN> are quoted strings id = <id1> [, <id2> [, <id3>] ...] ; # <idN> are quoted strings
desc = <description> ; # quoted string desc = <description> ; # quoted string
type = par | stk500 ; # programmer type type = par | stk500 ; # programmer type
baudrate = <num> ; # baudrate for avr910 baudrate = <num> ; # baudrate for serial ports
vcc = <num1> [, <num2> ... ] ; # pin number(s) vcc = <num1> [, <num2> ... ] ; # pin number(s)
reset = <num> ; # pin number reset = <num> ; # pin number
sck = <num> ; # pin number sck = <num> ; # 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} @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 @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 by an error caused by the programmer. Programmer of course meaning both the physical device, and the
person sitting at the keyboard. 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 @item
Problem: Updating the flash ROM from terminal mode does not work with the Problem: Updating the flash ROM from terminal mode does not work with the
JTAG ICE mkII. JTAG ICE mkII.