Implement -c */[sSA] (syntax-correct dump of programmer structure)

This commit is contained in:
Stefan Rueger 2022-08-08 16:52:09 +01:00
parent 075dee1dd3
commit 49fcd8a96e
No known key found for this signature in database
GPG Key ID: B0B4F1FD86B1EC55
12 changed files with 281 additions and 95 deletions

View File

@ -672,7 +672,7 @@ void avr_mem_display(const char * prefix, FILE * f, AVRMEM * m, AVRPART * p,
AVRPART * avr_new_part(void) AVRPART * avr_new_part(void)
{ {
AVRPART * p; AVRPART * p;
char *nulp = cache_string(""); const char *nulp = cache_string("");
p = (AVRPART *)malloc(sizeof(AVRPART)); p = (AVRPART *)malloc(sizeof(AVRPART));
if (p == NULL) { if (p == NULL) {

View File

@ -366,7 +366,7 @@ int read_config(const char * file)
// Linear-search cache for a few often-referenced strings // Linear-search cache for a few often-referenced strings
char *cache_string(const char *file) { const char *cache_string(const char *file) {
static char **fnames; static char **fnames;
static int n=0; static int n=0;
@ -394,3 +394,8 @@ char *cache_string(const char *file) {
return fnames[n++]; return fnames[n++];
} }
// Captures comments during parsing
int capture_comment_char(int c) {
return c;
}

View File

@ -101,6 +101,8 @@ void pyytext(void);
char * dup_string(const char * str); char * dup_string(const char * str);
int capture_comment_char(int c);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -1397,7 +1397,8 @@ yesno :
mem_specs : mem_specs :
mem_spec TKN_SEMI | mem_spec TKN_SEMI |
mem_alias TKN_SEMI | mem_alias TKN_SEMI |
mem_specs mem_spec TKN_SEMI mem_specs mem_spec TKN_SEMI |
/* empty */
; ;

View File

@ -613,8 +613,8 @@ void dev_output_part_defs(char *partdesc) {
if((flags = strchr(partdesc, '/'))) if((flags = strchr(partdesc, '/')))
*flags++ = 0; *flags++ = 0;
if(!flags && !strcmp(partdesc, "*")) // Treat -p * as if it was -p */* if(!flags && !strcmp(partdesc, "*")) // Treat -p * as if it was -p */s
flags = "*"; flags = "s";
if(!*flags || !strchr("cdoASsrw*t", *flags)) { if(!*flags || !strchr("cdoASsrw*t", *flags)) {
dev_info("%s: flags for developer option -p <wildcard>/<flags> not recognised\n", progname); dev_info("%s: flags for developer option -p <wildcard>/<flags> not recognised\n", progname);
@ -640,7 +640,7 @@ void dev_output_part_defs(char *partdesc) {
" $ avrdude -p m328*/st | grep chip_erase_delay\n" " $ avrdude -p m328*/st | grep chip_erase_delay\n"
" avrdude -p*/r | sort\n" " avrdude -p*/r | sort\n"
"Notes:\n" "Notes:\n"
" -p * is the same as -p */*\n" " -p * is the same as -p */s\n"
" This help message is printed using any unrecognised flag, eg, -p/h\n" " This help message is printed using any unrecognised flag, eg, -p/h\n"
" Leaving no space after -p can be an OK substitute for quoting in shells\n" " Leaving no space after -p can be an OK substitute for quoting in shells\n"
" /s, /S and /A outputs are designed to be used as input in avrdude.conf\n" " /s, /S and /A outputs are designed to be used as input in avrdude.conf\n"
@ -935,19 +935,37 @@ static void dev_pgm_raw(PROGRAMMER *pgm) {
dp.id = NULL; dp.id = NULL;
dp.parent_id = NULL; dp.parent_id = NULL;
dp.initpgm = NULL; dp.initpgm = NULL;
dp.usbpid = NULL;
dp.usbdev = NULL;
dp.usbsn = NULL;
dp.usbvendor = NULL;
dp.usbproduct = NULL;
dp.hvupdi_support = NULL;
// Only dump contents of PROGRAMMER struct up to and excluding the fd component // Only dump contents of PROGRAMMER struct up to and excluding the fd component
dev_raw_dump((char *) &dp, offsetof(PROGRAMMER, fd), id, "pgm", 0); dev_raw_dump((char *) &dp, offsetof(PROGRAMMER, fd), id, "pgm", 0);
} }
static void dev_pgm_strct(PROGRAMMER *pgm, bool tsv, PROGRAMMER *base) { static const char *connstr(conntype_t conntype) {
if(!tsv) { switch(conntype) {
int firstid = 1; case CONNTYPE_PARALLEL: return "parallel";
case CONNTYPE_SERIAL: return "serial";
case CONNTYPE_USB: return "usb";
case CONNTYPE_SPI: return "spi";
default: return "<unknown>";
}
}
static void dev_pgm_strct(PROGRAMMER *pgm, bool tsv, PROGRAMMER *base) {
char *id = ldata(lfirst(pgm->id));
LNODEID ln;
int firstid;
if(!tsv) {
dev_info("#------------------------------------------------------------\n"); dev_info("#------------------------------------------------------------\n");
dev_info("# "); dev_info("# ");
for(LNODEID ln=lfirst(pgm->id); ln; ln=lnext(ln)) { for(firstid=1, ln=lfirst(pgm->id); ln; ln=lnext(ln)) {
if(!firstid) if(!firstid)
dev_info("/"); dev_info("/");
firstid = 0; firstid = 0;
@ -961,6 +979,67 @@ static void dev_pgm_strct(PROGRAMMER *pgm, bool tsv, PROGRAMMER *base) {
dev_info("\nprogrammer\n"); dev_info("\nprogrammer\n");
} }
if(tsv)
dev_info(".prog\t%s\tid\t", id);
else
dev_info(" %-19s = ", "id");
for(firstid=1, ln=lfirst(pgm->id); ln; ln=lnext(ln)) {
if(!firstid)
dev_info(", ");
firstid = 0;
dev_info("\"%s\"", ldata(ln));
}
dev_info(tsv? "\n": ";\n");
_if_pgmout(strcmp, "\"%s\"", desc);
_pgmout_fmt("type", "\"%s\"", locate_programmer_type_id(pgm->initpgm));
_pgmout_fmt("connection_type", "%s", connstr(pgm->conntype));
_if_pgmout(intcmp, "%d", baudrate);
_if_pgmout(intcmp, "0x%04x", usbvid);
if(pgm->usbpid && lfirst(pgm->usbpid)) {
if(tsv)
dev_info(".prog\t%s\tusbpid\t", id);
else
dev_info(" %-19s = ", "usbpid");
for(firstid=1, ln=lfirst(pgm->usbpid); ln; ln=lnext(ln)) {
if(!firstid)
dev_info(", ");
firstid = 0;
dev_info("0x%04x", *(unsigned int *) ldata(ln));
}
dev_info(tsv? "\n": ";\n");
}
_if_pgmout(strcmp, "\"%s\"", usbdev);
_if_pgmout(strcmp, "\"%s\"", usbsn);
_if_pgmout(strcmp, "\"%s\"", usbvendor);
_if_pgmout(strcmp, "\"%s\"", usbproduct);
for(int i=0; i<N_PINS; i++) {
char *str = pins_to_strdup(pgm->pin+i);
if(str && *str)
_pgmout_fmt(avr_pin_lcname(i), "%s", str);
if(str)
free(str);
}
if(pgm->hvupdi_support && lfirst(pgm->hvupdi_support)) {
if(tsv)
dev_info(".prog\t%s\thvupdu_support\t", id);
else
dev_info(" %-19s = ", "hvupdi_support");
for(firstid=1, ln=lfirst(pgm->hvupdi_support); ln; ln=lnext(ln)) {
if(!firstid)
dev_info(", ");
firstid = 0;
dev_info("%d", *(unsigned int *) ldata(ln));
}
dev_info(tsv? "\n": ";\n");
}
if(!tsv) if(!tsv)
dev_info(";\n"); dev_info(";\n");
} }

View File

@ -51,6 +51,22 @@ static int dev_message(int msglvl, const char *fmt, ...);
#define dev_notice(...) dev_message(DEV_NOTICE, __VA_ARGS__) #define dev_notice(...) dev_message(DEV_NOTICE, __VA_ARGS__)
#define dev_notice2(...) dev_message(DEV_NOTICE2, __VA_ARGS__) #define dev_notice2(...) dev_message(DEV_NOTICE2, __VA_ARGS__)
#define _pgmout(fmt, component) \
dev_part_strct_entry(tsv, ".prog", id, NULL, #component, dev_sprintf(fmt, pgm->component))
#define _pgmout_fmt(name, fmt, what) \
dev_part_strct_entry(tsv, ".prog", id, NULL, name, dev_sprintf(fmt, what))
#define _if_pgmout(cmp, fmt, component) do { \
if(!base || cmp(base->component, pgm->component)) \
dev_part_strct_entry(tsv, ".prog", id, NULL, #component, dev_sprintf(fmt, pgm->component)); \
} while(0)
#define _if_pgmout_str(cmp, result, component) do { \
if(!base || cmp(base->component, pgm->component)) \
dev_part_strct_entry(tsv, ".prog", id, NULL, #component, result); \
} while(0)
#define _partout(fmt, component) \ #define _partout(fmt, component) \
dev_part_strct_entry(tsv, ".pt", p->desc, NULL, #component, dev_sprintf(fmt, p->component)) dev_part_strct_entry(tsv, ".pt", p->desc, NULL, #component, dev_sprintf(fmt, p->component))

View File

@ -67,13 +67,20 @@ SIGN [+-]
# { /* The following eats '#' style comments to end of line */ # { /* The following captures all '#' style comments to end of line */
BEGIN(comment); } BEGIN(comment); }
<comment>[^\n] { /* eat comments */ } <comment>[^\n]*\n+ { /* eat comments */
<comment>\n { cfg_lineno++; BEGIN(INITIAL); } capture_comment_char('#');
for(int i=0; yytext[i]; i++) {
capture_comment_char(yytext[i]);
if(yytext[i] == '\n')
cfg_lineno++;
}
BEGIN(INITIAL);
}
"/*" { /* The following eats multiline C style comments */ "/*" { /* The following eats multiline C style comments, they are not captured */
int c; int c;
int comment_start; int comment_start;

View File

@ -516,7 +516,15 @@ int pins_check(const struct programmer_t * const pgm, const struct pin_checklist
const char * avr_pin_name(int pinname); const char * avr_pin_name(int pinname);
/** /**
* This function returns a string representation of defined pins eg. ~1,2,~4,~5,7 * Returns the name of the pin as lowercase string.
*
* @param pinname the pinname which we want as string.
* @returns a lowercase string with the pinname, or <unknown> if pinname is invalid.
*/
const char * avr_pin_lcname(int pinname);
/**
* This function returns a string of defined pins, eg, ~1,2,~4,~5,7 or " (not used)"
* Another execution of this function will overwrite the previous result in the static buffer. * Another execution of this function will overwrite the previous result in the static buffer.
* *
* @param[in] pindef the pin definition for which we want the string representation * @param[in] pindef the pin definition for which we want the string representation
@ -525,9 +533,17 @@ const char * avr_pin_name(int pinname);
const char * pins_to_str(const struct pindef_t * const pindef); const char * pins_to_str(const struct pindef_t * const pindef);
/** /**
* This function returns a string representation of pins in the mask eg. 1,3,5-7,9,12 * This function returns a string of defined pins, eg, ~1, 2, ~4, ~5, 7 or ""
*
* @param[in] pindef the pin definition for which we want the string representation
* @returns a pointer to a string, which was created by strdup (NULL if out of memory)
*/
char *pins_to_strdup(const struct pindef_t * const pindef);
/**
* This function returns a string representation of pins in the mask, eg, 1,3,5-7,9,12
* Another execution of this function will overwrite the previous result in the static buffer. * Another execution of this function will overwrite the previous result in the static buffer.
* Consecutive pin number are representated as start-end. * Consecutive pin number are represented as start-end.
* *
* @param[in] pinmask the pin mask for which we want the string representation * @param[in] pinmask the pin mask for which we want the string representation
* @returns pointer to a static string. * @returns pointer to a static string.
@ -670,29 +686,32 @@ typedef enum {
typedef struct programmer_t { typedef struct programmer_t {
LISTID id; LISTID id;
char desc[PGM_DESCLEN]; char desc[PGM_DESCLEN];
char type[PGM_TYPELEN]; void (*initpgm)(struct programmer_t *pgm);
char port[PGM_PORTLEN]; const char *parent_id; // Used by developer options -c*/[sr...]
const char *parent_id;
unsigned int pinno[N_PINS];
struct pindef_t pin[N_PINS]; struct pindef_t pin[N_PINS];
exit_vcc_t exit_vcc;
exit_reset_t exit_reset;
exit_datahigh_t exit_datahigh;
conntype_t conntype; conntype_t conntype;
int ppidata;
int ppictrl;
int baudrate; int baudrate;
int usbvid; int usbvid;
LISTID usbpid; LISTID usbpid;
LISTID hvupdi_support; // List of UPDI HV variants the tool supports, see HV_UPDI_VARIANT_x const char *usbdev;
const char *usbdev, *usbsn, *usbvendor, *usbproduct; const char *usbsn;
double bitclock; // JTAG ICE clock period in microseconds const char *usbvendor;
int ispdelay; // ISP clock delay const char *usbproduct;
int page_size; // Page size if the programmer supports paged write/load 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; first one must be fd for dev_pgm_raw() // Values below are not set by config_gram.y; make sure fd is first for dev_pgm_raw()
union filedescriptor fd; union filedescriptor fd;
void (*initpgm)(struct programmer_t * pgm); char type[PGM_TYPELEN];
char port[PGM_PORTLEN];
unsigned int pinno[N_PINS]; // TODO to be removed if old pin data no longer needed
exit_vcc_t exit_vcc; // Should these be set in avrdude.conf?
exit_reset_t exit_reset;
exit_datahigh_t exit_datahigh;
int ppidata;
int ppictrl;
int ispdelay; // ISP clock delay
int page_size; // Page size if the programmer supports paged write/load
double bitclock; // JTAG ICE clock period in microseconds
int (*rdy_led) (struct programmer_t * pgm, int value); int (*rdy_led) (struct programmer_t * pgm, int value);
int (*err_led) (struct programmer_t * pgm, int value); int (*err_led) (struct programmer_t * pgm, int value);
@ -957,7 +976,9 @@ typedef struct programmer_type_t {
extern "C" { extern "C" {
#endif #endif
const PROGRAMMER_TYPE * locate_programmer_type(/*LISTID programmer_types, */const char * id); const PROGRAMMER_TYPE *locate_programmer_type(const char *id);
const char *locate_programmer_type_id(const void (*initpgm)(struct programmer_t *pgm));
typedef void (*walk_programmer_types_cb)(const char *id, const char *desc, typedef void (*walk_programmer_types_cb)(const char *id, const char *desc,
void *cookie); void *cookie);
@ -991,7 +1012,7 @@ void cleanup_config(void);
int read_config(const char * file); int read_config(const char * file);
char *cache_string(const char *file); const char *cache_string(const char *file);
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -752,13 +752,21 @@ int main(int argc, char * argv [])
} }
avrdude_message(MSG_NOTICE, "\n"); int dev_opts = 0;
// Developer option -c <wildcard>/[ASsrt] prints programmer description(s) and exits
if(programmer && (strcmp(programmer, "*") == 0 || strchr(programmer, '/'))) {
dev_output_pgm_defs(programmer);
dev_opts = 1;
}
// Developer option -p <wildcard>/[dASsrcow*t] prints part description(s) and exits // Developer option -p <wildcard>/[dASsrcow*t] prints part description(s) and exits
if(partdesc && (strcmp(partdesc, "*") == 0 || strchr(partdesc, '/'))) { if(partdesc && (strcmp(partdesc, "*") == 0 || strchr(partdesc, '/'))) {
dev_output_part_defs(partdesc); dev_output_part_defs(partdesc);
exit(1); dev_opts = 1;
} }
if(dev_opts)
exit(0);
avrdude_message(MSG_NOTICE, "\n");
if (partdesc) { if (partdesc) {
if (strcmp(partdesc, "?") == 0) { if (strcmp(partdesc, "?") == 0) {
@ -770,12 +778,6 @@ int main(int argc, char * argv [])
} }
} }
// Developer option -c <wildcard>/[ASsrt] prints programmer description(s) and exits
if(programmer && (strcmp(programmer, "*") == 0 || strchr(programmer, '/'))) {
dev_output_pgm_defs(programmer);
exit(1);
}
if (programmer) { if (programmer) {
if (strcmp(programmer, "?") == 0) { if (strcmp(programmer, "?") == 0) {
avrdude_message(MSG_INFO, "\n"); avrdude_message(MSG_INFO, "\n");

View File

@ -65,7 +65,7 @@ PROGRAMMER * pgm_new(void)
{ {
int i; int i;
PROGRAMMER * pgm; PROGRAMMER * pgm;
char *nulp = cache_string(""); const char *nulp = cache_string("");
pgm = (PROGRAMMER *)malloc(sizeof(*pgm)); pgm = (PROGRAMMER *)malloc(sizeof(*pgm));
if (pgm == NULL) { if (pgm == NULL) {

View File

@ -57,55 +57,55 @@
#include "xbee.h" #include "xbee.h"
const PROGRAMMER_TYPE programmers_types[] = { const PROGRAMMER_TYPE programmers_types[] = { // Name(s) the programmers call themselves
{"arduino", arduino_initpgm, arduino_desc}, {"arduino", arduino_initpgm, arduino_desc}, // "Arduino"
{"avr910", avr910_initpgm, avr910_desc}, {"avr910", avr910_initpgm, avr910_desc}, // "avr910"
{"avrftdi", avrftdi_initpgm, avrftdi_desc}, {"avrftdi", avrftdi_initpgm, avrftdi_desc}, // "avrftdi"
{"buspirate", buspirate_initpgm, buspirate_desc}, {"buspirate", buspirate_initpgm, buspirate_desc}, // "BusPirate"
{"buspirate_bb", buspirate_bb_initpgm, buspirate_bb_desc}, {"buspirate_bb", buspirate_bb_initpgm, buspirate_bb_desc}, // "BusPirate_BB"
{"butterfly", butterfly_initpgm, butterfly_desc}, {"butterfly", butterfly_initpgm, butterfly_desc}, // "butterfly"
{"butterfly_mk", butterfly_mk_initpgm, butterfly_mk_desc}, {"butterfly_mk", butterfly_mk_initpgm, butterfly_mk_desc}, // "butterfly_mk"
{"dragon_dw", jtagmkII_dragon_dw_initpgm, jtagmkII_dragon_dw_desc}, {"dragon_dw", jtagmkII_dragon_dw_initpgm, jtagmkII_dragon_dw_desc}, // "DRAGON_DW"
{"dragon_hvsp", stk500v2_dragon_hvsp_initpgm, stk500v2_dragon_hvsp_desc}, {"dragon_hvsp", stk500v2_dragon_hvsp_initpgm, stk500v2_dragon_hvsp_desc}, // "DRAGON_HVSP"
{"dragon_isp", stk500v2_dragon_isp_initpgm, stk500v2_dragon_isp_desc}, {"dragon_isp", stk500v2_dragon_isp_initpgm, stk500v2_dragon_isp_desc}, // "DRAGON_ISP"
{"dragon_jtag", jtagmkII_dragon_initpgm, jtagmkII_dragon_desc}, {"dragon_jtag", jtagmkII_dragon_initpgm, jtagmkII_dragon_desc}, // "DRAGON_JTAG"
{"dragon_pdi", jtagmkII_dragon_pdi_initpgm, jtagmkII_dragon_pdi_desc}, {"dragon_pdi", jtagmkII_dragon_pdi_initpgm, jtagmkII_dragon_pdi_desc}, // "DRAGON_PDI"
{"dragon_pp", stk500v2_dragon_pp_initpgm, stk500v2_dragon_pp_desc}, {"dragon_pp", stk500v2_dragon_pp_initpgm, stk500v2_dragon_pp_desc}, // "DRAGON_PP"
{"flip1", flip1_initpgm, flip1_desc}, {"flip1", flip1_initpgm, flip1_desc}, // "flip1"
{"flip2", flip2_initpgm, flip2_desc}, {"flip2", flip2_initpgm, flip2_desc}, // "flip2"
{"ftdi_syncbb", ft245r_initpgm, ft245r_desc}, {"ftdi_syncbb", ft245r_initpgm, ft245r_desc}, // "ftdi_syncbb"
{"jtagmki", jtagmkI_initpgm, jtagmkI_desc}, {"jtagmki", jtagmkI_initpgm, jtagmkI_desc}, // "JTAGMKI"
{"jtagmkii", jtagmkII_initpgm, jtagmkII_desc}, {"jtagmkii", jtagmkII_initpgm, jtagmkII_desc}, // "JTAGMKII"
{"jtagmkii_avr32", jtagmkII_avr32_initpgm, jtagmkII_avr32_desc}, {"jtagmkii_avr32", jtagmkII_avr32_initpgm, jtagmkII_avr32_desc}, // "JTAGMKII_AVR32"
{"jtagmkii_dw", jtagmkII_dw_initpgm, jtagmkII_dw_desc}, {"jtagmkii_dw", jtagmkII_dw_initpgm, jtagmkII_dw_desc}, // "JTAGMKII_DW"
{"jtagmkii_isp", stk500v2_jtagmkII_initpgm, stk500v2_jtagmkII_desc}, {"jtagmkii_isp", stk500v2_jtagmkII_initpgm, stk500v2_jtagmkII_desc}, // "JTAGMKII_ISP"
{"jtagmkii_pdi", jtagmkII_pdi_initpgm, jtagmkII_pdi_desc}, {"jtagmkii_pdi", jtagmkII_pdi_initpgm, jtagmkII_pdi_desc}, // "JTAGMKII_PDI"
{"jtagmkii_updi", jtagmkII_updi_initpgm, jtagmkII_updi_desc}, {"jtagmkii_updi", jtagmkII_updi_initpgm, jtagmkII_updi_desc}, // "JTAGMKII_UPDI"
{"jtagice3", jtag3_initpgm, jtag3_desc}, {"jtagice3", jtag3_initpgm, jtag3_desc}, // "JTAGICE3"
{"jtagice3_pdi", jtag3_pdi_initpgm, jtag3_pdi_desc}, {"jtagice3_pdi", jtag3_pdi_initpgm, jtag3_pdi_desc}, // "JTAGICE3_PDI"
{"jtagice3_updi", jtag3_updi_initpgm, jtag3_updi_desc}, {"jtagice3_updi", jtag3_updi_initpgm, jtag3_updi_desc}, // "JTAGICE3_UPDI"
{"jtagice3_dw", jtag3_dw_initpgm, jtag3_dw_desc}, {"jtagice3_dw", jtag3_dw_initpgm, jtag3_dw_desc}, // "JTAGICE3_DW"
{"jtagice3_isp", stk500v2_jtag3_initpgm, stk500v2_jtag3_desc}, {"jtagice3_isp", stk500v2_jtag3_initpgm, stk500v2_jtag3_desc}, // "JTAG3_ISP"
{"linuxgpio", linuxgpio_initpgm, linuxgpio_desc}, {"linuxgpio", linuxgpio_initpgm, linuxgpio_desc}, // "linuxgpio"
{"linuxspi", linuxspi_initpgm, linuxspi_desc}, {"linuxspi", linuxspi_initpgm, linuxspi_desc}, // LINUXSPI
{"micronucleus", micronucleus_initpgm, micronucleus_desc}, {"micronucleus", micronucleus_initpgm, micronucleus_desc}, // "micronucleus" or "Micronucleus V2.0"
{"par", par_initpgm, par_desc}, {"par", par_initpgm, par_desc}, // "PPI"
{"pickit2", pickit2_initpgm, pickit2_desc}, {"pickit2", pickit2_initpgm, pickit2_desc}, // "pickit2"
{"serbb", serbb_initpgm, serbb_desc}, {"serbb", serbb_initpgm, serbb_desc}, // "SERBB"
{"serialupdi", serialupdi_initpgm, serialupdi_desc}, {"serialupdi", serialupdi_initpgm, serialupdi_desc}, // "serialupdi"
{"stk500", stk500_initpgm, stk500_desc}, {"stk500", stk500_initpgm, stk500_desc}, // "STK500"
{"stk500generic", stk500generic_initpgm, stk500generic_desc}, {"stk500generic", stk500generic_initpgm, stk500generic_desc}, // "STK500GENERIC"
{"stk500v2", stk500v2_initpgm, stk500v2_desc}, {"stk500v2", stk500v2_initpgm, stk500v2_desc}, // "STK500V2"
{"stk500hvsp", stk500hvsp_initpgm, stk500hvsp_desc}, {"stk500hvsp", stk500hvsp_initpgm, stk500hvsp_desc}, // "STK500HVSP"
{"stk500pp", stk500pp_initpgm, stk500pp_desc}, {"stk500pp", stk500pp_initpgm, stk500pp_desc}, // "STK500PP"
{"stk600", stk600_initpgm, stk600_desc}, {"stk600", stk600_initpgm, stk600_desc}, // "STK600"
{"stk600hvsp", stk600hvsp_initpgm, stk600hvsp_desc}, {"stk600hvsp", stk600hvsp_initpgm, stk600hvsp_desc}, // "STK600HVSP"
{"stk600pp", stk600pp_initpgm, stk600pp_desc}, {"stk600pp", stk600pp_initpgm, stk600pp_desc}, // "STK600PP"
{"teensy", teensy_initpgm, teensy_desc}, {"teensy", teensy_initpgm, teensy_desc}, // "teensy"
{"usbasp", usbasp_initpgm, usbasp_desc}, {"usbasp", usbasp_initpgm, usbasp_desc}, // "usbasp"
{"usbtiny", usbtiny_initpgm, usbtiny_desc}, {"usbtiny", usbtiny_initpgm, usbtiny_desc}, // "USBtiny" or "usbtiny"
{"wiring", wiring_initpgm, wiring_desc}, {"wiring", wiring_initpgm, wiring_desc}, // "Wiring"
{"xbee", xbee_initpgm, xbee_desc}, {"xbee", xbee_initpgm, xbee_desc}, // "XBee"
}; };
const PROGRAMMER_TYPE * locate_programmer_type(const char * id) const PROGRAMMER_TYPE * locate_programmer_type(const char * id)
@ -128,6 +128,16 @@ const PROGRAMMER_TYPE * locate_programmer_type(const char * id)
return NULL; return NULL;
} }
// Return type id given the init function or "" if not found
const char *locate_programmer_type_id(void (*initpgm)(struct programmer_t *pgm)) {
for (int i=0; i < sizeof programmers_types/sizeof*programmers_types; i++)
if(programmers_types[i].initpgm == initpgm)
return programmers_types[i].id;
return "";
}
/* /*
* Iterate over the list of programmers given as "programmers", and * Iterate over the list of programmers given as "programmers", and
* call the callback function cb for each entry found. cb is being * call the callback function cb for each entry found. cb is being

View File

@ -312,7 +312,7 @@ int pins_check(const struct programmer_t * const pgm, const struct pin_checklist
} }
/** /**
* This function returns a string representation of defined pins eg. ~1,2,~4,~5,7 * This function returns a string of defined pins, eg, ~1,2,~4,~5,7 or " (not used)"
* Another execution of this function will overwrite the previous result in the static buffer. * Another execution of this function will overwrite the previous result in the static buffer.
* *
* @param[in] pindef the pin definition for which we want the string representation * @param[in] pindef the pin definition for which we want the string representation
@ -346,6 +346,28 @@ const char * pins_to_str(const struct pindef_t * const pindef) {
return buf; return buf;
} }
/**
* This function returns a string of defined pins, eg, ~1, 2, ~4, ~5, 7 or ""
*
* @param[in] pindef the pin definition for which we want the string representation
* @returns a pointer to a string, which was created by strdup (NULL if out of memory)
*/
char *pins_to_strdup(const struct pindef_t * const pindef) {
char buf[6*(PIN_MAX+1)], *p = buf;
*buf = 0;
for(int pin = PIN_MIN; pin <= PIN_MAX; pin++) {
int index = pin / PIN_FIELD_ELEMENT_SIZE, bit = pin % PIN_FIELD_ELEMENT_SIZE;
if(pindef->mask[index] & (1 << bit)) {
if(*buf)
*p++ = ',', *p++=' ';
p += sprintf(p, "~%d" + !(pindef->inverse[index] & (1 << bit)), pin);
}
}
return strdup(buf);
}
/** /**
* Returns the name of the pin as string. * Returns the name of the pin as string.
* *
@ -369,3 +391,24 @@ const char * avr_pin_name(int pinname) {
} }
/**
* Returns the name of the pin as string.
*
* @param pinname the pinname which we want as string.
* @returns a lowercase string with the pinname, or <unknown> if pinname is invalid.
*/
const char * avr_pin_lcname(int pinname) {
switch(pinname) {
case PPI_AVR_VCC : return "vcc";
case PPI_AVR_BUFF : return "buff";
case PIN_AVR_RESET : return "reset";
case PIN_AVR_SCK : return "sck";
case PIN_AVR_MOSI : return "mosi";
case PIN_AVR_MISO : return "miso";
case PIN_LED_ERR : return "errled";
case PIN_LED_RDY : return "rdyled";
case PIN_LED_PGM : return "pgmled";
case PIN_LED_VFY : return "vfyled";
default : return "<unknown>";
}
}