#include #include #include #include #include #define GPMC_BASE 0x50000000 #define GPMC_CHIPSELECTCONFIGDISPLACEMENT (0x30 / 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) static int devmemfd = -1; //map memory of length "len" at offset "offset" static void* util_mapmemoryblock(off_t offset, size_t len) { devmemfd = open("/dev/mem", O_RDWR | O_SYNC); void* registers = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED, devmemfd, offset); if (registers == MAP_FAILED) { printf("Map failed\n"); } return registers; } static void util_unmapmemoryblock(void* block, size_t len) { munmap((void*) block, len); if (devmemfd != -1) { close(devmemfd); } } #define REGLEN 0x10000000 static volatile uint32_t* registers = NULL; static void gpmc_mapregisters() { registers = (uint32_t*) util_mapmemoryblock(GPMC_BASE, REGLEN); } static void gpmc_unmapregisters() { util_unmapmemoryblock((void*) registers, REGLEN); } static void gpmc_setup(void) { gpmc_mapregisters(); if (registers != MAP_FAILED) { int chipselect = 0; int displacement = GPMC_CHIPSELECTCONFIGDISPLACEMENT * chipselect; // disable before playing with the registers.. *(registers + displacement + GPMC_CONFIG7) = 0x00000000; *(registers + displacement + GPMC_CONFIG1) = 0x00000000; //No burst, async, 8-bit, non multiplexed *(registers + displacement + GPMC_CONFIG2) = 0x00000300; //Assert CS on fclk 0, deassert CS on fclk 3 *(registers + displacement + GPMC_CONFIG3) = 0x00000000; //Unused ADV/ALE *(registers + displacement + GPMC_CONFIG4) = 0x00000301; //Assert OE on fclk 1, deassert OE on fclk 3 *(registers + displacement + GPMC_CONFIG5) = 0x00020003; //Data valid on fclk 2, cycle time 3 fclks *(registers + displacement + GPMC_CONFIG6) = 0x00000000; //No back to back cycle restrictions *(registers + displacement + GPMC_CONFIG7) = 0x00000f41; //CS0: Set base address 0x01000000, 16MB region, and enable CS gpmc_unmapregisters(); } } static volatile uint8_t* extbus; void bus_init() { gpmc_setup(); extbus = (uint8_t*) util_mapmemoryblock(0x01000000, 0x100); } void bus_writebyte(uint8_t address, uint8_t data) { *(extbus + address) = data; } uint8_t bus_readbyte(uint8_t address) { return *(extbus + address); } void bus_shutdown() { util_unmapmemoryblock((void*) extbus, 0x100); } int main() { bus_init(); for (int i = 0; i < 10; i++) { printf("byte at address %x: %X\n", i, bus_readbyte(i)); } bus_shutdown(); }