Version 3.13 : debounce time added for wiringPiISR and waitForInterrupt library functions. Documentation update

This commit is contained in:
phylax2020
2025-01-29 19:09:32 +01:00
parent b55101e013
commit 0bf457519d
6 changed files with 77 additions and 39 deletions

View File

@@ -473,9 +473,10 @@ static int isrFds [64] =
// ISR Data
static int chipFd = -1;
static void (*isrFunctions [64])(void) ;
static void (*isrFunctions [64])(unsigned int, long long int) ;
static pthread_t isrThreads[64];
static int isrMode[64];
static unsigned long long lastcall[64];
// Doing it the Arduino way with lookup tables...
// Yes, it's probably more innefficient than all the bit-twidling, but it
@@ -2566,16 +2567,26 @@ unsigned int digitalReadByte2 (void)
* This is actually done via the /dev/gpiochip interface regardless of
* the wiringPi access mode in-use. Maybe sometime it might get a better
* way for a bit more efficiency.
* Returns timestamp in microseconds, when interrupt happened
*********************************************************************************
*/
int waitForInterrupt (int pin, int mS)
long long int waitForInterrupt (int pin, int mS, int bouncetime) // bounctime in milliseconds
{
int fd, ret;
long long int ret;
int fd;
struct pollfd polls ;
struct gpioevent_data evdata;
//struct gpio_v2_line_request req2;
struct timeval tv_timenow;
unsigned long long timenow;
int finished = 0;
int initial_edge = 1;
if (wiringPiDebug) {
printf ("waitForInterrupt: mS = %d, bouncetime = %d\n", mS, bouncetime) ;
}
if (wiringPiMode == WPI_MODE_PINS)
pin = pinToGpio [pin] ;
else if (wiringPiMode == WPI_MODE_PHYS)
@@ -2590,23 +2601,46 @@ int waitForInterrupt (int pin, int mS)
polls.revents = 0;
// Wait for it ...
ret = poll(&polls, 1, mS);
if (ret <= 0) {
fprintf(stderr, "wiringPi: ERROR: poll returned=%d\n", ret);
} else {
//if (polls.revents & POLLIN)
if (wiringPiDebug) {
printf ("wiringPi: IRQ line %d received %d, fd=%d\n", pin, ret, isrFds[pin]) ;
}
/* read event data */
int readret = read(isrFds [pin], &evdata, sizeof(evdata));
if (readret == sizeof(evdata)) {
if (wiringPiDebug) {
printf ("wiringPi: IRQ data id: %d, timestamp: %lld\n", evdata.id, evdata.timestamp) ;
while (!finished) {
ret = (long long int)poll(&polls, 1, mS);
if (ret < 0) {
if (wiringPiDebug) {
fprintf(stderr, "wiringPi: ERROR: poll returned=%lld\n", ret);
}
break;
} else if (ret == 0) {
if (wiringPiDebug) {
fprintf(stderr, "wiringPi: timeout: poll returned=%lld\n", ret);
}
break;
}
else {
//if (polls.revents & POLLIN)
if (wiringPiDebug) {
printf ("wiringPi: IRQ line %d received %lld, fd=%d\n", pin, ret, isrFds[pin]) ;
}
if (initial_edge) { // first time triggers with current state, so ignore
initial_edge = 0;
} else {
/* read event data */
int readret = read(isrFds [pin], &evdata, sizeof(evdata));
if (readret == sizeof(evdata)) {
if (wiringPiDebug) {
printf ("wiringPi: IRQ data id: %d, timestamp: %lld\n", evdata.id, evdata.timestamp) ;
}
// ret = evdata.id;
gettimeofday(&tv_timenow, NULL);
timenow = tv_timenow.tv_sec*1E6 + tv_timenow.tv_usec;
if (bouncetime == 0 || timenow - lastcall[pin] > (unsigned int)bouncetime*1000 || lastcall[pin] == 0 || lastcall[pin] > timenow) {
lastcall[pin] = timenow;
finished = 1;
ret = evdata.timestamp / 1000LL; // nanoseconds u64 to microseconds
}
} else {
ret = -1;
break;
}
}
ret = evdata.id;
} else {
ret = 0;
}
}
return ret;
@@ -2683,7 +2717,7 @@ int waitForInterruptClose (int pin) {
if (wiringPiDebug) {
printf ("wiringPi: waitForInterruptClose close thread 0x%lX\n", (unsigned long)isrThreads[pin]) ;
}
if (pthread_cancel(isrThreads[pin]) == 0) {
if (isrThreads[pin] && pthread_cancel(isrThreads[pin]) == 0) {
if (wiringPiDebug) {
printf ("wiringPi: waitForInterruptClose thread canceled successfuly\n") ;
}
@@ -2696,7 +2730,7 @@ int waitForInterruptClose (int pin) {
}
isrFds [pin] = -1;
isrFunctions [pin] = NULL;
lastcall[pin] = 0;
/* -not closing so far - other isr may be using it - only close if no other is using - will code later
if (chipFd>0) {
close(chipFd);
@@ -2722,23 +2756,25 @@ int wiringPiISRStop (int pin) {
*********************************************************************************
*/
static void *interruptHandler (UNU void *arg)
static void *interruptHandler (void *arg)
{
int pin ;
int bouncetime;
(void)piHiPri (55) ; // Only effective if we run as root
pin = pinPass ;
bouncetime = *(int *)arg;
pinPass = -1 ;
for (;;) {
int ret = waitForInterrupt(pin, -1);
if ( ret> 0) {
long long int ret = waitForInterrupt(pin, -1, bouncetime);
if ( ret> 0) { // return timestamp in microseconds
if (wiringPiDebug) {
printf ("wiringPi: call function\n") ;
}
if(isrFunctions [pin]) {
isrFunctions [pin] () ;
isrFunctions [pin] ((unsigned int)pin, ret) ;
}
// wait again - in the past forever - now can be stopped by waitForInterruptClose
} else if( ret< 0) {
@@ -2762,7 +2798,7 @@ static void *interruptHandler (UNU void *arg)
*********************************************************************************
*/
int wiringPiISR (int pin, int mode, void (*function)(void))
int wiringPiISR (int pin, int mode, void (*function)(unsigned int, long long int), int bouncetime)
{
const int maxpin = GetMaxPin();
@@ -2779,11 +2815,12 @@ int wiringPiISR (int pin, int mode, void (*function)(void))
isrFunctions [pin] = function ;
isrMode[pin] = mode;
lastcall[pin] = 0;
if(waitForInterruptInit (pin, mode)<0) {
if (wiringPiDebug) {
fprintf (stderr, "wiringPi: waitForInterruptInit failed\n") ;
}
};
}
if (wiringPiDebug) {
printf ("wiringPi: mutex in\n") ;
@@ -2793,7 +2830,7 @@ int wiringPiISR (int pin, int mode, void (*function)(void))
if (wiringPiDebug) {
printf("wiringPi: pthread_create before 0x%lX\n", (unsigned long)isrThreads[pin]);
}
if (pthread_create (&isrThreads[pin], NULL, interruptHandler, NULL)==0) {
if (pthread_create (&isrThreads[pin], NULL, interruptHandler, &bouncetime)==0) {
if (wiringPiDebug) {
printf("wiringPi: pthread_create successed, 0x%lX\n", (unsigned long)isrThreads[pin]);
}

View File

@@ -289,10 +289,11 @@ extern void digitalWriteByte2 (int value) ;
// Interrupts
// (Also Pi hardware specific)
extern int waitForInterrupt (int pin, int mS) ;
extern int wiringPiISR (int pin, int mode, void (*function)(void)) ;
extern long long int waitForInterrupt (int pin, int mS, int bouncetime) ;
extern int wiringPiISR (int pin, int mode, void (*function)(unsigned int, long long int), int bouncetime) ;
extern int wiringPiISRStop (int pin) ; //V3.2
extern int waitForInterruptClose(int pin) ; //V3.2
extern int waitForInterruptInit (int pin, int mode); //v3.2
// Threads