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
This commit is contained in:
parent
2015a874e0
commit
49e5f2451c
|
@ -1,3 +1,10 @@
|
||||||
|
2021-11-25 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||||
|
|
||||||
|
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 <j.gnu@uriah.heep.sax.de>
|
2021-11-25 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||||
|
|
||||||
Submitted by David Mosberger-Tang:
|
Submitted by David Mosberger-Tang:
|
||||||
|
|
6
NEWS
6
NEWS
|
@ -14,10 +14,12 @@ Current:
|
||||||
debuggers (JTAGICE3 with firmware 3+, AtmelICE, EDBG, mEDBG)
|
debuggers (JTAGICE3 with firmware 3+, AtmelICE, EDBG, mEDBG)
|
||||||
- UPDI support added (AVR8X family)
|
- UPDI support added (AVR8X family)
|
||||||
- TPI support for USBtinyISP
|
- TPI support for USBtinyISP
|
||||||
|
- TPI support for ft245r
|
||||||
- AVR Doper uses libhidapi rather than raw libusb (patch #9033)
|
- AVR Doper uses libhidapi rather than raw libusb (patch #9033)
|
||||||
- -P net:host:port can use IPv6 now (Posix systems only)
|
- -P net:host:port can use IPv6 now (Posix systems only)
|
||||||
- New configure option: -disable-libusb_1_0
|
- New configure option: -disable-libusb_1_0
|
||||||
- extended UPDI device context (> 64 Ki flash)
|
- extended UPDI device context (> 64 Ki flash)
|
||||||
|
- major overhaul of ft245r driver (patch #9327/#9328)
|
||||||
|
|
||||||
* New devices supported:
|
* New devices supported:
|
||||||
|
|
||||||
|
@ -108,11 +110,13 @@ Current:
|
||||||
patch #9110: Let reserved fuse bits to be read as *don't care*
|
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 #9253: Fix for giving terminal_mode commands more than 20 arguments
|
||||||
patch #9320: fix TPI RESET in bitbang.c
|
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 #9122: Fixed MISO sampling in ftdi_syncbb
|
||||||
patch #9123: ftdi_syncbb: use FT245R_CYCLES in ft245r_set_bitclock()
|
patch #9123: ftdi_syncbb: use FT245R_CYCLES in ft245r_set_bitclock()
|
||||||
patch #8719: Support Over-the-Air bootloading with XBeeBoot
|
patch #8719: Support Over-the-Air bootloading with XBeeBoot
|
||||||
patch #9757: Fix ATtiny817 Xplained Mini programmer
|
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:
|
* Internals:
|
||||||
- New avrdude.conf keyword "family_id", used to verify SIB attributes
|
- New avrdude.conf keyword "family_id", used to verify SIB attributes
|
||||||
|
|
56
ft245r.c
56
ft245r.c
|
@ -59,6 +59,7 @@
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
#include "avrdude.h"
|
#include "avrdude.h"
|
||||||
#include "libavrdude.h"
|
#include "libavrdude.h"
|
||||||
|
@ -113,9 +114,26 @@ void ft245r_initpgm(PROGRAMMER * pgm) {
|
||||||
//#define USE_INLINE_WRITE_PAGE
|
//#define USE_INLINE_WRITE_PAGE
|
||||||
|
|
||||||
#define FT245R_DEBUG 0
|
#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;
|
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_ddr;
|
||||||
static unsigned char ft245r_out;
|
static unsigned char ft245r_out;
|
||||||
|
|
||||||
|
@ -213,15 +231,17 @@ static int ft245r_flush(PROGRAMMER * pgm) {
|
||||||
|
|
||||||
static int ft245r_send2(PROGRAMMER * pgm, unsigned char * buf, size_t len,
|
static int ft245r_send2(PROGRAMMER * pgm, unsigned char * buf, size_t len,
|
||||||
bool discard_rx_data) {
|
bool discard_rx_data) {
|
||||||
int i;
|
int i, j;
|
||||||
|
|
||||||
for (i = 0; i < len; ++i) {
|
for (i = 0; i < len; ++i) {
|
||||||
|
for (j = 0; j < baud_multiplier; ++j) {
|
||||||
if (discard_rx_data)
|
if (discard_rx_data)
|
||||||
++rx.discard;
|
++rx.discard;
|
||||||
tx.buf[tx.len++] = buf[i];
|
tx.buf[tx.len++] = buf[i];
|
||||||
if (tx.len >= FT245R_MIN_FIFO_SIZE)
|
if (tx.len >= FT245R_MIN_FIFO_SIZE)
|
||||||
ft245r_flush(pgm);
|
ft245r_flush(pgm);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return 0;
|
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) {
|
static int ft245r_recv(PROGRAMMER * pgm, unsigned char * buf, size_t len) {
|
||||||
int i;
|
int i, j;
|
||||||
|
|
||||||
ft245r_flush(pgm);
|
ft245r_flush(pgm);
|
||||||
ft245r_fill(pgm);
|
ft245r_fill(pgm);
|
||||||
|
@ -249,8 +269,11 @@ static int ft245r_recv(PROGRAMMER * pgm, unsigned char * buf, size_t len) {
|
||||||
--rx.discard;
|
--rx.discard;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < len; ++i)
|
for (i = 0; i < len; ++i) {
|
||||||
buf[i] = ft245r_rx_buf_get(pgm);
|
buf[i] = ft245r_rx_buf_get(pgm);
|
||||||
|
for (j = 1; j < baud_multiplier; ++j)
|
||||||
|
ft245r_rx_buf_get(pgm);
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -298,23 +321,32 @@ static int ft245r_chip_erase(PROGRAMMER * pgm, AVRPART * p) {
|
||||||
|
|
||||||
|
|
||||||
static int ft245r_set_bitclock(PROGRAMMER * pgm) {
|
static int ft245r_set_bitclock(PROGRAMMER * pgm) {
|
||||||
int r;
|
// libftdi1 multiplies bitbang baudrate by 4:
|
||||||
int rate = 0;
|
int r, rate = 0, ftdi_rate = 3000000 / 4;
|
||||||
|
|
||||||
/* bitclock is second. 1us = 0.000001. Max rate for ft232r 750000 */
|
/* bitclock is second. 1us = 0.000001. Max rate for ft232r 750000 */
|
||||||
if(pgm->bitclock) {
|
if(pgm->bitclock) {
|
||||||
rate = (uint32_t)(1.0/pgm->bitclock) * FT245R_CYCLES;
|
rate = (uint32_t)(1.0/pgm->bitclock);
|
||||||
} else if (pgm->baudrate) {
|
} else if (pgm->baudrate) {
|
||||||
rate = pgm->baudrate * FT245R_CYCLES;
|
rate = pgm->baudrate;
|
||||||
} else {
|
} else {
|
||||||
rate = 150000; /* should work for all ftdi chips and the avr default internal clock of 1MHz */
|
rate = 150000; /* should work for all ftdi chips and the avr default internal clock of 1MHz */
|
||||||
}
|
}
|
||||||
|
|
||||||
if (FT245R_DEBUG) {
|
#if FT245R_BITBANG_VARIABLE_PULSE_WIDTH_WORKAROUND
|
||||||
avrdude_message(MSG_NOTICE2, " ft245r: spi bitclk %d -> ft baudrate %d\n",
|
if (rate > 0 && rate < ftdi_rate)
|
||||||
rate / FT245R_CYCLES, rate);
|
baud_multiplier = round((ftdi_rate + rate - 1) / rate);
|
||||||
}
|
else
|
||||||
r = ftdi_set_baudrate(handle, rate);
|
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) {
|
if (r) {
|
||||||
avrdude_message(MSG_INFO, "Set baudrate (%d) failed with error '%s'.\n",
|
avrdude_message(MSG_INFO, "Set baudrate (%d) failed with error '%s'.\n",
|
||||||
rate, ftdi_get_error_string (handle));
|
rate, ftdi_get_error_string (handle));
|
||||||
|
|
Loading…
Reference in New Issue