From 65d5cfadc1f4088babd29cfb7957737db94db791 Mon Sep 17 00:00:00 2001 From: Joerg Wunsch Date: Tue, 11 Jan 2022 22:00:22 +0100 Subject: [PATCH] Fix for TPI fuse write In get_fuse_bitmask(), ensure the AVR_OP_READ and AVR_OP_WRITE m->op[] fields are actually filled in, before referencing them. If they are missing, just return a full byte mask (0xFF). In avr_write(), for TPI memory, if the write consist of one byte onle (which is the case for fuse byte writing), resort to avr_write_byte() instead as it already implements everything needed. This leaves the avr_write() implementation to handle full paged writes with an even number of bytes only. --- src/avr.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/avr.c b/src/avr.c index dd9095e4..68ecc9a4 100644 --- a/src/avr.c +++ b/src/avr.c @@ -867,6 +867,11 @@ int avr_write(PROGRAMMER * pgm, AVRPART * p, char * memtype, int size, if ((p->flags & AVRPART_HAS_TPI) && m->page_size > 1 && pgm->cmd_tpi != NULL) { + if (wsize == 1) { + /* fuse (configuration) memory: only single byte to write */ + return avr_write_byte(pgm, p, m, 0, m->buf[0]) == 0? 1: -1; + } + while (avr_tpi_poll_nvmbsy(pgm)); /* setup for WORD_WRITE */ @@ -1074,6 +1079,11 @@ static uint8_t get_fuse_bitmask(AVRMEM * m) { return 0xFF; } + if (m->op[AVR_OP_WRITE] == NULL || + m->op[AVR_OP_READ] == NULL) + // no memory operations provided by configuration, compare 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)