diff options
| author | Timothy Pearson <kb9vqf@pearsoncomputing.net> | 2014-01-09 21:02:03 -0600 |
|---|---|---|
| committer | Timothy Pearson <kb9vqf@pearsoncomputing.net> | 2014-01-09 21:02:03 -0600 |
| commit | 963b88fb0bb3a20bd4b6eb3d73095172a3760d55 (patch) | |
| tree | 3e583da09ecf0406d471f1d438881dd6dd1cd05a /fpga/interface/beaglebone_black/gpmc/test/bbb-gpmc-test.c | |
| parent | 38c56c7c1fe4ecd7e5907cc14c100e4af3a87e20 (diff) | |
| download | ulab-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.c | 240 |
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; +} + |
