enable capacity overriding
We have different-sized SPI flash chips, so when possible set the capacity based on various id codes. Also allow for manually overriding capacity with the -b option. Signed-off-by: Sean Cross <sean@xobs.io>
This commit is contained in:
parent
9b1b9b8a88
commit
27dec515e7
31
fomu-flash.c
31
fomu-flash.c
@ -132,12 +132,13 @@ static int print_help(FILE *stream, const char *progname) {
|
|||||||
fprintf(stream, "Fomu Raspberry Pi Flash Utilities\n");
|
fprintf(stream, "Fomu Raspberry Pi Flash Utilities\n");
|
||||||
fprintf(stream, "Usage:\n");
|
fprintf(stream, "Usage:\n");
|
||||||
fprintf(stream, "%15s (-[hri] | [-p offset] | [-f bin] | [-w bin] | [-v bin] | [-s out] | [-k n[:f]])\n", progname);
|
fprintf(stream, "%15s (-[hri] | [-p offset] | [-f bin] | [-w bin] | [-v bin] | [-s out] | [-k n[:f]])\n", progname);
|
||||||
fprintf(stream, " [-g pinspec] [-t spitype] [-r]\n");
|
fprintf(stream, " [-g pinspec] [-t spitype] [-b bytes]\n");
|
||||||
fprintf(stream, "Program mode (pick one):\n");
|
fprintf(stream, "Program mode (pick one):\n");
|
||||||
print_program_modes(stream);
|
print_program_modes(stream);
|
||||||
fprintf(stream, "Configuration options:\n");
|
fprintf(stream, "Configuration options:\n");
|
||||||
fprintf(stream, " -g ps Set the pin assignment with the given pinspec\n");
|
fprintf(stream, " -g ps Set the pin assignment with the given pinspec\n");
|
||||||
fprintf(stream, " -t type Set the number of bits to use for SPI (1, 2, 4, or Q)\n");
|
fprintf(stream, " -t type Set the number of bits to use for SPI (1, 2, 4, or Q)\n");
|
||||||
|
fprintf(stream, " -b bytes Override the size of the SPI flash, in bytes\n");
|
||||||
fprintf(stream, "You can remap various pins with -g. The format is [name]:[number].\n");
|
fprintf(stream, "You can remap various pins with -g. The format is [name]:[number].\n");
|
||||||
fprintf(stream, "\n");
|
fprintf(stream, "\n");
|
||||||
fprintf(stream, "The width of SPI can be set with 't [width]'. Valid widths are:\n");
|
fprintf(stream, "The width of SPI can be set with 't [width]'. Valid widths are:\n");
|
||||||
@ -163,6 +164,7 @@ int main(int argc, char **argv) {
|
|||||||
struct ff_spi *spi;
|
struct ff_spi *spi;
|
||||||
struct ff_fpga *fpga;
|
struct ff_fpga *fpga;
|
||||||
int peek_offset = 0;
|
int peek_offset = 0;
|
||||||
|
int spi_flash_bytes = -1;
|
||||||
uint8_t security_reg;
|
uint8_t security_reg;
|
||||||
uint8_t security_val[256];
|
uint8_t security_val[256];
|
||||||
enum op op = OP_UNKNOWN;
|
enum op op = OP_UNKNOWN;
|
||||||
@ -191,7 +193,7 @@ int main(int argc, char **argv) {
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
while ((opt = getopt(argc, argv, "hip:rf:w:s:2:3:v:g:t:k:")) != -1) {
|
while ((opt = getopt(argc, argv, "hip:rf:b:w:s:2:3:v:g:t:k:")) != -1) {
|
||||||
switch (opt) {
|
switch (opt) {
|
||||||
|
|
||||||
case 'r':
|
case 'r':
|
||||||
@ -200,6 +202,10 @@ int main(int argc, char **argv) {
|
|||||||
op = OP_FPGA_RESET;
|
op = OP_FPGA_RESET;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 'b':
|
||||||
|
spi_flash_bytes = strtoul(optarg, NULL, 0);
|
||||||
|
break;
|
||||||
|
|
||||||
case 'k': {
|
case 'k': {
|
||||||
if (op != OP_UNKNOWN)
|
if (op != OP_UNKNOWN)
|
||||||
return print_usage_error(stdout);
|
return print_usage_error(stdout);
|
||||||
@ -332,6 +338,9 @@ int main(int argc, char **argv) {
|
|||||||
spiSetType(spi, spi_type);
|
spiSetType(spi, spi_type);
|
||||||
fpgaReset(fpga);
|
fpgaReset(fpga);
|
||||||
|
|
||||||
|
if (spi_flash_bytes != -1)
|
||||||
|
spiOverrideSize(spi, spi_flash_bytes);
|
||||||
|
|
||||||
switch (op) {
|
switch (op) {
|
||||||
case OP_SPI_ID: {
|
case OP_SPI_ID: {
|
||||||
struct spi_id id = spiId(spi);
|
struct spi_id id = spiId(spi);
|
||||||
@ -366,15 +375,25 @@ int main(int argc, char **argv) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
case OP_SPI_READ: {
|
case OP_SPI_READ: {
|
||||||
|
struct spi_id id = spiId(spi);
|
||||||
|
if (id.bytes == -1) {
|
||||||
|
fprintf(stderr, "unknown spi flash size -- specify with -b\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
fd = open(op_filename, O_WRONLY | O_CREAT | O_TRUNC, 0777);
|
fd = open(op_filename, O_WRONLY | O_CREAT | O_TRUNC, 0777);
|
||||||
if (fd == -1) {
|
if (fd == -1) {
|
||||||
perror("unable to open output file");
|
perror("unable to open output file");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
uint8_t *bfr = malloc(16777216);
|
uint8_t *bfr = malloc(id.bytes);
|
||||||
spiRead(spi, 0, bfr, 16777216);
|
if (!bfr) {
|
||||||
if (write(fd, bfr, 16777216) != 16777216) {
|
perror("unable to allocate memory for spi");
|
||||||
perror("unable to write SPI flash image");
|
return 1;
|
||||||
|
}
|
||||||
|
spiRead(spi, 0, bfr, id.bytes);
|
||||||
|
if (write(fd, bfr, id.bytes) != id.bytes) {
|
||||||
|
perror("unable to write SPI flash image to disk");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
close(fd);
|
close(fd);
|
||||||
|
33
spi.c
33
spi.c
@ -29,6 +29,7 @@ struct ff_spi {
|
|||||||
enum spi_type desired_type;
|
enum spi_type desired_type;
|
||||||
struct spi_id id;
|
struct spi_id id;
|
||||||
enum ff_spi_quirks quirks;
|
enum ff_spi_quirks quirks;
|
||||||
|
int size_override;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
int clk;
|
int clk;
|
||||||
@ -457,6 +458,7 @@ static void spi_decode_id(struct ff_spi *spi) {
|
|||||||
spi->id.manufacturer = "unknown";
|
spi->id.manufacturer = "unknown";
|
||||||
spi->id.model = "unknown";
|
spi->id.model = "unknown";
|
||||||
spi->id.capacity = "unknown";
|
spi->id.capacity = "unknown";
|
||||||
|
spi->id.bytes = -1; // unknown
|
||||||
|
|
||||||
if (spi->id.manufacturer_id == 0xef) {
|
if (spi->id.manufacturer_id == 0xef) {
|
||||||
spi->id.manufacturer = "Winbond";
|
spi->id.manufacturer = "Winbond";
|
||||||
@ -464,6 +466,7 @@ static void spi_decode_id(struct ff_spi *spi) {
|
|||||||
&& (spi->id.memory_size == 0x18)) {
|
&& (spi->id.memory_size == 0x18)) {
|
||||||
spi->id.model = "W25Q128JV";
|
spi->id.model = "W25Q128JV";
|
||||||
spi->id.capacity = "128 Mbit";
|
spi->id.capacity = "128 Mbit";
|
||||||
|
spi->id.bytes = 16 * 1024 * 1024;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -473,6 +476,7 @@ static void spi_decode_id(struct ff_spi *spi) {
|
|||||||
&& (spi->id.memory_size == 0x01)) {
|
&& (spi->id.memory_size == 0x01)) {
|
||||||
spi->id.model = "AT25SF161";
|
spi->id.model = "AT25SF161";
|
||||||
spi->id.capacity = "16 Mbit";
|
spi->id.capacity = "16 Mbit";
|
||||||
|
spi->id.bytes = 1 * 1024 * 1024;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -522,6 +526,16 @@ static void spi_get_id(struct ff_spi *spi) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void spiOverrideSize(struct ff_spi *spi, uint32_t size) {
|
||||||
|
spi->size_override = size;
|
||||||
|
|
||||||
|
// If size is 0, re-read the capacity
|
||||||
|
if (!size)
|
||||||
|
spi_decode_id(spi);
|
||||||
|
else
|
||||||
|
spi->id.bytes = size;
|
||||||
|
}
|
||||||
|
|
||||||
int spiSetType(struct ff_spi *spi, enum spi_type type) {
|
int spiSetType(struct ff_spi *spi, enum spi_type type) {
|
||||||
|
|
||||||
if (spi->type == type)
|
if (spi->type == type)
|
||||||
@ -606,8 +620,14 @@ int spiRead(struct ff_spi *spi, uint32_t addr, uint8_t *data, unsigned int count
|
|||||||
spiCommand(spi, addr >> 8);
|
spiCommand(spi, addr >> 8);
|
||||||
spiCommand(spi, addr >> 0);
|
spiCommand(spi, addr >> 0);
|
||||||
spiCommand(spi, 0x00);
|
spiCommand(spi, 0x00);
|
||||||
for (i = 0; i < count; i++)
|
for (i = 0; i < count; i++) {
|
||||||
|
if ((i & 0x3fff) == 0) {
|
||||||
|
printf("\rReading @ %06x / %06x", i, count);
|
||||||
|
fflush(stdout);
|
||||||
|
}
|
||||||
data[i] = spiRx(spi);
|
data[i] = spiRx(spi);
|
||||||
|
}
|
||||||
|
printf("\rReading @ %06x / %06x Done\n", i, count);
|
||||||
|
|
||||||
spiEnd(spi);
|
spiEnd(spi);
|
||||||
return 0;
|
return 0;
|
||||||
@ -644,8 +664,9 @@ int spiWrite(struct ff_spi *spi, uint32_t addr, const uint8_t *data, unsigned in
|
|||||||
// Erase all applicable blocks
|
// Erase all applicable blocks
|
||||||
uint32_t erase_addr;
|
uint32_t erase_addr;
|
||||||
for (erase_addr = 0; erase_addr < count; erase_addr += 32768) {
|
for (erase_addr = 0; erase_addr < count; erase_addr += 32768) {
|
||||||
printf("\rErasing @ %06x", erase_addr);
|
printf("\rErasing @ %06x / %06x", erase_addr, count);
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
|
|
||||||
spiBegin(spi);
|
spiBegin(spi);
|
||||||
spiCommand(spi, 0x06);
|
spiCommand(spi, 0x06);
|
||||||
spiEnd(spi);
|
spiEnd(spi);
|
||||||
@ -659,6 +680,7 @@ int spiWrite(struct ff_spi *spi, uint32_t addr, const uint8_t *data, unsigned in
|
|||||||
|
|
||||||
spi_wait_for_not_busy(spi);
|
spi_wait_for_not_busy(spi);
|
||||||
}
|
}
|
||||||
|
printf(" Done\n");
|
||||||
|
|
||||||
uint8_t write_cmd;
|
uint8_t write_cmd;
|
||||||
switch (spi->type) {
|
switch (spi->type) {
|
||||||
@ -677,9 +699,9 @@ int spiWrite(struct ff_spi *spi, uint32_t addr, const uint8_t *data, unsigned in
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("\n");
|
int total = count;
|
||||||
while (count) {
|
while (count) {
|
||||||
printf("\rProgramming @ %06x", addr);
|
printf("\rProgramming @ %06x / %06x", addr, total);
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
spiBegin(spi);
|
spiBegin(spi);
|
||||||
spiCommand(spi, 0x06);
|
spiCommand(spi, 0x06);
|
||||||
@ -701,7 +723,8 @@ int spiWrite(struct ff_spi *spi, uint32_t addr, const uint8_t *data, unsigned in
|
|||||||
addr += i;
|
addr += i;
|
||||||
spi_wait_for_not_busy(spi);
|
spi_wait_for_not_busy(spi);
|
||||||
}
|
}
|
||||||
printf("\n");
|
printf("\rProgramming @ %06x / %06x", addr, total);
|
||||||
|
printf(" Done\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
2
spi.h
2
spi.h
@ -42,6 +42,7 @@ struct spi_id {
|
|||||||
uint8_t memory_size; // Result from 0x9f
|
uint8_t memory_size; // Result from 0x9f
|
||||||
uint8_t signature; // Result from 0xab
|
uint8_t signature; // Result from 0xab
|
||||||
uint8_t serial[4]; // Result from 0x4b
|
uint8_t serial[4]; // Result from 0x4b
|
||||||
|
int bytes; // -1 if unknown
|
||||||
const char *manufacturer;
|
const char *manufacturer;
|
||||||
const char *model;
|
const char *model;
|
||||||
const char *capacity;
|
const char *capacity;
|
||||||
@ -70,6 +71,7 @@ int spiSetType(struct ff_spi *spi, enum spi_type type);
|
|||||||
int spiRead(struct ff_spi *spi, uint32_t addr, uint8_t *data, unsigned int count);
|
int spiRead(struct ff_spi *spi, uint32_t addr, uint8_t *data, unsigned int count);
|
||||||
|
|
||||||
struct spi_id spiId(struct ff_spi *spi);
|
struct spi_id spiId(struct ff_spi *spi);
|
||||||
|
void spiOverrideSize(struct ff_spi *spi, uint32_t new_size);
|
||||||
|
|
||||||
//int spi_wait_for_not_busy(struct ff_spi *spi);
|
//int spi_wait_for_not_busy(struct ff_spi *spi);
|
||||||
int spiWrite(struct ff_spi *spi, uint32_t addr, const uint8_t *data, unsigned int count);
|
int spiWrite(struct ff_spi *spi, uint32_t addr, const uint8_t *data, unsigned int count);
|
||||||
|
Loading…
Reference in New Issue
Block a user