From 879432fb80830708b3173be93943bf7950f837b4 Mon Sep 17 00:00:00 2001 From: TMRh20 Date: Thu, 11 Jan 2024 16:33:54 -0600 Subject: [PATCH 01/16] Testing GPIO Very rudimentary changes for testing https://github.com/nRF24/RF24/issues/932 --- utility/SPIDEV/RF24_arch_config.h | 4 +- utility/SPIDEV/gpio.cpp | 76 ++++++++++++++++++++++++++++--- utility/SPIDEV/gpio.h | 13 +++--- 3 files changed, 79 insertions(+), 14 deletions(-) diff --git a/utility/SPIDEV/RF24_arch_config.h b/utility/SPIDEV/RF24_arch_config.h index fa457fde6..be7585b94 100644 --- a/utility/SPIDEV/RF24_arch_config.h +++ b/utility/SPIDEV/RF24_arch_config.h @@ -61,8 +61,8 @@ typedef uint16_t rf24_gpio_pin_t; #define HIGH GPIO::OUTPUT_HIGH #define INPUT GPIO::DIRECTION_IN #define OUTPUT GPIO::DIRECTION_OUT -#define digitalWrite(pin, value) GPIO::write(pin, value) -#define pinMode(pin, direction) GPIO::open(pin, direction) +#define digitalWrite(pin, value) GPIO::Gwrite(pin, value) +#define pinMode(pin, direction) GPIO::Gopen(pin, direction) #define delay(milisec) __msleep(milisec) #define delayMicroseconds(usec) __usleep(usec) #define millis() __millis() diff --git a/utility/SPIDEV/gpio.cpp b/utility/SPIDEV/gpio.cpp index a8986009d..10ed514a5 100644 --- a/utility/SPIDEV/gpio.cpp +++ b/utility/SPIDEV/gpio.cpp @@ -9,15 +9,27 @@ * * Patched for filedescriptor catching and error control by L Diaz 2018 */ - +#include #include "gpio.h" #include +#include #include #include +#include +#include +#include #include #include +#include + +const char* dev_name = "/dev/gpiochip0"; + +#define NEWGPIO + + +//std::map GPIO::cache; + -std::map GPIO::cache; GPIO::GPIO() { @@ -27,8 +39,20 @@ GPIO::~GPIO() { } -void GPIO::open(int port, int DDR) +int fd; + +void GPIO::Gopen(int port, int DDR) { + + + fd = open(dev_name, O_RDONLY); + if (fd >= 0){ + + } + close(fd); + #if !defined NEWGPIO + + FILE* f; f = fopen("/sys/class/gpio/export", "w"); if (f == NULL) { @@ -74,10 +98,14 @@ void GPIO::open(int port, int DDR) cache[port] = fd; // cache the fd; lseek(fd, SEEK_SET, 0); } + #endif + } -void GPIO::close(int port) +void GPIO::Gclose(int port) { + close(fd); + #if !defined NEWGPIO std::map::iterator i; i = cache.find(port); if (i != cache.end()) { @@ -91,10 +119,29 @@ void GPIO::close(int port) fprintf(f, "%d\n", port); fclose(f); } + #endif } -int GPIO::read(int port) +int GPIO::Gread(int port) { + + struct gpiohandle_request rq; + struct gpiohandle_data data; + int fd, ret; + fd = open(dev_name, O_RDONLY); + if (fd >= 0){ + rq.lineoffsets[0] = port; + rq.flags = GPIOHANDLE_REQUEST_INPUT; + rq.lines = 1; + ret = ioctl(fd, GPIO_GET_LINEHANDLE_IOCTL, &rq); + close(fd); + ret = ioctl(rq.fd, GPIOHANDLE_GET_LINE_VALUES_IOCTL, &data); + close(rq.fd); + return ret; + } + return -1; + + #if !defined NEWGPIO std::map::iterator i; int fd; i = cache.find(port); @@ -132,10 +179,26 @@ int GPIO::read(int port) fclose(f); return i; */ + #endif } -void GPIO::write(int port, int value) +void GPIO::Gwrite(int port, int value) { + + struct gpiohandle_request rq; + struct gpiohandle_data data; + int fd, ret; + fd = open(dev_name, O_RDONLY); + rq.lineoffsets[0] = port; + rq.flags = GPIOHANDLE_REQUEST_OUTPUT; + rq.lines = 1; + ret = ioctl(fd, GPIO_GET_LINEHANDLE_IOCTL, &rq); + close(fd); + data.values[0] = value; + ret = ioctl(rq.fd, GPIOHANDLE_SET_LINE_VALUES_IOCTL, &data); + close(rq.fd); + + #if !defined NEWGPIO std::map::iterator i; int fd; i = cache.find(port); @@ -175,4 +238,5 @@ void GPIO::write(int port, int value) fclose(f); */ + #endif } diff --git a/utility/SPIDEV/gpio.h b/utility/SPIDEV/gpio.h index c802ce6ac..aa7cd6295 100644 --- a/utility/SPIDEV/gpio.h +++ b/utility/SPIDEV/gpio.h @@ -17,6 +17,7 @@ #include #include + /** Specific excpetion for SPI errors */ class GPIOException : public std::runtime_error { @@ -41,19 +42,19 @@ class GPIO GPIO(); - static void open(int port, int DDR); + static void Gopen(int port, int DDR); - static void close(int port); + static void Gclose(int port); - static int read(int port); + static int Gread(int port); - static void write(int port, int value); + static void Gwrite(int port, int value); virtual ~GPIO(); - + private: /* fd cache */ - static std::map cache; + //static std::map cache; }; #endif // RF24_UTILITY_SPIDEV_GPIO_H_ From 6a78ecf5b0c3d9bdbd73ecc534810085e1298b02 Mon Sep 17 00:00:00 2001 From: TMRh20 Date: Sun, 14 Jan 2024 03:30:42 -0600 Subject: [PATCH 02/16] Add error handling for GPIO in SPIDEV --- utility/SPIDEV/gpio.cpp | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/utility/SPIDEV/gpio.cpp b/utility/SPIDEV/gpio.cpp index 10ed514a5..2d6f87072 100644 --- a/utility/SPIDEV/gpio.cpp +++ b/utility/SPIDEV/gpio.cpp @@ -47,9 +47,11 @@ void GPIO::Gopen(int port, int DDR) fd = open(dev_name, O_RDONLY); if (fd >= 0){ - + close(fd); + }else{ + throw GPIOException("Can't open device"); } - close(fd); + #if !defined NEWGPIO @@ -134,8 +136,16 @@ int GPIO::Gread(int port) rq.flags = GPIOHANDLE_REQUEST_INPUT; rq.lines = 1; ret = ioctl(fd, GPIO_GET_LINEHANDLE_IOCTL, &rq); + if(ret == -1){ + throw GPIOException("Can't get line handle from IOCTL"); + return ret; + } close(fd); ret = ioctl(rq.fd, GPIOHANDLE_GET_LINE_VALUES_IOCTL, &data); + if(ret == -1){ + throw GPIOException("Can't get line value from IOCTL"); + return ret; + } close(rq.fd); return ret; } @@ -189,13 +199,25 @@ void GPIO::Gwrite(int port, int value) struct gpiohandle_data data; int fd, ret; fd = open(dev_name, O_RDONLY); + if(fd < 0){ + throw GPIOException("Can't open dev"); + return; + } rq.lineoffsets[0] = port; rq.flags = GPIOHANDLE_REQUEST_OUTPUT; rq.lines = 1; ret = ioctl(fd, GPIO_GET_LINEHANDLE_IOCTL, &rq); + if(ret == -1){ + throw GPIOException("Can't get line handle from IOCTL"); + return; + } close(fd); data.values[0] = value; ret = ioctl(rq.fd, GPIOHANDLE_SET_LINE_VALUES_IOCTL, &data); + if(ret == -1){ + throw GPIOException("Can't set line value from IOCTL"); + return; + } close(rq.fd); #if !defined NEWGPIO From edab1cd0f0fdc7be3e0e379791d433f2a213e217 Mon Sep 17 00:00:00 2001 From: TMRh20 Date: Tue, 13 Feb 2024 05:56:36 -0600 Subject: [PATCH 03/16] Minor update - Try using gpiochip4 then 0 if that fails to support RPi5 - Remove old GPIO code --- utility/SPIDEV/gpio.cpp | 168 +++------------------------------------- utility/SPIDEV/gpio.h | 3 +- 2 files changed, 10 insertions(+), 161 deletions(-) diff --git a/utility/SPIDEV/gpio.cpp b/utility/SPIDEV/gpio.cpp index 2d6f87072..b6bac03ae 100644 --- a/utility/SPIDEV/gpio.cpp +++ b/utility/SPIDEV/gpio.cpp @@ -22,14 +22,7 @@ #include #include -const char* dev_name = "/dev/gpiochip0"; - -#define NEWGPIO - - -//std::map GPIO::cache; - - +char* dev_name = "/dev/gpiochip4"; GPIO::GPIO() { @@ -42,86 +35,23 @@ GPIO::~GPIO() int fd; void GPIO::Gopen(int port, int DDR) -{ - - +{ fd = open(dev_name, O_RDONLY); if (fd >= 0){ close(fd); }else{ - throw GPIOException("Can't open device"); - } - - #if !defined NEWGPIO - - - FILE* f; - f = fopen("/sys/class/gpio/export", "w"); - if (f == NULL) { - throw GPIOException("can't export GPIO pin .check access rights"); - } - fprintf(f, "%d\n", port); - fclose(f); - - int counter = 0; - char file[128]; - sprintf(file, "/sys/class/gpio/gpio%d/direction", port); - - while ((f = fopen(file, "w")) == NULL) { //Wait 10 seconds for the file to be accessible if not open on first attempt - sleep(1); - counter++; - if (counter > 10) { - throw GPIOException("can't access /sys/class/gpio/gpio%d/direction GPIO pin. check access rights"); - /*perror("Could not open /sys/class/gpio/gpio%d/direction"); - exit(0); */ - } - } - int l = (DDR == 0) ? fprintf(f, "in\n") : fprintf(f, "out\n"); - if (!(l == 3 || l == 4)) { - fclose(f); - throw GPIOException("can't set direction on GPIO pin. check access rights"); - } - /* - if (DDR == 0) - fprintf(f, "in\n"); - else - printf(f, "out\n"); - */ - fclose(f); - - // Caches the GPIO descriptor; - sprintf(file, "/sys/class/gpio/gpio%d/value", port); - int flags = (DDR == 0) ? O_RDONLY : O_WRONLY; - int fd = ::open(file, flags); - if (fd < 0) { - throw GPIOException("Can't open the GPIO"); - } - else { - cache[port] = fd; // cache the fd; - lseek(fd, SEEK_SET, 0); + dev_name = "/dev/gpiochip0"; + fd = open(dev_name, O_RDONLY); + if (fd >= 0){ + close(fd); + }else{ + throw GPIOException("can't open /dev/gpiochip"); } - #endif - + } } void GPIO::Gclose(int port) { - close(fd); - #if !defined NEWGPIO - std::map::iterator i; - i = cache.find(port); - if (i != cache.end()) { - close(i->second); // close the cached fd - cache.erase(i); // Delete cache entry - } - // Do unexport - FILE* f; - f = fopen("/sys/class/gpio/unexport", "w"); - if (f != NULL) { - fprintf(f, "%d\n", port); - fclose(f); - } - #endif } int GPIO::Gread(int port) @@ -151,45 +81,6 @@ int GPIO::Gread(int port) } return -1; - #if !defined NEWGPIO - std::map::iterator i; - int fd; - i = cache.find(port); - if (i == cache.end()) { // Fallback to open the gpio - GPIO::open(port, GPIO::DIRECTION_IN); - i = cache.find(port); - if (i == cache.end()) { - throw GPIOException("can't access to GPIO"); - } - else { - fd = i->second; - } - } - else { - fd = i->second; - } - - char c; - if (lseek(fd, 0, SEEK_SET) == 0 && ::read(fd, &c, 1) == 1) { - return (c == '0') ? 0 : 1; - } - else { - throw GPIOException("can't access to GPIO"); - } - - /* - FILE *f; - - char file[128]; - sprintf(file, "/sys/class/gpio/gpio%d/value", port); - f = fopen(file, "r"); - - int i; - fscanf(f, "%d", &i); - fclose(f); - return i; - */ - #endif } void GPIO::Gwrite(int port, int value) @@ -219,46 +110,5 @@ void GPIO::Gwrite(int port, int value) return; } close(rq.fd); - - #if !defined NEWGPIO - std::map::iterator i; - int fd; - i = cache.find(port); - if (i == cache.end()) { // Fallback to open the gpio - GPIO::open(port, GPIO::DIRECTION_OUT); - i = cache.find(port); - if (i == cache.end()) { - throw GPIOException("can't access to GPIO"); - } - else { - fd = i->second; - } - } - else { - fd = i->second; - } - - if (lseek(fd, 0, SEEK_SET) != 0) { - throw GPIOException("can't access to GPIO"); - } - int l = (value == 0) ? ::write(fd, "0\n", 2) : ::write(fd, "1\n", 2); - if (l != 2) { - throw GPIOException("can't access to GPIO"); - } - - /* - FILE *f; - - char file[128]; - sprintf(file, "/sys/class/gpio/gpio%d/value", port); - f = fopen(file, "w"); - - if (value == 0) - fprintf(f, "0\n"); - else - fprintf(f, "1\n"); - fclose(f); - */ - #endif } diff --git a/utility/SPIDEV/gpio.h b/utility/SPIDEV/gpio.h index aa7cd6295..6b7f5809b 100644 --- a/utility/SPIDEV/gpio.h +++ b/utility/SPIDEV/gpio.h @@ -53,8 +53,7 @@ class GPIO virtual ~GPIO(); private: - /* fd cache */ - //static std::map cache; + }; #endif // RF24_UTILITY_SPIDEV_GPIO_H_ From ded775b6914e50d52693d89a2a54bf5d465fc7be Mon Sep 17 00:00:00 2001 From: TMRh20 Date: Tue, 13 Feb 2024 05:59:36 -0600 Subject: [PATCH 04/16] Formatting --- utility/SPIDEV/gpio.cpp | 80 ++++++++++++++++++++--------------------- utility/SPIDEV/gpio.h | 4 +-- 2 files changed, 41 insertions(+), 43 deletions(-) diff --git a/utility/SPIDEV/gpio.cpp b/utility/SPIDEV/gpio.cpp index b6bac03ae..3c27330bf 100644 --- a/utility/SPIDEV/gpio.cpp +++ b/utility/SPIDEV/gpio.cpp @@ -35,19 +35,21 @@ GPIO::~GPIO() int fd; void GPIO::Gopen(int port, int DDR) -{ - fd = open(dev_name, O_RDONLY); - if (fd >= 0){ - close(fd); - }else{ - dev_name = "/dev/gpiochip0"; +{ fd = open(dev_name, O_RDONLY); - if (fd >= 0){ - close(fd); - }else{ - throw GPIOException("can't open /dev/gpiochip"); + if (fd >= 0) { + close(fd); + } + else { + dev_name = "/dev/gpiochip0"; + fd = open(dev_name, O_RDONLY); + if (fd >= 0) { + close(fd); + } + else { + throw GPIOException("can't open /dev/gpiochip"); + } } - } } void GPIO::Gclose(int port) @@ -56,59 +58,57 @@ void GPIO::Gclose(int port) int GPIO::Gread(int port) { - + struct gpiohandle_request rq; struct gpiohandle_data data; int fd, ret; fd = open(dev_name, O_RDONLY); - if (fd >= 0){ - rq.lineoffsets[0] = port; - rq.flags = GPIOHANDLE_REQUEST_INPUT; - rq.lines = 1; - ret = ioctl(fd, GPIO_GET_LINEHANDLE_IOCTL, &rq); - if(ret == -1){ - throw GPIOException("Can't get line handle from IOCTL"); + if (fd >= 0) { + rq.lineoffsets[0] = port; + rq.flags = GPIOHANDLE_REQUEST_INPUT; + rq.lines = 1; + ret = ioctl(fd, GPIO_GET_LINEHANDLE_IOCTL, &rq); + if (ret == -1) { + throw GPIOException("Can't get line handle from IOCTL"); + return ret; + } + close(fd); + ret = ioctl(rq.fd, GPIOHANDLE_GET_LINE_VALUES_IOCTL, &data); + if (ret == -1) { + throw GPIOException("Can't get line value from IOCTL"); + return ret; + } + close(rq.fd); return ret; - } - close(fd); - ret = ioctl(rq.fd, GPIOHANDLE_GET_LINE_VALUES_IOCTL, &data); - if(ret == -1){ - throw GPIOException("Can't get line value from IOCTL"); - return ret; - } - close(rq.fd); - return ret; } return -1; - } void GPIO::Gwrite(int port, int value) { - + struct gpiohandle_request rq; struct gpiohandle_data data; int fd, ret; fd = open(dev_name, O_RDONLY); - if(fd < 0){ - throw GPIOException("Can't open dev"); - return; + if (fd < 0) { + throw GPIOException("Can't open dev"); + return; } rq.lineoffsets[0] = port; rq.flags = GPIOHANDLE_REQUEST_OUTPUT; rq.lines = 1; ret = ioctl(fd, GPIO_GET_LINEHANDLE_IOCTL, &rq); - if(ret == -1){ - throw GPIOException("Can't get line handle from IOCTL"); - return; + if (ret == -1) { + throw GPIOException("Can't get line handle from IOCTL"); + return; } close(fd); data.values[0] = value; ret = ioctl(rq.fd, GPIOHANDLE_SET_LINE_VALUES_IOCTL, &data); - if(ret == -1){ - throw GPIOException("Can't set line value from IOCTL"); - return; + if (ret == -1) { + throw GPIOException("Can't set line value from IOCTL"); + return; } close(rq.fd); - } diff --git a/utility/SPIDEV/gpio.h b/utility/SPIDEV/gpio.h index 6b7f5809b..71b0f4295 100644 --- a/utility/SPIDEV/gpio.h +++ b/utility/SPIDEV/gpio.h @@ -17,7 +17,6 @@ #include #include - /** Specific excpetion for SPI errors */ class GPIOException : public std::runtime_error { @@ -51,9 +50,8 @@ class GPIO static void Gwrite(int port, int value); virtual ~GPIO(); - -private: +private: }; #endif // RF24_UTILITY_SPIDEV_GPIO_H_ From 51cccd991ab466b272f219b727a126d7537f773d Mon Sep 17 00:00:00 2001 From: TMRh20 Date: Thu, 11 Jan 2024 16:33:54 -0600 Subject: [PATCH 05/16] Testing GPIO Very rudimentary changes for testing https://github.com/nRF24/RF24/issues/932 --- utility/SPIDEV/RF24_arch_config.h | 4 +- utility/SPIDEV/gpio.cpp | 76 ++++++++++++++++++++++++++++--- utility/SPIDEV/gpio.h | 12 ++--- 3 files changed, 78 insertions(+), 14 deletions(-) diff --git a/utility/SPIDEV/RF24_arch_config.h b/utility/SPIDEV/RF24_arch_config.h index fa457fde6..be7585b94 100644 --- a/utility/SPIDEV/RF24_arch_config.h +++ b/utility/SPIDEV/RF24_arch_config.h @@ -61,8 +61,8 @@ typedef uint16_t rf24_gpio_pin_t; #define HIGH GPIO::OUTPUT_HIGH #define INPUT GPIO::DIRECTION_IN #define OUTPUT GPIO::DIRECTION_OUT -#define digitalWrite(pin, value) GPIO::write(pin, value) -#define pinMode(pin, direction) GPIO::open(pin, direction) +#define digitalWrite(pin, value) GPIO::Gwrite(pin, value) +#define pinMode(pin, direction) GPIO::Gopen(pin, direction) #define delay(milisec) __msleep(milisec) #define delayMicroseconds(usec) __usleep(usec) #define millis() __millis() diff --git a/utility/SPIDEV/gpio.cpp b/utility/SPIDEV/gpio.cpp index a8986009d..10ed514a5 100644 --- a/utility/SPIDEV/gpio.cpp +++ b/utility/SPIDEV/gpio.cpp @@ -9,15 +9,27 @@ * * Patched for filedescriptor catching and error control by L Diaz 2018 */ - +#include #include "gpio.h" #include +#include #include #include +#include +#include +#include #include #include +#include + +const char* dev_name = "/dev/gpiochip0"; + +#define NEWGPIO + + +//std::map GPIO::cache; + -std::map GPIO::cache; GPIO::GPIO() { @@ -27,8 +39,20 @@ GPIO::~GPIO() { } -void GPIO::open(int port, int DDR) +int fd; + +void GPIO::Gopen(int port, int DDR) { + + + fd = open(dev_name, O_RDONLY); + if (fd >= 0){ + + } + close(fd); + #if !defined NEWGPIO + + FILE* f; f = fopen("/sys/class/gpio/export", "w"); if (f == NULL) { @@ -74,10 +98,14 @@ void GPIO::open(int port, int DDR) cache[port] = fd; // cache the fd; lseek(fd, SEEK_SET, 0); } + #endif + } -void GPIO::close(int port) +void GPIO::Gclose(int port) { + close(fd); + #if !defined NEWGPIO std::map::iterator i; i = cache.find(port); if (i != cache.end()) { @@ -91,10 +119,29 @@ void GPIO::close(int port) fprintf(f, "%d\n", port); fclose(f); } + #endif } -int GPIO::read(int port) +int GPIO::Gread(int port) { + + struct gpiohandle_request rq; + struct gpiohandle_data data; + int fd, ret; + fd = open(dev_name, O_RDONLY); + if (fd >= 0){ + rq.lineoffsets[0] = port; + rq.flags = GPIOHANDLE_REQUEST_INPUT; + rq.lines = 1; + ret = ioctl(fd, GPIO_GET_LINEHANDLE_IOCTL, &rq); + close(fd); + ret = ioctl(rq.fd, GPIOHANDLE_GET_LINE_VALUES_IOCTL, &data); + close(rq.fd); + return ret; + } + return -1; + + #if !defined NEWGPIO std::map::iterator i; int fd; i = cache.find(port); @@ -132,10 +179,26 @@ int GPIO::read(int port) fclose(f); return i; */ + #endif } -void GPIO::write(int port, int value) +void GPIO::Gwrite(int port, int value) { + + struct gpiohandle_request rq; + struct gpiohandle_data data; + int fd, ret; + fd = open(dev_name, O_RDONLY); + rq.lineoffsets[0] = port; + rq.flags = GPIOHANDLE_REQUEST_OUTPUT; + rq.lines = 1; + ret = ioctl(fd, GPIO_GET_LINEHANDLE_IOCTL, &rq); + close(fd); + data.values[0] = value; + ret = ioctl(rq.fd, GPIOHANDLE_SET_LINE_VALUES_IOCTL, &data); + close(rq.fd); + + #if !defined NEWGPIO std::map::iterator i; int fd; i = cache.find(port); @@ -175,4 +238,5 @@ void GPIO::write(int port, int value) fclose(f); */ + #endif } diff --git a/utility/SPIDEV/gpio.h b/utility/SPIDEV/gpio.h index ff92806c5..d2ceda7b5 100644 --- a/utility/SPIDEV/gpio.h +++ b/utility/SPIDEV/gpio.h @@ -41,19 +41,19 @@ class GPIO GPIO(); - static void open(int port, int DDR); + static void Gopen(int port, int DDR); - static void close(int port); + static void Gclose(int port); - static int read(int port); + static int Gread(int port); - static void write(int port, int value); + static void Gwrite(int port, int value); virtual ~GPIO(); - + private: /* fd cache */ - static std::map cache; + //static std::map cache; }; #endif // RF24_UTILITY_SPIDEV_GPIO_H_ From 752c9b690bb0ea4ed3dccd971368aca60c337b8f Mon Sep 17 00:00:00 2001 From: TMRh20 Date: Sun, 14 Jan 2024 03:30:42 -0600 Subject: [PATCH 06/16] Add error handling for GPIO in SPIDEV --- utility/SPIDEV/gpio.cpp | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/utility/SPIDEV/gpio.cpp b/utility/SPIDEV/gpio.cpp index 10ed514a5..2d6f87072 100644 --- a/utility/SPIDEV/gpio.cpp +++ b/utility/SPIDEV/gpio.cpp @@ -47,9 +47,11 @@ void GPIO::Gopen(int port, int DDR) fd = open(dev_name, O_RDONLY); if (fd >= 0){ - + close(fd); + }else{ + throw GPIOException("Can't open device"); } - close(fd); + #if !defined NEWGPIO @@ -134,8 +136,16 @@ int GPIO::Gread(int port) rq.flags = GPIOHANDLE_REQUEST_INPUT; rq.lines = 1; ret = ioctl(fd, GPIO_GET_LINEHANDLE_IOCTL, &rq); + if(ret == -1){ + throw GPIOException("Can't get line handle from IOCTL"); + return ret; + } close(fd); ret = ioctl(rq.fd, GPIOHANDLE_GET_LINE_VALUES_IOCTL, &data); + if(ret == -1){ + throw GPIOException("Can't get line value from IOCTL"); + return ret; + } close(rq.fd); return ret; } @@ -189,13 +199,25 @@ void GPIO::Gwrite(int port, int value) struct gpiohandle_data data; int fd, ret; fd = open(dev_name, O_RDONLY); + if(fd < 0){ + throw GPIOException("Can't open dev"); + return; + } rq.lineoffsets[0] = port; rq.flags = GPIOHANDLE_REQUEST_OUTPUT; rq.lines = 1; ret = ioctl(fd, GPIO_GET_LINEHANDLE_IOCTL, &rq); + if(ret == -1){ + throw GPIOException("Can't get line handle from IOCTL"); + return; + } close(fd); data.values[0] = value; ret = ioctl(rq.fd, GPIOHANDLE_SET_LINE_VALUES_IOCTL, &data); + if(ret == -1){ + throw GPIOException("Can't set line value from IOCTL"); + return; + } close(rq.fd); #if !defined NEWGPIO From d068e75cd9a9c1f47fba9be1b136e9458c327a0c Mon Sep 17 00:00:00 2001 From: TMRh20 Date: Tue, 13 Feb 2024 05:56:36 -0600 Subject: [PATCH 07/16] Minor update - Try using gpiochip4 then 0 if that fails to support RPi5 - Remove old GPIO code --- utility/SPIDEV/gpio.cpp | 168 +++------------------------------------- utility/SPIDEV/gpio.h | 3 +- 2 files changed, 10 insertions(+), 161 deletions(-) diff --git a/utility/SPIDEV/gpio.cpp b/utility/SPIDEV/gpio.cpp index 2d6f87072..b6bac03ae 100644 --- a/utility/SPIDEV/gpio.cpp +++ b/utility/SPIDEV/gpio.cpp @@ -22,14 +22,7 @@ #include #include -const char* dev_name = "/dev/gpiochip0"; - -#define NEWGPIO - - -//std::map GPIO::cache; - - +char* dev_name = "/dev/gpiochip4"; GPIO::GPIO() { @@ -42,86 +35,23 @@ GPIO::~GPIO() int fd; void GPIO::Gopen(int port, int DDR) -{ - - +{ fd = open(dev_name, O_RDONLY); if (fd >= 0){ close(fd); }else{ - throw GPIOException("Can't open device"); - } - - #if !defined NEWGPIO - - - FILE* f; - f = fopen("/sys/class/gpio/export", "w"); - if (f == NULL) { - throw GPIOException("can't export GPIO pin .check access rights"); - } - fprintf(f, "%d\n", port); - fclose(f); - - int counter = 0; - char file[128]; - sprintf(file, "/sys/class/gpio/gpio%d/direction", port); - - while ((f = fopen(file, "w")) == NULL) { //Wait 10 seconds for the file to be accessible if not open on first attempt - sleep(1); - counter++; - if (counter > 10) { - throw GPIOException("can't access /sys/class/gpio/gpio%d/direction GPIO pin. check access rights"); - /*perror("Could not open /sys/class/gpio/gpio%d/direction"); - exit(0); */ - } - } - int l = (DDR == 0) ? fprintf(f, "in\n") : fprintf(f, "out\n"); - if (!(l == 3 || l == 4)) { - fclose(f); - throw GPIOException("can't set direction on GPIO pin. check access rights"); - } - /* - if (DDR == 0) - fprintf(f, "in\n"); - else - printf(f, "out\n"); - */ - fclose(f); - - // Caches the GPIO descriptor; - sprintf(file, "/sys/class/gpio/gpio%d/value", port); - int flags = (DDR == 0) ? O_RDONLY : O_WRONLY; - int fd = ::open(file, flags); - if (fd < 0) { - throw GPIOException("Can't open the GPIO"); - } - else { - cache[port] = fd; // cache the fd; - lseek(fd, SEEK_SET, 0); + dev_name = "/dev/gpiochip0"; + fd = open(dev_name, O_RDONLY); + if (fd >= 0){ + close(fd); + }else{ + throw GPIOException("can't open /dev/gpiochip"); } - #endif - + } } void GPIO::Gclose(int port) { - close(fd); - #if !defined NEWGPIO - std::map::iterator i; - i = cache.find(port); - if (i != cache.end()) { - close(i->second); // close the cached fd - cache.erase(i); // Delete cache entry - } - // Do unexport - FILE* f; - f = fopen("/sys/class/gpio/unexport", "w"); - if (f != NULL) { - fprintf(f, "%d\n", port); - fclose(f); - } - #endif } int GPIO::Gread(int port) @@ -151,45 +81,6 @@ int GPIO::Gread(int port) } return -1; - #if !defined NEWGPIO - std::map::iterator i; - int fd; - i = cache.find(port); - if (i == cache.end()) { // Fallback to open the gpio - GPIO::open(port, GPIO::DIRECTION_IN); - i = cache.find(port); - if (i == cache.end()) { - throw GPIOException("can't access to GPIO"); - } - else { - fd = i->second; - } - } - else { - fd = i->second; - } - - char c; - if (lseek(fd, 0, SEEK_SET) == 0 && ::read(fd, &c, 1) == 1) { - return (c == '0') ? 0 : 1; - } - else { - throw GPIOException("can't access to GPIO"); - } - - /* - FILE *f; - - char file[128]; - sprintf(file, "/sys/class/gpio/gpio%d/value", port); - f = fopen(file, "r"); - - int i; - fscanf(f, "%d", &i); - fclose(f); - return i; - */ - #endif } void GPIO::Gwrite(int port, int value) @@ -219,46 +110,5 @@ void GPIO::Gwrite(int port, int value) return; } close(rq.fd); - - #if !defined NEWGPIO - std::map::iterator i; - int fd; - i = cache.find(port); - if (i == cache.end()) { // Fallback to open the gpio - GPIO::open(port, GPIO::DIRECTION_OUT); - i = cache.find(port); - if (i == cache.end()) { - throw GPIOException("can't access to GPIO"); - } - else { - fd = i->second; - } - } - else { - fd = i->second; - } - - if (lseek(fd, 0, SEEK_SET) != 0) { - throw GPIOException("can't access to GPIO"); - } - int l = (value == 0) ? ::write(fd, "0\n", 2) : ::write(fd, "1\n", 2); - if (l != 2) { - throw GPIOException("can't access to GPIO"); - } - - /* - FILE *f; - - char file[128]; - sprintf(file, "/sys/class/gpio/gpio%d/value", port); - f = fopen(file, "w"); - - if (value == 0) - fprintf(f, "0\n"); - else - fprintf(f, "1\n"); - fclose(f); - */ - #endif } diff --git a/utility/SPIDEV/gpio.h b/utility/SPIDEV/gpio.h index d2ceda7b5..81799a461 100644 --- a/utility/SPIDEV/gpio.h +++ b/utility/SPIDEV/gpio.h @@ -52,8 +52,7 @@ class GPIO virtual ~GPIO(); private: - /* fd cache */ - //static std::map cache; + }; #endif // RF24_UTILITY_SPIDEV_GPIO_H_ From 86d0c38c9997554dde109d89247176addf776649 Mon Sep 17 00:00:00 2001 From: TMRh20 Date: Tue, 13 Feb 2024 05:59:36 -0600 Subject: [PATCH 08/16] Formatting --- utility/SPIDEV/gpio.cpp | 80 ++++++++++++++++++++--------------------- utility/SPIDEV/gpio.h | 3 +- 2 files changed, 41 insertions(+), 42 deletions(-) diff --git a/utility/SPIDEV/gpio.cpp b/utility/SPIDEV/gpio.cpp index b6bac03ae..3c27330bf 100644 --- a/utility/SPIDEV/gpio.cpp +++ b/utility/SPIDEV/gpio.cpp @@ -35,19 +35,21 @@ GPIO::~GPIO() int fd; void GPIO::Gopen(int port, int DDR) -{ - fd = open(dev_name, O_RDONLY); - if (fd >= 0){ - close(fd); - }else{ - dev_name = "/dev/gpiochip0"; +{ fd = open(dev_name, O_RDONLY); - if (fd >= 0){ - close(fd); - }else{ - throw GPIOException("can't open /dev/gpiochip"); + if (fd >= 0) { + close(fd); + } + else { + dev_name = "/dev/gpiochip0"; + fd = open(dev_name, O_RDONLY); + if (fd >= 0) { + close(fd); + } + else { + throw GPIOException("can't open /dev/gpiochip"); + } } - } } void GPIO::Gclose(int port) @@ -56,59 +58,57 @@ void GPIO::Gclose(int port) int GPIO::Gread(int port) { - + struct gpiohandle_request rq; struct gpiohandle_data data; int fd, ret; fd = open(dev_name, O_RDONLY); - if (fd >= 0){ - rq.lineoffsets[0] = port; - rq.flags = GPIOHANDLE_REQUEST_INPUT; - rq.lines = 1; - ret = ioctl(fd, GPIO_GET_LINEHANDLE_IOCTL, &rq); - if(ret == -1){ - throw GPIOException("Can't get line handle from IOCTL"); + if (fd >= 0) { + rq.lineoffsets[0] = port; + rq.flags = GPIOHANDLE_REQUEST_INPUT; + rq.lines = 1; + ret = ioctl(fd, GPIO_GET_LINEHANDLE_IOCTL, &rq); + if (ret == -1) { + throw GPIOException("Can't get line handle from IOCTL"); + return ret; + } + close(fd); + ret = ioctl(rq.fd, GPIOHANDLE_GET_LINE_VALUES_IOCTL, &data); + if (ret == -1) { + throw GPIOException("Can't get line value from IOCTL"); + return ret; + } + close(rq.fd); return ret; - } - close(fd); - ret = ioctl(rq.fd, GPIOHANDLE_GET_LINE_VALUES_IOCTL, &data); - if(ret == -1){ - throw GPIOException("Can't get line value from IOCTL"); - return ret; - } - close(rq.fd); - return ret; } return -1; - } void GPIO::Gwrite(int port, int value) { - + struct gpiohandle_request rq; struct gpiohandle_data data; int fd, ret; fd = open(dev_name, O_RDONLY); - if(fd < 0){ - throw GPIOException("Can't open dev"); - return; + if (fd < 0) { + throw GPIOException("Can't open dev"); + return; } rq.lineoffsets[0] = port; rq.flags = GPIOHANDLE_REQUEST_OUTPUT; rq.lines = 1; ret = ioctl(fd, GPIO_GET_LINEHANDLE_IOCTL, &rq); - if(ret == -1){ - throw GPIOException("Can't get line handle from IOCTL"); - return; + if (ret == -1) { + throw GPIOException("Can't get line handle from IOCTL"); + return; } close(fd); data.values[0] = value; ret = ioctl(rq.fd, GPIOHANDLE_SET_LINE_VALUES_IOCTL, &data); - if(ret == -1){ - throw GPIOException("Can't set line value from IOCTL"); - return; + if (ret == -1) { + throw GPIOException("Can't set line value from IOCTL"); + return; } close(rq.fd); - } diff --git a/utility/SPIDEV/gpio.h b/utility/SPIDEV/gpio.h index 81799a461..cbb2e48d2 100644 --- a/utility/SPIDEV/gpio.h +++ b/utility/SPIDEV/gpio.h @@ -50,9 +50,8 @@ class GPIO static void Gwrite(int port, int value); virtual ~GPIO(); - -private: +private: }; #endif // RF24_UTILITY_SPIDEV_GPIO_H_ From f05236a424247addb210c3125bc7c0996b0cbfe8 Mon Sep 17 00:00:00 2001 From: Brendan <2bndy5@gmail.com> Date: Sat, 17 Feb 2024 13:12:11 -0800 Subject: [PATCH 09/16] remove unnecessary includes --- utility/SPIDEV/gpio.cpp | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/utility/SPIDEV/gpio.cpp b/utility/SPIDEV/gpio.cpp index 3c27330bf..323844feb 100644 --- a/utility/SPIDEV/gpio.cpp +++ b/utility/SPIDEV/gpio.cpp @@ -11,16 +11,9 @@ */ #include #include "gpio.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include // close() +#include // open() +#include // ioctl() char* dev_name = "/dev/gpiochip4"; From 619b5fe8200993ef59eef4157d12799e47f30760 Mon Sep 17 00:00:00 2001 From: TMRh20 Date: Sat, 17 Feb 2024 17:34:22 -0600 Subject: [PATCH 10/16] Resolve compiler warnings --- utility/SPIDEV/gpio.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utility/SPIDEV/gpio.cpp b/utility/SPIDEV/gpio.cpp index 323844feb..d63c8f2e0 100644 --- a/utility/SPIDEV/gpio.cpp +++ b/utility/SPIDEV/gpio.cpp @@ -15,7 +15,7 @@ #include // open() #include // ioctl() -char* dev_name = "/dev/gpiochip4"; +const char* dev_name = "/dev/gpiochip4"; GPIO::GPIO() { From f5c61a57a9aa42914804fdec92a065004f91b3f6 Mon Sep 17 00:00:00 2001 From: TMRh20 Date: Sat, 17 Feb 2024 17:51:36 -0600 Subject: [PATCH 11/16] Make read() return value --- utility/SPIDEV/gpio.cpp | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/utility/SPIDEV/gpio.cpp b/utility/SPIDEV/gpio.cpp index d63c8f2e0..802ae3cad 100644 --- a/utility/SPIDEV/gpio.cpp +++ b/utility/SPIDEV/gpio.cpp @@ -1,13 +1,9 @@ /* - * https://github.com/mrshu/GPIOlib - * Copyright (c) 2011, Copyright (c) 2011 mr.Shu + * + * Copyright (c) 2024, Copyright (c) 2024 TMRh20 & 2bndy5 * All rights reserved. * - * Modified on 24 June 2012, 11:06 AM - * File: gpio.cpp - * Author: purinda (purinda@gmail.com) - * - * Patched for filedescriptor catching and error control by L Diaz 2018 + * */ #include #include "gpio.h" @@ -72,7 +68,7 @@ int GPIO::Gread(int port) return ret; } close(rq.fd); - return ret; + return data.values[0]; } return -1; } From da504fc858db623d514b637d4487d2d907f27a9c Mon Sep 17 00:00:00 2001 From: TMRh20 Date: Sat, 17 Feb 2024 17:57:05 -0600 Subject: [PATCH 12/16] Revert renaming of gpio functions --- utility/SPIDEV/RF24_arch_config.h | 4 ++-- utility/SPIDEV/gpio.cpp | 16 ++++++++-------- utility/SPIDEV/gpio.h | 8 ++++---- 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/utility/SPIDEV/RF24_arch_config.h b/utility/SPIDEV/RF24_arch_config.h index be7585b94..fa457fde6 100644 --- a/utility/SPIDEV/RF24_arch_config.h +++ b/utility/SPIDEV/RF24_arch_config.h @@ -61,8 +61,8 @@ typedef uint16_t rf24_gpio_pin_t; #define HIGH GPIO::OUTPUT_HIGH #define INPUT GPIO::DIRECTION_IN #define OUTPUT GPIO::DIRECTION_OUT -#define digitalWrite(pin, value) GPIO::Gwrite(pin, value) -#define pinMode(pin, direction) GPIO::Gopen(pin, direction) +#define digitalWrite(pin, value) GPIO::write(pin, value) +#define pinMode(pin, direction) GPIO::open(pin, direction) #define delay(milisec) __msleep(milisec) #define delayMicroseconds(usec) __usleep(usec) #define millis() __millis() diff --git a/utility/SPIDEV/gpio.cpp b/utility/SPIDEV/gpio.cpp index 802ae3cad..5d7c97e27 100644 --- a/utility/SPIDEV/gpio.cpp +++ b/utility/SPIDEV/gpio.cpp @@ -23,15 +23,15 @@ GPIO::~GPIO() int fd; -void GPIO::Gopen(int port, int DDR) +void GPIO::open(int port, int DDR) { - fd = open(dev_name, O_RDONLY); + fd = ::open(dev_name, O_RDONLY); if (fd >= 0) { close(fd); } else { dev_name = "/dev/gpiochip0"; - fd = open(dev_name, O_RDONLY); + fd = ::open(dev_name, O_RDONLY); if (fd >= 0) { close(fd); } @@ -41,17 +41,17 @@ void GPIO::Gopen(int port, int DDR) } } -void GPIO::Gclose(int port) +void GPIO::close(int port) { } -int GPIO::Gread(int port) +int GPIO::read(int port) { struct gpiohandle_request rq; struct gpiohandle_data data; int fd, ret; - fd = open(dev_name, O_RDONLY); + fd = ::open(dev_name, O_RDONLY); if (fd >= 0) { rq.lineoffsets[0] = port; rq.flags = GPIOHANDLE_REQUEST_INPUT; @@ -73,13 +73,13 @@ int GPIO::Gread(int port) return -1; } -void GPIO::Gwrite(int port, int value) +void GPIO::write(int port, int value) { struct gpiohandle_request rq; struct gpiohandle_data data; int fd, ret; - fd = open(dev_name, O_RDONLY); + fd = ::open(dev_name, O_RDONLY); if (fd < 0) { throw GPIOException("Can't open dev"); return; diff --git a/utility/SPIDEV/gpio.h b/utility/SPIDEV/gpio.h index cbb2e48d2..b9a607f20 100644 --- a/utility/SPIDEV/gpio.h +++ b/utility/SPIDEV/gpio.h @@ -41,13 +41,13 @@ class GPIO GPIO(); - static void Gopen(int port, int DDR); + static void open(int port, int DDR); - static void Gclose(int port); + static void close(int port); - static int Gread(int port); + static int read(int port); - static void Gwrite(int port, int value); + static void write(int port, int value); virtual ~GPIO(); From 8a3be527feae62095362776d2422c9ca20c74f25 Mon Sep 17 00:00:00 2001 From: TMRh20 Date: Sat, 17 Feb 2024 17:57:37 -0600 Subject: [PATCH 13/16] Update utility/SPIDEV/gpio.cpp Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- utility/SPIDEV/gpio.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utility/SPIDEV/gpio.cpp b/utility/SPIDEV/gpio.cpp index 802ae3cad..ba3dc80fc 100644 --- a/utility/SPIDEV/gpio.cpp +++ b/utility/SPIDEV/gpio.cpp @@ -1,5 +1,5 @@ /* - * + * * Copyright (c) 2024, Copyright (c) 2024 TMRh20 & 2bndy5 * All rights reserved. * From 8d577f3895c8bcc2f566e48b98091291dfe0e591 Mon Sep 17 00:00:00 2001 From: TMRh20 Date: Sat, 17 Feb 2024 17:57:44 -0600 Subject: [PATCH 14/16] Update utility/SPIDEV/gpio.cpp Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- utility/SPIDEV/gpio.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utility/SPIDEV/gpio.cpp b/utility/SPIDEV/gpio.cpp index ba3dc80fc..4b652f90a 100644 --- a/utility/SPIDEV/gpio.cpp +++ b/utility/SPIDEV/gpio.cpp @@ -3,7 +3,7 @@ * Copyright (c) 2024, Copyright (c) 2024 TMRh20 & 2bndy5 * All rights reserved. * - * + * */ #include #include "gpio.h" From 2abfebe68972e9c2a781819fa32f1b709ad9d6aa Mon Sep 17 00:00:00 2001 From: TMRh20 Date: Sat, 17 Feb 2024 18:16:30 -0600 Subject: [PATCH 15/16] Move int fd to gpio::open() function --- utility/SPIDEV/gpio.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/utility/SPIDEV/gpio.cpp b/utility/SPIDEV/gpio.cpp index be4f33543..f8b48a15e 100644 --- a/utility/SPIDEV/gpio.cpp +++ b/utility/SPIDEV/gpio.cpp @@ -21,10 +21,9 @@ GPIO::~GPIO() { } -int fd; - void GPIO::open(int port, int DDR) { + int fd; fd = ::open(dev_name, O_RDONLY); if (fd >= 0) { close(fd); From 9c9af87c5132de49e75e52ab9a749a3c5d7efce0 Mon Sep 17 00:00:00 2001 From: Brendan <2bndy5@gmail.com> Date: Sat, 17 Feb 2024 16:33:02 -0800 Subject: [PATCH 16/16] ensure we are calling ::close() instead of GPIO::close() --- utility/SPIDEV/gpio.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/utility/SPIDEV/gpio.cpp b/utility/SPIDEV/gpio.cpp index f8b48a15e..9f24a74eb 100644 --- a/utility/SPIDEV/gpio.cpp +++ b/utility/SPIDEV/gpio.cpp @@ -26,13 +26,13 @@ void GPIO::open(int port, int DDR) int fd; fd = ::open(dev_name, O_RDONLY); if (fd >= 0) { - close(fd); + ::close(fd); } else { dev_name = "/dev/gpiochip0"; fd = ::open(dev_name, O_RDONLY); if (fd >= 0) { - close(fd); + ::close(fd); } else { throw GPIOException("can't open /dev/gpiochip"); @@ -60,13 +60,13 @@ int GPIO::read(int port) throw GPIOException("Can't get line handle from IOCTL"); return ret; } - close(fd); + ::close(fd); ret = ioctl(rq.fd, GPIOHANDLE_GET_LINE_VALUES_IOCTL, &data); if (ret == -1) { throw GPIOException("Can't get line value from IOCTL"); return ret; } - close(rq.fd); + ::close(rq.fd); return data.values[0]; } return -1; @@ -91,12 +91,12 @@ void GPIO::write(int port, int value) throw GPIOException("Can't get line handle from IOCTL"); return; } - close(fd); + ::close(fd); data.values[0] = value; ret = ioctl(rq.fd, GPIOHANDLE_SET_LINE_VALUES_IOCTL, &data); if (ret == -1) { throw GPIOException("Can't set line value from IOCTL"); return; } - close(rq.fd); + ::close(rq.fd); }