Skip to content

Commit 49e5f24

Browse files
committed
patch #9328: ft245r.c: add TPI support (patches 5-7)
Submitted by David Mosberger-Tang: * ft245r.c (ft245r_set_bitclock): add workaround for FT245 hardware bugs in bitclock setting Correct baud rate calculation (multiplying with factor of 2 was wrong) and add compile-time workaround for FTDI chips suffering for the variable pulse-width errata. The workaround entails always running the chip at 3MHz and stuffing the channel with repeated bytes to achieve the desired baudrate. This has no effect on programming speed. Note, however, that now a baudrate option -b750000 has to be used to achieve maximum speed. (Option enabled by default now.) git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk/avrdude@1488 81a1dc3b-b13d-400b-aceb-764788c761c2
1 parent 2015a87 commit 49e5f24

File tree

3 files changed

+61
-18
lines changed

3 files changed

+61
-18
lines changed

ChangeLog

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
1+
2021-11-25 Joerg Wunsch <[email protected]>
2+
3+
Submitted by David Mosberger-Tang:
4+
patch #9328: ft245r.c: add TPI support (patches 5-7)
5+
* ft245r.c (ft245r_set_bitclock): add workaround for
6+
FT245 hardware bugs in bitclock setting
7+
18
2021-11-25 Joerg Wunsch <[email protected]>
29

310
Submitted by David Mosberger-Tang:

