Raspberry piのレジスタを直接たたいてI/O制御 with C言語

gpio_c.c

#define BCM2708_PERI_BASE 0x20000000
#define GPIO_BASE (BCM2708_PERI_BASE + 0x200000)

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <dirent.h>
#include <fcntl.h>
#include <assert.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>

#include <unistd.h>

#define PAGE_SIZE (4*1024)
#define BLOCK_SIZE (4*1024)

int mem_fd;
char *gpio_mem, *gpio_map;
char *spi0_mem, *spi0_map;

volatile unsigned *gpio;


#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)
#define GPIO_CLR * (gpio+10)
#define GPIO_GET * (gpio+13)
#define MAX_PORTNUM 25

char valid_port[] = 
{
	1,1,0,0,
	0,0,0,1,
	1,1,1,1,
	0,0,1,1,
	0,1,1,0,
	0,1,1,1,
	1,1
};

void setup_io();

int port_avail(int port)
{
	if((port < 0) || (port > MAX_PORTNUM))
		return(0);
	return ((int)valid_port[port]);
}

int gpio_read(int port)
{
	if(!port_avail(port))
		return(0);
	return((GPIO_GET & (1<<port)) ?1:0);
}

int gpio_write(int port,int data)
{
	if(!port_avail(port))
		return;
	if(data==0)
		GPIO_CLR = 1<<port;
	else
		GPIO_SET = 1 << port;
}

int initcount = 0;
void setup_io()
{
	initcount++;
	if((mem_fd = open("/dev/mem", O_RDWR | O_SYNC)) < 0) {
		printf("can't open /dev/mem \n");
	exit(-1);
}

if((gpio_mem = malloc(BLOCK_SIZE + (PAGE_SIZE-1))) == NULL) {
	printf("allocation error \n");;
	exit(-1);
}

if((unsigned long) gpio_mem % PAGE_SIZE)
	gpio_mem += PAGE_SIZE - ((unsigned long)gpio_mem % PAGE_SIZE);

gpio_map = (char *)mmap (
	(caddr_t)gpio_mem,
	BLOCK_SIZE,
	PROT_READ | PROT_WRITE,
	MAP_SHARED | MAP_FIXED,
	mem_fd,
	GPIO_BASE
);

 if((long)gpio_map < 0){
	printf("mmap error %d\n",(int)gpio_map);
	exit(-1);
}

gpio = (volatile unsigned *)gpio_map;

}


void gpio_init() 
{
	int i;
	setup_io();
	for (i=0;i<1;i++){
		INP_GPIO(i);
	}
	for(i=7;i<+11;i++){
		INP_GPIO(i);
		OUT_GPIO(i);
	}
}

void testmain()
{
	int p;
	for(p=7;p<=11;p++){
		gpio_write(p,1);
		sleep(1);
	}
	for(p=0;p<2;p++){
		printf("%d:",gpio_read(p));
		}
	printf("\n");
	for(p=7;p<=11;p++){
		gpio_write(p,0);
		sleep(1);
	}
	for(p=0;p<2;p++){
		printf("%d:",gpio_read(p));

	}
	printf("\n");
}

int main(int argc, char **argv)
{
	gpio_init();
	testmain();
	return 0;
}
$ cc -o gpio_c gpio_c.c
$ sudo ./gpio_c