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/17] 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/17] 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/17] 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/17] 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/17] 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/17] 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/17] 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/17] 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/17] 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/17] 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/17] 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/17] 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/17] 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/17] 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/17] 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/17] 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/17] 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