Skip to content

Commit

Permalink
Merge pull request #1343 from stefanrueger/avrdude.conf
Browse files Browse the repository at this point in the history
Review avrdude.conf, add variants and reconcile with ATDFs
  • Loading branch information
stefanrueger authored Apr 20, 2023
2 parents c70a3e3 + 6d40f95 commit 545df08
Show file tree
Hide file tree
Showing 10 changed files with 5,492 additions and 261 deletions.
12 changes: 8 additions & 4 deletions src/avrdude.1
Original file line number Diff line number Diff line change
Expand Up @@ -325,16 +325,20 @@ need to be specified to
.Bl -tag -offset indent -width indent
.It Fl p Ar partno
This option specifies the MCU connected to the programmer. The MCU
descriptions are read from the config file. For currently supported MCUs use
? as partno, which will print a list of partno ids and official part names.
Both can be used with the -p option. If -p ? is specified with a specific
descriptions are read from the config file. To see a list of currently
supported MCUs use ? as partno, which will print the part ids and official
part names. In connection with -v, this will also print a list of variant
part names followed by an optional colon, the package code and some
absolute maximum ratings. The part id, their official part name, any of
the full variant part names or their initial part up to a dash can be used
to specify a part 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
Following parts need special attention:
The following parts need special attention:
.Bl -tag -width "ATmega1234"
.It "AT90S1200"
The ISP programming protocol of the AT90S1200 differs in subtle ways
Expand Down
5,510 changes: 5,297 additions & 213 deletions src/avrdude.conf.in

Large diffs are not rendered by default.

