#include "gpiomonitor.h" #include GpioMonitor::GpioMonitor(int gpio, QObject *parent) : QThread(parent) { m_gpio = new Gpio(gpio, this); connect(this, &GpioMonitor::started, this, &GpioMonitor::onThreadStarted); connect(this, &GpioMonitor::finished, this, &GpioMonitor::onThreadFinished); } GpioMonitor::~GpioMonitor() { disable(); wait(); } Gpio::Value GpioMonitor::value() { QMutexLocker valueLocker(&m_valueMutex); return m_value; } bool GpioMonitor::enabled() const { return m_enabled; } void GpioMonitor::setValue(Gpio::Value value) { QMutexLocker valueLocker(&m_valueMutex); if (m_value == value) return; m_value = value; emit valueChanged(m_value); } void GpioMonitor::setEnabled(bool enabled) { if (m_enabled == enabled) return; m_enabled = enabled; emit enabledChanged(m_enabled); } void GpioMonitor::run() { // Poll the GPIO value until the stop is true while (true) { // Note: the setValue() method takes care about the mutex locking setValue(m_gpio->value()); // Check if we should stop the thread QMutexLocker stopLocker(&m_stopMutex); if (m_stop) break; msleep(50); } } void GpioMonitor::onThreadStarted() { setEnabled(true); } void GpioMonitor::onThreadFinished() { setEnabled(false); } bool GpioMonitor::enable() { if (isRunning()) { qCWarning(dcGpio()) << "This GPIO monitor is already running."; return true; } QMutexLocker locker(&m_stopMutex); m_stop = false; if (!m_gpio->exportGpio()) { qCWarning(dcGpio()) << "Could not enable GPIO monitor."; return false; } if (!m_gpio->setDirection(Gpio::DirectionInput)) { qCWarning(dcGpio()) << "Could not enable GPIO monitor."; return false; } if (!m_gpio->setEdgeInterrupt(Gpio::EdgeBoth)) { qCWarning(dcGpio()) << "Could not enable GPIO monitor."; return false; } // Everything went fine, lets start the poll thread and inform about the result start(); return true; } void GpioMonitor::disable() { // Stop the thread if not already disabled QMutexLocker locker(&m_stopMutex); if (m_stop) return; m_stop = true; }