updated on Thu Jan 26 16:09:46 UTC 2012
[aur-mirror.git] / avrdude-serjtag / patch-ft245r.c.diff
blob56ac9d317b4a34e183a6c8be0d2e8d0bc53587b3
1 --- /dev/null 2009-08-02 22:44:47.000000000 +0200
2 +++ ft245r.c 2009-08-02 21:56:45.000000000 +0200
3 @@ -0,0 +1,762 @@
4 +/*
5 + * avrdude - A Downloader/Uploader for AVR device programmers
6 + * Copyright (C) 2003-2004 Theodore A. Roth <troth@openavr.org>
7 + *
8 + * This program is free software; you can redistribute it and/or modify
9 + * it under the terms of the GNU General Public License as published by
10 + * the Free Software Foundation; either version 2 of the License, or
11 + * (at your option) any later version.
12 + *
13 + * This program is distributed in the hope that it will be useful,
14 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 + * GNU General Public License for more details.
17 + *
18 + * You should have received a copy of the GNU General Public License
19 + * along with this program; if not, write to the Free Software
20 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 + */
23 +/* $Id$ */
25 +/* ft245r -- FT245R/FT232R Synchronous BitBangMode Programmer
26 + default pin assign
27 + FT232R / FT245R
28 + miso = 1; # RxD / D1
29 + sck = 0; # RTS / D0
30 + mosi = 2; # TxD / D2
31 + reset = 4; # DTR / D4
32 +*/
34 +#include "ac_cfg.h"
36 +#include <stdio.h>
37 +#include <stdlib.h>
38 +#include <string.h>
39 +#include <errno.h>
40 +#include <sys/time.h>
41 +#include <unistd.h>
43 +#include "avr.h"
44 +#include "pindefs.h"
45 +#include "pgm.h"
46 +#include "bitbang.h"
47 +#include "ft245r.h"
49 +#if defined(_WIN32) || defined(SUPPORT_FT245R)
50 +#if defined(_WIN32)
51 +#include <windows.h>
52 +#include "ftd2xx.h"
53 +#else
54 +#include "ftd2xx.h"
55 +#endif
57 +#define FT245R_CYCLES 2
58 +#define FT245R_FRAGMENT_SIZE 512
59 +#define REQ_OUTSTANDINGS 10
60 +//#define USE_INLINE_WRITE_PAGE
62 +#define FT245R_DEBUG 1
64 +extern char * progname;
65 +extern int do_cycles;
66 +extern int ovsigck;
67 +extern int verbose;
69 +static FT_HANDLE handle;
71 +static unsigned char ft245r_ddr;
72 +static unsigned char ft245r_sck;
73 +static unsigned char ft245r_mosi;
74 +static unsigned char ft245r_reset;
75 +static unsigned char ft245r_miso;
77 +static inline void setbit(UCHAR *data, int pinno, int v)
79 + if (v) {
80 + *data |= (1 << (pinno));
81 + } else {
82 + *data &= ~(1 <<(pinno));
83 + }
86 +static int ft245r_send(PROGRAMMER * pgm, char * buf, size_t len)
88 + FT_STATUS r;
89 + DWORD rlen;
90 + r = FT_Write(handle, buf, len, &rlen);
91 + if (r == FT_OK) return 0;
92 + if (len != rlen) return -1;
93 + return -1;
97 +static int ft245r_recv(PROGRAMMER * pgm, char * buf, size_t len)
99 + FT_STATUS r;
100 + DWORD rlen;
102 + r = FT_Read(handle, buf, len, &rlen);
104 + if (r != FT_OK || len != rlen) {
105 + fprintf(stderr,
106 + "%s: ft245r_recv(): programmer is not responding\n",
107 + progname);
108 + exit(1);
110 + return 0;
114 +static int ft245r_drain(PROGRAMMER * pgm, int display)
116 + FT_STATUS r;
117 + DWORD n;
118 + r = FT_SetBitMode(handle, 0, 0x0); // reset
119 + if (r != FT_OK) return -1;
120 + r = FT_SetBitMode(handle, ft245r_ddr, 0x4); // set Synchronuse BitBang
121 + if (r != FT_OK) return -1;
123 + r = FT_GetQueueStatus(handle, &n);
124 + if (r != FT_OK) return -1;
125 + if (n) {
126 + fprintf(stderr, "ft245r_drain called but queue is not empty %d \n",
127 + (int)n);
129 + return 0;
132 +static inline int ft245r_sync(PROGRAMMER * pgm)
134 + FT_STATUS r;
135 + UCHAR ch;
136 + r = FT_GetBitMode(handle, &ch);
137 + if (r != FT_OK) return -1;
138 + return 0;
141 +static int ft245r_chip_erase(PROGRAMMER * pgm, AVRPART * p)
143 + unsigned char cmd[4];
144 + unsigned char res[4];
146 + if (p->op[AVR_OP_CHIP_ERASE] == NULL) {
147 + fprintf(stderr, "chip erase instruction not defined for part \"%s\"\n",
148 + p->desc);
149 + return -1;
152 + memset(cmd, 0, sizeof(cmd));
154 + avr_set_bits(p->op[AVR_OP_CHIP_ERASE], cmd);
155 + pgm->cmd(pgm, cmd, res);
156 + usleep(p->chip_erase_delay);
157 + pgm->initialize(pgm, p);
159 + return 0;
162 +static unsigned char saved_signature[3];
164 +static int valid_rates[] = {
165 + 2400, 4800, 9600, 14400, 19200, 38400, 57600,
166 + 115200, 230400, 460800, 921600, 3000000
169 +static void ft245r_set_bitclock(PROGRAMMER * pgm) {
170 + FT_STATUS r;
171 + int rate = 0;
172 + int i;
174 + if (pgm->bitclock == 0.0) { // using default
175 + rate = 235000.0 /2;
176 + } else if (pgm->bitclock >= 0.50 ) {
177 + rate = 500000.0 /2;
178 + } else if (pgm->bitclock < 0.01) {
179 + rate = 1000.0 /2;
180 + } else {
181 + rate = pgm->bitclock * 1000000.0 /2;
183 + for (i= sizeof(valid_rates)/sizeof(valid_rates[0]) -1; i>=0; --i)
185 + if (valid_rates[i] <= rate) {
186 + rate = valid_rates[i];
187 + break;
190 + if (i<0) rate = valid_rates[0];
192 + r = FT_SetBaudRate(handle, rate);
193 + if ((verbose>=1) || FT245R_DEBUG) {
194 + fprintf(stderr," ft245r: bitclk %d -> ft baud %d\n",
195 + rate * 2, rate);
199 +static int set_reset(PROGRAMMER * pgm, int val)
201 + unsigned char buf[1];
203 + buf[0] = 0;
204 + if (val) buf[0] |= ft245r_reset;
206 + ft245r_send (pgm, buf, 1);
207 + ft245r_recv (pgm, buf, 1);
208 + return 0;
211 +static int ft245r_cmd(PROGRAMMER * pgm, unsigned char cmd[4],
212 + unsigned char res[4]);
214 + * issue the 'program enable' command to the AVR device
215 + */
216 +static int ft245r_program_enable(PROGRAMMER * pgm, AVRPART * p)
218 + int retry_count = 0;
219 + unsigned char cmd[4];
220 + unsigned char res[4];
221 + int i,reset_ok;
223 + ft245r_set_bitclock(pgm);
225 +retry:
226 + reset_ok = 0;
227 + set_reset(pgm, 0);
228 + usleep(5000); // 5ms
229 + set_reset(pgm, 1);
230 + usleep(5000); // 5ms
231 + set_reset(pgm, 0);
232 + usleep(5000); // 5ms
234 + cmd[0] = 0xAC;
235 + cmd[1] = 0x53;
236 + cmd[2] = 0;
237 + cmd[3] = 0;
238 + ft245r_cmd(pgm, cmd, res);
239 + if (res[2] == 0x53 ) reset_ok = 1;
240 + for (i=0; i<3; i++) {
241 + cmd[0] = 0x30;
242 + cmd[1] = 0;
243 + cmd[2] = i;
244 + cmd[3] = 0;
245 + ft245r_cmd(pgm, cmd, res);
246 + saved_signature[i] = res[3];
249 + if (reset_ok && (saved_signature[0] == 0x1e)) // success
250 + return 0;
252 + if (retry_count < 5) {
253 + retry_count++;
254 + goto retry;
256 + if ((verbose>=1) || FT245R_DEBUG) {
257 + fprintf(stderr,
258 + "%s: ft245r_program_enable: failed\n", progname);
259 + fflush(stderr);
261 + return -1;
264 +static int ft245r_read_sig_bytes(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m)
266 + m->buf[0] = saved_signature[0];
267 + m->buf[1] = saved_signature[1];
268 + m->buf[2] = saved_signature[2];
269 + return 3;
273 + * initialize the AVR device and prepare it to accept commands
274 + */
275 +static int ft245r_initialize(PROGRAMMER * pgm, AVRPART * p)
277 + return ft245r_program_enable(pgm, p);
280 +static void ft245r_disable(PROGRAMMER * pgm)
282 + return;
286 +static void ft245r_enable(PROGRAMMER * pgm)
288 + /* Do nothing. */
290 + return;
293 +static inline int set_data(unsigned char *buf, unsigned char data)
295 + int j;
296 + int buf_pos = 0;
297 + unsigned char bit = 0x80;
299 + for (j=0; j<8; j++) {
300 + buf[buf_pos] = 0;
301 + if (data & bit) buf[buf_pos] |= ft245r_mosi;
302 + buf_pos++;
304 + buf[buf_pos] = 0;
305 + if (data & bit) buf[buf_pos] |= ft245r_mosi;
306 + buf[buf_pos] |= ft245r_sck;
307 + buf_pos++;
309 + bit >>= 1;
311 + return buf_pos;
314 +static inline unsigned char extract_data(unsigned char *buf, int offset)
316 + int j;
317 + int buf_pos = 1;
318 + unsigned char bit = 0x80;
319 + unsigned char r = 0;
321 + buf += offset * (8 * FT245R_CYCLES);
322 + for (j=0; j<8; j++) {
323 + if (buf[buf_pos] & ft245r_miso) {
324 + r |= bit;
326 + buf_pos += FT245R_CYCLES;
327 + bit >>= 1;
329 + return r;
332 +/* to check data */
333 +static inline unsigned char extract_data_out(unsigned char *buf, int offset)
335 + int j;
336 + int buf_pos = 1;
337 + unsigned char bit = 0x80;
338 + unsigned char r = 0;
340 + buf += offset * (8 * FT245R_CYCLES);
341 + for (j=0; j<8; j++) {
342 + if (buf[buf_pos] & ft245r_mosi) {
343 + r |= bit;
345 + buf_pos += FT245R_CYCLES;
346 + bit >>= 1;
348 + return r;
353 + * transmit an AVR device command and return the results; 'cmd' and
354 + * 'res' must point to at least a 4 byte data buffer
355 + */
356 +static int ft245r_cmd(PROGRAMMER * pgm, unsigned char cmd[4],
357 + unsigned char res[4])
359 + int i,buf_pos;
360 + unsigned char buf[128];
362 + buf_pos = 0;
363 + for (i=0; i<4; i++) {
364 + buf_pos += set_data(buf+buf_pos, cmd[i]);
366 + buf[buf_pos] = 0;
367 + buf_pos++;
369 + ft245r_send (pgm, buf, buf_pos);
370 + ft245r_recv (pgm, buf, buf_pos);
371 + res[0] = extract_data(buf, 0);
372 + res[1] = extract_data(buf, 1);
373 + res[2] = extract_data(buf, 2);
374 + res[3] = extract_data(buf, 3);
376 + return 0;
379 +static int ft245r_open(PROGRAMMER * pgm, char * port)
381 + FT_STATUS r;
382 + int devnum = -1;
383 + strcpy(pgm->port, port);
385 +#ifdef _WIN32
386 + if (!strncasecmp("ft", port, 2) && '0' <= port[2] && port[2] <= '9') {
387 + devnum = port[2] - '0';
388 + } else {
389 + fprintf(stderr,
390 + "%s: invalid portname %s: use ft0 - ft9\n",
391 + progname,port);
392 + exit(1);
394 + r = FT_Open(devnum, &handle);
395 +#else
396 + for (devnum=0; devnum<9; devnum++) {
397 + r = FT_Open(devnum, &handle);
398 + if (r == FT_OK) break;
400 +#endif
401 + if (r != FT_OK) {
402 + fprintf(stderr,
403 + "%s: %s open failed \n",
404 + progname, port);
405 + exit(1);
407 + r = FT_SetBitMode(handle, 0, 0x4); // set Synchronuse BitBang
408 + if (r != FT_OK) {
409 + fprintf(stderr,
410 + "%s: Synchronuse BitBangMode is not supported\n",
411 + progname);
412 + exit(1);
414 +#if FT245R_DEBUG
415 + fprintf(stderr, "%s: BitBang OK \n", progname);
416 + fflush(stderr);
417 +#endif
419 + ft245r_ddr = 0;
420 + setbit(&ft245r_ddr, pgm->pinno[PIN_AVR_SCK], 1);
421 + setbit(&ft245r_ddr, pgm->pinno[PIN_AVR_MOSI], 1);
422 + setbit(&ft245r_ddr, pgm->pinno[PIN_AVR_RESET], 1);
423 + ft245r_sck = 0;
424 + setbit(&ft245r_sck, pgm->pinno[PIN_AVR_SCK], 1);
425 + ft245r_mosi = 0;
426 + setbit(&ft245r_mosi, pgm->pinno[PIN_AVR_MOSI], 1);
427 + ft245r_reset = 0;
428 + setbit(&ft245r_reset, pgm->pinno[PIN_AVR_RESET], 1);
429 + ft245r_miso = 0;
430 + setbit(&ft245r_miso, pgm->pinno[PIN_AVR_MISO], 1);
431 + if ((verbose>=1) || FT245R_DEBUG) {
432 + fprintf(stderr,
433 + "%s: pin assign miso %d sck %d mosi %d reset %d\n",
434 + progname,
435 + pgm->pinno[PIN_AVR_MISO],
436 + pgm->pinno[PIN_AVR_SCK],
437 + pgm->pinno[PIN_AVR_MOSI],
438 + pgm->pinno[PIN_AVR_RESET]);
441 + /*
442 + * drain any extraneous input
443 + */
444 + ft245r_drain (pgm, 0);
445 +#if FT245R_DEBUG
446 + fprintf(stderr, "%s: drain OK \n", progname);
447 + fflush(stderr);
448 +#endif
450 + return 0;
453 +static void ft245r_close(PROGRAMMER * pgm)
455 + FT_Close(handle);
458 +static void ft245r_display(PROGRAMMER * pgm, char * p)
460 + return;
463 +static int ft245r_paged_write_gen(PROGRAMMER * pgm, AVRPART * p,
464 + AVRMEM * m, int page_size, int n_bytes)
466 + unsigned long i;
467 + int rc;
468 + for (i=0; i<n_bytes; i++) {
469 + report_progress(i, n_bytes, NULL);
471 + rc = avr_write_byte_default(pgm, p, m, i, m->buf[i]);
472 + if (rc != 0) {
473 + return -2;
476 + if (m->paged) {
477 + /*
478 + * check to see if it is time to flush the page with a page
479 + * write
480 + */
481 + if (((i % m->page_size) == m->page_size-1) || (i == n_bytes-1)) {
482 + rc = avr_write_page(pgm, p, m, i);
483 + if (rc != 0) {
484 + return -2;
489 + return i;
492 +static struct ft245r_request {
493 + int addr;
494 + int bytes;
495 + int n;
496 + struct ft245r_request *next;
497 +} *req_head,*req_tail,*req_pool;
499 +static void put_request(int addr, int bytes, int n)
501 + struct ft245r_request *p;
502 + if (req_pool) {
503 + p = req_pool;
504 + req_pool = p->next;
505 + } else {
506 + p = malloc(sizeof(struct ft245r_request));
507 + if (!p) {
508 + fprintf(stderr, "can't alloc memory\n");
509 + exit(1);
512 + memset(p, 0, sizeof(struct ft245r_request));
513 + p->addr = addr;
514 + p->bytes = bytes;
515 + p->n = n;
516 + if (req_tail) {
517 + req_tail->next = p;
518 + req_tail = p;
519 + } else {
520 + req_head = req_tail = p;
524 +static int do_request(PROGRAMMER * pgm, AVRMEM *m)
526 + struct ft245r_request *p;
527 + int addr, bytes, j, n;
528 + char buf[FT245R_FRAGMENT_SIZE+1+128];
530 + if (!req_head) return 0;
531 + p = req_head;
532 + req_head = p->next;
533 + if (!req_head) req_tail = req_head;
535 + addr = p->addr;
536 + bytes = p->bytes;
537 + n = p->n;
538 + memset(p, 0, sizeof(struct ft245r_request));
539 + p->next = req_pool;
540 + req_pool = p;
542 + ft245r_recv(pgm, buf, bytes);
543 + for (j=0; j<n; j++) {
544 + m->buf[addr++] = extract_data(buf , (j * 4 + 3));
546 +#if 0
547 +if (n == 0) // paged_write
548 +fprintf(stderr, "recv addr 0x%04x buf size %d \n",addr, bytes);
549 +#endif
550 + return 1;
553 +static int ft245r_paged_write_flash(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
554 + int page_size, int n_bytes)
556 + unsigned int i,j;
557 + int addr,addr_save,buf_pos,do_page_write,req_count;
558 + char buf[FT245R_FRAGMENT_SIZE+1+128];
560 + req_count = 0;
561 + addr = 0;
562 + for (i=0; i<n_bytes; ) {
563 + addr_save = addr;
564 + buf_pos = 0;
565 + do_page_write = 0;
566 + for (j=0; j< FT245R_FRAGMENT_SIZE/8/FT245R_CYCLES/4; j++) {
567 + buf_pos += set_data(buf+buf_pos, (addr & 1)?0x48:0x40 );
568 + buf_pos += set_data(buf+buf_pos, (addr >> 9) & 0xff );
569 + buf_pos += set_data(buf+buf_pos, (addr >> 1) & 0xff );
570 + buf_pos += set_data(buf+buf_pos, m->buf[i]);
571 + addr ++;
572 + i++;
573 + if ( (m->paged) &&
574 + (((i % m->page_size) == 0) || (i == n_bytes))) {
575 + do_page_write = 1;
576 + break;
579 +#if defined(USE_INLINE_WRITE_PAGE)
580 + if (do_page_write) {
581 + int addr_wk = addr_save - (addr_save % m->page_size);
582 + /* If this device has a "load extended address" command, issue it. */
583 + if (m->op[AVR_OP_LOAD_EXT_ADDR]) {
584 + unsigned char cmd[4];
585 + OPCODE *lext = m->op[AVR_OP_LOAD_EXT_ADDR];
587 + memset(cmd, 0, 4);
588 + avr_set_bits(lext, cmd);
589 + avr_set_addr(lext, cmd, addr_wk/2);
590 + buf_pos += set_data(buf+buf_pos, cmd[0]);
591 + buf_pos += set_data(buf+buf_pos, cmd[1]);
592 + buf_pos += set_data(buf+buf_pos, cmd[2]);
593 + buf_pos += set_data(buf+buf_pos, cmd[3]);
595 + buf_pos += set_data(buf+buf_pos, 0x4C); /* Issue Page Write */
596 + buf_pos += set_data(buf+buf_pos,(addr_wk >> 9) & 0xff);
597 + buf_pos += set_data(buf+buf_pos,(addr_wk >> 1) & 0xff);
598 + buf_pos += set_data(buf+buf_pos, 0);
600 +#endif
601 + if (i >= n_bytes) {
602 + buf[buf_pos++] = 0; // sck down
604 + ft245r_send(pgm, buf, buf_pos);
605 + put_request(addr_save, buf_pos, 0);
606 + //ft245r_sync(pgm);
607 +#if 0
608 +fprintf(stderr, "send addr 0x%04x bufsize %d [%02x %02x] page_write %d\n",
609 + addr_save,buf_pos,
610 + extract_data_out(buf , (0*4 + 3) ),
611 + extract_data_out(buf , (1*4 + 3) ),
612 + do_page_write);
613 +#endif
614 + req_count++;
615 + if (req_count > REQ_OUTSTANDINGS)
616 + do_request(pgm, m);
617 + if (do_page_write) {
618 +#if defined(USE_INLINE_WRITE_PAGE)
619 + while (do_request(pgm, m))
621 + usleep(m->max_write_delay);
622 +#else
623 + int addr_wk = addr_save - (addr_save % m->page_size);
624 + int rc;
625 + while (do_request(pgm, m))
627 + rc = avr_write_page(pgm, p, m, addr_wk);
628 + if (rc != 0) {
629 + return -2;
631 +#endif
632 + req_count = 0;
634 + report_progress(i, n_bytes, NULL);
636 + while (do_request(pgm, m))
638 + return i;
642 +static int ft245r_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
643 + int page_size, int n_bytes)
645 + if (strcmp(m->desc, "flash") == 0) {
646 + return ft245r_paged_write_flash(pgm, p, m, page_size, n_bytes);
648 + else if (strcmp(m->desc, "eeprom") == 0) {
649 + return ft245r_paged_write_gen(pgm, p, m, page_size, n_bytes);
651 + else {
652 + return -2;
656 +static int ft245r_paged_load_gen(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
657 + int page_size, int n_bytes)
659 + unsigned char rbyte;
660 + unsigned long i;
661 + int rc;
663 + for (i=0; i<n_bytes; i++) {
664 + rc = avr_read_byte_default(pgm, p, m, i, &rbyte);
665 + if (rc != 0) {
666 + return -2;
668 + m->buf[i] = rbyte;
669 + report_progress(i, n_bytes, NULL);
671 + return 0;
675 +static int ft245r_paged_load_flash(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
676 + int page_size, int n_bytes)
678 + unsigned long i,j,n;
679 + //int rc;
680 + int addr,addr_save,buf_pos;
681 + int req_count = 0;
682 + char buf[FT245R_FRAGMENT_SIZE+1];
684 + addr = 0;
685 + for (i=0; i<n_bytes; ) {
686 + buf_pos = 0;
687 + addr_save = addr;
688 + for (j=0; j< FT245R_FRAGMENT_SIZE/8/FT245R_CYCLES/4; j++) {
689 + if (i >= n_bytes) break;
690 + buf_pos += set_data(buf+buf_pos, (addr & 1)?0x28:0x20 );
691 + buf_pos += set_data(buf+buf_pos, (addr >> 9) & 0xff );
692 + buf_pos += set_data(buf+buf_pos, (addr >> 1) & 0xff );
693 + buf_pos += set_data(buf+buf_pos, 0);
694 + addr ++;
695 + i++;
697 + if (i >= n_bytes) {
698 + buf[buf_pos++] = 0; // sck down
700 + n = j;
701 + ft245r_send(pgm, buf, buf_pos);
702 + put_request(addr_save, buf_pos, n);
703 + req_count++;
704 + if (req_count > REQ_OUTSTANDINGS)
705 + do_request(pgm, m);
706 + report_progress(i, n_bytes, NULL);
708 + while (do_request(pgm, m))
710 + return 0;
713 +static int ft245r_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
714 + int page_size, int n_bytes)
716 + if (strcmp(m->desc, "flash") == 0) {
717 + return ft245r_paged_load_flash(pgm, p, m, page_size, n_bytes);
719 + else if (strcmp(m->desc, "eeprom") == 0) {
720 + return ft245r_paged_load_gen(pgm, p, m, page_size, n_bytes);
722 + else {
723 + return -2;
727 +void ft245r_initpgm(PROGRAMMER * pgm)
729 + strcpy(pgm->type, "ft245r");
731 + /*
732 + * mandatory functions
733 + */
734 + pgm->initialize = ft245r_initialize;
735 + pgm->display = ft245r_display;
736 + pgm->enable = ft245r_enable;
737 + pgm->disable = ft245r_disable;
738 + pgm->program_enable = ft245r_program_enable;
739 + pgm->chip_erase = ft245r_chip_erase;
740 + pgm->cmd = ft245r_cmd;
741 + pgm->open = ft245r_open;
742 + pgm->close = ft245r_close;
743 + pgm->read_byte = avr_read_byte_default;
744 + pgm->write_byte = avr_write_byte_default;
746 + /*
747 + * optional functions
748 + */
749 + pgm->paged_write = ft245r_paged_write;
750 + pgm->paged_load = ft245r_paged_load;
752 + pgm->read_sig_bytes = ft245r_read_sig_bytes;
754 +#else
755 +static int ft245r_initialize(PROGRAMMER * pgm, AVRPART * p)
757 + return -1;
760 +void ft245r_initpgm(PROGRAMMER * pgm)
762 + pgm->initialize = ft245r_initialize;
765 +#endif