Submitted by Martino Facchin:
patch #9110: Let reserved fuse bits to be read as *don't care* * avr.c (compare_memory_masked): New function * libavrdude.h: declare compare_memory_masked(); also, insist on C99 so <stdint.h> is required now * main.c: Use compare_memory_masked() in safemode comparisons C99 / stdint.h has basically already been required before, as types like uint8_t are in use in a number of other locations throughout the source. git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk/avrdude@1470 81a1dc3b-b13d-400b-aceb-764788c761c2
This commit is contained in:
parent
10df0ff15a
commit
db7249bf57
|
@ -1,3 +1,12 @@
|
||||||
|
2021-11-12 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||||
|
|
||||||
|
Submitted by Martino Facchin:
|
||||||
|
patch #9110: Let reserved fuse bits to be read as *don't care*
|
||||||
|
* avr.c (compare_memory_masked): New function
|
||||||
|
* libavrdude.h: declare compare_memory_masked(); also, insist on C99
|
||||||
|
so <stdint.h> is required now
|
||||||
|
* main.c: Use compare_memory_masked() in safemode comparisons
|
||||||
|
|
||||||
2021-11-11 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
2021-11-11 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||||
|
|
||||||
Submitted by Joseph Coffland:
|
Submitted by Joseph Coffland:
|
||||||
|
|
1
NEWS
1
NEWS
|
@ -104,6 +104,7 @@ Current:
|
||||||
patch #9697: Add iseavrprog support
|
patch #9697: Add iseavrprog support
|
||||||
patch #10017: uspasp / tpi: Automatically clear configuration byte (fuse) before writing it
|
patch #10017: uspasp / tpi: Automatically clear configuration byte (fuse) before writing it
|
||||||
patch #8957: Allow reading prodsig memory from stk500v2 on xmega devices
|
patch #8957: Allow reading prodsig memory from stk500v2 on xmega devices
|
||||||
|
patch #9110: Let reserved fuse bits to be read as *don't care*
|
||||||
|
|
||||||
* Internals:
|
* Internals:
|
||||||
- New avrdude.conf keyword "family_id", used to verify SIB attributes
|
- New avrdude.conf keyword "family_id", used to verify SIB attributes
|
||||||
|
|
43
avr.c
43
avr.c
|
@ -1063,6 +1063,30 @@ int avr_signature(PROGRAMMER * pgm, AVRPART * p)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static uint8_t get_fuse_bitmask(AVRMEM * m) {
|
||||||
|
uint8_t bitmask_r = 0;
|
||||||
|
uint8_t bitmask_w = 0;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (!m || m->size > 1) {
|
||||||
|
// not a fuse, compare bytes directly
|
||||||
|
return 0xFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
// For fuses, only compare bytes that are actually written *and* read.
|
||||||
|
for (i = 0; i < 32; i++) {
|
||||||
|
if (m->op[AVR_OP_WRITE]->bit[i].type == AVR_CMDBIT_INPUT)
|
||||||
|
bitmask_w |= (1 << m->op[AVR_OP_WRITE]->bit[i].bitno);
|
||||||
|
if (m->op[AVR_OP_READ]->bit[i].type == AVR_CMDBIT_OUTPUT)
|
||||||
|
bitmask_r |= (1 << m->op[AVR_OP_READ]->bit[i].bitno);
|
||||||
|
}
|
||||||
|
return bitmask_r & bitmask_w;
|
||||||
|
}
|
||||||
|
|
||||||
|
int compare_memory_masked(AVRMEM * m, uint8_t b1, uint8_t b2) {
|
||||||
|
uint8_t bitmask = get_fuse_bitmask(m);
|
||||||
|
return (b1 & bitmask) != (b2 & bitmask);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Verify the memory buffer of p with that of v. The byte range of v,
|
* Verify the memory buffer of p with that of v. The byte range of v,
|
||||||
|
@ -1109,11 +1133,30 @@ int avr_verify(AVRPART * p, AVRPART * v, char * memtype, int size)
|
||||||
for (i=0; i<size; i++) {
|
for (i=0; i<size; i++) {
|
||||||
if ((b->tags[i] & TAG_ALLOCATED) != 0 &&
|
if ((b->tags[i] & TAG_ALLOCATED) != 0 &&
|
||||||
buf1[i] != buf2[i]) {
|
buf1[i] != buf2[i]) {
|
||||||
|
uint8_t bitmask = get_fuse_bitmask(a);
|
||||||
|
if((buf1[i] & bitmask) != (buf2[i] & bitmask)) {
|
||||||
|
// Mismatch is not just in unused bits
|
||||||
avrdude_message(MSG_INFO, "%s: verification error, first mismatch at byte 0x%04x\n"
|
avrdude_message(MSG_INFO, "%s: verification error, first mismatch at byte 0x%04x\n"
|
||||||
"%s0x%02x != 0x%02x\n",
|
"%s0x%02x != 0x%02x\n",
|
||||||
progname, i,
|
progname, i,
|
||||||
progbuf, buf1[i], buf2[i]);
|
progbuf, buf1[i], buf2[i]);
|
||||||
return -1;
|
return -1;
|
||||||
|
} else {
|
||||||
|
// Mismatch is only in unused bits
|
||||||
|
if ((buf1[i] | bitmask) != 0xff) {
|
||||||
|
// Programmer returned unused bits as 0, must be the part/programmer
|
||||||
|
avrdude_message(MSG_INFO, "%s: WARNING: ignoring mismatch in unused bits of \"%s\"\n"
|
||||||
|
"%s(0x%02x != 0x%02x). To prevent this warning fix the part\n"
|
||||||
|
"%sor programmer definition in the config file.\n",
|
||||||
|
progname, memtype, progbuf, buf1[i], buf2[i], progbuf);
|
||||||
|
} else {
|
||||||
|
// Programmer returned unused bits as 1, must be the user
|
||||||
|
avrdude_message(MSG_INFO, "%s: WARNING: ignoring mismatch in unused bits of \"%s\"\n"
|
||||||
|
"%s(0x%02x != 0x%02x). To prevent this warning set unused bits\n"
|
||||||
|
"%sto 1 when writing (double check with your datasheet first).\n",
|
||||||
|
progname, memtype, progbuf, buf1[i], buf2[i], progbuf);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -33,11 +33,7 @@
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
typedef uint32_t pinmask_t;
|
typedef uint32_t pinmask_t;
|
||||||
#else
|
#else
|
||||||
#if UINT_MAX >= 0xFFFFFFFF
|
#error Need a C99 capable compiler
|
||||||
typedef unsigned int pinmask_t;
|
|
||||||
#else
|
|
||||||
typedef unsigned long pinmask_t;
|
|
||||||
#endif
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
@ -342,6 +338,9 @@ typedef void (*walk_avrparts_cb)(const char *name, const char *desc,
|
||||||
void *cookie);
|
void *cookie);
|
||||||
void walk_avrparts(LISTID avrparts, walk_avrparts_cb cb, void *cookie);
|
void walk_avrparts(LISTID avrparts, walk_avrparts_cb cb, void *cookie);
|
||||||
void sort_avrparts(LISTID avrparts);
|
void sort_avrparts(LISTID avrparts);
|
||||||
|
|
||||||
|
int compare_memory_masked(AVRMEM * m, uint8_t buf1, uint8_t buf2);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
16
main.c
16
main.c
|
@ -1300,8 +1300,11 @@ int main(int argc, char * argv [])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AVRMEM * m;
|
||||||
|
|
||||||
/* Now check what fuses are against what they should be */
|
/* Now check what fuses are against what they should be */
|
||||||
if (safemodeafter_fuse != safemode_fuse) {
|
m = avr_locate_mem(p, "fuse");
|
||||||
|
if (compare_memory_masked(m, safemodeafter_fuse, safemode_fuse)) {
|
||||||
fuses_updated = 1;
|
fuses_updated = 1;
|
||||||
avrdude_message(MSG_INFO, "%s: safemode: fuse changed! Was %x, and is now %x\n",
|
avrdude_message(MSG_INFO, "%s: safemode: fuse changed! Was %x, and is now %x\n",
|
||||||
progname, safemode_fuse, safemodeafter_fuse);
|
progname, safemode_fuse, safemodeafter_fuse);
|
||||||
|
@ -1329,7 +1332,8 @@ int main(int argc, char * argv [])
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Now check what fuses are against what they should be */
|
/* Now check what fuses are against what they should be */
|
||||||
if (safemodeafter_lfuse != safemode_lfuse) {
|
m = avr_locate_mem(p, "lfuse");
|
||||||
|
if (compare_memory_masked(m, safemodeafter_lfuse, safemode_lfuse)) {
|
||||||
fuses_updated = 1;
|
fuses_updated = 1;
|
||||||
avrdude_message(MSG_INFO, "%s: safemode: lfuse changed! Was %x, and is now %x\n",
|
avrdude_message(MSG_INFO, "%s: safemode: lfuse changed! Was %x, and is now %x\n",
|
||||||
progname, safemode_lfuse, safemodeafter_lfuse);
|
progname, safemode_lfuse, safemodeafter_lfuse);
|
||||||
|
@ -1357,7 +1361,8 @@ int main(int argc, char * argv [])
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Now check what fuses are against what they should be */
|
/* Now check what fuses are against what they should be */
|
||||||
if (safemodeafter_hfuse != safemode_hfuse) {
|
m = avr_locate_mem(p, "hfuse");
|
||||||
|
if (compare_memory_masked(m, safemodeafter_hfuse, safemode_hfuse)) {
|
||||||
fuses_updated = 1;
|
fuses_updated = 1;
|
||||||
avrdude_message(MSG_INFO, "%s: safemode: hfuse changed! Was %x, and is now %x\n",
|
avrdude_message(MSG_INFO, "%s: safemode: hfuse changed! Was %x, and is now %x\n",
|
||||||
progname, safemode_hfuse, safemodeafter_hfuse);
|
progname, safemode_hfuse, safemodeafter_hfuse);
|
||||||
|
@ -1382,7 +1387,8 @@ int main(int argc, char * argv [])
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Now check what fuses are against what they should be */
|
/* Now check what fuses are against what they should be */
|
||||||
if (safemodeafter_efuse != safemode_efuse) {
|
m = avr_locate_mem(p, "efuse");
|
||||||
|
if (compare_memory_masked(m, safemodeafter_efuse, safemode_efuse)) {
|
||||||
fuses_updated = 1;
|
fuses_updated = 1;
|
||||||
avrdude_message(MSG_INFO, "%s: safemode: efuse changed! Was %x, and is now %x\n",
|
avrdude_message(MSG_INFO, "%s: safemode: efuse changed! Was %x, and is now %x\n",
|
||||||
progname, safemode_efuse, safemodeafter_efuse);
|
progname, safemode_efuse, safemodeafter_efuse);
|
||||||
|
@ -1410,7 +1416,7 @@ int main(int argc, char * argv [])
|
||||||
avrdude_message(MSG_INFO, "%s: safemode: ", progname);
|
avrdude_message(MSG_INFO, "%s: safemode: ", progname);
|
||||||
if (failures == 0) {
|
if (failures == 0) {
|
||||||
avrdude_message(MSG_INFO, "Fuses OK (E:%02X, H:%02X, L:%02X)\n",
|
avrdude_message(MSG_INFO, "Fuses OK (E:%02X, H:%02X, L:%02X)\n",
|
||||||
safemode_efuse, safemode_hfuse, safemode_lfuse);
|
safemodeafter_efuse, safemodeafter_hfuse, safemodeafter_lfuse);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
avrdude_message(MSG_INFO, "Fuses not recovered, sorry\n");
|
avrdude_message(MSG_INFO, "Fuses not recovered, sorry\n");
|
||||||
|
|
Loading…
Reference in New Issue