]> Git Repo - pov-display-rpi.git/blob - src/GPIO.c
oops array indexing was off
[pov-display-rpi.git] / src / GPIO.c
1 //
2 //  How to access GPIO registers from C-code on the Raspberry-Pi
3 //  Example program
4 //  15-January-2012
5 //  Dom and Gert
6 //  Revised: 15-Feb-2013
7
8
9 // Access from ARM Running Linux
10
11 #define BCM2708_PERI_BASE        0xFE000000
12 #define GPIO_BASE                (BCM2708_PERI_BASE + 0x200000) /* GPIO controller */
13
14
15 #include "common.h"
16 #include <fcntl.h>
17 #include <sys/mman.h>
18
19 #define PAGE_SIZE (4*1024)
20 #define BLOCK_SIZE (4*1024)
21
22 int  mem_fd;
23 void *gpio_map;
24
25 // I/O access
26 volatile unsigned *gpio;
27
28
29 // GPIO setup macros. Always use INP_GPIO(x) before using OUT_GPIO(x) or SET_GPIO_ALT(x,y)
30 #define INP_GPIO(g) *(gpio+((g)/10)) &= ~(7<<(((g)%10)*3))
31 #define OUT_GPIO(g) *(gpio+((g)/10)) |=  (1<<(((g)%10)*3))
32 #define SET_GPIO_ALT(g,a) *(gpio+(((g)/10))) |= (((a)<=3?(a)+4:(a)==4?3:2)<<(((g)%10)*3))
33
34 #define GPIO_SET *(gpio+7)  // sets   bits which are 1 ignores bits which are 0
35 #define GPIO_CLR *(gpio+10) // clears bits which are 1 ignores bits which are 0
36
37 #define GET_GPIO(g) (*(gpio+13)&(1<<g)) // 0 if LOW, (1<<g) if HIGH
38
39 #define GPIO_PULL *(gpio+37) // Pull up/pull down
40 #define GPIO_PULLCLK0 *(gpio+38) // Pull up/pull down clock
41 extern int GPIORead(int pin){
42         return GET_GPIO(pin);
43 }
44 extern void GPIOPinmode(int pin,int dir){
45         INP_GPIO(pin);
46         if(dir)
47                 OUT_GPIO(pin);
48         
49 }
50 extern int GPIOInit()
51 {
52    /* open /dev/mem */
53    if ((mem_fd = open("/dev/mem", O_RDWR|O_SYNC) ) < 0) {
54       printf("can't open /dev/mem \n");
55       return -1;
56    }
57
58    /* mmap GPIO */
59    gpio_map = mmap(
60       NULL,             //Any adddress in our space will do
61       BLOCK_SIZE,       //Map length
62       PROT_READ|PROT_WRITE,// Enable reading & writting to mapped memory
63       MAP_SHARED,       //Shared with other processes
64       mem_fd,           //File to map
65       GPIO_BASE         //Offset to GPIO peripheral
66    );
67
68    close(mem_fd); //No need to keep mem_fd open after mmap
69
70    if (gpio_map == MAP_FAILED) {
71       printf("mmap error %llu\n", (uint64_t)gpio_map);//errno also set!
72       return -1;
73    }
74
75    // Always use volatile pointer!
76    gpio = (volatile unsigned *)gpio_map;
77         return 0;
78 }
This page took 0.02791 seconds and 4 git commands to generate.