Merge pull request #1099 from stefanrueger/prog_modes

Print compatible parts for programmer and vice versa using -c? or -p?
This commit is contained in:
Stefan Rueger 2022-09-24 13:23:12 +01:00 committed by GitHub
commit 94203eb441
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 460 additions and 160 deletions

View File

@ -301,10 +301,16 @@ need to be specified to
.Nm avrdude . .Nm avrdude .
.Bl -tag -offset indent -width indent .Bl -tag -offset indent -width indent
.It Fl p Ar partno .It Fl p Ar partno
This is the only option that is mandatory for every invocation of This option specifies the MCU connected to the programmer. The MCU
.Nm avrdude . descriptions are read from the config file. For currently supported MCUs use
It specifies the type of the MCU connected to the programmer. These are read from the config file. ? as partno, which will print a list of partno ids and official part names.
For currently supported MCU types use ? as partno, this will print a list of partno ids and official part names on the terminal. (Both can be used with the -p option.) Both can be used with the -p option. If -p ? is specified with a specific
programmer, see -c below, then only those parts are output that the
programmer expects to be able to handle, together with the programming
interface(s) that can be used in that combination. In reality there can be
deviations from this list, particularly if programming is directly via a
bootloader.
.Pp .Pp
Following parts need special attention: Following parts need special attention:
.Bl -tag -width "ATmega1234" .Bl -tag -width "ATmega1234"
@ -357,6 +363,11 @@ file to assign a default programmer to keep from having to specify
this option on every invocation. this option on every invocation.
A full list of all supported programmers is output to the terminal A full list of all supported programmers is output to the terminal
by using ? as programmer-id. by using ? as programmer-id.
If -c ? is specified with a specific part, see
-p above, then only those programmers are output that expect
to be able to handle this part, together with the programming interface(s) that can be
used in that combination. In reality there can be deviations from this list,
particularly if programming is directly via a bootloader.
.It Fl C Ar config-file .It Fl C Ar config-file
Use the specified config file to load configuration data. This file Use the specified config file to load configuration data. This file
contains all programmer and part definitions that contains all programmer and part definitions that

File diff suppressed because it is too large Load Diff

View File

@ -267,6 +267,9 @@ TOKEN *new_constant(const char *con) {
!strcmp("PM_HVPP", con)? PM_HVPP: !strcmp("PM_HVPP", con)? PM_HVPP:
!strcmp("PM_debugWIRE", con)? PM_debugWIRE: !strcmp("PM_debugWIRE", con)? PM_debugWIRE:
!strcmp("PM_JTAG", con)? PM_JTAG: !strcmp("PM_JTAG", con)? PM_JTAG:
!strcmp("PM_JTAGmkI", con)? PM_JTAGmkI:
!strcmp("PM_XMEGAJTAG", con)? PM_XMEGAJTAG:
!strcmp("PM_AVR32JTAG", con)? PM_AVR32JTAG:
!strcmp("PM_aWire", con)? PM_aWire: !strcmp("PM_aWire", con)? PM_aWire:
(assigned = 0); (assigned = 0);

View File

@ -1122,7 +1122,7 @@ part_parm :
if ($3->primary == K_YES) if ($3->primary == K_YES)
current_part->prog_modes |= PM_JTAG; current_part->prog_modes |= PM_JTAG;
else if ($3->primary == K_NO) else if ($3->primary == K_NO)
current_part->prog_modes &= ~PM_JTAG; current_part->prog_modes &= ~(PM_JTAG | PM_JTAGmkI | PM_XMEGAJTAG | PM_AVR32JTAG);
free_token($3); free_token($3);
} | } |

View File

