From 18295f0dfb86d657aaf4e337eb460af9c8ff73cc Mon Sep 17 00:00:00 2001 From: phylax2020 <61159697+phylax2020@users.noreply.github.com> Date: Tue, 28 Jan 2025 21:46:50 +0100 Subject: [PATCH 01/65] Update functions.md Vor Aufruf waitForInterrupt muss waitForInterruptInit aufgerufen werden. --- documentation/deutsch/functions.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/documentation/deutsch/functions.md b/documentation/deutsch/functions.md index 114faa3..d759b50 100644 --- a/documentation/deutsch/functions.md +++ b/documentation/deutsch/functions.md @@ -357,7 +357,7 @@ int waitForInterrupt (int pin, int mS) ``Rückgabewert``: Fehler > 0 ... Erfolgreich > -1 ... GPIO Device Chip nicht erfolgreich geöffnet -> -2 ... ISR wurde nicht registriert (wiringPiISR muss aufgerufen werden) +> -2 ... ISR wurde nicht registriert (waitForInterruptInit muss aufgerufen werden) ## Hardware PWM (Pulsweitenmodulation) @@ -564,4 +564,4 @@ if (fd>0) { ## SPI - Bus -... \ No newline at end of file +... From 3e1f99e24d581b9bc9a7589117203c6f1dedb6a5 Mon Sep 17 00:00:00 2001 From: phylax2020 Date: Tue, 28 Jan 2025 22:30:54 +0100 Subject: [PATCH 02/65] new example isr_debounce.c --- examples/isr_debounce.c | 118 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 118 insertions(+) create mode 100644 examples/isr_debounce.c diff --git a/examples/isr_debounce.c b/examples/isr_debounce.c new file mode 100644 index 0000000..5c6ca8b --- /dev/null +++ b/examples/isr_debounce.c @@ -0,0 +1,118 @@ +/* + * isr_debounce.c: + * Wait for Interrupt test program WiringPi >=3.2 - ISR method + * + * + */ + +#include +#include +#include +#include +#include +#include +#include +// #include +#include + +#define BOUNCETIME 300 +#define TIMEOUT 10000 +//************************************* +// BCM pins +// IRQpin : setup as input with internal pullup. Connected with push button to GND with 1K resistor in series. +// OUTpin : connected to a LED with 470 Ohm resistor in series to GND. Toggles LED with every push button pressed. +//************************************* +#define IRQpin 16 +#define OUTpin 12 + +int toggle = 0; + +/* + * myInterrupt: + ********************************************************************************* + */ + +static void wfi (unsigned int gpio, long long int timestamp) { +// struct timeval now; + long long int timenow, diff; + struct timespec curr; + + if (clock_gettime(CLOCK_MONOTONIC, &curr) == -1) { + printf("clock_gettime error"); + return; + } + + timenow = curr.tv_sec * 1000000LL + curr.tv_nsec/1000L; // convert to microseconds + diff = timenow - timestamp; + + printf("gpio BCM = %d, IRQ timestamp = %lld microseconds, timenow = %lld, diff = %lld\n", gpio, timestamp, timenow, diff); + if (toggle == 0) { + digitalWrite (OUTpin, HIGH) ; + toggle = 1; + } + else { + digitalWrite (OUTpin, LOW) ; + toggle = 0; + } +} + + + +int main (void) +{ + int major, minor; + long long int ret; + + wiringPiVersion(&major, &minor); + + printf("\nISR debounce test (WiringPi %d.%d)\n\n", major, minor); + + wiringPiSetupGpio() ; + + pinMode(IRQpin, INPUT); + + // pull up/down mode (PUD_OFF, PUD_UP, PUD_DOWN) => down + pullUpDnControl(IRQpin, PUD_UP); + + pinMode(OUTpin, OUTPUT); + digitalWrite (OUTpin, LOW) ; + + // test waitForInterrupt + + ret = waitForInterruptInit (IRQpin, INT_EDGE_FALLING); + if (ret < 0) { + printf("waitForInterruptInit returned error %d\n", ret); + pinMode(OUTpin, INPUT); + return 0; + } + + printf("Testing waitForInterrupt IRQ @ GPIO%d, timeout is %d\n", IRQpin, TIMEOUT); + ret = waitForInterrupt(IRQpin, TIMEOUT, 0); + if (ret < 0) { + printf("waitForInterrupt returned error %lld\n", ret); + wiringPiISRStop (IRQpin) ; + pinMode(OUTpin, INPUT); + return 0; + } + else if (ret == 0) { + printf("waitForInterrupt timed out %lld\n\n", ret); + wiringPiISRStop (IRQpin) ; + } + else { + printf("waitForInterrupt returned success. ret = %lld\n\n", ret); + wiringPiISRStop (IRQpin) ; + } + + printf("Testing IRQ @ GPIO%d with trigger @ GPIO%d falling edge and bouncetime %d ms. Toggle LED @ OUTpin on IRQ.\n\n", IRQpin, IRQpin, BOUNCETIME, OUTpin); + printf("To stop program hit return key\n\n"); + + wiringPiISR (IRQpin, INT_EDGE_FALLING, &wfi, BOUNCETIME) ; + +// sleep(30); + getc(stdin); + + wiringPiISRStop (IRQpin) ; + pinMode(OUTpin, INPUT); + + return 0 ; +} \ No newline at end of file From 349a5adb389ccc8c2baf649cfc7408401eb26e66 Mon Sep 17 00:00:00 2001 From: phylax2020 <61159697+phylax2020@users.noreply.github.com> Date: Tue, 28 Jan 2025 23:45:15 +0100 Subject: [PATCH 03/65] Update functions.md --- documentation/deutsch/functions.md | 38 ++++++++++++++++++++++++------ 1 file changed, 31 insertions(+), 7 deletions(-) diff --git a/documentation/deutsch/functions.md b/documentation/deutsch/functions.md index d759b50..461e4b1 100644 --- a/documentation/deutsch/functions.md +++ b/documentation/deutsch/functions.md @@ -291,7 +291,7 @@ Registriert eine Interrupt Service Routine (ISR) bzw. Funktion die bei Flankenwe >>> ```C -int wiringPiISR(int pin, int mode, void (*function)(void)); +int wiringPiISR(int pin, int mode, void (*function)(unsigned int, long long int), int bouncetime); ``` ``pin``: Der gewünschte Pin (BCM-, WiringPi- oder Pin-Nummer). @@ -300,7 +300,9 @@ int wiringPiISR(int pin, int mode, void (*function)(void)); - INT_EDGE_FALLING ... Fallende Flanke - INT_EDGE_BOTH ... Steigende und fallende Flanke -``*function``: Funktionspointer für ISR +``*function``: Funktionspointer für ISR mit Rückgabeparameter pin: unsigned int und Zeitstempel: long long int + +``bouncetime``: Entprellzeit in ms, 0 ms schaltet das Entprellen ab ``Rückgabewert``: > 0 ... Erfolgreich @@ -345,21 +347,43 @@ int main (void) { ### waitForInterrupt -Wartet auf einen Aufruf der Interrupt Service Routine (ISR) mit Timeout. +Wartet auf einen Aufruf der Interrupt Service Routine (ISR) mit Timeout und Entprellzeit in Millisekunden. >>> ```C -int waitForInterrupt (int pin, int mS) +long long int waitForInterrupt (int pin, int mS, int bouncetime) ``` ``pin``: Der gewünschte Pin (BCM-, WiringPi- oder Pin-Nummer). -``mS``: Timeout in Milisekunden. -``Rückgabewert``: Fehler -> 0 ... Erfolgreich +``mS``: Timeout in Milisekunden. -1 warten ohne timeout, 0 wartet nicht, >0 wartet maximal mS Millisekunden + +``bouncetime``: Entprellzeit in Millisekunden, 0 schaltet Entprellen ab + +``Rückgabewert``: +> >0 ... Zeitstempel des Interrupt Ereignisses +> 0 ... Timeout > -1 ... GPIO Device Chip nicht erfolgreich geöffnet > -2 ... ISR wurde nicht registriert (waitForInterruptInit muss aufgerufen werden) +### waitForInterruptInit + +Initiaölisiert die Funktion waitForInterrupt +>>> +```C +int waitForInterruptInit (int pin, int mode) +``` +``pin``: Der gewünschte Pin (BCM-, WiringPi- oder Pin-Nummer) + +``mode``: INT_EDGE_RISING,INT_EDGE_FALLING,INT_EDGE_BOTH + +``Rückgabewert``: + +> -1 ... Fehler +> +> 0 ... erfolgreich + + ## Hardware PWM (Pulsweitenmodulation) Verfügbare GPIOs: https://pinout.xyz/pinout/pwm From 12e3abab94b7b2c0066f1812cd19a428a424e7f4 Mon Sep 17 00:00:00 2001 From: phylax2020 Date: Wed, 29 Jan 2025 09:34:49 +0100 Subject: [PATCH 04/65] functions.md --- documentation/deutsch/functions.md | 35 ++++++++++++++++++++++++------ 1 file changed, 28 insertions(+), 7 deletions(-) diff --git a/documentation/deutsch/functions.md b/documentation/deutsch/functions.md index d759b50..7af3db9 100644 --- a/documentation/deutsch/functions.md +++ b/documentation/deutsch/functions.md @@ -291,7 +291,7 @@ Registriert eine Interrupt Service Routine (ISR) bzw. Funktion die bei Flankenwe >>> ```C -int wiringPiISR(int pin, int mode, void (*function)(void)); +int wiringPiISR(int pin, int mode, void (*function)(unsigned int, long long int), int bouncetime); ``` ``pin``: Der gewünschte Pin (BCM-, WiringPi- oder Pin-Nummer). @@ -300,7 +300,8 @@ int wiringPiISR(int pin, int mode, void (*function)(void)); - INT_EDGE_FALLING ... Fallende Flanke - INT_EDGE_BOTH ... Steigende und fallende Flanke -``*function``: Funktionspointer für ISR +``*function``: Funktionspointer für ISR mit Rückgabeparameter pin: unsigned int und Zeitstempel: long long int +``bouncetime``: Entprellzeit in ms, 0 ms schaltet das Entprellen ab ``Rückgabewert``: > 0 ... Erfolgreich @@ -345,21 +346,41 @@ int main (void) { ### waitForInterrupt -Wartet auf einen Aufruf der Interrupt Service Routine (ISR) mit Timeout. +Wartet auf einen Aufruf der Interrupt Service Routine (ISR) mit Timeout und Entprellzeit in Millisekunden. >>> ```C -int waitForInterrupt (int pin, int mS) +long long int waitForInterrupt (int pin, int mS, int bouncetime) ``` ``pin``: Der gewünschte Pin (BCM-, WiringPi- oder Pin-Nummer). -``mS``: Timeout in Milisekunden. -``Rückgabewert``: Fehler -> 0 ... Erfolgreich +``mS``: Timeout in Milisekunden. -1 warten ohne timeout, 0 wartet nicht, \>0 wartet maximal mS Millisekunden +``bouncetime``: Entprellzeit in Millisekunden, 0 schaltet Entprellen ab + +``Rückgabewert``: +> \>0 ... Zeitstempel des Interrupt Ereignisses in Mikrosekunden +> 0 ... Timeout > -1 ... GPIO Device Chip nicht erfolgreich geöffnet > -2 ... ISR wurde nicht registriert (waitForInterruptInit muss aufgerufen werden) +### waitForInterruptInit + +Initialisiert die Funktion waitForInterrupt, definiert, welche Flanke den Interrupt erzeugen soll + +>>> +```C +int waitForInterruptInit (int pin, int mode) +``` + +``pin``: Der gewünschte Pin (BCM-, WiringPi- oder Pin-Nummer) +``mode``: INT_EDGE_RISING, INT_EDGE_FALLING, INT_EDGE_BOTH + +``Rückgabewert``: +> -1 ... Fehler +> 0 ... erfolgreich + + ## Hardware PWM (Pulsweitenmodulation) Verfügbare GPIOs: https://pinout.xyz/pinout/pwm From cd65d29b14c867335cfd4bcea06dcc04f85d2016 Mon Sep 17 00:00:00 2001 From: phylax2020 Date: Wed, 29 Jan 2025 09:40:37 +0100 Subject: [PATCH 05/65] functions.md --- documentation/deutsch/functions.md | 28 ---------------------------- 1 file changed, 28 deletions(-) diff --git a/documentation/deutsch/functions.md b/documentation/deutsch/functions.md index 16d9bc6..7af3db9 100644 --- a/documentation/deutsch/functions.md +++ b/documentation/deutsch/functions.md @@ -301,10 +301,6 @@ int wiringPiISR(int pin, int mode, void (*function)(unsigned int, long long int) - INT_EDGE_BOTH ... Steigende und fallende Flanke ``*function``: Funktionspointer für ISR mit Rückgabeparameter pin: unsigned int und Zeitstempel: long long int -<<<<<<< HEAD -======= - ->>>>>>> 349a5adb389ccc8c2baf649cfc7408401eb26e66 ``bouncetime``: Entprellzeit in ms, 0 ms schaltet das Entprellen ab ``Rückgabewert``: > 0 ... Erfolgreich @@ -358,20 +354,11 @@ long long int waitForInterrupt (int pin, int mS, int bouncetime) ``` ``pin``: Der gewünschte Pin (BCM-, WiringPi- oder Pin-Nummer). -<<<<<<< HEAD ``mS``: Timeout in Milisekunden. -1 warten ohne timeout, 0 wartet nicht, \>0 wartet maximal mS Millisekunden ``bouncetime``: Entprellzeit in Millisekunden, 0 schaltet Entprellen ab ``Rückgabewert``: > \>0 ... Zeitstempel des Interrupt Ereignisses in Mikrosekunden -======= -``mS``: Timeout in Milisekunden. -1 warten ohne timeout, 0 wartet nicht, >0 wartet maximal mS Millisekunden - -``bouncetime``: Entprellzeit in Millisekunden, 0 schaltet Entprellen ab - -``Rückgabewert``: -> >0 ... Zeitstempel des Interrupt Ereignisses ->>>>>>> 349a5adb389ccc8c2baf649cfc7408401eb26e66 > 0 ... Timeout > -1 ... GPIO Device Chip nicht erfolgreich geöffnet > -2 ... ISR wurde nicht registriert (waitForInterruptInit muss aufgerufen werden) @@ -379,33 +366,18 @@ long long int waitForInterrupt (int pin, int mS, int bouncetime) ### waitForInterruptInit -<<<<<<< HEAD Initialisiert die Funktion waitForInterrupt, definiert, welche Flanke den Interrupt erzeugen soll -======= -Initiaölisiert die Funktion waitForInterrupt ->>>>>>> 349a5adb389ccc8c2baf649cfc7408401eb26e66 >>> ```C int waitForInterruptInit (int pin, int mode) ``` -<<<<<<< HEAD ``pin``: Der gewünschte Pin (BCM-, WiringPi- oder Pin-Nummer) ``mode``: INT_EDGE_RISING, INT_EDGE_FALLING, INT_EDGE_BOTH ``Rückgabewert``: > -1 ... Fehler -======= -``pin``: Der gewünschte Pin (BCM-, WiringPi- oder Pin-Nummer) - -``mode``: INT_EDGE_RISING,INT_EDGE_FALLING,INT_EDGE_BOTH - -``Rückgabewert``: - -> -1 ... Fehler -> ->>>>>>> 349a5adb389ccc8c2baf649cfc7408401eb26e66 > 0 ... erfolgreich From c6945bb450b375d737ae51078f3ec441bb17efa3 Mon Sep 17 00:00:00 2001 From: phylax2020 Date: Wed, 29 Jan 2025 09:45:16 +0100 Subject: [PATCH 06/65] functions.md --- documentation/deutsch/functions.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/documentation/deutsch/functions.md b/documentation/deutsch/functions.md index 7af3db9..67008ea 100644 --- a/documentation/deutsch/functions.md +++ b/documentation/deutsch/functions.md @@ -354,7 +354,8 @@ long long int waitForInterrupt (int pin, int mS, int bouncetime) ``` ``pin``: Der gewünschte Pin (BCM-, WiringPi- oder Pin-Nummer). -``mS``: Timeout in Milisekunden. -1 warten ohne timeout, 0 wartet nicht, \>0 wartet maximal mS Millisekunden +``mS``: Timeout in Milisekunden. -1 warten ohne timeout, 0 wartet nicht, \>0 wartet maximal mS Millisekunden. + ``bouncetime``: Entprellzeit in Millisekunden, 0 schaltet Entprellen ab ``Rückgabewert``: From 3370e8d137fc078e9bf001391ef7795615dfb89b Mon Sep 17 00:00:00 2001 From: phylax2020 Date: Wed, 29 Jan 2025 09:49:05 +0100 Subject: [PATCH 07/65] functions.md --- documentation/deutsch/functions.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/documentation/deutsch/functions.md b/documentation/deutsch/functions.md index 67008ea..b417c4c 100644 --- a/documentation/deutsch/functions.md +++ b/documentation/deutsch/functions.md @@ -354,8 +354,7 @@ long long int waitForInterrupt (int pin, int mS, int bouncetime) ``` ``pin``: Der gewünschte Pin (BCM-, WiringPi- oder Pin-Nummer). -``mS``: Timeout in Milisekunden. -1 warten ohne timeout, 0 wartet nicht, \>0 wartet maximal mS Millisekunden. - +``mS``: Timeout in Milisekunden. -1 warten ohne timeout, 0 wartet nicht, 1...n wartet maximal mS Millisekunden. ``bouncetime``: Entprellzeit in Millisekunden, 0 schaltet Entprellen ab ``Rückgabewert``: From ff440b029f69361b4f07aac4c1763ce440c16db6 Mon Sep 17 00:00:00 2001 From: phylax2020 Date: Wed, 29 Jan 2025 10:29:18 +0100 Subject: [PATCH 08/65] functions.md --- documentation/deutsch/functions.md | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/documentation/deutsch/functions.md b/documentation/deutsch/functions.md index b417c4c..499edab 100644 --- a/documentation/deutsch/functions.md +++ b/documentation/deutsch/functions.md @@ -353,15 +353,18 @@ Wartet auf einen Aufruf der Interrupt Service Routine (ISR) mit Timeout und Entp long long int waitForInterrupt (int pin, int mS, int bouncetime) ``` -``pin``: Der gewünschte Pin (BCM-, WiringPi- oder Pin-Nummer). -``mS``: Timeout in Milisekunden. -1 warten ohne timeout, 0 wartet nicht, 1...n wartet maximal mS Millisekunden. +``pin``: Der gewünschte Pin (BCM\-, WiringPi\- oder Pin\-Nummer). +``mS``: Timeout in Milisekunden. + - \-1 warten ohne timeout + - 0 wartet nicht + - 1...n wartet maximal mS Millisekunden ``bouncetime``: Entprellzeit in Millisekunden, 0 schaltet Entprellen ab ``Rückgabewert``: > \>0 ... Zeitstempel des Interrupt Ereignisses in Mikrosekunden > 0 ... Timeout -> -1 ... GPIO Device Chip nicht erfolgreich geöffnet -> -2 ... ISR wurde nicht registriert (waitForInterruptInit muss aufgerufen werden) +> \-1 ... GPIO Device Chip nicht erfolgreich geöffnet +> \-2 ... ISR wurde nicht registriert (waitForInterruptInit muss aufgerufen werden) ### waitForInterruptInit @@ -373,11 +376,11 @@ Initialisiert die Funktion waitForInterrupt, definiert, welche Flanke den Interr int waitForInterruptInit (int pin, int mode) ``` -``pin``: Der gewünschte Pin (BCM-, WiringPi- oder Pin-Nummer) +``pin``: Der gewünschte Pin (BCM\-, WiringPi\- oder Pin\-Nummer) ``mode``: INT_EDGE_RISING, INT_EDGE_FALLING, INT_EDGE_BOTH ``Rückgabewert``: -> -1 ... Fehler +> \-1 ... Fehler > 0 ... erfolgreich From 554b83236b86f21c2dec37c7aefb8bac21b26cb8 Mon Sep 17 00:00:00 2001 From: phylax2020 Date: Wed, 29 Jan 2025 10:53:35 +0100 Subject: [PATCH 09/65] functions.md --- documentation/deutsch/functions.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/documentation/deutsch/functions.md b/documentation/deutsch/functions.md index 499edab..6b79287 100644 --- a/documentation/deutsch/functions.md +++ b/documentation/deutsch/functions.md @@ -357,8 +357,8 @@ long long int waitForInterrupt (int pin, int mS, int bouncetime) ``mS``: Timeout in Milisekunden. - \-1 warten ohne timeout - 0 wartet nicht - - 1...n wartet maximal mS Millisekunden -``bouncetime``: Entprellzeit in Millisekunden, 0 schaltet Entprellen ab + - 1...n wartet maximal n mS Millisekunden +``bouncetime``: Entprellzeit in Millisekunden, 0 schaltet Entprellen ab ``Rückgabewert``: > \>0 ... Zeitstempel des Interrupt Ereignisses in Mikrosekunden @@ -376,12 +376,12 @@ Initialisiert die Funktion waitForInterrupt, definiert, welche Flanke den Interr int waitForInterruptInit (int pin, int mode) ``` -``pin``: Der gewünschte Pin (BCM\-, WiringPi\- oder Pin\-Nummer) -``mode``: INT_EDGE_RISING, INT_EDGE_FALLING, INT_EDGE_BOTH +``pin``: Der gewünschte Pin (BCM\-, WiringPi\- oder Pin\-Nummer) +``mode``: INT_EDGE_RISING, INT_EDGE_FALLING, INT_EDGE_BOTH ``Rückgabewert``: -> \-1 ... Fehler -> 0 ... erfolgreich +> \-1 ... Fehler +> 0 ... erfolgreich ## Hardware PWM (Pulsweitenmodulation) From 92793adf42e901d0c4d32ef5b3fc45eecc981871 Mon Sep 17 00:00:00 2001 From: phylax2020 Date: Wed, 29 Jan 2025 11:03:34 +0100 Subject: [PATCH 10/65] functions.md --- documentation/deutsch/functions.md | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/documentation/deutsch/functions.md b/documentation/deutsch/functions.md index 6b79287..103641f 100644 --- a/documentation/deutsch/functions.md +++ b/documentation/deutsch/functions.md @@ -294,13 +294,16 @@ Registriert eine Interrupt Service Routine (ISR) bzw. Funktion die bei Flankenwe int wiringPiISR(int pin, int mode, void (*function)(unsigned int, long long int), int bouncetime); ``` -``pin``: Der gewünschte Pin (BCM-, WiringPi- oder Pin-Nummer). -``mode``: Auslösende Flankenmodus +``pin``: Der gewünschte Pin (BCM\-, WiringPi\- oder Pin\-Nummer). +``mode``: Auslösende Flankenmodus - INT_EDGE_RISING ... Steigende Flanke - INT_EDGE_FALLING ... Fallende Flanke - INT_EDGE_BOTH ... Steigende und fallende Flanke -``*function``: Funktionspointer für ISR mit Rückgabeparameter pin: unsigned int und Zeitstempel: long long int +``*function``: Funktionspointer für ISR mit Rückgabeparameter pin und Zeitstempel: + > unsigned int: pin + > long long int: Zeitstempel + ``bouncetime``: Entprellzeit in ms, 0 ms schaltet das Entprellen ab ``Rückgabewert``: > 0 ... Erfolgreich From 2e3dae0f72a6b23c20c3aa891e0a5f2434511c1e Mon Sep 17 00:00:00 2001 From: phylax2020 Date: Wed, 29 Jan 2025 11:40:41 +0100 Subject: [PATCH 11/65] functions.md --- documentation/deutsch/functions.md | 143 ++++++++++++++++++++++++----- 1 file changed, 122 insertions(+), 21 deletions(-) diff --git a/documentation/deutsch/functions.md b/documentation/deutsch/functions.md index 103641f..1fb5ccb 100644 --- a/documentation/deutsch/functions.md +++ b/documentation/deutsch/functions.md @@ -305,11 +305,12 @@ int wiringPiISR(int pin, int mode, void (*function)(unsigned int, long long int) > long long int: Zeitstempel ``bouncetime``: Entprellzeit in ms, 0 ms schaltet das Entprellen ab + ``Rückgabewert``: > 0 ... Erfolgreich -Beispiel siehe wiringPiISRStop. +Beispiel siehe waitForInterruptInit. ### wiringPiISRStop @@ -327,26 +328,6 @@ int wiringPiISRStop (int pin) -**Beispiel:** - -```C -static volatile int edgeCounter; - -static void isr(void) { - edgeCounter++; -} - -int main (void) { - wiringPiSetupPinType(WPI_PIN_BCM); - edgeCounter = 0; - wiringPiISR (17, INT_EDGE_RISING, &isr); - Sleep(1000); - printf("%d rinsing edges\n", ) - wiringPiISRStop(17) ; -} -``` - - ### waitForInterrupt Wartet auf einen Aufruf der Interrupt Service Routine (ISR) mit Timeout und Entprellzeit in Millisekunden. @@ -387,6 +368,126 @@ int waitForInterruptInit (int pin, int mode) > 0 ... erfolgreich +**Beispiel:** + +```C +/* + * isr_debounce.c: + * Wait for Interrupt test program WiringPi >=3.13 - ISR method + * + * + */ + +#include +#include +#include +#include +#include + +#include + +#define BOUNCETIME 300 +#define TIMEOUT 10000 +//************************************* +// BCM pins +// IRQpin : setup as input with internal pullup. Connected with push button to GND with 1K resistor in series. +// OUTpin : connected to a LED with 470 Ohm resistor in series to GND. Toggles LED with every push button pressed. +//************************************* +#define IRQpin 16 +#define OUTpin 12 + +int toggle = 0; + +/* + * myInterrupt: + ********************************************************************************* + */ + +static void wfi (unsigned int gpio, long long int timestamp) { +// struct timeval now; + long long int timenow, diff; + struct timespec curr; + + if (clock_gettime(CLOCK_MONOTONIC, &curr) == -1) { + printf("clock_gettime error"); + return; + } + + timenow = curr.tv_sec * 1000000LL + curr.tv_nsec/1000L; // convert to microseconds + diff = timenow - timestamp; + + printf("gpio BCM = %d, IRQ timestamp = %lld microseconds, timenow = %lld, diff = %lld\n", gpio, timestamp, timenow, diff); + if (toggle == 0) { + digitalWrite (OUTpin, HIGH) ; + toggle = 1; + } + else { + digitalWrite (OUTpin, LOW) ; + toggle = 0; + } +} + + + +int main (void) +{ + int major, minor; + long long int ret; + + wiringPiVersion(&major, &minor); + + printf("\nISR debounce test (WiringPi %d.%d)\n\n", major, minor); + + wiringPiSetupGpio() ; + + pinMode(IRQpin, INPUT); + + // pull up/down mode (PUD_OFF, PUD_UP, PUD_DOWN) => down + pullUpDnControl(IRQpin, PUD_UP); + + pinMode(OUTpin, OUTPUT); + digitalWrite (OUTpin, LOW) ; + + // test waitForInterrupt + + ret = waitForInterruptInit (IRQpin, INT_EDGE_FALLING); + if (ret < 0) { + printf("waitForInterruptInit returned error %d\n", ret); + pinMode(OUTpin, INPUT); + return 0; + } + + printf("Testing waitForInterrupt IRQ @ GPIO%d, timeout is %d\n", IRQpin, TIMEOUT); + ret = waitForInterrupt(IRQpin, TIMEOUT, 0); + if (ret < 0) { + printf("waitForInterrupt returned error %lld\n", ret); + wiringPiISRStop (IRQpin) ; + pinMode(OUTpin, INPUT); + return 0; + } + else if (ret == 0) { + printf("waitForInterrupt timed out %lld\n\n", ret); + wiringPiISRStop (IRQpin) ; + } + else { + printf("waitForInterrupt: falling edge fired at %lld microseconds\n\n", ret); + wiringPiISRStop (IRQpin) ; + } + + printf("Testing IRQ @ GPIO%d with trigger @ GPIO%d falling edge and bouncetime %d ms. Toggle LED @ OUTpin on IRQ.\n\n", IRQpin, IRQpin, BOUNCETIME, OUTpin); + printf("To stop program hit return key\n\n"); + + wiringPiISR (IRQpin, INT_EDGE_FALLING, &wfi, BOUNCETIME) ; + + getc(stdin); + + wiringPiISRStop (IRQpin) ; + pinMode(OUTpin, INPUT); + + return 0 ; +} +``` + ## Hardware PWM (Pulsweitenmodulation) Verfügbare GPIOs: https://pinout.xyz/pinout/pwm From b29831d563902535eb29426983785080186b2c27 Mon Sep 17 00:00:00 2001 From: phylax2020 Date: Wed, 29 Jan 2025 11:47:07 +0100 Subject: [PATCH 12/65] functions.md --- documentation/deutsch/functions.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/documentation/deutsch/functions.md b/documentation/deutsch/functions.md index 1fb5ccb..a6ece16 100644 --- a/documentation/deutsch/functions.md +++ b/documentation/deutsch/functions.md @@ -338,17 +338,17 @@ long long int waitForInterrupt (int pin, int mS, int bouncetime) ``` ``pin``: Der gewünschte Pin (BCM\-, WiringPi\- oder Pin\-Nummer). -``mS``: Timeout in Milisekunden. - - \-1 warten ohne timeout - - 0 wartet nicht +``mS``: Timeout in Milisekunden. + - \-1 warten ohne timeout + - 0 wartet nicht - 1...n wartet maximal n mS Millisekunden ``bouncetime``: Entprellzeit in Millisekunden, 0 schaltet Entprellen ab -``Rückgabewert``: -> \>0 ... Zeitstempel des Interrupt Ereignisses in Mikrosekunden +``Rückgabewert``: +> \>0 ... Zeitstempel des Interrupt Ereignisses in Mikrosekunden > 0 ... Timeout > \-1 ... GPIO Device Chip nicht erfolgreich geöffnet -> \-2 ... ISR wurde nicht registriert (waitForInterruptInit muss aufgerufen werden) +> \-2 ... ISR wurde nicht registriert (waitForInterruptInit muss aufgerufen werden) ### waitForInterruptInit @@ -363,7 +363,7 @@ int waitForInterruptInit (int pin, int mode) ``pin``: Der gewünschte Pin (BCM\-, WiringPi\- oder Pin\-Nummer) ``mode``: INT_EDGE_RISING, INT_EDGE_FALLING, INT_EDGE_BOTH -``Rückgabewert``: +``Rückgabewert``: > \-1 ... Fehler > 0 ... erfolgreich From b55101e013c0af8b2255b487a7d7c6e19ce515aa Mon Sep 17 00:00:00 2001 From: phylax2020 Date: Wed, 29 Jan 2025 11:50:28 +0100 Subject: [PATCH 13/65] isr_debounce.c --- examples/isr_debounce.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/examples/isr_debounce.c b/examples/isr_debounce.c index 5c6ca8b..8ddc9c1 100644 --- a/examples/isr_debounce.c +++ b/examples/isr_debounce.c @@ -1,6 +1,6 @@ /* * isr_debounce.c: - * Wait for Interrupt test program WiringPi >=3.2 - ISR method + * Wait for Interrupt test program WiringPi >=3.13 - ISR method * * */ @@ -10,9 +10,7 @@ #include #include #include -#include -#include -// #include + #include #define BOUNCETIME 300 @@ -99,7 +97,7 @@ int main (void) wiringPiISRStop (IRQpin) ; } else { - printf("waitForInterrupt returned success. ret = %lld\n\n", ret); + printf("waitForInterrupt: falling edge fired at %lld microseconds\n\n", ret); wiringPiISRStop (IRQpin) ; } From 0bf457519da3178524945219247e62422e224ae3 Mon Sep 17 00:00:00 2001 From: phylax2020 Date: Wed, 29 Jan 2025 19:09:32 +0100 Subject: [PATCH 14/65] Version 3.13 : debounce time added for wiringPiISR and waitForInterrupt library functions. Documentation update --- VERSION | 2 +- documentation/deutsch/functions.md | 4 +- gpio/gpio.c | 4 +- version.h | 4 +- wiringPi/wiringPi.c | 97 +++++++++++++++++++++--------- wiringPi/wiringPi.h | 5 +- 6 files changed, 77 insertions(+), 39 deletions(-) diff --git a/VERSION b/VERSION index e4fba21..24ee5b1 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -3.12 +3.13 diff --git a/documentation/deutsch/functions.md b/documentation/deutsch/functions.md index a6ece16..2093650 100644 --- a/documentation/deutsch/functions.md +++ b/documentation/deutsch/functions.md @@ -20,13 +20,13 @@ sudo apt install git git clone https://github.com/WiringPi/WiringPi.git cd WiringPi ./build debian -mv debian-template/wiringpi-3.0-1.deb . +mv debian-template/wiringpi-3.13.deb . ``` **Debian-Paket installieren:** ```bash -sudo apt install ./wiringpi-3.0-1.deb +sudo apt install ./wiringpi-3.13.deb ``` **Debian-Paket deinstallieren:** diff --git a/gpio/gpio.c b/gpio/gpio.c index 3fc97a3..f79188b 100644 --- a/gpio/gpio.c +++ b/gpio/gpio.c @@ -177,7 +177,7 @@ void printgpio(const char* text) { } } -static void wfi (void) { +static void wfi (unsigned int pin, long long int timestamp) { globalCounter++; if(globalCounter>=iterations) { printgpio("finished\n"); @@ -217,7 +217,7 @@ void doWfi (int argc, char *argv []) timeoutSec = atoi(argv [5]); } - if (wiringPiISR (pin, mode, &wfi) < 0) + if (wiringPiISR (pin, mode, &wfi, 0) < 0) { fprintf (stderr, "%s: wfi: Unable to setup ISR: %s\n", argv [1], strerror (errno)) ; exit (1) ; diff --git a/version.h b/version.h index 225bee7..35a3048 100644 --- a/version.h +++ b/version.h @@ -1,3 +1,3 @@ -#define VERSION "3.12" +#define VERSION "3.13" #define VERSION_MAJOR 3 -#define VERSION_MINOR 12 +#define VERSION_MINOR 13 diff --git a/wiringPi/wiringPi.c b/wiringPi/wiringPi.c index 50d20fe..e3d6a25 100644 --- a/wiringPi/wiringPi.c +++ b/wiringPi/wiringPi.c @@ -473,9 +473,10 @@ static int isrFds [64] = // ISR Data static int chipFd = -1; -static void (*isrFunctions [64])(void) ; +static void (*isrFunctions [64])(unsigned int, long long int) ; static pthread_t isrThreads[64]; static int isrMode[64]; +static unsigned long long lastcall[64]; // Doing it the Arduino way with lookup tables... // Yes, it's probably more innefficient than all the bit-twidling, but it @@ -2566,16 +2567,26 @@ unsigned int digitalReadByte2 (void) * This is actually done via the /dev/gpiochip interface regardless of * the wiringPi access mode in-use. Maybe sometime it might get a better * way for a bit more efficiency. + * Returns timestamp in microseconds, when interrupt happened ********************************************************************************* */ -int waitForInterrupt (int pin, int mS) +long long int waitForInterrupt (int pin, int mS, int bouncetime) // bounctime in milliseconds { - int fd, ret; + long long int ret; + int fd; struct pollfd polls ; struct gpioevent_data evdata; //struct gpio_v2_line_request req2; + struct timeval tv_timenow; + unsigned long long timenow; + int finished = 0; + int initial_edge = 1; + if (wiringPiDebug) { + printf ("waitForInterrupt: mS = %d, bouncetime = %d\n", mS, bouncetime) ; + } + if (wiringPiMode == WPI_MODE_PINS) pin = pinToGpio [pin] ; else if (wiringPiMode == WPI_MODE_PHYS) @@ -2590,23 +2601,46 @@ int waitForInterrupt (int pin, int mS) polls.revents = 0; // Wait for it ... - ret = poll(&polls, 1, mS); - if (ret <= 0) { - fprintf(stderr, "wiringPi: ERROR: poll returned=%d\n", ret); - } else { - //if (polls.revents & POLLIN) - if (wiringPiDebug) { - printf ("wiringPi: IRQ line %d received %d, fd=%d\n", pin, ret, isrFds[pin]) ; - } - /* read event data */ - 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) ; + while (!finished) { + ret = (long long int)poll(&polls, 1, mS); + if (ret < 0) { + if (wiringPiDebug) { + fprintf(stderr, "wiringPi: ERROR: poll returned=%lld\n", ret); + } + break; + } else if (ret == 0) { + if (wiringPiDebug) { + fprintf(stderr, "wiringPi: timeout: poll returned=%lld\n", ret); + } + break; + } + else { + //if (polls.revents & POLLIN) + if (wiringPiDebug) { + printf ("wiringPi: IRQ line %d received %lld, fd=%d\n", pin, ret, isrFds[pin]) ; + } + if (initial_edge) { // first time triggers with current state, so ignore + initial_edge = 0; + } else { + /* read event data */ + 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) ; + } +// ret = evdata.id; + gettimeofday(&tv_timenow, NULL); + timenow = tv_timenow.tv_sec*1E6 + tv_timenow.tv_usec; + if (bouncetime == 0 || timenow - lastcall[pin] > (unsigned int)bouncetime*1000 || lastcall[pin] == 0 || lastcall[pin] > timenow) { + lastcall[pin] = timenow; + finished = 1; + ret = evdata.timestamp / 1000LL; // nanoseconds u64 to microseconds + } + } else { + ret = -1; + break; + } } - ret = evdata.id; - } else { - ret = 0; } } return ret; @@ -2683,7 +2717,7 @@ int waitForInterruptClose (int pin) { if (wiringPiDebug) { printf ("wiringPi: waitForInterruptClose close thread 0x%lX\n", (unsigned long)isrThreads[pin]) ; } - if (pthread_cancel(isrThreads[pin]) == 0) { + if (isrThreads[pin] && pthread_cancel(isrThreads[pin]) == 0) { if (wiringPiDebug) { printf ("wiringPi: waitForInterruptClose thread canceled successfuly\n") ; } @@ -2696,7 +2730,7 @@ int waitForInterruptClose (int pin) { } isrFds [pin] = -1; isrFunctions [pin] = NULL; - + lastcall[pin] = 0; /* -not closing so far - other isr may be using it - only close if no other is using - will code later if (chipFd>0) { close(chipFd); @@ -2722,23 +2756,25 @@ int wiringPiISRStop (int pin) { ********************************************************************************* */ -static void *interruptHandler (UNU void *arg) +static void *interruptHandler (void *arg) { int pin ; - + int bouncetime; + (void)piHiPri (55) ; // Only effective if we run as root pin = pinPass ; + bouncetime = *(int *)arg; pinPass = -1 ; - + for (;;) { - int ret = waitForInterrupt(pin, -1); - if ( ret> 0) { + long long int ret = waitForInterrupt(pin, -1, bouncetime); + if ( ret> 0) { // return timestamp in microseconds if (wiringPiDebug) { printf ("wiringPi: call function\n") ; } if(isrFunctions [pin]) { - isrFunctions [pin] () ; + isrFunctions [pin] ((unsigned int)pin, ret) ; } // wait again - in the past forever - now can be stopped by waitForInterruptClose } else if( ret< 0) { @@ -2762,7 +2798,7 @@ static void *interruptHandler (UNU void *arg) ********************************************************************************* */ -int wiringPiISR (int pin, int mode, void (*function)(void)) +int wiringPiISR (int pin, int mode, void (*function)(unsigned int, long long int), int bouncetime) { const int maxpin = GetMaxPin(); @@ -2779,11 +2815,12 @@ int wiringPiISR (int pin, int mode, void (*function)(void)) isrFunctions [pin] = function ; isrMode[pin] = mode; + lastcall[pin] = 0; if(waitForInterruptInit (pin, mode)<0) { if (wiringPiDebug) { fprintf (stderr, "wiringPi: waitForInterruptInit failed\n") ; } - }; + } if (wiringPiDebug) { printf ("wiringPi: mutex in\n") ; @@ -2793,7 +2830,7 @@ int wiringPiISR (int pin, int mode, void (*function)(void)) if (wiringPiDebug) { printf("wiringPi: pthread_create before 0x%lX\n", (unsigned long)isrThreads[pin]); } - if (pthread_create (&isrThreads[pin], NULL, interruptHandler, NULL)==0) { + if (pthread_create (&isrThreads[pin], NULL, interruptHandler, &bouncetime)==0) { if (wiringPiDebug) { printf("wiringPi: pthread_create successed, 0x%lX\n", (unsigned long)isrThreads[pin]); } diff --git a/wiringPi/wiringPi.h b/wiringPi/wiringPi.h index 79a895a..7659d84 100644 --- a/wiringPi/wiringPi.h +++ b/wiringPi/wiringPi.h @@ -289,10 +289,11 @@ extern void digitalWriteByte2 (int value) ; // Interrupts // (Also Pi hardware specific) -extern int waitForInterrupt (int pin, int mS) ; -extern int wiringPiISR (int pin, int mode, void (*function)(void)) ; +extern long long int waitForInterrupt (int pin, int mS, int bouncetime) ; +extern int wiringPiISR (int pin, int mode, void (*function)(unsigned int, long long int), int bouncetime) ; extern int wiringPiISRStop (int pin) ; //V3.2 extern int waitForInterruptClose(int pin) ; //V3.2 +extern int waitForInterruptInit (int pin, int mode); //v3.2 // Threads From 92be5caccd8761b25d23ec1798b4acd04c8e0f39 Mon Sep 17 00:00:00 2001 From: phylax2020 Date: Tue, 11 Feb 2025 16:02:33 +0100 Subject: [PATCH 15/65] Version 3.14: WiringPi functions upgrade to GPIO_V2 IOCTL --- VERSION | 2 +- documentation/deutsch/functions.md | 60 +-- version.h | 4 +- wiringPi/wiringPi.c | 641 +++++++++++++++++++---------- wiringPi/wiringPi.h | 6 +- 5 files changed, 457 insertions(+), 256 deletions(-) diff --git a/VERSION b/VERSION index 24ee5b1..3767b4b 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -3.13 +3.14 \ No newline at end of file diff --git a/documentation/deutsch/functions.md b/documentation/deutsch/functions.md index 2093650..fbfc431 100644 --- a/documentation/deutsch/functions.md +++ b/documentation/deutsch/functions.md @@ -291,11 +291,11 @@ Registriert eine Interrupt Service Routine (ISR) bzw. Funktion die bei Flankenwe >>> ```C -int wiringPiISR(int pin, int mode, void (*function)(unsigned int, long long int), int bouncetime); +int wiringPiISR(int pin, int edgeMode, void (*function)(unsigned int, long long int), unsigned long bouncetime); ``` ``pin``: Der gewünschte Pin (BCM\-, WiringPi\- oder Pin\-Nummer). -``mode``: Auslösende Flankenmodus +``edgeMode``: Auslösende Flankenmodus - INT_EDGE_RISING ... Steigende Flanke - INT_EDGE_FALLING ... Fallende Flanke - INT_EDGE_BOTH ... Steigende und fallende Flanke @@ -304,13 +304,13 @@ int wiringPiISR(int pin, int mode, void (*function)(unsigned int, long long int) > unsigned int: pin > long long int: Zeitstempel -``bouncetime``: Entprellzeit in ms, 0 ms schaltet das Entprellen ab +``bouncetime``: Entprellzeit in Microsekunden, 0 ms schaltet das Entprellen ab ``Rückgabewert``: > 0 ... Erfolgreich -Beispiel siehe waitForInterruptInit. +Beispiel siehe waitForInterrupt. ### wiringPiISRStop @@ -330,42 +330,29 @@ int wiringPiISRStop (int pin) ### waitForInterrupt -Wartet auf einen Aufruf der Interrupt Service Routine (ISR) mit Timeout und Entprellzeit in Millisekunden. - +Wartet auf einen Aufruf der Interrupt Service Routine (ISR) mit Timeout und Entprellzeit in Mikrosekunden. +Blockiert das Programm bis zum Eintreffen der auslösenden Flanke oder bis zum Ablauf des Timeouts. >>> ```C -long long int waitForInterrupt (int pin, int mS, int bouncetime) +long long int waitForInterrupt (int pin, int edgeMode, int mS, unsigned long bouncetime) ``` ``pin``: Der gewünschte Pin (BCM\-, WiringPi\- oder Pin\-Nummer). +``edgeMode``: Auslösende Flankenmodus + - INT_EDGE_RISING ... Steigende Flanke + - INT_EDGE_FALLING ... Fallende Flanke + - INT_EDGE_BOTH ... Steigende und fallende Flanke ``mS``: Timeout in Milisekunden. - \-1 warten ohne timeout - 0 wartet nicht - 1...n wartet maximal n mS Millisekunden -``bouncetime``: Entprellzeit in Millisekunden, 0 schaltet Entprellen ab +``bouncetime``: Entprellzeit in Microsekunden, 0 schaltet Entprellen ab. ``Rückgabewert``: > \>0 ... Zeitstempel des Interrupt Ereignisses in Mikrosekunden > 0 ... Timeout > \-1 ... GPIO Device Chip nicht erfolgreich geöffnet -> \-2 ... ISR wurde nicht registriert (waitForInterruptInit muss aufgerufen werden) - - -### waitForInterruptInit - -Initialisiert die Funktion waitForInterrupt, definiert, welche Flanke den Interrupt erzeugen soll - ->>> -```C -int waitForInterruptInit (int pin, int mode) -``` - -``pin``: Der gewünschte Pin (BCM\-, WiringPi\- oder Pin\-Nummer) -``mode``: INT_EDGE_RISING, INT_EDGE_FALLING, INT_EDGE_BOTH - -``Rückgabewert``: -> \-1 ... Fehler -> 0 ... erfolgreich +> \-2 ... ISR wurde nicht registriert **Beispiel:** @@ -373,7 +360,7 @@ int waitForInterruptInit (int pin, int mode) ```C /* * isr_debounce.c: - * Wait for Interrupt test program WiringPi >=3.13 - ISR method + * Wait for Interrupt test program WiringPi >=3.14 - ISR method * * */ @@ -382,11 +369,13 @@ int waitForInterruptInit (int pin, int mode) #include #include #include +#include #include #include -#define BOUNCETIME 300 +#define BOUNCETIME 3000 // microseconds +#define BOUNCETIME_WFI 300 #define TIMEOUT 10000 //************************************* // BCM pins @@ -447,18 +436,9 @@ int main (void) pinMode(OUTpin, OUTPUT); digitalWrite (OUTpin, LOW) ; - - // test waitForInterrupt - ret = waitForInterruptInit (IRQpin, INT_EDGE_FALLING); - if (ret < 0) { - printf("waitForInterruptInit returned error %d\n", ret); - pinMode(OUTpin, INPUT); - return 0; - } - printf("Testing waitForInterrupt IRQ @ GPIO%d, timeout is %d\n", IRQpin, TIMEOUT); - ret = waitForInterrupt(IRQpin, TIMEOUT, 0); + ret = waitForInterrupt(IRQpin, INT_EDGE_FALLING, TIMEOUT, BOUNCETIME_WFI ); if (ret < 0) { printf("waitForInterrupt returned error %lld\n", ret); wiringPiISRStop (IRQpin) ; @@ -470,11 +450,11 @@ int main (void) wiringPiISRStop (IRQpin) ; } else { - printf("waitForInterrupt: falling edge fired at %lld microseconds\n\n", ret); + printf("waitForInterrupt: falling edge fired at %lld microseconds\n\n", ret); wiringPiISRStop (IRQpin) ; } - printf("Testing IRQ @ GPIO%d with trigger @ GPIO%d falling edge and bouncetime %d ms. Toggle LED @ OUTpin on IRQ.\n\n", IRQpin, IRQpin, BOUNCETIME, OUTpin); + printf("Testing IRQ @ GPIO%d with trigger @ GPIO%d falling edge and bouncetime %d microseconds. Toggle LED @ OUTpin on IRQ.\n\n", IRQpin, IRQpin, BOUNCETIME, OUTpin); printf("To stop program hit return key\n\n"); wiringPiISR (IRQpin, INT_EDGE_FALLING, &wfi, BOUNCETIME) ; diff --git a/version.h b/version.h index 35a3048..c2da282 100644 --- a/version.h +++ b/version.h @@ -1,3 +1,3 @@ -#define VERSION "3.13" +#define VERSION "3.14" #define VERSION_MAJOR 3 -#define VERSION_MINOR 13 +#define VERSION_MINOR 14 diff --git a/wiringPi/wiringPi.c b/wiringPi/wiringPi.c index e3d6a25..1dafed5 100644 --- a/wiringPi/wiringPi.c +++ b/wiringPi/wiringPi.c @@ -56,6 +56,7 @@ #include #include #include +#include #include #include #include @@ -471,12 +472,14 @@ static int isrFds [64] = -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, } ; + + // ISR Data static int chipFd = -1; static void (*isrFunctions [64])(unsigned int, long long int) ; static pthread_t isrThreads[64]; -static int isrMode[64]; -static unsigned long long lastcall[64]; +static int isrMode[64]; // irq on rising/falling edge +static unsigned long isrDebouncePeriodUs [64]; // 0: debounce is off // Doing it the Arduino way with lookup tables... // Yes, it's probably more innefficient than all the bit-twidling, but it @@ -1734,11 +1737,14 @@ void releaseLine(int pin) { lineFlags[pin] = 0; close(lineFds[pin]); lineFds[pin] = -1; + isrDebouncePeriodUs[pin] = 0; } int requestLine(int pin, unsigned int lineRequestFlags) { - struct gpiohandle_request rq; - + struct gpio_v2_line_request req; + struct gpio_v2_line_config config; + int ret; + if (lineFds[pin]>=0) { if (lineRequestFlags == lineFlags[pin]) { //already requested @@ -1753,17 +1759,25 @@ int requestLine(int pin, unsigned int lineRequestFlags) { if (wiringPiGpioDeviceGetFd()<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) { + + memset(&req, 0, sizeof(req)); + memset(&config, 0, sizeof(config)); + config.flags = lineRequestFlags; + strcpy(req.consumer, "wiringpi_gpio_req"); + + req.offsets[0] = pin; + req.num_lines = 1; + req.config = config; + + ret = ioctl(chipFd, GPIO_V2_GET_LINE_IOCTL, &req); + + if (ret || req.fd<0) { ReportDeviceError("get line handle", pin, "RequestLine", ret); return -1; // error } lineFlags[pin] = lineRequestFlags; - lineFds[pin] = rq.fd; + lineFds[pin] = req.fd; if (wiringPiDebug) printf ("requestLine succeeded: pin:%d, flags: %u, fd :%d\n", pin, lineRequestFlags, lineFds[pin]) ; return lineFds[pin]; @@ -1863,16 +1877,16 @@ void pinModeFlagsDevice (int pin, int mode, unsigned int flags) { if (wiringPiDebug) printf ("pinModeFlagsDevice: pin:%d mode:%d, flags: %u\n", pin, mode, flags) ; - lflag &= ~(GPIOHANDLE_REQUEST_INPUT | GPIOHANDLE_REQUEST_OUTPUT); + lflag &= ~(GPIO_V2_LINE_FLAG_INPUT | GPIO_V2_LINE_FLAG_OUTPUT); switch(mode) { default: fprintf(stderr, "pinMode: invalid mode request (only input und output supported)\n"); return; case INPUT: - lflag |= GPIOHANDLE_REQUEST_INPUT; + lflag |= GPIO_V2_LINE_FLAG_INPUT; break; case OUTPUT: - lflag |= GPIOHANDLE_REQUEST_OUTPUT; + lflag |= GPIO_V2_LINE_FLAG_OUTPUT; break; case PM_OFF: pinModeFlagsDevice(pin, INPUT, 0); @@ -2038,20 +2052,20 @@ void pinMode (int pin, int mode) */ void pullUpDnControlDevice (int pin, int pud) { unsigned int flag = lineFlags[pin]; - unsigned int biasflags = GPIOHANDLE_REQUEST_BIAS_DISABLE | GPIOHANDLE_REQUEST_BIAS_PULL_UP | GPIOHANDLE_REQUEST_BIAS_PULL_DOWN; + unsigned int biasflags = GPIO_V2_LINE_FLAG_BIAS_DISABLED | GPIO_V2_LINE_FLAG_BIAS_PULL_UP | GPIO_V2_LINE_FLAG_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; + case PUD_OFF: flag |= GPIO_V2_LINE_FLAG_BIAS_DISABLED; break; + case PUD_UP: flag |= GPIO_V2_LINE_FLAG_BIAS_PULL_UP; break; + case PUD_DOWN: flag |= GPIO_V2_LINE_FLAG_BIAS_PULL_DOWN; break; default: return ; /* An illegal value */ } // reset input/output - if (lineFlags[pin] & GPIOHANDLE_REQUEST_OUTPUT) { + if (lineFlags[pin] & GPIO_V2_LINE_FLAG_OUTPUT) { pinModeFlagsDevice (pin, OUTPUT, flag); - } else if(lineFlags[pin] & GPIOHANDLE_REQUEST_INPUT) { + } else if(lineFlags[pin] & GPIO_V2_LINE_FLAG_INPUT) { pinModeFlagsDevice (pin, INPUT, flag); } else { lineFlags[pin] = flag; // only store for later @@ -2135,7 +2149,33 @@ void pullUpDnControl (int pin, int pud) } } +/* + helper functions for gpio_v2_line_values bits +*/ +static inline void gpiotools_set_bit(__u64 *b, int n) +{ + *b |= _BITULL(n); +} +static inline void gpiotools_clear_bit(__u64 *b, int n) +{ + *b &= ~_BITULL(n); +} + +static inline void gpiotools_assign_bit(__u64 *b, int n, bool value) +{ + if (value) + gpiotools_set_bit(b, n); + else + gpiotools_clear_bit(b, n); +} + +static inline int gpiotools_test_bit(__u64 b, int n) +{ + return !!(b & _BITULL(n)); +} + +//********************************************* /* @@ -2145,19 +2185,23 @@ void pullUpDnControl (int pin, int pud) */ int digitalReadDevice (int pin) { // INPUT and OUTPUT should work - - if (lineFds[pin]<0) { + struct gpio_v2_line_values lv; + int ret; + + if (lineFds[pin]<0) { // line not requested - auto request on first read as input - pinModeDevice(pin, INPUT); + pinModeDevice(pin, INPUT); } + lv.mask = 0; + lv.bits = 0; if (lineFds[pin]>=0) { - struct gpiohandle_data data; - int ret = ioctl(lineFds[pin], GPIOHANDLE_GET_LINE_VALUES_IOCTL, &data); + gpiotools_set_bit(&lv.mask, 0); + ret = ioctl(lineFds[pin], GPIO_V2_LINE_GET_VALUES_IOCTL, &lv); if (ret) { ReportDeviceError("get line values", pin, "digitalRead", ret); return LOW; // error } - return data.values[0]; + return gpiotools_test_bit(lv.bits, 0); } return LOW; // error , need to request line before } @@ -2239,7 +2283,9 @@ unsigned int digitalRead8 (int pin) */ void digitalWriteDevice (int pin, int value) { - + int ret; + struct gpio_v2_line_values values; + if (wiringPiDebug) printf ("digitalWriteDevice: ioctl pin:%d value: %d\n", pin, value) ; @@ -2247,22 +2293,25 @@ void digitalWriteDevice (int pin, int value) { // line not requested - auto request on first write as output pinModeDevice(pin, OUTPUT); } - 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 - } + + if (lineFds[pin]>=0 && (lineFlags[pin] & GPIO_V2_LINE_FLAG_OUTPUT)>0) { + values.mask = 0; + values.bits = 0; + gpiotools_set_bit(&values.mask, 0); + gpiotools_assign_bit(&values.bits, 0, !!value); + + ret = ioctl(lineFds[pin], GPIO_V2_LINE_SET_VALUES_IOCTL, &values); + if (ret == -1) { + ReportDeviceError("digitalWriteDevice", pin, "GPIO_V2_LINE_SET_VALUES_IOCTL", ret); + return; // error + } } else { fprintf(stderr, "digitalWrite: no output (%d)\n", lineFlags[pin]); } return; // error } + void digitalWrite (int pin, int value) { struct wiringPiNodeStruct *node = wiringPiNodes ; @@ -2560,6 +2609,103 @@ unsigned int digitalReadByte2 (void) } + + +//-------------------------------------------------------------------- +// waitForInteruptInit +// Prepares waitForInterrupt for edgeMode, and debounce_period_us +// +// returns -1 on error +// returns 0 on success +//-------------------------------------------------------------------- + +int waitForInterruptInit (int pin, int edgeMode, unsigned long debounce_period_us) +{ + const char* strmode = ""; + struct gpio_v2_line_config config; + struct gpio_v2_line_request req; + int attr, ret; + + if (wiringPiMode == WPI_MODE_PINS) { + pin = pinToGpio [pin] ; + } else if (wiringPiMode == WPI_MODE_PHYS) { + pin = physToGpio [pin] ; + } + + /* open gpio */ +// sleep(1); + if (wiringPiGpioDeviceGetFd()<0) { + return -1; + } + + memset(&req, 0, sizeof(req)); + memset(&config, 0, sizeof(config)); + + /* setup config */ + config.flags = GPIO_V2_LINE_FLAG_INPUT; + switch(edgeMode) { + default: + case INT_EDGE_SETUP: + if (wiringPiDebug) { + printf ("wiringPi: waitForInterruptMode mode INT_EDGE_SETUP - exiting\n") ; + } + return -1; + case INT_EDGE_FALLING: + config.flags |= GPIO_V2_LINE_FLAG_EDGE_FALLING; + strmode = "falling"; + break; + case INT_EDGE_RISING: + config.flags |= GPIO_V2_LINE_FLAG_EDGE_RISING; + strmode = "rising"; + break; + case INT_EDGE_BOTH: + config.flags |= (GPIO_V2_LINE_FLAG_EDGE_FALLING | GPIO_V2_LINE_FLAG_EDGE_RISING); + strmode = "both"; + break; + } + strcpy(req.consumer, "wiringpi_gpio_irq"); + + if (debounce_period_us) { + attr = config.num_attrs; + config.num_attrs++; + gpiotools_set_bit(&config.attrs[attr].mask, 0); + config.attrs[attr].attr.id = GPIO_V2_LINE_ATTR_ID_DEBOUNCE; + config.attrs[attr].attr.debounce_period_us = debounce_period_us; + } + + req.num_lines = 1; + req.offsets[0] = pin; + req.event_buffer_size = 32; + req.config = config; + + ret = ioctl(chipFd, GPIO_V2_GET_LINE_IOCTL, &req); + if (ret == -1) { + ReportDeviceError("GPIO_V2_GET_LINE_IOCTL", pin , strmode, ret); + return -1; + } + + if (wiringPiDebug) { + printf ("wiringPi: GPIO get line %d , mode %s succeded, fd=%d\n", pin, strmode, req.fd) ; + } + + int fd_line = req.fd; + isrFds [pin] = fd_line; + isrDebouncePeriodUs[pin] = debounce_period_us; + +/* set event fd nonbloack read */ + /* + int flags = fcntl(fd_line, F_GETFL); + flags |= O_NONBLOCK; + ret = fcntl(fd_line, F_SETFL, flags); + if (ret) { + fprintf(stderr, "wiringPi: ERROR: fcntl set nonblock return=%d\n", ret); + return -1; + } +*/ + return 0; +} + + /* * waitForInterrupt: * Pi Specific. @@ -2567,25 +2713,124 @@ unsigned int digitalReadByte2 (void) * This is actually done via the /dev/gpiochip interface regardless of * the wiringPi access mode in-use. Maybe sometime it might get a better * way for a bit more efficiency. - * Returns timestamp in microseconds, when interrupt happened + * Returns timestamp in microseconds on interrupt ********************************************************************************* */ -long long int waitForInterrupt (int pin, int mS, int bouncetime) // bounctime in milliseconds +long long int waitForInterrupt (int pin, int edgeMode, int mS, unsigned long debounce_period_us) // ms < 0 wait infinite, = 0 return immediately, > 0 wait timeout { long long int ret; int fd; struct pollfd polls ; - struct gpioevent_data evdata; - //struct gpio_v2_line_request req2; - struct timeval tv_timenow; - unsigned long long timenow; - int finished = 0; - int initial_edge = 1; + struct gpio_v2_line_event evdata; + + if (wiringPiMode == WPI_MODE_PINS) + pin = pinToGpio [pin] ; + else if (wiringPiMode == WPI_MODE_PHYS) + pin = physToGpio [pin] ; - if (wiringPiDebug) { - printf ("waitForInterrupt: mS = %d, bouncetime = %d\n", mS, bouncetime) ; + if (waitForInterruptInit (pin, edgeMode, debounce_period_us ) != 0) + return -1 ; + + fd = isrFds[pin]; + // Setup poll structure + polls.fd = fd; + polls.events = POLLIN | POLLERR ; + polls.revents = 0; + + ret = (long long int)poll(&polls, 1, mS); + + if (ret < 0) { + if (wiringPiDebug) + fprintf(stderr, "wiringPi: ERROR: poll returned=%lld\n", ret); + } else if (ret == 0) { + if (wiringPiDebug) + fprintf(stderr, "wiringPi: timeout: poll returned=%lld\n", ret); } + else { + if (wiringPiDebug) + printf ("wiringPi: IRQ line %d received %lld, fd=%d\n", pin, ret, isrFds[pin]) ; + if (polls.revents & POLLIN) { + /* read event data */ + int readret = read(isrFds [pin], &evdata, sizeof(evdata)); + if (readret == sizeof(evdata)) { + if (wiringPiDebug) + printf ("wiringPi: IRQ at PIN: %d, timestamp: %lld\n", evdata.offset, evdata.timestamp_ns) ; + + switch (evdata.id) { + case GPIO_V2_LINE_EVENT_RISING_EDGE: + if (wiringPiDebug) + printf("wiringPi: rising edge\n"); + break; + case GPIO_V2_LINE_EVENT_FALLING_EDGE: + if (wiringPiDebug) + printf("wiringPi: falling edge\n"); + break; + default: + if (wiringPiDebug) + printf("wiringPi: unknown event\n"); + break; + } + ret = evdata.timestamp_ns / 1000LL; // nanoseconds u64 to microseconds + } + else { + ret = -1; + } + } + } + return ret; +} + + +int waitForInterruptClose (int pin) { + if (isrFds[pin]>0) { + if (wiringPiDebug) { + printf ("wiringPi: waitForInterruptClose close thread 0x%lX\n", (unsigned long)isrThreads[pin]) ; + } + if (isrThreads[pin] != 0) { + if (pthread_cancel(isrThreads[pin]) == 0) { + if (wiringPiDebug) { + printf ("wiringPi: waitForInterruptClose thread canceled successfuly\n") ; + } + } else { + if (wiringPiDebug) { + fprintf (stderr, "wiringPi: waitForInterruptClose could not cancel thread\n"); + } + } + } + close(isrFds [pin]); + } + isrFds [pin] = -1; + isrFunctions [pin] = NULL; + isrDebouncePeriodUs[pin] = 0; + + /* -not closing so far - other isr may be using it - only close if no other is using - will code later + if (chipFd>0) { + close(chipFd); + } + chipFd = -1; + */ + if (wiringPiDebug) { + printf ("wiringPi: waitForInterruptClose finished\n") ; + } + return 0; +} + + +/* + * wfi: + * Pi Specific. + * Wait for Interrupt on a GPIO pin, called from interruptHandler + * Returns timestamp in microseconds on interrupt + ********************************************************************************* + */ + +long long int wfi(int pin) +{ + long long int ret; + int fd; + struct pollfd polls ; + struct gpio_v2_line_event evdata; if (wiringPiMode == WPI_MODE_PINS) pin = pinToGpio [pin] ; @@ -2600,150 +2845,49 @@ long long int waitForInterrupt (int pin, int mS, int bouncetime) // bounctime i polls.events = POLLIN | POLLERR ; polls.revents = 0; - // Wait for it ... - while (!finished) { - ret = (long long int)poll(&polls, 1, mS); - if (ret < 0) { - if (wiringPiDebug) { - fprintf(stderr, "wiringPi: ERROR: poll returned=%lld\n", ret); + ret = (long long int)poll(&polls, 1, -1); // no timeout, wait forevver + + if (ret < 0) { + if (wiringPiDebug) + fprintf(stderr, "wiringPi: ERROR: poll returned=%lld\n", ret); + } else if (ret == 0) { + if (wiringPiDebug) + fprintf(stderr, "wiringPi: timeout: poll returned=%lld\n", ret); + } + else { + if (wiringPiDebug) + printf ("wiringPi: IRQ line %d received %lld, fd=%d\n", pin, ret, isrFds[pin]) ; + if (polls.revents & POLLIN) { + /* read event data */ + int readret = read(isrFds [pin], &evdata, sizeof(evdata)); + if (readret == sizeof(evdata)) { + if (wiringPiDebug) + printf ("wiringPi: IRQ at PIN: %d, timestamp: %lld\n", evdata.offset, evdata.timestamp_ns) ; + + switch (evdata.id) { + case GPIO_V2_LINE_EVENT_RISING_EDGE: + if (wiringPiDebug) + printf("wiringPi: rising edge\n"); + break; + case GPIO_V2_LINE_EVENT_FALLING_EDGE: + if (wiringPiDebug) + printf("wiringPi: falling edge\n"); + break; + default: + if (wiringPiDebug) + printf("wiringPi: unknown event\n"); + break; + } + ret = evdata.timestamp_ns / 1000LL; // nanoseconds u64 to microseconds } - break; - } else if (ret == 0) { - if (wiringPiDebug) { - fprintf(stderr, "wiringPi: timeout: poll returned=%lld\n", ret); - } - break; - } - else { - //if (polls.revents & POLLIN) - if (wiringPiDebug) { - printf ("wiringPi: IRQ line %d received %lld, fd=%d\n", pin, ret, isrFds[pin]) ; - } - if (initial_edge) { // first time triggers with current state, so ignore - initial_edge = 0; - } else { - /* read event data */ - 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) ; - } -// ret = evdata.id; - gettimeofday(&tv_timenow, NULL); - timenow = tv_timenow.tv_sec*1E6 + tv_timenow.tv_usec; - if (bouncetime == 0 || timenow - lastcall[pin] > (unsigned int)bouncetime*1000 || lastcall[pin] == 0 || lastcall[pin] > timenow) { - lastcall[pin] = timenow; - finished = 1; - ret = evdata.timestamp / 1000LL; // nanoseconds u64 to microseconds - } - } else { - ret = -1; - break; - } + else { + ret = -1; } } } return ret; } -int waitForInterruptInit (int pin, int mode) -{ - const char* strmode = ""; - - if (wiringPiMode == WPI_MODE_PINS) { - pin = pinToGpio [pin] ; - } else if (wiringPiMode == WPI_MODE_PHYS) { - pin = physToGpio [pin] ; - } - - /* open gpio */ - sleep(1); - if (wiringPiGpioDeviceGetFd()<0) { - return -1; - } - - struct gpioevent_request req; - req.lineoffset = pin; - req.handleflags = GPIOHANDLE_REQUEST_INPUT; - switch(mode) { - default: - case INT_EDGE_SETUP: - if (wiringPiDebug) { - printf ("wiringPi: waitForInterruptMode mode INT_EDGE_SETUP - exiting\n") ; - } - return -1; - case INT_EDGE_FALLING: - req.eventflags = GPIOEVENT_REQUEST_FALLING_EDGE; - strmode = "falling"; - break; - case INT_EDGE_RISING: - req.eventflags = GPIOEVENT_REQUEST_RISING_EDGE; - strmode = "rising"; - break; - case INT_EDGE_BOTH: - req.eventflags = GPIOEVENT_REQUEST_BOTH_EDGES; - strmode = "both"; - break; - } - strncpy(req.consumer_label, "wiringpi_gpio_irq", sizeof(req.consumer_label) - 1); - - //later implement GPIO_V2_GET_LINE_IOCTL req2 - int ret = ioctl(chipFd, GPIO_GET_LINEEVENT_IOCTL, &req); - if (ret) { - ReportDeviceError("get line event", pin , strmode, ret); - return -1; - } - if (wiringPiDebug) { - printf ("wiringPi: GPIO get line %d , mode %s succeded, fd=%d\n", pin, strmode, req.fd) ; - } - - /* set event fd nonbloack read */ - int fd_line = req.fd; - isrFds [pin] = fd_line; - int flags = fcntl(fd_line, F_GETFL); - flags |= O_NONBLOCK; - ret = fcntl(fd_line, F_SETFL, flags); - if (ret) { - fprintf(stderr, "wiringPi: ERROR: fcntl set nonblock return=%d\n", ret); - return -1; - } - - return 0; -} - - -int waitForInterruptClose (int pin) { - if (isrFds[pin]>0) { - if (wiringPiDebug) { - printf ("wiringPi: waitForInterruptClose close thread 0x%lX\n", (unsigned long)isrThreads[pin]) ; - } - if (isrThreads[pin] && pthread_cancel(isrThreads[pin]) == 0) { - if (wiringPiDebug) { - printf ("wiringPi: waitForInterruptClose thread canceled successfuly\n") ; - } - } else { - if (wiringPiDebug) { - fprintf (stderr, "wiringPi: waitForInterruptClose could not cancel thread\n"); - } - } - close(isrFds [pin]); - } - isrFds [pin] = -1; - isrFunctions [pin] = NULL; - lastcall[pin] = 0; - /* -not closing so far - other isr may be using it - only close if no other is using - will code later - if (chipFd>0) { - close(chipFd); - } - chipFd = -1; - */ - if (wiringPiDebug) { - printf ("wiringPi: waitForInterruptClose finished\n") ; - } - return 0; -} - - int wiringPiISRStop (int pin) { return waitForInterruptClose (pin); } @@ -2756,20 +2900,89 @@ int wiringPiISRStop (int pin) { ********************************************************************************* */ -static void *interruptHandler (void *arg) +void *interruptHandler (void *arg) { - int pin ; - int bouncetime; + const char* strmode = ""; + int pin, mode ; + unsigned long debounce_period_us; + struct gpio_v2_line_config config; + struct gpio_v2_line_request req; + int attr, ret; + + pin = *(int *)arg; + +/* pin = pinPass ; + pinPass = -1 ; +*/ + if (wiringPiGpioDeviceGetFd()<0) { + return NULL; + } + + mode = isrMode[pin]; + debounce_period_us = isrDebouncePeriodUs[pin]; + + if (wiringPiDebug) { + printf ("interruptHandler: GPIO line %d, mode %d, debounce_period_us %lu \n", pin, mode, debounce_period_us) ; + } + + memset(&req, 0, sizeof(req)); + memset(&config, 0, sizeof(config)); + + /* setup config */ + config.flags = GPIO_V2_LINE_FLAG_INPUT; + switch(mode) { + default: + case INT_EDGE_SETUP: + if (wiringPiDebug) { + printf ("wiringPi: waitForInterruptMode mode INT_EDGE_SETUP - exiting\n") ; + } + return NULL; + case INT_EDGE_FALLING: + config.flags |= GPIO_V2_LINE_FLAG_EDGE_FALLING; + strmode = "falling"; + break; + case INT_EDGE_RISING: + config.flags |= GPIO_V2_LINE_FLAG_EDGE_RISING; + strmode = "rising"; + break; + case INT_EDGE_BOTH: + config.flags |= (GPIO_V2_LINE_FLAG_EDGE_FALLING | GPIO_V2_LINE_FLAG_EDGE_RISING); + strmode = "both"; + break; + } + strcpy(req.consumer, "wiringpi_gpio_irq"); + + if (debounce_period_us) { + attr = config.num_attrs; + config.num_attrs++; + gpiotools_set_bit(&config.attrs[attr].mask, 0); + config.attrs[attr].attr.id = GPIO_V2_LINE_ATTR_ID_DEBOUNCE; + config.attrs[attr].attr.debounce_period_us = debounce_period_us; + } + + req.num_lines = 1; + req.offsets[0] = pin; + req.config = config; + + ret = ioctl(chipFd, GPIO_V2_GET_LINE_IOCTL, &req); + if (ret == -1) { + ReportDeviceError("get line event", pin , strmode, ret); + return NULL; + } +/* + if (wiringPiDebug) { + printf ("wiringPi: GPIO get line %d , mode %s succeded, fd=%d\n", pin, strmode, req.fd) ; + } +*/ + /* set event fd */ + int fd_line = req.fd; + isrFds [pin] = fd_line; (void)piHiPri (55) ; // Only effective if we run as root - pin = pinPass ; - bouncetime = *(int *)arg; - pinPass = -1 ; - for (;;) { - long long int ret = waitForInterrupt(pin, -1, bouncetime); - if ( ret> 0) { // return timestamp in microseconds + long long int ret = wfi(pin); // poll for event and return timestamp + if ( ret> 0) { // return timestamp in microseconds if (wiringPiDebug) { printf ("wiringPi: call function\n") ; } @@ -2795,10 +3008,11 @@ static void *interruptHandler (void *arg) * Pi Specific. * Take the details and create an interrupt handler that will do a call- * back to the user supplied function. + * debounce_period_us in microseconds ********************************************************************************* */ -int wiringPiISR (int pin, int mode, void (*function)(unsigned int, long long int), int bouncetime) +int wiringPiISR (int pin, int edgeMode, void (*function)(unsigned int, long long int), unsigned long debounce_period_us) { const int maxpin = GetMaxPin(); @@ -2806,22 +3020,24 @@ int wiringPiISR (int pin, int mode, void (*function)(unsigned int, long long int return wiringPiFailure (WPI_FATAL, "wiringPiISR: pin must be 0-%d (%d)\n", maxpin, pin) ; if (wiringPiMode == WPI_MODE_UNINITIALISED) return wiringPiFailure (WPI_FATAL, "wiringPiISR: wiringPi has not been initialised. Unable to continue.\n") ; + + if (wiringPiMode == WPI_MODE_PINS) { + pin = pinToGpio [pin] ; + } else if (wiringPiMode == WPI_MODE_PHYS) { + pin = physToGpio [pin] ; + } + if (wiringPiDebug) { - printf ("wiringPi: wiringPiISR pin %d, mode %d\n", pin, mode) ; + printf ("wiringPi: wiringPiISR pin %d, edgeMode %d\n", pin, edgeMode) ; } if (isrFunctions [pin]) { - printf ("wiringPi: ISR function alread active, ignoring \n") ; + printf ("wiringPi: ISR function already active, ignoring \n") ; } isrFunctions [pin] = function ; - isrMode[pin] = mode; - lastcall[pin] = 0; - if(waitForInterruptInit (pin, mode)<0) { - if (wiringPiDebug) { - fprintf (stderr, "wiringPi: waitForInterruptInit failed\n") ; - } - } - + isrMode[pin] = edgeMode; + isrDebouncePeriodUs[pin] = debounce_period_us; + if (wiringPiDebug) { printf ("wiringPi: mutex in\n") ; } @@ -2830,12 +3046,17 @@ int wiringPiISR (int pin, int mode, void (*function)(unsigned int, long long int if (wiringPiDebug) { printf("wiringPi: pthread_create before 0x%lX\n", (unsigned long)isrThreads[pin]); } - if (pthread_create (&isrThreads[pin], NULL, interruptHandler, &bouncetime)==0) { + if (pthread_create (&isrThreads[pin], NULL, interruptHandler, &pin)==0) { if (wiringPiDebug) { printf("wiringPi: pthread_create successed, 0x%lX\n", (unsigned long)isrThreads[pin]); } - while (pinPass != -1) - delay (1) ; +/* while (pinPass != -1) + delay (1) ; */ + // wait so that interruptHandler is up und running. + // when interruptHandler is running, the calling function wiringPiISR + // must be still alive, otherwise the thread argument &pin points into nirwana, + // when it is picked up from interruptHandler. + delay (10); } else { if (wiringPiDebug) { printf("wiringPi: pthread_create failed\n"); @@ -3187,12 +3408,12 @@ int wiringPiSetup (void) /**/ if (piGpioLayout () == GPIO_LAYOUT_PI1_REV1) // A, B, Rev 1, 1.1 { - pinToGpio = pinToGpioR1 ; + pinToGpio = pinToGpioR1 ; physToGpio = physToGpioR1 ; } else // A2, B2, A+, B+, CM, Pi2, Pi3, Zero, Zero W, Zero 2 W { - pinToGpio = pinToGpioR2 ; + pinToGpio = pinToGpioR2 ; physToGpio = physToGpioR2 ; } @@ -3201,7 +3422,7 @@ int wiringPiSetup (void) // Try /dev/mem. If that fails, then // try /dev/gpiomem. If that fails then game over. - const char* gpiomemGlobal = gpiomem_global; + const char* gpiomemGlobal = gpiomem_global; const char* gpiomemModule = gpiomem_BCM; if (PI_MODEL_5 == model) { @@ -3242,7 +3463,7 @@ int wiringPiSetup (void) printf ("wiringPi: access to %s succeded %d\n", usingGpioMem ? gpiomemModule : gpiomemGlobal, fd) ; } // GPIO: - if (PI_MODEL_5 != model) { + if (PI_MODEL_5 != model) { //Set the offsets into the memory interface. GPIO_PADS = piGpioBase + 0x00100000 ; diff --git a/wiringPi/wiringPi.h b/wiringPi/wiringPi.h index 7659d84..e7cbfb6 100644 --- a/wiringPi/wiringPi.h +++ b/wiringPi/wiringPi.h @@ -289,11 +289,11 @@ extern void digitalWriteByte2 (int value) ; // Interrupts // (Also Pi hardware specific) -extern long long int waitForInterrupt (int pin, int mS, int bouncetime) ; -extern int wiringPiISR (int pin, int mode, void (*function)(unsigned int, long long int), int bouncetime) ; +extern long long int waitForInterrupt (int pin, int edgeMode, int mS, unsigned long debounce_period_us) ; +extern int wiringPiISR (int pin, int mode, void (*function)(unsigned int, long long int), unsigned long debounce_period_us) ; extern int wiringPiISRStop (int pin) ; //V3.2 extern int waitForInterruptClose(int pin) ; //V3.2 -extern int waitForInterruptInit (int pin, int mode); //v3.2 +// extern int waitForInterruptInit (int pin, int mode); //v3.2 // Threads From 9e105d1bb4a8169d0c61b045844674fd1ccb551a Mon Sep 17 00:00:00 2001 From: phylax2020 Date: Tue, 11 Feb 2025 16:11:41 +0100 Subject: [PATCH 16/65] functions.md --- documentation/deutsch/functions.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/documentation/deutsch/functions.md b/documentation/deutsch/functions.md index fbfc431..0267556 100644 --- a/documentation/deutsch/functions.md +++ b/documentation/deutsch/functions.md @@ -295,6 +295,7 @@ int wiringPiISR(int pin, int edgeMode, void (*function)(unsigned int, long long ``` ``pin``: Der gewünschte Pin (BCM\-, WiringPi\- oder Pin\-Nummer). + ``edgeMode``: Auslösende Flankenmodus - INT_EDGE_RISING ... Steigende Flanke - INT_EDGE_FALLING ... Fallende Flanke @@ -338,14 +339,17 @@ long long int waitForInterrupt (int pin, int edgeMode, int mS, unsigned long bo ``` ``pin``: Der gewünschte Pin (BCM\-, WiringPi\- oder Pin\-Nummer). + ``edgeMode``: Auslösende Flankenmodus - INT_EDGE_RISING ... Steigende Flanke - INT_EDGE_FALLING ... Fallende Flanke - INT_EDGE_BOTH ... Steigende und fallende Flanke + ``mS``: Timeout in Milisekunden. - \-1 warten ohne timeout - 0 wartet nicht - 1...n wartet maximal n mS Millisekunden + ``bouncetime``: Entprellzeit in Microsekunden, 0 schaltet Entprellen ab. ``Rückgabewert``: From a261ceb485acc55504d7af2a684aba77703d625f Mon Sep 17 00:00:00 2001 From: phylax2020 Date: Tue, 11 Feb 2025 20:01:41 +0100 Subject: [PATCH 17/65] Pi500/CM5 support --- wiringPi/wiringPi.c | 75 ++++++++++++++++++++++++++++----------------- wiringPi/wiringPi.h | 67 ++++++++++++++++++++++------------------ 2 files changed, 85 insertions(+), 57 deletions(-) diff --git a/wiringPi/wiringPi.c b/wiringPi/wiringPi.c index 1dafed5..28bec24 100644 --- a/wiringPi/wiringPi.c +++ b/wiringPi/wiringPi.c @@ -141,6 +141,8 @@ struct wiringPiNodeStruct *wiringPiNodes = NULL ; #define RP1_FSEL_NONE 0x09 #define RP1_FSEL_NONE_HW 0x1f //default, mask +// maybe faster then piRP1Model +#define ISRP1MODEL (PI_MODEL_5==RaspberryPiModel || PI_MODEL_CM5==RaspberryPiModel|| PI_MODEL_500==RaspberryPiModel || PI_MODEL_CM5L==RaspberryPiModel) //RP1 chip (@Pi5) RIO address const unsigned int RP1_RIO_OUT = 0x0000; const unsigned int RP1_RIO_OE = (0x0004/4); @@ -337,7 +339,7 @@ volatile unsigned int *_wiringPiRio ; static volatile unsigned int piGpioBase = 0 ; -const char *piModelNames [24] = +const char *piModelNames [PI_MODELS_MAX] = { "Model A", // 0 "Model B", // 1 @@ -363,6 +365,9 @@ const char *piModelNames [24] = "CM4S", // 21 "Unknown22", // 22 "Pi 5", // 23 + "CM5", // 24 + "Pi 500", // 25 + "CM5 Lite", // 26 } ; const char *piProcessor [5] = @@ -396,10 +401,10 @@ const char *piRevisionNames [16] = const char *piMakerNames [16] = { - "Sony", // 0 + "Sony UK",// 0 "Egoman", // 1 "Embest", // 2 - "Unknown",// 3 + "Sony Japan",// 3 "Embest", // 4 "Stadium",// 5 "Unknown06", // 6 @@ -422,7 +427,7 @@ const int piMemorySize [8] = 2048, // 3 4096, // 4 8192, // 5 - 0, // 6 + 16384, // 6 0, // 7 } ; @@ -629,16 +634,27 @@ int piBoard40Pin() { } } +int piRP1Model() { + switch(RaspberryPiModel){ + case PI_MODEL_5: + case PI_MODEL_CM5: + case PI_MODEL_500: + case PI_MODEL_CM5L: + return 1; + default: + return 0; + } +} int GetMaxPin() { - return PI_MODEL_5 == RaspberryPiModel ? 27 : 63; + return piRP1Model() ? 27 : 63; } -#define RETURN_ON_MODEL5 if (PI_MODEL_5 == RaspberryPiModel) { if (wiringPiDebug) printf("Function not supported on Pi5\n"); return; } +#define RETURN_ON_MODEL5 if (piRP1Model()) { if (wiringPiDebug) printf("Function not supported on Pi5\n"); return; } int FailOnModel5(const char *function) { - if (PI_MODEL_5 == RaspberryPiModel) { + if (piRP1Model()) { return wiringPiFailure (WPI_ALMOST, "Function '%s' not supported on Raspberry Pi 5.\n" " Unable to continue. Keep an eye of new versions at https://github.com/wiringpi/wiringpi\n", function) ; } @@ -1210,6 +1226,9 @@ void piBoardId (int *model, int *rev, int *mem, int *maker, int *warranty) break ; case PI_MODEL_5: + case PI_MODEL_CM5: + case PI_MODEL_500: + case PI_MODEL_CM5L: piGpioBase = GPIO_PERI_BASE_2712 ; piGpioPupOffset = 0 ; break ; @@ -1255,7 +1274,7 @@ int physPinToGpio (int physPin) ********************************************************************************* */ void setPadDrivePin (int pin, int value) { - if (PI_MODEL_5 != RaspberryPiModel) return; + if (!piRP1Model()) return; if (pin < 0 || pin > GetMaxPin()) return ; uint32_t wrVal; @@ -1275,7 +1294,7 @@ void setPadDrive (int group, int value) if ((wiringPiMode == WPI_MODE_PINS) || (wiringPiMode == WPI_MODE_PHYS) || (wiringPiMode == WPI_MODE_GPIO)) { value = value & 7; // 0-7 supported - if (PI_MODEL_5 == RaspberryPiModel) { + if (piRP1Model()) { if (-1==group) { printf ("Pad register:\n"); for (int pin=0, maxpin=GetMaxPin(); pin<=maxpin; ++pin) { @@ -1346,7 +1365,7 @@ int getAlt (int pin) else if (wiringPiMode != WPI_MODE_GPIO) return 0 ; - if (PI_MODEL_5 == RaspberryPiModel) { + if (piRP1Model()) { alt = (gpio[2*pin+1] & RP1_FSEL_NONE_HW); //0-4 function /* @@ -1406,7 +1425,7 @@ void pwmSetMode (int mode) { if ((wiringPiMode == WPI_MODE_PINS) || (wiringPiMode == WPI_MODE_PHYS) || (wiringPiMode == WPI_MODE_GPIO)) { - if (PI_MODEL_5 == RaspberryPiModel) { + if (piRP1Model()) { if(mode != PWM_MODE_MS) { fprintf(stderr, "pwmSetMode: Raspberry Pi 5 missing feature PWM BAL mode\n"); } @@ -1445,7 +1464,7 @@ void pwmSetRange (unsigned int range) return; } int readback = 0x00; - if (PI_MODEL_5 == RaspberryPiModel) { + if (piRP1Model()) { pwm[RP1_PWM0_CHAN0_RANGE] = range; pwm[RP1_PWM0_CHAN1_RANGE] = range; pwm[RP1_PWM0_CHAN2_RANGE] = range; @@ -1482,7 +1501,7 @@ void pwmSetClock (int divisor) if (divisor > PWMCLK_DIVI_MAX) { divisor = PWMCLK_DIVI_MAX; // even on Pi5 4095 is OK } - if (PI_MODEL_5 == RaspberryPiModel) { + if (piRP1Model()) { if (divisor < 1) { if (wiringPiDebug) { printf("Disable PWM0 clock"); } clk[CLK_PWM0_CTRL] = RP1_CLK_PWM0_CTRL_DISABLE_MAGIC; // 0 = disable on Pi5 @@ -1717,7 +1736,7 @@ int OpenAndCheckGpioChip(int GPIONo, const char* label, const unsigned int lines int wiringPiGpioDeviceGetFd() { if (chipFd<0) { piBoard(); - if (PI_MODEL_5 == RaspberryPiModel) { + if (piRP1Model()) { chipFd = OpenAndCheckGpioChip(0, "rp1", 54); // /dev/gpiochip0 @ Pi5 since Kernel 6.6.47 if (chipFd<0) { chipFd = OpenAndCheckGpioChip(4, "rp1", 54); // /dev/gpiochip4 @ Pi5 with older kernel @@ -1808,7 +1827,7 @@ void pinModeAlt (int pin, int mode) else if (wiringPiMode != WPI_MODE_GPIO) return ; - if (PI_MODEL_5 == RaspberryPiModel) { + if (piRP1Model()) { //confusion! diffrent to to BCM! this is taking directly the value for the register int modeRP1; switch(mode) { @@ -1947,7 +1966,7 @@ void pinMode (int pin, int mode) shift = gpioToShift [pin] ; if (INPUT==mode || PM_OFF==mode) { - if (PI_MODEL_5 == RaspberryPiModel) { + if (piRP1Model()) { if (INPUT==mode) { pads[1+pin] = (pin<=8) ? RP1_PAD_DEFAULT_0TO8 : RP1_PAD_DEFAULT_FROM9; gpio[2*pin+1] = RP1_FSEL_GPIO | RP1_DEBOUNCE_DEFAULT; // GPIO @@ -1962,14 +1981,14 @@ void pinMode (int pin, int mode) if (PM_OFF==mode && !usingGpioMem && pwm && gpioToPwmALT[pin]>0) { //PWM pin -> reset pwmWrite(origPin, 0); int channel = gpioToPwmPort[pin]; - if (channel>=0 && channel<=3 && PI_MODEL_5 == RaspberryPiModel) { + if (channel>=0 && channel<=3 && piRP1Model()) { unsigned int ctrl = pwm[RP1_PWM0_GLOBAL_CTRL]; pwm[RP1_PWM0_GLOBAL_CTRL] = (ctrl & ~(1<0x%08X)\n", channel, ctrl, pwm[RP1_PWM0_GLOBAL_CTRL]); } } } else if (mode == OUTPUT) { - if (PI_MODEL_5 == RaspberryPiModel) { + if (piRP1Model()) { pads[1+pin] = (pin<=8) ? RP1_PAD_DEFAULT_0TO8 : RP1_PAD_DEFAULT_FROM9; gpio[2*pin+1] = RP1_FSEL_GPIO | RP1_DEBOUNCE_DEFAULT; // GPIO rio[RP1_RIO_OE + RP1_SET_OFFSET] = 1<=0 && channel<=3) { // enable channel pwm m:s mode pwm[RP1_PWM0_CHAN_START+RP1_PWM0_CHAN_OFFSET*channel+RP1_PWM0_CHAN_CTRL] = (RP1_PWM_TRAIL_EDGE_MS | RP1_PWM_FIFO_POP_MASK); @@ -2101,7 +2120,7 @@ void pullUpDnControl (int pin, int pud) break; } - if (PI_MODEL_5 == RaspberryPiModel) { + if (piRP1Model()) { unsigned int pullbits = pads[1+pin] & RP1_INV_PUD_MASK; // remove bits switch (pud){ case PUD_OFF: pads[1+pin] = pullbits; break; @@ -2233,7 +2252,7 @@ int digitalRead (int pin) break; } - if (PI_MODEL_5 == RaspberryPiModel) { + if (ISRP1MODEL) { switch(gpio[2*pin] & RP1_STATUS_LEVEL_MASK) { default: // 11 or 00 not allowed, give LOW! case RP1_STATUS_LEVEL_LOW: return LOW ; @@ -2341,7 +2360,7 @@ void digitalWrite (int pin, int value) break; } - if (PI_MODEL_5 == RaspberryPiModel) { + if (ISRP1MODEL) { if (value == LOW) { //printf("Set pin %d >>0x%08x<< to low\n", pin, 1<=0 && channel<=3) { unsigned int addr = RP1_PWM0_CHAN_START+RP1_PWM0_CHAN_OFFSET*channel+RP1_PWM0_CHAN_DUTY; pwm[addr] = value; @@ -3249,7 +3268,7 @@ int wiringPiUserLevelAccess(void) const char* gpiomemModule = gpiomem_BCM; piBoard(); - if (PI_MODEL_5 == RaspberryPiModel) { + if (piRP1Model()) { gpiomemModule = gpiomem_RP1; } @@ -3316,7 +3335,7 @@ int wiringPiGlobalMemoryAccess(void) unsigned int BaseAddr, PWMAddr; piBoard(); - if (PI_MODEL_5 == RaspberryPiModel) { + if (piRP1Model()) { GetRP1Memory(pciemem_RP1, sizeof(pciemem_RP1)); gpiomemGlobal = pciemem_RP1; MMAP_size = pciemem_RP1_Size; @@ -3339,7 +3358,7 @@ int wiringPiGlobalMemoryAccess(void) 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) { + if (piRP1Model()) { returnvalue = 2; // GPIO & PWM accessible (same area, nothing to mmap) } else { //check PWM area @@ -3425,7 +3444,7 @@ int wiringPiSetup (void) const char* gpiomemGlobal = gpiomem_global; const char* gpiomemModule = gpiomem_BCM; - if (PI_MODEL_5 == model) { + if (piRP1Model()) { GetRP1Memory(); gpiomemGlobal = pciemem_RP1; gpiomemModule = gpiomem_RP1; @@ -3463,7 +3482,7 @@ int wiringPiSetup (void) printf ("wiringPi: access to %s succeded %d\n", usingGpioMem ? gpiomemModule : gpiomemGlobal, fd) ; } // GPIO: - if (PI_MODEL_5 != model) { + if (!piRP1Model()) { //Set the offsets into the memory interface. GPIO_PADS = piGpioBase + 0x00100000 ; diff --git a/wiringPi/wiringPi.h b/wiringPi/wiringPi.h index e7cbfb6..0b980e3 100644 --- a/wiringPi/wiringPi.h +++ b/wiringPi/wiringPi.h @@ -1,7 +1,7 @@ /* * wiringPi.h: * Arduino like Wiring library for the Raspberry Pi. - * Copyright (c) 2012-2017 Gordon Henderson + * Copyright (c) 2012-2025 Gordon Henderson *********************************************************************** * This file is part of wiringPi: * https://github.com/WiringPi/WiringPi/ @@ -93,35 +93,44 @@ // Pi model types and version numbers // Intended for the GPIO program Use at your own risk. // https://www.raspberrypi.com/documentation/computers/raspberry-pi.html#new-style-revision-codes +// https://github.com/raspberrypi/documentation/blob/develop/documentation/asciidoc/computers/raspberry-pi/revision-codes.adoc -#define PI_MODEL_A 0 -#define PI_MODEL_B 1 -#define PI_MODEL_AP 2 -#define PI_MODEL_BP 3 -#define PI_MODEL_2 4 -#define PI_ALPHA 5 -#define PI_MODEL_CM 6 -#define PI_MODEL_07 7 -#define PI_MODEL_3B 8 -#define PI_MODEL_ZERO 9 -#define PI_MODEL_CM3 10 -#define PI_MODEL_ZERO_W 12 -#define PI_MODEL_3BP 13 -#define PI_MODEL_3AP 14 -#define PI_MODEL_CM3P 16 -#define PI_MODEL_4B 17 -#define PI_MODEL_ZERO_2W 18 -#define PI_MODEL_400 19 -#define PI_MODEL_CM4 20 -#define PI_MODEL_CM4S 21 -#define PI_MODEL_5 23 +#define PI_MODEL_A 0 +#define PI_MODEL_B 1 +#define PI_MODEL_AP 2 +#define PI_MODEL_BP 3 +#define PI_MODEL_2 4 +#define PI_ALPHA 5 +#define PI_MODEL_CM 6 -#define PI_VERSION_1 0 +#define PI_MODEL_3B 8 +#define PI_MODEL_ZERO 9 +#define PI_MODEL_CM3 10 + +#define PI_MODEL_ZERO_W 12 +#define PI_MODEL_3BP 13 +#define PI_MODEL_3AP 14 + +#define PI_MODEL_CM3P 16 +#define PI_MODEL_4B 17 +#define PI_MODEL_ZERO_2W 18 +#define PI_MODEL_400 19 +#define PI_MODEL_CM4 20 +#define PI_MODEL_CM4S 21 + +#define PI_MODEL_5 23 +#define PI_MODEL_CM5 24 +#define PI_MODEL_500 25 +#define PI_MODEL_CM5L 26 + +#define PI_MODELS_MAX 27 + +#define PI_VERSION_1 0 #define PI_VERSION_1_1 1 #define PI_VERSION_1_2 2 -#define PI_VERSION_2 3 +#define PI_VERSION_2 3 -#define PI_MAKER_SONY 0 +#define PI_MAKER_SONY 0 #define PI_MAKER_EGOMAN 1 #define PI_MAKER_EMBEST 2 #define PI_MAKER_UNKNOWN 3 @@ -129,7 +138,7 @@ #define GPIO_LAYOUT_PI1_REV1 1 //Pi 1 A/B Revision 1, 1.1, CM #define GPIO_LAYOUT_DEFAULT 2 -extern const char *piModelNames [24] ; +extern const char *piModelNames [PI_MODELS_MAX] ; extern const char *piProcessor [ 5] ; extern const char *piRevisionNames [16] ; extern const char *piMakerNames [16] ; @@ -271,6 +280,7 @@ extern int piGpioLayout (void) ; extern int piBoardRev (void) ; // Deprecated, but does the same as piGpioLayout extern void piBoardId (int *model, int *rev, int *mem, int *maker, int *overVolted) ; extern int piBoard40Pin (void) ; // Interface V3.7 +extern int piRP1Model (void) ; // Interface V3.14 extern int wpiPinToGpio (int wpiPin) ; extern int physPinToGpio (int physPin) ; extern void setPadDrive (int group, int value) ; @@ -289,11 +299,10 @@ extern void digitalWriteByte2 (int value) ; // Interrupts // (Also Pi hardware specific) -extern long long int waitForInterrupt (int pin, int edgeMode, int mS, unsigned long debounce_period_us) ; -extern int wiringPiISR (int pin, int mode, void (*function)(unsigned int, long long int), unsigned long debounce_period_us) ; +extern long long int waitForInterrupt (int pin, int edgeMode, int mS, unsigned long debounce_period_us) ; // V3.14 phylax +extern int wiringPiISR (int pin, int mode, void (*function)(unsigned int, long long int), unsigned long debounce_period_us) ; // v3.14 phylax extern int wiringPiISRStop (int pin) ; //V3.2 extern int waitForInterruptClose(int pin) ; //V3.2 -// extern int waitForInterruptInit (int pin, int mode); //v3.2 // Threads From a7e20b8bf7e2c63b26f991ab450f161bbf525b85 Mon Sep 17 00:00:00 2001 From: phylax2020 Date: Sun, 16 Feb 2025 22:53:08 +0100 Subject: [PATCH 18/65] wiringPi.c : memory leak in wiringPiISR and wiringPiISRStop fixed --- VERSION | 2 +- version.h | 4 +- wiringPi/wiringPi.c | 203 ++++++++++++++++++++------------------------ 3 files changed, 95 insertions(+), 114 deletions(-) diff --git a/VERSION b/VERSION index 3767b4b..230693c 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -3.14 \ No newline at end of file +3.15 \ No newline at end of file diff --git a/version.h b/version.h index c2da282..d7f42c6 100644 --- a/version.h +++ b/version.h @@ -1,3 +1,3 @@ -#define VERSION "3.14" +#define VERSION "3.15" #define VERSION_MAJOR 3 -#define VERSION_MINOR 14 +#define VERSION_MINOR 15 diff --git a/wiringPi/wiringPi.c b/wiringPi/wiringPi.c index 28bec24..ba684ea 100644 --- a/wiringPi/wiringPi.c +++ b/wiringPi/wiringPi.c @@ -75,6 +75,7 @@ #include #include #include +#include #include "softPwm.h" #include "softTone.h" @@ -2800,21 +2801,35 @@ long long int waitForInterrupt (int pin, int edgeMode, int mS, unsigned long deb return ret; } +/* + * waitForInterruptClose: + * wait for thread interruptHandler to be stopped. + * close isrFds[pin], reset isrFds[pin], isrFunction[pin] and isrDebouncePeriodUs[pin] + * + ********************************************************************************* + */ int waitForInterruptClose (int pin) { - if (isrFds[pin]>0) { - if (wiringPiDebug) { - printf ("wiringPi: waitForInterruptClose close thread 0x%lX\n", (unsigned long)isrThreads[pin]) ; - } + void *res; + + if (isrFds[pin] > 0) { + if (wiringPiDebug) + printf ("waitForInterruptClose: close thread 0x%lX\n", (unsigned long)isrThreads[pin]) ; + if (isrThreads[pin] != 0) { if (pthread_cancel(isrThreads[pin]) == 0) { - if (wiringPiDebug) { - printf ("wiringPi: waitForInterruptClose thread canceled successfuly\n") ; + pthread_join(isrThreads[pin], &res); + if (res == PTHREAD_CANCELED) { + if (wiringPiDebug) + printf("waitForInterruptClose: thread was canceled\n"); + } + else { + if (wiringPiDebug) + printf("waitForInterruptClose: thread was not canceled\n"); } } else { - if (wiringPiDebug) { - fprintf (stderr, "wiringPi: waitForInterruptClose could not cancel thread\n"); - } + if (wiringPiDebug) + printf ("waitForInterruptClose: waitForInterruptClose could not cancel thread\n"); } } close(isrFds [pin]); @@ -2830,87 +2845,23 @@ int waitForInterruptClose (int pin) { chipFd = -1; */ if (wiringPiDebug) { - printf ("wiringPi: waitForInterruptClose finished\n") ; + printf ("waitForInterruptClose: waitForInterruptClose finished\n") ; } return 0; } - /* - * wfi: - * Pi Specific. - * Wait for Interrupt on a GPIO pin, called from interruptHandler - * Returns timestamp in microseconds on interrupt + * wiringPiISRStop: + * stop thread interruptHandler + * ********************************************************************************* */ -long long int wfi(int pin) -{ - long long int ret; - int fd; - struct pollfd polls ; - struct gpio_v2_line_event evdata; - - if (wiringPiMode == WPI_MODE_PINS) - pin = pinToGpio [pin] ; - else if (wiringPiMode == WPI_MODE_PHYS) - pin = physToGpio [pin] ; - - if ((fd = isrFds [pin]) == -1) - return -2 ; - - // Setup poll structure - polls.fd = fd; - polls.events = POLLIN | POLLERR ; - polls.revents = 0; - - ret = (long long int)poll(&polls, 1, -1); // no timeout, wait forevver - - if (ret < 0) { - if (wiringPiDebug) - fprintf(stderr, "wiringPi: ERROR: poll returned=%lld\n", ret); - } else if (ret == 0) { - if (wiringPiDebug) - fprintf(stderr, "wiringPi: timeout: poll returned=%lld\n", ret); - } - else { - if (wiringPiDebug) - printf ("wiringPi: IRQ line %d received %lld, fd=%d\n", pin, ret, isrFds[pin]) ; - if (polls.revents & POLLIN) { - /* read event data */ - int readret = read(isrFds [pin], &evdata, sizeof(evdata)); - if (readret == sizeof(evdata)) { - if (wiringPiDebug) - printf ("wiringPi: IRQ at PIN: %d, timestamp: %lld\n", evdata.offset, evdata.timestamp_ns) ; - - switch (evdata.id) { - case GPIO_V2_LINE_EVENT_RISING_EDGE: - if (wiringPiDebug) - printf("wiringPi: rising edge\n"); - break; - case GPIO_V2_LINE_EVENT_FALLING_EDGE: - if (wiringPiDebug) - printf("wiringPi: falling edge\n"); - break; - default: - if (wiringPiDebug) - printf("wiringPi: unknown event\n"); - break; - } - ret = evdata.timestamp_ns / 1000LL; // nanoseconds u64 to microseconds - } - else { - ret = -1; - } - } - } - return ret; -} - int wiringPiISRStop (int pin) { return waitForInterruptClose (pin); } + /* * interruptHandler: * This is a thread and gets started to wait for the interrupt we're @@ -2922,17 +2873,17 @@ int wiringPiISRStop (int pin) { void *interruptHandler (void *arg) { const char* strmode = ""; - int pin, mode ; + int pin, mode, ret, fd, attr, i; + unsigned int readret; unsigned long debounce_period_us; + struct pollfd polls ; struct gpio_v2_line_config config; struct gpio_v2_line_request req; - int attr, ret; + struct gpio_v2_line_event evdat[64]; + struct timespec tspec = {0, 1e6}; /* 0.5 ms timeout {0, 5e5} */ pin = *(int *)arg; - -/* pin = pinPass ; - pinPass = -1 ; -*/ + if (wiringPiGpioDeviceGetFd()<0) { return NULL; } @@ -2953,7 +2904,7 @@ void *interruptHandler (void *arg) default: case INT_EDGE_SETUP: if (wiringPiDebug) { - printf ("wiringPi: waitForInterruptMode mode INT_EDGE_SETUP - exiting\n") ; + printf ("interruptHandler: waitForInterruptMode mode INT_EDGE_SETUP - exiting\n") ; } return NULL; case INT_EDGE_FALLING: @@ -2980,45 +2931,75 @@ void *interruptHandler (void *arg) } req.num_lines = 1; + req.event_buffer_size = 45; req.offsets[0] = pin; req.config = config; ret = ioctl(chipFd, GPIO_V2_GET_LINE_IOCTL, &req); if (ret == -1) { - ReportDeviceError("get line event", pin , strmode, ret); + ReportDeviceError("interruptHandler: get line event", pin , strmode, ret); return NULL; } -/* - if (wiringPiDebug) { - printf ("wiringPi: GPIO get line %d , mode %s succeded, fd=%d\n", pin, strmode, req.fd) ; - } -*/ + + if (wiringPiDebug) + printf ("interruptHandler: GPIO get line %d , mode %s succeded, fd=%d\n", pin, strmode, req.fd) ; + /* set event fd */ - int fd_line = req.fd; - isrFds [pin] = fd_line; + fd = req.fd; + isrFds [pin] = fd; (void)piHiPri (55) ; // Only effective if we run as root - for (;;) { - long long int ret = wfi(pin); // poll for event and return timestamp - if ( ret> 0) { // return timestamp in microseconds - if (wiringPiDebug) { - printf ("wiringPi: call function\n") ; - } - if(isrFunctions [pin]) { - isrFunctions [pin] ((unsigned int)pin, ret) ; - } - // wait again - in the past forever - now can be stopped by waitForInterruptClose - } else if( ret< 0) { - break; // stop thread! + for (;;) { // check if event data is available, check if interruptHandler thread must be canceled + + // Setup poll structure + polls.fd = fd; + polls.events = POLLIN | POLLPRI;; + polls.revents = 0; + + // get event data, this is also a cancelation point, when pthread_cancel is called + ret = ppoll(&polls, 1, &tspec, NULL); // returns -1 on error, 0 on timeout, >0 number of elements + + if (ret < 0) { // we do not reach this point if canceled, ppoll does not return, is Cancellation Point + if (wiringPiDebug) + printf("interruptHandler: ERROR: poll returned=%d\n", ret); + pthread_exit(NULL); + return NULL; // never landing here + } else if (ret == 0) { +// if (wiringPiDebug) +// printf("interruptHandler: timeout: poll returned=%d\n", ret); + continue; + } + else { + if (wiringPiDebug) + printf ("interruptHandler: IRQ line %d received %d events, fd=%d\n", pin, ret, isrFds[pin]) ; + if (polls.revents & POLLIN) { + /* read event data */ + readret = read(fd, &evdat, sizeof(evdat)); + if (readret >= sizeof(evdat[0])) { + if (wiringPiDebug) + printf ("interruptHandler: IRQ at PIN: %d, events: %u\n", evdat[0].offset, readret/(unsigned int)sizeof(evdat[0])) ; + + ret = readret/sizeof(evdat[0]); // number of events read from fd + if (wiringPiDebug) + printf ("interruptHandler: call function\n") ; + for (i = 0; i < ret; ++i) { + if (isrFunctions [pin]) { + if (wiringPiDebug) + printf( "interruptHandler: GPIO EVENT at %" PRIu64 " on line %d (%d|%d) \n", (uint64_t)evdat[i].timestamp_ns, evdat[i].offset, evdat[i].line_seqno, evdat[i].seqno); + isrFunctions [pin] ((unsigned int)pin, evdat[i].timestamp_ns/1000LL) ; + } + } + } + else { // if thread canceled we do not reach this point, read(...) does not return, is Cancellation Point + if (wiringPiDebug) + printf ("interruptHandler: reading events from fd received signal, exit thread\n"); + pthread_exit(NULL); + return NULL; // never landing here + } + } } } - - waitForInterruptClose (pin); - if (wiringPiDebug) { - printf ("wiringPi: interruptHandler finished\n") ; - } - return NULL ; } From 3c3b69c88842a4101eee9a590a09a136cb9e9e64 Mon Sep 17 00:00:00 2001 From: phylax2020 Date: Sun, 16 Feb 2025 23:02:24 +0100 Subject: [PATCH 19/65] wiringPi.c : memory leak in wiringPiISR and wiringPiISRStop fixed --- wiringPi/wiringPi.c | 1 - 1 file changed, 1 deletion(-) diff --git a/wiringPi/wiringPi.c b/wiringPi/wiringPi.c index f0438d4..ba684ea 100644 --- a/wiringPi/wiringPi.c +++ b/wiringPi/wiringPi.c @@ -144,7 +144,6 @@ struct wiringPiNodeStruct *wiringPiNodes = NULL ; // maybe faster then piRP1Model #define ISRP1MODEL (PI_MODEL_5==RaspberryPiModel || PI_MODEL_CM5==RaspberryPiModel|| PI_MODEL_500==RaspberryPiModel || PI_MODEL_CM5L==RaspberryPiModel) - //RP1 chip (@Pi5) RIO address const unsigned int RP1_RIO_OUT = 0x0000; const unsigned int RP1_RIO_OE = (0x0004/4); From 04dc08e511ead3a6d41b72240aab7185b5e4e43a Mon Sep 17 00:00:00 2001 From: phylax2020 Date: Mon, 17 Feb 2025 12:23:11 +0100 Subject: [PATCH 20/65] wiringPi.c: waitForInterrupt rewritten --- documentation/deutsch/functions.md | 7 +- wiringPi/wiringPi.c | 104 ++++++++++++----------------- 2 files changed, 44 insertions(+), 67 deletions(-) diff --git a/documentation/deutsch/functions.md b/documentation/deutsch/functions.md index 0267556..82e94f8 100644 --- a/documentation/deutsch/functions.md +++ b/documentation/deutsch/functions.md @@ -20,13 +20,13 @@ sudo apt install git git clone https://github.com/WiringPi/WiringPi.git cd WiringPi ./build debian -mv debian-template/wiringpi-3.13.deb . +mv debian-template/wiringpi-3.1x.deb . ``` **Debian-Paket installieren:** ```bash -sudo apt install ./wiringpi-3.13.deb +sudo apt install ./wiringpi-3.1x.deb ``` **Debian-Paket deinstallieren:** @@ -445,17 +445,14 @@ int main (void) ret = waitForInterrupt(IRQpin, INT_EDGE_FALLING, TIMEOUT, BOUNCETIME_WFI ); if (ret < 0) { printf("waitForInterrupt returned error %lld\n", ret); - wiringPiISRStop (IRQpin) ; pinMode(OUTpin, INPUT); return 0; } else if (ret == 0) { printf("waitForInterrupt timed out %lld\n\n", ret); - wiringPiISRStop (IRQpin) ; } else { printf("waitForInterrupt: falling edge fired at %lld microseconds\n\n", ret); - wiringPiISRStop (IRQpin) ; } printf("Testing IRQ @ GPIO%d with trigger @ GPIO%d falling edge and bouncetime %d microseconds. Toggle LED @ OUTpin on IRQ.\n\n", IRQpin, IRQpin, BOUNCETIME, OUTpin); diff --git a/wiringPi/wiringPi.c b/wiringPi/wiringPi.c index ba684ea..2b37812 100644 --- a/wiringPi/wiringPi.c +++ b/wiringPi/wiringPi.c @@ -2630,30 +2630,33 @@ unsigned int digitalReadByte2 (void) +/* + * waitForInterrupt: + * Pi Specific. + * Wait for Interrupt on a GPIO pin. + * This is actually done via the /dev/gpiochip interface regardless of + * the wiringPi access mode in-use. Maybe sometime it might get a better + * way for a bit more efficiency. + * Returns timestamp in microseconds on interrupt + ********************************************************************************* + */ -//-------------------------------------------------------------------- -// waitForInteruptInit -// Prepares waitForInterrupt for edgeMode, and debounce_period_us -// -// returns -1 on error -// returns 0 on success -//-------------------------------------------------------------------- - -int waitForInterruptInit (int pin, int edgeMode, unsigned long debounce_period_us) +long long int waitForInterrupt (int pin, int edgeMode, int mS, unsigned long debounce_period_us) // ms < 0 wait infinite, = 0 return immediately, > 0 wait timeout { - const char* strmode = ""; + long long int ret; + int fd, attr, status, readret; + struct pollfd polls ; + struct gpio_v2_line_event evdata; struct gpio_v2_line_config config; struct gpio_v2_line_request req; - int attr, ret; + const char* strmode = ""; - if (wiringPiMode == WPI_MODE_PINS) { + if (wiringPiMode == WPI_MODE_PINS) pin = pinToGpio [pin] ; - } else if (wiringPiMode == WPI_MODE_PHYS) { + else if (wiringPiMode == WPI_MODE_PHYS) pin = physToGpio [pin] ; - } /* open gpio */ -// sleep(1); if (wiringPiGpioDeviceGetFd()<0) { return -1; } @@ -2663,6 +2666,7 @@ int waitForInterruptInit (int pin, int edgeMode, unsigned long debounce_period_u /* setup config */ config.flags = GPIO_V2_LINE_FLAG_INPUT; + switch(edgeMode) { default: case INT_EDGE_SETUP: @@ -2686,11 +2690,11 @@ int waitForInterruptInit (int pin, int edgeMode, unsigned long debounce_period_u strcpy(req.consumer, "wiringpi_gpio_irq"); if (debounce_period_us) { - attr = config.num_attrs; - config.num_attrs++; - gpiotools_set_bit(&config.attrs[attr].mask, 0); - config.attrs[attr].attr.id = GPIO_V2_LINE_ATTR_ID_DEBOUNCE; - config.attrs[attr].attr.debounce_period_us = debounce_period_us; + attr = config.num_attrs; + config.num_attrs++; + gpiotools_set_bit(&config.attrs[attr].mask, 0); + config.attrs[attr].attr.id = GPIO_V2_LINE_ATTR_ID_DEBOUNCE; + config.attrs[attr].attr.debounce_period_us = debounce_period_us; } req.num_lines = 1; @@ -2698,9 +2702,9 @@ int waitForInterruptInit (int pin, int edgeMode, unsigned long debounce_period_u req.event_buffer_size = 32; req.config = config; - ret = ioctl(chipFd, GPIO_V2_GET_LINE_IOCTL, &req); - if (ret == -1) { - ReportDeviceError("GPIO_V2_GET_LINE_IOCTL", pin , strmode, ret); + status = ioctl(chipFd, GPIO_V2_GET_LINE_IOCTL, &req); + if (status == -1) { + ReportDeviceError("GPIO_V2_GET_LINE_IOCTL", pin , strmode, status); return -1; } @@ -2708,54 +2712,24 @@ int waitForInterruptInit (int pin, int edgeMode, unsigned long debounce_period_u printf ("wiringPi: GPIO get line %d , mode %s succeded, fd=%d\n", pin, strmode, req.fd) ; } - int fd_line = req.fd; - isrFds [pin] = fd_line; + fd = req.fd; + isrFds [pin] = fd; isrDebouncePeriodUs[pin] = debounce_period_us; /* set event fd nonbloack read */ /* - int flags = fcntl(fd_line, F_GETFL); + int flags = fcntl(fd, F_GETFL); flags |= O_NONBLOCK; - ret = fcntl(fd_line, F_SETFL, flags); - if (ret) { - fprintf(stderr, "wiringPi: ERROR: fcntl set nonblock return=%d\n", ret); + status = fcntl(fd, F_SETFL, flags); + if (status) { + fprintf(stderr, "wiringPi: ERROR: fcntl set nonblock return=%d\n", status); return -1; } */ - return 0; -} - -/* - * waitForInterrupt: - * Pi Specific. - * Wait for Interrupt on a GPIO pin. - * This is actually done via the /dev/gpiochip interface regardless of - * the wiringPi access mode in-use. Maybe sometime it might get a better - * way for a bit more efficiency. - * Returns timestamp in microseconds on interrupt - ********************************************************************************* - */ - -long long int waitForInterrupt (int pin, int edgeMode, int mS, unsigned long debounce_period_us) // ms < 0 wait infinite, = 0 return immediately, > 0 wait timeout -{ - long long int ret; - int fd; - struct pollfd polls ; - struct gpio_v2_line_event evdata; - - if (wiringPiMode == WPI_MODE_PINS) - pin = pinToGpio [pin] ; - else if (wiringPiMode == WPI_MODE_PHYS) - pin = physToGpio [pin] ; - - if (waitForInterruptInit (pin, edgeMode, debounce_period_us ) != 0) - return -1 ; - - fd = isrFds[pin]; // Setup poll structure polls.fd = fd; - polls.events = POLLIN | POLLERR ; + polls.events = POLLIN | POLLPRI; polls.revents = 0; ret = (long long int)poll(&polls, 1, mS); @@ -2772,7 +2746,7 @@ long long int waitForInterrupt (int pin, int edgeMode, int mS, unsigned long deb printf ("wiringPi: IRQ line %d received %lld, fd=%d\n", pin, ret, isrFds[pin]) ; if (polls.revents & POLLIN) { /* read event data */ - int readret = read(isrFds [pin], &evdata, sizeof(evdata)); + readret = read(isrFds [pin], &evdata, sizeof(evdata)); if (readret == sizeof(evdata)) { if (wiringPiDebug) printf ("wiringPi: IRQ at PIN: %d, timestamp: %lld\n", evdata.offset, evdata.timestamp_ns) ; @@ -2798,6 +2772,12 @@ long long int waitForInterrupt (int pin, int edgeMode, int mS, unsigned long deb } } } + + if (isrFds[pin] > 0) { + close(isrFds [pin]); // release line + isrFds [pin] = -1; + isrDebouncePeriodUs[pin] = 0; + } return ret; } @@ -2954,7 +2934,7 @@ void *interruptHandler (void *arg) // Setup poll structure polls.fd = fd; - polls.events = POLLIN | POLLPRI;; + polls.events = POLLIN | POLLPRI; polls.revents = 0; // get event data, this is also a cancelation point, when pthread_cancel is called From 7abeddde2d64005bd8c8bcfb023160d719f96b7c Mon Sep 17 00:00:00 2001 From: phylax2020 Date: Mon, 17 Feb 2025 22:09:07 +0100 Subject: [PATCH 21/65] wiringPi.c ; waitForInterrupt releases fd and line itself, wiringPiISRStop not necessary to be called --- wiringPi/wiringPi.c | 26 ++++++++------------------ wiringPi/wiringPi.h | 2 +- 2 files changed, 9 insertions(+), 19 deletions(-) diff --git a/wiringPi/wiringPi.c b/wiringPi/wiringPi.c index 2b37812..f1ac321 100644 --- a/wiringPi/wiringPi.c +++ b/wiringPi/wiringPi.c @@ -2782,34 +2782,35 @@ long long int waitForInterrupt (int pin, int edgeMode, int mS, unsigned long deb } /* - * waitForInterruptClose: - * wait for thread interruptHandler to be stopped. + * wiringPiISRStop: + * stop interruptHandler thread and + * wait untill stopped. * close isrFds[pin], reset isrFds[pin], isrFunction[pin] and isrDebouncePeriodUs[pin] * ********************************************************************************* */ -int waitForInterruptClose (int pin) { +int wiringPiISRStop (int pin) { void *res; if (isrFds[pin] > 0) { if (wiringPiDebug) - printf ("waitForInterruptClose: close thread 0x%lX\n", (unsigned long)isrThreads[pin]) ; + printf ("wiringPiISRStop: close thread 0x%lX\n", (unsigned long)isrThreads[pin]) ; if (isrThreads[pin] != 0) { if (pthread_cancel(isrThreads[pin]) == 0) { pthread_join(isrThreads[pin], &res); if (res == PTHREAD_CANCELED) { if (wiringPiDebug) - printf("waitForInterruptClose: thread was canceled\n"); + printf("wiringPiISRStop: thread was canceled\n"); } else { if (wiringPiDebug) - printf("waitForInterruptClose: thread was not canceled\n"); + printf("wiringPiISRStop: thread was not canceled\n"); } } else { if (wiringPiDebug) - printf ("waitForInterruptClose: waitForInterruptClose could not cancel thread\n"); + printf ("wiringPiISRStop: could not cancel thread\n"); } } close(isrFds [pin]); @@ -2830,17 +2831,6 @@ int waitForInterruptClose (int pin) { return 0; } -/* - * wiringPiISRStop: - * stop thread interruptHandler - * - ********************************************************************************* - */ - -int wiringPiISRStop (int pin) { - return waitForInterruptClose (pin); -} - /* * interruptHandler: diff --git a/wiringPi/wiringPi.h b/wiringPi/wiringPi.h index 964fed3..e299f99 100644 --- a/wiringPi/wiringPi.h +++ b/wiringPi/wiringPi.h @@ -144,6 +144,7 @@ extern const char *piRevisionNames [16] ; extern const char *piMakerNames [16] ; extern const int piMemorySize [ 8] ; + // Intended for the GPIO program Use at your own risk. // Threads @@ -301,7 +302,6 @@ extern void digitalWriteByte2 (int value) ; extern long long int waitForInterrupt (int pin, int edgeMode, int mS, unsigned long debounce_period_us) ; // V3.14 phylax extern int wiringPiISR (int pin, int mode, void (*function)(unsigned int, long long int), unsigned long debounce_period_us) ; // v3.14 phylax extern int wiringPiISRStop (int pin) ; //V3.2 -extern int waitForInterruptClose(int pin) ; //V3.2 // Threads From 44538850b4db2690eb035bc7ca4ca3a24cdbc7eb Mon Sep 17 00:00:00 2001 From: phylax2020 Date: Tue, 18 Feb 2025 10:46:08 +0100 Subject: [PATCH 22/65] WiringPi.c interrupthandler ppoll timeout reduced --- wiringPi/wiringPi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wiringPi/wiringPi.c b/wiringPi/wiringPi.c index f1ac321..a818945 100644 --- a/wiringPi/wiringPi.c +++ b/wiringPi/wiringPi.c @@ -2850,7 +2850,7 @@ void *interruptHandler (void *arg) struct gpio_v2_line_config config; struct gpio_v2_line_request req; struct gpio_v2_line_event evdat[64]; - struct timespec tspec = {0, 1e6}; /* 0.5 ms timeout {0, 5e5} */ + struct timespec tspec = {0, 5e5}; /* 0.5 ms timeout {0, 1e6} */ pin = *(int *)arg; From 2f35ff5ec84b41ae2b249f87edec589f87dc30ab Mon Sep 17 00:00:00 2001 From: phylax2020 Date: Thu, 20 Feb 2025 11:29:30 +0100 Subject: [PATCH 23/65] Version v3.16: added wfi status for wiringPiISR and waitForInterrupt --- README.md | 8 +-- VERSION | 2 +- documentation/deutsch/functions.md | 100 +++++++++++++++++++++-------- gpio/gpio.c | 2 +- version.h | 4 +- wiringPi/wiringPi.c | 90 ++++++++++++++++++-------- wiringPi/wiringPi.h | 12 +++- 7 files changed, 157 insertions(+), 61 deletions(-) diff --git a/README.md b/README.md index 7125be7..e08470c 100644 --- a/README.md +++ b/README.md @@ -99,10 +99,10 @@ cd WiringPi # build the package ./build debian -mv debian-template/wiringpi-3.0-1.deb . +mv debian-template/wiringpi-3.x.deb . # install it -sudo apt install ./wiringpi-3.0-1.deb +sudo apt install ./wiringpi-3.x.deb ``` @@ -115,14 +115,14 @@ Unzip/use the portable prebuilt verison: ```sh # unzip the archive -tar -xfv wiringpi_3.0.tar.gz +tar -xfv wiringpi_3.x.tar.gz ``` Install the debian package: ```sh # install a dpkg -sudo apt install ./wiringpi-3.0-1.deb +sudo apt install ./wiringpi-3.x.deb ``` diff --git a/VERSION b/VERSION index 230693c..1bc446c 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -3.15 \ No newline at end of file +3.16 \ No newline at end of file diff --git a/documentation/deutsch/functions.md b/documentation/deutsch/functions.md index 82e94f8..6ff4933 100644 --- a/documentation/deutsch/functions.md +++ b/documentation/deutsch/functions.md @@ -291,7 +291,7 @@ Registriert eine Interrupt Service Routine (ISR) bzw. Funktion die bei Flankenwe >>> ```C -int wiringPiISR(int pin, int edgeMode, void (*function)(unsigned int, long long int), unsigned long bouncetime); +int wiringPiISR(int pin, int edgeMode, void (*function)(struct WPIWfiStatus wfiStatus), unsigned long bouncetime); ``` ``pin``: Der gewünschte Pin (BCM\-, WiringPi\- oder Pin\-Nummer). @@ -301,9 +301,15 @@ int wiringPiISR(int pin, int edgeMode, void (*function)(unsigned int, long long - INT_EDGE_FALLING ... Fallende Flanke - INT_EDGE_BOTH ... Steigende und fallende Flanke -``*function``: Funktionspointer für ISR mit Rückgabeparameter pin und Zeitstempel: - > unsigned int: pin - > long long int: Zeitstempel +``*function``: Funktionspointer für ISR mit Rückgabeparameter struct WPIWfiStatus: +```C +struct WPIWfiStatus { + int status; // -1: error, 0: timeout, 1: valid values for edge and timeStamp_us + unsigned int gpioPin; // gpio as BCM pin + int edge; // One of INT_EDGE_FALLING or INT_EDGE_RISING + long long int timeStamp_us; // time stamp in microseconds, when interrupt happened +}; +``` ``bouncetime``: Entprellzeit in Microsekunden, 0 ms schaltet das Entprellen ab @@ -335,7 +341,7 @@ Wartet auf einen Aufruf der Interrupt Service Routine (ISR) mit Timeout und Entp Blockiert das Programm bis zum Eintreffen der auslösenden Flanke oder bis zum Ablauf des Timeouts. >>> ```C -long long int waitForInterrupt (int pin, int edgeMode, int mS, unsigned long bouncetime) +struct WPIWfiStatus wfiStatus waitForInterrupt (int pin, int edgeMode, int mS, unsigned long bouncetime) ``` ``pin``: Der gewünschte Pin (BCM\-, WiringPi\- oder Pin\-Nummer). @@ -353,18 +359,21 @@ long long int waitForInterrupt (int pin, int edgeMode, int mS, unsigned long bo ``bouncetime``: Entprellzeit in Microsekunden, 0 schaltet Entprellen ab. ``Rückgabewert``: -> \>0 ... Zeitstempel des Interrupt Ereignisses in Mikrosekunden -> 0 ... Timeout -> \-1 ... GPIO Device Chip nicht erfolgreich geöffnet -> \-2 ... ISR wurde nicht registriert - +```C +struct WPIWfiStatus { + int status; // -1: error, 0: timeout, 1: valid values for edge and timeStamp_us + unsigned int gpioPin; // gpio as BCM pin + int edge; // One of INT_EDGE_FALLING or INT_EDGE_RISING + long long int timeStamp_us; // time stamp in microseconds, when interrupt happened +}; +``` **Beispiel:** ```C /* * isr_debounce.c: - * Wait for Interrupt test program WiringPi >=3.14 - ISR method + * Wait for Interrupt test program WiringPi >=3.16 - ISR method * * */ @@ -396,20 +405,26 @@ int toggle = 0; ********************************************************************************* */ -static void wfi (unsigned int gpio, long long int timestamp) { +static void wfi (struct WPIWfiStatus wfiStatus) { // struct timeval now; long long int timenow, diff; struct timespec curr; - + char *edgeType; + if (clock_gettime(CLOCK_MONOTONIC, &curr) == -1) { printf("clock_gettime error"); return; } timenow = curr.tv_sec * 1000000LL + curr.tv_nsec/1000L; // convert to microseconds - diff = timenow - timestamp; - - printf("gpio BCM = %d, IRQ timestamp = %lld microseconds, timenow = %lld, diff = %lld\n", gpio, timestamp, timenow, diff); + diff = timenow - wfiStatus.timeStamp_us; + if (wfiStatus.edge == INT_EDGE_RISING) + edgeType = "rising"; + else if (wfiStatus.edge == INT_EDGE_FALLING) + edgeType = "falling"; + else + edgeType = "none"; + printf("gpio BCM = %d, IRQ edge = %s, timestamp = %lld microseconds, timenow = %lld, diff = %lld\n", wfiStatus.gpioPin, edgeType, wfiStatus.timeStamp_us, timenow, diff); if (toggle == 0) { digitalWrite (OUTpin, HIGH) ; toggle = 1; @@ -425,7 +440,6 @@ static void wfi (unsigned int gpio, long long int timestamp) { int main (void) { int major, minor; - long long int ret; wiringPiVersion(&major, &minor); @@ -441,24 +455,27 @@ int main (void) pinMode(OUTpin, OUTPUT); digitalWrite (OUTpin, LOW) ; - printf("Testing waitForInterrupt IRQ @ GPIO%d, timeout is %d\n", IRQpin, TIMEOUT); - ret = waitForInterrupt(IRQpin, INT_EDGE_FALLING, TIMEOUT, BOUNCETIME_WFI ); - if (ret < 0) { - printf("waitForInterrupt returned error %lld\n", ret); + printf("Testing waitForInterrupt on both edges IRQ @ GPIO%d, timeout is %d\n", IRQpin, TIMEOUT); + struct WPIWfiStatus wfiStatus = waitForInterrupt(IRQpin, INT_EDGE_BOTH, TIMEOUT, BOUNCETIME_WFI ); + if (wfiStatus.status < 0) { + printf("waitForInterrupt returned error\n"); pinMode(OUTpin, INPUT); return 0; } - else if (ret == 0) { - printf("waitForInterrupt timed out %lld\n\n", ret); + else if (wfiStatus.status == 0) { + printf("waitForInterrupt timed out\n\n"); } else { - printf("waitForInterrupt: falling edge fired at %lld microseconds\n\n", ret); + if (wfiStatus.edge == INT_EDGE_FALLING) + printf("waitForInterrupt: GPIO pin %d falling edge fired at %lld microseconds\n\n", wfiStatus.gpioPin, wfiStatus.timeStamp_us); + else + printf("waitForInterrupt: GPIO pin %d rising edge fired at %lld microseconds\n\n", wfiStatus.gpioPin, wfiStatus.timeStamp_us); } - printf("Testing IRQ @ GPIO%d with trigger @ GPIO%d falling edge and bouncetime %d microseconds. Toggle LED @ OUTpin on IRQ.\n\n", IRQpin, IRQpin, BOUNCETIME, OUTpin); + printf("Testing IRQ @ GPIO%d with trigger @ GPIO%d on both edges and bouncetime %d microseconds. Toggle LED @ OUTpin on IRQ.\n\n", IRQpin, IRQpin, BOUNCETIME, OUTpin); printf("To stop program hit return key\n\n"); - wiringPiISR (IRQpin, INT_EDGE_FALLING, &wfi, BOUNCETIME) ; + wiringPiISR (IRQpin, INT_EDGE_BOTH, &wfi, BOUNCETIME) ; getc(stdin); @@ -469,6 +486,37 @@ int main (void) } ``` +Output auf dem Terminal: + +``` +pi@RaspberryPi:~/wiringpi-test-v3.16 $ gcc -o isr_debounce isr_debounce.c -l wiringPi +pi@RaspberryPi:~/wiringpi-test-v3.16 $ ./isr_debounce + +ISR debounce test (WiringPi 3.16) + +Testing waitForInterrupt on both edges IRQ @ GPIO16, timeout is 10000 +waitForInterrupt: GPIO pin 16 falling edge fired at 256522528012 microseconds + +Testing IRQ @ GPIO16 with trigger @ GPIO16 on both edges and bouncetime 3000 microseconds. Toggle LED @ OUTpin on IRQ. + +To stop program hit return key + +gpio BCM = 16, IRQ edge = rising, timestamp = 256522668010 microseconds, timenow = 256522668017, diff = 7 +gpio BCM = 16, IRQ edge = falling, timestamp = 256536364014 microseconds, timenow = 256536364021, diff = 7 +gpio BCM = 16, IRQ edge = rising, timestamp = 256536952011 microseconds, timenow = 256536952018, diff = 7 +gpio BCM = 16, IRQ edge = falling, timestamp = 256537856010 microseconds, timenow = 256537856016, diff = 6 +gpio BCM = 16, IRQ edge = rising, timestamp = 256538744011 microseconds, timenow = 256538744018, diff = 7 +gpio BCM = 16, IRQ edge = falling, timestamp = 256539664010 microseconds, timenow = 256539664017, diff = 7 +gpio BCM = 16, IRQ edge = rising, timestamp = 256540516010 microseconds, timenow = 256540516016, diff = 6 +gpio BCM = 16, IRQ edge = falling, timestamp = 256541560013 microseconds, timenow = 256541560022, diff = 9 +gpio BCM = 16, IRQ edge = rising, timestamp = 256542360010 microseconds, timenow = 256542360016, diff = 6 +gpio BCM = 16, IRQ edge = falling, timestamp = 256543320012 microseconds, timenow = 256543320020, diff = 8 +gpio BCM = 16, IRQ edge = rising, timestamp = 256544092021 microseconds, timenow = 256544092029, diff = 8 +^C +pi@RaspberryPi:~/wiringpi-test-v3.16 $ +``` + + ## Hardware PWM (Pulsweitenmodulation) Verfügbare GPIOs: https://pinout.xyz/pinout/pwm diff --git a/gpio/gpio.c b/gpio/gpio.c index f79188b..1ee2c33 100644 --- a/gpio/gpio.c +++ b/gpio/gpio.c @@ -177,7 +177,7 @@ void printgpio(const char* text) { } } -static void wfi (unsigned int pin, long long int timestamp) { +static void wfi (UNU struct WPIWfiStatus wfiStatus) { globalCounter++; if(globalCounter>=iterations) { printgpio("finished\n"); diff --git a/version.h b/version.h index d7f42c6..5ea1e8c 100644 --- a/version.h +++ b/version.h @@ -1,3 +1,3 @@ -#define VERSION "3.15" +#define VERSION "3.16" #define VERSION_MAJOR 3 -#define VERSION_MINOR 15 +#define VERSION_MINOR 16 diff --git a/wiringPi/wiringPi.c b/wiringPi/wiringPi.c index a818945..0f2ea7d 100644 --- a/wiringPi/wiringPi.c +++ b/wiringPi/wiringPi.c @@ -482,7 +482,7 @@ static int isrFds [64] = // ISR Data static int chipFd = -1; -static void (*isrFunctions [64])(unsigned int, long long int) ; +static void (*isrFunctions [64])(struct WPIWfiStatus) ; static pthread_t isrThreads[64]; static int isrMode[64]; // irq on rising/falling edge static unsigned long isrDebouncePeriodUs [64]; // 0: debounce is off @@ -2637,28 +2637,32 @@ unsigned int digitalReadByte2 (void) * This is actually done via the /dev/gpiochip interface regardless of * the wiringPi access mode in-use. Maybe sometime it might get a better * way for a bit more efficiency. - * Returns timestamp in microseconds on interrupt + * Returns struct WPIWfiStatus ********************************************************************************* */ -long long int waitForInterrupt (int pin, int edgeMode, int mS, unsigned long debounce_period_us) // ms < 0 wait infinite, = 0 return immediately, > 0 wait timeout +struct WPIWfiStatus waitForInterrupt (int pin, int edgeMode, int mS, unsigned long debounce_period_us) // ms < 0 wait infinite, = 0 return immediately, > 0 wait timeout { - long long int ret; + int ret; int fd, attr, status, readret; struct pollfd polls ; struct gpio_v2_line_event evdata; struct gpio_v2_line_config config; struct gpio_v2_line_request req; const char* strmode = ""; + struct WPIWfiStatus wfiStatus; if (wiringPiMode == WPI_MODE_PINS) pin = pinToGpio [pin] ; else if (wiringPiMode == WPI_MODE_PHYS) pin = physToGpio [pin] ; + memset(&wfiStatus, 0, sizeof(wfiStatus)); + /* open gpio */ if (wiringPiGpioDeviceGetFd()<0) { - return -1; + wfiStatus.status = -1; + return wfiStatus; } memset(&req, 0, sizeof(req)); @@ -2671,9 +2675,10 @@ long long int waitForInterrupt (int pin, int edgeMode, int mS, unsigned long deb default: case INT_EDGE_SETUP: if (wiringPiDebug) { - printf ("wiringPi: waitForInterruptMode mode INT_EDGE_SETUP - exiting\n") ; + printf ("waitForInterrupt: edgeMode INT_EDGE_SETUP - exiting\n") ; } - return -1; + wfiStatus.status = -1; + return wfiStatus; case INT_EDGE_FALLING: config.flags |= GPIO_V2_LINE_FLAG_EDGE_FALLING; strmode = "falling"; @@ -2705,11 +2710,12 @@ long long int waitForInterrupt (int pin, int edgeMode, int mS, unsigned long deb status = ioctl(chipFd, GPIO_V2_GET_LINE_IOCTL, &req); if (status == -1) { ReportDeviceError("GPIO_V2_GET_LINE_IOCTL", pin , strmode, status); - return -1; + wfiStatus.status = -1; + return wfiStatus; } if (wiringPiDebug) { - printf ("wiringPi: GPIO get line %d , mode %s succeded, fd=%d\n", pin, strmode, req.fd) ; + printf ("waitForInterrupt: GPIO get line %d , mode %s succeded, fd=%d\n", pin, strmode, req.fd) ; } fd = req.fd; @@ -2732,53 +2738,66 @@ long long int waitForInterrupt (int pin, int edgeMode, int mS, unsigned long deb polls.events = POLLIN | POLLPRI; polls.revents = 0; - ret = (long long int)poll(&polls, 1, mS); + ret = poll(&polls, 1, mS); if (ret < 0) { - if (wiringPiDebug) - fprintf(stderr, "wiringPi: ERROR: poll returned=%lld\n", ret); + if (wiringPiDebug) { + fprintf(stderr, "waitForInterrupt: ERROR: poll returned=%d\n", ret); + } + wfiStatus.status = -1; } else if (ret == 0) { - if (wiringPiDebug) - fprintf(stderr, "wiringPi: timeout: poll returned=%lld\n", ret); + if (wiringPiDebug) { + fprintf(stderr, "waitForInterrupt: timeout: poll returned=%d\n", ret); + } + wfiStatus.status = 0; } else { if (wiringPiDebug) - printf ("wiringPi: IRQ line %d received %lld, fd=%d\n", pin, ret, isrFds[pin]) ; + printf ("waitForInterrupt: IRQ line %d received %d, fd=%d\n", pin, ret, isrFds[pin]) ; if (polls.revents & POLLIN) { /* read event data */ readret = read(isrFds [pin], &evdata, sizeof(evdata)); if (readret == sizeof(evdata)) { if (wiringPiDebug) - printf ("wiringPi: IRQ at PIN: %d, timestamp: %lld\n", evdata.offset, evdata.timestamp_ns) ; + printf ("waitForInterrupt: IRQ at PIN: %d, timestamp: %lld\n", evdata.offset, evdata.timestamp_ns) ; switch (evdata.id) { case GPIO_V2_LINE_EVENT_RISING_EDGE: + wfiStatus.edge = INT_EDGE_RISING; if (wiringPiDebug) - printf("wiringPi: rising edge\n"); + printf("waitForInterrupt: rising edge\n"); break; case GPIO_V2_LINE_EVENT_FALLING_EDGE: + wfiStatus.edge = INT_EDGE_FALLING; if (wiringPiDebug) - printf("wiringPi: falling edge\n"); + printf("waitForInterrupt: falling edge\n"); break; default: + wfiStatus.edge = INT_EDGE_SETUP; // edge = 0 if (wiringPiDebug) - printf("wiringPi: unknown event\n"); + printf("waitForInterrupt: unknown event\n"); break; } - ret = evdata.timestamp_ns / 1000LL; // nanoseconds u64 to microseconds + wfiStatus.timeStamp_us = evdata.timestamp_ns / 1000LL; // nanoseconds u64 to microseconds + wfiStatus.gpioPin = evdata.offset; + wfiStatus.status = 1; } else { - ret = -1; + wfiStatus.status = -1; } } + else { + wfiStatus.status = -1; + } } - + if (isrFds[pin] > 0) { close(isrFds [pin]); // release line isrFds [pin] = -1; isrDebouncePeriodUs[pin] = 0; } - return ret; + + return wfiStatus; } /* @@ -2850,6 +2869,7 @@ void *interruptHandler (void *arg) struct gpio_v2_line_config config; struct gpio_v2_line_request req; struct gpio_v2_line_event evdat[64]; + struct WPIWfiStatus wfiStatus; struct timespec tspec = {0, 5e5}; /* 0.5 ms timeout {0, 1e6} */ pin = *(int *)arg; @@ -2957,7 +2977,27 @@ void *interruptHandler (void *arg) if (isrFunctions [pin]) { if (wiringPiDebug) printf( "interruptHandler: GPIO EVENT at %" PRIu64 " on line %d (%d|%d) \n", (uint64_t)evdat[i].timestamp_ns, evdat[i].offset, evdat[i].line_seqno, evdat[i].seqno); - isrFunctions [pin] ((unsigned int)pin, evdat[i].timestamp_ns/1000LL) ; + wfiStatus.status = 1; + wfiStatus.gpioPin = pin; + switch (evdat[i].id) { + case GPIO_V2_LINE_EVENT_RISING_EDGE: + wfiStatus.edge = INT_EDGE_RISING; + if (wiringPiDebug) + printf("waitForInterrupt: rising edge\n"); + break; + case GPIO_V2_LINE_EVENT_FALLING_EDGE: + wfiStatus.edge = INT_EDGE_FALLING; + if (wiringPiDebug) + printf("waitForInterrupt: falling edge\n"); + break; + default: + wfiStatus.edge = INT_EDGE_SETUP; // edge = 0 + if (wiringPiDebug) + printf("waitForInterrupt: unknown event\n"); + break; + } + wfiStatus.timeStamp_us = evdat[i].timestamp_ns/1000LL; + isrFunctions [pin] (wfiStatus) ; } } } @@ -2982,7 +3022,7 @@ void *interruptHandler (void *arg) ********************************************************************************* */ -int wiringPiISR (int pin, int edgeMode, void (*function)(unsigned int, long long int), unsigned long debounce_period_us) +int wiringPiISR (int pin, int edgeMode, void (*function)(struct WPIWfiStatus wfiStatus), unsigned long debounce_period_us) { const int maxpin = GetMaxPin(); diff --git a/wiringPi/wiringPi.h b/wiringPi/wiringPi.h index e299f99..be64b16 100644 --- a/wiringPi/wiringPi.h +++ b/wiringPi/wiringPi.h @@ -299,8 +299,16 @@ extern void digitalWriteByte2 (int value) ; // Interrupts // (Also Pi hardware specific) -extern long long int waitForInterrupt (int pin, int edgeMode, int mS, unsigned long debounce_period_us) ; // V3.14 phylax -extern int wiringPiISR (int pin, int mode, void (*function)(unsigned int, long long int), unsigned long debounce_period_us) ; // v3.14 phylax +// status returned from waitForInterrupt V3.16 +struct WPIWfiStatus { + int status; // -1: error, 0: timeout, 1: valud values for edge and timeStamp_us + unsigned int gpioPin; // gpio as BCM pin + int edge; // One of INT_EDGE_FALLING or INT_EDGE_RISING + long long int timeStamp_us; // time stamp in microseconds, when interrupt happened +}; + +extern struct WPIWfiStatus waitForInterrupt (int pin, int edgeMode, int mS, unsigned long debounce_period_us) ; // V3.16 phylax +extern int wiringPiISR (int pin, int mode, void (*function)(struct WPIWfiStatus wfiStatus), unsigned long debounce_period_us) ; // v3.16 phylax extern int wiringPiISRStop (int pin) ; //V3.2 // Threads From a9d8e734a80175d9cbd2fb74e5da382790da7383 Mon Sep 17 00:00:00 2001 From: Mr-Fishy Date: Wed, 12 Mar 2025 11:35:27 -0700 Subject: [PATCH 24/65] Further English Doc & Markdown Corrections --- documentation/english/functions.md | 304 +++++++++++++++-------------- 1 file changed, 157 insertions(+), 147 deletions(-) diff --git a/documentation/english/functions.md b/documentation/english/functions.md index a277e80..663892e 100644 --- a/documentation/english/functions.md +++ b/documentation/english/functions.md @@ -4,15 +4,18 @@ The WiringPi-library enables access to the GPIO pins of the Raspberry Pi. In thi Since Version 3, extensions to the interface have been made again. In the case of new implementations, you should rely on the current / new functions. The old [GPIO Sysfs Interface for Userspace](https://www.kernel.org/doc/Documentation/gpio/sysfs.txt) is no longer supported. -**Attention:** This documentation is still in progress and therefore incomplete. -The content of this documentation was created with care and to the best of our knowledge and belief. However, the authors do not guarantee the correctness, completeness and topicality of the information provided.The content of the documentation is used at your own risk. -No liability is generally assumed for damage caused by material or intangible nature caused by the use or non-use of the information provided or by the use of incorrect and incomplete information. +**Attention:** + +This documentation is still in progress and therefore incomplete. +The content of this documentation was created with care and to the best of our knowledge. However, the authors do not guarantee the correctness, completeness and topicality of the information provided.The content of the documentation is used at your own risk. + +No liability is assumed for material or intangible damage caused by the use or non-use of the information provided or by the use of incorrect or incomplete information. ## Installation -Unfortunately, the WiringPi Library is not directly available in Raspberry Pi OS, so it must be installed manually. Either download a Debian package or create it manually. +The WiringPi Library is not directly available in Raspberry Pi OS, so it must be installed manually. Either download a Debian package or create it manually. -**Create Debian package:** +**Create Debian package:** ```bash sudo apt install git @@ -22,24 +25,23 @@ cd WiringPi mv debian-template/wiringpi-3.0-1.deb . ``` -**Install Debian package:** +**Install Debian package:** ```bash sudo apt install ./wiringpi-3.0-1.deb ``` -**Uninstall Debian package:** +**Uninstall Debian package:** ```bash sudo apt purge wiringpi ``` - ## PIN Numbering and Raspberry Pi Models -GPIOs: https://pinout.xyz/pinout/wiringpi +GPIOs: [https://pinout.xyz/pinout/wiringpi](https://pinout.xyz/pinout/wiringpi) -**Raspberry Pi Models with 40-Pin GPIO J8 Header:** +**Raspberry Pi Models with 40-Pin GPIO J8 Header:** | BCM | WPI | Name | Physical | Name | WPI | BCM | |-----|-----|---------|:---------:|---------|-----|-----| @@ -64,8 +66,7 @@ GPIOs: https://pinout.xyz/pinout/wiringpi | 26 | 25 | GPIO.25 | 37 I 38 | GPIO.28 | 28 | 20 | | | | GND | 39 I 40 | GPIO.29 | 29 | 21 | - -**Raspberry Pi 1B Rev. 2 with 26-Pin GPIO P1 Header:** +**Raspberry Pi 1B Rev. 2 with 26-Pin GPIO P1 Header:** | BCM | WPI | Name | Physical | Name | WPI | BCM | |-----|-----|---------|:--------:|----------|-----|-----| @@ -83,9 +84,7 @@ GPIOs: https://pinout.xyz/pinout/wiringpi | 11 | 14 | SCLK | 23 I 24 | CE0 | 10 | 8 | | | | GND | 25 I 26 | CE1 | 11 | 7 | - - -**Raspberry Pi 1B Rev. 1 with 26-Pin GPIO P1 Header:** +**Raspberry Pi 1B Rev. 1 with 26-Pin GPIO P1 Header:** | BCM | WPI | Name | Physical | Name | WPI | BCM | |-----|-----|---------|:--------:|---------|-----|-----| @@ -103,22 +102,24 @@ GPIOs: https://pinout.xyz/pinout/wiringpi | 11 | 14 | SCLK | 23 I 24 | CE0 | 10 | 8 | | | | GND | 25 I 26 | CE1 | 11 | 7 | - **References** + Note the different pin numbers and the I2C0 at Raspberry Pi 1B Rev. 1! ## Initialization + At the beginning, the WiringPi Library must be initialized. To do this, one of the following functions must be called up: Outdated functions (no longer use): -``wiringPiSetup`` uses Wiringpi numbering (WPI) of the GPIO's and accesses the GPIO register directly. +``wiringPiSetup`` uses WiringPi numbering (WPI) of the GPIOs and accesses the GPIO register directly. ``wiringPiSetupGpio`` uses BCM numbering of the GPIOs and accesses the GPIO registers directly. ``wiringPiSetupPhys`` uses physical PIN numbering of the GPIOs and accesses the GPIO register directly. -``wiringPiSetupSys`` uses BCM numbering and calls the new function ``wiringPiSetupGpioDevice`` from version 3.4 to ensure compatibility with new core. In version 2, the virtual file system/SYS/Class/GPIO was used. However, the GPIO's exports had to take place externally before the initialization! The function is outdated and should not be used! +``wiringPiSetupSys`` uses BCM numbering and calls the new function ``wiringPiSetupGpioDevice`` from version 3.4 to ensure compatibility with new core. In version 2, the virtual file system/SYS/Class/GPIO was used. However, the GPIOs exports had to take place externally before the initialization! The function is outdated and should not be used! **Since Version 3.4:** + ``wiringPiSetupPinType`` decides whether WiringPi, BCM or physical PIN numbering is now used, based on the parameter pinType. So it combines the first 3 setup functions together. ``wiringPiSetupGpioDevice`` is the successor to the ``wiringPiSetupSys`` function and now uses "GPIO Character Device Userspace API" in version 1 (from kernel 5.10). More information can be found at [docs.kernel.org/driver-api/gpio/driver.html](https://docs.kernel.org/driver-api/gpio/driver.html) on the parameter pintype, it is again decided which pin numbering is used. In this variant, there is no direct access to the GPIO memory (DMA) but rather through a kernel interface that is available with user permissions. The disadvantage is the limited functionality and low performance. @@ -128,16 +129,18 @@ In this variant, there is no direct access to the GPIO memory (DMA) but rather t ### wiringPiSetup V2 (outdated) Inializating WiringPi in a classic way. ->>> + +**Notice:** This function is deprecated and should not be used in modern implementations. + ```C -int wiringPiSetupGpio(void) -``` +int wiringPiSetupGpio(void); +``` ``Return Value``: Error status -> 0 ... No Error +> 0 ... No Error -**Example:** +**Example:** ```C wiringPiSetupGpio(); @@ -146,22 +149,23 @@ wiringPiSetupGpio(); ### wiringPiSetup V3 Initializing WiringPi. ->>> + ```C -int wiringPiSetupPinType(enum WPIPinType pinType) +int wiringPiSetupPinType(enum WPIPinType pinType); ``` ``pinType``: Type of PIN numbering... - - `WPI_PIN_BCM` ... BCM-Numbering - - `WPI_PIN_WPI` ... WiringPi-Numbering - - `WPI_PIN_PHYS` ... Physical Numbering + +- `WPI_PIN_BCM` ... BCM-Numbering +- `WPI_PIN_WPI` ... WiringPi-Numbering +- `WPI_PIN_PHYS` ... Physical Numbering ``Return Value``: Error status > 0 ... No Error > -1 ... Invalid Parameter Error -**Example:** +**Example:** ```C wiringPiSetupPinType(WPI_PIN_BCM); @@ -172,13 +176,14 @@ wiringPiSetupPinType(WPI_PIN_BCM); ### pinMode Changes the mode of a GPIO pins. ->>> + ```C -void pinMode(int pin, int mode) +void pinMode(int pin, int mode); ``` ``Pin``: The desired PIN (BCM, Wiringpi or PIN number). ``Mode``: The desired pin mode... + - `INPUT` ... Input - `OUTPUT` ... Output - `PWM_OUTPUT` ... PWM output (frequency and pulse break ratio can be configured) @@ -187,42 +192,44 @@ void pinMode(int pin, int mode) - `GPIO_CLOCK` ... Frequency output - `PM_OFF` ... Release -**Example:** +**Example:** ```C pinMode(17, OUTPUT); ``` -**Support:** -`PM_OFF` resets the GPIO (Input) and releases it. PWM is stopped. -Raspberry Pi 5 does not support the PWM Bal (Balanced) mode. The MS mode is activated at `PWM_OUTPUT`. -`GPIO_CLOCK` is currently not yet supported in Raspberry Pi 5 (RP1). +**Notice:** + +- `PM_OFF` resets the GPIO (Input) and releases it. PWM is stopped. +- Raspberry Pi 5 does not support the PWM Bal (Balanced) mode. The MS mode is activated at `PWM_OUTPUT`. +- `GPIO_CLOCK` is currently not yet supported in Raspberry Pi 5 (RP1). **PWM Exit** + `PWM_OUTPUT` Activates the specified PWM output with the settings: - - Mode: BAL-Balanced (Pi0-4), MS-Mark/Space (Pi 5) - - Range: 1024 - - Divider: 32 + +- Mode: BAL-Balanced (Pi0-4), MS-Mark/Space (Pi 5) +- Range: 1024 +- Divider: 32 In order to make sure that the output starts without an active frequency, you should execute ``pwmWrite(PWM_GPIO, 0);`` before activating. After that, the corresponding clock and range values ​​can be adapted, without a frequency already being output unintentionally. -### pinMode - ### digitalWrite Set the value of a GPIO pin. ->>> + ```C -void digitalWrite(int pin, int value) +void digitalWrite(int pin, int value); ``` ``pin``: The desired Pin (BCM-, Wiringpi- or PIN number). ``value``: The logical value... - - `HIGH` ... Value 1 (electrical ~ 3.3 V) - - `LOW` ... Value 0 (electrical ~0 V / GND) -**Example:** +- `HIGH` ... Value 1 (electrical ~ 3.3 V) +- `LOW` ... Value 0 (electrical ~0 V / GND) + +**Example:** ```C pinMode(17, OUTPUT); @@ -232,18 +239,19 @@ DigitalWrite(17, HIGH); ### pullUpDnControl Changes the internal pull-up / pull-down resistance. ->>> + ```C -void pullUpDnControl (int pin, int pud) +void pullUpDnControl (int pin, int pud); ``` ``pin``: The desired Pin (BCM-, WiringPi-, or Pin-number). ``pud``: The resistance type... - - `PUD_OFF` ... No resistance - - `PUD_UP` ... Pull-Up resistance (~50 kOhm) - - `PUD_DOWN` ... Pull-Down resistance (~50 kOhm) -**Example:** +- `PUD_OFF` ... No resistance +- `PUD_UP` ... Pull-Up resistance (~50 kOhm) +- `PUD_DOWN` ... Pull-Down resistance (~50 kOhm) + +**Example:** ```C pullUpDnControl(17, PUD_DOWN); @@ -252,9 +260,9 @@ pullUpDnControl(17, PUD_DOWN); ### digitalRead Reads the value of one GPIO-Pin. ->>> + ```C -int digitalRead(int pin) +int digitalRead(int pin); ``` ``pin``: The desired Pin (BCM-, WiringPi-, or Pin-number). @@ -263,7 +271,7 @@ int digitalRead(int pin) > `HIGH` ... Value 1 > `LOW` ... Value 0 -**Example:** +**Example:** ```C pinMode(17, INPUT); @@ -283,34 +291,32 @@ if (value == HIGH) Registers an Interrupt Service Routine (ISR) / function that is executed on edge detection. ->>> ```C int wiringPiISR(int pin, int mode, void (*function)(void)); ``` ``pin``: The desired Pin (BCM-, WiringPi-, or Pin-number). ``mode``: Triggering edge mode... - - `INT_EDGE_RISING` ... Rising edge - - `INT_EDGE_FALLING` ... Falling edge - - `INT_EDGE_BOTH` ... Rising and falling edge + +- `INT_EDGE_RISING` ... Rising edge +- `INT_EDGE_FALLING` ... Falling edge +- `INT_EDGE_BOTH` ... Rising and falling edge ``*function``: Function pointer for ISR ``Return Value``: - + > 0 ... Successful -For example see **wiringPiISRStop**. - +For example see **[wiringPiISRStop](#wiringpiisrstop)**. ### wiringPiISRStop Deregisters the Interrupt Service Routine (ISR) on a Pin. ->>> ```C -int wiringPiISRStop (int pin) +int wiringPiISRStop (int pin); ``` ``pin``: The desired Pin (BCM-, WiringPi-, or Pin-number). @@ -320,8 +326,7 @@ int wiringPiISRStop (int pin) - -**Example:** +**Example:** ```C static volatile int edgeCounter; @@ -337,20 +342,18 @@ int main (void) { wiringPiISR (17, INT_EDGE_RISING, &isr); Sleep(1000); - printf("%d rinsing edges\n", ); + printf("%d rising edges\n", edgeCounter); wiringPiISRStop(17); } ``` - ### waitForInterrupt -Waits for a previously defined interrupt (wiringPiISR) on the GPIO pin. This function should not be used. +Waits for a previously defined interrupt ([wiringPiISR](#wiringpiisr)) on the GPIO pin. This function should not be used. ->>> ```C -int waitForInterrupt (int pin, int mS) +int waitForInterrupt (int pin, int mS); ``` ``pin``: The desired Pin (BCM-, WiringPi-, or Pin-number). @@ -360,17 +363,16 @@ int waitForInterrupt (int pin, int mS) > -1 ... GPIO Device Chip not successfully opened > -2 ... ISR was not registered (WiringPiISR must be called) - ## Hardware Pulse Width Modulation (PWM) -Available GPIOs: https://pinout.xyz/pinout/pwm +Available GPIOs: [https://pinout.xyz/pinout/pwm](https://pinout.xyz/pinout/pwm) ### pwmWrite Changes the PWM value of the pin. Possible values ​​are 0 -> { PWM Range }. ->>> + ```C -pwmWrite(int pin, int value) +pwmWrite(int pin, int value); ``` ``pin``: The desired Pin (BCM-, WiringPi-, or Pin-number). @@ -381,9 +383,9 @@ pwmWrite(int pin, int value) Set the range for the PWM value of all PWM pins or PWM channels. 19200 / divisor / range applies to the calculation of the PWM frequency (m/s mode). If ``pinMode(pin, PWM_OUTPUT)`` The value 1024 is automatically set for the divider. ->>> + ```C -pwmSetRange (unsigned int range) +pwmSetRange (unsigned int range); ``` ``range``: PWM Range @@ -391,60 +393,62 @@ pwmSetRange (unsigned int range) ### pwmSetMode Set the PWM mode for all PWM pins or PWM channels. ->>> + ```C pwmSetMode(int mode); ``` ``mode``: PWM Mode - - `PWM_MODE_MS` ... Mark / Space Mode (PWM Fixed Frequency) - - `PWM_MODE_BAL` ... Balanced Mode (PWM Variable Frequency) -**Support:** +- `PWM_MODE_MS` ... Mark / Space Mode (PWM Fixed Frequency) +- `PWM_MODE_BAL` ... Balanced Mode (PWM Variable Frequency) + +**Notice:** + Raspberry Pi 5 does not support the balanced mode! - ### pwmSetClock Set the divider for the basic PWM. The base clock is standardized for all Raspberry Pi's to 1900 kHz. 19200 / divisor / range applies to the calculation of the PWM frequency (m/s mode). -If ``pinmode(pin, PWM_OUTPUT)`` The value 32 is automatically set for the divider. ->>> +If ``pinMode(pin, PWM_OUTPUT)`` The value 32 is automatically set for the divider. + ```C -pwmSetClock(int divisor) +pwmSetClock(int divisor); ``` -``divisor``: Divider (Raspberry Pi 4: 1-1456, all other 1-4095) +``divisor``: Divider (Raspberry Pi 4: 1-1456, all other 1-4095) - `0` ... Deactivates the PWM clock on Raspberry Pi 5, with other Pi's divisor `1` is used -**Support:** +**Notice:** + Due to its higher internal basic clock, the Raspberry Pi 4 only has a setting range of `1 - 1456`. Otherwise, `0 - 4095` applies to a valid divider. -**Example:** +**Example:** ```C int main (void) { - wiringPiSetupGpio() ; + wiringPiSetupGpio(); pwmSetRange(1024); pwmSetClock(35); pwmWrite(18, 512); - + + // Notice: PWM_BAL_OUTPUT NOT supported on Pi 5 pinMode(18, PWM_MS_OUTPUT); - + double freq = 19200.0 / (double)pwmc / (double)pwmr; - + printf("PWM 50%% @ %g kHz", freq); delay(250); - + pinMode(18, PM_OFF); } ``` - ## I2C - Bus ``wiringPiI2CRawWrite`` and ``wiringPiI2CRawRead`` are the new functions in version 3 that now allow direct sending and reading of I2C data. The other write and read functions use the SMBus protocol, which is commonly used with I2C chips. @@ -453,18 +457,15 @@ int main (void) { Open the default I2C bus on the Raspberry Pi and addresses the specified device / slave. ->>> ```C -wiringPiI2CSetup(const int devId) +wiringPiI2CSetup(const int devId); ``` -``devId``: I2C-Gerät / Slave Adresse. -``Return Value``: File Handle to I2C-Bus +``devId``: I2C device / slave address. +``Return Value``: File handle to I2C bus, or -1 on error. -> -1 ... Error or EXIT (Programm termination) +**Example** -**Example** ->>> ```C int fd = wiringPiI2CSetup(0x20); ``` @@ -473,33 +474,41 @@ int fd = wiringPiI2CSetup(0x20); Opens the specified I2C bus and addresses the specified I2C device / slave. ->>> ```C -wiringPiI2CSetupInterface(const char *device, int devId) +wiringPiI2CSetupInterface(const char *device, int devId); ``` -``devId``: I2C-Gerät / Slave Adresse. -``Return Value``: File Handle to I2C-Bus +``devId``: I2C device / slave address. +``Return Value``: File handle to I2C bus, or -1 on error. -> -1 ... Error or EXIT (Programm termination) +**Example** -**Example** ->>> ```C int fd = wiringPiI2CSetupInterface("/dev/i2c-1", 0x20); ``` +### wiringPiI2CWrite -### wiringPiI2CWrite / wiringPiI2CWriteReg8 / wiringPiI2CWriteReg16 / wiringPiI2CWriteBlockData +Simple device write. Some devices accept data this way without needing to access any internal registers. + +### wiringPiI2CWriteReg8 + +Writes a 8-bit data value into the device register indicated. + +### wiringPiI2CWriteReg16 + +Writes a 16-bit data value into the device register indicated. + +### wiringPiI2CWriteBlockData ... ### wiringPiI2CRawWrite Writing data about an I2C slave. ->>> + ```C -int wiringPiI2CRawWrite(int fd, const uint8_t *values, uint8_t size) +int wiringPiI2CRawWrite(int fd, const uint8_t *values, uint8_t size); ``` ``fd``: File Handle. @@ -507,8 +516,8 @@ int wiringPiI2CRawWrite(int fd, const uint8_t *values, uint8_t size) ``size``: Number of bytes of the source buffer that should be written. ``Return Value``: Number of bytes that were written. -**Example** ->>> +**Example** + ```C int fd = wiringPiI2CSetup(I2C_ADDR); @@ -534,9 +543,9 @@ else { ### wiringPiI2CRawRead Reading data from an I2C slave. ->>> + ```C -int wiringPiI2CRawRead(int fd, uint8_t *values, uint8_t size) +int wiringPiI2CRawRead(int fd, uint8_t *values, uint8_t size); ``` ``fd``: File Handle. @@ -544,8 +553,8 @@ int wiringPiI2CRawRead(int fd, uint8_t *values, uint8_t size) ``size``: Number of bytes that are to be read into the target buffer. ``Return Value``: Number of bytes that were read. -**Example** ->>> +**Example** + ```C int fd = wiringPiI2CSetup(I2C_ADDR); @@ -564,32 +573,30 @@ else { } ``` - ## SPI - Bus Functions that start with ``wiringPiSPIx`` are new since version 3, allowing the SPI bus number to be specified. This is especially useful for the Compute Module, which has multiple SPI buses (0-7). The old functions remain available, but they always refer to SPI bus 0, which is available on the 40 pin GPIO connector. - ### wiringPiSPISetup / wiringPiSPISetupMode / wiringPiSPIxSetupMode Opens the specified SPI bus. ->>> ```C -int wiringPiSPISetup (int channel, int speed) -int wiringPiSPISetup (int channel, int speed, int mode) -int wiringPiSPIxSetupMode(const int number, const int channel, const int speed, const int mode) +int wiringPiSPISetup (int channel, int speed); + +int wiringPiSPISetup (int channel, int speed, int mode); + +int wiringPiSPIxSetupMode(const int number, const int channel, const int speed, const int mode); ``` -``number``: SPI muber (typically 0, on Compute Module 0-7). +``number``: SPI number (typically 0, on Compute Module 0-7). ``channel``: SPI channel (typically 0 or 1, on Compute Module 0-3). ``speed``: SPI clock. -``mode``: SPI mode (https://www.kernel.org/doc/Documentation/spi/spidev). -``Return Value``: File handle to the SPI bus -> -1 ... Error or EXIT (Programm termination) +``mode``: SPI mode ([www.kernel.org/doc/Documentation/spi/spidev](https://www.kernel.org/doc/Documentation/spi/spidev)). +``Return Value``: File handle to the SPI bus, or -1 on error. + +**Example** -**Example** ->>> ```C const int spiChannel = 1; const int spiSpeedInit = 250000; // Hz @@ -604,25 +611,26 @@ if ((hSPI = wiringPiSPISetup (spiChannel, spiSpeed)) < 0) { wiringPiSPIClose(spiChannel); ``` -### wiringPiSPIDataRW / wiringPiSPIxDataRW +### wiringPiSPIDataRW / wiringPiSPIxDataRW A synchronous fullduplex write and read operation is performed on the opened SPI bus. In the process, the sent data is overwritten by the received data. ->>> ```C -int wiringPiSPIDataRW (int channel, unsigned char *data, int len) -int wiringPiSPIxDataRW (const int number, const int channel, unsigned char *data, const int len) +int wiringPiSPIDataRW (int channel, unsigned char *data, int len); + +int wiringPiSPIxDataRW (const int number, const int channel, unsigned char *data, const int len); ``` -``number``: SPI muber (typically 0, on Compute Module 0-7). +``number``: SPI number (typically 0, on Compute Module 0-7). ``channel``: SPI channel (typically 0 or 1, on Compute Module 0-3). ``data``: Buffer ``len``: Size of ``data`` buffer or data size. -``Return Value``: Return Value of ``ioctl`` function (https://man7.org/linux/man-pages/man2/ioctl.2.html) -<0 ... Error, see ``errno`` for error number. +``Return Value``: Return Value of ``ioctl`` function ([https://man7.org/linux/man-pages/man2/ioctl.2.html](https://man7.org/linux/man-pages/man2/ioctl.2.html)) + +> 0 ... Error, see ``errno`` for error number. + +**Example** -**Example** ->>> ```C const int spiChannel = 1; const int spiSpeedInit = 250000; // Hz @@ -637,8 +645,9 @@ int returnvalue; spiData[0] = 0b11010000; spiData[1] = 0; spiData[2] = 0; + returnvalue = wiringPiSPIxDataRW(0, spiChannel, spiData, 3); -if (returnvalue<=0) { +if (returnvalue <= 0) { printf("SPI transfer error: %d\n", errno); } @@ -649,24 +658,25 @@ wiringPiSPIxClose(0, spiChannel); Returns the file handle to the opened SPI bus. ->>> ```C -int wiringPiSPIGetFd(int channel) -int wiringPiSPIxGetFd(const int number, int channel) +int wiringPiSPIGetFd(int channel); + +int wiringPiSPIxGetFd(const int number, int channel); ``` -``number``: SPI muber (typically 0, on Compute Module 0-7). +``number``: SPI number (typically 0, on Compute Module 0-7). ``channel``: SPI channel (typically 0 or 1, on Compute Module 0-3). -``Return Value``: File handle to the SPI bus +``Return Value``: File handle to the SPI bus + > -1 ... Invalid or not opened -**Example** ->>> +**Example** + ```C const int spiChannel = 1; const int spiSpeedInit = 250000; // Hz -int hSPI; +int hSPI; if ((hSPI = wiringPiSPISetup (spiChannel, spiSpeed)) < 0) { //error } From ab37fd21d6ae00760c44c93351d28ef769b92630 Mon Sep 17 00:00:00 2001 From: Mr-Fishy Date: Wed, 12 Mar 2025 12:03:39 -0700 Subject: [PATCH 25/65] Final Corrections & Added Basic Function Descriptions --- documentation/english/functions.md | 37 ++++++++++++++++++++++-------- 1 file changed, 27 insertions(+), 10 deletions(-) diff --git a/documentation/english/functions.md b/documentation/english/functions.md index 663892e..aad803d 100644 --- a/documentation/english/functions.md +++ b/documentation/english/functions.md @@ -217,7 +217,7 @@ After that, the corresponding clock and range values ​​can be adapted, witho ### digitalWrite -Set the value of a GPIO pin. +Writes the value `HIGH` or `LOW` (1 or 0) to the given pin which must have been previously set as an output. ```C void digitalWrite(int pin, int value); @@ -226,16 +226,21 @@ void digitalWrite(int pin, int value); ``pin``: The desired Pin (BCM-, Wiringpi- or PIN number). ``value``: The logical value... -- `HIGH` ... Value 1 (electrical ~ 3.3 V) +- `HIGH` ... Value 1 (electrical ~3.3 V) - `LOW` ... Value 0 (electrical ~0 V / GND) **Example:** ```C pinMode(17, OUTPUT); -DigitalWrite(17, HIGH); + +digitalWrite(17, HIGH); ``` +**Note** + +WiringPi treats any non-zero number as `HIGH`, however 0 is the only representation of `LOW`. + ### pullUpDnControl Changes the internal pull-up / pull-down resistance. @@ -248,8 +253,8 @@ void pullUpDnControl (int pin, int pud); ``pud``: The resistance type... - `PUD_OFF` ... No resistance -- `PUD_UP` ... Pull-Up resistance (~50 kOhm) -- `PUD_DOWN` ... Pull-Down resistance (~50 kOhm) +- `PUD_UP` ... Pull-Up to pull to 3.3v (~50 kOhm resistance) +- `PUD_DOWN` ... Pull-Down to pull to ground (~50 kOhm resistance) **Example:** @@ -259,7 +264,7 @@ pullUpDnControl(17, PUD_DOWN); ### digitalRead -Reads the value of one GPIO-Pin. +Reads the value of the given GPIO-Pin. It will be `HIGH` or `LOW` (1 or 0) depending on the logic level at the pin. ```C int digitalRead(int pin); @@ -269,7 +274,7 @@ int digitalRead(int pin); ``Return Value``: The logical value. > `HIGH` ... Value 1 -> `LOW` ... Value 0 +> `LOW` ... Value 0 **Example:** @@ -536,7 +541,19 @@ else { } ``` -### wiringPiI2CRead / wiringPiI2CReadReg8 / wiringPiI2CReadReg16 / wiringPiI2CReadBlockData +### wiringPiI2CRead + +Simple device read. Some devices accept data this way without needing to access any internal registers. + +### wiringPiI2CReadReg8 + +Reads an 8-bit data value into the device register indicated. + +### wiringPiI2CReadReg16 + +Reads an 16-bit data value into the device register indicated. + +### wiringPiI2CReadBlockData ... @@ -579,7 +596,7 @@ Functions that start with ``wiringPiSPIx`` are new since version 3, allowing th ### wiringPiSPISetup / wiringPiSPISetupMode / wiringPiSPIxSetupMode -Opens the specified SPI bus. +Opens the specified SPI bus. The Raspberry Pi has 2 channels, 0 and 1. The speed parameter is an integer in the range of 500,000 through 32,000,000 and represents the SPI clock speed in Hz. ```C int wiringPiSPISetup (int channel, int speed); @@ -591,7 +608,7 @@ int wiringPiSPIxSetupMode(const int number, const int channel, const int speed, ``number``: SPI number (typically 0, on Compute Module 0-7). ``channel``: SPI channel (typically 0 or 1, on Compute Module 0-3). -``speed``: SPI clock. +``speed``: SPI clock speed in Hz (500,000 to 32,000,000). ``mode``: SPI mode ([www.kernel.org/doc/Documentation/spi/spidev](https://www.kernel.org/doc/Documentation/spi/spidev)). ``Return Value``: File handle to the SPI bus, or -1 on error. From 7c2e519515f2f2bc8943a4e634e31b759a669c4e Mon Sep 17 00:00:00 2001 From: Mr-Fishy Date: Wed, 12 Mar 2025 12:24:28 -0700 Subject: [PATCH 26/65] Added CMake Linking Example --- README.md | 43 +++++++++++++++++++++++++++---------------- 1 file changed, 27 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index 574e017..794fe4f 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,9 @@ # WiringPi Library + Welcome to the WiringPi Library, the highly performant GPIO access library for Raspberry Pi boards. This library is written in C and is designed to provide fast and efficient control of the GPIO pins by directly accessing the hardware registers using DMA. -**Key Features:** +**Key Features:** + - **Support:** WiringPi supports all Raspberry Pi Boards including Pi 5 ( :construction: On the Pi 5, only the GCLK functionality is currently not supported due to missing documentation of the RP1 chip). - **High Performance:** By directly accessing the hardware registers, WiringPi ensures minimal latency and maximum performance for your GPIO operations. - **Wide Adoption:** WiringPi is widely used in numerous projects, making it a reliable choice for your Raspberry Pi GPIO needs. @@ -50,9 +52,23 @@ cd examples make ``` +To use WiringPi in a project with CMake, the following snippet is all that is required provided that WiringPi is installed. + +```CMake +add_executable(example + # project sources... +) + +target_link_libraries( + example + + PRIVATE wiringPi +) +``` + The tool `gpio` can be used to set single pins as well as get the state of everything at once: -``` +```none pi@wiringdemo:~ $ gpio readall +-----+-----+---------+------+---+---Pi 3B--+---+------+---------+-----+-----+ | BCM | wPi | Name | Mode | V | Physical | V | Mode | Name | wPi | BCM | @@ -82,12 +98,10 @@ pi@wiringdemo:~ $ gpio readall +-----+-----+---------+------+---+---Pi 3B--+---+------+---------+-----+-----+ ``` - ## Documentation -[German](https://github.com/WiringPi/WiringPi/blob/master/documentation/deutsch/functions.md) -[English](https://github.com/WiringPi/WiringPi/blob/master/documentation/english/functions.md) - +[German](./documentation/deutsch/functions.md) +[English](./documentation/english/functions.md) ## Installing @@ -111,12 +125,10 @@ mv debian-template/wiringpi-3.0-1.deb . sudo apt install ./wiringpi-3.0-1.deb ``` - ### Prebuilt Binaries Grab the latest release from [here](https://github.com/WiringPi/WiringPi/releases). - Unzip/use the portable prebuilt verison: ```sh @@ -131,16 +143,15 @@ Install the debian package: sudo apt install ./wiringpi-3.0-1.deb ``` - ## Ports wiringPi has been wrapped for multiple languages: -* Node - https://github.com/WiringPi/WiringPi-Node -* Perl - https://github.com/WiringPi/WiringPi-Perl -* PHP - https://github.com/WiringPi/WiringPi-PHP -* Python - https://github.com/WiringPi/WiringPi-Python -* Ruby - https://github.com/WiringPi/WiringPi-Ruby +- Node - [https://github.com/WiringPi/WiringPi-Node](https://github.com/WiringPi/WiringPi-Node) +- Perl - [https://github.com/WiringPi/WiringPi-Perl](https://github.com/WiringPi/WiringPi-Perl) +- PHP - [https://github.com/WiringPi/WiringPi-PHP](https://github.com/WiringPi/WiringPi-PHP) +- Python - [https://github.com/WiringPi/WiringPi-Python](https://github.com/WiringPi/WiringPi-Python) +- Ruby - [https://github.com/WiringPi/WiringPi-Ruby](https://github.com/WiringPi/WiringPi-Ruby) ## Support @@ -156,9 +167,9 @@ Please don't email GC2 for reporting issues, you might [contact us](mailto:wirin This repository is the continuation of 'Gordon's wiringPi 2.5' which has been [deprecated](https://web.archive.org/web/20220405225008/http://wiringpi.com/wiringpi-deprecated/), a while ago. -* The last "old wiringPi" source of Gordon's release can be found at the +- The last "old wiringPi" source of Gordon's release can be found at the [`final_source_2.50`](https://github.com/WiringPi/WiringPi/tree/final_official_2.50) tag. -* The default `master` branch contains code that has been written since version 2.5 +- The default `master` branch contains code that has been written since version 2.5 to provide support for newer hardware as well as new features. :information_source:️ Since 2024, [GC2](https://github.com/GrazerComputerClub) has taken over maintenance of the project, supporting new OS versions as well as current hardware generations. We are dedicated to keeping the arguably best-performing GPIO Library for Raspberry Pi running smoothly. We strive to do our best, but please note that this is a community effort, and we cannot provide any guarantees or take responsibility for implementing specific features you may need. From 2a848b5de1a9c5fdcb7f81390956967d4142c756 Mon Sep 17 00:00:00 2001 From: kovianyo Date: Fri, 18 Apr 2025 13:59:03 +0200 Subject: [PATCH 27/65] Using spaces instead of tabs in gpio usage text --- gpio/gpio.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/gpio/gpio.c b/gpio/gpio.c index 3fc97a3..1186a65 100644 --- a/gpio/gpio.c +++ b/gpio/gpio.c @@ -71,18 +71,18 @@ char *usage = "Usage: gpio -v\n" " gpio [-p] ...\n" " gpio ...\n" " gpio \n" - " gpio readall\n" - " gpio wfi \n" - " gpio drive \n" - " gpio pwm-bal/pwm-ms \n" - " gpio pwmr \n" - " gpio pwmc \n" - " gpio i2cd/i2cdetect\n" - " gpio rbx/rbd\n" - " gpio wb \n" - " gpio usbp high/low\n" - " gpio gbr \n" - " gpio gbw " ; // No trailing newline needed here. + " gpio readall\n" + " gpio wfi \n" + " gpio drive \n" + " gpio pwm-bal/pwm-ms \n" + " gpio pwmr \n" + " gpio pwmc \n" + " gpio i2cd/i2cdetect\n" + " gpio rbx/rbd\n" + " gpio wb \n" + " gpio usbp high/low\n" + " gpio gbr \n" + " gpio gbw " ; // No trailing newline needed here. #ifdef NOT_FOR_NOW From 9d34a0a9b57825729ddb1df0eba556e91d78221d Mon Sep 17 00:00:00 2001 From: kovianyo Date: Fri, 18 Apr 2025 14:03:10 +0200 Subject: [PATCH 28/65] Describing pin numbering arguments and wfi modes in gpio usage text --- gpio/gpio.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/gpio/gpio.c b/gpio/gpio.c index 1186a65..447e53d 100644 --- a/gpio/gpio.c +++ b/gpio/gpio.c @@ -66,6 +66,9 @@ int wpMode ; char *usage = "Usage: gpio -v\n" " gpio -h\n" " gpio [-g|-1] ...\n" + " where -g: pin numbering according to readall BCM column\n" + " where -1: pin numbering according to readall Physical column\n" + " when omitted: pin numbering according to readall wPi column\n" " gpio [-d] ...\n" " [-x extension:params] [[ -x ...]] ...\n" " gpio [-p] ...\n" @@ -73,6 +76,7 @@ char *usage = "Usage: gpio -v\n" " gpio \n" " gpio readall\n" " gpio wfi \n" + " where can be: rising, falling, both\n" " gpio drive \n" " gpio pwm-bal/pwm-ms \n" " gpio pwmr \n" From 38274fe6e89f0403f778af9e9ecba83002537861 Mon Sep 17 00:00:00 2001 From: mstroh76 Date: Fri, 2 May 2025 13:10:40 +0200 Subject: [PATCH 29/65] #346 GPIO Character Device Userspace API V2 - compatibility to old interface --- VERSION | 2 +- gpio/gpio.c | 4 +- version.h | 4 +- wiringPi/WiringpiV1.c | 246 +++++++++++++++++++++++ wiringPi/test/wiringpi_test1_sysfs.c | 1 + wiringPi/wiringPi.c | 287 ++++++++++++++++----------- wiringPi/wiringPi.h | 18 +- 7 files changed, 437 insertions(+), 125 deletions(-) create mode 100644 wiringPi/WiringpiV1.c diff --git a/VERSION b/VERSION index 1bc446c..230693c 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -3.16 \ No newline at end of file +3.15 \ No newline at end of file diff --git a/gpio/gpio.c b/gpio/gpio.c index 1ee2c33..9ffb1b7 100644 --- a/gpio/gpio.c +++ b/gpio/gpio.c @@ -177,7 +177,7 @@ void printgpio(const char* text) { } } -static void wfi (UNU struct WPIWfiStatus wfiStatus) { +static void wfi (void) { globalCounter++; if(globalCounter>=iterations) { printgpio("finished\n"); @@ -217,7 +217,7 @@ void doWfi (int argc, char *argv []) timeoutSec = atoi(argv [5]); } - if (wiringPiISR (pin, mode, &wfi, 0) < 0) + if (wiringPiISR (pin, mode, &wfi) < 0) { fprintf (stderr, "%s: wfi: Unable to setup ISR: %s\n", argv [1], strerror (errno)) ; exit (1) ; diff --git a/version.h b/version.h index 5ea1e8c..d7f42c6 100644 --- a/version.h +++ b/version.h @@ -1,3 +1,3 @@ -#define VERSION "3.16" +#define VERSION "3.15" #define VERSION_MAJOR 3 -#define VERSION_MINOR 16 +#define VERSION_MINOR 15 diff --git a/wiringPi/WiringpiV1.c b/wiringPi/WiringpiV1.c new file mode 100644 index 0000000..fe6b5ce --- /dev/null +++ b/wiringPi/WiringpiV1.c @@ -0,0 +1,246 @@ +#include "Wiringpi.h" + + +int requestLineV1(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 (wiringPiGpioDeviceGetFd()<0) { + return -1; // error + } + rq.lineoffsets[0] = pin; + rq.lines = 1; + rq.flags = 0; + // MAP to V1 Flag + if (lineRequestFlags & WPI_FLAG_INPUT) { + rq.flags |= GPIOHANDLE_REQUEST_INPUT; + } + if (lineRequestFlags & WPI_FLAG_OUTPUT) { + rq.flags |= GPIOHANDLE_REQUEST_OUTPUT; + } + if (lineRequestFlags & WPI_FLAG_BIAS_OFF) { + rq.flags |= GPIOHANDLE_REQUEST_BIAS_DISABLE; + } + if (lineRequestFlags & WPI_FLAG_BIAS_UP) { + rq.flags |= GPIOHANDLE_REQUEST_BIAS_PULL_UP; + } + if (lineRequestFlags & WPI_FLAG_BIAS_DOWN) { + rq.flags |= GPIOHANDLE_REQUEST_BIAS_PULL_DOWN; + } + int ret = ioctl(chipFd, GPIO_GET_LINEHANDLE_IOCTL, &rq); + if (ret || rq.fd<0) { + ReportDeviceError("get line handle", pin, "RequestLineV1", 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]; + } + + + int digitalReadDeviceV1(int pin) { // INPUT and OUTPUT should work + + if (lineFds[pin]<0) { + // line not requested - auto request on first read as input + pinModeDevice(pin, INPUT); + } + 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]; + } + return LOW; // error , need to request line before + } + + + void digitalWriteDeviceV1(int pin, int value) { + + if (wiringPiDebug) + printf ("digitalWriteDevice: ioctl pin:%d value: %d\n", pin, value) ; + + if (lineFds[pin]<0) { + // line not requested - auto request on first write as output + pinModeDevice(pin, OUTPUT); + } + 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]); + } + return; // error + } + + /* + * waitForInterrupt: + * Pi Specific. + * Wait for Interrupt on a GPIO pin. + * This is actually done via the /dev/gpiochip interface regardless of + * the wiringPi access mode in-use. Maybe sometime it might get a better + * way for a bit more efficiency. + ********************************************************************************* + */ + +int waitForInterruptV1(int pin, int mS) +{ + int fd, ret; + struct pollfd polls ; + struct gpioevent_data evdata; + //struct gpio_v2_line_request req2; + + if (wiringPiMode == WPI_MODE_PINS) + pin = pinToGpio [pin] ; + else if (wiringPiMode == WPI_MODE_PHYS) + pin = physToGpio [pin] ; + + if ((fd = isrFds [pin]) == -1) + return -2 ; + + // Setup poll structure + polls.fd = fd; + polls.events = POLLIN | POLLERR ; + polls.revents = 0; + + // Wait for it ... + ret = poll(&polls, 1, mS); + if (ret <= 0) { + fprintf(stderr, "wiringPi: ERROR: poll returned=%d\n", ret); + } else { + //if (polls.revents & POLLIN) + if (wiringPiDebug) { + printf ("wiringPi: IRQ line %d received %d, fd=%d\n", pin, ret, isrFds[pin]) ; + } + /* read event data */ + 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) ; + } + ret = evdata.id; + } else { + ret = 0; + } + } + return ret; +} + +int waitForInterruptInitV1(int pin, int mode) +{ + const char* strmode = ""; + + if (wiringPiMode == WPI_MODE_PINS) { + pin = pinToGpio [pin] ; + } else if (wiringPiMode == WPI_MODE_PHYS) { + pin = physToGpio [pin] ; + } + + /* open gpio */ + sleep(1); + if (wiringPiGpioDeviceGetFd()<0) { + return -1; + } + + struct gpioevent_request req; + req.lineoffset = pin; + req.handleflags = GPIOHANDLE_REQUEST_INPUT; + switch(mode) { + default: + case INT_EDGE_SETUP: + if (wiringPiDebug) { + printf ("wiringPi: waitForInterruptMode mode INT_EDGE_SETUP - exiting\n") ; + } + return -1; + case INT_EDGE_FALLING: + req.eventflags = GPIOEVENT_REQUEST_FALLING_EDGE; + strmode = "falling"; + break; + case INT_EDGE_RISING: + req.eventflags = GPIOEVENT_REQUEST_RISING_EDGE; + strmode = "rising"; + break; + case INT_EDGE_BOTH: + req.eventflags = GPIOEVENT_REQUEST_BOTH_EDGES; + strmode = "both"; + break; + } + strncpy(req.consumer_label, "wiringpi_gpio_irq", sizeof(req.consumer_label) - 1); + + //later implement GPIO_V2_GET_LINE_IOCTL req2 + int ret = ioctl(chipFd, GPIO_GET_LINEEVENT_IOCTL, &req); + if (ret) { + ReportDeviceError("get line event", pin , strmode, ret); + return -1; + } + if (wiringPiDebug) { + printf ("wiringPi: GPIO get line %d , mode %s succeded, fd=%d\n", pin, strmode, req.fd) ; + } + + /* set event fd nonbloack read */ + int fd_line = req.fd; + isrFds [pin] = fd_line; + int flags = fcntl(fd_line, F_GETFL); + flags |= O_NONBLOCK; + ret = fcntl(fd_line, F_SETFL, flags); + if (ret) { + fprintf(stderr, "wiringPi: ERROR: fcntl set nonblock return=%d\n", ret); + return -1; + } + + return 0; +} + + +int waitForInterruptClose (int pin) { + if (isrFds[pin]>0) { + if (wiringPiDebug) { + printf ("wiringPi: waitForInterruptClose close thread 0x%lX\n", (unsigned long)isrThreads[pin]) ; + } + if (pthread_cancel(isrThreads[pin]) == 0) { + if (wiringPiDebug) { + printf ("wiringPi: waitForInterruptClose thread canceled successfuly\n") ; + } + } else { + if (wiringPiDebug) { + fprintf (stderr, "wiringPi: waitForInterruptClose could not cancel thread\n"); + } + } + close(isrFds [pin]); + } + 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 + if (chipFd>0) { + close(chipFd); + } + chipFd = -1; + */ + if (wiringPiDebug) { + printf ("wiringPi: waitForInterruptClose finished\n") ; + } + return 0; +} diff --git a/wiringPi/test/wiringpi_test1_sysfs.c b/wiringPi/test/wiringpi_test1_sysfs.c index a97f85e..cc2af6b 100644 --- a/wiringPi/test/wiringpi_test1_sysfs.c +++ b/wiringPi/test/wiringpi_test1_sysfs.c @@ -52,6 +52,7 @@ int main (void) { delayMicroseconds(600000); } + //Error wrong direction - only for fun digitalWrite(GPIO, LOW); diff --git a/wiringPi/wiringPi.c b/wiringPi/wiringPi.c index 0f2ea7d..ee8fbb7 100644 --- a/wiringPi/wiringPi.c +++ b/wiringPi/wiringPi.c @@ -454,6 +454,15 @@ int wiringPiReturnCodes = FALSE ; int wiringPiTryGpioMem = FALSE ; +enum WPIFlag { + WPI_FLAG_INPUT = 0x04, + WPI_FLAG_OUTPUT = 0x08, + WPI_FLAG_BIAS_UP = 0x100, + WPI_FLAG_BIAS_DOWN= 0x200, + WPI_FLAG_BIAS_OFF = 0x400, +}; + + static unsigned int lineFlags [64] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -482,10 +491,11 @@ static int isrFds [64] = // ISR Data static int chipFd = -1; -static void (*isrFunctions [64])(struct WPIWfiStatus) ; +static void (*isrFunctionsV2[64])(struct WPIWfiStatus) ; +static void (*isrFunctions [64])(void) ; static pthread_t isrThreads[64]; -static int isrMode[64]; // irq on rising/falling edge -static unsigned long isrDebouncePeriodUs [64]; // 0: debounce is off +static int isrEdgeMode[64]; // irq on rising/falling edge +static unsigned long isrDebouncePeriodUs[64]; // 0: debounce is off // Doing it the Arduino way with lookup tables... // Yes, it's probably more innefficient than all the bit-twidling, but it @@ -1760,7 +1770,8 @@ void releaseLine(int pin) { isrDebouncePeriodUs[pin] = 0; } -int requestLine(int pin, unsigned int lineRequestFlags) { + +int requestLineV2(int pin, const unsigned int lineRequestFlags) { struct gpio_v2_line_request req; struct gpio_v2_line_config config; int ret; @@ -1782,7 +1793,24 @@ int requestLine(int pin, unsigned int lineRequestFlags) { memset(&req, 0, sizeof(req)); memset(&config, 0, sizeof(config)); - config.flags = lineRequestFlags; + if (lineRequestFlags & WPI_FLAG_INPUT) { + config.flags |= GPIO_V2_LINE_FLAG_INPUT; + } + if (lineRequestFlags & WPI_FLAG_OUTPUT) { + config.flags |= GPIO_V2_LINE_FLAG_OUTPUT; + } + if (lineRequestFlags & WPI_FLAG_BIAS_OFF) { + config.flags |= GPIO_V2_LINE_FLAG_BIAS_DISABLED; + } + if (lineRequestFlags & WPI_FLAG_BIAS_UP) { + config.flags |= GPIO_V2_LINE_FLAG_BIAS_PULL_UP; + } + if (lineRequestFlags & WPI_FLAG_BIAS_DOWN) { + config.flags |= GPIO_V2_LINE_FLAG_BIAS_PULL_DOWN; + } + if (wiringPiDebug) { + printf ("requestLine flags v2: %llu\n", config.flags); + } strcpy(req.consumer, "wiringpi_gpio_req"); req.offsets[0] = pin; @@ -1792,14 +1820,14 @@ int requestLine(int pin, unsigned int lineRequestFlags) { ret = ioctl(chipFd, GPIO_V2_GET_LINE_IOCTL, &req); if (ret || req.fd<0) { - ReportDeviceError("get line handle", pin, "RequestLine", ret); + ReportDeviceError("get line handle v2", pin, "RequestLine", ret); return -1; // error } lineFlags[pin] = lineRequestFlags; lineFds[pin] = req.fd; if (wiringPiDebug) - printf ("requestLine succeeded: pin:%d, flags: %u, fd :%d\n", pin, lineRequestFlags, lineFds[pin]) ; + printf ("requestLine succeeded: pin:%d, flags: 0x%u, fd :%d\n", pin, lineRequestFlags, lineFds[pin]) ; return lineFds[pin]; } @@ -1892,21 +1920,21 @@ 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) { +void pinModeFlagsDevice (int pin, int mode, const unsigned int flags) { unsigned int lflag = flags; - if (wiringPiDebug) + if (wiringPiDebug) { printf ("pinModeFlagsDevice: pin:%d mode:%d, flags: %u\n", pin, mode, flags) ; - - lflag &= ~(GPIO_V2_LINE_FLAG_INPUT | GPIO_V2_LINE_FLAG_OUTPUT); + } + lflag &= ~(WPI_FLAG_INPUT | WPI_FLAG_OUTPUT); switch(mode) { default: fprintf(stderr, "pinMode: invalid mode request (only input und output supported)\n"); return; case INPUT: - lflag |= GPIO_V2_LINE_FLAG_INPUT; + lflag |= WPI_FLAG_INPUT; break; case OUTPUT: - lflag |= GPIO_V2_LINE_FLAG_OUTPUT; + lflag |= WPI_FLAG_OUTPUT; break; case PM_OFF: pinModeFlagsDevice(pin, INPUT, 0); @@ -1914,7 +1942,7 @@ void pinModeFlagsDevice (int pin, int mode, unsigned int flags) { return; } - requestLine(pin, lflag); + requestLineV2(pin, lflag); } void pinModeDevice (int pin, int mode) { @@ -2072,20 +2100,20 @@ void pinMode (int pin, int mode) */ void pullUpDnControlDevice (int pin, int pud) { unsigned int flag = lineFlags[pin]; - unsigned int biasflags = GPIO_V2_LINE_FLAG_BIAS_DISABLED | GPIO_V2_LINE_FLAG_BIAS_PULL_UP | GPIO_V2_LINE_FLAG_BIAS_PULL_DOWN; + unsigned int biasflags = WPI_FLAG_BIAS_OFF | WPI_FLAG_BIAS_UP | WPI_FLAG_BIAS_DOWN; flag &= ~biasflags; switch (pud){ - case PUD_OFF: flag |= GPIO_V2_LINE_FLAG_BIAS_DISABLED; break; - case PUD_UP: flag |= GPIO_V2_LINE_FLAG_BIAS_PULL_UP; break; - case PUD_DOWN: flag |= GPIO_V2_LINE_FLAG_BIAS_PULL_DOWN; break; + case PUD_OFF: flag |= WPI_FLAG_BIAS_OFF; break; + case PUD_UP: flag |= WPI_FLAG_BIAS_UP; break; + case PUD_DOWN: flag |= WPI_FLAG_BIAS_DOWN; break; default: return ; /* An illegal value */ } // reset input/output - if (lineFlags[pin] & GPIO_V2_LINE_FLAG_OUTPUT) { + if (lineFlags[pin] & WPI_FLAG_OUTPUT) { pinModeFlagsDevice (pin, OUTPUT, flag); - } else if(lineFlags[pin] & GPIO_V2_LINE_FLAG_INPUT) { + } else if(lineFlags[pin] & WPI_FLAG_INPUT) { pinModeFlagsDevice (pin, INPUT, flag); } else { lineFlags[pin] = flag; // only store for later @@ -2204,7 +2232,7 @@ static inline int gpiotools_test_bit(__u64 b, int n) ********************************************************************************* */ -int digitalReadDevice (int pin) { // INPUT and OUTPUT should work +int digitalReadDeviceV2(int pin) { // INPUT and OUTPUT should work struct gpio_v2_line_values lv; int ret; @@ -2244,11 +2272,11 @@ int digitalRead (int pin) pin = physToGpio [pin]; break; case WPI_MODE_GPIO_DEVICE_BCM: - return digitalReadDevice(pin); + return digitalReadDeviceV2(pin); case WPI_MODE_GPIO_DEVICE_WPI: - return digitalReadDevice(pinToGpio[pin]); + return digitalReadDeviceV2(pinToGpio[pin]); case WPI_MODE_GPIO_DEVICE_PHYS: - return digitalReadDevice(physToGpio[pin]); + return digitalReadDeviceV2(physToGpio[pin]); case WPI_MODE_GPIO: break; } @@ -2302,12 +2330,12 @@ unsigned int digitalRead8 (int pin) ********************************************************************************* */ -void digitalWriteDevice (int pin, int value) { +void digitalWriteDeviceV2(int pin, int value) { int ret; struct gpio_v2_line_values values; if (wiringPiDebug) - printf ("digitalWriteDevice: ioctl pin:%d value: %d\n", pin, value) ; + printf ("digitalWriteDeviceV2: ioctl pin:%d value: %d\n", pin, value) ; if (lineFds[pin]<0) { // line not requested - auto request on first write as output @@ -2320,13 +2348,13 @@ void digitalWriteDevice (int pin, int value) { gpiotools_set_bit(&values.mask, 0); gpiotools_assign_bit(&values.bits, 0, !!value); - ret = ioctl(lineFds[pin], GPIO_V2_LINE_SET_VALUES_IOCTL, &values); - if (ret == -1) { - ReportDeviceError("digitalWriteDevice", pin, "GPIO_V2_LINE_SET_VALUES_IOCTL", ret); - return; // error - } + ret = ioctl(lineFds[pin], GPIO_V2_LINE_SET_VALUES_IOCTL, &values); + if (ret == -1) { + ReportDeviceError("digitalWriteDeviceV2", pin, "GPIO_V2_LINE_SET_VALUES_IOCTL", ret); + return; // error + } } else { - fprintf(stderr, "digitalWrite: no output (%d)\n", lineFlags[pin]); + fprintf(stderr, "digitalWriteDeviceV2: no output (%d)\n", lineFlags[pin]); } return; // error } @@ -2349,13 +2377,13 @@ void digitalWrite (int pin, int value) pin = physToGpio [pin]; break; case WPI_MODE_GPIO_DEVICE_BCM: - digitalWriteDevice(pin, value); + digitalWriteDeviceV2(pin, value); return; case WPI_MODE_GPIO_DEVICE_WPI: - digitalWriteDevice(pinToGpio[pin], value); + digitalWriteDeviceV2(pinToGpio[pin], value); return; case WPI_MODE_GPIO_DEVICE_PHYS: - digitalWriteDevice(physToGpio[pin], value); + digitalWriteDeviceV2(physToGpio[pin], value); return; case WPI_MODE_GPIO: break; @@ -2631,17 +2659,13 @@ unsigned int digitalReadByte2 (void) /* - * waitForInterrupt: - * Pi Specific. - * Wait for Interrupt on a GPIO pin. - * This is actually done via the /dev/gpiochip interface regardless of - * the wiringPi access mode in-use. Maybe sometime it might get a better - * way for a bit more efficiency. + * waitForInterrupt2: + * Wait for Interrupt on a GPIO pin and use v2 of the character device API, need Kernel 5.1 * Returns struct WPIWfiStatus ********************************************************************************* */ -struct WPIWfiStatus waitForInterrupt (int pin, int edgeMode, int mS, unsigned long debounce_period_us) // ms < 0 wait infinite, = 0 return immediately, > 0 wait timeout +struct WPIWfiStatus waitForInterrupt2(int pin, int edgeMode, int ms, unsigned long debounce_period_us) // ms < 0 wait infinite, = 0 return immediately, > 0 wait timeout { int ret; int fd, attr, status, readret; @@ -2675,7 +2699,7 @@ struct WPIWfiStatus waitForInterrupt (int pin, int edgeMode, int mS, unsigned lo default: case INT_EDGE_SETUP: if (wiringPiDebug) { - printf ("waitForInterrupt: edgeMode INT_EDGE_SETUP - exiting\n") ; + printf ("waitForInterrupt2: edgeMode INT_EDGE_SETUP - exiting\n") ; } wfiStatus.status = -1; return wfiStatus; @@ -2695,11 +2719,11 @@ struct WPIWfiStatus waitForInterrupt (int pin, int edgeMode, int mS, unsigned lo strcpy(req.consumer, "wiringpi_gpio_irq"); if (debounce_period_us) { - attr = config.num_attrs; - config.num_attrs++; + attr = config.num_attrs; + config.num_attrs++; gpiotools_set_bit(&config.attrs[attr].mask, 0); - config.attrs[attr].attr.id = GPIO_V2_LINE_ATTR_ID_DEBOUNCE; - config.attrs[attr].attr.debounce_period_us = debounce_period_us; + config.attrs[attr].attr.id = GPIO_V2_LINE_ATTR_ID_DEBOUNCE; + config.attrs[attr].attr.debounce_period_us = debounce_period_us; } req.num_lines = 1; @@ -2715,7 +2739,7 @@ struct WPIWfiStatus waitForInterrupt (int pin, int edgeMode, int mS, unsigned lo } if (wiringPiDebug) { - printf ("waitForInterrupt: GPIO get line %d , mode %s succeded, fd=%d\n", pin, strmode, req.fd) ; + printf ("waitForInterrupt2: GPIO get line %d , mode %s succeded, fd=%d\n", pin, strmode, req.fd) ; } fd = req.fd; @@ -2738,48 +2762,47 @@ struct WPIWfiStatus waitForInterrupt (int pin, int edgeMode, int mS, unsigned lo polls.events = POLLIN | POLLPRI; polls.revents = 0; - ret = poll(&polls, 1, mS); + ret = poll(&polls, 1, ms); if (ret < 0) { if (wiringPiDebug) { - fprintf(stderr, "waitForInterrupt: ERROR: poll returned=%d\n", ret); + fprintf(stderr, "waitForInterrupt2: ERROR: poll returned=%d\n", ret); } wfiStatus.status = -1; } else if (ret == 0) { if (wiringPiDebug) { - fprintf(stderr, "waitForInterrupt: timeout: poll returned=%d\n", ret); + fprintf(stderr, "waitForInterrupt2: timeout: poll returned zero\n"); } wfiStatus.status = 0; } else { - if (wiringPiDebug) - printf ("waitForInterrupt: IRQ line %d received %d, fd=%d\n", pin, ret, isrFds[pin]) ; + if (wiringPiDebug) { + printf ("waitForInterrupt2: IRQ line %d received %d, fd=%d\n", pin, ret, isrFds[pin]); + } if (polls.revents & POLLIN) { /* read event data */ readret = read(isrFds [pin], &evdata, sizeof(evdata)); if (readret == sizeof(evdata)) { - if (wiringPiDebug) - printf ("waitForInterrupt: IRQ at PIN: %d, timestamp: %lld\n", evdata.offset, evdata.timestamp_ns) ; - + if (wiringPiDebug) { + printf ("waitForInterrupt2: IRQ at PIN: %d, timestamp: %lld\n", evdata.offset, evdata.timestamp_ns) ; + } switch (evdata.id) { - case GPIO_V2_LINE_EVENT_RISING_EDGE: + case GPIO_V2_LINE_EVENT_RISING_EDGE: wfiStatus.edge = INT_EDGE_RISING; - if (wiringPiDebug) - printf("waitForInterrupt: rising edge\n"); - break; - case GPIO_V2_LINE_EVENT_FALLING_EDGE: + if (wiringPiDebug) printf("waitForInterrupV2: rising edge\n"); + break; + case GPIO_V2_LINE_EVENT_FALLING_EDGE: wfiStatus.edge = INT_EDGE_FALLING; - if (wiringPiDebug) - printf("waitForInterrupt: falling edge\n"); - break; - default: + if (wiringPiDebug) printf("waitForInterrupt2: falling edge\n"); + break; + default: wfiStatus.edge = INT_EDGE_SETUP; // edge = 0 - if (wiringPiDebug) - printf("waitForInterrupt: unknown event\n"); + if (wiringPiDebug) printf("waitForInterrupt2: unknown event\n"); break; - } + } wfiStatus.timeStamp_us = evdata.timestamp_ns / 1000LL; // nanoseconds u64 to microseconds - wfiStatus.gpioPin = evdata.offset; + wfiStatus.pin = evdata.offset; + wfiStatus.id = evdata.id; wfiStatus.status = 1; } else { @@ -2800,6 +2823,19 @@ struct WPIWfiStatus waitForInterrupt (int pin, int edgeMode, int mS, unsigned lo return wfiStatus; } +int waitForInterrupt (int pin, int ms) { + struct WPIWfiStatus status; + + int edgeMode = isrEdgeMode[pin]; + if (edgeMode==0) { + fprintf(stderr, "waitForInterrupt: ERROR: edge mode missing, legacy function, please use waitForInterrupt2!\n"); + return -1; + } + status = waitForInterrupt2(pin, edgeMode, ms, 0); + + return status.id; +} + /* * wiringPiISRStop: * stop interruptHandler thread and @@ -2835,7 +2871,8 @@ int wiringPiISRStop (int pin) { close(isrFds [pin]); } isrFds [pin] = -1; - isrFunctions [pin] = NULL; + isrFunctions[pin] = NULL; + isrFunctionsV2[pin] = NULL; isrDebouncePeriodUs[pin] = 0; /* -not closing so far - other isr may be using it - only close if no other is using - will code later @@ -2845,24 +2882,27 @@ int wiringPiISRStop (int pin) { chipFd = -1; */ if (wiringPiDebug) { - printf ("waitForInterruptClose: waitForInterruptClose finished\n") ; + printf ("wiringPiISRStop: wiringPiISRStop finished\n") ; } return 0; } +int waitForInterruptClose(int pin) { + return wiringPiISRStop(pin); +} /* - * interruptHandler: + * interruptHandlerV2: * This is a thread and gets started to wait for the interrupt we're * hoping to catch. It will call the user-function when the interrupt * fires. ********************************************************************************* */ -void *interruptHandler (void *arg) +void *interruptHandlerV2(void *arg) { const char* strmode = ""; - int pin, mode, ret, fd, attr, i; + int pin, EdgeMode, ret, fd, attr, i; unsigned int readret; unsigned long debounce_period_us; struct pollfd polls ; @@ -2878,11 +2918,11 @@ void *interruptHandler (void *arg) return NULL; } - mode = isrMode[pin]; + EdgeMode = isrEdgeMode[pin]; debounce_period_us = isrDebouncePeriodUs[pin]; if (wiringPiDebug) { - printf ("interruptHandler: GPIO line %d, mode %d, debounce_period_us %lu \n", pin, mode, debounce_period_us) ; + printf ("interruptHandlerV2: GPIO line %d, edge mode %d, debounce_period_us %lu \n", pin, EdgeMode, debounce_period_us) ; } memset(&req, 0, sizeof(req)); @@ -2890,11 +2930,11 @@ void *interruptHandler (void *arg) /* setup config */ config.flags = GPIO_V2_LINE_FLAG_INPUT; - switch(mode) { + switch(EdgeMode) { default: case INT_EDGE_SETUP: if (wiringPiDebug) { - printf ("interruptHandler: waitForInterruptMode mode INT_EDGE_SETUP - exiting\n") ; + printf ("interruptHandlerV2: waitForInterruptMode edge mode INT_EDGE_SETUP - exiting\n") ; } return NULL; case INT_EDGE_FALLING: @@ -2927,12 +2967,12 @@ void *interruptHandler (void *arg) ret = ioctl(chipFd, GPIO_V2_GET_LINE_IOCTL, &req); if (ret == -1) { - ReportDeviceError("interruptHandler: get line event", pin , strmode, ret); + ReportDeviceError("interruptHandlerV2: get line event", pin , strmode, ret); return NULL; } if (wiringPiDebug) - printf ("interruptHandler: GPIO get line %d , mode %s succeded, fd=%d\n", pin, strmode, req.fd) ; + printf ("interruptHandlerV2: GPIO get line %d , mode %s succeded, fd=%d\n", pin, strmode, req.fd) ; /* set event fd */ fd = req.fd; @@ -2940,7 +2980,7 @@ void *interruptHandler (void *arg) (void)piHiPri (55) ; // Only effective if we run as root - for (;;) { // check if event data is available, check if interruptHandler thread must be canceled + for (;;) { // check if event data is available, check if interruptHandlerV2 thread must be canceled // Setup poll structure polls.fd = fd; @@ -2952,58 +2992,71 @@ void *interruptHandler (void *arg) if (ret < 0) { // we do not reach this point if canceled, ppoll does not return, is Cancellation Point if (wiringPiDebug) - printf("interruptHandler: ERROR: poll returned=%d\n", ret); + printf("interruptHandlerV2: ERROR: poll returned=%d\n", ret); pthread_exit(NULL); return NULL; // never landing here } else if (ret == 0) { // if (wiringPiDebug) -// printf("interruptHandler: timeout: poll returned=%d\n", ret); +// printf("interruptHandlerV2: timeout: poll returned=%d\n", ret); continue; } else { if (wiringPiDebug) - printf ("interruptHandler: IRQ line %d received %d events, fd=%d\n", pin, ret, isrFds[pin]) ; + printf ("interruptHandlerV2: IRQ line %d received %d events, fd=%d\n", pin, ret, isrFds[pin]) ; if (polls.revents & POLLIN) { /* read event data */ readret = read(fd, &evdat, sizeof(evdat)); if (readret >= sizeof(evdat[0])) { if (wiringPiDebug) - printf ("interruptHandler: IRQ at PIN: %d, events: %u\n", evdat[0].offset, readret/(unsigned int)sizeof(evdat[0])) ; + printf ("interruptHandlerV2: IRQ at PIN: %d, events: %u\n", evdat[0].offset, readret/(unsigned int)sizeof(evdat[0])) ; ret = readret/sizeof(evdat[0]); // number of events read from fd - if (wiringPiDebug) - printf ("interruptHandler: call function\n") ; for (i = 0; i < ret; ++i) { - if (isrFunctions [pin]) { + if (isrFunctionsV2[pin]) { if (wiringPiDebug) - printf( "interruptHandler: GPIO EVENT at %" PRIu64 " on line %d (%d|%d) \n", (uint64_t)evdat[i].timestamp_ns, evdat[i].offset, evdat[i].line_seqno, evdat[i].seqno); + printf( "interruptHandlerV2: GPIO EVENT at %llu on line %u (%u|%u) \n", evdat[i].timestamp_ns, evdat[i].offset, evdat[i].line_seqno, evdat[i].seqno); wfiStatus.status = 1; - wfiStatus.gpioPin = pin; + wfiStatus.pin = pin; switch (evdat[i].id) { case GPIO_V2_LINE_EVENT_RISING_EDGE: wfiStatus.edge = INT_EDGE_RISING; if (wiringPiDebug) - printf("waitForInterrupt: rising edge\n"); + printf("waitForInterrupt2: rising edge\n"); break; case GPIO_V2_LINE_EVENT_FALLING_EDGE: wfiStatus.edge = INT_EDGE_FALLING; if (wiringPiDebug) - printf("waitForInterrupt: falling edge\n"); + printf("waitForInterrupt2: falling edge\n"); break; default: wfiStatus.edge = INT_EDGE_SETUP; // edge = 0 if (wiringPiDebug) - printf("waitForInterrupt: unknown event\n"); + printf("waitForInterrupt2: unknown event\n"); break; } wfiStatus.timeStamp_us = evdat[i].timestamp_ns/1000LL; - isrFunctions [pin] (wfiStatus) ; + if (wiringPiDebug) { + printf( "interruptHandlerV2: call isr function\n"); + } + isrFunctionsV2[pin](wfiStatus); + if (wiringPiDebug) { + printf( "interruptHandlerV2: return from isr function\n"); + } + } + if (isrFunctions[pin]) { + if (wiringPiDebug) { + printf( "interruptHandlerV2: call isr function classic\n"); + } + isrFunctions[pin](); + if (wiringPiDebug) { + printf( "interruptHandlerV2: return from isr function classic\n"); + } } } } else { // if thread canceled we do not reach this point, read(...) does not return, is Cancellation Point if (wiringPiDebug) - printf ("interruptHandler: reading events from fd received signal, exit thread\n"); + printf ("interruptHandlerV2: reading events from fd received signal, exit thread\n"); pthread_exit(NULL); return NULL; // never landing here } @@ -3022,7 +3075,7 @@ void *interruptHandler (void *arg) ********************************************************************************* */ -int wiringPiISR (int pin, int edgeMode, void (*function)(struct WPIWfiStatus wfiStatus), unsigned long debounce_period_us) +int wiringPiISRInternal(int pin, int edgeMode, void (*function)(struct WPIWfiStatus wfiStatus), void (*functionClassic)(void), unsigned long debounce_period_us) { const int maxpin = GetMaxPin(); @@ -3040,12 +3093,13 @@ int wiringPiISR (int pin, int edgeMode, void (*function)(struct WPIWfiStatus wfi if (wiringPiDebug) { printf ("wiringPi: wiringPiISR pin %d, edgeMode %d\n", pin, edgeMode) ; } - if (isrFunctions [pin]) { + if (isrFunctions[pin] || isrFunctionsV2[pin] ) { printf ("wiringPi: ISR function already active, ignoring \n") ; } - isrFunctions [pin] = function ; - isrMode[pin] = edgeMode; + isrFunctionsV2[pin] = function; + isrFunctions[pin] = functionClassic; + isrEdgeMode[pin] = edgeMode; isrDebouncePeriodUs[pin] = debounce_period_us; if (wiringPiDebug) { @@ -3056,7 +3110,7 @@ int wiringPiISR (int pin, int edgeMode, void (*function)(struct WPIWfiStatus wfi if (wiringPiDebug) { printf("wiringPi: pthread_create before 0x%lX\n", (unsigned long)isrThreads[pin]); } - if (pthread_create (&isrThreads[pin], NULL, interruptHandler, &pin)==0) { + if (pthread_create (&isrThreads[pin], NULL, interruptHandlerV2, &pin)==0) { if (wiringPiDebug) { printf("wiringPi: pthread_create successed, 0x%lX\n", (unsigned long)isrThreads[pin]); } @@ -3084,6 +3138,15 @@ int wiringPiISR (int pin, int edgeMode, void (*function)(struct WPIWfiStatus wfi return 0 ; } +int wiringPiISR (int pin, int mode, void (*function)(void)) +{ + return wiringPiISRInternal(pin, mode, NULL, function, 0); +} + +int wiringPiISR2(int pin, int edgeMode, void (*function)(struct WPIWfiStatus wfiStatus), unsigned long debounce_period_us) +{ + return wiringPiISRInternal(pin, edgeMode, function, NULL, debounce_period_us); +} /* * initialiseEpoch: @@ -3116,12 +3179,12 @@ static void initialiseEpoch (void) ********************************************************************************* */ -void delay (unsigned int howLong) +void delay (unsigned int ms) { struct timespec sleeper, dummy ; - sleeper.tv_sec = (time_t)(howLong / 1000) ; - sleeper.tv_nsec = (long)(howLong % 1000) * 1000000 ; + sleeper.tv_sec = (time_t)(ms / 1000) ; + sleeper.tv_nsec = (long)(ms % 1000) * 1000000 ; nanosleep (&sleeper, &dummy) ; } @@ -3145,29 +3208,29 @@ void delay (unsigned int howLong) ********************************************************************************* */ -void delayMicrosecondsHard (unsigned int howLong) +void delayMicrosecondsHard (unsigned int us) { struct timeval tNow, tLong, tEnd ; gettimeofday (&tNow, NULL) ; - tLong.tv_sec = howLong / 1000000 ; - tLong.tv_usec = howLong % 1000000 ; + tLong.tv_sec = us / 1000000 ; + tLong.tv_usec = us % 1000000 ; timeradd (&tNow, &tLong, &tEnd) ; while (timercmp (&tNow, &tEnd, <)) gettimeofday (&tNow, NULL) ; } -void delayMicroseconds (unsigned int howLong) +void delayMicroseconds (unsigned int us) { struct timespec sleeper ; - unsigned int uSecs = howLong % 1000000 ; - unsigned int wSecs = howLong / 1000000 ; + unsigned int uSecs = us % 1000000 ; + unsigned int wSecs = us / 1000000 ; - /**/ if (howLong == 0) + /**/ if (us == 0) return ; - else if (howLong < 100) - delayMicrosecondsHard (howLong) ; + else if (us < 100) + delayMicrosecondsHard (us) ; else { sleeper.tv_sec = wSecs ; diff --git a/wiringPi/wiringPi.h b/wiringPi/wiringPi.h index be64b16..6542caa 100644 --- a/wiringPi/wiringPi.h +++ b/wiringPi/wiringPi.h @@ -297,19 +297,21 @@ extern void digitalWriteByte (int value) ; extern void digitalWriteByte2 (int value) ; // Interrupts -// (Also Pi hardware specific) - -// status returned from waitForInterrupt V3.16 +// status returned from waitForInterruptV2 V3.16 struct WPIWfiStatus { + int id; int status; // -1: error, 0: timeout, 1: valud values for edge and timeStamp_us - unsigned int gpioPin; // gpio as BCM pin + unsigned int pin; // gpio as BCM pin int edge; // One of INT_EDGE_FALLING or INT_EDGE_RISING long long int timeStamp_us; // time stamp in microseconds, when interrupt happened }; -extern struct WPIWfiStatus waitForInterrupt (int pin, int edgeMode, int mS, unsigned long debounce_period_us) ; // V3.16 phylax -extern int wiringPiISR (int pin, int mode, void (*function)(struct WPIWfiStatus wfiStatus), unsigned long debounce_period_us) ; // v3.16 phylax +extern int waitForInterrupt (int pin, int ms) ; +extern int wiringPiISR (int pin, int mode, void (*function)(void)) ; +extern struct WPIWfiStatus waitForInterrupt2(int pin, int edgeMode, int ms, unsigned long debounce_period_us) ; // V3.16 phylax +extern int wiringPiISR2 (int pin, int mode, void (*function)(struct WPIWfiStatus wfiStatus), unsigned long debounce_period_us) ; // v3.16 phylax extern int wiringPiISRStop (int pin) ; //V3.2 +extern int waitForInterruptClose(int pin) ; //V3.2 legacy use wiringPiISRStop // Threads @@ -323,8 +325,8 @@ extern int piHiPri (const int pri) ; // Extras from arduino land -extern void delay (unsigned int howLong) ; -extern void delayMicroseconds (unsigned int howLong) ; +extern void delay (unsigned int ms) ; +extern void delayMicroseconds (unsigned int us) ; extern unsigned int millis (void) ; extern unsigned int micros (void) ; From b71a2b688e5a6c0212d109e06c3946c80c218222 Mon Sep 17 00:00:00 2001 From: mstroh76 Date: Fri, 2 May 2025 19:50:44 +0200 Subject: [PATCH 30/65] #346 irq status var name ajust --- wiringPi/wiringPi.c | 28 +++++++++++++--------------- wiringPi/wiringPi.h | 15 +++++++-------- 2 files changed, 20 insertions(+), 23 deletions(-) diff --git a/wiringPi/wiringPi.c b/wiringPi/wiringPi.c index ee8fbb7..d9b7c91 100644 --- a/wiringPi/wiringPi.c +++ b/wiringPi/wiringPi.c @@ -2685,7 +2685,7 @@ struct WPIWfiStatus waitForInterrupt2(int pin, int edgeMode, int ms, unsigned lo /* open gpio */ if (wiringPiGpioDeviceGetFd()<0) { - wfiStatus.status = -1; + wfiStatus.statusOK = -1; return wfiStatus; } @@ -2701,7 +2701,7 @@ struct WPIWfiStatus waitForInterrupt2(int pin, int edgeMode, int ms, unsigned lo if (wiringPiDebug) { printf ("waitForInterrupt2: edgeMode INT_EDGE_SETUP - exiting\n") ; } - wfiStatus.status = -1; + wfiStatus.statusOK = -1; return wfiStatus; case INT_EDGE_FALLING: config.flags |= GPIO_V2_LINE_FLAG_EDGE_FALLING; @@ -2734,7 +2734,7 @@ struct WPIWfiStatus waitForInterrupt2(int pin, int edgeMode, int ms, unsigned lo status = ioctl(chipFd, GPIO_V2_GET_LINE_IOCTL, &req); if (status == -1) { ReportDeviceError("GPIO_V2_GET_LINE_IOCTL", pin , strmode, status); - wfiStatus.status = -1; + wfiStatus.statusOK = -1; return wfiStatus; } @@ -2763,24 +2763,23 @@ struct WPIWfiStatus waitForInterrupt2(int pin, int edgeMode, int ms, unsigned lo polls.revents = 0; ret = poll(&polls, 1, ms); - if (ret < 0) { if (wiringPiDebug) { fprintf(stderr, "waitForInterrupt2: ERROR: poll returned=%d\n", ret); } - wfiStatus.status = -1; + wfiStatus.statusOK = -1; } else if (ret == 0) { if (wiringPiDebug) { fprintf(stderr, "waitForInterrupt2: timeout: poll returned zero\n"); } - wfiStatus.status = 0; + wfiStatus.statusOK = 0; // timeout } else { if (wiringPiDebug) { printf ("waitForInterrupt2: IRQ line %d received %d, fd=%d\n", pin, ret, isrFds[pin]); } if (polls.revents & POLLIN) { - /* read event data */ + /* read event data */ readret = read(isrFds [pin], &evdata, sizeof(evdata)); if (readret == sizeof(evdata)) { if (wiringPiDebug) { @@ -2801,16 +2800,15 @@ struct WPIWfiStatus waitForInterrupt2(int pin, int edgeMode, int ms, unsigned lo break; } wfiStatus.timeStamp_us = evdata.timestamp_ns / 1000LL; // nanoseconds u64 to microseconds - wfiStatus.pin = evdata.offset; - wfiStatus.id = evdata.id; - wfiStatus.status = 1; + wfiStatus.pinBCM = evdata.offset; + wfiStatus.statusOK = 1; } else { - wfiStatus.status = -1; + wfiStatus.statusOK = -1; } } else { - wfiStatus.status = -1; + wfiStatus.statusOK = -1; } } @@ -2833,7 +2831,7 @@ int waitForInterrupt (int pin, int ms) { } status = waitForInterrupt2(pin, edgeMode, ms, 0); - return status.id; + return status.statusOK; } /* @@ -3015,8 +3013,8 @@ void *interruptHandlerV2(void *arg) if (isrFunctionsV2[pin]) { if (wiringPiDebug) printf( "interruptHandlerV2: GPIO EVENT at %llu on line %u (%u|%u) \n", evdat[i].timestamp_ns, evdat[i].offset, evdat[i].line_seqno, evdat[i].seqno); - wfiStatus.status = 1; - wfiStatus.pin = pin; + wfiStatus.statusOK = 1; + wfiStatus.pinBCM = pin; switch (evdat[i].id) { case GPIO_V2_LINE_EVENT_RISING_EDGE: wfiStatus.edge = INT_EDGE_RISING; diff --git a/wiringPi/wiringPi.h b/wiringPi/wiringPi.h index 6542caa..1fe25e5 100644 --- a/wiringPi/wiringPi.h +++ b/wiringPi/wiringPi.h @@ -299,17 +299,16 @@ extern void digitalWriteByte2 (int value) ; // Interrupts // status returned from waitForInterruptV2 V3.16 struct WPIWfiStatus { - int id; - int status; // -1: error, 0: timeout, 1: valud values for edge and timeStamp_us - unsigned int pin; // gpio as BCM pin - int edge; // One of INT_EDGE_FALLING or INT_EDGE_RISING - long long int timeStamp_us; // time stamp in microseconds, when interrupt happened + int statusOK; // -1: error (return of 'poll' command), 0: timeout, 1: irq processed, next data values are valid if needed + unsigned int pinBCM; // gpio as BCM pin + int edge; // INT_EDGE_FALLING or INT_EDGE_RISING + long long int timeStamp_us; // time stamp in microseconds }; -extern int waitForInterrupt (int pin, int ms) ; +//extern int waitForInterrupt (int pin, int ms); unknown if still working, disabled for V3.16, please contact developer via github extern int wiringPiISR (int pin, int mode, void (*function)(void)) ; -extern struct WPIWfiStatus waitForInterrupt2(int pin, int edgeMode, int ms, unsigned long debounce_period_us) ; // V3.16 phylax -extern int wiringPiISR2 (int pin, int mode, void (*function)(struct WPIWfiStatus wfiStatus), unsigned long debounce_period_us) ; // v3.16 phylax +extern struct WPIWfiStatus waitForInterrupt2(int pin, int edgeMode, int ms, unsigned long debounce_period_us) ; // V3.16 +extern int wiringPiISR2 (int pin, int mode, void (*function)(struct WPIWfiStatus wfiStatus), unsigned long debounce_period_us) ; // V3.16 extern int wiringPiISRStop (int pin) ; //V3.2 extern int waitForInterruptClose(int pin) ; //V3.2 legacy use wiringPiISRStop From 50908a31ebac4669a469701c66befeeb73883e66 Mon Sep 17 00:00:00 2001 From: mstroh76 Date: Fri, 2 May 2025 19:51:24 +0200 Subject: [PATCH 31/65] #346 unit test --- wiringPi/test/Makefile | 5 +- wiringPi/test/wiringpi_test61_isr2.c | 255 +++++++++++++++++++++++++++ 2 files changed, 259 insertions(+), 1 deletion(-) create mode 100644 wiringPi/test/wiringpi_test61_isr2.c diff --git a/wiringPi/test/Makefile b/wiringPi/test/Makefile index 299dcb4..0b68f96 100644 --- a/wiringPi/test/Makefile +++ b/wiringPi/test/Makefile @@ -3,7 +3,7 @@ CFLAGS = -Wall LDFLAGS = # Need BCM19 <-> BCM26, +PWM: BCM12 <-> BCM13, BCM18 <-> BCM17 connected (1kOhm) -tests = wiringpi_test0_version wiringpi_test1_sysfs wiringpi_test2_sysfs wiringpi_test3_device_wpi wiringpi_test4_device_phys wiringpi_test5_default wiringpi_test6_isr wiringpi_test7_bench wiringpi_test8_pwm wiringpi_test9_pwm +tests = wiringpi_test0_version wiringpi_test1_sysfs wiringpi_test2_sysfs wiringpi_test3_device_wpi wiringpi_test4_device_phys wiringpi_test5_default wiringpi_test6_isr wiringpi_test61_isr2 wiringpi_test7_bench wiringpi_test8_pwm wiringpi_test9_pwm # Need XO hardware xotests = wiringpi_xotest_test1_spi wiringpi_i2c_test1_pcf8574 wiringpi_test8_pwm wiringpi_test9_pwm @@ -34,6 +34,9 @@ wiringpi_test5_default: wiringpi_test6_isr: ${CC} ${CFLAGS} wiringpi_test6_isr.c -o wiringpi_test6_isr -lwiringPi +wiringpi_test61_isr2: + ${CC} ${CFLAGS} wiringpi_test61_isr2.c -o wiringpi_test61_isr2 -lwiringPi + wiringpi_test7_bench: ${CC} ${CFLAGS} wiringpi_test7_bench.c -o wiringpi_test7_bench -lwiringPi diff --git a/wiringPi/test/wiringpi_test61_isr2.c b/wiringPi/test/wiringpi_test61_isr2.c new file mode 100644 index 0000000..59e70e5 --- /dev/null +++ b/wiringPi/test/wiringpi_test61_isr2.c @@ -0,0 +1,255 @@ +// WiringPi test program: 3.16 new ISR2 function with Kernel char device interface / sysfs successor +// Compile: gcc -Wall wiringpi_test1_device.c -o wiringpi_test1_device -lwiringPi + +#include "wpi_test.h" +#include +#include +#include +#include + + +int GPIO = 19; +int GPIOIN = 26; +const int ToggleValue = 4; +float irq_timstamp_duration_ms = 0; + +static volatile int globalCounter; +volatile long long gStartTime, gEndTime; +struct WPIWfiStatus wfiStatusOld; + +static void ISR(void) { + struct timeval now; + + gettimeofday(&now, 0); + if (0==gStartTime) { + gStartTime = now.tv_sec*1000000LL + now.tv_usec; + } else { + gEndTime = now.tv_sec*1000000LL + now.tv_usec; + } + globalCounter++; +} + + +static void ISR2(struct WPIWfiStatus wfiStatus) { + struct timeval now; + char strEdge[3][10] = {"unknown", "falling", "raising"}; + int strEdgeidx = 0; //default + + gettimeofday(&now, 0); + if (0==gStartTime) { + gStartTime = now.tv_sec*1000000LL + now.tv_usec; + } else { + gEndTime = now.tv_sec*1000000LL + now.tv_usec; + } + globalCounter++; + switch(wfiStatus.edge) { + case INT_EDGE_FALLING: strEdgeidx = INT_EDGE_FALLING; break; + case INT_EDGE_RISING: strEdgeidx = INT_EDGE_RISING; break; + } + if (wfiStatusOld.statusOK>0 && wfiStatusOld.pinBCM==wfiStatus.pinBCM) { + irq_timstamp_duration_ms = (wfiStatus.timeStamp_us - wfiStatusOld.timeStamp_us) / 1000.0f; + } else { + irq_timstamp_duration_ms = 0.0f; + } + printf("ISR occured @ %lld us: statusOK=%d, pin=%u, edge=%s (%d), duration=%g ms\n", + wfiStatus.timeStamp_us, wfiStatus.statusOK, wfiStatus.pinBCM, strEdge[strEdgeidx], wfiStatus.edge, irq_timstamp_duration_ms); + wfiStatusOld = wfiStatus; +} + +void digitalWriteBounce(int OUTpin, int value, int bounce) { + digitalWrite(OUTpin, value); + if (bounce>0) { + delay(1); + digitalWrite(OUTpin, !value); + delay(1); + digitalWrite(OUTpin, value); + } +} + +double StartSequence2(int Edge, int OUTpin, int INpin, int bounce) { + int expected; + float timeExpected_ms; + float irq_timstamp_sum = 0.0f; + + gStartTime = 0; + gEndTime = 0; + globalCounter = 0; + printf("Start\n"); + digitalWriteBounce(OUTpin, HIGH, bounce); + delay(10); + delay(190); + digitalWriteBounce(OUTpin, LOW, bounce); + delay(10); + if (INT_EDGE_BOTH == Edge) { + irq_timstamp_sum += irq_timstamp_duration_ms; + } + delay(90); + digitalWriteBounce(OUTpin, HIGH, bounce); + delay(10); + if (INT_EDGE_RISING == Edge || INT_EDGE_BOTH == Edge) { + irq_timstamp_sum += irq_timstamp_duration_ms; + } + delay(190); + digitalWriteBounce(OUTpin, LOW, bounce); + delay(10); + if (INT_EDGE_FALLING == Edge || INT_EDGE_BOTH == Edge) { + irq_timstamp_sum += irq_timstamp_duration_ms; + } + delay(90); + printf("Stop\n"); + int globalCounterCopy = globalCounter; + + if (INT_EDGE_BOTH == Edge) { + expected = 4; + timeExpected_ms = bounce ? 508: 500; + } else { + expected = 2; + timeExpected_ms = bounce ? 304: 300; + } + + if (globalCounter==expected) { + char str[1024]; + float fTime = (gEndTime - gStartTime) / 1000.0; + sprintf(str, "IRQ measured %g msec (~%g expected)", fTime, timeExpected_ms); + CheckSameFloat(str, fTime, timeExpected_ms, timeExpected_ms*0.01); + sprintf(str, "IRQ timestamp %g msec (~%g expected)", irq_timstamp_sum, timeExpected_ms); + CheckSameFloat(str, irq_timstamp_sum, timeExpected_ms, timeExpected_ms*0.01); + // new data struct + CheckSame("GPIO IRQ pin", wfiStatusOld.pinBCM, INpin); + if (INT_EDGE_FALLING==Edge || INT_EDGE_RISING==Edge) { + CheckSame("GPIO IRQ edge", wfiStatusOld.edge, Edge); + } + CheckSame("GPIO IRQ status", wfiStatusOld.statusOK, 1); + return fTime; + } else { + printf("IRQ not worked got %d iterations (%d exprected)\n\n", globalCounterCopy, expected); + return 0; + } +} + + +double DurationTime(int Enge, int OUTpin, int IRQpin, int new) { + struct timeval now; + double fTime = 0.0; + + gStartTime = 0; + gEndTime = 0; + globalCounter = 0; + printf("Start\n"); + + if (INT_EDGE_RISING == Enge) { + digitalWrite(OUTpin, LOW); + if (new) { + wiringPiISR2(IRQpin, INT_EDGE_RISING, &ISR2, 0); + } else { + wiringPiISR(IRQpin, INT_EDGE_RISING, &ISR); + } + sleep(1); + gettimeofday(&now, 0); + gStartTime = now.tv_sec*1000000LL + now.tv_usec; + digitalWrite(OUTpin, HIGH); + delay(20); + digitalWrite(OUTpin, LOW); + } else if (INT_EDGE_FALLING == Enge) { + digitalWrite(OUTpin, HIGH); + if (new) { + wiringPiISR2(IRQpin, INT_EDGE_FALLING, &ISR2, 0); + } else { + wiringPiISR(IRQpin, INT_EDGE_FALLING, &ISR); + } + sleep(1); + gettimeofday(&now, 0); + gStartTime = now.tv_sec*1000000LL + now.tv_usec; + digitalWrite(OUTpin, LOW); + } + + sleep(1); + fTime = (gEndTime - gStartTime); + printf("IRQ detect time %g usec", fTime); + if (fTime<2000 && fTime>0) { + printf(" -> %spassed%s\n", COLORGRN, COLORDEF); + } else { + printf(" -> %sfailed%s\n", COLORRED, COLORDEF); + } + wiringPiISRStop(IRQpin); + + return fTime; +} + + +int main (void) { + + int major=0, minor=0; + + wiringPiVersion(&major, &minor); + + printf("WiringPi GPIO test program 6b (using GPIO%d (output) and GPIO%d (input))\n", GPIO, GPIOIN); + printf("ISR and ISR2 test (WiringPi %d.%d)\n", major, minor); + + wiringPiSetupGpio() ; + if (!piBoard40Pin()) { + GPIO = 23; + GPIOIN = 24; + } + int IRQpin = GPIOIN; + int OUTpin = GPIO; + + wiringPiISR2(13, INT_EDGE_RISING, &ISR2, 0); // next pin + + memset(&wfiStatusOld, 0, sizeof(wfiStatusOld)); + + pinMode(IRQpin, INPUT); + pinMode(OUTpin, OUTPUT); + digitalWrite (OUTpin, LOW) ; + + /// -------------------- + for (int bounce=0; bounce<=1; bounce++) { + unsigned long bouncetime = 0; + if (0==bounce) { + printf("! --- default test (no bounce) --- !\n"); + } else { + bouncetime = 2000; //2 ms + printf("! --- test with bounce on input --- !\n"); + } + + printf("\nTesting IRQ @ GPIO%d with trigger @ GPIO%d rising\n", IRQpin, OUTpin); + wiringPiISR2(IRQpin, INT_EDGE_RISING, &ISR2, bouncetime); + sleep(1); + StartSequence2(INT_EDGE_RISING, OUTpin, IRQpin, bounce); + printf("Stopp IRQ\n"); + wiringPiISRStop(IRQpin); + + printf("\nTesting IRQ @ GPIO%d with trigger @ GPIO%d falling\n", IRQpin, OUTpin); + wiringPiISR2(IRQpin, INT_EDGE_FALLING, &ISR2, bouncetime); + sleep(1); + StartSequence2(INT_EDGE_FALLING, OUTpin, IRQpin, bounce); + printf("Stopp IRQ\n"); + wiringPiISRStop(IRQpin); + + printf("\nTesting IRQ @ GPIO%d with trigger @ GPIO%d both\n", IRQpin, OUTpin); + wiringPiISR2(IRQpin, INT_EDGE_BOTH, &ISR2, bouncetime); + sleep(1); + StartSequence2(INT_EDGE_BOTH, OUTpin, IRQpin, bounce); + printf("Stopp IRQ\n"); + wiringPiISRStop(IRQpin); + } + + for (int count=0; count<2; count++) { + printf("\nclassic function:\n"); + printf("=================\n"); + printf("Measuring duration IRQ @ GPIO%d with trigger @ GPIO%d rising\n", IRQpin, OUTpin); + DurationTime(INT_EDGE_RISING, OUTpin, IRQpin, 0); + printf("Measuring duration IRQ @ GPIO%d with trigger @ GPIO%d falling\n", IRQpin, OUTpin); + DurationTime(INT_EDGE_FALLING, OUTpin, IRQpin, 0); + + printf("\nnew function:\n"); + printf("===============\n"); + printf("Measuring duration IRQ @ GPIO%d with trigger @ GPIO%d rising\n", IRQpin, OUTpin); + DurationTime(INT_EDGE_RISING, OUTpin, IRQpin, 1); + printf("Measuring duration IRQ @ GPIO%d with trigger @ GPIO%d falling\n", IRQpin, OUTpin); + DurationTime(INT_EDGE_FALLING, OUTpin, IRQpin, 1); + } + pinMode(OUTpin, INPUT); + + return UnitTestState(); +} From 323f4d09f3df28d058cd9a3bb3d829d89089b039 Mon Sep 17 00:00:00 2001 From: mstroh76 Date: Sat, 3 May 2025 20:26:31 +0200 Subject: [PATCH 32/65] #346 ajust unit test for Pi1 --- wiringPi/test/wiringpi_test61_isr2.c | 62 ++++++++++++++++++---------- wiringPi/test/wiringpi_test7_bench.c | 2 +- 2 files changed, 41 insertions(+), 23 deletions(-) diff --git a/wiringPi/test/wiringpi_test61_isr2.c b/wiringPi/test/wiringpi_test61_isr2.c index 59e70e5..5f3bb3f 100644 --- a/wiringPi/test/wiringpi_test61_isr2.c +++ b/wiringPi/test/wiringpi_test61_isr2.c @@ -12,6 +12,7 @@ int GPIO = 19; int GPIOIN = 26; const int ToggleValue = 4; float irq_timstamp_duration_ms = 0; +float accuracy = 0.01; static volatile int globalCounter; volatile long long gStartTime, gEndTime; @@ -56,6 +57,7 @@ static void ISR2(struct WPIWfiStatus wfiStatus) { wfiStatusOld = wfiStatus; } + void digitalWriteBounce(int OUTpin, int value, int bounce) { digitalWrite(OUTpin, value); if (bounce>0) { @@ -66,6 +68,16 @@ void digitalWriteBounce(int OUTpin, int value, int bounce) { } } + +void DelayAndSumDuration(int ms, float* irq_timstamp_sum, const int doSum) { + delay(20); + if (doSum) { + *irq_timstamp_sum += irq_timstamp_duration_ms; + } + delay(ms-20); +} + + double StartSequence2(int Edge, int OUTpin, int INpin, int bounce) { int expected; float timeExpected_ms; @@ -76,26 +88,17 @@ double StartSequence2(int Edge, int OUTpin, int INpin, int bounce) { globalCounter = 0; printf("Start\n"); digitalWriteBounce(OUTpin, HIGH, bounce); - delay(10); - delay(190); + delay(200); + digitalWriteBounce(OUTpin, LOW, bounce); - delay(10); - if (INT_EDGE_BOTH == Edge) { - irq_timstamp_sum += irq_timstamp_duration_ms; - } - delay(90); + DelayAndSumDuration(100, &irq_timstamp_sum, INT_EDGE_BOTH == Edge); + digitalWriteBounce(OUTpin, HIGH, bounce); - delay(10); - if (INT_EDGE_RISING == Edge || INT_EDGE_BOTH == Edge) { - irq_timstamp_sum += irq_timstamp_duration_ms; - } - delay(190); + DelayAndSumDuration(200, &irq_timstamp_sum, INT_EDGE_RISING == Edge || INT_EDGE_BOTH == Edge); + digitalWriteBounce(OUTpin, LOW, bounce); - delay(10); - if (INT_EDGE_FALLING == Edge || INT_EDGE_BOTH == Edge) { - irq_timstamp_sum += irq_timstamp_duration_ms; - } - delay(90); + DelayAndSumDuration(100, &irq_timstamp_sum, INT_EDGE_FALLING == Edge || INT_EDGE_BOTH == Edge); + printf("Stop\n"); int globalCounterCopy = globalCounter; @@ -111,9 +114,9 @@ double StartSequence2(int Edge, int OUTpin, int INpin, int bounce) { char str[1024]; float fTime = (gEndTime - gStartTime) / 1000.0; sprintf(str, "IRQ measured %g msec (~%g expected)", fTime, timeExpected_ms); - CheckSameFloat(str, fTime, timeExpected_ms, timeExpected_ms*0.01); + CheckSameFloat(str, fTime, timeExpected_ms, timeExpected_ms*accuracy); sprintf(str, "IRQ timestamp %g msec (~%g expected)", irq_timstamp_sum, timeExpected_ms); - CheckSameFloat(str, irq_timstamp_sum, timeExpected_ms, timeExpected_ms*0.01); + CheckSameFloat(str, irq_timstamp_sum, timeExpected_ms, timeExpected_ms*accuracy); // new data struct CheckSame("GPIO IRQ pin", wfiStatusOld.pinBCM, INpin); if (INT_EDGE_FALLING==Edge || INT_EDGE_RISING==Edge) { @@ -186,7 +189,23 @@ int main (void) { printf("WiringPi GPIO test program 6b (using GPIO%d (output) and GPIO%d (input))\n", GPIO, GPIOIN); printf("ISR and ISR2 test (WiringPi %d.%d)\n", major, minor); - wiringPiSetupGpio() ; + wiringPiSetupGpio(); + + int RaspberryPiModel, rev, mem, maker, overVolted; + piBoardId(&RaspberryPiModel, &rev, &mem, &maker, &overVolted); + CheckNotSame("Model: ", RaspberryPiModel, -1); + switch(RaspberryPiModel) { + case PI_MODEL_A: + case PI_MODEL_B: //ARM=800MHz + case PI_MODEL_BP: + case PI_MODEL_AP: + case PI_MODEL_CM: + accuracy = 0.02; + break; + default: + accuracy = 0.01; + break; + } if (!piBoard40Pin()) { GPIO = 23; GPIOIN = 24; @@ -194,7 +213,7 @@ int main (void) { int IRQpin = GPIOIN; int OUTpin = GPIO; - wiringPiISR2(13, INT_EDGE_RISING, &ISR2, 0); // next pin + //wiringPiISR2(13, INT_EDGE_RISING, &ISR2, 0); // next pin memset(&wfiStatusOld, 0, sizeof(wfiStatusOld)); @@ -202,7 +221,6 @@ int main (void) { pinMode(OUTpin, OUTPUT); digitalWrite (OUTpin, LOW) ; - /// -------------------- for (int bounce=0; bounce<=1; bounce++) { unsigned long bouncetime = 0; if (0==bounce) { diff --git a/wiringPi/test/wiringpi_test7_bench.c b/wiringPi/test/wiringpi_test7_bench.c index f3eb6e2..316c07e 100644 --- a/wiringPi/test/wiringpi_test7_bench.c +++ b/wiringPi/test/wiringpi_test7_bench.c @@ -66,7 +66,7 @@ int main (void) { case PI_MODEL_ZERO_W: //ARM=1000MHz fExpectTimedigitalWrite = 0.104; //us; fExpectTimedigitalRead = 0.135; //us - fExpectTimepinMode = 0.250; //us + fExpectTimepinMode = 0.280; //us break; case PI_MODEL_2: ToggleValue /= 4; From 31bf218a7c17ed663eedb5c9247e20d826184bf1 Mon Sep 17 00:00:00 2001 From: mstroh76 Date: Sun, 4 May 2025 12:20:48 +0200 Subject: [PATCH 33/65] #346 unit test irq dection time with debounce --- wiringPi/test/wiringpi_test61_isr2.c | 83 +++++++++++----------------- wiringPi/test/wpi_test.h | 20 +++++++ 2 files changed, 53 insertions(+), 50 deletions(-) diff --git a/wiringPi/test/wiringpi_test61_isr2.c b/wiringPi/test/wiringpi_test61_isr2.c index 5f3bb3f..a2be628 100644 --- a/wiringPi/test/wiringpi_test61_isr2.c +++ b/wiringPi/test/wiringpi_test61_isr2.c @@ -131,51 +131,44 @@ double StartSequence2(int Edge, int OUTpin, int INpin, int bounce) { } -double DurationTime(int Enge, int OUTpin, int IRQpin, int new) { +double DurationTime(int Enge, int OUTpin, int IRQpin, int bounce) { struct timeval now; double fTime = 0.0; - + const char* strOp = INT_EDGE_RISING == Enge ? "rising" : "fallling"; gStartTime = 0; gEndTime = 0; globalCounter = 0; - printf("Start\n"); + //printf("Start\n"); - if (INT_EDGE_RISING == Enge) { - digitalWrite(OUTpin, LOW); - if (new) { - wiringPiISR2(IRQpin, INT_EDGE_RISING, &ISR2, 0); - } else { - wiringPiISR(IRQpin, INT_EDGE_RISING, &ISR); - } - sleep(1); - gettimeofday(&now, 0); - gStartTime = now.tv_sec*1000000LL + now.tv_usec; - digitalWrite(OUTpin, HIGH); - delay(20); - digitalWrite(OUTpin, LOW); - } else if (INT_EDGE_FALLING == Enge) { - digitalWrite(OUTpin, HIGH); - if (new) { - wiringPiISR2(IRQpin, INT_EDGE_FALLING, &ISR2, 0); - } else { - wiringPiISR(IRQpin, INT_EDGE_FALLING, &ISR); - } - sleep(1); - gettimeofday(&now, 0); - gStartTime = now.tv_sec*1000000LL + now.tv_usec; - digitalWrite(OUTpin, LOW); - } - - sleep(1); - fTime = (gEndTime - gStartTime); - printf("IRQ detect time %g usec", fTime); - if (fTime<2000 && fTime>0) { - printf(" -> %spassed%s\n", COLORGRN, COLORDEF); + digitalWrite(OUTpin, INT_EDGE_RISING == Enge ? LOW : HIGH); + if (bounce>=0) { + printf("\nnew function, bounce time %d ms, %s :\n", bounce, strOp); + wiringPiISR2(IRQpin, Enge, &ISR2, bounce*1000); } else { - printf(" -> %sfailed%s\n", COLORRED, COLORDEF); + printf("\nclassic function, %s :\n", strOp); + wiringPiISR(IRQpin, Enge, &ISR); + } + sleep(1); + gettimeofday(&now, 0); + gStartTime = now.tv_sec*1000000LL + now.tv_usec; + digitalWrite(OUTpin, INT_EDGE_RISING == Enge ? HIGH : LOW); + delay(20); + digitalWrite(OUTpin, LOW); + delay(20); + fTime = (gEndTime - gStartTime); + if (bounce<=0) { + printf("IRQ detection time %g usec", fTime); + } else { + printf("IRQ detection time %.1f msec", fTime/1000.0); + } + if (bounce>=0) { + // bounce time + 7ms (addtional bounce time) + 150 us (basic time) + CheckBetween("IRQ detection time with bounce [us]", fTime, 0, bounce*1000+ (bounce>0 ? 7000 : 0)+(15000*accuracy)); + } else { + CheckBetween("IRQ detection time [us]", fTime, 0, 15000*accuracy); } wiringPiISRStop(IRQpin); - + //printf("Stop\n"); return fTime; } @@ -252,20 +245,10 @@ int main (void) { wiringPiISRStop(IRQpin); } - for (int count=0; count<2; count++) { - printf("\nclassic function:\n"); - printf("=================\n"); - printf("Measuring duration IRQ @ GPIO%d with trigger @ GPIO%d rising\n", IRQpin, OUTpin); - DurationTime(INT_EDGE_RISING, OUTpin, IRQpin, 0); - printf("Measuring duration IRQ @ GPIO%d with trigger @ GPIO%d falling\n", IRQpin, OUTpin); - DurationTime(INT_EDGE_FALLING, OUTpin, IRQpin, 0); - - printf("\nnew function:\n"); - printf("===============\n"); - printf("Measuring duration IRQ @ GPIO%d with trigger @ GPIO%d rising\n", IRQpin, OUTpin); - DurationTime(INT_EDGE_RISING, OUTpin, IRQpin, 1); - printf("Measuring duration IRQ @ GPIO%d with trigger @ GPIO%d falling\n", IRQpin, OUTpin); - DurationTime(INT_EDGE_FALLING, OUTpin, IRQpin, 1); + printf("Measuring duration IRQ @ GPIO%d with trigger @ GPIO%d rising and falling\n", IRQpin, OUTpin); + for (int bounce=-1; bounce<=5; bounce++) { + DurationTime(INT_EDGE_RISING, OUTpin, IRQpin, bounce); + DurationTime(INT_EDGE_FALLING, OUTpin, IRQpin, bounce); } pinMode(OUTpin, INPUT); diff --git a/wiringPi/test/wpi_test.h b/wiringPi/test/wpi_test.h index f2eb81a..1a76480 100644 --- a/wiringPi/test/wpi_test.h +++ b/wiringPi/test/wpi_test.h @@ -94,6 +94,15 @@ void CheckNotSame(const char* msg, int value, int expect) { } } +void CheckBetween(const char* msg, int value, int min, int max) { + if (value>=min && value<=max) { + printf("%39s (% 3d< % 3d <% 3d) -> %spassed%s\n", msg, min, value, max, COLORGRN, COLORDEF); + } else { + printf("%39s (% 3d< % 3d <% 3d) -> %sfailed%s\n", msg, min, value, max, COLORRED, COLORDEF); + globalError=1; + } +} + void CheckSameFloat(const char* msg, float value, float expect, float epsilon) { if (fabs(value-expect)=min && value<=max) { + printf("%39s (%g< %g <%g) -> %spassed%s\n", msg, min, value, max, COLORGRN, COLORDEF); + } else { + printf("%39s (%g< %g <%g) -> %sfailed%s\n", msg, min, value, max, COLORRED, COLORDEF); + globalError=1; + } +} + void CheckSameDouble(const char* msg, double value, double expect, double epsilon) { if (fabs(value-expect) %spassed%s \n", msg, value, expect, COLORGRN, COLORDEF); From 08033bc787bea11fa922b717415161b405318e7c Mon Sep 17 00:00:00 2001 From: mstroh76 Date: Sun, 4 May 2025 13:42:35 +0200 Subject: [PATCH 34/65] #346 unit test adjust --- wiringPi/test/wiringpi_test61_isr2.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/wiringPi/test/wiringpi_test61_isr2.c b/wiringPi/test/wiringpi_test61_isr2.c index a2be628..971ed95 100644 --- a/wiringPi/test/wiringpi_test61_isr2.c +++ b/wiringPi/test/wiringpi_test61_isr2.c @@ -12,7 +12,8 @@ int GPIO = 19; int GPIOIN = 26; const int ToggleValue = 4; float irq_timstamp_duration_ms = 0; -float accuracy = 0.01; +float accuracy = 0.012; +float bounce_acc = 1.0; static volatile int globalCounter; volatile long long gStartTime, gEndTime; @@ -162,10 +163,10 @@ double DurationTime(int Enge, int OUTpin, int IRQpin, int bounce) { printf("IRQ detection time %.1f msec", fTime/1000.0); } if (bounce>=0) { - // bounce time + 7ms (addtional bounce time) + 150 us (basic time) - CheckBetween("IRQ detection time with bounce [us]", fTime, 0, bounce*1000+ (bounce>0 ? 7000 : 0)+(15000*accuracy)); + // bounce time + 7ms (addtional bounce time) + 100 us (basic time) + CheckBetween("IRQ detection time with bounce [us]", fTime, 0, bounce*1000+ (bounce>0 ? 7000*bounce_acc : 0)+(100*bounce_acc)); } else { - CheckBetween("IRQ detection time [us]", fTime, 0, 15000*accuracy); + CheckBetween("IRQ detection time [us]", fTime, 0, 100*bounce_acc); } wiringPiISRStop(IRQpin); //printf("Stop\n"); @@ -194,9 +195,11 @@ int main (void) { case PI_MODEL_AP: case PI_MODEL_CM: accuracy = 0.02; + bounce_acc = 2.7; break; default: - accuracy = 0.01; + accuracy = 0.012; + bounce_acc = 1.0; break; } if (!piBoard40Pin()) { From d5f0ea06f47b4a79bc4cf321b53912025bbdad8d Mon Sep 17 00:00:00 2001 From: mstroh76 Date: Sun, 4 May 2025 19:41:14 +0200 Subject: [PATCH 35/65] #337 ISr user datat and unit test --- wiringPi/test/wiringpi_test61_isr2.c | 35 +++++++++++++++++----------- wiringPi/wiringPi.c | 15 +++++++----- wiringPi/wiringPi.h | 2 +- 3 files changed, 32 insertions(+), 20 deletions(-) diff --git a/wiringPi/test/wiringpi_test61_isr2.c b/wiringPi/test/wiringpi_test61_isr2.c index 971ed95..9c37cc0 100644 --- a/wiringPi/test/wiringpi_test61_isr2.c +++ b/wiringPi/test/wiringpi_test61_isr2.c @@ -32,10 +32,12 @@ static void ISR(void) { } -static void ISR2(struct WPIWfiStatus wfiStatus) { + +static void ISR2(struct WPIWfiStatus wfiStatus, void* userdata) { struct timeval now; char strEdge[3][10] = {"unknown", "falling", "raising"}; int strEdgeidx = 0; //default + int* localCounter = (int*) userdata; gettimeofday(&now, 0); if (0==gStartTime) { @@ -44,6 +46,9 @@ static void ISR2(struct WPIWfiStatus wfiStatus) { gEndTime = now.tv_sec*1000000LL + now.tv_usec; } globalCounter++; + if (localCounter) { + (*localCounter)++; + } switch(wfiStatus.edge) { case INT_EDGE_FALLING: strEdgeidx = INT_EDGE_FALLING; break; case INT_EDGE_RISING: strEdgeidx = INT_EDGE_RISING; break; @@ -53,8 +58,8 @@ static void ISR2(struct WPIWfiStatus wfiStatus) { } else { irq_timstamp_duration_ms = 0.0f; } - printf("ISR occured @ %lld us: statusOK=%d, pin=%u, edge=%s (%d), duration=%g ms\n", - wfiStatus.timeStamp_us, wfiStatus.statusOK, wfiStatus.pinBCM, strEdge[strEdgeidx], wfiStatus.edge, irq_timstamp_duration_ms); + printf("ISR occured @ %lld us: statusOK=%d, pin=%u, edge=%s (%d), duration=%g ms, userdata=%p\n", + wfiStatus.timeStamp_us, wfiStatus.statusOK, wfiStatus.pinBCM, strEdge[strEdgeidx], wfiStatus.edge, irq_timstamp_duration_ms, userdata); wfiStatusOld = wfiStatus; } @@ -79,7 +84,7 @@ void DelayAndSumDuration(int ms, float* irq_timstamp_sum, const int doSum) { } -double StartSequence2(int Edge, int OUTpin, int INpin, int bounce) { +double StartSequence2(int Edge, int OUTpin, int INpin, int bounce, int* localCounter) { int expected; float timeExpected_ms; float irq_timstamp_sum = 0.0f; @@ -87,6 +92,7 @@ double StartSequence2(int Edge, int OUTpin, int INpin, int bounce) { gStartTime = 0; gEndTime = 0; globalCounter = 0; + *localCounter = 0; printf("Start\n"); digitalWriteBounce(OUTpin, HIGH, bounce); delay(200); @@ -101,7 +107,7 @@ double StartSequence2(int Edge, int OUTpin, int INpin, int bounce) { DelayAndSumDuration(100, &irq_timstamp_sum, INT_EDGE_FALLING == Edge || INT_EDGE_BOTH == Edge); printf("Stop\n"); - int globalCounterCopy = globalCounter; + int globalCounterCopy = globalCounter; if (INT_EDGE_BOTH == Edge) { expected = 4; @@ -111,6 +117,9 @@ double StartSequence2(int Edge, int OUTpin, int INpin, int bounce) { timeExpected_ms = bounce ? 304: 300; } + CheckSame("Global counted IRQ", globalCounter, expected); + CheckSame("Userdata pointer / Local counted IRQ ", *localCounter, expected); + if (globalCounter==expected) { char str[1024]; float fTime = (gEndTime - gStartTime) / 1000.0; @@ -144,7 +153,7 @@ double DurationTime(int Enge, int OUTpin, int IRQpin, int bounce) { digitalWrite(OUTpin, INT_EDGE_RISING == Enge ? LOW : HIGH); if (bounce>=0) { printf("\nnew function, bounce time %d ms, %s :\n", bounce, strOp); - wiringPiISR2(IRQpin, Enge, &ISR2, bounce*1000); + wiringPiISR2(IRQpin, Enge, &ISR2, bounce*1000, NULL); } else { printf("\nclassic function, %s :\n", strOp); wiringPiISR(IRQpin, Enge, &ISR); @@ -210,7 +219,7 @@ int main (void) { int OUTpin = GPIO; //wiringPiISR2(13, INT_EDGE_RISING, &ISR2, 0); // next pin - + int localCounter; memset(&wfiStatusOld, 0, sizeof(wfiStatusOld)); pinMode(IRQpin, INPUT); @@ -227,23 +236,23 @@ int main (void) { } printf("\nTesting IRQ @ GPIO%d with trigger @ GPIO%d rising\n", IRQpin, OUTpin); - wiringPiISR2(IRQpin, INT_EDGE_RISING, &ISR2, bouncetime); + wiringPiISR2(IRQpin, INT_EDGE_RISING, &ISR2, bouncetime, &localCounter); sleep(1); - StartSequence2(INT_EDGE_RISING, OUTpin, IRQpin, bounce); + StartSequence2(INT_EDGE_RISING, OUTpin, IRQpin, bounce, &localCounter); printf("Stopp IRQ\n"); wiringPiISRStop(IRQpin); printf("\nTesting IRQ @ GPIO%d with trigger @ GPIO%d falling\n", IRQpin, OUTpin); - wiringPiISR2(IRQpin, INT_EDGE_FALLING, &ISR2, bouncetime); + wiringPiISR2(IRQpin, INT_EDGE_FALLING, &ISR2, bouncetime, &localCounter); sleep(1); - StartSequence2(INT_EDGE_FALLING, OUTpin, IRQpin, bounce); + StartSequence2(INT_EDGE_FALLING, OUTpin, IRQpin, bounce, &localCounter); printf("Stopp IRQ\n"); wiringPiISRStop(IRQpin); printf("\nTesting IRQ @ GPIO%d with trigger @ GPIO%d both\n", IRQpin, OUTpin); - wiringPiISR2(IRQpin, INT_EDGE_BOTH, &ISR2, bouncetime); + wiringPiISR2(IRQpin, INT_EDGE_BOTH, &ISR2, bouncetime, &localCounter); sleep(1); - StartSequence2(INT_EDGE_BOTH, OUTpin, IRQpin, bounce); + StartSequence2(INT_EDGE_BOTH, OUTpin, IRQpin, bounce, &localCounter); printf("Stopp IRQ\n"); wiringPiISRStop(IRQpin); } diff --git a/wiringPi/wiringPi.c b/wiringPi/wiringPi.c index d9b7c91..b5bfbed 100644 --- a/wiringPi/wiringPi.c +++ b/wiringPi/wiringPi.c @@ -491,7 +491,8 @@ static int isrFds [64] = // ISR Data static int chipFd = -1; -static void (*isrFunctionsV2[64])(struct WPIWfiStatus) ; +static void* isrUserdata[64]; +static void (*isrFunctionsV2[64])(struct WPIWfiStatus, void* userdata) ; static void (*isrFunctions [64])(void) ; static pthread_t isrThreads[64]; static int isrEdgeMode[64]; // irq on rising/falling edge @@ -2871,6 +2872,7 @@ int wiringPiISRStop (int pin) { isrFds [pin] = -1; isrFunctions[pin] = NULL; isrFunctionsV2[pin] = NULL; + isrUserdata[pin] = NULL;; isrDebouncePeriodUs[pin] = 0; /* -not closing so far - other isr may be using it - only close if no other is using - will code later @@ -3036,7 +3038,7 @@ void *interruptHandlerV2(void *arg) if (wiringPiDebug) { printf( "interruptHandlerV2: call isr function\n"); } - isrFunctionsV2[pin](wfiStatus); + isrFunctionsV2[pin](wfiStatus, isrUserdata[pin]); if (wiringPiDebug) { printf( "interruptHandlerV2: return from isr function\n"); } @@ -3073,7 +3075,7 @@ void *interruptHandlerV2(void *arg) ********************************************************************************* */ -int wiringPiISRInternal(int pin, int edgeMode, void (*function)(struct WPIWfiStatus wfiStatus), void (*functionClassic)(void), unsigned long debounce_period_us) +int wiringPiISRInternal(int pin, int edgeMode, void (*function)(struct WPIWfiStatus wfiStatus, void* userdata), void (*functionClassic)(void), unsigned long debounce_period_us, void* userdata) { const int maxpin = GetMaxPin(); @@ -3096,6 +3098,7 @@ int wiringPiISRInternal(int pin, int edgeMode, void (*function)(struct WPIWfiSta } isrFunctionsV2[pin] = function; + isrUserdata[pin] = userdata; isrFunctions[pin] = functionClassic; isrEdgeMode[pin] = edgeMode; isrDebouncePeriodUs[pin] = debounce_period_us; @@ -3138,12 +3141,12 @@ int wiringPiISRInternal(int pin, int edgeMode, void (*function)(struct WPIWfiSta int wiringPiISR (int pin, int mode, void (*function)(void)) { - return wiringPiISRInternal(pin, mode, NULL, function, 0); + return wiringPiISRInternal(pin, mode, NULL, function, 0, NULL); } -int wiringPiISR2(int pin, int edgeMode, void (*function)(struct WPIWfiStatus wfiStatus), unsigned long debounce_period_us) +int wiringPiISR2(int pin, int edgeMode, void (*function)(struct WPIWfiStatus wfiStatus, void* userdata), unsigned long debounce_period_us, void* userdata) { - return wiringPiISRInternal(pin, edgeMode, function, NULL, debounce_period_us); + return wiringPiISRInternal(pin, edgeMode, function, NULL, debounce_period_us, userdata); } /* diff --git a/wiringPi/wiringPi.h b/wiringPi/wiringPi.h index 1fe25e5..9ae92d0 100644 --- a/wiringPi/wiringPi.h +++ b/wiringPi/wiringPi.h @@ -308,7 +308,7 @@ struct WPIWfiStatus { //extern int waitForInterrupt (int pin, int ms); unknown if still working, disabled for V3.16, please contact developer via github extern int wiringPiISR (int pin, int mode, void (*function)(void)) ; extern struct WPIWfiStatus waitForInterrupt2(int pin, int edgeMode, int ms, unsigned long debounce_period_us) ; // V3.16 -extern int wiringPiISR2 (int pin, int mode, void (*function)(struct WPIWfiStatus wfiStatus), unsigned long debounce_period_us) ; // V3.16 +extern int wiringPiISR2 (int pin, int edgeMode, void (*function)(struct WPIWfiStatus wfiStatus, void* userdata), unsigned long debounce_period_us, void* userdata) ; // V3.16 extern int wiringPiISRStop (int pin) ; //V3.2 extern int waitForInterruptClose(int pin) ; //V3.2 legacy use wiringPiISRStop From 799b484af0b2c76fbb600f54d720a4c736945f28 Mon Sep 17 00:00:00 2001 From: mstroh76 Date: Sat, 10 May 2025 11:55:19 +0200 Subject: [PATCH 36/65] #346 gpio wfi unit test --- gpio/test/gpio_test7_wfi.sh | 96 +++++++++++++++++++++++++++++++++++++ 1 file changed, 96 insertions(+) create mode 100755 gpio/test/gpio_test7_wfi.sh diff --git a/gpio/test/gpio_test7_wfi.sh b/gpio/test/gpio_test7_wfi.sh new file mode 100755 index 0000000..7f4ef39 --- /dev/null +++ b/gpio/test/gpio_test7_wfi.sh @@ -0,0 +1,96 @@ +#!/bin/bash + +RED='\033[0;31m' +GREEN='\033[0;32m' +NC='\033[0m' # Reset color + +UNITTEST_OK=true +TIMEOUT=8 +iteration=0 + +wait_with_timeout() { + local pid=$1 + local timeout=$2 + iteration=0 + + while kill -0 "$pid" 2>/dev/null; do + if [ $iteration -ge $timeout ]; then + kill -9 "$pid" 2>/dev/null + echo -e "${RED}ERROR: timeout ${timeout}s reached ${NC}" + return -1 + fi + gpio -g write 19 1 + sleep 1 + echo -n . + gpio -g write 19 0 + iteration=$((iteration + 1)) + done + + wait "$pid" + return $? +} + +echo +echo Unit test gpio GPIO19 and GPIO26 - functions: mode, write, wfi +echo ------------------------------------------------------------------ +echo + +#prepare trigger out +gpio -g mode 19 out +gpio -g write 19 0 + +#wfi test +gpio -g wfi 26 rising & +GPIO_PID=$! +wait_with_timeout "$GPIO_PID" "$TIMEOUT" +EXIT_CODE=$? +echo +if [ $EXIT_CODE -eq 0 ]; then + echo -e "${GREEN}wfi passt (exit code 0)${NC}" +else + echo -e "${RED}wfi failed (exit code $EXIT_CODE)${NC}" + UNITTEST_OK=false +fi + +#wfi iteration test +gpio -g wfi 26 rising 4 & +GPIO_PID=$! +wait_with_timeout "$GPIO_PID" "$TIMEOUT" +EXIT_CODE=$? +echo +if [ $EXIT_CODE -eq 0 ]; then + if [ "$iteration" -eq 5 ]; then + echo -e "${GREEN}wfi iteration passt (exit code 0)${NC}" + else + echo -e "${RED}wfi failed, iteration $iteration wrong${NC}" + UNITTEST_OK=false + fi +else + echo -e "${RED}wfi failed (exit code $EXIT_CODE)${NC}" + UNITTEST_OK=false +fi + +gpio -g write 19 0 +gpio -g mode 19 in + +### #wfi timeout test +gpio -g wfi 26 rising 2 4 & +GPIO_PID=$! +wait_with_timeout "$GPIO_PID" "$TIMEOUT" +EXIT_CODE=$? +echo +if [ $EXIT_CODE -eq 0 ]; then + echo -e "${GREEN}wfi timeout passed (exit code 0)${NC}" +else + echo -e "${RED}wfi timeout failed (code $EXIT_CODE)${NC}" + UNITTEST_OK=false +fi + + +if [ ${UNITTEST_OK} = true ]; then + echo -e "\n\n${GREEN}Unit test result OK.${NC}" + exit 0 +else + echo -e "\n\n${RED}Unit test result failed.${NC}" + exit 1 +fi \ No newline at end of file From b1b896582ec696f235925c62d10ce7b726a61cfa Mon Sep 17 00:00:00 2001 From: mstroh76 Date: Sun, 11 May 2025 20:21:39 +0200 Subject: [PATCH 37/65] #346 gpio wfidb command and unit test improvment --- gpio/gpio.c | 135 ++++++++++++++++++++++++++---------- gpio/test/gpio_test7_wfi.sh | 95 +++++++++++++++---------- 2 files changed, 158 insertions(+), 72 deletions(-) diff --git a/gpio/gpio.c b/gpio/gpio.c index 9ffb1b7..9fa5bf6 100644 --- a/gpio/gpio.c +++ b/gpio/gpio.c @@ -161,7 +161,7 @@ void LOAD_DEPRECATED(const char *progName) { ********************************************************************************* */ -static volatile int iterations ; +static volatile int globalIterations ; static volatile int globalCounter ; void printgpioflush(const char* text) { @@ -179,7 +179,7 @@ void printgpio(const char* text) { static void wfi (void) { globalCounter++; - if(globalCounter>=iterations) { + if(globalCounter>=globalIterations) { printgpio("finished\n"); exit (0) ; } else { @@ -187,40 +187,50 @@ static void wfi (void) { } } -void doWfi (int argc, char *argv []) -{ - int pin, mode; - int timeoutSec = 2147483647; - iterations = 1; +static void wfi2(struct WPIWfiStatus wfiStatus, void* userdata) { + (void)wfiStatus; + (void)userdata; + globalCounter++; + if (globalCounter>=globalIterations) { + printgpio("finished\n"); + exit(0); + } else { + printgpioflush("I"); + } +} + + +int get_wfi_edge(const char* arg_cmd, const char* arg_mode) { + if (strcasecmp (arg_mode, "rising") == 0) { + return INT_EDGE_RISING ; + } else if (strcasecmp (arg_mode, "falling") == 0) { + return INT_EDGE_FALLING ; + } else if (strcasecmp (arg_mode, "both") == 0) { + return INT_EDGE_BOTH ; + } else { + fprintf (stderr, "%s: wfi: Invalid mode: %s. Should be rising, falling or both\n", arg_cmd, arg_mode) ; + exit (1); + } +} + + +void doWfiInternal(const char* cmd, int pin, int mode, int interations, int timeoutSec, int debounce) { + + globalIterations = interations; globalCounter = 0; - if (argc != 4 && argc != 5 && argc != 6) - { - fprintf (stderr, "Usage: %s wfi pin mode [interations] [timeout sec.]\n", argv [0]) ; - exit (1) ; - } - - pin = atoi (argv [2]) ; - - /**/ if (strcasecmp (argv [3], "rising") == 0) mode = INT_EDGE_RISING ; - else if (strcasecmp (argv [3], "falling") == 0) mode = INT_EDGE_FALLING ; - else if (strcasecmp (argv [3], "both") == 0) mode = INT_EDGE_BOTH ; - else - { - fprintf (stderr, "%s: wfi: Invalid mode: %s. Should be rising, falling or both\n", argv [1], argv [3]) ; - exit (1) ; - } - if (argc>=5) { - iterations = atoi(argv [4]); - } - if (argc>=6) { - timeoutSec = atoi(argv [5]); - } - - if (wiringPiISR (pin, mode, &wfi) < 0) - { - fprintf (stderr, "%s: wfi: Unable to setup ISR: %s\n", argv [1], strerror (errno)) ; - exit (1) ; + if (debounce>=0) { + // V2 function + if (wiringPiISR2(pin, mode, &wfi2, debounce, NULL) < 0) { + fprintf (stderr, "%s: Unable to setup ISR2: %s\n", cmd, strerror (errno)); + exit(1); + } + } else { + // classic function + if (wiringPiISR(pin, mode, &wfi) < 0) { + fprintf (stderr, "%s: Unable to setup ISR: %s\n", cmd, strerror (errno)); + exit(1); + } } printgpio("wait for interrupt function call\n"); @@ -229,7 +239,56 @@ void doWfi (int argc, char *argv []) delay (999); } printgpio("\nstopping wait for interrupt\n"); - wiringPiISRStop (pin); + wiringPiISRStop(pin); +} + + +void doWfi(int argc, char *argv []) +{ + int pin, mode, interations=1; + int timeoutSec = 2147483647; + + if (argc != 4 && argc != 5 && argc != 6) { + fprintf (stderr, "Usage: %s wfi pin mode [interations] [timeout sec.]\n", argv [0]) ; + exit (1) ; + } + + pin = atoi (argv[2]) ; + mode = get_wfi_edge(argv[1], argv[3]); + if (argc>=5) { + interations = atoi(argv[4]); + } + if (argc>=6) { + timeoutSec = atoi(argv[5]); + } + + doWfiInternal(argv[1], pin, mode, interations, timeoutSec, -1); +} + + +void doWfi2(int argc, char *argv []) +{ + int pin, mode, interations=1, debounce=50000; + int timeoutSec = 2147483647; + + if (argc != 4 && argc != 5 && argc != 6 && argc != 7) { + fprintf (stderr, "Usage: %s wfidb pin mode [debounce period microsec.] [interations] [timeout sec.]\n", argv [0]) ; + exit(1); + } + + pin = atoi (argv[2]) ; + mode = get_wfi_edge(argv[1], argv[3]); + if (argc>=5) { + debounce = atoi(argv[4]); + } + if (argc>=6) { + interations = atoi(argv[5]); + } + if (argc>=7) { + timeoutSec = atoi(argv[6]); + } + + doWfiInternal(argv[1], pin, mode, interations, timeoutSec, debounce); } @@ -896,6 +955,10 @@ static void doVersion (char *argv []) } +static void doIs40Pin () +{ + exit(piBoard40Pin()); +} /* * main: @@ -1130,7 +1193,9 @@ int main (int argc, char *argv []) else if (strcasecmp (argv [1], "rbx" ) == 0) doReadByte (argc, argv, TRUE) ; else if (strcasecmp (argv [1], "rbd" ) == 0) doReadByte (argc, argv, FALSE) ; else if (strcasecmp (argv [1], "clock" ) == 0) doClock (argc, argv) ; + else if (strcasecmp (argv [1], "wfidb" ) == 0) doWfi2 (argc, argv) ; else if (strcasecmp (argv [1], "wfi" ) == 0) doWfi (argc, argv) ; + else if (strcasecmp (argv [1], "is40pin" ) == 0) doIs40Pin () ; else { fprintf (stderr, "%s: Unknown command: %s.\n", argv [0], argv [1]) ; diff --git a/gpio/test/gpio_test7_wfi.sh b/gpio/test/gpio_test7_wfi.sh index 7f4ef39..a5d2298 100755 --- a/gpio/test/gpio_test7_wfi.sh +++ b/gpio/test/gpio_test7_wfi.sh @@ -7,22 +7,26 @@ NC='\033[0m' # Reset color UNITTEST_OK=true TIMEOUT=8 iteration=0 +GPIOIN=26 +GPIOOUT=19 wait_with_timeout() { local pid=$1 local timeout=$2 iteration=0 + local toggle=0 while kill -0 "$pid" 2>/dev/null; do if [ $iteration -ge $timeout ]; then kill -9 "$pid" 2>/dev/null echo -e "${RED}ERROR: timeout ${timeout}s reached ${NC}" return -1 fi - gpio -g write 19 1 - sleep 1 echo -n . - gpio -g write 19 0 + sleep 1 + toggle=$((1 - toggle)) + gpio -g write $GPIOOUT $toggle + echo -n ${toggle} iteration=$((iteration + 1)) done @@ -30,51 +34,68 @@ wait_with_timeout() { return $? } +wfi_test() { + local edge=$1 + local set_iter=$2 + local set_iterOK=$3 + + #wfi test + if [ $iteration -eq 0 ]; then + gpio -g wfi $GPIOIN "$edge" & + else + gpio -g wfi $GPIOIN "$edge" "$set_iter" & + fi + GPIO_PID=$! + wait_with_timeout "$GPIO_PID" "$TIMEOUT" + EXIT_CODE=$? + echo + if [ $EXIT_CODE -eq 0 ]; then + if [ "$set_iter" -gt 0 ]; then + if [ "$iteration" -eq "$set_iterOK" ]; then + echo -e "${GREEN}wfi "$edge" $set_iter iteration passt (exit code 0)${NC}" + else + echo -e "${RED}wfi "$edge" failed, $iteration iterations of $set_iter is wrong${NC}" + UNITTEST_OK=false + fi + else + echo -e "${GREEN}wfi "$edge" passt (exit code 0)${NC}" + fi + else + echo -e "${RED}wfi "$edge" failed (exit code $EXIT_CODE)${NC}" + UNITTEST_OK=false + fi +} + echo -echo Unit test gpio GPIO19 and GPIO26 - functions: mode, write, wfi +echo Unit test gpio GPIO${GPIOOUT} and GPIO${GPIOIN} - functions: mode, write, wfi echo ------------------------------------------------------------------ echo #prepare trigger out -gpio -g mode 19 out -gpio -g write 19 0 +gpio -g mode $GPIOOUT out -#wfi test -gpio -g wfi 26 rising & -GPIO_PID=$! -wait_with_timeout "$GPIO_PID" "$TIMEOUT" -EXIT_CODE=$? -echo -if [ $EXIT_CODE -eq 0 ]; then - echo -e "${GREEN}wfi passt (exit code 0)${NC}" -else - echo -e "${RED}wfi failed (exit code $EXIT_CODE)${NC}" - UNITTEST_OK=false -fi +gpio -g write $GPIOOUT 0 +wfi_test "rising" 0 0 + +gpio -g write $GPIOOUT 1 +wfi_test "falling" 0 0 #wfi iteration test -gpio -g wfi 26 rising 4 & -GPIO_PID=$! -wait_with_timeout "$GPIO_PID" "$TIMEOUT" -EXIT_CODE=$? -echo -if [ $EXIT_CODE -eq 0 ]; then - if [ "$iteration" -eq 5 ]; then - echo -e "${GREEN}wfi iteration passt (exit code 0)${NC}" - else - echo -e "${RED}wfi failed, iteration $iteration wrong${NC}" - UNITTEST_OK=false - fi -else - echo -e "${RED}wfi failed (exit code $EXIT_CODE)${NC}" - UNITTEST_OK=false -fi -gpio -g write 19 0 -gpio -g mode 19 in +gpio -g write $GPIOOUT 0 +wfi_test "rising" 4 7 + +gpio -g write $GPIOOUT 1 +wfi_test "falling" 4 8 + +gpio -g write $GPIOOUT 0 +wfi_test "both" 4 4 + +gpio -g write $GPIOOUT 0 +gpio -g mode $GPIOOUT in ### #wfi timeout test -gpio -g wfi 26 rising 2 4 & +gpio -g wfi $GPIOIN rising 2 4 & GPIO_PID=$! wait_with_timeout "$GPIO_PID" "$TIMEOUT" EXIT_CODE=$? From 2f52fa27e5e119dd8d4490e82221341e0ff58364 Mon Sep 17 00:00:00 2001 From: mstroh76 Date: Fri, 16 May 2025 18:31:28 +0200 Subject: [PATCH 38/65] #264 gpio wfis & unit test --- gpio/gpio.c | 39 ++++--- .../{gpio_test7_wfi.sh => gpio_test6_wfi.sh} | 100 +++++++++++++++++- 2 files changed, 126 insertions(+), 13 deletions(-) rename gpio/test/{gpio_test7_wfi.sh => gpio_test6_wfi.sh} (52%) diff --git a/gpio/gpio.c b/gpio/gpio.c index 9fa5bf6..2f6b683 100644 --- a/gpio/gpio.c +++ b/gpio/gpio.c @@ -181,7 +181,7 @@ static void wfi (void) { globalCounter++; if(globalCounter>=globalIterations) { printgpio("finished\n"); - exit (0) ; + exit(0); } else { printgpioflush("I"); } @@ -193,15 +193,25 @@ static void wfi2(struct WPIWfiStatus wfiStatus, void* userdata) { (void)userdata; globalCounter++; if (globalCounter>=globalIterations) { - printgpio("finished\n"); - exit(0); + switch(wfiStatus.edge) { + case INT_EDGE_FALLING: + printgpio("finished falling\n"); + break; + case INT_EDGE_RISING: + printgpio("finished rising\n"); + break; + default: + printgpio("finished\n"); + break; + } + exit(wfiStatus.edge); } else { printgpioflush("I"); } } -int get_wfi_edge(const char* arg_cmd, const char* arg_mode) { +int get_wfi_edge(const char* arg_cmd, const char* arg_mode, int exitcode) { if (strcasecmp (arg_mode, "rising") == 0) { return INT_EDGE_RISING ; } else if (strcasecmp (arg_mode, "falling") == 0) { @@ -210,7 +220,7 @@ int get_wfi_edge(const char* arg_cmd, const char* arg_mode) { return INT_EDGE_BOTH ; } else { fprintf (stderr, "%s: wfi: Invalid mode: %s. Should be rising, falling or both\n", arg_cmd, arg_mode) ; - exit (1); + exit(exitcode); } } @@ -236,7 +246,7 @@ void doWfiInternal(const char* cmd, int pin, int mode, int interations, int time printgpio("wait for interrupt function call\n"); for (int Sec=0; Sec=5) { interations = atoi(argv[4]); } @@ -272,12 +282,12 @@ void doWfi2(int argc, char *argv []) int timeoutSec = 2147483647; if (argc != 4 && argc != 5 && argc != 6 && argc != 7) { - fprintf (stderr, "Usage: %s wfidb pin mode [debounce period microsec.] [interations] [timeout sec.]\n", argv [0]) ; - exit(1); + fprintf (stderr, "Usage: %s wfis pin mode [debounce period microsec.] [interations] [timeout sec.]\n", argv [0]); + exit(-2); } pin = atoi (argv[2]) ; - mode = get_wfi_edge(argv[1], argv[3]); + mode = get_wfi_edge(argv[1], argv[3], -1); if (argc>=5) { debounce = atoi(argv[4]); } @@ -287,8 +297,13 @@ void doWfi2(int argc, char *argv []) if (argc>=7) { timeoutSec = atoi(argv[6]); } + if (timeoutSec<0 || interations<0 || debounce<0) { + fprintf (stderr, " invalid parameter\n"); + exit(-2); + } doWfiInternal(argv[1], pin, mode, interations, timeoutSec, debounce); + exit(-1); // timeout } @@ -1193,7 +1208,7 @@ int main (int argc, char *argv []) else if (strcasecmp (argv [1], "rbx" ) == 0) doReadByte (argc, argv, TRUE) ; else if (strcasecmp (argv [1], "rbd" ) == 0) doReadByte (argc, argv, FALSE) ; else if (strcasecmp (argv [1], "clock" ) == 0) doClock (argc, argv) ; - else if (strcasecmp (argv [1], "wfidb" ) == 0) doWfi2 (argc, argv) ; + else if (strcasecmp (argv [1], "wfis" ) == 0) doWfi2 (argc, argv) ; else if (strcasecmp (argv [1], "wfi" ) == 0) doWfi (argc, argv) ; else if (strcasecmp (argv [1], "is40pin" ) == 0) doIs40Pin () ; else diff --git a/gpio/test/gpio_test7_wfi.sh b/gpio/test/gpio_test6_wfi.sh similarity index 52% rename from gpio/test/gpio_test7_wfi.sh rename to gpio/test/gpio_test6_wfi.sh index a5d2298..89f37e0 100755 --- a/gpio/test/gpio_test7_wfi.sh +++ b/gpio/test/gpio_test6_wfi.sh @@ -9,6 +9,7 @@ TIMEOUT=8 iteration=0 GPIOIN=26 GPIOOUT=19 +DEBOUNCE=100000 wait_with_timeout() { local pid=$1 @@ -27,6 +28,7 @@ wait_with_timeout() { toggle=$((1 - toggle)) gpio -g write $GPIOOUT $toggle echo -n ${toggle} + sleep 0.2 iteration=$((iteration + 1)) done @@ -39,7 +41,7 @@ wfi_test() { local set_iter=$2 local set_iterOK=$3 - #wfi test + #wfi call if [ $iteration -eq 0 ]; then gpio -g wfi $GPIOIN "$edge" & else @@ -66,6 +68,48 @@ wfi_test() { fi } +wfis_test() { + local edge=$1 + local set_iter=$2 + local set_iterOK=$3 + local set_EXITCODE=$4 + + #wfis call + if [ $iteration -eq 0 ]; then + gpio -g wfis $GPIOIN "$edge" $DEBOUNCE & + else + gpio -g wfis $GPIOIN "$edge" $DEBOUNCE "$set_iter" & + fi + GPIO_PID=$! + wait_with_timeout "$GPIO_PID" "$TIMEOUT" + EXIT_CODE=$? + echo + if [ $EXIT_CODE -lt 3 ]; then + + if [ $EXIT_CODE -eq "$set_EXITCODE" ]; then + + if [ "$set_iter" -gt 0 ]; then + if [ "$iteration" -eq "$set_iterOK" ]; then + echo -e "${GREEN}wfis "$edge" $set_iter iteration passt (exit code $EXIT_CODE)${NC}" + else + echo -e "${RED}wfis "$edge" failed, $iteration iterations of $set_iter is wrong${NC}" + UNITTEST_OK=false + fi + else + echo -e "${GREEN}wfi "$edge" passt (exit code $EXIT_CODE)${NC}" + fi + + else + echo -e "${RED}wfis "$edge" failed - wrong exit code $EXIT_CODE${NC}" + UNITTEST_OK=false + fi + + else # negativ + echo -e "${RED}wfis "$edge" failed (exit code $EXIT_CODE)${NC}" + UNITTEST_OK=false + fi +} + echo echo Unit test gpio GPIO${GPIOOUT} and GPIO${GPIOIN} - functions: mode, write, wfi echo ------------------------------------------------------------------ @@ -108,6 +152,60 @@ else fi +echo +echo Unit test gpio GPIO${GPIOOUT} and GPIO${GPIOIN} - functions: mode, write, wfis +echo ------------------------------------------------------------------ +echo + +#prepare trigger out +gpio -g mode $GPIOOUT out + +gpio -g write $GPIOOUT 1 +wfis_test "rising" 0 0 2 + +gpio -g write $GPIOOUT 0 +wfis_test "falling" 0 0 1 + +gpio -g write $GPIOOUT 1 +wfis_test "both" 0 0 1 + +gpio -g write $GPIOOUT 0 +wfis_test "both" 0 0 2 + + +#wfi iteration test + +gpio -g write $GPIOOUT 0 +wfis_test "rising" 4 7 2 + +gpio -g write $GPIOOUT 1 +wfis_test "falling" 4 8 1 + +gpio -g write $GPIOOUT 0 +wfis_test "both" 3 3 2 + +gpio -g write $GPIOOUT 1 +wfis_test "both" 3 4 1 + +gpio -g write $GPIOOUT 0 +gpio -g mode $GPIOOUT in + +### #wfi timeout test +gpio -g wfis $GPIOIN rising $DEBOUNCE 2 4 & +GPIO_PID=$! +wait_with_timeout "$GPIO_PID" "$TIMEOUT" +EXIT_CODE=$? +echo +if [ $EXIT_CODE -eq 255 ]; then + echo -e "${GREEN}wfi timeout passed (exit code $EXIT_CODE)${NC}" +else + echo -e "${RED}wfi timeout failed (code $EXIT_CODE)${NC}" + UNITTEST_OK=false +fi + + + + if [ ${UNITTEST_OK} = true ]; then echo -e "\n\n${GREEN}Unit test result OK.${NC}" exit 0 From 18fc04d7f268402399c4c0b1f1b5c8793f7cc72d Mon Sep 17 00:00:00 2001 From: mstroh76 Date: Sun, 18 May 2025 21:17:09 +0200 Subject: [PATCH 39/65] #322 check pin numbers after convert to BCM --- wiringPi/test/Makefile | 5 +- wiringPi/test/wiringpi_test62_isr_wpin.c | 114 +++++++++++ wiringPi/wiringPi.c | 248 ++++++++++++----------- wiringPi/wiringPi.h | 4 +- 4 files changed, 254 insertions(+), 117 deletions(-) create mode 100644 wiringPi/test/wiringpi_test62_isr_wpin.c diff --git a/wiringPi/test/Makefile b/wiringPi/test/Makefile index 0b68f96..40cbd25 100644 --- a/wiringPi/test/Makefile +++ b/wiringPi/test/Makefile @@ -3,7 +3,7 @@ CFLAGS = -Wall LDFLAGS = # Need BCM19 <-> BCM26, +PWM: BCM12 <-> BCM13, BCM18 <-> BCM17 connected (1kOhm) -tests = wiringpi_test0_version wiringpi_test1_sysfs wiringpi_test2_sysfs wiringpi_test3_device_wpi wiringpi_test4_device_phys wiringpi_test5_default wiringpi_test6_isr wiringpi_test61_isr2 wiringpi_test7_bench wiringpi_test8_pwm wiringpi_test9_pwm +tests = wiringpi_test0_version wiringpi_test1_sysfs wiringpi_test2_sysfs wiringpi_test3_device_wpi wiringpi_test4_device_phys wiringpi_test5_default wiringpi_test6_isr wiringpi_test61_isr2 wiringpi_test62_isr_wpin wiringpi_test7_bench wiringpi_test8_pwm wiringpi_test9_pwm # Need XO hardware xotests = wiringpi_xotest_test1_spi wiringpi_i2c_test1_pcf8574 wiringpi_test8_pwm wiringpi_test9_pwm @@ -37,6 +37,9 @@ wiringpi_test6_isr: wiringpi_test61_isr2: ${CC} ${CFLAGS} wiringpi_test61_isr2.c -o wiringpi_test61_isr2 -lwiringPi +wiringpi_test62_isr_wpin: + ${CC} ${CFLAGS} wiringpi_test62_isr_wpin.c -o wiringpi_test62_isr_wpin -lwiringPi + wiringpi_test7_bench: ${CC} ${CFLAGS} wiringpi_test7_bench.c -o wiringpi_test7_bench -lwiringPi diff --git a/wiringPi/test/wiringpi_test62_isr_wpin.c b/wiringPi/test/wiringpi_test62_isr_wpin.c new file mode 100644 index 0000000..7447c35 --- /dev/null +++ b/wiringPi/test/wiringpi_test62_isr_wpin.c @@ -0,0 +1,114 @@ +// WiringPi test program: Kernel char device interface / sysfs successor +// Compile: gcc -Wall wiringpi_test62_isr_wpin.c -o wiringpi_test62_isr_wpin -lwiringPi + +#include "wpi_test.h" +#include +#include +#include +#include + +//WPI pin numbers +int GPIO = 28; +int GPIOIN = 29; + +static volatile int globalCounter; + + +static void wfiup(void) { + + globalCounter++; + printf("I[%d] ", globalCounter); + fflush(stdout); +} + +static void wfidown(void) { + + globalCounter--; + printf("I[%d] ", globalCounter); + fflush(stdout); +} + + +void StartSequence (int Enge, int OUTpin, int count,int expected) { + /* + int expected = up ? count : 0; + globalCounter = up ? 0 : count; + */ + globalCounter = 0; + + printf("Start: "); + fflush(stdout); + for (int loop=0; loop 28\n"); + + printf("\nWiringPi %d.%d\n", major, minor); + + //printf("Error check - next call create fatal error with exit!\n"); + //CheckSame("wiringPiISRStop with wrong pin, result code:", wiringPiISRStop(5), 0); + + CheckSame("wiringPiSetupPinType(WPI_PIN_WPI)", wiringPiSetupPinType(WPI_PIN_WPI), 0); + + int rev, mem, maker, overVolted, RaspberryPiModel; + piBoardId(&RaspberryPiModel, &rev, &mem, &maker, &overVolted); + + CheckNotSame("piBoardId", RaspberryPiModel, 0); + + int IRQpin = GPIOIN; + int OUTpin = GPIO; + + if (RaspberryPiModel==PI_MODEL_4B) { + pinMode(IRQpin, INPUT); + pinMode(OUTpin, OUTPUT); + digitalWrite (OUTpin, LOW) ; + + printf("\nTesting IRQ @ WPI-GPIO%d with trigger @ WPI-GPIO%d rising\n", IRQpin, OUTpin); + CheckSame("wiringPiISR", wiringPiISR(IRQpin, INT_EDGE_RISING, &wfiup), 0); + sleep(1); + StartSequence(INT_EDGE_RISING, OUTpin, 3 , 3); + sleep(1); + CheckSame("wiringPiISRStop", wiringPiISRStop(IRQpin), 0); + printf("\n.IRQ off\n"); + sleep(1); + StartSequence(INT_EDGE_RISING, OUTpin, 2, 0); + + printf("\nTesting IRQ @ WPI-GPIO%d with trigger @ WPI-GPIO%d falling\n", IRQpin, OUTpin); + CheckSame("wiringPiISR", wiringPiISR(IRQpin, INT_EDGE_RISING, &wfidown), 0); + sleep(1); + StartSequence(INT_EDGE_FALLING, OUTpin, 4, -4); + sleep(1); + CheckSame("wiringPiISRStop", wiringPiISRStop(IRQpin), 0); + printf("\n.IRQ off\n"); + sleep(1); + StartSequence(INT_EDGE_RISING, OUTpin, 2, 0); + + printf("Error check - next call must be wrong!\n"); + CheckSame("wiringPiISRStop with wrong pin, result code:", wiringPiISRStop(5555), EINVAL); + + pinMode(OUTpin, INPUT); + } + + return UnitTestState(); +} diff --git a/wiringPi/wiringPi.c b/wiringPi/wiringPi.c index b5bfbed..f2e8252 100644 --- a/wiringPi/wiringPi.c +++ b/wiringPi/wiringPi.c @@ -646,6 +646,7 @@ int piBoard40Pin() { } } + int piRP1Model() { switch(RaspberryPiModel){ case PI_MODEL_5: @@ -658,8 +659,43 @@ int piRP1Model() { } } + int GetMaxPin() { - return piRP1Model() ? 27 : 63; + if (piRP1Model()) { + switch(wiringPiMode) { + case WPI_MODE_PHYS: + return 40; + case WPI_MODE_PINS: + return 31; + default: + return 27; + } + } else { + return 63; + } +} + + +int ToBCMPin(int* pin) { + if (*pin<0 || *pin>63) { + return FALSE; + } + switch(wiringPiMode) { + case WPI_MODE_PINS: + *pin = pinToGpio[*pin]; + break; + case WPI_MODE_PHYS: + *pin = physToGpio[*pin]; + break; + case WPI_MODE_GPIO: + return TRUE; + default: + return FALSE; + } + if (piRP1Model() && *pin>27) { + return FALSE; + } + return TRUE; } @@ -1286,8 +1322,9 @@ int physPinToGpio (int physPin) ********************************************************************************* */ void setPadDrivePin (int pin, int value) { - if (!piRP1Model()) return; - if (pin < 0 || pin > GetMaxPin()) return ; + if (!piRP1Model() || !ToBCMPin(&pin)) { + return; + } uint32_t wrVal; value = value & 3; // 0-3 supported @@ -1368,14 +1405,9 @@ int getAlt (int pin) { int alt; - pin &= 63 ; - - /**/ if (wiringPiMode == WPI_MODE_PINS) - pin = pinToGpio [pin] ; - else if (wiringPiMode == WPI_MODE_PHYS) - pin = physToGpio [pin] ; - else if (wiringPiMode != WPI_MODE_GPIO) - return 0 ; + if (!ToBCMPin(&pin)) { + return 0; + } if (piRP1Model()) { alt = (gpio[2*pin+1] & RP1_FSEL_NONE_HW); //0-4 function @@ -1586,14 +1618,9 @@ void gpioClockSet (int pin, int freq) int divi, divr, divf ; FailOnModel5("gpioClockSet"); - pin &= 63 ; - - /**/ if (wiringPiMode == WPI_MODE_PINS) - pin = pinToGpio [pin] ; - else if (wiringPiMode == WPI_MODE_PHYS) - pin = physToGpio [pin] ; - else if (wiringPiMode != WPI_MODE_GPIO) - return ; + if (!ToBCMPin(&pin)) { + return; + } divi = 19200000 / freq ; divr = 19200000 % freq ; @@ -1848,65 +1875,58 @@ void pinModeAlt (int pin, int mode) { setupCheck ("pinModeAlt") ; - 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 ; - - if (piRP1Model()) { - //confusion! diffrent to to BCM! this is taking directly the value for the register - int modeRP1; - switch(mode) { - case FSEL_ALT0: - modeRP1 = 0; - break; - case FSEL_ALT1: - modeRP1 = 1; - break; - case FSEL_ALT2: - modeRP1 = 2; - break; - case FSEL_ALT3: - modeRP1 = 3; - break; - case FSEL_ALT4: - modeRP1 = 4; - break; - case FSEL_ALT5: - modeRP1 = 5; - break; - case FSEL_ALT6: - modeRP1 = 6; - break; - case FSEL_ALT7: - modeRP1 = 7; - break; - case FSEL_ALT8: - modeRP1 = 8; - break; - case FSEL_OUTP: - case FSEL_INPT: - modeRP1 = RP1_FSEL_GPIO; - break; - default: - fprintf(stderr, "pinModeAlt: invalid mode %d\n", mode); - return; - } - //printf("pinModeAlt: Pi5 alt pin %d to %d\n", pin, modeRP1); - gpio[2*pin+1] = (modeRP1 & RP1_FSEL_NONE_HW) | RP1_DEBOUNCE_DEFAULT; //0-4 function, 5-11 debounce time - } else { - int fSel = gpioToGPFSEL [pin] ; - int shift = gpioToShift [pin] ; - - *(gpio + fSel) = (*(gpio + fSel) & ~(7 << shift)) | ((mode & 0x7) << shift) ; - } - + if (!ToBCMPin(&pin)) { + return; } -} + + if (piRP1Model()) { + //confusion! diffrent to to BCM! this is taking directly the value for the register + int modeRP1; + switch(mode) { + case FSEL_ALT0: + modeRP1 = 0; + break; + case FSEL_ALT1: + modeRP1 = 1; + break; + case FSEL_ALT2: + modeRP1 = 2; + break; + case FSEL_ALT3: + modeRP1 = 3; + break; + case FSEL_ALT4: + modeRP1 = 4; + break; + case FSEL_ALT5: + modeRP1 = 5; + break; + case FSEL_ALT6: + modeRP1 = 6; + break; + case FSEL_ALT7: + modeRP1 = 7; + break; + case FSEL_ALT8: + modeRP1 = 8; + break; + case FSEL_OUTP: + case FSEL_INPT: + modeRP1 = RP1_FSEL_GPIO; + break; + default: + fprintf(stderr, "pinModeAlt: invalid mode %d\n", mode); + return; + } + //printf("pinModeAlt: Pi5 alt pin %d to %d\n", pin, modeRP1); + gpio[2*pin+1] = (modeRP1 & RP1_FSEL_NONE_HW) | RP1_DEBOUNCE_DEFAULT; //0-4 function, 5-11 debounce time + } else { + int fSel = gpioToGPFSEL [pin] ; + int shift = gpioToShift [pin] ; + + *(gpio + fSel) = (*(gpio + fSel) & ~(7 << shift)) | ((mode & 0x7) << shift) ; + } + } /* @@ -2447,12 +2467,9 @@ void pwmWrite (int pin, int value) 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 ; + if (!ToBCMPin(&pin)) { + return; + } /* would be possible on ms mode but not on bal, deactivated, use pwmc modify instead if (piGpioBase == GPIO_PERI_BASE_2711) { @@ -2677,15 +2694,9 @@ struct WPIWfiStatus waitForInterrupt2(int pin, int edgeMode, int ms, unsigned lo const char* strmode = ""; struct WPIWfiStatus wfiStatus; - if (wiringPiMode == WPI_MODE_PINS) - pin = pinToGpio [pin] ; - else if (wiringPiMode == WPI_MODE_PHYS) - pin = physToGpio [pin] ; - memset(&wfiStatus, 0, sizeof(wfiStatus)); - /* open gpio */ - if (wiringPiGpioDeviceGetFd()<0) { + if (wiringPiGpioDeviceGetFd()<0 || !ToBCMPin(&pin)) { wfiStatus.statusOK = -1; return wfiStatus; } @@ -2844,12 +2855,24 @@ int waitForInterrupt (int pin, int ms) { ********************************************************************************* */ -int wiringPiISRStop (int pin) { - void *res; - +int wiringPiISRStop(int pin) { + + if (wiringPiMode == WPI_MODE_UNINITIALISED) { + return wiringPiFailure(WPI_FATAL, "wiringPiISRStop: wiringPi has not been initialised. Unable to continue.\n"); + } + if (!ToBCMPin(&pin)) { + fprintf(stderr, "wiringPiISRStop: wrong pin %d (mode: %d) number!\n", pin, wiringPiMode); + return EINVAL; + } + if (wiringPiDebug) { + printf("wiringPiISRStop: pin %d\n", pin) ; + } + if (isrFds[pin] > 0) { + void *res; + if (wiringPiDebug) - printf ("wiringPiISRStop: close thread 0x%lX\n", (unsigned long)isrThreads[pin]) ; + printf("wiringPiISRStop: close thread 0x%lX\n", (unsigned long)isrThreads[pin]); if (isrThreads[pin] != 0) { if (pthread_cancel(isrThreads[pin]) == 0) { @@ -2864,10 +2887,13 @@ int wiringPiISRStop (int pin) { } } else { if (wiringPiDebug) - printf ("wiringPiISRStop: could not cancel thread\n"); + printf("wiringPiISRStop: could not cancel thread\n"); } } close(isrFds [pin]); + } else { + if (wiringPiDebug) + printf("wiringPiISRStop: Warning stop isr, but its not active\n"); } isrFds [pin] = -1; isrFunctions[pin] = NULL; @@ -2882,7 +2908,7 @@ int wiringPiISRStop (int pin) { chipFd = -1; */ if (wiringPiDebug) { - printf ("wiringPiISRStop: wiringPiISRStop finished\n") ; + printf("wiringPiISRStop: wiringPiISRStop finished\n"); } return 0; } @@ -3077,24 +3103,18 @@ void *interruptHandlerV2(void *arg) int wiringPiISRInternal(int pin, int edgeMode, void (*function)(struct WPIWfiStatus wfiStatus, void* userdata), void (*functionClassic)(void), unsigned long debounce_period_us, void* userdata) { - const int maxpin = GetMaxPin(); - - if (pin < 0 || pin > maxpin) - return wiringPiFailure (WPI_FATAL, "wiringPiISR: pin must be 0-%d (%d)\n", maxpin, pin) ; - if (wiringPiMode == WPI_MODE_UNINITIALISED) - return wiringPiFailure (WPI_FATAL, "wiringPiISR: wiringPi has not been initialised. Unable to continue.\n") ; - - if (wiringPiMode == WPI_MODE_PINS) { - pin = pinToGpio [pin] ; - } else if (wiringPiMode == WPI_MODE_PHYS) { - pin = physToGpio [pin] ; + if (wiringPiMode == WPI_MODE_UNINITIALISED) { + return wiringPiFailure(WPI_FATAL, "wiringPiISR: wiringPi has not been initialised. Unable to continue.\n"); + } + if (!ToBCMPin(&pin)) { + fprintf(stderr, "wiringPiISRStop: wrong pin %d (mode: %d) number!\n", pin, wiringPiMode); + return EINVAL; } - if (wiringPiDebug) { - printf ("wiringPi: wiringPiISR pin %d, edgeMode %d\n", pin, edgeMode) ; + printf("wiringPi: wiringPiISR pin %d, edgeMode %d\n", pin, edgeMode); } - if (isrFunctions[pin] || isrFunctionsV2[pin] ) { - printf ("wiringPi: ISR function already active, ignoring \n") ; + if (isrFunctions[pin] || isrFunctionsV2[pin]) { + fprintf(stderr, "wiringPi: ISR function already active, ignoring \n"); } isrFunctionsV2[pin] = function; @@ -3104,7 +3124,7 @@ int wiringPiISRInternal(int pin, int edgeMode, void (*function)(struct WPIWfiSta isrDebouncePeriodUs[pin] = debounce_period_us; if (wiringPiDebug) { - printf ("wiringPi: mutex in\n") ; + printf("wiringPi: mutex in\n"); } pthread_mutex_lock (&pinMutex) ; pinPass = pin ; @@ -3129,12 +3149,12 @@ int wiringPiISRInternal(int pin, int edgeMode, void (*function)(struct WPIWfiSta } if (wiringPiDebug) { - printf ("wiringPi: mutex out\n") ; + printf("wiringPi: mutex out\n"); } pthread_mutex_unlock (&pinMutex) ; if (wiringPiDebug) { - printf ("wiringPi: wiringPiISR finished\n") ; + printf("wiringPi: wiringPiISR finished\n"); } return 0 ; } diff --git a/wiringPi/wiringPi.h b/wiringPi/wiringPi.h index 9ae92d0..e9be5a2 100644 --- a/wiringPi/wiringPi.h +++ b/wiringPi/wiringPi.h @@ -281,8 +281,8 @@ extern int piBoardRev (void) ; // Deprecated, but does the sa extern void piBoardId (int *model, int *rev, int *mem, int *maker, int *overVolted) ; extern int piBoard40Pin (void) ; // Interface V3.7 extern int piRP1Model (void) ; // Interface V3.14 -extern int wpiPinToGpio (int wpiPin) ; -extern int physPinToGpio (int physPin) ; +extern int wpiPinToGpio (int wpiPin) ; // please don't use outside 0-63 and on RP1 +extern int physPinToGpio (int physPin) ; // please don't use outside 0-63 and on RP1 extern void setPadDrive (int group, int value) ; extern void setPadDrivePin (int pin, int value); // Interface V3.0 extern int getAlt (int pin) ; From b87ca97daf913a8190c803f5b980a427953d78af Mon Sep 17 00:00:00 2001 From: mstroh76 Date: Fri, 23 May 2025 19:51:01 +0200 Subject: [PATCH 40/65] #264 adjust unit test and fix is40pin --- gpio/gpio.c | 2 +- gpio/test/gpio_test6_wfi.sh | 4 ++ wiringPi/test/wiringpi_test61_isr2.c | 2 +- wiringPi/test/wiringpi_test62_isr_wpin.c | 58 +++++++++++++----------- 4 files changed, 38 insertions(+), 28 deletions(-) diff --git a/gpio/gpio.c b/gpio/gpio.c index 2f6b683..a420cd3 100644 --- a/gpio/gpio.c +++ b/gpio/gpio.c @@ -972,7 +972,7 @@ static void doVersion (char *argv []) static void doIs40Pin () { - exit(piBoard40Pin()); + exit(piBoard40Pin() ? EXIT_SUCCESS : EXIT_FAILURE); } /* diff --git a/gpio/test/gpio_test6_wfi.sh b/gpio/test/gpio_test6_wfi.sh index 89f37e0..5a0d6af 100755 --- a/gpio/test/gpio_test6_wfi.sh +++ b/gpio/test/gpio_test6_wfi.sh @@ -110,11 +110,15 @@ wfis_test() { fi } +gpio is40pin || { GPIOIN=17; GPIOOUT=18; echo "old 28 pin system"; } + + echo echo Unit test gpio GPIO${GPIOOUT} and GPIO${GPIOIN} - functions: mode, write, wfi echo ------------------------------------------------------------------ echo + #prepare trigger out gpio -g mode $GPIOOUT out diff --git a/wiringPi/test/wiringpi_test61_isr2.c b/wiringPi/test/wiringpi_test61_isr2.c index 9c37cc0..e0d21f5 100644 --- a/wiringPi/test/wiringpi_test61_isr2.c +++ b/wiringPi/test/wiringpi_test61_isr2.c @@ -12,7 +12,7 @@ int GPIO = 19; int GPIOIN = 26; const int ToggleValue = 4; float irq_timstamp_duration_ms = 0; -float accuracy = 0.012; +float accuracy = 0.015; float bounce_acc = 1.0; static volatile int globalCounter; diff --git a/wiringPi/test/wiringpi_test62_isr_wpin.c b/wiringPi/test/wiringpi_test62_isr_wpin.c index 7447c35..00a599a 100644 --- a/wiringPi/test/wiringpi_test62_isr_wpin.c +++ b/wiringPi/test/wiringpi_test62_isr_wpin.c @@ -79,35 +79,41 @@ int main (void) { int IRQpin = GPIOIN; int OUTpin = GPIO; - if (RaspberryPiModel==PI_MODEL_4B) { - pinMode(IRQpin, INPUT); - pinMode(OUTpin, OUTPUT); - digitalWrite (OUTpin, LOW) ; - - printf("\nTesting IRQ @ WPI-GPIO%d with trigger @ WPI-GPIO%d rising\n", IRQpin, OUTpin); - CheckSame("wiringPiISR", wiringPiISR(IRQpin, INT_EDGE_RISING, &wfiup), 0); - sleep(1); - StartSequence(INT_EDGE_RISING, OUTpin, 3 , 3); - sleep(1); - CheckSame("wiringPiISRStop", wiringPiISRStop(IRQpin), 0); - printf("\n.IRQ off\n"); - sleep(1); - StartSequence(INT_EDGE_RISING, OUTpin, 2, 0); + switch(RaspberryPiModel) { + case PI_MODEL_4B: + case PI_MODEL_5: + pinMode(IRQpin, INPUT); + pinMode(OUTpin, OUTPUT); + digitalWrite (OUTpin, LOW) ; - printf("\nTesting IRQ @ WPI-GPIO%d with trigger @ WPI-GPIO%d falling\n", IRQpin, OUTpin); - CheckSame("wiringPiISR", wiringPiISR(IRQpin, INT_EDGE_RISING, &wfidown), 0); - sleep(1); - StartSequence(INT_EDGE_FALLING, OUTpin, 4, -4); - sleep(1); - CheckSame("wiringPiISRStop", wiringPiISRStop(IRQpin), 0); - printf("\n.IRQ off\n"); - sleep(1); - StartSequence(INT_EDGE_RISING, OUTpin, 2, 0); + printf("\nTesting IRQ @ WPI-GPIO%d with trigger @ WPI-GPIO%d rising\n", IRQpin, OUTpin); + CheckSame("wiringPiISR", wiringPiISR(IRQpin, INT_EDGE_RISING, &wfiup), 0); + sleep(1); + StartSequence(INT_EDGE_RISING, OUTpin, 3 , 3); + sleep(1); + CheckSame("wiringPiISRStop", wiringPiISRStop(IRQpin), 0); + printf("\n.IRQ off\n"); + sleep(1); + StartSequence(INT_EDGE_RISING, OUTpin, 2, 0); - printf("Error check - next call must be wrong!\n"); - CheckSame("wiringPiISRStop with wrong pin, result code:", wiringPiISRStop(5555), EINVAL); + printf("\nTesting IRQ @ WPI-GPIO%d with trigger @ WPI-GPIO%d falling\n", IRQpin, OUTpin); + CheckSame("wiringPiISR", wiringPiISR(IRQpin, INT_EDGE_RISING, &wfidown), 0); + sleep(1); + StartSequence(INT_EDGE_FALLING, OUTpin, 4, -4); + sleep(1); + CheckSame("wiringPiISRStop", wiringPiISRStop(IRQpin), 0); + printf("\n.IRQ off\n"); + sleep(1); + StartSequence(INT_EDGE_RISING, OUTpin, 2, 0); - pinMode(OUTpin, INPUT); + printf("Error check - next call must be wrong!\n"); + CheckSame("wiringPiISRStop with wrong pin, result code:", wiringPiISRStop(5555), EINVAL); + + pinMode(OUTpin, INPUT); + break; + default: + printf("unit test not possible with this hardware, need connection between Wiringpi pin 28 and 29!\n"); + break; } return UnitTestState(); From 0b8eede1bd26c88177622c9dcbf68ab7f734d53b Mon Sep 17 00:00:00 2001 From: mstroh76 Date: Fri, 23 May 2025 20:51:06 +0200 Subject: [PATCH 41/65] #346 adjust unit test --- wiringPi/test/wiringpi_test61_isr2.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/wiringPi/test/wiringpi_test61_isr2.c b/wiringPi/test/wiringpi_test61_isr2.c index e0d21f5..06f73ee 100644 --- a/wiringPi/test/wiringpi_test61_isr2.c +++ b/wiringPi/test/wiringpi_test61_isr2.c @@ -189,6 +189,14 @@ int main (void) { wiringPiVersion(&major, &minor); + if (!piBoard40Pin()) { + printf("Old 28pin system\n"); + //GPIO = 23; + //GPIOIN = 24; + GPIO = 17; + GPIOIN = 18; + } + printf("WiringPi GPIO test program 6b (using GPIO%d (output) and GPIO%d (input))\n", GPIO, GPIOIN); printf("ISR and ISR2 test (WiringPi %d.%d)\n", major, minor); @@ -206,6 +214,11 @@ int main (void) { accuracy = 0.02; bounce_acc = 2.7; break; + case PI_MODEL_ZERO: + case PI_MODEL_ZERO_W: //ARM=1000MHz + accuracy = 0.02; + bounce_acc = 2.5; + break; default: accuracy = 0.012; bounce_acc = 1.0; From bb0af182657762c6208cdc970b5af25ffde8482c Mon Sep 17 00:00:00 2001 From: mstroh76 Date: Sat, 24 May 2025 12:23:02 +0200 Subject: [PATCH 42/65] #264 adjust unit test and autodetect unit test 6.2 irq --- wiringPi/test/wiringpi_test61_isr2.c | 25 ++++++++++----- wiringPi/test/wiringpi_test62_isr_wpin.c | 39 +++++++++++++++--------- wiringPi/test/wiringpi_test7_bench.c | 2 +- 3 files changed, 43 insertions(+), 23 deletions(-) diff --git a/wiringPi/test/wiringpi_test61_isr2.c b/wiringPi/test/wiringpi_test61_isr2.c index e0d21f5..a6b9a2f 100644 --- a/wiringPi/test/wiringpi_test61_isr2.c +++ b/wiringPi/test/wiringpi_test61_isr2.c @@ -1,5 +1,5 @@ -// WiringPi test program: 3.16 new ISR2 function with Kernel char device interface / sysfs successor -// Compile: gcc -Wall wiringpi_test1_device.c -o wiringpi_test1_device -lwiringPi +// WiringPi test program: 6.1 new ISR2 function with Kernel char device interface / sysfs successor +// Compile: gcc -Wall wiringpi_test61_isr2.c -o wiringpi_test61_isr2 -lwiringPi #include "wpi_test.h" #include @@ -189,7 +189,17 @@ int main (void) { wiringPiVersion(&major, &minor); - printf("WiringPi GPIO test program 6b (using GPIO%d (output) and GPIO%d (input))\n", GPIO, GPIOIN); + int result = piBoard40Pin(); + CheckNotSame("40-Pin board: ", result, -1); + if (result==0) { + printf("Old 28pin system\n"); + //GPIO = 23; + //GPIOIN = 24; + GPIO = 17; + GPIOIN = 18; + } + + printf("WiringPi GPIO test program 6.2 (using GPIO%d (output) and GPIO%d (input))\n", GPIO, GPIOIN); printf("ISR and ISR2 test (WiringPi %d.%d)\n", major, minor); wiringPiSetupGpio(); @@ -206,15 +216,16 @@ int main (void) { accuracy = 0.02; bounce_acc = 2.7; break; + case PI_MODEL_ZERO: + case PI_MODEL_ZERO_W: //ARM=1000MHz + accuracy = 0.02; + bounce_acc = 2.5; + break; default: accuracy = 0.012; bounce_acc = 1.0; break; } - if (!piBoard40Pin()) { - GPIO = 23; - GPIOIN = 24; - } int IRQpin = GPIOIN; int OUTpin = GPIO; diff --git a/wiringPi/test/wiringpi_test62_isr_wpin.c b/wiringPi/test/wiringpi_test62_isr_wpin.c index 00a599a..500e7c6 100644 --- a/wiringPi/test/wiringpi_test62_isr_wpin.c +++ b/wiringPi/test/wiringpi_test62_isr_wpin.c @@ -76,15 +76,24 @@ int main (void) { CheckNotSame("piBoardId", RaspberryPiModel, 0); - int IRQpin = GPIOIN; - int OUTpin = GPIO; - - switch(RaspberryPiModel) { - case PI_MODEL_4B: - case PI_MODEL_5: - pinMode(IRQpin, INPUT); - pinMode(OUTpin, OUTPUT); - digitalWrite (OUTpin, LOW) ; + int _is40pin = is40pin(); + CheckNotSame("is40pin", _is40pin, -1); + + if (_is40pin) { + + int IRQpin = GPIOIN; + int OUTpin = GPIO; + + pinMode(IRQpin, INPUT); + pinMode(OUTpin, OUTPUT); + digitalWrite(OUTpin, LOW); + delayMicroseconds(100); + CheckNotSame("Input", digitalRead(IRQpin), LOW); + digitalWrite(OUTpin, HIGH); + delayMicroseconds(100); + if (digitalRead(IRQpin)==HIGH) { + digitalWrite(OUTpin, LOW); + delayMicroseconds(100); printf("\nTesting IRQ @ WPI-GPIO%d with trigger @ WPI-GPIO%d rising\n", IRQpin, OUTpin); CheckSame("wiringPiISR", wiringPiISR(IRQpin, INT_EDGE_RISING, &wfiup), 0); @@ -108,12 +117,12 @@ int main (void) { printf("Error check - next call must be wrong!\n"); CheckSame("wiringPiISRStop with wrong pin, result code:", wiringPiISRStop(5555), EINVAL); - - pinMode(OUTpin, INPUT); - break; - default: - printf("unit test not possible with this hardware, need connection between Wiringpi pin 28 and 29!\n"); - break; + } else { + printf("Hardware connection for unit test missing!\n"); + printf("unit test, need connection between Wiringpi pin 28 and 29!\n"); + } + } else { + printf("unit test is for 40-pin hardware only!\n"); } return UnitTestState(); diff --git a/wiringPi/test/wiringpi_test7_bench.c b/wiringPi/test/wiringpi_test7_bench.c index 316c07e..9c0f221 100644 --- a/wiringPi/test/wiringpi_test7_bench.c +++ b/wiringPi/test/wiringpi_test7_bench.c @@ -66,7 +66,7 @@ int main (void) { case PI_MODEL_ZERO_W: //ARM=1000MHz fExpectTimedigitalWrite = 0.104; //us; fExpectTimedigitalRead = 0.135; //us - fExpectTimepinMode = 0.280; //us + fExpectTimepinMode = 0.360; //us break; case PI_MODEL_2: ToggleValue /= 4; From 545eb4f5ed64170aa54e028ecb75cda2c64e1912 Mon Sep 17 00:00:00 2001 From: mstroh76 Date: Sat, 24 May 2025 12:30:02 +0200 Subject: [PATCH 43/65] #264 adjust unit test and autodetect unit test 6.2 irq --- wiringPi/test/wiringpi_test61_isr2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wiringPi/test/wiringpi_test61_isr2.c b/wiringPi/test/wiringpi_test61_isr2.c index 78a442a..67bb35f 100644 --- a/wiringPi/test/wiringpi_test61_isr2.c +++ b/wiringPi/test/wiringpi_test61_isr2.c @@ -219,7 +219,7 @@ int main (void) { case PI_MODEL_ZERO: case PI_MODEL_ZERO_W: //ARM=1000MHz accuracy = 0.02; - bounce_acc = 2.5; + bounce_acc = 2.7; break; default: accuracy = 0.012; From e914bb230023f81033c082129132dd330e98b4e0 Mon Sep 17 00:00:00 2001 From: mstroh76 Date: Sat, 24 May 2025 12:31:00 +0200 Subject: [PATCH 44/65] #264 adjust unit test and autodetect unit test 6.2 irq --- wiringPi/test/wiringpi_test62_isr_wpin.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/wiringPi/test/wiringpi_test62_isr_wpin.c b/wiringPi/test/wiringpi_test62_isr_wpin.c index 500e7c6..6132d21 100644 --- a/wiringPi/test/wiringpi_test62_isr_wpin.c +++ b/wiringPi/test/wiringpi_test62_isr_wpin.c @@ -76,10 +76,10 @@ int main (void) { CheckNotSame("piBoardId", RaspberryPiModel, 0); - int _is40pin = is40pin(); + int _is40pin = piBoard40Pin(); CheckNotSame("is40pin", _is40pin, -1); - if (_is40pin) { + if (_is40pin==1) { int IRQpin = GPIOIN; int OUTpin = GPIO; @@ -88,7 +88,7 @@ int main (void) { pinMode(OUTpin, OUTPUT); digitalWrite(OUTpin, LOW); delayMicroseconds(100); - CheckNotSame("Input", digitalRead(IRQpin), LOW); + CheckSame("Input", digitalRead(IRQpin), LOW); digitalWrite(OUTpin, HIGH); delayMicroseconds(100); if (digitalRead(IRQpin)==HIGH) { From 7d30759eacceff255c001f8d2af5be01203f2a31 Mon Sep 17 00:00:00 2001 From: Connor Gibson Date: Sat, 24 May 2025 18:28:27 -0700 Subject: [PATCH 45/65] [test/Makefile] Auto-generate .gitignore for test executables --- wiringPi/test/Makefile | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/wiringPi/test/Makefile b/wiringPi/test/Makefile index 299dcb4..151a476 100644 --- a/wiringPi/test/Makefile +++ b/wiringPi/test/Makefile @@ -11,7 +11,7 @@ xotests = wiringpi_xotest_test1_spi wiringpi_i2c_test1_pcf8574 wiringpi_test8_pw # Need PiFace hardware and BCM23 <-> BCM24 , BCM18 <-> BCM17 connected (1kOhm), and PiFace Out7<->In4, Out6<->In5, R0_NO<->In6, R0_NO<->In7, R_C<-100Ohm->GND pifacetests = wiringpi_piface_test1 wiringpi_test8_pwm wiringpi_test9_pwm -all: $(tests) $(xotests) $(pifacetests) +all: $(tests) $(xotests) $(pifacetests) .gitignore wiringpi_test0_version: ${CC} ${CFLAGS} wiringpi_test0_version.c -o wiringpi_test0_version -lwiringPi @@ -113,7 +113,23 @@ pifacetest: echo "\n\e[5mPIFACE TEST SUCCESS\e[0m\n"; \ fi +# Add all binaries to a folder-local .gitignore file +.gitignore: + @echo "Updating test directory .gitignore..." + @if ! test -f "./.gitignore"; then \ + echo "# This file is automatically generated by make." >> .gitignore; \ + echo "# Git will ignore this file and all generated WiringPi test binaries in this folder." >> .gitignore; \ + echo "/.gitignore" >> .gitignore; \ + fi + @for t in $(tests) $(xotests) $(pifacetests) ; do \ + if ! grep -q "/$$t" .gitignore; then \ + echo "/$$t" >> .gitignore; \ + echo "Added /$$t to .gitignore"; \ + fi; \ + done + clean: for t in $(tests) $(xotests) $(pifacetests) ; do \ rm -fv $${t} ; \ done + rm -fv .gitignore From efbf39df02a7242cd20762196918d2d0e4d1a5a6 Mon Sep 17 00:00:00 2001 From: Connor Gibson Date: Tue, 27 May 2025 16:16:41 -0700 Subject: [PATCH 46/65] Add function definition for `wiringPiSPIxSetup()` --- wiringPi/wiringPiSPI.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/wiringPi/wiringPiSPI.c b/wiringPi/wiringPiSPI.c index 4657b38..581a079 100644 --- a/wiringPi/wiringPiSPI.c +++ b/wiringPi/wiringPiSPI.c @@ -1,7 +1,7 @@ /* * wiringPiSPI.c: * Simplified SPI access routines - * Copyright (c) 2012-2015 Gordon Henderson + * Copyright (c) 2012-2025 Gordon Henderson and contributors *********************************************************************** * This file is part of wiringPi: * https://github.com/WiringPi/WiringPi/ @@ -195,6 +195,11 @@ int wiringPiSPISetupMode (int channel, int speed, int mode) { ********************************************************************************* */ +int wiringPiSPIxSetup (const int number, const int channel, const int speed) { + return wiringPiSPIxSetupMode(number, channel, speed, 0) ; +} + + int wiringPiSPISetup (int channel, int speed) { return wiringPiSPIxSetupMode(0, channel, speed, 0) ; } From 18a1509b5cec553bcdbffb40283a400449adc748 Mon Sep 17 00:00:00 2001 From: Connor Gibson Date: Tue, 27 May 2025 16:21:40 -0700 Subject: [PATCH 47/65] Update copyright date --- wiringPi/wiringPiSPI.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wiringPi/wiringPiSPI.h b/wiringPi/wiringPiSPI.h index cd1bc03..d60b064 100644 --- a/wiringPi/wiringPiSPI.h +++ b/wiringPi/wiringPiSPI.h @@ -1,7 +1,7 @@ /* * wiringPiSPI.h: * Simplified SPI access routines - * Copyright (c) 2012-2024 Gordon Henderson and contributors + * Copyright (c) 2012-2025 Gordon Henderson and contributors *********************************************************************** * This file is part of wiringPi: * https://github.com/WiringPi/WiringPi/ From f88e168b403490894e6ab3f225d6720aa6b23256 Mon Sep 17 00:00:00 2001 From: mstroh76 Date: Sat, 31 May 2025 19:06:30 +0200 Subject: [PATCH 48/65] #264 unit test for gpio wfis --- gpio/test/gpio_test61_wfi.sh | 140 +++++++++++++++++++++++++++++++++++ 1 file changed, 140 insertions(+) create mode 100755 gpio/test/gpio_test61_wfi.sh diff --git a/gpio/test/gpio_test61_wfi.sh b/gpio/test/gpio_test61_wfi.sh new file mode 100755 index 0000000..2576dec --- /dev/null +++ b/gpio/test/gpio_test61_wfi.sh @@ -0,0 +1,140 @@ +#!/bin/bash + +RED='\033[0;31m' +GREEN='\033[0;32m' +NC='\033[0m' # Reset color + +DEBOUNCE=100000 + +UNITTEST_OK=true +TIMEOUT=20 +iteration=0 +GPIOIN=26 +GPIOOUT=19 + +wait_with_timeout() { + local pid=$1 + local timeout=$2 + iteration=0 + + local toggle=0 + while kill -0 "$pid" 2>/dev/null; do + if [ $iteration -ge $timeout ]; then + kill -9 "$pid" 2>/dev/null + echo -e "${RED}ERROR: timeout ${timeout}s reached ${NC}" + return -1 + fi + echo -n . + sleep 1 + toggle=$((1 - toggle)) + gpio -g write $GPIOOUT $toggle + echo -n ${toggle} + sleep 0.2 + iteration=$((iteration + 1)) + done + + wait "$pid" + return $? +} + +wfis_test() { + local edge=$1 + local set_iter=$2 + local set_iterOK=$3 + local set_EXITCODE=$4 + + #wfi test + if [ $iteration -eq 0 ]; then + gpio -g wfis $GPIOIN "$edge" $DEBOUNCE & + else + gpio -g wfis $GPIOIN "$edge" $DEBOUNCE "$set_iter" & + fi + GPIO_PID=$! + wait_with_timeout "$GPIO_PID" "$TIMEOUT" + EXIT_CODE=$? + echo + if [ $EXIT_CODE -lt 3 ]; then + + if [ $EXIT_CODE -eq "$set_EXITCODE" ]; then + + if [ "$set_iter" -gt 0 ]; then + if [ "$iteration" -eq "$set_iterOK" ]; then + echo -e "${GREEN}wfis "$edge" $set_iter iteration passt (exit code $EXIT_CODE)${NC}" + else + echo -e "${RED}wfis "$edge" failed, $iteration iterations of $set_iter is wrong${NC}" + UNITTEST_OK=false + fi + else + echo -e "${GREEN}wfi "$edge" passt (exit code $EXIT_CODE)${NC}" + fi + + else + echo -e "${RED}wfis "$edge" failed - wrong exit code $EXIT_CODE${NC}" + UNITTEST_OK=false + fi + + else # negativ + echo -e "${RED}wfidb "$edge" failed (exit code $EXIT_CODE)${NC}" + UNITTEST_OK=false + fi +} + +echo +echo Unit test gpio GPIO${GPIOOUT} and GPIO${GPIOIN} - functions: mode, write, wfidb +echo ------------------------------------------------------------------ +echo + +#prepare trigger out +gpio -g mode $GPIOOUT out + +gpio -g write $GPIOOUT 1 +wfis_test "rising" 0 0 2 + +gpio -g write $GPIOOUT 0 +wfis_test "falling" 0 0 1 + +gpio -g write $GPIOOUT 1 +wfis_test "both" 0 0 1 + +gpio -g write $GPIOOUT 0 +wfis_test "both" 0 0 2 + + +#wfi iteration test + +gpio -g write $GPIOOUT 0 +wfis_test "rising" 4 7 2 + +gpio -g write $GPIOOUT 1 +wfis_test "falling" 4 8 1 + +gpio -g write $GPIOOUT 0 +wfis_test "both" 3 3 2 + +gpio -g write $GPIOOUT 1 +wfis_test "both" 3 4 1 + +gpio -g write $GPIOOUT 0 +gpio -g mode $GPIOOUT in + +### #wfi timeout test +gpio -g wfis $GPIOIN rising $DEBOUNCE 2 4 & +GPIO_PID=$! +wait_with_timeout "$GPIO_PID" "$TIMEOUT" +EXIT_CODE=$? +echo +if [ $EXIT_CODE -eq 255 ]; then + echo -e "${GREEN}wfi timeout passed (exit code $EXIT_CODE)${NC}" +else + echo -e "${RED}wfi timeout failed (code $EXIT_CODE)${NC}" + UNITTEST_OK=false +fi + + +if [ ${UNITTEST_OK} = true ]; then + echo -e "\n\n${GREEN}Unit test result OK.${NC}" + exit 0 +else + echo -e "\n\n${RED}Unit test result failed.${NC}" + exit 1 +fi From 18a6935530e460bf4d2b13820b56045d15112df4 Mon Sep 17 00:00:00 2001 From: mstroh76 Date: Sat, 31 May 2025 19:12:22 +0200 Subject: [PATCH 49/65] #264 unit test for gpio wfis --- gpio/test/gpio_test61_wfi.sh | 140 ----------------------------------- 1 file changed, 140 deletions(-) delete mode 100755 gpio/test/gpio_test61_wfi.sh diff --git a/gpio/test/gpio_test61_wfi.sh b/gpio/test/gpio_test61_wfi.sh deleted file mode 100755 index 2576dec..0000000 --- a/gpio/test/gpio_test61_wfi.sh +++ /dev/null @@ -1,140 +0,0 @@ -#!/bin/bash - -RED='\033[0;31m' -GREEN='\033[0;32m' -NC='\033[0m' # Reset color - -DEBOUNCE=100000 - -UNITTEST_OK=true -TIMEOUT=20 -iteration=0 -GPIOIN=26 -GPIOOUT=19 - -wait_with_timeout() { - local pid=$1 - local timeout=$2 - iteration=0 - - local toggle=0 - while kill -0 "$pid" 2>/dev/null; do - if [ $iteration -ge $timeout ]; then - kill -9 "$pid" 2>/dev/null - echo -e "${RED}ERROR: timeout ${timeout}s reached ${NC}" - return -1 - fi - echo -n . - sleep 1 - toggle=$((1 - toggle)) - gpio -g write $GPIOOUT $toggle - echo -n ${toggle} - sleep 0.2 - iteration=$((iteration + 1)) - done - - wait "$pid" - return $? -} - -wfis_test() { - local edge=$1 - local set_iter=$2 - local set_iterOK=$3 - local set_EXITCODE=$4 - - #wfi test - if [ $iteration -eq 0 ]; then - gpio -g wfis $GPIOIN "$edge" $DEBOUNCE & - else - gpio -g wfis $GPIOIN "$edge" $DEBOUNCE "$set_iter" & - fi - GPIO_PID=$! - wait_with_timeout "$GPIO_PID" "$TIMEOUT" - EXIT_CODE=$? - echo - if [ $EXIT_CODE -lt 3 ]; then - - if [ $EXIT_CODE -eq "$set_EXITCODE" ]; then - - if [ "$set_iter" -gt 0 ]; then - if [ "$iteration" -eq "$set_iterOK" ]; then - echo -e "${GREEN}wfis "$edge" $set_iter iteration passt (exit code $EXIT_CODE)${NC}" - else - echo -e "${RED}wfis "$edge" failed, $iteration iterations of $set_iter is wrong${NC}" - UNITTEST_OK=false - fi - else - echo -e "${GREEN}wfi "$edge" passt (exit code $EXIT_CODE)${NC}" - fi - - else - echo -e "${RED}wfis "$edge" failed - wrong exit code $EXIT_CODE${NC}" - UNITTEST_OK=false - fi - - else # negativ - echo -e "${RED}wfidb "$edge" failed (exit code $EXIT_CODE)${NC}" - UNITTEST_OK=false - fi -} - -echo -echo Unit test gpio GPIO${GPIOOUT} and GPIO${GPIOIN} - functions: mode, write, wfidb -echo ------------------------------------------------------------------ -echo - -#prepare trigger out -gpio -g mode $GPIOOUT out - -gpio -g write $GPIOOUT 1 -wfis_test "rising" 0 0 2 - -gpio -g write $GPIOOUT 0 -wfis_test "falling" 0 0 1 - -gpio -g write $GPIOOUT 1 -wfis_test "both" 0 0 1 - -gpio -g write $GPIOOUT 0 -wfis_test "both" 0 0 2 - - -#wfi iteration test - -gpio -g write $GPIOOUT 0 -wfis_test "rising" 4 7 2 - -gpio -g write $GPIOOUT 1 -wfis_test "falling" 4 8 1 - -gpio -g write $GPIOOUT 0 -wfis_test "both" 3 3 2 - -gpio -g write $GPIOOUT 1 -wfis_test "both" 3 4 1 - -gpio -g write $GPIOOUT 0 -gpio -g mode $GPIOOUT in - -### #wfi timeout test -gpio -g wfis $GPIOIN rising $DEBOUNCE 2 4 & -GPIO_PID=$! -wait_with_timeout "$GPIO_PID" "$TIMEOUT" -EXIT_CODE=$? -echo -if [ $EXIT_CODE -eq 255 ]; then - echo -e "${GREEN}wfi timeout passed (exit code $EXIT_CODE)${NC}" -else - echo -e "${RED}wfi timeout failed (code $EXIT_CODE)${NC}" - UNITTEST_OK=false -fi - - -if [ ${UNITTEST_OK} = true ]; then - echo -e "\n\n${GREEN}Unit test result OK.${NC}" - exit 0 -else - echo -e "\n\n${RED}Unit test result failed.${NC}" - exit 1 -fi From b5eac6062783903c9c35f180e497c165b4540737 Mon Sep 17 00:00:00 2001 From: mstroh76 Date: Sat, 31 May 2025 19:43:14 +0200 Subject: [PATCH 50/65] Release 3.16 --- VERSION | 2 +- version.h | 4 ++-- wiringPi/test/wiringpi_test9_pwm.c | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/VERSION b/VERSION index 230693c..5174c53 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -3.15 \ No newline at end of file +3.16 diff --git a/version.h b/version.h index d7f42c6..5ea1e8c 100644 --- a/version.h +++ b/version.h @@ -1,3 +1,3 @@ -#define VERSION "3.15" +#define VERSION "3.16" #define VERSION_MAJOR 3 -#define VERSION_MINOR 15 +#define VERSION_MINOR 16 diff --git a/wiringPi/test/wiringpi_test9_pwm.c b/wiringPi/test/wiringpi_test9_pwm.c index a5605f5..88775fc 100644 --- a/wiringPi/test/wiringpi_test9_pwm.c +++ b/wiringPi/test/wiringpi_test9_pwm.c @@ -135,7 +135,7 @@ int main (void) { pinMode(PWM, PWM_OUTPUT); //Mode BAL, pwmr=1024, pwmc=32 printf("pwmc 4.8kHz\n"); pwmSetClock(2000); - delay(250); + delay(1000); printf("Register ISR@%d\n", PWM); // INT_EDGE_BOTH, INT_EDGE_FALLING, INT_EDGE_RISING only one ISR per input From fbd4353121f3b1365a54a04f511b4304345e9029 Mon Sep 17 00:00:00 2001 From: Connor Gibson Date: Thu, 15 May 2025 17:19:22 -0700 Subject: [PATCH 51/65] Remove deprecated digitalRead8() and digitalWrite8() functions from comments --- wiringPi/wiringPi.c | 51 --------------------------------------------- wiringPi/wiringPi.h | 2 -- 2 files changed, 53 deletions(-) diff --git a/wiringPi/wiringPi.c b/wiringPi/wiringPi.c index 7887633..bea4084 100644 --- a/wiringPi/wiringPi.c +++ b/wiringPi/wiringPi.c @@ -1624,8 +1624,6 @@ struct wiringPiNodeStruct *wiringPiFindNode (int pin) static void pinModeDummy (UNU struct wiringPiNodeStruct *node, UNU int pin, UNU int mode) { return ; } static void pullUpDnControlDummy (UNU struct wiringPiNodeStruct *node, UNU int pin, UNU int pud) { return ; } -//static unsigned int digitalRead8Dummy (UNU struct wiringPiNodeStruct *node, UNU int UNU pin) { return 0 ; } -//static void digitalWrite8Dummy (UNU struct wiringPiNodeStruct *node, UNU int pin, UNU int value) { return ; } static int digitalReadDummy (UNU struct wiringPiNodeStruct *node, UNU int UNU pin) { return LOW ; } static void digitalWriteDummy (UNU struct wiringPiNodeStruct *node, UNU int pin, UNU int value) { return ; } static void pwmWriteDummy (UNU struct wiringPiNodeStruct *node, UNU int pin, UNU int value) { return ; } @@ -1657,9 +1655,7 @@ struct wiringPiNodeStruct *wiringPiNewNode (int pinBase, int numPins) node->pinMode = pinModeDummy ; node->pullUpDnControl = pullUpDnControlDummy ; node->digitalRead = digitalReadDummy ; -//node->digitalRead8 = digitalRead8Dummy ; node->digitalWrite = digitalWriteDummy ; -//node->digitalWrite8 = digitalWrite8Dummy ; node->pwmWrite = pwmWriteDummy ; node->analogRead = analogReadDummy ; node->analogWrite = analogWriteDummy ; @@ -2230,27 +2226,6 @@ int digitalRead (int pin) } -/* - * digitalRead8: - * Read 8-bits (a byte) from given start pin. - ********************************************************************************* - -unsigned int digitalRead8 (int pin) -{ - struct wiringPiNodeStruct *node = wiringPiNodes ; - - if ((pin & PI_GPIO_MASK) == 0) // On-Board Pin - return 0 ; - else - { - if ((node = wiringPiFindNode (pin)) == NULL) - return LOW ; - return node->digitalRead8 (node, pin) ; - } -} - */ - - /* * digitalWrite: * Set an output bit @@ -2334,32 +2309,6 @@ void digitalWrite (int pin, int value) } -/* - * digitalWrite8: - * Set an output 8-bit byte on the device from the given pin number - ********************************************************************************* - -void digitalWrite8 (int pin, int value) -{ - struct wiringPiNodeStruct *node = wiringPiNodes ; - - if ((pin & PI_GPIO_MASK) == 0) // On-Board Pin - return ; - else - { - if ((node = wiringPiFindNode (pin)) != NULL) - node->digitalWrite8 (node, pin, value) ; - } -} - */ - - -/* - * pwmWrite: - * Set an output PWM value - ********************************************************************************* - */ - void pwmWrite (int pin, int value) { struct wiringPiNodeStruct *node = wiringPiNodes ; diff --git a/wiringPi/wiringPi.h b/wiringPi/wiringPi.h index f2a4599..dd37943 100644 --- a/wiringPi/wiringPi.h +++ b/wiringPi/wiringPi.h @@ -178,9 +178,7 @@ struct wiringPiNodeStruct void (*pinMode) (struct wiringPiNodeStruct *node, int pin, int mode) ; void (*pullUpDnControl) (struct wiringPiNodeStruct *node, int pin, int mode) ; int (*digitalRead) (struct wiringPiNodeStruct *node, int pin) ; -//unsigned int (*digitalRead8) (struct wiringPiNodeStruct *node, int pin) ; void (*digitalWrite) (struct wiringPiNodeStruct *node, int pin, int value) ; -// void (*digitalWrite8) (struct wiringPiNodeStruct *node, int pin, int value) ; void (*pwmWrite) (struct wiringPiNodeStruct *node, int pin, int value) ; int (*analogRead) (struct wiringPiNodeStruct *node, int pin) ; void (*analogWrite) (struct wiringPiNodeStruct *node, int pin, int value) ; From 044af6cb9a8a35a0b6bdd75e7d8ff558b98a0dcf Mon Sep 17 00:00:00 2001 From: Connor Gibson Date: Thu, 15 May 2025 17:28:24 -0700 Subject: [PATCH 52/65] Fix indentation --- wiringPi/wiringPi.c | 14 +++++++------- wiringPi/wiringPi.h | 36 +++++++++++++++++------------------- 2 files changed, 24 insertions(+), 26 deletions(-) diff --git a/wiringPi/wiringPi.c b/wiringPi/wiringPi.c index bea4084..16c6cf4 100644 --- a/wiringPi/wiringPi.c +++ b/wiringPi/wiringPi.c @@ -1622,13 +1622,13 @@ struct wiringPiNodeStruct *wiringPiFindNode (int pin) ********************************************************************************* */ -static void pinModeDummy (UNU struct wiringPiNodeStruct *node, UNU int pin, UNU int mode) { return ; } -static void pullUpDnControlDummy (UNU struct wiringPiNodeStruct *node, UNU int pin, UNU int pud) { return ; } -static int digitalReadDummy (UNU struct wiringPiNodeStruct *node, UNU int UNU pin) { return LOW ; } -static void digitalWriteDummy (UNU struct wiringPiNodeStruct *node, UNU int pin, UNU int value) { return ; } -static void pwmWriteDummy (UNU struct wiringPiNodeStruct *node, UNU int pin, UNU int value) { return ; } -static int analogReadDummy (UNU struct wiringPiNodeStruct *node, UNU int pin) { return 0 ; } -static void analogWriteDummy (UNU struct wiringPiNodeStruct *node, UNU int pin, UNU int value) { return ; } +static void pinModeDummy (UNU struct wiringPiNodeStruct *node, UNU int pin, UNU int mode) { return ; } +static void pullUpDnControlDummy (UNU struct wiringPiNodeStruct *node, UNU int pin, UNU int pud) { return ; } +static int digitalReadDummy (UNU struct wiringPiNodeStruct *node, UNU int UNU pin) { return LOW ; } +static void digitalWriteDummy (UNU struct wiringPiNodeStruct *node, UNU int pin, UNU int value) { return ; } +static void pwmWriteDummy (UNU struct wiringPiNodeStruct *node, UNU int pin, UNU int value) { return ; } +static int analogReadDummy (UNU struct wiringPiNodeStruct *node, UNU int pin) { return 0 ; } +static void analogWriteDummy (UNU struct wiringPiNodeStruct *node, UNU int pin, UNU int value) { return ; } struct wiringPiNodeStruct *wiringPiNewNode (int pinBase, int numPins) { diff --git a/wiringPi/wiringPi.h b/wiringPi/wiringPi.h index dd37943..d612754 100644 --- a/wiringPi/wiringPi.h +++ b/wiringPi/wiringPi.h @@ -175,13 +175,13 @@ struct wiringPiNodeStruct unsigned int data2 ; // ditto unsigned int data3 ; // ditto - void (*pinMode) (struct wiringPiNodeStruct *node, int pin, int mode) ; - void (*pullUpDnControl) (struct wiringPiNodeStruct *node, int pin, int mode) ; - int (*digitalRead) (struct wiringPiNodeStruct *node, int pin) ; - void (*digitalWrite) (struct wiringPiNodeStruct *node, int pin, int value) ; - void (*pwmWrite) (struct wiringPiNodeStruct *node, int pin, int value) ; - int (*analogRead) (struct wiringPiNodeStruct *node, int pin) ; - void (*analogWrite) (struct wiringPiNodeStruct *node, int pin, int value) ; + void (*pinMode) (struct wiringPiNodeStruct *node, int pin, int mode) ; + void (*pullUpDnControl) (struct wiringPiNodeStruct *node, int pin, int mode) ; + int (*digitalRead) (struct wiringPiNodeStruct *node, int pin) ; + void (*digitalWrite) (struct wiringPiNodeStruct *node, int pin, int value) ; + void (*pwmWrite) (struct wiringPiNodeStruct *node, int pin, int value) ; + int (*analogRead) (struct wiringPiNodeStruct *node, int pin) ; + void (*analogWrite) (struct wiringPiNodeStruct *node, int pin, int value) ; struct wiringPiNodeStruct *next ; } ; @@ -252,18 +252,16 @@ enum WPIPinAlt { }; -extern int wiringPiGpioDeviceGetFd(); //Interface V3.3 -extern void pinModeAlt (int pin, int mode) ; -extern enum WPIPinAlt getPinModeAlt (int pin) ; // Interface V3.5, same as getAlt but wie enum -extern void pinMode (int pin, int mode) ; -extern void pullUpDnControl (int pin, int pud) ; -extern int digitalRead (int pin) ; -extern void digitalWrite (int pin, int value) ; -extern unsigned int digitalRead8 (int pin) ; -extern void digitalWrite8 (int pin, int value) ; -extern void pwmWrite (int pin, int value) ; -extern int analogRead (int pin) ; -extern void analogWrite (int pin, int value) ; +extern int wiringPiGpioDeviceGetFd(); //Interface V3.3 +extern void pinModeAlt (int pin, int mode) ; +extern enum WPIPinAlt getPinModeAlt (int pin) ; // Interface V3.5, same as getAlt but wie enum +extern void pinMode (int pin, int mode) ; +extern void pullUpDnControl (int pin, int pud) ; +extern int digitalRead (int pin) ; +extern void digitalWrite (int pin, int value) ; +extern void pwmWrite (int pin, int value) ; +extern int analogRead (int pin) ; +extern void analogWrite (int pin, int value) ; // PiFace specifics // (Deprecated) From 6c51ad838e460e191c749addd389e4c3fe2b645e Mon Sep 17 00:00:00 2001 From: Connor Gibson Date: Thu, 15 May 2025 17:30:24 -0700 Subject: [PATCH 53/65] [drcNet.c] Remove digitalRead8() and digitalWrite8() comments --- wiringPi/drcNet.c | 40 ---------------------------------------- 1 file changed, 40 deletions(-) diff --git a/wiringPi/drcNet.c b/wiringPi/drcNet.c index 0fc5d2b..88ff655 100644 --- a/wiringPi/drcNet.c +++ b/wiringPi/drcNet.c @@ -253,24 +253,6 @@ static void myDigitalWrite (struct wiringPiNodeStruct *node, int pin, int value) } -/* - * myDigitalWrite8: - ********************************************************************************* - -static void myDigitalWrite8 (struct wiringPiNodeStruct *node, int pin, int value) -{ - struct drcNetComStruct cmd ; - - cmd.pin = pin - node->pinBase ; - cmd.cmd = DRCN_DIGITAL_WRITE8 ; - cmd.data = value ; - - (void)send (node->fd, &cmd, sizeof (cmd), 0) ; - (void)recv (node->fd, &cmd, sizeof (cmd), 0) ; -} - */ - - /* * myAnalogWrite: ********************************************************************************* @@ -347,26 +329,6 @@ static int myDigitalRead (struct wiringPiNodeStruct *node, int pin) } -/* - * myDigitalRead8: - ********************************************************************************* - -static unsigned int myDigitalRead8 (struct wiringPiNodeStruct *node, int pin) -{ - struct drcNetComStruct cmd ; - - cmd.pin = pin - node->pinBase ; - cmd.cmd = DRCN_DIGITAL_READ8 ; - cmd.data = 0 ; - - (void)send (node->fd, &cmd, sizeof (cmd), 0) ; - (void)recv (node->fd, &cmd, sizeof (cmd), 0) ; - - return cmd.data ; -} - */ - - /* * drcNet: * Create a new instance of an DRC GPIO interface. @@ -397,8 +359,6 @@ int drcSetupNet (const int pinBase, const int numPins, const char *ipAddress, co node->analogWrite = myAnalogWrite ; node->digitalRead = myDigitalRead ; node->digitalWrite = myDigitalWrite ; -//node->digitalRead8 = myDigitalRead8 ; -//node->digitalWrite8 = myDigitalWrite8 ; node->pwmWrite = myPwmWrite ; return TRUE ; From 325bf0eccce07bd561c1cbcc33c38c6b43359e84 Mon Sep 17 00:00:00 2001 From: Connor Gibson Date: Thu, 15 May 2025 17:35:00 -0700 Subject: [PATCH 54/65] [runRemote.c] Remove digitalRead8() and digitalWrite8() comments --- wiringPiD/runRemote.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/wiringPiD/runRemote.c b/wiringPiD/runRemote.c index 7c6a5cb..d00ddf2 100644 --- a/wiringPiD/runRemote.c +++ b/wiringPiD/runRemote.c @@ -92,7 +92,6 @@ void runRemoteCommands (int fd) break ; case DRCN_DIGITAL_WRITE8: - //digitalWrite8 (pin, cmd.data) ; if (send (fd, &cmd, sizeof (cmd), 0) != sizeof (cmd)) return ; break ; @@ -104,7 +103,6 @@ void runRemoteCommands (int fd) break ; case DRCN_DIGITAL_READ8: - //cmd.data = digitalRead8 (pin) ; if (send (fd, &cmd, sizeof (cmd), 0) != sizeof (cmd)) return ; break ; From 26b4d8583e9761b38307f3ed4c96ddfa8b416165 Mon Sep 17 00:00:00 2001 From: Manfred Wallner Date: Thu, 5 Jun 2025 13:15:11 +0200 Subject: [PATCH 55/65] (maint) note on ports-support --- README.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 425d52b..46759d6 100644 --- a/README.md +++ b/README.md @@ -145,7 +145,10 @@ sudo apt install ./wiringpi-3.x.deb ## Ports -wiringPi has been wrapped for multiple languages: +wiringPi has been wrapped for multiple languages: + +NOTE: these wrappers are _not_ updated and maintained in sync with WiringPi version 3+, +therefore we cannot guarantee functionality or provide support for a specific implementation. - Node - [https://github.com/WiringPi/WiringPi-Node](https://github.com/WiringPi/WiringPi-Node) - Perl - [https://github.com/WiringPi/WiringPi-Perl](https://github.com/WiringPi/WiringPi-Perl) From 1fdd4f91e9964a2664d1afcf34e6dc85e58deabd Mon Sep 17 00:00:00 2001 From: mstroh Date: Thu, 5 Jun 2025 19:43:39 +0200 Subject: [PATCH 56/65] Update new ISR functions --- documentation/deutsch/functions.md | 85 +++++++++++++++++++----------- 1 file changed, 55 insertions(+), 30 deletions(-) diff --git a/documentation/deutsch/functions.md b/documentation/deutsch/functions.md index 3f92674..75ab285 100644 --- a/documentation/deutsch/functions.md +++ b/documentation/deutsch/functions.md @@ -285,13 +285,39 @@ if (value==HIGH) ## Interrupts -### wiringPiISR +### wiringPiISR (klassische Version) Registriert eine Interrupt Service Routine (ISR) bzw. Funktion die bei Flankenwechsel ausgeführt wird. +Es werden bei dieser klassischen Version keine Parameter and die ISR übergeben. >>> ```C -int wiringPiISR(int pin, int edgeMode, void (*function)(struct WPIWfiStatus wfiStatus), unsigned long bouncetime); +int wiringPiISR(int pin, int mode, void (*function)(void)); +``` + +``pin``: Der gewünschte Pin (BCM-, WiringPi- oder Pin-Nummer). +``mode``: Auslösende Flankenmodus + - INT_EDGE_RISING ... Steigende Flanke + - INT_EDGE_FALLING ... Fallende Flanke + - INT_EDGE_BOTH ... Steigende und fallende Flanke + +``*function``: Funktionspointer für ISR +``Rückgabewert``: + > 0 ... Erfolgreich + + +Beispiel siehe wiringPiISRStop. + + + +### wiringPiISR2 + +Registriert eine Interrupt Service Routine (ISR) bzw. Funktion die bei Flankenwechsel ausgeführt wird. +Es werden erweiterte Parameter an die ISR übergeben. + +>>> +```C +int wiringPiISR2(int pin, int edgeMode, void (*function)(struct WPIWfiStatus wfiStatus, void* userdata), unsigned long debounce_period_us, void* userdata); ``` ``pin``: Der gewünschte Pin (BCM\-, WiringPi\- oder Pin\-Nummer). @@ -301,17 +327,18 @@ int wiringPiISR(int pin, int edgeMode, void (*function)(struct WPIWfiStatus wfiS - INT_EDGE_FALLING ... Fallende Flanke - INT_EDGE_BOTH ... Steigende und fallende Flanke -``*function``: Funktionspointer für ISR mit Rückgabeparameter struct WPIWfiStatus: +``*function``: Funktionspointer für ISR mit Parameter struct WPIWfiStatus und einem Pointer: ```C struct WPIWfiStatus { - int status; // -1: error, 0: timeout, 1: valid values for edge and timeStamp_us - unsigned int gpioPin; // gpio as BCM pin - int edge; // One of INT_EDGE_FALLING or INT_EDGE_RISING - long long int timeStamp_us; // time stamp in microseconds, when interrupt happened + int statusOK; // -1: error (return of 'poll' command), 0: timeout, 1: irq processed, next data values are valid if needed + unsigned int pinBCM; // gpio as BCM pin + int edge; // INT_EDGE_FALLING or INT_EDGE_RISING + long long int timeStamp_us; // time stamp in microseconds }; ``` -``bouncetime``: Entprellzeit in Microsekunden, 0 ms schaltet das Entprellen ab +``debounce_period_us``: Entprellzeit in Microsekunden, 0 ms schaltet das Entprellen ab +``userdata``: Pointer der beim Aufruf der ISR übergeben wird ``Rückgabewert``: > 0 ... Erfolgreich @@ -337,13 +364,18 @@ int wiringPiISRStop (int pin) ### waitForInterrupt +Funktion ist nicht mehr verfügbar, es wird nur noch die ``waitForInterrupt2`` unterstützt! + + +### waitForInterrupt2 + Wartet auf einen Aufruf der Interrupt Service Routine (ISR) mit Timeout und Entprellzeit in Mikrosekunden. Blockiert das Programm bis zum Eintreffen der auslösenden Flanke oder bis zum Ablauf des Timeouts. Diese Funktion sollte nicht verwendet werden. >>> ```C -struct WPIWfiStatus wfiStatus waitForInterrupt (int pin, int edgeMode, int mS, unsigned long bouncetime) +struct WPIWfiStatus wfiStatus waitForInterrupt2(int pin, int edgeMode, int ms, unsigned long debounce_period_us) ``` ``pin``: Der gewünschte Pin (BCM\-, WiringPi\- oder Pin\-Nummer). @@ -356,26 +388,25 @@ struct WPIWfiStatus wfiStatus waitForInterrupt (int pin, int edgeMode, int mS, u ``mS``: Timeout in Milisekunden. - \-1 warten ohne timeout - 0 wartet nicht - - 1...n wartet maximal n mS Millisekunden + - 1...n wartet maximal n Millisekunden -``bouncetime``: Entprellzeit in Microsekunden, 0 schaltet Entprellen ab. +``debounce_period_us``: Entprellzeit in Microsekunden, 0 schaltet Entprellen ab. ``Rückgabewert``: ```C struct WPIWfiStatus { - int status; // -1: error, 0: timeout, 1: valid values for edge and timeStamp_us - unsigned int gpioPin; // gpio as BCM pin - int edge; // One of INT_EDGE_FALLING or INT_EDGE_RISING - long long int timeStamp_us; // time stamp in microseconds, when interrupt happened + int statusOK; // -1: error (return of 'poll' command), 0: timeout, 1: irq processed, next data values are valid if needed + unsigned int pinBCM; // gpio as BCM pin + int edge; // INT_EDGE_FALLING or INT_EDGE_RISING + long long int timeStamp_us; // time stamp in microseconds }; ``` -**Beispiel:** - +### Beispiel ```C /* * isr_debounce.c: - * Wait for Interrupt test program WiringPi >=3.16 - ISR method + * Wait for Interrupt test program WiringPi >=3.16 - ISR2 method * * */ @@ -386,7 +417,6 @@ struct WPIWfiStatus { #include #include #include - #include #define BOUNCETIME 3000 // microseconds @@ -402,12 +432,7 @@ struct WPIWfiStatus { int toggle = 0; -/* - * myInterrupt: - ********************************************************************************* - */ - -static void wfi (struct WPIWfiStatus wfiStatus) { +static void wfi(struct WPIWfiStatus wfiStatus, void* userdata) { // struct timeval now; long long int timenow, diff; struct timespec curr; @@ -457,7 +482,7 @@ int main (void) digitalWrite (OUTpin, LOW) ; printf("Testing waitForInterrupt on both edges IRQ @ GPIO%d, timeout is %d\n", IRQpin, TIMEOUT); - struct WPIWfiStatus wfiStatus = waitForInterrupt(IRQpin, INT_EDGE_BOTH, TIMEOUT, BOUNCETIME_WFI ); + struct WPIWfiStatus wfiStatus = waitForInterrupt2(IRQpin, INT_EDGE_BOTH, TIMEOUT, BOUNCETIME_WFI); if (wfiStatus.status < 0) { printf("waitForInterrupt returned error\n"); pinMode(OUTpin, INPUT); @@ -473,10 +498,10 @@ int main (void) printf("waitForInterrupt: GPIO pin %d rising edge fired at %lld microseconds\n\n", wfiStatus.gpioPin, wfiStatus.timeStamp_us); } - printf("Testing IRQ @ GPIO%d with trigger @ GPIO%d on both edges and bouncetime %d microseconds. Toggle LED @ OUTpin on IRQ.\n\n", IRQpin, IRQpin, BOUNCETIME, OUTpin); + printf("Testing IRQ @ GPIO%d on both edges and bouncetime %d microseconds. Toggle LED @ GPIO%d on IRQ.\n\n", IRQpin, BOUNCETIME, OUTpin); printf("To stop program hit return key\n\n"); - wiringPiISR (IRQpin, INT_EDGE_BOTH, &wfi, BOUNCETIME) ; + wiringPiISR2(IRQpin, INT_EDGE_BOTH, &wfi, BOUNCETIME, NULL) ; getc(stdin); @@ -487,7 +512,7 @@ int main (void) } ``` -Output auf dem Terminal: +Augabe am Terminal: ``` pi@RaspberryPi:~/wiringpi-test-v3.16 $ gcc -o isr_debounce isr_debounce.c -l wiringPi @@ -498,7 +523,7 @@ ISR debounce test (WiringPi 3.16) Testing waitForInterrupt on both edges IRQ @ GPIO16, timeout is 10000 waitForInterrupt: GPIO pin 16 falling edge fired at 256522528012 microseconds -Testing IRQ @ GPIO16 with trigger @ GPIO16 on both edges and bouncetime 3000 microseconds. Toggle LED @ OUTpin on IRQ. +Testing IRQ @ GPIO16 on both edges and bouncetime 3000 microseconds. Toggle LED @ GPIO12 on IRQ. To stop program hit return key From e4ade1840d461d526aef5772df6cc6a20bdf1b67 Mon Sep 17 00:00:00 2001 From: mstroh Date: Thu, 5 Jun 2025 19:46:47 +0200 Subject: [PATCH 57/65] Update functions.md --- documentation/deutsch/functions.md | 5 ----- 1 file changed, 5 deletions(-) diff --git a/documentation/deutsch/functions.md b/documentation/deutsch/functions.md index 75ab285..b293e3b 100644 --- a/documentation/deutsch/functions.md +++ b/documentation/deutsch/functions.md @@ -306,9 +306,6 @@ int wiringPiISR(int pin, int mode, void (*function)(void)); > 0 ... Erfolgreich -Beispiel siehe wiringPiISRStop. - - ### wiringPiISR2 @@ -344,8 +341,6 @@ struct WPIWfiStatus { > 0 ... Erfolgreich -Beispiel siehe waitForInterrupt. - ### wiringPiISRStop From 9cf2d3e5d05b3a34768e34445b69cb55ee4056ba Mon Sep 17 00:00:00 2001 From: mstroh Date: Thu, 5 Jun 2025 20:10:56 +0200 Subject: [PATCH 58/65] Update functions.md --- documentation/deutsch/functions.md | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/documentation/deutsch/functions.md b/documentation/deutsch/functions.md index b293e3b..512d005 100644 --- a/documentation/deutsch/functions.md +++ b/documentation/deutsch/functions.md @@ -125,10 +125,8 @@ mehr benutzt werden! **Ab Version 3.4:** ``wiringPiSetupPinType`` entscheidet ob nun WiringPi, BCM oder physische Pin-Nummerierung verwendet wird, anhand des Parameters pinType. Es führt also die ersten 3 Setup-Funktionen auf eine zusammen. -``wiringPiSetupGpioDevice`` ist der Nachfolger der ``wiringPiSetupSys`` Funktion und verwendet nun "GPIO Character Device Userspace API" in Version 1 (ab Kernel 5.10 verfügbar). Nähere Informationen findet man bei https://docs.kernel.org/driver-api/gpio/driver.html. Anhand des Parameters pinType wird wieder entschieden, welche Pin-Nummerierung verwendet wird. -Bei dieser Variante wird nicht direkt auf den GPIO-Speicher (DMA) zugegriffen sondern über eine Kernel Schnittstelle, die mit Benutzerrechten verfügbar ist. Nachteil ist der eingeschrenkte Funktionsumfang und die niedrige Performance. - - +``wiringPiSetupGpioDevice`` ist der Nachfolger der ``wiringPiSetupSys`` Funktion und verwendet nun "GPIO Character Device Userspace API" ab WiringPi Version 3.16 in Version 2 (ab Kernel 5.10 verfügbar). Nähere Informationen findet man bei https://docs.kernel.org/driver-api/gpio/driver.html. Anhand des Parameters pinType wird wieder entschieden, welche Pin-Nummerierung verwendet wird. +Bei dieser Variante wird nicht direkt auf den GPIO-Speicher (DMA) zugegriffen sondern über eine Kernel Schnittstelle, die mit Benutzerrechten verfügbar ist. Nachteil ist der eingeschränkte Funktionsumfang und die niedrige Performance. ### wiringPiSetup V2 (veraltet) From 99242653478c295cb4f9a704ceaad4171d81e5f1 Mon Sep 17 00:00:00 2001 From: mstroh Date: Thu, 5 Jun 2025 20:15:08 +0200 Subject: [PATCH 59/65] GPIO Character Device Userspace API Version 2 --- documentation/deutsch/functions.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/documentation/deutsch/functions.md b/documentation/deutsch/functions.md index 512d005..7052a93 100644 --- a/documentation/deutsch/functions.md +++ b/documentation/deutsch/functions.md @@ -125,7 +125,7 @@ mehr benutzt werden! **Ab Version 3.4:** ``wiringPiSetupPinType`` entscheidet ob nun WiringPi, BCM oder physische Pin-Nummerierung verwendet wird, anhand des Parameters pinType. Es führt also die ersten 3 Setup-Funktionen auf eine zusammen. -``wiringPiSetupGpioDevice`` ist der Nachfolger der ``wiringPiSetupSys`` Funktion und verwendet nun "GPIO Character Device Userspace API" ab WiringPi Version 3.16 in Version 2 (ab Kernel 5.10 verfügbar). Nähere Informationen findet man bei https://docs.kernel.org/driver-api/gpio/driver.html. Anhand des Parameters pinType wird wieder entschieden, welche Pin-Nummerierung verwendet wird. +``wiringPiSetupGpioDevice`` ist der Nachfolger der ``wiringPiSetupSys`` Funktion und verwendet nun "GPIO Character Device Userspace API" in Version 2 (ab WiringPi Version 3.16). Nähere Informationen findet man bei https://docs.kernel.org/driver-api/gpio/driver.html. Anhand des Parameters pinType wird wieder entschieden, welche Pin-Nummerierung verwendet wird. Bei dieser Variante wird nicht direkt auf den GPIO-Speicher (DMA) zugegriffen sondern über eine Kernel Schnittstelle, die mit Benutzerrechten verfügbar ist. Nachteil ist der eingeschränkte Funktionsumfang und die niedrige Performance. From b86be0969d56560a9d492b68d6bae0e5db70d8ea Mon Sep 17 00:00:00 2001 From: Connor Gibson Date: Fri, 30 May 2025 13:40:01 -0700 Subject: [PATCH 60/65] Remove extra indents before `if` followed by `if else` This was driving clangd crazy - replaced with indents between the if and conditional parentheses in most places. --- devLib/lcd128x64.c | 2 +- devLib/piGlow.c | 18 ++++-------- devLib/scrollPhat.c | 26 +++++++++-------- examples/Gertboard/7segments.c | 2 +- examples/PiGlow/piglow.c | 4 +-- examples/ds1302.c | 2 +- examples/scrollPhat/scphat.c | 2 +- gpio/gpio.c | 12 ++++---- gpio/readall.c | 6 ++-- wiringPi/ads1115.c | 2 +- wiringPi/bmp180.c | 2 +- wiringPi/drcSerial.c | 4 +-- wiringPi/htu21d.c | 2 +- wiringPi/softPwm.c | 6 ++-- wiringPi/softServo.c | 2 +- wiringPi/softTone.c | 2 +- wiringPi/wiringPi.c | 52 +++++++++++++++++----------------- 17 files changed, 70 insertions(+), 76 deletions(-) diff --git a/devLib/lcd128x64.c b/devLib/lcd128x64.c index e370488..272d6f8 100644 --- a/devLib/lcd128x64.c +++ b/devLib/lcd128x64.c @@ -370,7 +370,7 @@ void lcd128x64rectangle (int x1, int y1, int x2, int y2, int colour, int filled) if (filled) { - /**/ if (x1 == x2) + if (x1 == x2) lcd128x64line (x1, y1, x2, y2, colour) ; else if (x1 < x2) for (x = x1 ; x <= x2 ; ++x) diff --git a/devLib/piGlow.c b/devLib/piGlow.c index 7f1db7c..ebee3c4 100644 --- a/devLib/piGlow.c +++ b/devLib/piGlow.c @@ -47,12 +47,9 @@ void piGlow1 (const int leg, const int ring, const int intensity) if ((leg < 0) || (leg > 2)) return ; if ((ring < 0) || (ring > 5)) return ; - /**/ if (leg == 0) - legLeds = leg0 ; - else if (leg == 1) - legLeds = leg1 ; - else - legLeds = leg2 ; + if (leg == 0) { legLeds = leg0 ; } + else if (leg == 1) { legLeds = leg1 ; } + else { legLeds = leg2 ; } analogWrite (PIGLOW_BASE + legLeds [ring], intensity) ; } @@ -71,12 +68,9 @@ void piGlowLeg (const int leg, const int intensity) if ((leg < 0) || (leg > 2)) return ; - /**/ if (leg == 0) - legLeds = leg0 ; - else if (leg == 1) - legLeds = leg1 ; - else - legLeds = leg2 ; + if (leg == 0) { legLeds = leg0 ; } + else if (leg == 1) { legLeds = leg1 ; } + else { legLeds = leg2 ; } for (i = 0 ; i < 6 ; ++i) analogWrite (PIGLOW_BASE + legLeds [i], intensity) ; diff --git a/devLib/scrollPhat.c b/devLib/scrollPhat.c index d12666c..ca9a8b2 100644 --- a/devLib/scrollPhat.c +++ b/devLib/scrollPhat.c @@ -210,19 +210,21 @@ void scrollPhatRectangle (int x1, int y1, int x2, int y2, int colour, int filled { register int x ; - if (filled) - { - /**/ if (x1 == x2) + if (filled) { + if (x1 == x2) { scrollPhatLine (x1, y1, x2, y2, colour) ; - else if (x1 < x2) - for (x = x1 ; x <= x2 ; ++x) - scrollPhatLine (x, y1, x, y2, colour) ; - else - for (x = x2 ; x <= x1 ; ++x) - scrollPhatLine (x, y1, x, y2, colour) ; - } - else - { + } + else if (x1 < x2) { + for (x = x1 ; x <= x2 ; ++x) { + scrollPhatLine (x, y1, x, y2, colour) ; + } + } + else { + for (x = x2 ; x <= x1 ; ++x) { + scrollPhatLine (x, y1, x, y2, colour) ; + } + } + } else { scrollPhatLine (x1, y1, x2, y1, colour) ; scrollPhatLineTo (x2, y2, colour) ; scrollPhatLineTo (x1, y2, colour) ; diff --git a/examples/Gertboard/7segments.c b/examples/Gertboard/7segments.c index 8797e49..b477a5d 100644 --- a/examples/Gertboard/7segments.c +++ b/examples/Gertboard/7segments.c @@ -91,7 +91,7 @@ PI_THREAD (displayDigits) for (segment = 0 ; segment < 7 ; ++segment) { d = toupper (display [digit]) ; - /**/ if ((d >= '0') && (d <= '9')) // Digit + if ((d >= '0') && (d <= '9')) // Digit index = d - '0' ; else if ((d >= 'A') && (d <= 'F')) // Hex index = d - 'A' + 10 ; diff --git a/examples/PiGlow/piglow.c b/examples/PiGlow/piglow.c index be5a5e0..b83be61 100644 --- a/examples/PiGlow/piglow.c +++ b/examples/PiGlow/piglow.c @@ -97,7 +97,7 @@ int main (int argc, char *argv []) { percent = getPercent (argv [2]) ; - /**/ if (strcasecmp (argv [1], "red") == 0) + if (strcasecmp (argv [1], "red") == 0) piGlowRing (PIGLOW_RED, percent) ; else if (strcasecmp (argv [1], "yellow") == 0) piGlowRing (PIGLOW_YELLOW, percent) ; @@ -122,7 +122,7 @@ int main (int argc, char *argv []) if (argc == 4) { - /**/ if (strcasecmp (argv [1], "leg") == 0) + if (strcasecmp (argv [1], "leg") == 0) { leg = atoi (argv [2]) ; if ((leg < 0) || (leg > 2)) diff --git a/examples/ds1302.c b/examples/ds1302.c index 025e79b..fec690b 100644 --- a/examples/ds1302.c +++ b/examples/ds1302.c @@ -205,7 +205,7 @@ int main (int argc, char *argv []) if (argc == 2) { - /**/ if (strcmp (argv [1], "-slc") == 0) + if (strcmp (argv [1], "-slc") == 0) return setLinuxClock () ; else if (strcmp (argv [1], "-sdsc") == 0) return setDSclock () ; diff --git a/examples/scrollPhat/scphat.c b/examples/scrollPhat/scphat.c index cba6c0f..23abcb0 100644 --- a/examples/scrollPhat/scphat.c +++ b/examples/scrollPhat/scphat.c @@ -209,7 +209,7 @@ int main (int argc, char *argv []) while (arg != argc) { command = argv [arg] ; - /**/ if (strcasecmp (command, "clear") == 0) arg += doClear () ; + if (strcasecmp (command, "clear") == 0) arg += doClear () ; else if (strcasecmp (command, "cls") == 0) arg += doClear () ; else if (strcasecmp (command, "bright") == 0) arg += doBright (arg, argc, argv) ; else if (strcasecmp (command, "plot") == 0) arg += doPlot (arg, argc, argv) ; diff --git a/gpio/gpio.c b/gpio/gpio.c index 8644c4a..b5f0182 100644 --- a/gpio/gpio.c +++ b/gpio/gpio.c @@ -370,7 +370,7 @@ void doMode (int argc, char *argv []) mode = argv [3] ; - /**/ if (strcasecmp (mode, "in") == 0) pinMode (pin, INPUT) ; + if (strcasecmp (mode, "in") == 0) pinMode (pin, INPUT) ; else if (strcasecmp (mode, "input") == 0) pinMode (pin, INPUT) ; else if (strcasecmp (mode, "out") == 0) pinMode (pin, OUTPUT) ; else if (strcasecmp (mode, "output") == 0) pinMode (pin, OUTPUT) ; @@ -602,14 +602,14 @@ static void doWrite (int argc, char *argv []) pin = atoi (argv [2]) ; - /**/ if ((strcasecmp (argv [3], "up") == 0) || (strcasecmp (argv [3], "on") == 0)) + if ((strcasecmp (argv [3], "up") == 0) || (strcasecmp (argv [3], "on") == 0)) val = 1 ; else if ((strcasecmp (argv [3], "down") == 0) || (strcasecmp (argv [3], "off") == 0)) val = 0 ; else val = atoi (argv [3]) ; - /**/ if (val == 0) + if (val == 0) digitalWrite (pin, LOW) ; else digitalWrite (pin, HIGH) ; @@ -1063,7 +1063,7 @@ int main (int argc, char *argv []) // Initial test for /sys/class/gpio operations: --> deprecated, empty but still there - /**/ if (strcasecmp (argv [1], "exports" ) == 0) { SYSFS_DEPRECATED(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 ; } @@ -1094,7 +1094,7 @@ int main (int argc, char *argv []) // Check for -g argument - /**/ if (strcasecmp (argv [1], "-g") == 0) + if (strcasecmp (argv [1], "-g") == 0) { wiringPiSetupGpio () ; @@ -1180,7 +1180,7 @@ int main (int argc, char *argv []) // Core wiringPi functions - /**/ if (strcasecmp (argv [1], "mode" ) == 0) doMode (argc, argv) ; + if (strcasecmp (argv [1], "mode" ) == 0) doMode (argc, argv) ; else if (strcasecmp (argv [1], "read" ) == 0) doRead (argc, argv) ; else if (strcasecmp (argv [1], "write" ) == 0) doWrite (argc, argv) ; else if (strcasecmp (argv [1], "pwm" ) == 0) doPwm (argc, argv) ; diff --git a/gpio/readall.c b/gpio/readall.c index cf0caf4..6e2aa18 100644 --- a/gpio/readall.c +++ b/gpio/readall.c @@ -183,7 +183,7 @@ static void readallPhys (int physPin) printf (" | | ") ; else { - /**/ if (wpMode == WPI_MODE_GPIO) + if (wpMode == WPI_MODE_GPIO) pin = physPinToGpio (physPin) ; else if (wpMode == WPI_MODE_PHYS) pin = physPin ; @@ -206,7 +206,7 @@ static void readallPhys (int physPin) printf (" | | ") ; else { - /**/ if (wpMode == WPI_MODE_GPIO) + if (wpMode == WPI_MODE_GPIO) pin = physPinToGpio (physPin) ; else if (wpMode == WPI_MODE_PHYS) pin = physPin ; @@ -380,7 +380,7 @@ void doReadall (void) piBoardId (&model, &rev, &mem, &maker, &overVolted) ; - /**/ if ((model == PI_MODEL_A) || (model == PI_MODEL_B)) + if ((model == PI_MODEL_A) || (model == PI_MODEL_B)) abReadall (model, rev) ; else if ((model == PI_MODEL_BP) || (model == PI_MODEL_AP) || (model == PI_MODEL_2) || diff --git a/wiringPi/ads1115.c b/wiringPi/ads1115.c index 94ac22a..44e53cb 100644 --- a/wiringPi/ads1115.c +++ b/wiringPi/ads1115.c @@ -252,7 +252,7 @@ static void myAnalogWrite (struct wiringPiNodeStruct *node, int pin, int data) reg = chan + 2 ; - /**/ if (data < -32767) + if (data < -32767) ndata = -32767 ; else if (data > 32767) ndata = 32767 ; diff --git a/wiringPi/bmp180.c b/wiringPi/bmp180.c index c273ff3..bf6c209 100644 --- a/wiringPi/bmp180.c +++ b/wiringPi/bmp180.c @@ -164,7 +164,7 @@ static int myAnalogRead (struct wiringPiNodeStruct *node, int pin) bmp180ReadTempPress (node->fd) ; - /**/ if (chan == 0) // Read Temperature + if (chan == 0) // Read Temperature return cTemp ; else if (chan == 1) // Pressure return cPress ; diff --git a/wiringPi/drcSerial.c b/wiringPi/drcSerial.c index c5cb2b1..6ffc2b1 100644 --- a/wiringPi/drcSerial.c +++ b/wiringPi/drcSerial.c @@ -41,7 +41,7 @@ static void myPinMode (struct wiringPiNodeStruct *node, int pin, int mode) { - /**/ if (mode == OUTPUT) + if (mode == OUTPUT) serialPutchar (node->fd, 'o') ; // Input else if (mode == PWM_OUTPUT) serialPutchar (node->fd, 'p') ; // PWM @@ -66,7 +66,7 @@ static void myPullUpDnControl (struct wiringPiNodeStruct *node, int pin, int mod serialPutchar (node->fd, 'i' ) ; serialPutchar (node->fd, pin - node->pinBase) ; - /**/ if (mode == PUD_UP) + if (mode == PUD_UP) { serialPutchar (node->fd, '1') ; serialPutchar (node->fd, pin - node->pinBase) ; diff --git a/wiringPi/htu21d.c b/wiringPi/htu21d.c index d47f4de..11f20eb 100644 --- a/wiringPi/htu21d.c +++ b/wiringPi/htu21d.c @@ -59,7 +59,7 @@ static int myAnalogRead (struct wiringPiNodeStruct *node, int pin) double fTemp, fHumid ; int cTemp, cHumid ; - /**/ if (chan == 0) // Read Temperature + if (chan == 0) // Read Temperature { // Send read temperature command: diff --git a/wiringPi/softPwm.c b/wiringPi/softPwm.c index 6dccb05..3f2f42b 100644 --- a/wiringPi/softPwm.c +++ b/wiringPi/softPwm.c @@ -108,10 +108,8 @@ void softPwmWrite (int pin, int value) { if (pin < MAX_PINS) { - /**/ if (value < 0) - value = 0 ; - else if (value > range [pin]) - value = range [pin] ; + if (value < 0) { value = 0 ; } + else if (value > range [pin]) { value = range [pin] ; } marks [pin] = value ; } diff --git a/wiringPi/softServo.c b/wiringPi/softServo.c index f7381cc..2768fdc 100644 --- a/wiringPi/softServo.c +++ b/wiringPi/softServo.c @@ -165,7 +165,7 @@ void softServoWrite (int servoPin, int value) servoPin &= 63 ; - /**/ if (value < -250) + if (value < -250) value = -250 ; else if (value > 1250) value = 1250 ; diff --git a/wiringPi/softTone.c b/wiringPi/softTone.c index 0515336..cae0a96 100644 --- a/wiringPi/softTone.c +++ b/wiringPi/softTone.c @@ -92,7 +92,7 @@ void softToneWrite (int pin, int freq) { pin &= 63 ; - /**/ if (freq < 0) + if (freq < 0) freq = 0 ; else if (freq > 5000) // Max 5KHz freq = 5000 ; diff --git a/wiringPi/wiringPi.c b/wiringPi/wiringPi.c index 3f3d2f8..5bbe5b3 100644 --- a/wiringPi/wiringPi.c +++ b/wiringPi/wiringPi.c @@ -1217,37 +1217,37 @@ void piBoardId (int *model, int *rev, int *mem, int *maker, int *warranty) // Fill out the replys as appropriate RaspberryPiLayout = GPIO_LAYOUT_DEFAULT ; //default - /**/ if (strcmp (c, "0002") == 0) { *model = PI_MODEL_B ; *rev = PI_VERSION_1 ; *mem = 0 ; *maker = PI_MAKER_EGOMAN ; RaspberryPiLayout = GPIO_LAYOUT_PI1_REV1; } - else if (strcmp (c, "0003") == 0) { *model = PI_MODEL_B ; *rev = PI_VERSION_1_1 ; *mem = 0 ; *maker = PI_MAKER_EGOMAN ; RaspberryPiLayout = GPIO_LAYOUT_PI1_REV1; } + if (strcmp (c, "0002") == 0) { *model = PI_MODEL_B ; *rev = PI_VERSION_1 ; *mem = 0 ; *maker = PI_MAKER_EGOMAN ; RaspberryPiLayout = GPIO_LAYOUT_PI1_REV1; } + else if (strcmp (c, "0003") == 0) { *model = PI_MODEL_B ; *rev = PI_VERSION_1_1 ; *mem = 0 ; *maker = PI_MAKER_EGOMAN ; RaspberryPiLayout = GPIO_LAYOUT_PI1_REV1; } - else if (strcmp (c, "0004") == 0) { *model = PI_MODEL_B ; *rev = PI_VERSION_1_2 ; *mem = 0 ; *maker = PI_MAKER_SONY ; } - else if (strcmp (c, "0005") == 0) { *model = PI_MODEL_B ; *rev = PI_VERSION_1_2 ; *mem = 0 ; *maker = PI_MAKER_EGOMAN ; } - else if (strcmp (c, "0006") == 0) { *model = PI_MODEL_B ; *rev = PI_VERSION_1_2 ; *mem = 0 ; *maker = PI_MAKER_EGOMAN ; } + else if (strcmp (c, "0004") == 0) { *model = PI_MODEL_B ; *rev = PI_VERSION_1_2 ; *mem = 0 ; *maker = PI_MAKER_SONY ; } + else if (strcmp (c, "0005") == 0) { *model = PI_MODEL_B ; *rev = PI_VERSION_1_2 ; *mem = 0 ; *maker = PI_MAKER_EGOMAN ; } + else if (strcmp (c, "0006") == 0) { *model = PI_MODEL_B ; *rev = PI_VERSION_1_2 ; *mem = 0 ; *maker = PI_MAKER_EGOMAN ; } - else if (strcmp (c, "0007") == 0) { *model = PI_MODEL_A ; *rev = PI_VERSION_1_2 ; *mem = 0 ; *maker = PI_MAKER_EGOMAN ; } - else if (strcmp (c, "0008") == 0) { *model = PI_MODEL_A ; *rev = PI_VERSION_1_2 ; *mem = 0 ; *maker = PI_MAKER_SONY ; ; } - else if (strcmp (c, "0009") == 0) { *model = PI_MODEL_A ; *rev = PI_VERSION_1_2 ; *mem = 0 ; *maker = PI_MAKER_EGOMAN ; } + else if (strcmp (c, "0007") == 0) { *model = PI_MODEL_A ; *rev = PI_VERSION_1_2 ; *mem = 0 ; *maker = PI_MAKER_EGOMAN ; } + else if (strcmp (c, "0008") == 0) { *model = PI_MODEL_A ; *rev = PI_VERSION_1_2 ; *mem = 0 ; *maker = PI_MAKER_SONY ; } + else if (strcmp (c, "0009") == 0) { *model = PI_MODEL_A ; *rev = PI_VERSION_1_2 ; *mem = 0 ; *maker = PI_MAKER_EGOMAN ; } - else if (strcmp (c, "000d") == 0) { *model = PI_MODEL_B ; *rev = PI_VERSION_1_2 ; *mem = 1 ; *maker = PI_MAKER_EGOMAN ; } - else if (strcmp (c, "000e") == 0) { *model = PI_MODEL_B ; *rev = PI_VERSION_1_2 ; *mem = 1 ; *maker = PI_MAKER_SONY ; } - else if (strcmp (c, "000f") == 0) { *model = PI_MODEL_B ; *rev = PI_VERSION_1_2 ; *mem = 1 ; *maker = PI_MAKER_EGOMAN ; } + else if (strcmp (c, "000d") == 0) { *model = PI_MODEL_B ; *rev = PI_VERSION_1_2 ; *mem = 1 ; *maker = PI_MAKER_EGOMAN ; } + else if (strcmp (c, "000e") == 0) { *model = PI_MODEL_B ; *rev = PI_VERSION_1_2 ; *mem = 1 ; *maker = PI_MAKER_SONY ; } + else if (strcmp (c, "000f") == 0) { *model = PI_MODEL_B ; *rev = PI_VERSION_1_2 ; *mem = 1 ; *maker = PI_MAKER_EGOMAN ; } - else if (strcmp (c, "0010") == 0) { *model = PI_MODEL_BP ; *rev = PI_VERSION_1_2 ; *mem = 1 ; *maker = PI_MAKER_SONY ; } - else if (strcmp (c, "0013") == 0) { *model = PI_MODEL_BP ; *rev = PI_VERSION_1_2 ; *mem = 1 ; *maker = PI_MAKER_EMBEST ; } - else if (strcmp (c, "0016") == 0) { *model = PI_MODEL_BP ; *rev = PI_VERSION_1_2 ; *mem = 1 ; *maker = PI_MAKER_SONY ; } - else if (strcmp (c, "0019") == 0) { *model = PI_MODEL_BP ; *rev = PI_VERSION_1_2 ; *mem = 1 ; *maker = PI_MAKER_EGOMAN ; } + else if (strcmp (c, "0010") == 0) { *model = PI_MODEL_BP ; *rev = PI_VERSION_1_2 ; *mem = 1 ; *maker = PI_MAKER_SONY ; } + else if (strcmp (c, "0013") == 0) { *model = PI_MODEL_BP ; *rev = PI_VERSION_1_2 ; *mem = 1 ; *maker = PI_MAKER_EMBEST ; } + else if (strcmp (c, "0016") == 0) { *model = PI_MODEL_BP ; *rev = PI_VERSION_1_2 ; *mem = 1 ; *maker = PI_MAKER_SONY ; } + else if (strcmp (c, "0019") == 0) { *model = PI_MODEL_BP ; *rev = PI_VERSION_1_2 ; *mem = 1 ; *maker = PI_MAKER_EGOMAN ; } - else if (strcmp (c, "0011") == 0) { *model = PI_MODEL_CM ; *rev = PI_VERSION_1_1 ; *mem = 1 ; *maker = PI_MAKER_SONY ; } - else if (strcmp (c, "0014") == 0) { *model = PI_MODEL_CM ; *rev = PI_VERSION_1_1 ; *mem = 1 ; *maker = PI_MAKER_EMBEST ; } - else if (strcmp (c, "0017") == 0) { *model = PI_MODEL_CM ; *rev = PI_VERSION_1_1 ; *mem = 1 ; *maker = PI_MAKER_SONY ; } - else if (strcmp (c, "001a") == 0) { *model = PI_MODEL_CM ; *rev = PI_VERSION_1_1 ; *mem = 1 ; *maker = PI_MAKER_EGOMAN ; } + else if (strcmp (c, "0011") == 0) { *model = PI_MODEL_CM ; *rev = PI_VERSION_1_1 ; *mem = 1 ; *maker = PI_MAKER_SONY ; } + else if (strcmp (c, "0014") == 0) { *model = PI_MODEL_CM ; *rev = PI_VERSION_1_1 ; *mem = 1 ; *maker = PI_MAKER_EMBEST ; } + else if (strcmp (c, "0017") == 0) { *model = PI_MODEL_CM ; *rev = PI_VERSION_1_1 ; *mem = 1 ; *maker = PI_MAKER_SONY ; } + else if (strcmp (c, "001a") == 0) { *model = PI_MODEL_CM ; *rev = PI_VERSION_1_1 ; *mem = 1 ; *maker = PI_MAKER_EGOMAN ; } - else if (strcmp (c, "0012") == 0) { *model = PI_MODEL_AP ; *rev = PI_VERSION_1_1 ; *mem = 0 ; *maker = PI_MAKER_SONY ; } - else if (strcmp (c, "0015") == 0) { *model = PI_MODEL_AP ; *rev = PI_VERSION_1_1 ; *mem = 1 ; *maker = PI_MAKER_EMBEST ; } - else if (strcmp (c, "0018") == 0) { *model = PI_MODEL_AP ; *rev = PI_VERSION_1_1 ; *mem = 0 ; *maker = PI_MAKER_SONY ; } - else if (strcmp (c, "001b") == 0) { *model = PI_MODEL_AP ; *rev = PI_VERSION_1_1 ; *mem = 0 ; *maker = PI_MAKER_EGOMAN ; } + else if (strcmp (c, "0012") == 0) { *model = PI_MODEL_AP ; *rev = PI_VERSION_1_1 ; *mem = 0 ; *maker = PI_MAKER_SONY ; } + else if (strcmp (c, "0015") == 0) { *model = PI_MODEL_AP ; *rev = PI_VERSION_1_1 ; *mem = 1 ; *maker = PI_MAKER_EMBEST ; } + else if (strcmp (c, "0018") == 0) { *model = PI_MODEL_AP ; *rev = PI_VERSION_1_1 ; *mem = 0 ; *maker = PI_MAKER_SONY ; } + else if (strcmp (c, "001b") == 0) { *model = PI_MODEL_AP ; *rev = PI_VERSION_1_1 ; *mem = 0 ; *maker = PI_MAKER_EGOMAN ; } - else { *model = 0 ; *rev = 0 ; *mem = 0 ; *maker = 0 ; } + else { *model = 0 ; *rev = 0 ; *mem = 0 ; *maker = 0 ; } } RaspberryPiModel = *model; @@ -3197,7 +3197,7 @@ void delayMicroseconds (unsigned int us) unsigned int uSecs = us % 1000000 ; unsigned int wSecs = us / 1000000 ; - /**/ if (us == 0) + if (us == 0) return ; else if (us < 100) delayMicrosecondsHard (us) ; @@ -3449,7 +3449,7 @@ int wiringPiSetup (void) else wiringPiMode = WPI_MODE_PINS ; - /**/ if (piGpioLayout () == GPIO_LAYOUT_PI1_REV1) // A, B, Rev 1, 1.1 + if (piGpioLayout () == GPIO_LAYOUT_PI1_REV1) // A, B, Rev 1, 1.1 { pinToGpio = pinToGpioR1 ; physToGpio = physToGpioR1 ; From 30cbdf9373f9b7ad17d7b2250cf004a608ab4a26 Mon Sep 17 00:00:00 2001 From: mstroh76 Date: Fri, 6 Jun 2025 18:29:56 +0200 Subject: [PATCH 61/65] #363 v3.16 ISR docu english / deutsch --- documentation/deutsch/functions.md | 106 ++++++++------ documentation/english/functions.md | 223 ++++++++++++++++++++++++++--- 2 files changed, 271 insertions(+), 58 deletions(-) diff --git a/documentation/deutsch/functions.md b/documentation/deutsch/functions.md index 7052a93..83f6f82 100644 --- a/documentation/deutsch/functions.md +++ b/documentation/deutsch/functions.md @@ -283,7 +283,7 @@ if (value==HIGH) ## Interrupts -### wiringPiISR (klassische Version) +### wiringPiISR Registriert eine Interrupt Service Routine (ISR) bzw. Funktion die bei Flankenwechsel ausgeführt wird. Es werden bei dieser klassischen Version keine Parameter and die ISR übergeben. @@ -304,6 +304,7 @@ int wiringPiISR(int pin, int mode, void (*function)(void)); > 0 ... Erfolgreich +Beispiel siehe [wiringPiISRStop](#wiringPiISRStop). ### wiringPiISR2 @@ -317,28 +318,30 @@ int wiringPiISR2(int pin, int edgeMode, void (*function)(struct WPIWfiStatus wfi ``pin``: Der gewünschte Pin (BCM\-, WiringPi\- oder Pin\-Nummer). -``edgeMode``: Auslösende Flankenmodus +``edgeMode``: Auslösender Flankenmodus + - INT_EDGE_RISING ... Steigende Flanke - INT_EDGE_FALLING ... Fallende Flanke - INT_EDGE_BOTH ... Steigende und fallende Flanke ``*function``: Funktionspointer für ISR mit Parameter struct WPIWfiStatus und einem Pointer: -```C +```C struct WPIWfiStatus { int statusOK; // -1: error (return of 'poll' command), 0: timeout, 1: irq processed, next data values are valid if needed unsigned int pinBCM; // gpio as BCM pin int edge; // INT_EDGE_FALLING or INT_EDGE_RISING long long int timeStamp_us; // time stamp in microseconds }; -``` +``` -``debounce_period_us``: Entprellzeit in Microsekunden, 0 ms schaltet das Entprellen ab +``debounce_period_us``: Entprellzeit in Microsekunden, 0 schaltet das Entprellen ab ``userdata``: Pointer der beim Aufruf der ISR übergeben wird ``Rückgabewert``: > 0 ... Erfolgreich + Beispiel siehe [waitForInterrupt2](#waitForInterrupt2). ### wiringPiISRStop @@ -346,15 +349,40 @@ Deregistriert die Interrupt Service Routine (ISR) auf einem Pin. >>> ```C -int wiringPiISRStop (int pin) +int wiringPiISRStop (int pin); ``` ``pin``: Der gewünschte Pin (BCM-, WiringPi- oder Pin-Nummer). ``Rückgabewert``: + > 0 ... Erfolgreich +**Beispiel:** + +>>> +```C +static volatile int edgeCounter; + +static void isr(void) { + edgeCounter++; +} + +int main (void) { + wiringPiSetupPinType(WPI_PIN_BCM); + edgeCounter = 0; + + wiringPiISR(17, INT_EDGE_RISING, &isr); + + Sleep(1000); + printf("%d rising edges\n", edgeCounter); + + wiringPiISRStop(17); +} +``` + + ### waitForInterrupt Funktion ist nicht mehr verfügbar, es wird nur noch die ``waitForInterrupt2`` unterstützt! @@ -372,21 +400,21 @@ struct WPIWfiStatus wfiStatus waitForInterrupt2(int pin, int edgeMode, int ms, u ``` ``pin``: Der gewünschte Pin (BCM\-, WiringPi\- oder Pin\-Nummer). +``edgeMode``: Auslösender Flankenmodus -``edgeMode``: Auslösende Flankenmodus - INT_EDGE_RISING ... Steigende Flanke - INT_EDGE_FALLING ... Fallende Flanke - INT_EDGE_BOTH ... Steigende und fallende Flanke -``mS``: Timeout in Milisekunden. - - \-1 warten ohne timeout - - 0 wartet nicht - - 1...n wartet maximal n Millisekunden +``ms``: Timeout in Milisekunden. + - \-1 ... Warten ohne Timeout + - 0 ... Wartet nicht + - 1...n ... Wartet maximal n Millisekunden ``debounce_period_us``: Entprellzeit in Microsekunden, 0 schaltet Entprellen ab. -``Rückgabewert``: -```C +``Rückgabewert``: +```C struct WPIWfiStatus { int statusOK; // -1: error (return of 'poll' command), 0: timeout, 1: irq processed, next data values are valid if needed unsigned int pinBCM; // gpio as BCM pin @@ -395,8 +423,9 @@ struct WPIWfiStatus { }; ``` -### Beispiel -```C +**Beispiel:** + +```C /* * isr_debounce.c: * Wait for Interrupt test program WiringPi >=3.16 - ISR2 method @@ -421,21 +450,21 @@ struct WPIWfiStatus { // OUTpin : connected to a LED with 470 Ohm resistor in series to GND. Toggles LED with every push button pressed. //************************************* #define IRQpin 16 -#define OUTpin 12 +#define OUTpin 12 int toggle = 0; -static void wfi(struct WPIWfiStatus wfiStatus, void* userdata) { +static void wfi(struct WPIWfiStatus wfiStatus, void* userdata) { // struct timeval now; long long int timenow, diff; struct timespec curr; char *edgeType; - + if (clock_gettime(CLOCK_MONOTONIC, &curr) == -1) { printf("clock_gettime error"); return; } - + timenow = curr.tv_sec * 1000000LL + curr.tv_nsec/1000L; // convert to microseconds diff = timenow - wfiStatus.timeStamp_us; if (wfiStatus.edge == INT_EDGE_RISING) @@ -446,11 +475,11 @@ static void wfi(struct WPIWfiStatus wfiStatus, void* userdata) { edgeType = "none"; printf("gpio BCM = %d, IRQ edge = %s, timestamp = %lld microseconds, timenow = %lld, diff = %lld\n", wfiStatus.gpioPin, edgeType, wfiStatus.timeStamp_us, timenow, diff); if (toggle == 0) { - digitalWrite (OUTpin, HIGH) ; + digitalWrite (OUTpin, HIGH); toggle = 1; } else { - digitalWrite (OUTpin, LOW) ; + digitalWrite (OUTpin, LOW); toggle = 0; } } @@ -459,55 +488,50 @@ static void wfi(struct WPIWfiStatus wfiStatus, void* userdata) { int main (void) { int major, minor; - wiringPiVersion(&major, &minor); - printf("\nISR debounce test (WiringPi %d.%d)\n\n", major, minor); - - wiringPiSetupGpio() ; + wiringPiSetupGpio(); pinMode(IRQpin, INPUT); - // pull up/down mode (PUD_OFF, PUD_UP, PUD_DOWN) => down pullUpDnControl(IRQpin, PUD_UP); - pinMode(OUTpin, OUTPUT); digitalWrite (OUTpin, LOW) ; - printf("Testing waitForInterrupt on both edges IRQ @ GPIO%d, timeout is %d\n", IRQpin, TIMEOUT); + printf("Testing waitForInterrupt on both edges IRQ @ GPIO%d, timeout is %d\n", IRQpin, TIMEOUT); struct WPIWfiStatus wfiStatus = waitForInterrupt2(IRQpin, INT_EDGE_BOTH, TIMEOUT, BOUNCETIME_WFI); if (wfiStatus.status < 0) { printf("waitForInterrupt returned error\n"); pinMode(OUTpin, INPUT); - return 0; + return 0; } else if (wfiStatus.status == 0) { printf("waitForInterrupt timed out\n\n"); - } + } else { if (wfiStatus.edge == INT_EDGE_FALLING) - printf("waitForInterrupt: GPIO pin %d falling edge fired at %lld microseconds\n\n", wfiStatus.gpioPin, wfiStatus.timeStamp_us); + printf("waitForInterrupt: GPIO pin %d falling edge fired at %lld microseconds\n\n", wfiStatus.gpioPin, wfiStatus.timeStamp_us); else - printf("waitForInterrupt: GPIO pin %d rising edge fired at %lld microseconds\n\n", wfiStatus.gpioPin, wfiStatus.timeStamp_us); + printf("waitForInterrupt: GPIO pin %d rising edge fired at %lld microseconds\n\n", wfiStatus.gpioPin, wfiStatus.timeStamp_us); } printf("Testing IRQ @ GPIO%d on both edges and bouncetime %d microseconds. Toggle LED @ GPIO%d on IRQ.\n\n", IRQpin, BOUNCETIME, OUTpin); printf("To stop program hit return key\n\n"); - - wiringPiISR2(IRQpin, INT_EDGE_BOTH, &wfi, BOUNCETIME, NULL) ; - + + wiringPiISR2(IRQpin, INT_EDGE_BOTH, &wfi, BOUNCETIME, NULL); + getc(stdin); - - wiringPiISRStop (IRQpin) ; + + wiringPiISRStop (IRQpin); pinMode(OUTpin, INPUT); - return 0 ; + return 0; } ``` -Augabe am Terminal: +Ausgabe am Terminal: -``` +``` pi@RaspberryPi:~/wiringpi-test-v3.16 $ gcc -o isr_debounce isr_debounce.c -l wiringPi pi@RaspberryPi:~/wiringpi-test-v3.16 $ ./isr_debounce @@ -533,7 +557,7 @@ gpio BCM = 16, IRQ edge = falling, timestamp = 256543320012 microseconds, timeno gpio BCM = 16, IRQ edge = rising, timestamp = 256544092021 microseconds, timenow = 256544092029, diff = 8 ^C pi@RaspberryPi:~/wiringpi-test-v3.16 $ -``` +``` ## Hardware PWM (Pulsweitenmodulation) diff --git a/documentation/english/functions.md b/documentation/english/functions.md index aad803d..3c54530 100644 --- a/documentation/english/functions.md +++ b/documentation/english/functions.md @@ -120,11 +120,10 @@ Outdated functions (no longer use): **Since Version 3.4:** -``wiringPiSetupPinType`` decides whether WiringPi, BCM or physical PIN numbering is now used, based on the parameter pinType. So it combines the first 3 setup functions together. -``wiringPiSetupGpioDevice`` is the successor to the ``wiringPiSetupSys`` function and now uses "GPIO Character Device Userspace API" in version 1 (from kernel 5.10). More information can be found at [docs.kernel.org/driver-api/gpio/driver.html](https://docs.kernel.org/driver-api/gpio/driver.html) on the parameter pintype, it is again decided which pin numbering is used. +``wiringPiSetupPinType`` decides whether WiringPi, BCM or physical pin numbering is used, based on the parameter pinType. So it combines the first 3 setup functions together. +``wiringPiSetupGpioDevice`` is the successor to the ``wiringPiSetupSys`` function and now uses "GPIO Character Device Userspace API" in version 2 (WiringPi version 3.16 or higher). More information can be found at [docs.kernel.org/driver-api/gpio/driver.html](https://docs.kernel.org/driver-api/gpio/driver.html) on the parameter pintype, it is again decided which pin numbering is used. In this variant, there is no direct access to the GPIO memory (DMA) but rather through a kernel interface that is available with user permissions. The disadvantage is the limited functionality and low performance. - ### wiringPiSetup V2 (outdated) @@ -294,14 +293,15 @@ if (value == HIGH) ### wiringPiISR -Registers an Interrupt Service Routine (ISR) / function that is executed on edge detection. +Registers an Interrupt Service Routine (ISR) / function that is executed on edge detection. +In this classic version, no parameters are passed to the ISR. ```C int wiringPiISR(int pin, int mode, void (*function)(void)); ``` -``pin``: The desired Pin (BCM-, WiringPi-, or Pin-number). -``mode``: Triggering edge mode... +``pin``: The desired pin (BCM-, WiringPi-, or Pin-number). +``mode``: Triggering edge mode - `INT_EDGE_RISING` ... Rising edge - `INT_EDGE_FALLING` ... Falling edge @@ -311,14 +311,50 @@ int wiringPiISR(int pin, int mode, void (*function)(void)); ``Return Value``: > 0 ... Successful - -For example see **[wiringPiISRStop](#wiringpiisrstop)**. +For example see [wiringPiISRStop](#wiringPiISRStop). + + +### wiringPiISR2 + +Registers an Interrupt Service Routine (ISR) / function that is executed on edge detection. +Extended parameters are passed to the ISR. + +>>> +```C +int wiringPiISR2(int pin, int edgeMode, void (*function)(struct WPIWfiStatus wfiStatus, void* userdata), unsigned long debounce_period_us, void* userdata); +``` + +``pin``: The desired pin (BCM-, WiringPi-, or Pin-number). +``edgeMode``: Triggering edge mode + +- `INT_EDGE_RISING` ... Rising edge +- `INT_EDGE_FALLING` ... Falling edge +- `INT_EDGE_BOTH` ... Rising and falling edge + +``*function``: Function pointer for ISR with the parameter struct WPIWfiStatus and a pointer. +```C +struct WPIWfiStatus { + int statusOK; // -1: error (return of 'poll' command), 0: timeout, 1: irq processed, next data values are valid if needed + unsigned int pinBCM; // gpio as BCM pin + int edge; // INT_EDGE_FALLING or INT_EDGE_RISING + long long int timeStamp_us; // time stamp in microseconds +}; +``` + +``debounce_period_us``: Debounce time in microseconds, 0 disables debouncing. +``userdata``: Pointer that is passed when calling the ISR. + +``Return Value``: + > 0 ... Successful + + For example see [waitForInterrupt2](#waitForInterrupt2). + ### wiringPiISRStop -Deregisters the Interrupt Service Routine (ISR) on a Pin. +Deregisters the Interrupt Service Routine (ISR) on a pin. ```C int wiringPiISRStop (int pin); @@ -344,7 +380,7 @@ int main (void) { wiringPiSetupPinType(WPI_PIN_BCM); edgeCounter = 0; - wiringPiISR (17, INT_EDGE_RISING, &isr); + wiringPiISR(17, INT_EDGE_RISING, &isr); Sleep(1000); printf("%d rising edges\n", edgeCounter); @@ -355,18 +391,171 @@ int main (void) { ### waitForInterrupt -Waits for a previously defined interrupt ([wiringPiISR](#wiringpiisr)) on the GPIO pin. This function should not be used. +The function is no longer available, only ``waitForInterrupt2``! + + +### waitForInterrupt2 + +Waits for a call to the Interrupt Service Routine (ISR) with a timeout and debounce time in microseconds. Blocks the program until the triggering edge occurs or the timeout expires. ```C -int waitForInterrupt (int pin, int mS); +struct WPIWfiStatus wfiStatus waitForInterrupt2(int pin, int edgeMode, int ms, unsigned long debounce_period_us) ``` ``pin``: The desired Pin (BCM-, WiringPi-, or Pin-number). -``mS``: Timeout in milliseconds. -``Return Value``: Error -> 0 ... Successful -> -1 ... GPIO Device Chip not successfully opened -> -2 ... ISR was not registered (WiringPiISR must be called) +``ms``: Timeout in milliseconds. + - \-1 ... Wait without timeout + - 0 ... No wait + - 1...n ... Waits for a maximum of n milliseconds + +``debounce_period_us``: Debounce time in microseconds, 0 disables debouncing. + +``Return Value``: +```C +struct WPIWfiStatus { + int statusOK; // -1: error (return of 'poll' command), 0: timeout, 1: irq processed, next data values are valid if needed + unsigned int pinBCM; // gpio as BCM pin + int edge; // INT_EDGE_FALLING or INT_EDGE_RISING + long long int timeStamp_us; // time stamp in microseconds +}; +``` + +**Example:** + +```C +/* + * isr_debounce.c: + * Wait for Interrupt test program WiringPi >=3.16 - ISR2 method + * + * + */ + +#include +#include +#include +#include +#include +#include +#include + +#define BOUNCETIME 3000 // microseconds +#define BOUNCETIME_WFI 300 +#define TIMEOUT 10000 +//************************************* +// BCM pins +// IRQpin : setup as input with internal pullup. Connected with push button to GND with 1K resistor in series. +// OUTpin : connected to a LED with 470 Ohm resistor in series to GND. Toggles LED with every push button pressed. +//************************************* +#define IRQpin 16 +#define OUTpin 12 + +int toggle = 0; + +static void wfi(struct WPIWfiStatus wfiStatus, void* userdata) { +// struct timeval now; + long long int timenow, diff; + struct timespec curr; + char *edgeType; + + if (clock_gettime(CLOCK_MONOTONIC, &curr) == -1) { + printf("clock_gettime error"); + return; + } + + timenow = curr.tv_sec * 1000000LL + curr.tv_nsec/1000L; // convert to microseconds + diff = timenow - wfiStatus.timeStamp_us; + if (wfiStatus.edge == INT_EDGE_RISING) + edgeType = "rising"; + else if (wfiStatus.edge == INT_EDGE_FALLING) + edgeType = "falling"; + else + edgeType = "none"; + printf("gpio BCM = %d, IRQ edge = %s, timestamp = %lld microseconds, timenow = %lld, diff = %lld\n", wfiStatus.gpioPin, edgeType, wfiStatus.timeStamp_us, timenow, diff); + if (toggle == 0) { + digitalWrite (OUTpin, HIGH); + toggle = 1; + } + else { + digitalWrite (OUTpin, LOW); + toggle = 0; + } +} + + +int main (void) +{ + int major, minor; + wiringPiVersion(&major, &minor); + printf("\nISR debounce test (WiringPi %d.%d)\n\n", major, minor); + + wiringPiSetupGpio(); + pinMode(IRQpin, INPUT); + // pull up/down mode (PUD_OFF, PUD_UP, PUD_DOWN) => down + pullUpDnControl(IRQpin, PUD_UP); + pinMode(OUTpin, OUTPUT); + digitalWrite (OUTpin, LOW) ; + + printf("Testing waitForInterrupt on both edges IRQ @ GPIO%d, timeout is %d\n", IRQpin, TIMEOUT); + struct WPIWfiStatus wfiStatus = waitForInterrupt2(IRQpin, INT_EDGE_BOTH, TIMEOUT, BOUNCETIME_WFI); + if (wfiStatus.status < 0) { + printf("waitForInterrupt returned error\n"); + pinMode(OUTpin, INPUT); + return 0; + } + else if (wfiStatus.status == 0) { + printf("waitForInterrupt timed out\n\n"); + } + else { + if (wfiStatus.edge == INT_EDGE_FALLING) + printf("waitForInterrupt: GPIO pin %d falling edge fired at %lld microseconds\n\n", wfiStatus.gpioPin, wfiStatus.timeStamp_us); + else + printf("waitForInterrupt: GPIO pin %d rising edge fired at %lld microseconds\n\n", wfiStatus.gpioPin, wfiStatus.timeStamp_us); + } + + printf("Testing IRQ @ GPIO%d on both edges and bouncetime %d microseconds. Toggle LED @ GPIO%d on IRQ.\n\n", IRQpin, BOUNCETIME, OUTpin); + printf("To stop program hit return key\n\n"); + + wiringPiISR2(IRQpin, INT_EDGE_BOTH, &wfi, BOUNCETIME, NULL); + + getc(stdin); + + wiringPiISRStop (IRQpin); + pinMode(OUTpin, INPUT); + + return 0; +} +``` + +Output on terminal: + +``` +pi@RaspberryPi:~/wiringpi-test-v3.16 $ gcc -o isr_debounce isr_debounce.c -l wiringPi +pi@RaspberryPi:~/wiringpi-test-v3.16 $ ./isr_debounce + +ISR debounce test (WiringPi 3.16) + +Testing waitForInterrupt on both edges IRQ @ GPIO16, timeout is 10000 +waitForInterrupt: GPIO pin 16 falling edge fired at 256522528012 microseconds + +Testing IRQ @ GPIO16 on both edges and bouncetime 3000 microseconds. Toggle LED @ GPIO12 on IRQ. + +To stop program hit return key + +gpio BCM = 16, IRQ edge = rising, timestamp = 256522668010 microseconds, timenow = 256522668017, diff = 7 +gpio BCM = 16, IRQ edge = falling, timestamp = 256536364014 microseconds, timenow = 256536364021, diff = 7 +gpio BCM = 16, IRQ edge = rising, timestamp = 256536952011 microseconds, timenow = 256536952018, diff = 7 +gpio BCM = 16, IRQ edge = falling, timestamp = 256537856010 microseconds, timenow = 256537856016, diff = 6 +gpio BCM = 16, IRQ edge = rising, timestamp = 256538744011 microseconds, timenow = 256538744018, diff = 7 +gpio BCM = 16, IRQ edge = falling, timestamp = 256539664010 microseconds, timenow = 256539664017, diff = 7 +gpio BCM = 16, IRQ edge = rising, timestamp = 256540516010 microseconds, timenow = 256540516016, diff = 6 +gpio BCM = 16, IRQ edge = falling, timestamp = 256541560013 microseconds, timenow = 256541560022, diff = 9 +gpio BCM = 16, IRQ edge = rising, timestamp = 256542360010 microseconds, timenow = 256542360016, diff = 6 +gpio BCM = 16, IRQ edge = falling, timestamp = 256543320012 microseconds, timenow = 256543320020, diff = 8 +gpio BCM = 16, IRQ edge = rising, timestamp = 256544092021 microseconds, timenow = 256544092029, diff = 8 +^C +pi@RaspberryPi:~/wiringpi-test-v3.16 $ +``` + ## Hardware Pulse Width Modulation (PWM) From 681c5f13ef5df0501e0be454874597a2bcf1af5b Mon Sep 17 00:00:00 2001 From: mstroh76 Date: Fri, 6 Jun 2025 18:56:01 +0200 Subject: [PATCH 62/65] #363 v3.16 I2C function deutsch --- documentation/deutsch/functions.md | 42 +++++++++++++++++++++++++----- documentation/english/functions.md | 23 +++++++++------- 2 files changed, 48 insertions(+), 17 deletions(-) diff --git a/documentation/deutsch/functions.md b/documentation/deutsch/functions.md index 83f6f82..ff12ccc 100644 --- a/documentation/deutsch/functions.md +++ b/documentation/deutsch/functions.md @@ -20,13 +20,13 @@ sudo apt install git git clone https://github.com/WiringPi/WiringPi.git cd WiringPi ./build debian -mv debian-template/wiringpi-3.1x.deb . +mv debian-template/wiringpi_3.16_arm64.deb . ``` **Debian-Paket installieren:** ```bash -sudo apt install ./wiringpi-3.1x.deb +sudo apt install ./wiringpi_3.16_arm64.deb ``` **Debian-Paket deinstallieren:** @@ -409,7 +409,7 @@ struct WPIWfiStatus wfiStatus waitForInterrupt2(int pin, int edgeMode, int ms, u ``ms``: Timeout in Milisekunden. - \-1 ... Warten ohne Timeout - 0 ... Wartet nicht - - 1...n ... Wartet maximal n Millisekunden + - 1-n ... Wartet maximal n Millisekunden ``debounce_period_us``: Entprellzeit in Microsekunden, 0 schaltet Entprellen ab. @@ -690,9 +690,21 @@ int fd = wiringPiI2CSetupInterface("/dev/i2c-1", 0x20); ``` -### wiringPiI2CWrite / wiringPiI2CWriteReg8 / wiringPiI2CWriteReg16 / wiringPiI2CWriteBlockData +### wiringPiI2CWrite -... +Einfaches schreiben auf einen I2C-Slave. Manche Geräte benötigen keine Adressierung eines Registers. + +### wiringPiI2CWriteReg8 + +Schreibt 8-Bit Daten auf ein Register am Geräte. + +### wiringPiI2CWriteReg16 + +Schreibt 16-Bit Daten auf ein Register am Geräte. + +### wiringPiI2CWriteBlockData + +Schreibt entsprechend der angeben Größe Daten auf ein Register am Geräte. ### wiringPiI2CRawWrite @@ -725,9 +737,25 @@ if (fd>0) { } ``` -### wiringPiI2CRead / wiringPiI2CReadReg8 / wiringPiI2CReadReg16 / wiringPiI2CReadBlockData -... +### wiringPiI2CRead + +Einfaches lesen vom I2C-Slave. Manche Geräte benötigen keine Adressierung eines Registers. + +### wiringPiI2CReadReg8 + +Liest 8-Bit Daten vom Register am Geräte. + + +### wiringPiI2CReadReg16 + +Liest 16-Bit Daten vom Register am Geräte. + + +### wiringPiI2CReadBlockData + +Liest entsprechend der angeben Größe Daten vom Register am Geräte. + ### wiringPiI2CRawRead diff --git a/documentation/english/functions.md b/documentation/english/functions.md index 3c54530..30498f1 100644 --- a/documentation/english/functions.md +++ b/documentation/english/functions.md @@ -22,13 +22,13 @@ sudo apt install git git clone https://github.com/WiringPi/WiringPi.git cd WiringPi ./build debian -mv debian-template/wiringpi-3.0-1.deb . +mv debian-template/wiringpi_3.16_arm64.deb . ``` **Install Debian package:** ```bash -sudo apt install ./wiringpi-3.0-1.deb +sudo apt install ./wiringpi_3.16_arm64.deb ``` **Uninstall Debian package:** @@ -406,7 +406,7 @@ struct WPIWfiStatus wfiStatus waitForInterrupt2(int pin, int edgeMode, int ms, u ``ms``: Timeout in milliseconds. - \-1 ... Wait without timeout - 0 ... No wait - - 1...n ... Waits for a maximum of n milliseconds + - 1-n ... Waits for a maximum of n milliseconds ``debounce_period_us``: Debounce time in microseconds, 0 disables debouncing. @@ -687,15 +687,15 @@ Simple device write. Some devices accept data this way without needing to access ### wiringPiI2CWriteReg8 -Writes a 8-bit data value into the device register indicated. +Writes 8-bit data value to the device register. ### wiringPiI2CWriteReg16 -Writes a 16-bit data value into the device register indicated. +Writes 16-bit data value to the device register. ### wiringPiI2CWriteBlockData -... +Writes specified byte data values to the device register. ### wiringPiI2CRawWrite @@ -730,21 +730,24 @@ else { } ``` + ### wiringPiI2CRead -Simple device read. Some devices accept data this way without needing to access any internal registers. + +Simple read from I2C slave. Some devices accept data this way without needing to access any internal registers. ### wiringPiI2CReadReg8 -Reads an 8-bit data value into the device register indicated. +Reads 8-bit data value from the device register. ### wiringPiI2CReadReg16 -Reads an 16-bit data value into the device register indicated. +Reads 16-bit data value from the device register. + ### wiringPiI2CReadBlockData -... +Reads specified byte data values from the device register. ### wiringPiI2CRawRead From 7bec94a85a11ff6c42972066978a881fbd772d8d Mon Sep 17 00:00:00 2001 From: Nicolas DA SILVA Date: Fri, 6 Jun 2025 19:23:47 +0200 Subject: [PATCH 63/65] Update functions.md Missing "Mode" in wiringPiSPISetupMode example --- documentation/english/functions.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/documentation/english/functions.md b/documentation/english/functions.md index a277e80..c0a39e6 100644 --- a/documentation/english/functions.md +++ b/documentation/english/functions.md @@ -577,7 +577,7 @@ Opens the specified SPI bus. >>> ```C int wiringPiSPISetup (int channel, int speed) -int wiringPiSPISetup (int channel, int speed, int mode) +int wiringPiSPISetupMode (int channel, int speed, int mode) int wiringPiSPIxSetupMode(const int number, const int channel, const int speed, const int mode) ``` From f350e4f857100531add07df542920ec5912a3e03 Mon Sep 17 00:00:00 2001 From: mstroh76 Date: Fri, 6 Jun 2025 19:38:14 +0200 Subject: [PATCH 64/65] wiringPiSPISetupMode fix --- documentation/deutsch/functions.md | 6 ++++-- documentation/english/functions.md | 4 ++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/documentation/deutsch/functions.md b/documentation/deutsch/functions.md index ff12ccc..0c86b55 100644 --- a/documentation/deutsch/functions.md +++ b/documentation/deutsch/functions.md @@ -802,8 +802,10 @@ Die alten Funktionen bleiben erhalten beziehen sich allerdings immer auf den SPI >>> ```C -int wiringPiSPISetup (int channel, int speed) -int wiringPiSPISetup (int channel, int speed, int mode) +int wiringPiSPISetup(int channel, int speed) + +int wiringPiSPISetupMode(int channel, int speed, int mode) + int wiringPiSPIxSetupMode(const int number, const int channel, const int speed, const int mode) ``` diff --git a/documentation/english/functions.md b/documentation/english/functions.md index 981786b..f13874a 100644 --- a/documentation/english/functions.md +++ b/documentation/english/functions.md @@ -791,9 +791,9 @@ Functions that start with ``wiringPiSPIx`` are new since version 3, allowing th Opens the specified SPI bus. The Raspberry Pi has 2 channels, 0 and 1. The speed parameter is an integer in the range of 500,000 through 32,000,000 and represents the SPI clock speed in Hz. ```C -int wiringPiSPISetup (int channel, int speed); +int wiringPiSPISetup(int channel, int speed); -int wiringPiSPISetupMode (int channel, int speed, int mode); +int wiringPiSPISetupMode(int channel, int speed, int mode); int wiringPiSPIxSetupMode(const int number, const int channel, const int speed, const int mode); ``` From a18355e1d9632a5dd3b2687d4995a74be62acda1 Mon Sep 17 00:00:00 2001 From: mstroh76 Date: Fri, 6 Jun 2025 19:39:45 +0200 Subject: [PATCH 65/65] move old gpio unit tests --- gpio/{pintest => test/pintest.sh} | 0 gpio/{ => test}/test.sh | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename gpio/{pintest => test/pintest.sh} (100%) rename gpio/{ => test}/test.sh (100%) diff --git a/gpio/pintest b/gpio/test/pintest.sh similarity index 100% rename from gpio/pintest rename to gpio/test/pintest.sh diff --git a/gpio/test.sh b/gpio/test/test.sh similarity index 100% rename from gpio/test.sh rename to gpio/test/test.sh