111 lines
3.4 KiB
C++
111 lines
3.4 KiB
C++
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
|
* *
|
|
* This file is part of guh. *
|
|
* *
|
|
* Guh is free software: you can redistribute it and/or modify *
|
|
* it under the terms of the GNU General Public License as published by *
|
|
* the Free Software Foundation, version 2 of the License. *
|
|
* *
|
|
* Guh is distributed in the hope that it will be useful, *
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
|
* GNU General Public License for more details. *
|
|
* *
|
|
* You should have received a copy of the GNU General Public License *
|
|
* along with guh. If not, see <http://www.gnu.org/licenses/>. *
|
|
* *
|
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
|
|
|
#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);
|
|
}
|