diff options
Diffstat (limited to 'fpga/interface/beaglebone_black')
4 files changed, 442 insertions, 0 deletions
| diff --git a/fpga/interface/beaglebone_black/gpmc/test/BB-ULAB-00A0.dts b/fpga/interface/beaglebone_black/gpmc/test/BB-ULAB-00A0.dts new file mode 100644 index 0000000..e146171 --- /dev/null +++ b/fpga/interface/beaglebone_black/gpmc/test/BB-ULAB-00A0.dts @@ -0,0 +1,152 @@ +/* + *       Copyright (C) 2013 Tom King <ka6sox@gmail.com> + *		 (C) 2013 Ian McMahon <ian.mcmahon@prototechnical.com> + *		 (C) 2014 Timothy Pearson <kb9vqf@pearsoncomputing.net> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +/dts-v1/; +/plugin/; + +/ { +	compatible = "ti,beaglebone", "ti,beaglebone-black"; +	 +	/* identification */ +	manufacturer = "Raptor Engineering"; +	board-name = "Universal Laboratory Debug Control Interface"; +	model = "ULABCTL001"; +	part-number = "BB-BONE-ULAB"; +	version = "0001"; +	 +	/* state the resources this cape uses */ +	exclusive-use = +		/* the pin header uses */ +		"P8.45",	/* GPMC: gpmc_a0 */ +		"P8.46",	/* GPMC: gpmc_a1 */ +		"P9.14",	/* GPMC: gpmc_a2 */ +		"P8.44",	/* GPMC: gpmc_a3 */ +		"P8.41",	/* GPMC: gpmc_a4 */ +		"P8.42",	/* GPMC: gpmc_a5 */ +		"P8.39",	/* GPMC: gpmc_a6 */ +		"P8.40",	/* GPMC: gpmc_a7 */ +		"P8.27",	/* GPMC: gpmc_a8 */ +		"P8.29",	/* GPMC: gpmc_a9 */ +		"P8.28",	/* GPMC: gpmc_a10 */ +		"P8.30",	/* GPMC: gpmc_a11 */ +		"P8.37",	/* GPMC: gpmc_a12 */ +		"P8.38",	/* GPMC: gpmc_a13 */ +		"P8.36",	/* GPMC: gpmc_a14 */ +		"P8.34",	/* GPMC: gpmc_a15 */ +		"P8.35",	/* GPMC: gpmc_a16 */ +		"P8.33",	/* GPMC: gpmc_a17 */ +		"P8.31",	/* GPMC: gpmc_a18 */ +		"P8.32",	/* GPMC: gpmc_a19 */ + +		"P8.25",	/* GPMC: gpmc_ad0 */ +		"P8.24",	/* GPMC: gpmc_ad1 */ +		"P8.5",		/* GPMC: gpmc_ad2 */ +		"P8.6",		/* GPMC: gpmc_ad3 */ +		"P8.23",	/* GPMC: gpmc_ad4 */ +		"P8.22",	/* GPMC: gpmc_ad5 */ +		"P8.3",		/* GPMC: gpmc_ad6 */ +		"P8.4", 	/* GPMC: gpmc_ad7 */ + +		"P8.7",		/* GPMC: gpmc_advn_ale */ +		"P8.8",		/* GPMC: gpmc_oen_ren */ +		"P8.10",	/* GPMC: gpmc_wen */ +	 +		"P9.11",	/* GPIO: gpio0[30] */ +		"P9.13",	/* GPIO: gpio0[31] */ +		"P9.21",	/* GPIO: gpio0[3] */ +		"P9.22",	/* GPIO: gpio0[2] */ + +		"P8.43",	/* GPIO: boot select */ + +		/* the hardware IP this cape uses */ +		"GPMC"; + +	fragment@0 { +		target = <&am33xx_pinmux>; +		__overlay__ { +			bb_gpmc_pins: pinmux_bb_gpmc_pins { +				pinctrl-single,pins = < + +				/* address bus */ +				0x0a0 0x01  /* gpmc_a0, OUTPUT_PULLDOWN | MODE1 */ +				0x0a4 0x01  /* gpmc_a1, OUTPUT_PULLDOWN | MODE1 */ +				0x048 0x00  /* gpmc_a2, OUTPUT_PULLDOWN | MODE0 */ +				0x0ac 0x01  /* gpmc_a3, OUTPUT_PULLDOWN | MODE1 */ +				0x0b0 0x01  /* gpmc_a4, OUTPUT_PULLDOWN | MODE1 */ +				0x0b4 0x01  /* gpmc_a5, OUTPUT_PULLDOWN | MODE1 */ +				0x0b8 0x01  /* gpmc_a6, OUTPUT_PULLDOWN | MODE1 */ +				0x0bc 0x01  /* gpmc_a7, OUTPUT_PULLDOWN | MODE1 */ +				0x0e0 0x01  /* gpmc_a8, OUTPUT_PULLDOWN | MODE1 */ +				0x0e4 0x01  /* gpmc_a9, OUTPUT_PULLDOWN | MODE1 */ +				0x0e8 0x01  /* gpmc_a10, OUTPUT_PULLDOWN | MODE1 */ +				0x0ec 0x01  /* gpmc_a11, OUTPUT_PULLDOWN | MODE1 */ +				0x0c0 0x01  /* gpmc_a12, OUTPUT_PULLDOWN | MODE1 */ +				0x0c4 0x01  /* gpmc_a13, OUTPUT_PULLDOWN | MODE1 */ +				0x0c8 0x01  /* gpmc_a14, OUTPUT_PULLDOWN | MODE1 */ +				0x0cc 0x01  /* gpmc_a15, OUTPUT_PULLDOWN | MODE1 */ +				0x0d0 0x01  /* gpmc_a16, OUTPUT_PULLDOWN | MODE1 */ +				0x0d4 0x01  /* gpmc_a17, OUTPUT_PULLDOWN | MODE1 */ +				0x0d8 0x01  /* gpmc_a18, OUTPUT_PULLDOWN | MODE1 */ +				0x0dc 0x01  /* gpmc_a19, OUTPUT_PULLDOWN | MODE1 */ + +				/* address/data muxed bus */ +				0x000 0x30  /* gpmc_ad0, INPUT_PULLUP | MODE0 */ +				0x004 0x30  /* gpmc_ad1, INPUT_PULLUP | MODE0 */ +				0x008 0x30  /* gpmc_ad2, INPUT_PULLUP | MODE0 */ +				0x00c 0x30  /* gpmc_ad3, INPUT_PULLUP | MODE0 */ +				0x010 0x30  /* gpmc_ad4, INPUT_PULLUP | MODE0 */ +				0x014 0x30  /* gpmc_ad5, INPUT_PULLUP | MODE0 */ +				0x018 0x30  /* gpmc_ad6, INPUT_PULLUP | MODE0 */ +				0x01c 0x30  /* gpmc_ad7, INPUT_PULLUP | MODE0 */ + +				/* control */ +				0x090 0x10  /* gpmc_advn_ale, OUTPUT_PULLUP | MODE0 */ +				0x094 0x10  /* gpmc_oen_ren, OUTPUT_PULLUP | MODE0 */ +				0x098 0x10  /* gpmc_wen, OUTPUT_PULLUP | MODE0 */ + +				/* gpio */ +				0x070 0x07  /* gpio0[30], OUTPUT_PULLDOWN | MODE7 */ +				0x074 0x07  /* gpio0[31], OUTPUT_PULLDOWN | MODE7 */ +				0x154 0x27  /* gpio0[3], INPUT_PULLDOWN | MODE7 */ +				0x150 0x07  /* gpio0[2], OUTPUT_PULLDOWN | MODE7 */ + +				>; +			}; +		}; +	}; +	 +	fragment@1 { +		target = <&gpmc>; +		depth = <1>;    /* only create devices on depth 1 */ +	 +		/* stupid warnings */ +		#address-cells = <1>; +		#size-cells = <1>; +	 +		__overlay__ { +			status = "okay"; +	 +			#address-cells = <2>; +			#size-cells = <1>; +	 +			pinctrl-names = "default"; +			pinctrl-0 = <&bb_gpmc_pins>; +	 +			/* chip select ranges */ +			ranges = <0 0 0x10000000 0x02000000>; /* CS0 @addr 0x01000000, size 0x02000000 */ +	 +			sram@0 { +				compatible = "raptorengineering,ulab","sram"; +				address-cells = <1>; +				size-cells = <1>; +				bank-width = <1>; +			}; +		}; +	}; +}; diff --git a/fpga/interface/beaglebone_black/gpmc/test/Makefile b/fpga/interface/beaglebone_black/gpmc/test/Makefile new file mode 100644 index 0000000..fc42856 --- /dev/null +++ b/fpga/interface/beaglebone_black/gpmc/test/Makefile @@ -0,0 +1,47 @@ +# Copyright (C) 2014 Timothy Pearson +#  +# Permission to use, copy, modify, and/or distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +#  +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +AR = ar +RANLIB = ranlib +CC = gcc + +CFLAGS += -Wall -Os -ggdb -MD +#CFLAGS += -Wextra -Wno-unused-parameter -Werror + +help: +	@echo "" +	@echo "Usage:" +	@echo "" +	@echo "  $(MAKE) bbb-gpmc-test" +	@echo "                .... build bbb-gpmc-test" +	@echo "" +	@echo "  $(MAKE) all" +	@echo "                .... build everything" +	@echo "" +	@echo "  $(MAKE) install" +	@echo "                .... install everything in /usr/" +	@echo "" + +all: bbb-gpmc-test + +install: all +	install -Dt /usr/bin/ bbb-gpmc-test + +bbb-gpmc-test: bbb-gpmc-test.o + +clean: +	rm -f bbb-gpmc-test.o + +-include *.d + diff --git a/fpga/interface/beaglebone_black/gpmc/test/NOTES b/fpga/interface/beaglebone_black/gpmc/test/NOTES new file mode 100644 index 0000000..11a075f --- /dev/null +++ b/fpga/interface/beaglebone_black/gpmc/test/NOTES @@ -0,0 +1,3 @@ +Disable eMMC in uEnv.txt +Comment out eMMC block in /boot/dtbs/am335x-boneblack.dts (mmc@481d8000) +Compile and install uLab cape (BB-ULAB-00A0.dts) in /lib/firmware, then load it via the cape manager diff --git a/fpga/interface/beaglebone_black/gpmc/test/bbb-gpmc-test.c b/fpga/interface/beaglebone_black/gpmc/test/bbb-gpmc-test.c new file mode 100644 index 0000000..9b17634 --- /dev/null +++ b/fpga/interface/beaglebone_black/gpmc/test/bbb-gpmc-test.c @@ -0,0 +1,240 @@ +/* + *  bbb-gpmc-test + * + *  Copyright (C) 2014  Timothy Pearson <kb9vqf@pearsoncomputing.net> (Beaglebone Black) + * + *  Permission to use, copy, modify, and/or distribute this software for any + *  purpose with or without fee is hereby granted, provided that the above + *  copyright notice and this permission notice appear in all copies. + * + *  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + *  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + *  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + *  ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + *  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + *  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + *  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + */ + +#include <sys/time.h> +#include <unistd.h> +#include <string.h> +#include <stdlib.h> +#include <stdio.h> +#include <errno.h> + + +/** BEGIN: Low-Level I/O Implementation **/ + +// Beaglebone Black GPMC driver + +#include <sys/types.h> +#include <sys/stat.h> +#include <sys/mman.h> +#include <fcntl.h> + +#define MEMORY_SPACE_ADDRESS_BITS 15 + +#define GPMC_BASE 0x50000000 +#define GPMC_REGLEN 0x10000000 + +#define GPMC_CHIPSELECTCONFIGDISPLACEMENT (0x30 / 4) + +#define GPMC_CONFIG (0x50 / 4) +#define GPMC_CONFIG1 (0x60 / 4) +#define GPMC_CONFIG2 (0x64 / 4) +#define GPMC_CONFIG3 (0x68 / 4) +#define GPMC_CONFIG4 (0x6c / 4) +#define GPMC_CONFIG5 (0x70 / 4) +#define GPMC_CONFIG6 (0x74 / 4) +#define GPMC_CONFIG7 (0x78 / 4) + +#define MEMORY_SIZE (1 << MEMORY_SPACE_ADDRESS_BITS) + +int mem_fd = 0; +int gpmc_mem_fd = 0; +char *gpio_mem, *gpio_map, *gpmc_map; + +// I/O access +static volatile unsigned int *gpio = NULL; +static volatile unsigned char *gpio_char = NULL; +static volatile unsigned int *gpmc = NULL; + +static void gpmc_mapregisters() +{ +	/* open /dev/mem */ +	if ((gpmc_mem_fd = open("/dev/mem", O_RDWR|O_SYNC) ) < 0) { +		printf("can't open /dev/mem \n"); +		exit (-1); +	} + +	/* mmap GPMC */ +	gpmc_map = (char *)mmap( +		0, +		GPMC_REGLEN, +		PROT_READ|PROT_WRITE, +		MAP_SHARED, +		gpmc_mem_fd, +		GPMC_BASE +	); + +	if (gpmc_map == MAP_FAILED) { +		printf("mmap error %d\n", (int)gpmc_map); +		exit (-1); +	} + +	// Always use volatile pointer! +	gpmc = (volatile unsigned *)gpmc_map; +} + +static void gpmc_unmapregisters() +{ +	munmap((void*) gpmc, GPMC_REGLEN); +	if (gpmc_mem_fd != -1) { +		close(gpmc_mem_fd); +	} +} + +static void gpmc_setup(void) +{ +	// WARNING: The GPMC runs at the L3 clock frequency! +	// It is not well documented, but that frequency seems to be 200MHz on the AM335x series of chips + +	gpmc_mapregisters(); + +	if (gpmc != NULL) { +		int chipselect = 0; +		int displacement = GPMC_CHIPSELECTCONFIGDISPLACEMENT * chipselect; + +		// disable before playing with the registers +		*(gpmc + displacement + GPMC_CONFIG7) = 0x00000000; + +		*(gpmc + displacement + GPMC_CONFIG)  = 0x00000000; // Unlimited address space +		*(gpmc + displacement + GPMC_CONFIG1) = 0x00000000; // No burst, async, 8-bit, non multiplexed + +// 		// 200MHz compatible SRAM device +// 		*(gpmc + displacement + GPMC_CONFIG2) = 0x00000800; // Assert CS on fclk 0, deassert CS on fclk 8 +// 		*(gpmc + displacement + GPMC_CONFIG3) = 0x00000200; // Assert ADV on fclk0, deassert ADV on fclk2 +// 		*(gpmc + displacement + GPMC_CONFIG4) = 0x06020802; // Assert WE on fclk2, deassert WE on fclk6, assert OE on fclk2, deassert OE on fclk8 +// 		*(gpmc + displacement + GPMC_CONFIG5) = 0x00060808; // Data valid on fclk 6, cycle time 8 fclks + +		// 100MHz compatible SRAM device +		*(gpmc + displacement + GPMC_CONFIG2) = 0x00001000; // Assert CS on fclk0, deassert CS on fclk16 +		*(gpmc + displacement + GPMC_CONFIG3) = 0x00000400; // Assert ADV on fclk 0, deassert ADV on fclk 4 +		*(gpmc + displacement + GPMC_CONFIG4) = 0x0c041004; // Assert WE on fclk4, deassert WE on fclk12, assert OE on fclk4, deassert OE on fclk16 +		*(gpmc + displacement + GPMC_CONFIG5) = 0x000c1010; // Data valid on fclk 12, cycle time 16 fclks + +		*(gpmc + displacement + GPMC_CONFIG6) = 0x00000000; // No back to back cycle restrictions +		*(gpmc + displacement + GPMC_CONFIG7) = 0x00000e50; // CS0: Set base address 0x10000000, 32MB region, and enable CS + +		gpmc_unmapregisters(); +	} +} + +static void io_setup(void) +{ +	printf("sizeof int:\t%d\n", sizeof(int)); + +	/* open /dev/mem */ +	if ((mem_fd = open("/dev/mem", O_RDWR|O_SYNC) ) < 0) { +		printf("can't open /dev/mem \n"); +		exit (-1); +	} + +	/* mmap GPIO */ +	gpio_map = (char *)mmap( +		0, +		MEMORY_SIZE, +		PROT_READ|PROT_WRITE, +		MAP_SHARED, +		mem_fd, +		0x10000000 +	); + +	if (gpio_map == MAP_FAILED) { +		printf("mmap error %d\n", (int)gpio_map); +		exit (-1); +	} + +	// Always use volatile pointer! +	gpio = (volatile unsigned *)gpio_map; +	gpio_char = (volatile unsigned char *)gpio_map; + +	// Select a test from the following blocks of code... + +// 	// DEBUG ONLY +// 	// Clear out the mapped memory +// 	int i; +// 	for (i=0;i<0x3ff; i++) { +// 		*(gpio + i) = 0x00000000; +// 	} + +	// DEBUG ONLY +	// Fill the mapped memory with a test pattern +// 	int j; +// 	for (j=0;j<0x00001000; j++) { +// 		*(gpio + j) = j; +// 	} +// 	int j; +// 	for (j=0;j<0x3ff; j++) { +// 		*(gpio + j) = j; +// 	} +	int j; +	for (j=0;j<MEMORY_SIZE; j++) { +		*(gpio_char + j) = ((unsigned char)j); +	} + +	// DEBUG ONLY +	// Prints the contents of the mapped memory +	int k; +	for (k=0;k<(MEMORY_SIZE/4); k++) { +		printf("0x%08x\t%08x\n", k, *(gpio + k)); +	} +	fflush(stdout); + +// 	// DEBUG ONLY +// 	// Excercise the memory space +// 	int l; +// 	while (1) { +// 		for (l=0;l<(MEMORY_SIZE/4); l++) { +// 			k = *(gpio + l); +// 		} +// 	} + +// 	while (1) { +// 		printf("0x%08x\t0x%08x\t0x%08x\t0x%08x\r", *(gpio + 0), *(gpio + 1), *(gpio + 2), *(gpio + 3)); +// 		usleep(1); +// 	} + +// 	while (1) { +// 		printf("0x%08x\t0x%08x\t0x%08x\t0x%08x\r", *(gpio + 3), *(gpio + 2), *(gpio + 1), *(gpio + 0)); +// 		usleep(1); +// 	} + +// 	printf("0x%02x\t0x%02x\t0x%02x\t0x%02x\t0x%02x\t0x%02x\t0x%02x\t0x%02x\n\r", *(gpio_char + 0), *(gpio_char + 0), *(gpio_char + 0), *(gpio_char + 0), *(gpio_char + 0), *(gpio_char + 0), *(gpio_char + 0), *(gpio_char + 0)); +//  +	while (1) { +//		printf("0x%02x\t0x%02x\t0x%02x\t0x%02x\t0x%02x\t0x%02x\t0x%02x\t0x%02x\r", *(gpio_char + 0), *(gpio_char + 1), *(gpio_char + 2), *(gpio_char + 3), *(gpio_char + 4), *(gpio_char + 5), *(gpio_char + 6), *(gpio_char + 7)); +//		printf("0x%02x\t0x%02x\t0x%02x\t0x%02x\t0x%02x\t0x%02x\t0x%02x\t0x%02x\r", *(gpio_char + 0), *(gpio_char + 1), *(gpio_char + 2), *(gpio_char + 3), *(gpio_char + 0x1000), *(gpio_char + 0x1001), *(gpio_char + 0x1002), *(gpio_char + 0x1003)); +		printf("0x%02x\t0x%02x\t0x%02x\t0x%02x\t0x%02x\t0x%02x\t0x%02x\t0x%02x\r", *(gpio_char + 0), *(gpio_char + 1), *(gpio_char + 2), *(gpio_char + 3), *(gpio_char + 0x4000), *(gpio_char + 0x4001), *(gpio_char + 0x4002), *(gpio_char + 0x4003)); +// 		printf("0x%02x\t0x%02x\t0x%02x\t0x%02x\t0x%02x\t0x%02x\t0x%02x\t0x%02x\r", *(gpio_char + 0x4000), *(gpio_char + 0x4001), *(gpio_char + 0x4002), *(gpio_char + 0x4003), *(gpio_char + 0x4000), *(gpio_char + 0x4001), *(gpio_char + 0x4002), *(gpio_char + 0x4003)); +		usleep(10); +	} +} + +static void io_shutdown(void) +{ +	// +} + +/** END: Low-Level I/O Implementation **/ + +int main(int argc, char **argv) +{ +	gpmc_setup(); +	printf("GPMC setup complete!\n"); fflush(stdout); +	io_setup(); +	return 0; +} + | 
