[flashrom] [commit] r1571 - in trunk: . Documentation

repository service svn at flashrom.org
Mon Aug 13 18:33:04 CEST 2012


Author: stefanct
Date: Mon Aug 13 18:33:04 2012
New Revision: 1571
URL: http://flashrom.org/trac/flashrom/changeset/1571

Log:
serprog: Add support for setting the SPI frequency.

Introduce a new opcode (0x14) that sends the requested frequency as a 32b
long value in Hertz to the programmer and receives the frequency eventually
chosen by the programmer. The user can specify this with the programmer
parameter "spispeed" (named after the similar parameter for the buspirate)
including an optional suffix of 'M' or 'k' for specifying megahertz or kilohertz
respectively (lowercase suffixes are also accepted).

Thanks to Idwer and Uwe (and maybe others) for their feedback especially
regarding the unit of frequency to use.

Signed-off-by: Stefan Tauner <stefan.tauner at student.tuwien.ac.at>
Acked-by: Stefan Tauner <stefan.tauner at student.tuwien.ac.at>

Modified:
   trunk/Documentation/serprog-protocol.txt
   trunk/flashrom.8
   trunk/serprog.c

Modified: trunk/Documentation/serprog-protocol.txt
==============================================================================
--- trunk/Documentation/serprog-protocol.txt	Mon Aug 13 10:45:13 2012	(r1570)
+++ trunk/Documentation/serprog-protocol.txt	Mon Aug 13 18:33:04 2012	(r1571)
@@ -33,6 +33,7 @@
 0x12	Set used bustype		8-bit flags (as with 0x05)	ACK / NAK
 0x13	Perform SPI operation		24-bit slen + 24-bit rlen	ACK + rlen bytes of data / NAK
 					 + slen bytes of data
+0x14	Set SPI clock frequency in Hz	32-bit requested frequency	ACK + 32-bit set frequency / NAK
 0x??	unimplemented command - invalid.
 
 
@@ -73,6 +74,14 @@
 		Maximum slen is Q_WRNMAXLEN in case Q_BUSTYPE returns SPI only or S_BUSTYPE was used
 		to set SPI exclusively before. Same for rlen and Q_RDNMAXLEN.
 		This operation is immediate, meaning it doesnt use the operation buffer.
+	0x14 (S_SPI_FREQ):
+		Set the SPI clock frequency. The 32-bit value indicates the
+		requested frequency in Hertz. Value 0 is reserved and should
+		be NAKed by the programmer. The requested frequency should be
+		mapped by the programmer software to a supported frequency
+		lower than the one requested. If there is no lower frequency
+		available the lowest possible should be used. The value
+		chosen is sent back in the reply with an ACK.
 	About mandatory commands:
 		The only truly mandatory commands for any device are 0x00, 0x01, 0x02 and 0x10,
 		but one can't really do anything with these commands.
@@ -107,3 +116,4 @@
 #define S_CMD_Q_RDNMAXLEN	0x11		/* Query read-n maximum length			*/
 #define S_CMD_S_BUSTYPE		0x12		/* Set used bustype(s).				*/
 #define S_CMD_O_SPIOP		0x13		/* Perform SPI operation.			*/
+#define S_CMD_S_SPI_FREQ	0x14		/* Set SPI clock frequency */

Modified: trunk/flashrom.8
==============================================================================
--- trunk/flashrom.8	Mon Aug 13 10:45:13 2012	(r1570)
+++ trunk/flashrom.8	Mon Aug 13 18:33:04 2012	(r1571)
@@ -598,7 +598,17 @@
 .sp
 .B "  flashrom \-p serprog:ip=ipaddr:port"
 .sp
-instead. More information about serprog is available in
+instead. In case the device supports it, you can set the SPI clock frequency
+with the optional
+.B spispeed
+parameter. The frequency is parsed as Hertz, unless an
+.BR M ", or " k
+suffix is given, then megahertz or kilohertz are used respectively.
+Example that sets the frequency to 2 MHz:
+.sp
+.B "flashrom \-p serprog:dev=/dev/device:baud,spispeed=2M"
+.sp
+More information about serprog is available in
 .B serprog-protocol.txt
 in the source distribution.
 .SS

