// // How to access GPIO registers from C-code on the Raspberry-Pi // Example program // 15-January-2012 // Dom and Gert // Revised: 15-Feb-2013 // Access from ARM Running Linux #define BCM2708_PERI_BASE 0x20000000 #define GPIO_BASE (BCM2708_PERI_BASE + 0x200000) /* GPIO controller */ #include #include #include #include #include #include #include #define PAGE_SIZE (4*1024) #define BLOCK_SIZE (4*1024) #define SER_DAT_PIN 26 #define SER_CLK_PIN 19 #define GATE_PIN 13 #define PAR_CLK_PIN 6 #define SENSE_PIN 5 int mem_fd; void *gpio_map; // I/O access volatile unsigned *gpio; // GPIO setup macros. Always use INP_GPIO(x) before using OUT_GPIO(x) or SET_GPIO_ALT(x,y) #define INP_GPIO(g) *(gpio+((g)/10)) &= ~(7<<(((g)%10)*3)) #define OUT_GPIO(g) *(gpio+((g)/10)) |= (1<<(((g)%10)*3)) #define SET_GPIO_ALT(g,a) *(gpio+(((g)/10))) |= (((a)<=3?(a)+4:(a)==4?3:2)<<(((g)%10)*3)) #define GPIO_SET *(gpio+7) // sets bits which are 1 ignores bits which are 0 #define GPIO_CLR *(gpio+10) // clears bits which are 1 ignores bits which are 0 #define GPIO_ALTER(a) *(gpio+(a==0?10:7)) // alters (a==0: clear, else: set) bits which are 1 ignores bits which are 0 #define GET_GPIO(g) (*(gpio+13)&(1< bit is 1 <- port is HIGH=3.3V printf("Button pressed!\n"); else // port is LOW=0V printf("Button released!\n"); } int main(int argc, char **argv) { int rep; // Set up gpi pointer for direct register access // setup_io(); // Drop root privileges drop_privileges(); /************************************************************************\ * You are about to change the GPIO settings of your computer. * * Mess this up and it will stop working! * * It might be a good idea to 'sync' before running this program * * so at least you still have your code changes written to the SD-card! * \************************************************************************/ // must use INP_GPIO before we can use OUT_GPIO INP_GPIO(SER_DAT_PIN); OUT_GPIO(SER_DAT_PIN); INP_GPIO(SER_CLK_PIN); OUT_GPIO(SER_CLK_PIN); INP_GPIO(GATE_PIN); OUT_GPIO(GATE_PIN); INP_GPIO(PAR_CLK_PIN); OUT_GPIO(PAR_CLK_PIN); INP_GPIO(SENSE_PIN); put_on_display("0123456789abcdefghijklmnopqrstuvwxy"); return 0; } // main // // 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) { perror("can't open /dev/mem"); exit(-1); } /* mmap GPIO */ gpio_map = mmap( NULL, //Any adddress in our space will do BLOCK_SIZE, //Map length PROT_READ|PROT_WRITE,// Enable reading & writting to mapped memory MAP_SHARED, //Shared with other processes mem_fd, //File to map GPIO_BASE //Offset to GPIO peripheral ); close(mem_fd); //No need to keep mem_fd open after mmap if (gpio_map == MAP_FAILED) { perror("mmap error"); exit(-1); } // Always use volatile pointer! gpio = (volatile unsigned *)gpio_map; } // setup_io // // Drop (root) privileges // void drop_privileges() { /* Drop superuser privileges in correct order */ if (setgid(99) == -1) { perror("can't drop group privileges"); exit(-1); } if (setuid(99) == -1) { perror("can't drop user privileges"); exit(-1); } } // drop_root // // Shift the bits provided in content into the display // void put_on_display(char *content) { char *raw_output; int line; raw_output = malloc(7*(5+1)); if (raw_output == NULL) { perror("malloc failed"); exit(-1); } for (line=0; line<7; line++) { raw_output[line*6] = 1<>bit) & 0x01) = 1<