static int ft245r_paged_write_gen(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m, unsigned int page_size, unsigned int addr, unsigned int n_bytes) { unsigned long i, pa; int rc; for (i=0; i<n_bytes; i++, addr++) { rc = avr_write_byte_default(pgm, p, m, addr, m->buf[addr]); if (rc != 0) { return -2; } if (m->paged) { // Can this piece of code ever be activated?? Do AVRs exist that // have paged non-flash memories? -- REW // XXX Untested code below. /* * check to see if it is time to flush the page with a page * write */ if (((addr % m->page_size) == m->page_size-1) || (i == n_bytes-1)) { pa = addr - (addr % m->page_size); rc = avr_write_page(pgm, p, m, pa); if (rc != 0) { return -2; } } } } return i; }
static int ft245r_paged_write_gen(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m, int page_size, int n_bytes) { unsigned long i; int rc; for (i=0; i<n_bytes; i++) { report_progress(i, n_bytes, NULL); rc = avr_write_byte_default(pgm, p, m, i, m->buf[i]); if (rc != 0) { return -2; } if (m->paged) { /* * check to see if it is time to flush the page with a page * write */ if (((i % m->page_size) == m->page_size-1) || (i == n_bytes-1)) { rc = avr_write_page(pgm, p, m, i); if (rc != 0) { return -2; } } } } return i; }
/* Paged write function which utilizes the Bus Pirate's "Write then Read" binary SPI instruction */ static int buspirate_paged_write(struct programmer_t *pgm, AVRPART *p, AVRMEM *m, unsigned int page_size, unsigned int base_addr, unsigned int n_data_bytes) { int page, i; int addr = base_addr; int n_page_writes; int this_page_size; char cmd_buf[4096] = {'\0'}; char send_byte, recv_byte; if (!(pgm->flag & BP_FLAG_IN_BINMODE)) { /* Return if we are not in binary mode. */ return -1; } if (pgm->flag & BP_FLAG_NOPAGEDWRITE) { /* Return if we've nominated not to use paged writes. */ return -1; } if (page_size>1024) { /* Page sizes greater than 1kB not yet supported. */ return -1; } if (strcmp(m->desc,"flash") != 0) { /* Only flash memory currently supported. */ return -1; } /* pre-check opcodes */ if (m->op[AVR_OP_LOADPAGE_LO] == NULL) { fprintf(stderr, "%s failure: %s command not defined for %s\n", progname, "AVR_OP_LOADPAGE_LO", p->desc); return -1; } if (m->op[AVR_OP_LOADPAGE_HI] == NULL) { fprintf(stderr, "%s failure: %s command not defined for %s\n", progname, "AVR_OP_LOADPAGE_HI", p->desc); return -1; } /* Calculate total number of page writes needed: */ n_page_writes = n_data_bytes/page_size; if (n_data_bytes%page_size >0) n_page_writes++; /* Ensure error LED is off: */ pgm->err_led(pgm, OFF); /* Loop over pages: */ for (page=0; page<n_page_writes; page++) { /* Determine bytes to write in this page: */ this_page_size = page_size; if (page == n_page_writes-1) this_page_size = n_data_bytes - page_size*page; /* Set up command buffer: */ memset(cmd_buf, 0, 4*this_page_size); for (i=0; i<this_page_size; i++) { addr = base_addr + page*page_size + i; if (i%2 == 0) { avr_set_bits(m->op[AVR_OP_LOADPAGE_LO], &(cmd_buf[4*i])); avr_set_addr(m->op[AVR_OP_LOADPAGE_LO], &(cmd_buf[4*i]), addr/2); avr_set_input(m->op[AVR_OP_LOADPAGE_LO], &(cmd_buf[4*i]), m->buf[addr]); } else { avr_set_bits(m->op[AVR_OP_LOADPAGE_HI], &(cmd_buf[4*i])); avr_set_addr(m->op[AVR_OP_LOADPAGE_HI], &(cmd_buf[4*i]), addr/2); avr_set_input(m->op[AVR_OP_LOADPAGE_HI], &(cmd_buf[4*i]), m->buf[addr]); } } /* 00000100 - Write then read */ send_byte = 0x05; buspirate_send_bin(pgm, &send_byte, 1); /* Number of bytes to write: */ send_byte = (4*this_page_size)/0x100; buspirate_send_bin(pgm, &send_byte, 1); /* High byte */ send_byte = (4*this_page_size)%0x100; buspirate_send_bin(pgm, &send_byte, 1); /* Low byte */ /* Number of bytes to read: */ send_byte = 0x0; buspirate_send_bin(pgm, &send_byte, 1); /* High byte */ buspirate_send_bin(pgm, &send_byte, 1); /* Low byte */ /* Set programming LED: */ pgm->pgm_led(pgm, ON); /* Send command buffer: */ buspirate_send_bin(pgm, cmd_buf, 4*this_page_size); /* Check for write failure: */ if ((buspirate_recv_bin(pgm, &recv_byte, 1) == EOF) || (recv_byte != 0x01)) { fprintf(stderr, "BusPirate: Fatal error: Write Then Read did not succeed.\n"); pgm->pgm_led(pgm, OFF); pgm->err_led(pgm, ON); exit(1); } /* Unset programming LED: */ pgm->pgm_led(pgm, OFF); /* Write loaded page to flash: */ avr_write_page(pgm, p, m, addr); } return n_data_bytes; }
static int ft245r_paged_write_flash(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m, int page_size, int n_bytes) { unsigned int i,j; int addr,addr_save,buf_pos,do_page_write,req_count; char buf[FT245R_FRAGMENT_SIZE+1+128]; req_count = 0; addr = 0; for (i=0; i<n_bytes; ) { addr_save = addr; buf_pos = 0; do_page_write = 0; for (j=0; j< FT245R_FRAGMENT_SIZE/8/FT245R_CYCLES/4; j++) { buf_pos += set_data(buf+buf_pos, (addr & 1)?0x48:0x40 ); buf_pos += set_data(buf+buf_pos, (addr >> 9) & 0xff ); buf_pos += set_data(buf+buf_pos, (addr >> 1) & 0xff ); buf_pos += set_data(buf+buf_pos, m->buf[i]); addr ++; i++; if ( (m->paged) && (((i % m->page_size) == 0) || (i == n_bytes))) { do_page_write = 1; break; } } #if defined(USE_INLINE_WRITE_PAGE) if (do_page_write) { int addr_wk = addr_save - (addr_save % m->page_size); /* If this device has a "load extended address" command, issue it. */ if (m->op[AVR_OP_LOAD_EXT_ADDR]) { unsigned char cmd[4]; OPCODE *lext = m->op[AVR_OP_LOAD_EXT_ADDR]; memset(cmd, 0, 4); avr_set_bits(lext, cmd); avr_set_addr(lext, cmd, addr_wk/2); buf_pos += set_data(buf+buf_pos, cmd[0]); buf_pos += set_data(buf+buf_pos, cmd[1]); buf_pos += set_data(buf+buf_pos, cmd[2]); buf_pos += set_data(buf+buf_pos, cmd[3]); } buf_pos += set_data(buf+buf_pos, 0x4C); /* Issue Page Write */ buf_pos += set_data(buf+buf_pos,(addr_wk >> 9) & 0xff); buf_pos += set_data(buf+buf_pos,(addr_wk >> 1) & 0xff); buf_pos += set_data(buf+buf_pos, 0); } #endif if (i >= n_bytes) { buf[buf_pos++] = 0; // sck down } ft245r_send(pgm, buf, buf_pos); put_request(addr_save, buf_pos, 0); //ft245r_sync(pgm); #if 0 fprintf(stderr, "send addr 0x%04x bufsize %d [%02x %02x] page_write %d\n", addr_save,buf_pos, extract_data_out(buf , (0*4 + 3) ), extract_data_out(buf , (1*4 + 3) ), do_page_write); #endif req_count++; if (req_count > REQ_OUTSTANDINGS) do_request(pgm, m); if (do_page_write) { #if defined(USE_INLINE_WRITE_PAGE) while (do_request(pgm, m)) ; usleep(m->max_write_delay); #else int addr_wk = addr_save - (addr_save % m->page_size); int rc; while (do_request(pgm, m)) ; rc = avr_write_page(pgm, p, m, addr_wk); if (rc != 0) { return -2; } #endif req_count = 0; } report_progress(i, n_bytes, NULL); } while (do_request(pgm, m)) ; return i; }
/* * Write the whole memory region of the specified memory from the * corresponding buffer of the avrpart pointed to by 'p'. Write up to * 'size' bytes from the buffer. Data is only written if the new data * value is different from the existing data value. Data beyond * 'size' bytes is not affected. * * Return the number of bytes written, or -1 if an error occurs. */ int avr_write(PROGRAMMER * pgm, AVRPART * p, char * memtype, int size) { int rc; int wsize; long i; unsigned char data; int werror; AVRMEM * m = NULL; /* NEW */ if(strcmp(memtype, "flash") == 0) { m = p->flashmem; } else if(strcmp(memtype, "lfuse") == 0) { m = p->lfusemem; } else if(strcmp(memtype, "hfuse") == 0) { m = p->hfusemem; } if (m == NULL) { logprintf(LOG_ERR, "No \"%s\" memory for part %s", memtype, p->desc); return -1; } werror = 0; wsize = m->size; if (size < wsize) { wsize = size; } else if (size > wsize) { logprintf(LOG_ERR, "%d bytes requested, but memory region is only %d bytes", size, wsize); logprintf(LOG_ERR, "Only %d bytes will actually be written", wsize); } if (pgm->paged_write != NULL && m->page_size != 0) { /* * the programmer supports a paged mode write, perhaps more * efficiently than we can read it directly, so use its routine * instead */ if ((i = pgm->paged_write(pgm, p, m, m->page_size, size)) >= 0) return i; } if (pgm->write_setup) { pgm->write_setup(pgm, p, m); } for (i=0; i<wsize; i++) { data = m->buf[i]; report_progress(i, wsize, NULL); rc = avr_write_byte(pgm, p, m, i, data); if (rc) { logprintf(LOG_ERR, "***failed"); werror = 1; } if (m->paged) { /* * check to see if it is time to flush the page with a page * write */ if (((i % m->page_size) == m->page_size-1) || (i == wsize-1)) { rc = avr_write_page(pgm, p, m, i); if (rc) { logprintf(LOG_ERR, " *** page %ld (addresses 0x%04lx - 0x%04lx) failed to write", i % m->page_size, i - m->page_size + 1, i); werror = 1; } } } } return i; }