Ensure full words are loaded, low-byte first, for ISP programming (#1265)
This commit is contained in:
parent
5328b798e4
commit
653d66b014
67
src/avr.c
67
src/avr.c
|
@ -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) {
|
||||
pgm->write_setup(pgm, p, m);
|
||||
}
|
||||
// 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 {
|
||||
page_tainted |= do_write;
|
||||
}
|
||||
if (i % m->page_size == (unsigned int) m->page_size - 1 ||
|
||||
i == (unsigned int) wsize - 1) {
|
||||
/* last byte this page */
|
||||
int do_write = (paged? m->tags[i&~1] | m->tags[i|1]: m->tags[i]) & TAG_ALLOCATED;
|
||||
if (paged) {
|
||||
page_tainted |= do_write;
|
||||
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,13 +1100,9 @@ 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;
|
||||
|
|
Loading…
Reference in New Issue