1
0
mirror of https://review.coreboot.org/flashrom.git synced 2025-04-27 07:02:34 +02:00

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.

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

Corresponding to flashrom svn r776.

Signed-off-by: Carl-Daniel Hailfinger <c-d.hailfinger.devel.2006@gmx.net>
Acked-by: Sean Nelson <audiohacked@gmail.com>
This commit is contained in:
Carl-Daniel Hailfinger 2009-11-24 18:27:10 +00:00
parent d70b09ca13
commit d5b28fae1d
5 changed files with 108 additions and 20 deletions

View File

@ -131,34 +131,37 @@ int buspirate_sendrecv(unsigned char *buf, unsigned int writecnt, unsigned int r
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 @@ int buspirate_spi_init(void)
"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 @@ int buspirate_spi_init(void)
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_send_command(unsigned int writecnt, unsigned int readcnt,
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. */

View File

@ -488,6 +488,10 @@ 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 */
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 read_memmapped(struct flashchip *flash, uint8_t *buf, int start, int len);
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);

View File

@ -152,6 +152,8 @@ Specify the programmer device. Currently supported are:
.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 @@ syntax and for IP, you have to use
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.

View File

@ -336,6 +336,60 @@ char *strcat_realloc(char *dest, const char *src)
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)
{

3
spi.c
View File

@ -318,6 +318,9 @@ int probe_spi_rdid4(struct flashchip *flash)
#endif
#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: