Prepare for new components in avrdude.conf incl prog_modes
- Add prog_modes to part and programmer definitions; prog_mode is a bitwise or of programming modes + PM_SPM: Bootloaders, self-programming with SPM/NVM Controllers + PM_TPI: t4, t5, t9, t10, t20, t40, t102, t104 + PM_ISP: SPI programming for In-System Programming (typ classic parts) + PM_PDI: Program and Debug Interface (xmega parts) + PM_UPDI: Unified Program and Debug Interface + PM_HVSP: High Voltage Serial Programming (some classic parts) + PM_HVPP: High Voltage Parallel Programming (most non-HVSP classic parts) + PM_debugWIRE: Simpler alternative to JTAG (a subset of HVPP/HVSP parts) + PM_JTAG: some classic parts, some xmega + PM_aWire: AVR32 parts - Add mcuid, a unique id in 0..2039, to part definition for urclock programmer - Add n_interrupts, the number of interrupts, to part definition - Add n_page_erase to part definition (# of pages erased during NVM erase) - Implement a simple calculator in config_gram.y so numeric values can be expressed as simple expressions such as PM_SPM | PM_UPDI - Introduce a new method of assigning simple components to the grammar without touching config_gram.y via an eligible-component list in config.c; numeric expressions on the rhs of an assignment resolve to integer values - Update documentation in avrdude.conf.in and avrdude.texi
This commit is contained in:
parent
cddf2943eb
commit
ed2b8342df
|
@ -21,39 +21,56 @@
|
||||||
# id = <id1> [, <id2> [, <id3>] ...] ; # <idN> are quoted strings
|
# id = <id1> [, <id2> [, <id3>] ...] ; # <idN> are quoted strings
|
||||||
# desc = <description> ; # quoted string
|
# desc = <description> ; # quoted string
|
||||||
# type = <type>; # programmer type, quoted string
|
# type = <type>; # programmer type, quoted string
|
||||||
# # supported programmer types can be listed by "-c ?type"
|
# # supported types can be listed by "-c ?type"
|
||||||
|
# prog_modes = PM_<i/f> {| PM_<i/f>} # interfaces, eg, PM_SPM|PM_PDI (1)
|
||||||
# connection_type = parallel | serial | usb | spi
|
# connection_type = parallel | serial | usb | spi
|
||||||
# baudrate = <num> ; # baudrate for avr910-programmer
|
# baudrate = <num> ; # baudrate for avr910-programmer
|
||||||
# vcc = <num1> [, <num2> ... ] ; # pin number(s)
|
# vcc = <pin1> [, <pin2> ... ] ; # pin number(s)
|
||||||
# buff = <num1> [, <num2> ... ] ; # pin number(s)
|
# buff = <pin1> [, <pin2> ... ] ; # pin number(s)
|
||||||
# reset = <num> ; # pin number
|
# reset = <pin> ; # pin number
|
||||||
# sck = <num> ; # pin number
|
# sck = <pin> ; # pin number
|
||||||
# mosi = <num> ; # pin number
|
# mosi = <pin> ; # pin number
|
||||||
# miso = <num> ; # pin number
|
# miso = <pin> ; # pin number
|
||||||
# errled = <num> ; # pin number
|
# errled = <pin> ; # pin number
|
||||||
# rdyled = <num> ; # pin number
|
# rdyled = <pin> ; # pin number
|
||||||
# pgmled = <num> ; # pin number
|
# pgmled = <pin> ; # pin number
|
||||||
# vfyled = <num> ; # pin number
|
# vfyled = <pin> ; # pin number
|
||||||
# usbvid = <hexnum> ; # USB VID (Vendor ID)
|
# usbvid = <hexnum> ; # USB VID (Vendor ID)
|
||||||
# usbpid = <hexnum> [, <hexnum> ...] ; # USB PID (Product ID) (1)
|
# usbpid = <hexnum> [, <hexnum> ...] ; # USB PID (Product ID) (2)
|
||||||
# usbdev = <interface> ; # USB interface or other device info
|
# usbdev = <interface> ; # USB interface or other device info
|
||||||
# usbvendor = <vendorname> ; # USB Vendor Name
|
# usbvendor = <vendorname> ; # USB Vendor Name
|
||||||
# usbproduct = <productname> ; # USB Product Name
|
# usbproduct = <productname> ; # USB Product Name
|
||||||
# usbsn = <serialno> ; # USB Serial Number
|
# usbsn = <serialno> ; # USB Serial Number
|
||||||
# hvupdi_support = <num> [, <num>, ... ] ; # UPDI HV Variants Support
|
# hvupdi_support = <num> [, <num>, ... ] ; # UPDI HV Variants Support
|
||||||
#
|
|
||||||
# To invert a bit, use = ~ <num>, the spaces are important.
|
|
||||||
# For a pin list all pins must be inverted.
|
|
||||||
# A single pin can be specified as usual = ~ <num>, for lists
|
|
||||||
# specify it as follows = ~ ( <num> [, <num2> ... ] ) .
|
|
||||||
#
|
|
||||||
# (1) Not all programmer types can process a list of PIDs.
|
|
||||||
# ;
|
# ;
|
||||||
#
|
#
|
||||||
|
# # To invert a bit, use = ~ <num>, the spaces are important.
|
||||||
|
# # For a pin list all pins must be inverted.
|
||||||
|
# # A single pin can be specified as usual = ~ <num>, for lists
|
||||||
|
# # specify it as follows = ~ ( <num> [, <num2> ... ] ).
|
||||||
|
# #
|
||||||
|
# # (1) The following program modes are known:
|
||||||
|
# # - PM_SPM: Bootloaders, self-programming with SPM opcodes or NVM Controllers
|
||||||
|
# # - PM_TPI: Tiny Programming Interface (t4, t5, t9, t10, t20, t40, t102, t104)
|
||||||
|
# # - PM_ISP: SPI programming for In-System Programming (almost all classic parts)
|
||||||
|
# # - PM_PDI: Program and Debug Interface (xmega parts)
|
||||||
|
# # - PM_UPDI: Unified Program and Debug Interface
|
||||||
|
# # - PM_HVSP: High Voltage Serial Programming (some classic parts)
|
||||||
|
# # - PM_HVPP: High Voltage Parallel Programming (most non-HVSP classic parts)
|
||||||
|
# # - PM_debugWIRE: Simpler alternative to JTAG (a subset of HVPP/HVSP parts)
|
||||||
|
# # - PM_JTAG: Joint Test Action Group standard (some classic parts, some xmega)
|
||||||
|
# # - PM_aWire: AVR32 parts
|
||||||
|
# #
|
||||||
|
# # (2) Not all programmer types can process a list of PIDs
|
||||||
|
#
|
||||||
# part
|
# part
|
||||||
# desc = <description> ; # quoted string
|
# desc = <description> ; # quoted string
|
||||||
# id = <id> ; # quoted string
|
# id = <id> ; # quoted string
|
||||||
# family_id = <id> ; # quoted string, eg, "megaAVR" or "tinyAVR"
|
# 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 urclock programmer
|
||||||
|
# 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
|
# hvupdi_variant = <num> ; # numeric -1 (n/a) or 0..2
|
||||||
# devicecode = <num> ; # deprecated, use stk500_devcode
|
# devicecode = <num> ; # deprecated, use stk500_devcode
|
||||||
# stk500_devcode = <num> ; # numeric
|
# stk500_devcode = <num> ; # numeric
|
||||||
|
@ -63,8 +80,9 @@
|
||||||
# has_pdi = <yes/no> ; # part has PDI i/f
|
# has_pdi = <yes/no> ; # part has PDI i/f
|
||||||
# has_updi = <yes/no> ; # part has UPDI i/f
|
# has_updi = <yes/no> ; # part has UPDI i/f
|
||||||
# has_tpi = <yes/no> ; # part has TPI i/f
|
# has_tpi = <yes/no> ; # part has TPI i/f
|
||||||
# is_at90s1200 = <yes/no> ; # AT90S1200 part
|
|
||||||
# is_avr32 = <yes/no> ; # AVR32 part
|
# is_avr32 = <yes/no> ; # AVR32 part
|
||||||
|
#
|
||||||
|
# is_at90s1200 = <yes/no> ; # AT90S1200 part
|
||||||
# signature = <num> <num> <num> ; # signature bytes
|
# signature = <num> <num> <num> ; # signature bytes
|
||||||
# usbpid = <num> ; # DFU USB PID
|
# usbpid = <num> ; # DFU USB PID
|
||||||
# chip_erase_delay = <num> ; # micro-seconds
|
# chip_erase_delay = <num> ; # micro-seconds
|
||||||
|
@ -247,7 +265,7 @@
|
||||||
# section avr061.zip which accompanies the application note
|
# section avr061.zip which accompanies the application note
|
||||||
# AVR061 available from:
|
# AVR061 available from:
|
||||||
#
|
#
|
||||||
# http://www.atmel.com/dyn/resources/prod_documents/doc2525.pdf
|
# https://ww1.microchip.com/downloads/en/Appnotes/doc2525.pdf
|
||||||
#
|
#
|
||||||
|
|
||||||
#define ATTINY10 0x10 /* the _old_ one that never existed! */
|
#define ATTINY10 0x10 /* the _old_ one that never existed! */
|
||||||
|
|
154
src/config.c
154
src/config.c
|
@ -24,6 +24,7 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
#include <stddef.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
|
||||||
|
@ -44,6 +45,7 @@ LISTID number_list;
|
||||||
PROGRAMMER * current_prog;
|
PROGRAMMER * current_prog;
|
||||||
AVRPART * current_part;
|
AVRPART * current_part;
|
||||||
AVRMEM * current_mem;
|
AVRMEM * current_mem;
|
||||||
|
int current_strct;
|
||||||
LISTID part_list;
|
LISTID part_list;
|
||||||
LISTID programmers;
|
LISTID programmers;
|
||||||
bool is_alias;
|
bool is_alias;
|
||||||
|
@ -53,6 +55,22 @@ char * cfg_infile;
|
||||||
|
|
||||||
extern char * yytext;
|
extern char * yytext;
|
||||||
|
|
||||||
|
#define pgm_comp_desc(x, type) { #x, COMP_PROGRAMMER, offsetof(PROGRAMMER, x), sizeof(((PROGRAMMER *) NULL)->x), type }
|
||||||
|
#define part_comp_desc(x, type) { #x, COMP_AVRPART, offsetof(AVRPART, x), sizeof(((AVRPART *) NULL)->x), type }
|
||||||
|
#define mem_comp_desc(x, type) { #x, COMP_AVRMEM, offsetof(AVRMEM, x), sizeof(((AVRMEM *) NULL)->x), type }
|
||||||
|
|
||||||
|
// Component description for config_gram.y, will be sorted appropriately on first use
|
||||||
|
Component_t avr_comp[] = {
|
||||||
|
// PROGRAMMER
|
||||||
|
pgm_comp_desc(prog_modes, COMP_INT),
|
||||||
|
|
||||||
|
// AVRPART
|
||||||
|
part_comp_desc(prog_modes, COMP_INT),
|
||||||
|
part_comp_desc(mcuid, COMP_INT),
|
||||||
|
part_comp_desc(n_interrupts, COMP_INT),
|
||||||
|
part_comp_desc(n_page_erase, COMP_INT),
|
||||||
|
};
|
||||||
|
|
||||||
#define DEBUG 0
|
#define DEBUG 0
|
||||||
|
|
||||||
void cleanup_config(void)
|
void cleanup_config(void)
|
||||||
|
@ -190,7 +208,7 @@ void free_tokens(int n, ...)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
TOKEN *number(const char *text) {
|
TOKEN *new_number(const char *text) {
|
||||||
struct token_t *tkn = new_token(TKN_NUMBER);
|
struct token_t *tkn = new_token(TKN_NUMBER);
|
||||||
tkn->value.type = V_NUM;
|
tkn->value.type = V_NUM;
|
||||||
tkn->value.number = atoi(text);
|
tkn->value.number = atoi(text);
|
||||||
|
@ -202,7 +220,7 @@ TOKEN *number(const char *text) {
|
||||||
return tkn;
|
return tkn;
|
||||||
}
|
}
|
||||||
|
|
||||||
TOKEN *number_real(const char *text) {
|
TOKEN *new_number_real(const char *text) {
|
||||||
struct token_t * tkn = new_token(TKN_NUMBER);
|
struct token_t * tkn = new_token(TKN_NUMBER);
|
||||||
tkn->value.type = V_NUM_REAL;
|
tkn->value.type = V_NUM_REAL;
|
||||||
tkn->value.number_real = atof(text);
|
tkn->value.number_real = atof(text);
|
||||||
|
@ -214,7 +232,7 @@ TOKEN *number_real(const char *text) {
|
||||||
return tkn;
|
return tkn;
|
||||||
}
|
}
|
||||||
|
|
||||||
TOKEN *hexnumber(const char *text) {
|
TOKEN *new_hexnumber(const char *text) {
|
||||||
struct token_t *tkn = new_token(TKN_NUMBER);
|
struct token_t *tkn = new_token(TKN_NUMBER);
|
||||||
char * e;
|
char * e;
|
||||||
|
|
||||||
|
@ -233,11 +251,41 @@ TOKEN *hexnumber(const char *text) {
|
||||||
return tkn;
|
return tkn;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TOKEN *new_constant(const char *con) {
|
||||||
|
struct token_t *tkn = new_token(TKN_NUMBER);
|
||||||
|
int assigned = 1;
|
||||||
|
|
||||||
TOKEN *string(const char *text) {
|
tkn->value.type = V_NUM;
|
||||||
|
tkn->value.number =
|
||||||
|
!strcmp("PM_SPM", con)? PM_SPM:
|
||||||
|
!strcmp("PM_TPI", con)? PM_TPI:
|
||||||
|
!strcmp("PM_ISP", con)? PM_ISP:
|
||||||
|
!strcmp("PM_PDI", con)? PM_PDI:
|
||||||
|
!strcmp("PM_UPDI", con)? PM_UPDI:
|
||||||
|
!strcmp("PM_HVSP", con)? PM_HVSP:
|
||||||
|
!strcmp("PM_HVPP", con)? PM_HVPP:
|
||||||
|
!strcmp("PM_debugWIRE", con)? PM_debugWIRE:
|
||||||
|
!strcmp("PM_JTAG", con)? PM_JTAG:
|
||||||
|
!strcmp("PM_aWire", con)? PM_aWire:
|
||||||
|
(assigned = 0);
|
||||||
|
|
||||||
|
if(!assigned) {
|
||||||
|
yyerror("can't identify constant %s", con);
|
||||||
|
free_token(tkn);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if DEBUG
|
||||||
|
avrdude_message(MSG_INFO, "CONSTANT(%s=%d)\n", con, tkn->value.number);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return tkn;
|
||||||
|
}
|
||||||
|
|
||||||
|
TOKEN *new_string(const char *text) {
|
||||||
struct token_t *tkn = new_token(TKN_STRING);
|
struct token_t *tkn = new_token(TKN_STRING);
|
||||||
tkn->value.type = V_STR;
|
tkn->value.type = V_STR;
|
||||||
tkn->value.string = cfg_strdup("string()", text);
|
tkn->value.string = cfg_strdup("new_string()", text);
|
||||||
|
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
avrdude_message(MSG_INFO, "STRING(%s)\n", tkn->value.string);
|
avrdude_message(MSG_INFO, "STRING(%s)\n", tkn->value.string);
|
||||||
|
@ -247,7 +295,7 @@ TOKEN *string(const char *text) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
TOKEN * keyword(int primary) {
|
TOKEN *new_keyword(int primary) {
|
||||||
return new_token(primary);
|
return new_token(primary);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -692,3 +740,97 @@ char *cfg_escape(const char *s) {
|
||||||
|
|
||||||
return cfg_strdup("cfg_escape()", buf);
|
return cfg_strdup("cfg_escape()", buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int cmp_comp(const void *v1, const void *v2) {
|
||||||
|
const Component_t *c1 = v1, *c2 = v2;
|
||||||
|
int ret = strcmp(c1->name, c2->name);
|
||||||
|
|
||||||
|
return ret? ret: c1->strct - c2->strct;
|
||||||
|
}
|
||||||
|
|
||||||
|
Component_t *cfg_comp_search(const char *name, int strct) {
|
||||||
|
static int init;
|
||||||
|
Component_t key;
|
||||||
|
|
||||||
|
if(!init++)
|
||||||
|
qsort(avr_comp, sizeof avr_comp/sizeof*avr_comp, sizeof(Component_t), cmp_comp);
|
||||||
|
|
||||||
|
|
||||||
|
key.name = name;
|
||||||
|
key.strct = strct;
|
||||||
|
return bsearch(&key, avr_comp, sizeof avr_comp/sizeof*avr_comp, sizeof(Component_t), cmp_comp);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const char *cfg_strct_name(int strct) {
|
||||||
|
switch(strct) {
|
||||||
|
case COMP_CONFIG_MAIN: return "avrdude.conf main";
|
||||||
|
case COMP_AVRPART: return "AVRPART";
|
||||||
|
case COMP_AVRMEM: return "AVRMEM";
|
||||||
|
case COMP_PROGRAMMER: return "PROGRAMMER";
|
||||||
|
}
|
||||||
|
return "unknown struct";
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *cfg_v_type(int type) {
|
||||||
|
switch(type) {
|
||||||
|
case V_NONE: return "void";
|
||||||
|
case V_NUM: return "number";
|
||||||
|
case V_NUM_REAL: return "real";
|
||||||
|
case V_STR: return "string";
|
||||||
|
case V_COMPONENT: return "component";
|
||||||
|
}
|
||||||
|
return "unknown v type";
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *cfg_comp_type(int type) {
|
||||||
|
switch(type) {
|
||||||
|
case COMP_INT: return "number";
|
||||||
|
case COMP_SHORT: return "short";
|
||||||
|
case COMP_CHAR: return "char";
|
||||||
|
case COMP_STRING: return "string";
|
||||||
|
case COMP_CHAR_ARRAY: return "byte array";
|
||||||
|
case COMP_INT_LISTID: return "number list";
|
||||||
|
case COMP_STRING_LISTID: return "string list";
|
||||||
|
case COMP_OPCODE: return "opcode";
|
||||||
|
case COMP_PIN: return "pin";
|
||||||
|
case COMP_PIN_LIST: return "pin list";
|
||||||
|
}
|
||||||
|
return "unknown comp type";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Used by config_gram.y to assign a component in one of the relevant structures with a value
|
||||||
|
void cfg_assign(char *sp, int strct, Component_t *cp, VALUE *v) {
|
||||||
|
const char *str;
|
||||||
|
int num;
|
||||||
|
|
||||||
|
switch(cp->type) {
|
||||||
|
case COMP_CHAR:
|
||||||
|
case COMP_SHORT:
|
||||||
|
case COMP_INT:
|
||||||
|
if(v->type != V_NUM) {
|
||||||
|
yywarning("%s in %s expects a %s but is assigned a %s",
|
||||||
|
cp->name, cfg_strct_name(strct), cfg_comp_type(cp->type), cfg_v_type(v->type));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// TODO: consider endianess (code currently assumes little endian)
|
||||||
|
num = v->number;
|
||||||
|
memcpy(sp+cp->offset, &num, cp->size);
|
||||||
|
break;
|
||||||
|
case COMP_STRING:
|
||||||
|
if(v->type != V_STR) {
|
||||||
|
yywarning("%s in %s expects a string but is assigned a %s",
|
||||||
|
cp->name, cfg_strct_name(strct), cfg_v_type(v->type));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
str = cache_string(v->string);
|
||||||
|
memcpy(sp+cp->offset, &str, cp->size);
|
||||||
|
break;
|
||||||
|
// TODO: implement COMP_CHAR_ARRAY, COMP_INT_LISTID, COMP_STRING_LISTID, ...
|
||||||
|
default:
|
||||||
|
yywarning("%s in %s expects a %s but that is not implemented",
|
||||||
|
cp->name, cfg_strct_name(strct), cfg_comp_type(cp->type));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
59
src/config.h
59
src/config.h
|
@ -37,13 +37,48 @@ typedef struct {
|
||||||
} COMMENT;
|
} COMMENT;
|
||||||
|
|
||||||
|
|
||||||
enum { V_NONE, V_NUM, V_NUM_REAL, V_STR };
|
enum { // Which structures a component can occur in
|
||||||
|
COMP_CONFIG_MAIN,
|
||||||
|
COMP_PROGRAMMER,
|
||||||
|
COMP_AVRPART,
|
||||||
|
COMP_AVRMEM,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum { // Component types in structure
|
||||||
|
COMP_INT,
|
||||||
|
COMP_SHORT,
|
||||||
|
COMP_CHAR,
|
||||||
|
COMP_STRING,
|
||||||
|
COMP_CHAR_ARRAY, // This and below are not yet implemented
|
||||||
|
COMP_INT_LISTID,
|
||||||
|
COMP_STRING_LISTID,
|
||||||
|
COMP_OPCODE,
|
||||||
|
COMP_PIN, // Pins may never be implemented
|
||||||
|
COMP_PIN_LIST
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct { // Description of a component in a structure
|
||||||
|
const char *name; // Component name
|
||||||
|
int strct; // Structure, eg, COMP_AVRPART
|
||||||
|
int offset, size, type; // Location, size and type within structure
|
||||||
|
} Component_t;
|
||||||
|
|
||||||
|
|
||||||
|
enum { // Value types for VALUE struct
|
||||||
|
V_NONE,
|
||||||
|
V_NUM,
|
||||||
|
V_NUM_REAL,
|
||||||
|
V_STR,
|
||||||
|
V_COMPONENT,
|
||||||
|
};
|
||||||
|
|
||||||
typedef struct value_t {
|
typedef struct value_t {
|
||||||
int type;
|
int type;
|
||||||
union {
|
union {
|
||||||
int number;
|
int number;
|
||||||
double number_real;
|
double number_real;
|
||||||
char * string;
|
char * string;
|
||||||
|
Component_t *comp;
|
||||||
};
|
};
|
||||||
} VALUE;
|
} VALUE;
|
||||||
|
|
||||||
|
@ -59,6 +94,7 @@ extern FILE * yyin;
|
||||||
extern PROGRAMMER * current_prog;
|
extern PROGRAMMER * current_prog;
|
||||||
extern AVRPART * current_part;
|
extern AVRPART * current_part;
|
||||||
extern AVRMEM * current_mem;
|
extern AVRMEM * current_mem;
|
||||||
|
int current_strct;
|
||||||
extern int cfg_lineno;
|
extern int cfg_lineno;
|
||||||
extern char * cfg_infile;
|
extern char * cfg_infile;
|
||||||
extern LISTID string_list;
|
extern LISTID string_list;
|
||||||
|
@ -87,15 +123,17 @@ void free_token(TOKEN *tkn);
|
||||||
|
|
||||||
void free_tokens(int n, ...);
|
void free_tokens(int n, ...);
|
||||||
|
|
||||||
TOKEN *number(const char *text);
|
TOKEN *new_number(const char *text);
|
||||||
|
|
||||||
TOKEN *number_real(const char *text);
|
TOKEN *new_number_real(const char *text);
|
||||||
|
|
||||||
TOKEN *hexnumber(const char *text);
|
TOKEN *new_hexnumber(const char *text);
|
||||||
|
|
||||||
TOKEN *string(const char *text);
|
TOKEN *new_constant(const char *text);
|
||||||
|
|
||||||
TOKEN *keyword(int primary);
|
TOKEN *new_string(const char *text);
|
||||||
|
|
||||||
|
TOKEN *new_keyword(int primary);
|
||||||
|
|
||||||
void print_token(TOKEN *tkn);
|
void print_token(TOKEN *tkn);
|
||||||
|
|
||||||
|
@ -115,6 +153,15 @@ LISTID cfg_move_comments(void);
|
||||||
|
|
||||||
void cfg_pop_comms(void);
|
void cfg_pop_comms(void);
|
||||||
|
|
||||||
|
Component_t *cfg_comp_search(const char *name, int strct);
|
||||||
|
|
||||||
|
const char *cfg_v_type(int type);
|
||||||
|
|
||||||
|
const char *cfg_strct_name(int strct);
|
||||||
|
|
||||||
|
void cfg_assign(char *sp, int strct, Component_t *cp, VALUE *v);
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -208,12 +208,19 @@ static int pin_name;
|
||||||
%token TKN_COMMA
|
%token TKN_COMMA
|
||||||
%token TKN_EQUAL
|
%token TKN_EQUAL
|
||||||
%token TKN_SEMI
|
%token TKN_SEMI
|
||||||
%token TKN_TILDE
|
|
||||||
%token TKN_LEFT_PAREN
|
%token TKN_LEFT_PAREN
|
||||||
%token TKN_RIGHT_PAREN
|
%token TKN_RIGHT_PAREN
|
||||||
%token TKN_NUMBER
|
%token TKN_NUMBER
|
||||||
%token TKN_NUMBER_REAL
|
%token TKN_NUMBER_REAL
|
||||||
%token TKN_STRING
|
%token TKN_STRING
|
||||||
|
%token TKN_COMPONENT
|
||||||
|
|
||||||
|
%left OP_OR /* calculator operations */
|
||||||
|
%left OP_XOR
|
||||||
|
%left OP_AND
|
||||||
|
%left OP_PLUS OP_MINUS
|
||||||
|
%left OP_TIMES OP_DIVIDE OP_MODULO
|
||||||
|
%right OP_TILDE UNARY
|
||||||
|
|
||||||
%start configuration
|
%start configuration
|
||||||
|
|
||||||
|
@ -229,6 +236,27 @@ number_real :
|
||||||
TKN_NUMBER_REAL {
|
TKN_NUMBER_REAL {
|
||||||
$$ = $1;
|
$$ = $1;
|
||||||
}
|
}
|
||||||
|
;
|
||||||
|
|
||||||
|
|
||||||
|
expr: numexpr | TKN_STRING;
|
||||||
|
|
||||||
|
numexpr:
|
||||||
|
TKN_NUMBER |
|
||||||
|
numexpr OP_OR numexpr { $$ = $1; $$->value.number |= $3->value.number; } |
|
||||||
|
numexpr OP_XOR numexpr { $$ = $1; $$->value.number ^= $3->value.number; } |
|
||||||
|
numexpr OP_AND numexpr { $$ = $1; $$->value.number &= $3->value.number; } |
|
||||||
|
numexpr OP_PLUS numexpr { $$ = $1; $$->value.number += $3->value.number; } |
|
||||||
|
numexpr OP_MINUS numexpr { $$ = $1; $$->value.number -= $3->value.number; } |
|
||||||
|
numexpr OP_TIMES numexpr { $$ = $1; $$->value.number *= $3->value.number; } |
|
||||||
|
numexpr OP_DIVIDE numexpr { $$ = $1; $$->value.number /= $3->value.number; } |
|
||||||
|
numexpr OP_MODULO numexpr { $$ = $1; $$->value.number %= $3->value.number; } |
|
||||||
|
OP_PLUS numexpr %prec UNARY { $$ = $2; } |
|
||||||
|
OP_MINUS numexpr %prec UNARY { $$ = $2; $$->value.number = -$$->value.number; } |
|
||||||
|
OP_TILDE numexpr %prec UNARY { $$ = $2; $$->value.number = ~$$->value.number; } |
|
||||||
|
TKN_LEFT_PAREN numexpr TKN_RIGHT_PAREN { $$ = $2; }
|
||||||
|
;
|
||||||
|
|
||||||
|
|
||||||
configuration :
|
configuration :
|
||||||
/* empty */ | config
|
/* empty */ | config
|
||||||
|
@ -302,6 +330,7 @@ prog_def :
|
||||||
// pgm_fill_old_pins(current_prog); // TODO to be removed if old pin data no longer needed
|
// pgm_fill_old_pins(current_prog); // TODO to be removed if old pin data no longer needed
|
||||||
// pgm_display_generic(current_prog, id);
|
// pgm_display_generic(current_prog, id);
|
||||||
current_prog = NULL;
|
current_prog = NULL;
|
||||||
|
current_strct = COMP_CONFIG_MAIN;
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
@ -309,6 +338,7 @@ prog_def :
|
||||||
prog_decl :
|
prog_decl :
|
||||||
K_PROGRAMMER
|
K_PROGRAMMER
|
||||||
{ current_prog = pgm_new();
|
{ current_prog = pgm_new();
|
||||||
|
current_strct = COMP_PROGRAMMER;
|
||||||
current_prog->config_file = cache_string(cfg_infile);
|
current_prog->config_file = cache_string(cfg_infile);
|
||||||
current_prog->lineno = cfg_lineno;
|
current_prog->lineno = cfg_lineno;
|
||||||
}
|
}
|
||||||
|
@ -322,6 +352,7 @@ prog_decl :
|
||||||
YYABORT;
|
YYABORT;
|
||||||
}
|
}
|
||||||
current_prog = pgm_dup(pgm);
|
current_prog = pgm_dup(pgm);
|
||||||
|
current_strct = COMP_PROGRAMMER;
|
||||||
current_prog->parent_id = cache_string($3->value.string);
|
current_prog->parent_id = cache_string($3->value.string);
|
||||||
current_prog->comments = NULL;
|
current_prog->comments = NULL;
|
||||||
current_prog->config_file = cache_string(cfg_infile);
|
current_prog->config_file = cache_string(cfg_infile);
|
||||||
|
@ -389,6 +420,7 @@ part_def :
|
||||||
current_part->comments = cfg_move_comments();
|
current_part->comments = cfg_move_comments();
|
||||||
LISTADD(part_list, current_part);
|
LISTADD(part_list, current_part);
|
||||||
current_part = NULL;
|
current_part = NULL;
|
||||||
|
current_strct = COMP_CONFIG_MAIN;
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
@ -396,6 +428,7 @@ part_decl :
|
||||||
K_PART
|
K_PART
|
||||||
{
|
{
|
||||||
current_part = avr_new_part();
|
current_part = avr_new_part();
|
||||||
|
current_strct = COMP_AVRPART;
|
||||||
current_part->config_file = cache_string(cfg_infile);
|
current_part->config_file = cache_string(cfg_infile);
|
||||||
current_part->lineno = cfg_lineno;
|
current_part->lineno = cfg_lineno;
|
||||||
} |
|
} |
|
||||||
|
@ -409,6 +442,7 @@ part_decl :
|
||||||
}
|
}
|
||||||
|
|
||||||
current_part = avr_dup_part(parent_part);
|
current_part = avr_dup_part(parent_part);
|
||||||
|
current_strct = COMP_AVRPART;
|
||||||
current_part->parent_id = cache_string($3->value.string);
|
current_part->parent_id = cache_string($3->value.string);
|
||||||
current_part->comments = NULL;
|
current_part->comments = NULL;
|
||||||
current_part->config_file = cache_string(cfg_infile);
|
current_part->config_file = cache_string(cfg_infile);
|
||||||
|
@ -435,6 +469,10 @@ prog_parms :
|
||||||
;
|
;
|
||||||
|
|
||||||
prog_parm :
|
prog_parm :
|
||||||
|
TKN_COMPONENT TKN_EQUAL expr {
|
||||||
|
cfg_assign((char *) current_prog, COMP_PROGRAMMER, $1->value.comp, &$3->value);
|
||||||
|
free_token($1);
|
||||||
|
} |
|
||||||
K_ID TKN_EQUAL string_list {
|
K_ID TKN_EQUAL string_list {
|
||||||
{
|
{
|
||||||
while (lsize(string_list)) {
|
while (lsize(string_list)) {
|
||||||
|
@ -589,7 +627,7 @@ hvupdi_support_list:
|
||||||
pin_number_non_empty:
|
pin_number_non_empty:
|
||||||
TKN_NUMBER { if(0 != assign_pin(pin_name, $1, 0)) YYABORT; }
|
TKN_NUMBER { if(0 != assign_pin(pin_name, $1, 0)) YYABORT; }
|
||||||
|
|
|
|
||||||
TKN_TILDE TKN_NUMBER { if(0 != assign_pin(pin_name, $2, 1)) YYABORT; }
|
OP_TILDE TKN_NUMBER { if(0 != assign_pin(pin_name, $2, 1)) YYABORT; }
|
||||||
;
|
;
|
||||||
|
|
||||||
pin_number:
|
pin_number:
|
||||||
|
@ -601,7 +639,7 @@ pin_number:
|
||||||
pin_list_element:
|
pin_list_element:
|
||||||
pin_number_non_empty
|
pin_number_non_empty
|
||||||
|
|
|
|
||||||
TKN_TILDE TKN_LEFT_PAREN num_list TKN_RIGHT_PAREN { if(0 != assign_pin_list(1)) YYABORT; }
|
OP_TILDE TKN_LEFT_PAREN num_list TKN_RIGHT_PAREN { if(0 != assign_pin_list(1)) YYABORT; }
|
||||||
;
|
;
|
||||||
|
|
||||||
pin_list_non_empty:
|
pin_list_non_empty:
|
||||||
|
@ -665,6 +703,10 @@ retry_lines :
|
||||||
;
|
;
|
||||||
|
|
||||||
part_parm :
|
part_parm :
|
||||||
|
TKN_COMPONENT TKN_EQUAL expr {
|
||||||
|
cfg_assign((char *) current_part, COMP_AVRPART, $1->value.comp, &$3->value);
|
||||||
|
free_token($1);
|
||||||
|
} |
|
||||||
K_ID TKN_EQUAL TKN_STRING
|
K_ID TKN_EQUAL TKN_STRING
|
||||||
{
|
{
|
||||||
current_part->id = cache_string($3->value.string);
|
current_part->id = cache_string($3->value.string);
|
||||||
|
@ -1075,51 +1117,61 @@ part_parm :
|
||||||
|
|
||||||
K_HAS_JTAG TKN_EQUAL yesno
|
K_HAS_JTAG TKN_EQUAL yesno
|
||||||
{
|
{
|
||||||
if ($3->primary == K_YES)
|
if ($3->primary == K_YES) {
|
||||||
current_part->flags |= AVRPART_HAS_JTAG;
|
current_part->flags |= AVRPART_HAS_JTAG;
|
||||||
else if ($3->primary == K_NO)
|
current_part->prog_modes |= PM_JTAG;
|
||||||
|
} else if ($3->primary == K_NO) {
|
||||||
current_part->flags &= ~AVRPART_HAS_JTAG;
|
current_part->flags &= ~AVRPART_HAS_JTAG;
|
||||||
|
current_part->prog_modes &= ~PM_JTAG;
|
||||||
|
}
|
||||||
free_token($3);
|
free_token($3);
|
||||||
} |
|
} |
|
||||||
|
|
||||||
K_HAS_DW TKN_EQUAL yesno
|
K_HAS_DW TKN_EQUAL yesno
|
||||||
{
|
{
|
||||||
if ($3->primary == K_YES)
|
if ($3->primary == K_YES) {
|
||||||
current_part->flags |= AVRPART_HAS_DW;
|
current_part->flags |= AVRPART_HAS_DW;
|
||||||
else if ($3->primary == K_NO)
|
current_part->prog_modes |= PM_debugWIRE;
|
||||||
|
} else if ($3->primary == K_NO) {
|
||||||
current_part->flags &= ~AVRPART_HAS_DW;
|
current_part->flags &= ~AVRPART_HAS_DW;
|
||||||
|
current_part->prog_modes &= ~PM_debugWIRE;
|
||||||
|
}
|
||||||
free_token($3);
|
free_token($3);
|
||||||
} |
|
} |
|
||||||
|
|
||||||
K_HAS_PDI TKN_EQUAL yesno
|
K_HAS_PDI TKN_EQUAL yesno
|
||||||
{
|
{
|
||||||
if ($3->primary == K_YES)
|
if ($3->primary == K_YES) {
|
||||||
current_part->flags |= AVRPART_HAS_PDI;
|
current_part->flags |= AVRPART_HAS_PDI;
|
||||||
else if ($3->primary == K_NO)
|
current_part->prog_modes |= PM_PDI;
|
||||||
|
} else if ($3->primary == K_NO) {
|
||||||
current_part->flags &= ~AVRPART_HAS_PDI;
|
current_part->flags &= ~AVRPART_HAS_PDI;
|
||||||
|
current_part->prog_modes &= ~PM_PDI;
|
||||||
|
}
|
||||||
free_token($3);
|
free_token($3);
|
||||||
} |
|
} |
|
||||||
|
|
||||||
K_HAS_UPDI TKN_EQUAL yesno
|
K_HAS_UPDI TKN_EQUAL yesno
|
||||||
{
|
{
|
||||||
if ($3->primary == K_YES)
|
if ($3->primary == K_YES) {
|
||||||
current_part->flags |= AVRPART_HAS_UPDI;
|
current_part->flags |= AVRPART_HAS_UPDI;
|
||||||
else if ($3->primary == K_NO)
|
current_part->prog_modes |= PM_UPDI;
|
||||||
|
} else if ($3->primary == K_NO) {
|
||||||
current_part->flags &= ~AVRPART_HAS_UPDI;
|
current_part->flags &= ~AVRPART_HAS_UPDI;
|
||||||
|
current_part->prog_modes &= ~PM_UPDI;
|
||||||
|
}
|
||||||
free_token($3);
|
free_token($3);
|
||||||
} |
|
} |
|
||||||
|
|
||||||
K_HAS_TPI TKN_EQUAL yesno
|
K_HAS_TPI TKN_EQUAL yesno
|
||||||
{
|
{
|
||||||
if ($3->primary == K_YES)
|
if ($3->primary == K_YES) {
|
||||||
current_part->flags |= AVRPART_HAS_TPI;
|
current_part->flags |= AVRPART_HAS_TPI;
|
||||||
else if ($3->primary == K_NO)
|
current_part->prog_modes |= PM_TPI;
|
||||||
|
} else if ($3->primary == K_NO) {
|
||||||
current_part->flags &= ~AVRPART_HAS_TPI;
|
current_part->flags &= ~AVRPART_HAS_TPI;
|
||||||
|
current_part->prog_modes &= ~PM_TPI;
|
||||||
|
}
|
||||||
free_token($3);
|
free_token($3);
|
||||||
} |
|
} |
|
||||||
|
|
||||||
|
@ -1135,11 +1187,13 @@ part_parm :
|
||||||
|
|
||||||
K_IS_AVR32 TKN_EQUAL yesno
|
K_IS_AVR32 TKN_EQUAL yesno
|
||||||
{
|
{
|
||||||
if ($3->primary == K_YES)
|
if ($3->primary == K_YES) {
|
||||||
current_part->flags |= AVRPART_AVR32;
|
current_part->flags |= AVRPART_AVR32;
|
||||||
else if ($3->primary == K_NO)
|
current_part->prog_modes |= PM_aWire;
|
||||||
|
} else if ($3->primary == K_NO) {
|
||||||
current_part->flags &= ~AVRPART_AVR32;
|
current_part->flags &= ~AVRPART_AVR32;
|
||||||
|
current_part->prog_modes &= ~PM_aWire;
|
||||||
|
}
|
||||||
free_token($3);
|
free_token($3);
|
||||||
} |
|
} |
|
||||||
|
|
||||||
|
@ -1255,14 +1309,6 @@ part_parm :
|
||||||
} |
|
} |
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
K_EEPROM { current_mem = AVR_M_EEPROM; }
|
|
||||||
mem_specs |
|
|
||||||
|
|
||||||
K_FLASH { current_mem = AVR_M_FLASH; }
|
|
||||||
mem_specs |
|
|
||||||
*/
|
|
||||||
|
|
||||||
K_MEMORY TKN_STRING
|
K_MEMORY TKN_STRING
|
||||||
{ /* select memory for extension or create if not there */
|
{ /* select memory for extension or create if not there */
|
||||||
AVRMEM *mem = avr_locate_mem_noalias(current_part, $2->value.string);
|
AVRMEM *mem = avr_locate_mem_noalias(current_part, $2->value.string);
|
||||||
|
@ -1273,6 +1319,7 @@ part_parm :
|
||||||
}
|
}
|
||||||
avr_add_mem_order($2->value.string);
|
avr_add_mem_order($2->value.string);
|
||||||
current_mem = mem;
|
current_mem = mem;
|
||||||
|
current_strct = COMP_AVRMEM;
|
||||||
free_token($2);
|
free_token($2);
|
||||||
}
|
}
|
||||||
mem_specs
|
mem_specs
|
||||||
|
@ -1295,6 +1342,7 @@ part_parm :
|
||||||
}
|
}
|
||||||
cfg_pop_comms();
|
cfg_pop_comms();
|
||||||
current_mem = NULL;
|
current_mem = NULL;
|
||||||
|
current_strct = COMP_AVRPART;
|
||||||
} |
|
} |
|
||||||
K_MEMORY TKN_STRING TKN_EQUAL K_NULL
|
K_MEMORY TKN_STRING TKN_EQUAL K_NULL
|
||||||
{
|
{
|
||||||
|
@ -1306,6 +1354,7 @@ part_parm :
|
||||||
free_token($2);
|
free_token($2);
|
||||||
cfg_pop_comms();
|
cfg_pop_comms();
|
||||||
current_mem = NULL;
|
current_mem = NULL;
|
||||||
|
current_strct = COMP_AVRPART;
|
||||||
} |
|
} |
|
||||||
opcode TKN_EQUAL string_list {
|
opcode TKN_EQUAL string_list {
|
||||||
{
|
{
|
||||||
|
@ -1355,6 +1404,11 @@ mem_specs :
|
||||||
|
|
||||||
|
|
||||||
mem_spec :
|
mem_spec :
|
||||||
|
TKN_COMPONENT TKN_EQUAL expr {
|
||||||
|
cfg_assign((char *) current_mem, COMP_AVRMEM, $1->value.comp, &$3->value);
|
||||||
|
free_token($1);
|
||||||
|
} |
|
||||||
|
|
||||||
K_PAGED TKN_EQUAL yesno
|
K_PAGED TKN_EQUAL yesno
|
||||||
{
|
{
|
||||||
current_mem->paged = $3->primary == K_YES ? 1 : 0;
|
current_mem->paged = $3->primary == K_YES ? 1 : 0;
|
||||||
|
|
|
@ -63,7 +63,7 @@ static struct {
|
||||||
const char *mcu, *var, *value;
|
const char *mcu, *var, *value;
|
||||||
} ptinj[] = {
|
} ptinj[] = {
|
||||||
// Add triples here, eg, {"ATmega328P", "mcuid", "999"},
|
// Add triples here, eg, {"ATmega328P", "mcuid", "999"},
|
||||||
{NULL, NULL, NULL},
|
{NULL, NULL, NULL},
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct {
|
static struct {
|
||||||
|
@ -134,7 +134,7 @@ static void printallopcodes(const AVRPART *p, const char *d, OPCODE * const *opa
|
||||||
|
|
||||||
|
|
||||||
// Programming modes
|
// Programming modes
|
||||||
static char *prog_modes(const AVRPART *p) {
|
static char *prog_modes_str_flags(const AVRPART *p) {
|
||||||
static char type[1024];
|
static char type[1024];
|
||||||
|
|
||||||
*type = 0;
|
*type = 0;
|
||||||
|
@ -194,6 +194,34 @@ static char *prog_modes(const AVRPART *p) {
|
||||||
return type + (*type == '|');
|
return type + (*type == '|');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static char *prog_modes_str(int pm) {
|
||||||
|
static char type[1024];
|
||||||
|
|
||||||
|
strcpy(type, "0");
|
||||||
|
if(pm & PM_SPM)
|
||||||
|
strcat(type, " | PM_SPM");
|
||||||
|
if(pm & PM_TPI)
|
||||||
|
strcat(type, " | PM_TPI");
|
||||||
|
if(pm & PM_ISP)
|
||||||
|
strcat(type, " | PM_ISP");
|
||||||
|
if(pm & PM_PDI)
|
||||||
|
strcat(type, " | PM_PDI");
|
||||||
|
if(pm & PM_UPDI)
|
||||||
|
strcat(type, " | PM_UPDI");
|
||||||
|
if(pm & PM_HVSP)
|
||||||
|
strcat(type, " | PM_HVSP");
|
||||||
|
if(pm & PM_HVPP)
|
||||||
|
strcat(type, " | PM_HVPP");
|
||||||
|
if(pm & PM_debugWIRE)
|
||||||
|
strcat(type, " | PM_debugWIRE");
|
||||||
|
if(pm & PM_JTAG)
|
||||||
|
strcat(type, " | PM_JTAG");
|
||||||
|
if(pm & PM_aWire)
|
||||||
|
strcat(type, " | PM_aWire");
|
||||||
|
|
||||||
|
return type + (type[1] == 0? 0: 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Check whether address bits are where they should be in ISP commands
|
// Check whether address bits are where they should be in ISP commands
|
||||||
static void checkaddr(int memsize, int pagesize, int opnum, const OPCODE *op, const AVRPART *p, const AVRMEM *m) {
|
static void checkaddr(int memsize, int pagesize, int opnum, const OPCODE *op, const AVRPART *p, const AVRMEM *m) {
|
||||||
|
@ -573,6 +601,10 @@ static void dev_part_strct(const AVRPART *p, bool tsv, const AVRPART *base, bool
|
||||||
_if_partout_str(strcmp, descstr, desc);
|
_if_partout_str(strcmp, descstr, desc);
|
||||||
_if_partout_str(strcmp, cfg_escape(p->id), id);
|
_if_partout_str(strcmp, cfg_escape(p->id), id);
|
||||||
_if_partout_str(strcmp, cfg_escape(p->family_id), family_id);
|
_if_partout_str(strcmp, cfg_escape(p->family_id), family_id);
|
||||||
|
_if_partout_str(intcmp, cfg_strdup("dev_part_strct()", prog_modes_str(p->prog_modes)), prog_modes);
|
||||||
|
_if_partout(intcmp, "%d", mcuid);
|
||||||
|
_if_partout(intcmp, "%d", n_interrupts);
|
||||||
|
_if_partout(intcmp, "%d", n_page_erase);
|
||||||
_if_partout(intcmp, "%d", hvupdi_variant);
|
_if_partout(intcmp, "%d", hvupdi_variant);
|
||||||
_if_partout(intcmp, "0x%02x", stk500_devcode);
|
_if_partout(intcmp, "0x%02x", stk500_devcode);
|
||||||
_if_partout(intcmp, "0x%02x", avr910_devcode);
|
_if_partout(intcmp, "0x%02x", avr910_devcode);
|
||||||
|
@ -1032,7 +1064,7 @@ void dev_output_part_defs(char *partdesc) {
|
||||||
nfuses,
|
nfuses,
|
||||||
ok,
|
ok,
|
||||||
p->flags,
|
p->flags,
|
||||||
prog_modes(p),
|
prog_modes_str_flags(p),
|
||||||
p->config_file, p->lineno
|
p->config_file, p->lineno
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1189,6 +1221,7 @@ static void dev_pgm_strct(const PROGRAMMER *pgm, bool tsv, const PROGRAMMER *bas
|
||||||
_if_pgmout_str(strcmp, cfg_escape(pgm->desc), desc);
|
_if_pgmout_str(strcmp, cfg_escape(pgm->desc), desc);
|
||||||
if(!base || base->initpgm != pgm->initpgm)
|
if(!base || base->initpgm != pgm->initpgm)
|
||||||
_pgmout_fmt("type", "\"%s\"", locate_programmer_type_id(pgm->initpgm));
|
_pgmout_fmt("type", "\"%s\"", locate_programmer_type_id(pgm->initpgm));
|
||||||
|
_if_pgmout_str(intcmp, cfg_strdup("dev_pgm_strct()", prog_modes_str(pgm->prog_modes)), prog_modes);
|
||||||
if(!base || base->conntype != pgm->conntype)
|
if(!base || base->conntype != pgm->conntype)
|
||||||
_pgmout_fmt("connection_type", "%s", connstr(pgm->conntype));
|
_pgmout_fmt("connection_type", "%s", connstr(pgm->conntype));
|
||||||
_if_pgmout(intcmp, "%d", baudrate);
|
_if_pgmout(intcmp, "%d", baudrate);
|
||||||
|
|
|
@ -1694,34 +1694,53 @@ The format of the programmer definition is as follows:
|
||||||
|
|
||||||
@smallexample
|
@smallexample
|
||||||
programmer
|
programmer
|
||||||
parent <id> # <id> is a quoted string
|
parent <id> # optional parent
|
||||||
id = <id1> [, <id2> [, <id3>] ...] ; # <idN> are quoted strings
|
id = <id1> [, <id2> [, <id3>] ...] ; # <idN> are quoted strings
|
||||||
desc = <description> ; # quoted string
|
desc = <description> ; # quoted string
|
||||||
type = "par" | "stk500" | ... ; # programmer type (see below for a list)
|
type = <type>; # programmer type, quoted string
|
||||||
baudrate = <num> ; # baudrate for serial ports
|
# supported types can be listed by "-c ?type"
|
||||||
vcc = <num1> [, <num2> ... ] ; # pin number(s)
|
prog_modes = PM_<i/f> @{ | PM_<i/f> @} # interfaces, eg, PM_SPM|PM_PDI
|
||||||
buff = <num1> [, <num2> ... ] ; # pin number(s)
|
connection_type = parallel | serial | usb | spi
|
||||||
reset = <num> ; # pin number
|
baudrate = <num> ; # baudrate for avr910-programmer
|
||||||
sck = <num> ; # pin number
|
vcc = <pin1> [, <pin2> ... ] ; # pin number(s)
|
||||||
mosi = <num> ; # pin number
|
buff = <pin1> [, <pin2> ... ] ; # pin number(s)
|
||||||
miso = <num> ; # pin number
|
reset = <pin> ; # pin number
|
||||||
errled = <num> ; # pin number
|
sck = <pin> ; # pin number
|
||||||
rdyled = <num> ; # pin number
|
mosi = <pin> ; # pin number
|
||||||
pgmled = <num> ; # pin number
|
miso = <pin> ; # pin number
|
||||||
vfyled = <num> ; # pin number
|
errled = <pin> ; # pin number
|
||||||
usbvid = <hexnum>; # USB VID (Vendor ID)
|
rdyled = <pin> ; # pin number
|
||||||
usbpid = <hexnum> [, <hexnum> ...]; # USB PID (Product ID)
|
pgmled = <pin> ; # pin number
|
||||||
usbdev = <interface>; # USB interface or other device info
|
vfyled = <pin> ; # pin number
|
||||||
usbvendor = <vendorname>; # USB Vendor Name
|
usbvid = <hexnum> ; # USB VID (Vendor ID)
|
||||||
usbproduct = <productname>; # USB Product Name
|
usbpid = <hexnum> [, <hexnum> ...] ; # USB PID (Product ID)
|
||||||
usbsn = <serialno>; # USB Serial Number
|
usbdev = <interface> ; # USB interface or other device info
|
||||||
;
|
usbvendor = <vendorname> ; # USB Vendor Name
|
||||||
|
usbproduct = <productname> ; # USB Product Name
|
||||||
|
usbsn = <serialno> ; # USB Serial Number
|
||||||
|
hvupdi_support = <num> [, <num>, ... ] ; # UPDI HV Variants Support
|
||||||
|
;
|
||||||
@end smallexample
|
@end smallexample
|
||||||
|
|
||||||
@noindent
|
@noindent
|
||||||
If a parent is specified, all settings of it (except its ids) are used for the new
|
If a parent is specified, all settings of it (except its ids) are used for the new
|
||||||
programmer. These values can be changed by new setting them for the new programmer.
|
programmer. These values can be changed by new setting them for the new programmer.
|
||||||
|
|
||||||
|
@noindent
|
||||||
|
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
|
@noindent
|
||||||
To invert a bit in the pin definitions, use @code{= ~ <num>}.
|
To invert a bit in the pin definitions, use @code{= ~ <num>}.
|
||||||
|
|
||||||
|
@ -1729,7 +1748,7 @@ To invert a bit in the pin definitions, use @code{= ~ <num>}.
|
||||||
Not all programmer types can handle a list of USB PIDs.
|
Not all programmer types can handle a list of USB PIDs.
|
||||||
|
|
||||||
@noindent
|
@noindent
|
||||||
Following programmer types are currently implemented:
|
The following programmer types are currently implemented:
|
||||||
|
|
||||||
@multitable @columnfractions .25 .6
|
@multitable @columnfractions .25 .6
|
||||||
@include programmer_types.texi
|
@include programmer_types.texi
|
||||||
|
@ -1743,29 +1762,35 @@ Following programmer types are currently implemented:
|
||||||
|
|
||||||
@smallexample
|
@smallexample
|
||||||
part
|
part
|
||||||
id = <id> ; # quoted string
|
|
||||||
desc = <description> ; # quoted string
|
desc = <description> ; # quoted string
|
||||||
family_id = <description> ; # quoted string
|
id = <id> ; # quoted string
|
||||||
|
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 urclock programmer
|
||||||
|
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
|
has_jtag = <yes/no> ; # part has JTAG i/f
|
||||||
has_debugwire = <yes/no> ; # part has debugWire i/f
|
has_debugwire = <yes/no> ; # part has debugWire i/f
|
||||||
has_pdi = <yes/no> ; # part has PDI i/f
|
has_pdi = <yes/no> ; # part has PDI i/f
|
||||||
has_updi = <yes/no> ; # part has UPDI i/f
|
has_updi = <yes/no> ; # part has UPDI i/f
|
||||||
has_tpi = <yes/no> ; # part has TPI i/f
|
has_tpi = <yes/no> ; # part has TPI i/f
|
||||||
devicecode = <num> ; # numeric
|
is_avr32 = <yes/no> ; # AVR32 part
|
||||||
stk500_devcode = <num> ; # numeric
|
is_at90s1200 = <yes/no> ; # AT90S1200 part
|
||||||
avr910_devcode = <num> ; # numeric
|
|
||||||
signature = <num> <num> <num> ; # signature bytes
|
signature = <num> <num> <num> ; # signature bytes
|
||||||
usbpid = <num> ; # DFU USB PID
|
usbpid = <num> ; # DFU USB PID
|
||||||
reset = dedicated | io;
|
|
||||||
retry_pulse = reset | sck;
|
|
||||||
pgm_enable = <instruction format> ;
|
|
||||||
chip_erase = <instruction format> ;
|
|
||||||
chip_erase_delay = <num> ; # micro-seconds
|
chip_erase_delay = <num> ; # micro-seconds
|
||||||
|
reset = dedicated | io ;
|
||||||
|
retry_pulse = reset | sck ;
|
||||||
|
chip_erase_delay = <num> ; # chip erase delay (us)
|
||||||
# STK500 parameters (parallel programming IO lines)
|
# STK500 parameters (parallel programming IO lines)
|
||||||
pagel = <num> ; # pin name in hex, i.e., 0xD7
|
pagel = <num> ; # pin name in hex, i.e., 0xD7
|
||||||
bs2 = <num> ; # pin name in hex, i.e., 0xA0
|
bs2 = <num> ; # pin name in hex, i.e., 0xA0
|
||||||
serial = <yes/no> ; # can use serial downloading
|
serial = <yes/no> ; # can use serial downloading
|
||||||
parallel = <yes/no/pseudo>; # can use par. programming
|
parallel = <yes/no/pseudo> ; # can use par. programming
|
||||||
# STK500v2 parameters, to be taken from Atmel's XML files
|
# STK500v2 parameters, to be taken from Atmel's XML files
|
||||||
timeout = <num> ;
|
timeout = <num> ;
|
||||||
stabdelay = <num> ;
|
stabdelay = <num> ;
|
||||||
|
@ -1777,52 +1802,59 @@ part
|
||||||
predelay = <num> ;
|
predelay = <num> ;
|
||||||
postdelay = <num> ;
|
postdelay = <num> ;
|
||||||
pollmethod = <num> ;
|
pollmethod = <num> ;
|
||||||
mode = <num> ;
|
|
||||||
delay = <num> ;
|
|
||||||
blocksize = <num> ;
|
|
||||||
readsize = <num> ;
|
|
||||||
hvspcmdexedelay = <num> ;
|
hvspcmdexedelay = <num> ;
|
||||||
# STK500v2 HV programming parameters, from XML
|
# STK500v2 HV programming parameters, from XML
|
||||||
pp_controlstack = <num>, <num>, ...; # PP only
|
pp_controlstack = <num>, <num>, ... ; # PP only
|
||||||
hvsp_controlstack = <num>, <num>, ...; # HVSP only
|
hvsp_controlstack = <num>, <num>, ... ; # HVSP only
|
||||||
hventerstabdelay = <num>;
|
flash_instr = <num>, <num>, <num> ;
|
||||||
progmodedelay = <num>; # PP only
|
eeprom_instr = <num>, <num>, ... ;
|
||||||
latchcycles = <num>;
|
hventerstabdelay = <num> ;
|
||||||
togglevtg = <num>;
|
progmodedelay = <num> ; # PP only
|
||||||
poweroffdelay = <num>;
|
latchcycles = <num> ;
|
||||||
resetdelayms = <num>;
|
togglevtg = <num> ;
|
||||||
resetdelayus = <num>;
|
poweroffdelay = <num> ;
|
||||||
hvleavestabdelay = <num>;
|
resetdelayms = <num> ;
|
||||||
resetdelay = <num>;
|
resetdelayus = <num> ;
|
||||||
synchcycles = <num>; # HVSP only
|
hvleavestabdelay = <num> ;
|
||||||
chiperasepulsewidth = <num>; # PP only
|
resetdelay = <num> ;
|
||||||
chiperasepolltimeout = <num>;
|
synchcycles = <num> ; # HVSP only
|
||||||
chiperasetime = <num>; # HVSP only
|
chiperasepulsewidth = <num> ; # PP only
|
||||||
programfusepulsewidth = <num>; # PP only
|
chiperasepolltimeout = <num> ;
|
||||||
programfusepolltimeout = <num>;
|
chiperasetime = <num> ; # HVSP only
|
||||||
programlockpulsewidth = <num>; # PP only
|
programfusepulsewidth = <num> ; # PP only
|
||||||
programlockpolltimeout = <num>;
|
programfusepolltimeout = <num> ;
|
||||||
|
programlockpulsewidth = <num> ; # PP only
|
||||||
|
programlockpolltimeout = <num> ;
|
||||||
# JTAG ICE mkII parameters, also from XML files
|
# JTAG ICE mkII parameters, also from XML files
|
||||||
allowfullpagebitstream = <yes/no> ;
|
allowfullpagebitstream = <yes/no> ;
|
||||||
enablepageprogramming = <yes/no> ;
|
enablepageprogramming = <yes/no> ;
|
||||||
idr = <num> ; # IO addr of IDR (OCD) reg.
|
idr = <num> ; # IO addr of IDR (OCD) reg
|
||||||
rampz = <num> ; # IO addr of RAMPZ reg.
|
rampz = <num> ; # IO addr of RAMPZ reg
|
||||||
spmcr = <num> ; # mem addr of SPMC[S]R reg.
|
spmcr = <num> ; # mem addr of SPMC[S]R reg
|
||||||
eecr = <num> ; # mem addr of EECR reg.
|
eecr = <num> ; # mem addr of EECR reg only when != 0x3f
|
||||||
# (only when != 0x3F)
|
mcu_base = <num> ;
|
||||||
is_at90s1200 = <yes/no> ; # AT90S1200 part
|
nvm_base = <num> ;
|
||||||
is_avr32 = <yes/no> ; # AVR32 part
|
ocd_base = <num> ;
|
||||||
|
ocdrev = <num> ;
|
||||||
|
pgm_enable = <instruction format> ;
|
||||||
|
chip_erase = <instruction format> ;
|
||||||
|
|
||||||
memory <memtype>
|
memory <memtype>
|
||||||
paged = <yes/no> ; # yes / no
|
paged = <yes/no> ; # yes/no (flash only, do not use for EEPROM)
|
||||||
|
offset = <num> ; # memory offset
|
||||||
size = <num> ; # bytes
|
size = <num> ; # bytes
|
||||||
page_size = <num> ; # bytes
|
page_size = <num> ; # bytes
|
||||||
num_pages = <num> ; # numeric
|
num_pages = <num> ; # numeric
|
||||||
min_write_delay = <num> ; # micro-seconds
|
min_write_delay = <num> ; # micro-seconds
|
||||||
max_write_delay = <num> ; # micro-seconds
|
max_write_delay = <num> ; # micro-seconds
|
||||||
readback_p1 = <num> ; # byte value
|
readback = <num> <num> ; # pair of byte values
|
||||||
readback_p2 = <num> ; # byte value
|
readback_p1 = <num> ; # byte value (first component)
|
||||||
pwroff_after_write = <yes/no> ; # yes / no
|
readback_p2 = <num> ; # byte value (second component)
|
||||||
|
pwroff_after_write = <yes/no> ; # yes/no
|
||||||
|
mode = <num> ; # STK500 v2 file parameter from Atmel's XML files
|
||||||
|
delay = <num> ; # "
|
||||||
|
blocksize = <num> ; # "
|
||||||
|
readsize = <num> ; # "
|
||||||
read = <instruction format> ;
|
read = <instruction format> ;
|
||||||
write = <instruction format> ;
|
write = <instruction format> ;
|
||||||
read_lo = <instruction format> ;
|
read_lo = <instruction format> ;
|
||||||
|
@ -1832,8 +1864,8 @@ part
|
||||||
loadpage_lo = <instruction format> ;
|
loadpage_lo = <instruction format> ;
|
||||||
loadpage_hi = <instruction format> ;
|
loadpage_hi = <instruction format> ;
|
||||||
writepage = <instruction format> ;
|
writepage = <instruction format> ;
|
||||||
;
|
;
|
||||||
;
|
;
|
||||||
@end smallexample
|
@end smallexample
|
||||||
|
|
||||||
@menu
|
@menu
|
||||||
|
@ -1914,7 +1946,22 @@ write = "1 1 0 0 0 0 0 0 x x x x x x x x",
|
||||||
|
|
||||||
@end smallexample
|
@end smallexample
|
||||||
|
|
||||||
|
As the address bit numbers in the SPI opcodes are highly systematic, they
|
||||||
|
don't really need to be specified. A compact version of the format
|
||||||
|
specification neither uses bit-numbers for address lines nor spaces. If such
|
||||||
|
a string is longer than 7 characters, then the characters @code{0}, @code{1},
|
||||||
|
@code{x}, @code{a}, @code{i} and @code{o} will be recognised as the
|
||||||
|
corresponding bit, whilst any of the characters @code{.}, @code{-}, @code{_}
|
||||||
|
or @code{/} can act as arbitrary visual separators, which are ignored.
|
||||||
|
Examples:
|
||||||
|
|
||||||
|
@smallexample
|
||||||
|
|
||||||
|
loadpage_lo = "0100.0000--000x.xxxx--xxaa.aaaa--iiii.iiii";
|
||||||
|
|
||||||
|
loadpage_lo = "0100.0000", "000x.xxxx", "xxaa.aaaa", "iiii.iiii";
|
||||||
|
|
||||||
|
@end smallexample
|
||||||
|
|
||||||
@c
|
@c
|
||||||
@c Node
|
@c Node
|
||||||
|
|
39
src/lexer.l
39
src/lexer.l
|
@ -63,9 +63,9 @@ SIGN [+-]
|
||||||
|
|
||||||
%%
|
%%
|
||||||
|
|
||||||
{SIGN}?{DIGIT}+ { yylval = number(yytext); return TKN_NUMBER; }
|
{SIGN}?{DIGIT}+ { yylval = new_number(yytext); return TKN_NUMBER; }
|
||||||
{SIGN}?{DIGIT}+"."{DIGIT}* { yylval = number_real(yytext); return TKN_NUMBER_REAL; }
|
{SIGN}?{DIGIT}+"."{DIGIT}* { yylval = new_number_real(yytext); return TKN_NUMBER_REAL; }
|
||||||
{SIGN}?"."{DIGIT}+ { yylval = number_real(yytext); return TKN_NUMBER_REAL; }
|
{SIGN}?"."{DIGIT}+ { yylval = new_number_real(yytext); return TKN_NUMBER_REAL; }
|
||||||
|
|
||||||
["]([^"\\\n]|\\.|\\\n)*["] {
|
["]([^"\\\n]|\\.|\\\n)*["] {
|
||||||
char *str= cfg_strdup("lexer.l", yytext);
|
char *str= cfg_strdup("lexer.l", yytext);
|
||||||
|
@ -73,12 +73,12 @@ SIGN [+-]
|
||||||
size_t len = strlen(str);
|
size_t len = strlen(str);
|
||||||
if(len)
|
if(len)
|
||||||
str[len-1] = 0;
|
str[len-1] = 0;
|
||||||
yylval = string(str);
|
yylval = new_string(str);
|
||||||
free(str);
|
free(str);
|
||||||
return TKN_STRING;
|
return TKN_STRING;
|
||||||
}
|
}
|
||||||
|
|
||||||
0x{HEXDIGIT}+ { yylval = hexnumber(yytext); return TKN_NUMBER; }
|
0x{HEXDIGIT}+ { yylval = new_hexnumber(yytext); return TKN_NUMBER; }
|
||||||
|
|
||||||
#\n#\ PROGRAMMER\ DEFINITIONS\n#\n+ { /* Record comments so far as prologue and skip */
|
#\n#\ PROGRAMMER\ DEFINITIONS\n#\n+ { /* Record comments so far as prologue and skip */
|
||||||
cfg_capture_prologue();
|
cfg_capture_prologue();
|
||||||
|
@ -121,6 +121,23 @@ SIGN [+-]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
prog_modes|mcuid|n_interrupts|n_page_erase { /* Components for assignment */
|
||||||
|
Component_t *cp = cfg_comp_search(yytext, current_strct);
|
||||||
|
if(!cp) {
|
||||||
|
yyerror("Unknown component %s in %s", yytext, cfg_strct_name(current_strct));
|
||||||
|
return YYERRCODE;
|
||||||
|
}
|
||||||
|
yylval = new_token(TKN_COMPONENT);
|
||||||
|
yylval->value.comp = cp;
|
||||||
|
ccap();
|
||||||
|
return TKN_COMPONENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
PM_SPM|PM_TPI|PM_ISP|PM_PDI|PM_UPDI|PM_HVSP|PM_HVPP|PM_debugWIRE|PM_JTAG|PM_aWire { /* Constants */
|
||||||
|
yylval = new_constant(yytext);
|
||||||
|
return TKN_NUMBER;
|
||||||
|
}
|
||||||
|
|
||||||
alias { yylval=NULL; return K_ALIAS; }
|
alias { yylval=NULL; return K_ALIAS; }
|
||||||
allowfullpagebitstream { yylval=NULL; ccap(); return K_ALLOWFULLPAGEBITSTREAM; }
|
allowfullpagebitstream { yylval=NULL; ccap(); return K_ALLOWFULLPAGEBITSTREAM; }
|
||||||
avr910_devcode { yylval=NULL; ccap(); return K_AVR910_DEVCODE; }
|
avr910_devcode { yylval=NULL; ccap(); return K_AVR910_DEVCODE; }
|
||||||
|
@ -258,7 +275,17 @@ yes { yylval=new_token(K_YES); return K_YES; }
|
||||||
"," { yylval = NULL; pyytext(); return TKN_COMMA; }
|
"," { yylval = NULL; pyytext(); return TKN_COMMA; }
|
||||||
"=" { yylval = NULL; pyytext(); return TKN_EQUAL; }
|
"=" { yylval = NULL; pyytext(); return TKN_EQUAL; }
|
||||||
";" { yylval = NULL; pyytext(); return TKN_SEMI; }
|
";" { yylval = NULL; pyytext(); return TKN_SEMI; }
|
||||||
"~" { yylval = NULL; pyytext(); return TKN_TILDE; }
|
|
||||||
|
"|" { yylval = NULL; pyytext(); return OP_OR; }
|
||||||
|
"^" { yylval = NULL; pyytext(); return OP_XOR; }
|
||||||
|
"&" { yylval = NULL; pyytext(); return OP_AND; }
|
||||||
|
"+" { yylval = NULL; pyytext(); return OP_PLUS; }
|
||||||
|
"-" { yylval = NULL; pyytext(); return OP_MINUS; }
|
||||||
|
"*" { yylval = NULL; pyytext(); return OP_TIMES; }
|
||||||
|
"/" { yylval = NULL; pyytext(); return OP_DIVIDE; }
|
||||||
|
"%" { yylval = NULL; pyytext(); return OP_MODULO; }
|
||||||
|
"~" { yylval = NULL; pyytext(); return OP_TILDE; }
|
||||||
|
|
||||||
"(" { yylval = NULL; pyytext(); return TKN_LEFT_PAREN; }
|
"(" { yylval = NULL; pyytext(); return TKN_LEFT_PAREN; }
|
||||||
")" { yylval = NULL; pyytext(); return TKN_RIGHT_PAREN; }
|
")" { yylval = NULL; pyytext(); return TKN_RIGHT_PAREN; }
|
||||||
|
|
||||||
|
|
|
@ -169,6 +169,7 @@ enum ctl_stack_t {
|
||||||
CTL_STACK_HVSP /* high voltage serial programming control stack */
|
CTL_STACK_HVSP /* high voltage serial programming control stack */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* serial programming instruction bit specifications
|
* serial programming instruction bit specifications
|
||||||
*/
|
*/
|
||||||
|
@ -197,6 +198,18 @@ typedef struct opcode {
|
||||||
#define AVRPART_IS_AT90S1200 0x1000 /* part is an AT90S1200 (needs special treatment) */
|
#define AVRPART_IS_AT90S1200 0x1000 /* part is an AT90S1200 (needs special treatment) */
|
||||||
#define AVRPART_HAS_UPDI 0x2000 /* part has UPDI i/f (AVR8X) */
|
#define AVRPART_HAS_UPDI 0x2000 /* part has UPDI i/f (AVR8X) */
|
||||||
|
|
||||||
|
// 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_0 0 /* Shared UPDI/GPIO/RESET pin, HV on UPDI pin (tinyAVR0/1/2)*/
|
||||||
#define HV_UPDI_VARIANT_1 1 /* Dedicated UPDI pin, no HV (megaAVR0/AVR-Dx) */
|
#define HV_UPDI_VARIANT_1 1 /* Dedicated UPDI pin, no HV (megaAVR0/AVR-Dx) */
|
||||||
#define HV_UPDI_VARIANT_2 2 /* Shared UPDI pin, HV on _RESET (AVR-Ex) */
|
#define HV_UPDI_VARIANT_2 2 /* Shared UPDI pin, HV on _RESET (AVR-Ex) */
|
||||||
|
@ -209,13 +222,24 @@ typedef struct opcode {
|
||||||
|
|
||||||
#define TAG_ALLOCATED 1 /* memory byte is allocated */
|
#define TAG_ALLOCATED 1 /* memory byte is allocated */
|
||||||
|
|
||||||
/* Any changes here, please also reflect in dev_part_strct() of developer_opts.c */
|
/*
|
||||||
|
* Any changes in AVRPART or AVRMEM, please also ensure changes are made in
|
||||||
|
* - lexer.l
|
||||||
|
* - Either Component_t avr_comp[] of config.c or in config_gram.y
|
||||||
|
* - dev_part_strct() in developer_opts.c
|
||||||
|
* - avr_new_part() and/or avr_new_memtype() in avrpart.c for
|
||||||
|
* initialisation; note that all const char * must be initialised with ""
|
||||||
|
*/
|
||||||
typedef struct avrpart {
|
typedef struct avrpart {
|
||||||
const char * desc; /* long part name */
|
const char * desc; /* long part name */
|
||||||
const char * id; /* short part name */
|
const char * id; /* short part name */
|
||||||
LISTID comments; // Used by developer options -p*/[ASsr...]
|
LISTID comments; // Used by developer options -p*/[ASsr...]
|
||||||
const char * parent_id; /* Used by developer options */
|
const char * parent_id; /* Used by developer options */
|
||||||
const char * family_id; /* family id in the SIB (avr8x) */
|
const char * family_id; /* family id in the SIB (avr8x) */
|
||||||
|
int prog_modes; /* Programming interfaces, see #define PM_... */
|
||||||
|
int mcuid; /* Unique id in 0..2039 for urclock programmer */
|
||||||
|
int n_interrupts; /* Number of interrupts, used for vector bootloaders */
|
||||||
|
int n_page_erase; /* If set, number of pages erased during NVM erase */
|
||||||
int hvupdi_variant; /* HV pulse on UPDI pin, no pin or RESET pin */
|
int hvupdi_variant; /* HV pulse on UPDI pin, no pin or RESET pin */
|
||||||
int stk500_devcode; /* stk500 device code */
|
int stk500_devcode; /* stk500 device code */
|
||||||
int avr910_devcode; /* avr910 device code */
|
int avr910_devcode; /* avr910 device code */
|
||||||
|
@ -262,7 +286,7 @@ typedef struct avrpart {
|
||||||
int programlockpulsewidth; /* stk500 v2 hv mode parameter */
|
int programlockpulsewidth; /* stk500 v2 hv mode parameter */
|
||||||
int programlockpolltimeout; /* stk500 v2 hv mode parameter */
|
int programlockpolltimeout; /* stk500 v2 hv mode parameter */
|
||||||
int synchcycles; /* stk500 v2 hv mode parameter */
|
int synchcycles; /* stk500 v2 hv mode parameter */
|
||||||
int hvspcmdexedelay; /* stk500 v2 xml file parameter */
|
int hvspcmdexedelay; /* stk500 v2 hv mode file parameter */
|
||||||
|
|
||||||
unsigned char idr; /* JTAG ICE mkII XML file parameter */
|
unsigned char idr; /* JTAG ICE mkII XML file parameter */
|
||||||
unsigned char rampz; /* JTAG ICE mkII XML file parameter */
|
unsigned char rampz; /* JTAG ICE mkII XML file parameter */
|
||||||
|
@ -677,13 +701,21 @@ typedef enum {
|
||||||
CONNTYPE_SPI
|
CONNTYPE_SPI
|
||||||
} conntype_t;
|
} conntype_t;
|
||||||
|
|
||||||
/* Any changes here, please also reflect in dev_pgm_strct() of developer_opts.c */
|
/*
|
||||||
|
* Any changes in PROGRAMMER, please also ensure changes are made in
|
||||||
|
* - lexer.l
|
||||||
|
* - Either Component_t avr_comp[] of config.c or config_gram.y
|
||||||
|
* - dev_pgm_strct() in developer_opts.c
|
||||||
|
* - pgm_new() in pgm.c for initialisation; note that all const char * must
|
||||||
|
* be initialised with ""
|
||||||
|
*/
|
||||||
typedef struct programmer_t {
|
typedef struct programmer_t {
|
||||||
LISTID id;
|
LISTID id;
|
||||||
const char *desc;
|
const char *desc;
|
||||||
void (*initpgm)(struct programmer_t *pgm); // Sets up the AVRDUDE programmer
|
void (*initpgm)(struct programmer_t *pgm); // Sets up the AVRDUDE programmer
|
||||||
LISTID comments; // Used by developer options -c*/[ASsr...]
|
LISTID comments; // Used by developer options -c*/[ASsr...]
|
||||||
const char *parent_id; // Used by developer options
|
const char *parent_id; // Used by developer options
|
||||||
|
int prog_modes; // Programming interfaces, see #define PM_...
|
||||||
struct pindef_t pin[N_PINS];
|
struct pindef_t pin[N_PINS];
|
||||||
conntype_t conntype;
|
conntype_t conntype;
|
||||||
int baudrate;
|
int baudrate;
|
||||||
|
@ -695,7 +727,7 @@ typedef struct programmer_t {
|
||||||
const char *usbproduct;
|
const char *usbproduct;
|
||||||
LISTID hvupdi_support; // List of UPDI HV variants the tool supports, see HV_UPDI_VARIANT_x
|
LISTID hvupdi_support; // List of UPDI HV variants the tool supports, see HV_UPDI_VARIANT_x
|
||||||
|
|
||||||
// Values below are not set by config_gram.y; make sure fd is first for dev_pgm_raw()
|
// Values below are not set by config_gram.y; ensure fd is first for dev_pgm_raw()
|
||||||
union filedescriptor fd;
|
union filedescriptor fd;
|
||||||
char type[PGM_TYPELEN];
|
char type[PGM_TYPELEN];
|
||||||
char port[PGM_PORTLEN];
|
char port[PGM_PORTLEN];
|
||||||
|
|
Loading…
Reference in New Issue