Patch with SPI mode init code.
On Sat, Nov 21, 2009 at 2:50 AM, Sean Nelson audiohacked@gmail.com wrote:
Verbose log of flashrom-buspiratespi.
On Fri, Nov 20, 2009 at 8:53 PM, Carl-Daniel Hailfinger c-d.hailfinger.devel.2006@gmx.net wrote:
Add Bus Pirate SPI support to flashrom.
Untested, should work.
Signed-off-by: Carl-Daniel Hailfinger c-d.hailfinger.devel.2006@gmx.net
Index: flashrom-buspiratespi/flash.h
--- flashrom-buspiratespi/flash.h (Revision 767) +++ flashrom-buspiratespi/flash.h (Arbeitskopie) @@ -104,6 +104,9 @@ #if SERPROG_SUPPORT == 1 PROGRAMMER_SERPROG, #endif +#if BUSPIRATE_SPI_SUPPORT == 1
- PROGRAMMER_BUSPIRATESPI,
+#endif PROGRAMMER_INVALID /* This must always be the last entry. */ };
@@ -484,6 +487,12 @@ int bitbang_spi_read(struct flashchip *flash, uint8_t *buf, int start, int len); int bitbang_spi_write_256(struct flashchip *flash, uint8_t *buf);
+/* buspirate_spi.c */ +int buspirate_spi_init(void); +int buspirate_spi_shutdown(void); +int buspirate_spi_send_command(unsigned int writecnt, unsigned int readcnt, const unsigned char *writearr, unsigned char *readarr); +int buspirate_spi_read(struct flashchip *flash, uint8_t *buf, int start, int len);
/* flashrom.c */ extern char *programmer_param; extern int verbose; @@ -527,6 +536,9 @@ #if DUMMY_SUPPORT == 1 SPI_CONTROLLER_DUMMY, #endif +#if BUSPIRATE_SPI_SUPPORT == 1
- SPI_CONTROLLER_BUSPIRATE,
+#endif SPI_CONTROLLER_INVALID /* This must always be the last entry. */ }; extern const int spi_programmer_count; @@ -736,5 +748,8 @@ uint8_t serprog_chip_readb(const chipaddr addr); void serprog_chip_readn(uint8_t *buf, const chipaddr addr, size_t len); void serprog_delay(int delay); +void sp_flush_incoming(void); +int sp_openserport(char *dev, unsigned int baud); +extern int sp_fd;
#endif /* !__FLASH_H__ */ Index: flashrom-buspiratespi/buspirate_spi.c =================================================================== --- flashrom-buspiratespi/buspirate_spi.c (Revision 0) +++ flashrom-buspiratespi/buspirate_spi.c (Revision 0) @@ -0,0 +1,317 @@ +/*
- This file is part of the flashrom project.
- Copyright (C) 2009 Carl-Daniel Hailfinger
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
+#include <stdio.h> +#include <stdint.h> +#include <string.h> +#include <stdlib.h> +#include <ctype.h> +#include <fcntl.h> +#include "flash.h" +#include "spi.h"
+int buspirate_serialport_setup(char *dev) +{
- /* 115200bps, 8 databits, no parity, 1 stopbit */
- sp_fd = sp_openserport(dev, 115200);
- return 0;
+}
+int buspirate_serialport_shutdown(void) +{
- close(sp_fd);
- return 0;
+}
+int serialport_write(unsigned char *buf, unsigned int writecnt) +{
- int tmp = 0;
- while (tmp != writecnt) {
- tmp = write(sp_fd, buf + tmp, writecnt - tmp);
- if (tmp == -1)
- return 1;
- if (!tmp)
- printf_debug("Empty write\n");
- }
- return 0;
+}
+int serialport_read(unsigned char *buf, unsigned int readcnt) +{
- int tmp = 0;
- while (tmp != readcnt) {
- tmp = read(sp_fd, buf + tmp, readcnt - tmp);
- if (tmp == -1)
- return 1;
- if (!tmp)
- printf_debug("Empty read\n");
- }
- return 0;
+}
+int buspirate_discard_read(void) +{
- int flags;
- printf_debug("%s\n", __func__);
- flags = fcntl(sp_fd, F_GETFL);
- flags |= O_NONBLOCK;
- fcntl(sp_fd, F_SETFL, flags);
- sp_flush_incoming();
- flags &= ~O_NONBLOCK;
- fcntl(sp_fd, F_SETFL, flags);
- return 0;
+}
+#undef FAKE_COMMUNICATION +int buspirate_sendrecv(unsigned char *buf, unsigned int writecnt, unsigned int readcnt) +{
- int i, ret = 0;
- printf_debug("%s: write %i, read %i\n", __func__, writecnt, readcnt);
- if (!writecnt && !readcnt) {
- fprintf(stderr, "Zero length command!\n");
- return 1;
- }
- printf_debug("Sending");
- for (i = 0; i < writecnt; i++)
- printf_debug(" 0x%02x", buf[i]);
+#ifdef FAKE_COMMUNICATION
- /* Placate the caller for now. */
- buf[0] = 0x01;
- memset(buf + 1, 0xff, readcnt - 1);
- ret = 0;
+#else
- if (writecnt)
- ret = serialport_write(buf, writecnt);
- if (ret)
- return ret;
- if (readcnt)
- ret = serialport_read(buf, readcnt);
- if (ret)
- return ret;
+#endif
- printf_debug(", receiving");
- for (i = 0; i < readcnt; i++)
- printf_debug(" 0x%02x", buf[i]);
- printf_debug("\n");
- return 0;
+}
+int buspirate_spi_init(void) +{
- unsigned char buf[512];
- int ret = 0;
- int i;
- char *devpos = NULL;
- char *dev = NULL;
- int devlen;
- if (programmer_param && !strlen(programmer_param)) {
- free(programmer_param);
- programmer_param = NULL;
- }
- if (programmer_param) {
- devpos = strstr(programmer_param, "dev=");
- if (devpos) {
- devpos += 4;
- devlen = strcspn(devpos, ",:");
- if (devlen) {
- dev = malloc(devlen + 1);
- if (!dev) {
- fprintf(stderr, "Out of memory!\n");
- exit(1);
- }
- strncpy(dev, devpos, devlen);
- dev[devlen] = '\0';
- }
- }
- free(programmer_param);
- programmer_param = NULL;
- }
- if (!dev) {
- fprintf(stderr, "No serial device given. Use flashrom -p "
- "buspiratespi:dev=/dev/ttyUSB0\n");
- return 1;
- }
- ret = buspirate_serialport_setup(dev);
- if (ret)
- return ret;
- /* This is the brute force version, but it should work. */
- for (i = 0; i < 19; i++) {
- /* Enter raw bitbang mode */
- buf[0] = 0x00;
- /* Send the command, don't read the response. */
- ret = buspirate_sendrecv(buf, 1, 0);
- if (ret)
- return ret;
- /* Read any response and discard it. */
- ret = buspirate_discard_read();
- if (ret)
- return ret;
- }
- /* Enter raw bitbang mode */
- buf[0] = 0x00;
- ret = buspirate_sendrecv(buf, 1, 5);
- if (ret)
- return ret;
- if (memcmp(buf, "BBIO", 4)) {
- fprintf(stderr, "Entering raw bitbang mode failed!\n");
- return 1;
- }
- printf_debug("Raw bitbang mode version %c\n", buf[4]);
- if (buf[4] != '1') {
- fprintf(stderr, "Can't handle raw bitbang mode version %c!\n",
- buf[4]);
- return 1;
- }
- /* Enter raw SPI mode */
- buf[0] = 0x01;
- ret = buspirate_sendrecv(buf, 1, 4);
- if (memcmp(buf, "SPI", 3)) {
- fprintf(stderr, "Entering raw SPI mode failed!\n");
- return 1;
- }
- printf_debug("Raw SPI mode version %c\n", buf[3]);
- if (buf[3] != '1') {
- fprintf(stderr, "Can't handle raw SPI mode version %c!\n",
- buf[3]);
- return 1;
- }
- /* Initial setup: Enable power, */
- /* De-assert CS# */
- buf[0] = 0x03;
- ret = buspirate_sendrecv(buf, 1, 1);
- if (ret)
- return 1;
- if (buf[0] != 0x01) {
- fprintf(stderr, "Protocol error!\n");
- return 1;
- }
- buses_supported = CHIP_BUSTYPE_SPI;
- spi_controller = SPI_CONTROLLER_BUSPIRATE;
- return 0;
+}
+int buspirate_spi_shutdown(void) +{
- unsigned char buf[5];
- int ret = 0;
- /* Exit raw SPI mode (enter raw bitbang mode) */
- buf[0] = 0x00;
- ret = buspirate_sendrecv(buf, 1, 5);
- if (ret)
- return ret;
- if (memcmp(buf, "BBIO", 4)) {
- fprintf(stderr, "Entering raw bitbang mode failed!\n");
- return 1;
- }
- printf_debug("Raw bitbang mode version %c\n", buf[4]);
- if (buf[4] != '1') {
- fprintf(stderr, "Can't handle raw bitbang mode version %c!\n",
- buf[4]);
- return 1;
- }
- /* Reset Bus Pirate (return to user terminal) */
- buf[0] = 0x0f;
- ret = buspirate_sendrecv(buf, 1, 0);
- if (ret)
- return ret;
- /* Shut down serial port communication */
- ret = buspirate_serialport_shutdown();
- if (ret)
- return ret;
- printf_debug("Bus Pirate shutdown completed.\n");
- return 0;
+}
+int buspirate_spi_send_command(unsigned int writecnt, unsigned int readcnt,
- const unsigned char *writearr, unsigned char *readarr)
+{
- static unsigned char *buf = NULL;
- int i = 0, ret = 0;
- if (writecnt > 16 || readcnt > 16 || (readcnt + writecnt) > 16)
- return SPI_INVALID_LENGTH;
- /* +2 is pretty arbitrary. */
- buf = realloc(buf, writecnt + readcnt + 2);
- if (!buf) {
- fprintf(stderr, "Out of memory!\n");
- exit(1); // -1
- }
- /* Assert CS# */
- buf[i++] = 0x02;
- ret = buspirate_sendrecv(buf, 1, 1);
- if (ret)
- return SPI_GENERIC_ERROR;
- if (buf[0] != 0x01) {
- fprintf(stderr, "Protocol error!\n");
- return SPI_GENERIC_ERROR;
- }
- i = 0;
- buf[i++] = 0x10 | (writecnt + readcnt - 1);
- memcpy(buf + i, writearr, writecnt);
- i += writecnt;
- memset(buf + i, 0, readcnt);
- ret = buspirate_sendrecv(buf, i + readcnt, i + readcnt);
- if (ret)
- return SPI_GENERIC_ERROR;
- if (buf[0] != 0x01) {
- fprintf(stderr, "Protocol error!\n");
- return SPI_GENERIC_ERROR;
- }
- memcpy(readarr, buf + i, readcnt);
- i = 0;
- /* De-assert CS# */
- buf[i++] = 0x03;
- ret = buspirate_sendrecv(buf, 1, 1);
- if (ret)
- return SPI_GENERIC_ERROR;
- if (buf[0] != 0x01) {
- fprintf(stderr, "Protocol error!\n");
- return SPI_GENERIC_ERROR;
- }
- return ret;
+}
+int buspirate_spi_read(struct flashchip *flash, uint8_t *buf, int start, int len) +{
- /* Maximum read length is 12 bytes, use 8 for now. */
- return spi_read_chunked(flash, buf, start, len, 8);
+}
+/* We could do 12-byte writes, but for now we use the generic 1-byte code. */ Index: flashrom-buspiratespi/serprog.c =================================================================== --- flashrom-buspiratespi/serprog.c (Revision 767) +++ flashrom-buspiratespi/serprog.c (Arbeitskopie) @@ -61,7 +61,7 @@ #define S_CMD_Q_RDNMAXLEN 0x11 /* Query read-n maximum length */ #define S_CMD_S_BUSTYPE 0x12 /* Set used bustype(s). */
-static int sp_fd; +int sp_fd;
static uint16_t sp_device_serbuf_size = 16; static uint16_t sp_device_opbuf_size = 300; @@ -185,7 +185,7 @@ {0, 0} /* Terminator */ };
-static int sp_openserport(char *dev, unsigned int baud) +int sp_openserport(char *dev, unsigned int baud) { struct termios options; int fd, i; @@ -208,20 +208,16 @@ break; } }
- options.c_cflag &= ~PARENB;
- options.c_cflag &= ~CSTOPB;
- options.c_cflag &= ~CSIZE;
- options.c_cflag |= CS8;
- options.c_cflag &= ~CRTSCTS;
- options.c_cflag &= ~(PARENB | CSTOPB | CSIZE | CRTSCTS);
- options.c_cflag |= (CS8 | CLOCAL | CREAD);
options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); options.c_iflag &= ~(IXON | IXOFF | IXANY | ICRNL | IGNCR | INLCR); options.c_oflag &= ~OPOST;
- options.c_cflag |= (CLOCAL | CREAD);
tcsetattr(fd, TCSANOW, &options); return fd; }
-static void sp_flush_incoming(void) +void sp_flush_incoming(void) { int i; for (i=0;i<100;i++) { /* In case the device doesnt do EAGAIN, just read 0 */ Index: flashrom-buspiratespi/spi.c =================================================================== --- flashrom-buspiratespi/spi.c (Revision 767) +++ flashrom-buspiratespi/spi.c (Arbeitskopie) @@ -100,6 +100,15 @@ }, #endif
+#if BUSPIRATE_SPI_SUPPORT == 1
- { /* SPI_CONTROLLER_BUSPIRATE */
- .command = buspirate_spi_send_command,
- .multicommand = default_spi_send_multicommand,
- .read = buspirate_spi_read,
- .write_256 = spi_chip_write_1,
- },
+#endif
{}, /* This entry corresponds to SPI_CONTROLLER_INVALID. */ };
Index: flashrom-buspiratespi/Makefile
--- flashrom-buspiratespi/Makefile (Revision 767) +++ flashrom-buspiratespi/Makefile (Arbeitskopie) @@ -89,6 +89,9 @@ # Always enable Dr. Kaiser for now. CONFIG_DRKAISER ?= yes
+# Always enable Bus Pirate SPI for now. +CONFIG_BUSPIRATESPI ?= yes
# Disable wiki printing by default. It is only useful if you have wiki access. CONFIG_PRINT_WIKI ?= no
@@ -138,6 +141,11 @@ OBJS += drkaiser.o endif
+ifeq ($(CONFIG_BUSPIRATESPI), yes) +FEATURE_CFLAGS += -D'BUSPIRATE_SPI_SUPPORT=1' +OBJS += buspirate_spi.o +endif
ifeq ($(CONFIG_PRINT_WIKI), yes) FEATURE_CFLAGS += -D'PRINT_WIKI_SUPPORT=1' OBJS += print_wiki.o Index: flashrom-buspiratespi/spi.h =================================================================== --- flashrom-buspiratespi/spi.h (Revision 767) +++ flashrom-buspiratespi/spi.h (Arbeitskopie) @@ -106,6 +106,7 @@ #define JEDEC_BYTE_PROGRAM_INSIZE 0x00
/* Error codes */ +#define SPI_GENERIC_ERROR -1 #define SPI_INVALID_OPCODE -2 #define SPI_INVALID_ADDRESS -3 #define SPI_INVALID_LENGTH -4 Index: flashrom-buspiratespi/flashrom.c =================================================================== --- flashrom-buspiratespi/flashrom.c (Revision 767) +++ flashrom-buspiratespi/flashrom.c (Arbeitskopie) @@ -204,6 +204,25 @@ }, #endif
+#if BUSPIRATE_SPI_SUPPORT == 1
- {
- .name = "buspiratespi",
- .init = buspirate_spi_init,
- .shutdown = buspirate_spi_shutdown,
- .map_flash_region = fallback_map,
- .unmap_flash_region = fallback_unmap,
- .chip_readb = noop_chip_readb,
- .chip_readw = fallback_chip_readw,
- .chip_readl = fallback_chip_readl,
- .chip_readn = fallback_chip_readn,
- .chip_writeb = noop_chip_writeb,
- .chip_writew = fallback_chip_writew,
- .chip_writel = fallback_chip_writel,
- .chip_writen = fallback_chip_writen,
- .delay = internal_delay,
- },
+#endif
{}, /* This entry corresponds to PROGRAMMER_INVALID. */ };
-- Developer quote of the month: "We are juggling too many chainsaws and flaming arrows and tigers."
Add Bus Pirate SPI support to flashrom.
The code should work on Linux/*BSD/MacOSX and relies on the serial code implementation in serial.c. Support for additional platforms (Windows) will have to be added to serial.c for this to work. For tests without a Bus Pirate (or with non-functional serial code) it is possible to #define FAKE_COMMUNICATION in buspirate_spi.c. Thanks to Sean Nelson for the SPI mode settings code. I tweaked it a bit to make configuration from a commandline easier should anybody want that feature.
Signed-off-by: Carl-Daniel Hailfinger c-d.hailfinger.devel.2006@gmx.net Acked-by: Stefan Reinauer stepan@coresystems.de
Index: flashrom-buspiratespi/flash.h =================================================================== --- flashrom-buspiratespi/flash.h (Revision 771) +++ flashrom-buspiratespi/flash.h (Arbeitskopie) @@ -104,6 +104,9 @@ #if SERPROG_SUPPORT == 1 PROGRAMMER_SERPROG, #endif +#if BUSPIRATE_SPI_SUPPORT == 1 + PROGRAMMER_BUSPIRATESPI, +#endif PROGRAMMER_INVALID /* This must always be the last entry. */ };
@@ -484,6 +487,12 @@ int bitbang_spi_read(struct flashchip *flash, uint8_t *buf, int start, int len); int bitbang_spi_write_256(struct flashchip *flash, uint8_t *buf);
+/* buspirate_spi.c */ +int buspirate_spi_init(void); +int buspirate_spi_shutdown(void); +int buspirate_spi_send_command(unsigned int writecnt, unsigned int readcnt, const unsigned char *writearr, unsigned char *readarr); +int buspirate_spi_read(struct flashchip *flash, uint8_t *buf, int start, int len); + /* flashrom.c */ extern char *programmer_param; extern int verbose; @@ -527,6 +536,9 @@ #if DUMMY_SUPPORT == 1 SPI_CONTROLLER_DUMMY, #endif +#if BUSPIRATE_SPI_SUPPORT == 1 + SPI_CONTROLLER_BUSPIRATE, +#endif SPI_CONTROLLER_INVALID /* This must always be the last entry. */ }; extern const int spi_programmer_count; Index: flashrom-buspiratespi/buspirate_spi.c =================================================================== --- flashrom-buspiratespi/buspirate_spi.c (Revision 0) +++ flashrom-buspiratespi/buspirate_spi.c (Revision 0) @@ -0,0 +1,358 @@ +/* + * This file is part of the flashrom project. + * + * Copyright (C) 2009 Carl-Daniel Hailfinger + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include <stdio.h> +#include <stdint.h> +#include <string.h> +#include <stdlib.h> +#include <ctype.h> +#include <fcntl.h> +#include "flash.h" +#include "spi.h" + +/* Change this to #define if you want to test without a serial implementation */ +#undef FAKE_COMMUNICATION + +#ifndef FAKE_COMMUNICATION +int buspirate_serialport_setup(char *dev) +{ + /* 115200bps, 8 databits, no parity, 1 stopbit */ + sp_fd = sp_openserport(dev, 115200); + return 0; +} + +int buspirate_serialport_shutdown(void) +{ + close(sp_fd); + return 0; +} + +int serialport_write(unsigned char *buf, unsigned int writecnt) +{ + int tmp = 0; + + while (tmp != writecnt) { + tmp = write(sp_fd, buf + tmp, writecnt - tmp); + if (tmp == -1) + return 1; + if (!tmp) + printf_debug("Empty write\n"); + } + + return 0; +} + +int serialport_read(unsigned char *buf, unsigned int readcnt) +{ + int tmp = 0; + + while (tmp != readcnt) { + tmp = read(sp_fd, buf + tmp, readcnt - tmp); + if (tmp == -1) + return 1; + if (!tmp) + printf_debug("Empty read\n"); + } + + return 0; +} + +int buspirate_discard_read(void) +{ + int flags; + + printf_debug("%s\n", __func__); + flags = fcntl(sp_fd, F_GETFL); + flags |= O_NONBLOCK; + fcntl(sp_fd, F_SETFL, flags); + sp_flush_incoming(); + flags &= ~O_NONBLOCK; + fcntl(sp_fd, F_SETFL, flags); + + return 0; +} +#else +#define buspirate_serialport_setup(...) 0 +#define buspirate_serialport_shutdown(...) 0 +#define serialport_write(...) 0 +#define serialport_read(...) 0 +#define buspirate_discard_read(...) 0 +#endif + +int buspirate_sendrecv(unsigned char *buf, unsigned int writecnt, unsigned int readcnt) +{ + int i, ret = 0; + + printf_debug("%s: write %i, read %i\n", __func__, writecnt, readcnt); + if (!writecnt && !readcnt) { + fprintf(stderr, "Zero length command!\n"); + return 1; + } + printf_debug("Sending"); + for (i = 0; i < writecnt; i++) + printf_debug(" 0x%02x", buf[i]); +#ifdef FAKE_COMMUNICATION + /* Placate the caller for now. */ + if (readcnt) { + buf[0] = 0x01; + memset(buf + 1, 0xff, readcnt - 1); + } + ret = 0; +#else + if (writecnt) + ret = serialport_write(buf, writecnt); + if (ret) + return ret; + if (readcnt) + ret = serialport_read(buf, readcnt); + if (ret) + return ret; +#endif + printf_debug(", receiving"); + for (i = 0; i < readcnt; i++) + printf_debug(" 0x%02x", buf[i]); + printf_debug("\n"); + return 0; +} + +int buspirate_spi_init(void) +{ + unsigned char buf[512]; + int ret = 0; + int i; + char *devpos = NULL; + char *dev = NULL; + int devlen; + + if (programmer_param && !strlen(programmer_param)) { + free(programmer_param); + programmer_param = NULL; + } + if (programmer_param) { + devpos = strstr(programmer_param, "dev="); + if (devpos) { + devpos += 4; + devlen = strcspn(devpos, ",:"); + if (devlen) { + dev = malloc(devlen + 1); + if (!dev) { + fprintf(stderr, "Out of memory!\n"); + exit(1); + } + strncpy(dev, devpos, devlen); + dev[devlen] = '\0'; + } + } + free(programmer_param); + programmer_param = NULL; + } + if (!dev) { + fprintf(stderr, "No serial device given. Use flashrom -p " + "buspiratespi:dev=/dev/ttyUSB0\n"); + return 1; + } + + ret = buspirate_serialport_setup(dev); + if (ret) + return ret; + + /* This is the brute force version, but it should work. */ + for (i = 0; i < 19; i++) { + /* Enter raw bitbang mode */ + buf[0] = 0x00; + /* Send the command, don't read the response. */ + ret = buspirate_sendrecv(buf, 1, 0); + if (ret) + return ret; + /* Read any response and discard it. */ + ret = buspirate_discard_read(); + if (ret) + return ret; + } + /* Enter raw bitbang mode */ + buf[0] = 0x00; + ret = buspirate_sendrecv(buf, 1, 5); + if (ret) + return ret; + if (memcmp(buf, "BBIO", 4)) { + fprintf(stderr, "Entering raw bitbang mode failed!\n"); + return 1; + } + printf_debug("Raw bitbang mode version %c\n", buf[4]); + if (buf[4] != '1') { + fprintf(stderr, "Can't handle raw bitbang mode version %c!\n", + buf[4]); + return 1; + } + /* Enter raw SPI mode */ + buf[0] = 0x01; + ret = buspirate_sendrecv(buf, 1, 4); + if (memcmp(buf, "SPI", 3)) { + fprintf(stderr, "Entering raw SPI mode failed!\n"); + return 1; + } + printf_debug("Raw SPI mode version %c\n", buf[3]); + if (buf[3] != '1') { + fprintf(stderr, "Can't handle raw SPI mode version %c!\n", + buf[3]); + return 1; + } + + /* Initial setup (SPI peripherals config): Enable power, CS high, AUX */ + buf[0] = 0x40 | 0xb; + ret = buspirate_sendrecv(buf, 1, 1); + if (ret) + return 1; + if (buf[0] != 0x01) { + fprintf(stderr, "Protocol error while setting power/CS/AUX!\n"); + return 1; + } + + /* Set speed to 8 MHz */ + buf[0] = 0x60 | 0x7; + ret = buspirate_sendrecv(buf, 1, 1); + if (ret) + return 1; + if (buf[0] != 0x01) { + fprintf(stderr, "Protocol error while setting SPI speed!\n"); + return 1; + } + + /* Set SPI config: output type, idle, clock edge, sample */ + buf[0] = 0x80 | 0xa; + ret = buspirate_sendrecv(buf, 1, 1); + if (ret) + return 1; + if (buf[0] != 0x01) { + fprintf(stderr, "Protocol error while setting SPI config!\n"); + return 1; + } + + /* De-assert CS# */ + buf[0] = 0x03; + ret = buspirate_sendrecv(buf, 1, 1); + if (ret) + return 1; + if (buf[0] != 0x01) { + fprintf(stderr, "Protocol error while raising CS#!\n"); + return 1; + } + + buses_supported = CHIP_BUSTYPE_SPI; + spi_controller = SPI_CONTROLLER_BUSPIRATE; + + return 0; +} + +int buspirate_spi_shutdown(void) +{ + unsigned char buf[5]; + int ret = 0; + + /* Exit raw SPI mode (enter raw bitbang mode) */ + buf[0] = 0x00; + ret = buspirate_sendrecv(buf, 1, 5); + if (ret) + return ret; + if (memcmp(buf, "BBIO", 4)) { + fprintf(stderr, "Entering raw bitbang mode failed!\n"); + return 1; + } + printf_debug("Raw bitbang mode version %c\n", buf[4]); + if (buf[4] != '1') { + fprintf(stderr, "Can't handle raw bitbang mode version %c!\n", + buf[4]); + return 1; + } + /* Reset Bus Pirate (return to user terminal) */ + buf[0] = 0x0f; + ret = buspirate_sendrecv(buf, 1, 0); + if (ret) + return ret; + + /* Shut down serial port communication */ + ret = buspirate_serialport_shutdown(); + if (ret) + return ret; + printf_debug("Bus Pirate shutdown completed.\n"); + + return 0; +} + +int buspirate_spi_send_command(unsigned int writecnt, unsigned int readcnt, + const unsigned char *writearr, unsigned char *readarr) +{ + static unsigned char *buf = NULL; + int i = 0, ret = 0; + + if (writecnt > 16 || readcnt > 16 || (readcnt + writecnt) > 16) + return SPI_INVALID_LENGTH; + + /* +2 is pretty arbitrary. */ + buf = realloc(buf, writecnt + readcnt + 2); + if (!buf) { + fprintf(stderr, "Out of memory!\n"); + exit(1); // -1 + } + + /* Assert CS# */ + buf[i++] = 0x02; + ret = buspirate_sendrecv(buf, 1, 1); + if (ret) + return SPI_GENERIC_ERROR; + if (buf[0] != 0x01) { + fprintf(stderr, "Protocol error while lowering CS#!\n"); + return SPI_GENERIC_ERROR; + } + + i = 0; + buf[i++] = 0x10 | (writecnt + readcnt - 1); + memcpy(buf + i, writearr, writecnt); + i += writecnt; + memset(buf + i, 0, readcnt); + ret = buspirate_sendrecv(buf, i + readcnt, i + readcnt); + if (ret) + return SPI_GENERIC_ERROR; + if (buf[0] != 0x01) { + fprintf(stderr, "Protocol error while reading/writing SPI!\n"); + return SPI_GENERIC_ERROR; + } + memcpy(readarr, buf + i, readcnt); + + i = 0; + /* De-assert CS# */ + buf[i++] = 0x03; + ret = buspirate_sendrecv(buf, 1, 1); + if (ret) + return SPI_GENERIC_ERROR; + if (buf[0] != 0x01) { + fprintf(stderr, "Protocol error while raising CS#!\n"); + return SPI_GENERIC_ERROR; + } + + return ret; +} + +int buspirate_spi_read(struct flashchip *flash, uint8_t *buf, int start, int len) +{ + /* Maximum read length is 12 bytes, use 8 for now. */ + return spi_read_chunked(flash, buf, start, len, 8); +} + +/* We could do 12-byte writes, but for now we use the generic 1-byte code. */ Index: flashrom-buspiratespi/spi.c =================================================================== --- flashrom-buspiratespi/spi.c (Revision 771) +++ flashrom-buspiratespi/spi.c (Arbeitskopie) @@ -100,6 +100,15 @@ }, #endif
+#if BUSPIRATE_SPI_SUPPORT == 1 + { /* SPI_CONTROLLER_BUSPIRATE */ + .command = buspirate_spi_send_command, + .multicommand = default_spi_send_multicommand, + .read = buspirate_spi_read, + .write_256 = spi_chip_write_1, + }, +#endif + {}, /* This entry corresponds to SPI_CONTROLLER_INVALID. */ };
Index: flashrom-buspiratespi/Makefile =================================================================== --- flashrom-buspiratespi/Makefile (Revision 771) +++ flashrom-buspiratespi/Makefile (Arbeitskopie) @@ -25,7 +25,7 @@ DIFF = diff PREFIX ?= /usr/local MANDIR ?= $(PREFIX)/share/man -CFLAGS ?= -Os -Wall -Werror +CFLAGS ?= -Os -Wall -Werror -g EXPORTDIR ?= .
OS_ARCH = $(shell uname) @@ -89,6 +89,9 @@ # Always enable Dr. Kaiser for now. CONFIG_DRKAISER ?= yes
+# Always enable Bus Pirate SPI for now. +CONFIG_BUSPIRATESPI ?= yes + # Disable wiki printing by default. It is only useful if you have wiki access. CONFIG_PRINT_WIKI ?= no
@@ -138,9 +141,19 @@ OBJS += drkaiser.o endif
+ifeq ($(CONFIG_BUSPIRATESPI), yes) +FEATURE_CFLAGS += -D'BUSPIRATE_SPI_SUPPORT=1' +OBJS += buspirate_spi.o +endif + +# Ugly, but there's no elif/elseif. ifeq ($(CONFIG_SERPROG), yes) OBJS += serial.o +else +ifeq ($(CONFIG_BUSPIRATESPI), yes) +OBJS += serial.o endif +endif
ifeq ($(CONFIG_PRINT_WIKI), yes) FEATURE_CFLAGS += -D'PRINT_WIKI_SUPPORT=1' Index: flashrom-buspiratespi/spi.h =================================================================== --- flashrom-buspiratespi/spi.h (Revision 771) +++ flashrom-buspiratespi/spi.h (Arbeitskopie) @@ -106,6 +106,7 @@ #define JEDEC_BYTE_PROGRAM_INSIZE 0x00
/* Error codes */ +#define SPI_GENERIC_ERROR -1 #define SPI_INVALID_OPCODE -2 #define SPI_INVALID_ADDRESS -3 #define SPI_INVALID_LENGTH -4 Index: flashrom-buspiratespi/flashrom.c =================================================================== --- flashrom-buspiratespi/flashrom.c (Revision 771) +++ flashrom-buspiratespi/flashrom.c (Arbeitskopie) @@ -204,6 +204,25 @@ }, #endif
+#if BUSPIRATE_SPI_SUPPORT == 1 + { + .name = "buspiratespi", + .init = buspirate_spi_init, + .shutdown = buspirate_spi_shutdown, + .map_flash_region = fallback_map, + .unmap_flash_region = fallback_unmap, + .chip_readb = noop_chip_readb, + .chip_readw = fallback_chip_readw, + .chip_readl = fallback_chip_readl, + .chip_readn = fallback_chip_readn, + .chip_writeb = noop_chip_writeb, + .chip_writew = fallback_chip_writew, + .chip_writel = fallback_chip_writel, + .chip_writen = fallback_chip_writen, + .delay = internal_delay, + }, +#endif + {}, /* This entry corresponds to PROGRAMMER_INVALID. */ };
The Bus Pirate code works, but flashrom might hang if the chip has a "personal" problem; none of the Bus Pirate's fault. I think it has to do with the chip not being reset, internally.
Chip tested: Sanyo LF25FW203{T,A}
Acked-by: Sean Nelson audiohacked@gmail.com
On Mon, Nov 23, 2009 at 3:24 PM, Carl-Daniel Hailfinger c-d.hailfinger.devel.2006@gmx.net wrote:
Add Bus Pirate SPI support to flashrom.
The code should work on Linux/*BSD/MacOSX and relies on the serial code implementation in serial.c. Support for additional platforms (Windows) will have to be added to serial.c for this to work. For tests without a Bus Pirate (or with non-functional serial code) it is possible to #define FAKE_COMMUNICATION in buspirate_spi.c. Thanks to Sean Nelson for the SPI mode settings code. I tweaked it a bit to make configuration from a commandline easier should anybody want that feature.
Signed-off-by: Carl-Daniel Hailfinger c-d.hailfinger.devel.2006@gmx.net Acked-by: Stefan Reinauer stepan@coresystems.de
Index: flashrom-buspiratespi/flash.h
--- flashrom-buspiratespi/flash.h (Revision 771) +++ flashrom-buspiratespi/flash.h (Arbeitskopie) @@ -104,6 +104,9 @@ #if SERPROG_SUPPORT == 1 PROGRAMMER_SERPROG, #endif +#if BUSPIRATE_SPI_SUPPORT == 1
- PROGRAMMER_BUSPIRATESPI,
+#endif PROGRAMMER_INVALID /* This must always be the last entry. */ };
@@ -484,6 +487,12 @@ int bitbang_spi_read(struct flashchip *flash, uint8_t *buf, int start, int len); int bitbang_spi_write_256(struct flashchip *flash, uint8_t *buf);
+/* buspirate_spi.c */ +int buspirate_spi_init(void); +int buspirate_spi_shutdown(void); +int buspirate_spi_send_command(unsigned int writecnt, unsigned int readcnt, const unsigned char *writearr, unsigned char *readarr); +int buspirate_spi_read(struct flashchip *flash, uint8_t *buf, int start, int len);
/* flashrom.c */ extern char *programmer_param; extern int verbose; @@ -527,6 +536,9 @@ #if DUMMY_SUPPORT == 1 SPI_CONTROLLER_DUMMY, #endif +#if BUSPIRATE_SPI_SUPPORT == 1
- SPI_CONTROLLER_BUSPIRATE,
+#endif SPI_CONTROLLER_INVALID /* This must always be the last entry. */ }; extern const int spi_programmer_count; Index: flashrom-buspiratespi/buspirate_spi.c =================================================================== --- flashrom-buspiratespi/buspirate_spi.c (Revision 0) +++ flashrom-buspiratespi/buspirate_spi.c (Revision 0) @@ -0,0 +1,358 @@ +/*
- This file is part of the flashrom project.
- Copyright (C) 2009 Carl-Daniel Hailfinger
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
+#include <stdio.h> +#include <stdint.h> +#include <string.h> +#include <stdlib.h> +#include <ctype.h> +#include <fcntl.h> +#include "flash.h" +#include "spi.h"
+/* Change this to #define if you want to test without a serial implementation */ +#undef FAKE_COMMUNICATION
+#ifndef FAKE_COMMUNICATION +int buspirate_serialport_setup(char *dev) +{
- /* 115200bps, 8 databits, no parity, 1 stopbit */
- sp_fd = sp_openserport(dev, 115200);
- return 0;
+}
+int buspirate_serialport_shutdown(void) +{
- close(sp_fd);
- return 0;
+}
+int serialport_write(unsigned char *buf, unsigned int writecnt) +{
- int tmp = 0;
- while (tmp != writecnt) {
- tmp = write(sp_fd, buf + tmp, writecnt - tmp);
- if (tmp == -1)
- return 1;
- if (!tmp)
- printf_debug("Empty write\n");
- }
- return 0;
+}
+int serialport_read(unsigned char *buf, unsigned int readcnt) +{
- int tmp = 0;
- while (tmp != readcnt) {
- tmp = read(sp_fd, buf + tmp, readcnt - tmp);
- if (tmp == -1)
- return 1;
- if (!tmp)
- printf_debug("Empty read\n");
- }
- return 0;
+}
+int buspirate_discard_read(void) +{
- int flags;
- printf_debug("%s\n", __func__);
- flags = fcntl(sp_fd, F_GETFL);
- flags |= O_NONBLOCK;
- fcntl(sp_fd, F_SETFL, flags);
- sp_flush_incoming();
- flags &= ~O_NONBLOCK;
- fcntl(sp_fd, F_SETFL, flags);
- return 0;
+} +#else +#define buspirate_serialport_setup(...) 0 +#define buspirate_serialport_shutdown(...) 0 +#define serialport_write(...) 0 +#define serialport_read(...) 0 +#define buspirate_discard_read(...) 0 +#endif
+int buspirate_sendrecv(unsigned char *buf, unsigned int writecnt, unsigned int readcnt) +{
- int i, ret = 0;
- printf_debug("%s: write %i, read %i\n", __func__, writecnt, readcnt);
- if (!writecnt && !readcnt) {
- fprintf(stderr, "Zero length command!\n");
- return 1;
- }
- printf_debug("Sending");
- for (i = 0; i < writecnt; i++)
- printf_debug(" 0x%02x", buf[i]);
+#ifdef FAKE_COMMUNICATION
- /* Placate the caller for now. */
- if (readcnt) {
- buf[0] = 0x01;
- memset(buf + 1, 0xff, readcnt - 1);
- }
- ret = 0;
+#else
- if (writecnt)
- ret = serialport_write(buf, writecnt);
- if (ret)
- return ret;
- if (readcnt)
- ret = serialport_read(buf, readcnt);
- if (ret)
- return ret;
+#endif
- printf_debug(", receiving");
- for (i = 0; i < readcnt; i++)
- printf_debug(" 0x%02x", buf[i]);
- printf_debug("\n");
- return 0;
+}
+int buspirate_spi_init(void) +{
- unsigned char buf[512];
- int ret = 0;
- int i;
- char *devpos = NULL;
- char *dev = NULL;
- int devlen;
- if (programmer_param && !strlen(programmer_param)) {
- free(programmer_param);
- programmer_param = NULL;
- }
- if (programmer_param) {
- devpos = strstr(programmer_param, "dev=");
- if (devpos) {
- devpos += 4;
- devlen = strcspn(devpos, ",:");
- if (devlen) {
- dev = malloc(devlen + 1);
- if (!dev) {
- fprintf(stderr, "Out of memory!\n");
- exit(1);
- }
- strncpy(dev, devpos, devlen);
- dev[devlen] = '\0';
- }
- }
- free(programmer_param);
- programmer_param = NULL;
- }
- if (!dev) {
- fprintf(stderr, "No serial device given. Use flashrom -p "
- "buspiratespi:dev=/dev/ttyUSB0\n");
- return 1;
- }
- ret = buspirate_serialport_setup(dev);
- if (ret)
- return ret;
- /* This is the brute force version, but it should work. */
- for (i = 0; i < 19; i++) {
- /* Enter raw bitbang mode */
- buf[0] = 0x00;
- /* Send the command, don't read the response. */
- ret = buspirate_sendrecv(buf, 1, 0);
- if (ret)
- return ret;
- /* Read any response and discard it. */
- ret = buspirate_discard_read();
- if (ret)
- return ret;
- }
- /* Enter raw bitbang mode */
- buf[0] = 0x00;
- ret = buspirate_sendrecv(buf, 1, 5);
- if (ret)
- return ret;
- if (memcmp(buf, "BBIO", 4)) {
- fprintf(stderr, "Entering raw bitbang mode failed!\n");
- return 1;
- }
- printf_debug("Raw bitbang mode version %c\n", buf[4]);
- if (buf[4] != '1') {
- fprintf(stderr, "Can't handle raw bitbang mode version %c!\n",
- buf[4]);
- return 1;
- }
- /* Enter raw SPI mode */
- buf[0] = 0x01;
- ret = buspirate_sendrecv(buf, 1, 4);
- if (memcmp(buf, "SPI", 3)) {
- fprintf(stderr, "Entering raw SPI mode failed!\n");
- return 1;
- }
- printf_debug("Raw SPI mode version %c\n", buf[3]);
- if (buf[3] != '1') {
- fprintf(stderr, "Can't handle raw SPI mode version %c!\n",
- buf[3]);
- return 1;
- }
- /* Initial setup (SPI peripherals config): Enable power, CS high, AUX */
- buf[0] = 0x40 | 0xb;
- ret = buspirate_sendrecv(buf, 1, 1);
- if (ret)
- return 1;
- if (buf[0] != 0x01) {
- fprintf(stderr, "Protocol error while setting power/CS/AUX!\n");
- return 1;
- }
- /* Set speed to 8 MHz */
- buf[0] = 0x60 | 0x7;
- ret = buspirate_sendrecv(buf, 1, 1);
- if (ret)
- return 1;
- if (buf[0] != 0x01) {
- fprintf(stderr, "Protocol error while setting SPI speed!\n");
- return 1;
- }
- /* Set SPI config: output type, idle, clock edge, sample */
- buf[0] = 0x80 | 0xa;
- ret = buspirate_sendrecv(buf, 1, 1);
- if (ret)
- return 1;
- if (buf[0] != 0x01) {
- fprintf(stderr, "Protocol error while setting SPI config!\n");
- return 1;
- }
- /* De-assert CS# */
- buf[0] = 0x03;
- ret = buspirate_sendrecv(buf, 1, 1);
- if (ret)
- return 1;
- if (buf[0] != 0x01) {
- fprintf(stderr, "Protocol error while raising CS#!\n");
- return 1;
- }
- buses_supported = CHIP_BUSTYPE_SPI;
- spi_controller = SPI_CONTROLLER_BUSPIRATE;
- return 0;
+}
+int buspirate_spi_shutdown(void) +{
- unsigned char buf[5];
- int ret = 0;
- /* Exit raw SPI mode (enter raw bitbang mode) */
- buf[0] = 0x00;
- ret = buspirate_sendrecv(buf, 1, 5);
- if (ret)
- return ret;
- if (memcmp(buf, "BBIO", 4)) {
- fprintf(stderr, "Entering raw bitbang mode failed!\n");
- return 1;
- }
- printf_debug("Raw bitbang mode version %c\n", buf[4]);
- if (buf[4] != '1') {
- fprintf(stderr, "Can't handle raw bitbang mode version %c!\n",
- buf[4]);
- return 1;
- }
- /* Reset Bus Pirate (return to user terminal) */
- buf[0] = 0x0f;
- ret = buspirate_sendrecv(buf, 1, 0);
- if (ret)
- return ret;
- /* Shut down serial port communication */
- ret = buspirate_serialport_shutdown();
- if (ret)
- return ret;
- printf_debug("Bus Pirate shutdown completed.\n");
- return 0;
+}
+int buspirate_spi_send_command(unsigned int writecnt, unsigned int readcnt,
- const unsigned char *writearr, unsigned char *readarr)
+{
- static unsigned char *buf = NULL;
- int i = 0, ret = 0;
- if (writecnt > 16 || readcnt > 16 || (readcnt + writecnt) > 16)
- return SPI_INVALID_LENGTH;
- /* +2 is pretty arbitrary. */
- buf = realloc(buf, writecnt + readcnt + 2);
- if (!buf) {
- fprintf(stderr, "Out of memory!\n");
- exit(1); // -1
- }
- /* Assert CS# */
- buf[i++] = 0x02;
- ret = buspirate_sendrecv(buf, 1, 1);
- if (ret)
- return SPI_GENERIC_ERROR;
- if (buf[0] != 0x01) {
- fprintf(stderr, "Protocol error while lowering CS#!\n");
- return SPI_GENERIC_ERROR;
- }
- i = 0;
- buf[i++] = 0x10 | (writecnt + readcnt - 1);
- memcpy(buf + i, writearr, writecnt);
- i += writecnt;
- memset(buf + i, 0, readcnt);
- ret = buspirate_sendrecv(buf, i + readcnt, i + readcnt);
- if (ret)
- return SPI_GENERIC_ERROR;
- if (buf[0] != 0x01) {
- fprintf(stderr, "Protocol error while reading/writing SPI!\n");
- return SPI_GENERIC_ERROR;
- }
- memcpy(readarr, buf + i, readcnt);
- i = 0;
- /* De-assert CS# */
- buf[i++] = 0x03;
- ret = buspirate_sendrecv(buf, 1, 1);
- if (ret)
- return SPI_GENERIC_ERROR;
- if (buf[0] != 0x01) {
- fprintf(stderr, "Protocol error while raising CS#!\n");
- return SPI_GENERIC_ERROR;
- }
- return ret;
+}
+int buspirate_spi_read(struct flashchip *flash, uint8_t *buf, int start, int len) +{
- /* Maximum read length is 12 bytes, use 8 for now. */
- return spi_read_chunked(flash, buf, start, len, 8);
+}
+/* We could do 12-byte writes, but for now we use the generic 1-byte code. */ Index: flashrom-buspiratespi/spi.c =================================================================== --- flashrom-buspiratespi/spi.c (Revision 771) +++ flashrom-buspiratespi/spi.c (Arbeitskopie) @@ -100,6 +100,15 @@ }, #endif
+#if BUSPIRATE_SPI_SUPPORT == 1
- { /* SPI_CONTROLLER_BUSPIRATE */
- .command = buspirate_spi_send_command,
- .multicommand = default_spi_send_multicommand,
- .read = buspirate_spi_read,
- .write_256 = spi_chip_write_1,
- },
+#endif
{}, /* This entry corresponds to SPI_CONTROLLER_INVALID. */ };
Index: flashrom-buspiratespi/Makefile
--- flashrom-buspiratespi/Makefile (Revision 771) +++ flashrom-buspiratespi/Makefile (Arbeitskopie) @@ -25,7 +25,7 @@ DIFF = diff PREFIX ?= /usr/local MANDIR ?= $(PREFIX)/share/man -CFLAGS ?= -Os -Wall -Werror +CFLAGS ?= -Os -Wall -Werror -g EXPORTDIR ?= .
OS_ARCH = $(shell uname) @@ -89,6 +89,9 @@ # Always enable Dr. Kaiser for now. CONFIG_DRKAISER ?= yes
+# Always enable Bus Pirate SPI for now. +CONFIG_BUSPIRATESPI ?= yes
# Disable wiki printing by default. It is only useful if you have wiki access. CONFIG_PRINT_WIKI ?= no
@@ -138,9 +141,19 @@ OBJS += drkaiser.o endif
+ifeq ($(CONFIG_BUSPIRATESPI), yes) +FEATURE_CFLAGS += -D'BUSPIRATE_SPI_SUPPORT=1' +OBJS += buspirate_spi.o +endif
+# Ugly, but there's no elif/elseif. ifeq ($(CONFIG_SERPROG), yes) OBJS += serial.o +else +ifeq ($(CONFIG_BUSPIRATESPI), yes) +OBJS += serial.o endif +endif
ifeq ($(CONFIG_PRINT_WIKI), yes) FEATURE_CFLAGS += -D'PRINT_WIKI_SUPPORT=1' Index: flashrom-buspiratespi/spi.h =================================================================== --- flashrom-buspiratespi/spi.h (Revision 771) +++ flashrom-buspiratespi/spi.h (Arbeitskopie) @@ -106,6 +106,7 @@ #define JEDEC_BYTE_PROGRAM_INSIZE 0x00
/* Error codes */ +#define SPI_GENERIC_ERROR -1 #define SPI_INVALID_OPCODE -2 #define SPI_INVALID_ADDRESS -3 #define SPI_INVALID_LENGTH -4 Index: flashrom-buspiratespi/flashrom.c =================================================================== --- flashrom-buspiratespi/flashrom.c (Revision 771) +++ flashrom-buspiratespi/flashrom.c (Arbeitskopie) @@ -204,6 +204,25 @@ }, #endif
+#if BUSPIRATE_SPI_SUPPORT == 1
- {
- .name = "buspiratespi",
- .init = buspirate_spi_init,
- .shutdown = buspirate_spi_shutdown,
- .map_flash_region = fallback_map,
- .unmap_flash_region = fallback_unmap,
- .chip_readb = noop_chip_readb,
- .chip_readw = fallback_chip_readw,
- .chip_readl = fallback_chip_readl,
- .chip_readn = fallback_chip_readn,
- .chip_writeb = noop_chip_writeb,
- .chip_writew = fallback_chip_writew,
- .chip_writel = fallback_chip_writel,
- .chip_writen = fallback_chip_writen,
- .delay = internal_delay,
- },
+#endif
{}, /* This entry corresponds to PROGRAMMER_INVALID. */ };
-- Developer quote of the month: "We are juggling too many chainsaws and flaming arrows and tigers."
On 24.11.2009 01:09, Sean Nelson wrote:
The Bus Pirate code works, but flashrom might hang if the chip has a "personal" problem; none of the Bus Pirate's fault. I think it has to do with the chip not being reset, internally.
Interesting. In theory, this should not happen for read/probe, but it may happen for write/erase because we wait for a certain status code from the chip in that case.
Chip tested: Sanyo LF25FW203{T,A}
Acked-by: Sean Nelson audiohacked@gmail.com
Thanks, committed in r772.
Regards, Carl-Daniel