@@ -119,10 +119,10 @@ cd WiringPi
|
|||||||
|
|
||||||
# build the package
|
# build the package
|
||||||
./build debian
|
./build debian
|
||||||
mv debian-template/wiringpi-3.0-1.deb .
|
mv debian-template/wiringpi-3.x.deb .
|
||||||
|
|
||||||
# install it
|
# install it
|
||||||
sudo apt install ./wiringpi-3.0-1.deb
|
sudo apt install ./wiringpi-3.x.deb
|
||||||
```
|
```
|
||||||
|
|
||||||
### Prebuilt Binaries
|
### Prebuilt Binaries
|
||||||
@@ -133,14 +133,14 @@ Unzip/use the portable prebuilt verison:
|
|||||||
|
|
||||||
```sh
|
```sh
|
||||||
# unzip the archive
|
# unzip the archive
|
||||||
tar -xfv wiringpi_3.0.tar.gz
|
tar -xfv wiringpi_3.x.tar.gz
|
||||||
```
|
```
|
||||||
|
|
||||||
Install the debian package:
|
Install the debian package:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
# install a dpkg
|
# install a dpkg
|
||||||
sudo apt install ./wiringpi-3.0-1.deb
|
sudo apt install ./wiringpi-3.x.deb
|
||||||
```
|
```
|
||||||
|
|
||||||
## Ports
|
## Ports
|
||||||
|
|||||||
@@ -20,13 +20,13 @@ sudo apt install git
|
|||||||
git clone https://github.com/WiringPi/WiringPi.git
|
git clone https://github.com/WiringPi/WiringPi.git
|
||||||
cd WiringPi
|
cd WiringPi
|
||||||
./build debian
|
./build debian
|
||||||
mv debian-template/wiringpi-3.0-1.deb .
|
mv debian-template/wiringpi-3.1x.deb .
|
||||||
```
|
```
|
||||||
|
|
||||||
**Debian-Paket installieren:**
|
**Debian-Paket installieren:**
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
sudo apt install ./wiringpi-3.0-1.deb
|
sudo apt install ./wiringpi-3.1x.deb
|
||||||
```
|
```
|
||||||
|
|
||||||
**Debian-Paket deinstallieren:**
|
**Debian-Paket deinstallieren:**
|
||||||
@@ -291,21 +291,33 @@ Registriert eine Interrupt Service Routine (ISR) bzw. Funktion die bei Flankenwe
|
|||||||
|
|
||||||
>>>
|
>>>
|
||||||
```C
|
```C
|
||||||
int wiringPiISR(int pin, int mode, void (*function)(void));
|
int wiringPiISR(int pin, int edgeMode, void (*function)(struct WPIWfiStatus wfiStatus), unsigned long bouncetime);
|
||||||
```
|
```
|
||||||
|
|
||||||
``pin``: Der gewünschte Pin (BCM-, WiringPi- oder Pin-Nummer).
|
``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_RISING ... Steigende Flanke
|
||||||
- INT_EDGE_FALLING ... Fallende Flanke
|
- INT_EDGE_FALLING ... Fallende Flanke
|
||||||
- INT_EDGE_BOTH ... Steigende und fallende Flanke
|
- INT_EDGE_BOTH ... Steigende und fallende Flanke
|
||||||
|
|
||||||
``*function``: Funktionspointer für ISR
|
``*function``: Funktionspointer für ISR mit Rückgabeparameter struct WPIWfiStatus:
|
||||||
|
```C
|
||||||
|
struct WPIWfiStatus {
|
||||||
|
int status; // -1: error, 0: timeout, 1: valid values for edge and timeStamp_us
|
||||||
|
unsigned int gpioPin; // gpio as BCM pin
|
||||||
|
int edge; // One of INT_EDGE_FALLING or INT_EDGE_RISING
|
||||||
|
long long int timeStamp_us; // time stamp in microseconds, when interrupt happened
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
``bouncetime``: Entprellzeit in Microsekunden, 0 ms schaltet das Entprellen ab
|
||||||
|
|
||||||
``Rückgabewert``:
|
``Rückgabewert``:
|
||||||
> 0 ... Erfolgreich
|
> 0 ... Erfolgreich
|
||||||
<!-- > <>0 ... Fehler, zur Zeit nicht implementiert -->
|
<!-- > <>0 ... Fehler, zur Zeit nicht implementiert -->
|
||||||
|
|
||||||
Beispiel siehe wiringPiISRStop.
|
Beispiel siehe waitForInterrupt.
|
||||||
|
|
||||||
|
|
||||||
### wiringPiISRStop
|
### wiringPiISRStop
|
||||||
@@ -323,41 +335,187 @@ int wiringPiISRStop (int pin)
|
|||||||
<!-- > <>0 ... Fehler, zur Zeit nicht implementiert -->
|
<!-- > <>0 ... Fehler, zur Zeit nicht implementiert -->
|
||||||
|
|
||||||
|
|
||||||
**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
|
### waitForInterrupt
|
||||||
|
|
||||||
Wartet auf einen zuvor definierten Interrupt (wiringPiISR) am GPIO Pin. Diese Funktion sollte nicht verwendet werden.
|
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
|
```C
|
||||||
int waitForInterrupt (int pin, int mS)
|
struct WPIWfiStatus wfiStatus waitForInterrupt (int pin, int edgeMode, int mS, unsigned long bouncetime)
|
||||||
```
|
```
|
||||||
|
|
||||||
``pin``: Der gewünschte Pin (BCM-, WiringPi- oder Pin-Nummer).
|
``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.
|
``mS``: Timeout in Milisekunden.
|
||||||
``Rückgabewert``: Fehler
|
- \-1 warten ohne timeout
|
||||||
> 0 ... Erfolgreich
|
- 0 wartet nicht
|
||||||
> -1 ... GPIO Device Chip nicht erfolgreich geöffnet
|
- 1...n wartet maximal n mS Millisekunden
|
||||||
> -2 ... ISR wurde nicht registriert (wiringPiISR muss aufgerufen werden)
|
|
||||||
|
``bouncetime``: 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
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
**Beispiel:**
|
||||||
|
|
||||||
|
```C
|
||||||
|
/*
|
||||||
|
* isr_debounce.c:
|
||||||
|
* Wait for Interrupt test program WiringPi >=3.16 - ISR method
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <wiringPi.h>
|
||||||
|
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
|
#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;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* myInterrupt:
|
||||||
|
*********************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
static void wfi (struct WPIWfiStatus wfiStatus) {
|
||||||
|
// struct timeval now;
|
||||||
|
long long int timenow, diff;
|
||||||
|
struct timespec curr;
|
||||||
|
char *edgeType;
|
||||||
|
|
||||||
|
if (clock_gettime(CLOCK_MONOTONIC, &curr) == -1) {
|
||||||
|
printf("clock_gettime error");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
timenow = curr.tv_sec * 1000000LL + curr.tv_nsec/1000L; // convert to microseconds
|
||||||
|
diff = timenow - 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 = waitForInterrupt(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 with trigger @ GPIO%d on both edges and bouncetime %d microseconds. Toggle LED @ OUTpin on IRQ.\n\n", IRQpin, IRQpin, BOUNCETIME, OUTpin);
|
||||||
|
printf("To stop program hit return key\n\n");
|
||||||
|
|
||||||
|
wiringPiISR (IRQpin, INT_EDGE_BOTH, &wfi, BOUNCETIME) ;
|
||||||
|
|
||||||
|
getc(stdin);
|
||||||
|
|
||||||
|
wiringPiISRStop (IRQpin) ;
|
||||||
|
pinMode(OUTpin, INPUT);
|
||||||
|
|
||||||
|
return 0 ;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Output auf dem Terminal:
|
||||||
|
|
||||||
|
```
|
||||||
|
pi@RaspberryPi:~/wiringpi-test-v3.16 $ gcc -o isr_debounce isr_debounce.c -l wiringPi
|
||||||
|
pi@RaspberryPi:~/wiringpi-test-v3.16 $ ./isr_debounce
|
||||||
|
|
||||||
|
ISR debounce test (WiringPi 3.16)
|
||||||
|
|
||||||
|
Testing waitForInterrupt on both edges IRQ @ GPIO16, timeout is 10000
|
||||||
|
waitForInterrupt: GPIO pin 16 falling edge fired at 256522528012 microseconds
|
||||||
|
|
||||||
|
Testing IRQ @ GPIO16 with trigger @ GPIO16 on both edges and bouncetime 3000 microseconds. Toggle LED @ OUTpin on IRQ.
|
||||||
|
|
||||||
|
To stop program hit return key
|
||||||
|
|
||||||
|
gpio BCM = 16, IRQ edge = rising, timestamp = 256522668010 microseconds, timenow = 256522668017, diff = 7
|
||||||
|
gpio BCM = 16, IRQ edge = falling, timestamp = 256536364014 microseconds, timenow = 256536364021, diff = 7
|
||||||
|
gpio BCM = 16, IRQ edge = rising, timestamp = 256536952011 microseconds, timenow = 256536952018, diff = 7
|
||||||
|
gpio BCM = 16, IRQ edge = falling, timestamp = 256537856010 microseconds, timenow = 256537856016, diff = 6
|
||||||
|
gpio BCM = 16, IRQ edge = rising, timestamp = 256538744011 microseconds, timenow = 256538744018, diff = 7
|
||||||
|
gpio BCM = 16, IRQ edge = falling, timestamp = 256539664010 microseconds, timenow = 256539664017, diff = 7
|
||||||
|
gpio BCM = 16, IRQ edge = rising, timestamp = 256540516010 microseconds, timenow = 256540516016, diff = 6
|
||||||
|
gpio BCM = 16, IRQ edge = falling, timestamp = 256541560013 microseconds, timenow = 256541560022, diff = 9
|
||||||
|
gpio BCM = 16, IRQ edge = rising, timestamp = 256542360010 microseconds, timenow = 256542360016, diff = 6
|
||||||
|
gpio BCM = 16, IRQ edge = falling, timestamp = 256543320012 microseconds, timenow = 256543320020, diff = 8
|
||||||
|
gpio BCM = 16, IRQ edge = rising, timestamp = 256544092021 microseconds, timenow = 256544092029, diff = 8
|
||||||
|
^C
|
||||||
|
pi@RaspberryPi:~/wiringpi-test-v3.16 $
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
## Hardware PWM (Pulsweitenmodulation)
|
## Hardware PWM (Pulsweitenmodulation)
|
||||||
|
|||||||
116
examples/isr_debounce.c
Normal file
116
examples/isr_debounce.c
Normal file
@@ -0,0 +1,116 @@
|
|||||||
|
/*
|
||||||
|
* isr_debounce.c:
|
||||||
|
* Wait for Interrupt test program WiringPi >=3.13 - ISR method
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <wiringPi.h>
|
||||||
|
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
|
#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) ;
|
||||||
|
|
||||||
|
// sleep(30);
|
||||||
|
getc(stdin);
|
||||||
|
|
||||||
|
wiringPiISRStop (IRQpin) ;
|
||||||
|
pinMode(OUTpin, INPUT);
|
||||||
|
|
||||||
|
return 0 ;
|
||||||
|
}
|
||||||
156
gpio/gpio.c
156
gpio/gpio.c
@@ -165,7 +165,7 @@ void LOAD_DEPRECATED(const char *progName) {
|
|||||||
*********************************************************************************
|
*********************************************************************************
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static volatile int iterations ;
|
static volatile int globalIterations ;
|
||||||
static volatile int globalCounter ;
|
static volatile int globalCounter ;
|
||||||
|
|
||||||
void printgpioflush(const char* text) {
|
void printgpioflush(const char* text) {
|
||||||
@@ -181,59 +181,133 @@ void printgpio(const char* text) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void wfi (void) {
|
static void wfi (void) {
|
||||||
globalCounter++;
|
globalCounter++;
|
||||||
if(globalCounter>=iterations) {
|
if(globalCounter>=globalIterations) {
|
||||||
printgpio("finished\n");
|
printgpio("finished\n");
|
||||||
exit (0) ;
|
exit(0);
|
||||||
} else {
|
} else {
|
||||||
printgpioflush("I");
|
printgpioflush("I");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void doWfi (int argc, char *argv [])
|
|
||||||
{
|
|
||||||
int pin, mode;
|
|
||||||
int timeoutSec = 2147483647;
|
|
||||||
|
|
||||||
iterations = 1;
|
static void wfi2(struct WPIWfiStatus wfiStatus, void* userdata) {
|
||||||
|
(void)wfiStatus;
|
||||||
|
(void)userdata;
|
||||||
|
globalCounter++;
|
||||||
|
if (globalCounter>=globalIterations) {
|
||||||
|
switch(wfiStatus.edge) {
|
||||||
|
case INT_EDGE_FALLING:
|
||||||
|
printgpio("finished falling\n");
|
||||||
|
break;
|
||||||
|
case INT_EDGE_RISING:
|
||||||
|
printgpio("finished rising\n");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
printgpio("finished\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
exit(wfiStatus.edge);
|
||||||
|
} else {
|
||||||
|
printgpioflush("I");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int get_wfi_edge(const char* arg_cmd, const char* arg_mode, int exitcode) {
|
||||||
|
if (strcasecmp (arg_mode, "rising") == 0) {
|
||||||
|
return INT_EDGE_RISING ;
|
||||||
|
} else if (strcasecmp (arg_mode, "falling") == 0) {
|
||||||
|
return INT_EDGE_FALLING ;
|
||||||
|
} else if (strcasecmp (arg_mode, "both") == 0) {
|
||||||
|
return INT_EDGE_BOTH ;
|
||||||
|
} else {
|
||||||
|
fprintf (stderr, "%s: wfi: Invalid mode: %s. Should be rising, falling or both\n", arg_cmd, arg_mode) ;
|
||||||
|
exit(exitcode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void doWfiInternal(const char* cmd, int pin, int mode, int interations, int timeoutSec, int debounce) {
|
||||||
|
|
||||||
|
globalIterations = interations;
|
||||||
globalCounter = 0;
|
globalCounter = 0;
|
||||||
if (argc != 4 && argc != 5 && argc != 6)
|
if (debounce>=0) {
|
||||||
{
|
// V2 function
|
||||||
fprintf (stderr, "Usage: %s wfi pin mode [interations] [timeout sec.]\n", argv [0]) ;
|
if (wiringPiISR2(pin, mode, &wfi2, debounce, NULL) < 0) {
|
||||||
exit (1) ;
|
fprintf (stderr, "%s: Unable to setup ISR2: %s\n", cmd, strerror (errno));
|
||||||
}
|
exit(1);
|
||||||
|
}
|
||||||
pin = atoi (argv [2]) ;
|
} else {
|
||||||
|
// classic function
|
||||||
/**/ if (strcasecmp (argv [3], "rising") == 0) mode = INT_EDGE_RISING ;
|
if (wiringPiISR(pin, mode, &wfi) < 0) {
|
||||||
else if (strcasecmp (argv [3], "falling") == 0) mode = INT_EDGE_FALLING ;
|
fprintf (stderr, "%s: Unable to setup ISR: %s\n", cmd, strerror (errno));
|
||||||
else if (strcasecmp (argv [3], "both") == 0) mode = INT_EDGE_BOTH ;
|
exit(1);
|
||||||
else
|
}
|
||||||
{
|
|
||||||
fprintf (stderr, "%s: wfi: Invalid mode: %s. Should be rising, falling or both\n", argv [1], argv [3]) ;
|
|
||||||
exit (1) ;
|
|
||||||
}
|
|
||||||
if (argc>=5) {
|
|
||||||
iterations = atoi(argv [4]);
|
|
||||||
}
|
|
||||||
if (argc>=6) {
|
|
||||||
timeoutSec = atoi(argv [5]);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (wiringPiISR (pin, mode, &wfi) < 0)
|
|
||||||
{
|
|
||||||
fprintf (stderr, "%s: wfi: Unable to setup ISR: %s\n", argv [1], strerror (errno)) ;
|
|
||||||
exit (1) ;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
printgpio("wait for interrupt function call\n");
|
printgpio("wait for interrupt function call\n");
|
||||||
for (int Sec=0; Sec<timeoutSec; ++Sec) {
|
for (int Sec=0; Sec<timeoutSec; ++Sec) {
|
||||||
printgpioflush(".");
|
printgpioflush(".");
|
||||||
delay (999);
|
delay(999);
|
||||||
}
|
}
|
||||||
printgpio("\nstopping wait for interrupt\n");
|
printgpio("\nstopping wait for interrupt\n");
|
||||||
wiringPiISRStop (pin);
|
wiringPiISRStop(pin);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void doWfi(int argc, char *argv [])
|
||||||
|
{
|
||||||
|
int pin, mode, interations=1;
|
||||||
|
int timeoutSec = 2147483647;
|
||||||
|
|
||||||
|
if (argc != 4 && argc != 5 && argc != 6) {
|
||||||
|
fprintf (stderr, "Usage: %s wfi pin mode [interations] [timeout sec.]\n", argv [0]) ;
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
pin = atoi (argv[2]) ;
|
||||||
|
mode = get_wfi_edge(argv[1], argv[3], 1);
|
||||||
|
if (argc>=5) {
|
||||||
|
interations = atoi(argv[4]);
|
||||||
|
}
|
||||||
|
if (argc>=6) {
|
||||||
|
timeoutSec = atoi(argv[5]);
|
||||||
|
}
|
||||||
|
|
||||||
|
doWfiInternal(argv[1], pin, mode, interations, timeoutSec, -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void doWfi2(int argc, char *argv [])
|
||||||
|
{
|
||||||
|
int pin, mode, interations=1, debounce=50000;
|
||||||
|
int timeoutSec = 2147483647;
|
||||||
|
|
||||||
|
if (argc != 4 && argc != 5 && argc != 6 && argc != 7) {
|
||||||
|
fprintf (stderr, "Usage: %s wfis pin mode [debounce period microsec.] [interations] [timeout sec.]\n", argv [0]);
|
||||||
|
exit(-2);
|
||||||
|
}
|
||||||
|
|
||||||
|
pin = atoi (argv[2]) ;
|
||||||
|
mode = get_wfi_edge(argv[1], argv[3], -1);
|
||||||
|
if (argc>=5) {
|
||||||
|
debounce = atoi(argv[4]);
|
||||||
|
}
|
||||||
|
if (argc>=6) {
|
||||||
|
interations = atoi(argv[5]);
|
||||||
|
}
|
||||||
|
if (argc>=7) {
|
||||||
|
timeoutSec = atoi(argv[6]);
|
||||||
|
}
|
||||||
|
if (timeoutSec<0 || interations<0 || debounce<0) {
|
||||||
|
fprintf (stderr, " invalid parameter\n");
|
||||||
|
exit(-2);
|
||||||
|
}
|
||||||
|
|
||||||
|
doWfiInternal(argv[1], pin, mode, interations, timeoutSec, debounce);
|
||||||
|
exit(-1); // timeout
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -900,6 +974,10 @@ static void doVersion (char *argv [])
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void doIs40Pin ()
|
||||||
|
{
|
||||||
|
exit(piBoard40Pin() ? EXIT_SUCCESS : EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* main:
|
* main:
|
||||||
@@ -1134,7 +1212,9 @@ int main (int argc, char *argv [])
|
|||||||
else if (strcasecmp (argv [1], "rbx" ) == 0) doReadByte (argc, argv, TRUE) ;
|
else if (strcasecmp (argv [1], "rbx" ) == 0) doReadByte (argc, argv, TRUE) ;
|
||||||
else if (strcasecmp (argv [1], "rbd" ) == 0) doReadByte (argc, argv, FALSE) ;
|
else if (strcasecmp (argv [1], "rbd" ) == 0) doReadByte (argc, argv, FALSE) ;
|
||||||
else if (strcasecmp (argv [1], "clock" ) == 0) doClock (argc, argv) ;
|
else if (strcasecmp (argv [1], "clock" ) == 0) doClock (argc, argv) ;
|
||||||
|
else if (strcasecmp (argv [1], "wfis" ) == 0) doWfi2 (argc, argv) ;
|
||||||
else if (strcasecmp (argv [1], "wfi" ) == 0) doWfi (argc, argv) ;
|
else if (strcasecmp (argv [1], "wfi" ) == 0) doWfi (argc, argv) ;
|
||||||
|
else if (strcasecmp (argv [1], "is40pin" ) == 0) doIs40Pin () ;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
fprintf (stderr, "%s: Unknown command: %s.\n", argv [0], argv [1]) ;
|
fprintf (stderr, "%s: Unknown command: %s.\n", argv [0], argv [1]) ;
|
||||||
|
|||||||
219
gpio/test/gpio_test6_wfi.sh
Executable file
219
gpio/test/gpio_test6_wfi.sh
Executable file
@@ -0,0 +1,219 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
RED='\033[0;31m'
|
||||||
|
GREEN='\033[0;32m'
|
||||||
|
NC='\033[0m' # Reset color
|
||||||
|
|
||||||
|
UNITTEST_OK=true
|
||||||
|
TIMEOUT=8
|
||||||
|
iteration=0
|
||||||
|
GPIOIN=26
|
||||||
|
GPIOOUT=19
|
||||||
|
DEBOUNCE=100000
|
||||||
|
|
||||||
|
wait_with_timeout() {
|
||||||
|
local pid=$1
|
||||||
|
local timeout=$2
|
||||||
|
iteration=0
|
||||||
|
|
||||||
|
local toggle=0
|
||||||
|
while kill -0 "$pid" 2>/dev/null; do
|
||||||
|
if [ $iteration -ge $timeout ]; then
|
||||||
|
kill -9 "$pid" 2>/dev/null
|
||||||
|
echo -e "${RED}ERROR: timeout ${timeout}s reached ${NC}"
|
||||||
|
return -1
|
||||||
|
fi
|
||||||
|
echo -n .
|
||||||
|
sleep 1
|
||||||
|
toggle=$((1 - toggle))
|
||||||
|
gpio -g write $GPIOOUT $toggle
|
||||||
|
echo -n ${toggle}
|
||||||
|
sleep 0.2
|
||||||
|
iteration=$((iteration + 1))
|
||||||
|
done
|
||||||
|
|
||||||
|
wait "$pid"
|
||||||
|
return $?
|
||||||
|
}
|
||||||
|
|
||||||
|
wfi_test() {
|
||||||
|
local edge=$1
|
||||||
|
local set_iter=$2
|
||||||
|
local set_iterOK=$3
|
||||||
|
|
||||||
|
#wfi call
|
||||||
|
if [ $iteration -eq 0 ]; then
|
||||||
|
gpio -g wfi $GPIOIN "$edge" &
|
||||||
|
else
|
||||||
|
gpio -g wfi $GPIOIN "$edge" "$set_iter" &
|
||||||
|
fi
|
||||||
|
GPIO_PID=$!
|
||||||
|
wait_with_timeout "$GPIO_PID" "$TIMEOUT"
|
||||||
|
EXIT_CODE=$?
|
||||||
|
echo
|
||||||
|
if [ $EXIT_CODE -eq 0 ]; then
|
||||||
|
if [ "$set_iter" -gt 0 ]; then
|
||||||
|
if [ "$iteration" -eq "$set_iterOK" ]; then
|
||||||
|
echo -e "${GREEN}wfi "$edge" $set_iter iteration passt (exit code 0)${NC}"
|
||||||
|
else
|
||||||
|
echo -e "${RED}wfi "$edge" failed, $iteration iterations of $set_iter is wrong${NC}"
|
||||||
|
UNITTEST_OK=false
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo -e "${GREEN}wfi "$edge" passt (exit code 0)${NC}"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo -e "${RED}wfi "$edge" failed (exit code $EXIT_CODE)${NC}"
|
||||||
|
UNITTEST_OK=false
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
wfis_test() {
|
||||||
|
local edge=$1
|
||||||
|
local set_iter=$2
|
||||||
|
local set_iterOK=$3
|
||||||
|
local set_EXITCODE=$4
|
||||||
|
|
||||||
|
#wfis call
|
||||||
|
if [ $iteration -eq 0 ]; then
|
||||||
|
gpio -g wfis $GPIOIN "$edge" $DEBOUNCE &
|
||||||
|
else
|
||||||
|
gpio -g wfis $GPIOIN "$edge" $DEBOUNCE "$set_iter" &
|
||||||
|
fi
|
||||||
|
GPIO_PID=$!
|
||||||
|
wait_with_timeout "$GPIO_PID" "$TIMEOUT"
|
||||||
|
EXIT_CODE=$?
|
||||||
|
echo
|
||||||
|
if [ $EXIT_CODE -lt 3 ]; then
|
||||||
|
|
||||||
|
if [ $EXIT_CODE -eq "$set_EXITCODE" ]; then
|
||||||
|
|
||||||
|
if [ "$set_iter" -gt 0 ]; then
|
||||||
|
if [ "$iteration" -eq "$set_iterOK" ]; then
|
||||||
|
echo -e "${GREEN}wfis "$edge" $set_iter iteration passt (exit code $EXIT_CODE)${NC}"
|
||||||
|
else
|
||||||
|
echo -e "${RED}wfis "$edge" failed, $iteration iterations of $set_iter is wrong${NC}"
|
||||||
|
UNITTEST_OK=false
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo -e "${GREEN}wfi "$edge" passt (exit code $EXIT_CODE)${NC}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
else
|
||||||
|
echo -e "${RED}wfis "$edge" failed - wrong exit code $EXIT_CODE${NC}"
|
||||||
|
UNITTEST_OK=false
|
||||||
|
fi
|
||||||
|
|
||||||
|
else # negativ
|
||||||
|
echo -e "${RED}wfis "$edge" failed (exit code $EXIT_CODE)${NC}"
|
||||||
|
UNITTEST_OK=false
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
gpio is40pin || { GPIOIN=17; GPIOOUT=18; echo "old 28 pin system"; }
|
||||||
|
|
||||||
|
|
||||||
|
echo
|
||||||
|
echo Unit test gpio GPIO${GPIOOUT} and GPIO${GPIOIN} - functions: mode, write, wfi
|
||||||
|
echo ------------------------------------------------------------------
|
||||||
|
echo
|
||||||
|
|
||||||
|
|
||||||
|
#prepare trigger out
|
||||||
|
gpio -g mode $GPIOOUT out
|
||||||
|
|
||||||
|
gpio -g write $GPIOOUT 0
|
||||||
|
wfi_test "rising" 0 0
|
||||||
|
|
||||||
|
gpio -g write $GPIOOUT 1
|
||||||
|
wfi_test "falling" 0 0
|
||||||
|
|
||||||
|
#wfi iteration test
|
||||||
|
|
||||||
|
gpio -g write $GPIOOUT 0
|
||||||
|
wfi_test "rising" 4 7
|
||||||
|
|
||||||
|
gpio -g write $GPIOOUT 1
|
||||||
|
wfi_test "falling" 4 8
|
||||||
|
|
||||||
|
gpio -g write $GPIOOUT 0
|
||||||
|
wfi_test "both" 4 4
|
||||||
|
|
||||||
|
gpio -g write $GPIOOUT 0
|
||||||
|
gpio -g mode $GPIOOUT in
|
||||||
|
|
||||||
|
### #wfi timeout test
|
||||||
|
gpio -g wfi $GPIOIN rising 2 4 &
|
||||||
|
GPIO_PID=$!
|
||||||
|
wait_with_timeout "$GPIO_PID" "$TIMEOUT"
|
||||||
|
EXIT_CODE=$?
|
||||||
|
echo
|
||||||
|
if [ $EXIT_CODE -eq 0 ]; then
|
||||||
|
echo -e "${GREEN}wfi timeout passed (exit code 0)${NC}"
|
||||||
|
else
|
||||||
|
echo -e "${RED}wfi timeout failed (code $EXIT_CODE)${NC}"
|
||||||
|
UNITTEST_OK=false
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
echo
|
||||||
|
echo Unit test gpio GPIO${GPIOOUT} and GPIO${GPIOIN} - functions: mode, write, wfis
|
||||||
|
echo ------------------------------------------------------------------
|
||||||
|
echo
|
||||||
|
|
||||||
|
#prepare trigger out
|
||||||
|
gpio -g mode $GPIOOUT out
|
||||||
|
|
||||||
|
gpio -g write $GPIOOUT 1
|
||||||
|
wfis_test "rising" 0 0 2
|
||||||
|
|
||||||
|
gpio -g write $GPIOOUT 0
|
||||||
|
wfis_test "falling" 0 0 1
|
||||||
|
|
||||||
|
gpio -g write $GPIOOUT 1
|
||||||
|
wfis_test "both" 0 0 1
|
||||||
|
|
||||||
|
gpio -g write $GPIOOUT 0
|
||||||
|
wfis_test "both" 0 0 2
|
||||||
|
|
||||||
|
|
||||||
|
#wfi iteration test
|
||||||
|
|
||||||
|
gpio -g write $GPIOOUT 0
|
||||||
|
wfis_test "rising" 4 7 2
|
||||||
|
|
||||||
|
gpio -g write $GPIOOUT 1
|
||||||
|
wfis_test "falling" 4 8 1
|
||||||
|
|
||||||
|
gpio -g write $GPIOOUT 0
|
||||||
|
wfis_test "both" 3 3 2
|
||||||
|
|
||||||
|
gpio -g write $GPIOOUT 1
|
||||||
|
wfis_test "both" 3 4 1
|
||||||
|
|
||||||
|
gpio -g write $GPIOOUT 0
|
||||||
|
gpio -g mode $GPIOOUT in
|
||||||
|
|
||||||
|
### #wfi timeout test
|
||||||
|
gpio -g wfis $GPIOIN rising $DEBOUNCE 2 4 &
|
||||||
|
GPIO_PID=$!
|
||||||
|
wait_with_timeout "$GPIO_PID" "$TIMEOUT"
|
||||||
|
EXIT_CODE=$?
|
||||||
|
echo
|
||||||
|
if [ $EXIT_CODE -eq 255 ]; then
|
||||||
|
echo -e "${GREEN}wfi timeout passed (exit code $EXIT_CODE)${NC}"
|
||||||
|
else
|
||||||
|
echo -e "${RED}wfi timeout failed (code $EXIT_CODE)${NC}"
|
||||||
|
UNITTEST_OK=false
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if [ ${UNITTEST_OK} = true ]; then
|
||||||
|
echo -e "\n\n${GREEN}Unit test result OK.${NC}"
|
||||||
|
exit 0
|
||||||
|
else
|
||||||
|
echo -e "\n\n${RED}Unit test result failed.${NC}"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
@@ -1,3 +1,3 @@
|
|||||||
#define VERSION "3.14"
|
#define VERSION "3.16"
|
||||||
#define VERSION_MAJOR 3
|
#define VERSION_MAJOR 3
|
||||||
#define VERSION_MINOR 14
|
#define VERSION_MINOR 16
|
||||||
|
|||||||
246
wiringPi/WiringpiV1.c
Normal file
246
wiringPi/WiringpiV1.c
Normal file
@@ -0,0 +1,246 @@
|
|||||||
|
#include "Wiringpi.h"
|
||||||
|
|
||||||
|
|
||||||
|
int requestLineV1(int pin, unsigned int lineRequestFlags) {
|
||||||
|
struct gpiohandle_request rq;
|
||||||
|
|
||||||
|
if (lineFds[pin]>=0) {
|
||||||
|
if (lineRequestFlags == lineFlags[pin]) {
|
||||||
|
//already requested
|
||||||
|
return lineFds[pin];
|
||||||
|
} else {
|
||||||
|
//different request -> rerequest
|
||||||
|
releaseLine(pin);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//requested line
|
||||||
|
if (wiringPiGpioDeviceGetFd()<0) {
|
||||||
|
return -1; // error
|
||||||
|
}
|
||||||
|
rq.lineoffsets[0] = pin;
|
||||||
|
rq.lines = 1;
|
||||||
|
rq.flags = 0;
|
||||||
|
// MAP to V1 Flag
|
||||||
|
if (lineRequestFlags & WPI_FLAG_INPUT) {
|
||||||
|
rq.flags |= GPIOHANDLE_REQUEST_INPUT;
|
||||||
|
}
|
||||||
|
if (lineRequestFlags & WPI_FLAG_OUTPUT) {
|
||||||
|
rq.flags |= GPIOHANDLE_REQUEST_OUTPUT;
|
||||||
|
}
|
||||||
|
if (lineRequestFlags & WPI_FLAG_BIAS_OFF) {
|
||||||
|
rq.flags |= GPIOHANDLE_REQUEST_BIAS_DISABLE;
|
||||||
|
}
|
||||||
|
if (lineRequestFlags & WPI_FLAG_BIAS_UP) {
|
||||||
|
rq.flags |= GPIOHANDLE_REQUEST_BIAS_PULL_UP;
|
||||||
|
}
|
||||||
|
if (lineRequestFlags & WPI_FLAG_BIAS_DOWN) {
|
||||||
|
rq.flags |= GPIOHANDLE_REQUEST_BIAS_PULL_DOWN;
|
||||||
|
}
|
||||||
|
int ret = ioctl(chipFd, GPIO_GET_LINEHANDLE_IOCTL, &rq);
|
||||||
|
if (ret || rq.fd<0) {
|
||||||
|
ReportDeviceError("get line handle", pin, "RequestLineV1", ret);
|
||||||
|
return -1; // error
|
||||||
|
}
|
||||||
|
|
||||||
|
lineFlags[pin] = lineRequestFlags;
|
||||||
|
lineFds[pin] = rq.fd;
|
||||||
|
if (wiringPiDebug)
|
||||||
|
printf ("requestLine succeeded: pin:%d, flags: %u, fd :%d\n", pin, lineRequestFlags, lineFds[pin]) ;
|
||||||
|
return lineFds[pin];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int digitalReadDeviceV1(int pin) { // INPUT and OUTPUT should work
|
||||||
|
|
||||||
|
if (lineFds[pin]<0) {
|
||||||
|
// line not requested - auto request on first read as input
|
||||||
|
pinModeDevice(pin, INPUT);
|
||||||
|
}
|
||||||
|
if (lineFds[pin]>=0) {
|
||||||
|
struct gpiohandle_data data;
|
||||||
|
int ret = ioctl(lineFds[pin], GPIOHANDLE_GET_LINE_VALUES_IOCTL, &data);
|
||||||
|
if (ret) {
|
||||||
|
ReportDeviceError("get line values", pin, "digitalRead", ret);
|
||||||
|
return LOW; // error
|
||||||
|
}
|
||||||
|
return data.values[0];
|
||||||
|
}
|
||||||
|
return LOW; // error , need to request line before
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void digitalWriteDeviceV1(int pin, int value) {
|
||||||
|
|
||||||
|
if (wiringPiDebug)
|
||||||
|
printf ("digitalWriteDevice: ioctl pin:%d value: %d\n", pin, value) ;
|
||||||
|
|
||||||
|
if (lineFds[pin]<0) {
|
||||||
|
// line not requested - auto request on first write as output
|
||||||
|
pinModeDevice(pin, OUTPUT);
|
||||||
|
}
|
||||||
|
if (lineFds[pin]>=0 && (lineFlags[pin] & GPIOHANDLE_REQUEST_OUTPUT)>0) {
|
||||||
|
struct gpiohandle_data data;
|
||||||
|
data.values[0] = value;
|
||||||
|
if (wiringPiDebug)
|
||||||
|
printf ("digitalWriteDevice: ioctl pin:%d cmd: GPIOHANDLE_SET_LINE_VALUES_IOCTL, value: %d\n", pin, value) ;
|
||||||
|
int ret = ioctl(lineFds[pin], GPIOHANDLE_SET_LINE_VALUES_IOCTL, &data);
|
||||||
|
if (ret) {
|
||||||
|
ReportDeviceError("set line values", pin, "digitalWrite", ret);
|
||||||
|
return; // error
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
fprintf(stderr, "digitalWrite: no output (%d)\n", lineFlags[pin]);
|
||||||
|
}
|
||||||
|
return; // error
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* waitForInterrupt:
|
||||||
|
* Pi Specific.
|
||||||
|
* Wait for Interrupt on a GPIO pin.
|
||||||
|
* This is actually done via the /dev/gpiochip interface regardless of
|
||||||
|
* the wiringPi access mode in-use. Maybe sometime it might get a better
|
||||||
|
* way for a bit more efficiency.
|
||||||
|
*********************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
int waitForInterruptV1(int pin, int mS)
|
||||||
|
{
|
||||||
|
int fd, ret;
|
||||||
|
struct pollfd polls ;
|
||||||
|
struct gpioevent_data evdata;
|
||||||
|
//struct gpio_v2_line_request req2;
|
||||||
|
|
||||||
|
if (wiringPiMode == WPI_MODE_PINS)
|
||||||
|
pin = pinToGpio [pin] ;
|
||||||
|
else if (wiringPiMode == WPI_MODE_PHYS)
|
||||||
|
pin = physToGpio [pin] ;
|
||||||
|
|
||||||
|
if ((fd = isrFds [pin]) == -1)
|
||||||
|
return -2 ;
|
||||||
|
|
||||||
|
// Setup poll structure
|
||||||
|
polls.fd = fd;
|
||||||
|
polls.events = POLLIN | POLLERR ;
|
||||||
|
polls.revents = 0;
|
||||||
|
|
||||||
|
// Wait for it ...
|
||||||
|
ret = poll(&polls, 1, mS);
|
||||||
|
if (ret <= 0) {
|
||||||
|
fprintf(stderr, "wiringPi: ERROR: poll returned=%d\n", ret);
|
||||||
|
} else {
|
||||||
|
//if (polls.revents & POLLIN)
|
||||||
|
if (wiringPiDebug) {
|
||||||
|
printf ("wiringPi: IRQ line %d received %d, fd=%d\n", pin, ret, isrFds[pin]) ;
|
||||||
|
}
|
||||||
|
/* read event data */
|
||||||
|
int readret = read(isrFds [pin], &evdata, sizeof(evdata));
|
||||||
|
if (readret == sizeof(evdata)) {
|
||||||
|
if (wiringPiDebug) {
|
||||||
|
printf ("wiringPi: IRQ data id: %d, timestamp: %lld\n", evdata.id, evdata.timestamp) ;
|
||||||
|
}
|
||||||
|
ret = evdata.id;
|
||||||
|
} else {
|
||||||
|
ret = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int waitForInterruptInitV1(int pin, int mode)
|
||||||
|
{
|
||||||
|
const char* strmode = "";
|
||||||
|
|
||||||
|
if (wiringPiMode == WPI_MODE_PINS) {
|
||||||
|
pin = pinToGpio [pin] ;
|
||||||
|
} else if (wiringPiMode == WPI_MODE_PHYS) {
|
||||||
|
pin = physToGpio [pin] ;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* open gpio */
|
||||||
|
sleep(1);
|
||||||
|
if (wiringPiGpioDeviceGetFd()<0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct gpioevent_request req;
|
||||||
|
req.lineoffset = pin;
|
||||||
|
req.handleflags = GPIOHANDLE_REQUEST_INPUT;
|
||||||
|
switch(mode) {
|
||||||
|
default:
|
||||||
|
case INT_EDGE_SETUP:
|
||||||
|
if (wiringPiDebug) {
|
||||||
|
printf ("wiringPi: waitForInterruptMode mode INT_EDGE_SETUP - exiting\n") ;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
case INT_EDGE_FALLING:
|
||||||
|
req.eventflags = GPIOEVENT_REQUEST_FALLING_EDGE;
|
||||||
|
strmode = "falling";
|
||||||
|
break;
|
||||||
|
case INT_EDGE_RISING:
|
||||||
|
req.eventflags = GPIOEVENT_REQUEST_RISING_EDGE;
|
||||||
|
strmode = "rising";
|
||||||
|
break;
|
||||||
|
case INT_EDGE_BOTH:
|
||||||
|
req.eventflags = GPIOEVENT_REQUEST_BOTH_EDGES;
|
||||||
|
strmode = "both";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
strncpy(req.consumer_label, "wiringpi_gpio_irq", sizeof(req.consumer_label) - 1);
|
||||||
|
|
||||||
|
//later implement GPIO_V2_GET_LINE_IOCTL req2
|
||||||
|
int ret = ioctl(chipFd, GPIO_GET_LINEEVENT_IOCTL, &req);
|
||||||
|
if (ret) {
|
||||||
|
ReportDeviceError("get line event", pin , strmode, ret);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (wiringPiDebug) {
|
||||||
|
printf ("wiringPi: GPIO get line %d , mode %s succeded, fd=%d\n", pin, strmode, req.fd) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* set event fd nonbloack read */
|
||||||
|
int fd_line = req.fd;
|
||||||
|
isrFds [pin] = fd_line;
|
||||||
|
int flags = fcntl(fd_line, F_GETFL);
|
||||||
|
flags |= O_NONBLOCK;
|
||||||
|
ret = fcntl(fd_line, F_SETFL, flags);
|
||||||
|
if (ret) {
|
||||||
|
fprintf(stderr, "wiringPi: ERROR: fcntl set nonblock return=%d\n", ret);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int waitForInterruptClose (int pin) {
|
||||||
|
if (isrFds[pin]>0) {
|
||||||
|
if (wiringPiDebug) {
|
||||||
|
printf ("wiringPi: waitForInterruptClose close thread 0x%lX\n", (unsigned long)isrThreads[pin]) ;
|
||||||
|
}
|
||||||
|
if (pthread_cancel(isrThreads[pin]) == 0) {
|
||||||
|
if (wiringPiDebug) {
|
||||||
|
printf ("wiringPi: waitForInterruptClose thread canceled successfuly\n") ;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (wiringPiDebug) {
|
||||||
|
fprintf (stderr, "wiringPi: waitForInterruptClose could not cancel thread\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
close(isrFds [pin]);
|
||||||
|
}
|
||||||
|
isrFds [pin] = -1;
|
||||||
|
isrFunctions [pin] = NULL;
|
||||||
|
|
||||||
|
/* -not closing so far - other isr may be using it - only close if no other is using - will code later
|
||||||
|
if (chipFd>0) {
|
||||||
|
close(chipFd);
|
||||||
|
}
|
||||||
|
chipFd = -1;
|
||||||
|
*/
|
||||||
|
if (wiringPiDebug) {
|
||||||
|
printf ("wiringPi: waitForInterruptClose finished\n") ;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
@@ -3,7 +3,7 @@ CFLAGS = -Wall
|
|||||||
LDFLAGS =
|
LDFLAGS =
|
||||||
|
|
||||||
# Need BCM19 <-> BCM26, +PWM: BCM12 <-> BCM13, BCM18 <-> BCM17 connected (1kOhm)
|
# Need BCM19 <-> BCM26, +PWM: BCM12 <-> BCM13, BCM18 <-> BCM17 connected (1kOhm)
|
||||||
tests = wiringpi_test0_version wiringpi_test1_sysfs wiringpi_test2_sysfs wiringpi_test3_device_wpi wiringpi_test4_device_phys wiringpi_test5_default wiringpi_test6_isr wiringpi_test7_bench wiringpi_test8_pwm wiringpi_test9_pwm
|
tests = wiringpi_test0_version wiringpi_test1_sysfs wiringpi_test2_sysfs wiringpi_test3_device_wpi wiringpi_test4_device_phys wiringpi_test5_default wiringpi_test6_isr wiringpi_test61_isr2 wiringpi_test62_isr_wpin wiringpi_test7_bench wiringpi_test8_pwm wiringpi_test9_pwm
|
||||||
|
|
||||||
# Need XO hardware
|
# Need XO hardware
|
||||||
xotests = wiringpi_xotest_test1_spi wiringpi_i2c_test1_pcf8574 wiringpi_test8_pwm wiringpi_test9_pwm
|
xotests = wiringpi_xotest_test1_spi wiringpi_i2c_test1_pcf8574 wiringpi_test8_pwm wiringpi_test9_pwm
|
||||||
@@ -34,6 +34,12 @@ wiringpi_test5_default:
|
|||||||
wiringpi_test6_isr:
|
wiringpi_test6_isr:
|
||||||
${CC} ${CFLAGS} wiringpi_test6_isr.c -o wiringpi_test6_isr -lwiringPi
|
${CC} ${CFLAGS} wiringpi_test6_isr.c -o wiringpi_test6_isr -lwiringPi
|
||||||
|
|
||||||
|
wiringpi_test61_isr2:
|
||||||
|
${CC} ${CFLAGS} wiringpi_test61_isr2.c -o wiringpi_test61_isr2 -lwiringPi
|
||||||
|
|
||||||
|
wiringpi_test62_isr_wpin:
|
||||||
|
${CC} ${CFLAGS} wiringpi_test62_isr_wpin.c -o wiringpi_test62_isr_wpin -lwiringPi
|
||||||
|
|
||||||
wiringpi_test7_bench:
|
wiringpi_test7_bench:
|
||||||
${CC} ${CFLAGS} wiringpi_test7_bench.c -o wiringpi_test7_bench -lwiringPi
|
${CC} ${CFLAGS} wiringpi_test7_bench.c -o wiringpi_test7_bench -lwiringPi
|
||||||
|
|
||||||
|
|||||||
@@ -52,6 +52,7 @@ int main (void) {
|
|||||||
delayMicroseconds(600000);
|
delayMicroseconds(600000);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//Error wrong direction - only for fun
|
//Error wrong direction - only for fun
|
||||||
digitalWrite(GPIO, LOW);
|
digitalWrite(GPIO, LOW);
|
||||||
|
|
||||||
|
|||||||
279
wiringPi/test/wiringpi_test61_isr2.c
Normal file
279
wiringPi/test/wiringpi_test61_isr2.c
Normal file
@@ -0,0 +1,279 @@
|
|||||||
|
// WiringPi test program: 6.1 new ISR2 function with Kernel char device interface / sysfs successor
|
||||||
|
// Compile: gcc -Wall wiringpi_test61_isr2.c -o wiringpi_test61_isr2 -lwiringPi
|
||||||
|
|
||||||
|
#include "wpi_test.h"
|
||||||
|
#include <string.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
|
||||||
|
|
||||||
|
int GPIO = 19;
|
||||||
|
int GPIOIN = 26;
|
||||||
|
const int ToggleValue = 4;
|
||||||
|
float irq_timstamp_duration_ms = 0;
|
||||||
|
float accuracy = 0.015;
|
||||||
|
float bounce_acc = 1.0;
|
||||||
|
|
||||||
|
static volatile int globalCounter;
|
||||||
|
volatile long long gStartTime, gEndTime;
|
||||||
|
struct WPIWfiStatus wfiStatusOld;
|
||||||
|
|
||||||
|
static void ISR(void) {
|
||||||
|
struct timeval now;
|
||||||
|
|
||||||
|
gettimeofday(&now, 0);
|
||||||
|
if (0==gStartTime) {
|
||||||
|
gStartTime = now.tv_sec*1000000LL + now.tv_usec;
|
||||||
|
} else {
|
||||||
|
gEndTime = now.tv_sec*1000000LL + now.tv_usec;
|
||||||
|
}
|
||||||
|
globalCounter++;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static void ISR2(struct WPIWfiStatus wfiStatus, void* userdata) {
|
||||||
|
struct timeval now;
|
||||||
|
char strEdge[3][10] = {"unknown", "falling", "raising"};
|
||||||
|
int strEdgeidx = 0; //default
|
||||||
|
int* localCounter = (int*) userdata;
|
||||||
|
|
||||||
|
gettimeofday(&now, 0);
|
||||||
|
if (0==gStartTime) {
|
||||||
|
gStartTime = now.tv_sec*1000000LL + now.tv_usec;
|
||||||
|
} else {
|
||||||
|
gEndTime = now.tv_sec*1000000LL + now.tv_usec;
|
||||||
|
}
|
||||||
|
globalCounter++;
|
||||||
|
if (localCounter) {
|
||||||
|
(*localCounter)++;
|
||||||
|
}
|
||||||
|
switch(wfiStatus.edge) {
|
||||||
|
case INT_EDGE_FALLING: strEdgeidx = INT_EDGE_FALLING; break;
|
||||||
|
case INT_EDGE_RISING: strEdgeidx = INT_EDGE_RISING; break;
|
||||||
|
}
|
||||||
|
if (wfiStatusOld.statusOK>0 && wfiStatusOld.pinBCM==wfiStatus.pinBCM) {
|
||||||
|
irq_timstamp_duration_ms = (wfiStatus.timeStamp_us - wfiStatusOld.timeStamp_us) / 1000.0f;
|
||||||
|
} else {
|
||||||
|
irq_timstamp_duration_ms = 0.0f;
|
||||||
|
}
|
||||||
|
printf("ISR occured @ %lld us: statusOK=%d, pin=%u, edge=%s (%d), duration=%g ms, userdata=%p\n",
|
||||||
|
wfiStatus.timeStamp_us, wfiStatus.statusOK, wfiStatus.pinBCM, strEdge[strEdgeidx], wfiStatus.edge, irq_timstamp_duration_ms, userdata);
|
||||||
|
wfiStatusOld = wfiStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void digitalWriteBounce(int OUTpin, int value, int bounce) {
|
||||||
|
digitalWrite(OUTpin, value);
|
||||||
|
if (bounce>0) {
|
||||||
|
delay(1);
|
||||||
|
digitalWrite(OUTpin, !value);
|
||||||
|
delay(1);
|
||||||
|
digitalWrite(OUTpin, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DelayAndSumDuration(int ms, float* irq_timstamp_sum, const int doSum) {
|
||||||
|
delay(20);
|
||||||
|
if (doSum) {
|
||||||
|
*irq_timstamp_sum += irq_timstamp_duration_ms;
|
||||||
|
}
|
||||||
|
delay(ms-20);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
double StartSequence2(int Edge, int OUTpin, int INpin, int bounce, int* localCounter) {
|
||||||
|
int expected;
|
||||||
|
float timeExpected_ms;
|
||||||
|
float irq_timstamp_sum = 0.0f;
|
||||||
|
|
||||||
|
gStartTime = 0;
|
||||||
|
gEndTime = 0;
|
||||||
|
globalCounter = 0;
|
||||||
|
*localCounter = 0;
|
||||||
|
printf("Start\n");
|
||||||
|
digitalWriteBounce(OUTpin, HIGH, bounce);
|
||||||
|
delay(200);
|
||||||
|
|
||||||
|
digitalWriteBounce(OUTpin, LOW, bounce);
|
||||||
|
DelayAndSumDuration(100, &irq_timstamp_sum, INT_EDGE_BOTH == Edge);
|
||||||
|
|
||||||
|
digitalWriteBounce(OUTpin, HIGH, bounce);
|
||||||
|
DelayAndSumDuration(200, &irq_timstamp_sum, INT_EDGE_RISING == Edge || INT_EDGE_BOTH == Edge);
|
||||||
|
|
||||||
|
digitalWriteBounce(OUTpin, LOW, bounce);
|
||||||
|
DelayAndSumDuration(100, &irq_timstamp_sum, INT_EDGE_FALLING == Edge || INT_EDGE_BOTH == Edge);
|
||||||
|
|
||||||
|
printf("Stop\n");
|
||||||
|
int globalCounterCopy = globalCounter;
|
||||||
|
|
||||||
|
if (INT_EDGE_BOTH == Edge) {
|
||||||
|
expected = 4;
|
||||||
|
timeExpected_ms = bounce ? 508: 500;
|
||||||
|
} else {
|
||||||
|
expected = 2;
|
||||||
|
timeExpected_ms = bounce ? 304: 300;
|
||||||
|
}
|
||||||
|
|
||||||
|
CheckSame("Global counted IRQ", globalCounter, expected);
|
||||||
|
CheckSame("Userdata pointer / Local counted IRQ ", *localCounter, expected);
|
||||||
|
|
||||||
|
if (globalCounter==expected) {
|
||||||
|
char str[1024];
|
||||||
|
float fTime = (gEndTime - gStartTime) / 1000.0;
|
||||||
|
sprintf(str, "IRQ measured %g msec (~%g expected)", fTime, timeExpected_ms);
|
||||||
|
CheckSameFloat(str, fTime, timeExpected_ms, timeExpected_ms*accuracy);
|
||||||
|
sprintf(str, "IRQ timestamp %g msec (~%g expected)", irq_timstamp_sum, timeExpected_ms);
|
||||||
|
CheckSameFloat(str, irq_timstamp_sum, timeExpected_ms, timeExpected_ms*accuracy);
|
||||||
|
// new data struct
|
||||||
|
CheckSame("GPIO IRQ pin", wfiStatusOld.pinBCM, INpin);
|
||||||
|
if (INT_EDGE_FALLING==Edge || INT_EDGE_RISING==Edge) {
|
||||||
|
CheckSame("GPIO IRQ edge", wfiStatusOld.edge, Edge);
|
||||||
|
}
|
||||||
|
CheckSame("GPIO IRQ status", wfiStatusOld.statusOK, 1);
|
||||||
|
return fTime;
|
||||||
|
} else {
|
||||||
|
printf("IRQ not worked got %d iterations (%d exprected)\n\n", globalCounterCopy, expected);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
double DurationTime(int Enge, int OUTpin, int IRQpin, int bounce) {
|
||||||
|
struct timeval now;
|
||||||
|
double fTime = 0.0;
|
||||||
|
const char* strOp = INT_EDGE_RISING == Enge ? "rising" : "fallling";
|
||||||
|
gStartTime = 0;
|
||||||
|
gEndTime = 0;
|
||||||
|
globalCounter = 0;
|
||||||
|
//printf("Start\n");
|
||||||
|
|
||||||
|
digitalWrite(OUTpin, INT_EDGE_RISING == Enge ? LOW : HIGH);
|
||||||
|
if (bounce>=0) {
|
||||||
|
printf("\nnew function, bounce time %d ms, %s :\n", bounce, strOp);
|
||||||
|
wiringPiISR2(IRQpin, Enge, &ISR2, bounce*1000, NULL);
|
||||||
|
} else {
|
||||||
|
printf("\nclassic function, %s :\n", strOp);
|
||||||
|
wiringPiISR(IRQpin, Enge, &ISR);
|
||||||
|
}
|
||||||
|
sleep(1);
|
||||||
|
gettimeofday(&now, 0);
|
||||||
|
gStartTime = now.tv_sec*1000000LL + now.tv_usec;
|
||||||
|
digitalWrite(OUTpin, INT_EDGE_RISING == Enge ? HIGH : LOW);
|
||||||
|
delay(20);
|
||||||
|
digitalWrite(OUTpin, LOW);
|
||||||
|
delay(20);
|
||||||
|
fTime = (gEndTime - gStartTime);
|
||||||
|
if (bounce<=0) {
|
||||||
|
printf("IRQ detection time %g usec", fTime);
|
||||||
|
} else {
|
||||||
|
printf("IRQ detection time %.1f msec", fTime/1000.0);
|
||||||
|
}
|
||||||
|
if (bounce>=0) {
|
||||||
|
// bounce time + 7ms (addtional bounce time) + 100 us (basic time)
|
||||||
|
CheckBetween("IRQ detection time with bounce [us]", fTime, 0, bounce*1000+ (bounce>0 ? 7000*bounce_acc : 0)+(100*bounce_acc));
|
||||||
|
} else {
|
||||||
|
CheckBetween("IRQ detection time [us]", fTime, 0, 100*bounce_acc);
|
||||||
|
}
|
||||||
|
wiringPiISRStop(IRQpin);
|
||||||
|
//printf("Stop\n");
|
||||||
|
return fTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int main (void) {
|
||||||
|
|
||||||
|
int major=0, minor=0;
|
||||||
|
|
||||||
|
wiringPiVersion(&major, &minor);
|
||||||
|
|
||||||
|
int _is40pin = piBoard40Pin();
|
||||||
|
CheckNotSame("40-Pin board: ", _is40pin, -1);
|
||||||
|
if (_is40pin==0) {
|
||||||
|
printf("Old 28pin system\n");
|
||||||
|
//GPIO = 23;
|
||||||
|
//GPIOIN = 24;
|
||||||
|
GPIO = 17;
|
||||||
|
GPIOIN = 18;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("WiringPi GPIO test program 6.2 (using GPIO%d (output) and GPIO%d (input))\n", GPIO, GPIOIN);
|
||||||
|
printf("ISR and ISR2 test (WiringPi %d.%d)\n", major, minor);
|
||||||
|
|
||||||
|
wiringPiSetupGpio();
|
||||||
|
|
||||||
|
int RaspberryPiModel, rev, mem, maker, overVolted;
|
||||||
|
piBoardId(&RaspberryPiModel, &rev, &mem, &maker, &overVolted);
|
||||||
|
CheckNotSame("Model: ", RaspberryPiModel, -1);
|
||||||
|
switch(RaspberryPiModel) {
|
||||||
|
case PI_MODEL_A:
|
||||||
|
case PI_MODEL_B: //ARM=800MHz
|
||||||
|
case PI_MODEL_BP:
|
||||||
|
case PI_MODEL_AP:
|
||||||
|
case PI_MODEL_CM:
|
||||||
|
accuracy = 0.02;
|
||||||
|
bounce_acc = 2.7;
|
||||||
|
break;
|
||||||
|
case PI_MODEL_ZERO:
|
||||||
|
case PI_MODEL_ZERO_W: //ARM=1000MHz
|
||||||
|
accuracy = 0.02;
|
||||||
|
bounce_acc = 2.7;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
accuracy = 0.012;
|
||||||
|
bounce_acc = 1.0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
int IRQpin = GPIOIN;
|
||||||
|
int OUTpin = GPIO;
|
||||||
|
|
||||||
|
//wiringPiISR2(13, INT_EDGE_RISING, &ISR2, 0); // next pin
|
||||||
|
int localCounter;
|
||||||
|
memset(&wfiStatusOld, 0, sizeof(wfiStatusOld));
|
||||||
|
|
||||||
|
pinMode(IRQpin, INPUT);
|
||||||
|
pinMode(OUTpin, OUTPUT);
|
||||||
|
digitalWrite (OUTpin, LOW) ;
|
||||||
|
|
||||||
|
for (int bounce=0; bounce<=1; bounce++) {
|
||||||
|
unsigned long bouncetime = 0;
|
||||||
|
if (0==bounce) {
|
||||||
|
printf("! --- default test (no bounce) --- !\n");
|
||||||
|
} else {
|
||||||
|
bouncetime = 2000; //2 ms
|
||||||
|
printf("! --- test with bounce on input --- !\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("\nTesting IRQ @ GPIO%d with trigger @ GPIO%d rising\n", IRQpin, OUTpin);
|
||||||
|
wiringPiISR2(IRQpin, INT_EDGE_RISING, &ISR2, bouncetime, &localCounter);
|
||||||
|
sleep(1);
|
||||||
|
StartSequence2(INT_EDGE_RISING, OUTpin, IRQpin, bounce, &localCounter);
|
||||||
|
printf("Stopp IRQ\n");
|
||||||
|
wiringPiISRStop(IRQpin);
|
||||||
|
|
||||||
|
printf("\nTesting IRQ @ GPIO%d with trigger @ GPIO%d falling\n", IRQpin, OUTpin);
|
||||||
|
wiringPiISR2(IRQpin, INT_EDGE_FALLING, &ISR2, bouncetime, &localCounter);
|
||||||
|
sleep(1);
|
||||||
|
StartSequence2(INT_EDGE_FALLING, OUTpin, IRQpin, bounce, &localCounter);
|
||||||
|
printf("Stopp IRQ\n");
|
||||||
|
wiringPiISRStop(IRQpin);
|
||||||
|
|
||||||
|
printf("\nTesting IRQ @ GPIO%d with trigger @ GPIO%d both\n", IRQpin, OUTpin);
|
||||||
|
wiringPiISR2(IRQpin, INT_EDGE_BOTH, &ISR2, bouncetime, &localCounter);
|
||||||
|
sleep(1);
|
||||||
|
StartSequence2(INT_EDGE_BOTH, OUTpin, IRQpin, bounce, &localCounter);
|
||||||
|
printf("Stopp IRQ\n");
|
||||||
|
wiringPiISRStop(IRQpin);
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("Measuring duration IRQ @ GPIO%d with trigger @ GPIO%d rising and falling\n", IRQpin, OUTpin);
|
||||||
|
for (int bounce=-1; bounce<=5; bounce++) {
|
||||||
|
DurationTime(INT_EDGE_RISING, OUTpin, IRQpin, bounce);
|
||||||
|
DurationTime(INT_EDGE_FALLING, OUTpin, IRQpin, bounce);
|
||||||
|
}
|
||||||
|
pinMode(OUTpin, INPUT);
|
||||||
|
|
||||||
|
return UnitTestState();
|
||||||
|
}
|
||||||
129
wiringPi/test/wiringpi_test62_isr_wpin.c
Normal file
129
wiringPi/test/wiringpi_test62_isr_wpin.c
Normal file
@@ -0,0 +1,129 @@
|
|||||||
|
// WiringPi test program: Kernel char device interface / sysfs successor
|
||||||
|
// Compile: gcc -Wall wiringpi_test62_isr_wpin.c -o wiringpi_test62_isr_wpin -lwiringPi
|
||||||
|
|
||||||
|
#include "wpi_test.h"
|
||||||
|
#include <string.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
|
||||||
|
//WPI pin numbers
|
||||||
|
int GPIO = 28;
|
||||||
|
int GPIOIN = 29;
|
||||||
|
|
||||||
|
static volatile int globalCounter;
|
||||||
|
|
||||||
|
|
||||||
|
static void wfiup(void) {
|
||||||
|
|
||||||
|
globalCounter++;
|
||||||
|
printf("I[%d] ", globalCounter);
|
||||||
|
fflush(stdout);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void wfidown(void) {
|
||||||
|
|
||||||
|
globalCounter--;
|
||||||
|
printf("I[%d] ", globalCounter);
|
||||||
|
fflush(stdout);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void StartSequence (int Enge, int OUTpin, int count,int expected) {
|
||||||
|
/*
|
||||||
|
int expected = up ? count : 0;
|
||||||
|
globalCounter = up ? 0 : count;
|
||||||
|
*/
|
||||||
|
globalCounter = 0;
|
||||||
|
|
||||||
|
printf("Start: ");
|
||||||
|
fflush(stdout);
|
||||||
|
for (int loop=0; loop<count; ++loop) {
|
||||||
|
printf("H");
|
||||||
|
digitalWrite(OUTpin, HIGH);
|
||||||
|
printf("."); fflush(stdout);
|
||||||
|
delay(200);
|
||||||
|
printf("L");
|
||||||
|
digitalWrite(OUTpin, LOW);
|
||||||
|
delay(100);
|
||||||
|
printf("."); fflush(stdout);
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
|
||||||
|
CheckSame("IRQ count", globalCounter, expected);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int main (void) {
|
||||||
|
|
||||||
|
int major, minor;
|
||||||
|
|
||||||
|
wiringPiVersion(&major, &minor);
|
||||||
|
|
||||||
|
printf("WiringPi GPIO test program 6.2 (using GPIO%d (output) and GPIO%d (input))\n", GPIO, GPIOIN);
|
||||||
|
printf(" testing irq with WPI pin numbers > 28\n");
|
||||||
|
|
||||||
|
printf("\nWiringPi %d.%d\n", major, minor);
|
||||||
|
|
||||||
|
//printf("Error check - next call create fatal error with exit!\n");
|
||||||
|
//CheckSame("wiringPiISRStop with wrong pin, result code:", wiringPiISRStop(5), 0);
|
||||||
|
|
||||||
|
CheckSame("wiringPiSetupPinType(WPI_PIN_WPI)", wiringPiSetupPinType(WPI_PIN_WPI), 0);
|
||||||
|
|
||||||
|
int rev, mem, maker, overVolted, RaspberryPiModel;
|
||||||
|
piBoardId(&RaspberryPiModel, &rev, &mem, &maker, &overVolted);
|
||||||
|
|
||||||
|
CheckNotSame("piBoardId", RaspberryPiModel, 0);
|
||||||
|
|
||||||
|
int _is40pin = piBoard40Pin();
|
||||||
|
CheckNotSame("is40pin", _is40pin, -1);
|
||||||
|
|
||||||
|
if (_is40pin==1) {
|
||||||
|
|
||||||
|
int IRQpin = GPIOIN;
|
||||||
|
int OUTpin = GPIO;
|
||||||
|
|
||||||
|
pinMode(IRQpin, INPUT);
|
||||||
|
pinMode(OUTpin, OUTPUT);
|
||||||
|
digitalWrite(OUTpin, LOW);
|
||||||
|
delayMicroseconds(100);
|
||||||
|
CheckSame("Input", digitalRead(IRQpin), LOW);
|
||||||
|
digitalWrite(OUTpin, HIGH);
|
||||||
|
delayMicroseconds(100);
|
||||||
|
if (digitalRead(IRQpin)==HIGH) {
|
||||||
|
digitalWrite(OUTpin, LOW);
|
||||||
|
delayMicroseconds(100);
|
||||||
|
|
||||||
|
printf("\nTesting IRQ @ WPI-GPIO%d with trigger @ WPI-GPIO%d rising\n", IRQpin, OUTpin);
|
||||||
|
CheckSame("wiringPiISR", wiringPiISR(IRQpin, INT_EDGE_RISING, &wfiup), 0);
|
||||||
|
sleep(1);
|
||||||
|
StartSequence(INT_EDGE_RISING, OUTpin, 3 , 3);
|
||||||
|
sleep(1);
|
||||||
|
CheckSame("wiringPiISRStop", wiringPiISRStop(IRQpin), 0);
|
||||||
|
printf("\n.IRQ off\n");
|
||||||
|
sleep(1);
|
||||||
|
StartSequence(INT_EDGE_RISING, OUTpin, 2, 0);
|
||||||
|
|
||||||
|
printf("\nTesting IRQ @ WPI-GPIO%d with trigger @ WPI-GPIO%d falling\n", IRQpin, OUTpin);
|
||||||
|
CheckSame("wiringPiISR", wiringPiISR(IRQpin, INT_EDGE_RISING, &wfidown), 0);
|
||||||
|
sleep(1);
|
||||||
|
StartSequence(INT_EDGE_FALLING, OUTpin, 4, -4);
|
||||||
|
sleep(1);
|
||||||
|
CheckSame("wiringPiISRStop", wiringPiISRStop(IRQpin), 0);
|
||||||
|
printf("\n.IRQ off\n");
|
||||||
|
sleep(1);
|
||||||
|
StartSequence(INT_EDGE_RISING, OUTpin, 2, 0);
|
||||||
|
|
||||||
|
printf("Error check - next call must be wrong!\n");
|
||||||
|
CheckSame("wiringPiISRStop with wrong pin, result code:", wiringPiISRStop(5555), EINVAL);
|
||||||
|
} else {
|
||||||
|
printf("Hardware connection for unit test missing!\n");
|
||||||
|
printf("unit test, need connection between Wiringpi pin 28 and 29!\n");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
printf("unit test is for 40-pin hardware only!\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
return UnitTestState();
|
||||||
|
}
|
||||||
@@ -66,7 +66,7 @@ int main (void) {
|
|||||||
case PI_MODEL_ZERO_W: //ARM=1000MHz
|
case PI_MODEL_ZERO_W: //ARM=1000MHz
|
||||||
fExpectTimedigitalWrite = 0.104; //us;
|
fExpectTimedigitalWrite = 0.104; //us;
|
||||||
fExpectTimedigitalRead = 0.135; //us
|
fExpectTimedigitalRead = 0.135; //us
|
||||||
fExpectTimepinMode = 0.250; //us
|
fExpectTimepinMode = 0.360; //us
|
||||||
break;
|
break;
|
||||||
case PI_MODEL_2:
|
case PI_MODEL_2:
|
||||||
ToggleValue /= 4;
|
ToggleValue /= 4;
|
||||||
|
|||||||
@@ -135,7 +135,7 @@ int main (void) {
|
|||||||
pinMode(PWM, PWM_OUTPUT); //Mode BAL, pwmr=1024, pwmc=32
|
pinMode(PWM, PWM_OUTPUT); //Mode BAL, pwmr=1024, pwmc=32
|
||||||
printf("pwmc 4.8kHz\n");
|
printf("pwmc 4.8kHz\n");
|
||||||
pwmSetClock(2000);
|
pwmSetClock(2000);
|
||||||
delay(250);
|
delay(1000);
|
||||||
|
|
||||||
printf("Register ISR@%d\n", PWM);
|
printf("Register ISR@%d\n", PWM);
|
||||||
// INT_EDGE_BOTH, INT_EDGE_FALLING, INT_EDGE_RISING only one ISR per input
|
// INT_EDGE_BOTH, INT_EDGE_FALLING, INT_EDGE_RISING only one ISR per input
|
||||||
|
|||||||
@@ -94,6 +94,15 @@ void CheckNotSame(const char* msg, int value, int expect) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CheckBetween(const char* msg, int value, int min, int max) {
|
||||||
|
if (value>=min && value<=max) {
|
||||||
|
printf("%39s (% 3d< % 3d <% 3d) -> %spassed%s\n", msg, min, value, max, COLORGRN, COLORDEF);
|
||||||
|
} else {
|
||||||
|
printf("%39s (% 3d< % 3d <% 3d) -> %sfailed%s\n", msg, min, value, max, COLORRED, COLORDEF);
|
||||||
|
globalError=1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void CheckSameFloat(const char* msg, float value, float expect, float epsilon) {
|
void CheckSameFloat(const char* msg, float value, float expect, float epsilon) {
|
||||||
if (fabs(value-expect)<epsilon) {
|
if (fabs(value-expect)<epsilon) {
|
||||||
@@ -104,10 +113,21 @@ void CheckSameFloat(const char* msg, float value, float expect, float epsilon) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void CheckSameFloatX(const char* msg, float value, float expect) {
|
void CheckSameFloatX(const char* msg, float value, float expect) {
|
||||||
return CheckSameFloat(msg, value, expect, 0.08f);
|
return CheckSameFloat(msg, value, expect, 0.08f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void CheckBetweenDouble(const char* msg, double value, double min, double max) {
|
||||||
|
if (value>=min && value<=max) {
|
||||||
|
printf("%39s (%g< %g <%g) -> %spassed%s\n", msg, min, value, max, COLORGRN, COLORDEF);
|
||||||
|
} else {
|
||||||
|
printf("%39s (%g< %g <%g) -> %sfailed%s\n", msg, min, value, max, COLORRED, COLORDEF);
|
||||||
|
globalError=1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void CheckSameDouble(const char* msg, double value, double expect, double epsilon) {
|
void CheckSameDouble(const char* msg, double value, double expect, double epsilon) {
|
||||||
if (fabs(value-expect)<epsilon) {
|
if (fabs(value-expect)<epsilon) {
|
||||||
printf("%35s (%.3f==%.3f) -> %spassed%s \n", msg, value, expect, COLORGRN, COLORDEF);
|
printf("%35s (%.3f==%.3f) -> %spassed%s \n", msg, value, expect, COLORGRN, COLORDEF);
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -144,6 +144,7 @@ extern const char *piRevisionNames [16] ;
|
|||||||
extern const char *piMakerNames [16] ;
|
extern const char *piMakerNames [16] ;
|
||||||
extern const int piMemorySize [ 8] ;
|
extern const int piMemorySize [ 8] ;
|
||||||
|
|
||||||
|
|
||||||
// Intended for the GPIO program Use at your own risk.
|
// Intended for the GPIO program Use at your own risk.
|
||||||
|
|
||||||
// Threads
|
// Threads
|
||||||
@@ -280,8 +281,8 @@ extern int piBoardRev (void) ; // Deprecated, but does the sa
|
|||||||
extern void piBoardId (int *model, int *rev, int *mem, int *maker, int *overVolted) ;
|
extern void piBoardId (int *model, int *rev, int *mem, int *maker, int *overVolted) ;
|
||||||
extern int piBoard40Pin (void) ; // Interface V3.7
|
extern int piBoard40Pin (void) ; // Interface V3.7
|
||||||
extern int piRP1Model (void) ; // Interface V3.14
|
extern int piRP1Model (void) ; // Interface V3.14
|
||||||
extern int wpiPinToGpio (int wpiPin) ;
|
extern int wpiPinToGpio (int wpiPin) ; // please don't use outside 0-63 and on RP1
|
||||||
extern int physPinToGpio (int physPin) ;
|
extern int physPinToGpio (int physPin) ; // please don't use outside 0-63 and on RP1
|
||||||
extern void setPadDrive (int group, int value) ;
|
extern void setPadDrive (int group, int value) ;
|
||||||
extern void setPadDrivePin (int pin, int value); // Interface V3.0
|
extern void setPadDrivePin (int pin, int value); // Interface V3.0
|
||||||
extern int getAlt (int pin) ;
|
extern int getAlt (int pin) ;
|
||||||
@@ -296,12 +297,20 @@ extern void digitalWriteByte (int value) ;
|
|||||||
extern void digitalWriteByte2 (int value) ;
|
extern void digitalWriteByte2 (int value) ;
|
||||||
|
|
||||||
// Interrupts
|
// Interrupts
|
||||||
// (Also Pi hardware specific)
|
// status returned from waitForInterruptV2 V3.16
|
||||||
|
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
|
||||||
|
};
|
||||||
|
|
||||||
extern int waitForInterrupt (int pin, int mS) ;
|
//extern int waitForInterrupt (int pin, int ms); unknown if still working, disabled for V3.16, please contact developer via github
|
||||||
extern int wiringPiISR (int pin, int mode, void (*function)(void)) ;
|
extern int wiringPiISR (int pin, int mode, void (*function)(void)) ;
|
||||||
|
extern struct WPIWfiStatus waitForInterrupt2(int pin, int edgeMode, int ms, unsigned long debounce_period_us) ; // V3.16
|
||||||
|
extern int wiringPiISR2 (int pin, int edgeMode, void (*function)(struct WPIWfiStatus wfiStatus, void* userdata), unsigned long debounce_period_us, void* userdata) ; // V3.16
|
||||||
extern int wiringPiISRStop (int pin) ; //V3.2
|
extern int wiringPiISRStop (int pin) ; //V3.2
|
||||||
extern int waitForInterruptClose(int pin) ; //V3.2
|
extern int waitForInterruptClose(int pin) ; //V3.2 legacy use wiringPiISRStop
|
||||||
|
|
||||||
// Threads
|
// Threads
|
||||||
|
|
||||||
@@ -315,8 +324,8 @@ extern int piHiPri (const int pri) ;
|
|||||||
|
|
||||||
// Extras from arduino land
|
// Extras from arduino land
|
||||||
|
|
||||||
extern void delay (unsigned int howLong) ;
|
extern void delay (unsigned int ms) ;
|
||||||
extern void delayMicroseconds (unsigned int howLong) ;
|
extern void delayMicroseconds (unsigned int us) ;
|
||||||
extern unsigned int millis (void) ;
|
extern unsigned int millis (void) ;
|
||||||
extern unsigned int micros (void) ;
|
extern unsigned int micros (void) ;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user