Shawn Anastasio has uploaded this change for review.

View Change

buspirate_spi: Add support for variable serial speeds

This patch introduces the ability to set the baud rate for communication
between the host device and the Bus Pirate via the added 'serialspeed'
programmer parameter.

This is done in two parts. Firstly, the requested serial speed is looked up
in a table to determine the appropriate clock divisor and the divisor is sent
to the bus pirate. Then, the system's baud rate for the selected serial port
is set using serial.c's 'serialport_config'. This function's prototype had to
be added to programmer.h.

In testing, using the 2M baud rate was able to significantly decrease
flash times (down from 20+ minutes to less than 2 minutes for an 8MB flash).

Change-Id: I3706f17a94fdf056063f2ad4a5f0a219665cdcbf
Signed-off-by: Shawn Anastasio <shawnanastasio@yahoo.com>
---
M buspirate_spi.c
M programmer.h
2 files changed, 89 insertions(+), 7 deletions(-)

git pull ssh://review.coreboot.org:29418/flashrom refs/changes/57/23057/1
diff --git a/buspirate_spi.c b/buspirate_spi.c
index b6554ac..08a3daf 100644
--- a/buspirate_spi.c
+++ b/buspirate_spi.c
@@ -35,6 +35,12 @@
const int speed;
};

+struct buspirate_serialspeeds {
+ const char *name;
+ const int speed;
+ const int divisor;
+};
+
#ifndef FAKE_COMMUNICATION
static int buspirate_serialport_setup(char *dev)
{
@@ -154,7 +160,20 @@
{"2.6M", 0x5},
{"4M", 0x6},
{"8M", 0x7},
- {NULL, 0x0},
+ {NULL, 0x0}
+};
+
+static const struct buspirate_serialspeeds serialspeeds[] = {
+ {"9600", 9600, 415},
+ {"19200", 19200, 207},
+ {"38400", 38400, 103},
+ {"57600", 57600, 68},
+ /* 115200 is not included because it is the default setting */
+ {"230400", 230400, 16},
+ {"250000", 250000, 15},
+ {"2000000", 2000000, 1},
+ {"2M", 2000000, 1},
+ {NULL, 0, 0}
};

static int buspirate_spi_shutdown(void *data)
@@ -179,6 +198,8 @@
/* Reset Bus Pirate (return to user terminal) */
bp_commbuf[0] = 0x0f;
ret = buspirate_sendrecv(bp_commbuf, 1, 0);
+ if ((ret = serialport_config(sp_fd, 115200)))
+ goto out_shutdown;

out_shutdown:
/* Shut down serial port communication */
@@ -204,9 +225,11 @@
char *tmp;
char *dev;
int i;
+ int cnt;
unsigned int fw_version_major = 0;
unsigned int fw_version_minor = 0;
int spispeed = 0x7;
+ int serialspeed_index = -1;
int ret = 0;
int pullup = 0;

@@ -233,6 +256,20 @@
}
free(tmp);

