#include <pthread.h>
#include <stdio.h>
#include <string.h>
#include <bcm2835.h>
#include <fcntl.h>
#include <unistd.h>
#include <poll.h>
#define BUFFER_MAX 50
typedef void (*eventHandler)();
int openGPIO(int pin, int direction);
int writeGPIO(int gpio, int value);
int readGPIO(int gpio);
int setEdgeGPIO(int gpio, char *edge);
void *waitInterrupt(void *arg);
int attachGPIO(int gpio, char *edge, eventHandler func);
int fd[32] = {0};
typedef struct
{
int fd;
int gpio;
eventHandler func;
} intVec;
intVec intData;
static int count;
void myIntHandler()
{
count++;
};
int main(int argc, char **argv)
{
attachGPIO(4, "both", myIntHandler);
for (;;)
{
printf("Interrupt %d\n\r", count);
fflush(stdout);
};
return 0;
}
int openGPIO(int gpio, int direction)
{
if (gpio < 0 || gpio > 31)
return -1;
if (direction < 0 || direction > 1)
return -2;
int len;
char buf[BUFFER_MAX];
if (fd[gpio] != 0)
{
close(fd[gpio]);
fd[gpio] = open("/sys/class/gpio/unexport", O_WRONLY);
len = snprintf(buf, BUFFER_MAX, "%d", gpio);
write(fd[gpio], buf, len);
close(fd[gpio]);
fd[gpio] = 0;
}
fd[gpio] = open("/sys/class/gpio/export", O_WRONLY);
len = snprintf(buf, BUFFER_MAX, "%d", gpio);
write(fd[gpio], buf, len);
close(fd[gpio]);
len = snprintf(buf, BUFFER_MAX,
"/sys/class/gpio/gpio%d/direction", gpio);
fd[gpio] = open(buf, O_WRONLY);
if (direction == 1)
{
write(fd[gpio], "out", 4);
close(fd[gpio]);
len = snprintf(buf, BUFFER_MAX,
"/sys/class/gpio/gpio%d/value", gpio);
fd[gpio] = open(buf, O_WRONLY);
}
else
{
write(fd[gpio], "in", 3);
close(fd[gpio]);
len = snprintf(buf, BUFFER_MAX,
"/sys/class/gpio/gpio%d/value", gpio);
fd[gpio] = open(buf, O_RDONLY);
}
return 0;
}
int writeGPIO(int gpio, int b)
{
if (b == 0)
{
write(fd[gpio], "0", 1);
}
else
{
write(fd[gpio], "1", 1);
}
lseek(fd[gpio], 0, SEEK_SET);
return 0;
}
int readGPIO(int gpio)
{
char value_str[3];
int c = read(fd[gpio], value_str, 3);
lseek(fd[gpio], 0, SEEK_SET);
if (value_str[0] == '0')
{
return 0;
}
else
{
return 1;
}
}
int setEdgeGPIO(int gpio, char *edge)
{
char buf[BUFFER_MAX];
int len = snprintf(buf, BUFFER_MAX,
"/sys/class/gpio/gpio%d/edge", gpio);
int fd = open(buf, O_WRONLY);
write(fd, edge, strlen(edge) + 1);
close(fd);
return 0;
}
int attachGPIO(int gpio, char *edge, eventHandler func)
{
openGPIO(gpio, 0);
setEdgeGPIO(gpio, edge);
readGPIO(gpio);
intData.fd = fd[gpio];
intData.gpio = gpio;
intData.func = func;
pthread_t intThread;
if (pthread_create(&intThread,
NULL, waitInterrupt, (void *)&intData))
{
fprintf(stderr, "Error creating thread\n");
return 1;
}
return 0;
}
void *waitInterrupt(void *arg)
{
intVec *intData = (intVec *)arg;
int gpio = intData->gpio;
struct pollfd fdset[1];
fdset[0].fd = intData->fd;
fdset[0].events = POLLPRI;
fdset[0].revents = 0;
for (;;)
{
int rc = poll(fdset, 1, -1);
if (fdset[0].revents & POLLPRI)
{
intData->func();
lseek(fdset[0].fd, 0, SEEK_SET);
readGPIO(gpio);
}
}
pthread_exit(0);
}