53 #include <sys/types.h> 56 #include <sys/select.h> 64 #include "rnr/rnrconfig.h" 74 static const char *GpioRoot =
"/sys/class/gpio";
93 sprintf(buf,
"%s/gpio%d/direction", GpioRoot, gpio);
95 if( (fd = open(buf, O_RDONLY)) < 0 )
97 LOGSYSERROR(
"open(\"%s\", O_WRONLY)", buf);
101 if( (n = read(fd, buf,
sizeof(buf))) < 0 )
103 LOGSYSERROR(
"read(%d, %p, %zu)", fd, buf,
sizeof(buf));
122 LOGERROR(
"Unknown direction value: \"%s\".", buf);
145 sprintf(buf,
"%s/gpio%d/edge", GpioRoot, gpio);
147 if( (fd = open(buf, O_RDONLY)) < 0 )
149 LOGSYSERROR(
"open(\"%s\", O_WRONLY)", buf);
153 if( (n = read(fd, buf,
sizeof(buf))) < 0 )
155 LOGSYSERROR(
"read(%d, %p, %zu)", fd, buf,
sizeof(buf));
182 LOGERROR(
"Unknown edge value: \"%s\".", buf);
197 sprintf(buf,
"%s/export", GpioRoot);
199 if( (fd = open(buf, O_WRONLY)) < 0 )
201 LOGSYSERROR(
"open(\"%s\", O_WRONLY)", buf);
205 sprintf(buf,
"%d", gpio);
207 if( write(fd, buf, strlen(buf)) < 0 )
209 LOGSYSERROR(
"write(%d, \"%s\", %zu)", fd, buf, strlen(buf));
216 LOGDIAG3(
"Exported GPIO %d interface.", gpio);
226 sprintf(buf,
"%s/unexport", GpioRoot);
228 if( (fd = open(buf, O_WRONLY)) < 0 )
230 LOGSYSERROR(
"open(\"%s\", O_WRONLY)", buf);
234 sprintf(buf,
"%d", gpio);
236 if( write(fd, buf, strlen(buf)) < 0 )
238 LOGSYSERROR(
"write(%d, \"%s\", %zu)", fd, buf, strlen(buf));
245 LOGDIAG3(
"Unexported GPIO %d interface.", gpio);
265 LOGERROR(
"GPIO %d: \"%s\": Invalid direction. Must be one of: %d %d.",
270 sprintf(buf,
"%s/gpio%d/direction", GpioRoot, gpio);
272 if( (fd = open(buf, O_WRONLY)) < 0 )
274 LOGSYSERROR(
"open(\"%s\", O_WRONLY)", buf);
278 if( write(fd, sDir, strlen(sDir)) < 0 )
280 LOGSYSERROR(
"write(%d, \"%s\", %zu)", fd, sDir, strlen(sDir));
287 LOGDIAG3(
"GPIO %d direction set to %s.", gpio, sDir);
313 LOGERROR(
"GPIO %d: \"%s\": Invalid edge. Must be in range [%d-%d].",
318 sprintf(buf,
"%s/gpio%d/edge", GpioRoot, gpio);
320 if( (fd = open(buf, O_WRONLY)) < 0 )
322 LOGSYSERROR(
"open(\"%s\", O_WRONLY)", buf);
326 if( write(fd, sEdge, strlen(sEdge)) < 0 )
328 LOGSYSERROR(
"write(%d, \"%s\", %zu)", fd, sEdge, strlen(sEdge));
335 LOGDIAG3(
"GPIO %d edge set to %s.", gpio, sEdge);
342 LOGERROR(
"Sysfs GPIO pull operation not supported.");
394 sprintf(buf,
"%s/gpio%d/value", GpioRoot, gpio);
396 if( (fd = open(buf, O_RDONLY)) < 0 )
398 LOGSYSERROR(
"open(\"%s\", O_RDONLY)", buf);
402 if( read(fd, &c, 1) < 0 )
404 LOGSYSERROR(
"read(%s, ...)", fd);
409 LOGDIAG3(
"Read GPIO %d value %c.", gpio, c);
411 return c ==
'0'? 0: 1;
420 sprintf(buf,
"%s/gpio%d/value", GpioRoot, gpio);
422 if( (fd = open(buf, O_WRONLY)) < 0 )
424 LOGSYSERROR(
"open(\"%s\", O_WRONLY)", buf);
428 c = value == 0?
'0':
'1';
430 if( write(fd, &c, 1) < 0 )
432 LOGSYSERROR(
"write(%s, \"%c\", 1)", fd, c);
437 LOGDIAG3(
"Wrote GPIO %d value %c.", gpio, c);
454 rc = select(fd+1, NULL, NULL, &efds, NULL);
458 tv.tv_sec = (long)timeout;
459 tv.tv_usec = (long)((timeout - (
double)tv.tv_sec) * 1000000.0);
460 if( tv.tv_usec > 1000000 )
466 rc = select(fd+1, NULL, NULL, &efds, &tv);
472 LOGDIAG3(
"GPIO value changed.");
479 LOGDIAG3(
"GPIO watch timedout.");
486 LOGSYSERROR(
"select(%d, ...)", fd);
497 sprintf(buf,
"%s/gpio%d/value", GpioRoot, gpio);
499 if( (fd = open(buf, O_RDWR)) < 0 )
501 LOGSYSERROR(
"open(\"%s\", O_RDWR)", buf);
505 LOGDIAG3(
"Opened GPIO %d.", gpio);
525 lseek(fd, 0, SEEK_SET);
527 if( read(fd, &c, 1) < 0 )
529 LOGSYSERROR(
"read(%s, ...)", fd);
533 LOGDIAG3(
"Read GPIO value %c.", c);
535 return c ==
'0'? 0: 1;
543 lseek(fd, 0, SEEK_SET);
545 c = value == 0?
'0':
'1';
547 if( write(fd, &c, 1) < 0 )
549 LOGSYSERROR(
"write(%s, \"%c\", 1)", fd, c);
553 LOGDIAG3(
"Wrote GPIO value %c.", c);
561 unsigned int usecIbd)
563 size_t byteCount = (bitCount + 7) / 8;
567 for(i=0, k=0; i<byteCount; ++i)
569 for(j=0, mask=0x80; j<8 && k<bitCount; ++j, ++k)
575 value = pattern[i] & mask? 1: 0;
589 snprintf(buf, size,
"%s/gpio%d", GpioRoot, gpio);
#define GPIO_EDGE_FALLING
falling edge
int gpioClose(int fd)
Close GPIO pin.
int gpioExport(int gpio)
Export (create) a GPIO interface.
#define GPIO_PULL_DS
disable pullup/down
int gpioSetDirection(int gpio, int dir)
Set GPIO signal direction.
int gpio
sysfs exported gpio number
GPIO interface declarations and defines.
#define GPIO_EDGE_BOTH
both edges
#define GPIO_EDGE_FALLING_STR
falling edge string
static int gpioReadDirection(int gpio)
Read GPIO current direction.
int gpioSetPull(int gpio, int pull)
Set GPIO pull.
static int gpioReadEdge(int gpio)
Read GPIO current edge trigger.
#define GPIO_DIR_OUT_STR
output string
int edge
gpio edge type trigger
int gpioRead(int gpio)
Read GPIO pin's current value.
int gpioWrite(int gpio, int value)
Write GPIO value.
int gpioQuickWrite(int fd, int value)
Quick write GPIO pin value.
#define GPIO_EDGE_BOTH_STR
both edges string
#define GPIO_EDGE_NONE_STR
no edge string
int gpioOpen(int gpio)
Open GPIO pin.
#define GPIO_DIR_OUT
output
#define GPIO_DIR_IN_STR
input string
int gpioQuickRead(int fd)
Quick read GPIO pin's current value.
void gpioMakeDirname(int gpio, char buf[], size_t size)
Make GPIO directory name.
#define GPIO_EDGE_NONE
no edge
int gpioProbe(int gpio, gpio_info_t *p)
Safely probe GPIO parameters.
int pin
external header pin number
int gpioNotify(int fd, double timeout)
Notify on GPIO input value change.
#define GPIO_EDGE_RISING_STR
rising edge string
int gpioSetEdge(int gpio, int edge)
Set GPIO edge trigger type.
int gpioBitBang(int fd, byte_t pattern[], size_t bitCount, unsigned int usecIbd)
Bit-bang bits out a GPIO pin.
int gpioUnexport(int gpio)
Unexport (delete) a GPIO interface.
#define GPIO_EDGE_RISING
rising edge