259 lines
6.4 KiB
C
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);
|
|
}
|