Ensure full words are loaded, low-byte first, for ISP programming (#1265)

This commit is contained in:
Stefan Rueger 2023-01-05 16:43:35 +00:00 committed by GitHub
parent 5328b798e4
commit 653d66b014
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 25 additions and 42 deletions

View File

@ -843,7 +843,6 @@ int avr_write(const PROGRAMMER *pgm, const AVRPART *p, const char *memtype, int
*/
int avr_write_mem(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, int size, int auto_erase) {
int rc;
int newpage, page_tainted, flush_page, do_write;
int wsize;
unsigned int i, lastaddr;
unsigned char data;
@ -1044,51 +1043,42 @@ int avr_write_mem(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, int
/* else: fall back to byte-at-a-time write, for historical reasons */
}
if (pgm->write_setup) {
// ISP programming from now on; flash will look like NOR-memory
if (pgm->write_setup)
pgm->write_setup(pgm, p, m);
}
newpage = 1;
page_tainted = 0;
flush_page = 0;
int page_tainted = 0;
int flush_page = 0;
int paged = avr_mem_is_flash_type(m) && m->paged;
if(paged)
wsize = (wsize+1)/2*2; // Round up write size for word boundary
for (i = 0; i < (unsigned int) wsize; i++) {
data = m->buf[i];
report_progress(i, wsize, NULL);
/*
* Find out whether the write action must be invoked for this
* byte.
* Find out whether the write action must be invoked for this byte.
*
* For non-paged memory, this only happens if TAG_ALLOCATED is
* set for the byte.
* For non-paged memory, this means the byte is set to TAG_ALLOCATED.
*
* For paged memory, TAG_ALLOCATED also invokes the write
* operation, which is actually a page buffer fill only. This
* "taints" the page, and upon encountering the last byte of each
* tainted page, the write operation must also be invoked in order
* to actually write the page buffer to memory.
* For paged memory, TAG_ALLOCATED also invokes loading the associated
* full word, low-byte first, into the device page buffer as required by
* ISP page programming. This "taints" the page, and upon encountering
* the last byte of each tainted page, the write operation must also be
* invoked in order to actually write the page buffer to device memory.
*/
do_write = (m->tags[i] & TAG_ALLOCATED) != 0;
if (m->paged) {
if (newpage) {
page_tainted = do_write;
} else {
int do_write = (paged? m->tags[i&~1] | m->tags[i|1]: m->tags[i]) & TAG_ALLOCATED;
if (paged) {
page_tainted |= do_write;
}
if (i % m->page_size == (unsigned int) m->page_size - 1 ||
i == (unsigned int) wsize - 1) {
/* last byte this page */
if ((int) i % m->page_size == m->page_size - 1 || (int) i == wsize - 1) {
flush_page = page_tainted;
newpage = 1;
} else {
flush_page = newpage = 0;
page_tainted = 0;
}
}
if (!do_write && !flush_page) {
if (!do_write && !flush_page)
continue;
}
if (do_write) {
rc = avr_write_byte(pgm, p, m, i, data);
@ -1099,11 +1089,8 @@ int avr_write_mem(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, int
}
}
/*
* check to see if it is time to flush the page with a page
* write
*/
if (flush_page) {
if (flush_page) { // Time to flush the page with a page write
flush_page = 0;
rc = avr_write_page(pgm, p, m, i);
if (rc) {
msg_error(" *** page %d (addresses 0x%04x - 0x%04x) failed to write\n\n",
@ -1113,14 +1100,10 @@ int avr_write_mem(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, int
}
}
if (werror) {
/*
* make sure the error led stay on if there was a previous write
* error, otherwise it gets cleared in avr_write_byte()
*/
// Ensure error led stays on lest it was cleared in avr_write_byte()
if (werror)
pgm->err_led(pgm, ON);
}
}
return i;
}