diff options
| author | Timothy Pearson <kb9vqf@pearsoncomputing.net> | 2012-10-04 17:03:18 -0500 | 
|---|---|---|
| committer | Timothy Pearson <kb9vqf@pearsoncomputing.net> | 2012-10-04 17:03:18 -0500 | 
| commit | 9c6d284d49dd8849e3c0ebb614df72aa96f910f9 (patch) | |
| tree | 8ba1bea20903f5da425b102708c3af2c5b1d334c /fpga/xilinx/programmer | |
| parent | 7643298424eaca1c10dd7ed577b3b77246bbf441 (diff) | |
| download | ulab-9c6d284d49dd8849e3c0ebb614df72aa96f910f9.tar.gz ulab-9c6d284d49dd8849e3c0ebb614df72aa96f910f9.zip | |
Initial rpi jtag support
Diffstat (limited to 'fpga/xilinx/programmer')
| -rw-r--r-- | fpga/xilinx/programmer/svfplayer/xsvf-rpi.c | 199 | 
1 files changed, 93 insertions, 106 deletions
| diff --git a/fpga/xilinx/programmer/svfplayer/xsvf-rpi.c b/fpga/xilinx/programmer/svfplayer/xsvf-rpi.c index c46e4d7..45d8c78 100644 --- a/fpga/xilinx/programmer/svfplayer/xsvf-rpi.c +++ b/fpga/xilinx/programmer/svfplayer/xsvf-rpi.c @@ -1,6 +1,7 @@  /*   *  Lib(X)SVF  -  A library for implementing SVF and XSVF JTAG players   * + *  Copyright (C) 2012  Timothy Pearson <kb9vqf@pearsoncomputing.net>   *  Copyright (C) 2009  RIEGL Research ForschungsGmbH   *  Copyright (C) 2009  Clifford Wolf <clifford@clifford.at>   *   @@ -30,104 +31,127 @@  /** BEGIN: Low-Level I/O Implementation **/ -#ifdef XSVFTOOL_RLMS_VLINE - -// Simple example with MPC8349E GPIO pins -// (RIEGL LMS V-Line motherboard) +// Raspberry PI GPIO driver +// TMS: 18 +// TDI: 23 +// TDO: 24 +// TCK: 25  #include <sys/types.h>  #include <sys/stat.h>  #include <sys/mman.h>  #include <fcntl.h> -#define IO_PORT_ADDR 0xE0000C00 +#define BCM2708_PERI_BASE	0x20000000 +#define GPIO_BASE		(BCM2708_PERI_BASE + 0x200000) /* GPIO controller */ -struct io_layout { -	unsigned long tdi:1; -	unsigned long tdo:1; -	unsigned long tms:1; -	unsigned long tck:1; -	unsigned long reserved:28; -}; +#define PAGE_SIZE (4*1024) +#define BLOCK_SIZE (4*1024) + +int  mem_fd; +char *gpio_mem, *gpio_map; +char *spi0_mem, *spi0_map; + +// I/O access +volatile unsigned *gpio; -static volatile struct io_layout *io_direction; -static volatile struct io_layout *io_opendrain; -static volatile struct io_layout *io_data; +// GPIO setup macros. Always use INP_GPIO(x) before using OUT_GPIO(x) or SET_GPIO_ALT(x,y) +#define INP_GPIO(g) *(gpio+((g)/10)) &= ~(7<<(((g)%10)*3)) +#define OUT_GPIO(g) *(gpio+((g)/10)) |=  (1<<(((g)%10)*3)) +#define SET_GPIO_ALT(g,a) *(gpio+(((g)/10))) |= (((a)<=3?(a)+4:(a)==4?3:2)<<(((g)%10)*3)) + +#define GPIO_SET *(gpio+7)  // sets   bits which are 1 ignores bits which are 0 +#define GPIO_CLR *(gpio+10) // clears bits which are 1 ignores bits which are 0 + +#define GPLEV0 *(gpio+13)  static void io_setup(void)  { -	/* open /dev/mem device file */ -	int fd = open("/dev/mem", O_RDWR); -	if (fd < 0) { -		fprintf(stderr, "Can't open /dev/mem: %s\n", strerror(errno)); -		exit(1); +	/* open /dev/mem */ +	if ((mem_fd = open("/dev/mem", O_RDWR|O_SYNC) ) < 0) { +		printf("can't open /dev/mem \n"); +		exit (-1);  	} - -	/* calculate offsets to page and within page */ -	unsigned long psize = getpagesize(); -	unsigned long off_inpage = IO_PORT_ADDR % psize; -	unsigned long off_topage = IO_PORT_ADDR - off_inpage; -	unsigned long mapsize = off_inpage + sizeof(struct io_layout) * 3; - -	/* map it into logical memory */ -	void *io_addr_map = mmap(0, mapsize, PROT_WRITE, MAP_SHARED, fd, off_topage); -	if (io_addr_map == MAP_FAILED) { -		fprintf(stderr, "Can't map physical memory: %s\n", strerror(errno)); -		exit(1); +	 +	/* mmap GPIO */ +	 +	// Allocate MAP block +	if ((gpio_mem = malloc(BLOCK_SIZE + (PAGE_SIZE-1))) == NULL) { +		printf("allocation error \n"); +		exit (-1);  	} +	 +	// Make sure pointer is on 4K boundary +	if ((unsigned long)gpio_mem % PAGE_SIZE) { +		gpio_mem += PAGE_SIZE - ((unsigned long)gpio_mem % PAGE_SIZE); +	} +	 +	// Now map it +	gpio_map = (unsigned char *)mmap( +		(caddr_t)gpio_mem, +		BLOCK_SIZE, +		PROT_READ|PROT_WRITE, +		MAP_SHARED|MAP_FIXED, +		mem_fd, +		GPIO_BASE +	); +	 +	if ((long)gpio_map < 0) { +		printf("mmap error %d\n", (int)gpio_map); +		exit (-1); +	} +	 +	// Always use volatile pointer! +	gpio = (volatile unsigned *)gpio_map; + +	// Set GPIO pins 18, 23, 25 to output +	INP_GPIO(18); // must use INP_GPIO before we can use OUT_GPIO +	INP_GPIO(23); // must use INP_GPIO before we can use OUT_GPIO +	INP_GPIO(25); // must use INP_GPIO before we can use OUT_GPIO -	/* calculate register addresses */ -	io_direction = io_addr_map + off_inpage; -	io_opendrain = io_addr_map + off_inpage + 4; -	io_data = io_addr_map + off_inpage + 8; - -	/* set direction reg */ -	io_direction->tms = 1; -	io_direction->tck = 1; -	io_direction->tdo = 0; -	io_direction->tdi = 1; - -	/* set open drain reg */ -	io_opendrain->tms = 0; -	io_opendrain->tck = 0; -	io_opendrain->tdo = 0; -	io_opendrain->tdi = 0; - -#ifdef HAVE_TRST -	/* for boards with TRST, must be driven high */ -	io_data->trst = 1; -	io_direction->trst = 1; -	io_opendrain->trst = 0; -#endif +	OUT_GPIO(18); // output +	OUT_GPIO(23); // output +	INP_GPIO(24); // input +	OUT_GPIO(25); // output  }  static void io_shutdown(void)  { -	/* set all to z-state */ -	io_direction->tms = 0; -	io_direction->tck = 0; -	io_direction->tdo = 0; -	io_direction->tdi = 0; - -#ifdef HAVE_TRST -	/* for boards with TRST, assuming there is a pull-down resistor */ -	io_direction->trst = 0; -#endif +	INP_GPIO(18); +	INP_GPIO(23); +	INP_GPIO(24); +	INP_GPIO(25);  }  static void io_tms(int val)  { -	io_data->tms = val; +	if (val) { +		GPIO_SET = 1<<18; +	} +	else { +		GPIO_CLR = 1<<18; +	}  }  static void io_tdi(int val)  { -	io_data->tdi = val; +	if (val) { +		GPIO_SET = 1<<23; +	} +	else { +		GPIO_CLR = 1<<23; +	}  }  static void io_tck(int val)  { -	io_data->tck = val; +	if (val) { +		GPIO_SET = 1<<25; +	} +	else { +		GPIO_CLR = 1<<25; +	} +  	// usleep(1);  } @@ -143,46 +167,9 @@ static void io_trst(int val)  static int io_tdo()  { -	return io_data->tdo ? 1 : 0; -} - -#else - -static void io_setup(void) -{ -} - -static void io_shutdown(void) -{ +	return (GPLEV0 & (1<<24)) ? 1 : 0;  } -static void io_tms(int val) -{ -} - -static void io_tdi(int val) -{ -} - -static void io_tck(int val) -{ -} - -static void io_sck(int val) -{ -} - -static void io_trst(int val) -{ -} - -static int io_tdo() -{ -	return -1; -} - -#endif -  /** END: Low-Level I/O Implementation **/ | 
