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:
		
							
								
								
									
										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, "Usage:\n"); | ||||
| 	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"); | ||||
| 	print_program_modes(stream); | ||||
| 	fprintf(stream, "Configuration options:\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, "    -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, "\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_fpga *fpga; | ||||
| 	int peek_offset = 0; | ||||
| 	int spi_flash_bytes = -1; | ||||
| 	uint8_t security_reg; | ||||
| 	uint8_t security_val[256]; | ||||
| 	enum op op = OP_UNKNOWN; | ||||
| @@ -191,7 +193,7 @@ int main(int argc, char **argv) { | ||||
| 		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) { | ||||
|  | ||||
| 		case 'r': | ||||
| @@ -200,6 +202,10 @@ int main(int argc, char **argv) { | ||||
| 			op = OP_FPGA_RESET; | ||||
| 			break; | ||||
|  | ||||
| 		case 'b': | ||||
| 			spi_flash_bytes = strtoul(optarg, NULL, 0); | ||||
| 			break; | ||||
|  | ||||
| 		case 'k': { | ||||
| 			if (op != OP_UNKNOWN) | ||||
| 				return print_usage_error(stdout); | ||||
| @@ -332,6 +338,9 @@ int main(int argc, char **argv) { | ||||
| 	spiSetType(spi, spi_type); | ||||
| 	fpgaReset(fpga); | ||||
|  | ||||
| 	if (spi_flash_bytes != -1) | ||||
| 		spiOverrideSize(spi, spi_flash_bytes); | ||||
|  | ||||
| 	switch (op) { | ||||
| 	case OP_SPI_ID: { | ||||
| 		struct spi_id id = spiId(spi); | ||||
| @@ -366,15 +375,25 @@ int main(int argc, char **argv) { | ||||
| 	} | ||||
|  | ||||
| 	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); | ||||
| 		if (fd == -1) { | ||||
| 			perror("unable to open output file"); | ||||
| 			break; | ||||
| 		} | ||||
| 		uint8_t *bfr = malloc(16777216); | ||||
| 		spiRead(spi, 0, bfr, 16777216); | ||||
| 		if (write(fd, bfr, 16777216) != 16777216) { | ||||
| 			perror("unable to write SPI flash image"); | ||||
| 		uint8_t *bfr = malloc(id.bytes); | ||||
| 		if (!bfr) { | ||||
| 			perror("unable to allocate memory for spi"); | ||||
| 			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; | ||||
| 		} | ||||
| 		close(fd); | ||||
|   | ||||
							
								
								
									
										33
									
								
								spi.c
									
									
									
									
									
								
							
							
						
						
									
										33
									
								
								spi.c
									
									
									
									
									
								
							| @@ -29,6 +29,7 @@ struct ff_spi { | ||||
| 	enum spi_type desired_type; | ||||
| 	struct spi_id id; | ||||
| 	enum ff_spi_quirks quirks; | ||||
| 	int size_override; | ||||
|  | ||||
| 	struct { | ||||
| 		int clk; | ||||
| @@ -457,6 +458,7 @@ static void spi_decode_id(struct ff_spi *spi) { | ||||
| 	spi->id.manufacturer = "unknown"; | ||||
| 	spi->id.model = "unknown"; | ||||
| 	spi->id.capacity = "unknown"; | ||||
| 	spi->id.bytes = -1; // unknown | ||||
|  | ||||
| 	if (spi->id.manufacturer_id == 0xef) { | ||||
| 		spi->id.manufacturer = "Winbond"; | ||||
| @@ -464,6 +466,7 @@ static void spi_decode_id(struct ff_spi *spi) { | ||||
| 		 && (spi->id.memory_size == 0x18)) { | ||||
| 			spi->id.model = "W25Q128JV"; | ||||
| 			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.model = "AT25SF161"; | ||||
| 			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; | ||||
| } | ||||
|  | ||||
| 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) { | ||||
|  | ||||
| 	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 >> 0); | ||||
| 	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); | ||||
| 	} | ||||
| 	printf("\rReading @ %06x / %06x Done\n", i, count); | ||||
|  | ||||
| 	spiEnd(spi); | ||||
| 	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 | ||||
| 	uint32_t erase_addr; | ||||
| 	for (erase_addr = 0; erase_addr < count; erase_addr += 32768) { | ||||
| 		printf("\rErasing @ %06x", erase_addr); | ||||
| 		printf("\rErasing @ %06x / %06x", erase_addr, count); | ||||
| 		fflush(stdout); | ||||
|  | ||||
| 		spiBegin(spi); | ||||
| 		spiCommand(spi, 0x06); | ||||
| 		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); | ||||
| 	} | ||||
| 	printf("  Done\n"); | ||||
|  | ||||
| 	uint8_t write_cmd; | ||||
| 	switch (spi->type) { | ||||
| @@ -677,9 +699,9 @@ int spiWrite(struct ff_spi *spi, uint32_t addr, const uint8_t *data, unsigned in | ||||
| 		return 1; | ||||
| 	} | ||||
|  | ||||
| 	printf("\n"); | ||||
| 	int total = count; | ||||
| 	while (count) { | ||||
| 		printf("\rProgramming @ %06x", addr); | ||||
| 		printf("\rProgramming @ %06x / %06x", addr, total); | ||||
| 		fflush(stdout); | ||||
| 		spiBegin(spi); | ||||
| 		spiCommand(spi, 0x06); | ||||
| @@ -701,7 +723,8 @@ int spiWrite(struct ff_spi *spi, uint32_t addr, const uint8_t *data, unsigned in | ||||
| 		addr += i; | ||||
| 		spi_wait_for_not_busy(spi); | ||||
| 	} | ||||
| 	printf("\n"); | ||||
| 	printf("\rProgramming @ %06x / %06x", addr, total); | ||||
| 	printf("  Done\n"); | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
|   | ||||
							
								
								
									
										2
									
								
								spi.h
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								spi.h
									
									
									
									
									
								
							| @@ -42,6 +42,7 @@ struct spi_id { | ||||
| 	uint8_t memory_size;		// Result from 0x9f | ||||
| 	uint8_t signature;		// Result from 0xab | ||||
| 	uint8_t serial[4];		// Result from 0x4b | ||||
| 	int bytes;			// -1 if unknown | ||||
| 	const char *manufacturer; | ||||
| 	const char *model; | ||||
| 	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); | ||||
|  | ||||
| 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 spiWrite(struct ff_spi *spi, uint32_t addr, const uint8_t *data, unsigned int count); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user