Merge pull request #1091 from stefanrueger/config_file

Add new components in `avrdude.conf.in`
This commit is contained in:
Stefan Rueger 2022-08-31 17:27:05 +01:00 committed by GitHub
commit 0d1b49a4e4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
28 changed files with 8370 additions and 486 deletions

View File

@ -252,6 +252,8 @@ add_executable(avrdude
main.c main.c
term.c term.c
term.h term.h
avrintel.c
avrintel.h
developer_opts.c developer_opts.c
developer_opts.h developer_opts.h
developer_opts_private.h developer_opts_private.h

View File

@ -198,6 +198,8 @@ avrdude_SOURCES = \
main.c \ main.c \
whereami.c \ whereami.c \
whereami.h \ whereami.h \
avrintel.c \
avrintel.h \
developer_opts.c \ developer_opts.c \
developer_opts.h \ developer_opts.h \
developer_opts_private.h \ developer_opts_private.h \

View File

@ -52,7 +52,7 @@ int avr_tpi_chip_erase(const PROGRAMMER *pgm, const AVRPART *p) {
int err; int err;
AVRMEM *mem; AVRMEM *mem;
if (p->flags & AVRPART_HAS_TPI) { if (p->prog_modes & PM_TPI) {
pgm->pgm_led(pgm, ON); pgm->pgm_led(pgm, ON);
/* Set Pointer Register */ /* Set Pointer Register */
@ -102,7 +102,7 @@ int avr_tpi_program_enable(const PROGRAMMER *pgm, const AVRPART *p, unsigned cha
unsigned char cmd[2]; unsigned char cmd[2];
unsigned char response; unsigned char response;
if(p->flags & AVRPART_HAS_TPI) { if(p->prog_modes & PM_TPI) {
/* set guard time */ /* set guard time */
cmd[0] = (TPI_CMD_SSTCS | TPI_REG_TPIPCR); cmd[0] = (TPI_CMD_SSTCS | TPI_REG_TPIPCR);
cmd[1] = guard_time; cmd[1] = guard_time;
@ -194,7 +194,7 @@ int avr_read_byte_default(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM
pgm->pgm_led(pgm, ON); pgm->pgm_led(pgm, ON);
pgm->err_led(pgm, OFF); pgm->err_led(pgm, OFF);
if (p->flags & AVRPART_HAS_TPI) { if (p->prog_modes & PM_TPI) {
if (pgm->cmd_tpi == NULL) { if (pgm->cmd_tpi == NULL) {
avrdude_message(MSG_INFO, "%s: Error: %s programmer does not support TPI\n", avrdude_message(MSG_INFO, "%s: Error: %s programmer does not support TPI\n",
progname, pgm->type); progname, pgm->type);
@ -342,7 +342,7 @@ int avr_read(const PROGRAMMER *pgm, const AVRPART *p, const char *memtype,
memset(mem->buf, 0xff, mem->size); memset(mem->buf, 0xff, mem->size);
/* supports "paged load" thru post-increment */ /* supports "paged load" thru post-increment */
if ((p->flags & AVRPART_HAS_TPI) && mem->page_size > 1 && if ((p->prog_modes & PM_TPI) && mem->page_size > 1 &&
mem->size % mem->page_size == 0 && pgm->cmd_tpi != NULL) { mem->size % mem->page_size == 0 && pgm->cmd_tpi != NULL) {
while (avr_tpi_poll_nvmbsy(pgm)); while (avr_tpi_poll_nvmbsy(pgm));
@ -550,7 +550,7 @@ int avr_write_byte_default(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM
return -1; return -1;
} }
if (p->flags & AVRPART_HAS_TPI) { if (p->prog_modes & PM_TPI) {
if (pgm->cmd_tpi == NULL) { if (pgm->cmd_tpi == NULL) {
avrdude_message(MSG_INFO, "%s: Error: %s programmer does not support TPI\n", avrdude_message(MSG_INFO, "%s: Error: %s programmer does not support TPI\n",
progname, pgm->type); progname, pgm->type);
@ -596,8 +596,7 @@ int avr_write_byte_default(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM
return 0; return 0;
} }
if (!mem->paged && if (!mem->paged && (p->flags & AVRPART_IS_AT90S1200) == 0) {
(p->flags & AVRPART_IS_AT90S1200) == 0) {
/* /*
* check to see if the write is necessary by reading the existing * check to see if the write is necessary by reading the existing
* value and only write if we are changing the value; we can't * value and only write if we are changing the value; we can't
@ -839,9 +838,7 @@ int avr_write(const PROGRAMMER *pgm, const AVRPART *p, const char *memtype,
} }
if ((p->flags & AVRPART_HAS_TPI) && m->page_size > 1 && if ((p->prog_modes & PM_TPI) && m->page_size > 1 && pgm->cmd_tpi) {
pgm->cmd_tpi != NULL) {
if (wsize == 1) { if (wsize == 1) {
/* fuse (configuration) memory: only single byte to write */ /* fuse (configuration) memory: only single byte to write */
return avr_write_byte(pgm, p, m, 0, m->buf[0]) == 0? 1: -1; return avr_write_byte(pgm, p, m, 0, m->buf[0]) == 0? 1: -1;

File diff suppressed because it is too large Load Diff

View File

@ -267,7 +267,7 @@ static void avrftdi_enable(PROGRAMMER *pgm, const AVRPART *p) {
set_pin(pgm, PPI_AVR_BUFF, ON); set_pin(pgm, PPI_AVR_BUFF, ON);
// Switch to TPI initialisation in avrftdi_tpi.c // Switch to TPI initialisation in avrftdi_tpi.c
if(p->flags & AVRPART_HAS_TPI) if(p->prog_modes & PM_TPI)
avrftdi_tpi_initpgm(pgm); avrftdi_tpi_initpgm(pgm);
} }
@ -808,7 +808,7 @@ static void avrftdi_close(PROGRAMMER * pgm)
static int avrftdi_initialize(const PROGRAMMER *pgm, const AVRPART *p) { static int avrftdi_initialize(const PROGRAMMER *pgm, const AVRPART *p) {
avrftdi_powerup(pgm); avrftdi_powerup(pgm);
if(p->flags & AVRPART_HAS_TPI) if(p->prog_modes & PM_TPI)
{ {
/* see avrftdi_tpi.c */ /* see avrftdi_tpi.c */
avrftdi_tpi_initialize(pgm, p); avrftdi_tpi_initialize(pgm, p);

5458
src/avrintel.c Normal file

File diff suppressed because it is too large Load Diff

1477
src/avrintel.h Normal file

File diff suppressed because it is too large Load Diff

View File

@ -583,6 +583,7 @@ AVRPART *avr_new_part(void) {
p->mem_alias = lcreat(NULL, 0); p->mem_alias = lcreat(NULL, 0);
// Default values // Default values
p->mcuid = -1;
p->hvupdi_variant = -1; p->hvupdi_variant = -1;
memset(p->signature, 0xFF, 3); memset(p->signature, 0xFF, 3);
p->reset_disposition = RESET_DEDICATED; p->reset_disposition = RESET_DEDICATED;

View File

@ -422,7 +422,7 @@ int bitbang_chip_erase(const PROGRAMMER *pgm, const AVRPART *p) {
unsigned char res[4]; unsigned char res[4];
AVRMEM *mem; AVRMEM *mem;
if (p->flags & AVRPART_HAS_TPI) { if (p->prog_modes & PM_TPI) {
pgm->pgm_led(pgm, ON); pgm->pgm_led(pgm, ON);
while (avr_tpi_poll_nvmbsy(pgm)); while (avr_tpi_poll_nvmbsy(pgm));
@ -482,7 +482,7 @@ int bitbang_program_enable(const PROGRAMMER *pgm, const AVRPART *p) {
unsigned char res[4]; unsigned char res[4];
int i; int i;
if (p->flags & AVRPART_HAS_TPI) { if (p->prog_modes & PM_TPI) {
/* enable NVM programming */ /* enable NVM programming */
bitbang_tpi_tx(pgm, TPI_CMD_SKEY); bitbang_tpi_tx(pgm, TPI_CMD_SKEY);
for (i = sizeof(tpi_skey) - 1; i >= 0; i--) for (i = sizeof(tpi_skey) - 1; i >= 0; i--)
@ -524,7 +524,7 @@ int bitbang_initialize(const PROGRAMMER *pgm, const AVRPART *p) {
usleep(20000); usleep(20000);
/* TPIDATA is a single line, so MISO & MOSI should be connected */ /* TPIDATA is a single line, so MISO & MOSI should be connected */
if (p->flags & AVRPART_HAS_TPI) { if (p->prog_modes & PM_TPI) {
/* make sure cmd_tpi() is defined */ /* make sure cmd_tpi() is defined */
if (pgm->cmd_tpi == NULL) { if (pgm->cmd_tpi == NULL) {
avrdude_message(MSG_INFO, "%s: Error: %s programmer does not support TPI\n", avrdude_message(MSG_INFO, "%s: Error: %s programmer does not support TPI\n",
@ -559,7 +559,7 @@ int bitbang_initialize(const PROGRAMMER *pgm, const AVRPART *p) {
pgm->setpin(pgm, PIN_AVR_RESET, 0); pgm->setpin(pgm, PIN_AVR_RESET, 0);
usleep(20000); usleep(20000);
if (p->flags & AVRPART_HAS_TPI) { if (p->prog_modes & PM_TPI) {
/* keep TPIDATA high for 16 clock cycles */ /* keep TPIDATA high for 16 clock cycles */
pgm->setpin(pgm, PIN_AVR_MOSI, 1); pgm->setpin(pgm, PIN_AVR_MOSI, 1);
for (i = 0; i < 16; i++) for (i = 0; i < 16; i++)

View File

@ -24,12 +24,14 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <stdarg.h> #include <stdarg.h>
#include <stddef.h>
#include <string.h> #include <string.h>
#include <ctype.h> #include <ctype.h>
#include "avrdude.h" #include "avrdude.h"
#include "libavrdude.h" #include "libavrdude.h"
#include "config.h" #include "config.h"
#include "avrintel.h"
#include "config_gram.h" #include "config_gram.h"
@ -44,6 +46,7 @@ LISTID number_list;
PROGRAMMER * current_prog; PROGRAMMER * current_prog;
AVRPART * current_part; AVRPART * current_part;
AVRMEM * current_mem; AVRMEM * current_mem;
int current_strct;
LISTID part_list; LISTID part_list;
LISTID programmers; LISTID programmers;
bool is_alias; bool is_alias;
@ -53,6 +56,22 @@ char * cfg_infile;
extern char * yytext; extern char * yytext;
#define pgm_comp_desc(x, type) { #x, COMP_PROGRAMMER, offsetof(PROGRAMMER, x), sizeof(((PROGRAMMER *) NULL)->x), type }
#define part_comp_desc(x, type) { #x, COMP_AVRPART, offsetof(AVRPART, x), sizeof(((AVRPART *) NULL)->x), type }
#define mem_comp_desc(x, type) { #x, COMP_AVRMEM, offsetof(AVRMEM, x), sizeof(((AVRMEM *) NULL)->x), type }
// Component description for config_gram.y, will be sorted appropriately on first use
Component_t avr_comp[] = {
// PROGRAMMER
pgm_comp_desc(prog_modes, COMP_INT),
// AVRPART
part_comp_desc(prog_modes, COMP_INT),
part_comp_desc(mcuid, COMP_INT),
part_comp_desc(n_interrupts, COMP_INT),
part_comp_desc(n_page_erase, COMP_INT),
};
#define DEBUG 0 #define DEBUG 0
void cleanup_config(void) void cleanup_config(void)
@ -190,7 +209,7 @@ void free_tokens(int n, ...)
TOKEN *number(const char *text) { TOKEN *new_number(const char *text) {
struct token_t *tkn = new_token(TKN_NUMBER); struct token_t *tkn = new_token(TKN_NUMBER);
tkn->value.type = V_NUM; tkn->value.type = V_NUM;
tkn->value.number = atoi(text); tkn->value.number = atoi(text);
@ -202,7 +221,7 @@ TOKEN *number(const char *text) {
return tkn; return tkn;
} }
TOKEN *number_real(const char *text) { TOKEN *new_number_real(const char *text) {
struct token_t * tkn = new_token(TKN_NUMBER); struct token_t * tkn = new_token(TKN_NUMBER);
tkn->value.type = V_NUM_REAL; tkn->value.type = V_NUM_REAL;
tkn->value.number_real = atof(text); tkn->value.number_real = atof(text);
@ -214,7 +233,7 @@ TOKEN *number_real(const char *text) {
return tkn; return tkn;
} }
TOKEN *hexnumber(const char *text) { TOKEN *new_hexnumber(const char *text) {
struct token_t *tkn = new_token(TKN_NUMBER); struct token_t *tkn = new_token(TKN_NUMBER);
char * e; char * e;
@ -233,11 +252,41 @@ TOKEN *hexnumber(const char *text) {
return tkn; return tkn;
} }
TOKEN *new_constant(const char *con) {
struct token_t *tkn = new_token(TKN_NUMBER);
int assigned = 1;
TOKEN *string(const char *text) { tkn->value.type = V_NUM;
tkn->value.number =
!strcmp("PM_SPM", con)? PM_SPM:
!strcmp("PM_TPI", con)? PM_TPI:
!strcmp("PM_ISP", con)? PM_ISP:
!strcmp("PM_PDI", con)? PM_PDI:
!strcmp("PM_UPDI", con)? PM_UPDI:
!strcmp("PM_HVSP", con)? PM_HVSP:
!strcmp("PM_HVPP", con)? PM_HVPP:
!strcmp("PM_debugWIRE", con)? PM_debugWIRE:
!strcmp("PM_JTAG", con)? PM_JTAG:
!strcmp("PM_aWire", con)? PM_aWire:
(assigned = 0);
if(!assigned) {
yyerror("can't identify constant %s", con);
free_token(tkn);
return NULL;
}
#if DEBUG
avrdude_message(MSG_INFO, "CONSTANT(%s=%d)\n", con, tkn->value.number);
#endif
return tkn;
}
TOKEN *new_string(const char *text) {
struct token_t *tkn = new_token(TKN_STRING); struct token_t *tkn = new_token(TKN_STRING);
tkn->value.type = V_STR; tkn->value.type = V_STR;
tkn->value.string = cfg_strdup("string()", text); tkn->value.string = cfg_strdup("new_string()", text);
#if DEBUG #if DEBUG
avrdude_message(MSG_INFO, "STRING(%s)\n", tkn->value.string); avrdude_message(MSG_INFO, "STRING(%s)\n", tkn->value.string);
@ -247,7 +296,7 @@ TOKEN *string(const char *text) {
} }
TOKEN * keyword(int primary) { TOKEN *new_keyword(int primary) {
return new_token(primary); return new_token(primary);
} }
@ -692,3 +741,145 @@ char *cfg_escape(const char *s) {
return cfg_strdup("cfg_escape()", buf); return cfg_strdup("cfg_escape()", buf);
} }
static int cmp_comp(const void *v1, const void *v2) {
const Component_t *c1 = v1, *c2 = v2;
int ret = strcmp(c1->name, c2->name);
return ret? ret: c1->strct - c2->strct;
}
Component_t *cfg_comp_search(const char *name, int strct) {
static int init;
Component_t key;
if(!init++)
qsort(avr_comp, sizeof avr_comp/sizeof*avr_comp, sizeof(Component_t), cmp_comp);
key.name = name;
key.strct = strct;
return bsearch(&key, avr_comp, sizeof avr_comp/sizeof*avr_comp, sizeof(Component_t), cmp_comp);
}
const char *cfg_strct_name(int strct) {
switch(strct) {
case COMP_CONFIG_MAIN: return "avrdude.conf main";
case COMP_AVRPART: return "AVRPART";
case COMP_AVRMEM: return "AVRMEM";
case COMP_PROGRAMMER: return "PROGRAMMER";
}
return "unknown struct";
}
const char *cfg_v_type(int type) {
switch(type) {
case V_NONE: return "void";
case V_NUM: return "number";
case V_NUM_REAL: return "real";
case V_STR: return "string";
case V_COMPONENT: return "component";
}
return "unknown v type";
}
const char *cfg_comp_type(int type) {
switch(type) {
case COMP_INT: return "number";
case COMP_SHORT: return "short";
case COMP_CHAR: return "char";
case COMP_STRING: return "string";
case COMP_CHAR_ARRAY: return "byte array";
case COMP_INT_LISTID: return "number list";
case COMP_STRING_LISTID: return "string list";
case COMP_OPCODE: return "opcode";
case COMP_PIN: return "pin";
case COMP_PIN_LIST: return "pin list";
}
return "unknown comp type";
}
// Used by config_gram.y to assign a component in one of the relevant structures with a value
void cfg_assign(char *sp, int strct, Component_t *cp, VALUE *v) {
const char *str;
int num;
switch(cp->type) {
case COMP_CHAR:
case COMP_SHORT:
case COMP_INT:
if(v->type != V_NUM) {
yywarning("%s in %s expects a %s but is assigned a %s",
cp->name, cfg_strct_name(strct), cfg_comp_type(cp->type), cfg_v_type(v->type));
return;
}
// TODO: consider endianess (code currently assumes little endian)
num = v->number;
memcpy(sp+cp->offset, &num, cp->size);
break;
case COMP_STRING:
if(v->type != V_STR) {
yywarning("%s in %s expects a string but is assigned a %s",
cp->name, cfg_strct_name(strct), cfg_v_type(v->type));
return;
}
str = cache_string(v->string);
memcpy(sp+cp->offset, &str, cp->size);
break;
// TODO: implement COMP_CHAR_ARRAY, COMP_INT_LISTID, COMP_STRING_LISTID, ...
default:
yywarning("%s in %s expects a %s but that is not implemented",
cp->name, cfg_strct_name(strct), cfg_comp_type(cp->type));
}
}
// Automatically assign an mcuid if known from avrintel.c table
void cfg_update_mcuid(AVRPART *part) {
// Don't assign an mcuid for template parts that has a space in desc
if(!part->desc || *part->desc == 0 || strchr(part->desc, ' '))
return;
// Don't assign an mcuid for template parts where id starts with "."
if(!part->id || !*part->id || *part->id == '.')
return;
// Don't assign an mcuid for 32-bit AVR parts
if(part->prog_modes & PM_aWire)
return;
// Find an entry that shares the same name
for(int i=0; i < sizeof uP_table/sizeof *uP_table; i++) {
if(strcasecmp(part->desc, uP_table[i].name) == 0) {
if(part->mcuid != (int) uP_table[i].mcuid) {
part->mcuid = uP_table[i].mcuid;
yywarning("assigned mcuid = %d to part %s", part->mcuid, part->desc);
}
return;
}
}
// None have the same name: an entry with part->mcuid might be an error
for(int i=0; i < sizeof uP_table/sizeof *uP_table; i++)
if(part->mcuid == (int) uP_table[i].mcuid) {
// Complain unless it can be considered a variant, eg, ATmega32L and ATmega32
AVRMEM *flash = avr_locate_mem(part, "flash");
if(flash) {
size_t l1 = strlen(part->desc), l2 = strlen(uP_table[i].name);
if(strncasecmp(part->desc, uP_table[i].name, l1 < l2? l1: l2) ||
flash->size != uP_table[i].flashsize ||
flash->page_size != uP_table[i].pagesize ||
part->n_interrupts != uP_table[i].ninterrupts)
yywarning("mcuid %d is reserved for %s, use a free number >= %d",
part->mcuid, uP_table[i].name, sizeof uP_table/sizeof *uP_table);
}
return;
}
// Range check
if(part->mcuid < 0 || part->mcuid >= UB_N_MCU)
yywarning("mcuid %d for %s is out of range [0..%d], use a free number >= %d",
part->mcuid, part->desc, UB_N_MCU-1, sizeof uP_table/sizeof *uP_table);
}

View File

@ -37,13 +37,48 @@ typedef struct {
} COMMENT; } COMMENT;
enum { V_NONE, V_NUM, V_NUM_REAL, V_STR }; enum { // Which structures a component can occur in
COMP_CONFIG_MAIN,
COMP_PROGRAMMER,
COMP_AVRPART,
COMP_AVRMEM,
};
enum { // Component types in structure
COMP_INT,
COMP_SHORT,
COMP_CHAR,
COMP_STRING,
COMP_CHAR_ARRAY, // This and below are not yet implemented
COMP_INT_LISTID,
COMP_STRING_LISTID,
COMP_OPCODE,
COMP_PIN, // Pins may never be implemented
COMP_PIN_LIST
};
typedef struct { // Description of a component in a structure
const char *name; // Component name
int strct; // Structure, eg, COMP_AVRPART
int offset, size, type; // Location, size and type within structure
} Component_t;
enum { // Value types for VALUE struct
V_NONE,
V_NUM,
V_NUM_REAL,
V_STR,
V_COMPONENT,
};
typedef struct value_t { typedef struct value_t {
int type; int type;
union { union {
int number; int number;
double number_real; double number_real;
char * string; char * string;
Component_t *comp;
}; };
} VALUE; } VALUE;
@ -59,6 +94,7 @@ extern FILE * yyin;
extern PROGRAMMER * current_prog; extern PROGRAMMER * current_prog;
extern AVRPART * current_part; extern AVRPART * current_part;
extern AVRMEM * current_mem; extern AVRMEM * current_mem;
extern int current_strct;
extern int cfg_lineno; extern int cfg_lineno;
extern char * cfg_infile; extern char * cfg_infile;
extern LISTID string_list; extern LISTID string_list;
@ -87,15 +123,17 @@ void free_token(TOKEN *tkn);
void free_tokens(int n, ...); void free_tokens(int n, ...);
TOKEN *number(const char *text); TOKEN *new_number(const char *text);
TOKEN *number_real(const char *text); TOKEN *new_number_real(const char *text);
TOKEN *hexnumber(const char *text); TOKEN *new_hexnumber(const char *text);
TOKEN *string(const char *text); TOKEN *new_constant(const char *text);
TOKEN *keyword(int primary); TOKEN *new_string(const char *text);
TOKEN *new_keyword(int primary);
void print_token(TOKEN *tkn); void print_token(TOKEN *tkn);
@ -115,6 +153,16 @@ LISTID cfg_move_comments(void);
void cfg_pop_comms(void); void cfg_pop_comms(void);
Component_t *cfg_comp_search(const char *name, int strct);
const char *cfg_v_type(int type);
const char *cfg_strct_name(int strct);
void cfg_assign(char *sp, int strct, Component_t *cp, VALUE *v);
void cfg_update_mcuid(AVRPART *part);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -208,19 +208,26 @@ static int pin_name;
%token TKN_COMMA %token TKN_COMMA
%token TKN_EQUAL %token TKN_EQUAL
%token TKN_SEMI %token TKN_SEMI
%token TKN_TILDE
%token TKN_LEFT_PAREN %token TKN_LEFT_PAREN
%token TKN_RIGHT_PAREN %token TKN_RIGHT_PAREN
%token TKN_NUMBER %token TKN_NUMBER
%token TKN_NUMBER_REAL %token TKN_NUMBER_REAL
%token TKN_STRING %token TKN_STRING
%token TKN_COMPONENT
%left OP_OR /* calculator operations */
%left OP_XOR
%left OP_AND
%left OP_PLUS OP_MINUS
%left OP_TIMES OP_DIVIDE OP_MODULO
%right OP_TILDE UNARY
%start configuration %start configuration
%% %%
number_real : number_real :
TKN_NUMBER { numexpr {
$$ = $1; $$ = $1;
/* convert value to real */ /* convert value to real */
$$->value.number_real = $$->value.number; $$->value.number_real = $$->value.number;
@ -229,6 +236,27 @@ number_real :
TKN_NUMBER_REAL { TKN_NUMBER_REAL {
$$ = $1; $$ = $1;
} }
;
expr: numexpr | TKN_STRING;
numexpr:
TKN_NUMBER |
numexpr OP_OR numexpr { $$ = $1; $$->value.number |= $3->value.number; } |
numexpr OP_XOR numexpr { $$ = $1; $$->value.number ^= $3->value.number; } |
numexpr OP_AND numexpr { $$ = $1; $$->value.number &= $3->value.number; } |
numexpr OP_PLUS numexpr { $$ = $1; $$->value.number += $3->value.number; } |
numexpr OP_MINUS numexpr { $$ = $1; $$->value.number -= $3->value.number; } |
numexpr OP_TIMES numexpr { $$ = $1; $$->value.number *= $3->value.number; } |
numexpr OP_DIVIDE numexpr { $$ = $1; $$->value.number /= $3->value.number; } |
numexpr OP_MODULO numexpr { $$ = $1; $$->value.number %= $3->value.number; } |
OP_PLUS numexpr %prec UNARY { $$ = $2; } |
OP_MINUS numexpr %prec UNARY { $$ = $2; $$->value.number = -$$->value.number; } |
OP_TILDE numexpr %prec UNARY { $$ = $2; $$->value.number = ~$$->value.number; } |
TKN_LEFT_PAREN numexpr TKN_RIGHT_PAREN { $$ = $2; }
;
configuration : configuration :
/* empty */ | config /* empty */ | config
@ -302,6 +330,7 @@ prog_def :
// pgm_fill_old_pins(current_prog); // TODO to be removed if old pin data no longer needed // pgm_fill_old_pins(current_prog); // TODO to be removed if old pin data no longer needed
// pgm_display_generic(current_prog, id); // pgm_display_generic(current_prog, id);
current_prog = NULL; current_prog = NULL;
current_strct = COMP_CONFIG_MAIN;
} }
; ;
@ -309,6 +338,7 @@ prog_def :
prog_decl : prog_decl :
K_PROGRAMMER K_PROGRAMMER
{ current_prog = pgm_new(); { current_prog = pgm_new();
current_strct = COMP_PROGRAMMER;
current_prog->config_file = cache_string(cfg_infile); current_prog->config_file = cache_string(cfg_infile);
current_prog->lineno = cfg_lineno; current_prog->lineno = cfg_lineno;
} }
@ -322,6 +352,7 @@ prog_decl :
YYABORT; YYABORT;
} }
current_prog = pgm_dup(pgm); current_prog = pgm_dup(pgm);
current_strct = COMP_PROGRAMMER;
current_prog->parent_id = cache_string($3->value.string); current_prog->parent_id = cache_string($3->value.string);
current_prog->comments = NULL; current_prog->comments = NULL;
current_prog->config_file = cache_string(cfg_infile); current_prog->config_file = cache_string(cfg_infile);
@ -343,6 +374,8 @@ part_def :
YYABORT; YYABORT;
} }
cfg_update_mcuid(current_part);
// Sanity checks for memory sizes and compute/override num_pages entry // Sanity checks for memory sizes and compute/override num_pages entry
for (ln=lfirst(current_part->mem); ln; ln=lnext(ln)) { for (ln=lfirst(current_part->mem); ln; ln=lnext(ln)) {
m = ldata(ln); m = ldata(ln);
@ -389,6 +422,7 @@ part_def :
current_part->comments = cfg_move_comments(); current_part->comments = cfg_move_comments();
LISTADD(part_list, current_part); LISTADD(part_list, current_part);
current_part = NULL; current_part = NULL;
current_strct = COMP_CONFIG_MAIN;
} }
; ;
@ -396,6 +430,7 @@ part_decl :
K_PART K_PART
{ {
current_part = avr_new_part(); current_part = avr_new_part();
current_strct = COMP_AVRPART;
current_part->config_file = cache_string(cfg_infile); current_part->config_file = cache_string(cfg_infile);
current_part->lineno = cfg_lineno; current_part->lineno = cfg_lineno;
} | } |
@ -409,6 +444,7 @@ part_decl :
} }
current_part = avr_dup_part(parent_part); current_part = avr_dup_part(parent_part);
current_strct = COMP_AVRPART;
current_part->parent_id = cache_string($3->value.string); current_part->parent_id = cache_string($3->value.string);
current_part->comments = NULL; current_part->comments = NULL;
current_part->config_file = cache_string(cfg_infile); current_part->config_file = cache_string(cfg_infile);
@ -425,8 +461,8 @@ string_list :
num_list : num_list :
TKN_NUMBER { ladd(number_list, $1); } | numexpr { ladd(number_list, $1); } |
num_list TKN_COMMA TKN_NUMBER { ladd(number_list, $3); } num_list TKN_COMMA numexpr { ladd(number_list, $3); }
; ;
prog_parms : prog_parms :
@ -435,6 +471,10 @@ prog_parms :
; ;
prog_parm : prog_parm :
TKN_COMPONENT TKN_EQUAL expr {
cfg_assign((char *) current_prog, COMP_PROGRAMMER, $1->value.comp, &$3->value);
free_token($1);
} |
K_ID TKN_EQUAL string_list { K_ID TKN_EQUAL string_list {
{ {
while (lsize(string_list)) { while (lsize(string_list)) {
@ -456,7 +496,7 @@ prog_parm :
current_prog->desc = cache_string($3->value.string); current_prog->desc = cache_string($3->value.string);
free_token($3); free_token($3);
} | } |
K_BAUDRATE TKN_EQUAL TKN_NUMBER { K_BAUDRATE TKN_EQUAL numexpr {
{ {
current_prog->baudrate = $3->value.number; current_prog->baudrate = $3->value.number;
free_token($3); free_token($3);
@ -505,7 +545,7 @@ prog_parm_usb:
free_token($3); free_token($3);
} }
} | } |
K_USBVID TKN_EQUAL TKN_NUMBER { K_USBVID TKN_EQUAL numexpr {
{ {
current_prog->usbvid = $3->value.number; current_prog->usbvid = $3->value.number;
free_token($3); free_token($3);
@ -533,7 +573,7 @@ prog_parm_usb:
; ;
usb_pid_list: usb_pid_list:
TKN_NUMBER { numexpr {
{ {
/* overwrite pids, so clear the existing entries */ /* overwrite pids, so clear the existing entries */
if(current_prog->usbpid) if(current_prog->usbpid)
@ -547,7 +587,7 @@ usb_pid_list:
free_token($1); free_token($1);
} }
} | } |
usb_pid_list TKN_COMMA TKN_NUMBER { usb_pid_list TKN_COMMA numexpr {
{ {
int *ip = cfg_malloc("usb_pid_list", sizeof(int)); int *ip = cfg_malloc("usb_pid_list", sizeof(int));
*ip = $3->value.number; *ip = $3->value.number;
@ -562,7 +602,7 @@ prog_parm_updi:
; ;
hvupdi_support_list: hvupdi_support_list:
TKN_NUMBER { numexpr {
{ {
/* overwrite list entries, so clear the existing entries */ /* overwrite list entries, so clear the existing entries */
if(current_prog->hvupdi_support) if(current_prog->hvupdi_support)
@ -576,7 +616,7 @@ hvupdi_support_list:
free_token($1); free_token($1);
} }
} | } |
hvupdi_support_list TKN_COMMA TKN_NUMBER { hvupdi_support_list TKN_COMMA numexpr {
{ {
int *ip = cfg_malloc("hvupdi_support_list", sizeof(int)); int *ip = cfg_malloc("hvupdi_support_list", sizeof(int));
*ip = $3->value.number; *ip = $3->value.number;
@ -589,7 +629,7 @@ hvupdi_support_list:
pin_number_non_empty: pin_number_non_empty:
TKN_NUMBER { if(0 != assign_pin(pin_name, $1, 0)) YYABORT; } TKN_NUMBER { if(0 != assign_pin(pin_name, $1, 0)) YYABORT; }
| |
TKN_TILDE TKN_NUMBER { if(0 != assign_pin(pin_name, $2, 1)) YYABORT; } OP_TILDE TKN_NUMBER { if(0 != assign_pin(pin_name, $2, 1)) YYABORT; }
; ;
pin_number: pin_number:
@ -601,7 +641,7 @@ pin_number:
pin_list_element: pin_list_element:
pin_number_non_empty pin_number_non_empty
| |
TKN_TILDE TKN_LEFT_PAREN num_list TKN_RIGHT_PAREN { if(0 != assign_pin_list(1)) YYABORT; } OP_TILDE TKN_LEFT_PAREN num_list TKN_RIGHT_PAREN { if(0 != assign_pin_list(1)) YYABORT; }
; ;
pin_list_non_empty: pin_list_non_empty:
@ -665,6 +705,10 @@ retry_lines :
; ;
part_parm : part_parm :
TKN_COMPONENT TKN_EQUAL expr {
cfg_assign((char *) current_part, COMP_AVRPART, $1->value.comp, &$3->value);
free_token($1);
} |
K_ID TKN_EQUAL TKN_STRING K_ID TKN_EQUAL TKN_STRING
{ {
current_part->id = cache_string($3->value.string); current_part->id = cache_string($3->value.string);
@ -683,13 +727,13 @@ part_parm :
free_token($3); free_token($3);
} | } |
K_HVUPDI_VARIANT TKN_EQUAL TKN_NUMBER K_HVUPDI_VARIANT TKN_EQUAL numexpr
{ {
current_part->hvupdi_variant = $3->value.number; current_part->hvupdi_variant = $3->value.number;
free_token($3); free_token($3);
} | } |
K_DEVICECODE TKN_EQUAL TKN_NUMBER { K_DEVICECODE TKN_EQUAL numexpr {
{ {
yyerror("devicecode is deprecated, use " yyerror("devicecode is deprecated, use "
"stk500_devcode instead"); "stk500_devcode instead");
@ -697,14 +741,14 @@ part_parm :
} }
} | } |
K_STK500_DEVCODE TKN_EQUAL TKN_NUMBER { K_STK500_DEVCODE TKN_EQUAL numexpr {
{ {
current_part->stk500_devcode = $3->value.number; current_part->stk500_devcode = $3->value.number;
free_token($3); free_token($3);
} }
} | } |
K_AVR910_DEVCODE TKN_EQUAL TKN_NUMBER { K_AVR910_DEVCODE TKN_EQUAL numexpr {
{ {
current_part->avr910_devcode = $3->value.number; current_part->avr910_devcode = $3->value.number;
free_token($3); free_token($3);
@ -722,7 +766,7 @@ part_parm :
} }
} | } |
K_USBPID TKN_EQUAL TKN_NUMBER { K_USBPID TKN_EQUAL numexpr {
{ {
current_part->usbpid = $3->value.number; current_part->usbpid = $3->value.number;
free_token($3); free_token($3);
@ -877,19 +921,19 @@ part_parm :
} }
} | } |
K_CHIP_ERASE_DELAY TKN_EQUAL TKN_NUMBER K_CHIP_ERASE_DELAY TKN_EQUAL numexpr
{ {
current_part->chip_erase_delay = $3->value.number; current_part->chip_erase_delay = $3->value.number;
free_token($3); free_token($3);
} | } |
K_PAGEL TKN_EQUAL TKN_NUMBER K_PAGEL TKN_EQUAL numexpr
{ {
current_part->pagel = $3->value.number; current_part->pagel = $3->value.number;
free_token($3); free_token($3);
} | } |
K_BS2 TKN_EQUAL TKN_NUMBER K_BS2 TKN_EQUAL numexpr
{ {
current_part->bs2 = $3->value.number; current_part->bs2 = $3->value.number;
free_token($3); free_token($3);
@ -905,169 +949,169 @@ part_parm :
free_tokens(2, $1, $3); free_tokens(2, $1, $3);
} | } |
K_TIMEOUT TKN_EQUAL TKN_NUMBER K_TIMEOUT TKN_EQUAL numexpr
{ {
current_part->timeout = $3->value.number; current_part->timeout = $3->value.number;
free_token($3); free_token($3);
} | } |
K_STABDELAY TKN_EQUAL TKN_NUMBER K_STABDELAY TKN_EQUAL numexpr
{ {
current_part->stabdelay = $3->value.number; current_part->stabdelay = $3->value.number;
free_token($3); free_token($3);
} | } |
K_CMDEXEDELAY TKN_EQUAL TKN_NUMBER K_CMDEXEDELAY TKN_EQUAL numexpr
{ {
current_part->cmdexedelay = $3->value.number; current_part->cmdexedelay = $3->value.number;
free_token($3); free_token($3);
} | } |
K_HVSPCMDEXEDELAY TKN_EQUAL TKN_NUMBER K_HVSPCMDEXEDELAY TKN_EQUAL numexpr
{ {
current_part->hvspcmdexedelay = $3->value.number; current_part->hvspcmdexedelay = $3->value.number;
free_token($3); free_token($3);
} | } |
K_SYNCHLOOPS TKN_EQUAL TKN_NUMBER K_SYNCHLOOPS TKN_EQUAL numexpr
{ {
current_part->synchloops = $3->value.number; current_part->synchloops = $3->value.number;
free_token($3); free_token($3);
} | } |
K_BYTEDELAY TKN_EQUAL TKN_NUMBER K_BYTEDELAY TKN_EQUAL numexpr
{ {
current_part->bytedelay = $3->value.number; current_part->bytedelay = $3->value.number;
free_token($3); free_token($3);
} | } |
K_POLLVALUE TKN_EQUAL TKN_NUMBER K_POLLVALUE TKN_EQUAL numexpr
{ {
current_part->pollvalue = $3->value.number; current_part->pollvalue = $3->value.number;
free_token($3); free_token($3);
} | } |
K_POLLINDEX TKN_EQUAL TKN_NUMBER K_POLLINDEX TKN_EQUAL numexpr
{ {
current_part->pollindex = $3->value.number; current_part->pollindex = $3->value.number;
free_token($3); free_token($3);
} | } |
K_PREDELAY TKN_EQUAL TKN_NUMBER K_PREDELAY TKN_EQUAL numexpr
{ {
current_part->predelay = $3->value.number; current_part->predelay = $3->value.number;
free_token($3); free_token($3);
} | } |
K_POSTDELAY TKN_EQUAL TKN_NUMBER K_POSTDELAY TKN_EQUAL numexpr
{ {
current_part->postdelay = $3->value.number; current_part->postdelay = $3->value.number;
free_token($3); free_token($3);
} | } |
K_POLLMETHOD TKN_EQUAL TKN_NUMBER K_POLLMETHOD TKN_EQUAL numexpr
{ {
current_part->pollmethod = $3->value.number; current_part->pollmethod = $3->value.number;
free_token($3); free_token($3);
} | } |
K_HVENTERSTABDELAY TKN_EQUAL TKN_NUMBER K_HVENTERSTABDELAY TKN_EQUAL numexpr
{ {
current_part->hventerstabdelay = $3->value.number; current_part->hventerstabdelay = $3->value.number;
free_token($3); free_token($3);
} | } |
K_PROGMODEDELAY TKN_EQUAL TKN_NUMBER K_PROGMODEDELAY TKN_EQUAL numexpr
{ {
current_part->progmodedelay = $3->value.number; current_part->progmodedelay = $3->value.number;
free_token($3); free_token($3);
} | } |
K_LATCHCYCLES TKN_EQUAL TKN_NUMBER K_LATCHCYCLES TKN_EQUAL numexpr
{ {
current_part->latchcycles = $3->value.number; current_part->latchcycles = $3->value.number;
free_token($3); free_token($3);
} | } |
K_TOGGLEVTG TKN_EQUAL TKN_NUMBER K_TOGGLEVTG TKN_EQUAL numexpr
{ {
current_part->togglevtg = $3->value.number; current_part->togglevtg = $3->value.number;
free_token($3); free_token($3);
} | } |
K_POWEROFFDELAY TKN_EQUAL TKN_NUMBER K_POWEROFFDELAY TKN_EQUAL numexpr
{ {
current_part->poweroffdelay = $3->value.number; current_part->poweroffdelay = $3->value.number;
free_token($3); free_token($3);
} | } |
K_RESETDELAYMS TKN_EQUAL TKN_NUMBER K_RESETDELAYMS TKN_EQUAL numexpr
{ {
current_part->resetdelayms = $3->value.number; current_part->resetdelayms = $3->value.number;
free_token($3); free_token($3);
} | } |
K_RESETDELAYUS TKN_EQUAL TKN_NUMBER K_RESETDELAYUS TKN_EQUAL numexpr
{ {
current_part->resetdelayus = $3->value.number; current_part->resetdelayus = $3->value.number;
free_token($3); free_token($3);
} | } |
K_HVLEAVESTABDELAY TKN_EQUAL TKN_NUMBER K_HVLEAVESTABDELAY TKN_EQUAL numexpr
{ {
current_part->hvleavestabdelay = $3->value.number; current_part->hvleavestabdelay = $3->value.number;
free_token($3); free_token($3);
} | } |
K_RESETDELAY TKN_EQUAL TKN_NUMBER K_RESETDELAY TKN_EQUAL numexpr
{ {
current_part->resetdelay = $3->value.number; current_part->resetdelay = $3->value.number;
free_token($3); free_token($3);
} | } |
K_CHIPERASEPULSEWIDTH TKN_EQUAL TKN_NUMBER K_CHIPERASEPULSEWIDTH TKN_EQUAL numexpr
{ {
current_part->chiperasepulsewidth = $3->value.number; current_part->chiperasepulsewidth = $3->value.number;
free_token($3); free_token($3);
} | } |
K_CHIPERASEPOLLTIMEOUT TKN_EQUAL TKN_NUMBER K_CHIPERASEPOLLTIMEOUT TKN_EQUAL numexpr
{ {
current_part->chiperasepolltimeout = $3->value.number; current_part->chiperasepolltimeout = $3->value.number;
free_token($3); free_token($3);
} | } |
K_CHIPERASETIME TKN_EQUAL TKN_NUMBER K_CHIPERASETIME TKN_EQUAL numexpr
{ {
current_part->chiperasetime = $3->value.number; current_part->chiperasetime = $3->value.number;
free_token($3); free_token($3);
} | } |
K_PROGRAMFUSEPULSEWIDTH TKN_EQUAL TKN_NUMBER K_PROGRAMFUSEPULSEWIDTH TKN_EQUAL numexpr
{ {
current_part->programfusepulsewidth = $3->value.number; current_part->programfusepulsewidth = $3->value.number;
free_token($3); free_token($3);
} | } |
K_PROGRAMFUSEPOLLTIMEOUT TKN_EQUAL TKN_NUMBER K_PROGRAMFUSEPOLLTIMEOUT TKN_EQUAL numexpr
{ {
current_part->programfusepolltimeout = $3->value.number; current_part->programfusepolltimeout = $3->value.number;
free_token($3); free_token($3);
} | } |
K_PROGRAMLOCKPULSEWIDTH TKN_EQUAL TKN_NUMBER K_PROGRAMLOCKPULSEWIDTH TKN_EQUAL numexpr
{ {
current_part->programlockpulsewidth = $3->value.number; current_part->programlockpulsewidth = $3->value.number;
free_token($3); free_token($3);
} | } |
K_PROGRAMLOCKPOLLTIMEOUT TKN_EQUAL TKN_NUMBER K_PROGRAMLOCKPOLLTIMEOUT TKN_EQUAL numexpr
{ {
current_part->programlockpolltimeout = $3->value.number; current_part->programlockpolltimeout = $3->value.number;
free_token($3); free_token($3);
} | } |
K_SYNCHCYCLES TKN_EQUAL TKN_NUMBER K_SYNCHCYCLES TKN_EQUAL numexpr
{ {
current_part->synchcycles = $3->value.number; current_part->synchcycles = $3->value.number;
free_token($3); free_token($3);
@ -1076,50 +1120,45 @@ part_parm :
K_HAS_JTAG TKN_EQUAL yesno K_HAS_JTAG TKN_EQUAL yesno
{ {
if ($3->primary == K_YES) if ($3->primary == K_YES)
current_part->flags |= AVRPART_HAS_JTAG; current_part->prog_modes |= PM_JTAG;
else if ($3->primary == K_NO) else if ($3->primary == K_NO)
current_part->flags &= ~AVRPART_HAS_JTAG; current_part->prog_modes &= ~PM_JTAG;
free_token($3); free_token($3);
} | } |
K_HAS_DW TKN_EQUAL yesno K_HAS_DW TKN_EQUAL yesno
{ {
if ($3->primary == K_YES) if ($3->primary == K_YES)
current_part->flags |= AVRPART_HAS_DW; current_part->prog_modes |= PM_debugWIRE;
else if ($3->primary == K_NO) else if ($3->primary == K_NO)
current_part->flags &= ~AVRPART_HAS_DW; current_part->prog_modes &= ~PM_debugWIRE;
free_token($3); free_token($3);
} | } |
K_HAS_PDI TKN_EQUAL yesno K_HAS_PDI TKN_EQUAL yesno
{ {
if ($3->primary == K_YES) if ($3->primary == K_YES)
current_part->flags |= AVRPART_HAS_PDI; current_part->prog_modes |= PM_PDI;
else if ($3->primary == K_NO) else if ($3->primary == K_NO)
current_part->flags &= ~AVRPART_HAS_PDI; current_part->prog_modes &= ~PM_PDI;
free_token($3); free_token($3);
} | } |
K_HAS_UPDI TKN_EQUAL yesno K_HAS_UPDI TKN_EQUAL yesno
{ {
if ($3->primary == K_YES) if ($3->primary == K_YES)
current_part->flags |= AVRPART_HAS_UPDI; current_part->prog_modes |= PM_UPDI;
else if ($3->primary == K_NO) else if ($3->primary == K_NO)
current_part->flags &= ~AVRPART_HAS_UPDI; current_part->prog_modes &= ~PM_UPDI;
free_token($3); free_token($3);
} | } |
K_HAS_TPI TKN_EQUAL yesno K_HAS_TPI TKN_EQUAL yesno
{ {
if ($3->primary == K_YES) if ($3->primary == K_YES)
current_part->flags |= AVRPART_HAS_TPI; current_part->prog_modes |= PM_TPI;
else if ($3->primary == K_NO) else if ($3->primary == K_NO)
current_part->flags &= ~AVRPART_HAS_TPI; current_part->prog_modes &= ~PM_TPI;
free_token($3); free_token($3);
} | } |
@ -1136,10 +1175,9 @@ part_parm :
K_IS_AVR32 TKN_EQUAL yesno K_IS_AVR32 TKN_EQUAL yesno
{ {
if ($3->primary == K_YES) if ($3->primary == K_YES)
current_part->flags |= AVRPART_AVR32; current_part->prog_modes |= PM_aWire;
else if ($3->primary == K_NO) else if ($3->primary == K_NO)
current_part->flags &= ~AVRPART_AVR32; current_part->prog_modes &= ~PM_aWire;
free_token($3); free_token($3);
} | } |
@ -1163,49 +1201,49 @@ part_parm :
free_token($3); free_token($3);
} | } |
K_IDR TKN_EQUAL TKN_NUMBER K_IDR TKN_EQUAL numexpr
{ {
current_part->idr = $3->value.number; current_part->idr = $3->value.number;
free_token($3); free_token($3);
} | } |
K_RAMPZ TKN_EQUAL TKN_NUMBER K_RAMPZ TKN_EQUAL numexpr
{ {
current_part->rampz = $3->value.number; current_part->rampz = $3->value.number;
free_token($3); free_token($3);
} | } |
K_SPMCR TKN_EQUAL TKN_NUMBER K_SPMCR TKN_EQUAL numexpr
{ {
current_part->spmcr = $3->value.number; current_part->spmcr = $3->value.number;
free_token($3); free_token($3);
} | } |
K_EECR TKN_EQUAL TKN_NUMBER K_EECR TKN_EQUAL numexpr
{ {
current_part->eecr = $3->value.number; current_part->eecr = $3->value.number;
free_token($3); free_token($3);
} | } |
K_MCU_BASE TKN_EQUAL TKN_NUMBER K_MCU_BASE TKN_EQUAL numexpr
{ {
current_part->mcu_base = $3->value.number; current_part->mcu_base = $3->value.number;
free_token($3); free_token($3);
} | } |
K_NVM_BASE TKN_EQUAL TKN_NUMBER K_NVM_BASE TKN_EQUAL numexpr
{ {
current_part->nvm_base = $3->value.number; current_part->nvm_base = $3->value.number;
free_token($3); free_token($3);
} | } |
K_OCD_BASE TKN_EQUAL TKN_NUMBER K_OCD_BASE TKN_EQUAL numexpr
{ {
current_part->ocd_base = $3->value.number; current_part->ocd_base = $3->value.number;
free_token($3); free_token($3);
} | } |
K_OCDREV TKN_EQUAL TKN_NUMBER K_OCDREV TKN_EQUAL numexpr
{ {
current_part->ocdrev = $3->value.number; current_part->ocdrev = $3->value.number;
free_token($3); free_token($3);
@ -1255,14 +1293,6 @@ part_parm :
} | } |
/*
K_EEPROM { current_mem = AVR_M_EEPROM; }
mem_specs |
K_FLASH { current_mem = AVR_M_FLASH; }
mem_specs |
*/
K_MEMORY TKN_STRING K_MEMORY TKN_STRING
{ /* select memory for extension or create if not there */ { /* select memory for extension or create if not there */
AVRMEM *mem = avr_locate_mem_noalias(current_part, $2->value.string); AVRMEM *mem = avr_locate_mem_noalias(current_part, $2->value.string);
@ -1273,6 +1303,7 @@ part_parm :
} }
avr_add_mem_order($2->value.string); avr_add_mem_order($2->value.string);
current_mem = mem; current_mem = mem;
current_strct = COMP_AVRMEM;
free_token($2); free_token($2);
} }
mem_specs mem_specs
@ -1295,6 +1326,7 @@ part_parm :
} }
cfg_pop_comms(); cfg_pop_comms();
current_mem = NULL; current_mem = NULL;
current_strct = COMP_AVRPART;
} | } |
K_MEMORY TKN_STRING TKN_EQUAL K_NULL K_MEMORY TKN_STRING TKN_EQUAL K_NULL
{ {
@ -1306,6 +1338,7 @@ part_parm :
free_token($2); free_token($2);
cfg_pop_comms(); cfg_pop_comms();
current_mem = NULL; current_mem = NULL;
current_strct = COMP_AVRPART;
} | } |
opcode TKN_EQUAL string_list { opcode TKN_EQUAL string_list {
{ {
@ -1355,20 +1388,25 @@ mem_specs :
mem_spec : mem_spec :
TKN_COMPONENT TKN_EQUAL expr {
cfg_assign((char *) current_mem, COMP_AVRMEM, $1->value.comp, &$3->value);
free_token($1);
} |
K_PAGED TKN_EQUAL yesno K_PAGED TKN_EQUAL yesno
{ {
current_mem->paged = $3->primary == K_YES ? 1 : 0; current_mem->paged = $3->primary == K_YES ? 1 : 0;
free_token($3); free_token($3);
} | } |
K_SIZE TKN_EQUAL TKN_NUMBER K_SIZE TKN_EQUAL numexpr
{ {
current_mem->size = $3->value.number; current_mem->size = $3->value.number;
free_token($3); free_token($3);
} | } |
K_PAGE_SIZE TKN_EQUAL TKN_NUMBER K_PAGE_SIZE TKN_EQUAL numexpr
{ {
int ps = $3->value.number; int ps = $3->value.number;
if (ps <= 0) if (ps <= 0)
@ -1380,25 +1418,25 @@ mem_spec :
free_token($3); free_token($3);
} | } |
K_NUM_PAGES TKN_EQUAL TKN_NUMBER K_NUM_PAGES TKN_EQUAL numexpr
{ {
current_mem->num_pages = $3->value.number; current_mem->num_pages = $3->value.number;
free_token($3); free_token($3);
} | } |
K_OFFSET TKN_EQUAL TKN_NUMBER K_OFFSET TKN_EQUAL numexpr
{ {
current_mem->offset = $3->value.number; current_mem->offset = $3->value.number;
free_token($3); free_token($3);
} | } |
K_MIN_WRITE_DELAY TKN_EQUAL TKN_NUMBER K_MIN_WRITE_DELAY TKN_EQUAL numexpr
{ {
current_mem->min_write_delay = $3->value.number; current_mem->min_write_delay = $3->value.number;
free_token($3); free_token($3);
} | } |
K_MAX_WRITE_DELAY TKN_EQUAL TKN_NUMBER K_MAX_WRITE_DELAY TKN_EQUAL numexpr
{ {
current_mem->max_write_delay = $3->value.number; current_mem->max_write_delay = $3->value.number;
free_token($3); free_token($3);
@ -1418,44 +1456,44 @@ mem_spec :
free_token($4); free_token($4);
} | } |
K_READBACK_P1 TKN_EQUAL TKN_NUMBER K_READBACK_P1 TKN_EQUAL numexpr
{ {
current_mem->readback[0] = $3->value.number; current_mem->readback[0] = $3->value.number;
free_token($3); free_token($3);
} | } |
K_READBACK_P2 TKN_EQUAL TKN_NUMBER K_READBACK_P2 TKN_EQUAL numexpr
{ {
current_mem->readback[1] = $3->value.number; current_mem->readback[1] = $3->value.number;
free_token($3); free_token($3);
} | } |
K_MODE TKN_EQUAL TKN_NUMBER K_MODE TKN_EQUAL numexpr
{ {
current_mem->mode = $3->value.number; current_mem->mode = $3->value.number;
free_token($3); free_token($3);
} | } |
K_DELAY TKN_EQUAL TKN_NUMBER K_DELAY TKN_EQUAL numexpr
{ {
current_mem->delay = $3->value.number; current_mem->delay = $3->value.number;
free_token($3); free_token($3);
} | } |
K_BLOCKSIZE TKN_EQUAL TKN_NUMBER K_BLOCKSIZE TKN_EQUAL numexpr
{ {
current_mem->blocksize = $3->value.number; current_mem->blocksize = $3->value.number;
free_token($3); free_token($3);
} | } |
K_READSIZE TKN_EQUAL TKN_NUMBER K_READSIZE TKN_EQUAL numexpr
{ {
current_mem->readsize = $3->value.number; current_mem->readsize = $3->value.number;
free_token($3); free_token($3);
} | } |
K_POLLINDEX TKN_EQUAL TKN_NUMBER K_POLLINDEX TKN_EQUAL numexpr
{ {
current_mem->pollindex = $3->value.number; current_mem->pollindex = $3->value.number;
free_token($3); free_token($3);

View File

@ -74,8 +74,6 @@ static struct {
}; };
// Return 0 if op code would encode (essentially) the same SPI command // Return 0 if op code would encode (essentially) the same SPI command
static int opcodecmp(const OPCODE *op1, const OPCODE *op2, int opnum) { static int opcodecmp(const OPCODE *op1, const OPCODE *op2, int opnum) {
char *opstr1, *opstr2, *p; char *opstr1, *opstr2, *p;
@ -134,7 +132,14 @@ static void printallopcodes(const AVRPART *p, const char *d, OPCODE * const *opa
// Programming modes // Programming modes
static char *prog_modes(const AVRPART *p) {
/*
* p->flags no longer used for programming modes, use p->prog_modes
*
remove this comment in 2023
static char *prog_modes_str_flags(const AVRPART *p) {
static char type[1024]; static char type[1024];
*type = 0; *type = 0;
@ -194,6 +199,38 @@ static char *prog_modes(const AVRPART *p) {
return type + (*type == '|'); return type + (*type == '|');
} }
*
*/
static char *prog_modes_str(int pm) {
static char type[1024];
strcpy(type, "0");
if(pm & PM_SPM)
strcat(type, " | PM_SPM");
if(pm & PM_TPI)
strcat(type, " | PM_TPI");
if(pm & PM_ISP)
strcat(type, " | PM_ISP");
if(pm & PM_PDI)
strcat(type, " | PM_PDI");
if(pm & PM_UPDI)
strcat(type, " | PM_UPDI");
if(pm & PM_HVSP)
strcat(type, " | PM_HVSP");
if(pm & PM_HVPP)
strcat(type, " | PM_HVPP");
if(pm & PM_debugWIRE)
strcat(type, " | PM_debugWIRE");
if(pm & PM_JTAG)
strcat(type, " | PM_JTAG");
if(pm & PM_aWire)
strcat(type, " | PM_aWire");
return type + (type[1] == 0? 0: 4);
}
// Check whether address bits are where they should be in ISP commands // Check whether address bits are where they should be in ISP commands
static void checkaddr(int memsize, int pagesize, int opnum, const OPCODE *op, const AVRPART *p, const AVRMEM *m) { static void checkaddr(int memsize, int pagesize, int opnum, const OPCODE *op, const AVRPART *p, const AVRMEM *m) {
@ -573,6 +610,10 @@ static void dev_part_strct(const AVRPART *p, bool tsv, const AVRPART *base, bool
_if_partout_str(strcmp, descstr, desc); _if_partout_str(strcmp, descstr, desc);
_if_partout_str(strcmp, cfg_escape(p->id), id); _if_partout_str(strcmp, cfg_escape(p->id), id);
_if_partout_str(strcmp, cfg_escape(p->family_id), family_id); _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);
_if_partout(intcmp, "%d", n_interrupts);
_if_partout(intcmp, "%d", n_page_erase);
_if_partout(intcmp, "%d", hvupdi_variant); _if_partout(intcmp, "%d", hvupdi_variant);
_if_partout(intcmp, "0x%02x", stk500_devcode); _if_partout(intcmp, "0x%02x", stk500_devcode);
_if_partout(intcmp, "0x%02x", avr910_devcode); _if_partout(intcmp, "0x%02x", avr910_devcode);
@ -595,13 +636,7 @@ static void dev_part_strct(const AVRPART *p, bool tsv, const AVRPART *base, bool
if(tsv) { if(tsv) {
_partout("0x%04x", flags); _partout("0x%04x", flags);
} else { } else {
_if_flagout(AVRPART_HAS_JTAG, has_jtag);
_if_flagout(AVRPART_HAS_DW, has_debugwire);
_if_flagout(AVRPART_HAS_PDI, has_pdi);
_if_flagout(AVRPART_HAS_UPDI, has_updi);
_if_flagout(AVRPART_HAS_TPI, has_tpi);
_if_flagout(AVRPART_IS_AT90S1200, is_at90s1200); _if_flagout(AVRPART_IS_AT90S1200, is_at90s1200);
_if_flagout(AVRPART_AVR32, is_avr32);
_if_flagout(AVRPART_ALLOWFULLPAGEBITSTREAM, allowfullpagebitstream); _if_flagout(AVRPART_ALLOWFULLPAGEBITSTREAM, allowfullpagebitstream);
_if_flagout(AVRPART_ENABLEPAGEPROGRAMMING, enablepageprogramming); _if_flagout(AVRPART_ENABLEPAGEPROGRAMMING, enablepageprogramming);
_if_flagout(AVRPART_SERIALOK, serial); _if_flagout(AVRPART_SERIALOK, serial);
@ -1032,7 +1067,7 @@ void dev_output_part_defs(char *partdesc) {
nfuses, nfuses,
ok, ok,
p->flags, p->flags,
prog_modes(p), prog_modes_str(p->prog_modes),
p->config_file, p->lineno p->config_file, p->lineno
); );
} }
@ -1051,14 +1086,14 @@ void dev_output_part_defs(char *partdesc) {
// Print wait delays for AVR family parts // Print wait delays for AVR family parts
if(waits) { if(waits) {
if(!(p->flags & (AVRPART_HAS_PDI | AVRPART_HAS_UPDI | AVRPART_HAS_TPI | AVRPART_AVR32))) if(p->prog_modes & PM_ISP)
dev_info(".wd_chip_erase %.3f ms %s\n", p->chip_erase_delay/1000.0, p->desc); dev_info(".wd_chip_erase %.3f ms %s\n", p->chip_erase_delay/1000.0, p->desc);
if(p->mem) { if(p->mem) {
for(LNODEID lnm=lfirst(p->mem); lnm; lnm=lnext(lnm)) { for(LNODEID lnm=lfirst(p->mem); lnm; lnm=lnext(lnm)) {
AVRMEM *m = ldata(lnm); AVRMEM *m = ldata(lnm);
// Write delays not needed for read-only calibration and signature memories // Write delays not needed for read-only calibration and signature memories
if(strcmp(m->desc, "calibration") && strcmp(m->desc, "signature")) { if(strcmp(m->desc, "calibration") && strcmp(m->desc, "signature")) {
if(!(p->flags & (AVRPART_HAS_PDI | AVRPART_HAS_UPDI | AVRPART_HAS_TPI | AVRPART_AVR32))) { if(p->prog_modes & PM_ISP) {
if(m->min_write_delay == m->max_write_delay) if(m->min_write_delay == m->max_write_delay)
dev_info(".wd_%s %.3f ms %s\n", m->desc, m->min_write_delay/1000.0, p->desc); dev_info(".wd_%s %.3f ms %s\n", m->desc, m->min_write_delay/1000.0, p->desc);
else { else {
@ -1189,6 +1224,7 @@ static void dev_pgm_strct(const PROGRAMMER *pgm, bool tsv, const PROGRAMMER *bas
_if_pgmout_str(strcmp, cfg_escape(pgm->desc), desc); _if_pgmout_str(strcmp, cfg_escape(pgm->desc), desc);
if(!base || base->initpgm != pgm->initpgm) if(!base || base->initpgm != pgm->initpgm)
_pgmout_fmt("type", "\"%s\"", locate_programmer_type_id(pgm->initpgm)); _pgmout_fmt("type", "\"%s\"", locate_programmer_type_id(pgm->initpgm));
_if_pgmout_str(intcmp, cfg_strdup("dev_pgm_strct()", prog_modes_str(pgm->prog_modes)), prog_modes);
if(!base || base->conntype != pgm->conntype) if(!base || base->conntype != pgm->conntype)
_pgmout_fmt("connection_type", "%s", connstr(pgm->conntype)); _pgmout_fmt("connection_type", "%s", connstr(pgm->conntype));
_if_pgmout(intcmp, "%d", baudrate); _if_pgmout(intcmp, "%d", baudrate);

View File

@ -1694,28 +1694,32 @@ The format of the programmer definition is as follows:
@smallexample @smallexample
programmer programmer
parent <id> # <id> is a quoted string parent <id> # optional parent
id = <id1> [, <id2> [, <id3>] ...] ; # <idN> are quoted strings id = <id1> [, <id2> ... ] ; # <idN> are quoted strings
desc = <description> ; # quoted string desc = <description> ; # quoted string
type = "par" | "stk500" | ... ; # programmer type (see below for a list) type = <type>; # programmer type, quoted string
baudrate = <num> ; # baudrate for serial ports # supported types can be listed by "-c ?type"
vcc = <num1> [, <num2> ... ] ; # pin number(s) prog_modes = PM_<i/f> @{ | PM_<i/f> @} # interfaces, eg, PM_SPM|PM_PDI
buff = <num1> [, <num2> ... ] ; # pin number(s) connection_type = parallel | serial | usb | spi
reset = <num> ; # pin number baudrate = <num> ; # baudrate for avr910-programmer
sck = <num> ; # pin number vcc = <pin1> [, <pin2> ... ] ; # pin number(s)
mosi = <num> ; # pin number buff = <pin1> [, <pin2> ... ] ; # pin number(s)
miso = <num> ; # pin number reset = <pin> ; # pin number
errled = <num> ; # pin number sck = <pin> ; # pin number
rdyled = <num> ; # pin number mosi = <pin> ; # pin number
pgmled = <num> ; # pin number miso = <pin> ; # pin number
vfyled = <num> ; # pin number errled = <pin> ; # pin number
usbvid = <hexnum>; # USB VID (Vendor ID) rdyled = <pin> ; # pin number
usbpid = <hexnum> [, <hexnum> ...]; # USB PID (Product ID) pgmled = <pin> ; # pin number
usbdev = <interface>; # USB interface or other device info vfyled = <pin> ; # pin number
usbvendor = <vendorname>; # USB Vendor Name usbvid = <hexnum> ; # USB VID (Vendor ID)
usbproduct = <productname>; # USB Product Name usbpid = <hexnum> [, <hexnum> ...] ; # USB PID (Product ID)
usbsn = <serialno>; # USB Serial Number usbdev = <interface> ; # USB interface or other device info
; usbvendor = <vendorname> ; # USB Vendor Name
usbproduct = <productname> ; # USB Product Name
usbsn = <serialno> ; # USB Serial Number
hvupdi_support = <num> [, <num>, ... ] ; # UPDI HV Variants Support
;
@end smallexample @end smallexample
@noindent @noindent
@ -1723,13 +1727,29 @@ If a parent is specified, all settings of it (except its ids) are used for the n
programmer. These values can be changed by new setting them for the new programmer. programmer. These values can be changed by new setting them for the new programmer.
@noindent @noindent
To invert a bit in the pin definitions, use @code{= ~ <num>}. Known programming modes are
@itemize @bullet
@item @code{PM_SPM}: Bootloaders, self-programming with SPM opcodes or NVM Controllers
@item @code{PM_TPI}: Tiny Programming Interface (t4, t5, t9, t10, t20, t40, t102, t104)
@item @code{PM_ISP}: SPI programming for In-System Programming (almost all classic parts)
@item @code{PM_PDI}: Program and Debug Interface (xmega parts)
@item @code{PM_UPDI}: Unified Program and Debug Interface
@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_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_aWire}: AVR32 parts
@end itemize
@noindent
To invert a bit in the pin definitions, use @code{= ~ <num>}. To invert a pin list
(all pins get inverted) use @code{~ ( <num1> [, <num2> ... ] )}.
@noindent @noindent
Not all programmer types can handle a list of USB PIDs. Not all programmer types can handle a list of USB PIDs.
@noindent @noindent
Following programmer types are currently implemented: The following programmer types are currently implemented:
@multitable @columnfractions .25 .6 @multitable @columnfractions .25 .6
@include programmer_types.texi @include programmer_types.texi
@ -1743,30 +1763,36 @@ Following programmer types are currently implemented:
@smallexample @smallexample
part part
id = <id> ; # quoted string
desc = <description> ; # quoted string desc = <description> ; # quoted string
family_id = <description> ; # quoted string id = <id> ; # quoted string
has_jtag = <yes/no> ; # part has JTAG i/f family_id = <id> ; # quoted string, eg, "megaAVR" or "tinyAVR"
has_debugwire = <yes/no> ; # part has debugWire i/f prog_modes = PM_<i/f> @{| PM_<i/f>@} # interfaces, eg, PM_SPM|PM_ISP|PM_HVPP|PM_debugWIRE
has_pdi = <yes/no> ; # part has PDI i/f mcuid = <num>; # unique id in 0..2039 for 8-bit AVRs
has_updi = <yes/no> ; # part has UPDI i/f n_interrupts = <num>; # number of interrupts, used for vector bootloaders
has_tpi = <yes/no> ; # part has TPI i/f n_page_erase = <num>; # if set, number of pages erased during NVM erase
devicecode = <num> ; # numeric hvupdi_variant = <num> ; # numeric -1 (n/a) or 0..2
devicecode = <num> ; # deprecated, use stk500_devcode
stk500_devcode = <num> ; # numeric stk500_devcode = <num> ; # numeric
avr910_devcode = <num> ; # numeric avr910_devcode = <num> ; # numeric
has_jtag = <yes/no> ; # part has JTAG i/f (deprecated, use prog_modes)
has_debugwire = <yes/no> ; # part has debugWire i/f (deprecated, use prog_modes)
has_pdi = <yes/no> ; # part has PDI i/f (deprecated, use prog_modes)
has_updi = <yes/no> ; # part has UPDI i/f (deprecated, use prog_modes)
has_tpi = <yes/no> ; # part has TPI i/f (deprecated, use prog_modes)
is_avr32 = <yes/no> ; # AVR32 part (deprecated, use prog_modes)
is_at90s1200 = <yes/no> ; # AT90S1200 part
signature = <num> <num> <num> ; # signature bytes signature = <num> <num> <num> ; # signature bytes
usbpid = <num> ; # DFU USB PID usbpid = <num> ; # DFU USB PID
reset = dedicated | io;
retry_pulse = reset | sck;
pgm_enable = <instruction format> ;
chip_erase = <instruction format> ;
chip_erase_delay = <num> ; # micro-seconds chip_erase_delay = <num> ; # micro-seconds
reset = dedicated | io ;
retry_pulse = reset | sck ;
chip_erase_delay = <num> ; # chip erase delay (us)
# STK500 parameters (parallel programming IO lines) # STK500 parameters (parallel programming IO lines)
pagel = <num> ; # pin name in hex, i.e., 0xD7 pagel = <num> ; # pin name in hex, i.e., 0xD7
bs2 = <num> ; # pin name in hex, i.e., 0xA0 bs2 = <num> ; # pin name in hex, i.e., 0xA0
serial = <yes/no> ; # can use serial downloading serial = <yes/no> ; # can use serial downloading
parallel = <yes/no/pseudo>; # can use par. programming parallel = <yes/no/pseudo> ; # can use par. programming
# STK500v2 parameters, to be taken from Atmel's XML files # STK500v2 parameters, to be taken from Atmel's ATDF files
timeout = <num> ; timeout = <num> ;
stabdelay = <num> ; stabdelay = <num> ;
cmdexedelay = <num> ; cmdexedelay = <num> ;
@ -1777,52 +1803,59 @@ part
predelay = <num> ; predelay = <num> ;
postdelay = <num> ; postdelay = <num> ;
pollmethod = <num> ; pollmethod = <num> ;
mode = <num> ;
delay = <num> ;
blocksize = <num> ;
readsize = <num> ;
hvspcmdexedelay = <num> ; hvspcmdexedelay = <num> ;
# STK500v2 HV programming parameters, from XML # STK500v2 HV programming parameters, from ATDFs
pp_controlstack = <num>, <num>, ...; # PP only pp_controlstack = <num>, <num>, ... ; # PP only
hvsp_controlstack = <num>, <num>, ...; # HVSP only hvsp_controlstack = <num>, <num>, ... ; # HVSP only
hventerstabdelay = <num>; flash_instr = <num>, <num>, <num> ;
progmodedelay = <num>; # PP only eeprom_instr = <num>, <num>, ... ;
latchcycles = <num>; hventerstabdelay = <num> ;
togglevtg = <num>; progmodedelay = <num> ; # PP only
poweroffdelay = <num>; latchcycles = <num> ;
resetdelayms = <num>; togglevtg = <num> ;
resetdelayus = <num>; poweroffdelay = <num> ;
hvleavestabdelay = <num>; resetdelayms = <num> ;
resetdelay = <num>; resetdelayus = <num> ;
synchcycles = <num>; # HVSP only hvleavestabdelay = <num> ;
chiperasepulsewidth = <num>; # PP only resetdelay = <num> ;
chiperasepolltimeout = <num>; synchcycles = <num> ; # HVSP only
chiperasetime = <num>; # HVSP only chiperasepulsewidth = <num> ; # PP only
programfusepulsewidth = <num>; # PP only chiperasepolltimeout = <num> ;
programfusepolltimeout = <num>; chiperasetime = <num> ; # HVSP only
programlockpulsewidth = <num>; # PP only programfusepulsewidth = <num> ; # PP only
programlockpolltimeout = <num>; programfusepolltimeout = <num> ;
# JTAG ICE mkII parameters, also from XML files programlockpulsewidth = <num> ; # PP only
programlockpolltimeout = <num> ;
# JTAG ICE mkII parameters, also from ATDF files
allowfullpagebitstream = <yes/no> ; allowfullpagebitstream = <yes/no> ;
enablepageprogramming = <yes/no> ; enablepageprogramming = <yes/no> ;
idr = <num> ; # IO addr of IDR (OCD) reg. idr = <num> ; # IO addr of IDR (OCD) reg
rampz = <num> ; # IO addr of RAMPZ reg. rampz = <num> ; # IO addr of RAMPZ reg
spmcr = <num> ; # mem addr of SPMC[S]R reg. spmcr = <num> ; # mem addr of SPMC[S]R reg
eecr = <num> ; # mem addr of EECR reg. eecr = <num> ; # mem addr of EECR reg only when != 0x3f
# (only when != 0x3F) mcu_base = <num> ;
is_at90s1200 = <yes/no> ; # AT90S1200 part nvm_base = <num> ;
is_avr32 = <yes/no> ; # AVR32 part ocd_base = <num> ;
ocdrev = <num> ;
pgm_enable = <instruction format> ;
chip_erase = <instruction format> ;
memory <memtype> memory <memtype>
paged = <yes/no> ; # yes / no paged = <yes/no> ; # yes/no (flash only, do not use for EEPROM)
offset = <num> ; # memory offset
size = <num> ; # bytes size = <num> ; # bytes
page_size = <num> ; # bytes page_size = <num> ; # bytes
num_pages = <num> ; # numeric num_pages = <num> ; # numeric
min_write_delay = <num> ; # micro-seconds min_write_delay = <num> ; # micro-seconds
max_write_delay = <num> ; # micro-seconds max_write_delay = <num> ; # micro-seconds
readback_p1 = <num> ; # byte value readback = <num> <num> ; # pair of byte values
readback_p2 = <num> ; # byte value readback_p1 = <num> ; # byte value (first component)
pwroff_after_write = <yes/no> ; # yes / no readback_p2 = <num> ; # byte value (second component)
pwroff_after_write = <yes/no> ; # yes/no
mode = <num> ; # STK500 v2 file parameter from ATDF files
delay = <num> ; # "
blocksize = <num> ; # "
readsize = <num> ; # "
read = <instruction format> ; read = <instruction format> ;
write = <instruction format> ; write = <instruction format> ;
read_lo = <instruction format> ; read_lo = <instruction format> ;
@ -1833,9 +1866,19 @@ part
loadpage_hi = <instruction format> ; loadpage_hi = <instruction format> ;
writepage = <instruction format> ; writepage = <instruction format> ;
; ;
; ;
@end smallexample @end smallexample
@noindent
If any of the above parameters are not specified, the default value
of 0 is used for numerics (except for @code{mcuid}, @code{hvupdi_variant} and @code{ocdrev},
where the default value is -1) or the empty string @code{""} for string
values. If a required parameter is left empty, AVRDUDE will complain.
Almost all occurrences of numbers (with the exception of pin numbers
and where they are separated by space, eg, in signature and readback)
can also be given as simple expressions involving arithemtic and
bitwise operators.
@menu @menu
* Parent Part:: * Parent Part::
* Instruction Format:: * Instruction Format::
@ -1848,11 +1891,19 @@ part
@subsection Parent Part @subsection Parent Part
@noindent @noindent
Parts can also inherit parameters from previously defined parts Parts can also inherit parameters from previously defined parts using
using the following syntax. In this case specified integer and the following syntax. In this case specified integer and string values
string values override parameter values from the parent part. New override parameter values from the parent part. New memory definitions
memory definitions are added to the definitions inherited from the are added to the definitions inherited from the parent. If, however, a
parent. new memory definition refers to an existing one of the same name for
that part then, from v7.1, the existing memory definition is extended,
and components overwritten with new values. Assigning @code{NULL}
removes an inherited SPI instruction format, memory definition, control
stack, eeprom or flash instruction, eg, as in @code{memory "efuse" =
NULL;}
@noindent
Example format for part inheritance:
@smallexample @smallexample
part parent <id> # quoted string part parent <id> # quoted string
@ -1914,7 +1965,22 @@ write = "1 1 0 0 0 0 0 0 x x x x x x x x",
@end smallexample @end smallexample
As the address bit numbers in the SPI opcodes are highly systematic, they
don't really need to be specified. A compact version of the format
specification neither uses bit-numbers for address lines nor spaces. If such
a string is longer than 7 characters, then the characters @code{0}, @code{1},
@code{x}, @code{a}, @code{i} and @code{o} will be recognised as the
corresponding bit, whilst any of the characters @code{.}, @code{-}, @code{_}
or @code{/} can act as arbitrary visual separators, which are ignored.
Examples:
@smallexample
loadpage_lo = "0100.0000--000x.xxxx--xxaa.aaaa--iiii.iiii";
loadpage_lo = "0100.0000", "000x.xxxx", "xxaa.aaaa", "iiii.iiii";
@end smallexample
@c @c
@c Node @c Node

View File

@ -778,7 +778,7 @@ static int elf_mem_limits(AVRMEM *mem, struct avrpart * p,
{ {
int rv = 0; int rv = 0;
if (p->flags & AVRPART_AVR32) { if (p->prog_modes & PM_aWire) { // AVR32
if (strcmp(mem->desc, "flash") == 0) { if (strcmp(mem->desc, "flash") == 0) {
*lowbound = 0x80000000; *lowbound = 0x80000000;
*highbound = 0xffffffff; *highbound = 0xffffffff;
@ -850,7 +850,7 @@ static int elf2b(char * infile, FILE * inf,
* sections out of an ELF file that contains section data for more * sections out of an ELF file that contains section data for more
* than one sub-segment. * than one sub-segment.
*/ */
if ((p->flags & AVRPART_HAS_PDI) != 0 && if ((p->prog_modes & PM_PDI) != 0 &&
(strcmp(mem->desc, "boot") == 0 || (strcmp(mem->desc, "boot") == 0 ||
strcmp(mem->desc, "application") == 0 || strcmp(mem->desc, "application") == 0 ||
strcmp(mem->desc, "apptable") == 0)) { strcmp(mem->desc, "apptable") == 0)) {
@ -893,7 +893,7 @@ static int elf2b(char * infile, FILE * inf,
const char *endianname; const char *endianname;
unsigned char endianess; unsigned char endianess;
if (p->flags & AVRPART_AVR32) { if (p->prog_modes & PM_aWire) { // AVR32
endianess = ELFDATA2MSB; endianess = ELFDATA2MSB;
endianname = "little"; endianname = "little";
} else { } else {
@ -923,7 +923,7 @@ static int elf2b(char * infile, FILE * inf,
const char *mname; const char *mname;
uint16_t machine; uint16_t machine;
if (p->flags & AVRPART_AVR32) { if (p->prog_modes & PM_aWire) {
machine = EM_AVR32; machine = EM_AVR32;
mname = "AVR32"; mname = "AVR32";
} else { } else {
@ -1383,14 +1383,7 @@ int fileio_setparms(int op, struct fioparms * fp,
* AVR32 devices maintain their load offset within the file itself, * AVR32 devices maintain their load offset within the file itself,
* but AVRDUDE maintains all memory images 0-based. * but AVRDUDE maintains all memory images 0-based.
*/ */
if ((p->flags & AVRPART_AVR32) != 0) fp->fileoffset = p->prog_modes & PM_aWire? m->offset: 0;
{
fp->fileoffset = m->offset;
}
else
{
fp->fileoffset = 0;
}
return 0; return 0;
} }

View File

@ -239,7 +239,7 @@ int flip1_initialize(const PROGRAMMER *pgm, const AVRPART *part) {
} else { } else {
pid = part->usbpid; pid = part->usbpid;
} }
if (!ovsigck && (part->flags & AVRPART_HAS_PDI)) { if (!ovsigck && (part->prog_modes & PM_PDI)) {
avrdude_message(MSG_INFO, "%s: \"flip1\" (FLIP protocol version 1) is for AT90USB* and ATmega*U* devices.\n" avrdude_message(MSG_INFO, "%s: \"flip1\" (FLIP protocol version 1) is for AT90USB* and ATmega*U* devices.\n"
"%s For Xmega devices, use \"flip2\".\n" "%s For Xmega devices, use \"flip2\".\n"
"%s (Use -F to bypass this check.)\n", "%s (Use -F to bypass this check.)\n",

View File

@ -234,7 +234,7 @@ int flip2_initialize(const PROGRAMMER *pgm, const AVRPART *part) {
pid = part->usbpid; pid = part->usbpid;
} }
if (!ovsigck && !(part->flags & AVRPART_HAS_PDI)) { if (!ovsigck && !(part->prog_modes & PM_PDI)) {
avrdude_message(MSG_INFO, "%s: \"flip2\" (FLIP protocol version 2) is for Xmega devices.\n" avrdude_message(MSG_INFO, "%s: \"flip2\" (FLIP protocol version 2) is for Xmega devices.\n"
"%s For AT90USB* or ATmega*U* devices, use \"flip1\".\n" "%s For AT90USB* or ATmega*U* devices, use \"flip1\".\n"
"%s (Use -F to bypass this check.)\n", "%s (Use -F to bypass this check.)\n",

View File

@ -343,7 +343,7 @@ static int ft245r_chip_erase(const PROGRAMMER *pgm, const AVRPART *p) {
unsigned char cmd[4] = {0,0,0,0}; unsigned char cmd[4] = {0,0,0,0};
unsigned char res[4]; unsigned char res[4];
if (p->flags & AVRPART_HAS_TPI) if (p->prog_modes & PM_TPI)
return avr_tpi_chip_erase(pgm, p); return avr_tpi_chip_erase(pgm, p);
if (p->op[AVR_OP_CHIP_ERASE] == NULL) { if (p->op[AVR_OP_CHIP_ERASE] == NULL) {
@ -502,7 +502,7 @@ static int ft245r_program_enable(const PROGRAMMER *pgm, const AVRPART *p) {
unsigned char res[4]; unsigned char res[4];
int i; int i;
if (p->flags & AVRPART_HAS_TPI) if (p->prog_modes & PM_TPI)
return avr_tpi_program_enable(pgm, p, TPIPCR_GT_0b); return avr_tpi_program_enable(pgm, p, TPIPCR_GT_0b);
if (p->op[AVR_OP_PGM_ENABLE] == NULL) { if (p->op[AVR_OP_PGM_ENABLE] == NULL) {
@ -565,7 +565,7 @@ static int ft245r_initialize(const PROGRAMMER *pgm, const AVRPART *p) {
*/ */
ft245r_usleep(pgm, 20000); // 20ms ft245r_usleep(pgm, 20000); // 20ms
if (p->flags & AVRPART_HAS_TPI) { if (p->prog_modes & PM_TPI) {
bool io_link_ok = true; bool io_link_ok = true;
uint8_t byte; uint8_t byte;
int i; int i;

View File

@ -1064,19 +1064,19 @@ static int jtag3_initialize(const PROGRAMMER *pgm, const AVRPART *p) {
if (pgm->flag & PGM_FL_IS_DW) { if (pgm->flag & PGM_FL_IS_DW) {
ifname = "debugWire"; ifname = "debugWire";
if (p->flags & AVRPART_HAS_DW) if (p->prog_modes & PM_debugWIRE)
conn = PARM3_CONN_DW; conn = PARM3_CONN_DW;
} else if (pgm->flag & PGM_FL_IS_PDI) { } else if (pgm->flag & PGM_FL_IS_PDI) {
ifname = "PDI"; ifname = "PDI";
if (p->flags & AVRPART_HAS_PDI) if (p->prog_modes & PM_PDI)
conn = PARM3_CONN_PDI; conn = PARM3_CONN_PDI;
} else if (pgm->flag & PGM_FL_IS_UPDI) { } else if (pgm->flag & PGM_FL_IS_UPDI) {
ifname = "UPDI"; ifname = "UPDI";
if (p->flags & AVRPART_HAS_UPDI) if (p->prog_modes & PM_UPDI)
conn = PARM3_CONN_UPDI; conn = PARM3_CONN_UPDI;
} else { } else {
ifname = "JTAG"; ifname = "JTAG";
if (p->flags & AVRPART_HAS_JTAG) if (p->prog_modes & PM_JTAG)
conn = PARM3_CONN_JTAG; conn = PARM3_CONN_JTAG;
} }
@ -1086,11 +1086,11 @@ static int jtag3_initialize(const PROGRAMMER *pgm, const AVRPART *p) {
return -1; return -1;
} }
if (p->flags & AVRPART_HAS_PDI) if (p->prog_modes & PM_PDI)
parm[0] = PARM3_ARCH_XMEGA; parm[0] = PARM3_ARCH_XMEGA;
else if (p->flags & AVRPART_HAS_UPDI) else if (p->prog_modes & PM_UPDI)
parm[0] = PARM3_ARCH_UPDI; parm[0] = PARM3_ARCH_UPDI;
else if (p->flags & AVRPART_HAS_DW) else if (p->prog_modes & PM_debugWIRE)
parm[0] = PARM3_ARCH_TINY; parm[0] = PARM3_ARCH_TINY;
else else
parm[0] = PARM3_ARCH_MEGA; parm[0] = PARM3_ARCH_MEGA;
@ -1108,7 +1108,7 @@ static int jtag3_initialize(const PROGRAMMER *pgm, const AVRPART *p) {
if (conn == PARM3_CONN_PDI || conn == PARM3_CONN_UPDI) if (conn == PARM3_CONN_PDI || conn == PARM3_CONN_UPDI)
PDATA(pgm)->set_sck = jtag3_set_sck_xmega_pdi; PDATA(pgm)->set_sck = jtag3_set_sck_xmega_pdi;
else if (conn == PARM3_CONN_JTAG) { else if (conn == PARM3_CONN_JTAG) {
if (p->flags & AVRPART_HAS_PDI) if (p->prog_modes & PM_PDI)
PDATA(pgm)->set_sck = jtag3_set_sck_xmega_jtag; PDATA(pgm)->set_sck = jtag3_set_sck_xmega_jtag;
else else
PDATA(pgm)->set_sck = jtag3_set_sck_mega_jtag; PDATA(pgm)->set_sck = jtag3_set_sck_mega_jtag;
@ -1137,7 +1137,7 @@ static int jtag3_initialize(const PROGRAMMER *pgm, const AVRPART *p) {
} }
/* set device descriptor data */ /* set device descriptor data */
if ((p->flags & AVRPART_HAS_PDI)) if ((p->prog_modes & PM_PDI))
{ {
struct xmega_device_desc xd; struct xmega_device_desc xd;
LNODEID ln; LNODEID ln;
@ -1182,7 +1182,7 @@ static int jtag3_initialize(const PROGRAMMER *pgm, const AVRPART *p) {
if (jtag3_setparm(pgm, SCOPE_AVR, 2, PARM3_DEVICEDESC, (unsigned char *)&xd, sizeof xd) < 0) if (jtag3_setparm(pgm, SCOPE_AVR, 2, PARM3_DEVICEDESC, (unsigned char *)&xd, sizeof xd) < 0)
return -1; return -1;
} }
else if ((p->flags & AVRPART_HAS_UPDI)) else if ((p->prog_modes & PM_UPDI))
{ {
struct updi_device_desc xd; struct updi_device_desc xd;
LNODEID ln; LNODEID ln;
@ -1247,7 +1247,7 @@ static int jtag3_initialize(const PROGRAMMER *pgm, const AVRPART *p) {
// Generate UPDI high-voltage pulse if user asks for it and hardware supports it // Generate UPDI high-voltage pulse if user asks for it and hardware supports it
LNODEID support; LNODEID support;
if (p->flags & AVRPART_HAS_UPDI && if (p->prog_modes & PM_UPDI &&
PDATA(pgm)->use_hvupdi == true && PDATA(pgm)->use_hvupdi == true &&
p->hvupdi_variant != HV_UPDI_VARIANT_1) { p->hvupdi_variant != HV_UPDI_VARIANT_1) {
parm[0] = PARM3_UPDI_HV_NONE; parm[0] = PARM3_UPDI_HV_NONE;
@ -1332,7 +1332,7 @@ static int jtag3_initialize(const PROGRAMMER *pgm, const AVRPART *p) {
int ocdrev; int ocdrev;
/* lacking a proper definition, guess the OCD revision */ /* lacking a proper definition, guess the OCD revision */
if (p->flags & AVRPART_HAS_DW) if (p->prog_modes & PM_debugWIRE)
ocdrev = 1; /* exception: ATtiny13, 2313, 4313 */ ocdrev = 1; /* exception: ATtiny13, 2313, 4313 */
else if (flashsize > 128 * 1024) else if (flashsize > 128 * 1024)
ocdrev = 4; ocdrev = 4;
@ -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->flags & AVRPART_HAS_JTAG) if(strcmp(pgm->type, "JTAGICE3") == 0 && (p->prog_modes & PM_JTAG))
avrdude_message(MSG_INFO, "%s: JTAGEN fuse disabled?\n", progname); avrdude_message(MSG_INFO, "%s: JTAGEN fuse disabled?\n", progname);
return -1; return -1;
} }
@ -1394,7 +1394,7 @@ static int jtag3_initialize(const PROGRAMMER *pgm, const AVRPART *p) {
* doesn't apply here anyway), the response is just RSP_OK. * doesn't apply here anyway), the response is just RSP_OK.
*/ */
if (resp[1] == RSP3_DATA && status >= 7) { if (resp[1] == RSP3_DATA && status >= 7) {
if (p->flags & AVRPART_HAS_UPDI) { if (p->prog_modes & PM_UPDI) {
/* Partial Family_ID has been returned */ /* Partial Family_ID has been returned */
avrdude_message(MSG_NOTICE, "%s: Partial Family_ID returned: \"%c%c%c%c\"\n", avrdude_message(MSG_NOTICE, "%s: Partial Family_ID returned: \"%c%c%c%c\"\n",
progname, resp[3], resp[4], resp[5], resp[6]); progname, resp[3], resp[4], resp[5], resp[6]);
@ -1408,11 +1408,8 @@ static int jtag3_initialize(const PROGRAMMER *pgm, const AVRPART *p) {
free(resp); free(resp);
PDATA(pgm)->boot_start = ULONG_MAX; PDATA(pgm)->boot_start = ULONG_MAX;
if ((p->flags & AVRPART_HAS_PDI)) { if (p->prog_modes & PM_PDI) {
/* // Find the border between application and boot area
* Find out where the border between application and boot area
* is.
*/
AVRMEM *bootmem = avr_locate_mem(p, "boot"); AVRMEM *bootmem = avr_locate_mem(p, "boot");
AVRMEM *flashmem = avr_locate_mem(p, "flash"); AVRMEM *flashmem = avr_locate_mem(p, "flash");
if (bootmem == NULL || flashmem == NULL) { if (bootmem == NULL || flashmem == NULL) {
@ -1690,7 +1687,7 @@ static int jtag3_page_erase(const PROGRAMMER *pgm, const AVRPART *p, const AVRME
avrdude_message(MSG_NOTICE2, "%s: jtag3_page_erase(.., %s, 0x%x)\n", avrdude_message(MSG_NOTICE2, "%s: jtag3_page_erase(.., %s, 0x%x)\n",
progname, m->desc, addr); progname, m->desc, addr);
if (!(p->flags & AVRPART_HAS_PDI)) { if (!(p->prog_modes & PM_PDI)) {
avrdude_message(MSG_INFO, "%s: jtag3_page_erase: not an Xmega device\n", avrdude_message(MSG_INFO, "%s: jtag3_page_erase: not an Xmega device\n",
progname); progname);
return -1; return -1;
@ -1764,7 +1761,7 @@ static int jtag3_paged_write(const PROGRAMMER *pgm, const AVRPART *p, const AVRM
if (strcmp(m->desc, "flash") == 0) { if (strcmp(m->desc, "flash") == 0) {
PDATA(pgm)->flash_pageaddr = (unsigned long)-1L; PDATA(pgm)->flash_pageaddr = (unsigned long)-1L;
cmd[3] = jtag3_memtype(pgm, p, addr); cmd[3] = jtag3_memtype(pgm, p, addr);
if (p->flags & AVRPART_HAS_PDI) if (p->prog_modes & PM_PDI)
/* dynamically decide between flash/boot memtype */ /* dynamically decide between flash/boot memtype */
dynamic_memtype = 1; dynamic_memtype = 1;
} else if (strcmp(m->desc, "eeprom") == 0) { } else if (strcmp(m->desc, "eeprom") == 0) {
@ -1783,14 +1780,14 @@ static int jtag3_paged_write(const PROGRAMMER *pgm, const AVRPART *p, const AVRM
free(cmd); free(cmd);
return n_bytes; return n_bytes;
} }
cmd[3] = ( p->flags & AVRPART_HAS_PDI || p->flags & AVRPART_HAS_UPDI ) ? MTYPE_EEPROM_XMEGA : MTYPE_EEPROM_PAGE; cmd[3] = p->prog_modes & (PM_PDI | PM_UPDI)? MTYPE_EEPROM_XMEGA: MTYPE_EEPROM_PAGE;
PDATA(pgm)->eeprom_pageaddr = (unsigned long)-1L; PDATA(pgm)->eeprom_pageaddr = (unsigned long)-1L;
} else if (strcmp(m->desc, "usersig") == 0 || } else if (strcmp(m->desc, "usersig") == 0 ||
strcmp(m->desc, "userrow") == 0) { strcmp(m->desc, "userrow") == 0) {
cmd[3] = MTYPE_USERSIG; cmd[3] = MTYPE_USERSIG;
} else if (strcmp(m->desc, "boot") == 0) { } else if (strcmp(m->desc, "boot") == 0) {
cmd[3] = MTYPE_BOOT_FLASH; cmd[3] = MTYPE_BOOT_FLASH;
} else if ( p->flags & AVRPART_HAS_PDI || p->flags & AVRPART_HAS_UPDI ) { } else if (p->prog_modes & (PM_PDI | PM_UPDI)) {
cmd[3] = MTYPE_FLASH; cmd[3] = MTYPE_FLASH;
} else { } else {
cmd[3] = MTYPE_SPM; cmd[3] = MTYPE_SPM;
@ -1868,11 +1865,11 @@ static int jtag3_paged_load(const PROGRAMMER *pgm, const AVRPART *p, const AVRME
if (strcmp(m->desc, "flash") == 0) { if (strcmp(m->desc, "flash") == 0) {
cmd[3] = jtag3_memtype(pgm, p, addr); cmd[3] = jtag3_memtype(pgm, p, addr);
if (p->flags & AVRPART_HAS_PDI) if (p->prog_modes & PM_PDI)
/* dynamically decide between flash/boot memtype */ /* dynamically decide between flash/boot memtype */
dynamic_memtype = 1; dynamic_memtype = 1;
} else if (strcmp(m->desc, "eeprom") == 0) { } else if (strcmp(m->desc, "eeprom") == 0) {
cmd[3] = ( p->flags & AVRPART_HAS_PDI || p->flags & AVRPART_HAS_UPDI ) ? MTYPE_EEPROM : MTYPE_EEPROM_PAGE; cmd[3] = p->prog_modes & (PM_PDI | PM_UPDI)? MTYPE_EEPROM: MTYPE_EEPROM_PAGE;
if (pgm->flag & PGM_FL_IS_DW) if (pgm->flag & PGM_FL_IS_DW)
return -1; return -1;
} else if (strcmp(m->desc, "prodsig") == 0) { } else if (strcmp(m->desc, "prodsig") == 0) {
@ -1882,9 +1879,9 @@ static int jtag3_paged_load(const PROGRAMMER *pgm, const AVRPART *p, const AVRME
cmd[3] = MTYPE_USERSIG; cmd[3] = MTYPE_USERSIG;
} else if (strcmp(m->desc, "boot") == 0) { } else if (strcmp(m->desc, "boot") == 0) {
cmd[3] = MTYPE_BOOT_FLASH; cmd[3] = MTYPE_BOOT_FLASH;
} else if ( p->flags & AVRPART_HAS_PDI ) { } else if (p->prog_modes & PM_PDI) {
cmd[3] = MTYPE_FLASH; cmd[3] = MTYPE_FLASH;
} else if ( p->flags & AVRPART_HAS_UPDI ) { } else if (p->prog_modes & PM_UPDI) {
cmd[3] = MTYPE_SRAM; cmd[3] = MTYPE_SRAM;
} else { } else {
cmd[3] = MTYPE_SPM; cmd[3] = MTYPE_SPM;
@ -1949,7 +1946,7 @@ static int jtag3_read_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM
cmd[1] = CMD3_READ_MEMORY; cmd[1] = CMD3_READ_MEMORY;
cmd[2] = 0; cmd[2] = 0;
cmd[3] = ( p->flags & AVRPART_HAS_PDI || p->flags & AVRPART_HAS_UPDI ) ? MTYPE_FLASH : MTYPE_FLASH_PAGE; cmd[3] = p->prog_modes & (PM_PDI | PM_UPDI)? MTYPE_FLASH: MTYPE_FLASH_PAGE;
if (avr_mem_is_flash_type(mem)) { if (avr_mem_is_flash_type(mem)) {
addr += mem->offset & (512 * 1024 - 1); /* max 512 KiB flash */ addr += mem->offset & (512 * 1024 - 1); /* max 512 KiB flash */
pagesize = PDATA(pgm)->flash_pagesize; pagesize = PDATA(pgm)->flash_pagesize;
@ -1957,7 +1954,7 @@ static int jtag3_read_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM
paddr_ptr = &PDATA(pgm)->flash_pageaddr; paddr_ptr = &PDATA(pgm)->flash_pageaddr;
cache_ptr = PDATA(pgm)->flash_pagecache; cache_ptr = PDATA(pgm)->flash_pagecache;
} else if (avr_mem_is_eeprom_type(mem)) { } else if (avr_mem_is_eeprom_type(mem)) {
if ( (pgm->flag & PGM_FL_IS_DW) || ( p->flags & AVRPART_HAS_PDI ) || ( p->flags & AVRPART_HAS_UPDI ) ) { if ( (pgm->flag & PGM_FL_IS_DW) || (p->prog_modes & PM_PDI) || (p->prog_modes & PM_UPDI) ) {
cmd[3] = MTYPE_EEPROM; cmd[3] = MTYPE_EEPROM;
} else { } else {
cmd[3] = MTYPE_EEPROM_PAGE; cmd[3] = MTYPE_EEPROM_PAGE;
@ -1987,7 +1984,7 @@ static int jtag3_read_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM
unsupp = 1; unsupp = 1;
} else if (matches(mem->desc, "fuse")) { } else if (matches(mem->desc, "fuse")) {
cmd[3] = MTYPE_FUSE_BITS; cmd[3] = MTYPE_FUSE_BITS;
if (!(p->flags & AVRPART_HAS_UPDI)) if (!(p->prog_modes & PM_UPDI))
addr = mem->offset & 7; addr = mem->offset & 7;
} else if (strcmp(mem->desc, "usersig") == 0 || } else if (strcmp(mem->desc, "usersig") == 0 ||
strcmp(mem->desc, "userrow") == 0) { strcmp(mem->desc, "userrow") == 0) {
@ -2117,7 +2114,7 @@ static int jtag3_write_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVRME
cmd[0] = SCOPE_AVR; cmd[0] = SCOPE_AVR;
cmd[1] = CMD3_WRITE_MEMORY; cmd[1] = CMD3_WRITE_MEMORY;
cmd[2] = 0; cmd[2] = 0;
cmd[3] = ( p->flags & AVRPART_HAS_PDI || p->flags & AVRPART_HAS_UPDI ) ? MTYPE_FLASH : MTYPE_SPM; cmd[3] = p->prog_modes & (PM_PDI | PM_UPDI)? MTYPE_FLASH: MTYPE_SPM;
if (strcmp(mem->desc, "flash") == 0) { if (strcmp(mem->desc, "flash") == 0) {
cache_ptr = PDATA(pgm)->flash_pagecache; cache_ptr = PDATA(pgm)->flash_pagecache;
pagesize = PDATA(pgm)->flash_pagesize; pagesize = PDATA(pgm)->flash_pagesize;
@ -2149,7 +2146,7 @@ static int jtag3_write_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVRME
unsupp = 1; unsupp = 1;
} else if (matches(mem->desc, "fuse")) { } else if (matches(mem->desc, "fuse")) {
cmd[3] = MTYPE_FUSE_BITS; cmd[3] = MTYPE_FUSE_BITS;
if (!(p->flags & AVRPART_HAS_UPDI)) if (!(p->prog_modes & PM_UPDI))
addr = mem->offset & 7; addr = mem->offset & 7;
} else if (strcmp(mem->desc, "usersig") == 0 || } else if (strcmp(mem->desc, "usersig") == 0 ||
strcmp(mem->desc, "userrow") == 0) { strcmp(mem->desc, "userrow") == 0) {
@ -2457,7 +2454,7 @@ static void jtag3_print_parms(const PROGRAMMER *pgm) {
} }
static unsigned char jtag3_memtype(const PROGRAMMER *pgm, const AVRPART *p, unsigned long addr) { static unsigned char jtag3_memtype(const PROGRAMMER *pgm, const AVRPART *p, unsigned long addr) {
if ( p->flags & AVRPART_HAS_PDI ) { if (p->prog_modes & PM_PDI) {
if (addr >= PDATA(pgm)->boot_start) if (addr >= PDATA(pgm)->boot_start)
return MTYPE_BOOT_FLASH; return MTYPE_BOOT_FLASH;
else else
@ -2468,7 +2465,7 @@ static unsigned char jtag3_memtype(const PROGRAMMER *pgm, const AVRPART *p, unsi
} }
static unsigned int jtag3_memaddr(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, unsigned long addr) { static unsigned int jtag3_memaddr(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, unsigned long addr) {
if ((p->flags & AVRPART_HAS_PDI) != 0) { if (p->prog_modes & PM_PDI) {
if (addr >= PDATA(pgm)->boot_start) if (addr >= PDATA(pgm)->boot_start)
/* /*
* all memories but "flash" are smaller than boot_start anyway, so * all memories but "flash" are smaller than boot_start anyway, so
@ -2479,10 +2476,9 @@ static unsigned int jtag3_memaddr(const PROGRAMMER *pgm, const AVRPART *p, const
/* normal flash, or anything else */ /* normal flash, or anything else */
return addr; return addr;
} }
/*
* Non-Xmega device. // Non-Xmega device
*/ if (p->prog_modes & PM_UPDI) {
if (p->flags & AVRPART_HAS_UPDI) {
if (strcmp(m->desc, "flash") == 0) { if (strcmp(m->desc, "flash") == 0) {
return addr; return addr;
} }

View File

@ -523,7 +523,7 @@ 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->flags & AVRPART_HAS_JTAG)) { if (!(p->prog_modes & 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;

View File

@ -882,7 +882,7 @@ static int jtagmkII_chip_erase(const PROGRAMMER *pgm, const AVRPART *p) {
int status, len; int status, len;
unsigned char buf[6], *resp, c; unsigned char buf[6], *resp, c;
if (p->flags & (AVRPART_HAS_PDI | AVRPART_HAS_UPDI)) { if (p->prog_modes & (PM_PDI | PM_UPDI)) {
buf[0] = CMND_XMEGA_ERASE; buf[0] = CMND_XMEGA_ERASE;
buf[1] = XMEGA_ERASE_CHIP; buf[1] = XMEGA_ERASE_CHIP;
memset(buf + 2, 0, 4); /* address of area to be erased */ memset(buf + 2, 0, 4); /* address of area to be erased */
@ -893,7 +893,7 @@ static int jtagmkII_chip_erase(const PROGRAMMER *pgm, const AVRPART *p) {
} }
avrdude_message(MSG_NOTICE2, "%s: jtagmkII_chip_erase(): Sending %schip erase command: ", avrdude_message(MSG_NOTICE2, "%s: jtagmkII_chip_erase(): Sending %schip erase command: ",
progname, progname,
(p->flags & (AVRPART_HAS_PDI | AVRPART_HAS_UPDI))? "Xmega ": ""); p->prog_modes & (PM_PDI | PM_UPDI)? "Xmega ": "");
jtagmkII_send(pgm, buf, len); jtagmkII_send(pgm, buf, len);
status = jtagmkII_recv(pgm, &resp); status = jtagmkII_recv(pgm, &resp);
@ -919,7 +919,7 @@ static int jtagmkII_chip_erase(const PROGRAMMER *pgm, const AVRPART *p) {
return -1; return -1;
} }
if (!(p->flags & (AVRPART_HAS_PDI | AVRPART_HAS_UPDI))) if (!(p->prog_modes & (PM_PDI | PM_UPDI)))
pgm->initialize(pgm, p); pgm->initialize(pgm, p);
return 0; return 0;
@ -966,7 +966,7 @@ static void jtagmkII_set_devdescr(const PROGRAMMER *pgm, const AVRPART *p) {
u32_to_b4(sendbuf.dd.ulFlashSize, m->size); u32_to_b4(sendbuf.dd.ulFlashSize, m->size);
u16_to_b2(sendbuf.dd.uiFlashPageSize, m->page_size); u16_to_b2(sendbuf.dd.uiFlashPageSize, m->page_size);
u16_to_b2(sendbuf.dd.uiFlashpages, m->size / m->page_size); u16_to_b2(sendbuf.dd.uiFlashpages, m->size / m->page_size);
if (p->flags & AVRPART_HAS_DW) { if (p->prog_modes & PM_debugWIRE) {
memcpy(sendbuf.dd.ucFlashInst, p->flash_instr, FLASH_INSTR_SIZE); memcpy(sendbuf.dd.ucFlashInst, p->flash_instr, FLASH_INSTR_SIZE);
memcpy(sendbuf.dd.ucEepromInst, p->eeprom_instr, EEPROM_INSTR_SIZE); memcpy(sendbuf.dd.ucEepromInst, p->eeprom_instr, EEPROM_INSTR_SIZE);
} }
@ -975,7 +975,7 @@ static void jtagmkII_set_devdescr(const PROGRAMMER *pgm, const AVRPART *p) {
} }
} }
sendbuf.dd.ucCacheType = sendbuf.dd.ucCacheType =
(p->flags & (AVRPART_HAS_PDI | AVRPART_HAS_UPDI))? 0x02 /* ATxmega */: 0x00; p->prog_modes & (PM_PDI | PM_UPDI)? 0x02 /* ATxmega */: 0x00;
avrdude_message(MSG_NOTICE2, "%s: jtagmkII_set_devdescr(): " avrdude_message(MSG_NOTICE2, "%s: jtagmkII_set_devdescr(): "
"Sending set device descriptor command: ", "Sending set device descriptor command: ",
@ -1290,8 +1290,8 @@ static int jtagmkII_initialize(const PROGRAMMER *pgm, const AVRPART *p) {
const char *ifname; const char *ifname;
/* Abort and print error if programmer does not support the target microcontroller */ /* Abort and print error if programmer does not support the target microcontroller */
if ((strncmp(pgm->type, "JTAGMKII_UPDI", strlen("JTAGMKII_UPDI")) == 0 && !(p->flags & AVRPART_HAS_UPDI)) || if ((strncmp(pgm->type, "JTAGMKII_UPDI", strlen("JTAGMKII_UPDI")) == 0 && !(p->prog_modes & PM_UPDI)) ||
(strncmp(ldata(lfirst(pgm->id)), "jtagmkII", strlen("jtagmkII")) == 0 && p->flags & AVRPART_HAS_UPDI)) { (strncmp(ldata(lfirst(pgm->id)), "jtagmkII", strlen("jtagmkII")) == 0 && (p->prog_modes & PM_UPDI))) {
avrdude_message(MSG_INFO, "ERROR: programmer %s does not support target %s\n\n", avrdude_message(MSG_INFO, "ERROR: programmer %s does not support target %s\n\n",
ldata(lfirst(pgm->id)), p->desc); ldata(lfirst(pgm->id)), p->desc);
return -1; return -1;
@ -1300,15 +1300,15 @@ static int jtagmkII_initialize(const PROGRAMMER *pgm, const AVRPART *p) {
ok = 0; ok = 0;
if (pgm->flag & PGM_FL_IS_DW) { if (pgm->flag & PGM_FL_IS_DW) {
ifname = "debugWire"; ifname = "debugWire";
if (p->flags & AVRPART_HAS_DW) if (p->prog_modes & PM_debugWIRE)
ok = 1; ok = 1;
} else if (pgm->flag & PGM_FL_IS_PDI) { } else if (pgm->flag & PGM_FL_IS_PDI) {
ifname = "PDI"; ifname = "PDI";
if (p->flags & (AVRPART_HAS_PDI | AVRPART_HAS_UPDI)) if (p->prog_modes & (PM_PDI | PM_UPDI))
ok = 1; ok = 1;
} else { } else {
ifname = "JTAG"; ifname = "JTAG";
if (p->flags & AVRPART_HAS_JTAG) if (p->prog_modes & PM_JTAG)
ok = 1; ok = 1;
} }
@ -1350,24 +1350,21 @@ static int jtagmkII_initialize(const PROGRAMMER *pgm, const AVRPART *p) {
* mode from JTAG to JTAG_XMEGA. * mode from JTAG to JTAG_XMEGA.
*/ */
if ((pgm->flag & PGM_FL_IS_JTAG) && if ((pgm->flag & PGM_FL_IS_JTAG) &&
(p->flags & (AVRPART_HAS_PDI | AVRPART_HAS_UPDI))) { (p->prog_modes & (PM_PDI | PM_UPDI))) {
if (jtagmkII_getsync(pgm, EMULATOR_MODE_JTAG_XMEGA) < 0) if (jtagmkII_getsync(pgm, EMULATOR_MODE_JTAG_XMEGA) < 0)
return -1; return -1;
} }
/* /*
* Must set the device descriptor before entering programming mode. * Must set the device descriptor before entering programming mode.
*/ */
if (PDATA(pgm)->fwver >= 0x700 && (p->flags & (AVRPART_HAS_PDI | AVRPART_HAS_UPDI)) != 0) if (PDATA(pgm)->fwver >= 0x700 && (p->prog_modes & (PM_PDI | PM_UPDI)) != 0)
jtagmkII_set_xmega_params(pgm, p); jtagmkII_set_xmega_params(pgm, p);
else else
jtagmkII_set_devdescr(pgm, p); jtagmkII_set_devdescr(pgm, p);
PDATA(pgm)->boot_start = ULONG_MAX; PDATA(pgm)->boot_start = ULONG_MAX;
if ((p->flags & (AVRPART_HAS_PDI | AVRPART_HAS_UPDI))) { if ((p->prog_modes & (PM_PDI | PM_UPDI))) {
/* // Find the border between application and boot area
* Find out where the border between application and boot area
* is.
*/
AVRMEM *bootmem = avr_locate_mem(p, "boot"); AVRMEM *bootmem = avr_locate_mem(p, "boot");
AVRMEM *flashmem = avr_locate_mem(p, "flash"); AVRMEM *flashmem = avr_locate_mem(p, "flash");
if (bootmem == NULL || flashmem == NULL) { if (bootmem == NULL || flashmem == NULL) {
@ -1405,7 +1402,7 @@ static int jtagmkII_initialize(const PROGRAMMER *pgm, const AVRPART *p) {
} }
PDATA(pgm)->flash_pageaddr = PDATA(pgm)->eeprom_pageaddr = (unsigned long)-1L; PDATA(pgm)->flash_pageaddr = PDATA(pgm)->eeprom_pageaddr = (unsigned long)-1L;
if (PDATA(pgm)->fwver >= 0x700 && (p->flags & (AVRPART_HAS_PDI | AVRPART_HAS_UPDI))) { if (PDATA(pgm)->fwver >= 0x700 && (p->prog_modes & (PM_PDI | PM_UPDI))) {
/* /*
* Work around for * Work around for
* https://savannah.nongnu.org/bugs/index.php?37942 * https://savannah.nongnu.org/bugs/index.php?37942
@ -1422,7 +1419,7 @@ static int jtagmkII_initialize(const PROGRAMMER *pgm, const AVRPART *p) {
return -1; return -1;
} }
if ((pgm->flag & PGM_FL_IS_JTAG) && !(p->flags & (AVRPART_HAS_PDI | AVRPART_HAS_UPDI))) { if ((pgm->flag & PGM_FL_IS_JTAG) && !(p->prog_modes & (PM_PDI | PM_UPDI))) {
hfuse.desc = cache_string("hfuse"); hfuse.desc = cache_string("hfuse");
if (jtagmkII_read_byte(pgm, p, &hfuse, 1, &b) < 0) if (jtagmkII_read_byte(pgm, p, &hfuse, 1, &b) < 0)
return -1; return -1;
@ -1887,7 +1884,7 @@ static int jtagmkII_page_erase(const PROGRAMMER *pgm, const AVRPART *p, const AV
avrdude_message(MSG_NOTICE2, "%s: jtagmkII_page_erase(.., %s, 0x%x)\n", avrdude_message(MSG_NOTICE2, "%s: jtagmkII_page_erase(.., %s, 0x%x)\n",
progname, m->desc, addr); progname, m->desc, addr);
if (!(p->flags & (AVRPART_HAS_PDI | AVRPART_HAS_UPDI))) { if (!(p->prog_modes & (PM_PDI | PM_UPDI))) {
avrdude_message(MSG_INFO, "%s: jtagmkII_page_erase: not an Xmega device\n", avrdude_message(MSG_INFO, "%s: jtagmkII_page_erase: not an Xmega device\n",
progname); progname);
return -1; return -1;
@ -2002,7 +1999,7 @@ static int jtagmkII_paged_write(const PROGRAMMER *pgm, const AVRPART *p, const A
if (strcmp(m->desc, "flash") == 0) { if (strcmp(m->desc, "flash") == 0) {
PDATA(pgm)->flash_pageaddr = (unsigned long)-1L; PDATA(pgm)->flash_pageaddr = (unsigned long)-1L;
cmd[1] = jtagmkII_memtype(pgm, p, addr); cmd[1] = jtagmkII_memtype(pgm, p, addr);
if (p->flags & (AVRPART_HAS_PDI | AVRPART_HAS_UPDI)) if (p->prog_modes & (PM_PDI | PM_UPDI))
/* dynamically decide between flash/boot memtype */ /* dynamically decide between flash/boot memtype */
dynamic_memtype = 1; dynamic_memtype = 1;
} else if (strcmp(m->desc, "eeprom") == 0) { } else if (strcmp(m->desc, "eeprom") == 0) {
@ -2021,14 +2018,14 @@ static int jtagmkII_paged_write(const PROGRAMMER *pgm, const AVRPART *p, const A
free(cmd); free(cmd);
return n_bytes; return n_bytes;
} }
cmd[1] = (p->flags & (AVRPART_HAS_PDI | AVRPART_HAS_UPDI)) ? MTYPE_EEPROM : MTYPE_EEPROM_PAGE; cmd[1] = p->prog_modes & (PM_PDI | PM_UPDI)? MTYPE_EEPROM: MTYPE_EEPROM_PAGE;
PDATA(pgm)->eeprom_pageaddr = (unsigned long)-1L; PDATA(pgm)->eeprom_pageaddr = (unsigned long)-1L;
} else if (strcmp(m->desc, "usersig") == 0 || } else if (strcmp(m->desc, "usersig") == 0 ||
strcmp(m->desc, "userrow") == 0) { strcmp(m->desc, "userrow") == 0) {
cmd[1] = MTYPE_USERSIG; cmd[1] = MTYPE_USERSIG;
} else if (strcmp(m->desc, "boot") == 0) { } else if (strcmp(m->desc, "boot") == 0) {
cmd[1] = MTYPE_BOOT_FLASH; cmd[1] = MTYPE_BOOT_FLASH;
} else if (p->flags & (AVRPART_HAS_PDI | AVRPART_HAS_UPDI)) { } else if (p->prog_modes & (PM_PDI | PM_UPDI)) {
cmd[1] = MTYPE_FLASH; cmd[1] = MTYPE_FLASH;
} else { } else {
cmd[1] = MTYPE_SPM; cmd[1] = MTYPE_SPM;
@ -2130,11 +2127,11 @@ static int jtagmkII_paged_load(const PROGRAMMER *pgm, const AVRPART *p, const AV
cmd[0] = CMND_READ_MEMORY; cmd[0] = CMND_READ_MEMORY;
if (strcmp(m->desc, "flash") == 0) { if (strcmp(m->desc, "flash") == 0) {
cmd[1] = jtagmkII_memtype(pgm, p, addr); cmd[1] = jtagmkII_memtype(pgm, p, addr);
if (p->flags & (AVRPART_HAS_PDI | AVRPART_HAS_UPDI)) if (p->prog_modes & (PM_PDI | PM_UPDI))
/* dynamically decide between flash/boot memtype */ /* dynamically decide between flash/boot memtype */
dynamic_memtype = 1; dynamic_memtype = 1;
} else if (strcmp(m->desc, "eeprom") == 0) { } else if (strcmp(m->desc, "eeprom") == 0) {
cmd[1] = (p->flags & (AVRPART_HAS_PDI | AVRPART_HAS_UPDI)) ? MTYPE_EEPROM : MTYPE_EEPROM_PAGE; cmd[1] = p->prog_modes & (PM_PDI | PM_UPDI)? MTYPE_EEPROM: MTYPE_EEPROM_PAGE;
if (pgm->flag & PGM_FL_IS_DW) if (pgm->flag & PGM_FL_IS_DW)
return -1; return -1;
} else if (strcmp(m->desc, "prodsig") == 0) { } else if (strcmp(m->desc, "prodsig") == 0) {
@ -2144,7 +2141,7 @@ static int jtagmkII_paged_load(const PROGRAMMER *pgm, const AVRPART *p, const AV
cmd[1] = MTYPE_USERSIG; cmd[1] = MTYPE_USERSIG;
} else if (strcmp(m->desc, "boot") == 0) { } else if (strcmp(m->desc, "boot") == 0) {
cmd[1] = MTYPE_BOOT_FLASH; cmd[1] = MTYPE_BOOT_FLASH;
} else if (p->flags & (AVRPART_HAS_PDI | AVRPART_HAS_UPDI)) { } else if (p->prog_modes & (PM_PDI | PM_UPDI)) {
cmd[1] = MTYPE_FLASH; cmd[1] = MTYPE_FLASH;
} else { } else {
cmd[1] = MTYPE_SPM; cmd[1] = MTYPE_SPM;
@ -2230,14 +2227,14 @@ static int jtagmkII_read_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVR
unsupp = 0; unsupp = 0;
addr += mem->offset; addr += mem->offset;
cmd[1] = ( p->flags & (AVRPART_HAS_PDI | AVRPART_HAS_UPDI) ) ? MTYPE_FLASH : MTYPE_FLASH_PAGE; cmd[1] = p->prog_modes & (PM_PDI | PM_UPDI)? MTYPE_FLASH: MTYPE_FLASH_PAGE;
if (avr_mem_is_flash_type(mem)) { if (avr_mem_is_flash_type(mem)) {
pagesize = PDATA(pgm)->flash_pagesize; pagesize = PDATA(pgm)->flash_pagesize;
paddr = addr & ~(pagesize - 1); paddr = addr & ~(pagesize - 1);
paddr_ptr = &PDATA(pgm)->flash_pageaddr; paddr_ptr = &PDATA(pgm)->flash_pageaddr;
cache_ptr = PDATA(pgm)->flash_pagecache; cache_ptr = PDATA(pgm)->flash_pagecache;
} else if (avr_mem_is_eeprom_type(mem)) { } else if (avr_mem_is_eeprom_type(mem)) {
if ( (pgm->flag & PGM_FL_IS_DW) || ( p->flags & (AVRPART_HAS_PDI | AVRPART_HAS_UPDI) ) ) { if ( (pgm->flag & PGM_FL_IS_DW) || (p->prog_modes & (PM_PDI | PM_UPDI)) ) {
/* debugWire cannot use page access for EEPROM */ /* debugWire cannot use page access for EEPROM */
cmd[1] = MTYPE_EEPROM; cmd[1] = MTYPE_EEPROM;
} else { } else {
@ -2404,7 +2401,7 @@ static int jtagmkII_write_byte(const PROGRAMMER *pgm, const AVRPART *p, const AV
writedata = data; writedata = data;
cmd[0] = CMND_WRITE_MEMORY; cmd[0] = CMND_WRITE_MEMORY;
cmd[1] = ( p->flags & (AVRPART_HAS_PDI | AVRPART_HAS_UPDI) ) ? MTYPE_FLASH : MTYPE_SPM; cmd[1] = p->prog_modes & (PM_PDI | PM_UPDI)? MTYPE_FLASH: MTYPE_SPM;
if (strcmp(mem->desc, "flash") == 0) { if (strcmp(mem->desc, "flash") == 0) {
if ((addr & 1) == 1) { if ((addr & 1) == 1) {
/* odd address = high byte */ /* odd address = high byte */
@ -2418,7 +2415,7 @@ static int jtagmkII_write_byte(const PROGRAMMER *pgm, const AVRPART *p, const AV
if (pgm->flag & PGM_FL_IS_DW) if (pgm->flag & PGM_FL_IS_DW)
unsupp = 1; unsupp = 1;
} else if (strcmp(mem->desc, "eeprom") == 0) { } else if (strcmp(mem->desc, "eeprom") == 0) {
cmd[1] = ( p->flags & (AVRPART_HAS_PDI | AVRPART_HAS_UPDI) ) ? MTYPE_EEPROM_XMEGA: MTYPE_EEPROM; cmd[1] = p->prog_modes & (PM_PDI | PM_UPDI)? MTYPE_EEPROM_XMEGA: MTYPE_EEPROM;
need_progmode = 0; need_progmode = 0;
PDATA(pgm)->eeprom_pageaddr = (unsigned long)-1L; PDATA(pgm)->eeprom_pageaddr = (unsigned long)-1L;
} else if (strcmp(mem->desc, "lfuse") == 0) { } else if (strcmp(mem->desc, "lfuse") == 0) {
@ -2719,7 +2716,7 @@ static void jtagmkII_print_parms(const PROGRAMMER *pgm) {
} }
static unsigned char jtagmkII_memtype(const PROGRAMMER *pgm, const AVRPART *p, unsigned long addr) { static unsigned char jtagmkII_memtype(const PROGRAMMER *pgm, const AVRPART *p, unsigned long addr) {
if ( p->flags & (AVRPART_HAS_PDI | AVRPART_HAS_UPDI) ) { if (p->prog_modes & (PM_PDI | PM_UPDI)) {
if (addr >= PDATA(pgm)->boot_start) if (addr >= PDATA(pgm)->boot_start)
return MTYPE_BOOT_FLASH; return MTYPE_BOOT_FLASH;
else else
@ -2734,7 +2731,7 @@ static unsigned int jtagmkII_memaddr(const PROGRAMMER *pgm, const AVRPART *p, co
* Xmega devices handled by V7+ firmware don't want to be told their * Xmega devices handled by V7+ firmware don't want to be told their
* m->offset within the write memory command. * m->offset within the write memory command.
*/ */
if (PDATA(pgm)->fwver >= 0x700 && (p->flags & (AVRPART_HAS_PDI | AVRPART_HAS_UPDI)) != 0) { if (PDATA(pgm)->fwver >= 0x700 && (p->prog_modes & (PM_PDI | PM_UPDI))) {
if (addr >= PDATA(pgm)->boot_start) if (addr >= PDATA(pgm)->boot_start)
/* /*
* all memories but "flash" are smaller than boot_start anyway, so * all memories but "flash" are smaller than boot_start anyway, so
@ -3572,7 +3569,7 @@ static int jtagmkII_paged_write32(const PROGRAMMER *pgm, const AVRPART *p, const
} }
// Init SMC and set clocks // Init SMC and set clocks
if(!(p->flags & FLAGS32_INIT_SMC)) { if(!(PDATA(pgm)->flags32 & FLAGS32_INIT_SMC)) {
status = jtagmkII_smc_init32(pgm); status = jtagmkII_smc_init32(pgm);
if(status != 0) {lineno = __LINE__; goto eRR;} // PLL 0 if(status != 0) {lineno = __LINE__; goto eRR;} // PLL 0
PDATA(pgm)->flags32 |= FLAGS32_INIT_SMC; PDATA(pgm)->flags32 |= FLAGS32_INIT_SMC;

View File

@ -63,9 +63,9 @@ SIGN [+-]
%% %%
{SIGN}?{DIGIT}+ { yylval = number(yytext); return TKN_NUMBER; } {DIGIT}+ { yylval = new_number(yytext); return TKN_NUMBER; /* sign is treated in grammar */ }
{SIGN}?{DIGIT}+"."{DIGIT}* { yylval = number_real(yytext); return TKN_NUMBER_REAL; } {SIGN}?{DIGIT}+"."{DIGIT}* { yylval = new_number_real(yytext); return TKN_NUMBER_REAL; }
{SIGN}?"."{DIGIT}+ { yylval = number_real(yytext); return TKN_NUMBER_REAL; } {SIGN}?"."{DIGIT}+ { yylval = new_number_real(yytext); return TKN_NUMBER_REAL; }
["]([^"\\\n]|\\.|\\\n)*["] { ["]([^"\\\n]|\\.|\\\n)*["] {
char *str= cfg_strdup("lexer.l", yytext); char *str= cfg_strdup("lexer.l", yytext);
@ -73,12 +73,12 @@ SIGN [+-]
size_t len = strlen(str); size_t len = strlen(str);
if(len) if(len)
str[len-1] = 0; str[len-1] = 0;
yylval = string(str); yylval = new_string(str);
free(str); free(str);
return TKN_STRING; return TKN_STRING;
} }
0x{HEXDIGIT}+ { yylval = hexnumber(yytext); return TKN_NUMBER; } 0x{HEXDIGIT}+ { yylval = new_hexnumber(yytext); return TKN_NUMBER; }
#\n#\ PROGRAMMER\ DEFINITIONS\n#\n+ { /* Record comments so far as prologue and skip */ #\n#\ PROGRAMMER\ DEFINITIONS\n#\n+ { /* Record comments so far as prologue and skip */
cfg_capture_prologue(); cfg_capture_prologue();
@ -121,6 +121,23 @@ SIGN [+-]
} }
prog_modes|mcuid|n_interrupts|n_page_erase { /* Components for assignment */
Component_t *cp = cfg_comp_search(yytext, current_strct);
if(!cp) {
yyerror("Unknown component %s in %s", yytext, cfg_strct_name(current_strct));
return YYERRCODE;
}
yylval = new_token(TKN_COMPONENT);
yylval->value.comp = cp;
ccap();
return TKN_COMPONENT;
}
PM_SPM|PM_TPI|PM_ISP|PM_PDI|PM_UPDI|PM_HVSP|PM_HVPP|PM_debugWIRE|PM_JTAG|PM_aWire { /* Constants */
yylval = new_constant(yytext);
return TKN_NUMBER;
}
alias { yylval=NULL; return K_ALIAS; } alias { yylval=NULL; return K_ALIAS; }
allowfullpagebitstream { yylval=NULL; ccap(); return K_ALLOWFULLPAGEBITSTREAM; } allowfullpagebitstream { yylval=NULL; ccap(); return K_ALLOWFULLPAGEBITSTREAM; }
avr910_devcode { yylval=NULL; ccap(); return K_AVR910_DEVCODE; } avr910_devcode { yylval=NULL; ccap(); return K_AVR910_DEVCODE; }
@ -258,7 +275,17 @@ yes { yylval=new_token(K_YES); return K_YES; }
"," { yylval = NULL; pyytext(); return TKN_COMMA; } "," { yylval = NULL; pyytext(); return TKN_COMMA; }
"=" { yylval = NULL; pyytext(); return TKN_EQUAL; } "=" { yylval = NULL; pyytext(); return TKN_EQUAL; }
";" { yylval = NULL; pyytext(); return TKN_SEMI; } ";" { yylval = NULL; pyytext(); return TKN_SEMI; }
"~" { yylval = NULL; pyytext(); return TKN_TILDE; }
"|" { yylval = NULL; pyytext(); return OP_OR; }
"^" { yylval = NULL; pyytext(); return OP_XOR; }
"&" { yylval = NULL; pyytext(); return OP_AND; }
"+" { yylval = NULL; pyytext(); return OP_PLUS; }
"-" { yylval = NULL; pyytext(); return OP_MINUS; }
"*" { yylval = NULL; pyytext(); return OP_TIMES; }
"/" { yylval = NULL; pyytext(); return OP_DIVIDE; }
"%" { yylval = NULL; pyytext(); return OP_MODULO; }
"~" { yylval = NULL; pyytext(); return OP_TILDE; }
"(" { yylval = NULL; pyytext(); return TKN_LEFT_PAREN; } "(" { yylval = NULL; pyytext(); return TKN_LEFT_PAREN; }
")" { yylval = NULL; pyytext(); return TKN_RIGHT_PAREN; } ")" { yylval = NULL; pyytext(); return TKN_RIGHT_PAREN; }

View File

@ -169,6 +169,7 @@ enum ctl_stack_t {
CTL_STACK_HVSP /* high voltage serial programming control stack */ CTL_STACK_HVSP /* high voltage serial programming control stack */
}; };
/* /*
* serial programming instruction bit specifications * serial programming instruction bit specifications
*/ */
@ -183,19 +184,25 @@ typedef struct opcode {
} OPCODE; } OPCODE;
/* Any changes here, please also reflect in dev_part_strct() of developer_opts.c */ // Any changes here, please also reflect in dev_part_strct() of developer_opts.c
#define AVRPART_SERIALOK 0x0001 /* part supports serial programming */ #define AVRPART_SERIALOK 1 // Part supports serial programming
#define AVRPART_PARALLELOK 0x0002 /* part supports parallel programming */ #define AVRPART_PARALLELOK 2 // Part supports parallel programming
#define AVRPART_PSEUDOPARALLEL 0x0004 /* part has pseudo parallel support */ #define AVRPART_PSEUDOPARALLEL 4 // Part has pseudo parallel support
#define AVRPART_HAS_JTAG 0x0008 /* part has a JTAG i/f */ #define AVRPART_ALLOWFULLPAGEBITSTREAM 8 // JTAG ICE mkII param
#define AVRPART_ALLOWFULLPAGEBITSTREAM 0x0010 /* JTAG ICE mkII param. */ #define AVRPART_ENABLEPAGEPROGRAMMING 16 // JTAG ICE mkII param
#define AVRPART_ENABLEPAGEPROGRAMMING 0x0020 /* JTAG ICE mkII param. */ #define AVRPART_IS_AT90S1200 32 // Part is an AT90S1200, needs special treatment
#define AVRPART_HAS_DW 0x0040 /* part has a debugWire i/f */
#define AVRPART_HAS_PDI 0x0080 /* part has PDI i/f rather than ISP (ATxmega) */ // Programming modes for parts and programmers: reflect changes in lexer.l, developer_opts.c and config.c
#define AVRPART_AVR32 0x0100 /* part is in AVR32 family */ #define PM_SPM 1 // Bootloaders, self-programming with SPM opcodes or NVM Controllers
#define AVRPART_HAS_TPI 0x0800 /* part has TPI i/f rather than ISP (ATtiny4/5/9/10) */ #define PM_TPI 2 // Tiny Programming Interface (t4, t5, t9, t10, t20, t40, t102, t104)
#define AVRPART_IS_AT90S1200 0x1000 /* part is an AT90S1200 (needs special treatment) */ #define PM_ISP 4 // SPI programming for In-System Programming (almost all classic parts)
#define AVRPART_HAS_UPDI 0x2000 /* part has UPDI i/f (AVR8X) */ #define PM_PDI 8 // Program and Debug Interface (xmega parts)
#define PM_UPDI 16 // Unified Program and Debug Interface
#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_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_aWire 512 // AVR32 parts
#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) */
@ -209,13 +216,24 @@ typedef struct opcode {
#define TAG_ALLOCATED 1 /* memory byte is allocated */ #define TAG_ALLOCATED 1 /* memory byte is allocated */
/* Any changes here, please also reflect in dev_part_strct() of developer_opts.c */ /*
* Any changes in AVRPART or AVRMEM, please also ensure changes are made in
* - lexer.l
* - Either Component_t avr_comp[] of config.c or in config_gram.y
* - dev_part_strct() in developer_opts.c
* - avr_new_part() and/or avr_new_memtype() in avrpart.c for
* initialisation; note that all const char * must be initialised with ""
*/
typedef struct avrpart { typedef struct avrpart {
const char * desc; /* long part name */ const char * desc; /* long part name */
const char * id; /* short part name */ const char * id; /* short part name */
LISTID comments; // Used by developer options -p*/[ASsr...] LISTID comments; // Used by developer options -p*/[ASsr...]
const char * parent_id; /* Used by developer options */ const char * parent_id; /* Used by developer options */
const char * family_id; /* family id in the SIB (avr8x) */ const char * family_id; /* family id in the SIB (avr8x) */
int prog_modes; /* Programming interfaces, see #define PM_... */
int mcuid; /* Unique id in 0..2039 for urclock programmer */
int n_interrupts; /* Number of interrupts, used for vector bootloaders */
int n_page_erase; /* If set, number of pages erased during NVM erase */
int hvupdi_variant; /* HV pulse on UPDI pin, no pin or RESET pin */ int hvupdi_variant; /* HV pulse on UPDI pin, no pin or RESET pin */
int stk500_devcode; /* stk500 device code */ int stk500_devcode; /* stk500 device code */
int avr910_devcode; /* avr910 device code */ int avr910_devcode; /* avr910 device code */
@ -262,7 +280,7 @@ typedef struct avrpart {
int programlockpulsewidth; /* stk500 v2 hv mode parameter */ int programlockpulsewidth; /* stk500 v2 hv mode parameter */
int programlockpolltimeout; /* stk500 v2 hv mode parameter */ int programlockpolltimeout; /* stk500 v2 hv mode parameter */
int synchcycles; /* stk500 v2 hv mode parameter */ int synchcycles; /* stk500 v2 hv mode parameter */
int hvspcmdexedelay; /* stk500 v2 xml file parameter */ int hvspcmdexedelay; /* stk500 v2 hv mode file parameter */
unsigned char idr; /* JTAG ICE mkII XML file parameter */ unsigned char idr; /* JTAG ICE mkII XML file parameter */
unsigned char rampz; /* JTAG ICE mkII XML file parameter */ unsigned char rampz; /* JTAG ICE mkII XML file parameter */
@ -677,13 +695,21 @@ typedef enum {
CONNTYPE_SPI CONNTYPE_SPI
} conntype_t; } conntype_t;
/* Any changes here, please also reflect in dev_pgm_strct() of developer_opts.c */ /*
* Any changes in PROGRAMMER, please also ensure changes are made in
* - lexer.l
* - Either Component_t avr_comp[] of config.c or config_gram.y
* - dev_pgm_strct() in developer_opts.c
* - pgm_new() in pgm.c for initialisation; note that all const char * must
* be initialised with ""
*/
typedef struct programmer_t { typedef struct programmer_t {
LISTID id; LISTID id;
const char *desc; const char *desc;
void (*initpgm)(struct programmer_t *pgm); // Sets up the AVRDUDE programmer void (*initpgm)(struct programmer_t *pgm); // Sets up the AVRDUDE programmer
LISTID comments; // Used by developer options -c*/[ASsr...] LISTID comments; // Used by developer options -c*/[ASsr...]
const char *parent_id; // Used by developer options const char *parent_id; // Used by developer options
int prog_modes; // Programming interfaces, see #define PM_...
struct pindef_t pin[N_PINS]; struct pindef_t pin[N_PINS];
conntype_t conntype; conntype_t conntype;
int baudrate; int baudrate;
@ -695,7 +721,7 @@ typedef struct programmer_t {
const char *usbproduct; const char *usbproduct;
LISTID hvupdi_support; // List of UPDI HV variants the tool supports, see HV_UPDI_VARIANT_x LISTID hvupdi_support; // List of UPDI HV variants the tool supports, see HV_UPDI_VARIANT_x
// Values below are not set by config_gram.y; make sure fd is first for dev_pgm_raw() // Values below are not set by config_gram.y; ensure fd is first for dev_pgm_raw()
union filedescriptor fd; union filedescriptor fd;
char type[PGM_TYPELEN]; char type[PGM_TYPELEN];
char port[PGM_PORTLEN]; char port[PGM_PORTLEN];

View File

@ -270,8 +270,8 @@ static void linuxspi_display(const PROGRAMMER* pgm, const char* p) {
static int linuxspi_initialize(const PROGRAMMER *pgm, const AVRPART *p) { static int linuxspi_initialize(const PROGRAMMER *pgm, const AVRPART *p) {
int tries, ret; int tries, ret;
if (p->flags & AVRPART_HAS_TPI) { if (p->prog_modes & PM_TPI) {
/* We do not support tpi. This is a dedicated SPI thing */ /* We do not support TPI. This is a dedicated SPI thing */
avrdude_message(MSG_INFO, "%s: error: Programmer " LINUXSPI " does not support TPI\n", progname); avrdude_message(MSG_INFO, "%s: error: Programmer " LINUXSPI " does not support TPI\n", progname);
return -1; return -1;
} }

View File

@ -924,7 +924,7 @@ int main(int argc, char * argv [])
for (ln=lfirst(updates); ln; ln=lnext(ln)) { for (ln=lfirst(updates); ln; ln=lnext(ln)) {
upd = ldata(ln); upd = ldata(ln);
if (upd->memtype == NULL) { if (upd->memtype == NULL) {
const char *mtype = (p->flags & AVRPART_HAS_PDI)? "application": "flash"; const char *mtype = p->prog_modes & PM_PDI? "application": "flash";
avrdude_message(MSG_NOTICE2, "%s: defaulting memtype in -U %c:%s option to \"%s\"\n", avrdude_message(MSG_NOTICE2, "%s: defaulting memtype in -U %c:%s option to \"%s\"\n",
progname, progname,
(upd->op == DEVICE_READ)? 'r': (upd->op == DEVICE_WRITE)? 'w': 'v', (upd->op == DEVICE_READ)? 'r': (upd->op == DEVICE_WRITE)? 'w': 'v',
@ -1062,7 +1062,7 @@ int main(int argc, char * argv [])
* against 0xffffff / 0x000000 should ensure that the signature bytes * against 0xffffff / 0x000000 should ensure that the signature bytes
* are valid. * are valid.
*/ */
if(!(p->flags & AVRPART_AVR32)) { if(!(p->prog_modes & PM_aWire)) { // not AVR32
int attempt = 0; int attempt = 0;
int waittime = 10000; /* 10 ms */ int waittime = 10000; /* 10 ms */
@ -1071,7 +1071,7 @@ int main(int argc, char * argv [])
if (init_ok) { if (init_ok) {
rc = avr_signature(pgm, p); rc = avr_signature(pgm, p);
if (rc != LIBAVRDUDE_SUCCESS) { if (rc != LIBAVRDUDE_SUCCESS) {
if ((rc == LIBAVRDUDE_SOFTFAIL) && (p->flags & AVRPART_HAS_UPDI) && (attempt < 1)) { if (rc == LIBAVRDUDE_SOFTFAIL && (p->prog_modes & PM_UPDI) && attempt < 1) {
attempt++; attempt++;
if (pgm->read_sib) { if (pgm->read_sib) {
// Read SIB and compare FamilyID // Read SIB and compare FamilyID
@ -1193,8 +1193,7 @@ int main(int argc, char * argv [])
} }
if (uflags & UF_AUTO_ERASE) { if (uflags & UF_AUTO_ERASE) {
if ((p->flags & AVRPART_HAS_PDI) && pgm->page_erase != NULL && if ((p->prog_modes & PM_PDI) && pgm->page_erase && lsize(updates) > 0) {
lsize(updates) > 0) {
if (quell_progress < 2) { if (quell_progress < 2) {
avrdude_message(MSG_INFO, "%s: NOTE: Programmer supports page erase for Xmega devices.\n" avrdude_message(MSG_INFO, "%s: NOTE: Programmer supports page erase for Xmega devices.\n"
"%sEach page will be erased before programming it, but no chip erase is performed.\n" "%sEach page will be erased before programming it, but no chip erase is performed.\n"
@ -1203,7 +1202,7 @@ int main(int argc, char * argv [])
} }
} else { } else {
AVRMEM * m; AVRMEM * m;
const char *memname = (p->flags & AVRPART_HAS_PDI)? "application": "flash"; const char *memname = p->prog_modes & PM_PDI? "application": "flash";
uflags &= ~UF_AUTO_ERASE; uflags &= ~UF_AUTO_ERASE;
for (ln=lfirst(updates); ln; ln=lnext(ln)) { for (ln=lfirst(updates); ln; ln=lnext(ln)) {

View File

@ -1130,8 +1130,7 @@ retry:
break; break;
case PGMTYPE_JTAGICE3: case PGMTYPE_JTAGICE3:
if (buf[1] == STATUS_CMD_FAILED && if (buf[1] == STATUS_CMD_FAILED && (p->prog_modes & PM_debugWIRE)) {
(p->flags & AVRPART_HAS_DW) != 0) {
unsigned char cmd[4], *resp; unsigned char cmd[4], *resp;
/* Try debugWIRE, and MONCON_DISABLE */ /* Try debugWIRE, and MONCON_DISABLE */
@ -1239,16 +1238,13 @@ static int stk500v2_initialize(const PROGRAMMER *pgm, const AVRPART *p) {
if ((PDATA(pgm)->pgmtype == PGMTYPE_STK600 || if ((PDATA(pgm)->pgmtype == PGMTYPE_STK600 ||
PDATA(pgm)->pgmtype == PGMTYPE_AVRISP_MKII || PDATA(pgm)->pgmtype == PGMTYPE_AVRISP_MKII ||
PDATA(pgm)->pgmtype == PGMTYPE_JTAGICE_MKII) != 0 PDATA(pgm)->pgmtype == PGMTYPE_JTAGICE_MKII) != 0
&& (p->flags & (AVRPART_HAS_PDI | AVRPART_HAS_TPI)) != 0) { && (p->prog_modes & (PM_PDI | PM_TPI)) != 0) {
/* /*
* This is an ATxmega device, must use XPROG protocol for the * This is an ATxmega device, must use XPROG protocol for the
* remaining actions. * remaining actions.
*/ */
if ((p->flags & AVRPART_HAS_PDI) != 0) { if (p->prog_modes & PM_PDI) {
/* // Find the border between application and boot area
* Find out where the border between application and boot area
* is.
*/
AVRMEM *bootmem = avr_locate_mem(p, "boot"); AVRMEM *bootmem = avr_locate_mem(p, "boot");
AVRMEM *flashmem = avr_locate_mem(p, "flash"); AVRMEM *flashmem = avr_locate_mem(p, "flash");
if (bootmem == NULL || flashmem == NULL) { if (bootmem == NULL || flashmem == NULL) {
@ -1320,8 +1316,8 @@ static int stk500v2_jtag3_initialize(const PROGRAMMER *pgm, const AVRPART *p) {
LNODEID ln; LNODEID ln;
AVRMEM * m; AVRMEM * m;
if ((p->flags & AVRPART_HAS_PDI) || // FIXME: condition below looks fishy, suspect the code wants !(p->prog_modes & (PM_debugWIRE | PM_JTAG))
(p->flags & AVRPART_HAS_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);
return -1; return -1;
@ -1330,7 +1326,7 @@ static int stk500v2_jtag3_initialize(const PROGRAMMER *pgm, const AVRPART *p) {
PROGRAMMER *pgmcp = pgm_dup(pgm); PROGRAMMER *pgmcp = pgm_dup(pgm);
pgmcp->cookie = PDATA(pgm)->chained_pdata; pgmcp->cookie = PDATA(pgm)->chained_pdata;
if (p->flags & AVRPART_HAS_DW) if (p->prog_modes & PM_debugWIRE)
parm[0] = PARM3_ARCH_TINY; parm[0] = PARM3_ARCH_TINY;
else else
parm[0] = PARM3_ARCH_MEGA; parm[0] = PARM3_ARCH_MEGA;
@ -1574,7 +1570,7 @@ static void stk500v2_enable(PROGRAMMER *pgm, const AVRPART *p) {
if((PDATA(pgm)->pgmtype == PGMTYPE_STK600 || if((PDATA(pgm)->pgmtype == PGMTYPE_STK600 ||
PDATA(pgm)->pgmtype == PGMTYPE_AVRISP_MKII || PDATA(pgm)->pgmtype == PGMTYPE_AVRISP_MKII ||
PDATA(pgm)->pgmtype == PGMTYPE_JTAGICE_MKII) != 0 PDATA(pgm)->pgmtype == PGMTYPE_JTAGICE_MKII) != 0
&& (p->flags & (AVRPART_HAS_PDI | AVRPART_HAS_TPI)) != 0) { && (p->prog_modes & (PM_PDI | PM_TPI)) != 0) {
stk600_setup_xprog(pgm); stk600_setup_xprog(pgm);
} else { } else {
stk600_setup_isp(pgm); stk600_setup_isp(pgm);
@ -3689,7 +3685,7 @@ static int stk600_xprog_program_enable(const PROGRAMMER *pgm, const AVRPART *p)
AVRMEM *mem = NULL; AVRMEM *mem = NULL;
int use_tpi; int use_tpi;
use_tpi = (p->flags & AVRPART_HAS_TPI) != 0; use_tpi = (p->prog_modes & PM_TPI) != 0;
if (!use_tpi) { if (!use_tpi) {
if (p->nvm_base == 0) { if (p->nvm_base == 0) {
@ -3825,7 +3821,7 @@ static int stk600_xprog_write_byte(const PROGRAMMER *pgm, const AVRPART *p, cons
memcode = XPRG_MEM_TYPE_LOCKBITS; memcode = XPRG_MEM_TYPE_LOCKBITS;
} else if (strncmp(mem->desc, "fuse", strlen("fuse")) == 0) { } else if (strncmp(mem->desc, "fuse", strlen("fuse")) == 0) {
memcode = XPRG_MEM_TYPE_FUSE; memcode = XPRG_MEM_TYPE_FUSE;
if (p->flags & AVRPART_HAS_TPI) if (p->prog_modes & PM_TPI)
/* /*
* TPI devices need a mystic erase prior to writing their * TPI devices need a mystic erase prior to writing their
* fuses. * fuses.
@ -3855,7 +3851,7 @@ static int stk600_xprog_write_byte(const PROGRAMMER *pgm, const AVRPART *p, cons
} }
} }
if (p->flags & AVRPART_HAS_TPI) { if (p->prog_modes & PM_TPI) {
/* /*
* Some TPI memories (configuration aka. fuse) require a * Some TPI memories (configuration aka. fuse) require a
* larger write block size. We record that as a blocksize in * larger write block size. We record that as a blocksize in
@ -4217,7 +4213,7 @@ static int stk600_xprog_chip_erase(const PROGRAMMER *pgm, const AVRPART *p) {
AVRMEM *mem; AVRMEM *mem;
unsigned int addr = 0; unsigned int addr = 0;
if (p->flags & AVRPART_HAS_TPI) { if (p->prog_modes & PM_TPI) {
if ((mem = avr_locate_mem(p, "flash")) == NULL) { if ((mem = avr_locate_mem(p, "flash")) == NULL) {
avrdude_message(MSG_INFO, "%s: stk600_xprog_chip_erase(): no FLASH definition found for TPI device\n", avrdude_message(MSG_INFO, "%s: stk600_xprog_chip_erase(): no FLASH definition found for TPI device\n",
progname); progname);

View File

@ -674,7 +674,7 @@ static int usbasp_initialize(const PROGRAMMER *pgm, const AVRPART *p) {
else else
pdata->capabilities = 0; pdata->capabilities = 0;
pdata->use_tpi = (pdata->capabilities & USBASP_CAP_TPI) && (p->flags & AVRPART_HAS_TPI); pdata->use_tpi = (pdata->capabilities & USBASP_CAP_TPI) && (p->prog_modes & PM_TPI);
// query support for 3 MHz SCK in UsbAsp-flash firmware // query support for 3 MHz SCK in UsbAsp-flash firmware
// https://github.com/nofeletru/UsbAsp-flash // https://github.com/nofeletru/UsbAsp-flash
pdata->sck_3mhz = ((pdata->capabilities & USBASP_CAP_3MHZ) != 0) ? 1 :0; pdata->sck_3mhz = ((pdata->capabilities & USBASP_CAP_3MHZ) != 0) ? 1 :0;

View File

@ -454,7 +454,7 @@ static int usbtiny_initialize (const PROGRAMMER *pgm, const AVRPART *p ) {
// Let the device wake up. // Let the device wake up.
usleep(50000); usleep(50000);
if (p->flags & AVRPART_HAS_TPI) { if (p->prog_modes & PM_TPI) {
/* Since there is a single TPIDATA line, MOSI and MISO must be /* Since there is a single TPIDATA line, MOSI and MISO must be
linked together through a 1kOhm resistor. Verify that linked together through a 1kOhm resistor. Verify that
everything we send on MOSI gets mirrored back on MISO. */ everything we send on MOSI gets mirrored back on MISO. */
@ -605,7 +605,7 @@ static int usbtiny_spi(const PROGRAMMER *pgm, const unsigned char *cmd, unsigned
static int usbtiny_chip_erase(const PROGRAMMER *pgm, const AVRPART *p) { static int usbtiny_chip_erase(const PROGRAMMER *pgm, const AVRPART *p) {
unsigned char res[4]; unsigned char res[4];
if (p->flags & AVRPART_HAS_TPI) if (p->prog_modes & PM_TPI)
return avr_tpi_chip_erase(pgm, p); return avr_tpi_chip_erase(pgm, p);
if (p->op[AVR_OP_CHIP_ERASE] == NULL) { if (p->op[AVR_OP_CHIP_ERASE] == NULL) {
@ -773,7 +773,7 @@ static int usbtiny_paged_write(const PROGRAMMER *pgm, const AVRPART *p, const AV
static int usbtiny_program_enable(const PROGRAMMER *pgm, const AVRPART *p) { static int usbtiny_program_enable(const PROGRAMMER *pgm, const AVRPART *p) {
unsigned char buf[4]; unsigned char buf[4];
if (p->flags & AVRPART_HAS_TPI) if (p->prog_modes & PM_TPI)
return avr_tpi_program_enable(pgm, p, TPIPCR_GT_0b); return avr_tpi_program_enable(pgm, p, TPIPCR_GT_0b);
else else
return usbtiny_avr_op(pgm, p, AVR_OP_PGM_ENABLE, buf); return usbtiny_avr_op(pgm, p, AVR_OP_PGM_ENABLE, buf);