/*
* Copyright (c) 2019-2020, yzrh <yzrh@noema.org>
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "gpio.h"
#ifdef __FreeBSD__
int
gpio_config(int pin, int direction, int interrupt)
{
int ret;
int fd = open("/dev/gpioc0", O_RDWR);
if (fd == -1) {
fprintf(stderr, "GPIO configuration failure\n");
return 1;
}
struct gpio_pin pin_req = {
.gp_pin = pin,
.gp_caps = interrupt,
.gp_flags = direction
};
ret = ioctl(fd, GPIOSETCONFIG, &pin_req) == 0 ? 0 : 1;
close(fd);
return ret;
}
int
gpio_write(int pin, int value)
{
int ret;
int fd = open("/dev/gpioc0", O_RDWR);
if (fd == -1) {
fprintf(stderr, "GPIO output failure\n");
return 1;
}
struct gpio_req req = {
.gp_pin = pin,
.gp_value = value
};
ret = ioctl(fd, GPIOSET, &req) == 0 ? 0 : 1;
close(fd);
return ret;
}
int
gpio_read(int pin)
{
int fd = open("/dev/gpioc0", O_RDWR);
if (fd == -1) {
fprintf(stderr, "GPIO input failure\n");
return 1;
}
struct gpio_req req = {
.gp_pin = pin
};
ioctl(fd, GPIOGET, &req);
close(fd);
return req.gp_value;
}
#elif __linux__
int
gpio_export(int pin)
{
int export = open("/sys/class/gpio/export", O_RDWR);
if (export == -1) {
fprintf(stderr, "GPIO export failure\n");
return 1;
}
char buf[3];
int buf_size = snprintf(buf, 3, "%d", pin);
write(export, buf, buf_size);
close(export);
return 0;
}
int
gpio_unexport(int pin)
{
int unexport = open("/sys/class/gpio/unexport", O_RDWR);
if (unexport == -1) {
fprintf(stderr, "GPIO unexport failure\n");
return 1;
}
char buf[3];
int buf_size = snprintf(buf, 3, "%d", pin);
write(unexport, buf, buf_size);
close(unexport);
return 0;
}
int
gpio_config(int pin, int direction, int interrupt)
{
char path[33];
snprintf(path, 33, "/sys/class/gpio/gpio%d/direction", pin);
int config = open(path, O_RDWR);
if (config == -1) {
fprintf(stderr, "GPIO configuration failure\n");
return 1;
}
char buf[8];
int buf_size = snprintf(buf, 8, "%s", direction == 0 ? "in" : "out");
write(config, buf, buf_size);
close(config);
snprintf(path, 33, "/sys/class/gpio/gpio%d/edge", pin);
config = open(path, O_RDWR);
if (config == -1) {
fprintf(stderr, "GPIO configuration failure\n");
return 1;
}
buf_size = snprintf(buf, 8, "%s",
interrupt == 0 ? "falling" : "rising");
write(config, buf, buf_size);
close(config);
return 0;
}
int
gpio_write(int pin, int value)
{
char path[29];
snprintf(path, 29, "/sys/class/gpio/gpio%d/value", pin);
int config = open(path, O_RDWR);
if (config == -1) {
fprintf(stderr, "GPIO output failure\n");
return 1;
}
char buf[2];
int buf_size = snprintf(buf, 2, "%d", value);
write(config, buf, buf_size);
close(config);
return 0;
}
int
gpio_read(int pin)
{
char path[29];
snprintf(path, 29, "/sys/class/gpio/gpio%d/value", pin);
int config = open(path, O_RDONLY);
if (config == -1) {
fprintf(stderr, "GPIO input failure\n");
return 1;
}
char buf[2];
read(config, buf, 2);
close(config);
return atoi(buf);
}
#endif /* __FreeBSD__ */