From ad6d821329912dc0f5b465b1a0c85997f06a3f91 Mon Sep 17 00:00:00 2001 From: mstroh76 Date: Sat, 20 Apr 2024 19:48:33 +0200 Subject: [PATCH] #219 boost speed and improve compatibility with sysfs --- wiringPi/wiringPi.c | 162 +++++++++++++++++++++++++++++++--------------------- wiringPi/wiringPi.h | 1 + 2 files changed, 97 insertions(+), 66 deletions(-) diff --git a/wiringPi/wiringPi.c b/wiringPi/wiringPi.c index 3b227bf..2a05ce4 100644 --- a/wiringPi/wiringPi.c +++ b/wiringPi/wiringPi.c @@ -398,7 +398,7 @@ int wiringPiTryGpioMem = FALSE ; // sysFds: // Map a file descriptor from the /sys/class/gpio/gpioX/value -static unsigned int cdflags [64] = +static unsigned int lineFlags [64] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -406,6 +406,14 @@ static unsigned int cdflags [64] = 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, } ; +static int lineFds [64] = +{ + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +} ; + static int sysFds [64] = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, @@ -1557,6 +1565,48 @@ int GetChipFd() { return chipFd; } +void releaseLine(int pin) { + + if (wiringPiDebug) + printf ("releaseLine: pin:%d\n", pin) ; + lineFlags[pin] = 0; + close(lineFds[pin]); + lineFds[pin] = -1; +} + +int requestLine(int pin, unsigned int lineRequestFlags) { + struct gpiohandle_request rq; + + if (lineFds[pin]>=0) { + if (lineRequestFlags == lineFlags[pin]) { + //already requested + return lineFds[pin]; + } else { + //different request -> rerequest + releaseLine(pin); + } + } + + //requested line + if (GetChipFd()<0) { + return -1; // error + } + rq.lineoffsets[0] = pin; + rq.lines = 1; + rq.flags = lineRequestFlags; + int ret = ioctl(chipFd, GPIO_GET_LINEHANDLE_IOCTL, &rq); + if (ret || rq.fd<0) { + ReportDeviceError("get line handle", pin, "RequestLine", ret); + return -1; // error + } + + lineFlags[pin] = lineRequestFlags; + lineFds[pin] = rq.fd; + if (wiringPiDebug) + printf ("requestLine succeeded: pin:%d, flags: %u, fd :%d\n", pin, lineRequestFlags, lineFds[pin]) ; + return lineFds[pin]; +} + /* ********************************************************************************* * Core Functions @@ -1636,28 +1686,17 @@ void pinModeFlagsDevice (int pin, int mode, unsigned int flags) { case OUTPUT: lflag |= GPIOHANDLE_REQUEST_OUTPUT; break; - } - if (GetChipFd()<0) { - return; // error + case PM_OFF: + pinModeFlagsDevice(pin, INPUT, 0); + releaseLine(pin); + return; } - struct gpiohandle_request rq; - rq.lineoffsets[0] = pin; - rq.lines = 1; - rq.flags = lflag; - if (wiringPiDebug) - printf ("pinModeFlagsDevice: ioctl pin:%d cmd: GPIO_GET_LINEHANDLE_IOCTL, flags: %u\n", pin, lflag) ; - int ret = ioctl(chipFd, GPIO_GET_LINEHANDLE_IOCTL, &rq); - if (ret) { - ReportDeviceError("get line handle", pin, "pinMode", ret); - return; // error - } - cdflags[pin] = lflag; - close(rq.fd); + requestLine(pin, lflag); } void pinModeDevice (int pin, int mode) { - pinModeFlagsDevice (pin, mode, cdflags[pin]); + pinModeFlagsDevice(pin, mode, lineFlags[pin]); } void pinMode (int pin, int mode) @@ -1684,7 +1723,8 @@ void pinMode (int pin, int mode) pin = physToGpio [pin]; break; case WPI_MODE_GPIO_DEVICE: - return pinModeDevice(pin, mode); + pinModeDevice(pin, mode); + return; case WPI_MODE_GPIO: break; } @@ -1727,7 +1767,7 @@ void pinMode (int pin, int mode) { RETURN_ON_MODEL5 if ((alt = gpioToPwmALT [pin]) == 0) // Not a hardware capable PWM pin - return ; + return ; usingGpioMemCheck ("pinMode PWM") ; @@ -1744,7 +1784,7 @@ void pinMode (int pin, int mode) { RETURN_ON_MODEL5 if ((alt = gpioToGpClkALT0 [pin]) == 0) // Not a GPIO_CLOCK pin - return ; + return ; usingGpioMemCheck ("pinMode CLOCK") ; @@ -1770,7 +1810,7 @@ void pinMode (int pin, int mode) ********************************************************************************* */ void pullUpDnControlDevice (int pin, int pud) { - unsigned int flag = cdflags[pin]; + unsigned int flag = lineFlags[pin]; unsigned int biasflags = GPIOHANDLE_REQUEST_BIAS_DISABLE | GPIOHANDLE_REQUEST_BIAS_PULL_UP | GPIOHANDLE_REQUEST_BIAS_PULL_DOWN; flag &= ~biasflags; @@ -1782,12 +1822,12 @@ void pullUpDnControlDevice (int pin, int pud) { } // reset input/output - if (cdflags[pin] & GPIOHANDLE_REQUEST_OUTPUT) { + if (lineFlags[pin] & GPIOHANDLE_REQUEST_OUTPUT) { pinModeFlagsDevice (pin, OUTPUT, flag); - } else if(cdflags[pin] & GPIOHANDLE_REQUEST_INPUT) { + } else if(lineFlags[pin] & GPIOHANDLE_REQUEST_INPUT) { pinModeFlagsDevice (pin, INPUT, flag); } else { - cdflags[pin] = flag; // only store for later + lineFlags[pin] = flag; // only store for later } } @@ -1865,34 +1905,30 @@ void pullUpDnControl (int pin, int pud) } + + /* * digitalRead: * Read the value of a given Pin, returning HIGH or LOW ********************************************************************************* */ -int digitalReadDevice (int pin) { - struct gpiohandle_data data; - struct gpiohandle_request rq; +int digitalReadDevice (int pin) { // INPUT and OUTPUT should work - if (GetChipFd()<0) { - return LOW; // error - } - rq.lineoffsets[0] = pin; - rq.lines = 1; - rq.flags = GPIOHANDLE_REQUEST_INPUT; - int ret = ioctl(chipFd, GPIO_GET_LINEHANDLE_IOCTL, &rq); - if (ret) { - ReportDeviceError("get line handle", pin, "digitalRead", ret); - return LOW; // error + if (lineFds[pin]<0) { + // line not requested - auto request on first read as input + pinModeDevice(pin, INPUT); } - ret = ioctl(rq.fd, GPIOHANDLE_GET_LINE_VALUES_IOCTL, &data); - if (ret) { - ReportDeviceError("get line values", pin, "digitalRead", ret); - return LOW; // error + if (lineFds[pin]>=0) { + struct gpiohandle_data data; + int ret = ioctl(lineFds[pin], GPIOHANDLE_GET_LINE_VALUES_IOCTL, &data); + if (ret) { + ReportDeviceError("get line values", pin, "digitalRead", ret); + return LOW; // error + } + return data.values[0]; } - close(rq.fd); - return data.values[0]; + return LOW; // error , need to request line before } @@ -1969,33 +2005,27 @@ unsigned int digitalRead8 (int pin) void digitalWriteDevice (int pin, int value) { - struct gpiohandle_data data; - struct gpiohandle_request rq; - if (wiringPiDebug) printf ("digitalWriteDevice: ioctl pin:%d value: %d\n", pin, value) ; - if (GetChipFd()<0) { - return; // error + if (lineFds[pin]<0) { + // line not requested - auto request on first write as output + pinModeDevice(pin, OUTPUT); } - rq.lineoffsets[0] = pin; - rq.lines = 1; - rq.flags = GPIOHANDLE_REQUEST_OUTPUT; - int ret = ioctl(chipFd, GPIO_GET_LINEHANDLE_IOCTL, &rq); - if (ret && rq.fd>0) { - ReportDeviceError("get line handle", pin, "digitalWrite", ret); - return; // error - } - data.values[0] = value; - if (wiringPiDebug) - printf ("digitalWriteDevice: ioctl pin:%d cmd: GPIOHANDLE_SET_LINE_VALUES_IOCTL, value: %d\n", pin, value) ; - ret = ioctl(rq.fd, GPIOHANDLE_SET_LINE_VALUES_IOCTL, &data); - if (ret) { - ReportDeviceError("set line values", pin, "digitalWrite", ret); - return; // error + if (lineFds[pin]>=0 && (lineFlags[pin] & GPIOHANDLE_REQUEST_OUTPUT)>0) { + struct gpiohandle_data data; + data.values[0] = value; + if (wiringPiDebug) + printf ("digitalWriteDevice: ioctl pin:%d cmd: GPIOHANDLE_SET_LINE_VALUES_IOCTL, value: %d\n", pin, value) ; + int ret = ioctl(lineFds[pin], GPIOHANDLE_SET_LINE_VALUES_IOCTL, &data); + if (ret) { + ReportDeviceError("set line values", pin, "digitalWrite", ret); + return; // error + } + } else { + fprintf(stderr, "digitalWrite: no output (%d)\n", lineFlags[pin]); } - close(rq.fd); - return; + return; // error } void digitalWrite (int pin, int value) diff --git a/wiringPi/wiringPi.h b/wiringPi/wiringPi.h index 436143f..029b6bb 100644 --- a/wiringPi/wiringPi.h +++ b/wiringPi/wiringPi.h @@ -63,6 +63,7 @@ #define SOFT_PWM_OUTPUT 4 #define SOFT_TONE_OUTPUT 5 #define PWM_TONE_OUTPUT 6 +#define PM_OFF 7 // to input / release line #define LOW 0 #define HIGH 1