Here's a tiny hack that I use to externally flash my X200s with an FT2232H. It delays the SPI command by repeating the CS# assertion command many times.
Signed-off-by: Nico Huber nico.h@gmx.de --- ft2232_spi.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-)
diff --git a/ft2232_spi.c b/ft2232_spi.c index 08742ec..a85925c 100644 --- a/ft2232_spi.c +++ b/ft2232_spi.c @@ -419,15 +419,16 @@ static int ft2232_spi_send_command(struct flashctx *flash, struct ftdi_context *ftdic = &ftdic_context; static unsigned char *buf = NULL; /* failed is special. We use bitwise ops, but it is essentially bool. */ - int i = 0, ret = 0, failed = 0; + int i = 0, j, ret = 0, failed = 0; int bufsize; static int oldbufsize = 0; + const int extra_assert_time = 288;
if (writecnt > 65536 || readcnt > 65536) return SPI_INVALID_LENGTH;
/* buf is not used for the response from the chip. */ - bufsize = max(writecnt + 9, 260 + 9); + bufsize = max(writecnt, 260) + 9 + extra_assert_time * 3; /* Never shrink. realloc() calls are expensive. */ if (bufsize > oldbufsize) { buf = realloc(buf, bufsize); @@ -446,9 +447,11 @@ static int ft2232_spi_send_command(struct flashctx *flash, * operations. */ msg_pspew("Assert CS#\n"); - buf[i++] = SET_BITS_LOW; - buf[i++] = 0 & ~cs_bits; /* assertive */ - buf[i++] = pindir; + for (j = 0; j <= extra_assert_time; ++j) { + buf[i++] = SET_BITS_LOW; + buf[i++] = 0 & ~cs_bits; /* assertive */ + buf[i++] = pindir; + }
if (writecnt) { buf[i++] = MPSSE_DO_WRITE | MPSSE_WRITE_NEG;