예제 #1
0
파일: ft245r.c 프로젝트: dreimers/avrdude
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;
}
예제 #2
0
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;
}
예제 #3
0
파일: buspirate.c 프로젝트: steve-m/avrdude
/* 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;
}
예제 #4
0
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;
}
예제 #5
0
파일: avr.c 프로젝트: Keeward/pilight
/*
 * 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;
}