예제 #1
0
파일: ft245r.c 프로젝트: dreimers/avrdude
static inline int set_data(PROGRAMMER * pgm, unsigned char *buf, unsigned char data) {
    int j;
    int buf_pos = 0;
    unsigned char bit = 0x80;

    for (j=0; j<8; j++) {
        ft245r_out = SET_BITS_0(ft245r_out,pgm,PIN_AVR_MOSI,data & bit);

        ft245r_out = SET_BITS_0(ft245r_out,pgm,PIN_AVR_SCK,0);
        buf[buf_pos] = ft245r_out;
        buf_pos++;

        ft245r_out = SET_BITS_0(ft245r_out,pgm,PIN_AVR_SCK,1);
        buf[buf_pos] = ft245r_out;
        buf_pos++;

        bit >>= 1;
    }
    return buf_pos;
}
예제 #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;
}
예제 #3
0
파일: ft245r.c 프로젝트: dreimers/avrdude
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;
}
예제 #4
0
파일: ft245r.c 프로젝트: dreimers/avrdude
static int ft245r_paged_write_flash(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
                                    int page_size, int addr, int n_bytes) {
    unsigned int    i,j;
    int addr_save,buf_pos,do_page_write,req_count;
    unsigned char buf[FT245R_FRAGMENT_SIZE+1+128];

    req_count = 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(pgm, buf+buf_pos, (addr & 1)?0x48:0x40 );
            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, m->buf[addr]);
            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(pgm, buf+buf_pos, cmd[0]);
                buf_pos += set_data(pgm, buf+buf_pos, cmd[1]);
                buf_pos += set_data(pgm, buf+buf_pos, cmd[2]);
                buf_pos += set_data(pgm, buf+buf_pos, cmd[3]);
            }
            buf_pos += set_data(pgm, buf+buf_pos, 0x4C); /* Issue Page Write */
            buf_pos += set_data(pgm, buf+buf_pos,(addr_wk >> 9) & 0xff);
            buf_pos += set_data(pgm, buf+buf_pos,(addr_wk >> 1) & 0xff);
            buf_pos += set_data(pgm, buf+buf_pos, 0);
        }
#endif
        if (i >= n_bytes) {
            ft245r_out = SET_BITS_0(ft245r_out,pgm,PIN_AVR_SCK,0); // sck down
            buf[buf_pos++] = ft245r_out;
        }
        ft245r_send(pgm, buf, buf_pos);
        put_request(addr_save, buf_pos, 0);
        //ft245r_sync(pgm);
#if 0
        avrdude_message(MSG_INFO, "send addr 0x%04x bufsize %d [%02x %02x] page_write %d\n",
                addr_save,buf_pos,
                extract_data_out(pgm, buf , (0*4 + 3) ),
                extract_data_out(pgm, 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;
        }
    }
    while (do_request(pgm, m))
        ;
    return i;
}
예제 #5
0
파일: ft245r.c 프로젝트: dreimers/avrdude
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;
}