Sample code/C/gpregs

/****************************************************************************/ /*                                                                         */ /*   Copyright (c) 2006 Tim Crawford               */ /*                                                                         */ /*   This program is free software; you can redistribute it and/or modify   */ /*  it under the terms of the GNU General Public License version 2 as      */ /*  published by the Free Software Foundation. */ /*                                                                         */ /*   Alternatively, this software may be distributed under the terms of BSD */ /*  license. */ /*                                                                         */ /*   See README and COPYING for more details. */ /*                                                                         */ /****************************************************************************/ /*   Use this Makefile as an example on how to build:                       */ /*  http://svn.gumstix.org/wikifiles/hello-world/Makefile                  */ /*  This program demonstrates how to program the GPIO                      */ /*                                                                         */ /*   gpio(u32 direction, u32 set_clear, u32 gpio_bit)                       */ /*  example:                                                               */ /*    gpio(OUT, SET, 59); //This will program GPIO(59) as a GPIO function  */ /*                        // set the direction as output, and set the bit  */ /*                                                                         */ /*   gpio_function(u32 gpio_bit, u32 function);                             */ /*  example:                                                               */ /*    gpio_function(59, GPIO); //This will program GPIO(59) as a GPIO funct*/ /*                                                                         */ /*   gpio_direction(u32 gpio_bit, u32 direction)                            */ /*  example:                                                               */ /*    gpio_direction(59, OUT); //This will program GPIO(59) as an output   */ /*                                                                         */ /*   gpio_set(u32 gpio_bit)                                                 */ /*  example:                                                               */ /*    gpio_set(59); //This will program GPIO(59) to a logic 1              */ /*                                                                         */ /*   gpio_clear(u32 gpio_bit)                                               */ /*  example:                                                               */ /*    gpio_clear(59); //This will program GPIO(59) to a logic 0            */ /*                                                                         */ /*   gpio_status(u32 gpio_bit)                                              */ /*  example:                                                               */ /*    i = gpio_status(59); //i is set to the logic level of GPIO(59)       */ /*                                                                         */ /****************************************************************************/
 * 1) include 
 * 2) include 
 * 3) include  // Why is this need twice?
 * 4) include 
 * 5) include 
 * 6) include 
 * 7) include 
 * 8) include 
 * 9) include 
 * 10) include 
 * 11) include 
 * 12) define MAP_SIZE 4096
 * 13) define MAP_MASK ( MAP_SIZE - 1 )
 * 14) define GPLR0  0x40E00000
 * 15) define GPLR1  0x40E00004
 * 16) define GPLR2  0x40E00008
 * 17) define GPDR0  0x40E0000C
 * 18) define GPDR1  0x40E00010
 * 19) define GPDR2  0x40E00014
 * 20) define GPSR0  0x40E00018
 * 21) define GPSR1  0x40E0001C
 * 22) define GPSR2  0x40E00020
 * 23) define GPCR0  0x40E00024
 * 24) define GPCR1  0x40E00028
 * 25) define GPCR2  0x40E0002C
 * 26) define GAFR0_L 0x40E00054
 * 27) define GAFR0_U 0x40E00058
 * 28) define GAFR1_L 0x40E0005C
 * 29) define GAFR1_U 0x40E00060
 * 30) define GAFR2_L 0x40E00064
 * 31) define GAFR2_U 0x40E00068


 * 1) define IN 250
 * 2) define OUT 251
 * 3) define GPIO 0
 * 4) define AF0 0
 * 5) define AF1 1
 * 6) define AF2 2
 * 7) define AF3 3
 * 8) define SET 252
 * 9) define CLEAR 253

typedef unsigned int u32;

void *map, *regaddr; static void putmem(u32 addr, u32 val) {  regaddr = (void*)((u32)map + (addr & MAP_MASK)); *(u32*) regaddr = val; } static int getmem(u32 addr) {   u32 val;

regaddr = (void*)((u32)map + (addr & MAP_MASK)); val = *(u32*) regaddr; return val; } void gpio_set(u32 gpio) {   u32 pos; u32 bit = 1;

pos = gpio / 32; bit <<= gpio % 32; putmem(GPSR0 + (pos * 4), bit); } void gpio_clear(u32 gpio) {   u32 pos; u32 bit = 1;

pos = gpio / 32; bit <<= gpio % 32; putmem(GPCR0 + (pos * 4), bit); } u32 gpio_status(u32 gpio) {   u32 pos; u32 bit = 1; u32 data;

pos = gpio / 32; bit <<= gpio % 32; data = getmem(GPLR0 + (pos * 4)); data &= bit; if (data == 0) return(0); else return(1); } void gpio_direction(u32 gpio, u32 dir) {   u32 pos; u32 bit = 1; u32 data;

pos = gpio / 32; bit <<= gpio % 32; data = getmem(GPDR0 + (pos * 4)); data &= ~bit; if (dir == OUT) data |= bit; putmem(GPDR0 + (pos * 4), data); } void gpio_function(u32 gpio, u32 fun) {   u32 pos; u32 bit = 3; u32 data;

pos = gpio / 16; bit <<= (gpio % 16) * 2; fun <<= (gpio % 16) * 2; data = getmem(GAFR0_L + (pos * 4)); data &= ~bit; data |= fun; putmem(GAFR0_L + (pos * 4), data); } u32 gpio(u32 dir, u32 set, u32 reg) {   if ((dir != IN) & (dir != OUT)){ printf("ERROR: must specify a valid direction\n"); return(1); }   if ((set != SET) & (set != CLEAR)){ printf("ERROR: must specify a valid level\n"); return(1); }   if (reg > 84){ printf("ERROR: not a valid register -->%d\n", reg); return(1); }   gpio_function(reg, GPIO); gpio_direction(reg, dir); if (dir == OUT){ if (set == SET) gpio_set(reg); else gpio_clear(reg); }   return(0); } int main( int argc, char **argv ) {   unsigned int i, ii, rval, speed, count, tmp; int fd; fd = open("/dev/mem", O_RDWR | O_SYNC); if (fd<0) { perror("open(\"/dev/mem\")"); exit(1); }   map = mmap(0,              MAP_SIZE,              PROT_READ | PROT_WRITE,              MAP_SHARED,              fd, // The following was only needed for certain broken revisions of uClibc //#ifdef __ARM_EABI__ //              0x40E00000 / MAP_SIZE //#else              0x40E00000 & ~MAP_MASK //#endif             ); if (map == (void*)-1 ) { perror("mmap"); exit(1); }

/* Set GPIO functions first */ gpio_function(59, GPIO); gpio_function(60, GPIO); gpio_function(84, GPIO);

/* Then set the direction */ gpio_direction(59, IN); gpio_direction(60, OUT); gpio_direction(84, OUT);

/* Now set/clear/read GPIO bits */ gpio_set(84); i = gpio_status(59); printf("GPIO(59) = %d\n", i); if (i) gpio_set(60); else gpio_clear(60);

/* This is another way to program gpio */ gpio(IN, SET, 59); i = gpio_status(59); printf("GPIO(59) = %d\n", i); if (i) gpio(OUT, SET, 60); else gpio(OUT, CLEAR, 60); munmap(0,MAP_SIZE); return 0; }