Merge pull request #1091 from stefanrueger/config_file
Add new components in `avrdude.conf.in`
This commit is contained in:
commit
0d1b49a4e4
|
@ -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
|
||||
|
|
|
@ -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 \
|
||||
|
|
17
src/avr.c
17
src/avr.c
|
@ -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
|
@ -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);
|
||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -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;
|
||||
|
|
|
@ -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++)
|
||||
|
|
203
src/config.c
203
src/config.c
|
@ -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);
|
||||
}
|
||||
|
|
60
src/config.h
60
src/config.h
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
parent <id> # optional parent
|
||||
id = <id1> [, <id2> ... ] ; # <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
|
||||
;
|
||||
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> ;
|
||||
|
@ -1833,9 +1866,19 @@ part
|
|||
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
|
||||
|
|
17
src/fileio.c
17
src/fileio.c
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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;
|
||||
|
|
72
src/jtag3.c
72
src/jtag3.c
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
39
src/lexer.l
39
src/lexer.l
|
@ -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; }
|
||||
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
11
src/main.c
11
src/main.c
|
@ -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)) {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue