Example #1
0
static int set_reset(PROGRAMMER * pgm, int val)
{
  unsigned char buf[1];

  buf[0] = 0;
  if (val) buf[0] |= ft245r_reset;

  ft245r_send (pgm, buf, 1);
  ft245r_recv (pgm, buf, 1);
  return 0;
}
Example #2
0
static int set_pin(PROGRAMMER * pgm, int pinname, int val) {
    unsigned char buf[1];

    if (pgm->pin[pinname].mask[0] == 0) {
        // ignore not defined pins (might be the led or vcc or buff if not needed)
        return 0;
    }

    ft245r_out = SET_BITS_0(ft245r_out,pgm,pinname,val);
    buf[0] = ft245r_out;

    ft245r_send (pgm, buf, 1);
    ft245r_recv (pgm, buf, 1);
    return 0;
}
Example #3
0
/*
 * transmit an AVR device command and return the results; 'cmd' and
 * 'res' must point to at least a 4 byte data buffer
 */
static int ft245r_cmd(PROGRAMMER * pgm, const unsigned char *cmd,
                      unsigned char *res) {
    int i,buf_pos;
    unsigned char buf[128];

    buf_pos = 0;
    for (i=0; i<4; i++) {
        buf_pos += set_data(pgm, buf+buf_pos, cmd[i]);
    }
    buf[buf_pos] = 0;
    buf_pos++;

    ft245r_send (pgm, buf, buf_pos);
    ft245r_recv (pgm, buf, buf_pos);
    res[0] = extract_data(pgm, buf, 0);
    res[1] = extract_data(pgm, buf, 1);
    res[2] = extract_data(pgm, buf, 2);
    res[3] = extract_data(pgm, buf, 3);

    return 0;
}
Example #4
0
static int ft245r_paged_load_flash(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m, 
                             int page_size, int n_bytes)
{
  unsigned long    i,j,n;
  //int rc;
  int addr,addr_save,buf_pos;
  int req_count = 0;
  char buf[FT245R_FRAGMENT_SIZE+1];

  addr = 0;
  for (i=0; i<n_bytes; ) {
     buf_pos = 0;
     addr_save = addr;
     for (j=0; j< FT245R_FRAGMENT_SIZE/8/FT245R_CYCLES/4; j++) {
	if (i >= n_bytes) break;
        buf_pos += set_data(buf+buf_pos, (addr & 1)?0x28:0x20 ); 
        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, 0);
	addr ++;
	i++;
     }
     if (i >= n_bytes) {
        buf[buf_pos++] = 0; // sck down
     }
     n = j;
     ft245r_send(pgm, buf, buf_pos);
     put_request(addr_save, buf_pos, n);
     req_count++;
     if (req_count > REQ_OUTSTANDINGS)
        do_request(pgm, m);
     report_progress(i, n_bytes, NULL);
  }
  while (do_request(pgm, m))
	  ;
  return 0;
}
Example #5
0
static int ft245r_paged_load_flash(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
                                   unsigned int page_size, unsigned int addr,
                                   unsigned int n_bytes) {
    unsigned long    i,j,n;
    int addr_save,buf_pos;
    int req_count = 0;
    unsigned char buf[FT245R_FRAGMENT_SIZE+1];

    for (i=0; i<n_bytes; ) {
        buf_pos = 0;
        addr_save = addr;
        for (j=0; j< FT245R_FRAGMENT_SIZE/8/FT245R_CYCLES/4; j++) {
            if (i >= n_bytes) break;
            buf_pos += set_data(pgm, buf+buf_pos, (addr & 1)?0x28:0x20 );
            buf_pos += set_data(pgm, buf+buf_pos, (addr >> 9) & 0xff );
            buf_pos += set_data(pgm, buf+buf_pos, (addr >> 1) & 0xff );
            buf_pos += set_data(pgm, buf+buf_pos, 0);
            addr ++;
            i++;
        }
        if (i >= n_bytes) {
            ft245r_out = SET_BITS_0(ft245r_out,pgm,PIN_AVR_SCK,0); // sck down
            buf[buf_pos++] = ft245r_out;
        }
        n = j;
        ft245r_send(pgm, buf, buf_pos);
        put_request(addr_save, buf_pos, n);
        req_count++;
        if (req_count > REQ_OUTSTANDINGS)
            do_request(pgm, m);

    }
    while (do_request(pgm, m))
        ;
    return 0;
}
Example #6
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;
}
Example #7
0
static int ft245r_open(PROGRAMMER * pgm, char * port) {
    int rv;
    int devnum = -1;

    rv = pins_check(pgm,pin_checklist,sizeof(pin_checklist)/sizeof(pin_checklist[0]), true);
    if(rv) {
        pgm->display(pgm, progbuf);
        return rv;
    }

    strcpy(pgm->port, port);

    if (strcmp(port,DEFAULT_USB) != 0) {
        if (strncasecmp("ft", port, 2) == 0) {
            char *startptr = port + 2;
            char *endptr = NULL;
            devnum = strtol(startptr,&endptr,10);
            if ((startptr==endptr) || (*endptr != '\0')) {
                devnum = -1;
            }
        }
        if (devnum < 0) {
            avrdude_message(MSG_INFO, "%s: invalid portname '%s': use 'ft[0-9]+'\n",
                            progname,port);
            return -1;
        }
    } else {
        devnum = 0;
    }

    handle = malloc (sizeof (struct ftdi_context));
    ftdi_init(handle);
    LNODEID usbpid = lfirst(pgm->usbpid);
    int pid;
    if (usbpid) {
      pid = *(int *)(ldata(usbpid));
      if (lnext(usbpid))
	avrdude_message(MSG_INFO, "%s: Warning: using PID 0x%04x, ignoring remaining PIDs in list\n",
		progname, pid);
    } else {
      pid = USB_DEVICE_FT245;
    }
    rv = ftdi_usb_open_desc_index(handle,
                                  pgm->usbvid?pgm->usbvid:USB_VENDOR_FTDI,
                                  pid,
                                  pgm->usbproduct[0]?pgm->usbproduct:NULL,
                                  pgm->usbsn[0]?pgm->usbsn:NULL,
                                  devnum);
    if (rv) {
        avrdude_message(MSG_INFO, "can't open ftdi device %d. (%s)\n", devnum, ftdi_get_error_string(handle));
        goto cleanup_no_usb;
    }

    ft245r_ddr = 
         pgm->pin[PIN_AVR_SCK].mask[0]
       | pgm->pin[PIN_AVR_MOSI].mask[0]
       | pgm->pin[PIN_AVR_RESET].mask[0]
       | pgm->pin[PPI_AVR_BUFF].mask[0]
       | pgm->pin[PPI_AVR_VCC].mask[0]
       | pgm->pin[PIN_LED_ERR].mask[0]
       | pgm->pin[PIN_LED_RDY].mask[0]
       | pgm->pin[PIN_LED_PGM].mask[0]
       | pgm->pin[PIN_LED_VFY].mask[0];

    /* set initial values for outputs, no reset everything else is off */
    ft245r_out = 0;
    ft245r_out = SET_BITS_0(ft245r_out,pgm,PIN_AVR_RESET,1);
    ft245r_out = SET_BITS_0(ft245r_out,pgm,PIN_AVR_SCK,0);
    ft245r_out = SET_BITS_0(ft245r_out,pgm,PIN_AVR_MOSI,0);
    ft245r_out = SET_BITS_0(ft245r_out,pgm,PPI_AVR_BUFF,0);
    ft245r_out = SET_BITS_0(ft245r_out,pgm,PPI_AVR_VCC,0);
    ft245r_out = SET_BITS_0(ft245r_out,pgm,PIN_LED_ERR,0);
    ft245r_out = SET_BITS_0(ft245r_out,pgm,PIN_LED_RDY,0);
    ft245r_out = SET_BITS_0(ft245r_out,pgm,PIN_LED_PGM,0);
    ft245r_out = SET_BITS_0(ft245r_out,pgm,PIN_LED_VFY,0);


    rv = ftdi_set_bitmode(handle, ft245r_ddr, BITMODE_SYNCBB); // set Synchronous BitBang
    if (rv) {
        avrdude_message(MSG_INFO, "%s: Synchronous BitBangMode is not supported (%s)\n",
                        progname, ftdi_get_error_string(handle));
        goto cleanup;
    }

    rv = ft245r_set_bitclock(pgm);
    if (rv) {
        goto cleanup;
    }

    /* We start a new thread to read the output from the FTDI. This is
     * necessary because otherwise we'll deadlock. We cannot finish
     * writing because the ftdi cannot send the results because we
     * haven't provided a read buffer yet. */

    sem_init (&buf_data, 0, 0);
    sem_init (&buf_space, 0, BUFSIZE);
    pthread_create (&readerthread, NULL, reader, handle);

    /*
     * drain any extraneous input
     */
    ft245r_drain (pgm, 0);

    ft245r_send (pgm, &ft245r_out, 1);
    ft245r_recv (pgm, &ft245r_in, 1);

    return 0;

cleanup:
    ftdi_usb_close(handle);
cleanup_no_usb:
    ftdi_deinit (handle);
    free(handle);
    handle = NULL;
    return -1;
}