From 1fdd4f91e9964a2664d1afcf34e6dc85e58deabd Mon Sep 17 00:00:00 2001 From: mstroh Date: Thu, 5 Jun 2025 19:43:39 +0200 Subject: [PATCH 1/9] 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 2/9] 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 3/9] 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 4/9] 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 30cbdf9373f9b7ad17d7b2250cf004a608ab4a26 Mon Sep 17 00:00:00 2001 From: mstroh76 Date: Fri, 6 Jun 2025 18:29:56 +0200 Subject: [PATCH 5/9] #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 6/9] #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 7/9] 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 8/9] 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 9/9] 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