Patchwork FT2232 programmer frequency divider parameter support

login
register
about
Submitter Samir Ibradžić
Date 2011-10-23 07:54:47
Message ID <4EA3C847.5010501@gmail.com>
Download mbox | patch
Permalink /patch/3441/
State Superseded
Headers show

Comments

Samir Ibradžić - 2011-10-23 07:54:47
On 2011年10月17日 04:04, Samir Ibradžić wrote:
> Hello,
>
> I would like to submit a patch, that enables extra argument when using
> FT2232 external programmer, a frequency divider. For FT2232 programmer
> we have this divider set to 3 by default by DIVIDE_BY constant, which
> will result in 10MHz (H-chips) or 2MHz (non H-chips) SPI speeds.
>
> By providing divider as parameter, SPI interface frequency culd be
> overridden by user, resulting in different speeds (H-chip example):
>
> divider | freq
> ---------+--------
> 1 | 30Mhz
> 2 | 15Mhz
> 3 | 10Mhz
> 4 | 7.5Mhz
> 5 | 6Mhz
> 6 | 5Mhz
> 15 | 2Mhz
> 30 | 1Mhz
> 60 | 0.5Mhz
> 600 | 0.05Mhz
> (and so on)
>
> These lower than default SPI speeds can be very useful when we have
> flawed flash chips that would not support 10Mhz or bad quality or too
> long cabling between programmer and the chip. Higher than default speeds
> might also be useful (if only flashrom AAI implementation was faster).
>
> Please note that this parameter is arbitrary integer, maybe only a value
> up to 255 would really make sense, but i can not be sure about that
> since it may be programmer hardware dependent. All values between 1-255
> worked for me (PicoTAP programmer), as well as 300 & 600 (these resulted
> in extremely slow flash reads, as expected, 2MB flash that usually takes
> 16s to read @2-10Mhz, took more than 6 minutes @0.05Mhz). Others values
> i haven't tested.

After re-reading some FT2232 data sheets, it looks like the valid value 
for divider is any integer between 1 and 65535. Tested a lot of values 
in here (including 65535), and i can confirm that at least PicoTAP 
supports this parameter correctly, no reason other FT2232 devices 
wouldn't work too. I also added some simple divider parameter 
validation. Re-submitting this patch.

Signed-off-by: Samir Ibradžić <sibradzic@gmail.com>
Tested-by: Samir Ibradžić <sibradzic@gmail.com>
---
$ svn diff
--

R,
S

Patch

Index: ft2232_spi.c
===================================================================
--- ft2232_spi.c	(revision 1457)
+++ ft2232_spi.c	(working copy)
@@ -168,6 +168,7 @@ 
  	enum ftdi_interface ft2232_interface = INTERFACE_B;
  	char *arg;
  	double mpsse_clk;
+	uint16_t divider = DIVIDE_BY;

  	arg = extract_programmer_param("type");
  	if (arg) {
@@ -237,6 +238,20 @@ 
  		}
  	}
  	free(arg);
+	arg = extract_programmer_param("divider");
+	if (arg && strlen(arg)) {
+		unsigned int temp = 0;
+		char *trailing_char;
+		temp = strtoul(arg, &trailing_char, 10);
+		if (*trailing_char || !temp || temp > 65535) {
+			msg_perr("Error: Invalid frequency divider specified.\n");
+			free(arg);
+			return -2;
+		} else {
+			divider = (uint16_t)temp;
+		}
+	}
+	free(arg);
  	msg_pdbg("Using device type %s %s ",
  		 get_ft2232_vendorname(ft2232_vid, ft2232_type),
  		 get_ft2232_devicename(ft2232_vid, ft2232_type));
@@ -298,16 +313,16 @@ 
  	msg_pdbg("Set clock divisor\n");
  	buf[0] = 0x86;		/* command "set divisor" */
  	/* valueL/valueH are (desired_divisor - 1) */
-	buf[1] = (DIVIDE_BY - 1) & 0xff;
-	buf[2] = ((DIVIDE_BY - 1) >> 8) & 0xff;
+	buf[1] = (divider - 1) & 0xff;
+	buf[2] = ((divider - 1) >> 8) & 0xff;
  	if (send_buf(ftdic, buf, 3)) {
  		ret = -6;
  		goto ftdi_err;
  	}

  	msg_pdbg("MPSSE clock: %f MHz divisor: %d "
-		 "SPI clock: %f MHz\n", mpsse_clk, DIVIDE_BY,
-		 (double)(mpsse_clk / (((DIVIDE_BY - 1) + 1) * 2)));
+		 "SPI clock: %f MHz\n", mpsse_clk, divider,
+		 (double)(mpsse_clk / (((divider - 1) + 1) * 2)));

  	/* Disconnect TDI/DO to TDO/DI for loopback. */
  	msg_pdbg("No loopback of TDI/DO TDO/DI\n");