From 105cebb38935b4052ac71694b16c60f8f8ac7813 Mon Sep 17 00:00:00 2001
From: Joerg Wunsch <j@uriah.heep.sax.de>
Date: Wed, 24 Nov 2021 22:06:31 +0000
Subject: [PATCH] patch #9327: ft245r.c: add TPI support (patches 1-4)

Submitted by David Mosberger-Tang:

Optimize TPI programming speed by reducing number of USB reads.
Specifically, when writing to the FTDI chip (without needing the data
it accumulates), simply increment a count of how many bytes the next
read should ignore.  Thus, if there is one or more write followed by a
read, we only need to read from the device once.

Improves TPI programming speed by another factor of 2.



git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk/avrdude@1485 81a1dc3b-b13d-400b-aceb-764788c761c2
---
 ChangeLog |  7 +++++++
 ft245r.c  | 21 ++++++++++++++++-----
 2 files changed, 23 insertions(+), 5 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 92032451..c9d215f3 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2021-11-24  Joerg Wunsch <j.gnu@uriah.heep.sax.de>
+
+	Submitted by David Mosberger-Tang:
+	patch #9327: ft245r.c: add TPI support (patches 1-4)
+	* ft245r.c (ft245r_recv):  Optimize TPI programming
+	speed by reducing number of USB reads.
+
 2021-11-24  Joerg Wunsch <j.gnu@uriah.heep.sax.de>
 
 	Submitted by David Mosberger-Tang:
diff --git a/ft245r.c b/ft245r.c
index 588b099d..c2bfb561 100644
--- a/ft245r.c
+++ b/ft245r.c
@@ -161,6 +161,9 @@ static pthread_t readerthread;
 static sem_t buf_data, buf_space;
 static unsigned char buffer[BUFSIZE];
 static int head, tail;
+static struct {
+    int discard;	// # of bytes to discard during read
+} rx;
 
 static void add_to_buf (unsigned char c) {
     int nh;
@@ -206,15 +209,24 @@ static int ft245r_send(PROGRAMMER * pgm, unsigned char * buf, size_t len) {
     return 0;
 }
 
+static int ft245r_send_and_discard(PROGRAMMER * pgm, unsigned char * buf,
+				   size_t len) {
+    rx.discard += len;
+    return ft245r_send(pgm, buf, len);
+}
+
 static int ft245r_recv(PROGRAMMER * pgm, unsigned char * buf, size_t len) {
-    int i;
+    int i = 0;
 
     // Copy over data from the circular buffer..
     // XXX This should timeout, and return error if there isn't enough
     // data.
-    for (i=0; i<len; i++) {
+    while (i < len) {
         sem_wait (&buf_data);
-        buf[i] = buffer[tail];
+	if (rx.discard > 0)
+	    --rx.discard;
+	else
+	    buf[i++] = buffer[tail];
         if (tail == (BUFSIZE -1)) tail = 0;
         else                      tail++;
         sem_post (&buf_space);
@@ -645,8 +657,7 @@ static int ft245r_tpi_tx(PROGRAMMER * pgm, uint8_t byte) {
     int len;
 
     len = set_tpi_data(pgm, buf, byte);
-    ft245r_send(pgm, buf, len);
-    ft245r_recv(pgm, buf, len);
+    ft245r_send_and_discard(pgm, buf, len);
     return 0;
 }