@ -53,11 +53,18 @@
#include "developer_opts.h" #include "developer_opts.h"
#include "developer_opts_private.h" #include "developer_opts_private.h"
// Inject part parameters into a semi-automated rewrite of avrdude.conf // Inject part parameters into a semi-automated rewrite of avrdude.conf
// - Add entries to the tables below; they get written on -p*/i // - Add entries to the tables below; they get written on -p*/si or -c*/si
// - Use the output in a new avrdude.conf // - Use the output in a new avrdude.conf
// - Output again with -p* (no /i) and use that for final avrdude.conf // - Output again with -p* or -c* (no /i) and use that for final avrdude.conf
// - Remove entries from below tables // - Remove entries from below tables
static struct {
const char *pgmid, *var, *value;
} pgminj[] = {
// Add triples here, eg, {"stk500v2", "prog_modes", "PM_TPI|PM_ISP"},
{NULL, NULL, NULL},
};
static struct { static struct {
const char *mcu, *var, *value; const char *mcu, *var, *value;
@ -225,6 +232,12 @@ static char *prog_modes_str(int pm) {
strcat(type, " | PM_debugWIRE"); strcat(type, " | PM_debugWIRE");
if(pm & PM_JTAG) if(pm & PM_JTAG)
strcat(type, " | PM_JTAG"); strcat(type, " | PM_JTAG");
if(pm & PM_JTAGmkI)
strcat(type, " | PM_JTAGmkI");
if(pm & PM_XMEGAJTAG)
strcat(type, " | PM_XMEGAJTAG");
if(pm & PM_AVR32JTAG)
strcat(type, " | PM_AVR32JTAG");
if(pm & PM_aWire) if(pm & PM_aWire)
strcat(type, " | PM_aWire"); strcat(type, " | PM_aWire");
@ -812,7 +825,7 @@ void dev_output_pgm_part(int dev_opt_c, char *programmer, int dev_opt_p, char *p
} }
// -p */[dASsrcow*t] // -p */[dASsrcow*ti]
void dev_output_part_defs(char *partdesc) { void dev_output_part_defs(char *partdesc) {
bool cmdok, waits, opspi, descs, astrc, strct, cmpst, injct, raw, all, tsv; bool cmdok, waits, opspi, descs, astrc, strct, cmpst, injct, raw, all, tsv;
char *flags; char *flags;
@ -1171,7 +1184,7 @@ static const char *connstr(conntype_t conntype) {
} }
} }
static void dev_pgm_strct(const PROGRAMMER *pgm, bool tsv, const PROGRAMMER *base) { static void dev_pgm_strct(const PROGRAMMER *pgm, bool tsv, const PROGRAMMER *base, bool injct) {
char *id = ldata(lfirst(pgm->id)); char *id = ldata(lfirst(pgm->id));
LNODEID ln; LNODEID ln;
COMMENT *cp; COMMENT *cp;
@ -1289,6 +1302,14 @@ static void dev_pgm_strct(const PROGRAMMER *pgm, bool tsv, const PROGRAMMER *bas
} }
} }
if(injct)
for(size_t i=0; i<sizeof pgminj/sizeof*pgminj; i++)
if(pgminj[i].pgmid)
for(LNODEID *ln=lfirst(pgm->id); ln; ln=lnext(ln))
if(strcmp(pgminj[i].pgmid, ldata(ln)) == 0)
dev_part_strct_entry(tsv, ".prog", ldata(ln), NULL,
pgminj[i].var, cfg_strdup("pgminj", pgminj[i].value), NULL);
if(!tsv) { if(!tsv) {
dev_cout(pgm->comments, ";", 0, 0); dev_cout(pgm->comments, ";", 0, 0);
dev_info(";\n"); dev_info(";\n");
@ -1296,9 +1317,9 @@ static void dev_pgm_strct(const PROGRAMMER *pgm, bool tsv, const PROGRAMMER *bas
} }
// -c */[ASsrt] // -c */[ASsrti]
void dev_output_pgm_defs(char *pgmid) { void dev_output_pgm_defs(char *pgmid) {
bool astrc, strct, cmpst, raw, tsv; bool astrc, strct, cmpst, raw, tsv, injct;
char *flags; char *flags;
int nprinted; int nprinted;
PROGRAMMER *nullpgm = pgm_new(); PROGRAMMER *nullpgm = pgm_new();
@ -1309,7 +1330,7 @@ void dev_output_pgm_defs(char *pgmid) {
if(!flags && !strcmp(pgmid, "*")) // Treat -c * as if it was -c */s if(!flags && !strcmp(pgmid, "*")) // Treat -c * as if it was -c */s
flags = "s"; flags = "s";
if(!*flags || !strchr("ASsrt", *flags)) { if(!*flags || !strchr("ASsrti", *flags)) {
dev_info("%s: flags for developer option -c <wildcard>/<flags> not recognised\n", progname); dev_info("%s: flags for developer option -c <wildcard>/<flags> not recognised\n", progname);
dev_info( dev_info(
"Wildcard examples (these need protecting in the shell through quoting):\n" "Wildcard examples (these need protecting in the shell through quoting):\n"
@ -1323,6 +1344,7 @@ void dev_output_pgm_defs(char *pgmid) {
" s show short entries of avrdude.conf programmers using parent\n" " s show short entries of avrdude.conf programmers using parent\n"
" r show entries of avrdude.conf programmers as raw dump\n" " r show entries of avrdude.conf programmers as raw dump\n"
" t use tab separated values as much as possible\n" " t use tab separated values as much as possible\n"
" i inject assignments from source code table\n"
"Examples:\n" "Examples:\n"
" $ avrdude -c usbasp/s\n" " $ avrdude -c usbasp/s\n"
" $ avrdude -c */st | grep baudrate\n" " $ avrdude -c */st | grep baudrate\n"
@ -1343,6 +1365,7 @@ void dev_output_pgm_defs(char *pgmid) {
cmpst = !!strchr(flags, 's'); cmpst = !!strchr(flags, 's');
raw = !!strchr(flags, 'r'); raw = !!strchr(flags, 'r');
tsv = !!strchr(flags, 't'); tsv = !!strchr(flags, 't');
injct = !!strchr(flags, 'i');
nprinted = dev_nprinted; nprinted = dev_nprinted;
@ -1368,7 +1391,8 @@ void dev_output_pgm_defs(char *pgmid) {
dev_pgm_strct(pgm, tsv, dev_pgm_strct(pgm, tsv,
astrc? NULL: astrc? NULL:
strct? nullpgm: strct? nullpgm:
pgm->parent_id && *pgm->parent_id? locate_programmer(programmers, pgm->parent_id): nullpgm); pgm->parent_id && *pgm->parent_id? locate_programmer(programmers, pgm->parent_id): nullpgm,
injct);
if(raw) if(raw)
dev_pgm_raw(pgm); dev_pgm_raw(pgm);

View File

@ -399,14 +399,19 @@ following options are recognized:
@table @code @table @code
@item -p @var{partno} @item -p @var{partno}
This is the only mandatory option and it tells AVRDUDE what type of part This option tells AVRDUDE what part (MCU) is connected to the programmer.
(MCU) that is connected to the programmer. The @var{partno} parameter The @var{partno} parameter is the part's id listed in the configuration file.
is the part's id listed in the configuration file. Specify -p ? to list For currently supported MCU types use ? as partno, which will print a list of
all parts in the configuration file. If a part is unknown partno ids and official part names on the terminal. Both can be used with the
to AVRDUDE, it means that there is no config file entry for that part, -p option. If a part is unknown to AVRDUDE, it means that there is no config
but it can be added to the configuration file if you have the Atmel file entry for that part, but it can be added to the configuration file if
datasheet so that you can enter the programming specifications. you have the Atmel datasheet so that you can enter the programming
Currently, the following MCU types are understood: specifications. If @code{-p ?} is specified with a specific programmer, see
@code{-c} below, then only those parts are output that the programmer expects
to be able to handle, together with the programming interface(s) that can be
used in that combination. In reality there can be deviations from this list,
particularly if programming is directly via a bootloader. Currently, the
following MCU types are understood:
@cindex Device support @cindex Device support
@ -459,7 +464,12 @@ AVRDUDE, and the programmer is controlled via the PC parallel port,
there's a good chance that it can be easily added to the configuration there's a good chance that it can be easily added to the configuration
file without any code changes to AVRDUDE. Simply copy an existing entry file without any code changes to AVRDUDE. Simply copy an existing entry
and change the pin definitions to match that of the unknown programmer. and change the pin definitions to match that of the unknown programmer.
Currently, the following programmer ids are understood and supported: If @code{-c ?} is specified with a specific part, see @code{-p} above, then
only those programmers are output that expect to be able to handle this part,
together with the programming interface(s) that can be used in that
combination. In reality there can be deviations from this list, particularly
if programming is directly via a bootloader. Currently, the following
programmer ids are understood and supported:
@cindex Programmer support @cindex Programmer support
@ -1737,7 +1747,10 @@ Known programming modes are
@item @code{PM_HVSP}: High Voltage Serial Programming (some classic parts) @item @code{PM_HVSP}: High Voltage Serial Programming (some classic parts)
@item @code{PM_HVPP}: High Voltage Parallel Programming (most non-HVSP classic parts) @item @code{PM_HVPP}: High Voltage Parallel Programming (most non-HVSP classic parts)
@item @code{PM_debugWIRE}: Simpler alternative to JTAG (a subset of HVPP/HVSP parts) @item @code{PM_debugWIRE}: Simpler alternative to JTAG (a subset of HVPP/HVSP parts)
@item @code{PM_JTAG}: Joint Test Action Group standard (some classic parts, some xmega) @item @code{PM_JTAG}: Joint Test Action Group standard (some classic parts)
@item @code{PM_JTAGmkI}: Subset of @code{PM_JTAG}, older parts, Atmel ICE mkI
@item @code{PM_XMEGAJTAG}: JTAG, some XMEGA parts
@item @code{PM_AVR32JTAG}: JTAG for 32-bit AVRs
@item @code{PM_aWire}: AVR32 parts @item @code{PM_aWire}: AVR32 parts
@end itemize @end itemize

View File

@ -1076,7 +1076,7 @@ static int jtag3_initialize(const PROGRAMMER *pgm, const AVRPART *p) {
conn = PARM3_CONN_UPDI; conn = PARM3_CONN_UPDI;
} else { } else {
ifname = "JTAG"; ifname = "JTAG";
if (p->prog_modes & PM_JTAG) if (p->prog_modes & (PM_JTAG | PM_JTAGmkI | PM_XMEGAJTAG | PM_AVR32JTAG))
conn = PARM3_CONN_JTAG; conn = PARM3_CONN_JTAG;
} }
@ -1376,7 +1376,7 @@ static int jtag3_initialize(const PROGRAMMER *pgm, const AVRPART *p) {
} }
if (use_ext_reset > 1) { if (use_ext_reset > 1) {
if(strcmp(pgm->type, "JTAGICE3") == 0 && (p->prog_modes & PM_JTAG)) if(strcmp(pgm->type, "JTAGICE3") == 0 && (p->prog_modes & (PM_JTAG | PM_JTAGmkI | PM_XMEGAJTAG | PM_AVR32JTAG)))
avrdude_message(MSG_INFO, "%s: JTAGEN fuse disabled?\n", progname); avrdude_message(MSG_INFO, "%s: JTAGEN fuse disabled?\n", progname);
return -1; return -1;
} }

View File

@ -523,11 +523,14 @@ static int jtagmkI_initialize(const PROGRAMMER *pgm, const AVRPART *p) {
unsigned char cmd[1], resp[5]; unsigned char cmd[1], resp[5];
unsigned char b; unsigned char b;
if (!(p->prog_modes & PM_JTAG)) { if (!(p->prog_modes & (PM_JTAGmkI | PM_JTAG))) {
avrdude_message(MSG_INFO, "%s: jtagmkI_initialize(): part %s has no JTAG interface\n", avrdude_message(MSG_INFO, "%s: jtagmkI_initialize(): part %s has no JTAG interface\n",
progname, p->desc); progname, p->desc);
return -1; return -1;
} }
if (!(p->prog_modes & PM_JTAGmkI))
avrdude_message(MSG_INFO, "%s: jtagmkI_initialize(): warning part %s has JTAG interface, but may be too new\n",
progname, p->desc);
jtagmkI_drain(pgm, 0); jtagmkI_drain(pgm, 0);

View File

@ -1308,7 +1308,7 @@ static int jtagmkII_initialize(const PROGRAMMER *pgm, const AVRPART *p) {
ok = 1; ok = 1;
} else { } else {
ifname = "JTAG"; ifname = "JTAG";
if (p->prog_modes & PM_JTAG) if (p->prog_modes & (PM_JTAG | PM_JTAGmkI | PM_XMEGAJTAG | PM_AVR32JTAG))
ok = 1; ok = 1;
} }

View File

@ -133,7 +133,7 @@ prog_modes|mcuid|n_interrupts|n_page_erase { /* Components for assignment */
return TKN_COMPONENT; return TKN_COMPONENT;
} }
PM_SPM|PM_TPI|PM_ISP|PM_PDI|PM_UPDI|PM_HVSP|PM_HVPP|PM_debugWIRE|PM_JTAG|PM_aWire { /* Constants */ PM_(SPM|TPI|ISP|PDI|UPDI|HVSP|HVPP|debugWIRE|JTAG|JTAGmkI|XMEGAJTAG|AVR32JTAG|aWire) { /* Constants */
yylval = new_constant(yytext); yylval = new_constant(yytext);
return TKN_NUMBER; return TKN_NUMBER;
} }

View File

@ -201,8 +201,11 @@ typedef struct opcode {
#define PM_HVSP 32 // High Voltage Serial Programming (some classic parts) #define PM_HVSP 32 // High Voltage Serial Programming (some classic parts)
#define PM_HVPP 64 // High Voltage Parallel Programming (most non-HVSP classic parts) #define PM_HVPP 64 // High Voltage Parallel Programming (most non-HVSP classic parts)
#define PM_debugWIRE 128 // Simpler alternative to JTAG (a subset of HVPP/HVSP parts) #define PM_debugWIRE 128 // Simpler alternative to JTAG (a subset of HVPP/HVSP parts)
#define PM_JTAG 256 // Joint Test Action Group standard (some classic parts, some xmega) #define PM_JTAG 256 // Joint Test Action Group standard (some classic parts)
#define PM_aWire 512 // AVR32 parts #define PM_JTAGmkI 512 // Subset of PM_JTAG, older parts, Atmel ICE mkI
#define PM_XMEGAJTAG 1024 // JTAG, some XMEGA parts
#define PM_AVR32JTAG 2048 // JTAG for 32-bit AVRs
#define PM_aWire 4096 // For 32-bit AVRs
#define HV_UPDI_VARIANT_0 0 /* Shared UPDI/GPIO/RESET pin, HV on UPDI pin (tinyAVR0/1/2)*/ #define HV_UPDI_VARIANT_0 0 /* Shared UPDI/GPIO/RESET pin, HV on UPDI pin (tinyAVR0/1/2)*/
#define HV_UPDI_VARIANT_1 1 /* Dedicated UPDI pin, no HV (megaAVR0/AVR-Dx) */ #define HV_UPDI_VARIANT_1 1 /* Dedicated UPDI pin, no HV (megaAVR0/AVR-Dx) */

View File

@ -130,39 +130,122 @@ static void usage(void)
" -q Quell progress output. -q -q for less.\n" " -q Quell progress output. -q -q for less.\n"
" -l logfile Use logfile rather than stderr for diagnostics.\n" " -l logfile Use logfile rather than stderr for diagnostics.\n"
" -? Display this usage.\n" " -? Display this usage.\n"
"\navrdude version %s, URL: <https://github.com/avrdudes/avrdude>\n" "\navrdude version %s, URL: <https://github.com/avrdudes/avrdude>\n",
,progname, version); progname, version);
} }
static void list_programmers_callback(const char *name, const char *desc, static char *via_prog_modes(int pm) {
const char *cfgname, int cfglineno, static char type[1024];
void *cookie)
{
struct list_walk_cookie *c = (struct list_walk_cookie *)cookie;
if (*name == 0 || *name == '.') strcpy(type, "?");
return; 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");
if(pm & PM_JTAGmkI)
strcat(type, ", JTAGmkI");
if(pm & PM_XMEGAJTAG)
strcat(type, ", XMEGAJTAG");
if(pm & PM_AVR32JTAG)
strcat(type, ", AVR32JTAG");
if(pm & PM_aWire)
strcat(type, ", aWire");
if (verbose){ return type + (type[1] == 0? 0: 3);
fprintf(c->f, "%s%-16s = %-30s [%s:%d]\n", }
c->prefix, name, desc, cfgname, cfglineno);
} else {
fprintf(c->f, "%s%-16s = %-s\n", // Potentially shorten copy of prog description if it's the suggested mode
c->prefix, name, desc); 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"},
{" for bootloader", "bootloader"},
};
size_t len = strlen(desc);
for(size_t i=0; i<sizeof pairs/sizeof*pairs; i++) {
size_t elen = strlen(pairs[i].end);
if(len > elen && strcasecmp(desc+len-elen, pairs[i].end) == 0 && strcmp(modes, pairs[i].mode) == 0) {
desc[len-elen] = 0;
break;
} }
}
} }
static void list_programmers(FILE * f, const char *prefix, LISTID programmers) static void list_programmers(FILE *f, const char *prefix, LISTID programmers, int pm) {
{ LNODEID ln1;
struct list_walk_cookie c; LNODEID ln2;
PROGRAMMER *pgm;
int maxlen=0, len;
c.f = f; sort_programmers(programmers);
c.prefix = prefix;
sort_programmers(programmers); // Compute max length of programmer names
for(ln1 = lfirst(programmers); ln1; ln1 = lnext(ln1)) {
pgm = ldata(ln1);
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;
}
}
walk_programmers(programmers, list_programmers_callback, &c); for(ln1 = lfirst(programmers); ln1; ln1 = lnext(ln1)) {
pgm = ldata(ln1);
for(ln2=lfirst(pgm->id); ln2; ln2=lnext(ln2)) {
// 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);
char *desc = cfg_strdup("list_programmers()", pgm->desc);
const char *modes = via_prog_modes(pm & pgm->prog_modes);
if(pm != ~0)
pmshorten(desc, modes);
if(*id == 0 || *id == '.')
continue;
if(verbose)
fprintf(f, "%s%-*s = %-30s [%s:%d]", prefix, maxlen, id, desc, pgm->config_file, pgm->lineno);
else
fprintf(f, "%s%-*s = %-s", prefix, maxlen, id, desc);
if(pm != ~0)
fprintf(f, " via %s", modes);
fprintf(f, "\n");
free(desc);
}
}
}
} }
static void list_programmer_types_callback(const char *name, const char *desc, static void list_programmer_types_callback(const char *name, const char *desc,
@ -183,35 +266,42 @@ static void list_programmer_types(FILE * f, const char *prefix)
walk_programmer_types(list_programmer_types_callback, &c); walk_programmer_types(list_programmer_types_callback, &c);
} }
static void list_avrparts_callback(const char *name, const char *desc,
const char *cfgname, int cfglineno,
void *cookie)
{
struct list_walk_cookie *c = (struct list_walk_cookie *)cookie;
/* hide ids starting with '.' */ static void list_parts(FILE *f, const char *prefix, LISTID avrparts, int pm) {
if ((verbose < 2) && (name[0] == '.')) LNODEID ln1;
return; AVRPART *p;
int maxlen=0, len;
if (verbose) { sort_avrparts(avrparts);
fprintf(c->f, "%s%-8s = %-18s [%s:%d]\n",
c->prefix, name, desc, cfgname, cfglineno); // Compute max length of part names
} else { for(ln1 = lfirst(avrparts); ln1; ln1 = lnext(ln1)) {
fprintf(c->f, "%s%-8s = %s\n", p = ldata(ln1);
c->prefix, name, desc); // List part if pm or prog_modes uninitialised or if they are compatible otherwise
if(!pm || !p->prog_modes || (pm & p->prog_modes)) {
if((verbose < 2) && (p->id[0] == '.')) // hide ids starting with '.'
continue;
if((len = strlen(p->id)) > maxlen)
maxlen = len;
} }
} }
static void list_parts(FILE * f, const char *prefix, LISTID avrparts)
{
struct list_walk_cookie c;
c.f = f; for(ln1 = lfirst(avrparts); ln1; ln1 = lnext(ln1)) {
c.prefix = prefix; p = ldata(ln1);
// List part if pm or prog_modes uninitialised or if they are compatible otherwise
sort_avrparts(avrparts); if(!pm || !p->prog_modes || (pm & p->prog_modes)) {
if((verbose < 2) && (p->id[0] == '.')) // hide ids starting with '.'
walk_avrparts(avrparts, list_avrparts_callback, &c); continue;
if(verbose)
fprintf(f, "%s%-*s = %-18s [%s:%d]", prefix, maxlen, p->id, p->desc, p->config_file, p->lineno);
else
fprintf(f, "%s%-*s = %s", prefix, maxlen, p->id, p->desc);
if(pm != ~0)
fprintf(f, " via %s", via_prog_modes(pm & p->prog_modes));
fprintf(f, "\n");
}
}
} }
static void exithook(void) static void exithook(void)
@ -257,6 +347,35 @@ static int dev_opt(char *str) {
} }
static void exit_programmer_not_found(const char *programmer) {
if(programmer && *programmer)
avrdude_message(MSG_INFO, "\n%s: cannot find programmer id %s\n", progname, programmer);
else
avrdude_message(MSG_INFO, "\n%s: no programmer has been specified on the command line "
"or in the\n%sconfig file; specify one using the -c option and try again\n",
progname, progbuf);
avrdude_message(MSG_INFO, "\nValid programmers are:\n");
list_programmers(stderr, " ", programmers, ~0);
avrdude_message(MSG_INFO, "\n");
exit(1);
}
static void exit_part_not_found(const char *partdesc) {
if(partdesc && *partdesc)
avrdude_message(MSG_INFO, "\n%s: AVR part %s not found\n", progname, partdesc);
else
avrdude_message(MSG_INFO, "\n%s: no AVR part has been specified; use -p part\n", progname);
avrdude_message(MSG_INFO, "\nValid parts are:\n");
list_parts(stderr, " ", part_list, ~0);
avrdude_message(MSG_INFO, "\n");
exit(1);
}
/* /*
* main routine * main routine
*/ */
@ -773,13 +892,29 @@ int main(int argc, char * argv [])
exit(0); exit(0);
} }
avrdude_message(MSG_NOTICE, "\n"); 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))
avrdude_message(MSG_INFO, "%s warning: %s and %s share multiple modes (%s)\n",
progname, pgm->id? ldata(lfirst(pgm->id)): "???", p->desc, via_prog_modes(pm));
}
}
if (partdesc) { if (partdesc) {
if (strcmp(partdesc, "?") == 0) { if (strcmp(partdesc, "?") == 0) {
avrdude_message(MSG_INFO, "\n"); if(programmer && *programmer) {
avrdude_message(MSG_INFO, "Valid parts are:\n"); PROGRAMMER *pgm = locate_programmer(programmers, programmer);
list_parts(stderr, " ", part_list); if(!pgm)
exit_programmer_not_found(programmer);
avrdude_message(MSG_INFO, "\nValid parts for programmer %s are:\n", programmer);
list_parts(stderr, " ", part_list, pgm->prog_modes);
} else {
avrdude_message(MSG_INFO, "\nValid parts are:\n");
list_parts(stderr, " ", part_list, ~0);
}
avrdude_message(MSG_INFO, "\n"); avrdude_message(MSG_INFO, "\n");
exit(1); exit(1);
} }
@ -787,47 +922,41 @@ int main(int argc, char * argv [])
if (programmer) { if (programmer) {
if (strcmp(programmer, "?") == 0) { if (strcmp(programmer, "?") == 0) {
avrdude_message(MSG_INFO, "\n"); if(partdesc && *partdesc) {
avrdude_message(MSG_INFO, "Valid programmers are:\n"); AVRPART *p = locate_part(part_list, partdesc);
list_programmers(stderr, " ", programmers); if(!p)
exit_part_not_found(partdesc);
avrdude_message(MSG_INFO, "\nValid programmers for part %s are:\n", p->desc);
list_programmers(stderr, " ", programmers, p->prog_modes);
} else {
avrdude_message(MSG_INFO, "\nValid programmers are:\n");
list_programmers(stderr, " ", programmers, ~0);
}
avrdude_message(MSG_INFO, "\n"); avrdude_message(MSG_INFO, "\n");
exit(1); exit(1);
} }
if (strcmp(programmer, "?type") == 0) { if (strcmp(programmer, "?type") == 0) {
avrdude_message(MSG_INFO, "\n"); avrdude_message(MSG_INFO, "\nValid programmer types are:\n");
avrdude_message(MSG_INFO, "Valid programmer types are:\n");
list_programmer_types(stderr, " "); list_programmer_types(stderr, " ");
avrdude_message(MSG_INFO, "\n"); avrdude_message(MSG_INFO, "\n");
exit(1); exit(1);
} }
} }
avrdude_message(MSG_NOTICE, "\n");
if (programmer[0] == 0) { if (!programmer || !*programmer)
avrdude_message(MSG_INFO, "\n%s: no programmer has been specified on the command line " exit_programmer_not_found(NULL);
"or the config file\n",
progname);
avrdude_message(MSG_INFO, "%sSpecify a programmer using the -c option and try again\n\n",
progbuf);
exit(1);
}
pgm = locate_programmer(programmers, programmer); pgm = locate_programmer(programmers, programmer);
if (pgm == NULL) { if (pgm == NULL)
avrdude_message(MSG_INFO, "\n"); exit_programmer_not_found(programmer);
avrdude_message(MSG_INFO, "%s: Can't find programmer id \"%s\"\n",
progname, programmer);
avrdude_message(MSG_INFO, "\nValid programmers are:\n");
list_programmers(stderr, " ", programmers);
avrdude_message(MSG_INFO, "\n");
exit(1);
}
if (pgm->initpgm) { if (pgm->initpgm) {
pgm->initpgm(pgm); pgm->initpgm(pgm);
} else { } else {
avrdude_message(MSG_INFO, "\n%s: Can't initialize the programmer.\n\n", avrdude_message(MSG_INFO, "\n%s: cannot initialize the programmer\n\n", progname);
progname);
exit(1); exit(1);
} }
@ -876,24 +1005,12 @@ int main(int argc, char * argv [])
} }
if (partdesc == NULL) { if (partdesc == NULL)
avrdude_message(MSG_INFO, "%s: No AVR part has been specified, use \"-p Part\"\n\n", exit_part_not_found(NULL);
progname);
avrdude_message(MSG_INFO, "Valid parts are:\n");
list_parts(stderr, " ", part_list);
avrdude_message(MSG_INFO, "\n");
exit(1);
}
p = locate_part(part_list, partdesc); p = locate_part(part_list, partdesc);
if (p == NULL) { if (p == NULL)
avrdude_message(MSG_INFO, "%s: AVR Part \"%s\" not found.\n\n", exit_part_not_found(partdesc);
progname, partdesc);
avrdude_message(MSG_INFO, "Valid parts are:\n");
list_parts(stderr, " ", part_list);
avrdude_message(MSG_INFO, "\n");
exit(1);
}
if (exitspecs != NULL) { if (exitspecs != NULL) {
if (pgm->parseexitspecs == NULL) { if (pgm->parseexitspecs == NULL) {

View File

@ -1316,7 +1316,7 @@ static int stk500v2_jtag3_initialize(const PROGRAMMER *pgm, const AVRPART *p) {
LNODEID ln; LNODEID ln;
AVRMEM * m; AVRMEM * m;
// FIXME: condition below looks fishy, suspect the code wants !(p->prog_modes & (PM_debugWIRE | PM_JTAG)) // FIXME: condition below looks fishy, suspect the code wants !(p->prog_modes & (PM_debugWIRE | PM_JTAG | PM_JTAGmkI /* | PM_XMEGAJTAG | PM_AVR32JTAG */))
if (p->prog_modes & (PM_PDI | PM_TPI)) { if (p->prog_modes & (PM_PDI | PM_TPI)) {
avrdude_message(MSG_INFO, "%s: jtag3_initialize(): part %s has no ISP interface\n", avrdude_message(MSG_INFO, "%s: jtag3_initialize(): part %s has no ISP interface\n",
progname, p->desc); progname, p->desc);