Merge pull request #1059 from stefanrueger/programmer-devopts
Implement -c <wildcard>/dev_options for printing programmer entries of avrdude.conf
This commit is contained in:
commit
0b94ffdd3b
|
@ -1243,7 +1243,7 @@ void avr_add_mem_order(const char *str) {
|
|||
if(avr_mem_order[i] && !strcmp(avr_mem_order[i], str))
|
||||
return;
|
||||
if(!avr_mem_order[i]) {
|
||||
avr_mem_order[i] = strdup(str);
|
||||
avr_mem_order[i] = cfg_strdup("avr_mem_order()", str);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -651,7 +651,7 @@ static int avrftdi_pin_setup(PROGRAMMER * pgm)
|
|||
static int avrftdi_open(PROGRAMMER * pgm, char *port)
|
||||
{
|
||||
int vid, pid, interface, index, err;
|
||||
char * serial, *desc;
|
||||
const char *serial, *desc;
|
||||
|
||||
avrftdi_t* pdata = to_pdata(pgm);
|
||||
|
||||
|
|
478
src/avrpart.c
478
src/avrpart.c
|
@ -1,4 +1,3 @@
|
|||
|
||||
/*
|
||||
* avrdude - A Downloader/Uploader for AVR device programmers
|
||||
* Copyright (C) 2000-2004 Brian S. Dean <bsd@bsdhome.com>
|
||||
|
@ -31,44 +30,23 @@
|
|||
*** Elementary functions dealing with OPCODE structures
|
||||
***/
|
||||
|
||||
OPCODE * avr_new_opcode(void)
|
||||
{
|
||||
OPCODE * m;
|
||||
|
||||
m = (OPCODE *)malloc(sizeof(*m));
|
||||
if (m == NULL) {
|
||||
avrdude_message(MSG_INFO, "avr_new_opcode(): out of memory\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
memset(m, 0, sizeof(*m));
|
||||
|
||||
return m;
|
||||
OPCODE *avr_new_opcode(void) {
|
||||
return (OPCODE *) cfg_malloc("avr_new_opcode()", sizeof(OPCODE));
|
||||
}
|
||||
|
||||
static OPCODE * avr_dup_opcode(OPCODE * op)
|
||||
{
|
||||
OPCODE * m;
|
||||
|
||||
/* this makes life easier */
|
||||
if (op == NULL) {
|
||||
static OPCODE *avr_dup_opcode(const OPCODE *op) {
|
||||
if(op == NULL) // Caller wants NULL if op == NULL
|
||||
return NULL;
|
||||
}
|
||||
|
||||
m = (OPCODE *)malloc(sizeof(*m));
|
||||
if (m == NULL) {
|
||||
avrdude_message(MSG_INFO, "avr_dup_opcode(): out of memory\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
OPCODE *m = (OPCODE *) cfg_malloc("avr_dup_opcode()", sizeof(*m));
|
||||
memcpy(m, op, sizeof(*m));
|
||||
|
||||
return m;
|
||||
}
|
||||
|
||||
void avr_free_opcode(OPCODE * op)
|
||||
{
|
||||
free(op);
|
||||
void avr_free_opcode(OPCODE *op) {
|
||||
if(op)
|
||||
free(op);
|
||||
}
|
||||
|
||||
|
||||
|
@ -268,11 +246,10 @@ int avr_set_input(OPCODE * op, unsigned char * cmd, unsigned char data)
|
|||
/*
|
||||
* avr_get_output()
|
||||
*
|
||||
* Retreive output data bits from the command results based on the
|
||||
* Retrieve output data bits from the command results based on the
|
||||
* opcode data.
|
||||
*/
|
||||
int avr_get_output(OPCODE * op, unsigned char * res, unsigned char * data)
|
||||
{
|
||||
int avr_get_output(const OPCODE *op, const unsigned char *res, unsigned char *data) {
|
||||
int i, j, bit;
|
||||
unsigned char value;
|
||||
unsigned char mask;
|
||||
|
@ -301,8 +278,7 @@ int avr_get_output(OPCODE * op, unsigned char * res, unsigned char * data)
|
|||
* Calculate the byte number of the output data based on the
|
||||
* opcode data.
|
||||
*/
|
||||
int avr_get_output_index(OPCODE * op)
|
||||
{
|
||||
int avr_get_output_index(const OPCODE *op) {
|
||||
int i, j;
|
||||
|
||||
for (i=0; i<32; i++) {
|
||||
|
@ -353,34 +329,17 @@ static char * bittype(int type)
|
|||
*** Elementary functions dealing with AVRMEM structures
|
||||
***/
|
||||
|
||||
AVRMEM * avr_new_memtype(void)
|
||||
{
|
||||
AVRMEM * m;
|
||||
|
||||
m = (AVRMEM *)malloc(sizeof(*m));
|
||||
if (m == NULL) {
|
||||
avrdude_message(MSG_INFO, "avr_new_memtype(): out of memory\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
memset(m, 0, sizeof(*m));
|
||||
AVRMEM *avr_new_memtype(void) {
|
||||
AVRMEM *m = (AVRMEM *) cfg_malloc("avr_new_memtype()", sizeof(*m));
|
||||
m->desc = cache_string("");
|
||||
m->page_size = 1; // ensure not 0
|
||||
|
||||
return m;
|
||||
}
|
||||
|
||||
AVRMEM_ALIAS * avr_new_memalias(void)
|
||||
{
|
||||
AVRMEM_ALIAS * m;
|
||||
|
||||
m = (AVRMEM_ALIAS *)malloc(sizeof(*m));
|
||||
if (m == NULL) {
|
||||
avrdude_message(MSG_INFO, "avr_new_memalias(): out of memory\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
memset(m, 0, sizeof(*m));
|
||||
|
||||
AVRMEM_ALIAS *avr_new_memalias(void) {
|
||||
AVRMEM_ALIAS *m = (AVRMEM_ALIAS *) cfg_malloc("avr_new_memalias()", sizeof*m);
|
||||
m->desc = cache_string("");
|
||||
return m;
|
||||
}
|
||||
|
||||
|
@ -389,212 +348,154 @@ AVRMEM_ALIAS * avr_new_memalias(void)
|
|||
* Allocate and initialize memory buffers for each of the device's
|
||||
* defined memory regions.
|
||||
*/
|
||||
int avr_initmem(AVRPART * p)
|
||||
{
|
||||
LNODEID ln;
|
||||
AVRMEM * m;
|
||||
int avr_initmem(const AVRPART *p) {
|
||||
if(p == NULL || p->mem == NULL)
|
||||
return -1;
|
||||
|
||||
for (ln=lfirst(p->mem); ln; ln=lnext(ln)) {
|
||||
m = ldata(ln);
|
||||
m->buf = (unsigned char *) malloc(m->size);
|
||||
if (m->buf == NULL) {
|
||||
avrdude_message(MSG_INFO, "%s: can't alloc buffer for %s size of %d bytes\n",
|
||||
progname, m->desc, m->size);
|
||||
return -1;
|
||||
}
|
||||
m->tags = (unsigned char *) malloc(m->size);
|
||||
if (m->tags == NULL) {
|
||||
avrdude_message(MSG_INFO, "%s: can't alloc buffer for %s size of %d bytes\n",
|
||||
progname, m->desc, m->size);
|
||||
return -1;
|
||||
}
|
||||
for (LNODEID ln=lfirst(p->mem); ln; ln=lnext(ln)) {
|
||||
AVRMEM *m = ldata(ln);
|
||||
m->buf = (unsigned char *) cfg_malloc("avr_initmem()", m->size);
|
||||
m->tags = (unsigned char *) cfg_malloc("avr_initmem()", m->size);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
AVRMEM * avr_dup_mem(AVRMEM * m)
|
||||
{
|
||||
AVRMEM * n;
|
||||
int i;
|
||||
AVRMEM *avr_dup_mem(const AVRMEM *m) {
|
||||
AVRMEM *n = avr_new_memtype();
|
||||
|
||||
n = avr_new_memtype();
|
||||
if(m) {
|
||||
*n = *m;
|
||||
|
||||
*n = *m;
|
||||
|
||||
if (m->buf != NULL) {
|
||||
n->buf = (unsigned char *)malloc(n->size);
|
||||
if (n->buf == NULL) {
|
||||
avrdude_message(MSG_INFO, "avr_dup_mem(): out of memory (memsize=%d)\n",
|
||||
n->size);
|
||||
exit(1);
|
||||
if(m->buf) {
|
||||
n->buf = (unsigned char *) cfg_malloc("avr_dup_mem()", n->size);
|
||||
memcpy(n->buf, m->buf, n->size);
|
||||
}
|
||||
memcpy(n->buf, m->buf, n->size);
|
||||
}
|
||||
|
||||
if (m->tags != NULL) {
|
||||
n->tags = (unsigned char *)malloc(n->size);
|
||||
if (n->tags == NULL) {
|
||||
avrdude_message(MSG_INFO, "avr_dup_mem(): out of memory (memsize=%d)\n",
|
||||
n->size);
|
||||
exit(1);
|
||||
if(m->tags) {
|
||||
n->tags = (unsigned char *) cfg_malloc("avr_dup_mem()", n->size);
|
||||
memcpy(n->tags, m->tags, n->size);
|
||||
}
|
||||
memcpy(n->tags, m->tags, n->size);
|
||||
}
|
||||
|
||||
for (i = 0; i < AVR_OP_MAX; i++) {
|
||||
n->op[i] = avr_dup_opcode(n->op[i]);
|
||||
for(int i = 0; i < AVR_OP_MAX; i++)
|
||||
n->op[i] = avr_dup_opcode(n->op[i]);
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
AVRMEM_ALIAS * avr_dup_memalias(AVRMEM_ALIAS * m)
|
||||
{
|
||||
AVRMEM_ALIAS * n;
|
||||
AVRMEM_ALIAS *avr_dup_memalias(const AVRMEM_ALIAS *m) {
|
||||
AVRMEM_ALIAS *n = avr_new_memalias();
|
||||
|
||||
n = avr_new_memalias();
|
||||
|
||||
*n = *m;
|
||||
if(m)
|
||||
*n = *m;
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
void avr_free_mem(AVRMEM * m)
|
||||
{
|
||||
if (m->buf != NULL) {
|
||||
free(m->buf);
|
||||
m->buf = NULL;
|
||||
}
|
||||
if (m->tags != NULL) {
|
||||
free(m->tags);
|
||||
m->tags = NULL;
|
||||
}
|
||||
for(size_t i=0; i<sizeof(m->op)/sizeof(m->op[0]); i++)
|
||||
{
|
||||
if (m->op[i] != NULL)
|
||||
{
|
||||
avr_free_opcode(m->op[i]);
|
||||
m->op[i] = NULL;
|
||||
}
|
||||
}
|
||||
free(m);
|
||||
}
|
||||
void avr_free_mem(AVRMEM * m) {
|
||||
if(m == NULL)
|
||||
return;
|
||||
|
||||
void avr_free_memalias(AVRMEM_ALIAS * m)
|
||||
{
|
||||
if(m->buf) {
|
||||
free(m->buf);
|
||||
m->buf = NULL;
|
||||
}
|
||||
if(m->tags) {
|
||||
free(m->tags);
|
||||
m->tags = NULL;
|
||||
}
|
||||
for(size_t i=0; i<sizeof(m->op)/sizeof(m->op[0]); i++) {
|
||||
if(m->op[i]) {
|
||||
avr_free_opcode(m->op[i]);
|
||||
m->op[i] = NULL;
|
||||
}
|
||||
}
|
||||
free(m);
|
||||
}
|
||||
|
||||
AVRMEM_ALIAS * avr_locate_memalias(AVRPART * p, const char * desc)
|
||||
{
|
||||
void avr_free_memalias(AVRMEM_ALIAS *m) {
|
||||
if(m)
|
||||
free(m);
|
||||
}
|
||||
|
||||
AVRMEM_ALIAS *avr_locate_memalias(const AVRPART *p, const char *desc) {
|
||||
AVRMEM_ALIAS * m, * match;
|
||||
LNODEID ln;
|
||||
int matches;
|
||||
int matches, exact;
|
||||
int l;
|
||||
|
||||
if(!p || !desc || !p->mem_alias)
|
||||
return NULL;
|
||||
|
||||
l = strlen(desc);
|
||||
matches = 0;
|
||||
matches = exact = 0;
|
||||
match = NULL;
|
||||
for (ln=lfirst(p->mem_alias); ln; ln=lnext(ln)) {
|
||||
m = ldata(ln);
|
||||
if (strncmp(desc, m->desc, l) == 0) {
|
||||
if (strncmp(m->desc, desc, l) == 0) { // Partial initial match
|
||||
match = m;
|
||||
matches++;
|
||||
if(m->desc[l] == 0) // Exact match between arg and memory
|
||||
exact++;
|
||||
}
|
||||
}
|
||||
|
||||
if (matches == 1)
|
||||
return match;
|
||||
|
||||
return NULL;
|
||||
return exact == 1 || matches == 1? match: NULL;
|
||||
}
|
||||
|
||||
AVRMEM * avr_locate_mem_noalias(AVRPART * p, const char * desc)
|
||||
{
|
||||
AVRMEM *avr_locate_mem_noalias(const AVRPART *p, const char *desc) {
|
||||
AVRMEM * m, * match;
|
||||
LNODEID ln;
|
||||
int matches;
|
||||
int matches, exact;
|
||||
int l;
|
||||
|
||||
if(!p || !desc || !p->mem)
|
||||
return NULL;
|
||||
|
||||
l = strlen(desc);
|
||||
matches = 0;
|
||||
matches = exact = 0;
|
||||
match = NULL;
|
||||
for (ln=lfirst(p->mem); ln; ln=lnext(ln)) {
|
||||
m = ldata(ln);
|
||||
if (strncmp(desc, m->desc, l) == 0) {
|
||||
if (strncmp(m->desc, desc, l) == 0) { // Partial initial match
|
||||
match = m;
|
||||
matches++;
|
||||
if(m->desc[l] == 0) // Exact match between arg and memory
|
||||
exact++;
|
||||
}
|
||||
}
|
||||
|
||||
if (matches == 1)
|
||||
return match;
|
||||
|
||||
return NULL;
|
||||
return exact == 1 || matches == 1? match: NULL;
|
||||
}
|
||||
|
||||
|
||||
AVRMEM * avr_locate_mem(AVRPART * p, const char * desc)
|
||||
{
|
||||
AVRMEM * m, * match;
|
||||
AVRMEM_ALIAS * alias;
|
||||
LNODEID ln;
|
||||
int matches;
|
||||
int l;
|
||||
AVRMEM *avr_locate_mem(const AVRPART *p, const char *desc) {
|
||||
AVRMEM *m = avr_locate_mem_noalias(p, desc);
|
||||
|
||||
if(!p || !desc)
|
||||
return NULL;
|
||||
if(m)
|
||||
return m;
|
||||
|
||||
l = strlen(desc);
|
||||
matches = 0;
|
||||
match = NULL;
|
||||
if(p->mem) {
|
||||
for (ln=lfirst(p->mem); ln; ln=lnext(ln)) {
|
||||
m = ldata(ln);
|
||||
if (strncmp(desc, m->desc, l) == 0) {
|
||||
match = m;
|
||||
matches++;
|
||||
}
|
||||
// Not yet found: look for matching alias name
|
||||
AVRMEM_ALIAS *a = avr_locate_memalias(p, desc);
|
||||
return a? a->aliased_mem: NULL;
|
||||
}
|
||||
|
||||
AVRMEM_ALIAS *avr_find_memalias(const AVRPART *p, const AVRMEM *m_orig) {
|
||||
if(p && p->mem_alias && m_orig)
|
||||
for(LNODEID ln=lfirst(p->mem_alias); ln; ln=lnext(ln)) {
|
||||
AVRMEM_ALIAS *m = ldata(ln);
|
||||
if(m->aliased_mem == m_orig)
|
||||
return m;
|
||||
}
|
||||
}
|
||||
|
||||
if (matches == 1)
|
||||
return match;
|
||||
|
||||
/* not yet found: look for matching alias name */
|
||||
alias = avr_locate_memalias(p, desc);
|
||||
if (alias != NULL)
|
||||
return alias->aliased_mem;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
AVRMEM_ALIAS * avr_find_memalias(AVRPART * p, AVRMEM * m_orig)
|
||||
{
|
||||
AVRMEM_ALIAS * m;
|
||||
LNODEID ln;
|
||||
|
||||
for (ln=lfirst(p->mem_alias); ln; ln=lnext(ln)) {
|
||||
m = ldata(ln);
|
||||
if (m->aliased_mem == m_orig)
|
||||
return m;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
void avr_mem_display(const char * prefix, FILE * f, AVRMEM * m, AVRPART * p,
|
||||
int type, int verbose)
|
||||
{
|
||||
void avr_mem_display(const char *prefix, FILE *f, const AVRMEM *m,
|
||||
const AVRPART *p, int verbose) {
|
||||
static unsigned int prev_mem_offset;
|
||||
static int prev_mem_size;
|
||||
int i, j;
|
||||
|
@ -623,7 +524,7 @@ void avr_mem_display(const char * prefix, FILE * f, AVRMEM * m, AVRPART * p,
|
|||
AVRMEM_ALIAS *ap = avr_find_memalias(p, m);
|
||||
/* Show alias if the current and the next memory section has the same offset
|
||||
and size, we're not out of band and a family_id is present */
|
||||
char * mem_desc_alias = ap? ap->desc: "";
|
||||
const char *mem_desc_alias = ap? ap->desc: "";
|
||||
fprintf(f,
|
||||
"%s%-11s %-8s %4d %5d %5d %4d %-6s %6d %4d %6d %5d %5d 0x%02x 0x%02x\n",
|
||||
prefix,
|
||||
|
@ -669,73 +570,63 @@ void avr_mem_display(const char * prefix, FILE * f, AVRMEM * m, AVRPART * p,
|
|||
* Elementary functions dealing with AVRPART structures
|
||||
*/
|
||||
|
||||
AVRPART * avr_new_part(void)
|
||||
{
|
||||
AVRPART * p;
|
||||
|
||||
p = (AVRPART *)malloc(sizeof(AVRPART));
|
||||
if (p == NULL) {
|
||||
avrdude_message(MSG_INFO, "new_part(): out of memory\n");
|
||||
exit(1);
|
||||
}
|
||||
AVRPART *avr_new_part(void) {
|
||||
AVRPART *p = (AVRPART *) cfg_malloc("avr_new_part()", sizeof(AVRPART));
|
||||
const char *nulp = cache_string("");
|
||||
|
||||
memset(p, 0, sizeof(*p));
|
||||
|
||||
p->id[0] = 0;
|
||||
p->desc[0] = 0;
|
||||
// Initialise const char * and LISTID entities
|
||||
p->desc = nulp;
|
||||
p->id = nulp;
|
||||
p->parent_id = nulp;
|
||||
p->family_id = nulp;
|
||||
p->config_file = nulp;
|
||||
p->mem = lcreat(NULL, 0);
|
||||
p->mem_alias = lcreat(NULL, 0);
|
||||
|
||||
// Default values
|
||||
p->hvupdi_variant = -1;
|
||||
memset(p->signature, 0xFF, 3);
|
||||
p->reset_disposition = RESET_DEDICATED;
|
||||
p->retry_pulse = PIN_AVR_SCK;
|
||||
p->flags = AVRPART_SERIALOK | AVRPART_PARALLELOK | AVRPART_ENABLEPAGEPROGRAMMING;
|
||||
p->parent_id = NULL;
|
||||
p->config_file = NULL;
|
||||
p->lineno = 0;
|
||||
memset(p->signature, 0xFF, 3);
|
||||
p->ctl_stack_type = CTL_STACK_NONE;
|
||||
p->ocdrev = -1;
|
||||
p->hvupdi_variant = -1;
|
||||
|
||||
p->mem = lcreat(NULL, 0);
|
||||
p->mem_alias = lcreat(NULL, 0);
|
||||
p->lineno = 0;
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
|
||||
AVRPART * avr_dup_part(AVRPART * d)
|
||||
{
|
||||
AVRPART * p;
|
||||
LISTID save, save2;
|
||||
LNODEID ln, ln2;
|
||||
int i;
|
||||
AVRPART *avr_dup_part(const AVRPART *d) {
|
||||
AVRPART *p = avr_new_part();
|
||||
|
||||
p = avr_new_part();
|
||||
save = p->mem;
|
||||
save2 = p->mem_alias;
|
||||
if(d) {
|
||||
*p = *d;
|
||||
|
||||
*p = *d;
|
||||
// Duplicate the memory and alias chains
|
||||
p->mem = lcreat(NULL, 0);
|
||||
p->mem_alias = lcreat(NULL, 0);
|
||||
|
||||
p->mem = save;
|
||||
p->mem_alias = save2;
|
||||
for (ln=lfirst(d->mem); ln; ln=lnext(ln)) {
|
||||
AVRMEM *m = ldata(ln);
|
||||
AVRMEM *m2 = avr_dup_mem(m);
|
||||
ladd(p->mem, m2);
|
||||
// see if there is any alias for it
|
||||
for (ln2=lfirst(d->mem_alias); ln2; ln2=lnext(ln2)) {
|
||||
AVRMEM_ALIAS *a = ldata(ln2);
|
||||
if (a->aliased_mem == m) {
|
||||
// yes, duplicate it
|
||||
AVRMEM_ALIAS *a2 = avr_dup_memalias(a);
|
||||
// ... adjust the pointer ...
|
||||
a2->aliased_mem = m2;
|
||||
// ... and add to new list
|
||||
ladd(p->mem_alias, a2);
|
||||
for(LNODEID ln=lfirst(d->mem); ln; ln=lnext(ln)) {
|
||||
AVRMEM *m = ldata(ln);
|
||||
AVRMEM *m2 = avr_dup_mem(m);
|
||||
ladd(p->mem, m2);
|
||||
// See if there is any alias for it
|
||||
for(LNODEID ln2=lfirst(d->mem_alias); ln2; ln2=lnext(ln2)) {
|
||||
AVRMEM_ALIAS *a = ldata(ln2);
|
||||
if (a->aliased_mem == m) {
|
||||
// Yes, duplicate it, adjust the pointer and add to new list
|
||||
AVRMEM_ALIAS *a2 = avr_dup_memalias(a);
|
||||
a2->aliased_mem = m2;
|
||||
ladd(p->mem_alias, a2);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < AVR_OP_MAX; i++) {
|
||||
p->op[i] = avr_dup_opcode(p->op[i]);
|
||||
for(int i = 0; i < AVR_OP_MAX; i++)
|
||||
p->op[i] = avr_dup_opcode(p->op[i]);
|
||||
}
|
||||
|
||||
return p;
|
||||
|
@ -757,61 +648,45 @@ void avr_free_part(AVRPART * d)
|
|||
free(d);
|
||||
}
|
||||
|
||||
AVRPART * locate_part(LISTID parts, const char * partdesc)
|
||||
{
|
||||
LNODEID ln1;
|
||||
AVRPART *locate_part(const LISTID parts, const char *partdesc) {
|
||||
AVRPART * p = NULL;
|
||||
int found;
|
||||
int found = 0;
|
||||
|
||||
if(!parts || !partdesc)
|
||||
return NULL;
|
||||
|
||||
found = 0;
|
||||
|
||||
for (ln1=lfirst(parts); ln1 && !found; ln1=lnext(ln1)) {
|
||||
for (LNODEID ln1=lfirst(parts); ln1 && !found; ln1=lnext(ln1)) {
|
||||
p = ldata(ln1);
|
||||
if ((strcasecmp(partdesc, p->id) == 0) ||
|
||||
(strcasecmp(partdesc, p->desc) == 0))
|
||||
found = 1;
|
||||
}
|
||||
|
||||
if (found)
|
||||
return p;
|
||||
|
||||
return NULL;
|
||||
return found? p: NULL;
|
||||
}
|
||||
|
||||
AVRPART * locate_part_by_avr910_devcode(LISTID parts, int devcode)
|
||||
{
|
||||
LNODEID ln1;
|
||||
AVRPART * p = NULL;
|
||||
|
||||
for (ln1=lfirst(parts); ln1; ln1=lnext(ln1)) {
|
||||
p = ldata(ln1);
|
||||
if (p->avr910_devcode == devcode)
|
||||
return p;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
AVRPART * locate_part_by_signature(LISTID parts, unsigned char * sig,
|
||||
int sigsize)
|
||||
{
|
||||
LNODEID ln1;
|
||||
AVRPART * p = NULL;
|
||||
int i;
|
||||
|
||||
if (sigsize == 3) {
|
||||
for (ln1=lfirst(parts); ln1; ln1=lnext(ln1)) {
|
||||
p = ldata(ln1);
|
||||
for (i=0; i<3; i++)
|
||||
if (p->signature[i] != sig[i])
|
||||
break;
|
||||
if (i == 3)
|
||||
AVRPART *locate_part_by_avr910_devcode(const LISTID parts, int devcode) {
|
||||
if(parts)
|
||||
for (LNODEID ln1=lfirst(parts); ln1; ln1=lnext(ln1)) {
|
||||
AVRPART * p = ldata(ln1);
|
||||
if (p->avr910_devcode == devcode)
|
||||
return p;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
AVRPART *locate_part_by_signature(const LISTID parts, unsigned char *sig, int sigsize) {
|
||||
if(parts && sigsize == 3)
|
||||
for(LNODEID ln1=lfirst(parts); ln1; ln1=lnext(ln1)) {
|
||||
AVRPART *p = ldata(ln1);
|
||||
int i;
|
||||
for(i=0; i<3; i++)
|
||||
if(p->signature[i] != sig[i])
|
||||
break;
|
||||
if(i == 3)
|
||||
return p;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
@ -840,12 +715,11 @@ void walk_avrparts(LISTID avrparts, walk_avrparts_cb cb, void *cookie)
|
|||
/*
|
||||
* Compare function to sort the list of programmers
|
||||
*/
|
||||
static int sort_avrparts_compare(AVRPART * p1,AVRPART * p2)
|
||||
{
|
||||
if(p1 == NULL || p2 == NULL) {
|
||||
static int sort_avrparts_compare(const AVRPART *p1, const AVRPART *p2) {
|
||||
if(p1 == NULL || p1->desc == NULL || p2 == NULL || p2->desc == NULL)
|
||||
return 0;
|
||||
}
|
||||
return strncasecmp(p1->desc,p2->desc,AVR_DESCLEN);
|
||||
|
||||
return strcasecmp(p1->desc, p2->desc);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -867,9 +741,7 @@ static char * reset_disp_str(int r)
|
|||
}
|
||||
|
||||
|
||||
void avr_display(FILE * f, AVRPART * p, const char * prefix, int verbose)
|
||||
{
|
||||
int i;
|
||||
void avr_display(FILE *f, const AVRPART *p, const char *prefix, int verbose) {
|
||||
char * buf;
|
||||
const char * px;
|
||||
LNODEID ln;
|
||||
|
@ -904,23 +776,17 @@ void avr_display(FILE * f, AVRPART * p, const char * prefix, int verbose)
|
|||
fprintf( f, "%sMemory Detail :\n\n", prefix);
|
||||
|
||||
px = prefix;
|
||||
i = strlen(prefix) + 5;
|
||||
buf = (char *)malloc(i);
|
||||
if (buf == NULL) {
|
||||
/* ugh, this is not important enough to bail, just ignore it */
|
||||
}
|
||||
else {
|
||||
strcpy(buf, prefix);
|
||||
strcat(buf, " ");
|
||||
px = buf;
|
||||
}
|
||||
buf = (char *)cfg_malloc("avr_display()", strlen(prefix) + 5);
|
||||
strcpy(buf, prefix);
|
||||
strcat(buf, " ");
|
||||
px = buf;
|
||||
|
||||
if (verbose <= 2)
|
||||
avr_mem_display(px, f, NULL, p, verbose);
|
||||
|
||||
if (verbose <= 2) {
|
||||
avr_mem_display(px, f, NULL, p, 0, verbose);
|
||||
}
|
||||
for (ln=lfirst(p->mem); ln; ln=lnext(ln)) {
|
||||
m = ldata(ln);
|
||||
avr_mem_display(px, f, m, p, i, verbose);
|
||||
avr_mem_display(px, f, m, p, verbose);
|
||||
}
|
||||
|
||||
if (buf)
|
||||
|
@ -955,7 +821,7 @@ char *cmdbitstr(CMDBIT cb) {
|
|||
else
|
||||
space[1] = 0;
|
||||
|
||||
return strdup(space);
|
||||
return cfg_strdup("cmdbitstr()", space);
|
||||
}
|
||||
|
||||
|
||||
|
@ -997,7 +863,7 @@ char *opcode2str(OPCODE *op, int opnum, int detailed) {
|
|||
int compact = 1;
|
||||
|
||||
if(!op)
|
||||
return strdup("NULL");
|
||||
return cfg_strdup("opcode2str()", "NULL");
|
||||
|
||||
// Can the opcode be printed in a compact way? Only if address bits are systematic.
|
||||
for(int i=31; i >= 0; i--)
|
||||
|
@ -1032,7 +898,7 @@ char *opcode2str(OPCODE *op, int opnum, int detailed) {
|
|||
*sp++ = '"';
|
||||
*sp = 0;
|
||||
|
||||
return strdup(space);
|
||||
return cfg_strdup("opcode2str()", space);
|
||||
}
|
||||
|
||||
|
||||
|
|
496
src/config.c
496
src/config.c
|
@ -25,6 +25,7 @@
|
|||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "avrdude.h"
|
||||
#include "libavrdude.h"
|
||||
|
@ -32,15 +33,12 @@
|
|||
|
||||
#include "config_gram.h"
|
||||
|
||||
char default_programmer[MAX_STR_CONST];
|
||||
char default_parallel[PATH_MAX];
|
||||
char default_serial[PATH_MAX];
|
||||
char default_spi[PATH_MAX];
|
||||
const char *default_programmer;
|
||||
const char *default_parallel;
|
||||
const char *default_serial;
|
||||
const char *default_spi;
|
||||
double default_bitclock;
|
||||
|
||||
char string_buf[MAX_STR_CONST];
|
||||
char *string_buf_ptr;
|
||||
|
||||
LISTID string_list;
|
||||
LISTID number_list;
|
||||
PROGRAMMER * current_prog;
|
||||
|
@ -82,6 +80,36 @@ int init_config(void)
|
|||
return 0;
|
||||
}
|
||||
|
||||
void *cfg_malloc(const char *funcname, size_t n) {
|
||||
void *ret = malloc(n);
|
||||
if(!ret) {
|
||||
avrdude_message(MSG_INFO, "%s: out of memory in %s (needed %lu bytes)\n", progname, funcname, (unsigned long) n);
|
||||
exit(1);
|
||||
}
|
||||
memset(ret, 0, n);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void *cfg_realloc(const char *funcname, void *p, size_t n) {
|
||||
void *ret;
|
||||
|
||||
if(!(ret = p? realloc(p, n): calloc(1, n))) {
|
||||
avrdude_message(MSG_INFO, "%s: out of memory in %s (needed %lu bytes)\n", progname, funcname, (unsigned long) n);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
char *cfg_strdup(const char *funcname, const char *s) {
|
||||
char *ret = strdup(s);
|
||||
if(!ret) {
|
||||
avrdude_message(MSG_INFO, "%s: out of memory in %s\n", progname, funcname);
|
||||
exit(1);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int yywrap()
|
||||
|
@ -124,20 +152,9 @@ int yywarning(char * errmsg, ...)
|
|||
}
|
||||
|
||||
|
||||
TOKEN * new_token(int primary)
|
||||
{
|
||||
TOKEN * tkn;
|
||||
|
||||
tkn = (TOKEN *)malloc(sizeof(TOKEN));
|
||||
if (tkn == NULL) {
|
||||
yyerror("new_token(): out of memory");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memset(tkn, 0, sizeof(TOKEN));
|
||||
|
||||
TOKEN * new_token(int primary) {
|
||||
TOKEN * tkn = (TOKEN *) cfg_malloc("new_token()", sizeof(TOKEN));
|
||||
tkn->primary = primary;
|
||||
|
||||
return tkn;
|
||||
}
|
||||
|
||||
|
@ -173,14 +190,8 @@ void free_tokens(int n, ...)
|
|||
|
||||
|
||||
|
||||
TOKEN * number(char * text)
|
||||
{
|
||||
struct token_t * tkn;
|
||||
|
||||
tkn = new_token(TKN_NUMBER);
|
||||
if (tkn == NULL) {
|
||||
return NULL; /* yyerror already called */
|
||||
}
|
||||
TOKEN *number(const char *text) {
|
||||
struct token_t *tkn = new_token(TKN_NUMBER);
|
||||
tkn->value.type = V_NUM;
|
||||
tkn->value.number = atoi(text);
|
||||
|
||||
|
@ -191,11 +202,8 @@ TOKEN * number(char * text)
|
|||
return tkn;
|
||||
}
|
||||
|
||||
TOKEN * number_real(char * text)
|
||||
{
|
||||
struct token_t * tkn;
|
||||
|
||||
tkn = new_token(TKN_NUMBER);
|
||||
TOKEN *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);
|
||||
|
||||
|
@ -206,15 +214,10 @@ TOKEN * number_real(char * text)
|
|||
return tkn;
|
||||
}
|
||||
|
||||
TOKEN * hexnumber(char * text)
|
||||
{
|
||||
struct token_t * tkn;
|
||||
TOKEN *hexnumber(const char *text) {
|
||||
struct token_t *tkn = new_token(TKN_NUMBER);
|
||||
char * e;
|
||||
|
||||
tkn = new_token(TKN_NUMBER);
|
||||
if (tkn == NULL) {
|
||||
return NULL; /* yyerror already called */
|
||||
}
|
||||
tkn->value.type = V_NUM;
|
||||
tkn->value.number = strtoul(text, &e, 16);
|
||||
if ((e == text) || (*e != 0)) {
|
||||
|
@ -231,26 +234,10 @@ TOKEN * hexnumber(char * text)
|
|||
}
|
||||
|
||||
|
||||
TOKEN * string(char * text)
|
||||
{
|
||||
struct token_t * tkn;
|
||||
int len;
|
||||
|
||||
tkn = new_token(TKN_STRING);
|
||||
if (tkn == NULL) {
|
||||
return NULL; /* yyerror already called */
|
||||
}
|
||||
|
||||
len = strlen(text);
|
||||
|
||||
TOKEN *string(const char *text) {
|
||||
struct token_t *tkn = new_token(TKN_STRING);
|
||||
tkn->value.type = V_STR;
|
||||
tkn->value.string = (char *) malloc(len+1);
|
||||
if (tkn->value.string == NULL) {
|
||||
yyerror("string(): out of memory");
|
||||
free_token(tkn);
|
||||
return NULL;
|
||||
}
|
||||
strcpy(tkn->value.string, text);
|
||||
tkn->value.string = cfg_strdup("string()", text);
|
||||
|
||||
#if DEBUG
|
||||
avrdude_message(MSG_INFO, "STRING(%s)\n", tkn->value.string);
|
||||
|
@ -260,13 +247,8 @@ TOKEN * string(char * text)
|
|||
}
|
||||
|
||||
|
||||
TOKEN * keyword(int primary)
|
||||
{
|
||||
struct token_t * tkn;
|
||||
|
||||
tkn = new_token(primary);
|
||||
|
||||
return tkn;
|
||||
TOKEN * keyword(int primary) {
|
||||
return new_token(primary);
|
||||
}
|
||||
|
||||
|
||||
|
@ -306,19 +288,6 @@ void pyytext(void)
|
|||
}
|
||||
|
||||
|
||||
char * dup_string(const char * str)
|
||||
{
|
||||
char * s;
|
||||
|
||||
s = strdup(str);
|
||||
if (s == NULL) {
|
||||
yyerror("dup_string(): out of memory");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
#ifdef HAVE_YYLEX_DESTROY
|
||||
/* reset lexer and free any allocated memory */
|
||||
extern int yylex_destroy(void);
|
||||
|
@ -365,32 +334,361 @@ int read_config(const char * file)
|
|||
}
|
||||
|
||||
|
||||
// Linear-search cache for a few often-referenced strings
|
||||
char *cache_string(const char *file) {
|
||||
static char **fnames;
|
||||
static int n=0;
|
||||
// Adapted version of a neat empirical hash function from comp.lang.c by Daniel Bernstein
|
||||
unsigned strhash(const char *str) {
|
||||
unsigned c, hash = 5381, n = 0;
|
||||
|
||||
if(!file)
|
||||
return NULL;
|
||||
while((c = (unsigned char) *str++) && n++ < 20)
|
||||
hash = 33*hash ^ c;
|
||||
|
||||
// Exists in cache?
|
||||
for(int i=0; i<n; i++)
|
||||
if(strcmp(fnames[i], file) == 0)
|
||||
return fnames[i];
|
||||
return hash;
|
||||
}
|
||||
|
||||
// Expand cache?
|
||||
if(n%128 == 0) {
|
||||
if(!(fnames = realloc(fnames, (n+128)*sizeof*fnames))) {
|
||||
yyerror("cache_string(): out of memory");
|
||||
return NULL;
|
||||
|
||||
static char **hstrings[1<<12];
|
||||
|
||||
// Return a copy of the argument as hashed string
|
||||
const char *cache_string(const char *p) {
|
||||
int h, k;
|
||||
char **hs;
|
||||
|
||||
if(!p)
|
||||
p = "(NULL)";
|
||||
|
||||
h = strhash(p) % (sizeof hstrings/sizeof*hstrings);
|
||||
if(!(hs=hstrings[h]))
|
||||
hs = hstrings[h] = (char **) cfg_realloc("cache_string()", NULL, (16+1)*sizeof**hstrings);
|
||||
|
||||
for(k=0; hs[k]; k++)
|
||||
if(*p == *hs[k] && !strcmp(p, hs[k]))
|
||||
return hs[k];
|
||||
|
||||
if(k && k%16 == 0)
|
||||
hstrings[h] = (char **) cfg_realloc("cache_string()", hstrings[h], (k+16+1)*sizeof**hstrings);
|
||||
|
||||
hstrings[h][k+1]=NULL;
|
||||
|
||||
return hstrings[h][k] = cfg_strdup("cache_string()", p);
|
||||
}
|
||||
|
||||
|
||||
static LISTID cfg_comms; // A chain of comment lines
|
||||
static LISTID cfg_prologue; // Comment lines at start of avrdude.conf
|
||||
static char *lkw; // Last seen keyword
|
||||
static int lkw_lineno; // Line number of that
|
||||
|
||||
static LISTID cfg_strctcomms; // Passed on to config_gram.y
|
||||
static LISTID cfg_pushedcomms; // Temporarily pushed main comments
|
||||
static int cfg_pushed; // ... for memory sections
|
||||
|
||||
COMMENT *locate_comment(const LISTID comments, const char *where, int rhs) {
|
||||
if(comments)
|
||||
for(LNODEID ln=lfirst(comments); ln; ln=lnext(ln)) {
|
||||
COMMENT *n = ldata(ln);
|
||||
if(n && rhs == n->rhs && n->kw && strcmp(where, n->kw) == 0)
|
||||
return n;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void addcomment(int rhs) {
|
||||
if(lkw) {
|
||||
COMMENT *node = cfg_malloc("addcomment()", sizeof(*node));
|
||||
node->rhs = rhs;
|
||||
node->kw = cfg_strdup("addcomment()", lkw);
|
||||
node->comms = cfg_comms;
|
||||
cfg_comms = NULL;
|
||||
if(!cfg_strctcomms)
|
||||
cfg_strctcomms = lcreat(NULL, 0);
|
||||
ladd(cfg_strctcomms, node);
|
||||
}
|
||||
}
|
||||
|
||||
// Capture prologue during parsing (triggered by lexer.l)
|
||||
void cfg_capture_prologue(void) {
|
||||
cfg_prologue = cfg_comms;
|
||||
cfg_comms = NULL;
|
||||
}
|
||||
|
||||
LISTID cfg_get_prologue(void) {
|
||||
return cfg_prologue;
|
||||
}
|
||||
|
||||
// Captures comments during parsing
|
||||
void capture_comment_str(const char *com, int lineno) {
|
||||
if(!cfg_comms)
|
||||
cfg_comms = lcreat(NULL, 0);
|
||||
ladd(cfg_comms, cfg_strdup("capture_comment_str()", com));
|
||||
|
||||
// Last keyword lineno is the same as this comment's
|
||||
if(lkw && lkw_lineno == lineno)
|
||||
addcomment(1); // Register comms to show right of lkw = ...;
|
||||
}
|
||||
|
||||
// Capture assignments (keywords left of =) and associate comments to them
|
||||
void capture_lvalue_kw(const char *kw, int lineno) {
|
||||
if(!strcmp(kw, "memory")) { // Push part comments and start memory comments
|
||||
if(!cfg_pushed) { // config_gram.y pops the part comments
|
||||
cfg_pushed = 1;
|
||||
cfg_pushedcomms = cfg_strctcomms;
|
||||
cfg_strctcomms = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
fnames[n] = strdup(file);
|
||||
if(!fnames[n]) {
|
||||
yyerror("cache_string(): out of memory");
|
||||
return NULL;
|
||||
if(!strcmp(kw, "programmer") || !strcmp(kw, "part") || !strcmp(kw, "memory"))
|
||||
kw = "*"; // Show comment before programmer/part/memory
|
||||
|
||||
if(lkw)
|
||||
free(lkw);
|
||||
lkw = cfg_strdup("capture_lvalue_kw()", kw);
|
||||
lkw_lineno = lineno;
|
||||
if(cfg_comms) // Accrued list of # one-line comments
|
||||
addcomment(0); // Register comment to appear before lkw assignment
|
||||
}
|
||||
|
||||
// config_gram.y calls this once for each programmer/part/memory structure
|
||||
LISTID cfg_move_comments(void) {
|
||||
capture_lvalue_kw(";", -1);
|
||||
|
||||
LISTID ret = cfg_strctcomms;
|
||||
cfg_strctcomms = NULL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
// config_gram.y calls this after ingressing the memory structure
|
||||
void cfg_pop_comms(void) {
|
||||
if(cfg_pushed) {
|
||||
cfg_pushed = 0;
|
||||
cfg_strctcomms = cfg_pushedcomms;
|
||||
}
|
||||
}
|
||||
|
||||
// Convert the next n hex digits of s to a hex number
|
||||
static unsigned int tohex(const unsigned char *s, unsigned int n) {
|
||||
int ret, c;
|
||||
|
||||
ret = 0;
|
||||
while(n--) {
|
||||
ret *= 16;
|
||||
c = *s++;
|
||||
ret += c >= '0' && c <= '9'? c - '0': c >= 'a' && c <= 'f'? c - 'a' + 10: c - 'A' + 10;
|
||||
}
|
||||
|
||||
return fnames[n++];
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Create a utf-8 character sequence from a single unicode character.
|
||||
* Permissive for some invalid unicode sequences but not for those with
|
||||
* high bit set). Returns numbers of characters written (0-6).
|
||||
*/
|
||||
static int wc_to_utf8str(unsigned int wc, unsigned char *str) {
|
||||
if(!(wc & ~0x7fu)) {
|
||||
*str = (char) wc;
|
||||
return 1;
|
||||
}
|
||||
if(!(wc & ~0x7ffu)) {
|
||||
*str++ = (char) ((wc >> 6) | 0xc0);
|
||||
*str++ = (char) ((wc & 0x3f) | 0x80);
|
||||
return 2;
|
||||
}
|
||||
if(!(wc & ~0xffffu)) {
|
||||
*str++ = (char) ((wc >> 12) | 0xe0);
|
||||
*str++ = (char) (((wc >> 6) & 0x3f) | 0x80);
|
||||
*str++ = (char) ((wc & 0x3f) | 0x80);
|
||||
return 3;
|
||||
}
|
||||
if(!(wc & ~0x1fffffu)) {
|
||||
*str++ = (char) ((wc >> 18) | 0xf0);
|
||||
*str++ = (char) (((wc >> 12) & 0x3f) | 0x80);
|
||||
*str++ = (char) (((wc >> 6) & 0x3f) | 0x80);
|
||||
*str++ = (char) ((wc & 0x3f) | 0x80);
|
||||
return 4;
|
||||
}
|
||||
if(!(wc & ~0x3ffffffu)) {
|
||||
*str++ = (char) ((wc >> 24) | 0xf8);
|
||||
*str++ = (char) (((wc >> 18) & 0x3f) | 0x80);
|
||||
*str++ = (char) (((wc >> 12) & 0x3f) | 0x80);
|
||||
*str++ = (char) (((wc >> 6) & 0x3f) | 0x80);
|
||||
*str++ = (char) ((wc & 0x3f) | 0x80);
|
||||
return 5;
|
||||
}
|
||||
if(!(wc & ~0x7fffffffu)) {
|
||||
*str++ = (char) ((wc >> 30) | 0xfc);
|
||||
*str++ = (char) (((wc >> 24) & 0x3f) | 0x80);
|
||||
*str++ = (char) (((wc >> 18) & 0x3f) | 0x80);
|
||||
*str++ = (char) (((wc >> 12) & 0x3f) | 0x80);
|
||||
*str++ = (char) (((wc >> 6) & 0x3f) | 0x80);
|
||||
*str++ = (char) ((wc & 0x3f) | 0x80);
|
||||
return 6;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Unescape C-style strings, destination d must hold enough space (and can be source s)
|
||||
unsigned char *cfg_unescapeu(unsigned char *d, const unsigned char *s) {
|
||||
unsigned char *ret = d;
|
||||
int n, k;
|
||||
|
||||
while(*s) {
|
||||
switch (*s) {
|
||||
case '\\':
|
||||
switch (*++s) {
|
||||
case '\n': // String continuation over new line
|
||||
#if '\n' != '\r'
|
||||
case '\r':
|
||||
#endif
|
||||
--d;
|
||||
break;
|
||||
case 'n':
|
||||
*d = '\n';
|
||||
break;
|
||||
case 't':
|
||||
*d = '\t';
|
||||
break;
|
||||
case 'a':
|
||||
*d = '\a';
|
||||
break;
|
||||
case 'b':
|
||||
*d = '\b';
|
||||
break;
|
||||
case 'e': // Non-standard ESC
|
||||
*d = 27;
|
||||
break;
|
||||
case 'f':
|
||||
*d = '\f';
|
||||
break;
|
||||
case 'r':
|
||||
*d = '\r';
|
||||
break;
|
||||
case 'v':
|
||||
*d = '\v';
|
||||
break;
|
||||
case '?':
|
||||
*d = '?';
|
||||
break;
|
||||
case '`':
|
||||
*d = '`';
|
||||
break;
|
||||
case '"':
|
||||
*d = '"';
|
||||
break;
|
||||
case '\'':
|
||||
*d = '\'';
|
||||
break;
|
||||
case '\\':
|
||||
*d = '\\';
|
||||
break;
|
||||
case '0':
|
||||
case '1':
|
||||
case '2':
|
||||
case '3':
|
||||
case '4':
|
||||
case '5':
|
||||
case '6':
|
||||
case '7': // 1-3 octal digits
|
||||
n = *s - '0';
|
||||
for(k = 0; k < 2 && s[1] >= '0' && s[1] <= '7'; k++) // Max 2 more octal characters
|
||||
n *= 8, n += s[1] - '0', s++;
|
||||
*d = n;
|
||||
break;
|
||||
case 'x': // Unlimited hex digits
|
||||
for(k = 0; isxdigit(s[k + 1]); k++)
|
||||
continue;
|
||||
if(k > 0) {
|
||||
*d = tohex(s + 1, k);
|
||||
s += k;
|
||||
} else { // No hex digits after \x? copy \x
|
||||
*d++ = '\\';
|
||||
*d = 'x';
|
||||
}
|
||||
break;
|
||||
case 'u': // Exactly 4 hex digits and valid unicode
|
||||
if(isxdigit(s[1]) && isxdigit(s[2]) && isxdigit(s[3]) && isxdigit(s[4]) &&
|
||||
(n = wc_to_utf8str(tohex(s+1, 4), d))) {
|
||||
d += n - 1;
|
||||
s += 4;
|
||||
} else { // Invalid \u sequence? copy \u
|
||||
*d++ = '\\';
|
||||
*d = 'u';
|
||||
}
|
||||
break;
|
||||
case 'U': // Exactly 6 hex digits and valid unicode
|
||||
if(isxdigit(s[1]) && isxdigit(s[2]) && isxdigit(s[3]) && isxdigit(s[4]) && isxdigit(s[5]) && isxdigit(s[6]) &&
|
||||
(n = wc_to_utf8str(tohex(s+1, 6), d))) {
|
||||
d += n - 1;
|
||||
s += 6;
|
||||
} else { // Invalid \U sequence? copy \U
|
||||
*d++ = '\\';
|
||||
*d = 'U';
|
||||
}
|
||||
break;
|
||||
default: // Keep the escape sequence (C would warn and remove \)
|
||||
*d++ = '\\';
|
||||
*d = *s;
|
||||
}
|
||||
break;
|
||||
|
||||
default: // Not an escape sequence: just copy the character
|
||||
*d = *s;
|
||||
}
|
||||
d++;
|
||||
s++;
|
||||
}
|
||||
*d = *s; // Terminate
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Unescape C-style strings, destination d must hold enough space (and can be source s)
|
||||
char *cfg_unescape(char *d, const char *s) {
|
||||
return (char *) cfg_unescapeu((unsigned char *) d, (const unsigned char *) s);
|
||||
}
|
||||
|
||||
// Return an escaped string that looks like a C-style input string incl quotes, memory is malloc'd
|
||||
char *cfg_escape(const char *s) {
|
||||
char buf[50*1024], *d = buf;
|
||||
|
||||
*d++ = '"';
|
||||
for(; *s && d-buf < sizeof buf-7; s++) {
|
||||
switch(*s) {
|
||||
case '\n':
|
||||
*d++ = '\\'; *d++ = 'n';
|
||||
break;
|
||||
case '\t':
|
||||
*d++ = '\\'; *d++ = 't';
|
||||
break;
|
||||
case '\a':
|
||||
*d++ = '\\'; *d++ = 'a';
|
||||
break;
|
||||
case '\b':
|
||||
*d++ = '\\'; *d++ = 'b';
|
||||
break;
|
||||
case '\f':
|
||||
*d++ = '\\'; *d++ = 'f';
|
||||
break;
|
||||
#if '\r' != '\n'
|
||||
case '\r':
|
||||
*d++ = '\\'; *d++ = 'r';
|
||||
break;
|
||||
#endif
|
||||
case '\v':
|
||||
*d++ = '\\'; *d++ = 'v';
|
||||
break;
|
||||
case '\"':
|
||||
*d++ = '\\'; *d++ = '\"';
|
||||
break;
|
||||
default:
|
||||
if(*s == 0x7f || (*s >= 0 && *s < 32)) {
|
||||
sprintf(d, "\\%03o", *s);
|
||||
d += strlen(d);
|
||||
} else
|
||||
*d++ = *s;
|
||||
}
|
||||
}
|
||||
*d++ = '"';
|
||||
*d = 0;
|
||||
|
||||
return cfg_strdup("cfg_escape()", buf);
|
||||
}
|
||||
|
|
48
src/config.h
48
src/config.h
|
@ -30,16 +30,21 @@
|
|||
#endif
|
||||
|
||||
|
||||
#define MAX_STR_CONST 1024
|
||||
typedef struct {
|
||||
char *kw; // Keyword near the comments
|
||||
LISTID comms; // Chained list of comments
|
||||
int rhs; // Comments to print rhs of keyword line
|
||||
} COMMENT;
|
||||
|
||||
|
||||
enum { V_NONE, V_NUM, V_NUM_REAL, V_STR };
|
||||
typedef struct value_t {
|
||||
int type;
|
||||
/*union { TODO: use an anonymous union here ? */
|
||||
union {
|
||||
int number;
|
||||
double number_real;
|
||||
char * string;
|
||||
/*};*/
|
||||
};
|
||||
} VALUE;
|
||||
|
||||
|
||||
|
@ -66,42 +71,49 @@ extern bool is_alias; // current entry is alias
|
|||
#endif
|
||||
extern YYSTYPE yylval;
|
||||
|
||||
extern char string_buf[MAX_STR_CONST];
|
||||
extern char *string_buf_ptr;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
int yyparse(void);
|
||||
|
||||
int yyerror(char * errmsg, ...);
|
||||
int yyerror(char *errmsg, ...);
|
||||
|
||||
int yywarning(char * errmsg, ...);
|
||||
int yywarning(char *errmsg, ...);
|
||||
|
||||
TOKEN * new_token(int primary);
|
||||
TOKEN *new_token(int primary);
|
||||
|
||||
void free_token(TOKEN * tkn);
|
||||
void free_token(TOKEN *tkn);
|
||||
|
||||
void free_tokens(int n, ...);
|
||||
|
||||
TOKEN * number(char * text);
|
||||
TOKEN *number(const char *text);
|
||||
|
||||
TOKEN * number_real(char * text);
|
||||
TOKEN *number_real(const char *text);
|
||||
|
||||
TOKEN * hexnumber(char * text);
|
||||
TOKEN *hexnumber(const char *text);
|
||||
|
||||
TOKEN * string(char * text);
|
||||
TOKEN *string(const char *text);
|
||||
|
||||
TOKEN * keyword(int primary);
|
||||
TOKEN *keyword(int primary);
|
||||
|
||||
void print_token(TOKEN * tkn);
|
||||
void print_token(TOKEN *tkn);
|
||||
|
||||
void pyytext(void);
|
||||
|
||||
char * dup_string(const char * str);
|
||||
COMMENT *locate_comment(const LISTID comments, const char *where, int rhs);
|
||||
|
||||
char * cache_string(const char * file);
|
||||
void cfg_capture_prologue(void);
|
||||
|
||||
LISTID cfg_get_prologue(void);
|
||||
|
||||
void capture_comment_str(const char *com, int lineno);
|
||||
|
||||
void capture_lvalue_kw(const char *kw, int lineno);
|
||||
|
||||
LISTID cfg_move_comments(void);
|
||||
|
||||
void cfg_pop_comms(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -246,26 +246,22 @@ def :
|
|||
part_def TKN_SEMI |
|
||||
|
||||
K_DEFAULT_PROGRAMMER TKN_EQUAL TKN_STRING TKN_SEMI {
|
||||
strncpy(default_programmer, $3->value.string, MAX_STR_CONST);
|
||||
default_programmer[MAX_STR_CONST-1] = 0;
|
||||
default_programmer = cache_string($3->value.string);
|
||||
free_token($3);
|
||||
} |
|
||||
|
||||
K_DEFAULT_PARALLEL TKN_EQUAL TKN_STRING TKN_SEMI {
|
||||
strncpy(default_parallel, $3->value.string, PATH_MAX);
|
||||
default_parallel[PATH_MAX-1] = 0;
|
||||
default_parallel = cache_string($3->value.string);
|
||||
free_token($3);
|
||||
} |
|
||||
|
||||
K_DEFAULT_SERIAL TKN_EQUAL TKN_STRING TKN_SEMI {
|
||||
strncpy(default_serial, $3->value.string, PATH_MAX);
|
||||
default_serial[PATH_MAX-1] = 0;
|
||||
default_serial = cache_string($3->value.string);
|
||||
free_token($3);
|
||||
} |
|
||||
|
||||
K_DEFAULT_SPI TKN_EQUAL TKN_STRING TKN_SEMI {
|
||||
strncpy(default_spi, $3->value.string, PATH_MAX);
|
||||
default_spi[PATH_MAX-1] = 0;
|
||||
default_spi = cache_string($3->value.string);
|
||||
free_token($3);
|
||||
} |
|
||||
|
||||
|
@ -301,6 +297,7 @@ prog_def :
|
|||
lrmv_d(programmers, existing_prog);
|
||||
pgm_free(existing_prog);
|
||||
}
|
||||
current_prog->comments = cfg_move_comments();
|
||||
LISTADD(programmers, current_prog);
|
||||
// pgm_fill_old_pins(current_prog); // TODO to be removed if old pin data no longer needed
|
||||
// pgm_display_generic(current_prog, id);
|
||||
|
@ -312,10 +309,6 @@ prog_def :
|
|||
prog_decl :
|
||||
K_PROGRAMMER
|
||||
{ current_prog = pgm_new();
|
||||
if (current_prog == NULL) {
|
||||
yyerror("could not create pgm instance");
|
||||
YYABORT;
|
||||
}
|
||||
current_prog->config_file = cache_string(cfg_infile);
|
||||
current_prog->lineno = cfg_lineno;
|
||||
}
|
||||
|
@ -329,12 +322,8 @@ prog_decl :
|
|||
YYABORT;
|
||||
}
|
||||
current_prog = pgm_dup(pgm);
|
||||
if (current_prog == NULL) {
|
||||
yyerror("could not duplicate pgm instance");
|
||||
free_token($3);
|
||||
YYABORT;
|
||||
}
|
||||
current_prog->parent_id = cache_string($3->value.string);
|
||||
current_prog->comments = NULL;
|
||||
current_prog->config_file = cache_string(cfg_infile);
|
||||
current_prog->lineno = cfg_lineno;
|
||||
free_token($3);
|
||||
|
@ -354,32 +343,33 @@ part_def :
|
|||
YYABORT;
|
||||
}
|
||||
|
||||
/*
|
||||
* perform some sanity checking, and compute the number of bits
|
||||
* to shift a page for constructing the page address for
|
||||
* page-addressed memories.
|
||||
*/
|
||||
// Sanity checks for memory sizes and compute/override num_pages entry
|
||||
for (ln=lfirst(current_part->mem); ln; ln=lnext(ln)) {
|
||||
m = ldata(ln);
|
||||
if (m->paged) {
|
||||
if (m->page_size == 0) {
|
||||
yyerror("must specify page_size for paged memory");
|
||||
if (m->size <= 0) {
|
||||
yyerror("must specify a positive size for paged memory %s", m->desc);
|
||||
YYABORT;
|
||||
}
|
||||
if (m->num_pages == 0) {
|
||||
yyerror("must specify num_pages for paged memory");
|
||||
if (m->page_size <= 0) {
|
||||
yyerror("must specify a positive page size for paged memory %s", m->desc);
|
||||
YYABORT;
|
||||
}
|
||||
if (m->size != m->page_size * m->num_pages) {
|
||||
yyerror("page size (%u) * num_pages (%u) = "
|
||||
"%u does not match memory size (%u)",
|
||||
m->page_size,
|
||||
m->num_pages,
|
||||
m->page_size * m->num_pages,
|
||||
m->size);
|
||||
// Code base relies on page_size being a power of 2 in some places
|
||||
if (m->page_size & (m->page_size - 1)) {
|
||||
yyerror("page size must be a power of 2 for paged memory %s", m->desc);
|
||||
YYABORT;
|
||||
}
|
||||
// Code base relies on size being a multiple of page_size
|
||||
if (m->size % m->page_size) {
|
||||
yyerror("size must be a multiple of page size for paged memory %s", m->desc);
|
||||
YYABORT;
|
||||
}
|
||||
// Warn if num_pages was specified but is inconsistent with size and page size
|
||||
if (m->num_pages && m->num_pages != m->size / m->page_size)
|
||||
yywarning("overriding num_page to be %d for memory %s", m->size/m->page_size, m->desc);
|
||||
|
||||
m->num_pages = m->size / m->page_size;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -395,6 +385,8 @@ part_def :
|
|||
lrmv_d(part_list, existing_part);
|
||||
avr_free_part(existing_part);
|
||||
}
|
||||
|
||||
current_part->comments = cfg_move_comments();
|
||||
LISTADD(part_list, current_part);
|
||||
current_part = NULL;
|
||||
}
|
||||
|
@ -404,10 +396,6 @@ part_decl :
|
|||
K_PART
|
||||
{
|
||||
current_part = avr_new_part();
|
||||
if (current_part == NULL) {
|
||||
yyerror("could not create part instance");
|
||||
YYABORT;
|
||||
}
|
||||
current_part->config_file = cache_string(cfg_infile);
|
||||
current_part->lineno = cfg_lineno;
|
||||
} |
|
||||
|
@ -421,12 +409,8 @@ part_decl :
|
|||
}
|
||||
|
||||
current_part = avr_dup_part(parent_part);
|
||||
if (current_part == NULL) {
|
||||
yyerror("could not duplicate part instance");
|
||||
free_token($3);
|
||||
YYABORT;
|
||||
}
|
||||
current_part->parent_id = cache_string($3->value.string);
|
||||
current_part->comments = NULL;
|
||||
current_part->config_file = cache_string(cfg_infile);
|
||||
current_part->lineno = cfg_lineno;
|
||||
|
||||
|
@ -453,25 +437,11 @@ prog_parms :
|
|||
prog_parm :
|
||||
K_ID TKN_EQUAL string_list {
|
||||
{
|
||||
TOKEN * t;
|
||||
char *s;
|
||||
int do_yyabort = 0;
|
||||
while (lsize(string_list)) {
|
||||
t = lrmv_n(string_list, 1);
|
||||
if (!do_yyabort) {
|
||||
s = dup_string(t->value.string);
|
||||
if (s == NULL) {
|
||||
do_yyabort = 1;
|
||||
} else {
|
||||
ladd(current_prog->id, s);
|
||||
}
|
||||
}
|
||||
/* if do_yyabort == 1 just make the list empty */
|
||||
TOKEN *t = lrmv_n(string_list, 1);
|
||||
ladd(current_prog->id, cfg_strdup("config_gram.y", t->value.string));
|
||||
free_token(t);
|
||||
}
|
||||
if (do_yyabort) {
|
||||
YYABORT;
|
||||
}
|
||||
}
|
||||
} |
|
||||
prog_parm_type
|
||||
|
@ -483,8 +453,7 @@ prog_parm :
|
|||
prog_parm_conntype
|
||||
|
|
||||
K_DESC TKN_EQUAL TKN_STRING {
|
||||
strncpy(current_prog->desc, $3->value.string, PGM_DESCLEN);
|
||||
current_prog->desc[PGM_DESCLEN-1] = 0;
|
||||
current_prog->desc = cache_string($3->value.string);
|
||||
free_token($3);
|
||||
} |
|
||||
K_BAUDRATE TKN_EQUAL TKN_NUMBER {
|
||||
|
@ -532,8 +501,7 @@ prog_parm_conntype_id:
|
|||
prog_parm_usb:
|
||||
K_USBDEV TKN_EQUAL TKN_STRING {
|
||||
{
|
||||
strncpy(current_prog->usbdev, $3->value.string, PGM_USBSTRINGLEN);
|
||||
current_prog->usbdev[PGM_USBSTRINGLEN-1] = 0;
|
||||
current_prog->usbdev = cache_string($3->value.string);
|
||||
free_token($3);
|
||||
}
|
||||
} |
|
||||
|
@ -546,22 +514,19 @@ prog_parm_usb:
|
|||
K_USBPID TKN_EQUAL usb_pid_list |
|
||||
K_USBSN TKN_EQUAL TKN_STRING {
|
||||
{
|
||||
strncpy(current_prog->usbsn, $3->value.string, PGM_USBSTRINGLEN);
|
||||
current_prog->usbsn[PGM_USBSTRINGLEN-1] = 0;
|
||||
current_prog->usbsn = cache_string($3->value.string);
|
||||
free_token($3);
|
||||
}
|
||||
} |
|
||||
K_USBVENDOR TKN_EQUAL TKN_STRING {
|
||||
{
|
||||
strncpy(current_prog->usbvendor, $3->value.string, PGM_USBSTRINGLEN);
|
||||
current_prog->usbvendor[PGM_USBSTRINGLEN-1] = 0;
|
||||
current_prog->usbvendor = cache_string($3->value.string);
|
||||
free_token($3);
|
||||
}
|
||||
} |
|
||||
K_USBPRODUCT TKN_EQUAL TKN_STRING {
|
||||
{
|
||||
strncpy(current_prog->usbproduct, $3->value.string, PGM_USBSTRINGLEN);
|
||||
current_prog->usbproduct[PGM_USBSTRINGLEN-1] = 0;
|
||||
current_prog->usbproduct = cache_string($3->value.string);
|
||||
free_token($3);
|
||||
}
|
||||
}
|
||||
|
@ -708,22 +673,19 @@ retry_lines :
|
|||
part_parm :
|
||||
K_ID TKN_EQUAL TKN_STRING
|
||||
{
|
||||
strncpy(current_part->id, $3->value.string, AVR_IDLEN);
|
||||
current_part->id[AVR_IDLEN-1] = 0;
|
||||
current_part->id = cache_string($3->value.string);
|
||||
free_token($3);
|
||||
} |
|
||||
|
||||
K_DESC TKN_EQUAL TKN_STRING
|
||||
{
|
||||
strncpy(current_part->desc, $3->value.string, AVR_DESCLEN - 1);
|
||||
current_part->desc[AVR_DESCLEN-1] = 0;
|
||||
current_part->desc = cache_string($3->value.string);
|
||||
free_token($3);
|
||||
} |
|
||||
|
||||
K_FAMILY_ID TKN_EQUAL TKN_STRING
|
||||
{
|
||||
strncpy(current_part->family_id, $3->value.string, AVR_FAMILYIDLEN);
|
||||
current_part->family_id[AVR_FAMILYIDLEN] = 0;
|
||||
current_part->family_id = cache_string($3->value.string);
|
||||
free_token($3);
|
||||
} |
|
||||
|
||||
|
@ -1311,13 +1273,8 @@ part_parm :
|
|||
{ /* select memory for extension or create if not there */
|
||||
AVRMEM *mem = avr_locate_mem_noalias(current_part, $2->value.string);
|
||||
if(!mem) {
|
||||
if(!(mem = avr_new_memtype())) {
|
||||
yyerror("could not create mem instance");
|
||||
free_token($2);
|
||||
YYABORT;
|
||||
}
|
||||
strncpy(mem->desc, $2->value.string, AVR_MEMDESCLEN - 1);
|
||||
mem->desc[AVR_MEMDESCLEN-1] = 0;
|
||||
mem = avr_new_memtype();
|
||||
mem->desc = cache_string($2->value.string);
|
||||
ladd(current_part->mem, mem);
|
||||
}
|
||||
avr_add_mem_order($2->value.string);
|
||||
|
@ -1340,7 +1297,9 @@ part_parm :
|
|||
yywarning("%s's %s %s misses a necessary address bit a%d",
|
||||
current_part->desc, current_mem->desc, opcodename(i), bn-1);
|
||||
}
|
||||
current_mem->comments = cfg_move_comments();
|
||||
}
|
||||
cfg_pop_comms();
|
||||
current_mem = NULL;
|
||||
} |
|
||||
K_MEMORY TKN_STRING TKN_EQUAL K_NULL
|
||||
|
@ -1351,6 +1310,7 @@ part_parm :
|
|||
avr_free_mem(existing_mem);
|
||||
}
|
||||
free_token($2);
|
||||
cfg_pop_comms();
|
||||
current_mem = NULL;
|
||||
} |
|
||||
opcode TKN_EQUAL string_list {
|
||||
|
@ -1361,11 +1321,6 @@ part_parm :
|
|||
opnum = which_opcode($1);
|
||||
if (opnum < 0) YYABORT;
|
||||
op = avr_new_opcode();
|
||||
if (op == NULL) {
|
||||
yyerror("could not create opcode instance");
|
||||
free_token($1);
|
||||
YYABORT;
|
||||
}
|
||||
if(0 != parse_cmdbits(op, opnum))
|
||||
YYABORT;
|
||||
if (current_part->op[opnum] != NULL) {
|
||||
|
@ -1521,11 +1476,6 @@ mem_spec :
|
|||
opnum = which_opcode($1);
|
||||
if (opnum < 0) YYABORT;
|
||||
op = avr_new_opcode();
|
||||
if (op == NULL) {
|
||||
yyerror("could not create opcode instance");
|
||||
free_token($1);
|
||||
YYABORT;
|
||||
}
|
||||
if(0 != parse_cmdbits(op, opnum))
|
||||
YYABORT;
|
||||
if (current_mem->op[opnum] != NULL) {
|
||||
|
@ -1574,10 +1524,7 @@ mem_alias :
|
|||
|
||||
is_alias = true;
|
||||
alias = avr_new_memalias();
|
||||
|
||||
// alias->desc and current_mem->desc have the same length
|
||||
// definition, thus no need to check for length here
|
||||
strcpy(alias->desc, current_mem->desc);
|
||||
alias->desc = current_mem->desc;
|
||||
alias->aliased_mem = existing_mem;
|
||||
ladd(current_part->mem_alias, alias);
|
||||
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
#include <stdlib.h>
|
||||
#include <whereami.h>
|
||||
#include <stdarg.h>
|
||||
#include <stddef.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <limits.h>
|
||||
|
@ -47,11 +48,12 @@
|
|||
|
||||
#include "avrdude.h"
|
||||
#include "libavrdude.h"
|
||||
#include "config.h"
|
||||
|
||||
#include "developer_opts.h"
|
||||
#include "developer_opts_private.h"
|
||||
|
||||
// return 0 if op code would encode (essentially) the same SPI command
|
||||
// Return 0 if op code would encode (essentially) the same SPI command
|
||||
static int opcodecmp(OPCODE *op1, OPCODE *op2, int opnum) {
|
||||
char *opstr1, *opstr2, *p;
|
||||
int cmp;
|
||||
|
@ -68,7 +70,7 @@ static int opcodecmp(OPCODE *op1, OPCODE *op2, int opnum) {
|
|||
exit(1);
|
||||
}
|
||||
|
||||
// don't care x and 0 are functionally equivalent
|
||||
// Don't care x and 0 are functionally equivalent
|
||||
for(p=opstr1; *p; p++)
|
||||
if(*p == 'x')
|
||||
*p = '0';
|
||||
|
@ -108,7 +110,7 @@ static void printallopcodes(AVRPART *p, const char *d, OPCODE **opa) {
|
|||
|
||||
|
||||
|
||||
// mnemonic characterisation of flags
|
||||
// Mnemonic characterisation of flags
|
||||
static char *parttype(AVRPART *p) {
|
||||
static char type[1024];
|
||||
|
||||
|
@ -144,7 +146,7 @@ static char *parttype(AVRPART *p) {
|
|||
}
|
||||
|
||||
|
||||
// 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, OPCODE *op, AVRPART *p, AVRMEM *m) {
|
||||
int i, lo, hi;
|
||||
const char *opstr = opcodename(opnum);
|
||||
|
@ -152,7 +154,7 @@ static void checkaddr(int memsize, int pagesize, int opnum, OPCODE *op, AVRPART
|
|||
lo = intlog2(pagesize);
|
||||
hi = intlog2(memsize-1);
|
||||
|
||||
// address bits should be between positions lo and hi (and fall in line), outside should be 0 or don't care
|
||||
// Address bits should be between positions lo and hi (and fall in line), outside should be 0 or don't care
|
||||
for(i=0; i<16; i++) { // ISP programming only deals with 16-bit addresses (words for flash, bytes for eeprom)
|
||||
if(i < lo || i > hi) {
|
||||
if(op->bit[i+8].type != AVR_CMDBIT_IGNORE && !(op->bit[i+8].type == AVR_CMDBIT_VALUE && op->bit[i+8].value == 0)) {
|
||||
|
@ -168,7 +170,7 @@ static void checkaddr(int memsize, int pagesize, int opnum, OPCODE *op, AVRPART
|
|||
dev_info(".cmderr\t%s\t%s-%s\tbit %d inconsistent: a%d specified as a%d\n", p->desc, m->desc, opstr, i+8, i, op->bit[i+8].bitno);
|
||||
}
|
||||
}
|
||||
for(i=0; i<32; i++) // command bits 8..23 should not contain address bits
|
||||
for(i=0; i<32; i++) // Command bits 8..23 should not contain address bits
|
||||
if((i<8 || i>23) && op->bit[i].type == AVR_CMDBIT_ADDRESS)
|
||||
dev_info(".cmderr\t%s\t%s-%s\tbit %d contains a%d which it shouldn't\n", p->desc, m->desc, opstr, i, op->bit[i].bitno);
|
||||
}
|
||||
|
@ -180,26 +182,23 @@ static char *dev_sprintf(const char *fmt, ...) {
|
|||
char *p = NULL;
|
||||
va_list ap;
|
||||
|
||||
// compute size
|
||||
// Compute size
|
||||
va_start(ap, fmt);
|
||||
size = vsnprintf(p, size, fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
if(size < 0)
|
||||
return NULL;
|
||||
return cfg_strdup("dev_sprintf()", "");
|
||||
|
||||
size++; // for temrinating '\0'
|
||||
if(!(p = malloc(size)))
|
||||
return NULL;
|
||||
size++; // For terminating '\0'
|
||||
p = cfg_malloc("dev_sprintf()", size);
|
||||
|
||||
va_start(ap, fmt);
|
||||
size = vsnprintf(p, size, fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
if(size < 0) {
|
||||
free(p);
|
||||
return NULL;
|
||||
}
|
||||
if(size < 0)
|
||||
*p = 0;
|
||||
|
||||
return p;
|
||||
}
|
||||
|
@ -213,7 +212,7 @@ int dev_message(int msglvl, const char *fmt, ...) {
|
|||
|
||||
if(verbose >= msglvl) {
|
||||
va_start(ap, fmt);
|
||||
rc = vfprintf(stderr, fmt, ap);
|
||||
rc = vfprintf(stdout, fmt, ap);
|
||||
va_end(ap);
|
||||
if(rc > 0)
|
||||
dev_nprinted += rc;
|
||||
|
@ -223,12 +222,53 @@ int dev_message(int msglvl, const char *fmt, ...) {
|
|||
}
|
||||
|
||||
|
||||
// Any of the strings in the list contains subs as substring?
|
||||
int dev_has_subsstr_comms(const LISTID comms, const char *subs) {
|
||||
if(comms)
|
||||
for(LNODEID ln=lfirst(comms); ln; ln=lnext(ln))
|
||||
if(strstr((char *) ldata(ln), subs))
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Print a chained list of strings
|
||||
void dev_print_comment(const LISTID comms) {
|
||||
if(comms)
|
||||
for(LNODEID ln=lfirst(comms); ln; ln=lnext(ln))
|
||||
dev_info("%s", (char *) ldata(ln));
|
||||
}
|
||||
|
||||
// Conditional output of part, memory or programmer's comments field
|
||||
static void dev_cout(const LISTID comms, const char *name, int rhs, int elself) {
|
||||
COMMENT *cp;
|
||||
|
||||
if((cp = locate_comment(comms, name, rhs)))
|
||||
dev_print_comment(cp->comms);
|
||||
else if(elself)
|
||||
dev_info("\n");
|
||||
}
|
||||
|
||||
// Print part->comments, mem->comments or pgm->comments (for debugging)
|
||||
void dev_print_kw_comments(const LISTID comms) {
|
||||
if(comms)
|
||||
for(LNODEID ln=lfirst(comms); ln; ln=lnext(ln)) {
|
||||
COMMENT *n = ldata(ln);
|
||||
if(n && n->comms) {
|
||||
dev_info(">>> %s %c\n", n->kw, n->rhs? '>': '<');
|
||||
dev_print_comment(n->comms);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Ideally all assignment outputs run via this function
|
||||
static int dev_part_strct_entry(bool tsv, // Print as spreadsheet?
|
||||
const char *col0, const char *col1, const char *col2, // Descriptors of item
|
||||
const char *name, char *cont, const LISTID comms) { // Name, contents and comments
|
||||
|
||||
static int dev_part_strct_entry(bool tsv, char *col0, char *col1, char *col2, const char *name, char *cont) {
|
||||
const char *n = name? name: "name_error";
|
||||
const char *c = cont? cont: "cont_error";
|
||||
|
||||
if(tsv) { // tab separated values
|
||||
if(tsv) { // Tab separated values
|
||||
if(col0) {
|
||||
dev_info("%s\t", col0);
|
||||
if(col1) {
|
||||
|
@ -239,10 +279,11 @@ static int dev_part_strct_entry(bool tsv, char *col0, char *col1, char *col2, co
|
|||
}
|
||||
}
|
||||
dev_info("%s\t%s\n", n, c);
|
||||
} else { // grammar conform
|
||||
} else { // Grammar conform
|
||||
int indent = col2 && strcmp(col2, "part");
|
||||
|
||||
printf("%*s%-*s = %s;\n", indent? 8: 4, "", indent? 15: 19, n, c);
|
||||
dev_cout(comms, n, 0, 0); // Print comments before the line
|
||||
dev_info("%*s%-*s = %s;", indent? 8: 4, "", indent? 15: 19, n, c);
|
||||
dev_cout(comms, n, 1, 1); // Print comments on rhs
|
||||
}
|
||||
|
||||
if(cont)
|
||||
|
@ -269,14 +310,18 @@ static void dev_stack_out(bool tsv, AVRPART *p, const char *name, unsigned char
|
|||
|
||||
if(tsv)
|
||||
dev_info(".pt\t%s\t%s\t", p->desc, name);
|
||||
else
|
||||
else {
|
||||
dev_cout(p->comments, name, 0, 0);
|
||||
dev_info(" %-19s =%s", name, ns <=8? " ": "");
|
||||
}
|
||||
|
||||
if(ns <= 0)
|
||||
dev_info(tsv? "NULL\n": "NULL;\n");
|
||||
dev_info(tsv? "NULL\n": "NULL;");
|
||||
else
|
||||
for(int i=0; i<ns; i++)
|
||||
dev_info("%s0x%02x%s", !tsv && ns > 8 && i%8 == 0? "\n ": "", stack[i], i+1<ns? ", ": tsv? "\n": ";\n");
|
||||
dev_info("%s0x%02x%s", !tsv && ns > 8 && i%8 == 0? "\n ": "", stack[i], i+1<ns? ", ": tsv? "\n": ";");
|
||||
|
||||
dev_cout(p->comments, name, 1, 1);
|
||||
}
|
||||
|
||||
|
||||
|
@ -285,34 +330,32 @@ static int intcmp(int a, int b) {
|
|||
}
|
||||
|
||||
|
||||
// deep copies for comparison and raw output
|
||||
// Deep copies for comparison and raw output
|
||||
|
||||
typedef struct {
|
||||
char descbuf[32];
|
||||
AVRMEM base;
|
||||
OPCODE ops[AVR_OP_MAX];
|
||||
} AVRMEMdeep;
|
||||
|
||||
static int avrmem_deep_copy(AVRMEMdeep *d, AVRMEM *m) {
|
||||
size_t len;
|
||||
|
||||
static int avrmem_deep_copy(AVRMEMdeep *d, const AVRMEM *m) {
|
||||
d->base = *m;
|
||||
|
||||
// zap all bytes beyond terminating nul of desc array
|
||||
len = strlen(m->desc)+1;
|
||||
if(len < sizeof m->desc)
|
||||
memset(d->base.desc + len, 0, sizeof m->desc - len);
|
||||
// Note memory desc (name, really) is limited to 31 char here
|
||||
memset(d->descbuf, 0, sizeof d->descbuf);
|
||||
strncpy(d->descbuf, m->desc, sizeof d->descbuf-1);
|
||||
|
||||
// zap address values
|
||||
// Zap address values
|
||||
d->base.comments = NULL;
|
||||
d->base.buf = NULL;
|
||||
d->base.tags = NULL;
|
||||
d->base.desc = NULL;
|
||||
for(int i=0; i<AVR_OP_MAX; i++)
|
||||
d->base.op[i] = NULL;
|
||||
|
||||
|
||||
// copy over the SPI operations themselves
|
||||
memset(d->base.op, 0, sizeof d->base.op);
|
||||
// Copy over the SPI operations themselves
|
||||
memset(d->ops, 0, sizeof d->ops);
|
||||
for(size_t i=0; i<sizeof d->ops/sizeof *d->ops; i++)
|
||||
for(size_t i=0; i<AVR_OP_MAX; i++)
|
||||
if(m->op[i])
|
||||
d->ops[i] = *m->op[i];
|
||||
|
||||
|
@ -327,7 +370,7 @@ static int memorycmp(AVRMEM *m1, AVRMEM *m2) {
|
|||
|
||||
if(!m1 || !m2)
|
||||
return m1? -1: 1;
|
||||
|
||||
|
||||
avrmem_deep_copy(&dm1, m1);
|
||||
avrmem_deep_copy(&dm2, m2);
|
||||
|
||||
|
@ -336,53 +379,54 @@ static int memorycmp(AVRMEM *m1, AVRMEM *m2) {
|
|||
|
||||
|
||||
typedef struct {
|
||||
char descbuf[64];
|
||||
char idbuf[32];
|
||||
char family_idbuf[16];
|
||||
AVRPART base;
|
||||
OPCODE ops[AVR_OP_MAX];
|
||||
AVRMEMdeep mems[40];
|
||||
} AVRPARTdeep;
|
||||
|
||||
static int avrpart_deep_copy(AVRPARTdeep *d, AVRPART *p) {
|
||||
static int avrpart_deep_copy(AVRPARTdeep *d, const AVRPART *p) {
|
||||
AVRMEM *m;
|
||||
size_t len, di;
|
||||
size_t di;
|
||||
|
||||
memset(d, 0, sizeof *d);
|
||||
|
||||
d->base = *p;
|
||||
|
||||
d->base.comments = NULL;
|
||||
d->base.parent_id = NULL;
|
||||
d->base.config_file = NULL;
|
||||
d->base.lineno = 0;
|
||||
|
||||
// zap all bytes beyond terminating nul of desc, id and family_id array
|
||||
len = strlen(p->desc);
|
||||
if(len < sizeof p->desc)
|
||||
memset(d->base.desc + len, 0, sizeof p->desc - len);
|
||||
// Copy over desc, id, and family_id
|
||||
memset(d->descbuf, 0, sizeof d->descbuf);
|
||||
strncpy(d->descbuf, p->desc, sizeof d->descbuf-1);
|
||||
memset(d->idbuf, 0, sizeof d->idbuf);
|
||||
strncpy(d->idbuf, p->id, sizeof d->idbuf-1);
|
||||
memset(d->family_idbuf, 0, sizeof d->family_idbuf);
|
||||
strncpy(d->family_idbuf, p->family_id, sizeof d->family_idbuf-1);
|
||||
|
||||
len = strlen(p->family_id);
|
||||
if(len < sizeof p->family_id)
|
||||
memset(d->base.family_id + len, 0, sizeof p->family_id - len);
|
||||
|
||||
len = strlen(p->id);
|
||||
if(len < sizeof p->id)
|
||||
memset(d->base.id + len, 0, sizeof p->id - len);
|
||||
|
||||
// zap address values
|
||||
// Zap address values
|
||||
d->base.desc = NULL;
|
||||
d->base.id = NULL;
|
||||
d->base.family_id = NULL;
|
||||
d->base.mem = NULL;
|
||||
d->base.mem_alias = NULL;
|
||||
for(int i=0; i<AVR_OP_MAX; i++)
|
||||
d->base.op[i] = NULL;
|
||||
|
||||
// copy over the SPI operations
|
||||
memset(d->base.op, 0, sizeof d->base.op);
|
||||
// Copy over all used SPI operations
|
||||
memset(d->ops, 0, sizeof d->ops);
|
||||
for(int i=0; i<AVR_OP_MAX; i++)
|
||||
if(p->op[i])
|
||||
d->ops[i] = *p->op[i];
|
||||
|
||||
// fill in all memories we got in defined order
|
||||
// Fill in all memories we got in defined order
|
||||
di = 0;
|
||||
for(size_t mi=0; mi < sizeof avr_mem_order/sizeof *avr_mem_order && avr_mem_order[mi]; mi++) {
|
||||
m = p->mem? avr_locate_mem(p, avr_mem_order[mi]): NULL;
|
||||
m = p->mem? avr_locate_mem_noalias(p, avr_mem_order[mi]): NULL;
|
||||
if(m) {
|
||||
if(di >= sizeof d->mems/sizeof *d->mems) {
|
||||
avrdude_message(MSG_INFO, "%s: ran out of mems[] space, increase size in AVRMEMdeep of developer_opts.c and recompile\n", progname);
|
||||
|
@ -396,55 +440,90 @@ static int avrpart_deep_copy(AVRPARTdeep *d, AVRPART *p) {
|
|||
return di;
|
||||
}
|
||||
|
||||
|
||||
static char txtchar(unsigned char in) {
|
||||
in &= 0x7f;
|
||||
return in == ' '? '_': in > ' ' && in < 0x7f? in: '.';
|
||||
return in == 0? '.': in > ' ' && in < 0x7f? in: '_';
|
||||
}
|
||||
|
||||
static void dev_raw_dump(const void *v, int nbytes, const char *name, const char *sub, int idx) {
|
||||
const unsigned char *p = v;
|
||||
int n = (nbytes + 31)/32;
|
||||
|
||||
static void dev_raw_dump(unsigned char *p, int nbytes, const char *name, const char *sub, int idx) {
|
||||
unsigned char *end = p+nbytes;
|
||||
int n = ((end - p) + 15)/16;
|
||||
|
||||
for(int i=0; i<n; i++, p += 16) {
|
||||
dev_info("%s\t%s\t%02x%04x: ", name, sub, idx, i*16);
|
||||
for(int j=0; j<16; j++)
|
||||
dev_info("%02x", p+i*16+j<end? p[i*16+j]: 0);
|
||||
for(int i=0; i<n; i++, p += 32, nbytes -= 32) {
|
||||
dev_info("%s\t%s\t%02x.%03x0: ", name, sub, idx, 2*i);
|
||||
for(int j=0; j<32; j++) {
|
||||
if(j && j%8 == 0)
|
||||
dev_info(" ");
|
||||
if(j < nbytes)
|
||||
dev_info("%02x", p[j]);
|
||||
else
|
||||
dev_info(" ");
|
||||
}
|
||||
dev_info(" ");
|
||||
for(int j=0; j<16; j++)
|
||||
dev_info("%c", txtchar(p+i*16+j<end? p[i*16+j]: 0));
|
||||
for(int j=0; j<32 && j < nbytes; j++)
|
||||
dev_info("%c", txtchar(p[j]));
|
||||
dev_info("\n");
|
||||
}
|
||||
}
|
||||
|
||||
static int _is_all_zero(const void *p, size_t n) {
|
||||
const char *q = (const char *) p;
|
||||
return n <= 0 || (*q == 0 && memcmp(q, q+1, n-1) == 0);
|
||||
}
|
||||
|
||||
static char *opsnm(const char *pre, int opnum) {
|
||||
static char ret[128];
|
||||
sprintf(ret, "%.31s.%.95s", pre, opcodename(opnum));
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void dev_part_raw(AVRPART *part) {
|
||||
AVRPARTdeep dp;
|
||||
int di = avrpart_deep_copy(&dp, part);
|
||||
|
||||
dev_raw_dump((unsigned char *) &dp.base, sizeof dp.base, part->desc, "part", 0);
|
||||
dev_raw_dump((unsigned char *) &dp.ops, sizeof dp.ops, part->desc, "ops", 1);
|
||||
dev_raw_dump(&dp.base, sizeof dp.base, part->desc, "part", 0);
|
||||
for(int i=0; i<AVR_OP_MAX; i++)
|
||||
if(!_is_all_zero(dp.ops+i, sizeof*dp.ops))
|
||||
dev_raw_dump(dp.ops+i, sizeof*dp.ops, part->desc, opsnm("part", i), 1);
|
||||
|
||||
for(int i=0; i<di; i++)
|
||||
dev_raw_dump((unsigned char *) (dp.mems+i), sizeof dp.mems[i], part->desc, dp.mems[i].base.desc, i+2);
|
||||
for(int i=0; i<di; i++) {
|
||||
char *nm = dp.mems[i].descbuf;
|
||||
|
||||
dev_raw_dump(nm, sizeof dp.mems[i].descbuf, part->desc, nm, i+2);
|
||||
dev_raw_dump(&dp.mems[i].base, sizeof dp.mems[i].base, part->desc, nm, i+2);
|
||||
for(int j=0; j<AVR_OP_MAX; j++)
|
||||
if(!_is_all_zero(dp.mems[i].ops+j, sizeof(OPCODE)))
|
||||
dev_raw_dump(dp.mems[i].ops+j, sizeof(OPCODE), part->desc, opsnm(nm, j), i+2);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void dev_part_strct(AVRPART *p, bool tsv, AVRPART *base) {
|
||||
char *descstr = cfg_escape(p->desc);
|
||||
COMMENT *cp;
|
||||
|
||||
if(!tsv) {
|
||||
dev_info("#------------------------------------------------------------\n");
|
||||
dev_info("# %s\n", p->desc);
|
||||
dev_info("#------------------------------------------------------------\n");
|
||||
if(p->parent_id)
|
||||
dev_info("\npart parent \"%s\"\n", p->parent_id);
|
||||
const char *del = "#------------------------------------------------------------";
|
||||
cp = locate_comment(p->comments, "*", 0);
|
||||
|
||||
if(!cp || !dev_has_subsstr_comms(cp->comms, del)) {
|
||||
dev_info("%s\n", del);
|
||||
dev_info("# %.*s\n", strlen(descstr)-2, descstr+1); // Remove double quotes
|
||||
dev_info("%s\n\n", del);
|
||||
}
|
||||
if(cp)
|
||||
dev_print_comment(cp->comms);
|
||||
|
||||
if(p->parent_id && *p->parent_id)
|
||||
dev_info("part parent \"%s\"\n", p->parent_id);
|
||||
else
|
||||
dev_info("\npart\n");
|
||||
dev_info("part\n");
|
||||
}
|
||||
|
||||
_if_partout(strcmp, "\"%s\"", desc);
|
||||
_if_partout(strcmp, "\"%s\"", id);
|
||||
_if_partout(strcmp, "\"%s\"", family_id);
|
||||
_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(intcmp, "%d", hvupdi_variant);
|
||||
_if_partout(intcmp, "0x%02x", stk500_devcode);
|
||||
_if_partout(intcmp, "0x%02x", avr910_devcode);
|
||||
|
@ -455,9 +534,13 @@ static void dev_part_strct(AVRPART *p, bool tsv, AVRPART *base) {
|
|||
_if_partout(intcmp, "0x%04x", usbpid);
|
||||
|
||||
if(!base || base->reset_disposition != p->reset_disposition)
|
||||
_partout_str(strdup(p->reset_disposition == RESET_DEDICATED? "dedicated": p->reset_disposition == RESET_IO? "io": "unknown"), reset);
|
||||
_partout_str(cfg_strdup("dev_part_strct()",
|
||||
p->reset_disposition == RESET_DEDICATED? "dedicated": p->reset_disposition == RESET_IO? "io": "unknown"),
|
||||
reset);
|
||||
|
||||
_if_partout_str(intcmp, strdup(p->retry_pulse == PIN_AVR_RESET? "reset": p->retry_pulse == PIN_AVR_SCK? "sck": "unknown"), retry_pulse);
|
||||
_if_partout_str(intcmp, cfg_strdup("dev_part_strct()",
|
||||
p->retry_pulse == PIN_AVR_RESET? "reset": p->retry_pulse == PIN_AVR_SCK? "sck": "unknown"),
|
||||
retry_pulse);
|
||||
|
||||
if(!base || base->flags != p->flags) {
|
||||
if(tsv) {
|
||||
|
@ -476,7 +559,9 @@ static void dev_part_strct(AVRPART *p, bool tsv, AVRPART *base) {
|
|||
|
||||
if(!base || (base->flags & (AVRPART_PARALLELOK | AVRPART_PSEUDOPARALLEL)) != (p->flags & (AVRPART_PARALLELOK | AVRPART_PSEUDOPARALLEL))) {
|
||||
int par = p->flags & (AVRPART_PARALLELOK | AVRPART_PSEUDOPARALLEL);
|
||||
_partout_str(strdup(par == 0? "no": par == AVRPART_PSEUDOPARALLEL? "unknown": AVRPART_PARALLELOK? "yes": "pseudo"), parallel);
|
||||
_partout_str(cfg_strdup("dev_part_strct()",
|
||||
par == 0? "no": par == AVRPART_PSEUDOPARALLEL? "unknown": AVRPART_PARALLELOK? "yes": "pseudo"),
|
||||
parallel);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -527,7 +612,7 @@ static void dev_part_strct(AVRPART *p, bool tsv, AVRPART *base) {
|
|||
_if_partout(intcmp, "0x%02x", idr);
|
||||
_if_partout(intcmp, "0x%02x", rampz);
|
||||
_if_partout(intcmp, "0x%02x", spmcr);
|
||||
_if_partout(intcmp, "0x%02x", eecr); // why is eecr an unsigned short?
|
||||
_if_partout(intcmp, "0x%02x", eecr);
|
||||
_if_partout(intcmp, "0x%04x", mcu_base);
|
||||
_if_partout(intcmp, "0x%04x", nvm_base);
|
||||
_if_partout(intcmp, "0x%04x", ocd_base);
|
||||
|
@ -535,13 +620,13 @@ static void dev_part_strct(AVRPART *p, bool tsv, AVRPART *base) {
|
|||
|
||||
for(int i=0; i < AVR_OP_MAX; i++)
|
||||
if(!base || opcodecmp(p->op[i], base->op[i], i))
|
||||
dev_part_strct_entry(tsv, ".ptop", p->desc, "part", opcodename(i), opcode2str(p->op[i], i, !tsv));
|
||||
dev_part_strct_entry(tsv, ".ptop", p->desc, "part", opcodename(i), opcode2str(p->op[i], i, !tsv), p->comments);
|
||||
|
||||
for(size_t mi=0; mi < sizeof avr_mem_order/sizeof *avr_mem_order && avr_mem_order[mi]; mi++) {
|
||||
AVRMEM *m, *bm;
|
||||
|
||||
m = p->mem? avr_locate_mem(p, avr_mem_order[mi]): NULL;
|
||||
bm = base && base->mem? avr_locate_mem(base, avr_mem_order[mi]): NULL;
|
||||
m = p->mem? avr_locate_mem_noalias(p, avr_mem_order[mi]): NULL;
|
||||
bm = base && base->mem? avr_locate_mem_noalias(base, avr_mem_order[mi]): NULL;
|
||||
|
||||
if(!m && bm && !tsv)
|
||||
dev_info("\n memory \"%s\" = NULL;\n", bm->desc);
|
||||
|
@ -553,16 +638,17 @@ static void dev_part_strct(AVRPART *p, bool tsv, AVRPART *base) {
|
|||
bm = avr_new_memtype();
|
||||
|
||||
if(!tsv) {
|
||||
if(!memorycmp(bm, m)) // same memory bit for bit, no need to instantiate
|
||||
if(!memorycmp(bm, m)) // Same memory bit for bit, no need to instantiate
|
||||
continue;
|
||||
|
||||
dev_info("\n memory \"%s\"\n", m->desc);
|
||||
dev_cout(m->comments, "*", 0, 1);
|
||||
dev_info(" memory \"%s\"\n", m->desc);
|
||||
}
|
||||
|
||||
_if_memout_yn(paged);
|
||||
_if_memout(intcmp, m->size > 8192? "0x%x": "%d", size);
|
||||
_if_memout(intcmp, "%d", page_size);
|
||||
_if_memout(intcmp, "%d", num_pages); // why can AVRDUDE not compute this?
|
||||
_if_memout(intcmp, "%d", num_pages);
|
||||
_if_memout(intcmp, "0x%x", offset);
|
||||
_if_memout(intcmp, "%d", min_write_delay);
|
||||
_if_memout(intcmp, "%d", max_write_delay);
|
||||
|
@ -576,10 +662,12 @@ static void dev_part_strct(AVRPART *p, bool tsv, AVRPART *base) {
|
|||
|
||||
for(int i=0; i < AVR_OP_MAX; i++)
|
||||
if(!bm || opcodecmp(bm->op[i], m->op[i], i))
|
||||
dev_part_strct_entry(tsv, ".ptmmop", p->desc, m->desc, opcodename(i), opcode2str(m->op[i], i, !tsv));
|
||||
dev_part_strct_entry(tsv, ".ptmmop", p->desc, m->desc, opcodename(i), opcode2str(m->op[i], i, !tsv), m->comments);
|
||||
|
||||
if(!tsv)
|
||||
if(!tsv) {
|
||||
dev_cout(m->comments, ";", 0, 0);
|
||||
dev_info(" ;\n");
|
||||
}
|
||||
|
||||
for(LNODEID lnm=lfirst(p->mem_alias); lnm; lnm=lnext(lnm)) {
|
||||
AVRMEM_ALIAS *ma = ldata(lnm);
|
||||
|
@ -592,16 +680,43 @@ static void dev_part_strct(AVRPART *p, bool tsv, AVRPART *base) {
|
|||
}
|
||||
}
|
||||
|
||||
if(!tsv)
|
||||
if(!tsv) {
|
||||
dev_cout(p->comments, ";", 0, 0);
|
||||
dev_info(";\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void dev_output_pgm_part(int dev_opt_c, char *programmer, int dev_opt_p, char *partdesc) {
|
||||
if(dev_opt_c == 2 && dev_opt_p == 2) {
|
||||
char *p;
|
||||
|
||||
dev_print_comment(cfg_get_prologue());
|
||||
|
||||
dev_info("default_programmer = %s;\n", p = cfg_escape(default_programmer)); free(p);
|
||||
dev_info("default_parallel = %s;\n", p = cfg_escape(default_parallel)); free(p);
|
||||
dev_info("default_serial = %s;\n", p = cfg_escape(default_serial)); free(p);
|
||||
dev_info("default_spi = %s;\n", p = cfg_escape(default_spi)); free(p);
|
||||
|
||||
dev_info("\n#\n# PROGRAMMER DEFINITIONS\n#\n\n");
|
||||
}
|
||||
|
||||
if(dev_opt_c)
|
||||
dev_output_pgm_defs(cfg_strdup("main()", programmer));
|
||||
|
||||
if(dev_opt_p == 2 && dev_opt_c)
|
||||
dev_info("\n");
|
||||
if(dev_opt_p == 2)
|
||||
dev_info("#\n# PART DEFINITIONS\n#\n");
|
||||
|
||||
if(dev_opt_p)
|
||||
dev_output_part_defs(cfg_strdup("main()", partdesc));
|
||||
}
|
||||
|
||||
|
||||
// -p */[cdosw*]
|
||||
// -p */[dASsrcow*t]
|
||||
void dev_output_part_defs(char *partdesc) {
|
||||
bool cmdok, waits, opspi, descs, strct, cmpst, raw, all, tsv;
|
||||
bool cmdok, waits, opspi, descs, astrc, strct, cmpst, raw, all, tsv;
|
||||
char *flags;
|
||||
int nprinted;
|
||||
AVRPART *nullpart = avr_new_part();
|
||||
|
@ -609,10 +724,10 @@ void dev_output_part_defs(char *partdesc) {
|
|||
if((flags = strchr(partdesc, '/')))
|
||||
*flags++ = 0;
|
||||
|
||||
if(!flags && !strcmp(partdesc, "*")) // treat -p * as if it was -p */*
|
||||
flags = "*";
|
||||
if(!flags && !strcmp(partdesc, "*")) // Treat -p * as if it was -p */s
|
||||
flags = "s";
|
||||
|
||||
if(!*flags || !strchr("cdosSrw*t", *flags)) {
|
||||
if(!*flags || !strchr("cdoASsrw*t", *flags)) {
|
||||
dev_info("%s: flags for developer option -p <wildcard>/<flags> not recognised\n", progname);
|
||||
dev_info(
|
||||
"Wildcard examples (these need protecting in the shell through quoting):\n"
|
||||
|
@ -621,24 +736,25 @@ void dev_output_part_defs(char *partdesc) {
|
|||
" *32[0-9] matches ATmega329, ATmega325 and ATmega328\n"
|
||||
" *32? matches ATmega329, ATmega32A, ATmega325 and ATmega328\n"
|
||||
"Flags (one or more of the characters below):\n"
|
||||
" c check and report errors in address bits of SPI commands\n"
|
||||
" d description of core part features\n"
|
||||
" o opcodes for SPI programming parts and memories\n"
|
||||
" S show entries of avrdude.conf parts with all values\n"
|
||||
" s show entries of avrdude.conf parts with necessary values\n"
|
||||
" A show entries of avrdude.conf parts with all values\n"
|
||||
" S show entries of avrdude.conf parts with necessary values\n"
|
||||
" s show short entries of avrdude.conf parts using parent\n"
|
||||
" r show entries of avrdude.conf parts as raw dump\n"
|
||||
" c check and report errors in address bits of SPI commands\n"
|
||||
" o opcodes for SPI programming parts and memories\n"
|
||||
" w wd_... constants for ISP parts\n"
|
||||
" * all of the above except s\n"
|
||||
" * all of the above except s and S\n"
|
||||
" t use tab separated values as much as possible\n"
|
||||
"Examples:\n"
|
||||
" $ avrdude -p ATmega328P/s\n"
|
||||
" $ avrdude -p m328*/st | grep chip_erase_delay\n"
|
||||
" avrdude -p*/r | sort\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"
|
||||
" Leaving no space after -p can be an OK substitute for quoting in shells\n"
|
||||
" /s and /S 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"
|
||||
" Sorted /r output should stay invariant when rearranging avrdude.conf\n"
|
||||
" The /c, /o and /w flags are less generic and may be removed sometime\n"
|
||||
" These options are just to help development, so not further documented\n"
|
||||
|
@ -646,34 +762,35 @@ void dev_output_part_defs(char *partdesc) {
|
|||
return;
|
||||
}
|
||||
|
||||
// redirect stderr to stdout
|
||||
fflush(stderr); fflush(stdout); dup2(1, 2);
|
||||
|
||||
all = *flags == '*';
|
||||
cmdok = all || !!strchr(flags, 'c');
|
||||
descs = all || !!strchr(flags, 'd');
|
||||
opspi = all || !!strchr(flags, 'o');
|
||||
waits = all || !!strchr(flags, 'w');
|
||||
strct = all || !!strchr(flags, 'S');
|
||||
astrc = all || !!strchr(flags, 'A');
|
||||
raw = all || !!strchr(flags, 'r');
|
||||
strct = !!strchr(flags, 'S');
|
||||
cmpst = !!strchr(flags, 's');
|
||||
tsv = !!strchr(flags, 't');
|
||||
|
||||
|
||||
// go through all memories and add them to the memory order list
|
||||
// Go through all memories and add them to the memory order list
|
||||
for(LNODEID ln1 = lfirst(part_list); ln1; ln1 = lnext(ln1)) {
|
||||
AVRPART *p = ldata(ln1);
|
||||
if(p->mem)
|
||||
for(LNODEID lnm=lfirst(p->mem); lnm; lnm=lnext(lnm))
|
||||
avr_add_mem_order(((AVRMEM *) ldata(lnm))->desc);
|
||||
|
||||
// same for aliased memories (though probably not needed)
|
||||
// Same for aliased memories (though probably not needed)
|
||||
if(p->mem_alias)
|
||||
for(LNODEID lnm=lfirst(p->mem_alias); lnm; lnm=lnext(lnm))
|
||||
avr_add_mem_order(((AVRMEM_ALIAS *) ldata(lnm))->desc);
|
||||
}
|
||||
|
||||
nprinted = dev_nprinted;
|
||||
if((nprinted = dev_nprinted)) {
|
||||
dev_info("\n");
|
||||
nprinted = dev_nprinted;
|
||||
}
|
||||
for(LNODEID ln1 = lfirst(part_list); ln1; ln1 = lnext(ln1)) {
|
||||
AVRPART *p = ldata(ln1);
|
||||
int flashsize, flashoffset, flashpagesize, eepromsize , eepromoffset, eeprompagesize;
|
||||
|
@ -687,13 +804,16 @@ void dev_output_part_defs(char *partdesc) {
|
|||
if(!part_match(partdesc, p->desc) && !part_match(partdesc, p->id))
|
||||
continue;
|
||||
|
||||
if(strct || cmpst)
|
||||
dev_part_strct(p, tsv, !cmpst? NULL: p->parent_id? locate_part(part_list, p->parent_id): nullpart);
|
||||
if(astrc || strct || cmpst)
|
||||
dev_part_strct(p, tsv,
|
||||
astrc? NULL:
|
||||
strct? nullpart:
|
||||
p->parent_id && *p->parent_id? locate_part(part_list, p->parent_id): nullpart);
|
||||
|
||||
if(raw)
|
||||
dev_part_raw(p);
|
||||
|
||||
// identify core flash and eeprom parameters
|
||||
// Identify core flash and eeprom parameters
|
||||
|
||||
flashsize = flashoffset = flashpagesize = eepromsize = eepromoffset = eeprompagesize = 0;
|
||||
if(p->mem) {
|
||||
|
@ -712,7 +832,7 @@ void dev_output_part_defs(char *partdesc) {
|
|||
}
|
||||
}
|
||||
|
||||
// "real" entries don't seem to have a space in their desc (a bit hackey)
|
||||
// "Real" entries don't seem to have a space in their desc (a bit hackey)
|
||||
if(flashsize && !strchr(p->desc, ' ')) {
|
||||
int ok, nfuses;
|
||||
AVRMEM *m;
|
||||
|
@ -816,7 +936,7 @@ void dev_output_part_defs(char *partdesc) {
|
|||
} else
|
||||
ok &= ~DEV_SPI_CALIBRATION;
|
||||
|
||||
// actually, some AT90S... parts cannot read, only write lock bits :-0
|
||||
// Actually, some AT90S... parts cannot read, only write lock bits :-0
|
||||
if( ! ((m = avr_locate_mem(p, "lock")) && m->op[AVR_OP_WRITE]))
|
||||
ok &= ~DEV_SPI_LOCK;
|
||||
|
||||
|
@ -863,14 +983,14 @@ void dev_output_part_defs(char *partdesc) {
|
|||
}
|
||||
}
|
||||
|
||||
// print wait delays for AVR family parts
|
||||
// Print wait delays for AVR family parts
|
||||
if(waits) {
|
||||
if(!(p->flags & (AVRPART_HAS_PDI | AVRPART_HAS_UPDI | AVRPART_HAS_TPI | AVRPART_AVR32)))
|
||||
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
|
||||
// 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(m->min_write_delay == m->max_write_delay)
|
||||
|
@ -886,3 +1006,265 @@ void dev_output_part_defs(char *partdesc) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void dev_pgm_raw(PROGRAMMER *pgm) {
|
||||
PROGRAMMER dp;
|
||||
int len, idx;
|
||||
char *id = ldata(lfirst(pgm->id));
|
||||
LNODEID ln;
|
||||
|
||||
memcpy(&dp, pgm, sizeof dp);
|
||||
|
||||
// Dump id, usbpid and hvupdi_support lists
|
||||
for(idx=0, ln=lfirst(dp.id); ln; ln=lnext(ln))
|
||||
dev_raw_dump(ldata(ln), strlen(ldata(ln))+1, id, "id", idx++);
|
||||
for(idx=0, ln=lfirst(dp.usbpid); ln; ln=lnext(ln))
|
||||
dev_raw_dump(ldata(ln), sizeof(int), id, "usbpid", idx++);
|
||||
for(idx=0, ln=lfirst(dp.hvupdi_support); ln; ln=lnext(ln))
|
||||
dev_raw_dump(ldata(ln), sizeof(int), id, "hvupdi_", idx++);
|
||||
|
||||
if(dp.desc)
|
||||
dev_raw_dump(dp.desc, strlen(dp.desc)+1, id, "desc", 0);
|
||||
// Dump cache_string values
|
||||
if(dp.usbdev && *dp.usbdev)
|
||||
dev_raw_dump(dp.usbdev, strlen(dp.usbdev)+1, id, "usbdev", 0);
|
||||
if(dp.usbsn && *dp.usbsn)
|
||||
dev_raw_dump(dp.usbsn, strlen(dp.usbsn)+1, id, "usbsn", 0);
|
||||
if(dp.usbvendor && *dp.usbvendor)
|
||||
dev_raw_dump(dp.usbvendor, strlen(dp.usbvendor)+1, id, "usbvend", 0);
|
||||
if(dp.usbproduct && *dp.usbproduct)
|
||||
dev_raw_dump(dp.usbproduct, strlen(dp.usbproduct)+1, id, "usbprod", 0);
|
||||
|
||||
// Zap all bytes beyond terminating nul of desc, type and port array
|
||||
if((len = strlen(dp.type)+1) < sizeof dp.type)
|
||||
memset(dp.type + len, 0, sizeof dp.type - len);
|
||||
if((len = strlen(dp.port)+1) < sizeof dp.port)
|
||||
memset(dp.port + len, 0, sizeof dp.port - len);
|
||||
|
||||
// Zap address values
|
||||
dp.desc = NULL;
|
||||
dp.id = NULL;
|
||||
dp.comments = NULL;
|
||||
dp.parent_id = 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
|
||||
dev_raw_dump((char *) &dp, offsetof(PROGRAMMER, fd), id, "pgm", 0);
|
||||
}
|
||||
|
||||
|
||||
static const char *connstr(conntype_t conntype) {
|
||||
switch(conntype) {
|
||||
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;
|
||||
COMMENT *cp;
|
||||
int firstid;
|
||||
|
||||
if(!tsv) {
|
||||
const char *del = "#------------------------------------------------------------";
|
||||
cp = locate_comment(pgm->comments, "*", 0);
|
||||
|
||||
if(!cp || !dev_has_subsstr_comms(cp->comms, del)) {
|
||||
dev_info("%s\n# ", del);
|
||||
for(firstid=1, ln=lfirst(pgm->id); ln; ln=lnext(ln)) {
|
||||
if(!firstid)
|
||||
dev_info("/");
|
||||
firstid = 0;
|
||||
dev_info("%s", ldata(ln));
|
||||
}
|
||||
dev_info("\n%s\n\n", del);
|
||||
}
|
||||
if(cp)
|
||||
dev_print_comment(cp->comms);
|
||||
|
||||
if(pgm->parent_id && *pgm->parent_id)
|
||||
dev_info("programmer parent \"%s\"\n", pgm->parent_id);
|
||||
else
|
||||
dev_info("programmer\n");
|
||||
}
|
||||
|
||||
if(tsv)
|
||||
dev_info(".prog\t%s\tid\t", id);
|
||||
else {
|
||||
dev_cout(pgm->comments, "id", 0, 0);
|
||||
dev_info(" %-19s = ", "id");
|
||||
}
|
||||
for(firstid=1, ln=lfirst(pgm->id); ln; ln=lnext(ln)) {
|
||||
if(!firstid)
|
||||
dev_info(", ");
|
||||
firstid = 0;
|
||||
char *str = cfg_escape(ldata(ln));
|
||||
dev_info("%s", str);
|
||||
free(str);
|
||||
}
|
||||
if(tsv)
|
||||
dev_info("\n");
|
||||
else {
|
||||
dev_info(";");
|
||||
dev_cout(pgm->comments, "id", 1, 1);
|
||||
}
|
||||
|
||||
_if_pgmout_str(strcmp, cfg_escape(pgm->desc), desc);
|
||||
_pgmout_fmt("type", "\"%s\"", locate_programmer_type_id(pgm->initpgm));
|
||||
if(!base || base->conntype != pgm->conntype)
|
||||
_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_cout(pgm->comments, "usbpid", 0, 0);
|
||||
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));
|
||||
}
|
||||
if(tsv)
|
||||
dev_info("\n");
|
||||
else {
|
||||
dev_info(";");
|
||||
dev_cout(pgm->comments, "usbpid", 1, 1);
|
||||
}
|
||||
}
|
||||
|
||||
_if_pgmout_str(strcmp, cfg_escape(pgm->usbdev), usbdev);
|
||||
_if_pgmout_str(strcmp, cfg_escape(pgm->usbsn), usbsn);
|
||||
_if_pgmout_str(strcmp, cfg_escape(pgm->usbvendor), usbvendor);
|
||||
_if_pgmout_str(strcmp, cfg_escape(pgm->usbproduct), 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_cout(pgm->comments, "hvupdi_support", 0, 0);
|
||||
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));
|
||||
}
|
||||
if(tsv)
|
||||
dev_info("\n");
|
||||
else {
|
||||
dev_info(";");
|
||||
dev_cout(pgm->comments, "hvupdi_support", 1, 1);
|
||||
}
|
||||
}
|
||||
|
||||
if(!tsv) {
|
||||
dev_cout(pgm->comments, ";", 0, 0);
|
||||
dev_info(";\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// -c */[ASsrt]
|
||||
void dev_output_pgm_defs(char *pgmid) {
|
||||
bool astrc, strct, cmpst, raw, tsv;
|
||||
char *flags;
|
||||
int nprinted;
|
||||
PROGRAMMER *nullpgm = pgm_new();
|
||||
|
||||
if((flags = strchr(pgmid, '/')))
|
||||
*flags++ = 0;
|
||||
|
||||
if(!flags && !strcmp(pgmid, "*")) // Treat -c * as if it was -c */s
|
||||
flags = "s";
|
||||
|
||||
if(!*flags || !strchr("ASsrt", *flags)) {
|
||||
dev_info("%s: flags for developer option -c <wildcard>/<flags> not recognised\n", progname);
|
||||
dev_info(
|
||||
"Wildcard examples (these need protecting in the shell through quoting):\n"
|
||||
" * all known programmers\n"
|
||||
" avrftdi just this programmer\n"
|
||||
" jtag*pdi matches jtag2pdi, jtag3pdi, jtag3updi and jtag2updi\n"
|
||||
" jtag?pdi matches jtag2pdi and jtag3pdi\n"
|
||||
"Flags (one or more of the characters below):\n"
|
||||
" A show entries of avrdude.conf programmers with all values\n"
|
||||
" S show entries of avrdude.conf programmers with necessary values\n"
|
||||
" s show short entries of avrdude.conf programmers using parent\n"
|
||||
" r show entries of avrdude.conf programmers as raw dump\n"
|
||||
" t use tab separated values as much as possible\n"
|
||||
"Examples:\n"
|
||||
" $ avrdude -c usbasp/s\n"
|
||||
" $ avrdude -c */st | grep baudrate\n"
|
||||
" $ avrdude -c */r | sort\n"
|
||||
"Notes:\n"
|
||||
" -c * is the same as -c */s\n"
|
||||
" This help message is printed using any unrecognised flag, eg, -c/h\n"
|
||||
" Leaving no space after -c 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"
|
||||
" Sorted /r output should stay invariant when rearranging avrdude.conf\n"
|
||||
" These options are just to help development, so not further documented\n"
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
astrc = !!strchr(flags, 'A');
|
||||
strct = !!strchr(flags, 'S');
|
||||
cmpst = !!strchr(flags, 's');
|
||||
raw = !!strchr(flags, 'r');
|
||||
tsv = !!strchr(flags, 't');
|
||||
|
||||
nprinted = dev_nprinted;
|
||||
|
||||
LNODEID ln1, ln2;
|
||||
for(ln1=lfirst(programmers); ln1; ln1=lnext(ln1)) {
|
||||
PROGRAMMER *pgm = ldata(ln1);
|
||||
int matched = 0;
|
||||
for(ln2=lfirst(pgm->id); ln2; ln2=lnext(ln2)) {
|
||||
if(part_match(pgmid, ldata(ln2))) {
|
||||
matched = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(!matched)
|
||||
continue;
|
||||
|
||||
if(dev_nprinted > nprinted) {
|
||||
dev_info("\n");
|
||||
nprinted = dev_nprinted;
|
||||
}
|
||||
|
||||
if(astrc || strct || cmpst)
|
||||
dev_pgm_strct(pgm, tsv,
|
||||
astrc? NULL:
|
||||
strct? nullpgm:
|
||||
pgm->parent_id && *pgm->parent_id? locate_programmer(programmers, pgm->parent_id): nullpgm);
|
||||
|
||||
if(raw)
|
||||
dev_pgm_raw(pgm);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,6 +19,8 @@
|
|||
#ifndef developer_opts_h
|
||||
#define developer_opts_h
|
||||
|
||||
void dev_output_pgm_part(int dev_opt_c, char *programmer, int dev_opt_p, char *partdesc);
|
||||
void dev_output_part_defs(char *partdesc);
|
||||
void dev_output_pgm_defs(char *programmer);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -51,66 +51,90 @@ static int dev_message(int msglvl, const char *fmt, ...);
|
|||
#define dev_notice(...) dev_message(DEV_NOTICE, __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), pgm->comments)
|
||||
|
||||
#define _pgmout_fmt(name, fmt, what) \
|
||||
dev_part_strct_entry(tsv, ".prog", id, NULL, name, dev_sprintf(fmt, what), pgm->comments)
|
||||
|
||||
#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), pgm->comments); \
|
||||
} while(0)
|
||||
|
||||
// Result must be a malloc'd string
|
||||
#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, pgm->comments); \
|
||||
} while(0)
|
||||
|
||||
|
||||
#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), p->comments)
|
||||
|
||||
#define _if_partout(cmp, fmt, component) do { \
|
||||
if(!base || cmp(base->component, p->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), p->comments); \
|
||||
} while(0)
|
||||
|
||||
#define _if_n_partout(cmp, n, fmt, component) do { \
|
||||
if(!base || cmp(base->component, p->component, n)) \
|
||||
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), p->comments); \
|
||||
} while(0)
|
||||
|
||||
// Result must be a malloc'd string
|
||||
#define _partout_str(result, component) \
|
||||
dev_part_strct_entry(tsv, ".pt", p->desc, NULL, #component, result)
|
||||
dev_part_strct_entry(tsv, ".pt", p->desc, NULL, #component, result, p->comments)
|
||||
|
||||
// Result must be a malloc'd string
|
||||
#define _if_partout_str(cmp, result, component) do { \
|
||||
if(!base || cmp(base->component, p->component)) \
|
||||
dev_part_strct_entry(tsv, ".pt", p->desc, NULL, #component, result); \
|
||||
dev_part_strct_entry(tsv, ".pt", p->desc, NULL, #component, result, p->comments); \
|
||||
} while(0)
|
||||
|
||||
// Result must be a malloc'd string
|
||||
#define _if_n_partout_str(cmp, n, result, component) do { \
|
||||
if(!base || cmp(base->component, p->component, n)) \
|
||||
dev_part_strct_entry(tsv, ".pt", p->desc, NULL, #component, result); \
|
||||
dev_part_strct_entry(tsv, ".pt", p->desc, NULL, #component, result, p->comments); \
|
||||
} while(0)
|
||||
|
||||
|
||||
#define _memout(fmt, component) \
|
||||
dev_part_strct_entry(tsv, ".ptmm", p->desc, m->desc, #component, dev_sprintf(fmt, m->component))
|
||||
dev_part_strct_entry(tsv, ".ptmm", p->desc, m->desc, #component, dev_sprintf(fmt, m->component), m->comments)
|
||||
|
||||
#define _if_memout(cmp, fmt, component) do { \
|
||||
if(!bm || cmp(bm->component, m->component)) \
|
||||
dev_part_strct_entry(tsv, ".ptmm", p->desc, m->desc, #component, dev_sprintf(fmt, m->component)); \
|
||||
dev_part_strct_entry(tsv, ".ptmm", p->desc, m->desc, #component, dev_sprintf(fmt, m->component), m->comments); \
|
||||
} while(0)
|
||||
|
||||
// Result must be a malloc'd string
|
||||
#define _memout_str(result, component) \
|
||||
dev_part_strct_entry(tsv, ".ptmm", p->desc, m->desc, #component, result)
|
||||
dev_part_strct_entry(tsv, ".ptmm", p->desc, m->desc, #component, result, m->comments)
|
||||
|
||||
// Result must be a malloc'd string
|
||||
#define _if_n_memout_str(cmp, n, result, component) do { \
|
||||
if(!bm || cmp(bm->component, m->component, n)) \
|
||||
dev_part_strct_entry(tsv, ".ptmm", p->desc, m->desc, #component, result); \
|
||||
dev_part_strct_entry(tsv, ".ptmm", p->desc, m->desc, #component, result, m->comments); \
|
||||
} while(0)
|
||||
|
||||
#define _memout_yn(component) \
|
||||
dev_part_strct_entry(tsv, ".ptmm", p->desc, m->desc, #component, strdup(m->component? "yes": "no"))
|
||||
dev_part_strct_entry(tsv, ".ptmm", p->desc, m->desc, #component, cfg_strdup("_memout_yn()", m->component? "yes": "no"), m->comments)
|
||||
|
||||
#define _if_memout_yn(component) do { \
|
||||
if(!bm || bm->component != m->component) \
|
||||
dev_part_strct_entry(tsv, ".ptmm", p->desc, m->desc, #component, strdup(m->component? "yes": "no")); \
|
||||
dev_part_strct_entry(tsv, ".ptmm", p->desc, m->desc, #component, cfg_strdup("_if_memout_yn()", m->component? "yes": "no"), m->comments); \
|
||||
} while(0)
|
||||
|
||||
#define _flagout(mask, name) \
|
||||
_partout_str(strdup(p->flags & (mask)? "yes": "no"), name)
|
||||
_partout_str(cfg_strdup("_flagout()", p->flags & (mask)? "yes": "no"), name)
|
||||
|
||||
#define _if_flagout(mask, name) do { \
|
||||
if(!base || (base->flags & (mask)) != (p->flags & (mask))) \
|
||||
_partout_str(strdup(p->flags & (mask)? "yes": "no"), name); \
|
||||
_partout_str(cfg_strdup("_if_flagout()", p->flags & (mask)? "yes": "no"), name); \
|
||||
} while(0)
|
||||
|
||||
// Result must be a malloc'd string
|
||||
#define _cmderr(result, component) \
|
||||
dev_part_strct_entry(tsv, ".cmderr", p->desc, m->desc, #component, result)
|
||||
dev_part_strct_entry(tsv, ".cmderr", p->desc, m->desc, #component, result, NULL)
|
||||
|
||||
#endif
|
||||
|
|
|
@ -851,7 +851,7 @@ static int ft245r_open(PROGRAMMER * pgm, char * port) {
|
|||
avrdude_message(MSG_NOTICE,
|
||||
"%s: ft245r_open(): no device identifier in portname, using default\n",
|
||||
progname);
|
||||
pgm->usbsn[0] = 0;
|
||||
pgm->usbsn = cache_string("");
|
||||
devnum = 0;
|
||||
} else {
|
||||
if (strlen(device) == 8 ){ // serial number
|
||||
|
@ -863,7 +863,7 @@ static int ft245r_open(PROGRAMMER * pgm, char * port) {
|
|||
device);
|
||||
}
|
||||
// copy serial number to pgm struct
|
||||
strcpy(pgm->usbsn, device);
|
||||
pgm->usbsn = cache_string(device);
|
||||
// and use first device with matching serial (should be unique)
|
||||
devnum = 0;
|
||||
}
|
||||
|
|
|
@ -609,7 +609,7 @@ static int jtagmkI_initialize(PROGRAMMER * pgm, AVRPART * p)
|
|||
if (jtagmkI_reset(pgm) < 0)
|
||||
return -1;
|
||||
|
||||
strcpy(hfuse.desc, "hfuse");
|
||||
hfuse.desc = cache_string("hfuse");
|
||||
if (jtagmkI_read_byte(pgm, p, &hfuse, 1, &b) < 0)
|
||||
return -1;
|
||||
if ((b & OCDEN) != 0)
|
||||
|
|
|
@ -488,7 +488,6 @@ static int jtagmkII_recv_frame(PROGRAMMER * pgm, unsigned char **msg,
|
|||
int rv;
|
||||
unsigned char c, *buf = NULL, header[8];
|
||||
unsigned short r_seqno = 0;
|
||||
unsigned short checksum = 0;
|
||||
|
||||
struct timeval tv;
|
||||
double timeoutval = 100; /* seconds */
|
||||
|
@ -521,7 +520,6 @@ static int jtagmkII_recv_frame(PROGRAMMER * pgm, unsigned char **msg,
|
|||
if (serial_recv(&pgm->fd, &c, 1) != 0)
|
||||
goto timedout;
|
||||
}
|
||||
checksum ^= c;
|
||||
|
||||
if (state < sDATA)
|
||||
header[headeridx++] = c;
|
||||
|
@ -1439,7 +1437,7 @@ static int jtagmkII_initialize(PROGRAMMER * pgm, AVRPART * p)
|
|||
}
|
||||
|
||||
if ((pgm->flag & PGM_FL_IS_JTAG) && !(p->flags & (AVRPART_HAS_PDI | AVRPART_HAS_UPDI))) {
|
||||
strcpy(hfuse.desc, "hfuse");
|
||||
hfuse.desc = cache_string("hfuse");
|
||||
if (jtagmkII_read_byte(pgm, p, &hfuse, 1, &b) < 0)
|
||||
return -1;
|
||||
if ((b & OCDEN) != 0)
|
||||
|
|
281
src/lexer.l
281
src/lexer.l
|
@ -39,15 +39,21 @@
|
|||
#define YYERRCODE 256
|
||||
#endif
|
||||
|
||||
/* capture lvalue keywords to associate comments with that assignment */
|
||||
#define ccap() capture_lvalue_kw(yytext, cfg_lineno)
|
||||
|
||||
static void adjust_cfg_lineno(const char *p) {
|
||||
while(*p)
|
||||
if(*p++ == '\n')
|
||||
cfg_lineno++;
|
||||
}
|
||||
|
||||
%}
|
||||
|
||||
DIGIT [0-9]
|
||||
HEXDIGIT [0-9a-fA-F]
|
||||
SIGN [+-]
|
||||
|
||||
%x strng
|
||||
%x incl
|
||||
%x comment
|
||||
%option nounput
|
||||
|
||||
/* Bump resources for classic lex. */
|
||||
|
@ -61,19 +67,34 @@ SIGN [+-]
|
|||
{SIGN}?{DIGIT}+"."{DIGIT}* { yylval = number_real(yytext); return TKN_NUMBER_REAL; }
|
||||
{SIGN}?"."{DIGIT}+ { yylval = number_real(yytext); return TKN_NUMBER_REAL; }
|
||||
|
||||
"\"" { string_buf_ptr = string_buf; BEGIN(strng); }
|
||||
["]([^"\\\n]|\\.|\\\n)*["] {
|
||||
char *str= cfg_strdup("lexer.l", yytext);
|
||||
cfg_unescape(str, str+1);
|
||||
size_t len = strlen(str);
|
||||
if(len)
|
||||
str[len-1] = 0;
|
||||
yylval = string(str);
|
||||
free(str);
|
||||
return TKN_STRING;
|
||||
}
|
||||
|
||||
0x{HEXDIGIT}+ { yylval = hexnumber(yytext); return TKN_NUMBER; }
|
||||
|
||||
#\n#\ PROGRAMMER\ DEFINITIONS\n#\n+ { /* Record comments so far as prologue and skip */
|
||||
cfg_capture_prologue();
|
||||
adjust_cfg_lineno(yytext);
|
||||
}
|
||||
|
||||
#\n#\ PART\ DEFINITIONS\n#\n+ { /* Ignore part definions header */
|
||||
adjust_cfg_lineno(yytext);
|
||||
}
|
||||
|
||||
# { /* The following eats '#' style comments to end of line */
|
||||
BEGIN(comment); }
|
||||
<comment>[^\n] { /* eat comments */ }
|
||||
<comment>\n { cfg_lineno++; BEGIN(INITIAL); }
|
||||
[ \t]*#[^\n]*\n+ { /* Record and skip # comments including preceding white space */
|
||||
capture_comment_str(yytext, cfg_lineno);
|
||||
adjust_cfg_lineno(yytext);
|
||||
}
|
||||
|
||||
|
||||
"/*" { /* The following eats multiline C style comments */
|
||||
"/*" { /* The following eats multiline C style comments, they are not captured */
|
||||
int c;
|
||||
int comment_start;
|
||||
|
||||
|
@ -100,152 +121,138 @@ SIGN [+-]
|
|||
}
|
||||
|
||||
|
||||
<strng>\" { *string_buf_ptr = 0; string_buf_ptr = string_buf;
|
||||
yylval = string(string_buf_ptr); BEGIN(INITIAL); return TKN_STRING; }
|
||||
<strng>\\n *string_buf_ptr++ = '\n';
|
||||
<strng>\\t *string_buf_ptr++ = '\t';
|
||||
<strng>\\r *string_buf_ptr++ = '\r';
|
||||
<strng>\\b *string_buf_ptr++ = '\b';
|
||||
<strng>\\f *string_buf_ptr++ = '\f';
|
||||
<strng>\\(.|\n) *(string_buf_ptr++) = yytext[1];
|
||||
<strng>[^\\\n\"]+ { char *yptr = yytext; while (*yptr)
|
||||
*(string_buf_ptr++) = *(yptr++); }
|
||||
|
||||
<strng>\n { yyerror("unterminated character constant");
|
||||
return YYERRCODE; }
|
||||
|
||||
alias { yylval=NULL; return K_ALIAS; }
|
||||
allowfullpagebitstream { yylval=NULL; return K_ALLOWFULLPAGEBITSTREAM; }
|
||||
avr910_devcode { yylval=NULL; return K_AVR910_DEVCODE; }
|
||||
allowfullpagebitstream { yylval=NULL; ccap(); return K_ALLOWFULLPAGEBITSTREAM; }
|
||||
avr910_devcode { yylval=NULL; ccap(); return K_AVR910_DEVCODE; }
|
||||
bank_size { yylval=NULL; return K_PAGE_SIZE; }
|
||||
banked { yylval=NULL; return K_PAGED; }
|
||||
baudrate { yylval=NULL; return K_BAUDRATE; }
|
||||
blocksize { yylval=NULL; return K_BLOCKSIZE; }
|
||||
bs2 { yylval=NULL; return K_BS2; }
|
||||
buff { yylval=NULL; return K_BUFF; }
|
||||
bytedelay { yylval=NULL; return K_BYTEDELAY; }
|
||||
chip_erase { yylval=new_token(K_CHIP_ERASE); return K_CHIP_ERASE; }
|
||||
chip_erase_delay { yylval=NULL; return K_CHIP_ERASE_DELAY; }
|
||||
chiperasepolltimeout { yylval=NULL; return K_CHIPERASEPOLLTIMEOUT; }
|
||||
chiperasepulsewidth { yylval=NULL; return K_CHIPERASEPULSEWIDTH; }
|
||||
chiperasetime { yylval=NULL; return K_CHIPERASETIME; }
|
||||
cmdexedelay { yylval=NULL; return K_CMDEXEDELAY; }
|
||||
connection_type { yylval=NULL; return K_CONNTYPE; }
|
||||
baudrate { yylval=NULL; ccap(); return K_BAUDRATE; }
|
||||
blocksize { yylval=NULL; ccap(); return K_BLOCKSIZE; }
|
||||
bs2 { yylval=NULL; ccap(); return K_BS2; }
|
||||
buff { yylval=NULL; ccap(); return K_BUFF; }
|
||||
bytedelay { yylval=NULL; ccap(); return K_BYTEDELAY; }
|
||||
chip_erase { yylval=new_token(K_CHIP_ERASE); ccap(); return K_CHIP_ERASE; }
|
||||
chip_erase_delay { yylval=NULL; ccap(); return K_CHIP_ERASE_DELAY; }
|
||||
chiperasepolltimeout { yylval=NULL; ccap(); return K_CHIPERASEPOLLTIMEOUT; }
|
||||
chiperasepulsewidth { yylval=NULL; ccap(); return K_CHIPERASEPULSEWIDTH; }
|
||||
chiperasetime { yylval=NULL; ccap(); return K_CHIPERASETIME; }
|
||||
cmdexedelay { yylval=NULL; ccap(); return K_CMDEXEDELAY; }
|
||||
connection_type { yylval=NULL; ccap(); return K_CONNTYPE; }
|
||||
dedicated { yylval=new_token(K_DEDICATED); return K_DEDICATED; }
|
||||
default_bitclock { yylval=NULL; return K_DEFAULT_BITCLOCK; }
|
||||
default_parallel { yylval=NULL; return K_DEFAULT_PARALLEL; }
|
||||
default_programmer { yylval=NULL; return K_DEFAULT_PROGRAMMER; }
|
||||
default_serial { yylval=NULL; return K_DEFAULT_SERIAL; }
|
||||
default_spi { yylval=NULL; return K_DEFAULT_SPI; }
|
||||
delay { yylval=NULL; return K_DELAY; }
|
||||
desc { yylval=NULL; return K_DESC; }
|
||||
family_id { yylval=NULL; return K_FAMILY_ID; }
|
||||
devicecode { yylval=NULL; return K_DEVICECODE; }
|
||||
eecr { yylval=NULL; return K_EECR; }
|
||||
delay { yylval=NULL; ccap(); return K_DELAY; }
|
||||
desc { yylval=NULL; ccap(); return K_DESC; }
|
||||
devicecode { yylval=NULL; ccap(); return K_DEVICECODE; }
|
||||
eecr { yylval=NULL; ccap(); return K_EECR; }
|
||||
eeprom { yylval=NULL; return K_EEPROM; }
|
||||
eeprom_instr { yylval=NULL; return K_EEPROM_INSTR; }
|
||||
enablepageprogramming { yylval=NULL; return K_ENABLEPAGEPROGRAMMING; }
|
||||
errled { yylval=NULL; return K_ERRLED; }
|
||||
eeprom_instr { yylval=NULL; ccap(); return K_EEPROM_INSTR; }
|
||||
enablepageprogramming { yylval=NULL; ccap(); return K_ENABLEPAGEPROGRAMMING; }
|
||||
errled { yylval=NULL; ccap(); return K_ERRLED; }
|
||||
family_id { yylval=NULL; ccap(); return K_FAMILY_ID; }
|
||||
flash { yylval=NULL; return K_FLASH; }
|
||||
flash_instr { yylval=NULL; return K_FLASH_INSTR; }
|
||||
has_debugwire { yylval=NULL; return K_HAS_DW; }
|
||||
has_jtag { yylval=NULL; return K_HAS_JTAG; }
|
||||
has_pdi { yylval=NULL; return K_HAS_PDI; }
|
||||
has_tpi { yylval=NULL; return K_HAS_TPI; }
|
||||
has_updi { yylval=NULL; return K_HAS_UPDI; }
|
||||
hventerstabdelay { yylval=NULL; return K_HVENTERSTABDELAY; }
|
||||
hvleavestabdelay { yylval=NULL; return K_HVLEAVESTABDELAY; }
|
||||
hvsp_controlstack { yylval=NULL; return K_HVSP_CONTROLSTACK; }
|
||||
hvspcmdexedelay { yylval=NULL; return K_HVSPCMDEXEDELAY; }
|
||||
hvupdi_support { yylval=NULL; return K_HVUPDI_SUPPORT; }
|
||||
hvupdi_variant { yylval=NULL; return K_HVUPDI_VARIANT; }
|
||||
id { yylval=NULL; return K_ID; }
|
||||
idr { yylval=NULL; return K_IDR; }
|
||||
flash_instr { yylval=NULL; ccap(); return K_FLASH_INSTR; }
|
||||
has_debugwire { yylval=NULL; ccap(); return K_HAS_DW; }
|
||||
has_jtag { yylval=NULL; ccap(); return K_HAS_JTAG; }
|
||||
has_pdi { yylval=NULL; ccap(); return K_HAS_PDI; }
|
||||
has_tpi { yylval=NULL; ccap(); return K_HAS_TPI; }
|
||||
has_updi { yylval=NULL; ccap(); return K_HAS_UPDI; }
|
||||
hventerstabdelay { yylval=NULL; ccap(); return K_HVENTERSTABDELAY; }
|
||||
hvleavestabdelay { yylval=NULL; ccap(); return K_HVLEAVESTABDELAY; }
|
||||
hvsp_controlstack { yylval=NULL; ccap(); return K_HVSP_CONTROLSTACK; }
|
||||
hvspcmdexedelay { yylval=NULL; ccap(); return K_HVSPCMDEXEDELAY; }
|
||||
hvupdi_support { yylval=NULL; ccap(); return K_HVUPDI_SUPPORT; }
|
||||
hvupdi_variant { yylval=NULL; ccap(); return K_HVUPDI_VARIANT; }
|
||||
id { yylval=NULL; ccap(); return K_ID; }
|
||||
idr { yylval=NULL; ccap(); return K_IDR; }
|
||||
io { yylval=new_token(K_IO); return K_IO; }
|
||||
is_at90s1200 { yylval=NULL; return K_IS_AT90S1200; }
|
||||
is_avr32 { yylval=NULL; return K_IS_AVR32; }
|
||||
latchcycles { yylval=NULL; return K_LATCHCYCLES; }
|
||||
load_ext_addr { yylval=new_token(K_LOAD_EXT_ADDR); return K_LOAD_EXT_ADDR; }
|
||||
loadpage_hi { yylval=new_token(K_LOADPAGE_HI); return K_LOADPAGE_HI; }
|
||||
loadpage_lo { yylval=new_token(K_LOADPAGE_LO); return K_LOADPAGE_LO; }
|
||||
max_write_delay { yylval=NULL; return K_MAX_WRITE_DELAY; }
|
||||
mcu_base { yylval=NULL; return K_MCU_BASE; }
|
||||
memory { yylval=NULL; return K_MEMORY; }
|
||||
min_write_delay { yylval=NULL; return K_MIN_WRITE_DELAY; }
|
||||
miso { yylval=NULL; return K_MISO; }
|
||||
mode { yylval=NULL; return K_MODE; }
|
||||
mosi { yylval=NULL; return K_MOSI; }
|
||||
is_at90s1200 { yylval=NULL; ccap(); return K_IS_AT90S1200; }
|
||||
is_avr32 { yylval=NULL; ccap(); return K_IS_AVR32; }
|
||||
latchcycles { yylval=NULL; ccap(); return K_LATCHCYCLES; }
|
||||
load_ext_addr { yylval=new_token(K_LOAD_EXT_ADDR); ccap(); return K_LOAD_EXT_ADDR; }
|
||||
loadpage_hi { yylval=new_token(K_LOADPAGE_HI); ccap(); return K_LOADPAGE_HI; }
|
||||
loadpage_lo { yylval=new_token(K_LOADPAGE_LO); ccap(); return K_LOADPAGE_LO; }
|
||||
max_write_delay { yylval=NULL; ccap(); return K_MAX_WRITE_DELAY; }
|
||||
mcu_base { yylval=NULL; ccap(); return K_MCU_BASE; }
|
||||
memory { yylval=NULL; ccap(); return K_MEMORY; }
|
||||
min_write_delay { yylval=NULL; ccap(); return K_MIN_WRITE_DELAY; }
|
||||
miso { yylval=NULL; ccap(); return K_MISO; }
|
||||
mode { yylval=NULL; ccap(); return K_MODE; }
|
||||
mosi { yylval=NULL; ccap(); return K_MOSI; }
|
||||
no { yylval=new_token(K_NO); return K_NO; }
|
||||
NULL { yylval=NULL; return K_NULL; }
|
||||
num_banks { yylval=NULL; return K_NUM_PAGES; }
|
||||
num_pages { yylval=NULL; return K_NUM_PAGES; }
|
||||
nvm_base { yylval=NULL; return K_NVM_BASE; }
|
||||
ocd_base { yylval=NULL; return K_OCD_BASE; }
|
||||
ocdrev { yylval=NULL; return K_OCDREV; }
|
||||
offset { yylval=NULL; return K_OFFSET; }
|
||||
page_size { yylval=NULL; return K_PAGE_SIZE; }
|
||||
paged { yylval=NULL; return K_PAGED; }
|
||||
pagel { yylval=NULL; return K_PAGEL; }
|
||||
parallel { yylval=NULL; return K_PARALLEL; }
|
||||
num_pages { yylval=NULL; ccap(); return K_NUM_PAGES; }
|
||||
nvm_base { yylval=NULL; ccap(); return K_NVM_BASE; }
|
||||
ocd_base { yylval=NULL; ccap(); return K_OCD_BASE; }
|
||||
ocdrev { yylval=NULL; ccap(); return K_OCDREV; }
|
||||
offset { yylval=NULL; ccap(); return K_OFFSET; }
|
||||
paged { yylval=NULL; ccap(); return K_PAGED; }
|
||||
pagel { yylval=NULL; ccap(); return K_PAGEL; }
|
||||
page_size { yylval=NULL; ccap(); return K_PAGE_SIZE; }
|
||||
parallel { yylval=NULL; ccap(); return K_PARALLEL; }
|
||||
parent { yylval=NULL; return K_PARENT; }
|
||||
part { yylval=NULL; return K_PART; }
|
||||
pgm_enable { yylval=new_token(K_PGM_ENABLE); return K_PGM_ENABLE; }
|
||||
pgmled { yylval=NULL; return K_PGMLED; }
|
||||
pollindex { yylval=NULL; return K_POLLINDEX; }
|
||||
pollmethod { yylval=NULL; return K_POLLMETHOD; }
|
||||
pollvalue { yylval=NULL; return K_POLLVALUE; }
|
||||
postdelay { yylval=NULL; return K_POSTDELAY; }
|
||||
poweroffdelay { yylval=NULL; return K_POWEROFFDELAY; }
|
||||
pp_controlstack { yylval=NULL; return K_PP_CONTROLSTACK; }
|
||||
predelay { yylval=NULL; return K_PREDELAY; }
|
||||
progmodedelay { yylval=NULL; return K_PROGMODEDELAY; }
|
||||
programfusepolltimeout { yylval=NULL; return K_PROGRAMFUSEPOLLTIMEOUT; }
|
||||
programfusepulsewidth { yylval=NULL; return K_PROGRAMFUSEPULSEWIDTH; }
|
||||
programlockpolltimeout { yylval=NULL; return K_PROGRAMLOCKPOLLTIMEOUT; }
|
||||
programlockpulsewidth { yylval=NULL; return K_PROGRAMLOCKPULSEWIDTH; }
|
||||
programmer { yylval=NULL; return K_PROGRAMMER; }
|
||||
part { yylval=NULL; ccap(); return K_PART; }
|
||||
pgm_enable { yylval=new_token(K_PGM_ENABLE); ccap(); return K_PGM_ENABLE; }
|
||||
pgmled { yylval=NULL; ccap(); return K_PGMLED; }
|
||||
pollindex { yylval=NULL; ccap(); return K_POLLINDEX; }
|
||||
pollmethod { yylval=NULL; ccap(); return K_POLLMETHOD; }
|
||||
pollvalue { yylval=NULL; ccap(); return K_POLLVALUE; }
|
||||
postdelay { yylval=NULL; ccap(); return K_POSTDELAY; }
|
||||
poweroffdelay { yylval=NULL; ccap(); return K_POWEROFFDELAY; }
|
||||
pp_controlstack { yylval=NULL; ccap(); return K_PP_CONTROLSTACK; }
|
||||
predelay { yylval=NULL; ccap(); return K_PREDELAY; }
|
||||
progmodedelay { yylval=NULL; ccap(); return K_PROGMODEDELAY; }
|
||||
programfusepolltimeout { yylval=NULL; ccap(); return K_PROGRAMFUSEPOLLTIMEOUT; }
|
||||
programfusepulsewidth { yylval=NULL; ccap(); return K_PROGRAMFUSEPULSEWIDTH; }
|
||||
programlockpolltimeout { yylval=NULL; ccap(); return K_PROGRAMLOCKPOLLTIMEOUT; }
|
||||
programlockpulsewidth { yylval=NULL; ccap(); return K_PROGRAMLOCKPULSEWIDTH; }
|
||||
programmer { yylval=NULL; ccap(); return K_PROGRAMMER; }
|
||||
pseudo { yylval=new_token(K_PSEUDO); return K_PSEUDO; }
|
||||
pwroff_after_write { yylval=NULL; return K_PWROFF_AFTER_WRITE; }
|
||||
rampz { yylval=NULL; return K_RAMPZ; }
|
||||
rdyled { yylval=NULL; return K_RDYLED; }
|
||||
read { yylval=new_token(K_READ); return K_READ; }
|
||||
read_hi { yylval=new_token(K_READ_HI); return K_READ_HI; }
|
||||
read_lo { yylval=new_token(K_READ_LO); return K_READ_LO; }
|
||||
readback { yylval=NULL; return K_READBACK; }
|
||||
readback_p1 { yylval=NULL; return K_READBACK_P1; }
|
||||
readback_p2 { yylval=NULL; return K_READBACK_P2; }
|
||||
readsize { yylval=NULL; return K_READSIZE; }
|
||||
reset { yylval=new_token(K_RESET); return K_RESET; }
|
||||
resetdelay { yylval=NULL; return K_RESETDELAY; }
|
||||
resetdelayms { yylval=NULL; return K_RESETDELAYMS; }
|
||||
resetdelayus { yylval=NULL; return K_RESETDELAYUS; }
|
||||
retry_pulse { yylval=NULL; return K_RETRY_PULSE; }
|
||||
sck { yylval=new_token(K_SCK); return K_SCK; }
|
||||
serial { yylval=NULL; return K_SERIAL; }
|
||||
signature { yylval=NULL; return K_SIGNATURE; }
|
||||
size { yylval=NULL; return K_SIZE; }
|
||||
pwroff_after_write { yylval=NULL; ccap(); return K_PWROFF_AFTER_WRITE; }
|
||||
rampz { yylval=NULL; ccap(); return K_RAMPZ; }
|
||||
rdyled { yylval=NULL; ccap(); return K_RDYLED; }
|
||||
read { yylval=new_token(K_READ); ccap(); return K_READ; }
|
||||
read_hi { yylval=new_token(K_READ_HI); ccap(); return K_READ_HI; }
|
||||
read_lo { yylval=new_token(K_READ_LO); ccap(); return K_READ_LO; }
|
||||
readback { yylval=NULL; ccap(); return K_READBACK; }
|
||||
readback_p1 { yylval=NULL; ccap(); return K_READBACK_P1; }
|
||||
readback_p2 { yylval=NULL; ccap(); return K_READBACK_P2; }
|
||||
readsize { yylval=NULL; ccap(); return K_READSIZE; }
|
||||
reset { yylval=new_token(K_RESET); ccap(); return K_RESET; }
|
||||
resetdelay { yylval=NULL; ccap(); return K_RESETDELAY; }
|
||||
resetdelayms { yylval=NULL; ccap(); return K_RESETDELAYMS; }
|
||||
resetdelayus { yylval=NULL; ccap(); return K_RESETDELAYUS; }
|
||||
retry_pulse { yylval=NULL; ccap(); return K_RETRY_PULSE; }
|
||||
sck { yylval=new_token(K_SCK); ccap(); return K_SCK; }
|
||||
serial { yylval=NULL; ccap(); return K_SERIAL; }
|
||||
signature { yylval=NULL; ccap(); return K_SIGNATURE; }
|
||||
size { yylval=NULL; ccap(); return K_SIZE; }
|
||||
spi { yylval=NULL; return K_SPI; }
|
||||
spmcr { yylval=NULL; return K_SPMCR; }
|
||||
stabdelay { yylval=NULL; return K_STABDELAY; }
|
||||
stk500_devcode { yylval=NULL; return K_STK500_DEVCODE; }
|
||||
synchcycles { yylval=NULL; return K_SYNCHCYCLES; }
|
||||
synchloops { yylval=NULL; return K_SYNCHLOOPS; }
|
||||
timeout { yylval=NULL; return K_TIMEOUT; }
|
||||
togglevtg { yylval=NULL; return K_TOGGLEVTG; }
|
||||
type { yylval=NULL; return K_TYPE; }
|
||||
spmcr { yylval=NULL; ccap(); return K_SPMCR; }
|
||||
stabdelay { yylval=NULL; ccap(); return K_STABDELAY; }
|
||||
stk500_devcode { yylval=NULL; ccap(); return K_STK500_DEVCODE; }
|
||||
synchcycles { yylval=NULL; ccap(); return K_SYNCHCYCLES; }
|
||||
synchloops { yylval=NULL; ccap(); return K_SYNCHLOOPS; }
|
||||
timeout { yylval=NULL; ccap(); return K_TIMEOUT; }
|
||||
togglevtg { yylval=NULL; ccap(); return K_TOGGLEVTG; }
|
||||
type { yylval=NULL; ccap(); return K_TYPE; }
|
||||
usb { yylval=NULL; return K_USB; }
|
||||
usbdev { yylval=NULL; return K_USBDEV; }
|
||||
usbpid { yylval=NULL; return K_USBPID; }
|
||||
usbproduct { yylval=NULL; return K_USBPRODUCT; }
|
||||
usbsn { yylval=NULL; return K_USBSN; }
|
||||
usbvendor { yylval=NULL; return K_USBVENDOR; }
|
||||
usbvid { yylval=NULL; return K_USBVID; }
|
||||
vcc { yylval=NULL; return K_VCC; }
|
||||
vfyled { yylval=NULL; return K_VFYLED; }
|
||||
write { yylval=new_token(K_WRITE); return K_WRITE; }
|
||||
write_hi { yylval=new_token(K_WRITE_HI); return K_WRITE_HI; }
|
||||
write_lo { yylval=new_token(K_WRITE_LO); return K_WRITE_LO; }
|
||||
writepage { yylval=new_token(K_WRITEPAGE); return K_WRITEPAGE; }
|
||||
usbdev { yylval=NULL; ccap(); return K_USBDEV; }
|
||||
usbpid { yylval=NULL; ccap(); return K_USBPID; }
|
||||
usbproduct { yylval=NULL; ccap(); return K_USBPRODUCT; }
|
||||
usbsn { yylval=NULL; ccap(); return K_USBSN; }
|
||||
usbvendor { yylval=NULL; ccap(); return K_USBVENDOR; }
|
||||
usbvid { yylval=NULL; ccap(); return K_USBVID; }
|
||||
vcc { yylval=NULL; ccap(); return K_VCC; }
|
||||
vfyled { yylval=NULL; ccap(); return K_VFYLED; }
|
||||
write { yylval=new_token(K_WRITE); ccap(); return K_WRITE; }
|
||||
write_hi { yylval=new_token(K_WRITE_HI); ccap(); return K_WRITE_HI; }
|
||||
write_lo { yylval=new_token(K_WRITE_LO); ccap(); return K_WRITE_LO; }
|
||||
writepage { yylval=new_token(K_WRITEPAGE); ccap(); return K_WRITEPAGE; }
|
||||
yes { yylval=new_token(K_YES); return K_YES; }
|
||||
|
||||
"," { yylval = NULL; pyytext(); return TKN_COMMA; }
|
||||
|
|
158
src/libavrdude.h
158
src/libavrdude.h
|
@ -203,8 +203,6 @@ typedef struct opcode {
|
|||
#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 AVR_DESCLEN 64
|
||||
#define AVR_IDLEN 32
|
||||
#define AVR_FAMILYIDLEN 7
|
||||
#define AVR_SIBLEN 16
|
||||
#define CTL_STACK_SIZE 32
|
||||
|
@ -215,10 +213,11 @@ typedef struct opcode {
|
|||
|
||||
/* Any changes here, please also reflect in dev_part_strct() of developer_opts.c */
|
||||
typedef struct avrpart {
|
||||
char desc[AVR_DESCLEN]; /* long part name */
|
||||
char id[AVR_IDLEN]; /* short part name */
|
||||
char * parent_id; /* parent id if set, for -p.../s */
|
||||
char family_id[AVR_FAMILYIDLEN+1]; /* family id in the SIB (avr8x) */
|
||||
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 hvupdi_variant; /* HV pulse on UPDI pin, no pin or RESET pin */
|
||||
int stk500_devcode; /* stk500 device code */
|
||||
int avr910_devcode; /* avr910 device code */
|
||||
|
@ -270,7 +269,7 @@ typedef struct avrpart {
|
|||
unsigned char idr; /* JTAG ICE mkII XML file parameter */
|
||||
unsigned char rampz; /* JTAG ICE mkII XML file parameter */
|
||||
unsigned char spmcr; /* JTAG ICE mkII XML file parameter */
|
||||
unsigned short eecr; /* JTAC ICE mkII XML file parameter */
|
||||
unsigned char eecr; /* JTAC ICE mkII XML file parameter */
|
||||
unsigned int mcu_base; /* Base address of MCU control block in ATxmega devices */
|
||||
unsigned int nvm_base; /* Base address of NVM controller in ATxmega devices */
|
||||
unsigned int ocd_base; /* Base address of OCD module in AVR8X/UPDI devices */
|
||||
|
@ -280,13 +279,14 @@ typedef struct avrpart {
|
|||
|
||||
LISTID mem; /* avr memory definitions */
|
||||
LISTID mem_alias; /* memory alias definitions */
|
||||
char *config_file; /* config file where defined */
|
||||
const char * config_file; /* config file where defined */
|
||||
int lineno; /* config file line number */
|
||||
} AVRPART;
|
||||
|
||||
#define AVR_MEMDESCLEN 64
|
||||
typedef struct avrmem {
|
||||
char desc[AVR_MEMDESCLEN]; /* memory description ("flash", "eeprom", etc) */
|
||||
const char *desc; /* memory description ("flash", "eeprom", etc) */
|
||||
LISTID comments; // Used by developer options -p*/[ASsr...]
|
||||
int paged; /* page addressed (e.g. ATmega flash) */
|
||||
int size; /* total memory size in bytes */
|
||||
int page_size; /* size of memory page (if page addressed) */
|
||||
|
@ -312,7 +312,7 @@ typedef struct avrmem {
|
|||
} AVRMEM;
|
||||
|
||||
typedef struct avrmem_alias {
|
||||
char desc[AVR_MEMDESCLEN]; /* alias name ("syscfg0" etc.) */
|
||||
const char *desc; /* alias name ("syscfg0" etc.) */
|
||||
AVRMEM *aliased_mem;
|
||||
} AVRMEM_ALIAS;
|
||||
|
||||
|
@ -330,8 +330,8 @@ int avr_set_bits(OPCODE * op, unsigned char * cmd);
|
|||
int avr_set_addr(OPCODE * op, unsigned char * cmd, unsigned long addr);
|
||||
int avr_set_addr_mem(AVRMEM *mem, int opnum, unsigned char *cmd, unsigned long addr);
|
||||
int avr_set_input(OPCODE * op, unsigned char * cmd, unsigned char data);
|
||||
int avr_get_output(OPCODE * op, unsigned char * res, unsigned char * data);
|
||||
int avr_get_output_index(OPCODE * op);
|
||||
int avr_get_output(const OPCODE *op, const unsigned char *res, unsigned char *data);
|
||||
int avr_get_output_index(const OPCODE *op);
|
||||
char cmdbitchar(CMDBIT cb);
|
||||
char *cmdbitstr(CMDBIT cb);
|
||||
const char *opcodename(int opnum);
|
||||
|
@ -340,26 +340,26 @@ char *opcode2str(OPCODE *op, int opnum, int detailed);
|
|||
/* Functions for AVRMEM structures */
|
||||
AVRMEM * avr_new_memtype(void);
|
||||
AVRMEM_ALIAS * avr_new_memalias(void);
|
||||
int avr_initmem(AVRPART * p);
|
||||
AVRMEM * avr_dup_mem(AVRMEM * m);
|
||||
int avr_initmem(const AVRPART *p);
|
||||
AVRMEM * avr_dup_mem(const AVRMEM *m);
|
||||
void avr_free_mem(AVRMEM * m);
|
||||
void avr_free_memalias(AVRMEM_ALIAS * m);
|
||||
AVRMEM * avr_locate_mem(AVRPART * p, const char * desc);
|
||||
AVRMEM * avr_locate_mem_noalias(AVRPART * p, const char * desc);
|
||||
AVRMEM_ALIAS * avr_locate_memalias(AVRPART * p, const char * desc);
|
||||
AVRMEM_ALIAS * avr_find_memalias(AVRPART * p, AVRMEM * m_orig);
|
||||
void avr_mem_display(const char * prefix, FILE * f, AVRMEM * m, AVRPART * p,
|
||||
int type, int verbose);
|
||||
AVRMEM * avr_locate_mem(const AVRPART *p, const char *desc);
|
||||
AVRMEM * avr_locate_mem_noalias(const AVRPART *p, const char *desc);
|
||||
AVRMEM_ALIAS * avr_locate_memalias(const AVRPART *p, const char *desc);
|
||||
AVRMEM_ALIAS * avr_find_memalias(const AVRPART *p, const AVRMEM *m_orig);
|
||||
void avr_mem_display(const char *prefix, FILE *f, const AVRMEM *m,
|
||||
const AVRPART *p, int verbose);
|
||||
|
||||
/* Functions for AVRPART structures */
|
||||
AVRPART * avr_new_part(void);
|
||||
AVRPART * avr_dup_part(AVRPART * d);
|
||||
AVRPART * avr_dup_part(const AVRPART *d);
|
||||
void avr_free_part(AVRPART * d);
|
||||
AVRPART * locate_part(LISTID parts, const char * partdesc);
|
||||
AVRPART * locate_part_by_avr910_devcode(LISTID parts, int devcode);
|
||||
AVRPART * locate_part_by_signature(LISTID parts, unsigned char * sig,
|
||||
AVRPART * locate_part(const LISTID parts, const char *partdesc);
|
||||
AVRPART * locate_part_by_avr910_devcode(const LISTID parts, int devcode);
|
||||
AVRPART * locate_part_by_signature(const LISTID parts, unsigned char *sig,
|
||||
int sigsize);
|
||||
void avr_display(FILE * f, AVRPART * p, const char * prefix, int verbose);
|
||||
void avr_display(FILE *f, const AVRPART *p, const char *prefix, int verbose);
|
||||
|
||||
typedef void (*walk_avrparts_cb)(const char *name, const char *desc,
|
||||
const char *cfgname, int cfglineno,
|
||||
|
@ -516,7 +516,15 @@ int pins_check(const struct programmer_t * const pgm, const struct pin_checklist
|
|||
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.
|
||||
*
|
||||
* @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);
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
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.
|
||||
* 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
|
||||
* @returns pointer to a static string.
|
||||
|
@ -637,10 +653,8 @@ extern struct serial_device usbhid_serdev;
|
|||
#define ON 1
|
||||
#define OFF 0
|
||||
|
||||
#define PGM_DESCLEN 80
|
||||
#define PGM_PORTLEN PATH_MAX
|
||||
#define PGM_TYPELEN 32
|
||||
#define PGM_USBSTRINGLEN 256
|
||||
|
||||
typedef enum {
|
||||
EXIT_VCC_UNSPEC,
|
||||
|
@ -667,30 +681,38 @@ typedef enum {
|
|||
CONNTYPE_SPI
|
||||
} conntype_t;
|
||||
|
||||
/* Any changes here, please also reflect in dev_pgm_strct() of developer_opts.c */
|
||||
typedef struct programmer_t {
|
||||
LISTID id;
|
||||
char desc[PGM_DESCLEN];
|
||||
char type[PGM_TYPELEN];
|
||||
char port[PGM_PORTLEN];
|
||||
char *parent_id;
|
||||
void (*initpgm)(struct programmer_t * pgm);
|
||||
unsigned int pinno[N_PINS];
|
||||
const char *desc;
|
||||
void (*initpgm)(struct programmer_t *pgm);
|
||||
LISTID comments; // Used by developer options -c*/[ASsr...]
|
||||
const char *parent_id; // Used by developer options
|
||||
struct pindef_t pin[N_PINS];
|
||||
exit_vcc_t exit_vcc;
|
||||
exit_reset_t exit_reset;
|
||||
exit_datahigh_t exit_datahigh;
|
||||
conntype_t conntype;
|
||||
int ppidata;
|
||||
int ppictrl;
|
||||
int baudrate;
|
||||
int usbvid;
|
||||
LISTID usbpid;
|
||||
char usbdev[PGM_USBSTRINGLEN], usbsn[PGM_USBSTRINGLEN];
|
||||
char usbvendor[PGM_USBSTRINGLEN], usbproduct[PGM_USBSTRINGLEN];
|
||||
double bitclock; /* JTAG ICE clock period in microseconds */
|
||||
int ispdelay; /* ISP clock delay */
|
||||
const char *usbdev;
|
||||
const char *usbsn;
|
||||
const char *usbvendor;
|
||||
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()
|
||||
union filedescriptor fd;
|
||||
int page_size; /* page size if the programmer supports paged write/load */
|
||||
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 (*err_led) (struct programmer_t * pgm, int value);
|
||||
int (*pgm_led) (struct programmer_t * pgm, int value);
|
||||
|
@ -740,11 +762,11 @@ typedef struct programmer_t {
|
|||
int (*parseextparams) (struct programmer_t * pgm, LISTID xparams);
|
||||
void (*setup) (struct programmer_t * pgm);
|
||||
void (*teardown) (struct programmer_t * pgm);
|
||||
char *config_file; /* config file where defined */
|
||||
int lineno; /* config file line number */
|
||||
void *cookie; /* for private use by the programmer */
|
||||
char flag; /* for private use of the programmer */
|
||||
LISTID hvupdi_support; /* List of UPDI HV variants the tool supports. See HV_UPDI_VARIANT_ */
|
||||
|
||||
const char *config_file; // Config file where defined
|
||||
int lineno; // Config file line number
|
||||
void *cookie; // For private use by the programmer
|
||||
char flag; // For private use of the programmer
|
||||
} PROGRAMMER;
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -752,8 +774,8 @@ extern "C" {
|
|||
#endif
|
||||
|
||||
PROGRAMMER * pgm_new(void);
|
||||
PROGRAMMER * pgm_dup(const PROGRAMMER * const src);
|
||||
void pgm_free(PROGRAMMER * const p);
|
||||
PROGRAMMER * pgm_dup(const PROGRAMMER *src);
|
||||
void pgm_free(PROGRAMMER *p);
|
||||
|
||||
void programmer_display(PROGRAMMER * pgm, const char * p);
|
||||
|
||||
|
@ -762,10 +784,10 @@ void programmer_display(PROGRAMMER * pgm, const char * p);
|
|||
#define SHOW_PPI_PINS ((1<<PPI_AVR_VCC)|(1<<PPI_AVR_BUFF))
|
||||
#define SHOW_AVR_PINS ((1<<PIN_AVR_RESET)|(1<<PIN_AVR_SCK)|(1<<PIN_AVR_MOSI)|(1<<PIN_AVR_MISO))
|
||||
#define SHOW_LED_PINS ((1<<PIN_LED_ERR)|(1<<PIN_LED_RDY)|(1<<PIN_LED_PGM)|(1<<PIN_LED_VFY))
|
||||
void pgm_display_generic_mask(PROGRAMMER * pgm, const char * p, unsigned int show);
|
||||
void pgm_display_generic(PROGRAMMER * pgm, const char * p);
|
||||
void pgm_display_generic_mask(const PROGRAMMER *pgm, const char *p, unsigned int show);
|
||||
void pgm_display_generic(const PROGRAMMER *pgm, const char *p);
|
||||
|
||||
PROGRAMMER * locate_programmer(LISTID programmers, const char * configid);
|
||||
PROGRAMMER *locate_programmer(const LISTID programmers, const char *configid);
|
||||
|
||||
typedef void (*walk_programmers_cb)(const char *name, const char *desc,
|
||||
const char *cfgname, int cfglineno,
|
||||
|
@ -965,7 +987,9 @@ typedef struct programmer_type_t {
|
|||
extern "C" {
|
||||
#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(void (*initpgm)(struct programmer_t *pgm));
|
||||
|
||||
typedef void (*walk_programmer_types_cb)(const char *id, const char *desc,
|
||||
void *cookie);
|
||||
|
@ -979,10 +1003,10 @@ void walk_programmer_types(/*LISTID programmer_types,*/ walk_programmer_types_cb
|
|||
|
||||
extern LISTID part_list;
|
||||
extern LISTID programmers;
|
||||
extern char default_programmer[];
|
||||
extern char default_parallel[];
|
||||
extern char default_serial[];
|
||||
extern char default_spi[];
|
||||
extern const char *default_programmer;
|
||||
extern const char *default_parallel;
|
||||
extern const char *default_serial;
|
||||
extern const char *default_spi;
|
||||
extern double default_bitclock;
|
||||
|
||||
/* This name is fixed, it's only here for symmetry with
|
||||
|
@ -993,12 +1017,24 @@ extern double default_bitclock;
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
void *cfg_malloc(const char *funcname, size_t n);
|
||||
|
||||
char *cfg_strdup(const char *funcname, const char *s);
|
||||
|
||||
int init_config(void);
|
||||
|
||||
void cleanup_config(void);
|
||||
|
||||
int read_config(const char * file);
|
||||
|
||||
const char *cache_string(const char *file);
|
||||
|
||||
unsigned char *cfg_unescapeu(unsigned char *d, const unsigned char *s);
|
||||
|
||||
char *cfg_unescape(char *d, const char *s);
|
||||
|
||||
char *cfg_escape(const char *s);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
56
src/main.c
56
src/main.c
|
@ -140,6 +140,10 @@ static void list_programmers_callback(const char *name, const char *desc,
|
|||
void *cookie)
|
||||
{
|
||||
struct list_walk_cookie *c = (struct list_walk_cookie *)cookie;
|
||||
|
||||
if (*name == 0 || *name == '.')
|
||||
return;
|
||||
|
||||
if (verbose){
|
||||
fprintf(c->f, "%s%-16s = %-30s [%s:%d]\n",
|
||||
c->prefix, name, desc, cfgname, cfglineno);
|
||||
|
@ -244,6 +248,14 @@ static void replace_backslashes(char *s)
|
|||
}
|
||||
}
|
||||
|
||||
// Return 2 if string is * or starts with */, 1 if string contains /, 0 otherwise
|
||||
static int dev_opt(char *str) {
|
||||
return
|
||||
!str? 0:
|
||||
!strcmp(str, "*") || !strncmp(str, "*/", 2)? 2:
|
||||
!!strchr(str, '/');
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* main routine
|
||||
|
@ -314,10 +326,11 @@ int main(int argc, char * argv [])
|
|||
else
|
||||
progname = argv[0];
|
||||
|
||||
default_parallel[0] = 0;
|
||||
default_serial[0] = 0;
|
||||
default_spi[0] = 0;
|
||||
default_bitclock = 0.0;
|
||||
default_programmer = "";
|
||||
default_parallel = "";
|
||||
default_serial = "";
|
||||
default_spi = "";
|
||||
default_bitclock = 0.0;
|
||||
|
||||
init_config();
|
||||
|
||||
|
@ -351,7 +364,7 @@ int main(int argc, char * argv [])
|
|||
quell_progress = 0;
|
||||
exitspecs = NULL;
|
||||
pgm = NULL;
|
||||
programmer = default_programmer;
|
||||
programmer = cfg_strdup("main()", default_programmer);
|
||||
verbose = 0;
|
||||
baudrate = 0;
|
||||
bitclock = 0.0;
|
||||
|
@ -751,15 +764,17 @@ int main(int argc, char * argv [])
|
|||
bitclock = default_bitclock;
|
||||
}
|
||||
|
||||
// Developer options to print parts and/or programmer entries of avrdude.conf
|
||||
int dev_opt_c = dev_opt(programmer); // -c <wildcard>/[sSArt]
|
||||
int dev_opt_p = dev_opt(partdesc); // -p <wildcard>/[dsSArcow*t]
|
||||
|
||||
if(dev_opt_c || dev_opt_p) { // See -c/h and or -p/h
|
||||
dev_output_pgm_part(dev_opt_c, programmer, dev_opt_p, partdesc);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
avrdude_message(MSG_NOTICE, "\n");
|
||||
|
||||
// developer option -p <wildcard>/[*codws] prints various aspects of part descriptions and exits
|
||||
if(partdesc && (strcmp(partdesc, "*") == 0 || strchr(partdesc, '/'))) {
|
||||
dev_output_part_defs(partdesc);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (partdesc) {
|
||||
if (strcmp(partdesc, "?") == 0) {
|
||||
avrdude_message(MSG_INFO, "\n");
|
||||
|
@ -841,11 +856,11 @@ int main(int argc, char * argv [])
|
|||
switch (pgm->conntype)
|
||||
{
|
||||
case CONNTYPE_PARALLEL:
|
||||
port = default_parallel;
|
||||
port = cfg_strdup("main()", default_parallel);
|
||||
break;
|
||||
|
||||
case CONNTYPE_SERIAL:
|
||||
port = default_serial;
|
||||
port = cfg_strdup("main()", default_serial);
|
||||
break;
|
||||
|
||||
case CONNTYPE_USB:
|
||||
|
@ -916,10 +931,7 @@ int main(int argc, char * argv [])
|
|||
progname,
|
||||
(upd->op == DEVICE_READ)? 'r': (upd->op == DEVICE_WRITE)? 'w': 'v',
|
||||
upd->filename, mtype);
|
||||
if ((upd->memtype = strdup(mtype)) == NULL) {
|
||||
avrdude_message(MSG_INFO, "%s: out of memory\n", progname);
|
||||
exit(1);
|
||||
}
|
||||
upd->memtype = cfg_strdup("main()", mtype);
|
||||
}
|
||||
|
||||
rc = update_dryrun(p, upd);
|
||||
|
@ -1069,9 +1081,9 @@ int main(int argc, char * argv [])
|
|||
pgm->read_sib(pgm, p, sib);
|
||||
avrdude_message(MSG_NOTICE, "%s: System Information Block: \"%s\"\n",
|
||||
progname, sib);
|
||||
if (quell_progress < 2) {
|
||||
if (quell_progress < 2)
|
||||
avrdude_message(MSG_INFO, "%s: Received FamilyID: \"%.*s\"\n", progname, AVR_FAMILYIDLEN, sib);
|
||||
}
|
||||
|
||||
if (strncmp(p->family_id, sib, AVR_FAMILYIDLEN)) {
|
||||
avrdude_message(MSG_INFO, "%s: Expected FamilyID: \"%s\"\n", progname, p->family_id);
|
||||
if (!ovsigck) {
|
||||
|
@ -1089,9 +1101,8 @@ int main(int argc, char * argv [])
|
|||
avrdude_message(MSG_INFO, "%s: conflicting -e and -n options specified, NOT erasing chip\n",
|
||||
progname);
|
||||
} else {
|
||||
if (quell_progress < 2) {
|
||||
if (quell_progress < 2)
|
||||
avrdude_message(MSG_INFO, "%s: erasing chip\n", progname);
|
||||
}
|
||||
exitrc = avr_unlock(pgm, p);
|
||||
if(exitrc) goto main_exit;
|
||||
goto sig_again;
|
||||
|
@ -1225,9 +1236,8 @@ int main(int argc, char * argv [])
|
|||
avrdude_message(MSG_INFO, "%s: conflicting -e and -n options specified, NOT erasing chip\n",
|
||||
progname);
|
||||
} else {
|
||||
if (quell_progress < 2) {
|
||||
if (quell_progress < 2)
|
||||
avrdude_message(MSG_INFO, "%s: erasing chip\n", progname);
|
||||
}
|
||||
exitrc = avr_chip_erase(pgm, p);
|
||||
if(exitrc) goto main_exit;
|
||||
}
|
||||
|
|
155
src/pgm.c
155
src/pgm.c
|
@ -61,32 +61,29 @@ static void pgm_default_powerup_powerdown (struct programmer_t * pgm)
|
|||
}
|
||||
|
||||
|
||||
PROGRAMMER * pgm_new(void)
|
||||
{
|
||||
int i;
|
||||
PROGRAMMER * pgm;
|
||||
|
||||
pgm = (PROGRAMMER *)malloc(sizeof(*pgm));
|
||||
if (pgm == NULL) {
|
||||
avrdude_message(MSG_INFO, "%s: out of memory allocating programmer structure\n",
|
||||
progname);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memset(pgm, 0, sizeof(*pgm));
|
||||
PROGRAMMER *pgm_new(void) {
|
||||
PROGRAMMER *pgm = (PROGRAMMER *) cfg_malloc("pgm_new()", sizeof(*pgm));
|
||||
const char *nulp = cache_string("");
|
||||
|
||||
// Initialise const char * and LISTID entities
|
||||
pgm->id = lcreat(NULL, 0);
|
||||
pgm->usbpid = lcreat(NULL, 0);
|
||||
pgm->desc[0] = 0;
|
||||
pgm->type[0] = 0;
|
||||
pgm->parent_id = NULL;
|
||||
pgm->config_file = NULL;
|
||||
pgm->hvupdi_support = lcreat(NULL, 0);
|
||||
pgm->desc = nulp;
|
||||
pgm->parent_id = nulp;
|
||||
pgm->usbdev = nulp;
|
||||
pgm->usbsn = nulp;
|
||||
pgm->usbvendor = nulp;
|
||||
pgm->usbproduct = nulp;
|
||||
pgm->config_file = nulp;
|
||||
|
||||
// Default values
|
||||
pgm->initpgm = NULL;
|
||||
pgm->lineno = 0;
|
||||
pgm->baudrate = 0;
|
||||
pgm->initpgm = NULL;
|
||||
pgm->hvupdi_support = lcreat(NULL, 0);
|
||||
|
||||
for (i=0; i<N_PINS; i++) {
|
||||
// Clear pin array
|
||||
for(int i=0; i<N_PINS; i++) {
|
||||
pgm->pinno[i] = 0;
|
||||
pin_clear_all(&(pgm->pin[i]));
|
||||
}
|
||||
|
@ -122,60 +119,70 @@ PROGRAMMER * pgm_new(void)
|
|||
* optional functions - these are checked to make sure they are
|
||||
* assigned before they are called
|
||||
*/
|
||||
pgm->unlock = NULL;
|
||||
pgm->cmd = NULL;
|
||||
pgm->cmd_tpi = NULL;
|
||||
pgm->spi = NULL;
|
||||
pgm->paged_write = NULL;
|
||||
pgm->paged_load = NULL;
|
||||
pgm->page_erase = NULL;
|
||||
pgm->write_setup = NULL;
|
||||
pgm->read_sig_bytes = NULL;
|
||||
pgm->read_sib = NULL;
|
||||
pgm->print_parms = NULL;
|
||||
pgm->set_vtarget = NULL;
|
||||
pgm->set_varef = NULL;
|
||||
pgm->set_fosc = NULL;
|
||||
pgm->set_sck_period = NULL;
|
||||
pgm->setpin = NULL;
|
||||
pgm->getpin = NULL;
|
||||
pgm->highpulsepin = NULL;
|
||||
pgm->parseexitspecs = NULL;
|
||||
pgm->perform_osccal = NULL;
|
||||
pgm->parseextparams = NULL;
|
||||
pgm->setup = NULL;
|
||||
pgm->teardown = NULL;
|
||||
|
||||
// For allocating "global" memory by the programmer
|
||||
pgm->cookie = NULL;
|
||||
|
||||
return pgm;
|
||||
}
|
||||
|
||||
void pgm_free(PROGRAMMER * const p)
|
||||
{
|
||||
ldestroy_cb(p->id, free);
|
||||
ldestroy_cb(p->usbpid, free);
|
||||
p->id = NULL;
|
||||
p->usbpid = NULL;
|
||||
/* do not free p->parent_id nor p->config_file */
|
||||
/* p->cookie is freed by pgm_teardown */
|
||||
free(p);
|
||||
void pgm_free(PROGRAMMER *p) {
|
||||
if(p) {
|
||||
ldestroy_cb(p->id, free);
|
||||
ldestroy_cb(p->usbpid, free);
|
||||
ldestroy_cb(p->hvupdi_support, free);
|
||||
p->id = NULL;
|
||||
p->usbpid = NULL;
|
||||
p->hvupdi_support = NULL;
|
||||
// Never free const char *, eg, p->desc, which are set by cache_string()
|
||||
// p->cookie is freed by pgm_teardown
|
||||
free(p);
|
||||
}
|
||||
}
|
||||
|
||||
PROGRAMMER * pgm_dup(const PROGRAMMER * const src)
|
||||
{
|
||||
PROGRAMMER * pgm;
|
||||
LNODEID ln;
|
||||
PROGRAMMER *pgm_dup(const PROGRAMMER *src) {
|
||||
PROGRAMMER *pgm = pgm_new();
|
||||
|
||||
pgm = (PROGRAMMER *)malloc(sizeof(*pgm));
|
||||
if (pgm == NULL) {
|
||||
avrdude_message(MSG_INFO, "%s: out of memory allocating programmer structure\n",
|
||||
progname);
|
||||
return NULL;
|
||||
}
|
||||
if(src) {
|
||||
memcpy(pgm, src, sizeof(*pgm));
|
||||
pgm->id = lcreat(NULL, 0);
|
||||
pgm->usbpid = lcreat(NULL, 0);
|
||||
pgm->hvupdi_support = lcreat(NULL, 0);
|
||||
|
||||
memcpy(pgm, src, sizeof(*pgm));
|
||||
|
||||
pgm->id = lcreat(NULL, 0);
|
||||
pgm->usbpid = lcreat(NULL, 0);
|
||||
for (ln = lfirst(src->usbpid); ln; ln = lnext(ln)) {
|
||||
int *ip = malloc(sizeof(int));
|
||||
if (ip == NULL) {
|
||||
avrdude_message(MSG_INFO, "%s: out of memory allocating programmer structure\n",
|
||||
progname);
|
||||
exit(1);
|
||||
// Leave id list empty but copy usbpid and hvupdi_support over
|
||||
for(LNODEID ln = lfirst(src->hvupdi_support); ln; ln = lnext(ln)) {
|
||||
int *ip = cfg_malloc("pgm_dup()", sizeof(int));
|
||||
*ip = *(int *) ldata(ln);
|
||||
ladd(pgm->hvupdi_support, ip);
|
||||
}
|
||||
for(LNODEID ln = lfirst(src->usbpid); ln; ln = lnext(ln)) {
|
||||
int *ip = cfg_malloc("pgm_dup()", sizeof(int));
|
||||
*ip = *(int *) ldata(ln);
|
||||
ladd(pgm->usbpid, ip);
|
||||
}
|
||||
*ip = *(int *) ldata(ln);
|
||||
ladd(pgm->usbpid, ip);
|
||||
}
|
||||
|
||||
return pgm;
|
||||
|
@ -219,8 +226,7 @@ static void pgm_default_6 (struct programmer_t * pgm, const char * p)
|
|||
}
|
||||
|
||||
|
||||
void programmer_display(PROGRAMMER * pgm, const char * p)
|
||||
{
|
||||
void programmer_display(PROGRAMMER *pgm, const char * p) {
|
||||
avrdude_message(MSG_INFO, "%sProgrammer Type : %s\n", p, pgm->type);
|
||||
avrdude_message(MSG_INFO, "%sDescription : %s\n", p, pgm->desc);
|
||||
|
||||
|
@ -228,8 +234,7 @@ void programmer_display(PROGRAMMER * pgm, const char * p)
|
|||
}
|
||||
|
||||
|
||||
void pgm_display_generic_mask(PROGRAMMER * pgm, const char * p, unsigned int show)
|
||||
{
|
||||
void pgm_display_generic_mask(const PROGRAMMER *pgm, const char *p, unsigned int show) {
|
||||
if(show & (1<<PPI_AVR_VCC))
|
||||
avrdude_message(MSG_INFO, "%s VCC = %s\n", p, pins_to_str(&pgm->pin[PPI_AVR_VCC]));
|
||||
if(show & (1<<PPI_AVR_BUFF))
|
||||
|
@ -252,33 +257,22 @@ void pgm_display_generic_mask(PROGRAMMER * pgm, const char * p, unsigned int sho
|
|||
avrdude_message(MSG_INFO, "%s VFY LED = %s\n", p, pins_to_str(&pgm->pin[PIN_LED_VFY]));
|
||||
}
|
||||
|
||||
void pgm_display_generic(PROGRAMMER * pgm, const char * p)
|
||||
{
|
||||
void pgm_display_generic(const PROGRAMMER *pgm, const char *p) {
|
||||
pgm_display_generic_mask(pgm, p, SHOW_ALL_PINS);
|
||||
}
|
||||
|
||||
PROGRAMMER * locate_programmer(LISTID programmers, const char * configid)
|
||||
{
|
||||
LNODEID ln1, ln2;
|
||||
PROGRAMMER * p = NULL;
|
||||
const char * id;
|
||||
int found;
|
||||
PROGRAMMER *locate_programmer(const LISTID programmers, const char *configid) {
|
||||
PROGRAMMER *p = NULL;
|
||||
int found = 0;
|
||||
|
||||
found = 0;
|
||||
|
||||
for (ln1=lfirst(programmers); ln1 && !found; ln1=lnext(ln1)) {
|
||||
for(LNODEID ln1=lfirst(programmers); ln1 && !found; ln1=lnext(ln1)) {
|
||||
p = ldata(ln1);
|
||||
for (ln2=lfirst(p->id); ln2 && !found; ln2=lnext(ln2)) {
|
||||
id = ldata(ln2);
|
||||
if (strcasecmp(configid, id) == 0)
|
||||
for(LNODEID ln2=lfirst(p->id); ln2 && !found; ln2=lnext(ln2))
|
||||
if(strcasecmp(configid, (const char *) ldata(ln2)) == 0)
|
||||
found = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (found)
|
||||
return p;
|
||||
|
||||
return NULL;
|
||||
return found? p: NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -308,16 +302,11 @@ void walk_programmers(LISTID programmers, walk_programmers_cb cb, void *cookie)
|
|||
/*
|
||||
* Compare function to sort the list of programmers
|
||||
*/
|
||||
static int sort_programmer_compare(PROGRAMMER * p1,PROGRAMMER * p2)
|
||||
{
|
||||
char* id1;
|
||||
char* id2;
|
||||
if(p1 == NULL || p2 == NULL) {
|
||||
static int sort_programmer_compare(const PROGRAMMER *p1, const PROGRAMMER *p2) {
|
||||
if(p1 == NULL || p1->id == NULL || p2 == NULL || p2->id == NULL)
|
||||
return 0;
|
||||
}
|
||||
id1 = ldata(lfirst(p1->id));
|
||||
id2 = ldata(lfirst(p2->id));
|
||||
return strncasecmp(id1,id2,AVR_IDLEN);
|
||||
|
||||
return strcasecmp(ldata(lfirst(p1->id)), ldata(lfirst(p2->id)));
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
108
src/pgm_type.c
108
src/pgm_type.c
|
@ -57,55 +57,55 @@
|
|||
#include "xbee.h"
|
||||
|
||||
|
||||
const PROGRAMMER_TYPE programmers_types[] = {
|
||||
{"arduino", arduino_initpgm, arduino_desc},
|
||||
{"avr910", avr910_initpgm, avr910_desc},
|
||||
{"avrftdi", avrftdi_initpgm, avrftdi_desc},
|
||||
{"buspirate", buspirate_initpgm, buspirate_desc},
|
||||
{"buspirate_bb", buspirate_bb_initpgm, buspirate_bb_desc},
|
||||
{"butterfly", butterfly_initpgm, butterfly_desc},
|
||||
{"butterfly_mk", butterfly_mk_initpgm, butterfly_mk_desc},
|
||||
{"dragon_dw", jtagmkII_dragon_dw_initpgm, jtagmkII_dragon_dw_desc},
|
||||
{"dragon_hvsp", stk500v2_dragon_hvsp_initpgm, stk500v2_dragon_hvsp_desc},
|
||||
{"dragon_isp", stk500v2_dragon_isp_initpgm, stk500v2_dragon_isp_desc},
|
||||
{"dragon_jtag", jtagmkII_dragon_initpgm, jtagmkII_dragon_desc},
|
||||
{"dragon_pdi", jtagmkII_dragon_pdi_initpgm, jtagmkII_dragon_pdi_desc},
|
||||
{"dragon_pp", stk500v2_dragon_pp_initpgm, stk500v2_dragon_pp_desc},
|
||||
{"flip1", flip1_initpgm, flip1_desc},
|
||||
{"flip2", flip2_initpgm, flip2_desc},
|
||||
{"ftdi_syncbb", ft245r_initpgm, ft245r_desc},
|
||||
{"jtagmki", jtagmkI_initpgm, jtagmkI_desc},
|
||||
{"jtagmkii", jtagmkII_initpgm, jtagmkII_desc},
|
||||
{"jtagmkii_avr32", jtagmkII_avr32_initpgm, jtagmkII_avr32_desc},
|
||||
{"jtagmkii_dw", jtagmkII_dw_initpgm, jtagmkII_dw_desc},
|
||||
{"jtagmkii_isp", stk500v2_jtagmkII_initpgm, stk500v2_jtagmkII_desc},
|
||||
{"jtagmkii_pdi", jtagmkII_pdi_initpgm, jtagmkII_pdi_desc},
|
||||
{"jtagmkii_updi", jtagmkII_updi_initpgm, jtagmkII_updi_desc},
|
||||
{"jtagice3", jtag3_initpgm, jtag3_desc},
|
||||
{"jtagice3_pdi", jtag3_pdi_initpgm, jtag3_pdi_desc},
|
||||
{"jtagice3_updi", jtag3_updi_initpgm, jtag3_updi_desc},
|
||||
{"jtagice3_dw", jtag3_dw_initpgm, jtag3_dw_desc},
|
||||
{"jtagice3_isp", stk500v2_jtag3_initpgm, stk500v2_jtag3_desc},
|
||||
{"linuxgpio", linuxgpio_initpgm, linuxgpio_desc},
|
||||
{"linuxspi", linuxspi_initpgm, linuxspi_desc},
|
||||
{"micronucleus", micronucleus_initpgm, micronucleus_desc},
|
||||
{"par", par_initpgm, par_desc},
|
||||
{"pickit2", pickit2_initpgm, pickit2_desc},
|
||||
{"serbb", serbb_initpgm, serbb_desc},
|
||||
{"serialupdi", serialupdi_initpgm, serialupdi_desc},
|
||||
{"stk500", stk500_initpgm, stk500_desc},
|
||||
{"stk500generic", stk500generic_initpgm, stk500generic_desc},
|
||||
{"stk500v2", stk500v2_initpgm, stk500v2_desc},
|
||||
{"stk500hvsp", stk500hvsp_initpgm, stk500hvsp_desc},
|
||||
{"stk500pp", stk500pp_initpgm, stk500pp_desc},
|
||||
{"stk600", stk600_initpgm, stk600_desc},
|
||||
{"stk600hvsp", stk600hvsp_initpgm, stk600hvsp_desc},
|
||||
{"stk600pp", stk600pp_initpgm, stk600pp_desc},
|
||||
{"teensy", teensy_initpgm, teensy_desc},
|
||||
{"usbasp", usbasp_initpgm, usbasp_desc},
|
||||
{"usbtiny", usbtiny_initpgm, usbtiny_desc},
|
||||
{"wiring", wiring_initpgm, wiring_desc},
|
||||
{"xbee", xbee_initpgm, xbee_desc},
|
||||
const PROGRAMMER_TYPE programmers_types[] = { // Name(s) the programmers call themselves
|
||||
{"arduino", arduino_initpgm, arduino_desc}, // "Arduino"
|
||||
{"avr910", avr910_initpgm, avr910_desc}, // "avr910"
|
||||
{"avrftdi", avrftdi_initpgm, avrftdi_desc}, // "avrftdi"
|
||||
{"buspirate", buspirate_initpgm, buspirate_desc}, // "BusPirate"
|
||||
{"buspirate_bb", buspirate_bb_initpgm, buspirate_bb_desc}, // "BusPirate_BB"
|
||||
{"butterfly", butterfly_initpgm, butterfly_desc}, // "butterfly"
|
||||
{"butterfly_mk", butterfly_mk_initpgm, butterfly_mk_desc}, // "butterfly_mk"
|
||||
{"dragon_dw", jtagmkII_dragon_dw_initpgm, jtagmkII_dragon_dw_desc}, // "DRAGON_DW"
|
||||
{"dragon_hvsp", stk500v2_dragon_hvsp_initpgm, stk500v2_dragon_hvsp_desc}, // "DRAGON_HVSP"
|
||||
{"dragon_isp", stk500v2_dragon_isp_initpgm, stk500v2_dragon_isp_desc}, // "DRAGON_ISP"
|
||||
{"dragon_jtag", jtagmkII_dragon_initpgm, jtagmkII_dragon_desc}, // "DRAGON_JTAG"
|
||||
{"dragon_pdi", jtagmkII_dragon_pdi_initpgm, jtagmkII_dragon_pdi_desc}, // "DRAGON_PDI"
|
||||
{"dragon_pp", stk500v2_dragon_pp_initpgm, stk500v2_dragon_pp_desc}, // "DRAGON_PP"
|
||||
{"flip1", flip1_initpgm, flip1_desc}, // "flip1"
|
||||
{"flip2", flip2_initpgm, flip2_desc}, // "flip2"
|
||||
{"ftdi_syncbb", ft245r_initpgm, ft245r_desc}, // "ftdi_syncbb"
|
||||
{"jtagmki", jtagmkI_initpgm, jtagmkI_desc}, // "JTAGMKI"
|
||||
{"jtagmkii", jtagmkII_initpgm, jtagmkII_desc}, // "JTAGMKII"
|
||||
{"jtagmkii_avr32", jtagmkII_avr32_initpgm, jtagmkII_avr32_desc}, // "JTAGMKII_AVR32"
|
||||
{"jtagmkii_dw", jtagmkII_dw_initpgm, jtagmkII_dw_desc}, // "JTAGMKII_DW"
|
||||
{"jtagmkii_isp", stk500v2_jtagmkII_initpgm, stk500v2_jtagmkII_desc}, // "JTAGMKII_ISP"
|
||||
{"jtagmkii_pdi", jtagmkII_pdi_initpgm, jtagmkII_pdi_desc}, // "JTAGMKII_PDI"
|
||||
{"jtagmkii_updi", jtagmkII_updi_initpgm, jtagmkII_updi_desc}, // "JTAGMKII_UPDI"
|
||||
{"jtagice3", jtag3_initpgm, jtag3_desc}, // "JTAGICE3"
|
||||
{"jtagice3_pdi", jtag3_pdi_initpgm, jtag3_pdi_desc}, // "JTAGICE3_PDI"
|
||||
{"jtagice3_updi", jtag3_updi_initpgm, jtag3_updi_desc}, // "JTAGICE3_UPDI"
|
||||
{"jtagice3_dw", jtag3_dw_initpgm, jtag3_dw_desc}, // "JTAGICE3_DW"
|
||||
{"jtagice3_isp", stk500v2_jtag3_initpgm, stk500v2_jtag3_desc}, // "JTAG3_ISP"
|
||||
{"linuxgpio", linuxgpio_initpgm, linuxgpio_desc}, // "linuxgpio"
|
||||
{"linuxspi", linuxspi_initpgm, linuxspi_desc}, // LINUXSPI
|
||||
{"micronucleus", micronucleus_initpgm, micronucleus_desc}, // "micronucleus" or "Micronucleus V2.0"
|
||||
{"par", par_initpgm, par_desc}, // "PPI"
|
||||
{"pickit2", pickit2_initpgm, pickit2_desc}, // "pickit2"
|
||||
{"serbb", serbb_initpgm, serbb_desc}, // "SERBB"
|
||||
{"serialupdi", serialupdi_initpgm, serialupdi_desc}, // "serialupdi"
|
||||
{"stk500", stk500_initpgm, stk500_desc}, // "STK500"
|
||||
{"stk500generic", stk500generic_initpgm, stk500generic_desc}, // "STK500GENERIC"
|
||||
{"stk500v2", stk500v2_initpgm, stk500v2_desc}, // "STK500V2"
|
||||
{"stk500hvsp", stk500hvsp_initpgm, stk500hvsp_desc}, // "STK500HVSP"
|
||||
{"stk500pp", stk500pp_initpgm, stk500pp_desc}, // "STK500PP"
|
||||
{"stk600", stk600_initpgm, stk600_desc}, // "STK600"
|
||||
{"stk600hvsp", stk600hvsp_initpgm, stk600hvsp_desc}, // "STK600HVSP"
|
||||
{"stk600pp", stk600pp_initpgm, stk600pp_desc}, // "STK600PP"
|
||||
{"teensy", teensy_initpgm, teensy_desc}, // "teensy"
|
||||
{"usbasp", usbasp_initpgm, usbasp_desc}, // "usbasp"
|
||||
{"usbtiny", usbtiny_initpgm, usbtiny_desc}, // "USBtiny" or "usbtiny"
|
||||
{"wiring", wiring_initpgm, wiring_desc}, // "Wiring"
|
||||
{"xbee", xbee_initpgm, xbee_desc}, // "XBee"
|
||||
};
|
||||
|
||||
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 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
|
||||
* call the callback function cb for each entry found. cb is being
|
||||
|
|
|
@ -193,16 +193,18 @@ static int pickit2_open(PROGRAMMER * pgm, char * port)
|
|||
}
|
||||
else
|
||||
{
|
||||
// get the device description while we're at it
|
||||
short buff[PGM_DESCLEN-1], i;
|
||||
HidD_GetProductString(PDATA(pgm)->usb_handle, buff, PGM_DESCLEN-1);
|
||||
// Get the device description while we're at it and overlay it on pgm->desc
|
||||
short wbuf[80-1];
|
||||
char *cbuf = cfg_malloc("pickit2_open()", sizeof wbuf/sizeof*wbuf + (pgm->desc? strlen(pgm->desc): 0) + 2);
|
||||
HidD_GetProductString(PDATA(pgm)->usb_handle, wbuf, sizeof wbuf/sizeof*wbuf);
|
||||
|
||||
// convert from wide chars, but do not overwrite trailing '\0'
|
||||
memset(&(pgm->desc), 0, PGM_DESCLEN);
|
||||
for (i = 0; i < (PGM_DESCLEN-1) && buff[i]; i++)
|
||||
{
|
||||
pgm->desc[i] = (char)buff[i]; // TODO what about little/big endian???
|
||||
}
|
||||
if(pgm->desc && *pgm->desc)
|
||||
strcpy(cbuf, pgm->desc);
|
||||
|
||||
// Convert from wide chars and overlay over initial part of desc
|
||||
for (int i = 0; i < sizeof wbuf/sizeof*wbuf && wbuf[i]; i++)
|
||||
cbuf[i] = (char) wbuf[i]; // TODO what about little/big endian???
|
||||
pgm->desc = cache_string(cbuf);
|
||||
}
|
||||
#else
|
||||
if (usb_open_device(&(PDATA(pgm)->usb_handle), PICKIT2_VID, PICKIT2_PID) < 0)
|
||||
|
|
|
@ -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.
|
||||
*
|
||||
* @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;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
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, pindef->inverse[index] & (1 << bit)? "~%d": "%d", pin);
|
||||
}
|
||||
}
|
||||
|
||||
return cfg_strdup("pins_to_strdup()", buf);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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>";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -65,8 +65,8 @@ static int avrdoperRxPosition = 0; /* amount of bytes already consu
|
|||
/* ------------------------------------------------------------------------ */
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
static int usbOpenDevice(union filedescriptor *fdp, int vendor, char *vendorName,
|
||||
int product, char *productName, int doReportIDs)
|
||||
static int usbOpenDevice(union filedescriptor *fdp, int vendor, const char *vendorName,
|
||||
int product, const char *productName, int doReportIDs)
|
||||
{
|
||||
hid_device *dev;
|
||||
|
||||
|
|
|
@ -393,7 +393,7 @@ static int net_send(union filedescriptor *fd, const unsigned char * buf, size_t
|
|||
}
|
||||
|
||||
while (len) {
|
||||
rc = send(fd->ifd, p, (len > 1024) ? 1024 : len, 0);
|
||||
rc = send(fd->ifd, (const char *) p, (len > 1024)? 1024: len, 0);
|
||||
if (rc < 0) {
|
||||
FormatMessage(
|
||||
FORMAT_MESSAGE_ALLOCATE_BUFFER |
|
||||
|
@ -527,7 +527,7 @@ reselect:
|
|||
}
|
||||
}
|
||||
|
||||
rc = recv(fd->ifd, p, (buflen - len > 1024) ? 1024 : buflen - len, 0);
|
||||
rc = recv(fd->ifd, (char *) p, (buflen - len > 1024)? 1024: buflen - len, 0);
|
||||
if (rc < 0) {
|
||||
FormatMessage(
|
||||
FORMAT_MESSAGE_ALLOCATE_BUFFER |
|
||||
|
@ -693,7 +693,7 @@ static int net_drain(union filedescriptor *fd, int display)
|
|||
}
|
||||
}
|
||||
|
||||
rc = recv(fd->ifd, &buf, 1, 0);
|
||||
rc = recv(fd->ifd, (char *) &buf, 1, 0);
|
||||
if (rc < 0) {
|
||||
FormatMessage(
|
||||
FORMAT_MESSAGE_ALLOCATE_BUFFER |
|
||||
|
|
|
@ -3093,12 +3093,14 @@ static int stk500v2_setparm_real(PROGRAMMER * pgm, unsigned char parm, unsigned
|
|||
|
||||
static int stk500v2_setparm(PROGRAMMER * pgm, unsigned char parm, unsigned char value)
|
||||
{
|
||||
unsigned char current_value;
|
||||
unsigned char current_value = value;
|
||||
int res;
|
||||
|
||||
res = stk500v2_getparm(pgm, parm, ¤t_value);
|
||||
if (res < 0)
|
||||
if (res < 0) {
|
||||
avrdude_message(MSG_INFO, "%s: Unable to get parameter 0x%02x\n", progname, parm);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// don't issue a write if the correct value is already set.
|
||||
if (value == current_value) {
|
||||
|
@ -3245,7 +3247,7 @@ f_to_kHz_MHz(double f, const char **unit)
|
|||
|
||||
static void stk500v2_print_parms1(PROGRAMMER * pgm, const char * p)
|
||||
{
|
||||
unsigned char vtarget, vadjust, osc_pscale, osc_cmatch, sck_duration =0; //XXX 0 is not correct, check caller
|
||||
unsigned char vtarget = 0, vadjust = 0, osc_pscale = 0, osc_cmatch = 0, sck_duration =0; //XXX 0 is not correct, check caller
|
||||
unsigned int sck_stk600, clock_conf, dac, oct, varef;
|
||||
unsigned char vtarget_jtag[4];
|
||||
int prescale;
|
||||
|
@ -3253,6 +3255,8 @@ static void stk500v2_print_parms1(PROGRAMMER * pgm, const char * p)
|
|||
const char *unit;
|
||||
void *mycookie;
|
||||
|
||||
memset(vtarget_jtag, 0, sizeof vtarget_jtag);
|
||||
|
||||
if (PDATA(pgm)->pgmtype == PGMTYPE_JTAGICE_MKII) {
|
||||
mycookie = pgm->cookie;
|
||||
pgm->cookie = PDATA(pgm)->chained_pdata;
|
||||
|
|
174
src/term.c
174
src/term.c
|
@ -346,178 +346,6 @@ static int cmd_dump(PROGRAMMER * pgm, struct avrpart * p,
|
|||
}
|
||||
|
||||
|
||||
// Convert the next n hex digits of s to a hex number
|
||||
static unsigned int tohex(const unsigned char *s, unsigned int n) {
|
||||
int ret, c;
|
||||
|
||||
ret = 0;
|
||||
while(n--) {
|
||||
ret *= 16;
|
||||
c = *s++;
|
||||
ret += c >= '0' && c <= '9'? c - '0': c >= 'a' && c <= 'f'? c - 'a' + 10: c - 'A' + 10;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Create a utf-8 character sequence from a single unicode character.
|
||||
* Permissive for some invalid unicode sequences but not for those with
|
||||
* high bit set). Returns numbers of characters written (0-6).
|
||||
*/
|
||||
static int wc_to_utf8str(unsigned int wc, unsigned char *str) {
|
||||
if(!(wc & ~0x7fu)) {
|
||||
*str = (char) wc;
|
||||
return 1;
|
||||
}
|
||||
if(!(wc & ~0x7ffu)) {
|
||||
*str++ = (char) ((wc >> 6) | 0xc0);
|
||||
*str++ = (char) ((wc & 0x3f) | 0x80);
|
||||
return 2;
|
||||
}
|
||||
if(!(wc & ~0xffffu)) {
|
||||
*str++ = (char) ((wc >> 12) | 0xe0);
|
||||
*str++ = (char) (((wc >> 6) & 0x3f) | 0x80);
|
||||
*str++ = (char) ((wc & 0x3f) | 0x80);
|
||||
return 3;
|
||||
}
|
||||
if(!(wc & ~0x1fffffu)) {
|
||||
*str++ = (char) ((wc >> 18) | 0xf0);
|
||||
*str++ = (char) (((wc >> 12) & 0x3f) | 0x80);
|
||||
*str++ = (char) (((wc >> 6) & 0x3f) | 0x80);
|
||||
*str++ = (char) ((wc & 0x3f) | 0x80);
|
||||
return 4;
|
||||
}
|
||||
if(!(wc & ~0x3ffffffu)) {
|
||||
*str++ = (char) ((wc >> 24) | 0xf8);
|
||||
*str++ = (char) (((wc >> 18) & 0x3f) | 0x80);
|
||||
*str++ = (char) (((wc >> 12) & 0x3f) | 0x80);
|
||||
*str++ = (char) (((wc >> 6) & 0x3f) | 0x80);
|
||||
*str++ = (char) ((wc & 0x3f) | 0x80);
|
||||
return 5;
|
||||
}
|
||||
if(!(wc & ~0x7fffffffu)) {
|
||||
*str++ = (char) ((wc >> 30) | 0xfc);
|
||||
*str++ = (char) (((wc >> 24) & 0x3f) | 0x80);
|
||||
*str++ = (char) (((wc >> 18) & 0x3f) | 0x80);
|
||||
*str++ = (char) (((wc >> 12) & 0x3f) | 0x80);
|
||||
*str++ = (char) (((wc >> 6) & 0x3f) | 0x80);
|
||||
*str++ = (char) ((wc & 0x3f) | 0x80);
|
||||
return 6;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Unescape C-style strings, destination d must hold enough space (and can be source s)
|
||||
static unsigned char *unescape(unsigned char *d, const unsigned char *s) {
|
||||
unsigned char *ret = d;
|
||||
int n, k;
|
||||
|
||||
while(*s) {
|
||||
switch (*s) {
|
||||
case '\\':
|
||||
switch (*++s) {
|
||||
case 'n':
|
||||
*d = '\n';
|
||||
break;
|
||||
case 't':
|
||||
*d = '\t';
|
||||
break;
|
||||
case 'a':
|
||||
*d = '\a';
|
||||
break;
|
||||
case 'b':
|
||||
*d = '\b';
|
||||
break;
|
||||
case 'e': // Non-standard ESC
|
||||
*d = 27;
|
||||
break;
|
||||
case 'f':
|
||||
*d = '\f';
|
||||
break;
|
||||
case 'r':
|
||||
*d = '\r';
|
||||
break;
|
||||
case 'v':
|
||||
*d = '\v';
|
||||
break;
|
||||
case '?':
|
||||
*d = '?';
|
||||
break;
|
||||
case '`':
|
||||
*d = '`';
|
||||
break;
|
||||
case '"':
|
||||
*d = '"';
|
||||
break;
|
||||
case '\'':
|
||||
*d = '\'';
|
||||
break;
|
||||
case '\\':
|
||||
*d = '\\';
|
||||
break;
|
||||
case '0':
|
||||
case '1':
|
||||
case '2':
|
||||
case '3':
|
||||
case '4':
|
||||
case '5':
|
||||
case '6':
|
||||
case '7': // 1-3 octal digits
|
||||
n = *s - '0';
|
||||
for(k = 0; k < 2 && s[1] >= '0' && s[1] <= '7'; k++) // Max 2 more octal characters
|
||||
n *= 8, n += s[1] - '0', s++;
|
||||
*d = n;
|
||||
break;
|
||||
case 'x': // Unlimited hex digits
|
||||
for(k = 0; isxdigit(s[k + 1]); k++)
|
||||
continue;
|
||||
if(k > 0) {
|
||||
*d = tohex(s + 1, k);
|
||||
s += k;
|
||||
} else { // No hex digits after \x? copy \x
|
||||
*d++ = '\\';
|
||||
*d = 'x';
|
||||
}
|
||||
break;
|
||||
case 'u': // Exactly 4 hex digits and valid unicode
|
||||
if(isxdigit(s[1]) && isxdigit(s[2]) && isxdigit(s[3]) && isxdigit(s[4]) &&
|
||||
(n = wc_to_utf8str(tohex(s+1, 4), d))) {
|
||||
d += n - 1;
|
||||
s += 4;
|
||||
} else { // Invalid \u sequence? copy \u
|
||||
*d++ = '\\';
|
||||
*d = 'u';
|
||||
}
|
||||
break;
|
||||
case 'U': // Exactly 6 hex digits and valid unicode
|
||||
if(isxdigit(s[1]) && isxdigit(s[2]) && isxdigit(s[3]) && isxdigit(s[4]) && isxdigit(s[5]) && isxdigit(s[6]) &&
|
||||
(n = wc_to_utf8str(tohex(s+1, 6), d))) {
|
||||
d += n - 1;
|
||||
s += 6;
|
||||
} else { // Invalid \U sequence? copy \U
|
||||
*d++ = '\\';
|
||||
*d = 'U';
|
||||
}
|
||||
break;
|
||||
default: // Keep the escape sequence (C would warn and remove \)
|
||||
*d++ = '\\';
|
||||
*d = *s;
|
||||
}
|
||||
break;
|
||||
|
||||
default: // Not an escape sequence: just copy the character
|
||||
*d = *s;
|
||||
}
|
||||
d++;
|
||||
s++;
|
||||
}
|
||||
*d = *s; // Terminate
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static size_t maxstrlen(int argc, char **argv) {
|
||||
size_t max = 0;
|
||||
|
||||
|
@ -800,7 +628,7 @@ static int cmd_write(PROGRAMMER * pgm, struct avrpart * p,
|
|||
}
|
||||
// Strip start and end quotes, and unescape C string
|
||||
strncpy(s, argi+1, arglen-2);
|
||||
unescape((unsigned char *) s, (unsigned char *) s);
|
||||
cfg_unescape(s, s);
|
||||
if (*argi == '\'') { // Single C-style character
|
||||
if(*s && s[1])
|
||||
terminal_message(MSG_INFO, "%s (write): only using first character of %s\n",
|
||||
|
|
60
src/update.c
60
src/update.c
|
@ -40,11 +40,7 @@ UPDATE * parse_op(char * s)
|
|||
int i;
|
||||
size_t fnlen;
|
||||
|
||||
upd = (UPDATE *)malloc(sizeof(UPDATE));
|
||||
if (upd == NULL) {
|
||||
avrdude_message(MSG_INFO, "%s: out of memory\n", progname);
|
||||
exit(1);
|
||||
}
|
||||
upd = (UPDATE *) cfg_malloc("parse_op()", sizeof(UPDATE));
|
||||
|
||||
i = 0;
|
||||
p = s;
|
||||
|
@ -55,22 +51,12 @@ UPDATE * parse_op(char * s)
|
|||
if (*p != ':') {
|
||||
upd->memtype = NULL; /* default memtype, "flash", or "application" */
|
||||
upd->op = DEVICE_WRITE;
|
||||
upd->filename = (char *)malloc(strlen(buf) + 1);
|
||||
if (upd->filename == NULL) {
|
||||
avrdude_message(MSG_INFO, "%s: out of memory\n", progname);
|
||||
exit(1);
|
||||
}
|
||||
strcpy(upd->filename, buf);
|
||||
upd->filename = cfg_strdup("parse_op()", buf);
|
||||
upd->format = FMT_AUTO;
|
||||
return upd;
|
||||
}
|
||||
|
||||
upd->memtype = (char *)malloc(strlen(buf)+1);
|
||||
if (upd->memtype == NULL) {
|
||||
avrdude_message(MSG_INFO, "%s: out of memory\n", progname);
|
||||
exit(1);
|
||||
}
|
||||
strcpy(upd->memtype, buf);
|
||||
upd->memtype = cfg_strdup("parse_op()", buf);
|
||||
|
||||
p++;
|
||||
if (*p == 'r') {
|
||||
|
@ -121,10 +107,10 @@ UPDATE * parse_op(char * s)
|
|||
// and to binary for read operations:
|
||||
upd->format = upd->op == DEVICE_READ? FMT_RBIN: FMT_AUTO;
|
||||
fnlen = strlen(cp);
|
||||
upd->filename = (char *)malloc(fnlen + 1);
|
||||
upd->filename = (char *) cfg_malloc("parse_op()", fnlen + 1);
|
||||
} else {
|
||||
fnlen = p - cp;
|
||||
upd->filename = (char *)malloc(fnlen +1);
|
||||
upd->filename = (char *) cfg_malloc("parse_op()", fnlen +1);
|
||||
c = *++p;
|
||||
if (c && p[1])
|
||||
/* More than one char - force failure below. */
|
||||
|
@ -150,12 +136,6 @@ UPDATE * parse_op(char * s)
|
|||
}
|
||||
}
|
||||
|
||||
if (upd->filename == NULL) {
|
||||
avrdude_message(MSG_INFO, "%s: out of memory\n", progname);
|
||||
free(upd->memtype);
|
||||
free(upd);
|
||||
return NULL;
|
||||
}
|
||||
memcpy(upd->filename, cp, fnlen);
|
||||
upd->filename[fnlen] = 0;
|
||||
|
||||
|
@ -166,19 +146,15 @@ UPDATE * dup_update(UPDATE * upd)
|
|||
{
|
||||
UPDATE * u;
|
||||
|
||||
u = (UPDATE *)malloc(sizeof(UPDATE));
|
||||
if (u == NULL) {
|
||||
avrdude_message(MSG_INFO, "%s: out of memory\n", progname);
|
||||
exit(1);
|
||||
}
|
||||
u = (UPDATE *) cfg_malloc("dup_update()", sizeof(UPDATE));
|
||||
|
||||
memcpy(u, upd, sizeof(UPDATE));
|
||||
|
||||
if (upd->memtype != NULL)
|
||||
u->memtype = strdup(upd->memtype);
|
||||
u->memtype = cfg_strdup("dup_update()", upd->memtype);
|
||||
else
|
||||
u->memtype = NULL;
|
||||
u->filename = strdup(upd->filename);
|
||||
u->filename = cfg_strdup("dup_update()", upd->filename);
|
||||
|
||||
return u;
|
||||
}
|
||||
|
@ -187,14 +163,10 @@ UPDATE * new_update(int op, char * memtype, int filefmt, char * filename)
|
|||
{
|
||||
UPDATE * u;
|
||||
|
||||
u = (UPDATE *)malloc(sizeof(UPDATE));
|
||||
if (u == NULL) {
|
||||
avrdude_message(MSG_INFO, "%s: out of memory\n", progname);
|
||||
exit(1);
|
||||
}
|
||||
u = (UPDATE *) cfg_malloc("new_update()", sizeof(UPDATE));
|
||||
|
||||
u->memtype = strdup(memtype);
|
||||
u->filename = strdup(filename);
|
||||
u->memtype = cfg_strdup("new_update()", memtype);
|
||||
u->filename = cfg_strdup("new_update()", filename);
|
||||
u->op = op;
|
||||
u->format = filefmt;
|
||||
|
||||
|
@ -476,11 +448,11 @@ int do_op(PROGRAMMER * pgm, struct avrpart * p, UPDATE * upd, enum updateflags f
|
|||
return LIBAVRDUDE_SOFTFAIL;
|
||||
}
|
||||
|
||||
AVRMEM_ALIAS * alias_mem = avr_find_memalias(p, mem);
|
||||
char alias_mem_desc[AVR_DESCLEN + 1] = "";
|
||||
if(alias_mem) {
|
||||
strcat(alias_mem_desc, "/");
|
||||
strcat(alias_mem_desc, alias_mem->desc);
|
||||
AVRMEM_ALIAS *alias_mem = avr_find_memalias(p, mem);
|
||||
char *alias_mem_desc = cfg_malloc("do_op()", 2 + (alias_mem && alias_mem->desc? strlen(alias_mem->desc): 0));
|
||||
if(alias_mem && alias_mem->desc && *alias_mem->desc) {
|
||||
*alias_mem_desc = '/';
|
||||
strcpy(alias_mem_desc+1, alias_mem->desc);
|
||||
}
|
||||
|
||||
switch (upd->op) {
|
||||
|
|
|
@ -160,9 +160,9 @@ static int usbasp_transmit(PROGRAMMER * pgm, unsigned char receive,
|
|||
unsigned char functionid, const unsigned char *send,
|
||||
unsigned char *buffer, int buffersize);
|
||||
#ifdef USE_LIBUSB_1_0
|
||||
static int usbOpenDevice(libusb_device_handle **device, int vendor, char *vendorName, int product, char *productName);
|
||||
static int usbOpenDevice(libusb_device_handle **device, int vendor, const char *vendorName, int product, const char *productName);
|
||||
#else
|
||||
static int usbOpenDevice(usb_dev_handle **device, int vendor, char *vendorName, int product, char *productName);
|
||||
static int usbOpenDevice(usb_dev_handle **device, int vendor, const char *vendorName, int product, const char *productName);
|
||||
#endif
|
||||
// interface - prog.
|
||||
static int usbasp_open(PROGRAMMER * pgm, char * port);
|
||||
|
@ -337,7 +337,7 @@ static int usbasp_transmit(PROGRAMMER * pgm,
|
|||
*/
|
||||
#ifdef USE_LIBUSB_1_0
|
||||
static int usbOpenDevice(libusb_device_handle **device, int vendor,
|
||||
char *vendorName, int product, char *productName)
|
||||
const char *vendorName, int product, const char *productName)
|
||||
{
|
||||
libusb_device_handle *handle = NULL;
|
||||
int errorCode = USB_ERROR_NOTFOUND;
|
||||
|
@ -412,7 +412,7 @@ static int usbOpenDevice(libusb_device_handle **device, int vendor,
|
|||
}
|
||||
#else
|
||||
static int usbOpenDevice(usb_dev_handle **device, int vendor,
|
||||
char *vendorName, int product, char *productName)
|
||||
const char *vendorName, int product, const char *productName)
|
||||
{
|
||||
struct usb_bus *bus;
|
||||
struct usb_device *dev;
|
||||
|
|
Loading…
Reference in New Issue