Merge pull request #318 from phylax2020/development
Upgrade to GPIO_V2 IOCTL with debounce option
This commit is contained in:
@@ -20,13 +20,13 @@ sudo apt install git
|
||||
git clone https://github.com/WiringPi/WiringPi.git
|
||||
cd WiringPi
|
||||
./build debian
|
||||
mv debian-template/wiringpi-3.0-1.deb .
|
||||
mv debian-template/wiringpi-3.13.deb .
|
||||
```
|
||||
|
||||
**Debian-Paket installieren:**
|
||||
|
||||
```bash
|
||||
sudo apt install ./wiringpi-3.0-1.deb
|
||||
sudo apt install ./wiringpi-3.13.deb
|
||||
```
|
||||
|
||||
**Debian-Paket deinstallieren:**
|
||||
@@ -291,21 +291,27 @@ Registriert eine Interrupt Service Routine (ISR) bzw. Funktion die bei Flankenwe
|
||||
|
||||
>>>
|
||||
```C
|
||||
int wiringPiISR(int pin, int mode, void (*function)(void));
|
||||
int wiringPiISR(int pin, int edgeMode, void (*function)(unsigned int, long long int), unsigned long bouncetime);
|
||||
```
|
||||
|
||||
``pin``: Der gewünschte Pin (BCM-, WiringPi- oder Pin-Nummer).
|
||||
``mode``: Auslösende Flankenmodus
|
||||
``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
|
||||
|
||||
``*function``: Funktionspointer für ISR
|
||||
``*function``: Funktionspointer für ISR mit Rückgabeparameter pin und Zeitstempel:
|
||||
> unsigned int: pin
|
||||
> long long int: Zeitstempel
|
||||
|
||||
``bouncetime``: Entprellzeit in Microsekunden, 0 ms schaltet das Entprellen ab
|
||||
|
||||
``Rückgabewert``:
|
||||
> 0 ... Erfolgreich
|
||||
<!-- > <>0 ... Fehler, zur Zeit nicht implementiert -->
|
||||
|
||||
Beispiel siehe wiringPiISRStop.
|
||||
Beispiel siehe waitForInterrupt.
|
||||
|
||||
|
||||
### wiringPiISRStop
|
||||
@@ -323,42 +329,148 @@ int wiringPiISRStop (int pin)
|
||||
<!-- > <>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
|
||||
|
||||
Wartet auf einen Aufruf der Interrupt Service Routine (ISR) mit Timeout.
|
||||
|
||||
Wartet auf einen Aufruf der Interrupt Service Routine (ISR) mit Timeout und Entprellzeit in Mikrosekunden.
|
||||
Blockiert das Programm bis zum Eintreffen der auslösenden Flanke oder bis zum Ablauf des Timeouts.
|
||||
>>>
|
||||
```C
|
||||
int waitForInterrupt (int pin, int mS)
|
||||
long long int waitForInterrupt (int pin, int edgeMode, int mS, unsigned long bouncetime)
|
||||
```
|
||||
|
||||
``pin``: Der gewünschte Pin (BCM-, WiringPi- oder Pin-Nummer).
|
||||
``mS``: Timeout in Milisekunden.
|
||||
``Rückgabewert``: Fehler
|
||||
> 0 ... Erfolgreich
|
||||
> -1 ... GPIO Device Chip nicht erfolgreich geöffnet
|
||||
> -2 ... ISR wurde nicht registriert (wiringPiISR muss aufgerufen werden)
|
||||
``pin``: Der gewünschte Pin (BCM\-, WiringPi\- oder Pin\-Nummer).
|
||||
|
||||
``edgeMode``: Auslösende Flankenmodus
|
||||
- INT_EDGE_RISING ... Steigende Flanke
|
||||
- INT_EDGE_FALLING ... Fallende Flanke
|
||||
- INT_EDGE_BOTH ... Steigende und fallende Flanke
|
||||
|
||||
``mS``: Timeout in Milisekunden.
|
||||
- \-1 warten ohne timeout
|
||||
- 0 wartet nicht
|
||||
- 1...n wartet maximal n mS Millisekunden
|
||||
|
||||
``bouncetime``: Entprellzeit in Microsekunden, 0 schaltet Entprellen ab.
|
||||
|
||||
``Rückgabewert``:
|
||||
> \>0 ... Zeitstempel des Interrupt Ereignisses in Mikrosekunden
|
||||
> 0 ... Timeout
|
||||
> \-1 ... GPIO Device Chip nicht erfolgreich geöffnet
|
||||
> \-2 ... ISR wurde nicht registriert
|
||||
|
||||
|
||||
**Beispiel:**
|
||||
|
||||
```C
|
||||
/*
|
||||
* isr_debounce.c:
|
||||
* Wait for Interrupt test program WiringPi >=3.14 - 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 (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) ;
|
||||
|
||||
printf("Testing waitForInterrupt IRQ @ GPIO%d, timeout is %d\n", IRQpin, TIMEOUT);
|
||||
ret = waitForInterrupt(IRQpin, INT_EDGE_FALLING, TIMEOUT, BOUNCETIME_WFI );
|
||||
if (ret < 0) {
|
||||
printf("waitForInterrupt returned error %lld\n", ret);
|
||||
wiringPiISRStop (IRQpin) ;
|
||||
pinMode(OUTpin, INPUT);
|
||||
return 0;
|
||||
}
|
||||
else if (ret == 0) {
|
||||
printf("waitForInterrupt timed out %lld\n\n", ret);
|
||||
wiringPiISRStop (IRQpin) ;
|
||||
}
|
||||
else {
|
||||
printf("waitForInterrupt: falling edge fired at %lld microseconds\n\n", ret);
|
||||
wiringPiISRStop (IRQpin) ;
|
||||
}
|
||||
|
||||
printf("Testing IRQ @ GPIO%d with trigger @ GPIO%d falling edge and bouncetime %d microseconds. Toggle LED @ OUTpin on IRQ.\n\n", IRQpin, IRQpin, BOUNCETIME, OUTpin);
|
||||
printf("To stop program hit return key\n\n");
|
||||
|
||||
wiringPiISR (IRQpin, INT_EDGE_FALLING, &wfi, BOUNCETIME) ;
|
||||
|
||||
getc(stdin);
|
||||
|
||||
wiringPiISRStop (IRQpin) ;
|
||||
pinMode(OUTpin, INPUT);
|
||||
|
||||
return 0 ;
|
||||
}
|
||||
```
|
||||
|
||||
## Hardware PWM (Pulsweitenmodulation)
|
||||
|
||||
@@ -564,4 +676,4 @@ if (fd>0) {
|
||||
|
||||
## SPI - Bus
|
||||
|
||||
...
|
||||
...
|
||||
|
||||
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 ;
|
||||
}
|
||||
@@ -177,7 +177,7 @@ void printgpio(const char* text) {
|
||||
}
|
||||
}
|
||||
|
||||
static void wfi (void) {
|
||||
static void wfi (unsigned int pin, long long int timestamp) {
|
||||
globalCounter++;
|
||||
if(globalCounter>=iterations) {
|
||||
printgpio("finished\n");
|
||||
@@ -217,7 +217,7 @@ void doWfi (int argc, char *argv [])
|
||||
timeoutSec = atoi(argv [5]);
|
||||
}
|
||||
|
||||
if (wiringPiISR (pin, mode, &wfi) < 0)
|
||||
if (wiringPiISR (pin, mode, &wfi, 0) < 0)
|
||||
{
|
||||
fprintf (stderr, "%s: wfi: Unable to setup ISR: %s\n", argv [1], strerror (errno)) ;
|
||||
exit (1) ;
|
||||
|
||||
@@ -56,6 +56,7 @@
|
||||
#include <stdarg.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
#include <ctype.h>
|
||||
#include <poll.h>
|
||||
#include <unistd.h>
|
||||
@@ -477,11 +478,14 @@ static int isrFds [64] =
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
// ISR Data
|
||||
static int chipFd = -1;
|
||||
static void (*isrFunctions [64])(void) ;
|
||||
static void (*isrFunctions [64])(unsigned int, long long int) ;
|
||||
static pthread_t isrThreads[64];
|
||||
static int isrMode[64];
|
||||
static int isrMode[64]; // irq on rising/falling edge
|
||||
static unsigned long isrDebouncePeriodUs [64]; // 0: debounce is off
|
||||
|
||||
// Doing it the Arduino way with lookup tables...
|
||||
// Yes, it's probably more innefficient than all the bit-twidling, but it
|
||||
@@ -1753,11 +1757,14 @@ void releaseLine(int pin) {
|
||||
lineFlags[pin] = 0;
|
||||
close(lineFds[pin]);
|
||||
lineFds[pin] = -1;
|
||||
isrDebouncePeriodUs[pin] = 0;
|
||||
}
|
||||
|
||||
int requestLine(int pin, unsigned int lineRequestFlags) {
|
||||
struct gpiohandle_request rq;
|
||||
|
||||
struct gpio_v2_line_request req;
|
||||
struct gpio_v2_line_config config;
|
||||
int ret;
|
||||
|
||||
if (lineFds[pin]>=0) {
|
||||
if (lineRequestFlags == lineFlags[pin]) {
|
||||
//already requested
|
||||
@@ -1772,17 +1779,25 @@ int requestLine(int pin, unsigned int lineRequestFlags) {
|
||||
if (wiringPiGpioDeviceGetFd()<0) {
|
||||
return -1; // error
|
||||
}
|
||||
rq.lineoffsets[0] = pin;
|
||||
rq.lines = 1;
|
||||
rq.flags = lineRequestFlags;
|
||||
int ret = ioctl(chipFd, GPIO_GET_LINEHANDLE_IOCTL, &rq);
|
||||
if (ret || rq.fd<0) {
|
||||
|
||||
memset(&req, 0, sizeof(req));
|
||||
memset(&config, 0, sizeof(config));
|
||||
config.flags = lineRequestFlags;
|
||||
strcpy(req.consumer, "wiringpi_gpio_req");
|
||||
|
||||
req.offsets[0] = pin;
|
||||
req.num_lines = 1;
|
||||
req.config = config;
|
||||
|
||||
ret = ioctl(chipFd, GPIO_V2_GET_LINE_IOCTL, &req);
|
||||
|
||||
if (ret || req.fd<0) {
|
||||
ReportDeviceError("get line handle", pin, "RequestLine", ret);
|
||||
return -1; // error
|
||||
}
|
||||
|
||||
lineFlags[pin] = lineRequestFlags;
|
||||
lineFds[pin] = rq.fd;
|
||||
lineFds[pin] = req.fd;
|
||||
if (wiringPiDebug)
|
||||
printf ("requestLine succeeded: pin:%d, flags: %u, fd :%d\n", pin, lineRequestFlags, lineFds[pin]) ;
|
||||
return lineFds[pin];
|
||||
@@ -1882,16 +1897,16 @@ void pinModeFlagsDevice (int pin, int mode, unsigned int flags) {
|
||||
if (wiringPiDebug)
|
||||
printf ("pinModeFlagsDevice: pin:%d mode:%d, flags: %u\n", pin, mode, flags) ;
|
||||
|
||||
lflag &= ~(GPIOHANDLE_REQUEST_INPUT | GPIOHANDLE_REQUEST_OUTPUT);
|
||||
lflag &= ~(GPIO_V2_LINE_FLAG_INPUT | GPIO_V2_LINE_FLAG_OUTPUT);
|
||||
switch(mode) {
|
||||
default:
|
||||
fprintf(stderr, "pinMode: invalid mode request (only input und output supported)\n");
|
||||
return;
|
||||
case INPUT:
|
||||
lflag |= GPIOHANDLE_REQUEST_INPUT;
|
||||
lflag |= GPIO_V2_LINE_FLAG_INPUT;
|
||||
break;
|
||||
case OUTPUT:
|
||||
lflag |= GPIOHANDLE_REQUEST_OUTPUT;
|
||||
lflag |= GPIO_V2_LINE_FLAG_OUTPUT;
|
||||
break;
|
||||
case PM_OFF:
|
||||
pinModeFlagsDevice(pin, INPUT, 0);
|
||||
@@ -2057,20 +2072,20 @@ void pinMode (int pin, int mode)
|
||||
*/
|
||||
void pullUpDnControlDevice (int pin, int pud) {
|
||||
unsigned int flag = lineFlags[pin];
|
||||
unsigned int biasflags = GPIOHANDLE_REQUEST_BIAS_DISABLE | GPIOHANDLE_REQUEST_BIAS_PULL_UP | GPIOHANDLE_REQUEST_BIAS_PULL_DOWN;
|
||||
unsigned int biasflags = GPIO_V2_LINE_FLAG_BIAS_DISABLED | GPIO_V2_LINE_FLAG_BIAS_PULL_UP | GPIO_V2_LINE_FLAG_BIAS_PULL_DOWN;
|
||||
|
||||
flag &= ~biasflags;
|
||||
switch (pud){
|
||||
case PUD_OFF: flag |= GPIOHANDLE_REQUEST_BIAS_DISABLE; break;
|
||||
case PUD_UP: flag |= GPIOHANDLE_REQUEST_BIAS_PULL_UP; break;
|
||||
case PUD_DOWN: flag |= GPIOHANDLE_REQUEST_BIAS_PULL_DOWN; break;
|
||||
case PUD_OFF: flag |= GPIO_V2_LINE_FLAG_BIAS_DISABLED; break;
|
||||
case PUD_UP: flag |= GPIO_V2_LINE_FLAG_BIAS_PULL_UP; break;
|
||||
case PUD_DOWN: flag |= GPIO_V2_LINE_FLAG_BIAS_PULL_DOWN; break;
|
||||
default: return ; /* An illegal value */
|
||||
}
|
||||
|
||||
// reset input/output
|
||||
if (lineFlags[pin] & GPIOHANDLE_REQUEST_OUTPUT) {
|
||||
if (lineFlags[pin] & GPIO_V2_LINE_FLAG_OUTPUT) {
|
||||
pinModeFlagsDevice (pin, OUTPUT, flag);
|
||||
} else if(lineFlags[pin] & GPIOHANDLE_REQUEST_INPUT) {
|
||||
} else if(lineFlags[pin] & GPIO_V2_LINE_FLAG_INPUT) {
|
||||
pinModeFlagsDevice (pin, INPUT, flag);
|
||||
} else {
|
||||
lineFlags[pin] = flag; // only store for later
|
||||
@@ -2154,7 +2169,33 @@ void pullUpDnControl (int pin, int pud)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
helper functions for gpio_v2_line_values bits
|
||||
*/
|
||||
static inline void gpiotools_set_bit(__u64 *b, int n)
|
||||
{
|
||||
*b |= _BITULL(n);
|
||||
}
|
||||
|
||||
static inline void gpiotools_clear_bit(__u64 *b, int n)
|
||||
{
|
||||
*b &= ~_BITULL(n);
|
||||
}
|
||||
|
||||
static inline void gpiotools_assign_bit(__u64 *b, int n, bool value)
|
||||
{
|
||||
if (value)
|
||||
gpiotools_set_bit(b, n);
|
||||
else
|
||||
gpiotools_clear_bit(b, n);
|
||||
}
|
||||
|
||||
static inline int gpiotools_test_bit(__u64 b, int n)
|
||||
{
|
||||
return !!(b & _BITULL(n));
|
||||
}
|
||||
|
||||
//*********************************************
|
||||
|
||||
|
||||
/*
|
||||
@@ -2164,19 +2205,23 @@ void pullUpDnControl (int pin, int pud)
|
||||
*/
|
||||
|
||||
int digitalReadDevice (int pin) { // INPUT and OUTPUT should work
|
||||
|
||||
if (lineFds[pin]<0) {
|
||||
struct gpio_v2_line_values lv;
|
||||
int ret;
|
||||
|
||||
if (lineFds[pin]<0) {
|
||||
// line not requested - auto request on first read as input
|
||||
pinModeDevice(pin, INPUT);
|
||||
pinModeDevice(pin, INPUT);
|
||||
}
|
||||
lv.mask = 0;
|
||||
lv.bits = 0;
|
||||
if (lineFds[pin]>=0) {
|
||||
struct gpiohandle_data data;
|
||||
int ret = ioctl(lineFds[pin], GPIOHANDLE_GET_LINE_VALUES_IOCTL, &data);
|
||||
gpiotools_set_bit(&lv.mask, 0);
|
||||
ret = ioctl(lineFds[pin], GPIO_V2_LINE_GET_VALUES_IOCTL, &lv);
|
||||
if (ret) {
|
||||
ReportDeviceError("get line values", pin, "digitalRead", ret);
|
||||
return LOW; // error
|
||||
}
|
||||
return data.values[0];
|
||||
return gpiotools_test_bit(lv.bits, 0);
|
||||
}
|
||||
return LOW; // error , need to request line before
|
||||
}
|
||||
@@ -2258,7 +2303,9 @@ unsigned int digitalRead8 (int pin)
|
||||
*/
|
||||
|
||||
void digitalWriteDevice (int pin, int value) {
|
||||
|
||||
int ret;
|
||||
struct gpio_v2_line_values values;
|
||||
|
||||
if (wiringPiDebug)
|
||||
printf ("digitalWriteDevice: ioctl pin:%d value: %d\n", pin, value) ;
|
||||
|
||||
@@ -2266,22 +2313,25 @@ void digitalWriteDevice (int pin, int value) {
|
||||
// line not requested - auto request on first write as output
|
||||
pinModeDevice(pin, OUTPUT);
|
||||
}
|
||||
if (lineFds[pin]>=0 && (lineFlags[pin] & GPIOHANDLE_REQUEST_OUTPUT)>0) {
|
||||
struct gpiohandle_data data;
|
||||
data.values[0] = value;
|
||||
if (wiringPiDebug)
|
||||
printf ("digitalWriteDevice: ioctl pin:%d cmd: GPIOHANDLE_SET_LINE_VALUES_IOCTL, value: %d\n", pin, value) ;
|
||||
int ret = ioctl(lineFds[pin], GPIOHANDLE_SET_LINE_VALUES_IOCTL, &data);
|
||||
if (ret) {
|
||||
ReportDeviceError("set line values", pin, "digitalWrite", ret);
|
||||
return; // error
|
||||
}
|
||||
|
||||
if (lineFds[pin]>=0 && (lineFlags[pin] & GPIO_V2_LINE_FLAG_OUTPUT)>0) {
|
||||
values.mask = 0;
|
||||
values.bits = 0;
|
||||
gpiotools_set_bit(&values.mask, 0);
|
||||
gpiotools_assign_bit(&values.bits, 0, !!value);
|
||||
|
||||
ret = ioctl(lineFds[pin], GPIO_V2_LINE_SET_VALUES_IOCTL, &values);
|
||||
if (ret == -1) {
|
||||
ReportDeviceError("digitalWriteDevice", pin, "GPIO_V2_LINE_SET_VALUES_IOCTL", ret);
|
||||
return; // error
|
||||
}
|
||||
} else {
|
||||
fprintf(stderr, "digitalWrite: no output (%d)\n", lineFlags[pin]);
|
||||
}
|
||||
return; // error
|
||||
}
|
||||
|
||||
|
||||
void digitalWrite (int pin, int value)
|
||||
{
|
||||
struct wiringPiNodeStruct *node = wiringPiNodes ;
|
||||
@@ -2579,63 +2629,23 @@ unsigned int digitalReadByte2 (void)
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* waitForInterrupt:
|
||||
* Pi Specific.
|
||||
* Wait for Interrupt on a GPIO pin.
|
||||
* This is actually done via the /dev/gpiochip interface regardless of
|
||||
* the wiringPi access mode in-use. Maybe sometime it might get a better
|
||||
* way for a bit more efficiency.
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
int waitForInterrupt (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] ;
|
||||
//--------------------------------------------------------------------
|
||||
// waitForInteruptInit
|
||||
// Prepares waitForInterrupt for edgeMode, and debounce_period_us
|
||||
//
|
||||
// returns -1 on error
|
||||
// returns 0 on success
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
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 waitForInterruptInit (int pin, int mode)
|
||||
int waitForInterruptInit (int pin, int edgeMode, unsigned long debounce_period_us)
|
||||
{
|
||||
const char* strmode = "";
|
||||
|
||||
struct gpio_v2_line_config config;
|
||||
struct gpio_v2_line_request req;
|
||||
int attr, ret;
|
||||
|
||||
if (wiringPiMode == WPI_MODE_PINS) {
|
||||
pin = pinToGpio [pin] ;
|
||||
} else if (wiringPiMode == WPI_MODE_PHYS) {
|
||||
@@ -2643,15 +2653,17 @@ int waitForInterruptInit (int pin, int mode)
|
||||
}
|
||||
|
||||
/* open gpio */
|
||||
sleep(1);
|
||||
// sleep(1);
|
||||
if (wiringPiGpioDeviceGetFd()<0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
struct gpioevent_request req;
|
||||
req.lineoffset = pin;
|
||||
req.handleflags = GPIOHANDLE_REQUEST_INPUT;
|
||||
switch(mode) {
|
||||
|
||||
memset(&req, 0, sizeof(req));
|
||||
memset(&config, 0, sizeof(config));
|
||||
|
||||
/* setup config */
|
||||
config.flags = GPIO_V2_LINE_FLAG_INPUT;
|
||||
switch(edgeMode) {
|
||||
default:
|
||||
case INT_EDGE_SETUP:
|
||||
if (wiringPiDebug) {
|
||||
@@ -2659,33 +2671,49 @@ int waitForInterruptInit (int pin, int mode)
|
||||
}
|
||||
return -1;
|
||||
case INT_EDGE_FALLING:
|
||||
req.eventflags = GPIOEVENT_REQUEST_FALLING_EDGE;
|
||||
config.flags |= GPIO_V2_LINE_FLAG_EDGE_FALLING;
|
||||
strmode = "falling";
|
||||
break;
|
||||
case INT_EDGE_RISING:
|
||||
req.eventflags = GPIOEVENT_REQUEST_RISING_EDGE;
|
||||
config.flags |= GPIO_V2_LINE_FLAG_EDGE_RISING;
|
||||
strmode = "rising";
|
||||
break;
|
||||
case INT_EDGE_BOTH:
|
||||
req.eventflags = GPIOEVENT_REQUEST_BOTH_EDGES;
|
||||
config.flags |= (GPIO_V2_LINE_FLAG_EDGE_FALLING | GPIO_V2_LINE_FLAG_EDGE_RISING);
|
||||
strmode = "both";
|
||||
break;
|
||||
}
|
||||
strncpy(req.consumer_label, "wiringpi_gpio_irq", sizeof(req.consumer_label) - 1);
|
||||
strcpy(req.consumer, "wiringpi_gpio_irq");
|
||||
|
||||
if (debounce_period_us) {
|
||||
attr = config.num_attrs;
|
||||
config.num_attrs++;
|
||||
gpiotools_set_bit(&config.attrs[attr].mask, 0);
|
||||
config.attrs[attr].attr.id = GPIO_V2_LINE_ATTR_ID_DEBOUNCE;
|
||||
config.attrs[attr].attr.debounce_period_us = debounce_period_us;
|
||||
}
|
||||
|
||||
req.num_lines = 1;
|
||||
req.offsets[0] = pin;
|
||||
req.event_buffer_size = 32;
|
||||
req.config = config;
|
||||
|
||||
//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);
|
||||
ret = ioctl(chipFd, GPIO_V2_GET_LINE_IOCTL, &req);
|
||||
if (ret == -1) {
|
||||
ReportDeviceError("GPIO_V2_GET_LINE_IOCTL", pin , strmode, ret);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (wiringPiDebug) {
|
||||
printf ("wiringPi: GPIO get line %d , mode %s succeded, fd=%d\n", pin, strmode, req.fd) ;
|
||||
}
|
||||
|
||||
/* set event fd nonbloack read */
|
||||
|
||||
int fd_line = req.fd;
|
||||
isrFds [pin] = fd_line;
|
||||
isrDebouncePeriodUs[pin] = debounce_period_us;
|
||||
|
||||
/* set event fd nonbloack read */
|
||||
/*
|
||||
int flags = fcntl(fd_line, F_GETFL);
|
||||
flags |= O_NONBLOCK;
|
||||
ret = fcntl(fd_line, F_SETFL, flags);
|
||||
@@ -2693,30 +2721,109 @@ int waitForInterruptInit (int pin, int mode)
|
||||
fprintf(stderr, "wiringPi: ERROR: fcntl set nonblock return=%d\n", ret);
|
||||
return -1;
|
||||
}
|
||||
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* waitForInterrupt:
|
||||
* Pi Specific.
|
||||
* Wait for Interrupt on a GPIO pin.
|
||||
* This is actually done via the /dev/gpiochip interface regardless of
|
||||
* the wiringPi access mode in-use. Maybe sometime it might get a better
|
||||
* way for a bit more efficiency.
|
||||
* Returns timestamp in microseconds on interrupt
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
long long int waitForInterrupt (int pin, int edgeMode, int mS, unsigned long debounce_period_us) // ms < 0 wait infinite, = 0 return immediately, > 0 wait timeout
|
||||
{
|
||||
long long int ret;
|
||||
int fd;
|
||||
struct pollfd polls ;
|
||||
struct gpio_v2_line_event evdata;
|
||||
|
||||
if (wiringPiMode == WPI_MODE_PINS)
|
||||
pin = pinToGpio [pin] ;
|
||||
else if (wiringPiMode == WPI_MODE_PHYS)
|
||||
pin = physToGpio [pin] ;
|
||||
|
||||
if (waitForInterruptInit (pin, edgeMode, debounce_period_us ) != 0)
|
||||
return -1 ;
|
||||
|
||||
fd = isrFds[pin];
|
||||
// Setup poll structure
|
||||
polls.fd = fd;
|
||||
polls.events = POLLIN | POLLERR ;
|
||||
polls.revents = 0;
|
||||
|
||||
ret = (long long int)poll(&polls, 1, mS);
|
||||
|
||||
if (ret < 0) {
|
||||
if (wiringPiDebug)
|
||||
fprintf(stderr, "wiringPi: ERROR: poll returned=%lld\n", ret);
|
||||
} else if (ret == 0) {
|
||||
if (wiringPiDebug)
|
||||
fprintf(stderr, "wiringPi: timeout: poll returned=%lld\n", ret);
|
||||
}
|
||||
else {
|
||||
if (wiringPiDebug)
|
||||
printf ("wiringPi: IRQ line %d received %lld, fd=%d\n", pin, ret, isrFds[pin]) ;
|
||||
if (polls.revents & POLLIN) {
|
||||
/* read event data */
|
||||
int readret = read(isrFds [pin], &evdata, sizeof(evdata));
|
||||
if (readret == sizeof(evdata)) {
|
||||
if (wiringPiDebug)
|
||||
printf ("wiringPi: IRQ at PIN: %d, timestamp: %lld\n", evdata.offset, evdata.timestamp_ns) ;
|
||||
|
||||
switch (evdata.id) {
|
||||
case GPIO_V2_LINE_EVENT_RISING_EDGE:
|
||||
if (wiringPiDebug)
|
||||
printf("wiringPi: rising edge\n");
|
||||
break;
|
||||
case GPIO_V2_LINE_EVENT_FALLING_EDGE:
|
||||
if (wiringPiDebug)
|
||||
printf("wiringPi: falling edge\n");
|
||||
break;
|
||||
default:
|
||||
if (wiringPiDebug)
|
||||
printf("wiringPi: unknown event\n");
|
||||
break;
|
||||
}
|
||||
ret = evdata.timestamp_ns / 1000LL; // nanoseconds u64 to microseconds
|
||||
}
|
||||
else {
|
||||
ret = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int waitForInterruptClose (int pin) {
|
||||
if (isrFds[pin]>0) {
|
||||
if (wiringPiDebug) {
|
||||
printf ("wiringPi: waitForInterruptClose close thread 0x%lX\n", (unsigned long)isrThreads[pin]) ;
|
||||
}
|
||||
if (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");
|
||||
if (isrThreads[pin] != 0) {
|
||||
if (pthread_cancel(isrThreads[pin]) == 0) {
|
||||
if (wiringPiDebug) {
|
||||
printf ("wiringPi: waitForInterruptClose thread canceled successfuly\n") ;
|
||||
}
|
||||
} else {
|
||||
if (wiringPiDebug) {
|
||||
fprintf (stderr, "wiringPi: waitForInterruptClose could not cancel thread\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
close(isrFds [pin]);
|
||||
}
|
||||
isrFds [pin] = -1;
|
||||
isrFunctions [pin] = NULL;
|
||||
|
||||
isrDebouncePeriodUs[pin] = 0;
|
||||
|
||||
/* -not closing so far - other isr may be using it - only close if no other is using - will code later
|
||||
if (chipFd>0) {
|
||||
close(chipFd);
|
||||
@@ -2730,6 +2837,77 @@ int waitForInterruptClose (int pin) {
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* wfi:
|
||||
* Pi Specific.
|
||||
* Wait for Interrupt on a GPIO pin, called from interruptHandler
|
||||
* Returns timestamp in microseconds on interrupt
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
long long int wfi(int pin)
|
||||
{
|
||||
long long int ret;
|
||||
int fd;
|
||||
struct pollfd polls ;
|
||||
struct gpio_v2_line_event evdata;
|
||||
|
||||
if (wiringPiMode == WPI_MODE_PINS)
|
||||
pin = pinToGpio [pin] ;
|
||||
else if (wiringPiMode == WPI_MODE_PHYS)
|
||||
pin = physToGpio [pin] ;
|
||||
|
||||
if ((fd = isrFds [pin]) == -1)
|
||||
return -2 ;
|
||||
|
||||
// Setup poll structure
|
||||
polls.fd = fd;
|
||||
polls.events = POLLIN | POLLERR ;
|
||||
polls.revents = 0;
|
||||
|
||||
ret = (long long int)poll(&polls, 1, -1); // no timeout, wait forevver
|
||||
|
||||
if (ret < 0) {
|
||||
if (wiringPiDebug)
|
||||
fprintf(stderr, "wiringPi: ERROR: poll returned=%lld\n", ret);
|
||||
} else if (ret == 0) {
|
||||
if (wiringPiDebug)
|
||||
fprintf(stderr, "wiringPi: timeout: poll returned=%lld\n", ret);
|
||||
}
|
||||
else {
|
||||
if (wiringPiDebug)
|
||||
printf ("wiringPi: IRQ line %d received %lld, fd=%d\n", pin, ret, isrFds[pin]) ;
|
||||
if (polls.revents & POLLIN) {
|
||||
/* read event data */
|
||||
int readret = read(isrFds [pin], &evdata, sizeof(evdata));
|
||||
if (readret == sizeof(evdata)) {
|
||||
if (wiringPiDebug)
|
||||
printf ("wiringPi: IRQ at PIN: %d, timestamp: %lld\n", evdata.offset, evdata.timestamp_ns) ;
|
||||
|
||||
switch (evdata.id) {
|
||||
case GPIO_V2_LINE_EVENT_RISING_EDGE:
|
||||
if (wiringPiDebug)
|
||||
printf("wiringPi: rising edge\n");
|
||||
break;
|
||||
case GPIO_V2_LINE_EVENT_FALLING_EDGE:
|
||||
if (wiringPiDebug)
|
||||
printf("wiringPi: falling edge\n");
|
||||
break;
|
||||
default:
|
||||
if (wiringPiDebug)
|
||||
printf("wiringPi: unknown event\n");
|
||||
break;
|
||||
}
|
||||
ret = evdata.timestamp_ns / 1000LL; // nanoseconds u64 to microseconds
|
||||
}
|
||||
else {
|
||||
ret = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int wiringPiISRStop (int pin) {
|
||||
return waitForInterruptClose (pin);
|
||||
}
|
||||
@@ -2742,23 +2920,94 @@ int wiringPiISRStop (int pin) {
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
static void *interruptHandler (UNU void *arg)
|
||||
void *interruptHandler (void *arg)
|
||||
{
|
||||
int pin ;
|
||||
const char* strmode = "";
|
||||
int pin, mode ;
|
||||
unsigned long debounce_period_us;
|
||||
struct gpio_v2_line_config config;
|
||||
struct gpio_v2_line_request req;
|
||||
int attr, ret;
|
||||
|
||||
pin = *(int *)arg;
|
||||
|
||||
/* pin = pinPass ;
|
||||
pinPass = -1 ;
|
||||
*/
|
||||
if (wiringPiGpioDeviceGetFd()<0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
mode = isrMode[pin];
|
||||
debounce_period_us = isrDebouncePeriodUs[pin];
|
||||
|
||||
if (wiringPiDebug) {
|
||||
printf ("interruptHandler: GPIO line %d, mode %d, debounce_period_us %lu \n", pin, mode, debounce_period_us) ;
|
||||
}
|
||||
|
||||
memset(&req, 0, sizeof(req));
|
||||
memset(&config, 0, sizeof(config));
|
||||
|
||||
/* setup config */
|
||||
config.flags = GPIO_V2_LINE_FLAG_INPUT;
|
||||
switch(mode) {
|
||||
default:
|
||||
case INT_EDGE_SETUP:
|
||||
if (wiringPiDebug) {
|
||||
printf ("wiringPi: waitForInterruptMode mode INT_EDGE_SETUP - exiting\n") ;
|
||||
}
|
||||
return NULL;
|
||||
case INT_EDGE_FALLING:
|
||||
config.flags |= GPIO_V2_LINE_FLAG_EDGE_FALLING;
|
||||
strmode = "falling";
|
||||
break;
|
||||
case INT_EDGE_RISING:
|
||||
config.flags |= GPIO_V2_LINE_FLAG_EDGE_RISING;
|
||||
strmode = "rising";
|
||||
break;
|
||||
case INT_EDGE_BOTH:
|
||||
config.flags |= (GPIO_V2_LINE_FLAG_EDGE_FALLING | GPIO_V2_LINE_FLAG_EDGE_RISING);
|
||||
strmode = "both";
|
||||
break;
|
||||
}
|
||||
strcpy(req.consumer, "wiringpi_gpio_irq");
|
||||
|
||||
if (debounce_period_us) {
|
||||
attr = config.num_attrs;
|
||||
config.num_attrs++;
|
||||
gpiotools_set_bit(&config.attrs[attr].mask, 0);
|
||||
config.attrs[attr].attr.id = GPIO_V2_LINE_ATTR_ID_DEBOUNCE;
|
||||
config.attrs[attr].attr.debounce_period_us = debounce_period_us;
|
||||
}
|
||||
|
||||
req.num_lines = 1;
|
||||
req.offsets[0] = pin;
|
||||
req.config = config;
|
||||
|
||||
ret = ioctl(chipFd, GPIO_V2_GET_LINE_IOCTL, &req);
|
||||
if (ret == -1) {
|
||||
ReportDeviceError("get line event", pin , strmode, ret);
|
||||
return NULL;
|
||||
}
|
||||
/*
|
||||
if (wiringPiDebug) {
|
||||
printf ("wiringPi: GPIO get line %d , mode %s succeded, fd=%d\n", pin, strmode, req.fd) ;
|
||||
}
|
||||
*/
|
||||
/* set event fd */
|
||||
int fd_line = req.fd;
|
||||
isrFds [pin] = fd_line;
|
||||
|
||||
(void)piHiPri (55) ; // Only effective if we run as root
|
||||
|
||||
pin = pinPass ;
|
||||
pinPass = -1 ;
|
||||
|
||||
for (;;) {
|
||||
int ret = waitForInterrupt(pin, -1);
|
||||
if ( ret> 0) {
|
||||
long long int ret = wfi(pin); // poll for event and return timestamp
|
||||
if ( ret> 0) { // return timestamp in microseconds
|
||||
if (wiringPiDebug) {
|
||||
printf ("wiringPi: call function\n") ;
|
||||
}
|
||||
if(isrFunctions [pin]) {
|
||||
isrFunctions [pin] () ;
|
||||
isrFunctions [pin] ((unsigned int)pin, ret) ;
|
||||
}
|
||||
// wait again - in the past forever - now can be stopped by waitForInterruptClose
|
||||
} else if( ret< 0) {
|
||||
@@ -2779,10 +3028,11 @@ static void *interruptHandler (UNU void *arg)
|
||||
* Pi Specific.
|
||||
* Take the details and create an interrupt handler that will do a call-
|
||||
* back to the user supplied function.
|
||||
* debounce_period_us in microseconds
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
int wiringPiISR (int pin, int mode, void (*function)(void))
|
||||
int wiringPiISR (int pin, int edgeMode, void (*function)(unsigned int, long long int), unsigned long debounce_period_us)
|
||||
{
|
||||
const int maxpin = GetMaxPin();
|
||||
|
||||
@@ -2790,21 +3040,24 @@ int wiringPiISR (int pin, int mode, void (*function)(void))
|
||||
return wiringPiFailure (WPI_FATAL, "wiringPiISR: pin must be 0-%d (%d)\n", maxpin, pin) ;
|
||||
if (wiringPiMode == WPI_MODE_UNINITIALISED)
|
||||
return wiringPiFailure (WPI_FATAL, "wiringPiISR: wiringPi has not been initialised. Unable to continue.\n") ;
|
||||
|
||||
if (wiringPiMode == WPI_MODE_PINS) {
|
||||
pin = pinToGpio [pin] ;
|
||||
} else if (wiringPiMode == WPI_MODE_PHYS) {
|
||||
pin = physToGpio [pin] ;
|
||||
}
|
||||
|
||||
if (wiringPiDebug) {
|
||||
printf ("wiringPi: wiringPiISR pin %d, mode %d\n", pin, mode) ;
|
||||
printf ("wiringPi: wiringPiISR pin %d, edgeMode %d\n", pin, edgeMode) ;
|
||||
}
|
||||
if (isrFunctions [pin]) {
|
||||
printf ("wiringPi: ISR function alread active, ignoring \n") ;
|
||||
printf ("wiringPi: ISR function already active, ignoring \n") ;
|
||||
}
|
||||
|
||||
isrFunctions [pin] = function ;
|
||||
isrMode[pin] = mode;
|
||||
if(waitForInterruptInit (pin, mode)<0) {
|
||||
if (wiringPiDebug) {
|
||||
fprintf (stderr, "wiringPi: waitForInterruptInit failed\n") ;
|
||||
}
|
||||
};
|
||||
|
||||
isrMode[pin] = edgeMode;
|
||||
isrDebouncePeriodUs[pin] = debounce_period_us;
|
||||
|
||||
if (wiringPiDebug) {
|
||||
printf ("wiringPi: mutex in\n") ;
|
||||
}
|
||||
@@ -2813,12 +3066,17 @@ int wiringPiISR (int pin, int mode, void (*function)(void))
|
||||
if (wiringPiDebug) {
|
||||
printf("wiringPi: pthread_create before 0x%lX\n", (unsigned long)isrThreads[pin]);
|
||||
}
|
||||
if (pthread_create (&isrThreads[pin], NULL, interruptHandler, NULL)==0) {
|
||||
if (pthread_create (&isrThreads[pin], NULL, interruptHandler, &pin)==0) {
|
||||
if (wiringPiDebug) {
|
||||
printf("wiringPi: pthread_create successed, 0x%lX\n", (unsigned long)isrThreads[pin]);
|
||||
}
|
||||
while (pinPass != -1)
|
||||
delay (1) ;
|
||||
/* while (pinPass != -1)
|
||||
delay (1) ; */
|
||||
// wait so that interruptHandler is up und running.
|
||||
// when interruptHandler is running, the calling function wiringPiISR
|
||||
// must be still alive, otherwise the thread argument &pin points into nirwana,
|
||||
// when it is picked up from interruptHandler.
|
||||
delay (10);
|
||||
} else {
|
||||
if (wiringPiDebug) {
|
||||
printf("wiringPi: pthread_create failed\n");
|
||||
@@ -3170,12 +3428,12 @@ int wiringPiSetup (void)
|
||||
|
||||
/**/ if (piGpioLayout () == GPIO_LAYOUT_PI1_REV1) // A, B, Rev 1, 1.1
|
||||
{
|
||||
pinToGpio = pinToGpioR1 ;
|
||||
pinToGpio = pinToGpioR1 ;
|
||||
physToGpio = physToGpioR1 ;
|
||||
}
|
||||
else // A2, B2, A+, B+, CM, Pi2, Pi3, Zero, Zero W, Zero 2 W
|
||||
{
|
||||
pinToGpio = pinToGpioR2 ;
|
||||
pinToGpio = pinToGpioR2 ;
|
||||
physToGpio = physToGpioR2 ;
|
||||
}
|
||||
|
||||
@@ -3184,7 +3442,7 @@ int wiringPiSetup (void)
|
||||
// Try /dev/mem. If that fails, then
|
||||
// try /dev/gpiomem. If that fails then game over.
|
||||
|
||||
const char* gpiomemGlobal = gpiomem_global;
|
||||
const char* gpiomemGlobal = gpiomem_global;
|
||||
const char* gpiomemModule = gpiomem_BCM;
|
||||
|
||||
if (piRP1Model()) {
|
||||
@@ -3225,7 +3483,7 @@ int wiringPiSetup (void)
|
||||
printf ("wiringPi: access to %s succeded %d\n", usingGpioMem ? gpiomemModule : gpiomemGlobal, fd) ;
|
||||
}
|
||||
// GPIO:
|
||||
if (!piRP1Model()) {
|
||||
if (!piRP1Model()) {
|
||||
//Set the offsets into the memory interface.
|
||||
|
||||
GPIO_PADS = piGpioBase + 0x00100000 ;
|
||||
|
||||
@@ -298,8 +298,8 @@ extern void digitalWriteByte2 (int value) ;
|
||||
// Interrupts
|
||||
// (Also Pi hardware specific)
|
||||
|
||||
extern int waitForInterrupt (int pin, int mS) ;
|
||||
extern int wiringPiISR (int pin, int mode, void (*function)(void)) ;
|
||||
extern long long int waitForInterrupt (int pin, int edgeMode, int mS, unsigned long debounce_period_us) ; // V3.14 phylax
|
||||
extern int wiringPiISR (int pin, int mode, void (*function)(unsigned int, long long int), unsigned long debounce_period_us) ; // v3.14 phylax
|
||||
extern int wiringPiISRStop (int pin) ; //V3.2
|
||||
extern int waitForInterruptClose(int pin) ; //V3.2
|
||||
|
||||
|
||||
Reference in New Issue
Block a user