summaryrefslogtreecommitdiffstats
path: root/fpga/interface/beaglebone_black/gpmc/test/bbb-gpmc-test.c
diff options
context:
space:
mode:
authorTimothy Pearson <kb9vqf@pearsoncomputing.net>2014-01-09 21:02:03 -0600
committerTimothy Pearson <kb9vqf@pearsoncomputing.net>2014-01-09 21:02:03 -0600
commit963b88fb0bb3a20bd4b6eb3d73095172a3760d55 (patch)
tree3e583da09ecf0406d471f1d438881dd6dd1cd05a /fpga/interface/beaglebone_black/gpmc/test/bbb-gpmc-test.c
parent38c56c7c1fe4ecd7e5907cc14c100e4af3a87e20 (diff)
downloadulab-963b88fb0bb3a20bd4b6eb3d73095172a3760d55.tar.gz
ulab-963b88fb0bb3a20bd4b6eb3d73095172a3760d55.zip
Add initial GPMC test program and associated files for BeagleBone Black
Diffstat (limited to 'fpga/interface/beaglebone_black/gpmc/test/bbb-gpmc-test.c')
-rw-r--r--fpga/interface/beaglebone_black/gpmc/test/bbb-gpmc-test.c240
1 files changed, 240 insertions, 0 deletions
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;
+}
+