diff --git a/app/src/main/cpp/CMakeLists.txt b/app/src/main/cpp/CMakeLists.txt index cbd16ec1..4810b851 100644 --- a/app/src/main/cpp/CMakeLists.txt +++ b/app/src/main/cpp/CMakeLists.txt @@ -264,6 +264,7 @@ add_library( # Sets the name of the library. SHARED # Provides a relative path to your source file(s). + GPIOControl.cpp MicroPhoto.cpp TerminalDevice.cpp PhoneDevice.cpp diff --git a/app/src/main/cpp/GPIOControl.cpp b/app/src/main/cpp/GPIOControl.cpp new file mode 100644 index 00000000..00962ea8 --- /dev/null +++ b/app/src/main/cpp/GPIOControl.cpp @@ -0,0 +1,156 @@ +// +// Created by Matthew on 2023/12/27. +// + +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#include "GPIOControl.h" + +#define GPIO_DIRECTION_IN 0 +#define GPIO_DIRECTION_OUT 1 +#define GPIO_VALUE_LOW 0 +#define GPIO_VALUE_HIGH 1 + +#define BUFFER_MAX 3 +#define DIRECTION_MAX 48 + +int GpioControl::exp(int gpio) +{ + char buffer[BUFFER_MAX]; + int len; + int fd; + + fd = open("/sys/class/gpio/export", O_WRONLY); + if (fd < 0) + { + // LOGE("Failed to open export for writing!\n"); + return(0); + } + + len = snprintf(buffer, BUFFER_MAX, "%d", gpio); + if (write(fd, buffer, len) < 0) + { + // LOGE("Fail to export gpio!\n"); + return 0; + } + + close(fd); + return 1; +} + +int GpioControl::setDirection(int gpio, int direction) +{ + static const char dir_str[] = "in\0out"; + char path[DIRECTION_MAX]; + int fd; + + snprintf(path, DIRECTION_MAX, "/sys/class/gpio/gpio%d/direction", gpio); + fd = open(path, O_WRONLY); + if (fd < 0) + { + // LOGE("failed to open gpio direction for writing!\n"); + return 0; + } + + if (write(fd, &dir_str[direction == GPIO_DIRECTION_IN ? 0 : 3], direction == GPIO_DIRECTION_IN ? 2 : 3) < 0) + { + // LOGE("failed to set direction!\n"); + return 0; + } + + close(fd); + return 1; +} +int GpioControl::readStatus(int gpio) +{ + char path[DIRECTION_MAX]; + char value_str[3]; + int fd; + + snprintf(path, DIRECTION_MAX, "/sys/class/gpio/gpio%d/value", gpio); + fd = open(path, O_RDONLY); + if (fd < 0) + { + // LOGE("failed to open gpio value for reading!\n"); + return -1; + } + + if (read(fd, value_str, 3) < 0) + { + // LOGE("failed to read value!\n"); + return -1; + } + + close(fd); + return (atoi(value_str)); +} + +int GpioControl::writeStatus(int gpio, int value) +{ + static const char values_str[] = "01"; + char path[DIRECTION_MAX]; + int fd; + + snprintf(path, DIRECTION_MAX, "/sys/class/gpio/gpio%d/value", gpio); + fd = open(path, O_WRONLY); + if (fd < 0) + { + // LOGE("failed to open gpio value for writing!\n"); + return 0; + } + + if (write(fd, &values_str[value == GPIO_VALUE_LOW ? 0 : 1], 1) < 0) + { + // LOGE("failed to write value!\n"); + return 0; + } + + close(fd); + return 1; +} + +int GpioControl::unexp(int gpio) +{ + char buffer[BUFFER_MAX]; + int len; + int fd; + + fd = open("/sys/class/gpio/unexport", O_WRONLY); + if (fd < 0) + { + // LOGE("Failed to open unexport for writing!\n"); + return 0; + } + + len = snprintf(buffer, BUFFER_MAX, "%d", gpio); + if (write(fd, buffer, len) < 0) + { + // LOGE("Fail to unexport gpio!"); + return 0; + } + + close(fd); + return 1; +} + +bool GpioControl::EnableGpio(int gpio, bool en) +{ + GpioControl gpioControl; + gpioControl.exp(gpio); + gpioControl.setDirection(gpio, GPIO_DIRECTION_OUT); + + gpioControl.writeStatus(gpio, en ? GPIO_VALUE_HIGH : GPIO_VALUE_LOW); + + gpioControl.unexp(gpio); + + return true; +} diff --git a/app/src/main/cpp/GPIOControl.h b/app/src/main/cpp/GPIOControl.h new file mode 100644 index 00000000..dc2cb083 --- /dev/null +++ b/app/src/main/cpp/GPIOControl.h @@ -0,0 +1,22 @@ +// +// Created by Matthew on 2023/12/27. +// + +#ifndef MICROPHOTO_GPIOCONTROL_H +#define MICROPHOTO_GPIOCONTROL_H + + +class GpioControl +{ +public: + int exp(int gpio); + int setDirection(int gpio, int direction); + int readStatus(int gpio); + int writeStatus(int gpio, int value); + int unexp(int gpio); + + static bool EnableGpio(int gpio, bool en); +}; + + +#endif //MICROPHOTO_GPIOCONTROL_H