Author: stefanct
Date: Wed May 16 00:58:19 2012
New Revision: 1537
URL: http://flashrom.org/trac/flashrom/changeset/1537

Log:
ft2232_spi.c: add frequency divisor parameter.

This adds an optional argument when using the ft2232_spi programmer to set
the frequency divisor. The valid values for the divisor is any even integer
between 2 and 131072.

Signed-off-by: Samir Ibradžić <[email protected]>
Signed-off-by: Stefan Tauner <[email protected]>
Acked-by: Stefan Tauner <[email protected]>

Modified:
   trunk/flashrom.8
   trunk/ft2232_spi.c

Modified: trunk/flashrom.8
==============================================================================
--- trunk/flashrom.8    Tue May 15 00:54:58 2012        (r1536)
+++ trunk/flashrom.8    Wed May 16 00:58:19 2012        (r1537)
@@ -549,6 +549,17 @@
 .B 4232H
 and the default interface is
 .BR B .
+.sp
+All models supported by the ft2232_spi driver can configure the SPI clock rate 
by setting a divisor. The
+expressible divisors are all even numbers between 2 and 2^17 (=131072) 
resulting in SPI clock frequencies of
+6 MHz down to about 92 Hz for 12 MHz inputs. The default divisor is set to 2, 
but you can use another one by
+specifying the optional
+.B divisor
+parameter with the
+.sp
+.B "  flashrom \-p ft2232_spi:divisor=div"
+.sp
+syntax.
 .SS
 .BR "serprog " programmer
 A mandatory parameter specifies either a serial

Modified: trunk/ft2232_spi.c
==============================================================================
--- trunk/ft2232_spi.c  Tue May 15 00:54:58 2012        (r1536)
+++ trunk/ft2232_spi.c  Wed May 16 00:58:19 2012        (r1537)
@@ -64,17 +64,8 @@
        {},
 };
 
-/*
- * The 'H' chips can run internally at either 12MHz or 60MHz.
- * The non-H chips can only run at 12MHz.
- */
-static uint8_t clock_5x = 1;
 
-/*
- * In either case, the divisor is a simple integer clock divider.
- * If clock_5x is set, this divisor divides 30MHz, else it divides 6MHz.
- */
-#define DIVIDE_BY 3  /* e.g. '3' will give either 10MHz or 2MHz SPI clock. */
+#define DEFAULT_DIVISOR 2
 
 #define BITMODE_BITBANG_NORMAL 1
 #define BITMODE_BITBANG_SPI    2
@@ -162,12 +153,28 @@
 /* Returns 0 upon success, a negative number upon errors. */
 int ft2232_spi_init(void)
 {
-       int f, ret = 0;
+       int ret = 0;
        struct ftdi_context *ftdic = &ftdic_context;
        unsigned char buf[512];
        int ft2232_vid = FTDI_VID;
        int ft2232_type = FTDI_FT4232H_PID;
        enum ftdi_interface ft2232_interface = INTERFACE_B;
+       /*
+        * The 'H' chips can run with an internal clock of either 12 MHz or 60 
MHz,
+        * but the non-H chips can only run at 12 MHz. We enable the divide-by-5
+        * prescaler on the former to run on the same speed.
+        */
+       uint8_t clock_5x = 1;
+       /* In addition to the prescaler mentioned above there is also another
+        * configurable one on all versions of the chips. Its divisor div can be
+        * set by a 16 bit value x according to the following formula:
+        * div = (1 + x) * 2 <-> x = div / 2 - 1
+        * Hence the expressible divisors are all even numbers between 2 and
+        * 2^17 (=131072) resulting in SCK frequencies of 6 MHz down to about
+        * 92 Hz for 12 MHz inputs.
+        */
+       uint32_t divisor = DEFAULT_DIVISOR;
+       int f;
        char *arg;
        double mpsse_clk;
 
@@ -243,6 +250,21 @@
                }
        }
        free(arg);
+       arg = extract_programmer_param("divisor");
+       if (arg && strlen(arg)) {
+               unsigned int temp = 0;
+               char *endptr;
+               temp = strtoul(arg, &endptr, 10);
+               if (*endptr || temp < 2 || temp > 131072 || temp & 0x1) {
+                       msg_perr("Error: Invalid SPI frequency divisor 
specified: \"%s\".\n"
+                                "Valid are even values between 2 and 
131072.\n", arg);
+                       free(arg);
+                       return -2;
+               } else {
+                       divisor = (uint32_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));
@@ -303,17 +325,15 @@
 
        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;
        if (send_buf(ftdic, buf, 3)) {
                ret = -6;
                goto ftdi_err;
        }
+       buf[1] = (divisor / 2 - 1) & 0xff;
+       buf[2] = ((divisor / 2 - 1) >> 8) & 0xff;
 
-       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)));
+       msg_pdbg("MPSSE clock: %f MHz, divisor: %u, SPI clock: %f MHz\n",
+                mpsse_clk, divisor, (double)(mpsse_clk / divisor));
 
        /* Disconnect TDI/DO to TDO/DI for loopback. */
        msg_pdbg("No loopback of TDI/DO TDO/DI\n");

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

Reply via email to