18 //#define BCM2708_PERI_BASE 0x20000000 //pi0-1
19 #define BCM2708_PERI_BASE 0x3F000000 //pi3
20 #define BCM2708_PERI_SIZE 0x01000000
21 #define GPIO_BASE (BCM2708_PERI_BASE + 0x200000) /* GPIO controller */
22 #define GPCLK_BASE (BCM2708_PERI_BASE + 0x101000)
23 #define GPIO_ADDR 0x200000 /* GPIO controller */
24 #define GPCLK_ADDR 0x101000
25 #define CLK_PASSWD 0x5a000000
26 #define CLK_GP0_CTL 0x070
27 #define CLK_GP0_DIV 0x074
33 #define STATUSREGADDR GPIO_CLR = 1<<SA0;GPIO_CLR = 1<<SA1;GPIO_SET = 1<<SA2;
34 #define W16 GPIO_CLR = 1<<SA0;GPIO_CLR = 1<<SA1;GPIO_CLR = 1<<SA2;
35 #define R16 GPIO_SET = 1<<SA0;GPIO_CLR = 1<<SA1;GPIO_CLR = 1<<SA2;
36 #define W8 GPIO_CLR = 1<<SA0;GPIO_SET = 1<<SA1;GPIO_CLR = 1<<SA2;
37 #define R8 GPIO_SET = 1<<SA0;GPIO_SET = 1<<SA1;GPIO_CLR = 1<<SA2;
39 #define PAGE_SIZE (4*1024)
40 #define BLOCK_SIZE (4*1024)
42 #define GPIOSET(no, ishigh) \
47 reset |= (1 << (no)); \
51 #define MAX_RAM 0xFFFFFF
54 /* Read/write macros */
55 #define READ_BYTE(BASE, ADDR) (BASE)[ADDR]
56 #define READ_WORD(BASE, ADDR) (((BASE)[ADDR]<<8) | \
58 #define READ_LONG(BASE, ADDR) (((BASE)[ADDR]<<24) | \
59 ((BASE)[(ADDR)+1]<<16) | \
60 ((BASE)[(ADDR)+2]<<8) | \
63 #define WRITE_BYTE(BASE, ADDR, VAL) (BASE)[ADDR] = (VAL)&0xff
64 #define WRITE_WORD(BASE, ADDR, VAL) (BASE)[ADDR] = ((VAL)>>8) & 0xff; \
65 (BASE)[(ADDR)+1] = (VAL)&0xff
66 #define WRITE_LONG(BASE, ADDR, VAL) (BASE)[ADDR] = ((VAL)>>24) & 0xff; \
67 (BASE)[(ADDR)+1] = ((VAL)>>16)&0xff; \
68 (BASE)[(ADDR)+2] = ((VAL)>>8)&0xff; \
69 (BASE)[(ADDR)+3] = (VAL)&0xff
79 volatile unsigned int *gpio;
80 volatile unsigned int *gpclk;
81 volatile unsigned int gpfsel0;
82 volatile unsigned int gpfsel1;
83 volatile unsigned int gpfsel2;
84 volatile unsigned int gpfsel0_o;
85 volatile unsigned int gpfsel1_o;
86 volatile unsigned int gpfsel2_o;
88 // GPIO setup macros. Always use INP_GPIO(x) before using OUT_GPIO(x) or SET_GPIO_ALT(x,y)
89 #define INP_GPIO(g) *(gpio+((g)/10)) &= ~(7<<(((g)%10)*3))
90 #define OUT_GPIO(g) *(gpio+((g)/10)) |= (1<<(((g)%10)*3))
91 #define SET_GPIO_ALT(g,a) *(gpio+(((g)/10))) |= (((a)<=3?(a)+4:(a)==4?3:2)<<(((g)%10)*3))
93 #define GPIO_SET *(gpio+7) // sets bits which are 1 ignores bits which are 0
94 #define GPIO_CLR *(gpio+10) // clears bits which are 1 ignores bits which are 0
96 #define GET_GPIO(g) (*(gpio+13)&(1<<g)) // 0 if LOW, (1<<g) if HIGH
98 #define GPIO_PULL *(gpio+37) // Pull up/pull down
99 #define GPIO_PULLCLK0 *(gpio+38) // Pull up/pull down clock
104 uint32_t read8(uint32_t address);
105 void write8(uint32_t address, uint32_t data);
107 uint32_t read16(uint32_t address);
108 void write16(uint32_t address, uint32_t data);
110 void write32(uint32_t address, uint32_t data);
111 uint32_t read32(uint32_t address);
113 uint16_t read_reg(void);
114 void write_reg(unsigned int value);
116 volatile uint16_t srdata;
117 volatile uint32_t srdata2;
118 volatile uint32_t srdata2_old;
121 unsigned char g_ram[MAX_RAM+1]; /* RAM */
122 unsigned char toggle;
125 void* iplThread(void *args){
128 //srdata2_old = read_reg();
132 //printf("thread!/n");
133 if (GET_GPIO(1) == 0){
135 if (srdata != srdata2_old){
136 srdata2 = ((srdata >> 13)&0xff);
137 //printf("STATUS: %d\n", srdata2);
138 srdata2_old = srdata;
139 m68k_set_irq(srdata2);
145 srdata2 = ((srdata >> 13)&0xff);
146 srdata2_old = srdata;
147 m68k_set_irq(srdata2);
148 //printf("STATUS: 0\n");
164 const struct sched_param priority = {99};
166 sched_setscheduler(0, SCHED_RR , &priority);
167 printf("YES locked in memory\n");
168 mlockall(MCL_CURRENT); // lock in memory to keep us from paging out
173 //Enable 200MHz CLK output on GPIO4, adjust divider and pll source depending on pi model
174 printf("Enable GPCLK0 on GPIO4\n");
176 *(gpclk+ (CLK_GP0_CTL/4)) = CLK_PASSWD | (1 << 5);
178 while ( (*(gpclk+(CLK_GP0_CTL/4))) & (1 << 7));
180 *(gpclk+(CLK_GP0_DIV/4)) = CLK_PASSWD | (6 << 12); //divider , 6=200MHz on pi3
182 *(gpclk+(CLK_GP0_CTL/4)) = CLK_PASSWD | 5 | (1 << 4); //pll? 6=plld, 5=pllc
184 while (((*(gpclk+(CLK_GP0_CTL/4))) & (1 << 7))== 0);
187 SET_GPIO_ALT(4,0); //gpclk0
197 //set gpio0 (aux0) and gpio1 (aux1) to input
201 // Set GPIO pins 6,7 and 8-23 to output
202 for (g=6; g<=23; g++)
207 printf ("Precalculate GPIO8-23 aus Output\n");
208 gpfsel0_o =*(gpio); //store gpio ddr
209 printf ("gpfsel0: %#x\n", gpfsel0_o);
210 gpfsel1_o =*(gpio+1); //store gpio ddr
211 printf ("gpfsel1: %#x\n", gpfsel1_o);
212 gpfsel2_o =*(gpio+2); //store gpio ddr
213 printf ("gpfsel2: %#x\n", gpfsel2_o);
215 // Set GPIO pins 8-23 to input
216 for (g=8; g<=23; g++)
220 printf ("Precalculate GPIO8-23 as Input\n");
221 gpfsel0 =*(gpio); //store gpio ddr
222 printf ("gpfsel0: %#x\n", gpfsel0);
223 gpfsel1 =*(gpio+1); //store gpio ddr
224 printf ("gpfsel1: %#x\n", gpfsel1);
225 gpfsel2 =*(gpio+2); //store gpio ddr
226 printf ("gpfsel2: %#x\n", gpfsel2);
235 //reset cpld statemachine first
243 write8(0xbfe201,0x0001); //AMIGA OVL
244 write8(0xbfe001,0x0001); //AMIGA OVL high (ROM@0x0)
249 m68k_set_cpu_type(M68K_CPU_TYPE_68040);
251 srdata2_old = read_reg();
258 //err = pthread_create(&id, NULL, &iplThread, NULL);
260 printf("\ncan't create IPL thread :[%s]", strerror(err));
262 printf("\n IPL Thread created successfully\n");
270 if (GET_GPIO(1) == 0){
272 if (srdata != srdata2_old){
273 srdata2 = ((srdata >> 13)&0xff);
274 //printf("STATUS: %d\n", srdata2);
275 srdata2_old = srdata;
276 m68k_set_irq(srdata2);
282 srdata2 = ((srdata >> 13)&0xff);
283 srdata2_old = srdata;
284 m68k_set_irq(srdata2);
285 //printf("STATUS: 0\n");
298 void cpu_pulse_reset(void){
306 int cpu_irq_ack(int level)
308 printf("cpu irq ack\n");
314 unsigned int m68k_read_memory_8(unsigned int address){
316 if(address>0x07FFFFFF){
317 return g_ram[address- 0x07FFFFFF];
320 return read8((uint32_t)address);
323 unsigned int m68k_read_memory_16(unsigned int address){
325 if(address>0x07FFFFFF){
326 uint16_t value = *(uint16_t*)&g_ram[address- 0x07FFFFFF];
327 value = (value << 8) | (value >> 8);
330 return (unsigned int)read16((uint32_t)address);
333 unsigned int m68k_read_memory_32(unsigned int address){
336 if(address>0x07FFFFFF){
337 uint32_t value = *(uint32_t*)&g_ram[address- 0x07FFFFFF];
338 value = ((value << 8) & 0xFF00FF00 ) | ((value >> 8) & 0xFF00FF );
339 return value << 16 | value >> 16;
342 uint16_t a = read16(address);
343 uint16_t b = read16(address+2);
344 return (a << 16) | b;
347 void m68k_write_memory_8(unsigned int address, unsigned int value){
350 if(address>0x07FFFFFF){
351 g_ram[address- 0x07FFFFFF] = value;
355 write8((uint32_t)address,value);
359 void m68k_write_memory_16(unsigned int address, unsigned int value){
360 // if (address==0xdff030) printf("%c", value);
362 if(address>0x07FFFFFF){
363 uint16_t* dest = (uint16_t*)&g_ram[address- 0x07FFFFFF];
364 value = (value << 8) | (value >> 8);
369 write16((uint32_t)address,value);
373 void m68k_write_memory_32(unsigned int address, unsigned int value){
376 if(address>0x07FFFFFF){
377 uint32_t* dest = (uint32_t*)&g_ram[address- 0x07FFFFFF];
378 value = ((value << 8) & 0xFF00FF00 ) | ((value >> 8) & 0xFF00FF );
379 value = value << 16 | value >> 16;
384 write16(address , value >> 16);
385 write16(address+2 , value );
389 void write32(uint32_t address, uint32_t data){
390 write16(address+2 , data);
391 write16(address , data >>16 );
394 uint32_t read32(uint32_t address){
395 uint16_t a = read16(address+2);
396 uint16_t b = read16(address);
401 void write16(uint32_t address, uint32_t data)
403 asm volatile ("dmb" ::: "memory");
405 // asm volatile ("nop" ::);
406 // asm volatile ("nop" ::);
407 // asm volatile ("nop" ::);
410 *(gpio + 1) = gpfsel1_o;
411 *(gpio + 2) = gpfsel2_o;
413 *(gpio + 7) = (address & 0x0000ffff) << 8;
414 *(gpio + 10) = (~address & 0x0000ffff) << 8;
416 // GPIO_CLR = 1 << 7; //delay
419 *(gpio + 7) = (address >> 16) << 8;
420 *(gpio + 10) = (~address >> 16) << 8;
422 // GPIO_CLR = 1 << 7; //delay
426 *(gpio + 7) = (data & 0x0000ffff) << 8;
427 *(gpio + 10) = (~data & 0x0000ffff) << 8;
429 // GPIO_CLR = 1 << 7; //delay
433 *(gpio + 1) = gpfsel1;
434 *(gpio + 2) = gpfsel2;
435 while ((GET_GPIO(0)));
437 asm volatile ("dmb" ::: "memory");
441 void write8(uint32_t address, uint32_t data)
444 if ((address & 1) == 0)
445 data = data + (data << 8); //EVEN, A0=0,UDS
446 else data = data & 0xff ; //ODD , A0=1,LDS
448 asm volatile ("dmb" ::: "memory");
450 // asm volatile ("nop" ::);
451 // asm volatile ("nop" ::);
452 // asm volatile ("nop" ::);
455 *(gpio + 1) = gpfsel1_o;
456 *(gpio + 2) = gpfsel2_o;
458 *(gpio + 7) = (address & 0x0000ffff) << 8;
459 *(gpio + 10) = (~address & 0x0000ffff) << 8;
461 // GPIO_CLR = 1 << 7; //delay
464 *(gpio + 7) = (address >> 16) << 8;
465 *(gpio + 10) = (~address >> 16) << 8;
467 // GPIO_CLR = 1 << 7; //delay
471 *(gpio + 7) = (data & 0x0000ffff) << 8;
472 *(gpio + 10) = (~data & 0x0000ffff) << 8;
474 // GPIO_CLR = 1 << 7; //delay
478 *(gpio + 1) = gpfsel1;
479 *(gpio + 2) = gpfsel2;
480 while ((GET_GPIO(0)));
482 asm volatile ("dmb" ::: "memory");
486 uint32_t read16(uint32_t address)
489 // while ((GET_GPIO(0)));
490 asm volatile ("dmb" ::: "memory");
492 // asm volatile ("nop" ::);
493 // asm volatile ("nop" ::);
494 // asm volatile ("nop" ::);
497 *(gpio + 1) = gpfsel1_o;
498 *(gpio + 2) = gpfsel2_o;
500 val = address;// & 0x0000FFFF;
501 *(gpio + 7) = (val & 0xffff) << 8;
502 *(gpio + 10) = (~val & 0xffff) << 8;
505 // GPIO_CLR = 1 << 7; //delay
509 *(gpio + 7) = (val & 0xffff) << 8;
510 *(gpio + 10) = (~val & 0xffff) << 8;
512 // GPIO_CLR = 1 << 7; //delay
518 *(gpio + 1) = gpfsel1;
519 *(gpio + 2) = gpfsel2;
522 while (!(GET_GPIO(0)));
526 asm volatile ("dmb" ::: "memory");
527 return (val >>8)&0xffff;
531 uint32_t read8(uint32_t address)
534 // while ((GET_GPIO(0)));
535 asm volatile ("dmb" ::: "memory");
537 // asm volatile ("nop" ::);
538 // asm volatile ("nop" ::);
539 // asm volatile ("nop" ::);
542 *(gpio + 1) = gpfsel1_o;
543 *(gpio + 2) = gpfsel2_o;
545 val = address;// & 0x0000FFFF;
546 *(gpio + 7) = (val & 0xffff) << 8;
547 *(gpio + 10) = (~val & 0xffff) << 8;
550 // GPIO_CLR = 1 << 7; //delay
554 *(gpio + 7) = (val & 0xffff) << 8;
555 *(gpio + 10) = (~val & 0xffff) << 8;
557 // GPIO_CLR = 1 << 7; //delay
563 *(gpio + 1) = gpfsel1;
564 *(gpio + 2) = gpfsel2;
567 while (!(GET_GPIO(0)));
571 asm volatile ("dmb" ::: "memory");
572 // return (val >>8)&0xffff;
574 val = (val >>8)&0xffff;
575 if ((address & 1) == 0)
576 val = (val >> 8) & 0xff ; //EVEN, A0=0,UDS
578 val = val & 0xff ; //ODD , A0=1,LDS
584 /******************************************************/
586 void write_reg(unsigned int value)
588 asm volatile ("dmb" ::: "memory");
590 asm volatile ("nop" ::);
591 asm volatile ("nop" ::);
592 asm volatile ("nop" ::);
593 //Write Status register
599 *(gpio + 1) = gpfsel1_o;
600 *(gpio + 2) = gpfsel2_o;
601 *(gpio + 7) = (value & 0xffff) << 8;
602 *(gpio + 10) = (~value & 0xffff) << 8;
604 GPIO_CLR = 1 << 7; //delay
609 *(gpio + 1) = gpfsel1;
610 *(gpio + 2) = gpfsel2;
611 asm volatile ("dmb" ::: "memory");
615 uint16_t read_reg(void)
619 asm volatile ("dmb" ::: "memory");
621 asm volatile ("nop" ::);
622 asm volatile ("nop" ::);
623 asm volatile ("nop" ::);
626 *(gpio + 1) = gpfsel1;
627 *(gpio + 2) = gpfsel2;
630 GPIO_CLR = 1 << 6; //delay
635 asm volatile ("dmb" ::: "memory");
637 return (uint16_t)(val >> 8);
642 // Set up a memory regions to access GPIO
647 if ((mem_fd = open("/dev/mem", O_RDWR|O_SYNC) ) < 0) {
648 printf("can't open /dev/mem \n");
654 NULL, //Any adddress in our space will do
655 BCM2708_PERI_SIZE, //Map length
656 PROT_READ|PROT_WRITE,// Enable reading & writting to mapped memory
657 MAP_SHARED, //Shared with other processes
658 mem_fd, //File to map
659 BCM2708_PERI_BASE //Offset to GPIO peripheral
662 close(mem_fd); //No need to keep mem_fd open after mmap
664 if (gpio_map == MAP_FAILED) {
665 printf("gpio mmap error %d\n", (int)gpio_map);//errno also set!
669 gpio = ((volatile unsigned *)gpio_map) + GPIO_ADDR/4;
670 gpclk = ((volatile unsigned *)gpio_map) + GPCLK_ADDR/4;