|
| 1 | +--- avr.c |
| 2 | ++++ avr.c |
| 3 | +@@ -1058,6 +1058,36 @@ int avr_signature(PROGRAMMER * pgm, AVRPART * p) |
| 4 | + return 0; |
| 5 | + } |
| 6 | + |
| 7 | ++uint8_t get_fuse_bitmask(AVRMEM * m) { |
| 8 | ++ uint8_t bitmask_r = 0; |
| 9 | ++ uint8_t bitmask_w = 0; |
| 10 | ++ int i, j; |
| 11 | ++ |
| 12 | ++ if (m->size > 1) { |
| 13 | ++ // not a fuse, compare bytes directly |
| 14 | ++ return 0xFF; |
| 15 | ++ } |
| 16 | ++ |
| 17 | ++ for (i=0; i<AVR_OP_MAX; i++) { |
| 18 | ++ if (m->op[i] && i == AVR_OP_READ) { |
| 19 | ++ for (j=7; j>=0; j--) { |
| 20 | ++ bitmask_r |= (m->op[i]->bit[j].type != AVR_CMDBIT_IGNORE) << j; |
| 21 | ++ } |
| 22 | ++ } |
| 23 | ++ if (m->op[i] && i == AVR_OP_WRITE) { |
| 24 | ++ for (j=7; j>=0; j--) { |
| 25 | ++ bitmask_w |= (m->op[i]->bit[j].type != AVR_CMDBIT_VALUE && |
| 26 | ++ m->op[i]->bit[j].type != AVR_CMDBIT_IGNORE) << j; |
| 27 | ++ } |
| 28 | ++ } |
| 29 | ++ } |
| 30 | ++ return bitmask_r & bitmask_w; |
| 31 | ++} |
| 32 | ++ |
| 33 | ++int compare_memory_masked(AVRMEM * m, unsigned char buf1, unsigned char buf2) { |
| 34 | ++ uint8_t bitmask = get_fuse_bitmask(m); |
| 35 | ++ return ((buf1 & bitmask) != (buf2 & bitmask)); |
| 36 | ++} |
| 37 | + |
| 38 | + /* |
| 39 | + * Verify the memory buffer of p with that of v. The byte range of v, |
| 40 | +@@ -1103,7 +1133,7 @@ int avr_verify(AVRPART * p, AVRPART * v, char * memtype, int size) |
| 41 | + |
| 42 | + for (i=0; i<size; i++) { |
| 43 | + if ((b->tags[i] & TAG_ALLOCATED) != 0 && |
| 44 | +- buf1[i] != buf2[i]) { |
| 45 | ++ compare_memory_masked(a , buf1[i], buf2[i])) { |
| 46 | + avrdude_message(MSG_INFO, "%s: verification error, first mismatch at byte 0x%04x\n" |
| 47 | + "%s0x%02x != 0x%02x\n", |
| 48 | + progname, i, |
| 49 | +--- libavrdude.h |
| 50 | ++++ libavrdude.h |
| 51 | +@@ -337,6 +337,9 @@ typedef void (*walk_avrparts_cb)(const char *name, const char *desc, |
| 52 | + void *cookie); |
| 53 | + void walk_avrparts(LISTID avrparts, walk_avrparts_cb cb, void *cookie); |
| 54 | + void sort_avrparts(LISTID avrparts); |
| 55 | ++ |
| 56 | ++uint8_t get_fuse_bitmask(AVRMEM * m); |
| 57 | ++ |
| 58 | + #ifdef __cplusplus |
| 59 | + } |
| 60 | + #endif |
| 61 | +--- main.c |
| 62 | ++++ main.c |
| 63 | +@@ -1239,6 +1239,7 @@ int main(int argc, char * argv []) |
| 64 | + unsigned char safemodeafter_lfuse = 0xff; |
| 65 | + unsigned char safemodeafter_hfuse = 0xff; |
| 66 | + unsigned char safemodeafter_efuse = 0xff; |
| 67 | ++ unsigned char safemodeafter_efuse_mask = 0xff; |
| 68 | + unsigned char safemodeafter_fuse = 0xff; |
| 69 | + unsigned char failures = 0; |
| 70 | + char yes[1] = {'y'}; |
| 71 | +@@ -1345,8 +1346,15 @@ int main(int argc, char * argv []) |
| 72 | + } |
| 73 | + } |
| 74 | + |
| 75 | ++ /* Get efuse bitmask if it exists */ |
| 76 | ++ AVRMEM * m; |
| 77 | ++ m = avr_locate_mem(p, "efuse"); |
| 78 | ++ if (m != NULL) { |
| 79 | ++ safemodeafter_efuse_mask = get_fuse_bitmask(m); |
| 80 | ++ } |
| 81 | ++ |
| 82 | + /* Now check what fuses are against what they should be */ |
| 83 | +- if (safemodeafter_efuse != safemode_efuse) { |
| 84 | ++ if ((safemodeafter_efuse & safemodeafter_efuse_mask) != (safemode_efuse & safemodeafter_efuse_mask)) { |
| 85 | + fuses_updated = 1; |
| 86 | + avrdude_message(MSG_INFO, "%s: safemode: efuse changed! Was %x, and is now %x\n", |
| 87 | + progname, safemode_efuse, safemodeafter_efuse); |
| 88 | + |
0 commit comments