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 avr_write_mem(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, int size, int auto_erase) {
|
||||||
int rc;
|
int rc;
|
||||||
int newpage, page_tainted, flush_page, do_write;
|
|
||||||
int wsize;
|
int wsize;
|
||||||
unsigned int i, lastaddr;
|
unsigned int i, lastaddr;
|
||||||
unsigned char data;
|
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 */
|
/* 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
|
||||||
pgm->write_setup(pgm, p, m);
|
if (pgm->write_setup)
|
||||||
}
|
pgm->write_setup(pgm, p, m);
|
||||||
|
|
||||||
newpage = 1;
|
int page_tainted = 0;
|
||||||
page_tainted = 0;
|
int flush_page = 0;
|
||||||
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++) {
|
for (i = 0; i < (unsigned int) wsize; i++) {
|
||||||
data = m->buf[i];
|
data = m->buf[i];
|
||||||
report_progress(i, wsize, NULL);
|
report_progress(i, wsize, NULL);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Find out whether the write action must be invoked for this
|
* Find out whether the write action must be invoked for this byte.
|
||||||
* byte.
|
|
||||||
*
|
*
|
||||||
* For non-paged memory, this only happens if TAG_ALLOCATED is
|
* For non-paged memory, this means the byte is set to TAG_ALLOCATED.
|
||||||
* set for the byte.
|
|
||||||
*
|
*
|
||||||
* For paged memory, TAG_ALLOCATED also invokes the write
|
* For paged memory, TAG_ALLOCATED also invokes loading the associated
|
||||||
* operation, which is actually a page buffer fill only. This
|
* full word, low-byte first, into the device page buffer as required by
|
||||||
* "taints" the page, and upon encountering the last byte of each
|
* ISP page programming. This "taints" the page, and upon encountering
|
||||||
* tainted page, the write operation must also be invoked in order
|
* the last byte of each tainted page, the write operation must also be
|
||||||
* to actually write the page buffer to memory.
|
* invoked in order to actually write the page buffer to device memory.
|
||||||
*/
|
*/
|
||||||
do_write = (m->tags[i] & TAG_ALLOCATED) != 0;
|
int do_write = (paged? m->tags[i&~1] | m->tags[i|1]: m->tags[i]) & TAG_ALLOCATED;
|
||||||
if (m->paged) {
|
if (paged) {
|
||||||
if (newpage) {
|
page_tainted |= do_write;
|
||||||
page_tainted = do_write;
|
if ((int) i % m->page_size == m->page_size - 1 || (int) i == wsize - 1) {
|
||||||
} 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 */
|
|
||||||
flush_page = page_tainted;
|
flush_page = page_tainted;
|
||||||
newpage = 1;
|
page_tainted = 0;
|
||||||
} else {
|
|
||||||
flush_page = newpage = 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!do_write && !flush_page) {
|
if (!do_write && !flush_page)
|
||||||
continue;
|
continue;
|
||||||
}
|
|
||||||
|
|
||||||
if (do_write) {
|
if (do_write) {
|
||||||
rc = avr_write_byte(pgm, p, m, i, data);
|
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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
if (flush_page) { // Time to flush the page with a page write
|
||||||
* check to see if it is time to flush the page with a page
|
flush_page = 0;
|
||||||
* write
|
|
||||||
*/
|
|
||||||
if (flush_page) {
|
|
||||||
rc = avr_write_page(pgm, p, m, i);
|
rc = avr_write_page(pgm, p, m, i);
|
||||||
if (rc) {
|
if (rc) {
|
||||||
msg_error(" *** page %d (addresses 0x%04x - 0x%04x) failed to write\n\n",
|
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) {
|
// Ensure error led stays on lest it was cleared in avr_write_byte()
|
||||||
/*
|
if (werror)
|
||||||
* make sure the error led stay on if there was a previous write
|
|
||||||
* error, otherwise it gets cleared in avr_write_byte()
|
|
||||||
*/
|
|
||||||
pgm->err_led(pgm, ON);
|
pgm->err_led(pgm, ON);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return i;
|
return i;
|
||||||
|
|
Loading…
Reference in New Issue