added GpioMonitor
This commit is contained in:
parent
477a95477b
commit
3ffc015c01
@ -53,17 +53,19 @@ Gpio::~Gpio()
|
||||
/*! Returns true if the GPIO could be exported in the system file "/sys/class/gpio/export".*/
|
||||
bool Gpio::exportGpio()
|
||||
{
|
||||
unexportGpio();
|
||||
|
||||
char buf[64];
|
||||
|
||||
int fd = open("/sys/class/gpio/export", O_WRONLY);
|
||||
if (fd < 0) {
|
||||
//qDebug() << "ERROR: could not open /sys/class/gpio/export";
|
||||
qDebug() << "ERROR: could not open /sys/class/gpio/export";
|
||||
return false;
|
||||
}
|
||||
|
||||
ssize_t len = snprintf(buf, sizeof(buf), "%d", m_gpio);
|
||||
if(write(fd, buf, len) != len){
|
||||
qDebug() << "ERROR: could not set edge interrupt";
|
||||
qDebug() << "ERROR: could not write to gpio (export)";
|
||||
close(fd);
|
||||
return false;
|
||||
}
|
||||
@ -78,13 +80,13 @@ bool Gpio::unexportGpio()
|
||||
|
||||
int fd = open("/sys/class/gpio/unexport", O_WRONLY);
|
||||
if (fd < 0) {
|
||||
//qDebug() << "ERROR: could not open /sys/class/gpio/unexport";
|
||||
qDebug() << "ERROR: could not open /sys/class/gpio/unexport";
|
||||
return false;
|
||||
}
|
||||
|
||||
ssize_t len = snprintf(buf, sizeof(buf), "%d", m_gpio);
|
||||
if(write(fd, buf, len) != len){
|
||||
qDebug() << "ERROR: could not set edge interrupt";
|
||||
//qDebug() << "ERROR: could not write to gpio (unexport)";
|
||||
close(fd);
|
||||
return false;
|
||||
}
|
||||
@ -101,7 +103,7 @@ int Gpio::openGpio()
|
||||
|
||||
int fd = open(buf, O_RDONLY | O_NONBLOCK );
|
||||
if (fd < 0) {
|
||||
//qDebug() << "ERROR: could not open /sys/class/gpio" << m_gpio << "/direction";
|
||||
qDebug() << "ERROR: could not open /sys/class/gpio" << m_gpio << "/direction";
|
||||
return fd;
|
||||
}
|
||||
return fd;
|
||||
@ -129,12 +131,12 @@ bool Gpio::setDirection(int dir)
|
||||
|
||||
int fd = open(buf, O_WRONLY);
|
||||
if (fd < 0) {
|
||||
//qDebug() << "ERROR: could not open /sys/class/gpio" << m_gpio << "/direction";
|
||||
qDebug() << "ERROR: could not open /sys/class/gpio" << m_gpio << "/direction";
|
||||
return false;
|
||||
}
|
||||
if(dir == INPUT){
|
||||
if(write(fd, "in", 3) != 3){
|
||||
qDebug() << "ERROR: could not write to gpio";
|
||||
qDebug() << "ERROR: could not write to gpio (set INPUT)";
|
||||
close(fd);
|
||||
return false;
|
||||
}
|
||||
@ -144,7 +146,7 @@ bool Gpio::setDirection(int dir)
|
||||
}
|
||||
if(dir == OUTPUT){
|
||||
if(write(fd, "out", 4) != 4){
|
||||
qDebug() << "ERROR: could not write to gpio";
|
||||
qDebug() << "ERROR: could not write to gpio (set OUTPUT)";
|
||||
close(fd);
|
||||
return false;
|
||||
}
|
||||
@ -155,6 +157,7 @@ bool Gpio::setDirection(int dir)
|
||||
close(fd);
|
||||
return false;
|
||||
}
|
||||
|
||||
/*! Returns true, if the digital \a value of the GPIO could be set correctly.
|
||||
*
|
||||
* Possible \a value 's are:
|
||||
@ -179,13 +182,13 @@ bool Gpio::setValue(unsigned int value)
|
||||
|
||||
int fd = open(buf, O_WRONLY);
|
||||
if (fd < 0) {
|
||||
//qDebug() << "ERROR: could not open /sys/class/gpio" << m_gpio << "/value";
|
||||
qDebug() << "ERROR: could not open /sys/class/gpio" << m_gpio << "/value";
|
||||
return false;
|
||||
}
|
||||
|
||||
if(value == LOW){
|
||||
if(write(fd, "0", 2) != 2){
|
||||
qDebug() << "ERROR: could not write to gpio";
|
||||
qDebug() << "ERROR: could not write to gpio (set LOW)";
|
||||
close(fd);
|
||||
return false;
|
||||
}
|
||||
@ -194,7 +197,7 @@ bool Gpio::setValue(unsigned int value)
|
||||
}
|
||||
if(value == HIGH){
|
||||
if(write(fd, "1", 2) != 2){
|
||||
qDebug() << "ERROR: could not write to gpio";
|
||||
qDebug() << "ERROR: could not write to gpio (set HIGH)";
|
||||
close(fd);
|
||||
return false;
|
||||
}
|
||||
@ -204,10 +207,11 @@ bool Gpio::setValue(unsigned int value)
|
||||
close(fd);
|
||||
return false;
|
||||
}else{
|
||||
qDebug() << "ERROR: Gpio" << m_gpio << "is not a OUTPUT.";
|
||||
qDebug() << "ERROR: Gpio" << m_gpio << "is not an OUTPUT.";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/*! Returns the current digital value of the GPIO.
|
||||
*
|
||||
* Possible values are:
|
||||
@ -231,7 +235,7 @@ int Gpio::getValue()
|
||||
|
||||
int fd = open(buf, O_RDONLY);
|
||||
if (fd < 0) {
|
||||
//qDebug() << "ERROR: could not open /sys/class/gpio" << m_gpio << "/value";
|
||||
qDebug() << "ERROR: could not open /sys/class/gpio" << m_gpio << "/value";
|
||||
return -1;
|
||||
}
|
||||
char ch;
|
||||
@ -248,8 +252,6 @@ int Gpio::getValue()
|
||||
value = 0;
|
||||
}
|
||||
close(fd);
|
||||
|
||||
//qDebug() << "gpio" << m_gpio << "value = " << value;
|
||||
return value;
|
||||
}
|
||||
|
||||
@ -279,13 +281,13 @@ bool Gpio::setEdgeInterrupt(int edge)
|
||||
|
||||
int fd = open(buf, O_WRONLY);
|
||||
if (fd < 0) {
|
||||
//qDebug() << "ERROR: could not open /sys/class/gpio" << m_gpio << "/edge";
|
||||
qDebug() << "ERROR: could not open /sys/class/gpio" << m_gpio << "/edge";
|
||||
return false;
|
||||
}
|
||||
|
||||
if(edge == EDGE_FALLING){
|
||||
if(write(fd, "falling", 8) != 8){
|
||||
qDebug() << "ERROR: could not set edge interrupt";
|
||||
qDebug() << "ERROR: could not write to gpio (set EDGE_FALLING)";
|
||||
close(fd);
|
||||
return false;
|
||||
}
|
||||
@ -294,7 +296,7 @@ bool Gpio::setEdgeInterrupt(int edge)
|
||||
}
|
||||
if(edge == EDGE_RISING){
|
||||
if(write(fd, "rising", 7) != 7){
|
||||
qDebug() << "ERROR: could not set edge interrupt";
|
||||
qDebug() << "ERROR: could not write to gpio (set EDGE_RISING)";
|
||||
close(fd);
|
||||
return false;
|
||||
}
|
||||
@ -303,7 +305,7 @@ bool Gpio::setEdgeInterrupt(int edge)
|
||||
}
|
||||
if(edge == EDGE_BOTH){
|
||||
if(write(fd, "both", 5) != 5){
|
||||
qDebug() << "ERROR: could not set edge interrupt";
|
||||
qDebug() << "ERROR: could not write to gpio (set EDGE_BOTH)";
|
||||
close(fd);
|
||||
return false;
|
||||
}
|
||||
@ -313,3 +315,51 @@ bool Gpio::setEdgeInterrupt(int edge)
|
||||
close(fd);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Gpio::setActiveLow(bool activeLow)
|
||||
{
|
||||
char buf[64];
|
||||
snprintf(buf, sizeof(buf), "/sys/class/gpio/gpio%d/active_low", m_gpio);
|
||||
int fd = open(buf, O_WRONLY);
|
||||
if (fd < 0) {
|
||||
qDebug() << "ERROR: could not open /sys/class/gpio" << m_gpio << "/active_low";
|
||||
return false;
|
||||
}
|
||||
|
||||
if(activeLow){
|
||||
if(write(fd, "0", 2) != 2){
|
||||
qDebug() << "ERROR: could not write to gpio (set Active LOW)";
|
||||
close(fd);
|
||||
return false;
|
||||
}
|
||||
close(fd);
|
||||
return true;
|
||||
}
|
||||
if(!activeLow){
|
||||
if(write(fd, "1", 2) != 2){
|
||||
qDebug() << "ERROR: could not write to gpio (set Active HIGH)";
|
||||
close(fd);
|
||||
return false;
|
||||
}
|
||||
close(fd);
|
||||
return true;
|
||||
}
|
||||
close(fd);
|
||||
return false;
|
||||
}
|
||||
|
||||
int Gpio::gpioPin()
|
||||
{
|
||||
return m_gpio;
|
||||
}
|
||||
|
||||
int Gpio::gpioDirection()
|
||||
{
|
||||
return m_dir;
|
||||
}
|
||||
|
||||
bool Gpio::isAvailable()
|
||||
{
|
||||
QDir gpioDirectory("/sys/class/gpio");
|
||||
return gpioDirectory.exists();
|
||||
}
|
||||
|
||||
@ -23,6 +23,7 @@
|
||||
#include <QThread>
|
||||
#include <QMutex>
|
||||
#include <QMutexLocker>
|
||||
#include <QDir>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
@ -41,30 +42,31 @@
|
||||
#define EDGE_RISING 1
|
||||
#define EDGE_BOTH 2
|
||||
|
||||
|
||||
/**********************************
|
||||
* Raspberry Pi Rev. 2.0
|
||||
* ______________________
|
||||
* |______________________|
|
||||
* | File NR. | PIN NR. |
|
||||
* |___________|__________|
|
||||
* | GPIO 2 | 3 |
|
||||
* | GPIO 3 | 5 |
|
||||
* | GPIO 4 | 7 |
|
||||
* | GPIO 7 | 26 |
|
||||
* | GPIO 8 | 24 |
|
||||
* | GPIO 9 | 21 |
|
||||
* | GPIO 10 | 19 |
|
||||
* | GPIO 11 | 23 |
|
||||
* | GPIO 14 | 8 |
|
||||
* | GPIO 15 | 10 |
|
||||
* | GPIO 17 | 11 |
|
||||
* | GPIO 18 | 12 |
|
||||
* | GPIO 22 | 15 |
|
||||
* | GPIO 23 | 16 |
|
||||
* | GPIO 24 | 18 |
|
||||
* | GPIO 25 | 22 |
|
||||
* | GPIO 27 | 13 |
|
||||
* |___________|__________|
|
||||
* Raspberry Pi Rev. 2.0 P1 Header Raspberry Pi Rev. 2.0 P5 Header
|
||||
* __________________________________ __________________________________
|
||||
* |______________________|__________| |______________________|__________|
|
||||
* | Name | PIN NR. | Function | | Name | PIN NR. | Function |
|
||||
* |___________|__________|__________| |___________|__________|__________|
|
||||
* | GPIO 2 | 3 | SDA | | GPIO 28 | 3 | SDA |
|
||||
* | GPIO 3 | 5 | SCL | | GPIO 29 | 4 | SCL |
|
||||
* | GPIO 4 | 7 | | | GPIO 30 | 5 | |
|
||||
* | GPIO 7 | 26 | CE1 | | GPIO 31 | 6 | |
|
||||
* | GPIO 8 | 24 | CE0 | |___________|__________|__________|
|
||||
* | GPIO 9 | 21 | MISO |
|
||||
* | GPIO 10 | 19 | MOSI |
|
||||
* | GPIO 11 | 23 | SCLK |
|
||||
* | GPIO 14 | 8 | TXD |
|
||||
* | GPIO 15 | 10 | RXD |
|
||||
* | GPIO 17 | 11 | |
|
||||
* | GPIO 18 | 12 | PCM_CLK |
|
||||
* | GPIO 22 | 15 | |
|
||||
* | GPIO 23 | 16 | |
|
||||
* | GPIO 24 | 18 | |
|
||||
* | GPIO 25 | 22 | |
|
||||
* | GPIO 27 | 13 | |
|
||||
* |___________|__________|__________|
|
||||
*
|
||||
**********************************
|
||||
*/
|
||||
@ -86,15 +88,17 @@ public:
|
||||
int getValue();
|
||||
|
||||
bool setEdgeInterrupt(int edge);
|
||||
bool setActiveLow(bool activeLow);
|
||||
|
||||
int gpioPin();
|
||||
int gpioDirection();
|
||||
|
||||
bool isAvailable();
|
||||
|
||||
private:
|
||||
int m_gpio;
|
||||
int m_dir;
|
||||
|
||||
signals:
|
||||
|
||||
public slots:
|
||||
|
||||
};
|
||||
|
||||
#endif // GPIO_H
|
||||
|
||||
92
libguh/hardware/gpiomonitor.cpp
Normal file
92
libguh/hardware/gpiomonitor.cpp
Normal file
@ -0,0 +1,92 @@
|
||||
#include "gpiomonitor.h"
|
||||
|
||||
GpioMonitor::GpioMonitor(QObject *parent) :
|
||||
QThread(parent)
|
||||
{
|
||||
}
|
||||
|
||||
GpioMonitor::~GpioMonitor()
|
||||
{
|
||||
foreach (Gpio* gpio, m_gpioList) {
|
||||
gpio->unexportGpio();
|
||||
}
|
||||
quit();
|
||||
wait();
|
||||
deleteLater();
|
||||
}
|
||||
|
||||
void GpioMonitor::stop()
|
||||
{
|
||||
m_enabledMutex.lock();
|
||||
m_enabled = false;
|
||||
m_enabledMutex.unlock();
|
||||
}
|
||||
|
||||
bool GpioMonitor::addGpio(Gpio *gpio, bool activeLow)
|
||||
{
|
||||
if (!gpio->exportGpio() || !gpio->setDirection(INPUT) || !gpio->setEdgeInterrupt(EDGE_BOTH) || !gpio->setActiveLow(activeLow)) {
|
||||
return false;
|
||||
}
|
||||
m_gpioListMutex.lock();
|
||||
m_gpioList.append(gpio);
|
||||
m_gpioListMutex.unlock();
|
||||
return true;
|
||||
}
|
||||
|
||||
QList<Gpio *> GpioMonitor::gpioList()
|
||||
{
|
||||
m_gpioListMutex.lock();
|
||||
QList<Gpio*> gpioList = m_gpioList;
|
||||
m_gpioListMutex.unlock();
|
||||
return gpioList;
|
||||
}
|
||||
|
||||
void GpioMonitor::run()
|
||||
{
|
||||
struct pollfd *fds;
|
||||
char val;
|
||||
int ret;
|
||||
int retVal;
|
||||
|
||||
fds = (pollfd*) malloc(sizeof(pollfd) * m_gpioList.size());
|
||||
m_gpioListMutex.lock();
|
||||
for (int i = 0; i < m_gpioList.size(); i++) {
|
||||
fds[i].fd = m_gpioList[i]->openGpio();
|
||||
fds[i].events = POLLPRI | POLLERR;
|
||||
}
|
||||
m_gpioListMutex.unlock();
|
||||
|
||||
bool enabled = true;
|
||||
|
||||
m_enabledMutex.lock();
|
||||
m_enabled = true;
|
||||
m_enabledMutex.unlock();
|
||||
|
||||
while (enabled) {
|
||||
m_gpioListMutex.lock();
|
||||
ret = poll(fds, m_gpioList.size(), 2000);
|
||||
|
||||
if (ret > 0) {
|
||||
for (int i=0; i < m_gpioList.size(); i++) {
|
||||
if ((fds[i].revents & POLLPRI) || (fds[i].revents & POLLERR)) {
|
||||
lseek(fds[i].fd, 0, SEEK_SET);
|
||||
retVal = read(fds[i].fd, &val, 1);
|
||||
|
||||
emit changed(m_gpioList[i]->gpioPin(), m_gpioList[i]->getValue());
|
||||
|
||||
if (retVal < 0) {
|
||||
qWarning() << "ERROR: poll failed";
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (ret < 0) {
|
||||
qWarning() << "ERROR: poll failed: " << errno;
|
||||
}
|
||||
m_gpioListMutex.unlock();
|
||||
|
||||
m_enabledMutex.lock();
|
||||
enabled = m_enabled;
|
||||
m_enabledMutex.unlock();
|
||||
}
|
||||
free(fds);
|
||||
}
|
||||
40
libguh/hardware/gpiomonitor.h
Normal file
40
libguh/hardware/gpiomonitor.h
Normal file
@ -0,0 +1,40 @@
|
||||
#ifndef GPIOMONITOR_H
|
||||
#define GPIOMONITOR_H
|
||||
|
||||
#include <QThread>
|
||||
#include <QDebug>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <poll.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "hardware/gpio.h"
|
||||
|
||||
class GpioMonitor : public QThread
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit GpioMonitor(QObject *parent = 0);
|
||||
~GpioMonitor();
|
||||
|
||||
void stop();
|
||||
bool addGpio(Gpio *gpio, bool activeLow);
|
||||
QList<Gpio*> gpioList();
|
||||
|
||||
|
||||
private:
|
||||
QMutex m_enabledMutex;
|
||||
bool m_enabled;
|
||||
|
||||
QMutex m_gpioListMutex;
|
||||
QList<Gpio*> m_gpioList;
|
||||
|
||||
protected:
|
||||
void run();
|
||||
|
||||
signals:
|
||||
void changed(const int &gpioPin, const int &value);
|
||||
|
||||
};
|
||||
|
||||
#endif // GPIOMONITOR_H
|
||||
@ -33,6 +33,10 @@ Radio433Receiver::Radio433Receiver(QObject *parent, int gpio) :
|
||||
m_enabled = false;
|
||||
m_mutex.unlock();
|
||||
|
||||
if(Gpio::isAvailable()){
|
||||
|
||||
}
|
||||
|
||||
connect(this, &Radio433Receiver::timingReady, this, &Radio433Receiver::handleTiming, Qt::DirectConnection);
|
||||
}
|
||||
|
||||
|
||||
@ -29,7 +29,8 @@ SOURCES += plugin/device.cpp \
|
||||
types/paramtype.cpp \
|
||||
types/param.cpp \
|
||||
types/paramdescriptor.cpp \
|
||||
types/statedescriptor.cpp
|
||||
types/statedescriptor.cpp \
|
||||
hardware/gpiomonitor.cpp
|
||||
|
||||
HEADERS += plugin/device.h \
|
||||
plugin/deviceclass.h \
|
||||
@ -54,5 +55,6 @@ HEADERS += plugin/device.h \
|
||||
types/param.h \
|
||||
types/paramdescriptor.h \
|
||||
types/statedescriptor.h \
|
||||
typeutils.h
|
||||
typeutils.h \
|
||||
hardware/gpiomonitor.h
|
||||
|
||||
|
||||
@ -71,8 +71,7 @@ DeviceManager::HardwareResources DevicePluginElro::requiredHardware() const
|
||||
}
|
||||
|
||||
DeviceManager::DeviceError DevicePluginElro::executeAction(Device *device, const Action &action)
|
||||
{
|
||||
|
||||
{
|
||||
QList<int> rawData;
|
||||
QByteArray binCode;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user