]> git.sesse.net Git - pistorm/blob - gpio/gpio_old.c
Add Meson build files.
[pistorm] / gpio / gpio_old.c
1 #include <stdint.h>
2 #include <stddef.h>
3 #include <unistd.h>
4 #include <stdio.h>
5 #include <stdlib.h>
6 #include <signal.h>
7 #include <fcntl.h>
8 #include <sys/mman.h>
9 #include <sys/ioctl.h>
10 #include "m68k.h"
11 #include "platforms/amiga/Gayle.h"
12 #include "platforms/amiga/gayle-ide/ide.h"
13 #include "gpio_old.h"
14
15 // I/O access
16 volatile unsigned int *gpio;
17 volatile unsigned int *gpclk;
18 volatile unsigned int gpfsel0;
19 volatile unsigned int gpfsel1;
20 volatile unsigned int gpfsel2;
21 volatile unsigned int gpfsel0_o;
22 volatile unsigned int gpfsel1_o;
23 volatile unsigned int gpfsel2_o;
24
25 volatile uint16_t srdata;
26 volatile uint32_t srdata2;
27 volatile uint32_t srdata2_old;
28
29 extern int mem_fd, mouse_fd, keyboard_fd;
30 extern int mem_fd_gpclk;
31 extern uint8_t gayle_int;
32
33 void *gpio_map;
34 void *gpclk_map;
35
36 unsigned char toggle;
37
38 static int g = 0;
39
40 inline void write16(uint32_t address, uint32_t data) {
41   //      asm volatile ("dmb" ::: "memory");
42   W16
43   *(gpio) = gpfsel0_o;
44   *(gpio + 1) = gpfsel1_o;
45   *(gpio + 2) = gpfsel2_o;
46
47   *(gpio + 7) = ((address & 0x0000ffff) << 8);
48   *(gpio + 10) = ((~address & 0x0000ffff) << 8);
49   GPIO_CLR = 1 << 7;
50   GPIO_SET = 1 << 7;
51
52   *(gpio + 7) = ((address >> 16) << 8);
53   *(gpio + 10) = ((~address >> 16) << 8);
54   GPIO_CLR = 1 << 7;
55   GPIO_SET = 1 << 7;
56
57   // write phase
58   *(gpio + 7) = ((data & 0x0000ffff) << 8);
59   *(gpio + 10) = ((~data & 0x0000ffff) << 8);
60   GPIO_CLR = 1 << 7;
61   GPIO_SET = 1 << 7;
62
63   *(gpio) = gpfsel0;
64   *(gpio + 1) = gpfsel1;
65   *(gpio + 2) = gpfsel2;
66   while ((GET_GPIO(0)))
67     ;
68   //     asm volatile ("dmb" ::: "memory");
69 }
70
71 inline void write8(uint32_t address, uint32_t data) {
72   if ((address & 1) == 0)
73     data = data + (data << 8);  // EVEN, A0=0,UDS
74   else
75     data = data & 0xff;  // ODD , A0=1,LDS
76
77   //   asm volatile ("dmb" ::: "memory");
78   W8
79   *(gpio) = gpfsel0_o;
80   *(gpio + 1) = gpfsel1_o;
81   *(gpio + 2) = gpfsel2_o;
82
83   *(gpio + 7) = ((address & 0x0000ffff) << 8);
84   *(gpio + 10) = ((~address & 0x0000ffff) << 8);
85   GPIO_CLR = 1 << 7;
86   GPIO_SET = 1 << 7;
87
88   *(gpio + 7) = ((address >> 16) << 8);
89   *(gpio + 10) = ((~address >> 16) << 8);
90   GPIO_CLR = 1 << 7;
91   GPIO_SET = 1 << 7;
92
93   // write phase
94   *(gpio + 7) = ((data & 0x0000ffff) << 8);
95   *(gpio + 10) = ((~data & 0x0000ffff) << 8);
96   GPIO_CLR = 1 << 7;
97   GPIO_SET = 1 << 7;
98
99   *(gpio) = gpfsel0;
100   *(gpio + 1) = gpfsel1;
101   *(gpio + 2) = gpfsel2;
102   while ((GET_GPIO(0)))
103     ;
104   //   asm volatile ("dmb" ::: "memory");
105 }
106
107 inline uint32_t read32(uint32_t address) {
108   int val;
109   int a;
110   int b;
111   asm volatile ("dmb" ::: "memory");
112   R16
113   *(gpio) = gpfsel0_o;
114   *(gpio + 1) = gpfsel1_o;
115   *(gpio + 2) = gpfsel2_o;
116
117   *(gpio + 7) = ((address & 0x0000ffff) << 8);
118   *(gpio + 10) = ((~address & 0x0000ffff) << 8);
119   GPIO_CLR = 1 << 7;
120   GPIO_CLR = 1 << 7;
121   GPIO_SET = 1 << 7;
122
123   *(gpio + 7) = ((address >> 16) << 8);
124   *(gpio + 10) = ((~address >> 16) << 8);
125   GPIO_CLR = 1 << 7;
126   GPIO_SET = 1 << 7;
127
128   // read phase
129   *(gpio) = gpfsel0;
130   *(gpio + 1) = gpfsel1;
131   *(gpio + 2) = gpfsel2;
132   GPIO_CLR = 1 << 6;
133   while (!(GET_GPIO(0)))
134     ;
135   GPIO_CLR = 1 << 6;
136   GPIO_CLR = 1 << 6;
137   val = *(gpio + 13);
138   GPIO_SET = 1 << 6;
139   //    asm volatile ("dmb" ::: "memory");
140   a = (val >> 8) & 0xffff;
141   while (GET_GPIO(0));
142   //R16
143   *(gpio) = gpfsel0_o;
144   *(gpio + 1) = gpfsel1_o;
145   *(gpio + 2) = gpfsel2_o;
146
147   *(gpio + 7) = (((address+2) & 0x0000ffff) << 8);
148   *(gpio + 10) = ((~(address+2) & 0x0000ffff) << 8);
149   GPIO_CLR = 1 << 7;
150   GPIO_CLR = 1 << 7;
151   GPIO_SET = 1 << 7;
152
153   *(gpio + 7) = (((address+2) >> 16) << 8);
154   *(gpio + 10) = ((~(address+2) >> 16) << 8);
155   GPIO_CLR = 1 << 7;
156   GPIO_SET = 1 << 7;
157
158   // read phase
159   *(gpio) = gpfsel0;
160   *(gpio + 1) = gpfsel1;
161   *(gpio + 2) = gpfsel2;
162   GPIO_CLR = 1 << 6;
163   while (!(GET_GPIO(0)))
164     ;
165   GPIO_CLR = 1 << 6;
166   GPIO_CLR = 1 << 6;
167   val = *(gpio + 13);
168   GPIO_SET = 1 << 6;
169   b = (val >> 8) & 0xffff;
170   asm volatile ("dmb" ::: "memory");
171
172   return (a << 16) | b;
173 }
174
175 inline uint32_t read16(uint32_t address) {
176   int val;
177   //   asm volatile ("dmb" ::: "memory");
178   R16
179   *(gpio) = gpfsel0_o;
180   *(gpio + 1) = gpfsel1_o;
181   *(gpio + 2) = gpfsel2_o;
182
183   *(gpio + 7) = ((address & 0x0000ffff) << 8);
184   *(gpio + 10) = ((~address & 0x0000ffff) << 8);
185   GPIO_CLR = 1 << 7;
186   GPIO_CLR = 1 << 7;
187   GPIO_SET = 1 << 7;
188
189   *(gpio + 7) = ((address >> 16) << 8);
190   *(gpio + 10) = ((~address >> 16) << 8);
191   GPIO_CLR = 1 << 7;
192   GPIO_SET = 1 << 7;
193
194   // read phase
195   *(gpio) = gpfsel0;
196   *(gpio + 1) = gpfsel1;
197   *(gpio + 2) = gpfsel2;
198   GPIO_CLR = 1 << 6;
199   while (!(GET_GPIO(0)))
200     ;
201   GPIO_CLR = 1 << 6;
202   val = *(gpio + 13);
203   GPIO_SET = 1 << 6;
204   //    asm volatile ("dmb" ::: "memory");
205   return (val >> 8) & 0xffff;
206 }
207
208 inline uint32_t read8(uint32_t address) {
209   int val;
210   //    asm volatile ("dmb" ::: "memory");
211   R8
212   *(gpio) = gpfsel0_o;
213   *(gpio + 1) = gpfsel1_o;
214   *(gpio + 2) = gpfsel2_o;
215
216   *(gpio + 7) = ((address & 0x0000ffff) << 8);
217   *(gpio + 10) = ((~address & 0x0000ffff) << 8);
218   GPIO_CLR = 1 << 7;
219   GPIO_SET = 1 << 7;
220
221   *(gpio + 7) = ((address >> 16) << 8);
222   *(gpio + 10) = ((~address >> 16) << 8);
223   GPIO_CLR = 1 << 7;
224   GPIO_SET = 1 << 7;
225
226   // read phase
227   *(gpio) = gpfsel0;
228   *(gpio + 1) = gpfsel1;
229   *(gpio + 2) = gpfsel2;
230
231   GPIO_CLR = 1 << 6;
232   while (!(GET_GPIO(0)))
233     ;
234   GPIO_CLR = 1 << 6;
235   val = *(gpio + 13);
236   GPIO_SET = 1 << 6;
237   //    asm volatile ("dmb" ::: "memory");
238
239   val = (val >> 8) & 0xffff;
240   if ((address & 1) == 0)
241     return (val >> 8) & 0xff;  // EVEN, A0=0,UDS
242   else
243     return val & 0xff;  // ODD , A0=1,LDS
244 }
245
246 /******************************************************/
247
248 void write_reg(unsigned int value) {
249   STATUSREGADDR
250   *(gpio) = gpfsel0_o;
251   *(gpio + 1) = gpfsel1_o;
252   *(gpio + 2) = gpfsel2_o;
253   *(gpio + 7) = (value & 0xffff) << 8;
254   *(gpio + 10) = (~value & 0xffff) << 8;
255   GPIO_CLR = 1 << 7;
256   GPIO_CLR = 1 << 7;  // delay
257   GPIO_SET = 1 << 7;
258   GPIO_SET = 1 << 7;
259   // Bus HIGH-Z
260   *(gpio) = gpfsel0;
261   *(gpio + 1) = gpfsel1;
262   *(gpio + 2) = gpfsel2;
263 }
264
265 uint16_t read_reg(void) {
266   uint32_t val;
267   STATUSREGADDR
268   // Bus HIGH-Z
269   *(gpio) = gpfsel0;
270   *(gpio + 1) = gpfsel1;
271   *(gpio + 2) = gpfsel2;
272   GPIO_CLR = 1 << 6;
273   GPIO_CLR = 1 << 6;  // delay
274   GPIO_CLR = 1 << 6;
275   GPIO_CLR = 1 << 6;
276   val = *(gpio + 13);
277   GPIO_SET = 1 << 6;
278   return (uint16_t)(val >> 8);
279 }
280
281 //
282 // Set up a memory regions to access GPIO
283 //
284 void setup_io() {
285   /* open /dev/mem */
286   if ((mem_fd = open("/dev/mem", O_RDWR | O_SYNC)) < 0) {
287     printf("can't open /dev/mem \n");
288     exit(-1);
289   }
290
291   /* mmap GPIO */
292   gpio_map = mmap(
293       NULL,                    // Any adddress in our space will do
294       BCM2708_PERI_SIZE,       // Map length
295       PROT_READ | PROT_WRITE,  // Enable reading & writting to mapped memory
296       MAP_SHARED,              // Shared with other processes
297       mem_fd,                  // File to map
298       BCM2708_PERI_BASE        // Offset to GPIO peripheral
299   );
300
301   close(mem_fd);  // No need to keep mem_fd open after mmap
302
303   if (gpio_map == MAP_FAILED) {
304     printf("gpio mmap error %d\n", (int)gpio_map);  // errno also set!
305     exit(-1);
306   }
307
308   gpio = ((volatile unsigned *)gpio_map) + GPIO_ADDR / 4;
309   gpclk = ((volatile unsigned *)gpio_map) + GPCLK_ADDR / 4;
310
311 }  // setup_io
312
313 void gpio_enable_200mhz() {
314   *(gpclk + (CLK_GP0_CTL / 4)) = CLK_PASSWD | (1 << 5);
315   usleep(10);
316   while ((*(gpclk + (CLK_GP0_CTL / 4))) & (1 << 7))
317     ;
318   usleep(100);
319   *(gpclk + (CLK_GP0_DIV / 4)) =
320       CLK_PASSWD | (6 << 12);  // divider , 6=200MHz on pi3
321   usleep(10);
322   *(gpclk + (CLK_GP0_CTL / 4)) =
323       CLK_PASSWD | 5 | (1 << 4);  // pll? 6=plld, 5=pllc
324   usleep(10);
325   while (((*(gpclk + (CLK_GP0_CTL / 4))) & (1 << 7)) == 0)
326     ;
327   usleep(100);
328
329   SET_GPIO_ALT(4, 0);  // gpclk0
330
331   // set SA to output
332   INP_GPIO(2);
333   OUT_GPIO(2);
334   INP_GPIO(3);
335   OUT_GPIO(3);
336   INP_GPIO(5);
337   OUT_GPIO(5);
338
339   // set gpio0 (aux0) and gpio1 (aux1) to input
340   INP_GPIO(0);
341   INP_GPIO(1);
342
343   // Set GPIO pins 6,7 and 8-23 to output
344   for (g = 6; g <= 23; g++) {
345     INP_GPIO(g);
346     OUT_GPIO(g);
347   }
348   printf("Precalculate GPIO8-23 as Output\n");
349   gpfsel0_o = *(gpio);  // store gpio ddr
350   printf("gpfsel0: %#x\n", gpfsel0_o);
351   gpfsel1_o = *(gpio + 1);  // store gpio ddr
352   printf("gpfsel1: %#x\n", gpfsel1_o);
353   gpfsel2_o = *(gpio + 2);  // store gpio ddr
354   printf("gpfsel2: %#x\n", gpfsel2_o);
355
356   // Set GPIO pins 8-23 to input
357   for (g = 8; g <= 23; g++) {
358     INP_GPIO(g);
359   }
360   printf("Precalculate GPIO8-23 as Input\n");
361   gpfsel0 = *(gpio);  // store gpio ddr
362   printf("gpfsel0: %#x\n", gpfsel0);
363   gpfsel1 = *(gpio + 1);  // store gpio ddr
364   printf("gpfsel1: %#x\n", gpfsel1);
365   gpfsel2 = *(gpio + 2);  // store gpio ddr
366   printf("gpfsel2: %#x\n", gpfsel2);
367
368   GPIO_CLR = 1 << 2;
369   GPIO_CLR = 1 << 3;
370   GPIO_SET = 1 << 5;
371
372   GPIO_SET = 1 << 6;
373   GPIO_SET = 1 << 7;
374 }
375
376 inline void gpio_handle_irq() {
377   if (GET_GPIO(1) == 0) {
378     srdata = read_reg();
379     m68k_set_irq((srdata >> 13) & 0xff);
380   } else {
381     if ((gayle_int & 0x80) && (get_ide(0)->drive[0].intrq || get_ide(0)->drive[1].intrq)) {
382       write16(0xdff09c, 0x8008);
383       m68k_set_irq(2);
384     }
385     else
386         m68k_set_irq(0);
387   };
388 }
389
390 inline int gpio_get_irq() {
391   return (GET_GPIO(1));
392 }