#include #include #include #include #include #include #include #include #include #include "m68k.h" #include "platforms/amiga/Gayle.h" #include "platforms/amiga/gayle-ide/ide.h" #include "gpio_old.h" // I/O access volatile unsigned int *gpio; volatile unsigned int *gpclk; volatile unsigned int gpfsel0; volatile unsigned int gpfsel1; volatile unsigned int gpfsel2; volatile unsigned int gpfsel0_o; volatile unsigned int gpfsel1_o; volatile unsigned int gpfsel2_o; volatile uint16_t srdata; volatile uint32_t srdata2; volatile uint32_t srdata2_old; extern int mem_fd, mouse_fd, keyboard_fd; extern int mem_fd_gpclk; extern uint8_t gayle_int; void *gpio_map; void *gpclk_map; unsigned char toggle; static int g = 0; inline void write16(uint32_t address, uint32_t data) { // asm volatile ("dmb" ::: "memory"); W16 *(gpio) = gpfsel0_o; *(gpio + 1) = gpfsel1_o; *(gpio + 2) = gpfsel2_o; *(gpio + 7) = ((address & 0x0000ffff) << 8); *(gpio + 10) = ((~address & 0x0000ffff) << 8); GPIO_CLR = 1 << 7; GPIO_SET = 1 << 7; *(gpio + 7) = ((address >> 16) << 8); *(gpio + 10) = ((~address >> 16) << 8); GPIO_CLR = 1 << 7; GPIO_SET = 1 << 7; // write phase *(gpio + 7) = ((data & 0x0000ffff) << 8); *(gpio + 10) = ((~data & 0x0000ffff) << 8); GPIO_CLR = 1 << 7; GPIO_SET = 1 << 7; *(gpio) = gpfsel0; *(gpio + 1) = gpfsel1; *(gpio + 2) = gpfsel2; while ((GET_GPIO(0))) ; // asm volatile ("dmb" ::: "memory"); } inline void write8(uint32_t address, uint32_t data) { if ((address & 1) == 0) data = data + (data << 8); // EVEN, A0=0,UDS else data = data & 0xff; // ODD , A0=1,LDS // asm volatile ("dmb" ::: "memory"); W8 *(gpio) = gpfsel0_o; *(gpio + 1) = gpfsel1_o; *(gpio + 2) = gpfsel2_o; *(gpio + 7) = ((address & 0x0000ffff) << 8); *(gpio + 10) = ((~address & 0x0000ffff) << 8); GPIO_CLR = 1 << 7; GPIO_SET = 1 << 7; *(gpio + 7) = ((address >> 16) << 8); *(gpio + 10) = ((~address >> 16) << 8); GPIO_CLR = 1 << 7; GPIO_SET = 1 << 7; // write phase *(gpio + 7) = ((data & 0x0000ffff) << 8); *(gpio + 10) = ((~data & 0x0000ffff) << 8); GPIO_CLR = 1 << 7; GPIO_SET = 1 << 7; *(gpio) = gpfsel0; *(gpio + 1) = gpfsel1; *(gpio + 2) = gpfsel2; while ((GET_GPIO(0))) ; // asm volatile ("dmb" ::: "memory"); } inline uint32_t read32(uint32_t address) { int val; int a; int b; asm volatile ("dmb" ::: "memory"); R16 *(gpio) = gpfsel0_o; *(gpio + 1) = gpfsel1_o; *(gpio + 2) = gpfsel2_o; *(gpio + 7) = ((address & 0x0000ffff) << 8); *(gpio + 10) = ((~address & 0x0000ffff) << 8); GPIO_CLR = 1 << 7; GPIO_CLR = 1 << 7; GPIO_SET = 1 << 7; *(gpio + 7) = ((address >> 16) << 8); *(gpio + 10) = ((~address >> 16) << 8); GPIO_CLR = 1 << 7; GPIO_SET = 1 << 7; // read phase *(gpio) = gpfsel0; *(gpio + 1) = gpfsel1; *(gpio + 2) = gpfsel2; GPIO_CLR = 1 << 6; while (!(GET_GPIO(0))) ; GPIO_CLR = 1 << 6; GPIO_CLR = 1 << 6; val = *(gpio + 13); GPIO_SET = 1 << 6; // asm volatile ("dmb" ::: "memory"); a = (val >> 8) & 0xffff; while (GET_GPIO(0)); //R16 *(gpio) = gpfsel0_o; *(gpio + 1) = gpfsel1_o; *(gpio + 2) = gpfsel2_o; *(gpio + 7) = (((address+2) & 0x0000ffff) << 8); *(gpio + 10) = ((~(address+2) & 0x0000ffff) << 8); GPIO_CLR = 1 << 7; GPIO_CLR = 1 << 7; GPIO_SET = 1 << 7; *(gpio + 7) = (((address+2) >> 16) << 8); *(gpio + 10) = ((~(address+2) >> 16) << 8); GPIO_CLR = 1 << 7; GPIO_SET = 1 << 7; // read phase *(gpio) = gpfsel0; *(gpio + 1) = gpfsel1; *(gpio + 2) = gpfsel2; GPIO_CLR = 1 << 6; while (!(GET_GPIO(0))) ; GPIO_CLR = 1 << 6; GPIO_CLR = 1 << 6; val = *(gpio + 13); GPIO_SET = 1 << 6; b = (val >> 8) & 0xffff; asm volatile ("dmb" ::: "memory"); return (a << 16) | b; } inline uint32_t read16(uint32_t address) { int val; // asm volatile ("dmb" ::: "memory"); R16 *(gpio) = gpfsel0_o; *(gpio + 1) = gpfsel1_o; *(gpio + 2) = gpfsel2_o; *(gpio + 7) = ((address & 0x0000ffff) << 8); *(gpio + 10) = ((~address & 0x0000ffff) << 8); GPIO_CLR = 1 << 7; GPIO_CLR = 1 << 7; GPIO_SET = 1 << 7; *(gpio + 7) = ((address >> 16) << 8); *(gpio + 10) = ((~address >> 16) << 8); GPIO_CLR = 1 << 7; GPIO_SET = 1 << 7; // read phase *(gpio) = gpfsel0; *(gpio + 1) = gpfsel1; *(gpio + 2) = gpfsel2; GPIO_CLR = 1 << 6; while (!(GET_GPIO(0))) ; GPIO_CLR = 1 << 6; val = *(gpio + 13); GPIO_SET = 1 << 6; // asm volatile ("dmb" ::: "memory"); return (val >> 8) & 0xffff; } inline uint32_t read8(uint32_t address) { int val; // asm volatile ("dmb" ::: "memory"); R8 *(gpio) = gpfsel0_o; *(gpio + 1) = gpfsel1_o; *(gpio + 2) = gpfsel2_o; *(gpio + 7) = ((address & 0x0000ffff) << 8); *(gpio + 10) = ((~address & 0x0000ffff) << 8); GPIO_CLR = 1 << 7; GPIO_SET = 1 << 7; *(gpio + 7) = ((address >> 16) << 8); *(gpio + 10) = ((~address >> 16) << 8); GPIO_CLR = 1 << 7; GPIO_SET = 1 << 7; // read phase *(gpio) = gpfsel0; *(gpio + 1) = gpfsel1; *(gpio + 2) = gpfsel2; GPIO_CLR = 1 << 6; while (!(GET_GPIO(0))) ; GPIO_CLR = 1 << 6; val = *(gpio + 13); GPIO_SET = 1 << 6; // asm volatile ("dmb" ::: "memory"); val = (val >> 8) & 0xffff; if ((address & 1) == 0) return (val >> 8) & 0xff; // EVEN, A0=0,UDS else return val & 0xff; // ODD , A0=1,LDS } /******************************************************/ void write_reg(unsigned int value) { STATUSREGADDR *(gpio) = gpfsel0_o; *(gpio + 1) = gpfsel1_o; *(gpio + 2) = gpfsel2_o; *(gpio + 7) = (value & 0xffff) << 8; *(gpio + 10) = (~value & 0xffff) << 8; GPIO_CLR = 1 << 7; GPIO_CLR = 1 << 7; // delay GPIO_SET = 1 << 7; GPIO_SET = 1 << 7; // Bus HIGH-Z *(gpio) = gpfsel0; *(gpio + 1) = gpfsel1; *(gpio + 2) = gpfsel2; } uint16_t read_reg(void) { uint32_t val; STATUSREGADDR // Bus HIGH-Z *(gpio) = gpfsel0; *(gpio + 1) = gpfsel1; *(gpio + 2) = gpfsel2; GPIO_CLR = 1 << 6; GPIO_CLR = 1 << 6; // delay GPIO_CLR = 1 << 6; GPIO_CLR = 1 << 6; val = *(gpio + 13); GPIO_SET = 1 << 6; return (uint16_t)(val >> 8); } // // Set up a memory regions to access GPIO // void setup_io() { /* 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 = mmap( NULL, // Any adddress in our space will do BCM2708_PERI_SIZE, // Map length PROT_READ | PROT_WRITE, // Enable reading & writting to mapped memory MAP_SHARED, // Shared with other processes mem_fd, // File to map BCM2708_PERI_BASE // Offset to GPIO peripheral ); close(mem_fd); // No need to keep mem_fd open after mmap if (gpio_map == MAP_FAILED) { printf("gpio mmap error %d\n", (int)gpio_map); // errno also set! exit(-1); } gpio = ((volatile unsigned *)gpio_map) + GPIO_ADDR / 4; gpclk = ((volatile unsigned *)gpio_map) + GPCLK_ADDR / 4; } // setup_io void gpio_enable_200mhz() { *(gpclk + (CLK_GP0_CTL / 4)) = CLK_PASSWD | (1 << 5); usleep(10); while ((*(gpclk + (CLK_GP0_CTL / 4))) & (1 << 7)) ; usleep(100); *(gpclk + (CLK_GP0_DIV / 4)) = CLK_PASSWD | (6 << 12); // divider , 6=200MHz on pi3 usleep(10); *(gpclk + (CLK_GP0_CTL / 4)) = CLK_PASSWD | 5 | (1 << 4); // pll? 6=plld, 5=pllc usleep(10); while (((*(gpclk + (CLK_GP0_CTL / 4))) & (1 << 7)) == 0) ; usleep(100); SET_GPIO_ALT(4, 0); // gpclk0 // set SA to output INP_GPIO(2); OUT_GPIO(2); INP_GPIO(3); OUT_GPIO(3); INP_GPIO(5); OUT_GPIO(5); // set gpio0 (aux0) and gpio1 (aux1) to input INP_GPIO(0); INP_GPIO(1); // Set GPIO pins 6,7 and 8-23 to output for (g = 6; g <= 23; g++) { INP_GPIO(g); OUT_GPIO(g); } printf("Precalculate GPIO8-23 as Output\n"); gpfsel0_o = *(gpio); // store gpio ddr printf("gpfsel0: %#x\n", gpfsel0_o); gpfsel1_o = *(gpio + 1); // store gpio ddr printf("gpfsel1: %#x\n", gpfsel1_o); gpfsel2_o = *(gpio + 2); // store gpio ddr printf("gpfsel2: %#x\n", gpfsel2_o); // Set GPIO pins 8-23 to input for (g = 8; g <= 23; g++) { INP_GPIO(g); } printf("Precalculate GPIO8-23 as Input\n"); gpfsel0 = *(gpio); // store gpio ddr printf("gpfsel0: %#x\n", gpfsel0); gpfsel1 = *(gpio + 1); // store gpio ddr printf("gpfsel1: %#x\n", gpfsel1); gpfsel2 = *(gpio + 2); // store gpio ddr printf("gpfsel2: %#x\n", gpfsel2); GPIO_CLR = 1 << 2; GPIO_CLR = 1 << 3; GPIO_SET = 1 << 5; GPIO_SET = 1 << 6; GPIO_SET = 1 << 7; } inline void gpio_handle_irq() { if (GET_GPIO(1) == 0) { srdata = read_reg(); m68k_set_irq((srdata >> 13) & 0xff); } else { if ((gayle_int & 0x80) && (get_ide(0)->drive[0].intrq || get_ide(0)->drive[1].intrq)) { write16(0xdff09c, 0x8008); m68k_set_irq(2); } else m68k_set_irq(0); }; } inline int gpio_get_irq() { return (GET_GPIO(1)); }