[flashrom] [PATCH] Configurable SPI speed and man page for Bus Pirate

Sean Nelson audiohacked at gmail.com
Tue Nov 24 17:43:33 CET 2009


Send Ack to list. And send Tested-by while I'm at it.

Acked-by: Sean Nelson <audiohacked at gmail.com>
Tested-by: Sean Nelson <audiohacked at gmail.com>

On Tue, Nov 24, 2009 at 8:41 AM, Sean Nelson <audiohacked at gmail.com> wrote:
> Acked-by: Sean Nelson <audiohacked at gmail.com>
>
> On Tue, Nov 24, 2009 at 4:59 AM, Carl-Daniel Hailfinger
> <c-d.hailfinger.devel.2006 at gmx.net> wrote:
>> Add the ability to set Bus Pirate SPI speed via the command line.
>> Example usage:
>> flashrom -p buspiratespi:spispeed=2.6MHz,dev=/dev/foo
>> flashrom -p buspiratespi:dev=/dev/foo,spispeed=2.6M
>>
>> Refactor programmer option parsing (this allows cleanups in other
>> programmers as well).
>>
>> Increase SPI read size from 8 to 12 bytes (current single-transaction
>> limit of the Bus Pirate raw SPI protocol).
>>
>> Add Bus Pirate to the list of programmers supporting 4 byte RDID.
>>
>> Add Bus Pirate syntax to the man page.
>>
>> Signed-off-by: Carl-Daniel Hailfinger <c-d.hailfinger.devel.2006 at gmx.net>
>>
>> Index: flashrom-buspiratespi_spispeed_manpage/flashrom.8
>> ===================================================================
>> --- flashrom-buspiratespi_spispeed_manpage/flashrom.8   (Revision 775)
>> +++ flashrom-buspiratespi_spispeed_manpage/flashrom.8   (Arbeitskopie)
>> @@ -152,6 +152,8 @@
>>  .sp
>>  .BR "* serprog" " (for flash ROMs attached to Urja's AVR programmer)"
>>  .sp
>> +.BR "* buspiratespi" " (for flash ROMs attached to a Bus Pirate)"
>> +.sp
>>  The dummy programmer has an optional parameter specifying the bus types it
>>  should support. For that you have to use the
>>  .B "flashrom -p dummy:type"
>> @@ -219,6 +221,16 @@
>>  instead. More information about serprog is available in serprog-protocol.txt in
>>  the source distribution.
>>  .sp
>> +The buspiratespi programmer has a required dev parameter specifying the Bus
>> +Pirate device node and an optional spispeed parameter specifying the frequency
>> +of the SPI bus. The parameter delimiter is a comma. Syntax is
>> +.B "flashrom -p buspiratespi:dev=/dev/device,spispeed=frequency"
>> +where
>> +.B frequency
>> +can be any of
>> +.B 30k 125k 250k 1M 2M 2.6M 4M 8M
>> +(in Hz).
>> +.sp
>>  Support for some programmers can be disabled at compile time.
>>  .B "flashrom -h"
>>  lists all supported programmers.
>> Index: flashrom-buspiratespi_spispeed_manpage/flash.h
>> ===================================================================
>> --- flashrom-buspiratespi_spispeed_manpage/flash.h      (Revision 775)
>> +++ flashrom-buspiratespi_spispeed_manpage/flash.h      (Arbeitskopie)
>> @@ -488,6 +488,10 @@
>>  int bitbang_spi_write_256(struct flashchip *flash, uint8_t *buf);
>>
>>  /* buspirate_spi.c */
>> +struct buspirate_spispeeds {
>> +       const char *name;
>> +       const int speed;
>> +};
>>  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);
>> @@ -503,6 +507,7 @@
>>  int erase_flash(struct flashchip *flash);
>>  int min(int a, int b);
>>  int max(int a, int b);
>> +char *extract_param(char **haystack, char *needle, char *delim);
>>  int check_erased_range(struct flashchip *flash, int start, int len);
>>  int verify_range(struct flashchip *flash, uint8_t *cmpbuf, int start, int len, char *message);
>>  char *strcat_realloc(char *dest, const char *src);
>> Index: flashrom-buspiratespi_spispeed_manpage/buspirate_spi.c
>> ===================================================================
>> --- flashrom-buspiratespi_spispeed_manpage/buspirate_spi.c      (Revision 775)
>> +++ flashrom-buspiratespi_spispeed_manpage/buspirate_spi.c      (Arbeitskopie)
>> @@ -131,34 +131,37 @@
>>        return 0;
>>  }
>>
>> +static const struct buspirate_spispeeds spispeeds[] = {
>> +       {"30k",         0x0},
>> +       {"125k",        0x1},
>> +       {"250k",        0x2},
>> +       {"1M",          0x3},
>> +       {"2M",          0x4},
>> +       {"2.6M",        0x5},
>> +       {"4M",          0x6},
>> +       {"8M",          0x7},
>> +       {NULL,          0x0}
>> +};
>> +
>>  int buspirate_spi_init(void)
>>  {
>>        unsigned char buf[512];
>>        int ret = 0;
>>        int i;
>> -       char *devpos = NULL;
>>        char *dev = NULL;
>> -       int devlen;
>> +       char *speed = NULL;
>> +       int spispeed = 0x7;
>>
>>        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';
>> -                       }
>> -               }
>> +               dev = extract_param(&programmer_param, "dev=", ",:");
>> +               speed = extract_param(&programmer_param, "spispeed=", ",:");
>> +               if (strlen(programmer_param))
>> +                       fprintf(stderr, "Unhandled programmer parameters: %s\n",
>> +                               programmer_param);
>>                free(programmer_param);
>>                programmer_param = NULL;
>>        }
>> @@ -167,6 +170,18 @@
>>                        "buspiratespi:dev=/dev/ttyUSB0\n");
>>                return 1;
>>        }
>> +       if (speed) {
>> +               for (i = 0; spispeeds[i].name; i++)
>> +                       if (!strncasecmp(spispeeds[i].name, speed,
>> +                           strlen(spispeeds[i].name))) {
>> +                               spispeed = spispeeds[i].speed;
>> +                               break;
>> +                       }
>> +               if (!spispeeds[i].name)
>> +                       fprintf(stderr, "Invalid SPI speed, using default.\n");
>> +       }
>> +       /* This works because speeds numbering starts at 0 and is contiguous. */
>> +       printf_debug("SPI speed is %sHz\n", spispeeds[spispeed].name);
>>
>>        ret = buspirate_serialport_setup(dev);
>>        if (ret)
>> @@ -224,8 +239,8 @@
>>                return 1;
>>        }
>>
>> -       /* Set speed to 8 MHz */
>> -       buf[0] = 0x60 | 0x7;
>> +       /* Set SPI speed */
>> +       buf[0] = 0x60 | spispeed;
>>        ret = buspirate_sendrecv(buf, 1, 1);
>>        if (ret)
>>                return 1;
>> @@ -351,8 +366,7 @@
>>
>>  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);
>> +       return spi_read_chunked(flash, buf, start, len, 12);
>>  }
>>
>>  /* We could do 12-byte writes, but for now we use the generic 1-byte code. */
>> Index: flashrom-buspiratespi_spispeed_manpage/spi.c
>> ===================================================================
>> --- flashrom-buspiratespi_spispeed_manpage/spi.c        (Revision 775)
>> +++ flashrom-buspiratespi_spispeed_manpage/spi.c        (Arbeitskopie)
>> @@ -319,6 +319,9 @@
>>  #if DUMMY_SUPPORT == 1
>>        case SPI_CONTROLLER_DUMMY:
>>  #endif
>> +#if BUSPIRATE_SPI_SUPPORT == 1
>> +       case SPI_CONTROLLER_BUSPIRATE:
>> +#endif
>>                return probe_spi_rdid_generic(flash, 4);
>>        default:
>>                printf_debug("4b ID not supported on this SPI controller\n");
>> Index: flashrom-buspiratespi_spispeed_manpage/flashrom.c
>> ===================================================================
>> --- flashrom-buspiratespi_spispeed_manpage/flashrom.c   (Revision 775)
>> +++ flashrom-buspiratespi_spispeed_manpage/flashrom.c   (Arbeitskopie)
>> @@ -336,6 +336,60 @@
>>        return dest;
>>  }
>>
>> +/* This is a somewhat hacked function similar in some ways to strtok().
>> + * It will look for needle in haystack, return a copy of needle and remove
>> + * everything from the first occurrence of needle to the next delimiter
>> + * from haystack.
>> + */
>> +char *extract_param(char **haystack, char *needle, char *delim)
>> +{
>> +       char *param_pos, *rest, *tmp;
>> +       char *dev = NULL;
>> +       int devlen;
>> +
>> +       param_pos = strstr(*haystack, needle);
>> +       do {
>> +               if (!param_pos)
>> +                       return NULL;
>> +               /* Beginning of the string? */
>> +               if (param_pos == *haystack)
>> +                       break;
>> +               /* After a delimiter? */
>> +               if (strchr(delim, *(param_pos - 1)))
>> +                       break;
>> +               /* Continue searching. */
>> +               param_pos++;
>> +               param_pos = strstr(param_pos, needle);
>> +       } while (1);
>> +
>> +       if (param_pos) {
>> +               param_pos += strlen(needle);
>> +               devlen = strcspn(param_pos, delim);
>> +               if (devlen) {
>> +                       dev = malloc(devlen + 1);
>> +                       if (!dev) {
>> +                               fprintf(stderr, "Out of memory!\n");
>> +                               exit(1);
>> +                       }
>> +                       strncpy(dev, param_pos, devlen);
>> +                       dev[devlen] = '\0';
>> +               }
>> +               rest = param_pos + devlen;
>> +               rest += strspn(rest, delim);
>> +               param_pos -= strlen(needle);
>> +               memmove(param_pos, rest, strlen(rest) + 1);
>> +               tmp = realloc(*haystack, strlen(*haystack) + 1);
>> +               if (!tmp) {
>> +                       fprintf(stderr, "Out of memory!\n");
>> +                       exit(1);
>> +               }
>> +               *haystack = tmp;
>> +       }
>> +
>> +
>> +       return dev;
>> +}
>> +
>>  /* start is an offset to the base address of the flash chip */
>>  int check_erased_range(struct flashchip *flash, int start, int len)
>>  {
>>
>>
>> --
>> Developer quote of the month:
>> "We are juggling too many chainsaws and flaming arrows and tigers."
>>
>>
>> _______________________________________________
>> flashrom mailing list
>> flashrom at flashrom.org
>> http://www.flashrom.org/mailman/listinfo/flashrom
>>
>




More information about the flashrom mailing list