mirror of
https://github.com/ElvishArtisan/rivendell.git
synced 2025-10-11 00:53:53 +02:00
2017-05-23 Fred Gleason <fredg@paravelsystems.com>
* Added an 'RDMatrix::KernelGpio' element to the 'RDMatrix::Type enum. * Implemented a Kernel GPIO switcher driver in 'ripcd/kernelgpio.cpp' and 'ripcd/kernelgpio.h'.
This commit is contained in:
@@ -151,6 +151,7 @@ dist_librd_la_SOURCES = dbversion.h\
|
||||
rdintegeredit.cpp rdintegeredit.h\
|
||||
rdintegerdialog.cpp rdintegerdialog.h\
|
||||
rd.h\
|
||||
rdkernelgpio.cpp rdkernelgpio.h\
|
||||
rdlabel.cpp rdlabel.h\
|
||||
rdlibrary_conf.cpp rdlibrary_conf.h\
|
||||
rdlicense.cpp rdlicense.h\
|
||||
@@ -287,6 +288,7 @@ nodist_librd_la_SOURCES = moc_rdadd_cart.cpp\
|
||||
moc_rdimport_audio.cpp\
|
||||
moc_rdintegeredit.cpp\
|
||||
moc_rdintegerdialog.cpp\
|
||||
moc_rdkernelgpio.cpp\
|
||||
moc_rdlabel.cpp\
|
||||
moc_rdlicense.cpp\
|
||||
moc_rdlineedit.cpp\
|
||||
|
@@ -151,6 +151,7 @@ x11 {
|
||||
SOURCES += rdgroup.cpp
|
||||
SOURCES += rdhash.cpp
|
||||
SOURCES += rdimport_audio.cpp
|
||||
SOURCES += rdkernelgpio.cpp
|
||||
SOURCES += rdlist_groups.cpp
|
||||
SOURCES += rdlist_logs.cpp
|
||||
SOURCES += rdmarker_button.cpp
|
||||
@@ -286,6 +287,7 @@ x11 {
|
||||
HEADERS += rdgroup.h
|
||||
HEADERS += rdhash.h
|
||||
HEADERS += rdimport_audio.h
|
||||
HEADERS += rdkernelgpio.h
|
||||
HEADERS += rdlist_groups.h
|
||||
HEADERS += rdlist_logs.h
|
||||
HEADERS += rdmarker_button.h
|
||||
|
217
lib/rdkernelgpio.cpp
Normal file
217
lib/rdkernelgpio.cpp
Normal file
@@ -0,0 +1,217 @@
|
||||
// rdkernelgpio.cpp
|
||||
//
|
||||
// Control Class for the Linux SysFS GPIO Interface
|
||||
//
|
||||
// (C) Copyright 2017 Fred Gleason <fredg@paravelsystems.com>
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Library General Public License
|
||||
// version 2 as published by the Free Software Foundation.
|
||||
//
|
||||
// This program 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 this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
//
|
||||
|
||||
#include "rdkernelgpio.h"
|
||||
|
||||
RDKernelGpio::RDKernelGpio(QObject *parent)
|
||||
: QObject(parent)
|
||||
{
|
||||
gpio_poll_timer=new QTimer(this);
|
||||
connect(gpio_poll_timer,SIGNAL(timeout()),this,SLOT(pollData()));
|
||||
}
|
||||
|
||||
|
||||
RDKernelGpio::~RDKernelGpio()
|
||||
{
|
||||
for(unsigned i=0;i<gpio_gpios.size();i++) {
|
||||
removeGpio(gpio_gpios[i]);
|
||||
}
|
||||
delete gpio_poll_timer;
|
||||
}
|
||||
|
||||
|
||||
bool RDKernelGpio::addGpio(int gpio)
|
||||
{
|
||||
FILE *f=NULL;
|
||||
|
||||
for(unsigned i=0;i<gpio_gpios.size();i++) {
|
||||
if(gpio==gpio_gpios[i]) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if((f=OpenNode("export","w"))==NULL) {
|
||||
return false;
|
||||
}
|
||||
fprintf(f,"%u",gpio);
|
||||
fclose(f);
|
||||
gpio_gpios.push_back(gpio);
|
||||
gpio_states.push_back(value(gpio));
|
||||
|
||||
if(gpio_gpios.size()==1) {
|
||||
gpio_poll_timer->start(KERNELGPIO_POLL_INTERVAL);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool RDKernelGpio::removeGpio(int gpio)
|
||||
{
|
||||
FILE *f=NULL;
|
||||
|
||||
if((f=OpenNode("unexport","w"))==NULL) {
|
||||
return false;
|
||||
}
|
||||
fprintf(f,"%u",gpio);
|
||||
fclose(f);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
RDKernelGpio::Direction RDKernelGpio::direction(int gpio,bool *ok) const
|
||||
{
|
||||
RDKernelGpio::Direction ret=RDKernelGpio::In;
|
||||
FILE *f=NULL;
|
||||
char str[255];
|
||||
|
||||
if((f=OpenNode("direction","r",gpio))!=NULL) {
|
||||
fscanf(f,"%s",str);
|
||||
if(QString(str)=="out") {
|
||||
ret=RDKernelGpio::Out;
|
||||
}
|
||||
fclose(f);
|
||||
if(ok!=NULL) {
|
||||
*ok=true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if(ok!=NULL) {
|
||||
*ok=false;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
bool RDKernelGpio::setDirection(int gpio,RDKernelGpio::Direction dir) const
|
||||
{
|
||||
FILE *f=NULL;
|
||||
|
||||
if((f=OpenNode("direction","w",gpio))!=NULL) {
|
||||
switch(dir) {
|
||||
case RDKernelGpio::In:
|
||||
fprintf(f,"in");
|
||||
break;
|
||||
|
||||
case RDKernelGpio::Out:
|
||||
fprintf(f,"out");
|
||||
break;
|
||||
}
|
||||
fclose(f);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool RDKernelGpio::activeLow(int gpio,bool *ok) const
|
||||
{
|
||||
unsigned ret=false;
|
||||
FILE *f=NULL;
|
||||
|
||||
if((f=OpenNode("active_low","r",gpio))!=NULL) {
|
||||
fscanf(f,"%u",&ret);
|
||||
fclose(f);
|
||||
if(ok!=NULL) {
|
||||
*ok=true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if(ok!=NULL) {
|
||||
*ok=false;
|
||||
}
|
||||
}
|
||||
|
||||
return (bool)ret;
|
||||
}
|
||||
|
||||
|
||||
bool RDKernelGpio::setActiveLow(int gpio,bool state) const
|
||||
{
|
||||
FILE *f=NULL;
|
||||
|
||||
if((f=OpenNode("active_low","w",gpio))!=NULL) {
|
||||
fprintf(f,"%u",state);
|
||||
fclose(f);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool RDKernelGpio::value(int gpio,bool *ok) const
|
||||
{
|
||||
unsigned ret=false;
|
||||
FILE *f=NULL;
|
||||
|
||||
if((f=OpenNode("value","r",gpio))!=NULL) {
|
||||
fscanf(f,"%u",&ret);
|
||||
fclose(f);
|
||||
if(ok!=NULL) {
|
||||
*ok=true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if(ok!=NULL) {
|
||||
*ok=false;
|
||||
}
|
||||
}
|
||||
|
||||
return (bool)ret;
|
||||
}
|
||||
|
||||
|
||||
bool RDKernelGpio::setValue(int gpio,bool state) const
|
||||
{
|
||||
FILE *f=NULL;
|
||||
|
||||
if((f=OpenNode("value","w",gpio))!=NULL) {
|
||||
fprintf(f,"%u",state);
|
||||
fclose(f);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void RDKernelGpio::pollData()
|
||||
{
|
||||
bool state=false;
|
||||
|
||||
for(unsigned i=0;i<gpio_gpios.size();i++) {
|
||||
if((state=value(gpio_gpios[i]))!=gpio_states[i]) {
|
||||
gpio_states[i]=state;
|
||||
emit valueChanged(gpio_gpios[i],state);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
FILE *RDKernelGpio::OpenNode(const QString &name,const char *mode,int gpio) const
|
||||
{
|
||||
if(gpio<0) {
|
||||
return fopen((KERNELGPIO_SYS_FILE+"/"+name),mode);
|
||||
}
|
||||
return fopen((KERNELGPIO_SYS_FILE+QString().sprintf("/gpio%d/",gpio)+name),
|
||||
mode);
|
||||
}
|
71
lib/rdkernelgpio.h
Normal file
71
lib/rdkernelgpio.h
Normal file
@@ -0,0 +1,71 @@
|
||||
// rdkernelgpio.h
|
||||
//
|
||||
// Control Class for the Linux SysFS GPIO Interface
|
||||
//
|
||||
// (C) Copyright 2017 Fred Gleason <fredg@paravelsystems.com>
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Library General Public License
|
||||
// version 2 as published by the Free Software Foundation.
|
||||
//
|
||||
// This program 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 this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
//
|
||||
|
||||
#ifndef RDKERNELGPIO_H
|
||||
#define RDKERNELGPIO_H
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include <qobject.h>
|
||||
#include <qtimer.h>
|
||||
|
||||
//
|
||||
// See https://www.kernel.org/doc/Documentation/gpio/sysfs.txt
|
||||
// for an explanation of this interface.
|
||||
//
|
||||
#define KERNELGPIO_SYS_FILE QString("/sys/class/gpio")
|
||||
#define KERNELGPIO_POLL_INTERVAL 20
|
||||
|
||||
class RDKernelGpio : public QObject
|
||||
{
|
||||
Q_OBJECT;
|
||||
public:
|
||||
enum Direction {In=0,Out=1};
|
||||
enum Edge {None=0,Rising=1,Falling=2,Both=3};
|
||||
RDKernelGpio(QObject *parent=0);
|
||||
~RDKernelGpio();
|
||||
bool addGpio(int gpio);
|
||||
bool removeGpio(int gpio);
|
||||
Direction direction(int gpio, bool *ok=NULL) const;
|
||||
bool setDirection(int gpio,Direction dir) const;
|
||||
bool activeLow(int gpio, bool *ok=NULL) const;
|
||||
bool setActiveLow(int gpio,bool state) const;
|
||||
bool value(int gpio,bool *ok=NULL) const;
|
||||
|
||||
public slots:
|
||||
bool setValue(int gpio,bool state) const;
|
||||
|
||||
private slots:
|
||||
void pollData();
|
||||
|
||||
signals:
|
||||
void valueChanged(int gpio,bool state);
|
||||
|
||||
private:
|
||||
FILE *OpenNode(const QString &name,const char *mode,int gpio=-1) const;
|
||||
std::vector<int> gpio_gpios;
|
||||
std::vector<bool> gpio_states;
|
||||
QTimer *gpio_poll_timer;
|
||||
};
|
||||
|
||||
|
||||
#endif // RDKERNELGPIO_H
|
@@ -67,7 +67,8 @@ bool __mx_primary_controls[RDMatrix::LastType][RDMatrix::LastControl]=
|
||||
{0,1,0,0,0,0,0,0,1,0,0,1,1,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0}, // Ross NK/SCP
|
||||
{0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0}, // BT ADMS 44.22
|
||||
{0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0}, // BT SS 4.1 MLR
|
||||
{0,0,1,1,0,0,0,0,0,0,0,0,0,1,1,0,0,0,1,1,0,0,0,0,0,0,0,0,0} // Modbus
|
||||
{0,0,1,1,0,0,0,0,0,0,0,0,0,1,1,0,0,0,1,1,0,0,0,0,0,0,0,0,0}, // Modbus
|
||||
{0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,1,1,0,0,0,0,0,0,0,0,0} // Kernel GPIO
|
||||
};
|
||||
bool __mx_backup_controls[RDMatrix::LastType][RDMatrix::LastControl]=
|
||||
{
|
||||
@@ -111,7 +112,8 @@ bool __mx_backup_controls[RDMatrix::LastType][RDMatrix::LastControl]=
|
||||
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, // ROSS NK/SCP
|
||||
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, // BT ADMS 44.22
|
||||
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, // BT SS 4.1 MLR
|
||||
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0} // Modbus
|
||||
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, // Modbus
|
||||
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0} // Kernel GPIO
|
||||
};
|
||||
|
||||
int __mx_default_values[RDMatrix::LastType][RDMatrix::LastControl]=
|
||||
@@ -156,7 +158,8 @@ int __mx_default_values[RDMatrix::LastType][RDMatrix::LastControl]=
|
||||
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0}, // Ross NK/SCP
|
||||
{0,0,0,0,0,0,0,0,0,0,0,8,2,16,13,0,0,0,0,0,0,0,0,0,0,0,0,1,0}, // BT ADMS 44.22
|
||||
{0,0,0,0,0,0,0,0,0,0,0,4,1,8,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0}, // BT SS 4.1 MLR
|
||||
{1,0,0,502,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0} // Modbus
|
||||
{1,0,0,502,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0}, // Modbus
|
||||
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0} // Kernel GPIO
|
||||
};
|
||||
|
||||
RDMatrix::RDMatrix(const QString &station,int matrix)
|
||||
@@ -724,6 +727,10 @@ QString RDMatrix::typeString(RDMatrix::Type type)
|
||||
return QString("Modbus TCP");
|
||||
break;
|
||||
|
||||
case RDMatrix::KernelGpio:
|
||||
return QString("Kernel GPIO");
|
||||
break;
|
||||
|
||||
default:
|
||||
return QString("Unknown Type");
|
||||
break;
|
||||
|
@@ -38,7 +38,7 @@ class RDMatrix
|
||||
BtSrc16=24,Harlond=25,Acu1p=26,LiveWireMcastGpio=27,Am16=28,
|
||||
LiveWireLwrpGpio=29,BtSentinel4Web=30,BtGpi16=31,ModemLines=32,
|
||||
SoftwareAuthority=33,Sas16000=34,RossNkScp=35,BtAdms4422=36,
|
||||
BtSs41Mlr=37,Modbus=38,LastType=39};
|
||||
BtSs41Mlr=37,Modbus=38,KernelGpio=39,LastType=40};
|
||||
enum Endpoint {Input=0,Output=1};
|
||||
enum Mode {Stereo=0,Left=1,Right=2};
|
||||
enum VguestAttribute {VguestEngine=0,VguestDevice=1,VguestSurface=2,
|
||||
|
Reference in New Issue
Block a user