Modified: trunk/serprog.c
==============================================================================
--- trunk/serprog.c	Mon Aug 13 10:45:13 2012	(r1570)
+++ trunk/serprog.c	Mon Aug 13 18:33:04 2012	(r1571)
@@ -69,6 +69,7 @@
 #define S_CMD_Q_RDNMAXLEN	0x11	/* Query read-n maximum length			*/
 #define S_CMD_S_BUSTYPE		0x12	/* Set used bustype(s).				*/
 #define S_CMD_O_SPIOP		0x13	/* Perform SPI operation.			*/
+#define S_CMD_S_SPI_FREQ	0x14	/* Set SPI clock frequency			*/
 
 static uint16_t sp_device_serbuf_size = 16;
 static uint16_t sp_device_opbuf_size = 300;
@@ -482,6 +483,7 @@
 	/* Check for the minimum operational set of commands. */
 	if (serprog_buses_supported & BUS_SPI) {
 		uint8_t bt = BUS_SPI;
+		char *spispeed;
 		if (sp_check_commandavail(S_CMD_O_SPIOP) == 0) {
 			msg_perr("Error: SPI operation not supported while the "
 				 "bustype is SPI\n");
@@ -513,6 +515,51 @@
 			spi_programmer_serprog.max_data_read = v;
 			msg_pdbg(MSGHEADER "Maximum read-n length is %d\n", v);
 		}
+		spispeed = extract_programmer_param("spispeed");
+		if (spispeed && strlen(spispeed)) {
+			uint32_t f_spi_req, f_spi;
+			uint8_t buf[4];
+			char *f_spi_suffix;
+
+			errno = 0;
+			f_spi_req = strtol(spispeed, &f_spi_suffix, 0);
+			if (errno != 0 || spispeed == f_spi_suffix) {
+				msg_perr("Error: Could not convert 'spispeed'.\n");
+				return 1;
+			}
+			if (strlen(f_spi_suffix) == 1) {
+				if (!strcasecmp(f_spi_suffix, "M"))
+					f_spi_req *= 1000000;
+				else if (!strcasecmp(f_spi_suffix, "k"))
+					f_spi_req *= 1000;
+				else {
+					msg_perr("Error: Garbage following 'spispeed' value.\n");
+					return 1;
+				}
+			} else if (strlen(f_spi_suffix) > 1) {
+				msg_perr("Error: Garbage following 'spispeed' value.\n");
+				return 1;
+			}
+
+			buf[0] = (f_spi_req >> (0 * 8)) & 0xFF;
+			buf[1] = (f_spi_req >> (1 * 8)) & 0xFF;
+			buf[2] = (f_spi_req >> (2 * 8)) & 0xFF;
+			buf[3] = (f_spi_req >> (3 * 8)) & 0xFF;
+
+			if (sp_check_commandavail(S_CMD_S_SPI_FREQ) == 0)
+				msg_perr(MSGHEADER "Warning: Setting the SPI clock rate is not supported!\n");
+			else if (sp_docommand(S_CMD_S_SPI_FREQ, 4, buf, 4, buf)
+				 == 0) {
+				f_spi = buf[0];
+				f_spi |= buf[1] << (1 * 8);
+				f_spi |= buf[2] << (2 * 8);
+				f_spi |= buf[3] << (3 * 8);
+				msg_pdbg(MSGHEADER "Requested to set SPI clock frequency to %u Hz. "
+					 "It was actually set to %u Hz\n", f_spi_req, f_spi);
+			} else
+				msg_pdbg(MSGHEADER "Setting SPI clock rate to %u Hz failed!\n", f_spi_req);
+		}
+		free(spispeed);
 		bt = serprog_buses_supported;
 		if (sp_docommand(S_CMD_S_BUSTYPE, 1, &bt, 0, NULL))
 			return 1;




More information about the flashrom mailing list