diff --git a/ChangeLog b/ChangeLog index a6b12e6f..1a8691df 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2021-11-25 Joerg Wunsch + + Submitted by David Mosberger-Tang: + patch #9328: ft245r.c: add TPI support (patches 5-7) + * ft245r.c (ft245r_set_bitclock): add workaround for + FT245 hardware bugs in bitclock setting + 2021-11-25 Joerg Wunsch Submitted by David Mosberger-Tang: diff --git a/NEWS b/NEWS index 426438b6..21021303 100644 --- a/NEWS +++ b/NEWS @@ -14,10 +14,12 @@ Current: debuggers (JTAGICE3 with firmware 3+, AtmelICE, EDBG, mEDBG) - UPDI support added (AVR8X family) - TPI support for USBtinyISP + - TPI support for ft245r - AVR Doper uses libhidapi rather than raw libusb (patch #9033) - -P net:host:port can use IPv6 now (Posix systems only) - New configure option: -disable-libusb_1_0 - extended UPDI device context (> 64 Ki flash) + - major overhaul of ft245r driver (patch #9327/#9328) * New devices supported: @@ -108,11 +110,13 @@ Current: patch #9110: Let reserved fuse bits to be read as *don't care* patch #9253: Fix for giving terminal_mode commands more than 20 arguments patch #9320: fix TPI RESET in bitbang.c - patch #9079: Fix ftdi_syncbb teardown (supersedes #9893) + patch #9079: Fix ftdi_syncbb teardown (supersedes #9893, superseded by #9328) patch #9122: Fixed MISO sampling in ftdi_syncbb patch #9123: ftdi_syncbb: use FT245R_CYCLES in ft245r_set_bitclock() patch #8719: Support Over-the-Air bootloading with XBeeBoot patch #9757: Fix ATtiny817 Xplained Mini programmer + patch #9327: ft245r.c: add TPI support (patches 1-4) + patch #9328: ft245r.c: add TPI support (patches 5-7) * Internals: - New avrdude.conf keyword "family_id", used to verify SIB attributes diff --git a/ft245r.c b/ft245r.c index 4c4ffa60..9c717324 100644 --- a/ft245r.c +++ b/ft245r.c @@ -59,6 +59,7 @@ #include #include #include +#include #include "avrdude.h" #include "libavrdude.h" @@ -113,9 +114,26 @@ void ft245r_initpgm(PROGRAMMER * pgm) { //#define USE_INLINE_WRITE_PAGE #define FT245R_DEBUG 0 +/* + Some revisions of the FTDI chips mess up the timing in bitbang mode + unless the bitclock is set to the max (3MHz). For example, see: + + http://www.ftdichip.com/Support/Documents/TechnicalNotes/TN_120_FT232R%20Errata%20Technical%20Note.pdf + + To work around this problem, set the macro below to 1 to always set + the bitclock to 3MHz and then issue the same byte repeatedly to get + the desired timing. + +*/ +#define FT245R_BITBANG_VARIABLE_PULSE_WIDTH_WORKAROUND 1 static struct ftdi_context *handle; +#if FT245R_BITBANG_VARIABLE_PULSE_WIDTH_WORKAROUND +static unsigned int baud_multiplier; +#else +# define baud_multiplier 1 // this let's C compiler optimize +#endif static unsigned char ft245r_ddr; static unsigned char ft245r_out; @@ -213,14 +231,16 @@ static int ft245r_flush(PROGRAMMER * pgm) { static int ft245r_send2(PROGRAMMER * pgm, unsigned char * buf, size_t len, bool discard_rx_data) { - int i; + int i, j; for (i = 0; i < len; ++i) { - if (discard_rx_data) - ++rx.discard; - tx.buf[tx.len++] = buf[i]; - if (tx.len >= FT245R_MIN_FIFO_SIZE) - ft245r_flush(pgm); + for (j = 0; j < baud_multiplier; ++j) { + if (discard_rx_data) + ++rx.discard; + tx.buf[tx.len++] = buf[i]; + if (tx.len >= FT245R_MIN_FIFO_SIZE) + ft245r_flush(pgm); + } } return 0; } @@ -235,7 +255,7 @@ static int ft245r_send_and_discard(PROGRAMMER * pgm, unsigned char * buf, } static int ft245r_recv(PROGRAMMER * pgm, unsigned char * buf, size_t len) { - int i; + int i, j; ft245r_flush(pgm); ft245r_fill(pgm); @@ -249,8 +269,11 @@ static int ft245r_recv(PROGRAMMER * pgm, unsigned char * buf, size_t len) { --rx.discard; } - for (i = 0; i < len; ++i) + for (i = 0; i < len; ++i) { buf[i] = ft245r_rx_buf_get(pgm); + for (j = 1; j < baud_multiplier; ++j) + ft245r_rx_buf_get(pgm); + } return 0; } @@ -298,23 +321,32 @@ static int ft245r_chip_erase(PROGRAMMER * pgm, AVRPART * p) { static int ft245r_set_bitclock(PROGRAMMER * pgm) { - int r; - int rate = 0; + // libftdi1 multiplies bitbang baudrate by 4: + int r, rate = 0, ftdi_rate = 3000000 / 4; /* bitclock is second. 1us = 0.000001. Max rate for ft232r 750000 */ if(pgm->bitclock) { - rate = (uint32_t)(1.0/pgm->bitclock) * FT245R_CYCLES; + rate = (uint32_t)(1.0/pgm->bitclock); } else if (pgm->baudrate) { - rate = pgm->baudrate * FT245R_CYCLES; + rate = pgm->baudrate; } else { rate = 150000; /* should work for all ftdi chips and the avr default internal clock of 1MHz */ } - if (FT245R_DEBUG) { - avrdude_message(MSG_NOTICE2, " ft245r: spi bitclk %d -> ft baudrate %d\n", - rate / FT245R_CYCLES, rate); - } - r = ftdi_set_baudrate(handle, rate); +#if FT245R_BITBANG_VARIABLE_PULSE_WIDTH_WORKAROUND + if (rate > 0 && rate < ftdi_rate) + baud_multiplier = round((ftdi_rate + rate - 1) / rate); + else + baud_multiplier = 1; +#else + ftdi_rate = rate; +#endif + + avrdude_message(MSG_NOTICE2, + "%s: bitclk %d -> FTDI rate %d, baud multiplier %d\n", + __func__, rate, ftdi_rate, baud_multiplier); + + r = ftdi_set_baudrate(handle, ftdi_rate); if (r) { avrdude_message(MSG_INFO, "Set baudrate (%d) failed with error '%s'.\n", rate, ftdi_get_error_string (handle));