50 changes: 45 additions & 5 deletions src/avrpart.c
Original file line number Diff line number Diff line change
Expand Up @@ -329,7 +329,8 @@ static char * bittype(int type)
AVRMEM *avr_new_memtype(void) {
AVRMEM *m = (AVRMEM *) cfg_malloc("avr_new_memtype()", sizeof(*m));
m->desc = cache_string("");
m->page_size = 1; // ensure not 0
m->page_size = 1; // Ensure not 0
m->initval = -1; // Unknown value represented as -1

return m;
}
Expand Down Expand Up @@ -574,6 +575,7 @@ AVRPART *avr_new_part(void) {
p->config_file = nulp;
p->mem = lcreat(NULL, 0);
p->mem_alias = lcreat(NULL, 0);
p->variants = lcreat(NULL, 0);

// Default values
p->mcuid = -1;
Expand All @@ -597,10 +599,10 @@ AVRPART *avr_dup_part(const AVRPART *d) {
if(d) {
*p = *d;

// Duplicate the memory and alias chains
// Leave variants list empty but duplicate the memory and alias chains
p->variants = lcreat(NULL, 0);
p->mem = lcreat(NULL, 0);
p->mem_alias = lcreat(NULL, 0);

for(LNODEID ln=lfirst(d->mem); ln; ln=lnext(ln)) {
AVRMEM *m = ldata(ln);
AVRMEM *m2 = avr_dup_mem(m);
Expand Down Expand Up @@ -630,6 +632,9 @@ void avr_free_part(AVRPART * d)
d->mem = NULL;
ldestroy_cb(d->mem_alias, (void(*)(void *))avr_free_memalias);
d->mem_alias = NULL;
ldestroy_cb(d->variants, free);
d->variants = NULL;

/* do not free d->parent_id and d->config_file */
for(size_t i=0; i<sizeof(d->op)/sizeof(d->op[0]); i++) {
if (d->op[i] != NULL) {
Expand All @@ -649,8 +654,7 @@ AVRPART *locate_part(const LISTID parts, const char *partdesc) {

for (LNODEID ln1=lfirst(parts); ln1 && !found; ln1=lnext(ln1)) {
p = ldata(ln1);
if ((strcasecmp(partdesc, p->id) == 0) ||
(strcasecmp(partdesc, p->desc) == 0))
if(part_eq(p, partdesc, strcase_eq))
found = 1;
}

Expand Down Expand Up @@ -894,6 +898,42 @@ char *opcode2str(const OPCODE *op, int opnum, int detailed) {
}


int strcase_eq(const char *str1, const char *str2) {
return strcasecmp(str1, str2) == 0;
}

// Returns 1 if the part pointed to by p matches the string or pattern s under the function cmp(s, ...)
int part_eq(AVRPART *p, const char *s, int (*cmp)(const char *, const char *)) {
// Matching id or desc? OK
if(cmp(s, p->id) || cmp(s, p->desc))
return 1;

// Check against all variants, either up to colon or up to dash
size_t desclen = strlen(p->desc), variantlen, dashlen;
char query[1024];
for(LNODEID ln = lfirst(p->variants); ln; ln = lnext(ln)) {
const char *q = (const char *) ldata(ln), *qdash = strchr(q, '-'), *qcolon = strchr(q, ':');
variantlen = qcolon? (size_t) (qcolon-q): strlen(q);
dashlen = qdash? (size_t) (qdash-q): variantlen;
if(variantlen < sizeof query) { // Sanity: should not expect such long strings
// Variant names should be unique order numbers, but don't check (again) if it's the same as p->desc
if(variantlen != desclen || memcmp(q, p->desc, desclen)) {
memcpy(query, q, variantlen); query[variantlen] = 0;
if(cmp(s, query))
return 1;
// The name before dash should normally be p->desc and the dash is meant to come before the colon
if(dashlen > desclen && dashlen < variantlen) {
query[dashlen] = 0;
if(cmp(s, query))
return 1;
}
}
}
}
return 0;
}


/*
* Match STRING against the partname pattern PATTERN, returning 1 if it
* matches, 0 if not. NOTE: part_match() is a modified old copy of !fnmatch()
Expand Down
1 change: 1 addition & 0 deletions src/config.c
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,7 @@ Component_t avr_comp[] = {
mem_comp_desc(paged, COMP_BOOL),
mem_comp_desc(size, COMP_INT),
mem_comp_desc(num_pages, COMP_INT),
mem_comp_desc(initval, COMP_INT),
mem_comp_desc(n_word_writes, COMP_INT),
mem_comp_desc(offset, COMP_INT),
mem_comp_desc(min_write_delay, COMP_INT),
Expand Down
26 changes: 26 additions & 0 deletions src/config_gram.y
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ static int pin_name;
%token K_USB
%token K_USBPID
%token K_TYPE
%token K_VARIANTS
%token K_VCC
%token K_VFYLED

Expand Down Expand Up @@ -603,6 +604,31 @@ part_parm :
free_token($3);
} |

K_VARIANTS TKN_EQUAL K_NULL {
{
ldestroy_cb(current_part->variants, free);
current_part->variants = lcreat(NULL, 0);
}
} |

K_VARIANTS TKN_EQUAL string_list {
{
while (lsize(string_list)) {
TOKEN *t = lrmv_n(string_list, 1);
int found = 0;
for(LNODEID ln = lfirst(current_part->variants); ln; ln = lnext(ln)) {
if(!strcmp((char *) ldata(ln), t->value.string)) {
found = 1;
break;
}
}
if(!found)
ladd(current_part->variants, cfg_strdup("config_gram.y", t->value.string));
free_token(t);
}
}
} |

K_DEVICECODE TKN_EQUAL numexpr {
{
yyerror("devicecode is deprecated, will be removed in v8.0, use stk500_devcode instead");
Expand Down
72 changes: 65 additions & 7 deletions src/developer_opts.c
Original file line number Diff line number Diff line change
Expand Up @@ -496,6 +496,7 @@ typedef struct {
char descbuf[64];
char idbuf[32];
char family_idbuf[16];
char variants[4096-16-32-64];
AVRPART base;
OPCODE ops[AVR_OP_MAX];
AVRMEMdeep mems[40];
Expand All @@ -522,24 +523,28 @@ static int avrpart_deep_copy(AVRPARTdeep *d, const AVRPART *p) {
d->base.lineno = 0;

// Copy over desc, id, and family_id
memset(d->descbuf, 0, sizeof d->descbuf);
strncpy(d->descbuf, p->desc, sizeof d->descbuf-1);
memset(d->idbuf, 0, sizeof d->idbuf);
strncpy(d->idbuf, p->id, sizeof d->idbuf-1);
memset(d->family_idbuf, 0, sizeof d->family_idbuf);
strncpy(d->family_idbuf, p->family_id, sizeof d->family_idbuf-1);
char *vp = d->variants;
for(LNODEID ln=lfirst(p->variants); ln; ln=lnext(ln)) {
if(vp < d->variants+sizeof d->variants-2) {
strncpy(vp, (char *)ldata(ln), d->variants+sizeof d->variants-vp-1);
vp += strlen(vp)+1;
}
}

// Zap address values
d->base.desc = NULL;
d->base.id = NULL;
d->base.family_id = NULL;
d->base.mem = NULL;
d->base.mem_alias = NULL;
d->base.variants = NULL;
for(int i=0; i<AVR_OP_MAX; i++)
d->base.op[i] = NULL;

// Copy over all used SPI operations
memset(d->ops, 0, sizeof d->ops);
for(int i=0; i<AVR_OP_MAX; i++)
if(p->op[i])
d->ops[i] = *p->op[i];
Expand Down Expand Up @@ -603,6 +608,7 @@ static void dev_part_raw(const AVRPART *part) {
AVRPARTdeep dp;
int di = avrpart_deep_copy(&dp, part);

dev_raw_dump(&dp, (char *)&dp.base-(char *)&dp, part->desc, "part.intro", 0);
dev_raw_dump(&dp.base, sizeof dp.base, part->desc, "part", 0);
for(int i=0; i<AVR_OP_MAX; i++)
if(!_is_all_zero(dp.ops+i, sizeof*dp.ops))
Expand Down Expand Up @@ -644,6 +650,39 @@ static void dev_part_strct(const AVRPART *p, bool tsv, const AVRPART *base, bool

_if_partout_str(strcmp, descstr, desc);
_if_partout_str(strcmp, cfg_escape(p->id), id);

if(lsize(p->variants)) { // Variants are never inherited, so print if they exist
int firstid = 1;
if(tsv)
dev_info(".pt\t%s\tvariants\t", p->desc);
else {
dev_cout(p->comments, "variants", 0, 0);
dev_info(" %-22s =\n", "variants");
}
for(LNODEID ln=lfirst(p->variants); ln; ln=lnext(ln)) {
if(!firstid)
dev_info(tsv? ", ": ",\n");
firstid = 0;
char *str = cfg_escape(ldata(ln));
dev_info("%*s%s", tsv? 0: 8, "", str);
free(str);
}
if(tsv)
dev_info("\n");
else {
dev_info(";");
dev_cout(p->comments, "variants", 1, 1);
}
} else if(!base) { // Print NULL for /S option
if(tsv)
dev_info(".pt\t%s\tvariants\tNULL\n", p->desc);
else {
dev_cout(p->comments, "variants", 0, 0);
dev_info(" %-22s = NULL;\n", "variants");
dev_cout(p->comments, "variants", 1, 1);
}
}

_if_partout_str(strcmp, cfg_escape(p->family_id), family_id);
_if_partout_str(intcmp, cfg_strdup("dev_part_strct()", prog_modes_str(p->prog_modes)), prog_modes);
_if_partout(intcmp, "%d", mcuid);
Expand Down Expand Up @@ -761,8 +800,15 @@ static void dev_part_strct(const AVRPART *p, bool tsv, const AVRPART *base, bool
bm = avr_new_memtype();

if(!tsv) {
if(!memorycmp(bm, m)) // Same memory bit for bit, no need to instantiate
continue;
if(!memorycmp(bm, m)) { // Same memory bit for bit, only instantiate on injected parameters
int haveinjct = 0;
if(injct)
for(size_t i=0; i<sizeof meminj/sizeof*meminj; i++)
if(meminj[i].mcu && strcmp(meminj[i].mcu, p->desc) == 0 && strcmp(meminj[i].mem, m->desc) == 0)
haveinjct = 1;
if(!haveinjct)
continue;
}

dev_cout(m->comments, "*", 0, 1);
dev_info(" memory \"%s\"\n", m->desc);
Expand All @@ -772,6 +818,7 @@ static void dev_part_strct(const AVRPART *p, bool tsv, const AVRPART *base, bool
_if_memout(intcmp, m->size > 8192? "0x%x": "%d", size);
_if_memout(intcmp, "%d", page_size);
_if_memout(intcmp, "%d", num_pages);
_if_memout(intcmp, m->initval == -1? "%d": "0x%02x", initval);
_if_memout(intcmp, "%d", n_word_writes);
_if_memout(intcmp, "0x%x", offset);
_if_memout(intcmp, "%d", min_write_delay);
Expand Down Expand Up @@ -803,6 +850,17 @@ static void dev_part_strct(const AVRPART *p, bool tsv, const AVRPART *base, bool
for(LNODEID lnm=lfirst(p->mem_alias); lnm; lnm=lnext(lnm)) {
AVRMEM_ALIAS *ma = ldata(lnm);
if(ma->aliased_mem && !strcmp(ma->aliased_mem->desc, m->desc)) {
// There is a memory that's aliased to the current memory: is it inherited?
if(base) {
int basehasalias = 0;
for(LNODEID lnb=lfirst(base->mem_alias); lnb; lnb=lnext(lnb)) {
AVRMEM_ALIAS *mab = ldata(lnb);
if(!strcmp(mab->desc, ma->desc) && mab->aliased_mem && !strcmp(mab->aliased_mem->desc, m->desc))
basehasalias = 1;
}
if(basehasalias)
continue;
}
if(tsv)
dev_info(".ptmm\t%s\t%s\talias\t%s\n", p->desc, ma->desc, m->desc);
else
Expand Down Expand Up @@ -942,7 +1000,7 @@ void dev_output_part_defs(char *partdesc) {
nprinted = dev_nprinted;
}

if(!part_match(partdesc, p->desc) && !part_match(partdesc, p->id))
if(!part_eq(p, partdesc, part_match))
continue;

if(astrc || strct || cmpst)
Expand Down
Loading

0 comments on commit 545df08

Please sign in to comment.