Patch with SPI mode init code.
On Sat, Nov 21, 2009 at 2:50 AM, Sean Nelson <[email protected]> wrote: > Verbose log of flashrom-buspiratespi. > > On Fri, Nov 20, 2009 at 8:53 PM, Carl-Daniel Hailfinger > <[email protected]> wrote: >> Add Bus Pirate SPI support to flashrom. >> >> Untested, should work. >> >> Signed-off-by: Carl-Daniel Hailfinger <[email protected]> >> >> 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." >> >> >
my-flashrom-buspirate.diff
Description: Binary data
_______________________________________________ flashrom mailing list [email protected] http://www.flashrom.org/mailman/listinfo/flashrom
