Skip to content

Commit

Permalink
initial commit of the code
Browse files Browse the repository at this point in the history
  • Loading branch information
greenbreakfast committed Jul 26, 2017
1 parent c13ee38 commit 2bb0074
Show file tree
Hide file tree
Showing 2 changed files with 266 additions and 0 deletions.
254 changes: 254 additions & 0 deletions gpioIrq.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,254 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <fcntl.h>
#include <poll.h>

/****************************************************************
* Constants
****************************************************************/

#define SYSFS_GPIO_DIR "/sys/class/gpio"
#define POLL_TIMEOUT (3 * 1000) /* 3 seconds */
#define MAX_BUF 64

/****************************************************************
* gpio_export
****************************************************************/
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;
}

/****************************************************************
* gpio_unexport
****************************************************************/
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/export");
return fd;
}

len = snprintf(buf, sizeof(buf), "%d", gpio);
write(fd, buf, len);
close(fd);
return 0;
}

/****************************************************************
* gpio_set_dir
****************************************************************/
int gpio_set_dir(unsigned int gpio, unsigned 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("gpio/direction");
return fd;
}

if (out_flag)
write(fd, "out", 4);
else
write(fd, "in", 3);

close(fd);
return 0;
}

/****************************************************************
* gpio_set_value
****************************************************************/
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;
}

/****************************************************************
* gpio_get_value
****************************************************************/
int gpio_get_value(unsigned int gpio, unsigned int *value)
{
int fd, len;
char buf[MAX_BUF];
char ch;

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 != '0') {
*value = 1;
} else {
*value = 0;
}

close(fd);
return 0;
}


/****************************************************************
* gpio_set_edge
****************************************************************/

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;
}

/****************************************************************
* gpio_fd_open
****************************************************************/

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;
}

/****************************************************************
* gpio_fd_close
****************************************************************/

int gpio_fd_close(int fd)
{
return close(fd);
}

/****************************************************************
* Main
****************************************************************/
int main(int argc, char **argv, char **envp)
{
struct pollfd fdset[2];
int nfds = 2;
int gpio_fd, timeout, rc;
char *buf[MAX_BUF];
unsigned int gpio;
int len;
int val;



if (argc < 2) {
printf("Usage: gpioIrq <gpio-pin>\n\n");
printf("Waits for a change in the GPIO pin voltage level or input on stdin\n");
exit(-1);
}

gpio = atoi(argv[1]);

gpio_export(gpio);
gpio_set_dir(gpio, 0);
gpio_set_edge(gpio, "rising");
gpio_fd = gpio_fd_open(gpio);

timeout = POLL_TIMEOUT;

while (1) {
memset((void*)fdset, 0, sizeof(fdset));

fdset[0].fd = STDIN_FILENO;
fdset[0].events = POLLIN;

fdset[1].fd = gpio_fd;
fdset[1].events = POLLPRI;

rc = poll(fdset, nfds, timeout);

if (rc < 0) {
printf("\npoll() failed!\n");
return -1;
}

if (rc == 0) {
printf(".");
}

if (fdset[1].revents & POLLPRI) {
lseek(fdset[1].fd, 0, SEEK_SET);
len = read(fdset[1].fd, buf, MAX_BUF);
printf("\npoll() GPIO %d interrupt occurred\n", gpio);
printf("\tread value: '%c'\n", buf[0]);
}

if (fdset[0].revents & POLLIN) {
(void)read(fdset[0].fd, buf, 1);
printf("\npoll() stdin read 0x%2.2X\n", (unsigned int) buf[0]);
}

fflush(stdout);
}

gpio_fd_close(gpio_fd);
return 0;
}
12 changes: 12 additions & 0 deletions makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# main compiler
CC := gcc

TARGET1 := gpioIrq
all: $(TARGET1)

$(TARGET1):
@echo "Compiling C program"
$(CC) $(CFLAGS) $(TARGET1).c -o $(TARGET1)

clean:
@rm -rf $(TARGET1)

0 comments on commit 2bb0074

Please sign in to comment.