fomu-flash: add -l (rom) option to load a rom
				
					
				
			This can be used to quickly develop a bootloader, or other boot rom for an ICE40. Signed-off-by: Sean Cross <sean@xobs.io>
This commit is contained in:
		
							
								
								
									
										71
									
								
								fomu-flash.c
									
									
									
									
									
								
							
							
						
						
									
										71
									
								
								fomu-flash.c
									
									
									
									
									
								
							@@ -10,6 +10,7 @@
 | 
				
			|||||||
#include "rpi.h"
 | 
					#include "rpi.h"
 | 
				
			||||||
#include "spi.h"
 | 
					#include "spi.h"
 | 
				
			||||||
#include "fpga.h"
 | 
					#include "fpga.h"
 | 
				
			||||||
 | 
					#include "ice40.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define S_MOSI 10
 | 
					#define S_MOSI 10
 | 
				
			||||||
#define S_MISO 9
 | 
					#define S_MISO 9
 | 
				
			||||||
@@ -24,6 +25,15 @@
 | 
				
			|||||||
static unsigned int F_RESET = 27;
 | 
					static unsigned int F_RESET = 27;
 | 
				
			||||||
#define F_DONE 17
 | 
					#define F_DONE 17
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int spi_irw_readb(void *data) {
 | 
				
			||||||
 | 
						return spiRx(data);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int spi_irw_writeb(void *data, uint8_t b) {
 | 
				
			||||||
 | 
						spiTx(data, b);
 | 
				
			||||||
 | 
						return b;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static inline int isprint(int c)
 | 
					static inline int isprint(int c)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	return c > 32 && c < 127;
 | 
						return c > 32 && c < 127;
 | 
				
			||||||
@@ -120,7 +130,8 @@ static int print_program_modes(FILE *stream) {
 | 
				
			|||||||
	fprintf(stream, "    -r        Reset the FPGA and have it boot from SPI\n");
 | 
						fprintf(stream, "    -r        Reset the FPGA and have it boot from SPI\n");
 | 
				
			||||||
	fprintf(stream, "    -i        Print out the SPI ID code\n");
 | 
						fprintf(stream, "    -i        Print out the SPI ID code\n");
 | 
				
			||||||
	fprintf(stream, "    -p offset Peek at 256 bytes of SPI flash at the specified offset\n");
 | 
						fprintf(stream, "    -p offset Peek at 256 bytes of SPI flash at the specified offset\n");
 | 
				
			||||||
	fprintf(stream, "    -f bin    Load this binary directly into the FPGA\n");
 | 
						fprintf(stream, "    -f bin    Load this bitstream directly into the FPGA\n");
 | 
				
			||||||
 | 
						fprintf(stream, "    -l rom    Replace the ROM in the bitstream with this file\n");
 | 
				
			||||||
	fprintf(stream, "    -w bin    Write this binary into the SPI flash chip\n");
 | 
						fprintf(stream, "    -w bin    Write this binary into the SPI flash chip\n");
 | 
				
			||||||
	fprintf(stream, "    -v bin    Verify the SPI flash contains this data\n");
 | 
						fprintf(stream, "    -v bin    Verify the SPI flash contains this data\n");
 | 
				
			||||||
	fprintf(stream, "    -s out    Save the SPI flash contents to this file\n");
 | 
						fprintf(stream, "    -s out    Save the SPI flash contents to this file\n");
 | 
				
			||||||
@@ -131,10 +142,13 @@ static int print_program_modes(FILE *stream) {
 | 
				
			|||||||
static int print_help(FILE *stream, const char *progname) {
 | 
					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 bitstream] | \n", progname);
 | 
				
			||||||
 | 
						fprintf(stream, "%15s            [-w bin] | [-v bin] | [-s out] | [-k n[:f]])\n", "");
 | 
				
			||||||
	fprintf(stream, "                [-g pinspec] [-t spitype] [-b bytes]\n");
 | 
						fprintf(stream, "                [-g pinspec] [-t spitype] [-b bytes]\n");
 | 
				
			||||||
 | 
						fprintf(stream, "\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, "\n");
 | 
				
			||||||
	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");
 | 
				
			||||||
@@ -169,6 +183,7 @@ int main(int argc, char **argv) {
 | 
				
			|||||||
	uint8_t security_val[256];
 | 
						uint8_t security_val[256];
 | 
				
			||||||
	enum op op = OP_UNKNOWN;
 | 
						enum op op = OP_UNKNOWN;
 | 
				
			||||||
	enum spi_type spi_type = ST_SINGLE;
 | 
						enum spi_type spi_type = ST_SINGLE;
 | 
				
			||||||
 | 
						struct irw_file *replacement_rom = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (gpioInitialise() < 0) {
 | 
						if (gpioInitialise() < 0) {
 | 
				
			||||||
		fprintf(stderr, "Unable to initialize GPIO\n");
 | 
							fprintf(stderr, "Unable to initialize GPIO\n");
 | 
				
			||||||
@@ -199,7 +214,7 @@ int main(int argc, char **argv) {
 | 
				
			|||||||
	fpgaSetPin(fpga, FP_DONE, F_DONE);
 | 
						fpgaSetPin(fpga, FP_DONE, F_DONE);
 | 
				
			||||||
	fpgaSetPin(fpga, FP_CS, S_CE0);
 | 
						fpgaSetPin(fpga, FP_CS, S_CE0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	while ((opt = getopt(argc, argv, "hip:rf:b: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:l:")) != -1) {
 | 
				
			||||||
		switch (opt) {
 | 
							switch (opt) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		case 'r':
 | 
							case 'r':
 | 
				
			||||||
@@ -212,6 +227,14 @@ int main(int argc, char **argv) {
 | 
				
			|||||||
			spi_flash_bytes = strtoul(optarg, NULL, 0);
 | 
								spi_flash_bytes = strtoul(optarg, NULL, 0);
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							case 'l':
 | 
				
			||||||
 | 
								replacement_rom = irw_open(optarg, "r");
 | 
				
			||||||
 | 
								if (!replacement_rom) {
 | 
				
			||||||
 | 
									perror("couldn't open replacement rom file");
 | 
				
			||||||
 | 
									return 10;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		case 'k': {
 | 
							case 'k': {
 | 
				
			||||||
			if (op != OP_UNKNOWN)
 | 
								if (op != OP_UNKNOWN)
 | 
				
			||||||
				return print_usage_error(stdout);
 | 
									return print_usage_error(stdout);
 | 
				
			||||||
@@ -478,32 +501,42 @@ offset, file_src[offset], spi_src[offset]);
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	case OP_FPGA_BOOT: {
 | 
						case OP_FPGA_BOOT: {
 | 
				
			||||||
 | 
							int count;
 | 
				
			||||||
		spiHold(spi);
 | 
							spiHold(spi);
 | 
				
			||||||
		spiSwapTxRx(spi);
 | 
							spiSwapTxRx(spi);
 | 
				
			||||||
		fpgaResetSlave(fpga);
 | 
							fpgaResetSlave(fpga);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		fprintf(stderr, "FPGA Done? %d\n", fpgaDone(fpga));
 | 
							fprintf(stderr, "FPGA Done? %d\n", fpgaDone(fpga));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		int fd = open(op_filename, O_RDONLY);
 | 
					 | 
				
			||||||
		if (fd == -1) {
 | 
					 | 
				
			||||||
			perror("unable to open fpga bitstream");
 | 
					 | 
				
			||||||
			break;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		spiBegin(spi);
 | 
							spiBegin(spi);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		uint8_t bfr[32768];
 | 
							if (replacement_rom) {
 | 
				
			||||||
		int count;
 | 
								IRW_FILE *bitstream = irw_open(op_filename, "r");
 | 
				
			||||||
		while ((count = read(fd, bfr, sizeof(bfr))) > 0) {
 | 
								if (!bitstream) {
 | 
				
			||||||
			int i;
 | 
									perror("unable to open fpga bitstream");
 | 
				
			||||||
			for (i = 0; i < count; i++)
 | 
									break;
 | 
				
			||||||
				spiTx(spi, bfr[i]);
 | 
								}
 | 
				
			||||||
 | 
								IRW_FILE *spidev = irw_open_fake(spi, spi_irw_readb, spi_irw_writeb);
 | 
				
			||||||
 | 
								ice40_patch(bitstream, replacement_rom, spidev, 8192);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		if (count < 0) {
 | 
							else {
 | 
				
			||||||
			perror("unable to read from fpga bitstream file");
 | 
								uint8_t bfr[32768];
 | 
				
			||||||
			break;
 | 
								int fd = open(op_filename, O_RDONLY);
 | 
				
			||||||
 | 
								if (fd == -1) {
 | 
				
			||||||
 | 
									perror("unable to open fpga bitstream");
 | 
				
			||||||
 | 
									break;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								while ((count = read(fd, bfr, sizeof(bfr))) > 0) {
 | 
				
			||||||
 | 
									int i;
 | 
				
			||||||
 | 
									for (i = 0; i < count; i++)
 | 
				
			||||||
 | 
										spiTx(spi, bfr[i]);
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								if (count < 0) {
 | 
				
			||||||
 | 
									perror("unable to read from fpga bitstream file");
 | 
				
			||||||
 | 
									break;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								close(fd);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		close(fd);
 | 
					 | 
				
			||||||
		for (count = 0; count < 500; count++)
 | 
							for (count = 0; count < 500; count++)
 | 
				
			||||||
			spiTx(spi, 0xff);
 | 
								spiTx(spi, 0xff);
 | 
				
			||||||
		fprintf(stderr, "FPGA Done? %d\n", fpgaDone(fpga));
 | 
							fprintf(stderr, "FPGA Done? %d\n", fpgaDone(fpga));
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user