Add -p \* to summarise properties of parts in conf
This commit is contained in:
parent
4601bee4af
commit
952ad72fb9
313
src/main.c
313
src/main.c
|
@ -26,7 +26,7 @@
|
|||
* For parallel port connected programmers, the pin definitions can be
|
||||
* changed via a config file. See the config file for instructions on
|
||||
* how to add a programmer definition.
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
#include "ac_cfg.h"
|
||||
|
@ -102,7 +102,7 @@ int ovsigck; /* 1=override sig check, 0=don't */
|
|||
*/
|
||||
static void usage(void)
|
||||
{
|
||||
avrdude_message(MSG_INFO,
|
||||
avrdude_message(MSG_INFO,
|
||||
"Usage: %s [options]\n"
|
||||
"Options:\n"
|
||||
" -p <partno> Required. Specify AVR device.\n"
|
||||
|
@ -310,6 +310,119 @@ static void replace_backslashes(char *s)
|
|||
}
|
||||
|
||||
|
||||
static char cmdbitchar(CMDBIT cb) {
|
||||
switch(cb.type) {
|
||||
case AVR_CMDBIT_IGNORE:
|
||||
return 'x';
|
||||
case AVR_CMDBIT_VALUE:
|
||||
return cb.value? '1': '0';
|
||||
case AVR_CMDBIT_ADDRESS:
|
||||
return 'a';
|
||||
case AVR_CMDBIT_INPUT:
|
||||
return 'i';
|
||||
case AVR_CMDBIT_OUTPUT:
|
||||
return 'o';
|
||||
default:
|
||||
return '?';
|
||||
}
|
||||
}
|
||||
|
||||
static const char *opcodename(int what) {
|
||||
switch(what) {
|
||||
case AVR_OP_READ:
|
||||
return "read";
|
||||
case AVR_OP_WRITE:
|
||||
return "write";
|
||||
case AVR_OP_READ_LO:
|
||||
return "read_lo";
|
||||
case AVR_OP_READ_HI:
|
||||
return "read_hi";
|
||||
case AVR_OP_WRITE_LO:
|
||||
return "write_lo";
|
||||
case AVR_OP_WRITE_HI:
|
||||
return "write_hi";
|
||||
case AVR_OP_LOADPAGE_LO:
|
||||
return "loadpage_lo";
|
||||
case AVR_OP_LOADPAGE_HI:
|
||||
return "loadpage_hi";
|
||||
case AVR_OP_LOAD_EXT_ADDR:
|
||||
return "load_ext_addr";
|
||||
case AVR_OP_WRITEPAGE:
|
||||
return "writepage";
|
||||
case AVR_OP_CHIP_ERASE:
|
||||
return "chip_erase";
|
||||
case AVR_OP_PGM_ENABLE:
|
||||
return "pgm_enable";
|
||||
default:
|
||||
return "???";
|
||||
}
|
||||
}
|
||||
|
||||
static void printopcode(AVRPART *p, const char *d, OPCODE **opa, int what) {
|
||||
unsigned char cmd[4];
|
||||
int i;
|
||||
|
||||
if(opa && opa[what]) {
|
||||
memset(cmd, 0, sizeof cmd);
|
||||
avr_set_bits(opa[what], cmd);
|
||||
|
||||
avrdude_message(MSG_INFO, ".op %s %s %s 0x%02x%02x%02x%02x ", p->desc, d, opcodename(what), cmd[0], cmd[1], cmd[2], cmd[3]);
|
||||
for(i=31; i >= 0; i--) {
|
||||
avrdude_message(MSG_INFO, "%c", cmdbitchar(opa[what]->bit[i]));
|
||||
if(i%8 == 0)
|
||||
avrdude_message(MSG_INFO, "%c", i? ' ': '\n');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void printallopcodes(AVRPART *p, const char *d, OPCODE **opa) {
|
||||
for(int i=0; i<AVR_OP_MAX; i++)
|
||||
printopcode(p, d, opa, i);
|
||||
}
|
||||
|
||||
|
||||
/* returns position 0..31 of highest bit set or INT_MIN if no bit is set */
|
||||
static int intlog2(unsigned int n) {
|
||||
int ret;
|
||||
|
||||
if(!n)
|
||||
return INT_MIN;
|
||||
|
||||
for(ret = 0; n >>= 1; ret++)
|
||||
continue;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
// check whether address bits are where they should be in ISP commands
|
||||
static void checkaddr(int memsize, int pagesize, int what, OPCODE *op, AVRPART *p, AVRMEM *m) {
|
||||
int i, lo, hi;
|
||||
const char *whatstr = opcodename(what);
|
||||
|
||||
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
|
||||
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)) {
|
||||
avrdude_message(MSG_INFO, ".cmdbit%d %s %s-%s outside addressable space should be x or 0, but is %c", i+8, p->desc, m->desc, whatstr, cmdbitchar(op->bit[i+8]));
|
||||
if(op->bit[i+8].type == AVR_CMDBIT_ADDRESS)
|
||||
avrdude_message(MSG_INFO, "%d", op->bit[i+8].bitno);
|
||||
avrdude_message(MSG_INFO, "\n");
|
||||
}
|
||||
} else {
|
||||
if(op->bit[i+8].type != AVR_CMDBIT_ADDRESS)
|
||||
avrdude_message(MSG_INFO, ".cmdbit%d %s %s-%s is %c but should be a\n", i+8, p->desc, m->desc, whatstr, cmdbitchar(op->bit[i+8]));
|
||||
else if(op->bit[i+8].bitno != i)
|
||||
avrdude_message(MSG_INFO, ".cmdbit%d %s %s-%s inconsistent: a%d specified as a%d\n", i+8, p->desc, m->desc, whatstr, i, op->bit[i+8].bitno);
|
||||
}
|
||||
}
|
||||
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)
|
||||
avrdude_message(MSG_INFO, ".cmdbit%d %s %s-%s contains a%d which it shouldn't\n", i, p->desc, m->desc, whatstr, op->bit[i].bitno);
|
||||
}
|
||||
|
||||
/*
|
||||
* main routine
|
||||
*/
|
||||
|
@ -830,6 +943,200 @@ int main(int argc, char * argv [])
|
|||
|
||||
avrdude_message(MSG_NOTICE, "\n");
|
||||
|
||||
// print part descriptions for debugging avrdude.conf and exit
|
||||
if(partdesc && 0 == strcmp(partdesc, "*")) {
|
||||
int first = 1;
|
||||
|
||||
for(LNODEID ln1 = lfirst(part_list); ln1; ln1 = lnext(ln1)) {
|
||||
AVRPART *p = ldata(ln1);
|
||||
int flashsize = 0, flashoffset = 0, flashpagesize = 0, eepromsize = 0, eepromoffset = 0, eeprompagesize = 0;
|
||||
|
||||
if(p->mem) {
|
||||
for(LNODEID lnm=lfirst(p->mem); lnm; lnm=lnext(lnm)) {
|
||||
AVRMEM *m = ldata(lnm);
|
||||
if(!flashsize && m->desc && 0==strcmp(m->desc, "flash")) {
|
||||
flashsize = m->size;
|
||||
flashpagesize = m->page_size;
|
||||
flashoffset = m->offset;
|
||||
}
|
||||
if(!eepromsize && m->desc && 0==strcmp(m->desc, "eeprom")) {
|
||||
eepromsize = m->size;
|
||||
eepromoffset = m->offset;
|
||||
eeprompagesize = m->page_size;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#define AD_SPI_EN_CE_SIG 1
|
||||
#define AD_SPI_PROGMEM 2
|
||||
#define AD_SPI_PROGMEM_PAGED 4
|
||||
#define AD_SPI_LOAD_EXT_ADDR 8
|
||||
#define AD_SPI_EEPROM 16
|
||||
#define AD_SPI_EEPROM_PAGED 32
|
||||
#define AD_SPI_LOCK 64
|
||||
#define AD_SPI_CALIBRATION 128
|
||||
#define AD_SPI_LFUSE 256
|
||||
#define AD_SPI_HFUSE 512
|
||||
#define AD_SPI_EFUSE 1024
|
||||
|
||||
if(flashsize && !index(p->desc, ' ')) {
|
||||
int len, ok, nfuses;
|
||||
AVRMEM *m;
|
||||
OPCODE *oc;
|
||||
|
||||
if(!first)
|
||||
avrdude_message(MSG_INFO, "\n");
|
||||
first = 0;
|
||||
|
||||
ok = 2047;
|
||||
nfuses = 0;
|
||||
|
||||
if(!p->op[AVR_OP_PGM_ENABLE])
|
||||
ok &= ~AD_SPI_EN_CE_SIG;
|
||||
|
||||
if(!p->op[AVR_OP_CHIP_ERASE])
|
||||
ok &= ~AD_SPI_EN_CE_SIG;
|
||||
|
||||
if((m = avr_locate_mem(p, "flash"))) {
|
||||
if((oc = m->op[AVR_OP_LOAD_EXT_ADDR])) {
|
||||
// @@@ to do: check whether address is put at lsb of third byte
|
||||
} else
|
||||
ok &= ~AD_SPI_LOAD_EXT_ADDR;
|
||||
|
||||
if((oc = m->op[AVR_OP_READ_HI]))
|
||||
checkaddr(m->size>>1, 1, AVR_OP_READ_HI, oc, p, m);
|
||||
else
|
||||
ok &= ~AD_SPI_PROGMEM;
|
||||
|
||||
if((oc = m->op[AVR_OP_READ_LO]))
|
||||
checkaddr(m->size>>1, 1, AVR_OP_READ_LO, oc, p, m);
|
||||
else
|
||||
ok &= ~AD_SPI_PROGMEM;
|
||||
|
||||
if((oc = m->op[AVR_OP_WRITE_HI]))
|
||||
checkaddr(m->size>>1, 1, AVR_OP_WRITE_HI, oc, p, m);
|
||||
else
|
||||
ok &= ~AD_SPI_PROGMEM;
|
||||
|
||||
if((oc = m->op[AVR_OP_WRITE_LO]))
|
||||
checkaddr(m->size>>1, 1, AVR_OP_WRITE_LO, oc, p, m);
|
||||
else
|
||||
ok &= ~AD_SPI_PROGMEM;
|
||||
|
||||
if((oc = m->op[AVR_OP_LOADPAGE_HI]))
|
||||
checkaddr(m->page_size>>1, 1, AVR_OP_LOADPAGE_HI, oc, p, m);
|
||||
else
|
||||
ok &= ~AD_SPI_PROGMEM_PAGED;
|
||||
|
||||
if((oc = m->op[AVR_OP_LOADPAGE_LO]))
|
||||
checkaddr(m->page_size>>1, 1, AVR_OP_LOADPAGE_LO, oc, p, m);
|
||||
else
|
||||
ok &= ~AD_SPI_PROGMEM_PAGED;
|
||||
|
||||
if((oc = m->op[AVR_OP_WRITEPAGE]))
|
||||
checkaddr(m->size>>1, m->page_size>>1, AVR_OP_WRITEPAGE, oc, p, m);
|
||||
else
|
||||
ok &= ~AD_SPI_PROGMEM_PAGED;
|
||||
} else
|
||||
ok &= ~(AD_SPI_PROGMEM_PAGED | AD_SPI_PROGMEM);
|
||||
|
||||
if((m = avr_locate_mem(p, "eeprom"))) {
|
||||
if((oc = m->op[AVR_OP_READ])) {
|
||||
checkaddr(m->size, 1, AVR_OP_READ, oc, p, m);
|
||||
} else
|
||||
ok &= ~AD_SPI_EEPROM;
|
||||
|
||||
if((oc = m->op[AVR_OP_WRITE])) {
|
||||
checkaddr(m->size, 1, AVR_OP_WRITE, oc, p, m);
|
||||
} else
|
||||
ok &= ~AD_SPI_EEPROM;
|
||||
|
||||
if((oc = m->op[AVR_OP_LOADPAGE_LO])) {
|
||||
checkaddr(m->page_size, 1, AVR_OP_LOADPAGE_LO, oc, p, m);
|
||||
} else
|
||||
ok &= ~AD_SPI_EEPROM_PAGED;
|
||||
|
||||
if((oc = m->op[AVR_OP_WRITEPAGE])) {
|
||||
checkaddr(m->size, m->page_size, AVR_OP_WRITEPAGE, oc, p, m);
|
||||
} else
|
||||
ok &= ~AD_SPI_EEPROM_PAGED;
|
||||
} else
|
||||
ok &= ~(AD_SPI_EEPROM_PAGED | AD_SPI_EEPROM);
|
||||
|
||||
if((m = avr_locate_mem(p, "signature")) && (oc = m->op[AVR_OP_READ]))
|
||||
checkaddr(m->size, 1, AVR_OP_READ, oc, p, m);
|
||||
else
|
||||
ok &= ~AD_SPI_EN_CE_SIG;
|
||||
|
||||
if((m = avr_locate_mem(p, "calibration")) && (oc = m->op[AVR_OP_READ]))
|
||||
checkaddr(m->size, 1, AVR_OP_READ, oc, p, m);
|
||||
else
|
||||
ok &= ~AD_SPI_CALIBRATION;
|
||||
|
||||
// actually, some AT90S... parts cannot read, only write lock bits :-0
|
||||
if( ! ((m = avr_locate_mem(p, "lock")) && m->op[AVR_OP_WRITE]))
|
||||
ok &= ~AD_SPI_LOCK;
|
||||
|
||||
if(((m = avr_locate_mem(p, "fuse")) || (m = avr_locate_mem(p, "lfuse"))) && m->op[AVR_OP_READ] && m->op[AVR_OP_WRITE])
|
||||
nfuses++;
|
||||
else
|
||||
ok &= ~AD_SPI_LFUSE;
|
||||
|
||||
if((m = avr_locate_mem(p, "hfuse")) && m->op[AVR_OP_READ] && m->op[AVR_OP_WRITE])
|
||||
nfuses++;
|
||||
else
|
||||
ok &= ~AD_SPI_HFUSE;
|
||||
|
||||
if((m = avr_locate_mem(p, "efuse")) && m->op[AVR_OP_READ] && m->op[AVR_OP_WRITE])
|
||||
nfuses++;
|
||||
else
|
||||
ok &= ~AD_SPI_EFUSE;
|
||||
|
||||
len = 16-strlen(p->desc);
|
||||
avrdude_message(MSG_INFO, ".desc '%s' =>%*s [0x%02X, 0x%02X, 0x%02X, 0x%08x, 0x%05x, 0x%03x, 0x%06x, 0x%04x, 0x%03x, %d, 0x%03x, 0x%04x], # %s %d\n",
|
||||
p->desc, len > 0? len: 0, "",
|
||||
p->signature[0], p->signature[1], p->signature[2],
|
||||
flashoffset, flashsize, flashpagesize,
|
||||
eepromoffset, eepromsize, eeprompagesize,
|
||||
nfuses,
|
||||
ok,
|
||||
p->flags,
|
||||
p->config_file, p->lineno
|
||||
);
|
||||
}
|
||||
|
||||
printallopcodes(p, "part", p->op);
|
||||
if(p->mem) {
|
||||
for(LNODEID lnm=lfirst(p->mem); lnm; lnm=lnext(lnm)) {
|
||||
AVRMEM *m = ldata(lnm);
|
||||
if(m)
|
||||
printallopcodes(p, m->desc, m->op);
|
||||
}
|
||||
}
|
||||
|
||||
// print wait delays for AVR family parts
|
||||
if(!(p->flags & (AVRPART_HAS_PDI | AVRPART_HAS_UPDI | AVRPART_HAS_TPI | AVRPART_AVR32)))
|
||||
avrdude_message(MSG_INFO, ".wd_chip_erase %.3f ms %s\n", p->chip_erase_delay/1000.0, p->desc);
|
||||
if(p->mem) {
|
||||
for(LNODEID lnm=lfirst(p->mem); lnm; lnm=lnext(lnm)) {
|
||||
AVRMEM *m = ldata(lnm);
|
||||
// write delays not needed for read-only calibration and signature memories
|
||||
if(strcmp(m->desc, "calibration") && strcmp(m->desc, "signature")) {
|
||||
if(!(p->flags & (AVRPART_HAS_PDI | AVRPART_HAS_UPDI | AVRPART_HAS_TPI | AVRPART_AVR32))) {
|
||||
if(m->min_write_delay == m->max_write_delay)
|
||||
avrdude_message(MSG_INFO, ".wd_%s %.3f ms %s\n", m->desc, m->min_write_delay/1000.0, p->desc);
|
||||
else {
|
||||
avrdude_message(MSG_INFO, ".wd_min_%s %.3f ms %s\n", m->desc, m->min_write_delay/1000.0, p->desc);
|
||||
avrdude_message(MSG_INFO, ".wd_max_%s %.3f ms %s\n", m->desc, m->max_write_delay/1000.0, p->desc);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (partdesc) {
|
||||
if (strcmp(partdesc, "?") == 0) {
|
||||
avrdude_message(MSG_INFO, "\n");
|
||||
|
@ -1161,7 +1468,7 @@ int main(int argc, char * argv [])
|
|||
goto main_exit;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
sig = avr_locate_mem(p, "signature");
|
||||
if (sig == NULL) {
|
||||
avrdude_message(MSG_INFO, "%s: WARNING: signature data not defined for device \"%s\"\n",
|
||||
|
|
Loading…
Reference in New Issue