From RidgeRun Developer Wiki
gpioin.h
#ifndef GPIOPIN_H
#define GPIOPIN_H
#include <QObject>
class GpIoPin : public QObject{
Q_OBJECT
private:
bool _isOut;
int _ioFd;
uint _currentValue;
uint _pinNumber;
int exportPin();
void openFd();
int setDirection(bool out);
public:
explicit GpIoPin(uint pinNumber, bool isOut = true, QObject *parent = 0);
~GpIoPin();
int getValue(uint* value);
int setEdge(char *edge);
int setValue(uint value);
signals:
public slots:
};
#endif // GPIOPIN_H
gpioin.cpp
#include <fcntl.h>
#include <stdio.h>
#include <syslog.h>
#include <unistd.h>
#include "gpiopin.h"
#define MAX_BUF 64
#define SYSFS_GPIO_DIR "/sys/class/gpio"
void logError(QString methodName, int error){
syslog(LOG_INFO, QString("gpio: %1 error: %2").arg(methodName.toLatin1().constData()).arg(error).toLatin1());
}
GpIoPin::GpIoPin(uint pinNumber, bool isOut, QObject *parent) : QObject(parent){
_currentValue = 2; // Make it out of range to force write if out pin
_ioFd = -1; // Make it invalid to force initial open
_pinNumber = pinNumber;
exportPin();
setDirection(isOut);
}
GpIoPin::~GpIoPin(){
if( 0 <= _ioFd ) close(_ioFd);
}
int GpIoPin::getValue(uint* value){
#ifdef __ARMEL__
if( !_isOut ){
if( 0 > _ioFd ) openFd();
if( 0 > _ioFd ) return _ioFd;
char ch;
read(_ioFd, &ch, 1);
if( ch != '0' ){
*value = 1;
}else{
*value = 0;
}
_currentValue = *value;
}
#endif
return 0;
}
int GpIoPin::exportPin(){
#ifdef __ARMEL__
int fd, len;
char buf[MAX_BUF];
fd = open(SYSFS_GPIO_DIR "/export", O_WRONLY);
if( fd < 0 ){
logError("exportPin", fd);
return fd;
}
len = qsnprintf(buf, sizeof(buf), "%d", _pinNumber);
write(fd, buf, len);
close(fd);
#endif
return 0;
}
void GpIoPin::openFd(){
#ifdef __ARMEL__
int len;
char buf[MAX_BUF];
len = qsnprintf(buf, sizeof(buf), SYSFS_GPIO_DIR "/gpio%d/value", _pinNumber);
if( 0 <= _ioFd ) close(_ioFd );
if( _isOut )
_ioFd = open(buf, O_RDWR);
else
_ioFd = open(buf, O_RDONLY);
if( 0 > _ioFd ){
logError("openIoFd", _ioFd);
}
#endif
}
int GpIoPin::setDirection(bool out){
#ifdef __ARMEL__
int fd, len;
char buf[MAX_BUF];
len = qsnprintf(buf, sizeof(buf), SYSFS_GPIO_DIR "/gpio%d/direction", _pinNumber);
fd = open(buf, O_WRONLY);
if( fd < 0 ){
logError("setDirection", fd);
return fd;
}
if( out ){
write(fd, "out", 4);
}else{
write(fd, "in", 3);
}
close(fd);
#endif
_isOut = out;
return 0;
}
int GpIoPin::setEdge(char *edge){
#ifdef __ARMEL__
int fd, len;
char buf[MAX_BUF];
len = qsnprintf(buf, sizeof(buf), SYSFS_GPIO_DIR "/gpio%d/edge", _pinNumber);
fd = open(buf, O_WRONLY);
if( fd < 0 ){
logError("setEdge", fd);
return fd;
}
write(fd, edge, strlen(edge) + 1);
close(fd);
#endif
return 0;
}
int GpIoPin::setValue(uint value){
#ifdef __ARMEL__
if( _isOut && _currentValue != value ){
if( 0 > _ioFd ) openFd();
if( 0 > _ioFd ) return _ioFd;
if( value ){
write(_ioFd, "1", 2);
}else{
write(_ioFd, "0", 2);
}
_currentValue = value;
}
#endif
return 0;
}