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ć <[email protected]>
Tested-by: Samir Ibradžić <[email protected]>
---
$ svn diff
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");
--

R,
S

_______________________________________________
flashrom mailing list
[email protected]
http://www.flashrom.org/mailman/listinfo/flashrom

Reply via email to