raw gpio access pi


// BCM2835-ARM-Peripherals.pdf section 6.1

// Each GPFSELn has 10 x 3 bits (with bits 31:30 reserved) ‘b000 = i/p, ‘b001 = o/p, others = alternate uses
// Always use INP_GPIO(x) before using OUT_GPIO(x) as this will force 000 before setting 001

#define INP_GPIO(g) *(gpio+((g)/10)) &= ~(7<<(((g)%10)*3)) // existing bits ANDed with 111..111000111..111
#define OUT_GPIO(g) *(gpio+((g)/10)) |= (1<<(((g)%10)*3)) // existing bits ORed with 000..000001000..000

// GPSETn is at PERI_BASE + GPIO_BASE + 0x1C bytes. 0x1C = 28 bytes = 7 dwords
#define GPIO_SET *(gpio+7) // assigning 1<<n will set bit(n) only

// GPCLRn is at PERI_BASE + GPIO_BASE + 0x28 bytes. 0x28 = 40 bytes = 10 dwords
#define GPIO_CLR *(gpio+10) // assigning 1<<n will clear bit(n) only

//  //  How to access GPIO registers from C-code on the Raspberry-Pi  //  Example program  //  15-January-2012  //  Dom and Gert  //  Revised: 01-01-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     #define PAGE_SIZE (4*1024)  #define BLOCK_SIZE (4*1024)    int  mem_fd;  char *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    void setup_io();    int main(int argc, char **argv)  {    int g,rep;      // Set up gpi pointer for direct register access    setup_io();      // Switch GPIO 7..11 to output mode     /************************************************************************\    * 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! *   \************************************************************************/      // Set GPIO pins 7-11 to output    for (g=7; g<=11; g++)    {      INP_GPIO(g); // must use INP_GPIO before we can use OUT_GPIO      OUT_GPIO(g);    }      for (rep=0; rep<10; rep++)    {       for (g=7; g<=11; g++)       {         GPIO_SET = 1<<g;         sleep(1);       }       for (g=7; g<=11; g++)       {         GPIO_CLR = 1<<g;         sleep(1);       }    }      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) {        printf("can't open /dev/mem \n");        exit(-1);     }       /* mmap GPIO */     gpio_map = (char *)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 ((long)gpio_map < 0) {        printf("mmap error %d\n", (int)gpio_map);        exit(-1);     }       // Always use volatile pointer!     gpio = (volatile unsigned *)gpio_map;      } // setup_io

Advertisements
This entry was posted in Raspberry Pi. Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s