Skip to content

Instantly share code, notes, and snippets.

@masquaremo
Last active December 11, 2015 19:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save masquaremo/4647697 to your computer and use it in GitHub Desktop.
Save masquaremo/4647697 to your computer and use it in GitHub Desktop.
雑誌インターフェース 2012年12月号のGPIO制御のコードがRev1用みたいだったのでRev2用に修正。 また、GPIO4がなぜか無効になっていた(何故かはよくわからない)ので使えるようにした。
//
// How to access GPIO registers from C-code on the Raspberry-Pi
// Example program
// 15-January-2012
// Dom and Gert
//
// Access from ARM Running Linux
#define BCM2708_PERI_BASE 0x20000000
#define GPIO_BASE (BCM2708_PERI_BASE + 0x200000) /* GPIO controller */
#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;
// 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_GET *(gpio+13) // read bits
#define REV2 // for rev2 board
#ifdef REV2
#define MAX_PORTNUM 27
char valid_port[] = {
0,0,1,1, // 0..3
1,0,0,1, // 4..7
1,1,1,1, // 8..11
0,0,1,1, // 12..15
0,1,1,0, // 16..19
0,0,1,1, // 20..23
1,1,0,1, // 24..27
};
#else
#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
};
#endif
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);
}
void gpio_write(int port, int data)
{
if (!port_avail(port)) {
printf("illigal port:%d\n", port);
return;
}
if (data == 0)
GPIO_CLR = 1<<port;
else
GPIO_SET = 1<<port;
}
//
// Set up a memory regions to access GPIO
//
int initcount= 0;
void setup_io()
{
initcount++;
/* 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 */
// Allocate MAP block
if ((gpio_mem = malloc(BLOCK_SIZE + (PAGE_SIZE-1))) == NULL) {
printf("allocation error \n");
exit (-1);
}
// Make sure pointer is on 4K boundary
if ((unsigned long)gpio_mem % PAGE_SIZE)
gpio_mem += PAGE_SIZE - ((unsigned long)gpio_mem % PAGE_SIZE);
// Now map it
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);
}
// Always use volatile pointer!
gpio = (volatile unsigned *)gpio_map;
} // setup_io
void gpio_init()
{
int i;
setup_io();
#if 1 // modify. test gpio4
INP_GPIO(4); // must use INP_GPIO before we can use OUT_GPIO
OUT_GPIO(4);
#else
for (i=0; i<1; i++) {
INP_GPIO(i);
}
for (i=7; i<=11; i++) {
INP_GPIO(i); // must use INP_GPIO before we can use OUT_GPIO
OUT_GPIO(i);
}
#endif
}
void testmain()
{
#if 1 // modify. test gpio4
int i;
for(i = 0; i < 10; i++) {
gpio_write(4, 1);
sleep(1);
gpio_write(4, 0);
sleep(1);
}
#else
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");
#endif
}
int main(int argc, char **argv)
{
gpio_init();
testmain();
return 0;
} // main
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment