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
term.c
term.h
avrintel.c
avrintel.h
developer_opts.c
developer_opts.h
developer_opts_private.h

View File

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

View File

@ -52,7 +52,7 @@ int avr_tpi_chip_erase(const PROGRAMMER *pgm, const AVRPART *p) {
int err;
AVRMEM *mem;
if (p->flags & AVRPART_HAS_TPI) {
if (p->prog_modes & PM_TPI) {
pgm->pgm_led(pgm, ON);
/* 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 response;
if(p->flags & AVRPART_HAS_TPI) {
if(p->prog_modes & PM_TPI) {
/* set guard time */
cmd[0] = (TPI_CMD_SSTCS | TPI_REG_TPIPCR);
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->err_led(pgm, OFF);
if (p->flags & AVRPART_HAS_TPI) {
if (p->prog_modes & PM_TPI) {
if (pgm->cmd_tpi == NULL) {
avrdude_message(MSG_INFO, "%s: Error: %s programmer does not support TPI\n",
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);
/* 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) {
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;
}
if (p->flags & AVRPART_HAS_TPI) {
if (p->prog_modes & PM_TPI) {
if (pgm->cmd_tpi == NULL) {
avrdude_message(MSG_INFO, "%s: Error: %s programmer does not support TPI\n",
progname, pgm->type);
@ -596,8 +596,7 @@ int avr_write_byte_default(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM
return 0;
}
if (!mem->paged &&
(p->flags & AVRPART_IS_AT90S1200) == 0) {
if (!mem->paged && (p->flags & AVRPART_IS_AT90S1200) == 0) {
/*
* 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
@ -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 &&
pgm->cmd_tpi != NULL) {
if ((p->prog_modes & PM_TPI) && m->page_size > 1 && pgm->cmd_tpi) {
if (wsize == 1) {
/* fuse (configuration) memory: only single byte to write */
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);
// Switch to TPI initialisation in avrftdi_tpi.c
if(p->flags & AVRPART_HAS_TPI)
if(p->prog_modes & PM_TPI)
avrftdi_tpi_initpgm(pgm);
}
@ -808,7 +808,7 @@ static void avrftdi_close(PROGRAMMER * pgm)
static int avrftdi_initialize(const PROGRAMMER *pgm, const AVRPART *p) {
avrftdi_powerup(pgm);
if(p->flags & AVRPART_HAS_TPI)
if(p->prog_modes & PM_TPI)
{
/* see avrftdi_tpi.c */
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);
// Default values
p->mcuid = -1;
p->hvupdi_variant = -1;
memset(p->signature, 0xFF, 3);
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];
AVRMEM *mem;
if (p->flags & AVRPART_HAS_TPI) {
if (p->prog_modes & PM_TPI) {
pgm->pgm_led(pgm, ON);
while (avr_tpi_poll_nvmbsy(pgm));
@ -482,7 +482,7 @@ int bitbang_program_enable(const PROGRAMMER *pgm, const AVRPART *p) {
unsigned char res[4];
int i;
if (p->flags & AVRPART_HAS_TPI) {
if (p->prog_modes & PM_TPI) {
/* enable NVM programming */
bitbang_tpi_tx(pgm, TPI_CMD_SKEY);
for (i = sizeof(tpi_skey) - 1; i >= 0; i--)
@ -524,7 +524,7 @@ int bitbang_initialize(const PROGRAMMER *pgm, const AVRPART *p) {
usleep(20000);
/* 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 */
if (pgm->cmd_tpi == NULL) {
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);
usleep(20000);
if (p->flags & AVRPART_HAS_TPI) {
if (p->prog_modes & PM_TPI) {
/* keep TPIDATA high for 16 clock cycles */
pgm->setpin(pgm, PIN_AVR_MOSI, 1);
for (i = 0; i < 16; i++)

View File

@ -24,12 +24,14 @@
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <stddef.h>
#include <string.h>
#include <ctype.h>
#include "avrdude.h"
#include "libavrdude.h"
#include "config.h"
#include "avrintel.h"
#include "config_gram.h"
@ -44,6 +46,7 @@ LISTID number_list;
PROGRAMMER * current_prog;
AVRPART * current_part;
AVRMEM * current_mem;
int current_strct;
LISTID part_list;
LISTID programmers;
bool is_alias;
@ -53,6 +56,22 @@ char * cfg_infile;
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
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);
tkn->value.type = V_NUM;
tkn->value.number = atoi(text);
@ -202,7 +221,7 @@ TOKEN *number(const char *text) {
return tkn;
}
TOKEN *number_real(const char *text) {
TOKEN *new_number_real(const char *text) {
struct token_t * tkn = new_token(TKN_NUMBER);
tkn->value.type = V_NUM_REAL;
tkn->value.number_real = atof(text);
@ -214,7 +233,7 @@ TOKEN *number_real(const char *text) {
return tkn;
}
TOKEN *hexnumber(const char *text) {
TOKEN *new_hexnumber(const char *text) {
struct token_t *tkn = new_token(TKN_NUMBER);
char * e;
@ -233,11 +252,41 @@ TOKEN *hexnumber(const char *text) {
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);
tkn->value.type = V_STR;
tkn->value.string = cfg_strdup("string()", text);
tkn->value.string = cfg_strdup("new_string()", text);
#if DEBUG
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);
}
@ -692,3 +741,145 @@ char *cfg_escape(const char *s) {
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;
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 {
int type;
union {
int number;
double number_real;
char * string;
Component_t *comp;
};
} VALUE;
@ -59,6 +94,7 @@ extern FILE * yyin;
extern PROGRAMMER * current_prog;
extern AVRPART * current_part;
extern AVRMEM * current_mem;
extern int current_strct;
extern int cfg_lineno;
extern char * cfg_infile;
extern LISTID string_list;
@ -87,15 +123,17 @@ void free_token(TOKEN *tkn);
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);
@ -115,6 +153,16 @@ LISTID cfg_move_comments(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
}
#endif

View File

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

View File

@ -63,7 +63,7 @@ static struct {
const char *mcu, *var, *value;
} ptinj[] = {
// Add triples here, eg, {"ATmega328P", "mcuid", "999"},
{NULL, NULL, NULL},
{NULL, NULL, NULL},
};
static struct {
@ -74,8 +74,6 @@ static struct {
};
// Return 0 if op code would encode (essentially) the same SPI command
static int opcodecmp(const OPCODE *op1, const OPCODE *op2, int opnum) {
char *opstr1, *opstr2, *p;
@ -134,7 +132,14 @@ static void printallopcodes(const AVRPART *p, const char *d, OPCODE * const *opa
// 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];
*type = 0;
@ -194,6 +199,38 @@ static char *prog_modes(const AVRPART *p) {
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
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, cfg_escape(p->id), 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, "0x%02x", stk500_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) {
_partout("0x%04x", flags);
} 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_AVR32, is_avr32);
_if_flagout(AVRPART_ALLOWFULLPAGEBITSTREAM, allowfullpagebitstream);
_if_flagout(AVRPART_ENABLEPAGEPROGRAMMING, enablepageprogramming);
_if_flagout(AVRPART_SERIALOK, serial);
@ -1032,7 +1067,7 @@ void dev_output_part_defs(char *partdesc) {
nfuses,
ok,
p->flags,
prog_modes(p),
prog_modes_str(p->prog_modes),
p->config_file, p->lineno
);
}
@ -1051,14 +1086,14 @@ void dev_output_part_defs(char *partdesc) {
// Print wait delays for AVR family parts
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);
if(p->mem) {
for(LNODEID lnm=lfirst(p->mem); lnm; lnm=lnext(lnm)) {
AVRMEM *m = ldata(lnm);
// Write delays not needed for read-only calibration and signature memories
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)
dev_info(".wd_%s %.3f ms %s\n", m->desc, m->min_write_delay/1000.0, p->desc);
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(!base || base->initpgm != 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)
_pgmout_fmt("connection_type", "%s", connstr(pgm->conntype));
_if_pgmout(intcmp, "%d", baudrate);

View File

@ -1694,28 +1694,32 @@ The format of the programmer definition is as follows:
@smallexample
programmer
parent <id> # <id> is a quoted string
id = <id1> [, <id2> [, <id3>] ...] ; # <idN> are quoted strings
desc = <description> ; # quoted string
type = "par" | "stk500" | ... ; # programmer type (see below for a list)
baudrate = <num> ; # baudrate for serial ports
vcc = <num1> [, <num2> ... ] ; # pin number(s)
buff = <num1> [, <num2> ... ] ; # pin number(s)
reset = <num> ; # pin number
sck = <num> ; # pin number
mosi = <num> ; # pin number
miso = <num> ; # pin number
errled = <num> ; # pin number
rdyled = <num> ; # pin number
pgmled = <num> ; # pin number
vfyled = <num> ; # pin number
usbvid = <hexnum>; # USB VID (Vendor ID)
usbpid = <hexnum> [, <hexnum> ...]; # USB PID (Product ID)
usbdev = <interface>; # USB interface or other device info
usbvendor = <vendorname>; # USB Vendor Name
usbproduct = <productname>; # USB Product Name
usbsn = <serialno>; # USB Serial Number
;
parent <id> # optional parent
id = <id1> [, <id2> ... ] ; # <idN> are quoted strings
desc = <description> ; # quoted string
type = <type>; # programmer type, quoted string
# supported types can be listed by "-c ?type"
prog_modes = PM_<i/f> @{ | PM_<i/f> @} # interfaces, eg, PM_SPM|PM_PDI
connection_type = parallel | serial | usb | spi
baudrate = <num> ; # baudrate for avr910-programmer
vcc = <pin1> [, <pin2> ... ] ; # pin number(s)
buff = <pin1> [, <pin2> ... ] ; # pin number(s)
reset = <pin> ; # pin number
sck = <pin> ; # pin number
mosi = <pin> ; # pin number
miso = <pin> ; # pin number
errled = <pin> ; # pin number
rdyled = <pin> ; # pin number
pgmled = <pin> ; # pin number
vfyled = <pin> ; # pin number
usbvid = <hexnum> ; # USB VID (Vendor ID)
usbpid = <hexnum> [, <hexnum> ...] ; # USB PID (Product ID)
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
@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.
@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
Not all programmer types can handle a list of USB PIDs.
@noindent
Following programmer types are currently implemented:
The following programmer types are currently implemented:
@multitable @columnfractions .25 .6
@include programmer_types.texi
@ -1743,30 +1763,36 @@ Following programmer types are currently implemented:
@smallexample
part
id = <id> ; # quoted string
desc = <description> ; # quoted string
family_id = <description> ; # quoted string
has_jtag = <yes/no> ; # part has JTAG i/f
has_debugwire = <yes/no> ; # part has debugWire i/f
has_pdi = <yes/no> ; # part has PDI i/f
has_updi = <yes/no> ; # part has UPDI i/f
has_tpi = <yes/no> ; # part has TPI i/f
devicecode = <num> ; # numeric
id = <id> ; # quoted string
family_id = <id> ; # quoted string, eg, "megaAVR" or "tinyAVR"
prog_modes = PM_<i/f> @{| PM_<i/f>@} # interfaces, eg, PM_SPM|PM_ISP|PM_HVPP|PM_debugWIRE
mcuid = <num>; # unique id in 0..2039 for 8-bit AVRs
n_interrupts = <num>; # number of interrupts, used for vector bootloaders
n_page_erase = <num>; # if set, number of pages erased during NVM erase
hvupdi_variant = <num> ; # numeric -1 (n/a) or 0..2
devicecode = <num> ; # deprecated, use stk500_devcode
stk500_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
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
reset = dedicated | io ;
retry_pulse = reset | sck ;
chip_erase_delay = <num> ; # chip erase delay (us)
# STK500 parameters (parallel programming IO lines)
pagel = <num> ; # pin name in hex, i.e., 0xD7
bs2 = <num> ; # pin name in hex, i.e., 0xA0
serial = <yes/no> ; # can use serial downloading
parallel = <yes/no/pseudo>; # can use par. programming
# STK500v2 parameters, to be taken from Atmel's XML files
parallel = <yes/no/pseudo> ; # can use par. programming
# STK500v2 parameters, to be taken from Atmel's ATDF files
timeout = <num> ;
stabdelay = <num> ;
cmdexedelay = <num> ;
@ -1777,52 +1803,59 @@ part
predelay = <num> ;
postdelay = <num> ;
pollmethod = <num> ;
mode = <num> ;
delay = <num> ;
blocksize = <num> ;
readsize = <num> ;
hvspcmdexedelay = <num> ;
# STK500v2 HV programming parameters, from XML
pp_controlstack = <num>, <num>, ...; # PP only
hvsp_controlstack = <num>, <num>, ...; # HVSP only
hventerstabdelay = <num>;
progmodedelay = <num>; # PP only
latchcycles = <num>;
togglevtg = <num>;
poweroffdelay = <num>;
resetdelayms = <num>;
resetdelayus = <num>;
hvleavestabdelay = <num>;
resetdelay = <num>;
synchcycles = <num>; # HVSP only
chiperasepulsewidth = <num>; # PP only
chiperasepolltimeout = <num>;
chiperasetime = <num>; # HVSP only
programfusepulsewidth = <num>; # PP only
programfusepolltimeout = <num>;
programlockpulsewidth = <num>; # PP only
programlockpolltimeout = <num>;
# JTAG ICE mkII parameters, also from XML files
# STK500v2 HV programming parameters, from ATDFs
pp_controlstack = <num>, <num>, ... ; # PP only
hvsp_controlstack = <num>, <num>, ... ; # HVSP only
flash_instr = <num>, <num>, <num> ;
eeprom_instr = <num>, <num>, ... ;
hventerstabdelay = <num> ;
progmodedelay = <num> ; # PP only
latchcycles = <num> ;
togglevtg = <num> ;
poweroffdelay = <num> ;
resetdelayms = <num> ;
resetdelayus = <num> ;
hvleavestabdelay = <num> ;
resetdelay = <num> ;
synchcycles = <num> ; # HVSP only
chiperasepulsewidth = <num> ; # PP only
chiperasepolltimeout = <num> ;
chiperasetime = <num> ; # HVSP only
programfusepulsewidth = <num> ; # PP only
programfusepolltimeout = <num> ;
programlockpulsewidth = <num> ; # PP only
programlockpolltimeout = <num> ;
# JTAG ICE mkII parameters, also from ATDF files
allowfullpagebitstream = <yes/no> ;
enablepageprogramming = <yes/no> ;
idr = <num> ; # IO addr of IDR (OCD) reg.
rampz = <num> ; # IO addr of RAMPZ reg.
spmcr = <num> ; # mem addr of SPMC[S]R reg.
eecr = <num> ; # mem addr of EECR reg.
# (only when != 0x3F)
is_at90s1200 = <yes/no> ; # AT90S1200 part
is_avr32 = <yes/no> ; # AVR32 part
idr = <num> ; # IO addr of IDR (OCD) reg
rampz = <num> ; # IO addr of RAMPZ reg
spmcr = <num> ; # mem addr of SPMC[S]R reg
eecr = <num> ; # mem addr of EECR reg only when != 0x3f
mcu_base = <num> ;
nvm_base = <num> ;
ocd_base = <num> ;
ocdrev = <num> ;
pgm_enable = <instruction format> ;
chip_erase = <instruction format> ;
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
page_size = <num> ; # bytes
num_pages = <num> ; # numeric
min_write_delay = <num> ; # micro-seconds
max_write_delay = <num> ; # micro-seconds
readback_p1 = <num> ; # byte value
readback_p2 = <num> ; # byte value
pwroff_after_write = <yes/no> ; # yes / no
readback = <num> <num> ; # pair of byte values
readback_p1 = <num> ; # byte value (first component)
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> ;
write = <instruction format> ;
read_lo = <instruction format> ;
@ -1832,10 +1865,20 @@ part
loadpage_lo = <instruction format> ;
loadpage_hi = <instruction format> ;
writepage = <instruction format> ;
;
;
;
;
@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
* Parent Part::
* Instruction Format::
@ -1848,11 +1891,19 @@ part
@subsection Parent Part
@noindent
Parts can also inherit parameters from previously defined parts
using the following syntax. In this case specified integer and
string values override parameter values from the parent part. New
memory definitions are added to the definitions inherited from the
parent.
Parts can also inherit parameters from previously defined parts using
the following syntax. In this case specified integer and string values
override parameter values from the parent part. New memory definitions
are added to the definitions inherited from the parent. If, however, a
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
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
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 Node

View File

@ -778,7 +778,7 @@ static int elf_mem_limits(AVRMEM *mem, struct avrpart * p,
{
int rv = 0;
if (p->flags & AVRPART_AVR32) {
if (p->prog_modes & PM_aWire) { // AVR32
if (strcmp(mem->desc, "flash") == 0) {
*lowbound = 0x80000000;
*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
* 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, "application") == 0 ||
strcmp(mem->desc, "apptable") == 0)) {
@ -893,7 +893,7 @@ static int elf2b(char * infile, FILE * inf,
const char *endianname;
unsigned char endianess;
if (p->flags & AVRPART_AVR32) {
if (p->prog_modes & PM_aWire) { // AVR32
endianess = ELFDATA2MSB;
endianname = "little";
} else {
@ -923,7 +923,7 @@ static int elf2b(char * infile, FILE * inf,
const char *mname;
uint16_t machine;
if (p->flags & AVRPART_AVR32) {
if (p->prog_modes & PM_aWire) {
machine = EM_AVR32;
mname = "AVR32";
} else {
@ -1383,14 +1383,7 @@ int fileio_setparms(int op, struct fioparms * fp,
* AVR32 devices maintain their load offset within the file itself,
* but AVRDUDE maintains all memory images 0-based.
*/
if ((p->flags & AVRPART_AVR32) != 0)
{
fp->fileoffset = m->offset;
}
else
{
fp->fileoffset = 0;
}
fp->fileoffset = p->prog_modes & PM_aWire? m->offset: 0;
return 0;
}

View File

@ -239,7 +239,7 @@ int flip1_initialize(const PROGRAMMER *pgm, const AVRPART *part) {
} else {
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"
"%s For Xmega devices, use \"flip2\".\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;
}
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"
"%s For AT90USB* or ATmega*U* devices, use \"flip1\".\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 res[4];
if (p->flags & AVRPART_HAS_TPI)
if (p->prog_modes & PM_TPI)
return avr_tpi_chip_erase(pgm, p);
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];
int i;
if (p->flags & AVRPART_HAS_TPI)
if (p->prog_modes & PM_TPI)
return avr_tpi_program_enable(pgm, p, TPIPCR_GT_0b);
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
if (p->flags & AVRPART_HAS_TPI) {
if (p->prog_modes & PM_TPI) {
bool io_link_ok = true;
uint8_t byte;
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) {
ifname = "debugWire";
if (p->flags & AVRPART_HAS_DW)
if (p->prog_modes & PM_debugWIRE)
conn = PARM3_CONN_DW;
} else if (pgm->flag & PGM_FL_IS_PDI) {
ifname = "PDI";
if (p->flags & AVRPART_HAS_PDI)
if (p->prog_modes & PM_PDI)
conn = PARM3_CONN_PDI;
} else if (pgm->flag & PGM_FL_IS_UPDI) {
ifname = "UPDI";
if (p->flags & AVRPART_HAS_UPDI)
if (p->prog_modes & PM_UPDI)
conn = PARM3_CONN_UPDI;
} else {
ifname = "JTAG";
if (p->flags & AVRPART_HAS_JTAG)
if (p->prog_modes & PM_JTAG)
conn = PARM3_CONN_JTAG;
}
@ -1086,11 +1086,11 @@ static int jtag3_initialize(const PROGRAMMER *pgm, const AVRPART *p) {
return -1;
}
if (p->flags & AVRPART_HAS_PDI)
if (p->prog_modes & PM_PDI)
parm[0] = PARM3_ARCH_XMEGA;
else if (p->flags & AVRPART_HAS_UPDI)
else if (p->prog_modes & PM_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;
else
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)
PDATA(pgm)->set_sck = jtag3_set_sck_xmega_pdi;
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;
else
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 */
if ((p->flags & AVRPART_HAS_PDI))
if ((p->prog_modes & PM_PDI))
{
struct xmega_device_desc xd;
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)
return -1;
}
else if ((p->flags & AVRPART_HAS_UPDI))
else if ((p->prog_modes & PM_UPDI))
{
struct updi_device_desc xd;
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
LNODEID support;
if (p->flags & AVRPART_HAS_UPDI &&
if (p->prog_modes & PM_UPDI &&
PDATA(pgm)->use_hvupdi == true &&
p->hvupdi_variant != HV_UPDI_VARIANT_1) {
parm[0] = PARM3_UPDI_HV_NONE;
@ -1332,7 +1332,7 @@ static int jtag3_initialize(const PROGRAMMER *pgm, const AVRPART *p) {
int ocdrev;
/* 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 */
else if (flashsize > 128 * 1024)
ocdrev = 4;
@ -1376,7 +1376,7 @@ static int jtag3_initialize(const PROGRAMMER *pgm, const AVRPART *p) {
}
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);
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.
*/
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 */
avrdude_message(MSG_NOTICE, "%s: Partial Family_ID returned: \"%c%c%c%c\"\n",
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);
PDATA(pgm)->boot_start = ULONG_MAX;
if ((p->flags & AVRPART_HAS_PDI)) {
/*
* Find out where the border between application and boot area
* is.
*/
if (p->prog_modes & PM_PDI) {
// Find the border between application and boot area
AVRMEM *bootmem = avr_locate_mem(p, "boot");
AVRMEM *flashmem = avr_locate_mem(p, "flash");
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",
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",
progname);
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) {
PDATA(pgm)->flash_pageaddr = (unsigned long)-1L;
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 */
dynamic_memtype = 1;
} 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);
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;
} else if (strcmp(m->desc, "usersig") == 0 ||
strcmp(m->desc, "userrow") == 0) {
cmd[3] = MTYPE_USERSIG;
} else if (strcmp(m->desc, "boot") == 0) {
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;
} else {
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) {
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 */
dynamic_memtype = 1;
} 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)
return -1;
} 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;
} else if (strcmp(m->desc, "boot") == 0) {
cmd[3] = MTYPE_BOOT_FLASH;
} else if ( p->flags & AVRPART_HAS_PDI ) {
} else if (p->prog_modes & PM_PDI) {
cmd[3] = MTYPE_FLASH;
} else if ( p->flags & AVRPART_HAS_UPDI ) {
} else if (p->prog_modes & PM_UPDI) {
cmd[3] = MTYPE_SRAM;
} else {
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[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)) {
addr += mem->offset & (512 * 1024 - 1); /* max 512 KiB flash */
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;
cache_ptr = PDATA(pgm)->flash_pagecache;
} 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;
} else {
cmd[3] = MTYPE_EEPROM_PAGE;
@ -1987,7 +1984,7 @@ static int jtag3_read_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM
unsupp = 1;
} else if (matches(mem->desc, "fuse")) {
cmd[3] = MTYPE_FUSE_BITS;
if (!(p->flags & AVRPART_HAS_UPDI))
if (!(p->prog_modes & PM_UPDI))
addr = mem->offset & 7;
} else if (strcmp(mem->desc, "usersig") == 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[1] = CMD3_WRITE_MEMORY;
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) {
cache_ptr = PDATA(pgm)->flash_pagecache;
pagesize = PDATA(pgm)->flash_pagesize;
@ -2149,7 +2146,7 @@ static int jtag3_write_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVRME
unsupp = 1;
} else if (matches(mem->desc, "fuse")) {
cmd[3] = MTYPE_FUSE_BITS;
if (!(p->flags & AVRPART_HAS_UPDI))
if (!(p->prog_modes & PM_UPDI))
addr = mem->offset & 7;
} else if (strcmp(mem->desc, "usersig") == 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) {
if ( p->flags & AVRPART_HAS_PDI ) {
if (p->prog_modes & PM_PDI) {
if (addr >= PDATA(pgm)->boot_start)
return MTYPE_BOOT_FLASH;
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) {
if ((p->flags & AVRPART_HAS_PDI) != 0) {
if (p->prog_modes & PM_PDI) {
if (addr >= PDATA(pgm)->boot_start)
/*
* 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 */
return addr;
}
/*
* Non-Xmega device.
*/
if (p->flags & AVRPART_HAS_UPDI) {
// Non-Xmega device
if (p->prog_modes & PM_UPDI) {
if (strcmp(m->desc, "flash") == 0) {
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 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",
progname, p->desc);
return -1;

View File

@ -882,7 +882,7 @@ static int jtagmkII_chip_erase(const PROGRAMMER *pgm, const AVRPART *p) {
int status, len;
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[1] = XMEGA_ERASE_CHIP;
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: ",
progname,
(p->flags & (AVRPART_HAS_PDI | AVRPART_HAS_UPDI))? "Xmega ": "");
p->prog_modes & (PM_PDI | PM_UPDI)? "Xmega ": "");
jtagmkII_send(pgm, buf, len);
status = jtagmkII_recv(pgm, &resp);
@ -919,7 +919,7 @@ static int jtagmkII_chip_erase(const PROGRAMMER *pgm, const AVRPART *p) {
return -1;
}
if (!(p->flags & (AVRPART_HAS_PDI | AVRPART_HAS_UPDI)))
if (!(p->prog_modes & (PM_PDI | PM_UPDI)))
pgm->initialize(pgm, p);
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);
u16_to_b2(sendbuf.dd.uiFlashPageSize, 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.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 =
(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(): "
"Sending set device descriptor command: ",
@ -1290,8 +1290,8 @@ static int jtagmkII_initialize(const PROGRAMMER *pgm, const AVRPART *p) {
const char *ifname;
/* 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)) ||
(strncmp(ldata(lfirst(pgm->id)), "jtagmkII", strlen("jtagmkII")) == 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->prog_modes & PM_UPDI))) {
avrdude_message(MSG_INFO, "ERROR: programmer %s does not support target %s\n\n",
ldata(lfirst(pgm->id)), p->desc);
return -1;
@ -1300,15 +1300,15 @@ static int jtagmkII_initialize(const PROGRAMMER *pgm, const AVRPART *p) {
ok = 0;
if (pgm->flag & PGM_FL_IS_DW) {
ifname = "debugWire";
if (p->flags & AVRPART_HAS_DW)
if (p->prog_modes & PM_debugWIRE)
ok = 1;
} else if (pgm->flag & PGM_FL_IS_PDI) {
ifname = "PDI";
if (p->flags & (AVRPART_HAS_PDI | AVRPART_HAS_UPDI))
if (p->prog_modes & (PM_PDI | PM_UPDI))
ok = 1;
} else {
ifname = "JTAG";
if (p->flags & AVRPART_HAS_JTAG)
if (p->prog_modes & PM_JTAG)
ok = 1;
}
@ -1350,24 +1350,21 @@ static int jtagmkII_initialize(const PROGRAMMER *pgm, const AVRPART *p) {
* mode from JTAG to JTAG_XMEGA.
*/
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)
return -1;
}
/*
* 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);
else
jtagmkII_set_devdescr(pgm, p);
PDATA(pgm)->boot_start = ULONG_MAX;
if ((p->flags & (AVRPART_HAS_PDI | AVRPART_HAS_UPDI))) {
/*
* Find out where the border between application and boot area
* is.
*/
if ((p->prog_modes & (PM_PDI | PM_UPDI))) {
// Find the border between application and boot area
AVRMEM *bootmem = avr_locate_mem(p, "boot");
AVRMEM *flashmem = avr_locate_mem(p, "flash");
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;
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
* https://savannah.nongnu.org/bugs/index.php?37942
@ -1422,7 +1419,7 @@ static int jtagmkII_initialize(const PROGRAMMER *pgm, const AVRPART *p) {
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");
if (jtagmkII_read_byte(pgm, p, &hfuse, 1, &b) < 0)
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",
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",
progname);
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) {
PDATA(pgm)->flash_pageaddr = (unsigned long)-1L;
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 */
dynamic_memtype = 1;
} 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);
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;
} else if (strcmp(m->desc, "usersig") == 0 ||
strcmp(m->desc, "userrow") == 0) {
cmd[1] = MTYPE_USERSIG;
} else if (strcmp(m->desc, "boot") == 0) {
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;
} else {
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;
if (strcmp(m->desc, "flash") == 0) {
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 */
dynamic_memtype = 1;
} 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)
return -1;
} 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;
} else if (strcmp(m->desc, "boot") == 0) {
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;
} else {
cmd[1] = MTYPE_SPM;
@ -2230,14 +2227,14 @@ static int jtagmkII_read_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVR
unsupp = 0;
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)) {
pagesize = PDATA(pgm)->flash_pagesize;
paddr = addr & ~(pagesize - 1);
paddr_ptr = &PDATA(pgm)->flash_pageaddr;
cache_ptr = PDATA(pgm)->flash_pagecache;
} 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 */
cmd[1] = MTYPE_EEPROM;
} else {
@ -2404,7 +2401,7 @@ static int jtagmkII_write_byte(const PROGRAMMER *pgm, const AVRPART *p, const AV
writedata = data;
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 ((addr & 1) == 1) {
/* 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)
unsupp = 1;
} 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;
PDATA(pgm)->eeprom_pageaddr = (unsigned long)-1L;
} 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) {
if ( p->flags & (AVRPART_HAS_PDI | AVRPART_HAS_UPDI) ) {
if (p->prog_modes & (PM_PDI | PM_UPDI)) {
if (addr >= PDATA(pgm)->boot_start)
return MTYPE_BOOT_FLASH;
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
* 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)
/*
* 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
if(!(p->flags & FLAGS32_INIT_SMC)) {
if(!(PDATA(pgm)->flags32 & FLAGS32_INIT_SMC)) {
status = jtagmkII_smc_init32(pgm);
if(status != 0) {lineno = __LINE__; goto eRR;} // PLL 0
PDATA(pgm)->flags32 |= FLAGS32_INIT_SMC;

View File

@ -63,9 +63,9 @@ SIGN [+-]
%%
{SIGN}?{DIGIT}+ { yylval = number(yytext); return TKN_NUMBER; }
{SIGN}?{DIGIT}+"."{DIGIT}* { yylval = number_real(yytext); return TKN_NUMBER_REAL; }
{SIGN}?"."{DIGIT}+ { yylval = number_real(yytext); return TKN_NUMBER_REAL; }
{DIGIT}+ { yylval = new_number(yytext); return TKN_NUMBER; /* sign is treated in grammar */ }
{SIGN}?{DIGIT}+"."{DIGIT}* { yylval = new_number_real(yytext); return TKN_NUMBER_REAL; }
{SIGN}?"."{DIGIT}+ { yylval = new_number_real(yytext); return TKN_NUMBER_REAL; }
["]([^"\\\n]|\\.|\\\n)*["] {
char *str= cfg_strdup("lexer.l", yytext);
@ -73,12 +73,12 @@ SIGN [+-]
size_t len = strlen(str);
if(len)
str[len-1] = 0;
yylval = string(str);
yylval = new_string(str);
free(str);
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 */
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; }
allowfullpagebitstream { yylval=NULL; ccap(); return K_ALLOWFULLPAGEBITSTREAM; }
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_EQUAL; }
";" { 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_RIGHT_PAREN; }

View File

@ -169,6 +169,7 @@ enum ctl_stack_t {
CTL_STACK_HVSP /* high voltage serial programming control stack */
};
/*
* serial programming instruction bit specifications
*/
@ -183,19 +184,25 @@ typedef struct opcode {
} OPCODE;
/* Any changes here, please also reflect in dev_part_strct() of developer_opts.c */
#define AVRPART_SERIALOK 0x0001 /* part supports serial programming */
#define AVRPART_PARALLELOK 0x0002 /* part supports parallel programming */
#define AVRPART_PSEUDOPARALLEL 0x0004 /* part has pseudo parallel support */
#define AVRPART_HAS_JTAG 0x0008 /* part has a JTAG i/f */
#define AVRPART_ALLOWFULLPAGEBITSTREAM 0x0010 /* JTAG ICE mkII param. */
#define AVRPART_ENABLEPAGEPROGRAMMING 0x0020 /* JTAG ICE mkII param. */
#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) */
#define AVRPART_AVR32 0x0100 /* part is in AVR32 family */
#define AVRPART_HAS_TPI 0x0800 /* part has TPI i/f rather than ISP (ATtiny4/5/9/10) */
#define AVRPART_IS_AT90S1200 0x1000 /* part is an AT90S1200 (needs special treatment) */
#define AVRPART_HAS_UPDI 0x2000 /* part has UPDI i/f (AVR8X) */
// Any changes here, please also reflect in dev_part_strct() of developer_opts.c
#define AVRPART_SERIALOK 1 // Part supports serial programming
#define AVRPART_PARALLELOK 2 // Part supports parallel programming
#define AVRPART_PSEUDOPARALLEL 4 // Part has pseudo parallel support
#define AVRPART_ALLOWFULLPAGEBITSTREAM 8 // JTAG ICE mkII param
#define AVRPART_ENABLEPAGEPROGRAMMING 16 // JTAG ICE mkII param
#define AVRPART_IS_AT90S1200 32 // Part is an AT90S1200, needs special treatment
// Programming modes for parts and programmers: reflect changes in lexer.l, developer_opts.c and config.c
#define PM_SPM 1 // Bootloaders, self-programming with SPM opcodes or NVM Controllers
#define PM_TPI 2 // Tiny Programming Interface (t4, t5, t9, t10, t20, t40, t102, t104)
#define PM_ISP 4 // SPI programming for In-System Programming (almost all classic parts)
#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_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 */
/* 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 {
const char * desc; /* long part name */
const char * id; /* short part name */
LISTID comments; // Used by developer options -p*/[ASsr...]
const char * parent_id; /* Used by developer options */
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 stk500_devcode; /* stk500 device code */
int avr910_devcode; /* avr910 device code */
@ -262,7 +280,7 @@ typedef struct avrpart {
int programlockpulsewidth; /* stk500 v2 hv mode parameter */
int programlockpolltimeout; /* 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 rampz; /* JTAG ICE mkII XML file parameter */
@ -677,13 +695,21 @@ typedef enum {
CONNTYPE_SPI
} 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 {
LISTID id;
const char *desc;
void (*initpgm)(struct programmer_t *pgm); // Sets up the AVRDUDE programmer
LISTID comments; // Used by developer options -c*/[ASsr...]
const char *parent_id; // Used by developer options
int prog_modes; // Programming interfaces, see #define PM_...
struct pindef_t pin[N_PINS];
conntype_t conntype;
int baudrate;
@ -695,7 +721,7 @@ typedef struct programmer_t {
const char *usbproduct;
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;
char type[PGM_TYPELEN];
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) {
int tries, ret;
if (p->flags & AVRPART_HAS_TPI) {
/* We do not support tpi. This is a dedicated SPI thing */
if (p->prog_modes & PM_TPI) {
/* 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);
return -1;
}

View File

@ -924,7 +924,7 @@ int main(int argc, char * argv [])
for (ln=lfirst(updates); ln; ln=lnext(ln)) {
upd = ldata(ln);
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",
progname,
(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
* are valid.
*/
if(!(p->flags & AVRPART_AVR32)) {
if(!(p->prog_modes & PM_aWire)) { // not AVR32
int attempt = 0;
int waittime = 10000; /* 10 ms */
@ -1071,7 +1071,7 @@ int main(int argc, char * argv [])
if (init_ok) {
rc = avr_signature(pgm, p);
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++;
if (pgm->read_sib) {
// Read SIB and compare FamilyID
@ -1193,8 +1193,7 @@ int main(int argc, char * argv [])
}
if (uflags & UF_AUTO_ERASE) {
if ((p->flags & AVRPART_HAS_PDI) && pgm->page_erase != NULL &&
lsize(updates) > 0) {
if ((p->prog_modes & PM_PDI) && pgm->page_erase && lsize(updates) > 0) {
if (quell_progress < 2) {
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"
@ -1203,7 +1202,7 @@ int main(int argc, char * argv [])
}
} else {
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;
for (ln=lfirst(updates); ln; ln=lnext(ln)) {

View File

@ -1130,8 +1130,7 @@ retry:
break;
case PGMTYPE_JTAGICE3:
if (buf[1] == STATUS_CMD_FAILED &&
(p->flags & AVRPART_HAS_DW) != 0) {
if (buf[1] == STATUS_CMD_FAILED && (p->prog_modes & PM_debugWIRE)) {
unsigned char cmd[4], *resp;
/* 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 ||
PDATA(pgm)->pgmtype == PGMTYPE_AVRISP_MKII ||
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
* remaining actions.
*/
if ((p->flags & AVRPART_HAS_PDI) != 0) {
/*
* Find out where the border between application and boot area
* is.
*/
if (p->prog_modes & PM_PDI) {
// Find the border between application and boot area
AVRMEM *bootmem = avr_locate_mem(p, "boot");
AVRMEM *flashmem = avr_locate_mem(p, "flash");
if (bootmem == NULL || flashmem == NULL) {
@ -1320,8 +1316,8 @@ static int stk500v2_jtag3_initialize(const PROGRAMMER *pgm, const AVRPART *p) {
LNODEID ln;
AVRMEM * m;
if ((p->flags & AVRPART_HAS_PDI) ||
(p->flags & AVRPART_HAS_TPI)) {
// FIXME: condition below looks fishy, suspect the code wants !(p->prog_modes & (PM_debugWIRE | PM_JTAG))
if (p->prog_modes & (PM_PDI | PM_TPI)) {
avrdude_message(MSG_INFO, "%s: jtag3_initialize(): part %s has no ISP interface\n",
progname, p->desc);
return -1;
@ -1330,7 +1326,7 @@ static int stk500v2_jtag3_initialize(const PROGRAMMER *pgm, const AVRPART *p) {
PROGRAMMER *pgmcp = pgm_dup(pgm);
pgmcp->cookie = PDATA(pgm)->chained_pdata;
if (p->flags & AVRPART_HAS_DW)
if (p->prog_modes & PM_debugWIRE)
parm[0] = PARM3_ARCH_TINY;
else
parm[0] = PARM3_ARCH_MEGA;
@ -1574,7 +1570,7 @@ static void stk500v2_enable(PROGRAMMER *pgm, const AVRPART *p) {
if((PDATA(pgm)->pgmtype == PGMTYPE_STK600 ||
PDATA(pgm)->pgmtype == PGMTYPE_AVRISP_MKII ||
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);
} else {
stk600_setup_isp(pgm);
@ -3689,7 +3685,7 @@ static int stk600_xprog_program_enable(const PROGRAMMER *pgm, const AVRPART *p)
AVRMEM *mem = NULL;
int use_tpi;
use_tpi = (p->flags & AVRPART_HAS_TPI) != 0;
use_tpi = (p->prog_modes & PM_TPI) != 0;
if (!use_tpi) {
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;
} else if (strncmp(mem->desc, "fuse", strlen("fuse")) == 0) {
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
* 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
* 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;
unsigned int addr = 0;
if (p->flags & AVRPART_HAS_TPI) {
if (p->prog_modes & PM_TPI) {
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",
progname);

View File

@ -674,7 +674,7 @@ static int usbasp_initialize(const PROGRAMMER *pgm, const AVRPART *p) {
else
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
// https://github.com/nofeletru/UsbAsp-flash
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.
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
linked together through a 1kOhm resistor. Verify that
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) {
unsigned char res[4];
if (p->flags & AVRPART_HAS_TPI)
if (p->prog_modes & PM_TPI)
return avr_tpi_chip_erase(pgm, p);
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) {
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);
else
return usbtiny_avr_op(pgm, p, AVR_OP_PGM_ENABLE, buf);