From b0c579308668d64bf237652eb9d5d0ee74095d4c Mon Sep 17 00:00:00 2001 From: mstroh76 Date: Tue, 16 Apr 2024 18:50:37 +0200 Subject: [PATCH 01/16] #219 --- wiringPi/wiringPi.c | 343 +++++++++++++++++++++++++++++++++++++++++----------- wiringPi/wiringPi.h | 14 ++- 2 files changed, 278 insertions(+), 79 deletions(-) diff --git a/wiringPi/wiringPi.c b/wiringPi/wiringPi.c index 7f685b9..3b227bf 100644 --- a/wiringPi/wiringPi.c +++ b/wiringPi/wiringPi.c @@ -398,6 +398,14 @@ int wiringPiTryGpioMem = FALSE ; // sysFds: // Map a file descriptor from the /sys/class/gpio/gpioX/value +static unsigned int cdflags [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, + 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, +} ; + static int sysFds [64] = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, @@ -561,12 +569,18 @@ static int physToSysGPIOPi5 [41] = _0v, 420, //39, 40 } ; -int GPIOToSysFS(const int pin) { - int sysfspin = pin; + +int piBoard() { if (RaspberryPiModel<0) { //need to detect pi model - int model, rev, mem, maker, overVolted ; - piBoardId (&model, &rev, &mem, &maker, &overVolted) ; + int model, rev, mem, maker, overVolted; + piBoardId (&model, &rev, &mem, &maker, &overVolted); } + return RaspberryPiModel<0 ? 0 : 1; +} + +int GPIOToSysFS(const int pin) { + int sysfspin = pin; + piBoard(); if (PI_MODEL_5 == RaspberryPiModel) { sysfspin = pin + 399; if (sysfspin<399 || sysfspin>426) { // only 399-426 supported, 40-pin GPIO header @@ -884,6 +898,10 @@ void piFunctionOops (const char *function, const char* suggestion, const char* u exit (EXIT_FAILURE) ; } +void ReportDeviceError(const char *function, int pin, const char *mode, int ret) { + fprintf(stderr, "wiringPi: ERROR: ioctl %s of %d (%s) returned error '%s' (%d)\n", function, pin, mode, strerror(errno), ret); +} + /* * piGpioLayout: @@ -923,10 +941,7 @@ void piGpioLayoutOops (const char *why) int piGpioLayout (void) { - if (-1==RaspberryPiLayout) { - int model, rev, mem, maker, overVolted ; - piBoardId (&model, &rev, &mem, &maker, &overVolted) ; - } + piBoard(); return RaspberryPiLayout; } @@ -1525,6 +1540,23 @@ void pinEnableED01Pi (int pin) #endif +const char DEV_GPIO_PI[] ="/dev/gpiochip0"; +const char DEV_GPIO_PI5[]="/dev/gpiochip4"; + +int GetChipFd() { + if (chipFd<0) { + piBoard(); + const char* gpiochip = PI_MODEL_5 == RaspberryPiModel ? DEV_GPIO_PI5 : DEV_GPIO_PI; + chipFd = open(gpiochip, O_RDWR); + if (chipFd < 0) { + fprintf(stderr, "wiringPi: ERROR: %s open ret=%d\n", gpiochip, chipFd); + } else if (wiringPiDebug) { + printf ("wiringPi: Open chip %s succeded, fd=%d\n", gpiochip, chipFd) ; + } + } + return chipFd; +} + /* ********************************************************************************* * Core Functions @@ -1588,6 +1620,46 @@ void rp1_set_pad(int pin, int slewfast, int schmitt, int pulldown, int pullup, i pads[1+pin] = (slewfast != 0) | ((schmitt != 0) << 1) | ((pulldown != 0) << 2) | ((pullup != 0) << 3) | ((drive & 0x3) << 4) | ((inputenable != 0) << 6) | ((outputdisable != 0) << 7); } +void pinModeFlagsDevice (int pin, int mode, unsigned int flags) { + unsigned int lflag = flags; + if (wiringPiDebug) + printf ("pinModeFlagsDevice: pin:%d mode:%d, flags: %u\n", pin, mode, flags) ; + + lflag &= ~(GPIOHANDLE_REQUEST_INPUT | GPIOHANDLE_REQUEST_OUTPUT); + switch(mode) { + default: + fprintf(stderr, "pinMode: invalid mode request (only input und output supported)\n"); + return; + case INPUT: + lflag |= GPIOHANDLE_REQUEST_INPUT; + break; + case OUTPUT: + lflag |= GPIOHANDLE_REQUEST_OUTPUT; + break; + } + if (GetChipFd()<0) { + return; // error + } + + 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); +} + +void pinModeDevice (int pin, int mode) { + pinModeFlagsDevice (pin, mode, cdflags[pin]); +} + void pinMode (int pin, int mode) { int fSel, shift, alt ; @@ -1595,18 +1667,27 @@ void pinMode (int pin, int mode) int origPin = pin ; if (wiringPiDebug) - printf ("pinMode: pin:%d mode:%d\n", pin, mode) ; + printf ("pinMode: pin:%d mode:%d\n", pin, mode) ; setupCheck ("pinMode") ; if ((pin & PI_GPIO_MASK) == 0) // On-board pin { - /**/ if (wiringPiMode == WPI_MODE_PINS) - pin = pinToGpio [pin] ; - else if (wiringPiMode == WPI_MODE_PHYS) - pin = physToGpio [pin] ; - else if (wiringPiMode != WPI_MODE_GPIO) - return ; + switch(wiringPiMode) { + default: //WPI_MODE_GPIO_SYS + fprintf(stderr, "pinMode: invalid mode\n"); + return; + case WPI_MODE_PINS: + pin = pinToGpio [pin]; + break; + case WPI_MODE_PHYS: + pin = physToGpio [pin]; + break; + case WPI_MODE_GPIO_DEVICE: + return pinModeDevice(pin, mode); + case WPI_MODE_GPIO: + break; + } if (wiringPiDebug) printf ("pinMode: bcm pin:%d mode:%d\n", pin, mode) ; @@ -1688,6 +1769,28 @@ void pinMode (int pin, int mode) * Control the internal pull-up/down resistors on a GPIO pin. ********************************************************************************* */ +void pullUpDnControlDevice (int pin, int pud) { + unsigned int flag = cdflags[pin]; + unsigned int biasflags = GPIOHANDLE_REQUEST_BIAS_DISABLE | GPIOHANDLE_REQUEST_BIAS_PULL_UP | GPIOHANDLE_REQUEST_BIAS_PULL_DOWN; + + flag &= ~biasflags; + switch (pud){ + case PUD_OFF: flag |= GPIOHANDLE_REQUEST_BIAS_DISABLE; break; + case PUD_UP: flag |= GPIOHANDLE_REQUEST_BIAS_PULL_UP; break; + case PUD_DOWN: flag |= GPIOHANDLE_REQUEST_BIAS_PULL_DOWN; break; + default: return ; /* An illegal value */ + } + + // reset input/output + if (cdflags[pin] & GPIOHANDLE_REQUEST_OUTPUT) { + pinModeFlagsDevice (pin, OUTPUT, flag); + } else if(cdflags[pin] & GPIOHANDLE_REQUEST_INPUT) { + pinModeFlagsDevice (pin, INPUT, flag); + } else { + cdflags[pin] = flag; // only store for later + } +} + void pullUpDnControl (int pin, int pud) { @@ -1697,13 +1800,21 @@ void pullUpDnControl (int pin, int pud) if ((pin & PI_GPIO_MASK) == 0) // On-Board Pin { - - /**/ if (wiringPiMode == WPI_MODE_PINS) - pin = pinToGpio [pin] ; - else if (wiringPiMode == WPI_MODE_PHYS) - pin = physToGpio [pin] ; - else if (wiringPiMode != WPI_MODE_GPIO) - return ; + switch(wiringPiMode) { + default: //WPI_MODE_GPIO_SYS + fprintf(stderr, "pinMode: invalid mode\n"); + return; + case WPI_MODE_PINS: + pin = pinToGpio [pin]; + break; + case WPI_MODE_PHYS: + pin = physToGpio [pin]; + break; + case WPI_MODE_GPIO_DEVICE: + return pullUpDnControlDevice(pin, pud); + case WPI_MODE_GPIO: + break; + } if (PI_MODEL_5 == RaspberryPiModel) { unsigned int pullbits = pads[1+pin] & RP1_INV_PUD_MASK; // remove bits @@ -1722,11 +1833,10 @@ void pullUpDnControl (int pin, int pud) unsigned int pullbits; unsigned int pull; - switch (pud) - { - case PUD_OFF: pull = 0; break; - case PUD_UP: pull = 1; break; - case PUD_DOWN: pull = 2; break; + switch (pud) { + case PUD_OFF: pull = 0; break; + case PUD_UP: pull = 1; break; + case PUD_DOWN: pull = 2; break; default: return ; /* An illegal value */ } @@ -1761,20 +1871,52 @@ void pullUpDnControl (int pin, int pud) ********************************************************************************* */ +int digitalReadDevice (int pin) { + struct gpiohandle_data data; + struct gpiohandle_request rq; + + 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 + } + ret = ioctl(rq.fd, GPIOHANDLE_GET_LINE_VALUES_IOCTL, &data); + if (ret) { + ReportDeviceError("get line values", pin, "digitalRead", ret); + return LOW; // error + } + close(rq.fd); + return data.values[0]; +} + + int digitalRead (int pin) { struct wiringPiNodeStruct *node = wiringPiNodes ; if ((pin & PI_GPIO_MASK) == 0) // On-Board Pin { - if (wiringPiMode == WPI_MODE_GPIO_SYS) - return LOW ; - else if (wiringPiMode == WPI_MODE_PINS) - pin = pinToGpio [pin] ; - else if (wiringPiMode == WPI_MODE_PHYS) - pin = physToGpio [pin] ; - else if (wiringPiMode != WPI_MODE_GPIO) - return LOW ; + switch(wiringPiMode) { + default: //WPI_MODE_GPIO_SYS + fprintf(stderr, "digitalRead: invalid mode\n"); + return LOW; + case WPI_MODE_PINS: + pin = pinToGpio [pin]; + break; + case WPI_MODE_PHYS: + pin = physToGpio [pin]; + break; + case WPI_MODE_GPIO_DEVICE: + return digitalReadDevice(pin); + case WPI_MODE_GPIO: + break; + } if (PI_MODEL_5 == RaspberryPiModel) { switch(gpio[2*pin] & RP1_STATUS_LEVEL_MASK) { @@ -1825,20 +1967,60 @@ 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 + } + 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 + } + close(rq.fd); + return; +} + void digitalWrite (int pin, int value) { struct wiringPiNodeStruct *node = wiringPiNodes ; if ((pin & PI_GPIO_MASK) == 0) // On-Board Pin { - if (wiringPiMode == WPI_MODE_GPIO_SYS) // Sys mode - return ; - else if (wiringPiMode == WPI_MODE_PINS) - pin = pinToGpio [pin] ; - else if (wiringPiMode == WPI_MODE_PHYS) - pin = physToGpio [pin] ; - else if (wiringPiMode != WPI_MODE_GPIO) - return ; + switch(wiringPiMode) { + default: //WPI_MODE_GPIO_SYS + fprintf(stderr, "digitalWrite: invalid mode\n"); + return; + case WPI_MODE_PINS: + pin = pinToGpio [pin]; + break; + case WPI_MODE_PHYS: + pin = physToGpio [pin]; + break; + case WPI_MODE_GPIO_DEVICE: + digitalWriteDevice(pin, value); + return; + case WPI_MODE_GPIO: + break; + } + if (PI_MODEL_5 == RaspberryPiModel) { if (value == LOW) { //printf("Set pin %d >>0x%08x<< to low\n", pin, 1< Date: Tue, 16 Apr 2024 18:55:53 +0200 Subject: [PATCH 02/16] new Version 3.3 for #219 --- VERSION | 2 +- version.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/VERSION b/VERSION index a3ec5a4..eb39e53 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -3.2 +3.3 diff --git a/version.h b/version.h index bbf3ef7..6f3b26e 100644 --- a/version.h +++ b/version.h @@ -1,3 +1,3 @@ -#define VERSION "3.2" +#define VERSION "3.3" #define VERSION_MAJOR 3 -#define VERSION_MINOR 2 +#define VERSION_MINOR 3 From ad6d821329912dc0f5b465b1a0c85997f06a3f91 Mon Sep 17 00:00:00 2001 From: mstroh76 Date: Sat, 20 Apr 2024 19:48:33 +0200 Subject: [PATCH 03/16] #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 From 734cebe8bfec099a9e62bc9c67945300dbe0e216 Mon Sep 17 00:00:00 2001 From: mstroh76 Date: Sun, 21 Apr 2024 17:59:46 +0200 Subject: [PATCH 04/16] #219 test1 --- wiringPi/test/wiringpi_test1_device.c | 83 +++++++++++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) create mode 100644 wiringPi/test/wiringpi_test1_device.c diff --git a/wiringPi/test/wiringpi_test1_device.c b/wiringPi/test/wiringpi_test1_device.c new file mode 100644 index 0000000..e8d6ce1 --- /dev/null +++ b/wiringPi/test/wiringpi_test1_device.c @@ -0,0 +1,83 @@ +// WiringPi test program: Kernel char device interface / sysfs successor +// Compile: gcc -Wall wiringpi_test1_device.c -o wiringpi_test1_device -lwiringPi + +#include +#include +#include +#include +#include +#include +#include + + +//const int GPIO = 24; //LED +const int GPIO = 19; +const int GPIOIN = 26; +const int ToggleValue = 4; + +void CheckGPIO(int out) { + int in = digitalRead(GPIOIN); + int read = digitalRead(GPIO); + + int pass = 0; + if (out==in && in==read) { + pass = 1; + } + printf("GPIO%d = %d (GPIO%d = %d) -> %s\n", GPIOIN, in, GPIO, read, pass ? "passed":"failed" ); +} + +void digitalWriteEx(int pin, int mode) { + digitalWrite(pin, mode); + printf("out = %d ", mode); + delayMicroseconds(5000); + CheckGPIO(mode); +} + +void pullUpDnControlEx (int pin ,int mode) { + pullUpDnControl (pin, mode); + int out = mode==PUD_UP ? 1:0; + printf("in = %4s ", mode==PUD_UP ? "up":"down"); + delayMicroseconds(5000); + CheckGPIO(out); +} + +int main (void) { + + printf("WiringPi GPIO test program (using GPIO%d (output) and GPIO%d (input) via sys)\n", GPIO, GPIOIN); + + if (wiringPiSetupSys() == -1) { + printf("wiringPiSetupGpioDevice failed\n\n"); + exit(EXIT_FAILURE); + } + pinMode(GPIOIN, INPUT); + pinMode(GPIO, OUTPUT); + + printf("toggle %d times ...\n", ToggleValue); + for (int loop=1; loop Date: Fri, 26 Apr 2024 17:28:02 +0200 Subject: [PATCH 05/16] #219 test2 --- wiringPi/test/wiringpi_test1_device.c | 8 ++-- wiringPi/test/wiringpi_test2_device.c | 80 +++++++++++++++++++++++++++++++++++ 2 files changed, 84 insertions(+), 4 deletions(-) create mode 100644 wiringPi/test/wiringpi_test2_device.c diff --git a/wiringPi/test/wiringpi_test1_device.c b/wiringPi/test/wiringpi_test1_device.c index e8d6ce1..189dd9f 100644 --- a/wiringPi/test/wiringpi_test1_device.c +++ b/wiringPi/test/wiringpi_test1_device.c @@ -10,7 +10,6 @@ #include -//const int GPIO = 24; //LED const int GPIO = 19; const int GPIOIN = 26; const int ToggleValue = 4; @@ -43,7 +42,8 @@ void pullUpDnControlEx (int pin ,int mode) { int main (void) { - printf("WiringPi GPIO test program (using GPIO%d (output) and GPIO%d (input) via sys)\n", GPIO, GPIOIN); + printf("WiringPi GPIO test program 1 (using GPIO%d (output) and GPIO%d (input) via sys)\n", GPIO, GPIOIN); + printf(" testing digitalWrite, digitalRead and pullUpDnControl\n"); if (wiringPiSetupSys() == -1) { printf("wiringPiSetupGpioDevice failed\n\n"); @@ -68,12 +68,12 @@ int main (void) { delayMicroseconds(3000000); pullUpDnControl (GPIOIN, PUD_OFF); - for (int loop=1; loop +#include +#include +#include +#include +#include +#include + + +const int GPIO = 19; +const int GPIOIN = 26; +const int ToggleValue = 4; + +void CheckGPIO(int out) { + int in = digitalRead(GPIOIN); + int read = digitalRead(GPIO); + + int pass = 0; + if (out==in && in==read) { + pass = 1; + } + printf("GPIO%d = %d (GPIO%d = %d) -> %s\n", GPIOIN, in, GPIO, read, pass ? "passed":"failed" ); +} + +void digitalWriteEx(int pin, int mode) { + digitalWrite(pin, mode); + printf("out = %d ", mode); + delayMicroseconds(5000); + CheckGPIO(mode); +} + +void pullUpDnControlEx (int pin ,int mode) { + pullUpDnControl (pin, mode); + int out = mode==PUD_UP ? 1:0; + printf("in = %4s ", mode==PUD_UP ? "up":"down"); + delayMicroseconds(5000); + CheckGPIO(out); +} + +int main (void) { + + printf("WiringPi GPIO test program 2 (using GPIO%d (output) and GPIO%d (input) via sys)\n", GPIO, GPIOIN); + printf(" testing pullUpDnControl and pinMode PM_OFF\n"); + + if (wiringPiSetupSys() == -1) { + printf("wiringPiSetupGpioDevice failed\n\n"); + exit(EXIT_FAILURE); + } + pinMode(GPIOIN, INPUT); + pinMode(GPIO, OUTPUT); + + printf("\nTest output\n"); + digitalWriteEx(GPIO, HIGH); + delayMicroseconds(600000); + digitalWriteEx(GPIO, LOW); + delayMicroseconds(600000); + + printf("\nTest output off with pull up\n"); + pinMode(GPIO, OUTPUT); + digitalWriteEx(GPIO, LOW); + pullUpDnControl (GPIO, PUD_UP); + pinMode(GPIO, PM_OFF); + delayMicroseconds(600000); + printf("out = off "); + CheckGPIO(HIGH); + delayMicroseconds(600000); + + printf("\nTest output off with pull down\n"); + pullUpDnControl (GPIO, PUD_DOWN); + pinMode(GPIO, PM_OFF); + delayMicroseconds(600000); + printf("out = off "); + CheckGPIO(LOW); + delayMicroseconds(600000); + + return(EXIT_SUCCESS); +} From 58fd2654a387fda7739f071fd86fb11fb21da545 Mon Sep 17 00:00:00 2001 From: mstroh76 Date: Fri, 26 Apr 2024 17:45:12 +0200 Subject: [PATCH 06/16] #219 report /dev/gpiochip support --- gpio/gpio.c | 8 ++++++-- wiringPi/wiringPi.h | 1 + 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/gpio/gpio.c b/gpio/gpio.c index 1e7ec59..fb2da2f 100644 --- a/gpio/gpio.c +++ b/gpio/gpio.c @@ -1363,7 +1363,7 @@ static void doVersion (char *argv []) piModelNames [model], piRevisionNames [rev], piMemorySize [mem], piMakerNames [maker], warranty ? "[Out of Warranty]" : "") ; // Check for device tree - printf ("System details:\n") ; + printf ("\nSystem details:\n") ; if (stat ("/proc/device-tree", &statBuf) == 0) { // We're on a devtree system ... printf (" * Device tree present.\n") ; } @@ -1394,9 +1394,13 @@ static void doVersion (char *argv []) } else { printf (" * Does not support basic user-level GPIO access via /dev/gpiomem.\n") ; if(0==bGlobalAccess) { - printf (" * root or sudo may be required for GPIO access.\n") ; + printf (" * root or sudo may be required for direct GPIO access.\n") ; } } + if (GetChipFd()>0) { + printf (" * Supports basic user-level GPIO access via /dev/gpiochip (slow).\n") ; + } + } diff --git a/wiringPi/wiringPi.h b/wiringPi/wiringPi.h index 029b6bb..81c4001 100644 --- a/wiringPi/wiringPi.h +++ b/wiringPi/wiringPi.h @@ -218,6 +218,7 @@ extern int wiringPiSetupGpio (void) ; extern int wiringPiSetupPhys (void) ; extern int wiringPiSetupGpioDevice(void) ; //Interface 3.3 +extern int GetChipFd (); extern void pinModeAlt (int pin, int mode) ; extern void pinMode (int pin, int mode) ; extern void pullUpDnControl (int pin, int pud) ; From d3a23725b8c4dbafb05f2ab5f78757f1440fc6db Mon Sep 17 00:00:00 2001 From: mstroh76 Date: Sat, 27 Apr 2024 18:19:46 +0200 Subject: [PATCH 07/16] #210 --- examples/speed.c | 11 +- gpio/gpio.1 | 72 +----------- gpio/gpio.c | 293 +++------------------------------------------- wiringPi/wiringPi.c | 19 ++- wiringPi/wiringPiLegacy.c | 63 ---------- 5 files changed, 40 insertions(+), 418 deletions(-) diff --git a/examples/speed.c b/examples/speed.c index 2cd2fe1..19b2b06 100644 --- a/examples/speed.c +++ b/examples/speed.c @@ -84,12 +84,19 @@ int main (void) pinMode (11, OUTPUT) ; speedTest (11, FAST_COUNT) ; -// Switch to SYS mode: +// Switch to SYS mode: -> character device ABI - system ("/usr/local/bin/gpio export 17 out") ; printf ("\n/sys/class/gpio method: (%8d iterations)\n", SLOW_COUNT) ; wiringPiSetupSys () ; speedTest (17, SLOW_COUNT) ; +// character device ABI + + printf ("\ncharacter device ABI method: (%8d iterations)\n", SLOW_COUNT) ; + wiringPiSetupGpioDevice () ; + pinMode (17, OUTPUT) ; + speedTest (17, SLOW_COUNT) ; + + return 0 ; } diff --git a/gpio/gpio.1 b/gpio/gpio.1 index b1be603..84bbbde 100644 --- a/gpio/gpio.1 +++ b/gpio/gpio.1 @@ -29,13 +29,6 @@ gpio \- Command-line access to Raspberry Pi's GPIO .B readall .PP .B gpio -.B unexportall/exports -.PP -.B gpio -.B export/edge/unexport -.B ... -.PP -.B gpio .B wfi .B ... .PP @@ -77,10 +70,6 @@ somewhat slow control of the GPIO pins. It can also control the IO's on the PiFace IO board and load the SPI and I2C kernel modules if required. -Additionally, it can be used to set the exports in the \fI/sys/class/gpio\fR -system directory to allow subsequent programs to use the \fR/sys/class/gpio\fR -interface without needing to be run as root. - .SH OPTIONS .TP @@ -90,15 +79,14 @@ Output the current version including the board revision of the Raspberry Pi. .TP .B \-g Use the BCM_GPIO pins numbers rather than wiringPi pin numbers. -\fINote:\fR The BCM_GPIO pin numbers are always used with the -export and edge commands. +.\" \fINote:\fR The BCM_GPIO pin numbers are always used with character device ABI. .TP .B \-1 Use the physical pin numbers rather than wiringPi pin numbers. \fINote:\fR that this applies to the P1 connector only. It is not possible to use pins on the Revision 2 P5 connector this way, and as with \-g the -BCM_GPIO pin numbers are always used with the export and edge commands. +.\" BCM_GPIO pin numbers are always used with character device ABI. .TP .B \-x extension @@ -191,47 +179,6 @@ pull-up, pull-down or tristate (off) controls. The ALT modes can also be set using \fIalt0\fR, \fIalt1\fR, ... \fIalt5\fR. .TP -.B unexportall -Un-Export all the GPIO pins in the /sys/class/gpio directory. - -.TP -.B exports -Print a list (if any) of all the exported GPIO pins and their current values. - -.TP -.B export -Export a GPIO pin in the \fI/sys/class/gpio\fR directory. Use like the -mode command above however only \fIin\fR, \fIout\fR, \fIhigh\fR and -\fRlow\fR are supported at this time. Note that the pin number is the -\fBBCM_GPIO\fR number and not the wiringPi number. The \fIhigh\fR and -\fIlow\fR commands pre-set the output value at the same time as the -export to output mode. - -Once a GPIO pin has been exported, the \fBgpio\fR program changes the -ownership of the \fI/sys/class/gpio/gpioX/value\fR and if present in -later kernels, the \fI/sys/class/gpio/gpioX/edge\fR pseudo files to -that of the user running the \fBgpio\fR program. This means that you -can have a small script of gpio exports to setup the gpio pins as your -program requires without the need to run anything as root, or with the -sudo command. - -.TP -.B edge -This exports a GPIO pin in the \fI/sys/class/gpio\fR directory, set -the direction to input and set the edge interrupt method to \fInone\fR, -\fIrising\fR, \fIfalling\fR or \fIboth\fR. Use like the export command -above and note that \fBBCM_GPIO\fR pin number is used not not wiringPi pin -numbering. - -Like the export commands above, ownership is set to that of the -calling user, allowing subsequent access from user programs without -requiring root/sudo. - -.TP -.B unexport -Un-Export a GPIO pin in the /sys/class/gpio directory. - -.TP .B wfi This set the given pin to the supplied interrupt mode: rising, falling or both then waits for the interrupt to happen. It's a non-busy wait, @@ -299,18 +246,10 @@ gpio mode 1 pwm # Set pin 1 to PWM mode .PP gpio pwm 1 512 # Set pin 1 to PWM value 512 - half brightness .PP -gpio export 17 out # Set GPIO Pin 17 to output -.PP -gpio export 0 in # Set GPIO Pin 0 (SDA0) to input. -.PP gpio -g read 0 # Read GPIO Pin 0 (SDA0) .SH "NOTES" -When using the \fIexport\fR, \fIedge\fR or \fIunexport\fR commands, the -pin numbers are \fBalways\fR native BCM_GPIO numbers and never wiringPi -pin numbers. - As of kernels 4.1.7, a user-level GPIO access mechanism is available, however wiringPi will not use this by default - because at this time there appears to be issues when trying to program the PWM or clock output @@ -326,13 +265,13 @@ in future releases once the /dev/gpiomem interface is fully operational. .SH "SEE ALSO" .LP -WiringPi's home page +WiringPi's development .IP https://github.com/WiringPi/WiringPi/ .SH AUTHOR -Gordon Henderson +Gordon Henderson and contributors .SH "REPORTING BUGS" @@ -340,7 +279,8 @@ Please report bugs to https://github.com/WiringPi/WiringPi/issues .SH COPYRIGHT -Copyright (c) 2012-2018 Gordon Henderson +Copyright (c) 2012-2024 Gordon Henderson and contributors +.brq This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. diff --git a/gpio/gpio.c b/gpio/gpio.c index fb2da2f..0e49560 100644 --- a/gpio/gpio.c +++ b/gpio/gpio.c @@ -72,8 +72,8 @@ char *usage = "Usage: gpio -v\n" " gpio ...\n" " gpio \n" " gpio readall\n" - " gpio unexportall/exports\n" - " gpio export/edge/unexport ...\n" +// " gpio unexportall/exports\n" +// " gpio export/edge/unexport ...\n" " gpio wfi \n" " gpio drive \n" " gpio pwm-bal/pwm-ms \n" @@ -89,15 +89,6 @@ char *usage = "Usage: gpio -v\n" " gpio gbw " ; // No trailing newline needed here. -int GPIOToSysFS_ExitonFail (const int pin, const char* name) { - int pinFS = GPIOToSysFS(pin); - if (pinFS<0) { - fprintf (stderr, "%s: invalid sysfs pin of bcm pin %d\n", name, pin) ; - exit (1) ; - } - return pinFS; -} - #ifdef NOT_FOR_NOW /* * decodePin: @@ -392,160 +383,23 @@ static void doI2Cdetect (UNU int argc, char *argv []) } +void SYSFS_DEPRECATED(const char *progName) { + fprintf(stderr, "%s: GPIO Sysfs Interface for Userspace is deprecated (https://www.kernel.org/doc/Documentation/gpio/sysfs.txt).\n Function is now useless and empty.\n\n", progName); +} + /* - * doExports: + * doExports: -> deprecated, removed * List all GPIO exports ********************************************************************************* */ -static void doExports (UNU int argc, UNU char *argv []) -{ - int fd ; - int pin, l, first ; - char fName [128] ; - char buf [16] ; - - for (first = 0, pin = 0 ; pin < 64 ; ++pin) // Crude, but effective - { - -// Try to read the direction - int pinFS = GPIOToSysFS(pin); - if (pinFS<0) { - continue; - } - sprintf (fName, "/sys/class/gpio/gpio%d/direction", pinFS) ; - if ((fd = open (fName, O_RDONLY)) == -1) - continue ; - - if (first == 0) - { - ++first ; - printf ("GPIO Pins exported:\n") ; - } - - if(pinFS==pin) { - printf ("%4d: ", pin) ; - } else { - printf ("%4d (%4d): ", pin, pinFS) ; - } - - if ((l = read (fd, buf, 16)) == 0) - sprintf (buf, "%s", "?") ; - - buf [l] = 0 ; - if ((buf [strlen (buf) - 1]) == '\n') - buf [strlen (buf) - 1] = 0 ; - - printf ("%-3s", buf) ; - - close (fd) ; - -// Try to Read the value - - sprintf (fName, "/sys/class/gpio/gpio%d/value", pinFS) ; - if ((fd = open (fName, O_RDONLY)) == -1) - { - printf ("No Value file (huh?)\n") ; - continue ; - } - - if ((l = read (fd, buf, 16)) == 0) - sprintf (buf, "%s", "?") ; - - buf [l] = 0 ; - if ((buf [strlen (buf) - 1]) == '\n') - buf [strlen (buf) - 1] = 0 ; - - printf (" %s", buf) ; - -// Read any edge trigger file - - sprintf (fName, "/sys/class/gpio/gpio%d/edge", pinFS) ; - if ((fd = open (fName, O_RDONLY)) == -1) - { - printf ("\n") ; - continue ; - } - - if ((l = read (fd, buf, 16)) == 0) - sprintf (buf, "%s", "?") ; - - buf [l] = 0 ; - if ((buf [strlen (buf) - 1]) == '\n') - buf [strlen (buf) - 1] = 0 ; - - printf (" %-8s\n", buf) ; - - close (fd) ; - } -} - - /* - * doExport: + * doExport: -> deprecated, removed * gpio export pin mode * This uses the /sys/class/gpio device interface. ********************************************************************************* */ -void doExport (int argc, char *argv []) -{ - FILE *fd ; - int pin ; - char *mode ; - char fName [128] ; - - if (argc != 4) - { - fprintf (stderr, "Usage: %s export pin mode\n", argv [0]) ; - exit (1) ; - } - - pin = atoi (argv [2]) ; - int pinFS = GPIOToSysFS_ExitonFail(pin, argv [0]); - mode = argv [3] ; - - if ((fd = fopen ("/sys/class/gpio/export", "w")) == NULL) - { - fprintf (stderr, "%s: Unable to open GPIO export interface: %s\n", argv [0], strerror (errno)) ; - exit (1) ; - } - - fprintf (fd, "%d\n", pinFS) ; - fclose (fd) ; - sprintf (fName, "/sys/class/gpio/gpio%d/direction", pinFS) ; - if ((fd = fopen (fName, "w")) == NULL) - { - fprintf (stderr, "%s: Unable to open GPIO direction interface for pin %d: %s\n", argv [0], pin, strerror (errno)) ; - exit (1) ; - } - - /**/ if ((strcasecmp (mode, "in") == 0) || (strcasecmp (mode, "input") == 0)) - fprintf (fd, "in\n") ; - else if ((strcasecmp (mode, "out") == 0) || (strcasecmp (mode, "output") == 0)) - fprintf (fd, "out\n") ; - else if ((strcasecmp (mode, "high") == 0) || (strcasecmp (mode, "up") == 0)) - fprintf (fd, "high\n") ; - else if ((strcasecmp (mode, "low") == 0) || (strcasecmp (mode, "down") == 0)) - fprintf (fd, "low\n") ; - else - { - fprintf (stderr, "%s: Invalid mode: %s. Should be in, out, high or low\n", argv [1], mode) ; - exit (1) ; - } - - fclose (fd) ; - -// Change ownership so the current user can actually use it - - sprintf (fName, "/sys/class/gpio/gpio%d/value", pinFS) ; - changeOwner (argv [0], fName) ; - - sprintf (fName, "/sys/class/gpio/gpio%d/edge", pinFS) ; - changeOwner (argv [0], fName) ; - -} - /* * doWfi: @@ -630,142 +484,29 @@ void doWfi (int argc, char *argv []) } - /* - * doEdge: + * doEdge: -> deprecated, removed * gpio edge pin mode * Easy access to changing the edge trigger on a GPIO pin * This uses the /sys/class/gpio device interface. ********************************************************************************* */ -void doEdge (int argc, char *argv []) -{ - FILE *fd ; - int pin ; - char *mode ; - char fName [128] ; - - if (argc != 4) - { - fprintf (stderr, "Usage: %s edge pin mode\n", argv [0]) ; - exit (1) ; - } - - pin = atoi (argv [2]) ; - int pinFS = GPIOToSysFS_ExitonFail(pin, argv [0]); - mode = argv [3] ; - -// Export the pin and set direction to input - - if ((fd = fopen ("/sys/class/gpio/export", "w")) == NULL) - { - fprintf (stderr, "%s: Unable to open GPIO export interface: %s\n", argv [0], strerror (errno)) ; - exit (1) ; - } - - fprintf (fd, "%d\n", pinFS) ; - fclose (fd) ; - - sprintf (fName, "/sys/class/gpio/gpio%d/direction", pinFS) ; - if ((fd = fopen (fName, "w")) == NULL) - { - fprintf (stderr, "%s: Unable to open GPIO direction interface for pin %d: %s\n", argv [0], pin, strerror (errno)) ; - exit (1) ; - } - - fprintf (fd, "in\n") ; - fclose (fd) ; - - sprintf (fName, "/sys/class/gpio/gpio%d/edge", pinFS) ; - if ((fd = fopen (fName, "w")) == NULL) - { - fprintf (stderr, "%s: Unable to open GPIO edge interface for pin %d: %s\n", argv [0], pin, strerror (errno)) ; - exit (1) ; - } - - /**/ if (strcasecmp (mode, "none") == 0) fprintf (fd, "none\n") ; - else if (strcasecmp (mode, "rising") == 0) fprintf (fd, "rising\n") ; - else if (strcasecmp (mode, "falling") == 0) fprintf (fd, "falling\n") ; - else if (strcasecmp (mode, "both") == 0) fprintf (fd, "both\n") ; - else - { - fprintf (stderr, "%s: Invalid mode: %s. Should be none, rising, falling or both\n", argv [1], mode) ; - exit (1) ; - } - -// Change ownership of the value and edge files, so the current user can actually use it! - - sprintf (fName, "/sys/class/gpio/gpio%d/value", pinFS) ; - changeOwner (argv [0], fName) ; - - sprintf (fName, "/sys/class/gpio/gpio%d/edge", pinFS) ; - changeOwner (argv [0], fName) ; - - fclose (fd) ; -} - - /* - * doUnexport: + * doUnexport: -> deprecated, removed * gpio unexport pin * This uses the /sys/class/gpio device interface. ********************************************************************************* */ -void doUnexport (int argc, char *argv []) -{ - FILE *fd ; - int pin ; - - if (argc != 3) - { - fprintf (stderr, "Usage: %s unexport pin\n", argv [0]) ; - exit (1) ; - } - - pin = atoi (argv [2]) ; - int pinFS = GPIOToSysFS_ExitonFail(pin, argv [0]); - - if ((fd = fopen ("/sys/class/gpio/unexport", "w")) == NULL) - { - fprintf (stderr, "%s: Unable to open GPIO export interface\n", argv [0]) ; - exit (1) ; - } - - fprintf (fd, "%d\n", pinFS) ; - fclose (fd) ; -} - - /* - * doUnexportAll: + * doUnexportAll: -> deprecated, removed * gpio unexportall * Un-Export all the GPIO pins. * This uses the /sys/class/gpio device interface. ********************************************************************************* */ -void doUnexportall (char *progName) -{ - FILE *fd ; - int pin ; - - for (pin = 0 ; pin < 63 ; ++pin) - { - int pinFS = GPIOToSysFS(pin); - if (pinFS>=0) { - if ((fd = fopen ("/sys/class/gpio/unexport", "w")) == NULL) - { - fprintf (stderr, "%s: Unable to open GPIO export interface\n", progName) ; - exit (1) ; - } - fprintf (fd, "%d\n", pinFS) ; - fclose (fd) ; - } - } -} - /* * doReset: @@ -1486,13 +1227,13 @@ int main (int argc, char *argv []) exit (EXIT_FAILURE) ; } -// Initial test for /sys/class/gpio operations: +// Initial test for /sys/class/gpio operations: - -> deprecated, empty but still there - /**/ if (strcasecmp (argv [1], "exports" ) == 0) { doExports (argc, argv) ; return 0 ; } - else if (strcasecmp (argv [1], "export" ) == 0) { doExport (argc, argv) ; return 0 ; } - else if (strcasecmp (argv [1], "edge" ) == 0) { doEdge (argc, argv) ; return 0 ; } - else if (strcasecmp (argv [1], "unexport" ) == 0) { doUnexport (argc, argv) ; return 0 ; } - else if (strcasecmp (argv [1], "unexportall") == 0) { doUnexportall (argv [0]) ; return 0 ; } + /**/ if (strcasecmp (argv [1], "exports" ) == 0) { SYSFS_DEPRECATED(argv[0]); return 0 ; } + else if (strcasecmp (argv [1], "export" ) == 0) { SYSFS_DEPRECATED(argv[0]); return 0 ; } + else if (strcasecmp (argv [1], "edge" ) == 0) { SYSFS_DEPRECATED(argv[0]); return 0 ; } + else if (strcasecmp (argv [1], "unexport" ) == 0) { SYSFS_DEPRECATED(argv[0]); return 0 ; } + else if (strcasecmp (argv [1], "unexportall") == 0) { SYSFS_DEPRECATED(argv[0]); return 0 ; } // Check for load command: diff --git a/wiringPi/wiringPi.c b/wiringPi/wiringPi.c index 2a05ce4..c083e80 100644 --- a/wiringPi/wiringPi.c +++ b/wiringPi/wiringPi.c @@ -395,9 +395,6 @@ int wiringPiReturnCodes = FALSE ; int wiringPiTryGpioMem = FALSE ; -// sysFds: -// Map a file descriptor from the /sys/class/gpio/gpioX/value - static unsigned int lineFlags [64] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -414,7 +411,7 @@ static int lineFds [64] = -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, } ; -static int sysFds [64] = +static int isrFds [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, @@ -2323,7 +2320,7 @@ int waitForInterrupt (int pin, int mS) else if (wiringPiMode == WPI_MODE_PHYS) pin = physToGpio [pin] ; - if ((fd = sysFds [pin]) == -1) + if ((fd = isrFds [pin]) == -1) return -2 ; // Setup poll structure @@ -2338,10 +2335,10 @@ int waitForInterrupt (int pin, int mS) } else { //if (polls.revents & POLLIN) if (wiringPiDebug) { - printf ("wiringPi: IRQ line %d received %d, fd=%d\n", pin, ret, sysFds [pin]) ; + printf ("wiringPi: IRQ line %d received %d, fd=%d\n", pin, ret, isrFds[pin]) ; } /* read event data */ - int readret = read(sysFds [pin], &evdata, sizeof(evdata)); + int readret = read(isrFds [pin], &evdata, sizeof(evdata)); if (readret == sizeof(evdata)) { if (wiringPiDebug) { printf ("wiringPi: IRQ data id: %d, timestamp: %lld\n", evdata.id, evdata.timestamp) ; @@ -2407,7 +2404,7 @@ int waitForInterruptInit (int pin, int mode) /* set event fd nonbloack read */ int fd_line = req.fd; - sysFds [pin] = fd_line; + isrFds [pin] = fd_line; int flags = fcntl(fd_line, F_GETFL); flags |= O_NONBLOCK; ret = fcntl(fd_line, F_SETFL, flags); @@ -2421,7 +2418,7 @@ int waitForInterruptInit (int pin, int mode) int waitForInterruptClose (int pin) { - if (sysFds[pin]>0) { + if (isrFds[pin]>0) { if (wiringPiDebug) { printf ("wiringPi: waitForInterruptClose close thread 0x%lX\n", (unsigned long)isrThreads[pin]) ; } @@ -2434,9 +2431,9 @@ int waitForInterruptClose (int pin) { fprintf (stderr, "wiringPi: waitForInterruptClose could not cancel thread\n"); } } - close(sysFds [pin]); + close(isrFds [pin]); } - sysFds [pin] = -1; + isrFds [pin] = -1; isrFunctions [pin] = NULL; /* -not closing so far - other isr may be using it - only close if no other is using - will code later diff --git a/wiringPi/wiringPiLegacy.c b/wiringPi/wiringPiLegacy.c index e14b45a..0ec4f8c 100644 --- a/wiringPi/wiringPiLegacy.c +++ b/wiringPi/wiringPiLegacy.c @@ -186,66 +186,3 @@ int piGpioLayoutLegacy (void) return gpioLayout ; } - - -/* - * wiringPiSetupSys: - * Must be called once at the start of your program execution. - * - * Initialisation (again), however this time we are using the /sys/class/gpio - * interface to the GPIO systems - slightly slower, but always usable as - * a non-root user, assuming the devices are already exported and setup correctly. - */ - -/* -int wiringPiSetupSys (void) -{ - char fName [128] ; - - if (wiringPiSetuped) - return 0 ; - - wiringPiSetuped = TRUE ; - - if (getenv (ENV_DEBUG) != NULL) - wiringPiDebug = TRUE ; - - if (getenv (ENV_CODES) != NULL) - wiringPiReturnCodes = TRUE ; - - if (wiringPiDebug) - printf ("wiringPi: wiringPiSetupSys called\n") ; - - int model, rev, mem, maker, overVolted ; - piBoardId (&model, &rev, &mem, &maker, &overVolted) ; - - if (piGpioLayout () == GPIO_LAYOUT_PI1_REV1) - { - pinToGpio = pinToGpioR1 ; - physToGpio = physToGpioR1 ; - } - else - { - pinToGpio = pinToGpioR2 ; - physToGpio = physToGpioR2 ; - } - -// Open and scan the directory, looking for exported GPIOs, and pre-open -// the 'value' interface to speed things up for later - - for (int pin = 0, maxpin=GetMaxPin() ; pin <= maxpin ; ++pin) - { - int pinFS = GPIOToSysFS(pin); - if (pinFS>=0) { - sprintf (fName, "/sys/class/gpio/gpio%d/value", pinFS) ; - sysFds [pin] = open (fName, O_RDWR) ; - } - } - - initialiseEpoch () ; - - wiringPiMode = WPI_MODE_GPIO_SYS ; - - return 0 ; -} -*/ From 199622c930b3e3ff190455c55dc01c4957b4a907 Mon Sep 17 00:00:00 2001 From: mstroh76 Date: Sat, 27 Apr 2024 18:22:14 +0200 Subject: [PATCH 08/16] #210 --- gpio/gpio.1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gpio/gpio.1 b/gpio/gpio.1 index 84bbbde..7b71596 100644 --- a/gpio/gpio.1 +++ b/gpio/gpio.1 @@ -280,7 +280,7 @@ Please report bugs to https://github.com/WiringPi/WiringPi/issues .SH COPYRIGHT Copyright (c) 2012-2024 Gordon Henderson and contributors -.brq +.br This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. From 86f47476b2a4780fd1152a7e06ff03a6d336bce0 Mon Sep 17 00:00:00 2001 From: mstroh76 Date: Sun, 28 Apr 2024 16:33:16 +0200 Subject: [PATCH 09/16] #212 wiringPiI2CReadBlockData and wiringPiI2CWriteBlockData --- wiringPi/wiringPiI2C.c | 27 ++++++++++++++++++++++++++- wiringPi/wiringPiI2C.h | 4 ++++ 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/wiringPi/wiringPiI2C.c b/wiringPi/wiringPiI2C.c index 3fa787d..51f92dd 100644 --- a/wiringPi/wiringPiI2C.c +++ b/wiringPi/wiringPiI2C.c @@ -47,7 +47,6 @@ #include #include -#include #include #include #include @@ -154,6 +153,21 @@ int wiringPiI2CReadReg16 (int fd, int reg) return data.word & 0xFFFF ; } +int wiringPiI2CReadBlockData (int fd, int reg, uint8_t size, uint8_t *values) +{ + union i2c_smbus_data data; + + if (size>I2C_SMBUS_BLOCK_MAX) { + size = I2C_SMBUS_BLOCK_MAX; + } + data.block[0] = size; + int result = i2c_smbus_access (fd, I2C_SMBUS_READ, reg, I2C_SMBUS_I2C_BLOCK_DATA, &data); + if (result<0) { + return result; + } + memcpy(values, &data.block[1], size); + return data.block[0]; +} /* * wiringPiI2CWrite: @@ -189,6 +203,17 @@ int wiringPiI2CWriteReg16 (int fd, int reg, int value) return i2c_smbus_access (fd, I2C_SMBUS_WRITE, reg, I2C_SMBUS_WORD_DATA, &data) ; } +int wiringPiI2CWriteBlockData (int fd, int reg, uint8_t size, const uint8_t *values) +{ + union i2c_smbus_data data; + + if (size>I2C_SMBUS_BLOCK_MAX) { + size = I2C_SMBUS_BLOCK_MAX; + } + data.block[0] = size; + memcpy(&data.block[1], values, size); + return i2c_smbus_access (fd, I2C_SMBUS_WRITE, reg, I2C_SMBUS_BLOCK_DATA, &data) ; +} /* * wiringPiI2CSetupInterface: diff --git a/wiringPi/wiringPiI2C.h b/wiringPi/wiringPiI2C.h index 73f031c..5734bdb 100644 --- a/wiringPi/wiringPiI2C.h +++ b/wiringPi/wiringPiI2C.h @@ -22,6 +22,8 @@ *********************************************************************** */ +#include + #ifdef __cplusplus extern "C" { #endif @@ -29,10 +31,12 @@ extern "C" { extern int wiringPiI2CRead (int fd) ; extern int wiringPiI2CReadReg8 (int fd, int reg) ; extern int wiringPiI2CReadReg16 (int fd, int reg) ; +extern int wiringPiI2CReadBlockData (int fd, int reg, uint8_t size, uint8_t *values); extern int wiringPiI2CWrite (int fd, int data) ; extern int wiringPiI2CWriteReg8 (int fd, int reg, int data) ; extern int wiringPiI2CWriteReg16 (int fd, int reg, int data) ; +extern int wiringPiI2CWriteBlockData (int fd, int reg, uint8_t size, const uint8_t *values); extern int wiringPiI2CSetupInterface (const char *device, int devId) ; extern int wiringPiI2CSetup (const int devId) ; From e728c9dfa3586b7c49aaf62740f442e2da9e6130 Mon Sep 17 00:00:00 2001 From: mstroh76 Date: Sun, 28 Apr 2024 17:35:53 +0200 Subject: [PATCH 10/16] #212 wiringPiI2CRawWrite and wiringPiI2CRawRead --- wiringPi/wiringPiI2C.c | 15 +++++++++++++-- wiringPi/wiringPiI2C.h | 6 ++++-- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/wiringPi/wiringPiI2C.c b/wiringPi/wiringPiI2C.c index 51f92dd..0bd166a 100644 --- a/wiringPi/wiringPiI2C.c +++ b/wiringPi/wiringPiI2C.c @@ -47,6 +47,7 @@ #include #include +#include #include #include #include @@ -153,7 +154,7 @@ int wiringPiI2CReadReg16 (int fd, int reg) return data.word & 0xFFFF ; } -int wiringPiI2CReadBlockData (int fd, int reg, uint8_t size, uint8_t *values) +int wiringPiI2CReadBlockData (int fd, int reg, uint8_t *values, uint8_t size) { union i2c_smbus_data data; @@ -169,6 +170,11 @@ int wiringPiI2CReadBlockData (int fd, int reg, uint8_t size, uint8_t *values) return data.block[0]; } +int wiringPiI2CRawRead (int fd, uint8_t *values, uint8_t size) +{ + return(read(fd, values, size)); +} + /* * wiringPiI2CWrite: * Simple device write @@ -203,7 +209,7 @@ int wiringPiI2CWriteReg16 (int fd, int reg, int value) return i2c_smbus_access (fd, I2C_SMBUS_WRITE, reg, I2C_SMBUS_WORD_DATA, &data) ; } -int wiringPiI2CWriteBlockData (int fd, int reg, uint8_t size, const uint8_t *values) +int wiringPiI2CWriteBlockData (int fd, int reg, const uint8_t *values, uint8_t size) { union i2c_smbus_data data; @@ -215,6 +221,11 @@ int wiringPiI2CWriteBlockData (int fd, int reg, uint8_t size, const uint8_t *val return i2c_smbus_access (fd, I2C_SMBUS_WRITE, reg, I2C_SMBUS_BLOCK_DATA, &data) ; } +int wiringPiI2CRawWrite (int fd, const uint8_t *values, uint8_t size) +{ + return(write(fd, values, size)); +} + /* * wiringPiI2CSetupInterface: * Undocumented access to set the interface explicitly - might be used diff --git a/wiringPi/wiringPiI2C.h b/wiringPi/wiringPiI2C.h index 5734bdb..d9660b9 100644 --- a/wiringPi/wiringPiI2C.h +++ b/wiringPi/wiringPiI2C.h @@ -31,12 +31,14 @@ extern "C" { extern int wiringPiI2CRead (int fd) ; extern int wiringPiI2CReadReg8 (int fd, int reg) ; extern int wiringPiI2CReadReg16 (int fd, int reg) ; -extern int wiringPiI2CReadBlockData (int fd, int reg, uint8_t size, uint8_t *values); +extern int wiringPiI2CReadBlockData (int fd, int reg, uint8_t *values, uint8_t size); //Interface 3.3 +extern int wiringPiI2CRawRead (int fd, uint8_t *values, uint8_t size); //Interface 3.3 extern int wiringPiI2CWrite (int fd, int data) ; extern int wiringPiI2CWriteReg8 (int fd, int reg, int data) ; extern int wiringPiI2CWriteReg16 (int fd, int reg, int data) ; -extern int wiringPiI2CWriteBlockData (int fd, int reg, uint8_t size, const uint8_t *values); +extern int wiringPiI2CWriteBlockData (int fd, int reg, const uint8_t *values, uint8_t size); //Interface 3.3 +extern int wiringPiI2CRawWrite (int fd, const uint8_t *values, uint8_t size); //Interface 3.3 extern int wiringPiI2CSetupInterface (const char *device, int devId) ; extern int wiringPiI2CSetup (const int devId) ; From e20bda7a121cf76dd1b12e498c6113c56d0d58cb Mon Sep 17 00:00:00 2001 From: mstroh76 Date: Sun, 28 Apr 2024 17:40:19 +0200 Subject: [PATCH 11/16] #210 --- wiringPi/wiringPi.c | 30 ------------------------------ wiringPi/wiringPi.h | 2 -- 2 files changed, 32 deletions(-) diff --git a/wiringPi/wiringPi.c b/wiringPi/wiringPi.c index c083e80..ae98547 100644 --- a/wiringPi/wiringPi.c +++ b/wiringPi/wiringPi.c @@ -544,36 +544,6 @@ static int physToGpioR2 [64] = -1, -1, } ; -const int _5v=-1; -const int _0v=-1; -const int _3v=-1; - - -static int physToSysGPIOPi5 [41] = -{ - -1, // 0 - _3v, _5v, // 1, 2 - 401, _5v, - 402, _0v, - 403, 413, - _0v, 414, - 416, 417, - 426, _0v, - 421, 422, - _3v, 423, - 409, _0v, - 408, 424, - 410, 407, - _0v, 406, - 399, 400, - 404, _0v, - 405, 411, - 412, _0v, - 418, 415, - 425, 419, - _0v, 420, //39, 40 -} ; - int piBoard() { if (RaspberryPiModel<0) { //need to detect pi model diff --git a/wiringPi/wiringPi.h b/wiringPi/wiringPi.h index 81c4001..195ac36 100644 --- a/wiringPi/wiringPi.h +++ b/wiringPi/wiringPi.h @@ -207,8 +207,6 @@ extern int wiringPiFailure (int fatal, const char *message, ...) ; extern struct wiringPiNodeStruct *wiringPiFindNode (int pin) ; extern struct wiringPiNodeStruct *wiringPiNewNode (int pinBase, int numPins) ; -extern int GPIOToSysFS(const int pin) ; - extern void wiringPiVersion (int *major, int *minor) ; extern int wiringPiGlobalMemoryAccess(void); //Interface 3.3 extern int wiringPiUserLevelAccess (void) ; From f3415b593cba31043906c0838a4fb8b28627a144 Mon Sep 17 00:00:00 2001 From: mstroh76 Date: Wed, 1 May 2024 20:28:52 +0200 Subject: [PATCH 12/16] #225 --- wiringPi/wiringPi.c | 66 +++++++++++++++++++++++++++++++++++++++++++---------- wiringPi/wiringPi.h | 25 +++++++++++++------- 2 files changed, 71 insertions(+), 20 deletions(-) diff --git a/wiringPi/wiringPi.c b/wiringPi/wiringPi.c index ae98547..f3f8020 100644 --- a/wiringPi/wiringPi.c +++ b/wiringPi/wiringPi.c @@ -1689,9 +1689,15 @@ void pinMode (int pin, int mode) case WPI_MODE_PHYS: pin = physToGpio [pin]; break; - case WPI_MODE_GPIO_DEVICE: + case WPI_MODE_GPIO_DEVICE_BCM: pinModeDevice(pin, mode); return; + case WPI_MODE_GPIO_DEVICE_WPI: + pinModeDevice(pinToGpio[pin], mode); + return; + case WPI_MODE_GPIO_DEVICE_PHYS: + pinModeDevice(physToGpio[pin], mode); + return; case WPI_MODE_GPIO: break; } @@ -1817,8 +1823,12 @@ void pullUpDnControl (int pin, int pud) case WPI_MODE_PHYS: pin = physToGpio [pin]; break; - case WPI_MODE_GPIO_DEVICE: + case WPI_MODE_GPIO_DEVICE_BCM: return pullUpDnControlDevice(pin, pud); + case WPI_MODE_GPIO_DEVICE_WPI: + return pullUpDnControlDevice(pinToGpio[pin], pud); + case WPI_MODE_GPIO_DEVICE_PHYS: + return pullUpDnControlDevice(physToGpio[pin], pud); case WPI_MODE_GPIO: break; } @@ -1915,8 +1925,12 @@ int digitalRead (int pin) case WPI_MODE_PHYS: pin = physToGpio [pin]; break; - case WPI_MODE_GPIO_DEVICE: + case WPI_MODE_GPIO_DEVICE_BCM: return digitalReadDevice(pin); + case WPI_MODE_GPIO_DEVICE_WPI: + return digitalReadDevice(pinToGpio[pin]); + case WPI_MODE_GPIO_DEVICE_PHYS: + return digitalReadDevice(physToGpio[pin]); case WPI_MODE_GPIO: break; } @@ -2011,9 +2025,15 @@ void digitalWrite (int pin, int value) case WPI_MODE_PHYS: pin = physToGpio [pin]; break; - case WPI_MODE_GPIO_DEVICE: + case WPI_MODE_GPIO_DEVICE_BCM: digitalWriteDevice(pin, value); return; + case WPI_MODE_GPIO_DEVICE_WPI: + digitalWriteDevice(pinToGpio[pin], value); + return; + case WPI_MODE_GPIO_DEVICE_PHYS: + digitalWriteDevice(physToGpio[pin], value); + return; case WPI_MODE_GPIO: break; } @@ -2933,7 +2953,6 @@ int wiringPiSetup (void) _wiringPiPads = pads ; _wiringPiTimer = timer ; _wiringPiRio = NULL ; - } else { unsigned int MMAP_size = (usingGpioMem) ? gpiomem_RP1_Size : pciemem_RP1_Size; GPIO_PADS = (RP1_PADS0_Addr-RP1_IO0_Addr) ; @@ -3024,13 +3043,24 @@ int wiringPiSetupPhys (void) return 0 ; } +int wiringPiSetupPinType (enum WPIPinType pinType) { + if (wiringPiDebug) + printf ("wiringPi: wiringPiSetupPinType(%d) called\n", (int) pinType) ; + switch (pinType) { + case WPI_PIN_BCM: return wiringPiSetupGpio(); + case WPI_PIN_WPI: return wiringPiSetup(); + case WPI_PIN_PHYS: return wiringPiSetupPhys(); + default: return -1; + } +} -int wiringPiSetupGpioDevice (void) { + +int wiringPiSetupGpioDevice (enum WPIPinType pinType) { if (wiringPiSetuped) return 0 ; - if (wiringPiDebug) - printf ("wiringPi: wiringPiSetupGpioDevice called\n") ; - + if (wiringPiDebug) { + printf ("wiringPi: wiringPiSetupGpioDevice(%d) called\n", (int)pinType) ; + } if (getenv (ENV_DEBUG) != NULL) wiringPiDebug = TRUE ; @@ -3042,7 +3072,6 @@ int wiringPiSetupGpioDevice (void) { } wiringPiSetuped = TRUE ; - // not used or needed but still assigned if (piGpioLayout () == GPIO_LAYOUT_PI1_REV1){ pinToGpio = pinToGpioR1 ; physToGpio = physToGpioR1 ; @@ -3053,7 +3082,20 @@ int wiringPiSetupGpioDevice (void) { initialiseEpoch () ; - wiringPiMode = WPI_MODE_GPIO_DEVICE ; + switch (pinType) { + case WPI_PIN_BCM: + wiringPiMode = WPI_MODE_GPIO_DEVICE_BCM; + break; + case WPI_PIN_WPI: + wiringPiMode = WPI_MODE_GPIO_DEVICE_WPI; + break; + case WPI_PIN_PHYS: + wiringPiMode = WPI_MODE_GPIO_DEVICE_PHYS; + break; + default: + wiringPiSetuped = FALSE; + return -1; + } return 0 ; } @@ -3072,5 +3114,5 @@ int wiringPiSetupSys (void) return 0 ; if (wiringPiDebug) printf ("wiringPi: wiringPiSetupSys called\n") ; - return wiringPiSetupGpioDevice(); + return wiringPiSetupGpioDevice(WPI_PIN_BCM); } diff --git a/wiringPi/wiringPi.h b/wiringPi/wiringPi.h index 195ac36..f90b582 100644 --- a/wiringPi/wiringPi.h +++ b/wiringPi/wiringPi.h @@ -46,12 +46,14 @@ // wiringPi modes -#define WPI_MODE_PINS 0 -#define WPI_MODE_GPIO 1 -#define WPI_MODE_GPIO_SYS 2 // deprecated since 3.2 -#define WPI_MODE_PHYS 3 -#define WPI_MODE_PIFACE 4 -#define WPI_MODE_GPIO_DEVICE 5 // BCM numbers like WPI_MODE_GPIO +#define WPI_MODE_PINS 0 +#define WPI_MODE_GPIO 1 +#define WPI_MODE_GPIO_SYS 2 // deprecated since 3.2 +#define WPI_MODE_PHYS 3 +#define WPI_MODE_PIFACE 4 +#define WPI_MODE_GPIO_DEVICE_BCM 5 // BCM pin numbers like WPI_MODE_GPIO +#define WPI_MODE_GPIO_DEVICE_WPI 6 // WiringPi pin numbers like WPI_MODE_PINS +#define WPI_MODE_GPIO_DEVICE_PHYS 7 // Physic pin numbers like WPI_MODE_PHYS #define WPI_MODE_UNINITIALISED -1 // Pin modes @@ -207,14 +209,21 @@ extern int wiringPiFailure (int fatal, const char *message, ...) ; extern struct wiringPiNodeStruct *wiringPiFindNode (int pin) ; extern struct wiringPiNodeStruct *wiringPiNewNode (int pinBase, int numPins) ; +enum WPIPinType { + WPI_PIN_BCM = 1, + WPI_PIN_WPI, + WPI_PIN_PHYS, +}; + extern void wiringPiVersion (int *major, int *minor) ; -extern int wiringPiGlobalMemoryAccess(void); //Interface 3.3 +extern int wiringPiGlobalMemoryAccess(void); //Interface V3.3 extern int wiringPiUserLevelAccess (void) ; extern int wiringPiSetup (void) ; extern int wiringPiSetupSys (void) ; extern int wiringPiSetupGpio (void) ; extern int wiringPiSetupPhys (void) ; -extern int wiringPiSetupGpioDevice(void) ; //Interface 3.3 +extern int wiringPiSetupPinType (enum WPIPinType pinType); //Interface V3.3 +extern int wiringPiSetupGpioDevice(enum WPIPinType pinType); //Interface V3.3 extern int GetChipFd (); extern void pinModeAlt (int pin, int mode) ; From 4eea4634dddaaeb686ff96f184b08905ca5e2a5b Mon Sep 17 00:00:00 2001 From: mstroh76 Date: Wed, 1 May 2024 20:31:21 +0200 Subject: [PATCH 13/16] #210 --- wiringPi/wiringPi.c | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/wiringPi/wiringPi.c b/wiringPi/wiringPi.c index f3f8020..1d802bd 100644 --- a/wiringPi/wiringPi.c +++ b/wiringPi/wiringPi.c @@ -553,21 +553,6 @@ int piBoard() { return RaspberryPiModel<0 ? 0 : 1; } -int GPIOToSysFS(const int pin) { - int sysfspin = pin; - piBoard(); - if (PI_MODEL_5 == RaspberryPiModel) { - sysfspin = pin + 399; - if (sysfspin<399 || sysfspin>426) { // only 399-426 supported, 40-pin GPIO header - sysfspin = -1; - } - } - if (wiringPiDebug) - printf ("GPIOToSysFS: translate bcm gpio %d to sysfs gpio %d\n", pin, sysfspin) ; - - return sysfspin; -} - int GetMaxPin() { return PI_MODEL_5 == RaspberryPiModel ? 27 : 63; } From 05c84ad7a383a9ed43a42534f7ab673ab736e39c Mon Sep 17 00:00:00 2001 From: mstroh76 Date: Wed, 1 May 2024 20:57:08 +0200 Subject: [PATCH 14/16] #225 unit test --- wiringPi/test/wiringpi_test2_device.c | 2 +- wiringPi/test/wiringpi_test3_device.c | 80 +++++++++++++++++++++++++++++++++++ wiringPi/test/wiringpi_test4_device.c | 80 +++++++++++++++++++++++++++++++++++ 3 files changed, 161 insertions(+), 1 deletion(-) create mode 100644 wiringPi/test/wiringpi_test3_device.c create mode 100644 wiringPi/test/wiringpi_test4_device.c diff --git a/wiringPi/test/wiringpi_test2_device.c b/wiringPi/test/wiringpi_test2_device.c index 2746a6e..5edf526 100644 --- a/wiringPi/test/wiringpi_test2_device.c +++ b/wiringPi/test/wiringpi_test2_device.c @@ -46,7 +46,7 @@ int main (void) { printf(" testing pullUpDnControl and pinMode PM_OFF\n"); if (wiringPiSetupSys() == -1) { - printf("wiringPiSetupGpioDevice failed\n\n"); + printf("wiringPiSetupSys failed\n\n"); exit(EXIT_FAILURE); } pinMode(GPIOIN, INPUT); diff --git a/wiringPi/test/wiringpi_test3_device.c b/wiringPi/test/wiringpi_test3_device.c new file mode 100644 index 0000000..362ae68 --- /dev/null +++ b/wiringPi/test/wiringpi_test3_device.c @@ -0,0 +1,80 @@ +// WiringPi test program: Kernel char device interface / sysfs successor +// Compile: gcc -Wall wiringpi_test3_device.c -o wiringpi_test3_device -lwiringPi + +#include +#include +#include +#include +#include +#include +#include + + +const int GPIO = 24; //BCM 19 +const int GPIOIN = 25; //BCM 26; +const int ToggleValue = 4; + +void CheckGPIO(int out) { + int in = digitalRead(GPIOIN); + int read = digitalRead(GPIO); + + int pass = 0; + if (out==in && in==read) { + pass = 1; + } + printf("GPIO%d = %d (GPIO%d = %d) -> %s\n", GPIOIN, in, GPIO, read, pass ? "passed":"failed" ); +} + +void digitalWriteEx(int pin, int mode) { + digitalWrite(pin, mode); + printf("out = %d ", mode); + delayMicroseconds(5000); + CheckGPIO(mode); +} + +void pullUpDnControlEx (int pin ,int mode) { + pullUpDnControl (pin, mode); + int out = mode==PUD_UP ? 1:0; + printf("in = %4s ", mode==PUD_UP ? "up":"down"); + delayMicroseconds(5000); + CheckGPIO(out); +} + +int main (void) { + + printf("WiringPi GPIO test program 2 (using WiringPi GPIO%d (output) and GPIO%d (input) via GPIO device)\n", GPIO, GPIOIN); + printf(" testing pullUpDnControl and pinMode PM_OFF\n"); + + if (wiringPiSetupGpioDevice(WPI_PIN_WPI) == -1) { + printf("wiringPiSetupGpioDevice failed\n\n"); + exit(EXIT_FAILURE); + } + pinMode(GPIOIN, INPUT); + pinMode(GPIO, OUTPUT); + + printf("\nTest output\n"); + digitalWriteEx(GPIO, HIGH); + delayMicroseconds(600000); + digitalWriteEx(GPIO, LOW); + delayMicroseconds(600000); + + printf("\nTest output off with pull up\n"); + pinMode(GPIO, OUTPUT); + digitalWriteEx(GPIO, LOW); + pullUpDnControl (GPIO, PUD_UP); + pinMode(GPIO, PM_OFF); + delayMicroseconds(600000); + printf("out = off "); + CheckGPIO(HIGH); + delayMicroseconds(600000); + + printf("\nTest output off with pull down\n"); + pullUpDnControl (GPIO, PUD_DOWN); + pinMode(GPIO, PM_OFF); + delayMicroseconds(600000); + printf("out = off "); + CheckGPIO(LOW); + delayMicroseconds(600000); + + return(EXIT_SUCCESS); +} diff --git a/wiringPi/test/wiringpi_test4_device.c b/wiringPi/test/wiringpi_test4_device.c new file mode 100644 index 0000000..f336212 --- /dev/null +++ b/wiringPi/test/wiringpi_test4_device.c @@ -0,0 +1,80 @@ +// WiringPi test program: Kernel char device interface / sysfs successor +// Compile: gcc -Wall wiringpi_test4_device.c -o wiringpi_test4_device -lwiringPi + +#include +#include +#include +#include +#include +#include +#include + + +const int GPIO = 35; //BCM 19 +const int GPIOIN = 37; //BCM 26; +const int ToggleValue = 4; + +void CheckGPIO(int out) { + int in = digitalRead(GPIOIN); + int read = digitalRead(GPIO); + + int pass = 0; + if (out==in && in==read) { + pass = 1; + } + printf("GPIO%d = %d (GPIO%d = %d) -> %s\n", GPIOIN, in, GPIO, read, pass ? "passed":"failed" ); +} + +void digitalWriteEx(int pin, int mode) { + digitalWrite(pin, mode); + printf("out = %d ", mode); + delayMicroseconds(5000); + CheckGPIO(mode); +} + +void pullUpDnControlEx (int pin ,int mode) { + pullUpDnControl (pin, mode); + int out = mode==PUD_UP ? 1:0; + printf("in = %4s ", mode==PUD_UP ? "up":"down"); + delayMicroseconds(5000); + CheckGPIO(out); +} + +int main (void) { + + printf("WiringPi GPIO test program 2 (using physical GPIO%d (output) and GPIO%d (input) via GPIO device)\n", GPIO, GPIOIN); + printf(" testing pullUpDnControl and pinMode PM_OFF\n"); + + if (wiringPiSetupGpioDevice(WPI_PIN_PHYS) == -1) { + printf("wiringPiSetupGpioDevice failed\n\n"); + exit(EXIT_FAILURE); + } + pinMode(GPIOIN, INPUT); + pinMode(GPIO, OUTPUT); + + printf("\nTest output\n"); + digitalWriteEx(GPIO, HIGH); + delayMicroseconds(600000); + digitalWriteEx(GPIO, LOW); + delayMicroseconds(600000); + + printf("\nTest output off with pull up\n"); + pinMode(GPIO, OUTPUT); + digitalWriteEx(GPIO, LOW); + pullUpDnControl (GPIO, PUD_UP); + pinMode(GPIO, PM_OFF); + delayMicroseconds(600000); + printf("out = off "); + CheckGPIO(HIGH); + delayMicroseconds(600000); + + printf("\nTest output off with pull down\n"); + pullUpDnControl (GPIO, PUD_DOWN); + pinMode(GPIO, PM_OFF); + delayMicroseconds(600000); + printf("out = off "); + CheckGPIO(LOW); + delayMicroseconds(600000); + + return(EXIT_SUCCESS); +} From 23b7251a2dc71f8c823340895c54ab6530e33f41 Mon Sep 17 00:00:00 2001 From: mstroh76 Date: Fri, 3 May 2024 14:36:09 +0200 Subject: [PATCH 15/16] #227 --- gpio/gpio.c | 2 +- wiringPi/wiringPi.c | 8 ++++---- wiringPi/wiringPi.h | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/gpio/gpio.c b/gpio/gpio.c index 0e49560..fae1b79 100644 --- a/gpio/gpio.c +++ b/gpio/gpio.c @@ -1138,7 +1138,7 @@ static void doVersion (char *argv []) printf (" * root or sudo may be required for direct GPIO access.\n") ; } } - if (GetChipFd()>0) { + if (wiringPiGpioDeviceGetFd()>0) { printf (" * Supports basic user-level GPIO access via /dev/gpiochip (slow).\n") ; } diff --git a/wiringPi/wiringPi.c b/wiringPi/wiringPi.c index 1d802bd..7d7b503 100644 --- a/wiringPi/wiringPi.c +++ b/wiringPi/wiringPi.c @@ -1503,7 +1503,7 @@ void pinEnableED01Pi (int pin) const char DEV_GPIO_PI[] ="/dev/gpiochip0"; const char DEV_GPIO_PI5[]="/dev/gpiochip4"; -int GetChipFd() { +int wiringPiGpioDeviceGetFd() { if (chipFd<0) { piBoard(); const char* gpiochip = PI_MODEL_5 == RaspberryPiModel ? DEV_GPIO_PI5 : DEV_GPIO_PI; @@ -1540,7 +1540,7 @@ int requestLine(int pin, unsigned int lineRequestFlags) { } //requested line - if (GetChipFd()<0) { + if (wiringPiGpioDeviceGetFd()<0) { return -1; // error } rq.lineoffsets[0] = pin; @@ -2338,7 +2338,7 @@ int waitForInterruptInit (int pin, int mode) /* open gpio */ sleep(1); - if (GetChipFd()<0) { + if (wiringPiGpioDeviceGetFd()<0) { return -1; } @@ -3052,7 +3052,7 @@ int wiringPiSetupGpioDevice (enum WPIPinType pinType) { if (getenv (ENV_CODES) != NULL) wiringPiReturnCodes = TRUE ; - if (GetChipFd()<0) { + if (wiringPiGpioDeviceGetFd()<0) { return -1; } wiringPiSetuped = TRUE ; diff --git a/wiringPi/wiringPi.h b/wiringPi/wiringPi.h index f90b582..9bd749f 100644 --- a/wiringPi/wiringPi.h +++ b/wiringPi/wiringPi.h @@ -216,7 +216,7 @@ enum WPIPinType { }; extern void wiringPiVersion (int *major, int *minor) ; -extern int wiringPiGlobalMemoryAccess(void); //Interface V3.3 +extern int wiringPiGlobalMemoryAccess(void); //Interface V3.3 extern int wiringPiUserLevelAccess (void) ; extern int wiringPiSetup (void) ; extern int wiringPiSetupSys (void) ; @@ -225,7 +225,7 @@ extern int wiringPiSetupPhys (void) ; extern int wiringPiSetupPinType (enum WPIPinType pinType); //Interface V3.3 extern int wiringPiSetupGpioDevice(enum WPIPinType pinType); //Interface V3.3 -extern int GetChipFd (); +extern int wiringPiGpioDeviceGetFd(); //Interface V3.3 extern void pinModeAlt (int pin, int mode) ; extern void pinMode (int pin, int mode) ; extern void pullUpDnControl (int pin, int pud) ; From 9044333c75fce395d32b814d58ab8344ef821398 Mon Sep 17 00:00:00 2001 From: mstroh76 Date: Fri, 3 May 2024 20:29:43 +0200 Subject: [PATCH 16/16] #231 --- wiringPi/wiringPi.c | 70 ++++++++++++++++++++++++++--------------------------- 1 file changed, 34 insertions(+), 36 deletions(-) diff --git a/wiringPi/wiringPi.c b/wiringPi/wiringPi.c index 7d7b503..ec63b6f 100644 --- a/wiringPi/wiringPi.c +++ b/wiringPi/wiringPi.c @@ -1110,6 +1110,37 @@ void piBoardId (int *model, int *rev, int *mem, int *maker, int *warranty) } RaspberryPiModel = *model; + + switch (RaspberryPiModel){ + case PI_MODEL_A: + case PI_MODEL_B: + case PI_MODEL_AP: + case PI_MODEL_BP: + case PI_ALPHA: + case PI_MODEL_CM: + case PI_MODEL_ZERO: + case PI_MODEL_ZERO_W: + piGpioBase = GPIO_PERI_BASE_OLD ; + piGpioPupOffset = GPPUD ; + break ; + + case PI_MODEL_4B: + case PI_MODEL_400: + case PI_MODEL_CM4: + piGpioBase = GPIO_PERI_BASE_2711 ; + piGpioPupOffset = GPPUPPDN0 ; + break ; + + case PI_MODEL_5: + piGpioBase = GPIO_PERI_BASE_2712 ; + piGpioPupOffset = 0 ; + break ; + + default: + piGpioBase = GPIO_PERI_BASE_2835 ; + piGpioPupOffset = GPPUD ; + break ; + } } @@ -2731,7 +2762,7 @@ int wiringPiGlobalMemoryAccess(void) if (lgpio == MAP_FAILED) { returnvalue = 0; if (wiringPiDebug) - fprintf(stderr,"wiringPiGlobalMemoryAccess: mmap (GPIO) failed: %s\n", strerror (errno)) ; + fprintf(stderr,"wiringPiGlobalMemoryAccess: mmap (GPIO 0x%X,0x%X) failed: %s\n", BaseAddr, MMAP_size, strerror (errno)) ; } else { munmap(lgpio, MMAP_size); if (PI_MODEL_5 == RaspberryPiModel) { @@ -2742,7 +2773,7 @@ int wiringPiGlobalMemoryAccess(void) if (lpwm == MAP_FAILED) { returnvalue = 1; // only GPIO accessible if (wiringPiDebug) - fprintf(stderr,"wiringPiGlobalMemoryAccess: mmap (PWM) failed: %s\n", strerror (errno)) ; + fprintf(stderr,"wiringPiGlobalMemoryAccess: mmap (PWM 0x%X,0x%X) failed: %s\n", PWMAddr, MMAP_size, strerror (errno)) ; } else { returnvalue = 2; // GPIO & PWM accessible munmap(lpwm, BLOCK_SIZE); @@ -2812,40 +2843,6 @@ int wiringPiSetup (void) physToGpio = physToGpioR2 ; } -// ... - - switch (model) - { - case PI_MODEL_A: - case PI_MODEL_B: - case PI_MODEL_AP: - case PI_MODEL_BP: - case PI_ALPHA: - case PI_MODEL_CM: - case PI_MODEL_ZERO: - case PI_MODEL_ZERO_W: - piGpioBase = GPIO_PERI_BASE_OLD ; - piGpioPupOffset = GPPUD ; - break ; - - case PI_MODEL_4B: - case PI_MODEL_400: - case PI_MODEL_CM4: - piGpioBase = GPIO_PERI_BASE_2711 ; - piGpioPupOffset = GPPUPPDN0 ; - break ; - - case PI_MODEL_5: - piGpioBase = GPIO_PERI_BASE_2712 ; - piGpioPupOffset = 0 ; - break ; - - default: - piGpioBase = GPIO_PERI_BASE_2835 ; - piGpioPupOffset = GPPUD ; - break ; - } - // Open the master /dev/ memory control device // Device strategy: December 2016: // Try /dev/mem. If that fails, then @@ -2938,6 +2935,7 @@ int wiringPiSetup (void) _wiringPiPads = pads ; _wiringPiTimer = timer ; _wiringPiRio = NULL ; + } else { unsigned int MMAP_size = (usingGpioMem) ? gpiomem_RP1_Size : pciemem_RP1_Size; GPIO_PADS = (RP1_PADS0_Addr-RP1_IO0_Addr) ;