Patchwork Bus Pirate UART speedup

login
register
about
Submitter Carl-Daniel Hailfinger
Date 2012-11-02 00:54:03
Message ID <509319AB.3080804@gmx.net>
Download mbox | patch
Permalink /patch/3783/
State Superseded
Headers show

Comments

Carl-Daniel Hailfinger - 2012-11-02 00:54:03
Increase PIC/FT232 UART speed to 2 Mbaud (instead of 115200 baud) in
firmware 5.5 and newer. Given that UART speed is the biggest bottleneck
for Bus Pirate communication (right now 90% of the read time is caused
by slow BP<->host communication), this patch is absolutely needed to get
any decent speed out of the Bus Pirate.

WARNING: This patch may hang flashrom or corrupt data for any non-v3 Bus
Pirate model. I haven't tested such models, and it might work without
problems. Who knows. We would have to find someone with a v2 (or
earlier) Bus Pirate and a firmware version >=v5.5 to test this. For Bus
Pirate model v4 this patch may be completely superfluous. Anyway,
activating fast UART only for some models is probably the way to go. We
already have code to determine the hardware model in the init function,
this just needs to be stored in some variable.

Signed-off-by: Carl-Daniel Hailfinger <c-d.hailfinger.devel.2006@gmx.net>

Patch

Index: flashrom-buspirate_serialspeedup/buspirate_spi.c
===================================================================
--- flashrom-buspirate_serialspeedup/buspirate_spi.c	(revision 1621)
+++ flashrom-buspirate_serialspeedup/buspirate_spi.c	(working copy)
@@ -179,6 +179,7 @@ 
 	/* Reset Bus Pirate (return to user terminal) */
 	bp_commbuf[0] = 0x0f;
 	ret = buspirate_sendrecv(bp_commbuf, 1, 0);
+	sp_serport_changebaud(115200);
 
 out_shutdown:
 	/* Shut down serial port communication */
@@ -354,6 +355,44 @@ 
 		spi_programmer_buspirate.command = buspirate_spi_send_command_v1;
 	}
 
+	/* Increase PIC/FT232 UART speed to 2 Mbaud (instead of 115200 baud) in firmware 5.5 and newer.
+	 * Although this is already possible in firmware 5.2, fast UART in combination with the old SPI
+	 * command set causes hangs for bigger transactions. This is caused by a UART buffer overrun
+	 * in the PIC, and all firmware versions up to (hopefully not including) 6.2 are affected.
+	 */
+	if (BP_FWVERSION(fw_version_major, fw_version_minor) >= BP_FWVERSION(5, 5)) {
+		// FIXME: Do this only for USB-based Bus Pirates... unless you're sure the UART can handle more.
+		int cmdlen;
+		/* Request setting the UART baud rate. */
+		cmdlen = snprintf((char *)bp_commbuf, DEFAULT_BUFSIZE, "b\n");
+		if ((ret = buspirate_sendrecv(bp_commbuf, cmdlen, 0)))
+			return ret;
+		if ((ret = buspirate_wait_for_string(bp_commbuf, ">")))
+			return ret;
+		/* Request setting the UART clock divisor manually. */
+		cmdlen = snprintf((char *)bp_commbuf, DEFAULT_BUFSIZE, "10\n");
+		if ((ret = buspirate_sendrecv(bp_commbuf, cmdlen, 0)))
+			return ret;
+		if ((ret = buspirate_wait_for_string(bp_commbuf, ">")))
+			return ret;
+		/* Set the UART clock divisor. New clock is 4000000/(divisor+1). */
+		cmdlen = snprintf((char *)bp_commbuf, DEFAULT_BUFSIZE, "%i\n", 1);
+		if ((ret = buspirate_sendrecv(bp_commbuf, cmdlen, 0)))
+			return ret;
+		sleep(1);
+		sp_serport_changebaud(2000000);
+		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("Using fast 2 Mbaud for Bus Pirate <-> host communication.\n");
+	} else {
+		msg_pinfo("Bus Pirate firmware 5.4 and older does not support fast Bus Pirate <-> host "
+			  "communication. Limiting UART speed to 115200 Baud.\n");
+		msg_pinfo("It is recommended to upgrade to firmware 6.2 or newer.\n");
+	}
+
 	/* Workaround for broken speed settings in firmware 6.1 and older. */
 	if (BP_FWVERSION(fw_version_major, fw_version_minor) < BP_FWVERSION(6, 2))
 		if (spispeed > 0x4) {
Index: flashrom-buspirate_serialspeedup/serial.c
===================================================================
--- flashrom-buspirate_serialspeedup/serial.c	(revision 1621)
+++ flashrom-buspirate_serialspeedup/serial.c	(working copy)
@@ -104,6 +104,28 @@ 
 };
 #endif
 
+int sp_serport_changebaud(unsigned int baud)
+{
+	struct termios options;
+	int i;
+
+	tcgetattr(sp_fd, &options);
+	for (i = 0;; i++) {
+		if (sp_baudtable[i].baud == 0) {
+			close(sp_fd);
+			msg_perr("Error: cannot configure for baudrate %d\n", baud);
+			exit(1);
+		}
+		if (sp_baudtable[i].baud == baud) {
+			cfsetispeed(&options, sp_baudtable[i].flag);
+			cfsetospeed(&options, sp_baudtable[i].flag);
+			break;
+		}
+	}
+	tcsetattr(sp_fd, TCSANOW, &options);
+	return 0;
+}
+
 fdtype sp_openserport(char *dev, unsigned int baud)
 {
 #ifdef _WIN32
Index: flashrom-buspirate_serialspeedup/programmer.h
===================================================================
--- flashrom-buspirate_serialspeedup/programmer.h	(revision 1621)
+++ flashrom-buspirate_serialspeedup/programmer.h	(working copy)
@@ -644,6 +644,7 @@ 
 
 void sp_flush_incoming(void);
 fdtype sp_openserport(char *dev, unsigned int baud);
+int sp_serport_changebaud(unsigned int baud);
 void __attribute__((noreturn)) sp_die(char *msg);
 extern fdtype sp_fd;
 /* expose serialport_shutdown as it's currently used by buspirate */