#include<stdio.h>
#include <stdlib.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<unistd.h>
#include<errno.h>
#include<string.h>
#include <poll.h>
#define SYSFS_GPIO_DIR "/sys/class/gpio"
#define GPIO_LED 41
#define MAX_BUF 60
#define POLL_TIMEOUT (3 * 1000) /* 3 seconds */
#define OUT 1
#define IN 0
int
gpio_export(unsigned
int
gpio)
{
int
fd ,len;
char
buf[MAX_BUF];
fd = open(SYSFS_GPIO_DIR
"/export"
,O_WRONLY);
if
(fd < 0) {
perror
(
"gpio/export"
);
return
fd;
}
len = snprintf(buf ,
sizeof
(buf) ,
"%d"
,gpio);
write(fd ,buf ,len);
close(fd);
return
0;
}
int
gpio_unexport(unsigned
int
gpio)
{
int
fd ,len;
char
buf[MAX_BUF];
fd = open(SYSFS_GPIO_DIR
"/unexport"
,O_WRONLY);
if
(fd < 0) {
perror
(
"gpio/unexport"
);
return
fd;
}
len = snprintf(buf ,
sizeof
(buf) ,
"%d"
,gpio);
write(fd ,buf ,len);
close(fd);
return
0;
}
int
gpio_set_dir(unsigned
int
gpio ,
int
out_flag)
{
int
fd ,len;
char
buf[MAX_BUF];
len = snprintf(buf,
sizeof
(buf), SYSFS_GPIO_DIR
"/gpio%d/direction"
, gpio);
fd = open(buf ,O_WRONLY);
if
(fd < 0) {
perror
(buf);
return
fd;
}
if
(out_flag)
write(fd ,
"out"
,4);
else
write(fd ,
"in"
,3);
close(fd);
return
0;
}
int
gpio_set_value(unsigned
int
gpio, unsigned
int
value)
{
int
fd, len;
char
buf[MAX_BUF];
len = snprintf(buf,
sizeof
(buf), SYSFS_GPIO_DIR
"/gpio%d/value"
, gpio);
fd = open(buf, O_WRONLY);
if
(fd < 0) {
perror
(
"gpio/set-value"
);
return
fd;
}
if
(value)
write(fd,
"1"
, 2);
else
write(fd,
"0"
, 2);
close(fd);
return
0;
}
int
gpio_get_value(unsigned
int
gpio, unsigned
int
*value)
{
int
fd, len;
char
ch;
char
buf[MAX_BUF];
len = snprintf(buf ,
sizeof
(buf), SYSFS_GPIO_DIR
"/gpio%d/value"
,gpio);
fd = open(buf ,O_RDONLY);
if
(fd < 0) {
perror
(
"gpio_get_value"
);
return
fd;
}
read(fd ,&ch ,1);
if
(ch ==
'1'
)
*value = 1;
else
if
(ch ==
'0'
)
*value = 0;
close(fd);
return
0;
}
int
gpio_set_edge(unsigned
int
gpio ,
char
*edge)
{
int
fd ,len;
char
buf[MAX_BUF];
len = snprintf(buf ,
sizeof
(buf) ,SYSFS_GPIO_DIR
"/gpio%d/edge"
,gpio);
fd = open(buf ,O_WRONLY);
if
(fd < 0) {
perror
(
"gpio_set_edge"
);
return
fd;
}
write(fd ,edge ,
strlen
(edge) + 1);
close(fd);
return
0;
}
int
gpio_fd_open(unsigned
int
gpio)
{
int
fd, len;
char
buf[MAX_BUF];
len = snprintf(buf,
sizeof
(buf), SYSFS_GPIO_DIR
"/gpio%d/value"
, gpio);
fd = open(buf, O_RDONLY | O_NONBLOCK );
if
(fd < 0) {
perror
(
"gpio/fd_open"
);
}
return
fd;
}
int
gpio_fd_close(
int
fd)
{
return
close(fd);
}
int
main(
int
argc,
char
**argv)
{
struct
pollfd *fdset;
int
nfds = 1;
int
gpio_fd, timeout, rc;
char
*buf[MAX_BUF];
unsigned
int
gpio;
int
len;
char
*cmd;
unsigned
int
value;
fdset = (
struct
pollfd*)
malloc
(
sizeof
(
struct
pollfd));
if
(argc < 3) {
printf
(
"Usage: %s <gpio-pin> <direction> [value]\n\n"
, argv[0]);
exit
(-1);
}
cmd = argv[2];
gpio =
atoi
(argv[1]);
gpio_export(gpio);
if
(
strcmp
(cmd,
"interrupt"
) == 0) {
printf
(
"\n**************************GPIO interrupt***************************\n"
);
gpio_set_dir(gpio, IN);
gpio_set_edge(gpio,
"rising"
);
gpio_fd = gpio_fd_open(gpio);
timeout = POLL_TIMEOUT;
while
(1) {
memset
((
void
*)fdset, 0,
sizeof
(fdset));
fdset->fd = gpio_fd;
fdset->events = POLLPRI;
rc = poll(fdset, nfds, timeout);
if
(rc < 0) {
printf
(
"\npoll() failed!\n"
);
return
-1;
}
if
(rc == 0) {
printf
(
"."
);
}
if
(fdset->revents & POLLPRI) {
len = read(fdset->fd, buf, MAX_BUF);
printf
(
"\nGPIO %d interrupt occurred\n"
, gpio);
}
fflush
(stdout);
}
gpio_fd_close(gpio_fd);
}
else
if
(
strcmp
(cmd,
"out"
) == 0) {
gpio_set_dir(gpio, OUT);
if
(argc = 4) {
gpio_set_value(gpio,
atoi
(argv[3]));
printf
(
"gpio%d is set to %d\n"
, gpio,
atoi
(argv[3]));
}
}
else
if
(
strcmp
(cmd,
"in"
) == 0) {
gpio_set_dir(gpio, IN);
printf
(
"\n"
);
while
(1) {
gpio_get_value(gpio, &value);
printf
(
"\rvalue:%d"
, value);
}
}
else
if
(
strcmp
(cmd,
"unexport"
) == 0) {
gpio_unexport(gpio);
}
else
{
printf
(
"Usage: %s <gpio-pin> <direction> [value]\n\n"
, argv[0]);
exit
(-1);
}
return
0;
}