2001-01-19 02:46:50 +00:00
|
|
|
/*
|
2003-02-08 04:17:25 +00:00
|
|
|
* avrdude - A Downloader/Uploader for AVR device programmers
|
Mega-commit to bring in both, the STK500v2 support from Erik
Walthinsen, as well as JTAG ICE mkII support (by me).
Erik's submission has been cleaned up a little bit, mostly to add his
name and the current year to the copyright of the new file, remove
trailing white space before importing the files, and fix the minor
syntax errors in his avrdude.conf.in additions (missing semicolons).
The JTAG ICE mkII support should be considered alpha to beta quality
at this point. Few things are still to be done, like defering the
hfuse (OCDEN) tweaks until they are really required. Also, for
reasons not yet known, the target MCU doesn't start to run after
signing off from the ICE, it needs a power-cycle first (at least on my
STK500).
Note that for the JTAG ICE, I did change a few things in the internal
API. Notably I made the serial receive timeout configurable by the
backends via an exported variable (done in both the Posix and the
Win32 implementation), and I made the serial_recv() function return a
-1 instead of bailing out with exit(1) upon encountering a receive
timeout (currently only done in the Posix implementation). Both
measures together allow me to receive a datastreem from the ICE at 115
kbps on a somewhat lossy PCI multi-UART card that occasionally drops a
character. The JTAG ICE mkII protocol has enough of safety layers to
allow recovering from these events, but the previous code wasn't
prepared for any kind of recovery. The Win32 change for this still
has to be done, and the traditional drivers need to be converted to
exit(1) upon encountering a timeout (as they're now getting a -1
returned they didn't see before in that case).
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk/avrdude@451 81a1dc3b-b13d-400b-aceb-764788c761c2
2005-05-10 19:17:12 +00:00
|
|
|
* Copyright (C) 2000-2005 Brian S. Dean <bsd@bsdhome.com>
|
2021-12-16 21:02:35 +00:00
|
|
|
* Copyright Joerg Wunsch <j@uriah.heep.sax.de>
|
2001-01-19 02:46:50 +00:00
|
|
|
*
|
2003-02-06 19:08:33 +00:00
|
|
|
* 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
|
|
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
|
|
* (at your option) any later version.
|
2001-01-19 02:46:50 +00:00
|
|
|
*
|
2003-02-06 19:08:33 +00:00
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
2001-01-19 02:46:50 +00:00
|
|
|
*
|
2003-02-06 19:08:33 +00:00
|
|
|
* You should have received a copy of the GNU General Public License
|
2012-11-20 14:03:50 +00:00
|
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
2001-01-19 02:46:50 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
/* $Id$ */
|
|
|
|
|
|
|
|
/*
|
Mega-commit to bring in both, the STK500v2 support from Erik
Walthinsen, as well as JTAG ICE mkII support (by me).
Erik's submission has been cleaned up a little bit, mostly to add his
name and the current year to the copyright of the new file, remove
trailing white space before importing the files, and fix the minor
syntax errors in his avrdude.conf.in additions (missing semicolons).
The JTAG ICE mkII support should be considered alpha to beta quality
at this point. Few things are still to be done, like defering the
hfuse (OCDEN) tweaks until they are really required. Also, for
reasons not yet known, the target MCU doesn't start to run after
signing off from the ICE, it needs a power-cycle first (at least on my
STK500).
Note that for the JTAG ICE, I did change a few things in the internal
API. Notably I made the serial receive timeout configurable by the
backends via an exported variable (done in both the Posix and the
Win32 implementation), and I made the serial_recv() function return a
-1 instead of bailing out with exit(1) upon encountering a receive
timeout (currently only done in the Posix implementation). Both
measures together allow me to receive a datastreem from the ICE at 115
kbps on a somewhat lossy PCI multi-UART card that occasionally drops a
character. The JTAG ICE mkII protocol has enough of safety layers to
allow recovering from these events, but the previous code wasn't
prepared for any kind of recovery. The Win32 change for this still
has to be done, and the traditional drivers need to be converted to
exit(1) upon encountering a timeout (as they're now getting a -1
returned they didn't see before in that case).
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk/avrdude@451 81a1dc3b-b13d-400b-aceb-764788c761c2
2005-05-10 19:17:12 +00:00
|
|
|
* Code to program an Atmel AVR device through one of the supported
|
|
|
|
* programmers.
|
2001-01-19 02:46:50 +00:00
|
|
|
*
|
2003-02-21 21:19:56 +00:00
|
|
|
* For parallel port connected programmers, the pin definitions can be
|
|
|
|
* changed via a config file. See the config file for instructions on
|
|
|
|
* how to add a programmer definition.
|
2022-05-24 15:56:11 +00:00
|
|
|
*
|
2001-01-19 02:46:50 +00:00
|
|
|
*/
|
|
|
|
|
2003-02-14 20:34:03 +00:00
|
|
|
#include "ac_cfg.h"
|
|
|
|
|
2001-01-19 02:46:50 +00:00
|
|
|
#include <stdio.h>
|
2001-09-19 17:04:25 +00:00
|
|
|
#include <stdlib.h>
|
2022-01-03 22:20:31 +00:00
|
|
|
#include <whereami.h>
|
2014-05-18 08:41:46 +00:00
|
|
|
#include <stdarg.h>
|
2001-01-19 02:46:50 +00:00
|
|
|
#include <errno.h>
|
|
|
|
#include <fcntl.h>
|
|
|
|
#include <limits.h>
|
|
|
|
#include <string.h>
|
2001-01-26 20:34:08 +00:00
|
|
|
#include <time.h>
|
2001-01-19 02:46:50 +00:00
|
|
|
#include <unistd.h>
|
2001-09-19 17:04:25 +00:00
|
|
|
#include <ctype.h>
|
2003-02-22 16:45:13 +00:00
|
|
|
#include <sys/types.h>
|
|
|
|
#include <sys/stat.h>
|
2003-07-30 23:01:52 +00:00
|
|
|
#include <sys/time.h>
|
2001-01-19 02:46:50 +00:00
|
|
|
|
2014-05-19 10:01:59 +00:00
|
|
|
#include "avrdude.h"
|
|
|
|
#include "libavrdude.h"
|
2022-10-17 14:44:55 +00:00
|
|
|
#include "config.h"
|
2001-01-19 02:46:50 +00:00
|
|
|
#include "term.h"
|
2022-06-28 19:14:29 +00:00
|
|
|
#include "developer_opts.h"
|
Introduce a new option, -U, for performing memory operions. Its
argument is a 4 field string (fields seperated by colons) which
indicate what memory type to operate on, what operation to perform is
(read, write, or verify), the filename to read from, write to, or
verify against, and an optional file format field. Multple -U options
can be specified to operate on more than one memory at a time with a
single invocation. For example, to update both the flash and the
eeprom at the same time one can now specify the following:
avrdude -p -e -U flash:w:main.hex:i -U eeprom:w:eeprom.hex:i
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk/avrdude@341 81a1dc3b-b13d-400b-aceb-764788c761c2
2003-08-21 04:52:36 +00:00
|
|
|
|
2003-03-06 19:18:40 +00:00
|
|
|
/* Get VERSION from ac_cfg.h */
|
|
|
|
char * version = VERSION;
|
2001-01-19 02:46:50 +00:00
|
|
|
|
|
|
|
char * progname;
|
|
|
|
char progbuf[PATH_MAX]; /* temporary buffer of spaces the same
|
|
|
|
length as progname; used for lining up
|
|
|
|
multiline messages */
|
|
|
|
|
2022-10-17 14:44:55 +00:00
|
|
|
int avrdude_message(int msglvl, const char *format, ...)
|
2014-05-18 08:41:46 +00:00
|
|
|
{
|
2014-06-13 20:07:40 +00:00
|
|
|
int rc = 0;
|
2014-05-18 08:41:46 +00:00
|
|
|
va_list ap;
|
2014-06-13 20:07:40 +00:00
|
|
|
if (verbose >= msglvl) {
|
|
|
|
va_start(ap, format);
|
|
|
|
rc = vfprintf(stderr, format, ap);
|
|
|
|
va_end(ap);
|
|
|
|
}
|
2014-05-18 08:41:46 +00:00
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
2022-10-17 14:44:55 +00:00
|
|
|
static const char *avrdude_message_type(int msglvl) {
|
|
|
|
switch(msglvl) {
|
|
|
|
case MSG_EXT_ERROR: return "OS error";
|
|
|
|
case MSG_ERROR: return "error";
|
|
|
|
case MSG_WARNING: return "warning";
|
|
|
|
case MSG_INFO: return "info";
|
|
|
|
case MSG_NOTICE: return "notice";
|
|
|
|
case MSG_NOTICE2: return "notice2";
|
|
|
|
case MSG_DEBUG: return "debug";
|
|
|
|
case MSG_TRACE: return "trace";
|
|
|
|
case MSG_TRACE2: return "trace2";
|
|
|
|
default: return "unknown msglvl";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-10-23 20:56:45 +00:00
|
|
|
int avrdude_message2(FILE *fp, int lno, const char *file, const char *func, int msgmode, int msglvl, const char *format, ...) {
|
2022-10-17 14:44:55 +00:00
|
|
|
int rc = 0;
|
|
|
|
va_list ap;
|
|
|
|
|
2022-10-23 20:56:45 +00:00
|
|
|
if(msglvl <= MSG_ERROR) // Serious error? Freee progress bars (if any)
|
|
|
|
report_progress(1, -1, NULL);
|
|
|
|
|
2022-10-17 14:44:55 +00:00
|
|
|
if(msgmode & MSG2_FLUSH) {
|
|
|
|
fflush(stdout);
|
|
|
|
fflush(stderr);
|
|
|
|
}
|
2022-11-01 18:06:52 +00:00
|
|
|
|
2022-10-23 20:56:45 +00:00
|
|
|
// Reduce effective verbosity level by number of -q above one when printing to stderr
|
|
|
|
if ((quell_progress < 2 || fp != stderr? verbose: verbose+1-quell_progress) >= msglvl) {
|
2022-10-17 14:44:55 +00:00
|
|
|
if(msgmode & MSG2_PROGNAME) {
|
2022-10-23 20:56:45 +00:00
|
|
|
fprintf(fp, "%s", progname);
|
2022-10-17 14:44:55 +00:00
|
|
|
if(verbose >= MSG_NOTICE && (msgmode & MSG2_FUNCTION))
|
2022-10-23 20:56:45 +00:00
|
|
|
fprintf(fp, " %s()", func);
|
|
|
|
if(verbose >= MSG_DEBUG && (msgmode & MSG2_FILELINE)) {
|
|
|
|
const char *pr = strrchr(file, '/'); // only print basename
|
|
|
|
#if defined (WIN32)
|
|
|
|
if(!pr)
|
|
|
|
pr = strrchr(file, '\\');
|
|
|
|
#endif
|
|
|
|
pr = pr? pr+1: file;
|
|
|
|
fprintf(fp, " [%s:%d]", pr, lno);
|
|
|
|
}
|
2022-10-17 14:44:55 +00:00
|
|
|
if(msgmode & MSG2_TYPE)
|
2022-10-23 20:56:45 +00:00
|
|
|
fprintf(fp, " %s", avrdude_message_type(msglvl));
|
|
|
|
fprintf(fp, ": ");
|
2022-10-17 14:44:55 +00:00
|
|
|
} else if(msgmode & MSG2_INDENT1) {
|
2022-10-23 20:56:45 +00:00
|
|
|
fprintf(fp, "%*s", (int) strlen(progname)+1, "");
|
2022-10-17 14:44:55 +00:00
|
|
|
} else if(msgmode & MSG2_INDENT2) {
|
2022-10-23 20:56:45 +00:00
|
|
|
fprintf(fp, "%*s", (int) strlen(progname)+2, "");
|
2022-10-17 14:44:55 +00:00
|
|
|
}
|
|
|
|
va_start(ap, format);
|
2022-10-23 20:56:45 +00:00
|
|
|
rc = vfprintf(fp, format, ap);
|
2022-10-17 14:44:55 +00:00
|
|
|
va_end(ap);
|
|
|
|
}
|
|
|
|
|
|
|
|
if(msgmode & MSG2_FLUSH)
|
2022-10-23 20:56:45 +00:00
|
|
|
fflush(fp);
|
2022-10-17 14:44:55 +00:00
|
|
|
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
2014-05-16 15:52:25 +00:00
|
|
|
|
2007-01-29 20:41:47 +00:00
|
|
|
struct list_walk_cookie
|
|
|
|
{
|
|
|
|
FILE *f;
|
|
|
|
const char *prefix;
|
|
|
|
};
|
|
|
|
|
2012-01-17 20:56:37 +00:00
|
|
|
static LISTID updates = NULL;
|
Introduce a new option, -U, for performing memory operions. Its
argument is a 4 field string (fields seperated by colons) which
indicate what memory type to operate on, what operation to perform is
(read, write, or verify), the filename to read from, write to, or
verify against, and an optional file format field. Multple -U options
can be specified to operate on more than one memory at a time with a
single invocation. For example, to update both the flash and the
eeprom at the same time one can now specify the following:
avrdude -p -e -U flash:w:main.hex:i -U eeprom:w:eeprom.hex:i
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk/avrdude@341 81a1dc3b-b13d-400b-aceb-764788c761c2
2003-08-21 04:52:36 +00:00
|
|
|
|
2012-01-17 20:56:37 +00:00
|
|
|
static LISTID extended_params = NULL;
|
2007-11-06 19:42:16 +00:00
|
|
|
|
2012-01-17 20:56:37 +00:00
|
|
|
static LISTID additional_config_files = NULL;
|
2012-01-10 18:07:19 +00:00
|
|
|
|
main.c, pgm.c, pgm.h: Add setup and teardown hooks to the programmer
definition. If present, call the setup hook immediately after finding
the respective programmer object, and schedule the teardown hook to be
called upon exit. This allows the programmer implementation to
dynamically allocate private programmer data.
avr910.c, butterfly.c, jtagmkI.c, jtagmkII.c, stk500v2.c, usbasp.c,
usbtiny.c: Convert static programmer data into dynamically allocated
data.
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk/avrdude@764 81a1dc3b-b13d-400b-aceb-764788c761c2
2007-11-07 20:36:12 +00:00
|
|
|
static PROGRAMMER * pgm;
|
|
|
|
|
2002-08-01 02:06:48 +00:00
|
|
|
/*
|
|
|
|
* global options
|
|
|
|
*/
|
2022-11-01 18:06:52 +00:00
|
|
|
int verbose; // Verbose output
|
|
|
|
int quell_progress; // Quell progress report and un-verbose output
|
|
|
|
int ovsigck; // 1 = override sig check, 0 = don't
|
|
|
|
const char *partdesc; // Part id
|
2001-09-19 17:04:25 +00:00
|
|
|
|
2014-05-18 08:41:46 +00:00
|
|
|
|
2001-01-19 02:46:50 +00:00
|
|
|
/*
|
|
|
|
* usage message
|
|
|
|
*/
|
2007-01-24 22:43:46 +00:00
|
|
|
static void usage(void)
|
2001-01-19 02:46:50 +00:00
|
|
|
{
|
2022-10-17 14:44:55 +00:00
|
|
|
msg_error(
|
|
|
|
"Usage: %s [options]\n"
|
|
|
|
"Options:\n"
|
|
|
|
" -p <partno> Specify AVR device\n"
|
|
|
|
" -b <baudrate> Override RS-232 baud rate\n"
|
2022-10-23 21:26:07 +00:00
|
|
|
" -B <bitclock> Specify bit clock period (us)\n"
|
2022-10-17 14:44:55 +00:00
|
|
|
" -C <config-file> Specify location of configuration file\n"
|
|
|
|
" -c <programmer> Specify programmer type\n"
|
|
|
|
" -A Disable trailing-0xff removal from file and AVR read\n"
|
|
|
|
" -D Disable auto erase for flash memory; implies -A\n"
|
|
|
|
" -i <delay> ISP Clock Delay [in microseconds]\n"
|
|
|
|
" -P <port> Specify connection port\n"
|
2022-10-23 21:26:07 +00:00
|
|
|
" -F Override invalid signature or initialisation check\n"
|
2022-10-17 14:44:55 +00:00
|
|
|
" -e Perform a chip erase\n"
|
|
|
|
" -O Perform RC oscillator calibration (see AVR053)\n"
|
|
|
|
" -U <memtype>:r|w|v:<filename>[:format]\n"
|
|
|
|
" Memory operation specification\n"
|
|
|
|
" Multiple -U options are allowed, each request\n"
|
|
|
|
" is performed in the order specified\n"
|
|
|
|
" -n Do not write anything to the device\n"
|
|
|
|
" -V Do not verify\n"
|
|
|
|
" -t Enter terminal mode\n"
|
|
|
|
" -E <exitspec>[,<exitspec>] List programmer exit specifications\n"
|
|
|
|
" -x <extended_param> Pass <extended_param> to programmer\n"
|
|
|
|
" -v Verbose output; -v -v for more\n"
|
|
|
|
" -q Quell progress output; -q -q for less\n"
|
|
|
|
" -l logfile Use logfile rather than stderr for diagnostics\n"
|
|
|
|
" -? Display this usage\n"
|
|
|
|
"\navrdude version %s, URL: <https://github.com/avrdudes/avrdude>\n",
|
2022-09-14 21:57:16 +00:00
|
|
|
progname, version);
|
2001-01-19 02:46:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-09-14 21:57:16 +00:00
|
|
|
static char *via_prog_modes(int pm) {
|
|
|
|
static char type[1024];
|
|
|
|
|
|
|
|
strcpy(type, "?");
|
|
|
|
if(pm & PM_SPM)
|
|
|
|
strcat(type, ", bootloader");
|
|
|
|
if(pm & PM_TPI)
|
|
|
|
strcat(type, ", TPI");
|
|
|
|
if(pm & PM_ISP)
|
|
|
|
strcat(type, ", ISP");
|
|
|
|
if(pm & PM_PDI)
|
|
|
|
strcat(type, ", PDI");
|
|
|
|
if(pm & PM_UPDI)
|
|
|
|
strcat(type, ", UPDI");
|
|
|
|
if(pm & PM_HVSP)
|
|
|
|
strcat(type, ", HVSP");
|
|
|
|
if(pm & PM_HVPP)
|
|
|
|
strcat(type, ", HVPP");
|
|
|
|
if(pm & PM_debugWIRE)
|
|
|
|
strcat(type, ", debugWIRE");
|
|
|
|
if(pm & PM_JTAG)
|
|
|
|
strcat(type, ", JTAG");
|
2022-09-20 17:36:46 +00:00
|
|
|
if(pm & PM_JTAGmkI)
|
|
|
|
strcat(type, ", JTAGmkI");
|
|
|
|
if(pm & PM_XMEGAJTAG)
|
|
|
|
strcat(type, ", XMEGAJTAG");
|
|
|
|
if(pm & PM_AVR32JTAG)
|
|
|
|
strcat(type, ", AVR32JTAG");
|
2022-09-14 21:57:16 +00:00
|
|
|
if(pm & PM_aWire)
|
|
|
|
strcat(type, ", aWire");
|
|
|
|
|
|
|
|
return type + (type[1] == 0? 0: 3);
|
2007-01-29 20:41:47 +00:00
|
|
|
}
|
|
|
|
|
2022-09-20 20:37:49 +00:00
|
|
|
|
|
|
|
// Potentially shorten copy of prog description if it's the suggested mode
|
|
|
|
static void pmshorten(char *desc, const char *modes) {
|
|
|
|
struct { const char *end, *mode; } pairs[] = {
|
|
|
|
{" in parallel programming mode", "HVPP"},
|
|
|
|
{" in PP mode", "HVPP"},
|
|
|
|
{" in high-voltage serial programming mode", "HVSP"},
|
|
|
|
{" in HVSP mode", "HVSP"},
|
|
|
|
{" in ISP mode", "ISP"},
|
|
|
|
{" in debugWire mode", "debugWIRE"},
|
|
|
|
{" in AVR32 mode", "aWire"},
|
|
|
|
{" in PDI mode", "PDI"},
|
|
|
|
{" in UPDI mode", "UPDI"},
|
|
|
|
{" in JTAG mode", "JTAG"},
|
|
|
|
{" in JTAG mode", "JTAGmkI"},
|
|
|
|
{" in JTAG mode", "XMEGAJTAG"},
|
|
|
|
{" in JTAG mode", "AVR32JTAG"},
|
2022-09-20 20:55:29 +00:00
|
|
|
{" for bootloader", "bootloader"},
|
2022-09-20 20:37:49 +00:00
|
|
|
};
|
|
|
|
size_t len = strlen(desc);
|
|
|
|
|
|
|
|
for(size_t i=0; i<sizeof pairs/sizeof*pairs; i++) {
|
|
|
|
size_t elen = strlen(pairs[i].end);
|
2022-09-20 21:03:40 +00:00
|
|
|
if(len > elen && strcasecmp(desc+len-elen, pairs[i].end) == 0 && strcmp(modes, pairs[i].mode) == 0) {
|
2022-09-20 20:37:49 +00:00
|
|
|
desc[len-elen] = 0;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-09-14 21:57:16 +00:00
|
|
|
static void list_programmers(FILE *f, const char *prefix, LISTID programmers, int pm) {
|
|
|
|
LNODEID ln1;
|
|
|
|
LNODEID ln2;
|
|
|
|
PROGRAMMER *pgm;
|
2022-09-16 18:09:35 +00:00
|
|
|
int maxlen=0, len;
|
2022-09-14 21:57:16 +00:00
|
|
|
|
|
|
|
sort_programmers(programmers);
|
|
|
|
|
2022-09-16 18:09:35 +00:00
|
|
|
// Compute max length of programmer names
|
|
|
|
for(ln1 = lfirst(programmers); ln1; ln1 = lnext(ln1)) {
|
2022-09-14 21:57:16 +00:00
|
|
|
pgm = ldata(ln1);
|
2022-09-16 18:09:35 +00:00
|
|
|
for(ln2=lfirst(pgm->id); ln2; ln2=lnext(ln2))
|
|
|
|
if(!pm || !pgm->prog_modes || (pm & pgm->prog_modes)) {
|
|
|
|
const char *id = ldata(ln2);
|
|
|
|
if(*id == 0 || *id == '.')
|
|
|
|
continue;
|
|
|
|
if((len = strlen(id)) > maxlen)
|
|
|
|
maxlen = len;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
for(ln1 = lfirst(programmers); ln1; ln1 = lnext(ln1)) {
|
|
|
|
pgm = ldata(ln1);
|
|
|
|
for(ln2=lfirst(pgm->id); ln2; ln2=lnext(ln2)) {
|
2022-09-14 21:57:16 +00:00
|
|
|
// List programmer if pm or prog_modes uninitialised or if they are compatible otherwise
|
|
|
|
if(!pm || !pgm->prog_modes || (pm & pgm->prog_modes)) {
|
|
|
|
const char *id = ldata(ln2);
|
2022-09-20 20:37:49 +00:00
|
|
|
char *desc = cfg_strdup("list_programmers()", pgm->desc);
|
|
|
|
const char *modes = via_prog_modes(pm & pgm->prog_modes);
|
|
|
|
|
|
|
|
if(pm != ~0)
|
|
|
|
pmshorten(desc, modes);
|
|
|
|
|
2022-09-14 21:57:16 +00:00
|
|
|
if(*id == 0 || *id == '.')
|
|
|
|
continue;
|
|
|
|
if(verbose)
|
2022-09-20 20:37:49 +00:00
|
|
|
fprintf(f, "%s%-*s = %-30s [%s:%d]", prefix, maxlen, id, desc, pgm->config_file, pgm->lineno);
|
2022-09-14 21:57:16 +00:00
|
|
|
else
|
2022-09-20 20:37:49 +00:00
|
|
|
fprintf(f, "%s%-*s = %-s", prefix, maxlen, id, desc);
|
2022-09-14 21:57:16 +00:00
|
|
|
if(pm != ~0)
|
2022-09-20 20:37:49 +00:00
|
|
|
fprintf(f, " via %s", modes);
|
2022-09-14 21:57:16 +00:00
|
|
|
fprintf(f, "\n");
|
2022-09-20 20:37:49 +00:00
|
|
|
|
|
|
|
free(desc);
|
2022-09-14 21:57:16 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2007-01-29 20:41:47 +00:00
|
|
|
}
|
|
|
|
|
2012-01-31 17:03:43 +00:00
|
|
|
static void list_programmer_types_callback(const char *name, const char *desc,
|
|
|
|
void *cookie)
|
|
|
|
{
|
|
|
|
struct list_walk_cookie *c = (struct list_walk_cookie *)cookie;
|
2022-10-17 14:44:55 +00:00
|
|
|
fprintf(c->f, "%s%-16s = %-s\n", c->prefix, name, desc);
|
2012-01-31 17:03:43 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void list_programmer_types(FILE * f, const char *prefix)
|
|
|
|
{
|
|
|
|
struct list_walk_cookie c;
|
|
|
|
|
|
|
|
c.f = f;
|
|
|
|
c.prefix = prefix;
|
|
|
|
|
|
|
|
walk_programmer_types(list_programmer_types_callback, &c);
|
|
|
|
}
|
|
|
|
|
2007-01-29 20:41:47 +00:00
|
|
|
|
2022-09-14 21:57:16 +00:00
|
|
|
static void list_parts(FILE *f, const char *prefix, LISTID avrparts, int pm) {
|
|
|
|
LNODEID ln1;
|
|
|
|
AVRPART *p;
|
2022-09-16 18:09:35 +00:00
|
|
|
int maxlen=0, len;
|
2022-09-14 21:57:16 +00:00
|
|
|
|
|
|
|
sort_avrparts(avrparts);
|
|
|
|
|
2022-09-16 18:09:35 +00:00
|
|
|
// Compute max length of part names
|
|
|
|
for(ln1 = lfirst(avrparts); ln1; ln1 = lnext(ln1)) {
|
|
|
|
p = ldata(ln1);
|
|
|
|
// List part if pm or prog_modes uninitialised or if they are compatible otherwise
|
|
|
|
if(!pm || !p->prog_modes || (pm & p->prog_modes)) {
|
2022-10-17 14:44:55 +00:00
|
|
|
if(verbose < 2 && p->id[0] == '.') // hide ids starting with '.'
|
2022-09-16 18:09:35 +00:00
|
|
|
continue;
|
|
|
|
if((len = strlen(p->id)) > maxlen)
|
|
|
|
maxlen = len;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
for(ln1 = lfirst(avrparts); ln1; ln1 = lnext(ln1)) {
|
2022-09-14 21:57:16 +00:00
|
|
|
p = ldata(ln1);
|
|
|
|
// List part if pm or prog_modes uninitialised or if they are compatible otherwise
|
|
|
|
if(!pm || !p->prog_modes || (pm & p->prog_modes)) {
|
2022-10-17 14:44:55 +00:00
|
|
|
if(verbose < 2 && p->id[0] == '.') // hide ids starting with '.'
|
2022-09-14 21:57:16 +00:00
|
|
|
continue;
|
2022-09-16 18:09:35 +00:00
|
|
|
if(verbose)
|
|
|
|
fprintf(f, "%s%-*s = %-18s [%s:%d]", prefix, maxlen, p->id, p->desc, p->config_file, p->lineno);
|
2022-09-14 21:57:16 +00:00
|
|
|
else
|
2022-09-16 18:09:35 +00:00
|
|
|
fprintf(f, "%s%-*s = %s", prefix, maxlen, p->id, p->desc);
|
2022-09-14 21:57:16 +00:00
|
|
|
if(pm != ~0)
|
|
|
|
fprintf(f, " via %s", via_prog_modes(pm & p->prog_modes));
|
|
|
|
fprintf(f, "\n");
|
2011-12-16 20:44:07 +00:00
|
|
|
}
|
2022-09-14 21:57:16 +00:00
|
|
|
}
|
2007-01-29 20:41:47 +00:00
|
|
|
}
|
|
|
|
|
main.c, pgm.c, pgm.h: Add setup and teardown hooks to the programmer
definition. If present, call the setup hook immediately after finding
the respective programmer object, and schedule the teardown hook to be
called upon exit. This allows the programmer implementation to
dynamically allocate private programmer data.
avr910.c, butterfly.c, jtagmkI.c, jtagmkII.c, stk500v2.c, usbasp.c,
usbtiny.c: Convert static programmer data into dynamically allocated
data.
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk/avrdude@764 81a1dc3b-b13d-400b-aceb-764788c761c2
2007-11-07 20:36:12 +00:00
|
|
|
static void exithook(void)
|
|
|
|
{
|
|
|
|
if (pgm->teardown)
|
|
|
|
pgm->teardown(pgm);
|
|
|
|
}
|
|
|
|
|
2012-01-17 20:56:37 +00:00
|
|
|
static void cleanup_main(void)
|
|
|
|
{
|
|
|
|
if (updates) {
|
2012-01-31 17:03:43 +00:00
|
|
|
ldestroy_cb(updates, (void(*)(void*))free_update);
|
2012-01-17 20:56:37 +00:00
|
|
|
updates = NULL;
|
|
|
|
}
|
|
|
|
if (extended_params) {
|
|
|
|
ldestroy(extended_params);
|
|
|
|
extended_params = NULL;
|
|
|
|
}
|
|
|
|
if (additional_config_files) {
|
|
|
|
ldestroy(additional_config_files);
|
|
|
|
additional_config_files = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
cleanup_config();
|
|
|
|
}
|
|
|
|
|
2022-01-04 22:10:14 +00:00
|
|
|
static void replace_backslashes(char *s)
|
|
|
|
{
|
|
|
|
// Replace all backslashes with forward slashes
|
Enable stdin verification and display correct number of bytes written/verified
Counting the number of bytes written to a memory and/or verified is not
trivial owing to potential holes in the input file and to potential trailing
0xff bytes in flash memory that are not written per default (but see -A). The
new function memstats(), which is best called just after an input file has
been read into mem->buf/mem->tags, computes the right number of bytes written
and allows easy computation of the number of bytes verified.
This commit also changes the strategy for the default verification after
writing to a chip memory, so that the input file only needs reading once thus
enabling successful verification of stdin input files.
Other, minor changes:
- Improving the grammar of AVRDUDE output, eg, 1 byte written instead of
1 bytes written
- Better description of the input file structure in terms of its sections,
the interval it spans, the number of pages, the number of padding bytes
in pages, and the number of actually cut off trailing 0xff bytes for flash
- Printing <stdin> or <stdout> instead of - in the -U routines
- Option -V no longer needs to be specified before option -U in order to work
As an aside this commit also provides useful helper functions for printing
plural(), inname(), outname() and interval() all of which return strings fit
for printing.
$ avrdude -qp ATmega2560 -c usbtiny -U blink-mega2560+lext-test.hex
avrdude: AVR device initialized and ready to accept instructions
avrdude: Device signature = 0x1e9801 (probably m2560)
avrdude: NOTE: "flash" memory has been specified, an erase cycle will be performed
To disable this feature, specify the -D option.
avrdude: erasing chip
avrdude: input file blink-mega2560+lext-test.hex auto detected as Intel Hex
avrdude: reading input file blink-mega2560+lext-test.hex for flash
with 1346 bytes in 4 sections within [0, 0x3106d]
using 7 pages and 446 pad bytes
avrdude: writing 1346 bytes flash ...
avrdude: 1346 bytes of flash written
avrdude: verifying flash memory against blink-mega2560+lext-test.hex
avrdude: 1346 bytes of flash verified
avrdude done. Thank you.
$ avrdude -qp ATmega328P -c usb-bub-ii -U sketch-ending-in-ff.hex
avrdude: AVR device initialized and ready to accept instructions
avrdude: Device signature = 0x1e950f (probably m328p)
avrdude: NOTE: "flash" memory has been specified, an erase cycle will be performed
To disable this feature, specify the -D option.
avrdude: erasing chip
avrdude: input file sketch-ending-in-ff.hex auto detected as Intel Hex
avrdude: reading input file sketch-ending-in-ff.hex for flash
with 2160 bytes in 1 section within [0, 0x888]
using 17 pages and 16 pad bytes, cutting off 25 trailing 0xff bytes
avrdude: writing 2160 bytes flash ...
avrdude: 2160 bytes of flash written
avrdude: verifying flash memory against sketch-ending-in-ff.hex
avrdude: 2185 bytes of flash verified
avrdude done. Thank you.
$ echo "Hello, world..." | avrdude -qp ATmega328P -c ... -U eeprom:w:-:r
avrdude: AVR device initialized and ready to accept instructions
avrdude: Device signature = 0x1e950f (probably m328p)
avrdude: reading input file <stdin> for eeprom
avrdude: writing 16 bytes eeprom ...
avrdude: 16 bytes of eeprom written
avrdude: verifying eeprom memory against <stdin>
avrdude: 16 bytes of eeprom verified
avrdude done. Thank you.
2022-08-02 22:26:01 +00:00
|
|
|
for (size_t i = 0; i < strlen(s); i++) {
|
2022-01-04 22:10:14 +00:00
|
|
|
if (s[i] == '\\') {
|
|
|
|
s[i] = '/';
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-08-11 23:28:54 +00:00
|
|
|
// Return 2 if string is * or starts with */, 1 if string contains /, 0 otherwise
|
2022-11-01 18:06:52 +00:00
|
|
|
static int dev_opt(const char *str) {
|
2022-08-11 23:28:54 +00:00
|
|
|
return
|
|
|
|
!str? 0:
|
|
|
|
!strcmp(str, "*") || !strncmp(str, "*/", 2)? 2:
|
|
|
|
!!strchr(str, '/');
|
|
|
|
}
|
|
|
|
|
2022-01-04 22:10:14 +00:00
|
|
|
|
2022-11-01 18:06:52 +00:00
|
|
|
static void programmer_not_found(const char *programmer) {
|
2022-10-17 14:44:55 +00:00
|
|
|
msg_error("\n");
|
2022-09-21 14:38:05 +00:00
|
|
|
if(programmer && *programmer)
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_error("cannot find programmer id %s\n", programmer);
|
|
|
|
else {
|
|
|
|
pmsg_error("no programmer has been specified on the command line or in the\n");
|
|
|
|
imsg_error("config file(s); specify one using the -c option and try again\n");
|
|
|
|
}
|
2022-09-21 14:38:05 +00:00
|
|
|
|
2022-10-17 14:44:55 +00:00
|
|
|
msg_error("\nValid programmers are:\n");
|
2022-09-21 14:38:05 +00:00
|
|
|
list_programmers(stderr, " ", programmers, ~0);
|
2022-10-17 14:44:55 +00:00
|
|
|
msg_error("\n");
|
2022-09-21 14:38:05 +00:00
|
|
|
}
|
|
|
|
|
2022-11-01 18:06:52 +00:00
|
|
|
static void part_not_found(const char *partdesc) {
|
2022-10-17 14:44:55 +00:00
|
|
|
msg_error("\n");
|
2022-09-21 14:38:05 +00:00
|
|
|
if(partdesc && *partdesc)
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_error("AVR part %s not found\n", partdesc);
|
2022-09-21 14:38:05 +00:00
|
|
|
else
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_error("no AVR part has been specified; use -p part\n");
|
2022-09-21 14:38:05 +00:00
|
|
|
|
2022-10-17 14:44:55 +00:00
|
|
|
msg_error("\nValid parts are:\n");
|
2022-09-21 14:38:05 +00:00
|
|
|
list_parts(stderr, " ", part_list, ~0);
|
2022-10-17 14:44:55 +00:00
|
|
|
msg_error("\n");
|
2022-09-21 14:38:05 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-10-23 20:52:54 +00:00
|
|
|
#if !defined(WIN32)
|
|
|
|
// Safely concatenate dir/file into dst that has size n
|
|
|
|
static char *concatpath(char *dst, char *dir, char *file, size_t n) {
|
|
|
|
// Dir or file empty?
|
|
|
|
if(!dir || !*dir || !file || !*file)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
size_t len = strlen(dir);
|
|
|
|
|
|
|
|
// Insufficient space?
|
|
|
|
if(len + (dir[len-1] != '/') + strlen(file) > n-1)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
if(dst != dir)
|
|
|
|
strcpy(dst, dir);
|
|
|
|
|
|
|
|
if(dst[len-1] != '/')
|
|
|
|
strcat(dst, "/");
|
|
|
|
|
|
|
|
strcat(dst, file);
|
|
|
|
|
|
|
|
return dst;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
2001-01-19 02:46:50 +00:00
|
|
|
/*
|
|
|
|
* main routine
|
|
|
|
*/
|
2001-10-13 03:13:13 +00:00
|
|
|
int main(int argc, char * argv [])
|
2001-01-19 02:46:50 +00:00
|
|
|
{
|
|
|
|
int rc; /* general return code checking */
|
|
|
|
int exitrc; /* exit code for main() */
|
|
|
|
int i; /* general loop counter */
|
|
|
|
int ch; /* options flag */
|
|
|
|
int len; /* length for various strings */
|
2001-10-14 23:17:26 +00:00
|
|
|
struct avrpart * p; /* which avr part we are programming */
|
2001-11-21 02:46:55 +00:00
|
|
|
AVRMEM * sig; /* signature data */
|
2003-02-22 16:45:13 +00:00
|
|
|
struct stat sb;
|
Introduce a new option, -U, for performing memory operions. Its
argument is a 4 field string (fields seperated by colons) which
indicate what memory type to operate on, what operation to perform is
(read, write, or verify), the filename to read from, write to, or
verify against, and an optional file format field. Multple -U options
can be specified to operate on more than one memory at a time with a
single invocation. For example, to update both the flash and the
eeprom at the same time one can now specify the following:
avrdude -p -e -U flash:w:main.hex:i -U eeprom:w:eeprom.hex:i
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk/avrdude@341 81a1dc3b-b13d-400b-aceb-764788c761c2
2003-08-21 04:52:36 +00:00
|
|
|
UPDATE * upd;
|
|
|
|
LNODEID * ln;
|
2007-01-24 22:43:46 +00:00
|
|
|
|
2001-01-19 02:46:50 +00:00
|
|
|
|
|
|
|
/* options / operating mode variables */
|
|
|
|
int erase; /* 1=erase chip, 0=don't */
|
2006-10-09 14:34:24 +00:00
|
|
|
int calibrate; /* 1=calibrate RC oscillator, 0=don't */
|
2002-11-30 14:09:12 +00:00
|
|
|
char * port; /* device port (/dev/xxx) */
|
2001-01-19 02:46:50 +00:00
|
|
|
int terminal; /* 1=enter terminal mode, 0=don't */
|
Use const in PROGRAMMER function arguments where appropriate
In order to get meaningful const properties for the PROGRAMMER, AVRPART and
AVRMEM arguments, some code needed to be moved around, otherwise a network of
"tainted" assignments risked rendering nothing const:
- Change void (*enable)(PROGRAMMER *pgm) to void (*enable)(PROGRAMMER *pgm,
const AVRPART *p); this allows changes in the PROGRAMMER structure after
the part is known. For example, use TPI, UPDI, PDI functions in that
programmer appropriate to the part. This used to be done later in the
process, eg, in the initialize() function, which "taints" all other
programmer functions wrt const and sometimes requires other finessing with
flags etc. Much clearer with the modified enable() interface.
- Move TPI initpgm-type code from initialize() to enable() --- note that
initpgm() does not have the info at the time when it is called whether or
not TPI is required
- buspirate.c: move pgm->flag to PDATA(pgm)->flag (so legitimate
modification of the flag does not change PROGRAMMER structure)
- Move AVRPART_INIT_SMC and AVRPART_WRITE bits from the flags field in
AVRPART to jtagmkII.c's private data flags32 fiels as FLAGS32_INIT_SMC and
FLAGS32_WRITE bits
- Move the xbeeResetPin component to private data in stk500.c as this is
needed by xbee when it saddles on the stk500 code (previously, the flags
component of the part was re-dedicated to this)
- Change the way the "chained" private data are used in jtag3.c whilst
keeping the PROGRAMMER structure read-only otherwise
- In stk500v2.c move the STK600 pgm update from stk500v2_initialize() to
stk500v2_enable() so the former keeps the PROGRAMMER structure read-only
(for const assertion).
- In usbasp change the code from changing PROGRAMMER functions late to
dispatching to TPI or regular SPI protocol functions at runtime; reason
being the decision whether to use TPI protocol is done at run-time
depending on the capability of the attached programmer
Also fixes Issue #1071, the treatment of default eecr value.
2022-08-17 15:05:28 +00:00
|
|
|
const char *exitspecs; /* exit specs string from command line */
|
2022-11-10 18:20:13 +00:00
|
|
|
const char *programmer; /* programmer id */
|
2003-02-22 16:45:13 +00:00
|
|
|
char sys_config[PATH_MAX]; /* system wide config file */
|
|
|
|
char usr_config[PATH_MAX]; /* per-user config file */
|
2022-01-03 22:20:31 +00:00
|
|
|
char executable_abspath[PATH_MAX]; /* absolute path to avrdude executable */
|
|
|
|
char executable_dirpath[PATH_MAX]; /* absolute path to folder with executable */
|
|
|
|
bool executable_abspath_found = false; /* absolute path to executable found */
|
|
|
|
bool sys_config_found = false; /* 'avrdude.conf' file found */
|
2002-12-12 03:59:28 +00:00
|
|
|
char * e; /* for strtol() error checking */
|
2004-05-19 23:00:38 +00:00
|
|
|
int baudrate; /* override default programmer baud rate */
|
Mega-commit to bring in both, the STK500v2 support from Erik
Walthinsen, as well as JTAG ICE mkII support (by me).
Erik's submission has been cleaned up a little bit, mostly to add his
name and the current year to the copyright of the new file, remove
trailing white space before importing the files, and fix the minor
syntax errors in his avrdude.conf.in additions (missing semicolons).
The JTAG ICE mkII support should be considered alpha to beta quality
at this point. Few things are still to be done, like defering the
hfuse (OCDEN) tweaks until they are really required. Also, for
reasons not yet known, the target MCU doesn't start to run after
signing off from the ICE, it needs a power-cycle first (at least on my
STK500).
Note that for the JTAG ICE, I did change a few things in the internal
API. Notably I made the serial receive timeout configurable by the
backends via an exported variable (done in both the Posix and the
Win32 implementation), and I made the serial_recv() function return a
-1 instead of bailing out with exit(1) upon encountering a receive
timeout (currently only done in the Posix implementation). Both
measures together allow me to receive a datastreem from the ICE at 115
kbps on a somewhat lossy PCI multi-UART card that occasionally drops a
character. The JTAG ICE mkII protocol has enough of safety layers to
allow recovering from these events, but the previous code wasn't
prepared for any kind of recovery. The Win32 change for this still
has to be done, and the traditional drivers need to be converted to
exit(1) upon encountering a timeout (as they're now getting a -1
returned they didn't see before in that case).
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk/avrdude@451 81a1dc3b-b13d-400b-aceb-764788c761c2
2005-05-10 19:17:12 +00:00
|
|
|
double bitclock; /* Specify programmer bit clock (JTAG ICE) */
|
2006-08-17 15:06:20 +00:00
|
|
|
int ispdelay; /* Specify the delay for ISP clock */
|
2008-07-29 21:26:55 +00:00
|
|
|
int init_ok; /* Device initialization worked well */
|
2010-01-13 12:44:54 +00:00
|
|
|
int is_open; /* Device open succeeded */
|
2013-05-16 09:11:32 +00:00
|
|
|
char * logfile; /* Use logfile rather than stderr for diagnostics */
|
Enable stdin verification and display correct number of bytes written/verified
Counting the number of bytes written to a memory and/or verified is not
trivial owing to potential holes in the input file and to potential trailing
0xff bytes in flash memory that are not written per default (but see -A). The
new function memstats(), which is best called just after an input file has
been read into mem->buf/mem->tags, computes the right number of bytes written
and allows easy computation of the number of bytes verified.
This commit also changes the strategy for the default verification after
writing to a chip memory, so that the input file only needs reading once thus
enabling successful verification of stdin input files.
Other, minor changes:
- Improving the grammar of AVRDUDE output, eg, 1 byte written instead of
1 bytes written
- Better description of the input file structure in terms of its sections,
the interval it spans, the number of pages, the number of padding bytes
in pages, and the number of actually cut off trailing 0xff bytes for flash
- Printing <stdin> or <stdout> instead of - in the -U routines
- Option -V no longer needs to be specified before option -U in order to work
As an aside this commit also provides useful helper functions for printing
plural(), inname(), outname() and interval() all of which return strings fit
for printing.
$ avrdude -qp ATmega2560 -c usbtiny -U blink-mega2560+lext-test.hex
avrdude: AVR device initialized and ready to accept instructions
avrdude: Device signature = 0x1e9801 (probably m2560)
avrdude: NOTE: "flash" memory has been specified, an erase cycle will be performed
To disable this feature, specify the -D option.
avrdude: erasing chip
avrdude: input file blink-mega2560+lext-test.hex auto detected as Intel Hex
avrdude: reading input file blink-mega2560+lext-test.hex for flash
with 1346 bytes in 4 sections within [0, 0x3106d]
using 7 pages and 446 pad bytes
avrdude: writing 1346 bytes flash ...
avrdude: 1346 bytes of flash written
avrdude: verifying flash memory against blink-mega2560+lext-test.hex
avrdude: 1346 bytes of flash verified
avrdude done. Thank you.
$ avrdude -qp ATmega328P -c usb-bub-ii -U sketch-ending-in-ff.hex
avrdude: AVR device initialized and ready to accept instructions
avrdude: Device signature = 0x1e950f (probably m328p)
avrdude: NOTE: "flash" memory has been specified, an erase cycle will be performed
To disable this feature, specify the -D option.
avrdude: erasing chip
avrdude: input file sketch-ending-in-ff.hex auto detected as Intel Hex
avrdude: reading input file sketch-ending-in-ff.hex for flash
with 2160 bytes in 1 section within [0, 0x888]
using 17 pages and 16 pad bytes, cutting off 25 trailing 0xff bytes
avrdude: writing 2160 bytes flash ...
avrdude: 2160 bytes of flash written
avrdude: verifying flash memory against sketch-ending-in-ff.hex
avrdude: 2185 bytes of flash verified
avrdude done. Thank you.
$ echo "Hello, world..." | avrdude -qp ATmega328P -c ... -U eeprom:w:-:r
avrdude: AVR device initialized and ready to accept instructions
avrdude: Device signature = 0x1e950f (probably m328p)
avrdude: reading input file <stdin> for eeprom
avrdude: writing 16 bytes eeprom ...
avrdude: 16 bytes of eeprom written
avrdude: verifying eeprom memory against <stdin>
avrdude: 16 bytes of eeprom verified
avrdude done. Thank you.
2022-08-02 22:26:01 +00:00
|
|
|
enum updateflags uflags = UF_AUTO_ERASE | UF_VERIFY; /* Flags for do_op() */
|
2005-09-21 00:20:32 +00:00
|
|
|
|
2022-01-12 19:41:52 +00:00
|
|
|
#ifdef _MSC_VER
|
|
|
|
_set_printf_count_output(1);
|
|
|
|
#endif
|
|
|
|
|
2007-10-29 22:46:45 +00:00
|
|
|
/*
|
|
|
|
* Set line buffering for file descriptors so we see stdout and stderr
|
|
|
|
* properly interleaved.
|
|
|
|
*/
|
|
|
|
setvbuf(stdout, (char*)NULL, _IOLBF, 0);
|
|
|
|
setvbuf(stderr, (char*)NULL, _IOLBF, 0);
|
|
|
|
|
2022-01-04 21:45:47 +00:00
|
|
|
sys_config[0] = '\0';
|
|
|
|
|
2022-10-17 14:44:55 +00:00
|
|
|
progname = strrchr(argv[0], '/');
|
2005-02-10 16:34:55 +00:00
|
|
|
|
2022-01-07 12:15:55 +00:00
|
|
|
#if defined (WIN32)
|
2004-06-24 11:05:07 +00:00
|
|
|
/* take care of backslash as dir sep in W32 */
|
2022-10-17 14:44:55 +00:00
|
|
|
if (!progname)
|
|
|
|
progname = strrchr(argv[0], '\\');
|
2022-01-07 12:15:55 +00:00
|
|
|
#endif /* WIN32 */
|
2005-02-10 16:34:55 +00:00
|
|
|
|
2001-10-14 23:17:26 +00:00
|
|
|
if (progname)
|
|
|
|
progname++;
|
|
|
|
else
|
|
|
|
progname = argv[0];
|
2001-01-19 02:46:50 +00:00
|
|
|
|
2022-10-17 14:44:55 +00:00
|
|
|
// Remove trailing .exe
|
|
|
|
if(strlen(progname) > 4 && strcmp(progname+strlen(progname)-4, ".exe") == 0) {
|
|
|
|
progname = cfg_strdup("main()", progname); // Don't write to argv[0]
|
|
|
|
progname[strlen(progname)-4] = 0;
|
|
|
|
}
|
|
|
|
|
2022-08-09 20:45:04 +00:00
|
|
|
default_programmer = "";
|
|
|
|
default_parallel = "";
|
|
|
|
default_serial = "";
|
|
|
|
default_spi = "";
|
|
|
|
default_bitclock = 0.0;
|
2003-02-21 18:46:51 +00:00
|
|
|
|
2001-10-14 23:17:26 +00:00
|
|
|
init_config();
|
|
|
|
|
2012-01-17 20:56:37 +00:00
|
|
|
atexit(cleanup_main);
|
|
|
|
|
Introduce a new option, -U, for performing memory operions. Its
argument is a 4 field string (fields seperated by colons) which
indicate what memory type to operate on, what operation to perform is
(read, write, or verify), the filename to read from, write to, or
verify against, and an optional file format field. Multple -U options
can be specified to operate on more than one memory at a time with a
single invocation. For example, to update both the flash and the
eeprom at the same time one can now specify the following:
avrdude -p -e -U flash:w:main.hex:i -U eeprom:w:eeprom.hex:i
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk/avrdude@341 81a1dc3b-b13d-400b-aceb-764788c761c2
2003-08-21 04:52:36 +00:00
|
|
|
updates = lcreat(NULL, 0);
|
|
|
|
if (updates == NULL) {
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_error("cannot initialize updater list\n");
|
Introduce a new option, -U, for performing memory operions. Its
argument is a 4 field string (fields seperated by colons) which
indicate what memory type to operate on, what operation to perform is
(read, write, or verify), the filename to read from, write to, or
verify against, and an optional file format field. Multple -U options
can be specified to operate on more than one memory at a time with a
single invocation. For example, to update both the flash and the
eeprom at the same time one can now specify the following:
avrdude -p -e -U flash:w:main.hex:i -U eeprom:w:eeprom.hex:i
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk/avrdude@341 81a1dc3b-b13d-400b-aceb-764788c761c2
2003-08-21 04:52:36 +00:00
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
2007-11-06 19:42:16 +00:00
|
|
|
extended_params = lcreat(NULL, 0);
|
|
|
|
if (extended_params == NULL) {
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_error("cannot initialize extended parameter list\n");
|
2007-11-06 19:42:16 +00:00
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
2012-01-10 18:07:19 +00:00
|
|
|
additional_config_files = lcreat(NULL, 0);
|
|
|
|
if (additional_config_files == NULL) {
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_error("cannot initialize additional config files list\n");
|
2012-01-10 18:07:19 +00:00
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
2001-10-14 23:17:26 +00:00
|
|
|
partdesc = NULL;
|
2012-01-30 17:08:48 +00:00
|
|
|
port = NULL;
|
2001-09-19 17:04:25 +00:00
|
|
|
erase = 0;
|
2006-10-09 14:34:24 +00:00
|
|
|
calibrate = 0;
|
2001-09-19 17:04:25 +00:00
|
|
|
p = NULL;
|
|
|
|
ovsigck = 0;
|
|
|
|
terminal = 0;
|
2003-07-29 22:08:21 +00:00
|
|
|
quell_progress = 0;
|
2001-09-21 03:27:20 +00:00
|
|
|
exitspecs = NULL;
|
2001-10-14 23:17:26 +00:00
|
|
|
pgm = NULL;
|
2022-11-10 18:20:13 +00:00
|
|
|
programmer = "";
|
2001-10-13 03:12:52 +00:00
|
|
|
verbose = 0;
|
2004-05-19 23:00:38 +00:00
|
|
|
baudrate = 0;
|
Mega-commit to bring in both, the STK500v2 support from Erik
Walthinsen, as well as JTAG ICE mkII support (by me).
Erik's submission has been cleaned up a little bit, mostly to add his
name and the current year to the copyright of the new file, remove
trailing white space before importing the files, and fix the minor
syntax errors in his avrdude.conf.in additions (missing semicolons).
The JTAG ICE mkII support should be considered alpha to beta quality
at this point. Few things are still to be done, like defering the
hfuse (OCDEN) tweaks until they are really required. Also, for
reasons not yet known, the target MCU doesn't start to run after
signing off from the ICE, it needs a power-cycle first (at least on my
STK500).
Note that for the JTAG ICE, I did change a few things in the internal
API. Notably I made the serial receive timeout configurable by the
backends via an exported variable (done in both the Posix and the
Win32 implementation), and I made the serial_recv() function return a
-1 instead of bailing out with exit(1) upon encountering a receive
timeout (currently only done in the Posix implementation). Both
measures together allow me to receive a datastreem from the ICE at 115
kbps on a somewhat lossy PCI multi-UART card that occasionally drops a
character. The JTAG ICE mkII protocol has enough of safety layers to
allow recovering from these events, but the previous code wasn't
prepared for any kind of recovery. The Win32 change for this still
has to be done, and the traditional drivers need to be converted to
exit(1) upon encountering a timeout (as they're now getting a -1
returned they didn't see before in that case).
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk/avrdude@451 81a1dc3b-b13d-400b-aceb-764788c761c2
2005-05-10 19:17:12 +00:00
|
|
|
bitclock = 0.0;
|
2006-08-17 15:06:20 +00:00
|
|
|
ispdelay = 0;
|
2010-01-13 12:44:54 +00:00
|
|
|
is_open = 0;
|
2013-05-16 09:11:32 +00:00
|
|
|
logfile = NULL;
|
2007-11-06 19:42:16 +00:00
|
|
|
|
2001-01-19 02:46:50 +00:00
|
|
|
len = strlen(progname) + 2;
|
|
|
|
for (i=0; i<len; i++)
|
|
|
|
progbuf[i] = ' ';
|
|
|
|
progbuf[i] = 0;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* check for no arguments
|
|
|
|
*/
|
|
|
|
if (argc == 1) {
|
|
|
|
usage();
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* process command line arguments
|
|
|
|
*/
|
2022-04-28 16:29:06 +00:00
|
|
|
while ((ch = getopt(argc,argv,"?Ab:B:c:C:DeE:Fi:l:np:OP:qstU:uvVx:yY:")) != -1) {
|
2001-01-19 02:46:50 +00:00
|
|
|
|
|
|
|
switch (ch) {
|
2004-05-19 23:00:38 +00:00
|
|
|
case 'b': /* override default programmer baud rate */
|
|
|
|
baudrate = strtol(optarg, &e, 0);
|
|
|
|
if ((e == optarg) || (*e != 0)) {
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_error("invalid baud rate specified '%s'\n", optarg);
|
2004-05-19 23:00:38 +00:00
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
Mega-commit to bring in both, the STK500v2 support from Erik
Walthinsen, as well as JTAG ICE mkII support (by me).
Erik's submission has been cleaned up a little bit, mostly to add his
name and the current year to the copyright of the new file, remove
trailing white space before importing the files, and fix the minor
syntax errors in his avrdude.conf.in additions (missing semicolons).
The JTAG ICE mkII support should be considered alpha to beta quality
at this point. Few things are still to be done, like defering the
hfuse (OCDEN) tweaks until they are really required. Also, for
reasons not yet known, the target MCU doesn't start to run after
signing off from the ICE, it needs a power-cycle first (at least on my
STK500).
Note that for the JTAG ICE, I did change a few things in the internal
API. Notably I made the serial receive timeout configurable by the
backends via an exported variable (done in both the Posix and the
Win32 implementation), and I made the serial_recv() function return a
-1 instead of bailing out with exit(1) upon encountering a receive
timeout (currently only done in the Posix implementation). Both
measures together allow me to receive a datastreem from the ICE at 115
kbps on a somewhat lossy PCI multi-UART card that occasionally drops a
character. The JTAG ICE mkII protocol has enough of safety layers to
allow recovering from these events, but the previous code wasn't
prepared for any kind of recovery. The Win32 change for this still
has to be done, and the traditional drivers need to be converted to
exit(1) upon encountering a timeout (as they're now getting a -1
returned they didn't see before in that case).
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk/avrdude@451 81a1dc3b-b13d-400b-aceb-764788c761c2
2005-05-10 19:17:12 +00:00
|
|
|
case 'B': /* specify JTAG ICE bit clock period */
|
|
|
|
bitclock = strtod(optarg, &e);
|
2014-11-23 21:49:56 +00:00
|
|
|
if (*e != 0) {
|
|
|
|
/* trailing unit of measure present */
|
|
|
|
int suffixlen = strlen(e);
|
|
|
|
switch (suffixlen) {
|
|
|
|
case 2:
|
|
|
|
if ((e[0] != 'h' && e[0] != 'H') || e[1] != 'z')
|
|
|
|
bitclock = 0.0;
|
|
|
|
else
|
|
|
|
/* convert from Hz to microseconds */
|
|
|
|
bitclock = 1E6 / bitclock;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 3:
|
|
|
|
if ((e[1] != 'h' && e[1] != 'H') || e[2] != 'z')
|
|
|
|
bitclock = 0.0;
|
|
|
|
else {
|
|
|
|
switch (e[0]) {
|
|
|
|
case 'M':
|
|
|
|
case 'm': /* no Millihertz here :) */
|
|
|
|
bitclock = 1.0 / bitclock;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 'k':
|
|
|
|
bitclock = 1E3 / bitclock;
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
bitclock = 0.0;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
bitclock = 0.0;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (bitclock == 0.0)
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_error("invalid bit clock unit of measure '%s'\n", e);
|
2014-11-23 21:49:56 +00:00
|
|
|
}
|
|
|
|
if ((e == optarg) || bitclock == 0.0) {
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_error("invalid bit clock period specified '%s'\n", optarg);
|
Mega-commit to bring in both, the STK500v2 support from Erik
Walthinsen, as well as JTAG ICE mkII support (by me).
Erik's submission has been cleaned up a little bit, mostly to add his
name and the current year to the copyright of the new file, remove
trailing white space before importing the files, and fix the minor
syntax errors in his avrdude.conf.in additions (missing semicolons).
The JTAG ICE mkII support should be considered alpha to beta quality
at this point. Few things are still to be done, like defering the
hfuse (OCDEN) tweaks until they are really required. Also, for
reasons not yet known, the target MCU doesn't start to run after
signing off from the ICE, it needs a power-cycle first (at least on my
STK500).
Note that for the JTAG ICE, I did change a few things in the internal
API. Notably I made the serial receive timeout configurable by the
backends via an exported variable (done in both the Posix and the
Win32 implementation), and I made the serial_recv() function return a
-1 instead of bailing out with exit(1) upon encountering a receive
timeout (currently only done in the Posix implementation). Both
measures together allow me to receive a datastreem from the ICE at 115
kbps on a somewhat lossy PCI multi-UART card that occasionally drops a
character. The JTAG ICE mkII protocol has enough of safety layers to
allow recovering from these events, but the previous code wasn't
prepared for any kind of recovery. The Win32 change for this still
has to be done, and the traditional drivers need to be converted to
exit(1) upon encountering a timeout (as they're now getting a -1
returned they didn't see before in that case).
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk/avrdude@451 81a1dc3b-b13d-400b-aceb-764788c761c2
2005-05-10 19:17:12 +00:00
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2006-08-17 15:06:20 +00:00
|
|
|
case 'i': /* specify isp clock delay */
|
|
|
|
ispdelay = strtol(optarg, &e,10);
|
|
|
|
if ((e == optarg) || (*e != 0) || ispdelay == 0) {
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_error("invalid isp clock delay specified '%s'\n", optarg);
|
2006-08-17 15:06:20 +00:00
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2003-02-21 21:07:43 +00:00
|
|
|
case 'c': /* programmer id */
|
|
|
|
programmer = optarg;
|
2001-09-19 17:04:25 +00:00
|
|
|
break;
|
|
|
|
|
2003-02-22 16:45:13 +00:00
|
|
|
case 'C': /* system wide configuration file */
|
2012-01-10 18:07:19 +00:00
|
|
|
if (optarg[0] == '+') {
|
|
|
|
ladd(additional_config_files, optarg+1);
|
|
|
|
} else {
|
|
|
|
strncpy(sys_config, optarg, PATH_MAX);
|
|
|
|
sys_config[PATH_MAX-1] = 0;
|
|
|
|
}
|
2001-09-19 17:04:25 +00:00
|
|
|
break;
|
|
|
|
|
2003-08-29 23:17:32 +00:00
|
|
|
case 'D': /* disable auto erase */
|
2012-05-04 10:02:30 +00:00
|
|
|
uflags &= ~UF_AUTO_ERASE;
|
2022-04-28 16:29:06 +00:00
|
|
|
/* fall through */
|
|
|
|
|
|
|
|
case 'A': /* explicit disabling of trailing-0xff removal */
|
2022-04-28 16:26:09 +00:00
|
|
|
disable_trailing_ff_removal();
|
2003-08-29 23:17:32 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case 'e': /* perform a chip erase */
|
|
|
|
erase = 1;
|
2012-05-04 10:02:30 +00:00
|
|
|
uflags &= ~UF_AUTO_ERASE;
|
2003-08-29 23:17:32 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case 'E':
|
|
|
|
exitspecs = optarg;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 'F': /* override invalid signature check */
|
|
|
|
ovsigck = 1;
|
|
|
|
break;
|
|
|
|
|
2013-05-16 09:11:32 +00:00
|
|
|
case 'l':
|
|
|
|
logfile = optarg;
|
|
|
|
break;
|
|
|
|
|
2001-01-19 02:46:50 +00:00
|
|
|
case 'n':
|
2012-05-04 10:02:30 +00:00
|
|
|
uflags |= UF_NOWRITE;
|
2001-01-19 02:46:50 +00:00
|
|
|
break;
|
|
|
|
|
2006-10-09 14:34:24 +00:00
|
|
|
case 'O': /* perform RC oscillator calibration */
|
|
|
|
calibrate = 1;
|
|
|
|
break;
|
|
|
|
|
2001-01-19 02:46:50 +00:00
|
|
|
case 'p' : /* specify AVR part */
|
2001-10-14 23:17:26 +00:00
|
|
|
partdesc = optarg;
|
2001-01-19 02:46:50 +00:00
|
|
|
break;
|
|
|
|
|
2003-08-29 23:17:32 +00:00
|
|
|
case 'P':
|
|
|
|
port = optarg;
|
2003-04-19 23:06:01 +00:00
|
|
|
break;
|
|
|
|
|
2003-08-29 23:17:32 +00:00
|
|
|
case 'q' : /* Quell progress output */
|
2005-09-16 21:52:42 +00:00
|
|
|
quell_progress++ ;
|
2001-01-19 02:46:50 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case 't': /* enter terminal mode */
|
|
|
|
terminal = 1;
|
|
|
|
break;
|
|
|
|
|
2022-07-18 15:13:10 +00:00
|
|
|
case 's':
|
2022-03-20 20:49:20 +00:00
|
|
|
case 'u':
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_error("\"safemode\" feature no longer supported\n");
|
2022-03-20 20:49:20 +00:00
|
|
|
break;
|
|
|
|
|
Introduce a new option, -U, for performing memory operions. Its
argument is a 4 field string (fields seperated by colons) which
indicate what memory type to operate on, what operation to perform is
(read, write, or verify), the filename to read from, write to, or
verify against, and an optional file format field. Multple -U options
can be specified to operate on more than one memory at a time with a
single invocation. For example, to update both the flash and the
eeprom at the same time one can now specify the following:
avrdude -p -e -U flash:w:main.hex:i -U eeprom:w:eeprom.hex:i
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk/avrdude@341 81a1dc3b-b13d-400b-aceb-764788c761c2
2003-08-21 04:52:36 +00:00
|
|
|
case 'U':
|
|
|
|
upd = parse_op(optarg);
|
|
|
|
if (upd == NULL) {
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_error("unable to parse update operation '%s'\n", optarg);
|
Introduce a new option, -U, for performing memory operions. Its
argument is a 4 field string (fields seperated by colons) which
indicate what memory type to operate on, what operation to perform is
(read, write, or verify), the filename to read from, write to, or
verify against, and an optional file format field. Multple -U options
can be specified to operate on more than one memory at a time with a
single invocation. For example, to update both the flash and the
eeprom at the same time one can now specify the following:
avrdude -p -e -U flash:w:main.hex:i -U eeprom:w:eeprom.hex:i
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk/avrdude@341 81a1dc3b-b13d-400b-aceb-764788c761c2
2003-08-21 04:52:36 +00:00
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
ladd(updates, upd);
|
|
|
|
break;
|
|
|
|
|
2001-10-13 03:12:52 +00:00
|
|
|
case 'v':
|
|
|
|
verbose++;
|
2001-01-19 02:46:50 +00:00
|
|
|
break;
|
|
|
|
|
2002-10-29 01:59:02 +00:00
|
|
|
case 'V':
|
Enable stdin verification and display correct number of bytes written/verified
Counting the number of bytes written to a memory and/or verified is not
trivial owing to potential holes in the input file and to potential trailing
0xff bytes in flash memory that are not written per default (but see -A). The
new function memstats(), which is best called just after an input file has
been read into mem->buf/mem->tags, computes the right number of bytes written
and allows easy computation of the number of bytes verified.
This commit also changes the strategy for the default verification after
writing to a chip memory, so that the input file only needs reading once thus
enabling successful verification of stdin input files.
Other, minor changes:
- Improving the grammar of AVRDUDE output, eg, 1 byte written instead of
1 bytes written
- Better description of the input file structure in terms of its sections,
the interval it spans, the number of pages, the number of padding bytes
in pages, and the number of actually cut off trailing 0xff bytes for flash
- Printing <stdin> or <stdout> instead of - in the -U routines
- Option -V no longer needs to be specified before option -U in order to work
As an aside this commit also provides useful helper functions for printing
plural(), inname(), outname() and interval() all of which return strings fit
for printing.
$ avrdude -qp ATmega2560 -c usbtiny -U blink-mega2560+lext-test.hex
avrdude: AVR device initialized and ready to accept instructions
avrdude: Device signature = 0x1e9801 (probably m2560)
avrdude: NOTE: "flash" memory has been specified, an erase cycle will be performed
To disable this feature, specify the -D option.
avrdude: erasing chip
avrdude: input file blink-mega2560+lext-test.hex auto detected as Intel Hex
avrdude: reading input file blink-mega2560+lext-test.hex for flash
with 1346 bytes in 4 sections within [0, 0x3106d]
using 7 pages and 446 pad bytes
avrdude: writing 1346 bytes flash ...
avrdude: 1346 bytes of flash written
avrdude: verifying flash memory against blink-mega2560+lext-test.hex
avrdude: 1346 bytes of flash verified
avrdude done. Thank you.
$ avrdude -qp ATmega328P -c usb-bub-ii -U sketch-ending-in-ff.hex
avrdude: AVR device initialized and ready to accept instructions
avrdude: Device signature = 0x1e950f (probably m328p)
avrdude: NOTE: "flash" memory has been specified, an erase cycle will be performed
To disable this feature, specify the -D option.
avrdude: erasing chip
avrdude: input file sketch-ending-in-ff.hex auto detected as Intel Hex
avrdude: reading input file sketch-ending-in-ff.hex for flash
with 2160 bytes in 1 section within [0, 0x888]
using 17 pages and 16 pad bytes, cutting off 25 trailing 0xff bytes
avrdude: writing 2160 bytes flash ...
avrdude: 2160 bytes of flash written
avrdude: verifying flash memory against sketch-ending-in-ff.hex
avrdude: 2185 bytes of flash verified
avrdude done. Thank you.
$ echo "Hello, world..." | avrdude -qp ATmega328P -c ... -U eeprom:w:-:r
avrdude: AVR device initialized and ready to accept instructions
avrdude: Device signature = 0x1e950f (probably m328p)
avrdude: reading input file <stdin> for eeprom
avrdude: writing 16 bytes eeprom ...
avrdude: 16 bytes of eeprom written
avrdude: verifying eeprom memory against <stdin>
avrdude: 16 bytes of eeprom verified
avrdude done. Thank you.
2022-08-02 22:26:01 +00:00
|
|
|
uflags &= ~UF_VERIFY;
|
2002-10-29 01:59:02 +00:00
|
|
|
break;
|
|
|
|
|
2007-11-06 19:42:16 +00:00
|
|
|
case 'x':
|
|
|
|
ladd(extended_params, optarg);
|
|
|
|
break;
|
|
|
|
|
2002-08-01 01:00:03 +00:00
|
|
|
case 'y':
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_error("erase cycle counter no longer supported\n");
|
2002-08-01 01:00:03 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case 'Y':
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_error("erase cycle counter no longer supported\n");
|
2002-08-01 01:00:03 +00:00
|
|
|
break;
|
|
|
|
|
2001-01-19 02:46:50 +00:00
|
|
|
case '?': /* help */
|
|
|
|
usage();
|
|
|
|
exit(0);
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_error("invalid option -%c\n\n", ch);
|
2001-01-19 02:46:50 +00:00
|
|
|
usage();
|
|
|
|
exit(1);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2013-05-16 09:11:32 +00:00
|
|
|
if (logfile != NULL) {
|
|
|
|
FILE *newstderr = freopen(logfile, "w", stderr);
|
|
|
|
if (newstderr == NULL) {
|
|
|
|
/* Help! There's no stderr to complain to anymore now. */
|
2022-10-17 14:44:55 +00:00
|
|
|
printf("Cannot create logfile %s: %s\n", logfile, strerror(errno));
|
2013-05-16 09:11:32 +00:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
}
|
2003-08-29 23:17:32 +00:00
|
|
|
|
2022-01-04 21:45:47 +00:00
|
|
|
/* search for system configuration file unless -C conffile was given */
|
|
|
|
if (strlen(sys_config) == 0) {
|
|
|
|
/*
|
|
|
|
* EXECUTABLE ABSPATH
|
|
|
|
* ------------------
|
|
|
|
* Determine the absolute path to avrdude executable. This will be used to
|
|
|
|
* locate the 'avrdude.conf' file later.
|
|
|
|
*/
|
|
|
|
int executable_dirpath_len;
|
|
|
|
int executable_abspath_len = wai_getExecutablePath(
|
|
|
|
executable_abspath,
|
|
|
|
PATH_MAX,
|
|
|
|
&executable_dirpath_len
|
|
|
|
);
|
|
|
|
if (
|
|
|
|
(executable_abspath_len != -1) &&
|
|
|
|
(executable_abspath_len != 0) &&
|
|
|
|
(executable_dirpath_len != -1) &&
|
|
|
|
(executable_dirpath_len != 0)
|
|
|
|
) {
|
|
|
|
// All requirements satisfied, executable path was found
|
|
|
|
executable_abspath_found = true;
|
|
|
|
|
|
|
|
// Make sure the string is null terminated
|
|
|
|
executable_abspath[executable_abspath_len] = '\0';
|
|
|
|
|
2022-01-04 22:10:14 +00:00
|
|
|
replace_backslashes(executable_abspath);
|
2022-01-04 21:45:47 +00:00
|
|
|
|
|
|
|
// Define 'executable_dirpath' to be the path to the parent folder of the
|
|
|
|
// executable.
|
|
|
|
strcpy(executable_dirpath, executable_abspath);
|
|
|
|
executable_dirpath[executable_dirpath_len] = '\0';
|
|
|
|
|
|
|
|
// Debug output
|
2022-10-17 14:44:55 +00:00
|
|
|
msg_debug("executable_abspath = %s\n", executable_abspath);
|
|
|
|
msg_debug("executable_abspath_len = %i\n", executable_abspath_len);
|
|
|
|
msg_debug("executable_dirpath = %s\n", executable_dirpath);
|
|
|
|
msg_debug("executable_dirpath_len = %i\n", executable_dirpath_len);
|
2022-01-04 21:45:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* SYSTEM CONFIG
|
|
|
|
* -------------
|
|
|
|
* Determine the location of 'avrdude.conf'. Check in this order:
|
|
|
|
* 1. <dirpath of executable>/../etc/avrdude.conf
|
|
|
|
* 2. <dirpath of executable>/avrdude.conf
|
|
|
|
* 3. CONFIG_DIR/avrdude.conf
|
|
|
|
*
|
|
|
|
* When found, write the result into the 'sys_config' variable.
|
|
|
|
*/
|
|
|
|
if (executable_abspath_found) {
|
|
|
|
// 1. Check <dirpath of executable>/../etc/avrdude.conf
|
|
|
|
strcpy(sys_config, executable_dirpath);
|
|
|
|
sys_config[PATH_MAX - 1] = '\0';
|
|
|
|
i = strlen(sys_config);
|
|
|
|
if (i && (sys_config[i - 1] != '/'))
|
|
|
|
strcat(sys_config, "/");
|
2022-01-04 22:03:47 +00:00
|
|
|
strcat(sys_config, "../etc/" SYSTEM_CONF_FILE);
|
2022-01-04 21:45:47 +00:00
|
|
|
sys_config[PATH_MAX - 1] = '\0';
|
|
|
|
if (access(sys_config, F_OK) == 0) {
|
|
|
|
sys_config_found = true;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
// 2. Check <dirpath of executable>/avrdude.conf
|
|
|
|
strcpy(sys_config, executable_dirpath);
|
|
|
|
sys_config[PATH_MAX - 1] = '\0';
|
|
|
|
i = strlen(sys_config);
|
|
|
|
if (i && (sys_config[i - 1] != '/'))
|
|
|
|
strcat(sys_config, "/");
|
2022-01-04 22:03:47 +00:00
|
|
|
strcat(sys_config, SYSTEM_CONF_FILE);
|
2022-01-04 21:45:47 +00:00
|
|
|
sys_config[PATH_MAX - 1] = '\0';
|
|
|
|
if (access(sys_config, F_OK) == 0) {
|
|
|
|
sys_config_found = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (!sys_config_found) {
|
|
|
|
// 3. Check CONFIG_DIR/avrdude.conf
|
2022-01-07 12:15:55 +00:00
|
|
|
#if defined(WIN32)
|
2022-01-04 21:45:47 +00:00
|
|
|
win_sys_config_set(sys_config);
|
|
|
|
#else
|
|
|
|
strcpy(sys_config, CONFIG_DIR);
|
|
|
|
i = strlen(sys_config);
|
|
|
|
if (i && (sys_config[i - 1] != '/'))
|
|
|
|
strcat(sys_config, "/");
|
2022-01-04 22:03:47 +00:00
|
|
|
strcat(sys_config, SYSTEM_CONF_FILE);
|
2022-01-04 21:45:47 +00:00
|
|
|
#endif
|
|
|
|
if (access(sys_config, F_OK) == 0) {
|
|
|
|
sys_config_found = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// Debug output
|
2022-10-17 14:44:55 +00:00
|
|
|
msg_debug("sys_config = %s\n", sys_config);
|
|
|
|
msg_debug("sys_config_found = %s\n", sys_config_found ? "true" : "false");
|
|
|
|
msg_debug("\n");
|
2022-01-04 21:45:47 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* USER CONFIG
|
|
|
|
* -----------
|
2022-01-04 22:03:47 +00:00
|
|
|
* Determine the location of '.avrduderc'.
|
2022-01-04 21:45:47 +00:00
|
|
|
*/
|
2022-01-07 12:15:55 +00:00
|
|
|
#if defined(WIN32)
|
2022-01-04 21:45:47 +00:00
|
|
|
win_usr_config_set(usr_config);
|
|
|
|
#else
|
|
|
|
usr_config[0] = 0;
|
2022-10-23 20:52:54 +00:00
|
|
|
if(!concatpath(usr_config, getenv("XDG_CONFIG_HOME"), XDG_USER_CONF_FILE, sizeof usr_config))
|
|
|
|
concatpath(usr_config, getenv("HOME"), ".config/" XDG_USER_CONF_FILE, sizeof usr_config);
|
|
|
|
if(stat(usr_config, &sb) < 0 || (sb.st_mode & S_IFREG) == 0)
|
|
|
|
concatpath(usr_config, getenv("HOME"), USER_CONF_FILE, sizeof usr_config);
|
2022-01-04 21:45:47 +00:00
|
|
|
#endif
|
|
|
|
|
2022-07-13 10:38:43 +00:00
|
|
|
if (quell_progress == 0)
|
|
|
|
terminal_setup_update_progress();
|
2003-07-29 22:08:21 +00:00
|
|
|
|
2014-06-13 20:07:40 +00:00
|
|
|
/*
|
|
|
|
* Print out an identifying string so folks can tell what version
|
|
|
|
* they are running
|
|
|
|
*/
|
2022-10-17 14:44:55 +00:00
|
|
|
msg_notice("\n");
|
|
|
|
pmsg_notice("Version %s\n", version);
|
2022-11-18 20:24:10 +00:00
|
|
|
imsg_notice("Copyright the AVRDUDE authors;\n");
|
|
|
|
imsg_notice("see https://github.com/avrdudes/avrdude/blob/main/AUTHORS\n\n");
|
2022-10-17 14:44:55 +00:00
|
|
|
|
|
|
|
if(*sys_config) {
|
|
|
|
char *real_sys_config = realpath(sys_config, NULL);
|
|
|
|
if(real_sys_config) {
|
|
|
|
imsg_notice("System wide configuration file is %s\n", real_sys_config);
|
|
|
|
} else
|
|
|
|
pmsg_warning("cannot determine realpath() of config file %s: %s\n", sys_config, strerror(errno));
|
|
|
|
|
|
|
|
rc = read_config(real_sys_config);
|
|
|
|
if (rc) {
|
|
|
|
pmsg_error("unable to process system wide configuration file %s\n", real_sys_config);
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
free(real_sys_config);
|
2001-10-14 23:17:26 +00:00
|
|
|
}
|
2001-10-13 03:12:52 +00:00
|
|
|
|
2003-02-22 16:45:13 +00:00
|
|
|
if (usr_config[0] != 0) {
|
2022-10-17 14:44:55 +00:00
|
|
|
imsg_notice("User configuration file is %s\n", usr_config);
|
2003-02-22 16:45:13 +00:00
|
|
|
|
|
|
|
rc = stat(usr_config, &sb);
|
2022-10-17 14:44:55 +00:00
|
|
|
if ((rc < 0) || ((sb.st_mode & S_IFREG) == 0))
|
|
|
|
imsg_notice("User configuration file does not exist or is not a regular file, skipping\n");
|
2003-02-22 16:45:13 +00:00
|
|
|
else {
|
|
|
|
rc = read_config(usr_config);
|
|
|
|
if (rc) {
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_error("unable to process user configuration file %s\n", usr_config);
|
2003-02-22 16:45:13 +00:00
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2012-01-10 18:07:19 +00:00
|
|
|
|
|
|
|
if (lsize(additional_config_files) > 0) {
|
|
|
|
LNODEID ln1;
|
|
|
|
const char * p = NULL;
|
|
|
|
|
|
|
|
for (ln1=lfirst(additional_config_files); ln1; ln1=lnext(ln1)) {
|
|
|
|
p = ldata(ln1);
|
2022-10-17 14:44:55 +00:00
|
|
|
imsg_notice("additional configuration file is %s\n", p);
|
2012-01-10 18:07:19 +00:00
|
|
|
|
|
|
|
rc = read_config(p);
|
|
|
|
if (rc) {
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_error("unable to process additional configuration file %s\n", p);
|
2012-01-10 18:07:19 +00:00
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-08-26 20:30:26 +00:00
|
|
|
// set bitclock from configuration files unless changed by command line
|
|
|
|
if (default_bitclock > 0 && bitclock == 0.0) {
|
|
|
|
bitclock = default_bitclock;
|
|
|
|
}
|
2003-02-22 16:45:13 +00:00
|
|
|
|
2022-11-10 18:20:13 +00:00
|
|
|
if(!(programmer && *programmer) && *default_programmer)
|
|
|
|
programmer = cache_string(default_programmer);
|
|
|
|
|
2022-08-11 23:28:54 +00:00
|
|
|
// Developer options to print parts and/or programmer entries of avrdude.conf
|
|
|
|
int dev_opt_c = dev_opt(programmer); // -c <wildcard>/[sSArt]
|
|
|
|
int dev_opt_p = dev_opt(partdesc); // -p <wildcard>/[dsSArcow*t]
|
2022-08-03 23:14:19 +00:00
|
|
|
|
2022-08-11 23:28:54 +00:00
|
|
|
if(dev_opt_c || dev_opt_p) { // See -c/h and or -p/h
|
|
|
|
dev_output_pgm_part(dev_opt_c, programmer, dev_opt_p, partdesc);
|
2022-08-08 15:52:09 +00:00
|
|
|
exit(0);
|
2022-05-24 15:56:11 +00:00
|
|
|
}
|
|
|
|
|
2022-09-21 11:10:24 +00:00
|
|
|
for(LNODEID ln1 = lfirst(part_list); ln1; ln1 = lnext(ln1)) {
|
|
|
|
AVRPART *p = ldata(ln1);
|
|
|
|
for(LNODEID ln2 = lfirst(programmers); ln2; ln2 = lnext(ln2)) {
|
|
|
|
PROGRAMMER *pgm = ldata(ln2);
|
|
|
|
int pm = pgm->prog_modes & p->prog_modes;
|
|
|
|
if(pm & (pm-1))
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_warning("%s and %s share multiple modes (%s)\n",
|
|
|
|
pgm->id? (char *) ldata(lfirst(pgm->id)): "???", p->desc, via_prog_modes(pm));
|
2022-09-21 11:10:24 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2003-03-05 00:53:49 +00:00
|
|
|
if (partdesc) {
|
|
|
|
if (strcmp(partdesc, "?") == 0) {
|
2022-09-21 14:38:05 +00:00
|
|
|
if(programmer && *programmer) {
|
|
|
|
PROGRAMMER *pgm = locate_programmer(programmers, programmer);
|
2022-11-01 18:06:52 +00:00
|
|
|
if(!pgm) {
|
|
|
|
programmer_not_found(programmer);
|
|
|
|
exit(1);
|
|
|
|
}
|
2022-10-17 14:44:55 +00:00
|
|
|
msg_error("\nValid parts for programmer %s are:\n", programmer);
|
2022-09-21 14:38:05 +00:00
|
|
|
list_parts(stderr, " ", part_list, pgm->prog_modes);
|
|
|
|
} else {
|
2022-10-17 14:44:55 +00:00
|
|
|
msg_error("\nValid parts are:\n");
|
2022-09-21 14:38:05 +00:00
|
|
|
list_parts(stderr, " ", part_list, ~0);
|
|
|
|
}
|
2022-10-17 14:44:55 +00:00
|
|
|
msg_error("\n");
|
2003-03-05 00:53:49 +00:00
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (programmer) {
|
|
|
|
if (strcmp(programmer, "?") == 0) {
|
2022-09-21 14:38:05 +00:00
|
|
|
if(partdesc && *partdesc) {
|
|
|
|
AVRPART *p = locate_part(part_list, partdesc);
|
2022-11-01 18:06:52 +00:00
|
|
|
if(!p) {
|
|
|
|
part_not_found(partdesc);
|
|
|
|
exit(1);
|
|
|
|
}
|
2022-10-17 14:44:55 +00:00
|
|
|
msg_error("\nValid programmers for part %s are:\n", p->desc);
|
2022-09-21 14:38:05 +00:00
|
|
|
list_programmers(stderr, " ", programmers, p->prog_modes);
|
|
|
|
} else {
|
2022-10-17 14:44:55 +00:00
|
|
|
msg_error("\nValid programmers are:\n");
|
2022-09-21 14:38:05 +00:00
|
|
|
list_programmers(stderr, " ", programmers, ~0);
|
|
|
|
}
|
2022-10-17 14:44:55 +00:00
|
|
|
msg_error("\n");
|
2003-03-05 00:53:49 +00:00
|
|
|
exit(1);
|
|
|
|
}
|
2022-09-21 14:38:05 +00:00
|
|
|
|
2012-01-31 17:03:43 +00:00
|
|
|
if (strcmp(programmer, "?type") == 0) {
|
2022-10-17 14:44:55 +00:00
|
|
|
msg_error("\nValid programmer types are:\n");
|
2012-01-31 17:03:43 +00:00
|
|
|
list_programmer_types(stderr, " ");
|
2022-10-17 14:44:55 +00:00
|
|
|
msg_error("\n");
|
2012-01-31 17:03:43 +00:00
|
|
|
exit(1);
|
|
|
|
}
|
2003-03-05 00:53:49 +00:00
|
|
|
}
|
|
|
|
|
2022-10-17 14:44:55 +00:00
|
|
|
msg_notice("\n");
|
2003-03-05 00:53:49 +00:00
|
|
|
|
2022-11-01 18:06:52 +00:00
|
|
|
if (!programmer || !*programmer) {
|
|
|
|
programmer_not_found(NULL);
|
|
|
|
exit(1);
|
|
|
|
}
|
2003-02-21 21:07:43 +00:00
|
|
|
|
|
|
|
pgm = locate_programmer(programmers, programmer);
|
2022-11-01 18:06:52 +00:00
|
|
|
if (pgm == NULL) {
|
|
|
|
programmer_not_found(programmer);
|
|
|
|
exit(1);
|
|
|
|
}
|
2003-02-21 21:07:43 +00:00
|
|
|
|
2012-01-22 12:31:54 +00:00
|
|
|
if (pgm->initpgm) {
|
|
|
|
pgm->initpgm(pgm);
|
|
|
|
} else {
|
2022-10-17 14:44:55 +00:00
|
|
|
msg_error("\n");
|
|
|
|
pmsg_error("cannot initialize the programmer\n\n");
|
2012-01-22 12:31:54 +00:00
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
main.c, pgm.c, pgm.h: Add setup and teardown hooks to the programmer
definition. If present, call the setup hook immediately after finding
the respective programmer object, and schedule the teardown hook to be
called upon exit. This allows the programmer implementation to
dynamically allocate private programmer data.
avr910.c, butterfly.c, jtagmkI.c, jtagmkII.c, stk500v2.c, usbasp.c,
usbtiny.c: Convert static programmer data into dynamically allocated
data.
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk/avrdude@764 81a1dc3b-b13d-400b-aceb-764788c761c2
2007-11-07 20:36:12 +00:00
|
|
|
if (pgm->setup) {
|
|
|
|
pgm->setup(pgm);
|
|
|
|
}
|
|
|
|
if (pgm->teardown) {
|
|
|
|
atexit(exithook);
|
|
|
|
}
|
|
|
|
|
2007-11-06 19:42:16 +00:00
|
|
|
if (lsize(extended_params) > 0) {
|
|
|
|
if (pgm->parseextparams == NULL) {
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_error("programmer does not support extended parameters, -x option(s) ignored\n");
|
2007-11-06 19:42:16 +00:00
|
|
|
} else {
|
|
|
|
if (pgm->parseextparams(pgm, extended_params) < 0) {
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_error("unable to parse extended parameter list\n");
|
2007-11-06 19:42:16 +00:00
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-01-30 17:08:48 +00:00
|
|
|
if (port == NULL) {
|
|
|
|
switch (pgm->conntype)
|
|
|
|
{
|
|
|
|
case CONNTYPE_PARALLEL:
|
2022-08-09 20:45:04 +00:00
|
|
|
port = cfg_strdup("main()", default_parallel);
|
2012-01-30 17:08:48 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case CONNTYPE_SERIAL:
|
2022-08-09 20:45:04 +00:00
|
|
|
port = cfg_strdup("main()", default_serial);
|
2012-01-30 17:08:48 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case CONNTYPE_USB:
|
|
|
|
port = DEFAULT_USB;
|
|
|
|
break;
|
2022-04-10 21:36:53 +00:00
|
|
|
|
|
|
|
case CONNTYPE_SPI:
|
2022-07-18 16:34:06 +00:00
|
|
|
#ifdef HAVE_LINUXSPI
|
Use const in PROGRAMMER function arguments where appropriate
In order to get meaningful const properties for the PROGRAMMER, AVRPART and
AVRMEM arguments, some code needed to be moved around, otherwise a network of
"tainted" assignments risked rendering nothing const:
- Change void (*enable)(PROGRAMMER *pgm) to void (*enable)(PROGRAMMER *pgm,
const AVRPART *p); this allows changes in the PROGRAMMER structure after
the part is known. For example, use TPI, UPDI, PDI functions in that
programmer appropriate to the part. This used to be done later in the
process, eg, in the initialize() function, which "taints" all other
programmer functions wrt const and sometimes requires other finessing with
flags etc. Much clearer with the modified enable() interface.
- Move TPI initpgm-type code from initialize() to enable() --- note that
initpgm() does not have the info at the time when it is called whether or
not TPI is required
- buspirate.c: move pgm->flag to PDATA(pgm)->flag (so legitimate
modification of the flag does not change PROGRAMMER structure)
- Move AVRPART_INIT_SMC and AVRPART_WRITE bits from the flags field in
AVRPART to jtagmkII.c's private data flags32 fiels as FLAGS32_INIT_SMC and
FLAGS32_WRITE bits
- Move the xbeeResetPin component to private data in stk500.c as this is
needed by xbee when it saddles on the stk500 code (previously, the flags
component of the part was re-dedicated to this)
- Change the way the "chained" private data are used in jtag3.c whilst
keeping the PROGRAMMER structure read-only otherwise
- In stk500v2.c move the STK600 pgm update from stk500v2_initialize() to
stk500v2_enable() so the former keeps the PROGRAMMER structure read-only
(for const assertion).
- In usbasp change the code from changing PROGRAMMER functions late to
dispatching to TPI or regular SPI protocol functions at runtime; reason
being the decision whether to use TPI protocol is done at run-time
depending on the capability of the attached programmer
Also fixes Issue #1071, the treatment of default eecr value.
2022-08-17 15:05:28 +00:00
|
|
|
port = cfg_strdup("main()", *default_spi? default_spi: "unknown");
|
2022-04-10 21:36:53 +00:00
|
|
|
#endif
|
2022-07-18 16:34:06 +00:00
|
|
|
break;
|
2001-10-14 23:17:26 +00:00
|
|
|
}
|
|
|
|
}
|
2012-01-30 17:08:48 +00:00
|
|
|
|
2022-11-01 18:06:52 +00:00
|
|
|
/*
|
|
|
|
* open the programmer
|
|
|
|
*/
|
|
|
|
if (port[0] == 0) {
|
|
|
|
msg_error("\n");
|
|
|
|
pmsg_error("no port has been specified on the command line or in the config file\n");
|
|
|
|
imsg_error("specify a port using the -P option and try again\n\n");
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (verbose) {
|
|
|
|
imsg_notice("Using Port : %s\n", port);
|
|
|
|
imsg_notice("Using Programmer : %s\n", programmer);
|
|
|
|
}
|
Use const in PROGRAMMER function arguments where appropriate
In order to get meaningful const properties for the PROGRAMMER, AVRPART and
AVRMEM arguments, some code needed to be moved around, otherwise a network of
"tainted" assignments risked rendering nothing const:
- Change void (*enable)(PROGRAMMER *pgm) to void (*enable)(PROGRAMMER *pgm,
const AVRPART *p); this allows changes in the PROGRAMMER structure after
the part is known. For example, use TPI, UPDI, PDI functions in that
programmer appropriate to the part. This used to be done later in the
process, eg, in the initialize() function, which "taints" all other
programmer functions wrt const and sometimes requires other finessing with
flags etc. Much clearer with the modified enable() interface.
- Move TPI initpgm-type code from initialize() to enable() --- note that
initpgm() does not have the info at the time when it is called whether or
not TPI is required
- buspirate.c: move pgm->flag to PDATA(pgm)->flag (so legitimate
modification of the flag does not change PROGRAMMER structure)
- Move AVRPART_INIT_SMC and AVRPART_WRITE bits from the flags field in
AVRPART to jtagmkII.c's private data flags32 fiels as FLAGS32_INIT_SMC and
FLAGS32_WRITE bits
- Move the xbeeResetPin component to private data in stk500.c as this is
needed by xbee when it saddles on the stk500 code (previously, the flags
component of the part was re-dedicated to this)
- Change the way the "chained" private data are used in jtag3.c whilst
keeping the PROGRAMMER structure read-only otherwise
- In stk500v2.c move the STK600 pgm update from stk500v2_initialize() to
stk500v2_enable() so the former keeps the PROGRAMMER structure read-only
(for const assertion).
- In usbasp change the code from changing PROGRAMMER functions late to
dispatching to TPI or regular SPI protocol functions at runtime; reason
being the decision whether to use TPI protocol is done at run-time
depending on the capability of the attached programmer
Also fixes Issue #1071, the treatment of default eecr value.
2022-08-17 15:05:28 +00:00
|
|
|
|
2022-11-01 18:06:52 +00:00
|
|
|
if (baudrate != 0) {
|
|
|
|
imsg_notice("Overriding Baud Rate : %d\n", baudrate);
|
|
|
|
pgm->baudrate = baudrate;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (bitclock != 0.0) {
|
|
|
|
imsg_notice("Setting bit clk period : %.1f\n", bitclock);
|
|
|
|
pgm->bitclock = bitclock * 1e-6;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ispdelay != 0) {
|
|
|
|
imsg_notice("Setting isp clock delay : %3i\n", ispdelay);
|
|
|
|
pgm->ispdelay = ispdelay;
|
|
|
|
}
|
|
|
|
|
|
|
|
rc = pgm->open(pgm, port);
|
|
|
|
if (rc < 0) {
|
|
|
|
pmsg_error("unable to open programmer %s on port %s\n", programmer, port);
|
|
|
|
exitrc = 1;
|
|
|
|
pgm->ppidata = 0; /* clear all bits at exit */
|
|
|
|
goto main_exit;
|
|
|
|
}
|
|
|
|
is_open = 1;
|
|
|
|
|
|
|
|
if (partdesc == NULL) {
|
|
|
|
part_not_found(NULL);
|
|
|
|
exitrc = 1;
|
|
|
|
goto main_exit;
|
|
|
|
}
|
2001-01-19 02:46:50 +00:00
|
|
|
|
2001-10-14 23:17:26 +00:00
|
|
|
p = locate_part(part_list, partdesc);
|
2022-11-01 18:06:52 +00:00
|
|
|
if (p == NULL) {
|
|
|
|
part_not_found(partdesc);
|
|
|
|
exitrc = 1;
|
|
|
|
goto main_exit;
|
|
|
|
}
|
2001-09-19 17:04:25 +00:00
|
|
|
|
2001-09-21 03:27:20 +00:00
|
|
|
if (exitspecs != NULL) {
|
2006-08-29 23:12:15 +00:00
|
|
|
if (pgm->parseexitspecs == NULL) {
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_warning("-E option not supported by this programmer type\n");
|
2002-11-30 14:09:12 +00:00
|
|
|
exitspecs = NULL;
|
|
|
|
}
|
2006-08-29 23:12:15 +00:00
|
|
|
else if (pgm->parseexitspecs(pgm, exitspecs) < 0) {
|
2001-09-21 03:27:20 +00:00
|
|
|
usage();
|
2022-11-01 18:06:52 +00:00
|
|
|
exitrc = 1;
|
|
|
|
goto main_exit;
|
2001-09-21 03:27:20 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
Use const in PROGRAMMER function arguments where appropriate
In order to get meaningful const properties for the PROGRAMMER, AVRPART and
AVRMEM arguments, some code needed to be moved around, otherwise a network of
"tainted" assignments risked rendering nothing const:
- Change void (*enable)(PROGRAMMER *pgm) to void (*enable)(PROGRAMMER *pgm,
const AVRPART *p); this allows changes in the PROGRAMMER structure after
the part is known. For example, use TPI, UPDI, PDI functions in that
programmer appropriate to the part. This used to be done later in the
process, eg, in the initialize() function, which "taints" all other
programmer functions wrt const and sometimes requires other finessing with
flags etc. Much clearer with the modified enable() interface.
- Move TPI initpgm-type code from initialize() to enable() --- note that
initpgm() does not have the info at the time when it is called whether or
not TPI is required
- buspirate.c: move pgm->flag to PDATA(pgm)->flag (so legitimate
modification of the flag does not change PROGRAMMER structure)
- Move AVRPART_INIT_SMC and AVRPART_WRITE bits from the flags field in
AVRPART to jtagmkII.c's private data flags32 fiels as FLAGS32_INIT_SMC and
FLAGS32_WRITE bits
- Move the xbeeResetPin component to private data in stk500.c as this is
needed by xbee when it saddles on the stk500 code (previously, the flags
component of the part was re-dedicated to this)
- Change the way the "chained" private data are used in jtag3.c whilst
keeping the PROGRAMMER structure read-only otherwise
- In stk500v2.c move the STK600 pgm update from stk500v2_initialize() to
stk500v2_enable() so the former keeps the PROGRAMMER structure read-only
(for const assertion).
- In usbasp change the code from changing PROGRAMMER functions late to
dispatching to TPI or regular SPI protocol functions at runtime; reason
being the decision whether to use TPI protocol is done at run-time
depending on the capability of the attached programmer
Also fixes Issue #1071, the treatment of default eecr value.
2022-08-17 15:05:28 +00:00
|
|
|
if (avr_initmem(p) != 0) {
|
2022-10-17 14:44:55 +00:00
|
|
|
msg_error("\n");
|
|
|
|
pmsg_error("unable to initialize memories\n");
|
2022-11-01 18:06:52 +00:00
|
|
|
exitrc = 1;
|
|
|
|
goto main_exit;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(verbose) {
|
|
|
|
if ((strcmp(pgm->type, "avr910") == 0)) {
|
|
|
|
imsg_notice("avr910_devcode (avrdude.conf) : ");
|
|
|
|
if(p->avr910_devcode)
|
|
|
|
msg_notice("0x%02x\n", (uint8_t) p->avr910_devcode);
|
|
|
|
else
|
|
|
|
msg_notice("none\n");
|
|
|
|
}
|
2011-09-14 21:49:42 +00:00
|
|
|
}
|
2001-01-19 02:46:50 +00:00
|
|
|
|
2012-04-25 16:32:23 +00:00
|
|
|
/*
|
2022-08-05 16:38:59 +00:00
|
|
|
* Now that we know which part we are going to program, locate any -U
|
|
|
|
* options using the default memory region, fill in the device-dependent
|
|
|
|
* default region name ("application" for Xmega parts or "flash" otherwise)
|
|
|
|
* and check for basic problems with memory names or file access with a
|
|
|
|
* view to exit before programming.
|
2012-04-25 16:32:23 +00:00
|
|
|
*/
|
2022-08-05 16:38:59 +00:00
|
|
|
int doexit = 0;
|
2012-04-25 16:32:23 +00:00
|
|
|
for (ln=lfirst(updates); ln; ln=lnext(ln)) {
|
|
|
|
upd = ldata(ln);
|
|
|
|
if (upd->memtype == NULL) {
|
2022-08-30 15:33:42 +00:00
|
|
|
const char *mtype = p->prog_modes & PM_PDI? "application": "flash";
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_notice2("defaulting memtype in -U %c:%s option to \"%s\"\n",
|
|
|
|
(upd->op == DEVICE_READ)? 'r': (upd->op == DEVICE_WRITE)? 'w': 'v',
|
|
|
|
upd->filename, mtype);
|
2022-08-09 20:20:44 +00:00
|
|
|
upd->memtype = cfg_strdup("main()", mtype);
|
2012-04-25 16:32:23 +00:00
|
|
|
}
|
2022-08-03 23:14:19 +00:00
|
|
|
|
2022-08-05 16:38:59 +00:00
|
|
|
rc = update_dryrun(p, upd);
|
|
|
|
if (rc && rc != LIBAVRDUDE_SOFTFAIL)
|
|
|
|
doexit = 1;
|
2012-04-25 16:32:23 +00:00
|
|
|
}
|
2022-11-01 18:06:52 +00:00
|
|
|
if(doexit) {
|
2004-01-28 20:01:44 +00:00
|
|
|
exitrc = 1;
|
|
|
|
goto main_exit;
|
|
|
|
}
|
2001-01-19 02:46:50 +00:00
|
|
|
|
2006-10-09 14:34:24 +00:00
|
|
|
if (calibrate) {
|
|
|
|
/*
|
|
|
|
* perform an RC oscillator calibration
|
|
|
|
* as outlined in appnote AVR053
|
|
|
|
*/
|
2009-07-01 16:08:49 +00:00
|
|
|
if (pgm->perform_osccal == 0) {
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_error("programmer does not support RC oscillator calibration\n");
|
2009-07-01 16:08:49 +00:00
|
|
|
exitrc = 1;
|
|
|
|
} else {
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_info("performing RC oscillator calibration\n");
|
2009-07-01 16:08:49 +00:00
|
|
|
exitrc = pgm->perform_osccal(pgm);
|
|
|
|
}
|
2022-10-17 14:44:55 +00:00
|
|
|
if (exitrc == 0)
|
|
|
|
pmsg_info("calibration value is now stored in EEPROM at address 0\n");
|
2006-10-09 14:34:24 +00:00
|
|
|
goto main_exit;
|
|
|
|
}
|
|
|
|
|
2022-10-17 14:44:55 +00:00
|
|
|
if (verbose && quell_progress < 2) {
|
2013-05-05 13:35:35 +00:00
|
|
|
avr_display(stderr, p, progbuf, verbose);
|
2022-10-17 14:44:55 +00:00
|
|
|
msg_notice("\n");
|
2013-05-05 13:35:35 +00:00
|
|
|
programmer_display(pgm, progbuf);
|
|
|
|
}
|
|
|
|
|
2022-10-17 14:44:55 +00:00
|
|
|
msg_info("\n");
|
2002-12-01 06:35:18 +00:00
|
|
|
|
2001-01-19 02:46:50 +00:00
|
|
|
exitrc = 0;
|
|
|
|
|
2002-11-23 00:47:29 +00:00
|
|
|
/*
|
2002-11-30 14:09:12 +00:00
|
|
|
* enable the programmer
|
2002-11-23 00:47:29 +00:00
|
|
|
*/
|
Use const in PROGRAMMER function arguments where appropriate
In order to get meaningful const properties for the PROGRAMMER, AVRPART and
AVRMEM arguments, some code needed to be moved around, otherwise a network of
"tainted" assignments risked rendering nothing const:
- Change void (*enable)(PROGRAMMER *pgm) to void (*enable)(PROGRAMMER *pgm,
const AVRPART *p); this allows changes in the PROGRAMMER structure after
the part is known. For example, use TPI, UPDI, PDI functions in that
programmer appropriate to the part. This used to be done later in the
process, eg, in the initialize() function, which "taints" all other
programmer functions wrt const and sometimes requires other finessing with
flags etc. Much clearer with the modified enable() interface.
- Move TPI initpgm-type code from initialize() to enable() --- note that
initpgm() does not have the info at the time when it is called whether or
not TPI is required
- buspirate.c: move pgm->flag to PDATA(pgm)->flag (so legitimate
modification of the flag does not change PROGRAMMER structure)
- Move AVRPART_INIT_SMC and AVRPART_WRITE bits from the flags field in
AVRPART to jtagmkII.c's private data flags32 fiels as FLAGS32_INIT_SMC and
FLAGS32_WRITE bits
- Move the xbeeResetPin component to private data in stk500.c as this is
needed by xbee when it saddles on the stk500 code (previously, the flags
component of the part was re-dedicated to this)
- Change the way the "chained" private data are used in jtag3.c whilst
keeping the PROGRAMMER structure read-only otherwise
- In stk500v2.c move the STK600 pgm update from stk500v2_initialize() to
stk500v2_enable() so the former keeps the PROGRAMMER structure read-only
(for const assertion).
- In usbasp change the code from changing PROGRAMMER functions late to
dispatching to TPI or regular SPI protocol functions at runtime; reason
being the decision whether to use TPI protocol is done at run-time
depending on the capability of the attached programmer
Also fixes Issue #1071, the treatment of default eecr value.
2022-08-17 15:05:28 +00:00
|
|
|
pgm->enable(pgm, p);
|
2002-11-23 00:47:29 +00:00
|
|
|
|
2001-01-24 19:10:34 +00:00
|
|
|
/*
|
2002-11-30 14:09:12 +00:00
|
|
|
* turn off all the status leds
|
2001-01-24 19:10:34 +00:00
|
|
|
*/
|
2002-11-30 14:09:12 +00:00
|
|
|
pgm->rdy_led(pgm, OFF);
|
|
|
|
pgm->err_led(pgm, OFF);
|
|
|
|
pgm->pgm_led(pgm, OFF);
|
|
|
|
pgm->vfy_led(pgm, OFF);
|
2001-01-24 19:10:34 +00:00
|
|
|
|
2001-01-19 02:46:50 +00:00
|
|
|
/*
|
2022-01-07 10:31:16 +00:00
|
|
|
* initialize the chip in preparation for accepting commands
|
2001-01-19 02:46:50 +00:00
|
|
|
*/
|
2008-07-29 21:26:55 +00:00
|
|
|
init_ok = (rc = pgm->initialize(pgm, p)) >= 0;
|
|
|
|
if (!init_ok) {
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_error("initialization failed, rc=%d\n", rc);
|
2022-10-20 15:34:21 +00:00
|
|
|
imsg_error("- double check the connections and try again\n");
|
|
|
|
imsg_error("- use -B to set lower ISP clock frequency, e.g. -B 200kHz\n");
|
2003-08-31 15:40:59 +00:00
|
|
|
if (!ovsigck) {
|
2022-10-20 15:34:21 +00:00
|
|
|
imsg_error("- use -F to override this check\n\n");
|
2003-08-31 15:40:59 +00:00
|
|
|
exitrc = 1;
|
|
|
|
goto main_exit;
|
|
|
|
}
|
2001-01-19 02:46:50 +00:00
|
|
|
}
|
|
|
|
|
2001-01-24 19:10:34 +00:00
|
|
|
/* indicate ready */
|
2002-11-30 14:09:12 +00:00
|
|
|
pgm->rdy_led(pgm, ON);
|
2001-01-24 19:10:34 +00:00
|
|
|
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_info("AVR device initialized and ready to accept instructions\n");
|
2001-01-19 02:46:50 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Let's read the signature bytes to make sure there is at least a
|
|
|
|
* chip on the other end that is responding correctly. A check
|
2006-02-27 17:18:42 +00:00
|
|
|
* against 0xffffff / 0x000000 should ensure that the signature bytes
|
|
|
|
* are valid.
|
2001-01-19 02:46:50 +00:00
|
|
|
*/
|
2022-08-30 15:33:42 +00:00
|
|
|
if(!(p->prog_modes & PM_aWire)) { // not AVR32
|
2012-04-20 12:33:15 +00:00
|
|
|
int attempt = 0;
|
|
|
|
int waittime = 10000; /* 10 ms */
|
|
|
|
|
|
|
|
sig_again:
|
|
|
|
usleep(waittime);
|
2009-10-10 20:09:56 +00:00
|
|
|
if (init_ok) {
|
|
|
|
rc = avr_signature(pgm, p);
|
2022-06-15 21:32:22 +00:00
|
|
|
if (rc != LIBAVRDUDE_SUCCESS) {
|
2022-08-30 15:33:42 +00:00
|
|
|
if (rc == LIBAVRDUDE_SOFTFAIL && (p->prog_modes & PM_UPDI) && attempt < 1) {
|
Submitted by Jan Egil Ruud <janegil.ruud@microchip.com>
patch #9507: Fix UPDI chip erase
* lexer.l (family_id): New keyword.
* config_gram.y: (Ditto)
* doc/avrdude.texi: Document new keyword
* avrdude.conf.in: Add family_id for avr8x devices
* avr.c: Pass error code up.
* jtag3.c: Pass error code from memory read up; implement
jtag3_read_sib()
* libavrdude.h: Add new items.
* main.c: Implement different chip erase handling required
for UPDI devices.
Submitted by Jan Egil Ruud <janegil.ruud@microchip.com>
patch #9506: Script to create device configuration stub from Atmel ATDF files
* avrdude.conf.in (ATtiny202, ATtiny204, ATtiny402, ATtiny404)
(ATtiny406, ATtiny804, ATtiny806, ATtiny807, ATtiny1604)
(ATtiny1606, ATtiny1607, ATtiny212, ATtiny214, ATtiny412)
(ATTiny414, ATtiny416, ATtiny417, ATtiny814, ATtiny816)
(ATtiny1614, ATtiny1616, ATtiny3214, ATtiny3216, ATtiny3217)
(ATmega3208, ATmega3209, ATmega4808, ATmega4809): New devices
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk/avrdude@1405 81a1dc3b-b13d-400b-aceb-764788c761c2
2018-01-09 23:29:31 +00:00
|
|
|
attempt++;
|
|
|
|
if (pgm->read_sib) {
|
2022-10-13 12:06:15 +00:00
|
|
|
// Read SIB and compare FamilyID
|
|
|
|
char sib[AVR_SIBLEN + 1];
|
|
|
|
pgm->read_sib(pgm, p, sib);
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_notice("System Information Block: %s\n", sib);
|
|
|
|
pmsg_info("received FamilyID: \"%.*s\"\n", AVR_FAMILYIDLEN, sib);
|
2022-10-13 12:06:15 +00:00
|
|
|
if (strncmp(p->family_id, sib, AVR_FAMILYIDLEN))
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_error("expected FamilyID: \"%s\"\n", p->family_id);
|
Submitted by Jan Egil Ruud <janegil.ruud@microchip.com>
patch #9507: Fix UPDI chip erase
* lexer.l (family_id): New keyword.
* config_gram.y: (Ditto)
* doc/avrdude.texi: Document new keyword
* avrdude.conf.in: Add family_id for avr8x devices
* avr.c: Pass error code up.
* jtag3.c: Pass error code from memory read up; implement
jtag3_read_sib()
* libavrdude.h: Add new items.
* main.c: Implement different chip erase handling required
for UPDI devices.
Submitted by Jan Egil Ruud <janegil.ruud@microchip.com>
patch #9506: Script to create device configuration stub from Atmel ATDF files
* avrdude.conf.in (ATtiny202, ATtiny204, ATtiny402, ATtiny404)
(ATtiny406, ATtiny804, ATtiny806, ATtiny807, ATtiny1604)
(ATtiny1606, ATtiny1607, ATtiny212, ATtiny214, ATtiny412)
(ATTiny414, ATtiny416, ATtiny417, ATtiny814, ATtiny816)
(ATtiny1614, ATtiny1616, ATtiny3214, ATtiny3216, ATtiny3217)
(ATmega3208, ATmega3209, ATmega4808, ATmega4809): New devices
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk/avrdude@1405 81a1dc3b-b13d-400b-aceb-764788c761c2
2018-01-09 23:29:31 +00:00
|
|
|
}
|
|
|
|
if(erase) {
|
|
|
|
erase = 0;
|
|
|
|
if (uflags & UF_NOWRITE) {
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_warning("conflicting -e and -n options specified, NOT erasing chip\n");
|
Submitted by Jan Egil Ruud <janegil.ruud@microchip.com>
patch #9507: Fix UPDI chip erase
* lexer.l (family_id): New keyword.
* config_gram.y: (Ditto)
* doc/avrdude.texi: Document new keyword
* avrdude.conf.in: Add family_id for avr8x devices
* avr.c: Pass error code up.
* jtag3.c: Pass error code from memory read up; implement
jtag3_read_sib()
* libavrdude.h: Add new items.
* main.c: Implement different chip erase handling required
for UPDI devices.
Submitted by Jan Egil Ruud <janegil.ruud@microchip.com>
patch #9506: Script to create device configuration stub from Atmel ATDF files
* avrdude.conf.in (ATtiny202, ATtiny204, ATtiny402, ATtiny404)
(ATtiny406, ATtiny804, ATtiny806, ATtiny807, ATtiny1604)
(ATtiny1606, ATtiny1607, ATtiny212, ATtiny214, ATtiny412)
(ATTiny414, ATtiny416, ATtiny417, ATtiny814, ATtiny816)
(ATtiny1614, ATtiny1616, ATtiny3214, ATtiny3216, ATtiny3217)
(ATmega3208, ATmega3209, ATmega4808, ATmega4809): New devices
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk/avrdude@1405 81a1dc3b-b13d-400b-aceb-764788c761c2
2018-01-09 23:29:31 +00:00
|
|
|
} else {
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_info("erasing chip\n");
|
2018-01-16 21:17:04 +00:00
|
|
|
exitrc = avr_unlock(pgm, p);
|
2022-10-17 14:44:55 +00:00
|
|
|
if(exitrc)
|
|
|
|
goto main_exit;
|
Submitted by Jan Egil Ruud <janegil.ruud@microchip.com>
patch #9507: Fix UPDI chip erase
* lexer.l (family_id): New keyword.
* config_gram.y: (Ditto)
* doc/avrdude.texi: Document new keyword
* avrdude.conf.in: Add family_id for avr8x devices
* avr.c: Pass error code up.
* jtag3.c: Pass error code from memory read up; implement
jtag3_read_sib()
* libavrdude.h: Add new items.
* main.c: Implement different chip erase handling required
for UPDI devices.
Submitted by Jan Egil Ruud <janegil.ruud@microchip.com>
patch #9506: Script to create device configuration stub from Atmel ATDF files
* avrdude.conf.in (ATtiny202, ATtiny204, ATtiny402, ATtiny404)
(ATtiny406, ATtiny804, ATtiny806, ATtiny807, ATtiny1604)
(ATtiny1606, ATtiny1607, ATtiny212, ATtiny214, ATtiny412)
(ATTiny414, ATtiny416, ATtiny417, ATtiny814, ATtiny816)
(ATtiny1614, ATtiny1616, ATtiny3214, ATtiny3216, ATtiny3217)
(ATmega3208, ATmega3209, ATmega4808, ATmega4809): New devices
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk/avrdude@1405 81a1dc3b-b13d-400b-aceb-764788c761c2
2018-01-09 23:29:31 +00:00
|
|
|
goto sig_again;
|
|
|
|
}
|
|
|
|
}
|
2022-10-13 12:06:15 +00:00
|
|
|
if (!ovsigck) {
|
2022-10-17 14:44:55 +00:00
|
|
|
imsg_error("double check chip or use -F to override this check\n");
|
2022-10-13 12:06:15 +00:00
|
|
|
exitrc = 1;
|
|
|
|
goto main_exit;
|
|
|
|
}
|
Submitted by Jan Egil Ruud <janegil.ruud@microchip.com>
patch #9507: Fix UPDI chip erase
* lexer.l (family_id): New keyword.
* config_gram.y: (Ditto)
* doc/avrdude.texi: Document new keyword
* avrdude.conf.in: Add family_id for avr8x devices
* avr.c: Pass error code up.
* jtag3.c: Pass error code from memory read up; implement
jtag3_read_sib()
* libavrdude.h: Add new items.
* main.c: Implement different chip erase handling required
for UPDI devices.
Submitted by Jan Egil Ruud <janegil.ruud@microchip.com>
patch #9506: Script to create device configuration stub from Atmel ATDF files
* avrdude.conf.in (ATtiny202, ATtiny204, ATtiny402, ATtiny404)
(ATtiny406, ATtiny804, ATtiny806, ATtiny807, ATtiny1604)
(ATtiny1606, ATtiny1607, ATtiny212, ATtiny214, ATtiny412)
(ATTiny414, ATtiny416, ATtiny417, ATtiny814, ATtiny816)
(ATtiny1614, ATtiny1616, ATtiny3214, ATtiny3216, ATtiny3217)
(ATmega3208, ATmega3209, ATmega4808, ATmega4809): New devices
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk/avrdude@1405 81a1dc3b-b13d-400b-aceb-764788c761c2
2018-01-09 23:29:31 +00:00
|
|
|
}
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_error("unable to read signature data, rc=%d\n", rc);
|
2009-10-10 20:09:56 +00:00
|
|
|
exitrc = 1;
|
|
|
|
goto main_exit;
|
|
|
|
}
|
|
|
|
}
|
2022-05-24 15:56:11 +00:00
|
|
|
|
2009-10-10 20:09:56 +00:00
|
|
|
sig = avr_locate_mem(p, "signature");
|
2022-10-17 14:44:55 +00:00
|
|
|
if (sig == NULL)
|
|
|
|
pmsg_warning("signature memory not defined for device %s\n", p->desc);
|
|
|
|
|
|
|
|
if (sig != NULL) {
|
2009-10-10 20:09:56 +00:00
|
|
|
int ff, zz;
|
2001-11-21 02:46:55 +00:00
|
|
|
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_info("device signature = 0x");
|
2009-10-10 20:09:56 +00:00
|
|
|
ff = zz = 1;
|
|
|
|
for (i=0; i<sig->size; i++) {
|
2022-10-17 14:44:55 +00:00
|
|
|
msg_info("%02x", sig->buf[i]);
|
2009-10-10 20:09:56 +00:00
|
|
|
if (sig->buf[i] != 0xff)
|
|
|
|
ff = 0;
|
|
|
|
if (sig->buf[i] != 0x00)
|
|
|
|
zz = 0;
|
|
|
|
}
|
2022-01-09 10:50:35 +00:00
|
|
|
|
|
|
|
bool signature_matches =
|
|
|
|
sig->size == 3 &&
|
|
|
|
sig->buf[0] == p->signature[0] &&
|
|
|
|
sig->buf[1] == p->signature[1] &&
|
|
|
|
sig->buf[2] == p->signature[2];
|
|
|
|
|
2014-08-18 21:43:08 +00:00
|
|
|
if (quell_progress < 2) {
|
|
|
|
AVRPART * part;
|
2022-10-17 14:44:55 +00:00
|
|
|
if((part = locate_part_by_signature(part_list, sig->buf, sig->size)))
|
|
|
|
msg_info(" (probably %s)", signature_matches ? p->id : part->id);
|
2014-08-18 21:43:08 +00:00
|
|
|
}
|
2009-10-10 20:09:56 +00:00
|
|
|
if (ff || zz) {
|
2012-04-20 12:33:15 +00:00
|
|
|
if (++attempt < 3) {
|
|
|
|
waittime *= 5;
|
2022-10-17 14:44:55 +00:00
|
|
|
msg_info(" (retrying)\n");
|
2012-04-20 12:33:15 +00:00
|
|
|
goto sig_again;
|
|
|
|
}
|
2022-10-17 14:44:55 +00:00
|
|
|
msg_info("\n");
|
|
|
|
pmsg_error("Yikes! Invalid device signature.\n");
|
2009-10-10 20:09:56 +00:00
|
|
|
if (!ovsigck) {
|
2022-10-17 14:44:55 +00:00
|
|
|
imsg_error("Double check connections and try again, or use -F to override\n");
|
|
|
|
imsg_error("this check.\n\n");
|
2009-10-10 20:09:56 +00:00
|
|
|
exitrc = 1;
|
|
|
|
goto main_exit;
|
|
|
|
}
|
2012-04-20 12:33:15 +00:00
|
|
|
} else {
|
2022-10-17 14:44:55 +00:00
|
|
|
msg_info("\n");
|
2001-11-21 02:46:55 +00:00
|
|
|
}
|
2012-04-20 12:33:15 +00:00
|
|
|
|
2022-01-09 10:50:35 +00:00
|
|
|
if (!signature_matches) {
|
2022-10-17 14:44:55 +00:00
|
|
|
if (ovsigck) {
|
|
|
|
pmsg_warning("expected signature for %s is %02X %02X %02X\n", p->desc,
|
|
|
|
p->signature[0], p->signature[1], p->signature[2]);
|
|
|
|
} else {
|
|
|
|
pmsg_error("expected signature for %s is %02X %02X %02X\n", p->desc,
|
|
|
|
p->signature[0], p->signature[1], p->signature[2]);
|
|
|
|
imsg_error("double check chip or use -F to override this check\n");
|
2012-04-20 12:33:15 +00:00
|
|
|
exitrc = 1;
|
|
|
|
goto main_exit;
|
|
|
|
}
|
2006-02-27 17:18:42 +00:00
|
|
|
}
|
2001-01-19 02:46:50 +00:00
|
|
|
}
|
|
|
|
}
|
2005-02-10 16:34:55 +00:00
|
|
|
|
2012-05-04 10:02:30 +00:00
|
|
|
if (uflags & UF_AUTO_ERASE) {
|
2022-08-30 15:33:42 +00:00
|
|
|
if ((p->prog_modes & PM_PDI) && pgm->page_erase && lsize(updates) > 0) {
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_info("Note: programmer supports page erase for Xmega devices.\n");
|
|
|
|
imsg_info("Each page will be erased before programming it, but no chip erase is performed.\n");
|
|
|
|
imsg_info("To disable page erases, specify the -D option; for a chip-erase, use the -e option.\n");
|
2012-05-04 10:02:30 +00:00
|
|
|
} else {
|
|
|
|
AVRMEM * m;
|
2022-08-30 15:33:42 +00:00
|
|
|
const char *memname = p->prog_modes & PM_PDI? "application": "flash";
|
2013-09-18 05:54:37 +00:00
|
|
|
|
|
|
|
uflags &= ~UF_AUTO_ERASE;
|
2012-05-04 10:02:30 +00:00
|
|
|
for (ln=lfirst(updates); ln; ln=lnext(ln)) {
|
|
|
|
upd = ldata(ln);
|
|
|
|
m = avr_locate_mem(p, upd->memtype);
|
|
|
|
if (m == NULL)
|
|
|
|
continue;
|
2022-08-15 13:57:04 +00:00
|
|
|
if ((strcmp(m->desc, memname) == 0) && (upd->op == DEVICE_WRITE)) {
|
2012-05-04 10:02:30 +00:00
|
|
|
erase = 1;
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_info("Note: %s memory has been specified, an erase cycle will be performed.\n", memname);
|
|
|
|
imsg_info("To disable this feature, specify the -D option.\n");
|
2012-05-04 10:02:30 +00:00
|
|
|
break;
|
2005-09-16 21:52:42 +00:00
|
|
|
}
|
2003-08-29 23:17:32 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-07-29 21:26:55 +00:00
|
|
|
if (init_ok && erase) {
|
2004-01-03 18:04:54 +00:00
|
|
|
/*
|
|
|
|
* erase the chip's flash and eeprom memories, this is required
|
|
|
|
* before the chip can accept new programming
|
|
|
|
*/
|
2012-05-04 10:02:30 +00:00
|
|
|
if (uflags & UF_NOWRITE) {
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_warning("conflicting -e and -n options specified, NOT erasing chip\n");
|
2008-11-04 12:10:28 +00:00
|
|
|
} else {
|
2022-11-10 23:18:43 +00:00
|
|
|
pmsg_info("erasing chip\n");
|
2009-10-10 20:09:56 +00:00
|
|
|
exitrc = avr_chip_erase(pgm, p);
|
2022-11-19 23:09:18 +00:00
|
|
|
if(exitrc == LIBAVRDUDE_SOFTFAIL) {
|
|
|
|
imsg_info("delaying chip erase until first -U upload to flash\n");
|
|
|
|
exitrc = 1;
|
|
|
|
} else if(exitrc)
|
2022-11-01 18:06:52 +00:00
|
|
|
goto main_exit;
|
2005-09-16 21:52:42 +00:00
|
|
|
}
|
2004-01-03 18:04:54 +00:00
|
|
|
}
|
|
|
|
|
2001-01-19 02:46:50 +00:00
|
|
|
if (terminal) {
|
|
|
|
/*
|
|
|
|
* terminal mode
|
2008-07-29 21:26:55 +00:00
|
|
|
*/
|
2002-11-30 14:09:12 +00:00
|
|
|
exitrc = terminal_mode(pgm, p);
|
2001-01-19 02:46:50 +00:00
|
|
|
}
|
|
|
|
|
2008-07-29 21:26:55 +00:00
|
|
|
if (!init_ok) {
|
|
|
|
/*
|
|
|
|
* If we came here by the -tF options, bail out now.
|
|
|
|
*/
|
|
|
|
exitrc = 1;
|
|
|
|
goto main_exit;
|
|
|
|
}
|
|
|
|
|
2001-01-20 16:34:28 +00:00
|
|
|
|
Introduce a new option, -U, for performing memory operions. Its
argument is a 4 field string (fields seperated by colons) which
indicate what memory type to operate on, what operation to perform is
(read, write, or verify), the filename to read from, write to, or
verify against, and an optional file format field. Multple -U options
can be specified to operate on more than one memory at a time with a
single invocation. For example, to update both the flash and the
eeprom at the same time one can now specify the following:
avrdude -p -e -U flash:w:main.hex:i -U eeprom:w:eeprom.hex:i
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk/avrdude@341 81a1dc3b-b13d-400b-aceb-764788c761c2
2003-08-21 04:52:36 +00:00
|
|
|
for (ln=lfirst(updates); ln; ln=lnext(ln)) {
|
|
|
|
upd = ldata(ln);
|
2012-05-04 10:02:30 +00:00
|
|
|
rc = do_op(pgm, p, upd, uflags);
|
2022-08-02 23:23:15 +00:00
|
|
|
if (rc && rc != LIBAVRDUDE_SOFTFAIL) {
|
2001-01-19 02:46:50 +00:00
|
|
|
exitrc = 1;
|
Introduce a new option, -U, for performing memory operions. Its
argument is a 4 field string (fields seperated by colons) which
indicate what memory type to operate on, what operation to perform is
(read, write, or verify), the filename to read from, write to, or
verify against, and an optional file format field. Multple -U options
can be specified to operate on more than one memory at a time with a
single invocation. For example, to update both the flash and the
eeprom at the same time one can now specify the following:
avrdude -p -e -U flash:w:main.hex:i -U eeprom:w:eeprom.hex:i
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk/avrdude@341 81a1dc3b-b13d-400b-aceb-764788c761c2
2003-08-21 04:52:36 +00:00
|
|
|
break;
|
2001-01-19 02:46:50 +00:00
|
|
|
}
|
|
|
|
}
|
2005-02-10 16:34:55 +00:00
|
|
|
|
|
|
|
main_exit:
|
2001-01-19 02:46:50 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* program complete
|
|
|
|
*/
|
2005-02-10 16:34:55 +00:00
|
|
|
|
2010-01-13 12:44:54 +00:00
|
|
|
if (is_open) {
|
|
|
|
pgm->powerdown(pgm);
|
2001-01-19 02:46:50 +00:00
|
|
|
|
2010-01-13 12:44:54 +00:00
|
|
|
pgm->disable(pgm);
|
2001-09-21 03:27:20 +00:00
|
|
|
|
2010-01-13 12:44:54 +00:00
|
|
|
pgm->rdy_led(pgm, OFF);
|
2001-02-08 01:42:09 +00:00
|
|
|
|
2014-02-27 07:35:15 +00:00
|
|
|
pgm->close(pgm);
|
|
|
|
}
|
2001-01-19 02:46:50 +00:00
|
|
|
|
2022-10-17 14:44:55 +00:00
|
|
|
msg_info("\n%s done. Thank you.\n\n", progname);
|
2001-01-19 02:46:50 +00:00
|
|
|
|
|
|
|
return exitrc;
|
|
|
|
}
|