mirror of
				https://github.com/ElvishArtisan/rivendell.git
				synced 2025-11-04 16:14:03 +01:00 
			
		
		
		
	* Cleaned up deprecation warnings for 'QString::sprintf()'. Signed-off-by: Fred Gleason <fredg@paravelsystems.com>
		
			
				
	
	
		
			237 lines
		
	
	
		
			4.5 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			237 lines
		
	
	
		
			4.5 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
// rdkernelgpio.cpp
 | 
						|
//
 | 
						|
// Control Class for the Linux SysFS GPIO Interface
 | 
						|
//
 | 
						|
//   (C) Copyright 2017-2021 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 "rdapplication.h"
 | 
						|
#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) {
 | 
						|
    if(fscanf(f,"%s",str)!=1) {
 | 
						|
      rda->syslog(LOG_WARNING,
 | 
						|
	   "RDKernelGpio::direction fscanf returned unexpected item count [%s]",
 | 
						|
	   strerror(errno));
 | 
						|
    }
 | 
						|
    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) {
 | 
						|
    if(fscanf(f,"%u",&ret)!=1) {
 | 
						|
      rda->syslog(LOG_WARNING,
 | 
						|
	   "RDKernelGpio::activeLow fscanf returned unexpected item count [%s]",
 | 
						|
	   strerror(errno));
 | 
						|
      if(ok!=NULL) {
 | 
						|
	*ok=false;
 | 
						|
      }
 | 
						|
    }
 | 
						|
    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) {
 | 
						|
    if(fscanf(f,"%u",&ret)!=1) {
 | 
						|
      rda->syslog(LOG_WARNING,
 | 
						|
	   "RDKernelGpio::activeLow fscanf returned unexpected item count [%s]",
 | 
						|
	   strerror(errno));
 | 
						|
      if(ok!=NULL) {
 | 
						|
	*ok=false;
 | 
						|
      }
 | 
						|
    }
 | 
						|
    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).toUtf8(),mode);
 | 
						|
  }
 | 
						|
  return fopen((KERNELGPIO_SYS_FILE+QString::asprintf("/gpio%d/",gpio)+name).
 | 
						|
	       toUtf8(),mode);
 | 
						|
}
 |