Hi,
there was still a problem in the first patch, so it reads the
samecontent for bitbanging and mpsse after the patch but this was both
wrong compared to the state before.
This is now fixed, eeprom should now work, and it uses mpsse when the
correct pins are used and falls back to bitbanging when using other pins.
Any comments?
René Liebscher
On 16.06.2013 23:03, René Liebscher wrote:
Hi,
for a first try you might test the attached patch. It modifies avrftdi
(not ftdi_syncbb, so you have to modify your conf entry).
It changes the avrftdi to use bitbanging over mpsse (using the set
bits commands) and disables the pin check for now. (eeprom writing
might not work.)
With my FT2232D it reads an ATmega168 in 27s (which was 4s using
mpsse). However I do not own any FT232H hardware so I can not do any
further checks.
Kind regards
René Liebscher
On 15.06.2013 22:59, "Ing. Daniel Rozsnyó" wrote:
Hi,
would somebody on this list try to implement this? We can lend the
hardware for testing if required and even offer some compensation
/payment/.
Would be nice to have a really universal soft-BB for FTDI chips.
Thanks,
Daniel Rozsnyo
On 06/06/2013 11:25 PM, René Liebscher wrote:
Hi,
currently only FT232R/FT245R are supported, for other chips one had to
extend this module.
René
On 06.06.2013 21:44, "Ing. Daniel Rozsnyó" wrote:
Hi,
how can I make use of pins AC3~AC7 on a FT232HL for bitbang
programming an AVR?
I naturally tried to count the pins in order AD0..AD7,AC0-AC9, but
avrdude is complaining:
$ avrdude -p atmega32 -c prob-hand -P usb -b 9600
avrdude: BUFF: Following pins are not valid pins for this function: 16
avrdude: RESET: Following pins are not valid pins for this
function: 12
avrdude: SCK: Following pins are not valid pins for this function: 13
avrdude: MOSI: Following pins are not valid pins for this function: 15
avrdude: MISO: Following pins are not valid pins for this function: 14
Pin assignment : 0..7 = DBUS0..7
VCC = (not used)
BUFF = 16
RESET = 12
SCK = 13
MOSI = 15
MISO = 14
ERR LED = (not used)
RDY LED = (not used)
PGM LED = (not used)
VFY LED = (not used)
avrdude done. Thank you.
CONFIG:
programmer
id = "prob-hand";
type = "ftdi_syncbb";
connection_type = usb;
usbvid = 0x0403;
usbpid = 0x6014;
reset = 12;
sck = 13;
miso = 14;
mosi = 15;
buff = 16;
;
Is there a trick or the support is just not there?
Thanks,
Daniel
_______________________________________________
_______________________________________________
avrdude-dev mailing list
[email protected]
https://lists.nongnu.org/mailman/listinfo/avrdude-dev
Index: avrftdi_private.h
===================================================================
--- avrftdi_private.h (Revision 1183)
+++ avrftdi_private.h (Arbeitskopie)
@@ -78,8 +78,8 @@
int pin_limit;
/* internal RX buffer of the device. needed for INOUT transfers */
int rx_buffer_size;
- /* pin checklist. */
- struct pin_checklist_t pin_checklist[N_PINS];
+ /* use bitbanging instead of mpsse spi */
+ bool use_bitbanging;
} avrftdi_t;
void avrftdi_log(int level, const char * func, int line, const char * fmt, ...);
Index: pindefs.c
===================================================================
--- pindefs.c (Revision 1183)
+++ pindefs.c (Arbeitskopie)
@@ -201,7 +201,7 @@
* @param[in] size the number of entries in checklist
* @returns 0 if all pin definitions are valid, -1 otherwise
*/
-int pins_check(const struct programmer_t * const pgm, const struct pin_checklist_t * const checklist, const int size) {
+int pins_check(const struct programmer_t * const pgm, const struct pin_checklist_t * const checklist, const int size, bool output) {
static const struct pindef_t no_valid_pins = {{0}, {0}}; // default value if check list does not contain anything else
int rv = 0; // return value
int pinname; // loop counter through pinnames
@@ -253,46 +253,53 @@
already_used_all[segment] |= pgm->pin[pinname].mask[segment];
}
if(invalid) {
- fprintf(stderr,
- "%s: %s: Following pins are not valid pins for this function: %s\n",
- progname, avr_pin_name(pinname), pinmask_to_str(invalid_used));
- if(verbose >= 2) {
+ if(output) {
fprintf(stderr,
- "%s: %s: Valid pins for this function are: %s\n",
- progname, avr_pin_name(pinname), pinmask_to_str(valid_pins->mask));
+ "%s: %s: Following pins are not valid pins for this function: %s\n",
+ progname, avr_pin_name(pinname), pinmask_to_str(invalid_used));
+ if(verbose >= 2) {
+ fprintf(stderr,
+ "%s: %s: Valid pins for this function are: %s\n",
+ progname, avr_pin_name(pinname), pinmask_to_str(valid_pins->mask));
+ }
}
is_ok = false;
}
if(inverse) {
- fprintf(stderr,
+ if(output) {
+ fprintf(stderr,
"%s: %s: Following pins are not usable as inverse pins for this function: %s\n",
progname, avr_pin_name(pinname), pinmask_to_str(inverse_used));
- if(verbose >= 2) {
- fprintf(stderr,
- "%s: %s: Valid inverse pins for this function are: %s\n",
- progname, avr_pin_name(pinname), pinmask_to_str(valid_pins->inverse));
+ if(verbose >= 2) {
+ fprintf(stderr,
+ "%s: %s: Valid inverse pins for this function are: %s\n",
+ progname, avr_pin_name(pinname), pinmask_to_str(valid_pins->inverse));
+ }
}
is_ok = false;
}
if(used) {
- fprintf(stderr,
- "%s: %s: Following pins are set for other functions too: %s\n",
- progname, avr_pin_name(pinname), pinmask_to_str(already_used));
- is_ok = false;
+ if(output) {
+ fprintf(stderr,
+ "%s: %s: Following pins are set for other functions too: %s\n",
+ progname, avr_pin_name(pinname), pinmask_to_str(already_used));
+ is_ok = false;
+ }
}
if(!mandatory_used && is_mandatory && !invalid) {
- fprintf(stderr,
- "%s: %s: Mandatory pin is not defined.\n",
- progname, avr_pin_name(pinname));
+ if(output) {
+ fprintf(stderr,
+ "%s: %s: Mandatory pin is not defined.\n",
+ progname, avr_pin_name(pinname));
+ }
is_ok = false;
}
if(!is_ok) {
rv = -1;
- } else if(verbose >= 3) {
+ } else if(output && verbose >= 3) {
fprintf(stderr,
"%s: %s: Pin is ok.\n",
progname, avr_pin_name(pinname));
-
}
}
return rv;
Index: pindefs.h
===================================================================
--- pindefs.h (Revision 1183)
+++ pindefs.h (Arbeitskopie)
@@ -165,9 +165,10 @@
* @param[in] pgm the programmer to check
* @param[in] checklist the constraint for the pins
* @param[in] size the number of entries in checklist
+ * @param[in] output false suppresses error messages to the user
* @returns 0 if all pin definitions are valid, -1 otherwise
*/
-int pins_check(const struct programmer_t * const pgm, const struct pin_checklist_t * const checklist, const int size);
+int pins_check(const struct programmer_t * const pgm, const struct pin_checklist_t * const checklist, const int size, const bool output);
/**
* Returns the name of the pin as string.
Index: ft245r.c
===================================================================
--- ft245r.c (Revision 1183)
+++ ft245r.c (Arbeitskopie)
@@ -528,7 +528,7 @@
int rv;
int devnum = -1;
- rv = pins_check(pgm,pin_checklist,sizeof(pin_checklist)/sizeof(pin_checklist[0]));
+ rv = pins_check(pgm,pin_checklist,sizeof(pin_checklist)/sizeof(pin_checklist[0]), true);
if(rv) {
pgm->display(pgm, progbuf);
return rv;
Index: avrftdi.c
===================================================================
--- avrftdi.c (Revision 1183)
+++ avrftdi.c (Arbeitskopie)
@@ -295,12 +295,133 @@
set_pin(pgm, PPI_AVR_VCC, OFF);
}
+static inline int set_data(PROGRAMMER * pgm, unsigned char *buf, unsigned char data, bool read_data) {
+ int j;
+ int buf_pos = 0;
+ unsigned char bit = 0x80;
+ avrftdi_t* pdata = to_pdata(pgm);
+
+ for (j=0; j<8; j++) {
+ pdata->pin_value = SET_BITS_0(pdata->pin_value,pgm,PIN_AVR_MOSI,data & bit);
+ pdata->pin_value = SET_BITS_0(pdata->pin_value,pgm,PIN_AVR_SCK,0);
+ buf[buf_pos++] = SET_BITS_LOW;
+ buf[buf_pos++] = (pdata->pin_value) & 0xff;
+ buf[buf_pos++] = (pdata->pin_direction) & 0xff;
+ buf[buf_pos++] = SET_BITS_HIGH;
+ buf[buf_pos++] = ((pdata->pin_value) >> 8) & 0xff;
+ buf[buf_pos++] = ((pdata->pin_direction) >> 8) & 0xff;
+
+ pdata->pin_value = SET_BITS_0(pdata->pin_value,pgm,PIN_AVR_SCK,1);
+ buf[buf_pos++] = SET_BITS_LOW;
+ buf[buf_pos++] = (pdata->pin_value) & 0xff;
+ buf[buf_pos++] = (pdata->pin_direction) & 0xff;
+ buf[buf_pos++] = SET_BITS_HIGH;
+ buf[buf_pos++] = ((pdata->pin_value) >> 8) & 0xff;
+ buf[buf_pos++] = ((pdata->pin_direction) >> 8) & 0xff;
+
+ if (read_data) {
+ buf[buf_pos++] = GET_BITS_LOW;
+ buf[buf_pos++] = GET_BITS_HIGH;
+ }
+
+ bit >>= 1;
+ }
+ return buf_pos;
+}
+
+static inline unsigned char extract_data(PROGRAMMER * pgm, unsigned char *buf, int offset) {
+ int j;
+ unsigned char bit = 0x80;
+ unsigned char r = 0;
+
+ buf += offset * 16; // 2 bytes per bit, 8 bits
+ for (j=0; j<8; j++) {
+ uint16_t in = buf[0] | (buf[1] << 8);
+ if (GET_BITS_0(in,pgm,PIN_AVR_MISO)) {
+ r |= bit;
+ }
+ buf += 2; // 2 bytes per input
+ bit >>= 1;
+ }
+ return r;
+}
+
+
+static int avrftdi_transmit_bb(PROGRAMMER * pgm, unsigned char mode, unsigned char *buf,
+ unsigned char *data, int buf_size)
+{
+ size_t blocksize;
+ size_t remaining = buf_size;
+ size_t written = 0;
+ avrftdi_t* pdata = to_pdata(pgm);
+
+ // more than this does not work with FT2232D
+ blocksize = 16;//pdata->rx_buffer_size/2; // we are reading 2 bytes per data byte
+
+ while(remaining)
+ {
+
+ size_t transfer_size = (remaining > blocksize) ? blocksize : remaining;
+
+ // (8*2) outputs per data byte, 6 transmit bytes per output (SET_BITS_LOW/HIGH),
+ // (8*1) inputs per data byte, 2 transmit bytes per input (GET_BITS_LOW/HIGH),
+ // 1x SEND_IMMEDIATE
+ unsigned char send_buffer[(8*2*6)*transfer_size+(8*1*2)*transfer_size+7];
+ int len = 0;
+ int i;
+
+ for(i = 0 ; i< transfer_size; i++) {
+ len += set_data(pgm, send_buffer + len, buf[written+i], (mode & MPSSE_DO_READ) != 0);
+ }
+
+ pdata->pin_value = SET_BITS_0(pdata->pin_value,pgm,PIN_AVR_SCK,0);
+ send_buffer[len++] = SET_BITS_LOW;
+ send_buffer[len++] = (pdata->pin_value) & 0xff;
+ send_buffer[len++] = (pdata->pin_direction) & 0xff;
+ send_buffer[len++] = SET_BITS_HIGH;
+ send_buffer[len++] = ((pdata->pin_value) >> 8) & 0xff;
+ send_buffer[len++] = ((pdata->pin_direction) >> 8) & 0xff;
+
+ send_buffer[len++] = SEND_IMMEDIATE;
+
+// fprintf(stderr,"ftdi_write_data: [%d]\n",len);
+//int hexdump_buf(FILE * f, int startaddr, unsigned char * buf, int len);
+// hexdump_buf(stderr,0,&buf[written],transfer_size);
+// hexdump_buf(stderr,0,send_buffer,len);
+
+ E(ftdi_write_data(pdata->ftdic, send_buffer, len) != len, pdata->ftdic);
+ if (mode & MPSSE_DO_READ) {
+ unsigned char recv_buffer[2*16*transfer_size];
+ int n;
+ int k = 0;
+ do {
+ n = ftdi_read_data(pdata->ftdic, &recv_buffer[k], 2*16*transfer_size - k);
+ E(n < 0, pdata->ftdic);
+ k += n;
+ } while (k < transfer_size);
+
+// fprintf(stderr,"ftdi_read_data: [%d]\n",k);
+//int hexdump_buf(FILE * f, int startaddr, unsigned char * buf, int len);
+// hexdump_buf(stderr,0,recv_buffer,k);
+ for(i = 0 ; i< transfer_size; i++) {
+ data[written + i] = extract_data(pgm, recv_buffer, i);
+ }
+// hexdump_buf(stderr,0,&data[written],transfer_size);
+ }
+
+ written += transfer_size;
+ remaining -= transfer_size;
+ }
+
+ return written;
+}
+
/* Send 'buf_size' bytes from 'cmd' to device and return data from device in
* buffer 'data'.
* Write is only performed when mode contains MPSSE_DO_WRITE.
* Read is only performed when mode contains MPSSE_DO_WRITE and MPSSE_DO_READ.
*/
-static int avrftdi_transmit(avrftdi_t* pdata, unsigned char mode, unsigned char *buf,
+static int avrftdi_transmit_mpsse(avrftdi_t* pdata, unsigned char mode, unsigned char *buf,
unsigned char *data, int buf_size)
{
size_t blocksize;
@@ -358,6 +479,15 @@
return written;
}
+static inline int avrftdi_transmit(PROGRAMMER * pgm, unsigned char mode, unsigned char *buf,
+ unsigned char *data, int buf_size)
+{
+ avrftdi_t* pdata = to_pdata(pgm);
+ if (pdata->use_bitbanging)
+ return avrftdi_transmit_bb(pgm, mode, buf, data, buf_size);
+ else
+ return avrftdi_transmit_mpsse(pdata, mode, buf, data, buf_size);
+}
/* this function tries to sync up with the FTDI. See FTDI application note AN_129.
* AN_135 uses 0xab as bad command and enables/disables loopback around synchronisation.
* This may fail if data is left in the buffer (i.e. avrdude aborted with ctrl-c)
@@ -477,14 +607,41 @@
}
-static int avrftdi_pin_setup(PROGRAMMER * pgm)
+static int avrftdi_check_pins_bb(PROGRAMMER * pgm, bool output)
{
- /*************
- * pin setup *
- *************/
+ int pin;
+ /* pin checklist. */
+ struct pin_checklist_t pin_checklist[N_PINS];
+
+ avrftdi_t* pdata = to_pdata(pgm);
+
+ /* value for 8/12/16 bit wide interface */
+ int valid_mask = ((1 << pdata->pin_limit) - 1);
+
+ log_debug("Using valid mask bibanging: 0x%08x\n", valid_mask);
+ static struct pindef_t valid_pins;
+ valid_pins.mask[0] = valid_mask;
+ valid_pins.inverse[0] = valid_mask ;
+
+ /* build pin checklist */
+ for(pin = 0; pin < N_PINS; ++pin) {
+ pin_checklist[pin].pinname = pin;
+ pin_checklist[pin].mandatory = 0;
+ pin_checklist[pin].valid_pins = &valid_pins;
+ }
+
+ /* assumes all checklists above have same number of entries */
+ return pins_check(pgm, pin_checklist, N_PINS, output);
+}
+
+static int avrftdi_check_pins_mpsse(PROGRAMMER * pgm, bool output)
+{
int pin;
+ /* pin checklist. */
+ struct pin_checklist_t pin_checklist[N_PINS];
+
avrftdi_t* pdata = to_pdata(pgm);
/* SCK/MOSI/MISO are fixed and not invertable?*/
@@ -498,56 +655,80 @@
/* mask out SCK/MISO/MOSI */
valid_mask &= ~((1 << FTDI_SCK) | (1 << FTDI_MOSI) | (1 << FTDI_MISO));
- log_debug("Using valid mask: 0x%08x\n", valid_mask);
+ log_debug("Using valid mask mpsse: 0x%08x\n", valid_mask);
static struct pindef_t valid_pins_others;
valid_pins_others.mask[0] = valid_mask;
valid_pins_others.inverse[0] = valid_mask ;
/* build pin checklist */
for(pin = 0; pin < N_PINS; ++pin) {
- pdata->pin_checklist[pin].pinname = pin;
- pdata->pin_checklist[pin].mandatory = 0;
- pdata->pin_checklist[pin].valid_pins = &valid_pins_others;
+ pin_checklist[pin].pinname = pin;
+ pin_checklist[pin].mandatory = 0;
+ pin_checklist[pin].valid_pins = &valid_pins_others;
}
- pdata->pin_checklist[PIN_AVR_SCK].mandatory = 1;
- pdata->pin_checklist[PIN_AVR_SCK].valid_pins = &valid_pins_SCK;
- pdata->pin_checklist[PIN_AVR_MOSI].mandatory = 1;
- pdata->pin_checklist[PIN_AVR_MOSI].valid_pins = &valid_pins_MOSI;
- pdata->pin_checklist[PIN_AVR_MISO].mandatory = 1;
- pdata->pin_checklist[PIN_AVR_MISO].valid_pins = &valid_pins_MISO;
- pdata->pin_checklist[PIN_AVR_RESET].mandatory = 1;
- /* everything is an output, except MISO */
- for(pin = 0; pin < N_PINS; ++pin) {
- pdata->pin_direction |= pgm->pin[pin].mask[0];
- pdata->pin_value = SET_BITS_0(pdata->pin_value, pgm, pin, OFF);
- }
- pdata->pin_direction &= ~pgm->pin[PIN_AVR_MISO].mask[0];
+ /* now set mpsse specific pins */
+ pin_checklist[PIN_AVR_SCK].mandatory = 1;
+ pin_checklist[PIN_AVR_SCK].valid_pins = &valid_pins_SCK;
+ pin_checklist[PIN_AVR_MOSI].mandatory = 1;
+ pin_checklist[PIN_AVR_MOSI].valid_pins = &valid_pins_MOSI;
+ pin_checklist[PIN_AVR_MISO].mandatory = 1;
+ pin_checklist[PIN_AVR_MISO].valid_pins = &valid_pins_MISO;
+ pin_checklist[PIN_AVR_RESET].mandatory = 1;
- for(pin = PIN_LED_ERR; pin < N_PINS; ++pin) {
- pdata->led_mask |= pgm->pin[pin].mask[0];
- }
+ /* assumes all checklists above have same number of entries */
+ return pins_check(pgm, pin_checklist, N_PINS, output);
+}
- /* assumes all checklists above have same number of entries */
- if (pins_check(pgm, pdata->pin_checklist,N_PINS)) {
+static int avrftdi_pin_setup(PROGRAMMER * pgm)
+{
+ int pin;
+
+ /*************
+ * pin setup *
+ *************/
+
+ avrftdi_t* pdata = to_pdata(pgm);
+
+ bool pin_check_mpsse = (0 == avrftdi_check_pins_mpsse(pgm, verbose>3));
+
+ bool pin_check_bitbanging = (0 == avrftdi_check_pins_bb(pgm, verbose>3));
+
+ if (!pin_check_mpsse && !pin_check_bitbanging) {
+ log_err("No valid pin configuration found.\n");
+ avrftdi_check_pins_bb(pgm, true);
log_err("Pin configuration for FTDI MPSSE must be:\n");
log_err("%s: 0, %s: 1, %s: 2 (is: %s, %s, %s)\n", avr_pin_name(PIN_AVR_SCK),
avr_pin_name(PIN_AVR_MOSI), avr_pin_name(PIN_AVR_MISO),
pins_to_str(&pgm->pin[PIN_AVR_SCK]),
pins_to_str(&pgm->pin[PIN_AVR_MOSI]),
pins_to_str(&pgm->pin[PIN_AVR_MISO]));
- log_err("Please correct your cabling and/or configuration.\n");
- log_err("If your hardware is fixed, consider using a bitbang programmer.\n");
+ log_err("If other pin configuration is used, fallback to slower bitbanging mode is used.\n");
return -1;
}
+ pdata->use_bitbanging = !pin_check_mpsse || 1;
+ if (pdata->use_bitbanging) log_info("Because of pin configuration fallback to bitbanging mode.\n");
+
/*
* TODO: No need to fail for a wrongly configured led or something.
* Maybe we should only fail for SCK; MISO, MOSI, RST (and probably
* VCC and BUFF).
*/
+ /* everything is an output, except MISO */
+ for(pin = 0; pin < N_PINS; ++pin) {
+ pdata->pin_direction |= pgm->pin[pin].mask[0];
+ pdata->pin_value = SET_BITS_0(pdata->pin_value, pgm, pin, OFF);
+ }
+ pdata->pin_direction &= ~pgm->pin[PIN_AVR_MISO].mask[0];
+
+ for(pin = PIN_LED_ERR; pin < N_PINS; ++pin) {
+ pdata->led_mask |= pgm->pin[pin].mask[0];
+ }
+
+
log_info("Pin direction mask: %04x\n", pdata->pin_direction);
log_info("Pin value mask: %04x\n", pdata->pin_value);
@@ -754,7 +935,7 @@
{
/* Do not use 'sizeof(cmd)'. => message from cppcheck:
Using sizeof for array given as function argument returns the size of pointer. */
- return avrftdi_transmit(to_pdata(pgm), MPSSE_DO_READ | MPSSE_DO_WRITE, cmd, res, 4);
+ return avrftdi_transmit(pgm, MPSSE_DO_READ | MPSSE_DO_WRITE, cmd, res, 4);
}
@@ -838,8 +1019,7 @@
static int avrftdi_eeprom_write(PROGRAMMER *pgm, AVRPART *p, AVRMEM *m,
unsigned int page_size, unsigned int addr, unsigned int len)
{
- unsigned char cmd[] =
- { MPSSE_DO_WRITE | MPSSE_WRITE_NEG, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00 };
+ unsigned char cmd[] = { 0x00, 0x00, 0x00, 0x00 };
unsigned char *data = &m->buf[addr];
unsigned int add;
@@ -847,14 +1027,12 @@
for (add = addr; add < addr + len; add++)
{
- avr_set_addr(m->op[AVR_OP_WRITE], &cmd[3], add);
- avr_set_input(m->op[AVR_OP_WRITE], &cmd[3], *data++);
+ avr_set_addr(m->op[AVR_OP_WRITE], cmd, add);
+ avr_set_input(m->op[AVR_OP_WRITE], cmd, *data++);
- //avrftdi_transmit(to_pdata(pgm), MPSSE_DO_WRITE, cmd, cmd, 4);
- E(ftdi_write_data(to_pdata(pgm)->ftdic, cmd, sizeof(cmd)) != sizeof(cmd),
- to_pdata(pgm)->ftdic);
+ avrftdi_transmit(pgm, MPSSE_DO_WRITE, cmd, cmd, 4);
+ usleep((m->max_write_delay));
- usleep((m->max_write_delay));
}
return len;
}
@@ -873,7 +1051,7 @@
avr_set_bits(m->op[AVR_OP_READ], cmd);
avr_set_addr(m->op[AVR_OP_READ], cmd, add);
- avrftdi_transmit(to_pdata(pgm), MPSSE_DO_READ | MPSSE_DO_WRITE, cmd, cmd, 4);
+ avrftdi_transmit(pgm, MPSSE_DO_READ | MPSSE_DO_WRITE, cmd, cmd, 4);
avr_get_output(m->op[AVR_OP_READ], cmd, bufptr++);
}
@@ -963,7 +1141,7 @@
buf_dump(buf, buf_size, "command buffer", 0, 16*2);
log_info("Transmitting buffer of size: %d\n", buf_size);
- avrftdi_transmit(to_pdata(pgm), MPSSE_DO_WRITE, buf, buf, buf_size);
+ avrftdi_transmit(pgm, MPSSE_DO_WRITE, buf, buf, buf_size);
bufptr = buf;
/* find a poll byte. we cannot poll a value of 0xff, so look
@@ -1053,7 +1231,7 @@
buf_dump(o_buf, sizeof(o_buf), "o_buf", 0, 32);
}
- avrftdi_transmit(to_pdata(pgm), MPSSE_DO_READ | MPSSE_DO_WRITE, o_buf, i_buf, len * 4);
+ avrftdi_transmit(pgm, MPSSE_DO_READ | MPSSE_DO_WRITE, o_buf, i_buf, len * 4);
if(verbose > TRACE) {
buf_dump(i_buf, sizeof(i_buf), "i_buf", 0, 32);
_______________________________________________
avrdude-dev mailing list
[email protected]
https://lists.nongnu.org/mailman/listinfo/avrdude-dev