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
avrdude-dev@nongnu.org
https://lists.nongnu.org/mailman/listinfo/avrdude-dev


_______________________________________________
avrdude-dev mailing list
avrdude-dev@nongnu.org
https://lists.nongnu.org/mailman/listinfo/avrdude-dev


_______________________________________________
avrdude-dev mailing list
avrdude-dev@nongnu.org
https://lists.nongnu.org/mailman/listinfo/avrdude-dev

Index: avrftdi_private.h
===================================================================
--- avrftdi_private.h	(Revision 1183)
+++ avrftdi_private.h	(Arbeitskopie)
@@ -80,6 +80,7 @@
 	int rx_buffer_size;
 	/* pin checklist. */
  struct pin_checklist_t pin_checklist[N_PINS];
+bool use_bitbanging;
 } avrftdi_t;
 
 void avrftdi_log(int level, const char * func, int line, const char * fmt, ...);
Index: avrftdi.c
===================================================================
--- avrftdi.c	(Revision 1183)
+++ avrftdi.c	(Arbeitskopie)
@@ -295,6 +295,131 @@
 	set_pin(pgm, PPI_AVR_VCC, OFF);
 }
 
+
+static inline int set_data(PROGRAMMER * pgm, avrftdi_t* pdata, unsigned char *buf, unsigned char data, bool read_data) {
+    int j;
+    int buf_pos = 0;
+    unsigned char bit = 0x80;
+
+    for (j=0; j<8; j++) {
+        pdata->pin_value = SET_BITS_0(pdata->pin_value,pgm,PIN_AVR_MOSI,data & bit);
+        // could be optimized if we know if sck is in same byte as mosi
+        // in case if not if we would sent the byte containing the mosi data first
+	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;
+        }
+
+        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;
+
+        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;
+    uint16_t in;
+
+    buf += offset * 16; // 2 bytes per bit, 8 bits
+    for (j=0; j<8; j++) {
+        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, avrftdi_t* pdata, unsigned char mode, unsigned char *buf,
+			    unsigned char *data, int buf_size)
+{
+	size_t blocksize;
+	size_t remaining = buf_size;
+	size_t written = 0;
+	
+	//if we are not reading back, we can just write the data out
+	//if(!(mode & MPSSE_DO_READ))
+	//	blocksize = buf_size;
+	//else
+		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*3) 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*3*6)*transfer_size+(8*1*2)*transfer_size+1];
+		int len = 0,len2;
+		int i;
+		
+		for(i = 0 ; i< transfer_size; i++) {
+		    len += set_data(pgm,pdata,send_buffer + len, buf[written+i], (mode & MPSSE_DO_READ) != 0);
+		}
+		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.
@@ -527,9 +652,11 @@
 	for(pin = PIN_LED_ERR; pin < N_PINS; ++pin) {
 		pdata->led_mask |= pgm->pin[pin].mask[0];
 	}
+	pdata->use_bitbanging = 1;
 
+
 	/* assumes all checklists above have same number of entries */
-	if (pins_check(pgm, pdata->pin_checklist,N_PINS)) {
+	if (0 && pins_check(pgm, pdata->pin_checklist,N_PINS)) {
 		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),
@@ -754,7 +881,10 @@
 {
 	/* 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);
+	if (to_pdata(pgm)->use_bitbanging)
+	    return avrftdi_transmit_bb(pgm, to_pdata(pgm), MPSSE_DO_READ | MPSSE_DO_WRITE, cmd, res, 4);
+	else
+	    return avrftdi_transmit(to_pdata(pgm), MPSSE_DO_READ | MPSSE_DO_WRITE, cmd, res, 4);
 }
 
 
@@ -849,7 +979,7 @@
 	{
 		avr_set_addr(m->op[AVR_OP_WRITE], &cmd[3], add);
 		avr_set_input(m->op[AVR_OP_WRITE], &cmd[3], *data++);
-
+// TODO
 		//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);
@@ -873,7 +1003,10 @@
 		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);
+		if (to_pdata(pgm)->use_bitbanging)
+			avrftdi_transmit_bb(pgm, to_pdata(pgm), MPSSE_DO_READ | MPSSE_DO_WRITE, cmd, cmd, 4);
+		else
+			avrftdi_transmit(to_pdata(pgm), MPSSE_DO_READ | MPSSE_DO_WRITE, cmd, cmd, 4);
 
 		avr_get_output(m->op[AVR_OP_READ], cmd, bufptr++);
 	}
@@ -963,7 +1096,10 @@
 		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);
+	if (to_pdata(pgm)->use_bitbanging)
+	    return avrftdi_transmit_bb(pgm, to_pdata(pgm), MPSSE_DO_WRITE, buf, buf, buf_size);
+	else
+	    return avrftdi_transmit(to_pdata(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 +1189,10 @@
 		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);
+	if (to_pdata(pgm)->use_bitbanging)
+	    return avrftdi_transmit_bb(pgm, to_pdata(pgm), MPSSE_DO_READ | MPSSE_DO_WRITE, o_buf, i_buf, len * 4);
+	else
+	    return avrftdi_transmit(to_pdata(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
avrdude-dev@nongnu.org
https://lists.nongnu.org/mailman/listinfo/avrdude-dev

Reply via email to