194 lines
3.1 KiB
C
194 lines
3.1 KiB
C
/*
|
|
* 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__ */
|