+ /* Extract serialspeed paramater and ignore requests for the default 115200 baud speed */
+ tmp = extract_programmer_param("serialspeed");
+ if (tmp && strncmp("115200", tmp, 6)) {
+ for (i = 0; serialspeeds[i].name; i++) {
+ if (!strncasecmp(serialspeeds[i].name, tmp, strlen(serialspeeds[i].name))) {
+ serialspeed_index = i;
+ break;
+ }
+ }
+ if (!serialspeeds[i].name)
+ msg_perr("Invalid serial speed %s, using default.\n", tmp);
+ }
+ free(tmp);
+
tmp = extract_programmer_param("pullups");
if (tmp) {
if (strcasecmp("on", tmp) == 0)
@@ -341,7 +378,7 @@

if ((ret = buspirate_wait_for_string(bp_commbuf, "HiZ>")))
return ret;
-
+
/* Tell the user about missing SPI binary mode in firmware 2.3 and older. */
if (BP_FWVERSION(fw_version_major, fw_version_minor) < BP_FWVERSION(2, 4)) {
msg_pinfo("Bus Pirate firmware 2.3 and older does not support binary SPI access.\n");
@@ -351,7 +388,7 @@

/* Use fast SPI mode in firmware 5.5 and newer. */
if (BP_FWVERSION(fw_version_major, fw_version_minor) >= BP_FWVERSION(5, 5)) {
- msg_pdbg("Using SPI command set v2.\n");
+ msg_pdbg("Using SPI command set v2.\n");
/* Sensible default buffer size. */
if (buspirate_commbuf_grow(260 + 5))
return ERROR_OOM;
@@ -378,10 +415,54 @@
msg_pinfo("It is recommended to upgrade to firmware 6.2 or newer.\n");
spispeed = 0x4;
}
-
+
/* This works because speeds numbering starts at 0 and is contiguous. */
msg_pdbg("SPI speed is %sHz\n", spispeeds[spispeed].name);

+ /* Set custom serial speed if specified */
+ if (serialspeed_index != -1) {
+ /* This feature requires firmware 5.5 or newer */
+ if (BP_FWVERSION(fw_version_major, fw_version_minor) < BP_FWVERSION(5, 5)) {
+ msg_perr("Bus Pirate firmware 5.4 and older does not support custom serial speeds."
+ "Using default speed of 115200 baud.\n");
+ } else {
+ /* Enter baud rate configuration mode */
+ cnt = snprintf((char *)bp_commbuf, DEFAULT_BUFSIZE, "b\n");
+ if ((ret = buspirate_sendrecv(bp_commbuf, cnt, 0)))
+ return ret;
+ if ((ret = buspirate_wait_for_string(bp_commbuf, ">")))
+ return ret;
+
+ /* Enter manual clock divisor entry mode */
+ cnt = snprintf((char *)bp_commbuf, DEFAULT_BUFSIZE, "10\n");
+ if ((ret = buspirate_sendrecv(bp_commbuf, cnt, 0)))
+ return ret;
+ if ((ret=buspirate_wait_for_string(bp_commbuf, ">")))
+ return ret;
+
+ /* Set the clock divisor to the value calculated from the user's input */
+ cnt = snprintf((char *)bp_commbuf, DEFAULT_BUFSIZE, "%d\n", serialspeeds[serialspeed_index].divisor);
+ if ((ret = buspirate_sendrecv(bp_commbuf, cnt, 0)))
+ return ret;
+ sleep(1);
+
+ /* Reconfigure the host's serial baud rate to the new value */
+ if ((ret = serialport_config(sp_fd, serialspeeds[serialspeed_index].speed))) {
+ msg_perr("Unable to configure system baud rate to specified value.");
+ return ret;
+ }
+
+ /* Return to the main prompt */
+ bp_commbuf[0] = ' ';
+ if ((ret = buspirate_sendrecv(bp_commbuf, 1, 0)))
+ return ret;
+ if ((ret = buspirate_wait_for_string(bp_commbuf, "HiZ>")))
+ return ret;
+
+ msg_pdbg("Serial speed is %d baud\n", serialspeeds[serialspeed_index].speed);
+ }
+ }
+
/* Enter raw bitbang mode */
for (i = 0; i < 20; i++) {
bp_commbuf[0] = 0x00;
@@ -433,7 +514,7 @@
msg_perr("Protocol error while setting SPI speed!\n");
return 1;
}
-
+
/* Set SPI config: output type, idle, clock edge, sample */
bp_commbuf[0] = 0x80 | 0xa;
ret = buspirate_sendrecv(bp_commbuf, 1, 1);
@@ -533,7 +614,7 @@
bp_commbuf[i++] = (readcnt >> 8) & 0xff;
bp_commbuf[i++] = readcnt & 0xff;
memcpy(bp_commbuf + i, writearr, writecnt);
-
+
ret = buspirate_sendrecv(bp_commbuf, i + writecnt, 1 + readcnt);

if (ret) {
@@ -550,4 +631,4 @@
memcpy(readarr, bp_commbuf + 1, readcnt);

return ret;
-}
+}
\ No newline at end of file
diff --git a/programmer.h b/programmer.h
index b390a53..98d82b4 100644
--- a/programmer.h
+++ b/programmer.h
@@ -753,6 +753,7 @@
void sp_flush_incoming(void);
fdtype sp_openserport(char *dev, int baud);
extern fdtype sp_fd;
+int serialport_config(fdtype fd, int baud);
int serialport_shutdown(void *data);
int serialport_write(const unsigned char *buf, unsigned int writecnt);
int serialport_write_nonblock(const unsigned char *buf, unsigned int writecnt, unsigned int timeout, unsigned int *really_wrote);

To view, visit change 23057. To unsubscribe, or for help writing mail filters, visit settings.

Gerrit-Project: flashrom
Gerrit-Branch: master
Gerrit-MessageType: newchange
Gerrit-Change-Id: I3706f17a94fdf056063f2ad4a5f0a219665cdcbf
Gerrit-Change-Number: 23057
Gerrit-PatchSet: 1
Gerrit-Owner: Shawn Anastasio <shawnanastasio@yahoo.com>