#include "gpio.h" #include Gpio::Gpio(QObject *parent, int gpio) : QThread(parent),m_gpio(gpio) { exportGpio(); } Gpio::~Gpio() { unexportGpio(); } void Gpio::run() { struct pollfd fdset[2]; int gpio_fd = openGpio(); int nfds = 2; int rc; int timeout = 3000; char buf[64]; bool enabled = true; m_mutex.lock(); m_enabled = true; m_mutex.unlock(); while(enabled){ 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) { qDebug() << "ERROR: poll failed"; return; } if(rc == 0){ //timeout } if (fdset[1].revents & POLLPRI) { read(fdset[1].fd, buf, 64); emit pinInterrupt(); } m_mutex.lock(); enabled = m_enabled; m_mutex.unlock(); } } bool Gpio::exportGpio() { char buf[64]; int fd = open("/sys/class/gpio/export", O_WRONLY); if (fd < 0) { qDebug() << "ERROR: could not open /sys/class/gpio/export"; return false; } int len = snprintf(buf, sizeof(buf), "%d", m_gpio); write(fd, buf, len); close(fd); return true; } bool Gpio::unexportGpio() { char buf[64]; int fd = open("/sys/class/gpio/unexport", O_WRONLY); if (fd < 0) { qDebug() << "ERROR: could not open /sys/class/gpio/unexport"; return false; } int len = snprintf(buf, sizeof(buf), "%d", m_gpio); write(fd, buf, len); close(fd); return true; } int Gpio::openGpio() { char buf[64]; snprintf(buf, sizeof(buf), "/sys/class/gpio/gpio%d/value", m_gpio); int fd = open(buf, O_RDONLY | O_NONBLOCK ); if (fd < 0) { qDebug() << "ERROR: could not open /sys/class/gpio" << m_gpio << "/direction"; return fd; } return fd; } bool Gpio::setDirection(int dir) { char buf[64]; snprintf(buf, sizeof(buf), "/sys/class/gpio/gpio%d/direction", m_gpio); int fd = open(buf, O_WRONLY); if (fd < 0) { qDebug() << "ERROR: could not open /sys/class/gpio" << m_gpio << "/direction"; return false; } if(dir == INPUT){ write(fd, "in", 3); m_dir = INPUT; close(fd); return true; } if(dir == OUTPUT){ write(fd, "out", 4); m_dir = OUTPUT; close(fd); return true; } close(fd); return false; } bool Gpio::setValue(unsigned int value) { // check if gpio is a output if( m_dir == OUTPUT){ char buf[64]; snprintf(buf, sizeof(buf), "/sys/class/gpio/gpio%d/value", m_gpio); int fd = open(buf, O_WRONLY); if (fd < 0) { qDebug() << "ERROR: could not open /sys/class/gpio" << m_gpio << "/value"; return false; } if(value == LOW){ write(fd, "0", 2); close(fd); return true; } if(value == HIGH){ write(fd, "1", 2); close(fd); return true; } close(fd); return false; }else{ qDebug() << "ERROR: Gpio" << m_gpio << "is not a OUTPUT."; return false; } } int Gpio::getValue() { char buf[64]; snprintf(buf, sizeof(buf), "/sys/class/gpio/gpio%d/value", m_gpio); int fd = open(buf, O_RDONLY); if (fd < 0) { qDebug() << "ERROR: could not open /sys/class/gpio" << m_gpio << "/value"; return -1; } char ch; int value = -1; read(fd, &ch, 1); if (ch != '0') { value = 1; }else{ value = 0; } close(fd); qDebug() << "gpio" << m_gpio << "value = " << value; return value; } bool Gpio::setEdgeInterrupt(int edge) { char buf[64]; snprintf(buf, sizeof(buf), "/sys/class/gpio/gpio%d/edge", m_gpio); int fd = open(buf, O_WRONLY); if (fd < 0) { qDebug() << "ERROR: could not open /sys/class/gpio" << m_gpio << "/edge"; return false; } if(edge == EDGE_FALLING){ write(fd, "falling", 8); close(fd); return true; } if(edge == EDGE_RISING){ write(fd, "rising", 7); close(fd); return true; } if(edge == EDGE_BOTH){ write(fd, "both", 5); close(fd); return true; } close(fd); return false; } void Gpio::stop() { m_mutex.lock(); m_enabled = false; m_mutex.unlock(); }