NEWS

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,12 @@ Current:
1414
debuggers (JTAGICE3 with firmware 3+, AtmelICE, EDBG, mEDBG)
1515
- UPDI support added (AVR8X family)
1616
- TPI support for USBtinyISP
17+
- TPI support for ft245r
1718
- AVR Doper uses libhidapi rather than raw libusb (patch #9033)
1819
- -P net:host:port can use IPv6 now (Posix systems only)
1920
- New configure option: -disable-libusb_1_0
2021
- extended UPDI device context (> 64 Ki flash)
22+
- major overhaul of ft245r driver (patch #9327/#9328)
2123

2224
* New devices supported:
2325

@@ -108,11 +110,13 @@ Current:
108110
patch #9110: Let reserved fuse bits to be read as *don't care*
109111
patch #9253: Fix for giving terminal_mode commands more than 20 arguments
110112
patch #9320: fix TPI RESET in bitbang.c
111-
patch #9079: Fix ftdi_syncbb teardown (supersedes #9893)
113+
patch #9079: Fix ftdi_syncbb teardown (supersedes #9893, superseded by #9328)
112114
patch #9122: Fixed MISO sampling in ftdi_syncbb
113115
patch #9123: ftdi_syncbb: use FT245R_CYCLES in ft245r_set_bitclock()
114116
patch #8719: Support Over-the-Air bootloading with XBeeBoot
115117
patch #9757: Fix ATtiny817 Xplained Mini programmer
118+
patch #9327: ft245r.c: add TPI support (patches 1-4)
119+
patch #9328: ft245r.c: add TPI support (patches 5-7)
116120

117121
* Internals:
118122
- New avrdude.conf keyword "family_id", used to verify SIB attributes

ft245r.c

Lines changed: 49 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@
5959
#include <sys/time.h>
6060
#include <unistd.h>
6161
#include <stdint.h>
62+
#include <math.h>
6263

6364
#include "avrdude.h"
6465
#include "libavrdude.h"
@@ -113,9 +114,26 @@ void ft245r_initpgm(PROGRAMMER * pgm) {
113114
//#define USE_INLINE_WRITE_PAGE
114115

115116
#define FT245R_DEBUG 0
117+
/*
118+
Some revisions of the FTDI chips mess up the timing in bitbang mode
119+
unless the bitclock is set to the max (3MHz). For example, see:
120+
121+
http://www.ftdichip.com/Support/Documents/TechnicalNotes/TN_120_FT232R%20Errata%20Technical%20Note.pdf
122+
123+
To work around this problem, set the macro below to 1 to always set
124+
the bitclock to 3MHz and then issue the same byte repeatedly to get
125+
the desired timing.
126+
127+
*/
128+
#define FT245R_BITBANG_VARIABLE_PULSE_WIDTH_WORKAROUND 1
116129

117130
static struct ftdi_context *handle;
118131

132+
#if FT245R_BITBANG_VARIABLE_PULSE_WIDTH_WORKAROUND
133+
static unsigned int baud_multiplier;
134+
#else
135+
# define baud_multiplier 1 // this let's C compiler optimize
136+
#endif
119137
static unsigned char ft245r_ddr;
120138
static unsigned char ft245r_out;
121139

@@ -213,14 +231,16 @@ static int ft245r_flush(PROGRAMMER * pgm) {
213231

214232
static int ft245r_send2(PROGRAMMER * pgm, unsigned char * buf, size_t len,
215233
bool discard_rx_data) {
216-
int i;
234+
int i, j;
217235

218236
for (i = 0; i < len; ++i) {
219-
if (discard_rx_data)
220-
++rx.discard;
221-
tx.buf[tx.len++] = buf[i];
222-
if (tx.len >= FT245R_MIN_FIFO_SIZE)
223-
ft245r_flush(pgm);
237+
for (j = 0; j < baud_multiplier; ++j) {
238+
if (discard_rx_data)
239+
++rx.discard;
240+
tx.buf[tx.len++] = buf[i];
241+
if (tx.len >= FT245R_MIN_FIFO_SIZE)
242+
ft245r_flush(pgm);
243+
}
224244
}
225245
return 0;
226246
}
@@ -235,7 +255,7 @@ static int ft245r_send_and_discard(PROGRAMMER * pgm, unsigned char * buf,
235255
}
236256

237257
static int ft245r_recv(PROGRAMMER * pgm, unsigned char * buf, size_t len) {
238-
int i;
258+
int i, j;
239259

240260
ft245r_flush(pgm);
241261
ft245r_fill(pgm);
@@ -249,8 +269,11 @@ static int ft245r_recv(PROGRAMMER * pgm, unsigned char * buf, size_t len) {
249269
--rx.discard;
250270
}
251271

252-
for (i = 0; i < len; ++i)
272+
for (i = 0; i < len; ++i) {
253273
buf[i] = ft245r_rx_buf_get(pgm);
274+
for (j = 1; j < baud_multiplier; ++j)
275+
ft245r_rx_buf_get(pgm);
276+
}
254277
return 0;
255278
}
256279

@@ -298,23 +321,32 @@ static int ft245r_chip_erase(PROGRAMMER * pgm, AVRPART * p) {
298321

299322

300323
static int ft245r_set_bitclock(PROGRAMMER * pgm) {
301-
int r;
302-
int rate = 0;
324+
// libftdi1 multiplies bitbang baudrate by 4:
325+
int r, rate = 0, ftdi_rate = 3000000 / 4;
303326

304327
/* bitclock is second. 1us = 0.000001. Max rate for ft232r 750000 */
305328
if(pgm->bitclock) {
306-
rate = (uint32_t)(1.0/pgm->bitclock) * FT245R_CYCLES;
329+
rate = (uint32_t)(1.0/pgm->bitclock);
307330
} else if (pgm->baudrate) {
308-
rate = pgm->baudrate * FT245R_CYCLES;
331+
rate = pgm->baudrate;
309332
} else {
310333
rate = 150000; /* should work for all ftdi chips and the avr default internal clock of 1MHz */
311334
}
312335

313-
if (FT245R_DEBUG) {
314-
avrdude_message(MSG_NOTICE2, " ft245r: spi bitclk %d -> ft baudrate %d\n",
315-
rate / FT245R_CYCLES, rate);
316-
}
317-
r = ftdi_set_baudrate(handle, rate);
336+
#if FT245R_BITBANG_VARIABLE_PULSE_WIDTH_WORKAROUND
337+
if (rate > 0 && rate < ftdi_rate)
338+
baud_multiplier = round((ftdi_rate + rate - 1) / rate);
339+
else
340+
baud_multiplier = 1;
341+
#else
342+
ftdi_rate = rate;
343+
#endif
344+
345+
avrdude_message(MSG_NOTICE2,
346+
"%s: bitclk %d -> FTDI rate %d, baud multiplier %d\n",
347+
__func__, rate, ftdi_rate, baud_multiplier);
348+
349+
r = ftdi_set_baudrate(handle, ftdi_rate);
318350
if (r) {
319351
avrdude_message(MSG_INFO, "Set baudrate (%d) failed with error '%s'.\n",
320352
rate, ftdi_get_error_string (handle));

0 commit comments

Comments
 (0)