Files
ACSreader/gpio.c
Martijn Scheepers 949aacdcbd cleanup old code
2019-01-29 13:19:10 +01:00

259 lines
6.4 KiB
C

#define _GNU_SOURCE
#include <errno.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <string.h>
#include <syslog.h>
#include "gpio.h"
#include "log.h"
//export gpio pin in sysfs
int GPIOExport(unsigned int pin){
#define BUFFER_MAX 3
char buffer[BUFFER_MAX];
int fd = open("/sys/class/gpio/export", O_WRONLY);
if (-1 == fd) {
writesyslog(LOG_ERR, "GPIOExport: Failed to open /sys/class/gpio/export for writing!");
return(-1);
}
int bytes_written = snprintf(buffer, BUFFER_MAX, "%d", pin);
if(bytes_written <= 0){
writesyslog(LOG_ERR, "GPIOExport: Failed to snprintf the pin value");
return(-1);
}
if(0 == write(fd, buffer, (size_t)bytes_written)) {
char *log;
if(asprintf(&log, "GPIOExport: Failed to write value to %d", pin) > 0 ){
writesyslog(LOG_ERR, log);
}
free(log);
return(-1);
}
close(fd);
return(0);
}
//unexport the gpio in sysfs
int GPIOUnexport(unsigned int pin){
char buffer[BUFFER_MAX];
int fd = open("/sys/class/gpio/unexport", O_WRONLY);
if (-1 == fd) {
writesyslog(LOG_ERR, "GPIOUnexport: Failed to open/sys/class/gpio/unexport for writing!");
return(-1);
}
int bytes_written = snprintf(buffer, BUFFER_MAX, "%d", pin);
if(bytes_written <= 0){
writesyslog(LOG_ERR, "GPIOUnexport: Failed to snprintf the pin value");
return(-1);
}
if (0 == write(fd, buffer, (size_t)bytes_written)){
char *log;
if(asprintf(&log, "GPIOUnexport: Failed to write value to %d", pin) > 0 ){
writesyslog(LOG_ERR, log);
}
free(log);
return(-1);
}
close(fd);
return(0);
}
//set the direction off the gpio in sysfs
int GPIODirection(unsigned int pin,unsigned int dir){
static const char s_directions_str[] = "in\0out";
#define DIRECTION_MAX 35
char path[DIRECTION_MAX];
#ifdef TEST
int bytes_written = snprintf(path, DIRECTION_MAX, "/sys/class/gpio/gpio%d/direction", pin);
#else
int bytes_written = snprintf(path, DIRECTION_MAX, "/sys/class/gpio/pioC%d/direction", pin);
#endif
if(bytes_written <= 0){
writesyslog(LOG_ERR, "GPIODirection: Failed to snprintf the gpio path");
return(-1);
}
int fd = open(path, O_WRONLY);
if (-1 == fd) {
char *log;
if(asprintf(&log, "GPIODirection: Failed to open /sys/class/gpio/pioC%d/direction for writing!", pin) > 0 ){
writesyslog(LOG_ERR, log);
}
free(log);
return(-1);
}
if (-1 == write(fd, &s_directions_str[IN == dir ? 0 : 3], IN == dir ? 2 : 3)) {
char *log;
if(asprintf(&log, "GPIODirection: Failed to set direction - pin:%d dir:%d", pin, dir) > 0 ){
writesyslog(LOG_ERR, log);
}
free(log);
return(-1);
}
close(fd);
return(0);
}
//read the pin value in sysfs
int GPIORead(unsigned int pin){
#define VALUE_MAX 30
char path[VALUE_MAX];
char value_str[3];
#ifdef TEST
int bytes_written = snprintf(path, VALUE_MAX, "/sys/class/gpio/gpio%d/value", pin);
#else
int bytes_written = snprintf(path, VALUE_MAX, "/sys/class/gpio/pioC%d/value", pin);
#endif
if(bytes_written <= 0){
writesyslog(LOG_ERR, "GPIORead: Failed to snprintf the read path");
return(-1);
}
int fd = open(path, O_RDONLY);
if (-1 == fd) {
char *log;
if(asprintf(&log, "Failed to open /sys/class/gpio/pioC%d/value for reading", pin) > 0 ){
writesyslog(LOG_ERR, log);
}
free(log);
return(-1);
}
if (-1 == read(fd, value_str, 3)) {
char *log;
if(asprintf(&log, "GPIORead: Failed to read pin:%d", pin) > 0 ){
writesyslog(LOG_ERR, log);
}
free(log);
return(-1);
}
close(fd);
return(atoi(value_str));
}
int GPIOWrite(unsigned int pin, unsigned int value){
static const char s_values_str[] = "01";
char path[VALUE_MAX];
#ifdef TEST
int bytes_written = snprintf(path, VALUE_MAX, "/sys/class/gpio/gpio%d/value", pin);
#else
int bytes_written = snprintf(path, VALUE_MAX, "/sys/class/gpio/pioC%d/value", pin);
#endif
if(bytes_written <= 0){
writesyslog(LOG_ERR, "GPIOWrite: Failed the snprintf the write path");
return(-1);
}
int fd = open(path, O_WRONLY);
if (-1 == fd) {
char *log;
if(asprintf(&log, "GPIOWrite: Failed to open /sys/class/gpio/pioC%d/value for writing", pin) > 0 ){
writesyslog(LOG_ERR, log);
}
free(log);
return(-1);
}
if (1 != write(fd, &s_values_str[LOW == value ? 0 : 1], 1)) {
char *log;
if(asprintf(&log, "Failed to write value - pin:%d value:%d", pin, value) > 0 ){
writesyslog(LOG_ERR, log);
}
free(log);
return(-1);
}
close(fd);
return(0);
}
#ifdef TEST
unsigned int relaysysfs[9] = {0, 17, 17, 17, 17, 17, 17, 17, 17}; //SYSFS export number
unsigned int relaypin[9] = {0, 17, 17, 17, 17, 17, 17, 17, 17}; //PortC number
#else
unsigned int relaysysfs[9] = {0, 81, 80, 79, 78, 83, 84, 76, 77}; //SYSFS export number
unsigned int relaypin[9] = {0, 17, 16, 15, 14, 19, 20, 12, 13}; //PortC number
#endif
unsigned int get_relaypin(unsigned int pin){
return(relaypin[pin]);
}
int gpio_initrelay(unsigned int relay, cfg_bool_t relayinvert){
if(relay > 8 || relay < 1){
char *log;
if(asprintf(&log, "GPIO: Invalid relay number - %d", relay) > 0 ){
writesyslog(LOG_ERR, log);
}
free(log);
return(-1);
}
for (int i = 1; i<9; i++ ) {
if(GPIOExport(relaysysfs[i]) < 0){
return(-1);
}
if(GPIODirection(relaypin[i], OUT) < 0){
return(-1);
}
}
if(relayinvert == cfg_true){
if(GPIOWrite(relaypin[relay], HIGH) < 0){
return(-1);
}
}
else{
if(GPIOWrite(relaypin[relay], LOW) < 0){
return(-1);
}
}
return(0);
}
#ifdef TEST
unsigned int inputsysfs[9] = {0, 2, 2, 2, 2, 2, 2, 2, 2}; //SYSFS export number
unsigned int inputpin[9] = {0, 2, 2, 2, 2, 2, 2, 2, 2}; //PortA number
#else
unsigned int inputsysfs[9] = {0, 29, 28, 27, 26, 25, 24, 23, 22}; //SYSFS export number
unsigned int inputpin[9] = {0, 29, 28, 27, 26, 25, 24, 23, 22}; //PortA number
#endif
unsigned int get_inputpin(int pin){
return(inputpin[pin]);
}
int gpio_initinput(unsigned int input){
if(input > 8 || input < 1){
char *log;
if(asprintf(&log, "GPIO: Invalid manualinput number - %d", input) > 0 ){
writesyslog(LOG_ERR, log);
}
free(log);
return(-1);
}
//input is pioA
for (int i = 1; i<9; i++ ) {
if(GPIOExport(inputsysfs[i]) < 0){
return(-1);
}
if(GPIODirection(inputpin[i], IN) < 0){
return(-1);
}
}
return(0);
}