Merge pull request #360 from WiringPi/GPIO_V2_IOCTL

release 3.16 prep.
This commit is contained in:
Manfred Wallner
2025-06-05 13:10:44 +02:00
committed by GitHub
17 changed files with 1986 additions and 391 deletions

View File

@@ -119,10 +119,10 @@ cd WiringPi
# build the package
./build debian
mv debian-template/wiringpi-3.0-1.deb .
mv debian-template/wiringpi-3.x.deb .
# install it
sudo apt install ./wiringpi-3.0-1.deb
sudo apt install ./wiringpi-3.x.deb
```
### Prebuilt Binaries
@@ -133,14 +133,14 @@ Unzip/use the portable prebuilt verison:
```sh
# unzip the archive
tar -xfv wiringpi_3.0.tar.gz
tar -xfv wiringpi_3.x.tar.gz
```
Install the debian package:
```sh
# install a dpkg
sudo apt install ./wiringpi-3.0-1.deb
sudo apt install ./wiringpi-3.x.deb
```
## Ports

View File

@@ -1 +1 @@
3.14
3.16

View File

@@ -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.1x.deb .
```
**Debian-Paket installieren:**
```bash
sudo apt install ./wiringpi-3.0-1.deb
sudo apt install ./wiringpi-3.1x.deb
```
**Debian-Paket deinstallieren:**
@@ -291,21 +291,33 @@ 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)(struct WPIWfiStatus wfiStatus), 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 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``:
> 0 ... Erfolgreich
<!-- > <>0 ... Fehler, zur Zeit nicht implementiert -->
Beispiel siehe wiringPiISRStop.
Beispiel siehe waitForInterrupt.
### wiringPiISRStop
@@ -323,41 +335,187 @@ 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 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
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.
``Rückgabewert``: Fehler
> 0 ... Erfolgreich
> -1 ... GPIO Device Chip nicht erfolgreich geöffnet
> -2 ... ISR wurde nicht registriert (wiringPiISR muss aufgerufen werden)
- \-1 warten ohne timeout
- 0 wartet nicht
- 1...n wartet maximal n mS Millisekunden
``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)

116
examples/isr_debounce.c Normal file
View 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 ;
}

View File

@@ -165,7 +165,7 @@ void LOAD_DEPRECATED(const char *progName) {
*********************************************************************************
*/
static volatile int iterations ;
static volatile int globalIterations ;
static volatile int globalCounter ;
void printgpioflush(const char* text) {
@@ -181,59 +181,133 @@ void printgpio(const char* text) {
}
}
static void wfi (void) {
static void wfi (void) {
globalCounter++;
if(globalCounter>=iterations) {
if(globalCounter>=globalIterations) {
printgpio("finished\n");
exit (0) ;
exit(0);
} else {
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;
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]) ;
/**/ if (strcasecmp (argv [3], "rising") == 0) mode = INT_EDGE_RISING ;
else if (strcasecmp (argv [3], "falling") == 0) mode = INT_EDGE_FALLING ;
else if (strcasecmp (argv [3], "both") == 0) mode = INT_EDGE_BOTH ;
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) ;
if (debounce>=0) {
// V2 function
if (wiringPiISR2(pin, mode, &wfi2, debounce, NULL) < 0) {
fprintf (stderr, "%s: Unable to setup ISR2: %s\n", cmd, strerror (errno));
exit(1);
}
} else {
// classic function
if (wiringPiISR(pin, mode, &wfi) < 0) {
fprintf (stderr, "%s: Unable to setup ISR: %s\n", cmd, strerror (errno));
exit(1);
}
}
printgpio("wait for interrupt function call\n");
for (int Sec=0; Sec<timeoutSec; ++Sec) {
printgpioflush(".");
delay (999);
delay(999);
}
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:
@@ -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], "rbd" ) == 0) doReadByte (argc, argv, FALSE) ;
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], "is40pin" ) == 0) doIs40Pin () ;
else
{
fprintf (stderr, "%s: Unknown command: %s.\n", argv [0], argv [1]) ;

219
gpio/test/gpio_test6_wfi.sh Executable file
View 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

View File

@@ -1,3 +1,3 @@
#define VERSION "3.14"
#define VERSION "3.16"
#define VERSION_MAJOR 3
#define VERSION_MINOR 14
#define VERSION_MINOR 16

246
wiringPi/WiringpiV1.c Normal file
View 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;
}

View File

@@ -3,7 +3,7 @@ CFLAGS = -Wall
LDFLAGS =
# 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
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:
${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:
${CC} ${CFLAGS} wiringpi_test7_bench.c -o wiringpi_test7_bench -lwiringPi

View File

@@ -52,6 +52,7 @@ int main (void) {
delayMicroseconds(600000);
}
//Error wrong direction - only for fun
digitalWrite(GPIO, LOW);

View 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();
}

View 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();
}

View File

@@ -66,7 +66,7 @@ int main (void) {
case PI_MODEL_ZERO_W: //ARM=1000MHz
fExpectTimedigitalWrite = 0.104; //us;
fExpectTimedigitalRead = 0.135; //us
fExpectTimepinMode = 0.250; //us
fExpectTimepinMode = 0.360; //us
break;
case PI_MODEL_2:
ToggleValue /= 4;

View File

@@ -135,7 +135,7 @@ int main (void) {
pinMode(PWM, PWM_OUTPUT); //Mode BAL, pwmr=1024, pwmc=32
printf("pwmc 4.8kHz\n");
pwmSetClock(2000);
delay(250);
delay(1000);
printf("Register ISR@%d\n", PWM);
// INT_EDGE_BOTH, INT_EDGE_FALLING, INT_EDGE_RISING only one ISR per input

View File

@@ -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) {
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) {
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) {
if (fabs(value-expect)<epsilon) {
printf("%35s (%.3f==%.3f) -> %spassed%s \n", msg, value, expect, COLORGRN, COLORDEF);

File diff suppressed because it is too large Load Diff

View File

@@ -144,6 +144,7 @@ extern const char *piRevisionNames [16] ;
extern const char *piMakerNames [16] ;
extern const int piMemorySize [ 8] ;
// Intended for the GPIO program Use at your own risk.
// 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 int piBoard40Pin (void) ; // Interface V3.7
extern int piRP1Model (void) ; // Interface V3.14
extern int wpiPinToGpio (int wpiPin) ;
extern int physPinToGpio (int physPin) ;
extern int wpiPinToGpio (int wpiPin) ; // please don't use outside 0-63 and on RP1
extern int physPinToGpio (int physPin) ; // please don't use outside 0-63 and on RP1
extern void setPadDrive (int group, int value) ;
extern void setPadDrivePin (int pin, int value); // Interface V3.0
extern int getAlt (int pin) ;
@@ -296,12 +297,20 @@ extern void digitalWriteByte (int value) ;
extern void digitalWriteByte2 (int value) ;
// 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 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 waitForInterruptClose(int pin) ; //V3.2
extern int waitForInterruptClose(int pin) ; //V3.2 legacy use wiringPiISRStop
// Threads
@@ -315,8 +324,8 @@ extern int piHiPri (const int pri) ;
// Extras from arduino land
extern void delay (unsigned int howLong) ;
extern void delayMicroseconds (unsigned int howLong) ;
extern void delay (unsigned int ms) ;
extern void delayMicroseconds (unsigned int us) ;
extern unsigned int millis (void) ;
extern unsigned int micros (void) ;